diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 00000000..c127c3f9 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,35 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: bug +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Desktop (please complete the following information):** + - OS: [e.g. Linux] + - Minecraft [e.g. 1.16.4] + - Fabric Loader version [e.g. 0.10.6+build.214] + - Mods [e.g. fabric-api v0.25.1+build.416-1.16, lambdynamiclights v1.3.2, modmenu v1.14.6+build.31] + - Version [e.g. 1.3.2] + - Branch [e.g. mc1.16] + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 00000000..11fc491e --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: enhancement +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. diff --git a/API.md b/API.md index 4512ede9..3fa822e8 100644 --- a/API.md +++ b/API.md @@ -6,12 +6,28 @@ Then try the API of this mod! ## Quick note -Every time entity is referenced it means either an entity or a block entity. +Every time an entity is referenced it means either an entity or a block entity. Block entity dynamic lighting is non-recommended if avoidable with block states. If your entity re-implements tick without calling the super method the dynamic light handler will not work. +## LambDynamicLights entrypoint + +Any API calls should be done in the custom entrypoint. + +To use the entrypoint, make a new class implementing `DynamicLightsInitializer`, +add in your `fabric.mod.json` this: +```json + "entrypoints": { + "dynamiclights": [ + "path.to.your.Class" + ] + } +``` + +Once done, you can call the methods presented in the rest of this document in the method `onInitializeDynamicLights`. + ## Dynamic light handlers ### `DynamicLightHandler` diff --git a/CHANGELOG.md b/CHANGELOG.md index d7be7962..e4b8ef5d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -64,6 +64,15 @@ - Fixed entity lighting issue with [Sodium] 0.1.0. ([#23](https://github.com/LambdAurora/LambDynamicLights/issues/23)) +## v1.3.2 + + - Added entity lighting capabilities to minecarts. + - Added `DynamicLightsInitializer` and `dynamiclights` entrypoint. + - Added Estonian translations. + - Added Turkish translations. + - Updated French translations. + - Fixed memory leak in dynamic light source tracking. ([#30](https://github.com/LambdAurora/LambDynamicLights/issues/30)) + [SpruceUI]: https://github.com/LambdAurora/SpruceUI "SpruceUI page" [Sodium]: https://www.curseforge.com/minecraft/mc-mods/sodium "Sodium CurseForge page" [Canvas Renderer]: https://www.curseforge.com/minecraft/mc-mods/canvas-renderer "Canvas Renderer CurseForge page" diff --git a/HEADER b/HEADER new file mode 100644 index 00000000..73a4a9bb --- /dev/null +++ b/HEADER @@ -0,0 +1,6 @@ +Copyright © 2020 LambdAurora + +This file is part of LambDynamicLights. + +Licensed under the MIT license. For more information, +see the LICENSE file. \ No newline at end of file diff --git a/build.gradle b/build.gradle index 620d3005..f0f9d15d 100644 --- a/build.gradle +++ b/build.gradle @@ -4,6 +4,7 @@ plugins { id 'fabric-loom' version '0.4-SNAPSHOT' id 'java-library' id 'maven-publish' + id 'net.minecrell.licenser' version '0.4.1' } group = project.maven_group @@ -96,6 +97,11 @@ jar { from "../LICENSE" } +license { + header file('HEADER') + include '**/*.java' +} + task shadowJar(type: Jar) { archiveClassifier.set("dev") diff --git a/gradle.properties b/gradle.properties index aa59ad11..ae65d97f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,17 +3,17 @@ org.gradle.jvmargs=-Xmx1G # Fabric Properties # check these on https://fabricmc.net/use -minecraft_version=1.16.3 -yarn_mappings=1.16.3+build.17 -loader_version=0.9.3+build.207 +minecraft_version=1.16.4 +yarn_mappings=1.16.4+build.3 +loader_version=0.10.6+build.214 # Mod Properties -mod_version = 1.3.1 +mod_version = 1.3.2 maven_group = me.lambdaurora archives_base_name = lambdynamiclights # Dependencies # currently not on the main fabric site, check on the maven: https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api -fabric_version=0.20.2+build.402-1.16 +fabric_version=0.25.1+build.416-1.16 spruceui_version=1.6.4 modmenu_version=1.14.6+build.31 diff --git a/src/main/java/me/lambdaurora/lambdynlights/DynamicLightSource.java b/src/main/java/me/lambdaurora/lambdynlights/DynamicLightSource.java index c0511430..e9dbade4 100644 --- a/src/main/java/me/lambdaurora/lambdynlights/DynamicLightSource.java +++ b/src/main/java/me/lambdaurora/lambdynlights/DynamicLightSource.java @@ -17,7 +17,7 @@ * Represents a dynamic light source. * * @author LambdAurora - * @version 1.1.0 + * @version 1.3.2 * @since 1.0.0 */ public interface DynamicLightSource @@ -98,7 +98,7 @@ default void setDynamicLightEnabled(boolean enabled) */ boolean shouldUpdateDynamicLight(); - void lambdynlights_updateDynamicLight(@NotNull WorldRenderer renderer); + boolean lambdynlights_updateDynamicLight(@NotNull WorldRenderer renderer); void lambdynlights_scheduleTrackedChunksRebuild(@NotNull WorldRenderer renderer); } diff --git a/src/main/java/me/lambdaurora/lambdynlights/DynamicLightsConfig.java b/src/main/java/me/lambdaurora/lambdynlights/DynamicLightsConfig.java index c32e24e9..4bc88e53 100644 --- a/src/main/java/me/lambdaurora/lambdynlights/DynamicLightsConfig.java +++ b/src/main/java/me/lambdaurora/lambdynlights/DynamicLightsConfig.java @@ -14,39 +14,35 @@ import net.minecraft.client.options.Option; import net.minecraft.text.LiteralText; import net.minecraft.text.TranslatableText; -import net.minecraft.util.Identifier; import org.jetbrains.annotations.NotNull; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.Arrays; -import java.util.List; -import java.util.stream.Collectors; /** * Represents the mod configuration. * * @author LambdAurora - * @version 1.3.0 + * @version 1.3.2 * @since 1.0.0 */ public class DynamicLightsConfig { - private static final DynamicLightsMode DEFAULT_DYNAMIC_LIGHTS_MODE = DynamicLightsMode.OFF; - private static final boolean DEFAULT_ENTITIES_LIGHT_SOURCE = true; - private static final boolean DEFAULT_BLOCK_ENTITIES_LIGHT_SOURCE = true; - private static final boolean DEFAULT_WATER_SENSITIVE_CHECK = true; - private static final ExplosiveLightingMode DEFAULT_CREEPER_LIGHTING_MODE = ExplosiveLightingMode.SIMPLE; - private static final ExplosiveLightingMode DEFAULT_TNT_LIGHTING_MODE = ExplosiveLightingMode.OFF; - - public static final Path CONFIG_FILE_PATH = Paths.get("config/lambdynlights.toml"); - protected final FileConfig config; - private final LambDynLights mod; - private boolean firstTime; - private DynamicLightsMode dynamicLightsMode; - private ExplosiveLightingMode creeperLightingMode; - private ExplosiveLightingMode tntLightingMode; + private static final DynamicLightsMode DEFAULT_DYNAMIC_LIGHTS_MODE = DynamicLightsMode.OFF; + private static final boolean DEFAULT_ENTITIES_LIGHT_SOURCE = true; + private static final boolean DEFAULT_BLOCK_ENTITIES_LIGHT_SOURCE = true; + private static final boolean DEFAULT_WATER_SENSITIVE_CHECK = true; + private static final ExplosiveLightingMode DEFAULT_CREEPER_LIGHTING_MODE = ExplosiveLightingMode.SIMPLE; + private static final ExplosiveLightingMode DEFAULT_TNT_LIGHTING_MODE = ExplosiveLightingMode.OFF; + + public static final Path CONFIG_FILE_PATH = Paths.get("config/lambdynlights.toml"); + protected final FileConfig config; + private final LambDynLights mod; + private boolean firstTime; + private DynamicLightsMode dynamicLightsMode; + private ExplosiveLightingMode creeperLightingMode; + private ExplosiveLightingMode tntLightingMode; public final Option dynamicLightsModeOption = new SpruceCyclingOption("lambdynlights.option.mode", amount -> this.setDynamicLightsMode(this.dynamicLightsMode.next()), @@ -136,13 +132,13 @@ public DynamicLightsMode getDynamicLightsMode() */ public void setDynamicLightsMode(@NotNull DynamicLightsMode mode) { - this.dynamicLightsMode = mode; - this.config.set("mode", mode.getName()); - if (!mode.isEnabled()) { this.mod.clearLightSources(); } + this.dynamicLightsMode = mode; + this.config.set("mode", mode.getName()); + this.firstTime = false; } diff --git a/src/main/java/me/lambdaurora/lambdynlights/LambDynLights.java b/src/main/java/me/lambdaurora/lambdynlights/LambDynLights.java index 01f336a2..77b76ebe 100644 --- a/src/main/java/me/lambdaurora/lambdynlights/LambDynLights.java +++ b/src/main/java/me/lambdaurora/lambdynlights/LambDynLights.java @@ -12,11 +12,14 @@ import it.unimi.dsi.fastutil.longs.LongOpenHashSet; import me.lambdaurora.lambdynlights.accessor.WorldRendererAccessor; import me.lambdaurora.lambdynlights.api.DynamicLightHandlers; +import me.lambdaurora.lambdynlights.api.DynamicLightsInitializer; import me.lambdaurora.lambdynlights.api.item.ItemLightSources; import net.fabricmc.api.ClientModInitializer; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; import net.fabricmc.fabric.api.resource.ResourceManagerHelper; import net.fabricmc.fabric.api.resource.SimpleSynchronousResourceReloadListener; +import net.fabricmc.loader.api.FabricLoader; +import net.fabricmc.loader.api.entrypoint.EntrypointContainer; import net.minecraft.block.entity.BlockEntity; import net.minecraft.client.MinecraftClient; import net.minecraft.client.render.LightmapTextureManager; @@ -41,26 +44,29 @@ import org.jetbrains.annotations.Nullable; import java.util.Iterator; +import java.util.List; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.function.Predicate; +import java.util.stream.Collectors; /** * Represents the LambDynamicLights mod. * * @author LambdAurora - * @version 1.3.1 + * @version 1.3.2 * @since 1.0.0 */ public class LambDynLights implements ClientModInitializer { - public static final String MODID = "lambdynlights"; - private static final double MAX_RADIUS = 7.75; - private static LambDynLights INSTANCE; - public final Logger logger = LogManager.getLogger(MODID); - public final DynamicLightsConfig config = new DynamicLightsConfig(this); - private final ConcurrentLinkedQueue dynamicLightSources = new ConcurrentLinkedQueue<>(); - private long lastUpdate = System.currentTimeMillis(); - private boolean notifiedFirstTime = false; + public static final String MODID = "lambdynlights"; + private static final double MAX_RADIUS = 7.75; + private static LambDynLights INSTANCE; + public final Logger logger = LogManager.getLogger(MODID); + public final DynamicLightsConfig config = new DynamicLightsConfig(this); + private final ConcurrentLinkedQueue dynamicLightSources = new ConcurrentLinkedQueue<>(); + private long lastUpdate = System.currentTimeMillis(); + private int lastUpdateCount = 0; + private boolean notifiedFirstTime = false; @Override public void onInitializeClient() @@ -82,6 +88,10 @@ public void onInitializeClient() } }); + FabricLoader.getInstance().getEntrypointContainers("dynamiclights", DynamicLightsInitializer.class) + .stream().map(EntrypointContainer::getEntrypoint) + .forEach(DynamicLightsInitializer::onInitializeDynamicLights); + ResourceManagerHelper.get(ResourceType.CLIENT_RESOURCES).registerReloadListener(new SimpleSynchronousResourceReloadListener() { @Override @@ -113,17 +123,28 @@ public void updateAll(@NotNull WorldRenderer renderer) long now = System.currentTimeMillis(); if (now >= this.lastUpdate + 50) { this.lastUpdate = now; + this.lastUpdateCount = 0; for (DynamicLightSource lightSource : this.dynamicLightSources) { - lightSource.lambdynlights_updateDynamicLight(renderer); + if (lightSource.lambdynlights_updateDynamicLight(renderer)) this.lastUpdateCount++; } } } + /** + * Returns the last number of dynamic light source updates. + * + * @return The last number of dynamic light source updates. + */ + public int getLastUpdateCount() + { + return this.lastUpdateCount; + } + /** * Returns the lightmap with combined light levels. * - * @param pos The position. + * @param pos The position. * @param lightmap The vanilla lightmap. * @return The modified lightmap. */ @@ -135,7 +156,7 @@ public int getLightmapWithDynamicLight(@NotNull BlockPos pos, int lightmap) /** * Returns the lightmap with combined light levels. * - * @param entity The entity. + * @param entity The entity. * @param lightmap The vanilla lightmap. * @return The */ @@ -151,7 +172,7 @@ public int getLightmapWithDynamicLight(@NotNull Entity entity, int lightmap) * Returns the lightmap with combined light levels. * * @param dynamicLightLevel The dynamic light level. - * @param lightmap The vanilla lightmap. + * @param lightmap The vanilla lightmap. * @return The modified lightmap. */ public int getLightmapWithDynamicLight(double dynamicLightLevel, int lightmap) @@ -191,8 +212,8 @@ public double getDynamicLightLevel(@NotNull BlockPos pos) /** * Returns the dynamic light level generated by the light source at the specified position. * - * @param pos The position. - * @param lightSource The light source. + * @param pos The position. + * @param lightSource The light source. * @param currentLightLevel The current surrounding dynamic light level. * @return The dynamic light level. */ @@ -259,6 +280,16 @@ public boolean containsLightSource(@NotNull DynamicLightSource lightSource) return this.dynamicLightSources.contains(lightSource); } + /** + * Returns the number of dynamic light sources that currently emit lights. + * + * @return The number of dynamic light sources emitting light. + */ + public int getLightSourcesCount() + { + return this.dynamicLightSources.size(); + } + /** * Removes the light source from the tracked light sources. * @@ -289,9 +320,11 @@ public void clearLightSources() while (dynamicLightSources.hasNext()) { it = dynamicLightSources.next(); dynamicLightSources.remove(); - if (MinecraftClient.getInstance().worldRenderer != null) + if (MinecraftClient.getInstance().worldRenderer != null) { + if (it.getLuminance() > 0) + it.resetDynamicLight(); it.lambdynlights_scheduleTrackedChunksRebuild(MinecraftClient.getInstance().worldRenderer); - break; + } } } @@ -308,8 +341,11 @@ public void removeLightSources(@NotNull Predicate filter) it = dynamicLightSources.next(); if (filter.test(it)) { dynamicLightSources.remove(); - if (MinecraftClient.getInstance().worldRenderer != null) + if (MinecraftClient.getInstance().worldRenderer != null) { + if (it.getLuminance() > 0) + it.resetDynamicLight(); it.lambdynlights_scheduleTrackedChunksRebuild(MinecraftClient.getInstance().worldRenderer); + } break; } } @@ -382,8 +418,8 @@ public static void scheduleChunkRebuild(@NotNull WorldRenderer renderer, @NotNul * Updates the tracked chunk sets. * * @param chunkPos The chunk position. - * @param old The set of old chunk coordinates to remove this chunk from it. - * @param newPos The set of new chunk coordinates to add this chunk to it. + * @param old The set of old chunk coordinates to remove this chunk from it. + * @param newPos The set of new chunk coordinates to add this chunk to it. */ public static void updateTrackedChunks(@NotNull BlockPos chunkPos, @Nullable LongOpenHashSet old, @Nullable LongOpenHashSet newPos) { @@ -413,7 +449,7 @@ public static void updateTracking(@NotNull DynamicLightSource lightSource) /** * Returns the luminance from an item stack. * - * @param stack The item stack. + * @param stack The item stack. * @param submergedInWater True if the stack is submerged in water, else false. * @return The luminance of the item. */ diff --git a/src/main/java/me/lambdaurora/lambdynlights/api/DynamicLightHandlers.java b/src/main/java/me/lambdaurora/lambdynlights/api/DynamicLightHandlers.java index 6335c121..c4c700ac 100644 --- a/src/main/java/me/lambdaurora/lambdynlights/api/DynamicLightHandlers.java +++ b/src/main/java/me/lambdaurora/lambdynlights/api/DynamicLightHandlers.java @@ -24,14 +24,19 @@ /** * @author LambdAurora - * @version 1.3.0 + * @version 1.3.2 * @since 1.1.0 */ public final class DynamicLightHandlers { - private static Map, DynamicLightHandler> ENTITES_HANDLER = new HashMap<>(); + private static Map, DynamicLightHandler> ENTITES_HANDLER = new HashMap<>(); private static Map, DynamicLightHandler> BLOCK_ENTITIES_HANDLER = new HashMap<>(); + private DynamicLightHandlers() + { + throw new UnsupportedOperationException("DynamicLightHandlers only contains static definitions."); + } + /** * Registers the default handlers. */ @@ -57,9 +62,9 @@ public static void registerDefaultHandlers() /** * Registers an entity dynamic light handler. * - * @param type The entity type. + * @param type The entity type. * @param handler The dynamic light handler. - * @param The type of the entity. + * @param The type of the entity. */ public static void registerDynamicLightHandler(@NotNull EntityType type, @NotNull DynamicLightHandler handler) { @@ -74,9 +79,9 @@ public static void registerDynamicLightHandler(@NotNull Entit /** * Registers a block entity dynamic light handler. * - * @param type The block entity type. + * @param type The block entity type. * @param handler The dynamic light handler. - * @param The type of the block entity. + * @param The type of the block entity. */ public static void registerDynamicLightHandler(@NotNull BlockEntityType type, @NotNull DynamicLightHandler handler) { @@ -92,7 +97,7 @@ public static void registerDynamicLightHandler(@NotNull * Returns the registered dynamic light handler of the specified entity. * * @param type The entity type. - * @param The type of the entity. + * @param The type of the entity. * @return The registered dynamic light handler. */ @SuppressWarnings("unchecked") @@ -105,7 +110,7 @@ public static void registerDynamicLightHandler(@NotNull * Returns the registered dynamic light handler of the specified block entity. * * @param type The block entity type. - * @param The type of the block entity. + * @param The type of the block entity. * @return The registered dynamic light handler. */ @SuppressWarnings("unchecked") @@ -118,7 +123,7 @@ public static void registerDynamicLightHandler(@NotNull * Returns the luminance from an entity. * * @param entity The entity. - * @param The type of the entity. + * @param The type of the entity. * @return The luminance. */ @SuppressWarnings("unchecked") @@ -138,7 +143,7 @@ public static int getLuminanceFrom(@NotNull T entity) * Returns the luminance from a block entity. * * @param entity The block entity. - * @param The type of the block entity. + * @param The type of the block entity. * @return The luminance. */ @SuppressWarnings("unchecked") diff --git a/src/main/java/me/lambdaurora/lambdynlights/api/DynamicLightsInitializer.java b/src/main/java/me/lambdaurora/lambdynlights/api/DynamicLightsInitializer.java new file mode 100644 index 00000000..5b67909a --- /dev/null +++ b/src/main/java/me/lambdaurora/lambdynlights/api/DynamicLightsInitializer.java @@ -0,0 +1,34 @@ +/* + * Copyright © 2020 LambdAurora + * + * This file is part of LambDynamicLights. + * + * Licensed under the MIT license. For more information, + * see the LICENSE file. + */ + +package me.lambdaurora.lambdynlights.api; + +import me.lambdaurora.lambdynlights.api.item.ItemLightSource; +import me.lambdaurora.lambdynlights.api.item.ItemLightSources; +import net.minecraft.block.entity.BlockEntityType; +import net.minecraft.entity.EntityType; + +/** + * Represents the entrypoint for LambDynamicLights API. + * + * @author LambdAurora + * @version 1.3.2 + * @since 1.3.2 + */ +public interface DynamicLightsInitializer +{ + /** + * Method called when LambDynamicLights is initialized to register custom dynamic light handlers and item light sources. + * + * @see DynamicLightHandlers#registerDynamicLightHandler(EntityType, DynamicLightHandler) + * @see DynamicLightHandlers#registerDynamicLightHandler(BlockEntityType, DynamicLightHandler) + * @see ItemLightSources#registerItemLightSource(ItemLightSource) + */ + void onInitializeDynamicLights(); +} diff --git a/src/main/java/me/lambdaurora/lambdynlights/api/item/ItemLightSources.java b/src/main/java/me/lambdaurora/lambdynlights/api/item/ItemLightSources.java index d52170f0..3d1e6790 100644 --- a/src/main/java/me/lambdaurora/lambdynlights/api/item/ItemLightSources.java +++ b/src/main/java/me/lambdaurora/lambdynlights/api/item/ItemLightSources.java @@ -30,14 +30,19 @@ * Represents an item light sources manager. * * @author LambdAurora - * @version 1.3.1 + * @version 1.3.2 * @since 1.3.0 */ public final class ItemLightSources { - private static final List ITEM_LIGHT_SOURCES = new ArrayList<>(); + private static final List ITEM_LIGHT_SOURCES = new ArrayList<>(); private static final List STATIC_ITEM_LIGHT_SOURCES = new ArrayList<>(); + private ItemLightSources() + { + throw new UnsupportedOperationException("ItemLightSources only contains static definitions."); + } + /** * Loads the item light source data from resource pack. * @@ -112,7 +117,7 @@ public static void registerItemLightSource(@NotNull ItemLightSource data) /** * Returns the luminance of the item in the stack. * - * @param stack The item stack. + * @param stack The item stack. * @param submergedInWater True if the stack is submerged in water, else false. * @return A luminance value. */ diff --git a/src/main/java/me/lambdaurora/lambdynlights/mixin/ClientWorldMixin.java b/src/main/java/me/lambdaurora/lambdynlights/mixin/ClientWorldMixin.java new file mode 100644 index 00000000..b27dc544 --- /dev/null +++ b/src/main/java/me/lambdaurora/lambdynlights/mixin/ClientWorldMixin.java @@ -0,0 +1,29 @@ +/* + * Copyright © 2020 LambdAurora + * + * This file is part of LambDynamicLights. + * + * Licensed under the MIT license. For more information, + * see the LICENSE file. + */ + +package me.lambdaurora.lambdynlights.mixin; + +import me.lambdaurora.lambdynlights.DynamicLightSource; +import net.minecraft.client.world.ClientWorld; +import net.minecraft.entity.Entity; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(ClientWorld.class) +public class ClientWorldMixin +{ + @Inject(method = "finishRemovingEntity", at = @At("RETURN")) + private void onFinishRemovingEntity(Entity entity, CallbackInfo ci) + { + DynamicLightSource dls = (DynamicLightSource) entity; + dls.setDynamicLightEnabled(false); + } +} diff --git a/src/main/java/me/lambdaurora/lambdynlights/mixin/DebugHudMixin.java b/src/main/java/me/lambdaurora/lambdynlights/mixin/DebugHudMixin.java new file mode 100644 index 00000000..454393b1 --- /dev/null +++ b/src/main/java/me/lambdaurora/lambdynlights/mixin/DebugHudMixin.java @@ -0,0 +1,52 @@ +/* + * Copyright © 2020 LambdAurora + * + * This file is part of LambDynamicLights. + * + * Licensed under the MIT license. For more information, + * see the LICENSE file. + */ + +package me.lambdaurora.lambdynlights.mixin; + +import me.lambdaurora.lambdynlights.LambDynLights; +import net.minecraft.client.gui.hud.DebugHud; +import net.minecraft.util.Formatting; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import java.util.List; + +/** + * Adds a debug string for dynamic light sources tracking and updates. + * + * @author LambdAurora + * @version 1.3.2 + * @since 1.3.2 + */ +@Mixin(DebugHud.class) +public class DebugHudMixin +{ + @Inject(method = "getLeftText", at = @At("RETURN")) + private void onGetLeftText(CallbackInfoReturnable> cir) + { + List list = cir.getReturnValue(); + LambDynLights ldl = LambDynLights.get(); + StringBuilder builder = new StringBuilder("Dynamic Light Sources: "); + builder.append(ldl.getLightSourcesCount()) + .append(" (U: ") + .append(ldl.getLastUpdateCount()); + + if (!ldl.config.getDynamicLightsMode().isEnabled()) { + builder.append(" ; "); + builder.append(Formatting.RED); + builder.append("Disabled"); + builder.append(Formatting.RESET); + } + + builder.append(')'); + list.add(builder.toString()); + } +} diff --git a/src/main/java/me/lambdaurora/lambdynlights/mixin/MinecraftClientMixin.java b/src/main/java/me/lambdaurora/lambdynlights/mixin/MinecraftClientMixin.java new file mode 100644 index 00000000..41e2cdea --- /dev/null +++ b/src/main/java/me/lambdaurora/lambdynlights/mixin/MinecraftClientMixin.java @@ -0,0 +1,36 @@ +/* + * Copyright © 2020 LambdAurora + * + * This file is part of LambDynamicLights. + * + * Licensed under the MIT license. For more information, + * see the LICENSE file. + */ + +package me.lambdaurora.lambdynlights.mixin; + +import me.lambdaurora.lambdynlights.LambDynLights; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.world.ClientWorld; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +/** + * Mixin to MinecraftClient. + *

+ * Goal: clear light sources cache when changing world. + * + * @author LambdAurora + * @version 1.3.2 + * @since 1.3.2 + */ +@Mixin(MinecraftClient.class) +public class MinecraftClientMixin +{ + @Inject(method = "setWorld", at = @At("HEAD")) + private void onSetWorld(ClientWorld world, CallbackInfo ci) { + LambDynLights.get().clearLightSources(); + } +} diff --git a/src/main/java/me/lambdaurora/lambdynlights/mixin/lightsource/AbstractDecorationEntityMixin.java b/src/main/java/me/lambdaurora/lambdynlights/mixin/lightsource/AbstractDecorationEntityMixin.java index a896bb66..3159df1c 100644 --- a/src/main/java/me/lambdaurora/lambdynlights/mixin/lightsource/AbstractDecorationEntityMixin.java +++ b/src/main/java/me/lambdaurora/lambdynlights/mixin/lightsource/AbstractDecorationEntityMixin.java @@ -31,8 +31,8 @@ public AbstractDecorationEntityMixin(EntityType type, World world) @Inject(method = "tick", at = @At("TAIL")) private void onTick(CallbackInfo ci) { + // We do not want to update the entity on the server. if (this.getEntityWorld().isClient()) { - // We do not want to update the entity on the server. if (this.removed) { this.setDynamicLightEnabled(false); } else { diff --git a/src/main/java/me/lambdaurora/lambdynlights/mixin/lightsource/AbstractMinecartEntityMixin.java b/src/main/java/me/lambdaurora/lambdynlights/mixin/lightsource/AbstractMinecartEntityMixin.java new file mode 100644 index 00000000..ac8ce443 --- /dev/null +++ b/src/main/java/me/lambdaurora/lambdynlights/mixin/lightsource/AbstractMinecartEntityMixin.java @@ -0,0 +1,51 @@ +/* + * Copyright © 2020 LambdAurora + * + * This file is part of LambDynamicLights. + * + * Licensed under the MIT license. For more information, + * see the LICENSE file. + */ + +package me.lambdaurora.lambdynlights.mixin.lightsource; + +import me.lambdaurora.lambdynlights.DynamicLightSource; +import me.lambdaurora.lambdynlights.LambDynLights; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.vehicle.AbstractMinecartEntity; +import net.minecraft.world.World; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +/** + * Adds the tick method for dynamic light source tracking in minecart entities. + * + * @author LambdAurora + * @version 1.3.2 + * @since 1.3.2 + */ +@Mixin(AbstractMinecartEntity.class) +public abstract class AbstractMinecartEntityMixin extends Entity implements DynamicLightSource +{ + public AbstractMinecartEntityMixin(EntityType type, World world) + { + super(type, world); + } + + @Inject(method = "tick", at = @At("TAIL")) + private void onTick(CallbackInfo ci) + { + // We do not want to update the entity on the server. + if (this.getEntityWorld().isClient()) { + if (this.removed) { + this.setDynamicLightEnabled(false); + } else { + this.dynamicLightTick(); + LambDynLights.updateTracking(this); + } + } + } +} diff --git a/src/main/java/me/lambdaurora/lambdynlights/mixin/lightsource/BlockEntityMixin.java b/src/main/java/me/lambdaurora/lambdynlights/mixin/lightsource/BlockEntityMixin.java index d16fd313..636c39cc 100644 --- a/src/main/java/me/lambdaurora/lambdynlights/mixin/lightsource/BlockEntityMixin.java +++ b/src/main/java/me/lambdaurora/lambdynlights/mixin/lightsource/BlockEntityMixin.java @@ -40,11 +40,11 @@ public abstract class BlockEntityMixin implements DynamicLightSource protected World world; @Shadow - protected boolean removed; - private int lambdynlights_luminance = 0; - private int lambdynlights_lastLuminance = 0; - private long lambdynlights_lastUpdate = 0; - private LongOpenHashSet trackedLitChunkPos = new LongOpenHashSet(); + protected boolean removed; + private int lambdynlights_luminance = 0; + private int lambdynlights_lastLuminance = 0; + private long lambdynlights_lastUpdate = 0; + private LongOpenHashSet trackedLitChunkPos = new LongOpenHashSet(); @Override public double getDynamicLightX() @@ -85,9 +85,9 @@ public void resetDynamicLight() @Override public void dynamicLightTick() { + // We do not want to update the entity on the server. if (this.world == null || !this.world.isClient()) return; - // We do not want to update the entity on the server. if (!this.removed) { this.lambdynlights_luminance = DynamicLightHandlers.getLuminanceFrom((BlockEntity) (Object) this); LambDynLights.updateTracking(this); @@ -122,10 +122,10 @@ public boolean shouldUpdateDynamicLight() } @Override - public void lambdynlights_updateDynamicLight(@NotNull WorldRenderer renderer) + public boolean lambdynlights_updateDynamicLight(@NotNull WorldRenderer renderer) { if (!this.shouldUpdateDynamicLight()) - return; + return false; int luminance = this.getLuminance(); @@ -160,7 +160,9 @@ public void lambdynlights_updateDynamicLight(@NotNull WorldRenderer renderer) // Schedules the rebuild of chunks. this.lambdynlights_scheduleTrackedChunksRebuild(renderer); + return true; } + return false; } @Override diff --git a/src/main/java/me/lambdaurora/lambdynlights/mixin/lightsource/EntityMixin.java b/src/main/java/me/lambdaurora/lambdynlights/mixin/lightsource/EntityMixin.java index 85c83e45..36daff80 100644 --- a/src/main/java/me/lambdaurora/lambdynlights/mixin/lightsource/EntityMixin.java +++ b/src/main/java/me/lambdaurora/lambdynlights/mixin/lightsource/EntityMixin.java @@ -63,19 +63,19 @@ public abstract class EntityMixin implements DynamicLightSource @Shadow public abstract BlockPos getBlockPos(); - private int lambdynlights_luminance = 0; - private int lambdynlights_lastLuminance = 0; - private long lambdynlights_lastUpdate = 0; - private double lambdynlights_prevX; - private double lambdynlights_prevY; - private double lambdynlights_prevZ; - private LongOpenHashSet trackedLitChunkPos = new LongOpenHashSet(); + private int lambdynlights_luminance = 0; + private int lambdynlights_lastLuminance = 0; + private long lambdynlights_lastUpdate = 0; + private double lambdynlights_prevX; + private double lambdynlights_prevY; + private double lambdynlights_prevZ; + private LongOpenHashSet trackedLitChunkPos = new LongOpenHashSet(); @Inject(method = "tick", at = @At("TAIL")) public void onTick(CallbackInfo ci) { + // We do not want to update the entity on the server. if (this.world.isClient()) { - // We do not want to update the entity on the server. if (this.removed) { this.setDynamicLightEnabled(false); } else { @@ -158,10 +158,10 @@ public int getLuminance() } @Override - public void lambdynlights_updateDynamicLight(@NotNull WorldRenderer renderer) + public boolean lambdynlights_updateDynamicLight(@NotNull WorldRenderer renderer) { if (!this.shouldUpdateDynamicLight()) - return; + return false; double deltaX = this.getX() - this.lambdynlights_prevX; double deltaY = this.getY() - this.lambdynlights_prevY; @@ -207,7 +207,9 @@ public void lambdynlights_updateDynamicLight(@NotNull WorldRenderer renderer) this.lambdynlights_scheduleTrackedChunksRebuild(renderer); // Update tracked lit chunks. this.trackedLitChunkPos = newPos; + return true; } + return false; } @Override diff --git a/src/main/java/me/lambdaurora/lambdynlights/mixin/lightsource/TntEntityMixin.java b/src/main/java/me/lambdaurora/lambdynlights/mixin/lightsource/TntEntityMixin.java index d2ee7b7d..327bc317 100644 --- a/src/main/java/me/lambdaurora/lambdynlights/mixin/lightsource/TntEntityMixin.java +++ b/src/main/java/me/lambdaurora/lambdynlights/mixin/lightsource/TntEntityMixin.java @@ -29,7 +29,7 @@ public abstract class TntEntityMixin extends Entity implements DynamicLightSourc private int fuseTimer; private double lambdynlights_startFuseTimer = 80.0; - private int lambdynlights_luminance; + private int lambdynlights_luminance; public TntEntityMixin(EntityType type, World world) { @@ -45,11 +45,11 @@ private void onNew(EntityType entityType, World world, Call @Inject(method = "tick", at = @At("TAIL")) private void onTick(CallbackInfo ci) { + // We do not want to update the entity on the server. if (this.getEntityWorld().isClient()) { if (!LambDynLights.get().config.getTntLightingMode().isEnabled()) return; - // We do not want to update the entity on the server. if (this.removed) { this.setDynamicLightEnabled(false); } else { diff --git a/src/main/resources/lambdynlights.lightsource.mixins.json b/src/main/resources/lambdynlights.lightsource.mixins.json index dc753596..a299d11d 100644 --- a/src/main/resources/lambdynlights.lightsource.mixins.json +++ b/src/main/resources/lambdynlights.lightsource.mixins.json @@ -4,6 +4,7 @@ "compatibilityLevel": "JAVA_8", "client": [ "AbstractDecorationEntityMixin", + "AbstractMinecartEntityMixin", "BlockEntityMixin", "EntityMixin", "ExplosiveProjectileEntityMixin", diff --git a/src/main/resources/lambdynlights.mixins.json b/src/main/resources/lambdynlights.mixins.json index f7b26c9b..ea2beeb2 100644 --- a/src/main/resources/lambdynlights.mixins.json +++ b/src/main/resources/lambdynlights.mixins.json @@ -4,9 +4,12 @@ "plugin": "me.lambdaurora.lambdynlights.LambDynLightsMixinPlugin", "compatibilityLevel": "JAVA_8", "client": [ + "ClientWorldMixin", "CommonWorldRendererMixin", + "DebugHudMixin", "EntityLighterMixin", "EntityRendererMixin", + "MinecraftClientMixin", "VideoOptionsScreenMixin", "WorldMixin", "WorldRendererMixin",