diff --git a/build.gradle.kts b/build.gradle.kts index 00752cd40..262d19a80 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -109,7 +109,9 @@ tasks.withType(JavaCompile::class.java) { sourceSets { create("data") { compileClasspath += sourceSets["main"].output + compileClasspath += sourceSets["main"].compileClasspath runtimeClasspath += sourceSets["main"].output + runtimeClasspath += sourceSets["main"].runtimeClasspath } this["main"].resources { @@ -189,12 +191,10 @@ dependencies { } } -configurations { - getByName("dataImplementation").extendsFrom(getByName("implementation")) -} - minecraft { - //accessTransformer(file("src/main/resources/META-INF/accesstransformer.cfg")) + accessTransformers { + files("src/main/resources/META-INF/accesstransformer.cfg") + } runs { configureEach { @@ -243,7 +243,7 @@ minecraft { mixin { config("$mod_id.mixins.json") - config("$mod_id.ad_astra.mixins.json") + // config("$mod_id.ad_astra.mixins.json") } repositories { diff --git a/gradle.properties b/gradle.properties index 3d87f7c07..a2a114d13 100644 --- a/gradle.properties +++ b/gradle.properties @@ -14,7 +14,7 @@ mc_version=1.21 jei_mc_version=1.21 curios_mc_version=1.20.2 -forge_gradle_version=[7.0.145,) +forge_gradle_version=7.0.153 forge_version=21.0.54-beta mixingradle_version=0.7.33 mixin_version=0.8.5 diff --git a/settings.gradle.kts b/settings.gradle.kts index f89f10103..7d4171a30 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -24,14 +24,6 @@ buildscript { } } - maven(url = "https://repo.spongepowered.org/repository/maven-public/") { - name = "Spongepowered" - - content { - includeGroup("org.spongepowered") - } - } - mavenCentral() } @@ -43,7 +35,6 @@ buildscript { classpath(group = "net.neoforged.gradle", name = "userdev", version = forge_gradle_version) classpath(group = "net.neoforged.gradle", name = "mixin", version = forge_gradle_version) classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${kotlin_version}") - classpath("org.spongepowered:mixingradle:${mixingradle_version}") classpath(group = "org.gradle.toolchains", name = "foojay-resolver", version = "0.5.0") } diff --git a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/DataGen.kt b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/DataGen.kt index 92894f6aa..356d1a4b9 100644 --- a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/DataGen.kt +++ b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/DataGen.kt @@ -21,6 +21,8 @@ import net.minecraftforge.eventbus.api.SubscribeEvent import net.minecraftforge.fml.common.Mod import net.minecraftforge.data.event.GatherDataEvent import net.minecraftforge.registries.ForgeRegistries +import net.neoforged.fml.common.EventBusSubscriber +import net.neoforged.fml.common.Mod import ru.dbotthepony.mc.otm.OverdriveThatMatters import ru.dbotthepony.mc.otm.android.AndroidResearchDataProvider import ru.dbotthepony.mc.otm.block.* @@ -55,7 +57,7 @@ import kotlin.properties.Delegates internal fun modLocation(string: String) = ResourceLocation(DataGen.MOD_ID, string) -@Mod.EventBusSubscriber(modid = DataGen.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD) +@EventBusSubscriber(modid = DataGen.MOD_ID, bus = EventBusSubscriber.Bus.MOD) object DataGen { const val MOD_ID = OverdriveThatMatters.MOD_ID diff --git a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/tags/Tags.kt b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/tags/Tags.kt index 7bb46aece..4bda0864d 100644 --- a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/tags/Tags.kt +++ b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/tags/Tags.kt @@ -30,6 +30,8 @@ fun addTags(tagsProvider: TagsProvider) { tagsProvider.plates.add("gold", MItems.GOLD_PLATE) tagsProvider.plates.add("carbon", MItems.CARBON_MESH) + tagsProvider.items.Appender(ItemTags.MEAT).add(MItems.NUTRIENT_PASTE) + tagsProvider.fluids.forge("experience").add(MFluids.LIQUID_XP).add(MFluids.LIQUID_XP_FLOWING) tagsProvider.fluidTypes.forge("experience").add(MFluids.LIQUID_XP_TYPE) diff --git a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/tags/TagsProvider.kt b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/tags/TagsProvider.kt index 41ad89edd..fc80ba9a7 100644 --- a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/tags/TagsProvider.kt +++ b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/tags/TagsProvider.kt @@ -18,7 +18,7 @@ import net.minecraftforge.common.Tags import net.minecraftforge.data.event.GatherDataEvent import net.minecraftforge.registries.ForgeRegistries import net.minecraftforge.registries.IForgeRegistry -import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability +import ru.dbotthepony.mc.otm.capability.MatteryPlayer import ru.dbotthepony.mc.otm.datagen.DataGen import java.util.stream.Stream import net.minecraft.data.tags.TagsProvider as MinecraftTagsProvider @@ -172,7 +172,7 @@ class TagsProvider(private val event: GatherDataEvent) { val mobEffects = Delegate(ForgeRegistries.MOB_EFFECTS) val damageTypes = Delegate(Registries.DAMAGE_TYPE) - val androidImmuneEffects = mobEffects.Appender(MatteryPlayerCapability.ANDROID_IMMUNE_EFFECTS) + val androidImmuneEffects = mobEffects.Appender(MatteryPlayer.ANDROID_IMMUNE_EFFECTS) val requiresShovel = blocks.Appender(BlockTags.MINEABLE_WITH_SHOVEL) val requiresAxe = blocks.Appender(BlockTags.MINEABLE_WITH_AXE) diff --git a/src/main/java/ru/dbotthepony/mc/otm/OverdriveThatMatters.java b/src/main/java/ru/dbotthepony/mc/otm/OverdriveThatMatters.java index 8f0b0c57b..619fc654e 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/OverdriveThatMatters.java +++ b/src/main/java/ru/dbotthepony/mc/otm/OverdriveThatMatters.java @@ -3,27 +3,26 @@ package ru.dbotthepony.mc.otm; import kotlin.KotlinVersion; import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.item.crafting.Ingredient; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.eventbus.api.EventPriority; -import net.minecraftforge.fml.DistExecutor; -import net.minecraftforge.fml.ModList; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; -import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; -import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; -import net.minecraftforge.registries.IdMappingEvent; +import net.neoforged.api.distmarker.Dist; +import net.neoforged.bus.api.EventPriority; +import net.neoforged.bus.api.IEventBus; +import net.neoforged.fml.ModContainer; +import net.neoforged.fml.ModList; +import net.neoforged.fml.common.Mod; +import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent; +import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent; +import net.neoforged.fml.loading.FMLLoader; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import ru.dbotthepony.mc.otm.android.AndroidResearchDescription; +import ru.dbotthepony.mc.otm.android.AndroidResearchDescriptions; import ru.dbotthepony.mc.otm.android.AndroidResearchManager; +import ru.dbotthepony.mc.otm.android.AndroidResearchResult; +import ru.dbotthepony.mc.otm.android.AndroidResearchResults; import ru.dbotthepony.mc.otm.android.feature.EnderTeleporterFeature; import ru.dbotthepony.mc.otm.block.entity.MatteryBlockEntity; -import ru.dbotthepony.mc.otm.block.entity.blackhole.ExplosionQueue; import ru.dbotthepony.mc.otm.block.entity.decorative.DevChestBlockEntity; -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.capability.drive.DrivePool; import ru.dbotthepony.mc.otm.client.AndroidAbilityKeyMapping; import ru.dbotthepony.mc.otm.client.AndroidMenuKeyMapping; @@ -36,8 +35,8 @@ import ru.dbotthepony.mc.otm.client.model.TritaniumArmorModel; import ru.dbotthepony.mc.otm.client.render.ShockwaveRenderer; import ru.dbotthepony.mc.otm.client.render.blockentity.BatteryBankRenderer; import ru.dbotthepony.mc.otm.client.render.blockentity.MatterBatteryBankRenderer; -import ru.dbotthepony.mc.otm.compat.adastra.AdAstraCompatKt; import ru.dbotthepony.mc.otm.compat.curios.CuriosCompatKt; +import ru.dbotthepony.mc.otm.compat.vanilla.MatteryChestMenu; import ru.dbotthepony.mc.otm.config.AndroidConfig; import ru.dbotthepony.mc.otm.config.CablesConfig; import ru.dbotthepony.mc.otm.config.ClientConfig; @@ -47,22 +46,24 @@ import ru.dbotthepony.mc.otm.config.MachinesConfig; import ru.dbotthepony.mc.otm.config.ServerCompatConfig; import ru.dbotthepony.mc.otm.config.ServerConfig; import ru.dbotthepony.mc.otm.config.ToolsConfig; +import ru.dbotthepony.mc.otm.data.DecimalProvider; import ru.dbotthepony.mc.otm.item.ChestUpgraderItem; import ru.dbotthepony.mc.otm.item.tool.ExplosiveHammerItem; import ru.dbotthepony.mc.otm.item.armor.TritaniumArmorItem; 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.AbstractRegistryAction; +import ru.dbotthepony.mc.otm.matter.IMatterFunction; import ru.dbotthepony.mc.otm.matter.MatterManager; import ru.dbotthepony.mc.otm.network.*; import ru.dbotthepony.mc.otm.registry.*; +import ru.dbotthepony.mc.otm.storage.StorageStack; import ru.dbotthepony.mc.otm.triggers.KillAsAndroidTrigger; import top.theillusivec4.curios.api.CuriosApi; -import static net.minecraftforge.common.MinecraftForge.EVENT_BUS; +import static net.neoforged.neoforge.common.NeoForge.EVENT_BUS; import javax.annotation.ParametersAreNonnullByDefault; -import java.util.concurrent.atomic.AtomicInteger; // The value here should match an entry in the META-INF/mods.toml file @Mod(OverdriveThatMatters.MOD_ID) @@ -72,21 +73,9 @@ public final class OverdriveThatMatters { // Directly reference a log4j logger. public static final String MOD_ID = "overdrive_that_matters"; private static final Logger LOGGER = LogManager.getLogger(); - public static final AtomicInteger INGREDIENT_CACHE_INVALIDATION_COUNTER; - - static { - try { - var f = Ingredient.class.getDeclaredField("INVALIDATION_COUNTER"); - f.setAccessible(true); - INGREDIENT_CACHE_INVALIDATION_COUNTER = (AtomicInteger) f.get(null); - } catch (IllegalAccessException | NoSuchFieldException e) { - throw new RuntimeException(e); - } - } - public static OverdriveThatMatters INSTANCE; public static ResourceLocation loc(String path) { - return new ResourceLocation(MOD_ID, path); + return ResourceLocation.fromNamespaceAndPath(MOD_ID, path); } private static void checkIfKotlinIsInstalled() { @@ -95,9 +84,9 @@ public final class OverdriveThatMatters { } } - public OverdriveThatMatters() { + public OverdriveThatMatters(IEventBus bus, Dist dist, ModContainer container) { if (INSTANCE != null) { - throw new IllegalStateException("yo what the fuck"); + throw new IllegalStateException("wei wei wei... hello?"); } try { @@ -121,35 +110,67 @@ public final class OverdriveThatMatters { INSTANCE = this; - var modBus = FMLJavaModLoadingContext.get().getModEventBus(); + bus.addListener(MRegistry.INSTANCE::register); - MRegistry.INSTANCE.initialize(modBus); - MatterManager.INSTANCE.initialize(modBus); + MBlocks.INSTANCE.register(bus); + MFluids.INSTANCE.register(bus); + MBlockEntities.INSTANCE.register(bus); + MEntityTypes.INSTANCE.register(bus); + MMenus.INSTANCE.register(bus); + MItems.INSTANCE.register(bus); + AndroidFeatures.INSTANCE.register(bus); + MSoundEvents.INSTANCE.register(bus); + LootModifiers.INSTANCE.register(bus); + MItemFunctionTypes.INSTANCE.register(bus); + MLootItemConditions.INSTANCE.register(bus); + MRecipes.INSTANCE.register(bus); + MDataComponentTypes.INSTANCE.register(bus); + MArmorMaterials.INSTANCE.register(bus); - modBus.addListener(EventPriority.HIGHEST, this::setup); - modBus.addListener(EventPriority.NORMAL, this::setupClient); - modBus.addListener(EventPriority.NORMAL, MatteryCapability::register); + StorageStack.Companion.register(bus); + MatteryChestMenu.Companion.register(bus); - DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> { - modBus.addListener(EventPriority.NORMAL, AndroidMenuKeyMapping.INSTANCE::register); - modBus.addListener(EventPriority.NORMAL, AndroidAbilityKeyMapping.INSTANCE::register); - modBus.addListener(EventPriority.NORMAL, TritaniumArmorModel::register); - modBus.addListener(EventPriority.NORMAL, GravitationStabilizerModel::register); - modBus.addListener(EventPriority.NORMAL, MCreativeTabs.INSTANCE::register); + MCreativeTabs.INSTANCE.initialize(bus); - modBus.addListener(EventPriority.NORMAL, BatteryBankRenderer.Companion::onRegisterAdditionalModels); - modBus.addListener(EventPriority.NORMAL, MatterBatteryBankRenderer.Companion::onRegisterAdditionalModels); - }); + bus.addListener(NetworkPacketsKt::registerNetworkPackets); - ClientConfig.INSTANCE.register(); - ServerConfig.INSTANCE.register(); - CablesConfig.INSTANCE.register(); - ServerCompatConfig.INSTANCE.register(); - AndroidConfig.INSTANCE.register(); - ExopackConfig.INSTANCE.register(); - ItemsConfig.INSTANCE.register(); - MachinesConfig.INSTANCE.register(); - ToolsConfig.INSTANCE.register(); + DecimalProvider.Companion.register(bus); + AndroidResearchDescription.Companion.register(bus); + AndroidResearchDescriptions.INSTANCE.register(bus); + AndroidResearchResult.Companion.register(bus); + AndroidResearchResults.INSTANCE.register(bus); + + AbstractRegistryAction.Companion.register(bus); + IMatterFunction.Companion.register(bus); + + MRegistry.INSTANCE.initialize(bus); + MatterManager.INSTANCE.initialize(bus); + + bus.addListener(EventPriority.HIGHEST, this::setup); + bus.addListener(EventPriority.NORMAL, this::setupClient); + + if (FMLLoader.getDist() == Dist.CLIENT) { + bus.addListener(EventPriority.NORMAL, AndroidMenuKeyMapping.INSTANCE::register); + bus.addListener(EventPriority.NORMAL, AndroidAbilityKeyMapping.INSTANCE::register); + bus.addListener(EventPriority.NORMAL, TritaniumArmorModel::register); + bus.addListener(EventPriority.NORMAL, GravitationStabilizerModel::register); + bus.addListener(EventPriority.NORMAL, MCreativeTabs.INSTANCE::register); + + bus.addListener(EventPriority.NORMAL, BatteryBankRenderer.Companion::onRegisterAdditionalModels); + bus.addListener(EventPriority.NORMAL, MatterBatteryBankRenderer.Companion::onRegisterAdditionalModels); + + MBlockColors.INSTANCE.register(bus); + } + + ClientConfig.INSTANCE.register(container); + ServerConfig.INSTANCE.register(container); + CablesConfig.INSTANCE.register(container); + ServerCompatConfig.INSTANCE.register(container); + AndroidConfig.INSTANCE.register(container); + ExopackConfig.INSTANCE.register(container); + ItemsConfig.INSTANCE.register(container); + MachinesConfig.INSTANCE.register(container); + ToolsConfig.INSTANCE.register(container); } private void setup(final FMLCommonSetupEvent event) { @@ -158,23 +179,22 @@ public final class OverdriveThatMatters { 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::onLevelTick); - EVENT_BUS.addListener(EventPriority.LOWEST, GlobalEventHandlerKt::onServerTick); + EVENT_BUS.addListener(EventPriority.HIGH, GlobalEventHandlerKt::onLevelTickPre); + EVENT_BUS.addListener(EventPriority.LOWEST, GlobalEventHandlerKt::onLevelTickPost); + EVENT_BUS.addListener(EventPriority.HIGH, GlobalEventHandlerKt::onServerTickPre); + EVENT_BUS.addListener(EventPriority.LOWEST, GlobalEventHandlerKt::onServerTickPost); - EVENT_BUS.addListener(EventPriority.NORMAL, MatteryPlayerCapability.Companion::onPlayerTick); - EVENT_BUS.addListener(EventPriority.NORMAL, MatteryPlayerCapability.Companion::isMobEffectApplicable); - EVENT_BUS.addListener(EventPriority.LOW, MatteryPlayerCapability.Companion::onHurtEvent); - EVENT_BUS.addListener(EventPriority.HIGH, MatteryPlayerCapability.Companion::onAttackEvent); - 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.NORMAL, MatteryPlayerCapability.Companion::onStartTracking); - EVENT_BUS.addListener(EventPriority.NORMAL, MatteryPlayerCapability.Companion::onStopTracking); - EVENT_BUS.addListener(EventPriority.NORMAL, MatteryPlayerCapability.Companion::addCommands); + EVENT_BUS.addListener(EventPriority.NORMAL, MatteryPlayer.Companion::onPlayerTickPre); + EVENT_BUS.addListener(EventPriority.NORMAL, MatteryPlayer.Companion::onPlayerTickPost); + EVENT_BUS.addListener(EventPriority.NORMAL, MatteryPlayer.Companion::isMobEffectApplicable); + EVENT_BUS.addListener(EventPriority.LOW, MatteryPlayer.Companion::onHurtEvent); + EVENT_BUS.addListener(EventPriority.NORMAL, MatteryPlayer.Companion::onPlayerChangeDimensionEvent); + EVENT_BUS.addListener(EventPriority.LOWEST, MatteryPlayer.Companion::onPlayerDeath); + EVENT_BUS.addListener(EventPriority.NORMAL, MatteryPlayer.Companion::onPlayerCloneEvent); + EVENT_BUS.addListener(EventPriority.NORMAL, MatteryPlayer.Companion::onStartTracking); + EVENT_BUS.addListener(EventPriority.NORMAL, MatteryPlayer.Companion::onStopTracking); + EVENT_BUS.addListener(EventPriority.NORMAL, MatteryPlayer.Companion::addCommands); - 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); @@ -191,6 +211,7 @@ public final class OverdriveThatMatters { EVENT_BUS.addListener(EventPriority.NORMAL, MatteryBlockEntity.Companion::onWatch); EVENT_BUS.addListener(EventPriority.NORMAL, MatteryBlockEntity.Companion::onForget); EVENT_BUS.addListener(EventPriority.NORMAL, MatteryBlockEntity.Companion::playerDisconnected); + EVENT_BUS.addListener(EventPriority.NORMAL, MatteryBlockEntity.Companion::postLevelTick); EVENT_BUS.addListener(EventPriority.LOWEST, KillAsAndroidTrigger.INSTANCE::onKill); @@ -203,29 +224,14 @@ public final class OverdriveThatMatters { EVENT_BUS.addListener(EventPriority.NORMAL, DevChestBlockEntity.Companion::mappingsChanged); - MatteryPlayerNetworkChannel.INSTANCE.register(); - MenuNetworkChannel.INSTANCE.register(); - WeaponNetworkChannel.INSTANCE.register(); - GenericNetworkChannel.INSTANCE.register(); - if (ModList.get().isLoaded(CuriosApi.MODID)) { EVENT_BUS.addListener(EventPriority.NORMAL, CuriosCompatKt::onCuriosSlotModifiersUpdated); } - - if (AdAstraCompatKt.isAdAstraLoaded()) { - EVENT_BUS.addListener(EventPriority.NORMAL, AdAstraCompatKt::onDamageEvent); - EVENT_BUS.addListener(EventPriority.NORMAL, AdAstraCompatKt::onMatteryTick); - } } private void setupClient(final FMLClientSetupEvent event) { EVENT_BUS.addListener(EventPriority.NORMAL, MatterManager.INSTANCE::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); diff --git a/src/main/java/ru/dbotthepony/mc/otm/capability/MatteryCapability.java b/src/main/java/ru/dbotthepony/mc/otm/capability/MatteryCapability.java index 6d09603f4..8f266908b 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/capability/MatteryCapability.java +++ b/src/main/java/ru/dbotthepony/mc/otm/capability/MatteryCapability.java @@ -1,9 +1,12 @@ package ru.dbotthepony.mc.otm.capability; -import net.minecraftforge.common.capabilities.CapabilityManager; -import net.minecraftforge.common.capabilities.Capability; -import net.minecraftforge.common.capabilities.CapabilityToken; +import net.minecraft.core.Direction; +import net.minecraft.resources.ResourceLocation; +import net.neoforged.neoforge.capabilities.BlockCapability; +import net.neoforged.neoforge.capabilities.ItemCapability; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import ru.dbotthepony.mc.otm.OverdriveThatMatters; import ru.dbotthepony.mc.otm.block.entity.cable.EnergyCableBlockEntity; import ru.dbotthepony.mc.otm.capability.drive.IMatteryDrive; import ru.dbotthepony.mc.otm.capability.energy.IMatteryEnergyStorage; @@ -12,57 +15,56 @@ import ru.dbotthepony.mc.otm.capability.matter.IReplicationTaskProvider; import ru.dbotthepony.mc.otm.capability.matter.IPatternStorage; import ru.dbotthepony.mc.otm.graph.matter.MatterNode; import ru.dbotthepony.mc.otm.graph.storage.StorageNode; -import top.theillusivec4.curios.api.type.capability.ICurio; -import top.theillusivec4.curios.api.type.capability.ICuriosItemHandler; import javax.annotation.Nonnull; public class MatteryCapability { @Nonnull @NotNull - public static final Capability ENERGY = CapabilityManager.get(new CapabilityToken<>() {}); + public static final BlockCapability BLOCK_ENERGY = BlockCapability.createSided(ResourceLocation.fromNamespaceAndPath(OverdriveThatMatters.MOD_ID, "energy"), IMatteryEnergyStorage.class); @Nonnull @NotNull - public static final Capability MATTERY_PLAYER = CapabilityManager.get(new CapabilityToken<>() {}); + public static final ItemCapability ITEM_ENERGY = ItemCapability.createVoid(ResourceLocation.fromNamespaceAndPath(OverdriveThatMatters.MOD_ID, "energy"), IMatteryEnergyStorage.class); @Nonnull @NotNull - public static final Capability MATTER = CapabilityManager.get(new CapabilityToken<>() {}); + public static final ItemCapability MATTER_ITEM = ItemCapability.createVoid(ResourceLocation.fromNamespaceAndPath(OverdriveThatMatters.MOD_ID, "matter"), IMatterStorage.class); @Nonnull @NotNull - public static final Capability MATTER_NODE = CapabilityManager.get(new CapabilityToken<>() {}); + public static final BlockCapability MATTER_BLOCK = BlockCapability.createSided(ResourceLocation.fromNamespaceAndPath(OverdriveThatMatters.MOD_ID, "matter"), IMatterStorage.class); @Nonnull @NotNull - public static final Capability PATTERN = CapabilityManager.get(new CapabilityToken<>() {}); + public static final BlockCapability MATTER_NODE = BlockCapability.createSided(ResourceLocation.fromNamespaceAndPath(OverdriveThatMatters.MOD_ID, "matter_node"), MatterNode.class); @Nonnull @NotNull - public static final Capability TASK = CapabilityManager.get(new CapabilityToken<>() {}); + public static final ItemCapability PATTERN_ITEM = ItemCapability.createVoid(ResourceLocation.fromNamespaceAndPath(OverdriveThatMatters.MOD_ID, "pattern"), IPatternStorage.class); @Nonnull @NotNull - public static final Capability> DRIVE = CapabilityManager.get(new CapabilityToken<>() {}); + public static final BlockCapability PATTERN_BLOCK = BlockCapability.createSided(ResourceLocation.fromNamespaceAndPath(OverdriveThatMatters.MOD_ID, "pattern"), IPatternStorage.class); @Nonnull @NotNull - public static final Capability STORAGE_NODE = CapabilityManager.get(new CapabilityToken<>() {}); + public static final BlockCapability REPLICATION_TASK = BlockCapability.createVoid(ResourceLocation.fromNamespaceAndPath(OverdriveThatMatters.MOD_ID, "replication_task"), IReplicationTaskProvider.class); @Nonnull @NotNull - public static final Capability ENERGY_CABLE_NODE = CapabilityManager.get(new CapabilityToken<>() {}); + public static final ItemCapability CONDENSATION_DRIVE = ItemCapability.createVoid(ResourceLocation.fromNamespaceAndPath(OverdriveThatMatters.MOD_ID, "condensation_drive"), IMatteryDrive.class); @Nonnull @NotNull - public static final Capability CURIOS_INVENTORY = CapabilityManager.get(new CapabilityToken<>() {}); + public static final BlockCapability STORAGE_NODE = BlockCapability.createSided(ResourceLocation.fromNamespaceAndPath(OverdriveThatMatters.MOD_ID, "storage_node"), StorageNode.class); + + // TODO: remove this + @Nonnull + @NotNull + public static final BlockCapability ENERGY_CABLE_NODE = BlockCapability.createVoid(ResourceLocation.fromNamespaceAndPath(OverdriveThatMatters.MOD_ID, "energy_cable_node"), EnergyCableBlockEntity.Node.class); @Nonnull @NotNull - public static final Capability CURIOS_ITEM = CapabilityManager.get(new CapabilityToken<>() {}); - - @Nonnull - @NotNull - public static final Capability UPGRADE = CapabilityManager.get(new CapabilityToken<>() {}); + public static final ItemCapability UPGRADE = ItemCapability.createVoid(ResourceLocation.fromNamespaceAndPath(OverdriveThatMatters.MOD_ID, "machine_upgrade"), IMatteryUpgrade.class); } diff --git a/src/main/java/ru/dbotthepony/mc/otm/client/model/ExosuitModel.java b/src/main/java/ru/dbotthepony/mc/otm/client/model/ExosuitModel.java index 3fef0651e..cb9bbadbc 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/client/model/ExosuitModel.java +++ b/src/main/java/ru/dbotthepony/mc/otm/client/model/ExosuitModel.java @@ -1,9 +1,7 @@ package ru.dbotthepony.mc.otm.client.model; -import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.PoseStack; import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet; -import net.minecraft.client.Minecraft; import net.minecraft.client.model.HumanoidModel; import net.minecraft.client.model.PlayerModel; import net.minecraft.client.model.geom.PartPose; @@ -21,11 +19,8 @@ import net.minecraft.client.renderer.entity.layers.RenderLayer; import net.minecraft.client.renderer.entity.player.PlayerRenderer; import net.minecraft.resources.ResourceLocation; import net.minecraftforge.client.event.RenderPlayerEvent; -import org.joml.Vector3f; -import org.joml.Vector4f; import ru.dbotthepony.mc.otm.OverdriveThatMatters; import ru.dbotthepony.mc.otm.capability.MatteryCapability; -import ru.dbotthepony.mc.otm.network.SmokeParticlesPacket; import javax.annotation.Nonnull; import java.util.Set; diff --git a/src/main/java/ru/dbotthepony/mc/otm/mixin/MixinInventory.java b/src/main/java/ru/dbotthepony/mc/otm/mixin/MixinInventory.java index 0b9a709b3..8c69e3245 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/mixin/MixinInventory.java +++ b/src/main/java/ru/dbotthepony/mc/otm/mixin/MixinInventory.java @@ -18,7 +18,7 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import ru.dbotthepony.mc.otm.capability.MatteryCapability; -import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability; +import ru.dbotthepony.mc.otm.capability.MatteryPlayer; import java.util.function.Predicate; @@ -61,7 +61,7 @@ public class MixinInventory { at = @At("TAIL") ) private void dropAll(CallbackInfo ci) { - MatteryPlayerCapability.inventoryDropAll((Inventory)(Object)this); + MatteryPlayer.inventoryDropAll((Inventory)(Object)this); } @Inject( @@ -69,7 +69,7 @@ public class MixinInventory { at = @At("TAIL") ) private void clearContent(CallbackInfo ci) { - MatteryPlayerCapability.inventoryClearContent((Inventory)(Object)this); + MatteryPlayer.inventoryClearContent((Inventory)(Object)this); } @Inject( diff --git a/src/main/java/ru/dbotthepony/mc/otm/mixin/MixinMinecraft.java b/src/main/java/ru/dbotthepony/mc/otm/mixin/MixinMinecraft.java index bbf7892bd..0adc06a71 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/mixin/MixinMinecraft.java +++ b/src/main/java/ru/dbotthepony/mc/otm/mixin/MixinMinecraft.java @@ -5,10 +5,8 @@ import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.item.ItemStack; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Redirect; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability; +import ru.dbotthepony.mc.otm.capability.MatteryPlayer; @Mixin(Minecraft.class) public class MixinMinecraft { @@ -22,7 +20,7 @@ public class MixinMinecraft { private int pickBlock(Inventory inventory, ItemStack itemStack) { int i = inventory.findSlotMatchingItem(itemStack); - MatteryPlayerCapability.pickBlockHook(i, itemStack); + MatteryPlayer.pickBlockHook(i, itemStack); return i; } diff --git a/src/main/java/ru/dbotthepony/mc/otm/mixin/MixinPatchProjectileFinder.java b/src/main/java/ru/dbotthepony/mc/otm/mixin/MixinPatchProjectileFinder.java deleted file mode 100644 index 4dd8325cb..000000000 --- a/src/main/java/ru/dbotthepony/mc/otm/mixin/MixinPatchProjectileFinder.java +++ /dev/null @@ -1,30 +0,0 @@ -package ru.dbotthepony.mc.otm.mixin; - -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.item.ItemStack; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability; - -@Mixin(Player.class) -public class MixinPatchProjectileFinder { - @Inject( - method = "getProjectile(Lnet/minecraft/world/item/ItemStack;)Lnet/minecraft/world/item/ItemStack;", - at = @At( - value = "INVOKE", - target = "net.minecraftforge.common.ForgeHooks.getProjectile(Lnet/minecraft/world/entity/LivingEntity;Lnet/minecraft/world/item/ItemStack;Lnet/minecraft/world/item/ItemStack;)Lnet/minecraft/world/item/ItemStack;", - ordinal = 2, - shift = At.Shift.BEFORE, - remap = false - ), - cancellable = true) - private void exosuitGetProjectileHook(ItemStack weaponItem, CallbackInfoReturnable hook) { - ItemStack result = MatteryPlayerCapability.getProjectileHook((Player) ((Object) this), weaponItem); - - if (result != null) { - hook.setReturnValue(result); - } - } -} diff --git a/src/main/java/ru/dbotthepony/mc/otm/mixin/MixinPlayer.java b/src/main/java/ru/dbotthepony/mc/otm/mixin/MixinPlayer.java index 1e112bcde..9cc01fed5 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/mixin/MixinPlayer.java +++ b/src/main/java/ru/dbotthepony/mc/otm/mixin/MixinPlayer.java @@ -1,19 +1,85 @@ package ru.dbotthepony.mc.otm.mixin; +import com.mojang.authlib.GameProfile; +import net.minecraft.core.BlockPos; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Level; +import org.jetbrains.annotations.NotNull; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import ru.dbotthepony.mc.otm.capability.IMatteryPlayer; +import ru.dbotthepony.mc.otm.capability.MatteryPlayer; + +import java.util.Objects; @Mixin(Player.class) -public class MixinPlayer { +public class MixinPlayer implements IMatteryPlayer { + private Player otmSelf() { + return (Player) (Object) this; + } + + @Inject( + method = "getProjectile(Lnet/minecraft/world/item/ItemStack;)Lnet/minecraft/world/item/ItemStack;", + at = @At( + value = "INVOKE", + target = "net.minecraftforge.common.ForgeHooks.getProjectile(Lnet/minecraft/world/entity/LivingEntity;Lnet/minecraft/world/item/ItemStack;Lnet/minecraft/world/item/ItemStack;)Lnet/minecraft/world/item/ItemStack;", + ordinal = 2, + shift = At.Shift.BEFORE, + remap = false + ), + cancellable = true) + private void exosuitGetProjectileHook(ItemStack weaponItem, CallbackInfoReturnable hook) { + ItemStack result = MatteryPlayer.getProjectileHook(otmSelf(), weaponItem); + + if (result != null) { + hook.setReturnValue(result); + } + } + @Inject( method = "destroyVanishingCursedItems()V", at = @At("TAIL") ) private void destroyVanishingCursedItems(CallbackInfo ci) { - MatteryPlayerCapability.playerDestroyVanishingCursedItems((Player)(Object)this); + MatteryPlayer.playerDestroyVanishingCursedItems(otmSelf()); + } + + private MatteryPlayer otmPlayer; + + @Inject( + method = "(Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;FLcom/mojang/authlib/GameProfile;)V", + at = @At("TAIL") + ) + private void constructOtmPlayer(Level p_250508_, BlockPos p_250289_, float p_251702_, GameProfile p_252153_, CallbackInfo ci) { + otmPlayer = new MatteryPlayer(otmSelf()); + } + + @NotNull + @Override + public MatteryPlayer getOtmPlayer() { + return Objects.requireNonNull(otmPlayer, "Something went horribly wrong, otmPlayer is null"); + } + + @Inject( + method = "addAdditionalSaveData(Lnet/minecraft/nbt/CompoundTag;)V", + at = @At("TAIL") + ) + private void addAdditionalSaveData(CompoundTag data, CallbackInfo ci) { + data.put("overdrive_that_matters_player", otmPlayer.serializeNBT(otmSelf().registryAccess())); + } + + @Inject( + method = "readAdditionalSaveData(Lnet/minecraft/nbt/CompoundTag;)V", + at = @At("TAIL") + ) + private void readAdditionalSaveData(CompoundTag data, CallbackInfo ci) { + otmPlayer.deserializeNBT(data.getCompound("overdrive_that_matters_player"), otmSelf().registryAccess()); } } diff --git a/src/main/java/ru/dbotthepony/mc/otm/mixin/compat/ad_astra/EntityOxygenSystemMixin.java b/src/main/java/ru/dbotthepony/mc/otm/mixin/compat/ad_astra/EntityOxygenSystemMixin.java deleted file mode 100644 index 6201620d0..000000000 --- a/src/main/java/ru/dbotthepony/mc/otm/mixin/compat/ad_astra/EntityOxygenSystemMixin.java +++ /dev/null @@ -1,31 +0,0 @@ -package ru.dbotthepony.mc.otm.mixin.compat.ad_astra; - -import earth.terrarium.ad_astra.common.entity.system.EntityOxygenSystem; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.entity.LivingEntity; -import net.minecraft.world.entity.player.Player; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import ru.dbotthepony.mc.otm.capability.MatteryCapability; -import ru.dbotthepony.mc.otm.config.ServerCompatConfig; - -@Mixin(EntityOxygenSystem.class) -public class EntityOxygenSystemMixin { - @Inject( - method = "oxygenTick(Lnet/minecraft/world/entity/LivingEntity;Lnet/minecraft/server/level/ServerLevel;)V", - at = @At("HEAD"), - cancellable = true, - remap = false - ) - private static void oxygenTick(LivingEntity entity, ServerLevel level, CallbackInfo hook) { - if (entity instanceof Player && ServerCompatConfig.AdAstra.INSTANCE.getANDROIDS_DO_NOT_NEED_OXYGEN()) { - entity.getCapability(MatteryCapability.MATTERY_PLAYER).ifPresent(it -> { - if (it.isAndroid()) { - hook.cancel(); - } - }); - } - } -} diff --git a/src/main/java/ru/dbotthepony/mc/otm/mixin/compat/ad_astra/EntityTemperatureSystemMixin.java b/src/main/java/ru/dbotthepony/mc/otm/mixin/compat/ad_astra/EntityTemperatureSystemMixin.java deleted file mode 100644 index 421069a9c..000000000 --- a/src/main/java/ru/dbotthepony/mc/otm/mixin/compat/ad_astra/EntityTemperatureSystemMixin.java +++ /dev/null @@ -1,27 +0,0 @@ -package ru.dbotthepony.mc.otm.mixin.compat.ad_astra; - -import earth.terrarium.ad_astra.common.entity.system.EntityTemperatureSystem; -import earth.terrarium.ad_astra.common.util.ModUtils; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.entity.LivingEntity; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import ru.dbotthepony.mc.otm.config.ServerCompatConfig; - -// STAHP! -@Mixin(EntityTemperatureSystem.class) -public class EntityTemperatureSystemMixin { - @Inject( - method = "temperatureTick(Lnet/minecraft/world/entity/LivingEntity;Lnet/minecraft/server/level/ServerLevel;)V", - at = @At("HEAD"), - cancellable = true, - remap = false - ) - private static void temperatureTick(LivingEntity entity, ServerLevel level, CallbackInfo hook) { - if (ServerCompatConfig.AdAstra.INSTANCE.getWHATS_UP_WITH_TEMPERATURE() && !ModUtils.planetHasAtmosphere(level)) { - hook.cancel(); - } - } -} diff --git a/src/main/java/ru/dbotthepony/mc/otm/mixin/compat/ad_astra/OxygenUtilsMixin.java b/src/main/java/ru/dbotthepony/mc/otm/mixin/compat/ad_astra/OxygenUtilsMixin.java deleted file mode 100644 index e8a1a7d57..000000000 --- a/src/main/java/ru/dbotthepony/mc/otm/mixin/compat/ad_astra/OxygenUtilsMixin.java +++ /dev/null @@ -1,31 +0,0 @@ -package ru.dbotthepony.mc.otm.mixin.compat.ad_astra; - -import earth.terrarium.ad_astra.common.util.OxygenUtils; -import net.minecraft.world.entity.LivingEntity; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.level.Level; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import ru.dbotthepony.mc.otm.capability.MatteryCapability; -import ru.dbotthepony.mc.otm.config.ServerCompatConfig; - -@Mixin(OxygenUtils.class) -public class OxygenUtilsMixin { - @Inject( - method = "entityHasOxygen(Lnet/minecraft/world/level/Level;Lnet/minecraft/world/entity/LivingEntity;)Z", - at = @At("HEAD"), - cancellable = true, - remap = false - ) - private static void entityHasOxygen(Level level, LivingEntity entity, CallbackInfoReturnable hook) { - if (entity instanceof Player && ServerCompatConfig.AdAstra.INSTANCE.getANDROIDS_DO_NOT_NEED_OXYGEN()) { - entity.getCapability(MatteryCapability.MATTERY_PLAYER).ifPresent(it -> { - if (it.isAndroid()) { - hook.setReturnValue(true); - } - }); - } - } -} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/GlobalEventHandler.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/GlobalEventHandler.kt index 136e5c99f..a08c1870e 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/GlobalEventHandler.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/GlobalEventHandler.kt @@ -4,16 +4,19 @@ package ru.dbotthepony.mc.otm import net.minecraft.client.server.IntegratedServer +import net.minecraft.core.HolderLookup import net.minecraft.server.MinecraftServer import net.minecraft.world.level.Level -import net.minecraftforge.api.distmarker.Dist -import net.minecraftforge.event.TickEvent -import net.minecraftforge.event.TickEvent.ServerTickEvent -import net.minecraftforge.event.TickEvent.LevelTickEvent -import net.minecraftforge.event.server.ServerAboutToStartEvent -import net.minecraftforge.event.server.ServerStoppedEvent -import net.minecraftforge.event.server.ServerStoppingEvent -import net.minecraftforge.fml.loading.FMLLoader +import net.neoforged.api.distmarker.Dist +import net.neoforged.bus.api.EventPriority +import net.neoforged.bus.api.SubscribeEvent +import net.neoforged.fml.common.EventBusSubscriber +import net.neoforged.fml.loading.FMLLoader +import net.neoforged.neoforge.event.server.ServerAboutToStartEvent +import net.neoforged.neoforge.event.server.ServerStoppedEvent +import net.neoforged.neoforge.event.server.ServerStoppingEvent +import net.neoforged.neoforge.event.tick.LevelTickEvent +import net.neoforged.neoforge.event.tick.ServerTickEvent import org.apache.logging.log4j.LogManager import ru.dbotthepony.mc.otm.block.entity.MatteryBlockEntity import ru.dbotthepony.mc.otm.capability.AbstractProfiledStorage @@ -24,7 +27,6 @@ import ru.dbotthepony.mc.otm.core.util.IConditionalTickable import ru.dbotthepony.mc.otm.core.util.ITickable import ru.dbotthepony.mc.otm.core.util.TickList import ru.dbotthepony.mc.otm.graph.GraphNodeList -import ru.dbotthepony.mc.otm.network.MatteryNetworkChannel import java.util.* import java.util.concurrent.atomic.AtomicInteger @@ -43,6 +45,15 @@ val isClient: Boolean by lazy { FMLLoader.getDist() == Dist.CLIENT } val UNIVERSE_TICKS get() = postServerTick.ticks val Level.ticksPassed get() = postWorldTick.computeIfAbsent(this) { TickList() }.ticks +@Deprecated("Use when absolutely necessary, like context-less methods/properties") +val Registries: HolderLookup.Provider get() { + if (isClient) { + return NULLABLE_MINECRAFT_SERVER?.registryAccess() ?: minecraft.level?.registryAccess() ?: throw IllegalStateException("Not in game") + } else { + return NULLABLE_MINECRAFT_SERVER?.registryAccess() ?: throw IllegalStateException("Not in game") + } +} + fun lazyPerServer(fn: (MinecraftServer) -> V): Lazy { return AtomicallyInvalidatedLazy(serverCounter) { if (!SERVER_IS_LIVE) @@ -169,31 +180,30 @@ var SERVER_IS_LIVE = false private val LOGGER = LogManager.getLogger() -fun onServerTick(event: ServerTickEvent) { - if (event.phase === TickEvent.Phase.START) { - preServerTick.tick() - serverThreads.add(Thread.currentThread()) +fun onServerTickPre(event: ServerTickEvent.Pre) { + preServerTick.tick() + serverThreads.add(Thread.currentThread()) +} + +fun onServerTickPost(event: ServerTickEvent.Post) { + postServerTick.tick() + // чтоб не плодить кучу подписчиков, вызовем напрямую отсюда + GraphNodeList.tick() + AbstractProfiledStorage.onServerPostTick() +} + +fun onLevelTickPre(event: LevelTickEvent.Pre) { + preWorldTick[event.level]?.tick() + + if (event.level.isClientSide) { + clientThreads.add(Thread.currentThread()) } else { - postServerTick.tick() - // чтоб не плодить кучу подписчиков, вызовем напрямую отсюда - GraphNodeList.tick() - AbstractProfiledStorage.onServerPostTick() + serverThreads.add(Thread.currentThread()) } } -fun onLevelTick(event: LevelTickEvent) { - if (event.phase === TickEvent.Phase.START) { - preWorldTick[event.level]?.tick() - - if (event.side.isClient) { - clientThreads.add(Thread.currentThread()) - } else if (event.side.isServer) { - serverThreads.add(Thread.currentThread()) - } - } else { - postWorldTick[event.level]?.tick() - MatteryBlockEntity.postLevelTick(event) - } +fun onLevelTickPost(event: LevelTickEvent.Post) { + postWorldTick[event.level]?.tick() } fun onceServerPre(ticker: ITickable) { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/ObservedConfigList.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/ObservedConfigList.kt index 7a9493536..a227a6282 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/ObservedConfigList.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/ObservedConfigList.kt @@ -1,13 +1,13 @@ package ru.dbotthepony.mc.otm import it.unimi.dsi.fastutil.ints.IntArrayList +import net.minecraft.core.Registry import net.minecraft.resources.ResourceLocation -import net.minecraftforge.common.ForgeConfigSpec -import net.minecraftforge.registries.IForgeRegistry +import net.neoforged.neoforge.common.ModConfigSpec import ru.dbotthepony.mc.otm.config.getValue import java.util.LinkedList -abstract class ObservedConfigList(val parent: ForgeConfigSpec.ConfigValue>, private val allowNulls: Boolean = false) : AbstractMutableList(), RandomAccess { +abstract class ObservedConfigList(val parent: ModConfigSpec.ConfigValue>, private val allowNulls: Boolean = false) : AbstractMutableList(), RandomAccess { private val rawValue: MutableList by parent private val observedValue = LinkedList() private val parsedView: ArrayList = ArrayList() @@ -140,33 +140,3 @@ abstract class ObservedConfigList(val parent: ForgeConfigSpec.ConfigVal return parsedView[index] } } - -fun ForgeConfigSpec.Builder.defineObjectList( - name: String, - defaultValues: () -> List, - write: (value: T) -> Pair?, - read: (value: String) -> T? -): ObservedConfigList { - val parent = defineListAllowEmpty(name.split('.'), { defaultValues.invoke().mapNotNull { write.invoke(it)?.first }.toMutableList()}, { it is String }) as ForgeConfigSpec.ConfigValue> - - return object : ObservedConfigList(parent) { - override fun toString(value: T): Pair? { - return write.invoke(value) - } - - override fun fromString(value: String): T? { - return read.invoke(value) - } - } -} - -@Deprecated("Obviously better use tags") -fun ForgeConfigSpec.Builder.defineForgeObjectList( - name: String, - defaultValues: () -> List, - registry: IForgeRegistry -): ObservedConfigList { - return defineObjectList(name, defaultValues, - write = { (registry.getKey(it)?.toString() ?: return@defineObjectList null) to it }, - read = { registry.getValue(ResourceLocation(it)) }) -} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/android/AndroidActiveFeature.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/android/AndroidActiveFeature.kt index 93eea6d6e..ff8d06398 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/android/AndroidActiveFeature.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/android/AndroidActiveFeature.kt @@ -2,10 +2,10 @@ package ru.dbotthepony.mc.otm.android import com.mojang.blaze3d.vertex.PoseStack import net.minecraft.client.Camera -import net.minecraftforge.client.event.RenderLevelStageEvent -import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability +import net.neoforged.neoforge.client.event.RenderLevelStageEvent +import ru.dbotthepony.mc.otm.capability.MatteryPlayer -abstract class AndroidActiveFeature(type: AndroidFeatureType<*>, android: MatteryPlayerCapability) : AndroidSwitchableFeature(type, android) { +abstract class AndroidActiveFeature(type: AndroidFeatureType<*>, android: MatteryPlayer) : AndroidSwitchableFeature(type, android) { /** * return true to send packet to server if [isClient] is true * diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/android/AndroidFeature.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/android/AndroidFeature.kt index 9fa3c0348..b7cdbbb44 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/android/AndroidFeature.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/android/AndroidFeature.kt @@ -1,18 +1,18 @@ package ru.dbotthepony.mc.otm.android import it.unimi.dsi.fastutil.io.FastByteArrayOutputStream +import net.minecraft.core.HolderLookup import net.minecraft.nbt.CompoundTag -import net.minecraftforge.common.util.INBTSerializable -import net.minecraftforge.event.entity.living.LivingAttackEvent -import net.minecraftforge.event.entity.living.LivingHurtEvent +import net.neoforged.neoforge.common.util.INBTSerializable +import net.neoforged.neoforge.event.entity.living.LivingIncomingDamageEvent import ru.dbotthepony.kommons.io.DelegateSyncher import ru.dbotthepony.kommons.util.getValue import ru.dbotthepony.kommons.util.setValue -import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability +import ru.dbotthepony.mc.otm.capability.MatteryPlayer import ru.dbotthepony.mc.otm.core.nbt.set import java.io.InputStream -abstract class AndroidFeature(val type: AndroidFeatureType<*>, val android: MatteryPlayerCapability) : INBTSerializable { +abstract class AndroidFeature(val type: AndroidFeatureType<*>, val android: MatteryPlayer) : INBTSerializable { val ply get() = android.ply val syncher = DelegateSyncher() val syncherRemote = syncher.Remote() @@ -37,8 +37,7 @@ abstract class AndroidFeature(val type: AndroidFeatureType<*>, val android: Matt open fun applyModifiers() {} open fun removeModifiers() {} - open fun onHurt(event: LivingHurtEvent) {} - open fun onAttack(event: LivingAttackEvent) {} + open fun onHurt(event: LivingIncomingDamageEvent) {} open fun collectNetworkPayload(): FastByteArrayOutputStream? { syncher.observe() @@ -49,23 +48,23 @@ abstract class AndroidFeature(val type: AndroidFeatureType<*>, val android: Matt syncher.read(stream) } - override fun serializeNBT(): CompoundTag { + override fun serializeNBT(registry: HolderLookup.Provider): CompoundTag { return CompoundTag().also { it["level"] = level } } - override fun deserializeNBT(nbt: CompoundTag) { + override fun deserializeNBT(registry: HolderLookup.Provider, nbt: CompoundTag) { level = nbt.getInt("level") } } -class DummyAndroidFeature(type: AndroidFeatureType<*>, android: MatteryPlayerCapability) : AndroidFeature(type, android) { - override fun serializeNBT(): CompoundTag { +class DummyAndroidFeature(type: AndroidFeatureType<*>, android: MatteryPlayer) : AndroidFeature(type, android) { + override fun serializeNBT(registry: HolderLookup.Provider): CompoundTag { return CompoundTag() } - override fun deserializeNBT(nbt: CompoundTag) { + override fun deserializeNBT(registry: HolderLookup.Provider, nbt: CompoundTag) { } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/android/AndroidFeatureType.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/android/AndroidFeatureType.kt index 4a3da406a..43c6d78ca 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/android/AndroidFeatureType.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/android/AndroidFeatureType.kt @@ -4,26 +4,26 @@ 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.capability.MatteryPlayerCapability +import ru.dbotthepony.mc.otm.capability.MatteryPlayer import ru.dbotthepony.mc.otm.core.getKeyNullable import ru.dbotthepony.mc.otm.registry.MRegistry open class AndroidFeatureType { - protected val factory: (AndroidFeatureType, MatteryPlayerCapability) -> T + protected val factory: (AndroidFeatureType, MatteryPlayer) -> T - constructor(factory: (MatteryPlayerCapability) -> T) : super() { + constructor(factory: (MatteryPlayer) -> T) : super() { this.factory = { _, capability -> factory.invoke(capability) } } - constructor(factory: (AndroidFeatureType, MatteryPlayerCapability) -> T) : super() { + constructor(factory: (AndroidFeatureType, MatteryPlayer) -> T) : super() { this.factory = factory } - fun create(android: MatteryPlayerCapability): T { + fun create(android: MatteryPlayer): T { return factory.invoke(this, android) } - open fun isApplicable(android: MatteryPlayerCapability) = true + open fun isApplicable(android: MatteryPlayer) = true val registryName by lazy { MRegistry.ANDROID_FEATURES.getKeyNullable(this) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/android/AndroidResearch.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/android/AndroidResearch.kt index 30c5a743e..aeb204908 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/android/AndroidResearch.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/android/AndroidResearch.kt @@ -2,19 +2,19 @@ package ru.dbotthepony.mc.otm.android import it.unimi.dsi.fastutil.io.FastByteArrayOutputStream import net.minecraft.ChatFormatting +import net.minecraft.core.HolderLookup import net.minecraft.nbt.CompoundTag import net.minecraft.network.chat.Component import net.minecraft.server.level.ServerPlayer import net.minecraft.world.entity.player.Player -import net.minecraftforge.common.MinecraftForge -import net.minecraftforge.common.util.INBTSerializable -import net.minecraftforge.eventbus.api.Event -import net.minecraftforge.eventbus.api.Event.HasResult +import net.neoforged.bus.api.Event +import net.neoforged.neoforge.common.NeoForge +import net.neoforged.neoforge.common.util.INBTSerializable import ru.dbotthepony.kommons.io.DelegateSyncher import ru.dbotthepony.kommons.util.getValue import ru.dbotthepony.kommons.util.setValue import ru.dbotthepony.mc.otm.OverdriveThatMatters -import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability +import ru.dbotthepony.mc.otm.capability.MatteryPlayer import ru.dbotthepony.mc.otm.capability.awareItemsStream import ru.dbotthepony.mc.otm.core.TextComponent import ru.dbotthepony.mc.otm.core.TranslatableComponent @@ -25,33 +25,27 @@ import ru.dbotthepony.mc.otm.triggers.AndroidResearchTrigger import java.io.InputStream import kotlin.math.absoluteValue -class AndroidResearch(val type: AndroidResearchType, val capability: MatteryPlayerCapability) : INBTSerializable { +class AndroidResearch(val type: AndroidResearchType, val capability: MatteryPlayer) : INBTSerializable { /** - * Fired on main event bus [MinecraftForge.EVENT_BUS] + * Fired on main event bus [NeoForge.EVENT_BUS] */ data class OnResearched(val research: AndroidResearch) : Event() /** - * Fired on main event bus [MinecraftForge.EVENT_BUS] + * Fired on main event bus [NeoForge.EVENT_BUS] */ data class OnUnResearched(val research: AndroidResearch) : Event() /** - * Fired on main event bus [MinecraftForge.EVENT_BUS] + * Fired on main event bus [NeoForge.EVENT_BUS] */ data class OnRefunded(val research: AndroidResearch) : Event() /** - * Fired on main event bus [MinecraftForge.EVENT_BUS] + * Fired on main event bus [NeoForge.EVENT_BUS] */ data class GatherTooltipsEvent(val research: AndroidResearch, val tooltips: MutableList) : Event() - /** - * Fired on main event bus [MinecraftForge.EVENT_BUS] - */ - @HasResult - data class ConsumeResearchCost(val research: AndroidResearch, val isSimulating: Boolean) : Event() - val ply: Player get() = capability.ply val syncher = DelegateSyncher() @@ -84,7 +78,7 @@ class AndroidResearch(val type: AndroidResearchType, val capability: MatteryPlay result.onUnResearched(this) } - MinecraftForge.EVENT_BUS.post(OnUnResearched(this)) + NeoForge.EVENT_BUS.post(OnUnResearched(this)) } fun onResearched() { @@ -92,7 +86,7 @@ class AndroidResearch(val type: AndroidResearchType, val capability: MatteryPlay result.onResearched(this) } - MinecraftForge.EVENT_BUS.post(OnResearched(this)) + NeoForge.EVENT_BUS.post(OnResearched(this)) } /** @@ -108,15 +102,6 @@ class AndroidResearch(val type: AndroidResearchType, val capability: MatteryPlay return true } - val event = ConsumeResearchCost(this, simulate) - MinecraftForge.EVENT_BUS.post(event) - - if (event.result == Event.Result.ALLOW) { - return true - } else if (event.result == Event.Result.DENY) { - return false - } - if (!simulate && !consumeResearchCost(true)) { return false } @@ -183,7 +168,7 @@ class AndroidResearch(val type: AndroidResearchType, val capability: MatteryPlay } } - MinecraftForge.EVENT_BUS.post(OnRefunded(this)) + NeoForge.EVENT_BUS.post(OnRefunded(this)) return true } @@ -300,7 +285,7 @@ class AndroidResearch(val type: AndroidResearchType, val capability: MatteryPlay line.addLines(this, lines) } - MinecraftForge.EVENT_BUS.post(GatherTooltipsEvent(this, lines)) + NeoForge.EVENT_BUS.post(GatherTooltipsEvent(this, lines)) return lines } @@ -382,14 +367,14 @@ class AndroidResearch(val type: AndroidResearchType, val capability: MatteryPlay */ val screenTooltipHeader: Component get() = type.displayName - override fun serializeNBT(): CompoundTag { + override fun serializeNBT(registry: HolderLookup.Provider): CompoundTag { return CompoundTag().also { it["researched"] = isResearched it["tag"] = tag } } - override fun deserializeNBT(nbt: CompoundTag) { + override fun deserializeNBT(registry: HolderLookup.Provider, nbt: CompoundTag) { isResearched = nbt.getBoolean("researched") tag = nbt.getCompound("tag") } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/android/AndroidResearchDataProvider.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/android/AndroidResearchDataProvider.kt index 98d175bfc..1ca529af2 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/android/AndroidResearchDataProvider.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/android/AndroidResearchDataProvider.kt @@ -6,8 +6,7 @@ import net.minecraft.data.CachedOutput import net.minecraft.data.DataProvider import net.minecraft.data.PackOutput import net.minecraft.resources.ResourceLocation -import net.minecraftforge.data.event.GatherDataEvent -import ru.dbotthepony.mc.otm.core.toJson +import net.neoforged.neoforge.data.event.GatherDataEvent import ru.dbotthepony.mc.otm.core.toJsonStrict import ru.dbotthepony.mc.otm.core.util.WriteOnce import java.util.Collections diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/android/AndroidResearchDescription.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/android/AndroidResearchDescription.kt index e5b2f2a81..44b450b0d 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/android/AndroidResearchDescription.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/android/AndroidResearchDescription.kt @@ -2,11 +2,12 @@ package ru.dbotthepony.mc.otm.android import com.mojang.datafixers.util.Either import com.mojang.serialization.Codec +import com.mojang.serialization.MapCodec import com.mojang.serialization.codecs.RecordCodecBuilder import net.minecraft.ChatFormatting import net.minecraft.network.chat.Component -import net.minecraftforge.eventbus.api.IEventBus -import net.minecraftforge.registries.DeferredRegister +import net.minecraft.network.chat.ComponentSerialization +import net.neoforged.bus.api.IEventBus import ru.dbotthepony.kommons.util.getValue import ru.dbotthepony.mc.otm.OverdriveThatMatters import ru.dbotthepony.mc.otm.client.ShiftPressedCond @@ -15,19 +16,19 @@ import ru.dbotthepony.mc.otm.core.TextComponent import ru.dbotthepony.mc.otm.core.TranslatableComponent import ru.dbotthepony.mc.otm.core.getValue import ru.dbotthepony.mc.otm.core.util.formatPower -import ru.dbotthepony.mc.otm.data.ComponentCodec import ru.dbotthepony.mc.otm.data.SingletonCodec import ru.dbotthepony.mc.otm.data.simpleCodec +import ru.dbotthepony.mc.otm.registry.MDeferredRegister import ru.dbotthepony.mc.otm.registry.RegistryDelegate object AndroidResearchDescriptions { - private val registrar = DeferredRegister.create(AndroidResearchDescription.registryKey, OverdriveThatMatters.MOD_ID) + private val registrar = MDeferredRegister(AndroidResearchDescription.registryKey, OverdriveThatMatters.MOD_ID) init { registrar.register("plain") { PlainAndroidResearchDescription } } - internal fun register(bus: IEventBus) { + fun register(bus: IEventBus) { registrar.register(bus) } @@ -73,11 +74,11 @@ interface AndroidResearchDescription { * Type, representing raw description populator in registry */ interface Type { - val codec: Codec + val codec: MapCodec } abstract class Singleton : AndroidResearchDescription, Type { - override val codec = SingletonCodec(this) + override val codec: MapCodec = MapCodec.unit(this) override val type: Type<*> get() = this } @@ -92,8 +93,8 @@ interface AndroidResearchDescription { get() = this@Leveled } - override val codec: Codec by lazy { - RecordCodecBuilder.create { + override val codec: MapCodec by lazy { + RecordCodecBuilder.mapCodec { it.group(Codec.INT.fieldOf("level").forGetter(Instance::level)).apply(it, ::Instance) } } @@ -103,18 +104,16 @@ interface AndroidResearchDescription { val type: Type<*> companion object { - private val delegate = RegistryDelegate>("android_research_description") { - disableSaving() - } + private val delegate = RegistryDelegate>("android_research_description") {} val registry by delegate val registryKey get() = delegate.key val CODEC: Codec by lazy { - registry.codec.dispatch({ it.type }, { it.codec }) + registry.byNameCodec().dispatch({ it.type }, { it.codec }) } - internal fun register(bus: IEventBus) { + fun register(bus: IEventBus) { bus.addListener(delegate::build) } @@ -140,9 +139,11 @@ object PlainAndroidResearchDescription : AndroidResearchDescription.Type by lazy { - Codec - .either(ComponentCodec, simpleCodec(::Instance, Instance::line, ComponentCodec)) - .xmap({ c -> c.map({ Instance(it) }, { it }) }, { c -> Either.left(c.line) }) + override val codec: MapCodec by lazy { + RecordCodecBuilder.mapCodec { + it.group( + ComponentSerialization.CODEC.fieldOf("line").forGetter { it.line } + ).apply(it, ::Instance) + } } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/android/AndroidResearchManager.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/android/AndroidResearchManager.kt index 86eaa2846..5190b4dd0 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/android/AndroidResearchManager.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/android/AndroidResearchManager.kt @@ -7,28 +7,31 @@ import com.google.gson.JsonObject import com.google.gson.JsonSyntaxException import net.minecraft.client.server.IntegratedServer import net.minecraft.network.FriendlyByteBuf +import net.minecraft.network.codec.StreamCodec +import net.minecraft.network.protocol.common.custom.CustomPacketPayload import net.minecraft.resources.ResourceLocation +import net.minecraft.server.level.ServerPlayer import net.minecraft.server.packs.resources.ResourceManager import net.minecraft.server.packs.resources.SimpleJsonResourceReloadListener import net.minecraft.util.profiling.ProfilerFiller -import net.minecraftforge.event.AddReloadListenerEvent -import net.minecraftforge.event.OnDatapackSyncEvent -import net.minecraftforge.network.PacketDistributor +import net.neoforged.neoforge.event.AddReloadListenerEvent +import net.neoforged.neoforge.event.OnDatapackSyncEvent +import net.neoforged.neoforge.network.PacketDistributor +import net.neoforged.neoforge.network.handling.IPayloadContext import org.apache.logging.log4j.LogManager import ru.dbotthepony.mc.otm.MINECRAFT_SERVER import ru.dbotthepony.mc.otm.NULLABLE_MINECRAFT_SERVER +import ru.dbotthepony.mc.otm.OverdriveThatMatters import ru.dbotthepony.mc.otm.SERVER_IS_LIVE import ru.dbotthepony.mc.otm.capability.matteryPlayer import ru.dbotthepony.mc.otm.client.minecraft +import ru.dbotthepony.mc.otm.core.ResourceLocation import ru.dbotthepony.mc.otm.core.fromJsonStrict import ru.dbotthepony.mc.otm.core.fromNetwork import ru.dbotthepony.mc.otm.core.set import ru.dbotthepony.mc.otm.core.toNetwork -import ru.dbotthepony.mc.otm.network.GenericNetworkChannel -import ru.dbotthepony.mc.otm.network.MNetworkContext -import ru.dbotthepony.mc.otm.network.MatteryPacket import ru.dbotthepony.mc.otm.onceServer -import java.util.LinkedList +import java.util.* object AndroidResearchManager : SimpleJsonResourceReloadListener(GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create(), "otm_android_research"), Iterable { const val DIRECTORY = "otm_android_research" @@ -85,7 +88,7 @@ object AndroidResearchManager : SimpleJsonResourceReloadListener(GsonBuilder().s if (SERVER_IS_LIVE) { onceServer { for (ply in MINECRAFT_SERVER.playerList.players) { - ply.matteryPlayer?.reloadResearch() + ply.matteryPlayer.reloadResearch() } } } @@ -99,21 +102,22 @@ object AndroidResearchManager : SimpleJsonResourceReloadListener(GsonBuilder().s val packet = SyncPacket(researchMap.values) if (event.player != null) { - GenericNetworkChannel.send(event.player!!, packet) + PacketDistributor.sendToPlayer(event.player as ServerPlayer, packet) } else { - GenericNetworkChannel.send(PacketDistributor.ALL.noArg(), packet) + PacketDistributor.sendToAllPlayers(packet) } } - class SyncPacket(val collection: Collection) : MatteryPacket { - override fun write(buff: FriendlyByteBuf) { + val SYNC_TYPE = CustomPacketPayload.Type(ResourceLocation(OverdriveThatMatters.MOD_ID, "research_sync")) + val SYNC_CODEC: StreamCodec = StreamCodec.ofMember(SyncPacket::write, ::readSyncPacket) + + class SyncPacket(val collection: Collection) : CustomPacketPayload { + fun write(buff: FriendlyByteBuf) { buff.writeCollection(collection) { a, b -> AndroidResearchType.CODEC.toNetwork(a, b) } LOGGER.debug("Constructed android research registry packet, ${buff.writerIndex()} bytes in size") } - override fun play(context: MNetworkContext) { - context.packetHandled = true - + fun play(context: IPayloadContext) { if (NULLABLE_MINECRAFT_SERVER is IntegratedServer) return @@ -133,6 +137,10 @@ object AndroidResearchManager : SimpleJsonResourceReloadListener(GsonBuilder().s minecraft.player?.matteryPlayer?.reloadResearch() } } + + override fun type(): CustomPacketPayload.Type { + return SYNC_TYPE + } } fun readSyncPacket(buff: FriendlyByteBuf): SyncPacket { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/android/AndroidResearchResult.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/android/AndroidResearchResult.kt index d83324d76..3e2d74dfe 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/android/AndroidResearchResult.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/android/AndroidResearchResult.kt @@ -2,21 +2,22 @@ package ru.dbotthepony.mc.otm.android import com.mojang.datafixers.util.Either import com.mojang.serialization.Codec +import com.mojang.serialization.MapCodec import com.mojang.serialization.codecs.RecordCodecBuilder import net.minecraft.resources.ResourceLocation -import net.minecraftforge.eventbus.api.IEventBus -import net.minecraftforge.registries.DeferredRegister +import net.neoforged.bus.api.IEventBus import org.apache.logging.log4j.LogManager import ru.dbotthepony.kommons.util.getValue import ru.dbotthepony.mc.otm.OverdriveThatMatters import ru.dbotthepony.mc.otm.core.getValue import ru.dbotthepony.mc.otm.data.SingletonCodec import ru.dbotthepony.mc.otm.registry.AndroidFeatures +import ru.dbotthepony.mc.otm.registry.MDeferredRegister import ru.dbotthepony.mc.otm.registry.MRegistry import ru.dbotthepony.mc.otm.registry.RegistryDelegate object AndroidResearchResults { - private val registrar = DeferredRegister.create(AndroidResearchResult.registryKey, OverdriveThatMatters.MOD_ID) + private val registrar = MDeferredRegister(AndroidResearchResult.registryKey, OverdriveThatMatters.MOD_ID) init { registrar.register("feature") { AndroidResearchResult.Feature.Companion } @@ -24,7 +25,7 @@ object AndroidResearchResults { } private object NanobotsArmorStrength : AndroidResearchResult.Singleton { - override val codec: Codec = SingletonCodec(this) + override val codec: MapCodec = MapCodec.unit(this) override val type: AndroidResearchResult.Type<*> get() = this @@ -40,7 +41,7 @@ object AndroidResearchResults { } private object NanobotsArmorSpeed : AndroidResearchResult.Singleton { - override val codec: Codec = SingletonCodec(this) + override val codec: MapCodec = MapCodec.unit(this) override val type: AndroidResearchResult.Type<*> get() = this @@ -58,14 +59,14 @@ object AndroidResearchResults { val NANOBOTS_ARMOR_STRENGTH: AndroidResearchResult.Singleton<*> by registrar.register("nanobots_armor_strength") { NanobotsArmorStrength } val NANOBOTS_ARMOR_SPEED: AndroidResearchResult.Singleton<*> by registrar.register("nanobots_armor_speed") { NanobotsArmorSpeed } - internal fun register(bus: IEventBus) { + fun register(bus: IEventBus) { registrar.register(bus) } } interface AndroidResearchResult { interface Type { - val codec: Codec + val codec: MapCodec } interface Singleton> : Type, AndroidResearchResult @@ -74,7 +75,7 @@ interface AndroidResearchResult { * Adds specific android feature [id] to target, does nothing if target already has specified feature */ class Feature(val id: ResourceLocation, val optional: Boolean = false) : AndroidResearchResult { - val feature = MRegistry.ANDROID_FEATURES.getValue(id) ?: if (optional) null else throw NoSuchElementException("Unknown android feature $id") + val feature = MRegistry.ANDROID_FEATURES.get(id) ?: if (optional) null else throw NoSuchElementException("Unknown android feature $id") override val type: Type<*> get() = Companion @@ -108,7 +109,7 @@ interface AndroidResearchResult { * Increases level of specific android feature [id] by specified amount [levels] */ class FeatureLevel(val id: ResourceLocation, val optional: Boolean = false, val levels: Int = 1) : AndroidResearchResult { - val feature = MRegistry.ANDROID_FEATURES.getValue(id) ?: if (optional) null else throw NoSuchElementException("Unknown android feature $id") + val feature = MRegistry.ANDROID_FEATURES.get(id) ?: if (optional) null else throw NoSuchElementException("Unknown android feature $id") override val type: Type<*> get() = Companion @@ -165,18 +166,16 @@ interface AndroidResearchResult { companion object { private val LOGGER = LogManager.getLogger() - private val delegate = RegistryDelegate>("android_research_result") { - disableSaving() - } + private val delegate = RegistryDelegate>("android_research_result") {} val registry by delegate val registryKey get() = delegate.key val CODEC: Codec by lazy { - registry.codec.dispatch({ it.type }, { it.codec }) + registry.byNameCodec().dispatch({ it.type }, { it.codec }) } - internal fun register(bus: IEventBus) { + fun register(bus: IEventBus) { bus.addListener(delegate::build) } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/android/AndroidResearchType.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/android/AndroidResearchType.kt index ad2610563..2c87d3625 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/android/AndroidResearchType.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/android/AndroidResearchType.kt @@ -8,8 +8,10 @@ import com.mojang.serialization.Codec import com.mojang.serialization.codecs.ListCodec import com.mojang.serialization.codecs.RecordCodecBuilder import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet +import net.minecraft.core.registries.BuiltInRegistries import net.minecraft.network.chat.Component import net.minecraft.network.chat.ComponentContents +import net.minecraft.network.chat.ComponentSerialization import net.minecraft.network.chat.MutableComponent import net.minecraft.network.chat.contents.TranslatableContents import net.minecraft.resources.ResourceLocation @@ -18,13 +20,10 @@ import net.minecraft.world.item.Item import net.minecraft.world.item.ItemStack import net.minecraft.world.item.crafting.Ingredient import net.minecraft.world.level.ItemLike -import net.minecraftforge.registries.ForgeRegistries import ru.dbotthepony.mc.otm.client.render.sprites.AbstractMatterySprite import ru.dbotthepony.mc.otm.client.render.sprites.SpriteType import ru.dbotthepony.mc.otm.core.collect.ListSet import ru.dbotthepony.mc.otm.core.TranslatableComponent -import ru.dbotthepony.mc.otm.core.isActuallyEmpty -import ru.dbotthepony.mc.otm.data.ComponentCodec import ru.dbotthepony.mc.otm.data.JsonElementCodec import ru.dbotthepony.mc.otm.isClient import java.util.Optional @@ -181,7 +180,7 @@ class AndroidResearchType( private val definedItems: List> = ImmutableList.copyOf(items) val results: ImmutableList = ImmutableList.copyOf(results) - val items: Stream> get() = definedItems.stream().filter { !it.first.isActuallyEmpty } + val items: Stream> get() = definedItems.stream().filter { !it.first.hasNoItems() } val description: ImmutableList = ImmutableList.copyOf(description) /** @@ -387,9 +386,9 @@ class AndroidResearchType( RecordCodecBuilder.create { it.group( ResourceLocation.CODEC.fieldOf("id").forGetter(AndroidResearchType::id), - ListCodec(Reference.CODEC).fieldOf("prerequisites").forGetter(AndroidResearchType::prerequisites), - ListCodec(Reference.CODEC).fieldOf("blockedBy").forGetter(AndroidResearchType::blockedBy), - ListCodec( + Codec.list(Reference.CODEC).fieldOf("prerequisites").forGetter(AndroidResearchType::prerequisites), + Codec.list(Reference.CODEC).fieldOf("blockedBy").forGetter(AndroidResearchType::blockedBy), + Codec.list( RecordCodecBuilder.create> { it.group( Ingredient.CODEC.fieldOf("item").forGetter { it.first }, @@ -397,13 +396,13 @@ class AndroidResearchType( ).apply(it, ::Pair) } ).fieldOf("items").forGetter { it.definedItems }, - ListCodec(AndroidResearchResult.CODEC).fieldOf("results").forGetter(AndroidResearchType::results), - ListCodec(AndroidResearchDescription.CODEC).fieldOf("description").forGetter(AndroidResearchType::description), + Codec.list(AndroidResearchResult.CODEC).fieldOf("results").forGetter(AndroidResearchType::results), + Codec.list(AndroidResearchDescription.CODEC).fieldOf("description").forGetter(AndroidResearchType::description), Codec.intRange(0, Int.MAX_VALUE).fieldOf("experienceLevels").forGetter(AndroidResearchType::experienceLevels), - ComponentCodec.optionalFieldOf("customName").forGetter { Optional.ofNullable(it.customName) }, + ComponentSerialization.CODEC.optionalFieldOf("customName").forGetter { Optional.ofNullable(it.customName) }, JsonElementCodec.xmap({ it as? JsonObject ?: throw JsonSyntaxException("Not a json object: $it") }, { it }).optionalFieldOf("skinIcon").forGetter { Optional.ofNullable(it.skinIcon) }, - ForgeRegistries.ITEMS.codec.optionalFieldOf("itemIcon").forGetter { Optional.ofNullable(it.itemIcon) }, - ComponentCodec.optionalFieldOf("iconTextValue").forGetter { Optional.ofNullable(it.iconTextValue) }, + BuiltInRegistries.ITEM.byNameCodec().optionalFieldOf("itemIcon").forGetter { Optional.ofNullable(it.itemIcon) }, + ComponentSerialization.CODEC.optionalFieldOf("iconTextValue").forGetter { Optional.ofNullable(it.iconTextValue) }, ).apply(it, ::AndroidResearchType) } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/android/AndroidSwitchableFeature.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/android/AndroidSwitchableFeature.kt index 6563b1066..021c03993 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/android/AndroidSwitchableFeature.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/android/AndroidSwitchableFeature.kt @@ -1,17 +1,18 @@ package ru.dbotthepony.mc.otm.android import net.minecraft.client.multiplayer.ClientLevel +import net.minecraft.core.HolderLookup import net.minecraft.nbt.CompoundTag import net.minecraft.server.level.ServerPlayer import ru.dbotthepony.kommons.math.RGBAColor import ru.dbotthepony.kommons.util.getValue import ru.dbotthepony.kommons.util.setValue -import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability +import ru.dbotthepony.mc.otm.capability.MatteryPlayer import ru.dbotthepony.mc.otm.client.render.MGUIGraphics import ru.dbotthepony.mc.otm.client.minecraft import ru.dbotthepony.mc.otm.core.nbt.set -abstract class AndroidSwitchableFeature(type: AndroidFeatureType<*>, android: MatteryPlayerCapability) : AndroidFeature(type, android) { +abstract class AndroidSwitchableFeature(type: AndroidFeatureType<*>, android: MatteryPlayer) : AndroidFeature(type, android) { var isActive by syncher.boolean(setter = setter@{ access, value -> if (value != access.get()) { access.accept(value) @@ -52,15 +53,15 @@ abstract class AndroidSwitchableFeature(type: AndroidFeatureType<*>, android: Ma // but it doesn't seem to cause issues? abstract fun renderIcon(graphics: MGUIGraphics, x: Float, y: Float, width: Float, height: Float, color: RGBAColor = RGBAColor.WHITE) - override fun serializeNBT(): CompoundTag { - return super.serializeNBT().also { + override fun serializeNBT(registry: HolderLookup.Provider): CompoundTag { + return super.serializeNBT(registry).also { it["isActive"] = isActive it["cooldown"] = cooldown } } - override fun deserializeNBT(nbt: CompoundTag) { - super.deserializeNBT(nbt) + override fun deserializeNBT(registry: HolderLookup.Provider, nbt: CompoundTag) { + super.deserializeNBT(registry, nbt) isActive = nbt.getBoolean("isActive") cooldown = nbt.getInt("cooldown") } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/AttackBoostFeature.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/AttackBoostFeature.kt index b04db591f..1a2d2809c 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/AttackBoostFeature.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/AttackBoostFeature.kt @@ -3,11 +3,11 @@ package ru.dbotthepony.mc.otm.android.feature import net.minecraft.world.entity.ai.attributes.AttributeModifier import net.minecraft.world.entity.ai.attributes.Attributes import ru.dbotthepony.mc.otm.android.AndroidFeature -import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability +import ru.dbotthepony.mc.otm.capability.MatteryPlayer import ru.dbotthepony.mc.otm.registry.AndroidFeatures import java.util.* -class AttackBoostFeature(android: MatteryPlayerCapability) : AndroidFeature(AndroidFeatures.ATTACK_BOOST, android) { +class AttackBoostFeature(android: MatteryPlayer) : AndroidFeature(AndroidFeatures.ATTACK_BOOST, android) { override fun applyModifiers() { val modifier = ply.getAttribute(Attributes.ATTACK_DAMAGE) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/EnderTeleporterFeature.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/EnderTeleporterFeature.kt index 196470827..dd2b85ce3 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/EnderTeleporterFeature.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/EnderTeleporterFeature.kt @@ -20,22 +20,23 @@ import net.minecraft.world.phys.HitResult import net.minecraft.world.phys.shapes.BooleanOp import net.minecraft.world.phys.shapes.CollisionContext import net.minecraft.world.phys.shapes.Shapes -import net.minecraftforge.client.event.RenderLevelStageEvent -import net.minecraftforge.event.ForgeEventFactory -import net.minecraftforge.event.entity.living.LivingDeathEvent +import net.neoforged.neoforge.client.event.RenderLevelStageEvent +import net.neoforged.neoforge.event.EventHooks +import net.neoforged.neoforge.event.entity.living.LivingDeathEvent import ru.dbotthepony.kommons.math.RGBAColor import ru.dbotthepony.mc.otm.NULLABLE_MINECRAFT_SERVER import ru.dbotthepony.mc.otm.OverdriveThatMatters import ru.dbotthepony.mc.otm.android.AndroidActiveFeature -import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability +import ru.dbotthepony.mc.otm.capability.MatteryPlayer import ru.dbotthepony.mc.otm.capability.energy.extractEnergyExact import ru.dbotthepony.mc.otm.capability.matteryPlayer -import ru.dbotthepony.mc.otm.client.render.MGUIGraphics import ru.dbotthepony.mc.otm.client.render.DynamicBufferSource +import ru.dbotthepony.mc.otm.client.render.MGUIGraphics import ru.dbotthepony.mc.otm.client.render.ResearchIcons import ru.dbotthepony.mc.otm.client.render.linesIgnoreZRenderType import ru.dbotthepony.mc.otm.client.render.sprites.sprite import ru.dbotthepony.mc.otm.config.AndroidConfig +import ru.dbotthepony.mc.otm.core.ResourceLocation import ru.dbotthepony.mc.otm.core.genericPositions import ru.dbotthepony.mc.otm.core.holder import ru.dbotthepony.mc.otm.core.isFall @@ -55,7 +56,7 @@ import ru.dbotthepony.mc.otm.triggers.EnderTeleporterFallDeathTrigger import java.util.* import kotlin.math.sin -class EnderTeleporterFeature(capability: MatteryPlayerCapability) : AndroidActiveFeature(AndroidFeatures.ENDER_TELEPORTER, capability) { +class EnderTeleporterFeature(capability: MatteryPlayer) : AndroidActiveFeature(AndroidFeatures.ENDER_TELEPORTER, capability) { var lastTeleport = 0 private set @@ -299,7 +300,7 @@ class EnderTeleporterFeature(capability: MatteryPlayerCapability) : AndroidActiv val (blockPos) = trace() blockPos ?: return false - val event = ForgeEventFactory.onEnderTeleport(ply, blockPos.x + 0.5, blockPos.y.toDouble(), blockPos.z + 0.5) + val event = EventHooks.onEnderTeleport(ply, blockPos.x + 0.5, blockPos.y.toDouble(), blockPos.z + 0.5) if (event.isCanceled) { (ply as ServerPlayer).connection.send(ClientboundSoundEntityPacket(SoundEvents.ITEM_BREAK.holder, SoundSource.PLAYERS, ply, 0.3f, 0.5f, ply.level().random.nextLong())) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/ExtendedReachFeature.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/ExtendedReachFeature.kt index 270e08963..219e31a1a 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/ExtendedReachFeature.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/ExtendedReachFeature.kt @@ -1,31 +1,26 @@ package ru.dbotthepony.mc.otm.android.feature import net.minecraft.world.entity.ai.attributes.AttributeModifier -import net.minecraftforge.common.ForgeMod +import net.minecraft.world.entity.ai.attributes.Attributes +import ru.dbotthepony.mc.otm.OverdriveThatMatters import ru.dbotthepony.mc.otm.android.AndroidFeature -import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability +import ru.dbotthepony.mc.otm.capability.MatteryPlayer +import ru.dbotthepony.mc.otm.core.ResourceLocation import ru.dbotthepony.mc.otm.registry.AndroidFeatures -import java.util.* -class ExtendedReachFeature(android: MatteryPlayerCapability) : AndroidFeature(AndroidFeatures.EXTENDED_REACH, android) { +class ExtendedReachFeature(android: MatteryPlayer) : AndroidFeature(AndroidFeatures.EXTENDED_REACH, android) { override fun applyModifiers() { - if (!ForgeMod.BLOCK_REACH.isPresent) - return + val reach = ply.getAttribute(Attributes.BLOCK_INTERACTION_RANGE) ?: return - val reach = ply.getAttribute(ForgeMod.BLOCK_REACH.get()) ?: return - - reach.removePermanentModifier(MODIFIER_ID) - reach.addPermanentModifier(AttributeModifier(MODIFIER_ID, type.displayName.toString(), level + 1.0, AttributeModifier.Operation.ADDITION)) + reach.removeModifier(MODIFIER_ID) + reach.addPermanentModifier(AttributeModifier(MODIFIER_ID, level + 1.0, AttributeModifier.Operation.ADD_VALUE)) } override fun removeModifiers() { - if (!ForgeMod.BLOCK_REACH.isPresent) - return - - ply.getAttribute(ForgeMod.BLOCK_REACH.get())?.removePermanentModifier(MODIFIER_ID) + ply.getAttribute(Attributes.BLOCK_INTERACTION_RANGE)?.removeModifier(MODIFIER_ID) } companion object { - private val MODIFIER_ID = UUID.fromString("4a3fae46-47a8-a03f-857d-f5c2b2c8f2f2") + private val MODIFIER_ID = ResourceLocation(OverdriveThatMatters.MOD_ID, "android_extended_reach") } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/FallDampenersFeature.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/FallDampenersFeature.kt index 4b1b75900..900234f6f 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/FallDampenersFeature.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/FallDampenersFeature.kt @@ -1,24 +1,16 @@ package ru.dbotthepony.mc.otm.android.feature -import net.minecraft.ChatFormatting -import net.minecraft.resources.ResourceLocation import net.minecraft.server.level.ServerPlayer -import net.minecraftforge.event.entity.living.LivingAttackEvent -import net.minecraftforge.event.entity.living.LivingHurtEvent -import ru.dbotthepony.mc.otm.OverdriveThatMatters +import net.neoforged.neoforge.event.entity.living.LivingIncomingDamageEvent import ru.dbotthepony.mc.otm.android.AndroidFeature -import ru.dbotthepony.mc.otm.android.AndroidResearchManager -import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability +import ru.dbotthepony.mc.otm.capability.MatteryPlayer import ru.dbotthepony.mc.otm.config.AndroidConfig -import ru.dbotthepony.mc.otm.core.TextComponent -import ru.dbotthepony.mc.otm.core.TranslatableComponent import ru.dbotthepony.mc.otm.core.isFall import ru.dbotthepony.mc.otm.registry.AndroidFeatures -import ru.dbotthepony.mc.otm.registry.MNames import ru.dbotthepony.mc.otm.triggers.FallDampenersSaveTrigger -class FallDampenersFeature(capability: MatteryPlayerCapability) : AndroidFeature(AndroidFeatures.FALL_DAMPENERS, capability) { - override fun onHurt(event: LivingHurtEvent) { +class FallDampenersFeature(capability: MatteryPlayer) : AndroidFeature(AndroidFeatures.FALL_DAMPENERS, capability) { + override fun onHurt(event: LivingIncomingDamageEvent) { if (event.source.isFall) { val reduction = (AndroidConfig.FALL_DAMAGE_REDUCTION_PER_LEVEL_P * (level + 1)).toFloat().coerceIn(0f, 1f) val flat = (AndroidConfig.FALL_DAMAGE_REDUCTION_PER_LEVEL_F * (level + 1)).toFloat().coerceIn(0f, Float.MAX_VALUE) @@ -35,15 +27,4 @@ class FallDampenersFeature(capability: MatteryPlayerCapability) : AndroidFeature } } } - - override fun onAttack(event: LivingAttackEvent) { - if (event.source.isFall) { - val reduction = (AndroidConfig.FALL_DAMAGE_REDUCTION_PER_LEVEL_P * (level + 1)).toFloat().coerceIn(0f, 1f) - val flat = (AndroidConfig.FALL_DAMAGE_REDUCTION_PER_LEVEL_F * (level + 1)).toFloat().coerceIn(0f, Float.MAX_VALUE) - - if (reduction >= 1f || event.amount <= flat) { - event.isCanceled = true - } - } - } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/ItemMagnetFeature.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/ItemMagnetFeature.kt index bd0e622d1..e83d05050 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/ItemMagnetFeature.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/ItemMagnetFeature.kt @@ -2,25 +2,29 @@ package ru.dbotthepony.mc.otm.android.feature import net.minecraft.client.multiplayer.ClientLevel import net.minecraft.network.FriendlyByteBuf +import net.minecraft.network.codec.StreamCodec +import net.minecraft.network.protocol.common.custom.CustomPacketPayload +import net.minecraft.server.level.ServerPlayer import net.minecraft.world.entity.Entity import net.minecraft.world.entity.item.ItemEntity +import net.neoforged.neoforge.network.PacketDistributor +import net.neoforged.neoforge.network.handling.IPayloadContext import ru.dbotthepony.kommons.math.RGBAColor +import ru.dbotthepony.mc.otm.OverdriveThatMatters import ru.dbotthepony.mc.otm.config.AndroidConfig import ru.dbotthepony.mc.otm.android.AndroidSwitchableFeature -import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability +import ru.dbotthepony.mc.otm.capability.MatteryPlayer import ru.dbotthepony.mc.otm.capability.energy.extractEnergyExact import ru.dbotthepony.mc.otm.client.render.MGUIGraphics import ru.dbotthepony.mc.otm.client.minecraft import ru.dbotthepony.mc.otm.client.render.ResearchIcons +import ru.dbotthepony.mc.otm.core.ResourceLocation import ru.dbotthepony.mc.otm.core.math.Vector import ru.dbotthepony.mc.otm.core.getEntitiesInEllipsoid import ru.dbotthepony.mc.otm.core.math.minus import ru.dbotthepony.mc.otm.core.math.plus import ru.dbotthepony.mc.otm.core.position import ru.dbotthepony.mc.otm.core.math.times -import ru.dbotthepony.mc.otm.network.GenericNetworkChannel -import ru.dbotthepony.mc.otm.network.MNetworkContext -import ru.dbotthepony.mc.otm.network.MatteryPacket import ru.dbotthepony.mc.otm.registry.AndroidFeatures import java.util.UUID import java.util.WeakHashMap @@ -34,8 +38,8 @@ private data class SharedItemEntityData(val owner: UUID? = null, val age: Int = private val datatable = WeakHashMap() -class ItemEntityDataPacket(val itemUUID: Int, val owner: UUID? = null, val age: Int = 0, val lifespan: Int = 0, val hasPickupDelay: Boolean = true) : MatteryPacket { - override fun write(buff: FriendlyByteBuf) { +class ItemEntityDataPacket(val itemUUID: Int, val owner: UUID? = null, val age: Int = 0, val lifespan: Int = 0, val hasPickupDelay: Boolean = true) : CustomPacketPayload { + fun write(buff: FriendlyByteBuf) { buff.writeVarInt(itemUUID) buff.writeBoolean(owner != null) if (owner != null) buff.writeUUID(owner) @@ -44,20 +48,27 @@ class ItemEntityDataPacket(val itemUUID: Int, val owner: UUID? = null, val age: buff.writeBoolean(hasPickupDelay) } - override fun play(context: MNetworkContext) { + fun play(context: IPayloadContext) { val level = minecraft.player?.level() as ClientLevel? ?: return val entity = level.getEntity(itemUUID) as ItemEntity? ?: return datatable[entity] = SharedItemEntityData(owner, age, lifespan, hasPickupDelay) } + override fun type(): CustomPacketPayload.Type { + return TYPE + } + companion object { + val TYPE = CustomPacketPayload.Type(ResourceLocation(OverdriveThatMatters.MOD_ID, "item_entity_data")) + val CODEC: StreamCodec = StreamCodec.ofMember(ItemEntityDataPacket::write, ::read) + fun read(buff: FriendlyByteBuf): ItemEntityDataPacket { return ItemEntityDataPacket(buff.readVarInt(), if (buff.readBoolean()) buff.readUUID() else null, buff.readVarInt(), buff.readVarInt(), buff.readBoolean()) } } } -class ItemMagnetFeature(capability: MatteryPlayerCapability) : AndroidSwitchableFeature(AndroidFeatures.ITEM_MAGNET, capability) { +class ItemMagnetFeature(capability: MatteryPlayer) : AndroidSwitchableFeature(AndroidFeatures.ITEM_MAGNET, capability) { private data class ItemPos(var position: Vector, var ticksSinceActivity: Int) private val rememberPositions = WeakHashMap() @@ -79,7 +90,7 @@ class ItemMagnetFeature(capability: MatteryPlayerCapability) : AndroidSwitchable ent as ItemEntity if (server) { - GenericNetworkChannel.send(ply, ItemEntityDataPacket(ent.id, ent.owner?.uuid, ent.age, ent.lifespan, ent.hasPickUpDelay())) + PacketDistributor.sendToPlayer(ply as ServerPlayer, ItemEntityDataPacket(ent.id, ent.owner?.uuid, ent.age, ent.lifespan, ent.hasPickUpDelay())) if (!serverPredicate.test(ent)) { continue diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/JumpBoostFeature.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/JumpBoostFeature.kt index 4d0a3a502..bc8a5512a 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/JumpBoostFeature.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/JumpBoostFeature.kt @@ -1,57 +1,26 @@ package ru.dbotthepony.mc.otm.android.feature -import net.minecraft.network.FriendlyByteBuf import net.minecraft.server.level.ServerPlayer import net.minecraft.sounds.SoundSource +import net.neoforged.neoforge.network.PacketDistributor import ru.dbotthepony.kommons.math.RGBAColor import ru.dbotthepony.kommons.util.getValue import ru.dbotthepony.kommons.util.setValue import ru.dbotthepony.mc.otm.android.AndroidSwitchableFeature -import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability +import ru.dbotthepony.mc.otm.capability.MatteryPlayer import ru.dbotthepony.mc.otm.capability.energy.extractEnergyExact -import ru.dbotthepony.mc.otm.capability.matteryPlayer import ru.dbotthepony.mc.otm.client.render.MGUIGraphics import ru.dbotthepony.mc.otm.client.render.ResearchIcons import ru.dbotthepony.mc.otm.config.AndroidConfig import ru.dbotthepony.mc.otm.config.ClientConfig import ru.dbotthepony.mc.otm.core.math.Vector import ru.dbotthepony.mc.otm.core.math.plus -import ru.dbotthepony.mc.otm.network.GenericNetworkChannel -import ru.dbotthepony.mc.otm.network.MNetworkContext -import ru.dbotthepony.mc.otm.network.MatteryPacket -import ru.dbotthepony.mc.otm.network.MatteryPlayerNetworkChannel import ru.dbotthepony.mc.otm.network.SmokeParticlesPacket +import ru.dbotthepony.mc.otm.network.TriggerJumpBoostPacket import ru.dbotthepony.mc.otm.registry.AndroidFeatures import ru.dbotthepony.mc.otm.registry.MSoundEvents -object TriggerJumpBoostPacket : MatteryPacket { - override fun write(buff: FriendlyByteBuf) { - // no op - } - - override fun play(context: MNetworkContext) { - val mattery = context.sender?.matteryPlayer ?: return - - if (!mattery.isAndroid) - return - - val feature = mattery.getFeature(AndroidFeatures.JUMP_BOOST) ?: return - - if (feature.isActive && feature.cooldown <= 4 && mattery.androidEnergy.extractEnergyExact(AndroidConfig.JumpBoost.ENERGY_COST, false)) { - feature.putOnCooldown() - - context.sender.level().playSound( - context.sender, context.sender, - MSoundEvents.ANDROID_JUMP_BOOST, SoundSource.PLAYERS, - 1f, 1f - ) - - GenericNetworkChannel.makeSmoke(context.sender, context.sender.x, context.sender.y, context.sender.z) - } - } -} - -class JumpBoostFeature(capability: MatteryPlayerCapability) : AndroidSwitchableFeature(AndroidFeatures.JUMP_BOOST, capability) { +class JumpBoostFeature(capability: MatteryPlayer) : AndroidSwitchableFeature(AndroidFeatures.JUMP_BOOST, capability) { private var tickCooldownClient = false override val maxCooldown: Int @@ -80,7 +49,7 @@ class JumpBoostFeature(capability: MatteryPlayerCapability) : AndroidSwitchableF if (isActive && cooldown <= 0 && old != lastGround && !lastGround && isJumping && isShifting && ply.xRot <= ClientConfig.JUMP_BOOST_LOOK_ANGLE && android.androidEnergy.extractEnergyExact(AndroidConfig.JumpBoost.ENERGY_COST, true)) { ply.deltaMovement += Vector(0.0, AndroidConfig.JumpBoost.POWER * (level + 1) / 20.0, 0.0) putOnCooldown() - MatteryPlayerNetworkChannel.sendToServer(TriggerJumpBoostPacket) + PacketDistributor.sendToServer(TriggerJumpBoostPacket) ply.level().playSound( ply, ply, diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/LimbOverclockingFeature.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/LimbOverclockingFeature.kt index 8cc4a134a..eb8169153 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/LimbOverclockingFeature.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/LimbOverclockingFeature.kt @@ -4,36 +4,38 @@ import net.minecraft.world.entity.LivingEntity import net.minecraft.world.entity.ai.attributes.AttributeModifier import net.minecraft.world.entity.ai.attributes.Attributes import net.minecraft.world.entity.player.Player +import ru.dbotthepony.mc.otm.OverdriveThatMatters import ru.dbotthepony.mc.otm.android.AndroidFeature -import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability +import ru.dbotthepony.mc.otm.capability.MatteryPlayer import ru.dbotthepony.mc.otm.capability.matteryPlayer +import ru.dbotthepony.mc.otm.core.ResourceLocation import ru.dbotthepony.mc.otm.registry.AndroidFeatures import java.util.* -class LimbOverclockingFeature(android: MatteryPlayerCapability) : AndroidFeature(AndroidFeatures.LIMB_OVERCLOCKING, android) { +class LimbOverclockingFeature(android: MatteryPlayer) : AndroidFeature(AndroidFeatures.LIMB_OVERCLOCKING, android) { override fun applyModifiers() { val speed = ply.getAttribute(Attributes.MOVEMENT_SPEED) if (speed != null) { - speed.removePermanentModifier(MODIFIER_ID) - speed.addPermanentModifier(AttributeModifier(MODIFIER_ID, type.displayName.toString(), (level + 1) * 0.08, AttributeModifier.Operation.MULTIPLY_TOTAL)) + speed.removeModifier(MODIFIER_ID) + speed.addPermanentModifier(AttributeModifier(MODIFIER_ID,(level + 1) * 0.08, AttributeModifier.Operation.ADD_MULTIPLIED_TOTAL)) } val attackSpeed = ply.getAttribute(Attributes.ATTACK_SPEED) if (attackSpeed != null) { - attackSpeed.removePermanentModifier(MODIFIER_ID) - attackSpeed.addPermanentModifier(AttributeModifier(MODIFIER_ID, type.displayName.toString(), (level + 1) * 0.06, AttributeModifier.Operation.MULTIPLY_TOTAL)) + attackSpeed.removeModifier(MODIFIER_ID) + attackSpeed.addPermanentModifier(AttributeModifier(MODIFIER_ID, (level + 1) * 0.06, AttributeModifier.Operation.ADD_MULTIPLIED_TOTAL)) } } override fun removeModifiers() { - ply.getAttribute(Attributes.MOVEMENT_SPEED)?.removePermanentModifier(MODIFIER_ID) - ply.getAttribute(Attributes.ATTACK_SPEED)?.removePermanentModifier(MODIFIER_ID) + ply.getAttribute(Attributes.MOVEMENT_SPEED)?.removeModifier(MODIFIER_ID) + ply.getAttribute(Attributes.ATTACK_SPEED)?.removeModifier(MODIFIER_ID) } companion object { - private val MODIFIER_ID = UUID.fromString("4a3fae46-e57b-4e20-857d-f5c2b2c8f2f2") + private val MODIFIER_ID = ResourceLocation(OverdriveThatMatters.MOD_ID, "limb_overclocking") @JvmStatic fun getBrushCooldown(entity: LivingEntity): Int { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/NanobotsArmorFeature.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/NanobotsArmorFeature.kt index d51c19f5f..512117f6b 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/NanobotsArmorFeature.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/NanobotsArmorFeature.kt @@ -1,12 +1,13 @@ package ru.dbotthepony.mc.otm.android.feature +import net.minecraft.core.HolderLookup import net.minecraft.nbt.CompoundTag import net.minecraft.server.level.ServerPlayer -import net.minecraftforge.event.entity.living.LivingHurtEvent +import net.neoforged.neoforge.event.entity.living.LivingIncomingDamageEvent import ru.dbotthepony.kommons.util.getValue import ru.dbotthepony.kommons.util.setValue import ru.dbotthepony.mc.otm.android.AndroidFeature -import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability +import ru.dbotthepony.mc.otm.capability.MatteryPlayer import ru.dbotthepony.mc.otm.capability.energy.extractEnergyExact import ru.dbotthepony.mc.otm.core.isBypassArmor import ru.dbotthepony.mc.otm.core.math.Decimal @@ -17,7 +18,7 @@ import ru.dbotthepony.mc.otm.onceServer import ru.dbotthepony.mc.otm.triggers.NanobotsArmorTrigger import kotlin.math.roundToInt -class NanobotsArmorFeature(android: MatteryPlayerCapability) : AndroidFeature(AndroidFeatures.NANOBOTS_ARMOR, android) { +class NanobotsArmorFeature(android: MatteryPlayer) : AndroidFeature(AndroidFeatures.NANOBOTS_ARMOR, android) { var strength by syncher.int( setter = setter@{ access, value -> access.accept(value.coerceIn(0 .. 3)) } ) @@ -42,7 +43,7 @@ class NanobotsArmorFeature(android: MatteryPlayerCapability) : AndroidFeature(An } } - override fun onHurt(event: LivingHurtEvent) { + override fun onHurt(event: LivingIncomingDamageEvent) { ticksPassed = 0 if (!event.source.isBypassArmor && layers > 0) { @@ -69,8 +70,8 @@ class NanobotsArmorFeature(android: MatteryPlayerCapability) : AndroidFeature(An } } - override fun serializeNBT(): CompoundTag { - return super.serializeNBT().also { + override fun serializeNBT(registry: HolderLookup.Provider): CompoundTag { + return super.serializeNBT(registry).also { it["ticksPassed"] = ticksPassed it["layers"] = layers it["strength"] = strength @@ -78,8 +79,8 @@ class NanobotsArmorFeature(android: MatteryPlayerCapability) : AndroidFeature(An } } - override fun deserializeNBT(nbt: CompoundTag) { - super.deserializeNBT(nbt) + override fun deserializeNBT(registry: HolderLookup.Provider, nbt: CompoundTag) { + super.deserializeNBT(registry, nbt) ticksPassed = nbt.getInt("ticksPassed") layers = nbt.getInt("layers") strength = nbt.getInt("strength") diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/NanobotsRegenerationFeature.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/NanobotsRegenerationFeature.kt index b5cd2d73c..dda855383 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/NanobotsRegenerationFeature.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/NanobotsRegenerationFeature.kt @@ -1,18 +1,19 @@ package ru.dbotthepony.mc.otm.android.feature +import net.minecraft.core.HolderLookup import net.minecraft.nbt.CompoundTag import net.minecraft.server.level.ServerPlayer import net.minecraft.world.level.GameRules -import net.minecraftforge.event.entity.living.LivingHurtEvent +import net.neoforged.neoforge.event.entity.living.LivingIncomingDamageEvent import ru.dbotthepony.mc.otm.config.AndroidConfig import ru.dbotthepony.mc.otm.android.AndroidFeature -import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability +import ru.dbotthepony.mc.otm.capability.MatteryPlayer import ru.dbotthepony.mc.otm.registry.AndroidFeatures import ru.dbotthepony.mc.otm.registry.StatNames import ru.dbotthepony.mc.otm.core.nbt.set import kotlin.math.roundToInt -class NanobotsRegenerationFeature(android: MatteryPlayerCapability) : AndroidFeature(AndroidFeatures.NANOBOTS_REGENERATION, android) { +class NanobotsRegenerationFeature(android: MatteryPlayer) : AndroidFeature(AndroidFeatures.NANOBOTS_REGENERATION, android) { private var ticksPassed = 0 private var healTicks = 0 @@ -41,22 +42,22 @@ class NanobotsRegenerationFeature(android: MatteryPlayerCapability) : AndroidFea } } - override fun onHurt(event: LivingHurtEvent) { + override fun onHurt(event: LivingIncomingDamageEvent) { if (event.amount > 0f) { ticksPassed = 0 healTicks = 0 } } - override fun serializeNBT(): CompoundTag { - return super.serializeNBT().also { + override fun serializeNBT(registry: HolderLookup.Provider): CompoundTag { + return super.serializeNBT(registry).also { it["ticksPassed"] = ticksPassed it["healTicks"] = healTicks } } - override fun deserializeNBT(nbt: CompoundTag) { - super.deserializeNBT(nbt) + override fun deserializeNBT(registry: HolderLookup.Provider, nbt: CompoundTag) { + super.deserializeNBT(registry, nbt) ticksPassed = nbt.getInt("ticksPassed") healTicks = nbt.getInt("healTicks") } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/NightVisionFeature.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/NightVisionFeature.kt index 18572422f..d27e73fca 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/NightVisionFeature.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/NightVisionFeature.kt @@ -4,14 +4,14 @@ import net.minecraft.world.effect.MobEffectInstance import net.minecraft.world.effect.MobEffects import ru.dbotthepony.kommons.math.RGBAColor import ru.dbotthepony.mc.otm.android.AndroidSwitchableFeature -import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability +import ru.dbotthepony.mc.otm.capability.MatteryPlayer import ru.dbotthepony.mc.otm.capability.energy.extractEnergyExact import ru.dbotthepony.mc.otm.client.render.MGUIGraphics import ru.dbotthepony.mc.otm.client.render.ResearchIcons import ru.dbotthepony.mc.otm.config.AndroidConfig import ru.dbotthepony.mc.otm.registry.AndroidFeatures -class NightVisionFeature(android: MatteryPlayerCapability) : AndroidSwitchableFeature(AndroidFeatures.NIGHT_VISION, android) { +class NightVisionFeature(android: MatteryPlayer) : AndroidSwitchableFeature(AndroidFeatures.NIGHT_VISION, android) { override val allowToSwitchByPlayerWhileSpectator: Boolean get() = true diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/ShockwaveFeature.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/ShockwaveFeature.kt index 54751846d..c8642a4a9 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/ShockwaveFeature.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/ShockwaveFeature.kt @@ -2,13 +2,16 @@ package ru.dbotthepony.mc.otm.android.feature import it.unimi.dsi.fastutil.objects.ReferenceArraySet import net.minecraft.network.FriendlyByteBuf +import net.minecraft.network.protocol.common.custom.CustomPacketPayload import net.minecraft.server.level.ServerPlayer import net.minecraft.sounds.SoundSource import net.minecraft.world.entity.Entity import net.minecraft.world.entity.LivingEntity import net.minecraft.world.entity.monster.warden.Warden +import net.neoforged.neoforge.network.PacketDistributor +import net.neoforged.neoforge.network.handling.IPayloadContext import ru.dbotthepony.mc.otm.android.AndroidSwitchableFeature -import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability +import ru.dbotthepony.mc.otm.capability.MatteryPlayer import ru.dbotthepony.mc.otm.capability.energy.extractEnergyExact import ru.dbotthepony.mc.otm.capability.matteryPlayer import ru.dbotthepony.mc.otm.client.render.MGUIGraphics @@ -25,11 +28,8 @@ import ru.dbotthepony.mc.otm.core.math.plus import ru.dbotthepony.mc.otm.core.math.roundToIntVector import ru.dbotthepony.mc.otm.core.math.times import ru.dbotthepony.mc.otm.core.position -import ru.dbotthepony.mc.otm.network.MNetworkContext -import ru.dbotthepony.mc.otm.network.MatteryPacket -import ru.dbotthepony.mc.otm.network.MatteryPlayerNetworkChannel import ru.dbotthepony.mc.otm.network.ShockwaveEffectPacket -import ru.dbotthepony.mc.otm.onceServer +import ru.dbotthepony.mc.otm.network.TriggerShockwavePacket import ru.dbotthepony.mc.otm.registry.AndroidFeatures import ru.dbotthepony.mc.otm.registry.MDamageTypes import ru.dbotthepony.mc.otm.registry.MSoundEvents @@ -39,23 +39,7 @@ import ru.dbotthepony.mc.otm.triggers.ShockwaveTrigger import kotlin.math.pow import kotlin.math.roundToInt -object TriggerShockwavePacket : MatteryPacket { - override fun write(buff: FriendlyByteBuf) { - // no op - } - - override fun play(context: MNetworkContext) { - val shockwave = context.sender?.matteryPlayer?.getFeature(AndroidFeatures.SHOCKWAVE) ?: return - - if (!shockwave.isOnCooldown && shockwave.isActive && shockwave.airTicks > 0) { - onceServer { // delay by one tick so player update its position as well - shockwave.shockwave() - } - } - } -} - -class ShockwaveFeature(capability: MatteryPlayerCapability) : AndroidSwitchableFeature(AndroidFeatures.SHOCKWAVE, capability) { +class ShockwaveFeature(capability: MatteryPlayer) : AndroidSwitchableFeature(AndroidFeatures.SHOCKWAVE, capability) { override val maxCooldown: Int get() = AndroidConfig.Shockwave.COOLDOWN @@ -91,7 +75,7 @@ class ShockwaveFeature(capability: MatteryPlayerCapability) : AndroidSwitchableF if (ply is ServerPlayer) { ShockwaveTrigger.trigger(ply as ServerPlayer) - MatteryPlayerNetworkChannel.sendTrackingAndSelf(ply, ShockwaveEffectPacket(ply.position)) + PacketDistributor.sendToPlayersTrackingEntityAndSelf(ply, ShockwaveEffectPacket(ply.position)) ply.level().playSound( null, @@ -204,7 +188,7 @@ class ShockwaveFeature(capability: MatteryPlayerCapability) : AndroidSwitchableF // I HATE SELF-UPDATING PLAYERS // fix "bug" where shockwave doesn't trigger even when player is falling faster than orbiting satellite putOnCooldown() - MatteryPlayerNetworkChannel.sendToServer(TriggerShockwavePacket) + PacketDistributor.sendToServer(TriggerShockwavePacket) } else { shockwave() } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/StepAssistFeature.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/StepAssistFeature.kt index ecfb5580f..f97573ec5 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/StepAssistFeature.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/StepAssistFeature.kt @@ -1,31 +1,29 @@ package ru.dbotthepony.mc.otm.android.feature import net.minecraft.world.entity.ai.attributes.AttributeModifier -import net.minecraftforge.common.ForgeMod +import net.minecraft.world.entity.ai.attributes.Attributes import ru.dbotthepony.mc.otm.android.AndroidSwitchableFeature -import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability +import ru.dbotthepony.mc.otm.capability.MatteryPlayer import ru.dbotthepony.mc.otm.client.render.MGUIGraphics import ru.dbotthepony.mc.otm.client.render.ResearchIcons import ru.dbotthepony.kommons.math.RGBAColor +import ru.dbotthepony.mc.otm.OverdriveThatMatters +import ru.dbotthepony.mc.otm.core.ResourceLocation import ru.dbotthepony.mc.otm.registry.AndroidFeatures -import java.util.* -class StepAssistFeature(android: MatteryPlayerCapability) : AndroidSwitchableFeature(AndroidFeatures.STEP_ASSIST, android) { +class StepAssistFeature(android: MatteryPlayer) : AndroidSwitchableFeature(AndroidFeatures.STEP_ASSIST, android) { override fun applyModifiers() { - if (!ForgeMod.STEP_HEIGHT_ADDITION.isPresent || !isActive) + if (!isActive) return - val reach = ply.getAttribute(ForgeMod.STEP_HEIGHT_ADDITION.get()) ?: return + val reach = ply.getAttribute(Attributes.STEP_HEIGHT) ?: return reach.removeModifier(MODIFIER_ID) - reach.addPermanentModifier(AttributeModifier(MODIFIER_ID, type.displayName.toString(), (level + 1) * 0.5, AttributeModifier.Operation.ADDITION)) + reach.addPermanentModifier(AttributeModifier(MODIFIER_ID, (level + 1) * 0.5, AttributeModifier.Operation.ADD_VALUE)) } override fun removeModifiers() { - if (!ForgeMod.STEP_HEIGHT_ADDITION.isPresent) - return - - ply.getAttribute(ForgeMod.STEP_HEIGHT_ADDITION.get())?.removeModifier(MODIFIER_ID) + ply.getAttribute(Attributes.STEP_HEIGHT)?.removeModifier(MODIFIER_ID) } private var isShiftKeyDown = false @@ -59,6 +57,6 @@ class StepAssistFeature(android: MatteryPlayerCapability) : AndroidSwitchableFea } companion object { - private val MODIFIER_ID = UUID.fromString("4a3fae46-47a8-a03f-857d-f5c2b2c8f2f4") + private val MODIFIER_ID = ResourceLocation(OverdriveThatMatters.MOD_ID, "step_assist_feature") } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/SwimBoostersFeature.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/SwimBoostersFeature.kt index 60d1b9ce6..acd4e1df9 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/SwimBoostersFeature.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/SwimBoostersFeature.kt @@ -1,32 +1,30 @@ package ru.dbotthepony.mc.otm.android.feature import net.minecraft.world.entity.ai.attributes.AttributeModifier -import net.minecraftforge.common.ForgeMod +import net.neoforged.neoforge.common.NeoForgeMod import ru.dbotthepony.mc.otm.android.AndroidSwitchableFeature -import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability +import ru.dbotthepony.mc.otm.capability.MatteryPlayer import ru.dbotthepony.mc.otm.client.render.MGUIGraphics import ru.dbotthepony.mc.otm.client.render.ResearchIcons import ru.dbotthepony.mc.otm.config.AndroidConfig import ru.dbotthepony.kommons.math.RGBAColor +import ru.dbotthepony.mc.otm.OverdriveThatMatters +import ru.dbotthepony.mc.otm.core.ResourceLocation import ru.dbotthepony.mc.otm.registry.AndroidFeatures -import java.util.* -class SwimBoostersFeature(android: MatteryPlayerCapability) : AndroidSwitchableFeature(AndroidFeatures.SWIM_BOOSTERS, android) { +class SwimBoostersFeature(android: MatteryPlayer) : AndroidSwitchableFeature(AndroidFeatures.SWIM_BOOSTERS, android) { override fun applyModifiers() { - if (!ForgeMod.SWIM_SPEED.isPresent || !isActive) + if (!isActive) return - val attr = ply.getAttribute(ForgeMod.SWIM_SPEED.get()) ?: return + val attr = ply.getAttribute(NeoForgeMod.SWIM_SPEED) ?: return attr.removeModifier(MODIFIER_ID) - attr.addPermanentModifier(AttributeModifier(MODIFIER_ID, type.displayName.toString(), (level + 1) * AndroidConfig.SWIM_BOOSTERS, AttributeModifier.Operation.ADDITION)) + attr.addPermanentModifier(AttributeModifier(MODIFIER_ID, (level + 1) * AndroidConfig.SWIM_BOOSTERS, AttributeModifier.Operation.ADD_VALUE)) } override fun removeModifiers() { - if (!ForgeMod.SWIM_SPEED.isPresent) - return - - ply.getAttribute(ForgeMod.SWIM_SPEED.get())?.removeModifier(MODIFIER_ID) + ply.getAttribute(NeoForgeMod.SWIM_SPEED)?.removeModifier(MODIFIER_ID) } override fun renderIcon(graphics: MGUIGraphics, x: Float, y: Float, width: Float, height: Float, color: RGBAColor) { @@ -34,6 +32,6 @@ class SwimBoostersFeature(android: MatteryPlayerCapability) : AndroidSwitchableF } companion object { - private val MODIFIER_ID = UUID.fromString("4a3ffa46-47a8-a03f-857d-f5c2b2c8f2f6") + private val MODIFIER_ID = ResourceLocation(OverdriveThatMatters.MOD_ID, "swim_boosters_feature") } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/MatteryBlock.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/MatteryBlock.kt index 54865f369..54af818c1 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/MatteryBlock.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/MatteryBlock.kt @@ -17,6 +17,7 @@ import net.minecraft.world.InteractionResult import net.minecraft.world.MenuProvider import net.minecraft.world.entity.LivingEntity import net.minecraft.world.entity.player.Player +import net.minecraft.world.item.Item import net.minecraft.world.item.ItemStack import net.minecraft.world.item.TooltipFlag import net.minecraft.world.level.BlockGetter @@ -42,7 +43,6 @@ import ru.dbotthepony.mc.otm.core.math.BlockRotationFreedom import ru.dbotthepony.mc.otm.core.math.component1 import ru.dbotthepony.mc.otm.core.math.component2 import ru.dbotthepony.mc.otm.core.math.component3 -import ru.dbotthepony.mc.otm.core.tagNotNull import ru.dbotthepony.mc.otm.once import java.util.concurrent.Callable import java.util.function.Function @@ -117,13 +117,11 @@ open class MatteryBlock(properties: Properties = DEFAULT_PROPERTIES) : Block(pro return getShapeForEachState(ArrayList(stateDefinition.properties), mapper) } - @Suppress("OVERRIDE_DEPRECATION") - override fun use( + override fun useWithoutItem( blockState: BlockState, level: Level, blockPos: BlockPos, ply: Player, - hand: InteractionHand, blockHitResult: BlockHitResult ): InteractionResult { if (this is EntityBlock && !level.isClientSide) { @@ -138,8 +136,7 @@ open class MatteryBlock(properties: Properties = DEFAULT_PROPERTIES) : Block(pro if (this is EntityBlock && level.isClientSide) return InteractionResult.SUCCESS - @Suppress("DEPRECATION") - return super.use(blockState, level, blockPos, ply, hand, blockHitResult) + return super.useWithoutItem(blockState, level, blockPos, ply, blockHitResult) } override fun animateTick(blockState: BlockState, level: Level, blockPos: BlockPos, random: RandomSource) { @@ -261,9 +258,14 @@ open class MatteryBlock(properties: Properties = DEFAULT_PROPERTIES) : Block(pro } } - override fun appendHoverText(itemStack: ItemStack, blockAccessor: BlockGetter?, components: MutableList, tooltipType: TooltipFlag) { - super.appendHoverText(itemStack, blockAccessor, components, tooltipType) - tooltips.assemble(itemStack, components) + override fun appendHoverText( + itemStack: ItemStack, + p_339606_: Item.TooltipContext, + components: MutableList, + tooltipType: TooltipFlag + ) { + super.appendHoverText(itemStack, p_339606_, components, tooltipType) + tooltips.assemble(itemStack, p_339606_, components) } companion object { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/decorative/FluidTankBlock.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/decorative/FluidTankBlock.kt index edeb9f709..367f5429f 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/decorative/FluidTankBlock.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/decorative/FluidTankBlock.kt @@ -14,7 +14,7 @@ import net.minecraft.world.level.block.state.BlockState import net.minecraft.world.phys.BlockHitResult import net.minecraft.world.phys.shapes.CollisionContext import net.minecraft.world.phys.shapes.VoxelShape -import net.minecraftforge.fluids.FluidUtil +import net.neoforged.neoforge.fluids.FluidUtil import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock import ru.dbotthepony.mc.otm.block.entity.decorative.FluidTankBlockEntity import ru.dbotthepony.mc.otm.block.getShapeForEachState @@ -54,12 +54,11 @@ class FluidTankBlock : RotatableMatteryBlock(DEFAULT_MACHINE_PROPERTIES), Entity return shapes[state]!! } - override fun getLightEmission(state: BlockState?, level: BlockGetter?, pos: BlockPos?): Int { + override fun getLightEmission(state: BlockState, level: BlockGetter, pos: BlockPos): Int { if (pos == BlockPos.ZERO) return 15 val lightLevel = super.getLightEmission(state, level, pos) - - val tile = level?.getExistingBlockEntity(pos) ?: lightLevel + val tile = level.getBlockEntity(pos) if (tile is FluidTankBlockEntity) { val fluid = tile.fluid.fluid diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/decorative/InfiniteWaterSourceBlock.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/decorative/InfiniteWaterSourceBlock.kt index d9a0b1524..97e482b91 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/decorative/InfiniteWaterSourceBlock.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/decorative/InfiniteWaterSourceBlock.kt @@ -3,7 +3,9 @@ package ru.dbotthepony.mc.otm.block.decorative import net.minecraft.core.BlockPos import net.minecraft.world.InteractionHand import net.minecraft.world.InteractionResult +import net.minecraft.world.ItemInteractionResult import net.minecraft.world.entity.player.Player +import net.minecraft.world.item.ItemStack import net.minecraft.world.level.Level import net.minecraft.world.level.block.EntityBlock import net.minecraft.world.level.block.entity.BlockEntity @@ -13,7 +15,7 @@ import net.minecraft.world.level.block.state.BlockState import net.minecraft.world.level.material.MapColor import net.minecraft.world.level.material.PushReaction import net.minecraft.world.phys.BlockHitResult -import net.minecraftforge.fluids.FluidUtil +import net.neoforged.neoforge.fluids.FluidUtil import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock import ru.dbotthepony.mc.otm.block.entity.decorative.InfiniteWaterSourceBlockEntity @@ -22,13 +24,20 @@ class InfiniteWaterSourceBlock : RotatableMatteryBlock(Properties.of().destroyTi return InfiniteWaterSourceBlockEntity(p_153215_, p_153216_) } - @Suppress("OVERRIDE_DEPRECATION") - override fun use(blockState: BlockState, level: Level, blockPos: BlockPos, ply: Player, hand: InteractionHand, blockHitResult: BlockHitResult): InteractionResult { - if (FluidUtil.interactWithFluidHandler(ply, hand, level, blockPos, blockHitResult.direction)) { - return InteractionResult.sidedSuccess(level.isClientSide) + override fun useItemOn( + p_316304_: ItemStack, + p_316362_: BlockState, + p_316459_: Level, + p_316366_: BlockPos, + p_316132_: Player, + p_316595_: InteractionHand, + p_316140_: BlockHitResult + ): ItemInteractionResult { + if (FluidUtil.interactWithFluidHandler(p_316132_, p_316595_, p_316459_, p_316366_, p_316140_.direction)) { + return ItemInteractionResult.sidedSuccess(p_316459_.isClientSide) } - return super.use(blockState, level, blockPos, ply, hand, blockHitResult) + return super.useItemOn(p_316304_, p_316362_, p_316459_, p_316366_, p_316132_, p_316595_, p_316140_) } override fun getTicker(p_153212_: Level, p_153213_: BlockState, p_153214_: BlockEntityType): BlockEntityTicker? { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/decorative/LaboratoryLamp.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/decorative/LaboratoryLamp.kt index c8d8d6afe..a2ad72b16 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/decorative/LaboratoryLamp.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/decorative/LaboratoryLamp.kt @@ -3,6 +3,7 @@ package ru.dbotthepony.mc.otm.block.decorative import net.minecraft.ChatFormatting import net.minecraft.core.BlockPos import net.minecraft.network.chat.Component +import net.minecraft.world.item.Item import net.minecraft.world.item.ItemStack import net.minecraft.world.item.Items import net.minecraft.world.item.TooltipFlag @@ -122,11 +123,11 @@ class LaboratoryLamp(val invertRedstone: Boolean) : Block(Properties.of().mapCol override fun appendHoverText( p_49816_: ItemStack, - p_49817_: BlockGetter?, + p_339606_: Item.TooltipContext, p_49818_: MutableList, p_49819_: TooltipFlag ) { - super.appendHoverText(p_49816_, p_49817_, p_49818_, p_49819_) + super.appendHoverText(p_49816_, p_339606_, p_49818_, p_49819_) p_49818_.add(TranslatableComponent("${MBlocks.LABORATORY_LAMP.descriptionId}.description").withStyle(ChatFormatting.GRAY)) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/decorative/PainterBlock.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/decorative/PainterBlock.kt index d471cda7e..a112f959d 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/decorative/PainterBlock.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/decorative/PainterBlock.kt @@ -3,7 +3,9 @@ package ru.dbotthepony.mc.otm.block.decorative import net.minecraft.core.BlockPos import net.minecraft.world.InteractionHand import net.minecraft.world.InteractionResult +import net.minecraft.world.ItemInteractionResult import net.minecraft.world.entity.player.Player +import net.minecraft.world.item.ItemStack import net.minecraft.world.level.Level import net.minecraft.world.level.block.EntityBlock import net.minecraft.world.level.block.entity.BlockEntity @@ -11,7 +13,7 @@ import net.minecraft.world.level.block.entity.BlockEntityTicker import net.minecraft.world.level.block.entity.BlockEntityType import net.minecraft.world.level.block.state.BlockState import net.minecraft.world.phys.BlockHitResult -import net.minecraftforge.fluids.FluidUtil +import net.neoforged.neoforge.fluids.FluidUtil import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock import ru.dbotthepony.mc.otm.block.entity.decorative.PainterBlockEntity @@ -20,13 +22,20 @@ class PainterBlock : RotatableMatteryBlock(DEFAULT_MACHINE_PROPERTIES), EntityBl return PainterBlockEntity(p_153215_, p_153216_) } - @Suppress("OVERRIDE_DEPRECATION") - override fun use(blockState: BlockState, level: Level, blockPos: BlockPos, ply: Player, hand: InteractionHand, blockHitResult: BlockHitResult): InteractionResult { + override fun useItemOn( + p_316304_: ItemStack, + blockState: BlockState, + level: Level, + blockPos: BlockPos, + ply: Player, + hand: InteractionHand, + blockHitResult: BlockHitResult + ): ItemInteractionResult { if (FluidUtil.interactWithFluidHandler(ply, hand, level, blockPos, blockHitResult.direction)) { - return InteractionResult.sidedSuccess(level.isClientSide) + return ItemInteractionResult.sidedSuccess(level.isClientSide) } - return super.use(blockState, level, blockPos, ply, hand, blockHitResult) + return super.useItemOn(p_316304_, blockState, level, blockPos, ply, hand, blockHitResult) } override fun getTicker(p_153212_: Level, p_153213_: BlockState, p_153214_: BlockEntityType): BlockEntityTicker? { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/decorative/TritaniumPressurePlate.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/decorative/TritaniumPressurePlate.kt index 68cf09679..a9776fb54 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/decorative/TritaniumPressurePlate.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/decorative/TritaniumPressurePlate.kt @@ -1,13 +1,14 @@ package ru.dbotthepony.mc.otm.block.decorative +import com.mojang.serialization.MapCodec import net.minecraft.ChatFormatting import net.minecraft.core.BlockPos import net.minecraft.network.chat.Component import net.minecraft.server.level.ServerPlayer import net.minecraft.world.item.DyeColor +import net.minecraft.world.item.Item import net.minecraft.world.item.ItemStack import net.minecraft.world.item.TooltipFlag -import net.minecraft.world.level.BlockGetter import net.minecraft.world.level.Level import net.minecraft.world.level.block.BasePressurePlateBlock import net.minecraft.world.level.block.Block @@ -18,7 +19,6 @@ import net.minecraft.world.level.block.state.properties.BlockSetType import net.minecraft.world.level.block.state.properties.BlockStateProperties import ru.dbotthepony.mc.otm.core.TooltipList import ru.dbotthepony.mc.otm.core.TranslatableComponent -import ru.dbotthepony.mc.otm.core.collect.iteratorOf import ru.dbotthepony.mc.otm.core.get class TritaniumPressurePlate(color: DyeColor?) : BasePressurePlateBlock(Properties.of().mapColor(color ?: DyeColor.LIGHT_BLUE).sound(SoundType.METAL).explosionResistance(80f).noOcclusion().destroyTime(3f).requiresCorrectToolForDrops().forceSolidOn().noCollission(), BlockSetType.IRON) { @@ -26,12 +26,12 @@ class TritaniumPressurePlate(color: DyeColor?) : BasePressurePlateBlock(Properti override fun appendHoverText( itemStack: ItemStack, - level: BlockGetter?, + context: Item.TooltipContext, lines: MutableList, tooltipType: TooltipFlag ) { - super.appendHoverText(itemStack, level, lines, tooltipType) - tooltips.assemble(itemStack, lines) + super.appendHoverText(itemStack, context, lines, tooltipType) + tooltips.assemble(itemStack, context, lines) } init { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/ExperienceStorage.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/ExperienceStorage.kt index 310f47590..586e344b5 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/ExperienceStorage.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/ExperienceStorage.kt @@ -2,6 +2,7 @@ package ru.dbotthepony.mc.otm.block.entity import net.minecraft.core.BlockPos import net.minecraft.core.Direction +import net.minecraft.core.HolderLookup import net.minecraft.nbt.DoubleTag import net.minecraft.server.level.ServerLevel import net.minecraft.server.level.ServerPlayer @@ -10,9 +11,9 @@ import net.minecraft.world.level.Level import net.minecraft.world.level.block.Block import net.minecraft.world.level.block.entity.BlockEntity import net.minecraft.world.level.block.state.BlockState -import net.minecraftforge.common.util.INBTSerializable -import net.minecraftforge.fluids.FluidStack -import net.minecraftforge.fluids.capability.IFluidHandler +import net.neoforged.neoforge.common.util.INBTSerializable +import net.neoforged.neoforge.fluids.FluidStack +import net.neoforged.neoforge.fluids.capability.IFluidHandler import ru.dbotthepony.mc.otm.block.INeighbourChangeListener import ru.dbotthepony.mc.otm.block.entity.tech.EssenceStorageBlockEntity import ru.dbotthepony.mc.otm.core.math.plus @@ -98,11 +99,11 @@ class ExperienceStorage(val maxExperience: DoubleSupplier = DoubleSupplier { Dou } } - override fun serializeNBT(): DoubleTag { + override fun serializeNBT(registry: HolderLookup.Provider): DoubleTag { return DoubleTag.valueOf(experience) } - override fun deserializeNBT(nbt: DoubleTag?) { + override fun deserializeNBT(registry: HolderLookup.Provider, nbt: DoubleTag?) { experience = (nbt?.asDouble ?: 0.0).coerceAtLeast(0.0) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/Jobs.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/Jobs.kt index 840537cf4..a0a922ce6 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/Jobs.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/Jobs.kt @@ -3,10 +3,11 @@ package ru.dbotthepony.mc.otm.block.entity import com.mojang.datafixers.Products import com.mojang.serialization.Codec import com.mojang.serialization.codecs.RecordCodecBuilder +import net.minecraft.core.HolderLookup import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.NbtOps import net.minecraft.world.item.ItemStack -import net.minecraftforge.common.util.INBTSerializable +import net.neoforged.neoforge.common.util.INBTSerializable import org.apache.logging.log4j.LogManager import ru.dbotthepony.mc.otm.capability.IMatteryUpgrade import ru.dbotthepony.mc.otm.capability.energy.IMatteryEnergyStorage @@ -17,7 +18,6 @@ import ru.dbotthepony.mc.otm.core.math.weakGreaterThan import ru.dbotthepony.mc.otm.core.math.weakLessThan import ru.dbotthepony.mc.otm.core.nbt.set import ru.dbotthepony.mc.otm.data.DecimalCodec -import ru.dbotthepony.mc.otm.data.minRange private fun isReason(status: Any?, reason: Any) = status == null || status == reason private val LOGGER = LogManager.getLogger() @@ -325,12 +325,12 @@ abstract class MachineJobEventLoop(val codec: Codec) : OBSERVING } - override fun serializeNBT(): CompoundTag { + override fun serializeNBT(registry: HolderLookup.Provider): CompoundTag { return CompoundTag().also { nbt -> nbt["WorkTicks"] = workTicks currentJob?.let { - codec.encode(it, NbtOps.INSTANCE, NbtOps.INSTANCE.empty()).get().map( + codec.encode(it, NbtOps.INSTANCE, NbtOps.INSTANCE.empty()).mapOrElse( { nbt["Job"] = it }, @@ -342,14 +342,14 @@ abstract class MachineJobEventLoop(val codec: Codec) : } } - override fun deserializeNBT(nbt: CompoundTag?) { + override fun deserializeNBT(registry: HolderLookup.Provider, nbt: CompoundTag?) { nbt ?: return workTicks = nbt.getDouble("WorkTicks") currentJob = null if ("Job" in nbt) { - codec.decode(NbtOps.INSTANCE, nbt["Job"]!!).get().map( + codec.decode(NbtOps.INSTANCE, nbt["Job"]!!).mapOrElse( { currentJob = it.first }, diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryBlockEntity.kt index a810816c3..9251fb91a 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryBlockEntity.kt @@ -10,6 +10,7 @@ import it.unimi.dsi.fastutil.objects.Reference2IntArrayMap import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap import net.minecraft.core.BlockPos import net.minecraft.core.Direction +import net.minecraft.core.HolderLookup.Provider import net.minecraft.core.SectionPos import net.minecraft.core.Vec3i import net.minecraft.nbt.CompoundTag @@ -26,15 +27,15 @@ import net.minecraft.world.level.block.entity.RandomizableContainerBlockEntity import net.minecraft.world.level.block.state.BlockState import net.minecraft.world.level.chunk.LevelChunk import net.minecraft.world.phys.Vec3 -import net.minecraftforge.common.capabilities.Capability -import net.minecraftforge.common.capabilities.ForgeCapabilities -import net.minecraftforge.common.util.LazyOptional -import net.minecraftforge.energy.IEnergyStorage -import net.minecraftforge.event.TickEvent.LevelTickEvent -import net.minecraftforge.event.entity.player.PlayerEvent -import net.minecraftforge.event.level.ChunkWatchEvent -import net.minecraftforge.event.level.LevelEvent -import net.minecraftforge.event.server.ServerStoppingEvent +import net.neoforged.neoforge.capabilities.BlockCapability +import net.neoforged.neoforge.capabilities.BlockCapabilityCache +import net.neoforged.neoforge.capabilities.Capabilities +import net.neoforged.neoforge.event.entity.player.PlayerEvent +import net.neoforged.neoforge.event.level.ChunkWatchEvent +import net.neoforged.neoforge.event.level.LevelEvent +import net.neoforged.neoforge.event.server.ServerStoppingEvent +import net.neoforged.neoforge.event.tick.LevelTickEvent +import net.neoforged.neoforge.network.PacketDistributor import org.apache.logging.log4j.LogManager import ru.dbotthepony.kommons.io.DelegateSyncher import ru.dbotthepony.kommons.util.Listenable @@ -45,21 +46,20 @@ import ru.dbotthepony.mc.otm.capability.MatteryCapability import ru.dbotthepony.mc.otm.capability.energy.IMatteryEnergyStorage import ru.dbotthepony.mc.otm.core.collect.WeakHashSet import ru.dbotthepony.mc.otm.core.get -import ru.dbotthepony.mc.otm.core.immutableList import ru.dbotthepony.mc.otm.core.math.BlockRotation import ru.dbotthepony.mc.otm.core.math.RelativeSide -import ru.dbotthepony.mc.otm.core.math.minus import ru.dbotthepony.mc.otm.core.math.plus import ru.dbotthepony.mc.otm.core.util.IntCounter import ru.dbotthepony.mc.otm.core.util.Savetables import ru.dbotthepony.mc.otm.core.util.TickList import ru.dbotthepony.mc.otm.core.util.countingLazy import ru.dbotthepony.mc.otm.network.BlockEntitySyncPacket -import ru.dbotthepony.mc.otm.network.GenericNetworkChannel import ru.dbotthepony.mc.otm.once +import ru.dbotthepony.mc.otm.onceServer import ru.dbotthepony.mc.otm.sometimeServer import java.lang.ref.WeakReference import java.util.* +import java.util.function.BooleanSupplier import java.util.function.Consumer import java.util.function.Predicate import java.util.function.Supplier @@ -74,7 +74,11 @@ import kotlin.reflect.KProperty abstract class MatteryBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: BlockPos, p_155230_: BlockState) : BlockEntity(p_155228_, p_155229_, p_155230_), INeighbourChangeListener { private var isSynchronizing = false - private val sidelessCaps = Reference2ObjectOpenHashMap, SidelessCap<*>>() + private val sidelessCaps = Reference2ObjectOpenHashMap, Any>() + private val sidedCaps = Array(RelativeSide.entries.size) { + Reference2ObjectOpenHashMap, Any>() + } + protected val tickList = TickList() protected val blockStateChangesCounter = IntCounter() protected val dirtyListeners = Listenable.Impl() @@ -85,9 +89,6 @@ abstract class MatteryBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: Bloc val droppableContainers: Set = Collections.unmodifiableSet(_droppableContainers) val neighbourChangeListeners: Set = Collections.unmodifiableSet(_neighbourChangeListeners) - private val _sides = EnumMap(RelativeSide::class.java) - val sides: Map = Collections.unmodifiableMap(_sides) - /** * Shared savetables, written both to level storage and to item tag */ @@ -121,10 +122,6 @@ abstract class MatteryBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: Bloc open fun beforeDroppingItems(oldBlockState: BlockState, level: Level, blockPos: BlockPos, newBlockState: BlockState, movedByPiston: Boolean) {} open fun beforeDestroyedByPlayer(level: Level, blockPos: BlockPos, blockState: BlockState, player: Player) {} - fun side(side: RelativeSide) = sides[side]!! - - private data class SidelessCap(val cap: T, var optional: LazyOptional) - open fun tick() { tickList.tick() } @@ -132,40 +129,45 @@ abstract class MatteryBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: Bloc /** * exposes capability when no side is specified */ - protected fun exposeSideless(capability: Capability, value: T) { + protected fun exposeSideless(capability: BlockCapability, value: T) { check(!sidelessCaps.containsKey(capability)) { "Already has globally exposed $capability!" } - sidelessCaps[capability] = SidelessCap(value, LazyOptional.of { value }) + sidelessCaps[capability] = value setChanged() + level?.invalidateCapabilities(blockPos) + } + + protected fun exposeSided(side: RelativeSide, capability: BlockCapability, value: T) { + val map = sidedCaps[side.ordinal] + check(!map.containsKey(capability)) { "Already has exposed $capability on $side!" } + map[capability] = value + setChanged() + level?.invalidateCapabilities(blockPos) } /** * Exposes capability unconditionally, on all sides and sideless */ - protected fun exposeGlobally(capability: Capability, value: T, predicate: Predicate = Predicate { true }) { + protected fun exposeGlobally(capability: BlockCapability, value: T, predicate: Predicate = Predicate { true }) { exposeSideless(capability, value) - for (side in _sides.values) - if (predicate.test(side.side)) - side.Cap(capability, value) - } - - protected fun exposeEnergyGlobally(value: IMatteryEnergyStorage, predicate: Predicate = Predicate { true }) { - exposeGlobally(ForgeCapabilities.ENERGY, value, predicate) - exposeGlobally(MatteryCapability.ENERGY, value, predicate) + for (side in RelativeSide.entries) + if (predicate.test(side)) + exposeSided(side, capability, value) } protected fun exposeEnergySideless(value: IMatteryEnergyStorage) { - exposeSideless(ForgeCapabilities.ENERGY, value) - exposeSideless(MatteryCapability.ENERGY, value) + exposeSideless(Capabilities.EnergyStorage.BLOCK, value) + exposeSideless(MatteryCapability.BLOCK_ENERGY, value) } - protected fun exposeEnergy(side: RelativeSide, value: IMatteryEnergyStorage): ImmutableList> { - return immutableList { - val thisSide = _sides[side]!! + protected fun exposeEnergyGlobally(value: IMatteryEnergyStorage) { + exposeGlobally(Capabilities.EnergyStorage.BLOCK, value) + exposeGlobally(MatteryCapability.BLOCK_ENERGY, value) + } - accept(thisSide.Cap(ForgeCapabilities.ENERGY, value)) - accept(thisSide.Cap(MatteryCapability.ENERGY, value)) - } + protected fun exposeEnergySided(side: RelativeSide, value: IMatteryEnergyStorage) { + exposeSided(side, Capabilities.EnergyStorage.BLOCK, value) + exposeSided(side, MatteryCapability.BLOCK_ENERGY, value) } protected fun waitForServerLevel(lambda: () -> Unit) { @@ -176,266 +178,38 @@ abstract class MatteryBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: Bloc } } - interface SideListener : Supplier>, Listenable> - - inner class Side(val side: RelativeSide) { - init { - check(!_sides.containsKey(side)) { "dafuq are you trying to do" } - _sides[side] = this - } - - private val caps = Reference2ObjectOpenHashMap, Cap<*>>() - private val subscriptions = Reference2ObjectOpenHashMap, SubRef<*>>() - private val knownLOs = WeakHashSet>() - - private inner class SubRef(value: LazyOptional) : SideListener { - var value: LazyOptional = value - set(value) { - if (value !== field) { - field = value - listeners.accept(value) - } - } - - private val listeners = Listenable.Impl>() - - override fun addListener(listener: Consumer>): Listenable.L { - val l = listeners.addListener(listener) - if (level is ServerLevel) listener.accept(value) - return l - } - - override fun get(): LazyOptional { - return value - } - - fun unset() { - value = LazyOptional.empty() - } - } - - fun track(capability: Capability): SideListener { - var subref = subscriptions[capability] as SideListener? - - if (subref == null) { - subref = SubRef(LazyOptional.empty()) as SubRef - subscriptions[capability] = subref - level?.once { updateTracked(capability) } - } - - return subref - } - - fun trackEnergy(): SideListener { - return track(ForgeCapabilities.ENERGY) - } - - fun updateTracked() { - for (key in subscriptions.keys) { - // Concurrent Modification safety: - // we do not add nor remove keys from map, we only update values - updateTracked(key) - } - } - - private fun updateTracked(capability: Capability<*>) { - if (isRemoved || !SERVER_IS_LIVE) return - val dir = blockRotation.side2Dir(side) - val targetPos = blockPos + dir.normal - - val chunk = level - ?.chunkSource - ?.getChunkNow(SectionPos.blockToSectionCoord(targetPos.x), SectionPos.blockToSectionCoord(targetPos.z)) - - val subref = subscriptions[capability] as SubRef - - if (chunk == null) { - subref.unset() - level?.once { updateTracked(capability) } - return - } - - val entity = chunk.getBlockEntity(targetPos) - - if (entity == null) { - subref.unset() - return - } - - val new = entity.getCapability(capability, dir.opposite) - - if (!new.isPresent) { - subref.unset() - return - } - - if (subref.value !== new) { - if (knownLOs.add(new)) { - val ref = WeakReference(this) - - new.addListener { - ref.get()?.updateTracked(capability) - } - } - - subref.value = new as LazyOptional - } - } - - operator fun get(capability: Capability): Cap? { - return caps[capability] as Cap? - } - - fun invalidate() { - for (cap in caps.values) - cap.invalidate() - } - - fun revive() { - for (cap in caps.values) - cap.revive() - } - - inner class Cap(val type: Capability, val capability: T) { - init { - check(!caps.containsKey(type)) { "Already has capability $type on side $side" } - caps[type] = this - } - - var isExposed = true - private set - var isValid = true - private set - var isRemoved = false - private set - - var optional: LazyOptional by object : ReadWriteProperty> { - private var value: LazyOptional? = null - - override fun getValue(thisRef: Any?, property: KProperty<*>): LazyOptional { - if (value == null) { - value = LazyOptional.of { capability } - } - - return value!! - } - - override fun setValue(thisRef: Any?, property: KProperty<*>, value: LazyOptional) { - this.value = value - } - } - private set - - fun remove() { - if (!isRemoved) { - isRemoved = true - val removed = caps.remove(type) - check(removed == this) { "$removed != $this" } - optional.invalidate() - } - } - - fun close() { - if (!isRemoved && isExposed) { - isExposed = false - optional.invalidate() - - if (SERVER_IS_LIVE) - level?.once { if (!this@MatteryBlockEntity.isRemoved) setChanged() } - } - } - - fun expose() { - if (!isRemoved && !isExposed) { - isExposed = true - - if (isValid) { - optional = LazyOptional.of { capability } - - if (SERVER_IS_LIVE) - level?.once { if (!this@MatteryBlockEntity.isRemoved) setChanged() } - } - } - } - - fun invalidate() { - if (!isRemoved && isValid) { - isValid = false - optional.invalidate() - - if (SERVER_IS_LIVE) - level?.once { if (!this@MatteryBlockEntity.isRemoved) setChanged() } - } - } - - fun revive() { - if (!isRemoved && !isValid) { - isValid = true - - if (isExposed) { - optional = LazyOptional.of { capability } - - if (SERVER_IS_LIVE) - level?.once { if (!this@MatteryBlockEntity.isRemoved) setChanged() } - } - } - } - } - } - - val front = Side(RelativeSide.FRONT) - val back = Side(RelativeSide.BACK) - val left = Side(RelativeSide.LEFT) - val right = Side(RelativeSide.RIGHT) - val top = Side(RelativeSide.TOP) - val bottom = Side(RelativeSide.BOTTOM) - - override fun getCapability(cap: Capability, side: Direction?): LazyOptional { + fun getCapability(cap: BlockCapability, side: Direction?): T? { if (side != null) { - return _sides[blockRotation.dir2Side(side)]!![cap]?.optional ?: super.getCapability(cap, side) + return sidedCaps[blockRotation.dir2Side(side).ordinal][cap] as T? } - return sidelessCaps[cap]?.optional?.cast() ?: super.getCapability(cap, side) + return sidelessCaps[cap] as T? } - override fun invalidateCaps() { - super.invalidateCaps() - - for (side in sides.values) - side.invalidate() - } - - override fun reviveCaps() { - super.reviveCaps() - - for (side in sides.values) - side.revive() - } - - final override fun saveAdditional(nbt: CompoundTag) { - super.saveAdditional(nbt) - saveShared(nbt) - saveLevel(nbt) + final override fun saveAdditional(nbt: CompoundTag, registry: Provider) { + super.saveAdditional(nbt, registry) + saveShared(nbt, registry) + saveLevel(nbt, registry) } /** * Saved both to item dropped, and to level storage */ - open fun saveShared(nbt: CompoundTag) { - savetables.serializeNBT(nbt) + open fun saveShared(nbt: CompoundTag, registry: Provider) { + savetables.serializeNBT(nbt, registry) } /** * Only saved to level storage, discarded when dropped as item */ - open fun saveLevel(nbt: CompoundTag) { - savetablesLevel.serializeNBT(nbt) + open fun saveLevel(nbt: CompoundTag, registry: Provider) { + savetablesLevel.serializeNBT(nbt, registry) } - override fun load(nbt: CompoundTag) { - super.load(nbt) - savetables.deserializeNBT(nbt) - savetablesLevel.deserializeNBT(nbt) + override fun loadAdditional(nbt: CompoundTag, registry: Provider) { + super.loadAdditional(nbt, registry) + savetables.deserializeNBT(registry, nbt) + savetablesLevel.deserializeNBT(registry, nbt) } @Suppress("OVERRIDE_DEPRECATION") @@ -447,21 +221,13 @@ abstract class MatteryBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: Bloc val new = blockRotation if (old != new) { - for (side in _sides.values) { - side.updateTracked() - side.invalidate() - } - } - - for (side in _sides.values) { - side.revive() + level?.invalidateCapabilities(blockPos) + capabilityCaches.forEach { it.rebuildCache() } } } override fun neighborChanged(state: BlockState, level: Level, pos: BlockPos, neighbour: Block, neighbourPos: BlockPos, movedByPiston: Boolean) { _neighbourChangeListeners.forEach { it.neighborChanged(state, level, pos, neighbour, neighbourPos, movedByPiston) } - val dir = vec2Dir[vecKey(neighbourPos - blockPos)] ?: return - _sides[blockRotation.dir2Side(dir)]!!.updateTracked() } override fun setChanged() { @@ -483,6 +249,51 @@ abstract class MatteryBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: Bloc dirtyListeners.accept(Unit) } + private val capabilityCaches = ArrayList>() + + inner class CapabilityCache(val side: RelativeSide, val capability: BlockCapability) : Supplier, Listenable { + private var currentVersion = 0 + private var cache: BlockCapabilityCache? = null + private val listeners = Listenable.Impl() + + override fun addListener(listener: Consumer): Listenable.L { + return listeners.addListener(listener) + } + + init { + capabilityCaches.add(this) + } + + override fun get(): T? { + return cache?.capability + } + + val isPresent: Boolean + get() = cache?.capability != null + + val isEmpty: Boolean + get() = cache?.capability == null + + fun rebuildCache() { + val level = level as? ServerLevel + + if (level == null) { + cache = null + return + } + + val creationVersion = ++currentVersion + + cache = BlockCapabilityCache.create( + capability, level, blockPos, + blockRotation.side2Dir(side), + { !isRemoved || creationVersion != currentVersion }, + // IllegalStateException("Do not call getCapability on an invalid cache or from the invalidation listener!") + // what a shame. + { onceServer { if (!isRemoved && creationVersion == currentVersion) listeners.accept(cache?.capability) } }) + } + } + val syncher = DelegateSyncher() private val synchers = Object2ObjectArrayMap() @@ -494,30 +305,11 @@ abstract class MatteryBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: Bloc if (!level.isClientSide) { subscribe() - - if (old != null) { - for (side in _sides.values) { - side.updateTracked() - side.invalidate() - } - - for (side in _sides.values) { - side.revive() - } - } else { - level.once { - if (!isRemoved) { - for (side in _sides.values) { - side.updateTracked() - } - } - } - } - waitForServerLevel.forEach { it.invoke() } + capabilityCaches.forEach { it.rebuildCache() } + waitForServerLevel.clear() } else { waitForServerLevel.clear() - BlockEntitySyncPacket.applyBacklog(this) } } @@ -718,7 +510,7 @@ abstract class MatteryBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: Bloc /** * Returns stream of players watching (tracking) specified [chunk] */ - fun watchingPlayers(chunk: LevelChunk) = watchingPlayers(chunk.pos, chunk.level) + fun watchingPlayers(chunk: LevelChunk) = watchingPlayers(chunk.pos, chunk.level!!) private fun vecKey(value: Vec3i): Int { if (value.x !in -1 .. 1) return -1 @@ -759,7 +551,7 @@ abstract class MatteryBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: Bloc val payload = data.write() if (payload != null) { - GenericNetworkChannel.send(player, BlockEntitySyncPacket(be.blockPos, payload.array, payload.length)) + PacketDistributor.sendToPlayer(player, BlockEntitySyncPacket(be.blockPos, payload.array, payload.length)) } } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryDeviceBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryDeviceBlockEntity.kt index cbb233e24..5c270b8c6 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryDeviceBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryDeviceBlockEntity.kt @@ -1,8 +1,11 @@ package ru.dbotthepony.mc.otm.block.entity import com.google.common.collect.ImmutableSet +import com.google.gson.JsonParser import net.minecraft.world.level.block.entity.BlockEntityType import net.minecraft.core.BlockPos +import net.minecraft.core.Direction +import net.minecraft.core.HolderLookup import net.minecraft.world.level.block.state.BlockState import net.minecraft.world.MenuProvider import net.minecraft.world.entity.player.Inventory @@ -12,10 +15,12 @@ import net.minecraft.nbt.CompoundTag import net.minecraft.network.chat.Component import net.minecraft.world.item.ItemStack import net.minecraft.world.level.Level -import net.minecraftforge.common.capabilities.ForgeCapabilities -import net.minecraftforge.fluids.FluidStack -import net.minecraftforge.fluids.capability.IFluidHandler -import net.minecraftforge.items.IItemHandler +import net.minecraft.world.level.block.entity.BlockEntity +import net.neoforged.neoforge.capabilities.Capabilities +import net.neoforged.neoforge.capabilities.ICapabilityProvider +import net.neoforged.neoforge.fluids.FluidStack +import net.neoforged.neoforge.fluids.capability.IFluidHandler +import net.neoforged.neoforge.items.IItemHandler import ru.dbotthepony.kommons.util.getValue import ru.dbotthepony.kommons.util.setValue import ru.dbotthepony.mc.otm.capability.item.CombinedItemHandler @@ -28,7 +33,6 @@ import ru.dbotthepony.mc.otm.capability.moveEnergy import ru.dbotthepony.mc.otm.capability.moveFluid import ru.dbotthepony.mc.otm.core.TextComponent import ru.dbotthepony.mc.otm.core.getValue -import ru.dbotthepony.mc.otm.core.ifPresentK import ru.dbotthepony.mc.otm.core.immutableMap import ru.dbotthepony.mc.otm.core.math.Decimal import ru.dbotthepony.mc.otm.core.math.RelativeSide @@ -67,16 +71,16 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo protected open fun redstoneStatusUpdated(newBlocked: Boolean, oldBlocked: Boolean) {} - override fun saveShared(nbt: CompoundTag) { - super.saveShared(nbt) + override fun saveShared(nbt: CompoundTag, registry: HolderLookup.Provider) { + super.saveShared(nbt, registry) if (customDisplayName != null) - nbt.putJson("Name", Component.Serializer.toJsonTree(customDisplayName!!)) + nbt.putJson("Name", JsonParser.parseString(Component.Serializer.toJson(customDisplayName!!, registry))) } - override fun load(nbt: CompoundTag) { - super.load(nbt) - customDisplayName = nbt.getJson("Name")?.let(Component.Serializer::fromJson) + override fun loadAdditional(nbt: CompoundTag, registry: HolderLookup.Provider) { + super.loadAdditional(nbt, registry) + customDisplayName = nbt.getJson("Name")?.let { Component.Serializer.fromJson(it, registry) } } override fun setLevel(level: Level) { @@ -102,7 +106,7 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo val bottomDefault: FlowDirection = possibleModes, ) { init { - exposeSideless(ForgeCapabilities.FLUID_HANDLER, capability) + exposeSideless(Capabilities.FluidHandler.BLOCK, capability) } val front = Piece(RelativeSide.FRONT).also { it.flow = frontDefault } @@ -132,11 +136,18 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo inner class Piece(val side: RelativeSide) : IFluidHandler, ITickable { private val ticker = tickList.Ticker(this) - private val controller = side(side).Cap(ForgeCapabilities.FLUID_HANDLER, this) - private val neighbour = side(side).track(ForgeCapabilities.FLUID_HANDLER) + private val neighbour = CapabilityCache(side, Capabilities.FluidHandler.BLOCK) + + init { + exposeSided(side, Capabilities.FluidHandler.BLOCK, this) + } private fun updateTickerState() { - ticker.isEnabled = (automatePull || automatePush) && flow != FlowDirection.NONE && !redstoneControl.isBlockedByRedstone && neighbour.get().isPresent + ticker.isEnabled = + (automatePull || automatePush) && + flow != FlowDirection.NONE && + !redstoneControl.isBlockedByRedstone && + neighbour.isPresent } init { @@ -152,15 +163,8 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo if (access.get() != value) { access.accept(value) markDirtyFast() - - if (value == FlowDirection.NONE) { - controller.close() - } else { - controller.close() - controller.expose() - } - updateTickerState() + level?.invalidateCapabilities(blockPos) } }) @@ -193,14 +197,14 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo if (flow == FlowDirection.NONE || !automatePull && !automatePush || redstoneControl.isBlockedByRedstone) return - neighbour.get().ifPresentK { - if (flow.input && automatePull) { - moveFluid(source = it, destination = capability) - } + val it = neighbour.get() ?: return - if (flow.output && automatePush) { - moveFluid(source = capability, destination = it) - } + if (flow.input && automatePull) { + moveFluid(source = it, destination = capability) + } + + if (flow.output && automatePush) { + moveFluid(source = capability, destination = it) } } @@ -334,15 +338,12 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo put(RelativeSide.BOTTOM, bottomDefault) } - fun invalidate(force: Boolean = false) { - for (piece in pieces.values) { - piece.invalidate(force) - } - } - inner class Piece(val side: RelativeSide, val possibleModes: FlowDirection) : IMatteryEnergyStorage, ITickable { - private val capControllers = exposeEnergy(side, this@Piece) - private val neighbour = side(side).trackEnergy() + private val neighbour = CapabilityCache(side, Capabilities.EnergyStorage.BLOCK) + + init { + exposeEnergySided(side, this) + } override var batteryLevel: Decimal by energy::batteryLevel override val maxBatteryLevel: Decimal by energy::maxBatteryLevel @@ -356,7 +357,7 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo ticker.isEnabled = (automatePull || automatePush) && energyFlow != FlowDirection.NONE && !redstoneControl.isBlockedByRedstone && - neighbour.get().isPresent && + neighbour.isPresent && (volatileEnergyValues || energy.batteryLevel.isPositive) } @@ -424,14 +425,14 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo } override fun tick() { - neighbour.get().ifPresentK { - if (energyFlow.input && automatePull) { - moveEnergy(source = it, destination = energy, simulate = false) - } + val it = neighbour.get() ?: return - if (energyFlow.output && automatePush) { - moveEnergy(source = energy, destination = it, simulate = false) - } + if (energyFlow.input && automatePull) { + moveEnergy(source = it, destination = energy, simulate = false) + } + + if (energyFlow.output && automatePush) { + moveEnergy(source = energy, destination = it, simulate = false) } } @@ -441,42 +442,10 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo if (access.get() != value) { access.accept(value) markDirtyFast() - - if (value == FlowDirection.NONE) { - for (controller in capControllers) - controller.close() - } else { - for (controller in capControllers) { - controller.close() - controller.expose() - } - } - updateTickerState() + level?.invalidateCapabilities(blockPos) } }).delegate - - fun invalidate(force: Boolean = false) { - if (force) { - for (controller in capControllers) { - controller.close() - controller.expose() - } - - if (energyFlow == FlowDirection.NONE) { - for (controller in capControllers) { - controller.close() - } - } - } else { - if (energyFlow != FlowDirection.NONE) { - for (controller in capControllers) { - controller.close() - controller.expose() - } - } - } - } } } @@ -550,7 +519,7 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo if (battery != null) caps.add(battery) sideless = UnmodifiableItemHandler(CombinedItemHandler(caps)) - exposeSideless(ForgeCapabilities.ITEM_HANDLER, sideless) + exposeSideless(Capabilities.ItemHandler.BLOCK, sideless) } val front = Piece(RelativeSide.FRONT).also { it.mode = frontDefault } @@ -585,10 +554,13 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo updateTickerState() } - private val capController = side(side).Cap(ForgeCapabilities.ITEM_HANDLER, this) - private val neighbour = side(side).track(ForgeCapabilities.ITEM_HANDLER) + private val neighbour = CapabilityCache(side, Capabilities.ItemHandler.BLOCK) private val ticker = tickList.Ticker(this) + init { + exposeSided(side, Capabilities.ItemHandler.BLOCK, this) + } + private var innerSlotPull = 0 private var outerSlotPull = 0 @@ -596,11 +568,12 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo private var outerSlotPush = 0 private fun updateTickerState() { - ticker.isEnabled = (automatePull || automatePush) && mode != ItemHandlerMode.DISABLED && !redstoneControl.isBlockedByRedstone && currentHandler.slots != 0 && neighbour.get().isPresent - } - - init { - capController.close() + ticker.isEnabled = + (automatePull || automatePush) && + mode != ItemHandlerMode.DISABLED && + !redstoneControl.isBlockedByRedstone && + currentHandler.slots != 0 && + neighbour.isPresent } var mode by syncher.enum(ItemHandlerMode.DISABLED, setter = { access, value -> @@ -610,13 +583,6 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo access.accept(value) markDirtyFast() - if (value == ItemHandlerMode.DISABLED) { - capController.close() - } else { - capController.close() - capController.expose() - } - currentHandler = when (value) { ItemHandlerMode.DISABLED -> EmptyItemHandler ItemHandlerMode.INPUT -> input!! @@ -624,6 +590,8 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo ItemHandlerMode.INPUT_OUTPUT -> inputOutput!! ItemHandlerMode.BATTERY -> battery!! } + + level?.invalidateCapabilities(blockPos) } }).delegate @@ -674,33 +642,33 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo if (mode == ItemHandlerMode.DISABLED || !automatePull && !automatePush || redstoneControl.isBlockedByRedstone || currentHandler.slots == 0) return - neighbour.get().ifPresentK { - if (it.slots == 0) - return + val it = neighbour.get() ?: return - if (automatePull) { - if (innerSlotPull !in 0 until currentHandler.slots) - innerSlotPull = 0 + if (it.slots == 0) + return - if (outerSlotPull !in 0 until it.slots) - outerSlotPull = 0 + if (automatePull) { + if (innerSlotPull !in 0 until currentHandler.slots) + innerSlotPull = 0 - val (outerSlotPull, innerSlotPull) = moveBetweenSlots(it, outerSlotPull, currentHandler, innerSlotPull) - this.innerSlotPull = innerSlotPull - this.outerSlotPull = outerSlotPull - } + if (outerSlotPull !in 0 until it.slots) + outerSlotPull = 0 - if (automatePush) { - if (innerSlotPush !in 0 until currentHandler.slots) - innerSlotPush = 0 + val (outerSlotPull, innerSlotPull) = moveBetweenSlots(it, outerSlotPull, currentHandler, innerSlotPull) + this.innerSlotPull = innerSlotPull + this.outerSlotPull = outerSlotPull + } - if (outerSlotPush !in 0 until it.slots) - outerSlotPush = 0 + if (automatePush) { + if (innerSlotPush !in 0 until currentHandler.slots) + innerSlotPush = 0 - val (innerSlotPush, outerSlotPush) = moveBetweenSlots(currentHandler, innerSlotPush, it, outerSlotPush) - this.innerSlotPush = innerSlotPush - this.outerSlotPush = outerSlotPush - } + if (outerSlotPush !in 0 until it.slots) + outerSlotPush = 0 + + val (innerSlotPush, outerSlotPush) = moveBetweenSlots(currentHandler, innerSlotPush, it, outerSlotPush) + this.innerSlotPush = innerSlotPush + this.outerSlotPush = outerSlotPush } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryPoweredBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryPoweredBlockEntity.kt index 290457998..40f1bd7b9 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryPoweredBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryPoweredBlockEntity.kt @@ -3,12 +3,11 @@ package ru.dbotthepony.mc.otm.block.entity import net.minecraft.core.BlockPos import net.minecraft.world.level.block.entity.BlockEntityType import net.minecraft.world.level.block.state.BlockState -import net.minecraftforge.common.capabilities.ForgeCapabilities +import ru.dbotthepony.mc.otm.capability.energy import ru.dbotthepony.mc.otm.capability.energy.IMatteryEnergyStorage import ru.dbotthepony.mc.otm.capability.extractEnergy import ru.dbotthepony.mc.otm.container.HandlerFilter import ru.dbotthepony.mc.otm.container.MatteryContainer -import ru.dbotthepony.mc.otm.core.ifPresentK import ru.dbotthepony.mc.otm.core.math.Decimal abstract class MatteryPoweredBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: BlockPos, p_155230_: BlockState) : MatteryDeviceBlockEntity(p_155228_, p_155229_, p_155230_) { @@ -31,7 +30,7 @@ abstract class MatteryPoweredBlockEntity(p_155228_: BlockEntityType<*>, p_155229 if (demand.isZero) return for (stack in batteryContainer) { - stack.getCapability(ForgeCapabilities.ENERGY).ifPresentK { + stack.energy?.let { val diff = it.extractEnergy(demand, false) energy.receiveEnergy(diff, false) demand -= diff diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryWorkerBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryWorkerBlockEntity.kt index 86c7170ac..27eaeb517 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryWorkerBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryWorkerBlockEntity.kt @@ -3,6 +3,7 @@ package ru.dbotthepony.mc.otm.block.entity import com.google.common.collect.ImmutableList import com.mojang.serialization.Codec import net.minecraft.core.BlockPos +import net.minecraft.core.HolderLookup import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.ListTag import net.minecraft.network.chat.Component @@ -75,26 +76,26 @@ abstract class MatteryWorkerBlockEntity( protected open fun onJobTick(status: JobStatus, id: Int) {} - override fun saveShared(nbt: CompoundTag) { - super.saveShared(nbt) + override fun saveShared(nbt: CompoundTag, registry: HolderLookup.Provider) { + super.saveShared(nbt, registry) nbt["jobs"] = ListTag().also { for ((i, job) in jobEventLoops.withIndex()) { - it.add(job.serializeNBT().also { + it.add(job.serializeNBT(registry).also { it["_id"] = i }) } } } - override fun load(nbt: CompoundTag) { - super.load(nbt) + override fun loadAdditional(nbt: CompoundTag, registry: HolderLookup.Provider) { + super.loadAdditional(nbt, registry) for (v in nbt.getCompoundList("jobs")) { if ("_id" in v) { val id = v.getInt("_id") if (id in jobEventLoops.indices) { - jobEventLoops[id].deserializeNBT(v) + jobEventLoops[id].deserializeNBT(registry, v) } } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/RedstoneControl.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/RedstoneControl.kt index 4a5bb03b9..615c2382a 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/RedstoneControl.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/RedstoneControl.kt @@ -1,7 +1,8 @@ package ru.dbotthepony.mc.otm.block.entity +import net.minecraft.core.HolderLookup import net.minecraft.nbt.CompoundTag -import net.minecraftforge.common.util.INBTSerializable +import net.neoforged.neoforge.common.util.INBTSerializable import ru.dbotthepony.kommons.io.DelegateSyncher import ru.dbotthepony.kommons.util.Listenable import ru.dbotthepony.kommons.util.getValue @@ -25,14 +26,14 @@ abstract class AbstractRedstoneControl : INBTSerializable, Listena return listeners.addListener(listener) } - override fun serializeNBT(): CompoundTag { + override fun serializeNBT(registry: HolderLookup.Provider): CompoundTag { return CompoundTag().also { it[SETTING_KEY] = redstoneSetting.toString() it[SIGNAL_KEY] = redstoneSignal } } - override fun deserializeNBT(nbt: CompoundTag?) { + override fun deserializeNBT(registry: HolderLookup.Provider, nbt: CompoundTag?) { if (nbt == null) { redstoneSetting = RedstoneSetting.LOW redstoneSignal = 0 diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/blackhole/BlackHoleBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/blackhole/BlackHoleBlockEntity.kt index fed7679f2..4daef4b9c 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/blackhole/BlackHoleBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/blackhole/BlackHoleBlockEntity.kt @@ -3,6 +3,7 @@ package ru.dbotthepony.mc.otm.block.entity.blackhole import it.unimi.dsi.fastutil.objects.ObjectArraySet import net.minecraft.client.Minecraft import net.minecraft.core.BlockPos +import net.minecraft.core.HolderLookup import net.minecraft.nbt.CompoundTag import net.minecraft.server.level.ServerLevel import net.minecraft.server.level.ServerPlayer @@ -18,13 +19,12 @@ import net.minecraft.world.level.block.state.BlockState import net.minecraft.world.level.levelgen.structure.BoundingBox import net.minecraft.world.phys.AABB import net.minecraft.world.phys.Vec3 -import net.minecraftforge.common.Tags +import net.neoforged.neoforge.common.Tags import ru.dbotthepony.kommons.util.getValue import ru.dbotthepony.kommons.util.setValue import ru.dbotthepony.mc.otm.block.BlackHoleBlock import ru.dbotthepony.mc.otm.block.entity.tech.GravitationStabilizerBlockEntity import ru.dbotthepony.mc.otm.block.entity.MatteryBlockEntity -import ru.dbotthepony.mc.otm.block.entity.blackhole.ExplosionQueue.Companion.queueForLevel import ru.dbotthepony.mc.otm.config.ServerConfig import ru.dbotthepony.mc.otm.core.damageType import ru.dbotthepony.mc.otm.core.getExplosionResistance @@ -101,37 +101,6 @@ class BlackHoleBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Mattery val level = level as? ServerLevel ?: return level.setBlock(blockPos, Blocks.AIR.defaultBlockState(), Block.UPDATE_ALL) - - if (gravitationStrength > 0.25) { - val x0 = blockPos.x + 0.5 - val y0 = blockPos.y + 0.5 - val z0 = blockPos.z + 0.5 - val queue = queueForLevel(level) - var radius = 0 - - while (radius < Math.ceil(gravitationStrength * 4)) { - queue.explodeRing( - x0, - y0, - z0, - radius.toDouble(), Math.min(20.0, Math.max(1.0, (gravitationStrength * 4 - radius) * 20)).toFloat() - ) - - radius++ - } - } else { - level.explode( - null, - MatteryDamageSource(level.registryAccess().damageType(MDamageTypes.HAWKING_RADIATION)), - null, - blockPos.x + 0.5, - blockPos.y + 0.5, - blockPos.z + 0.5, - gravitationStrength.toFloat() * 60, - false, - Level.ExplosionInteraction.BLOCK // TODO: 1.19.3 - ) - } } private fun updateGravStrength() { @@ -162,19 +131,14 @@ class BlackHoleBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Mattery affectedBoundsAABB = AABB.of(affectedBounds) } - override fun getRenderBoundingBox(): AABB { - return AABB(blockPos.offset(-GravitationStabilizerBlockEntity.RANGE, -GravitationStabilizerBlockEntity.RANGE, -GravitationStabilizerBlockEntity.RANGE), blockPos.offset( - GravitationStabilizerBlockEntity.RANGE, GravitationStabilizerBlockEntity.RANGE, GravitationStabilizerBlockEntity.RANGE)) - } - - override fun saveLevel(nbt: CompoundTag) { - super.saveLevel(nbt) + override fun saveLevel(nbt: CompoundTag, registry: HolderLookup.Provider) { + super.saveLevel(nbt, registry) nbt["mass"] = mass.serializeNBT() nbt["spin_direction"] = spinDirection } - override fun load(nbt: CompoundTag) { - super.load(nbt) + override fun loadAdditional(nbt: CompoundTag, registry: HolderLookup.Provider) { + super.loadAdditional(nbt, registry) mass = nbt.map("mass", Decimal::deserializeNBT) ?: BASELINE_MASS spinDirection = nbt.getBoolean("spin_direction") } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/blackhole/ExplosionDebuggerBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/blackhole/ExplosionDebuggerBlockEntity.kt deleted file mode 100644 index cb821cc50..000000000 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/blackhole/ExplosionDebuggerBlockEntity.kt +++ /dev/null @@ -1,49 +0,0 @@ -package ru.dbotthepony.mc.otm.block.entity.blackhole - -import net.minecraft.core.BlockPos -import net.minecraft.server.level.ServerLevel -import net.minecraft.world.level.block.Block -import net.minecraft.world.level.block.Blocks -import net.minecraft.world.level.block.entity.BlockEntity -import net.minecraft.world.level.block.state.BlockState -import net.minecraft.world.phys.Vec3 -import ru.dbotthepony.mc.otm.core.math.plus -import ru.dbotthepony.mc.otm.core.math.times -import ru.dbotthepony.mc.otm.registry.MBlockEntities - -class BlockEntityExplosionDebugger(p_155229_: BlockPos, p_155230_: BlockState) : BlockEntity(MBlockEntities.DEBUG_EXPLOSION_SMALL, p_155229_, p_155230_) { - private var hive: ExplosionRayHive? = null - - fun tick() { - if (hive == null) { - val hive = ExplosionRayHive(level as ServerLevel) - this.hive = hive - - val tx = blockPos.x.toDouble() + 0.5 - val ty = blockPos.y.toDouble() + 0.5 - val tz = blockPos.z.toDouble() + 0.5 - val tpos = Vec3(tx, ty, tz) - - for (normal in ExplosionRayHive.evenlyDistributedPoints(1000)) { - hive.addRay(normal + tpos, normal, 200.0) - } - } - - hive!!.step() - } -} - -class BlockEntitySphereDebugger(p_155229_: BlockPos, p_155230_: BlockState) : BlockEntity(MBlockEntities.DEBUG_SPHERE_POINTS, p_155229_, p_155230_) { - private var placed = false - - fun tick() { - if (!placed) { - placed = true - - for (normal in ExplosionRayHive.evenlyDistributedPoints(400)) { - val multiplied = normal * 20.0 - level!!.setBlock(blockPos + BlockPos(multiplied.x.toInt(), multiplied.y.toInt(), multiplied.z.toInt()), Blocks.COAL_BLOCK.defaultBlockState(), Block.UPDATE_ALL) - } - } - } -} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/blackhole/Explosions.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/blackhole/Explosions.kt deleted file mode 100644 index ed6136dd2..000000000 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/blackhole/Explosions.kt +++ /dev/null @@ -1,687 +0,0 @@ -package ru.dbotthepony.mc.otm.block.entity.blackhole - -import net.minecraft.core.BlockPos -import net.minecraft.nbt.CompoundTag -import net.minecraft.nbt.DoubleTag -import net.minecraft.nbt.ListTag -import net.minecraft.nbt.Tag -import net.minecraft.server.level.ServerLevel -import net.minecraft.util.datafix.DataFixTypes -import net.minecraft.world.level.BlockGetter -import net.minecraft.world.level.Explosion -import net.minecraft.world.level.ExplosionDamageCalculator -import net.minecraft.world.level.Level -import net.minecraft.world.level.block.Block -import net.minecraft.world.level.block.Blocks -import net.minecraft.world.level.block.state.BlockState -import net.minecraft.world.level.material.FluidState -import net.minecraft.world.level.saveddata.SavedData -import net.minecraft.world.phys.Vec3 -import net.minecraftforge.event.TickEvent -import net.minecraftforge.eventbus.api.SubscribeEvent -import org.apache.logging.log4j.LogManager -import ru.dbotthepony.mc.otm.block.BlockExplosionDebugger -import ru.dbotthepony.mc.otm.core.* -import ru.dbotthepony.mc.otm.core.math.Vector -import ru.dbotthepony.mc.otm.core.math.component1 -import ru.dbotthepony.mc.otm.core.math.component2 -import ru.dbotthepony.mc.otm.core.math.component3 -import ru.dbotthepony.mc.otm.core.math.left -import ru.dbotthepony.mc.otm.core.math.plus -import ru.dbotthepony.mc.otm.core.math.rotateAroundAxis -import ru.dbotthepony.mc.otm.core.math.up -import ru.dbotthepony.mc.otm.core.nbt.set -import ru.dbotthepony.mc.otm.registry.MDamageTypes -import ru.dbotthepony.mc.otm.registry.MRegistry -import ru.dbotthepony.mc.otm.registry.MatteryDamageSource -import java.util.* -import kotlin.collections.ArrayList -import kotlin.collections.HashMap -import kotlin.math.acos -import kotlin.math.cos -import kotlin.math.sin -import kotlin.math.sqrt - -private fun round(v: Double): Int { - return (v + 0.5).toInt() -} - -private val sphere = arrayOf( - // ядро - BlockPos(-1, -1, -1), - BlockPos(-1, -1, 0), - BlockPos(-1, -1, 1), - BlockPos(-1, 0, -1), - BlockPos(-1, 0, 0), - BlockPos(-1, 0, 1), - BlockPos(-1, 1, -1), - BlockPos(-1, 1, 0), - BlockPos(-1, 1, 1), - BlockPos(0, -1, -1), - BlockPos(0, -1, 0), - BlockPos(0, -1, 1), - BlockPos(0, 0, -1), - BlockPos(0, 0, 0), - BlockPos(0, 0, 1), - BlockPos(0, 1, -1), - BlockPos(0, 1, 0), - BlockPos(0, 1, 1), - BlockPos(1, -1, -1), - BlockPos(1, -1, 0), - BlockPos(1, -1, 1), - BlockPos(1, 0, -1), - BlockPos(1, 0, 0), - BlockPos(1, 0, 1), - BlockPos(1, 1, -1), - BlockPos(1, 1, 0), - BlockPos(1, 1, 1), - - // столбы - BlockPos(-2, 0, 0), - BlockPos(2, 0, 0), - BlockPos(0, 2, 0), - BlockPos(0, -2, 0), - BlockPos(0, 0, 2), - BlockPos(0, 0, -2), -) - -private val initialDirections = arrayOf( - Vector(1.0, 0.0, 0.0), - Vector(-1.0, 0.0, 0.0), - Vector(0.0, 1.0, 0.0), - Vector(0.0, -1.0, 0.0), - Vector(0.0, 0.0, 1.0), - Vector(0.0, 0.0, -1.0), - - Vector(-1.0, -1.0, -1.0).normalize(), - Vector(1.0, -1.0, 1.0).normalize(), - Vector(1.0, -1.0, -1.0).normalize(), - Vector(-1.0, -1.0, 1.0).normalize(), - Vector(-1.0, 1.0, -1.0).normalize(), - Vector(1.0, 1.0, 1.0).normalize(), - Vector(1.0, 1.0, -1.0).normalize(), - Vector(-1.0, 1.0, 1.0).normalize(), -) - -class ExplosionSphere(val hive: ExplosionSphereHive, var pos: Vec3, var stepVelocity: Vec3, var force: Double) { - val initialPos = pos - private var lastSplitPos = pos - val level: ServerLevel get() = hive.level - val blockPos: BlockPos get() = BlockPos(round(pos.x), round(pos.y), round(pos.z)) - - fun travelled(): Double { - return pos.distanceTo(initialPos) - } - - private fun travelledFromLastSplit(): Double { - return pos.distanceTo(lastSplitPos) - } - - fun step(): Boolean { - if (force <= 0.0) { - return false - } - - val blockPos = blockPos - - for (point in sphere) { - val finalPos = blockPos + point - val block = level.getBlockState(finalPos) - - if (!block.isAir && block.block !is BlockExplosionDebugger) { - val explosion = Explosion(level, null, null, null, pos.x, pos.y, pos.z, force.toFloat(), false, Explosion.BlockInteraction.DESTROY_WITH_DECAY) - val explosionResistance = block.getExplosionResistance(level, blockPos, explosion) - - if (explosionResistance > force) { - // поглощено - // TODO: вместо полного поглощения отражение - force = 0.0 - return false - } else { - // взорвано - force -= explosionResistance - - // TODO: дропы когда будет добавлена более общая версия - level.setBlock(blockPos, Blocks.AIR.defaultBlockState(), Block.UPDATE_ALL) - } - } - } - - pos += stepVelocity - - force -= 0.4 - - if (travelledFromLastSplit() >= TRAVEL_TO_SPLIT && force >= 10) { - force /= 2.0 - - val up = stepVelocity.up() - val left = stepVelocity.left() - - val a = stepVelocity.rotateAroundAxis(up, Math.PI / 4) - val b = stepVelocity.rotateAroundAxis(up, -Math.PI / 4) - val c = stepVelocity.rotateAroundAxis(left, Math.PI / 4) - val d = stepVelocity.rotateAroundAxis(left, -Math.PI / 4) - - hive.addRay(pos, a, force) - hive.addRay(pos, b, force) - hive.addRay(pos, c, force) - hive.addRay(pos, d, force) - - lastSplitPos = pos - } - - return force > 0.0 - } - - fun serializeNbt(): CompoundTag { - return CompoundTag() - } - - companion object { - const val TRAVEL_TO_SPLIT = 4.0 - - fun deserializeNbt(hive: ExplosionSphereHive, tag: CompoundTag): ExplosionSphere { - return ExplosionSphere(hive, Vector.ZERO, Vector.ZERO, 0.0) - } - } -} - -class ExplosionSphereHive(val level: ServerLevel) { - private val spheres = ArrayList() - - var stepNumber = 0 - private set - - fun addRay(pos: Vec3, stepVelocity: Vec3, force: Double) { - spheres.add(ExplosionSphere(this, pos, stepVelocity, force)) - } - - fun addDefaultRays(pos: Vec3, force: Double) { - for (stepVelocity in initialDirections) { - addRay(pos, stepVelocity, force * 8) - } - } - - fun step() { - stepNumber++ - - val toRemove = ArrayList() - - for (i in 0 until spheres.size) { - if (!spheres[i].step()) { - toRemove.add(i) - } - } - - for (i in toRemove.size - 1 downTo 0) { - spheres.removeAt(toRemove[i]) - } - } - - fun serializeNbt(): CompoundTag { - return CompoundTag().also { - it["spheres"] = ListTag().also { - for (ray in spheres) - it.add(ray.serializeNbt()) - } - } - } - - fun deserializeNbt(tag: CompoundTag) { - (tag["spheres"] as? ListTag)?.also { - for (elem in it) { - spheres.add(ExplosionSphere.deserializeNbt(this, elem as CompoundTag)) - } - } - } - - fun isEmpty(): Boolean { - return spheres.isEmpty() - } -} - -class ExplosionRay(val hive: ExplosionRayHive, var pos: Vec3, var stepVelocity: Vec3, var force: Double) { - val initialPos = pos - private var lastSplitPos = pos - val level: ServerLevel get() = hive.level - val blockPos: BlockPos get() = BlockPos(round(pos.x), round(pos.y), round(pos.z)) - private var prev: MutableInt? = null - - fun travelled(): Double { - return pos.distanceTo(initialPos) - } - - private fun travelledFromLastSplit(): Double { - return pos.distanceTo(lastSplitPos) - } - - fun step(spread: Boolean): Boolean { - if (force <= 0.0) { - return false - } - - val blockPos = blockPos - - if (!level.isInWorldBounds(blockPos)) - return false - - // val chunk = level.chunkSource.getChunkNow(SectionPos.blockToSectionCoord(blockPos.x), SectionPos.blockToSectionCoord(blockPos.z)) ?: return true - val block = level.getBlockState(blockPos) - - if (!block.isAir && block.block !is BlockExplosionDebugger) { - val explosion = Explosion(level, null, null, null, pos.x, pos.y, pos.z, force.toFloat(), false, Explosion.BlockInteraction.DESTROY_WITH_DECAY) - val explosionResistance = block.getExplosionResistance(level, blockPos, explosion) - - if (explosionResistance > force) { - // поглощено - // TODO: вместо полного поглощения отражение - force = 0.0 - return false - } else { - // взорвано - force -= explosionResistance - - // TODO: дропы когда будет добавлена более общая версия - level.setBlock(blockPos, Blocks.AIR.defaultBlockState(), Block.UPDATE_ALL) - } - } - - val old = this.blockPos - pos += stepVelocity - val new = this.blockPos - - if (old != new) { - val prev = prev - - if (prev != null) { - prev.dec() - - if (prev.value <= 0) { - hive.checkKey(old) - } - } - - this.prev = hive.incDensity(new) - } - - force -= 0.4 - - if (spread && travelledFromLastSplit() >= TRAVEL_TO_SPLIT * sqrt(travelled() / 9.0) && force >= 10) { - force /= 2.0 - - val up = stepVelocity.up() - val left = stepVelocity.left() - - val a = stepVelocity.rotateAroundAxis(up, Math.PI / 5.5) - val b = stepVelocity.rotateAroundAxis(up, -Math.PI / 5.5) - val c = stepVelocity.rotateAroundAxis(left, Math.PI / 5.5) - val d = stepVelocity.rotateAroundAxis(left, -Math.PI / 5.5) - - hive.addRay(pos, a, force) - hive.addRay(pos, b, force) - hive.addRay(pos, c, force) - hive.addRay(pos, d, force) - - lastSplitPos = pos - } - - return force > 0f - } - - fun serializeNbt(): CompoundTag { - return CompoundTag().also { - it["pos"] = ListTag().also { - it.add(DoubleTag.valueOf(pos.x)) - it.add(DoubleTag.valueOf(pos.y)) - it.add(DoubleTag.valueOf(pos.z)) - } - - it["stepVelocity"] = ListTag().also { - it.add(DoubleTag.valueOf(stepVelocity.x)) - it.add(DoubleTag.valueOf(stepVelocity.y)) - it.add(DoubleTag.valueOf(stepVelocity.z)) - } - - it["force"] = force - } - } - - companion object { - const val TRAVEL_TO_SPLIT = 4.0 - - fun deserializeNbt(hive: ExplosionRayHive, tag: CompoundTag): ExplosionRay { - val pos = tag["pos"] as ListTag - val stepVelocity = tag["stepVelocity"] as ListTag - - return ExplosionRay(hive, - Vector((pos[0] as DoubleTag).asDouble, (pos[1] as DoubleTag).asDouble, (pos[2] as DoubleTag).asDouble), - Vector((stepVelocity[0] as DoubleTag).asDouble, (stepVelocity[1] as DoubleTag).asDouble, (stepVelocity[2] as DoubleTag).asDouble), - (tag["force"] as DoubleTag).asDouble - ) - } - } -} - -data class MutableInt(var value: Int = 0) { - fun inc() {value++} - fun dec() {value--} - fun zero() = value <= 0 -} - -class ExplosionRayHive(val level: ServerLevel) { - private val rays = ArrayList() - private val densityMap = HashMap() - var stepNumber = 0 - private set - - fun incDensity(pos: BlockPos): MutableInt { - return densityMap.computeIfAbsent(pos) {MutableInt()}.also(MutableInt::inc) - } - - fun decDensity(pos: BlockPos) { - val value = densityMap.computeIfAbsent(pos) {MutableInt()} - value.dec() - - if (value.zero()) { - densityMap.remove(pos) - } - } - - fun checkKey(pos: BlockPos) { - val value = densityMap.computeIfAbsent(pos) {MutableInt()} - - if (value.zero()) { - densityMap.remove(pos) - } - } - - fun addRay(pos: Vec3, stepVelocity: Vec3, force: Double) { - rays.add(ExplosionRay(this, pos, stepVelocity, force)) - } - - fun step() { - stepNumber++ - - val toRemove = ArrayList() - val density = calculateDensity() - - for (i in 0 until rays.size) { - if (!rays[i].step(density < 3.0)) { - toRemove.add(i) - decDensity(rays[i].blockPos) - } - } - - for (i in toRemove.size - 1 downTo 0) { - rays.removeAt(toRemove[i]) - } - - if (stepNumber % 4 == 0) { - LOGGER.info("At step {} density of hive {} with {} elements is {}", stepNumber, this, rays.size, density) - } - } - - fun calculateDensity(): Double { - return rays.size.toDouble() / densityMap.size - } - - fun serializeNbt(): CompoundTag { - return CompoundTag().also { - it["rays"] = ListTag().also { - for (ray in rays) - it.add(ray.serializeNbt()) - } - } - } - - fun deserializeNbt(tag: CompoundTag) { - (tag["rays"] as? ListTag)?.also { - for (elem in it) { - rays.add(ExplosionRay.deserializeNbt(this, elem as CompoundTag)) - } - } - } - - fun isEmpty(): Boolean { - return rays.isEmpty() - } - - companion object { - private val LOGGER = LogManager.getLogger() - private val SQUARE_5 = sqrt(5.0) - - fun evenlyDistributedPoints(amount: Int): List { - val list = ArrayList() - - for (i in 0 .. amount) { - val idx = i.toDouble() / amount - val phi = acos(1.0 - 2.0 * idx) - val theta = Math.PI * (1.0 + SQUARE_5) * i - - list.add(Vec3(cos(theta) * sin(phi), sin(theta) * sin(phi), cos(phi))) - } - - return list - } - } -} - -private object BlackHoleExplosionDamageCalculator : ExplosionDamageCalculator() { - override fun getBlockExplosionResistance( - explosion: Explosion, - getter: BlockGetter, - pos: BlockPos, - state: BlockState, - fstate: FluidState - ): Optional { - return if (state.isAir && fstate.isEmpty) Optional.empty() else Optional.of( - Math.sqrt( - Math.max( - 0f, - Math.max( - state.getExplosionResistance(getter, pos, explosion), - fstate.getExplosionResistance(getter, pos, explosion) - ) - ).toDouble() - ).toFloat() - ) - } -} - -private data class RingExplosion(val x: Double, val y: Double, val z: Double, val radius: Double, val strength: Float) { - fun serializeNBT(): CompoundTag { - return CompoundTag().also { - it["x"] = x - it["y"] = y - it["z"] = z - it["radius"] = radius - it["strength"] = strength - } - } - - fun explode(queue: ExplosionQueue) { - for (pos in ExplosionRayHive.evenlyDistributedPoints(radius.toInt() * 80)) { - val (x, y, z) = pos - - queue.explode( - this.x + x * radius * 15, - this.y + y * radius * 15, - this.z + z * radius * 15, - strength - ) - } - } - - companion object { - @JvmStatic - fun deserializeNBT(tag: CompoundTag): RingExplosion { - return RingExplosion( - tag.getDouble("x"), - tag.getDouble("y"), - tag.getDouble("z"), - tag.getDouble("radius"), - tag.getFloat("strength") - ) - } - } -} - -private data class QueuedExplosion(val x: Double, val y: Double, val z: Double, val radius: Float) { - fun serializeNBT(): CompoundTag { - return CompoundTag().also { - it["x"] = x - it["y"] = y - it["z"] = z - it["radius"] = radius - } - } - - fun explode(level: Level) { - level.explode( - null, - MatteryDamageSource(level.registryAccess().damageType(MDamageTypes.HAWKING_RADIATION)), - BlackHoleExplosionDamageCalculator, - x, - y, - z, - radius, - false, - Level.ExplosionInteraction.BLOCK // TODO: 1.19.3 - ) - } - - companion object { - fun deserializeNBT(tag: CompoundTag): QueuedExplosion { - return QueuedExplosion(tag.getDouble("x"), tag.getDouble("y"), tag.getDouble("z"), tag.getFloat("radius")) - } - } -} - -class ExplosionQueue(private val level: ServerLevel) : SavedData() { - private var indexExplosion = 0 - private var indexRing = 0 - private val explosions = ArrayList() - private val rings = ArrayList() - private val hives = ArrayList() - - override fun save(tag: CompoundTag): CompoundTag { - val listExplosions = ListTag() - val listRings = ListTag() - - for (i in indexExplosion until explosions.size) - listExplosions.add(explosions[i].serializeNBT()) - - for (i in indexRing until rings.size) - listRings.add(rings[i].serializeNBT()) - - tag["explosions"] = listExplosions - tag["rings"] = listRings - // tag["hives"] = ListTag().also { - // for (hive in hives) { - // it.add(hive.serializeNbt()) - // } - // } - - return tag - } - - fun load(tag: CompoundTag) { - explosions.clear() - rings.clear() - hives.clear() - - indexExplosion = 0 - indexRing = 0 - - for (explosion in tag.getList("explosions", Tag.TAG_COMPOUND.toInt())) - explosions.add(QueuedExplosion.deserializeNBT(explosion as CompoundTag)) - - for (ring in tag.getList("rings", Tag.TAG_COMPOUND.toInt())) - rings.add(RingExplosion.deserializeNBT(ring as CompoundTag)) - - for (hive in tag.getList("hives", Tag.TAG_COMPOUND.toInt())) - hives.add(ExplosionRayHive(level).also { it.deserializeNbt(hive as CompoundTag) }) - } - - fun explode(x: Double, y: Double, z: Double, radius: Float) { - if (level.isOutsideBuildHeight(BlockPos(x.toInt(), y.toInt() + 24, z.toInt())) || level.isOutsideBuildHeight(BlockPos(x.toInt(), y.toInt() - 24, z.toInt()))) - return - - explosions.add(QueuedExplosion(x, y, z, radius)) - isDirty = true - } - - fun explodeRing(x: Double, y: Double, z: Double, radius: Double, strength: Float) { - rings.add(RingExplosion(x, y, z, radius, strength)) - isDirty = true - } - - fun explodeRays(tpos: Vector, force: Double) { - val hive = ExplosionRayHive(level) - hives.add(hive) - - for (normal in ExplosionRayHive.evenlyDistributedPoints(1000)) { - hive.addRay(normal + tpos, normal, force) - } - - isDirty = true - } - - fun tick() { - if (explosions.size != 0) { - isDirty = true - var iterations = 0 - - for (i in indexExplosion until explosions.size) { - explosions[i].explode(level) - indexExplosion++ - - if (iterations++ == 4) { - break - } - } - - if (indexExplosion >= explosions.size) { - indexExplosion = 0 - explosions.clear() - } - } else if (rings.size != 0) { - if (indexRing >= rings.size) { - indexRing = 0 - rings.clear() - } else { - rings[indexRing++].explode(this) - } - } - - for (i in hives.size - 1 downTo 0) { - isDirty = true - hives[i].step() - - if (hives[i].isEmpty()) { - hives.removeAt(i) - } - } - } - - companion object { - @JvmStatic - fun queueForLevel(level: ServerLevel): ExplosionQueue { - return level.dataStorage.computeIfAbsent( - Factory({ ExplosionQueue(level) }, { - val factory = ExplosionQueue(level) - factory.load(it) - factory - }, DataFixTypes.LEVEL), - "otm_blackhole_explosion_queue" - ) - } - - @SubscribeEvent - fun onWorldTick(event: TickEvent.LevelTickEvent) { - if (event.phase == TickEvent.Phase.START && event.level is ServerLevel) { - queueForLevel(event.level as ServerLevel).tick() - } - } - } -} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/cable/EnergyCableBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/cable/EnergyCableBlockEntity.kt index 8ab790400..27f03ce86 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/cable/EnergyCableBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/cable/EnergyCableBlockEntity.kt @@ -6,7 +6,7 @@ import net.minecraft.world.level.Level import net.minecraft.world.level.block.Block import net.minecraft.world.level.block.entity.BlockEntityType import net.minecraft.world.level.block.state.BlockState -import net.minecraftforge.common.capabilities.ForgeCapabilities +import net.neoforged.neoforge.capabilities.Capabilities import ru.dbotthepony.mc.otm.SERVER_IS_LIVE import ru.dbotthepony.mc.otm.block.CableBlock import ru.dbotthepony.mc.otm.block.entity.MatteryBlockEntity @@ -43,23 +43,23 @@ abstract class EnergyCableBlockEntity(type: BlockEntityType<*>, blockPos: BlockP init { check(side !in energySidesInternal) energySidesInternal[side] = this - sides[side]!!.Cap(ForgeCapabilities.ENERGY, this) + exposeSided(side, Capabilities.EnergyStorage.BLOCK, this) } - val neighbour = sides[side]!!.trackEnergy() + val neighbour = CapabilityCache(side, Capabilities.EnergyStorage.BLOCK) init { waitForServerLevel { neighbour.addListener(Consumer { if (isEnabled) { - if (it.isPresent) { - if (it.resolve().get() !is CableSide) { + if (neighbour.isPresent) { + if (neighbour.get() !is CableSide) { node.graph.livelyNodes.add(node) } } onceServer { - updateBlockState(blockRotation.side2Dir(side), it.isPresent || node.neighboursView[GraphNode.link(blockRotation.side2Dir(side))] != null) + updateBlockState(blockRotation.side2Dir(side), neighbour.isPresent || node.neighboursView[GraphNode.link(blockRotation.side2Dir(side))] != null) } } }) @@ -144,8 +144,8 @@ abstract class EnergyCableBlockEntity(type: BlockEntityType<*>, blockPos: BlockP } init { - sides.keys.forEach { CableSide(it) } - exposeGlobally(MatteryCapability.ENERGY_CABLE_NODE, node) + RelativeSide.entries.forEach { CableSide(it) } + exposeSideless(MatteryCapability.ENERGY_CABLE_NODE, node) } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/cable/EnergyCableGraph.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/cable/EnergyCableGraph.kt index c6f435c08..7e391ec77 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/cable/EnergyCableGraph.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/cable/EnergyCableGraph.kt @@ -1,14 +1,10 @@ package ru.dbotthepony.mc.otm.block.entity.cable -import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap -import it.unimi.dsi.fastutil.objects.ObjectAVLTreeSet -import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet import ru.dbotthepony.mc.otm.capability.receiveEnergy -import ru.dbotthepony.mc.otm.core.ifPresentK import ru.dbotthepony.mc.otm.core.math.Decimal import ru.dbotthepony.mc.otm.core.math.RelativeSide import ru.dbotthepony.mc.otm.graph.GraphNodeList -import java.util.PriorityQueue +import java.util.* import kotlin.math.ln class EnergyCableGraph : GraphNodeList() { @@ -102,7 +98,7 @@ class EnergyCableGraph : GraphNodeList ResourceLocation.tryParse(it.asString) } lootTableSeed = (nbt[LOOT_TABLE_SEED_KEY] as LongTag?)?.asLong } @@ -105,7 +106,7 @@ class CargoCrateBlockEntity( val lootTableSeed = lootTableSeed ?: 0L val server = level?.server ?: return - val loot = server.lootData.getLootTable(lootTable) + val loot = server.loot.getLootTable(lootTable) if (ply is ServerPlayer) { CriteriaTriggers.GENERATE_LOOT.trigger(ply, lootTable) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/decorative/DevChestBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/decorative/DevChestBlockEntity.kt index 16b68cb47..d3fb15df3 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/decorative/DevChestBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/decorative/DevChestBlockEntity.kt @@ -2,14 +2,13 @@ package ru.dbotthepony.mc.otm.block.entity.decorative import it.unimi.dsi.fastutil.ints.Int2ObjectAVLTreeMap import net.minecraft.core.BlockPos +import net.minecraft.core.registries.BuiltInRegistries import net.minecraft.world.item.ItemStack import net.minecraft.world.level.block.state.BlockState -import net.minecraftforge.common.capabilities.ForgeCapabilities -import net.minecraftforge.items.IItemHandler -import net.minecraftforge.registries.ForgeRegistries -import net.minecraftforge.registries.IdMappingEvent +import net.neoforged.neoforge.capabilities.Capabilities +import net.neoforged.neoforge.items.IItemHandler +import net.neoforged.neoforge.registries.IdMappingEvent import ru.dbotthepony.mc.otm.block.entity.MatteryBlockEntity -import ru.dbotthepony.mc.otm.core.getID import ru.dbotthepony.mc.otm.registry.MBlockEntities class DevChestBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryBlockEntity(MBlockEntities.DEV_CHEST, blockPos, blockState), IItemHandler { @@ -38,7 +37,7 @@ class DevChestBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryB } init { - exposeGlobally(ForgeCapabilities.ITEM_HANDLER, this) + exposeGlobally(Capabilities.ItemHandler.BLOCK, this) } companion object { @@ -52,8 +51,8 @@ class DevChestBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryB val sorted = Int2ObjectAVLTreeMap() - for (item in ForgeRegistries.ITEMS.values) { - check(sorted.put(ForgeRegistries.ITEMS.getID(item), ItemStack(item, 1).also { it.count = item.getMaxStackSize(it) }) == null) + for (item in BuiltInRegistries.ITEM) { + check(sorted.put(BuiltInRegistries.ITEM.getId(item), ItemStack(item, 1).also { it.count = item.getMaxStackSize(it) }) == null) } cache.addAll(sorted.values) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/decorative/FluidTankBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/decorative/FluidTankBlockEntity.kt index 110353896..3ea66d026 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/decorative/FluidTankBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/decorative/FluidTankBlockEntity.kt @@ -8,9 +8,9 @@ import net.minecraft.world.entity.player.Player import net.minecraft.world.inventory.AbstractContainerMenu import net.minecraft.world.item.ItemStack import net.minecraft.world.level.block.state.BlockState -import net.minecraftforge.common.capabilities.ForgeCapabilities -import net.minecraftforge.fluids.FluidStack -import net.minecraftforge.fluids.capability.IFluidHandler +import net.neoforged.neoforge.capabilities.Capabilities +import net.neoforged.neoforge.fluids.FluidStack +import net.neoforged.neoforge.fluids.capability.IFluidHandler import org.apache.logging.log4j.LogManager import ru.dbotthepony.kommons.util.ListenableDelegate import ru.dbotthepony.mc.otm.block.entity.MatteryDeviceBlockEntity @@ -22,7 +22,6 @@ import ru.dbotthepony.mc.otm.container.HandlerFilter import ru.dbotthepony.mc.otm.container.MatteryContainer import ru.dbotthepony.mc.otm.container.get import ru.dbotthepony.mc.otm.core.isNotEmpty -import ru.dbotthepony.mc.otm.core.orNull import ru.dbotthepony.mc.otm.core.util.FluidStackValueCodec import ru.dbotthepony.mc.otm.menu.decorative.FluidTankMenu import ru.dbotthepony.mc.otm.registry.MBlockEntities @@ -47,10 +46,10 @@ class FluidTankBlockEntity(blockPos: BlockPos, blockState: BlockState) : Mattery fillInput.handler(object : HandlerFilter { override fun canInsert(slot: Int, stack: ItemStack): Boolean { if (fluid.isEmpty) { - return stack.getCapability(ForgeCapabilities.FLUID_HANDLER_ITEM).map { it.tanks > 0 }.orElse(false) + return stack.getCapability(Capabilities.FluidHandler.ITEM)?.let { it.tanks > 0 } ?: false } - return stack.getCapability(ForgeCapabilities.FLUID_HANDLER_ITEM).map { it.fill(fluid[0], IFluidHandler.FluidAction.SIMULATE) > 0 }.orElse(false) + return stack.getCapability(Capabilities.FluidHandler.ITEM)?.let { it.fill(fluid[0], IFluidHandler.FluidAction.SIMULATE) > 0 } ?: false } override fun canExtract(slot: Int, amount: Int, stack: ItemStack): Boolean { @@ -80,7 +79,7 @@ class FluidTankBlockEntity(blockPos: BlockPos, blockState: BlockState) : Mattery val item = drainInput[0] if (item.isNotEmpty) { - val cap = (if (item.count == 1) item else item.copyWithCount(1)).getCapability(ForgeCapabilities.FLUID_HANDLER_ITEM).orNull() + val cap = (if (item.count == 1) item else item.copyWithCount(1)).getCapability(Capabilities.FluidHandler.ITEM) if (cap == null) { if (output.consumeItem(item, simulate = false)) { @@ -106,7 +105,7 @@ class FluidTankBlockEntity(blockPos: BlockPos, blockState: BlockState) : Mattery if (moved0.isNotEmpty) { if (output.consumeItem(cap.container, simulate = true)) { - val cap1 = item.copyWithCount(1).getCapability(ForgeCapabilities.FLUID_HANDLER_ITEM).orNull() ?: throw ConcurrentModificationException() + val cap1 = item.copyWithCount(1).getCapability(Capabilities.FluidHandler.ITEM) ?: throw ConcurrentModificationException() val moved1 = moveFluid(source = cap1, destination = fluid) @@ -132,7 +131,7 @@ class FluidTankBlockEntity(blockPos: BlockPos, blockState: BlockState) : Mattery val item = fillInput[0] if (item.isNotEmpty) { - val cap = (if (item.count == 1) item else item.copyWithCount(1)).getCapability(ForgeCapabilities.FLUID_HANDLER_ITEM).orNull() + val cap = (if (item.count == 1) item else item.copyWithCount(1)).getCapability(Capabilities.FluidHandler.ITEM) if (cap == null) { if (output.consumeItem(item, simulate = false)) { @@ -158,7 +157,7 @@ class FluidTankBlockEntity(blockPos: BlockPos, blockState: BlockState) : Mattery if (moved0.isNotEmpty) { if (output.consumeItem(cap.container, simulate = true)) { - val cap1 = item.copyWithCount(1).getCapability(ForgeCapabilities.FLUID_HANDLER_ITEM).orNull() ?: throw ConcurrentModificationException() + val cap1 = item.copyWithCount(1).getCapability(Capabilities.FluidHandler.ITEM) ?: throw ConcurrentModificationException() val moved1 = moveFluid(source = fluid, destination = cap1) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/decorative/HoloSignBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/decorative/HoloSignBlockEntity.kt index 420932af9..34a356892 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/decorative/HoloSignBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/decorative/HoloSignBlockEntity.kt @@ -1,6 +1,7 @@ package ru.dbotthepony.mc.otm.block.entity.decorative import net.minecraft.core.BlockPos +import net.minecraft.core.HolderLookup import net.minecraft.nbt.CompoundTag import net.minecraft.network.chat.Component import net.minecraft.server.level.ServerLevel @@ -86,8 +87,8 @@ class HoloSignBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryB } } - override fun load(nbt: CompoundTag) { - super.load(nbt) + override fun loadAdditional(nbt: CompoundTag, registry: HolderLookup.Provider) { + super.loadAdditional(nbt, registry) if (!isLocked) signText = truncate(signText) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/decorative/InfiniteWaterSourceBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/decorative/InfiniteWaterSourceBlockEntity.kt index 57892f006..e6d2969fc 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/decorative/InfiniteWaterSourceBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/decorative/InfiniteWaterSourceBlockEntity.kt @@ -3,11 +3,11 @@ package ru.dbotthepony.mc.otm.block.entity.decorative import net.minecraft.core.BlockPos import net.minecraft.world.level.block.state.BlockState import net.minecraft.world.level.material.Fluids -import net.minecraftforge.common.capabilities.ForgeCapabilities -import net.minecraftforge.fluids.FluidStack -import net.minecraftforge.fluids.capability.IFluidHandler +import net.neoforged.neoforge.capabilities.Capabilities +import net.neoforged.neoforge.fluids.FluidStack +import net.neoforged.neoforge.fluids.capability.IFluidHandler import ru.dbotthepony.mc.otm.block.entity.MatteryBlockEntity -import ru.dbotthepony.mc.otm.core.ifPresentK +import ru.dbotthepony.mc.otm.core.math.RelativeSide import ru.dbotthepony.mc.otm.registry.MBlockEntities import java.util.function.Consumer @@ -45,18 +45,16 @@ class InfiniteWaterSourceBlockEntity(blockPos: BlockPos, blockState: BlockState) } init { - exposeGlobally(ForgeCapabilities.FLUID_HANDLER, this) + exposeGlobally(Capabilities.FluidHandler.BLOCK, this) - for (side in sides.values) { - val tracker = side.track(ForgeCapabilities.FLUID_HANDLER) + for (side in RelativeSide.entries) { + val tracker = CapabilityCache(side, Capabilities.FluidHandler.BLOCK) val ticker = tickList.Ticker { - tracker.get().ifPresentK { - it.fill(FluidStack(Fluids.WATER, Int.MAX_VALUE), IFluidHandler.FluidAction.EXECUTE) - } + tracker.get()?.fill(FluidStack(Fluids.WATER, Int.MAX_VALUE), IFluidHandler.FluidAction.EXECUTE) } - tracker.addListener(Consumer { ticker.isEnabled = it.isPresent }) + tracker.addListener(Consumer { ticker.isEnabled = tracker.isPresent }) } } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/decorative/PainterBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/decorative/PainterBlockEntity.kt index 5b594f8de..1c7542d3d 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/decorative/PainterBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/decorative/PainterBlockEntity.kt @@ -1,12 +1,11 @@ package ru.dbotthepony.mc.otm.block.entity.decorative import com.google.common.collect.ImmutableList -import com.mojang.datafixers.util.Either import it.unimi.dsi.fastutil.ints.Int2IntArrayMap import it.unimi.dsi.fastutil.objects.Object2IntArrayMap import it.unimi.dsi.fastutil.objects.Object2IntMap -import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap import net.minecraft.core.BlockPos +import net.minecraft.core.HolderLookup import net.minecraft.nbt.CompoundTag import net.minecraft.world.entity.player.Inventory import net.minecraft.world.entity.player.Player @@ -15,13 +14,12 @@ import net.minecraft.world.item.DyeColor import net.minecraft.world.item.ItemStack import net.minecraft.world.level.block.state.BlockState import net.minecraft.world.level.material.Fluids -import net.minecraftforge.common.capabilities.ForgeCapabilities -import net.minecraftforge.fluids.FluidStack -import net.minecraftforge.fluids.capability.IFluidHandler +import net.neoforged.neoforge.capabilities.Capabilities +import net.neoforged.neoforge.fluids.FluidStack +import net.neoforged.neoforge.fluids.capability.IFluidHandler import ru.dbotthepony.mc.otm.block.entity.MatteryDeviceBlockEntity import ru.dbotthepony.mc.otm.container.HandlerFilter import ru.dbotthepony.mc.otm.container.MatteryContainer -import ru.dbotthepony.mc.otm.core.ifPresentK import ru.dbotthepony.mc.otm.core.immutableList import ru.dbotthepony.mc.otm.core.immutableMap import ru.dbotthepony.mc.otm.core.isNotEmpty @@ -85,7 +83,7 @@ class PainterBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryDe addDroppableContainer(dyeInput) savetables.stateful(dyeInput, INVENTORY_KEY) savetables.bool(::isBulk) - exposeGlobally(ForgeCapabilities.FLUID_HANDLER, this) + exposeGlobally(Capabilities.FluidHandler.BLOCK, this) } fun takeDyes(dyes: Map) { @@ -113,7 +111,7 @@ class PainterBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryDe val config = ConfigurableItemHandler(input = dyeInput.handler(object : HandlerFilter { override fun canInsert(slot: Int, stack: ItemStack): Boolean { if (waterStored() < MAX_WATER_STORAGE) { - stack.getCapability(ForgeCapabilities.FLUID_HANDLER_ITEM).ifPresentK { + stack.getCapability(Capabilities.FluidHandler.ITEM)?.let { val drain = it.drain(FluidStack(Fluids.WATER, MAX_WATER_STORAGE - waterStored()), IFluidHandler.FluidAction.SIMULATE) if (drain.isNotEmpty) { @@ -127,7 +125,7 @@ class PainterBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryDe } override fun modifyInsertCount(slot: Int, stack: ItemStack, existing: ItemStack, simulate: Boolean): Int { - if (!stack.equals(existing, false)) + if (!ItemStack.isSameItemSameComponents(stack, existing)) return super.modifyInsertCount(slot, stack, existing, simulate) val dye = DyeColor.entries.firstOrNull { stack.`is`(it.tag) } ?: return 0 @@ -147,8 +145,8 @@ class PainterBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryDe return dyeStored.getInt(dye) } - override fun saveShared(nbt: CompoundTag) { - super.saveShared(nbt) + override fun saveShared(nbt: CompoundTag, registry: HolderLookup.Provider) { + super.saveShared(nbt, registry) nbt["dyes"] = CompoundTag().also { for ((k, v) in dyeStored) { @@ -157,8 +155,8 @@ class PainterBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryDe } } - override fun load(nbt: CompoundTag) { - super.load(nbt) + override fun loadAdditional(nbt: CompoundTag, registry: HolderLookup.Provider) { + super.loadAdditional(nbt, registry) dyeStored.clear() @@ -177,7 +175,7 @@ class PainterBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryDe for (slot in dyeInput.slotIterator()) { if (waterStored() < MAX_WATER_STORAGE) { - slot.item.getCapability(ForgeCapabilities.FLUID_HANDLER_ITEM).ifPresentK { + slot.item.getCapability(Capabilities.FluidHandler.ITEM)?.let { val drain = it.drain(FluidStack(Fluids.WATER, MAX_WATER_STORAGE - waterStored()), IFluidHandler.FluidAction.EXECUTE) if (drain.isNotEmpty) { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterBottlerBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterBottlerBlockEntity.kt index 4f1e6a8fd..04843effc 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterBottlerBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterBottlerBlockEntity.kt @@ -81,13 +81,13 @@ class MatterBottlerBlockEntity(blockPos: BlockPos, blockState: BlockState) : val bottlingHandler = bottling.handler(object : HandlerFilter { override fun canInsert(slot: Int, stack: ItemStack): Boolean { - return isBottling && stack.getCapability(MatteryCapability.MATTER).map { it.matterFlow.input && it.missingMatter.isPositive }.orElse(false) + return isBottling && stack.getCapability(MatteryCapability.MATTER_ITEM)?.let { it.matterFlow.input && it.missingMatter.isPositive } ?: false } }) val unbottlingHandler = unbottling.handler(object : HandlerFilter { override fun canInsert(slot: Int, stack: ItemStack): Boolean { - return !isBottling && stack.getCapability(MatteryCapability.MATTER).map { it.matterFlow.output && it.storedMatter.isPositive }.orElse(false) + return !isBottling && stack.getCapability(MatteryCapability.MATTER_ITEM)?.let { it.matterFlow.output && it.storedMatter.isPositive } ?: false } }) @@ -109,7 +109,7 @@ class MatterBottlerBlockEntity(blockPos: BlockPos, blockState: BlockState) : val matterNode = SimpleMatterNode(matter = matter) init { - exposeGlobally(MatteryCapability.MATTER, matter) + exposeGlobally(MatteryCapability.MATTER_BLOCK, matter) exposeGlobally(MatteryCapability.MATTER_NODE, matterNode) savetables.bool(::isBottling) @@ -145,7 +145,7 @@ class MatterBottlerBlockEntity(blockPos: BlockPos, blockState: BlockState) : var state = blockState for (i in 0 .. 2) { - val desired = !container.getItem(i).isEmpty && container.getItem(i).getCapability(MatteryCapability.MATTER).isPresent + val desired = !container.getItem(i).isEmpty && container.getItem(i).getCapability(MatteryCapability.MATTER_ITEM) != null if (state.getValue(MatterBottlerBlock.SLOT_PROPERTIES[i]) != desired) { state = state.setValue(MatterBottlerBlock.SLOT_PROPERTIES[i], desired) @@ -190,7 +190,7 @@ class MatterBottlerBlockEntity(blockPos: BlockPos, blockState: BlockState) : for (slot in bottling.slotIterator()) { val item = slot.item - item.getCapability(MatteryCapability.MATTER).ifPresentK { + item.getCapability(MatteryCapability.MATTER_ITEM)?.let { if (!it.missingMatter.isPositive) { unbottling.consumeItem(item, false) slot.setChanged() @@ -256,7 +256,7 @@ class MatterBottlerBlockEntity(blockPos: BlockPos, blockState: BlockState) : for (slot in unbottling.slotIterator()) { val item = slot.item - item.getCapability(MatteryCapability.MATTER).ifPresentK { + item.getCapability(MatteryCapability.MATTER_ITEM)?.let { if (!it.storedMatter.isPositive) { bottling.consumeItem(item, false) slot.setChanged() diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterCapacitorBankBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterCapacitorBankBlockEntity.kt index a8e6df930..34598cccf 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterCapacitorBankBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterCapacitorBankBlockEntity.kt @@ -19,7 +19,6 @@ import ru.dbotthepony.mc.otm.container.HandlerFilter import ru.dbotthepony.mc.otm.container.MatteryContainer import ru.dbotthepony.mc.otm.core.immutableList import ru.dbotthepony.mc.otm.core.math.Decimal -import ru.dbotthepony.mc.otm.core.ifPresentK import ru.dbotthepony.mc.otm.graph.matter.SimpleMatterNode import ru.dbotthepony.mc.otm.menu.matter.MatterCapacitorBankMenu import ru.dbotthepony.mc.otm.registry.MBlockEntities @@ -39,7 +38,7 @@ class MatterCapacitorBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) for (stack in container) if (!stack.isEmpty) - stack.getCapability(MatteryCapability.MATTER).ifPresentK { + stack.getCapability(MatteryCapability.MATTER_ITEM)?.let { summ += it.storedMatter } @@ -55,7 +54,7 @@ class MatterCapacitorBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) for (stack in container) if (!stack.isEmpty) - stack.getCapability(MatteryCapability.MATTER).ifPresentK { + stack.getCapability(MatteryCapability.MATTER_ITEM)?.let { summ += it.maxStoredMatter } @@ -72,7 +71,7 @@ class MatterCapacitorBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) for (stack in container) { if (!stack.isEmpty) { - stack.getCapability(MatteryCapability.MATTER).ifPresent { + stack.getCapability(MatteryCapability.MATTER_ITEM)?.let { val diff = it.receiveMatterChecked(howMuch, simulate) summ += diff howMuch -= diff @@ -101,7 +100,7 @@ class MatterCapacitorBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) for (stack in container) { if (!stack.isEmpty) { - stack.getCapability(MatteryCapability.MATTER).ifPresent { + stack.getCapability(MatteryCapability.MATTER_ITEM)?.let { val diff = it.extractMatterChecked(howMuch, simulate) summ += diff howMuch -= diff @@ -123,10 +122,10 @@ class MatterCapacitorBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) override val matterFlow: FlowDirection get() = FlowDirection.BI_DIRECTIONAL - val container = object : MatteryContainer(this::markDirtyFast, BatteryBankBlockEntity.CAPACITY) { + val container = object : MatteryContainer(::markDirtyFast, BatteryBankBlockEntity.CAPACITY) { override fun setChanged(slot: Int, new: ItemStack, old: ItemStack) { super.setChanged(slot, new, old) - capacitorStatus[slot].value = new.getCapability(MatteryCapability.MATTER).isPresent + capacitorStatus[slot].value = new.getCapability(MatteryCapability.MATTER_ITEM) != null gaugeLevel = storedMatter.percentage(maxStoredMatter) } @@ -135,11 +134,11 @@ class MatterCapacitorBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) val itemConfig = ConfigurableItemHandler(inputOutput = container.handler(object : HandlerFilter { override fun canInsert(slot: Int, stack: ItemStack): Boolean { - return stack.getCapability(MatteryCapability.MATTER).isPresent + return stack.getCapability(MatteryCapability.MATTER_ITEM) != null } override fun canExtract(slot: Int, amount: Int, stack: ItemStack): Boolean { - stack.getCapability(MatteryCapability.MATTER).ifPresentK { + stack.getCapability(MatteryCapability.MATTER_ITEM)?.let { if (it.storedMatter.isPositive) { return false } @@ -155,7 +154,7 @@ class MatterCapacitorBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) init { savetables.stateful(::container, INVENTORY_KEY) - exposeGlobally(MatteryCapability.MATTER, this) + exposeGlobally(MatteryCapability.MATTER_BLOCK, this) exposeGlobally(MatteryCapability.MATTER_NODE, matterNode) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterDecomposerBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterDecomposerBlockEntity.kt index d454e94b3..f3f5fc62f 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterDecomposerBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterDecomposerBlockEntity.kt @@ -67,7 +67,7 @@ class MatterDecomposerBlockEntity(pos: BlockPos, state: BlockState) val matterNode = SimpleMatterNode(matter = matter) init { - exposeGlobally(MatteryCapability.MATTER, matter) + exposeGlobally(MatteryCapability.MATTER_BLOCK, matter) exposeGlobally(MatteryCapability.MATTER_NODE, matterNode) savetables.stateful(::matter, MATTER_STORAGE_KEY) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterEntanglerBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterEntanglerBlockEntity.kt index 40c2212b5..6860f13b8 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterEntanglerBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterEntanglerBlockEntity.kt @@ -7,9 +7,10 @@ import net.minecraft.world.entity.player.Inventory import net.minecraft.world.entity.player.Player import net.minecraft.world.inventory.AbstractContainerMenu import net.minecraft.world.item.ItemStack +import net.minecraft.world.item.crafting.CraftingInput import net.minecraft.world.level.Level import net.minecraft.world.level.block.state.BlockState -import net.minecraftforge.common.capabilities.ForgeCapabilities +import net.neoforged.neoforge.capabilities.Capabilities import ru.dbotthepony.mc.otm.block.entity.ExperienceStorage import ru.dbotthepony.mc.otm.block.entity.ItemJob import ru.dbotthepony.mc.otm.block.entity.JobContainer @@ -26,7 +27,6 @@ import ru.dbotthepony.mc.otm.config.MachinesConfig import ru.dbotthepony.mc.otm.container.MatteryCraftingContainer import ru.dbotthepony.mc.otm.container.HandlerFilter import ru.dbotthepony.mc.otm.container.MatteryContainer -import ru.dbotthepony.mc.otm.container.ShadowCraftingContainer import ru.dbotthepony.mc.otm.container.UpgradeContainer import ru.dbotthepony.mc.otm.core.math.Decimal import ru.dbotthepony.mc.otm.data.DecimalCodec @@ -75,12 +75,13 @@ class MatterEntanglerBlockEntity(blockPos: BlockPos, blockState: BlockState) : M val itemConfig = ConfigurableItemHandler( input = inputs.handler(object : HandlerFilter { override fun canInsert(slot: Int, stack: ItemStack): Boolean { - val shadow = ShadowCraftingContainer.shadow(inputs, slot, stack) + val list = inputs.toList() + list[slot] = stack + val shadow = CraftingInput.of(3, 3, list) return (level ?: return false) .recipeManager .byType(MRecipes.MATTER_ENTANGLER) - .values .any { it.value.preemptivelyMatches(shadow, level!!) } } @@ -92,7 +93,7 @@ class MatterEntanglerBlockEntity(blockPos: BlockPos, blockState: BlockState) : M ) init { - exposeGlobally(ForgeCapabilities.FLUID_HANDLER, experience) + exposeGlobally(Capabilities.FluidHandler.BLOCK, experience) savetables.stateful(::energy, ENERGY_KEY) savetables.stateful(::matter, MATTER_STORAGE_KEY) @@ -102,7 +103,7 @@ class MatterEntanglerBlockEntity(blockPos: BlockPos, blockState: BlockState) : M savetables.stateful(::experience) exposeGlobally(MatteryCapability.MATTER_NODE, node) - exposeGlobally(MatteryCapability.MATTER, matter) + exposeGlobally(MatteryCapability.MATTER_BLOCK, matter) } override fun setLevel(level: Level) { @@ -144,16 +145,17 @@ class MatterEntanglerBlockEntity(blockPos: BlockPos, blockState: BlockState) : M if (!energy.batteryLevel.isPositive) return JobContainer.noEnergy() + val inputs = CraftingInput.of(3, 3, inputs.toList()) + val recipe = (level ?: return JobContainer.failure()) .recipeManager .byType(MRecipes.MATTER_ENTANGLER) - .values .firstOrNull { it.value.matches(inputs, level!!) } ?: return JobContainer.noItem() val result = recipe.value.assemble(inputs, level!!.registryAccess()) - inputs.forEach { it.shrink(1) } - inputs.setChanged() + this.inputs.forEach { it.shrink(1) } + this.inputs.setChanged() return JobContainer.success( Job( diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterPanelBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterPanelBlockEntity.kt index ae73612fd..e9a165d62 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterPanelBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterPanelBlockEntity.kt @@ -3,27 +3,28 @@ package ru.dbotthepony.mc.otm.block.entity.matter import it.unimi.dsi.fastutil.objects.Object2ObjectFunction import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap import net.minecraft.core.BlockPos -import net.minecraft.world.level.block.state.BlockState -import ru.dbotthepony.mc.otm.menu.matter.MatterPanelMenu +import net.minecraft.core.HolderLookup +import net.minecraft.nbt.CompoundTag +import net.minecraft.nbt.ListTag import net.minecraft.world.entity.player.Inventory import net.minecraft.world.entity.player.Player import net.minecraft.world.inventory.AbstractContainerMenu -import ru.dbotthepony.mc.otm.capability.MatteryCapability -import net.minecraft.nbt.CompoundTag -import net.minecraft.nbt.ListTag import net.minecraft.world.level.Level -import net.minecraftforge.common.util.INBTSerializable +import net.minecraft.world.level.block.state.BlockState import ru.dbotthepony.mc.otm.block.entity.MatteryDeviceBlockEntity -import ru.dbotthepony.mc.otm.capability.matter.* +import ru.dbotthepony.mc.otm.capability.MatteryCapability +import ru.dbotthepony.mc.otm.capability.matter.IReplicationTaskProvider +import ru.dbotthepony.mc.otm.capability.matter.PatternState +import ru.dbotthepony.mc.otm.capability.matter.ReplicationTask +import ru.dbotthepony.mc.otm.capability.matter.ReplicationTaskAllocation import ru.dbotthepony.mc.otm.core.collect.WeakHashSet -import ru.dbotthepony.mc.otm.core.nbt.getBoolean import ru.dbotthepony.mc.otm.core.nbt.getCompoundList import ru.dbotthepony.mc.otm.core.nbt.map -import ru.dbotthepony.mc.otm.core.nbt.mapString import ru.dbotthepony.mc.otm.core.nbt.set import ru.dbotthepony.mc.otm.core.util.ItemSorter import ru.dbotthepony.mc.otm.graph.matter.SimpleMatterNode import ru.dbotthepony.mc.otm.menu.IItemSortingSettings +import ru.dbotthepony.mc.otm.menu.matter.MatterPanelMenu import ru.dbotthepony.mc.otm.registry.MBlockEntities import java.util.* import java.util.stream.Stream @@ -81,7 +82,7 @@ class MatterPanelBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matte init { exposeGlobally(MatteryCapability.MATTER_NODE, matterNode) - exposeGlobally(MatteryCapability.TASK, this) + exposeGlobally(MatteryCapability.REPLICATION_TASK, this) savetables.bool(::isProvidingTasks) } @@ -149,8 +150,8 @@ class MatterPanelBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matte return true } - override fun saveShared(nbt: CompoundTag) { - super.saveShared(nbt) + override fun saveShared(nbt: CompoundTag, registry: HolderLookup.Provider) { + super.saveShared(nbt, registry) val list = ListTag() @@ -163,14 +164,14 @@ class MatterPanelBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matte val settings = CompoundTag() for ((uuid, value) in playerSettings) { - settings[uuid.toString()] = value.serializeNBT() + settings[uuid.toString()] = value.serializeNBT(registry) } nbt["settings"] = settings } - override fun load(nbt: CompoundTag) { - super.load(nbt) + override fun loadAdditional(nbt: CompoundTag, registry: HolderLookup.Provider) { + super.loadAdditional(nbt, registry) _tasks.clear() val list = nbt.getCompoundList("tasks") @@ -186,8 +187,9 @@ class MatterPanelBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matte nbt.map("settings") { it: CompoundTag -> for (k in it.allKeys) { - playerSettings.computeIfAbsent(UUID.fromString(k), Object2ObjectFunction { PlayerSettings() }) - .deserializeNBT(it.getCompound(k)) + playerSettings + .computeIfAbsent(UUID.fromString(k), Object2ObjectFunction { PlayerSettings() }) + .deserializeNBT(registry, it.getCompound(k)) } } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterReconstructorBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterReconstructorBlockEntity.kt index 2245711ed..9006e64d9 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterReconstructorBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterReconstructorBlockEntity.kt @@ -1,6 +1,7 @@ package ru.dbotthepony.mc.otm.block.entity.matter import net.minecraft.core.BlockPos +import net.minecraft.core.registries.BuiltInRegistries import net.minecraft.nbt.StringTag import net.minecraft.resources.ResourceLocation import net.minecraft.world.entity.player.Inventory @@ -10,7 +11,6 @@ import net.minecraft.world.item.Item import net.minecraft.world.item.ItemStack import net.minecraft.world.level.Level import net.minecraft.world.level.block.state.BlockState -import net.minecraftforge.registries.ForgeRegistries import ru.dbotthepony.kommons.util.getValue import ru.dbotthepony.kommons.util.setValue import ru.dbotthepony.mc.otm.block.entity.MatteryPoweredBlockEntity @@ -78,7 +78,7 @@ class MatterReconstructorBlockEntity(blockPos: BlockPos, blockState: BlockState) } init { - exposeGlobally(MatteryCapability.MATTER, matter) + exposeGlobally(MatteryCapability.MATTER_BLOCK, matter) exposeGlobally(MatteryCapability.MATTER_NODE, matterNode) savetables.stateful(::repairContainer) @@ -92,7 +92,7 @@ class MatterReconstructorBlockEntity(blockPos: BlockPos, blockState: BlockState) savetables.Stateless(::lastItem, type = StringTag::class.java) .withSerializer { it?.registryName?.toString()?.let(StringTag::valueOf) } - .withDeserializer { ResourceLocation.tryParse(it.asString)?.let { ForgeRegistries.ITEMS.getValue(it) } } + .withDeserializer { ResourceLocation.tryParse(it.asString)?.let { BuiltInRegistries.ITEM.get(it) } } } val energyConfig = ConfigurableEnergy(energy) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterRecyclerBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterRecyclerBlockEntity.kt index 1602236fb..e1a4d9e3d 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterRecyclerBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterRecyclerBlockEntity.kt @@ -66,7 +66,7 @@ class MatterRecyclerBlockEntity(blockPos: BlockPos, blockState: BlockState) val energyConfig = ConfigurableEnergy(energy) init { - exposeGlobally(MatteryCapability.MATTER, matter) + exposeGlobally(MatteryCapability.MATTER_BLOCK, matter) exposeGlobally(MatteryCapability.MATTER_NODE, matterNode) savetables.stateful(::energy, ENERGY_KEY) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterReplicatorBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterReplicatorBlockEntity.kt index bcc8d307e..5130d082a 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterReplicatorBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterReplicatorBlockEntity.kt @@ -30,7 +30,6 @@ import ru.dbotthepony.mc.otm.container.UpgradeContainer import ru.dbotthepony.mc.otm.core.math.Decimal import ru.dbotthepony.mc.otm.core.util.item import ru.dbotthepony.mc.otm.data.DecimalCodec -import ru.dbotthepony.mc.otm.data.UUIDCodec import ru.dbotthepony.mc.otm.data.minRange import ru.dbotthepony.mc.otm.graph.matter.MatterNode import ru.dbotthepony.mc.otm.matter.MatterManager @@ -96,7 +95,7 @@ class MatterReplicatorBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : } init { - exposeGlobally(MatteryCapability.MATTER, matter) + exposeGlobally(MatteryCapability.MATTER_BLOCK, matter) exposeGlobally(MatteryCapability.MATTER_NODE, matterNode) savetables.stateful(::energy, ENERGY_KEY) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterScannerBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterScannerBlockEntity.kt index baeadaa50..8af075a13 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterScannerBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterScannerBlockEntity.kt @@ -72,11 +72,6 @@ class MatterScannerBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : savetables.stateful(::upgrades) } - override fun invalidateCaps() { - super.invalidateCaps() - matterNode.isValid = false - } - override fun setRemoved() { super.setRemoved() matterNode.isValid = false diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/PatternStorageBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/PatternStorageBlockEntity.kt index 6048a42d5..2ee1873c1 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/PatternStorageBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/PatternStorageBlockEntity.kt @@ -19,7 +19,6 @@ import ru.dbotthepony.mc.otm.core.collect.filterNotNull import ru.dbotthepony.mc.otm.core.collect.map import ru.dbotthepony.mc.otm.core.filterNotNull import ru.dbotthepony.mc.otm.core.isNotEmpty -import ru.dbotthepony.mc.otm.core.orNull import ru.dbotthepony.mc.otm.graph.matter.SimpleMatterNode import ru.dbotthepony.mc.otm.registry.MBlockEntities import java.util.stream.Stream @@ -29,17 +28,17 @@ class PatternStorageBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : val matterNode = SimpleMatterNode(patterns = this) - val container: MatteryContainer = object : MatteryContainer(this::setChanged, 8) { + val container: MatteryContainer = object : MatteryContainer(::markDirtyFast, 8) { override fun setChanged(slot: Int, new: ItemStack, old: ItemStack) { - if (!ItemStack.isSameItemSameTags(new, old)) { + if (!ItemStack.isSameItemSameComponents(new, old)) { if (!old.isEmpty) { - old.getCapability(MatteryCapability.PATTERN).ifPresent { cap: IPatternStorage -> + old.getCapability(MatteryCapability.PATTERN_ITEM)?.let { cap: IPatternStorage -> cap.patterns.forEach { matterNode.graph.onPatternRemoved(it) } } } if (!new.isEmpty) { - new.getCapability(MatteryCapability.PATTERN).ifPresent { cap: IPatternStorage -> + new.getCapability(MatteryCapability.PATTERN_ITEM)?.let { cap: IPatternStorage -> cap.patterns.forEach { matterNode.graph.onPatternAdded(it) } } } @@ -61,7 +60,7 @@ class PatternStorageBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : for (i in 0..7) { state = state.setValue( PatternStorageBlock.PATTERN_STORAGE_DISKS_PROPS[i], - this.container.getItem(i).getCapability(MatteryCapability.PATTERN).isPresent + this.container.getItem(i).getCapability(MatteryCapability.PATTERN_ITEM) != null ) } @@ -77,13 +76,8 @@ class PatternStorageBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : matterNode.discover(this) } - override fun invalidateCaps() { - super.invalidateCaps() - matterNode.isValid = false - } - init { - exposeGlobally(MatteryCapability.PATTERN, this) + exposeGlobally(MatteryCapability.PATTERN_BLOCK, this) exposeGlobally(MatteryCapability.MATTER_NODE, matterNode) savetables.stateful(::container, INVENTORY_KEY) @@ -96,7 +90,7 @@ class PatternStorageBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : override val patterns: Stream get() { return container.stream() .filter { it.isNotEmpty } - .map { it.getCapability(MatteryCapability.PATTERN).orNull() } + .map { it.getCapability(MatteryCapability.PATTERN_ITEM) } .filterNotNull() .flatMap { it.patterns } } @@ -104,7 +98,7 @@ class PatternStorageBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : override val patternCapacity: Int get() { var stored = 0L - for (pattern in this.container.iterator().map { it.getCapability(MatteryCapability.PATTERN).orNull() }.filterNotNull()) + for (pattern in this.container.iterator().map { it.getCapability(MatteryCapability.PATTERN_ITEM) }.filterNotNull()) stored += pattern.patternCapacity.toLong() return if (stored > Int.MAX_VALUE) Int.MAX_VALUE else stored.toInt() @@ -113,7 +107,7 @@ class PatternStorageBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : override val storedPatterns: Int get() { var stored = 0L - for (pattern in this.container.iterator().map { it.getCapability(MatteryCapability.PATTERN).orNull() }.filterNotNull()) + for (pattern in this.container.iterator().map { it.getCapability(MatteryCapability.PATTERN_ITEM) }.filterNotNull()) stored += pattern.storedPatterns.toLong() return if (stored > Int.MAX_VALUE) Int.MAX_VALUE else stored.toInt() @@ -125,7 +119,7 @@ class PatternStorageBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : } override fun insertPattern(pattern: PatternState, onlyUpdate: Boolean, simulate: Boolean): PatternInsertStatus { - for (spattern in this.container.iterator().map { it.getCapability(MatteryCapability.PATTERN).orNull() }.filterNotNull()) { + for (spattern in this.container.iterator().map { it.getCapability(MatteryCapability.PATTERN_ITEM) }.filterNotNull()) { val status = spattern.insertPattern(pattern, onlyUpdate, simulate) if (!status.isFailed) { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/DriveRackBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/DriveRackBlockEntity.kt index 43d369993..dbd81872b 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/DriveRackBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/DriveRackBlockEntity.kt @@ -15,7 +15,6 @@ import ru.dbotthepony.mc.otm.capability.energy.ProfiledEnergyStorage import ru.dbotthepony.mc.otm.capability.energy.WorkerEnergyStorage import ru.dbotthepony.mc.otm.config.MachinesConfig import ru.dbotthepony.mc.otm.container.MatteryContainer -import ru.dbotthepony.mc.otm.core.ifPresentK import ru.dbotthepony.mc.otm.menu.storage.DriveRackMenu import ru.dbotthepony.mc.otm.registry.MBlockEntities import ru.dbotthepony.mc.otm.storage.optics.priority @@ -46,15 +45,15 @@ class DriveRackBlockEntity(blockPos: BlockPos, blockState: BlockState) : Mattery markDirtyFast() } - val container: MatteryContainer = object : MatteryContainer(this::setChanged, 4) { + val container: MatteryContainer = object : MatteryContainer(::markDirtyFast, 4) { override fun setChanged(slot: Int, new: ItemStack, old: ItemStack) { super.setChanged(slot, new, old) - old.getCapability(MatteryCapability.DRIVE).ifPresentK { + old.getCapability(MatteryCapability.CONDENSATION_DRIVE)?.let { cell.removeStorageComponent(it.priority(::insertPriority, ::extractPriority).powered(energy).flow(::mode)) } - new.getCapability(MatteryCapability.DRIVE).ifPresentK { + new.getCapability(MatteryCapability.CONDENSATION_DRIVE)?.let { cell.addStorageComponent(it.priority(::insertPriority, ::extractPriority).powered(energy).flow(::mode)) } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/DriveViewerBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/DriveViewerBlockEntity.kt index d6dee99b5..3d6bf153f 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/DriveViewerBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/DriveViewerBlockEntity.kt @@ -29,7 +29,7 @@ class DriveViewerBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matte override val energy = ProfiledEnergyStorage(WorkerEnergyStorage(this::energyUpdated, MachinesConfig.DRIVE_VIEWER)) val energyConfig = ConfigurableEnergy(energy) - val container: MatteryContainer = object : MatteryContainer(this::markDirtyFast, 1) { + val container: MatteryContainer = object : MatteryContainer(::markDirtyFast, 1) { override fun setChanged(slot: Int, new: ItemStack, old: ItemStack) { super.setChanged(slot, new, old) @@ -37,7 +37,7 @@ class DriveViewerBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matte if (level is ServerLevel) { tickList.once { - val isPresent = new.getCapability(MatteryCapability.DRIVE).isPresent + val isPresent = new.getCapability(MatteryCapability.CONDENSATION_DRIVE) != null var state = this@DriveViewerBlockEntity.blockState.setValue(DriveViewerBlock.DRIVE_PRESENT, isPresent) if (!isPresent) { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/ItemMonitorBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/ItemMonitorBlockEntity.kt index 970a12ba2..19b7836b2 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/ItemMonitorBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/ItemMonitorBlockEntity.kt @@ -3,6 +3,7 @@ package ru.dbotthepony.mc.otm.block.entity.storage import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap import net.minecraft.core.BlockPos +import net.minecraft.core.HolderLookup import net.minecraft.core.NonNullList import net.minecraft.nbt.CompoundTag import net.minecraft.network.chat.Component @@ -11,15 +12,13 @@ import net.minecraft.world.Container import net.minecraft.world.entity.player.Inventory import net.minecraft.world.entity.player.Player import net.minecraft.world.inventory.AbstractContainerMenu -import net.minecraft.world.inventory.TransientCraftingContainer import net.minecraft.world.item.ItemStack import net.minecraft.world.item.crafting.CraftingRecipe import net.minecraft.world.item.crafting.RecipeType import net.minecraft.world.level.Level import net.minecraft.world.level.block.state.BlockState -import net.minecraftforge.common.ForgeHooks -import net.minecraftforge.common.util.INBTSerializable -import ru.dbotthepony.mc.otm.core.TranslatableComponent +import net.neoforged.neoforge.common.CommonHooks +import net.neoforged.neoforge.common.util.INBTSerializable import ru.dbotthepony.mc.otm.block.entity.MatteryPoweredBlockEntity import ru.dbotthepony.mc.otm.capability.MatteryCapability import ru.dbotthepony.mc.otm.capability.energy.ProfiledEnergyStorage @@ -27,28 +26,35 @@ import ru.dbotthepony.mc.otm.capability.energy.WorkerEnergyStorage import ru.dbotthepony.mc.otm.capability.matteryPlayer import ru.dbotthepony.mc.otm.client.render.IGUIRenderable import ru.dbotthepony.mc.otm.client.render.UVWindingOrder +import ru.dbotthepony.mc.otm.client.render.Widgets8 import ru.dbotthepony.mc.otm.config.MachinesConfig -import ru.dbotthepony.mc.otm.container.MatteryContainer -import ru.dbotthepony.mc.otm.graph.storage.StorageNode -import ru.dbotthepony.mc.otm.graph.storage.StorageGraph -import ru.dbotthepony.mc.otm.registry.MBlockEntities -import ru.dbotthepony.mc.otm.container.set +import ru.dbotthepony.mc.otm.container.CombinedContainer +import ru.dbotthepony.mc.otm.container.MatteryCraftingContainer +import ru.dbotthepony.mc.otm.container.util.slotIterator +import ru.dbotthepony.mc.otm.core.TranslatableComponent +import ru.dbotthepony.mc.otm.core.collect.map +import ru.dbotthepony.mc.otm.core.collect.toList +import ru.dbotthepony.mc.otm.core.isNotEmpty import ru.dbotthepony.mc.otm.core.nbt.mapString import ru.dbotthepony.mc.otm.core.nbt.set +import ru.dbotthepony.mc.otm.core.util.ItemStorageStackSorter +import ru.dbotthepony.mc.otm.graph.storage.StorageGraph +import ru.dbotthepony.mc.otm.graph.storage.StorageNode import ru.dbotthepony.mc.otm.menu.storage.ItemMonitorMenu -import ru.dbotthepony.mc.otm.storage.* +import ru.dbotthepony.mc.otm.registry.MBlockEntities +import ru.dbotthepony.mc.otm.storage.IStorageEventConsumer +import ru.dbotthepony.mc.otm.storage.IStorageProvider +import ru.dbotthepony.mc.otm.storage.ItemStorageStack +import ru.dbotthepony.mc.otm.storage.StorageStack import ru.dbotthepony.mc.otm.storage.powered.PoweredVirtualComponent import java.math.BigInteger import java.util.* import kotlin.collections.HashMap -import ru.dbotthepony.mc.otm.client.render.Widgets8 -import ru.dbotthepony.mc.otm.container.CombinedContainer -import ru.dbotthepony.mc.otm.container.MatteryCraftingContainer -import ru.dbotthepony.mc.otm.container.util.slotIterator -import ru.dbotthepony.mc.otm.core.collect.map -import ru.dbotthepony.mc.otm.core.collect.toList -import ru.dbotthepony.mc.otm.core.isNotEmpty -import ru.dbotthepony.mc.otm.core.util.ItemStorageStackSorter +import kotlin.collections.component1 +import kotlin.collections.component2 +import kotlin.collections.indices +import kotlin.collections.iterator +import kotlin.collections.set interface IItemMonitorPlayerSettings { var ingredientPriority: ItemMonitorPlayerSettings.IngredientPriority @@ -64,7 +70,7 @@ private fun takeOne(inventory: Container?, item: ItemStack): Boolean { for (slot in iterator) { val stack = slot.item - if (stack.equals(item, false)) { + if (ItemStack.isSameItemSameComponents(stack, item)) { stack.shrink(1) slot.setChanged() return true @@ -154,7 +160,7 @@ class ItemMonitorPlayerSettings : INBTSerializable, IItemMonitorPla override var sorting: ItemStorageStackSorter = ItemStorageStackSorter.DEFAULT override var ascendingSort: Boolean = false - override fun serializeNBT(): CompoundTag { + override fun serializeNBT(registry: HolderLookup.Provider): CompoundTag { return CompoundTag().also { it["ingredientPriority"] = ingredientPriority.name it["resultTarget"] = resultTarget.name @@ -164,7 +170,7 @@ class ItemMonitorPlayerSettings : INBTSerializable, IItemMonitorPla } } - override fun deserializeNBT(nbt: CompoundTag) { + override fun deserializeNBT(registry: HolderLookup.Provider, nbt: CompoundTag) { ingredientPriority = nbt.mapString("ingredientPriority", IngredientPriority::valueOf, IngredientPriority.SYSTEM) resultTarget = nbt.mapString("resultTarget", ResultTarget::valueOf, ResultTarget.MIXED) craftingAmount = nbt.mapString("quickCraftAmount", Amount::valueOf, Amount.STACK) @@ -227,10 +233,10 @@ class ItemMonitorBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matte val server = level.server ?: return false var craftingRecipe = craftingRecipe - if (craftingRecipe != null && craftingRecipe.matches(craftingGrid, level)) return true + if (craftingRecipe != null && craftingRecipe.matches(craftingGrid.asCraftInput(), level)) return true if (justCheckForRecipeChange) return false - craftingRecipe = server.recipeManager.getRecipeFor(RecipeType.CRAFTING, craftingGrid, level).orElse(null)?.value + craftingRecipe = server.recipeManager.getRecipeFor(RecipeType.CRAFTING, craftingGrid.asCraftInput(), level).orElse(null)?.value Arrays.fill(craftingGridTuples, null) val poweredView = poweredView @@ -303,13 +309,14 @@ class ItemMonitorBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matte val craftingPlayer = craftingPlayer ?: return ItemStack.EMPTY try { - ForgeHooks.setCraftingPlayer(craftingPlayer) + CommonHooks.setCraftingPlayer(craftingPlayer) if (craftingRecipe.getResultItem(level.registryAccess()).count != amount) { return ItemStack.EMPTY } } finally { - ForgeHooks.setCraftingPlayer(null) + @Suppress("NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS") + CommonHooks.setCraftingPlayer(null) } craftingAmount[craftingPlayer] = craftingAmount.getInt(craftingPlayer) + 1 @@ -325,15 +332,16 @@ class ItemMonitorBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matte inProcessOfCraft = true try { - ForgeHooks.setCraftingPlayer(craftingPlayer) + CommonHooks.setCraftingPlayer(craftingPlayer) val residue: NonNullList val result: ItemStack try { - residue = craftingRecipe.getRemainingItems(craftingGrid) + residue = craftingRecipe.getRemainingItems(craftingGrid.asCraftInput()) result = craftingRecipe.getResultItem(level.registryAccess()) } finally { - ForgeHooks.setCraftingPlayer(null) + @Suppress("NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS") + CommonHooks.setCraftingPlayer(null) } check(residue.size == craftingGrid.containerSize) { "Container and residue list sizes mismatch: ${residue.size} != ${craftingGrid.containerSize}" } @@ -408,29 +416,29 @@ class ItemMonitorBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matte val craftingResultContainer = CraftingResultContainer() - override fun saveLevel(nbt: CompoundTag) { - super.saveLevel(nbt) + override fun saveLevel(nbt: CompoundTag, registry: HolderLookup.Provider) { + super.saveLevel(nbt, registry) nbt.put("player_settings", CompoundTag().also { for ((key, value) in this.settings) { - it[key.toString()] = value.serializeNBT() + it[key.toString()] = value.serializeNBT(registry) } }) - nbt["crafting_grid"] = craftingGrid.serializeNBT() + nbt["crafting_grid"] = craftingGrid.serializeNBT(registry) } - override fun load(nbt: CompoundTag) { - super.load(nbt) + override fun loadAdditional(nbt: CompoundTag, registry: HolderLookup.Provider) { + super.loadAdditional(nbt, registry) this.settings.clear() val settings = nbt.getCompound("player_settings") for (key in settings.allKeys) { - check(this.settings.put(UUID.fromString(key), ItemMonitorPlayerSettings().also { it.deserializeNBT(settings.getCompound(key)) }) == null) + check(this.settings.put(UUID.fromString(key), ItemMonitorPlayerSettings().also { it.deserializeNBT(registry, settings.getCompound(key)) }) == null) } - craftingGrid.deserializeNBT(nbt["crafting_grid"]) + craftingGrid.deserializeNBT(registry, nbt["crafting_grid"]) } fun getSettings(ply: ServerPlayer): ItemMonitorPlayerSettings { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/StorageBusBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/StorageBusBlockEntity.kt index 03a2ea81e..cc1c9610b 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/StorageBusBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/StorageBusBlockEntity.kt @@ -12,8 +12,8 @@ import net.minecraft.world.item.ItemStack import net.minecraft.world.level.Level import net.minecraft.world.level.block.Block import net.minecraft.world.level.block.state.BlockState -import net.minecraftforge.common.capabilities.ForgeCapabilities -import net.minecraftforge.items.IItemHandler +import net.neoforged.neoforge.capabilities.Capabilities +import net.neoforged.neoforge.items.IItemHandler import ru.dbotthepony.mc.otm.* import ru.dbotthepony.mc.otm.block.CableBlock import ru.dbotthepony.mc.otm.block.entity.MatteryPoweredBlockEntity @@ -102,10 +102,10 @@ class StorageBusBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matter savetables.int(::extractPriority) exposeGlobally(MatteryCapability.STORAGE_NODE, cell) { it != RelativeSide.FRONT } - side(RelativeSide.FRONT).track(ForgeCapabilities.ITEM_HANDLER).addListener(Consumer { + CapabilityCache(RelativeSide.FRONT, Capabilities.ItemHandler.BLOCK).addListener(Consumer { component?.let(cell::removeStorageComponent) - component = if (it.isPresent) { - ItemHandlerComponent(it.orThrow()).also { if (!redstoneControl.isBlockedByRedstone) cell.addStorageComponent(it) } + component = if (it != null) { + ItemHandlerComponent(it).also { if (!redstoneControl.isBlockedByRedstone) cell.addStorageComponent(it) } } else { null } @@ -353,7 +353,7 @@ class StorageBusBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matter } else if (current != null && last == null) { addTracked(slot, current) } else if (current != null && last != null) { - if (!ItemStack.isSameItemSameTags(current, last)) { + if (!ItemStack.isSameItemSameComponents(current, last)) { removeTracked(slot) addTracked(slot, current) } else if (current.count != last.count) { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/StorageInterfaces.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/StorageInterfaces.kt index e03e29597..e5c2c9c3d 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/StorageInterfaces.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/StorageInterfaces.kt @@ -11,8 +11,8 @@ import net.minecraft.world.level.Level import net.minecraft.world.level.block.Block import net.minecraft.world.level.block.entity.BlockEntityType import net.minecraft.world.level.block.state.BlockState -import net.minecraftforge.common.capabilities.ForgeCapabilities -import net.minecraftforge.items.IItemHandler +import net.neoforged.neoforge.capabilities.Capabilities +import net.neoforged.neoforge.items.IItemHandler import ru.dbotthepony.mc.otm.OverdriveThatMatters import ru.dbotthepony.mc.otm.SERVER_IS_LIVE import ru.dbotthepony.mc.otm.block.CableBlock @@ -27,7 +27,6 @@ import ru.dbotthepony.mc.otm.container.ItemFilter import ru.dbotthepony.mc.otm.core.TranslatableComponent import ru.dbotthepony.mc.otm.core.isNotEmpty import ru.dbotthepony.mc.otm.core.math.RelativeSide -import ru.dbotthepony.mc.otm.core.orNull import ru.dbotthepony.mc.otm.graph.storage.StorageNode import ru.dbotthepony.mc.otm.menu.storage.StorageImporterExporterMenu import ru.dbotthepony.mc.otm.once @@ -39,7 +38,6 @@ import ru.dbotthepony.mc.otm.storage.ItemStorageStack import ru.dbotthepony.mc.otm.storage.StorageStack import java.math.BigInteger import java.util.* -import kotlin.collections.ArrayList abstract class AbstractStorageImportExport( blockType: BlockEntityType<*>, @@ -97,7 +95,7 @@ abstract class AbstractStorageImportExport( cell.discover(this) } - protected val target = front.track(ForgeCapabilities.ITEM_HANDLER) + protected val target = CapabilityCache(RelativeSide.FRONT, Capabilities.ItemHandler.BLOCK) abstract val filter: ItemFilter @@ -122,7 +120,7 @@ class StorageImporterBlockEntity( private var nextTick = INTERVAL init { - front.Cap(ForgeCapabilities.ITEM_HANDLER, this) + exposeSided(RelativeSide.FRONT, Capabilities.ItemHandler.BLOCK, this) } override fun getSlots(): Int { @@ -190,7 +188,7 @@ class StorageImporterBlockEntity( nextTick-- - val target = target.get().orNull() + val target = target.get() if (nextTick <= 0 && target != null) { if (lastSlot >= target.slots) { @@ -280,7 +278,7 @@ class StorageExporterBlockEntity(blockPos: BlockPos, blockState: BlockState) : nextTick-- - val target = target.get().orNull() + val target = target.get() if (nextTick <= 0 && target != null) { val items = cell.graph.getVirtualComponent(StorageStack.ITEMS) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/AbstractPoweredFurnaceBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/AbstractPoweredFurnaceBlockEntity.kt index b2b69e2b1..94d8fd791 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/AbstractPoweredFurnaceBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/AbstractPoweredFurnaceBlockEntity.kt @@ -1,5 +1,6 @@ package ru.dbotthepony.mc.otm.block.entity.tech +import it.unimi.dsi.fastutil.ints.IntList import net.minecraft.core.BlockPos import net.minecraft.server.level.ServerLevel import net.minecraft.world.entity.player.Inventory @@ -9,19 +10,19 @@ import net.minecraft.world.item.ItemStack import net.minecraft.world.item.crafting.AbstractCookingRecipe import net.minecraft.world.item.crafting.BlastingRecipe import net.minecraft.world.item.crafting.RecipeType +import net.minecraft.world.item.crafting.SingleRecipeInput import net.minecraft.world.item.crafting.SmeltingRecipe import net.minecraft.world.item.crafting.SmokingRecipe import net.minecraft.world.level.block.entity.BlockEntityType import net.minecraft.world.level.block.state.BlockState -import net.minecraftforge.common.capabilities.ForgeCapabilities +import net.neoforged.neoforge.capabilities.Capabilities import ru.dbotthepony.kommons.util.getValue import ru.dbotthepony.kommons.util.setValue import ru.dbotthepony.mc.otm.block.entity.ExperienceStorage +import ru.dbotthepony.mc.otm.block.entity.ItemJob import ru.dbotthepony.mc.otm.block.entity.JobContainer import ru.dbotthepony.mc.otm.block.entity.JobStatus -import ru.dbotthepony.mc.otm.block.entity.ItemJob import ru.dbotthepony.mc.otm.block.entity.MatteryWorkerBlockEntity -import ru.dbotthepony.mc.otm.capability.item.CombinedItemHandler import ru.dbotthepony.mc.otm.capability.UpgradeType import ru.dbotthepony.mc.otm.capability.energy.ProfiledEnergyStorage import ru.dbotthepony.mc.otm.capability.energy.WorkerEnergyStorage @@ -34,7 +35,6 @@ import ru.dbotthepony.mc.otm.container.UpgradeContainer import ru.dbotthepony.mc.otm.container.balance import ru.dbotthepony.mc.otm.core.collect.filter import ru.dbotthepony.mc.otm.core.collect.maybe -import ru.dbotthepony.mc.otm.core.getValue import ru.dbotthepony.mc.otm.core.immutableList import ru.dbotthepony.mc.otm.core.util.item import ru.dbotthepony.mc.otm.menu.tech.PoweredFurnaceMenu @@ -55,12 +55,12 @@ sealed class AbstractPoweredFurnaceBlockEntity

, id: Int) { - if (outputs[id].fullyAddItem(status.job.itemStack)) { + if (outputs.fullyAddItem(status.job.itemStack, slots = IntList.of(id))) { experience.storeExperience(status.experience, this) syncSlots[id].inputItem = ItemStack.EMPTY syncSlots[id].outputItem = ItemStack.EMPTY @@ -132,16 +132,22 @@ sealed class AbstractPoweredFurnaceBlockEntity

0 && diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/EnergyCounterBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/EnergyCounterBlockEntity.kt index 1bdb492ea..5fe62e3c6 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/EnergyCounterBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/EnergyCounterBlockEntity.kt @@ -1,6 +1,7 @@ package ru.dbotthepony.mc.otm.block.entity.tech import net.minecraft.core.BlockPos +import net.minecraft.core.HolderLookup import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.IntTag import net.minecraft.nbt.ListTag @@ -9,7 +10,7 @@ import net.minecraft.world.entity.player.Inventory import net.minecraft.world.entity.player.Player import net.minecraft.world.inventory.AbstractContainerMenu import net.minecraft.world.level.block.state.BlockState -import net.minecraftforge.common.capabilities.ForgeCapabilities +import net.neoforged.neoforge.capabilities.Capabilities import ru.dbotthepony.kommons.util.getValue import ru.dbotthepony.kommons.util.setValue import ru.dbotthepony.mc.otm.block.tech.EnergyCounterBlock @@ -19,6 +20,7 @@ import ru.dbotthepony.mc.otm.capability.energy.IMatteryEnergyStorage import ru.dbotthepony.mc.otm.core.* import ru.dbotthepony.mc.otm.core.math.BlockRotation import ru.dbotthepony.mc.otm.core.math.Decimal +import ru.dbotthepony.mc.otm.core.math.RelativeSide import ru.dbotthepony.mc.otm.core.math.getDecimal import ru.dbotthepony.mc.otm.core.nbt.getByteArrayList import ru.dbotthepony.mc.otm.core.nbt.map @@ -84,14 +86,14 @@ class EnergyCounterBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Mat return value } - override fun saveShared(nbt: CompoundTag) { - super.saveShared(nbt) + override fun saveShared(nbt: CompoundTag, registry: HolderLookup.Provider) { + super.saveShared(nbt, registry) nbt[PASSED_ENERGY_KEY] = passed.serializeNBT() ioLimit?.let { nbt[IO_LIMIT_KEY] = it.serializeNBT() } } - override fun saveLevel(nbt: CompoundTag) { - super.saveLevel(nbt) + override fun saveLevel(nbt: CompoundTag, registry: HolderLookup.Provider) { + super.saveLevel(nbt, registry) val list = ListTag() nbt[POWER_HISTORY_KEY] = list nbt[POWER_HISTORY_POINTER_KEY] = historyTick @@ -100,8 +102,8 @@ class EnergyCounterBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Mat list.add(num.serializeNBT()) } - override fun load(nbt: CompoundTag) { - super.load(nbt) + override fun loadAdditional(nbt: CompoundTag, registry: HolderLookup.Provider) { + super.loadAdditional(nbt, registry) passed = nbt.getDecimal(PASSED_ENERGY_KEY) ioLimit = nbt.mapPresent(IO_LIMIT_KEY, Decimal.Companion::deserializeNBT) @@ -127,8 +129,8 @@ class EnergyCounterBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Mat private val energyInput = EnergyCounterCap(true) private val energyOutput = EnergyCounterCap(false) - private val inputCapability by front.trackEnergy() - private val outputCapability by back.trackEnergy() + private val inputCapability by CapabilityCache(RelativeSide.FRONT, Capabilities.EnergyStorage.BLOCK) + private val outputCapability by CapabilityCache(RelativeSide.BACK, Capabilities.EnergyStorage.BLOCK) private inner class EnergyCounterCap(isInput: Boolean) : IMatteryEnergyStorage { override val energyFlow = FlowDirection.input(isInput) @@ -137,7 +139,7 @@ class EnergyCounterBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Mat if (redstoneControl.isBlockedByRedstone) return Decimal.ZERO - val it = inputCapability.orNull() + val it = inputCapability if (it != null) { val diff: Decimal @@ -165,7 +167,7 @@ class EnergyCounterBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Mat if (redstoneControl.isBlockedByRedstone) return Decimal.ZERO - val it = outputCapability.orNull() + val it = outputCapability if (it != null) { val diff: Decimal @@ -195,7 +197,7 @@ class EnergyCounterBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Mat override var batteryLevel: Decimal get() { if (energyFlow.input) { - val it = outputCapability.orNull() + val it = outputCapability if (it != null) { if (it is IMatteryEnergyStorage) { @@ -205,7 +207,7 @@ class EnergyCounterBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Mat return Decimal(it.energyStored) } } else { - val it = inputCapability.orNull() + val it = inputCapability if (it != null) { if (it is IMatteryEnergyStorage) { @@ -225,7 +227,7 @@ class EnergyCounterBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Mat override val maxBatteryLevel: Decimal get() { if (energyFlow.input) { - val it = outputCapability.orNull() + val it = outputCapability if (it != null) { if (it is IMatteryEnergyStorage) { @@ -235,7 +237,7 @@ class EnergyCounterBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Mat return Decimal(it.maxEnergyStored) } } else { - val it = inputCapability.orNull() + val it = inputCapability if (it != null) { if (it is IMatteryEnergyStorage) { @@ -252,7 +254,7 @@ class EnergyCounterBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Mat override val missingPower: Decimal get() { if (energyFlow.input) { - val it = outputCapability.orNull() + val it = outputCapability if (it != null) { if (it is IMatteryEnergyStorage) { @@ -262,7 +264,7 @@ class EnergyCounterBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Mat return Decimal((it.maxEnergyStored - it.energyStored).coerceAtLeast(0)) } } else { - val it = inputCapability.orNull() + val it = inputCapability if (it != null) { if (it is IMatteryEnergyStorage) { @@ -278,11 +280,8 @@ class EnergyCounterBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Mat } init { - front.Cap(ForgeCapabilities.ENERGY, energyInput) - front.Cap(MatteryCapability.ENERGY, energyInput) - - back.Cap(ForgeCapabilities.ENERGY, energyOutput) - back.Cap(MatteryCapability.ENERGY, energyOutput) + exposeEnergySided(RelativeSide.FRONT, energyInput) + exposeEnergySided(RelativeSide.BACK, energyOutput) } override fun tick() { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/EnergyHatchBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/EnergyHatchBlockEntity.kt index af76a7e9d..b42dfc868 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/EnergyHatchBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/EnergyHatchBlockEntity.kt @@ -7,10 +7,9 @@ import net.minecraft.world.inventory.AbstractContainerMenu import net.minecraft.world.item.ItemStack import net.minecraft.world.level.block.entity.BlockEntityType import net.minecraft.world.level.block.state.BlockState -import net.minecraftforge.common.capabilities.ForgeCapabilities +import net.neoforged.neoforge.capabilities.Capabilities import ru.dbotthepony.mc.otm.block.entity.MatteryDeviceBlockEntity import ru.dbotthepony.mc.otm.capability.FlowDirection -import ru.dbotthepony.mc.otm.capability.MatteryCapability import ru.dbotthepony.mc.otm.capability.energy.BlockEnergyStorageImpl import ru.dbotthepony.mc.otm.capability.energy.ProfiledEnergyStorage import ru.dbotthepony.mc.otm.capability.moveEnergy @@ -19,7 +18,6 @@ import ru.dbotthepony.mc.otm.config.MachinesConfig import ru.dbotthepony.mc.otm.container.HandlerFilter import ru.dbotthepony.mc.otm.container.MatteryContainer import ru.dbotthepony.mc.otm.core.MultiblockBuilder -import ru.dbotthepony.mc.otm.core.ifPresentK import ru.dbotthepony.mc.otm.menu.tech.EnergyHatchMenu import ru.dbotthepony.mc.otm.registry.MBlockEntities @@ -32,7 +30,7 @@ class EnergyHatchBlockEntity( ) : MatteryDeviceBlockEntity(type, blockPos, blockState) { val energy = ProfiledEnergyStorage(BlockEnergyStorageImpl(this::markDirtyFast, FlowDirection.input(isInput), capacity)) - val container = object : MatteryContainer(this::markDirtyFast, CAPACITY) { + val container = object : MatteryContainer(::markDirtyFast, CAPACITY) { override fun getMaxStackSize(slot: Int, itemStack: ItemStack): Int { return 1 } @@ -45,9 +43,8 @@ class EnergyHatchBlockEntity( savetables.stateful(::container, BATTERY_KEY) // it would cause a lot of frustration if hatches accept stuff only though one face - exposeGlobally(ForgeCapabilities.ENERGY, energy) - exposeGlobally(MatteryCapability.ENERGY, energy) - exposeGlobally(ForgeCapabilities.ITEM_HANDLER, itemHandler) + exposeGlobally(Capabilities.EnergyStorage.BLOCK, energy) + exposeGlobally(Capabilities.ItemHandler.BLOCK, itemHandler) } override fun tick() { @@ -55,7 +52,7 @@ class EnergyHatchBlockEntity( if (!redstoneControl.isBlockedByRedstone) { container.forEach { - it.getCapability(ForgeCapabilities.ENERGY).ifPresentK { + it.getCapability(Capabilities.EnergyStorage.ITEM)?.let { if (isInput) { moveEnergy(it, energy, simulate = false) } else { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/EssenceStorageBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/EssenceStorageBlockEntity.kt index 80c28c98e..4a7722a5d 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/EssenceStorageBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/EssenceStorageBlockEntity.kt @@ -1,6 +1,9 @@ package ru.dbotthepony.mc.otm.block.entity.tech import net.minecraft.core.BlockPos +import net.minecraft.core.Holder +import net.minecraft.core.HolderLookup +import net.minecraft.nbt.CompoundTag import net.minecraft.server.level.ServerLevel import net.minecraft.sounds.SoundEvents import net.minecraft.sounds.SoundSource @@ -9,11 +12,12 @@ import net.minecraft.world.entity.player.Inventory import net.minecraft.world.entity.player.Player import net.minecraft.world.inventory.AbstractContainerMenu import net.minecraft.world.item.ItemStack +import net.minecraft.world.item.enchantment.Enchantment import net.minecraft.world.item.enchantment.Enchantments import net.minecraft.world.level.block.Block import net.minecraft.world.level.block.state.BlockState -import net.minecraftforge.fluids.FluidStack -import net.minecraftforge.fluids.capability.IFluidHandler +import net.neoforged.neoforge.fluids.FluidStack +import net.neoforged.neoforge.fluids.capability.IFluidHandler import ru.dbotthepony.mc.otm.block.entity.ExperienceStorage.Companion.XP_TO_LIQUID_RATIO import ru.dbotthepony.mc.otm.block.entity.MatteryDeviceBlockEntity import ru.dbotthepony.mc.otm.block.tech.EssenceStorageBlock @@ -22,6 +26,7 @@ import ru.dbotthepony.mc.otm.config.MachinesConfig import ru.dbotthepony.mc.otm.container.HandlerFilter import ru.dbotthepony.mc.otm.container.MatteryContainer import ru.dbotthepony.mc.otm.core.getEntitiesInEllipsoid +import ru.dbotthepony.mc.otm.core.lookupOrThrow import ru.dbotthepony.mc.otm.core.math.Vector import ru.dbotthepony.mc.otm.core.util.countingLazy import ru.dbotthepony.mc.otm.item.EssenceCapsuleItem @@ -42,6 +47,8 @@ class EssenceStorageBlockEntity(blockPos: BlockPos, blockState: BlockState) : Ma val servoContainer = MatteryContainer(::markDirtyFast, 1) val mendingContainer = MatteryContainer(::markDirtyFast, 1).also(::addDroppableContainer) + private var mending: Holder? = null + init { savetables.long(::experienceStored) savetables.stateful(::capsuleContainer) @@ -62,7 +69,7 @@ class EssenceStorageBlockEntity(blockPos: BlockPos, blockState: BlockState) : Ma })), mendingContainer.handler(object : HandlerFilter { override fun canInsert(slot: Int, stack: ItemStack): Boolean { - return stack.isDamaged && stack.getEnchantmentLevel(Enchantments.MENDING) > 0 + return stack.isDamaged && stack.getEnchantmentLevel(mending!!) > 0 } override fun canExtract(slot: Int, amount: Int, stack: ItemStack): Boolean { @@ -72,6 +79,12 @@ class EssenceStorageBlockEntity(blockPos: BlockPos, blockState: BlockState) : Ma ) ) + override fun loadAdditional(nbt: CompoundTag, registry: HolderLookup.Provider) { + super.loadAdditional(nbt, registry) + + mending = registry.lookupOrThrow(Enchantments.MENDING) + } + val fluidConfig = ConfigurableFluidHandler(this) override fun getTanks(): Int { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/GravitationStabilizerBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/GravitationStabilizerBlockEntity.kt index 5e119bf06..be89d3322 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/GravitationStabilizerBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/GravitationStabilizerBlockEntity.kt @@ -70,10 +70,6 @@ class GravitationStabilizerBlockEntity(p_155229_: BlockPos, p_155230_: BlockStat blackHole?.stabilizerDetached(this) } - override fun getRenderBoundingBox(): AABB { - return AABB(blockPos.offset(-RANGE, -RANGE, -RANGE), blockPos.offset(RANGE, RANGE, RANGE)) - } - companion object { const val RANGE = 64 } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/ItemHatchBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/ItemHatchBlockEntity.kt index 2e00b1113..1fea51d5e 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/ItemHatchBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/ItemHatchBlockEntity.kt @@ -6,7 +6,7 @@ import net.minecraft.world.entity.player.Player import net.minecraft.world.inventory.AbstractContainerMenu import net.minecraft.world.level.block.entity.BlockEntityType import net.minecraft.world.level.block.state.BlockState -import net.minecraftforge.common.capabilities.ForgeCapabilities +import net.neoforged.neoforge.capabilities.Capabilities import ru.dbotthepony.mc.otm.block.entity.MatteryDeviceBlockEntity import ru.dbotthepony.mc.otm.block.entity.decorative.CargoCrateBlockEntity import ru.dbotthepony.mc.otm.container.HandlerFilter @@ -26,7 +26,7 @@ class ItemHatchBlockEntity( init { savetables.stateful(::container, INVENTORY_KEY) - exposeGlobally(ForgeCapabilities.ITEM_HANDLER, itemHandler) + exposeGlobally(Capabilities.ItemHandler.BLOCK, itemHandler) } override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/MatterHatchBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/MatterHatchBlockEntity.kt index 5e0f7b7a0..a234a34f0 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/MatterHatchBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/MatterHatchBlockEntity.kt @@ -7,7 +7,7 @@ import net.minecraft.world.inventory.AbstractContainerMenu import net.minecraft.world.item.ItemStack import net.minecraft.world.level.block.entity.BlockEntityType import net.minecraft.world.level.block.state.BlockState -import net.minecraftforge.common.capabilities.ForgeCapabilities +import net.neoforged.neoforge.capabilities.Capabilities import ru.dbotthepony.mc.otm.block.entity.MatteryDeviceBlockEntity import ru.dbotthepony.mc.otm.capability.FlowDirection import ru.dbotthepony.mc.otm.capability.MatteryCapability @@ -18,7 +18,6 @@ import ru.dbotthepony.mc.otm.config.MachinesConfig import ru.dbotthepony.mc.otm.container.HandlerFilter import ru.dbotthepony.mc.otm.container.MatteryContainer import ru.dbotthepony.mc.otm.core.MultiblockBuilder -import ru.dbotthepony.mc.otm.core.ifPresentK import ru.dbotthepony.mc.otm.core.math.Decimal import ru.dbotthepony.mc.otm.menu.tech.MatterHatchMenu import ru.dbotthepony.mc.otm.registry.MBlockEntities @@ -29,7 +28,7 @@ class MatterHatchBlockEntity( blockPos: BlockPos, blockState: BlockState ) : MatteryDeviceBlockEntity(type, blockPos, blockState) { - val container = object : MatteryContainer(this::markDirtyFast, CAPACITY) { + val container = object : MatteryContainer(::markDirtyFast, CAPACITY) { override fun getMaxStackSize(slot: Int, itemStack: ItemStack): Int { return 1 } @@ -48,8 +47,8 @@ class MatterHatchBlockEntity( savetables.stateful(::matter, MATTER_STORAGE_KEY) // it would cause a lot of frustration if hatches accept stuff only though one face - exposeGlobally(ForgeCapabilities.ITEM_HANDLER, itemHandler) - exposeGlobally(MatteryCapability.MATTER, matter) + exposeGlobally(Capabilities.ItemHandler.BLOCK, itemHandler) + exposeGlobally(MatteryCapability.MATTER_BLOCK, matter) } override fun tick() { @@ -57,7 +56,7 @@ class MatterHatchBlockEntity( if (!redstoneControl.isBlockedByRedstone && matter.missingMatter > Decimal.ZERO) { container.forEach { - it.getCapability(MatteryCapability.MATTER).ifPresentK { + it.getCapability(MatteryCapability.MATTER_ITEM)?.let { if (isInput) { moveMatter(it, matter, simulate = false) } else { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/PlatePressBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/PlatePressBlockEntity.kt index b074929fc..74e72acef 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/PlatePressBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/PlatePressBlockEntity.kt @@ -6,7 +6,7 @@ import net.minecraft.world.entity.player.Inventory import net.minecraft.world.entity.player.Player import net.minecraft.world.inventory.AbstractContainerMenu import net.minecraft.world.level.block.state.BlockState -import net.minecraftforge.common.capabilities.ForgeCapabilities +import net.neoforged.neoforge.capabilities.Capabilities import ru.dbotthepony.mc.otm.block.entity.ExperienceStorage import ru.dbotthepony.mc.otm.block.entity.JobContainer import ru.dbotthepony.mc.otm.block.entity.JobStatus @@ -44,7 +44,7 @@ class PlatePressBlockEntity( ) init { - exposeGlobally(ForgeCapabilities.FLUID_HANDLER, experience) + exposeGlobally(Capabilities.FluidHandler.BLOCK, experience) savetables.stateful(::energy, ENERGY_KEY) savetables.stateful(::inputContainer) @@ -76,7 +76,6 @@ class PlatePressBlockEntity( val recipe = level.recipeManager .byType(MRecipes.PLATE_PRESS) - .values .iterator() .filter { it.value.matches(inputContainer, id) } .maybe()?.value ?: return JobContainer.noItem() diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/tech/AndroidStationBlock.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/tech/AndroidStationBlock.kt index 2659dea5d..767d9981f 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/tech/AndroidStationBlock.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/tech/AndroidStationBlock.kt @@ -22,7 +22,7 @@ import ru.dbotthepony.mc.otm.block.addSimpleDescription import ru.dbotthepony.mc.otm.block.entity.tech.AndroidStationBlockEntity import ru.dbotthepony.mc.otm.block.entity.WorkerState import ru.dbotthepony.mc.otm.capability.MatteryCapability -import ru.dbotthepony.mc.otm.core.orNull +import ru.dbotthepony.mc.otm.capability.matteryPlayer import ru.dbotthepony.mc.otm.registry.MBlockEntities import ru.dbotthepony.mc.otm.shapes.BlockShapes @@ -41,9 +41,7 @@ class AndroidStationBlock(val color: DyeColor?) : MatteryBlock(DEFAULT_MACHINE_P hand: InteractionHand, blockHitResult: BlockHitResult ): InteractionResult { - val cap = ply.getCapability(MatteryCapability.MATTERY_PLAYER).orNull() ?: return InteractionResult.FAIL - - if (!cap.isAndroid) + if (!ply.matteryPlayer.isAndroid) return InteractionResult.FAIL return super.use(blockState, level, blockPos, ply, hand, blockHitResult) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/tech/EssenceStorageBlock.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/tech/EssenceStorageBlock.kt index 1628451d7..ed7d56301 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/tech/EssenceStorageBlock.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/tech/EssenceStorageBlock.kt @@ -40,7 +40,7 @@ class EssenceStorageBlock(val color: DyeColor?) : RotatableMatteryBlock(Properti addSimpleDescription() - tooltips.blockEntityData("experienceStored") { _, l, acceptor -> + tooltips.blockEntityData("experienceStored") { _, _, l, acceptor -> if (minecraft.window.isShiftDown) { acceptor(TranslatableComponent("otm.gui.experience", l.asLong).withStyle(ChatFormatting.GRAY)) } else { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/AbstractProfiledStorage.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/AbstractProfiledStorage.kt index 29aacc60d..1bc882e33 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/AbstractProfiledStorage.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/AbstractProfiledStorage.kt @@ -2,10 +2,11 @@ package ru.dbotthepony.mc.otm.capability import com.google.common.collect.ImmutableList import it.unimi.dsi.fastutil.objects.ObjectArrayList +import net.minecraft.core.HolderLookup import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.ListTag import net.minecraft.nbt.NumericTag -import net.minecraftforge.common.util.INBTSerializable +import net.neoforged.neoforge.common.util.INBTSerializable import ru.dbotthepony.mc.otm.core.forValidRefs import ru.dbotthepony.mc.otm.core.math.Decimal import ru.dbotthepony.mc.otm.core.nbt.map @@ -81,7 +82,7 @@ abstract class AbstractProfiledStorage(val parent: P) : INBTSerializable< } val savedata: INBTSerializable = object : INBTSerializable { - override fun serializeNBT(): CompoundTag { + override fun serializeNBT(registry: HolderLookup.Provider): CompoundTag { return CompoundTag().also { tag -> tag["historyReceive"] = ListTag().also { for (value in historyReceiveInternal) { @@ -99,7 +100,7 @@ abstract class AbstractProfiledStorage(val parent: P) : INBTSerializable< } } - override fun deserializeNBT(nbt: CompoundTag?) { + override fun deserializeNBT(registry: HolderLookup.Provider, nbt: CompoundTag?) { tick = 0 thisTickReceive = Decimal.ZERO thisTickTransfer = Decimal.ZERO @@ -131,16 +132,16 @@ abstract class AbstractProfiledStorage(val parent: P) : INBTSerializable< } } - override fun serializeNBT(): CompoundTag { + override fun serializeNBT(registry: HolderLookup.Provider): CompoundTag { val tag: CompoundTag if (parent is INBTSerializable<*>) { - tag = (parent as INBTSerializable).serializeNBT() ?: CompoundTag() + tag = (parent as INBTSerializable).serializeNBT(registry) ?: CompoundTag() } else { tag = CompoundTag() } - val tag2 = savedata.serializeNBT()!! + val tag2 = savedata.serializeNBT(registry)!! for (k in tag2.allKeys) { tag[k] = tag2[k]!! @@ -157,12 +158,12 @@ abstract class AbstractProfiledStorage(val parent: P) : INBTSerializable< return calcWeightedAverage(historyReceive, tick) } - override fun deserializeNBT(nbt: CompoundTag?) { + override fun deserializeNBT(registry: HolderLookup.Provider, nbt: CompoundTag?) { if (parent is INBTSerializable<*>) { - (parent as INBTSerializable).deserializeNBT(nbt) + (parent as INBTSerializable).deserializeNBT(registry, nbt) } - savedata.deserializeNBT(nbt) + savedata.deserializeNBT(registry, nbt) } companion object { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/Ext.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/Ext.kt index bc93e7e4a..d2ac47101 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/Ext.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/Ext.kt @@ -3,14 +3,14 @@ package ru.dbotthepony.mc.otm.capability import com.google.common.collect.Streams import net.minecraft.ChatFormatting import net.minecraft.network.chat.Component +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.energy.IEnergyStorage -import net.minecraftforge.fluids.FluidStack -import net.minecraftforge.fluids.capability.IFluidHandler -import net.minecraftforge.items.IItemHandler +import net.neoforged.neoforge.capabilities.Capabilities +import net.neoforged.neoforge.energy.IEnergyStorage +import net.neoforged.neoforge.fluids.FluidStack +import net.neoforged.neoforge.fluids.capability.IFluidHandler +import net.neoforged.neoforge.items.IItemHandler import org.apache.logging.log4j.LogManager import ru.dbotthepony.mc.otm.capability.energy.IMatteryEnergyStorage import ru.dbotthepony.mc.otm.capability.fluid.iterator @@ -33,13 +33,13 @@ import ru.dbotthepony.mc.otm.core.collect.filter import ru.dbotthepony.mc.otm.core.collect.map import ru.dbotthepony.mc.otm.core.isNotEmpty import ru.dbotthepony.mc.otm.core.math.Decimal -import ru.dbotthepony.mc.otm.core.orNull import ru.dbotthepony.mc.otm.core.util.formatFluidLevel import java.util.stream.Stream private val LOGGER = LogManager.getLogger() -val ICapabilityProvider.matteryPlayer: MatteryPlayerCapability? get() = getCapability(MatteryCapability.MATTERY_PLAYER).orNull() +val Player.matteryPlayer: MatteryPlayer get() = (this as IMatteryPlayer).otmPlayer +val LivingEntity.matteryPlayer: MatteryPlayer? get() = (this as? IMatteryPlayer)?.otmPlayer /** * Does a checked energy receive, calls [IMatteryEnergyStorage.receiveEnergyChecked] if possible @@ -131,21 +131,21 @@ val IEnergyStorage.chargeRatio: Float get() { /** * Shortcut for getting [IEnergyStorage], including wrappers for it */ -val ICapabilityProvider.energy: IEnergyStorage? get() { - val mattery = getCapability(MatteryCapability.ENERGY) +val ItemStack.energy: IEnergyStorage? get() { + //val mattery = getCapability(MatteryCapability.ITEM_ENERGY) - if (mattery.isPresent) { - return mattery.orNull() - } + //if (mattery != null) { + // return mattery + //} - return getCapability(ForgeCapabilities.ENERGY).orNull() + return getCapability(Capabilities.EnergyStorage.ITEM) } /** * Shortcut for getting sideless [IMatteryEnergyStorage], including wrappers for it */ -val ICapabilityProvider.matteryEnergy: IMatteryEnergyStorage? get() { - return getCapability(MatteryCapability.ENERGY).orNull() +val ItemStack.matteryEnergy: IMatteryEnergyStorage? get() { + return getCapability(MatteryCapability.ITEM_ENERGY) } fun Player.items(includeCosmetics: Boolean = true): Iterator { @@ -320,7 +320,7 @@ internal fun IFluidHandler.fluidLevel(tooltips: (Component) -> Unit) { if (fluid.isEmpty) { tooltips(formatFluidLevel(0, getTankCapacity(0), formatAsReadable = ShiftPressedCond).withStyle(ChatFormatting.GRAY)) } else { - tooltips(formatFluidLevel(fluid.amount, getTankCapacity(0), fluid.displayName, formatAsReadable = ShiftPressedCond).withStyle(ChatFormatting.GRAY)) + tooltips(formatFluidLevel(fluid.amount, getTankCapacity(0), fluid.hoverName, formatAsReadable = ShiftPressedCond).withStyle(ChatFormatting.GRAY)) } } @@ -330,18 +330,18 @@ private fun actuallyMoveFluid(drained: FluidStack, source: IFluidHandler, destin val filled = destination.fill(drained, IFluidHandler.FluidAction.SIMULATE) if (filled == 0) return FluidStack.EMPTY - val drained2 = source.drain(FluidStack(drained, filled), IFluidHandler.FluidAction.SIMULATE) + val drained2 = source.drain(drained.copyWithAmount(filled), IFluidHandler.FluidAction.SIMULATE) if (drained2.amount != filled) return FluidStack.EMPTY val filled2 = destination.fill(drained2, IFluidHandler.FluidAction.SIMULATE) if (filled2 != drained2.amount) return FluidStack.EMPTY - if (!actuallyDrain && !actuallyFill) return FluidStack(drained2, filled2) + if (!actuallyDrain && !actuallyFill) return drained2.copyWithAmount(filled2) val drained3: FluidStack if (actuallyDrain) { - drained3 = source.drain(FluidStack(drained2, filled2), IFluidHandler.FluidAction.EXECUTE) + drained3 = source.drain(drained2.copyWithAmount(filled2), IFluidHandler.FluidAction.EXECUTE) if (drained3.amount != filled2) { LOGGER.warn("Inconsistency of fluid extraction from $source between simulate and execute modes (simulated $drained2; extracted $drained3); This can lead to duping!!!") @@ -362,7 +362,7 @@ private fun actuallyMoveFluid(drained: FluidStack, source: IFluidHandler, destin filled3 = filled2 } - return FluidStack(drained3, filled3) + return drained3.copyWithAmount(filled3) } fun moveFluid(source: IFluidHandler, sourceTank: Int? = null, destination: IFluidHandler, limit: Int = Int.MAX_VALUE, actuallyDrain: Boolean = true, actuallyFill: Boolean = true): FluidStack { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/IMatteryPlayer.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/IMatteryPlayer.kt new file mode 100644 index 000000000..890f6385f --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/IMatteryPlayer.kt @@ -0,0 +1,8 @@ +package ru.dbotthepony.mc.otm.capability + +interface IMatteryPlayer { + // since new capabilities dont get to live through getCapability calls by design + // and data attachments are.... limited. + // We gonna do it Fabric way + val otmPlayer: MatteryPlayer +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/MatteryPlayerCapability.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/MatteryPlayer.kt similarity index 85% rename from src/main/kotlin/ru/dbotthepony/mc/otm/capability/MatteryPlayerCapability.kt rename to src/main/kotlin/ru/dbotthepony/mc/otm/capability/MatteryPlayer.kt index 52cde2994..c529aa144 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/MatteryPlayerCapability.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/MatteryPlayer.kt @@ -10,12 +10,14 @@ import net.minecraft.client.model.PlayerModel import net.minecraft.client.player.AbstractClientPlayer import net.minecraft.commands.Commands import net.minecraft.commands.arguments.EntityArgument -import net.minecraft.core.Direction +import net.minecraft.core.HolderLookup +import net.minecraft.core.registries.BuiltInRegistries import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.IntTag import net.minecraft.nbt.ListTag import net.minecraft.nbt.StringTag import net.minecraft.network.chat.Component +import net.minecraft.network.protocol.common.custom.CustomPacketPayload import net.minecraft.resources.ResourceLocation import net.minecraft.server.level.ServerLevel import net.minecraft.server.level.ServerPlayer @@ -26,40 +28,31 @@ import net.minecraft.world.damagesource.DamageSource import net.minecraft.world.effect.MobEffect import net.minecraft.world.effect.MobEffectInstance import net.minecraft.world.effect.MobEffects -import net.minecraft.world.entity.Entity import net.minecraft.world.entity.LivingEntity import net.minecraft.world.entity.boss.wither.WitherBoss import net.minecraft.world.entity.player.Inventory import net.minecraft.world.entity.player.Player import net.minecraft.world.item.Item import net.minecraft.world.item.ItemStack -import net.minecraft.world.item.Items import net.minecraft.world.item.ProjectileWeaponItem import net.minecraft.world.item.crafting.RecipeManager import net.minecraft.world.item.crafting.RecipeType +import net.minecraft.world.item.crafting.SingleRecipeInput import net.minecraft.world.level.GameRules import net.minecraft.world.level.Level import net.minecraft.world.phys.Vec3 -import net.minecraftforge.common.ForgeHooks -import net.minecraftforge.common.MinecraftForge -import net.minecraftforge.common.capabilities.Capability -import net.minecraftforge.common.capabilities.ICapabilityProvider -import net.minecraftforge.common.util.INBTSerializable -import net.minecraftforge.common.util.LazyOptional -import net.minecraftforge.event.AttachCapabilitiesEvent -import net.minecraftforge.event.RegisterCommandsEvent -import net.minecraftforge.event.TickEvent -import net.minecraftforge.event.TickEvent.PlayerTickEvent -import net.minecraftforge.event.entity.living.LivingAttackEvent -import net.minecraftforge.event.entity.living.LivingDeathEvent -import net.minecraftforge.event.entity.living.LivingHurtEvent -import net.minecraftforge.event.entity.living.MobEffectEvent -import net.minecraftforge.event.entity.player.PlayerEvent -import net.minecraftforge.eventbus.api.Cancelable -import net.minecraftforge.eventbus.api.Event -import net.minecraftforge.network.PacketDistributor -import net.minecraftforge.registries.ForgeRegistries -import net.minecraftforge.server.command.EnumArgument +import net.neoforged.bus.api.Event +import net.neoforged.bus.api.ICancellableEvent +import net.neoforged.neoforge.common.CommonHooks +import net.neoforged.neoforge.common.NeoForge +import net.neoforged.neoforge.event.RegisterCommandsEvent +import net.neoforged.neoforge.event.entity.living.LivingDeathEvent +import net.neoforged.neoforge.event.entity.living.LivingIncomingDamageEvent +import net.neoforged.neoforge.event.entity.living.MobEffectEvent +import net.neoforged.neoforge.event.entity.player.PlayerEvent +import net.neoforged.neoforge.event.tick.PlayerTickEvent +import net.neoforged.neoforge.network.PacketDistributor +import net.neoforged.neoforge.server.command.EnumArgument import org.apache.logging.log4j.LogManager import org.joml.Vector4f import ru.dbotthepony.kommons.collect.ListenableMap @@ -93,18 +86,18 @@ import ru.dbotthepony.mc.otm.client.minecraft import ru.dbotthepony.mc.otm.config.AndroidConfig import ru.dbotthepony.mc.otm.config.ExopackConfig import ru.dbotthepony.mc.otm.container.CombinedContainer -import ru.dbotthepony.mc.otm.container.MatteryContainer -import ru.dbotthepony.mc.otm.container.get import ru.dbotthepony.mc.otm.container.DynamicallyProxiedContainer import ru.dbotthepony.mc.otm.container.IContainer import ru.dbotthepony.mc.otm.container.IMatteryContainer +import ru.dbotthepony.mc.otm.container.MatteryContainer +import ru.dbotthepony.mc.otm.container.get import ru.dbotthepony.mc.otm.container.util.slotIterator import ru.dbotthepony.mc.otm.container.vanishCursedItems import ru.dbotthepony.mc.otm.core.* import ru.dbotthepony.mc.otm.core.collect.UUIDIntModifiersMap import ru.dbotthepony.mc.otm.core.collect.filter -import ru.dbotthepony.mc.otm.core.math.RGBColorDFUCodec import ru.dbotthepony.mc.otm.core.math.Decimal +import ru.dbotthepony.mc.otm.core.math.RGBColorDFUCodec import ru.dbotthepony.mc.otm.core.math.minus import ru.dbotthepony.mc.otm.core.nbt.getCompoundList import ru.dbotthepony.mc.otm.core.nbt.getIntList @@ -147,45 +140,32 @@ private fun Player.dropContainer(container: Container, spill: Boolean = true, se } @Suppress("unused") -class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerializable { +class MatteryPlayer(val ply: Player) { /** * This event is fired on main event bus before ticking logic takes place. * * Cancelling it is probably not a good idea, but you can do it anyway. */ - @Cancelable - data class PreTick(val capability: MatteryPlayerCapability) : Event() { + data class PreTick(val capability: MatteryPlayer) : Event(), ICancellableEvent { val player get() = capability.ply val level: Level get() = capability.ply.level() - - override fun isCancelable(): Boolean { - return true - } } /** * This event is fired on main event bus after ticking logic took place. */ - data class PostTick(val capability: MatteryPlayerCapability) : Event() { + data class PostTick(val capability: MatteryPlayer) : Event() { val player get() = capability.ply val level: Level get() = capability.ply.level() - - override fun isCancelable(): Boolean { - return false - } } /** * This event is fired on main event bus when [Inventory.add] was called and entire [ItemStack] can not be stored - * (both in [Inventory] and [MatteryPlayerCapability] exopack due to inventory filters or no free space). + * (both in [Inventory] and [MatteryPlayer] exopack due to inventory filters or no free space). */ - data class ItemStackLeftoverEvent(val stack: ItemStack, val capability: MatteryPlayerCapability) : Event() { + data class ItemStackLeftoverEvent(val stack: ItemStack, val capability: MatteryPlayer) : Event() { val player get() = capability.ply val level: Level get() = capability.ply.level() - - override fun isCancelable(): Boolean { - return false - } } private inner class PlayerMatteryContainer(size: Int) : MatteryContainer(size) { @@ -327,7 +307,7 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial field[i] = ItemStack.EMPTY } - value.deserializeNBT(field.serializeNBT()) + value.deserializeNBT(ply.level().registryAccess(), field.serializeNBT(ply.level().registryAccess())) value.addFilterSynchronizer(syncher) field = value @@ -449,7 +429,7 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial private val deathLog = ArrayDeque>() private val featureMap = IdentityHashMap, AndroidFeature>() - private val networkQueue = ArrayList() + private val networkQueue = ArrayList() private val queuedTicks = ArrayList() private var tickedOnce = false @@ -474,7 +454,7 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial private var lastLiquidPosition = Vec3(0.0, 0.0, 0.0) private var liquidDistanceTravelled = 0.0 private var wasInLiquid = false - private var lastDimension = ResourceLocation("overworld") + private var lastDimension = ResourceLocation("minecraft", "overworld") // clientside only flag for render hook // TODO: actual code, currently particles spawn just behind player on ExopackSmokePacket @@ -539,13 +519,13 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial override fun computeNextJob(): JobContainer { if (!exopackEnergy.batteryLevel.isPositive) return JobContainer.noEnergy() val level = ply.level() as? ServerLevel ?: return JobContainer.failure() - val recipe = cache.getRecipeFor(input, level) + val recipe = cache.getRecipeFor(SingleRecipeInput(input[0]), level) if (recipe.isEmpty) { return JobContainer.noItem() } else { val actual = recipe.get() - val item = actual.value.assemble(input, level.registryAccess()) + val item = actual.value.assemble(SingleRecipeInput(input[0]), level.registryAccess()) input[0].shrink(1) input.setChanged(0) return JobContainer.success(ItemJob(item, actual.value.cookingTime.toDouble(), ExopackConfig.FURNACE_POWER_CONSUMPTION, actual.value.experience)) @@ -556,7 +536,7 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial super.onJobTick(status) if (isExopackVisible && ply.level().random.nextFloat() <= 0.05f) { - MatteryPlayerNetworkChannel.send(PacketDistributor.TRACKING_ENTITY_AND_SELF.with(ply as ServerPlayer), ExopackSmokePacket(ply.uuid)) + PacketDistributor.sendToPlayersTrackingEntityAndSelf(ply, ExopackSmokePacket(ply.uuid)) } } @@ -912,7 +892,7 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial return featureMap[feature] as T? } - private fun onHurt(event: LivingHurtEvent) { + private fun onHurt(event: LivingIncomingDamageEvent) { if (isAndroid) { for (feature in featureMap.values) { feature.onHurt(event) @@ -924,14 +904,6 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial } } - private fun onAttack(event: LivingAttackEvent) { - if (isAndroid) { - for (feature in featureMap.values) { - feature.onAttack(event) - } - } - } - internal fun computeIfAbsent(feature: AndroidFeatureType): T { return getFeature(feature) ?: addFeature(feature) } @@ -947,22 +919,22 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial } } - override fun serializeNBT(): CompoundTag { - val tag = savetables.serializeNBT() + fun serializeNBT(registry: HolderLookup.Provider): CompoundTag { + val tag = savetables.serializeNBT(registry) // iteration tag["deathLog"] = ListTag().also { for ((ticks, component) in deathLog) { it.add(CompoundTag().also { it["ticks"] = ticks - it["component"] = StringTag.valueOf(Component.Serializer.toJson(component)) + it["component"] = StringTag.valueOf(Component.Serializer.toJson(component, registry)) }) } } tag["features"] = ListTag().also { for (feature in featureMap.values) { - it.add(feature.serializeNBT().also { + it.add(feature.serializeNBT(registry).also { it["id"] = feature.type.registryName!!.toString() }) } @@ -991,8 +963,8 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial return tag } - override fun deserializeNBT(tag: CompoundTag) { - savetables.deserializeNBT(tag) + fun deserializeNBT(tag: CompoundTag, registry: HolderLookup.Provider) { + savetables.deserializeNBT(registry, tag) if (MItems.ExopackUpgrades.INVENTORY_UPGRADE_ENDER_DRAGON.uuid(ItemStack.EMPTY) in exopackSlotModifierMap.delegate) { isExopackEnderAccessInstalled = true @@ -1014,7 +986,7 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial for (i in 0 until regularSlotFilters.size.coerceAtMost(this.regularSlotFilters.size)) { val path = regularSlotFilters[i].asString if (path == "") continue - this.regularSlotFilters[i].value = ForgeRegistries.ITEMS.getValue(ResourceLocation.tryParse(path) ?: continue) ?: Items.AIR + this.regularSlotFilters[i].value = BuiltInRegistries.ITEM.get(ResourceLocation.tryParse(path) ?: continue) } if ("slotsChargeFlag" in tag) { @@ -1029,7 +1001,7 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial deathLog.clear() for (value in tag.getCompoundList("deathLog")) { - val component = Component.Serializer.fromJson(value.getString("component")) + val component = Component.Serializer.fromJson(value.getString("component"), registry) if (component != null) { deathLog.add(value.getInt("ticks") to component) @@ -1040,12 +1012,12 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial research.clear() for (featureTag in tag.getCompoundList("features")) { - val feature = MRegistry.ANDROID_FEATURES.getValue(ResourceLocation(featureTag.getString("id"))) + val feature = MRegistry.ANDROID_FEATURES.get(ResourceLocation.parse(featureTag.getString("id"))) if (feature?.isApplicable(this) == true) { val instance = feature.create(this) - instance.deserializeNBT(featureTag) + instance.deserializeNBT(registry, featureTag) addFeature(instance) if (!ply.level().isClientSide) { @@ -1055,7 +1027,7 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial } for (researchTag in tag.getCompoundList("research")) { - val research = AndroidResearchManager[ResourceLocation(researchTag.getString("id"))] + val research = AndroidResearchManager[ResourceLocation.parse(researchTag.getString("id"))] if (research != null) { val instance = AndroidResearch(research, this) @@ -1088,10 +1060,10 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial androidEnergy.item = ItemStack.EMPTY } - private fun sendNetwork(packet: Any) { + private fun sendNetwork(packet: CustomPacketPayload) { if (ply is ServerPlayer) { if (tickedOnce) { - MatteryPlayerNetworkChannel.send(ply, packet) + PacketDistributor.sendToPlayer(ply, packet) } else { networkQueue.add(packet) } @@ -1128,7 +1100,7 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial if (!ply.isAlive) return if (isAndroid) { - ForgeRegistries.MOB_EFFECTS.tags()?.getTag(ANDROID_IMMUNE_EFFECTS)?.forEach { + BuiltInRegistries.MOB_EFFECT.getOrCreateTag(ANDROID_IMMUNE_EFFECTS).forEach { if (ply.hasEffect(it)) ply.removeEffect(it) } @@ -1138,10 +1110,7 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial private fun tick() { if (!ply.isAlive) return - PreTick(this).also { - MinecraftForge.EVENT_BUS.post(it) - if (it.isCanceled) return - } + if (NeoForge.EVENT_BUS.post(PreTick(this)).isCanceled) return ticksIExist++ @@ -1335,7 +1304,7 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial val payload = privateSyncherRemote.write() if (payload != null) { - MatteryPlayerNetworkChannel.send(ply, MatteryPlayerFieldPacket(payload, false)) + PacketDistributor.sendToPlayer(ply as ServerPlayer, MatteryPlayerDataPacket(payload, false)) } val trackingIterator = remoteSynchers.entries.iterator() @@ -1349,19 +1318,19 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial val payload2 = remote.write() if (payload2 != null) { - MatteryPlayerNetworkChannel.send(ply, MatteryPlayerFieldPacket(payload2, true, this.ply.uuid)) + PacketDistributor.sendToPlayer(ply as ServerPlayer, MatteryPlayerDataPacket(payload2, true, this.ply.uuid)) } } val payload3 = publicSyncherRemote.write() if (payload3 != null) { - MatteryPlayerNetworkChannel.send(ply, MatteryPlayerFieldPacket(payload3, true)) + PacketDistributor.sendToPlayer(ply as ServerPlayer, MatteryPlayerDataPacket(payload3, true)) } if (networkQueue.size != 0) { for (packet in networkQueue) { - MatteryPlayerNetworkChannel.send(ply, packet) + PacketDistributor.sendToPlayer(ply as ServerPlayer, packet) } networkQueue.clear() @@ -1395,18 +1364,10 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial tickInventory() PostTick(this).also { - MinecraftForge.EVENT_BUS.post(it) + NeoForge.EVENT_BUS.post(it) } } - private val resolver = LazyOptional.of { this } - - override fun getCapability(cap: Capability, side: Direction?): LazyOptional { - return if (cap == MatteryCapability.MATTERY_PLAYER) { - resolver.cast() - } else LazyOptional.empty() - } - /** * This re-implement [Inventory.add] logic (original method is redirected to this) */ @@ -1421,7 +1382,7 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial wrappedItemInventory.consumeItem(stack, false, onlyIntoExisting = false, popTime = 5) } - MinecraftForge.EVENT_BUS.post(ItemStackLeftoverEvent(stack, this)) + NeoForge.EVENT_BUS.post(ItemStackLeftoverEvent(stack, this)) if (ply.abilities.instabuild) { stack.count = 0 @@ -1445,10 +1406,10 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial } } - enum class UpgradeType(val prop: KMutableProperty1) { - CRAFTING(MatteryPlayerCapability::isExopackCraftingUpgraded), - ENDER_ACCESS(MatteryPlayerCapability::isExopackEnderAccessInstalled), - SMELTING(MatteryPlayerCapability::isExopackSmeltingInstalled); + enum class UpgradeType(val prop: KMutableProperty1) { + CRAFTING(MatteryPlayer::isExopackCraftingUpgraded), + ENDER_ACCESS(MatteryPlayer::isExopackEnderAccessInstalled), + SMELTING(MatteryPlayer::isExopackSmeltingInstalled); } @Suppress("unused") @@ -1457,8 +1418,8 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial private fun setExoPack(players: Collection, hasExoPack: Boolean): Int { for (player in players) { - player.matteryPlayer?.hasExopack = hasExoPack - player.matteryPlayer?._exoPackMenu = null + player.matteryPlayer.hasExopack = hasExoPack + player.matteryPlayer._exoPackMenu = null } return players.size @@ -1466,7 +1427,7 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial private fun makeAndroid(players: Collection): Int { for (player in players) { - player.matteryPlayer?.becomeAndroid() + player.matteryPlayer.becomeAndroid() } return players.size @@ -1474,7 +1435,7 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial private fun makeHuman(players: Collection): Int { for (player in players) { - player.matteryPlayer?.becomeHumane() + player.matteryPlayer.becomeHumane() } return players.size @@ -1482,7 +1443,7 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial private fun setUpgrade(players: Collection, type: UpgradeType, state: Boolean): Int { for (player in players) { - player.matteryPlayer?.let { type.prop.set(it, state) } + player.matteryPlayer.let { type.prop.set(it, state) } } return players.size @@ -1530,104 +1491,73 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial WitherBoss.LIVING_ENTITY_SELECTOR = WitherBoss.LIVING_ENTITY_SELECTOR.and { it.matteryPlayer?.isAndroid != true } } - val ANDROID_IMMUNE_EFFECTS: TagKey = TagKey.create(ForgeRegistries.MOB_EFFECTS.registryKey, ResourceLocation(OverdriveThatMatters.MOD_ID, "android_immune_effects")) + val ANDROID_IMMUNE_EFFECTS: TagKey = TagKey.create(BuiltInRegistries.MOB_EFFECT.key(), ResourceLocation(OverdriveThatMatters.MOD_ID, "android_immune_effects")) - fun onPlayerTick(event: PlayerTickEvent) { - val ent = event.player + fun onPlayerTickPre(event: PlayerTickEvent.Pre) { + val ent = event.entity - if (event.phase == TickEvent.Phase.START) { - if (!ent.level().isClientSide) { - ent.getCapability(MatteryCapability.MATTERY_PLAYER).ifPresentK { - it.preTick() - } - } + if (!ent.level().isClientSide) { + ent.matteryPlayer.preTick() + } + } + + fun onPlayerTickPost(event: PlayerTickEvent.Pre) { + val ent = event.entity + + if (ent.level().isClientSide) { + ent.matteryPlayer.tickClient() } else { - if (ent.level().isClientSide) { - ent.getCapability(MatteryCapability.MATTERY_PLAYER).ifPresentK { - it.tickClient() - } - } else { - ent.getCapability(MatteryCapability.MATTERY_PLAYER).ifPresentK { - it.tick() - } - } + ent.matteryPlayer.tick() } } fun isMobEffectApplicable(event: MobEffectEvent.Applicable) { - event.entity.getCapability(MatteryCapability.MATTERY_PLAYER).ifPresentK { - if (it.isAndroid && ForgeRegistries.MOB_EFFECTS.tags()?.getTag(ANDROID_IMMUNE_EFFECTS)?.stream()?.anyMatch { it == event.effectInstance.effect } == true) { - event.result = Event.Result.DENY + event.entity.matteryPlayer?.let { + if (it.isAndroid && BuiltInRegistries.MOB_EFFECT.getOrCreateTag(ANDROID_IMMUNE_EFFECTS).any { it == event.effectInstance?.effect }) { + event.result = MobEffectEvent.Applicable.Result.DO_NOT_APPLY } } } - fun onHurtEvent(event: LivingHurtEvent) { - event.entity.getCapability(MatteryCapability.MATTERY_PLAYER).ifPresentK { it.onHurt(event) } - } - - fun onAttackEvent(event: LivingAttackEvent) { - event.entity.getCapability(MatteryCapability.MATTERY_PLAYER).ifPresentK { it.onAttack(event) } - } - - val CAPABILITY_LOCATION = ResourceLocation(OverdriveThatMatters.MOD_ID, "player") - - fun onAttachCapabilityEvent(event: AttachCapabilitiesEvent) { - val ent = event.`object` - - if (ent is Player) { - event.addCapability(CAPABILITY_LOCATION, MatteryPlayerCapability(ent)) - } + fun onHurtEvent(event: LivingIncomingDamageEvent) { + event.entity.matteryPlayer?.onHurt(event) } fun onPlayerChangeDimensionEvent(event: PlayerEvent.PlayerChangedDimensionEvent) { onceServer { - event.entity.getCapability(MatteryCapability.MATTERY_PLAYER).ifPresentK { - it.invalidateNetworkState() - it.recreateExoPackMenu() - } + event.entity.matteryPlayer.invalidateNetworkState() + event.entity.matteryPlayer.recreateExoPackMenu() } } fun onPlayerDeath(event: LivingDeathEvent) { val ply = event.entity as? Player ?: return - val mattery = ply.matteryPlayer ?: return - if (mattery.lastDeathTick != ply.tickCount) { - mattery.lastDeathTick = ply.tickCount + if (ply.matteryPlayer.lastDeathTick != ply.tickCount) { + ply.matteryPlayer.lastDeathTick = ply.tickCount } else { return } - if (!mattery.isAndroid) { + if (!ply.matteryPlayer.isAndroid) { return } - mattery.iteration++ - mattery.shouldSendIteration = true - mattery.deathLog.addLast(ply.tickCount to ply.combatTracker.deathMessage) + ply.matteryPlayer.iteration++ + ply.matteryPlayer.shouldSendIteration = true + ply.matteryPlayer.deathLog.addLast(ply.tickCount to ply.combatTracker.deathMessage) - if (mattery.androidEnergy.batteryLevel < AndroidConfig.ANDROID_MAX_ENERGY * Decimal("0.2")) - mattery.androidEnergy.batteryLevel = AndroidConfig.ANDROID_MAX_ENERGY * Decimal("0.2") // если смерть была от разряда батареи, то предотвращаем софтлок + if (ply.matteryPlayer.androidEnergy.batteryLevel < AndroidConfig.ANDROID_MAX_ENERGY * Decimal("0.2")) + ply.matteryPlayer.androidEnergy.batteryLevel = AndroidConfig.ANDROID_MAX_ENERGY * Decimal("0.2") // если смерть была от разряда батареи, то предотвращаем софтлок - while (mattery.deathLog.size > 6) { - mattery.deathLog.removeFirst() + while (ply.matteryPlayer.deathLog.size > 6) { + ply.matteryPlayer.deathLog.removeFirst() } } fun onPlayerCloneEvent(event: PlayerEvent.Clone) { - val it = event.entity.matteryPlayer ?: return - var original = event.original.matteryPlayer - - if (original == null) { - event.original.reviveCaps() - original = event.original.matteryPlayer - } - - if (original == null) { - event.original.invalidateCaps() - return - } + val it = event.entity.matteryPlayer + val original = event.original.matteryPlayer if (original.willBecomeAndroid && event.isWasDeath) { original.becomeAndroid() @@ -1640,15 +1570,12 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial } } - it.deserializeNBT(original.serializeNBT()) + it.deserializeNBT(original.serializeNBT(it.ply.registryAccess()), it.ply.registryAccess()) it.invalidateNetworkState() - event.original.invalidateCaps() onceServer { - event.entity.getCapability(MatteryCapability.MATTERY_PLAYER).ifPresentK { - it.invalidateNetworkState() - it.recreateExoPackMenu() - } + event.entity.matteryPlayer.invalidateNetworkState() + event.entity.matteryPlayer.recreateExoPackMenu() } } @@ -1661,7 +1588,7 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial */ @JvmStatic fun phantomSpawnHook(iterator: Iterator): Iterator { - return iterator.filter { it.matteryPlayer?.isAndroid != true } + return iterator.filter { it.matteryPlayer.isAndroid != true } } /** @@ -1673,9 +1600,7 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial return iterator } - val mattery = entity.matteryPlayer ?: return iterator - - if (mattery.isAndroid) { + if (entity.matteryPlayer.isAndroid) { return iterator.filter { it.first.effect != MobEffects.HUNGER } @@ -1686,7 +1611,7 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial @JvmStatic fun inventoryDropAll(inventory: Inventory) { - val mattery = inventory.player.matteryPlayer ?: return + val mattery = inventory.player.matteryPlayer if (!mattery.hasExopack) { return @@ -1724,16 +1649,14 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial @JvmStatic fun playerDestroyVanishingCursedItems(player: Player) { - player.matteryPlayer?.let { - if (it.hasExopack) { - it.exopackContainer.vanishCursedItems() - it.exopackChargeSlots.vanishCursedItems() - // it.exoPackEnergy.parent.vanishCursedItems() + if (player.matteryPlayer.hasExopack) { + player.matteryPlayer.exopackContainer.vanishCursedItems() + player.matteryPlayer.exopackChargeSlots.vanishCursedItems() + // it.exoPackEnergy.parent.vanishCursedItems() - for (smelter in it.smelters) { - smelter.input.vanishCursedItems() - smelter.output.vanishCursedItems() - } + for (smelter in player.matteryPlayer.smelters) { + smelter.input.vanishCursedItems() + smelter.output.vanishCursedItems() } } } @@ -1746,25 +1669,25 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial return } - val matteryPlayer = player.matteryPlayer ?: return + val matteryPlayer = player.matteryPlayer if (!matteryPlayer.hasExopack) { return } val targetSlot = player.inventory.suitableHotbarSlot - val itemSlot = matteryPlayer.exopackContainer.indexOfFirst { !it.isEmpty && ItemStack.isSameItemSameTags(itemStack, it) } + val itemSlot = matteryPlayer.exopackContainer.indexOfFirst { !it.isEmpty && ItemStack.isSameItemSameComponents(itemStack, it) } if (itemSlot == -1) { return } - MatteryPlayerNetworkChannel.sendToServer(PickItemFromInventoryPacket(targetSlot, itemSlot)) + PacketDistributor.sendToServer(PickItemFromInventoryPacket(targetSlot, itemSlot)) } fun onStartTracking(event: PlayerEvent.StartTracking) { if (event.target is ServerPlayer) { - event.target.matteryPlayer?.let { + (event.target as ServerPlayer).matteryPlayer.let { it.remoteSynchers[event.entity as ServerPlayer] = it.publicSyncher.Remote() } } @@ -1772,21 +1695,21 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial fun onStopTracking(event: PlayerEvent.StopTracking) { if (event.target is ServerPlayer) { - event.target.matteryPlayer?.remoteSynchers?.remove(event.entity as ServerPlayer) + (event.target as ServerPlayer).matteryPlayer.remoteSynchers.remove(event.entity as ServerPlayer) } } @JvmStatic fun getProjectileHook(player: Player, weaponItem: ItemStack): ItemStack? { val weapon = weaponItem.item as? ProjectileWeaponItem ?: return null - val matteryPlayer = player.matteryPlayer ?: return null + val matteryPlayer = player.matteryPlayer if (!matteryPlayer.hasExopack) { return null } val item = matteryPlayer.exopackContainer.stream().filter(weapon.allSupportedProjectiles).findFirst().orElse(null) ?: return null - return ForgeHooks.getProjectile(player, weaponItem, item) + return CommonHooks.getProjectile(player, weaponItem, item) } } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/drive/API.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/drive/API.kt index 689056cb4..e716d7438 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/drive/API.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/drive/API.kt @@ -1,5 +1,6 @@ package ru.dbotthepony.mc.otm.capability.drive +import net.minecraft.core.HolderLookup import net.minecraft.nbt.CompoundTag import net.minecraft.world.item.Item import net.minecraft.world.item.ItemStack @@ -33,6 +34,6 @@ interface IMatteryDrive> : IStorageComponent { val driveCapacity: BigInteger // not extending INBTSerializable to avoid serializing it as forgecaps - fun serializeNBT(): CompoundTag - fun deserializeNBT(nbt: CompoundTag) + fun serializeNBT(registry: HolderLookup.Provider): CompoundTag + fun deserializeNBT(nbt: CompoundTag, registry: HolderLookup.Provider) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/drive/AbstractMatteryDrive.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/drive/AbstractMatteryDrive.kt index 4d506a470..29a0f5855 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/drive/AbstractMatteryDrive.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/drive/AbstractMatteryDrive.kt @@ -4,6 +4,8 @@ import it.unimi.dsi.fastutil.objects.Object2ObjectOpenCustomHashMap import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap import it.unimi.dsi.fastutil.objects.ObjectArraySet import it.unimi.dsi.fastutil.objects.ObjectLinkedOpenHashSet +import net.minecraft.core.HolderLookup +import net.minecraft.core.HolderLookup.Provider import kotlin.jvm.JvmOverloads import java.util.UUID import net.minecraft.nbt.CompoundTag @@ -147,10 +149,10 @@ abstract class AbstractMatteryDrive>( return copy } - protected abstract fun serializeStack(item: T): CompoundTag? - protected abstract fun deserializeStack(tag: CompoundTag): T? + protected abstract fun serializeStack(item: T, registry: Provider): CompoundTag? + protected abstract fun deserializeStack(tag: CompoundTag, registry: Provider): T? - override fun serializeNBT(): CompoundTag { + override fun serializeNBT(registry: Provider): CompoundTag { val compound = CompoundTag() compound["capacity"] = driveCapacity.serializeNBT() @@ -160,7 +162,7 @@ abstract class AbstractMatteryDrive>( compound["items"] = list for (tuple in stack2tuples.values) { - val serialized = serializeStack(tuple.stack) + val serialized = serializeStack(tuple.stack, registry) if (serialized != null) { list.add(serialized) @@ -170,7 +172,7 @@ abstract class AbstractMatteryDrive>( return compound } - override fun deserializeNBT(nbt: CompoundTag) { + override fun deserializeNBT(nbt: CompoundTag, registry: HolderLookup.Provider) { for (listener in listeners) { for (get in stack2tuples.values) { listener.onStackRemoved(get.id) @@ -183,12 +185,12 @@ abstract class AbstractMatteryDrive>( storedDifferentStacks = 0 // nextID = 0L - driveCapacity = nbt.map("capacity", ::BigInteger) ?: driveCapacity + driveCapacity = nbt.get("capacity")?.let { BigInteger(it) } ?: driveCapacity maxDifferentStacks = nbt.getInt("max_different_stacks") for (entry in nbt.getList("items", Tag.TAG_COMPOUND.toInt())) { if (entry is CompoundTag) { - val stack = deserializeStack(entry) + val stack = deserializeStack(entry, registry) if (stack != null && stack.isNotEmpty) { storedCount += stack.count diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/drive/DrivePool.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/drive/DrivePool.kt index 9794484b9..6b18ec9dd 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/drive/DrivePool.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/drive/DrivePool.kt @@ -1,25 +1,27 @@ package ru.dbotthepony.mc.otm.capability.drive import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap -import java.util.UUID -import net.minecraft.ReportedException -import net.minecraft.nbt.CompoundTag -import net.minecraft.nbt.NbtIo import net.minecraft.CrashReport +import net.minecraft.ReportedException import net.minecraft.Util +import net.minecraft.core.HolderLookup +import net.minecraft.core.HolderLookup.Provider +import net.minecraft.nbt.CompoundTag +import net.minecraft.nbt.NbtAccounter +import net.minecraft.nbt.NbtIo import net.minecraft.world.level.storage.LevelResource -import java.util.concurrent.locks.LockSupport -import net.minecraftforge.event.server.ServerAboutToStartEvent -import net.minecraftforge.event.server.ServerStoppingEvent -import net.minecraftforge.event.level.LevelEvent +import net.neoforged.neoforge.event.level.LevelEvent import org.apache.logging.log4j.LogManager -import ru.dbotthepony.mc.otm.NULLABLE_MINECRAFT_SERVER +import ru.dbotthepony.mc.otm.MINECRAFT_SERVER +import ru.dbotthepony.mc.otm.Registries import ru.dbotthepony.mc.otm.SERVER_IS_LIVE import ru.dbotthepony.mc.otm.isServerThread -import java.io.File import java.lang.ref.WeakReference -import java.util.ArrayList +import java.nio.file.Files +import java.nio.file.Path +import java.util.* import java.util.concurrent.ConcurrentLinkedQueue +import kotlin.io.path.exists private class WeakDriveReference(drive: IMatteryDrive<*>) { private var drive: IMatteryDrive<*>? = drive @@ -33,7 +35,7 @@ private class WeakDriveReference(drive: IMatteryDrive<*>) { return drive ?: weak.get() } - fun sync(): CompoundTag? { + fun sync(registry: HolderLookup.Provider): CompoundTag? { val drive = drive() ?: return null if (!drive.isDirty) { @@ -41,7 +43,7 @@ private class WeakDriveReference(drive: IMatteryDrive<*>) { return null } - val tag = drive.serializeNBT() + val tag = drive.serializeNBT(registry) drive.isDirty = false this.drive = null @@ -65,22 +67,20 @@ object DrivePool { private val pool = Object2ObjectOpenHashMap() private val backlog = ConcurrentLinkedQueue() - private var knownBaseDirectory: File? = null + private var knownBaseDirectory: Path? = null - private val baseDirectory: File? get() { - val server = NULLABLE_MINECRAFT_SERVER ?: return null - - val baseDirectory = server.storageSource.getLevelPath(resource).toFile() + private val baseDirectory: Path get() { + val baseDirectory = MINECRAFT_SERVER.storageSource.getLevelPath(resource) if (knownBaseDirectory != baseDirectory) { - baseDirectory.mkdirs() + Files.createDirectories(baseDirectory) knownBaseDirectory = baseDirectory } return baseDirectory } - operator fun > get(id: UUID, deserializer: (CompoundTag) -> T, factory: () -> T): T { + fun > get(id: UUID, deserializer: (CompoundTag, HolderLookup.Provider) -> T, factory: () -> T): T { if (!isServerThread()) throw IllegalAccessException("Can not access drive pool from outside of server thread.") @@ -93,11 +93,11 @@ object DrivePool { return get as T } - val file = File(baseDirectory, "$id.dat") + val file = baseDirectory.resolve("$id.dat") if (file.exists()) { try { - val factorize = deserializer(NbtIo.readCompressed(file)) + val factorize = deserializer(NbtIo.readCompressed(file, NbtAccounter.unlimitedHeap()), MINECRAFT_SERVER.registryAccess()) pool[id] = WeakDriveReference(factorize) return factorize } catch (error: Throwable) { @@ -119,16 +119,16 @@ object DrivePool { } fun onWorldSave(event: LevelEvent.Save) { - writeBacklog() + writeBacklog(event.level.server!!.registryAccess()) } - private fun writeBacklog() { + private fun writeBacklog(registry: Provider) { var needsSync = false val removeKeys = ArrayList() for ((key, value) in pool) { try { - val tag = value.sync() + val tag = value.sync(registry) if (tag != null) { LOGGER.debug("Serializing OTM Drive {}", key) @@ -147,11 +147,11 @@ object DrivePool { } if (needsSync) { - Util.backgroundExecutor().execute(::sync) + Util.backgroundExecutor().execute { sync(registry) } } } - private fun sync() { + private fun sync(registry: HolderLookup.Provider) { while (true) { val next = backlog.poll() ?: return val (uuid, tag) = next @@ -159,11 +159,11 @@ object DrivePool { try { LOGGER.debug("Syncing OTM Drive {}", uuid) - val oldFile = File(baseDirectory, "$uuid.dat_old") - val newFile = File(baseDirectory, "$uuid.dat") + val oldFile = baseDirectory.resolve("$uuid.dat_old") + val newFile = baseDirectory.resolve("$uuid.dat") - if (oldFile.exists()) check(oldFile.delete()) { "Unable to delete old dat file" } - if (newFile.exists()) check(newFile.renameTo(oldFile)) { "Unable to move old dat file" } + if (oldFile.exists()) Files.delete(oldFile) + if (newFile.exists()) Files.move(newFile, oldFile) NbtIo.writeCompressed(tag, newFile) } catch (error: Throwable) { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/drive/ItemMatteryDrive.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/drive/ItemMatteryDrive.kt index a5fb59159..f38073b4c 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/drive/ItemMatteryDrive.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/drive/ItemMatteryDrive.kt @@ -1,5 +1,6 @@ package ru.dbotthepony.mc.otm.capability.drive +import net.minecraft.core.HolderLookup import net.minecraft.nbt.CompoundTag import net.minecraft.world.item.Item import net.minecraft.world.item.ItemStack @@ -24,18 +25,18 @@ class ItemMatteryDrive : AbstractMatteryDrive, IItemMatteryDri return insertStack(ItemStorageStack(item), simulate).toItemStack() } - override fun serializeStack(item: ItemStorageStack): CompoundTag { + override fun serializeStack(item: ItemStorageStack, registry: HolderLookup.Provider): CompoundTag { val tag = CompoundTag() - tag["item"] = item.toItemStack(1).serializeNBT() + tag["item"] = item.toItemStack(1).save(registry) tag["count"] = item.count.serializeNBT() return tag } - override fun deserializeStack(tag: CompoundTag): ItemStorageStack? { + override fun deserializeStack(tag: CompoundTag, registry: HolderLookup.Provider): ItemStorageStack? { if ("item" in tag && "count" in tag) { val item = tag["item"] as? CompoundTag ?: return null val count = BigInteger(tag["count"]) - return ItemStorageStack.unsafe(ItemStack.of(item), count) + return ItemStorageStack.unsafe(ItemStack.parseOptional(registry, item), count) } return null diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/energy/BatteryBackedEnergyStorage.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/energy/BatteryBackedEnergyStorage.kt index f43df3712..9bb35f2f7 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/energy/BatteryBackedEnergyStorage.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/energy/BatteryBackedEnergyStorage.kt @@ -1,12 +1,13 @@ package ru.dbotthepony.mc.otm.capability.energy +import net.minecraft.core.HolderLookup import net.minecraft.nbt.CompoundTag import net.minecraft.server.level.ServerPlayer import net.minecraft.world.entity.player.Player import net.minecraft.world.item.ItemStack import net.minecraft.world.ticks.ContainerSingleItem -import net.minecraftforge.common.capabilities.ForgeCapabilities -import net.minecraftforge.common.util.INBTSerializable +import net.neoforged.neoforge.capabilities.Capabilities +import net.neoforged.neoforge.common.util.INBTSerializable import ru.dbotthepony.kommons.io.DelegateSyncher import ru.dbotthepony.kommons.util.getValue import ru.dbotthepony.kommons.util.setValue @@ -15,8 +16,6 @@ import ru.dbotthepony.mc.otm.capability.extractEnergy import ru.dbotthepony.mc.otm.capability.receiveEnergy import ru.dbotthepony.mc.otm.core.math.Decimal import ru.dbotthepony.mc.otm.core.math.getDecimal -import ru.dbotthepony.mc.otm.core.nbt.getItemStack -import ru.dbotthepony.mc.otm.core.ifPresentK import ru.dbotthepony.mc.otm.core.nbt.set import ru.dbotthepony.mc.otm.core.util.decimal import ru.dbotthepony.mc.otm.core.util.observedItem @@ -55,6 +54,14 @@ class BatteryBackedEnergyStorage( return item } + override fun getTheItem(): ItemStack { + return item + } + + override fun setTheItem(p_304718_: ItemStack) { + item = p_304718_ + } + override fun removeItem(slot: Int, count: Int): ItemStack { require(slot == 0) { "Invalid slot $slot" } return item.split(count) @@ -73,24 +80,24 @@ class BatteryBackedEnergyStorage( return true } - override fun serializeNBT(): CompoundTag { + override fun serializeNBT(registry: HolderLookup.Provider): CompoundTag { return CompoundTag().also { it["battery"] = battery.serializeNBT() it["maxBattery"] = maxBattery.serializeNBT() - it["item"] = item.serializeNBT() + it["item"] = item.saveOptional(registry) } } - override fun deserializeNBT(tag: CompoundTag?) { + override fun deserializeNBT(registry: HolderLookup.Provider, tag: CompoundTag?) { tag ?: return battery = tag.getDecimal("battery") maxBattery = tag.getDecimal("maxBattery") - item = tag.getItemStack("item") + item = ItemStack.parseOptional(registry, tag.getCompound("item")) } fun tick() { if (!item.isEmpty && battery < maxBattery) { - item.getCapability(ForgeCapabilities.ENERGY).ifPresentK { + item.getCapability(Capabilities.EnergyStorage.ITEM)?.let { battery += it.extractEnergy(maxBattery - battery, false) } } @@ -102,7 +109,7 @@ class BatteryBackedEnergyStorage( var drained = Decimal.ZERO if (!item.isEmpty) { - item.getCapability(ForgeCapabilities.ENERGY).ifPresentK { + item.getCapability(Capabilities.EnergyStorage.ITEM)?.let { val extracted = it.extractEnergy(howMuch, simulate) drained += extracted howMuch -= extracted @@ -140,7 +147,7 @@ class BatteryBackedEnergyStorage( var received = Decimal.ZERO if (!item.isEmpty) { - item.getCapability(ForgeCapabilities.ENERGY).ifPresentK { + item.getCapability(Capabilities.EnergyStorage.ITEM)?.let { val extracted = it.receiveEnergy(howMuch, simulate) received += extracted howMuch -= extracted @@ -166,7 +173,7 @@ class BatteryBackedEnergyStorage( override var batteryLevel: Decimal get() { if (!item.isEmpty) { - item.getCapability(ForgeCapabilities.ENERGY).ifPresentK { + item.getCapability(Capabilities.EnergyStorage.ITEM)?.let { if (it is IMatteryEnergyStorage) { return battery + it.batteryLevel } else { @@ -185,7 +192,7 @@ class BatteryBackedEnergyStorage( override var maxBatteryLevel: Decimal get() { if (item != ItemStack.EMPTY) { - item.getCapability(ForgeCapabilities.ENERGY).ifPresentK { + item.getCapability(Capabilities.EnergyStorage.ITEM)?.let { if (it is IMatteryEnergyStorage) { return maxBattery + it.maxBatteryLevel } else { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/energy/BlockEnergyStorageImpl.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/energy/BlockEnergyStorageImpl.kt index a798bb3f6..ded418754 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/energy/BlockEnergyStorageImpl.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/energy/BlockEnergyStorageImpl.kt @@ -3,9 +3,9 @@ package ru.dbotthepony.mc.otm.capability.energy +import net.minecraft.core.HolderLookup import net.minecraft.nbt.CompoundTag -import net.minecraftforge.common.util.INBTSerializable -import net.minecraftforge.common.util.LazyOptional +import net.neoforged.neoforge.common.util.INBTSerializable import ru.dbotthepony.mc.otm.capability.FlowDirection import ru.dbotthepony.mc.otm.config.EnergyBalanceValues import ru.dbotthepony.mc.otm.config.VerboseEnergyBalanceValues @@ -105,7 +105,7 @@ open class BlockEnergyStorageImpl( return diff } - override fun serializeNBT(): CompoundTag { + override fun serializeNBT(registry: HolderLookup.Provider): CompoundTag { val tag = CompoundTag() tag[ENERGY_STORED_KEY] = batteryLevel.serializeNBT() @@ -116,7 +116,7 @@ open class BlockEnergyStorageImpl( return tag } - override fun deserializeNBT(nbt: CompoundTag?) { + override fun deserializeNBT(registry: HolderLookup.Provider, nbt: CompoundTag?) { if (nbt == null) return batteryLevel = nbt.mapPresent(ENERGY_STORED_KEY, Decimal.Companion::deserializeNBT) ?: Decimal.ZERO maxBatteryLevelStorage = nbt.mapPresent(ENERGY_STORED_MAX_KEY, Decimal.Companion::deserializeNBT) @@ -124,17 +124,6 @@ open class BlockEnergyStorageImpl( maxOutputStorage = nbt.mapPresent(MAX_OUTPUT_KEY, Decimal.Companion::deserializeNBT) } - var resolver: LazyOptional = LazyOptional.of { this } - private set - - fun invalidate() { - resolver.invalidate() - } - - fun revive() { - resolver = LazyOptional.of { this } - } - companion object { val DEFAULT_MAX_IO = Decimal(400) val DEFAULT_MAX_CAPACITY = Decimal(40_000) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/energy/IEnergyStorageImpl.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/energy/IEnergyStorageImpl.kt index 9cbf683af..28fa9e8cc 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/energy/IEnergyStorageImpl.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/energy/IEnergyStorageImpl.kt @@ -2,7 +2,7 @@ package ru.dbotthepony.mc.otm.capability.energy import net.minecraft.ChatFormatting import net.minecraft.network.chat.Component -import net.minecraftforge.energy.IEnergyStorage +import net.neoforged.neoforge.energy.IEnergyStorage import ru.dbotthepony.mc.otm.capability.FlowDirection import ru.dbotthepony.mc.otm.client.ShiftPressedCond import ru.dbotthepony.mc.otm.core.math.Decimal diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/energy/IMatteryEnergyStorage.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/energy/IMatteryEnergyStorage.kt index 4dcf2b376..ce8a73ea1 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/energy/IMatteryEnergyStorage.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/energy/IMatteryEnergyStorage.kt @@ -1,6 +1,6 @@ package ru.dbotthepony.mc.otm.capability.energy -import net.minecraftforge.energy.IEnergyStorage +import net.neoforged.neoforge.energy.IEnergyStorage import ru.dbotthepony.mc.otm.capability.FlowDirection import ru.dbotthepony.mc.otm.core.math.Decimal import ru.dbotthepony.kommons.math.RGBAColor diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/energy/ItemEnergyStorageImpl.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/energy/ItemEnergyStorageImpl.kt index 44268e9ab..111bbf8d4 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/energy/ItemEnergyStorageImpl.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/energy/ItemEnergyStorageImpl.kt @@ -1,39 +1,16 @@ package ru.dbotthepony.mc.otm.capability.energy -import net.minecraft.core.Direction -import net.minecraft.network.chat.Component import net.minecraft.world.item.ItemStack -import net.minecraft.world.item.TooltipFlag -import net.minecraft.world.level.Level -import net.minecraftforge.common.capabilities.Capability -import net.minecraftforge.common.capabilities.ForgeCapabilities -import net.minecraftforge.common.capabilities.ICapabilityProvider -import net.minecraftforge.common.util.LazyOptional import ru.dbotthepony.mc.otm.capability.FlowDirection -import ru.dbotthepony.mc.otm.capability.MatteryCapability -import ru.dbotthepony.mc.otm.capability.energy -import ru.dbotthepony.mc.otm.core.TooltipList import ru.dbotthepony.mc.otm.core.math.Decimal -import ru.dbotthepony.mc.otm.core.nbt.map -import ru.dbotthepony.mc.otm.core.nbt.set -import ru.dbotthepony.mc.otm.core.tagNotNull - -abstract class ItemEnergyStorageImpl(val itemStack: ItemStack) : IMatteryEnergyStorage, ICapabilityProvider, IEnergyStorageImpl { - private val resolver = LazyOptional.of { this } - - override fun getCapability(cap: Capability, side: Direction?): LazyOptional { - if (cap === ForgeCapabilities.ENERGY || cap === MatteryCapability.ENERGY) { - return resolver.cast() - } - - return LazyOptional.empty() - } +import ru.dbotthepony.mc.otm.registry.MDataComponentTypes +abstract class ItemEnergyStorageImpl(val itemStack: ItemStack) : IMatteryEnergyStorage, IEnergyStorageImpl { abstract val initialBatteryLevel: Decimal override var batteryLevel: Decimal - get() = itemStack.tag?.map(ENERGY_KEY, Decimal.Companion::deserializeNBT) ?: initialBatteryLevel - set(value) { itemStack.tagNotNull[ENERGY_KEY] = value.serializeNBT() } + get() = itemStack[MDataComponentTypes.BATTERY_LEVEL] ?: initialBatteryLevel + set(value) { itemStack[MDataComponentTypes.BATTERY_LEVEL] = value } override fun extractEnergy(howMuch: Decimal, simulate: Boolean): Decimal { if (!howMuch.isPositive || itemStack.count != 1) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/fluid/AbstractMatteryFluidHandler.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/fluid/AbstractMatteryFluidHandler.kt index ded8ab5a4..7799e9397 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/fluid/AbstractMatteryFluidHandler.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/fluid/AbstractMatteryFluidHandler.kt @@ -1,7 +1,7 @@ package ru.dbotthepony.mc.otm.capability.fluid -import net.minecraftforge.fluids.FluidStack -import net.minecraftforge.fluids.capability.IFluidHandler +import net.neoforged.neoforge.fluids.FluidStack +import net.neoforged.neoforge.fluids.capability.IFluidHandler import ru.dbotthepony.mc.otm.capability.FlowDirection import ru.dbotthepony.mc.otm.core.isNotEmpty @@ -49,12 +49,12 @@ abstract class AbstractMatteryFluidHandler : IFluidHandler { val fluid = fluid - if (fluid.isEmpty || fluid.isFluidEqual(resource)) { + if (fluid.isEmpty || FluidStack.isSameFluidSameComponents(fluid, resource)) { val new = (fluid.amount.toLong() + resource.amount.toLong()).coerceAtMost(capacity.toLong()).toInt() if (new <= fluid.amount) return 0 if (action.execute()) { - this.fluid = FluidStack(resource, new) + this.fluid = resource.copyWithAmount(new) } return new - fluid.amount @@ -70,7 +70,7 @@ abstract class AbstractMatteryFluidHandler : IFluidHandler { val fluid = fluid - if (!fluid.isEmpty && fluid.isFluidEqual(resource)) { + if (!fluid.isEmpty && FluidStack.isSameFluidSameComponents(fluid, resource)) { return drain(resource.amount, action) } else { return FluidStack.EMPTY @@ -92,11 +92,11 @@ abstract class AbstractMatteryFluidHandler : IFluidHandler { if (new == 0) { this.fluid = FluidStack.EMPTY } else { - this.fluid = FluidStack(fluid, new) + this.fluid = fluid.copyWithAmount(new) } } - return FluidStack(fluid, fluid.amount - new) + return fluid.copyWithAmount(fluid.amount - new) } } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/fluid/BlockMatteryFluidHandler.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/fluid/BlockMatteryFluidHandler.kt index 0851929d6..f2ac59c5a 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/fluid/BlockMatteryFluidHandler.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/fluid/BlockMatteryFluidHandler.kt @@ -1,32 +1,39 @@ package ru.dbotthepony.mc.otm.capability.fluid +import net.minecraft.core.HolderLookup +import net.minecraft.core.component.DataComponents import net.minecraft.nbt.CompoundTag +import net.minecraft.nbt.Tag import net.minecraft.world.item.BlockItem import net.minecraft.world.item.ItemStack -import net.minecraftforge.common.util.INBTSerializable -import net.minecraftforge.fluids.FluidStack +import net.minecraft.world.item.component.CustomData +import net.neoforged.neoforge.common.util.INBTSerializable +import net.neoforged.neoforge.fluids.FluidStack import ru.dbotthepony.kommons.util.Delegate import ru.dbotthepony.kommons.util.getValue import ru.dbotthepony.kommons.util.setValue +import ru.dbotthepony.mc.otm.Registries import ru.dbotthepony.mc.otm.core.nbt.set -import ru.dbotthepony.mc.otm.core.tagNotNull import java.util.function.IntSupplier /** * Fluid handler for blocks */ -open class BlockMatteryFluidHandler(private val _capacity: IntSupplier, field: Delegate) : AbstractMatteryFluidHandler(), INBTSerializable { +open class BlockMatteryFluidHandler(private val _capacity: IntSupplier, field: Delegate) : AbstractMatteryFluidHandler(), INBTSerializable { override var fluid by field override val capacity: Int get() = _capacity.asInt - override fun serializeNBT(): CompoundTag { - return fluid.writeToNBT(CompoundTag()) + override fun serializeNBT(registry: HolderLookup.Provider): Tag { + return fluid.save(registry) } - override fun deserializeNBT(nbt: CompoundTag?) { - fluid = FluidStack.loadFluidStackFromNBT(nbt) + override fun deserializeNBT(registry: HolderLookup.Provider, nbt: Tag?) { + if (nbt !is CompoundTag) + fluid = FluidStack.EMPTY + else + fluid = FluidStack.parseOptional(registry, nbt) } /** @@ -35,39 +42,16 @@ open class BlockMatteryFluidHandler(private val _capacity: IntSupplier, field: D open class Item(itemStack: ItemStack, capacity: IntSupplier, private val nbtName: String) : ItemMatteryFluidHandler(itemStack, capacity) { override var fluid: FluidStack get() { - val sub = itemStack.tag?.get(BlockItem.BLOCK_ENTITY_TAG) as? CompoundTag ?: return FluidStack.EMPTY - return FluidStack.loadFluidStackFromNBT(sub[nbtName] as? CompoundTag ?: return FluidStack.EMPTY) + val custom = itemStack.getOrDefault(DataComponents.BLOCK_ENTITY_DATA, CustomData.EMPTY) + val sub = custom.unsafe[nbtName] as? CompoundTag ?: return FluidStack.EMPTY + return FluidStack.parseOptional(Registries, sub) } set(value) { - if (value.isEmpty) { - val tag = itemStack.tag ?: return - val subTag = tag.get(BlockItem.BLOCK_ENTITY_TAG) as? CompoundTag + val data = itemStack.getOrDefault(DataComponents.BLOCK_ENTITY_DATA, CustomData.EMPTY) - if (subTag == null) { - if (tag.isEmpty) { - itemStack.tag = null - } - } else { - subTag.remove(nbtName) - - if (subTag.isEmpty) { - tag.remove(BlockItem.BLOCK_ENTITY_TAG) - - if (tag.isEmpty) { - itemStack.tag = null - } - } - } - } else { - var sub = itemStack.tagNotNull.get(BlockItem.BLOCK_ENTITY_TAG) as? CompoundTag - - if (sub == null) { - sub = CompoundTag() - itemStack.tagNotNull[BlockItem.BLOCK_ENTITY_TAG] = sub - } - - sub[nbtName] = value.writeToNBT(CompoundTag()) - } + itemStack[DataComponents.BLOCK_ENTITY_DATA] = CustomData.of(data.copyTag().also { + it[nbtName] = value.saveOptional(Registries) + }) } } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/fluid/FluidHandlerIterator.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/fluid/FluidHandlerIterator.kt index 6e81f7cfb..a89e628ed 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/fluid/FluidHandlerIterator.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/fluid/FluidHandlerIterator.kt @@ -1,8 +1,8 @@ package ru.dbotthepony.mc.otm.capability.fluid import it.unimi.dsi.fastutil.objects.ObjectIterators.AbstractIndexBasedIterator -import net.minecraftforge.fluids.FluidStack -import net.minecraftforge.fluids.capability.IFluidHandler +import net.neoforged.neoforge.fluids.FluidStack +import net.neoforged.neoforge.fluids.capability.IFluidHandler import ru.dbotthepony.mc.otm.container.get class FluidHandlerIterator(private val handler: IFluidHandler, initialPosition: Int = 0) : AbstractIndexBasedIterator(0, initialPosition) { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/fluid/FluidHandlerSpliterator.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/fluid/FluidHandlerSpliterator.kt index 4d7f874d8..9afa4881b 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/fluid/FluidHandlerSpliterator.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/fluid/FluidHandlerSpliterator.kt @@ -2,8 +2,8 @@ package ru.dbotthepony.mc.otm.capability.fluid import it.unimi.dsi.fastutil.objects.ObjectSpliterator import it.unimi.dsi.fastutil.objects.ObjectSpliterators.AbstractIndexBasedSpliterator -import net.minecraftforge.fluids.FluidStack -import net.minecraftforge.fluids.capability.IFluidHandler +import net.neoforged.neoforge.fluids.FluidStack +import net.neoforged.neoforge.fluids.capability.IFluidHandler import ru.dbotthepony.mc.otm.container.get import java.util.Spliterator import java.util.stream.Stream diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/fluid/ItemMatteryFluidHandler.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/fluid/ItemMatteryFluidHandler.kt index fcde61b2b..4a9fc3428 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/fluid/ItemMatteryFluidHandler.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/fluid/ItemMatteryFluidHandler.kt @@ -1,43 +1,19 @@ package ru.dbotthepony.mc.otm.capability.fluid -import net.minecraft.core.Direction -import net.minecraft.nbt.CompoundTag -import net.minecraft.world.item.BlockItem import net.minecraft.world.item.ItemStack -import net.minecraftforge.common.capabilities.Capability -import net.minecraftforge.common.capabilities.ForgeCapabilities -import net.minecraftforge.common.capabilities.ICapabilityProvider -import net.minecraftforge.common.util.LazyOptional -import net.minecraftforge.fluids.FluidStack -import net.minecraftforge.fluids.capability.IFluidHandler -import net.minecraftforge.fluids.capability.IFluidHandlerItem -import ru.dbotthepony.mc.otm.core.nbt.set -import ru.dbotthepony.mc.otm.core.tagNotNull +import net.neoforged.neoforge.fluids.FluidStack +import net.neoforged.neoforge.fluids.capability.IFluidHandler +import net.neoforged.neoforge.fluids.capability.IFluidHandlerItem +import ru.dbotthepony.mc.otm.registry.MDataComponentTypes import java.util.function.IntSupplier /** * Fluid handler for standalone items */ -open class ItemMatteryFluidHandler(val itemStack: ItemStack, private val _capacity: IntSupplier) : AbstractMatteryFluidHandler(), IFluidHandlerItem, ICapabilityProvider { - private val resolver = LazyOptional.of { this } - +open class ItemMatteryFluidHandler(val itemStack: ItemStack, private val _capacity: IntSupplier) : AbstractMatteryFluidHandler(), IFluidHandlerItem { override var fluid: FluidStack - get() { return FluidStack.loadFluidStackFromNBT(itemStack.tag?.get("fluid") as? CompoundTag ?: return FluidStack.EMPTY) } - set(value) { - if (value.isEmpty) { - val tag = itemStack.tag - - if (tag != null) { - tag.remove("fluid") - - if (tag.isEmpty) { - itemStack.tag = null - } - } - } else { - itemStack.tagNotNull["fluid"] = value.writeToNBT(CompoundTag()) - } - } + get() = itemStack[MDataComponentTypes.FLUID_STACK] ?: FluidStack.EMPTY + set(value) { itemStack[MDataComponentTypes.FLUID_STACK] = value } final override val capacity: Int get() = _capacity.asInt @@ -46,14 +22,6 @@ open class ItemMatteryFluidHandler(val itemStack: ItemStack, private val _capaci return itemStack } - override fun getCapability(cap: Capability, side: Direction?): LazyOptional { - if (cap === ForgeCapabilities.FLUID_HANDLER_ITEM || cap === ForgeCapabilities.FLUID_HANDLER) { - return resolver.cast() - } - - return LazyOptional.empty() - } - override fun fill(resource: FluidStack, action: IFluidHandler.FluidAction): Int { if (itemStack.count != 1) return 0 diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/item/CombinedItemHandler.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/item/CombinedItemHandler.kt index 518d43e3e..83c426d0f 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/item/CombinedItemHandler.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/item/CombinedItemHandler.kt @@ -2,7 +2,7 @@ package ru.dbotthepony.mc.otm.capability.item import com.google.common.collect.ImmutableList import net.minecraft.world.item.ItemStack -import net.minecraftforge.items.IItemHandler +import net.neoforged.neoforge.items.IItemHandler import ru.dbotthepony.mc.otm.container.ContainerHandler import java.util.stream.Stream diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/item/EmptyItemHandler.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/item/EmptyItemHandler.kt index 5fb9e1ff3..598bdd942 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/item/EmptyItemHandler.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/item/EmptyItemHandler.kt @@ -1,7 +1,7 @@ package ru.dbotthepony.mc.otm.capability.item import net.minecraft.world.item.ItemStack -import net.minecraftforge.items.IItemHandler +import net.neoforged.neoforge.items.IItemHandler object EmptyItemHandler : IItemHandler { override fun getSlots(): Int { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/item/ProxiedItemHandler.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/item/ProxiedItemHandler.kt index 81533ebd0..4d440d3c3 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/item/ProxiedItemHandler.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/item/ProxiedItemHandler.kt @@ -1,7 +1,7 @@ package ru.dbotthepony.mc.otm.capability.item import net.minecraft.world.item.ItemStack -import net.minecraftforge.items.IItemHandler +import net.neoforged.neoforge.items.IItemHandler class ProxiedItemHandler(var parent: T? = null) : IItemHandler { override fun getSlots(): Int { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/item/UnmodifiableItemHandler.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/item/UnmodifiableItemHandler.kt index 7895a417b..3beaf5ed3 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/item/UnmodifiableItemHandler.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/item/UnmodifiableItemHandler.kt @@ -1,7 +1,7 @@ package ru.dbotthepony.mc.otm.capability.item import net.minecraft.world.item.ItemStack -import net.minecraftforge.items.IItemHandler +import net.neoforged.neoforge.items.IItemHandler class UnmodifiableItemHandler(private val parent: IItemHandler) : IItemHandler by parent { override fun extractItem(slot: Int, amount: Int, simulate: Boolean): ItemStack { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/matter/IMatterStorage.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/matter/IMatterStorage.kt index 9ef928958..dfaa1e3ec 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/matter/IMatterStorage.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/matter/IMatterStorage.kt @@ -1,11 +1,8 @@ package ru.dbotthepony.mc.otm.capability.matter -import net.minecraftforge.common.capabilities.ICapabilityProvider -import ru.dbotthepony.mc.otm.capability.MatteryCapability import ru.dbotthepony.mc.otm.capability.FlowDirection import ru.dbotthepony.mc.otm.core.math.Decimal import ru.dbotthepony.kommons.math.RGBAColor -import ru.dbotthepony.mc.otm.core.orNull import ru.dbotthepony.mc.otm.capability.energy.IMatteryEnergyStorage import kotlin.math.roundToInt @@ -125,5 +122,3 @@ fun IMatterStorage.getBarWidth(): Int { fun IMatterStorage.getBarColor(): Int { return RGBAColor.LOW_MATTER.linearInterpolation((storedMatter / maxStoredMatter).toFloat(), RGBAColor.FULL_MATTER).toBGR() } - -val ICapabilityProvider.matter: IMatterStorage? get() = getCapability(MatteryCapability.MATTER).orNull() diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/matter/IPatternStorage.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/matter/IPatternStorage.kt index 8b3886e1d..70238b168 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/matter/IPatternStorage.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/matter/IPatternStorage.kt @@ -1,10 +1,7 @@ package ru.dbotthepony.mc.otm.capability.matter import net.minecraft.world.item.Item -import net.minecraftforge.common.capabilities.ICapabilityProvider -import ru.dbotthepony.mc.otm.capability.MatteryCapability import ru.dbotthepony.kommons.math.RGBAColor -import ru.dbotthepony.mc.otm.core.orNull import java.util.* import java.util.function.Predicate import java.util.stream.Collectors @@ -75,5 +72,3 @@ fun IPatternStorage.getBarWidth(): Int { fun IPatternStorage.getBarColor(): Int { return RGBAColor.LOW_PATTERNS.linearInterpolation((storedPatterns / patternCapacity).toFloat(), RGBAColor.FULL_PATTERNS).toBGR() } - -val ICapabilityProvider.patterns: IPatternStorage? get() = getCapability(MatteryCapability.PATTERN).orNull() diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/matter/MatterStorageImpl.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/matter/MatterStorageImpl.kt index dbcb66cee..9e361793c 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/matter/MatterStorageImpl.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/matter/MatterStorageImpl.kt @@ -1,7 +1,8 @@ package ru.dbotthepony.mc.otm.capability.matter +import net.minecraft.core.HolderLookup import net.minecraft.nbt.CompoundTag -import net.minecraftforge.common.util.INBTSerializable +import net.neoforged.neoforge.common.util.INBTSerializable import ru.dbotthepony.mc.otm.config.EnergyBalanceValues import ru.dbotthepony.mc.otm.config.VerboseEnergyBalanceValues import ru.dbotthepony.mc.otm.capability.FlowDirection @@ -91,7 +92,7 @@ open class MatterStorageImpl( return diff } - override fun serializeNBT(): CompoundTag { + override fun serializeNBT(registry: HolderLookup.Provider): CompoundTag { return CompoundTag().also { it[MATTER_STORED_KEY] = storedMatter.serializeNBT() //it["max_storage"] = maxStoredMatter.serializeNBT() @@ -100,7 +101,7 @@ open class MatterStorageImpl( } } - override fun deserializeNBT(tag: CompoundTag?) { + override fun deserializeNBT(registry: HolderLookup.Provider, tag: CompoundTag?) { if (tag == null) return storedMatter = Decimal.deserializeNBT(tag[MATTER_STORED_KEY]) //maxStoredMatter = ImpreciseFraction.deserializeNBT(tag["max_storage"]) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/matter/PatternState.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/matter/PatternState.kt index d3ae04379..82315afaf 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/matter/PatternState.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/matter/PatternState.kt @@ -2,16 +2,12 @@ package ru.dbotthepony.mc.otm.capability.matter import com.mojang.serialization.Codec import com.mojang.serialization.codecs.RecordCodecBuilder -import net.minecraft.nbt.CompoundTag -import net.minecraft.nbt.NbtOps -import net.minecraft.nbt.Tag +import net.minecraft.core.registries.BuiltInRegistries import net.minecraft.network.FriendlyByteBuf import net.minecraft.world.item.Item import net.minecraft.world.item.ItemStack -import net.minecraftforge.registries.ForgeRegistries import ru.dbotthepony.mc.otm.core.util.readBinaryJsonWithCodec import ru.dbotthepony.mc.otm.core.util.writeBinaryJsonWithCodec -import ru.dbotthepony.mc.otm.data.UUIDCodec import java.util.* data class PatternState( @@ -31,17 +27,7 @@ data class PatternState( buff.writeBinaryJsonWithCodec(CODEC, this) } - fun serializeNBT(): CompoundTag { - return CODEC.encode(this, NbtOps.INSTANCE, NbtOps.INSTANCE.empty()).get() - .map({ it as CompoundTag }, { throw RuntimeException("Failed to serialize PatternState: ${it.message()}") }) - } - companion object { - fun deserializeNBT(tag: Tag?): PatternState? { - tag ?: return null - return CODEC.decode(NbtOps.INSTANCE, tag).result().map { it.first }.orElse(null) - } - fun read(buff: FriendlyByteBuf): PatternState { return buff.readBinaryJsonWithCodec(CODEC) } @@ -50,7 +36,7 @@ data class PatternState( RecordCodecBuilder.create { it.group( UUIDCodec.fieldOf("id").forGetter(PatternState::id), - ForgeRegistries.ITEMS.codec.fieldOf("item").forGetter(PatternState::item), + BuiltInRegistries.ITEM.byNameCodec().fieldOf("item").forGetter(PatternState::item), Codec.doubleRange(0.0, 1.0).fieldOf("researchPercent").forGetter(PatternState::researchPercent) ).apply(it, ::PatternState) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/matter/ReplicationTask.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/matter/ReplicationTask.kt index feb080e75..2b8f52a07 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/matter/ReplicationTask.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/matter/ReplicationTask.kt @@ -2,16 +2,15 @@ package ru.dbotthepony.mc.otm.capability.matter import com.mojang.serialization.Codec import com.mojang.serialization.codecs.RecordCodecBuilder +import net.minecraft.core.registries.BuiltInRegistries import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.NbtOps import net.minecraft.nbt.Tag import net.minecraft.network.FriendlyByteBuf import net.minecraft.world.item.Item import net.minecraft.world.item.ItemStack -import net.minecraftforge.registries.ForgeRegistries import ru.dbotthepony.mc.otm.core.util.readBinaryJsonWithCodec import ru.dbotthepony.mc.otm.core.util.writeBinaryJsonWithCodec -import ru.dbotthepony.mc.otm.data.UUIDCodec import java.util.Optional import java.util.UUID @@ -48,7 +47,7 @@ data class ReplicationTask( } fun serializeNBT(): CompoundTag { - return CODEC.encode(this, NbtOps.INSTANCE, NbtOps.INSTANCE.empty()).get().map({ it as CompoundTag }, { throw RuntimeException("Failed to serialize ReplicationTask: ${it.message()}") }) + return CODEC.encode(this, NbtOps.INSTANCE, NbtOps.INSTANCE.empty()).mapOrElse({ it as CompoundTag }, { throw RuntimeException("Failed to serialize ReplicationTask: ${it.message()}") }) } fun write(buff: FriendlyByteBuf) { @@ -69,7 +68,7 @@ data class ReplicationTask( it.group( UUIDCodec.fieldOf("id").forGetter(ReplicationTask::id), UUIDCodec.optionalFieldOf("patternId").forGetter(ReplicationTask::patternId), - ForgeRegistries.ITEMS.codec.fieldOf("item").forGetter(ReplicationTask::item), + BuiltInRegistries.ITEM.byNameCodec().fieldOf("item").forGetter(ReplicationTask::item), Codec.intRange(0, Int.MAX_VALUE).fieldOf("inProgress").forGetter(ReplicationTask::inProgress), Codec.intRange(0, Int.MAX_VALUE).fieldOf("finished").forGetter(ReplicationTask::finished), Codec.intRange(0, Int.MAX_VALUE).fieldOf("required").forGetter(ReplicationTask::required), diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/AndroidAbilityKeyMapping.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/AndroidAbilityKeyMapping.kt index 3fd14d90f..0d65f5591 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/AndroidAbilityKeyMapping.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/AndroidAbilityKeyMapping.kt @@ -2,10 +2,11 @@ package ru.dbotthepony.mc.otm.client import com.mojang.blaze3d.platform.InputConstants import net.minecraft.client.KeyMapping -import net.minecraftforge.client.event.RegisterKeyMappingsEvent -import net.minecraftforge.client.event.RenderGuiEvent -import net.minecraftforge.client.event.RenderLevelStageEvent -import net.minecraftforge.client.settings.KeyConflictContext +import net.neoforged.neoforge.client.event.RegisterKeyMappingsEvent +import net.neoforged.neoforge.client.event.RenderGuiEvent +import net.neoforged.neoforge.client.event.RenderLevelStageEvent +import net.neoforged.neoforge.client.settings.KeyConflictContext +import net.neoforged.neoforge.network.PacketDistributor import ru.dbotthepony.mc.otm.OverdriveThatMatters import ru.dbotthepony.mc.otm.android.AndroidActiveFeature import ru.dbotthepony.mc.otm.capability.matteryPlayer @@ -14,7 +15,6 @@ import ru.dbotthepony.mc.otm.client.render.Widgets18 import ru.dbotthepony.mc.otm.client.render.is3DContext import ru.dbotthepony.kommons.math.RGBAColor import ru.dbotthepony.mc.otm.network.ActivateAndroidFeaturePacket -import ru.dbotthepony.mc.otm.network.MatteryPlayerNetworkChannel import kotlin.math.roundToInt object AndroidAbilityKeyMapping : KeyMapping("key.otm.android_ability", KeyConflictContext.IN_GAME, InputConstants.Type.KEYSYM.getOrCreate(InputConstants.KEY_V), OverdriveThatMatters.MOD_ID) { @@ -37,7 +37,7 @@ object AndroidAbilityKeyMapping : KeyMapping("key.otm.android_ability", KeyConfl val feature = feature if (feature != null && feature.activate(true) && minecraft.player != null && feature.android.isAndroid) { - MatteryPlayerNetworkChannel.sendToServer(ActivateAndroidFeaturePacket(feature.type)) + PacketDistributor.sendToServer(ActivateAndroidFeaturePacket(feature.type)) } this.feature = null diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/AndroidMenuKeyMapping.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/AndroidMenuKeyMapping.kt index 0ac414113..6deaaeba9 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/AndroidMenuKeyMapping.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/AndroidMenuKeyMapping.kt @@ -5,10 +5,11 @@ import com.mojang.blaze3d.systems.RenderSystem import it.unimi.dsi.fastutil.objects.Object2FloatArrayMap import it.unimi.dsi.fastutil.objects.Object2FloatFunction import net.minecraft.client.KeyMapping -import net.minecraftforge.client.event.InputEvent -import net.minecraftforge.client.event.RegisterKeyMappingsEvent -import net.minecraftforge.client.event.RenderGuiEvent -import net.minecraftforge.client.settings.KeyConflictContext +import net.neoforged.neoforge.client.event.InputEvent +import net.neoforged.neoforge.client.event.RegisterKeyMappingsEvent +import net.neoforged.neoforge.client.event.RenderGuiEvent +import net.neoforged.neoforge.client.settings.KeyConflictContext +import net.neoforged.neoforge.network.PacketDistributor import ru.dbotthepony.mc.otm.OverdriveThatMatters import ru.dbotthepony.mc.otm.android.AndroidFeature import ru.dbotthepony.mc.otm.android.AndroidSwitchableFeature @@ -21,7 +22,6 @@ import ru.dbotthepony.mc.otm.core.math.angleDifference import ru.dbotthepony.mc.otm.core.math.normalizeAngle import ru.dbotthepony.mc.otm.core.util.formatTickDuration import ru.dbotthepony.mc.otm.milliTimeD -import ru.dbotthepony.mc.otm.network.MatteryPlayerNetworkChannel import ru.dbotthepony.mc.otm.network.SwitchAndroidFeaturePacket import java.util.stream.Collectors import kotlin.math.PI @@ -84,7 +84,7 @@ object AndroidMenuKeyMapping : KeyMapping("key.otm.android_menu", KeyConflictCon val selectedFeature = selectedFeature if (selectedFeature != null) { - MatteryPlayerNetworkChannel.sendToServer(SwitchAndroidFeaturePacket(selectedFeature.type, !selectedFeature.isActive)) + PacketDistributor.sendToServer(SwitchAndroidFeaturePacket(selectedFeature.type, !selectedFeature.isActive)) playGuiClickSound() } } @@ -122,7 +122,7 @@ object AndroidMenuKeyMapping : KeyMapping("key.otm.android_menu", KeyConflictCon val selectedFeature = selectedFeature if (selectedFeature != null) { - MatteryPlayerNetworkChannel.sendToServer(SwitchAndroidFeaturePacket(selectedFeature.type, !selectedFeature.isActive)) + PacketDistributor.sendToServer(SwitchAndroidFeaturePacket(selectedFeature.type, !selectedFeature.isActive)) } } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/ClientEventHandler.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/ClientEventHandler.kt index 66b76fa4a..0621d3e0a 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/ClientEventHandler.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/ClientEventHandler.kt @@ -13,14 +13,13 @@ import net.minecraft.world.inventory.Slot import net.minecraft.world.item.BlockItem import net.minecraft.world.item.Item import net.minecraft.world.level.block.Block -import net.minecraftforge.client.event.MovementInputUpdateEvent -import net.minecraftforge.client.event.ScreenEvent -import net.minecraftforge.client.event.ScreenEvent.MouseDragged -import net.minecraftforge.client.event.ScreenEvent.MouseScrolled -import net.minecraftforge.event.entity.player.ItemTooltipEvent +import net.neoforged.neoforge.client.event.MovementInputUpdateEvent +import net.neoforged.neoforge.client.event.ScreenEvent +import net.neoforged.neoforge.event.entity.player.ItemTooltipEvent +import net.neoforged.neoforge.network.PacketDistributor import ru.dbotthepony.mc.otm.config.ClientConfig import ru.dbotthepony.mc.otm.android.feature.JumpBoostFeature -import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability +import ru.dbotthepony.mc.otm.capability.MatteryPlayer import ru.dbotthepony.mc.otm.capability.matteryPlayer import ru.dbotthepony.mc.otm.client.render.UVWindingOrder import ru.dbotthepony.mc.otm.client.render.Widgets18 @@ -36,7 +35,6 @@ import ru.dbotthepony.mc.otm.core.TranslatableComponent import ru.dbotthepony.mc.otm.core.addAll import ru.dbotthepony.mc.otm.core.math.integerDivisionUp import ru.dbotthepony.mc.otm.menu.MatteryMenu -import ru.dbotthepony.mc.otm.network.MenuNetworkChannel import ru.dbotthepony.mc.otm.registry.AndroidFeatures import java.util.WeakHashMap @@ -115,10 +113,10 @@ private fun inventoryLogic(event: ScreenEvent.Init.Post) { } } -private class InventoryScrollbarPanel(screen: S, matteryPlayer: MatteryPlayerCapability) : DiscreteScrollBarPanel( +private class InventoryScrollbarPanel(screen: S, matteryPlayer: MatteryPlayer) : DiscreteScrollBarPanel( screen, null, { integerDivisionUp(matteryPlayer.exopackContainer.containerSize, 9) }, { _, _, newScroll -> inventoryScroll = newScroll - MenuNetworkChannel.sendToServer(InventoryScrollPacket(newScroll).also { it.play(matteryPlayer.ply) }) + PacketDistributor.sendToServer(InventoryScrollPacket(newScroll).also { it.play(matteryPlayer.ply) }) }, isSlim = true ) @@ -200,7 +198,7 @@ private fun exosuitInventoryLogic(screen: Screen, addListener: (GuiEventListener scrollbar.scroll = inventoryScroll } -fun onMouseDragged(event: MouseDragged.Pre) { +fun onMouseDragged(event: ScreenEvent.MouseDragged.Pre) { val screen = minecraft.screen as? AbstractContainerScreen<*> ?: return if (screen is MatteryScreen<*>) @@ -216,7 +214,7 @@ fun onMouseDragged(event: MouseDragged.Pre) { } } -fun onMouseScrolled(event: MouseScrolled.Pre) { +fun onMouseScrolled(event: ScreenEvent.MouseScrolled.Pre) { val screen = minecraft.screen as? AbstractContainerScreen<*> ?: return if (screen is MatteryScreen<*>) @@ -224,7 +222,7 @@ fun onMouseScrolled(event: MouseScrolled.Pre) { for (widget in screen.renderables) { if (widget is Panel2Widget<*, *>) { - if (widget.panel.mouseScrolledChecked(event.mouseX, event.mouseY, event.deltaX)) { + if (widget.panel.mouseScrolledChecked(event.mouseX, event.mouseY, event.scrollDeltaX)) { event.isCanceled = true return } @@ -233,7 +231,7 @@ fun onMouseScrolled(event: MouseScrolled.Pre) { val slot = screen.slotUnderMouse if (slot != null && (slot.container == minecraft.player?.inventory && slot.containerSlot in 9 .. 35 || slot.container == minecraft.player?.matteryPlayer?.exopackContainer)) { - widget.panel.mouseScrolledInner(event.mouseX, event.mouseY, event.deltaX) + widget.panel.mouseScrolledInner(event.mouseX, event.mouseY, event.scrollDeltaX) event.isCanceled = true return } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/ClientTickHandler.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/ClientTickHandler.kt index 4b456c734..d9bd0339d 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/ClientTickHandler.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/ClientTickHandler.kt @@ -1,8 +1,7 @@ package ru.dbotthepony.mc.otm.client -import net.minecraftforge.client.event.ClientPlayerNetworkEvent -import net.minecraftforge.event.TickEvent -import net.minecraftforge.event.TickEvent.RenderTickEvent +import net.neoforged.neoforge.client.event.ClientPlayerNetworkEvent +import net.neoforged.neoforge.client.event.ClientTickEvent import org.lwjgl.glfw.GLFW import ru.dbotthepony.mc.otm.core.util.IConditionalTickable import ru.dbotthepony.mc.otm.core.util.ITickable @@ -107,12 +106,12 @@ fun tickWhileClientPre(condition: () -> Boolean, ticker: () -> Unit) { tickClientPre(IConditionalTickable.wrap(condition, ticker)) } -fun onClientTick(event: TickEvent.ClientTickEvent) { - if (event.phase == TickEvent.Phase.START) { - preTickList.tick() - } else { - postTickList.tick() - } +fun onClientTickPre(event: ClientTickEvent.Pre) { + preTickList.tick() +} + +fun onClientTickPost(event: ClientTickEvent.Post) { + postTickList.tick() } fun onClientDisconnected(event: ClientPlayerNetworkEvent.LoggingOut) { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/MatteryGUI.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/MatteryGUI.kt index 5cb58196d..8b0628872 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/MatteryGUI.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/MatteryGUI.kt @@ -2,6 +2,7 @@ package ru.dbotthepony.mc.otm.client import com.mojang.blaze3d.systems.RenderSystem import net.minecraft.client.gui.Font +import net.minecraft.client.gui.Gui import net.minecraft.client.gui.GuiGraphics import net.minecraft.client.gui.components.Button import net.minecraft.client.gui.screens.DeathScreen @@ -14,17 +15,17 @@ import net.minecraft.world.entity.LivingEntity import net.minecraft.world.entity.player.Player import net.minecraft.world.item.ItemStack import net.minecraft.world.item.ShieldItem -import net.minecraftforge.client.event.RenderGuiEvent -import net.minecraftforge.client.event.RenderGuiOverlayEvent -import net.minecraftforge.client.event.ScreenEvent -import net.minecraftforge.client.gui.overlay.ForgeGui -import net.minecraftforge.client.gui.overlay.GuiOverlayManager -import net.minecraftforge.common.ToolActions +import net.neoforged.neoforge.client.event.RenderGuiEvent +import net.neoforged.neoforge.client.event.RenderGuiLayerEvent +import net.neoforged.neoforge.client.event.ScreenEvent +import net.neoforged.neoforge.client.gui.VanillaGuiLayers +import net.neoforged.neoforge.common.ItemAbilities +import net.neoforged.neoforge.common.ItemAbility import ru.dbotthepony.mc.otm.OverdriveThatMatters import ru.dbotthepony.mc.otm.android.feature.NanobotsArmorFeature 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.capability.matteryPlayer import ru.dbotthepony.mc.otm.client.render.* import ru.dbotthepony.mc.otm.client.render.sprites.MatteryAtlas @@ -32,8 +33,8 @@ import ru.dbotthepony.mc.otm.client.render.sprites.MatterySprite import ru.dbotthepony.mc.otm.config.ClientConfig import ru.dbotthepony.mc.otm.core.TextComponent import ru.dbotthepony.kommons.math.RGBAColor +import ru.dbotthepony.mc.otm.core.ResourceLocation import ru.dbotthepony.mc.otm.core.util.formatPower -import ru.dbotthepony.mc.otm.core.ifPresentK import ru.dbotthepony.mc.otm.registry.AndroidFeatures import java.util.* import kotlin.math.PI @@ -61,8 +62,6 @@ object MatteryGUI { private var originalBedButtonX = -1 private var originalBedButtonY = -1 - private var lastState: MatteryPlayerCapability? = null - private val buttonShaker = Random() fun onScreenRender(event: ScreenEvent.Render.Pre) { @@ -79,16 +78,16 @@ object MatteryGUI { originalBedButtonY = screen.leaveBedButton.y } - minecraft.player?.getCapability(MatteryCapability.MATTERY_PLAYER)?.ifPresentK { + minecraft.player?.matteryPlayer?.let { if (!it.willBecomeAndroid) { screen.leaveBedButton.x = originalBedButtonX screen.leaveBedButton.y = originalBedButtonY originalBedButtonX = -1 originalBedButtonY = -1 - return@ifPresentK + return@let } - val dispersion = (10.0 * Math.max(0, it.ply.sleepTimer - 20) / (MatteryPlayerCapability.SLEEP_TICKS_LIMIT - 20)).toInt() + val dispersion = (10.0 * Math.max(0, it.ply.sleepTimer - 20) / (MatteryPlayer.SLEEP_TICKS_LIMIT - 20)).toInt() screen.leaveBedButton.x = originalBedButtonX - dispersion / 2 + (buttonShaker.nextDouble() * dispersion).toInt() @@ -106,24 +105,12 @@ object MatteryGUI { val screen = event.screen if (screen is DeathScreen) { - minecraft.player?.getCapability(MatteryCapability.MATTERY_PLAYER)?.ifPresentK { + minecraft.player?.matteryPlayer?.let { if (it.isAndroid) screen.title = TranslatableComponent("otm.death_reason") } } } - private val FOOD_LEVEL_ELEMENT by lazy { - GuiOverlayManager.findOverlay(ResourceLocation("minecraft", "food_level")) - } - - private val AIR_LEVEL_ELEMENT by lazy { - GuiOverlayManager.findOverlay(ResourceLocation("minecraft", "air_level")) - } - - private val PLAYER_HEALTH_ELEMENT by lazy { - GuiOverlayManager.findOverlay(ResourceLocation("minecraft", "player_health")) - } - var iteration = 0 var showIterationUntil = 0L var showIterationUntilFade = 0L @@ -143,7 +130,7 @@ object MatteryGUI { val guiGraphics = MGUIGraphics(event.guiGraphics) val stack = guiGraphics.pose - val window = event.window + val window = minecraft.window stack.pushPose() @@ -207,29 +194,19 @@ object MatteryGUI { showIteration(event) } - private fun renderFoodAndAir(event: RenderGuiOverlayEvent.Pre, gui: ForgeGui) { + private fun renderFoodAndAir(event: RenderGuiLayerEvent.Pre, gui: Gui) { val ply: LocalPlayer = minecraft.player ?: return - if (ply.vehicle is LivingEntity) { + if (ply.vehicle is LivingEntity) return - } - var mattery = ply.matteryPlayer + val mattery = ply.matteryPlayer - if (!ply.isAlive && mattery == null) { - mattery = lastState - } else if (ply.isAlive && mattery != null) { - lastState = mattery - } - - if (mattery != null && mattery.isAndroid) { + if (mattery.isAndroid) { event.isCanceled = true - if (event.overlay === AIR_LEVEL_ELEMENT) { + if (event.name === VanillaGuiLayers.AIR_LEVEL) return - } - - if (!gui.shouldDrawSurvivalElements()) return var level: Float @@ -242,11 +219,13 @@ object MatteryGUI { level = 1f } - gui.setupOverlayRenderState(true, false) + RenderSystem.enableBlend() + RenderSystem.defaultBlendFunc() + RenderSystem.disableDepthTest() RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f) - val width = event.window.guiScaledWidth - val height = event.window.guiScaledHeight + val width = minecraft.window.guiScaledWidth + val height = minecraft.window.guiScaledHeight val left = width / 2 + 10 val top: Int = height - gui.rightHeight gui.rightHeight += 10 @@ -267,6 +246,9 @@ object MatteryGUI { val scale = ClientConfig.HUD.BAR_TEXT_SCALE.toFloat() guiGraphics.draw(formattedPower, left + CHARGE_BG.width + 2f + scale, top + CHARGE_BG.height / 2f + scale, font = gui.font, scale = scale, gravity = RenderGravity.CENTER_LEFT, color = RGBAColor.YELLOW, drawOutline = true) + + RenderSystem.disableBlend() + RenderSystem.enableDepthTest() } } @@ -294,31 +276,25 @@ object MatteryGUI { return RGBAColor.RED } // можно вынести в конфиг, но для этого нужен селектор цвета - private fun renderPlayerHealth(event: RenderGuiOverlayEvent.Pre, gui: ForgeGui) { + private fun renderPlayerHealth(event: RenderGuiLayerEvent.Pre, gui: Gui) { if (!ClientConfig.HUD.ANDROID_HEALTH_BAR) return val ply: LocalPlayer = minecraft.player ?: return - var mattery = ply.matteryPlayer + val mattery = ply.matteryPlayer - if (!ply.isAlive && mattery == null) { - mattery = lastState - } else if (ply.isAlive && mattery != null) { - lastState = mattery - } - - if (mattery != null && mattery.isAndroid) { + if (mattery.isAndroid) { event.isCanceled = true - if (!gui.shouldDrawSurvivalElements()) return - val level: Float = (ply.health / ply.maxHealth).coerceIn(0.0f, 1.0f) val levelAbsorb: Float = (ply.absorptionAmount / ply.maxHealth).coerceIn(0.0f, 1.0f) - gui.setupOverlayRenderState(true, false) + RenderSystem.enableBlend() + RenderSystem.defaultBlendFunc() + RenderSystem.disableDepthTest() RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f) - val width = event.window.guiScaledWidth - val height = event.window.guiScaledHeight + val width = minecraft.window.guiScaledWidth + val height = minecraft.window.guiScaledHeight val left = width / 2 - 10 - 81 val top: Int = height - gui.leftHeight gui.leftHeight += 10 @@ -346,28 +322,30 @@ object MatteryGUI { val scale = ClientConfig.HUD.BAR_TEXT_SCALE.toFloat() guiGraphics.draw(formattedHealth, left - 2f, top + HEALTH_BG.height / 2f + 1f * scale, scale = scale, gravity = RenderGravity.CENTER_RIGHT, color = getHealthColorForPlayer(ply), drawOutline = true) + + RenderSystem.disableBlend() + RenderSystem.enableDepthTest() } } - fun onLayerRenderEvent(event: RenderGuiOverlayEvent.Pre) { - val gui = minecraft.gui as? ForgeGui ?: return - if (minecraft.options.hideGui || !gui.shouldDrawSurvivalElements()) return + fun onLayerRenderEvent(event: RenderGuiLayerEvent.Pre) { + val gui = minecraft.gui - if (event.overlay == FOOD_LEVEL_ELEMENT || event.overlay == AIR_LEVEL_ELEMENT) { + if (event.name == VanillaGuiLayers.FOOD_LEVEL || event.name == VanillaGuiLayers.AIR_LEVEL) { renderFoodAndAir(event, gui) - } else if (event.overlay == PLAYER_HEALTH_ELEMENT) { + } else if (event.name == VanillaGuiLayers.PLAYER_HEALTH) { renderPlayerHealth(event, gui) } } fun renderShieldCooldownOverlay(graphics: GuiGraphics, font: Font, stack: ItemStack, x: Int, y: Int): Boolean { if (!stack.isEmpty && stack.item is ShieldItem) { - if (!stack.canPerformAction(ToolActions.SHIELD_BLOCK)) return false + if (!stack.canPerformAction(ItemAbilities.SHIELD_BLOCK)) return false val ply = minecraft.player ?: return false if (!ply.isUsingItem || stack != ply.useItem || ply.isBlocking) return false - val percent = ((stack.item.getUseDuration(stack) - ply.useItemRemainingTicks + minecraft.partialTick) / 5f).coerceIn(0f, 1f) + val percent = (((stack.item as ShieldItem).getUseDuration(stack, ply) - ply.useItemRemainingTicks + minecraft.gameRenderer.mainCamera.partialTickTime) / 5f).coerceIn(0f, 1f) RenderSystem.setShaderColor(1f, 1f, 1f, 0.5f) drawArc(graphics.pose(), x + 8f, y + 8f, 8f, 0f, PI / 2.0, PI / 2.0 + PI * 2.0 * percent, alignAtCenter = true) RenderSystem.setShaderColor(1f, 1f, 1f, 1f) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/GlitchRenderer.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/GlitchRenderer.kt index 9a3fcf2cb..14f601f8e 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/GlitchRenderer.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/GlitchRenderer.kt @@ -11,7 +11,7 @@ import net.minecraft.client.renderer.GameRenderer import net.minecraft.world.level.levelgen.XoroshiroRandomSource import net.minecraft.world.level.material.FogType import org.joml.Matrix4f -import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability +import ru.dbotthepony.mc.otm.capability.MatteryPlayer import ru.dbotthepony.mc.otm.capability.matteryPlayer import ru.dbotthepony.mc.otm.client.minecraft import ru.dbotthepony.mc.otm.core.math.linearInterpolation @@ -23,17 +23,17 @@ import kotlin.math.absoluteValue object GlitchRenderer { private val random = XoroshiroRandomSource(System.nanoTime(), System.currentTimeMillis()) - var redShiftX = 0.0 + var redShiftX = 0.0f private set - var redShiftY = 0.0 + var redShiftY = 0.0f private set - var greenShiftX = 0.0 + var greenShiftX = 0.0f private set - var greenShiftY = 0.0 + var greenShiftY = 0.0f private set - var blueShiftX = 0.0 + var blueShiftX = 0.0f private set - var blueShiftY = 0.0 + var blueShiftY = 0.0f private set var lastGlitch = System.nanoTime() @@ -46,79 +46,76 @@ object GlitchRenderer { MainTarget(minecraft.window.width, minecraft.window.height) } - private fun upload(builder: BufferBuilder, offsetX: Double, offsetY: Double, u0: Float, v0: Float, u1: Float, v1: Float) { - builder.vertex(offsetX - 1.0, offsetY + 1.0, 0.0).uv(u0, v1).endVertex() - builder.vertex(offsetX + 1.0, offsetY + 1.0, 0.0).uv(u1, v1).endVertex() - builder.vertex(offsetX + 1.0, offsetY - 1.0, 0.0).uv(u1, v0).endVertex() - builder.vertex(offsetX - 1.0, offsetY - 1.0, 0.0).uv(u0, v0).endVertex() + private fun upload(builder: BufferBuilder, offsetX: Float, offsetY: Float, u0: Float, v0: Float, u1: Float, v1: Float) { + builder.vertex(offsetX - 1.0f, offsetY + 1.0f, 0.0f).uv(u0, v1) + builder.vertex(offsetX + 1.0f, offsetY + 1.0f, 0.0f).uv(u1, v1) + builder.vertex(offsetX + 1.0f, offsetY - 1.0f, 0.0f).uv(u1, v0) + builder.vertex(offsetX - 1.0f, offsetY - 1.0f, 0.0f).uv(u0, v0) } - private fun uploadEmpty(builder: BufferBuilder, offsetX: Double, offsetY: Double) { - builder.vertex(offsetX - 1.0, offsetY + 1.0, 0.0).endVertex() - builder.vertex(offsetX + 1.0, offsetY + 1.0, 0.0).endVertex() - builder.vertex(offsetX + 1.0, offsetY - 1.0, 0.0).endVertex() - builder.vertex(offsetX - 1.0, offsetY - 1.0, 0.0).endVertex() + private fun uploadEmpty(builder: BufferBuilder, offsetX: Float, offsetY: Float) { + builder.vertex(offsetX - 1.0f, offsetY + 1.0f, 0.0f) + builder.vertex(offsetX + 1.0f, offsetY + 1.0f, 0.0f) + builder.vertex(offsetX + 1.0f, offsetY - 1.0f, 0.0f) + builder.vertex(offsetX - 1.0f, offsetY - 1.0f, 0.0f) } - private fun uploadLine(builder: BufferBuilder, offsetX: Double, offsetY: Double, height: Double, u0: Float, v0: Float, u1: Float, v1: Float) { - builder.vertex(offsetX - 1.0, offsetY - height, 0.0).uv(u0, v1).endVertex() - builder.vertex(offsetX + 1.0, offsetY - height, 0.0).uv(u1, v1).endVertex() - builder.vertex(offsetX + 1.0, offsetY, 0.0).uv(u1, v0).endVertex() - builder.vertex(offsetX - 1.0, offsetY, 0.0).uv(u0, v0).endVertex() + private fun uploadLine(builder: BufferBuilder, offsetX: Float, offsetY: Float, height: Float, u0: Float, v0: Float, u1: Float, v1: Float) { + builder.vertex(offsetX - 1.0f, offsetY - height, 0.0f).uv(u0, v1) + builder.vertex(offsetX + 1.0f, offsetY - height, 0.0f).uv(u1, v1) + builder.vertex(offsetX + 1.0f, offsetY, 0.0f).uv(u1, v0) + builder.vertex(offsetX - 1.0f, offsetY, 0.0f).uv(u0, v0) } - private inline fun makeMirrors(handler: (x: Double, y: Double, u0: Float, v0: Float, u1: Float, v1: Float) -> Unit) { - handler(0.0 - 2f, 0.0, 1f, 0f, 0f, 1f) - handler(0.0 + 2f, 0.0, 1f, 0f, 0f, 1f) + private inline fun makeMirrors(handler: (x: Float, y: Float, u0: Float, v0: Float, u1: Float, v1: Float) -> Unit) { + handler(0.0f - 2f, 0.0f, 1f, 0f, 0f, 1f) + handler(0.0f + 2f, 0.0f, 1f, 0f, 0f, 1f) - handler(0.0, 2.0, 0f, 1f, 1f, 0f) - handler(0.0, -2.0, 0f, 1f, 1f, 0f) + handler(0.0f, 2.0f, 0f, 1f, 1f, 0f) + handler(0.0f, -2.0f, 0f, 1f, 1f, 0f) - handler(0.0 - 2f, -2.0, 1f, 1f, 0f, 0f) - handler(0.0 + 2f, -2.0, 1f, 1f, 0f, 0f) + handler(0.0f - 2f, -2.0f, 1f, 1f, 0f, 0f) + handler(0.0f + 2f, -2.0f, 1f, 1f, 0f, 0f) - handler(0.0 - 2f, +2.0, 1f, 1f, 0f, 0f) - handler(0.0 + 2f, +2.0, 1f, 1f, 0f, 0f) + handler(0.0f - 2f, +2.0f, 1f, 1f, 0f, 0f) + handler(0.0f + 2f, +2.0f, 1f, 1f, 0f, 0f) } - private fun draw(offsetX: Double, offsetY: Double) { - val builder = tesselator.builder - - builder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX) + private fun draw(offsetX: Float, offsetY: Float) { + val builder = tesselator.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX) upload(builder, offsetX, offsetY, 0f, 0f, 1f, 1f) - if (offsetX != 0.0 || offsetY != 0.0) { - makeMirrors { x: Double, y: Double, u0: Float, v0: Float, u1: Float, v1: Float -> + if (offsetX != 0.0f || offsetY != 0.0f) { + makeMirrors { x: Float, y: Float, u0: Float, v0: Float, u1: Float, v1: Float -> upload(builder, offsetX + x, offsetY + y, u0, v0, u1, v1) } } - BufferUploader.drawWithShader(builder.end()) + BufferUploader.drawWithShader(builder.buildOrThrow()) } - private fun pixel2ViewX(value: Double) = linearInterpolation(value / glitchBuffer.width, 1.0, -1.0) - private fun pixel2ViewY(value: Double) = linearInterpolation(value / glitchBuffer.height, 1.0, -1.0) - private fun pixel2TextureX(value: Double) = (value / glitchBuffer.width).toFloat() - private fun pixel2TextureY(value: Double) = 1f - (value / glitchBuffer.height).toFloat() + private fun pixel2ViewX(value: Float) = linearInterpolation(value / glitchBuffer.width, 1.0f, -1.0f) + private fun pixel2ViewY(value: Float) = linearInterpolation(value / glitchBuffer.height, 1.0f, -1.0f) + private fun pixel2TextureX(value: Float) = (value / glitchBuffer.width).toFloat() + private fun pixel2TextureY(value: Float) = 1f - (value / glitchBuffer.height).toFloat() - private fun drawVHSLineGap(y: Double, height: Double) { - val builder = tesselator.builder + private fun drawVHSLineGap(y: Float, height: Float) { + val builder = tesselator.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX) val v = pixel2TextureY(y) - builder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX) - uploadLine(builder, 0.0, pixel2ViewY(y), (height / glitchBuffer.height) * 2.0, 0f, v, 1f, v) - BufferUploader.drawWithShader(builder.end()) + uploadLine(builder, 0.0f, pixel2ViewY(y), (height / glitchBuffer.height) * 2.0f, 0f, v, 1f, v) + BufferUploader.drawWithShader(builder.buildOrThrow()) } private fun makeGlitch() { - redShiftX = random.nextDouble() * 0.05 - 0.025 - redShiftY = random.nextDouble() * 0.05 - 0.025 - greenShiftX = random.nextDouble() * 0.05 - 0.025 - greenShiftY = random.nextDouble() * 0.05 - 0.025 - blueShiftX = random.nextDouble() * 0.05 - 0.025 - blueShiftY = random.nextDouble() * 0.05 - 0.025 + redShiftX = random.nextFloat() * 0.05f - 0.025f + redShiftY = random.nextFloat() * 0.05f - 0.025f + greenShiftX = random.nextFloat() * 0.05f - 0.025f + greenShiftY = random.nextFloat() * 0.05f - 0.025f + blueShiftX = random.nextFloat() * 0.05f - 0.025f + blueShiftY = random.nextFloat() * 0.05f - 0.025f lastGlitch = System.nanoTime() nextGlitch = random.nextIntBetweenInclusive(75_000_000, 400_000_000).toLong() } @@ -135,7 +132,7 @@ object GlitchRenderer { } } - private var lastAndroid: WeakReference? = null + private var lastAndroid: WeakReference? = null @JvmStatic fun render() { @@ -151,8 +148,8 @@ object GlitchRenderer { RenderSystem.setProjectionMatrix(Matrix4f(), VertexSorting.ORTHOGRAPHIC_Z) RenderSystem.getModelViewStack().also { - it.pushPose() - it.setIdentity() + it.pushMatrix() + it.identity() } RenderSystem.applyModelViewMatrix() @@ -186,7 +183,7 @@ object GlitchRenderer { RenderSystem.setShader(GameRenderer::getPositionTexShader) RenderSystem.setShaderColor(1f, 1f, 1f, 1f) - draw(0.0, 0.0) + draw(0.0f, 0.0f) minecraft.mainRenderTarget.bindWrite(true) RenderSystem.setShader(GameRenderer::getPositionTexShader) @@ -194,7 +191,7 @@ object GlitchRenderer { RenderSystem.blendFunc(GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO) RenderSystem.setShaderColor(1f, 1f, 1f, 1f) RenderSystem.setShaderTexture(0, glitchBuffer.colorTextureId) - draw(0.0, 0.0) + draw(0.0f, 0.0f) } glitchBuffer.bindWrite(true) @@ -222,17 +219,17 @@ object GlitchRenderer { RenderSystem.blendFunc(GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO) RenderSystem.setShaderColor(1f, 1f, 1f, 1f) RenderSystem.setShaderTexture(0, glitchBuffer.colorTextureId) - draw(0.0, 0.0) + draw(0.0f, 0.0f) // return to our frame buffer (post process stage) glitchBuffer.bindWrite(true) RenderSystem.setShaderTexture(0, minecraft.mainRenderTarget.colorTextureId) // color perception errors (eye-camera glitch) - drawVHSLineGap((milliTime % glitchBuffer.height).toDouble(), glitchBuffer.height * 0.025) - drawVHSLineGap(((milliTime + glitchBuffer.height / 2) % glitchBuffer.height).toDouble(), glitchBuffer.height * 0.075) - drawVHSLineGap(((milliTime + glitchBuffer.height / 3) % glitchBuffer.height).toDouble(), glitchBuffer.height * 0.04) - drawVHSLineGap(((-milliTime - glitchBuffer.height / 3) % glitchBuffer.height).toDouble().absoluteValue, glitchBuffer.height * 0.07) + drawVHSLineGap((milliTime % glitchBuffer.height).toFloat(), glitchBuffer.height * 0.025f) + drawVHSLineGap(((milliTime + glitchBuffer.height / 2) % glitchBuffer.height).toFloat(), glitchBuffer.height * 0.075f) + drawVHSLineGap(((milliTime + glitchBuffer.height / 3) % glitchBuffer.height).toFloat(), glitchBuffer.height * 0.04f) + drawVHSLineGap(((-milliTime - glitchBuffer.height / 3) % glitchBuffer.height).toFloat().absoluteValue, glitchBuffer.height * 0.07f) // upload final result to main frame buffer minecraft.mainRenderTarget.bindWrite(true) @@ -242,10 +239,10 @@ object GlitchRenderer { RenderSystem.blendFunc(GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO) RenderSystem.setShaderColor(1f, 1f, 1f, 1f) RenderSystem.setShaderTexture(0, glitchBuffer.colorTextureId) - draw(0.0, 0.0) + draw(0.0f, 0.0f) RenderSystem.setProjectionMatrix(projection, VertexSorting.DISTANCE_TO_ORIGIN) - RenderSystem.getModelViewStack().popPose() + RenderSystem.getModelViewStack().popMatrix() RenderSystem.applyModelViewMatrix() } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/RenderExtensions.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/RenderExtensions.kt index 98d6442e5..1c7ad7433 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/RenderExtensions.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/RenderExtensions.kt @@ -4,6 +4,7 @@ import com.mojang.blaze3d.vertex.PoseStack import com.mojang.blaze3d.vertex.Tesselator import com.mojang.blaze3d.vertex.VertexConsumer import net.minecraft.core.Vec3i +import org.joml.Matrix3f import org.joml.Matrix4f import org.joml.Vector3f import ru.dbotthepony.kommons.math.RGBAColor @@ -15,15 +16,29 @@ import ru.dbotthepony.mc.otm.core.math.translation val tesselator: Tesselator get() = Tesselator.getInstance() -fun VertexConsumer.normal(vector: Vector): VertexConsumer = normal(vector.x.toFloat(), vector.y.toFloat(), vector.z.toFloat()) +// what meth have you been smoking, mojang, with new names +fun VertexConsumer.vertex(matrix4f: Matrix4f, x: Float, y: Float, z: Float): VertexConsumer = addVertex(matrix4f, x, y, z) +fun VertexConsumer.vertex(x: Float, y: Float, z: Float): VertexConsumer = addVertex(x, y, z) +fun VertexConsumer.uv(u: Float, v: Float): VertexConsumer = setUv(u, v) +fun VertexConsumer.overlayCoords(coords: Int): VertexConsumer = setOverlay(coords) +fun VertexConsumer.light(coords: Int): VertexConsumer = setLight(coords) + +fun VertexConsumer.normal(vector: Vector): VertexConsumer = setNormal(vector.x.toFloat(), vector.y.toFloat(), vector.z.toFloat()) +fun VertexConsumer.normal(pose: PoseStack.Pose, vector: Vector): VertexConsumer = setNormal(pose, vector.x.toFloat(), vector.y.toFloat(), vector.z.toFloat()) +fun VertexConsumer.normal(x: Float, y: Float, z: Float): VertexConsumer = setNormal(x, y, z) +fun VertexConsumer.normal(pose: PoseStack.Pose, x: Float, y: Float, z: Float): VertexConsumer = setNormal(pose, x, y, z) fun VertexConsumer.vertex(matrix4f: Matrix4f, vector: Vector): VertexConsumer = vertex(matrix4f, vector.x.toFloat(), vector.y.toFloat(), vector.z.toFloat()) fun VertexConsumer.color(color: RGBAColor?): VertexConsumer { if (color != null) - color(color.redInt, color.greenInt, color.blueInt, color.alphaInt) + setColor(color.redInt, color.greenInt, color.blueInt, color.alphaInt) return this } +fun VertexConsumer.color(r: Float, g: Float, b: Float, a: Float): VertexConsumer { + return setColor(r, g, b, a) +} + fun PoseStack.translate(vector: Vector) = translate(vector.x, vector.y, vector.z) fun PoseStack.translate(vector: Vec3i) = translate(vector.x.toDouble(), vector.y.toDouble(), vector.z.toDouble()) fun PoseStack.translate(vector: Vector3f) = translate(vector.x(), vector.y(), vector.z()) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/RenderHelper.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/RenderHelper.kt index f5f3b0a83..b2808cb34 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/RenderHelper.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/RenderHelper.kt @@ -17,6 +17,7 @@ import org.lwjgl.opengl.GL11.GL_LESS import ru.dbotthepony.kommons.math.RGBAColor import ru.dbotthepony.mc.otm.OverdriveThatMatters import ru.dbotthepony.mc.otm.client.minecraft +import ru.dbotthepony.mc.otm.core.ResourceLocation import java.util.* import kotlin.collections.ArrayDeque import kotlin.math.PI @@ -70,26 +71,25 @@ fun renderRect( if (!is3DContext) RenderSystem.depthFunc(GL_ALWAYS) - val tess = tesselator - val builder = tess.builder - if (color.isWhite) { - builder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION) + val builder = tesselator.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION) - builder.vertex(matrix, x, y + height, z).endVertex() - builder.vertex(matrix, x + width, y + height, z).endVertex() - builder.vertex(matrix, x + width, y, z).endVertex() - builder.vertex(matrix, x, y, z).endVertex() + builder.vertex(matrix, x, y + height, z) + builder.vertex(matrix, x + width, y + height, z) + builder.vertex(matrix, x + width, y, z) + builder.vertex(matrix, x, y, z) + + BufferUploader.drawWithShader(builder.buildOrThrow()) } else { - builder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR) + val builder = tesselator.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR) - builder.vertex(matrix, x, y + height, z).color(color).endVertex() - builder.vertex(matrix, x + width, y + height, z).color(color).endVertex() - builder.vertex(matrix, x + width, y, z).color(color).endVertex() - builder.vertex(matrix, x, y, z).color(color).endVertex() + builder.vertex(matrix, x, y + height, z).color(color) + builder.vertex(matrix, x + width, y + height, z).color(color) + builder.vertex(matrix, x + width, y, z).color(color) + builder.vertex(matrix, x, y, z).color(color) + + BufferUploader.drawWithShader(builder.buildOrThrow()) } - - tess.end() } @Suppress("NAME_SHADOWING") @@ -110,10 +110,7 @@ fun renderCheckerboard( if (!is3DContext) RenderSystem.depthFunc(GL_ALWAYS) - val tess = tesselator - val builder = tess.builder - - builder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR) + val builder = tesselator.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR) for (i in 0 ..< width.toInt()) { val x = x + i.toFloat() @@ -122,15 +119,15 @@ fun renderCheckerboard( val y = y + j.toFloat() if ((i + j) % 2 == 0) { - builder.vertex(matrix, x, y + 1f, z).color(color).endVertex() - builder.vertex(matrix, x + 1f, y + 1f, z).color(color).endVertex() - builder.vertex(matrix, x + 1f, y, z).color(color).endVertex() - builder.vertex(matrix, x, y, z).color(color).endVertex() + builder.vertex(matrix, x, y + 1f, z).color(color) + builder.vertex(matrix, x + 1f, y + 1f, z).color(color) + builder.vertex(matrix, x + 1f, y, z).color(color) + builder.vertex(matrix, x, y, z).color(color) } } } - tess.end() + BufferUploader.drawWithShader(builder.buildOrThrow()) } fun renderTexturedRect( @@ -164,25 +161,25 @@ fun renderTexturedRect( if (!is3DContext) RenderSystem.depthFunc(GL_ALWAYS) - val builder = tesselator.builder - if (color.isWhite) { - builder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX) + val builder = tesselator.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX) - builder.vertex(matrix, x, y + height, z).uv(u0, v1).endVertex() - builder.vertex(matrix, x + width, y + height, z).uv(u1, v1).endVertex() - builder.vertex(matrix, x + width, y, z).uv(u1, v0).endVertex() - builder.vertex(matrix, x, y, z).uv(u0, v0).endVertex() + builder.vertex(matrix, x, y + height, z).uv(u0, v1) + builder.vertex(matrix, x + width, y + height, z).uv(u1, v1) + builder.vertex(matrix, x + width, y, z).uv(u1, v0) + builder.vertex(matrix, x, y, z).uv(u0, v0) + + BufferUploader.drawWithShader(builder.buildOrThrow()) } else { - builder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX_COLOR) + val builder = tesselator.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX_COLOR) - builder.vertex(matrix, x, y + height, z).uv(u0, v1).color(color).endVertex() - builder.vertex(matrix, x + width, y + height, z).uv(u1, v1).color(color).endVertex() - builder.vertex(matrix, x + width, y, z).uv(u1, v0).color(color).endVertex() - builder.vertex(matrix, x, y, z).uv(u0, v0).color(color).endVertex() + builder.vertex(matrix, x, y + height, z).uv(u0, v1).color(color) + builder.vertex(matrix, x + width, y + height, z).uv(u1, v1).color(color) + builder.vertex(matrix, x + width, y, z).uv(u1, v0).color(color) + builder.vertex(matrix, x, y, z).uv(u0, v0).color(color) + + BufferUploader.drawWithShader(builder.buildOrThrow()) } - - BufferUploader.drawWithShader(builder.end()) } fun renderColoredSphere(pose: PoseStack, radius: Float, color: RGBAColor = RGBAColor.WHITE) { @@ -190,8 +187,7 @@ fun renderColoredSphere(pose: PoseStack, radius: Float, color: RGBAColor = RGBAC RenderSystem.enableBlend() RenderSystem.defaultBlendFunc() - val builder = tesselator.builder - builder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR) + val builder = tesselator.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR) val turnStep = Math.PI * (1 / fragments.toDouble()) * 2 val stripeStep = Math.PI * (1 / fragments.toDouble()) @@ -212,23 +208,19 @@ fun renderColoredSphere(pose: PoseStack, radius: Float, color: RGBAColor = RGBAC builder.vertex(pose.last().pose(), xPre * cos(tiltPost).toFloat(), yPost, zPre * cos(tiltPost).toFloat()) .color(color) - .endVertex() builder.vertex(pose.last().pose(), xPost * cos(tiltPost).toFloat(), yPost, zPost * cos(tiltPost).toFloat()) .color(color) - .endVertex() builder.vertex(pose.last().pose(), xPost * cos(tiltPre).toFloat(), yPre, zPost * cos(tiltPre).toFloat()) .color(color) - .endVertex() builder.vertex(pose.last().pose(), xPre * cos(tiltPre).toFloat(), yPre, zPre * cos(tiltPre).toFloat()) .color(color) - .endVertex() } } - BufferUploader.drawWithShader(builder.end()) + BufferUploader.drawWithShader(builder.buildOrThrow()) } fun drawLine( @@ -248,10 +240,7 @@ fun drawLine( if (!is3DContext) RenderSystem.depthFunc(GL_ALWAYS) - val tess = Tesselator.getInstance() - val builder = tess.builder - - builder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR) + val builder = tesselator.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR) val length = ((startX - endX).pow(2f) + (startY - endY).pow(2f)).pow(0.5f) val angle = acos((endX - startX) / length) @@ -272,24 +261,24 @@ fun drawLine( builder.vertex(matrix, startX - y0 * sin, startY + y0 * cos, - z).color(color).endVertex() + z).color(color) builder.vertex(matrix, startX - y1 * sin, startY + y1 * cos, - z).color(color).endVertex() + z).color(color) builder.vertex(matrix, startX + x2 * cos - y2 * sin, startY + x2 * sin + y2 * cos, - z).color(color).endVertex() + z).color(color) builder.vertex(matrix, startX + x3 * cos - y3 * sin, startY + x3 * sin + y3 * cos, - z).color(color).endVertex() + z).color(color) - tess.end() + BufferUploader.drawWithShader(builder.buildOrThrow()) } data class ScissorRect(val xStart: Int, val yStart: Int, val xEnd: Int, val yEnd: Int, val lock: Boolean = false) { @@ -421,17 +410,15 @@ fun clearDepth(stack: PoseStack, x: Float, y: Float, width: Float, height: Float RenderSystem.enableDepthTest() RenderSystem.depthFunc(GL_ALWAYS) - val builder = tesselator.builder - val matrix = stack.last().pose() - builder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION) - builder.vertex(matrix, x, y + height, depth).endVertex() - builder.vertex(matrix, x + width, y + height, depth).endVertex() - builder.vertex(matrix, x + width, y, depth).endVertex() - builder.vertex(matrix, x, y, depth).endVertex() + val builder = tesselator.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION) + builder.vertex(matrix, x, y + height, depth) + builder.vertex(matrix, x + width, y + height, depth) + builder.vertex(matrix, x + width, y, depth) + builder.vertex(matrix, x, y, depth) - BufferUploader.drawWithShader(builder.end()) + BufferUploader.drawWithShader(builder.buildOrThrow()) RenderSystem.defaultBlendFunc() RenderSystem.depthFunc(GL_LESS) @@ -498,13 +485,13 @@ fun uploadArc( if (triangleFan) { val singleStep = (endDegree - startDegree) / steps - builder.vertex(matrix, x, y, z).endVertex() + builder.vertex(matrix, x, y, z) for (i in 0 .. steps) { val sin = sin(startDegree + i * singleStep).toFloat() val cos = cos(startDegree + i * singleStep).toFloat() - builder.vertex(matrix, x + outerRadius * sin, y + cos * outerRadius, z).endVertex() + builder.vertex(matrix, x + outerRadius * sin, y + cos * outerRadius, z) } } else { val singleStep = (endDegree - startDegree) / (steps + 1) @@ -516,10 +503,10 @@ fun uploadArc( val sin2 = sin(startDegree + (i + 1) * singleStep).toFloat() val cos2 = cos(startDegree + (i + 1) * singleStep).toFloat() - builder.vertex(matrix, x + outerRadius * sin, y + cos * outerRadius, z).endVertex() - builder.vertex(matrix, x + outerRadius * sin2, y + cos2 * outerRadius, z).endVertex() - builder.vertex(matrix, x + innerRadius * sin2, y + cos2 * innerRadius, z).endVertex() - builder.vertex(matrix, x + innerRadius * sin, y + cos * innerRadius, z).endVertex() + builder.vertex(matrix, x + outerRadius * sin, y + cos * outerRadius, z) + builder.vertex(matrix, x + outerRadius * sin2, y + cos2 * outerRadius, z) + builder.vertex(matrix, x + innerRadius * sin2, y + cos2 * innerRadius, z) + builder.vertex(matrix, x + innerRadius * sin, y + cos * innerRadius, z) } } } @@ -545,18 +532,16 @@ fun drawArc( RenderSystem.defaultBlendFunc() RenderSystem.depthFunc(GL_ALWAYS) - val builder = tesselator.builder - if (innerRadius == 0f) { if (steps >= 1) { - builder.begin(VertexFormat.Mode.TRIANGLE_FAN, DefaultVertexFormat.POSITION) + val builder = tesselator.begin(VertexFormat.Mode.TRIANGLE_FAN, DefaultVertexFormat.POSITION) uploadArc(matrix, builder, x, y, outerRadius, innerRadius, startDegree, endDegree, steps, alignAtCenter, triangleFan = true, z = z) - BufferUploader.drawWithShader(builder.end()) + BufferUploader.drawWithShader(builder.buildOrThrow()) } } else { - builder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION) + val builder = tesselator.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION) uploadArc(matrix, builder, x, y, outerRadius, innerRadius, startDegree, endDegree, steps, alignAtCenter, triangleFan = false, z = z) - BufferUploader.drawWithShader(builder.end()) + BufferUploader.drawWithShader(builder.buildOrThrow()) } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/ResearchIcons.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/ResearchIcons.kt index 1124d674f..05d050374 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/ResearchIcons.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/ResearchIcons.kt @@ -5,6 +5,7 @@ import ru.dbotthepony.mc.otm.OverdriveThatMatters import ru.dbotthepony.mc.otm.client.render.sprites.AbstractMatterySprite import ru.dbotthepony.mc.otm.client.render.sprites.GridAtlas import ru.dbotthepony.mc.otm.client.render.sprites.sprite +import ru.dbotthepony.mc.otm.core.ResourceLocation object ResearchIcons { val ICON_TRANSFER: AbstractMatterySprite diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/ShockwaveRenderer.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/ShockwaveRenderer.kt index c408b8245..1c4515def 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/ShockwaveRenderer.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/ShockwaveRenderer.kt @@ -5,10 +5,9 @@ import com.mojang.blaze3d.vertex.BufferUploader import com.mojang.blaze3d.vertex.DefaultVertexFormat import com.mojang.blaze3d.vertex.VertexFormat import net.minecraft.client.renderer.GameRenderer -import net.minecraftforge.client.event.RenderLevelStageEvent +import net.neoforged.neoforge.client.event.RenderLevelStageEvent import org.lwjgl.opengl.GL11.GL_LESS import ru.dbotthepony.mc.otm.config.AndroidConfig -import ru.dbotthepony.mc.otm.config.ServerConfig import ru.dbotthepony.mc.otm.core.math.Vector import ru.dbotthepony.mc.otm.core.math.component1 import ru.dbotthepony.mc.otm.core.math.component2 @@ -39,8 +38,6 @@ object ShockwaveRenderer { lastRender = secondTimeD if (radius <= finalRadius) { - val builder = tesselator.builder - RenderSystem.setShader(GameRenderer::getPositionShader) RenderSystem.setShaderColor(1f, 1f, 1f, linearInterpolation(radius / finalRadius, 0.5f, 0f)) RenderSystem.defaultBlendFunc() @@ -48,7 +45,7 @@ object ShockwaveRenderer { RenderSystem.enableDepthTest() RenderSystem.depthFunc(GL_LESS) - builder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION) + val builder = tesselator.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION) event.poseStack.pushPose() val (x, y, z) = event.camera.position @@ -57,7 +54,7 @@ object ShockwaveRenderer { uploadArc(event.poseStack.last.pose, builder, x = 0f, y = 0f, innerRadius = (radius - 1f).coerceAtLeast(0f), outerRadius = radius, triangleFan = false) event.poseStack.popPose() - BufferUploader.drawWithShader(builder.end()) + BufferUploader.drawWithShader(builder.buildOrThrow()) } return radius <= finalRadius @@ -72,13 +69,7 @@ object ShockwaveRenderer { } synchronized(activeShockwaves) { - val iterator = activeShockwaves.listIterator() - - for (value in iterator) { - if (!value.render(event)) { - iterator.remove() - } - } + activeShockwaves.removeIf { !it.render(event) } } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/WidgetLocation.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/WidgetLocation.kt index 7929fc86c..17a21e0be 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/WidgetLocation.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/WidgetLocation.kt @@ -3,6 +3,7 @@ package ru.dbotthepony.mc.otm.client.render import net.minecraft.resources.ResourceLocation import ru.dbotthepony.mc.otm.OverdriveThatMatters import ru.dbotthepony.mc.otm.client.render.sprites.MatteryAtlas +import ru.dbotthepony.mc.otm.core.ResourceLocation object WidgetLocation { val LARGE_BUTTON = MatteryAtlas(ResourceLocation(OverdriveThatMatters.MOD_ID, "textures/gui/widgets/large_button.png"), 72f, 18f) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/Widgets8.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/Widgets8.kt index 44af60e19..d53587cc0 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/Widgets8.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/Widgets8.kt @@ -3,6 +3,7 @@ package ru.dbotthepony.mc.otm.client.render import net.minecraft.resources.ResourceLocation import ru.dbotthepony.mc.otm.OverdriveThatMatters import ru.dbotthepony.mc.otm.client.render.sprites.GridAtlas +import ru.dbotthepony.mc.otm.core.ResourceLocation object Widgets8 { val GRID = GridAtlas(ResourceLocation(OverdriveThatMatters.MOD_ID, "textures/gui/widgets_8.png"), 8f, 8f, columns = 64 / 8, rows = 32 / 8) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/blockentity/BlackHoleRenderer.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/blockentity/BlackHoleRenderer.kt index 770ef3d96..f6b3174da 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/blockentity/BlackHoleRenderer.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/blockentity/BlackHoleRenderer.kt @@ -8,6 +8,7 @@ import net.minecraft.client.renderer.MultiBufferSource import net.minecraft.client.renderer.blockentity.BeaconRenderer import net.minecraft.client.renderer.blockentity.BlockEntityRenderer import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider +import net.minecraft.world.phys.AABB import net.minecraft.world.phys.Vec3 import org.joml.Matrix4f import org.lwjgl.opengl.GL30 @@ -19,6 +20,7 @@ import ru.dbotthepony.mc.otm.client.ShiftPressedCond import ru.dbotthepony.mc.otm.client.minecraft import ru.dbotthepony.mc.otm.client.render.* import ru.dbotthepony.kommons.math.RGBAColor +import ru.dbotthepony.mc.otm.core.AABB import ru.dbotthepony.mc.otm.core.math.VECTOR_FORWARD import ru.dbotthepony.mc.otm.core.math.VECTOR_RIGHT import ru.dbotthepony.mc.otm.core.math.VECTOR_UP @@ -60,10 +62,10 @@ private fun pushQuad(matrix4f: Matrix4f, builder: BufferBuilder, quad: Array(context) { @@ -33,10 +39,10 @@ class PlasmaProjectileRenderer(context: EntityRendererProvider.Context) : Entity val matrix = poseStack.last().pose() val normal = poseStack.last().normal() - consumer.vertex(matrix, -.5f, -.5f, 0f).color(1f, 1f, 1f, 1f).uv(0f, 1f).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(packedLight).normal(normal, 0f, 1f, 0f).endVertex() - consumer.vertex(matrix, .5f, -.5f, 0f).color(1f, 1f, 1f, 1f).uv(1f, 1f).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(packedLight).normal(normal, 0f, 1f, 0f).endVertex() - consumer.vertex(matrix, .5f, .5f, 0f).color(1f, 1f, 1f, 1f).uv(1f, 0f).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(packedLight).normal(normal, 0f, 1f, 0f).endVertex() - consumer.vertex(matrix, -.5f, .5f, 0f).color(1f, 1f, 1f, 1f).uv(0f, 0f).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(packedLight).normal(normal, 0f, 1f, 0f).endVertex() + consumer.vertex(matrix, -.5f, -.5f, 0f).color(1f, 1f, 1f, 1f).uv(0f, 1f).overlayCoords(OverlayTexture.NO_OVERLAY).light(packedLight).normal(poseStack.last(), 0f, 1f, 0f) + consumer.vertex(matrix, .5f, -.5f, 0f).color(1f, 1f, 1f, 1f).uv(1f, 1f).overlayCoords(OverlayTexture.NO_OVERLAY).light(packedLight).normal(poseStack.last(), 0f, 1f, 0f) + consumer.vertex(matrix, .5f, .5f, 0f).color(1f, 1f, 1f, 1f).uv(1f, 0f).overlayCoords(OverlayTexture.NO_OVERLAY).light(packedLight).normal(poseStack.last(), 0f, 1f, 0f) + consumer.vertex(matrix, -.5f, .5f, 0f).color(1f, 1f, 1f, 1f).uv(0f, 0f).overlayCoords(OverlayTexture.NO_OVERLAY).light(packedLight).normal(poseStack.last(), 0f, 1f, 0f) poseStack.popPose() diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/sprites/AbstractMatterySprite.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/sprites/AbstractMatterySprite.kt index a65fc4dce..faeb8d4cf 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/sprites/AbstractMatterySprite.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/sprites/AbstractMatterySprite.kt @@ -19,6 +19,8 @@ import ru.dbotthepony.mc.otm.client.render.IUVCoords import ru.dbotthepony.mc.otm.client.render.UVWindingOrder import ru.dbotthepony.mc.otm.client.render.color import ru.dbotthepony.mc.otm.client.render.renderTexturedRect +import ru.dbotthepony.mc.otm.client.render.uv +import ru.dbotthepony.mc.otm.client.render.vertex import ru.dbotthepony.mc.otm.core.math.linearInterpolation import java.util.concurrent.ConcurrentHashMap @@ -129,10 +131,10 @@ sealed class AbstractMatterySprite : IGUIRenderable, IUVCoords { v1: Float, ) { val matrix = pose.last().pose() - builder.vertex(matrix, x, y + height, z).color(color).uv(u0, v1).endVertex() - builder.vertex(matrix, x + width, y + height, z).color(color).uv(u1, v1).endVertex() - builder.vertex(matrix, x + width, y, z).color(color).uv(u1, v0).endVertex() - builder.vertex(matrix, x, y, z).color(color).uv(u0, v0).endVertex() + builder.vertex(matrix, x, y + height, z).color(color).uv(u0, v1) + builder.vertex(matrix, x + width, y + height, z).color(color).uv(u1, v1) + builder.vertex(matrix, x + width, y, z).color(color).uv(u1, v0) + builder.vertex(matrix, x, y, z).color(color).uv(u0, v0) } fun uploadOnto( @@ -185,7 +187,7 @@ sealed class AbstractMatterySprite : IGUIRenderable, IUVCoords { val builder = RenderType.CompositeState.builder() builder.setTextureState(RenderStateShard.TextureStateShard(it, false, false)) - builder.setShaderState(RenderStateShard.ShaderStateShard(GameRenderer::getPositionColorTexShader)) + builder.setShaderState(RenderStateShard.ShaderStateShard(GameRenderer::getPositionTexColorShader)) builder.setDepthTestState(RenderStateShard.DepthTestStateShard("always", GL_ALWAYS)) builder.setTransparencyState(RenderStateShard.TransparencyStateShard("normal_blend", { RenderSystem.enableBlend() @@ -196,7 +198,7 @@ sealed class AbstractMatterySprite : IGUIRenderable, IUVCoords { @Suppress("INACCESSIBLE_TYPE") RenderType.create("otm_gui_element_no_depth", - DefaultVertexFormat.POSITION_COLOR_TEX, + DefaultVertexFormat.POSITION_TEX_COLOR, VertexFormat.Mode.QUADS, 2048, false, @@ -210,7 +212,7 @@ sealed class AbstractMatterySprite : IGUIRenderable, IUVCoords { val builder = RenderType.CompositeState.builder() builder.setTextureState(RenderStateShard.TextureStateShard(it, false, false)) - builder.setShaderState(RenderStateShard.ShaderStateShard(GameRenderer::getPositionColorTexShader)) + builder.setShaderState(RenderStateShard.ShaderStateShard(GameRenderer::getPositionTexColorShader)) builder.setTransparencyState(RenderStateShard.TransparencyStateShard("normal_blend", { RenderSystem.enableBlend() RenderSystem.defaultBlendFunc() @@ -220,7 +222,7 @@ sealed class AbstractMatterySprite : IGUIRenderable, IUVCoords { @Suppress("INACCESSIBLE_TYPE") RenderType.create("otm_gui_element_depth", - DefaultVertexFormat.POSITION_COLOR_TEX, + DefaultVertexFormat.POSITION_TEX_COLOR, VertexFormat.Mode.QUADS, 2048, false, @@ -234,7 +236,7 @@ sealed class AbstractMatterySprite : IGUIRenderable, IUVCoords { val builder = RenderType.CompositeState.builder() builder.setTextureState(RenderStateShard.TextureStateShard(it, false, false)) - builder.setShaderState(RenderStateShard.ShaderStateShard(GameRenderer::getPositionColorTexShader)) + builder.setShaderState(RenderStateShard.ShaderStateShard(GameRenderer::getPositionTexColorShader)) builder.setTransparencyState(RenderStateShard.TransparencyStateShard("normal_blend", { RenderSystem.enableBlend() RenderSystem.defaultBlendFunc() @@ -244,7 +246,7 @@ sealed class AbstractMatterySprite : IGUIRenderable, IUVCoords { @Suppress("INACCESSIBLE_TYPE") RenderType.create("otm_gui_element_world", - DefaultVertexFormat.POSITION_COLOR_TEX, + DefaultVertexFormat.POSITION_TEX_COLOR, VertexFormat.Mode.QUADS, 8192, false, diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/sprites/SpriteType.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/sprites/SpriteType.kt index 9fd4b7efd..c81bfb36f 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/sprites/SpriteType.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/sprites/SpriteType.kt @@ -39,7 +39,7 @@ enum class SpriteType { } override fun fromNetwork(buff: FriendlyByteBuf): AbstractMatterySprite { - val texture = ResourceLocation(buff.readUtf()) + val texture = ResourceLocation.parse(buff.readUtf()) val x = buff.readFloat() val y = buff.readFloat() val width = buff.readFloat() diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/ExopackInventoryScreen.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/ExopackInventoryScreen.kt index ee8b3b2bf..3f627a499 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/ExopackInventoryScreen.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/ExopackInventoryScreen.kt @@ -4,6 +4,7 @@ import mezz.jei.api.constants.RecipeTypes import net.minecraft.client.gui.screens.inventory.InventoryScreen import net.minecraft.world.item.ItemStack import net.minecraft.world.item.Items +import net.neoforged.neoforge.network.PacketDistributor import ru.dbotthepony.mc.otm.client.mousePos import ru.dbotthepony.mc.otm.client.moveMousePosScaled import ru.dbotthepony.mc.otm.client.render.ItemStackIcon @@ -27,7 +28,6 @@ import ru.dbotthepony.mc.otm.compat.curios.openCuriosScreen import ru.dbotthepony.mc.otm.core.math.integerDivisionDown import ru.dbotthepony.mc.otm.menu.ExopackInventoryMenu import ru.dbotthepony.mc.otm.network.ExopackMenuOpen -import ru.dbotthepony.mc.otm.network.MatteryPlayerNetworkChannel import yalter.mousetweaks.api.MouseTweaksDisableWheelTweak @MouseTweaksDisableWheelTweak @@ -295,7 +295,7 @@ class ExopackInventoryScreen(menu: ExopackInventoryMenu) : MatteryScreen(menu: T, inventory: Inventory, tit panels.asReversed().any { it.updateCursor1() } RenderSystem.depthFunc(GL11.GL_LESS) - MinecraftForge.EVENT_BUS.post(Background(this, graphics, mouseX, mouseY)) + NeoForge.EVENT_BUS.post(ContainerScreenEvent.Render.Background(this, graphics, mouseX, mouseY)) RenderSystem.disableDepthTest() // Screen.super.render @@ -690,7 +689,7 @@ abstract class MatteryScreen(menu: T, inventory: Inventory, tit // /Screen.super.render RenderSystem.disableDepthTest() - MinecraftForge.EVENT_BUS.post(Foreground(this, graphics, mouseX, mouseY)) + NeoForge.EVENT_BUS.post(ContainerScreenEvent.Render.Foreground(this, graphics, mouseX, mouseY)) var itemstack = if (draggingItem.isEmpty) menu.carried else draggingItem diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/decorative/PainterScreen.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/decorative/PainterScreen.kt index dbec4100b..1c0dc1c2d 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/decorative/PainterScreen.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/decorative/PainterScreen.kt @@ -1,14 +1,14 @@ package ru.dbotthepony.mc.otm.client.screen.decorative import net.minecraft.ChatFormatting +import net.minecraft.core.registries.BuiltInRegistries import net.minecraft.network.chat.Component import net.minecraft.util.RandomSource import net.minecraft.world.entity.player.Inventory import net.minecraft.world.item.DyeColor import net.minecraft.world.item.ItemStack import net.minecraft.world.item.Items -import net.minecraftforge.common.Tags -import net.minecraftforge.registries.ForgeRegistries +import net.neoforged.neoforge.common.Tags import ru.dbotthepony.mc.otm.block.entity.decorative.PainterBlockEntity import ru.dbotthepony.mc.otm.client.render.MGUIGraphics import ru.dbotthepony.mc.otm.client.render.FlatRectangleIcon @@ -105,7 +105,7 @@ class PainterScreen(menu: PainterMenu, inventory: Inventory, title: Component) : it.dock = Dock.FILL it.dockResize = DockResizeMode.NONE it.slotBackgroundEmpty = - ItemStackIcon(ItemStack(ForgeRegistries.ITEMS.tags()!!.getTag(Tags.Items.DYES).getRandomElement(RandomSource.create()).orElse(Items.AIR)), 16f, 16f) + ItemStackIcon(ItemStack(BuiltInRegistries.ITEM.getOrCreateTag(Tags.Items.DYES).getRandomElement(menu.player.level().random).map { it.value() }.orElse(Items.AIR)), 16f, 16f) .fixed() .composeBefore(FlatRectangleIcon(16f, 16f, RGBAColor.rgb(0x8b8b8b).copy(alpha = 0.6f))) .fixed() diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/matter/MatterPanelScreen.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/matter/MatterPanelScreen.kt index 10a39519d..21f37ce0f 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/matter/MatterPanelScreen.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/matter/MatterPanelScreen.kt @@ -4,6 +4,7 @@ import net.minecraft.ChatFormatting import net.minecraft.network.chat.Component import net.minecraft.world.entity.player.Inventory import net.minecraft.world.item.ItemStack +import net.neoforged.neoforge.network.PacketDistributor import ru.dbotthepony.mc.otm.capability.matter.PatternState import ru.dbotthepony.mc.otm.capability.matter.ReplicationTask import ru.dbotthepony.mc.otm.client.render.MGUIGraphics @@ -30,7 +31,6 @@ import ru.dbotthepony.mc.otm.core.util.formatTickDuration import ru.dbotthepony.mc.otm.matter.MatterManager import ru.dbotthepony.mc.otm.menu.matter.MatterPanelMenu import ru.dbotthepony.mc.otm.menu.matter.ReplicationRequestPacket -import ru.dbotthepony.mc.otm.network.MenuNetworkChannel import yalter.mousetweaks.api.MouseTweaksDisableWheelTweak import java.util.function.Predicate import kotlin.math.ceil @@ -394,7 +394,7 @@ class MatterPanelScreen( } catch (_: NumberFormatException) { } - MenuNetworkChannel.sendToServer(ReplicationRequestPacket(pattern.id, count)) + PacketDistributor.sendToServer(ReplicationRequestPacket(pattern.id, count)) frame.remove() } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/ColorPicker.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/ColorPicker.kt index 63083b69e..76568231c 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/ColorPicker.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/ColorPicker.kt @@ -21,6 +21,7 @@ import ru.dbotthepony.mc.otm.client.screen.panels.input.TextInputPanel import ru.dbotthepony.mc.otm.core.TextComponent import ru.dbotthepony.mc.otm.core.TranslatableComponent import ru.dbotthepony.kommons.math.RGBAColor +import ru.dbotthepony.mc.otm.core.ResourceLocation import java.util.function.Consumer import java.util.function.Supplier import kotlin.math.roundToInt diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/EffectListPanel.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/EffectListPanel.kt index 40ae1f12d..4f4680962 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/EffectListPanel.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/EffectListPanel.kt @@ -4,6 +4,7 @@ import com.mojang.blaze3d.systems.RenderSystem import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap import it.unimi.dsi.fastutil.objects.Object2ObjectFunction import net.minecraft.client.gui.screens.Screen +import net.minecraft.core.Holder import net.minecraft.resources.ResourceLocation import net.minecraft.world.effect.MobEffect import net.minecraft.world.effect.MobEffectInstance @@ -15,6 +16,7 @@ import ru.dbotthepony.mc.otm.client.render.determineTooltipPosition import ru.dbotthepony.mc.otm.client.render.sprites.sprite import ru.dbotthepony.mc.otm.client.screen.panels.util.DiscreteScrollBarPanel import ru.dbotthepony.kommons.math.RGBAColor +import ru.dbotthepony.mc.otm.core.ResourceLocation import ru.dbotthepony.mc.otm.core.TranslatableComponent import ru.dbotthepony.mc.otm.core.util.formatTickDuration import ru.dbotthepony.mc.otm.core.math.integerDivisionDown @@ -73,7 +75,7 @@ open class EffectListPanel @JvmOverloads constructor( ) : EditablePanel(screen, this@EffectListPanel.canvas, x, y, width, height) { protected var lastInstance: MobEffectInstance = effect - val effectType: MobEffect = effect.effect + val effectType = effect.effect val effect: MobEffectInstance get() { val get = entity.activeEffectsMap[effectType] @@ -134,7 +136,7 @@ open class EffectListPanel @JvmOverloads constructor( width = renderWidth, height = renderHeight) - val name = effect.effect.displayName.copy() + val name = effect.effect.value().displayName.copy() if (effect.amplifier in 1 .. 9) { name.append(" ").append(TranslatableComponent("enchantment.level.${effect.amplifier + 1}")) @@ -150,7 +152,7 @@ open class EffectListPanel @JvmOverloads constructor( } } - protected val effectButtons: MutableMap = Object2ObjectArrayMap() + protected val effectButtons: MutableMap, EffectSquare> = Object2ObjectArrayMap() fun calculateMaxScroll(scrollBarPanel: DiscreteScrollBarPanel<*>): Int { return integerDivisionDown(entity.activeEffects.size, gridWidth) @@ -264,7 +266,7 @@ open class EffectListPanel @JvmOverloads constructor( } companion object { - val BAR = ResourceLocation("textures/gui/sprites/container/inventory/effect_background_large.png").sprite(0f, 0f, 120f, 32f, 120f, 32f) - val SQUARE_THIN = ResourceLocation("textures/gui/sprites/hud/effect_background.png").sprite(0f, 0f, 24f, 24f, 24f, 24f) + val BAR = ResourceLocation("minecraft", "textures/gui/sprites/container/inventory/effect_background_large.png").sprite(0f, 0f, 120f, 32f, 120f, 32f) + val SQUARE_THIN = ResourceLocation("minecraft", "textures/gui/sprites/hud/effect_background.png").sprite(0f, 0f, 24f, 24f, 24f, 24f) } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/EntityRendererPanel.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/EntityRendererPanel.kt index 86dac7021..9811a3056 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/EntityRendererPanel.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/EntityRendererPanel.kt @@ -5,7 +5,8 @@ import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen import net.minecraft.client.gui.screens.inventory.InventoryScreen import net.minecraft.world.entity.LivingEntity import net.minecraft.world.entity.player.Player -import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability +import net.neoforged.neoforge.network.PacketDistributor +import ru.dbotthepony.mc.otm.capability.MatteryPlayer import ru.dbotthepony.mc.otm.capability.matteryPlayer import ru.dbotthepony.mc.otm.client.render.MGUIGraphics import ru.dbotthepony.mc.otm.client.render.Widgets8 @@ -25,7 +26,6 @@ import ru.dbotthepony.mc.otm.network.DisableExopackGlowPacket import ru.dbotthepony.mc.otm.network.DisplayExopackPacket import ru.dbotthepony.mc.otm.network.EnableExopackGlowPacket import ru.dbotthepony.mc.otm.network.HideExopackPacket -import ru.dbotthepony.mc.otm.network.MatteryPlayerNetworkChannel import ru.dbotthepony.mc.otm.network.ResetExopackColorPacket import ru.dbotthepony.mc.otm.network.SetExopackColorPacket import java.util.function.IntConsumer @@ -44,7 +44,7 @@ private fun calculateScale(width: Float, height: Float): Int { } } -private fun createExopackAppearanceWindow(screen: MatteryScreen<*>, matteryPlayer: MatteryPlayerCapability): FramePanel<*> { +private fun createExopackAppearanceWindow(screen: MatteryScreen<*>, matteryPlayer: MatteryPlayer): FramePanel<*> { val frame = FramePanel.padded(screen, width = 200f, height = 90f, title = TranslatableComponent("otm.gui.exopack.customization")) screen.addPanel(frame) @@ -63,9 +63,9 @@ private fun createExopackAppearanceWindow(screen: MatteryScreen<*>, matteryPlaye }, { if (it) { - MatteryPlayerNetworkChannel.sendToServer(DisplayExopackPacket) + PacketDistributor.sendToServer(DisplayExopackPacket) } else { - MatteryPlayerNetworkChannel.sendToServer(HideExopackPacket) + PacketDistributor.sendToServer(HideExopackPacket) } } ) @@ -84,9 +84,9 @@ private fun createExopackAppearanceWindow(screen: MatteryScreen<*>, matteryPlaye }, { if (it) { - MatteryPlayerNetworkChannel.sendToServer(EnableExopackGlowPacket) + PacketDistributor.sendToServer(EnableExopackGlowPacket) } else { - MatteryPlayerNetworkChannel.sendToServer(DisableExopackGlowPacket) + PacketDistributor.sendToServer(DisableExopackGlowPacket) } } ) @@ -98,7 +98,7 @@ private fun createExopackAppearanceWindow(screen: MatteryScreen<*>, matteryPlaye ButtonPanel(screen, frame, label = TranslatableComponent("otm.gui.exopack.change_color"), onPress = IntConsumer { frame.blockingWindow = ColorPickerPanel.frame( screen, - callback = { MatteryPlayerNetworkChannel.sendToServer(SetExopackColorPacket(it)) }, + callback = { PacketDistributor.sendToServer(SetExopackColorPacket(it)) }, color = matteryPlayer.exopackColor ?: RGBAColor.WHITE, title = TranslatableComponent("otm.gui.exopack.change_color")) }).also { @@ -106,7 +106,7 @@ private fun createExopackAppearanceWindow(screen: MatteryScreen<*>, matteryPlaye it.dockTop = 2f } - ButtonPanel(screen, frame, label = TranslatableComponent("otm.gui.exopack.change_color2"), onPress = IntConsumer { MatteryPlayerNetworkChannel.sendToServer(ResetExopackColorPacket) }).also { + ButtonPanel(screen, frame, label = TranslatableComponent("otm.gui.exopack.change_color2"), onPress = IntConsumer { PacketDistributor.sendToServer(ResetExopackColorPacket) }).also { it.dock = Dock.TOP it.dockTop = 2f } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/input/TextInputPanel.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/input/TextInputPanel.kt index 929ce3368..474c14dbd 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/input/TextInputPanel.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/input/TextInputPanel.kt @@ -2,6 +2,7 @@ package ru.dbotthepony.mc.otm.client.screen.panels.input import com.mojang.blaze3d.platform.InputConstants import com.mojang.blaze3d.systems.RenderSystem +import com.mojang.blaze3d.vertex.BufferUploader import com.mojang.blaze3d.vertex.DefaultVertexFormat import com.mojang.blaze3d.vertex.VertexFormat import it.unimi.dsi.fastutil.chars.Char2IntFunction @@ -29,6 +30,7 @@ import ru.dbotthepony.mc.otm.core.addAll import ru.dbotthepony.mc.otm.core.collect.map import ru.dbotthepony.mc.otm.core.collect.reduce import ru.dbotthepony.kommons.math.RGBAColor +import ru.dbotthepony.mc.otm.client.render.vertex import ru.dbotthepony.mc.otm.milliTime import java.util.function.Predicate import kotlin.math.roundToInt @@ -1204,16 +1206,14 @@ open class TextInputPanel( RenderSystem.defaultBlendFunc() RenderSystem.enableBlend() - val builder = tesselator.builder + val builder = tesselator.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION) - builder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION) + builder.vertex(stack.last().pose(), x, y + font.lineHeight + rowSpacing, 0f) + builder.vertex(stack.last().pose(), x + width, y + font.lineHeight + rowSpacing, 0f) + builder.vertex(stack.last().pose(), x + width, y, 0f) + builder.vertex(stack.last().pose(), x, y, 0f) - builder.vertex(stack.last().pose(), x, y + font.lineHeight + rowSpacing, 0f).endVertex() - builder.vertex(stack.last().pose(), x + width, y + font.lineHeight + rowSpacing, 0f).endVertex() - builder.vertex(stack.last().pose(), x + width, y, 0f).endVertex() - builder.vertex(stack.last().pose(), x, y, 0f).endVertex() - - tesselator.end() + BufferUploader.drawWithShader(builder.buildOrThrow()) RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f) //RenderSystem.disableColorLogicOp() diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/slot/AbstractSlotPanel.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/slot/AbstractSlotPanel.kt index e31357af2..ce1f04d26 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/slot/AbstractSlotPanel.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/slot/AbstractSlotPanel.kt @@ -5,7 +5,7 @@ import net.minecraft.client.gui.screens.Screen.getTooltipFromItem import net.minecraft.client.renderer.GameRenderer import net.minecraft.network.chat.Component import net.minecraft.world.item.ItemStack -import net.minecraftforge.client.extensions.common.IClientItemExtensions +import net.neoforged.neoforge.client.extensions.common.IClientItemExtensions import ru.dbotthepony.mc.otm.client.render.IGUIRenderable import ru.dbotthepony.mc.otm.client.render.MGUIGraphics import ru.dbotthepony.mc.otm.client.render.WidgetLocation diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/slot/UserFilteredSlotPanel.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/slot/UserFilteredSlotPanel.kt index d36d53db7..9130dd5f5 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/slot/UserFilteredSlotPanel.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/slot/UserFilteredSlotPanel.kt @@ -7,7 +7,7 @@ import net.minecraft.world.inventory.Slot import net.minecraft.world.item.Item import net.minecraft.world.item.ItemStack import net.minecraft.world.item.Items -import net.minecraftforge.client.extensions.common.IClientItemExtensions +import net.neoforged.neoforge.client.extensions.common.IClientItemExtensions import ru.dbotthepony.mc.otm.client.render.MGUIGraphics import ru.dbotthepony.mc.otm.client.isCtrlDown import ru.dbotthepony.mc.otm.client.minecraft diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/util/ScrollBarConstants.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/util/ScrollBarConstants.kt index 5309d2144..b079bdbc1 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/util/ScrollBarConstants.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/util/ScrollBarConstants.kt @@ -4,6 +4,7 @@ import net.minecraft.resources.ResourceLocation import ru.dbotthepony.mc.otm.OverdriveThatMatters import ru.dbotthepony.mc.otm.client.render.sprites.MatteryAtlas import ru.dbotthepony.mc.otm.client.render.sprites.sprite +import ru.dbotthepony.mc.otm.core.ResourceLocation object ScrollBarConstants { const val WIDTH = 14f diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/tech/AndroidStationScreen.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/tech/AndroidStationScreen.kt index 387ef43af..7adcf7fd6 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/tech/AndroidStationScreen.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/tech/AndroidStationScreen.kt @@ -9,11 +9,12 @@ import net.minecraft.client.Minecraft import net.minecraft.network.chat.Component import net.minecraft.world.entity.player.Inventory import net.minecraft.world.item.ItemStack +import net.neoforged.neoforge.network.PacketDistributor import ru.dbotthepony.mc.otm.core.TranslatableComponent import ru.dbotthepony.mc.otm.android.AndroidResearch import ru.dbotthepony.mc.otm.android.AndroidResearchManager import ru.dbotthepony.mc.otm.android.AndroidResearchType -import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability +import ru.dbotthepony.mc.otm.capability.MatteryPlayer import ru.dbotthepony.mc.otm.capability.MatteryCapability import ru.dbotthepony.mc.otm.client.CursorType import ru.dbotthepony.mc.otm.client.render.MGUIGraphics @@ -32,9 +33,8 @@ import ru.dbotthepony.mc.otm.client.screen.panels.util.DraggableCanvasPanel import ru.dbotthepony.mc.otm.client.screen.widget.WideProfiledPowerGaugePanel import ru.dbotthepony.mc.otm.config.MachinesConfig import ru.dbotthepony.kommons.math.RGBAColor -import ru.dbotthepony.mc.otm.core.ifPresentK +import ru.dbotthepony.mc.otm.capability.matteryPlayer import ru.dbotthepony.mc.otm.menu.tech.AndroidStationMenu -import ru.dbotthepony.mc.otm.network.MatteryPlayerNetworkChannel import ru.dbotthepony.mc.otm.network.AndroidResearchRequestPacket import java.util.* import kotlin.collections.ArrayList @@ -163,7 +163,7 @@ private class Tree(val node: AndroidResearchType) : Iterable { fun put( rows: Int2ObjectFunction>, left: Float, - capability: MatteryPlayerCapability + capability: MatteryPlayer ): Pair { val totalWidth = width * 24f @@ -395,13 +395,13 @@ private class AndroidResearchButton( *node.type.flatBlocking.map { it.displayName }.toTypedArray() ), onConfirm = { - MatteryPlayerNetworkChannel.sendToServer(AndroidResearchRequestPacket(node.type)) + PacketDistributor.sendToServer(AndroidResearchRequestPacket(node.type)) } ) playGuiClickSound() } else { - MatteryPlayerNetworkChannel.sendToServer(AndroidResearchRequestPacket(node.type)) + PacketDistributor.sendToServer(AndroidResearchRequestPacket(node.type)) playGuiClickSound() } } @@ -535,7 +535,7 @@ class AndroidStationScreen constructor(p_97741_: AndroidStationMenu, p_97742_: I } } - minecraft?.player?.getCapability(MatteryCapability.MATTERY_PLAYER)?.ifPresentK { + minecraft?.player?.matteryPlayer?.let { var totalWidth = 0f for (graph in findGraphs()) { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/tech/EssenceStorageScreen.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/tech/EssenceStorageScreen.kt index 970f19148..3f92975fd 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/tech/EssenceStorageScreen.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/tech/EssenceStorageScreen.kt @@ -23,6 +23,7 @@ import ru.dbotthepony.mc.otm.client.screen.panels.button.makeDeviceControls import ru.dbotthepony.mc.otm.client.screen.panels.input.TextInputPanel import ru.dbotthepony.mc.otm.client.screen.panels.slot.SlotPanel import ru.dbotthepony.mc.otm.client.screen.panels.util.HorizontalStripPanel +import ru.dbotthepony.mc.otm.core.ResourceLocation import ru.dbotthepony.mc.otm.core.TextComponent import ru.dbotthepony.mc.otm.core.TranslatableComponent import ru.dbotthepony.mc.otm.core.util.getLevelFromXp diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/widget/FluidGaugePanel.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/widget/FluidGaugePanel.kt index 0a3f10eee..12cf5c213 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/widget/FluidGaugePanel.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/widget/FluidGaugePanel.kt @@ -1,28 +1,31 @@ package ru.dbotthepony.mc.otm.client.screen.widget import com.mojang.blaze3d.systems.RenderSystem +import com.mojang.blaze3d.vertex.BufferUploader import com.mojang.blaze3d.vertex.DefaultVertexFormat import com.mojang.blaze3d.vertex.VertexFormat import net.minecraft.ChatFormatting import net.minecraft.client.gui.screens.Screen import net.minecraft.client.renderer.GameRenderer import net.minecraft.network.chat.Component -import net.minecraft.resources.ResourceLocation import net.minecraft.world.inventory.InventoryMenu -import net.minecraftforge.client.extensions.common.IClientFluidTypeExtensions -import net.minecraftforge.fml.ModList +import net.neoforged.fml.ModList +import net.neoforged.neoforge.client.extensions.common.IClientFluidTypeExtensions import org.lwjgl.opengl.GL11 +import ru.dbotthepony.kommons.math.RGBAColor import ru.dbotthepony.mc.otm.OverdriveThatMatters import ru.dbotthepony.mc.otm.client.ShiftPressedCond import ru.dbotthepony.mc.otm.client.minecraft import ru.dbotthepony.mc.otm.client.render.MGUIGraphics import ru.dbotthepony.mc.otm.client.render.sprites.MatterySprite import ru.dbotthepony.mc.otm.client.render.tesselator +import ru.dbotthepony.mc.otm.client.render.uv +import ru.dbotthepony.mc.otm.client.render.vertex import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel +import ru.dbotthepony.mc.otm.core.ResourceLocation import ru.dbotthepony.mc.otm.core.TextComponent import ru.dbotthepony.mc.otm.core.TranslatableComponent import ru.dbotthepony.mc.otm.core.isNotEmpty -import ru.dbotthepony.kommons.math.RGBAColor import ru.dbotthepony.mc.otm.core.math.linearInterpolation import ru.dbotthepony.mc.otm.core.registryName import ru.dbotthepony.mc.otm.core.util.formatFluidLevel @@ -71,9 +74,7 @@ open class FluidGaugePanel( var bottom = this.height val matrix = graphics.pose.last().pose() - val builder = tesselator.builder - - builder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX) + val builder = tesselator.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX) while (height > 0.01f) { val thisHeight = height.coerceAtMost(1f) @@ -82,10 +83,10 @@ open class FluidGaugePanel( val interp = linearInterpolation(thisHeight, sprite.v1, sprite.v0) - builder.vertex(matrix, 0f, bottom, 0f).uv(sprite.u0, sprite.v1).endVertex() - builder.vertex(matrix, width, bottom, 0f).uv(sprite.u1, sprite.v1).endVertex() - builder.vertex(matrix, width, bottom - actualHeight, 0f).uv(sprite.u1, interp).endVertex() - builder.vertex(matrix, 0f, bottom - actualHeight, 0f).uv(sprite.u0, interp).endVertex() + builder.vertex(matrix, 0f, bottom, 0f).uv(sprite.u0, sprite.v1) + builder.vertex(matrix, width, bottom, 0f).uv(sprite.u1, sprite.v1) + builder.vertex(matrix, width, bottom - actualHeight, 0f).uv(sprite.u1, interp) + builder.vertex(matrix, 0f, bottom - actualHeight, 0f).uv(sprite.u0, interp) bottom -= actualHeight } @@ -98,7 +99,7 @@ open class FluidGaugePanel( RenderSystem.setShaderColor(tint.red, tint.green, tint.blue, tint.alpha) RenderSystem.setShaderTexture(0, sprite.atlasLocation()) - tesselator.end() + BufferUploader.drawWithShader(builder.buildOrThrow()) RenderSystem.setShaderColor(1f, 1f, 1f, 1f) RenderSystem.depthFunc(GL11.GL_LESS) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/widget/MatterGaugePanel.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/widget/MatterGaugePanel.kt index cd05ee603..973ef7d45 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/widget/MatterGaugePanel.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/widget/MatterGaugePanel.kt @@ -18,6 +18,8 @@ import ru.dbotthepony.mc.otm.client.isShiftDown import ru.dbotthepony.mc.otm.client.minecraft import ru.dbotthepony.mc.otm.client.render.WidgetLocation import ru.dbotthepony.mc.otm.client.render.tesselator +import ru.dbotthepony.mc.otm.client.render.uv +import ru.dbotthepony.mc.otm.client.render.vertex import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel import ru.dbotthepony.mc.otm.core.TextComponent import ru.dbotthepony.mc.otm.core.TranslatableComponent @@ -111,12 +113,10 @@ open class MatterGaugePanel @JvmOverloads constructor( val v1 = GAUGE_FOREGROUND.v1 val matrix = graphics.pose.last().pose() - val builder = tesselator.builder + val builder = tesselator.begin(VertexFormat.Mode.TRIANGLE_FAN, DefaultVertexFormat.POSITION_TEX) - builder.begin(VertexFormat.Mode.TRIANGLE_FAN, DefaultVertexFormat.POSITION_TEX) - - builder.vertex(matrix, 0f, height, 0f).uv(u0, v1).endVertex() - builder.vertex(matrix, width, height, 0f).uv(u1, v1).endVertex() + builder.vertex(matrix, 0f, height, 0f).uv(u0, v1) + builder.vertex(matrix, width, height, 0f).uv(u1, v1) for (i in 4 downTo 0) { val sin = sin((System.currentTimeMillis() / 50L + i * 2L).toDouble() / 4.0).toFloat() * wavesStrength.coerceAtMost(4f) @@ -128,10 +128,10 @@ open class MatterGaugePanel @JvmOverloads constructor( builder.vertex(matrix, thisX, thisY, 0f).uv( GAUGE_FOREGROUND.partialU((i / 4f) * GAUGE_FOREGROUND.width), GAUGE_FOREGROUND.partialV(thisY), - ).endVertex() + ) } - BufferUploader.drawWithShader(builder.end()) + BufferUploader.drawWithShader(builder.buildOrThrow()) graphics.pose.popPose() } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/compat/adastra/AdAstraCompat.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/compat/adastra/AdAstraCompat.kt deleted file mode 100644 index b29c3359e..000000000 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/compat/adastra/AdAstraCompat.kt +++ /dev/null @@ -1,58 +0,0 @@ -package ru.dbotthepony.mc.otm.compat.adastra - -import earth.terrarium.ad_astra.AdAstra -import earth.terrarium.ad_astra.common.data.Planet -import earth.terrarium.ad_astra.common.data.PlanetData -import earth.terrarium.ad_astra.common.item.armor.SpaceSuit -import earth.terrarium.ad_astra.common.registry.ModDamageSources -import net.minecraft.world.entity.player.Player -import net.minecraftforge.event.entity.living.LivingHurtEvent -import net.minecraftforge.fml.ModList -import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability -import ru.dbotthepony.mc.otm.capability.matteryPlayer -import ru.dbotthepony.mc.otm.config.ServerCompatConfig -import ru.dbotthepony.mc.otm.core.damageType -import ru.dbotthepony.mc.otm.registry.MDamageTypes -import ru.dbotthepony.mc.otm.registry.MItems -import ru.dbotthepony.mc.otm.registry.MatteryDamageSource - -val isAdAstraLoaded by lazy { - ModList.get().isLoaded(AdAstra.MOD_ID) -} - -// для надёжности -fun onDamageEvent(event: LivingHurtEvent) { - check(isAdAstraLoaded) { "Ad Astra is not loaded!" } - val ply = event.entity as? Player ?: return - - if (ServerCompatConfig.AdAstra.ANDROIDS_DO_NOT_NEED_OXYGEN) { - if (ply.matteryPlayer?.isAndroid != true) return - - if (event.source.`is`(ModDamageSources.OXYGEN)) { - event.amount = 0f - event.isCanceled = true - } - } -} - -fun onMatteryTick(event: MatteryPlayerCapability.PostTick) { - check(isAdAstraLoaded) { "Ad Astra is not loaded!" } - - if ( - ServerCompatConfig.AdAstra.ANDROID_COSMIC_RAYS && - !event.player.abilities.invulnerable && - event.capability.isAndroid && - !PlanetData.getPlanetFromLevel(event.level.dimension()).map(Planet::hasAtmosphere).orElse(true) - ) { - val rand = event.level.random - - val noSpacesuits = event.player.armorSlots.count { it.item !is SpaceSuit } - val yesTritanium0 = if (!ServerCompatConfig.AdAstra.TRITANIUM_ARMOR_PROTECTS_AGAINST_COSMIC_RAYS) 0.0 else event.player.armorSlots.count { it.item in MItems.TRITANIUM_ARMOR } * 0.75 - val yesTritanium1 = if (!ServerCompatConfig.AdAstra.TRITANIUM_ARMOR_PROTECTS_AGAINST_COSMIC_RAYS) 0.0 else event.player.armorSlots.count { it.item in MItems.SIMPLE_TRITANIUM_ARMOR } * 0.2 - val yesTritanium = yesTritanium0 + yesTritanium1 - - if (rand.nextDouble() <= (noSpacesuits - yesTritanium) * ServerCompatConfig.AdAstra.ANDROID_COSMIC_RAYS_CHANCE) { - event.player.hurt(MatteryDamageSource(event.level.registryAccess().damageType(MDamageTypes.COSMIC_RAYS)), 1f) - } - } -} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/compat/cos/CosmeticArmorCompat.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/compat/cos/CosmeticArmorCompat.kt index 9ad73c8cd..40146f476 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/compat/cos/CosmeticArmorCompat.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/compat/cos/CosmeticArmorCompat.kt @@ -15,6 +15,7 @@ import net.minecraft.world.inventory.InventoryMenu import net.minecraft.world.inventory.Slot import net.minecraft.world.item.ItemStack import net.minecraftforge.fml.ModList +import net.neoforged.fml.ModList import ru.dbotthepony.mc.otm.client.render.MGUIGraphics import ru.dbotthepony.mc.otm.client.minecraft import ru.dbotthepony.mc.otm.client.render.sprites.MatterySprite diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jade/providers/MatterStorageProvider.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jade/providers/MatterStorageProvider.kt index e56319174..21c6c37ea 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jade/providers/MatterStorageProvider.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jade/providers/MatterStorageProvider.kt @@ -10,7 +10,6 @@ import ru.dbotthepony.mc.otm.compat.jade.JadeColors import ru.dbotthepony.mc.otm.compat.jade.JadeTagKeys import ru.dbotthepony.mc.otm.compat.jade.JadeUids import ru.dbotthepony.mc.otm.core.TranslatableComponent -import ru.dbotthepony.mc.otm.core.ifPresentK import ru.dbotthepony.mc.otm.core.math.Decimal import ru.dbotthepony.kommons.math.RGBAColor import ru.dbotthepony.mc.otm.core.math.getDecimal diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jade/providers/MatteryWorkerProvider.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jade/providers/MatteryWorkerProvider.kt index b13359070..41b80264f 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jade/providers/MatteryWorkerProvider.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jade/providers/MatteryWorkerProvider.kt @@ -9,7 +9,6 @@ import ru.dbotthepony.mc.otm.compat.jade.JadeTagKeys import ru.dbotthepony.mc.otm.compat.jade.JadeUids import ru.dbotthepony.kommons.math.RGBAColor import ru.dbotthepony.mc.otm.core.nbt.getCompoundList -import ru.dbotthepony.mc.otm.core.nbt.getItemStack import ru.dbotthepony.mc.otm.core.nbt.set import snownee.jade.api.BlockAccessor import snownee.jade.api.IBlockComponentProvider diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jei/MicrowaveRecipeCategory.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jei/MicrowaveRecipeCategory.kt index 74e5f6872..6cd4b88c7 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jei/MicrowaveRecipeCategory.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jei/MicrowaveRecipeCategory.kt @@ -19,6 +19,7 @@ import ru.dbotthepony.mc.otm.client.render.RenderGravity import ru.dbotthepony.mc.otm.client.screen.panels.slot.AbstractSlotPanel import ru.dbotthepony.mc.otm.client.screen.widget.ProgressGaugePanel import ru.dbotthepony.kommons.math.RGBAColor +import ru.dbotthepony.mc.otm.core.ResourceLocation import ru.dbotthepony.mc.otm.core.TranslatableComponent import ru.dbotthepony.mc.otm.core.registryName import ru.dbotthepony.mc.otm.recipe.MicrowaveRecipe diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jei/PainterRecipeCategory.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jei/PainterRecipeCategory.kt index 50bb55cea..98213c09a 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jei/PainterRecipeCategory.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jei/PainterRecipeCategory.kt @@ -18,6 +18,7 @@ import ru.dbotthepony.mc.otm.client.render.MGUIGraphics import ru.dbotthepony.mc.otm.client.render.ItemStackIcon import ru.dbotthepony.mc.otm.client.screen.panels.slot.AbstractSlotPanel import ru.dbotthepony.mc.otm.client.screen.widget.ProgressGaugePanel +import ru.dbotthepony.mc.otm.core.ResourceLocation import ru.dbotthepony.mc.otm.recipe.PainterRecipe import ru.dbotthepony.mc.otm.registry.MItems import ru.dbotthepony.mc.otm.registry.MNames diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jei/PlatePressRecipeCategory.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jei/PlatePressRecipeCategory.kt index 5b6759e34..32613840e 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jei/PlatePressRecipeCategory.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jei/PlatePressRecipeCategory.kt @@ -19,6 +19,7 @@ import ru.dbotthepony.mc.otm.client.render.RenderGravity import ru.dbotthepony.mc.otm.client.screen.panels.slot.AbstractSlotPanel import ru.dbotthepony.mc.otm.client.screen.widget.ProgressGaugePanel import ru.dbotthepony.kommons.math.RGBAColor +import ru.dbotthepony.mc.otm.core.ResourceLocation import ru.dbotthepony.mc.otm.core.TranslatableComponent import ru.dbotthepony.mc.otm.core.registryName import ru.dbotthepony.mc.otm.recipe.PlatePressRecipe diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/compat/vanilla/ExtendedInventoryHandler.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/compat/vanilla/ExtendedInventoryHandler.kt index 910a6933f..e5bb727c2 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/compat/vanilla/ExtendedInventoryHandler.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/compat/vanilla/ExtendedInventoryHandler.kt @@ -6,6 +6,8 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectFunction import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap import it.unimi.dsi.fastutil.objects.ReferenceArraySet import net.minecraft.network.FriendlyByteBuf +import net.minecraft.network.codec.StreamCodec +import net.minecraft.network.protocol.common.custom.CustomPacketPayload import net.minecraft.world.SimpleContainer import net.minecraft.world.entity.player.Player import net.minecraft.world.inventory.AbstractContainerMenu @@ -13,13 +15,14 @@ import net.minecraft.world.inventory.InventoryMenu import net.minecraft.world.inventory.Slot import net.minecraft.world.item.ItemStack import net.minecraft.world.item.Items +import net.neoforged.neoforge.network.handling.IPayloadContext import org.apache.logging.log4j.LogManager -import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability +import ru.dbotthepony.mc.otm.OverdriveThatMatters +import ru.dbotthepony.mc.otm.capability.MatteryPlayer import ru.dbotthepony.mc.otm.capability.matteryPlayer +import ru.dbotthepony.mc.otm.core.ResourceLocation import ru.dbotthepony.mc.otm.menu.MatteryMenu import ru.dbotthepony.mc.otm.menu.MatterySlot -import ru.dbotthepony.mc.otm.network.MNetworkContext -import ru.dbotthepony.mc.otm.network.MatteryPacket import java.util.* private val menuConfigurations = WeakHashMap() @@ -38,7 +41,7 @@ private class MenuConfiguration( private val rows = Int2ObjectOpenHashMap>() val isIncomplete: Boolean - private fun getRow(index: Int, matteryPlayer: MatteryPlayerCapability) = rows.computeIfAbsent(index, Int2ObjectFunction { + private fun getRow(index: Int, matteryPlayer: MatteryPlayer) = rows.computeIfAbsent(index, Int2ObjectFunction { val row = ArrayList(9) val offset = (it - 3) * 9 @@ -197,8 +200,8 @@ private class FakeSlot : MatterySlot(SimpleContainer(1), 0, 0, 0) { } } -class InventoryScrollPacket(val scroll: Int) : MatteryPacket { - override fun write(buff: FriendlyByteBuf) { +class InventoryScrollPacket(val scroll: Int) : CustomPacketPayload { + fun write(buff: FriendlyByteBuf) { buff.writeVarInt(scroll) } @@ -223,11 +226,25 @@ class InventoryScrollPacket(val scroll: Int) : MatteryPacket { }.scroll = scroll } - override fun play(context: MNetworkContext) { - play(context.sender ?: throw IllegalStateException("Illegal side")) + fun play(context: IPayloadContext) { + play(context.player()) + } + + override fun type(): CustomPacketPayload.Type { + return TYPE } companion object { + val TYPE = CustomPacketPayload.Type( + ResourceLocation( + OverdriveThatMatters.MOD_ID, + "inventory_scroll" + ) + ) + + val CODEC: StreamCodec = + StreamCodec.ofMember(InventoryScrollPacket::write, ::read) + fun read(buff: FriendlyByteBuf): InventoryScrollPacket { return InventoryScrollPacket(buff.readVarInt()) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/compat/vanilla/MatteryChestMenu.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/compat/vanilla/MatteryChestMenu.kt index 446cb3fb3..d5ef52363 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/compat/vanilla/MatteryChestMenu.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/compat/vanilla/MatteryChestMenu.kt @@ -1,6 +1,5 @@ package ru.dbotthepony.mc.otm.compat.vanilla -import net.minecraft.client.gui.screens.MenuScreens import net.minecraft.core.registries.Registries import net.minecraft.world.Container import net.minecraft.world.SimpleContainer @@ -8,15 +7,13 @@ import net.minecraft.world.entity.player.Inventory import net.minecraft.world.entity.player.Player import net.minecraft.world.flag.FeatureFlags import net.minecraft.world.inventory.MenuType -import net.minecraftforge.eventbus.api.IEventBus -import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent -import net.minecraftforge.registries.DeferredRegister -import ru.dbotthepony.kommons.util.getValue +import net.neoforged.bus.api.IEventBus +import net.neoforged.neoforge.client.event.RegisterMenuScreensEvent import ru.dbotthepony.mc.otm.OverdriveThatMatters -import ru.dbotthepony.mc.otm.core.getValue import ru.dbotthepony.mc.otm.menu.MatteryMenu import ru.dbotthepony.mc.otm.menu.MatterySlot import ru.dbotthepony.mc.otm.menu.makeSlots +import ru.dbotthepony.mc.otm.registry.MDeferredRegister class MatteryChestMenu( type: MenuType<*>, containerId: Int, @@ -43,7 +40,7 @@ class MatteryChestMenu( } companion object { - private val registrar = DeferredRegister.create(Registries.MENU, OverdriveThatMatters.MOD_ID) + private val registrar = MDeferredRegister(Registries.MENU, OverdriveThatMatters.MOD_ID) private val GENERIC_9x1 by registrar.register("generic_9x1") { MenuType(::c9x1, FeatureFlags.VANILLA_SET) } private val GENERIC_9x2 by registrar.register("generic_9x2") { MenuType(::c9x2, FeatureFlags.VANILLA_SET) } @@ -102,22 +99,20 @@ class MatteryChestMenu( return MatteryChestMenu(HOPPER, containerId, inventory, 1, 5, container) } - internal fun register(bus: IEventBus) { + fun register(bus: IEventBus) { registrar.register(bus) - bus.addListener(this::registerClient) + bus.addListener(this::registerScreens) } - private fun registerClient(event: FMLClientSetupEvent) { - event.enqueueWork { - MenuScreens.register(GENERIC_9x1, ::MatteryChestScreen) - MenuScreens.register(GENERIC_9x2, ::MatteryChestScreen) - MenuScreens.register(GENERIC_9x3, ::MatteryChestScreen) - MenuScreens.register(GENERIC_9x4, ::MatteryChestScreen) - MenuScreens.register(GENERIC_9x5, ::MatteryChestScreen) - MenuScreens.register(GENERIC_9x6, ::MatteryChestScreen) - MenuScreens.register(GENERIC_3x3, ::MatteryChestScreen) - MenuScreens.register(HOPPER, ::MatteryChestScreen) - } + private fun registerScreens(event: RegisterMenuScreensEvent) { + event.register(GENERIC_9x1, ::MatteryChestScreen) + event.register(GENERIC_9x2, ::MatteryChestScreen) + event.register(GENERIC_9x3, ::MatteryChestScreen) + event.register(GENERIC_9x4, ::MatteryChestScreen) + event.register(GENERIC_9x5, ::MatteryChestScreen) + event.register(GENERIC_9x6, ::MatteryChestScreen) + event.register(GENERIC_3x3, ::MatteryChestScreen) + event.register(HOPPER, ::MatteryChestScreen) } } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/config/AbstractConfig.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/config/AbstractConfig.kt index d56270c19..98e7277eb 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/config/AbstractConfig.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/config/AbstractConfig.kt @@ -1,19 +1,18 @@ package ru.dbotthepony.mc.otm.config -import net.minecraftforge.common.ForgeConfigSpec -import net.minecraftforge.fml.ModLoadingContext -import net.minecraftforge.fml.config.ModConfig +import net.neoforged.fml.ModContainer +import net.neoforged.fml.config.ModConfig +import net.neoforged.neoforge.common.ModConfigSpec import ru.dbotthepony.kommons.util.Delegate import ru.dbotthepony.kommons.util.getValue import ru.dbotthepony.mc.otm.OverdriveThatMatters -import ru.dbotthepony.mc.otm.core.getValue import ru.dbotthepony.mc.otm.core.math.Decimal import ru.dbotthepony.mc.otm.core.math.defineDecimal import ru.dbotthepony.mc.otm.core.util.WriteOnce abstract class AbstractConfig(private val configName: String, private val type: ModConfig.Type = ModConfig.Type.SERVER) { - private var spec: ForgeConfigSpec by WriteOnce() - protected val builder = ForgeConfigSpec.Builder() + private var spec: ModConfigSpec by WriteOnce() + protected val builder = ModConfigSpec.Builder() private var registered = false fun batteryValues(name: String, storage: Decimal, receive: Decimal, extract: Decimal = receive, initialBatteryLevel: Decimal = Decimal.ZERO): BatteryBalanceValues { @@ -31,7 +30,7 @@ abstract class AbstractConfig(private val configName: String, private val type: return obj } - fun conciseValues(name: String, storage: Decimal, throughput: Decimal, configurator: ForgeConfigSpec.Builder.() -> Unit = {}): EnergyBalanceValues { + fun conciseValues(name: String, storage: Decimal, throughput: Decimal, configurator: ModConfigSpec.Builder.() -> Unit = {}): EnergyBalanceValues { builder.push(name) val obj = object : EnergyBalanceValues { @@ -53,7 +52,7 @@ abstract class AbstractConfig(private val configName: String, private val type: energyConsumption: Decimal?, matterCapacity: Decimal? = null, maxExperience: Double? = null, - configurator: ForgeConfigSpec.Builder.() -> Unit = {} + configurator: ModConfigSpec.Builder.() -> Unit = {} ): WorkerBalanceValues { builder.push(name) @@ -72,10 +71,10 @@ abstract class AbstractConfig(private val configName: String, private val type: return obj } - fun register() { + fun register(container: ModContainer) { check(!registered) { "Already registered config" } registered = true spec = builder.build() - ModLoadingContext.get().registerConfig(type, spec, "${OverdriveThatMatters.MOD_ID}-$configName.toml") + container.registerConfig(type, spec, "${OverdriveThatMatters.MOD_ID}-$configName.toml") } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/config/ConfigExt.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/config/ConfigExt.kt index 9febd526a..245d92661 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/config/ConfigExt.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/config/ConfigExt.kt @@ -1,20 +1,20 @@ package ru.dbotthepony.mc.otm.config -import net.minecraftforge.common.ForgeConfigSpec +import net.neoforged.neoforge.common.ModConfigSpec import kotlin.reflect.KProperty -operator fun ForgeConfigSpec.ConfigValue.setValue(config: Any, property: KProperty<*>, value: T) { +operator fun ModConfigSpec.ConfigValue.setValue(config: Any, property: KProperty<*>, value: T) { set(value) } -operator fun ForgeConfigSpec.ConfigValue.getValue(config: Any, property: KProperty<*>): T { +operator fun ModConfigSpec.ConfigValue.getValue(config: Any, property: KProperty<*>): T { return get() } -fun ForgeConfigSpec.Builder.defineInRange(path: String, value: Int, minValue: Int): ForgeConfigSpec.IntValue { +fun ModConfigSpec.Builder.defineInRange(path: String, value: Int, minValue: Int): ModConfigSpec.IntValue { return defineInRange(path, value, minValue, Int.MAX_VALUE) } -fun ForgeConfigSpec.Builder.defineInRange(path: String, value: Double, minValue: Double): ForgeConfigSpec.DoubleValue { +fun ModConfigSpec.Builder.defineInRange(path: String, value: Double, minValue: Double): ModConfigSpec.DoubleValue { return defineInRange(path, value, minValue, Double.MAX_VALUE) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/config/ObservedConfigValue.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/config/ObservedConfigValue.kt index ca69d1fba..e9c1efed6 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/config/ObservedConfigValue.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/config/ObservedConfigValue.kt @@ -1,10 +1,10 @@ package ru.dbotthepony.mc.otm.config -import net.minecraftforge.common.ForgeConfigSpec.ConfigValue +import net.neoforged.neoforge.common.ModConfigSpec import org.apache.logging.log4j.LogManager import ru.dbotthepony.kommons.util.Delegate -abstract class ObservedConfigValue(val parent: ConfigValue) : Delegate { +abstract class ObservedConfigValue(val parent: ModConfigSpec.ConfigValue) : Delegate { var rawValue: String by parent private var observedValue: String? = null private var cachedValue: V? = null diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/container/ContainerHandler.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/container/ContainerHandler.kt index eefa76b79..f3c21eb2d 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/container/ContainerHandler.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/container/ContainerHandler.kt @@ -1,7 +1,7 @@ package ru.dbotthepony.mc.otm.container import net.minecraft.world.item.ItemStack -import net.minecraftforge.items.IItemHandler +import net.neoforged.neoforge.items.IItemHandler class ContainerHandler( private val container: IMatteryContainer, @@ -34,7 +34,7 @@ class ContainerHandler( } else { return stack.copyWithCount(stack.count - amount) } - } else if (localStack.isStackable && container.getMaxStackSize(slot, localStack) > localStack.count && ItemStack.isSameItemSameTags(localStack, stack)) { + } else if (localStack.isStackable && container.getMaxStackSize(slot, localStack) > localStack.count && ItemStack.isSameItemSameComponents(localStack, stack)) { val newCount = container.getMaxStackSize(slot, localStack).coerceAtMost(localStack.count + stack.count.coerceAtMost(amount)) val diff = newCount - localStack.count diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/container/ContainerHelpers.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/container/ContainerHelpers.kt index c50cd7b5c..5750aa75d 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/container/ContainerHelpers.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/container/ContainerHelpers.kt @@ -15,8 +15,9 @@ import it.unimi.dsi.fastutil.objects.ObjectArrayList import net.minecraft.world.Container import net.minecraft.world.inventory.CraftingContainer import net.minecraft.world.item.ItemStack -import net.minecraft.world.item.enchantment.EnchantmentHelper.hasVanishingCurse -import net.minecraftforge.fluids.capability.IFluidHandler +import net.minecraft.world.item.enchantment.EnchantmentEffectComponents +import net.minecraft.world.item.enchantment.EnchantmentHelper +import net.neoforged.neoforge.fluids.capability.IFluidHandler import ru.dbotthepony.mc.otm.container.util.IContainerSlot import ru.dbotthepony.mc.otm.container.util.ItemStackHashStrategy import ru.dbotthepony.mc.otm.container.util.containerSlot @@ -74,7 +75,7 @@ fun Container.addItem(stack: ItemStack, simulate: Boolean, slots: IntIterable = while (i.hasNext()) { val slot = i.nextInt() - if (ItemStack.isSameItemSameTags(this[slot], copy)) { + if (ItemStack.isSameItemSameComponents(this[slot], copy)) { val slotStack = this[slot] val slotLimit = maxStackSize.coerceAtMost(slotStack.maxStackSize) @@ -125,7 +126,7 @@ fun Container.addItem(stack: ItemStack, simulate: Boolean, slots: IntIterable = fun Container.vanishCursedItems() { for (slot in slotIterator()) { - if (hasVanishingCurse(slot.item)) { + if (EnchantmentHelper.has(slot.item, EnchantmentEffectComponents.PREVENT_EQUIPMENT_DROP)) { slot.remove() } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/container/HandlerFilter.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/container/HandlerFilter.kt index eadb8a8e0..dbe17de88 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/container/HandlerFilter.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/container/HandlerFilter.kt @@ -1,8 +1,7 @@ package ru.dbotthepony.mc.otm.container import net.minecraft.world.item.ItemStack -import net.minecraftforge.common.ForgeHooks -import net.minecraftforge.common.capabilities.ForgeCapabilities +import net.neoforged.neoforge.capabilities.Capabilities import ru.dbotthepony.mc.otm.capability.MatteryCapability import ru.dbotthepony.mc.otm.capability.fluid.stream import ru.dbotthepony.mc.otm.core.isNotEmpty @@ -52,13 +51,13 @@ interface HandlerFilter { object FluidContainers : HandlerFilter { override fun canInsert(slot: Int, stack: ItemStack): Boolean { - return stack.getCapability(ForgeCapabilities.FLUID_HANDLER_ITEM).map { it.tanks > 0 }.orElse(false) + return stack.getCapability(Capabilities.FluidHandler.ITEM)?.let { it.tanks > 0 } ?: false } } object DrainableFluidContainers : HandlerFilter { override fun canInsert(slot: Int, stack: ItemStack): Boolean { - return stack.getCapability(ForgeCapabilities.FLUID_HANDLER_ITEM).map { it.stream().anyMatch { it.isNotEmpty } }.orElse(false) + return stack.getCapability(Capabilities.FluidHandler.ITEM)?.let { it.stream().anyMatch { it.isNotEmpty } } ?: false } override fun canExtract(slot: Int, amount: Int, stack: ItemStack): Boolean { @@ -90,65 +89,65 @@ interface HandlerFilter { object Dischargeable : HandlerFilter { override fun canInsert(slot: Int, stack: ItemStack): Boolean { - return stack.getCapability(ForgeCapabilities.ENERGY).map { it.canExtract() && it.extractEnergy(Int.MAX_VALUE, true) > 0 }.orElse(false) + return stack.getCapability(Capabilities.EnergyStorage.ITEM)?.let { it.canExtract() && it.extractEnergy(Int.MAX_VALUE, true) > 0 } ?: false } override fun canExtract(slot: Int, amount: Int, stack: ItemStack): Boolean { - return stack.getCapability(ForgeCapabilities.ENERGY).map { !it.canExtract() || it.extractEnergy(Int.MAX_VALUE, true) <= 0 }.orElse(true) + return stack.getCapability(Capabilities.EnergyStorage.ITEM)?.let { !it.canExtract() || it.extractEnergy(Int.MAX_VALUE, true) <= 0 } ?: false } } object Chargeable : HandlerFilter { override fun canInsert(slot: Int, stack: ItemStack): Boolean { - return stack.getCapability(ForgeCapabilities.ENERGY).map { it.canReceive() && it.receiveEnergy(Int.MAX_VALUE, true) > 0 }.orElse(false) + return stack.getCapability(Capabilities.EnergyStorage.ITEM)?.let { it.canReceive() && it.receiveEnergy(Int.MAX_VALUE, true) > 0 } ?: false } override fun canExtract(slot: Int, amount: Int, stack: ItemStack): Boolean { - return stack.getCapability(ForgeCapabilities.ENERGY).map { !it.canReceive() || it.receiveEnergy(Int.MAX_VALUE, true) <= 0 }.orElse(true) + return stack.getCapability(Capabilities.EnergyStorage.ITEM)?.let { !it.canReceive() || it.receiveEnergy(Int.MAX_VALUE, true) <= 0 } ?: false } } object ChemicalFuel : HandlerFilter { override fun canExtract(slot: Int, amount: Int, stack: ItemStack): Boolean { - return ForgeHooks.getBurnTime(stack, null) <= 0 + return stack.getBurnTime(null) <= 0 } override fun canInsert(slot: Int, stack: ItemStack): Boolean { - return ForgeHooks.getBurnTime(stack, null) > 0 + return stack.getBurnTime(null) > 0 } } object IsPattern : HandlerFilter { override fun canInsert(slot: Int, stack: ItemStack): Boolean { - return stack.getCapability(MatteryCapability.PATTERN).isPresent + return stack.getCapability(MatteryCapability.PATTERN_ITEM) != null } } object MatterProviders : HandlerFilter { override fun canInsert(slot: Int, stack: ItemStack): Boolean { - return stack.getCapability(MatteryCapability.MATTER) - .map { it.matterFlow.output && it.extractMatterChecked(Decimal.POSITIVE_INFINITY, true) > Decimal.ZERO } - .orElse(false) + return stack.getCapability(MatteryCapability.MATTER_ITEM) + ?.let { it.matterFlow.output && it.extractMatterChecked(Decimal.POSITIVE_INFINITY, true) > Decimal.ZERO } + ?: false } override fun canExtract(slot: Int, amount: Int, stack: ItemStack): Boolean { - return stack.getCapability(MatteryCapability.MATTER) - .map { !it.matterFlow.output || it.extractMatterChecked(Decimal.POSITIVE_INFINITY, true) <= Decimal.ZERO } - .orElse(true) + return stack.getCapability(MatteryCapability.MATTER_ITEM) + ?.let { !it.matterFlow.output || it.extractMatterChecked(Decimal.POSITIVE_INFINITY, true) <= Decimal.ZERO } + ?: false } } object MatterConsumers : HandlerFilter { override fun canInsert(slot: Int, stack: ItemStack): Boolean { - return stack.getCapability(MatteryCapability.MATTER) - .map { it.matterFlow.input && it.receiveMatterChecked(Decimal.POSITIVE_INFINITY, true) > Decimal.ZERO } - .orElse(false) + return stack.getCapability(MatteryCapability.MATTER_ITEM) + ?.let { it.matterFlow.input && it.receiveMatterChecked(Decimal.POSITIVE_INFINITY, true) > Decimal.ZERO } + ?: false } override fun canExtract(slot: Int, amount: Int, stack: ItemStack): Boolean { - return stack.getCapability(MatteryCapability.MATTER) - .map { !it.matterFlow.input || it.receiveMatterChecked(Decimal.POSITIVE_INFINITY, true) <= Decimal.ZERO } - .orElse(true) + return stack.getCapability(MatteryCapability.MATTER_ITEM) + ?.let { !it.matterFlow.input || it.receiveMatterChecked(Decimal.POSITIVE_INFINITY, true) <= Decimal.ZERO } + ?: false } } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/container/IMatteryContainer.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/container/IMatteryContainer.kt index fcc12e259..7010e7038 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/container/IMatteryContainer.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/container/IMatteryContainer.kt @@ -220,4 +220,14 @@ interface IMatteryContainer : IContainer, RecipeInput, Iterable { return addItem(stack, false, slots, ignoreFilters).isEmpty } + + fun toList(): MutableList { + val list = ArrayList(size()) + + for (i in 0 until size()) { + list[i] = this[i] + } + + return list + } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/container/ItemFilter.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/container/ItemFilter.kt index 5bd791cb2..58be92692 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/container/ItemFilter.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/container/ItemFilter.kt @@ -1,97 +1,72 @@ package ru.dbotthepony.mc.otm.container -import net.minecraft.nbt.CompoundTag -import net.minecraft.nbt.ListTag +import com.google.common.collect.ImmutableList +import com.mojang.serialization.Codec +import com.mojang.serialization.codecs.RecordCodecBuilder import net.minecraft.tags.TagKey import net.minecraft.world.item.Item import net.minecraft.world.item.ItemStack -import net.minecraftforge.common.util.INBTSerializable -import ru.dbotthepony.mc.otm.core.nbt.map -import ru.dbotthepony.mc.otm.core.nbt.set -import java.util.* -import java.util.function.Consumer -class ItemFilter( - val size: Int, - private val modified: Consumer? = null -) : INBTSerializable { - private val filter = Array(size) { ItemStack.EMPTY } - private val linkedFilter = LinkedList() +data class ItemFilter(val filter: List, val isWhitelist: Boolean = false, val matchTag: Boolean = false, val matchComponents: Boolean = false) { + fun add(item: ItemStack): ItemFilter { + if (filter.any { ItemStack.isSameItemSameComponents(it, item) }) + return this - var isLocked = false - - var isWhitelist = false - set(value) { - if (value != field) { - field = value - modified?.accept(this) - } - } - - var matchTag = false - set(value) { - if (value != field) { - field = value - modified?.accept(this) - } - } - - var matchNBT = false - set(value) { - if (value != field) { - field = value - modified?.accept(this) - } - } - - fun clear() { - isWhitelist = false - matchTag = false - matchNBT = false - - Arrays.fill(filter, ItemStack.EMPTY) - linkedFilter.clear() - - modified?.accept(this) + return copy( + filter = ArrayList(filter).also { it.add(item) } + ) } - operator fun set(index: Int, value: ItemStack) { - if (value.isEmpty && filter[index].isEmpty) { - return - } + fun remove(item: ItemStack): ItemFilter { + val indexOf = filter.indexOfFirst { ItemStack.isSameItemSameComponents(it, item) } - val old = filter[index] - filter[index] = value.let { if (!it.isEmpty) it.copy().also { it.count = 1 } else it } + if (indexOf == -1) + return this - if (!filter[index].isEmpty && filter[index].tag != null && filter[index].tag!!.isEmpty) { - filter[index].tag = null - } - - if (!old.isEmpty) - linkedFilter.remove(old) - - if (!filter[index].isEmpty) - linkedFilter.add(filter[index]) - - modified?.accept(this) + return copy( + filter = ArrayList(filter).also { it.removeAt(indexOf) } + ) } - operator fun get(index: Int): ItemStack = filter[index].copy() + fun get(index: Int): ItemStack { + return filter.getOrElse(index) { ItemStack.EMPTY } + } + + fun isWhitelist(flag: Boolean): ItemFilter { + if (flag == isWhitelist) + return this + else + return copy(isWhitelist = flag) + } + + fun matchTag(flag: Boolean): ItemFilter { + if (flag == matchTag) + return this + else + return copy(matchTag = flag) + } + + fun matchComponents(flag: Boolean): ItemFilter { + if (flag == matchComponents) + return this + else + return copy(matchComponents = flag) + } fun match(value: ItemStack): Boolean { if (value.isEmpty) { return false } - if (linkedFilter.isEmpty()) { + if (filter.isEmpty()) { return !isWhitelist } - for (item in linkedFilter) { - var matched = item.`is`(value.item) + for (item in filter) { + var matches = item.`is`(value.item) - if (matched && matchTag) { - matched = false + if (matches && matchTag) { + matches = false val thisTags = item.tags val stackTags = HashSet>() @@ -102,28 +77,17 @@ class ItemFilter( for (tag1 in thisTags) { if (stackTags.contains(tag1)) { - matched = true + matches = true break } } } - if (matched && matchNBT) { - val a = item.tag - val b = value.tag - - if (a == null && b == null) { - // nothing - } else if (a != null && b != null) { - matched = a == b - } else if (a != null) { - matched = a.isEmpty - } else { - matched = false - } + if (matches && matchComponents) { + matches = item.components == value.components } - if (matched) { + if (matches) { return isWhitelist } } @@ -131,41 +95,18 @@ class ItemFilter( return !isWhitelist } - override fun serializeNBT(): CompoundTag { - return CompoundTag().also { - it["items"] = ListTag().also { - for (value in filter) { - it.add(value.serializeNBT()) - } - } + companion object { + val EMPTY = ItemFilter(ImmutableList.of()) - it["is_whitelist"] = isWhitelist - it["match_tag"] = matchTag - it["match_nbt"] = matchNBT - } - } - - override fun deserializeNBT(nbt: CompoundTag?) { - for (i in filter.indices) - filter[i] = ItemStack.EMPTY - - if (nbt == null) - return - - nbt.map("items") { it: ListTag -> - for ((i, value) in it.withIndex()) { - if (value is CompoundTag) { - filter[i] = ItemStack.of(value) - - if (!filter[i].isEmpty) { - linkedFilter.add(filter[i]) - } - } + val CODEC: Codec by lazy { + RecordCodecBuilder.create { + it.group( + Codec.list(ItemStack.CODEC, 0, 40).fieldOf("filter").forGetter { it.filter }, + Codec.BOOL.optionalFieldOf("isWhitelist", false).forGetter { it.isWhitelist }, + Codec.BOOL.optionalFieldOf("matchTag", false).forGetter { it.matchTag }, + Codec.BOOL.optionalFieldOf("matchComponents", false).forGetter { it.matchComponents }, + ).apply(it, ::ItemFilter) } } - - isWhitelist = nbt.getBoolean("is_whitelist") - matchTag = nbt.getBoolean("match_tag") - matchNBT = nbt.getBoolean("match_nbt") } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/container/MatteryContainer.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/container/MatteryContainer.kt index 7c9a607a0..8984bcf4f 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/container/MatteryContainer.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/container/MatteryContainer.kt @@ -9,20 +9,19 @@ import it.unimi.dsi.fastutil.ints.IntComparators import it.unimi.dsi.fastutil.ints.IntSpliterator import it.unimi.dsi.fastutil.objects.ObjectSpliterators import net.minecraft.core.HolderLookup +import net.minecraft.core.registries.BuiltInRegistries import net.minecraft.world.item.ItemStack import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.ListTag import net.minecraft.nbt.NbtOps import net.minecraft.nbt.Tag -import net.minecraft.resources.ResourceLocation import net.minecraft.world.Container import net.minecraft.world.entity.player.Player import net.minecraft.world.entity.player.StackedContents import net.minecraft.world.inventory.StackedContentsCompatible import net.minecraft.world.item.Item import net.minecraft.world.item.Items -import net.minecraftforge.common.util.INBTSerializable -import net.minecraftforge.registries.ForgeRegistries +import net.neoforged.neoforge.common.util.INBTSerializable import org.apache.logging.log4j.LogManager import ru.dbotthepony.kommons.collect.ListenableMap import ru.dbotthepony.kommons.io.DelegateSyncher @@ -35,7 +34,6 @@ import ru.dbotthepony.mc.otm.core.collect.emptyIterator import ru.dbotthepony.mc.otm.core.collect.filter import ru.dbotthepony.mc.otm.core.collect.map import ru.dbotthepony.mc.otm.core.isNotEmpty -import ru.dbotthepony.mc.otm.core.nbt.map import ru.dbotthepony.mc.otm.core.nbt.set import ru.dbotthepony.mc.otm.core.registryName import ru.dbotthepony.mc.otm.core.util.ItemValueCodec @@ -205,7 +203,7 @@ open class MatteryContainer(var listener: ContainerListener, private val size: I companion object { val CODEC: Codec = RecordCodecBuilder.create { it.group( - ForgeRegistries.ITEMS.codec.fieldOf("item").forGetter { it.item }, + BuiltInRegistries.ITEM.byNameCodec().fieldOf("item").forGetter { it.item }, Codec.INT.minRange(0).fieldOf("slot").forGetter { it.slot }, ).apply(it, ::SerializedFilter) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/container/MatteryCraftingContainer.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/container/MatteryCraftingContainer.kt index 65831e744..036e7bc27 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/container/MatteryCraftingContainer.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/container/MatteryCraftingContainer.kt @@ -16,9 +16,6 @@ open class MatteryCraftingContainer(listener: ContainerListener, private val wid } final override fun getItems(): MutableList { - val i = spliterator() - val result = ArrayList(i.estimateSize().toInt()) - i.forEachRemaining { result.add(it) } - return result + return toList() } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/container/UpgradeContainer.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/container/UpgradeContainer.kt index 9b178fa01..df8109ef5 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/container/UpgradeContainer.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/container/UpgradeContainer.kt @@ -18,20 +18,20 @@ open class UpgradeContainer(slotCount: Int, open val allowedUpgrades: Set Decimal, reducer: (Decimal, Decimal) -> Decimal): Decimal { return iterator() - .map { it.getCapability(MatteryCapability.UPGRADE).map(fn).orElse(Decimal.ZERO).moreThanZero() * it.count } + .map { (it.getCapability(MatteryCapability.UPGRADE)?.let(fn) ?: Decimal.ZERO).moreThanZero() * it.count } .reduce(Decimal.ZERO, reducer) } protected fun anyDecimals(fn: (IMatteryUpgrade) -> Decimal, reducer: (Decimal, Decimal) -> Decimal): Decimal { return iterator() - .map { it.getCapability(MatteryCapability.UPGRADE).map(fn).orElse(Decimal.ZERO) * it.count } + .map { (it.getCapability(MatteryCapability.UPGRADE)?.let(fn) ?: Decimal.ZERO) * it.count } .reduce(Decimal.ZERO, reducer) } override val speedBonus: Double - get() = iterator().map { it.getCapability(MatteryCapability.UPGRADE).map { it.speedBonus }.orElse(0.0) * it.count }.reduce(0.0) { a, b -> a + b } + get() = iterator().map { (it.getCapability(MatteryCapability.UPGRADE)?.speedBonus ?: 0.0) * it.count }.reduce(0.0) { a, b -> a + b } override val processingItems: Int - get() = iterator().map { it.getCapability(MatteryCapability.UPGRADE).map { it.processingItems }.orElse(0).coerceAtLeast(0) * it.count }.reduce(0) { a, b -> a + b } + get() = iterator().map { (it.getCapability(MatteryCapability.UPGRADE)?.processingItems ?: 0).coerceAtLeast(0) * it.count }.reduce(0) { a, b -> a + b } override val energyStorageFlat: Decimal get() = positiveDecimals(IMatteryUpgrade::energyStorageFlat, Decimal::plus) override val energyStorage: Decimal @@ -43,7 +43,7 @@ open class UpgradeContainer(slotCount: Int, open val allowedUpgrades: Set a * b } + get() = iterator().map { (it.getCapability(MatteryCapability.UPGRADE)?.failureMultiplier ?: 1.0).coerceAtLeast(0.0).pow(it.count.toDouble()) }.reduce(1.0) { a, b -> a * b } override val energyThroughputFlat: Decimal get() = positiveDecimals(IMatteryUpgrade::energyThroughputFlat, Decimal::plus) override val energyThroughput: Decimal diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/container/util/ItemHandlerSpliterator.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/container/util/ItemHandlerSpliterator.kt index 9d7c27669..9227b3b39 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/container/util/ItemHandlerSpliterator.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/container/util/ItemHandlerSpliterator.kt @@ -3,7 +3,7 @@ package ru.dbotthepony.mc.otm.container.util import it.unimi.dsi.fastutil.objects.ObjectSpliterator import it.unimi.dsi.fastutil.objects.ObjectSpliterators import net.minecraft.world.item.ItemStack -import net.minecraftforge.items.IItemHandler +import net.neoforged.neoforge.items.IItemHandler import ru.dbotthepony.mc.otm.core.collect.AwareItemStack import ru.dbotthepony.mc.otm.core.collect.ItemHandlerItemStackEntry import ru.dbotthepony.mc.otm.core.collect.filter diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/container/util/ItemStackHashStrategy.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/container/util/ItemStackHashStrategy.kt index 5d635e5af..9ff9bae12 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/container/util/ItemStackHashStrategy.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/container/util/ItemStackHashStrategy.kt @@ -5,11 +5,11 @@ import net.minecraft.world.item.ItemStack object ItemStackHashStrategy : Hash.Strategy { override fun equals(a: ItemStack?, b: ItemStack?): Boolean { - return a === b || a != null && b != null && ItemStack.isSameItemSameTags(a, b) + return a === b || a != null && b != null && ItemStack.isSameItemSameComponents(a, b) } override fun hashCode(o: ItemStack?): Int { o ?: return 0 - return o.item.hashCode().xor(o.tag.hashCode()) + return o.item.hashCode().xor(o.components.hashCode()) } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/Ext.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/Ext.kt index 18a9e39d6..cb8641ab3 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/Ext.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/core/Ext.kt @@ -13,19 +13,25 @@ import com.google.gson.JsonPrimitive import it.unimi.dsi.fastutil.objects.ObjectComparators import net.minecraft.Util import net.minecraft.core.BlockPos +import net.minecraft.core.Holder +import net.minecraft.core.HolderLookup +import net.minecraft.core.HolderSet +import net.minecraft.core.Registry import net.minecraft.core.SectionPos -import net.minecraft.nbt.CompoundTag -import net.minecraft.nbt.NbtAccounter +import net.minecraft.core.registries.BuiltInRegistries import net.minecraft.network.FriendlyByteBuf +import net.minecraft.network.RegistryFriendlyByteBuf +import net.minecraft.network.chat.Component import net.minecraft.network.chat.ComponentContents +import net.minecraft.network.chat.ComponentSerialization import net.minecraft.network.chat.contents.TranslatableContents +import net.minecraft.resources.ResourceKey import net.minecraft.resources.ResourceLocation +import net.minecraft.tags.TagKey import net.minecraft.world.entity.Entity import net.minecraft.world.item.Item import net.minecraft.world.item.ItemStack -import net.minecraft.world.item.Items import net.minecraft.world.item.crafting.CraftingInput -import net.minecraft.world.item.crafting.Ingredient import net.minecraft.world.item.crafting.RecipeInput import net.minecraft.world.level.BlockGetter import net.minecraft.world.level.Level @@ -36,42 +42,25 @@ import net.minecraft.world.level.block.state.BlockState import net.minecraft.world.level.block.state.StateHolder import net.minecraft.world.level.block.state.properties.Property import net.minecraft.world.phys.Vec3 -import net.minecraftforge.common.ForgeHooks -import net.minecraftforge.common.util.LazyOptional -import net.minecraftforge.fluids.FluidStack -import net.minecraftforge.items.IItemHandler -import net.minecraftforge.registries.ForgeRegistries -import net.minecraftforge.registries.ForgeRegistry -import net.minecraftforge.registries.IForgeRegistry -import ru.dbotthepony.kommons.io.DelegateSyncher -import ru.dbotthepony.kommons.io.StreamCodec -import ru.dbotthepony.kommons.util.DelegateGetter -import ru.dbotthepony.kommons.util.DelegateSetter -import ru.dbotthepony.kommons.util.ListenableDelegate +import net.neoforged.neoforge.fluids.FluidStack +import net.neoforged.neoforge.items.IItemHandler import ru.dbotthepony.mc.otm.core.math.BlockRotation import ru.dbotthepony.mc.otm.core.math.BlockRotationFreedom -import ru.dbotthepony.mc.otm.core.math.Decimal import ru.dbotthepony.mc.otm.core.math.Vector -import ru.dbotthepony.mc.otm.core.math.readDecimal -import ru.dbotthepony.mc.otm.core.math.writeDecimal -import ru.dbotthepony.mc.otm.core.util.DecimalValueCodec -import ru.dbotthepony.mc.otm.core.util.readInt import ru.dbotthepony.mc.otm.core.util.readVarIntLE -import ru.dbotthepony.mc.otm.core.util.writeInt import ru.dbotthepony.mc.otm.core.util.writeVarIntLE import java.io.InputStream import java.io.OutputStream import java.lang.ref.Reference import java.math.BigInteger -import java.util.Arrays -import java.util.Spliterators -import java.util.UUID +import java.util.* import java.util.concurrent.Callable import java.util.concurrent.Future import java.util.function.Consumer import java.util.function.Supplier import java.util.stream.Stream import java.util.stream.StreamSupport +import kotlin.jvm.optionals.getOrNull import kotlin.reflect.KProperty operator fun RecipeInput.get(index: Int): ItemStack = getItem(index) @@ -125,29 +114,6 @@ fun LevelAccessor.getBlockStateNow(pos: BlockPos): BlockState { return chunkSource.getChunkNow(SectionPos.blockToSectionCoord(pos.x), SectionPos.blockToSectionCoord(pos.z))?.getBlockState(pos) ?: Blocks.AIR.defaultBlockState() } -fun LazyOptional.orNull(): T? { - if (!isPresent) { - return null - } - - return resolve().orElse(null) -} - -fun LazyOptional.orThrow(): T { - if (!isPresent) { - throw IllegalStateException("Capability was expected to be not null") - } - - return resolve().get() ?: throw IllegalStateException("Capability was expected to be not null") -} - -inline fun LazyOptional.ifPresentK(lambda: (T) -> Unit) { - if (isPresent) { - val value = resolve().orElse(null) ?: throw IllegalStateException("Capability was expected to be not null") - lambda.invoke(value) - } -} - inline val FluidStack.isNotEmpty get() = !isEmpty inline val ItemStack.isNotEmpty get() = !isEmpty @@ -234,32 +200,36 @@ fun immutableList(a: V, vararg values: V): ImmutableList { return builder.build() } -fun IForgeRegistry.getID(value: T): Int { - return (this as ForgeRegistry).getID(value) -} - -fun IForgeRegistry.getValue(index: Int): T? { - return (this as ForgeRegistry).getValue(index) -} - -fun IForgeRegistry<*>.getID(value: ResourceLocation): Int { - return (this as ForgeRegistry<*>).getID(value) -} - fun FriendlyByteBuf.writeItemType(value: Item) { - writeInt(ForgeRegistries.ITEMS.getID(value)) + writeInt(BuiltInRegistries.ITEM.getId(value)) +} + +fun RegistryFriendlyByteBuf.writeItem(value: ItemStack) { + ItemStack.STREAM_CODEC.encode(this, value) +} + +fun RegistryFriendlyByteBuf.writeComponent(value: Component) { + ComponentSerialization.STREAM_CODEC.encode(this, value) } fun OutputStream.writeItemType(value: Item) { - writeVarIntLE(ForgeRegistries.ITEMS.getID(value)) + writeVarIntLE(BuiltInRegistries.ITEM.getId(value)) } fun FriendlyByteBuf.readItemType(): Item { - return ForgeRegistries.ITEMS.getValue(readInt()) ?: Items.AIR + return BuiltInRegistries.ITEM.byId(readInt()) +} + +fun RegistryFriendlyByteBuf.readItem(): ItemStack { + return ItemStack.STREAM_CODEC.decode(this) +} + +fun RegistryFriendlyByteBuf.readComponent(): Component { + return ComponentSerialization.STREAM_CODEC.decode(this) } fun InputStream.readItemType(): Item { - return ForgeRegistries.ITEMS.getValue(readVarIntLE()) ?: Items.AIR + return BuiltInRegistries.ITEM.byId(readVarIntLE()) } operator fun > StateHolder<*, *>.get(property: Property): T { @@ -326,8 +296,6 @@ fun Iterator.stream(): Stream { return StreamSupport.stream(Spliterators.spliteratorUnknownSize(this, 0), false) } -val Ingredient.isActuallyEmpty: Boolean get() = ForgeHooks.hasNoElements(this) - fun Entity.genericPositions(): Collection { return listOf( position, @@ -520,3 +488,21 @@ fun lazy2(a: () -> A, b: A.() -> B): Supplier { return Supplier { b.invoke(first.value) } } +fun HolderLookup.Provider.lookupOrThrow(key: ResourceKey): Holder { + return lookupOrThrow(key.registryKey()).getOrThrow(key) +} + +fun Registry.getHolder(value: T): Holder? { + // this is so stupid + return getHolder(getResourceKey(value).getOrNull() ?: return null).getOrNull() +} + +fun Registry.getHolderOrThrow(value: T): Holder { + // this is so stupid + return getHolder(getResourceKey(value).orElseThrow()).orElseThrow() +} + +// forge registry functionality emulation on vanilla registry +fun Registry.getReverseTag(value: T): Stream> { + return getHolder(value)?.tags() ?: Stream.empty() +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/TooltipList.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/TooltipList.kt index cff6c59ac..dfb56003e 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/TooltipList.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/core/TooltipList.kt @@ -1,21 +1,21 @@ package ru.dbotthepony.mc.otm.core import net.minecraft.ChatFormatting +import net.minecraft.core.HolderLookup +import net.minecraft.core.component.DataComponents import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.Tag import net.minecraft.network.chat.Component import net.minecraft.world.item.BlockItem import net.minecraft.world.item.DyeColor +import net.minecraft.world.item.Item.TooltipContext import net.minecraft.world.item.ItemStack -import net.minecraftforge.common.capabilities.ForgeCapabilities +import net.minecraft.world.item.component.CustomData +import net.neoforged.neoforge.capabilities.Capabilities import ru.dbotthepony.mc.otm.block.entity.MatteryBlockEntity import ru.dbotthepony.mc.otm.capability.energy import ru.dbotthepony.mc.otm.capability.energy.BlockEnergyStorageImpl -import ru.dbotthepony.mc.otm.capability.energy.CapacitorEnergyStorage -import ru.dbotthepony.mc.otm.capability.energy.GeneratorEnergyStorage import ru.dbotthepony.mc.otm.capability.energy.IMatteryEnergyStorage -import ru.dbotthepony.mc.otm.capability.energy.ItemEnergyStorageImpl -import ru.dbotthepony.mc.otm.capability.energy.WorkerEnergyStorage import ru.dbotthepony.mc.otm.capability.energy.batteryLevel import ru.dbotthepony.mc.otm.capability.fluidLevel import ru.dbotthepony.mc.otm.capability.matter.MatterStorageImpl @@ -31,36 +31,40 @@ import ru.dbotthepony.mc.otm.core.util.formatMatter import ru.dbotthepony.mc.otm.core.util.formatPower class TooltipList { - private val descriptionLines = ArrayList<(itemStack: ItemStack, acceptor: (text: Component) -> Unit) -> Unit>() + fun interface TooltipProvider { + fun invoke(itemStack: ItemStack, context: TooltipContext, acceptor: (text: Component) -> Unit) + } - fun assemble(itemStack: ItemStack, into: (Component) -> Unit) { + private val descriptionLines = ArrayList() + + fun assemble(itemStack: ItemStack, context: TooltipContext, into: (Component) -> Unit) { if (descriptionLines.isNotEmpty()) { - if (ClientConfig.HIDE_DESCRIPTION && !minecraft.window.isShiftDown && descriptionLines.any { var flag = false; it.invoke(itemStack) { flag = true }; flag }) { + if (ClientConfig.HIDE_DESCRIPTION && !minecraft.window.isShiftDown && descriptionLines.any { var flag = false; it.invoke(itemStack, context) { flag = true }; flag }) { into.invoke(TranslatableComponent("otm.gui.shift_for_more_info").withStyle(ChatFormatting.GRAY).withStyle(ChatFormatting.ITALIC)) } else { for (lines in descriptionLines) { - lines.invoke(itemStack, into) + lines.invoke(itemStack, context, into) } } } } - fun assemble(itemStack: ItemStack, into: MutableCollection) { - assemble(itemStack, into::add) + fun assemble(itemStack: ItemStack, context: TooltipContext, into: MutableCollection) { + assemble(itemStack, context, into::add) } - fun addNormal(function: (itemStack: ItemStack, acceptor: (text: Component) -> Unit) -> Unit) { + fun addNormal(function: TooltipProvider) { descriptionLines.add(function) } @JvmName("addPlain") fun add(component: Component) { - descriptionLines.add { _, result -> result.invoke(component.copy()) } + descriptionLines.add { _, _, result -> result.invoke(component.copy()) } } @JvmName("addFunction2Component") fun add(component: () -> Component) { - descriptionLines.add { _, result -> result.invoke(component.invoke()) } + descriptionLines.add { _, _, result -> result.invoke(component.invoke()) } } fun needsNoPower(formatting: ChatFormatting = ChatFormatting.GRAY) { @@ -75,15 +79,15 @@ class TooltipList { fun colored(color: DyeColor?) = painted(color) - inline fun blockEntityData(key: String, noinline callback: (itemStack: ItemStack, data: T, acceptor: (line: Component) -> Unit) -> Unit) { - addNormal { itemStack, acceptor -> - val tag = (itemStack.tag?.get(BlockItem.BLOCK_ENTITY_TAG) as? CompoundTag)?.get(key) as? T ?: return@addNormal - callback(itemStack, tag, acceptor) + inline fun blockEntityData(key: String, noinline callback: (itemStack: ItemStack, context: TooltipContext, data: T, acceptor: (line: Component) -> Unit) -> Unit) { + addNormal { itemStack, context, acceptor -> + val data = itemStack.getOrDefault(DataComponents.BLOCK_ENTITY_DATA, CustomData.EMPTY) + callback(itemStack, context, data.unsafe.get(key) as? T ?: return@addNormal, acceptor) } } fun blockEntityEnergy(energyKey: String = MatteryBlockEntity.ENERGY_KEY, batteryKey: String = MatteryBlockEntity.BATTERY_KEY) { - blockEntityData(energyKey) { _, tag, acceptor -> + blockEntityData(energyKey) { _, context, tag, acceptor -> val stored = tag.mapPresent(BlockEnergyStorageImpl.ENERGY_STORED_KEY, Decimal::deserializeNBT) if (stored != null) { @@ -94,25 +98,29 @@ class TooltipList { ).withStyle(ChatFormatting.GRAY)) } - val container = MatteryContainer(1) - tag.map(batteryKey, container::deserializeNBT) + val registry = context.registries() - if (!container[0].isEmpty) { - acceptor(TranslatableComponent("otm.item.block.stored_battery", container[0].displayName).withStyle(ChatFormatting.GRAY)) + if (registry != null) { + val container = MatteryContainer(1) + tag.map(batteryKey) { it: Tag -> container.deserializeNBT(registry, it) } - val energy = container[0].energy ?: return@blockEntityData + if (!container[0].isEmpty) { + acceptor(TranslatableComponent("otm.item.block.stored_battery", container[0].displayName).withStyle(ChatFormatting.GRAY)) - if (energy is IMatteryEnergyStorage) { - batteryLevel(energy, acceptor) - } else { - batteryLevel(energy, acceptor) + val energy = container[0].energy ?: return@blockEntityData + + if (energy is IMatteryEnergyStorage) { + batteryLevel(energy, acceptor) + } else { + batteryLevel(energy, acceptor) + } } } } } fun blockEntityMatter(matterKey: String = MatteryBlockEntity.MATTER_STORAGE_KEY) { - blockEntityData(matterKey) { _, tag, acceptor -> + blockEntityData(matterKey) { _, _, tag, acceptor -> val stored = tag.mapPresent(MatterStorageImpl.MATTER_STORED_KEY, Decimal::deserializeNBT) if (stored != null) { @@ -126,7 +134,7 @@ class TooltipList { } fun itemEnergy() { - addNormal { itemStack, acceptor -> + addNormal { itemStack, _, acceptor -> val energy = itemStack.energy ?: return@addNormal if (energy is IMatteryEnergyStorage) { @@ -142,10 +150,8 @@ class TooltipList { } fun itemFluid() { - addNormal { itemStack, acceptor -> - itemStack.getCapability(ForgeCapabilities.FLUID_HANDLER_ITEM).ifPresentK { - it.fluidLevel(acceptor) - } + addNormal { itemStack, _, acceptor -> + itemStack.getCapability(Capabilities.FluidHandler.ITEM)?.fluidLevel(acceptor) } } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/UnOverengineering.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/UnOverengineering.kt index 428f34283..1c9e701f5 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/UnOverengineering.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/core/UnOverengineering.kt @@ -2,12 +2,14 @@ package ru.dbotthepony.mc.otm.core import com.google.gson.JsonElement import com.google.gson.JsonSyntaxException -import com.mojang.datafixers.util.Either import com.mojang.serialization.Codec import com.mojang.serialization.DataResult import com.mojang.serialization.JsonOps import net.minecraft.core.Holder +import net.minecraft.core.Registry import net.minecraft.core.RegistryAccess +import net.minecraft.core.Vec3i +import net.minecraft.core.registries.BuiltInRegistries import net.minecraft.core.registries.Registries import net.minecraft.nbt.NbtOps import net.minecraft.nbt.Tag @@ -24,8 +26,8 @@ import net.minecraft.world.damagesource.DamageType import net.minecraft.world.item.Item import net.minecraft.world.level.block.Block import net.minecraft.world.level.material.Fluid -import net.minecraftforge.registries.ForgeRegistries -import net.minecraftforge.registries.IForgeRegistry +import net.minecraft.world.phys.AABB +import net.minecraft.world.phys.Vec3 import ru.dbotthepony.mc.otm.core.util.readBinaryJson import ru.dbotthepony.mc.otm.core.util.writeBinaryJson import kotlin.jvm.optionals.getOrNull @@ -36,31 +38,31 @@ fun Codec.fromJson(value: JsonElement): V? { } fun Codec.fromJsonStrict(value: JsonElement): V { - return decode(JsonOps.INSTANCE, value).get({ left -> left.first }, { throw JsonSyntaxException("Error decoding element: ${it.message()}") }) + return decode(JsonOps.INSTANCE, value).mapOrElse({ left -> left.first }, { throw JsonSyntaxException("Error decoding element: ${it.message()}") }) } fun Codec.toJson(value: V, prefix: JsonElement = JsonOps.INSTANCE.empty()): JsonElement? { - return encode(value, JsonOps.INSTANCE, prefix).getOrNull { it } + return encode(value, JsonOps.INSTANCE, prefix).mapOrNull { it } } fun Codec.toJsonStrict(value: V, prefix: JsonElement = JsonOps.INSTANCE.empty()): JsonElement { - return encode(value, JsonOps.INSTANCE, prefix).get({ it }, { throw RuntimeException("Error encoding element: ${it.message()}") }) + return encode(value, JsonOps.INSTANCE, prefix).mapOrElse({ it }, { throw RuntimeException("Error encoding element: ${it.message()}") }) } fun Codec.fromNbt(value: Tag): V? { - return decode(NbtOps.INSTANCE, value).getOrNull { left -> left.first } + return decode(NbtOps.INSTANCE, value).mapOrNull { left -> left.first } } fun Codec.fromNbtStrict(value: Tag): V { - return decode(NbtOps.INSTANCE, value).get({ left -> left.first }, { throw RuntimeException("Error decoding element: ${it.message()}") }) + return decode(NbtOps.INSTANCE, value).mapOrElse({ left -> left.first }, { throw RuntimeException("Error decoding element: ${it.message()}") }) } fun Codec.toNbt(value: V, prefix: Tag = NbtOps.INSTANCE.empty()): Tag? { - return encode(value, NbtOps.INSTANCE, prefix).getOrNull { it } + return encode(value, NbtOps.INSTANCE, prefix).mapOrNull { it } } fun Codec.toNbtStrict(value: V, prefix: Tag = NbtOps.INSTANCE.empty()): Tag { - return encode(value, NbtOps.INSTANCE, prefix).get({ it }, { throw RuntimeException("Error encoding element: ${it.message()}") }) + return encode(value, NbtOps.INSTANCE, prefix).mapOrElse({ it }, { throw RuntimeException("Error encoding element: ${it.message()}") }) } fun Codec.toNetwork(buff: FriendlyByteBuf, value: V) { @@ -75,7 +77,7 @@ fun Codec.fromNetwork(buff: FriendlyByteBuf): V { fun TranslatableComponent(key: String, vararg values: Any): MutableComponent = MutableComponent.create(TranslatableContents(key, null, values)) fun TextComponent(value: String): MutableComponent = MutableComponent.create(PlainTextContents.create(value)) -fun IForgeRegistry.getKeyNullable(value: T): ResourceLocation? { +fun Registry.getKeyNullable(value: T): ResourceLocation? { val key = getResourceKey(value) if (key.isPresent) { @@ -85,14 +87,12 @@ fun IForgeRegistry.getKeyNullable(value: T): ResourceLocation? { return null } -val Item.registryName get() = ForgeRegistries.ITEMS.getKeyNullable(this) -val Fluid.registryName get() = ForgeRegistries.FLUIDS.getKeyNullable(this) -val Block.registryName get() = ForgeRegistries.BLOCKS.getKeyNullable(this) - -fun FriendlyByteBuf.writeRegistryId(value: Item) = writeRegistryId(ForgeRegistries.ITEMS, value) +val Item.registryName get() = BuiltInRegistries.ITEM.getKeyNullable(this) +val Fluid.registryName get() = BuiltInRegistries.FLUID.getKeyNullable(this) +val Block.registryName get() = BuiltInRegistries.BLOCK.getKeyNullable(this) // 1.19.3 lol -inline val SoundEvent.holder get() = ForgeRegistries.SOUND_EVENTS.getHolder(this).orElse(null) ?: throw NoSuchElementException("$this is missing from ${ForgeRegistries.SOUND_EVENTS}") +inline val SoundEvent.holder: Holder get() = BuiltInRegistries.SOUND_EVENT.wrapAsHolder(this) // 1.19.4 :thonkang: inline val DamageSource.isFall get() = `is`(DamageTypeTags.IS_FALL) @@ -104,14 +104,13 @@ fun RegistryAccess.damageType(key: ResourceKey): Holder return registryOrThrow(Registries.DAMAGE_TYPE).getHolderOrThrow(key) } -// 1.21 -fun ResourceLocation(namespace: String, path: String) = ResourceLocation.fromNamespaceAndPath(namespace, path) +// 1.21 :help_me: +fun ResourceLocation(namespace: String, path: String): ResourceLocation = ResourceLocation.fromNamespaceAndPath(namespace, path) -// mojang hello? -fun DataResult.get(map: (IN) -> OUT, orThrow: (DataResult.Error) -> Nothing): OUT { - return result().map(map).orElseGet { orThrow(error().get()) } -} - -fun DataResult.getOrNull(map: (IN) -> OUT): OUT? { +fun DataResult.mapOrNull(map: (IN) -> OUT): OUT? { return result().map(map).orElse(null) } + +fun AABB(mins: Vec3i, maxs: Vec3i): AABB { + return AABB(Vec3.atLowerCornerOf(mins), Vec3.atLowerCornerOf(maxs)) +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/collect/AwareItemStack.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/collect/AwareItemStack.kt index cc60cfe9d..a29c78778 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/collect/AwareItemStack.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/core/collect/AwareItemStack.kt @@ -3,8 +3,9 @@ package ru.dbotthepony.mc.otm.core.collect import net.minecraft.world.Container import net.minecraft.world.entity.player.Inventory import net.minecraft.world.item.ItemStack -import net.minecraft.world.item.enchantment.EnchantmentHelper.hasBindingCurse -import net.minecraftforge.items.IItemHandler +import net.minecraft.world.item.enchantment.EnchantmentEffectComponents +import net.minecraft.world.item.enchantment.EnchantmentHelper +import net.neoforged.neoforge.items.IItemHandler import ru.dbotthepony.mc.otm.container.get import ru.dbotthepony.mc.otm.container.set import ru.dbotthepony.mc.otm.core.get @@ -28,7 +29,7 @@ data class ContainerItemStackEntry(val index: Int, val container: Container) : A } override fun extract(amount: Int, simulate: Boolean): ItemStack { - if (container is Inventory && index in 36 .. 39 && hasBindingCurse(container[index])) { + if (container is Inventory && index in 36 .. 39 && EnchantmentHelper.has(container[index], EnchantmentEffectComponents.PREVENT_ARMOR_CHANGE)) { return ItemStack.EMPTY } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/collect/UUIDIntModifiersMap.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/collect/UUIDIntModifiersMap.kt index 601913052..a2f86c992 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/collect/UUIDIntModifiersMap.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/core/collect/UUIDIntModifiersMap.kt @@ -1,8 +1,9 @@ package ru.dbotthepony.mc.otm.core.collect +import net.minecraft.core.HolderLookup import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.ListTag -import net.minecraftforge.common.util.INBTSerializable +import net.neoforged.neoforge.common.util.INBTSerializable import ru.dbotthepony.mc.otm.core.nbt.contains import java.util.UUID @@ -88,7 +89,7 @@ class UUIDIntModifiersMap(private val observer: (Int) -> Unit, private val backi } } - override fun serializeNBT(): ListTag { + override fun serializeNBT(registry: HolderLookup.Provider): ListTag { return ListTag().also { for ((key, value) in backingMap) { it.add(CompoundTag().also { @@ -99,7 +100,7 @@ class UUIDIntModifiersMap(private val observer: (Int) -> Unit, private val backi } } - override fun deserializeNBT(nbt: ListTag?) { + override fun deserializeNBT(registry: HolderLookup.Provider, nbt: ListTag?) { backingMap.clear() nbt ?: return val old = this.value diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/math/BlockRotation.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/math/BlockRotation.kt index fee43c2be..e7446b2f2 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/math/BlockRotation.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/core/math/BlockRotation.kt @@ -5,19 +5,12 @@ import net.minecraft.core.Direction import net.minecraft.core.Vec3i import net.minecraft.util.StringRepresentable import net.minecraft.world.level.block.Rotation -import net.minecraftforge.common.capabilities.Capability -import net.minecraftforge.common.capabilities.ICapabilityProvider -import net.minecraftforge.common.util.LazyOptional import java.util.Collections import java.util.EnumMap internal inline val Direction.blockRotation get() = BlockRotation.of(this) -fun ICapabilityProvider.getCapability(capability: Capability, side: BlockRotation?): LazyOptional { - return getCapability(capability, side?.front) -} - operator fun Vec3i.plus(other: BlockRotation): Vec3i { return this + other.normal } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/math/Decimal.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/math/Decimal.kt index 9011af8c0..7c7186da3 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/math/Decimal.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/core/math/Decimal.kt @@ -1,14 +1,12 @@ package ru.dbotthepony.mc.otm.core.math -import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap import net.minecraft.nbt.ByteArrayTag import net.minecraft.nbt.CompoundTag -import net.minecraft.nbt.NbtAccounter import net.minecraft.nbt.StringTag import net.minecraft.nbt.Tag import net.minecraft.network.FriendlyByteBuf import net.minecraft.util.RandomSource -import net.minecraftforge.common.ForgeConfigSpec +import net.neoforged.neoforge.common.ModConfigSpec import ru.dbotthepony.mc.otm.config.ObservedConfigValue import ru.dbotthepony.mc.otm.core.util.readVarIntLE import ru.dbotthepony.mc.otm.core.util.writeVarIntLE @@ -1595,7 +1593,7 @@ fun Long.toDecimal() = Decimal(this) fun Decimal.toDecimal() = this class DecimalConfigValue( - parent: ForgeConfigSpec.ConfigValue, + parent: ModConfigSpec.ConfigValue, val minimum: Decimal? = null, val maximum: Decimal? = null, ) : ObservedConfigValue(parent) { @@ -1626,7 +1624,7 @@ class DecimalConfigValue( } } -private fun ForgeConfigSpec.Builder.commentRange(minimum: Decimal?, maximum: Decimal?) { +private fun ModConfigSpec.Builder.commentRange(minimum: Decimal?, maximum: Decimal?) { if (minimum != null && maximum != null) { comment("Range: $minimum ~ $maximum") } else if (minimum != null) { @@ -1636,13 +1634,13 @@ private fun ForgeConfigSpec.Builder.commentRange(minimum: Decimal?, maximum: Dec } } -fun ForgeConfigSpec.Builder.defineDecimal(path: String, defaultValue: Decimal, minimum: Decimal? = null, maximum: Decimal? = null): DecimalConfigValue { +fun ModConfigSpec.Builder.defineDecimal(path: String, defaultValue: Decimal, minimum: Decimal? = null, maximum: Decimal? = null): DecimalConfigValue { commentRange(minimum, maximum) comment("Default: $defaultValue") return DecimalConfigValue(define(path, defaultValue.toString()), minimum, maximum) } -fun ForgeConfigSpec.Builder.defineDecimal(path: List, defaultValue: Decimal, minimum: Decimal? = null, maximum: Decimal? = null): DecimalConfigValue { +fun ModConfigSpec.Builder.defineDecimal(path: List, defaultValue: Decimal, minimum: Decimal? = null, maximum: Decimal? = null): DecimalConfigValue { commentRange(minimum, maximum) comment("Default: $defaultValue") return DecimalConfigValue(define(path, defaultValue.toString()), minimum, maximum) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/nbt/CompoundTagExt.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/nbt/CompoundTagExt.kt index f3ff05318..22230c67e 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/nbt/CompoundTagExt.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/core/nbt/CompoundTagExt.kt @@ -79,8 +79,6 @@ fun CompoundTag.mapString(index: String, mapper: (String) -> T, orElse: T): } } -fun CompoundTag.getItemStack(key: String): ItemStack = map(key, ItemStack::of) ?: ItemStack.EMPTY - @Suppress("unchecked_cast") // type is checked inside getList fun CompoundTag.getByteList(key: String): MutableList = getList(key, Tag.TAG_BYTE.toInt()) as MutableList @Suppress("unchecked_cast") // type is checked inside getList diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/ByteBufExtensions.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/ByteBufExtensions.kt index 3949f9121..de70fb81c 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/ByteBufExtensions.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/ByteBufExtensions.kt @@ -10,6 +10,7 @@ import io.netty.handler.codec.DecoderException import io.netty.handler.codec.EncoderException import net.minecraft.nbt.NbtAccounter import net.minecraft.network.FriendlyByteBuf +import net.minecraft.network.RegistryFriendlyByteBuf import net.minecraft.network.chat.Component fun FriendlyByteBuf.readBinaryJson(): JsonElement { @@ -21,27 +22,18 @@ fun FriendlyByteBuf.writeBinaryJson(value: JsonElement) { } fun FriendlyByteBuf.writeBinaryJsonWithCodec(codec: Codec, value: S) { - writeBinaryJson(codec.encode(value, JsonOps.INSTANCE, JsonOps.INSTANCE.empty()) - .get().map({ it }, { throw EncoderException("Failed to encode input data: ${it.message()}") })) + writeBinaryJson(codec.encode(value, JsonOps.INSTANCE, JsonOps.INSTANCE.empty()).mapOrElse({ it }, { throw EncoderException("Failed to encode input data: ${it.message()}") })) } fun FriendlyByteBuf.readBinaryJsonWithCodec(codec: Codec): S { return codec.decode(JsonOps.INSTANCE, readBinaryJson()) - .get().map({ it.first }, { throw DecoderException("Failed to decode data from network: ${it.message()}") }) + .mapOrElse({ it.first }, { throw DecoderException("Failed to decode data from network: ${it.message()}") }) } fun FriendlyByteBuf.readBinaryJsonWithCodecIndirect(codec: Codec): DataResult { return codec.decode(JsonOps.INSTANCE, readBinaryJson()).map { it.first } } -fun FriendlyByteBuf.readBinaryComponent(): Component { - return Component.Serializer.fromJson(readBinaryJson()) ?: throw NullPointerException("Received null component") -} - -fun FriendlyByteBuf.writeBinaryComponent(component: Component) { - writeBinaryJson(Component.Serializer.toJsonTree(component)) -} - // обратный порядок аргументов у лямбда выражения fun FriendlyByteBuf.writeCollection(collection: Collection, writer: (T, FriendlyByteBuf) -> Unit) { writeCollection(collection) { a, b -> writer.invoke(b, a) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/FriendlyStreams.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/FriendlyStreams.kt index 2327a2abf..855ab7541 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/FriendlyStreams.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/FriendlyStreams.kt @@ -1,6 +1,7 @@ package ru.dbotthepony.mc.otm.core.util import io.netty.handler.codec.EncoderException +import net.minecraft.core.registries.BuiltInRegistries import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.NbtAccounter import net.minecraft.nbt.NbtIo @@ -9,9 +10,7 @@ import net.minecraft.resources.ResourceLocation import net.minecraft.world.item.Item import net.minecraft.world.item.ItemStack import net.minecraft.world.level.material.Fluid -import net.minecraftforge.fluids.FluidStack -import net.minecraftforge.registries.ForgeRegistries -import net.minecraftforge.registries.ForgeRegistry +import net.neoforged.neoforge.fluids.FluidStack import java.io.* import java.math.BigDecimal import java.math.BigInteger @@ -43,14 +42,14 @@ fun OutputStream.writeItem(itemStack: ItemStack, limitedTag: Boolean = true) { write(0) } else { write(1) - val id = (ForgeRegistries.ITEMS as ForgeRegistry).getID(itemStack.item) + val id = BuiltInRegistries.ITEM.getId(itemStack.item) writeInt(id) writeInt(itemStack.count) var compoundtag: CompoundTag? = null - if (itemStack.item.isDamageable(itemStack) || itemStack.item.shouldOverrideMultiplayerNbt()) { + if (itemStack.item.isDamageable(itemStack)) { compoundtag = if (limitedTag) itemStack.shareTag else itemStack.tag } @@ -67,7 +66,7 @@ fun InputStream.readItem(): ItemStack { return ItemStack.EMPTY } - val item = (ForgeRegistries.ITEMS as ForgeRegistry).getValue(readInt()) + val item = BuiltInRegistries.ITEM.byId(readInt()) val itemStack = ItemStack(item, readInt()) if (read() != 0) { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/InvalidableLazy.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/InvalidableLazy.kt index f6c16c449..4e93f08b0 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/InvalidableLazy.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/InvalidableLazy.kt @@ -1,5 +1,31 @@ package ru.dbotthepony.mc.otm.core.util +import ru.dbotthepony.kommons.util.KOptional + interface InvalidableLazy : Lazy { fun invalidate() + + class Impl(private val supplier: () -> V) : InvalidableLazy { + private var _value: KOptional = KOptional.empty() + + override val value: V get() { + _value.ifPresent { + return it + }.ifNotPresent { + val v = supplier.invoke() + _value = KOptional(v) + return v + } + + throw RuntimeException() + } + + override fun invalidate() { + _value = KOptional() + } + + override fun isInitialized(): Boolean { + return _value.isPresent + } + } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/ItemSorter.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/ItemSorter.kt index 6319572f0..a0e9ca6dd 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/ItemSorter.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/ItemSorter.kt @@ -7,14 +7,13 @@ import net.minecraft.network.chat.MutableComponent import net.minecraft.world.item.CreativeModeTabs import net.minecraft.world.item.Item import net.minecraft.world.item.ItemStack -import net.minecraftforge.common.CreativeModeTabRegistry +import net.neoforged.neoforge.common.CreativeModeTabRegistry import ru.dbotthepony.mc.otm.client.minecraft import ru.dbotthepony.mc.otm.client.render.IGUIRenderable import ru.dbotthepony.mc.otm.core.TranslatableComponent import ru.dbotthepony.mc.otm.core.nullsFirst import ru.dbotthepony.mc.otm.core.nullsLast import ru.dbotthepony.mc.otm.core.registryName -import ru.dbotthepony.mc.otm.core.suppliers import ru.dbotthepony.mc.otm.matter.MatterManager import ru.dbotthepony.mc.otm.storage.ItemStorageStack import ru.dbotthepony.mc.otm.client.render.Widgets18 diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/LOHolder.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/LOHolder.kt deleted file mode 100644 index 289c1785f..000000000 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/LOHolder.kt +++ /dev/null @@ -1,20 +0,0 @@ -package ru.dbotthepony.mc.otm.core.util - -import net.minecraftforge.common.util.LazyOptional - -class LOHolder(val value: T) { - private var lazyOptional: LazyOptional = LazyOptional.of { value } - - fun invalidate() { - lazyOptional.invalidate() - } - - fun revive() { - lazyOptional.invalidate() - lazyOptional = LazyOptional.of { value } - } - - fun get(): LazyOptional { - return lazyOptional.cast() - } -} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/Savetables.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/Savetables.kt index d422d6851..9d7c2583c 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/Savetables.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/Savetables.kt @@ -2,21 +2,23 @@ package ru.dbotthepony.mc.otm.core.util import com.google.common.collect.ImmutableList import com.mojang.serialization.Codec +import net.minecraft.core.HolderLookup +import net.minecraft.core.HolderLookup.Provider import net.minecraft.nbt.ByteTag import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.DoubleTag import net.minecraft.nbt.FloatTag import net.minecraft.nbt.IntTag -import net.minecraft.nbt.ListTag import net.minecraft.nbt.LongTag import net.minecraft.nbt.NbtOps import net.minecraft.nbt.NumericTag import net.minecraft.nbt.StringTag import net.minecraft.nbt.Tag import net.minecraft.resources.ResourceLocation -import net.minecraftforge.common.util.INBTSerializable +import net.neoforged.neoforge.common.util.INBTSerializable import org.apache.logging.log4j.LogManager import ru.dbotthepony.kommons.util.Delegate +import ru.dbotthepony.mc.otm.core.get import ru.dbotthepony.mc.otm.core.immutableList import ru.dbotthepony.mc.otm.core.math.Decimal import ru.dbotthepony.mc.otm.core.math.Vector @@ -59,20 +61,20 @@ class Savetables : INBTSerializable { fun , T : Tag> stateful(getter: Supplier, name: String, type: Class): Stateful { return Stateful(getter, name, type) - .withSerializer { it.serializeNBT() } - .withDeserializer { v, t -> v.deserializeNBT(t) } + .withSerializer { it, l -> it.serializeNBT(l) } + .withDeserializer { v, t, l -> v.deserializeNBT(l, t) } } fun , T : Tag> stateful(getter: V, name: String, type: Class): Stateful { return Stateful({ getter }, name, type) - .withSerializer { it.serializeNBT() } - .withDeserializer { v, t -> v.deserializeNBT(t) } + .withSerializer { it, l -> it.serializeNBT(l) } + .withDeserializer { v, t, l -> v.deserializeNBT(l, t) } } fun , T : Tag> stateful(getter: KProperty0, name: String = getter.name, type: Class): Stateful { return Stateful(getter, name, type) - .withSerializer { it.serializeNBT() } - .withDeserializer { v, t -> v.deserializeNBT(t) } + .withSerializer { it, l -> it.serializeNBT(l) } + .withDeserializer { v, t, l -> v.deserializeNBT(l, t) } } fun decimal(prop: Delegate, name: String, default: Decimal = Decimal.ZERO): Stateless { @@ -172,8 +174,8 @@ class Savetables : INBTSerializable { fun codecNullable(prop: Delegate, codec: Codec, name: String): Stateless { return Stateless(prop, name, Tag::class.java) - .withSerializer { prop.get()?.let { codec.encode(it, NbtOps.INSTANCE, NbtOps.INSTANCE.empty()).getOrThrow(false) { throw IllegalStateException("Failed to write NBT data for $name: $it") } } } - .withDeserializer { codec.decode(NbtOps.INSTANCE, it).getOrThrow(false) { throw IllegalStateException("Failed to read NBT data for $name: $it") }.first } + .withSerializer { prop.get()?.let { codec.encode(it, NbtOps.INSTANCE, NbtOps.INSTANCE.empty()).getOrThrow() { throw IllegalStateException("Failed to write NBT data for $name: $it") } } } + .withDeserializer { codec.decode(NbtOps.INSTANCE, it).getOrThrow() { throw IllegalStateException("Failed to read NBT data for $name: $it") }.first } } fun codecNullable(prop: KMutableProperty0, codec: Codec, name: String = prop.name): Stateless { @@ -182,8 +184,8 @@ class Savetables : INBTSerializable { fun codecNullable(prop: Delegate, codec: Codec, name: String, default: T?): Stateless { return Stateless(prop, name, Tag::class.java) - .withSerializer { prop.get()?.let { codec.encode(it, NbtOps.INSTANCE, NbtOps.INSTANCE.empty()).getOrThrow(false) { throw IllegalStateException("Failed to write NBT data for $name: $it") } } } - .withDeserializer { codec.decode(NbtOps.INSTANCE, it).get().map({ it.first }, { LOGGER.error("Failed to read NBT data for $name", RuntimeException(it.message())); default }) } + .withSerializer { prop.get()?.let { codec.encode(it, NbtOps.INSTANCE, NbtOps.INSTANCE.empty()).getOrThrow { throw IllegalStateException("Failed to write NBT data for $name: $it") } } } + .withDeserializer { codec.decode(NbtOps.INSTANCE, it).mapOrElse({ it.first }, { LOGGER.error("Failed to read NBT data for $name", RuntimeException(it.message())); default }) } .withDefault { default } } @@ -193,14 +195,14 @@ class Savetables : INBTSerializable { fun codec(prop: Delegate, codec: Codec, name: String): Stateless { return Stateless(prop, name, Tag::class.java) - .withSerializer { codec.encode(prop.get(), NbtOps.INSTANCE, NbtOps.INSTANCE.empty()).getOrThrow(false) { throw IllegalStateException("Failed to write NBT data for $name: $it") } } - .withDeserializer { codec.decode(NbtOps.INSTANCE, it).getOrThrow(false) { throw IllegalStateException("Failed to read NBT data for $name: $it") }.first } + .withSerializer { codec.encode(prop.get(), NbtOps.INSTANCE, NbtOps.INSTANCE.empty()).getOrThrow { throw IllegalStateException("Failed to write NBT data for $name: $it") } } + .withDeserializer { codec.decode(NbtOps.INSTANCE, it).getOrThrow() { throw IllegalStateException("Failed to read NBT data for $name: $it") }.first } } fun codec(prop: Delegate, codec: Codec, name: String, default: T): Stateless { return Stateless(prop, name, Tag::class.java) - .withSerializer { codec.encode(prop.get(), NbtOps.INSTANCE, NbtOps.INSTANCE.empty()).getOrThrow(false) { throw IllegalStateException("Failed to write NBT data for $name: $it") } } - .withDeserializer { codec.decode(NbtOps.INSTANCE, it).get().map({ it.first }, { LOGGER.error("Failed to read NBT data for $name", RuntimeException(it.message())); default }) } + .withSerializer { codec.encode(prop.get(), NbtOps.INSTANCE, NbtOps.INSTANCE.empty()).getOrThrow { throw IllegalStateException("Failed to write NBT data for $name: $it") } } + .withDeserializer { codec.decode(NbtOps.INSTANCE, it).mapOrElse({ it.first }, { LOGGER.error("Failed to read NBT data for $name", RuntimeException(it.message())); default }) } .withDefault { default } } @@ -228,8 +230,8 @@ class Savetables : INBTSerializable { return location(Delegate.Of(prop), name) } - override fun serializeNBT(): CompoundTag { - return CompoundTag().also(::serializeNBT) + override fun serializeNBT(registry: Provider): CompoundTag { + return CompoundTag().also { this.serializeNBT(it, registry) } } private var validated = false @@ -243,31 +245,31 @@ class Savetables : INBTSerializable { validated = true } - override fun deserializeNBT(nbt: CompoundTag?) { + override fun deserializeNBT(registry: Provider, nbt: CompoundTag?) { validate() if (nbt == null) { for (entry in entries) { - entry.deserializeNBT(null) + entry.deserializeNBT(registry, null) } } else { for (entry in entries) { val value = nbt[entry.name] if (value != null && entry.type.isAssignableFrom(value.javaClass)) { - (entry as INBTSerializable).deserializeNBT(value) + (entry as INBTSerializable).deserializeNBT(registry, value) } else { - entry.deserializeNBT(null) + entry.deserializeNBT(registry, null) } } } } - fun serializeNBT(nbt: CompoundTag) { + fun serializeNBT(nbt: CompoundTag, registry: Provider) { validate() for (entry in entries) { - val value = entry.serializeNBT() + val value = entry.serializeNBT(registry) if (value != null) nbt[entry.name] = value @@ -283,16 +285,16 @@ class Savetables : INBTSerializable { validated = false } - private var serializer: ((V) -> T?)? = null - private var deserializer: ((V, T) -> Unit)? = null + private var serializer: ((V, HolderLookup.Provider) -> T?)? = null + private var deserializer: ((V, T, HolderLookup.Provider) -> Unit)? = null private var resetter: ((V) -> Unit)? = null - fun withSerializer(serializer: (V) -> T?): Stateful { + fun withSerializer(serializer: (V, HolderLookup.Provider) -> T?): Stateful { this.serializer = serializer return this } - fun withDeserializer(deserializer: (V, T) -> Unit): Stateful { + fun withDeserializer(deserializer: (V, T, HolderLookup.Provider) -> Unit): Stateful { this.deserializer = deserializer return this } @@ -302,15 +304,15 @@ class Savetables : INBTSerializable { return this } - override fun serializeNBT(): T? { - return checkNotNull(serializer) { "No serializer specified for $name" }.invoke(prop.get()) + override fun serializeNBT(registry: HolderLookup.Provider): T? { + return checkNotNull(serializer) { "No serializer specified for $name" }.invoke(prop.get(), registry) } - override fun deserializeNBT(nbt: T?) { + override fun deserializeNBT(registry: Provider, nbt: T?) { if (nbt == null) { resetter?.invoke(prop.get()) } else { - checkNotNull(deserializer) { "No deserializer specified for $name" }.invoke(prop.get(), nbt) + checkNotNull(deserializer) { "No deserializer specified for $name" }.invoke(prop.get(), nbt, registry) } } @@ -353,11 +355,11 @@ class Savetables : INBTSerializable { return this } - override fun serializeNBT(): T? { + override fun serializeNBT(registry: Provider): T? { return checkNotNull(serializer) { "No serializer specified for $name" }.invoke(prop.get()) } - override fun deserializeNBT(nbt: T?) { + override fun deserializeNBT(registry: Provider, nbt: T?) { if (nbt == null) { if (default != null) { prop.accept(default!!.invoke()) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/StreamCodecs.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/StreamCodecs.kt index 79c8db41b..7d99dd590 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/StreamCodecs.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/StreamCodecs.kt @@ -1,38 +1,22 @@ package ru.dbotthepony.mc.otm.core.util -import com.google.common.collect.ImmutableList -import com.mojang.datafixers.util.Pair -import com.mojang.serialization.Codec -import com.mojang.serialization.DataResult -import com.mojang.serialization.DynamicOps -import net.minecraft.nbt.NbtAccounter import net.minecraft.world.item.ItemStack -import net.minecraftforge.fluids.FluidStack +import net.neoforged.neoforge.fluids.FluidStack import ru.dbotthepony.kommons.io.DelegateSyncher import ru.dbotthepony.kommons.io.StreamCodec import ru.dbotthepony.kommons.util.Delegate import ru.dbotthepony.kommons.util.DelegateGetter import ru.dbotthepony.kommons.util.DelegateSetter import ru.dbotthepony.kommons.util.ListenableDelegate -import ru.dbotthepony.mc.otm.core.immutableMap import ru.dbotthepony.mc.otm.core.math.Decimal -import ru.dbotthepony.kommons.math.RGBAColor import ru.dbotthepony.mc.otm.core.math.readDecimal import ru.dbotthepony.mc.otm.core.math.writeDecimal import ru.dbotthepony.mc.otm.core.readItemType import ru.dbotthepony.mc.otm.core.writeItemType -import java.io.DataInput import java.io.DataInputStream -import java.io.DataOutput import java.io.DataOutputStream -import java.io.InputStream -import java.io.OutputStream import java.util.* -import java.util.function.Predicate import java.util.function.Supplier -import kotlin.NoSuchElementException -import kotlin.math.absoluteValue -import kotlin.reflect.KClass val ItemStackValueCodec = StreamCodec.Impl(DataInputStream::readItem, DataOutputStream::writeItem, ItemStack::copy) { a, b -> a.equals(b, true) } val FluidStackValueCodec = StreamCodec.Impl(DataInputStream::readFluidStack, DataOutputStream::writeFluidStack, FluidStack::copy) { a, b -> a == b && a.amount == b.amount } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/data/Codec2RecipeSerializer.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/data/Codec2RecipeSerializer.kt deleted file mode 100644 index b32702611..000000000 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/data/Codec2RecipeSerializer.kt +++ /dev/null @@ -1,191 +0,0 @@ -package ru.dbotthepony.mc.otm.data - -import com.google.gson.JsonObject -import com.google.gson.JsonParseException -import com.google.gson.JsonSyntaxException -import com.mojang.datafixers.util.Pair -import com.mojang.serialization.Codec -import com.mojang.serialization.DataResult -import com.mojang.serialization.DynamicOps -import com.mojang.serialization.JsonOps -import io.netty.buffer.ByteBuf -import io.netty.buffer.Unpooled -import net.minecraft.advancements.AdvancementHolder -import net.minecraft.data.recipes.FinishedRecipe -import net.minecraft.network.FriendlyByteBuf -import net.minecraft.resources.ResourceLocation -import net.minecraft.world.item.ItemStack -import net.minecraft.world.item.crafting.Ingredient -import net.minecraft.world.item.crafting.Recipe -import net.minecraft.world.item.crafting.RecipeSerializer -import org.apache.logging.log4j.LogManager -import ru.dbotthepony.mc.otm.core.set -import ru.dbotthepony.mc.otm.core.util.readBinaryJsonWithCodecIndirect -import ru.dbotthepony.mc.otm.core.util.writeBinaryJsonWithCodec -import kotlin.collections.ArrayDeque -import kotlin.concurrent.getOrSet -import kotlin.reflect.KProperty - -/** - * 1.20.2: Mojang FINALLY moved json IO of recipes to codecs - * - * ...but they forgot to do the same for Networking them, Ingredient does not have codec for network. - * - * Mojang.... Mojang never changes. - */ -class Codec2RecipeSerializer>( - val empty: S?, - codec: (Codec2RecipeSerializer.Context) -> Codec, -) : Codec, RecipeSerializer { - constructor(supplier: (Codec2RecipeSerializer.Context) -> Codec) : this(null, supplier) - - private class CurrentContext { - var isNetwork = 0 - } - - inner class Context { - val ingredients: Codec get() = ActualIngredientCodec - - fun

> wrap(serializer: RecipeSerializer

): Codec

{ - return object : Codec

{ - override fun encode(input: P, ops: DynamicOps, prefix: T): DataResult { - if (context.isNetwork > 0) { - val parent = Unpooled.buffer() - val buff = FriendlyByteBuf(parent) - serializer.toNetwork(buff, input) - return DataResult.success(ops.createByteList(parent.nioBuffer())) - } else { - return serializer.codec().encode(input, ops, prefix) - } - } - - override fun decode(ops: DynamicOps, input: T): DataResult> { - if (context.isNetwork > 0) { - return ops.getByteBuffer(input).flatMap { - val parent = Unpooled.buffer() - val buff = FriendlyByteBuf(parent) - parent.writeBytes(it) - parent.setIndex(0, 0) - val read = serializer.fromNetwork(buff) - - if (read == null) - DataResult.error { "Unable to read parent recipe from network" } - else - DataResult.success(Pair(read, ops.empty())) - } - } else { - return serializer.codec().decode(ops, input) - } - } - } - } - } - - private val codec = codec.invoke(Context()) - - override fun encode(input: S, ops: DynamicOps, prefix: T): DataResult { - return codec.encode(input, ops, prefix) - } - - override fun decode(ops: DynamicOps, input: T): DataResult> { - return codec.decode(ops, input) - } - - fun > xmap(to: (S) -> O, from: (O) -> S): Codec2RecipeSerializer { - return Codec2RecipeSerializer(empty?.let(to)) { _ -> - codec.xmap(to, from) - } - } - - override fun codec(): Codec { - return this - } - - override fun fromNetwork(data: FriendlyByteBuf): S? { - try { - context.isNetwork++ - return data.readBinaryJsonWithCodecIndirect(this) - .resultOrPartial { LOGGER.error("Failed to read recipe from network: $it") }.orElse(null) - } finally { - context.isNetwork-- - } - } - - override fun toNetwork(data: FriendlyByteBuf, recipe: S) { - try { - context.isNetwork++ - data.writeBinaryJsonWithCodec(this, recipe) - } finally { - context.isNetwork-- - } - } - - fun toFinished(recipe: S, id: ResourceLocation): FinishedRecipe { - return object : FinishedRecipe { - override fun serializeRecipeData(p_125967_: JsonObject) { - encode(recipe, JsonOps.INSTANCE, p_125967_).get().map( - { - it as JsonObject - - for ((k, v) in it.entrySet()) { - p_125967_[k] = v - } - }, - { - throw JsonParseException("Failed to serialize recipe: ${it.message()}") - } - ) - } - - override fun id(): ResourceLocation { - return id - } - - override fun type(): RecipeSerializer<*> { - return this@Codec2RecipeSerializer - } - - override fun advancement(): AdvancementHolder? { - return null - } - } - } - - private object ActualIngredientCodec : Codec { - override fun encode(input: Ingredient, ops: DynamicOps, prefix: T): DataResult { - return if (context.isNetwork > 0) { - networkIngredientCodec.encode(input, ops, prefix) - } else { - Ingredient.CODEC.encode(input, ops, prefix) - } - } - - override fun decode(ops: DynamicOps, input: T): DataResult> { - return if (context.isNetwork > 0) { - networkIngredientCodec.decode(ops, input) - } else { - Ingredient.CODEC.decode(ops, input) - } - } - } - - companion object { - private val LOGGER = LogManager.getLogger() - private val networkIngredientCodec = Codec.list(ItemStack.CODEC).xmap({ Ingredient.of(it.stream()) }, { it.items.toMutableList() }) - - /** - * [ThreadLocal] because optimization mods can (and probably should) parallelize recipe deserialization, - * since RecipeSerializers are expected to be stateless. [Codec2RecipeSerializer], however, is stateful (threading PoV). - * To make it stateless, [ThreadLocal] is used. - */ - private val context by object : ThreadLocal() { - override fun initialValue(): CurrentContext { - return CurrentContext() - } - } - } -} - -private operator fun ThreadLocal.getValue(companion: Codec2RecipeSerializer.Companion, property: KProperty<*>): T { - return get() -} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/data/ComponentCodec.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/data/ComponentCodec.kt deleted file mode 100644 index ec65bb31a..000000000 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/data/ComponentCodec.kt +++ /dev/null @@ -1,25 +0,0 @@ -package ru.dbotthepony.mc.otm.data - -import com.google.gson.JsonSyntaxException -import com.mojang.datafixers.util.Pair -import com.mojang.serialization.Codec -import com.mojang.serialization.DataResult -import com.mojang.serialization.DynamicOps -import com.mojang.serialization.JsonOps -import net.minecraft.network.chat.Component - -object ComponentCodec : Codec { - override fun encode(input: Component, ops: DynamicOps, prefix: T): DataResult { - return DataResult.success(JsonOps.INSTANCE.convertTo(ops, Component.Serializer.toJsonTree(input))) - } - - override fun decode(ops: DynamicOps, input: T): DataResult> { - val value = ops.convertTo(JsonOps.INSTANCE, input) - - try { - return DataResult.success(Pair(Component.Serializer.fromJson(value), ops.empty())) - } catch (err: JsonSyntaxException) { - return DataResult.error { "Error decoding component: ${err.message}" } - } - } -} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/data/DecimalCodec.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/data/DecimalCodec.kt index 062564586..353a4578a 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/data/DecimalCodec.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/data/DecimalCodec.kt @@ -6,14 +6,26 @@ import com.mojang.serialization.DataResult import com.mojang.serialization.DynamicOps import it.unimi.dsi.fastutil.bytes.ByteArrayList import net.minecraft.nbt.NbtOps +import net.minecraft.network.FriendlyByteBuf +import net.minecraft.network.codec.StreamCodec import ru.dbotthepony.mc.otm.core.math.Decimal +import ru.dbotthepony.mc.otm.core.math.Decimal.Companion.fromByteArray import java.nio.ByteBuffer -import java.util.stream.Collector -import java.util.stream.Stream object DecimalCodec : Codec { + val NETWORK = object : StreamCodec { + override fun decode(buf: FriendlyByteBuf): Decimal { + return fromByteArray(buf.readByteArray()) + } + + override fun encode(buf: FriendlyByteBuf, p_320396_: Decimal) { + buf.writeByteArray(p_320396_.toByteArray()) + } + } + override fun encode(input: Decimal, ops: DynamicOps, prefix: T): DataResult { if (ops === NbtOps.INSTANCE) { + // this is a hack, but at least we will get binary representation in binary file return DataResult.success((ops as DynamicOps).createByteList(ByteBuffer.wrap(input.toByteArray()))) } @@ -27,14 +39,14 @@ object DecimalCodec : Codec { } catch (err: NumberFormatException) { DataResult.error { "Not a valid number for converting into Decimal: $it" } } - }.get().map( + }.mapOrElse( { DataResult.success(it) }, { e0 -> ops.getIntStream(input).flatMap { try { - DataResult.success(Pair(Decimal.fromByteArray( + DataResult.success(Pair(fromByteArray( it .collect(::ByteArrayList, { v, a -> v.add(a.toByte()) }, ByteArrayList::addAll) .toByteArray() @@ -42,14 +54,14 @@ object DecimalCodec : Codec { } catch (err: NumberFormatException) { DataResult.error { "Failed to convert array of bytes into Decimal: $it" } } - }.get().map( + }.mapOrElse( { DataResult.success(it) }, { e1 -> ops.getNumberValue(input).flatMap { DataResult.success(Pair(Decimal(it.toString()), ops.empty())) - }.get().map( + }.mapOrElse( { DataResult.success(it) }, diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/data/DecimalProvider.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/data/DecimalProvider.kt index 1143aac1f..442ae3f43 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/data/DecimalProvider.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/data/DecimalProvider.kt @@ -2,14 +2,15 @@ package ru.dbotthepony.mc.otm.data import com.mojang.datafixers.util.Either import com.mojang.serialization.Codec +import com.mojang.serialization.MapCodec import com.mojang.serialization.codecs.RecordCodecBuilder -import net.minecraft.resources.ResourceLocation import net.minecraft.util.RandomSource -import net.minecraftforge.eventbus.api.IEventBus -import net.minecraftforge.registries.DeferredRegister +import net.neoforged.bus.api.IEventBus import ru.dbotthepony.mc.otm.OverdriveThatMatters +import ru.dbotthepony.mc.otm.core.ResourceLocation import ru.dbotthepony.mc.otm.core.math.Decimal import ru.dbotthepony.mc.otm.core.math.nextDecimal +import ru.dbotthepony.mc.otm.registry.MDeferredRegister import ru.dbotthepony.mc.otm.registry.RegistryDelegate fun interface SampledDecimal { @@ -18,7 +19,7 @@ fun interface SampledDecimal { abstract class DecimalProvider : SampledDecimal { interface Type { - val codec: Codec + val codec: MapCodec } abstract val minValue: Decimal @@ -27,13 +28,12 @@ abstract class DecimalProvider : SampledDecimal { companion object { private val registryHolder = RegistryDelegate>("decimal_provider_type") { - setDefaultKey(ResourceLocation(OverdriveThatMatters.MOD_ID, "zero")) - disableSaving() + defaultKey(ResourceLocation(OverdriveThatMatters.MOD_ID, "zero")) } val CODEC: Codec by lazy { Codec - .either(DecimalCodec, registry.codec.dispatch({ it.type }, { it.codec })) + .either(DecimalCodec, registry.byNameCodec().dispatch({ it.type }, { it.codec })) .xmap( { c -> c.map(::ConstantDecimal, { it }) }, { if (it.type === ConstantDecimal.Companion) Either.left(it.minValue) else Either.right(it) } @@ -43,7 +43,7 @@ abstract class DecimalProvider : SampledDecimal { val registry by registryHolder val registryKey get() = registryHolder.key - private val registror = DeferredRegister.create(registryKey, OverdriveThatMatters.MOD_ID) + private val registror = MDeferredRegister(registryKey, OverdriveThatMatters.MOD_ID) init { registror.register("zero") { ConstantDecimal.Zero } @@ -51,7 +51,7 @@ abstract class DecimalProvider : SampledDecimal { registror.register("uniform") { UniformDecimal.Companion } } - internal fun register(bus: IEventBus) { + fun register(bus: IEventBus) { bus.addListener(registryHolder::build) registror.register(bus) } @@ -64,7 +64,7 @@ class ConstantDecimal(val value: Decimal) : DecimalProvider() { return Decimal.ZERO } - override val codec: Codec = Codec.unit(this) + override val codec: MapCodec = MapCodec.unit(this) override val minValue: Decimal get() = Decimal.ZERO @@ -86,7 +86,7 @@ class ConstantDecimal(val value: Decimal) : DecimalProvider() { get() = Companion companion object : Type { - override val codec: Codec = RecordCodecBuilder.create { + override val codec: MapCodec = RecordCodecBuilder.mapCodec { it.group(DecimalCodec.fieldOf("value").forGetter(ConstantDecimal::value)).apply(it, ::ConstantDecimal) } } @@ -107,7 +107,7 @@ class UniformDecimal(override val minValue: Decimal, override val maxValue: Deci get() = Companion companion object : Type { - override val codec: Codec = RecordCodecBuilder.create { + override val codec: MapCodec = RecordCodecBuilder.mapCodec { it.group( DecimalCodec.fieldOf("minValue").forGetter(UniformDecimal::minValue), DecimalCodec.fieldOf("maxValue").forGetter(UniformDecimal::maxValue), diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/data/Ext.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/data/Ext.kt index da9e8fde5..6660f58a2 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/data/Ext.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/data/Ext.kt @@ -12,6 +12,7 @@ import net.minecraft.world.entity.player.Player import net.minecraft.world.level.storage.loot.LootContext import net.minecraft.world.level.storage.loot.parameters.LootContextParam import net.minecraft.world.level.storage.loot.parameters.LootContextParams +import ru.dbotthepony.mc.otm.core.mapOrNull import java.util.Optional import kotlin.reflect.KProperty1 @@ -61,15 +62,15 @@ operator fun LootContext.get(param: LootContextParam): T? { } fun DataResult.getOrNull(): T? { - return get().left().orElse(null) + return mapOrNull { it } } fun LootContext.findPlayer(): Player? { - return getParamOrNull(LootContextParams.DIRECT_KILLER_ENTITY).let { + return getParamOrNull(LootContextParams.DIRECT_ATTACKING_ENTITY).let { if (it != null) it as? Player else - getParamOrNull(LootContextParams.KILLER_ENTITY).let { + getParamOrNull(LootContextParams.ATTACKING_ENTITY).let { if (it != null) it as? Player else getParamOrNull(LootContextParams.THIS_ENTITY) as? Player } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/data/IngredientMatrixCodec.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/data/IngredientMatrixCodec.kt index 12d7117cd..cafb075bb 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/data/IngredientMatrixCodec.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/data/IngredientMatrixCodec.kt @@ -52,7 +52,7 @@ class IngredientMatrixCodec(ingredientCodec: Codec) : Codec decode(ops: DynamicOps, input: T): DataResult> { - return ops.getList(input).get().map( + return ops.getList(input).mapOrElse( { val lines = ArrayList>>() @@ -65,7 +65,7 @@ class IngredientMatrixCodec(ingredientCodec: Codec) : Codec) : Codec - handwrittenCodec.decode(ops, input).get().map( + handwrittenCodec.decode(ops, input).mapOrElse( { DataResult.success(it) }, diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/data/SingletonCodec.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/data/SingletonCodec.kt index eb2ade209..07613af20 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/data/SingletonCodec.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/data/SingletonCodec.kt @@ -1,16 +1,22 @@ package ru.dbotthepony.mc.otm.data -import com.mojang.datafixers.util.Pair -import com.mojang.serialization.Codec import com.mojang.serialization.DataResult import com.mojang.serialization.DynamicOps +import com.mojang.serialization.MapCodec +import com.mojang.serialization.MapLike +import com.mojang.serialization.RecordBuilder +import java.util.stream.Stream -class SingletonCodec(val value: V) : Codec { - override fun encode(input: V, ops: DynamicOps, prefix: T): DataResult { - return DataResult.success(ops.empty()) +class SingletonCodec(val value: V) : MapCodec() { + override fun keys(ops: DynamicOps): Stream { + return Stream.empty() } - override fun decode(ops: DynamicOps, input: T? /* Так то, оно должно быть null */): DataResult> { - return DataResult.success(Pair(value, ops.empty())) + override fun decode(ops: DynamicOps, input: MapLike): DataResult { + return DataResult.success(value) + } + + override fun encode(input: V, ops: DynamicOps, prefix: RecordBuilder): RecordBuilder { + return prefix } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/data/UUIDCodec.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/data/UUIDCodec.kt deleted file mode 100644 index a6fead1fb..000000000 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/data/UUIDCodec.kt +++ /dev/null @@ -1,52 +0,0 @@ -package ru.dbotthepony.mc.otm.data - -import com.mojang.datafixers.util.Pair -import com.mojang.serialization.Codec -import com.mojang.serialization.DataResult -import com.mojang.serialization.DynamicOps -import net.minecraft.nbt.NbtOps -import java.util.UUID -import java.util.stream.LongStream - -// because UUIDUtil codec is in unexpected place -// and can't work with both strings, array of longs and array of ints -object UUIDCodec : Codec { - override fun encode(input: UUID, ops: DynamicOps, prefix: T): DataResult { - if (ops === NbtOps.INSTANCE) { - return DataResult.success((ops as DynamicOps).createLongList(LongStream.of(input.mostSignificantBits, input.leastSignificantBits))) - } - - return DataResult.success(ops.createString(input.toString())) - } - - override fun decode(ops: DynamicOps, input: T): DataResult> { - return ops.getLongStream(input).flatMap { - val l = it.limit(4).toArray() - - if (l.size == 4) { - // 4 int - DataResult.success(Pair(UUID((l[0] shl 32) or l[1], (l[2] shl 32) or l[3]), ops.empty())) - } else if (l.size == 2) { - DataResult.success(Pair(UUID(l[0], l[1]), ops.empty())) - } else { - DataResult.error { "Can't construct UUID from ${l.size} elements" } - } - }.get().map( - { - DataResult.success(it) - }, - { e0 -> - ops.getStringValue(input).map { - Pair(UUID.fromString(it), ops.empty()) - }.get().map( - { - DataResult.success(it) - }, - { - DataResult.error { "Unable to deserialize UUID: ${e0.message()}; ${it.message()}" } - } - ) - } - ) - } -} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/data/condition/ChanceCondition.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/data/condition/ChanceCondition.kt index 4f8316e44..05a2a0c1a 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/data/condition/ChanceCondition.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/data/condition/ChanceCondition.kt @@ -1,6 +1,7 @@ package ru.dbotthepony.mc.otm.data.condition import com.mojang.serialization.Codec +import com.mojang.serialization.MapCodec import com.mojang.serialization.codecs.RecordCodecBuilder import net.minecraft.world.level.storage.loot.LootContext import net.minecraft.world.level.storage.loot.predicates.LootItemCondition @@ -28,8 +29,8 @@ data class ChanceCondition(val chance: Double) : LootItemCondition, LootItemCond } companion object { - val CODEC: Codec by lazy { - RecordCodecBuilder.create { + val CODEC: MapCodec by lazy { + RecordCodecBuilder.mapCodec { it.group( Codec.doubleRange(0.0, 1.0).fieldOf("chance").forGetter(ChanceCondition::chance) ).apply(it, ::ChanceCondition) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/data/condition/ChanceWithPlaytimeCondition.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/data/condition/ChanceWithPlaytimeCondition.kt index 92e501c6d..2f77776e6 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/data/condition/ChanceWithPlaytimeCondition.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/data/condition/ChanceWithPlaytimeCondition.kt @@ -1,6 +1,7 @@ package ru.dbotthepony.mc.otm.data.condition import com.mojang.serialization.Codec +import com.mojang.serialization.MapCodec import com.mojang.serialization.codecs.RecordCodecBuilder import net.minecraft.world.level.storage.loot.LootContext import net.minecraft.world.level.storage.loot.parameters.LootContextParams @@ -48,8 +49,8 @@ data class ChanceWithPlaytimeCondition( } companion object { - val CODEC: Codec by lazy { - RecordCodecBuilder.create { + val CODEC: MapCodec by lazy { + RecordCodecBuilder.mapCodec { it.group( Codec.INT.optionalFieldOf("minPlaytime", 0).forGetter(ChanceWithPlaytimeCondition::minPlaytime), Codec.INT.fieldOf("maxPlaytime").forGetter(ChanceWithPlaytimeCondition::maxPlaytime), diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/data/condition/ItemInInventoryCondition.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/data/condition/ItemInInventoryCondition.kt index f25f12e7d..d103a4966 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/data/condition/ItemInInventoryCondition.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/data/condition/ItemInInventoryCondition.kt @@ -1,6 +1,7 @@ package ru.dbotthepony.mc.otm.data.condition import com.mojang.serialization.Codec +import com.mojang.serialization.MapCodec import com.mojang.serialization.codecs.RecordCodecBuilder import net.minecraft.world.item.ItemStack import net.minecraft.world.level.storage.loot.LootContext @@ -14,25 +15,12 @@ import ru.dbotthepony.mc.otm.registry.MLootItemConditions data class ItemInInventoryCondition( val item: ItemStack, - val matchDamage: Boolean = false, - val matchNBT: Boolean = false, + val matchComponents: Boolean = false, val matchCosmetics: Boolean = true, ) : LootItemCondition, LootItemCondition.Builder { override fun test(t: LootContext): Boolean { val matches = t[LootContextParams.LAST_DAMAGE_PLAYER]?.items(matchCosmetics)?.filter { - if (it.isEmpty) { - return@filter false - } - - if (matchDamage && matchNBT) { - it.item == item.item && it.tag == item.tag && it.damageValue == item.damageValue - } else if (matchDamage) { - it.item == item.item && it.damageValue == item.damageValue - } else if (matchNBT) { - it.item == item.item && it.tag == item.tag - } else { - it.item == item.item - } + !it.isEmpty && it.item == item.item && (!matchComponents || it.components == item.components) } ?: return false var count = 0 @@ -57,12 +45,11 @@ data class ItemInInventoryCondition( } companion object { - val CODEC: Codec by lazy { - RecordCodecBuilder.create { + val CODEC: MapCodec by lazy { + RecordCodecBuilder.mapCodec { it.group( ItemStack.CODEC.fieldOf("item").forGetter(ItemInInventoryCondition::item), - Codec.BOOL.optionalFieldOf("matchDamage", false).forGetter(ItemInInventoryCondition::matchDamage), - Codec.BOOL.optionalFieldOf("matchNBT", false).forGetter(ItemInInventoryCondition::matchNBT), + Codec.BOOL.optionalFieldOf("matchComponents", false).forGetter(ItemInInventoryCondition::matchComponents), Codec.BOOL.optionalFieldOf("matchCosmetics", false).forGetter(ItemInInventoryCondition::matchCosmetics), ).apply(it, ::ItemInInventoryCondition) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/data/condition/KilledByRealPlayerOrIndirectly.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/data/condition/KilledByRealPlayerOrIndirectly.kt index b181ada7a..624ad09fb 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/data/condition/KilledByRealPlayerOrIndirectly.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/data/condition/KilledByRealPlayerOrIndirectly.kt @@ -16,8 +16,8 @@ object KilledByRealPlayerOrIndirectly : LootItemCondition, LootItemCondition.Bui return true } - if (t.hasParam(LootContextParams.KILLER_ENTITY)) { - val killer = t[LootContextParams.KILLER_ENTITY] as? OwnableEntity + if (t.hasParam(LootContextParams.ATTACKING_ENTITY)) { + val killer = t[LootContextParams.ATTACKING_ENTITY] as? OwnableEntity if (killer != null) { val owner = killer.owner diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/data/loot/CopyTileNbtFunction.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/data/loot/CopyTileNbtFunction.kt index 5cd4f3c64..c97a73f92 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/data/loot/CopyTileNbtFunction.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/data/loot/CopyTileNbtFunction.kt @@ -2,6 +2,7 @@ package ru.dbotthepony.mc.otm.data.loot import com.google.common.collect.ImmutableList import com.mojang.serialization.Codec +import com.mojang.serialization.MapCodec import com.mojang.serialization.codecs.RecordCodecBuilder import net.minecraft.nbt.CompoundTag import net.minecraft.network.chat.Component @@ -15,7 +16,6 @@ import ru.dbotthepony.mc.otm.block.entity.MatteryBlockEntity import ru.dbotthepony.mc.otm.core.nbt.getJson import ru.dbotthepony.mc.otm.core.nbt.set import ru.dbotthepony.mc.otm.core.stream -import ru.dbotthepony.mc.otm.core.tagNotNull import ru.dbotthepony.mc.otm.registry.MItemFunctionTypes import java.util.Optional import java.util.stream.Stream @@ -73,8 +73,8 @@ class CopyTileNbtFunction(filter: Stream = Stream.empty()) : LootIte } companion object { - val CODEC: Codec by lazy { - RecordCodecBuilder.create { + val CODEC: MapCodec by lazy { + RecordCodecBuilder.mapCodec { it.group( Codec.STRING.listOf() .optionalFieldOf("filter") diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/data/loot/LootPoolAppender.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/data/loot/LootPoolAppender.kt index 99556a944..514745168 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/data/loot/LootPoolAppender.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/data/loot/LootPoolAppender.kt @@ -1,15 +1,15 @@ package ru.dbotthepony.mc.otm.data.loot import com.google.common.collect.ImmutableList -import com.mojang.serialization.Codec +import com.mojang.serialization.MapCodec import com.mojang.serialization.codecs.RecordCodecBuilder import it.unimi.dsi.fastutil.objects.ObjectArrayList import net.minecraft.world.item.ItemStack import net.minecraft.world.level.storage.loot.LootContext import net.minecraft.world.level.storage.loot.LootPool import net.minecraft.world.level.storage.loot.predicates.LootItemCondition -import net.minecraftforge.common.loot.IGlobalLootModifier -import net.minecraftforge.common.loot.LootModifier +import net.neoforged.neoforge.common.loot.IGlobalLootModifier +import net.neoforged.neoforge.common.loot.LootModifier import java.util.* import java.util.stream.Stream @@ -27,13 +27,13 @@ class LootPoolAppender(conditions: Array, pools: Stream { + override fun codec(): MapCodec { return CODEC } companion object { - val CODEC: Codec = - RecordCodecBuilder.create { + val CODEC: MapCodec = + RecordCodecBuilder.mapCodec { codecStart(it).and( LootPool.CODEC.listOf().fieldOf("pools").forGetter(LootPoolAppender::pools) ).apply(it, ::LootPoolAppender) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/entity/MinecartCargoCrate.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/entity/MinecartCargoCrate.kt index 8e55da5e9..3e9863b8b 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/entity/MinecartCargoCrate.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/entity/MinecartCargoCrate.kt @@ -76,9 +76,9 @@ class MinecartCargoCrate( return ItemStack(item, 1) } - override fun defineSynchedData() { - super.defineSynchedData() - entityData.define(INTERACTING_PLAYERS, 0) + override fun defineSynchedData(p_326003_: SynchedEntityData.Builder) { + super.defineSynchedData(p_326003_) + p_326003_.define(INTERACTING_PLAYERS, 0) } var interactingPlayers by entityData.delegate(INTERACTING_PLAYERS) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/entity/PlasmaProjectile.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/entity/PlasmaProjectile.kt index 405a5f41f..a876e4c90 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/entity/PlasmaProjectile.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/entity/PlasmaProjectile.kt @@ -1,7 +1,7 @@ package ru.dbotthepony.mc.otm.entity import net.minecraft.core.particles.ParticleTypes -import net.minecraft.world.entity.EntityType +import net.minecraft.network.syncher.SynchedEntityData import net.minecraft.world.entity.projectile.Projectile import net.minecraft.world.entity.projectile.ProjectileUtil import net.minecraft.world.item.ItemStack @@ -11,18 +11,18 @@ import net.minecraft.world.level.block.LevelEvent import net.minecraft.world.phys.BlockHitResult import net.minecraft.world.phys.EntityHitResult import net.minecraft.world.phys.HitResult -import net.minecraftforge.event.ForgeEventFactory +import net.neoforged.neoforge.event.EventHooks import ru.dbotthepony.mc.otm.core.damageType import ru.dbotthepony.mc.otm.registry.MDamageTypes import ru.dbotthepony.mc.otm.registry.MEntityTypes import ru.dbotthepony.mc.otm.registry.MatteryDamageSource -class PlasmaProjectile(level: Level) : Projectile(MEntityTypes.PLASMA as EntityType, level) { +class PlasmaProjectile(level: Level) : Projectile(MEntityTypes.PLASMA, level) { var inflictor: ItemStack? = null var damage = 6.0f var ttl = 200 - override fun defineSynchedData() { + override fun defineSynchedData(p_326003_: SynchedEntityData.Builder) { } @@ -71,7 +71,7 @@ class PlasmaProjectile(level: Level) : Projectile(MEntityTypes.PLASMA as EntityT } } - if (trace.type != HitResult.Type.MISS && !ForgeEventFactory.onProjectileImpact(this, trace)) { + if (trace.type != HitResult.Type.MISS && !EventHooks.onProjectileImpact(this, trace)) { onHit(trace) } @@ -106,8 +106,4 @@ class PlasmaProjectile(level: Level) : Projectile(MEntityTypes.PLASMA as EntityT setPos(x, y, z) } - - companion object { - - } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/graph/GraphNode.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/graph/GraphNode.kt index 86d5f126e..151f87c8d 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/graph/GraphNode.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/graph/GraphNode.kt @@ -7,10 +7,9 @@ import net.minecraft.core.Direction import net.minecraft.core.SectionPos import net.minecraft.server.level.ServerLevel import net.minecraft.world.level.block.entity.BlockEntity -import net.minecraftforge.common.capabilities.Capability +import net.neoforged.neoforge.capabilities.BlockCapability import ru.dbotthepony.mc.otm.addTicker import ru.dbotthepony.mc.otm.core.math.plus -import ru.dbotthepony.mc.otm.core.orNull import ru.dbotthepony.mc.otm.core.util.IConditionalTickable import ru.dbotthepony.mc.otm.core.util.ITickable import java.util.* @@ -165,12 +164,12 @@ open class GraphNode, G : GraphNodeList>(val graphFact fun discover( level: ServerLevel, blockPos: BlockPos, - capability: Capability + capability: BlockCapability ) { if (!isValid) return level.addTicker { - isValid && !discoverStep(level, blockPos) { it.getCapability(capability).orNull() } + isValid && !discoverStep(level, blockPos) { level.getCapability(capability, blockPos, level.getBlockState(blockPos), it, null) } } } @@ -178,7 +177,7 @@ open class GraphNode, G : GraphNodeList>(val graphFact discover(blockEntity.level as? ServerLevel ?: return, blockEntity.blockPos, nodeGetter) } - fun discover(blockEntity: BlockEntity, capability: Capability) { + fun discover(blockEntity: BlockEntity, capability: BlockCapability) { discover(blockEntity.level as? ServerLevel ?: return, blockEntity.blockPos, capability) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/item/BatteryItem.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/item/BatteryItem.kt index 183d94078..7e33e097c 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/item/BatteryItem.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/item/BatteryItem.kt @@ -12,12 +12,10 @@ import net.minecraft.world.entity.LivingEntity import net.minecraft.world.entity.player.Player import net.minecraft.world.item.* import net.minecraft.world.level.Level -import net.minecraftforge.common.capabilities.ForgeCapabilities -import net.minecraftforge.common.capabilities.ICapabilityProvider +import net.neoforged.neoforge.capabilities.Capabilities import ru.dbotthepony.mc.otm.config.BatteryBalanceValues import ru.dbotthepony.mc.otm.capability.* import ru.dbotthepony.mc.otm.capability.energy.EnergyCapacitorItem -import ru.dbotthepony.mc.otm.capability.energy.ItemEnergyStorageImpl import ru.dbotthepony.mc.otm.capability.energy.getBarColor import ru.dbotthepony.mc.otm.capability.energy.getBarWidth import ru.dbotthepony.mc.otm.client.minecraft @@ -108,13 +106,14 @@ open class BatteryItem : MatteryItem { } override fun initCapabilities(stack: ItemStack, nbt: CompoundTag?): ICapabilityProvider { + stack.getCapability() return EnergyCapacitorItem(stack, this@BatteryItem.capacity, this@BatteryItem.receive, this@BatteryItem.extract, initialBatteryLevel = this@BatteryItem.initialBatteryLevel) } } class CrudeBatteryItem : BatteryItem(ItemsConfig.Batteries.CRUDE) { init { - tooltips.addNormal { itemStack, acceptor -> + tooltips.addNormal { itemStack, context, acceptor -> val isAndroid = runIfClient(false) { minecraft.player?.matteryPlayer?.isAndroid ?: false } if (isAndroid) { @@ -128,7 +127,7 @@ class CrudeBatteryItem : BatteryItem(ItemsConfig.Batteries.CRUDE) { return UseAnim.BOW } - override fun getUseDuration(itemStack: ItemStack): Int { + override fun getUseDuration(itemStack: ItemStack, p_344979_: LivingEntity): Int { return 100 } @@ -148,7 +147,7 @@ class CrudeBatteryItem : BatteryItem(ItemsConfig.Batteries.CRUDE) { if (player is ServerPlayer) { if (!mattery.androidEnergy.item.isEmpty) { - mattery.androidEnergy.item.getCapability(ForgeCapabilities.ENERGY).ifPresentK { + mattery.androidEnergy.item.getCapability(Capabilities.EnergyStorage.ITEM)?.let { it.extractEnergy((it.maxEnergyStored * level.random.nextFloat() * .2f).roundToInt(), false) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/item/ChestUpgraderItem.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/item/ChestUpgraderItem.kt index 2a0af4fcf..ffee079ab 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/item/ChestUpgraderItem.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/item/ChestUpgraderItem.kt @@ -21,6 +21,7 @@ import net.minecraft.world.level.gameevent.GameEvent import net.minecraft.world.level.storage.loot.LootParams import net.minecraft.world.level.storage.loot.parameters.LootContextParams import net.minecraftforge.event.entity.player.PlayerInteractEvent +import net.neoforged.neoforge.event.entity.player.PlayerInteractEvent import ru.dbotthepony.mc.otm.OverdriveThatMatters.MOD_ID import ru.dbotthepony.mc.otm.block.decorative.CargoCrateBlock import ru.dbotthepony.mc.otm.block.entity.decorative.CargoCrateBlockEntity diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/item/FluidCapsuleItem.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/item/FluidCapsuleItem.kt index c070a58a0..7822330e7 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/item/FluidCapsuleItem.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/item/FluidCapsuleItem.kt @@ -2,7 +2,6 @@ package ru.dbotthepony.mc.otm.item import net.minecraft.core.BlockPos import net.minecraft.core.Direction -import net.minecraft.nbt.CompoundTag import net.minecraft.network.chat.Component import net.minecraft.server.level.ServerLevel import net.minecraft.sounds.SoundEvent @@ -12,9 +11,7 @@ import net.minecraft.world.InteractionHand import net.minecraft.world.InteractionResult import net.minecraft.world.InteractionResultHolder import net.minecraft.world.entity.player.Player -import net.minecraft.world.item.Item import net.minecraft.world.item.ItemStack -import net.minecraft.world.item.TooltipFlag import net.minecraft.world.item.context.UseOnContext import net.minecraft.world.level.ClipContext import net.minecraft.world.level.Level @@ -26,27 +23,25 @@ import net.minecraft.world.level.block.state.BlockState import net.minecraft.world.level.material.Fluid import net.minecraft.world.level.material.Fluids import net.minecraft.world.phys.HitResult -import net.minecraftforge.common.SoundActions -import net.minecraftforge.common.capabilities.ForgeCapabilities -import net.minecraftforge.common.capabilities.ICapabilityProvider -import net.minecraftforge.fluids.FluidStack -import net.minecraftforge.fluids.FluidUtil -import net.minecraftforge.fluids.capability.IFluidHandler +import net.neoforged.neoforge.capabilities.Capabilities +import net.neoforged.neoforge.capabilities.RegisterCapabilitiesEvent +import net.neoforged.neoforge.common.SoundActions +import net.neoforged.neoforge.fluids.FluidStack +import net.neoforged.neoforge.fluids.FluidUtil +import net.neoforged.neoforge.fluids.capability.IFluidHandler import ru.dbotthepony.mc.otm.capability.fluid.ItemMatteryFluidHandler -import ru.dbotthepony.mc.otm.capability.fluidLevel import ru.dbotthepony.mc.otm.capability.fluid.iterator import ru.dbotthepony.mc.otm.capability.moveFluid import ru.dbotthepony.mc.otm.container.get import ru.dbotthepony.mc.otm.core.TranslatableComponent import ru.dbotthepony.mc.otm.core.collect.any -import ru.dbotthepony.mc.otm.core.ifPresentK import ru.dbotthepony.mc.otm.core.immutableList import ru.dbotthepony.mc.otm.core.immutableMap import ru.dbotthepony.mc.otm.core.isNotEmpty -import ru.dbotthepony.mc.otm.core.orNull +import ru.dbotthepony.mc.otm.registry.CapabilitiesRegisterListener import java.util.function.IntSupplier -class FluidCapsuleItem(val capacity: IntSupplier) : MatteryItem(Properties().stacksTo(64)) { +class FluidCapsuleItem(val capacity: IntSupplier) : MatteryItem(Properties().stacksTo(64)), CapabilitiesRegisterListener { // TODO: Так как использование предмета заблокировано за player.abilities.canBuild // капсулу нельзя использовать в режиме приключения // почему же можно использовать вёдра на котлах? @@ -60,11 +55,15 @@ class FluidCapsuleItem(val capacity: IntSupplier) : MatteryItem(Properties().sta return super.onItemUseFirst(stack, pContext) } + override fun registerCapabilities(event: RegisterCapabilitiesEvent) { + event.registerItem(Capabilities.FluidHandler.ITEM, { o, c -> ItemMatteryFluidHandler(o, capacity) }, this) + } + override fun getName(pStack: ItemStack): Component { - pStack.getCapability(ForgeCapabilities.FLUID_HANDLER_ITEM).ifPresentK { + pStack.getCapability(Capabilities.FluidHandler.ITEM)?.let { it.getFluidInTank(0).also { if (!it.isEmpty) { - return TranslatableComponent("$descriptionId.named", it.displayName) + return TranslatableComponent("$descriptionId.named", it.hoverName) } } } @@ -76,14 +75,10 @@ class FluidCapsuleItem(val capacity: IntSupplier) : MatteryItem(Properties().sta tooltips.itemFluid() } - override fun initCapabilities(stack: ItemStack, nbt: CompoundTag?): ICapabilityProvider { - return ItemMatteryFluidHandler(stack, capacity) - } - override fun use(level: Level, player: Player, hand: InteractionHand): InteractionResultHolder { val item = player.getItemInHand(hand) var targetItem = item.copyWithCount(1) - val cap = targetItem.getCapability(ForgeCapabilities.FLUID_HANDLER_ITEM).orNull() ?: return InteractionResultHolder.fail(item) + val cap = targetItem.getCapability(Capabilities.FluidHandler.ITEM) ?: return InteractionResultHolder.fail(item) val fluid = cap.getFluidInTank(0) if (fluid.isNotEmpty && fluid.amount != 1000) return InteractionResultHolder.pass(item) @@ -147,7 +142,7 @@ class FluidCapsuleItem(val capacity: IntSupplier) : MatteryItem(Properties().sta val targetItem = if (item.count == 1) item else item.copyWithCount(1) - val cap = targetItem.getCapability(ForgeCapabilities.FLUID_HANDLER_ITEM).orNull() ?: return InteractionResult.FAIL + val cap = targetItem.getCapability(Capabilities.FluidHandler.ITEM) ?: return InteractionResult.FAIL for ((fluid, newState, soundEvent) in mapping) { val toDrain = FluidStack(fluid, 1000) @@ -190,7 +185,7 @@ class FluidCapsuleItem(val capacity: IntSupplier) : MatteryItem(Properties().sta val targetItem = if (item.count == 1) item else item.copyWithCount(1) - val cap = targetItem.getCapability(ForgeCapabilities.FLUID_HANDLER_ITEM).orNull() ?: return InteractionResult.FAIL + val cap = targetItem.getCapability(Capabilities.FluidHandler.ITEM) ?: return InteractionResult.FAIL val mapped = mapping[context.blockState] ?: return InteractionResult.FAIL val toFill = FluidStack(mapped.first, 1000) @@ -218,8 +213,8 @@ class FluidCapsuleItem(val capacity: IntSupplier) : MatteryItem(Properties().sta private object FillEmptyCapability : Interaction { override fun canInteract(item: ItemStack, player: Player, context: Context): Boolean { - val target = player.level().getBlockEntity(context.blockPos)?.getCapability(ForgeCapabilities.FLUID_HANDLER, context.side)?.orNull() ?: return false - val cap = item.getCapability(ForgeCapabilities.FLUID_HANDLER_ITEM).orNull() ?: return false + val target = player.level().getCapability(Capabilities.FluidHandler.BLOCK, context.blockPos, context.side) ?: return false + val cap = item.getCapability(Capabilities.FluidHandler.ITEM) ?: return false return target.iterator().any { !it.isEmpty } || cap.iterator().any { !it.isEmpty } } @@ -228,8 +223,8 @@ class FluidCapsuleItem(val capacity: IntSupplier) : MatteryItem(Properties().sta val targetItem = if (item.count == 1) item else item.copyWithCount(1) - val itemCap = targetItem.getCapability(ForgeCapabilities.FLUID_HANDLER_ITEM).orNull() ?: return InteractionResult.FAIL - val blockCap = player.level().getBlockEntity(context.blockPos)?.getCapability(ForgeCapabilities.FLUID_HANDLER, context.side)?.orNull() ?: return InteractionResult.FAIL + val itemCap = targetItem.getCapability(Capabilities.FluidHandler.ITEM) ?: return InteractionResult.FAIL + val blockCap = player.level().getCapability(Capabilities.FluidHandler.BLOCK, context.blockPos, context.side) ?: return InteractionResult.FAIL val fluid = itemCap[0] if (fluid.isEmpty) { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/item/FluidTankItem.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/item/FluidTankItem.kt index 168385514..1474eafd9 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/item/FluidTankItem.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/item/FluidTankItem.kt @@ -1,41 +1,35 @@ package ru.dbotthepony.mc.otm.item import net.minecraft.client.renderer.BlockEntityWithoutLevelRenderer -import net.minecraft.nbt.CompoundTag import net.minecraft.network.chat.Component import net.minecraft.world.InteractionResult import net.minecraft.world.item.BlockItem import net.minecraft.world.item.ItemStack import net.minecraft.world.item.TooltipFlag import net.minecraft.world.item.context.UseOnContext -import net.minecraft.world.level.Level -import net.minecraftforge.client.extensions.common.IClientItemExtensions -import net.minecraftforge.common.capabilities.ForgeCapabilities -import net.minecraftforge.common.capabilities.ICapabilityProvider +import net.neoforged.neoforge.capabilities.Capabilities +import net.neoforged.neoforge.capabilities.RegisterCapabilitiesEvent +import net.neoforged.neoforge.client.extensions.common.IClientItemExtensions import ru.dbotthepony.mc.otm.block.decorative.FluidTankBlock import ru.dbotthepony.mc.otm.block.entity.decorative.FluidTankBlockEntity -import ru.dbotthepony.mc.otm.capability.FlowDirection -import ru.dbotthepony.mc.otm.capability.MatteryCapability -import ru.dbotthepony.mc.otm.capability.energy.BlockEnergyStorageImpl import ru.dbotthepony.mc.otm.capability.fluid.BlockMatteryFluidHandler -import ru.dbotthepony.mc.otm.capability.fluidLevel import ru.dbotthepony.mc.otm.client.render.blockentity.FluidTankRenderer -import ru.dbotthepony.mc.otm.config.MachinesConfig import ru.dbotthepony.mc.otm.core.TooltipList import ru.dbotthepony.mc.otm.core.TranslatableComponent -import ru.dbotthepony.mc.otm.core.ifPresentK +import ru.dbotthepony.mc.otm.registry.CapabilitiesRegisterListener import java.util.function.Consumer import java.util.function.IntSupplier -class FluidTankItem(block: FluidTankBlock, properties: Properties, val capacity: IntSupplier) : BlockItem(block, properties) { +class FluidTankItem(block: FluidTankBlock, properties: Properties, val capacity: IntSupplier) : BlockItem(block, properties), + CapabilitiesRegisterListener { val tooltips = TooltipList() init { tooltips.itemFluid() } - override fun initCapabilities(stack: ItemStack, nbt: CompoundTag?): ICapabilityProvider { - return BlockMatteryFluidHandler.Item(stack, capacity, FluidTankBlockEntity.FLUID_KEY) + override fun registerCapabilities(event: RegisterCapabilitiesEvent) { + event.registerItem(Capabilities.FluidHandler.ITEM, { o, c -> BlockMatteryFluidHandler.Item(o, capacity, FluidTankBlockEntity.FLUID_KEY) }, this) } override fun onItemUseFirst(stack: ItemStack, pContext: UseOnContext): InteractionResult { @@ -51,10 +45,10 @@ class FluidTankItem(block: FluidTankBlock, properties: Properties, val capacity: } override fun getName(pStack: ItemStack): Component { - pStack.getCapability(ForgeCapabilities.FLUID_HANDLER_ITEM).ifPresentK { + pStack.getCapability(Capabilities.FluidHandler.ITEM)?.let { it.getFluidInTank(0).also { if (!it.isEmpty) { - return TranslatableComponent("$descriptionId.named", it.displayName) + return TranslatableComponent("$descriptionId.named", it.hoverName) } } } @@ -62,9 +56,14 @@ class FluidTankItem(block: FluidTankBlock, properties: Properties, val capacity: return super.getName(pStack) } - override fun appendHoverText(pStack: ItemStack, pLevel: Level?, pTooltip: MutableList, pFlag: TooltipFlag) { - super.appendHoverText(pStack, pLevel, pTooltip, pFlag) - tooltips.assemble(pStack, pTooltip::add) + override fun appendHoverText( + pStack: ItemStack, + p_339594_: TooltipContext, + pTooltip: MutableList, + pFlag: TooltipFlag + ) { + super.appendHoverText(pStack, p_339594_, pTooltip, pFlag) + tooltips.assemble(pStack, p_339594_, pTooltip::add) } override fun initializeClient(consumer: Consumer) { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/item/GravitationalDisruptorItem.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/item/GravitationalDisruptorItem.kt index 4839d319f..b2ac1e5c8 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/item/GravitationalDisruptorItem.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/item/GravitationalDisruptorItem.kt @@ -14,11 +14,11 @@ class GravitationalDisruptorItem : Item(Properties().stacksTo(1).rarity(Rarity.EPIC)) { override fun appendHoverText( p_41421_: ItemStack, - p_41422_: Level?, + p_339594_: TooltipContext, list: MutableList, p_41424_: TooltipFlag ) { - super.appendHoverText(p_41421_, p_41422_, list, p_41424_) + super.appendHoverText(p_41421_, p_339594_, list, p_41424_) list.add(DESCRIPTION) list.add(DESCRIPTION2) list.add(DESCRIPTION3) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/item/MatteryItem.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/item/MatteryItem.kt index d74a6294c..2670c9320 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/item/MatteryItem.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/item/MatteryItem.kt @@ -13,9 +13,9 @@ import ru.dbotthepony.mc.otm.core.TranslatableComponent open class MatteryItem(properties: Properties) : Item(properties) { val tooltips = TooltipList() - override fun appendHoverText(itemStack: ItemStack, level: Level?, components: MutableList, tooltipType: TooltipFlag) { - super.appendHoverText(itemStack, level, components, tooltipType) - tooltips.assemble(itemStack, components) + override fun appendHoverText(itemStack: ItemStack, context: TooltipContext, components: MutableList, tooltipType: TooltipFlag) { + super.appendHoverText(itemStack, context, components, tooltipType) + tooltips.assemble(itemStack, context, components) } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/item/PillItem.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/item/PillItem.kt index 8b0f17bb1..0b58ee83d 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/item/PillItem.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/item/PillItem.kt @@ -13,13 +13,14 @@ import net.minecraft.world.item.* import net.minecraft.world.level.Level import ru.dbotthepony.mc.otm.core.TranslatableComponent import ru.dbotthepony.mc.otm.capability.MatteryCapability +import ru.dbotthepony.mc.otm.capability.matteryPlayer enum class PillType { BECOME_ANDROID, BECOME_HUMANE, OBLIVION } class HealPillItem : MatteryItem(Properties().stacksTo(64).rarity(Rarity.UNCOMMON)) { - override fun getUseDuration(itemStack: ItemStack): Int { + override fun getUseDuration(itemStack: ItemStack, p_344979_: LivingEntity): Int { return 24 } @@ -29,9 +30,7 @@ class HealPillItem : MatteryItem(Properties().stacksTo(64).rarity(Rarity.UNCOMMO } override fun use(level: Level, ply: Player, hand: InteractionHand): InteractionResultHolder { - val resolver = ply.getCapability(MatteryCapability.MATTERY_PLAYER).resolve() - - if (!resolver.isEmpty && resolver.get().isAndroid) + if (ply.matteryPlayer.isAndroid) return super.use(level, ply, hand) ply.startUsingItem(hand) @@ -39,16 +38,13 @@ class HealPillItem : MatteryItem(Properties().stacksTo(64).rarity(Rarity.UNCOMMO } override fun finishUsingItem(stack: ItemStack, level: Level, ent: LivingEntity): ItemStack { - val resolver = ent.getCapability(MatteryCapability.MATTERY_PLAYER).resolve() - - if (!resolver.isEmpty && resolver.get().isAndroid) + if (ent.matteryPlayer?.isAndroid == true) return super.finishUsingItem(stack, level, ent) stack.shrink(1) ent.addEffect(MobEffectInstance(MobEffects.ABSORPTION, 20 * 60 * 2, 4)) ent.addEffect(MobEffectInstance(MobEffects.REGENERATION, 20 * 8, 2)) ent.heal(8f) - return stack } @@ -69,17 +65,12 @@ class PillItem(val pillType: PillType) : MatteryItem(Properties().stacksTo(64).r } } - override fun getUseDuration(p_41454_: ItemStack): Int { + override fun getUseDuration(p_41454_: ItemStack, p_344979_: LivingEntity): Int { return 32 } override fun use(level: Level, ply: Player, hand: InteractionHand): InteractionResultHolder { - val resolver = ply.getCapability(MatteryCapability.MATTERY_PLAYER).resolve() - - if (resolver.isEmpty) - return super.use(level, ply, hand) - - val cap = resolver.get() + val cap = ply.matteryPlayer if ( pillType == PillType.BECOME_ANDROID && !cap.isEverAndroid || @@ -95,12 +86,7 @@ class PillItem(val pillType: PillType) : MatteryItem(Properties().stacksTo(64).r override fun finishUsingItem(stack: ItemStack, level: Level, ent: LivingEntity): ItemStack { if (ent is Player) { - val resolver = ent.getCapability(MatteryCapability.MATTERY_PLAYER).resolve() - - if (resolver.isEmpty) - return super.finishUsingItem(stack, level, ent) - - val cap = resolver.get() + val cap = ent.matteryPlayer if (pillType == PillType.OBLIVION && cap.isAndroid) { if (!ent.abilities.instabuild) { @@ -137,7 +123,7 @@ class PillItem(val pillType: PillType) : MatteryItem(Properties().stacksTo(64).r } } - return stack; + return stack } return super.finishUsingItem(stack, level, ent) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/item/PortableCondensationDriveItem.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/item/PortableCondensationDriveItem.kt index 5a36f6891..dc9c23b7f 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/item/PortableCondensationDriveItem.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/item/PortableCondensationDriveItem.kt @@ -1,150 +1,107 @@ package ru.dbotthepony.mc.otm.item -import net.minecraft.world.item.ItemStack -import net.minecraftforge.common.capabilities.ICapabilityProvider -import net.minecraftforge.common.util.LazyOptional -import ru.dbotthepony.mc.otm.capability.drive.IMatteryDrive -import ru.dbotthepony.mc.otm.capability.drive.ItemMatteryDrive -import net.minecraft.nbt.CompoundTag -import ru.dbotthepony.mc.otm.capability.MatteryCapability -import net.minecraft.world.item.TooltipFlag import net.minecraft.ChatFormatting -import net.minecraft.core.Direction +import net.minecraft.nbt.CompoundTag import net.minecraft.network.chat.Component import net.minecraft.stats.Stats import net.minecraft.world.item.Item -import net.minecraft.world.level.Level -import net.minecraftforge.common.capabilities.Capability -import net.minecraftforge.event.ForgeEventFactory -import net.minecraftforge.event.entity.player.EntityItemPickupEvent -import ru.dbotthepony.mc.otm.core.TextComponent +import net.minecraft.world.item.ItemStack +import net.minecraft.world.item.TooltipFlag +import net.neoforged.neoforge.capabilities.RegisterCapabilitiesEvent +import net.neoforged.neoforge.common.util.TriState +import net.neoforged.neoforge.event.entity.player.ItemEntityPickupEvent +import ru.dbotthepony.mc.otm.capability.MatteryCapability import ru.dbotthepony.mc.otm.capability.drive.DrivePool +import ru.dbotthepony.mc.otm.capability.drive.ItemMatteryDrive import ru.dbotthepony.mc.otm.container.ItemFilter -import ru.dbotthepony.mc.otm.core.nbt.map -import ru.dbotthepony.mc.otm.core.nbt.set -import ru.dbotthepony.mc.otm.core.tagNotNull +import ru.dbotthepony.mc.otm.core.TextComponent import ru.dbotthepony.mc.otm.isServerThread +import ru.dbotthepony.mc.otm.registry.CapabilitiesRegisterListener +import ru.dbotthepony.mc.otm.registry.MDataComponentTypes import java.math.BigInteger import java.util.* -class PortableCondensationDriveItem(capacity: Int) : - Item(Properties().stacksTo(1)) { +class PortableCondensationDriveItem(capacity: Int) : Item(Properties().stacksTo(1)), CapabilitiesRegisterListener { val capacity: BigInteger = capacity.toBigInteger() - private inner class DriveCapability(private val stack: ItemStack) : ICapabilityProvider { - private var uuid: UUID? = null - - private val resolver = LazyOptional.of> { - if (!isServerThread()) { - return@of ItemMatteryDrive.DUMMY - } - - val uuid = uuid - - return@of DrivePool.get(uuid!!, { tag: CompoundTag? -> - val drive = ItemMatteryDrive(capacity, uuid) - drive.deserializeNBT(tag!!) - return@get drive - }, { ItemMatteryDrive(capacity, uuid) }) - } - - override fun getCapability(cap: Capability, side: Direction?): LazyOptional { - if (cap === MatteryCapability.DRIVE) { - if (uuid == null) { - val array = stack.orCreateTag.getLongArray("uuid") - - if (array.size == 2) { - uuid = UUID(array[0], array[1]) - } else { - uuid = UUID.randomUUID() - stack.orCreateTag.putLongArray("uuid", longArrayOf(uuid!!.mostSignificantBits, uuid!!.leastSignificantBits)) - } - } - - return resolver.cast() - } - - return LazyOptional.empty() - } - } - override fun appendHoverText( stack: ItemStack, - p_41422_: Level?, + p_339594_: TooltipContext, p_41423_: MutableList, p_41424_: TooltipFlag ) { - super.appendHoverText(stack, p_41422_, p_41423_, p_41424_) - if (stack.tag != null) { - val uuid = stack.tag!!.getLongArray("uuid") - if (uuid.size == 2) { - p_41423_.add(TextComponent(UUID(uuid[0], uuid[1]).toString()).withStyle(ChatFormatting.GRAY)) - } + super.appendHoverText(stack, p_339594_, p_41423_, p_41424_) + + if (stack.has(MDataComponentTypes.CONDENSATION_DRIVE_UUID)) { + p_41423_.add(TextComponent(stack[MDataComponentTypes.CONDENSATION_DRIVE_UUID].toString()).withStyle(ChatFormatting.GRAY)) } } - override fun initCapabilities(stack: ItemStack, nbt: CompoundTag?): ICapabilityProvider { - return DriveCapability(stack) - } + override fun registerCapabilities(event: RegisterCapabilitiesEvent) { + event.registerItem(MatteryCapability.CONDENSATION_DRIVE, { o, _ -> + if (!o.has(MDataComponentTypes.CONDENSATION_DRIVE_UUID)) { + o[MDataComponentTypes.CONDENSATION_DRIVE_UUID] = UUID.randomUUID() + } - fun getFilterSettings(drive: ItemStack): ItemFilter { - var ignore = true - val filter = ItemFilter(MAX_FILTERS) { if (!ignore) drive.tagNotNull[FILTER_PATH] = it.serializeNBT() } - filter.isWhitelist = true - drive.tag?.map(FILTER_PATH, filter::deserializeNBT) - ignore = false - return filter + if (!isServerThread()) { + return@registerItem ItemMatteryDrive.DUMMY + } + + DrivePool.get(o[MDataComponentTypes.CONDENSATION_DRIVE_UUID]!!, { tag: CompoundTag?, lookup -> + val drive = ItemMatteryDrive(capacity, o[MDataComponentTypes.CONDENSATION_DRIVE_UUID]!!) + drive.deserializeNBT(tag!!, lookup) + return@get drive + }, { ItemMatteryDrive(capacity, o[MDataComponentTypes.CONDENSATION_DRIVE_UUID]!!) }) + }, this) } @Suppress("unused") companion object { - const val MAX_FILTERS = 4 * 3 - const val FILTER_PATH = "filter" - - fun onPickupEvent(event: EntityItemPickupEvent) { - if (event.item.owner != null && event.item.owner != event.entity && event.item.age < 200 || event.item.item.isEmpty) { + fun onPickupEvent(event: ItemEntityPickupEvent.Pre) { + if (event.itemEntity.owner != null && event.itemEntity.owner != event.player && event.itemEntity.age < 200 || event.itemEntity.item.isEmpty) { return } - var amount = event.item.item.count - val item = event.item.item.item + var amount = event.itemEntity.item.count + val item = event.itemEntity.item.item - for (stack in event.entity.inventory.items) { + for (stack in event.player.inventory.items) { val drive = stack.item if (drive is PortableCondensationDriveItem) { var doBreak = false - stack.getCapability(MatteryCapability.DRIVE).ifPresent { - val filter = drive.getFilterSettings(stack) + stack.getCapability(MatteryCapability.CONDENSATION_DRIVE)?.let { + val filter = stack[MDataComponentTypes.ITEM_FILTER] ?: ItemFilter.EMPTY - if (filter.match(event.item.item)) { - val copy = event.item.item.copy() - val remaining = (it as ItemMatteryDrive).insertStack(event.item.item, false) + if (filter.match(event.itemEntity.item)) { + val copy = event.itemEntity.item.copy() + val remaining = (it as ItemMatteryDrive).insertStack(event.itemEntity.item, false) - if (remaining.count == event.item.item.count) { - return@ifPresent + if (remaining.count == event.itemEntity.item.count) { + return@let } copy.count -= remaining.count - event.isCanceled = true - ForgeEventFactory.firePlayerItemPickupEvent(event.entity, event.item, copy) + event.setCanPickup(TriState.FALSE) + // TODO + // EventHooks.firePlayerItemPickupEvent(event.entity, event.item, copy) if (remaining.count > 0) { - event.item.item.count = remaining.count - event.entity.take(event.item, amount - remaining.count) + event.itemEntity.item.count = remaining.count + event.player.take(event.itemEntity, amount - remaining.count) - event.entity.awardStat(Stats.ITEM_PICKED_UP.get(item), amount - remaining.count) - event.entity.onItemPickup(event.item) + event.player.awardStat(Stats.ITEM_PICKED_UP.get(item), amount - remaining.count) + event.player.onItemPickup(event.itemEntity) amount = remaining.count } else { - event.entity.take(event.item, amount) + event.player.take(event.itemEntity, amount) - event.entity.awardStat(Stats.ITEM_PICKED_UP.get(item), amount) - event.entity.onItemPickup(event.item) + event.player.awardStat(Stats.ITEM_PICKED_UP.get(item), amount) + event.player.onItemPickup(event.itemEntity) - event.item.discard() + event.itemEntity.discard() doBreak = true } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/item/ProceduralBatteryItem.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/item/ProceduralBatteryItem.kt index b50df462c..7ba2650ad 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/item/ProceduralBatteryItem.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/item/ProceduralBatteryItem.kt @@ -1,19 +1,16 @@ package ru.dbotthepony.mc.otm.item -import com.mojang.serialization.Codec +import com.mojang.serialization.MapCodec import com.mojang.serialization.codecs.RecordCodecBuilder import net.minecraft.ChatFormatting -import net.minecraft.nbt.CompoundTag -import net.minecraft.network.chat.Component -import net.minecraft.world.item.Item import net.minecraft.world.item.ItemStack -import net.minecraft.world.item.TooltipFlag -import net.minecraft.world.level.Level import net.minecraft.world.level.storage.loot.LootContext import net.minecraft.world.level.storage.loot.functions.LootItemFunction import net.minecraft.world.level.storage.loot.functions.LootItemFunctionType -import net.minecraftforge.common.capabilities.ICapabilityProvider +import net.neoforged.neoforge.capabilities.Capabilities +import net.neoforged.neoforge.capabilities.RegisterCapabilitiesEvent import ru.dbotthepony.mc.otm.capability.FlowDirection +import ru.dbotthepony.mc.otm.capability.MatteryCapability import ru.dbotthepony.mc.otm.capability.energy.ItemEnergyStorageImpl import ru.dbotthepony.mc.otm.capability.energy.batteryLevel import ru.dbotthepony.mc.otm.capability.energy.getBarColor @@ -21,26 +18,25 @@ import ru.dbotthepony.mc.otm.capability.energy.getBarWidth import ru.dbotthepony.mc.otm.capability.matteryEnergy import ru.dbotthepony.mc.otm.core.TranslatableComponent import ru.dbotthepony.mc.otm.core.math.Decimal -import ru.dbotthepony.mc.otm.core.math.set -import ru.dbotthepony.mc.otm.core.nbt.mapPresent -import ru.dbotthepony.mc.otm.core.tagNotNull import ru.dbotthepony.mc.otm.data.DecimalProvider +import ru.dbotthepony.mc.otm.registry.CapabilitiesRegisterListener +import ru.dbotthepony.mc.otm.registry.MDataComponentTypes import ru.dbotthepony.mc.otm.registry.MItemFunctionTypes -import java.util.Optional +import java.util.* -class ProceduralBatteryItem : MatteryItem(Properties().stacksTo(1)) { +class ProceduralBatteryItem : MatteryItem(Properties().stacksTo(1)), CapabilitiesRegisterListener { class Cap(stack: ItemStack) : ItemEnergyStorageImpl(stack) { override var maxInput: Decimal - get() = itemStack.tag?.mapPresent("maxInput", Decimal.Companion::deserializeNBT) ?: Decimal.ZERO - set(value) { itemStack.tagNotNull["maxInput"] = value } + get() = itemStack[MDataComponentTypes.MAX_BATTERY_INPUT] ?: Decimal.ZERO + set(value) { itemStack[MDataComponentTypes.MAX_BATTERY_INPUT] = value } override var maxOutput: Decimal - get() = itemStack.tag?.mapPresent("maxOutput", Decimal.Companion::deserializeNBT) ?: Decimal.ZERO - set(value) { itemStack.tagNotNull["maxOutput"] = value } + get() = itemStack[MDataComponentTypes.MAX_BATTERY_OUTPUT] ?: Decimal.ZERO + set(value) { itemStack[MDataComponentTypes.MAX_BATTERY_OUTPUT] = value } override var maxBatteryLevel: Decimal - get() = itemStack.tag?.mapPresent("maxBatteryLevel", Decimal.Companion::deserializeNBT) ?: Decimal.ZERO - set(value) { itemStack.tagNotNull["maxBatteryLevel"] = value } + get() = itemStack[MDataComponentTypes.MAX_BATTERY_LEVEL] ?: Decimal.ZERO + set(value) { itemStack[MDataComponentTypes.MAX_BATTERY_LEVEL] = value } override val energyFlow: FlowDirection get() = FlowDirection.BI_DIRECTIONAL @@ -62,7 +58,7 @@ class ProceduralBatteryItem : MatteryItem(Properties().stacksTo(1)) { } init { - tooltips.addNormal { itemStack, acceptor -> + tooltips.addNormal { itemStack, context, acceptor -> val energy = itemStack.matteryEnergy if (energy is Cap) { @@ -110,7 +106,7 @@ class ProceduralBatteryItem : MatteryItem(Properties().stacksTo(1)) { return t } - override fun getType(): LootItemFunctionType { + override fun getType(): LootItemFunctionType { return MItemFunctionTypes.PROCEDURAL_BATTERY } @@ -119,8 +115,8 @@ class ProceduralBatteryItem : MatteryItem(Properties().stacksTo(1)) { } companion object { - val CODEC: Codec by lazy { - RecordCodecBuilder.create { + val CODEC: MapCodec by lazy { + RecordCodecBuilder.mapCodec { it.group( DecimalProvider.CODEC.fieldOf("maxBatteryLevel").forGetter(Randomizer::maxBatteryLevel), DecimalProvider.CODEC.optionalFieldOf("batteryLevel").forGetter(Randomizer::batteryLevel), @@ -132,7 +128,8 @@ class ProceduralBatteryItem : MatteryItem(Properties().stacksTo(1)) { } } - override fun initCapabilities(stack: ItemStack, nbt: CompoundTag?): ICapabilityProvider { - return Cap(stack) + override fun registerCapabilities(event: RegisterCapabilitiesEvent) { + event.registerItem(Capabilities.EnergyStorage.ITEM, { o, _ -> Cap(o) }, this) + event.registerItem(MatteryCapability.ITEM_ENERGY, { o, _ -> Cap(o) }, this) } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/item/QuantumBatteryItem.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/item/QuantumBatteryItem.kt index 9abcfed1b..fe3d2605f 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/item/QuantumBatteryItem.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/item/QuantumBatteryItem.kt @@ -4,9 +4,12 @@ import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet import net.minecraft.ChatFormatting import net.minecraft.core.Direction +import net.minecraft.core.registries.BuiltInRegistries import net.minecraft.nbt.CompoundTag import net.minecraft.network.FriendlyByteBuf import net.minecraft.network.chat.Component +import net.minecraft.network.codec.StreamCodec +import net.minecraft.network.protocol.common.custom.CustomPacketPayload import net.minecraft.util.datafix.DataFixTypes import net.minecraft.world.item.Item import net.minecraft.world.item.ItemStack @@ -22,6 +25,8 @@ import net.minecraftforge.common.util.LazyOptional import net.minecraftforge.event.TickEvent import net.minecraftforge.event.TickEvent.ServerTickEvent import net.minecraftforge.registries.ForgeRegistries +import net.neoforged.neoforge.network.handling.IPayloadContext +import ru.dbotthepony.mc.otm.OverdriveThatMatters import ru.dbotthepony.mc.otm.capability.FlowDirection import ru.dbotthepony.mc.otm.capability.MatteryCapability import ru.dbotthepony.mc.otm.capability.trackedItems @@ -30,6 +35,7 @@ import ru.dbotthepony.mc.otm.capability.energy.getBarColor import ru.dbotthepony.mc.otm.capability.energy.getBarWidth import ru.dbotthepony.mc.otm.capability.matteryEnergy import ru.dbotthepony.mc.otm.config.EnergyBalanceValues +import ru.dbotthepony.mc.otm.core.ResourceLocation import ru.dbotthepony.mc.otm.core.TranslatableComponent import ru.dbotthepony.mc.otm.core.collect.filter import ru.dbotthepony.mc.otm.core.getID @@ -48,8 +54,6 @@ import ru.dbotthepony.mc.otm.core.util.formatPower import ru.dbotthepony.mc.otm.isClientThread import ru.dbotthepony.mc.otm.isServerThread import ru.dbotthepony.mc.otm.lazyPerServer -import ru.dbotthepony.mc.otm.network.GenericNetworkChannel -import ru.dbotthepony.mc.otm.network.MNetworkContext import ru.dbotthepony.mc.otm.network.MatteryPacket import java.util.* import java.util.function.Function @@ -352,27 +356,34 @@ class QuantumBatteryItem(val savedataID: String, val balanceValues: EnergyBalanc } } } + + val PACKET_TYPE = CustomPacketPayload.Type(ResourceLocation(OverdriveThatMatters.MOD_ID, "quantum_charge")) + val PACKET_CODEC: StreamCodec = StreamCodec.ofMember(ChargePacket::write, ::readPacket) } - class ChargePacket( + data class ChargePacket( val type: QuantumBatteryItem, override val uuid: UUID, override var energy: Decimal, override var passed: Decimal, override var received: Decimal, - ) : MatteryPacket, IValues { + ) : CustomPacketPayload, IValues { override val isServer: Boolean get() = false - override fun write(buff: FriendlyByteBuf) { - buff.writeInt(ForgeRegistries.ITEMS.getID(type)) + override fun type(): CustomPacketPayload.Type { + return PACKET_TYPE + } + + fun write(buff: FriendlyByteBuf) { + buff.writeInt(BuiltInRegistries.ITEM.getId(type)) buff.writeUUID(uuid) buff.writeDecimal(energy) buff.writeDecimal(passed) buff.writeDecimal(received) } - override fun play(context: MNetworkContext) { + fun play(context: IPayloadContext) { val data = type.clientData.computeIfAbsent(uuid, Function { UnboundValues(it) }) data.energy = energy data.passed = passed diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/item/SimpleUpgrade.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/item/SimpleUpgrade.kt index bdee5e757..e3fe8dc83 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/item/SimpleUpgrade.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/item/SimpleUpgrade.kt @@ -1,21 +1,12 @@ package ru.dbotthepony.mc.otm.item -import net.minecraft.core.Direction -import net.minecraft.nbt.CompoundTag -import net.minecraft.network.chat.Component -import net.minecraft.world.item.Item -import net.minecraft.world.item.ItemStack -import net.minecraft.world.item.TooltipFlag -import net.minecraft.world.level.Level -import net.minecraftforge.common.capabilities.Capability -import net.minecraftforge.common.capabilities.ICapabilityProvider -import net.minecraftforge.common.util.LazyOptional +import net.neoforged.neoforge.capabilities.RegisterCapabilitiesEvent import ru.dbotthepony.mc.otm.capability.IMatteryUpgrade import ru.dbotthepony.mc.otm.capability.MatteryCapability import ru.dbotthepony.mc.otm.capability.UpgradeType import ru.dbotthepony.mc.otm.capability.addUpgradeTooltipLines -import ru.dbotthepony.mc.otm.core.TextComponent import ru.dbotthepony.mc.otm.core.math.Decimal +import ru.dbotthepony.mc.otm.registry.CapabilitiesRegisterListener class SimpleUpgrade( properties: Properties, @@ -30,25 +21,15 @@ class SimpleUpgrade( override val matterStorage: Decimal = Decimal.ZERO, override val matterStorageFlat: Decimal = Decimal.ZERO, override val failureMultiplier: Double = 1.0, -) : MatteryItem(properties), IMatteryUpgrade, ICapabilityProvider { - private val resolver = LazyOptional.of { this } - - override fun getCapability(cap: Capability, side: Direction?): LazyOptional { - if (cap === MatteryCapability.UPGRADE) { - return resolver.cast() - } - - return LazyOptional.empty() - } - +) : MatteryItem(properties), IMatteryUpgrade, CapabilitiesRegisterListener { init { - tooltips.addNormal { _, acceptor -> + tooltips.addNormal { _, _, acceptor -> addUpgradeTooltipLines(acceptor) } } - override fun initCapabilities(stack: ItemStack, nbt: CompoundTag?): ICapabilityProvider { - return this + override fun registerCapabilities(event: RegisterCapabilitiesEvent) { + event.registerItem(MatteryCapability.UPGRADE, { _, _ -> this }, this) } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/item/SingleUseBatteryItem.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/item/SingleUseBatteryItem.kt index a1e4f6d2d..b1b172ad7 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/item/SingleUseBatteryItem.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/item/SingleUseBatteryItem.kt @@ -1,29 +1,26 @@ package ru.dbotthepony.mc.otm.item import net.minecraft.ChatFormatting -import net.minecraft.nbt.CompoundTag -import net.minecraft.network.chat.Component -import net.minecraft.world.item.Item import net.minecraft.world.item.ItemStack import net.minecraft.world.item.Rarity -import net.minecraft.world.item.TooltipFlag -import net.minecraft.world.level.Level -import net.minecraftforge.common.capabilities.ICapabilityProvider -import ru.dbotthepony.mc.otm.config.EnergyBalanceValues -import ru.dbotthepony.mc.otm.capability.* +import net.neoforged.neoforge.capabilities.Capabilities +import net.neoforged.neoforge.capabilities.RegisterCapabilitiesEvent +import ru.dbotthepony.mc.otm.capability.MatteryCapability import ru.dbotthepony.mc.otm.capability.energy.EnergyProducerItem -import ru.dbotthepony.mc.otm.capability.energy.ItemEnergyStorageImpl import ru.dbotthepony.mc.otm.capability.energy.getBarColor import ru.dbotthepony.mc.otm.capability.energy.getBarWidth +import ru.dbotthepony.mc.otm.capability.matteryEnergy +import ru.dbotthepony.mc.otm.config.EnergyBalanceValues import ru.dbotthepony.mc.otm.config.ItemsConfig -import ru.dbotthepony.mc.otm.core.* +import ru.dbotthepony.mc.otm.core.TranslatableComponent import ru.dbotthepony.mc.otm.core.math.Decimal +import ru.dbotthepony.mc.otm.registry.CapabilitiesRegisterListener open class SingleUseBatteryItem( private val _capacity: () -> Decimal, private val _throughput: () -> Decimal? = { null }, properties: Properties = Properties().stacksTo(1) -) : MatteryItem(properties) { +) : MatteryItem(properties), CapabilitiesRegisterListener { constructor(values: EnergyBalanceValues, properties: Properties = Properties().stacksTo(1)) : this(values::energyCapacity, values::energyThroughput, properties) constructor(storage: Decimal, throughput: Decimal? = null, properties: Properties = Properties().stacksTo(1)) : this({ storage }, { throughput }, properties) @@ -35,8 +32,9 @@ open class SingleUseBatteryItem( tooltips.itemEnergy() } - override fun initCapabilities(stack: ItemStack, nbt: CompoundTag?): ICapabilityProvider { - return EnergyProducerItem(stack, capacity, throughput, initialBatteryLevel = capacity) + override fun registerCapabilities(event: RegisterCapabilitiesEvent) { + event.registerItem(MatteryCapability.ITEM_ENERGY, { o, _ -> EnergyProducerItem(o, capacity, throughput, initialBatteryLevel = capacity) }, this) + event.registerItem(Capabilities.EnergyStorage.ITEM, { o, _ -> EnergyProducerItem(o, capacity, throughput, initialBatteryLevel = capacity) }, this) } override fun isBarVisible(p_150899_: ItemStack): Boolean { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/item/armor/PortableGravitationStabilizerItem.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/item/armor/PortableGravitationStabilizerItem.kt index 39eff1c51..9df928cca 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/item/armor/PortableGravitationStabilizerItem.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/item/armor/PortableGravitationStabilizerItem.kt @@ -9,8 +9,7 @@ import net.minecraft.world.entity.EquipmentSlot import net.minecraft.world.entity.LivingEntity import net.minecraft.world.item.* import net.minecraft.world.item.crafting.Ingredient -import net.minecraft.world.level.Level -import net.minecraftforge.client.extensions.common.IClientItemExtensions +import net.neoforged.neoforge.client.extensions.common.IClientItemExtensions import ru.dbotthepony.mc.otm.OverdriveThatMatters import ru.dbotthepony.mc.otm.core.TranslatableComponent import ru.dbotthepony.mc.otm.client.model.GravitationStabilizerModel @@ -49,11 +48,11 @@ class PortableGravitationStabilizerItem : ArmorItem(GravitationStabilizerArmorMa override fun appendHoverText( p_41421_: ItemStack, - p_41422_: Level?, + p_339594_: TooltipContext, p_41423_: MutableList, p_41424_: TooltipFlag ) { - super.appendHoverText(p_41421_, p_41422_, p_41423_, p_41424_) + super.appendHoverText(p_41421_, p_339594_, p_41423_, p_41424_) p_41423_.add(DESCRIPTION) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/item/armor/SimpleTritaniumArmorItem.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/item/armor/SimpleTritaniumArmorItem.kt index 4441e7237..3ed2400e7 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/item/armor/SimpleTritaniumArmorItem.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/item/armor/SimpleTritaniumArmorItem.kt @@ -1,5 +1,6 @@ package ru.dbotthepony.mc.otm.item.armor +import net.minecraft.resources.ResourceLocation import net.minecraft.sounds.SoundEvent import net.minecraft.sounds.SoundEvents import net.minecraft.world.entity.Entity @@ -9,46 +10,22 @@ import net.minecraft.world.item.ArmorMaterial import net.minecraft.world.item.ItemStack import net.minecraft.world.item.crafting.Ingredient import ru.dbotthepony.mc.otm.OverdriveThatMatters +import ru.dbotthepony.mc.otm.core.ResourceLocation +import ru.dbotthepony.mc.otm.registry.MArmorMaterials import ru.dbotthepony.mc.otm.registry.MItemTags -private object SimpleTritaniumArmorMaterial : ArmorMaterial { - override fun getDurabilityForType(p_40410_: ArmorItem.Type): Int { - return when (p_40410_) { - ArmorItem.Type.HELMET -> 380 - ArmorItem.Type.CHESTPLATE -> 590 - ArmorItem.Type.LEGGINGS -> 500 - ArmorItem.Type.BOOTS -> 420 - else -> throw IllegalArgumentException("yo dude what the fuck $p_40410_") - } - } - - override fun getDefenseForType(p_40411_: ArmorItem.Type): Int { - return when (p_40411_) { - ArmorItem.Type.HELMET -> 2 - ArmorItem.Type.CHESTPLATE -> 6 - ArmorItem.Type.LEGGINGS -> 7 - ArmorItem.Type.BOOTS -> 2 - else -> throw IllegalArgumentException("yo dude what the fuck $p_40411_") - } - } - - override fun getEnchantmentValue() = 9 - override fun getEquipSound(): SoundEvent = SoundEvents.ARMOR_EQUIP_IRON - override fun getRepairIngredient(): Ingredient = Ingredient.of(MItemTags.TRITANIUM_INGOTS) - - const val ID = "${OverdriveThatMatters.MOD_ID}:simple_tritanium_armor" - - override fun getName(): String = ID - override fun getToughness() = 0.3f - override fun getKnockbackResistance() = 0f -} - -class SimpleTritaniumArmorItem(slot: Type) : ArmorItem(SimpleTritaniumArmorMaterial, slot, Properties().stacksTo(1)) { - override fun getArmorTexture(stack: ItemStack, entity: Entity?, slot: EquipmentSlot, type: String?): String? { - if (type != "overlay" || slot == EquipmentSlot.FEET) +class SimpleTritaniumArmorItem(slot: Type) : ArmorItem(MArmorMaterials.SIMPLE_TRITANIUM, slot, Properties().stacksTo(1)) { + override fun getArmorTexture( + stack: ItemStack, + entity: Entity, + slot: EquipmentSlot, + layer: ArmorMaterial.Layer, + innerModel: Boolean + ): ResourceLocation? { + if (!innerModel || slot == EquipmentSlot.FEET) return when (slot) { - EquipmentSlot.LEGS -> "${OverdriveThatMatters.MOD_ID}:textures/models/armor/tritanium_simple_layer_2.png" - EquipmentSlot.FEET, EquipmentSlot.CHEST, EquipmentSlot.HEAD -> "${OverdriveThatMatters.MOD_ID}:textures/models/armor/tritanium_simple_layer_1.png" + EquipmentSlot.LEGS -> ResourceLocation(OverdriveThatMatters.MOD_ID, "textures/models/armor/tritanium_simple_layer_2.png") + EquipmentSlot.FEET, EquipmentSlot.CHEST, EquipmentSlot.HEAD -> ResourceLocation(OverdriveThatMatters.MOD_ID, "textures/models/armor/tritanium_simple_layer_1.png") else -> throw IllegalArgumentException("Invalid slot $slot") } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/item/armor/TritaniumArmorItem.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/item/armor/TritaniumArmorItem.kt index dcb2beb0b..9efa14e31 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/item/armor/TritaniumArmorItem.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/item/armor/TritaniumArmorItem.kt @@ -1,53 +1,18 @@ package ru.dbotthepony.mc.otm.item.armor import net.minecraft.client.model.HumanoidModel -import net.minecraft.sounds.SoundEvent -import net.minecraft.sounds.SoundEvents import net.minecraft.world.damagesource.DamageTypes -import net.minecraft.world.entity.Entity import net.minecraft.world.entity.EquipmentSlot import net.minecraft.world.entity.LivingEntity import net.minecraft.world.item.* -import net.minecraft.world.item.crafting.Ingredient -import net.minecraftforge.client.extensions.common.IClientItemExtensions -import net.minecraftforge.event.entity.living.LivingAttackEvent -import ru.dbotthepony.mc.otm.OverdriveThatMatters -import ru.dbotthepony.mc.otm.client.model.TritaniumArmorModel +import net.neoforged.neoforge.client.extensions.common.IClientItemExtensions +import net.neoforged.neoforge.event.entity.living.LivingIncomingDamageEvent import ru.dbotthepony.kommons.math.RGBAColor -import ru.dbotthepony.mc.otm.registry.MItemTags +import ru.dbotthepony.mc.otm.client.model.TritaniumArmorModel +import ru.dbotthepony.mc.otm.registry.MArmorMaterials import ru.dbotthepony.mc.otm.registry.MItems import java.util.function.Consumer -private object TritaniumArmorMaterial : ArmorMaterial { - override fun getDurabilityForType(p_40410_: ArmorItem.Type): Int { - return when (p_40410_) { - ArmorItem.Type.HELMET -> 520 - ArmorItem.Type.CHESTPLATE -> 920 - ArmorItem.Type.LEGGINGS -> 650 - ArmorItem.Type.BOOTS -> 540 - } - } - - override fun getDefenseForType(p_40411_: ArmorItem.Type): Int { - return when (p_40411_) { - ArmorItem.Type.HELMET -> 4 - ArmorItem.Type.CHESTPLATE -> 9 - ArmorItem.Type.LEGGINGS -> 7 - ArmorItem.Type.BOOTS -> 3 - } - } - - override fun getEnchantmentValue() = 9 - override fun getEquipSound(): SoundEvent = SoundEvents.ARMOR_EQUIP_IRON - override fun getRepairIngredient(): Ingredient = Ingredient.of(MItemTags.REINFORCED_TRITANIUM_PLATES) - - const val ID = "${OverdriveThatMatters.MOD_ID}:tritanium_armor" - - override fun getName(): String = ID - override fun getToughness() = 1f - override fun getKnockbackResistance() = 0.08f -} - private object TritaniumArmorRenderProperties : IClientItemExtensions { override fun getHumanoidArmorModel( entityLiving: LivingEntity, @@ -63,30 +28,16 @@ private object TritaniumArmorRenderProperties : IClientItemExtensions { } } -class TritaniumArmorItem(slot: Type) : DyeableArmorItem(TritaniumArmorMaterial, slot, Properties().stacksTo(1).rarity(Rarity.RARE)) { +class TritaniumArmorItem(slot: Type) : ArmorItem(MArmorMaterials.TRITANIUM, slot, Properties().stacksTo(1).rarity(Rarity.RARE)) { override fun initializeClient(consumer: Consumer) { super.initializeClient(consumer) consumer.accept(TritaniumArmorRenderProperties) } - override fun getArmorTexture(stack: ItemStack, entity: Entity, slot: EquipmentSlot, type: String?): String = - if (type.equals("overlay")) TEXTURE_LOCATION_OVERLAY else TEXTURE_LOCATION_BASE - - override fun getColor(stack: ItemStack): Int { - val tag = stack.getTagElement("display")?: return TRITANIUM_COLOR - if (tag.contains("color", 99)) { - return tag.getInt("color") - } - - return TRITANIUM_COLOR - } - companion object { val TRITANIUM_COLOR = RGBAColor(157, 187, 204).toBGRA() - const val TEXTURE_LOCATION_BASE = "${OverdriveThatMatters.MOD_ID}:textures/models/armor/tritanium_armor_base.png" - const val TEXTURE_LOCATION_OVERLAY = "${OverdriveThatMatters.MOD_ID}:textures/models/armor/tritanium_armor_overlay.png" - fun onHurt(event: LivingAttackEvent) { + fun onHurt(event: LivingIncomingDamageEvent) { if (event.source.typeHolder().`is`(DamageTypes.SWEET_BERRY_BUSH) || event.source.msgId == "sweetBerryBush") { if ( event.entity.getItemBySlot(EquipmentSlot.FEET).let { !it.isEmpty && it.item == MItems.TRITANIUM_BOOTS } && diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/item/exopack/AbstractExopackSlotUpgradeItem.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/item/exopack/AbstractExopackSlotUpgradeItem.kt index d99790504..949c648e5 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/item/exopack/AbstractExopackSlotUpgradeItem.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/item/exopack/AbstractExopackSlotUpgradeItem.kt @@ -34,12 +34,17 @@ abstract class AbstractExopackSlotUpgradeItem(properties: Properties = defaultPr return super.canBeHurtBy(p_41387_) && !p_41387_.isExplosion && !p_41387_.isFire } - override fun getUseDuration(p_41454_: ItemStack): Int { + override fun getUseDuration(p_41454_: ItemStack, p_344979_: LivingEntity): Int { return 30 } - override fun appendHoverText(p_41421_: ItemStack, p_41422_: Level?, tooltip: MutableList, p_41424_: TooltipFlag) { - super.appendHoverText(p_41421_, p_41422_, tooltip, p_41424_) + override fun appendHoverText( + p_41421_: ItemStack, + p_339594_: TooltipContext, + tooltip: MutableList, + p_41424_: TooltipFlag + ) { + super.appendHoverText(p_41421_, p_339594_, tooltip, p_41424_) val alreadyHasExosuit = runIfClient(true) { minecraft.player?.matteryPlayer?.hasExopack == true @@ -85,7 +90,7 @@ abstract class AbstractExopackSlotUpgradeItem(properties: Properties = defaultPr override fun finishUsingItem(itemStack: ItemStack, level: Level, player: LivingEntity): ItemStack { if (player !is Player) return super.finishUsingItem(itemStack, level, player) - val matteryPlayer = player.matteryPlayer ?: return super.finishUsingItem(itemStack, level, player) + val matteryPlayer = player.matteryPlayer val uuid = uuid(itemStack) val slotCount = slotCount(itemStack) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/item/exopack/ExopackProbeItem.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/item/exopack/ExopackProbeItem.kt index fd4a6c8a4..4be2ec216 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/item/exopack/ExopackProbeItem.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/item/exopack/ExopackProbeItem.kt @@ -19,12 +19,17 @@ import ru.dbotthepony.mc.otm.registry.MatteryDamageSource import ru.dbotthepony.mc.otm.runIfClient class ExopackProbeItem : Item(Properties().stacksTo(1).rarity(Rarity.EPIC)) { - override fun getUseDuration(p_41454_: ItemStack): Int { + override fun getUseDuration(p_41454_: ItemStack, p_344979_: LivingEntity): Int { return 30 } - override fun appendHoverText(p_41421_: ItemStack, p_41422_: Level?, tooltip: MutableList, p_41424_: TooltipFlag) { - super.appendHoverText(p_41421_, p_41422_, tooltip, p_41424_) + override fun appendHoverText( + p_41421_: ItemStack, + p_339594_: TooltipContext, + tooltip: MutableList, + p_41424_: TooltipFlag + ) { + super.appendHoverText(p_41421_, p_339594_, tooltip, p_41424_) val alreadyHas = runIfClient(false) { return@runIfClient minecraft.player?.matteryPlayer?.hasExopack ?: false @@ -40,7 +45,7 @@ class ExopackProbeItem : Item(Properties().stacksTo(1).rarity(Rarity.EPIC)) { } override fun use(p_41432_: Level, player: Player, hand: InteractionHand): InteractionResultHolder { - if (player.matteryPlayer?.hasExopack == false) { + if (!player.matteryPlayer.hasExopack) { player.startUsingItem(hand) return InteractionResultHolder.consume(player.getItemInHand(hand)) } @@ -50,7 +55,7 @@ class ExopackProbeItem : Item(Properties().stacksTo(1).rarity(Rarity.EPIC)) { override fun finishUsingItem(itemStack: ItemStack, level: Level, player: LivingEntity): ItemStack { if (player !is Player) return super.finishUsingItem(itemStack, level, player) - val mattery = player.matteryPlayer ?: return super.finishUsingItem(itemStack, level, player) + val mattery = player.matteryPlayer if (mattery.hasExopack) { return super.finishUsingItem(itemStack, level, player) @@ -72,7 +77,7 @@ class ExopackProbeItem : Item(Properties().stacksTo(1).rarity(Rarity.EPIC)) { onceServer((i - 1) * 100) { if (!player.hasDisconnected()) { if (i == 6) { - player.displayClientMessage(TranslatableComponent("otm.exopack.granted$i", player.displayName.copy().withStyle(ChatFormatting.DARK_PURPLE)).withStyle(ChatFormatting.DARK_AQUA), false) + player.displayClientMessage(TranslatableComponent("otm.exopack.granted$i", player.displayName!!.copy().withStyle(ChatFormatting.DARK_PURPLE)).withStyle(ChatFormatting.DARK_AQUA), false) } else { player.displayClientMessage(TranslatableComponent("otm.exopack.granted$i").withStyle(ChatFormatting.GRAY), false) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/item/exopack/ExopackUpgradeItem.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/item/exopack/ExopackUpgradeItem.kt index 668539320..2bc925cc7 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/item/exopack/ExopackUpgradeItem.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/item/exopack/ExopackUpgradeItem.kt @@ -13,23 +13,28 @@ import net.minecraft.world.item.Rarity import net.minecraft.world.item.TooltipFlag import net.minecraft.world.item.UseAnim import net.minecraft.world.level.Level -import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability +import ru.dbotthepony.mc.otm.capability.MatteryPlayer import ru.dbotthepony.mc.otm.capability.matteryPlayer import ru.dbotthepony.mc.otm.client.minecraft import ru.dbotthepony.mc.otm.core.TranslatableComponent import ru.dbotthepony.mc.otm.runIfClient class ExopackUpgradeItem( - val type: MatteryPlayerCapability.UpgradeType, + val type: MatteryPlayer.UpgradeType, val upgradeName: String, val upgradedName: String, ) : Item(Properties().stacksTo(1).rarity(Rarity.RARE)) { - override fun getUseDuration(p_41454_: ItemStack): Int { + override fun getUseDuration(p_41454_: ItemStack, p_344979_: LivingEntity): Int { return 30 } - override fun appendHoverText(p_41421_: ItemStack, p_41422_: Level?, tooltip: MutableList, p_41424_: TooltipFlag) { - super.appendHoverText(p_41421_, p_41422_, tooltip, p_41424_) + override fun appendHoverText( + p_41421_: ItemStack, + p_339594_: TooltipContext, + tooltip: MutableList, + p_41424_: TooltipFlag + ) { + super.appendHoverText(p_41421_, p_339594_, tooltip, p_41424_) val alreadyHasExosuit = runIfClient(true) { minecraft.player?.matteryPlayer?.hasExopack == true diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/item/exopack/ProceduralExopackSlotUpgradeItem.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/item/exopack/ProceduralExopackSlotUpgradeItem.kt index 1a0188d3d..c4e4c2832 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/item/exopack/ProceduralExopackSlotUpgradeItem.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/item/exopack/ProceduralExopackSlotUpgradeItem.kt @@ -1,6 +1,7 @@ package ru.dbotthepony.mc.otm.item.exopack import com.mojang.serialization.Codec +import com.mojang.serialization.MapCodec import com.mojang.serialization.codecs.RecordCodecBuilder import net.minecraft.ChatFormatting import net.minecraft.network.chat.Component @@ -13,19 +14,18 @@ import net.minecraft.world.level.storage.loot.LootContext import net.minecraft.world.level.storage.loot.functions.LootItemFunction import net.minecraft.world.level.storage.loot.functions.LootItemFunctionType import ru.dbotthepony.mc.otm.core.TranslatableComponent -import ru.dbotthepony.mc.otm.core.nbt.set -import ru.dbotthepony.mc.otm.core.tagNotNull +import ru.dbotthepony.mc.otm.registry.MDataComponentTypes import ru.dbotthepony.mc.otm.registry.MItemFunctionTypes import java.util.* class ProceduralExopackSlotUpgradeItem : AbstractExopackSlotUpgradeItem(defaultProperties()) { class Randomizer(val slots: IntProvider, val luckBias: IntProvider = ConstantInt.ZERO) : LootItemFunction, LootItemFunction.Builder { override fun apply(t: ItemStack, u: LootContext): ItemStack { - t.tagNotNull[SLOT_COUNT_KEY] = slots.sample(u.random) + (luckBias.sample(u.random) * u.luck / 1024f).coerceAtLeast(0f).toInt() + t[MDataComponentTypes.EXOPACK_SLOT_COUNT] = slots.sample(u.random) + (luckBias.sample(u.random) * u.luck / 1024f).coerceAtLeast(0f).toInt() return t } - override fun getType(): LootItemFunctionType { + override fun getType(): LootItemFunctionType { return MItemFunctionTypes.PROCEDURAL_EXOPACK_UPGRADE } @@ -34,7 +34,7 @@ class ProceduralExopackSlotUpgradeItem : AbstractExopackSlotUpgradeItem(defaultP } companion object { - val CODEC: Codec = RecordCodecBuilder.create { + val CODEC: MapCodec = RecordCodecBuilder.mapCodec { it.group( IntProvider.CODEC.fieldOf("slots").forGetter(Randomizer::slots), IntProvider.CODEC.optionalFieldOf("luck_bias", ConstantInt.ZERO).forGetter(Randomizer::luckBias), @@ -48,7 +48,7 @@ class ProceduralExopackSlotUpgradeItem : AbstractExopackSlotUpgradeItem(defaultP } override fun slotCount(itemStack: ItemStack): Int { - return itemStack.tag?.getInt(SLOT_COUNT_KEY) ?: 0 + return itemStack[MDataComponentTypes.EXOPACK_SLOT_COUNT] ?: 0 } override fun uuid(itemStack: ItemStack): UUID? { @@ -57,13 +57,13 @@ class ProceduralExopackSlotUpgradeItem : AbstractExopackSlotUpgradeItem(defaultP override fun appendHoverText( p_41421_: ItemStack, - p_41422_: Level?, + p_339594_: TooltipContext, tooltip: MutableList, p_41424_: TooltipFlag ) { - super.appendHoverText(p_41421_, p_41422_, tooltip, p_41424_) + super.appendHoverText(p_41421_, p_339594_, tooltip, p_41424_) - if (p_41421_.tag?.get(SLOT_COUNT_KEY) == null) { + if (!p_41421_.has(MDataComponentTypes.EXOPACK_SLOT_COUNT)) { tooltip.add(TranslatableComponent("$descriptionId.description").withStyle(ChatFormatting.GRAY)) } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/item/matter/CreativePatternItem.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/item/matter/CreativePatternItem.kt index b06eb053f..18d3b215f 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/item/matter/CreativePatternItem.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/item/matter/CreativePatternItem.kt @@ -1,35 +1,28 @@ package ru.dbotthepony.mc.otm.item.matter import net.minecraft.ChatFormatting -import net.minecraft.core.Direction -import net.minecraft.nbt.CompoundTag +import net.minecraft.core.registries.BuiltInRegistries import net.minecraft.network.chat.Component import net.minecraft.world.item.Item import net.minecraft.world.item.ItemStack import net.minecraft.world.item.Rarity import net.minecraft.world.item.TooltipFlag -import net.minecraft.world.level.Level -import net.minecraftforge.common.capabilities.Capability -import net.minecraftforge.common.capabilities.ICapabilityProvider -import net.minecraftforge.common.util.LazyOptional -import net.minecraftforge.registries.ForgeRegistries +import net.neoforged.neoforge.capabilities.RegisterCapabilitiesEvent import ru.dbotthepony.mc.otm.capability.MatteryCapability import ru.dbotthepony.mc.otm.capability.matter.PatternState import ru.dbotthepony.mc.otm.capability.matter.IPatternStorage import ru.dbotthepony.mc.otm.capability.matter.PatternInsertFailure import ru.dbotthepony.mc.otm.capability.matter.PatternInsertStatus import ru.dbotthepony.mc.otm.core.TranslatableComponent -import ru.dbotthepony.mc.otm.core.getID +import ru.dbotthepony.mc.otm.registry.CapabilitiesRegisterListener import ru.dbotthepony.mc.otm.matter.MatterManager import java.util.* import java.util.stream.Stream -class CreativePatternItem : Item(Properties().rarity(Rarity.EPIC).stacksTo(1)) { - private object Patterns : IPatternStorage, ICapabilityProvider { - private val resolver = LazyOptional.of { this } - +class CreativePatternItem : Item(Properties().rarity(Rarity.EPIC).stacksTo(1)), CapabilitiesRegisterListener { + private object Patterns : IPatternStorage { override val patterns: Stream - get() = MatterManager.map.keys.stream().map { PatternState(UUID(34783464838L, 4463458382L + ForgeRegistries.ITEMS.getID(it)), it, 1.0) } + get() = MatterManager.map.keys.stream().map { PatternState(UUID(34783464838L, 4463458382L + BuiltInRegistries.ITEM.getId(it)), it, 1.0) } override val patternCapacity: Int get() { @@ -48,23 +41,19 @@ class CreativePatternItem : Item(Properties().rarity(Rarity.EPIC).stacksTo(1)) { ): PatternInsertStatus { return PatternInsertFailure } - - override fun getCapability(cap: Capability, side: Direction?): LazyOptional { - return if (cap == MatteryCapability.PATTERN) resolver.cast() else LazyOptional.empty() - } } - override fun initCapabilities(stack: ItemStack?, nbt: CompoundTag?): ICapabilityProvider { - return Patterns + override fun registerCapabilities(event: RegisterCapabilitiesEvent) { + event.registerItem(MatteryCapability.PATTERN_ITEM, { o, c -> Patterns }, this) } override fun appendHoverText( p_41421_: ItemStack, - p_41422_: Level?, + p_339594_: TooltipContext, p_41423_: MutableList, p_41424_: TooltipFlag ) { - super.appendHoverText(p_41421_, p_41422_, p_41423_, p_41424_) + super.appendHoverText(p_41421_, p_339594_, p_41423_, p_41424_) p_41423_.add(TranslatableComponent("$descriptionId.description1").withStyle(ChatFormatting.DARK_GRAY)) p_41423_.add(TranslatableComponent("$descriptionId.description2").withStyle(ChatFormatting.DARK_GRAY)) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/item/matter/MatterCapacitorItem.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/item/matter/MatterCapacitorItem.kt index 6d4e9a693..956479be7 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/item/matter/MatterCapacitorItem.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/item/matter/MatterCapacitorItem.kt @@ -1,40 +1,31 @@ package ru.dbotthepony.mc.otm.item.matter import net.minecraft.ChatFormatting -import net.minecraft.core.Direction -import net.minecraft.nbt.CompoundTag import net.minecraft.world.item.ItemStack import net.minecraft.world.item.Rarity -import net.minecraftforge.common.capabilities.Capability -import net.minecraftforge.common.capabilities.ICapabilityProvider -import net.minecraftforge.common.util.LazyOptional +import net.neoforged.neoforge.capabilities.RegisterCapabilitiesEvent import ru.dbotthepony.mc.otm.capability.FlowDirection -import ru.dbotthepony.mc.otm.core.TranslatableComponent import ru.dbotthepony.mc.otm.capability.MatteryCapability -import ru.dbotthepony.mc.otm.capability.matter.* +import ru.dbotthepony.mc.otm.capability.matter.IMatterStorage +import ru.dbotthepony.mc.otm.capability.matter.getBarColor +import ru.dbotthepony.mc.otm.capability.matter.getBarWidth import ru.dbotthepony.mc.otm.client.ShiftPressedCond +import ru.dbotthepony.mc.otm.core.TranslatableComponent import ru.dbotthepony.mc.otm.core.math.Decimal import ru.dbotthepony.mc.otm.core.util.formatMatter -import ru.dbotthepony.mc.otm.core.ifPresentK -import ru.dbotthepony.mc.otm.core.nbt.map -import ru.dbotthepony.mc.otm.core.tagNotNull +import ru.dbotthepony.mc.otm.registry.CapabilitiesRegisterListener import ru.dbotthepony.mc.otm.item.MatteryItem +import ru.dbotthepony.mc.otm.registry.MDataComponentTypes -class MatterCapacitorItem : MatteryItem { - private inner class Matter(private val stack: ItemStack) : ICapabilityProvider, IMatterStorage { - private val resolver = LazyOptional.of { this } - - override fun getCapability(cap: Capability, side: Direction?): LazyOptional { - return if (cap === MatteryCapability.MATTER) resolver.cast() else LazyOptional.empty() - } - +class MatterCapacitorItem : MatteryItem, CapabilitiesRegisterListener { + private inner class Matter(private val stack: ItemStack) : IMatterStorage { override var storedMatter: Decimal get() { if (isCreative) return Decimal.POSITIVE_INFINITY - return stack.tag?.map("matter", Decimal.Companion::deserializeNBT) ?: Decimal.ZERO + return stack.getOrDefault(MDataComponentTypes.MATTER_LEVEL, Decimal.ZERO) } set(value) { - stack.tagNotNull.put("matter", value.serializeNBT()) + stack[MDataComponentTypes.MATTER_LEVEL] = value } override val maxStoredMatter: Decimal get() { @@ -96,26 +87,26 @@ class MatterCapacitorItem : MatteryItem { if (isCreative) return false - return p_150899_.matter != null + return p_150899_.getCapability(MatteryCapability.MATTER_ITEM) != null } override fun getBarWidth(p_150900_: ItemStack): Int { if (isCreative) return 13 - return p_150900_.matter?.getBarWidth() ?: super.getBarWidth(p_150900_) + return p_150900_.getCapability(MatteryCapability.MATTER_ITEM)?.getBarWidth() ?: super.getBarWidth(p_150900_) } override fun getBarColor(p_150901_: ItemStack): Int { if (isCreative) return 0 - return p_150901_.matter?.getBarColor() ?: super.getBarColor(p_150901_) + return p_150901_.getCapability(MatteryCapability.MATTER_ITEM)?.getBarColor() ?: super.getBarColor(p_150901_) } init { - tooltips.addNormal { itemStack, acceptor -> - itemStack.getCapability(MatteryCapability.MATTER).ifPresentK { + tooltips.addNormal { itemStack, context, acceptor -> + itemStack.getCapability(MatteryCapability.MATTER_ITEM)?.let { acceptor( TranslatableComponent( "otm.item.matter.storage", @@ -127,8 +118,8 @@ class MatterCapacitorItem : MatteryItem { } } - override fun initCapabilities(stack: ItemStack, nbt: CompoundTag?): ICapabilityProvider { - return Matter(stack) + override fun registerCapabilities(event: RegisterCapabilitiesEvent) { + event.registerItem(MatteryCapability.MATTER_ITEM, { o, _ -> Matter(o) }, this) } companion object { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/item/matter/MatterDustItem.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/item/matter/MatterDustItem.kt index 8447d888a..5965e0c15 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/item/matter/MatterDustItem.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/item/matter/MatterDustItem.kt @@ -18,20 +18,21 @@ import ru.dbotthepony.mc.otm.matter.IMatterItem import ru.dbotthepony.mc.otm.core.nbt.set import ru.dbotthepony.mc.otm.matter.IMatterValue import ru.dbotthepony.mc.otm.matter.MatterValue +import ru.dbotthepony.mc.otm.registry.MDataComponentTypes import ru.dbotthepony.mc.otm.registry.MItems class MatterDustItem : Item(Properties().stacksTo(64)), IMatterItem { private fun matter(stack: ItemStack): Decimal { - return stack.tag?.get("matter")?.let { return@let Decimal.deserializeNBT(it) } ?: return Decimal.ZERO + return stack.getOrDefault(MDataComponentTypes.MATTER_LEVEL, Decimal.ZERO) } private fun matter(stack: ItemStack, matter: Decimal) { - stack.orCreateTag["matter"] = matter.serializeNBT() + stack[MDataComponentTypes.MATTER_LEVEL] = matter } override fun getMatterValue(stack: ItemStack): IMatterValue? { - val value = stack.tag?.get("matter") ?: return null - return MatterValue(Decimal.deserializeNBT(value), 1.0) + val value = stack[MDataComponentTypes.MATTER_LEVEL] ?: return null + return MatterValue(value, 1.0) } fun moveIntoContainer(matterValue: Decimal, container: MatteryContainer, mainSlot: Int, stackingSlot: Int): Decimal { @@ -71,7 +72,7 @@ class MatterDustItem : Item(Properties().stacksTo(64)), IMatterItem { // можем ли мы стакнуть материю из второго слота в первый? if (!stack2.isEmpty && isFull(stack2)) { - if (ItemStack.isSameItemSameTags(stack, stack2) && container.getMaxStackSize(mainSlot, stack) >= stack.count + 1) { + if (ItemStack.isSameItemSameComponents(stack, stack2) && container.getMaxStackSize(mainSlot, stack) >= stack.count + 1) { stack.count++ stack2.count-- @@ -91,11 +92,11 @@ class MatterDustItem : Item(Properties().stacksTo(64)), IMatterItem { override fun appendHoverText( p_41421_: ItemStack, - p_41422_: Level?, + p_339594_: TooltipContext, p_41423_: MutableList, p_41424_: TooltipFlag ) { - super.appendHoverText(p_41421_, p_41422_, p_41423_, p_41424_) + super.appendHoverText(p_41421_, p_339594_, p_41423_, p_41424_) val matter = this.getMatterValue(p_41421_) if (matter == null) { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/item/matter/PatternStorageItem.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/item/matter/PatternStorageItem.kt index 6358a8258..514561761 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/item/matter/PatternStorageItem.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/item/matter/PatternStorageItem.kt @@ -1,27 +1,27 @@ package ru.dbotthepony.mc.otm.item.matter -import net.minecraft.world.item.ItemStack -import net.minecraft.nbt.CompoundTag -import net.minecraftforge.common.capabilities.ICapabilityProvider -import net.minecraft.world.item.TooltipFlag -import ru.dbotthepony.mc.otm.capability.MatteryCapability import net.minecraft.ChatFormatting -import net.minecraftforge.common.util.LazyOptional -import net.minecraft.nbt.ListTag -import net.minecraft.core.Direction import net.minecraft.network.chat.Component import net.minecraft.world.item.Item +import net.minecraft.world.item.ItemStack import net.minecraft.world.item.Rarity -import net.minecraft.world.level.Level -import net.minecraftforge.common.capabilities.Capability +import net.minecraft.world.item.TooltipFlag +import net.neoforged.neoforge.capabilities.RegisterCapabilitiesEvent +import ru.dbotthepony.mc.otm.capability.MatteryCapability +import ru.dbotthepony.mc.otm.capability.matter.IPatternStorage +import ru.dbotthepony.mc.otm.capability.matter.PatternInsertFailure +import ru.dbotthepony.mc.otm.capability.matter.PatternInsertInserted +import ru.dbotthepony.mc.otm.capability.matter.PatternInsertStatus +import ru.dbotthepony.mc.otm.capability.matter.PatternInsertUpdated +import ru.dbotthepony.mc.otm.capability.matter.PatternState +import ru.dbotthepony.mc.otm.capability.matter.getBarColor +import ru.dbotthepony.mc.otm.capability.matter.getBarWidth import ru.dbotthepony.mc.otm.core.TranslatableComponent -import ru.dbotthepony.mc.otm.capability.matter.* -import ru.dbotthepony.mc.otm.core.filterNotNull -import ru.dbotthepony.mc.otm.core.nbt.map -import java.util.* +import ru.dbotthepony.mc.otm.registry.CapabilitiesRegisterListener +import ru.dbotthepony.mc.otm.registry.MDataComponentTypes import java.util.stream.Stream -class PatternStorageItem : Item { +class PatternStorageItem : Item, CapabilitiesRegisterListener { private val _capacity: () -> Int val capacity get() = _capacity.invoke() var isCreative: Boolean @@ -41,17 +41,17 @@ class PatternStorageItem : Item { _capacity = { Int.MAX_VALUE } } - override fun initCapabilities(stack: ItemStack, nbt: CompoundTag?): ICapabilityProvider? { - return ItemPatternStorageCapability(stack) + override fun registerCapabilities(event: RegisterCapabilitiesEvent) { + event.registerItem(MatteryCapability.PATTERN_ITEM, { o, _ -> ItemPatternStorageCapability(o) }, this) } override fun appendHoverText( p_41421_: ItemStack, - p_41422_: Level?, + p_339594_: TooltipContext, list: MutableList, p_41424_: TooltipFlag ) { - p_41421_.getCapability(MatteryCapability.PATTERN).ifPresent { + p_41421_.getCapability(MatteryCapability.PATTERN_ITEM)?.let { if (isCreative) list.add(TranslatableComponent("otm.item.pattern.infinite.stored", it.storedPatterns).withStyle(ChatFormatting.GRAY)) else @@ -68,51 +68,41 @@ class PatternStorageItem : Item { } } - super.appendHoverText(p_41421_, p_41422_, list, p_41424_) + super.appendHoverText(p_41421_, p_339594_, list, p_41424_) } override fun isBarVisible(p_150899_: ItemStack): Boolean { if (isCreative) return false - return p_150899_.patterns != null + return p_150899_.getCapability(MatteryCapability.PATTERN_ITEM) != null } override fun getBarWidth(p_150900_: ItemStack): Int { if (isCreative) return 13 - return p_150900_.patterns?.getBarWidth() ?: super.getBarWidth(p_150900_) + return p_150900_.getCapability(MatteryCapability.PATTERN_ITEM)?.getBarWidth() ?: super.getBarWidth(p_150900_) } override fun getBarColor(p_150901_: ItemStack): Int { if (isCreative) return 0 - return p_150901_.patterns?.getBarColor() ?: super.getBarColor(p_150901_) + return p_150901_.getCapability(MatteryCapability.PATTERN_ITEM)?.getBarColor() ?: super.getBarColor(p_150901_) } - private inner class ItemPatternStorageCapability(val stack: ItemStack) : IPatternStorage, ICapabilityProvider { - private val resolver = LazyOptional.of { this } - + inner class ItemPatternStorageCapability(val stack: ItemStack) : IPatternStorage { override val patternCapacity: Int get() { return this@PatternStorageItem.capacity } override val storedPatterns: Int get() { - return stack.tag?.map("otm_patterns") { it: ListTag -> - it.size - } ?: 0 - } - - override fun getCapability(cap: Capability, side: Direction?): LazyOptional { - return if (cap == MatteryCapability.PATTERN) resolver.cast() else LazyOptional.empty() + return stack[MDataComponentTypes.PATTERNS]?.size ?: 0 } override val patterns: Stream get() { - return stack.tag?.map("otm_patterns") { it: ListTag -> - it.stream().map { PatternState.deserializeNBT(it) }.filterNotNull() - } ?: Stream.empty() + return stack[MDataComponentTypes.PATTERNS]?.stream() ?: Stream.empty() } override fun insertPattern( @@ -120,62 +110,28 @@ class PatternStorageItem : Item { onlyUpdate: Boolean, simulate: Boolean ): PatternInsertStatus { - val tag = stack.orCreateTag - var list = tag["otm_patterns"] + val patterns = ArrayList(stack[MDataComponentTypes.PATTERNS] ?: listOf()) - if (list !is ListTag) { - if (onlyUpdate) - return PatternInsertFailure - - if (simulate) { - if (patternCapacity > 0) - return PatternInsertInserted(pattern) - else - return PatternInsertFailure - } - - list = ListTag() - tag.put("otm_patterns", list) - } - - var invalidCounter = 0 - - for (i in list.indices) { - val state = PatternState.deserializeNBT(list.getCompound(i)) - - if (state != null) { - if (state.id == pattern.id) { - if (!simulate) { - list[i] = pattern.serializeNBT() - } - - return PatternInsertUpdated(pattern, state) + for ((i, ePattern) in patterns.withIndex()) { + if (ePattern.id == pattern.id) { + if (simulate) { + return PatternInsertUpdated(pattern, ePattern) } - } else { - invalidCounter++ + + patterns[i] = pattern + stack[MDataComponentTypes.PATTERNS] = patterns + return PatternInsertUpdated(pattern, ePattern) } } - if (onlyUpdate || patternCapacity <= list.size - invalidCounter) + if (onlyUpdate || patternCapacity <= patterns.size) return PatternInsertFailure - if (invalidCounter > 0) { - if (simulate) - return PatternInsertInserted(pattern) - - for (i in list.indices) { - val state = PatternState.deserializeNBT(list.getCompound(i)) - - if (state == null) { - list[i] = pattern.serializeNBT() - return PatternInsertInserted(pattern) - } - } + if (!simulate) { + patterns.add(pattern) + stack[MDataComponentTypes.PATTERNS] = patterns } - if (!simulate) - list.add(pattern.serializeNBT()) - return PatternInsertInserted(pattern) } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/item/tool/ExplosiveHammerItem.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/item/tool/ExplosiveHammerItem.kt index a5181c8b2..1e297179f 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/item/tool/ExplosiveHammerItem.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/item/tool/ExplosiveHammerItem.kt @@ -25,21 +25,22 @@ import net.minecraft.world.item.Item import net.minecraft.world.item.ItemStack import net.minecraft.world.item.TooltipFlag import net.minecraft.world.item.UseAnim +import net.minecraft.world.item.component.ItemAttributeModifiers import net.minecraft.world.level.Explosion import net.minecraft.world.level.Level import net.minecraft.world.phys.AABB import net.minecraft.world.phys.Vec3 -import net.minecraftforge.common.ForgeHooks -import net.minecraftforge.common.MinecraftForge -import net.minecraftforge.common.Tags -import net.minecraftforge.event.entity.player.PlayerInteractEvent -import net.minecraftforge.event.level.BlockEvent +import net.neoforged.neoforge.common.CommonHooks +import net.neoforged.neoforge.common.Tags +import net.neoforged.neoforge.event.EventHooks +import net.neoforged.neoforge.event.entity.player.PlayerInteractEvent import ru.dbotthepony.mc.otm.block.entity.MatteryBlockEntity import ru.dbotthepony.mc.otm.config.ToolsConfig import ru.dbotthepony.mc.otm.core.* import ru.dbotthepony.mc.otm.core.math.* import ru.dbotthepony.mc.otm.core.nbt.set import ru.dbotthepony.mc.otm.registry.MDamageTypes +import ru.dbotthepony.mc.otm.registry.MDataComponentTypes import ru.dbotthepony.mc.otm.registry.MatteryDamageSource import ru.dbotthepony.mc.otm.triggers.NailedEntityTrigger import java.util.function.Predicate @@ -50,16 +51,16 @@ class ExplosiveHammerItem(durability: Int = 512) : Item(Properties().stacksTo(1) } fun isPrimed(itemStack: ItemStack): Boolean { - return itemStack.tag?.getBoolean("primed") ?: false + return itemStack[MDataComponentTypes.PRIMED] ?: false } fun prime(itemStack: ItemStack) { - itemStack.tagNotNull["primed"] = true + itemStack[MDataComponentTypes.PRIMED] = true } fun unprime(itemStack: ItemStack) { if (isPrimed(itemStack)) - itemStack.tagNotNull["primed"] = false + itemStack[MDataComponentTypes.PRIMED] = false } fun canPrime(player: Player): Boolean { @@ -77,7 +78,7 @@ class ExplosiveHammerItem(durability: Int = 512) : Item(Properties().stacksTo(1) override fun hasCraftingRemainingItem(itemStack: ItemStack): Boolean = true override fun getCraftingRemainingItem(itemStack: ItemStack): ItemStack { - val player = ForgeHooks.getCraftingPlayer() ?: return itemStack.copy() + val player = CommonHooks.getCraftingPlayer() ?: return itemStack.copy() if (player.level().isClientSide) return itemStack.copy() if (!isPrimed(itemStack)) { @@ -234,9 +235,7 @@ class ExplosiveHammerItem(durability: Int = 512) : Item(Properties().stacksTo(1) val copy = itemStack.copy() - itemStack.hurtAndBreak(level.random.nextInt(1, 20), attacker) { - it.broadcastBreakEvent(hand) - } + itemStack.hurtAndBreak(level.random.nextInt(1, 20), attacker, EquipmentSlot.MAINHAND) if (!itemStack.isEmpty && attacker.random.nextDouble() <= ToolsConfig.ExplosiveHammer.FLY_OFF_CHANCE) { attacker.setItemInHand(hand, ItemStack.EMPTY) @@ -274,8 +273,13 @@ class ExplosiveHammerItem(durability: Int = 512) : Item(Properties().stacksTo(1) return true } - override fun appendHoverText(pStack: ItemStack, pLevel: Level?, pTooltipComponents: MutableList, pIsAdvanced: TooltipFlag) { - super.appendHoverText(pStack, pLevel, pTooltipComponents, pIsAdvanced) + override fun appendHoverText( + pStack: ItemStack, + p_339594_: TooltipContext, + pTooltipComponents: MutableList, + pIsAdvanced: TooltipFlag + ) { + super.appendHoverText(pStack, p_339594_, pTooltipComponents, pIsAdvanced) pTooltipComponents.add(TranslatableComponent("$descriptionId.desc").withStyle(ChatFormatting.DARK_GRAY)) @@ -291,8 +295,8 @@ class ExplosiveHammerItem(durability: Int = 512) : Item(Properties().stacksTo(1) return if (isPrimed(stack)) super.getUseAnimation(stack) else UseAnim.CROSSBOW } - override fun getUseDuration(stack: ItemStack): Int { - return if (isPrimed(stack)) super.getUseDuration(stack) else 20 + override fun getUseDuration(stack: ItemStack, p_344979_: LivingEntity): Int { + return if (isPrimed(stack)) super.getUseDuration(stack, p_344979_) else 20 } override fun use(level: Level, player: Player, hand: InteractionHand): InteractionResultHolder { @@ -321,7 +325,7 @@ class ExplosiveHammerItem(durability: Int = 512) : Item(Properties().stacksTo(1) } companion object { - val GUNPOWDER_PREDICATE = Predicate { stack: ItemStack -> stack.`is`(Tags.Items.GUNPOWDER) } + val GUNPOWDER_PREDICATE = Predicate { stack: ItemStack -> stack.`is`(Tags.Items.GUNPOWDERS) } val IRON_NUGGET_PREDICATE = Predicate { stack: ItemStack -> stack.`is`(Tags.Items.NUGGETS_IRON) } fun onLeftClickBlock(event: PlayerInteractEvent.LeftClickBlock) { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/item/tool/MatteryAxeItem.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/item/tool/MatteryAxeItem.kt index fcb65eaf3..dc01429aa 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/item/tool/MatteryAxeItem.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/item/tool/MatteryAxeItem.kt @@ -7,7 +7,7 @@ import net.minecraft.world.item.Tier import net.minecraft.world.level.block.state.BlockState import ru.dbotthepony.mc.otm.config.ToolsConfig -class MatteryAxeItem(pTier: Tier, pAttackDamageModifier: Float, pAttackSpeedModifier: Float, pProperties: Properties) : AxeItem(pTier, pAttackDamageModifier, pAttackSpeedModifier, pProperties) { +class MatteryAxeItem(pTier: Tier, pProperties: Properties) : AxeItem(pTier, pProperties) { override fun getDestroySpeed(pStack: ItemStack, pState: BlockState): Float { if (pState.`is`(BlockTags.LEAVES) && ToolsConfig.AXES_BREAK_LEAVES_INSTANTLY) return 64f diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/item/weapon/AbstractWeaponItem.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/item/weapon/AbstractWeaponItem.kt deleted file mode 100644 index ed973cc3e..000000000 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/item/weapon/AbstractWeaponItem.kt +++ /dev/null @@ -1,598 +0,0 @@ -package ru.dbotthepony.mc.otm.item.weapon - -import com.mojang.blaze3d.systems.RenderSystem -import net.minecraft.client.Minecraft -import net.minecraft.client.model.HumanoidModel -import net.minecraft.nbt.CompoundTag -import net.minecraft.network.FriendlyByteBuf -import net.minecraft.server.level.ServerPlayer -import net.minecraft.world.entity.Entity -import net.minecraft.world.entity.player.Player -import net.minecraft.world.item.Item -import net.minecraft.world.item.ItemDisplayContext -import net.minecraft.world.item.ItemStack -import net.minecraft.world.item.Rarity -import net.minecraft.world.level.block.state.BlockState -import net.minecraftforge.client.event.InputEvent -import net.minecraftforge.client.event.RenderHandEvent -import net.minecraftforge.client.event.RenderPlayerEvent -import net.minecraftforge.client.event.ViewportEvent -import net.minecraftforge.event.TickEvent -import net.minecraftforge.fml.LogicalSide -import ru.dbotthepony.mc.otm.capability.matteryEnergy -import ru.dbotthepony.mc.otm.client.font -import ru.dbotthepony.mc.otm.client.render.draw -import ru.dbotthepony.mc.otm.client.render.renderRect -import ru.dbotthepony.mc.otm.core.math.Angle -import ru.dbotthepony.kommons.math.RGBAColor -import ru.dbotthepony.mc.otm.core.math.Vector -import ru.dbotthepony.mc.otm.core.math.bezierCurve -import ru.dbotthepony.mc.otm.core.math.component1 -import ru.dbotthepony.mc.otm.core.math.component2 -import ru.dbotthepony.mc.otm.core.math.component3 -import ru.dbotthepony.mc.otm.core.math.linearInterpolation -import ru.dbotthepony.mc.otm.core.math.rotateX -import ru.dbotthepony.mc.otm.core.math.rotateY -import ru.dbotthepony.mc.otm.core.math.rotateZ -import ru.dbotthepony.mc.otm.core.nbt.EMPTY_UUID -import ru.dbotthepony.mc.otm.core.nbt.booleans -import ru.dbotthepony.mc.otm.core.nbt.ints -import ru.dbotthepony.mc.otm.core.nbt.uuids -import ru.dbotthepony.mc.otm.core.tagNotNull -import ru.dbotthepony.mc.otm.core.util.formatPower -import ru.dbotthepony.mc.otm.item.MatteryItem -import ru.dbotthepony.mc.otm.network.MNetworkContext -import ru.dbotthepony.mc.otm.network.MatteryPacket -import ru.dbotthepony.mc.otm.network.WeaponNetworkChannel -import java.util.* -import kotlin.collections.set -import kotlin.math.PI -import kotlin.math.abs -import kotlin.reflect.KClass -import kotlin.reflect.full.isSubclassOf -import kotlin.reflect.full.primaryConstructor - -private val ItemStack.weaponDataTable get() = tag?.let(::WeaponDataTable) - -enum class WeaponScopePacket(val scope: Boolean) : MatteryPacket { - SCOPE_IN(true), SCOPE_OUT(false); - - override fun write(buff: FriendlyByteBuf) { - buff.writeBoolean(scope) - } - - override fun play(context: MNetworkContext) { - // TODO: Manual synchronization - val stack = context.sender!!.mainHandItem - val item = stack.item as? AbstractWeaponItem<*> ?: return - - item.dataTable(stack).wantsToScope = scope - } - - companion object { - fun read(buff: FriendlyByteBuf) = if (buff.readBoolean()) SCOPE_IN else SCOPE_OUT - } -} - -enum class WeaponFireInputPacket(val primary: Boolean) : MatteryPacket { - PRIMARY(true), SECONDARY(false); - - override fun write(buff: FriendlyByteBuf) { - buff.writeBoolean(primary) - } - - override fun play(context: MNetworkContext) { - // TODO: Manual synchronization - val stack = context.sender!!.mainHandItem - val item = stack.item as? AbstractWeaponItem<*> ?: return - - // Listen server: client and server thread compete for lock - // so it is very likely item is being in predicted context - val predictedData = item.dataTable - item.dataTable = null - - if (primary) - item.tryPrimaryFire(stack, context.sender) - else - item.trySecondaryFire(stack, context.sender) - - (item as AbstractWeaponItem).dataTable = predictedData - } - - companion object { - fun read(buff: FriendlyByteBuf) = if (buff.readBoolean()) PRIMARY else SECONDARY - } -} - -open class WeaponDataTable(val tag: CompoundTag) { - var shotCooldown by tag.ints - var wantsToScope by tag.booleans - var scoped by tag.booleans - var scopeTicks by tag.ints - var nextPrimaryFire by tag.ints - var nextSecondaryFire by tag.ints - var uuid by tag.uuids - - var fireAnim = 0.0 - var fireAnimDeviation = Angle.ZERO - - fun doFireAnim(amount: Double = 0.8, deviation: Angle? = null) { - fireAnim = (fireAnim + amount).coerceAtLeast(0.0).coerceAtMost(1.0) - - if (deviation != null) { - fireAnimDeviation = Angle( - deviation.pitch * RANDOM.nextGaussian(), - deviation.yaw * RANDOM.nextGaussian(), - deviation.roll * RANDOM.nextGaussian(), - ) - } else { - fireAnimDeviation = Angle.ZERO - } - } - - var deployTime = 0.0 - - companion object { - private val RANDOM = Random() - } -} - -abstract class AbstractWeaponItem(val tables: KClass, properties: Properties = Properties().stacksTo(1).rarity(Rarity.RARE)) : MatteryItem(properties) { - fun makeDataTable(tag: CompoundTag) = tables.primaryConstructor!!.call(tag) - - /** - * Predicted data table, for client use only - */ - var dataTable: D? = null - set(value) { - field = if (value == null || value::class.isSubclassOf(tables)) { - value - } else { - throw ClassCastException("Reified generics: ${value::class.qualifiedName} cannot be cast to ${tables.qualifiedName}") - } - } - - fun compatibleDataTable(value: WeaponDataTable?) = value == null || value::class.isSubclassOf(tables) - - @Suppress("unchecked_cast") - fun dataTable(itemStack: ItemStack): D { - if (dataTable != null) { - return dataTable!! - } - - return makeDataTable(itemStack.tagNotNull) - } - - open fun holster(itemStack: ItemStack, player: Player, dt: D = dataTable(itemStack)) { - dt.wantsToScope = false - } - - open fun deploy(itemStack: ItemStack, player: Player, dt: D = dataTable(itemStack)) { - dt.wantsToScope = false - - if (dt.uuid == EMPTY_UUID) { - dt.uuid = UUID.randomUUID() - } - } - - abstract val roundsPerMinute: Int - val roundsPerSecond get() = roundsPerMinute / 60 - val fireCooldown get() = (1200 / roundsPerMinute).coerceAtLeast(1) - - open val positionHolstered get() = Vector(1.0, -2.5, -1.0) - open val positionIdle get() = Vector(1.0, -0.5, -1.0) - open val positionIronSights get() = Vector(0.0, -0.23, -1.0) - open val rotIdle get() = Angle(PI / 36, PI / 18) - open val rotIronSights get() = Angle.ZERO - open val rotFireAnim get() = Angle.deg(20.0, 0.0, 0.0) - open val rotFireAnimDeviation get() = Angle.deg(2.0, 1.0, 1.0) - - open val fireAnimRecovery = 1.0 - open val deployAnimSpeed = 1.0 - - open val primaryAutomatic = true - open val secondaryAutomatic = true - - open val ironSightsFOV: Double get() = 2.0 - - fun ironSightsProgress(itemStack: ItemStack, partialTicks: Double = 0.0, dt: D = dataTable(itemStack)): Double { - if (!dt.wantsToScope) - return (((dt.scopeTicks.toDouble() - partialTicks).coerceAtLeast(0.0) / scopingTime.toDouble()) * 1.4).coerceAtMost(1.0) - - return (((dt.scopeTicks.toDouble() + partialTicks) / scopingTime.toDouble()) * 1.4).coerceAtMost(1.0) - } - - abstract val scopingTime: Int - - open fun think(itemStack: ItemStack, player: Player, dt: D = dataTable(itemStack)) { - if (dt.wantsToScope && dt.scopeTicks < scopingTime) { - dt.scopeTicks++ - } else if (!dt.wantsToScope && dt.scopeTicks > 0) { - dt.scopeTicks-- - } - } - - open fun thinkHolstered(itemStack: ItemStack, player: Player, dt: D = dataTable(itemStack)) { - if (dt.shotCooldown > 0) { - dt.shotCooldown-- - } - } - - open fun think2(itemStack: ItemStack, player: Player, dt: D = dataTable(itemStack)) { - if (dt.nextPrimaryFire > 0) { - dt.nextPrimaryFire-- - } - - if (dt.nextSecondaryFire > 0) { - dt.nextSecondaryFire-- - } - } - - open fun primaryFire(itemStack: ItemStack, player: Player, dt: D = dataTable(itemStack)): Boolean { - return false - } - - open fun secondaryFire(itemStack: ItemStack, player: Player, dt: D = dataTable(itemStack)): Boolean { - return false - } - - open fun canPrimaryFire(itemStack: ItemStack, player: Player, dt: D = dataTable(itemStack)): Boolean { - if (player is ServerPlayer) { - // allow a little deviation, because nothing is perfect - return dt.nextPrimaryFire <= 2 - } - - return dt.nextPrimaryFire <= 0 - } - - fun tryPrimaryFire(itemStack: ItemStack, player: Player, dt: D = dataTable(itemStack)): Boolean { - if (canPrimaryFire(itemStack, player, dt) && primaryFire(itemStack, player, dt)) { - dt.nextPrimaryFire = fireCooldown - return true - } - - return false - } - - fun trySecondaryFire(itemStack: ItemStack, player: Player, dt: D = dataTable(itemStack)): Boolean { - if (dt.nextSecondaryFire <= 0 && secondaryFire(itemStack, player, dt)) { - dt.nextSecondaryFire = fireCooldown - return true - } - - return false - } - - override fun getDestroySpeed(p_41425_: ItemStack, p_41426_: BlockState): Float { - return 0f - } - - override fun onLeftClickEntity(stack: ItemStack?, player: Player?, entity: Entity?): Boolean { - return true - } - - companion object { - // shared - private val items = WeakHashMap() - - // client only - private var inRender = false - var predictedData: WeaponDataTable? = null - private var lastFov = 1.0 - private var lastFovTime = 0L - - fun fovHook(event: ViewportEvent.ComputeFov) { - val player = event.camera.entity as? Player ?: return - - val it = (player.mainHandItem.item as? AbstractWeaponItem<*>) - - if (it != null) { - @Suppress("unchecked_cast") - if (it.compatibleDataTable(predictedData)) - (it as AbstractWeaponItem).dataTable = predictedData - - val interp = ru.dbotthepony.mc.otm.core.math.linearInterpolation( - it.ironSightsProgress( - player.mainHandItem, - event.partialTick - ) * 1.7 - 0.6, 1.0, it.ironSightsFOV - ) - - val time = System.nanoTime() - val diff = abs(lastFovTime - time) - lastFov = ru.dbotthepony.mc.otm.core.math.linearInterpolation( - diff.coerceIn(0L, 10_000_000L).toDouble() / 10_000_000.0, lastFov, interp - ).coerceAtLeast(0.001) - lastFovTime = time - - event.fov /= lastFov - - it.dataTable = null - } else { - lastFov = 1.0 - lastFovTime = 0L - } - } - - fun playerRenderHook(event: RenderPlayerEvent.Pre) { - if (event.entity.mainHandItem.item is AbstractWeaponItem<*> && event.entity.offhandItem.isEmpty) { - event.renderer.model.rightArmPose = HumanoidModel.ArmPose.BOW_AND_ARROW - event.renderer.model.leftArmPose = HumanoidModel.ArmPose.EMPTY - } - } - - fun clickHook(event: InputEvent.InteractionKeyMappingTriggered) { - val player = Minecraft.getInstance().player!! - - if (player.mainHandItem.item is AbstractWeaponItem<*> && player.offhandItem.isEmpty && event.isAttack) { - event.isCanceled = true - event.setSwingHand(false) - } - } - - private var lastClientRender = 0L - - private val fireAnimInterp = doubleArrayOf( - 0.0, - 0.01, - 0.03, - 0.04, - 0.05, - 0.06, - 0.07, - 0.1, - 0.15, - 0.3, - 0.45, - 0.6, - 0.8, - 0.85, - 0.9, - 1.0, - 0.9, - 0.6, - ) - - @Suppress("unchecked_cast") - fun renderViewModel(event: RenderHandEvent) { - if (inRender) { - return - } - - val time = System.nanoTime() - val diff = abs(lastClientRender - time) - lastClientRender = time - - val stack = event.itemStack - val item = stack.item as? AbstractWeaponItem<*> ?: return - - inRender = true - event.isCanceled = true - - (item as AbstractWeaponItem).dataTable = predictedData - - predictedData?.deployTime = (predictedData!!.deployTime + diff.toDouble() / (300_000_000.0 * item.deployAnimSpeed)).coerceAtMost(1.0).coerceAtLeast(0.0) - predictedData?.fireAnim = (predictedData!!.fireAnim - diff.toDouble() / (400_000_000.0 * item.fireAnimRecovery)).coerceAtMost(1.0).coerceAtLeast(0.0) - - val player = Minecraft.getInstance().player!! - val pose = event.poseStack - val itemInHandRenderer = Minecraft.getInstance().entityRenderDispatcher.itemInHandRenderer - - pose.pushPose() - - val progress = item.ironSightsProgress(stack, event.partialTick.toDouble()) - - val (x, y, z) = linearInterpolation( - // 1.0 - event.equipProgress.toDouble(), - item.dataTable?.deployTime ?: 0.0, - item.positionHolstered, - bezierCurve( - progress, - item.positionIdle, - item.positionIdle, - item.positionIdle, - Vector(0.0, -1.0, -1.0), - item.positionIronSights, - item.positionIronSights, - item.positionIronSights, - ) - ) - - pose.translate(x, y, z) - - var (pitch, yaw, roll) = bezierCurve( - progress, - item.rotIdle, - item.rotIdle, - item.rotIdle, - item.rotIdle.copy(roll = -PI.toFloat() / 6f + item.rotIdle.roll), - item.rotIronSights, - item.rotIronSights, - item.rotIronSights, - item.rotIronSights, - item.rotIronSights, - ) - - val fireAnim = bezierCurve( - predictedData?.fireAnim ?: 0.0, - fireAnimInterp - ) - - val rotFire = item.rotFireAnim - pitch += (rotFire.pitch + (predictedData?.fireAnimDeviation?.pitch ?: 0.0)) * fireAnim * (1.0 - progress * 0.6) - yaw += (rotFire.yaw + (predictedData?.fireAnimDeviation?.yaw ?: 0.0)) * fireAnim * (1.0 - progress * 0.6) - roll += (rotFire.roll + (predictedData?.fireAnimDeviation?.roll ?: 0.0)) * fireAnim * (1.0 - progress * 0.6) - - pose.rotateZ(roll.toFloat()) - pose.rotateY(yaw.toFloat()) - pose.rotateX(pitch.toFloat()) - - itemInHandRenderer.renderItem( - player, - stack, - ItemDisplayContext.FIRST_PERSON_RIGHT_HAND, - false, - pose, - event.multiBufferSource, - event.packedLight - ) - - if (item is PlasmaWeaponItem<*>) { - // RenderSystem.setShader(GameRenderer::getPositionColorShader) - // RenderSystem.disableTexture() - // RenderSystem.enableBlend() - - RenderSystem.setShaderColor(1f, 1f, 1f, 1f) - - pose.translate(-0.85, 0.25, -0.25) - pose.rotateZ(PI.toFloat()) - pose.rotateY(PI.toFloat()) - pose.scale(0.01f, 0.01f, 0.01f) - - renderRect(pose.last().pose(), -2f, -2f, 72f, 34f, color = holoHudBackground) - - stack.matteryEnergy?.let { - pose.pushPose() - pose.translate(0.0, 0.0, -1.0) - pose.scale(0.7f, 0.7f, 0.7f) - val text = it.batteryLevel.formatPower() - font.draw(pose, text, 2f, 2f, color = RGBAColor.WHITE) - pose.popPose() - } - - pose.translate(60.0, 0.0, 0.0) - - renderRect(pose.last().pose(), -1f, -1f, 9f, 32f, color = heatBackground) - - val heat = item.heatProgress(stack, event.partialTick.toDouble()).toFloat() - renderRect(pose.last().pose(), 0f, 30f * (1f - heat), 7f, 30f * heat, color = initialHeatColor.linearInterpolation(heat, finalHeatColor)) - } - - pose.popPose() - - item.dataTable = null - inRender = false - } - - private val holoHudBackground get() = RGBAColor(75, 75, 75, 160) - private val heatBackground get() = RGBAColor(40, 144, 210, 160) - private val initialHeatColor get() = RGBAColor(85, 68, 7, 160) - private val finalHeatColor get() = RGBAColor(245, 118, 41, 160) - - private val localPlayer: Player? get() { - return Minecraft.getInstance().player - } - - private var firedPrimary = false - private var firedSecondary = false - - private fun processClientInputs(item: AbstractWeaponItem<*>, itemStack: ItemStack) { - val minecraft = Minecraft.getInstance() - val player = minecraft.player ?: return - val dt = item.dataTable(itemStack) - - if (!dt.wantsToScope && minecraft.options.keyUse.isDown) { - dt.wantsToScope = true - WeaponNetworkChannel.sendToServer(WeaponScopePacket.SCOPE_IN) - } else if (dt.wantsToScope && !minecraft.options.keyUse.isDown) { - dt.wantsToScope = false - WeaponNetworkChannel.sendToServer(WeaponScopePacket.SCOPE_OUT) - } - - if (minecraft.options.keyAttack.isDown && (item.primaryAutomatic || !firedPrimary)) { - firedPrimary = true - - if (item.tryPrimaryFire(itemStack, player)) { - WeaponNetworkChannel.sendToServer(WeaponFireInputPacket.PRIMARY) - } - } else if (!minecraft.options.keyAttack.isDown) { - firedPrimary = false - } - - if (minecraft.options.keyAttack.isDown && (item.secondaryAutomatic || !firedSecondary)) { - firedSecondary = true - - if (item.trySecondaryFire(itemStack, player)) { - WeaponNetworkChannel.sendToServer(WeaponFireInputPacket.SECONDARY) - } - } else if (!minecraft.options.keyAttack.isDown) { - firedSecondary = false - } - } - - @Suppress("unchecked_cast") - fun tick(event: TickEvent.PlayerTickEvent) { - if (event.phase != TickEvent.Phase.START) - return - - if (event.side == LogicalSide.CLIENT && event.player != localPlayer) - return - - val held = event.player.mainHandItem - - for (stack in event.player.inventory.items) { - if (held !== stack) { - (stack.item as? AbstractWeaponItem<*>)?.thinkHolstered(stack, event.player) - } - - (stack.item as? AbstractWeaponItem<*>)?.let { - if (event.side == LogicalSide.CLIENT && stack.weaponDataTable?.uuid != predictedData?.uuid) - return@let - - if (event.side == LogicalSide.CLIENT) { - (it as AbstractWeaponItem).dataTable = predictedData - } - - it.think2(stack, event.player) - - if (event.side == LogicalSide.CLIENT) { - it.dataTable = null - } - } - } - - val prev = items[event.player] - val heldItem = held.item - - if (held.weaponDataTable?.uuid != prev?.weaponDataTable?.uuid) { - (prev?.item as? AbstractWeaponItem<*>)?.let { - if (event.side == LogicalSide.CLIENT) { - (it as AbstractWeaponItem).dataTable = predictedData - } - - it.holster(prev, event.player) - - if (event.side == LogicalSide.CLIENT) { - it.dataTable = null - } - } - - (held.item as? AbstractWeaponItem<*>)?.deploy(held, event.player) - - items[event.player] = held - - if (event.side == LogicalSide.CLIENT && heldItem is AbstractWeaponItem<*>) { - predictedData = heldItem.makeDataTable(held.tagNotNull.copy()) - - firedPrimary = false - firedSecondary = false - } - } - - if (heldItem is AbstractWeaponItem<*>) { - // this can fail horribly, and die horribly, if weapon item changed, - // but its UUID did not (compound tag fraud) - if (event.side == LogicalSide.CLIENT) { - (heldItem as AbstractWeaponItem).dataTable = predictedData - processClientInputs(heldItem, held) - } - - heldItem.think(held, event.player) - - if (event.side == LogicalSide.CLIENT) { - heldItem.dataTable = null - } - } - } - } -} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/item/weapon/EnergySwordItem.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/item/weapon/EnergySwordItem.kt index 072273f12..cc39cae4b 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/item/weapon/EnergySwordItem.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/item/weapon/EnergySwordItem.kt @@ -2,10 +2,9 @@ package ru.dbotthepony.mc.otm.item.weapon import com.google.common.collect.ImmutableMultimap import com.google.common.collect.Multimap -import net.minecraft.ChatFormatting import net.minecraft.core.BlockPos +import net.minecraft.core.Holder import net.minecraft.nbt.CompoundTag -import net.minecraft.network.chat.Component import net.minecraft.tags.BlockTags import net.minecraft.world.entity.EquipmentSlot import net.minecraft.world.entity.LivingEntity @@ -13,49 +12,40 @@ import net.minecraft.world.entity.ai.attributes.Attribute import net.minecraft.world.entity.ai.attributes.AttributeModifier import net.minecraft.world.entity.ai.attributes.Attributes import net.minecraft.world.entity.player.Player -import net.minecraft.world.item.Item import net.minecraft.world.item.ItemStack import net.minecraft.world.item.Rarity -import net.minecraft.world.item.TooltipFlag -import net.minecraft.world.item.Vanishable +import net.minecraft.world.item.component.ItemAttributeModifiers import net.minecraft.world.item.enchantment.Enchantment import net.minecraft.world.item.enchantment.EnchantmentCategory import net.minecraft.world.item.enchantment.Enchantments import net.minecraft.world.level.Level import net.minecraft.world.level.block.Blocks import net.minecraft.world.level.block.state.BlockState -import net.minecraftforge.common.ForgeConfigSpec -import net.minecraftforge.common.ToolAction -import net.minecraftforge.common.ToolActions -import net.minecraftforge.common.capabilities.ICapabilityProvider -import ru.dbotthepony.mc.otm.capability.energy.EnergyConsumerItem -import ru.dbotthepony.mc.otm.capability.energy.ItemEnergyStorageImpl +import net.neoforged.neoforge.common.ModConfigSpec import ru.dbotthepony.mc.otm.capability.MatteryCapability +import ru.dbotthepony.mc.otm.capability.energy.EnergyConsumerItem import ru.dbotthepony.mc.otm.capability.energy.extractEnergyExact import ru.dbotthepony.mc.otm.capability.energy.getBarColor import ru.dbotthepony.mc.otm.capability.energy.getBarWidth import ru.dbotthepony.mc.otm.capability.matteryEnergy import ru.dbotthepony.mc.otm.capability.matteryPlayer +import ru.dbotthepony.mc.otm.core.damageType import ru.dbotthepony.mc.otm.core.math.Decimal import ru.dbotthepony.mc.otm.core.math.DecimalConfigValue -import ru.dbotthepony.mc.otm.core.TranslatableComponent -import ru.dbotthepony.mc.otm.core.damageType import ru.dbotthepony.mc.otm.core.math.defineDecimal -import ru.dbotthepony.mc.otm.core.ifPresentK import ru.dbotthepony.mc.otm.core.math.nextVariance -import ru.dbotthepony.mc.otm.core.orNull import ru.dbotthepony.mc.otm.core.util.WriteOnce import ru.dbotthepony.mc.otm.item.MatteryItem import ru.dbotthepony.mc.otm.item.addSimpleDescription import ru.dbotthepony.mc.otm.registry.MDamageTypes import ru.dbotthepony.mc.otm.registry.MatteryDamageSource -class EnergySwordItem : MatteryItem(Properties().stacksTo(1).rarity(Rarity.RARE)), Vanishable { - val chargedAttributes: Multimap - val dischargedAttributes: Multimap +class EnergySwordItem : MatteryItem(Properties().stacksTo(1).rarity(Rarity.RARE)) { + val chargedAttributes: ItemAttributeModifiers + val dischargedAttributes: ItemAttributeModifiers init { - var builder = ImmutableMultimap.builder() + var builder = ImmutableMultimap.builder, AttributeModifier>() builder.put(Attributes.ATTACK_DAMAGE, AttributeModifier(BASE_ATTACK_DAMAGE_UUID, "Weapon modifier", 11.0, AttributeModifier.Operation.ADDITION)) builder.put(Attributes.ATTACK_SPEED, AttributeModifier(BASE_ATTACK_SPEED_UUID, "Weapon modifier", -2.4, AttributeModifier.Operation.ADDITION)) @@ -83,7 +73,7 @@ class EnergySwordItem : MatteryItem(Properties().stacksTo(1).rarity(Rarity.RARE) } override fun getDestroySpeed(itemStack: ItemStack, blockState: BlockState): Float { - val energy = itemStack.getCapability(MatteryCapability.ENERGY).orNull() ?: return 1f + val energy = itemStack.getCapability(MatteryCapability.ITEM_ENERGY) ?: return 1f if (blockState.`is`(Blocks.COBWEB)) { return if (energy.batteryLevel < COBWEB_POWER_COST) 2f else 25f @@ -110,7 +100,7 @@ class EnergySwordItem : MatteryItem(Properties().stacksTo(1).rarity(Rarity.RARE) return true } - itemStack.getCapability(MatteryCapability.ENERGY).ifPresentK { + itemStack.getCapability(MatteryCapability.ITEM_ENERGY)?.let { if (it.extractEnergyExact(ENERGY_PER_SWING, false)) { it.extractEnergy(attacker.level().random.nextVariance(ENERGY_PER_SWING_VARIANCE), false) victim.matteryPlayer?.let { @@ -174,6 +164,10 @@ class EnergySwordItem : MatteryItem(Properties().stacksTo(1).rarity(Rarity.RARE) return EnergyConsumerItem(stack, MAX_ENERGY) } + override fun getDefaultAttributeModifiers(stack: ItemStack): ItemAttributeModifiers { + return super.getDefaultAttributeModifiers(stack) + } + override fun getAttributeModifiers( slot: EquipmentSlot, itemStack: ItemStack @@ -220,7 +214,7 @@ class EnergySwordItem : MatteryItem(Properties().stacksTo(1).rarity(Rarity.RARE) private var _PLANT_POWER_COST: DecimalConfigValue by WriteOnce() private var _PLANT_POWER_COST_VARIANCE: DecimalConfigValue by WriteOnce() - fun registerConfig(builder: ForgeConfigSpec.Builder) { + fun registerConfig(builder: ModConfigSpec.Builder) { builder.comment("Energy sword values").push("EnergySword") _MAX_ENERGY = builder.defineDecimal("MAX_ENERGY", Decimal(2_000_000), Decimal.ZERO) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/item/weapon/PlasmaRifleItem.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/item/weapon/PlasmaRifleItem.kt deleted file mode 100644 index afdbc7a1d..000000000 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/item/weapon/PlasmaRifleItem.kt +++ /dev/null @@ -1,66 +0,0 @@ -package ru.dbotthepony.mc.otm.item.weapon - -import net.minecraft.sounds.SoundSource -import net.minecraft.world.entity.player.Player -import net.minecraft.world.item.ItemStack -import ru.dbotthepony.mc.otm.capability.energy.extractEnergyExact -import ru.dbotthepony.mc.otm.core.math.Angle -import ru.dbotthepony.mc.otm.core.math.Vector -import ru.dbotthepony.mc.otm.core.math.Decimal -import ru.dbotthepony.mc.otm.entity.PlasmaProjectile -import ru.dbotthepony.mc.otm.core.position -import ru.dbotthepony.mc.otm.registry.MSoundEvents - -class PlasmaRifleItem : PlasmaWeaponItem(PlasmaWeaponDataTable::class, Decimal(200_000)) { - override val roundsPerMinute: Int = 200 - override val scopingTime: Int = 7 - - override val positionIdle: Vector - get() = Vector(0.2, -0.4, -0.6) - override val positionIronSights: Vector - get() = Vector(0.0, -0.24, -1.0) - override val rotIdle: Angle - get() = Angle(0.0, -0.02, 0.0) - override val rotIronSights: Angle - get() = Angle(-0.02, 0.0, 0.0) - - override fun primaryFire(itemStack: ItemStack, player: Player, dt: PlasmaWeaponDataTable): Boolean { - if (!player.level().isClientSide) { - val arrow = PlasmaProjectile(player.level()) - arrow.position = player.eyePosition - - val calc = VelocityCalculation(player, force = 4.0, deviation = 0.3) - calc.load(arrow) - - arrow.owner = player - - player.level().addFreshEntity(arrow) - } else { - dt.doFireAnim(deviation = rotFireAnimDeviation) - } - - receiveHeat(itemStack, player, 10.0, dt) - - player.level().playSound( - player, - player, - MSoundEvents.RIFLE_SHOT, - SoundSource.PLAYERS, - 1f, - 1f - ) - - if (!player.abilities.instabuild) - energyData(itemStack).extractEnergy(ENERGY_PER_SHOT, false) - - return true - } - - override fun canPrimaryFire(itemStack: ItemStack, player: Player, dt: PlasmaWeaponDataTable): Boolean { - return super.canPrimaryFire(itemStack, player, dt) && (player.abilities.instabuild || energyData(itemStack).extractEnergyExact(ENERGY_PER_SHOT, true)) - } - - companion object { - private val ENERGY_PER_SHOT = Decimal(3_000) - } -} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/item/weapon/PlasmaWeaponItem.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/item/weapon/PlasmaWeaponItem.kt deleted file mode 100644 index d593ec91e..000000000 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/item/weapon/PlasmaWeaponItem.kt +++ /dev/null @@ -1,295 +0,0 @@ -package ru.dbotthepony.mc.otm.item.weapon - -import net.minecraft.ChatFormatting -import net.minecraft.core.Direction -import net.minecraft.nbt.CompoundTag -import net.minecraft.network.chat.Component -import net.minecraft.server.level.ServerPlayer -import net.minecraft.sounds.SoundSource -import net.minecraft.world.entity.player.Player -import net.minecraft.world.item.ItemStack -import net.minecraft.world.item.TooltipFlag -import net.minecraft.world.level.Level -import net.minecraftforge.common.capabilities.Capability -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 ru.dbotthepony.mc.otm.* -import ru.dbotthepony.mc.otm.capability.* -import ru.dbotthepony.mc.otm.capability.energy.IMatteryEnergyStorage -import ru.dbotthepony.mc.otm.capability.energy.ItemEnergyStorageImpl -import ru.dbotthepony.mc.otm.capability.energy.getBarColor -import ru.dbotthepony.mc.otm.capability.energy.getBarWidth -import ru.dbotthepony.mc.otm.core.* -import ru.dbotthepony.mc.otm.core.math.Decimal -import ru.dbotthepony.mc.otm.core.math.bezierCurve -import ru.dbotthepony.mc.otm.core.nbt.doubles -import ru.dbotthepony.mc.otm.core.nbt.ints -import ru.dbotthepony.mc.otm.core.nbt.set -import ru.dbotthepony.mc.otm.core.util.formatPower -import ru.dbotthepony.mc.otm.registry.MSoundEvents -import kotlin.reflect.KClass - -class PlasmaWeaponEnergy(val itemStack: ItemStack, private val innerCapacity: Decimal) : IMatteryEnergyStorage, ICapabilityProvider, INBTSerializable { - private val energyResolver = LazyOptional.of { this } - private var innerBatteryLevel = Decimal.ZERO - - override val energyFlow: FlowDirection - get() = FlowDirection.INPUT - - var battery: ItemStack = ItemStack.EMPTY - - override fun getCapability(cap: Capability, side: Direction?): LazyOptional { - if (cap == MatteryCapability.ENERGY || cap == ForgeCapabilities.ENERGY) { - return energyResolver.cast() - } - - return LazyOptional.empty() - } - - override fun serializeNBT(): CompoundTag { - val nbt = CompoundTag() - nbt["battery_level"] = innerBatteryLevel.serializeNBT() - nbt["battery"] = battery.serializeNBT() - return nbt - } - - override fun deserializeNBT(nbt: CompoundTag) { - innerBatteryLevel = Decimal.deserializeNBT(nbt["battery_level"]) - battery = ItemStack.of(nbt["battery"] as CompoundTag) - } - - override fun extractEnergy(howMuch: Decimal, simulate: Boolean): Decimal { - if (!howMuch.isPositive) - return Decimal.ZERO - - @Suppress("NAME_SHADOWING") - var howMuch = howMuch - var totalExtracted = Decimal.ZERO - - if (!battery.isEmpty) { - battery.getCapability(ForgeCapabilities.ENERGY).ifPresentK { - val extracted = it.extractEnergy(howMuch, simulate) - - if (extracted >= howMuch) { - return extracted - } - - howMuch -= extracted - totalExtracted += extracted - } - } - - val newEnergy = (innerBatteryLevel - howMuch).moreThanZero() - val diff = innerBatteryLevel - newEnergy - - if (!simulate) { - innerBatteryLevel = newEnergy - } - - return diff + totalExtracted - } - - override fun receiveEnergy(howMuch: Decimal, simulate: Boolean): Decimal { - if (!howMuch.isPositive) - return Decimal.ZERO - - @Suppress("NAME_SHADOWING") - var howMuch = howMuch - var totalReceived = Decimal.ZERO - - if (!battery.isEmpty) { - battery.getCapability(ForgeCapabilities.ENERGY).ifPresentK { - val received = it.receiveEnergy(howMuch, simulate) - - if (received >= howMuch) { - return received - } - - howMuch -= received - totalReceived += received - } - } - - if (innerBatteryLevel >= innerCapacity) { - return totalReceived - } - - val newEnergy = (innerBatteryLevel + howMuch).coerceAtMost(innerCapacity) - val diff = newEnergy - innerBatteryLevel - - if (!simulate) { - innerBatteryLevel = newEnergy - } - - return diff + totalReceived - } - - fun think() { - if (!battery.isEmpty && innerBatteryLevel < innerCapacity) { - battery.getCapability(ForgeCapabilities.ENERGY).ifPresentK { - innerBatteryLevel += it.extractEnergy(innerCapacity - innerBatteryLevel, false) - } - } - } - - override fun drainBattery(): Boolean { - innerBatteryLevel = Decimal.ZERO - - if (!battery.isEmpty) { - battery.getCapability(MatteryCapability.ENERGY).ifPresentK { - return it.drainBattery() - } - } - - return true - } - - override fun fillBattery(): Boolean { - innerBatteryLevel = innerCapacity - - if (!battery.isEmpty) { - battery.getCapability(MatteryCapability.ENERGY).ifPresentK { - return it.fillBattery() - } - } - - return true - } - - override var batteryLevel: Decimal - get() = (battery.energy?.energyStoredMattery ?: Decimal.ZERO) + innerBatteryLevel - set(value) { - innerBatteryLevel = value - } - - override val maxBatteryLevel: Decimal - get() = (battery.energy?.maxEnergyStoredMattery ?: Decimal.ZERO) + innerCapacity -} - -open class PlasmaWeaponDataTable(tag: CompoundTag) : WeaponDataTable(tag) { - var heatScore by tag.doubles - var heatCooldown by tag.ints -} - -abstract class PlasmaWeaponItem(tables: KClass, private val energyCapacity: Decimal) : AbstractWeaponItem(tables) { - init { - tooltips.itemEnergy() - } - - fun energyData(itemStack: ItemStack) = itemStack.matteryEnergy as PlasmaWeaponEnergy - - open val cooldownSpeed get() = 1.0 - open val maxHeat = 40.0 - open val overheatCooldown = 30 - - open val cooldownSpline = doubleArrayOf( - 0.1, - 0.14, - 0.18, - 0.25, - 0.35, - 0.45, - 0.6, - 0.8, - 0.97, - 1.0, - 1.0, - 1.0, - 1.0, - 1.0, - 1.0, - 1.1, - 1.2, - 1.3, - 1.4, - ) - - override fun canPrimaryFire(itemStack: ItemStack, player: Player, dt: D): Boolean { - if (player is ServerPlayer) { - // allow little deviation because nothing is perfect - return super.canPrimaryFire(itemStack, player, dt) && dt.heatCooldown <= 2 - } - - return super.canPrimaryFire(itemStack, player, dt) && dt.heatCooldown <= 0 - } - - open fun canCooldown(itemStack: ItemStack, player: Player, dt: D = dataTable(itemStack)): Boolean { - return true - } - - override fun isBarVisible(p_150899_: ItemStack): Boolean { - return p_150899_.matteryEnergy != null - } - - override fun getBarWidth(p_150900_: ItemStack): Int { - return p_150900_.matteryEnergy?.getBarWidth() ?: super.getBarWidth(p_150900_) - } - - override fun getBarColor(p_150901_: ItemStack): Int { - return p_150901_.matteryEnergy?.getBarColor() ?: super.getBarColor(p_150901_) - } - - protected open fun coolWeaponDown(itemStack: ItemStack, player: Player, dt: D) { - if (!canCooldown(itemStack, player, dt)) - return - - if (dt.heatScore > 0.0) - dt.heatScore = (dt.heatScore - cooldownSpeed * bezierCurve(heatProgress(itemStack, dt = dt), cooldownSpline)).coerceAtLeast(0.0) - - if (dt.heatCooldown > 0) - dt.heatCooldown-- - } - - open fun heatProgress(itemStack: ItemStack, partialTicks: Double = 0.0, dt: D = dataTable(itemStack)): Double { - if (dt.heatScore <= 0) - return 0.0 - - if (dt.heatScore - cooldownSpeed > maxHeat) - return 1.0 - - val result = dt.heatScore - cooldownSpeed * partialTicks - return result / maxHeat - } - - open fun overheatProgress(itemStack: ItemStack, partialTicks: Double = 0.0, dt: D = dataTable(itemStack)): Double { - if (dt.heatCooldown <= 0) - return 0.0 - - if (dt.heatCooldown - partialTicks > overheatCooldown) - return 1.0 - - val result = dt.heatCooldown - partialTicks - return result / overheatCooldown - } - - open fun receiveHeat(itemStack: ItemStack, player: Player, byTicks: Double, dt: D = dataTable(itemStack)) { - dt.heatScore = (dt.heatScore + byTicks).coerceAtMost(maxHeat * 2) - - if (dt.heatScore > maxHeat) { - val before = dt.heatCooldown > 0 - - dt.heatCooldown = overheatCooldown - - if (!before) { - player.level().playSound(player, player, MSoundEvents.PLASMA_WEAPON_OVERHEAT, SoundSource.PLAYERS, 1f, 1f) - } - } - } - - override fun think2(itemStack: ItemStack, player: Player, dt: D) { - super.think2(itemStack, player, dt) - - coolWeaponDown(itemStack, player, dt) - - itemStack.getCapability(MatteryCapability.ENERGY).ifPresentK { - it as PlasmaWeaponEnergy - it.think() - } - } - - override fun initCapabilities(stack: ItemStack, nbt: CompoundTag?): ICapabilityProvider { - return PlasmaWeaponEnergy(stack, energyCapacity) - } -} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/matter/AbstractRegistryAction.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/matter/AbstractRegistryAction.kt index d03613743..69147d98b 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/matter/AbstractRegistryAction.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/matter/AbstractRegistryAction.kt @@ -6,13 +6,14 @@ import com.mojang.datafixers.util.Pair import com.mojang.serialization.Codec import com.mojang.serialization.DataResult import com.mojang.serialization.DynamicOps +import com.mojang.serialization.MapCodec import net.minecraft.core.registries.Registries import net.minecraft.resources.ResourceLocation import net.minecraft.tags.TagKey import net.minecraft.world.item.Item -import net.minecraftforge.eventbus.api.IEventBus -import net.minecraftforge.registries.DeferredRegister +import net.neoforged.bus.api.IEventBus import ru.dbotthepony.mc.otm.OverdriveThatMatters +import ru.dbotthepony.mc.otm.registry.MDeferredRegister import ru.dbotthepony.mc.otm.registry.RegistryDelegate import java.util.* @@ -22,7 +23,7 @@ abstract class AbstractRegistryAction( val priority: Optional = Optional.empty(), ) : Comparable { interface Type { - val codec: Codec + val codec: MapCodec } fun update(registry: MutableCollection, source: ResourceLocation) { @@ -98,12 +99,12 @@ abstract class AbstractRegistryAction( } companion object { - private val registryDelegate = RegistryDelegate>("matter_registry_action") { disableSaving(); disableSync() } + private val registryDelegate = RegistryDelegate>("matter_registry_action") { sync(false) } val registryKey get() = registryDelegate.key val registry by registryDelegate - private val registrar = DeferredRegister.create(registryKey, OverdriveThatMatters.MOD_ID) + private val registrar = MDeferredRegister(registryKey, OverdriveThatMatters.MOD_ID) init { registrar.register("insert") { InsertAction.Companion } @@ -113,13 +114,13 @@ abstract class AbstractRegistryAction( registrar.register("blacklist") { BlacklistAction.Companion } } - internal fun register(bus: IEventBus) { + fun register(bus: IEventBus) { registrar.register(bus) bus.addListener(registryDelegate::build) } val CODEC: Codec by lazy { - registry.codec.dispatch({ it.type }, { it.codec }) + registry.byNameCodec().dispatch({ it.type }, { it.codec }) } } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/matter/ComputeAction.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/matter/ComputeAction.kt index 50449c5dd..6932d86af 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/matter/ComputeAction.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/matter/ComputeAction.kt @@ -6,11 +6,12 @@ import com.mojang.datafixers.util.Pair import com.mojang.serialization.Codec import com.mojang.serialization.DataResult import com.mojang.serialization.DynamicOps +import com.mojang.serialization.MapCodec import com.mojang.serialization.codecs.RecordCodecBuilder +import net.minecraft.core.registries.BuiltInRegistries import net.minecraft.resources.ResourceLocation import net.minecraft.tags.TagKey import net.minecraft.world.item.Item -import net.minecraftforge.registries.ForgeRegistries import ru.dbotthepony.mc.otm.core.math.Decimal import ru.dbotthepony.mc.otm.data.DecimalCodec import ru.dbotthepony.mc.otm.data.PredicatedCodecList @@ -28,8 +29,8 @@ class ComputeAction( it.group( DecimalCodec.fieldOf("matter").forGetter(Constant::matter), Codec.DOUBLE.fieldOf("complexity").forGetter(Constant::complexity), - IMatterFunction.registry.codec.fieldOf("matterFunction").forGetter(Constant::matterFunction), - IMatterFunction.registry.codec.fieldOf("complexityFunction").forGetter(Constant::complexityFunction), + IMatterFunction.registry.byNameCodec().fieldOf("matterFunction").forGetter(Constant::matterFunction), + IMatterFunction.registry.byNameCodec().fieldOf("complexityFunction").forGetter(Constant::complexityFunction), ).apply(it, ::Constant) } to Predicate { true } } @@ -39,7 +40,7 @@ class ComputeAction( it.group( DecimalCodec.fieldOf("matter").forGetter(Constant::matter), Codec.DOUBLE.fieldOf("complexity").forGetter(Constant::complexity), - IMatterFunction.registry.codec.fieldOf("function").forGetter(Constant::matterFunction), + IMatterFunction.registry.byNameCodec().fieldOf("function").forGetter(Constant::matterFunction), ).apply(it) { a, b, c -> Constant(a, b, c, c) } } to Predicate { it.matterFunction == it.complexityFunction } } @@ -48,8 +49,8 @@ class ComputeAction( RecordCodecBuilder.create { it.group( DecimalCodec.fieldOf("value").forGetter(Constant::matter), - IMatterFunction.registry.codec.fieldOf("matterFunction").forGetter(Constant::matterFunction), - IMatterFunction.registry.codec.fieldOf("complexityFunction").forGetter(Constant::complexityFunction), + IMatterFunction.registry.byNameCodec().fieldOf("matterFunction").forGetter(Constant::matterFunction), + IMatterFunction.registry.byNameCodec().fieldOf("complexityFunction").forGetter(Constant::complexityFunction), ).apply(it) { a, b, c -> Constant(a, a.toDouble(), b, c) } } to Predicate { it.matter == Decimal(it.complexity.toString()) } } @@ -58,7 +59,7 @@ class ComputeAction( RecordCodecBuilder.create { it.group( DecimalCodec.fieldOf("value").forGetter(Constant::matter), - IMatterFunction.registry.codec.fieldOf("function").forGetter(Constant::matterFunction), + IMatterFunction.registry.byNameCodec().fieldOf("function").forGetter(Constant::matterFunction), ).apply(it) { a, b -> Constant(a, a.toDouble(), b, b) } } to Predicate { it.matter == Decimal(it.complexity.toString()) && it.matterFunction == it.complexityFunction } } @@ -67,7 +68,7 @@ class ComputeAction( RecordCodecBuilder.create { it.group( Codec.DOUBLE.fieldOf("complexity").forGetter(Constant::complexity), - IMatterFunction.registry.codec.fieldOf("function").forGetter(Constant::complexityFunction), + IMatterFunction.registry.byNameCodec().fieldOf("function").forGetter(Constant::complexityFunction), ).apply(it) { a, b -> Constant(Decimal.ZERO, a.toDouble(), IMatterFunction.NOOP, b) } } to Predicate { it.matterFunction == IMatterFunction.NOOP } } @@ -76,7 +77,7 @@ class ComputeAction( RecordCodecBuilder.create { it.group( Codec.DOUBLE.fieldOf("complexity").forGetter(Constant::complexity), - IMatterFunction.registry.codec.fieldOf("complexityFunction").forGetter(Constant::complexityFunction), + IMatterFunction.registry.byNameCodec().fieldOf("complexityFunction").forGetter(Constant::complexityFunction), ).apply(it) { a, b -> Constant(Decimal.ZERO, a.toDouble(), IMatterFunction.NOOP, b) } } to Predicate { it.matterFunction == IMatterFunction.NOOP } } @@ -85,7 +86,7 @@ class ComputeAction( RecordCodecBuilder.create { it.group( DecimalCodec.fieldOf("matter").forGetter(Constant::matter), - IMatterFunction.registry.codec.fieldOf("function").forGetter(Constant::matterFunction), + IMatterFunction.registry.byNameCodec().fieldOf("function").forGetter(Constant::matterFunction), ).apply(it) { a, b -> Constant(a, 0.0, b, IMatterFunction.NOOP) } } to Predicate { it.complexityFunction == IMatterFunction.NOOP } } @@ -94,7 +95,7 @@ class ComputeAction( RecordCodecBuilder.create { it.group( DecimalCodec.fieldOf("matter").forGetter(Constant::matter), - IMatterFunction.registry.codec.fieldOf("matterFunction").forGetter(Constant::matterFunction), + IMatterFunction.registry.byNameCodec().fieldOf("matterFunction").forGetter(Constant::matterFunction), ).apply(it) { a, b -> Constant(a, 0.0, b, IMatterFunction.NOOP) } } to Predicate { it.complexityFunction == IMatterFunction.NOOP } } @@ -181,7 +182,7 @@ class ComputeAction( RecordCodecBuilder.create { it.group( TargetCodec.fieldOf("id").forGetter(Value::id), - IMatterFunction.registry.codec.fieldOf("function").forGetter(Value::matterFunction), + IMatterFunction.registry.byNameCodec().fieldOf("function").forGetter(Value::matterFunction), ).apply(it, ::Value) } } @@ -190,8 +191,8 @@ class ComputeAction( RecordCodecBuilder.create { it.group( TargetCodec.fieldOf("id").forGetter(Value::id), - IMatterFunction.registry.codec.fieldOf("matterFunction").forGetter(Value::matterFunction), - IMatterFunction.registry.codec.fieldOf("complexityFunction").forGetter(Value::complexityFunction), + IMatterFunction.registry.byNameCodec().fieldOf("matterFunction").forGetter(Value::matterFunction), + IMatterFunction.registry.byNameCodec().fieldOf("complexityFunction").forGetter(Value::complexityFunction), ).apply(it, ::Value) } } @@ -221,8 +222,8 @@ class ComputeAction( } } - override val codec: Codec by lazy { - RecordCodecBuilder.create { + override val codec: MapCodec by lazy { + RecordCodecBuilder.mapCodec { it.group( TargetCodec.fieldOf("id").forGetter(ComputeAction::id), Codec.list(Codec @@ -284,7 +285,7 @@ class ComputeAction( override fun provideValues(): MatterManager.Result { return id.map( { - MatterManager.compute(ForgeRegistries.ITEMS.getValue(it) ?: throw NullPointerException("$it does not point to anything")) + MatterManager.compute(BuiltInRegistries.ITEM.get(it)) }, { MatterManager.compute(it) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/matter/DeleteAction.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/matter/DeleteAction.kt index f1b91b715..cd145fc6e 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/matter/DeleteAction.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/matter/DeleteAction.kt @@ -2,6 +2,7 @@ package ru.dbotthepony.mc.otm.matter import com.mojang.datafixers.util.Either import com.mojang.serialization.Codec +import com.mojang.serialization.MapCodec import com.mojang.serialization.codecs.RecordCodecBuilder import net.minecraft.resources.ResourceLocation import net.minecraft.tags.TagKey @@ -28,8 +29,8 @@ open class DeleteAction( get() = Companion companion object : Type { - override val codec: Codec by lazy { - RecordCodecBuilder.create { + override val codec: MapCodec by lazy { + RecordCodecBuilder.mapCodec { it.group( TargetCodec.fieldOf("id").forGetter(DeleteAction::id), Codec.BOOL.optionalFieldOf("errorOnFailure", false).forGetter(DeleteAction::errorOnFailure) @@ -44,8 +45,8 @@ class BlacklistAction(id: Either>) : DeleteAction get() = Companion companion object : Type { - override val codec: Codec by lazy { - RecordCodecBuilder.create { + override val codec: MapCodec by lazy { + RecordCodecBuilder.mapCodec { it.group( TargetCodec.fieldOf("id").forGetter(BlacklistAction::id) ).apply(it, ::BlacklistAction) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/matter/IMatterFunction.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/matter/IMatterFunction.kt index f7bf8df86..4c6e670e9 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/matter/IMatterFunction.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/matter/IMatterFunction.kt @@ -1,11 +1,12 @@ package ru.dbotthepony.mc.otm.matter -import net.minecraftforge.eventbus.api.IEventBus -import net.minecraftforge.registries.DeferredRegister -import ru.dbotthepony.kommons.util.getValue +import net.neoforged.bus.api.IEventBus import ru.dbotthepony.mc.otm.OverdriveThatMatters -import ru.dbotthepony.mc.otm.core.getValue import ru.dbotthepony.mc.otm.core.math.Decimal +import ru.dbotthepony.mc.otm.matter.SimpleMatterFunction.DecimalFunction +import ru.dbotthepony.mc.otm.matter.SimpleMatterFunction.DoubleFunction +import ru.dbotthepony.mc.otm.matter.SimpleMatterFunction.IntFunction +import ru.dbotthepony.mc.otm.registry.MDeferredRegister import ru.dbotthepony.mc.otm.registry.RegistryDelegate interface IMatterFunction { @@ -14,12 +15,12 @@ interface IMatterFunction { fun updateValue(self: Double, other: Double): Double companion object : IMatterFunction { - private val registryDelegate = RegistryDelegate("matter_function") { disableSync(); disableSaving() } + private val registryDelegate = RegistryDelegate("matter_function") { sync(false) } val registryKey get() = registryDelegate.key val registry by registryDelegate - private val registrar = DeferredRegister.create(registryKey, OverdriveThatMatters.MOD_ID) + private val registrar = MDeferredRegister(registryKey, OverdriveThatMatters.MOD_ID) init { registrar.register("noop") { this } @@ -35,7 +36,7 @@ interface IMatterFunction { val AT_MOST: IMatterFunction by registrar.register("at_most") { SimpleMatterFunction(Int::coerceAtMost, Double::coerceAtMost, Decimal::coerceAtMost) } val REPLACE: IMatterFunction by registrar.register("replace") { SimpleMatterFunction({ _, value -> value }, { _, value -> value }, { _, value -> value }) } - internal fun register(bus: IEventBus) { + fun register(bus: IEventBus) { registrar.register(bus) bus.addListener(registryDelegate::build) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/matter/InsertAction.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/matter/InsertAction.kt index b0fccf9c5..87bab4b7e 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/matter/InsertAction.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/matter/InsertAction.kt @@ -2,6 +2,7 @@ package ru.dbotthepony.mc.otm.matter import com.mojang.datafixers.util.Either import com.mojang.serialization.Codec +import com.mojang.serialization.MapCodec import com.mojang.serialization.codecs.RecordCodecBuilder import net.minecraft.resources.ResourceLocation import net.minecraft.tags.TagKey @@ -52,8 +53,8 @@ class InsertAction( get() = Companion companion object : Type { - override val codec: Codec by lazy { - RecordCodecBuilder.create { + override val codec: MapCodec by lazy { + RecordCodecBuilder.mapCodec { it.group( TargetCodec.fieldOf("id").forGetter(InsertAction::id), DecimalCodec.fieldOf("matter").forGetter(InsertAction::matter), diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/matter/MatterDataProvider.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/matter/MatterDataProvider.kt index 6f45e0283..e490e82a1 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/matter/MatterDataProvider.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/matter/MatterDataProvider.kt @@ -8,7 +8,8 @@ import net.minecraft.resources.ResourceLocation import net.minecraft.tags.TagKey import net.minecraft.world.item.Item import net.minecraft.world.level.ItemLike -import net.minecraftforge.data.event.GatherDataEvent +import net.neoforged.neoforge.data.event.GatherDataEvent +import ru.dbotthepony.mc.otm.core.ResourceLocation import ru.dbotthepony.mc.otm.core.math.Decimal import ru.dbotthepony.mc.otm.core.util.WriteOnce import ru.dbotthepony.mc.otm.core.registryName diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/matter/MatterManager.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/matter/MatterManager.kt index 125672996..5e3ae2c6a 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/matter/MatterManager.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/matter/MatterManager.kt @@ -26,43 +26,44 @@ import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet import net.minecraft.ChatFormatting import net.minecraft.commands.CommandSourceStack import net.minecraft.commands.Commands +import net.minecraft.core.registries.BuiltInRegistries import net.minecraft.network.FriendlyByteBuf import net.minecraft.network.chat.Component import net.minecraft.network.chat.MutableComponent +import net.minecraft.network.codec.StreamCodec +import net.minecraft.network.protocol.common.custom.CustomPacketPayload import net.minecraft.resources.ResourceKey import net.minecraft.resources.ResourceLocation import net.minecraft.server.MinecraftServer +import net.minecraft.server.level.ServerPlayer import net.minecraft.server.packs.resources.ResourceManager import net.minecraft.server.packs.resources.SimpleJsonResourceReloadListener import net.minecraft.tags.TagKey import net.minecraft.util.profiling.ProfilerFiller -import net.minecraft.world.Container -import net.minecraft.world.entity.player.Player -import net.minecraft.world.inventory.AbstractContainerMenu -import net.minecraft.world.inventory.TransientCraftingContainer import net.minecraft.world.item.Item import net.minecraft.world.item.ItemStack +import net.minecraft.world.item.crafting.CraftingInput import net.minecraft.world.item.crafting.Ingredient import net.minecraft.world.item.crafting.Recipe +import net.minecraft.world.item.crafting.RecipeInput import net.minecraft.world.item.crafting.RecipeType +import net.minecraft.world.item.crafting.SmithingRecipeInput import net.minecraft.world.item.crafting.SmithingTransformRecipe import net.minecraft.world.level.ItemLike -import net.minecraftforge.common.capabilities.ForgeCapabilities -import net.minecraftforge.common.crafting.IShapedRecipe -import net.minecraftforge.event.AddReloadListenerEvent -import net.minecraftforge.event.OnDatapackSyncEvent -import net.minecraftforge.event.RegisterCommandsEvent -import net.minecraftforge.event.entity.player.ItemTooltipEvent -import net.minecraftforge.event.network.CustomPayloadEvent -import net.minecraftforge.event.server.ServerStartedEvent -import net.minecraftforge.eventbus.api.IEventBus -import net.minecraftforge.fml.ModList -import net.minecraftforge.network.PacketDistributor -import net.minecraftforge.registries.DeferredRegister -import net.minecraftforge.registries.ForgeRegistries -import net.minecraftforge.server.command.EnumArgument +import net.neoforged.bus.api.IEventBus +import net.neoforged.fml.ModList +import net.neoforged.neoforge.capabilities.Capabilities +import net.neoforged.neoforge.common.crafting.IShapedRecipe +import net.neoforged.neoforge.event.AddReloadListenerEvent +import net.neoforged.neoforge.event.OnDatapackSyncEvent +import net.neoforged.neoforge.event.RegisterCommandsEvent +import net.neoforged.neoforge.event.entity.player.ItemTooltipEvent +import net.neoforged.neoforge.event.server.ServerStartedEvent +import net.neoforged.neoforge.network.PacketDistributor +import net.neoforged.neoforge.network.handling.IPayloadContext +import net.neoforged.neoforge.registries.DeferredRegister +import net.neoforged.neoforge.server.command.EnumArgument import org.apache.logging.log4j.LogManager -import ru.dbotthepony.mc.otm.config.ClientConfig import ru.dbotthepony.mc.otm.MINECRAFT_SERVER import ru.dbotthepony.mc.otm.NULLABLE_MINECRAFT_SERVER import ru.dbotthepony.mc.otm.OverdriveThatMatters @@ -72,33 +73,34 @@ import ru.dbotthepony.mc.otm.capability.MatteryCapability import ru.dbotthepony.mc.otm.capability.drive.IMatteryDrive import ru.dbotthepony.mc.otm.client.isShiftDown import ru.dbotthepony.mc.otm.client.minecraft -import ru.dbotthepony.mc.otm.container.set +import ru.dbotthepony.mc.otm.config.ClientConfig +import ru.dbotthepony.mc.otm.container.MatteryCraftingContainer import ru.dbotthepony.mc.otm.container.util.stream -import ru.dbotthepony.mc.otm.core.math.Decimal +import ru.dbotthepony.mc.otm.core.ResourceLocation import ru.dbotthepony.mc.otm.core.TextComponent import ru.dbotthepony.mc.otm.core.TranslatableComponent +import ru.dbotthepony.mc.otm.core.collect.any +import ru.dbotthepony.mc.otm.core.collect.filter import ru.dbotthepony.mc.otm.core.filterNotNull +import ru.dbotthepony.mc.otm.core.getReverseTag +import ru.dbotthepony.mc.otm.core.isNotEmpty +import ru.dbotthepony.mc.otm.core.math.Decimal +import ru.dbotthepony.mc.otm.core.math.isZero +import ru.dbotthepony.mc.otm.core.readItemType +import ru.dbotthepony.mc.otm.core.registryName +import ru.dbotthepony.mc.otm.core.stream import ru.dbotthepony.mc.otm.core.util.formatMatter import ru.dbotthepony.mc.otm.core.util.formatMatterFull import ru.dbotthepony.mc.otm.core.util.formatSiComponent import ru.dbotthepony.mc.otm.core.util.formatTickDuration -import ru.dbotthepony.mc.otm.core.ifPresentK -import ru.dbotthepony.mc.otm.core.isActuallyEmpty -import ru.dbotthepony.mc.otm.core.isNotEmpty -import ru.dbotthepony.mc.otm.core.math.isZero -import ru.dbotthepony.mc.otm.core.orNull -import ru.dbotthepony.mc.otm.core.readItemType -import ru.dbotthepony.mc.otm.core.registryName -import ru.dbotthepony.mc.otm.core.stream import ru.dbotthepony.mc.otm.core.util.readBinaryComponent import ru.dbotthepony.mc.otm.core.util.readCollection import ru.dbotthepony.mc.otm.core.util.writeBinaryComponent import ru.dbotthepony.mc.otm.core.util.writeCollection import ru.dbotthepony.mc.otm.core.writeItemType +import ru.dbotthepony.mc.otm.matter.MatterManager.Finder import ru.dbotthepony.mc.otm.milliTime -import ru.dbotthepony.mc.otm.network.GenericNetworkChannel -import ru.dbotthepony.mc.otm.network.MNetworkContext -import ru.dbotthepony.mc.otm.network.MatteryPacket +import ru.dbotthepony.mc.otm.registry.MDeferredRegister import ru.dbotthepony.mc.otm.registry.RegistryDelegate import ru.dbotthepony.mc.otm.secondTime import ru.dbotthepony.mc.otm.storage.ItemStorageStack @@ -113,12 +115,37 @@ import java.util.function.BooleanSupplier import java.util.stream.Stream import java.util.zip.Deflater import java.util.zip.Inflater -import kotlin.ConcurrentModificationException import kotlin.collections.ArrayDeque import kotlin.collections.ArrayList +import kotlin.collections.Collection import kotlin.collections.HashMap import kotlin.collections.LinkedHashMap -import kotlin.jvm.optionals.getOrNull +import kotlin.collections.List +import kotlin.collections.Map +import kotlin.collections.MutableMap +import kotlin.collections.all +import kotlin.collections.component1 +import kotlin.collections.component2 +import kotlin.collections.contains +import kotlin.collections.copyOfRange +import kotlin.collections.count +import kotlin.collections.filter +import kotlin.collections.firstOrNull +import kotlin.collections.forEach +import kotlin.collections.indices +import kotlin.collections.isNotEmpty +import kotlin.collections.isNullOrEmpty +import kotlin.collections.iterator +import kotlin.collections.joinToString +import kotlin.collections.last +import kotlin.collections.listOf +import kotlin.collections.map +import kotlin.collections.mapOf +import kotlin.collections.set +import kotlin.collections.sortBy +import kotlin.collections.sortWith +import kotlin.collections.toTypedArray +import kotlin.collections.withIndex import kotlin.math.pow import kotlin.math.roundToInt @@ -159,18 +186,12 @@ object MatterManager { return keyEntry } - val reverse = ForgeRegistries.ITEMS.tags()!!.getReverseTag(value).orElse(null) - - if (reverse != null) { - return reverse.tagKeys - .map { tagEntries[it] } - .filterNotNull() - .sorted { o1, o2 -> o1.priority.compareTo(o2.priority) } - .findFirst() - .orElse(null) ?: IMatterValue.Companion - } - - return IRegistryEntry.Companion + return BuiltInRegistries.ITEM.getReverseTag(value) + .map { tagEntries[it] } + .filterNotNull() + .sorted { o1, o2 -> o1.priority.compareTo(o2.priority) } + .findFirst() + .orElse(null) ?: IMatterValue.Companion } /** @@ -185,16 +206,12 @@ object MatterManager { var compute = computeKeys[value.registryName!!] if (compute == null) { - val reverse = ForgeRegistries.ITEMS.tags()!!.getReverseTag(value).orElse(null) - - if (reverse != null) { - compute = reverse.tagKeys - .map { computeTags[it] } - .filterNotNull() - .sorted() - .findFirst() - .orElse(null) - } + compute = BuiltInRegistries.ITEM.getReverseTag(value) + .map { computeTags[it] } + .filterNotNull() + .sorted() + .findFirst() + .orElse(null) } if (compute != null) { @@ -214,25 +231,15 @@ object MatterManager { if (key in keyEntriesBlacklist) return@fn true - val reverse = ForgeRegistries.ITEMS.tags()!!.getReverseTag(value).orElse(null) - - if (reverse != null) { - return@fn reverse.tagKeys.anyMatch { it in tagEntriesBlacklist } - } - - return@fn false + return@fn BuiltInRegistries.ITEM.getReverseTag(value).anyMatch { it in tagEntriesBlacklist } }) } fun isBlacklisted(value: TagKey): Boolean { return blacklistCacheTag.computeIfAbsent(value, Object2BooleanFunction fn@{ - return@fn value in tagEntriesBlacklist || ForgeRegistries.ITEMS.tags()!!.getTag(value).let { - if (it.isEmpty || !it.isBound) { - false - } else { - it.stream().anyMatch { item -> !isBlacklisted(item) } - } - } + return@fn value in tagEntriesBlacklist || BuiltInRegistries.ITEM.getTag(value).map { + it.stream().anyMatch { item -> !isBlacklisted(item.value()) } + }.orElse(false) }) } @@ -297,7 +304,7 @@ object MatterManager { val result = AbstractRegistryAction.CODEC .decode(JsonOps.INSTANCE, json) - .getOrThrow(false) { throw JsonSyntaxException("Failed to deserialize matter registry entry $key: $it") } + .getOrThrow { throw JsonSyntaxException("Failed to deserialize matter registry entry $key: $it") } .first when (result) { @@ -419,33 +426,30 @@ object MatterManager { } private object Resolver : SimpleJsonResourceReloadListener(GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create(), FINDER_DIRECTORY) { - val delegate = RegistryDelegate("recipe_finder") { - disableSync() - disableSaving() - } + val delegate = RegistryDelegate("recipe_finder") { sync(false) } var ready = false private set - val registrar: DeferredRegister = DeferredRegister.create(delegate.key, OverdriveThatMatters.MOD_ID) + val registrar = MDeferredRegister(delegate.key, OverdriveThatMatters.MOD_ID) init { registrar.register("simple") { Finder { server, data -> val location = (data["recipe_type"] ?: throw JsonSyntaxException("Missing recipe type")).let { ResourceLocation.tryParse(it.asString) } ?: throw JsonSyntaxException("Invalid recipe type: ${data["recipe_type"]}") - if (!ForgeRegistries.RECIPE_TYPES.containsKey(location)) { + if (!BuiltInRegistries.RECIPE_TYPE.containsKey(location)) { LOGGER.error("Invalid or missing recipe category: $location!") return@Finder Stream.empty() } - val findRecipeType = ForgeRegistries.RECIPE_TYPES.getValue(location) as RecipeType>? ?: throw ConcurrentModificationException() + val findRecipeType = BuiltInRegistries.RECIPE_TYPE.get(location) as RecipeType>? ?: throw ConcurrentModificationException() val isCritical = data["is_critical"]?.asBoolean ?: true val ignoreDamageables = data["ignore_damageables"]?.asBoolean ?: false val allowBacktrack = data["allow_backtrack"]?.asBoolean ?: true - var stream = server.recipeManager.byType(findRecipeType).values.stream().filter { !it.value.isIncomplete } + var stream = server.recipeManager.byType(findRecipeType).stream().filter { !it.value.isIncomplete } if (ignoreDamageables) { stream = stream.filter { it.value.ingredients.stream().flatMap { it.items.stream() }.noneMatch { it.isDamageableItem } } @@ -455,7 +459,7 @@ object MatterManager { try { ResolvedRecipe( it.value.ingredients.stream() - .filter { !it.isActuallyEmpty } + .filter { !it.hasNoItems() } .map { it.items.stream().filter { it.isNotEmpty }.map(::RecipeEntry) }, ImmutableStack(it.value.getResultItem(server.registryAccess())), isCritical = isCritical, @@ -481,17 +485,17 @@ object MatterManager { Finder { server, data -> val location = (data["recipe_type"] ?: throw JsonSyntaxException("Missing recipe type")).let { ResourceLocation.tryParse(it.asString) } ?: throw JsonSyntaxException("Invalid recipe type: ${data["recipe_type"]}") - if (!ForgeRegistries.RECIPE_TYPES.containsKey(location)) { + if (!BuiltInRegistries.RECIPE_TYPE.containsKey(location)) { LOGGER.error("Invalid or missing recipe category: $location!") return@Finder Stream.empty() } - val findRecipeType = ForgeRegistries.RECIPE_TYPES.getValue(location) as RecipeType>? ?: throw ConcurrentModificationException() + val findRecipeType = BuiltInRegistries.RECIPE_TYPE.get(location) as RecipeType>? ?: throw ConcurrentModificationException() val allowBacktrack = data["allow_backtrack"]?.asBoolean ?: true val ignoreDamageables = data["ignore_damageables"]?.asBoolean ?: false val isCritical = data["is_critical"]?.asBoolean ?: true - var stream = server.recipeManager.byType(findRecipeType).values.stream().filter { !it.value.isIncomplete } + var stream = server.recipeManager.byType(findRecipeType).stream().filter { !it.value.isIncomplete } if (ignoreDamageables) { stream = stream.filter { it.value.ingredients.stream().flatMap { it.items.stream() }.noneMatch { it.isDamageableItem } } @@ -508,9 +512,10 @@ object MatterManager { var width: Int var height: Int + // FIXME: this gonna break after neoforge update if (it.value is IShapedRecipe<*>) { - width = (it.value as IShapedRecipe<*>).recipeWidth - height = (it.value as IShapedRecipe<*>).recipeHeight + width = (it.value as IShapedRecipe<*>).width + height = (it.value as IShapedRecipe<*>).height } else { width = 3 height = 3 @@ -521,26 +526,17 @@ object MatterManager { height = it.value.ingredients.size.coerceAtLeast(height) } - val container = TransientCraftingContainer(object : AbstractContainerMenu(null, 0) { - override fun quickMoveStack(pPlayer: Player, pIndex: Int): ItemStack { - return ItemStack.EMPTY - } - - override fun stillValid(pPlayer: Player): Boolean { - return false - } - }, width, height) - + val container = MatteryCraftingContainer(width, height) val realIngredients = ArrayList>() for (c in it.value.ingredients.indices) { - if (it.value.ingredients[c].isActuallyEmpty) { + if (it.value.ingredients[c].hasNoItems()) { continue } for ((i, ingredient) in it.value.ingredients.withIndex()) { if (i != c) { - container[i] = if (ingredient.isActuallyEmpty) ItemStack.EMPTY else ingredient.items.firstOrNull() ?: ItemStack.EMPTY + container[i] = if (ingredient.hasNoItems()) ItemStack.EMPTY else ingredient.items.firstOrNull() ?: ItemStack.EMPTY } } @@ -548,9 +544,13 @@ object MatterManager { for (item in it.value.ingredients[c].items) { container[c] = item + // this gonna create enormous GC pressure but who cares lmao + // if you are playing post 1.12.2 you own supercomputer anyway + // deadass. + val input = CraftingInput.of(width, height, container.toList()) - if (!it.value.assemble(container, server.registryAccess()).isEmpty) { - val residue = it.value.getRemainingItems(container) + if (!it.value.assemble(input, server.registryAccess()).isEmpty) { + val residue = it.value.getRemainingItems(input) val thisResidue = residue[c] @@ -593,17 +593,17 @@ object MatterManager { Finder { server, data -> val location = (data["recipe_type"] ?: throw JsonSyntaxException("Missing recipe type")).let { ResourceLocation.tryParse(it.asString) } ?: throw JsonSyntaxException("Invalid recipe type: ${data["recipe_type"]}") - if (!ForgeRegistries.RECIPE_TYPES.containsKey(location)) { + if (!BuiltInRegistries.RECIPE_TYPE.containsKey(location)) { LOGGER.error("Invalid or missing recipe category: $location!") return@Finder Stream.empty() } - val findRecipeType = ForgeRegistries.RECIPE_TYPES.getValue(location) as RecipeType>? ?: throw ConcurrentModificationException() + val findRecipeType = BuiltInRegistries.RECIPE_TYPE.get(location) as RecipeType>? ?: throw ConcurrentModificationException() val isCritical = data["is_critical"]?.asBoolean ?: true val allowBacktrack = data["allow_backtrack"]?.asBoolean ?: true - var stream = server.recipeManager.byType(findRecipeType).values.stream().filter { !it.value.isIncomplete } + var stream = server.recipeManager.byType(findRecipeType).stream().filter { !it.value.isIncomplete } stream = stream.filter { it.value is SmithingTransformRecipe } stream.filter { it.value.getResultItem(server.registryAccess()).isNotEmpty }.map { @@ -617,7 +617,7 @@ object MatterManager { ResolvedRecipe( ingredients.stream() - .filter { !it.isActuallyEmpty } + .filter { !it.hasNoItems() } .map { it.items.stream().filter { it.isNotEmpty }.map(::RecipeEntry) }, ImmutableStack(it.value.getResultItem(server.registryAccess())), isCritical = isCritical, @@ -667,7 +667,7 @@ object MatterManager { throw JsonParseException("Resolver type $location does not exist (in $key)") } - val resolver = recipeFinders.getValue(location) ?: throw ConcurrentModificationException() + val resolver = recipeFinders.get(location) ?: throw ConcurrentModificationException() builder.put(key, resolver to json) } @@ -936,7 +936,6 @@ object MatterManager { * Если у 60% <= предметов со значением материи есть тег, и он есть у всех * предметов без значения материи, то предметы без материи игнорируются */ - val manager = ForgeRegistries.ITEMS.tags()!! val tagSetsPresent = Object2IntArrayMap>() val tagSetsMissing = Object2IntArrayMap>() @@ -945,7 +944,7 @@ object MatterManager { continue } - val list = manager.getReverseTag(input.input.item).getOrNull()?.tagKeys?.collect(ImmutableList.toImmutableList()) ?: ImmutableList.of() + val list = BuiltInRegistries.ITEM.getReverseTag(input.input.item).toList() if (input !in skips) { for (tag in list) @@ -1268,14 +1267,14 @@ object MatterManager { undamagedMatterValue = matter } - val matterCap = value.getCapability(MatteryCapability.MATTER).orNull() + val matterCap = value.getCapability(MatteryCapability.MATTER_ITEM) if (matterCap != null) { matter = MatterValue(matter.matter + matterCap.storedMatter, matter.complexity.coerceAtLeast(1.0)) undamagedMatterValue = MatterValue(undamagedMatterValue.matter + matterCap.storedMatter, undamagedMatterValue.complexity) } - val drive = value.getCapability(MatteryCapability.DRIVE).orNull() + val drive = value.getCapability(MatteryCapability.CONDENSATION_DRIVE) if (drive != null && drive.storageType == StorageStack.ITEMS) { (drive as IMatteryDrive).stacks @@ -1289,7 +1288,7 @@ object MatterManager { } } - value.getCapability(ForgeCapabilities.ITEM_HANDLER).ifPresentK { + value.getCapability(Capabilities.ItemHandler.ITEM)?.let { it.stream().filter { !it.isEmpty }.map { get(it, level + 1, true) }.reduce(::reduce).ifPresent { matter += it undamagedMatterValue += it @@ -1332,8 +1331,8 @@ object MatterManager { if (value.item is IMatterItem) can = (value.item as IMatterItem).canDecompose(value) - can = can && (value.getCapability(MatteryCapability.MATTER).orNull()?.storedMatter ?: Decimal.ZERO).isZero - can = can && (value.getCapability(MatteryCapability.DRIVE).orNull()?.storedCount ?: BigInteger.ZERO).isZero + can = can && (value.getCapability(MatteryCapability.MATTER_ITEM)?.storedMatter ?: Decimal.ZERO).isZero + can = can && (value.getCapability(MatteryCapability.CONDENSATION_DRIVE)?.storedCount ?: BigInteger.ZERO).isZero return can && get(value).hasMatterValue } @@ -1589,8 +1588,8 @@ object MatterManager { } private fun dumpRegistry(stack: CommandContext, filter: DumpFilter = DumpFilter.ALL, mod: String? = null): Int { - val targetFile = File(MINECRAFT_SERVER.serverDirectory, "otm/registry_dumps/${filter.name.lowercase()}_${System.currentTimeMillis() / 1_000L}.csv") - File(MINECRAFT_SERVER.serverDirectory, "otm/registry_dumps").mkdirs() + val targetFile = MINECRAFT_SERVER.serverDirectory.resolve("otm/registry_dumps/${filter.name.lowercase()}_${System.currentTimeMillis() / 1_000L}.csv").toFile() + MINECRAFT_SERVER.serverDirectory.resolve("otm/registry_dumps").toFile().mkdirs() stack.source.sendSuccess({ TranslatableComponent("otm.dumping_matter_registry", targetFile.absolutePath) }, false) @@ -1599,7 +1598,7 @@ object MatterManager { writer.write(arrayOf("Registry ID", "Matter Value", "Complexity", "Commentary").joinToString(";", transform = ::transformQuotes)) writer.write("\n") - var stream = ForgeRegistries.ITEMS.entries.stream() + var stream = BuiltInRegistries.ITEM.entrySet().stream() if (mod != null) { stream = stream.filter { it.key.location().namespace == mod } @@ -1668,11 +1667,11 @@ object MatterManager { .executes { dumpRegistry(it, it.getArgument("mode", DumpFilter::class.java), StringArgumentType.getString(it, "mod")) } .suggests { context, builder -> val startingWith = builder.input.substring(builder.start).lowercase() - ModList.get().mods.stream() + ModList.get().mods.iterator() .filter { it.modId.startsWith(startingWith) } - .filter { key -> ForgeRegistries.ITEMS.entries.stream() - .filter { it.key.location() == key } - .anyMatch { !Registry.isBlacklisted(it.value) } } + .filter { key -> BuiltInRegistries.ITEM.entrySet().iterator() + .filter { it.key.location().namespace == key.namespace } + .any { !Registry.isBlacklisted(it.value) } } .forEach { builder.suggest(it.modId, TextComponent(it.displayName)) } builder.buildFuture() }) @@ -1700,14 +1699,14 @@ object MatterManager { Resolver.resolve(server) - for (item in ForgeRegistries.ITEMS) { + for (item in BuiltInRegistries.ITEM) { val value = compute(item).value if (value?.hasMatterValue == true) matterValues[item] = value } - syncRegistry(PacketDistributor.ALL.noArg()) + syncRegistry(PacketDistributor::sendToAllPlayers) } fun onDataPackSync(event: OnDatapackSyncEvent) { @@ -1715,9 +1714,9 @@ object MatterManager { return if (event.player == null) { - syncRegistry(PacketDistributor.ALL.noArg()) + syncRegistry(PacketDistributor::sendToAllPlayers) } else { - syncRegistry(PacketDistributor.PLAYER.with(event.player!!)) + syncRegistry { PacketDistributor.sendToPlayer(event.player as ServerPlayer, it) } } } @@ -1733,7 +1732,7 @@ object MatterManager { private val receivedPackets = ArrayList() - private fun syncRegistry(distributor: PacketDistributor.PacketTarget) { + private fun syncRegistry(distributor: (CustomPacketPayload) -> Unit) { val time = SystemTime() val stream = FastByteArrayOutputStream() val data = DataOutputStream(stream) @@ -1794,7 +1793,7 @@ object MatterManager { LOGGER.debug("Encoding matter registry packet took ${time.millis}ms, (${stream.length} bytes total, $totalSize bytes compressed)") for (chunk in chunks) { - GenericNetworkChannel.send(distributor, chunk) + distributor.invoke(chunk) } } @@ -1897,13 +1896,20 @@ object MatterManager { private const val LAST = 2 private const val FIRST_AND_LAST = 3 - class SyncPacket(val payload: ByteArray, val length: Int, var mode: Int) : MatteryPacket { - override fun write(buff: FriendlyByteBuf) { + val SYNC_TYPE = CustomPacketPayload.Type(ResourceLocation(OverdriveThatMatters.MOD_ID, "matter_sync")) + val SYNC_CODEC: StreamCodec = StreamCodec.ofMember(SyncPacket::write, ::readSyncPacket) + + class SyncPacket(val payload: ByteArray, val length: Int, var mode: Int) : CustomPacketPayload { + fun write(buff: FriendlyByteBuf) { buff.writeByte(mode) buff.writeBytes(payload, 0, length) } - override fun play(context: MNetworkContext) { + override fun type(): CustomPacketPayload.Type { + return SYNC_TYPE + } + + fun play(context: IPayloadContext) { if (SERVER_IS_LIVE) return // singleplayer or LAN host diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/matter/RegistryEntries.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/matter/RegistryEntries.kt index ddab4fed1..fcc57f483 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/matter/RegistryEntries.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/matter/RegistryEntries.kt @@ -4,6 +4,7 @@ import com.mojang.datafixers.util.Either import net.minecraft.resources.ResourceLocation import net.minecraft.tags.TagKey import net.minecraft.world.item.Item +import ru.dbotthepony.mc.otm.core.ResourceLocation import ru.dbotthepony.mc.otm.core.math.Decimal interface IRegistryEntry : IMatterValue { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/matter/UpdateAction.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/matter/UpdateAction.kt index 6f6748ecf..12fc4eab1 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/matter/UpdateAction.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/matter/UpdateAction.kt @@ -3,6 +3,7 @@ package ru.dbotthepony.mc.otm.matter import com.google.common.collect.ImmutableList import com.mojang.datafixers.util.Either import com.mojang.serialization.Codec +import com.mojang.serialization.MapCodec import com.mojang.serialization.codecs.RecordCodecBuilder import net.minecraft.resources.ResourceLocation import net.minecraft.tags.TagKey @@ -21,7 +22,7 @@ class UpdateAction( data class MatterFunction(val function: IMatterFunction, val value: Decimal) { companion object { val CODEC: Codec by lazy { - simpleCodec(::MatterFunction, MatterFunction::function, IMatterFunction.registry.codec, MatterFunction::value, DecimalCodec) + simpleCodec(::MatterFunction, MatterFunction::function, IMatterFunction.registry.byNameCodec(), MatterFunction::value, DecimalCodec) } } } @@ -29,7 +30,7 @@ class UpdateAction( data class ComplexityFunction(val function: IMatterFunction, val value: Double) { companion object { val CODEC: Codec by lazy { - simpleCodec(::ComplexityFunction, ComplexityFunction::function, IMatterFunction.registry.codec, ComplexityFunction::value, Codec.DOUBLE) + simpleCodec(::ComplexityFunction, ComplexityFunction::function, IMatterFunction.registry.byNameCodec(), ComplexityFunction::value, Codec.DOUBLE) } } } @@ -37,14 +38,14 @@ class UpdateAction( data class PriorityFunction(val function: IMatterFunction, val value: Int) { companion object { val CODEC: Codec by lazy { - simpleCodec(::PriorityFunction, PriorityFunction::function, IMatterFunction.registry.codec, PriorityFunction::value, Codec.INT) + simpleCodec(::PriorityFunction, PriorityFunction::function, IMatterFunction.registry.byNameCodec(), PriorityFunction::value, Codec.INT) } } } companion object : Type { - override val codec: Codec by lazy { - RecordCodecBuilder.create { + override val codec: MapCodec by lazy { + RecordCodecBuilder.mapCodec { it.group( TargetCodec.fieldOf("id").forGetter(UpdateAction::id), Codec.list(MatterFunction.CODEC).fieldOf("matterFunctions").forGetter(UpdateAction::matterFunctions), diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/ExopackInventoryMenu.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/ExopackInventoryMenu.kt index d93732cb3..e6a145df1 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/ExopackInventoryMenu.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/ExopackInventoryMenu.kt @@ -9,7 +9,8 @@ import net.minecraft.world.entity.ExperienceOrb import net.minecraft.world.entity.player.Player import net.minecraft.world.inventory.* import net.minecraft.world.item.ItemStack -import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability +import net.neoforged.neoforge.network.PacketDistributor +import ru.dbotthepony.mc.otm.capability.MatteryPlayer import ru.dbotthepony.mc.otm.compat.curios.curiosSlots import ru.dbotthepony.mc.otm.container.util.slotIterator import ru.dbotthepony.mc.otm.menu.input.InstantBooleanInput @@ -17,9 +18,8 @@ import ru.dbotthepony.mc.otm.menu.widget.ProgressGaugeWidget import ru.dbotthepony.mc.otm.network.ExopackCarriedPacket import ru.dbotthepony.mc.otm.network.ExopackMenuInitPacket import ru.dbotthepony.mc.otm.network.ExopackSlotPacket -import ru.dbotthepony.mc.otm.network.MatteryPlayerNetworkChannel -class ExopackInventoryMenu(val capability: MatteryPlayerCapability) : MatteryMenu(null, CONTAINER_ID, capability.ply.inventory) { +class ExopackInventoryMenu(val capability: MatteryPlayer) : MatteryMenu(null, CONTAINER_ID, capability.ply.inventory) { val craftingGrid: CraftingContainer val craftingSlots: List @@ -241,16 +241,16 @@ class ExopackInventoryMenu(val capability: MatteryPlayerCapability) : MatteryMen } fun sendInitialData(container: ExopackInventoryMenu, itemStacks: NonNullList, carried: ItemStack, remoteDataSlots: IntArray) { - MatteryPlayerNetworkChannel.send(container.player as ServerPlayer, ExopackMenuInitPacket(itemStacks, carried, container.incrementStateId())) + PacketDistributor.sendToPlayer(container.player as ServerPlayer, ExopackMenuInitPacket(itemStacks, carried, container.incrementStateId())) } fun sendSlotChange(container: ExopackInventoryMenu, slotId: Int, itemStack: ItemStack) { if (container.slots[slotId].container != container.player.inventory || container.player.containerMenu is ExopackInventoryMenu) - MatteryPlayerNetworkChannel.send(container.player as ServerPlayer, ExopackSlotPacket(slotId, itemStack, container.stateId)) + PacketDistributor.sendToPlayer(container.player as ServerPlayer, ExopackSlotPacket(slotId, itemStack, container.stateId)) } fun sendCarriedChange(container: ExopackInventoryMenu, itemStack: ItemStack) { - MatteryPlayerNetworkChannel.send(container.player as ServerPlayer, ExopackCarriedPacket(itemStack, container.stateId)) + PacketDistributor.sendToPlayer(container.player as ServerPlayer, ExopackCarriedPacket(itemStack, container.stateId)) } fun sendDataChange(container: ExopackInventoryMenu, dataSlotId: Int, shortData: Int) { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/ISortingSettings.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/ISortingSettings.kt index 04d414327..aae04954d 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/ISortingSettings.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/ISortingSettings.kt @@ -1,9 +1,10 @@ package ru.dbotthepony.mc.otm.menu +import net.minecraft.core.HolderLookup import net.minecraft.nbt.CompoundTag import net.minecraft.world.item.Item import net.minecraft.world.item.ItemStack -import net.minecraftforge.common.util.INBTSerializable +import net.neoforged.neoforge.common.util.INBTSerializable import ru.dbotthepony.kommons.util.getValue import ru.dbotthepony.kommons.util.setValue import ru.dbotthepony.mc.otm.core.nbt.getBoolean @@ -17,13 +18,13 @@ import ru.dbotthepony.mc.otm.menu.input.EnumInputWithFeedback interface IBaseSortingSettings : INBTSerializable { var isAscending: Boolean - override fun serializeNBT(): CompoundTag { + override fun serializeNBT(registry: HolderLookup.Provider): CompoundTag { return CompoundTag().also { it["isAscending"] = isAscending } } - override fun deserializeNBT(nbt: CompoundTag?) { + override fun deserializeNBT(registry: HolderLookup.Provider, nbt: CompoundTag?) { nbt ?: return isAscending = nbt.getBoolean("isAscending", true) } @@ -37,15 +38,15 @@ interface IItemStackSortingSettings : IBaseSortingSettings { var sorting: ItemStackSorter - override fun serializeNBT(): CompoundTag { - return super.serializeNBT().also { + override fun serializeNBT(registry: HolderLookup.Provider): CompoundTag { + return super.serializeNBT(registry).also { it["sorting"] = sorting.name } } - override fun deserializeNBT(nbt: CompoundTag?) { + override fun deserializeNBT(registry: HolderLookup.Provider, nbt: CompoundTag?) { nbt ?: return - super.deserializeNBT(nbt) + super.deserializeNBT(registry, nbt) sorting = nbt.mapString("sorting", ItemStackSorter::valueOf, ItemStackSorter.DEFAULT) } @@ -85,15 +86,15 @@ interface IItemSortingSettings : IBaseSortingSettings { var sorting: ItemSorter - override fun serializeNBT(): CompoundTag { - return super.serializeNBT().also { + override fun serializeNBT(registry: HolderLookup.Provider): CompoundTag { + return super.serializeNBT(registry).also { it["sorting"] = sorting.name } } - override fun deserializeNBT(nbt: CompoundTag?) { + override fun deserializeNBT(registry: HolderLookup.Provider, nbt: CompoundTag?) { nbt ?: return - super.deserializeNBT(nbt) + super.deserializeNBT(registry, nbt) sorting = nbt.mapString("sorting", ItemSorter::valueOf, ItemSorter.DEFAULT) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/MatteryMenu.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/MatteryMenu.kt index 1d0727448..f19b76614 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/MatteryMenu.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/MatteryMenu.kt @@ -10,6 +10,7 @@ import it.unimi.dsi.fastutil.objects.Reference2ObjectFunction import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap import it.unimi.dsi.fastutil.objects.ReferenceArrayList import net.minecraft.network.FriendlyByteBuf +import net.minecraft.network.protocol.common.custom.CustomPacketPayload import net.minecraft.resources.ResourceLocation import net.minecraft.server.level.ServerPlayer import net.minecraft.world.Container @@ -22,8 +23,9 @@ import net.minecraft.world.inventory.MenuType import net.minecraft.world.inventory.Slot import net.minecraft.world.item.Item import net.minecraft.world.item.ItemStack -import net.minecraft.world.item.enchantment.EnchantmentHelper.hasBindingCurse import net.minecraft.world.level.block.entity.BlockEntity +import net.neoforged.neoforge.network.PacketDistributor +import net.neoforged.neoforge.network.handling.IPayloadContext import ru.dbotthepony.kommons.io.BinaryStringCodec import ru.dbotthepony.kommons.io.BooleanValueCodec import ru.dbotthepony.kommons.io.DelegateSyncher @@ -35,6 +37,7 @@ import ru.dbotthepony.kommons.io.nullable import ru.dbotthepony.kommons.util.Delegate import ru.dbotthepony.kommons.util.getValue import ru.dbotthepony.kommons.util.setValue +import ru.dbotthepony.mc.otm.OverdriveThatMatters import ru.dbotthepony.mc.otm.capability.IMatteryUpgrade import ru.dbotthepony.mc.otm.capability.MatteryCapability import ru.dbotthepony.mc.otm.capability.UpgradeType @@ -49,6 +52,7 @@ import ru.dbotthepony.mc.otm.container.ItemFilter import ru.dbotthepony.mc.otm.container.UpgradeContainer import ru.dbotthepony.mc.otm.container.computeSortedIndices import ru.dbotthepony.mc.otm.container.sortWithIndices +import ru.dbotthepony.mc.otm.core.ResourceLocation import ru.dbotthepony.mc.otm.core.collect.ConditionalEnumSet import ru.dbotthepony.mc.otm.core.collect.ConditionalSet import ru.dbotthepony.mc.otm.core.immutableList @@ -61,10 +65,7 @@ import ru.dbotthepony.mc.otm.core.util.computedDecimal import ru.dbotthepony.mc.otm.core.util.computedItem import ru.dbotthepony.mc.otm.menu.input.InstantBooleanInput import ru.dbotthepony.mc.otm.menu.widget.ProfiledLevelGaugeWidget -import ru.dbotthepony.mc.otm.network.MNetworkContext -import ru.dbotthepony.mc.otm.network.MatteryPacket -import ru.dbotthepony.mc.otm.network.MenuFieldPacket -import ru.dbotthepony.mc.otm.network.MenuNetworkChannel +import ru.dbotthepony.mc.otm.network.MenuDataPacket import ru.dbotthepony.mc.otm.network.SetCarriedPacket import java.io.DataInputStream import java.io.DataOutputStream @@ -114,22 +115,38 @@ abstract class MatteryMenu( private val playerInputs = ArrayList>() - class PlayerInputPacket(val containerId: Int, val inputId: Int, val payload: ByteArray) : MatteryPacket { + class PlayerInputPacket(val containerId: Int, val inputId: Int, val payload: ByteArray) : CustomPacketPayload { constructor(buff: FriendlyByteBuf) : this(buff.readVarInt(), buff.readVarInt(), ByteArray(buff.readableBytes()).also { buff.readBytes(it) }) - override fun write(buff: FriendlyByteBuf) { + fun write(buff: FriendlyByteBuf) { buff.writeVarInt(containerId) buff.writeVarInt(inputId) buff.writeBytes(payload) } - override fun play(context: MNetworkContext) { - val menu = context.sender?.containerMenu as? MatteryMenu ?: return - if (menu.containerId != containerId || !menu.stillValid(context.sender)) return + fun play(context: IPayloadContext) { + val menu = context.player().containerMenu as? MatteryMenu ?: return + if (menu.containerId != containerId || !menu.stillValid(context.player())) return val input = menu.playerInputs.getOrNull(inputId) ?: return - if (!input.test(context.sender)) return + if (!input.test(context.player())) return input.invoke(input.codec.read(DataInputStream(FastByteArrayInputStream(payload)))) } + + override fun type(): CustomPacketPayload.Type { + return TYPE + } + + companion object { + val TYPE = CustomPacketPayload.Type( + ResourceLocation( + OverdriveThatMatters.MOD_ID, + "menu_input" + ) + ) + + val CODEC: net.minecraft.network.codec.StreamCodec = + net.minecraft.network.codec.StreamCodec.ofMember(PlayerInputPacket::write, ::PlayerInputPacket) + } } /** @@ -163,7 +180,7 @@ abstract class MatteryMenu( if (test(minecraft.player as Player?)) { val stream = FastByteArrayOutputStream() codec.write(DataOutputStream(stream), value) - MenuNetworkChannel.sendToServer(PlayerInputPacket(containerId, id, stream.array.copyOfRange(0, stream.length))) + PacketDistributor.sendToServer(PlayerInputPacket(containerId, id, stream.array.copyOfRange(0, stream.length))) } } @@ -283,7 +300,7 @@ abstract class MatteryMenu( private set init { - val mattery = player.matteryPlayer!! + val mattery = player.matteryPlayer if (addFilter) { val mContainer = container as IMatteryContainer @@ -328,7 +345,7 @@ abstract class MatteryMenu( protected fun addInventorySlots(autoFrame: Boolean = !player.isSpectator) { check(_playerInventorySlots.isEmpty()) { "Already created inventory slots" } - val mattery = player.matteryPlayer ?: return + val mattery = player.matteryPlayer autoCreateInventoryFrame = autoFrame @@ -381,14 +398,14 @@ abstract class MatteryMenu( } - protected fun matteryBroadcast() { + private fun matteryBroadcast() { beforeBroadcast() mSynchronizer.observe() val payload = synchronizerRemote.write() if (payload != null) { - MenuNetworkChannel.send(player, MenuFieldPacket(containerId, payload)) + PacketDistributor.sendToPlayer(player as ServerPlayer, MenuDataPacket(containerId, payload)) } broadcastOnce = true @@ -419,7 +436,7 @@ abstract class MatteryMenu( fun syncCarried() { setRemoteCarried(carried.copy()) - MenuNetworkChannel.send(player as ServerPlayer, SetCarriedPacket(carried)) + PacketDistributor.sendToPlayer(player as ServerPlayer, SetCarriedPacket(carried)) } fun syncCarried(stack: ItemStack) { @@ -633,7 +650,7 @@ abstract class MatteryMenu( val limit = slot.getMaxStackSize(copy) - if (limit > slot.item.count && slot.mayPlace(item) && ItemStack.isSameItemSameTags(slot.item, copy)) { + if (limit > slot.item.count && slot.mayPlace(item) && ItemStack.isSameItemSameComponents(slot.item, copy)) { val newCount = (slot.item.count + copy.count).coerceAtMost(limit) val diff = newCount - slot.item.count copy.count -= diff @@ -803,7 +820,7 @@ abstract class MatteryMenu( } override fun mayPlace(itemStack: ItemStack): Boolean { - return super.mayPlace(itemStack) && itemStack.getCapability(MatteryCapability.UPGRADE).map { it.upgradeTypes.any { allowedTypes[it]!!.asBoolean } }.orElse(false) + return super.mayPlace(itemStack) && (itemStack.getCapability(MatteryCapability.UPGRADE)?.let { it.upgradeTypes.any { allowedTypes[it]!!.asBoolean } } == true) } } }.also { for (i in it.indices.reversed()) addStorageSlot(it[i], prepend = true, condition = isOpen) }, diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/Slots.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/Slots.kt index c7995158a..89c463723 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/Slots.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/Slots.kt @@ -7,7 +7,7 @@ import net.minecraft.world.entity.player.Player import net.minecraft.world.inventory.Slot import net.minecraft.world.item.Item import net.minecraft.world.item.ItemStack -import net.minecraftforge.common.capabilities.ForgeCapabilities +import net.neoforged.neoforge.capabilities.Capabilities import ru.dbotthepony.kommons.util.Delegate import ru.dbotthepony.mc.otm.capability.FlowDirection import ru.dbotthepony.mc.otm.capability.MatteryCapability @@ -131,7 +131,7 @@ open class ChargeSlot(container: Container, index: Int, x: Int = 0, y: Int = 0) open class EnergyContainerInputSlot(container: Container, index: Int, x: Int = 0, y: Int = 0, val direction: FlowDirection = FlowDirection.BI_DIRECTIONAL) : MatterySlot(container, index, x, y) { override fun mayPlace(itemStack: ItemStack): Boolean { - return super.mayPlace(itemStack) && itemStack.getCapability(ForgeCapabilities.ENERGY).map { direction.test(FlowDirection.of(it.canReceive(), it.canExtract())) }.orElse(false) + return super.mayPlace(itemStack) && (itemStack.getCapability(Capabilities.EnergyStorage.ITEM)?.let { direction.test(FlowDirection.of(it.canReceive(), it.canExtract())) } ?: false) } } @@ -143,20 +143,19 @@ open class MatterContainerInputSlot( val direction: FlowDirection = FlowDirection.BI_DIRECTIONAL ) : MatterySlot(container, index, x, y) { override fun mayPlace(itemStack: ItemStack): Boolean { - val handler = itemStack.getCapability(MatteryCapability.MATTER).resolve() - if (handler.isEmpty) return false - return super.mayPlace(itemStack) && this.direction.test(handler.get().matterFlow) + val handler = itemStack.getCapability(MatteryCapability.MATTER_ITEM) + return handler != null && super.mayPlace(itemStack) && this.direction.test(handler.matterFlow) } } open class PatternSlot(container: Container, index: Int, x: Int = 0, y: Int = 0) : MatterySlot(container, index, x, y) { override fun mayPlace(itemStack: ItemStack): Boolean { - return super.mayPlace(itemStack) && itemStack.getCapability(MatteryCapability.PATTERN).isPresent + return super.mayPlace(itemStack) && itemStack.getCapability(MatteryCapability.PATTERN_ITEM) != null } } open class DriveSlot(container: Container, index: Int, x: Int = 0, y: Int = 0) : MatterySlot(container, index, x, y) { override fun mayPlace(itemStack: ItemStack): Boolean { - return super.mayPlace(itemStack) && itemStack.getCapability(MatteryCapability.DRIVE).isPresent + return super.mayPlace(itemStack) && itemStack.getCapability(MatteryCapability.CONDENSATION_DRIVE) != null } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/data/NetworkedItemView.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/data/NetworkedItemView.kt index f79daf008..0a0f43408 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/data/NetworkedItemView.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/data/NetworkedItemView.kt @@ -6,13 +6,18 @@ import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap import net.minecraft.client.Minecraft import net.minecraft.client.gui.screens.Screen import net.minecraft.network.FriendlyByteBuf +import net.minecraft.network.codec.StreamCodec +import net.minecraft.network.protocol.common.custom.CustomPacketPayload import net.minecraft.server.level.ServerPlayer import net.minecraft.world.entity.player.Player import net.minecraft.world.inventory.ClickAction import net.minecraft.world.inventory.ClickType import net.minecraft.world.item.ItemStack -import net.minecraftforge.network.PacketDistributor +import net.neoforged.neoforge.network.PacketDistributor +import net.neoforged.neoforge.network.handling.IPayloadContext +import ru.dbotthepony.mc.otm.OverdriveThatMatters import ru.dbotthepony.mc.otm.client.minecraft +import ru.dbotthepony.mc.otm.core.ResourceLocation import ru.dbotthepony.mc.otm.core.addSorted import ru.dbotthepony.mc.otm.core.isNotEmpty import ru.dbotthepony.mc.otm.core.map @@ -34,15 +39,15 @@ interface INetworkedItemViewProvider { private fun all(stack: ItemStack): Int = stack.maxStackSize.coerceAtMost(stack.count) private fun half(stack: ItemStack): Int = (stack.maxStackSize.coerceAtMost(stack.count) / 2).coerceAtLeast(1) -data class ItemViewInteractPacket(val stackID: Int, val type: ClickType, val action: ClickAction) : MatteryPacket { - override fun write(buff: FriendlyByteBuf) { +data class ItemViewInteractPacket(val stackID: Int, val type: ClickType, val action: ClickAction) : CustomPacketPayload { + fun write(buff: FriendlyByteBuf) { buff.writeInt(stackID) buff.writeEnum(type) buff.writeEnum(action) } - override fun play(context: MNetworkContext) { - val sender = context.sender ?: return + fun play(context: IPayloadContext) { + val sender = context.player() as ServerPlayer if (!sender.isSpectator) { sender.resetLastActionTime() @@ -50,15 +55,29 @@ data class ItemViewInteractPacket(val stackID: Int, val type: ClickType, val act } } + override fun type(): CustomPacketPayload.Type { + return TYPE + } + companion object { + val TYPE = CustomPacketPayload.Type( + ResourceLocation( + OverdriveThatMatters.MOD_ID, + "item_view_interaction" + ) + ) + + val CODEC: StreamCodec = + StreamCodec.ofMember(ItemViewInteractPacket::write, ::read) + fun read(buff: FriendlyByteBuf): ItemViewInteractPacket { return ItemViewInteractPacket(buff.readInt(), buff.readEnum(ClickType::class.java), buff.readEnum(ClickAction::class.java)) } } } -abstract class NetworkedItemViewPacket : MatteryPacket { - final override fun play(context: MNetworkContext) { +abstract class NetworkedItemViewPacket : CustomPacketPayload { + fun play(context: IPayloadContext) { val get = Minecraft.getInstance().player?.containerMenu ?: return val view = (get as? INetworkedItemViewProvider)?.networkedItemView ?: throw IllegalStateException("No NetworkedItemView is present in currently open menu") action(view) @@ -68,7 +87,19 @@ abstract class NetworkedItemViewPacket : MatteryPacket { } object ClearItemViewPacket : NetworkedItemViewPacket() { - override fun write(buff: FriendlyByteBuf) {} + val TYPE = CustomPacketPayload.Type( + ResourceLocation( + OverdriveThatMatters.MOD_ID, + "clear_item_view" + ) + ) + + override fun type(): CustomPacketPayload.Type { + return TYPE + } + + val CODEC: StreamCodec = + StreamCodec.ofMember({ _, _ -> }, { ClearItemViewPacket }) override fun action(view: NetworkedItemView) { view.clear() @@ -76,7 +107,7 @@ object ClearItemViewPacket : NetworkedItemViewPacket() { } class StackAddPacket(val stackId: Int, val stack: ItemStorageStack) : NetworkedItemViewPacket() { - override fun write(buff: FriendlyByteBuf) { + fun write(buff: FriendlyByteBuf) { buff.writeInt(stackId) stack.write(buff) } @@ -91,7 +122,21 @@ class StackAddPacket(val stackId: Int, val stack: ItemStorageStack) : NetworkedI view.sortedView.addSorted(tuple, view.sorter.map(NetworkedItemView.Tuple::stack)) } + override fun type(): CustomPacketPayload.Type { + return TYPE + } + companion object { + val TYPE = CustomPacketPayload.Type( + ResourceLocation( + OverdriveThatMatters.MOD_ID, + "item_view_addition" + ) + ) + + val CODEC: StreamCodec = + StreamCodec.ofMember(StackAddPacket::write, ::read) + fun read(buffer: FriendlyByteBuf): StackAddPacket { val id = buffer.readInt() val item = StorageStack.ITEMS.read(buffer) @@ -101,7 +146,7 @@ class StackAddPacket(val stackId: Int, val stack: ItemStorageStack) : NetworkedI } class StackChangePacket(val stackId: Int, val newCount: BigInteger) : NetworkedItemViewPacket() { - override fun write(buff: FriendlyByteBuf) { + fun write(buff: FriendlyByteBuf) { buff.writeInt(stackId) buff.writeBigInteger(newCount) } @@ -112,7 +157,21 @@ class StackChangePacket(val stackId: Int, val newCount: BigInteger) : NetworkedI view.resort() } + override fun type(): CustomPacketPayload.Type { + return TYPE + } + companion object { + val TYPE = CustomPacketPayload.Type( + ResourceLocation( + OverdriveThatMatters.MOD_ID, + "item_view_change" + ) + ) + + val CODEC: StreamCodec = + StreamCodec.ofMember(StackChangePacket::write, ::read) + fun read(buffer: FriendlyByteBuf): StackChangePacket { val stackID = buffer.readInt() val newCount = buffer.readBigInteger() @@ -122,7 +181,7 @@ class StackChangePacket(val stackId: Int, val newCount: BigInteger) : NetworkedI } class StackRemovePacket(val stackId: Int) : NetworkedItemViewPacket() { - override fun write(buff: FriendlyByteBuf) { + fun write(buff: FriendlyByteBuf) { buff.writeInt(stackId) } @@ -132,7 +191,21 @@ class StackRemovePacket(val stackId: Int) : NetworkedItemViewPacket() { view.resort() } + override fun type(): CustomPacketPayload.Type { + return TYPE + } + companion object { + val TYPE = CustomPacketPayload.Type( + ResourceLocation( + OverdriveThatMatters.MOD_ID, + "item_view_remove" + ) + ) + + val CODEC: StreamCodec = + StreamCodec.ofMember(StackRemovePacket::write, ::read) + fun read(buffer: FriendlyByteBuf): StackRemovePacket { val stackID = buffer.readInt() return StackRemovePacket(stackID) @@ -167,7 +240,7 @@ class NetworkedItemView(val ply: Player, val menu: MatteryMenu, val isRemote: Bo private var nextItemID = 0 private val uuid2tuple = Object2ObjectOpenHashMap() - private val networkBacklog = ArrayList() + private val networkBacklog = ArrayList() operator fun get(id: Int): Tuple? = id2tuple[id] @@ -189,7 +262,7 @@ class NetworkedItemView(val ply: Player, val menu: MatteryMenu, val isRemote: Bo fun mouseClick(index: Int, mouseButton: Int) { if (minecraft.player?.isSpectator == true) return - MenuNetworkChannel.sendToServer(ItemViewInteractPacket( + PacketDistributor.sendToServer(ItemViewInteractPacket( sortedView.getOrNull(index)?.networkId ?: -1, if (mouseButton == InputConstants.MOUSE_BUTTON_MIDDLE) ClickType.CLONE else if (Screen.hasShiftDown()) ClickType.QUICK_MOVE else ClickType.PICKUP, if (mouseButton == InputConstants.MOUSE_BUTTON_LEFT) ClickAction.PRIMARY else ClickAction.SECONDARY @@ -223,7 +296,7 @@ class NetworkedItemView(val ply: Player, val menu: MatteryMenu, val isRemote: Bo network { StackRemovePacket(get.networkId) } } - private inline fun network(fn: () -> Any) { + private inline fun network(fn: () -> CustomPacketPayload) { if (!isRemote) { networkBacklog.add(fn()) } @@ -242,10 +315,9 @@ class NetworkedItemView(val ply: Player, val menu: MatteryMenu, val isRemote: Bo fun network() { check(!isRemote) { "Not a server" } - val consumer = PacketDistributor.PLAYER.with(ply as ServerPlayer) for (packet in networkBacklog) { - MenuNetworkChannel.send(consumer, packet) + PacketDistributor.sendToPlayer(ply as ServerPlayer, packet) } networkBacklog.clear() diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/decorative/FluidTankMenu.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/decorative/FluidTankMenu.kt index 401057a94..d3b3795f9 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/decorative/FluidTankMenu.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/decorative/FluidTankMenu.kt @@ -3,8 +3,8 @@ package ru.dbotthepony.mc.otm.menu.decorative import net.minecraft.world.SimpleContainer import net.minecraft.world.entity.player.Inventory import net.minecraft.world.item.ItemStack -import net.minecraftforge.common.capabilities.ForgeCapabilities -import net.minecraftforge.fluids.capability.IFluidHandler +import net.neoforged.neoforge.capabilities.Capabilities +import net.neoforged.neoforge.fluids.capability.IFluidHandler import ru.dbotthepony.mc.otm.block.entity.RedstoneSetting import ru.dbotthepony.mc.otm.block.entity.decorative.FluidTankBlockEntity import ru.dbotthepony.mc.otm.capability.isNotEmpty @@ -27,25 +27,22 @@ class FluidTankMenu(containerId: Int, inventory: Inventory, tile: FluidTankBlock val drainInput = object : MatterySlot(tile?.drainInput ?: SimpleContainer(1), 0) { override fun mayPlace(itemStack: ItemStack): Boolean { return super.mayPlace(itemStack) && - itemStack - .getCapability(ForgeCapabilities.FLUID_HANDLER_ITEM) - .map { it.isNotEmpty } - .orElse(false) + (itemStack.getCapability(Capabilities.FluidHandler.ITEM)?.isNotEmpty ?: false) } } val fillInput = object : MatterySlot(tile?.fillInput ?: SimpleContainer(1), 0) { override fun mayPlace(itemStack: ItemStack): Boolean { return super.mayPlace(itemStack) && - (if (itemStack.count <= 1) itemStack else itemStack.copyWithCount(1)) - .getCapability(ForgeCapabilities.FLUID_HANDLER_ITEM) - .map { - if (fluid.fluid.isEmpty) - it.tanks > 0 - else - it.fill(fluid.fluid, IFluidHandler.FluidAction.SIMULATE) > 0 - } - .orElse(false) + (if (itemStack.count <= 1) itemStack + else itemStack.copyWithCount(1)) + .getCapability(Capabilities.FluidHandler.ITEM) + ?.let { + if (fluid.fluid.isEmpty) + it.tanks > 0 + else + it.fill(fluid.fluid, IFluidHandler.FluidAction.SIMULATE) > 0 + } == true } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/decorative/PainterMenu.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/decorative/PainterMenu.kt index ed6279d1a..732ca65d0 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/decorative/PainterMenu.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/decorative/PainterMenu.kt @@ -6,9 +6,9 @@ import net.minecraft.world.entity.player.Player import net.minecraft.world.item.* import net.minecraft.world.item.crafting.RecipeHolder import net.minecraft.world.level.material.Fluids -import net.minecraftforge.common.capabilities.ForgeCapabilities -import net.minecraftforge.fluids.FluidStack -import net.minecraftforge.fluids.capability.IFluidHandler +import net.neoforged.neoforge.capabilities.Capabilities +import net.neoforged.neoforge.fluids.FluidStack +import net.neoforged.neoforge.fluids.capability.IFluidHandler import ru.dbotthepony.kommons.io.nullable import ru.dbotthepony.kommons.util.Listenable import ru.dbotthepony.kommons.util.ListenableDelegate @@ -61,7 +61,7 @@ class PainterMenu( return super.mayPlace(itemStack) } - return super.mayPlace(itemStack) && inventory.player.level().recipeManager.byType(MRecipes.PAINTER).values.any { it.value.matches(itemStack) } + return super.mayPlace(itemStack) && inventory.player.level().recipeManager.byType(MRecipes.PAINTER).any { it.value.matches(itemStack) } } } @@ -76,9 +76,9 @@ class PainterMenu( lastRecipe?.value?.dyes?.let { tile?.takeDyes(it) } if (isBulk.value) { - val found = player.matteryPlayer!!.inventoryAndExopack + val found = player.matteryPlayer.inventoryAndExopack .slotIterator() - .filter { !it.isForbiddenForAutomation && ItemStack.isSameItemSameTags(it.item, inputSlot.item) } + .filter { !it.isForbiddenForAutomation && ItemStack.isSameItemSameComponents(it.item, inputSlot.item) } .maybe() if (found != null) { @@ -103,9 +103,9 @@ class PainterMenu( val dyeSlot = object : MatterySlot(tile?.dyeInput ?: SimpleContainer(1), 0) { override fun mayPlace(itemStack: ItemStack): Boolean { return super.mayPlace(itemStack) && (( - itemStack.getCapability(ForgeCapabilities.FLUID_HANDLER_ITEM).resolve().map { + itemStack.getCapability(Capabilities.FluidHandler.ITEM)?.let { dyeStoredDirect[null]!! < PainterBlockEntity.MAX_WATER_STORAGE && it.drain(FluidStack(Fluids.WATER, PainterBlockEntity.MAX_WATER_STORAGE - dyeStoredDirect[null]!!), IFluidHandler.FluidAction.SIMULATE).isNotEmpty - }.orElse(false) + } ?: false ) || (DyeColor.getColor(itemStack)?.let { dyeStoredDirect[it]!! + PainterBlockEntity.HUE_PER_ITEM <= PainterBlockEntity.MAX_STORAGE } ?: false)) } } @@ -132,7 +132,7 @@ class PainterMenu( private fun rescan() { possibleRecipes.clear() - possibleRecipes.addAll(inventory.player.level().recipeManager.byType(MRecipes.PAINTER).values.iterator().filter { it.value.matches(inputContainer[0]) }) + possibleRecipes.addAll(inventory.player.level().recipeManager.byType(MRecipes.PAINTER).iterator().filter { it.value.matches(inputContainer[0]) }) listeners.run() if (tile !is PainterBlockEntity) return diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/matter/MatterBottlerMenu.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/matter/MatterBottlerMenu.kt index 0e0ad51f7..016d0824e 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/matter/MatterBottlerMenu.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/matter/MatterBottlerMenu.kt @@ -7,21 +7,19 @@ import net.minecraft.world.item.ItemStack import ru.dbotthepony.mc.otm.core.immutableList import ru.dbotthepony.mc.otm.block.entity.matter.MatterBottlerBlockEntity import ru.dbotthepony.mc.otm.capability.MatteryCapability -import ru.dbotthepony.mc.otm.capability.matter.ProfiledMatterStorage import ru.dbotthepony.mc.otm.capability.matter.canExtractMatter import ru.dbotthepony.mc.otm.capability.matter.canReceiveMatter import ru.dbotthepony.mc.otm.container.CombinedContainer import ru.dbotthepony.mc.otm.menu.input.BooleanInputWithFeedback import ru.dbotthepony.mc.otm.menu.widget.LevelGaugeWidget import ru.dbotthepony.mc.otm.menu.widget.ProgressGaugeWidget -import ru.dbotthepony.mc.otm.core.orNull import ru.dbotthepony.mc.otm.menu.MatteryPoweredMenu import ru.dbotthepony.mc.otm.menu.MatterySlot import ru.dbotthepony.mc.otm.menu.makeSlots import ru.dbotthepony.mc.otm.menu.widget.ProfiledLevelGaugeWidget import ru.dbotthepony.mc.otm.registry.MMenus -class MatterBottlerMenu @JvmOverloads constructor( +class MatterBottlerMenu( p_38852_: Int, inventory: Inventory, tile: MatterBottlerBlockEntity? = null @@ -33,7 +31,7 @@ class MatterBottlerMenu @JvmOverloads constructor( val storageSlots: ImmutableList = makeSlots(CombinedContainer(tile?.bottling ?: SimpleContainer(3), tile?.unbottling ?: SimpleContainer(3))) { it, index -> object : MatterySlot(it, index) { override fun mayPlace(itemStack: ItemStack): Boolean { - val cap = itemStack.getCapability(MatteryCapability.MATTER).orNull() ?: return false + val cap = itemStack.getCapability(MatteryCapability.MATTER_ITEM) ?: return false if (workFlow.value) { return index < 3 && cap.canReceiveMatter diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/matter/MatterEntanglerMenu.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/matter/MatterEntanglerMenu.kt index 7b3884ee5..e3ebd7ebd 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/matter/MatterEntanglerMenu.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/matter/MatterEntanglerMenu.kt @@ -6,6 +6,7 @@ import net.minecraft.world.SimpleContainer import net.minecraft.world.entity.player.Inventory import net.minecraft.world.entity.player.Player import net.minecraft.world.item.ItemStack +import net.minecraft.world.item.crafting.CraftingInput import ru.dbotthepony.mc.otm.block.entity.matter.MatterEntanglerBlockEntity import ru.dbotthepony.mc.otm.container.MatteryContainer import ru.dbotthepony.mc.otm.container.MatteryCraftingContainer @@ -45,13 +46,14 @@ class MatterEntanglerMenu( }) { it, i -> object : MatterySlot(it, i) { override fun mayPlace(itemStack: ItemStack): Boolean { - val shadow = ShadowCraftingContainer.shadow(it, i, itemStack) + val list = it.toList() + list[i] = itemStack + val shadow = CraftingInput.of(3, 3, list) val level = player.level() return super.mayPlace(itemStack) && (level ?: return false) .recipeManager .byType(MRecipes.MATTER_ENTANGLER) - .values .any { it.value.preemptivelyMatches(shadow, level) } } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/matter/MatterPanelMenu.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/matter/MatterPanelMenu.kt index 451b0549b..c06f06170 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/matter/MatterPanelMenu.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/matter/MatterPanelMenu.kt @@ -1,17 +1,23 @@ package ru.dbotthepony.mc.otm.menu.matter import net.minecraft.network.FriendlyByteBuf +import net.minecraft.network.codec.StreamCodec +import net.minecraft.network.protocol.common.custom.CustomPacketPayload import net.minecraft.server.level.ServerPlayer import net.minecraft.world.entity.player.Inventory import net.minecraft.world.entity.player.Player import net.minecraft.world.item.Item +import net.neoforged.neoforge.network.PacketDistributor +import net.neoforged.neoforge.network.handling.IPayloadContext import org.apache.logging.log4j.LogManager import ru.dbotthepony.kommons.io.NullValueCodec import ru.dbotthepony.kommons.util.getValue import ru.dbotthepony.kommons.util.setValue +import ru.dbotthepony.mc.otm.OverdriveThatMatters import ru.dbotthepony.mc.otm.block.entity.matter.MatterPanelBlockEntity import ru.dbotthepony.mc.otm.capability.matter.* import ru.dbotthepony.mc.otm.client.minecraft +import ru.dbotthepony.mc.otm.core.ResourceLocation import ru.dbotthepony.mc.otm.core.addSorted import ru.dbotthepony.mc.otm.core.map import ru.dbotthepony.mc.otm.core.math.Decimal @@ -27,30 +33,44 @@ import ru.dbotthepony.mc.otm.registry.MMenus import java.util.* import java.util.function.Predicate -class CancelTaskPacket(val id: UUID) : MatteryPacket { - override fun write(buff: FriendlyByteBuf) { +class CancelTaskPacket(val id: UUID) : CustomPacketPayload { + fun write(buff: FriendlyByteBuf) { buff.writeUUID(id) } - override fun play(context: MNetworkContext) { - val sender = context.sender!! + fun play(context: IPayloadContext) { + val sender = context.player() as ServerPlayer (sender.containerMenu as? MatterPanelMenu)?.receiveTaskCancel(sender, id) } + override fun type(): CustomPacketPayload.Type { + return TYPE + } + companion object { + val TYPE = CustomPacketPayload.Type( + ResourceLocation( + OverdriveThatMatters.MOD_ID, + "cancel_replication_task" + ) + ) + + val CODEC: StreamCodec = + StreamCodec.ofMember(CancelTaskPacket::write, ::read) + fun read(buff: FriendlyByteBuf): CancelTaskPacket { return CancelTaskPacket(buff.readUUID()) } } } -class PatternsChangePacket(val isUpdate: Boolean, val patterns: Collection) : MatteryPacket { - override fun write(buff: FriendlyByteBuf) { +class PatternsChangePacket(val isUpdate: Boolean, val patterns: Collection) : CustomPacketPayload { + fun write(buff: FriendlyByteBuf) { buff.writeBoolean(isUpdate) buff.writeCollection(patterns, PatternState::write) } - override fun play(context: MNetworkContext) { + fun play(context: IPayloadContext) { val menu = minecraft.player?.containerMenu as? MatterPanelMenu ?: return if (isUpdate) { @@ -60,20 +80,34 @@ class PatternsChangePacket(val isUpdate: Boolean, val patterns: Collection { + return TYPE + } + companion object { + val TYPE = CustomPacketPayload.Type( + ResourceLocation( + OverdriveThatMatters.MOD_ID, + "pattern_change_data" + ) + ) + + val CODEC: StreamCodec = + StreamCodec.ofMember(PatternsChangePacket::write, ::read) + fun read(buff: FriendlyByteBuf): PatternsChangePacket { return PatternsChangePacket(buff.readBoolean(), buff.readCollection(::ArrayList, PatternState::read)) } } } -class TasksChangePacket(val isUpdate: Boolean, val tasks: Collection) : MatteryPacket { - override fun write(buff: FriendlyByteBuf) { +class TasksChangePacket(val isUpdate: Boolean, val tasks: Collection) : CustomPacketPayload { + fun write(buff: FriendlyByteBuf) { buff.writeBoolean(isUpdate) buff.writeCollection(tasks, ReplicationTask::write) } - override fun play(context: MNetworkContext) { + fun play(context: IPayloadContext) { val menu = minecraft.player?.containerMenu as? MatterPanelMenu ?: return if (isUpdate) { @@ -83,29 +117,55 @@ class TasksChangePacket(val isUpdate: Boolean, val tasks: Collection { + return TYPE + } + companion object { + val TYPE = CustomPacketPayload.Type( + ResourceLocation( + OverdriveThatMatters.MOD_ID, + "task_change_data" + ) + ) + + val CODEC: StreamCodec = + StreamCodec.ofMember(TasksChangePacket::write, ::read) + fun read(buff: FriendlyByteBuf): TasksChangePacket { return TasksChangePacket(buff.readBoolean(), buff.readCollection(::ArrayList, ReplicationTask::read)) } } } -class ReplicationRequestPacket(val id: UUID, amount: Int) : MatteryPacket { +class ReplicationRequestPacket(val id: UUID, amount: Int) : CustomPacketPayload { val amount = amount.coerceAtLeast(1).coerceAtMost(99999) - override fun write(buff: FriendlyByteBuf) { + fun write(buff: FriendlyByteBuf) { buff.writeUUID(id) buff.writeInt(amount) } - override fun play(context: MNetworkContext) { - val sender = context.sender ?: return - val menu = sender.containerMenu as? MatterPanelMenu ?: return + fun play(context: IPayloadContext) { + val sender = context.player() as ServerPlayer + (sender.containerMenu as? MatterPanelMenu)?.requestReplication(sender, id, amount) + } - menu.requestReplication(sender, id, amount) + override fun type(): CustomPacketPayload.Type { + return TYPE } companion object { + val TYPE = CustomPacketPayload.Type( + ResourceLocation( + OverdriveThatMatters.MOD_ID, + "replication_request" + ) + ) + + val CODEC: StreamCodec = + StreamCodec.ofMember(ReplicationRequestPacket::write, ::read) + fun read(buff: FriendlyByteBuf): ReplicationRequestPacket { return ReplicationRequestPacket(buff.readUUID(), buff.readInt()) } @@ -284,7 +344,7 @@ class MatterPanelMenu( fun requestTaskCancel(id: UUID) { if (minecraft.player?.isSpectator != true) - MenuNetworkChannel.sendToServer(CancelTaskPacket(id)) + PacketDistributor.sendToServer(CancelTaskPacket(id)) } override fun onPatternAdded(state: PatternState) { @@ -321,8 +381,8 @@ class MatterPanelMenu( if (!initialSend) fullPatternBroadcast() } - private fun sendNetwork(packet: Any) { - MenuNetworkChannel.send(inventory.player, packet) + private fun sendNetwork(packet: CustomPacketPayload) { + PacketDistributor.sendToPlayer(inventory.player as ServerPlayer, packet) } fun fullPatternBroadcast() { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/storage/DriveViewerMenu.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/storage/DriveViewerMenu.kt index ff2b8e2a7..f45713220 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/storage/DriveViewerMenu.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/storage/DriveViewerMenu.kt @@ -4,7 +4,7 @@ import net.minecraft.world.SimpleContainer import net.minecraft.world.entity.player.Inventory import net.minecraft.world.entity.player.Player import net.minecraft.world.item.ItemStack -import net.minecraftforge.common.capabilities.ForgeCapabilities +import net.neoforged.neoforge.capabilities.Capabilities import ru.dbotthepony.kommons.util.Delegate import ru.dbotthepony.kommons.util.getValue import ru.dbotthepony.kommons.util.setValue @@ -13,7 +13,6 @@ import ru.dbotthepony.mc.otm.capability.MatteryCapability import ru.dbotthepony.mc.otm.capability.drive.IMatteryDrive import ru.dbotthepony.mc.otm.capability.energy.ProfiledEnergyStorage import ru.dbotthepony.mc.otm.container.ItemFilter -import ru.dbotthepony.mc.otm.core.ifPresentK import ru.dbotthepony.mc.otm.core.immutableList import ru.dbotthepony.mc.otm.core.util.ItemStorageStackSorter import ru.dbotthepony.mc.otm.core.util.computedItem @@ -40,7 +39,7 @@ class DriveViewerMenu( val driveSlot = object : MatterySlot(tile?.container ?: SimpleContainer(1), 0) { override fun mayPlace(itemStack: ItemStack): Boolean { - return itemStack.getCapability(MatteryCapability.DRIVE).isPresent + return itemStack.getCapability(MatteryCapability.CONDENSATION_DRIVE) != null } } @@ -98,7 +97,7 @@ class DriveViewerMenu( val isWhitelist = BooleanInputWithFeedback(this, make { Delegate.Of(it::isWhitelist) }).also { it.filter { drivePresent } } val matchTag = BooleanInputWithFeedback(this, make { Delegate.Of(it::matchTag) }).also { it.filter { drivePresent } } - val matchNBT = BooleanInputWithFeedback(this, make { Delegate.Of(it::matchNBT) }).also { it.filter { drivePresent } } + val matchNBT = BooleanInputWithFeedback(this, make { Delegate.Of(it::matchComponents) }).also { it.filter { drivePresent } } override fun broadcastChanges() { super.broadcastChanges() @@ -110,7 +109,7 @@ class DriveViewerMenu( lastDrive = null if (!itemStack.isEmpty) { - itemStack.getCapability(MatteryCapability.DRIVE).ifPresentK { + itemStack.getCapability(MatteryCapability.CONDENSATION_DRIVE)?.let { if (it.storageType == StorageStack.ITEMS) { lastDrive = it as IMatteryDrive } @@ -139,7 +138,7 @@ class DriveViewerMenu( val slot = slots[slotIndex] val item = slot.item - if (item.isEmpty || item.getCapability(MatteryCapability.DRIVE).isPresent || item.getCapability(ForgeCapabilities.ENERGY).isPresent) + if (item.isEmpty || item.getCapability(MatteryCapability.CONDENSATION_DRIVE) != null || item.getCapability(Capabilities.EnergyStorage.ITEM) != null) return super.quickMoveStack(ply, slotIndex) val powered = powered diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/storage/StorageImporterExporterMenu.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/storage/StorageImporterExporterMenu.kt index f0573601a..4ab3901f6 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/storage/StorageImporterExporterMenu.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/storage/StorageImporterExporterMenu.kt @@ -13,7 +13,7 @@ class StorageImporterExporterMenu( ) : MatteryPoweredMenu(MMenus.STORAGE_IMPORTER_EXPORTER, containerId, inventory, tile) { val filterSlots = addFilterSlots(tile?.filter, AbstractStorageImportExport.MAX_FILTERS) val isWhitelist = BooleanInputWithFeedback(this, tile?.let { it.filter::isWhitelist }) - val matchNBT = BooleanInputWithFeedback(this, tile?.let { it.filter::matchNBT }) + val matchNBT = BooleanInputWithFeedback(this, tile?.let { it.filter::matchComponents }) val matchTag = BooleanInputWithFeedback(this, tile?.let { it.filter::matchTag }) val profiledEnergy = ProfiledLevelGaugeWidget(this, tile?.energy, energyWidget) val energyConfig = EnergyConfigPlayerInput(this, tile?.energyConfig) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/AndroidStationMenu.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/AndroidStationMenu.kt index 301f24d27..c919c8d9c 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/AndroidStationMenu.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/AndroidStationMenu.kt @@ -6,9 +6,9 @@ import net.minecraft.world.SimpleContainer import net.minecraft.world.entity.player.Inventory import net.minecraft.world.entity.player.Player import net.minecraft.world.item.ItemStack -import net.minecraftforge.common.capabilities.ForgeCapabilities +import net.neoforged.neoforge.capabilities.Capabilities import ru.dbotthepony.mc.otm.block.entity.tech.AndroidStationBlockEntity -import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability +import ru.dbotthepony.mc.otm.capability.MatteryPlayer import ru.dbotthepony.mc.otm.capability.matteryPlayer import ru.dbotthepony.mc.otm.config.MachinesConfig import ru.dbotthepony.mc.otm.menu.MatteryPoweredMenu @@ -23,7 +23,7 @@ class AndroidStationMenu @JvmOverloads constructor( inventory: Inventory, tile: AndroidStationBlockEntity? = null ) : MatteryPoweredMenu(MMenus.ANDROID_STATION, containerID, inventory, tile) { - private fun container(target: (MatteryPlayerCapability) -> KMutableProperty0): Container { + private fun container(target: (MatteryPlayer) -> KMutableProperty0): Container { if (player is ServerPlayer) return PartContainer(target.invoke(player.matteryPlayer ?: throw NullPointerException("OTM player capability is missing"))) else @@ -109,7 +109,7 @@ class AndroidStationMenu @JvmOverloads constructor( } val androidBattery: MatterySlot = AndroidSlot(container { it.androidEnergy::item }) { - it.getCapability(ForgeCapabilities.ENERGY).isPresent + it.getCapability(Capabilities.EnergyStorage.ITEM) != null } val equipment = makeEquipmentSlots() diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/ChemicalGeneratorMenu.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/ChemicalGeneratorMenu.kt index 523d7ddd2..1ca7495a7 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/ChemicalGeneratorMenu.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/ChemicalGeneratorMenu.kt @@ -3,13 +3,11 @@ package ru.dbotthepony.mc.otm.menu.tech import net.minecraft.world.SimpleContainer import net.minecraft.world.entity.player.Inventory import net.minecraft.world.item.ItemStack -import net.minecraftforge.common.ForgeHooks -import net.minecraftforge.common.capabilities.ForgeCapabilities +import net.neoforged.neoforge.capabilities.Capabilities import ru.dbotthepony.kommons.util.getValue import ru.dbotthepony.kommons.util.setValue import ru.dbotthepony.mc.otm.block.entity.RedstoneSetting import ru.dbotthepony.mc.otm.block.entity.tech.ChemicalGeneratorBlockEntity -import ru.dbotthepony.mc.otm.core.ifPresentK import ru.dbotthepony.mc.otm.menu.MatteryMenu import ru.dbotthepony.mc.otm.menu.MatterySlot import ru.dbotthepony.mc.otm.menu.input.EnergyConfigPlayerInput @@ -34,7 +32,7 @@ class ChemicalGeneratorMenu @JvmOverloads constructor(id: Int, inv: Inventory, t val fuelSlot = object : MatterySlot(tile?.fuelContainer ?: SimpleContainer(1), 0) { override fun mayPlace(itemStack: ItemStack): Boolean { - return ForgeHooks.getBurnTime(itemStack, null) > 0 + return itemStack.getBurnTime(null) > 0 } } @@ -46,11 +44,7 @@ class ChemicalGeneratorMenu @JvmOverloads constructor(id: Int, inv: Inventory, t val batterySlot = object : MatterySlot(tile?.batteryContainer ?: SimpleContainer(1), 0) { override fun mayPlace(itemStack: ItemStack): Boolean { - itemStack.getCapability(ForgeCapabilities.ENERGY).ifPresentK { - return it.canReceive() - } - - return false + return itemStack.getCapability(Capabilities.EnergyStorage.ITEM)?.canReceive() ?: false } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/PoweredFurnaceMenu.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/PoweredFurnaceMenu.kt index 06fb5781f..3a7eadedf 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/PoweredFurnaceMenu.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/PoweredFurnaceMenu.kt @@ -3,6 +3,7 @@ package ru.dbotthepony.mc.otm.menu.tech import mezz.jei.api.constants.RecipeTypes import mezz.jei.api.recipe.RecipeType import net.minecraft.server.level.ServerPlayer +import net.minecraft.world.SimpleContainer import net.minecraft.world.entity.player.Inventory import net.minecraft.world.inventory.MenuType import ru.dbotthepony.mc.otm.block.entity.tech.AbstractPoweredFurnaceBlockEntity @@ -30,8 +31,8 @@ class PoweredFurnaceMenu( inventory: Inventory, tile: AbstractPoweredFurnaceBlockEntity<*, *>? = null ) : AbstractProcessingMachineMenu(type, containerID, inventory, tile) { - val inputSlots = makeSlots(tile?.inputs, 2, ::MatterySlot) - val outputSlots = makeSlots(tile?.outputs, 2) { c, s -> OutputSlot(c, s) { tile?.experience?.popExperience(player as ServerPlayer) } } + val inputSlots = makeSlots(tile?.inputs ?: SimpleContainer(2), ::MatterySlot) + val outputSlots = makeSlots(tile?.outputs ?: SimpleContainer(2)) { c, s -> OutputSlot(c, s) { tile?.experience?.popExperience(player as ServerPlayer) } } val progressGauge = immutableList(2) { ProgressGaugeWidget(this, tile?.jobEventLoops?.get(it)) } override val itemConfig = ItemConfigPlayerInput(this, tile?.itemConfig, allowPush = true) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/widget/FluidGaugeWidget.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/widget/FluidGaugeWidget.kt index a6cde9eb0..1b9391bdd 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/widget/FluidGaugeWidget.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/widget/FluidGaugeWidget.kt @@ -1,7 +1,7 @@ package ru.dbotthepony.mc.otm.menu.widget -import net.minecraftforge.fluids.FluidStack -import net.minecraftforge.fluids.capability.IFluidHandler +import net.neoforged.neoforge.fluids.FluidStack +import net.neoforged.neoforge.fluids.capability.IFluidHandler import ru.dbotthepony.kommons.io.DelegateSyncher import ru.dbotthepony.kommons.util.getValue import ru.dbotthepony.mc.otm.container.get diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/network/AndroidPackets.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/network/AndroidPackets.kt new file mode 100644 index 000000000..136c4fc2d --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/network/AndroidPackets.kt @@ -0,0 +1,400 @@ +package ru.dbotthepony.mc.otm.network + +import it.unimi.dsi.fastutil.io.FastByteArrayOutputStream +import net.minecraft.network.FriendlyByteBuf +import net.minecraft.network.RegistryFriendlyByteBuf +import net.minecraft.network.chat.Component +import net.minecraft.network.codec.StreamCodec +import net.minecraft.network.protocol.common.custom.CustomPacketPayload +import net.minecraft.server.level.ServerPlayer +import net.minecraft.sounds.SoundSource +import net.neoforged.neoforge.network.PacketDistributor +import net.neoforged.neoforge.network.handling.IPayloadContext +import ru.dbotthepony.mc.otm.OverdriveThatMatters +import ru.dbotthepony.mc.otm.android.AndroidActiveFeature +import ru.dbotthepony.mc.otm.android.AndroidFeatureType +import ru.dbotthepony.mc.otm.android.AndroidResearchManager +import ru.dbotthepony.mc.otm.android.AndroidResearchType +import ru.dbotthepony.mc.otm.android.AndroidSwitchableFeature +import ru.dbotthepony.mc.otm.capability.energy.extractEnergyExact +import ru.dbotthepony.mc.otm.capability.matteryPlayer +import ru.dbotthepony.mc.otm.client.MatteryGUI +import ru.dbotthepony.mc.otm.client.minecraft +import ru.dbotthepony.mc.otm.client.render.GlitchRenderer +import ru.dbotthepony.mc.otm.config.AndroidConfig +import ru.dbotthepony.mc.otm.core.ResourceLocation +import ru.dbotthepony.mc.otm.core.readComponent +import ru.dbotthepony.mc.otm.core.writeComponent +import ru.dbotthepony.mc.otm.menu.tech.AndroidStationMenu +import ru.dbotthepony.mc.otm.onceServer +import ru.dbotthepony.mc.otm.registry.AndroidFeatures +import ru.dbotthepony.mc.otm.registry.MRegistry +import ru.dbotthepony.mc.otm.registry.MSoundEvents +import java.io.ByteArrayInputStream + +class AndroidFeatureSyncPacket(val type: AndroidFeatureType<*>, val dataList: FastByteArrayOutputStream?, val dataBytes: ByteArray?) : CustomPacketPayload { + fun write(buff: FriendlyByteBuf) { + dataList ?: throw NullPointerException("No byte list is present") + buff.writeInt(MRegistry.ANDROID_FEATURES.getId(type)) + buff.writeBytes(dataList.array, 0, dataList.length) + } + + fun play(context: IPayloadContext) { + dataBytes ?: throw NullPointerException("No data bytes array is present") + val android = minecraft.player?.matteryPlayer ?: return + android.computeIfAbsent(type).applyNetworkPayload(ByteArrayInputStream(dataBytes)) + } + + override fun type(): CustomPacketPayload.Type { + return TYPE + } + + companion object { + val TYPE = CustomPacketPayload.Type( + ResourceLocation( + OverdriveThatMatters.MOD_ID, + "android_feature_sync" + ) + ) + + val CODEC: StreamCodec = + StreamCodec.ofMember(AndroidFeatureSyncPacket::write, ::read) + + fun read(buff: FriendlyByteBuf): AndroidFeatureSyncPacket { + return AndroidFeatureSyncPacket( + MRegistry.ANDROID_FEATURES.byIdOrThrow(buff.readInt()), + null, ByteArray(buff.readableBytes()).also { buff.readBytes(it) } + ) + } + } +} + +class AndroidResearchSyncPacket(val type: AndroidResearchType, val dataList: FastByteArrayOutputStream?, val dataBytes: ByteArray?) : + CustomPacketPayload { + fun write(buff: FriendlyByteBuf) { + dataList ?: throw NullPointerException("No byte list is present") + buff.writeUtf(type.id.toString()) + buff.writeBytes(dataList.array, 0, dataList.length) + } + + fun play(context: IPayloadContext) { + dataBytes ?: throw NullPointerException("No data bytes array is present") + val android = minecraft.player?.matteryPlayer ?: return + android.getResearch(type).applyNetworkPayload(ByteArrayInputStream(dataBytes)) + } + + override fun type(): CustomPacketPayload.Type { + return TYPE + } + + companion object { + val TYPE = CustomPacketPayload.Type( + ResourceLocation( + OverdriveThatMatters.MOD_ID, + "android_research_sync" + ) + ) + + val CODEC: StreamCodec = + StreamCodec.ofMember(AndroidResearchSyncPacket::write, ::read) + + fun read(buff: FriendlyByteBuf): AndroidResearchSyncPacket { + return AndroidResearchSyncPacket( + AndroidResearchManager[net.minecraft.resources.ResourceLocation.parse(buff.readUtf())] ?: throw NoSuchElementException(), + null, ByteArray(buff.readableBytes()).also { buff.readBytes(it) } + ) + } + } +} + +class AndroidResearchRequestPacket(val type: AndroidResearchType) : CustomPacketPayload { + fun write(buff: FriendlyByteBuf) { + buff.writeUtf(type.id.toString()) + } + + fun play(context: IPayloadContext) { + val ply = context.player() + if (ply.isSpectator) return + + if (!ply.matteryPlayer.isAndroid || ply.containerMenu !is AndroidStationMenu) + return + + ply.matteryPlayer.getResearch(type).research() + } + + override fun type(): CustomPacketPayload.Type { + return TYPE + } + + companion object { + val TYPE = CustomPacketPayload.Type( + ResourceLocation( + OverdriveThatMatters.MOD_ID, + "android_research_request" + ) + ) + + val CODEC: StreamCodec = StreamCodec.ofMember(AndroidResearchRequestPacket::write, ::read) + + fun read(buff: FriendlyByteBuf): AndroidResearchRequestPacket { + return AndroidResearchRequestPacket( + AndroidResearchManager[net.minecraft.resources.ResourceLocation.parse(buff.readUtf())] ?: throw NoSuchElementException() + ) + } + } +} + +class AndroidFeatureRemovePacket(val type: AndroidFeatureType<*>) : CustomPacketPayload { + fun write(buff: FriendlyByteBuf) { + buff.writeInt(MRegistry.ANDROID_FEATURES.getId(type)) + } + + fun play(context: IPayloadContext) { + val android = minecraft.player?.matteryPlayer ?: return + android.removeFeature(type) + } + + override fun type(): CustomPacketPayload.Type { + return TYPE + } + + companion object { + val TYPE = CustomPacketPayload.Type( + ResourceLocation( + OverdriveThatMatters.MOD_ID, + "android_feature_remove" + ) + ) + + val CODEC: StreamCodec = + StreamCodec.ofMember(AndroidFeatureRemovePacket::write, ::read) + + fun read(buff: FriendlyByteBuf): AndroidFeatureRemovePacket { + return AndroidFeatureRemovePacket(MRegistry.ANDROID_FEATURES.byIdOrThrow(buff.readInt())) + } + } +} + +class PlayerIterationPacket(val iteration: Int, val deathLog: List>) : CustomPacketPayload { + fun write(buff: RegistryFriendlyByteBuf) { + buff.writeInt(iteration) + buff.writeInt(deathLog.size) + + for ((ticks, value) in deathLog) { + buff.writeInt(ticks) + buff.writeComponent(value) + } + } + + fun play(context: IPayloadContext) { + MatteryGUI.iteration = iteration + MatteryGUI.deathLog.clear() + MatteryGUI.deathLog.addAll(deathLog) + MatteryGUI.showIterationUntil = System.currentTimeMillis() + 4000L + MatteryGUI.showIterationUntilFade = System.currentTimeMillis() + 5000L + } + + override fun type(): CustomPacketPayload.Type { + return TYPE + } + + companion object { + val TYPE = CustomPacketPayload.Type( + ResourceLocation( + OverdriveThatMatters.MOD_ID, + "player_iteration" + ) + ) + val CODEC: StreamCodec = + StreamCodec.ofMember(PlayerIterationPacket::write, ::read) + + fun read(buff: RegistryFriendlyByteBuf): PlayerIterationPacket { + val iteration = buff.readInt() + val size = buff.readInt() + + val list = ArrayList>() + + for (i in 0 until size) { + list.add(buff.readInt() to buff.readComponent()) + } + + return PlayerIterationPacket(iteration, list) + } + } +} + +class SwitchAndroidFeaturePacket(val type: AndroidFeatureType<*>, val newState: Boolean) : CustomPacketPayload { + fun write(buff: FriendlyByteBuf) { + buff.writeInt(MRegistry.ANDROID_FEATURES.getId(type)) + buff.writeBoolean(newState) + } + + fun play(context: IPayloadContext) { + val matteryPlayer = context.player().matteryPlayer + + if (!matteryPlayer.isAndroid) { + return + } + + val feature = matteryPlayer.getFeature(type) ?: return + + if (feature is AndroidActiveFeature && feature.allowToSwitchByPlayer && (!matteryPlayer.ply.isSpectator || feature.allowToSwitchByPlayerWhileSpectator)) { + matteryPlayer.features + .map { it as? AndroidActiveFeature } + .filter { it != null && it !== feature && it.allowToSwitchByPlayer && (!matteryPlayer.ply.isSpectator || it.allowToSwitchByPlayerWhileSpectator) } + .forEach { it!!.isActive = false } + + feature.isActive = newState + } else if (feature is AndroidSwitchableFeature && feature.allowToSwitchByPlayer && (!matteryPlayer.ply.isSpectator || feature.allowToSwitchByPlayerWhileSpectator)) { + feature.isActive = newState + } + } + + override fun type(): CustomPacketPayload.Type { + return TYPE + } + + companion object { + val TYPE = CustomPacketPayload.Type( + ResourceLocation( + OverdriveThatMatters.MOD_ID, + "switch_android_feature" + ) + ) + val CODEC: StreamCodec = + StreamCodec.ofMember(SwitchAndroidFeaturePacket::write, ::read) + + fun read(buff: FriendlyByteBuf): SwitchAndroidFeaturePacket { + return SwitchAndroidFeaturePacket(MRegistry.ANDROID_FEATURES.byIdOrThrow(buff.readInt()), buff.readBoolean()) + } + } +} + +class ActivateAndroidFeaturePacket(val type: AndroidFeatureType<*>) : CustomPacketPayload { + fun write(buff: FriendlyByteBuf) { + buff.writeInt(MRegistry.ANDROID_FEATURES.getId(type)) + } + + fun play(context: IPayloadContext) { + val matteryPlayer = context.player().matteryPlayer + + if (!matteryPlayer.isAndroid || matteryPlayer.ply.isSpectator) { + return + } + + val feature = matteryPlayer.getFeature(type) as? AndroidActiveFeature ?: return + + if (feature.isActive || feature.allowToSwitchByPlayer) { + feature.activate(false) + } + } + + override fun type(): CustomPacketPayload.Type { + return TYPE + } + + companion object { + val TYPE = CustomPacketPayload.Type( + ResourceLocation( + OverdriveThatMatters.MOD_ID, + "activate_android_feature" + ) + ) + val CODEC: StreamCodec = + StreamCodec.ofMember(ActivateAndroidFeaturePacket::write, ::read) + + fun read(buff: FriendlyByteBuf): ActivateAndroidFeaturePacket { + return ActivateAndroidFeaturePacket(MRegistry.ANDROID_FEATURES.byIdOrThrow(buff.readInt())) + } + } +} + +class GlitchPacket(val millis: Long) : CustomPacketPayload { + fun write(buff: FriendlyByteBuf) { + buff.writeVarLong(millis) + } + + fun play(context: IPayloadContext) { + GlitchRenderer.glitchFor(millis) + } + + override fun type(): CustomPacketPayload.Type { + return TYPE + } + + companion object { + val TYPE = CustomPacketPayload.Type( + ResourceLocation( + OverdriveThatMatters.MOD_ID, + "android_glitch" + ) + ) + val CODEC: StreamCodec = + StreamCodec.ofMember(GlitchPacket::write, ::read) + + fun read(buff: FriendlyByteBuf): GlitchPacket { + return GlitchPacket(buff.readVarLong()) + } + } +} + +object TriggerShockwavePacket : CustomPacketPayload { + fun play(context: IPayloadContext) { + val shockwave = context.player().matteryPlayer.getFeature(AndroidFeatures.SHOCKWAVE) ?: return + + if (!shockwave.isOnCooldown && shockwave.isActive && shockwave.airTicks > 0) { + onceServer { // delay by one tick so player update its position as well + shockwave.shockwave() + } + } + } + + override fun type(): CustomPacketPayload.Type { + return TYPE + } + + val TYPE = CustomPacketPayload.Type( + ResourceLocation( + OverdriveThatMatters.MOD_ID, + "trigger_shockwave" + ) + ) + val CODEC: StreamCodec = + StreamCodec.ofMember({ _, _ -> }, { TriggerShockwavePacket }) +} + +object TriggerJumpBoostPacket : CustomPacketPayload { + fun play(context: IPayloadContext) { + val mattery = context.player().matteryPlayer + + if (!mattery.isAndroid) + return + + val feature = mattery.getFeature(AndroidFeatures.JUMP_BOOST) ?: return + + if (feature.isActive && feature.cooldown <= 4 && mattery.androidEnergy.extractEnergyExact(AndroidConfig.JumpBoost.ENERGY_COST, false)) { + feature.putOnCooldown() + + context.player().level().playSound( + context.player(), context.player(), + MSoundEvents.ANDROID_JUMP_BOOST, SoundSource.PLAYERS, + 1f, 1f + ) + + SmokeParticlesPacket.makeSmoke(context.player() as ServerPlayer, context.player().x, context.player().y, context.player().z) + } + } + + override fun type(): CustomPacketPayload.Type { + return TYPE + } + + val TYPE = CustomPacketPayload.Type( + ResourceLocation( + OverdriveThatMatters.MOD_ID, + "trigger_jump_boost" + ) + ) + val CODEC: StreamCodec = + StreamCodec.ofMember({ _, _ -> }, { TriggerJumpBoostPacket }) +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/network/GenericNetworkChannel.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/network/BlockEntitySyncPacket.kt similarity index 56% rename from src/main/kotlin/ru/dbotthepony/mc/otm/network/GenericNetworkChannel.kt rename to src/main/kotlin/ru/dbotthepony/mc/otm/network/BlockEntitySyncPacket.kt index 9d3c19820..81732437e 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/network/GenericNetworkChannel.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/network/BlockEntitySyncPacket.kt @@ -4,53 +4,24 @@ import it.unimi.dsi.fastutil.io.FastByteArrayInputStream import it.unimi.dsi.fastutil.objects.Object2ObjectFunction import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap import net.minecraft.core.BlockPos -import net.minecraft.core.particles.ParticleTypes import net.minecraft.network.FriendlyByteBuf -import net.minecraft.server.level.ServerPlayer -import net.minecraft.util.RandomSource +import net.minecraft.network.codec.StreamCodec +import net.minecraft.network.protocol.common.custom.CustomPacketPayload import net.minecraft.world.level.Level -import net.minecraftforge.network.NetworkDirection -import net.minecraftforge.network.PacketDistributor +import net.neoforged.neoforge.network.handling.IPayloadContext import org.apache.logging.log4j.LogManager -import ru.dbotthepony.mc.otm.android.AndroidResearchManager -import ru.dbotthepony.mc.otm.android.feature.ItemEntityDataPacket +import ru.dbotthepony.mc.otm.OverdriveThatMatters import ru.dbotthepony.mc.otm.block.entity.MatteryBlockEntity import ru.dbotthepony.mc.otm.client.minecraft import ru.dbotthepony.mc.otm.client.onceClient +import ru.dbotthepony.mc.otm.core.ResourceLocation import ru.dbotthepony.mc.otm.core.collect.map import ru.dbotthepony.mc.otm.core.collect.reduce -import ru.dbotthepony.mc.otm.item.QuantumBatteryItem -import ru.dbotthepony.mc.otm.matter.MatterManager import java.util.* import kotlin.collections.ArrayList -class SmokeParticlesPacket(val x: Double, val y: Double, val z: Double) : MatteryPacket { - override fun write(buff: FriendlyByteBuf) { - buff.writeDouble(x) - buff.writeDouble(y) - buff.writeDouble(z) - } - - override fun play(context: MNetworkContext) { - minecraft.player?.level()?.let { - makeSmoke(x, y, z, it.random, it) - } - } - - companion object { - fun read(buff: FriendlyByteBuf): SmokeParticlesPacket { - return SmokeParticlesPacket(buff.readDouble(), buff.readDouble(), buff.readDouble()) - } - - fun makeSmoke(x: Double, y: Double, z: Double, random: RandomSource, level: Level) { - for (i in 0 .. random.nextInt(4, 8)) - level.addParticle(ParticleTypes.POOF, x + random.nextDouble() * 0.5 - 0.25, y + random.nextDouble() * 0.5 - 0.25, z + random.nextDouble() * 0.5 - 0.25, random.nextGaussian() * 0.02, random.nextGaussian() * 0.02, random.nextGaussian() * 0.02) - } - } -} - -class BlockEntitySyncPacket(val position: BlockPos, val buffer: ByteArray, val validBytes: Int) : MatteryPacket { - override fun write(buff: FriendlyByteBuf) { +class BlockEntitySyncPacket(val position: BlockPos, val buffer: ByteArray, val validBytes: Int) : CustomPacketPayload { + fun write(buff: FriendlyByteBuf) { buff.writeBlockPos(position) buff.writeBytes(buffer, 0, validBytes) } @@ -100,13 +71,20 @@ class BlockEntitySyncPacket(val position: BlockPos, val buffer: ByteArray, val v } } - override fun play(context: MNetworkContext) { + fun play(context: IPayloadContext) { execute() } + override fun type(): CustomPacketPayload.Type { + return TYPE + } + companion object { private val backlog = WeakHashMap>>() + val CODEC: StreamCodec = StreamCodec.ofMember(BlockEntitySyncPacket::write, ::read) + val TYPE = CustomPacketPayload.Type(ResourceLocation(OverdriveThatMatters.MOD_ID, "block_entity_data")) + fun read(buff: FriendlyByteBuf): BlockEntitySyncPacket { val position = buff.readBlockPos() val size = buff.readableBytes() @@ -134,28 +112,3 @@ class BlockEntitySyncPacket(val position: BlockPos, val buffer: ByteArray, val v } } } - -object GenericNetworkChannel : MatteryNetworkChannel( - version = 5, - name = "generic" -) { - fun makeSmoke(x: Double, y: Double, z: Double, level: Level) { - send(PacketDistributor.NEAR.with(PacketDistributor.TargetPoint(x, y, z, 64.0, level.dimension())), SmokeParticlesPacket(x, y, z)) - } - - fun makeSmoke(excluded: ServerPlayer, x: Double, y: Double, z: Double) { - send(PacketDistributor.NEAR.with(PacketDistributor.TargetPoint(excluded, x, y, z, 64.0, excluded.level().dimension())), SmokeParticlesPacket(x, y, z)) - } - - fun register() { - add(QuantumBatteryItem.ChargePacket::class.java, QuantumBatteryItem.Companion::readPacket, NetworkDirection.PLAY_TO_CLIENT) - - add(BlockEntitySyncPacket::class.java, BlockEntitySyncPacket.Companion::read, NetworkDirection.PLAY_TO_CLIENT) - add(ItemEntityDataPacket::class.java, ItemEntityDataPacket.Companion::read, NetworkDirection.PLAY_TO_CLIENT) - - add(AndroidResearchManager.SyncPacket::class.java, AndroidResearchManager::readSyncPacket, NetworkDirection.PLAY_TO_CLIENT, handleOnMainThread = false) - add(MatterManager.SyncPacket::class.java, MatterManager::readSyncPacket, NetworkDirection.PLAY_TO_CLIENT) - - add(SmokeParticlesPacket::class, SmokeParticlesPacket.Companion::read, NetworkDirection.PLAY_TO_CLIENT) - } -} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/network/Ext.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/network/Ext.kt new file mode 100644 index 000000000..649826d53 --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/network/Ext.kt @@ -0,0 +1,20 @@ +package ru.dbotthepony.mc.otm.network + +import net.minecraft.network.FriendlyByteBuf +import net.minecraft.network.codec.StreamCodec +import net.minecraft.network.protocol.common.custom.CustomPacketPayload +import net.neoforged.neoforge.network.handling.IPayloadContext +import net.neoforged.neoforge.network.registration.PayloadRegistrar +import kotlin.reflect.KFunction1 + +fun PayloadRegistrar.playToClient( + type: CustomPacketPayload.Type, + codec: StreamCodec, + handler: KFunction1 +): PayloadRegistrar = playToClient(type, codec) { _, context -> handler(context) } + +fun PayloadRegistrar.playToServer( + type: CustomPacketPayload.Type, + codec: StreamCodec, + handler: KFunction1 +): PayloadRegistrar = playToServer(type, codec) { _, context -> handler(context) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/network/MatteryNetworkChannel.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/network/MatteryNetworkChannel.kt deleted file mode 100644 index 8777da206..000000000 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/network/MatteryNetworkChannel.kt +++ /dev/null @@ -1,121 +0,0 @@ -package ru.dbotthepony.mc.otm.network - -import net.minecraft.network.FriendlyByteBuf -import net.minecraft.resources.ResourceLocation -import net.minecraft.server.level.ServerPlayer -import net.minecraft.world.entity.Entity -import net.minecraft.world.entity.player.Player -import net.minecraftforge.event.network.CustomPayloadEvent -import net.minecraftforge.network.Channel -import net.minecraftforge.network.ChannelBuilder -import net.minecraftforge.network.NetworkDirection -import net.minecraftforge.network.PacketDistributor -import net.minecraftforge.network.SimpleChannel -import org.apache.logging.log4j.LogManager -import ru.dbotthepony.kommons.util.Delegate -import ru.dbotthepony.kommons.util.getValue -import ru.dbotthepony.kommons.util.setValue -import ru.dbotthepony.mc.otm.NULLABLE_MINECRAFT_SERVER -import ru.dbotthepony.mc.otm.OverdriveThatMatters -import java.util.concurrent.CompletableFuture -import java.util.concurrent.ConcurrentLinkedQueue -import java.util.concurrent.locks.LockSupport -import java.util.function.BiConsumer -import java.util.function.Function -import kotlin.reflect.KClass - -class MNetworkContext(val sender: ServerPlayer?, packetHandled: Delegate, private val enqueuer: (Runnable) -> CompletableFuture<*>) { - var packetHandled by packetHandled - - fun enqueueWork(callback: Runnable): CompletableFuture<*> { - return enqueuer(callback) - } -} - -interface MatteryPacket { - fun write(buff: FriendlyByteBuf) - fun play(context: MNetworkContext) -} - -abstract class MatteryNetworkChannel(val version: Int, val name: String) { - val channel: SimpleChannel = ChannelBuilder - .named(ResourceLocation(OverdriveThatMatters.MOD_ID, name)) - .clientAcceptedVersions { status, version -> (status == Channel.VersionTest.Status.MISSING || status == Channel.VersionTest.Status.VANILLA) || version == this.version } - .serverAcceptedVersions { status, version -> status == Channel.VersionTest.Status.PRESENT || version == this.version } - .networkProtocolVersion(version) - .simpleChannel() - - fun sendToServer(packet: Any) = channel.send(packet, PacketDistributor.SERVER.noArg()) - - fun send(ply: Player, packet: Any) { - if (ply is ServerPlayer) { - channel.send(packet, PacketDistributor.PLAYER.with(ply)) - } - } - - fun sendTracking(entity: Entity, packet: Any) { - if ((NULLABLE_MINECRAFT_SERVER?.playerCount ?: 0) <= 0) { - return - } - - channel.send(packet, PacketDistributor.TRACKING_ENTITY.with(entity)) - } - - fun sendTrackingAndSelf(entity: Entity, packet: Any) { - if ((NULLABLE_MINECRAFT_SERVER?.playerCount ?: 0) <= 0) { - return - } - - channel.send(packet, PacketDistributor.TRACKING_ENTITY_AND_SELF.with(entity)) - } - - fun send(distributor: PacketDistributor.PacketTarget, packet: Any) { - channel.send(packet, distributor) - } - - private var nextNetworkPacketID = 0 - - fun add( - packetClass: Class, - writer: BiConsumer, - reader: Function, - handler: (T, MNetworkContext) -> Unit, - direction: NetworkDirection? = null, - handleOnMainThread: Boolean = true, - ) { - if (nextNetworkPacketID >= 256) { - throw IndexOutOfBoundsException("Network message ID overflow!") - } - - val builder = channel.messageBuilder(packetClass, direction) - val bridgeHandler = BiConsumer { a, b -> handler(a, MNetworkContext(b.sender, Delegate.Of({ b.packetHandled }, { b.packetHandled = it }), b::enqueueWork)) } - - if (handleOnMainThread) { - builder.consumerMainThread(bridgeHandler) - } else { - builder.consumerNetworkThread(bridgeHandler) - } - - builder.encoder(writer) - builder.decoder(reader) - builder.add() - } - - fun add( - packetClass: Class, - reader: Function, - direction: NetworkDirection? = null, - handleOnMainThread: Boolean = true, - ) { - add(packetClass, MatteryPacket::write, reader, MatteryPacket::play, direction, handleOnMainThread) - } - - fun add( - packetClass: KClass, - reader: Function, - direction: NetworkDirection? = null, - handleOnMainThread: Boolean = true, - ) { - add(packetClass.java, MatteryPacket::write, reader, MatteryPacket::play, direction, handleOnMainThread) - } -} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/network/MatteryPlayerNetworkChannel.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/network/MatteryPlayerNetworkChannel.kt deleted file mode 100644 index 42b9e281f..000000000 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/network/MatteryPlayerNetworkChannel.kt +++ /dev/null @@ -1,600 +0,0 @@ -package ru.dbotthepony.mc.otm.network - -import it.unimi.dsi.fastutil.io.FastByteArrayOutputStream -import net.minecraft.core.particles.ParticleTypes -import net.minecraft.network.FriendlyByteBuf -import net.minecraft.network.chat.Component -import net.minecraft.network.protocol.game.ClientboundSetCarriedItemPacket -import net.minecraft.resources.ResourceLocation -import net.minecraft.world.entity.player.Inventory -import net.minecraft.world.item.ItemStack -import net.minecraftforge.network.NetworkDirection.PLAY_TO_CLIENT -import net.minecraftforge.network.NetworkDirection.PLAY_TO_SERVER -import org.apache.logging.log4j.LogManager -import ru.dbotthepony.mc.otm.android.AndroidActiveFeature -import ru.dbotthepony.mc.otm.android.AndroidFeatureType -import ru.dbotthepony.mc.otm.android.AndroidResearchManager -import ru.dbotthepony.mc.otm.android.AndroidResearchType -import ru.dbotthepony.mc.otm.android.AndroidSwitchableFeature -import ru.dbotthepony.mc.otm.android.feature.TriggerJumpBoostPacket -import ru.dbotthepony.mc.otm.android.feature.TriggerShockwavePacket -import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability -import ru.dbotthepony.mc.otm.capability.matteryPlayer -import ru.dbotthepony.mc.otm.client.MatteryGUI -import ru.dbotthepony.mc.otm.client.minecraft -import ru.dbotthepony.mc.otm.client.render.GlitchRenderer -import ru.dbotthepony.mc.otm.client.render.ShockwaveRenderer -import ru.dbotthepony.mc.otm.container.get -import ru.dbotthepony.mc.otm.container.set -import ru.dbotthepony.kommons.math.RGBAColor -import ru.dbotthepony.mc.otm.core.math.Vector -import ru.dbotthepony.mc.otm.core.math.component1 -import ru.dbotthepony.mc.otm.core.math.component2 -import ru.dbotthepony.mc.otm.core.math.component3 -import ru.dbotthepony.mc.otm.core.math.toRadians -import ru.dbotthepony.mc.otm.core.position -import ru.dbotthepony.mc.otm.menu.tech.AndroidStationMenu -import ru.dbotthepony.mc.otm.menu.ExopackInventoryMenu -import ru.dbotthepony.mc.otm.registry.AndroidFeatures -import ru.dbotthepony.mc.otm.registry.MRegistry -import java.io.ByteArrayInputStream -import java.util.UUID - -class MatteryPlayerFieldPacket(val bytes: ByteArray, val length: Int, val isPublic: Boolean, val target: UUID? = null) : MatteryPacket { - constructor(stream: FastByteArrayOutputStream, isPublic: Boolean, target: UUID? = null) : this(stream.array, stream.length, isPublic, target) - - override fun write(buff: FriendlyByteBuf) { - buff.writeBoolean(target != null) - - if (target != null) - buff.writeUUID(target) - - buff.writeBoolean(isPublic) - buff.writeBytes(bytes, 0, length) - } - - override fun play(context: MNetworkContext) { - val player: MatteryPlayerCapability - - if (target != null) { - player = minecraft.level?.players()?.firstOrNull { it.uuid == target }?.matteryPlayer ?: return - } else { - player = minecraft.player?.matteryPlayer ?: return - } - - if (isPublic) { - player.publicSyncher.read(ByteArrayInputStream(bytes, 0, length)) - } else { - player.syncher.read(ByteArrayInputStream(bytes, 0, length)) - } - } - - companion object { - fun read(buff: FriendlyByteBuf): MatteryPlayerFieldPacket { - val target = if (buff.readBoolean()) - buff.readUUID() - else - null - - val isPublic = buff.readBoolean() - val readable = buff.readableBytes() - return MatteryPlayerFieldPacket(ByteArray(readable).also(buff::readBytes), readable, isPublic, target) - } - } -} - -class AndroidResearchRequestPacket(val type: AndroidResearchType) : MatteryPacket { - override fun write(buff: FriendlyByteBuf) { - buff.writeUtf(type.id.toString()) - } - - override fun play(context: MNetworkContext) { - val ply = context.sender ?: return - if (ply.isSpectator) return - val android = ply.matteryPlayer ?: return - - if (!android.isAndroid || ply.containerMenu !is AndroidStationMenu) - return - - android.getResearch(type).research() - } - - companion object { - fun read(buff: FriendlyByteBuf): AndroidResearchRequestPacket { - return AndroidResearchRequestPacket(AndroidResearchManager[ResourceLocation(buff.readUtf())] ?: throw NoSuchElementException()) - } - } -} - -class AndroidResearchSyncPacket(val type: AndroidResearchType, val dataList: FastByteArrayOutputStream?, val dataBytes: ByteArray?) : MatteryPacket { - override fun write(buff: FriendlyByteBuf) { - dataList ?: throw NullPointerException("No byte list is present") - buff.writeUtf(type.id.toString()) - buff.writeBytes(dataList.array, 0, dataList.length) - } - - override fun play(context: MNetworkContext) { - dataBytes ?: throw NullPointerException("No data bytes array is present") - val android = minecraft.player?.matteryPlayer ?: return - android.getResearch(type).applyNetworkPayload(ByteArrayInputStream(dataBytes)) - } - - companion object { - fun read(buff: FriendlyByteBuf): AndroidResearchSyncPacket { - return AndroidResearchSyncPacket( - AndroidResearchManager[ResourceLocation(buff.readUtf())] ?: throw NoSuchElementException(), - null, ByteArray(buff.readableBytes()).also { buff.readBytes(it) } - ) - } - } -} - -class AndroidFeatureSyncPacket(val type: AndroidFeatureType<*>, val dataList: FastByteArrayOutputStream?, val dataBytes: ByteArray?) : MatteryPacket { - override fun write(buff: FriendlyByteBuf) { - dataList ?: throw NullPointerException("No byte list is present") - buff.writeInt(MRegistry.ANDROID_FEATURES.getID(type)) - buff.writeBytes(dataList.array, 0, dataList.length) - } - - override fun play(context: MNetworkContext) { - dataBytes ?: throw NullPointerException("No data bytes array is present") - val android = minecraft.player?.matteryPlayer ?: return - android.computeIfAbsent(type).applyNetworkPayload(ByteArrayInputStream(dataBytes)) - } - - companion object { - fun read(buff: FriendlyByteBuf): AndroidFeatureSyncPacket { - return AndroidFeatureSyncPacket( - MRegistry.ANDROID_FEATURES.getValue(buff.readInt()), - null, ByteArray(buff.readableBytes()).also { buff.readBytes(it) } - ) - } - } -} - -class AndroidFeatureRemovePacket(val type: AndroidFeatureType<*>) : MatteryPacket { - override fun write(buff: FriendlyByteBuf) { - buff.writeInt(MRegistry.ANDROID_FEATURES.getID(type)) - } - - override fun play(context: MNetworkContext) { - val android = minecraft.player?.matteryPlayer ?: return - android.removeFeature(type) - } - - companion object { - fun read(buff: FriendlyByteBuf): AndroidFeatureRemovePacket { - return AndroidFeatureRemovePacket(MRegistry.ANDROID_FEATURES.getValue(buff.readInt())) - } - } -} - -class PlayerIterationPacket(val iteration: Int, val deathLog: List>) : MatteryPacket { - override fun write(buff: FriendlyByteBuf) { - buff.writeInt(iteration) - buff.writeInt(deathLog.size) - - for ((ticks, value) in deathLog) { - buff.writeInt(ticks) - buff.writeComponent(value) - } - } - - override fun play(context: MNetworkContext) { - context.packetHandled = true - - MatteryGUI.iteration = iteration - MatteryGUI.deathLog.clear() - MatteryGUI.deathLog.addAll(deathLog) - MatteryGUI.showIterationUntil = System.currentTimeMillis() + 4000L - MatteryGUI.showIterationUntilFade = System.currentTimeMillis() + 5000L - } - - companion object { - fun read(buff: FriendlyByteBuf): PlayerIterationPacket { - val iteration = buff.readInt() - val size = buff.readInt() - - val list = ArrayList>() - - for (i in 0 until size) { - list.add(buff.readInt() to buff.readComponent()) - } - - return PlayerIterationPacket(iteration, list) - } - } -} - -class ExopackCarriedPacket(val itemStack: ItemStack, val containerState: Int) : MatteryPacket { - override fun write(buff: FriendlyByteBuf) { - buff.writeItem(itemStack) - buff.writeInt(containerState) - } - - override fun play(context: MNetworkContext) { - val mattery = minecraft.player?.matteryPlayer ?: return - - if (mattery.hasExopack) { - mattery.exoPackMenu.carried = itemStack - mattery.exoPackMenu.stateId = containerState - } - } - - companion object { - fun read(buff: FriendlyByteBuf): ExopackCarriedPacket { - return ExopackCarriedPacket(buff.readItem(), buff.readInt()) - } - } -} - -class ExopackSlotPacket(val slotId: Int, val itemStack: ItemStack, val containerState: Int) : MatteryPacket { - override fun write(buff: FriendlyByteBuf) { - buff.writeInt(slotId) - buff.writeItem(itemStack) - buff.writeInt(containerState) - } - - override fun play(context: MNetworkContext) { - if (slotId < 0) { - LOGGER.error("Unknown slot with ID {} in exosuit menu", slotId) - return - } - - val mattery = minecraft.player?.matteryPlayer ?: return - - if (mattery.hasExopack) { - if (slotId >= mattery.exoPackMenu.slots.size) { - LOGGER.error("Unknown slot with ID {} in exosuit menu", slotId) - return - } - - // don't duplicate data - // really. - if (mattery.exoPackMenu.slots[slotId].container == minecraft.player?.inventory && minecraft.player?.containerMenu !is ExopackInventoryMenu) - return - - mattery.exoPackMenu.slots[slotId].set(itemStack) - mattery.exoPackMenu.stateId = containerState - } - } - - companion object { - private val LOGGER = LogManager.getLogger() - - fun read(buff: FriendlyByteBuf): ExopackSlotPacket { - return ExopackSlotPacket(buff.readInt(), buff.readItem(), buff.readInt()) - } - } -} - -class ExopackMenuInitPacket(val slots: List, val carried: ItemStack, val containerState: Int) : MatteryPacket { - override fun write(buff: FriendlyByteBuf) { - buff.writeInt(slots.size) - - for (item in slots) { - buff.writeItem(item) - } - - buff.writeItem(carried) - buff.writeInt(containerState) - } - - override fun play(context: MNetworkContext) { - val mattery = minecraft.player?.matteryPlayer ?: return - - if (mattery.hasExopack) { - mattery.exoPackMenu.initializeContents(containerState, slots, carried) - } - } - - companion object { - fun read(buff: FriendlyByteBuf): ExopackMenuInitPacket { - val size = buff.readInt() - val slots = ArrayList(size) - - for (i in 0 until size) { - slots.add(buff.readItem()) - } - - val carried = buff.readItem() - val containerState = buff.readInt() - - return ExopackMenuInitPacket(slots, carried, containerState) - } - } -} - -object ExopackMenuOpen : MatteryPacket { - override fun write(buff: FriendlyByteBuf) {} - - override fun play(context: MNetworkContext) { - val player = context.sender ?: return - val mattery = player.matteryPlayer ?: return - - if (mattery.hasExopack) { - player.containerMenu = mattery.exoPackMenu - } - } -} - -class SwitchAndroidFeaturePacket(val type: AndroidFeatureType<*>, val newState: Boolean) : MatteryPacket { - override fun write(buff: FriendlyByteBuf) { - buff.writeInt(MRegistry.ANDROID_FEATURES.getID(type)) - buff.writeBoolean(newState) - } - - override fun play(context: MNetworkContext) { - val matteryPlayer = context.sender?.matteryPlayer ?: return - - if (!matteryPlayer.isAndroid) { - return - } - - val feature = matteryPlayer.getFeature(type) ?: return - - if (feature is AndroidActiveFeature && feature.allowToSwitchByPlayer && (!matteryPlayer.ply.isSpectator || feature.allowToSwitchByPlayerWhileSpectator)) { - matteryPlayer.features - .map { it as? AndroidActiveFeature } - .filter { it != null } - .filter { it !== feature && it!!.allowToSwitchByPlayer && (!matteryPlayer.ply.isSpectator || it.allowToSwitchByPlayerWhileSpectator) } - .forEach { it!!.isActive = false } - feature.isActive = newState - } else if (feature is AndroidSwitchableFeature && feature.allowToSwitchByPlayer && (!matteryPlayer.ply.isSpectator || feature.allowToSwitchByPlayerWhileSpectator)) { - feature.isActive = newState - } - } - - companion object { - fun read(buff: FriendlyByteBuf): SwitchAndroidFeaturePacket { - return SwitchAndroidFeaturePacket(MRegistry.ANDROID_FEATURES.getValue(buff.readInt()) ?: AndroidFeatures.AIR_BAGS, buff.readBoolean()) - } - } -} - -class ActivateAndroidFeaturePacket(val type: AndroidFeatureType<*>) : MatteryPacket { - override fun write(buff: FriendlyByteBuf) { - buff.writeInt(MRegistry.ANDROID_FEATURES.getID(type)) - } - - override fun play(context: MNetworkContext) { - val matteryPlayer = context.sender?.matteryPlayer ?: return - - if (!matteryPlayer.isAndroid || matteryPlayer.ply.isSpectator) { - return - } - - val feature = matteryPlayer.getFeature(type) as? AndroidActiveFeature ?: return - - if (feature.isActive || feature.allowToSwitchByPlayer) { - feature.activate(false) - } - } - - companion object { - fun read(buff: FriendlyByteBuf): ActivateAndroidFeaturePacket { - return ActivateAndroidFeaturePacket(MRegistry.ANDROID_FEATURES.getValue(buff.readInt()) ?: AndroidFeatures.AIR_BAGS) - } - } -} - -class PickItemFromInventoryPacket( - val targetHotbarSlot: Int, - val sourceExosuitSlot: Int -) : MatteryPacket { - override fun write(buff: FriendlyByteBuf) { - buff.writeVarInt(targetHotbarSlot) - buff.writeVarInt(sourceExosuitSlot) - } - - override fun play(context: MNetworkContext) { - val player = context.sender ?: return - val mattery = player.matteryPlayer ?: return - - if (!mattery.hasExopack || sourceExosuitSlot !in 0 until mattery.exopackContainer.containerSize) { - return - } - - if (!Inventory.isHotbarSlot(targetHotbarSlot)) { - return - } - - player.inventory.selected = targetHotbarSlot - val existingItem = player.inventory[targetHotbarSlot].copy() - val inventoryItem = mattery.exopackContainer[sourceExosuitSlot].copy() - - player.inventory[targetHotbarSlot] = if (inventoryItem.isEmpty) ItemStack.EMPTY else inventoryItem - mattery.exopackContainer[sourceExosuitSlot] = if (existingItem.isEmpty) ItemStack.EMPTY else existingItem - - player.connection.send(ClientboundSetCarriedItemPacket(targetHotbarSlot)) - } - - companion object { - fun read(buff: FriendlyByteBuf): PickItemFromInventoryPacket { - return PickItemFromInventoryPacket(buff.readVarInt(), buff.readVarInt()) - } - } -} - -class GlitchPacket(val millis: Long) : MatteryPacket { - override fun write(buff: FriendlyByteBuf) { - buff.writeVarLong(millis) - } - - override fun play(context: MNetworkContext) { - context.packetHandled = true - GlitchRenderer.glitchFor(millis) - } - - companion object { - fun read(buff: FriendlyByteBuf): GlitchPacket { - return GlitchPacket(buff.readVarLong()) - } - } -} - -class ShockwaveEffectPacket(val pos: Vector) : MatteryPacket { - override fun write(buff: FriendlyByteBuf) { - buff.writeDouble(pos.x) - buff.writeDouble(pos.y) - buff.writeDouble(pos.z) - } - - override fun play(context: MNetworkContext) { - context.packetHandled = true - ShockwaveRenderer.handle(this) - } - - companion object { - fun read(buff: FriendlyByteBuf): ShockwaveEffectPacket { - return ShockwaveEffectPacket(Vector(buff.readDouble(), buff.readDouble(), buff.readDouble())) - } - } -} - -object DisplayExopackPacket : MatteryPacket { - override fun write(buff: FriendlyByteBuf) {} - - override fun play(context: MNetworkContext) { - context.packetHandled = true - context.sender?.matteryPlayer?.isExopackVisible = true - } -} - -object HideExopackPacket : MatteryPacket { - override fun write(buff: FriendlyByteBuf) {} - - override fun play(context: MNetworkContext) { - context.packetHandled = true - context.sender?.matteryPlayer?.isExopackVisible = false - } -} - -object EnableExopackGlowPacket : MatteryPacket { - override fun write(buff: FriendlyByteBuf) {} - - override fun play(context: MNetworkContext) { - context.packetHandled = true - context.sender?.matteryPlayer?.exopackGlows = true - } -} - -object DisableExopackGlowPacket : MatteryPacket { - override fun write(buff: FriendlyByteBuf) {} - - override fun play(context: MNetworkContext) { - context.packetHandled = true - context.sender?.matteryPlayer?.exopackGlows = false - } -} - -object ResetExopackColorPacket : MatteryPacket { - override fun write(buff: FriendlyByteBuf) {} - - override fun play(context: MNetworkContext) { - context.packetHandled = true - context.sender?.matteryPlayer?.exopackColor = null - } -} - -data class SetExopackColorPacket(val color: RGBAColor) : MatteryPacket { - override fun write(buff: FriendlyByteBuf) { - buff.writeFloat(color.red) - buff.writeFloat(color.green) - buff.writeFloat(color.blue) - } - - override fun play(context: MNetworkContext) { - context.packetHandled = true - context.sender?.matteryPlayer?.exopackColor = color - } - - companion object { - fun read(buff: FriendlyByteBuf): SetExopackColorPacket { - return SetExopackColorPacket(RGBAColor(buff.readFloat(), buff.readFloat(), buff.readFloat())) - } - } -} - -data class ExopackSmokePacket(val player: UUID) : MatteryPacket { - override fun write(buff: FriendlyByteBuf) { - buff.writeUUID(player) - } - - override fun play(context: MNetworkContext) { - context.packetHandled = true - // minecraft.player?.level()?.getPlayerByUUID(player)?.matteryPlayer?.spawnExopackSmoke = true - - minecraft.player?.level()?.getPlayerByUUID(player)?.let { ply -> - if (ply != minecraft.player || minecraft.gameRenderer.mainCamera.isDetached) { - var (x, y, z) = ply.position - - y += 1.5 - val deg = toRadians(ply.yBodyRot + 90f) - - x += kotlin.math.cos(deg) * -0.4 - z += kotlin.math.sin(deg) * -0.4 - - val level = ply.level() - val random = level.random - - for (i in 0 .. random.nextInt(2, 4)) - level.addParticle( - ParticleTypes.SMOKE, - x + random.nextDouble() * 0.4 - 0.2, - y + random.nextDouble() * 0.4 - 0.2, - z + random.nextDouble() * 0.4 - 0.2, - random.nextGaussian() * 0.02, - random.nextGaussian() * 0.02, - random.nextGaussian() * 0.02) - } - } - } - - companion object { - fun read(buff: FriendlyByteBuf): ExopackSmokePacket { - return ExopackSmokePacket(buff.readUUID()) - } - } -} - -object MatteryPlayerNetworkChannel : MatteryNetworkChannel( - version = 7, - name = "player" -) { - fun register() { - add(MatteryPlayerFieldPacket::class, MatteryPlayerFieldPacket.Companion::read, PLAY_TO_CLIENT) - - add(AndroidResearchRequestPacket::class, AndroidResearchRequestPacket.Companion::read, PLAY_TO_SERVER) - add(AndroidResearchSyncPacket::class, AndroidResearchSyncPacket.Companion::read, PLAY_TO_CLIENT) - add(AndroidFeatureSyncPacket::class, AndroidFeatureSyncPacket.Companion::read, PLAY_TO_CLIENT) - add(AndroidFeatureRemovePacket::class, AndroidFeatureRemovePacket.Companion::read, PLAY_TO_CLIENT) - - add(PlayerIterationPacket::class, PlayerIterationPacket.Companion::read, PLAY_TO_CLIENT) - - add(ExopackCarriedPacket::class, ExopackCarriedPacket.Companion::read, PLAY_TO_CLIENT) - add(ExopackSlotPacket::class, ExopackSlotPacket.Companion::read, PLAY_TO_CLIENT) - add(ExopackMenuInitPacket::class, ExopackMenuInitPacket.Companion::read, PLAY_TO_CLIENT) - add(ExopackSmokePacket::class, ExopackSmokePacket.Companion::read, PLAY_TO_CLIENT) - - add(ExopackMenuOpen::class, { ExopackMenuOpen }, PLAY_TO_SERVER) - - add(SwitchAndroidFeaturePacket::class, SwitchAndroidFeaturePacket.Companion::read, PLAY_TO_SERVER) - add(ActivateAndroidFeaturePacket::class, ActivateAndroidFeaturePacket.Companion::read, PLAY_TO_SERVER) - - add(TriggerShockwavePacket::class, { TriggerShockwavePacket }, PLAY_TO_SERVER) - add(TriggerJumpBoostPacket::class, { TriggerJumpBoostPacket }, PLAY_TO_SERVER) - - add(PickItemFromInventoryPacket::class, PickItemFromInventoryPacket.Companion::read, PLAY_TO_SERVER) - - add(GlitchPacket::class, GlitchPacket.Companion::read, PLAY_TO_CLIENT) - add(ShockwaveEffectPacket::class, ShockwaveEffectPacket.Companion::read, PLAY_TO_CLIENT) - - add(DisplayExopackPacket::class, { DisplayExopackPacket }, PLAY_TO_SERVER) - add(HideExopackPacket::class, { HideExopackPacket }, PLAY_TO_SERVER) - add(EnableExopackGlowPacket::class, { EnableExopackGlowPacket }, PLAY_TO_SERVER) - add(DisableExopackGlowPacket::class, { DisableExopackGlowPacket }, PLAY_TO_SERVER) - add(ResetExopackColorPacket::class, { ResetExopackColorPacket }, PLAY_TO_SERVER) - add(SetExopackColorPacket::class, SetExopackColorPacket.Companion::read, PLAY_TO_SERVER) - } -} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/network/MatteryPlayerPackets.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/network/MatteryPlayerPackets.kt new file mode 100644 index 000000000..77c5b6d85 --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/network/MatteryPlayerPackets.kt @@ -0,0 +1,484 @@ +package ru.dbotthepony.mc.otm.network + +import it.unimi.dsi.fastutil.io.FastByteArrayOutputStream +import net.minecraft.core.particles.ParticleTypes +import net.minecraft.network.FriendlyByteBuf +import net.minecraft.network.RegistryFriendlyByteBuf +import net.minecraft.network.codec.StreamCodec +import net.minecraft.network.protocol.common.custom.CustomPacketPayload +import net.minecraft.network.protocol.game.ClientboundSetCarriedItemPacket +import net.minecraft.server.level.ServerPlayer +import net.minecraft.world.entity.player.Inventory +import net.minecraft.world.item.ItemStack +import net.neoforged.neoforge.network.handling.IPayloadContext +import org.apache.logging.log4j.LogManager +import ru.dbotthepony.kommons.math.RGBAColor +import ru.dbotthepony.mc.otm.OverdriveThatMatters +import ru.dbotthepony.mc.otm.capability.MatteryPlayer +import ru.dbotthepony.mc.otm.capability.matteryPlayer +import ru.dbotthepony.mc.otm.client.minecraft +import ru.dbotthepony.mc.otm.container.get +import ru.dbotthepony.mc.otm.container.set +import ru.dbotthepony.mc.otm.core.ResourceLocation +import ru.dbotthepony.mc.otm.core.math.component1 +import ru.dbotthepony.mc.otm.core.math.component2 +import ru.dbotthepony.mc.otm.core.math.component3 +import ru.dbotthepony.mc.otm.core.math.toRadians +import ru.dbotthepony.mc.otm.core.position +import ru.dbotthepony.mc.otm.core.readItem +import ru.dbotthepony.mc.otm.core.writeItem +import ru.dbotthepony.mc.otm.menu.ExopackInventoryMenu +import java.io.ByteArrayInputStream +import java.util.* + + +class MatteryPlayerDataPacket(val bytes: ByteArray, val length: Int, val isPublic: Boolean, val target: UUID? = null) : + CustomPacketPayload { + constructor(stream: FastByteArrayOutputStream, isPublic: Boolean, target: UUID? = null) : this(stream.array, stream.length, isPublic, target) + + fun write(buff: FriendlyByteBuf) { + buff.writeBoolean(target != null) + + if (target != null) + buff.writeUUID(target) + + buff.writeBoolean(isPublic) + buff.writeBytes(bytes, 0, length) + } + + fun play(context: IPayloadContext) { + val player: MatteryPlayer + + if (target != null) { + player = minecraft.level?.players()?.firstOrNull { it.uuid == target }?.matteryPlayer ?: return + } else { + player = minecraft.player?.matteryPlayer ?: return + } + + if (isPublic) { + player.publicSyncher.read(ByteArrayInputStream(bytes, 0, length)) + } else { + player.syncher.read(ByteArrayInputStream(bytes, 0, length)) + } + } + + override fun type(): CustomPacketPayload.Type { + return TYPE + } + + companion object { + val TYPE = CustomPacketPayload.Type( + ResourceLocation( + OverdriveThatMatters.MOD_ID, + "player_data" + ) + ) + val CODEC: StreamCodec = + StreamCodec.ofMember(MatteryPlayerDataPacket::write, ::read) + + fun read(buff: FriendlyByteBuf): MatteryPlayerDataPacket { + val target = if (buff.readBoolean()) + buff.readUUID() + else + null + + val isPublic = buff.readBoolean() + val readable = buff.readableBytes() + return MatteryPlayerDataPacket(ByteArray(readable).also(buff::readBytes), readable, isPublic, target) + } + } +} + +class ExopackCarriedPacket(val itemStack: ItemStack, val containerState: Int) : CustomPacketPayload { + fun write(buff: RegistryFriendlyByteBuf) { + buff.writeItem(itemStack) + buff.writeInt(containerState) + } + + fun play(context: IPayloadContext) { + val mattery = minecraft.player?.matteryPlayer ?: return + + if (mattery.hasExopack) { + mattery.exoPackMenu.carried = itemStack + mattery.exoPackMenu.stateId = containerState + } + } + + override fun type(): CustomPacketPayload.Type { + return TYPE + } + + companion object { + val TYPE = CustomPacketPayload.Type( + ResourceLocation( + OverdriveThatMatters.MOD_ID, + "exopack_carried" + ) + ) + val CODEC: StreamCodec = + StreamCodec.ofMember(ExopackCarriedPacket::write, ::read) + + fun read(buff: RegistryFriendlyByteBuf): ExopackCarriedPacket { + return ExopackCarriedPacket(buff.readItem(), buff.readInt()) + } + } +} + +class ExopackSlotPacket(val slotId: Int, val itemStack: ItemStack, val containerState: Int) : CustomPacketPayload { + fun write(buff: RegistryFriendlyByteBuf) { + buff.writeInt(slotId) + buff.writeItem(itemStack) + buff.writeInt(containerState) + } + + fun play(context: IPayloadContext) { + if (slotId < 0) { + LOGGER.error("Unknown slot with ID {} in exosuit menu", slotId) + return + } + + val mattery = minecraft.player?.matteryPlayer ?: return + + if (mattery.hasExopack) { + if (slotId >= mattery.exoPackMenu.slots.size) { + LOGGER.error("Unknown slot with ID {} in exosuit menu", slotId) + return + } + + // don't duplicate data + // really. + if (mattery.exoPackMenu.slots[slotId].container == minecraft.player?.inventory && minecraft.player?.containerMenu !is ExopackInventoryMenu) + return + + mattery.exoPackMenu.slots[slotId].set(itemStack) + mattery.exoPackMenu.stateId = containerState + } + } + + override fun type(): CustomPacketPayload.Type { + return TYPE + } + + companion object { + private val LOGGER = LogManager.getLogger() + + val TYPE = CustomPacketPayload.Type( + ResourceLocation( + OverdriveThatMatters.MOD_ID, + "exopack_slot" + ) + ) + val CODEC: StreamCodec = + StreamCodec.ofMember(ExopackSlotPacket::write, ::read) + + fun read(buff: RegistryFriendlyByteBuf): ExopackSlotPacket { + return ExopackSlotPacket(buff.readInt(), buff.readItem(), buff.readInt()) + } + } +} + +class ExopackMenuInitPacket(val slots: List, val carried: ItemStack, val containerState: Int) : CustomPacketPayload { + fun write(buff: RegistryFriendlyByteBuf) { + buff.writeInt(slots.size) + + for (item in slots) { + buff.writeItem(item) + } + + buff.writeItem(carried) + buff.writeInt(containerState) + } + + fun play(context: IPayloadContext) { + val mattery = minecraft.player?.matteryPlayer ?: return + + if (mattery.hasExopack) { + mattery.exoPackMenu.initializeContents(containerState, slots, carried) + } + } + + override fun type(): CustomPacketPayload.Type { + return TYPE + } + + companion object { + val TYPE = CustomPacketPayload.Type( + ResourceLocation( + OverdriveThatMatters.MOD_ID, + "exopack_menu_init" + ) + ) + val CODEC: StreamCodec = + StreamCodec.ofMember(ExopackMenuInitPacket::write, ::read) + + fun read(buff: RegistryFriendlyByteBuf): ExopackMenuInitPacket { + val size = buff.readInt() + val slots = ArrayList(size) + + for (i in 0 until size) { + slots.add(buff.readItem()) + } + + val carried = buff.readItem() + val containerState = buff.readInt() + + return ExopackMenuInitPacket(slots, carried, containerState) + } + } +} + +object ExopackMenuOpen : CustomPacketPayload { + fun play(context: IPayloadContext) { + val player = context.player() + val mattery = player.matteryPlayer + + if (mattery.hasExopack) { + player.containerMenu = mattery.exoPackMenu + } + } + + override fun type(): CustomPacketPayload.Type { + return TYPE + } + + val TYPE = CustomPacketPayload.Type( + ResourceLocation( + OverdriveThatMatters.MOD_ID, + "exopack_menu_open" + ) + ) + + val CODEC: StreamCodec = + StreamCodec.ofMember({ _, _ -> }, { ExopackMenuOpen }) +} + +class PickItemFromInventoryPacket( + val targetHotbarSlot: Int, + val sourceExosuitSlot: Int +) : CustomPacketPayload { + fun write(buff: FriendlyByteBuf) { + buff.writeVarInt(targetHotbarSlot) + buff.writeVarInt(sourceExosuitSlot) + } + + fun play(context: IPayloadContext) { + val player = context.player() as ServerPlayer + val mattery = player.matteryPlayer + + if (!mattery.hasExopack || sourceExosuitSlot !in 0 until mattery.exopackContainer.containerSize) { + return + } + + if (!Inventory.isHotbarSlot(targetHotbarSlot)) { + return + } + + player.inventory.selected = targetHotbarSlot + val existingItem = player.inventory[targetHotbarSlot].copy() + val inventoryItem = mattery.exopackContainer[sourceExosuitSlot].copy() + + player.inventory[targetHotbarSlot] = if (inventoryItem.isEmpty) ItemStack.EMPTY else inventoryItem + mattery.exopackContainer[sourceExosuitSlot] = if (existingItem.isEmpty) ItemStack.EMPTY else existingItem + + player.connection.send(ClientboundSetCarriedItemPacket(targetHotbarSlot)) + } + + override fun type(): CustomPacketPayload.Type { + return TYPE + } + + companion object { + val TYPE = CustomPacketPayload.Type( + ResourceLocation( + OverdriveThatMatters.MOD_ID, + "pick_item_from_inventory" + ) + ) + val CODEC: StreamCodec = + StreamCodec.ofMember(PickItemFromInventoryPacket::write, ::read) + + fun read(buff: FriendlyByteBuf): PickItemFromInventoryPacket { + return PickItemFromInventoryPacket(buff.readVarInt(), buff.readVarInt()) + } + } +} + +class SetExopackColorPacket(val color: RGBAColor) : CustomPacketPayload { + fun write(buff: FriendlyByteBuf) { + buff.writeFloat(color.red) + buff.writeFloat(color.green) + buff.writeFloat(color.blue) + } + + fun play(context: IPayloadContext) { + context.player().matteryPlayer.exopackColor = color + } + + override fun type(): CustomPacketPayload.Type { + return TYPE + } + + companion object { + val TYPE = CustomPacketPayload.Type( + ResourceLocation( + OverdriveThatMatters.MOD_ID, + "set_exopack_color" + ) + ) + val CODEC: StreamCodec = + StreamCodec.ofMember(SetExopackColorPacket::write, ::read) + + fun read(buff: FriendlyByteBuf): SetExopackColorPacket { + return SetExopackColorPacket(RGBAColor(buff.readFloat(), buff.readFloat(), buff.readFloat())) + } + } +} + +object DisplayExopackPacket : CustomPacketPayload { + fun play(context: IPayloadContext) { + context.player().matteryPlayer.isExopackVisible = true + } + + override fun type(): CustomPacketPayload.Type { + return TYPE + } + + val TYPE = CustomPacketPayload.Type( + ResourceLocation( + OverdriveThatMatters.MOD_ID, + "display_exopack" + ) + ) + val CODEC: StreamCodec = + StreamCodec.ofMember({ _, _ -> }, { DisplayExopackPacket }) +} + +object HideExopackPacket : CustomPacketPayload { + fun play(context: IPayloadContext) { + context.player().matteryPlayer.isExopackVisible = false + } + + override fun type(): CustomPacketPayload.Type { + return TYPE + } + + val TYPE = CustomPacketPayload.Type( + ResourceLocation( + OverdriveThatMatters.MOD_ID, + "hide_exopack" + ) + ) + val CODEC: StreamCodec = + StreamCodec.ofMember({ _, _ -> }, { HideExopackPacket }) +} + +object EnableExopackGlowPacket : CustomPacketPayload { + fun play(context: IPayloadContext) { + context.player().matteryPlayer.exopackGlows = true + } + + override fun type(): CustomPacketPayload.Type { + return TYPE + } + + val TYPE = CustomPacketPayload.Type( + ResourceLocation( + OverdriveThatMatters.MOD_ID, + "enable_exopack_glow" + ) + ) + val CODEC: StreamCodec = + StreamCodec.ofMember({ _, _ -> }, { EnableExopackGlowPacket }) +} + +object DisableExopackGlowPacket : CustomPacketPayload { + fun play(context: IPayloadContext) { + context.player().matteryPlayer.exopackGlows = false + } + + override fun type(): CustomPacketPayload.Type { + return TYPE + } + + val TYPE = CustomPacketPayload.Type( + ResourceLocation( + OverdriveThatMatters.MOD_ID, + "disable_exopack_glow" + ) + ) + val CODEC: StreamCodec = + StreamCodec.ofMember({ _, _ -> }, { DisableExopackGlowPacket }) +} + +object ResetExopackColorPacket : CustomPacketPayload { + fun play(context: IPayloadContext) { + context.player().matteryPlayer.exopackColor = null + } + + override fun type(): CustomPacketPayload.Type { + return TYPE + } + + val TYPE = CustomPacketPayload.Type( + ResourceLocation( + OverdriveThatMatters.MOD_ID, + "reset_exopack_color" + ) + ) + val CODEC: StreamCodec = + StreamCodec.ofMember({ _, _ -> }, { ResetExopackColorPacket }) +} + +class ExopackSmokePacket(val player: UUID) : CustomPacketPayload { + fun write(buff: FriendlyByteBuf) { + buff.writeUUID(player) + } + + fun play(context: IPayloadContext) { + // minecraft.player?.level()?.getPlayerByUUID(player)?.matteryPlayer?.spawnExopackSmoke = true + + minecraft.player?.level()?.getPlayerByUUID(player)?.let { ply -> + if (ply != minecraft.player || minecraft.gameRenderer.mainCamera.isDetached) { + var (x, y, z) = ply.position + + y += 1.5 + val deg = toRadians(ply.yBodyRot + 90f) + + x += kotlin.math.cos(deg) * -0.4 + z += kotlin.math.sin(deg) * -0.4 + + val level = ply.level() + val random = level.random + + for (i in 0 .. random.nextInt(2, 4)) + level.addParticle( + ParticleTypes.SMOKE, + x + random.nextDouble() * 0.4 - 0.2, + y + random.nextDouble() * 0.4 - 0.2, + z + random.nextDouble() * 0.4 - 0.2, + random.nextGaussian() * 0.02, + random.nextGaussian() * 0.02, + random.nextGaussian() * 0.02) + } + } + } + + override fun type(): CustomPacketPayload.Type { + return TYPE + } + + companion object { + val TYPE = CustomPacketPayload.Type( + ResourceLocation( + OverdriveThatMatters.MOD_ID, + "exopack_smoke" + ) + ) + val CODEC: StreamCodec = + StreamCodec.ofMember(ExopackSmokePacket::write, ::read) + + fun read(buff: FriendlyByteBuf): ExopackSmokePacket { + return ExopackSmokePacket(buff.readUUID()) + } + } +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/network/MenuDataPacket.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/network/MenuDataPacket.kt new file mode 100644 index 000000000..be8e83470 --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/network/MenuDataPacket.kt @@ -0,0 +1,56 @@ +package ru.dbotthepony.mc.otm.network + +import it.unimi.dsi.fastutil.io.FastByteArrayOutputStream +import net.minecraft.network.FriendlyByteBuf +import net.minecraft.network.codec.StreamCodec +import net.minecraft.network.protocol.common.custom.CustomPacketPayload +import net.neoforged.neoforge.network.handling.IPayloadContext +import ru.dbotthepony.mc.otm.OverdriveThatMatters +import ru.dbotthepony.mc.otm.capability.matteryPlayer +import ru.dbotthepony.mc.otm.client.minecraft +import ru.dbotthepony.mc.otm.core.ResourceLocation +import ru.dbotthepony.mc.otm.menu.ExopackInventoryMenu +import ru.dbotthepony.mc.otm.menu.MatteryMenu +import java.io.ByteArrayInputStream + +class MenuDataPacket(val containerId: Int, val bytes: ByteArray, val length: Int) : CustomPacketPayload { + constructor(containerId: Int, stream: FastByteArrayOutputStream) : this(containerId, stream.array, stream.length) + + fun write(buff: FriendlyByteBuf) { + buff.writeVarInt(containerId) + buff.writeBytes(bytes, 0, length) + } + + fun play(context: IPayloadContext) { + if (containerId == ExopackInventoryMenu.CONTAINER_ID) { + minecraft.player?.matteryPlayer?.exoPackMenu?.mSynchronizer?.read(ByteArrayInputStream(bytes, 0, length)) + } else { + val menu = minecraft.player?.containerMenu as? MatteryMenu ?: return + + if (menu.containerId == containerId) + menu.mSynchronizer.read(ByteArrayInputStream(bytes, 0, length)) + } + } + + override fun type(): CustomPacketPayload.Type { + return TYPE + } + + companion object { + val TYPE = CustomPacketPayload.Type( + ResourceLocation( + OverdriveThatMatters.MOD_ID, + "menu_data" + ) + ) + + val CODEC: StreamCodec = + StreamCodec.ofMember(MenuDataPacket::write, ::read) + + fun read(buff: FriendlyByteBuf): MenuDataPacket { + val containerId = buff.readVarInt() + val readable = buff.readableBytes() + return MenuDataPacket(containerId, ByteArray(readable).also(buff::readBytes), readable) + } + } +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/network/MenuNetworkChannel.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/network/MenuNetworkChannel.kt deleted file mode 100644 index dacc8ad7f..000000000 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/network/MenuNetworkChannel.kt +++ /dev/null @@ -1,95 +0,0 @@ -package ru.dbotthepony.mc.otm.network - -import it.unimi.dsi.fastutil.io.FastByteArrayOutputStream -import net.minecraft.network.FriendlyByteBuf -import net.minecraft.world.item.ItemStack -import net.minecraftforge.network.NetworkDirection -import ru.dbotthepony.mc.otm.capability.matteryPlayer -import ru.dbotthepony.mc.otm.client.minecraft -import ru.dbotthepony.mc.otm.compat.vanilla.InventoryScrollPacket -import ru.dbotthepony.mc.otm.menu.ExopackInventoryMenu -import ru.dbotthepony.mc.otm.menu.matter.CancelTaskPacket -import ru.dbotthepony.mc.otm.menu.MatteryMenu -import ru.dbotthepony.mc.otm.menu.matter.PatternsChangePacket -import ru.dbotthepony.mc.otm.menu.matter.ReplicationRequestPacket -import ru.dbotthepony.mc.otm.menu.matter.TasksChangePacket -import ru.dbotthepony.mc.otm.menu.data.ClearItemViewPacket -import ru.dbotthepony.mc.otm.menu.data.ItemViewInteractPacket -import ru.dbotthepony.mc.otm.menu.data.StackAddPacket -import ru.dbotthepony.mc.otm.menu.data.StackChangePacket -import ru.dbotthepony.mc.otm.menu.data.StackRemovePacket -import java.io.ByteArrayInputStream - -class MenuFieldPacket(val containerId: Int, val bytes: ByteArray, val length: Int) : MatteryPacket { - constructor(containerId: Int, stream: FastByteArrayOutputStream) : this(containerId, stream.array, stream.length) - - override fun write(buff: FriendlyByteBuf) { - buff.writeVarInt(containerId) - buff.writeBytes(bytes, 0, length) - } - - override fun play(context: MNetworkContext) { - if (containerId == ExopackInventoryMenu.CONTAINER_ID) { - minecraft.player?.matteryPlayer?.exoPackMenu?.mSynchronizer?.read(ByteArrayInputStream(bytes, 0, length)) - } else { - val menu = minecraft.player?.containerMenu as? MatteryMenu ?: return - - if (menu.containerId == containerId) - menu.mSynchronizer.read(ByteArrayInputStream(bytes, 0, length)) - } - } - - companion object { - fun read(buff: FriendlyByteBuf): MenuFieldPacket { - val containerId = buff.readVarInt() - val readable = buff.readableBytes() - return MenuFieldPacket(containerId, ByteArray(readable).also(buff::readBytes), readable) - } - } -} - -class SetCarriedPacket(val item: ItemStack) : MatteryPacket { - override fun write(buff: FriendlyByteBuf) { - buff.writeItem(item) - } - - override fun play(context: MNetworkContext) { - minecraft.player?.containerMenu?.carried = item - } - - companion object { - fun read(buff: FriendlyByteBuf): SetCarriedPacket { - return SetCarriedPacket(buff.readItem()) - } - } -} - -object MenuNetworkChannel : MatteryNetworkChannel( - version = 5, - name = "menu" -) { - fun register() { - add(SetCarriedPacket::class.java, SetCarriedPacket.Companion::read, NetworkDirection.PLAY_TO_CLIENT) - - // networked item view - add(ClearItemViewPacket::class.java, { ClearItemViewPacket }, NetworkDirection.PLAY_TO_CLIENT) - add(ItemViewInteractPacket::class.java, ItemViewInteractPacket.Companion::read, NetworkDirection.PLAY_TO_SERVER) - add(StackAddPacket::class.java, StackAddPacket.Companion::read, NetworkDirection.PLAY_TO_CLIENT) - add(StackChangePacket::class.java, StackChangePacket.Companion::read, NetworkDirection.PLAY_TO_CLIENT) - add(StackRemovePacket::class.java, StackRemovePacket.Companion::read, NetworkDirection.PLAY_TO_CLIENT) - - // Menu data - // Server->Client - add(MenuFieldPacket::class.java, MenuFieldPacket.Companion::read, NetworkDirection.PLAY_TO_CLIENT) - // Client->Server - add(MatteryMenu.PlayerInputPacket::class.java, MatteryMenu::PlayerInputPacket, NetworkDirection.PLAY_TO_SERVER) - - // matter panel menu - add(CancelTaskPacket::class.java, CancelTaskPacket.Companion::read, NetworkDirection.PLAY_TO_SERVER) - add(PatternsChangePacket::class.java, PatternsChangePacket.Companion::read, NetworkDirection.PLAY_TO_CLIENT) - add(TasksChangePacket::class.java, TasksChangePacket.Companion::read, NetworkDirection.PLAY_TO_CLIENT) - add(ReplicationRequestPacket::class.java, ReplicationRequestPacket.Companion::read, NetworkDirection.PLAY_TO_SERVER) - - add(InventoryScrollPacket::class.java, InventoryScrollPacket.Companion::read, NetworkDirection.PLAY_TO_SERVER) - } -} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/network/NetworkPackets.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/network/NetworkPackets.kt new file mode 100644 index 000000000..516ee51ee --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/network/NetworkPackets.kt @@ -0,0 +1,103 @@ +package ru.dbotthepony.mc.otm.network + +import net.neoforged.neoforge.network.event.RegisterPayloadHandlersEvent +import net.neoforged.neoforge.network.registration.HandlerThread +import ru.dbotthepony.mc.otm.android.AndroidResearchManager +import ru.dbotthepony.mc.otm.android.feature.ItemEntityDataPacket +import ru.dbotthepony.mc.otm.compat.vanilla.InventoryScrollPacket +import ru.dbotthepony.mc.otm.item.QuantumBatteryItem +import ru.dbotthepony.mc.otm.matter.MatterManager +import ru.dbotthepony.mc.otm.menu.MatteryMenu +import ru.dbotthepony.mc.otm.menu.data.ClearItemViewPacket +import ru.dbotthepony.mc.otm.menu.data.ItemViewInteractPacket +import ru.dbotthepony.mc.otm.menu.data.StackAddPacket +import ru.dbotthepony.mc.otm.menu.data.StackChangePacket +import ru.dbotthepony.mc.otm.menu.data.StackRemovePacket +import ru.dbotthepony.mc.otm.menu.matter.CancelTaskPacket +import ru.dbotthepony.mc.otm.menu.matter.PatternsChangePacket +import ru.dbotthepony.mc.otm.menu.matter.ReplicationRequestPacket +import ru.dbotthepony.mc.otm.menu.matter.TasksChangePacket + +fun registerNetworkPackets(event: RegisterPayloadHandlersEvent) { + val r = event.registrar("1.5.0") + + // world + r + .playToClient(BlockEntitySyncPacket.TYPE, BlockEntitySyncPacket.CODEC, BlockEntitySyncPacket::play) + .playToClient(SmokeParticlesPacket.TYPE, SmokeParticlesPacket.CODEC, SmokeParticlesPacket::play) + + // items + r + .playToClient(QuantumBatteryItem.PACKET_TYPE, QuantumBatteryItem.PACKET_CODEC, QuantumBatteryItem.ChargePacket::play) + .playToClient(ItemEntityDataPacket.TYPE, ItemEntityDataPacket.CODEC, ItemEntityDataPacket::play) + + // registries + r.executesOn(HandlerThread.NETWORK) + .playToClient(AndroidResearchManager.SYNC_TYPE, AndroidResearchManager.SYNC_CODEC, AndroidResearchManager.SyncPacket::play) + .playToClient(MatterManager.SYNC_TYPE, MatterManager.SYNC_CODEC, MatterManager.SyncPacket::play) + + // exopack + r + .playToClient(ExopackCarriedPacket.TYPE, ExopackCarriedPacket.CODEC, ExopackCarriedPacket::play) + .playToClient(ExopackSlotPacket.TYPE, ExopackSlotPacket.CODEC, ExopackSlotPacket::play) + .playToClient(ExopackMenuInitPacket.TYPE, ExopackMenuInitPacket.CODEC, ExopackMenuInitPacket::play) + .playToClient(ExopackSmokePacket.TYPE, ExopackSmokePacket.CODEC, ExopackSmokePacket::play) + .playToServer(ExopackMenuOpen.TYPE, ExopackMenuOpen.CODEC, ExopackMenuOpen::play) + + .playToServer(PickItemFromInventoryPacket.TYPE, PickItemFromInventoryPacket.CODEC, PickItemFromInventoryPacket::play) + + .playToServer(DisplayExopackPacket.TYPE, DisplayExopackPacket.CODEC, DisplayExopackPacket::play) + .playToServer(HideExopackPacket.TYPE, HideExopackPacket.CODEC, HideExopackPacket::play) + .playToServer(EnableExopackGlowPacket.TYPE, EnableExopackGlowPacket.CODEC, EnableExopackGlowPacket::play) + .playToServer(DisableExopackGlowPacket.TYPE, DisableExopackGlowPacket.CODEC, DisableExopackGlowPacket::play) + .playToServer(ResetExopackColorPacket.TYPE, ResetExopackColorPacket.CODEC, ResetExopackColorPacket::play) + .playToServer(SetExopackColorPacket.TYPE, SetExopackColorPacket.CODEC, SetExopackColorPacket::play) + + // otm player general + r + .playToClient(MatteryPlayerDataPacket.TYPE, MatteryPlayerDataPacket.CODEC, MatteryPlayerDataPacket::play) + + // android + r + .playToClient(PlayerIterationPacket.TYPE, PlayerIterationPacket.CODEC, PlayerIterationPacket::play) + .playToClient(GlitchPacket.TYPE, GlitchPacket.CODEC, GlitchPacket::play) + .playToClient(ShockwaveEffectPacket.TYPE, ShockwaveEffectPacket.CODEC, ShockwaveEffectPacket::play) + + .playToServer(AndroidResearchRequestPacket.TYPE, AndroidResearchRequestPacket.CODEC, AndroidResearchRequestPacket::play) + .playToClient(AndroidResearchSyncPacket.TYPE, AndroidResearchSyncPacket.CODEC, AndroidResearchSyncPacket::play) + + .playToClient(AndroidFeatureSyncPacket.TYPE, AndroidFeatureSyncPacket.CODEC, AndroidFeatureSyncPacket::play) + .playToClient(AndroidFeatureRemovePacket.TYPE, AndroidFeatureRemovePacket.CODEC, AndroidFeatureRemovePacket::play) + + .playToServer(SwitchAndroidFeaturePacket.TYPE, SwitchAndroidFeaturePacket.CODEC, SwitchAndroidFeaturePacket::play) + .playToServer(ActivateAndroidFeaturePacket.TYPE, ActivateAndroidFeaturePacket.CODEC, ActivateAndroidFeaturePacket::play) + + .playToServer(TriggerShockwavePacket.TYPE, TriggerShockwavePacket.CODEC, TriggerShockwavePacket::play) + .playToServer(TriggerJumpBoostPacket.TYPE, TriggerJumpBoostPacket.CODEC, TriggerJumpBoostPacket::play) + + // menus + r + // carried item stack set + .playToClient(SetCarriedPacket.TYPE, SetCarriedPacket.CODEC, SetCarriedPacket::play) + + // server->client data + .playToClient(MenuDataPacket.TYPE, MenuDataPacket.CODEC, MenuDataPacket::play) + // client->server input + .playToServer(MatteryMenu.PlayerInputPacket.TYPE, MatteryMenu.PlayerInputPacket.CODEC, MatteryMenu.PlayerInputPacket::play) + + // extended inventory compat + .playToServer(InventoryScrollPacket.TYPE, InventoryScrollPacket.CODEC, InventoryScrollPacket::play) + + // matter replication menu + .playToClient(PatternsChangePacket.TYPE, PatternsChangePacket.CODEC, PatternsChangePacket::play) + .playToClient(TasksChangePacket.TYPE, TasksChangePacket.CODEC, TasksChangePacket::play) + .playToServer(ReplicationRequestPacket.TYPE, ReplicationRequestPacket.CODEC, ReplicationRequestPacket::play) + .playToServer(CancelTaskPacket.TYPE, CancelTaskPacket.CODEC, CancelTaskPacket::play) + + // item view + .playToClient(StackAddPacket.TYPE, StackAddPacket.CODEC, StackAddPacket::play) + .playToClient(StackChangePacket.TYPE, StackChangePacket.CODEC, StackChangePacket::play) + .playToClient(StackRemovePacket.TYPE, StackRemovePacket.CODEC, StackRemovePacket::play) + .playToClient(ClearItemViewPacket.TYPE, ClearItemViewPacket.CODEC, ClearItemViewPacket::play) + .playToServer(ItemViewInteractPacket.TYPE, ItemViewInteractPacket.CODEC, ItemViewInteractPacket::play) +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/network/SetCarriedPacket.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/network/SetCarriedPacket.kt new file mode 100644 index 000000000..24651ff9b --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/network/SetCarriedPacket.kt @@ -0,0 +1,42 @@ +package ru.dbotthepony.mc.otm.network + +import net.minecraft.network.RegistryFriendlyByteBuf +import net.minecraft.network.codec.StreamCodec +import net.minecraft.network.protocol.common.custom.CustomPacketPayload +import net.minecraft.world.item.ItemStack +import net.neoforged.neoforge.network.handling.IPayloadContext +import ru.dbotthepony.mc.otm.OverdriveThatMatters +import ru.dbotthepony.mc.otm.client.minecraft +import ru.dbotthepony.mc.otm.core.ResourceLocation +import ru.dbotthepony.mc.otm.core.readItem +import ru.dbotthepony.mc.otm.core.writeItem + +class SetCarriedPacket(val item: ItemStack) : CustomPacketPayload { + fun write(buff: RegistryFriendlyByteBuf) { + buff.writeItem(item) + } + + fun play(context: IPayloadContext) { + minecraft.player?.containerMenu?.carried = item + } + + override fun type(): CustomPacketPayload.Type { + return TYPE + } + + companion object { + val TYPE = CustomPacketPayload.Type( + ResourceLocation( + OverdriveThatMatters.MOD_ID, + "menu_set_carried" + ) + ) + + val CODEC: StreamCodec = + StreamCodec.ofMember(SetCarriedPacket::write, ::read) + + fun read(buff: RegistryFriendlyByteBuf): SetCarriedPacket { + return SetCarriedPacket(buff.readItem()) + } + } +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/network/ShockwaveEffectPacket.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/network/ShockwaveEffectPacket.kt new file mode 100644 index 000000000..b5b125ca7 --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/network/ShockwaveEffectPacket.kt @@ -0,0 +1,41 @@ +package ru.dbotthepony.mc.otm.network + +import net.minecraft.network.FriendlyByteBuf +import net.minecraft.network.codec.StreamCodec +import net.minecraft.network.protocol.common.custom.CustomPacketPayload +import net.neoforged.neoforge.network.handling.IPayloadContext +import ru.dbotthepony.mc.otm.OverdriveThatMatters +import ru.dbotthepony.mc.otm.client.render.ShockwaveRenderer +import ru.dbotthepony.mc.otm.core.ResourceLocation +import ru.dbotthepony.mc.otm.core.math.Vector + +class ShockwaveEffectPacket(val pos: Vector) : CustomPacketPayload { + fun write(buff: FriendlyByteBuf) { + buff.writeDouble(pos.x) + buff.writeDouble(pos.y) + buff.writeDouble(pos.z) + } + + fun play(context: IPayloadContext) { + ShockwaveRenderer.handle(this) + } + + override fun type(): CustomPacketPayload.Type { + return TYPE + } + + companion object { + val TYPE = CustomPacketPayload.Type( + ResourceLocation( + OverdriveThatMatters.MOD_ID, + "shockwave_effect" + ) + ) + val CODEC: StreamCodec = + StreamCodec.ofMember(ShockwaveEffectPacket::write, ::read) + + fun read(buff: FriendlyByteBuf): ShockwaveEffectPacket { + return ShockwaveEffectPacket(Vector(buff.readDouble(), buff.readDouble(), buff.readDouble())) + } + } +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/network/SmokeParticlesPacket.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/network/SmokeParticlesPacket.kt new file mode 100644 index 000000000..a80bb1ec5 --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/network/SmokeParticlesPacket.kt @@ -0,0 +1,57 @@ +package ru.dbotthepony.mc.otm.network + +import net.minecraft.core.particles.ParticleTypes +import net.minecraft.network.FriendlyByteBuf +import net.minecraft.network.codec.StreamCodec +import net.minecraft.network.protocol.common.custom.CustomPacketPayload +import net.minecraft.server.level.ServerLevel +import net.minecraft.server.level.ServerPlayer +import net.minecraft.util.RandomSource +import net.minecraft.world.level.Level +import net.neoforged.neoforge.network.PacketDistributor +import net.neoforged.neoforge.network.handling.IPayloadContext +import ru.dbotthepony.mc.otm.OverdriveThatMatters +import ru.dbotthepony.mc.otm.client.minecraft +import ru.dbotthepony.mc.otm.core.ResourceLocation + +class SmokeParticlesPacket(val x: Double, val y: Double, val z: Double) : CustomPacketPayload { + fun write(buff: FriendlyByteBuf) { + buff.writeDouble(x) + buff.writeDouble(y) + buff.writeDouble(z) + } + + fun play(context: IPayloadContext) { + minecraft.player?.level()?.let { + makeSmoke(x, y, z, it.random, it) + } + } + + override fun type(): CustomPacketPayload.Type { + return TYPE + } + + companion object { + val TYPE = + CustomPacketPayload.Type(ResourceLocation(OverdriveThatMatters.MOD_ID, "smoke")) + val CODEC: StreamCodec = + StreamCodec.ofMember(SmokeParticlesPacket::write, ::read) + + fun read(buff: FriendlyByteBuf): SmokeParticlesPacket { + return SmokeParticlesPacket(buff.readDouble(), buff.readDouble(), buff.readDouble()) + } + + fun makeSmoke(x: Double, y: Double, z: Double, level: ServerLevel) { + PacketDistributor.sendToPlayersNear(level, null, x, y, z, 64.0, SmokeParticlesPacket(x, y, z)) + } + + fun makeSmoke(excluded: ServerPlayer, x: Double, y: Double, z: Double) { + PacketDistributor.sendToPlayersNear(excluded.serverLevel(), excluded, x, y, z, 64.0, SmokeParticlesPacket(x, y, z)) + } + + fun makeSmoke(x: Double, y: Double, z: Double, random: RandomSource, level: Level) { + for (i in 0 .. random.nextInt(4, 8)) + level.addParticle(ParticleTypes.POOF, x + random.nextDouble() * 0.5 - 0.25, y + random.nextDouble() * 0.5 - 0.25, z + random.nextDouble() * 0.5 - 0.25, random.nextGaussian() * 0.02, random.nextGaussian() * 0.02, random.nextGaussian() * 0.02) + } + } +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/network/StreamCodecs.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/network/StreamCodecs.kt new file mode 100644 index 000000000..a9803ffac --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/network/StreamCodecs.kt @@ -0,0 +1,13 @@ +package ru.dbotthepony.mc.otm.network + +import net.minecraft.network.FriendlyByteBuf +import net.minecraft.network.codec.StreamCodec + +// because mojang didn't bother +object StreamCodecs { + val INT: StreamCodec = StreamCodec.of(FriendlyByteBuf::writeInt, FriendlyByteBuf::readInt) + val LONG: StreamCodec = StreamCodec.of(FriendlyByteBuf::writeLong, FriendlyByteBuf::readLong) + val DOUBLE: StreamCodec = StreamCodec.of(FriendlyByteBuf::writeDouble, FriendlyByteBuf::readDouble) + val FLOAT: StreamCodec = StreamCodec.of(FriendlyByteBuf::writeFloat, FriendlyByteBuf::readFloat) + val BOOLEAN: StreamCodec = StreamCodec.of(FriendlyByteBuf::writeBoolean, FriendlyByteBuf::readBoolean) +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/network/WeaponNetworkChannel.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/network/WeaponNetworkChannel.kt deleted file mode 100644 index 6c54049f6..000000000 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/network/WeaponNetworkChannel.kt +++ /dev/null @@ -1,15 +0,0 @@ -package ru.dbotthepony.mc.otm.network - -import net.minecraftforge.network.NetworkDirection -import ru.dbotthepony.mc.otm.item.weapon.WeaponFireInputPacket -import ru.dbotthepony.mc.otm.item.weapon.WeaponScopePacket - -object WeaponNetworkChannel : MatteryNetworkChannel( - version = 3, - name = "weapon" -) { - fun register() { - add(WeaponScopePacket::class.java, WeaponScopePacket.Companion::read, NetworkDirection.PLAY_TO_SERVER) - add(WeaponFireInputPacket::class.java, WeaponFireInputPacket.Companion::read, NetworkDirection.PLAY_TO_SERVER) - } -} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/recipe/IMatteryRecipe.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/recipe/IMatteryRecipe.kt index 8d3e9ae30..83ff38568 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/recipe/IMatteryRecipe.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/recipe/IMatteryRecipe.kt @@ -1,13 +1,10 @@ package ru.dbotthepony.mc.otm.recipe import net.minecraft.core.NonNullList -import net.minecraft.world.Container import net.minecraft.world.item.ItemStack import net.minecraft.world.item.crafting.Ingredient import net.minecraft.world.item.crafting.Recipe import net.minecraft.world.item.crafting.RecipeInput -import net.minecraft.world.item.crafting.RecipeSerializer -import ru.dbotthepony.mc.otm.data.Codec2RecipeSerializer // passthrough all default methods to fix Kotlin bug related to implementation delegation not properly working on Java interfaces // https://youtrack.jetbrains.com/issue/KT-55080/Change-the-behavior-of-inheritance-delegation-to-delegates-implementing-Java-interfaces-with-default-methods diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/recipe/IngredientMatrix.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/recipe/IngredientMatrix.kt index a9d6a96d9..407806a1c 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/recipe/IngredientMatrix.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/recipe/IngredientMatrix.kt @@ -1,19 +1,15 @@ package ru.dbotthepony.mc.otm.recipe import net.minecraft.core.NonNullList -import net.minecraft.world.inventory.CraftingContainer import net.minecraft.world.item.crafting.CraftingInput import net.minecraft.world.item.crafting.Ingredient -import ru.dbotthepony.mc.otm.OverdriveThatMatters -import ru.dbotthepony.mc.otm.container.get import ru.dbotthepony.mc.otm.core.collect.allEqual import ru.dbotthepony.mc.otm.core.collect.any import ru.dbotthepony.mc.otm.core.collect.flatMap import ru.dbotthepony.mc.otm.core.collect.map import ru.dbotthepony.mc.otm.core.get -import ru.dbotthepony.mc.otm.core.isActuallyEmpty import ru.dbotthepony.mc.otm.core.isNotEmpty -import ru.dbotthepony.mc.otm.core.util.countingLazy +import ru.dbotthepony.mc.otm.core.util.InvalidableLazy import java.util.function.Predicate interface IIngredientMatrix : Predicate, Iterable { @@ -23,7 +19,7 @@ interface IIngredientMatrix : Predicate, Iterable { get() = width == 0 || height == 0 val isIncomplete: Boolean - get() = iterator().any { it.isActuallyEmpty } + get() = iterator().any { it.hasNoItems() } operator fun get(column: Int, row: Int): Ingredient @@ -123,7 +119,7 @@ interface IIngredientMatrix : Predicate, Iterable { class IngredientMatrix(override val width: Int, override val height: Int) : IIngredientMatrix { private val data = Array(width * height) { Ingredient.EMPTY } - private val lazy = countingLazy(OverdriveThatMatters.INGREDIENT_CACHE_INVALIDATION_COUNTER) { + private val lazy = InvalidableLazy.Impl { super.isIncomplete } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/recipe/MatterEntanglerRecipe.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/recipe/MatterEntanglerRecipe.kt index a95f676e5..689182a1b 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/recipe/MatterEntanglerRecipe.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/recipe/MatterEntanglerRecipe.kt @@ -6,24 +6,18 @@ import net.minecraft.core.HolderLookup import net.minecraft.core.NonNullList import net.minecraft.core.RegistryAccess import net.minecraft.core.UUIDUtil -import net.minecraft.data.recipes.FinishedRecipe import net.minecraft.resources.ResourceLocation -import net.minecraft.world.inventory.CraftingContainer import net.minecraft.world.item.ItemStack import net.minecraft.world.item.crafting.CraftingInput import net.minecraft.world.item.crafting.Ingredient import net.minecraft.world.item.crafting.RecipeSerializer import net.minecraft.world.item.crafting.RecipeType import net.minecraft.world.level.Level -import ru.dbotthepony.mc.otm.capability.matter.matter import ru.dbotthepony.mc.otm.capability.matteryEnergy -import ru.dbotthepony.mc.otm.container.util.iterator import ru.dbotthepony.mc.otm.core.collect.filterNotNull import ru.dbotthepony.mc.otm.core.collect.map import ru.dbotthepony.mc.otm.core.math.Decimal import ru.dbotthepony.mc.otm.core.nbt.set -import ru.dbotthepony.mc.otm.core.tagNotNull -import ru.dbotthepony.mc.otm.data.Codec2RecipeSerializer import ru.dbotthepony.mc.otm.data.DecimalCodec import ru.dbotthepony.mc.otm.data.IngredientMatrixCodec import ru.dbotthepony.mc.otm.data.minRange diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/recipe/MatteryCookingRecipe.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/recipe/MatteryCookingRecipe.kt index f3bb8f4dd..cce6310d7 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/recipe/MatteryCookingRecipe.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/recipe/MatteryCookingRecipe.kt @@ -4,23 +4,15 @@ import com.mojang.serialization.Codec import com.mojang.serialization.codecs.RecordCodecBuilder import net.minecraft.core.HolderLookup import net.minecraft.core.NonNullList -import net.minecraft.core.RegistryAccess import net.minecraft.data.recipes.FinishedRecipe -import net.minecraft.network.FriendlyByteBuf import net.minecraft.resources.ResourceLocation import net.minecraft.util.valueproviders.ConstantFloat import net.minecraft.util.valueproviders.FloatProvider -import net.minecraft.world.Container import net.minecraft.world.item.ItemStack -import net.minecraft.world.item.Items import net.minecraft.world.item.crafting.* import net.minecraft.world.level.Level import ru.dbotthepony.mc.otm.OverdriveThatMatters -import ru.dbotthepony.mc.otm.container.get -import ru.dbotthepony.mc.otm.core.get -import ru.dbotthepony.mc.otm.core.isActuallyEmpty import ru.dbotthepony.mc.otm.core.registryName -import ru.dbotthepony.mc.otm.data.Codec2RecipeSerializer import ru.dbotthepony.mc.otm.data.minRange import ru.dbotthepony.mc.otm.registry.MItems import ru.dbotthepony.mc.otm.registry.MRecipes @@ -31,19 +23,12 @@ abstract class MatteryCookingRecipe( val count: Int = 1, val workTime: Int = 200, val experience: FloatProvider = ConstantFloat.ZERO -) : Recipe { - override fun matches(container: RecipeInput, level: Level): Boolean { +) : Recipe { + override fun matches(container: SingleRecipeInput, level: Level): Boolean { if (isIncomplete) return false - return input.test(container[0]) - } - - fun matches(container: RecipeInput, slot: Int): Boolean { - if (isIncomplete) - return false - - return input.test(container[slot]) + return input.test(container.item) } private val outputStack: ItemStack by lazy { @@ -63,9 +48,9 @@ abstract class MatteryCookingRecipe( return NonNullList.of(Ingredient.EMPTY, input) } - override fun isIncomplete(): Boolean = input.isActuallyEmpty || output.isActuallyEmpty + override fun isIncomplete(): Boolean = input.hasNoItems() || output.hasNoItems() - override fun assemble(container: RecipeInput, registry: HolderLookup.Provider): ItemStack = outputStack.copy() + override fun assemble(container: SingleRecipeInput, registry: HolderLookup.Provider): ItemStack = outputStack.copy() override fun canCraftInDimensions(width: Int, height: Int): Boolean = true diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/recipe/PainterRecipe.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/recipe/PainterRecipe.kt index 124d68946..da1f91b92 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/recipe/PainterRecipe.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/recipe/PainterRecipe.kt @@ -8,7 +8,6 @@ import it.unimi.dsi.fastutil.objects.Object2IntMap import it.unimi.dsi.fastutil.objects.Object2IntMaps import net.minecraft.core.HolderLookup import net.minecraft.core.NonNullList -import net.minecraft.core.RegistryAccess import net.minecraft.data.recipes.FinishedRecipe import net.minecraft.resources.ResourceLocation import net.minecraft.util.StringRepresentable @@ -25,7 +24,6 @@ import ru.dbotthepony.mc.otm.core.get import ru.dbotthepony.mc.otm.core.isActuallyEmpty import ru.dbotthepony.mc.otm.core.nbt.set import ru.dbotthepony.mc.otm.core.tagNotNull -import ru.dbotthepony.mc.otm.data.Codec2RecipeSerializer import ru.dbotthepony.mc.otm.data.PredicatedCodecList import ru.dbotthepony.mc.otm.data.minRange import ru.dbotthepony.mc.otm.registry.MItems diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/recipe/PlatePressRecipe.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/recipe/PlatePressRecipe.kt index cba8be8c9..84e49d68b 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/recipe/PlatePressRecipe.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/recipe/PlatePressRecipe.kt @@ -4,7 +4,6 @@ import com.mojang.serialization.Codec import com.mojang.serialization.codecs.RecordCodecBuilder import net.minecraft.core.HolderLookup import net.minecraft.core.NonNullList -import net.minecraft.core.RegistryAccess import net.minecraft.resources.ResourceLocation import net.minecraft.util.valueproviders.ConstantFloat import net.minecraft.util.valueproviders.FloatProvider @@ -19,10 +18,8 @@ import net.minecraft.world.level.Level import ru.dbotthepony.mc.otm.OverdriveThatMatters import ru.dbotthepony.mc.otm.container.get import ru.dbotthepony.mc.otm.core.get -import ru.dbotthepony.mc.otm.core.isActuallyEmpty import ru.dbotthepony.mc.otm.registry.MRecipes import ru.dbotthepony.mc.otm.core.registryName -import ru.dbotthepony.mc.otm.data.Codec2RecipeSerializer import ru.dbotthepony.mc.otm.data.minRange import ru.dbotthepony.mc.otm.registry.MItems @@ -65,7 +62,7 @@ class PlatePressRecipe( } override fun isIncomplete(): Boolean { - return input.isActuallyEmpty || output.isActuallyEmpty + return input.hasNoItems() || output.hasNoItems() } override fun assemble(p_44001_: RecipeInput, registry: HolderLookup.Provider): ItemStack = outputStack.copy() diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/recipe/UpgradeRecipe.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/recipe/UpgradeRecipe.kt index ea8bddc0d..c00371944 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/recipe/UpgradeRecipe.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/recipe/UpgradeRecipe.kt @@ -1,16 +1,13 @@ package ru.dbotthepony.mc.otm.recipe import com.google.common.collect.ImmutableList -import com.google.gson.JsonObject -import com.google.gson.JsonPrimitive import com.mojang.serialization.Codec +import com.mojang.serialization.MapCodec import com.mojang.serialization.codecs.RecordCodecBuilder import net.minecraft.core.NonNullList import net.minecraft.core.RegistryAccess import net.minecraft.nbt.CompoundTag -import net.minecraft.network.FriendlyByteBuf import net.minecraft.resources.ResourceLocation -import net.minecraft.util.GsonHelper import net.minecraft.util.StringRepresentable import net.minecraft.world.inventory.CraftingContainer import net.minecraft.world.item.ItemStack @@ -25,12 +22,7 @@ import net.minecraftforge.common.crafting.IShapedRecipe import ru.dbotthepony.mc.otm.container.util.stream import ru.dbotthepony.mc.otm.core.nbt.set import ru.dbotthepony.mc.otm.core.registryName -import ru.dbotthepony.mc.otm.core.set import ru.dbotthepony.mc.otm.core.tagNotNull -import ru.dbotthepony.mc.otm.core.util.readBinaryJson -import ru.dbotthepony.mc.otm.core.util.writeBinaryJson -import ru.dbotthepony.mc.otm.core.collect.stream -import ru.dbotthepony.mc.otm.data.Codec2RecipeSerializer import ru.dbotthepony.mc.otm.data.SingletonCodec import java.util.stream.Stream @@ -91,14 +83,14 @@ class UpgradeRecipe( enum class OpType : StringRepresentable { DIRECT { - override val codec: Codec = RecordCodecBuilder.create { + override val codec: MapCodec = RecordCodecBuilder.mapCodec { it.group( Codec.STRING.fieldOf("path").forGetter(Direct::path) ).apply(it, ::Direct) } }, INDIRECT { - override val codec: Codec = RecordCodecBuilder.create { + override val codec: MapCodec = RecordCodecBuilder.mapCodec { it.group( Codec.STRING.fieldOf("source").forGetter(Indirect::pathSource), Codec.STRING.fieldOf("destination").forGetter(Indirect::pathDestination), @@ -106,7 +98,7 @@ class UpgradeRecipe( } }, ALL { - override val codec: Codec by lazy { SingletonCodec(All) } + override val codec: MapCodec by lazy { MapCodec.unit(All) } }, ; @@ -114,7 +106,7 @@ class UpgradeRecipe( return name.lowercase() } - abstract val codec: Codec + abstract val codec: MapCodec } sealed class Op { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/AndroidFeatures.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/AndroidFeatures.kt index c8c195727..6b19e61ed 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/AndroidFeatures.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/AndroidFeatures.kt @@ -1,8 +1,6 @@ package ru.dbotthepony.mc.otm.registry -import net.minecraftforge.eventbus.api.IEventBus -import net.minecraftforge.registries.DeferredRegister -import ru.dbotthepony.mc.otm.OverdriveThatMatters +import net.neoforged.bus.api.IEventBus import ru.dbotthepony.mc.otm.android.AndroidFeatureType import ru.dbotthepony.mc.otm.android.DummyAndroidFeature import ru.dbotthepony.mc.otm.android.feature.* @@ -25,7 +23,7 @@ object AndroidFeatures { val JUMP_BOOST by registry.register(MNames.JUMP_BOOST) { AndroidFeatureType(::JumpBoostFeature) } val ENDER_TELEPORTER by registry.register(MNames.ENDER_TELEPORTER) { AndroidFeatureType(::EnderTeleporterFeature) } - internal fun register(bus: IEventBus) { + fun register(bus: IEventBus) { registry.register(bus) } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/CapabilitiesRegisterListener.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/CapabilitiesRegisterListener.kt new file mode 100644 index 000000000..945c89500 --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/CapabilitiesRegisterListener.kt @@ -0,0 +1,7 @@ +package ru.dbotthepony.mc.otm.registry + +import net.neoforged.neoforge.capabilities.RegisterCapabilitiesEvent + +interface CapabilitiesRegisterListener { + fun registerCapabilities(event: RegisterCapabilitiesEvent) +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/LootModifiers.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/LootModifiers.kt index 8ae067580..4b11c5876 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/LootModifiers.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/LootModifiers.kt @@ -1,19 +1,18 @@ package ru.dbotthepony.mc.otm.registry -import net.minecraftforge.eventbus.api.IEventBus -import net.minecraftforge.registries.DeferredRegister -import net.minecraftforge.registries.ForgeRegistries +import net.neoforged.bus.api.IEventBus +import net.neoforged.neoforge.registries.NeoForgeRegistries import ru.dbotthepony.mc.otm.OverdriveThatMatters import ru.dbotthepony.mc.otm.data.loot.LootPoolAppender object LootModifiers { - private val registry = DeferredRegister.create(ForgeRegistries.Keys.GLOBAL_LOOT_MODIFIER_SERIALIZERS, OverdriveThatMatters.MOD_ID) + private val registry = MDeferredRegister(NeoForgeRegistries.Keys.GLOBAL_LOOT_MODIFIER_SERIALIZERS, OverdriveThatMatters.MOD_ID) init { registry.register("loot_appender") { LootPoolAppender.CODEC } } - internal fun register(bus: IEventBus) { + fun register(bus: IEventBus) { registry.register(bus) } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MArmorMaterials.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MArmorMaterials.kt new file mode 100644 index 000000000..8a9916df7 --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MArmorMaterials.kt @@ -0,0 +1,59 @@ +package ru.dbotthepony.mc.otm.registry + +import net.minecraft.core.registries.BuiltInRegistries +import net.minecraft.sounds.SoundEvents +import net.minecraft.world.item.ArmorItem +import net.minecraft.world.item.ArmorMaterial +import net.minecraft.world.item.crafting.Ingredient +import net.neoforged.bus.api.IEventBus +import ru.dbotthepony.mc.otm.OverdriveThatMatters +import ru.dbotthepony.mc.otm.core.ResourceLocation + +// why is this even a thing holy shit +object MArmorMaterials { + private val registrar = MDeferredRegister(BuiltInRegistries.ARMOR_MATERIAL) + + fun register(bus: IEventBus) { + registrar.register(bus) + } + + val TRITANIUM = registrar.register("tritanium") { + ArmorMaterial( + mapOf( + ArmorItem.Type.HELMET to 4, + ArmorItem.Type.CHESTPLATE to 9, + ArmorItem.Type.LEGGINGS to 7, + ArmorItem.Type.BOOTS to 3, + ), + 9, + SoundEvents.ARMOR_EQUIP_IRON, + { Ingredient.of(MItemTags.REINFORCED_TRITANIUM_PLATES) }, + listOf( + ArmorMaterial.Layer(ResourceLocation(OverdriveThatMatters.MOD_ID, "textures/models/armor/tritanium_armor_base.png")), + ArmorMaterial.Layer(ResourceLocation(OverdriveThatMatters.MOD_ID, "textures/models/armor/tritanium_armor_overlay.png"), "", true), + ), + 1f, + 0.08f + ) + } + + val SIMPLE_TRITANIUM = registrar.register("simple_tritanium") { + ArmorMaterial( + mapOf( + ArmorItem.Type.HELMET to 2, + ArmorItem.Type.CHESTPLATE to 6, + ArmorItem.Type.LEGGINGS to 7, + ArmorItem.Type.BOOTS to 2, + ), + 9, + SoundEvents.ARMOR_EQUIP_IRON, + { Ingredient.of(MItemTags.TRITANIUM_INGOTS) }, + listOf( + ArmorMaterial.Layer(ResourceLocation(OverdriveThatMatters.MOD_ID, "textures/models/armor/simple_tritanium_armor.png")), + // ArmorMaterial.Layer(ResourceLocation(OverdriveThatMatters.MOD_ID, "textures/models/armor/simple_tritanium_armor_overlay.png"), "", true), + ), + 0.3f, + 0f + ) + } +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MBlockColors.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MBlockColors.kt index 398052552..0e4471da9 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MBlockColors.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MBlockColors.kt @@ -7,8 +7,8 @@ import net.minecraft.core.BlockPos import net.minecraft.world.item.ItemStack import net.minecraft.world.level.BlockAndTintGetter import net.minecraft.world.level.block.state.BlockState -import net.minecraftforge.client.event.RegisterColorHandlersEvent -import net.minecraftforge.eventbus.api.IEventBus +import net.neoforged.bus.api.IEventBus +import net.neoforged.neoforge.client.event.RegisterColorHandlersEvent import ru.dbotthepony.mc.otm.block.entity.decorative.HoloSignBlockEntity import ru.dbotthepony.kommons.math.RGBAColor @@ -64,7 +64,7 @@ object MBlockColors { event.register(HoloSightColor, MBlocks.HOLO_SIGN) } - internal fun register(bus: IEventBus) { + fun register(bus: IEventBus) { bus.addListener(this::registerBlockColors) bus.addListener(this::registerItemColors) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MBlockEntities.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MBlockEntities.kt index 27aea31ec..ad8e53695 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MBlockEntities.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MBlockEntities.kt @@ -1,12 +1,12 @@ package ru.dbotthepony.mc.otm.registry import net.minecraft.client.renderer.blockentity.BlockEntityRenderers +import net.minecraft.core.registries.BuiltInRegistries import net.minecraft.world.level.block.Block import net.minecraft.world.level.block.entity.BlockEntity import net.minecraft.world.level.block.entity.BlockEntityType -import net.minecraftforge.eventbus.api.IEventBus -import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent -import net.minecraftforge.registries.ForgeRegistries +import net.neoforged.bus.api.IEventBus +import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent import ru.dbotthepony.mc.otm.block.entity.* import ru.dbotthepony.mc.otm.block.entity.tech.* import ru.dbotthepony.mc.otm.block.entity.blackhole.BlackHoleBlockEntity @@ -34,7 +34,7 @@ import java.util.function.Supplier @Suppress("NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS") // Type<*> is unused in BlockEntityType.Builder object MBlockEntities { - private val registry = MDeferredRegister(ForgeRegistries.BLOCK_ENTITY_TYPES) + private val registry = MDeferredRegister(BuiltInRegistries.BLOCK_ENTITY_TYPE) private fun register(name: String, factory: BlockEntityType.BlockEntitySupplier, vararg blocks: Supplier): MDeferredRegister<*>.Entry> { return registry.register(name) { BlockEntityType.Builder.of(factory, *blocks.map { it.get() }.toTypedArray()).build(null) } @@ -112,7 +112,7 @@ object MBlockEntities { val DEBUG_EXPLOSION_SMALL: BlockEntityType by registry.register(MNames.DEBUG_EXPLOSION_SMALL) { BlockEntityType.Builder.of(::BlockEntityExplosionDebugger, MBlocks.DEBUG_EXPLOSION_SMALL).build(null) } val DEBUG_SPHERE_POINTS: BlockEntityType by registry.register(MNames.DEBUG_SPHERE_POINTS) { BlockEntityType.Builder.of(::BlockEntitySphereDebugger, MBlocks.DEBUG_SPHERE_POINTS).build(null) } - internal fun register(bus: IEventBus) { + fun register(bus: IEventBus) { registry.register(bus) bus.addListener(this::registerClient) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MBlockTags.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MBlockTags.kt index 57b04b64b..d0d8814b4 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MBlockTags.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MBlockTags.kt @@ -1,10 +1,10 @@ package ru.dbotthepony.mc.otm.registry -import net.minecraft.resources.ResourceLocation import net.minecraft.tags.BlockTags import net.minecraft.tags.TagKey import net.minecraft.world.level.block.Block import ru.dbotthepony.mc.otm.OverdriveThatMatters +import ru.dbotthepony.mc.otm.core.ResourceLocation @Suppress("unused") object MBlockTags { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MBlocks.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MBlocks.kt index ac49301a8..447bca469 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MBlocks.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MBlocks.kt @@ -1,5 +1,7 @@ package ru.dbotthepony.mc.otm.registry +import net.minecraft.core.Direction +import net.minecraft.core.registries.BuiltInRegistries import net.minecraft.util.valueproviders.UniformInt import net.minecraft.world.level.block.AnvilBlock import net.minecraft.world.level.block.Block @@ -15,8 +17,10 @@ import net.minecraft.world.level.block.state.BlockBehaviour import net.minecraft.world.level.block.state.properties.NoteBlockInstrument import net.minecraft.world.level.material.MapColor import net.minecraft.world.level.material.PushReaction -import net.minecraftforge.eventbus.api.IEventBus -import net.minecraftforge.registries.ForgeRegistries +import net.neoforged.bus.api.IEventBus +import net.neoforged.neoforge.capabilities.BlockCapability +import net.neoforged.neoforge.capabilities.IBlockCapabilityProvider +import net.neoforged.neoforge.capabilities.RegisterCapabilitiesEvent import ru.dbotthepony.mc.otm.block.BlackHoleBlock import ru.dbotthepony.mc.otm.block.BlockExplosionDebugger import ru.dbotthepony.mc.otm.block.BlockSphereDebugger @@ -37,6 +41,7 @@ import ru.dbotthepony.mc.otm.block.decorative.LaboratoryLampLight import ru.dbotthepony.mc.otm.block.decorative.PainterBlock import ru.dbotthepony.mc.otm.block.decorative.TritaniumDoorBlock import ru.dbotthepony.mc.otm.block.decorative.TritaniumTrapdoorBlock +import ru.dbotthepony.mc.otm.block.entity.MatteryBlockEntity import ru.dbotthepony.mc.otm.block.entity.tech.EnergyHatchBlockEntity import ru.dbotthepony.mc.otm.block.entity.tech.ItemHatchBlockEntity import ru.dbotthepony.mc.otm.block.entity.tech.MatterHatchBlockEntity @@ -80,10 +85,28 @@ import ru.dbotthepony.mc.otm.core.collect.SupplierMap import java.util.function.Supplier object MBlocks { - private val registry = MDeferredRegister(ForgeRegistries.BLOCKS) + private val registry = MDeferredRegister(BuiltInRegistries.BLOCK) - internal fun register(bus: IEventBus) { + private fun registerCapabilities(event: RegisterCapabilitiesEvent) { + // ugly + for (cap in BlockCapability.getAll()) { + val provider = IBlockCapabilityProvider { level, pos, state, be, context: Direction? -> + if (be is MatteryBlockEntity) { + return@IBlockCapabilityProvider be.getCapability(cap as BlockCapability, context) + } + + return@IBlockCapabilityProvider null + } + + for (block in registry.entries.values) { + event.registerBlock(cap as BlockCapability, provider, block.value) + } + } + } + + fun register(bus: IEventBus) { registry.register(bus) + bus.addListener(::registerCapabilities) } val ANDROID_STATION = registry.coloredWithBase(MNames.ANDROID_STATION, ::AndroidStationBlock) @@ -150,14 +173,14 @@ object MBlocks { val MATTER_INPUT_HATCH by registry.register(MNames.MATTER_INPUT_HATCH) { HatchBlock(MatterHatchBlockEntity::input, true) } val MATTER_OUTPUT_HATCH by registry.register(MNames.MATTER_OUTPUT_HATCH) { HatchBlock(MatterHatchBlockEntity::output, true) } - val LIQUID_XP: LiquidBlock by registry.register("liquid_xp") { LiquidBlock(MFluids::LIQUID_XP, BlockBehaviour.Properties.of().mapColor(MapColor.EMERALD).replaceable().noCollission().strength(100.0f).pushReaction(PushReaction.DESTROY).noLootTable().liquid().sound(SoundType.EMPTY)) } + val LIQUID_XP: LiquidBlock by registry.register("liquid_xp") { LiquidBlock(MFluids.LIQUID_XP_FLOWING, BlockBehaviour.Properties.of().mapColor(MapColor.EMERALD).replaceable().noCollission().strength(100.0f).pushReaction(PushReaction.DESTROY).noLootTable().liquid().sound(SoundType.EMPTY)) } val TRITANIUM_ORE: Block by registry.register(MNames.TRITANIUM_ORE) { DropExperienceBlock( + UniformInt.of(0, 3), BlockBehaviour.Properties.of() .mapColor(MapColor.STONE) .strength(3.25f, 6.0f) .requiresCorrectToolForDrops(), - UniformInt.of(0, 3) ) } val TRITANIUM_INGOT_BLOCK: Block by registry.register(MNames.TRITANIUM_INGOT_BLOCK) { @@ -188,12 +211,12 @@ object MBlocks { } val DEEPSLATE_TRITANIUM_ORE: Block by registry.register(MNames.DEEPSLATE_TRITANIUM_ORE) { DropExperienceBlock( + UniformInt.of(0, 3), BlockBehaviour.Properties.of() .mapColor(MapColor.DEEPSLATE) .sound(SoundType.DEEPSLATE) .strength(4.75f, 6.5f) .requiresCorrectToolForDrops().sound(SoundType.DEEPSLATE), - UniformInt.of(0, 3) ) } val TRITANIUM_RAW_BLOCK: Block by registry.register(MNames.TRITANIUM_RAW_BLOCK) { Block( @@ -244,16 +267,16 @@ object MBlocks { ) } val TRITANIUM_STRIPED_STAIRS: Block by registry.register(MNames.TRITANIUM_STRIPED_STAIRS) { StairBlock( - { TRITANIUM_STRIPED_BLOCK.defaultBlockState() }, - BlockBehaviour.Properties.copy(TRITANIUM_STRIPED_BLOCK) + TRITANIUM_STRIPED_BLOCK.defaultBlockState(), + BlockBehaviour.Properties.ofLegacyCopy(TRITANIUM_STRIPED_BLOCK) ) } val TRITANIUM_STRIPED_SLAB: Block by registry.register(MNames.TRITANIUM_STRIPED_SLAB) { - SlabBlock(BlockBehaviour.Properties.copy(TRITANIUM_STRIPED_BLOCK)) + SlabBlock(BlockBehaviour.Properties.ofLegacyCopy(TRITANIUM_STRIPED_BLOCK)) } val TRITANIUM_STRIPED_WALL: Block by registry.register(MNames.TRITANIUM_STRIPED_WALL) { - WallBlock(BlockBehaviour.Properties.copy(TRITANIUM_STRIPED_BLOCK)) + WallBlock(BlockBehaviour.Properties.ofLegacyCopy(TRITANIUM_STRIPED_BLOCK)) } val CARBON_FIBRE_BLOCK: Block by registry.register(MNames.CARBON_FIBRE_BLOCK) { Block( diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MCreativeTabs.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MCreativeTabs.kt index 3379b32f3..91d7bfa36 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MCreativeTabs.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MCreativeTabs.kt @@ -1,27 +1,25 @@ package ru.dbotthepony.mc.otm.registry +import net.minecraft.core.registries.BuiltInRegistries import net.minecraft.core.registries.Registries -import net.minecraft.resources.ResourceLocation import net.minecraft.world.item.CreativeModeTab import net.minecraft.world.item.CreativeModeTabs import net.minecraft.world.item.DyeColor import net.minecraft.world.item.Item import net.minecraft.world.item.ItemStack import net.minecraft.world.level.material.Fluids -import net.minecraftforge.common.capabilities.ForgeCapabilities -import net.minecraftforge.event.BuildCreativeModeTabContentsEvent -import net.minecraftforge.eventbus.api.IEventBus -import net.minecraftforge.fluids.FluidStack -import net.minecraftforge.fluids.capability.IFluidHandler -import net.minecraftforge.registries.DeferredRegister -import net.minecraftforge.registries.ForgeRegistries +import net.neoforged.bus.api.IEventBus +import net.neoforged.neoforge.capabilities.Capabilities +import net.neoforged.neoforge.event.BuildCreativeModeTabContentsEvent +import net.neoforged.neoforge.fluids.FluidStack +import net.neoforged.neoforge.fluids.capability.IFluidHandler import ru.dbotthepony.mc.otm.OverdriveThatMatters -import ru.dbotthepony.mc.otm.capability.matter.matter +import ru.dbotthepony.mc.otm.capability.MatteryCapability import ru.dbotthepony.mc.otm.capability.matteryEnergy -import ru.dbotthepony.mc.otm.core.util.CreativeMenuItemComparator +import ru.dbotthepony.mc.otm.core.ResourceLocation import ru.dbotthepony.mc.otm.core.TranslatableComponent -import ru.dbotthepony.mc.otm.core.ifPresentK import ru.dbotthepony.mc.otm.core.registryName +import ru.dbotthepony.mc.otm.core.util.CreativeMenuItemComparator import ru.dbotthepony.mc.otm.registry.MItems.BATTERY_CREATIVE private fun CreativeModeTab.Output.accept(values: Collection) { @@ -99,11 +97,11 @@ private fun CreativeModeTab.Output.mattery(value: Item) { accept(value) val stack = ItemStack(value, 1) - val matter = stack.matter ?: throw IllegalArgumentException("${value.registryName} does not implement matter capability") + val matter = stack.getCapability(MatteryCapability.MATTER_ITEM) ?: throw IllegalArgumentException("${value.registryName} does not implement matter capability") matter.fillMatter() - if (ItemStack(value, 1).matter!!.storedMatter != matter.storedMatter) + if (ItemStack(value, 1).getCapability(MatteryCapability.MATTER_ITEM)!!.storedMatter != matter.storedMatter) accept(stack) } @@ -116,10 +114,10 @@ private fun CreativeModeTab.Output.mattery(values: Iterable) { private fun CreativeModeTab.Output.fluids(value: Item) { accept(value) - for (fluid in ForgeRegistries.FLUIDS.values) { + for (fluid in BuiltInRegistries.FLUID) { if (fluid != Fluids.EMPTY && fluid.isSource(fluid.defaultFluidState())) { accept(ItemStack(value, 1).also { - it.getCapability(ForgeCapabilities.FLUID_HANDLER_ITEM).ifPresentK { + it.getCapability(Capabilities.FluidHandler.ITEM)?.let { it.fill(FluidStack(fluid, it.getTankCapacity(0)), IFluidHandler.FluidAction.EXECUTE) } }) @@ -162,7 +160,6 @@ private fun addMainCreativeTabItems(consumer: CreativeModeTab.Output) { accept(MItems.TRITANIUM_ARMOR) energized(MItems.ENERGY_SWORD) - energized(MItems.PLASMA_RIFLE) accept(MItems.EXPLOSIVE_HAMMER) accept(ItemStack(MItems.EXPLOSIVE_HAMMER).also { MItems.EXPLOSIVE_HAMMER.prime(it) }) @@ -293,7 +290,7 @@ object MCreativeTabs { .build() } - internal fun initialize(bus: IEventBus) { + fun initialize(bus: IEventBus) { registry.register(bus) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MDamageTypes.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MDamageTypes.kt index a1af1bade..4066db2ad 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MDamageTypes.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MDamageTypes.kt @@ -5,6 +5,7 @@ import net.minecraft.resources.ResourceKey import net.minecraft.resources.ResourceLocation import net.minecraft.world.damagesource.DamageType import ru.dbotthepony.mc.otm.OverdriveThatMatters +import ru.dbotthepony.mc.otm.core.ResourceLocation object MDamageTypes { private fun register(name: String): ResourceKey = ResourceKey.create(Registries.DAMAGE_TYPE, ResourceLocation(OverdriveThatMatters.MOD_ID, name)) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MDataComponentTypes.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MDataComponentTypes.kt new file mode 100644 index 000000000..b7bd1a49c --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MDataComponentTypes.kt @@ -0,0 +1,71 @@ +package ru.dbotthepony.mc.otm.registry + +import com.mojang.serialization.Codec +import net.minecraft.core.UUIDUtil +import net.minecraft.core.component.DataComponentType +import net.minecraft.core.registries.BuiltInRegistries +import net.minecraft.network.RegistryFriendlyByteBuf +import net.minecraft.network.codec.StreamCodec +import net.neoforged.bus.api.IEventBus +import net.neoforged.neoforge.fluids.FluidStack +import ru.dbotthepony.mc.otm.capability.matter.PatternState +import ru.dbotthepony.mc.otm.container.ItemFilter +import ru.dbotthepony.mc.otm.core.math.Decimal +import ru.dbotthepony.mc.otm.data.DecimalCodec +import ru.dbotthepony.mc.otm.network.StreamCodecs +import java.util.UUID + +object MDataComponentTypes { + private val registry = MDeferredRegister(BuiltInRegistries.DATA_COMPONENT_TYPE) + + // class instead of object to preserve identity distinction for registry reversal search + private class DecimalComponent : DataComponentType { + override fun codec(): Codec { + return DecimalCodec + } + + override fun streamCodec(): StreamCodec { + return DecimalCodec.NETWORK + } + } + + val FLUID_STACK by registry.register("fluid_stack") { + object : DataComponentType { + override fun codec(): Codec { + return FluidStack.OPTIONAL_CODEC + } + + override fun streamCodec(): StreamCodec { + return FluidStack.OPTIONAL_STREAM_CODEC + } + } + } + + val BATTERY_LEVEL: DataComponentType by registry.register("battery_level") { DecimalComponent() } + val MAX_BATTERY_LEVEL: DataComponentType by registry.register("max_battery_level") { DecimalComponent() } + val MAX_BATTERY_INPUT: DataComponentType by registry.register("max_battery_input") { DecimalComponent() } + val MAX_BATTERY_OUTPUT: DataComponentType by registry.register("max_battery_output") { DecimalComponent() } + val MATTER_LEVEL: DataComponentType by registry.register("matter_level") { DecimalComponent() } + + val EXOPACK_SLOT_COUNT: DataComponentType by registry.register("exopack_slot_count") { DataComponentType.builder().persistent(Codec.INT).networkSynchronized(StreamCodecs.INT).build() } + val EXOPACK_UPGRADE_UUID: DataComponentType by registry.register("exopack_upgrade_uuid") { DataComponentType.builder().persistent(UUIDUtil.CODEC).networkSynchronized(UUIDUtil.STREAM_CODEC).build() } + val CONDENSATION_DRIVE_UUID: DataComponentType by registry.register("condensation_drive_uuid") { DataComponentType.builder().persistent(UUIDUtil.CODEC).networkSynchronized(UUIDUtil.STREAM_CODEC).build() } + val PATTERNS: DataComponentType> by registry.register("patterns") { DataComponentType.builder>().persistent(Codec.list(PatternState.CODEC)).build() } + val ITEM_FILTER: DataComponentType by registry.register("item_filter") { DataComponentType.builder().persistent(ItemFilter.CODEC).build() } + + val PRIMED by registry.register("primed") { + object : DataComponentType { + override fun codec(): Codec { + return Codec.BOOL + } + + override fun streamCodec(): StreamCodec { + return StreamCodecs.BOOLEAN + } + } + } + + fun register(bus: IEventBus) { + registry.register(bus) + } +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MDeferredRegister.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MDeferredRegister.kt index 24bb19ba8..89c14cfd6 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MDeferredRegister.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MDeferredRegister.kt @@ -1,35 +1,44 @@ package ru.dbotthepony.mc.otm.registry +import com.mojang.datafixers.util.Either import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap import net.minecraft.Util +import net.minecraft.core.Holder +import net.minecraft.core.HolderOwner import net.minecraft.core.Registry import net.minecraft.resources.ResourceKey import net.minecraft.resources.ResourceLocation +import net.minecraft.tags.TagKey import net.minecraft.world.item.DyeColor -import net.minecraftforge.eventbus.api.IEventBus -import net.minecraftforge.registries.IForgeRegistry -import net.minecraftforge.registries.RegisterEvent +import net.neoforged.bus.api.IEventBus +import net.neoforged.neoforge.capabilities.RegisterCapabilitiesEvent +import net.neoforged.neoforge.registries.RegisterEvent import org.apache.logging.log4j.LogManager import ru.dbotthepony.mc.otm.OverdriveThatMatters import ru.dbotthepony.mc.otm.SystemTime +import ru.dbotthepony.mc.otm.core.ResourceLocation import ru.dbotthepony.mc.otm.core.collect.SupplierMap -import java.util.LinkedList +import java.util.* import java.util.concurrent.FutureTask import java.util.concurrent.locks.LockSupport +import java.util.function.Predicate import java.util.function.Supplier +import java.util.stream.Stream import kotlin.reflect.KProperty /** * DeferredRegister which allows parallel initialization */ class MDeferredRegister(val registry: ResourceKey>, val modId: String = OverdriveThatMatters.MOD_ID, val allowParallel: Boolean = false) { - constructor(registry: IForgeRegistry, modId: String = OverdriveThatMatters.MOD_ID, allowParallel: Boolean = false) : this(registry.registryKey, modId, allowParallel) + constructor(registry: Registry, modId: String = OverdriveThatMatters.MOD_ID, allowParallel: Boolean = false) : this(registry.key(), modId, allowParallel) - private val entries = Object2ObjectLinkedOpenHashMap>() + private val entriesInternal = Object2ObjectLinkedOpenHashMap>() private var allowRegistration = true private var eventRegistered = false private val stages = ArrayList() + val entries: Map> = Collections.unmodifiableMap(entriesInternal) + private inner class RegistrationStage(val serial: Boolean) { private val entries = ArrayList>() @@ -37,17 +46,19 @@ class MDeferredRegister(val registry: ResourceKey>, val entries.add(entry) } - fun run(): List> { + fun run(registry: Registry) { + check(registry.key() == this@MDeferredRegister.registry) { "Hey." } + if (serial) { - LOGGER.debug("Serial registration of {} entries from {} for {}...", entries.size, modId, registry.location()) + LOGGER.debug("Serial registration of {} entries from {} for {}...", entries.size, modId, registry.key().location()) val t = SystemTime() - entries.forEach { it.initialize() } - LOGGER.debug("Serial registration of {} entries from {} for {} took {} ms", entries.size, modId, registry.location(), t.millis) + entries.forEach { it.initialize(registry) } + LOGGER.debug("Serial registration of {} entries from {} for {} took {} ms", entries.size, modId, registry.key().location(), t.millis) } else { - LOGGER.debug("Parallel registration of {} entries from {} for {}...", entries.size, modId, registry.location()) + LOGGER.debug("Parallel registration of {} entries from {} for {}...", entries.size, modId, registry.key().location()) val t = SystemTime() val futures = LinkedList>() - entries.forEach { futures.add(FutureTask(it::initialize)) } + entries.forEach { futures.add(FutureTask { it.initialize(registry) }) } futures.forEach { Util.backgroundExecutor().submit(it) } while (futures.isNotEmpty()) { @@ -60,19 +71,17 @@ class MDeferredRegister(val registry: ResourceKey>, val // memory barrier to avoid specifying _value as @Volatile LockSupport.parkNanos(1_000_000L) - LOGGER.debug("Parallel registration of {} entries from {} for {} took {} ms", entries.size, modId, registry.location(), t.millis) + LOGGER.debug("Parallel registration of {} entries from {} for {} took {} ms", entries.size, modId, registry.key().location(), t.millis) } - - return entries } } - inner class Entry(val name: String, private val factory: Supplier, serial: Boolean) : Supplier<@UnsafeVariance T>, Lazy { + inner class Entry(val name: String, private val factory: Supplier, serial: Boolean) : Supplier<@UnsafeVariance T>, Lazy, Holder { constructor(name: String, factory: Supplier) : this(name, factory, false) init { check(allowRegistration) { "Unable to register new entries after RegisterEvent has been fired" } - require(entries.put(name, this) == null) { "Duplicate entry $name for registry $registry" } + require(entriesInternal.put(name, this) == null) { "Duplicate entry $name for registry $registry" } val actualSerial = if (allowParallel) serial else true @@ -85,7 +94,58 @@ class MDeferredRegister(val registry: ResourceKey>, val } } - val key = ResourceLocation(modId, name) + val key: ResourceKey = ResourceKey.create(registry, ResourceLocation(modId, name)) + private var parentHolder: Holder? = null + + override fun value(): T { + return value + } + + override fun isBound(): Boolean { + return _value != null + } + + override fun `is`(p_205713_: ResourceLocation): Boolean { + return p_205713_ == key.location() + } + + override fun `is`(p_205712_: ResourceKey): Boolean { + return p_205712_ == key + } + + override fun `is`(p_205711_: Predicate>): Boolean { + return p_205711_.test(key) + } + + override fun `is`(p_205705_: TagKey): Boolean { + return parentHolder?.`is`(p_205705_) ?: false + } + + @Deprecated("Deprecated in Java") + override fun `is`(p_316447_: Holder): Boolean { + return p_316447_.`is`(key) + } + + override fun tags(): Stream> { + return parentHolder?.tags() ?: Stream.empty() + } + + override fun unwrap(): Either, R> { + return Either.left(key) + } + + override fun unwrapKey(): Optional> { + return Optional.of(key) + } + + override fun kind(): Holder.Kind { + return Holder.Kind.REFERENCE + } + + override fun canSerializeIn(p_255833_: HolderOwner): Boolean { + return parentHolder?.canSerializeIn(p_255833_) ?: false + } + private var _value: T? = null override val value: T get() { @@ -104,16 +164,17 @@ class MDeferredRegister(val registry: ResourceKey>, val return value } - fun initialize(): T { + fun initialize(registry: Registry): T { check(_value == null) { "Already initialized $name of $registry!" } - val getValue = try { + val compute = try { factory.get() } catch (err: Throwable) { throw RuntimeException("Unable to initialize registry entry $name of $registry", err) } - _value = getValue + _value = compute + parentHolder = Registry.registerForHolder(registry, key, compute) return value } } @@ -140,9 +201,7 @@ class MDeferredRegister(val registry: ResourceKey>, val allowRegistration = false for (stage in stages) { - stage.run().forEach { - event.register(registry, it.key, it) - } + stage.run(event.registry as Registry) } } } @@ -151,6 +210,17 @@ class MDeferredRegister(val registry: ResourceKey>, val check(!eventRegistered) { "Already registered!" } eventRegistered = true bus.addListener(this::onRegisterEvent) + bus.addListener(this::registerCapabilities) + } + + private fun registerCapabilities(event: RegisterCapabilitiesEvent) { + entriesInternal.values.forEach { + val value = it.value + + if (value is CapabilitiesRegisterListener) { + value.registerCapabilities(event) + } + } } companion object { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MEntityTypes.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MEntityTypes.kt index 237fa3885..149e14f7e 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MEntityTypes.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MEntityTypes.kt @@ -4,30 +4,29 @@ import net.minecraft.client.model.geom.ModelLayers import net.minecraft.client.renderer.entity.EntityRenderer import net.minecraft.client.renderer.entity.EntityRenderers import net.minecraft.client.renderer.entity.MinecartRenderer +import net.minecraft.core.registries.BuiltInRegistries import net.minecraft.world.entity.Entity import net.minecraft.world.entity.EntityType import net.minecraft.world.entity.MobCategory -import net.minecraftforge.eventbus.api.IEventBus -import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent -import net.minecraftforge.registries.DeferredRegister -import net.minecraftforge.registries.ForgeRegistries -import ru.dbotthepony.mc.otm.OverdriveThatMatters +import net.minecraft.world.item.DyeColor +import net.neoforged.bus.api.IEventBus +import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent import ru.dbotthepony.mc.otm.client.render.entity.PlasmaProjectileRenderer import ru.dbotthepony.mc.otm.entity.MinecartCargoCrate import ru.dbotthepony.mc.otm.entity.PlasmaProjectile object MEntityTypes { - private val registry = MDeferredRegister(ForgeRegistries.ENTITY_TYPES) + private val registry = MDeferredRegister(BuiltInRegistries.ENTITY_TYPE) - val PLASMA: EntityType<*> by registry.register(MNames.PLASMA) { - EntityType.Builder.of({ _, level -> PlasmaProjectile(level) }, MobCategory.MISC).sized(0.4f, 0.4f).build(MNames.PLASMA) + val PLASMA: EntityType by registry.register(MNames.PLASMA) { + EntityType.Builder.of({ _, level -> PlasmaProjectile(level) }, MobCategory.MISC).sized(0.4f, 0.4f).build(MNames.PLASMA) } - val CARGO_CRATE_MINECARTS = registry.coloredWithBase(MNames.MINECART_CARGO_CRATE) { color -> - EntityType.Builder.of({ it, level -> MinecartCargoCrate(it, color, level)}, MobCategory.MISC).sized(0.98F, 0.7F).clientTrackingRange(8).build("dfu doesn't works ✅") + val CARGO_CRATE_MINECARTS: Map> = registry.coloredWithBase(MNames.MINECART_CARGO_CRATE) { color -> + EntityType.Builder.of({ it, level -> MinecartCargoCrate(it, color, level)}, MobCategory.MISC).sized(0.98F, 0.7F).clientTrackingRange(8).build("dfu doesn't works ✅") } - internal fun register(bus: IEventBus) { + fun register(bus: IEventBus) { registry.register(bus) bus.addListener(this::registerClient) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MFluids.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MFluids.kt index 2212399a4..2bc9bd59f 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MFluids.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MFluids.kt @@ -1,30 +1,30 @@ package ru.dbotthepony.mc.otm.registry +import net.minecraft.core.registries.BuiltInRegistries import net.minecraft.resources.ResourceLocation import net.minecraft.sounds.SoundEvents import net.minecraft.world.item.Rarity -import net.minecraft.world.level.material.Fluid -import net.minecraftforge.client.extensions.common.IClientFluidTypeExtensions -import net.minecraftforge.common.SoundActions -import net.minecraftforge.eventbus.api.IEventBus -import net.minecraftforge.fluids.FluidType -import net.minecraftforge.fluids.ForgeFlowingFluid -import net.minecraftforge.registries.DeferredRegister -import net.minecraftforge.registries.ForgeRegistries +import net.neoforged.bus.api.IEventBus +import net.neoforged.neoforge.client.extensions.common.IClientFluidTypeExtensions +import net.neoforged.neoforge.common.SoundActions +import net.neoforged.neoforge.fluids.BaseFlowingFluid +import net.neoforged.neoforge.fluids.FluidType +import net.neoforged.neoforge.registries.NeoForgeRegistries import ru.dbotthepony.mc.otm.OverdriveThatMatters +import ru.dbotthepony.mc.otm.core.ResourceLocation import java.util.function.Consumer object MFluids { - private val types = MDeferredRegister(ForgeRegistries.Keys.FLUID_TYPES) - private val fluids = MDeferredRegister(ForgeRegistries.FLUIDS) + private val types = MDeferredRegister(NeoForgeRegistries.FLUID_TYPES.key()) + private val fluids = MDeferredRegister(BuiltInRegistries.FLUID) - internal fun register(bus: IEventBus) { + fun register(bus: IEventBus) { types.register(bus) fluids.register(bus) } - private fun makeXpProps(): ForgeFlowingFluid.Properties { - return ForgeFlowingFluid.Properties(::LIQUID_XP_TYPE, ::LIQUID_XP, ::LIQUID_XP_FLOWING).bucket(MItems::LIQUID_XP_BUCKET).block(MBlocks::LIQUID_XP) + private fun makeXpProps(): BaseFlowingFluid.Properties { + return BaseFlowingFluid.Properties(::LIQUID_XP_TYPE, ::LIQUID_XP, ::LIQUID_XP_FLOWING).bucket(MItems::LIQUID_XP_BUCKET).block(MBlocks::LIQUID_XP) } private val xpProps = makeXpProps() @@ -62,6 +62,6 @@ object MFluids { } } - val LIQUID_XP: ForgeFlowingFluid.Source by fluids.register("liquid_xp") { ForgeFlowingFluid.Source(xpProps) } - val LIQUID_XP_FLOWING: ForgeFlowingFluid.Flowing by fluids.register("liquid_xp_flowing") { ForgeFlowingFluid.Flowing(xpProps) } + val LIQUID_XP: BaseFlowingFluid.Source by fluids.register("liquid_xp") { BaseFlowingFluid.Source(xpProps) } + val LIQUID_XP_FLOWING: BaseFlowingFluid.Flowing by fluids.register("liquid_xp_flowing") { BaseFlowingFluid.Flowing(xpProps) } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MItemFunctionTypes.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MItemFunctionTypes.kt index 89052a1a9..f3afca109 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MItemFunctionTypes.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MItemFunctionTypes.kt @@ -2,8 +2,7 @@ package ru.dbotthepony.mc.otm.registry import net.minecraft.core.registries.Registries import net.minecraft.world.level.storage.loot.functions.LootItemFunctionType -import net.minecraftforge.eventbus.api.IEventBus -import net.minecraftforge.registries.DeferredRegister +import net.neoforged.bus.api.IEventBus import ru.dbotthepony.mc.otm.OverdriveThatMatters import ru.dbotthepony.mc.otm.data.loot.CopyTileNbtFunction import ru.dbotthepony.mc.otm.item.ProceduralBatteryItem @@ -12,11 +11,11 @@ import ru.dbotthepony.mc.otm.item.exopack.ProceduralExopackSlotUpgradeItem object MItemFunctionTypes { private val registry = MDeferredRegister(Registries.LOOT_FUNCTION_TYPE, OverdriveThatMatters.MOD_ID) - val COPY_TILE_NBT: LootItemFunctionType by registry.register("copy_tile_nbt") { LootItemFunctionType(CopyTileNbtFunction.CODEC) } - val PROCEDURAL_BATTERY: LootItemFunctionType by registry.register(MNames.PROCEDURAL_BATTERY) { LootItemFunctionType(ProceduralBatteryItem.Randomizer.CODEC) } - val PROCEDURAL_EXOPACK_UPGRADE: LootItemFunctionType by registry.register("exopack_upgrade") { LootItemFunctionType(ProceduralExopackSlotUpgradeItem.Randomizer.CODEC) } + val COPY_TILE_NBT by registry.register("copy_tile_nbt") { LootItemFunctionType(CopyTileNbtFunction.CODEC) } + val PROCEDURAL_BATTERY by registry.register(MNames.PROCEDURAL_BATTERY) { LootItemFunctionType(ProceduralBatteryItem.Randomizer.CODEC) } + val PROCEDURAL_EXOPACK_UPGRADE by registry.register("exopack_upgrade") { LootItemFunctionType(ProceduralExopackSlotUpgradeItem.Randomizer.CODEC) } - internal fun register(bus: IEventBus) { + fun register(bus: IEventBus) { registry.register(bus) } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MItemTags.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MItemTags.kt index cf19f67a7..3f04e15ad 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MItemTags.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MItemTags.kt @@ -5,6 +5,7 @@ import net.minecraft.tags.ItemTags import net.minecraft.tags.TagKey import net.minecraft.world.item.Item import ru.dbotthepony.mc.otm.OverdriveThatMatters +import ru.dbotthepony.mc.otm.core.ResourceLocation @Suppress("unused") object MItemTags { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MItems.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MItems.kt index b006169ff..0dea12847 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MItems.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MItems.kt @@ -1,60 +1,84 @@ package ru.dbotthepony.mc.otm.registry -import net.minecraft.ChatFormatting -import net.minecraft.network.chat.Component -import net.minecraft.resources.ResourceLocation +import net.minecraft.core.registries.BuiltInRegistries +import net.minecraft.tags.BlockTags import net.minecraft.world.food.FoodProperties -import net.minecraft.world.item.* +import net.minecraft.world.item.ArmorItem +import net.minecraft.world.item.BlockItem +import net.minecraft.world.item.BucketItem +import net.minecraft.world.item.DoubleHighBlockItem +import net.minecraft.world.item.DyeColor +import net.minecraft.world.item.HoeItem +import net.minecraft.world.item.Item import net.minecraft.world.item.Item.Properties +import net.minecraft.world.item.ItemStack +import net.minecraft.world.item.PickaxeItem +import net.minecraft.world.item.Rarity +import net.minecraft.world.item.ShearsItem +import net.minecraft.world.item.ShieldItem +import net.minecraft.world.item.ShovelItem +import net.minecraft.world.item.SwordItem +import net.minecraft.world.item.Tiers import net.minecraft.world.item.crafting.Ingredient -import net.minecraft.world.level.Level import net.minecraft.world.level.block.Block -import net.minecraftforge.common.ForgeTier -import net.minecraftforge.common.TierSortingRegistry -import net.minecraftforge.eventbus.api.IEventBus -import net.minecraftforge.registries.DeferredRegister -import net.minecraftforge.registries.ForgeRegistries -import net.minecraftforge.registries.RegistryObject -import ru.dbotthepony.mc.otm.OverdriveThatMatters +import net.neoforged.bus.api.IEventBus +import net.neoforged.neoforge.capabilities.RegisterCapabilitiesEvent +import net.neoforged.neoforge.common.SimpleTier import ru.dbotthepony.mc.otm.capability.ITieredUpgradeSet -import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability +import ru.dbotthepony.mc.otm.capability.MatteryPlayer import ru.dbotthepony.mc.otm.capability.UpgradeType import ru.dbotthepony.mc.otm.config.CablesConfig import ru.dbotthepony.mc.otm.config.ItemsConfig -import ru.dbotthepony.mc.otm.core.collect.SupplierList -import ru.dbotthepony.mc.otm.core.TranslatableComponent import ru.dbotthepony.mc.otm.core.addAll import ru.dbotthepony.mc.otm.core.asSupplierArray +import ru.dbotthepony.mc.otm.core.collect.SupplierList import ru.dbotthepony.mc.otm.core.collect.SupplierMap import ru.dbotthepony.mc.otm.core.math.Decimal -import ru.dbotthepony.mc.otm.item.* +import ru.dbotthepony.mc.otm.item.BatteryItem +import ru.dbotthepony.mc.otm.item.ChestUpgraderItem +import ru.dbotthepony.mc.otm.item.CrudeBatteryItem +import ru.dbotthepony.mc.otm.item.EssenceCapsuleItem +import ru.dbotthepony.mc.otm.item.EssenceServoItem +import ru.dbotthepony.mc.otm.item.FluidCapsuleItem +import ru.dbotthepony.mc.otm.item.FluidTankItem +import ru.dbotthepony.mc.otm.item.GravitationalDisruptorItem +import ru.dbotthepony.mc.otm.item.HealPillItem +import ru.dbotthepony.mc.otm.item.MatteryItem +import ru.dbotthepony.mc.otm.item.MinecartCargoCrateItem +import ru.dbotthepony.mc.otm.item.PillItem +import ru.dbotthepony.mc.otm.item.PillType +import ru.dbotthepony.mc.otm.item.PortableCondensationDriveItem +import ru.dbotthepony.mc.otm.item.ProceduralBatteryItem +import ru.dbotthepony.mc.otm.item.QuantumBatteryItem +import ru.dbotthepony.mc.otm.item.SimpleUpgrade +import ru.dbotthepony.mc.otm.item.ZPMItem +import ru.dbotthepony.mc.otm.item.addSimpleDescription +import ru.dbotthepony.mc.otm.item.armor.PortableGravitationStabilizerItem +import ru.dbotthepony.mc.otm.item.armor.SimpleTritaniumArmorItem +import ru.dbotthepony.mc.otm.item.armor.TritaniumArmorItem import ru.dbotthepony.mc.otm.item.exopack.ExopackProbeItem import ru.dbotthepony.mc.otm.item.exopack.ExopackSlotUpgradeItem +import ru.dbotthepony.mc.otm.item.exopack.ExopackUpgradeItem +import ru.dbotthepony.mc.otm.item.exopack.ProceduralExopackSlotUpgradeItem import ru.dbotthepony.mc.otm.item.matter.CreativePatternItem import ru.dbotthepony.mc.otm.item.matter.MatterCapacitorItem import ru.dbotthepony.mc.otm.item.matter.MatterDustItem import ru.dbotthepony.mc.otm.item.matter.PatternStorageItem -import ru.dbotthepony.mc.otm.item.weapon.EnergySwordItem import ru.dbotthepony.mc.otm.item.tool.ExplosiveHammerItem import ru.dbotthepony.mc.otm.item.tool.MatteryAxeItem -import ru.dbotthepony.mc.otm.item.armor.PortableGravitationStabilizerItem -import ru.dbotthepony.mc.otm.item.armor.SimpleTritaniumArmorItem -import ru.dbotthepony.mc.otm.item.armor.TritaniumArmorItem -import ru.dbotthepony.mc.otm.item.exopack.ExopackUpgradeItem -import ru.dbotthepony.mc.otm.item.exopack.ProceduralExopackSlotUpgradeItem -import ru.dbotthepony.mc.otm.item.weapon.PlasmaRifleItem +import ru.dbotthepony.mc.otm.item.weapon.EnergySwordItem import java.util.function.Supplier object MItems { private val DEFAULT_PROPERTIES = Properties() - private val registry = MDeferredRegister(ForgeRegistries.ITEMS) + private val registry = MDeferredRegister(BuiltInRegistries.ITEM) private fun register(name: String, blocks: Map, properties: Properties = DEFAULT_PROPERTIES): Map { return registry.coloredWithBase(name) { color -> BlockItem(blocks[color]!!, properties) } } - internal fun register(bus: IEventBus) { + fun register(bus: IEventBus) { registry.register(bus) } @@ -298,30 +322,23 @@ object MItems { val FLUID_CAPSULE: FluidCapsuleItem by registry.register("fluid_capsule") { FluidCapsuleItem(ItemsConfig::FLUID_CAPSULE_CAPACITY) } val FLUID_TANK: FluidTankItem by registry.register(MNames.FLUID_TANK) { FluidTankItem(MBlocks.FLUID_TANK, Item.Properties().stacksTo(1), ItemsConfig::FLUID_TANK_CAPACITY) } - val LIQUID_XP_BUCKET: BucketItem by registry.register("liquid_xp_bucket") { BucketItem(MFluids::LIQUID_XP, Item.Properties().stacksTo(1).rarity(Rarity.UNCOMMON)) } + val LIQUID_XP_BUCKET: BucketItem by registry.register("liquid_xp_bucket") { BucketItem(MFluids.LIQUID_XP, Item.Properties().stacksTo(1).rarity(Rarity.UNCOMMON)) } - val TRITANIUM_COMPONENT: ForgeTier = ForgeTier( - Tiers.IRON.level, + val TRITANIUM_COMPONENT: SimpleTier = SimpleTier( + BlockTags.INCORRECT_FOR_IRON_TOOL, 3072, Tiers.IRON.speed * 1.1f, 3.5f, 16, - MBlockTags.REQUIRES_TRITANIUM_TOOL ) { Ingredient.of(TRITANIUM_INGOT) } - val TRITANIUM_COMPONENT_NAME = ResourceLocation(OverdriveThatMatters.MOD_ID, "tritanium") - - init { - TierSortingRegistry.registerTier(TRITANIUM_COMPONENT, TRITANIUM_COMPONENT_NAME, listOf(Tiers.IRON), listOf(Tiers.DIAMOND)) - } - private val TOOLS_PROPRTIES = Item.Properties() - val TRITANIUM_SWORD: SwordItem by registry.register(MNames.TRITANIUM_SWORD) { SwordItem(TRITANIUM_COMPONENT, 4, -2.7f, TOOLS_PROPRTIES) } - val TRITANIUM_SHOVEL: ShovelItem by registry.register(MNames.TRITANIUM_SHOVEL) { ShovelItem(TRITANIUM_COMPONENT, 1.5f, -2.4f, TOOLS_PROPRTIES) } - val TRITANIUM_AXE: MatteryAxeItem by registry.register(MNames.TRITANIUM_AXE) { MatteryAxeItem(TRITANIUM_COMPONENT, 8.5f, -3.4f, TOOLS_PROPRTIES) } - val TRITANIUM_PICKAXE: PickaxeItem by registry.register(MNames.TRITANIUM_PICKAXE) { PickaxeItem(TRITANIUM_COMPONENT, 2, -2.8f, TOOLS_PROPRTIES) } - val TRITANIUM_HOE: HoeItem by registry.register(MNames.TRITANIUM_HOE) { HoeItem(TRITANIUM_COMPONENT, 0, -3.4f, TOOLS_PROPRTIES) } + val TRITANIUM_SWORD: SwordItem by registry.register(MNames.TRITANIUM_SWORD) { SwordItem(TRITANIUM_COMPONENT, TOOLS_PROPRTIES) } + val TRITANIUM_SHOVEL: ShovelItem by registry.register(MNames.TRITANIUM_SHOVEL) { ShovelItem(TRITANIUM_COMPONENT, TOOLS_PROPRTIES) } + val TRITANIUM_AXE: MatteryAxeItem by registry.register(MNames.TRITANIUM_AXE) { MatteryAxeItem(TRITANIUM_COMPONENT, TOOLS_PROPRTIES) } + val TRITANIUM_PICKAXE: PickaxeItem by registry.register(MNames.TRITANIUM_PICKAXE) { PickaxeItem(TRITANIUM_COMPONENT, TOOLS_PROPRTIES) } + val TRITANIUM_HOE: HoeItem by registry.register(MNames.TRITANIUM_HOE) { HoeItem(TRITANIUM_COMPONENT, TOOLS_PROPRTIES) } val TRITANIUM_SHEARS: ShearsItem by registry.register(MNames.TRITANIUM_SHEARS) { object : ShearsItem(Properties().durability(3072)) { override fun isValidRepairItem(pToRepair: ItemStack, pRepair: ItemStack): Boolean { return pRepair.`is`(MItemTags.TRITANIUM_INGOTS) @@ -371,8 +388,6 @@ object MItems { val ENERGY_SWORD: Item by registry.register(MNames.ENERGY_SWORD) { EnergySwordItem() } - val PLASMA_RIFLE: Item by registry.register(MNames.PLASMA_RIFLE) { PlasmaRifleItem() } - val BLACK_HOLE_SCANNER: Item by registry.register(MNames.BLACK_HOLE_SCANNER) { MatteryItem(DEFAULT_PROPERTIES).addSimpleDescription().addSimpleDescription("2") } val GRAVITATION_FIELD_LIMITER: Item by registry.register(MNames.GRAVITATION_FIELD_LIMITER) { Item(DEFAULT_PROPERTIES) } @@ -456,7 +471,7 @@ object MItems { val PORTABLE_CONDENSATION_DRIVE: Item by registry.register(MNames.PORTABLE_CONDENSATION_DRIVE) { PortableCondensationDriveItem(4000) } val PORTABLE_DENSE_CONDENSATION_DRIVE: Item by registry.register(MNames.PORTABLE_DENSE_CONDENSATION_DRIVE) { PortableCondensationDriveItem(25000) } - val NUTRIENT_PASTE: Item by registry.register(MNames.NUTRIENT_PASTE) { Item(Item.Properties().stacksTo(64).food(FoodProperties.Builder().meat().nutrition(8).saturationMod(0.9F).build())) } + val NUTRIENT_PASTE: Item by registry.register(MNames.NUTRIENT_PASTE) { Item(Properties().stacksTo(64).food(FoodProperties.Builder().nutrition(8).saturationModifier(0.9F).build())) } val LABORATORY_LAMP: Item by registry.register(MNames.LABORATORY_LAMP) { BlockItem(MBlocks.LABORATORY_LAMP, DEFAULT_PROPERTIES) } val LABORATORY_LAMP_INVERTED: Item by registry.register(MNames.LABORATORY_LAMP_INVERTED) { BlockItem(MBlocks.LABORATORY_LAMP_INVERTED, DEFAULT_PROPERTIES) } @@ -562,9 +577,9 @@ object MItems { object ExopackUpgrades { val INVENTORY_UPGRADE_CREATIVE: ExopackSlotUpgradeItem by registry.register("exosuit_inventory_upgrade_creative") { ExopackSlotUpgradeItem(null, 27, Rarity.EPIC) } - val CRAFTING_UPGRADE: ExopackUpgradeItem by registry.register("exosuit_crafting_upgrade") { ExopackUpgradeItem(MatteryPlayerCapability.UpgradeType.CRAFTING, "crafting_upgrade", "crafting_upgraded") } - val SMELTING_UPGRADE: ExopackUpgradeItem by registry.register("exopack_smelting_upgrade") { ExopackUpgradeItem(MatteryPlayerCapability.UpgradeType.SMELTING, "smelting_upgrade", "smelting_installed") } - val ENDER_UPGRADE: ExopackUpgradeItem by registry.register("exopack_ender_upgrade") { ExopackUpgradeItem(MatteryPlayerCapability.UpgradeType.ENDER_ACCESS, "ender_access_upgrade", "ender_access_installed") } + val CRAFTING_UPGRADE: ExopackUpgradeItem by registry.register("exosuit_crafting_upgrade") { ExopackUpgradeItem(MatteryPlayer.UpgradeType.CRAFTING, "crafting_upgrade", "crafting_upgraded") } + val SMELTING_UPGRADE: ExopackUpgradeItem by registry.register("exopack_smelting_upgrade") { ExopackUpgradeItem(MatteryPlayer.UpgradeType.SMELTING, "smelting_upgrade", "smelting_installed") } + val ENDER_UPGRADE: ExopackUpgradeItem by registry.register("exopack_ender_upgrade") { ExopackUpgradeItem(MatteryPlayer.UpgradeType.ENDER_ACCESS, "ender_access_upgrade", "ender_access_installed") } val INVENTORY_UPGRADES = SupplierList(8) { registry.register("exosuit_inventory_upgrade_$it") { ExopackSlotUpgradeItem(18, Rarity.COMMON) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MLootItemConditions.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MLootItemConditions.kt index 29a890a59..4b2f95d77 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MLootItemConditions.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MLootItemConditions.kt @@ -1,10 +1,8 @@ package ru.dbotthepony.mc.otm.registry -import net.minecraft.core.Registry import net.minecraft.core.registries.Registries import net.minecraft.world.level.storage.loot.predicates.LootItemConditionType -import net.minecraftforge.eventbus.api.IEventBus -import net.minecraftforge.registries.DeferredRegister +import net.neoforged.bus.api.IEventBus import ru.dbotthepony.mc.otm.OverdriveThatMatters import ru.dbotthepony.mc.otm.data.SingletonCodec import ru.dbotthepony.mc.otm.data.condition.ChanceWithPlaytimeCondition @@ -24,7 +22,7 @@ object MLootItemConditions { val KILLED_BY_REAL_PLAYER_OR_INDIRECTLY: LootItemConditionType by registry.register("killed_by_real_player_or_indirectly") { LootItemConditionType(SingletonCodec(KilledByRealPlayerOrIndirectly)) } val CHANCE: LootItemConditionType by registry.register("chance") { LootItemConditionType(ChanceCondition.CODEC) } - internal fun register(bus: IEventBus) { + fun register(bus: IEventBus) { registry.register(bus) } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MMenus.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MMenus.kt index 6beedd44e..912826c41 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MMenus.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MMenus.kt @@ -1,22 +1,22 @@ package ru.dbotthepony.mc.otm.registry -import net.minecraft.client.gui.screens.MenuScreens +import net.minecraft.core.registries.BuiltInRegistries import net.minecraft.world.flag.FeatureFlags import net.minecraft.world.inventory.MenuType -import net.minecraftforge.eventbus.api.IEventBus -import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent -import net.minecraftforge.registries.ForgeRegistries +import net.neoforged.bus.api.IEventBus +import net.neoforged.neoforge.client.event.RegisterMenuScreensEvent import ru.dbotthepony.mc.otm.block.entity.tech.AndroidChargerBlockEntity import ru.dbotthepony.mc.otm.client.screen.decorative.CargoCrateScreen import ru.dbotthepony.mc.otm.client.screen.decorative.FluidTankScreen import ru.dbotthepony.mc.otm.client.screen.decorative.HoloSignScreen import ru.dbotthepony.mc.otm.client.screen.decorative.MinecartCargoCrateScreen -import ru.dbotthepony.mc.otm.client.screen.matter.MatterReconstructorScreen +import ru.dbotthepony.mc.otm.client.screen.decorative.PainterScreen import ru.dbotthepony.mc.otm.client.screen.matter.MatterBottlerScreen import ru.dbotthepony.mc.otm.client.screen.matter.MatterCapacitorBankScreen import ru.dbotthepony.mc.otm.client.screen.matter.MatterDecomposerScreen import ru.dbotthepony.mc.otm.client.screen.matter.MatterEntanglerScreen import ru.dbotthepony.mc.otm.client.screen.matter.MatterPanelScreen +import ru.dbotthepony.mc.otm.client.screen.matter.MatterReconstructorScreen import ru.dbotthepony.mc.otm.client.screen.matter.MatterRecyclerScreen import ru.dbotthepony.mc.otm.client.screen.matter.MatterReplicatorScreen import ru.dbotthepony.mc.otm.client.screen.matter.MatterScannerScreen @@ -27,29 +27,29 @@ import ru.dbotthepony.mc.otm.client.screen.storage.ItemMonitorScreen import ru.dbotthepony.mc.otm.client.screen.storage.StorageBusScreen import ru.dbotthepony.mc.otm.client.screen.storage.StorageImporterExporterScreen import ru.dbotthepony.mc.otm.client.screen.storage.StoragePowerSupplierScreen +import ru.dbotthepony.mc.otm.client.screen.tech.AbstractProcessingMachineScreen import ru.dbotthepony.mc.otm.client.screen.tech.AndroidChargerScreen import ru.dbotthepony.mc.otm.client.screen.tech.AndroidStationScreen import ru.dbotthepony.mc.otm.client.screen.tech.BatteryBankScreen import ru.dbotthepony.mc.otm.client.screen.tech.ChemicalGeneratorScreen import ru.dbotthepony.mc.otm.client.screen.tech.CobblerScreen import ru.dbotthepony.mc.otm.client.screen.tech.EnergyCounterScreen +import ru.dbotthepony.mc.otm.client.screen.tech.EnergyHatchScreen import ru.dbotthepony.mc.otm.client.screen.tech.EnergyServoScreen import ru.dbotthepony.mc.otm.client.screen.tech.EssenceStorageScreen -import ru.dbotthepony.mc.otm.client.screen.decorative.PainterScreen -import ru.dbotthepony.mc.otm.client.screen.tech.AbstractProcessingMachineScreen -import ru.dbotthepony.mc.otm.client.screen.tech.EnergyHatchScreen import ru.dbotthepony.mc.otm.client.screen.tech.ItemHatchScreen import ru.dbotthepony.mc.otm.client.screen.tech.MatterHatchScreen import ru.dbotthepony.mc.otm.menu.decorative.CargoCrateMenu import ru.dbotthepony.mc.otm.menu.decorative.FluidTankMenu import ru.dbotthepony.mc.otm.menu.decorative.HoloSignMenu import ru.dbotthepony.mc.otm.menu.decorative.MinecartCargoCrateMenu -import ru.dbotthepony.mc.otm.menu.matter.MatterReconstructorMenu +import ru.dbotthepony.mc.otm.menu.decorative.PainterMenu import ru.dbotthepony.mc.otm.menu.matter.MatterBottlerMenu import ru.dbotthepony.mc.otm.menu.matter.MatterCapacitorBankMenu import ru.dbotthepony.mc.otm.menu.matter.MatterDecomposerMenu import ru.dbotthepony.mc.otm.menu.matter.MatterEntanglerMenu import ru.dbotthepony.mc.otm.menu.matter.MatterPanelMenu +import ru.dbotthepony.mc.otm.menu.matter.MatterReconstructorMenu import ru.dbotthepony.mc.otm.menu.matter.MatterRecyclerMenu import ru.dbotthepony.mc.otm.menu.matter.MatterReplicatorMenu import ru.dbotthepony.mc.otm.menu.matter.MatterScannerMenu @@ -66,17 +66,16 @@ import ru.dbotthepony.mc.otm.menu.tech.BatteryBankMenu import ru.dbotthepony.mc.otm.menu.tech.ChemicalGeneratorMenu import ru.dbotthepony.mc.otm.menu.tech.CobblerMenu import ru.dbotthepony.mc.otm.menu.tech.EnergyCounterMenu +import ru.dbotthepony.mc.otm.menu.tech.EnergyHatchMenu import ru.dbotthepony.mc.otm.menu.tech.EnergyServoMenu import ru.dbotthepony.mc.otm.menu.tech.EssenceStorageMenu -import ru.dbotthepony.mc.otm.menu.decorative.PainterMenu -import ru.dbotthepony.mc.otm.menu.tech.EnergyHatchMenu import ru.dbotthepony.mc.otm.menu.tech.ItemHatchMenu import ru.dbotthepony.mc.otm.menu.tech.MatterHatchMenu import ru.dbotthepony.mc.otm.menu.tech.PlatePressMenu import ru.dbotthepony.mc.otm.menu.tech.PoweredFurnaceMenu object MMenus { - private val registry = MDeferredRegister(ForgeRegistries.MENU_TYPES) + private val registry = MDeferredRegister(BuiltInRegistries.MENU) val ANDROID_STATION by registry.register(MNames.ANDROID_STATION) { MenuType(::AndroidStationMenu, FeatureFlags.VANILLA_SET) } val ANDROID_CHARGER by registry.register(MNames.ANDROID_CHARGER) { MenuType({ a, b -> AndroidChargerMenu(a, b, null as AndroidChargerBlockEntity?) }, FeatureFlags.VANILLA_SET) } @@ -120,53 +119,51 @@ object MMenus { val STORAGE_IMPORTER_EXPORTER by registry.register(MNames.STORAGE_IMPORTER) { MenuType(::StorageImporterExporterMenu, FeatureFlags.VANILLA_SET) } val STORAGE_POWER_SUPPLIER by registry.register(MNames.STORAGE_POWER_SUPPLIER) { MenuType(::StoragePowerSupplierMenu, FeatureFlags.VANILLA_SET) } - internal fun register(bus: IEventBus) { + fun register(bus: IEventBus) { registry.register(bus) - bus.addListener(this::registerClient) + bus.addListener(this::registerScreens) } - private fun registerClient(event: FMLClientSetupEvent) { - event.enqueueWork { - MenuScreens.register(ANDROID_STATION, ::AndroidStationScreen) - MenuScreens.register(ANDROID_CHARGER, ::AndroidChargerScreen) - MenuScreens.register(BATTERY_BANK, ::BatteryBankScreen) - MenuScreens.register(MATTER_DECOMPOSER, ::MatterDecomposerScreen) - MenuScreens.register(MATTER_CAPACITOR_BANK, ::MatterCapacitorBankScreen) - MenuScreens.register(PATTERN_STORAGE, ::PatternStorageScreen) - MenuScreens.register(MATTER_SCANNER, ::MatterScannerScreen) - MenuScreens.register(MATTER_PANEL, ::MatterPanelScreen) - MenuScreens.register(MATTER_REPLICATOR, ::MatterReplicatorScreen) - MenuScreens.register(MATTER_BOTTLER, ::MatterBottlerScreen) - MenuScreens.register(DRIVE_VIEWER, ::DriveViewerScreen) - MenuScreens.register(CARGO_CRATE, ::CargoCrateScreen) - MenuScreens.register(MINECART_CARGO_CRATE, ::MinecartCargoCrateScreen) - MenuScreens.register(DRIVE_RACK, ::DriveRackScreen) - MenuScreens.register(ITEM_MONITOR, ::ItemMonitorScreen) - MenuScreens.register(ENERGY_COUNTER, ::EnergyCounterScreen) - MenuScreens.register(CHEMICAL_GENERATOR, ::ChemicalGeneratorScreen) - MenuScreens.register(PLATE_PRESS, ::AbstractProcessingMachineScreen) - MenuScreens.register(TWIN_PLATE_PRESS, ::AbstractProcessingMachineScreen) - MenuScreens.register(MATTER_RECYCLER, ::MatterRecyclerScreen) - MenuScreens.register(STORAGE_BUS, ::StorageBusScreen) - MenuScreens.register(STORAGE_IMPORTER_EXPORTER, ::StorageImporterExporterScreen) - MenuScreens.register(STORAGE_POWER_SUPPLIER, ::StoragePowerSupplierScreen) - MenuScreens.register(ENERGY_SERVO, ::EnergyServoScreen) - MenuScreens.register(HOLO_SIGN, ::HoloSignScreen) - MenuScreens.register(COBBLESTONE_GENERATOR, ::CobblerScreen) - MenuScreens.register(ESSENCE_STORAGE, ::EssenceStorageScreen) - MenuScreens.register(ITEM_REPAIER, ::MatterReconstructorScreen) - MenuScreens.register(FLUID_TANK, ::FluidTankScreen) - MenuScreens.register(POWERED_FURNACE, ::AbstractProcessingMachineScreen) - MenuScreens.register(POWERED_BLAST_FURNACE, ::AbstractProcessingMachineScreen) - MenuScreens.register(POWERED_SMOKER, ::AbstractProcessingMachineScreen) - MenuScreens.register(PAINTER, ::PainterScreen) - MenuScreens.register(MATTER_ENTANGLER, ::MatterEntanglerScreen) - MenuScreens.register(ITEM_INPUT_HATCH, ::ItemHatchScreen) - MenuScreens.register(ITEM_OUTPUT_HATCH, ::ItemHatchScreen) - MenuScreens.register(MATTER_INPUT_HATCH, ::MatterHatchScreen) - MenuScreens.register(MATTER_OUTPUT_HATCH, ::MatterHatchScreen) - MenuScreens.register(ENERGY_INPUT_HATCH, ::EnergyHatchScreen) - MenuScreens.register(ENERGY_OUTPUT_HATCH, ::EnergyHatchScreen) - } + private fun registerScreens(event: RegisterMenuScreensEvent) { + event.register(ANDROID_STATION, ::AndroidStationScreen) + event.register(ANDROID_CHARGER, ::AndroidChargerScreen) + event.register(BATTERY_BANK, ::BatteryBankScreen) + event.register(MATTER_DECOMPOSER, ::MatterDecomposerScreen) + event.register(MATTER_CAPACITOR_BANK, ::MatterCapacitorBankScreen) + event.register(PATTERN_STORAGE, ::PatternStorageScreen) + event.register(MATTER_SCANNER, ::MatterScannerScreen) + event.register(MATTER_PANEL, ::MatterPanelScreen) + event.register(MATTER_REPLICATOR, ::MatterReplicatorScreen) + event.register(MATTER_BOTTLER, ::MatterBottlerScreen) + event.register(DRIVE_VIEWER, ::DriveViewerScreen) + event.register(CARGO_CRATE, ::CargoCrateScreen) + event.register(MINECART_CARGO_CRATE, ::MinecartCargoCrateScreen) + event.register(DRIVE_RACK, ::DriveRackScreen) + event.register(ITEM_MONITOR, ::ItemMonitorScreen) + event.register(ENERGY_COUNTER, ::EnergyCounterScreen) + event.register(CHEMICAL_GENERATOR, ::ChemicalGeneratorScreen) + event.register(PLATE_PRESS, ::AbstractProcessingMachineScreen) + event.register(TWIN_PLATE_PRESS, ::AbstractProcessingMachineScreen) + event.register(MATTER_RECYCLER, ::MatterRecyclerScreen) + event.register(STORAGE_BUS, ::StorageBusScreen) + event.register(STORAGE_IMPORTER_EXPORTER, ::StorageImporterExporterScreen) + event.register(STORAGE_POWER_SUPPLIER, ::StoragePowerSupplierScreen) + event.register(ENERGY_SERVO, ::EnergyServoScreen) + event.register(HOLO_SIGN, ::HoloSignScreen) + event.register(COBBLESTONE_GENERATOR, ::CobblerScreen) + event.register(ESSENCE_STORAGE, ::EssenceStorageScreen) + event.register(ITEM_REPAIER, ::MatterReconstructorScreen) + event.register(FLUID_TANK, ::FluidTankScreen) + event.register(POWERED_FURNACE, ::AbstractProcessingMachineScreen) + event.register(POWERED_BLAST_FURNACE, ::AbstractProcessingMachineScreen) + event.register(POWERED_SMOKER, ::AbstractProcessingMachineScreen) + event.register(PAINTER, ::PainterScreen) + event.register(MATTER_ENTANGLER, ::MatterEntanglerScreen) + event.register(ITEM_INPUT_HATCH, ::ItemHatchScreen) + event.register(ITEM_OUTPUT_HATCH, ::ItemHatchScreen) + event.register(MATTER_INPUT_HATCH, ::MatterHatchScreen) + event.register(MATTER_OUTPUT_HATCH, ::MatterHatchScreen) + event.register(ENERGY_INPUT_HATCH, ::EnergyHatchScreen) + event.register(ENERGY_OUTPUT_HATCH, ::EnergyHatchScreen) } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MNames.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MNames.kt index ffaf11717..d884f51ee 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MNames.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MNames.kt @@ -1,7 +1,7 @@ package ru.dbotthepony.mc.otm.registry -import net.minecraft.resources.ResourceLocation import ru.dbotthepony.mc.otm.OverdriveThatMatters +import ru.dbotthepony.mc.otm.core.ResourceLocation object MNames { const val LABORATORY_LAMP = "laboratory_lamp" diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MRecipes.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MRecipes.kt index 6be2006db..379d2403f 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MRecipes.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MRecipes.kt @@ -1,12 +1,9 @@ package ru.dbotthepony.mc.otm.registry -import net.minecraft.resources.ResourceLocation +import net.minecraft.core.registries.BuiltInRegistries import net.minecraft.world.item.crafting.Recipe import net.minecraft.world.item.crafting.RecipeType -import net.minecraftforge.eventbus.api.IEventBus -import net.minecraftforge.registries.DeferredRegister -import net.minecraftforge.registries.ForgeRegistries -import net.minecraftforge.registries.RegistryObject +import net.neoforged.bus.api.IEventBus import ru.dbotthepony.mc.otm.OverdriveThatMatters import ru.dbotthepony.mc.otm.core.ResourceLocation import ru.dbotthepony.mc.otm.recipe.* @@ -21,10 +18,10 @@ object MRecipes { } } - private val types = MDeferredRegister(ForgeRegistries.RECIPE_TYPES, OverdriveThatMatters.MOD_ID) - private val serializers = MDeferredRegister(ForgeRegistries.RECIPE_SERIALIZERS, OverdriveThatMatters.MOD_ID) + private val types = MDeferredRegister(BuiltInRegistries.RECIPE_TYPE, OverdriveThatMatters.MOD_ID) + private val serializers = MDeferredRegister(BuiltInRegistries.RECIPE_SERIALIZER, OverdriveThatMatters.MOD_ID) - internal fun register(bus: IEventBus) { + fun register(bus: IEventBus) { types.register(bus) serializers.register(bus) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MRegistry.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MRegistry.kt index ef9395342..9137cdb18 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MRegistry.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MRegistry.kt @@ -7,9 +7,9 @@ import net.minecraft.advancements.CriteriaTriggers import net.minecraft.client.renderer.item.ItemProperties import net.minecraft.core.BlockPos import net.minecraft.core.cauldron.CauldronInteraction +import net.minecraft.core.registries.BuiltInRegistries import net.minecraft.core.registries.Registries import net.minecraft.nbt.CompoundTag -import net.minecraft.resources.ResourceLocation import net.minecraft.world.entity.EntityType import net.minecraft.world.entity.ai.village.poi.PoiType import net.minecraft.world.entity.ai.village.poi.PoiTypes @@ -24,46 +24,34 @@ import net.minecraft.world.level.block.state.BlockBehaviour import net.minecraft.world.level.block.state.BlockState import net.minecraft.world.level.block.state.properties.NoteBlockInstrument import net.minecraft.world.level.material.MapColor -import net.minecraftforge.api.distmarker.Dist -import net.minecraftforge.client.event.RegisterColorHandlersEvent -import net.minecraftforge.client.event.RegisterItemDecorationsEvent -import net.minecraftforge.client.model.DynamicFluidContainerModel -import net.minecraftforge.eventbus.api.IEventBus -import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent -import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent -import net.minecraftforge.fml.loading.FMLEnvironment -import net.minecraftforge.registries.ForgeRegistries -import net.minecraftforge.registries.NewRegistryEvent -import net.minecraftforge.registries.RegisterEvent +import net.neoforged.bus.api.IEventBus +import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent +import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent +import net.neoforged.neoforge.client.event.RegisterColorHandlersEvent +import net.neoforged.neoforge.client.event.RegisterItemDecorationsEvent +import net.neoforged.neoforge.client.model.DynamicFluidContainerModel +import net.neoforged.neoforge.registries.NewRegistryEvent +import net.neoforged.neoforge.registries.RegisterEvent +import ru.dbotthepony.kommons.math.RGBAColor import ru.dbotthepony.mc.otm.OverdriveThatMatters -import ru.dbotthepony.mc.otm.android.AndroidResearchResult -import ru.dbotthepony.mc.otm.android.AndroidResearchResults import ru.dbotthepony.mc.otm.android.AndroidFeatureType -import ru.dbotthepony.mc.otm.android.AndroidResearchDescription -import ru.dbotthepony.mc.otm.android.AndroidResearchDescriptions import ru.dbotthepony.mc.otm.android.feature.EnderTeleporterFeature import ru.dbotthepony.mc.otm.android.feature.NanobotsArmorFeature import ru.dbotthepony.mc.otm.block.decorative.CargoCrateBlock import ru.dbotthepony.mc.otm.block.decorative.TritaniumPressurePlate import ru.dbotthepony.mc.otm.capability.matteryEnergy import ru.dbotthepony.mc.otm.client.MatteryGUI -import ru.dbotthepony.mc.otm.compat.vanilla.MatteryChestMenu +import ru.dbotthepony.mc.otm.core.ResourceLocation import ru.dbotthepony.mc.otm.core.math.BlockRotationFreedom import ru.dbotthepony.mc.otm.core.math.Decimal -import ru.dbotthepony.kommons.math.RGBAColor -import ru.dbotthepony.mc.otm.data.DecimalProvider import ru.dbotthepony.mc.otm.isClient import ru.dbotthepony.mc.otm.item.weapon.EnergySwordItem -import ru.dbotthepony.mc.otm.matter.AbstractRegistryAction -import ru.dbotthepony.mc.otm.matter.IMatterFunction import ru.dbotthepony.mc.otm.registry.objects.ColoredDecorativeBlock import ru.dbotthepony.mc.otm.registry.objects.DecorativeBlock import ru.dbotthepony.mc.otm.registry.objects.IBlockItemRegistryAcceptor import ru.dbotthepony.mc.otm.registry.objects.StripedColoredDecorativeBlock import ru.dbotthepony.mc.otm.shapes.BlockShapes -import ru.dbotthepony.mc.otm.storage.StorageStack import ru.dbotthepony.mc.otm.triggers.AndroidBatteryTrigger -import ru.dbotthepony.mc.otm.triggers.KillAsAndroidTrigger import ru.dbotthepony.mc.otm.triggers.AndroidResearchTrigger import ru.dbotthepony.mc.otm.triggers.AndroidTravelUnderwater import ru.dbotthepony.mc.otm.triggers.BecomeAndroidDeathTrigger @@ -79,6 +67,7 @@ import ru.dbotthepony.mc.otm.triggers.ExopackGainedSmeltingTrigger import ru.dbotthepony.mc.otm.triggers.ExopackObtainedTrigger import ru.dbotthepony.mc.otm.triggers.ExopackSlotsExpandedTrigger import ru.dbotthepony.mc.otm.triggers.FallDampenersSaveTrigger +import ru.dbotthepony.mc.otm.triggers.KillAsAndroidTrigger import ru.dbotthepony.mc.otm.triggers.NailedEntityTrigger import ru.dbotthepony.mc.otm.triggers.NanobotsArmorTrigger import ru.dbotthepony.mc.otm.triggers.ShockwaveDamageMobTrigger @@ -86,7 +75,7 @@ import ru.dbotthepony.mc.otm.triggers.ShockwaveTrigger import ru.dbotthepony.mc.otm.triggers.TakeItemOutOfReplicatorTrigger object MRegistry : IBlockItemRegistryAcceptor { - private val features = RegistryDelegate>("android_features") + private val features = RegistryDelegate>("android_features") { sync(true) } val ANDROID_FEATURES by features val ANDROID_FEATURES_LOCATION get() = features.location val ANDROID_FEATURES_KEY get() = features.key @@ -110,7 +99,7 @@ object MRegistry : IBlockItemRegistryAcceptor { DyeColor.YELLOW, ) - private fun register(event: NewRegistryEvent) { + fun register(event: NewRegistryEvent) { features.build(event) } @@ -155,16 +144,16 @@ object MRegistry : IBlockItemRegistryAcceptor { val TRITANIUM_STAIRS = DecorativeBlock(MNames.TRITANIUM_STAIRS) { StairBlock( { TRITANIUM_BLOCK.allBlocks[it]!!.defaultBlockState() }, - BlockBehaviour.Properties.copy(TRITANIUM_BLOCK.allBlocks[it]!!) + BlockBehaviour.Properties.ofFullCopy(TRITANIUM_BLOCK.allBlocks[it]!!) ) }.also { decorativeBlocks.add(it) } val TRITANIUM_SLAB = DecorativeBlock(MNames.TRITANIUM_SLAB) { - SlabBlock(BlockBehaviour.Properties.copy(TRITANIUM_BLOCK.allBlocks[it]!!)) + SlabBlock(BlockBehaviour.Properties.ofLegacyCopy(TRITANIUM_BLOCK.allBlocks[it]!!)) }.also { decorativeBlocks.add(it) } val TRITANIUM_WALL = DecorativeBlock(MNames.TRITANIUM_WALL) { - WallBlock(BlockBehaviour.Properties.copy(TRITANIUM_BLOCK.allBlocks[it]!!)) + WallBlock(BlockBehaviour.Properties.ofLegacyCopy(TRITANIUM_BLOCK.allBlocks[it]!!)) }.also { decorativeBlocks.add(it) } val TRITANIUM_PRESSURE_PLATE = DecorativeBlock(MNames.TRITANIUM_PRESSURE_PLATE, ::TritaniumPressurePlate).also { decorativeBlocks.add(it) } @@ -262,15 +251,15 @@ object MRegistry : IBlockItemRegistryAcceptor { }).also { decorativeBlocks.add(it) } val TRITANIUM_STRIPED_STAIRS = StripedColoredDecorativeBlock(MNames.TRITANIUM_STRIPED_STAIRS, { colorA, colorB -> - StairBlock({ TRITANIUM_STRIPED_BLOCK.getBlock(colorA, colorB).defaultBlockState() }, BlockBehaviour.Properties.copy(TRITANIUM_STRIPED_BLOCK.getBlock(colorA, colorB))) + StairBlock(TRITANIUM_STRIPED_BLOCK.getBlock(colorA, colorB).defaultBlockState(), BlockBehaviour.Properties.ofFullCopy(TRITANIUM_STRIPED_BLOCK.getBlock(colorA, colorB))) }).also { decorativeBlocks.add(it) } val TRITANIUM_STRIPED_SLAB = StripedColoredDecorativeBlock(MNames.TRITANIUM_STRIPED_SLAB, { colorA, colorB -> - SlabBlock(BlockBehaviour.Properties.copy(TRITANIUM_STRIPED_BLOCK.getBlock(colorA, colorB))) + SlabBlock(BlockBehaviour.Properties.ofFullCopy(TRITANIUM_STRIPED_BLOCK.getBlock(colorA, colorB))) }).also { decorativeBlocks.add(it) } val TRITANIUM_STRIPED_WALL = StripedColoredDecorativeBlock(MNames.TRITANIUM_STRIPED_WALL, { colorA, colorB -> - WallBlock(BlockBehaviour.Properties.copy(TRITANIUM_STRIPED_BLOCK.getBlock(colorA, colorB))) + WallBlock(BlockBehaviour.Properties.ofFullCopy(TRITANIUM_STRIPED_BLOCK.getBlock(colorA, colorB))) }).also { decorativeBlocks.add(it) } private fun registerEvent(event: RegisterEvent) { @@ -300,36 +289,6 @@ object MRegistry : IBlockItemRegistryAcceptor { if (isClient) bus.addListener(this::registerItemColorHandlers) if (isClient) bus.addListener(this::registerItemDecorators) - MCreativeTabs.initialize(bus) - - DecimalProvider.register(bus) - AndroidResearchDescription.register(bus) - AndroidResearchDescriptions.register(bus) - AndroidResearchResult.register(bus) - AndroidResearchResults.register(bus) - - AbstractRegistryAction.register(bus) - IMatterFunction.register(bus) - - MBlocks.register(bus) - MFluids.register(bus) - MBlockEntities.register(bus) - MEntityTypes.register(bus) - MMenus.register(bus) - MItems.register(bus) - AndroidFeatures.register(bus) - MSoundEvents.register(bus) - LootModifiers.register(bus) - MItemFunctionTypes.register(bus) - MLootItemConditions.register(bus) - MRecipes.register(bus) - StorageStack.register(bus) - MatteryChestMenu.register(bus) - - if (FMLEnvironment.dist == Dist.CLIENT) { - MBlockColors.register(bus) - } - // call static constructors NanobotsArmorFeature.Companion EnderTeleporterFeature.Companion @@ -381,13 +340,13 @@ object MRegistry : IBlockItemRegistryAcceptor { } ItemProperties.register(MItems.EXPLOSIVE_HAMMER, ResourceLocation(OverdriveThatMatters.MOD_ID, "is_primed")) { stack, level, entity, _ -> - if (MItems.EXPLOSIVE_HAMMER.isPrimed(stack)) { + if (MItems.EXPLOSIVE_HAMMER.isPrimed(stack) || entity == null) { 1f } else { - if ((entity?.useItemRemainingTicks ?: 0) <= 0) { + if (entity.useItemRemainingTicks <= 0) { 0f } else { - (stack.useDuration - (entity?.useItemRemainingTicks ?: stack.useDuration)).toFloat() / stack.useDuration + (stack.getUseDuration(entity) - entity.useItemRemainingTicks).toFloat() / stack.getUseDuration(entity) } } } @@ -420,7 +379,7 @@ object MRegistry : IBlockItemRegistryAcceptor { } private fun registerItemDecorators(event: RegisterItemDecorationsEvent) { - ForgeRegistries.ITEMS.forEach { + BuiltInRegistries.ITEM.forEach { if (it is ShieldItem) { event.register(it, MatteryGUI::renderShieldCooldownOverlay) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MSoundEvents.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MSoundEvents.kt index 56946d77c..83c32d073 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MSoundEvents.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MSoundEvents.kt @@ -1,17 +1,13 @@ package ru.dbotthepony.mc.otm.registry -import net.minecraft.resources.ResourceLocation +import net.minecraft.core.registries.BuiltInRegistries import net.minecraft.sounds.SoundEvent -import net.minecraft.sounds.SoundEvents -import net.minecraft.world.entity.EntityType -import net.minecraftforge.eventbus.api.IEventBus -import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext -import net.minecraftforge.registries.DeferredRegister -import net.minecraftforge.registries.ForgeRegistries +import net.neoforged.bus.api.IEventBus import ru.dbotthepony.mc.otm.OverdriveThatMatters +import ru.dbotthepony.mc.otm.core.ResourceLocation object MSoundEvents { - private val registry: MDeferredRegister = MDeferredRegister(ForgeRegistries.SOUND_EVENTS, OverdriveThatMatters.MOD_ID) + private val registry: MDeferredRegister = MDeferredRegister(BuiltInRegistries.SOUND_EVENT, OverdriveThatMatters.MOD_ID) // TODO: 1.19.3 private fun make(name: String): MDeferredRegister.Entry = registry.register(name) { SoundEvent.createVariableRangeEvent(ResourceLocation(OverdriveThatMatters.MOD_ID, name)) } @@ -25,7 +21,7 @@ object MSoundEvents { val ANDROID_SHOCKWAVE by make("android.shockwave") val ANDROID_PROJ_PARRY by make("android.projectile_parry") - internal fun register(bus: IEventBus) { + fun register(bus: IEventBus) { registry.register(bus) } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/RegistryDelegate.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/RegistryDelegate.kt index 784b775c3..fc412a415 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/RegistryDelegate.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/RegistryDelegate.kt @@ -2,20 +2,18 @@ package ru.dbotthepony.mc.otm.registry import net.minecraft.core.Registry import net.minecraft.resources.ResourceKey -import net.minecraft.resources.ResourceLocation -import net.minecraftforge.registries.ForgeRegistry -import net.minecraftforge.registries.IForgeRegistry -import net.minecraftforge.registries.NewRegistryEvent -import net.minecraftforge.registries.RegistryBuilder +import net.neoforged.neoforge.registries.NewRegistryEvent +import net.neoforged.neoforge.registries.RegistryBuilder import ru.dbotthepony.mc.otm.OverdriveThatMatters +import ru.dbotthepony.mc.otm.core.ResourceLocation import java.util.function.Supplier import kotlin.properties.ReadOnlyProperty import kotlin.reflect.KProperty -class RegistryDelegate(key: String, private val configurator: RegistryBuilder.() -> Unit = {}) : ReadOnlyProperty>, Supplier>, Lazy> { - private var _value: Supplier?>? = null +class RegistryDelegate(key: String, private val configurator: RegistryBuilder.() -> Unit = {}) : ReadOnlyProperty>, Supplier>, Lazy> { + private var _value: Registry? = null - override val value: ForgeRegistry + override val value: Registry get() = get() override fun isInitialized(): Boolean { @@ -25,12 +23,12 @@ class RegistryDelegate(key: String, private val configurator: RegistryBuilder val location = ResourceLocation(OverdriveThatMatters.MOD_ID, key) val key: ResourceKey> = ResourceKey.createRegistryKey(location) - override fun get(): ForgeRegistry { - val supp = _value ?: throw IllegalStateException("Tried to access uninitialized registry $location") - return supp.get() as ForgeRegistry? ?: throw IllegalStateException("Accessing registry $location too early") + override fun get(): Registry { + val value = _value ?: throw IllegalStateException("Tried to access uninitialized registry $location") + return value } - override fun getValue(thisRef: Any, property: KProperty<*>): ForgeRegistry { + override fun getValue(thisRef: Any, property: KProperty<*>): Registry { return get() } @@ -39,9 +37,7 @@ class RegistryDelegate(key: String, private val configurator: RegistryBuilder throw IllegalStateException("Already built registry $location!") } - _value = RegistryBuilder().let { - it.setName(location) - // it.type = AndroidFeatureType::class.java + _value = RegistryBuilder(key).let { configurator.invoke(it) event.create(it) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/objects/ColoredDecorativeBlock.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/objects/ColoredDecorativeBlock.kt index 4416da20d..1b1a52221 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/objects/ColoredDecorativeBlock.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/objects/ColoredDecorativeBlock.kt @@ -5,8 +5,6 @@ import net.minecraft.world.item.DyeColor import net.minecraft.world.item.Item import net.minecraft.world.level.block.Block import net.minecraft.world.level.block.state.BlockBehaviour -import net.minecraftforge.registries.DeferredRegister -import net.minecraftforge.registries.RegistryObject import ru.dbotthepony.mc.otm.core.collect.SupplierMap import ru.dbotthepony.mc.otm.registry.MDeferredRegister import ru.dbotthepony.mc.otm.registry.MRegistry diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/objects/StripedColoredDecorativeBlock.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/objects/StripedColoredDecorativeBlock.kt index c0a68796d..63f2b57cb 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/objects/StripedColoredDecorativeBlock.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/objects/StripedColoredDecorativeBlock.kt @@ -6,8 +6,6 @@ import net.minecraft.world.item.BlockItem import net.minecraft.world.item.DyeColor import net.minecraft.world.item.Item import net.minecraft.world.level.block.Block -import net.minecraftforge.registries.DeferredRegister -import net.minecraftforge.registries.RegistryObject import ru.dbotthepony.mc.otm.core.collect.SupplierList import ru.dbotthepony.mc.otm.core.collect.SupplierMap import ru.dbotthepony.mc.otm.registry.MDeferredRegister diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/saveddata/SavedCountingMap.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/saveddata/SavedCountingMap.kt index 42263a437..087240065 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/saveddata/SavedCountingMap.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/saveddata/SavedCountingMap.kt @@ -2,6 +2,7 @@ package ru.dbotthepony.mc.otm.saveddata import it.unimi.dsi.fastutil.ints.Int2ObjectAVLTreeMap import it.unimi.dsi.fastutil.ints.Int2ObjectFunction +import net.minecraft.core.HolderLookup import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.IntTag import net.minecraft.nbt.ListTag @@ -84,7 +85,7 @@ class SavedCountingMap private constructor( return computeIfAbsent(nextIndex++) } - override fun save(output: CompoundTag): CompoundTag { + override fun save(output: CompoundTag, registry: HolderLookup.Provider): CompoundTag { output["map"] = ListTag().also { for ((key, value) in this.map) { val compound = CompoundTag() diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/storage/ItemStorageStack.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/storage/ItemStorageStack.kt index c58cbf17f..a2afdabd3 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/storage/ItemStorageStack.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/storage/ItemStorageStack.kt @@ -29,19 +29,19 @@ class ItemStorageStack private constructor(private val stack: ItemStack, count: } override fun equals(other: Any?): Boolean { - return other is ItemStorageStack && other.count == count && ItemStack.isSameItemSameTags(stack, other.stack) + return other is ItemStorageStack && other.count == count && ItemStack.isSameItemSameComponents(stack, other.stack) } override fun hashCode(): Int { - return Integer.rotateLeft(count.hashCode(), 12) xor (stack.item.hashCode() * 31 + stack.tag.hashCode()) + return Integer.rotateLeft(count.hashCode(), 12) xor (stack.item.hashCode() * 31 + stack.components.hashCode()) } override fun equalsWithoutCount(other: StorageStack<*>): Boolean { - return other is ItemStorageStack && ItemStack.isSameItemSameTags(stack, other.stack) + return other is ItemStorageStack && ItemStack.isSameItemSameComponents(stack, other.stack) } override fun hashCodeWithoutCount(): Int { - return stack.item.hashCode() * 31 + stack.tag.hashCode() + return stack.item.hashCode() * 31 + stack.components.hashCode() } override val isEmpty: Boolean = stack.isEmpty || super.isEmpty diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/storage/StorageStack.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/storage/StorageStack.kt index 6b161f570..e2e28eb23 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/storage/StorageStack.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/storage/StorageStack.kt @@ -1,17 +1,17 @@ package ru.dbotthepony.mc.otm.storage import it.unimi.dsi.fastutil.Hash -import net.minecraft.network.FriendlyByteBuf +import net.minecraft.network.RegistryFriendlyByteBuf import net.minecraft.world.item.ItemStack -import net.minecraftforge.eventbus.api.IEventBus -import net.minecraftforge.registries.DeferredRegister -import ru.dbotthepony.kommons.util.getValue +import net.neoforged.bus.api.IEventBus import ru.dbotthepony.mc.otm.OverdriveThatMatters import ru.dbotthepony.mc.otm.core.getValue import ru.dbotthepony.mc.otm.core.math.Decimal import ru.dbotthepony.mc.otm.core.readBigInteger +import ru.dbotthepony.mc.otm.core.readItem import ru.dbotthepony.mc.otm.core.writeBigInteger -import ru.dbotthepony.mc.otm.core.writeItemType +import ru.dbotthepony.mc.otm.core.writeItem +import ru.dbotthepony.mc.otm.registry.MDeferredRegister import ru.dbotthepony.mc.otm.registry.RegistryDelegate import java.math.BigInteger @@ -54,15 +54,15 @@ abstract class StorageStack>(val count: BigInteger) { return copy(newCount) } - fun write(buff: FriendlyByteBuf) { + fun write(buff: RegistryFriendlyByteBuf) { type.write(buff, this as S) } interface Type> { val empty: T - fun read(buff: FriendlyByteBuf): T - fun write(buff: FriendlyByteBuf, value: T) + fun read(buff: RegistryFriendlyByteBuf): T + fun write(buff: RegistryFriendlyByteBuf, value: T) /** * If there is not enough energy for operation, it is completely cancelled @@ -83,14 +83,14 @@ abstract class StorageStack>(val count: BigInteger) { class SimpleType>( val energyPerOperation: Decimal, override val empty: T, - private val read: (FriendlyByteBuf) -> T, - private val write: (FriendlyByteBuf, T) -> Unit + private val read: (RegistryFriendlyByteBuf) -> T, + private val write: (RegistryFriendlyByteBuf, T) -> Unit ) : Type { - override fun read(buff: FriendlyByteBuf): T { + override fun read(buff: RegistryFriendlyByteBuf): T { return read.invoke(buff) } - override fun write(buff: FriendlyByteBuf, value: T) { + override fun write(buff: RegistryFriendlyByteBuf, value: T) { write.invoke(buff, value) } @@ -110,11 +110,11 @@ abstract class StorageStack>(val count: BigInteger) { return o?.hashCodeWithoutCount() ?: 0 } - private val delegate = RegistryDelegate>("stack_type") { disableSaving() } + private val delegate = RegistryDelegate>("stack_type") {} val REGISTRY by delegate val REGISTRY_KEY by delegate::key - private val registrar = DeferredRegister.create(REGISTRY_KEY, OverdriveThatMatters.MOD_ID) + private val registrar = MDeferredRegister(REGISTRY_KEY, OverdriveThatMatters.MOD_ID) val ITEMS: Type by registrar.register("items") { SimpleType( @@ -130,7 +130,7 @@ abstract class StorageStack>(val count: BigInteger) { ) } - internal fun register(bus: IEventBus) { + fun register(bus: IEventBus) { bus.addListener(delegate::build) registrar.register(bus) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/triggers/AndroidResearchTrigger.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/triggers/AndroidResearchTrigger.kt index 800d22894..a761cc0bb 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/triggers/AndroidResearchTrigger.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/triggers/AndroidResearchTrigger.kt @@ -7,6 +7,7 @@ import net.minecraft.resources.ResourceLocation import net.minecraft.server.level.ServerPlayer import ru.dbotthepony.mc.otm.OverdriveThatMatters import ru.dbotthepony.mc.otm.android.AndroidResearchType +import ru.dbotthepony.mc.otm.core.ResourceLocation import java.util.* import java.util.function.Predicate @@ -18,7 +19,7 @@ object AndroidResearchTrigger : MCriterionTrigger = RecordCodecBuilder.create { it.group( ResourceLocation.CODEC.optionalFieldOf("research").forGetter(Instance::research), - playerPredicateCodec.forGetter(Instance::playerPredicate) + ContextAwarePredicate.CODEC.optionalFieldOf("player").forGetter(Instance::playerPredicate) ).apply(it, ::Instance) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/triggers/AndroidTravelUnderwater.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/triggers/AndroidTravelUnderwater.kt index 94d02e89d..c2039f212 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/triggers/AndroidTravelUnderwater.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/triggers/AndroidTravelUnderwater.kt @@ -6,6 +6,7 @@ import net.minecraft.advancements.critereon.ContextAwarePredicate import net.minecraft.resources.ResourceLocation import net.minecraft.server.level.ServerPlayer import ru.dbotthepony.mc.otm.OverdriveThatMatters +import ru.dbotthepony.mc.otm.core.ResourceLocation import ru.dbotthepony.mc.otm.data.minRange import java.util.* @@ -17,7 +18,7 @@ object AndroidTravelUnderwater : MCriterionTrigger = RecordCodecBuilder.create { it.group( Codec.DOUBLE.minRange(0.0).fieldOf("distanceToTravel").forGetter(Instance::distanceToTravel), - playerPredicateCodec.forGetter(Instance::playerPredicate) + ContextAwarePredicate.CODEC.optionalFieldOf("player").forGetter(Instance::playerPredicate) ).apply(it, ::Instance) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/triggers/ExopackTriggers.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/triggers/ExopackTriggers.kt index 1f8523669..98228bd13 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/triggers/ExopackTriggers.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/triggers/ExopackTriggers.kt @@ -6,6 +6,7 @@ import net.minecraft.advancements.critereon.ContextAwarePredicate import net.minecraft.resources.ResourceLocation import net.minecraft.server.level.ServerPlayer import ru.dbotthepony.mc.otm.OverdriveThatMatters +import ru.dbotthepony.mc.otm.core.ResourceLocation import java.util.* val ExopackObtainedTrigger = SingletonTrigger(ResourceLocation(OverdriveThatMatters.MOD_ID, "exopack_obtained")) @@ -20,7 +21,7 @@ object ExopackSlotsExpandedTrigger : MCriterionTrigger = RecordCodecBuilder.create { it.group( - predicateCodec.optionalFieldOf("predicate").forGetter(Instance::predicate), + ContextAwarePredicate.CODEC.optionalFieldOf("predicate").forGetter(Instance::predicate), DamagePredicateCodec.optionalFieldOf("damagePredicate").forGetter(Instance::damagePredicate), - playerPredicateCodec.forGetter(Instance::playerPredicate) + ContextAwarePredicate.CODEC.optionalFieldOf("player").forGetter(Instance::playerPredicate) ).apply(it, ::Instance) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/triggers/ItemTrigger.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/triggers/ItemTrigger.kt index a7cd9c923..f7c716c17 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/triggers/ItemTrigger.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/triggers/ItemTrigger.kt @@ -11,14 +11,14 @@ import java.util.* class ItemTrigger(id: ResourceLocation) : MCriterionTrigger(id) { fun trigger(player: ServerPlayer, item: ItemStack) { - trigger(player) { if (it.invert) !it.predicate.matches(item) else it.predicate.matches(item) } + trigger(player) { if (it.invert) !it.predicate.test(item) else it.predicate.test(item) } } override val codec: Codec = RecordCodecBuilder.create { it.group( ItemPredicate.CODEC.fieldOf("predicate").forGetter(Instance::predicate), Codec.BOOL.optionalFieldOf("invert", false).forGetter(Instance::invert), - playerPredicateCodec.forGetter(Instance::playerPredicate) + ContextAwarePredicate.CODEC.optionalFieldOf("player").forGetter(Instance::playerPredicate) ).apply(it, ::Instance) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/triggers/KillAsAndroidTrigger.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/triggers/KillAsAndroidTrigger.kt index 432303360..d0b374989 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/triggers/KillAsAndroidTrigger.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/triggers/KillAsAndroidTrigger.kt @@ -2,16 +2,18 @@ package ru.dbotthepony.mc.otm.triggers import com.google.common.collect.ImmutableList import com.mojang.serialization.Codec +import com.mojang.serialization.MapCodec import com.mojang.serialization.codecs.RecordCodecBuilder import net.minecraft.advancements.critereon.* import net.minecraft.resources.ResourceLocation import net.minecraft.server.level.ServerPlayer import net.minecraft.util.StringRepresentable import net.minecraft.world.entity.monster.ElderGuardian -import net.minecraftforge.event.entity.living.LivingDeathEvent +import net.neoforged.neoforge.event.entity.living.LivingDeathEvent import ru.dbotthepony.mc.otm.OverdriveThatMatters -import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability +import ru.dbotthepony.mc.otm.capability.MatteryPlayer import ru.dbotthepony.mc.otm.capability.matteryPlayer +import ru.dbotthepony.mc.otm.core.ResourceLocation import ru.dbotthepony.mc.otm.data.SingletonCodec import ru.dbotthepony.mc.otm.registry.MRegistry import java.util.Optional @@ -22,33 +24,33 @@ object KillAsAndroidTrigger : MCriterionTrigger(R override val codec: Codec = RecordCodecBuilder.create { it.group( - predicateCodec.optionalFieldOf("entityPredicate").forGetter(Instance::predicate), + ContextAwarePredicate.CODEC.optionalFieldOf("entityPredicate").forGetter(Instance::predicate), FEATURE_CODEC.fieldOf("featurePredicate").forGetter(Instance::featurePredicate), - playerPredicateCodec.forGetter(Instance::playerPredicate) + ContextAwarePredicate.CODEC.optionalFieldOf("player").forGetter(Instance::playerPredicate) ).apply(it, ::Instance) } - enum class PredicateType(codec: Lazy>) : StringRepresentable { + enum class PredicateType(codec: Lazy>) : StringRepresentable { ALWAYS(lazy { SingletonCodec(Always) }), HAS(lazy { - RecordCodecBuilder.create { + RecordCodecBuilder.mapCodec { it.group(ResourceLocation.CODEC.fieldOf("name").forGetter(Has::name)).apply(it, ::Has) } }), NOT(lazy { - RecordCodecBuilder.create { + RecordCodecBuilder.mapCodec { it.group(FEATURE_CODEC.fieldOf("parent").forGetter(Not::parent)).apply(it, ::Not) } }), AND(lazy { - RecordCodecBuilder.create { + RecordCodecBuilder.mapCodec { it.group(FEATURE_CODEC.listOf().fieldOf("children").forGetter(And::children)).apply(it, ::And) } }), OR(lazy { - RecordCodecBuilder.create { + RecordCodecBuilder.mapCodec { it.group(FEATURE_CODEC.listOf().fieldOf("children").forGetter(OrPredicate::children)).apply(it, ::OrPredicate) } }); @@ -60,7 +62,7 @@ object KillAsAndroidTrigger : MCriterionTrigger(R } } - abstract class FeaturePredicate : Predicate { + abstract class FeaturePredicate : Predicate { abstract val type: PredicateType } @@ -68,18 +70,18 @@ object KillAsAndroidTrigger : MCriterionTrigger(R override val type: PredicateType get() = PredicateType.ALWAYS - override fun test(t: MatteryPlayerCapability): Boolean { + override fun test(t: MatteryPlayer): Boolean { return true } } class Has(val name: ResourceLocation) : FeaturePredicate() { - private val resolved by lazy { MRegistry.ANDROID_FEATURES.getValue(name) } + private val resolved by lazy { MRegistry.ANDROID_FEATURES.get(name) } override val type: PredicateType get() = PredicateType.HAS - override fun test(t: MatteryPlayerCapability): Boolean { + override fun test(t: MatteryPlayer): Boolean { return t.hasFeature(resolved ?: return false) } } @@ -88,7 +90,7 @@ object KillAsAndroidTrigger : MCriterionTrigger(R override val type: PredicateType get() = PredicateType.NOT - override fun test(t: MatteryPlayerCapability): Boolean { + override fun test(t: MatteryPlayer): Boolean { return !parent.test(t) } } @@ -99,7 +101,7 @@ object KillAsAndroidTrigger : MCriterionTrigger(R override val type: PredicateType get() = PredicateType.AND - override fun test(t: MatteryPlayerCapability): Boolean { + override fun test(t: MatteryPlayer): Boolean { return children.all { it.test(t) } } } @@ -110,7 +112,7 @@ object KillAsAndroidTrigger : MCriterionTrigger(R override val type: PredicateType get() = PredicateType.OR - override fun test(t: MatteryPlayerCapability): Boolean { + override fun test(t: MatteryPlayer): Boolean { return children.any { it.test(t) } } } @@ -126,7 +128,7 @@ object KillAsAndroidTrigger : MCriterionTrigger(R val killer = event.source.entity if (killer is ServerPlayer) { - val data = killer.matteryPlayer ?: return + val data = killer.matteryPlayer if (data.isAndroid) { val context = EntityPredicate.createContext(killer, event.entity) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/triggers/MCriterionTrigger.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/triggers/MCriterionTrigger.kt index d1c9b2370..6aee75154 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/triggers/MCriterionTrigger.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/triggers/MCriterionTrigger.kt @@ -1,13 +1,6 @@ package ru.dbotthepony.mc.otm.triggers -import com.google.gson.JsonObject -import com.google.gson.JsonParseException -import com.mojang.datafixers.util.Pair import com.mojang.serialization.Codec -import com.mojang.serialization.DataResult -import com.mojang.serialization.DynamicOps -import com.mojang.serialization.JsonOps -import com.mojang.serialization.MapCodec import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet import it.unimi.dsi.fastutil.objects.Reference2ObjectFunction import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap @@ -15,20 +8,17 @@ import net.minecraft.advancements.Criterion import net.minecraft.advancements.CriterionTrigger import net.minecraft.advancements.CriterionTriggerInstance import net.minecraft.advancements.critereon.ContextAwarePredicate -import net.minecraft.advancements.critereon.DeserializationContext +import net.minecraft.advancements.critereon.CriterionValidator import net.minecraft.advancements.critereon.EntityPredicate import net.minecraft.resources.ResourceLocation import net.minecraft.server.PlayerAdvancements import net.minecraft.server.level.ServerPlayer import ru.dbotthepony.mc.otm.core.collect.filter import ru.dbotthepony.mc.otm.core.collect.toImmutableList -import ru.dbotthepony.mc.otm.core.set -import ru.dbotthepony.mc.otm.core.toJsonStrict -import java.util.Optional +import java.util.* import java.util.function.Predicate -// allows to support both 1.20.1 and 1.20.2 with ease -// and has slightly less memory footprint than vanilla SimpleCriterionTrigger +// has slightly less memory footprint than vanilla SimpleCriterionTrigger abstract class MCriterionTrigger.AbstractInstance>(val id: ResourceLocation) : CriterionTrigger { private val listeners = Reference2ObjectOpenHashMap>>() @@ -46,13 +36,8 @@ abstract class MCriterionTrigger.AbstractInstance>(val protected abstract val codec: Codec - override fun createInstance(data: JsonObject, context: DeserializationContext): T { - return try { - deserializationContext.get().addLast(context) - codec.decode(JsonOps.INSTANCE, data).getOrThrow(false) { throw JsonParseException("Failed to decode data: $it") }.first - } finally { - deserializationContext.get().removeLast() - } + final override fun codec(): Codec { + return codec } fun trigger(player: ServerPlayer, predicate: Predicate = Predicate { true }) { @@ -70,36 +55,8 @@ abstract class MCriterionTrigger.AbstractInstance>(val abstract inner class AbstractInstance(val playerPredicate: Optional) : CriterionTriggerInstance { fun criterion() = Criterion(this@MCriterionTrigger, this as T) - final override fun serializeToJson(): JsonObject { - return codec.toJsonStrict(this as T) as JsonObject + override fun validate(validator: CriterionValidator) { + validator.validateEntity(playerPredicate, ".player") } } - - companion object { - protected val deserializationContext = object : ThreadLocal>() { - override fun initialValue(): ArrayDeque { - return ArrayDeque() - } - } - - @JvmStatic - protected val predicateCodec: Codec = object : Codec { - override fun encode(input: ContextAwarePredicate, ops: DynamicOps, prefix: T): DataResult { - return DataResult.success(JsonOps.INSTANCE.convertTo(ops, input.toJson())) - } - - override fun decode(ops: DynamicOps, input: T): DataResult> { - val context = deserializationContext.get().lastOrNull() ?: return DataResult.error { "Not current deserializing trigger instance" } - - return try { - DataResult.success(Pair.of(EntityPredicate.fromJson(JsonObject().also { it["a"] = ops.convertTo(JsonOps.INSTANCE, input) }, "a", context).get(), ops.empty())) - } catch (err: Exception) { - DataResult.error { "Failed to deserialize ContextAwarePredicate: " + err.message } - } - } - } - - @JvmStatic - protected val playerPredicateCodec: MapCodec> = predicateCodec.optionalFieldOf("player") - } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/triggers/MatteryInventoryChangeTrigger.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/triggers/MatteryInventoryChangeTrigger.kt index c3064c2fa..cd2fccf4f 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/triggers/MatteryInventoryChangeTrigger.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/triggers/MatteryInventoryChangeTrigger.kt @@ -11,7 +11,6 @@ import it.unimi.dsi.fastutil.objects.Reference2ObjectFunction import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap import net.minecraft.advancements.CriteriaTriggers import net.minecraft.advancements.CriterionTrigger -import net.minecraft.advancements.critereon.DeserializationContext import net.minecraft.advancements.critereon.InventoryChangeTrigger import net.minecraft.advancements.critereon.MinMaxBounds import net.minecraft.server.PlayerAdvancements @@ -77,19 +76,19 @@ object MatteryInventoryChangeTrigger : CriterionTrigger>() init { - nodes.add(Node(BoundsStrategy, { listOf(slotsOccupied) }, { v, inventory: Container, item: ItemStack, slotsFull: Int, slotsEmpty: Int, slotsOccupied: Int -> v!!.matches(slotsOccupied) })) - nodes.add(Node(BoundsStrategy, { listOf(slotsFull) }, { v, inventory: Container, item: ItemStack, slotsFull: Int, slotsEmpty: Int, slotsOccupied: Int -> v!!.matches(slotsFull) })) - nodes.add(Node(BoundsStrategy, { listOf(slotsEmpty) }, { v, inventory: Container, item: ItemStack, slotsFull: Int, slotsEmpty: Int, slotsOccupied: Int -> v!!.matches(slotsEmpty) })) + nodes.add(Node(BoundsStrategy, { listOf(slots.occupied) }, { v, inventory: Container, item: ItemStack, slotsFull: Int, slotsEmpty: Int, slotsOccupied: Int -> v!!.matches(slotsOccupied) })) + nodes.add(Node(BoundsStrategy, { listOf(slots.full) }, { v, inventory: Container, item: ItemStack, slotsFull: Int, slotsEmpty: Int, slotsOccupied: Int -> v!!.matches(slotsFull) })) + nodes.add(Node(BoundsStrategy, { listOf(slots.empty) }, { v, inventory: Container, item: ItemStack, slotsFull: Int, slotsEmpty: Int, slotsOccupied: Int -> v!!.matches(slotsEmpty) })) nodes.add(Node( DefaultStrategy, - { predicates.iterator().flatMap { (it.items.map { it.map { it.value() } }.orElse(listOf(null))).iterator() }.toList() }, + { items.iterator().flatMap { (it.items.map { it.map { it.value() } }.orElse(listOf(null))).iterator() }.toList() }, { v, inventory: Container, item: ItemStack, slotsFull: Int, slotsEmpty: Int, slotsOccupied: Int -> v == null || item.item == v }, { inventory: Container, item: ItemStack, slotsFull: Int, slotsEmpty: Int, slotsOccupied: Int -> mutableListOf(item.item) })) nodes.add(Node( DefaultStrategy, - { predicates.map { it.tag.orElse(null) } }, + { items.map { it.tag.orElse(null) } }, { v, inventory: Container, item: ItemStack, slotsFull: Int, slotsEmpty: Int, slotsOccupied: Int -> v == null || item.`is`(v) }, { inventory: Container, item: ItemStack, slotsFull: Int, slotsEmpty: Int, slotsOccupied: Int -> item.tags.collect(Collectors.toCollection(::ArrayList)) })) @@ -97,7 +96,7 @@ object MatteryInventoryChangeTrigger : CriterionTrigger v!!.isAny || item.isDamageableItem && v.matches(item.maxDamage - item.damageValue) })) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/triggers/NanobotsArmorTrigger.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/triggers/NanobotsArmorTrigger.kt index 9c290969e..812e32188 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/triggers/NanobotsArmorTrigger.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/triggers/NanobotsArmorTrigger.kt @@ -4,16 +4,16 @@ import com.mojang.serialization.Codec import com.mojang.serialization.codecs.RecordCodecBuilder import net.minecraft.advancements.critereon.ContextAwarePredicate import net.minecraft.advancements.critereon.MinMaxBounds.Doubles -import net.minecraft.resources.ResourceLocation import net.minecraft.server.level.ServerPlayer import ru.dbotthepony.mc.otm.OverdriveThatMatters +import ru.dbotthepony.mc.otm.core.ResourceLocation import java.util.* object NanobotsArmorTrigger : MCriterionTrigger(ResourceLocation(OverdriveThatMatters.MOD_ID, "nanobots_armor")) { override val codec: Codec = RecordCodecBuilder.create { it.group( Doubles.CODEC.fieldOf("predicate").forGetter(Instance::predicate), - playerPredicateCodec.forGetter(Instance::playerPredicate), + ContextAwarePredicate.CODEC.optionalFieldOf("player").forGetter(Instance::playerPredicate), ).apply(it, ::Instance) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/triggers/SimpleTriggers.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/triggers/SimpleTriggers.kt index 18adae924..e014aeacb 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/triggers/SimpleTriggers.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/triggers/SimpleTriggers.kt @@ -2,6 +2,7 @@ package ru.dbotthepony.mc.otm.triggers import net.minecraft.resources.ResourceLocation import ru.dbotthepony.mc.otm.OverdriveThatMatters +import ru.dbotthepony.mc.otm.core.ResourceLocation val BlackHoleTrigger = SingletonTrigger(ResourceLocation(OverdriveThatMatters.MOD_ID, "black_hole_pull")) val FallDampenersSaveTrigger = SingletonTrigger(ResourceLocation(OverdriveThatMatters.MOD_ID, "fall_dampeners_save")) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/triggers/SingletonTrigger.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/triggers/SingletonTrigger.kt index 6ad9afd6d..4b51ffba2 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/triggers/SingletonTrigger.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/triggers/SingletonTrigger.kt @@ -9,7 +9,9 @@ import java.util.* class SingletonTrigger(id: ResourceLocation) : MCriterionTrigger(id) { override val codec: Codec = RecordCodecBuilder.create { - it.group(playerPredicateCodec.forGetter(Instance::playerPredicate)).apply(it, ::Instance) + it.group( + ContextAwarePredicate.CODEC.optionalFieldOf("player").forGetter(Instance::playerPredicate) + ).apply(it, ::Instance) } val empty = Instance() diff --git a/src/main/resources/META-INF/accesstransformer.cfg b/src/main/resources/META-INF/accesstransformer.cfg index 69270ee06..4da41e68e 100644 --- a/src/main/resources/META-INF/accesstransformer.cfg +++ b/src/main/resources/META-INF/accesstransformer.cfg @@ -1,174 +1,174 @@ # Make Screen.title be public and easily modifiable -public-f net.minecraft.client.gui.screens.Screen f_96539_ # title -public net.minecraft.server.MinecraftServer f_129744_ # storageSource +public-f net.minecraft.client.gui.screens.Screen title +public net.minecraft.server.MinecraftServer storageSource -public net.minecraft.world.entity.player.Inventory f_150070_ # SELECTION_SIZE +public net.minecraft.world.entity.player.Inventory SELECTION_SIZE # for accessing and setting from MatteryScreen class public net.minecraft.client.gui.screens.inventory.AbstractContainerScreen f_169600_ public net.minecraft.client.gui.screens.inventory.AbstractContainerScreen f_169605_ public net.minecraft.client.gui.screens.inventory.AbstractContainerScreen f_169602_ -public net.minecraft.client.gui.screens.inventory.AbstractContainerScreen f_97732_ # menu -public net.minecraft.client.gui.screens.inventory.AbstractContainerScreen f_169604_ # playerInventoryTitle +public net.minecraft.client.gui.screens.inventory.AbstractContainerScreen menu +public net.minecraft.client.gui.screens.inventory.AbstractContainerScreen playerInventoryTitle -protected net.minecraft.client.gui.screens.inventory.AbstractContainerScreen f_97706_ # clickedSlot -protected net.minecraft.client.gui.screens.inventory.AbstractContainerScreen f_97707_ # snapbackEnd -protected net.minecraft.client.gui.screens.inventory.AbstractContainerScreen f_97708_ # quickdropSlot -protected net.minecraft.client.gui.screens.inventory.AbstractContainerScreen f_97709_ # lastClickSlot -protected net.minecraft.client.gui.screens.inventory.AbstractContainerScreen f_97710_ # isSplittingStack -protected net.minecraft.client.gui.screens.inventory.AbstractContainerScreen f_97711_ # draggingItem -protected net.minecraft.client.gui.screens.inventory.AbstractContainerScreen f_97712_ # snapbackStartX -protected net.minecraft.client.gui.screens.inventory.AbstractContainerScreen f_97713_ # snapbackStartY -protected net.minecraft.client.gui.screens.inventory.AbstractContainerScreen f_97714_ # snapbackTime -protected net.minecraft.client.gui.screens.inventory.AbstractContainerScreen f_97715_ # snapbackItem -protected net.minecraft.client.gui.screens.inventory.AbstractContainerScreen f_97716_ # quickdropTime -protected net.minecraft.client.gui.screens.inventory.AbstractContainerScreen f_97717_ # quickCraftingType -protected net.minecraft.client.gui.screens.inventory.AbstractContainerScreen f_97718_ # quickCraftingButton -protected net.minecraft.client.gui.screens.inventory.AbstractContainerScreen f_97719_ # skipNextRelease -protected net.minecraft.client.gui.screens.inventory.AbstractContainerScreen f_97720_ # quickCraftingRemainder -protected net.minecraft.client.gui.screens.inventory.AbstractContainerScreen f_97721_ # lastClickTime -protected net.minecraft.client.gui.screens.inventory.AbstractContainerScreen f_97722_ # lastClickButton -protected net.minecraft.client.gui.screens.inventory.AbstractContainerScreen f_97723_ # doubleclick -protected net.minecraft.client.gui.screens.inventory.AbstractContainerScreen f_97724_ # lastQuickMoved +protected net.minecraft.client.gui.screens.inventory.AbstractContainerScreen clickedSlot +protected net.minecraft.client.gui.screens.inventory.AbstractContainerScreen snapbackEnd +protected net.minecraft.client.gui.screens.inventory.AbstractContainerScreen quickdropSlot +protected net.minecraft.client.gui.screens.inventory.AbstractContainerScreen lastClickSlot +protected net.minecraft.client.gui.screens.inventory.AbstractContainerScreen isSplittingStack +protected net.minecraft.client.gui.screens.inventory.AbstractContainerScreen draggingItem +protected net.minecraft.client.gui.screens.inventory.AbstractContainerScreen snapbackStartX +protected net.minecraft.client.gui.screens.inventory.AbstractContainerScreen snapbackStartY +protected net.minecraft.client.gui.screens.inventory.AbstractContainerScreen snapbackTime +protected net.minecraft.client.gui.screens.inventory.AbstractContainerScreen snapbackItem +protected net.minecraft.client.gui.screens.inventory.AbstractContainerScreen quickdropTime +protected net.minecraft.client.gui.screens.inventory.AbstractContainerScreen quickCraftingType +protected net.minecraft.client.gui.screens.inventory.AbstractContainerScreen quickCraftingButton +protected net.minecraft.client.gui.screens.inventory.AbstractContainerScreen skipNextRelease +protected net.minecraft.client.gui.screens.inventory.AbstractContainerScreen quickCraftingRemainder +protected net.minecraft.client.gui.screens.inventory.AbstractContainerScreen lastClickTime +protected net.minecraft.client.gui.screens.inventory.AbstractContainerScreen lastClickButton +protected net.minecraft.client.gui.screens.inventory.AbstractContainerScreen doubleclick +protected net.minecraft.client.gui.screens.inventory.AbstractContainerScreen lastQuickMoved -public net.minecraft.world.item.BlockItem f_150696_ # BLOCK_ENTITY_TAG +public net.minecraft.world.item.BlockItem BLOCK_ENTITY_TAG -public net.minecraft.client.gui.screens.InBedChatScreen f_263129_ # leaveBedButton +public net.minecraft.client.gui.screens.InBedChatScreen leaveBedButton -public net.minecraft.world.inventory.AbstractContainerMenu f_182405_ # stateId +public net.minecraft.world.inventory.AbstractContainerMenu stateId -public net.minecraft.world.inventory.CraftingMenu m_150546_(Lnet/minecraft/world/inventory/AbstractContainerMenu;Lnet/minecraft/world/level/Level;Lnet/minecraft/world/entity/player/Player;Lnet/minecraft/world/inventory/CraftingContainer;Lnet/minecraft/world/inventory/ResultContainer;)V # slotChangedCraftingGrid +public net.minecraft.world.inventory.CraftingMenu slotChangedCraftingGrid(Lnet/minecraft/world/inventory/AbstractContainerMenu;Lnet/minecraft/world/level/Level;Lnet/minecraft/world/entity/player/Player;Lnet/minecraft/world/inventory/CraftingContainer;Lnet/minecraft/world/inventory/ResultContainer;)V -public net.minecraft.server.level.ServerPlayer f_143380_ # containerListener +public net.minecraft.server.level.ServerPlayer containerListener # for overriding from MatteryScreen class -protected net.minecraft.client.gui.screens.inventory.AbstractContainerScreen m_97762_(I)V # checkHotbarMouseClicked -protected net.minecraft.client.gui.screens.inventory.AbstractContainerScreen m_97818_()V # recalculateQuickCraftRemaining -protected net.minecraft.client.gui.screens.inventory.AbstractContainerScreen m_97744_(DD)Lnet/minecraft/world/inventory/Slot; # findSlot -protected net.minecraft.client.gui.screens.inventory.AbstractContainerScreen m_280211_(Lnet/minecraft/client/gui/GuiGraphics;Lnet/minecraft/world/item/ItemStack;IILjava/lang/String;)V # renderFloatingItem +protected net.minecraft.client.gui.screens.inventory.AbstractContainerScreen checkHotbarMouseClicked(I)V +protected net.minecraft.client.gui.screens.inventory.AbstractContainerScreen recalculateQuickCraftRemaining()V +protected net.minecraft.client.gui.screens.inventory.AbstractContainerScreen findSlot(DD)Lnet/minecraft/world/inventory/Slot; +protected net.minecraft.client.gui.screens.inventory.AbstractContainerScreen renderFloatingItem(Lnet/minecraft/client/gui/GuiGraphics;Lnet/minecraft/world/item/ItemStack;IILjava/lang/String;)V -protected net.minecraft.client.resources.TextureAtlasHolder f_118884_ # textureAtlas +protected net.minecraft.client.resources.TextureAtlasHolder textureAtlas -public net.minecraft.client.renderer.RenderStateShard f_110133_ # name +public net.minecraft.client.renderer.RenderStateShard name -public-f net.minecraft.world.inventory.Slot f_40220_ # x -public-f net.minecraft.world.inventory.Slot f_40221_ # y +public-f net.minecraft.world.inventory.Slot x +public-f net.minecraft.world.inventory.Slot y -public net.minecraft.client.renderer.LevelRenderer m_109782_(Lcom/mojang/blaze3d/vertex/PoseStack;Lcom/mojang/blaze3d/vertex/VertexConsumer;Lnet/minecraft/world/phys/shapes/VoxelShape;DDDFFFF)V # renderShape +public net.minecraft.client.renderer.LevelRenderer renderShape(Lcom/mojang/blaze3d/vertex/PoseStack;Lcom/mojang/blaze3d/vertex/VertexConsumer;Lnet/minecraft/world/phys/shapes/VoxelShape;DDDFFFF)V -public net.minecraft.client.renderer.RenderStateShard f_110135_ # ADDITIVE_TRANSPARENCY -public net.minecraft.client.renderer.RenderStateShard f_173097_ # BLOCK_SHADER -public net.minecraft.client.renderer.RenderStateShard f_110146_ # BLOCK_SHEET -public net.minecraft.client.renderer.RenderStateShard f_110145_ # BLOCK_SHEET_MIPPED -public net.minecraft.client.renderer.RenderStateShard f_110128_ # CLOUDS_TARGET -public net.minecraft.client.renderer.RenderStateShard f_110114_ # COLOR_DEPTH_WRITE -public net.minecraft.client.renderer.RenderStateShard f_110115_ # COLOR_WRITE -public net.minecraft.client.renderer.RenderStateShard f_110138_ # CRUMBLING_TRANSPARENCY -public net.minecraft.client.renderer.RenderStateShard f_110158_ # CULL -public net.minecraft.client.renderer.RenderStateShard f_110130_ # DEFAULT_LINE -public net.minecraft.client.renderer.RenderStateShard f_110148_ # DEFAULT_TEXTURING -public net.minecraft.client.renderer.RenderStateShard f_110116_ # DEPTH_WRITE -public net.minecraft.client.renderer.RenderStateShard f_110151_ # ENTITY_GLINT_TEXTURING -public net.minecraft.client.renderer.RenderStateShard f_110112_ # EQUAL_DEPTH_TEST -public net.minecraft.client.renderer.RenderStateShard f_110150_ # GLINT_TEXTURING -public net.minecraft.client.renderer.RenderStateShard f_110137_ # GLINT_TRANSPARENCY -public net.minecraft.client.renderer.RenderStateShard f_110129_ # ITEM_ENTITY_TARGET -public net.minecraft.client.renderer.RenderStateShard f_110113_ # LEQUAL_DEPTH_TEST -public net.minecraft.client.renderer.RenderStateShard f_110152_ # LIGHTMAP -public net.minecraft.client.renderer.RenderStateShard f_110136_ # LIGHTNING_TRANSPARENCY -public net.minecraft.client.renderer.RenderStateShard f_110123_ # MAIN_TARGET -public net.minecraft.client.renderer.RenderStateShard f_173098_ # NEW_ENTITY_SHADER -public net.minecraft.client.renderer.RenderStateShard f_110110_ # NO_CULL -public net.minecraft.client.renderer.RenderStateShard f_110111_ # NO_DEPTH_TEST -public net.minecraft.client.renderer.RenderStateShard f_110117_ # NO_LAYERING -public net.minecraft.client.renderer.RenderStateShard f_110153_ # NO_LIGHTMAP -public net.minecraft.client.renderer.RenderStateShard f_110155_ # NO_OVERLAY -public net.minecraft.client.renderer.RenderStateShard f_173096_ # NO_SHADER -public net.minecraft.client.renderer.RenderStateShard f_110147_ # NO_TEXTURE -public net.minecraft.client.renderer.RenderStateShard f_110134_ # NO_TRANSPARENCY -public net.minecraft.client.renderer.RenderStateShard f_110124_ # OUTLINE_TARGET -public net.minecraft.client.renderer.RenderStateShard f_110154_ # OVERLAY -public net.minecraft.client.renderer.RenderStateShard f_110126_ # PARTICLES_TARGET -public net.minecraft.client.renderer.RenderStateShard f_110118_ # POLYGON_OFFSET_LAYERING -public net.minecraft.client.renderer.RenderStateShard f_173099_ # POSITION_COLOR_LIGHTMAP_SHADER -public net.minecraft.client.renderer.RenderStateShard f_173104_ # POSITION_COLOR_SHADER -public net.minecraft.client.renderer.RenderStateShard f_173103_ # POSITION_COLOR_TEX_LIGHTMAP_SHADER -public net.minecraft.client.renderer.RenderStateShard f_173101_ # POSITION_COLOR_TEX_SHADER -public net.minecraft.client.renderer.RenderStateShard f_173100_ # POSITION_SHADER -public net.minecraft.client.renderer.RenderStateShard f_173102_ # POSITION_TEX_SHADER -public net.minecraft.client.renderer.RenderStateShard f_173111_ # RENDERTYPE_ARMOR_CUTOUT_NO_CULL_SHADER -public net.minecraft.client.renderer.RenderStateShard f_173079_ # RENDERTYPE_ARMOR_ENTITY_GLINT_SHADER -public net.minecraft.client.renderer.RenderStateShard f_173078_ # RENDERTYPE_ARMOR_GLINT_SHADER -public net.minecraft.client.renderer.RenderStateShard f_173068_ # RENDERTYPE_BEACON_BEAM_SHADER -public net.minecraft.client.renderer.RenderStateShard f_173085_ # RENDERTYPE_CRUMBLING_SHADER -public net.minecraft.client.renderer.RenderStateShard f_173106_ # RENDERTYPE_CUTOUT_MIPPED_SHADER -public net.minecraft.client.renderer.RenderStateShard f_173107_ # RENDERTYPE_CUTOUT_SHADER -public net.minecraft.client.renderer.RenderStateShard f_173094_ # RENDERTYPE_END_GATEWAY_SHADER -public net.minecraft.client.renderer.RenderStateShard f_173093_ # RENDERTYPE_END_PORTAL_SHADER -public net.minecraft.client.renderer.RenderStateShard f_173074_ # RENDERTYPE_ENERGY_SWIRL_SHADER -public net.minecraft.client.renderer.RenderStateShard f_173072_ # RENDERTYPE_ENTITY_ALPHA_SHADER -public net.minecraft.client.renderer.RenderStateShard f_173114_ # RENDERTYPE_ENTITY_CUTOUT_NO_CULL_SHADER -public net.minecraft.client.renderer.RenderStateShard f_173063_ # RENDERTYPE_ENTITY_CUTOUT_NO_CULL_Z_OFFSET_SHADER -public net.minecraft.client.renderer.RenderStateShard f_173113_ # RENDERTYPE_ENTITY_CUTOUT_SHADER -public net.minecraft.client.renderer.RenderStateShard f_173069_ # RENDERTYPE_ENTITY_DECAL_SHADER -public net.minecraft.client.renderer.RenderStateShard f_173084_ # RENDERTYPE_ENTITY_GLINT_DIRECT_SHADER -public net.minecraft.client.renderer.RenderStateShard f_173083_ # RENDERTYPE_ENTITY_GLINT_SHADER -public net.minecraft.client.renderer.RenderStateShard f_173070_ # RENDERTYPE_ENTITY_NO_OUTLINE_SHADER -public net.minecraft.client.renderer.RenderStateShard f_173071_ # RENDERTYPE_ENTITY_SHADOW_SHADER -public net.minecraft.client.renderer.RenderStateShard f_173067_ # RENDERTYPE_ENTITY_SMOOTH_CUTOUT_SHADER -public net.minecraft.client.renderer.RenderStateShard f_173112_ # RENDERTYPE_ENTITY_SOLID_SHADER -public net.minecraft.client.renderer.RenderStateShard f_173065_ # RENDERTYPE_ENTITY_TRANSLUCENT_CULL_SHADER -public net.minecraft.client.renderer.RenderStateShard f_234323_ # RENDERTYPE_ENTITY_TRANSLUCENT_EMISSIVE_SHADER -public net.minecraft.client.renderer.RenderStateShard f_173066_ # RENDERTYPE_ENTITY_TRANSLUCENT_SHADER -public net.minecraft.client.renderer.RenderStateShard f_173073_ # RENDERTYPE_EYES_SHADER -public net.minecraft.client.renderer.RenderStateShard f_173082_ # RENDERTYPE_GLINT_DIRECT_SHADER -public net.minecraft.client.renderer.RenderStateShard f_173081_ # RENDERTYPE_GLINT_SHADER -public net.minecraft.client.renderer.RenderStateShard f_173080_ # RENDERTYPE_GLINT_TRANSLUCENT_SHADER -public net.minecraft.client.renderer.RenderStateShard f_173064_ # RENDERTYPE_ITEM_ENTITY_TRANSLUCENT_CULL_SHADER -public net.minecraft.client.renderer.RenderStateShard f_173075_ # RENDERTYPE_LEASH_SHADER -public net.minecraft.client.renderer.RenderStateShard f_173091_ # RENDERTYPE_LIGHTNING_SHADER -public net.minecraft.client.renderer.RenderStateShard f_173095_ # RENDERTYPE_LINES_SHADER -public net.minecraft.client.renderer.RenderStateShard f_173077_ # RENDERTYPE_OUTLINE_SHADER -public net.minecraft.client.renderer.RenderStateShard f_173105_ # RENDERTYPE_SOLID_SHADER -public net.minecraft.client.renderer.RenderStateShard f_173090_ # RENDERTYPE_TEXT_INTENSITY_SEE_THROUGH_SHADER -public net.minecraft.client.renderer.RenderStateShard f_173087_ # RENDERTYPE_TEXT_INTENSITY_SHADER -public net.minecraft.client.renderer.RenderStateShard f_173088_ # RENDERTYPE_TEXT_SEE_THROUGH_SHADER -public net.minecraft.client.renderer.RenderStateShard f_173086_ # RENDERTYPE_TEXT_SHADER -public net.minecraft.client.renderer.RenderStateShard f_173109_ # RENDERTYPE_TRANSLUCENT_MOVING_BLOCK_SHADER -public net.minecraft.client.renderer.RenderStateShard f_173110_ # RENDERTYPE_TRANSLUCENT_NO_CRUMBLING_SHADER -public net.minecraft.client.renderer.RenderStateShard f_173108_ # RENDERTYPE_TRANSLUCENT_SHADER -public net.minecraft.client.renderer.RenderStateShard f_173092_ # RENDERTYPE_TRIPWIRE_SHADER -public net.minecraft.client.renderer.RenderStateShard f_173076_ # RENDERTYPE_WATER_MASK_SHADER -public net.minecraft.client.renderer.RenderStateShard f_110125_ # TRANSLUCENT_TARGET -public net.minecraft.client.renderer.RenderStateShard f_110139_ # TRANSLUCENT_TRANSPARENCY -public net.minecraft.client.renderer.RenderStateShard f_110119_ # VIEW_OFFSET_Z_LAYERING -public net.minecraft.client.renderer.RenderStateShard f_173089_ # VIEW_SCALE_Z_EPSILON -public net.minecraft.client.renderer.RenderStateShard f_110127_ # WEATHER_TARGET +public net.minecraft.client.renderer.RenderStateShard ADDITIVE_TRANSPARENCY +public net.minecraft.client.renderer.RenderStateShard BLOCK_SHADER +public net.minecraft.client.renderer.RenderStateShard BLOCK_SHEET +public net.minecraft.client.renderer.RenderStateShard BLOCK_SHEET_MIPPED +public net.minecraft.client.renderer.RenderStateShard CLOUDS_TARGET +public net.minecraft.client.renderer.RenderStateShard COLOR_DEPTH_WRITE +public net.minecraft.client.renderer.RenderStateShard COLOR_WRITE +public net.minecraft.client.renderer.RenderStateShard CRUMBLING_TRANSPARENCY +public net.minecraft.client.renderer.RenderStateShard CULL +public net.minecraft.client.renderer.RenderStateShard DEFAULT_LINE +public net.minecraft.client.renderer.RenderStateShard DEFAULT_TEXTURING +public net.minecraft.client.renderer.RenderStateShard DEPTH_WRITE +public net.minecraft.client.renderer.RenderStateShard ENTITY_GLINT_TEXTURING +public net.minecraft.client.renderer.RenderStateShard EQUAL_DEPTH_TEST +public net.minecraft.client.renderer.RenderStateShard GLINT_TEXTURING +public net.minecraft.client.renderer.RenderStateShard GLINT_TRANSPARENCY +public net.minecraft.client.renderer.RenderStateShard ITEM_ENTITY_TARGET +public net.minecraft.client.renderer.RenderStateShard LEQUAL_DEPTH_TEST +public net.minecraft.client.renderer.RenderStateShard LIGHTMAP +public net.minecraft.client.renderer.RenderStateShard LIGHTNING_TRANSPARENCY +public net.minecraft.client.renderer.RenderStateShard MAIN_TARGET +public net.minecraft.client.renderer.RenderStateShard NEW_ENTITY_SHADER +public net.minecraft.client.renderer.RenderStateShard NO_CULL +public net.minecraft.client.renderer.RenderStateShard NO_DEPTH_TEST +public net.minecraft.client.renderer.RenderStateShard NO_LAYERING +public net.minecraft.client.renderer.RenderStateShard NO_LIGHTMAP +public net.minecraft.client.renderer.RenderStateShard NO_OVERLAY +public net.minecraft.client.renderer.RenderStateShard NO_SHADER +public net.minecraft.client.renderer.RenderStateShard NO_TEXTURE +public net.minecraft.client.renderer.RenderStateShard NO_TRANSPARENCY +public net.minecraft.client.renderer.RenderStateShard OUTLINE_TARGET +public net.minecraft.client.renderer.RenderStateShard OVERLAY +public net.minecraft.client.renderer.RenderStateShard PARTICLES_TARGET +public net.minecraft.client.renderer.RenderStateShard POLYGON_OFFSET_LAYERING +public net.minecraft.client.renderer.RenderStateShard POSITION_COLOR_LIGHTMAP_SHADER +public net.minecraft.client.renderer.RenderStateShard POSITION_COLOR_SHADER +public net.minecraft.client.renderer.RenderStateShard POSITION_COLOR_TEX_LIGHTMAP_SHADER +public net.minecraft.client.renderer.RenderStateShard POSITION_COLOR_TEX_SHADER +public net.minecraft.client.renderer.RenderStateShard POSITION_SHADER +public net.minecraft.client.renderer.RenderStateShard POSITION_TEX_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_ARMOR_CUTOUT_NO_CULL_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_ARMOR_ENTITY_GLINT_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_ARMOR_GLINT_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_BEACON_BEAM_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_CRUMBLING_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_CUTOUT_MIPPED_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_CUTOUT_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_END_GATEWAY_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_END_PORTAL_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_ENERGY_SWIRL_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_ENTITY_ALPHA_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_ENTITY_CUTOUT_NO_CULL_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_ENTITY_CUTOUT_NO_CULL_Z_OFFSET_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_ENTITY_CUTOUT_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_ENTITY_DECAL_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_ENTITY_GLINT_DIRECT_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_ENTITY_GLINT_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_ENTITY_NO_OUTLINE_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_ENTITY_SHADOW_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_ENTITY_SMOOTH_CUTOUT_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_ENTITY_SOLID_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_ENTITY_TRANSLUCENT_CULL_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_ENTITY_TRANSLUCENT_EMISSIVE_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_ENTITY_TRANSLUCENT_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_EYES_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_GLINT_DIRECT_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_GLINT_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_GLINT_TRANSLUCENT_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_ITEM_ENTITY_TRANSLUCENT_CULL_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_LEASH_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_LIGHTNING_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_LINES_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_OUTLINE_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_SOLID_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_TEXT_INTENSITY_SEE_THROUGH_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_TEXT_INTENSITY_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_TEXT_SEE_THROUGH_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_TEXT_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_TRANSLUCENT_MOVING_BLOCK_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_TRANSLUCENT_NO_CRUMBLING_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_TRANSLUCENT_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_TRIPWIRE_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_WATER_MASK_SHADER +public net.minecraft.client.renderer.RenderStateShard TRANSLUCENT_TARGET +public net.minecraft.client.renderer.RenderStateShard TRANSLUCENT_TRANSPARENCY +public net.minecraft.client.renderer.RenderStateShard VIEW_OFFSET_Z_LAYERING +public net.minecraft.client.renderer.RenderStateShard VIEW_SCALE_Z_EPSILON +public net.minecraft.client.renderer.RenderStateShard WEATHER_TARGET public net.minecraft.client.renderer.RenderStateShard$LineStateShard -public net.minecraft.world.inventory.AbstractContainerMenu m_38897_(Lnet/minecraft/world/inventory/Slot;)Lnet/minecraft/world/inventory/Slot; # addSlot +public net.minecraft.world.inventory.AbstractContainerMenu addSlot(Lnet/minecraft/world/inventory/Slot;)Lnet/minecraft/world/inventory/Slot; -public net.minecraft.client.renderer.FogRenderer f_109012_ # fogBlue -public net.minecraft.client.renderer.FogRenderer f_109011_ # fogGreen -public net.minecraft.client.renderer.FogRenderer f_109010_ # fogRed +public net.minecraft.client.renderer.FogRenderer fogBlue +public net.minecraft.client.renderer.FogRenderer fogGreen +public net.minecraft.client.renderer.FogRenderer fogRed -public net.minecraft.world.item.crafting.RecipeManager m_44054_(Lnet/minecraft/world/item/crafting/RecipeType;)Ljava/util/Map; # byType +public net.minecraft.world.item.crafting.RecipeManager byType(Lnet/minecraft/world/item/crafting/RecipeType;)Ljava/util/Collection; -public net.minecraft.world.item.crafting.SmithingTransformRecipe f_265888_ # base -public net.minecraft.world.item.crafting.SmithingTransformRecipe f_265907_ # addition +public net.minecraft.world.item.crafting.SmithingTransformRecipe base +public net.minecraft.world.item.crafting.SmithingTransformRecipe addition -public net.minecraft.world.entity.boss.wither.WitherBoss f_31432_ # TARGETING_CONDITIONS -public-f net.minecraft.world.entity.boss.wither.WitherBoss f_31431_ # LIVING_ENTITY_SELECTOR -public net.minecraft.world.entity.ai.targeting.TargetingConditions f_26879_ # selector +public net.minecraft.world.entity.boss.wither.WitherBoss TARGETING_CONDITIONS +public-f net.minecraft.world.entity.boss.wither.WitherBoss LIVING_ENTITY_SELECTOR +public net.minecraft.world.entity.ai.targeting.TargetingConditions selector -public net.minecraft.world.entity.ExperienceOrb f_147072_ # count +public net.minecraft.world.entity.ExperienceOrb count # count public net.minecraft.advancements.critereon.InventoryChangeTrigger$TriggerInstance f_43179_ public net.minecraft.advancements.critereon.InventoryChangeTrigger$TriggerInstance f_43178_ public net.minecraft.advancements.critereon.InventoryChangeTrigger$TriggerInstance f_43177_ public net.minecraft.advancements.critereon.InventoryChangeTrigger$TriggerInstance f_43176_ -#public-f net.minecraft.advancements.critereon.SimpleCriterionTrigger m_6467_(Lnet/minecraft/server/PlayerAdvancements;Lnet/minecraft/advancements/CriterionTrigger$Listener;)V # addPlayerListener -#public-f net.minecraft.advancements.critereon.SimpleCriterionTrigger m_6468_(Lnet/minecraft/server/PlayerAdvancements;Lnet/minecraft/advancements/CriterionTrigger$Listener;)V # removePlayerListener -#public-f net.minecraft.advancements.critereon.SimpleCriterionTrigger m_5656_(Lnet/minecraft/server/PlayerAdvancements;)V # removePlayerListeners +#public-f net.minecraft.advancements.critereon.SimpleCriterionTrigger addPlayerListener(Lnet/minecraft/server/PlayerAdvancements;Lnet/minecraft/advancements/CriterionTrigger$Listener;)V +#public-f net.minecraft.advancements.critereon.SimpleCriterionTrigger removePlayerListener(Lnet/minecraft/server/PlayerAdvancements;Lnet/minecraft/advancements/CriterionTrigger$Listener;)V +#public-f net.minecraft.advancements.critereon.SimpleCriterionTrigger removePlayerListeners(Lnet/minecraft/server/PlayerAdvancements;)V diff --git a/src/main/resources/overdrive_that_matters.ad_astra.mixins.json b/src/main/resources/overdrive_that_matters.ad_astra.mixins.json deleted file mode 100644 index 2ee1936df..000000000 --- a/src/main/resources/overdrive_that_matters.ad_astra.mixins.json +++ /dev/null @@ -1,13 +0,0 @@ - -{ - "required": false, - "package": "ru.dbotthepony.mc.otm.mixin.compat.ad_astra", - "compatibilityLevel": "JAVA_17", - "minVersion": "0.8", - "refmap": "overdrive_that_matters.refmap.json", - "mixins": [ - "EntityOxygenSystemMixin", - "EntityTemperatureSystemMixin", - "OxygenUtilsMixin" - ] -} diff --git a/src/main/resources/overdrive_that_matters.mixins.json b/src/main/resources/overdrive_that_matters.mixins.json index 95ba2b017..4e22d4fd8 100644 --- a/src/main/resources/overdrive_that_matters.mixins.json +++ b/src/main/resources/overdrive_that_matters.mixins.json @@ -9,7 +9,6 @@ "BlockEntityMixin", "EnchantmentHelperMixin", "FoodDataMixin", - "MixinPatchProjectileFinder", "MixinLivingEntity", "MixinAnvilBlock", "MixinInventory",