diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index efcbc840..a55befda 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -71,4 +71,4 @@ jobs: uses: Anvil-Dev/dedicated-server-launch-test@1.21.1-neoforge with: mod: build/libs/${{ steps.properties.outputs.mod_id }}-neoforge-${{ steps.version.outputs.version }}.jar - extra-mods: anvilcraft:1.6.0+snapshot.2068 + extra-mods: anvilcraft:1.6.0+snapshot.2087 diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 897aeeea..141b6d6a 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -62,4 +62,4 @@ jobs: uses: Anvil-Dev/dedicated-server-launch-test@1.21.1-neoforge with: mod: build/libs/${{ steps.properties.outputs.mod_id }}-neoforge-${{ steps.version.outputs.version }}.jar - extra-mods: anvilcraft:1.6.0+snapshot.2068 + extra-mods: anvilcraft:1.6.0+snapshot.2087 diff --git a/README.md b/README.md index b33aa16c..a5dd7ef0 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,6 @@ * 可调式能量转换器:将kW与FE双向转换 * 幽匿技术 * 回响母岩:生产幽匿方块与回响碎片 - * 幽匿萃取体:获取大量经验 ## 使用许可 diff --git a/README_en.md b/README_en.md index f75647c0..7b63443a 100644 --- a/README_en.md +++ b/README_en.md @@ -14,7 +14,6 @@ * Adjustable Power Converter: Bidirectional conversion between kW and FE * Sculk Technology: * Echo Cluster: Produces sculk blocks and echo shards - * Sculk Extractor: Obtain large amounts of experience ## Usage License @@ -76,5 +75,26 @@ ## Special Thanks: + + + + + + + +
+ +
+ 三只大猪 +

+ 💻 + 🤔
+ 87423598 +
+ + + +
+ diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 2aae2cf1..3eb85f51 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -3,7 +3,7 @@ minecraft = "1.21.1" neoForge = "21.1.219" ageratum = "0.0.1+build.106" anvillib = "2.0.0+snapshot.490" -anvilcraft = "1.6.0+snapshot.2068" +anvilcraft = "1.6.0+snapshot.2087" jei = "19.32.0.358" jade = "15.3.4+neoforge" modDevGradle = "2.0.140" diff --git a/net/minecraft/client/Minecraft.java b/net/minecraft/client/Minecraft.java deleted file mode 100644 index a4c23a0a..00000000 --- a/net/minecraft/client/Minecraft.java +++ /dev/null @@ -1,3034 +0,0 @@ -package net.minecraft.client; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Lists; -import com.mojang.authlib.GameProfile; -import com.mojang.authlib.exceptions.AuthenticationException; -import com.mojang.authlib.minecraft.BanDetails; -import com.mojang.authlib.minecraft.UserApiService; -import com.mojang.authlib.minecraft.UserApiService.UserFlag; -import com.mojang.authlib.minecraft.UserApiService.UserProperties; -import com.mojang.authlib.yggdrasil.ProfileActionType; -import com.mojang.authlib.yggdrasil.ProfileResult; -import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService; -import com.mojang.blaze3d.TracyFrameCapture; -import com.mojang.blaze3d.opengl.GlBackend; -import com.mojang.blaze3d.pipeline.MainTarget; -import com.mojang.blaze3d.pipeline.RenderTarget; -import com.mojang.blaze3d.platform.BackendOptions; -import com.mojang.blaze3d.platform.ClientShutdownWatchdog; -import com.mojang.blaze3d.platform.DisplayData; -import com.mojang.blaze3d.platform.FramerateLimitTracker; -import com.mojang.blaze3d.platform.GLX; -import com.mojang.blaze3d.platform.IconSet; -import com.mojang.blaze3d.platform.InputConstants; -import com.mojang.blaze3d.platform.MessageBox; -import com.mojang.blaze3d.platform.TextInputManager; -import com.mojang.blaze3d.platform.Window; -import com.mojang.blaze3d.platform.WindowEventHandler; -import com.mojang.blaze3d.shaders.GpuDebugOptions; -import com.mojang.blaze3d.systems.BackendCreationException; -import com.mojang.blaze3d.systems.GpuBackend; -import com.mojang.blaze3d.systems.GpuDevice; -import com.mojang.blaze3d.systems.RenderSystem; -import com.mojang.blaze3d.systems.TimerQuery; -import com.mojang.blaze3d.vertex.Tesselator; -import com.mojang.datafixers.DataFixer; -import com.mojang.jtracy.DiscontinuousFrame; -import com.mojang.jtracy.TracyClient; -import com.mojang.logging.LogUtils; -import com.mojang.realmsclient.RealmsMainScreen; -import com.mojang.realmsclient.client.RealmsClient; -import com.mojang.realmsclient.gui.RealmsDataFetcher; -import java.io.File; -import java.io.IOException; -import java.io.UncheckedIOException; -import java.lang.management.ManagementFactory; -import java.net.Proxy; -import java.net.SocketAddress; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.time.Duration; -import java.time.Instant; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Locale; -import java.util.MissingResourceException; -import java.util.Objects; -import java.util.Optional; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CompletionStage; -import java.util.concurrent.TimeUnit; -import java.util.function.Consumer; -import java.util.function.Function; -import net.minecraft.ChatFormatting; -import net.minecraft.CrashReport; -import net.minecraft.CrashReportCategory; -import net.minecraft.Optionull; -import net.minecraft.ReportType; -import net.minecraft.ReportedException; -import net.minecraft.SharedConstants; -import net.minecraft.SystemReport; -import net.minecraft.client.color.block.BlockColors; -import net.minecraft.client.entity.ClientMannequin; -import net.minecraft.client.gui.Font; -import net.minecraft.client.gui.Gui; -import net.minecraft.client.gui.components.ChatComponent; -import net.minecraft.client.gui.components.DebugScreenOverlay; -import net.minecraft.client.gui.components.LogoRenderer; -import net.minecraft.client.gui.components.debug.DebugScreenEntries; -import net.minecraft.client.gui.components.debug.DebugScreenEntryList; -import net.minecraft.client.gui.components.debugchart.ProfilerPieChart; -import net.minecraft.client.gui.components.events.GuiEventListener; -import net.minecraft.client.gui.components.toasts.SystemToast; -import net.minecraft.client.gui.components.toasts.ToastManager; -import net.minecraft.client.gui.components.toasts.TutorialToast; -import net.minecraft.client.gui.font.FontManager; -import net.minecraft.client.gui.font.providers.FreeTypeUtil; -import net.minecraft.client.gui.screens.AccessibilityOnboardingScreen; -import net.minecraft.client.gui.screens.BanNoticeScreens; -import net.minecraft.client.gui.screens.ChatScreen; -import net.minecraft.client.gui.screens.DeathScreen; -import net.minecraft.client.gui.screens.GenericMessageScreen; -import net.minecraft.client.gui.screens.InBedChatScreen; -import net.minecraft.client.gui.screens.LevelLoadingScreen; -import net.minecraft.client.gui.screens.LoadingOverlay; -import net.minecraft.client.gui.screens.MenuScreens; -import net.minecraft.client.gui.screens.OutOfMemoryScreen; -import net.minecraft.client.gui.screens.Overlay; -import net.minecraft.client.gui.screens.PauseScreen; -import net.minecraft.client.gui.screens.ProgressScreen; -import net.minecraft.client.gui.screens.Screen; -import net.minecraft.client.gui.screens.TitleScreen; -import net.minecraft.client.gui.screens.advancements.AdvancementsScreen; -import net.minecraft.client.gui.screens.inventory.CreativeModeInventoryScreen; -import net.minecraft.client.gui.screens.inventory.InventoryScreen; -import net.minecraft.client.gui.screens.multiplayer.JoinMultiplayerScreen; -import net.minecraft.client.gui.screens.social.PlayerSocialManager; -import net.minecraft.client.gui.screens.social.SocialInteractionsScreen; -import net.minecraft.client.gui.screens.worldselection.WorldOpenFlows; -import net.minecraft.client.main.GameConfig; -import net.minecraft.client.main.SilentInitException; -import net.minecraft.client.model.geom.EntityModelSet; -import net.minecraft.client.multiplayer.ClientHandshakePacketListenerImpl; -import net.minecraft.client.multiplayer.ClientLevel; -import net.minecraft.client.multiplayer.ClientPacketListener; -import net.minecraft.client.multiplayer.LevelLoadTracker; -import net.minecraft.client.multiplayer.MultiPlayerGameMode; -import net.minecraft.client.multiplayer.ProfileKeyPairManager; -import net.minecraft.client.multiplayer.ServerData; -import net.minecraft.client.multiplayer.chat.ChatAbilities; -import net.minecraft.client.multiplayer.chat.ChatListener; -import net.minecraft.client.multiplayer.chat.ChatRestriction; -import net.minecraft.client.multiplayer.chat.report.ReportEnvironment; -import net.minecraft.client.multiplayer.chat.report.ReportingContext; -import net.minecraft.client.particle.ParticleEngine; -import net.minecraft.client.particle.ParticleResources; -import net.minecraft.client.player.LocalPlayer; -import net.minecraft.client.player.LocalPlayerResolver; -import net.minecraft.client.profiling.ClientMetricsSamplersProvider; -import net.minecraft.client.quickplay.QuickPlay; -import net.minecraft.client.quickplay.QuickPlayLog; -import net.minecraft.client.renderer.GameRenderer; -import net.minecraft.client.renderer.GpuWarnlistManager; -import net.minecraft.client.renderer.LevelRenderer; -import net.minecraft.client.renderer.MapRenderer; -import net.minecraft.client.renderer.PlayerSkinRenderCache; -import net.minecraft.client.renderer.RenderBuffers; -import net.minecraft.client.renderer.ShaderManager; -import net.minecraft.client.renderer.block.BlockModelResolver; -import net.minecraft.client.renderer.block.BlockStateModelSet; -import net.minecraft.client.renderer.block.dispatch.BlockStateModel; -import net.minecraft.client.renderer.blockentity.BlockEntityRenderDispatcher; -import net.minecraft.client.renderer.entity.EntityRenderDispatcher; -import net.minecraft.client.renderer.entity.EntityRenderers; -import net.minecraft.client.renderer.item.ItemModelResolver; -import net.minecraft.client.renderer.state.GameRenderState; -import net.minecraft.client.renderer.state.WindowRenderState; -import net.minecraft.client.renderer.texture.SkinTextureDownloader; -import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraft.client.renderer.texture.TextureManager; -import net.minecraft.client.resources.ClientPackSource; -import net.minecraft.client.resources.DryFoliageColorReloadListener; -import net.minecraft.client.resources.FoliageColorReloadListener; -import net.minecraft.client.resources.GrassColorReloadListener; -import net.minecraft.client.resources.MapTextureManager; -import net.minecraft.client.resources.SkinManager; -import net.minecraft.client.resources.SplashManager; -import net.minecraft.client.resources.WaypointStyleManager; -import net.minecraft.client.resources.language.I18n; -import net.minecraft.client.resources.language.LanguageManager; -import net.minecraft.client.resources.model.EquipmentAssetManager; -import net.minecraft.client.resources.model.ModelManager; -import net.minecraft.client.resources.model.sprite.AtlasManager; -import net.minecraft.client.resources.server.DownloadedPackSource; -import net.minecraft.client.server.IntegratedServer; -import net.minecraft.client.sounds.MusicManager; -import net.minecraft.client.sounds.SoundBufferLibrary; -import net.minecraft.client.sounds.SoundManager; -import net.minecraft.client.telemetry.ClientTelemetryManager; -import net.minecraft.client.telemetry.TelemetryProperty; -import net.minecraft.client.telemetry.events.GameLoadTimesEvent; -import net.minecraft.client.tutorial.Tutorial; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.core.Holder; -import net.minecraft.core.Registry; -import net.minecraft.core.component.DataComponents; -import net.minecraft.core.registries.BuiltInRegistries; -import net.minecraft.core.registries.Registries; -import net.minecraft.gizmos.Gizmos; -import net.minecraft.gizmos.SimpleGizmoCollector; -import net.minecraft.network.Connection; -import net.minecraft.network.PacketProcessor; -import net.minecraft.network.chat.ClickEvent; -import net.minecraft.network.chat.Component; -import net.minecraft.network.chat.MutableComponent; -import net.minecraft.network.chat.contents.KeybindResolver; -import net.minecraft.network.protocol.game.ServerboundClientTickEndPacket; -import net.minecraft.network.protocol.game.ServerboundPlayerActionPacket; -import net.minecraft.network.protocol.login.ServerboundHelloPacket; -import net.minecraft.resources.Identifier; -import net.minecraft.server.Bootstrap; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.Services; -import net.minecraft.server.WorldStem; -import net.minecraft.server.dialog.Dialog; -import net.minecraft.server.dialog.Dialogs; -import net.minecraft.server.level.ChunkLevel; -import net.minecraft.server.level.progress.LevelLoadListener; -import net.minecraft.server.level.progress.LoggingLevelLoadListener; -import net.minecraft.server.packs.PackResources; -import net.minecraft.server.packs.PackType; -import net.minecraft.server.packs.VanillaPackResources; -import net.minecraft.server.packs.repository.FolderRepositorySource; -import net.minecraft.server.packs.repository.PackRepository; -import net.minecraft.server.packs.repository.PackSource; -import net.minecraft.server.packs.repository.RepositorySource; -import net.minecraft.server.packs.resources.ReloadInstance; -import net.minecraft.server.packs.resources.ReloadableResourceManager; -import net.minecraft.server.packs.resources.ResourceManager; -import net.minecraft.server.players.ProfileResolver; -import net.minecraft.sounds.Music; -import net.minecraft.sounds.Musics; -import net.minecraft.sounds.SoundSource; -import net.minecraft.tags.DialogTags; -import net.minecraft.util.CommonLinks; -import net.minecraft.util.FileUtil; -import net.minecraft.util.FileZipper; -import net.minecraft.util.MemoryReserve; -import net.minecraft.util.ModCheck; -import net.minecraft.util.TimeUtil; -import net.minecraft.util.Unit; -import net.minecraft.util.Util; -import net.minecraft.util.datafix.DataFixers; -import net.minecraft.util.profiling.ContinuousProfiler; -import net.minecraft.util.profiling.EmptyProfileResults; -import net.minecraft.util.profiling.InactiveProfiler; -import net.minecraft.util.profiling.ProfileResults; -import net.minecraft.util.profiling.Profiler; -import net.minecraft.util.profiling.ProfilerFiller; -import net.minecraft.util.profiling.SingleTickProfiler; -import net.minecraft.util.profiling.Zone; -import net.minecraft.util.profiling.metrics.profiling.ActiveMetricsRecorder; -import net.minecraft.util.profiling.metrics.profiling.InactiveMetricsRecorder; -import net.minecraft.util.profiling.metrics.profiling.MetricsRecorder; -import net.minecraft.util.profiling.metrics.storage.MetricsPersister; -import net.minecraft.util.thread.ReentrantBlockableEventLoop; -import net.minecraft.world.InteractionHand; -import net.minecraft.world.InteractionResult; -import net.minecraft.world.TickRateManager; -import net.minecraft.world.attribute.BackgroundMusic; -import net.minecraft.world.attribute.EnvironmentAttributes; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.EntityType; -import net.minecraft.world.entity.player.ChatVisiblity; -import net.minecraft.world.item.Item; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.component.AttackRange; -import net.minecraft.world.item.component.PiercingWeapon; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.RenderShape; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.gamerules.GameRules; -import net.minecraft.world.level.storage.LevelStorageSource; -import net.minecraft.world.level.validation.DirectoryValidator; -import net.minecraft.world.phys.BlockHitResult; -import net.minecraft.world.phys.EntityHitResult; -import net.minecraft.world.phys.HitResult; -import net.neoforged.api.distmarker.Dist; -import net.neoforged.api.distmarker.OnlyIn; -import org.apache.commons.io.FileUtils; -import org.jspecify.annotations.Nullable; -import org.slf4j.Logger; - -@OnlyIn(Dist.CLIENT) -public class Minecraft extends ReentrantBlockableEventLoop implements WindowEventHandler, net.neoforged.neoforge.client.extensions.IMinecraftExtension { - private static Minecraft instance; - private static final Logger LOGGER = LogUtils.getLogger(); - private static final int MAX_TICKS_PER_UPDATE = 10; - public static final Identifier DEFAULT_FONT = Identifier.withDefaultNamespace("default"); - public static final Identifier UNIFORM_FONT = Identifier.withDefaultNamespace("uniform"); - public static final Identifier ALT_FONT = Identifier.withDefaultNamespace("alt"); - private static final Identifier REGIONAL_COMPLIANCIES = Identifier.withDefaultNamespace("regional_compliancies.json"); - private static final CompletableFuture RESOURCE_RELOAD_INITIAL_TASK = CompletableFuture.completedFuture(Unit.INSTANCE); - private static final Component SOCIAL_INTERACTIONS_NOT_AVAILABLE = Component.translatable("multiplayer.socialInteractions.not_available"); - private static final Component SAVING_LEVEL = Component.translatable("menu.savingLevel"); - public static final String UPDATE_DRIVERS_ADVICE = "Please make sure you have up-to-date drivers (see aka.ms/mcdriver for instructions)."; - private final long canary = Double.doubleToLongBits(Math.PI); - private final Path resourcePackDirectory; - private final CompletableFuture<@Nullable ProfileResult> profileFuture; - private final TextureManager textureManager; - private final ShaderManager shaderManager; - private final DataFixer fixerUpper; - private final Window window; - private final TextInputManager textInputManager; - private final DeltaTracker.Timer deltaTracker = new DeltaTracker.Timer(20.0F, 0L, this::getTickTargetMillis); - private final RenderBuffers renderBuffers; - public final LevelRenderer levelRenderer; - private final EntityRenderDispatcher entityRenderDispatcher; - private final BlockModelResolver blockModelResolver; - private final ItemModelResolver itemModelResolver; - private final MapRenderer mapRenderer; - public final ParticleEngine particleEngine; - private final ParticleResources particleResources; - private final User user; - public final Font font; - public final Font fontFilterFishy; - public final GameRenderer gameRenderer; - public final Gui gui; - public final Options options; - public final DebugScreenEntryList debugEntries; - private final HotbarManager hotbarManager; - public final MouseHandler mouseHandler; - public final KeyboardHandler keyboardHandler; - private InputType lastInputType = InputType.NONE; - public final File gameDirectory; - private final String launchedVersion; - private final String versionType; - private final Proxy proxy; - private final boolean offlineDeveloperMode; - private final LevelStorageSource levelSource; - private final boolean demo; - private final boolean allowsMultiplayer; - private final boolean allowsChat; - private final ReloadableResourceManager resourceManager; - private final VanillaPackResources vanillaPackResources; - private final DownloadedPackSource downloadedPackSource; - private final PackRepository resourcePackRepository; - private final LanguageManager languageManager; - private final BlockColors blockColors; - private final RenderTarget mainRenderTarget; - private final @Nullable TracyFrameCapture tracyFrameCapture; - private final SoundManager soundManager; - private final MusicManager musicManager; - private final FontManager fontManager; - private final SplashManager splashManager; - private final GpuWarnlistManager gpuWarnlistManager; - private final PeriodicNotificationManager regionalCompliancies = new PeriodicNotificationManager(REGIONAL_COMPLIANCIES, Minecraft::countryEqualsISO3); - private final UserApiService userApiService; - private final CompletableFuture userPropertiesFuture; - private final SkinManager skinManager; - private final AtlasManager atlasManager; - private final ModelManager modelManager; - private final MapTextureManager mapTextureManager; - private final WaypointStyleManager waypointStyles; - private final ToastManager toastManager; - private final Tutorial tutorial; - private final PlayerSocialManager playerSocialManager; - private final BlockEntityRenderDispatcher blockEntityRenderDispatcher; - private final ClientTelemetryManager telemetryManager; - private final ProfileKeyPairManager profileKeyPairManager; - private final RealmsDataFetcher realmsDataFetcher; - private final QuickPlayLog quickPlayLog; - private final Services services; - private final PlayerSkinRenderCache playerSkinRenderCache; - public @Nullable MultiPlayerGameMode gameMode; - public @Nullable ClientLevel level; - public @Nullable LocalPlayer player; - private @Nullable IntegratedServer singleplayerServer; - private @Nullable Connection pendingConnection; - private boolean isLocalServer; - public @Nullable Entity crosshairPickEntity; - public @Nullable HitResult hitResult; - private int rightClickDelay; - protected int missTime; - private volatile boolean pause; - private long lastNanoTime = Util.getNanos(); - private long lastTime; - private int frames; - public @Nullable Screen screen; - private @Nullable Overlay overlay; - private boolean clientLevelTeardownInProgress; - private Thread gameThread; - private volatile boolean running; - private static int fps; - private long frameTimeNs; - private final FramerateLimitTracker framerateLimitTracker; - public boolean wireframe; - public boolean smartCull = true; - private long lastActiveTime = Util.getMillis(); - private @Nullable CompletableFuture pendingReload; - private @Nullable TutorialToast socialInteractionsToast; - private int fpsPieRenderTicks; - private final ContinuousProfiler fpsPieProfiler; - private MetricsRecorder metricsRecorder = InactiveMetricsRecorder.INSTANCE; - private final ResourceLoadStateTracker reloadStateTracker = new ResourceLoadStateTracker(); - private long savedCpuDuration; - private double gpuUtilization; - private TimerQuery.@Nullable FrameProfile currentFrameProfile; - private final GameNarrator narrator; - private final ChatListener chatListener; - private ReportingContext reportingContext; - private final CommandHistory commandHistory; - private final DirectoryValidator directoryValidator; - private boolean gameLoadFinished; - private final long clientStartTimeMs; - private long clientTickCount; - private final PacketProcessor packetProcessor; - private final SimpleGizmoCollector perTickGizmos = new SimpleGizmoCollector(); - private List drainedLatestTickGizmos = new ArrayList<>(); - - public Minecraft(GameConfig gameConfig) { - super("Client", true); - instance = this; - this.clientStartTimeMs = System.currentTimeMillis(); - this.gameDirectory = gameConfig.location.gameDirectory; - File assetsDirectory = gameConfig.location.assetDirectory; - this.resourcePackDirectory = gameConfig.location.resourcePackDirectory.toPath(); - this.launchedVersion = gameConfig.game.launchVersion; - this.versionType = gameConfig.game.versionType; - Path gameDirPath = this.gameDirectory.toPath(); - this.directoryValidator = LevelStorageSource.parseValidator(gameDirPath.resolve("allowed_symlinks.txt")); - ClientPackSource clientPackSource = new ClientPackSource(gameConfig.location.getExternalAssetSource(), this.directoryValidator); - this.downloadedPackSource = new DownloadedPackSource(this, gameDirPath.resolve("downloads"), gameConfig.user); - RepositorySource directoryPacks = new FolderRepositorySource( - this.resourcePackDirectory, PackType.CLIENT_RESOURCES, PackSource.DEFAULT, this.directoryValidator - ); - this.resourcePackRepository = new PackRepository(clientPackSource, this.downloadedPackSource.createRepositorySource(), directoryPacks); - this.vanillaPackResources = clientPackSource.getVanillaPack(); - this.proxy = gameConfig.user.proxy; - this.offlineDeveloperMode = gameConfig.game.offlineDeveloperMode; - YggdrasilAuthenticationService authenticationService = this.offlineDeveloperMode - ? YggdrasilAuthenticationService.createOffline(this.proxy) - : new YggdrasilAuthenticationService(this.proxy); - this.services = Services.create(authenticationService, this.gameDirectory); - this.user = gameConfig.user.user; - this.profileFuture = this.offlineDeveloperMode - ? CompletableFuture.completedFuture(null) - : CompletableFuture.supplyAsync(() -> this.services.sessionService().fetchProfile(this.user.getProfileId(), true), Util.nonCriticalIoPool()); - this.userApiService = this.createUserApiService(authenticationService, gameConfig); - this.userPropertiesFuture = CompletableFuture.supplyAsync(() -> { - try { - return this.userApiService.fetchProperties(); - } catch (AuthenticationException var2x) { - LOGGER.error("Failed to fetch user properties", (Throwable)var2x); - return UserApiService.OFFLINE_PROPERTIES; - } - }, Util.nonCriticalIoPool()); - LOGGER.info("Setting user: {}", this.user.getName()); - this.demo = gameConfig.game.demo; - this.allowsMultiplayer = !gameConfig.game.disableMultiplayer; - this.allowsChat = !gameConfig.game.disableChat; - this.singleplayerServer = null; - KeybindResolver.setKeyResolver(KeyMapping::createNameSupplier); - this.fixerUpper = DataFixers.getDataFixer(); - this.gameThread = Thread.currentThread(); - this.options = new Options(this, this.gameDirectory); - this.debugEntries = new DebugScreenEntryList(this.gameDirectory, this.fixerUpper); - this.toastManager = new ToastManager(this, this.options); - boolean lastStartWasClean = this.options.startedCleanly; - this.options.startedCleanly = false; - this.options.save(); - this.running = true; - this.tutorial = new Tutorial(this, this.options); - this.hotbarManager = new HotbarManager(gameDirPath, this.fixerUpper); - LOGGER.info("Backend library: {}", RenderSystem.getBackendDescription()); - DisplayData displayData = gameConfig.display; - if (this.options.overrideHeight > 0 && this.options.overrideWidth > 0) { - displayData = gameConfig.display.withSize(this.options.overrideWidth, this.options.overrideHeight); - } - - if (!lastStartWasClean) { - displayData = displayData.withFullscreen(false); - this.options.fullscreenVideoModeString = null; - LOGGER.warn("Detected unexpected shutdown during last game startup: resetting fullscreen mode"); - } - - Util.timeSource = RenderSystem.initBackendSystem(new BackendOptions(this.options.exclusiveFullscreen().get())); - GpuBackend[] backends = new GpuBackend[]{new GlBackend()}; - StringBuilder errorMsgBuilder = new StringBuilder("No supported graphics backend was found."); - Window windowCandidate = null; - GpuDevice device = null; - // Neo: Enable GL debug labels and synchronous GL debug output via FML config - boolean enableGlDebug = net.neoforged.fml.loading.FMLConfig.getBoolConfigValue(net.neoforged.fml.loading.FMLConfig.ConfigValue.DEBUG_OPENGL); - - for (GpuBackend backend : backends) { - try { - windowCandidate = new Window(this, displayData, this.options.fullscreenVideoModeString, this.createTitle(), backend); - device = windowCandidate.backend() - .createDevice( - windowCandidate.handle(), - (id, type) -> this.getShaderManager().getShader(id, type), - new GpuDebugOptions(this.options.glDebugVerbosity, SharedConstants.DEBUG_SYNCHRONOUS_GL_LOGS || enableGlDebug, gameConfig.game.renderDebugLabels || enableGlDebug) - ); - RenderSystem.initRenderer(device); - break; - } catch (BackendCreationException var24) { - LOGGER.error("Failed to create backend {}", backend.getName(), var24); - errorMsgBuilder.append("\n\n- Tried ").append(backend.getName()).append(": \n ").append(var24.getMessage()); - if (windowCandidate != null) { - windowCandidate.close(); - windowCandidate = null; - } - } - } - - if (windowCandidate == null) { - String errorMsg = errorMsgBuilder.toString(); - MessageBox.error(errorMsg); - throw new Window.WindowInitFailed(errorMsg); - } else { - this.window = windowCandidate; - this.textInputManager = new TextInputManager(this.window); - this.window.setWindowCloseCallback(new Runnable() { - private boolean threadStarted; - - { - Objects.requireNonNull(Minecraft.this); - } - - @Override - public void run() { - if (!this.threadStarted) { - this.threadStarted = true; - ClientShutdownWatchdog.startShutdownWatchdog(Minecraft.this, gameConfig.location.gameDirectory, Minecraft.this.gameThread.threadId()); - } - } - }); - GameLoadTimesEvent.INSTANCE.endStep(TelemetryProperty.LOAD_TIME_PRE_WINDOW_MS); - - try { - this.window.setIcon(this.vanillaPackResources, SharedConstants.getCurrentVersion().stable() ? IconSet.RELEASE : IconSet.SNAPSHOT); - } catch (IOException var23) { - LOGGER.error("Couldn't set icon", (Throwable)var23); - } - - // FORGE: Move mouse and keyboard handler setup further below - this.mouseHandler = new MouseHandler(this); - this.keyboardHandler = new KeyboardHandler(this); - this.options.applyGraphicsPreset(this.options.graphicsPreset().get()); - LOGGER.info("Using optional rendering extensions: {}", String.join(", ", RenderSystem.getDevice().getEnabledExtensions())); - this.mainRenderTarget = net.neoforged.neoforge.client.ClientHooks.instantiateMainTarget(this.window.getWidth(), this.window.getHeight()); - this.resourceManager = new ReloadableResourceManager(PackType.CLIENT_RESOURCES); - net.neoforged.neoforge.client.loading.ClientModLoader.setupModResourcePacks(this.resourcePackRepository); - //Move client bootstrap to after mod loading so that events can be fired for it. - ClientBootstrap.bootstrap(); - this.resourcePackRepository.reload(); - this.options.loadSelectedResourcePacks(this.resourcePackRepository); - this.languageManager = new LanguageManager(this.options.languageCode, languageData -> { - if (this.player != null) { - this.player.connection.updateSearchTrees(); - } - }); - this.resourceManager.registerReloadListener(this.languageManager); - this.textureManager = new TextureManager(this.resourceManager); - this.resourceManager.registerReloadListener(this.textureManager); - this.shaderManager = new ShaderManager(this.textureManager, this::triggerResourcePackRecovery); - this.resourceManager.registerReloadListener(this.shaderManager); - SkinTextureDownloader skinTextureDownloader = new SkinTextureDownloader(this.proxy, this.textureManager, this); - this.skinManager = new SkinManager(assetsDirectory.toPath().resolve("skins"), this.services, skinTextureDownloader, this); - this.levelSource = new LevelStorageSource(gameDirPath.resolve("saves"), gameDirPath.resolve("backups"), this.directoryValidator, this.fixerUpper); - this.commandHistory = new CommandHistory(gameDirPath); - this.musicManager = new MusicManager(this); - this.soundManager = new SoundManager(this.options); - this.resourceManager.registerReloadListener(this.soundManager); - this.splashManager = new SplashManager(this.user); - this.resourceManager.registerReloadListener(this.splashManager); - this.atlasManager = new AtlasManager(this.textureManager, this.options.mipmapLevels().get()); - this.resourceManager.registerReloadListener(this.atlasManager); - ProfileResolver localProfileResolver = new LocalPlayerResolver(this, this.services.profileResolver()); - this.playerSkinRenderCache = new PlayerSkinRenderCache(this.textureManager, this.skinManager, localProfileResolver); - ClientMannequin.registerOverrides(this.playerSkinRenderCache); - this.fontManager = new FontManager(this.textureManager, this.atlasManager, this.playerSkinRenderCache); - this.font = this.fontManager.createFont(); - this.fontFilterFishy = this.fontManager.createFontFilterFishy(); - this.resourceManager.registerReloadListener(this.fontManager); - this.updateFontOptions(); - this.resourceManager.registerReloadListener(new GrassColorReloadListener()); - this.resourceManager.registerReloadListener(new FoliageColorReloadListener()); - this.resourceManager.registerReloadListener(new DryFoliageColorReloadListener()); - this.window.setErrorSection("Startup"); - RenderSystem.setupDefaultState(); - this.window.setErrorSection("Post startup"); - this.blockColors = BlockColors.createDefault(); - net.neoforged.neoforge.client.model.UnbakedModelParser.init(); - this.modelManager = new ModelManager(this.blockColors, this.atlasManager, this.playerSkinRenderCache); - this.resourceManager.registerReloadListener(this.modelManager); - EquipmentAssetManager equipmentAssets = new EquipmentAssetManager(); - this.resourceManager.registerReloadListener(equipmentAssets); - this.blockModelResolver = new BlockModelResolver(this.modelManager); - this.itemModelResolver = new ItemModelResolver(this.modelManager); - this.mapTextureManager = new MapTextureManager(this.textureManager); - this.mapRenderer = new MapRenderer(this.atlasManager, this.mapTextureManager); - - try { - int maxSectionBuilders = Runtime.getRuntime().availableProcessors(); - Tesselator.init(); - this.renderBuffers = new RenderBuffers(maxSectionBuilders); - } catch (OutOfMemoryError var22) { - MessageBox.error( - "Oh no! The game was unable to allocate memory off-heap while trying to start. You may try to free some memory by closing other applications on your computer, check that your system meets the minimum requirements, and try again. If the problem persists, please visit: " - + CommonLinks.GENERAL_HELP - ); - throw new SilentInitException("Unable to allocate render buffers", var22); - } - - this.playerSocialManager = new PlayerSocialManager(this, this.userApiService); - this.entityRenderDispatcher = new EntityRenderDispatcher( - this, - this.textureManager, - this.blockModelResolver, - this.itemModelResolver, - this.mapRenderer, - this.atlasManager, - this.font, - this.options, - this.modelManager.entityModels(), - equipmentAssets, - this.playerSkinRenderCache - ); - this.resourceManager.registerReloadListener(this.entityRenderDispatcher); - this.blockEntityRenderDispatcher = new BlockEntityRenderDispatcher( - this.font, - this.modelManager.entityModels(), - this.blockModelResolver, - this.itemModelResolver, - this.entityRenderDispatcher, - this.atlasManager, - this.playerSkinRenderCache - ); - this.resourceManager.registerReloadListener(this.blockEntityRenderDispatcher); - this.particleResources = new ParticleResources(); - this.resourceManager.registerReloadListener(this.particleResources); - this.particleEngine = new ParticleEngine(this.level, this.particleResources); - this.particleResources.onReload(this.particleEngine::clearParticles); - net.neoforged.neoforge.client.ClientHooks.onRegisterParticleProviders(this.particleResources); - this.waypointStyles = new WaypointStyleManager(); - this.resourceManager.registerReloadListener(this.waypointStyles); - this.gameRenderer = new GameRenderer(this, this.entityRenderDispatcher.getItemInHandRenderer(), this.renderBuffers, this.modelManager); - WindowRenderState windowRenderState = this.gameRenderer.getGameRenderState().windowRenderState; - windowRenderState.width = this.window.getWidth(); - windowRenderState.height = this.window.getHeight(); - this.levelRenderer = new LevelRenderer( - this, - this.entityRenderDispatcher, - this.blockEntityRenderDispatcher, - this.renderBuffers, - this.gameRenderer.getGameRenderState(), - this.gameRenderer.getFeatureRenderDispatcher() - ); - this.resourceManager.registerReloadListener(this.levelRenderer); - this.resourceManager.registerReloadListener(this.levelRenderer.getCloudRenderer()); - this.gpuWarnlistManager = new GpuWarnlistManager(); - this.resourceManager.registerReloadListener(this.gpuWarnlistManager); - this.resourceManager.registerReloadListener(this.regionalCompliancies); - // NEO: Moved keyboard and mouse handler setup below ingame gui creation to prevent NPEs in them. - this.mouseHandler.setup(this.window); - this.keyboardHandler.setup(this.window); - this.gui = new Gui(this); - RealmsClient realmsClient = RealmsClient.getOrCreate(this); - this.realmsDataFetcher = new RealmsDataFetcher(realmsClient); - RenderSystem.setErrorCallback(this::onFullscreenError); - if (this.mainRenderTarget.width != this.window.getWidth() || this.mainRenderTarget.height != this.window.getHeight()) { - StringBuilder message = new StringBuilder( - "Recovering from unsupported resolution (" - + this.window.getWidth() - + "x" - + this.window.getHeight() - + ").\nPlease make sure you have up-to-date drivers (see aka.ms/mcdriver for instructions)." - ); - - try { - List messages = device.getLastDebugMessages(); - if (!messages.isEmpty()) { - message.append("\n\nReported GL debug messages:\n").append(String.join("\n", messages)); - } - } catch (Throwable var21) { - } - - this.window.setWindowed(this.mainRenderTarget.width, this.mainRenderTarget.height); - MessageBox.error(message.toString()); - } else if (this.options.fullscreen().get() && !this.window.isFullscreen()) { - if (lastStartWasClean) { - this.window.toggleFullScreen(); - this.options.fullscreen().set(this.window.isFullscreen()); - } else { - this.options.fullscreen().set(false); - } - } - - net.neoforged.neoforge.client.ClientHooks.initClientHooks(this, this.resourceManager); - this.window.updateVsync(this.options.enableVsync().get()); - this.window.updateRawMouseInput(this.options.rawMouseInput().get()); - this.window.setAllowCursorChanges(this.options.allowCursorChanges().get()); - this.window.setDefaultErrorCallback(); - this.resizeGui(); - this.gameRenderer.preloadUiShader(this.vanillaPackResources.asProvider()); - this.telemetryManager = new ClientTelemetryManager(this, this.userApiService, this.user); - this.profileKeyPairManager = this.offlineDeveloperMode - ? ProfileKeyPairManager.EMPTY_KEY_MANAGER - : ProfileKeyPairManager.create(this.userApiService, this.user, gameDirPath); - this.narrator = new GameNarrator(this); - this.narrator.checkStatus(this.options.narrator().get() != NarratorStatus.OFF); - this.chatListener = new ChatListener(this); - this.chatListener.setMessageDelay(this.options.chatDelay().get()); - this.reportingContext = ReportingContext.create(ReportEnvironment.local(), this.userApiService); - TitleScreen.registerTextures(this.textureManager); - LoadingOverlay.registerTextures(this.textureManager); - this.gameRenderer.registerPanoramaTextures(this.textureManager); - net.neoforged.neoforge.client.loading.ClientModLoader.finish(); - this.setScreen(new GenericMessageScreen(Component.translatable("gui.loadingMinecraft"))); - List packs = this.resourcePackRepository.openAllSelected(); - this.reloadStateTracker.startReload(ResourceLoadStateTracker.ReloadReason.INITIAL, packs); - ReloadInstance reloadInstance = this.resourceManager - .createReload(Util.backgroundExecutor().forName("resourceLoad"), this, RESOURCE_RELOAD_INITIAL_TASK, packs); - GameLoadTimesEvent.INSTANCE.beginStep(TelemetryProperty.LOAD_TIME_LOADING_OVERLAY_MS); - Minecraft.GameLoadCookie loadCookie = new Minecraft.GameLoadCookie(realmsClient, gameConfig.quickPlay); - this.setOverlay(new LoadingOverlay(this, reloadInstance, maybeT -> Util.ifElse(maybeT, t -> this.rollbackResourcePacks(t, loadCookie), () -> { - if (SharedConstants.IS_RUNNING_IN_IDE && false /* Neo: Disable self-test */) { - this.selfTest(); - } - - this.reloadStateTracker.finishReload(); - this.onResourceLoadFinished(loadCookie); - }), false)); - this.quickPlayLog = QuickPlayLog.of(gameConfig.quickPlay.logPath()); - this.framerateLimitTracker = new FramerateLimitTracker(this.options, this); - this.fpsPieProfiler = new ContinuousProfiler(Util.timeSource, () -> this.fpsPieRenderTicks, this.framerateLimitTracker::isHeavilyThrottled); - if (TracyClient.isAvailable() && gameConfig.game.captureTracyImages) { - this.tracyFrameCapture = new TracyFrameCapture(); - } else { - this.tracyFrameCapture = null; - } - - this.packetProcessor = new PacketProcessor(this.gameThread); - } - } - - public boolean hasShiftDown() { - Window window = this.getWindow(); - return InputConstants.isKeyDown(window, 340) || InputConstants.isKeyDown(window, 344); - } - - public boolean hasControlDown() { - Window window = this.getWindow(); - return InputConstants.isKeyDown(window, 341) || InputConstants.isKeyDown(window, 345); - } - - public boolean hasAltDown() { - Window window = this.getWindow(); - return InputConstants.isKeyDown(window, 342) || InputConstants.isKeyDown(window, 346); - } - - private void onResourceLoadFinished(Minecraft.@Nullable GameLoadCookie loadCookie) { - net.neoforged.neoforge.client.ClientHooks.fireResourceLoadFinishedEvent(!this.gameLoadFinished); - if (!this.gameLoadFinished) { - this.gameLoadFinished = true; - this.onGameLoadFinished(loadCookie); - } - } - - private void onGameLoadFinished(Minecraft.@Nullable GameLoadCookie cookie) { - Runnable showScreen = this.buildInitialScreens(cookie); - GameLoadTimesEvent.INSTANCE.endStep(TelemetryProperty.LOAD_TIME_LOADING_OVERLAY_MS); - GameLoadTimesEvent.INSTANCE.endStep(TelemetryProperty.LOAD_TIME_TOTAL_TIME_MS); - GameLoadTimesEvent.INSTANCE.send(this.telemetryManager.getOutsideSessionSender()); - showScreen.run(); - this.options.startedCleanly = true; - this.options.save(); - } - - public boolean isGameLoadFinished() { - return this.gameLoadFinished; - } - - private Runnable buildInitialScreens(Minecraft.@Nullable GameLoadCookie cookie) { - List> screens = new ArrayList<>(); - boolean onboardingScreenAdded = this.addInitialScreens(screens); - Runnable nextStep = () -> { - if (cookie != null && cookie.quickPlayData.isEnabled()) { - QuickPlay.connect(this, cookie.quickPlayData.variant(), cookie.realmsClient()); - } else { - this.setScreen(new TitleScreen(true, new LogoRenderer(onboardingScreenAdded))); - } - }; - - for (Function function : Lists.reverse(screens)) { - Screen screen = function.apply(nextStep); - nextStep = () -> this.setScreen(screen); - } - - nextStep = net.neoforged.neoforge.client.loading.ClientModLoader.completeModLoading(nextStep); - - return nextStep; - } - - private boolean addInitialScreens(List> screens) { - boolean onboardingScreenAdded = false; - if (this.options.onboardAccessibility || SharedConstants.DEBUG_FORCE_ONBOARDING_SCREEN) { - screens.add(next -> new AccessibilityOnboardingScreen(this.options, next)); - onboardingScreenAdded = true; - } - - BanDetails multiplayerBan = this.multiplayerBan(); - if (multiplayerBan != null) { - screens.add(next -> BanNoticeScreens.create(result -> { - if (result) { - Util.getPlatform().openUri(CommonLinks.SUSPENSION_HELP); - } - - next.run(); - }, multiplayerBan)); - } - - ProfileResult profileResult = this.profileFuture.join(); - if (profileResult != null) { - GameProfile profile = profileResult.profile(); - Set actions = profileResult.actions(); - if (actions.contains(ProfileActionType.FORCED_NAME_CHANGE)) { - screens.add(onClose -> BanNoticeScreens.createNameBan(profile.name(), onClose)); - } - - if (actions.contains(ProfileActionType.USING_BANNED_SKIN)) { - screens.add(BanNoticeScreens::createSkinBan); - } - } - - return onboardingScreenAdded; - } - - private static boolean countryEqualsISO3(Object iso3Locale) { - try { - return Locale.getDefault().getISO3Country().equals(iso3Locale); - } catch (MissingResourceException var2) { - return false; - } - } - - public void updateTitle() { - this.window.setTitle(this.createTitle()); - } - - private String createTitle() { - StringBuilder builder = new StringBuilder("Minecraft"); - if (checkModStatus().shouldReportAsModified()) { - builder.append(' ').append(net.neoforged.neoforge.internal.BrandingControl.BRANDING_NAME).append('*'); - } - - builder.append(" "); - builder.append(SharedConstants.getCurrentVersion().name()); - ClientPacketListener connection = this.getConnection(); - if (connection != null && connection.getConnection().isConnected()) { - builder.append(" - "); - ServerData server = this.getCurrentServer(); - if (this.singleplayerServer != null && !this.singleplayerServer.isPublished()) { - builder.append(I18n.get("title.singleplayer")); - } else if (server != null && server.isRealm()) { - builder.append(I18n.get("title.multiplayer.realms")); - } else if (this.singleplayerServer == null && (server == null || !server.isLan())) { - builder.append(I18n.get("title.multiplayer.other")); - } else { - builder.append(I18n.get("title.multiplayer.lan")); - } - } - - return builder.toString(); - } - - private UserApiService createUserApiService(YggdrasilAuthenticationService authService, GameConfig config) { - return config.game.offlineDeveloperMode ? UserApiService.OFFLINE : authService.createUserApiService(config.user.user.getAccessToken()); - } - - public boolean isOfflineDeveloperMode() { - return this.offlineDeveloperMode; - } - - public static ModCheck checkModStatus() { - return ModCheck.identify("vanilla", ClientBrandRetriever::getClientModName, "Client", Minecraft.class); - } - - private void rollbackResourcePacks(Throwable t, Minecraft.@Nullable GameLoadCookie loadCookie) { - if (this.resourcePackRepository.getSelectedPacks().stream().anyMatch(e -> !e.isRequired())) { //Forge: This caused infinite loop if any resource packs are forced. Such as mod resources. So check if we can disable any. - this.clearResourcePacksOnError(t, null, loadCookie); - } else { - Util.throwAsRuntime(t); - } - } - - public void clearResourcePacksOnError(Throwable t, @Nullable Component message, Minecraft.@Nullable GameLoadCookie loadCookie) { - LOGGER.info("Caught error loading resourcepacks, removing all selected resourcepacks", t); - this.reloadStateTracker.startRecovery(t); - this.downloadedPackSource.onRecovery(); - this.resourcePackRepository.setSelected(Collections.emptyList()); - this.options.resourcePacks.clear(); - this.options.incompatibleResourcePacks.clear(); - this.options.save(); - this.reloadResourcePacks(true, loadCookie).thenRunAsync(() -> this.addResourcePackLoadFailToast(message), this); - } - - private void abortResourcePackRecovery() { - this.setOverlay(null); - if (this.level != null) { - this.level.disconnect(ClientLevel.DEFAULT_QUIT_MESSAGE); - this.disconnectWithProgressScreen(); - } - - this.setScreen(new TitleScreen()); - this.addResourcePackLoadFailToast(null); - } - - private void addResourcePackLoadFailToast(@Nullable Component message) { - ToastManager toastManager = this.getToastManager(); - SystemToast.addOrUpdate(toastManager, SystemToast.SystemToastId.PACK_LOAD_FAILURE, Component.translatable("resourcePack.load_fail"), message); - } - - public void triggerResourcePackRecovery(Exception exception) { - if (!this.resourcePackRepository.isAbleToClearAnyPack()) { - if (this.resourcePackRepository.getSelectedIds().size() <= 1) { - LOGGER.error(LogUtils.FATAL_MARKER, exception.getMessage(), (Throwable)exception); - this.emergencySaveAndCrash(new CrashReport(exception.getMessage(), exception)); - } else { - this.schedule(this::abortResourcePackRecovery); - } - } else { - this.clearResourcePacksOnError(exception, Component.translatable("resourcePack.runtime_failure"), null); - } - } - - public void run() { - this.gameThread = Thread.currentThread(); - if (Runtime.getRuntime().availableProcessors() > 4) { - this.gameThread.setPriority(10); - } - - DiscontinuousFrame tickFrame = TracyClient.createDiscontinuousFrame("Client Tick"); - - try { - net.neoforged.neoforge.client.ClientLifecycleHooks.handleClientStarted(this); - - boolean oomRecovery = false; - - while (this.running) { - try { - SingleTickProfiler tickProfiler = SingleTickProfiler.createTickProfiler("Renderer"); - boolean shouldCollectFrameProfile = this.getDebugOverlay().showProfilerChart(); - - try (Profiler.Scope ignored = Profiler.use(this.constructProfiler(shouldCollectFrameProfile, tickProfiler))) { - this.metricsRecorder.startTick(); - tickFrame.start(); - this.window.resetIsResized(); - RenderSystem.pollEvents(); - this.runTick(!oomRecovery); - tickFrame.end(); - this.metricsRecorder.endTick(); - } - - this.finishProfilers(shouldCollectFrameProfile, tickProfiler); - } catch (OutOfMemoryError var10) { - if (oomRecovery) { - throw var10; - } - - this.emergencySave(); - this.setScreen(new OutOfMemoryScreen()); - System.gc(); - LOGGER.error(LogUtils.FATAL_MARKER, "Out of memory", (Throwable)var10); - oomRecovery = true; - } - } - } catch (ReportedException var11) { - LOGGER.error(LogUtils.FATAL_MARKER, "Reported exception thrown!", (Throwable)var11); - this.emergencySaveAndCrash(var11.getReport()); - } catch (Throwable var12) { - LOGGER.error(LogUtils.FATAL_MARKER, "Unreported exception thrown!", var12); - this.emergencySaveAndCrash(new CrashReport("Unexpected error", var12)); - } - } - - void updateFontOptions() { - this.fontManager.updateOptions(this.options); - } - - private void onFullscreenError(int error, long description) { - this.options.enableVsync().set(false); - this.options.save(); - } - - public RenderTarget getMainRenderTarget() { - return this.mainRenderTarget; - } - - public String getLaunchedVersion() { - return this.launchedVersion; - } - - public String getVersionType() { - return this.versionType; - } - - @Override - public void delayCrash(CrashReport crash) { - super.delayCrash(this.fillReport(crash)); - } - - public void emergencySaveAndCrash(CrashReport partialReport) { - MemoryReserve.release(); - CrashReport finalReport = this.fillReport(partialReport); - int exitCode = saveReportAndShutdownSoundManager(this, this.gameDirectory, finalReport); - this.emergencySave(); - net.neoforged.neoforge.server.ServerLifecycleHooks.handleExit(exitCode); - } - - public static int saveReport(File gameDirectory, CrashReport crash) { - Path crashDir = gameDirectory.toPath().resolve("crash-reports"); - Path crashFile = crashDir.resolve("crash-" + Util.getFilenameFormattedDateTime() + "-client.txt"); - Bootstrap.realStdoutPrintln(crash.getFriendlyReport(ReportType.CRASH)); - LOGGER.debug("Disabling console - remaining logs will be available only in log file"); - - byte var4; - try { - if (crash.getSaveFile() != null) { - Bootstrap.realStdoutPrintln("#@!@# Game crashed! Crash report saved to: #@!@# " + crash.getSaveFile().toAbsolutePath()); - return -1; - } - - if (!crash.saveToFile(crashFile, ReportType.CRASH)) { - Bootstrap.realStdoutPrintln("#@?@# Game crashed! Crash report could not be saved. #@?@#"); - return -2; - } - - Bootstrap.realStdoutPrintln("#@!@# Game crashed! Crash report saved to: #@!@# " + crashFile.toAbsolutePath()); - var4 = -1; - } finally { - Bootstrap.shutdownStdout(); - } - - return var4; - } - - public static void crash(@Nullable Minecraft minecraft, File gameDirectory, CrashReport crash) { - int exitCode = saveReportAndShutdownSoundManager(minecraft, gameDirectory, crash); - net.neoforged.neoforge.server.ServerLifecycleHooks.handleExit(exitCode); - } - - private static int saveReportAndShutdownSoundManager(@Nullable Minecraft minecraft, File gameDirectory, CrashReport crash) { - int exitCode = saveReport(gameDirectory, crash); - if (minecraft != null) { - minecraft.soundManager.emergencyShutdown(); - } - - return exitCode; - } - - public boolean isEnforceUnicode() { - return this.options.forceUnicodeFont().get(); - } - - public CompletableFuture reloadResourcePacks() { - return this.reloadResourcePacks(false, null); - } - - private CompletableFuture reloadResourcePacks(boolean isRecovery, Minecraft.@Nullable GameLoadCookie loadCookie) { - if (this.pendingReload != null) { - return this.pendingReload; - } else { - CompletableFuture result = new CompletableFuture<>(); - if (!isRecovery && this.overlay instanceof LoadingOverlay) { - this.pendingReload = result; - return result; - } else { - this.resourcePackRepository.reload(); - List packs = this.resourcePackRepository.openAllSelected(); - if (!isRecovery) { - this.reloadStateTracker.startReload(ResourceLoadStateTracker.ReloadReason.MANUAL, packs); - } - - this.setOverlay( - new LoadingOverlay( - this, - this.resourceManager.createReload(Util.backgroundExecutor().forName("resourceLoad"), this, RESOURCE_RELOAD_INITIAL_TASK, packs), - maybeT -> Util.ifElse(maybeT, t -> { - if (isRecovery) { - this.downloadedPackSource.onRecoveryFailure(); - this.abortResourcePackRecovery(); - } else { - this.rollbackResourcePacks(t, loadCookie); - } - }, () -> { - this.levelRenderer.allChanged(); - this.reloadStateTracker.finishReload(); - this.downloadedPackSource.onReloadSuccess(); - result.complete(null); - this.onResourceLoadFinished(loadCookie); - }), - !isRecovery - ) - ); - return result; - } - } - } - - private void selfTest() { - boolean error = false; - BlockStateModelSet blockModelSet = this.getModelManager().getBlockStateModelSet(); - BlockStateModel missingModel = blockModelSet.missingModel(); - - for (Block block : BuiltInRegistries.BLOCK) { - for (BlockState state : block.getStateDefinition().getPossibleStates()) { - if (state.getRenderShape() == RenderShape.MODEL) { - BlockStateModel model = blockModelSet.get(state); - if (model == missingModel) { - LOGGER.debug("Missing model for: {}", state); - error = true; - } - } - } - } - - TextureAtlasSprite missingIcon = missingModel.particleMaterial().sprite(); - - for (Block block : BuiltInRegistries.BLOCK) { - for (BlockState statex : block.getStateDefinition().getPossibleStates()) { - TextureAtlasSprite particleIcon = blockModelSet.getParticleMaterial(statex).sprite(); - if (!statex.isAir() && particleIcon == missingIcon) { - LOGGER.debug("Missing particle icon for: {}", statex); - } - } - } - - BuiltInRegistries.ITEM.listElements().forEach(holder -> { - Item item = holder.value(); - String descriptionId = item.getDescriptionId(); - String name = Component.translatable(descriptionId).getString(); - if (name.toLowerCase(Locale.ROOT).equals(item.getDescriptionId())) { - LOGGER.debug("Missing translation for: {} {} {}", holder.key().identifier(), descriptionId, item); - } - }); - error |= MenuScreens.selfTest(); - error |= EntityRenderers.validateRegistrations(); - if (error) { - throw new IllegalStateException("Your game data is foobar, fix the errors above!"); - } - } - - public LevelStorageSource getLevelSource() { - return this.levelSource; - } - - public void openChatScreen(ChatComponent.ChatMethod chatMethod) { - if (this.player != null) { - this.gui.getChat().openScreen(chatMethod, ChatScreen::new); - } - } - - public void setScreen(@Nullable Screen screen) { - if (SharedConstants.IS_RUNNING_IN_IDE && Thread.currentThread() != this.gameThread) { - LOGGER.error("setScreen called from non-game thread"); - } - - if (this.screen == null) { - this.setLastInputType(InputType.NONE); - } - - if (screen == null) { - if (this.clientLevelTeardownInProgress) { - throw new IllegalStateException("Trying to return to in-game GUI during disconnection"); - } - - if (this.level == null) { - screen = new TitleScreen(); - } else if (this.player.isDeadOrDying()) { - if (this.player.shouldShowDeathScreen()) { - screen = new DeathScreen(null, this.level.getLevelData().isHardcore(), this.player); - } else { - this.player.respawn(); - } - } else { - screen = this.gui.getChat().restoreChatScreen(); - } - } - - net.neoforged.neoforge.client.ClientHooks.clearGuiLayers(this); - Screen old = this.screen; - if (screen != null) { - var event = new net.neoforged.neoforge.client.event.ScreenEvent.Opening(old, screen); - if (net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(event).isCanceled()) return; - screen = event.getNewScreen(); - } - - if (old != null && screen != old) { - net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.client.event.ScreenEvent.Closing(old)); - old.removed(); - } - - this.screen = screen; - if (this.screen != null) { - this.screen.added(); - } - - if (screen != null) { - this.mouseHandler.releaseMouse(); - KeyMapping.releaseAll(); - screen.init(this.window.getGuiScaledWidth(), this.window.getGuiScaledHeight()); - } else { - this.textInputManager.stopTextInput(); - if (this.level != null) { - KeyMapping.restoreToggleStatesOnScreenClosed(); - } - - this.soundManager.resume(); - this.mouseHandler.grabMouse(); - } - - this.updateTitle(); - } - - public void setOverlay(@Nullable Overlay overlay) { - this.overlay = overlay; - } - - public void destroy() { - try { - net.neoforged.neoforge.client.ClientLifecycleHooks.handleClientStopping(this); - LOGGER.info("Stopping!"); - - try { - this.narrator.destroy(); - } catch (Throwable var7) { - } - - try { - if (this.level != null) { - this.level.disconnect(ClientLevel.DEFAULT_QUIT_MESSAGE); - } - - this.disconnectWithProgressScreen(); - } catch (Throwable var6) { - } - - if (this.screen != null) { - this.screen.removed(); - } - - this.close(); - net.neoforged.neoforge.client.ClientLifecycleHooks.handleClientStopped(this); - } finally { - Util.timeSource = System::nanoTime; - if (!this.hasDelayedCrash()) { - System.exit(0); - } - } - } - - @Override - public void close() { - if (this.currentFrameProfile != null) { - this.currentFrameProfile.cancel(); - } - - try { - this.telemetryManager.close(); - this.regionalCompliancies.close(); - this.atlasManager.close(); - this.fontManager.close(); - this.gameRenderer.close(); - this.shaderManager.close(); - this.levelRenderer.close(); - this.soundManager.destroy(); - this.mapTextureManager.close(); - this.textureManager.close(); - this.resourceManager.close(); - if (this.tracyFrameCapture != null) { - this.tracyFrameCapture.close(); - } - - FreeTypeUtil.destroy(); - Util.shutdownExecutors(); - RenderSystem.getSamplerCache().close(); - RenderSystem.getDevice().close(); - } catch (Throwable var5) { - LOGGER.error("Shutdown failure!", var5); - throw var5; - } finally { - this.window.close(); - } - } - - private void runTick(boolean advanceGameTime) { - this.window.setErrorSection("Pre render"); - if (this.window.shouldClose()) { - this.stop(); - } - - if (this.pendingReload != null && !(this.overlay instanceof LoadingOverlay)) { - CompletableFuture future = this.pendingReload; - this.pendingReload = null; - this.reloadResourcePacks().thenRun(() -> future.complete(null)); - } - - int ticksToDo = advanceGameTime ? this.deltaTracker.advanceGameTime(Util.getMillis()) : 0; - ProfilerFiller profiler = Profiler.get(); - if (advanceGameTime) { - try (Gizmos.TemporaryCollection ignored = this.collectPerTickGizmos()) { - profiler.push("scheduledPacketProcessing"); - this.packetProcessor.processQueuedPackets(); - profiler.popPush("scheduledExecutables"); - this.runAllTasks(); - profiler.pop(); - } - - profiler.push("tick"); - if (ticksToDo > 0 && this.isLevelRunningNormally()) { - profiler.push("textures"); - this.textureManager.tick(); - profiler.pop(); - } - - for (int i = 0; i < Math.min(10, ticksToDo); i++) { - profiler.incrementCounter("clientTick"); - - try (Gizmos.TemporaryCollection ignored = this.collectPerTickGizmos()) { - this.tick(); - } - } - - if (ticksToDo > 0 && (this.level == null || this.level.tickRateManager().runsNormally())) { - this.drainedLatestTickGizmos = this.perTickGizmos.drainGizmos(); - } - - profiler.pop(); - } - - this.window.setErrorSection("Render"); - - try (Gizmos.TemporaryCollection ignored = this.levelRenderer.collectPerFrameGizmos()) { - profiler.push("sound"); - this.soundManager.updateSource(this.gameRenderer.getMainCamera()); - profiler.popPush("toasts"); - this.toastManager.update(); - profiler.popPush("mouse"); - this.mouseHandler.handleAccumulatedMovement(); - profiler.popPush("frame"); - this.renderFrame(advanceGameTime); - profiler.pop(); - } - - this.window.setErrorSection("Post render"); - boolean previouslyPaused = this.pause; - boolean pause = this.hasSingleplayerServer() - && (this.screen != null && this.screen.isPauseScreen() || this.overlay != null && this.overlay.isPauseScreen()) - && !this.singleplayerServer.isPublished(); - if (pause != this.pause && !net.neoforged.neoforge.client.ClientHooks.onClientPauseChangePre(pause)) { - this.pause = pause; - net.neoforged.neoforge.client.ClientHooks.onClientPauseChangePost(pause); - } - if (!previouslyPaused && this.pause) { - this.soundManager.pauseAllExcept(SoundSource.MUSIC, SoundSource.UI); - } - - this.deltaTracker.updatePauseState(this.pause); - this.deltaTracker.updateFrozenState(!this.isLevelRunningNormally()); - } - - private void renderFrame(boolean advanceGameTime) { - ProfilerFiller profiler = Profiler.get(); - profiler.push("update"); - this.deltaTracker.advanceRealTime(Util.getMillis()); - boolean recordGpuUtilization; - if (!this.debugEntries.isCurrentlyEnabled(DebugScreenEntries.GPU_UTILIZATION) && !this.metricsRecorder.isRecording()) { - recordGpuUtilization = false; - this.gpuUtilization = 0.0; - } else { - recordGpuUtilization = (this.currentFrameProfile == null || this.currentFrameProfile.isDone()) && !TimerQuery.getInstance().isRecording(); - if (recordGpuUtilization) { - TimerQuery.getInstance().beginProfile(); - } - } - - long renderStartTimer = Util.getNanos(); - this.pauseIfInactive(); - this.window.updateFullscreenIfChanged(); - if (this.isGameLoadFinished() && advanceGameTime && this.level != null) { - this.level.update(); - } - - this.gameRenderer.update(this.deltaTracker, advanceGameTime); - float worldPartialTicks = this.deltaTracker.getGameTimeDeltaPartialTick(false); - this.pick(worldPartialTicks); - profiler.popPush("extract"); - this.gameRenderer.getGameRenderState().framerateLimit = this.framerateLimitTracker.getFramerateLimit(); - this.gameRenderer.extract(this.deltaTracker, advanceGameTime); - profiler.popPush("gpuAsync"); - RenderSystem.executePendingTasks(); - profiler.pop(); - net.neoforged.neoforge.client.ClientHooks.fireRenderFramePre(this.deltaTracker); - this.gameRenderer.render(this.deltaTracker, advanceGameTime); - net.neoforged.neoforge.client.ClientHooks.fireRenderFramePost(this.deltaTracker); - profiler.push("present"); - if (!this.gameRenderer.getGameRenderState().windowRenderState.isMinimized) { - this.mainRenderTarget.blitToScreen(); - } - - this.frameTimeNs = Util.getNanos() - renderStartTimer; - if (recordGpuUtilization) { - this.currentFrameProfile = TimerQuery.getInstance().endProfile(); - } - - profiler.popPush("swapBuffers"); - if (this.tracyFrameCapture != null) { - this.tracyFrameCapture.upload(); - this.tracyFrameCapture.capture(this.mainRenderTarget); - } - - RenderSystem.flipFrame(this.tracyFrameCapture); - profiler.popPush("frameLimiter"); - int framerateLimit = this.gameRenderer.getGameRenderState().framerateLimit; - if (framerateLimit < 260) { - FramerateLimiter.limitDisplayFPS(framerateLimit); - } - - profiler.popPush("fpsUpdate"); - this.frames++; - long currentTime = Util.getNanos(); - long frameDuration = currentTime - this.lastNanoTime; - if (recordGpuUtilization) { - this.savedCpuDuration = frameDuration; - } - - this.getDebugOverlay().logFrameDuration(frameDuration); - this.lastNanoTime = currentTime; - if (this.currentFrameProfile != null && this.currentFrameProfile.isDone()) { - this.gpuUtilization = this.currentFrameProfile.get() * 100.0 / this.savedCpuDuration; - } - - while (Util.getMillis() >= this.lastTime + 1000L) { - fps = this.frames; - this.lastTime += 1000L; - this.frames = 0; - } - - profiler.pop(); - } - - private void pauseIfInactive() { - if (!this.window.isFocused() && this.options.pauseOnLostFocus && (!this.options.touchscreen().get() || !this.mouseHandler.isRightPressed())) { - if (Util.getMillis() - this.lastActiveTime > 500L) { - this.pauseGame(false); - } - } else { - this.lastActiveTime = Util.getMillis(); - } - } - - private ProfilerFiller constructProfiler(boolean shouldCollectFrameProfile, @Nullable SingleTickProfiler tickProfiler) { - if (!shouldCollectFrameProfile) { - this.fpsPieProfiler.disable(); - if (!this.metricsRecorder.isRecording() && tickProfiler == null) { - return InactiveProfiler.INSTANCE; - } - } - - ProfilerFiller result; - if (shouldCollectFrameProfile) { - if (!this.fpsPieProfiler.isEnabled()) { - this.fpsPieRenderTicks = 0; - this.fpsPieProfiler.enable(); - } - - this.fpsPieRenderTicks++; - result = this.fpsPieProfiler.getFiller(); - } else { - result = InactiveProfiler.INSTANCE; - } - - if (this.metricsRecorder.isRecording()) { - result = ProfilerFiller.combine(result, this.metricsRecorder.getProfiler()); - } - - return SingleTickProfiler.decorateFiller(result, tickProfiler); - } - - private void finishProfilers(boolean shouldCollectFrameProfile, @Nullable SingleTickProfiler tickProfiler) { - if (tickProfiler != null) { - tickProfiler.endTick(); - } - - ProfilerPieChart profilerPieChart = this.getDebugOverlay().getProfilerPieChart(); - if (shouldCollectFrameProfile) { - profilerPieChart.setPieChartResults(this.fpsPieProfiler.getResults()); - } else { - profilerPieChart.setPieChartResults(null); - } - } - - @Override - public void resizeGui() { - int guiScale = this.window.calculateScale(this.options.guiScale().get(), this.isEnforceUnicode()); - this.window.setGuiScale(guiScale); - net.neoforged.neoforge.client.ClientHooks.fireWindowResize(this.window); - if (this.screen != null) { - this.screen.resize(this.window.getGuiScaledWidth(), this.window.getGuiScaledHeight()); - net.neoforged.neoforge.client.ClientHooks.resizeGuiLayers(this.window.getGuiScaledWidth(), this.window.getGuiScaledHeight()); - } - - this.mouseHandler.setIgnoreFirstMove(); - } - - @Override - public void cursorEntered() { - this.mouseHandler.cursorEntered(); - } - - public int getFps() { - return fps; - } - - public long getFrameTimeNs() { - return this.frameTimeNs; - } - - public void sendLowDiskSpaceWarning() { - this.execute(() -> SystemToast.onLowDiskSpace(this)); - } - - private void emergencySave() { - MemoryReserve.release(); - - try { - if (this.isLocalServer && this.singleplayerServer != null) { - this.singleplayerServer.halt(true); - } - - this.disconnectWithSavingScreen(); - } catch (Throwable var2) { - } - - System.gc(); - } - - public boolean debugClientMetricsStart(Consumer debugFeedback) { - if (this.metricsRecorder.isRecording()) { - this.debugClientMetricsStop(); - return false; - } else { - Consumer onStopped = results -> { - if (results != EmptyProfileResults.EMPTY) { - int ticks = results.getTickDuration(); - double durationInSeconds = (double)results.getNanoDuration() / TimeUtil.NANOSECONDS_PER_SECOND; - this.execute( - () -> debugFeedback.accept( - Component.translatable( - "commands.debug.stopped", - String.format(Locale.ROOT, "%.2f", durationInSeconds), - ticks, - String.format(Locale.ROOT, "%.2f", ticks / durationInSeconds) - ) - ) - ); - } - }; - Consumer onFinished = profilePath -> { - Component profilePathComponent = Component.literal(profilePath.toString()) - .withStyle(ChatFormatting.UNDERLINE) - .withStyle(s -> s.withClickEvent(new ClickEvent.OpenFile(profilePath.getParent()))); - this.execute(() -> debugFeedback.accept(Component.translatable("debug.profiling.stop", profilePathComponent))); - }; - SystemReport systemReport = fillSystemReport(new SystemReport(), this, this.languageManager, this.launchedVersion, this.options); - Consumer> profileReports = logs -> { - Path profilePath = this.archiveProfilingReport(systemReport, logs); - onFinished.accept(profilePath); - }; - Consumer whenClientMetricsRecordingFinished; - if (this.singleplayerServer == null) { - whenClientMetricsRecordingFinished = path -> profileReports.accept(ImmutableList.of(path)); - } else { - this.singleplayerServer.fillSystemReport(systemReport); - CompletableFuture clientMetricRecordingResult = new CompletableFuture<>(); - CompletableFuture serverMetricRecordingResult = new CompletableFuture<>(); - CompletableFuture.allOf(clientMetricRecordingResult, serverMetricRecordingResult) - .thenRunAsync( - () -> profileReports.accept(ImmutableList.of(clientMetricRecordingResult.join(), serverMetricRecordingResult.join())), Util.ioPool() - ); - this.singleplayerServer.startRecordingMetrics(ignored -> {}, serverMetricRecordingResult::complete); - whenClientMetricsRecordingFinished = clientMetricRecordingResult::complete; - } - - this.metricsRecorder = ActiveMetricsRecorder.createStarted( - new ClientMetricsSamplersProvider(Util.timeSource, this.levelRenderer), - Util.timeSource, - Util.ioPool(), - new MetricsPersister("client"), - results -> { - this.metricsRecorder = InactiveMetricsRecorder.INSTANCE; - onStopped.accept(results); - }, - whenClientMetricsRecordingFinished - ); - return true; - } - } - - private void debugClientMetricsStop() { - this.metricsRecorder.end(); - if (this.singleplayerServer != null) { - this.singleplayerServer.finishRecordingMetrics(); - } - } - - private void debugClientMetricsCancel() { - this.metricsRecorder.cancel(); - if (this.singleplayerServer != null) { - this.singleplayerServer.cancelRecordingMetrics(); - } - } - - private Path archiveProfilingReport(SystemReport systemReport, List profilingResultPaths) { - String levelName; - if (this.isLocalServer()) { - levelName = this.getSingleplayerServer().getWorldData().getLevelName(); - } else { - ServerData server = this.getCurrentServer(); - levelName = server != null ? server.name : "unknown"; - } - - Path archivePath; - try { - String profilingName = String.format( - Locale.ROOT, "%s-%s-%s", Util.getFilenameFormattedDateTime(), levelName, SharedConstants.getCurrentVersion().id() - ); - String zipFileName = FileUtil.findAvailableName(MetricsPersister.PROFILING_RESULTS_DIR, profilingName, ".zip"); - archivePath = MetricsPersister.PROFILING_RESULTS_DIR.resolve(zipFileName); - } catch (IOException var21) { - throw new UncheckedIOException(var21); - } - - try (FileZipper fileZipper = new FileZipper(archivePath)) { - fileZipper.add(Paths.get("system.txt"), systemReport.toLineSeparatedString()); - fileZipper.add(Paths.get("client").resolve(this.options.getFile().getName()), this.options.dumpOptionsForReport()); - profilingResultPaths.forEach(fileZipper::add); - } finally { - for (Path path : profilingResultPaths) { - try { - FileUtils.forceDelete(path.toFile()); - } catch (IOException var18) { - LOGGER.warn("Failed to delete temporary profiling result {}", path, var18); - } - } - } - - return archivePath; - } - - public void stop() { - if (this.isRunning()) net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.event.GameShuttingDownEvent()); - this.running = false; - } - - public boolean isRunning() { - return this.running; - } - - public void pauseGame(boolean suppressPauseMenuIfWeReallyArePausing) { - if (this.screen == null) { - boolean canGameReallyBePaused = this.hasSingleplayerServer() && !this.singleplayerServer.isPublished(); - if (canGameReallyBePaused) { - this.setScreen(new PauseScreen(!suppressPauseMenuIfWeReallyArePausing)); - } else { - this.setScreen(new PauseScreen(true)); - } - } - } - - private void continueAttack(boolean down) { - if (!down) { - this.missTime = 0; - } - - if (this.missTime <= 0 && !this.player.isUsingItem()) { - ItemStack heldItem = this.player.getItemInHand(InteractionHand.MAIN_HAND); - if (!heldItem.has(DataComponents.PIERCING_WEAPON)) { - if (down && this.hitResult != null && this.hitResult.getType() == HitResult.Type.BLOCK) { - BlockHitResult blockHit = (BlockHitResult)this.hitResult; - BlockPos pos = blockHit.getBlockPos(); - if (!this.level.getBlockState(pos).isAir()) { - Direction direction = blockHit.getDirection(); - var inputEvent = net.neoforged.neoforge.client.ClientHooks.onClickInput(0, this.options.keyAttack, InteractionHand.MAIN_HAND); - if (inputEvent.isCanceled()) { - if (inputEvent.shouldSwingHand()) { - this.level.addBreakingBlockEffect(pos, direction, blockHit); - this.player.swing(InteractionHand.MAIN_HAND); - } - return; - } - if (this.gameMode.continueDestroyBlock(pos, direction) && inputEvent.shouldSwingHand()) { - this.level.addBreakingBlockEffect(pos, direction, blockHit); - this.player.swing(InteractionHand.MAIN_HAND); - } - } - } else { - this.gameMode.stopDestroyBlock(); - } - } - } - } - - private boolean startAttack() { - if (this.missTime > 0) { - return false; - } else if (this.hitResult == null) { - LOGGER.error("Null returned as 'hitResult', this shouldn't happen!"); - if (this.gameMode.hasMissTime()) { - this.missTime = 10; - } - - return false; - } else if (this.player.isHandsBusy()) { - return false; - } else if (this.gameMode.isSpectator()) { - if (this.hitResult instanceof EntityHitResult entityHitResult) { - this.gameMode.spectate(entityHitResult.getEntity()); - } - - return true; - } else { - ItemStack heldItem = this.player.getItemInHand(InteractionHand.MAIN_HAND); - if (!heldItem.isItemEnabled(this.level.enabledFeatures())) { - return false; - } else if (this.player.cannotAttackWithItem(heldItem, 0)) { - return false; - } else { - boolean endAttack = false; - var inputEvent = net.neoforged.neoforge.client.ClientHooks.onClickInput(0, this.options.keyAttack, InteractionHand.MAIN_HAND); - if (inputEvent.isCanceled()) { - if (inputEvent.shouldSwingHand()) - this.player.swing(InteractionHand.MAIN_HAND); - return endAttack; - } - PiercingWeapon piercingWeapon = heldItem.get(DataComponents.PIERCING_WEAPON); - if (piercingWeapon != null) { - this.gameMode.piercingAttack(piercingWeapon); - if (inputEvent.shouldSwingHand()) - this.player.swing(InteractionHand.MAIN_HAND); - return true; - } else { - switch (this.hitResult.getType()) { - case ENTITY: - AttackRange customItemRange = heldItem.get(DataComponents.ATTACK_RANGE); - if (customItemRange == null || customItemRange.isInRange(this.player, this.hitResult.getLocation())) { - this.gameMode.attack(this.player, ((EntityHitResult)this.hitResult).getEntity()); - } - break; - case BLOCK: - BlockHitResult blockHit = (BlockHitResult)this.hitResult; - BlockPos pos = blockHit.getBlockPos(); - if (!this.level.getBlockState(pos).isAir()) { - this.gameMode.startDestroyBlock(pos, blockHit.getDirection()); - if (this.level.getBlockState(pos).isAir()) { - endAttack = true; - } - break; - } - case MISS: - if (this.gameMode.hasMissTime()) { - this.missTime = 10; - } - - this.player.resetAttackStrengthTicker(); - net.neoforged.neoforge.common.CommonHooks.onEmptyLeftClick(this.player); - } - - if (inputEvent.shouldSwingHand()) - this.player.swing(InteractionHand.MAIN_HAND); - return endAttack; - } - } - } - } - - private void startUseItem() { - if (!this.gameMode.isDestroying()) { - this.rightClickDelay = 4; - if (!this.player.isHandsBusy()) { - if (this.hitResult == null) { - LOGGER.warn("Null returned as 'hitResult', this shouldn't happen!"); - } - - for (InteractionHand hand : InteractionHand.values()) { - var inputEvent = net.neoforged.neoforge.client.ClientHooks.onClickInput(1, this.options.keyUse, hand); - if (inputEvent.isCanceled()) { - if (inputEvent.shouldSwingHand()) this.player.swing(hand); - return; - } - ItemStack heldItem = this.player.getItemInHand(hand); - if (!heldItem.isItemEnabled(this.level.enabledFeatures())) { - return; - } - - if (this.hitResult != null) { - switch (this.hitResult.getType()) { - case ENTITY: - EntityHitResult entityHit = (EntityHitResult)this.hitResult; - Entity entity = entityHit.getEntity(); - if (!this.level.getWorldBorder().isWithinBounds(entity.blockPosition())) { - return; - } - - if (this.player.isWithinEntityInteractionRange(entity, 0.0) - && this.gameMode.interact(this.player, entity, entityHit, hand) instanceof InteractionResult.Success success) { - if (success.swingSource() == InteractionResult.SwingSource.CLIENT && inputEvent.shouldSwingHand()) { - this.player.swing(hand); - } - - return; - } - break; - case BLOCK: - BlockHitResult blockHit = (BlockHitResult)this.hitResult; - int oldCount = heldItem.getCount(); - InteractionResult useResult = this.gameMode.useItemOn(this.player, hand, blockHit); - if (useResult instanceof InteractionResult.Success success) { - if (success.swingSource() == InteractionResult.SwingSource.CLIENT && inputEvent.shouldSwingHand()) { - this.player.swing(hand); - if (!heldItem.isEmpty() && (heldItem.getCount() != oldCount || this.player.hasInfiniteMaterials())) { - this.gameRenderer.itemInHandRenderer.itemUsed(hand); - } - } - - return; - } - - if (useResult instanceof InteractionResult.Fail) { - return; - } - } - } - - if (heldItem.isEmpty() && (this.hitResult == null || this.hitResult.getType() == HitResult.Type.MISS)) - net.neoforged.neoforge.common.CommonHooks.onEmptyClick(this.player, hand); - - if (!heldItem.isEmpty() && this.gameMode.useItem(this.player, hand) instanceof InteractionResult.Success success) { - if (success.swingSource() == InteractionResult.SwingSource.CLIENT && inputEvent.shouldSwingHand()) { - this.player.swing(hand); - } - - this.gameRenderer.itemInHandRenderer.itemUsed(hand); - return; - } - } - } - } - } - - public MusicManager getMusicManager() { - return this.musicManager; - } - - public void tick() { - this.clientTickCount++; - if (this.gameLoadFinished) { - net.neoforged.neoforge.client.ClientHooks.fireClientTickPre(); - } - - if (this.level != null && !this.pause) { - this.level.tickRateManager().tick(); - } - - if (this.rightClickDelay > 0) { - this.rightClickDelay--; - } - - ProfilerFiller profiler = Profiler.get(); - profiler.push("gui"); - this.textInputManager.tick(); - this.chatListener.tick(); - this.gui.tick(this.pause); - profiler.pop(); - this.pick(1.0F); - this.tutorial.onLookAt(this.level, this.hitResult); - profiler.push("gameMode"); - if (!this.pause && this.level != null) { - this.gameMode.tick(); - } - - profiler.popPush("screen"); - if (this.screen != null || this.player == null) { - if (this.screen instanceof InBedChatScreen inBedScreen && !this.player.isSleeping()) { - inBedScreen.onPlayerWokeUp(); - } - } else if (this.player.isDeadOrDying() && !(this.screen instanceof DeathScreen)) { - this.setScreen(null); - } else if (this.player.isSleeping() && this.level != null) { - this.gui.getChat().openScreen(ChatComponent.ChatMethod.MESSAGE, InBedChatScreen::new); - } - - if (this.screen != null) { - this.missTime = 10000; - } - - if (this.screen != null) { - try { - this.screen.tick(); - } catch (Throwable var5) { - CrashReport report = CrashReport.forThrowable(var5, "Ticking screen"); - this.screen.fillCrashDetails(report); - throw new ReportedException(report); - } - } - - if (this.overlay != null) { - this.overlay.tick(); - } - - if (!this.getDebugOverlay().showDebugScreen()) { - this.gui.clearCache(); - } - - if (this.overlay == null && this.screen == null) { - profiler.popPush("Keybindings"); - this.handleKeybinds(); - if (this.missTime > 0) { - this.missTime--; - } - } - - if (this.level != null) { - if (!this.pause) { - profiler.popPush("gameRenderer"); - this.gameRenderer.tick(); - profiler.popPush("entities"); - this.level.tickEntities(); - profiler.popPush("blockEntities"); - this.level.tickBlockEntities(); - } - } else if (this.gameRenderer.currentPostEffect() != null) { - this.gameRenderer.clearPostEffect(); - } - - this.musicManager.tick(); - this.soundManager.tick(this.pause); - if (this.level != null) { - if (!this.pause) { - profiler.popPush("level"); - if (!this.options.joinedFirstServer && this.isMultiplayerServer()) { - Component title = Component.translatable("tutorial.socialInteractions.title"); - Component message = Component.translatable("tutorial.socialInteractions.description", Tutorial.key("socialInteractions")); - this.socialInteractionsToast = new TutorialToast(this.font, TutorialToast.Icons.SOCIAL_INTERACTIONS, title, message, true, 8000); - this.toastManager.addToast(this.socialInteractionsToast); - this.options.joinedFirstServer = true; - this.options.save(); - } - - this.tutorial.tick(); - - net.neoforged.neoforge.event.EventHooks.fireLevelTickPre(this.level, () -> true); - try { - this.level.tick(() -> true); - } catch (Throwable var6) { - CrashReport report = CrashReport.forThrowable(var6, "Exception in world tick"); - if (this.level == null) { - CrashReportCategory levelCategory = report.addCategory("Affected level"); - levelCategory.setDetail("Problem", "Level is null!"); - } else { - this.level.fillReportDetails(report); - } - - throw new ReportedException(report); - } - net.neoforged.neoforge.event.EventHooks.fireLevelTickPost(this.level, () -> true); - } - - profiler.popPush("animateTick"); - if (!this.pause && this.isLevelRunningNormally()) { - this.level.animateTick(this.player.getBlockX(), this.player.getBlockY(), this.player.getBlockZ()); - } - - profiler.popPush("particles"); - if (!this.pause && this.isLevelRunningNormally()) { - this.particleEngine.tick(); - } - - ClientPacketListener connection = this.getConnection(); - if (connection != null && !this.pause) { - connection.send(ServerboundClientTickEndPacket.INSTANCE); - } - } else if (this.pendingConnection != null) { - profiler.popPush("pendingConnection"); - this.pendingConnection.tick(); - } - - profiler.popPush("keyboard"); - this.keyboardHandler.tick(); - profiler.pop(); - - if (this.gameLoadFinished) { - net.neoforged.neoforge.client.ClientHooks.fireClientTickPost(); - } - } - - private boolean isLevelRunningNormally() { - return this.level == null || this.level.tickRateManager().runsNormally(); - } - - private boolean isMultiplayerServer() { - return !this.isLocalServer || this.singleplayerServer != null && this.singleplayerServer.isPublished(); - } - - private void handleKeybinds() { - while (this.options.keyTogglePerspective.consumeClick()) { - CameraType previous = this.options.getCameraType(); - this.options.setCameraType(this.options.getCameraType().cycle()); - if (previous.isFirstPerson() != this.options.getCameraType().isFirstPerson()) { - this.gameRenderer.checkEntityPostEffect(this.options.getCameraType().isFirstPerson() ? this.getCameraEntity() : null); - } - - this.levelRenderer.needsUpdate(); - } - - while (this.options.keySmoothCamera.consumeClick()) { - this.options.smoothCamera = !this.options.smoothCamera; - } - - while (this.options.keyToggleGui.consumeClick()) { - this.options.hideGui = !this.options.hideGui; - } - - while (this.options.keyToggleSpectatorShaderEffects.consumeClick()) { - this.gameRenderer.togglePostEffect(); - } - - for (int i = 0; i < 9; i++) { - boolean savePressed = this.options.keySaveHotbarActivator.isDown(); - boolean loadPressed = this.options.keyLoadHotbarActivator.isDown(); - if (this.options.keyHotbarSlots[i].consumeClick()) { - if (this.player.isSpectator()) { - this.gui.getSpectatorGui().onHotbarSelected(i); - } else if (!this.player.hasInfiniteMaterials() || this.screen != null || !loadPressed && !savePressed) { - this.player.getInventory().setSelectedSlot(i); - } else { - CreativeModeInventoryScreen.handleHotbarLoadOrSave(this, i, loadPressed, savePressed); - } - } - } - - while (this.options.keySocialInteractions.consumeClick()) { - if (!this.isMultiplayerServer() && !SharedConstants.DEBUG_SOCIAL_INTERACTIONS) { - this.chatListener.handleOverlay(SOCIAL_INTERACTIONS_NOT_AVAILABLE); - this.narrator.saySystemNow(SOCIAL_INTERACTIONS_NOT_AVAILABLE); - } else { - if (this.socialInteractionsToast != null) { - this.socialInteractionsToast.hide(); - this.socialInteractionsToast = null; - } - - this.setScreen(new SocialInteractionsScreen()); - } - } - - while (this.options.keyInventory.consumeClick()) { - if (this.gameMode.isServerControlledInventory()) { - this.player.sendOpenInventory(); - } else { - this.tutorial.onOpenInventory(); - this.setScreen(new InventoryScreen(this.player)); - } - } - - while (this.options.keyAdvancements.consumeClick()) { - this.setScreen(new AdvancementsScreen(this.player.connection.getAdvancements())); - } - - while (this.options.keyQuickActions.consumeClick()) { - this.getQuickActionsDialog().ifPresent(dialog -> this.player.connection.showDialog((Holder)dialog, this.screen)); - } - - while (this.options.keySwapOffhand.consumeClick()) { - if (!this.player.isSpectator()) { - this.getConnection() - .send(new ServerboundPlayerActionPacket(ServerboundPlayerActionPacket.Action.SWAP_ITEM_WITH_OFFHAND, BlockPos.ZERO, Direction.DOWN)); - } - } - - while (this.options.keyDrop.consumeClick()) { - if (!this.player.isSpectator() && this.player.drop(this.hasControlDown())) { - this.player.swing(InteractionHand.MAIN_HAND); - } - } - - while (this.options.keyChat.consumeClick()) { - this.openChatScreen(ChatComponent.ChatMethod.MESSAGE); - } - - if (this.screen == null && this.overlay == null && this.options.keyCommand.consumeClick()) { - this.openChatScreen(ChatComponent.ChatMethod.COMMAND); - } - - boolean instantAttack = false; - if (this.player.isUsingItem()) { - if (!this.options.keyUse.isDown()) { - this.gameMode.releaseUsingItem(this.player); - } - - while (this.options.keyAttack.consumeClick()) { - } - - while (this.options.keyUse.consumeClick()) { - } - - while (this.options.keyPickItem.consumeClick()) { - } - } else { - while (this.options.keyAttack.consumeClick()) { - instantAttack |= this.startAttack(); - } - - while (this.options.keyUse.consumeClick()) { - this.startUseItem(); - } - - while (this.options.keyPickItem.consumeClick()) { - this.pickBlockOrEntity(); - } - - if (this.player.isSpectator()) { - while (this.options.keySpectatorHotbar.consumeClick()) { - this.gui.getSpectatorGui().onHotbarActionKeyPressed(); - } - } - } - - if (this.options.keyUse.isDown() && this.rightClickDelay == 0 && !this.player.isUsingItem()) { - this.startUseItem(); - } - - this.continueAttack(this.screen == null && !instantAttack && this.options.keyAttack.isDown() && this.mouseHandler.isMouseGrabbed()); - } - - private Optional> getQuickActionsDialog() { - Registry dialogRegistry = this.player.connection.registryAccess().lookupOrThrow(Registries.DIALOG); - return dialogRegistry.get(DialogTags.QUICK_ACTIONS).flatMap(quickActions -> { - if (quickActions.size() == 0) { - return Optional.empty(); - } else { - return quickActions.size() == 1 ? Optional.of(quickActions.get(0)) : dialogRegistry.get(Dialogs.QUICK_ACTIONS); - } - }); - } - - public ClientTelemetryManager getTelemetryManager() { - return this.telemetryManager; - } - - public double getGpuUtilization() { - return this.gpuUtilization; - } - - public ProfileKeyPairManager getProfileKeyPairManager() { - return this.profileKeyPairManager; - } - - public WorldOpenFlows createWorldOpenFlows() { - return new WorldOpenFlows(this, this.levelSource); - } - - public void doWorldLoad( - LevelStorageSource.LevelStorageAccess levelSourceAccess, - PackRepository packRepository, - WorldStem worldStem, - Optional gameRules, - boolean newWorld - ) { - this.disconnectWithProgressScreen(); - Instant worldLoadStart = Instant.now(); - LevelLoadTracker loadTracker = new LevelLoadTracker(newWorld ? 500L : 0L); - LevelLoadingScreen screen = new LevelLoadingScreen(loadTracker, LevelLoadingScreen.Reason.OTHER); - this.setScreen(screen); - int chunkStatusViewRadius = Math.max(5, 3) + ChunkLevel.RADIUS_AROUND_FULL_CHUNK + 1; - - try { - levelSourceAccess.saveDataTag(worldStem.worldDataAndGenSettings().data()); - LevelLoadListener loadListener = LevelLoadListener.compose(loadTracker, LoggingLevelLoadListener.forSingleplayer()); - this.singleplayerServer = MinecraftServer.spin( - thread -> new IntegratedServer(thread, this, levelSourceAccess, packRepository, worldStem, gameRules, this.services, loadListener) - ); - loadTracker.setServerChunkStatusView(this.singleplayerServer.createChunkLoadStatusView(chunkStatusViewRadius)); - this.isLocalServer = true; - this.updateReportEnvironment(ReportEnvironment.local()); - this.quickPlayLog - .setWorldData(QuickPlayLog.Type.SINGLEPLAYER, levelSourceAccess.getLevelId(), worldStem.worldDataAndGenSettings().data().getLevelName()); - } catch (Throwable var16) { - CrashReport report = CrashReport.forThrowable(var16, "Starting integrated server"); - CrashReportCategory category = report.addCategory("Starting integrated server"); - category.setDetail("Level ID", levelSourceAccess.getLevelId()); - category.setDetail("Level Name", () -> worldStem.worldDataAndGenSettings().data().getLevelName()); - throw new ReportedException(report); - } - - ProfilerFiller profiler = Profiler.get(); - profiler.push("waitForServer"); - long tickLengthNs = TimeUnit.SECONDS.toNanos(1L) / 60L; - - while (!this.singleplayerServer.isReady() || this.overlay != null) { - long finishTime = Util.getNanos() + tickLengthNs; - screen.tick(); - if (this.overlay != null) { - this.overlay.tick(); - } - - this.renderFrame(false); - this.runAllTasks(); - this.managedBlock(() -> Util.getNanos() > finishTime); - } - - profiler.pop(); - Duration worldLoadDuration = Duration.between(worldLoadStart, Instant.now()); - SocketAddress socketAddress = this.singleplayerServer.getConnection().startMemoryChannel(); - Connection connection = Connection.connectToLocalServer(socketAddress); - connection.initiateServerboundPlayConnection( - socketAddress.toString(), - 0, - new ClientHandshakePacketListenerImpl(connection, this, null, null, newWorld, worldLoadDuration, status -> {}, loadTracker, null) - ); - connection.send(new ServerboundHelloPacket(this.getUser().getName(), this.getUser().getProfileId())); - this.pendingConnection = connection; - } - - public void setLevel(ClientLevel level) { - if (this.level != null) net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.event.level.LevelEvent.Unload(this.level)); - this.level = level; - this.updateLevelInEngines(level); - } - - public void disconnectFromWorld(Component message) { - boolean localServer = this.isLocalServer(); - ServerData currentServer = this.getCurrentServer(); - if (this.level != null) { - this.level.disconnect(message); - } - - if (localServer) { - this.disconnectWithSavingScreen(); - } else { - this.disconnectWithProgressScreen(); - } - - TitleScreen titleScreen = new TitleScreen(); - if (localServer) { - this.setScreen(titleScreen); - } else if (currentServer != null && currentServer.isRealm()) { - this.setScreen(new RealmsMainScreen(titleScreen)); - } else { - this.setScreen(new JoinMultiplayerScreen(titleScreen)); - } - } - - public void disconnectWithSavingScreen() { - this.disconnect(new GenericMessageScreen(SAVING_LEVEL), false); - } - - public void disconnectWithProgressScreen() { - this.disconnectWithProgressScreen(true); - } - - public void disconnectWithProgressScreen(boolean stopSound) { - this.disconnect(new ProgressScreen(true), false, stopSound); - } - - public void disconnect(Screen screen, boolean keepResourcePacks) { - this.disconnect(screen, keepResourcePacks, true); - } - - public void disconnect(Screen screen, boolean keepResourcePacks, boolean stopSound) { - ClientPacketListener connection = this.getConnection(); - if (connection != null) { - this.dropAllTasks(); - connection.close(); - if (!keepResourcePacks) { - this.clearDownloadedResourcePacks(); - } - } - - this.playerSocialManager.stopOnlineMode(); - if (this.metricsRecorder.isRecording()) { - this.debugClientMetricsCancel(); - } - - IntegratedServer server = this.singleplayerServer; - this.singleplayerServer = null; - this.gameRenderer.resetData(); - net.neoforged.neoforge.client.ClientHooks.firePlayerLogout(this.gameMode, this.player); - this.gameMode = null; - this.narrator.clear(); - this.clientLevelTeardownInProgress = true; - - var shouldRevertRegistriesToFrozen = this.getConnection() != null && this.getConnection().getConnection() != null; // Neo: Track whether to revert registries after disconnect - try { - if (this.level != null) { - this.gui.onDisconnected(); - net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.event.level.LevelEvent.Unload(this.level)); - } - - this.level = null; - if (server != null) { - server.halt(false); - this.setScreen(new GenericMessageScreen(SAVING_LEVEL)); - ProfilerFiller profiler = Profiler.get(); - profiler.push("waitForServer"); - - while (!server.isShutdown()) { - this.renderFrame(false); - } - - profiler.pop(); - } - - this.setScreenAndShow(screen); - this.isLocalServer = false; - this.updateLevelInEngines(null, stopSound); - this.player = null; - } finally { - this.clientLevelTeardownInProgress = false; - } - if(shouldRevertRegistriesToFrozen) net.neoforged.neoforge.registries.RegistryManager.revertToFrozen(); // Neo: Revert registries to frozen on disconnect - } - - public void clearDownloadedResourcePacks() { - this.downloadedPackSource.cleanupAfterDisconnect(); - this.runAllTasks(); - } - - public void clearClientLevel(Screen screen) { - ClientPacketListener connection = this.getConnection(); - if (connection != null) { - connection.clearLevel(); - } - - if (this.metricsRecorder.isRecording()) { - this.debugClientMetricsCancel(); - } - - this.gameRenderer.resetData(); - this.gameMode = null; - this.narrator.clear(); - this.clientLevelTeardownInProgress = true; - - try { - this.setScreenAndShow(screen); - this.gui.onDisconnected(); - if (this.level != null) net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.event.level.LevelEvent.Unload(this.level)); - this.level = null; - this.updateLevelInEngines(null); - this.player = null; - } finally { - this.clientLevelTeardownInProgress = false; - } - } - - public void setScreenAndShow(Screen screen) { - try (Zone ignored = Profiler.get().zone("forcedTick")) { - this.setScreen(screen); - this.renderFrame(false); - } - } - - private void updateLevelInEngines(@Nullable ClientLevel level) { - this.updateLevelInEngines(level, true); - } - - private void updateLevelInEngines(@Nullable ClientLevel level, boolean stopSound) { - if (stopSound) { - this.soundManager.stop(); - } - - this.setCameraEntity(null); - this.pendingConnection = null; - this.levelRenderer.setLevel(level); - this.particleEngine.setLevel(level); - this.gameRenderer.setLevel(level); - this.updateTitle(); - } - - private UserProperties userProperties() { - return this.userPropertiesFuture.join(); - } - - public boolean telemetryOptInExtra() { - return this.extraTelemetryAvailable() && this.options.telemetryOptInExtra().get(); - } - - public boolean extraTelemetryAvailable() { - return this.allowsTelemetry() && this.userProperties().flag(UserFlag.OPTIONAL_TELEMETRY_AVAILABLE); - } - - public boolean allowsTelemetry() { - return SharedConstants.IS_RUNNING_IN_IDE && !SharedConstants.DEBUG_FORCE_TELEMETRY ? false : this.userProperties().flag(UserFlag.TELEMETRY_ENABLED); - } - - public boolean allowsMultiplayer() { - return this.allowsMultiplayer && this.userProperties().flag(UserFlag.SERVERS_ALLOWED) && this.multiplayerBan() == null && !this.isNameBanned(); - } - - public boolean allowsRealms() { - return this.userProperties().flag(UserFlag.REALMS_ALLOWED) && this.multiplayerBan() == null; - } - - public @Nullable BanDetails multiplayerBan() { - return this.userProperties().bannedScopes().get("MULTIPLAYER"); - } - - public boolean isNameBanned() { - ProfileResult result = this.profileFuture.getNow(null); - return result != null && result.actions().contains(ProfileActionType.FORCED_NAME_CHANGE); - } - - public boolean isBlocked(UUID uuid) { - return !this.isLocalOrUnknownPlayer(uuid) && this.playerSocialManager.shouldHideMessageFrom(uuid); - } - - private boolean isLocalOrUnknownPlayer(UUID uuid) { - return uuid.equals(Util.NIL_UUID) ? true : this.player != null && uuid.equals(this.player.getUUID()); - } - - public ChatAbilities computeChatAbilities() { - ChatAbilities.Builder builder = new ChatAbilities.Builder(); - ChatVisiblity visiblityOption = this.options.chatVisibility().get(); - if (visiblityOption == ChatVisiblity.HIDDEN) { - builder.addRestriction(ChatRestriction.CHAT_AND_COMMANDS_DISABLED_BY_OPTIONS); - } else if (visiblityOption == ChatVisiblity.SYSTEM) { - builder.addRestriction(ChatRestriction.CHAT_DISABLED_BY_OPTIONS); - } - - if (this.isMultiplayerServer()) { - if (!this.allowsChat) { - builder.addRestriction(ChatRestriction.DISABLED_BY_LAUNCHER); - } - - if (SharedConstants.DEBUG_CHAT_DISABLED || !this.userProperties().flag(UserFlag.CHAT_ALLOWED)) { - builder.addRestriction(ChatRestriction.DISABLED_BY_PROFILE); - } - } - - return builder.build(); - } - - public final boolean isDemo() { - return this.demo; - } - - public final boolean canSwitchGameMode() { - return this.player != null && this.gameMode != null; - } - - public @Nullable ClientPacketListener getConnection() { - return this.player == null ? null : this.player.connection; - } - - public static boolean renderNames() { - return !instance.options.hideGui; - } - - public static boolean useShaderTransparency() { - GameRenderState gameRenderState = instance.gameRenderer.getGameRenderState(); - return !gameRenderState.levelRenderState.cameraRenderState.isPanoramicMode && gameRenderState.optionsRenderState.improvedTransparency; - } - - private void pickBlockOrEntity() { - if (this.hitResult != null && this.hitResult.getType() != HitResult.Type.MISS) { - if (net.neoforged.neoforge.client.ClientHooks.onClickInput(2, this.options.keyPickItem, InteractionHand.MAIN_HAND).isCanceled()) return; - boolean includeData = this.hasControlDown(); - switch (this.hitResult) { - case BlockHitResult blockHitResult: - this.gameMode.handlePickItemFromBlock(blockHitResult.getBlockPos(), includeData); - break; - case EntityHitResult entityHitResult: - this.gameMode.handlePickItemFromEntity(entityHitResult.getEntity(), includeData); - break; - default: - } - } - } - - public CrashReport fillReport(CrashReport report) { - SystemReport systemReport = report.getSystemReport(); - - try { - fillSystemReport(systemReport, this, this.languageManager, this.launchedVersion, this.options); - this.fillUptime(report.addCategory("Uptime")); - if (this.level != null) { - this.level.fillReportDetails(report); - } - - if (this.singleplayerServer != null) { - this.singleplayerServer.fillSystemReport(systemReport); - } - - this.reloadStateTracker.fillCrashReport(report); - } catch (Throwable var4) { - LOGGER.error("Failed to collect details", var4); - } - - return report; - } - - public static void fillReport( - @Nullable Minecraft minecraft, @Nullable LanguageManager languageManager, String launchedVersion, @Nullable Options options, CrashReport report - ) { - SystemReport system = report.getSystemReport(); - fillSystemReport(system, minecraft, languageManager, launchedVersion, options); - } - - private static String formatSeconds(double timeInSeconds) { - return String.format(Locale.ROOT, "%.3fs", timeInSeconds); - } - - private void fillUptime(CrashReportCategory category) { - category.setDetail("JVM uptime", () -> formatSeconds(ManagementFactory.getRuntimeMXBean().getUptime() / 1000.0)); - category.setDetail("Wall uptime", () -> formatSeconds((System.currentTimeMillis() - this.clientStartTimeMs) / 1000.0)); - category.setDetail("High-res time", () -> formatSeconds(Util.getMillis() / 1000.0)); - category.setDetail("Client ticks", () -> String.format(Locale.ROOT, "%d ticks / %.3fs", this.clientTickCount, this.clientTickCount / 20.0)); - } - - private static SystemReport fillSystemReport( - SystemReport systemReport, @Nullable Minecraft minecraft, @Nullable LanguageManager languageManager, String launchedVersion, @Nullable Options options - ) { - systemReport.setDetail("Launched Version", () -> launchedVersion); - String launcherBrand = getLauncherBrand(); - if (launcherBrand != null) { - systemReport.setDetail("Launcher name", launcherBrand); - } - - systemReport.setDetail("Backend library", RenderSystem::getBackendDescription); - systemReport.setDetail("Backend API", RenderSystem::getApiDescription); - systemReport.setDetail("Window size", () -> minecraft != null ? minecraft.window.getWidth() + "x" + minecraft.window.getHeight() : ""); - systemReport.setDetail("GFLW Platform", Window::getPlatform); - systemReport.setDetail("Render Extensions", () -> { - GpuDevice device = RenderSystem.tryGetDevice(); - if (device == null) { - return ""; - } else { - return String.join(", ", device.getEnabledExtensions()); - } - }); - systemReport.setDetail("GL debug messages", () -> { - GpuDevice device = RenderSystem.tryGetDevice(); - if (device == null) { - return ""; - } else { - return device.isDebuggingEnabled() ? String.join("\n", device.getLastDebugMessages()) : ""; - } - }); - systemReport.setDetail("Is Modded", () -> checkModStatus().fullDescription()); - systemReport.setDetail("Universe", () -> minecraft != null ? Long.toHexString(minecraft.canary) : "404"); - systemReport.setDetail("Type", "Client"); - if (options != null) { - if (minecraft != null) { - String gpuWarnings = minecraft.getGpuWarnlistManager().getAllWarnings(); - if (gpuWarnings != null) { - systemReport.setDetail("GPU Warnings", gpuWarnings); - } - } - - systemReport.setDetail("Transparency", options.improvedTransparency().get() ? "shader" : "regular"); - systemReport.setDetail("Render Distance", options.getEffectiveRenderDistance() + "/" + options.renderDistance().get() + " chunks"); - } - - if (minecraft != null) { - systemReport.setDetail("Resource Packs", () -> PackRepository.displayPackList(minecraft.getResourcePackRepository().getSelectedPacks())); - systemReport.setDetail("Sound Cache", () -> { - SoundBufferLibrary.DebugOutput.Counter counter = new SoundBufferLibrary.DebugOutput.Counter(); - minecraft.getSoundManager().getSoundCacheDebugStats(counter); - return String.format(Locale.ROOT, "%d bytes in %d buffers", counter.totalSize(), counter.totalCount()); - }); - } - - if (languageManager != null) { - systemReport.setDetail("Current Language", () -> languageManager.getSelected()); - } - - systemReport.setDetail("Locale", String.valueOf(Locale.getDefault())); - systemReport.setDetail("System encoding", () -> System.getProperty("sun.jnu.encoding", "")); - systemReport.setDetail("File encoding", () -> System.getProperty("file.encoding", "")); - systemReport.setDetail("CPU", GLX::_getCpuInfo); - return systemReport; - } - - public static Minecraft getInstance() { - return instance; - } - - public CompletableFuture delayTextureReload() { - return this.>submit((java.util.function.Supplier>)this::reloadResourcePacks).thenCompose(result -> (CompletionStage)result); - } - - public void updateReportEnvironment(ReportEnvironment environment) { - if (!this.reportingContext.matches(environment)) { - this.reportingContext = ReportingContext.create(environment, this.userApiService); - } - } - - public @Nullable ServerData getCurrentServer() { - return Optionull.map(this.getConnection(), ClientPacketListener::getServerData); - } - - public boolean isLocalServer() { - return this.isLocalServer; - } - - public boolean hasSingleplayerServer() { - return this.isLocalServer && this.singleplayerServer != null; - } - - public @Nullable IntegratedServer getSingleplayerServer() { - return this.singleplayerServer; - } - - public boolean isSingleplayer() { - IntegratedServer singleplayerServer = this.getSingleplayerServer(); - return singleplayerServer != null && !singleplayerServer.isPublished(); - } - - public boolean isLocalPlayer(UUID profileId) { - return profileId.equals(this.getUser().getProfileId()); - } - - public User getUser() { - return this.user; - } - - public GameProfile getGameProfile() { - ProfileResult profileResult = this.profileFuture.join(); - return profileResult != null ? profileResult.profile() : new GameProfile(this.user.getProfileId(), this.user.getName()); - } - - public Proxy getProxy() { - return this.proxy; - } - - public TextureManager getTextureManager() { - return this.textureManager; - } - - public ShaderManager getShaderManager() { - return this.shaderManager; - } - - public ResourceManager getResourceManager() { - return this.resourceManager; - } - - public PackRepository getResourcePackRepository() { - return this.resourcePackRepository; - } - - public VanillaPackResources getVanillaPackResources() { - return this.vanillaPackResources; - } - - public DownloadedPackSource getDownloadedPackSource() { - return this.downloadedPackSource; - } - - public Path getResourcePackDirectory() { - return this.resourcePackDirectory; - } - - public LanguageManager getLanguageManager() { - return this.languageManager; - } - - public boolean isPaused() { - return this.pause; - } - - public GpuWarnlistManager getGpuWarnlistManager() { - return this.gpuWarnlistManager; - } - - public SoundManager getSoundManager() { - return this.soundManager; - } - - public @Nullable Music getSituationalMusic() { - Music screenMusic = Optionull.map(this.screen, Screen::getBackgroundMusic); - if (screenMusic != null) { - return screenMusic; - } else { - Camera camera = this.gameRenderer.getMainCamera(); - if (this.player != null && camera != null) { - Level playerLevel = this.player.level(); - if (playerLevel.dimension() == Level.END && this.gui.getBossOverlay().shouldPlayMusic()) { - return Musics.END_BOSS; - } else { - BackgroundMusic backgroundMusic = camera.attributeProbe().getValue(EnvironmentAttributes.BACKGROUND_MUSIC, 1.0F); - boolean isCreative = this.player.getAbilities().instabuild && this.player.getAbilities().mayfly; - boolean isUnderwater = this.player.isUnderWater(); - return backgroundMusic.select(isCreative, isUnderwater).orElse(null); - } - } else { - return Musics.MENU; - } - } - } - - public float getMusicVolume() { - if (this.screen != null && this.screen.getBackgroundMusic() != null) { - return 1.0F; - } else { - Camera camera = this.gameRenderer.getMainCamera(); - return camera != null ? camera.attributeProbe().getValue(EnvironmentAttributes.MUSIC_VOLUME, 1.0F) : 1.0F; - } - } - - public Services services() { - return this.services; - } - - public SkinManager getSkinManager() { - return this.skinManager; - } - - public @Nullable Entity getCameraEntity() { - return this.gameRenderer.getMainCamera().entity(); - } - - public void setCameraEntity(@Nullable Entity cameraEntity) { - this.gameRenderer.getMainCamera().setEntity(cameraEntity); - this.gameRenderer.checkEntityPostEffect(cameraEntity); - } - - public boolean shouldEntityAppearGlowing(Entity entity) { - return entity.isCurrentlyGlowing() - || this.player != null && this.player.isSpectator() && this.options.keySpectatorOutlines.isDown() && entity.is(EntityType.PLAYER); - } - - @Override - protected Thread getRunningThread() { - return this.gameThread; - } - - @Override - public Runnable wrapRunnable(Runnable runnable) { - return runnable; - } - - @Override - protected boolean shouldRun(Runnable task) { - return true; - } - - public EntityRenderDispatcher getEntityRenderDispatcher() { - return this.entityRenderDispatcher; - } - - public BlockEntityRenderDispatcher getBlockEntityRenderDispatcher() { - return this.blockEntityRenderDispatcher; - } - - public MapRenderer getMapRenderer() { - return this.mapRenderer; - } - - public DataFixer getFixerUpper() { - return this.fixerUpper; - } - - public DeltaTracker getDeltaTracker() { - return this.deltaTracker; - } - - public BlockColors getBlockColors() { - return this.blockColors; - } - - public boolean showOnlyReducedInfo() { - return this.player != null && this.player.isReducedDebugInfo() || this.options.reducedDebugInfo().get(); - } - - public ToastManager getToastManager() { - return this.toastManager; - } - - public Tutorial getTutorial() { - return this.tutorial; - } - - public boolean isWindowActive() { - return this.window.isFocused(); - } - - public HotbarManager getHotbarManager() { - return this.hotbarManager; - } - - public ModelManager getModelManager() { - return this.modelManager; - } - - public AtlasManager getAtlasManager() { - return this.atlasManager; - } - - public MapTextureManager getMapTextureManager() { - return this.mapTextureManager; - } - - public WaypointStyleManager getWaypointStyles() { - return this.waypointStyles; - } - - public Component grabPanoramixScreenshot(File folder) { - int downscaleFactor = 4; - int width = 4096; - int height = 4096; - int ow = this.window.getWidth(); - int oh = this.window.getHeight(); - RenderTarget target = this.getMainRenderTarget(); - float xRot = this.player.getXRot(); - float yRot = this.player.getYRot(); - float xRotO = this.player.xRotO; - float yRotO = this.player.yRotO; - this.gameRenderer.setRenderBlockOutline(false); - Camera camera = this.gameRenderer.getMainCamera(); - - MutableComponent var14; - try { - camera.enablePanoramicMode(); - this.window.setWidth(4096); - this.window.setHeight(4096); - target.resize(4096, 4096); - - for (int i = 0; i < 6; i++) { - switch (i) { - case 0: - this.player.setYRot(yRot); - this.player.setXRot(0.0F); - break; - case 1: - this.player.setYRot((yRot + 90.0F) % 360.0F); - this.player.setXRot(0.0F); - break; - case 2: - this.player.setYRot((yRot + 180.0F) % 360.0F); - this.player.setXRot(0.0F); - break; - case 3: - this.player.setYRot((yRot - 90.0F) % 360.0F); - this.player.setXRot(0.0F); - break; - case 4: - this.player.setYRot(yRot); - this.player.setXRot(-90.0F); - break; - case 5: - default: - this.player.setYRot(yRot); - this.player.setXRot(90.0F); - } - - this.player.yRotO = this.player.getYRot(); - this.player.xRotO = this.player.getXRot(); - this.gameRenderer.update(DeltaTracker.ONE, true); - this.gameRenderer.extract(DeltaTracker.ONE, true); - this.gameRenderer.renderLevel(DeltaTracker.ONE); - - try { - Thread.sleep(10L); - } catch (InterruptedException var19) { - } - - Screenshot.grab(folder, "panorama_" + i + ".png", target, 4, result -> {}); - } - - Component name = Component.literal(folder.getName()) - .withStyle(ChatFormatting.UNDERLINE) - .withStyle(s -> s.withClickEvent(new ClickEvent.OpenFile(folder.getAbsoluteFile()))); - return Component.translatable("screenshot.success", name); - } catch (Exception var20) { - LOGGER.error("Couldn't save image", (Throwable)var20); - var14 = Component.translatable("screenshot.failure", var20.getMessage()); - } finally { - this.player.setXRot(xRot); - this.player.setYRot(yRot); - this.player.xRotO = xRotO; - this.player.yRotO = yRotO; - this.gameRenderer.setRenderBlockOutline(true); - this.window.setWidth(ow); - this.window.setHeight(oh); - target.resize(ow, oh); - camera.disablePanoramicMode(); - } - - return var14; - } - - public SplashManager getSplashManager() { - return this.splashManager; - } - - public @Nullable Overlay getOverlay() { - return this.overlay; - } - - public PlayerSocialManager getPlayerSocialManager() { - return this.playerSocialManager; - } - - public Window getWindow() { - return this.window; - } - - public TextInputManager textInputManager() { - return this.textInputManager; - } - - public void onTextInputFocusChange(GuiEventListener element, boolean isFocused) { - this.textInputManager.onTextInputFocusChange(isFocused); - if (this.screen != null) { - if (isFocused) { - this.keyboardHandler.resubmitLastPreeditEvent(element); - } else { - KeyboardHandler.submitPreeditEvent(element, null); - } - } - } - - public FramerateLimitTracker getFramerateLimitTracker() { - return this.framerateLimitTracker; - } - - public DebugScreenOverlay getDebugOverlay() { - return this.gui.getDebugOverlay(); - } - - public RenderBuffers renderBuffers() { - return this.renderBuffers; - } - - public void updateMaxMipLevel(int mipmapLevels) { - this.atlasManager.updateMaxMipLevel(mipmapLevels); - } - - public EntityModelSet getEntityModels() { - return this.modelManager.entityModels().get(); - } - - public boolean isTextFilteringEnabled() { - return this.userProperties().flag(UserFlag.PROFANITY_FILTER_ENABLED); - } - - public void prepareForMultiplayer() { - this.playerSocialManager.startOnlineMode(); - this.getProfileKeyPairManager().prepareKeyPair(); - } - - public InputType getLastInputType() { - return this.lastInputType; - } - - public void setLastInputType(InputType lastInputType) { - this.lastInputType = lastInputType; - } - - public GameNarrator getNarrator() { - return this.narrator; - } - - public ChatListener getChatListener() { - return this.chatListener; - } - - public ReportingContext getReportingContext() { - return this.reportingContext; - } - - public RealmsDataFetcher realmsDataFetcher() { - return this.realmsDataFetcher; - } - - public QuickPlayLog quickPlayLog() { - return this.quickPlayLog; - } - - public CommandHistory commandHistory() { - return this.commandHistory; - } - - public DirectoryValidator directoryValidator() { - return this.directoryValidator; - } - - public PlayerSkinRenderCache playerSkinRenderCache() { - return this.playerSkinRenderCache; - } - - private float getTickTargetMillis(float defaultTickTargetMillis) { - if (this.level != null) { - TickRateManager manager = this.level.tickRateManager(); - if (manager.runsNormally()) { - return Math.max(defaultTickTargetMillis, manager.millisecondsPerTick()); - } - } - - return defaultTickTargetMillis; - } - - public BlockModelResolver getBlockModelResolver() { - return this.blockModelResolver; - } - - public ItemModelResolver getItemModelResolver() { - return this.itemModelResolver; - } - - public boolean canInterruptScreen() { - return (this.screen == null || this.screen.canInterruptWithAnotherScreen()) && !this.clientLevelTeardownInProgress; - } - - public static @Nullable String getLauncherBrand() { - return System.getProperty("minecraft.launcher.brand"); - } - - public PacketProcessor packetProcessor() { - return this.packetProcessor; - } - - public Gizmos.TemporaryCollection collectPerTickGizmos() { - return Gizmos.withCollector(this.perTickGizmos); - } - - public Collection getPerTickGizmos() { - return this.drainedLatestTickGizmos; - } - - private void pick(float partialTicks) { - Entity cameraEntity = this.getCameraEntity(); - if (cameraEntity != null) { - if (this.level != null && this.player != null) { - Profiler.get().push("pick"); - this.hitResult = this.player.raycastHitResult(partialTicks, cameraEntity); - this.crosshairPickEntity = this.hitResult instanceof EntityHitResult entityHitResult ? entityHitResult.getEntity() : null; - Profiler.get().pop(); - } - } - } - - @OnlyIn(Dist.CLIENT) - private record GameLoadCookie(RealmsClient realmsClient, GameConfig.QuickPlayData quickPlayData) { - } -} diff --git a/net/minecraft/client/multiplayer/ClientLevel.java b/net/minecraft/client/multiplayer/ClientLevel.java deleted file mode 100644 index 2cd74615..00000000 --- a/net/minecraft/client/multiplayer/ClientLevel.java +++ /dev/null @@ -1,1188 +0,0 @@ -package net.minecraft.client.multiplayer; - -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.collect.Queues; -import com.mojang.logging.LogUtils; -import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap; -import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet; -import java.util.Arrays; -import java.util.Deque; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Objects; -import java.util.Set; -import java.util.function.BooleanSupplier; -import net.minecraft.CrashReport; -import net.minecraft.CrashReportCategory; -import net.minecraft.ReportedException; -import net.minecraft.SharedConstants; -import net.minecraft.client.Camera; -import net.minecraft.client.ClientClockManager; -import net.minecraft.client.Minecraft; -import net.minecraft.client.color.block.BlockTintCache; -import net.minecraft.client.color.block.BlockTintSource; -import net.minecraft.client.gui.screens.WinScreen; -import net.minecraft.client.multiplayer.prediction.BlockStatePredictionHandler; -import net.minecraft.client.particle.FireworkParticles; -import net.minecraft.client.particle.TerrainParticle; -import net.minecraft.client.player.AbstractClientPlayer; -import net.minecraft.client.player.LocalPlayer; -import net.minecraft.client.renderer.BiomeColors; -import net.minecraft.client.renderer.EndFlashState; -import net.minecraft.client.renderer.LevelEventHandler; -import net.minecraft.client.renderer.LevelRenderer; -import net.minecraft.client.renderer.block.BlockAndTintGetter; -import net.minecraft.client.renderer.blockentity.BlockEntityRenderer; -import net.minecraft.client.resources.sounds.DirectionalSoundInstance; -import net.minecraft.client.resources.sounds.EntityBoundSoundInstance; -import net.minecraft.client.resources.sounds.SimpleSoundInstance; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Cursor3D; -import net.minecraft.core.Direction; -import net.minecraft.core.Holder; -import net.minecraft.core.particles.BlockParticleOption; -import net.minecraft.core.particles.ExplosionParticleInfo; -import net.minecraft.core.particles.ParticleOptions; -import net.minecraft.core.particles.ParticleTypes; -import net.minecraft.core.registries.BuiltInRegistries; -import net.minecraft.core.registries.Registries; -import net.minecraft.nbt.NbtOps; -import net.minecraft.network.chat.Component; -import net.minecraft.network.protocol.Packet; -import net.minecraft.resources.ResourceKey; -import net.minecraft.server.level.ParticleStatus; -import net.minecraft.sounds.SoundEvent; -import net.minecraft.sounds.SoundEvents; -import net.minecraft.sounds.SoundSource; -import net.minecraft.tags.BlockTags; -import net.minecraft.util.ARGB; -import net.minecraft.util.Mth; -import net.minecraft.util.RandomSource; -import net.minecraft.util.Util; -import net.minecraft.util.profiling.Profiler; -import net.minecraft.util.profiling.ProfilerFiller; -import net.minecraft.util.profiling.Zone; -import net.minecraft.util.profiling.jfr.JvmProfiler; -import net.minecraft.util.random.WeightedList; -import net.minecraft.world.Difficulty; -import net.minecraft.world.TickRateManager; -import net.minecraft.world.attribute.AmbientParticle; -import net.minecraft.world.attribute.EnvironmentAttributeSystem; -import net.minecraft.world.attribute.EnvironmentAttributes; -import net.minecraft.world.damagesource.DamageSource; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.EntitySelector; -import net.minecraft.world.entity.boss.enderdragon.EnderDragon; -import net.minecraft.world.entity.boss.enderdragon.EnderDragonPart; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.flag.FeatureFlagSet; -import net.minecraft.world.item.BlockItem; -import net.minecraft.world.item.Item; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.Items; -import net.minecraft.world.item.alchemy.PotionBrewing; -import net.minecraft.world.item.component.FireworkExplosion; -import net.minecraft.world.item.crafting.RecipeAccess; -import net.minecraft.world.level.CardinalLighting; -import net.minecraft.world.level.ChunkPos; -import net.minecraft.world.level.ColorResolver; -import net.minecraft.world.level.ExplosionDamageCalculator; -import net.minecraft.world.level.GameType; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.LevelHeightAccessor; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.biome.Biomes; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.RenderShape; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.entity.FuelValues; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.border.WorldBorder; -import net.minecraft.world.level.chunk.LevelChunk; -import net.minecraft.world.level.dimension.DimensionType; -import net.minecraft.world.level.entity.EntityTickList; -import net.minecraft.world.level.entity.LevelCallback; -import net.minecraft.world.level.entity.LevelEntityGetter; -import net.minecraft.world.level.entity.TransientEntitySectionManager; -import net.minecraft.world.level.gameevent.GameEvent; -import net.minecraft.world.level.material.Fluid; -import net.minecraft.world.level.material.FluidState; -import net.minecraft.world.level.saveddata.maps.MapId; -import net.minecraft.world.level.saveddata.maps.MapItemSavedData; -import net.minecraft.world.level.storage.LevelData; -import net.minecraft.world.level.storage.WritableLevelData; -import net.minecraft.world.phys.AABB; -import net.minecraft.world.phys.Vec3; -import net.minecraft.world.phys.shapes.VoxelShape; -import net.minecraft.world.scores.Scoreboard; -import net.minecraft.world.ticks.BlackholeTickAccess; -import net.minecraft.world.ticks.LevelTickAccess; -import net.neoforged.api.distmarker.Dist; -import net.neoforged.api.distmarker.OnlyIn; -import org.jspecify.annotations.Nullable; -import org.slf4j.Logger; - -@OnlyIn(Dist.CLIENT) -public class ClientLevel extends Level implements BlockAndTintGetter, CacheSlot.Cleaner { - private static final Logger LOGGER = LogUtils.getLogger(); - public static final Component DEFAULT_QUIT_MESSAGE = Component.translatable("multiplayer.status.quitting"); - private static final double FLUID_PARTICLE_SPAWN_OFFSET = 0.05; - private static final int NORMAL_LIGHT_UPDATES_PER_FRAME = 10; - private static final int LIGHT_UPDATE_QUEUE_SIZE_THRESHOLD = 1000; - private final EntityTickList tickingEntities = new EntityTickList(); - private final TransientEntitySectionManager entityStorage = new TransientEntitySectionManager<>(Entity.class, new ClientLevel.EntityCallbacks()); - private final ClientPacketListener connection; - private final LevelRenderer levelRenderer; - private final LevelEventHandler levelEventHandler; - private final ClientLevel.ClientLevelData clientLevelData; - private final TickRateManager tickRateManager; - private final @Nullable EndFlashState endFlashState; - private final Minecraft minecraft = Minecraft.getInstance(); - private final List players = Lists.newArrayList(); - private final List> dragonParts = Lists.newArrayList(); - private final Map mapData = Maps.newHashMap(); - private int skyFlashTime; - private final Object2ObjectArrayMap tintCaches = Util.make(new Object2ObjectArrayMap<>(3), cache -> { - cache.put(BiomeColors.GRASS_COLOR_RESOLVER, new BlockTintCache(pos -> this.calculateBlockTint(pos, BiomeColors.GRASS_COLOR_RESOLVER))); - cache.put(BiomeColors.FOLIAGE_COLOR_RESOLVER, new BlockTintCache(pos -> this.calculateBlockTint(pos, BiomeColors.FOLIAGE_COLOR_RESOLVER))); - cache.put(BiomeColors.DRY_FOLIAGE_COLOR_RESOLVER, new BlockTintCache(pos -> this.calculateBlockTint(pos, BiomeColors.DRY_FOLIAGE_COLOR_RESOLVER))); - cache.put(BiomeColors.WATER_COLOR_RESOLVER, new BlockTintCache(pos -> this.calculateBlockTint(pos, BiomeColors.WATER_COLOR_RESOLVER))); - net.neoforged.neoforge.client.ColorResolverManager.registerBlockTintCaches(ClientLevel.this, cache); - }); - private final ClientChunkCache chunkSource; - private final Deque lightUpdateQueue = Queues.newArrayDeque(); - private int serverSimulationDistance; - private final BlockStatePredictionHandler blockStatePredictionHandler = new BlockStatePredictionHandler(); - private final Set globallyRenderedBlockEntities = new ReferenceOpenHashSet<>(); - private final ClientExplosionTracker explosionTracker = new ClientExplosionTracker(); - private final WorldBorder worldBorder = new WorldBorder(); - private final EnvironmentAttributeSystem environmentAttributes; - private final int seaLevel; - private static final Set MARKER_PARTICLE_ITEMS = Set.of(Items.BARRIER, Items.LIGHT); - private final net.neoforged.neoforge.model.data.ModelDataManager modelDataManager = new net.neoforged.neoforge.model.data.ModelDataManager(this); - - public void handleBlockChangedAck(int sequence) { - if (SharedConstants.DEBUG_BLOCK_BREAK) { - LOGGER.debug("ACK {}", sequence); - } - - this.blockStatePredictionHandler.endPredictionsUpTo(sequence, this); - } - - @Override - public void onBlockEntityAdded(BlockEntity blockEntity) { - BlockEntityRenderer renderer = this.minecraft.getBlockEntityRenderDispatcher().getRenderer(blockEntity); - if (renderer != null && renderer.shouldRenderOffScreen()) { - this.globallyRenderedBlockEntities.add(blockEntity); - } - } - - public Set getGloballyRenderedBlockEntities() { - return this.globallyRenderedBlockEntities; - } - - public void setServerVerifiedBlockState(BlockPos pos, BlockState blockState, @Block.UpdateFlags int updateFlag) { - if (!this.blockStatePredictionHandler.updateKnownServerState(pos, blockState)) { - super.setBlock(pos, blockState, updateFlag, 512); - } - } - - public void syncBlockState(BlockPos pos, BlockState state, @Nullable Vec3 playerPos) { - BlockState oldState = this.getBlockState(pos); - if (oldState != state) { - this.setBlock(pos, state, 19); - Player player = this.minecraft.player; - if (playerPos != null && this == player.level() && player.isColliding(pos, state)) { - player.absSnapTo(playerPos.x, playerPos.y, playerPos.z); - } - } - } - - BlockStatePredictionHandler getBlockStatePredictionHandler() { - return this.blockStatePredictionHandler; - } - - @Override - public boolean setBlock(BlockPos pos, BlockState blockState, @Block.UpdateFlags int updateFlags, int updateLimit) { - if (this.blockStatePredictionHandler.isPredicting()) { - // Neo: Record and store a snapshot in the prediction so that BE data can be restored if the break is denied. - // Fixes MC-36093 and permits correct server-side only cancellation of block changes. - var snapshot = net.neoforged.neoforge.common.util.BlockSnapshot.create(this.dimension(), this, pos, updateFlags); - - BlockState oldState = this.getBlockState(pos); - boolean success = super.setBlock(pos, blockState, updateFlags, updateLimit); - if (success) { - this.blockStatePredictionHandler.retainKnownServerState(pos, oldState, this.minecraft.player); - this.blockStatePredictionHandler.retainSnapshot(pos, snapshot); - } - - return success; - } else { - return super.setBlock(pos, blockState, updateFlags, updateLimit); - } - } - - public ClientLevel( - ClientPacketListener connection, - ClientLevel.ClientLevelData levelData, - ResourceKey dimension, - Holder dimensionType, - int serverChunkRadius, - int serverSimulationDistance, - LevelRenderer levelRenderer, - boolean isDebug, - long biomeZoomSeed, - int seaLevel - ) { - super(levelData, dimension, connection.registryAccess(), dimensionType, true, isDebug, biomeZoomSeed, 1000000); - this.connection = connection; - this.chunkSource = new ClientChunkCache(this, serverChunkRadius); - this.tickRateManager = new TickRateManager(); - this.clientLevelData = levelData; - this.levelRenderer = levelRenderer; - this.seaLevel = seaLevel; - this.levelEventHandler = new LevelEventHandler(this.minecraft, this); - this.endFlashState = dimensionType.value().hasEndFlashes() ? new EndFlashState() : null; - this.setRespawnData(LevelData.RespawnData.of(dimension, new BlockPos(8, 64, 8), 0.0F, 0.0F)); - this.serverSimulationDistance = serverSimulationDistance; - this.environmentAttributes = this.addEnvironmentAttributeLayers(EnvironmentAttributeSystem.builder()).build(); - this.updateSkyBrightness(); - net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.event.level.LevelEvent.Load(this)); - } - - private EnvironmentAttributeSystem.Builder addEnvironmentAttributeLayers(EnvironmentAttributeSystem.Builder environmentAttributes) { - environmentAttributes.addDefaultLayers(this); - int flashColor = ARGB.color(204, 204, 255); - environmentAttributes.addTimeBasedLayer( - EnvironmentAttributes.SKY_COLOR, (skyColor, cacheTickId) -> this.getSkyFlashTime() > 0 ? ARGB.srgbLerp(0.22F, skyColor, flashColor) : skyColor - ); - environmentAttributes.addTimeBasedLayer( - EnvironmentAttributes.SKY_LIGHT_FACTOR, (skyFactor, cacheTickId) -> this.getSkyFlashTime() > 0 ? 1.0F : skyFactor - ); - return environmentAttributes; - } - - public void queueLightUpdate(Runnable update) { - this.lightUpdateQueue.add(update); - } - - public void pollLightUpdates() { - int size = this.lightUpdateQueue.size(); - int lightUpdatesPerFrame = size < 1000 ? Math.max(10, size / 10) : size; - - for (int i = 0; i < lightUpdatesPerFrame; i++) { - Runnable update = this.lightUpdateQueue.poll(); - if (update == null) { - break; - } - - update.run(); - } - } - - public @Nullable EndFlashState endFlashState() { - return this.endFlashState; - } - - public void tick(BooleanSupplier haveTime) { - this.updateSkyBrightness(); - if (this.tickRateManager().runsNormally()) { - this.getWorldBorder().tick(); - this.tickTime(); - } - - if (this.skyFlashTime > 0) { - this.setSkyFlashTime(this.skyFlashTime - 1); - } - - if (this.endFlashState != null) { - this.endFlashState.tick(this.getDefaultClockTime()); - if (this.endFlashState.flashStartedThisTick() && !(this.minecraft.screen instanceof WinScreen)) { - this.minecraft - .getSoundManager() - .playDelayed( - new DirectionalSoundInstance( - SoundEvents.WEATHER_END_FLASH, - SoundSource.WEATHER, - this.random, - this.minecraft.gameRenderer.getMainCamera(), - this.endFlashState.getXAngle(), - this.endFlashState.getYAngle() - ), - 30 - ); - } - } - - this.explosionTracker.tick(this); - - try (Zone ignored = Profiler.get().zone("blocks")) { - this.chunkSource.tick(haveTime, true); - } - - JvmProfiler.INSTANCE.onClientTick(this.minecraft.getFps()); - this.environmentAttributes().invalidateTickCache(); - } - - private void tickTime() { - this.clientLevelData.setGameTime(this.clientLevelData.getGameTime() + 1L); - } - - public void setTimeFromServer(long gameTime) { - this.clientLevelData.setGameTime(gameTime); - } - - public Iterable entitiesForRendering() { - return this.getEntities().getAll(); - } - - public void tickEntities() { - this.tickingEntities.forEach(entity -> { - if (!entity.isRemoved() && !entity.isPassenger() && !this.tickRateManager.isEntityFrozen(entity)) { - this.guardEntityTick(this::tickNonPassenger, entity); - } - }); - } - - public boolean isTickingEntity(Entity entity) { - return this.tickingEntities.contains(entity); - } - - @Override - public boolean shouldTickDeath(Entity entity) { - return entity.chunkPosition().getChessboardDistance(this.minecraft.player.chunkPosition()) <= this.serverSimulationDistance; - } - - public void tickNonPassenger(Entity entity) { - entity.setOldPosAndRot(); - entity.tickCount++; - Profiler.get().push(entity.typeHolder()::getRegisteredName); - // Neo: Permit cancellation of Entity#tick via EntityTickEvent.Pre - if (!net.neoforged.neoforge.event.EventHooks.fireEntityTickPre(entity).isCanceled()) { - entity.tick(); - net.neoforged.neoforge.event.EventHooks.fireEntityTickPost(entity); - } - Profiler.get().pop(); - - for (Entity passenger : entity.getPassengers()) { - this.tickPassenger(entity, passenger); - } - } - - private void tickPassenger(Entity vehicle, Entity entity) { - if (entity.isRemoved() || entity.getVehicle() != vehicle) { - entity.stopRiding(); - } else if (entity instanceof Player || this.tickingEntities.contains(entity)) { - entity.setOldPosAndRot(); - entity.tickCount++; - entity.rideTick(); - - for (Entity passenger : entity.getPassengers()) { - this.tickPassenger(entity, passenger); - } - } - } - - public void update() { - ProfilerFiller profiler = Profiler.get(); - profiler.push("populateLightUpdates"); - this.pollLightUpdates(); - profiler.popPush("runLightUpdates"); - this.getChunkSource().getLightEngine().runLightUpdates(); - profiler.pop(); - } - - public void unload(LevelChunk levelChunk) { - levelChunk.clearAllBlockEntities(); - this.chunkSource.getLightEngine().setLightEnabled(levelChunk.getPos(), false); - this.entityStorage.stopTicking(levelChunk.getPos()); - } - - public void onChunkLoaded(ChunkPos pos) { - this.tintCaches.forEach((resolver, cache) -> cache.invalidateForChunk(pos.x(), pos.z())); - this.entityStorage.startTicking(pos); - } - - public void onSectionBecomingNonEmpty(long sectionNode) { - this.levelRenderer.onSectionBecomingNonEmpty(sectionNode); - } - - public void clearTintCaches() { - this.tintCaches.forEach((resolver, cache) -> cache.invalidateAll()); - } - - @Override - public boolean hasChunk(int chunkX, int chunkZ) { - return true; - } - - public int getEntityCount() { - return this.entityStorage.count(); - } - - public void addEntity(Entity entity) { - if (net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.event.entity.EntityJoinLevelEvent(entity, this)).isCanceled()) return; - this.removeEntity(entity.getId(), Entity.RemovalReason.DISCARDED); - this.entityStorage.addEntity(entity); - entity.onAddedToLevel(); - } - - public void removeEntity(int id, Entity.RemovalReason reason) { - Entity entity = this.getEntities().get(id); - if (entity != null) { - entity.setRemoved(reason); - entity.onClientRemoval(); - } - } - - @Override - public List getPushableEntities(Entity pusher, AABB boundingBox) { - LocalPlayer player = this.minecraft.player; - return player != null && player != pusher && player.getBoundingBox().intersects(boundingBox) && EntitySelector.pushableBy(pusher).test(player) - ? List.of(player) - : List.of(); - } - - @Override - public @Nullable Entity getEntity(int id) { - return this.getEntities().get(id); - } - - public void disconnect(Component message) { - this.connection.getConnection().disconnect(message); - } - - public void animateTick(int xt, int yt, int zt) { - int r = 32; - RandomSource animateRandom = RandomSource.createThreadLocalInstance(); - Block markerParticleTarget = this.getMarkerParticleTarget(); - BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos(); - - for (int i = 0; i < 667; i++) { - this.doAnimateTick(xt, yt, zt, 16, animateRandom, markerParticleTarget, pos); - this.doAnimateTick(xt, yt, zt, 32, animateRandom, markerParticleTarget, pos); - } - } - - private @Nullable Block getMarkerParticleTarget() { - if (this.minecraft.gameMode.getPlayerMode() == GameType.CREATIVE) { - ItemStack carriedItemStack = this.minecraft.player.getMainHandItem(); - Item carriedItem = carriedItemStack.getItem(); - if (MARKER_PARTICLE_ITEMS.contains(carriedItem) && carriedItem instanceof BlockItem blockItem) { - return blockItem.getBlock(); - } - } - - return null; - } - - public void doAnimateTick(int xt, int yt, int zt, int r, RandomSource animateRandom, @Nullable Block markerParticleTarget, BlockPos.MutableBlockPos pos) { - int x = xt + this.random.nextInt(r) - this.random.nextInt(r); - int y = yt + this.random.nextInt(r) - this.random.nextInt(r); - int z = zt + this.random.nextInt(r) - this.random.nextInt(r); - pos.set(x, y, z); - BlockState state = this.getBlockState(pos); - state.getBlock().animateTick(state, this, pos, animateRandom); - FluidState fluidState = this.getFluidState(pos); - if (!fluidState.isEmpty()) { - fluidState.animateTick(this, pos, animateRandom); - ParticleOptions dripParticle = fluidState.getDripParticle(); - if (dripParticle != null && this.random.nextInt(10) == 0) { - boolean hasWatertightBottom = state.isFaceSturdy(this, pos, Direction.DOWN); - BlockPos below = pos.below(); - this.trySpawnDripParticles(below, this.getBlockState(below), dripParticle, hasWatertightBottom); - } - } - - if (markerParticleTarget == state.getBlock()) { - this.addParticle(new BlockParticleOption(ParticleTypes.BLOCK_MARKER, state), x + 0.5, y + 0.5, z + 0.5, 0.0, 0.0, 0.0); - } - - if (!state.isCollisionShapeFullBlock(this, pos)) { - for (AmbientParticle particle : this.environmentAttributes().getValue(EnvironmentAttributes.AMBIENT_PARTICLES, pos)) { - if (particle.canSpawn(this.random)) { - this.addParticle( - particle.particle(), - pos.getX() + this.random.nextDouble(), - pos.getY() + this.random.nextDouble(), - pos.getZ() + this.random.nextDouble(), - 0.0, - 0.0, - 0.0 - ); - } - } - } - } - - private void trySpawnDripParticles(BlockPos pos, BlockState state, ParticleOptions dripParticle, boolean isTopSolid) { - if (state.getFluidState().isEmpty()) { - VoxelShape collisionShape = state.getCollisionShape(this, pos); - double topSideHeight = collisionShape.max(Direction.Axis.Y); - if (topSideHeight < 1.0) { - if (isTopSolid) { - this.spawnFluidParticle(pos.getX(), pos.getX() + 1, pos.getZ(), pos.getZ() + 1, pos.getY() + 1 - 0.05, dripParticle); - } - } else if (!state.is(BlockTags.IMPERMEABLE)) { - double bottomSideHeight = collisionShape.min(Direction.Axis.Y); - if (bottomSideHeight > 0.0) { - this.spawnParticle(pos, dripParticle, collisionShape, pos.getY() + bottomSideHeight - 0.05); - } else { - BlockPos below = pos.below(); - BlockState belowState = this.getBlockState(below); - VoxelShape belowShape = belowState.getCollisionShape(this, below); - double belowTopSideHeight = belowShape.max(Direction.Axis.Y); - if (belowTopSideHeight < 1.0 && belowState.getFluidState().isEmpty()) { - this.spawnParticle(pos, dripParticle, collisionShape, pos.getY() - 0.05); - } - } - } - } - } - - private void spawnParticle(BlockPos pos, ParticleOptions dripParticle, VoxelShape dripShape, double height) { - this.spawnFluidParticle( - pos.getX() + dripShape.min(Direction.Axis.X), - pos.getX() + dripShape.max(Direction.Axis.X), - pos.getZ() + dripShape.min(Direction.Axis.Z), - pos.getZ() + dripShape.max(Direction.Axis.Z), - height, - dripParticle - ); - } - - private void spawnFluidParticle(double x1, double x2, double z1, double z2, double y, ParticleOptions dripParticle) { - this.addParticle(dripParticle, Mth.lerp(this.random.nextDouble(), x1, x2), y, Mth.lerp(this.random.nextDouble(), z1, z2), 0.0, 0.0, 0.0); - } - - @Override - public CrashReportCategory fillReportDetails(CrashReport report) { - CrashReportCategory category = super.fillReportDetails(report); - category.setDetail("Server brand", () -> this.minecraft.player.connection.serverBrand()); - category.setDetail( - "Server type", () -> this.minecraft.getSingleplayerServer() == null ? "Non-integrated multiplayer server" : "Integrated singleplayer server" - ); - category.setDetail("Tracked entity count", () -> String.valueOf(this.getEntityCount())); - category.setDetail("Client weather", () -> String.format(Locale.ROOT, "Raining: %b, thundering: %b", this.isRaining(), this.isThundering())); - return category; - } - - @Override - public void playSeededSound( - @Nullable Entity except, double x, double y, double z, Holder sound, SoundSource source, float volume, float pitch, long seed - ) { - net.neoforged.neoforge.event.PlayLevelSoundEvent.AtPosition event = net.neoforged.neoforge.event.EventHooks.onPlaySoundAtPosition(this, x, y, z, sound, source, volume, pitch); - if (event.isCanceled() || event.getSound() == null) return; - sound = event.getSound(); - source = event.getSource(); - volume = event.getNewVolume(); - pitch = event.getNewPitch(); - - if (except == this.minecraft.player) { - this.playSound(x, y, z, sound.value(), source, volume, pitch, false, seed); - } - } - - @Override - public void playSeededSound( - @Nullable Entity except, Entity sourceEntity, Holder sound, SoundSource source, float volume, float pitch, long seed - ) { - net.neoforged.neoforge.event.PlayLevelSoundEvent.AtEntity event = net.neoforged.neoforge.event.EventHooks.onPlaySoundAtEntity(sourceEntity, sound, source, volume, pitch); - if (event.isCanceled() || event.getSound() == null) return; - sound = event.getSound(); - source = event.getSource(); - volume = event.getNewVolume(); - pitch = event.getNewPitch(); - if (except == this.minecraft.player) { - this.minecraft.getSoundManager().play(new EntityBoundSoundInstance(sound.value(), source, volume, pitch, sourceEntity, seed)); - } - } - - @Override - public void playLocalSound(Entity sourceEntity, SoundEvent sound, SoundSource source, float volume, float pitch) { - this.minecraft.getSoundManager().play(new EntityBoundSoundInstance(sound, source, volume, pitch, sourceEntity, this.random.nextLong())); - } - - @Override - public void playPlayerSound(SoundEvent sound, SoundSource source, float volume, float pitch) { - if (this.minecraft.player != null) { - this.minecraft.getSoundManager().play(new EntityBoundSoundInstance(sound, source, volume, pitch, this.minecraft.player, this.random.nextLong())); - } - } - - @Override - public void playLocalSound(double x, double y, double z, SoundEvent sound, SoundSource source, float volume, float pitch, boolean distanceDelay) { - this.playSound(x, y, z, sound, source, volume, pitch, distanceDelay, this.random.nextLong()); - } - - private void playSound(double x, double y, double z, SoundEvent sound, SoundSource source, float volume, float pitch, boolean distanceDelay, long seed) { - double distanceToSqr = this.minecraft.gameRenderer.getMainCamera().position().distanceToSqr(x, y, z); - SimpleSoundInstance instance = new SimpleSoundInstance(sound, source, volume, pitch, RandomSource.create(seed), x, y, z); - if (distanceDelay && distanceToSqr > 100.0) { - double delayInSeconds = Math.sqrt(distanceToSqr) / 40.0; - this.minecraft.getSoundManager().playDelayed(instance, (int)(delayInSeconds * 20.0)); - } else { - this.minecraft.getSoundManager().play(instance); - } - } - - @Override - public void createFireworks(double x, double y, double z, double xd, double yd, double zd, List explosions) { - if (explosions.isEmpty()) { - for (int i = 0; i < this.random.nextInt(3) + 2; i++) { - this.addParticle(ParticleTypes.POOF, x, y, z, this.random.nextGaussian() * 0.05, 0.005, this.random.nextGaussian() * 0.05); - } - } else { - this.minecraft.particleEngine.add(new FireworkParticles.Starter(this, x, y, z, xd, yd, zd, this.minecraft.particleEngine, explosions)); - } - } - - @Override - public void sendPacketToServer(Packet packet) { - this.connection.send(packet); - } - - @Override - public WorldBorder getWorldBorder() { - return this.worldBorder; - } - - @Override - public RecipeAccess recipeAccess() { - return this.connection.recipes(); - } - - @Override - public TickRateManager tickRateManager() { - return this.tickRateManager; - } - - public ClientClockManager clockManager() { - return this.connection.clockManager(); - } - - @Override - public EnvironmentAttributeSystem environmentAttributes() { - return this.environmentAttributes; - } - - @Override - public LevelTickAccess getBlockTicks() { - return BlackholeTickAccess.emptyLevelList(); - } - - @Override - public LevelTickAccess getFluidTicks() { - return BlackholeTickAccess.emptyLevelList(); - } - - public ClientChunkCache getChunkSource() { - return this.chunkSource; - } - - @Override - public @Nullable MapItemSavedData getMapData(MapId id) { - return this.mapData.get(id); - } - - public void overrideMapData(MapId id, MapItemSavedData data) { - this.mapData.put(id, data); - } - - @Override - public Scoreboard getScoreboard() { - return this.connection.scoreboard(); - } - - @Override - public void sendBlockUpdated(BlockPos pos, BlockState old, BlockState current, @Block.UpdateFlags int updateFlags) { - this.levelRenderer.blockChanged(this, pos, old, current, updateFlags); - } - - @Override - public void setBlocksDirty(BlockPos pos, BlockState oldState, BlockState newState) { - this.levelRenderer.setBlockDirty(pos, oldState, newState); - } - - public void setSectionDirtyWithNeighbors(int chunkX, int chunkY, int chunkZ) { - this.levelRenderer.setSectionDirtyWithNeighbors(chunkX, chunkY, chunkZ); - } - - public void setSectionRangeDirty(int minSectionX, int minSectionY, int minSectionZ, int maxSectionX, int maxSectionY, int maxSectionZ) { - this.levelRenderer.setSectionRangeDirty(minSectionX, minSectionY, minSectionZ, maxSectionX, maxSectionY, maxSectionZ); - } - - @Override - public void destroyBlockProgress(int id, BlockPos blockPos, int progress) { - this.levelRenderer.destroyBlockProgress(id, blockPos, progress); - } - - @Override - public void globalLevelEvent(int type, BlockPos pos, int data) { - this.levelEventHandler.globalLevelEvent(type, pos, data); - } - - @Override - public void levelEvent(@Nullable Entity source, int type, BlockPos pos, int data) { - try { - this.levelEventHandler.levelEvent(type, pos, data); - } catch (Throwable var8) { - CrashReport report = CrashReport.forThrowable(var8, "Playing level event"); - CrashReportCategory category = report.addCategory("Level event being played"); - category.setDetail("Block coordinates", CrashReportCategory.formatLocation(this, pos)); - category.setDetail("Event source", source); - category.setDetail("Event type", type); - category.setDetail("Event data", data); - throw new ReportedException(report); - } - } - - @Override - public void addParticle(ParticleOptions particle, double x, double y, double z, double xd, double yd, double zd) { - this.doAddParticle(particle, particle.getType().getOverrideLimiter(), false, x, y, z, xd, yd, zd); - } - - @Override - public void addParticle( - ParticleOptions particle, boolean overrideLimiter, boolean alwaysShow, double x, double y, double z, double xd, double yd, double zd - ) { - this.doAddParticle(particle, particle.getType().getOverrideLimiter() || overrideLimiter, alwaysShow, x, y, z, xd, yd, zd); - } - - @Override - public void addAlwaysVisibleParticle(ParticleOptions particle, double x, double y, double z, double xd, double yd, double zd) { - this.doAddParticle(particle, false, true, x, y, z, xd, yd, zd); - } - - @Override - public void addAlwaysVisibleParticle(ParticleOptions particle, boolean overrideLimiter, double x, double y, double z, double xd, double yd, double zd) { - this.doAddParticle(particle, particle.getType().getOverrideLimiter() || overrideLimiter, true, x, y, z, xd, yd, zd); - } - - private void doAddParticle( - ParticleOptions particle, boolean overrideLimiter, boolean alwaysShowParticles, double x, double y, double z, double xd, double yd, double zd - ) { - try { - Camera camera = this.minecraft.gameRenderer.getMainCamera(); - ParticleStatus particleLevel = this.calculateParticleLevel(alwaysShowParticles); - if (overrideLimiter) { - this.minecraft.particleEngine.createParticle(particle, x, y, z, xd, yd, zd); - } else if (!(camera.position().distanceToSqr(x, y, z) > 1024.0)) { - if (particleLevel != ParticleStatus.MINIMAL) { - this.minecraft.particleEngine.createParticle(particle, x, y, z, xd, yd, zd); - } - } - } catch (Throwable var19) { - CrashReport report = CrashReport.forThrowable(var19, "Exception while adding particle"); - CrashReportCategory category = report.addCategory("Particle being added"); - category.setDetail("ID", BuiltInRegistries.PARTICLE_TYPE.getKey(particle.getType())); - category.setDetail( - "Parameters", () -> ParticleTypes.CODEC.encodeStart(this.registryAccess().createSerializationContext(NbtOps.INSTANCE), particle).toString() - ); - category.setDetail("Position", () -> CrashReportCategory.formatLocation(this, x, y, z)); - throw new ReportedException(report); - } - } - - private ParticleStatus calculateParticleLevel(boolean alwaysShowParticles) { - ParticleStatus particleLevel = this.minecraft.options.particles().get(); - if (alwaysShowParticles && particleLevel == ParticleStatus.MINIMAL && this.random.nextInt(10) == 0) { - particleLevel = ParticleStatus.DECREASED; - } - - if (particleLevel == ParticleStatus.DECREASED && this.random.nextInt(3) == 0) { - particleLevel = ParticleStatus.MINIMAL; - } - - return particleLevel; - } - - @Override - public List players() { - return this.players; - } - - public List> dragonParts() { - return this.dragonParts; - } - - @Override - public Holder getUncachedNoiseBiome(int quartX, int quartY, int quartZ) { - return this.registryAccess().lookupOrThrow(Registries.BIOME).getOrThrow(Biomes.PLAINS); - } - - private int getSkyFlashTime() { - return this.minecraft.options.hideLightningFlash().get() ? 0 : this.skyFlashTime; - } - - @Override - public void setSkyFlashTime(int skyFlashTime) { - this.skyFlashTime = skyFlashTime; - } - - @Override - public CardinalLighting cardinalLighting() { - return this.dimensionType().cardinalLightType().get(); - } - - @Override - public int getBlockTint(BlockPos pos, ColorResolver resolver) { - BlockTintCache cache = this.tintCaches.get(resolver); - return cache.getColor(pos); - } - - public int calculateBlockTint(BlockPos pos, ColorResolver colorResolver) { - int dist = Minecraft.getInstance().options.biomeBlendRadius().get(); - if (dist == 0) { - return colorResolver.getColor(this.getBiome(pos).value(), pos.getX(), pos.getZ()); - } else { - int count = (dist * 2 + 1) * (dist * 2 + 1); - int totalRed = 0; - int totalGreen = 0; - int totalBlue = 0; - Cursor3D cursor = new Cursor3D(pos.getX() - dist, pos.getY(), pos.getZ() - dist, pos.getX() + dist, pos.getY(), pos.getZ() + dist); - BlockPos.MutableBlockPos nextPos = new BlockPos.MutableBlockPos(); - - while (cursor.advance()) { - nextPos.set(cursor.nextX(), cursor.nextY(), cursor.nextZ()); - int color = colorResolver.getColor(this.getBiome(nextPos).value(), nextPos.getX(), nextPos.getZ()); - totalRed += ARGB.red(color); - totalGreen += ARGB.green(color); - totalBlue += ARGB.blue(color); - } - - return ARGB.color(totalRed / count, totalGreen / count, totalBlue / count); - } - } - - @Override - public void setRespawnData(LevelData.RespawnData respawnData) { - this.levelData.setSpawn(this.getWorldBorderAdjustedRespawnData(respawnData)); - } - - @Override - public LevelData.RespawnData getRespawnData() { - return this.levelData.getRespawnData(); - } - - @Override - public String toString() { - return "ClientLevel"; - } - - public ClientLevel.ClientLevelData getLevelData() { - return this.clientLevelData; - } - - @Override - public void gameEvent(Holder gameEvent, Vec3 pos, GameEvent.Context context) { - } - - protected Map getAllMapData() { - return ImmutableMap.copyOf(this.mapData); - } - - protected void addMapData(Map mapData) { - this.mapData.putAll(mapData); - } - - @Override - protected LevelEntityGetter getEntities() { - return this.entityStorage.getEntityGetter(); - } - - @Override - public String gatherChunkSourceStats() { - return "Chunks[C] W: " + this.chunkSource.gatherStats() + " E: " + this.entityStorage.gatherStats(); - } - - @Override - public void addDestroyBlockEffect(BlockPos pos, BlockState blockState) { - if (!blockState.isAir() && !net.neoforged.neoforge.client.extensions.common.IClientBlockExtensions.of(blockState).addDestroyEffects(blockState, this, pos, this.minecraft.particleEngine)) { - VoxelShape shape = blockState.getShape(this, pos); - double density = 0.25; - shape.forAllBoxes( - (x1, y1, z1, x2, y2, z2) -> { - double widthX = Math.min(1.0, x2 - x1); - double widthY = Math.min(1.0, y2 - y1); - double widthZ = Math.min(1.0, z2 - z1); - int countX = Math.max(2, Mth.ceil(widthX / 0.25)); - int countY = Math.max(2, Mth.ceil(widthY / 0.25)); - int countZ = Math.max(2, Mth.ceil(widthZ / 0.25)); - - for (int xx = 0; xx < countX; xx++) { - for (int yy = 0; yy < countY; yy++) { - for (int zz = 0; zz < countZ; zz++) { - double relX = (xx + 0.5) / countX; - double relY = (yy + 0.5) / countY; - double relZ = (zz + 0.5) / countZ; - double x = relX * widthX + x1; - double y = relY * widthY + y1; - double z = relZ * widthZ + z1; - this.minecraft - .particleEngine - .add( - new TerrainParticle( - this, pos.getX() + x, pos.getY() + y, pos.getZ() + z, relX - 0.5, relY - 0.5, relZ - 0.5, blockState, pos - ).updateSprite(blockState, pos) - ); - } - } - } - } - ); - } - } - - /** - * @deprecated Neo: use {@link #addBreakingBlockEffect(BlockPos, Direction, net.minecraft.world.phys.HitResult)} instead - */ - public void addBreakingBlockEffect(BlockPos pos, Direction direction) { - this.addBreakingBlockEffect(pos, direction, null); - } - - public void addBreakingBlockEffect(BlockPos pos, Direction direction, net.minecraft.world.phys.@Nullable HitResult hitResult) { - BlockState blockState = this.getBlockState(pos); - if (blockState.getRenderShape() != RenderShape.INVISIBLE && !net.neoforged.neoforge.client.extensions.common.IClientBlockExtensions.of(blockState).addHitEffects(blockState, this, hitResult, this.minecraft.particleEngine)) { - int x = pos.getX(); - int y = pos.getY(); - int z = pos.getZ(); - float r = 0.1F; - AABB shape = blockState.getShape(this, pos).bounds(); - double xp = x + this.random.nextDouble() * (shape.maxX - shape.minX - 0.2F) + 0.1F + shape.minX; - double yp = y + this.random.nextDouble() * (shape.maxY - shape.minY - 0.2F) + 0.1F + shape.minY; - double zp = z + this.random.nextDouble() * (shape.maxZ - shape.minZ - 0.2F) + 0.1F + shape.minZ; - if (direction == Direction.DOWN) { - yp = y + shape.minY - 0.1F; - } - - if (direction == Direction.UP) { - yp = y + shape.maxY + 0.1F; - } - - if (direction == Direction.NORTH) { - zp = z + shape.minZ - 0.1F; - } - - if (direction == Direction.SOUTH) { - zp = z + shape.maxZ + 0.1F; - } - - if (direction == Direction.WEST) { - xp = x + shape.minX - 0.1F; - } - - if (direction == Direction.EAST) { - xp = x + shape.maxX + 0.1F; - } - - this.minecraft.particleEngine.add(new TerrainParticle(this, xp, yp, zp, 0.0, 0.0, 0.0, blockState, pos).updateSprite(blockState, pos).setPower(0.2F).scale(0.6F)); - } - } - - public void setServerSimulationDistance(int serverSimulationDistance) { - this.serverSimulationDistance = serverSimulationDistance; - } - - public int getServerSimulationDistance() { - return this.serverSimulationDistance; - } - - @Override - public FeatureFlagSet enabledFeatures() { - return this.connection.enabledFeatures(); - } - - @Override - public PotionBrewing potionBrewing() { - return this.connection.potionBrewing(); - } - - @Override - public FuelValues fuelValues() { - return this.connection.fuelValues(); - } - - @Override - public void explode( - @Nullable Entity source, - @Nullable DamageSource damageSource, - @Nullable ExplosionDamageCalculator damageCalculator, - double x, - double y, - double z, - float r, - boolean fire, - Level.ExplosionInteraction interactionType, - ParticleOptions smallExplosionParticles, - ParticleOptions largeExplosionParticles, - WeightedList secondaryParticles, - Holder explosionSound - ) { - } - - @Override - public int getSeaLevel() { - return this.seaLevel; - } - - @Override - public int getClientLeafTintColor(BlockPos pos) { - BlockState state = this.getBlockState(pos); - BlockTintSource tintSource = Minecraft.getInstance().getBlockColors().getTintSource(state, 0); - return tintSource != null ? tintSource.colorInWorld(state, this, pos) : -1; - } - - @Override - public void registerForCleaning(CacheSlot slot) { - this.connection.registerForCleaning(slot); - } - - public void trackExplosionEffects(Vec3 center, float radius, int blockCount, WeightedList blockParticles) { - this.explosionTracker.track(center, radius, blockCount, blockParticles); - } - - @OnlyIn(Dist.CLIENT) - public static class ClientLevelData implements WritableLevelData { - private final boolean hardcore; - private final boolean isFlat; - private LevelData.RespawnData respawnData; - private long gameTime; - private Difficulty difficulty; - private boolean difficultyLocked; - - public ClientLevelData(Difficulty difficulty, boolean hardcore, boolean isFlat) { - this.difficulty = difficulty; - this.hardcore = hardcore; - this.isFlat = isFlat; - } - - @Override - public LevelData.RespawnData getRespawnData() { - return this.respawnData; - } - - @Override - public long getGameTime() { - return this.gameTime; - } - - public void setGameTime(long time) { - this.gameTime = time; - } - - @Override - public void setSpawn(LevelData.RespawnData respawnData) { - this.respawnData = respawnData; - } - - @Override - public boolean isHardcore() { - return this.hardcore; - } - - @Override - public Difficulty getDifficulty() { - return this.difficulty; - } - - @Override - public boolean isDifficultyLocked() { - return this.difficultyLocked; - } - - @Override - public void fillCrashReportCategory(CrashReportCategory category, LevelHeightAccessor levelHeightAccessor) { - WritableLevelData.super.fillCrashReportCategory(category, levelHeightAccessor); - } - - public void setDifficulty(Difficulty difficulty) { - net.neoforged.neoforge.common.CommonHooks.onDifficultyChange(difficulty, this.difficulty); - this.difficulty = difficulty; - } - - public void setDifficultyLocked(boolean locked) { - this.difficultyLocked = locked; - } - - public double getHorizonHeight(LevelHeightAccessor level) { - return this.isFlat ? level.getMinY() : 63.0; - } - - public float voidDarknessOnsetRange() { - return this.isFlat ? 1.0F : 32.0F; - } - } - - @OnlyIn(Dist.CLIENT) - private final class EntityCallbacks implements LevelCallback { - private EntityCallbacks() { - Objects.requireNonNull(ClientLevel.this); - super(); - } - - public void onCreated(Entity entity) { - } - - public void onDestroyed(Entity entity) { - } - - public void onTickingStart(Entity entity) { - ClientLevel.this.tickingEntities.add(entity); - } - - public void onTickingEnd(Entity entity) { - ClientLevel.this.tickingEntities.remove(entity); - } - - public void onTrackingStart(Entity entity) { - switch (entity) { - case AbstractClientPlayer player: - ClientLevel.this.players.add(player); - break; - case EnderDragon dragon: - ClientLevel.this.dragonParts.addAll(Arrays.asList(dragon.getSubEntities())); - break; - default: - if (entity.isMultipartEntity()) { - ClientLevel.this.dragonParts.addAll(Arrays.asList(entity.getParts())); - } - } - } - - public void onTrackingEnd(Entity entity) { - entity.unRide(); - switch (entity) { - case AbstractClientPlayer player: - ClientLevel.this.players.remove(player); - break; - case EnderDragon dragon: - ClientLevel.this.dragonParts.removeAll(Arrays.asList(dragon.getSubEntities())); - break; - default: - if (entity.isMultipartEntity()) { - ClientLevel.this.dragonParts.removeAll(Arrays.asList(entity.getParts())); - } - } - - entity.onRemovedFromLevel(); - net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.event.entity.EntityLeaveLevelEvent(entity, ClientLevel.this)); - } - - public void onSectionChange(Entity entity) { - } - } - - @Override - public net.neoforged.neoforge.model.data.ModelDataManager getModelDataManager() { - return modelDataManager; - } - - @Override - public net.neoforged.neoforge.model.data.ModelData getModelData(BlockPos pos) { - return modelDataManager.getAt(pos); - } -} diff --git a/net/minecraft/client/particle/Particle.java b/net/minecraft/client/particle/Particle.java deleted file mode 100644 index 4359ea19..00000000 --- a/net/minecraft/client/particle/Particle.java +++ /dev/null @@ -1,229 +0,0 @@ -package net.minecraft.client.particle; - -import java.util.List; -import java.util.Optional; -import net.minecraft.client.multiplayer.ClientLevel; -import net.minecraft.client.renderer.LevelRenderer; -import net.minecraft.core.BlockPos; -import net.minecraft.core.particles.ParticleLimit; -import net.minecraft.util.Mth; -import net.minecraft.util.RandomSource; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.phys.AABB; -import net.minecraft.world.phys.Vec3; -import net.neoforged.api.distmarker.Dist; -import net.neoforged.api.distmarker.OnlyIn; - -@OnlyIn(Dist.CLIENT) -public abstract class Particle { - private static final AABB INITIAL_AABB = new AABB(0.0, 0.0, 0.0, 0.0, 0.0, 0.0); - private static final double MAXIMUM_COLLISION_VELOCITY_SQUARED = Mth.square(100.0); - protected final ClientLevel level; - protected double xo; - protected double yo; - protected double zo; - protected double x; - protected double y; - protected double z; - protected double xd; - protected double yd; - protected double zd; - private AABB bb = INITIAL_AABB; - protected boolean onGround; - protected boolean hasPhysics = true; - private boolean stoppedByCollision; - protected boolean removed; - protected float bbWidth = 0.6F; - protected float bbHeight = 1.8F; - protected final RandomSource random = RandomSource.create(); - protected int age; - protected int lifetime; - protected float gravity; - protected float friction = 0.98F; - protected boolean speedUpWhenYMotionIsBlocked = false; - - public Particle(ClientLevel level, double x, double y, double z) { - this.level = level; - this.setSize(0.2F, 0.2F); - this.setPos(x, y, z); - this.xo = x; - this.yo = y; - this.zo = z; - this.lifetime = (int)(4.0F / (this.random.nextFloat() * 0.9F + 0.1F)); - } - - public Particle(ClientLevel level, double x, double y, double z, double xa, double ya, double za) { - this(level, x, y, z); - this.xd = xa + (this.random.nextFloat() * 2.0F - 1.0F) * 0.4F; - this.yd = ya + (this.random.nextFloat() * 2.0F - 1.0F) * 0.4F; - this.zd = za + (this.random.nextFloat() * 2.0F - 1.0F) * 0.4F; - double speed = (this.random.nextFloat() + this.random.nextFloat() + 1.0F) * 0.15F; - double dd = Math.sqrt(this.xd * this.xd + this.yd * this.yd + this.zd * this.zd); - this.xd = this.xd / dd * speed * 0.4F; - this.yd = this.yd / dd * speed * 0.4F + 0.1F; - this.zd = this.zd / dd * speed * 0.4F; - } - - public Particle setPower(float power) { - this.xd *= power; - this.yd = (this.yd - 0.1F) * power + 0.1F; - this.zd *= power; - return this; - } - - public void setParticleSpeed(double xd, double yd, double zd) { - this.xd = xd; - this.yd = yd; - this.zd = zd; - } - - public Particle scale(float scale) { - this.setSize(0.2F * scale, 0.2F * scale); - return this; - } - - public void setLifetime(int lifetime) { - this.lifetime = lifetime; - } - - public int getLifetime() { - return this.lifetime; - } - - public void tick() { - this.xo = this.x; - this.yo = this.y; - this.zo = this.z; - if (this.age++ >= this.lifetime) { - this.remove(); - } else { - this.yd = this.yd - 0.04 * this.gravity; - this.move(this.xd, this.yd, this.zd); - if (this.speedUpWhenYMotionIsBlocked && this.y == this.yo) { - this.xd *= 1.1; - this.zd *= 1.1; - } - - this.xd = this.xd * this.friction; - this.yd = this.yd * this.friction; - this.zd = this.zd * this.friction; - if (this.onGround) { - this.xd *= 0.7F; - this.zd *= 0.7F; - } - } - } - - public abstract ParticleRenderType getGroup(); - - @Override - public String toString() { - return this.getClass().getSimpleName() + ", Pos (" + this.x + "," + this.y + "," + this.z + "), Age " + this.age; - } - - public void remove() { - this.removed = true; - } - - protected void setSize(float w, float h) { - if (w != this.bbWidth || h != this.bbHeight) { - this.bbWidth = w; - this.bbHeight = h; - AABB aabb = this.getBoundingBox(); - double newMinX = (aabb.minX + aabb.maxX - w) / 2.0; - double newMinZ = (aabb.minZ + aabb.maxZ - w) / 2.0; - this.setBoundingBox(new AABB(newMinX, aabb.minY, newMinZ, newMinX + this.bbWidth, aabb.minY + this.bbHeight, newMinZ + this.bbWidth)); - } - } - - public void setPos(double x, double y, double z) { - this.x = x; - this.y = y; - this.z = z; - float w = this.bbWidth / 2.0F; - float h = this.bbHeight; - this.setBoundingBox(new AABB(x - w, y, z - w, x + w, y + h, z + w)); - } - - public void move(double xa, double ya, double za) { - if (!this.stoppedByCollision) { - double originalXa = xa; - double originalYa = ya; - double originalZa = za; - if (this.hasPhysics && (xa != 0.0 || ya != 0.0 || za != 0.0) && xa * xa + ya * ya + za * za < MAXIMUM_COLLISION_VELOCITY_SQUARED) { - Vec3 movement = Entity.collideBoundingBox(null, new Vec3(xa, ya, za), this.getBoundingBox(), this.level, List.of()); - xa = movement.x; - ya = movement.y; - za = movement.z; - } - - if (xa != 0.0 || ya != 0.0 || za != 0.0) { - this.setBoundingBox(this.getBoundingBox().move(xa, ya, za)); - this.setLocationFromBoundingbox(); - } - - if (Math.abs(originalYa) >= 1.0E-5F && Math.abs(ya) < 1.0E-5F) { - this.stoppedByCollision = true; - } - - this.onGround = originalYa != ya && originalYa < 0.0; - if (originalXa != xa) { - this.xd = 0.0; - } - - if (originalZa != za) { - this.zd = 0.0; - } - } - } - - protected void setLocationFromBoundingbox() { - AABB aabb = this.getBoundingBox(); - this.x = (aabb.minX + aabb.maxX) / 2.0; - this.y = aabb.minY; - this.z = (aabb.minZ + aabb.maxZ) / 2.0; - } - - protected int getLightCoords(float a) { - BlockPos pos = BlockPos.containing(this.x, this.y, this.z); - return this.level.hasChunkAt(pos) ? LevelRenderer.getLightCoords(this.level, pos) : 15728640; - } - - public boolean isAlive() { - return !this.removed; - } - - public AABB getBoundingBox() { - return this.bb; - } - - public void setBoundingBox(AABB bb) { - this.bb = bb; - } - - public Optional getParticleLimit() { - return Optional.empty(); - } - - public Vec3 getPos() { - return new Vec3(this.x, this.y, this.z); - } - - @OnlyIn(Dist.CLIENT) - public record LifetimeAlpha(float startAlpha, float endAlpha, float startAtNormalizedAge, float endAtNormalizedAge) { - public static final Particle.LifetimeAlpha ALWAYS_OPAQUE = new Particle.LifetimeAlpha(1.0F, 1.0F, 0.0F, 1.0F); - - public boolean isOpaque() { - return this.startAlpha >= 1.0F && this.endAlpha >= 1.0F; - } - - public float currentAlphaForAge(int age, int lifetime, float partialTickTime) { - if (Mth.equal(this.startAlpha, this.endAlpha)) { - return this.startAlpha; - } else { - float timeNormalized = Mth.inverseLerp((age + partialTickTime) / lifetime, this.startAtNormalizedAge, this.endAtNormalizedAge); - return Mth.clampedLerp(timeNormalized, this.startAlpha, this.endAlpha); - } - } - } -} diff --git a/net/minecraft/client/particle/ParticleEngine.java b/net/minecraft/client/particle/ParticleEngine.java deleted file mode 100644 index 29d826ba..00000000 --- a/net/minecraft/client/particle/ParticleEngine.java +++ /dev/null @@ -1,157 +0,0 @@ -package net.minecraft.client.particle; - -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.collect.Queues; -import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Queue; -import net.minecraft.client.Camera; -import net.minecraft.client.multiplayer.ClientLevel; -import net.minecraft.client.renderer.culling.Frustum; -import net.minecraft.client.renderer.state.level.ParticlesRenderState; -import net.minecraft.core.particles.ParticleLimit; -import net.minecraft.core.particles.ParticleOptions; -import net.minecraft.core.registries.BuiltInRegistries; -import net.minecraft.util.RandomSource; -import net.minecraft.util.profiling.Profiler; -import net.minecraft.world.entity.Entity; -import net.neoforged.api.distmarker.Dist; -import net.neoforged.api.distmarker.OnlyIn; -import org.jspecify.annotations.Nullable; - -@OnlyIn(Dist.CLIENT) -public class ParticleEngine { - private static final List RENDER_ORDER = List.of( - ParticleRenderType.SINGLE_QUADS, ParticleRenderType.ITEM_PICKUP, ParticleRenderType.ELDER_GUARDIANS - ); - protected ClientLevel level; - private final Map> particles = Maps.newIdentityHashMap(); - private final Queue trackingEmitters = Queues.newArrayDeque(); - private final Queue particlesToAdd = Queues.newArrayDeque(); - private final Object2IntOpenHashMap trackedParticleCounts = new Object2IntOpenHashMap<>(); - private final ParticleResources resourceManager; - private final RandomSource random = RandomSource.create(); - private final Map>> particleGroupFactories; - private final List particleRenderOrder; - - public ParticleEngine(ClientLevel level, ParticleResources resourceManager) { - this.level = level; - this.resourceManager = resourceManager; - var particleGroupFactories = new it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap>>(); - var particleRenderOrder = new java.util.ArrayList<>(RENDER_ORDER); - net.neoforged.fml.ModLoader.postEvent(new net.neoforged.neoforge.client.event.RegisterParticleGroupsEvent(particleGroupFactories, particleRenderOrder)); - this.particleGroupFactories = it.unimi.dsi.fastutil.objects.Reference2ObjectMaps.unmodifiable(particleGroupFactories); - this.particleRenderOrder = List.copyOf(particleRenderOrder); - } - - public void createTrackingEmitter(Entity entity, ParticleOptions particle) { - this.trackingEmitters.add(new TrackingEmitter(this.level, entity, particle)); - } - - public void createTrackingEmitter(Entity entity, ParticleOptions particle, int lifeTime) { - this.trackingEmitters.add(new TrackingEmitter(this.level, entity, particle, lifeTime)); - } - - public @Nullable Particle createParticle(ParticleOptions options, double x, double y, double z, double xa, double ya, double za) { - Particle particle = this.makeParticle(options, x, y, z, xa, ya, za); - if (particle != null) { - this.add(particle); - return particle; - } else { - return null; - } - } - - private @Nullable Particle makeParticle(T options, double x, double y, double z, double xa, double ya, double za) { - ParticleProvider provider = (ParticleProvider)this.resourceManager.getProviders().get(BuiltInRegistries.PARTICLE_TYPE.getKey(options.getType())); - return provider == null ? null : provider.createParticle(options, this.level, x, y, z, xa, ya, za, this.random); - } - - public void add(Particle p) { - Optional limit = p.getParticleLimit(); - if (limit.isPresent()) { - if (this.hasSpaceInParticleLimit(limit.get())) { - this.particlesToAdd.add(p); - this.updateCount(limit.get(), 1); - } - } else { - this.particlesToAdd.add(p); - } - } - - public void tick() { - this.particles.forEach((type, group) -> { - Profiler.get().push(type.name()); - group.tickParticles(); - Profiler.get().pop(); - }); - if (!this.trackingEmitters.isEmpty()) { - List removed = Lists.newArrayList(); - - for (TrackingEmitter emitter : this.trackingEmitters) { - emitter.tick(); - if (!emitter.isAlive()) { - removed.add(emitter); - } - } - - this.trackingEmitters.removeAll(removed); - } - - Particle particle; - if (!this.particlesToAdd.isEmpty()) { - while ((particle = this.particlesToAdd.poll()) != null) { - this.particles.computeIfAbsent(particle.getGroup(), this::createParticleGroup).add(particle); - } - } - } - - private ParticleGroup createParticleGroup(ParticleRenderType type) { - if (type == ParticleRenderType.ITEM_PICKUP) { - return new ItemPickupParticleGroup(this); - } else if (type == ParticleRenderType.ELDER_GUARDIANS) { - return new ElderGuardianParticleGroup(this); - } else if (this.particleGroupFactories.containsKey(type)) { - return this.particleGroupFactories.get(type).apply(this); - } else { - return (ParticleGroup)(type == ParticleRenderType.NO_RENDER ? new NoRenderParticleGroup(this) : new QuadParticleGroup(this, type)); - } - } - - protected void updateCount(ParticleLimit limit, int change) { - this.trackedParticleCounts.addTo(limit, change); - } - - public void extract(ParticlesRenderState particlesRenderState, Frustum frustum, Camera camera, float partialTickTime) { - for (ParticleRenderType particleType : this.particleRenderOrder) { - ParticleGroup particles = this.particles.get(particleType); - if (particles != null && !particles.isEmpty()) { - particlesRenderState.add(particles.extractRenderState(frustum, camera, partialTickTime)); - } - } - } - - public void setLevel(@Nullable ClientLevel level) { - this.level = level; - this.clearParticles(); - this.trackingEmitters.clear(); - } - - public String countParticles() { - return String.valueOf(this.particles.values().stream().mapToInt(ParticleGroup::size).sum()); - } - - private boolean hasSpaceInParticleLimit(ParticleLimit limit) { - return this.trackedParticleCounts.getInt(limit) < limit.limit(); - } - - public void clearParticles() { - this.particles.clear(); - this.particlesToAdd.clear(); - this.trackingEmitters.clear(); - this.trackedParticleCounts.clear(); - } -} diff --git a/net/minecraft/client/particle/ParticleGroup.java b/net/minecraft/client/particle/ParticleGroup.java deleted file mode 100644 index 24567071..00000000 --- a/net/minecraft/client/particle/ParticleGroup.java +++ /dev/null @@ -1,69 +0,0 @@ -package net.minecraft.client.particle; - -import com.google.common.collect.EvictingQueue; -import java.util.Iterator; -import java.util.Queue; -import net.minecraft.CrashReport; -import net.minecraft.CrashReportCategory; -import net.minecraft.ReportedException; -import net.minecraft.client.Camera; -import net.minecraft.client.renderer.culling.Frustum; -import net.minecraft.client.renderer.state.level.ParticleGroupRenderState; -import net.neoforged.api.distmarker.Dist; -import net.neoforged.api.distmarker.OnlyIn; - -@OnlyIn(Dist.CLIENT) -public abstract class ParticleGroup

{ - private static final int MAX_PARTICLES = 16384; - protected final ParticleEngine engine; - protected final Queue

particles = EvictingQueue.create(16384); - - public ParticleGroup(ParticleEngine engine) { - this.engine = engine; - } - - public boolean isEmpty() { - return this.particles.isEmpty(); - } - - public void tickParticles() { - if (!this.particles.isEmpty()) { - Iterator

iterator = this.particles.iterator(); - - while (iterator.hasNext()) { - P particle = iterator.next(); - this.tickParticle(particle); - if (!particle.isAlive()) { - particle.getParticleLimit().ifPresent(options -> this.engine.updateCount(options, -1)); - iterator.remove(); - } - } - } - } - - private void tickParticle(Particle particle) { - try { - particle.tick(); - } catch (Throwable var5) { - CrashReport report = CrashReport.forThrowable(var5, "Ticking Particle"); - CrashReportCategory category = report.addCategory("Particle being ticked"); - category.setDetail("Particle", particle::toString); - category.setDetail("Particle Type", particle.getGroup()::toString); - throw new ReportedException(report); - } - } - - public void add(Particle particle) { - this.particles.add((P)particle); - } - - public int size() { - return this.particles.size(); - } - - public abstract ParticleGroupRenderState extractRenderState(Frustum frustum, Camera camera, float partialTickTime); - - public Queue

getAll() { - return this.particles; - } -} diff --git a/net/minecraft/client/particle/ParticleResources.java b/net/minecraft/client/particle/ParticleResources.java deleted file mode 100644 index 240114fc..00000000 --- a/net/minecraft/client/particle/ParticleResources.java +++ /dev/null @@ -1,318 +0,0 @@ -package net.minecraft.client.particle; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Maps; -import com.mojang.logging.LogUtils; -import it.unimi.dsi.fastutil.ints.Int2ObjectMap; -import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; -import java.io.IOException; -import java.io.Reader; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Set; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.Executor; -import java.util.stream.Collectors; -import net.minecraft.client.renderer.texture.SpriteLoader; -import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraft.client.resources.model.sprite.AtlasManager; -import net.minecraft.core.particles.ParticleOptions; -import net.minecraft.core.particles.ParticleType; -import net.minecraft.core.particles.ParticleTypes; -import net.minecraft.core.registries.BuiltInRegistries; -import net.minecraft.data.AtlasIds; -import net.minecraft.resources.FileToIdConverter; -import net.minecraft.resources.Identifier; -import net.minecraft.server.packs.resources.PreparableReloadListener; -import net.minecraft.server.packs.resources.Resource; -import net.minecraft.server.packs.resources.ResourceManager; -import net.minecraft.util.GsonHelper; -import net.minecraft.util.RandomSource; -import net.minecraft.util.Util; -import net.minecraft.util.profiling.Profiler; -import net.minecraft.util.profiling.ProfilerFiller; -import net.neoforged.api.distmarker.Dist; -import net.neoforged.api.distmarker.OnlyIn; -import org.jspecify.annotations.Nullable; -import org.slf4j.Logger; - -@OnlyIn(Dist.CLIENT) -public class ParticleResources implements PreparableReloadListener { - private static final Logger LOGGER = LogUtils.getLogger(); - private static final FileToIdConverter PARTICLE_LISTER = FileToIdConverter.json("particles"); - private final Map spriteSets = Maps.newHashMap(); - private final Map> providers = new java.util.HashMap<>(); - private @Nullable Runnable onReload; - - public ParticleResources() { - this.registerProviders(); - } - - public void onReload(Runnable onReload) { - this.onReload = onReload; - } - - private void registerProviders() { - this.register(ParticleTypes.ANGRY_VILLAGER, HeartParticle.AngryVillagerProvider::new); - this.register(ParticleTypes.BLOCK_MARKER, new BlockMarker.Provider()); - this.register(ParticleTypes.BLOCK, new TerrainParticle.Provider()); - this.register(ParticleTypes.BUBBLE, BubbleParticle.Provider::new); - this.register(ParticleTypes.BUBBLE_COLUMN_UP, BubbleColumnUpParticle.Provider::new); - this.register(ParticleTypes.BUBBLE_POP, BubblePopParticle.Provider::new); - this.register(ParticleTypes.CAMPFIRE_COSY_SMOKE, CampfireSmokeParticle.CosyProvider::new); - this.register(ParticleTypes.CAMPFIRE_SIGNAL_SMOKE, CampfireSmokeParticle.SignalProvider::new); - this.register(ParticleTypes.CLOUD, PlayerCloudParticle.Provider::new); - this.register(ParticleTypes.COMPOSTER, SuspendedTownParticle.ComposterFillProvider::new); - this.register(ParticleTypes.COPPER_FIRE_FLAME, FlameParticle.Provider::new); - this.register(ParticleTypes.CRIT, CritParticle.Provider::new); - this.register(ParticleTypes.CURRENT_DOWN, WaterCurrentDownParticle.Provider::new); - this.register(ParticleTypes.DAMAGE_INDICATOR, CritParticle.DamageIndicatorProvider::new); - this.register(ParticleTypes.DRAGON_BREATH, DragonBreathParticle.Provider::new); - this.register(ParticleTypes.DOLPHIN, SuspendedTownParticle.DolphinSpeedProvider::new); - this.register(ParticleTypes.DRIPPING_LAVA, DripParticle.LavaHangProvider::new); - this.register(ParticleTypes.FALLING_LAVA, DripParticle.LavaFallProvider::new); - this.register(ParticleTypes.LANDING_LAVA, DripParticle.LavaLandProvider::new); - this.register(ParticleTypes.DRIPPING_WATER, DripParticle.WaterHangProvider::new); - this.register(ParticleTypes.FALLING_WATER, DripParticle.WaterFallProvider::new); - this.register(ParticleTypes.DUST, DustParticle.Provider::new); - this.register(ParticleTypes.DUST_COLOR_TRANSITION, DustColorTransitionParticle.Provider::new); - this.register(ParticleTypes.EFFECT, SpellParticle.InstantProvider::new); - this.register(ParticleTypes.ELDER_GUARDIAN, new ElderGuardianParticle.Provider()); - this.register(ParticleTypes.ENCHANTED_HIT, CritParticle.MagicProvider::new); - this.register(ParticleTypes.ENCHANT, FlyTowardsPositionParticle.EnchantProvider::new); - this.register(ParticleTypes.END_ROD, EndRodParticle.Provider::new); - this.register(ParticleTypes.ENTITY_EFFECT, SpellParticle.MobEffectProvider::new); - this.register(ParticleTypes.EXPLOSION_EMITTER, new HugeExplosionSeedParticle.Provider()); - this.register(ParticleTypes.EXPLOSION, HugeExplosionParticle.Provider::new); - this.register(ParticleTypes.SONIC_BOOM, SonicBoomParticle.Provider::new); - this.register(ParticleTypes.FALLING_DUST, FallingDustParticle.Provider::new); - this.register(ParticleTypes.GUST, GustParticle.Provider::new); - this.register(ParticleTypes.SMALL_GUST, GustParticle.SmallProvider::new); - this.register(ParticleTypes.GUST_EMITTER_LARGE, new GustSeedParticle.Provider(3.0, 7, 0)); - this.register(ParticleTypes.GUST_EMITTER_SMALL, new GustSeedParticle.Provider(1.0, 3, 2)); - this.register(ParticleTypes.FIREWORK, FireworkParticles.SparkProvider::new); - this.register(ParticleTypes.FISHING, WakeParticle.Provider::new); - this.register(ParticleTypes.FLAME, FlameParticle.Provider::new); - this.register(ParticleTypes.INFESTED, SpellParticle.Provider::new); - this.register(ParticleTypes.SCULK_SOUL, SoulParticle.EmissiveProvider::new); - this.register(ParticleTypes.SCULK_CHARGE, SculkChargeParticle.Provider::new); - this.register(ParticleTypes.SCULK_CHARGE_POP, SculkChargePopParticle.Provider::new); - this.register(ParticleTypes.SOUL, SoulParticle.Provider::new); - this.register(ParticleTypes.SOUL_FIRE_FLAME, FlameParticle.Provider::new); - this.register(ParticleTypes.FLASH, FireworkParticles.FlashProvider::new); - this.register(ParticleTypes.HAPPY_VILLAGER, SuspendedTownParticle.HappyVillagerProvider::new); - this.register(ParticleTypes.HEART, HeartParticle.Provider::new); - this.register(ParticleTypes.INSTANT_EFFECT, SpellParticle.InstantProvider::new); - this.register(ParticleTypes.ITEM, new BreakingItemParticle.Provider()); - this.register(ParticleTypes.ITEM_SLIME, new BreakingItemParticle.SlimeProvider()); - this.register(ParticleTypes.ITEM_COBWEB, new BreakingItemParticle.CobwebProvider()); - this.register(ParticleTypes.ITEM_SNOWBALL, new BreakingItemParticle.SnowballProvider()); - this.register(ParticleTypes.LARGE_SMOKE, LargeSmokeParticle.Provider::new); - this.register(ParticleTypes.LAVA, LavaParticle.Provider::new); - this.register(ParticleTypes.MYCELIUM, SuspendedTownParticle.Provider::new); - this.register(ParticleTypes.NAUTILUS, FlyTowardsPositionParticle.NautilusProvider::new); - this.register(ParticleTypes.NOTE, NoteParticle.Provider::new); - this.register(ParticleTypes.POOF, ExplodeParticle.Provider::new); - this.register(ParticleTypes.PORTAL, PortalParticle.Provider::new); - this.register(ParticleTypes.RAIN, WaterDropParticle.Provider::new); - this.register(ParticleTypes.SMOKE, SmokeParticle.Provider::new); - this.register(ParticleTypes.WHITE_SMOKE, WhiteSmokeParticle.Provider::new); - this.register(ParticleTypes.SNEEZE, PlayerCloudParticle.SneezeProvider::new); - this.register(ParticleTypes.SNOWFLAKE, SnowflakeParticle.Provider::new); - this.register(ParticleTypes.SPIT, SpitParticle.Provider::new); - this.register(ParticleTypes.SWEEP_ATTACK, AttackSweepParticle.Provider::new); - this.register(ParticleTypes.TOTEM_OF_UNDYING, TotemParticle.Provider::new); - this.register(ParticleTypes.SQUID_INK, SquidInkParticle.Provider::new); - this.register(ParticleTypes.UNDERWATER, SuspendedParticle.UnderwaterProvider::new); - this.register(ParticleTypes.SPLASH, SplashParticle.Provider::new); - this.register(ParticleTypes.WITCH, SpellParticle.WitchProvider::new); - this.register(ParticleTypes.DRIPPING_HONEY, DripParticle.HoneyHangProvider::new); - this.register(ParticleTypes.FALLING_HONEY, DripParticle.HoneyFallProvider::new); - this.register(ParticleTypes.LANDING_HONEY, DripParticle.HoneyLandProvider::new); - this.register(ParticleTypes.FALLING_NECTAR, DripParticle.NectarFallProvider::new); - this.register(ParticleTypes.FALLING_SPORE_BLOSSOM, DripParticle.SporeBlossomFallProvider::new); - this.register(ParticleTypes.SPORE_BLOSSOM_AIR, SuspendedParticle.SporeBlossomAirProvider::new); - this.register(ParticleTypes.ASH, AshParticle.Provider::new); - this.register(ParticleTypes.CRIMSON_SPORE, SuspendedParticle.CrimsonSporeProvider::new); - this.register(ParticleTypes.WARPED_SPORE, SuspendedParticle.WarpedSporeProvider::new); - this.register(ParticleTypes.DRIPPING_OBSIDIAN_TEAR, DripParticle.ObsidianTearHangProvider::new); - this.register(ParticleTypes.FALLING_OBSIDIAN_TEAR, DripParticle.ObsidianTearFallProvider::new); - this.register(ParticleTypes.LANDING_OBSIDIAN_TEAR, DripParticle.ObsidianTearLandProvider::new); - this.register(ParticleTypes.REVERSE_PORTAL, ReversePortalParticle.ReversePortalProvider::new); - this.register(ParticleTypes.WHITE_ASH, WhiteAshParticle.Provider::new); - this.register(ParticleTypes.SMALL_FLAME, FlameParticle.SmallFlameProvider::new); - this.register(ParticleTypes.DRIPPING_DRIPSTONE_WATER, DripParticle.DripstoneWaterHangProvider::new); - this.register(ParticleTypes.FALLING_DRIPSTONE_WATER, DripParticle.DripstoneWaterFallProvider::new); - this.register(ParticleTypes.CHERRY_LEAVES, FallingLeavesParticle.CherryProvider::new); - this.register(ParticleTypes.PALE_OAK_LEAVES, FallingLeavesParticle.PaleOakProvider::new); - this.register(ParticleTypes.TINTED_LEAVES, FallingLeavesParticle.TintedLeavesProvider::new); - this.register(ParticleTypes.DRIPPING_DRIPSTONE_LAVA, DripParticle.DripstoneLavaHangProvider::new); - this.register(ParticleTypes.FALLING_DRIPSTONE_LAVA, DripParticle.DripstoneLavaFallProvider::new); - this.register(ParticleTypes.VIBRATION, VibrationSignalParticle.Provider::new); - this.register(ParticleTypes.TRAIL, TrailParticle.Provider::new); - this.register(ParticleTypes.PAUSE_MOB_GROWTH, SimpleVerticalParticle.PauseMobGrowthProvider::new); - this.register(ParticleTypes.RESET_MOB_GROWTH, SimpleVerticalParticle.ResetMobGrowthProvider::new); - this.register(ParticleTypes.GLOW_SQUID_INK, SquidInkParticle.GlowInkProvider::new); - this.register(ParticleTypes.GLOW, GlowParticle.GlowSquidProvider::new); - this.register(ParticleTypes.WAX_ON, GlowParticle.WaxOnProvider::new); - this.register(ParticleTypes.WAX_OFF, GlowParticle.WaxOffProvider::new); - this.register(ParticleTypes.ELECTRIC_SPARK, GlowParticle.ElectricSparkProvider::new); - this.register(ParticleTypes.SCRAPE, GlowParticle.ScrapeProvider::new); - this.register(ParticleTypes.SHRIEK, ShriekParticle.Provider::new); - this.register(ParticleTypes.EGG_CRACK, SuspendedTownParticle.EggCrackProvider::new); - this.register(ParticleTypes.DUST_PLUME, DustPlumeParticle.Provider::new); - this.register(ParticleTypes.TRIAL_SPAWNER_DETECTED_PLAYER, TrialSpawnerDetectionParticle.Provider::new); - this.register(ParticleTypes.TRIAL_SPAWNER_DETECTED_PLAYER_OMINOUS, TrialSpawnerDetectionParticle.Provider::new); - this.register(ParticleTypes.VAULT_CONNECTION, FlyTowardsPositionParticle.VaultConnectionProvider::new); - this.register(ParticleTypes.DUST_PILLAR, new TerrainParticle.DustPillarProvider()); - this.register(ParticleTypes.RAID_OMEN, SpellParticle.Provider::new); - this.register(ParticleTypes.TRIAL_OMEN, SpellParticle.Provider::new); - this.register(ParticleTypes.OMINOUS_SPAWNING, FlyStraightTowardsParticle.OminousSpawnProvider::new); - this.register(ParticleTypes.BLOCK_CRUMBLE, new TerrainParticle.CrumblingProvider()); - this.register(ParticleTypes.FIREFLY, FireflyParticle.FireflyProvider::new); - } - - /** @deprecated Register via {@link net.neoforged.neoforge.client.event.RegisterParticleProvidersEvent} */ - @Deprecated - public void register(ParticleType type, ParticleProvider provider) { - this.providers.put(BuiltInRegistries.PARTICLE_TYPE.getKey(type), provider); - } - - /** @deprecated Register via {@link net.neoforged.neoforge.client.event.RegisterParticleProvidersEvent} */ - @Deprecated - public void register(ParticleType type, ParticleResources.SpriteParticleRegistration provider) { - ParticleResources.MutableSpriteSet spriteSet = new ParticleResources.MutableSpriteSet(); - this.spriteSets.put(BuiltInRegistries.PARTICLE_TYPE.getKey(type), spriteSet); - this.providers.put(BuiltInRegistries.PARTICLE_TYPE.getKey(type), provider.create(spriteSet)); - } - - @Override - public CompletableFuture reload( - PreparableReloadListener.SharedState currentReload, - Executor taskExecutor, - PreparableReloadListener.PreparationBarrier preparationBarrier, - Executor reloadExecutor - ) { - ResourceManager manager = currentReload.resourceManager(); - - @OnlyIn(Dist.CLIENT) - record ParticleDefinition(Identifier id, Optional> sprites) { - } - - CompletableFuture> spriteSetsToLoad = CompletableFuture.>supplyAsync( - () -> PARTICLE_LISTER.listMatchingResources(manager), taskExecutor - ) - .thenCompose( - definitionsToScan -> { - List> loadTasks = new ArrayList<>(definitionsToScan.size()); - definitionsToScan.forEach( - (resourceId, resource) -> { - Identifier particleId = PARTICLE_LISTER.fileToId(resourceId); - loadTasks.add( - CompletableFuture.supplyAsync( - () -> new ParticleDefinition(particleId, this.loadParticleDescription(particleId, resource)), taskExecutor - ) - ); - } - ); - return Util.sequence(loadTasks); - } - ); - CompletableFuture pendingSprites = currentReload.get(AtlasManager.PENDING_STITCH).get(AtlasIds.PARTICLES); - return CompletableFuture.allOf(spriteSetsToLoad, pendingSprites).thenCompose(preparationBarrier::wait).thenAcceptAsync(unused -> { - if (this.onReload != null) { - this.onReload.run(); - } - - ProfilerFiller reloadProfiler = Profiler.get(); - reloadProfiler.push("upload"); - SpriteLoader.Preparations sprites = pendingSprites.join(); - reloadProfiler.popPush("bindSpriteSets"); - Set missingSprites = new HashSet<>(); - TextureAtlasSprite missingSprite = sprites.missing(); - spriteSetsToLoad.join().forEach(p -> { - Optional> spriteIds = p.sprites(); - if (!spriteIds.isEmpty()) { - List contents = new ArrayList<>(); - - for (Identifier spriteId : spriteIds.get()) { - TextureAtlasSprite sprite = sprites.getSprite(spriteId); - if (sprite == null) { - missingSprites.add(spriteId); - contents.add(missingSprite); - } else { - contents.add(sprite); - } - } - - if (contents.isEmpty()) { - contents.add(missingSprite); - } - - this.spriteSets.get(p.id()).rebind(contents); - } - }); - if (!missingSprites.isEmpty()) { - LOGGER.warn("Missing particle sprites: {}", missingSprites.stream().sorted().map(Identifier::toString).collect(Collectors.joining(","))); - } - - reloadProfiler.pop(); - }, reloadExecutor); - } - - private Optional> loadParticleDescription(Identifier id, Resource resource) { - if (!this.spriteSets.containsKey(id)) { - LOGGER.debug("Redundant texture list for particle: {}", id); - return Optional.empty(); - } else { - try { - Optional var5; - try (Reader reader = resource.openAsReader()) { - ParticleDescription description = ParticleDescription.fromJson(GsonHelper.parse(reader)); - var5 = Optional.of(description.getTextures()); - } - - return var5; - } catch (IOException var8) { - throw new IllegalStateException("Failed to load description for particle " + id, var8); - } - } - } - - public Map> getProviders() { - return this.providers; - } - - @OnlyIn(Dist.CLIENT) - private static class MutableSpriteSet implements SpriteSet { - private List sprites; - - @Override - public TextureAtlasSprite get(int index, int max) { - return this.sprites.get(index * (this.sprites.size() - 1) / max); - } - - @Override - public TextureAtlasSprite get(RandomSource random) { - return this.sprites.get(random.nextInt(this.sprites.size())); - } - - @Override - public TextureAtlasSprite first() { - return this.sprites.getFirst(); - } - - public void rebind(List ids) { - this.sprites = ImmutableList.copyOf(ids); - } - } - - @FunctionalInterface - @OnlyIn(Dist.CLIENT) - public interface SpriteParticleRegistration { - ParticleProvider create(SpriteSet spriteSet); - } -} diff --git a/net/minecraft/client/particle/QuadParticleGroup.java b/net/minecraft/client/particle/QuadParticleGroup.java deleted file mode 100644 index 6e48c7f1..00000000 --- a/net/minecraft/client/particle/QuadParticleGroup.java +++ /dev/null @@ -1,41 +0,0 @@ -package net.minecraft.client.particle; - -import net.minecraft.CrashReport; -import net.minecraft.CrashReportCategory; -import net.minecraft.ReportedException; -import net.minecraft.client.Camera; -import net.minecraft.client.renderer.culling.Frustum; -import net.minecraft.client.renderer.state.level.ParticleGroupRenderState; -import net.minecraft.client.renderer.state.level.QuadParticleRenderState; -import net.neoforged.api.distmarker.Dist; -import net.neoforged.api.distmarker.OnlyIn; - -@OnlyIn(Dist.CLIENT) -public class QuadParticleGroup extends ParticleGroup { - private final ParticleRenderType particleType; - final QuadParticleRenderState particleTypeRenderState = new QuadParticleRenderState(); - - public QuadParticleGroup(ParticleEngine engine, ParticleRenderType particleType) { - super(engine); - this.particleType = particleType; - } - - @Override - public ParticleGroupRenderState extractRenderState(Frustum frustum, Camera camera, float partialTickTime) { - for (SingleQuadParticle particle : this.particles) { - if (frustum.pointInFrustum(particle.x, particle.y, particle.z)) { - try { - particle.extract(this.particleTypeRenderState, camera, partialTickTime); - } catch (Throwable var9) { - CrashReport report = CrashReport.forThrowable(var9, "Rendering Particle"); - CrashReportCategory category = report.addCategory("Particle being rendered"); - category.setDetail("Particle", particle::toString); - category.setDetail("Particle Type", this.particleType::toString); - throw new ReportedException(report); - } - } - } - - return this.particleTypeRenderState; - } -} diff --git a/net/minecraft/client/particle/SingleQuadParticle.java b/net/minecraft/client/particle/SingleQuadParticle.java deleted file mode 100644 index 91f3db5c..00000000 --- a/net/minecraft/client/particle/SingleQuadParticle.java +++ /dev/null @@ -1,197 +0,0 @@ -package net.minecraft.client.particle; - -import com.mojang.blaze3d.pipeline.RenderPipeline; -import net.minecraft.client.Camera; -import net.minecraft.client.multiplayer.ClientLevel; -import net.minecraft.client.renderer.RenderPipelines; -import net.minecraft.client.renderer.state.level.QuadParticleRenderState; -import net.minecraft.client.renderer.texture.TextureAtlas; -import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraft.resources.Identifier; -import net.minecraft.util.ARGB; -import net.minecraft.util.Mth; -import net.minecraft.world.phys.Vec3; -import net.neoforged.api.distmarker.Dist; -import net.neoforged.api.distmarker.OnlyIn; -import org.joml.Quaternionf; - -@OnlyIn(Dist.CLIENT) -public abstract class SingleQuadParticle extends Particle { - protected float quadSize; - protected float rCol = 1.0F; - protected float gCol = 1.0F; - protected float bCol = 1.0F; - protected float alpha = 1.0F; - protected float roll; - protected float oRoll; - protected TextureAtlasSprite sprite; - - public SingleQuadParticle(ClientLevel level, double x, double y, double z, TextureAtlasSprite sprite) { - super(level, x, y, z); - this.sprite = sprite; - this.quadSize = 0.1F * (this.random.nextFloat() * 0.5F + 0.5F) * 2.0F; - } - - public SingleQuadParticle(ClientLevel level, double x, double y, double z, double xa, double ya, double za, TextureAtlasSprite sprite) { - super(level, x, y, z, xa, ya, za); - this.sprite = sprite; - this.quadSize = 0.1F * (this.random.nextFloat() * 0.5F + 0.5F) * 2.0F; - } - - public SingleQuadParticle.FacingCameraMode getFacingCameraMode() { - return SingleQuadParticle.FacingCameraMode.LOOKAT_XYZ; - } - - public void extract(QuadParticleRenderState particleTypeRenderState, Camera camera, float partialTickTime) { - Quaternionf rotation = new Quaternionf(); - this.getFacingCameraMode().setRotation(rotation, camera, partialTickTime); - if (this.roll != 0.0F) { - rotation.rotateZ(Mth.lerp(partialTickTime, this.oRoll, this.roll)); - } - - this.extractRotatedQuad(particleTypeRenderState, camera, rotation, partialTickTime); - } - - protected void extractRotatedQuad(QuadParticleRenderState particleTypeRenderState, Camera camera, Quaternionf rotation, float partialTickTime) { - Vec3 pos = camera.position(); - float x = (float)(Mth.lerp((double)partialTickTime, this.xo, this.x) - pos.x()); - float y = (float)(Mth.lerp((double)partialTickTime, this.yo, this.y) - pos.y()); - float z = (float)(Mth.lerp((double)partialTickTime, this.zo, this.z) - pos.z()); - this.extractRotatedQuad(particleTypeRenderState, rotation, x, y, z, partialTickTime); - } - - protected void extractRotatedQuad(QuadParticleRenderState particleTypeRenderState, Quaternionf rotation, float x, float y, float z, float partialTickTime) { - particleTypeRenderState.add( - this.getLayer(), - x, - y, - z, - rotation.x, - rotation.y, - rotation.z, - rotation.w, - this.getQuadSize(partialTickTime), - this.getU0(), - this.getU1(), - this.getV0(), - this.getV1(), - ARGB.colorFromFloat(this.alpha, this.rCol, this.gCol, this.bCol), - this.getLightCoords(partialTickTime) - ); - } - - public float getQuadSize(float a) { - return this.quadSize; - } - - @Override - public Particle scale(float scale) { - this.quadSize *= scale; - return super.scale(scale); - } - - @Override - public ParticleRenderType getGroup() { - return ParticleRenderType.SINGLE_QUADS; - } - - public void setSpriteFromAge(SpriteSet sprites) { - if (!this.removed) { - this.setSprite(sprites.get(this.age, this.lifetime)); - } - } - - protected void setSprite(TextureAtlasSprite icon) { - this.sprite = icon; - } - - protected float getU0() { - return this.sprite.getU0(); - } - - protected float getU1() { - return this.sprite.getU1(); - } - - protected float getV0() { - return this.sprite.getV0(); - } - - protected float getV1() { - return this.sprite.getV1(); - } - - protected abstract SingleQuadParticle.Layer getLayer(); - - public void setColor(float r, float g, float b) { - this.rCol = r; - this.gCol = g; - this.bCol = b; - } - - protected void setAlpha(float alpha) { - this.alpha = alpha; - } - - @Override - public String toString() { - return this.getClass().getSimpleName() - + ", Pos (" - + this.x - + "," - + this.y - + "," - + this.z - + "), RGBA (" - + this.rCol - + "," - + this.gCol - + "," - + this.bCol - + "," - + this.alpha - + "), Age " - + this.age; - } - - @OnlyIn(Dist.CLIENT) - public interface FacingCameraMode { - SingleQuadParticle.FacingCameraMode LOOKAT_XYZ = (target, camera, partialTickTime) -> target.set(camera.rotation()); - SingleQuadParticle.FacingCameraMode LOOKAT_Y = (target, camera, partialTickTime) -> target.set(0.0F, camera.rotation().y, 0.0F, camera.rotation().w); - - void setRotation(final Quaternionf target, final Camera camera, final float partialTickTime); - } - - @OnlyIn(Dist.CLIENT) - public record Layer(boolean translucent, Identifier textureAtlasLocation, RenderPipeline pipeline) { - public static final SingleQuadParticle.Layer OPAQUE_TERRAIN = new SingleQuadParticle.Layer( - false, TextureAtlas.LOCATION_BLOCKS, RenderPipelines.OPAQUE_PARTICLE - ); - public static final SingleQuadParticle.Layer TRANSLUCENT_TERRAIN = new SingleQuadParticle.Layer( - true, TextureAtlas.LOCATION_BLOCKS, RenderPipelines.TRANSLUCENT_PARTICLE - ); - public static final SingleQuadParticle.Layer OPAQUE_ITEMS = new SingleQuadParticle.Layer( - false, TextureAtlas.LOCATION_ITEMS, RenderPipelines.OPAQUE_PARTICLE - ); - public static final SingleQuadParticle.Layer TRANSLUCENT_ITEMS = new SingleQuadParticle.Layer( - true, TextureAtlas.LOCATION_ITEMS, RenderPipelines.TRANSLUCENT_PARTICLE - ); - public static final SingleQuadParticle.Layer OPAQUE = new SingleQuadParticle.Layer( - false, TextureAtlas.LOCATION_PARTICLES, RenderPipelines.OPAQUE_PARTICLE - ); - public static final SingleQuadParticle.Layer TRANSLUCENT = new SingleQuadParticle.Layer( - true, TextureAtlas.LOCATION_PARTICLES, RenderPipelines.TRANSLUCENT_PARTICLE - ); - - public static SingleQuadParticle.Layer bySprite(TextureAtlasSprite sprite) { - boolean translucent = sprite.transparency().hasTranslucent(); - if (sprite.atlasLocation().equals(TextureAtlas.LOCATION_BLOCKS)) { - return translucent ? TRANSLUCENT_TERRAIN : OPAQUE_TERRAIN; - } else if (sprite.atlasLocation().equals(TextureAtlas.LOCATION_ITEMS)) { - return translucent ? TRANSLUCENT_ITEMS : OPAQUE_ITEMS; - } else { - return translucent ? TRANSLUCENT : OPAQUE; - } - } - } -} diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java deleted file mode 100644 index db8fc58c..00000000 --- a/net/minecraft/world/level/Level.java +++ /dev/null @@ -1,1122 +0,0 @@ -package net.minecraft.world.level; - -import com.google.common.collect.Lists; -import com.mojang.serialization.Codec; -import java.io.IOException; -import java.util.Iterator; -import java.util.List; -import java.util.function.Consumer; -import java.util.function.Predicate; -import java.util.function.Supplier; -import javax.annotation.Nullable; -import net.minecraft.CrashReport; -import net.minecraft.CrashReportCategory; -import net.minecraft.ReportedException; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.core.Holder; -import net.minecraft.core.RegistryAccess; -import net.minecraft.core.SectionPos; -import net.minecraft.core.particles.ParticleOptions; -import net.minecraft.core.particles.ParticleTypes; -import net.minecraft.core.registries.BuiltInRegistries; -import net.minecraft.core.registries.Registries; -import net.minecraft.network.protocol.Packet; -import net.minecraft.resources.ResourceKey; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.level.FullChunkStatus; -import net.minecraft.sounds.SoundEvent; -import net.minecraft.sounds.SoundEvents; -import net.minecraft.sounds.SoundSource; -import net.minecraft.util.AbortableIterationConsumer; -import net.minecraft.util.Mth; -import net.minecraft.util.RandomSource; -import net.minecraft.util.StringRepresentable; -import net.minecraft.util.profiling.ProfilerFiller; -import net.minecraft.world.DifficultyInstance; -import net.minecraft.world.TickRateManager; -import net.minecraft.world.damagesource.DamageSource; -import net.minecraft.world.damagesource.DamageSources; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.boss.EnderDragonPart; -import net.minecraft.world.entity.boss.enderdragon.EnderDragon; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.alchemy.PotionBrewing; -import net.minecraft.world.item.component.FireworkExplosion; -import net.minecraft.world.item.crafting.RecipeManager; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.biome.BiomeManager; -import net.minecraft.world.level.block.BaseFireBlock; -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.entity.TickingBlockEntity; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.border.WorldBorder; -import net.minecraft.world.level.chunk.ChunkAccess; -import net.minecraft.world.level.chunk.LevelChunk; -import net.minecraft.world.level.chunk.status.ChunkStatus; -import net.minecraft.world.level.dimension.DimensionType; -import net.minecraft.world.level.entity.EntityTypeTest; -import net.minecraft.world.level.entity.LevelEntityGetter; -import net.minecraft.world.level.gameevent.GameEvent; -import net.minecraft.world.level.levelgen.Heightmap; -import net.minecraft.world.level.lighting.LevelLightEngine; -import net.minecraft.world.level.material.FluidState; -import net.minecraft.world.level.material.Fluids; -import net.minecraft.world.level.redstone.CollectingNeighborUpdater; -import net.minecraft.world.level.redstone.NeighborUpdater; -import net.minecraft.world.level.saveddata.maps.MapId; -import net.minecraft.world.level.saveddata.maps.MapItemSavedData; -import net.minecraft.world.level.storage.LevelData; -import net.minecraft.world.level.storage.WritableLevelData; -import net.minecraft.world.phys.AABB; -import net.minecraft.world.phys.Vec3; -import net.minecraft.world.scores.Scoreboard; - -public abstract class Level implements LevelAccessor, AutoCloseable { - public static final Codec> RESOURCE_KEY_CODEC = ResourceKey.codec(Registries.DIMENSION); - public static final ResourceKey OVERWORLD = ResourceKey.create(Registries.DIMENSION, ResourceLocation.withDefaultNamespace("overworld")); - public static final ResourceKey NETHER = ResourceKey.create(Registries.DIMENSION, ResourceLocation.withDefaultNamespace("the_nether")); - public static final ResourceKey END = ResourceKey.create(Registries.DIMENSION, ResourceLocation.withDefaultNamespace("the_end")); - public static final int MAX_LEVEL_SIZE = 30000000; - public static final int LONG_PARTICLE_CLIP_RANGE = 512; - public static final int SHORT_PARTICLE_CLIP_RANGE = 32; - public static final int MAX_BRIGHTNESS = 15; - public static final int TICKS_PER_DAY = 24000; - public static final int MAX_ENTITY_SPAWN_Y = 20000000; - public static final int MIN_ENTITY_SPAWN_Y = -20000000; - protected final List blockEntityTickers = Lists.newArrayList(); - protected final NeighborUpdater neighborUpdater; - private final List pendingBlockEntityTickers = Lists.newArrayList(); - private boolean tickingBlockEntities; - private final Thread thread; - private final boolean isDebug; - private int skyDarken; - protected int randValue = RandomSource.create().nextInt(); - protected final int addend = 1013904223; - protected float oRainLevel; - protected float rainLevel; - protected float oThunderLevel; - protected float thunderLevel; - public final RandomSource random = RandomSource.create(); - @Deprecated - private final RandomSource threadSafeRandom = RandomSource.createThreadSafe(); - private final Holder dimensionTypeRegistration; - protected final WritableLevelData levelData; - private final Supplier profiler; - public final boolean isClientSide; - private final WorldBorder worldBorder; - private final BiomeManager biomeManager; - private final ResourceKey dimension; - private final RegistryAccess registryAccess; - private final DamageSources damageSources; - private long subTickCount; - - protected Level( - WritableLevelData p_270739_, - ResourceKey p_270683_, - RegistryAccess p_270200_, - Holder p_270240_, - Supplier p_270692_, - boolean p_270904_, - boolean p_270470_, - long p_270248_, - int p_270466_ - ) { - this.profiler = p_270692_; - this.levelData = p_270739_; - this.dimensionTypeRegistration = p_270240_; - final DimensionType dimensiontype = p_270240_.value(); - this.dimension = p_270683_; - this.isClientSide = p_270904_; - if (dimensiontype.coordinateScale() != 1.0) { - this.worldBorder = new WorldBorder() { - @Override - public double getCenterX() { - return super.getCenterX() / dimensiontype.coordinateScale(); - } - - @Override - public double getCenterZ() { - return super.getCenterZ() / dimensiontype.coordinateScale(); - } - }; - } else { - this.worldBorder = new WorldBorder(); - } - - this.thread = Thread.currentThread(); - this.biomeManager = new BiomeManager(this, p_270248_); - this.isDebug = p_270470_; - this.neighborUpdater = new CollectingNeighborUpdater(this, p_270466_); - this.registryAccess = p_270200_; - this.damageSources = new DamageSources(p_270200_); - } - - @Override - public boolean isClientSide() { - return this.isClientSide; - } - - @Nullable - @Override - public MinecraftServer getServer() { - return null; - } - - public boolean isInWorldBounds(BlockPos p_46740_) { - return !this.isOutsideBuildHeight(p_46740_) && isInWorldBoundsHorizontal(p_46740_); - } - - public static boolean isInSpawnableBounds(BlockPos p_46742_) { - return !isOutsideSpawnableHeight(p_46742_.getY()) && isInWorldBoundsHorizontal(p_46742_); - } - - private static boolean isInWorldBoundsHorizontal(BlockPos p_46458_) { - return p_46458_.getX() >= -30000000 && p_46458_.getZ() >= -30000000 && p_46458_.getX() < 30000000 && p_46458_.getZ() < 30000000; - } - - private static boolean isOutsideSpawnableHeight(int p_46725_) { - return p_46725_ < -20000000 || p_46725_ >= 20000000; - } - - public LevelChunk getChunkAt(BlockPos p_46746_) { - return this.getChunk(SectionPos.blockToSectionCoord(p_46746_.getX()), SectionPos.blockToSectionCoord(p_46746_.getZ())); - } - - public LevelChunk getChunk(int p_46727_, int p_46728_) { - return (LevelChunk)this.getChunk(p_46727_, p_46728_, ChunkStatus.FULL); - } - - @Nullable - @Override - public ChunkAccess getChunk(int p_46502_, int p_46503_, ChunkStatus p_331611_, boolean p_46505_) { - ChunkAccess chunkaccess = this.getChunkSource().getChunk(p_46502_, p_46503_, p_331611_, p_46505_); - if (chunkaccess == null && p_46505_) { - throw new IllegalStateException("Should always be able to create a chunk!"); - } else { - return chunkaccess; - } - } - - @Override - public boolean setBlock(BlockPos p_46601_, BlockState p_46602_, int p_46603_) { - return this.setBlock(p_46601_, p_46602_, p_46603_, 512); - } - - @Override - public boolean setBlock(BlockPos p_46605_, BlockState p_46606_, int p_46607_, int p_46608_) { - if (this.isOutsideBuildHeight(p_46605_)) { - return false; - } else if (!this.isClientSide && this.isDebug()) { - return false; - } else { - LevelChunk levelchunk = this.getChunkAt(p_46605_); - Block block = p_46606_.getBlock(); - BlockState blockstate = levelchunk.setBlockState(p_46605_, p_46606_, (p_46607_ & 64) != 0); - if (blockstate == null) { - return false; - } else { - BlockState blockstate1 = this.getBlockState(p_46605_); - if (blockstate1 == p_46606_) { - if (blockstate != blockstate1) { - this.setBlocksDirty(p_46605_, blockstate, blockstate1); - } - - if ((p_46607_ & 2) != 0 - && (!this.isClientSide || (p_46607_ & 4) == 0) - && (this.isClientSide || levelchunk.getFullStatus() != null && levelchunk.getFullStatus().isOrAfter(FullChunkStatus.BLOCK_TICKING))) { - this.sendBlockUpdated(p_46605_, blockstate, p_46606_, p_46607_); - } - - if ((p_46607_ & 1) != 0) { - this.blockUpdated(p_46605_, blockstate.getBlock()); - if (!this.isClientSide && p_46606_.hasAnalogOutputSignal()) { - this.updateNeighbourForOutputSignal(p_46605_, block); - } - } - - if ((p_46607_ & 16) == 0 && p_46608_ > 0) { - int i = p_46607_ & -34; - blockstate.updateIndirectNeighbourShapes(this, p_46605_, i, p_46608_ - 1); - p_46606_.updateNeighbourShapes(this, p_46605_, i, p_46608_ - 1); - p_46606_.updateIndirectNeighbourShapes(this, p_46605_, i, p_46608_ - 1); - } - - this.onBlockStateChange(p_46605_, blockstate, blockstate1); - } - - return true; - } - } - } - - public void onBlockStateChange(BlockPos p_46609_, BlockState p_46610_, BlockState p_46611_) { - } - - @Override - public boolean removeBlock(BlockPos p_46623_, boolean p_46624_) { - FluidState fluidstate = this.getFluidState(p_46623_); - return this.setBlock(p_46623_, fluidstate.createLegacyBlock(), 3 | (p_46624_ ? 64 : 0)); - } - - @Override - public boolean destroyBlock(BlockPos p_46626_, boolean p_46627_, @Nullable Entity p_46628_, int p_46629_) { - BlockState blockstate = this.getBlockState(p_46626_); - if (blockstate.isAir()) { - return false; - } else { - FluidState fluidstate = this.getFluidState(p_46626_); - if (!(blockstate.getBlock() instanceof BaseFireBlock)) { - this.levelEvent(2001, p_46626_, Block.getId(blockstate)); - } - - if (p_46627_) { - BlockEntity blockentity = blockstate.hasBlockEntity() ? this.getBlockEntity(p_46626_) : null; - Block.dropResources(blockstate, this, p_46626_, blockentity, p_46628_, ItemStack.EMPTY); - } - - boolean flag = this.setBlock(p_46626_, fluidstate.createLegacyBlock(), 3, p_46629_); - if (flag) { - this.gameEvent(GameEvent.BLOCK_DESTROY, p_46626_, GameEvent.Context.of(p_46628_, blockstate)); - } - - return flag; - } - } - - public void addDestroyBlockEffect(BlockPos p_151531_, BlockState p_151532_) { - } - - public boolean setBlockAndUpdate(BlockPos p_46598_, BlockState p_46599_) { - return this.setBlock(p_46598_, p_46599_, 3); - } - - public abstract void sendBlockUpdated(BlockPos p_46612_, BlockState p_46613_, BlockState p_46614_, int p_46615_); - - public void setBlocksDirty(BlockPos p_46678_, BlockState p_46679_, BlockState p_46680_) { - } - - public void updateNeighborsAt(BlockPos p_46673_, Block p_46674_) { - } - - public void updateNeighborsAtExceptFromFacing(BlockPos p_46591_, Block p_46592_, Direction p_46593_) { - } - - public void neighborChanged(BlockPos p_46587_, Block p_46588_, BlockPos p_46589_) { - } - - public void neighborChanged(BlockState p_220379_, BlockPos p_220380_, Block p_220381_, BlockPos p_220382_, boolean p_220383_) { - } - - @Override - public void neighborShapeChanged(Direction p_220385_, BlockState p_220386_, BlockPos p_220387_, BlockPos p_220388_, int p_220389_, int p_220390_) { - this.neighborUpdater.shapeUpdate(p_220385_, p_220386_, p_220387_, p_220388_, p_220389_, p_220390_); - } - - @Override - public int getHeight(Heightmap.Types p_46571_, int p_46572_, int p_46573_) { - int i; - if (p_46572_ >= -30000000 && p_46573_ >= -30000000 && p_46572_ < 30000000 && p_46573_ < 30000000) { - if (this.hasChunk(SectionPos.blockToSectionCoord(p_46572_), SectionPos.blockToSectionCoord(p_46573_))) { - i = this.getChunk(SectionPos.blockToSectionCoord(p_46572_), SectionPos.blockToSectionCoord(p_46573_)) - .getHeight(p_46571_, p_46572_ & 15, p_46573_ & 15) - + 1; - } else { - i = this.getMinBuildHeight(); - } - } else { - i = this.getSeaLevel() + 1; - } - - return i; - } - - @Override - public LevelLightEngine getLightEngine() { - return this.getChunkSource().getLightEngine(); - } - - @Override - public BlockState getBlockState(BlockPos p_46732_) { - if (this.isOutsideBuildHeight(p_46732_)) { - return Blocks.VOID_AIR.defaultBlockState(); - } else { - LevelChunk levelchunk = this.getChunk(SectionPos.blockToSectionCoord(p_46732_.getX()), SectionPos.blockToSectionCoord(p_46732_.getZ())); - return levelchunk.getBlockState(p_46732_); - } - } - - @Override - public FluidState getFluidState(BlockPos p_46671_) { - if (this.isOutsideBuildHeight(p_46671_)) { - return Fluids.EMPTY.defaultFluidState(); - } else { - LevelChunk levelchunk = this.getChunkAt(p_46671_); - return levelchunk.getFluidState(p_46671_); - } - } - - public boolean isDay() { - return !this.dimensionType().hasFixedTime() && this.skyDarken < 4; - } - - public boolean isNight() { - return !this.dimensionType().hasFixedTime() && !this.isDay(); - } - - public void playSound(@Nullable Entity p_252137_, BlockPos p_251749_, SoundEvent p_248842_, SoundSource p_251104_, float p_249531_, float p_250763_) { - this.playSound(p_252137_ instanceof Player player ? player : null, p_251749_, p_248842_, p_251104_, p_249531_, p_250763_); - } - - @Override - public void playSound(@Nullable Player p_46560_, BlockPos p_46561_, SoundEvent p_46562_, SoundSource p_46563_, float p_46564_, float p_46565_) { - this.playSound( - p_46560_, (double)p_46561_.getX() + 0.5, (double)p_46561_.getY() + 0.5, (double)p_46561_.getZ() + 0.5, p_46562_, p_46563_, p_46564_, p_46565_ - ); - } - - public abstract void playSeededSound( - @Nullable Player p_262953_, - double p_263004_, - double p_263398_, - double p_263376_, - Holder p_263359_, - SoundSource p_263020_, - float p_263055_, - float p_262914_, - long p_262991_ - ); - - public void playSeededSound( - @Nullable Player p_220363_, - double p_220364_, - double p_220365_, - double p_220366_, - SoundEvent p_220367_, - SoundSource p_220368_, - float p_220369_, - float p_220370_, - long p_220371_ - ) { - this.playSeededSound( - p_220363_, p_220364_, p_220365_, p_220366_, BuiltInRegistries.SOUND_EVENT.wrapAsHolder(p_220367_), p_220368_, p_220369_, p_220370_, p_220371_ - ); - } - - public abstract void playSeededSound( - @Nullable Player p_220372_, Entity p_220373_, Holder p_263500_, SoundSource p_220375_, float p_220376_, float p_220377_, long p_220378_ - ); - - public void playSound(@Nullable Player p_309201_, double p_308925_, double p_309072_, double p_308916_, SoundEvent p_308917_, SoundSource p_308902_) { - this.playSound(p_309201_, p_308925_, p_309072_, p_308916_, p_308917_, p_308902_, 1.0F, 1.0F); - } - - public void playSound( - @Nullable Player p_46543_, double p_46544_, double p_46545_, double p_46546_, SoundEvent p_46547_, SoundSource p_46548_, float p_46549_, float p_46550_ - ) { - this.playSeededSound(p_46543_, p_46544_, p_46545_, p_46546_, p_46547_, p_46548_, p_46549_, p_46550_, this.threadSafeRandom.nextLong()); - } - - public void playSound( - @Nullable Player p_347719_, - double p_347460_, - double p_347457_, - double p_347558_, - Holder p_347499_, - SoundSource p_347522_, - float p_347447_, - float p_347667_ - ) { - this.playSeededSound(p_347719_, p_347460_, p_347457_, p_347558_, p_347499_, p_347522_, p_347447_, p_347667_, this.threadSafeRandom.nextLong()); - } - - public void playSound(@Nullable Player p_46551_, Entity p_46552_, SoundEvent p_46553_, SoundSource p_46554_, float p_46555_, float p_46556_) { - this.playSeededSound( - p_46551_, p_46552_, BuiltInRegistries.SOUND_EVENT.wrapAsHolder(p_46553_), p_46554_, p_46555_, p_46556_, this.threadSafeRandom.nextLong() - ); - } - - public void playLocalSound(BlockPos p_250938_, SoundEvent p_252209_, SoundSource p_249161_, float p_249980_, float p_250277_, boolean p_250151_) { - this.playLocalSound( - (double)p_250938_.getX() + 0.5, - (double)p_250938_.getY() + 0.5, - (double)p_250938_.getZ() + 0.5, - p_252209_, - p_249161_, - p_249980_, - p_250277_, - p_250151_ - ); - } - - public void playLocalSound(Entity p_312189_, SoundEvent p_312080_, SoundSource p_312905_, float p_312914_, float p_312831_) { - } - - public void playLocalSound( - double p_46482_, double p_46483_, double p_46484_, SoundEvent p_46485_, SoundSource p_46486_, float p_46487_, float p_46488_, boolean p_46489_ - ) { - } - - @Override - public void addParticle(ParticleOptions p_46631_, double p_46632_, double p_46633_, double p_46634_, double p_46635_, double p_46636_, double p_46637_) { - } - - public void addParticle( - ParticleOptions p_46638_, boolean p_46639_, double p_46640_, double p_46641_, double p_46642_, double p_46643_, double p_46644_, double p_46645_ - ) { - } - - public void addAlwaysVisibleParticle( - ParticleOptions p_46684_, double p_46685_, double p_46686_, double p_46687_, double p_46688_, double p_46689_, double p_46690_ - ) { - } - - public void addAlwaysVisibleParticle( - ParticleOptions p_46691_, boolean p_46692_, double p_46693_, double p_46694_, double p_46695_, double p_46696_, double p_46697_, double p_46698_ - ) { - } - - public float getSunAngle(float p_46491_) { - float f = this.getTimeOfDay(p_46491_); - return f * (float) (Math.PI * 2); - } - - public void addBlockEntityTicker(TickingBlockEntity p_151526_) { - (this.tickingBlockEntities ? this.pendingBlockEntityTickers : this.blockEntityTickers).add(p_151526_); - } - - protected void tickBlockEntities() { - ProfilerFiller profilerfiller = this.getProfiler(); - profilerfiller.push("blockEntities"); - this.tickingBlockEntities = true; - if (!this.pendingBlockEntityTickers.isEmpty()) { - this.blockEntityTickers.addAll(this.pendingBlockEntityTickers); - this.pendingBlockEntityTickers.clear(); - } - - Iterator iterator = this.blockEntityTickers.iterator(); - boolean flag = this.tickRateManager().runsNormally(); - - while (iterator.hasNext()) { - TickingBlockEntity tickingblockentity = iterator.next(); - if (tickingblockentity.isRemoved()) { - iterator.remove(); - } else if (flag && this.shouldTickBlocksAt(tickingblockentity.getPos())) { - tickingblockentity.tick(); - } - } - - this.tickingBlockEntities = false; - profilerfiller.pop(); - } - - public void guardEntityTick(Consumer p_46654_, T p_46655_) { - try { - p_46654_.accept(p_46655_); - } catch (Throwable throwable) { - CrashReport crashreport = CrashReport.forThrowable(throwable, "Ticking entity"); - CrashReportCategory crashreportcategory = crashreport.addCategory("Entity being ticked"); - p_46655_.fillCrashReportCategory(crashreportcategory); - throw new ReportedException(crashreport); - } - } - - public boolean shouldTickDeath(Entity p_186458_) { - return true; - } - - public boolean shouldTickBlocksAt(long p_186456_) { - return true; - } - - public boolean shouldTickBlocksAt(BlockPos p_220394_) { - return this.shouldTickBlocksAt(ChunkPos.asLong(p_220394_)); - } - - public Explosion explode( - @Nullable Entity p_256599_, double p_255914_, double p_255684_, double p_255843_, float p_256310_, Level.ExplosionInteraction p_256178_ - ) { - return this.explode( - p_256599_, - Explosion.getDefaultDamageSource(this, p_256599_), - null, - p_255914_, - p_255684_, - p_255843_, - p_256310_, - false, - p_256178_, - ParticleTypes.EXPLOSION, - ParticleTypes.EXPLOSION_EMITTER, - SoundEvents.GENERIC_EXPLODE - ); - } - - public Explosion explode( - @Nullable Entity p_255682_, - double p_255803_, - double p_256403_, - double p_256538_, - float p_255674_, - boolean p_256634_, - Level.ExplosionInteraction p_256111_ - ) { - return this.explode( - p_255682_, - Explosion.getDefaultDamageSource(this, p_255682_), - null, - p_255803_, - p_256403_, - p_256538_, - p_255674_, - p_256634_, - p_256111_, - ParticleTypes.EXPLOSION, - ParticleTypes.EXPLOSION_EMITTER, - SoundEvents.GENERIC_EXPLODE - ); - } - - public Explosion explode( - @Nullable Entity p_255653_, - @Nullable DamageSource p_256558_, - @Nullable ExplosionDamageCalculator p_255929_, - Vec3 p_256001_, - float p_255963_, - boolean p_256099_, - Level.ExplosionInteraction p_256371_ - ) { - return this.explode( - p_255653_, - p_256558_, - p_255929_, - p_256001_.x(), - p_256001_.y(), - p_256001_.z(), - p_255963_, - p_256099_, - p_256371_, - ParticleTypes.EXPLOSION, - ParticleTypes.EXPLOSION_EMITTER, - SoundEvents.GENERIC_EXPLODE - ); - } - - public Explosion explode( - @Nullable Entity p_256145_, - @Nullable DamageSource p_256004_, - @Nullable ExplosionDamageCalculator p_255696_, - double p_256208_, - double p_256036_, - double p_255746_, - float p_256647_, - boolean p_256098_, - Level.ExplosionInteraction p_256104_ - ) { - return this.explode( - p_256145_, - p_256004_, - p_255696_, - p_256208_, - p_256036_, - p_255746_, - p_256647_, - p_256098_, - p_256104_, - ParticleTypes.EXPLOSION, - ParticleTypes.EXPLOSION_EMITTER, - SoundEvents.GENERIC_EXPLODE - ); - } - - public Explosion explode( - @Nullable Entity p_256233_, - @Nullable DamageSource p_255861_, - @Nullable ExplosionDamageCalculator p_255867_, - double p_256447_, - double p_255732_, - double p_255717_, - float p_256013_, - boolean p_256228_, - Level.ExplosionInteraction p_255784_, - ParticleOptions p_311886_, - ParticleOptions p_311887_, - Holder p_320084_ - ) { - return this.explode( - p_256233_, p_255861_, p_255867_, p_256447_, p_255732_, p_255717_, p_256013_, p_256228_, p_255784_, true, p_311886_, p_311887_, p_320084_ - ); - } - - public Explosion explode( - @Nullable Entity p_311934_, - @Nullable DamageSource p_312790_, - @Nullable ExplosionDamageCalculator p_311975_, - double p_312493_, - double p_312456_, - double p_312719_, - float p_312292_, - boolean p_312144_, - Level.ExplosionInteraction p_312265_, - boolean p_312145_, - ParticleOptions p_312842_, - ParticleOptions p_312060_, - Holder p_320283_ - ) { - Explosion.BlockInteraction explosion$blockinteraction = switch (p_312265_) { - case NONE -> Explosion.BlockInteraction.KEEP; - case BLOCK -> this.getDestroyType(GameRules.RULE_BLOCK_EXPLOSION_DROP_DECAY); - case MOB -> this.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) - ? this.getDestroyType(GameRules.RULE_MOB_EXPLOSION_DROP_DECAY) - : Explosion.BlockInteraction.KEEP; - case TNT -> this.getDestroyType(GameRules.RULE_TNT_EXPLOSION_DROP_DECAY); - case TRIGGER -> Explosion.BlockInteraction.TRIGGER_BLOCK; - }; - Explosion explosion = new Explosion( - this, - p_311934_, - p_312790_, - p_311975_, - p_312493_, - p_312456_, - p_312719_, - p_312292_, - p_312144_, - explosion$blockinteraction, - p_312842_, - p_312060_, - p_320283_ - ); - explosion.explode(); - explosion.finalizeExplosion(p_312145_); - return explosion; - } - - private Explosion.BlockInteraction getDestroyType(GameRules.Key p_256250_) { - return this.getGameRules().getBoolean(p_256250_) ? Explosion.BlockInteraction.DESTROY_WITH_DECAY : Explosion.BlockInteraction.DESTROY; - } - - public abstract String gatherChunkSourceStats(); - - @Nullable - @Override - public BlockEntity getBlockEntity(BlockPos p_46716_) { - if (this.isOutsideBuildHeight(p_46716_)) { - return null; - } else { - return !this.isClientSide && Thread.currentThread() != this.thread - ? null - : this.getChunkAt(p_46716_).getBlockEntity(p_46716_, LevelChunk.EntityCreationType.IMMEDIATE); - } - } - - public void setBlockEntity(BlockEntity p_151524_) { - BlockPos blockpos = p_151524_.getBlockPos(); - if (!this.isOutsideBuildHeight(blockpos)) { - this.getChunkAt(blockpos).addAndRegisterBlockEntity(p_151524_); - } - } - - public void removeBlockEntity(BlockPos p_46748_) { - if (!this.isOutsideBuildHeight(p_46748_)) { - this.getChunkAt(p_46748_).removeBlockEntity(p_46748_); - } - } - - public boolean isLoaded(BlockPos p_46750_) { - return this.isOutsideBuildHeight(p_46750_) - ? false - : this.getChunkSource().hasChunk(SectionPos.blockToSectionCoord(p_46750_.getX()), SectionPos.blockToSectionCoord(p_46750_.getZ())); - } - - public boolean loadedAndEntityCanStandOnFace(BlockPos p_46579_, Entity p_46580_, Direction p_46581_) { - if (this.isOutsideBuildHeight(p_46579_)) { - return false; - } else { - ChunkAccess chunkaccess = this.getChunk( - SectionPos.blockToSectionCoord(p_46579_.getX()), SectionPos.blockToSectionCoord(p_46579_.getZ()), ChunkStatus.FULL, false - ); - return chunkaccess == null ? false : chunkaccess.getBlockState(p_46579_).entityCanStandOnFace(this, p_46579_, p_46580_, p_46581_); - } - } - - public boolean loadedAndEntityCanStandOn(BlockPos p_46576_, Entity p_46577_) { - return this.loadedAndEntityCanStandOnFace(p_46576_, p_46577_, Direction.UP); - } - - public void updateSkyBrightness() { - double d0 = 1.0 - (double)(this.getRainLevel(1.0F) * 5.0F) / 16.0; - double d1 = 1.0 - (double)(this.getThunderLevel(1.0F) * 5.0F) / 16.0; - double d2 = 0.5 + 2.0 * Mth.clamp((double)Mth.cos(this.getTimeOfDay(1.0F) * (float) (Math.PI * 2)), -0.25, 0.25); - this.skyDarken = (int)((1.0 - d2 * d0 * d1) * 11.0); - } - - public void setSpawnSettings(boolean p_46704_, boolean p_46705_) { - this.getChunkSource().setSpawnSettings(p_46704_, p_46705_); - } - - public BlockPos getSharedSpawnPos() { - BlockPos blockpos = this.levelData.getSpawnPos(); - if (!this.getWorldBorder().isWithinBounds(blockpos)) { - blockpos = this.getHeightmapPos( - Heightmap.Types.MOTION_BLOCKING, BlockPos.containing(this.getWorldBorder().getCenterX(), 0.0, this.getWorldBorder().getCenterZ()) - ); - } - - return blockpos; - } - - public float getSharedSpawnAngle() { - return this.levelData.getSpawnAngle(); - } - - protected void prepareWeather() { - if (this.levelData.isRaining()) { - this.rainLevel = 1.0F; - if (this.levelData.isThundering()) { - this.thunderLevel = 1.0F; - } - } - } - - @Override - public void close() throws IOException { - this.getChunkSource().close(); - } - - @Nullable - @Override - public BlockGetter getChunkForCollisions(int p_46711_, int p_46712_) { - return this.getChunk(p_46711_, p_46712_, ChunkStatus.FULL, false); - } - - @Override - public List getEntities(@Nullable Entity p_46536_, AABB p_46537_, Predicate p_46538_) { - this.getProfiler().incrementCounter("getEntities"); - List list = Lists.newArrayList(); - this.getEntities().get(p_46537_, p_151522_ -> { - if (p_151522_ != p_46536_ && p_46538_.test(p_151522_)) { - list.add(p_151522_); - } - - if (p_151522_ instanceof EnderDragon) { - for (EnderDragonPart enderdragonpart : ((EnderDragon)p_151522_).getSubEntities()) { - if (p_151522_ != p_46536_ && p_46538_.test(enderdragonpart)) { - list.add(enderdragonpart); - } - } - } - }); - return list; - } - - @Override - public List getEntities(EntityTypeTest p_151528_, AABB p_151529_, Predicate p_151530_) { - List list = Lists.newArrayList(); - this.getEntities(p_151528_, p_151529_, p_151530_, list); - return list; - } - - public void getEntities(EntityTypeTest p_261899_, AABB p_261837_, Predicate p_261519_, List p_262046_) { - this.getEntities(p_261899_, p_261837_, p_261519_, p_262046_, Integer.MAX_VALUE); - } - - public void getEntities( - EntityTypeTest p_261885_, AABB p_262086_, Predicate p_261688_, List p_262071_, int p_261858_ - ) { - this.getProfiler().incrementCounter("getEntities"); - this.getEntities().get(p_261885_, p_262086_, p_261454_ -> { - if (p_261688_.test(p_261454_)) { - p_262071_.add(p_261454_); - if (p_262071_.size() >= p_261858_) { - return AbortableIterationConsumer.Continuation.ABORT; - } - } - - if (p_261454_ instanceof EnderDragon enderdragon) { - for (EnderDragonPart enderdragonpart : enderdragon.getSubEntities()) { - T t = p_261885_.tryCast(enderdragonpart); - if (t != null && p_261688_.test(t)) { - p_262071_.add(t); - if (p_262071_.size() >= p_261858_) { - return AbortableIterationConsumer.Continuation.ABORT; - } - } - } - } - - return AbortableIterationConsumer.Continuation.CONTINUE; - }); - } - - @Nullable - public abstract Entity getEntity(int p_46492_); - - public void blockEntityChanged(BlockPos p_151544_) { - if (this.hasChunkAt(p_151544_)) { - this.getChunkAt(p_151544_).setUnsaved(true); - } - } - - @Override - public int getSeaLevel() { - return 63; - } - - public void disconnect() { - } - - public long getGameTime() { - return this.levelData.getGameTime(); - } - - public long getDayTime() { - return this.levelData.getDayTime(); - } - - public boolean mayInteract(Player p_46557_, BlockPos p_46558_) { - return true; - } - - public void broadcastEntityEvent(Entity p_46509_, byte p_46510_) { - } - - public void broadcastDamageEvent(Entity p_270831_, DamageSource p_270361_) { - } - - public void blockEvent(BlockPos p_46582_, Block p_46583_, int p_46584_, int p_46585_) { - this.getBlockState(p_46582_).triggerEvent(this, p_46582_, p_46584_, p_46585_); - } - - @Override - public LevelData getLevelData() { - return this.levelData; - } - - public GameRules getGameRules() { - return this.levelData.getGameRules(); - } - - public abstract TickRateManager tickRateManager(); - - public float getThunderLevel(float p_46662_) { - return Mth.lerp(p_46662_, this.oThunderLevel, this.thunderLevel) * this.getRainLevel(p_46662_); - } - - public void setThunderLevel(float p_46708_) { - float f = Mth.clamp(p_46708_, 0.0F, 1.0F); - this.oThunderLevel = f; - this.thunderLevel = f; - } - - public float getRainLevel(float p_46723_) { - return Mth.lerp(p_46723_, this.oRainLevel, this.rainLevel); - } - - public void setRainLevel(float p_46735_) { - float f = Mth.clamp(p_46735_, 0.0F, 1.0F); - this.oRainLevel = f; - this.rainLevel = f; - } - - public boolean isThundering() { - return this.dimensionType().hasSkyLight() && !this.dimensionType().hasCeiling() ? (double)this.getThunderLevel(1.0F) > 0.9 : false; - } - - public boolean isRaining() { - return (double)this.getRainLevel(1.0F) > 0.2; - } - - public boolean isRainingAt(BlockPos p_46759_) { - if (!this.isRaining()) { - return false; - } else if (!this.canSeeSky(p_46759_)) { - return false; - } else if (this.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING, p_46759_).getY() > p_46759_.getY()) { - return false; - } else { - Biome biome = this.getBiome(p_46759_).value(); - return biome.getPrecipitationAt(p_46759_) == Biome.Precipitation.RAIN; - } - } - - @Nullable - public abstract MapItemSavedData getMapData(MapId p_324234_); - - public abstract void setMapData(MapId p_324009_, MapItemSavedData p_151534_); - - public abstract MapId getFreeMapId(); - - public void globalLevelEvent(int p_46665_, BlockPos p_46666_, int p_46667_) { - } - - public CrashReportCategory fillReportDetails(CrashReport p_46656_) { - CrashReportCategory crashreportcategory = p_46656_.addCategory("Affected level", 1); - crashreportcategory.setDetail("All players", () -> this.players().size() + " total; " + this.players()); - crashreportcategory.setDetail("Chunk stats", this.getChunkSource()::gatherStats); - crashreportcategory.setDetail("Level dimension", () -> this.dimension().location().toString()); - - try { - this.levelData.fillCrashReportCategory(crashreportcategory, this); - } catch (Throwable throwable) { - crashreportcategory.setDetailError("Level Data Unobtainable", throwable); - } - - return crashreportcategory; - } - - public abstract void destroyBlockProgress(int p_46506_, BlockPos p_46507_, int p_46508_); - - public void createFireworks( - double p_46475_, double p_46476_, double p_46477_, double p_46478_, double p_46479_, double p_46480_, List p_332050_ - ) { - } - - public abstract Scoreboard getScoreboard(); - - public void updateNeighbourForOutputSignal(BlockPos p_46718_, Block p_46719_) { - for (Direction direction : Direction.Plane.HORIZONTAL) { - BlockPos blockpos = p_46718_.relative(direction); - if (this.hasChunkAt(blockpos)) { - BlockState blockstate = this.getBlockState(blockpos); - if (blockstate.is(Blocks.COMPARATOR)) { - this.neighborChanged(blockstate, blockpos, p_46719_, p_46718_, false); - } else if (blockstate.isRedstoneConductor(this, blockpos)) { - blockpos = blockpos.relative(direction); - blockstate = this.getBlockState(blockpos); - if (blockstate.is(Blocks.COMPARATOR)) { - this.neighborChanged(blockstate, blockpos, p_46719_, p_46718_, false); - } - } - } - } - } - - @Override - public DifficultyInstance getCurrentDifficultyAt(BlockPos p_46730_) { - long i = 0L; - float f = 0.0F; - if (this.hasChunkAt(p_46730_)) { - f = this.getMoonBrightness(); - i = this.getChunkAt(p_46730_).getInhabitedTime(); - } - - return new DifficultyInstance(this.getDifficulty(), this.getDayTime(), i, f); - } - - @Override - public int getSkyDarken() { - return this.skyDarken; - } - - public void setSkyFlashTime(int p_46709_) { - } - - @Override - public WorldBorder getWorldBorder() { - return this.worldBorder; - } - - public void sendPacketToServer(Packet p_46657_) { - throw new UnsupportedOperationException("Can't send packets to server unless you're on the client."); - } - - @Override - public DimensionType dimensionType() { - return this.dimensionTypeRegistration.value(); - } - - public Holder dimensionTypeRegistration() { - return this.dimensionTypeRegistration; - } - - public ResourceKey dimension() { - return this.dimension; - } - - @Override - public RandomSource getRandom() { - return this.random; - } - - @Override - public boolean isStateAtPosition(BlockPos p_46620_, Predicate p_46621_) { - return p_46621_.test(this.getBlockState(p_46620_)); - } - - @Override - public boolean isFluidAtPosition(BlockPos p_151541_, Predicate p_151542_) { - return p_151542_.test(this.getFluidState(p_151541_)); - } - - public abstract RecipeManager getRecipeManager(); - - public BlockPos getBlockRandomPos(int p_46497_, int p_46498_, int p_46499_, int p_46500_) { - this.randValue = this.randValue * 3 + 1013904223; - int i = this.randValue >> 2; - return new BlockPos(p_46497_ + (i & 15), p_46498_ + (i >> 16 & p_46500_), p_46499_ + (i >> 8 & 15)); - } - - public boolean noSave() { - return false; - } - - public ProfilerFiller getProfiler() { - return this.profiler.get(); - } - - public Supplier getProfilerSupplier() { - return this.profiler; - } - - @Override - public BiomeManager getBiomeManager() { - return this.biomeManager; - } - - public final boolean isDebug() { - return this.isDebug; - } - - protected abstract LevelEntityGetter getEntities(); - - @Override - public long nextSubTickCount() { - return this.subTickCount++; - } - - @Override - public RegistryAccess registryAccess() { - return this.registryAccess; - } - - public DamageSources damageSources() { - return this.damageSources; - } - - public abstract PotionBrewing potionBrewing(); - - public static enum ExplosionInteraction implements StringRepresentable { - NONE("none"), - BLOCK("block"), - MOB("mob"), - TNT("tnt"), - TRIGGER("trigger"); - - public static final Codec CODEC = StringRepresentable.fromEnum(Level.ExplosionInteraction::values); - private final String id; - - private ExplosionInteraction(String p_346300_) { - this.id = p_346300_; - } - - @Override - public String getSerializedName() { - return this.id; - } - } -} diff --git a/net/neoforged/neoforge/client/event/RegisterParticleProvidersEvent.java b/net/neoforged/neoforge/client/event/RegisterParticleProvidersEvent.java deleted file mode 100644 index a095112a..00000000 --- a/net/neoforged/neoforge/client/event/RegisterParticleProvidersEvent.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) Forge Development LLC and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.neoforged.neoforge.client.event; - -import net.minecraft.client.particle.ParticleEngine; -import net.minecraft.client.particle.ParticleProvider; -import net.minecraft.client.particle.TextureSheetParticle; -import net.minecraft.core.particles.ParticleOptions; -import net.minecraft.core.particles.ParticleType; -import net.neoforged.bus.api.Event; -import net.neoforged.bus.api.ICancellableEvent; -import net.neoforged.fml.LogicalSide; -import net.neoforged.fml.event.IModBusEvent; -import net.neoforged.neoforge.registries.RegisterEvent; -import org.jetbrains.annotations.ApiStatus; - -/** - * Fired for registering particle providers at the appropriate time. - * - *

{@link ParticleType}s must be registered during {@link RegisterEvent} as usual; - * this event is only for the {@link ParticleProvider}s.

- * - *

This event is not {@linkplain ICancellableEvent cancellable}, and does not {@linkplain HasResult have a result}.

- * - *

This event is fired on the mod-specific event bus, only on the {@linkplain LogicalSide#CLIENT logical client}.

- */ -public class RegisterParticleProvidersEvent extends Event implements IModBusEvent { - private final ParticleEngine particleEngine; - - @ApiStatus.Internal - public RegisterParticleProvidersEvent(ParticleEngine particleEngine) { - this.particleEngine = particleEngine; - } - - /** - *

Registers a ParticleProvider for a non-json-based ParticleType. - * These particles do not receive a list of texture sprites to use for rendering themselves.

- * - *

There must be no particle json with an ID matching the ParticleType, - * or a redundant texture list error will occur when particle jsons load.

- * - * @param ParticleOptions used by the ParticleType and ParticleProvider. - * @param type ParticleType to register a ParticleProvider for. - * @param provider ParticleProvider function responsible for providing that ParticleType's particles. - */ - @SuppressWarnings("deprecation") - public void registerSpecial(ParticleType type, ParticleProvider provider) { - particleEngine.register(type, provider); - } - - /** - *

Registers a ParticleProvider for a json-based ParticleType with a single texture; - * the resulting {@link TextureSheetParticle}s will use that texture when created.

- * - *

A particle json with an ID matching the ParticleType must exist in the particles asset folder, - * or a missing texture list error will occur when particle jsons load.

- * - * @param ParticleOptions used by the ParticleType and Sprite function. - * @param type ParticleType to register a ParticleProvider for. - * @param sprite Sprite function responsible for providing that ParticleType's particles. - */ - @SuppressWarnings("deprecation") - public void registerSprite(ParticleType type, ParticleProvider.Sprite sprite) { - particleEngine.register(type, sprite); - } - - /** - *

Registers a ParticleProvider for a json-based ParticleType. - * Particle jsons define a list of texture sprites which the particle can use to render itself.

- * - *

A particle json with an ID matching the ParticleType must exist in the particles asset folder, - * or a missing texture list error will occur when particle jsons load.

- * - * @param ParticleOptions used by the ParticleType and SpriteParticleRegistration function. - * @param type ParticleType to register a particle provider for. - * @param registration SpriteParticleRegistration function responsible for providing that ParticleType's particles. - */ - @SuppressWarnings("deprecation") - public void registerSpriteSet(ParticleType type, ParticleEngine.SpriteParticleRegistration registration) { - particleEngine.register(type, registration); - } -} diff --git a/src/generated/resources/assets/anvilcraft_pigsplus/lang/en_ud.json b/src/generated/resources/assets/anvilcraft_pigsplus/lang/en_ud.json index 794e6cf6..32871b94 100644 --- a/src/generated/resources/assets/anvilcraft_pigsplus/lang/en_ud.json +++ b/src/generated/resources/assets/anvilcraft_pigsplus/lang/en_ud.json @@ -27,6 +27,8 @@ "anvilcraft_pigsplus.configuration.section.anvilcraft_pigsplus.server.toml": "uoᴉʇɐɹnᵷᴉɟuoƆ ɹǝʌɹǝS snꞁdsᵷᴉԀ ʇɟɐɹɔꞁᴉʌuⱯ", "anvilcraft_pigsplus.configuration.section.anvilcraft_pigsplus.server.toml.title": "uoᴉʇɐɹnᵷᴉɟuoƆ ɹǝʌɹǝS snꞁdsᵷᴉԀ ʇɟɐɹɔꞁᴉʌuⱯ", "anvilcraft_pigsplus.configuration.title": "uoᴉʇɐɹnᵷᴉɟuoƆ snꞁdsᵷᴉԀ ʇɟɐɹɔꞁᴉʌuⱯ", + "anvilcraft_pigsplus.configuration.void_acid_destroy": "ʎoɹʇsǝᗡ pᴉɔⱯ pᴉoɅ", + "anvilcraft_pigsplus.configuration.void_acid_destroy.tooltip": "sʞɔoꞁq ʎoɹʇsǝp oʇ pᴉɔⱯ pᴉoɅ ǝɥʇ ʍoꞁꞁⱯ", "block.anvilcraft_pigsplus.adjustable_power_converter": "ɹǝʇɹǝʌuoƆ ɹǝʍoԀ ǝꞁqɐʇsnɾpⱯ", "block.anvilcraft_pigsplus.auto_chicken": "uǝʞɔᴉɥƆ oʇnⱯ", "block.anvilcraft_pigsplus.auto_jewel_crafting_table": "ǝꞁqɐ⟘ ᵷuᴉʇɟɐɹƆ ꞁǝʍǝՐ oʇnⱯ", @@ -43,10 +45,11 @@ "block.anvilcraft_pigsplus.enchanted_generator.placement_too_close_to_another": "ɹoʇɐɹǝuǝᵷ pǝʇuɐɥɔuǝ ɹǝɥʇouɐ oʇ ǝsoꞁɔ oo⟘", "block.anvilcraft_pigsplus.experience_interface": "ǝɔɐɟɹǝʇuI ǝɔuǝᴉɹǝdxƎ", "block.anvilcraft_pigsplus.fake_menger_sponge": "ǝᵷuodS ɹǝᵷuǝW ǝʞɐℲ", + "block.anvilcraft_pigsplus.memory_block_comparator": "ɹoʇɐɹɐdɯoƆ ʞɔoꞁᗺ ʎɹoɯǝW", + "block.anvilcraft_pigsplus.memory_block_comparator.structure_too_large": "ɹoʇɐɹɐdɯoɔ ʞɔoꞁq ʎɹoɯǝɯ oʇuᴉ pɐoꞁ ʇouuɐɔ '⥝x⥝x⥝ uɐɥʇ ɹǝᵷɹɐꞁ sᴉ ǝɹnʇɔnɹʇs pǝʌɐS", "block.anvilcraft_pigsplus.pig_anvil": "ꞁᴉʌuⱯ ᵷᴉԀ", "block.anvilcraft_pigsplus.precision_magnetic_pivot": "ʇoʌᴉԀ ɔᴉʇǝuᵷɐW uoᴉsᴉɔǝɹԀ", "block.anvilcraft_pigsplus.redstone_conduit_block": "ʞɔoꞁᗺ ʇᴉnpuoƆ ǝuoʇspǝᴚ", - "block.anvilcraft_pigsplus.sculk_extractor": "ɹoʇɔɐɹʇxƎ ʞꞁnɔS", "block.anvilcraft_pigsplus.void_acid": "pᴉɔⱯ pᴉoɅ", "block.anvilcraft_pigsplus.void_acid_cauldron": "uoɹpꞁnɐƆ pᴉɔⱯ pᴉoɅ", "block.anvilcraft_pigsplus.void_catalyst": "ʇsʎꞁɐʇɐƆ pᴉoɅ", diff --git a/src/generated/resources/assets/anvilcraft_pigsplus/lang/en_us.json b/src/generated/resources/assets/anvilcraft_pigsplus/lang/en_us.json index c98595d3..425b233d 100644 --- a/src/generated/resources/assets/anvilcraft_pigsplus/lang/en_us.json +++ b/src/generated/resources/assets/anvilcraft_pigsplus/lang/en_us.json @@ -27,6 +27,8 @@ "anvilcraft_pigsplus.configuration.section.anvilcraft_pigsplus.server.toml": "Anvilcraft Pigsplus Server Configuration", "anvilcraft_pigsplus.configuration.section.anvilcraft_pigsplus.server.toml.title": "Anvilcraft Pigsplus Server Configuration", "anvilcraft_pigsplus.configuration.title": "Anvilcraft Pigsplus Configuration", + "anvilcraft_pigsplus.configuration.void_acid_destroy": "Void Acid Destroy", + "anvilcraft_pigsplus.configuration.void_acid_destroy.tooltip": "Allow the Void Acid to destroy blocks", "block.anvilcraft_pigsplus.adjustable_power_converter": "Adjustable Power Converter", "block.anvilcraft_pigsplus.auto_chicken": "Auto Chicken", "block.anvilcraft_pigsplus.auto_jewel_crafting_table": "Auto Jewel Crafting Table", @@ -43,10 +45,11 @@ "block.anvilcraft_pigsplus.enchanted_generator.placement_too_close_to_another": "Too close to another enchanted generator", "block.anvilcraft_pigsplus.experience_interface": "Experience Interface", "block.anvilcraft_pigsplus.fake_menger_sponge": "Fake Menger Sponge", + "block.anvilcraft_pigsplus.memory_block_comparator": "Memory Block Comparator", + "block.anvilcraft_pigsplus.memory_block_comparator.structure_too_large": "Saved structure is larger than 1x1x1, cannot load into memory block comparator", "block.anvilcraft_pigsplus.pig_anvil": "Pig Anvil", "block.anvilcraft_pigsplus.precision_magnetic_pivot": "Precision Magnetic Pivot", "block.anvilcraft_pigsplus.redstone_conduit_block": "Redstone Conduit Block", - "block.anvilcraft_pigsplus.sculk_extractor": "Sculk Extractor", "block.anvilcraft_pigsplus.void_acid": "Void Acid", "block.anvilcraft_pigsplus.void_acid_cauldron": "Void Acid Cauldron", "block.anvilcraft_pigsplus.void_catalyst": "Void Catalyst", diff --git a/src/generated/resources/assets/anvilcraft_pigsplus/models/item/memory_block_comparator.json b/src/generated/resources/assets/anvilcraft_pigsplus/models/item/memory_block_comparator.json new file mode 100644 index 00000000..755df04e --- /dev/null +++ b/src/generated/resources/assets/anvilcraft_pigsplus/models/item/memory_block_comparator.json @@ -0,0 +1,3 @@ +{ + "parent": "anvilcraft_pigsplus:block/memory_block_comparator" +} \ No newline at end of file diff --git a/src/generated/resources/assets/anvilcraft_pigsplus/models/item/sculk_extractor.json b/src/generated/resources/assets/anvilcraft_pigsplus/models/item/sculk_extractor.json deleted file mode 100644 index 081ddb89..00000000 --- a/src/generated/resources/assets/anvilcraft_pigsplus/models/item/sculk_extractor.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "parent": "anvilcraft_pigsplus:block/sculk_extractor" -} \ No newline at end of file diff --git a/src/generated/resources/data/anvilcraft_pigsplus/advancement/recipes/misc/sculk_extractor.json b/src/generated/resources/data/anvilcraft_pigsplus/advancement/recipes/misc/memory_block_comparator.json similarity index 62% rename from src/generated/resources/data/anvilcraft_pigsplus/advancement/recipes/misc/sculk_extractor.json rename to src/generated/resources/data/anvilcraft_pigsplus/advancement/recipes/misc/memory_block_comparator.json index 70fe2e18..63480a70 100644 --- a/src/generated/resources/data/anvilcraft_pigsplus/advancement/recipes/misc/sculk_extractor.json +++ b/src/generated/resources/data/anvilcraft_pigsplus/advancement/recipes/misc/memory_block_comparator.json @@ -1,11 +1,11 @@ { "parent": "minecraft:recipes/root", "criteria": { - "has_echo_shard": { + "has_karakuri_component": { "conditions": { "items": [ { - "items": "minecraft:echo_shard" + "items": "anvilcraft_pigsplus:karakuri_component" } ] }, @@ -13,7 +13,7 @@ }, "has_the_recipe": { "conditions": { - "recipe": "anvilcraft_pigsplus:sculk_extractor" + "recipe": "anvilcraft_pigsplus:memory_block_comparator" }, "trigger": "minecraft:recipe_unlocked" } @@ -21,12 +21,12 @@ "requirements": [ [ "has_the_recipe", - "has_echo_shard" + "has_karakuri_component" ] ], "rewards": { "recipes": [ - "anvilcraft_pigsplus:sculk_extractor" + "anvilcraft_pigsplus:memory_block_comparator" ] } } \ No newline at end of file diff --git a/src/generated/resources/data/anvilcraft_pigsplus/advancement/recipes/redstone/stonecutting/memory_block_comparator.json b/src/generated/resources/data/anvilcraft_pigsplus/advancement/recipes/redstone/stonecutting/memory_block_comparator.json new file mode 100644 index 00000000..7fbe3d82 --- /dev/null +++ b/src/generated/resources/data/anvilcraft_pigsplus/advancement/recipes/redstone/stonecutting/memory_block_comparator.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_the_recipe": { + "conditions": { + "recipe": "anvilcraft_pigsplus:stonecutting/memory_block_comparator" + }, + "trigger": "minecraft:recipe_unlocked" + }, + "has_universal_redstone_component": { + "conditions": { + "items": [ + { + "items": "anvilcraft_pigsplus:universal_redstone_component" + } + ] + }, + "trigger": "minecraft:inventory_changed" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_universal_redstone_component" + ] + ], + "rewards": { + "recipes": [ + "anvilcraft_pigsplus:stonecutting/memory_block_comparator" + ] + } +} \ No newline at end of file diff --git a/src/generated/resources/data/anvilcraft_pigsplus/advancement/recipes/redstone/stonecutting/observer.json b/src/generated/resources/data/anvilcraft_pigsplus/advancement/recipes/redstone/stonecutting/observer.json new file mode 100644 index 00000000..ae48d0b9 --- /dev/null +++ b/src/generated/resources/data/anvilcraft_pigsplus/advancement/recipes/redstone/stonecutting/observer.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_the_recipe": { + "conditions": { + "recipe": "anvilcraft_pigsplus:stonecutting/observer" + }, + "trigger": "minecraft:recipe_unlocked" + }, + "has_universal_redstone_component": { + "conditions": { + "items": [ + { + "items": "anvilcraft_pigsplus:universal_redstone_component" + } + ] + }, + "trigger": "minecraft:inventory_changed" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_universal_redstone_component" + ] + ], + "rewards": { + "recipes": [ + "anvilcraft_pigsplus:stonecutting/observer" + ] + } +} \ No newline at end of file diff --git a/src/generated/resources/data/anvilcraft_pigsplus/advancement/recipes/redstone/stonecutting/redstone_conduit_block.json b/src/generated/resources/data/anvilcraft_pigsplus/advancement/recipes/redstone/stonecutting/redstone_conduit_block.json new file mode 100644 index 00000000..1cda3cee --- /dev/null +++ b/src/generated/resources/data/anvilcraft_pigsplus/advancement/recipes/redstone/stonecutting/redstone_conduit_block.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_the_recipe": { + "conditions": { + "recipe": "anvilcraft_pigsplus:stonecutting/redstone_conduit_block" + }, + "trigger": "minecraft:recipe_unlocked" + }, + "has_universal_redstone_component": { + "conditions": { + "items": [ + { + "items": "anvilcraft_pigsplus:universal_redstone_component" + } + ] + }, + "trigger": "minecraft:inventory_changed" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_universal_redstone_component" + ] + ], + "rewards": { + "recipes": [ + "anvilcraft_pigsplus:stonecutting/redstone_conduit_block" + ] + } +} \ No newline at end of file diff --git a/src/generated/resources/data/anvilcraft_pigsplus/loot_table/blocks/sculk_extractor.json b/src/generated/resources/data/anvilcraft_pigsplus/loot_table/blocks/memory_block_comparator.json similarity index 68% rename from src/generated/resources/data/anvilcraft_pigsplus/loot_table/blocks/sculk_extractor.json rename to src/generated/resources/data/anvilcraft_pigsplus/loot_table/blocks/memory_block_comparator.json index 7d3bcda1..7d9ecd93 100644 --- a/src/generated/resources/data/anvilcraft_pigsplus/loot_table/blocks/sculk_extractor.json +++ b/src/generated/resources/data/anvilcraft_pigsplus/loot_table/blocks/memory_block_comparator.json @@ -11,11 +11,11 @@ "entries": [ { "type": "minecraft:item", - "name": "anvilcraft_pigsplus:sculk_extractor" + "name": "anvilcraft_pigsplus:memory_block_comparator" } ], "rolls": 1.0 } ], - "random_sequence": "anvilcraft_pigsplus:blocks/sculk_extractor" + "random_sequence": "anvilcraft_pigsplus:blocks/memory_block_comparator" } \ No newline at end of file diff --git a/src/generated/resources/data/anvilcraft_pigsplus/recipe/memory_block_comparator.json b/src/generated/resources/data/anvilcraft_pigsplus/recipe/memory_block_comparator.json new file mode 100644 index 00000000..3c4d7f5d --- /dev/null +++ b/src/generated/resources/data/anvilcraft_pigsplus/recipe/memory_block_comparator.json @@ -0,0 +1,24 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "misc", + "key": { + "A": { + "item": "minecraft:observer" + }, + "B": { + "item": "anvilcraft:processor" + }, + "C": { + "item": "anvilcraft_pigsplus:karakuri_component" + } + }, + "pattern": [ + " ", + "ABC", + " " + ], + "result": { + "count": 1, + "id": "anvilcraft_pigsplus:memory_block_comparator" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/anvilcraft_pigsplus/recipe/sculk_extractor.json b/src/generated/resources/data/anvilcraft_pigsplus/recipe/sculk_extractor.json deleted file mode 100644 index 32a9c774..00000000 --- a/src/generated/resources/data/anvilcraft_pigsplus/recipe/sculk_extractor.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "category": "misc", - "key": { - "C": { - "item": "anvilcraft_pigsplus:spiritual_component" - }, - "L": { - "item": "minecraft:echo_shard" - }, - "S": { - "item": "minecraft:sculk_catalyst" - } - }, - "pattern": [ - " S ", - "LCL", - "LCL" - ], - "result": { - "count": 1, - "id": "anvilcraft_pigsplus:sculk_extractor" - } -} \ No newline at end of file diff --git a/src/generated/resources/data/anvilcraft_pigsplus/recipe/stonecutting/memory_block_comparator.json b/src/generated/resources/data/anvilcraft_pigsplus/recipe/stonecutting/memory_block_comparator.json new file mode 100644 index 00000000..055b16bb --- /dev/null +++ b/src/generated/resources/data/anvilcraft_pigsplus/recipe/stonecutting/memory_block_comparator.json @@ -0,0 +1,10 @@ +{ + "type": "minecraft:stonecutting", + "ingredient": { + "item": "anvilcraft_pigsplus:universal_redstone_component" + }, + "result": { + "count": 1, + "id": "anvilcraft_pigsplus:memory_block_comparator" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/anvilcraft_pigsplus/recipe/stonecutting/observer.json b/src/generated/resources/data/anvilcraft_pigsplus/recipe/stonecutting/observer.json new file mode 100644 index 00000000..5103c9d8 --- /dev/null +++ b/src/generated/resources/data/anvilcraft_pigsplus/recipe/stonecutting/observer.json @@ -0,0 +1,10 @@ +{ + "type": "minecraft:stonecutting", + "ingredient": { + "item": "anvilcraft_pigsplus:universal_redstone_component" + }, + "result": { + "count": 4, + "id": "minecraft:observer" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/anvilcraft_pigsplus/recipe/stonecutting/redstone_conduit_block.json b/src/generated/resources/data/anvilcraft_pigsplus/recipe/stonecutting/redstone_conduit_block.json new file mode 100644 index 00000000..fbb76471 --- /dev/null +++ b/src/generated/resources/data/anvilcraft_pigsplus/recipe/stonecutting/redstone_conduit_block.json @@ -0,0 +1,10 @@ +{ + "type": "minecraft:stonecutting", + "ingredient": { + "item": "anvilcraft_pigsplus:universal_redstone_component" + }, + "result": { + "count": 64, + "id": "anvilcraft_pigsplus:redstone_conduit_block" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/tags/block/mineable/hoe.json b/src/generated/resources/data/minecraft/tags/block/mineable/hoe.json index d4959b9b..f00f5878 100644 --- a/src/generated/resources/data/minecraft/tags/block/mineable/hoe.json +++ b/src/generated/resources/data/minecraft/tags/block/mineable/hoe.json @@ -1,6 +1,5 @@ { "values": [ - "anvilcraft_pigsplus:sculk_extractor", "anvilcraft_pigsplus:fake_menger_sponge" ] } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/tags/block/mineable/pickaxe.json b/src/generated/resources/data/minecraft/tags/block/mineable/pickaxe.json index 009ce54a..a8f9b16c 100644 --- a/src/generated/resources/data/minecraft/tags/block/mineable/pickaxe.json +++ b/src/generated/resources/data/minecraft/tags/block/mineable/pickaxe.json @@ -1,8 +1,10 @@ { "values": [ "anvilcraft_pigsplus:void_acid_cauldron", + "anvilcraft_pigsplus:experience_interface", "anvilcraft_pigsplus:auto_chicken", "anvilcraft_pigsplus:redstone_conduit_block", + "anvilcraft_pigsplus:memory_block_comparator", "anvilcraft_pigsplus:block_breaker", "anvilcraft_pigsplus:precision_magnetic_pivot", "anvilcraft_pigsplus:chain_smithing_table", @@ -11,12 +13,11 @@ "anvilcraft_pigsplus:auto_royal_grindstone", "anvilcraft_pigsplus:adjustable_power_converter", "anvilcraft_pigsplus:chaotic_raw_ore_block", + "anvilcraft_pigsplus:void_catalyst", "anvilcraft_pigsplus:deepslate_chaotic_ore", "anvilcraft_pigsplus:enchanted_generator", "anvilcraft_pigsplus:electric_enchanting_table", "anvilcraft_pigsplus:echo_cluster", - "anvilcraft_pigsplus:budding_echo_shard", - "anvilcraft_pigsplus:void_catalyst", - "anvilcraft_pigsplus:experience_interface" + "anvilcraft_pigsplus:budding_echo_shard" ] } \ No newline at end of file diff --git a/src/main/java/dev/anvilcraft/pigsplus/api/RedstoneConduitLike.java b/src/main/java/dev/anvilcraft/pigsplus/api/RedstoneConduitLike.java deleted file mode 100644 index 66ab701a..00000000 --- a/src/main/java/dev/anvilcraft/pigsplus/api/RedstoneConduitLike.java +++ /dev/null @@ -1,4 +0,0 @@ -package dev.anvilcraft.pigsplus.api; - -public interface RedstoneConduitLike { -} diff --git a/src/main/java/dev/anvilcraft/pigsplus/block/MemoryBlockComparatorBlock.java b/src/main/java/dev/anvilcraft/pigsplus/block/MemoryBlockComparatorBlock.java new file mode 100644 index 00000000..fab761e5 --- /dev/null +++ b/src/main/java/dev/anvilcraft/pigsplus/block/MemoryBlockComparatorBlock.java @@ -0,0 +1,299 @@ +package dev.anvilcraft.pigsplus.block; + +import com.mojang.serialization.MapCodec; +import dev.anvilcraft.lib.v2.piston.IMoveableEntityBlock; +import dev.anvilcraft.lib.v2.util.ShapeUtil; +import dev.anvilcraft.lib.v2.util.Util; +import dev.anvilcraft.pigsplus.block.entity.MemoryBlockComparatorBlockEntity; +import dev.anvilcraft.pigsplus.init.AddonBlockEntities; +import dev.anvilcraft.pigsplus.util.StructureDiskUtil; +import dev.dubhe.anvilcraft.api.hammer.IHammerRemovable; +import dev.dubhe.anvilcraft.block.better.BetterBaseEntityBlock; +import dev.dubhe.anvilcraft.init.item.ModComponents; +import dev.dubhe.anvilcraft.init.item.ModItems; +import dev.dubhe.anvilcraft.util.StructureLoadUtil; +import net.minecraft.ChatFormatting; +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.server.level.ServerPlayer; +import net.minecraft.util.RandomSource; +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.item.context.BlockPlaceContext; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.BaseEntityBlock; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Mirror; +import net.minecraft.world.level.block.RenderShape; +import net.minecraft.world.level.block.Rotation; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.level.block.state.properties.BooleanProperty; +import net.minecraft.world.level.block.state.properties.DirectionProperty; +import net.minecraft.world.level.pathfinder.PathComputationType; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.Shapes; +import net.minecraft.world.phys.shapes.VoxelShape; +import org.jetbrains.annotations.Nullable; + +public class MemoryBlockComparatorBlock extends BetterBaseEntityBlock implements IHammerRemovable, IMoveableEntityBlock { + public static final DirectionProperty FACING = BlockStateProperties.FACING; + public static final BooleanProperty PRECISE = BooleanProperty.create("precise"); + public static final BooleanProperty POWERED = BlockStateProperties.POWERED; + + private static final VoxelShape BASE_SHAPE = Shapes.or( + Block.box(2, 0, 2, 14, 4, 14), + Block.box(5, 4, 5, 11, 10, 11), + Block.box(4, 10, 4, 12, 16, 12) + ); + + private static final VoxelShape SHAPE_DOWN = BASE_SHAPE; + private static final VoxelShape SHAPE_UP = ShapeUtil.rotate(Direction.Axis.X, 180, BASE_SHAPE); + private static final VoxelShape SHAPE_SOUTH = ShapeUtil.rotate(Direction.Axis.X, 90, BASE_SHAPE); + private static final VoxelShape SHAPE_NORTH = ShapeUtil.rotate(Direction.Axis.X, 270, BASE_SHAPE); + private static final VoxelShape SHAPE_EAST = ShapeUtil.rotate(Direction.Axis.Y, 270, SHAPE_NORTH); + private static final VoxelShape SHAPE_WEST = ShapeUtil.rotate(Direction.Axis.Y, 90, SHAPE_NORTH); + + public MemoryBlockComparatorBlock(Properties properties) { + super(properties); + this.registerDefaultState( + this.stateDefinition + .any() + .setValue(FACING, Direction.DOWN) + .setValue(PRECISE, false) + .setValue(POWERED, false) + ); + } + + @Override + protected MapCodec codec() { + return simpleCodec(MemoryBlockComparatorBlock::new); + } + + @Override + protected void createBlockStateDefinition(StateDefinition.Builder builder) { + builder.add(FACING).add(PRECISE).add(POWERED); + } + + @Override + public VoxelShape getShape( + BlockState state, + BlockGetter level, + BlockPos pos, + CollisionContext context + ) { + return switch (state.getValue(FACING)) { + case DOWN -> SHAPE_DOWN; + case UP -> SHAPE_UP; + case NORTH -> SHAPE_NORTH; + case SOUTH -> SHAPE_SOUTH; + case EAST -> SHAPE_EAST; + case WEST -> SHAPE_WEST; + }; + } + + @Override + public RenderShape getRenderShape(BlockState state) { + return RenderShape.MODEL; + } + + @Nullable + @Override + public BlockEntity newBlockEntity(BlockPos pos, BlockState state) { + return AddonBlockEntities.MEMORY_BLOCK_COMPARATOR.create(pos, state); + } + + @Nullable + @Override + public BlockState getStateForPlacement(BlockPlaceContext context) { + Direction facing = context.getNearestLookingDirection(); + if (context.getPlayer() != null && context.getPlayer().isShiftKeyDown()) { + facing = facing.getOpposite(); + } + return defaultBlockState().setValue(FACING, facing); + } + + @Override + protected void onPlace(BlockState state, Level level, BlockPos pos, BlockState oldState, boolean isMoving) { + if (level.isClientSide) return; + if (!oldState.is(state.getBlock()) && level.getBlockEntity(pos) instanceof MemoryBlockComparatorBlockEntity be) { + BlockState frontState = level.getBlockState(pos.relative(state.getValue(FACING))); + be.setRememberedState(frontState); + } + level.scheduleTick(pos, this, 1); + } + + @Override + protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hitResult) { + if (!player.getAbilities().mayBuild) { + return InteractionResult.PASS; + } + BlockState newState = state.cycle(PRECISE); + level.setBlock(pos, newState, Block.UPDATE_ALL); + this.updateNeighborsInFront(level, pos, state); + return InteractionResult.sidedSuccess(level.isClientSide); + } + + @Override + protected ItemInteractionResult useItemOn( + ItemStack stack, + BlockState state, + Level level, + BlockPos pos, + Player player, + InteractionHand hand, + BlockHitResult hitResult + ) { + if (level.isClientSide) return ItemInteractionResult.SUCCESS; + + if (player instanceof ServerPlayer serverPlayer) { + if (level.getBlockEntity(pos) instanceof MemoryBlockComparatorBlockEntity be) { + ItemStack held = serverPlayer.getItemInHand(hand); + + // Regular disk handling (IDiskCloneable) + if (held.is(ModItems.DISK)) { + return Util.interactionResultConverter() + .apply(be.useDisk(level, serverPlayer, hand, held, hitResult)); + } + + // 结构磁盘处理 + if (held.is(ModItems.STRUCTURE_DISK)) { + return handleStructureDisk(level, pos, state, serverPlayer, held, be, this); + } + } + } + return super.useItemOn(stack, state, level, pos, player, hand, hitResult); + } + + @Override + protected void neighborChanged( + BlockState state, + Level level, + BlockPos pos, + Block neighborBlock, + BlockPos neighborPos, + boolean movedByPiston + ) { + if (!level.isClientSide && neighborPos.equals(pos.relative(state.getValue(FACING)))) { + if (!level.getBlockTicks().hasScheduledTick(pos, this)) { + level.scheduleTick(pos, this, 2); + } + } + } + + @Override + protected void tick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) { + boolean matches = checkMatch(level, pos, state); + if (matches != state.getValue(POWERED)) { + level.setBlock(pos, state.setValue(POWERED, matches), Block.UPDATE_ALL); + this.updateNeighborsInFront(level, pos, state); + } + } + + private boolean checkMatch(Level level, BlockPos pos, BlockState state) { + if (!(level.getBlockEntity(pos) instanceof MemoryBlockComparatorBlockEntity be)) { + return false; + } + Direction facing = state.getValue(FACING); + BlockState current = level.getBlockState(pos.relative(facing)); + BlockState remembered = be.getRememberedState(); + return state.getValue(PRECISE) + ? current.equals(remembered) + : current.is(remembered.getBlock()); + } + + /** + * 处理结构磁盘与记忆方块比较器的交互。 + * 若磁盘已有数据则加载,否则保存为 1x1x1 结构。 + */ + protected static ItemInteractionResult handleStructureDisk( + Level level, + BlockPos pos, + BlockState state, + ServerPlayer serverPlayer, + ItemStack held, + MemoryBlockComparatorBlockEntity be, + Block block + ) { + // 磁盘已有数据 → 加载结构 + if (held.has(ModComponents.STRUCTURE_DISK_DATA)) { + StructureLoadUtil.StructureData structureData = StructureLoadUtil.loadStructureFromDisk(level, held); + if (structureData == null || structureData.blocks.isEmpty()) { + return ItemInteractionResult.FAIL; + } + if (structureData.blocks.size() > 1) { + serverPlayer.displayClientMessage( + Component.translatable("block.anvilcraft_pigsplus.memory_block_comparator.structure_too_large") + .withStyle(ChatFormatting.RED), + true + ); + return ItemInteractionResult.SUCCESS; + } + // 单个方块,直接应用 + be.setRememberedState(structureData.blocks.getFirst().state()); + level.scheduleTick(pos, block, 2); + return ItemInteractionResult.SUCCESS; + } else { + // 空磁盘 → 将记忆的方块状态保存为 1x1x1 结构 + BlockState remembered = be.getRememberedState(); + + CompoundTag tag = StructureDiskUtil.getCompoundTag(remembered); + + return StructureDiskUtil.saveData(level, state.getValue(MemoryBlockComparatorBlock.FACING), held, tag) + ? ItemInteractionResult.SUCCESS + : ItemInteractionResult.FAIL; + } + } + + protected void updateNeighborsInFront(Level level, BlockPos pos, BlockState state) { + Direction outputDirection = state.getValue(FACING).getOpposite(); + BlockPos blockPos = pos.relative(outputDirection); + level.neighborChanged(blockPos, this, pos); + level.updateNeighborsAtExceptFromFacing(blockPos, this, outputDirection); + } + + @Override + public boolean canConnectRedstone(BlockState state, BlockGetter level, BlockPos pos, @Nullable Direction direction) { + return direction != (state.getValue(FACING).getOpposite()); + } + + @Override + protected boolean isSignalSource(BlockState state) { + return true; + } + + @Override + protected int getDirectSignal(BlockState blockState, BlockGetter blockAccess, BlockPos pos, Direction side) { + return blockState.getSignal(blockAccess, pos, side); + } + + @Override + protected int getSignal(BlockState blockState, BlockGetter blockAccess, BlockPos pos, Direction side) { + return blockState.getValue(POWERED) && blockState.getValue(FACING).getOpposite() != side ? 15 : 0; + } + + @Override + protected boolean isPathfindable(BlockState state, PathComputationType pathComputationType) { + return false; + } + + @Override + protected BlockState rotate(BlockState state, Rotation rotation) { + return state.setValue(FACING, rotation.rotate(state.getValue(FACING))); + } + + @Override + protected BlockState mirror(BlockState state, Mirror mirror) { + return state.setValue(FACING, mirror.mirror(state.getValue(FACING))); + } +} diff --git a/src/main/java/dev/anvilcraft/pigsplus/block/RedstoneConduitBlock.java b/src/main/java/dev/anvilcraft/pigsplus/block/RedstoneConduitBlock.java index f3489763..f9008999 100644 --- a/src/main/java/dev/anvilcraft/pigsplus/block/RedstoneConduitBlock.java +++ b/src/main/java/dev/anvilcraft/pigsplus/block/RedstoneConduitBlock.java @@ -1,22 +1,24 @@ package dev.anvilcraft.pigsplus.block; -import dev.anvilcraft.pigsplus.api.RedstoneConduitLike; +import dev.anvilcraft.pigsplus.init.AddonBlocks; import dev.dubhe.anvilcraft.api.hammer.IHammerRemovable; +import dev.dubhe.anvilcraft.init.block.ModBlocks; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.util.Mth; import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.RedStoneWireBlock; +import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.StateDefinition; import net.minecraft.world.level.block.state.properties.BlockStateProperties; import net.minecraft.world.level.block.state.properties.IntegerProperty; import net.minecraft.world.level.redstone.Redstone; -public class RedstoneConduitBlock extends Block implements IHammerRemovable, RedstoneConduitLike { +public class RedstoneConduitBlock extends Block implements IHammerRemovable { public static final IntegerProperty POWER = BlockStateProperties.POWER; + private boolean shouldSignal = true; public RedstoneConduitBlock(Properties properties) { super(properties); @@ -30,41 +32,57 @@ protected void createBlockStateDefinition(StateDefinition.Builder= Redstone.SIGNAL_MAX) { - break; - } + private void updatePower(Level level, BlockPos pos) { + if (level.isClientSide) return; + + // 计算期间临时关闭信号输出,防止自我反馈 + this.shouldSignal = false; + + int pow = 0; + for (Direction direction : Direction.values()) { + BlockPos neighborPos = pos.relative(direction); + BlockState neighborState = level.getBlockState(neighborPos); + + int signal; + if (neighborState.is(AddonBlocks.REDSTONE_CONDUIT_BLOCK)) { + signal = neighborState.getValue(POWER) - 1; + } else if (neighborState.is(Blocks.REDSTONE_WIRE)) { + signal = level.getSignal(neighborPos, direction) - 1; + } else if (neighborState.is(ModBlocks.REDSTONE_WIRE)) { + signal = level.getSignal(neighborPos, direction) - 1; + } else { + signal = level.getSignal(neighborPos, direction); } - level.setBlock(pos, state.setValue(POWER, Mth.clamp(pow, 0, 15)), 1 | 2 | 4); + + pow = Math.max(pow, signal); + if (pow >= Redstone.SIGNAL_MAX) break; + } + + this.shouldSignal = true; + + int clamped = Mth.clamp(pow, Redstone.SIGNAL_MIN, Redstone.SIGNAL_MAX); + BlockState state = level.getBlockState(pos); + if (state.getValue(POWER) != clamped) { + level.setBlock(pos, state.setValue(POWER, clamped), Block.UPDATE_ALL); } } @Override public boolean isSignalSource(BlockState state) { - return true; + return this.shouldSignal; } @Override public int getSignal(BlockState blockState, BlockGetter blockAccess, BlockPos pos, Direction side) { - return Math.max(0, blockState.getValue(POWER)); + return !this.shouldSignal ? 0 : blockState.getValue(POWER); } -} \ No newline at end of file +} diff --git a/src/main/java/dev/anvilcraft/pigsplus/block/SculkExtractorBlock.java b/src/main/java/dev/anvilcraft/pigsplus/block/SculkExtractorBlock.java deleted file mode 100644 index 316f4af5..00000000 --- a/src/main/java/dev/anvilcraft/pigsplus/block/SculkExtractorBlock.java +++ /dev/null @@ -1,48 +0,0 @@ -package dev.anvilcraft.pigsplus.block; - -import com.mojang.serialization.MapCodec; -import dev.anvilcraft.pigsplus.block.entity.SculkExtractorBlockEntity; -import dev.anvilcraft.pigsplus.init.AddonBlockEntities; -import dev.dubhe.anvilcraft.api.hammer.IHammerRemovable; -import dev.dubhe.anvilcraft.block.better.BetterBaseEntityBlock; -import net.minecraft.core.BlockPos; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.BaseEntityBlock; -import net.minecraft.world.level.block.RenderShape; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.entity.BlockEntityTicker; -import net.minecraft.world.level.block.entity.BlockEntityType; -import net.minecraft.world.level.block.state.BlockState; -import org.jetbrains.annotations.Nullable; - -public class SculkExtractorBlock extends BetterBaseEntityBlock implements IHammerRemovable { - public SculkExtractorBlock(Properties properties) { - super(properties); - } - - @Override - public BlockEntity newBlockEntity(BlockPos pos, BlockState state) { - return new SculkExtractorBlockEntity(AddonBlockEntities.SCULK_EXTRACTOR.get(),pos, state); - } - - @Override - protected MapCodec codec() { - return simpleCodec(AutoRoyalSmithingTableBlock::new); - } - - @Override - public @Nullable BlockEntityTicker getTicker(Level level, BlockState state, BlockEntityType type) { - if (level.isClientSide) { - return null; - } - return createTickerHelper( - type, AddonBlockEntities.SCULK_EXTRACTOR.get(), - (level1, pos, state1, blockEntity) -> blockEntity.tick() - ); - } - - @Override - public RenderShape getRenderShape(BlockState state) { - return RenderShape.MODEL; - } -} \ No newline at end of file diff --git a/src/main/java/dev/anvilcraft/pigsplus/block/entity/ElectricEnchantingTableBlockEntity.java b/src/main/java/dev/anvilcraft/pigsplus/block/entity/ElectricEnchantingTableBlockEntity.java index 76ebd722..f9073f6d 100644 --- a/src/main/java/dev/anvilcraft/pigsplus/block/entity/ElectricEnchantingTableBlockEntity.java +++ b/src/main/java/dev/anvilcraft/pigsplus/block/entity/ElectricEnchantingTableBlockEntity.java @@ -1,9 +1,10 @@ package dev.anvilcraft.pigsplus.block.entity; import dev.anvilcraft.pigsplus.block.ElectricEnchantingTableBlock; -import dev.anvilcraft.pigsplus.init.AddonParticleTypes; import dev.anvilcraft.pigsplus.util.ChiseledBookShelfUtil; import dev.anvilcraft.pigsplus.util.ExpUtil; +import dev.anvilcraft.pigsplus.util.FluidUtil; +import dev.anvilcraft.pigsplus.util.ParticleUtil; import dev.dubhe.anvilcraft.AnvilCraft; import dev.dubhe.anvilcraft.api.IHasDisplayItem; import dev.dubhe.anvilcraft.api.itemhandler.FilteredItemStackHandler; @@ -11,7 +12,7 @@ import dev.dubhe.anvilcraft.api.power.IPowerConsumer; import dev.dubhe.anvilcraft.api.power.PowerGrid; import dev.dubhe.anvilcraft.block.entity.IFilterBlockEntity; -import dev.dubhe.anvilcraft.init.block.ModFluids; +import dev.dubhe.anvilcraft.init.block.ModFluidTags; import dev.dubhe.anvilcraft.network.UpdateDisplayItemPacket; import it.unimi.dsi.fastutil.objects.Object2IntMap; import lombok.Getter; @@ -47,7 +48,6 @@ public class ElectricEnchantingTableBlockEntity extends BlockEntity implements IPowerConsumer, IFilterBlockEntity, IItemHandlerHolder, IHasDisplayItem { - public static final double PARTICLE_SPEED = 0.06; public Map, Integer> enchantments = new HashMap<>(); @Getter private int needXpLiquid = 0; @@ -176,20 +176,10 @@ protected void absorbXP(ServerLevel level) { int onceNeedXpLiquid = this.needXpLiquid - this.absorbedXpLiquid; onceNeedXpLiquid = Math.clamp(onceNeedXpLiquid, 0, CONFIG.electricEnchantingTable.fluidComsumeSpeed); - FluidStack accepted = handler.drain(new FluidStack(ModFluids.EXP_FLUID, onceNeedXpLiquid), IFluidHandler.FluidAction.EXECUTE); + FluidStack accepted = FluidUtil.drain(handler, ModFluidTags.EXPERIENCE, onceNeedXpLiquid, IFluidHandler.FluidAction.EXECUTE); if (accepted.getAmount() > 0) { - level.sendParticles( - AddonParticleTypes.EXP.get(), - (double) blockPos1.getX() + (double) 0.5F, - (double) blockPos1.getY() + (double) 0.5F, - (double) blockPos1.getZ() + (double) 0.5F, - 0, - blockPos.getX() * -PARTICLE_SPEED * (level.getRandom().nextFloat() * 0.2 + 0.9), - blockPos.getY() * -PARTICLE_SPEED * (level.getRandom().nextFloat() * 0.2 + 0.9), - blockPos.getZ() * -PARTICLE_SPEED * (level.getRandom().nextFloat() * 0.2 + 0.9), - 1.0 - ); + ParticleUtil.sendParticle(level, blockPos1, this.getBlockPos()); this.absorbedXpLiquid += accepted.getAmount(); } diff --git a/src/main/java/dev/anvilcraft/pigsplus/block/entity/ExperienceInterfaceBlockEntity.java b/src/main/java/dev/anvilcraft/pigsplus/block/entity/ExperienceInterfaceBlockEntity.java index 23768bee..26b5bf68 100644 --- a/src/main/java/dev/anvilcraft/pigsplus/block/entity/ExperienceInterfaceBlockEntity.java +++ b/src/main/java/dev/anvilcraft/pigsplus/block/entity/ExperienceInterfaceBlockEntity.java @@ -3,7 +3,9 @@ import dev.anvilcraft.pigsplus.block.ExperienceInterfaceBlock; import dev.anvilcraft.pigsplus.inventory.ExperienceInterfaceMenu; import dev.anvilcraft.pigsplus.util.ExpUtil; -import dev.dubhe.anvilcraft.init.block.ModFluids; +import dev.anvilcraft.pigsplus.util.FluidUtil; +import dev.anvilcraft.pigsplus.util.ParticleUtil; +import dev.dubhe.anvilcraft.init.block.ModFluidTags; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.core.HolderLookup; @@ -26,10 +28,11 @@ import java.util.List; +import static dev.anvilcraft.pigsplus.AnvilCraftPigsPlus.CONFIG; + public class ExperienceInterfaceBlockEntity extends BlockEntity implements MenuProvider { private static final int SEARCH_RADIUS = 2; - private static final int SCAN_COOLDOWN = 20; - public static final int XP_PER_TIME = 100; + private static final int SCAN_COOLDOWN = 40; private int xp_target = 30; private int cooldown = 0; @@ -63,7 +66,7 @@ public void setXpTarget(int xpTarget) { } public void tick(Level level) { - if (!(level instanceof ServerLevel)) return; + if (!(level instanceof ServerLevel level1)) return; if (working) { cooldown = 1; @@ -82,45 +85,53 @@ public void tick(Level level) { if (!player.isRemoved() && !player.isSpectator()) { int playerLevel = player.experienceLevel; if (playerLevel >= xp_target) { - absorbPlayerExperience(player, getHandler()); + absorbPlayerExperience(player, getHandler(), level1); } else { - releaseExperienceToPlayer(player, getHandler()); + releaseExperienceToPlayer(player, getHandler(), level1); } } } } - private void absorbPlayerExperience(Player player, IFluidHandler handler) { - int totalExp; - if (player.experienceLevel > xp_target) { - totalExp = XP_PER_TIME; - } else { - totalExp = Math.min(XP_PER_TIME, (int) (player.experienceProgress * player.getXpNeededForNextLevel())); - } - + private void absorbPlayerExperience(Player player, IFluidHandler handler, ServerLevel level1) { + int totalExp = ExpUtil.getPlayerXp(player) - ExpUtil.getXpfromAllLevel(xp_target); if (totalExp <= 0) return; + int liquidExp = ExpUtil.getFLuidFromXp(totalExp); - int accepted = handler.fill(new FluidStack(ModFluids.EXP_FLUID, liquidExp), IFluidHandler.FluidAction.SIMULATE); + int accepted = FluidUtil.fill(handler, ModFluidTags.EXPERIENCE, liquidExp, IFluidHandler.FluidAction.SIMULATE); + if (accepted <= 0) return; liquidExp = ExpUtil.XpRound(accepted); // 确保只接受完整的经验单位 - handler.fill(new FluidStack(ModFluids.EXP_FLUID, liquidExp), IFluidHandler.FluidAction.EXECUTE); + if (liquidExp <= 0) return; + FluidUtil.fill(handler, ModFluidTags.EXPERIENCE, liquidExp, IFluidHandler.FluidAction.EXECUTE); player.giveExperiencePoints(-ExpUtil.getXpFromFluid(liquidExp)); - } - private void releaseExperienceToPlayer(Player player, IFluidHandler handler) { + int particleNum = Math.max(20, liquidExp / CONFIG.electricEnchantingTable.fluidComsumeSpeed); + for (int i = 0; i < particleNum; i++) { + ParticleUtil.sendParticle(level1, player.getPosition(0), this.getBlockPos().getCenter()); + } + } - int liquidExp = ExpUtil.getFLuidFromXp(XP_PER_TIME); - FluidStack accepted = handler.drain(new FluidStack(ModFluids.EXP_FLUID, liquidExp), IFluidHandler.FluidAction.SIMULATE); + private void releaseExperienceToPlayer(Player player, IFluidHandler handler, ServerLevel level1) { + int totalExp = ExpUtil.getXpfromAllLevel(xp_target) - ExpUtil.getPlayerXp(player); + if (totalExp <= 0) return; - if (accepted.getAmount() <= 0) return; + int liquidExp = ExpUtil.getFLuidFromXp(totalExp); + FluidStack accepted = FluidUtil.drain(handler, ModFluidTags.EXPERIENCE, liquidExp, IFluidHandler.FluidAction.SIMULATE); + if (accepted.isEmpty()) return; liquidExp = ExpUtil.XpRound(accepted.getAmount()); // 确保只接受完整的经验单位 + if (liquidExp <= 0) return; - handler.drain(new FluidStack(ModFluids.EXP_FLUID, liquidExp), IFluidHandler.FluidAction.EXECUTE); - + FluidUtil.drain(handler, ModFluidTags.EXPERIENCE, liquidExp, IFluidHandler.FluidAction.EXECUTE); player.giveExperiencePoints(ExpUtil.getXpFromFluid(liquidExp)); + + int particleNum = Math.max(20, liquidExp / CONFIG.electricEnchantingTable.fluidComsumeSpeed); + for (int i = 0; i < particleNum; i++) { + ParticleUtil.sendParticle(level1, this.getBlockPos().getCenter(), player.getPosition(0)); + } } @Override diff --git a/src/main/java/dev/anvilcraft/pigsplus/block/entity/MemoryBlockComparatorBlockEntity.java b/src/main/java/dev/anvilcraft/pigsplus/block/entity/MemoryBlockComparatorBlockEntity.java new file mode 100644 index 00000000..7533d696 --- /dev/null +++ b/src/main/java/dev/anvilcraft/pigsplus/block/entity/MemoryBlockComparatorBlockEntity.java @@ -0,0 +1,64 @@ +package dev.anvilcraft.pigsplus.block.entity; + +import dev.dubhe.anvilcraft.api.item.IDiskCloneable; +import lombok.Getter; +import net.minecraft.core.BlockPos; +import net.minecraft.core.HolderLookup; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.core.registries.Registries; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtUtils; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; + +public class MemoryBlockComparatorBlockEntity extends BlockEntity implements IDiskCloneable { + @Getter + private BlockState rememberedState = Blocks.AIR.defaultBlockState(); + + public MemoryBlockComparatorBlockEntity(BlockEntityType type, BlockPos pos, BlockState blockState) { + super(type, pos, blockState); + } + + public void setRememberedState(BlockState state) { + this.rememberedState = state; + setChanged(); + } + + @Override + protected void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) { + super.saveAdditional(tag, registries); + tag.put("remembered_state", NbtUtils.writeBlockState(this.rememberedState)); + } + + @Override + protected void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) { + super.loadAdditional(tag, registries); + if (tag.contains("remembered_state")) { + this.rememberedState = NbtUtils.readBlockState( + registries.lookupOrThrow(Registries.BLOCK), + tag.getCompound("remembered_state") + ); + } + } + + @Override + public void storeDiskData(CompoundTag tag) { + tag.put("remembered_state", NbtUtils.writeBlockState(this.rememberedState)); + } + + @Override + public void applyDiskData(CompoundTag tag) { + if (tag.contains("remembered_state")) { + this.rememberedState = NbtUtils.readBlockState( + BuiltInRegistries.BLOCK.asLookup(), + tag.getCompound("remembered_state") + ); + } + setChanged(); + if (level != null && !level.isClientSide) { + level.scheduleTick(this.getBlockPos(), this.getBlockState().getBlock(), 2); + } + } +} diff --git a/src/main/java/dev/anvilcraft/pigsplus/block/entity/PecisionMagneticPivotBlockEntity.java b/src/main/java/dev/anvilcraft/pigsplus/block/entity/PecisionMagneticPivotBlockEntity.java index e1e3cfb5..5be38fbe 100644 --- a/src/main/java/dev/anvilcraft/pigsplus/block/entity/PecisionMagneticPivotBlockEntity.java +++ b/src/main/java/dev/anvilcraft/pigsplus/block/entity/PecisionMagneticPivotBlockEntity.java @@ -80,8 +80,6 @@ public void onAdjacentMagnetPushed(Direction sourceDirection, Direction pushDire preDirection = pushDirection; setChanged(); - ChargeCollectorManager.charge(Math.pow(2, frictionCount), level, this.getBlockPos()); - if (frictionCount == 4) { ChargeCollectorManager.charge(64, level, this.getBlockPos()); frictionCount = 0; diff --git a/src/main/java/dev/anvilcraft/pigsplus/block/entity/SculkExtractorBlockEntity.java b/src/main/java/dev/anvilcraft/pigsplus/block/entity/SculkExtractorBlockEntity.java deleted file mode 100644 index c810a69a..00000000 --- a/src/main/java/dev/anvilcraft/pigsplus/block/entity/SculkExtractorBlockEntity.java +++ /dev/null @@ -1,82 +0,0 @@ -package dev.anvilcraft.pigsplus.block.entity; - -import dev.anvilcraft.pigsplus.init.AddonBlocks; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.core.HolderLookup; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.entity.ExperienceOrb; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.entity.BlockEntityType; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.phys.Vec3; - -import java.util.concurrent.atomic.AtomicInteger; - -public class SculkExtractorBlockEntity extends BlockEntity { - private int cooldown = 0; - private static final int SCAN_COOLDOWN = 100; - - public SculkExtractorBlockEntity(BlockEntityType type, BlockPos pos, BlockState blockState) { - super(type, pos, blockState); - } - - @Override - protected void loadAdditional(CompoundTag tag, HolderLookup.Provider provider) { - super.loadAdditional(tag, provider); - cooldown = tag.getInt("Cooldown"); - } - - @Override - protected void saveAdditional(CompoundTag tag, HolderLookup.Provider provider) { - super.saveAdditional(tag, provider); - tag.putInt("Cooldown", cooldown); - } - - public void tick() { - if (level == null || level.isClientSide()) return; - if (cooldown-- > 0) return; - cooldown = SCAN_COOLDOWN; - - // 计算周围的幽匿类方块数量 - AtomicInteger sculkValue = new AtomicInteger(); - BlockPos.breadthFirstTraversal( - getBlockPos(), 8, (int) Math.pow(2, 10), - (blockPos, consumer) -> { - for (Direction direction : Direction.values()) { - consumer.accept(blockPos.relative(direction)); - } - }, - blockPos -> { - BlockState state = level.getBlockState(blockPos); - if (state.is(Blocks.SCULK) || - state.is(Blocks.SCULK_VEIN) || - state.is(Blocks.SCULK_CATALYST) || - state.is(Blocks.SCULK_SHRIEKER) || - state.is(Blocks.SCULK_SENSOR)) { - level.setBlockAndUpdate(blockPos, Blocks.AIR.defaultBlockState()); - sculkValue.getAndIncrement(); - return true; - } else if ( - state.is(AddonBlocks.ECHO_CLUSTER)) { - level.setBlockAndUpdate(blockPos, Blocks.AIR.defaultBlockState()); - sculkValue.getAndAdd(50); - return true; - } else if (state.is(AddonBlocks.BUDDING_ECHO_SHARD) || - state.is(AddonBlocks.SCULK_EXTRACTOR)) { - return true; - } else { - return false; - } - } - ); - - // 根据周围的幽匿方块数量确定经验球的数量 - int experienceAmount = Math.max(0, 10 * sculkValue.get()); - if (experienceAmount == 0) return; - Vec3 spawnPos = Vec3.atCenterOf(getBlockPos()).add(0, 1, 0); - ExperienceOrb.award((ServerLevel) level, spawnPos, experienceAmount); - } -} \ No newline at end of file diff --git a/src/main/java/dev/anvilcraft/pigsplus/config/AddonServerConfig.java b/src/main/java/dev/anvilcraft/pigsplus/config/AddonServerConfig.java index a1864056..489eeacc 100644 --- a/src/main/java/dev/anvilcraft/pigsplus/config/AddonServerConfig.java +++ b/src/main/java/dev/anvilcraft/pigsplus/config/AddonServerConfig.java @@ -19,6 +19,10 @@ public class AddonServerConfig { @BoundedDiscrete(min = 1, max = 1024000) public int portableWirelessChargerEnergyConversion = 16; + // 虚空酸 + @Comment("Allow the Void Acid to destroy blocks") + public boolean voidAcidDestroy = true; + // 电力附魔台 @CollapsibleObject public ElectricEnchantingTable electricEnchantingTable = new ElectricEnchantingTable(); diff --git a/src/main/java/dev/anvilcraft/pigsplus/data/lang/LangHandler.java b/src/main/java/dev/anvilcraft/pigsplus/data/lang/LangHandler.java index 4274fa91..98d4f5fc 100644 --- a/src/main/java/dev/anvilcraft/pigsplus/data/lang/LangHandler.java +++ b/src/main/java/dev/anvilcraft/pigsplus/data/lang/LangHandler.java @@ -19,6 +19,11 @@ public static void init(RegistrumLangProvider provider) { "Too close to another enchanted generator" ); + provider.add( + "block.anvilcraft_pigsplus.memory_block_comparator.structure_too_large", + "Saved structure is larger than 1x1x1, cannot load into memory block comparator" + ); + provider.add("tooltip.anvilcraft_pigsplus.enchanted_generator.decrease_rate", "XP decrease rate: %s"); provider.add("tooltip.anvilcraft_pigsplus.menger_sponge_staff", "Remove a large amount of liquid"); provider.add("tooltip.anvilcraft_pigsplus.precision_magnetic_pivot.time", "Status: %s"); diff --git a/src/main/java/dev/anvilcraft/pigsplus/data/recipe/VanillaRecipesLoader.java b/src/main/java/dev/anvilcraft/pigsplus/data/recipe/VanillaRecipesLoader.java index 8676fd1e..57df654c 100644 --- a/src/main/java/dev/anvilcraft/pigsplus/data/recipe/VanillaRecipesLoader.java +++ b/src/main/java/dev/anvilcraft/pigsplus/data/recipe/VanillaRecipesLoader.java @@ -2,6 +2,7 @@ import dev.anvilcraft.lib.v2.registrum.providers.RegistrumRecipeProvider; import dev.anvilcraft.pigsplus.AnvilCraftPigsPlus; +import dev.anvilcraft.pigsplus.init.AddonBlocks; import dev.anvilcraft.pigsplus.init.AddonItems; import dev.dubhe.anvilcraft.data.AnvilCraftDatagen; import dev.dubhe.anvilcraft.init.block.ModBlocks; @@ -25,6 +26,8 @@ public static void init(RegistrumRecipeProvider provider) { .unlockedBy("hasitem", AnvilCraftDatagen.has(AddonItems.KARAKURI_COMPONENT)) .save(provider, AnvilCraftPigsPlus.of("circuit_board")); + cuttingUniversalRedstoneComponent(provider, AddonBlocks.MEMORY_BLOCK_COMPARATOR, 1); + cuttingUniversalRedstoneComponent(provider, AddonBlocks.REDSTONE_CONDUIT_BLOCK, 64); cuttingUniversalRedstoneComponent(provider, ModBlocks.PULSE_GENERATOR, 1); cuttingUniversalRedstoneComponent(provider, ModBlocks.ADVANCED_COMPARATOR, 1); cuttingUniversalRedstoneComponent(provider, ModBlocks.BLOCK_COMPARATOR, 1); @@ -34,6 +37,7 @@ public static void init(RegistrumRecipeProvider provider) { cuttingUniversalRedstoneComponent(provider, Items.COMPARATOR, 3); cuttingUniversalRedstoneComponent(provider, Items.LEVER, 8); cuttingUniversalRedstoneComponent(provider, Items.TRIPWIRE_HOOK, 4); + cuttingUniversalRedstoneComponent(provider, Items.OBSERVER, 4); } diff --git a/src/main/java/dev/anvilcraft/pigsplus/fluid/VoidAcidFluid.java b/src/main/java/dev/anvilcraft/pigsplus/fluid/VoidAcidFluid.java index 6b5e15dd..c7547717 100644 --- a/src/main/java/dev/anvilcraft/pigsplus/fluid/VoidAcidFluid.java +++ b/src/main/java/dev/anvilcraft/pigsplus/fluid/VoidAcidFluid.java @@ -13,26 +13,34 @@ import net.minecraft.world.level.material.FluidState; import net.neoforged.neoforge.fluids.BaseFlowingFluid; +import static dev.anvilcraft.pigsplus.AnvilCraftPigsPlus.CONFIG; + public abstract class VoidAcidFluid extends BaseFlowingFluid { protected VoidAcidFluid(Properties properties) { super(properties); } + @Override + protected boolean isRandomlyTicking() { + return true; + } + @Override public void randomTick(Level level, BlockPos pos, FluidState state, RandomSource random) { - // TODO: 不知道为什么不触发 super.randomTick(level, pos, state, random); + if (level.isClientSide()) return; + if (!CONFIG.voidAcidDestroy) return; + for (Direction direction : Direction.values()) { BlockPos targetPos = pos.relative(direction); BlockState targetState = level.getBlockState(targetPos); if (targetState.is(AddonBlockTags.VOID_ACID_IMMUNE)) continue; - float hardness = targetState.getDestroySpeed(level, targetPos); if (hardness <= 0.0f) continue; - float probability = 5f / (hardness + 10.0f); + float probability = 1f / (hardness + 2.0f); if (random.nextFloat() < probability) { level.destroyBlock(targetPos, false); if (random.nextFloat() < 0.1f) { diff --git a/src/main/java/dev/anvilcraft/pigsplus/init/AddonBlockEntities.java b/src/main/java/dev/anvilcraft/pigsplus/init/AddonBlockEntities.java index aa00c6cd..22781cf2 100644 --- a/src/main/java/dev/anvilcraft/pigsplus/init/AddonBlockEntities.java +++ b/src/main/java/dev/anvilcraft/pigsplus/init/AddonBlockEntities.java @@ -8,8 +8,8 @@ import dev.anvilcraft.pigsplus.block.entity.ElectricEnchantingTableBlockEntity; import dev.anvilcraft.pigsplus.block.entity.EnchantedGeneratorBlockEntity; import dev.anvilcraft.pigsplus.block.entity.ExperienceInterfaceBlockEntity; +import dev.anvilcraft.pigsplus.block.entity.MemoryBlockComparatorBlockEntity; import dev.anvilcraft.pigsplus.block.entity.PecisionMagneticPivotBlockEntity; -import dev.anvilcraft.pigsplus.block.entity.SculkExtractorBlockEntity; import dev.anvilcraft.pigsplus.client.renderer.blockentity.AdjustablePowerConverterRenderer; import dev.anvilcraft.pigsplus.client.renderer.blockentity.ElectricEnchantingTableRenderer; import dev.anvilcraft.pigsplus.client.renderer.blockentity.EnchantedGeneratorRenderer; @@ -44,10 +44,6 @@ public class AddonBlockEntities { .renderer(() -> ElectricEnchantingTableRenderer::new) .register(); - public static final BlockEntityEntry SCULK_EXTRACTOR = - REGISTRATE.blockEntity("sculk_extractor", SculkExtractorBlockEntity::new) - .validBlock(AddonBlocks.SCULK_EXTRACTOR) - .register(); public static final BlockEntityEntry ADJUSTABLE_POWER_CONVERTER = REGISTRATE.blockEntity("adjustable_power_converter", AdjustablePowerConverterBlockEntity::new) @@ -65,6 +61,11 @@ public class AddonBlockEntities { .validBlock(AddonBlocks.PRECISION_MAGNETIC_PIVOT) .register(); + public static final BlockEntityEntry MEMORY_BLOCK_COMPARATOR = + REGISTRATE.blockEntity("memory_block_comparator", MemoryBlockComparatorBlockEntity::new) + .validBlock(AddonBlocks.MEMORY_BLOCK_COMPARATOR) + .register(); + public static void register() { } } \ No newline at end of file diff --git a/src/main/java/dev/anvilcraft/pigsplus/init/AddonBlocks.java b/src/main/java/dev/anvilcraft/pigsplus/init/AddonBlocks.java index fe23300c..5529feaa 100644 --- a/src/main/java/dev/anvilcraft/pigsplus/init/AddonBlocks.java +++ b/src/main/java/dev/anvilcraft/pigsplus/init/AddonBlocks.java @@ -14,10 +14,10 @@ import dev.anvilcraft.pigsplus.block.EnchantedGeneratorBlock; import dev.anvilcraft.pigsplus.block.ExperienceInterfaceBlock; import dev.anvilcraft.pigsplus.block.FakeMengerSpongeBlock; +import dev.anvilcraft.pigsplus.block.MemoryBlockComparatorBlock; import dev.anvilcraft.pigsplus.block.PecisionMagneticPivotBlock; import dev.anvilcraft.pigsplus.block.PigAnvilBlock; import dev.anvilcraft.pigsplus.block.RedstoneConduitBlock; -import dev.anvilcraft.pigsplus.block.SculkExtractorBlock; import dev.anvilcraft.pigsplus.block.VoidAcidCauldronBlock; import dev.anvilcraft.pigsplus.block.VoidCatalystBlock; import dev.anvilcraft.pigsplus.block.WeakResinBlock; @@ -113,6 +113,26 @@ public class AddonBlocks { .save(provider)) .register(); + public static final BlockEntry EXPERIENCE_INTERFACE = REGISTRATE + .block("experience_interface", ExperienceInterfaceBlock::new) + .lang("Experience Interface") + .initialProperties(() -> Blocks.IRON_BLOCK) + .properties(p -> p.noOcclusion().isValidSpawn(Blocks::never)) + .blockstate(DataGenUtil::noExtraModelOrState) + .simpleItem() + .tag(BlockTags.MINEABLE_WITH_PICKAXE) + .recipe((ctx, provider) -> ShapedRecipeBuilder.shaped(RecipeCategory.MISC, ctx.get()) + .pattern(" ") + .pattern(" E ") + .pattern("ABA") + .define('A', AddonItems.KARAKURI_COMPONENT) + .define('B', ModItemTags.BRASS_INGOTS) + .define('E', ModItems.EXP_GEM) + .unlockedBy(AnvilCraftDatagen.hasItem(AddonItems.KARAKURI_COMPONENT), AnvilCraftDatagen.has(AddonItems.KARAKURI_COMPONENT)) + .unlockedBy(AnvilCraftDatagen.hasItem(ModItems.EXP_GEM), AnvilCraftDatagen.has(ModItems.EXP_GEM)) + .save(provider)) + .register(); + public static final BlockEntry AUTO_CHICKEN = REGISTRATE .block("auto_chicken", AutoChickenBlock::new) .lang("Auto Chicken") @@ -142,6 +162,25 @@ public class AddonBlocks { .save(provider)) .register(); + public static final BlockEntry MEMORY_BLOCK_COMPARATOR = REGISTRATE + .block("memory_block_comparator", MemoryBlockComparatorBlock::new) + .lang("Memory Block Comparator") + .initialProperties(() -> Blocks.OBSERVER) + .properties(p -> p.noOcclusion().isValidSpawn(Blocks::never)) + .blockstate(DataGenUtil::noExtraModelOrState) + .simpleItem() + .recipe((ctx, provider) -> ShapedRecipeBuilder.shaped(RecipeCategory.MISC, ctx.get()) + .pattern(" ") + .pattern("ABC") + .pattern(" ") + .define('A', Items.OBSERVER) + .define('B', ModItems.PROCESSOR) + .define('C', AddonItems.KARAKURI_COMPONENT) + .unlockedBy(AnvilCraftDatagen.hasItem(AddonItems.KARAKURI_COMPONENT), AnvilCraftDatagen.has(AddonItems.KARAKURI_COMPONENT)) + .save(provider)) + .tag(BlockTags.MINEABLE_WITH_PICKAXE) + .register(); + public static final BlockEntry BLOCK_BREAKER = REGISTRATE .block("block_breaker", BlockBreakerBlock::new) .lang("Block Breaker") @@ -317,6 +356,24 @@ public class AddonBlocks { .tag(BlockTags.MINEABLE_WITH_PICKAXE, Tags.Blocks.STORAGE_BLOCKS) .register(); + public static final BlockEntry VOID_CATALYST = REGISTRATE + .block("void_catalyst", VoidCatalystBlock::new) + .lang("Void Catalyst") + .initialProperties(() -> Blocks.IRON_BLOCK) + .properties(BlockBehaviour.Properties::randomTicks) + .blockstate(DataGenUtil::noExtraModelOrState) + .simpleItem() + .tag(BlockTags.MINEABLE_WITH_PICKAXE) + .recipe((ctx, provider) -> ShapedRecipeBuilder.shaped(RecipeCategory.MISC, ctx.get()) + .pattern(" A ") + .pattern("ABA") + .pattern(" A ") + .define('A', ModBlocks.VOID_MATTER_BLOCK) + .define('B', AddonItems.KARAKURI_COMPONENT) + .unlockedBy(AnvilCraftDatagen.hasItem(ModBlocks.VOID_MATTER_BLOCK), AnvilCraftDatagen.has(ModBlocks.VOID_MATTER_BLOCK)) + .save(provider)) + .register(); + public static final BlockEntry DEEPSLATE_CHAOTIC_ORE = REGISTRATE .block("deepslate_chaotic_ore", Block::new) .initialProperties(() -> Blocks.DEEPSLATE_IRON_ORE) @@ -399,63 +456,6 @@ public class AddonBlocks { tables.add(block, tables.createSilkTouchDispatchTable(block, LootItem.lootTableItem(AddonItems.ECHO_GEODE.get())))) .register(); - public static final BlockEntry SCULK_EXTRACTOR = REGISTRATE - .block("sculk_extractor", SculkExtractorBlock::new) - .lang("Sculk Extractor") - .initialProperties(() -> Blocks.SCULK) - .properties(p -> p.mapColor(MapColor.COLOR_BLACK).strength(4.0F, 3.0F).sound(SoundType.SCULK_CATALYST).lightLevel((state) -> 9)) - .blockstate(DataGenUtil::noExtraModelOrState) - .simpleItem() - .tag(BlockTags.MINEABLE_WITH_HOE) - .recipe((ctx, provider) -> ShapedRecipeBuilder.shaped(RecipeCategory.MISC, ctx.get()) - .pattern(" S ") - .pattern("LCL") - .pattern("LCL") - .define('S', Blocks.SCULK_CATALYST) - .define('L', Items.ECHO_SHARD) - .define('C', AddonItems.SPIRITUAL_COMPONENT) - .unlockedBy(AnvilCraftDatagen.hasItem(Items.ECHO_SHARD), AnvilCraftDatagen.has(Items.ECHO_SHARD)) - .save(provider)) - .register(); - - public static final BlockEntry VOID_CATALYST = REGISTRATE - .block("void_catalyst", VoidCatalystBlock::new) - .lang("Void Catalyst") - .initialProperties(() -> Blocks.IRON_BLOCK) - .properties(BlockBehaviour.Properties::randomTicks) - .blockstate(DataGenUtil::noExtraModelOrState) - .simpleItem() - .tag(BlockTags.MINEABLE_WITH_PICKAXE) - .recipe((ctx, provider) -> ShapedRecipeBuilder.shaped(RecipeCategory.MISC, ctx.get()) - .pattern(" A ") - .pattern("ABA") - .pattern(" A ") - .define('A', ModBlocks.VOID_MATTER_BLOCK) - .define('B', AddonItems.KARAKURI_COMPONENT) - .unlockedBy(AnvilCraftDatagen.hasItem(ModBlocks.VOID_MATTER_BLOCK), AnvilCraftDatagen.has(ModBlocks.VOID_MATTER_BLOCK)) - .save(provider)) - .register(); - - public static final BlockEntry EXPERIENCE_INTERFACE = REGISTRATE - .block("experience_interface", ExperienceInterfaceBlock::new) - .lang("Experience Interface") - .initialProperties(() -> Blocks.IRON_BLOCK) - .properties(p -> p.noOcclusion().isValidSpawn(Blocks::never)) - .blockstate(DataGenUtil::noExtraModelOrState) - .simpleItem() - .tag(BlockTags.MINEABLE_WITH_PICKAXE) - .recipe((ctx, provider) -> ShapedRecipeBuilder.shaped(RecipeCategory.MISC, ctx.get()) - .pattern(" ") - .pattern(" E ") - .pattern("ABA") - .define('A', AddonItems.KARAKURI_COMPONENT) - .define('B', ModItemTags.BRASS_INGOTS) - .define('E', ModItems.EXP_GEM) - .unlockedBy(AnvilCraftDatagen.hasItem(AddonItems.KARAKURI_COMPONENT), AnvilCraftDatagen.has(AddonItems.KARAKURI_COMPONENT)) - .unlockedBy(AnvilCraftDatagen.hasItem(ModItems.EXP_GEM), AnvilCraftDatagen.has(ModItems.EXP_GEM)) - .save(provider)) - .register(); - public static final BlockEntry FAKE_MENGER_SPONGE = REGISTRATE .block("fake_menger_sponge", FakeMengerSpongeBlock::new) .initialProperties(() -> Blocks.SPONGE) diff --git a/src/main/java/dev/anvilcraft/pigsplus/init/AddonItems.java b/src/main/java/dev/anvilcraft/pigsplus/init/AddonItems.java index 62b8474b..48e63ca7 100644 --- a/src/main/java/dev/anvilcraft/pigsplus/init/AddonItems.java +++ b/src/main/java/dev/anvilcraft/pigsplus/init/AddonItems.java @@ -79,11 +79,6 @@ public class AddonItems { .save(provider)) .register(); - public static final ItemEntry UNIVERSAL_REDSTONE_COMPONENT = REGISTRATE - .item("universal_redstone_component", Item::new) - .model(DataGenUtil::noExtraModelOrState) - .register(); - public static final ItemEntry MENGER_SPONGE_STAFF = REGISTRATE .item("menger_sponge_staff", MengerSpongeStaffItem::new) .properties((properties) -> properties.stacksTo(1)) @@ -116,6 +111,11 @@ public class AddonItems { .model(ModelProviderUtil::bucket) .register(); + public static final ItemEntry UNIVERSAL_REDSTONE_COMPONENT = REGISTRATE + .item("universal_redstone_component", Item::new) + .model(DataGenUtil::noExtraModelOrState) + .register(); + public static void register() { } } \ No newline at end of file diff --git a/src/main/java/dev/anvilcraft/pigsplus/util/ExpUtil.java b/src/main/java/dev/anvilcraft/pigsplus/util/ExpUtil.java index c8d84d73..226ecd1b 100644 --- a/src/main/java/dev/anvilcraft/pigsplus/util/ExpUtil.java +++ b/src/main/java/dev/anvilcraft/pigsplus/util/ExpUtil.java @@ -1,23 +1,9 @@ package dev.anvilcraft.pigsplus.util; +import net.minecraft.world.entity.player.Player; + public class ExpUtil { public static final int EXPERIENCE_TO_LIQUID = 20; - public static final int XP_LEVEL_NUM = 3; - public static final int[] XP_LEVEL_N = { - 30, - 15, - 0 - }; - public static final int[] XP_LEVEL_A = { - 9, - 5, - 2 - }; - public static final int[] XP_LEVEL_B = { - 112, - 37, - 7 - }; public static int getFLuidFromXp(int xp) { return EXPERIENCE_TO_LIQUID * xp; @@ -31,23 +17,23 @@ public static int XpRound(int fluid) { return fluid - fluid % EXPERIENCE_TO_LIQUID; } - public static int getXpfromLevel(int level) { - for (int i = 0; i < XP_LEVEL_NUM; i++) { - if (level >= XP_LEVEL_N[i]) { - return level * XP_LEVEL_A[i] + XP_LEVEL_B[i]; - } + public static int getXpfromAllLevel(int level) { + if (level == 0) { + return 0; + } + if (level > 0 && level < 16) { + return level * (12 + level * 2) / 2; + } else if (level > 15 && level < 31) { + return (level - 15) * (69 + (level - 15) * 5) / 2 + 315; + } else { + return (int) Math.min(Integer.MAX_VALUE, (level - 30L) * (215 + (level - 30) * 9L) / 2 + 1395); } - return 0; } - public static int getXpfromAllLevel(int level) { - int xp = 0; - for (int i = 0; i < XP_LEVEL_NUM; i++) { - if (level >= XP_LEVEL_N[i]) { - xp += (getXpfromLevel(level) + getXpFromFluid(XP_LEVEL_N[i])) * (level - XP_LEVEL_N[i] + 1) / 2; - level = XP_LEVEL_N[i] - 1; - } - } - return xp; + public static int getPlayerXp(Player player) { + return (int) Math.min( + Integer.MAX_VALUE, + getXpfromAllLevel(player.experienceLevel) + ((long) (player.experienceProgress * player.getXpNeededForNextLevel())) + ); } } diff --git a/src/main/java/dev/anvilcraft/pigsplus/util/FluidUtil.java b/src/main/java/dev/anvilcraft/pigsplus/util/FluidUtil.java new file mode 100644 index 00000000..10e410e5 --- /dev/null +++ b/src/main/java/dev/anvilcraft/pigsplus/util/FluidUtil.java @@ -0,0 +1,32 @@ +package dev.anvilcraft.pigsplus.util; + +import dev.dubhe.anvilcraft.init.block.ModFluids; +import net.minecraft.core.Holder; +import net.minecraft.tags.TagKey; +import net.minecraft.world.level.material.Fluid; +import net.neoforged.neoforge.fluids.FluidStack; +import net.neoforged.neoforge.fluids.capability.IFluidHandler; + +public class FluidUtil { + public static int fill(IFluidHandler handler, TagKey fluidTagKey, int liquidExp, IFluidHandler.FluidAction action) { + for (int tank = 0; tank < handler.getTanks(); tank++) { + Holder tankFluid = handler.getFluidInTank(tank).getFluidHolder(); + if (tankFluid.is(fluidTagKey)) { + int accepted = handler.fill(new FluidStack(tankFluid, liquidExp), action); + if (accepted > 0) return accepted; + } + } + return handler.fill(new FluidStack(ModFluids.EXP_FLUID, liquidExp), action); + } + + public static FluidStack drain(IFluidHandler handler, TagKey fluidTagKey, int liquidExp, IFluidHandler.FluidAction action) { + for (int tank = 0; tank < handler.getTanks(); tank++) { + Holder tankFluid = handler.getFluidInTank(tank).getFluidHolder(); + if (tankFluid.is(fluidTagKey)) { + FluidStack accepted = handler.drain(new FluidStack(tankFluid, liquidExp), action); + if (accepted.getAmount() > 0) return accepted; + } + } + return FluidStack.EMPTY; + } +} diff --git a/src/main/java/dev/anvilcraft/pigsplus/util/ParticleUtil.java b/src/main/java/dev/anvilcraft/pigsplus/util/ParticleUtil.java new file mode 100644 index 00000000..232b43f2 --- /dev/null +++ b/src/main/java/dev/anvilcraft/pigsplus/util/ParticleUtil.java @@ -0,0 +1,36 @@ +package dev.anvilcraft.pigsplus.util; + +import dev.anvilcraft.pigsplus.init.AddonParticleTypes; +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.phys.Vec3; + +public class ParticleUtil { + public static final double EXP_PARTICLE_SPEED = 0.025; + + public static void sendParticle(ServerLevel level, BlockPos startPos, BlockPos endPos) { + sendParticle(level, startPos.getCenter(), endPos.getCenter()); + } + + public static void sendParticle(ServerLevel level, Vec3 startPos, Vec3 endPos) { + Vec3 start = startPos.offsetRandom(level.getRandom(), 0.3f); + Vec3 end = endPos.offsetRandom(level.getRandom(), 0.3f); + Vec3 offset = start.vectorTo(end); + double distance = offset.length(); + sendParticle(level, start, offset, distance * EXP_PARTICLE_SPEED); + } + + public static void sendParticle(ServerLevel level, Vec3 start, Vec3 offset, double speed) { + level.sendParticles( + AddonParticleTypes.EXP.get(), + start.x(), + start.y(), + start.z(), + 0, + offset.x(), + offset.y(), + offset.z(), + speed + ); + } +} diff --git a/src/main/java/dev/anvilcraft/pigsplus/util/StructureDiskUtil.java b/src/main/java/dev/anvilcraft/pigsplus/util/StructureDiskUtil.java new file mode 100644 index 00000000..a5c1ad9a --- /dev/null +++ b/src/main/java/dev/anvilcraft/pigsplus/util/StructureDiskUtil.java @@ -0,0 +1,77 @@ +package dev.anvilcraft.pigsplus.util; + +import dev.dubhe.anvilcraft.init.item.ModComponents; +import dev.dubhe.anvilcraft.item.property.component.StructureDiskData; +import net.minecraft.SharedConstants; +import net.minecraft.core.Direction; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.IntTag; +import net.minecraft.nbt.ListTag; +import net.minecraft.nbt.NbtIo; +import net.minecraft.nbt.NbtUtils; +import net.minecraft.server.MinecraftServer; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.storage.LevelResource; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.UUID; + +public class StructureDiskUtil { + + public static boolean saveData(Level level, Direction direction, ItemStack held, CompoundTag tag) { + try { + MinecraftServer server = level.getServer(); + if (server == null) return false; + Path baseDir = server.getWorldPath(LevelResource.ROOT) + .toAbsolutePath() + .normalize() + .resolve("anvilcraft") + .resolve("structures"); + UUID uuid = UUID.randomUUID(); + String name = "memory_block_comparator"; + String fileName = "%s_%s.nbt".formatted(name, uuid); + Path structureFile = baseDir.resolve(fileName); + Files.createDirectories(baseDir); + NbtIo.writeCompressed(tag, structureFile); + + StructureDiskData diskData = new StructureDiskData(fileName, name, uuid, direction, 1, 1, 1); + held.set(ModComponents.STRUCTURE_DISK_DATA, diskData); + return true; + } catch (IOException e) { + return false; + } + } + + public static CompoundTag getCompoundTag(BlockState remembered) { + CompoundTag tag = new CompoundTag(); + tag.putInt("DataVersion", SharedConstants.getCurrentVersion().getDataVersion().getVersion()); + tag.putString("author", "Memory Block Comparator"); + + ListTag sizeTag = new ListTag(); + sizeTag.add(IntTag.valueOf(1)); + sizeTag.add(IntTag.valueOf(1)); + sizeTag.add(IntTag.valueOf(1)); + tag.put("size", sizeTag); + + ListTag paletteTag = new ListTag(); + paletteTag.add(NbtUtils.writeBlockState(remembered)); + tag.put("palette", paletteTag); + + ListTag blocksTag = new ListTag(); + CompoundTag blockTag = new CompoundTag(); + ListTag posTag = new ListTag(); + posTag.add(IntTag.valueOf(0)); + posTag.add(IntTag.valueOf(0)); + posTag.add(IntTag.valueOf(0)); + blockTag.put("pos", posTag); + blockTag.putInt("state", 0); + blocksTag.add(blockTag); + tag.put("blocks", blocksTag); + tag.put("entities", new ListTag()); + return tag; + } +} diff --git a/src/main/resources/assets/anvilcraft/ageratum/en_us/100_pigsplus_automation_components/101_memory_block_comparator.md b/src/main/resources/assets/anvilcraft/ageratum/en_us/100_pigsplus_automation_components/101_memory_block_comparator.md new file mode 100644 index 00000000..4e3295b9 --- /dev/null +++ b/src/main/resources/assets/anvilcraft/ageratum/en_us/100_pigsplus_automation_components/101_memory_block_comparator.md @@ -0,0 +1,24 @@ +--- +navigation: + title: "§2Memory Block Comparator" + icon: "anvilcraft_pigsplus:memory_block_comparator" +items: + - anvilcraft_pigsplus:memory_block_comparator +--- + +# + + + + + +# Function + +1. Can compare blocks, similar to +2. Immediately records the block state in front of it when placed +3. Afterwards, if the block in front matches the recorded memory, outputs a redstone signal +4. Can be right-clicked to switch to precise mode, same behavior as + +# Reading and Writing + +The memory can be read and overwritten using or diff --git a/src/main/resources/assets/anvilcraft/ageratum/en_us/100_pigsplus_automation_components/101_precision_magnetic_pivot.md b/src/main/resources/assets/anvilcraft/ageratum/en_us/100_pigsplus_automation_components/101_precision_magnetic_pivot.md index 7452d67d..ed451a81 100644 --- a/src/main/resources/assets/anvilcraft/ageratum/en_us/100_pigsplus_automation_components/101_precision_magnetic_pivot.md +++ b/src/main/resources/assets/anvilcraft/ageratum/en_us/100_pigsplus_automation_components/101_precision_magnetic_pivot.md @@ -4,6 +4,7 @@ navigation: icon: "anvilcraft_pigsplus:precision_magnetic_pivot" items: - anvilcraft_pigsplus:precision_magnetic_pivot + - anvilcraft_pigsplus:universal_redstone_component --- # @@ -20,7 +21,6 @@ items: # Charge -- Rubbing the 1st, 2nd, 3rd, and 4th sides generates 2, 4, 8, and 16 charges respectively - Completing a full rubbing cycle generates an additional 64 charges - Charges can be collected using @@ -29,12 +29,12 @@ items: An activated can perform *Precision Electromagnetic Processing* - - + + - + @@ -42,3 +42,9 @@ An activated can perf + +# + + + +Can be crafted into various redstone components in a diff --git a/src/main/resources/assets/anvilcraft/ageratum/en_us/100_pigsplus_automation_components/101_redstone_conduit.md b/src/main/resources/assets/anvilcraft/ageratum/en_us/100_pigsplus_automation_components/101_redstone_conduit.md index a448b2b2..0fed2b30 100644 --- a/src/main/resources/assets/anvilcraft/ageratum/en_us/100_pigsplus_automation_components/101_redstone_conduit.md +++ b/src/main/resources/assets/anvilcraft/ageratum/en_us/100_pigsplus_automation_components/101_redstone_conduit.md @@ -16,5 +16,6 @@ items: # Function -- A block-shaped redstone dust that can be linked in any shape +- A block-shaped that can be linked in any shape +- When receiving redstone signal input from , , or , the signal decays by one level diff --git a/src/main/resources/assets/anvilcraft/ageratum/en_us/100_pigsplus_automation_components/141_void_acid.md b/src/main/resources/assets/anvilcraft/ageratum/en_us/100_pigsplus_automation_components/141_void_acid.md index 08a3b9e0..60581c7a 100644 --- a/src/main/resources/assets/anvilcraft/ageratum/en_us/100_pigsplus_automation_components/141_void_acid.md +++ b/src/main/resources/assets/anvilcraft/ageratum/en_us/100_pigsplus_automation_components/141_void_acid.md @@ -12,6 +12,10 @@ items: + +Void acid placed in the world will slowly destroy surrounding blocks. The higher the hardness, the slower the destruction. This can be disabled in config. + + # Ore Refining @@ -24,6 +28,6 @@ items: - + diff --git a/src/main/resources/assets/anvilcraft/ageratum/en_us/100_pigsplus_automation_components/201_sculk_extractor.md b/src/main/resources/assets/anvilcraft/ageratum/en_us/100_pigsplus_automation_components/201_sculk_extractor.md deleted file mode 100644 index 8300755e..00000000 --- a/src/main/resources/assets/anvilcraft/ageratum/en_us/100_pigsplus_automation_components/201_sculk_extractor.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -navigation: - title: "§6Sculk Extractor" - icon: "anvilcraft_pigsplus:sculk_extractor" -items: - - anvilcraft_pigsplus:sculk_extractor ---- - -# Sculk Extractor - - - -Can absorb sculk blocks and release large amounts of experience - -> By reverse-engineering the mechanism behind the Sculk Catalyst, the Sculk Extractor was created, capable of reverse-converting sculk blocks into experience orbs - -# Obtaining - - - -# Function - -- Devours connected sculk-related blocks within a distance of 7, generating experience based on the amount -- provides much more experience (50x) -- can participate in the connection, but will not be consumed and does not grant experience - -# Related - -- - diff --git a/src/main/resources/assets/anvilcraft/ageratum/en_us/100_pigsplus_building_props/index.md b/src/main/resources/assets/anvilcraft/ageratum/en_us/100_pigsplus_building_props/index.md index 2e3bee60..48832a0f 100644 --- a/src/main/resources/assets/anvilcraft/ageratum/en_us/100_pigsplus_building_props/index.md +++ b/src/main/resources/assets/anvilcraft/ageratum/en_us/100_pigsplus_building_props/index.md @@ -1,6 +1,6 @@ --- navigation: - title: "Pigs+ Building Props" + title: "Pigs+ Props" icon: "anvilcraft_pigsplus:karakuri_component" --- @@ -8,4 +8,4 @@ navigation: Hello! This is Da Zhu. AnvilCraft: Pigs+ aims to add more blocks and machines, making AnvilCraft more convenient and fun to play. -This chapter introduces various building props +This chapter introduces various props diff --git a/src/main/resources/assets/anvilcraft/ageratum/zh_cn/100_pigsplus_automation_components/101_memory_block_comparator.md b/src/main/resources/assets/anvilcraft/ageratum/zh_cn/100_pigsplus_automation_components/101_memory_block_comparator.md new file mode 100644 index 00000000..acae95c1 --- /dev/null +++ b/src/main/resources/assets/anvilcraft/ageratum/zh_cn/100_pigsplus_automation_components/101_memory_block_comparator.md @@ -0,0 +1,24 @@ +--- +navigation: + title: "§2记忆方块比较器" + icon: "anvilcraft_pigsplus:memory_block_comparator" +items: + - anvilcraft_pigsplus:memory_block_comparator +--- + +# + + + + + +# 功能 + +1. 可以比较方块,类似于 +2. 放下时立刻记录面前的方块状态 +3. 之后,如果面前的方块和记忆中相同,输出红石信号 +4. 可以右键调整为精准模式,效果同 + +# 读取与写入 + +可以使用或读取和覆写记忆 diff --git a/src/main/resources/assets/anvilcraft/ageratum/zh_cn/100_pigsplus_automation_components/101_precision_magnetic_pivot.md b/src/main/resources/assets/anvilcraft/ageratum/zh_cn/100_pigsplus_automation_components/101_precision_magnetic_pivot.md index e7fd0078..4ed0f5fd 100644 --- a/src/main/resources/assets/anvilcraft/ageratum/zh_cn/100_pigsplus_automation_components/101_precision_magnetic_pivot.md +++ b/src/main/resources/assets/anvilcraft/ageratum/zh_cn/100_pigsplus_automation_components/101_precision_magnetic_pivot.md @@ -21,8 +21,7 @@ items: # 电荷 -- 摩擦到第1、2、3、4个面时,分别产生2、4、8、16个电荷 -- 如果完成一个摩擦周期,还会额外产生64个电荷 +- 如果完成一个摩擦周期,额外产生64个电荷 - 可用收集这些电荷 # 高效配方 diff --git a/src/main/resources/assets/anvilcraft/ageratum/zh_cn/100_pigsplus_automation_components/101_redstone_conduit.md b/src/main/resources/assets/anvilcraft/ageratum/zh_cn/100_pigsplus_automation_components/101_redstone_conduit.md index ffff1057..0eccc394 100644 --- a/src/main/resources/assets/anvilcraft/ageratum/zh_cn/100_pigsplus_automation_components/101_redstone_conduit.md +++ b/src/main/resources/assets/anvilcraft/ageratum/zh_cn/100_pigsplus_automation_components/101_redstone_conduit.md @@ -16,4 +16,5 @@ items: # 功能 -- 方块状的红石粉,可以以任意形状链接 +- 方块状的,可以以任意形状链接 +- 受到包括、、输入的红石信号时,都会衰减一个等级 diff --git a/src/main/resources/assets/anvilcraft/ageratum/zh_cn/100_pigsplus_automation_components/141_void_acid.md b/src/main/resources/assets/anvilcraft/ageratum/zh_cn/100_pigsplus_automation_components/141_void_acid.md index 7f8d6d6f..ecdb55eb 100644 --- a/src/main/resources/assets/anvilcraft/ageratum/zh_cn/100_pigsplus_automation_components/141_void_acid.md +++ b/src/main/resources/assets/anvilcraft/ageratum/zh_cn/100_pigsplus_automation_components/141_void_acid.md @@ -12,6 +12,10 @@ items: + +放置在世界中的虚空酸会缓慢破坏周围的方块,硬度越高破坏越慢,可在config中关闭 + + # 矿物提炼 diff --git a/src/main/resources/assets/anvilcraft/ageratum/zh_cn/100_pigsplus_automation_components/201_sculk_extractor.md b/src/main/resources/assets/anvilcraft/ageratum/zh_cn/100_pigsplus_automation_components/201_sculk_extractor.md deleted file mode 100644 index 1c9523e9..00000000 --- a/src/main/resources/assets/anvilcraft/ageratum/zh_cn/100_pigsplus_automation_components/201_sculk_extractor.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -navigation: - title: "§6幽匿萃取体" - icon: "anvilcraft_pigsplus:sculk_extractor" -items: - - anvilcraft_pigsplus:sculk_extractor ---- - -# 幽匿萃取体 - - - -可以吸收幽匿方块,释放大量经验 - -> 通过逆向研究幽匿催发体的机理构造,幽匿萃取体被制作出来,能够将幽匿块反向转化为经验球 - -# 获得 - - - -# 功能 - -- 吞噬7格范围内相连接的幽匿类方块,根据数量生成经验 -- 提供的经验更多(50倍) -- 可以参与连接,但不会被吞噬,也不产出经验 - -# 相关 - -- \ No newline at end of file diff --git a/src/main/resources/assets/anvilcraft/ageratum/zh_cn/100_pigsplus_building_props/index.md b/src/main/resources/assets/anvilcraft/ageratum/zh_cn/100_pigsplus_building_props/index.md index addb1b9c..531acefc 100644 --- a/src/main/resources/assets/anvilcraft/ageratum/zh_cn/100_pigsplus_building_props/index.md +++ b/src/main/resources/assets/anvilcraft/ageratum/zh_cn/100_pigsplus_building_props/index.md @@ -1,6 +1,6 @@ --- navigation: - title: "猪+建设道具" + title: "猪+道具" icon: "anvilcraft_pigsplus:karakuri_component" --- @@ -8,4 +8,4 @@ navigation: 你好!这里是大猪。《铁砧工艺:猪+》旨在添加更多方块和机器,让玩家游玩铁砧工艺更加方便有趣。 -这一章节介绍各种建设道具 +这一章节介绍各种道具 diff --git a/src/main/resources/assets/anvilcraft_pigsplus/blockstates/memory_block_comparator.json b/src/main/resources/assets/anvilcraft_pigsplus/blockstates/memory_block_comparator.json new file mode 100644 index 00000000..df7ca6ec --- /dev/null +++ b/src/main/resources/assets/anvilcraft_pigsplus/blockstates/memory_block_comparator.json @@ -0,0 +1,104 @@ +{ + "variants": { + "facing=down,precise=false,powered=false": { + "model": "anvilcraft_pigsplus:block/memory_block_comparator" + }, + "facing=down,precise=false,powered=true": { + "model": "anvilcraft_pigsplus:block/memory_block_comparator_on" + }, + "facing=down,precise=true,powered=false": { + "model": "anvilcraft_pigsplus:block/memory_block_comparator_precise" + }, + "facing=down,precise=true,powered=true": { + "model": "anvilcraft_pigsplus:block/memory_block_comparator_precise_on" + }, + "facing=up,precise=false,powered=false": { + "model": "anvilcraft_pigsplus:block/memory_block_comparator", + "x": 180 + }, + "facing=up,precise=false,powered=true": { + "model": "anvilcraft_pigsplus:block/memory_block_comparator_on", + "x": 180 + }, + "facing=up,precise=true,powered=false": { + "model": "anvilcraft_pigsplus:block/memory_block_comparator_precise", + "x": 180 + }, + "facing=up,precise=true,powered=true": { + "model": "anvilcraft_pigsplus:block/memory_block_comparator_precise_on", + "x": 180 + }, + "facing=north,precise=false,powered=false": { + "model": "anvilcraft_pigsplus:block/memory_block_comparator", + "x": 270 + }, + "facing=north,precise=false,powered=true": { + "model": "anvilcraft_pigsplus:block/memory_block_comparator_on", + "x": 270 + }, + "facing=north,precise=true,powered=false": { + "model": "anvilcraft_pigsplus:block/memory_block_comparator_precise", + "x": 270 + }, + "facing=north,precise=true,powered=true": { + "model": "anvilcraft_pigsplus:block/memory_block_comparator_precise_on", + "x": 270 + }, + "facing=south,precise=false,powered=false": { + "model": "anvilcraft_pigsplus:block/memory_block_comparator", + "x": 90 + }, + "facing=south,precise=false,powered=true": { + "model": "anvilcraft_pigsplus:block/memory_block_comparator_on", + "x": 90 + }, + "facing=south,precise=true,powered=false": { + "model": "anvilcraft_pigsplus:block/memory_block_comparator_precise", + "x": 90 + }, + "facing=south,precise=true,powered=true": { + "model": "anvilcraft_pigsplus:block/memory_block_comparator_precise_on", + "x": 90 + }, + "facing=east,precise=false,powered=false": { + "model": "anvilcraft_pigsplus:block/memory_block_comparator", + "x": 90, + "y": 270 + }, + "facing=east,precise=false,powered=true": { + "model": "anvilcraft_pigsplus:block/memory_block_comparator_on", + "x": 90, + "y": 270 + }, + "facing=east,precise=true,powered=false": { + "model": "anvilcraft_pigsplus:block/memory_block_comparator_precise", + "x": 90, + "y": 270 + }, + "facing=east,precise=true,powered=true": { + "model": "anvilcraft_pigsplus:block/memory_block_comparator_precise_on", + "x": 90, + "y": 270 + }, + "facing=west,precise=false,powered=false": { + "model": "anvilcraft_pigsplus:block/memory_block_comparator", + "x": 90, + "y": 90 + }, + "facing=west,precise=false,powered=true": { + "model": "anvilcraft_pigsplus:block/memory_block_comparator_on", + "x": 90, + "y": 90 + }, + "facing=west,precise=true,powered=false": { + "model": "anvilcraft_pigsplus:block/memory_block_comparator_precise", + "x": 90, + "y": 90 + }, + "facing=west,precise=true,powered=true": { + "model": "anvilcraft_pigsplus:block/memory_block_comparator_precise_on", + "x": 90, + "y": 90 + } + } +} diff --git a/src/main/resources/assets/anvilcraft_pigsplus/blockstates/sculk_extractor.json b/src/main/resources/assets/anvilcraft_pigsplus/blockstates/sculk_extractor.json deleted file mode 100644 index 81d0f5ba..00000000 --- a/src/main/resources/assets/anvilcraft_pigsplus/blockstates/sculk_extractor.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "variants": { - "": { - "model": "anvilcraft_pigsplus:block/sculk_extractor" - } - } -} \ No newline at end of file diff --git a/src/main/resources/assets/anvilcraft_pigsplus/lang/zh_cn.json b/src/main/resources/assets/anvilcraft_pigsplus/lang/zh_cn.json index fcf0f7ae..8a0a5de8 100644 --- a/src/main/resources/assets/anvilcraft_pigsplus/lang/zh_cn.json +++ b/src/main/resources/assets/anvilcraft_pigsplus/lang/zh_cn.json @@ -27,6 +27,8 @@ "anvilcraft_pigsplus.configuration.section.anvilcraft_pigsplus.server.toml": "铁砧工艺:猪+ 服务端配置", "anvilcraft_pigsplus.configuration.section.anvilcraft_pigsplus.server.toml.title": "铁砧工艺:猪+ 服务端配置", "anvilcraft_pigsplus.configuration.title": "铁砧工艺:猪+ 配置", + "anvilcraft_pigsplus.configuration.void_acid_destroy": "Void Acid Destroy", + "anvilcraft_pigsplus.configuration.void_acid_destroy.tooltip": "允许虚空酸破坏方块", "block.anvilcraft_pigsplus.adjustable_power_converter": "可调式能量转换器", "block.anvilcraft_pigsplus.auto_chicken": "叮砧鸡", "block.anvilcraft_pigsplus.auto_jewel_crafting_table": "自动珠宝加工台", @@ -43,10 +45,11 @@ "block.anvilcraft_pigsplus.enchanted_generator.placement_too_close_to_another": "距离其他附魔发电机太近了", "block.anvilcraft_pigsplus.experience_interface": "经验接口", "block.anvilcraft_pigsplus.fake_menger_sponge": "假门格海绵", + "block.anvilcraft_pigsplus.memory_block_comparator": "记忆方块比较器", + "block.anvilcraft_pigsplus.memory_block_comparator.structure_too_large": "保存的结构大小大于 1x1x1, 无法加载到记忆方块比较器", "block.anvilcraft_pigsplus.pig_anvil": "猪砧", "block.anvilcraft_pigsplus.precision_magnetic_pivot": "精密磁枢", "block.anvilcraft_pigsplus.redstone_conduit_block": "红石传导块", - "block.anvilcraft_pigsplus.sculk_extractor": "幽匿萃取体", "block.anvilcraft_pigsplus.void_acid": "虚空酸", "block.anvilcraft_pigsplus.void_acid_cauldron": "虚空酸炼药锅", "block.anvilcraft_pigsplus.void_catalyst": "虚空催化体", diff --git a/src/main/resources/assets/anvilcraft_pigsplus/models/block/memory_block_comparator.json b/src/main/resources/assets/anvilcraft_pigsplus/models/block/memory_block_comparator.json new file mode 100644 index 00000000..64280b12 --- /dev/null +++ b/src/main/resources/assets/anvilcraft_pigsplus/models/block/memory_block_comparator.json @@ -0,0 +1,52 @@ +{ + "format_version": "1.9.0", + "credit": "Made with Blockbench by TBpig", + "parent": "minecraft:block/block", + "textures": { + "particle": "anvilcraft_pigsplus:block/memory_block_comparator_input", + "input": "anvilcraft_pigsplus:block/memory_block_comparator_input", + "middle": "anvilcraft_pigsplus:block/memory_block_comparator_middle", + "output": "anvilcraft_pigsplus:block/memory_block_comparator_output" + }, + "elements": [ + { + "from": [2, 0, 2], + "to": [14, 4, 14], + "rotation": {"angle": 0, "axis": "y", "origin": [2, 0, 2]}, + "faces": { + "north": {"uv": [0, 0, 12, 4], "texture": "#input"}, + "east": {"uv": [0, 0, 12, 4], "texture": "#input"}, + "south": {"uv": [0, 0, 12, 4], "texture": "#input"}, + "west": {"uv": [0, 0, 12, 4], "texture": "#input"}, + "up": {"uv": [0, 4, 12, 16], "texture": "#input"}, + "down": {"uv": [0, 4, 12, 16], "texture": "#input"} + } + }, + { + "from": [5, 4, 5], + "to": [11, 10, 11], + "rotation": {"angle": 0, "axis": "y", "origin": [5, 4, 5]}, + "faces": { + "north": {"uv": [0, 0, 6, 6], "texture": "#middle"}, + "east": {"uv": [0, 0, 6, 6], "texture": "#middle"}, + "south": {"uv": [0, 0, 6, 6], "texture": "#middle"}, + "west": {"uv": [0, 0, 6, 6], "texture": "#middle"}, + "up": {"uv": [0, 0, 6, 6], "texture": "#middle"}, + "down": {"uv": [0, 0, 6, 6], "texture": "#middle"} + } + }, + { + "from": [4, 10, 4], + "to": [12, 16, 12], + "rotation": {"angle": 0, "axis": "y", "origin": [4, 10, 4]}, + "faces": { + "north": {"uv": [0, 8, 8, 14], "texture": "#output"}, + "east": {"uv": [0, 8, 8, 14], "texture": "#output"}, + "south": {"uv": [0, 8, 8, 14], "texture": "#output"}, + "west": {"uv": [0, 8, 8, 14], "texture": "#output"}, + "up": {"uv": [0, 0, 8, 8], "texture": "#output"}, + "down": {"uv": [0, 0, 8, 8], "texture": "#output"} + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/anvilcraft_pigsplus/models/block/memory_block_comparator_on.json b/src/main/resources/assets/anvilcraft_pigsplus/models/block/memory_block_comparator_on.json new file mode 100644 index 00000000..e30947e6 --- /dev/null +++ b/src/main/resources/assets/anvilcraft_pigsplus/models/block/memory_block_comparator_on.json @@ -0,0 +1,9 @@ +{ + "parent": "anvilcraft_pigsplus:block/memory_block_comparator", + "textures": { + "particle": "anvilcraft_pigsplus:block/memory_block_comparator_input_on", + "input": "anvilcraft_pigsplus:block/memory_block_comparator_input_on", + "middle": "anvilcraft_pigsplus:block/memory_block_comparator_middle", + "output": "anvilcraft_pigsplus:block/memory_block_comparator_output_on" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/anvilcraft_pigsplus/models/block/memory_block_comparator_precise.json b/src/main/resources/assets/anvilcraft_pigsplus/models/block/memory_block_comparator_precise.json new file mode 100644 index 00000000..70b8f726 --- /dev/null +++ b/src/main/resources/assets/anvilcraft_pigsplus/models/block/memory_block_comparator_precise.json @@ -0,0 +1,9 @@ +{ + "parent": "anvilcraft_pigsplus:block/memory_block_comparator", + "textures": { + "particle": "anvilcraft_pigsplus:block/memory_block_comparator_input_precise", + "input": "anvilcraft_pigsplus:block/memory_block_comparator_input_precise", + "middle": "anvilcraft_pigsplus:block/memory_block_comparator_middle", + "output": "anvilcraft_pigsplus:block/memory_block_comparator_output_precise" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/anvilcraft_pigsplus/models/block/memory_block_comparator_precise_on.json b/src/main/resources/assets/anvilcraft_pigsplus/models/block/memory_block_comparator_precise_on.json new file mode 100644 index 00000000..262b6036 --- /dev/null +++ b/src/main/resources/assets/anvilcraft_pigsplus/models/block/memory_block_comparator_precise_on.json @@ -0,0 +1,9 @@ +{ + "parent": "anvilcraft_pigsplus:block/memory_block_comparator", + "textures": { + "particle": "anvilcraft_pigsplus:block/memory_block_comparator_input_precise_on", + "input": "anvilcraft_pigsplus:block/memory_block_comparator_input_precise_on", + "middle": "anvilcraft_pigsplus:block/memory_block_comparator_middle", + "output": "anvilcraft_pigsplus:block/memory_block_comparator_output_precise_on" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/anvilcraft_pigsplus/models/block/sculk_extractor.json b/src/main/resources/assets/anvilcraft_pigsplus/models/block/sculk_extractor.json deleted file mode 100644 index 38a6fafd..00000000 --- a/src/main/resources/assets/anvilcraft_pigsplus/models/block/sculk_extractor.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "format_version": "1.21.6", - "credit": "Made with Blockbench", - "parent": "minecraft:block/cube", - "textures": { - "0": "anvilcraft_pigsplus:block/sculk_extractor_top", - "1": "anvilcraft_pigsplus:block/sculk_extractor_side", - "2": "anvilcraft_pigsplus:block/sculk_extractor_bottom", - "particle": "anvilcraft_pigsplus:block/sculk_extractor_side" - }, - "elements": [ - { - "from": [0, 0, 0], - "to": [16, 16, 16], - "faces": { - "north": {"uv": [0, 0, 16, 16], "texture": "#1"}, - "east": {"uv": [0, 0, 16, 16], "texture": "#1"}, - "south": {"uv": [0, 0, 16, 16], "texture": "#1"}, - "west": {"uv": [0, 0, 16, 16], "texture": "#1"}, - "up": {"uv": [16, 16, 0, 0], "texture": "#0"}, - "down": {"uv": [16, 0, 0, 16], "texture": "#2"} - } - } - ] -} \ No newline at end of file diff --git a/src/main/resources/assets/anvilcraft_pigsplus/textures/block/memory_block_comparator_input.png b/src/main/resources/assets/anvilcraft_pigsplus/textures/block/memory_block_comparator_input.png new file mode 100644 index 00000000..2f994f2f Binary files /dev/null and b/src/main/resources/assets/anvilcraft_pigsplus/textures/block/memory_block_comparator_input.png differ diff --git a/src/main/resources/assets/anvilcraft_pigsplus/textures/block/memory_block_comparator_input_on.png b/src/main/resources/assets/anvilcraft_pigsplus/textures/block/memory_block_comparator_input_on.png new file mode 100644 index 00000000..df0d120d Binary files /dev/null and b/src/main/resources/assets/anvilcraft_pigsplus/textures/block/memory_block_comparator_input_on.png differ diff --git a/src/main/resources/assets/anvilcraft_pigsplus/textures/block/memory_block_comparator_input_precise.png b/src/main/resources/assets/anvilcraft_pigsplus/textures/block/memory_block_comparator_input_precise.png new file mode 100644 index 00000000..e8a72e5e Binary files /dev/null and b/src/main/resources/assets/anvilcraft_pigsplus/textures/block/memory_block_comparator_input_precise.png differ diff --git a/src/main/resources/assets/anvilcraft_pigsplus/textures/block/memory_block_comparator_input_precise_on.png b/src/main/resources/assets/anvilcraft_pigsplus/textures/block/memory_block_comparator_input_precise_on.png new file mode 100644 index 00000000..1ccb878a Binary files /dev/null and b/src/main/resources/assets/anvilcraft_pigsplus/textures/block/memory_block_comparator_input_precise_on.png differ diff --git a/src/main/resources/assets/anvilcraft_pigsplus/textures/block/memory_block_comparator_middle.png b/src/main/resources/assets/anvilcraft_pigsplus/textures/block/memory_block_comparator_middle.png new file mode 100644 index 00000000..7d5f7566 Binary files /dev/null and b/src/main/resources/assets/anvilcraft_pigsplus/textures/block/memory_block_comparator_middle.png differ diff --git a/src/main/resources/assets/anvilcraft_pigsplus/textures/block/memory_block_comparator_output.png b/src/main/resources/assets/anvilcraft_pigsplus/textures/block/memory_block_comparator_output.png new file mode 100644 index 00000000..dcc87a79 Binary files /dev/null and b/src/main/resources/assets/anvilcraft_pigsplus/textures/block/memory_block_comparator_output.png differ diff --git a/src/main/resources/assets/anvilcraft_pigsplus/textures/block/memory_block_comparator_output_on.png b/src/main/resources/assets/anvilcraft_pigsplus/textures/block/memory_block_comparator_output_on.png new file mode 100644 index 00000000..194643c6 Binary files /dev/null and b/src/main/resources/assets/anvilcraft_pigsplus/textures/block/memory_block_comparator_output_on.png differ diff --git a/src/main/resources/assets/anvilcraft_pigsplus/textures/block/memory_block_comparator_output_precise.png b/src/main/resources/assets/anvilcraft_pigsplus/textures/block/memory_block_comparator_output_precise.png new file mode 100644 index 00000000..77fec689 Binary files /dev/null and b/src/main/resources/assets/anvilcraft_pigsplus/textures/block/memory_block_comparator_output_precise.png differ diff --git a/src/main/resources/assets/anvilcraft_pigsplus/textures/block/memory_block_comparator_output_precise_on.png b/src/main/resources/assets/anvilcraft_pigsplus/textures/block/memory_block_comparator_output_precise_on.png new file mode 100644 index 00000000..669aba00 Binary files /dev/null and b/src/main/resources/assets/anvilcraft_pigsplus/textures/block/memory_block_comparator_output_precise_on.png differ diff --git a/src/main/resources/assets/anvilcraft_pigsplus/textures/block/sculk_extractor_bottom.png b/src/main/resources/assets/anvilcraft_pigsplus/textures/block/sculk_extractor_bottom.png deleted file mode 100644 index fe63a86a..00000000 Binary files a/src/main/resources/assets/anvilcraft_pigsplus/textures/block/sculk_extractor_bottom.png and /dev/null differ diff --git a/src/main/resources/assets/anvilcraft_pigsplus/textures/block/sculk_extractor_side.png b/src/main/resources/assets/anvilcraft_pigsplus/textures/block/sculk_extractor_side.png deleted file mode 100644 index e5e37a17..00000000 Binary files a/src/main/resources/assets/anvilcraft_pigsplus/textures/block/sculk_extractor_side.png and /dev/null differ diff --git a/src/main/resources/assets/anvilcraft_pigsplus/textures/block/sculk_extractor_top.png b/src/main/resources/assets/anvilcraft_pigsplus/textures/block/sculk_extractor_top.png deleted file mode 100644 index 36b0095a..00000000 Binary files a/src/main/resources/assets/anvilcraft_pigsplus/textures/block/sculk_extractor_top.png and /dev/null differ diff --git a/src/main/resources/data/anvilcraft_pigsplus/recipe/anvilcraft_alloyextension/ender_component.json b/src/main/resources/data/anvilcraft_pigsplus/recipe/anvilcraft_alloyextension/ender_component.json index b81fa36c..b6c8eec6 100644 --- a/src/main/resources/data/anvilcraft_pigsplus/recipe/anvilcraft_alloyextension/ender_component.json +++ b/src/main/resources/data/anvilcraft_pigsplus/recipe/anvilcraft_alloyextension/ender_component.json @@ -1,24 +1,24 @@ { - "neoforge:conditions": [ - { - "type": "neoforge:mod_loaded", - "modid": "anvilcraft_alloyextension" - } - ], - "type": "anvilcraft:time_warp", - "ingredients": [ - { - "count": 6, - "items": "anvilcraft_alloyextension:ender_dust" - }, - { - "count": 18, - "items": "minecraft:end_stone" - } - ], - "results": [ - { - "id": "anvilcraft_pigsplus:ender_component" - } - ] + "neoforge:conditions": [ + { + "type": "neoforge:mod_loaded", + "modid": "anvilcraft_alloyextension" + } + ], + "type": "anvilcraft:time_warp", + "ingredients": [ + { + "count": 6, + "items": "anvilcraft_alloyextension:ender_dust" + }, + { + "count": 18, + "items": "minecraft:end_stone" + } + ], + "results": [ + { + "id": "anvilcraft_pigsplus:ender_component" + } + ] } \ No newline at end of file diff --git a/src/main/resources/data/anvilcraft_pigsplus/recipe/anvilcraft_alloyextension/item_transporter.json b/src/main/resources/data/anvilcraft_pigsplus/recipe/anvilcraft_alloyextension/item_transporter.json index 7c97a01f..bbe333b8 100644 --- a/src/main/resources/data/anvilcraft_pigsplus/recipe/anvilcraft_alloyextension/item_transporter.json +++ b/src/main/resources/data/anvilcraft_pigsplus/recipe/anvilcraft_alloyextension/item_transporter.json @@ -1,30 +1,30 @@ { - "neoforge:conditions": [ - { - "type": "neoforge:mod_loaded", - "modid": "anvilcraft_alloyextension" - } - ], - "type": "minecraft:crafting_shaped", - "category": "building", - "key": { - "I": { - "item": "minecraft:iron_ingot" - }, - "E": { - "item": "anvilcraft_pigsplus:ender_component" + "neoforge:conditions": [ + { + "type": "neoforge:mod_loaded", + "modid": "anvilcraft_alloyextension" + } + ], + "type": "minecraft:crafting_shaped", + "category": "building", + "key": { + "I": { + "item": "minecraft:iron_ingot" + }, + "E": { + "item": "anvilcraft_pigsplus:ender_component" + }, + "S": { + "item": "anvilcraft:magnetic_chute" + } }, - "S": { - "item": "anvilcraft:magnetic_chute" + "pattern": [ + " ", + " E ", + "ISI" + ], + "result": { + "count": 8, + "id": "anvilcraft_alloyextension:item_transporter" } - }, - "pattern": [ - " ", - " E ", - "ISI" - ], - "result": { - "count": 8, - "id": "anvilcraft_alloyextension:item_transporter" - } } \ No newline at end of file diff --git a/src/main/resources/data/anvilcraft_pigsplus/recipe/anvilcraftextrapower/lead_acid_battery_empty.json b/src/main/resources/data/anvilcraft_pigsplus/recipe/anvilcraftextrapower/lead_acid_battery_empty.json new file mode 100644 index 00000000..97356c7e --- /dev/null +++ b/src/main/resources/data/anvilcraft_pigsplus/recipe/anvilcraftextrapower/lead_acid_battery_empty.json @@ -0,0 +1,27 @@ +{ + "neoforge:conditions": [ + { + "type": "neoforge:mod_loaded", + "modid": "anvilcraftextrapower" + } + ], + "type": "anvilcraft_pigsplus:precision_electromagnetic_processing", + "consume": 250, + "fluid": "minecraft:water", + "ingredients": [ + { + "items": "#c:ingots/lead" + }, + { + "items": "#c:sulfur" + }, + { + "items": "anvilcraft:royal_steel_ingot" + } + ], + "results": [ + { + "id": "anvilcraftextrapower:lead_acid_battery_empty" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/data/anvilcraft_pigsplus/recipe/anvilcraftextrapower/multiphase_capacitor_empty.json b/src/main/resources/data/anvilcraft_pigsplus/recipe/anvilcraftextrapower/multiphase_capacitor_empty.json new file mode 100644 index 00000000..e2769991 --- /dev/null +++ b/src/main/resources/data/anvilcraft_pigsplus/recipe/anvilcraftextrapower/multiphase_capacitor_empty.json @@ -0,0 +1,24 @@ +{ + "neoforge:conditions": [ + { + "type": "neoforge:mod_loaded", + "modid": "anvilcraftextrapower" + } + ], + "type": "anvilcraft_pigsplus:precision_electromagnetic_processing", + "ingredients": [ + { + "count": 2, + "items": "#c:ingots/lead" + }, + { + "items": "anvilcraft:multiphase_matter" + } + ], + "results": [ + { + "count": 2, + "id": "anvilcraftextrapower:multiphase_capacitor_empty" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/data/anvilcraft_pigsplus/recipe/anvilcraftextrapower/potato_battery.json b/src/main/resources/data/anvilcraft_pigsplus/recipe/anvilcraftextrapower/potato_battery.json new file mode 100644 index 00000000..20cf8510 --- /dev/null +++ b/src/main/resources/data/anvilcraft_pigsplus/recipe/anvilcraftextrapower/potato_battery.json @@ -0,0 +1,26 @@ +{ + "neoforge:conditions": [ + { + "type": "neoforge:mod_loaded", + "modid": "anvilcraftextrapower" + } + ], + "type": "anvilcraft_pigsplus:precision_electromagnetic_processing", + "ingredients": [ + { + "items": "#c:ingots/copper" + }, + { + "items": "#c:ingots/zinc" + }, + { + "items": "#c:crops/potato" + } + ], + "results": [ + { + "count": 2, + "id": "anvilcraftextrapower:potato_battery" + } + ] +} \ No newline at end of file