├── jitpack.yml ├── src └── main │ ├── resources │ ├── pack.mcmeta │ ├── assets │ │ └── tweakeroo │ │ │ └── icon.png │ ├── tweakeroo.accesswidener │ ├── fabric.mod.json │ └── mixins.tweakeroo.json │ └── java │ └── fi │ └── dy │ └── masa │ └── tweakeroo │ ├── util │ ├── ISignTextAccess.java │ ├── IDecorationEntity.java │ ├── IMinecraftClientInvoker.java │ ├── IGuiEditSign.java │ ├── DummyMovementInput.java │ ├── EntityRestriction.java │ ├── PotionRestriction.java │ ├── SnapAimMode.java │ ├── ItemRestriction.java │ ├── PlacementRestrictionMode.java │ ├── EasyPlacementProtocol.java │ ├── CreativeExtraItems.java │ └── CameraPreset.java │ ├── mixin │ ├── option │ │ ├── IMixinSimpleOption.java │ │ └── MixinGameOptions.java │ ├── block │ │ ├── IMixinPistonBlock.java │ │ ├── IMixinCommandBlockExecutor.java │ │ ├── IMixinAbstractBlock.java │ │ ├── MixinMobSpawnerLogic.java │ │ ├── MixinSculkSensor.java │ │ ├── MixinScaffoldingBlock.java │ │ ├── MixinPistonBlock.java │ │ ├── MixinNetherPortalBlock.java │ │ ├── MixinAbstractBlockState.java │ │ ├── MixinObserverBlock.java │ │ ├── MixinSlimeBlock.java │ │ ├── MixinHopperBlockEntity.java │ │ ├── MixinSignBlockEntity.java │ │ └── MixinStructureBlockBlockEntity.java │ ├── item │ │ ├── IMixinAxeItem.java │ │ ├── IMixinShovelItem.java │ │ ├── MixinItemGroup.java │ │ ├── MixinItem.java │ │ ├── MixinBundleItem.java │ │ ├── MixinBlockItem.java │ │ └── MixinItemStack.java │ ├── world │ │ ├── IMixinChunkLightProvider.java │ │ ├── IMixinClientWorld.java │ │ ├── MixinBuiltChunk.java │ │ ├── MixinDimensionEffects_Nether.java │ │ ├── MixinChunkBuilder_BuiltChunk.java │ │ ├── MixinClientWorld_Properties.java │ │ ├── MixinServerChunkLoadingManager.java │ │ ├── MixinLightingProvider.java │ │ ├── MixinUpdateStructureBlockC2SPacket.java │ │ ├── MixinWorld.java │ │ └── MixinClientWorld.java │ ├── screen │ │ ├── IMixinCustomizeFlatLevelScreen.java │ │ ├── MixinScreen.java │ │ ├── MixinPresetsScreen.java │ │ ├── MixinCreativeInventoryScreen.java │ │ ├── MixinChatScreen.java │ │ └── MixinAbstractSignEditScreen.java │ ├── fog │ │ ├── MixinStandardFogModifier.java │ │ ├── MixinAtmosphericFogModifier.java │ │ ├── MixinWaterFogModifier.java │ │ ├── MixinLavaFogModifier.java │ │ ├── MixinDarknessEffectFogModifier.java │ │ └── MixinFogRenderer.java │ ├── freecam │ │ ├── MixinCamera_freeCam.java │ │ ├── MixinJumpBar_freeCam.java │ │ ├── MixinExperienceBar_freeCam.java │ │ ├── MixinClientPlayerInteractionManager_freeCam.java │ │ ├── MixinPlayerEntity_freeCam.java │ │ ├── MixinLocatorBar_freeCam.java │ │ ├── MixinHeldItemRenderer_freeCam.java │ │ ├── MixinClientPlayerEntity_freeCam.java │ │ ├── MixinGameRenderer_freeCam.java │ │ ├── MixinInGameHud_freeCam.java │ │ └── MixinWorldRenderer_freeCam.java │ ├── input │ │ ├── MixinMouse.java │ │ ├── MixinCloneCommand.java │ │ ├── MixinFillCommand.java │ │ ├── MixinKeyboardInput.java │ │ └── MixinClientCommandSource.java │ ├── hud │ │ ├── MixinClientBossBar.java │ │ ├── MixinStatusEffectsDisplay.java │ │ ├── MixinBossBarHud.java │ │ ├── MixinTeleportSpectatorMenu.java │ │ ├── MixinChatHud.java │ │ └── MixinInGameHud.java │ ├── entity │ │ ├── MixinBlockAttachedEntity.java │ │ ├── MixinRavagerEntity.java │ │ ├── MixinTradeOffer.java │ │ ├── MixinPlayerAbilities.java │ │ ├── MixinBatEntity.java │ │ ├── MixinPlayerEntity.java │ │ └── MixinLivingEntity.java │ ├── network │ │ ├── MixinServerPlayNetworkHandler.java │ │ ├── MixinDataQueryHandler.java │ │ └── MixinClientCommonNetworkHandler.java │ └── render │ │ ├── MixinMobSpawnerBlockEntityRenderer.java │ │ ├── MixinExplosionEmitterParticle.java │ │ ├── MixinGameRenderer_ViewBob.java │ │ ├── MixinBeaconBlockEntityRenderer.java │ │ ├── MixinBlockEntityRenderManager.java │ │ ├── MixinWeatherRendering.java │ │ ├── MixinParticleManager.java │ │ ├── MixinHeldItemRenderer.java │ │ ├── MixinWindow.java │ │ ├── MixinGameRenderer.java │ │ └── MixinEntityRenderManager.java │ ├── compat │ └── modmenu │ │ └── ModMenuImpl.java │ ├── event │ └── ClientTickHandler.java │ ├── Reference.java │ ├── Tweakeroo.java │ ├── config │ └── ConfigBooleanClient.java │ ├── InitHandler.java │ ├── data │ └── DataManager.java │ ├── world │ └── FakeChunk.java │ └── gui │ └── widgets │ └── WidgetCameraPresetList.java ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── .gitignore ├── settings.gradle ├── .gitattributes ├── gradle.properties ├── README.md ├── .github └── workflows │ └── build.yml └── gradlew.bat /jitpack.yml: -------------------------------------------------------------------------------- 1 | before_install: 2 | - sdk install java 21.0.9-tem 3 | - sdk use java 21.0.9-tem 4 | -------------------------------------------------------------------------------- /src/main/resources/pack.mcmeta: -------------------------------------------------------------------------------- 1 | { 2 | "pack": { 3 | "pack_format": 11, 4 | "description": "Tweakeroo" 5 | } 6 | } -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sakura-ryoko/tweakeroo/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /src/main/resources/assets/tweakeroo/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sakura-ryoko/tweakeroo/HEAD/src/main/resources/assets/tweakeroo/icon.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | .settings 3 | bin/ 4 | build/ 5 | eclipse/ 6 | logs/ 7 | .classpath 8 | .project 9 | build.number 10 | run 11 | .vscode 12 | libs/ 13 | .idea/ 14 | run/ 15 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | maven { 4 | name = 'Fabric' 5 | url = 'https://maven.fabricmc.net/' 6 | } 7 | gradlePluginPortal() 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/main/resources/tweakeroo.accesswidener: -------------------------------------------------------------------------------- 1 | accessWidener v2 named 2 | accessible class net/minecraft/client/gui/components/ChatComponent$LineConsumer 3 | accessible class net/minecraft/client/gui/Gui$ContextualInfo 4 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/util/ISignTextAccess.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.util; 2 | 3 | import net.minecraft.world.level.block.entity.SignText; 4 | 5 | public interface ISignTextAccess 6 | { 7 | SignText tweakeroo$getText(boolean front); 8 | } 9 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/util/IDecorationEntity.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.util; 2 | 3 | import net.minecraft.core.BlockPos; 4 | 5 | /** 6 | * Copied From Tweak Fork by Andrew54757 7 | */ 8 | public interface IDecorationEntity 9 | { 10 | BlockPos tweakeroo$getAttached(); 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/util/IMinecraftClientInvoker.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.util; 2 | 3 | public interface IMinecraftClientInvoker 4 | { 5 | void tweakeroo_setItemUseCooldown(int value); 6 | 7 | boolean tweakeroo_invokeDoAttack(); 8 | 9 | void tweakeroo_invokeDoItemUse(); 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/util/IGuiEditSign.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.util; 2 | 3 | import net.minecraft.world.level.block.entity.SignBlockEntity; 4 | import net.minecraft.world.level.block.entity.SignText; 5 | 6 | public interface IGuiEditSign 7 | { 8 | SignBlockEntity tweakeroo$getTile(); 9 | 10 | void tweakeroo$applyText(SignText text); 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/option/IMixinSimpleOption.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.option; 2 | 3 | import net.minecraft.client.OptionInstance; 4 | import org.spongepowered.asm.mixin.Mixin; 5 | import org.spongepowered.asm.mixin.gen.Accessor; 6 | 7 | @Mixin(OptionInstance.class) 8 | public interface IMixinSimpleOption 9 | { 10 | @Accessor("value") 11 | void tweakeroo_setValueWithoutCheck(T value); 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/util/DummyMovementInput.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.util; 2 | 3 | import net.minecraft.client.Options; 4 | import net.minecraft.client.player.KeyboardInput; 5 | 6 | public class DummyMovementInput extends KeyboardInput 7 | { 8 | public DummyMovementInput(Options options) 9 | { 10 | super(options); 11 | } 12 | 13 | @Override 14 | public void tick() 15 | { 16 | // NO-OP 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/block/IMixinPistonBlock.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.block; 2 | 3 | import net.minecraft.world.level.block.piston.PistonBaseBlock; 4 | import org.spongepowered.asm.mixin.Mixin; 5 | import org.spongepowered.asm.mixin.gen.Accessor; 6 | 7 | /** 8 | * Copied From Tweak Fork by Andrew54757 9 | */ 10 | @Mixin(PistonBaseBlock.class) 11 | public interface IMixinPistonBlock 12 | { 13 | @Accessor("isSticky") 14 | boolean getSticky(); 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/item/IMixinAxeItem.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.item; 2 | 3 | import java.util.Map; 4 | import net.minecraft.world.item.AxeItem; 5 | import net.minecraft.world.level.block.Block; 6 | import org.spongepowered.asm.mixin.Mixin; 7 | import org.spongepowered.asm.mixin.gen.Accessor; 8 | 9 | @Mixin(AxeItem.class) 10 | public interface IMixinAxeItem 11 | { 12 | @Accessor("STRIPPABLES") 13 | static Map tweakeroo_getStrippedBlocks() { return null; } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/world/IMixinChunkLightProvider.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.world; 2 | 3 | import net.minecraft.world.level.chunk.LightChunkGetter; 4 | import net.minecraft.world.level.lighting.LightEngine; 5 | import org.spongepowered.asm.mixin.Mixin; 6 | import org.spongepowered.asm.mixin.gen.Accessor; 7 | 8 | @Mixin(LightEngine.class) 9 | public interface IMixinChunkLightProvider 10 | { 11 | @Accessor("chunkSource") 12 | LightChunkGetter tweakeroo_getChunkProvider(); 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/block/IMixinCommandBlockExecutor.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.block; 2 | 3 | import net.minecraft.world.level.BaseCommandBlock; 4 | import org.spongepowered.asm.mixin.Mixin; 5 | import org.spongepowered.asm.mixin.gen.Accessor; 6 | 7 | @Mixin(BaseCommandBlock.class) 8 | public interface IMixinCommandBlockExecutor 9 | { 10 | @Accessor("updateLastExecution") 11 | boolean getUpdateLastExecution(); 12 | 13 | @Accessor("updateLastExecution") 14 | void setUpdateLastExecution(boolean value); 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/screen/IMixinCustomizeFlatLevelScreen.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.screen; 2 | 3 | import net.minecraft.client.gui.screens.CreateFlatWorldScreen; 4 | import net.minecraft.client.gui.screens.worldselection.CreateWorldScreen; 5 | import org.spongepowered.asm.mixin.Mixin; 6 | import org.spongepowered.asm.mixin.gen.Accessor; 7 | 8 | @Mixin(CreateFlatWorldScreen.class) 9 | public interface IMixinCustomizeFlatLevelScreen 10 | { 11 | @Accessor("parent") 12 | CreateWorldScreen tweakeroo_getCreateWorldParent(); 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/item/IMixinShovelItem.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.item; 2 | 3 | import java.util.Map; 4 | import net.minecraft.world.item.ShovelItem; 5 | import net.minecraft.world.level.block.Block; 6 | import net.minecraft.world.level.block.state.BlockState; 7 | import org.spongepowered.asm.mixin.Mixin; 8 | import org.spongepowered.asm.mixin.gen.Accessor; 9 | 10 | @Mixin(ShovelItem.class) 11 | public interface IMixinShovelItem 12 | { 13 | @Accessor("FLATTENABLES") 14 | static Map tweakeroo_getPathStates() { return null; } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/world/IMixinClientWorld.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.world; 2 | 3 | import java.util.Map; 4 | import net.minecraft.client.multiplayer.ClientLevel; 5 | import net.minecraft.world.level.saveddata.maps.MapId; 6 | import net.minecraft.world.level.saveddata.maps.MapItemSavedData; 7 | import org.spongepowered.asm.mixin.Mixin; 8 | import org.spongepowered.asm.mixin.gen.Invoker; 9 | 10 | @Mixin(ClientLevel.class) 11 | public interface IMixinClientWorld 12 | { 13 | @Invoker("getAllMapData") 14 | Map tweakeroo_getMapStates(); 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/compat/modmenu/ModMenuImpl.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.compat.modmenu; 2 | 3 | import com.terraformersmc.modmenu.api.ConfigScreenFactory; 4 | import com.terraformersmc.modmenu.api.ModMenuApi; 5 | import fi.dy.masa.tweakeroo.gui.GuiConfigs; 6 | 7 | public class ModMenuImpl implements ModMenuApi 8 | { 9 | @Override 10 | public ConfigScreenFactory getModConfigScreenFactory() 11 | { 12 | return (screen) -> { 13 | GuiConfigs gui = new GuiConfigs(); 14 | gui.setParent(screen); 15 | return gui; 16 | }; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # text stuff 2 | * text=auto 3 | *.bat text eol=crlf 4 | *.groovy text eol=lf 5 | *.java text eol=crlf 6 | *.md text 7 | *.properties text eol=lf 8 | *.scala text eol=lf 9 | *.sh text eol=lf 10 | .gitattributes text eol=lf 11 | .gitignore text eol=lf 12 | build.gradle text eol=lf 13 | gradlew text eol=lf 14 | gradle/wrapper/gradle-wrapper.properties text eol=crlf 15 | COPYING.txt text eol=lf 16 | COPYING.LESSER.txt text eol=lf 17 | README.md text eol=lf 18 | 19 | #binary 20 | *.dat binary 21 | *.bin binary 22 | *.png binary 23 | *.exe binary 24 | *.dll binary 25 | *.zip binary 26 | *.jar binary 27 | *.7z binary 28 | *.db binary 29 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/event/ClientTickHandler.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.event; 2 | 3 | import fi.dy.masa.malilib.interfaces.IClientTickHandler; 4 | import fi.dy.masa.tweakeroo.tweaks.MiscTweaks; 5 | import fi.dy.masa.tweakeroo.tweaks.RenderTweaks; 6 | import net.minecraft.client.Minecraft; 7 | 8 | public class ClientTickHandler implements IClientTickHandler 9 | { 10 | @Override 11 | public void onClientTick(Minecraft mc) 12 | { 13 | if (mc.level != null && mc.player != null) 14 | { 15 | MiscTweaks.onTick(mc); 16 | RenderTweaks.onTick(); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs = -Xmx3G 2 | org.gradle.daemon = false 3 | org.gradle.cache.cleanup = false 4 | 5 | group = fi.dy.masa 6 | mod_id = tweakeroo 7 | mod_name = Tweakeroo 8 | author = masa 9 | mod_file_name = tweakeroo-fabric 10 | 11 | # Current mod version 12 | mod_version = 0.27.1 13 | 14 | # Required malilib version 15 | malilib_version = 1.21.11-0.27.2 16 | 17 | # Minecraft, Fabric Loader and API and mappings versions 18 | minecraft_version_out = 1.21.11 19 | minecraft_version = 1.21.11 20 | mappings_version = 1.21.11+build.1 21 | 22 | fabric_loader_version = 0.18.2 23 | mod_menu_version = 17.0.0-alpha.1 24 | # fabric_api_version = 0.139.5+1.21.11 25 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/Reference.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo; 2 | 3 | import net.minecraft.SharedConstants; 4 | import fi.dy.masa.malilib.util.StringUtils; 5 | 6 | public class Reference 7 | { 8 | public static final String MOD_ID = "tweakeroo"; 9 | public static final String MOD_NAME = "Tweakeroo"; 10 | public static final String MOD_VERSION = StringUtils.getModVersionString(MOD_ID); 11 | public static final String MC_VERSION = SharedConstants.getCurrentVersion().id(); 12 | public static final String MOD_TYPE = "fabric"; 13 | public static final String MOD_STRING = MOD_ID+"-"+MOD_TYPE+"-"+MC_VERSION+"-"+MOD_VERSION; 14 | } 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![](https://jitpack.io/v/sakura-ryoko/tweakeroo.svg)](https://jitpack.io/#sakura-ryoko/tweakeroo) 2 | 3 | Tweakeroo 4 | ============== 5 | Tweakeroo is a client-side-only Minecraft mod using LiteLoader. 6 | It adds a selection of miscellaneous, configurable, client-side tweaks to the game. 7 | Some examples of these are the "flexible block placement" tweak and the "fast block placement" tweak. 8 | For more information and the downloads (compiled builds), see https://www.curseforge.com/minecraft/mc-mods/tweakeroo/files/all 9 | 10 | Compiling 11 | ========= 12 | * Clone the repository 13 | * Open a command prompt/terminal to the repository directory 14 | * run 'gradlew build' 15 | * The built jar file will be in build/libs/ 16 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/option/MixinGameOptions.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.option; 2 | 3 | import net.minecraft.client.Options; 4 | import org.spongepowered.asm.mixin.Mixin; 5 | 6 | @Mixin(Options.class) 7 | public class MixinGameOptions 8 | { 9 | // @Inject(method = "getTextBackgroundColor(I)I", at = @At("RETURN"), cancellable = true) 10 | // private void tweakeroo_tweakChatBackgroundColor(int fallbackColor, CallbackInfoReturnable cir) 11 | // { 12 | // if (FeatureToggle.TWEAK_CHAT_BACKGROUND_COLOR.getBooleanValue()) 13 | // { 14 | // cir.setReturnValue(Configs.Generic.CHAT_BACKGROUND_COLOR.getIntegerValue()); 15 | // } 16 | // } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/item/MixinItemGroup.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.item; 2 | 3 | import net.minecraft.world.item.CreativeModeTab; 4 | import org.spongepowered.asm.mixin.Mixin; 5 | 6 | @Mixin(CreativeModeTab.class) 7 | public abstract class MixinItemGroup 8 | { 9 | /* // TODO 1.19.3+ 10 | @Inject(method = "appendStacks", at = @At("RETURN")) 11 | private void appendCustomItems(net.minecraft.util.collection.DefaultedList stacks, CallbackInfo ci) 12 | { 13 | if (FeatureToggle.TWEAK_CREATIVE_EXTRA_ITEMS.getBooleanValue()) 14 | { 15 | List extraStacks = CreativeExtraItems.getExtraStacksForGroup((net.minecraft.item.ItemGroup) (Object) this); 16 | stacks.addAll(extraStacks); 17 | } 18 | } 19 | */ 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/world/MixinBuiltChunk.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.world; 2 | 3 | import org.spongepowered.asm.mixin.Mixin; 4 | import org.spongepowered.asm.mixin.injection.At; 5 | import org.spongepowered.asm.mixin.injection.Inject; 6 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 7 | import fi.dy.masa.tweakeroo.config.Configs; 8 | import net.minecraft.client.renderer.chunk.SectionRenderDispatcher; 9 | 10 | @Mixin(SectionRenderDispatcher.RenderSection.class) 11 | public abstract class MixinBuiltChunk 12 | { 13 | @Inject(method = "setDirty(Z)V", at = @At("HEAD"), cancellable = true) 14 | private void disableChunkReRenders(boolean important, CallbackInfo ci) 15 | { 16 | if (Configs.Disable.DISABLE_CHUNK_RENDERING.getBooleanValue()) 17 | { 18 | ci.cancel(); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/block/IMixinAbstractBlock.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.block; 2 | 3 | import net.minecraft.core.BlockPos; 4 | import net.minecraft.world.item.ItemStack; 5 | import net.minecraft.world.level.LevelReader; 6 | import net.minecraft.world.level.block.state.BlockBehaviour; 7 | import net.minecraft.world.level.block.state.BlockState; 8 | import org.spongepowered.asm.mixin.Mixin; 9 | import org.spongepowered.asm.mixin.Mutable; 10 | import org.spongepowered.asm.mixin.gen.Accessor; 11 | import org.spongepowered.asm.mixin.gen.Invoker; 12 | 13 | @Mixin(BlockBehaviour.class) 14 | public interface IMixinAbstractBlock 15 | { 16 | @Mutable 17 | @Accessor("friction") 18 | void setFriction(float friction); 19 | 20 | @Invoker("getCloneItemStack") 21 | ItemStack tweakeroo_getPickStack(LevelReader world, BlockPos pos, BlockState state, boolean bl); 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/fog/MixinStandardFogModifier.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.fog; 2 | 3 | //@Mixin(StandardFogModifier.class) 4 | // todo -- removed from game; now Sky Rendering uses a single constant value supplier. 5 | @Deprecated 6 | public class MixinStandardFogModifier 7 | { 8 | // @Inject(method = "getFogColor", at = @At("HEAD"), cancellable = true) 9 | // private void tweakeroo_adjustFogColor(ClientWorld world, Camera camera, int viewDistance, float skyDarkness, CallbackInfoReturnable cir) 10 | // { 11 | // if (FeatureToggle.TWEAK_MATCHING_SKY_FOG.getBooleanValue()) 12 | // { 13 | // if (world.getDimension().hasSkyLight()) 14 | // { 15 | // int color = world.getSkyColor(camera.getCameraPos(), skyDarkness); 16 | // cir.setReturnValue(color); 17 | // } 18 | // } 19 | // } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/world/MixinDimensionEffects_Nether.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.world; 2 | 3 | // todo (CameraSubmersionType.DIMENSION_OR_BOSS) aka 'thickFog' removed from game 4 | //@Mixin(DimensionEffects.Nether.class) 5 | @Deprecated 6 | public abstract class MixinDimensionEffects_Nether 7 | // extends DimensionEffects 8 | { 9 | 10 | // private MixinDimensionEffects_Nether(SkyType skyType, boolean shouldRenderSky, boolean darkened) 11 | // { 12 | // super(skyType, shouldRenderSky, darkened); 13 | // } 14 | // 15 | // @Inject(method = "useThickFog", at = @At("HEAD"), cancellable = true) 16 | // private void disableNetherFog(int x, int z, CallbackInfoReturnable cir) 17 | // { 18 | // if (Configs.Disable.DISABLE_NETHER_FOG.getBooleanValue()) 19 | // { 20 | // cir.setReturnValue(false); 21 | // } 22 | // } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/block/MixinMobSpawnerLogic.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.block; 2 | 3 | import org.spongepowered.asm.mixin.Mixin; 4 | import org.spongepowered.asm.mixin.injection.At; 5 | import org.spongepowered.asm.mixin.injection.Inject; 6 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 7 | import fi.dy.masa.tweakeroo.config.Configs; 8 | import net.minecraft.core.BlockPos; 9 | import net.minecraft.world.level.BaseSpawner; 10 | import net.minecraft.world.level.Level; 11 | 12 | @Mixin(BaseSpawner.class) 13 | public abstract class MixinMobSpawnerLogic 14 | { 15 | @Inject(method = "clientTick", at = @At("HEAD"), cancellable = true) 16 | private void cancelParticleRendering(Level world, BlockPos pos, CallbackInfo ci) 17 | { 18 | if (Configs.Disable.DISABLE_MOB_SPAWNER_MOB_RENDER.getBooleanValue()) 19 | { 20 | ci.cancel(); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/freecam/MixinCamera_freeCam.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.freecam; 2 | 3 | import org.spongepowered.asm.mixin.Mixin; 4 | import org.spongepowered.asm.mixin.injection.At; 5 | import org.spongepowered.asm.mixin.injection.Inject; 6 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 7 | 8 | import fi.dy.masa.tweakeroo.config.FeatureToggle; 9 | import net.minecraft.client.Camera; 10 | import net.minecraft.world.level.material.FogType; 11 | 12 | @Mixin(value = Camera.class, priority = 1005) 13 | public class MixinCamera_freeCam 14 | { 15 | @Inject(method = "getFluidInCamera", at = @At("HEAD"), cancellable = true) 16 | private void tweakeroo_disableFluidFog(CallbackInfoReturnable cir) 17 | { 18 | if (FeatureToggle.TWEAK_FREE_CAMERA.getBooleanValue()) 19 | { 20 | cir.setReturnValue(FogType.NONE); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/world/MixinChunkBuilder_BuiltChunk.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.world; 2 | 3 | import org.spongepowered.asm.mixin.Mixin; 4 | import org.spongepowered.asm.mixin.injection.At; 5 | import org.spongepowered.asm.mixin.injection.Inject; 6 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 7 | import fi.dy.masa.tweakeroo.config.FeatureToggle; 8 | import net.minecraft.client.renderer.chunk.SectionRenderDispatcher; 9 | 10 | @Mixin(SectionRenderDispatcher.RenderSection.class) 11 | public abstract class MixinChunkBuilder_BuiltChunk 12 | { 13 | @Inject(method = "doesChunkExistAt", at = @At("HEAD"), cancellable = true) 14 | private void allowEdgeChunksToRender(long l, CallbackInfoReturnable cir) 15 | { 16 | if (FeatureToggle.TWEAK_RENDER_EDGE_CHUNKS.getBooleanValue()) 17 | { 18 | cir.setReturnValue(true); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/input/MixinMouse.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.input; 2 | 3 | import org.spongepowered.asm.mixin.Mixin; 4 | import org.spongepowered.asm.mixin.injection.At; 5 | import org.spongepowered.asm.mixin.injection.ModifyVariable; 6 | 7 | import fi.dy.masa.tweakeroo.config.Configs; 8 | import net.minecraft.client.MouseHandler; 9 | import net.minecraft.util.Util; 10 | 11 | @Mixin(MouseHandler.class) 12 | public abstract class MixinMouse 13 | { 14 | @ModifyVariable(method = "onScroll", ordinal = 1, at = @At("HEAD"), argsOnly = true) 15 | private double applyHorizontalScroll(double vertical, long argWindow, double argHorizontal, double argVertical) 16 | { 17 | if (Configs.Fixes.MAC_HORIZONTAL_SCROLL.getBooleanValue() && 18 | Util.getPlatform() == Util.OS.OSX && 19 | vertical == 0) 20 | { 21 | return argHorizontal; 22 | } 23 | 24 | return vertical; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/item/MixinItem.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.item; 2 | 3 | import net.minecraft.world.item.Item; 4 | import org.spongepowered.asm.mixin.Mixin; 5 | import org.spongepowered.asm.mixin.Shadow; 6 | 7 | @Mixin(net.minecraft.world.item.Item.class) 8 | public abstract class MixinItem 9 | { 10 | @Shadow public abstract Item asItem(); 11 | 12 | /* // TODO 1.19.3+ 13 | @Inject(method = "getGroup", at = @At("HEAD"), cancellable = true) 14 | private void overrideItemGroup(CallbackInfoReturnable cir) 15 | { 16 | if (FeatureToggle.TWEAK_CREATIVE_EXTRA_ITEMS.getBooleanValue()) 17 | { 18 | net.minecraft.item.ItemGroup group = CreativeExtraItems.getGroupFor((net.minecraft.item.Item) (Object) this); 19 | 20 | if (group != null) 21 | { 22 | cir.setReturnValue(group); 23 | } 24 | } 25 | } 26 | */ 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/Tweakeroo.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo; 2 | 3 | import net.fabricmc.api.ModInitializer; 4 | import org.apache.logging.log4j.LogManager; 5 | import org.apache.logging.log4j.Logger; 6 | import fi.dy.masa.malilib.event.InitializationHandler; 7 | import fi.dy.masa.tweakeroo.config.Configs; 8 | 9 | public class Tweakeroo implements ModInitializer 10 | { 11 | public static final Logger LOGGER = LogManager.getLogger(Reference.MOD_ID); 12 | 13 | public static int renderCountItems; 14 | public static int renderCountXPOrbs; 15 | 16 | @Override 17 | public void onInitialize() 18 | { 19 | InitializationHandler.getInstance().registerInitializationHandler(new InitHandler()); 20 | } 21 | 22 | public static void debugLog(String msg, Object... args) 23 | { 24 | if (Configs.Generic.DEBUG_LOGGING.getBooleanValue()) 25 | { 26 | Tweakeroo.LOGGER.info(msg, args); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/hud/MixinClientBossBar.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.hud; 2 | 3 | import java.util.UUID; 4 | import net.minecraft.client.gui.components.LerpingBossEvent; 5 | import net.minecraft.network.chat.Component; 6 | import net.minecraft.world.BossEvent; 7 | import org.spongepowered.asm.mixin.Mixin; 8 | import fi.dy.masa.tweakeroo.config.Configs; 9 | 10 | @Mixin(LerpingBossEvent.class) 11 | public abstract class MixinClientBossBar extends BossEvent 12 | { 13 | public MixinClientBossBar(UUID uniqueIdIn, Component nameIn, BossEvent.BossBarColor colorIn, BossEvent.BossBarOverlay styleIn) 14 | { 15 | super(uniqueIdIn, nameIn, colorIn, styleIn); 16 | } 17 | 18 | @Override 19 | public boolean shouldCreateWorldFog() 20 | { 21 | if (Configs.Disable.DISABLE_BOSS_FOG.getBooleanValue()) 22 | { 23 | return false; 24 | } 25 | 26 | return super.shouldCreateWorldFog(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/block/MixinSculkSensor.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.block; 2 | 3 | import org.spongepowered.asm.mixin.Mixin; 4 | import org.spongepowered.asm.mixin.injection.At; 5 | import org.spongepowered.asm.mixin.injection.Inject; 6 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 7 | import fi.dy.masa.tweakeroo.config.Configs; 8 | import fi.dy.masa.tweakeroo.config.FeatureToggle; 9 | import net.minecraft.world.level.block.SculkSensorBlock; 10 | 11 | @Mixin(SculkSensorBlock.class) 12 | public abstract class MixinSculkSensor 13 | { 14 | @Inject(method = "getActiveTicks", at = @At(value = "HEAD"), require = 0, cancellable = true) 15 | private void modifyPulseLength(CallbackInfoReturnable cir) 16 | { 17 | if (FeatureToggle.TWEAK_SCULK_PULSE_LENGTH.getBooleanValue()) 18 | { 19 | cir.setReturnValue(Configs.Generic.SCULK_SENSOR_PULSE_LENGTH.getIntegerValue()); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/entity/MixinBlockAttachedEntity.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.entity; 2 | 3 | import org.spongepowered.asm.mixin.Mixin; 4 | import org.spongepowered.asm.mixin.Shadow; 5 | 6 | import fi.dy.masa.tweakeroo.util.IDecorationEntity; 7 | import net.minecraft.core.BlockPos; 8 | import net.minecraft.world.entity.Entity; 9 | import net.minecraft.world.entity.EntityType; 10 | import net.minecraft.world.entity.decoration.BlockAttachedEntity; 11 | import net.minecraft.world.level.Level; 12 | 13 | /** 14 | * Copied From Tweak Fork by Andrew54757 15 | */ 16 | @Mixin(BlockAttachedEntity.class) 17 | public abstract class MixinBlockAttachedEntity extends Entity implements IDecorationEntity 18 | { 19 | @Shadow protected BlockPos pos; 20 | 21 | public MixinBlockAttachedEntity(EntityType type, Level world) 22 | { 23 | super(type, world); 24 | } 25 | 26 | @Override 27 | public BlockPos tweakeroo$getAttached() 28 | { 29 | return this.pos; 30 | } 31 | } -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/screen/MixinScreen.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.screen; 2 | 3 | import org.spongepowered.asm.mixin.Mixin; 4 | import org.spongepowered.asm.mixin.Shadow; 5 | import org.spongepowered.asm.mixin.injection.At; 6 | import org.spongepowered.asm.mixin.injection.Redirect; 7 | 8 | import fi.dy.masa.tweakeroo.config.Configs; 9 | import net.minecraft.client.gui.screens.Screen; 10 | 11 | @Mixin(value = Screen.class) 12 | public abstract class MixinScreen 13 | { 14 | @Shadow public abstract boolean isPauseScreen(); 15 | 16 | @Redirect(method = "isAllowedInPortal", 17 | at = @At(value = "INVOKE", 18 | target = "Lnet/minecraft/client/gui/screens/Screen;isPauseScreen()Z")) 19 | private boolean tweakeroo_keepGuiOpenThroughPortals(Screen instance) 20 | { 21 | // Spoof the return value to prevent entering the if block 22 | if (Configs.Disable.DISABLE_PORTAL_GUI_CLOSING.getBooleanValue()) 23 | { 24 | return true; 25 | } 26 | 27 | return this.isPauseScreen(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/entity/MixinRavagerEntity.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.entity; 2 | 3 | import org.objectweb.asm.Opcodes; 4 | 5 | import org.spongepowered.asm.mixin.Mixin; 6 | import org.spongepowered.asm.mixin.injection.At; 7 | import org.spongepowered.asm.mixin.injection.Redirect; 8 | import fi.dy.masa.tweakeroo.config.Configs; 9 | import net.minecraft.world.entity.monster.Ravager; 10 | 11 | @Mixin(Ravager.class) 12 | public abstract class MixinRavagerEntity 13 | { 14 | @Redirect(method = "aiStep", at = @At( 15 | value = "FIELD", 16 | target = "Lnet/minecraft/world/entity/monster/Ravager;horizontalCollision:Z", 17 | opcode = Opcodes.GETFIELD)) 18 | private boolean fixDontBreakBlocksOnClient(Ravager entity) 19 | { 20 | if (Configs.Fixes.RAVAGER_CLIENT_BLOCK_BREAK_FIX.getBooleanValue()) 21 | { 22 | return entity.horizontalCollision && entity.level().isClientSide() == false; 23 | } 24 | 25 | return entity.horizontalCollision; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/freecam/MixinJumpBar_freeCam.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.freecam; 2 | 3 | import org.spongepowered.asm.mixin.Mixin; 4 | import org.spongepowered.asm.mixin.injection.At; 5 | import org.spongepowered.asm.mixin.injection.Inject; 6 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 7 | 8 | import fi.dy.masa.tweakeroo.config.Configs; 9 | import fi.dy.masa.tweakeroo.config.FeatureToggle; 10 | import net.minecraft.client.DeltaTracker; 11 | import net.minecraft.client.gui.GuiGraphics; 12 | import net.minecraft.client.gui.contextualbar.JumpableVehicleBarRenderer; 13 | 14 | @Mixin(value = JumpableVehicleBarRenderer.class, priority = 999) 15 | public class MixinJumpBar_freeCam 16 | { 17 | @Inject(method = "renderBackground", at = @At("HEAD"), cancellable = true) 18 | private void tweakeroo_disableJumpBar(GuiGraphics context, DeltaTracker tickCounter, CallbackInfo ci) 19 | { 20 | if (FeatureToggle.TWEAK_FREE_CAMERA.getBooleanValue() && 21 | !Configs.Generic.FREE_CAMERA_SHOW_STATUS_BARS.getBooleanValue()) 22 | { 23 | ci.cancel(); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/network/MixinServerPlayNetworkHandler.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.network; 2 | 3 | import org.spongepowered.asm.mixin.Mixin; 4 | import org.spongepowered.asm.mixin.injection.At; 5 | import org.spongepowered.asm.mixin.injection.Redirect; 6 | import fi.dy.masa.tweakeroo.config.Configs; 7 | import net.minecraft.server.network.ServerGamePacketListenerImpl; 8 | import net.minecraft.world.phys.Vec3; 9 | 10 | @Mixin(value = ServerGamePacketListenerImpl.class, priority = 1005) 11 | public class MixinServerPlayNetworkHandler 12 | { 13 | @Redirect(method = "handleUseItemOn", require = 0, 14 | at = @At(value = "INVOKE", 15 | target = "Lnet/minecraft/world/phys/Vec3;subtract(Lnet/minecraft/world/phys/Vec3;)Lnet/minecraft/world/phys/Vec3;")) 16 | private Vec3 tweakeroo_removeHitPosCheck(Vec3 hitVec, Vec3 blockCenter) 17 | { 18 | if (Configs.Generic.ITEM_USE_PACKET_CHECK_BYPASS.getBooleanValue()) 19 | { 20 | return Vec3.ZERO; 21 | } 22 | 23 | return hitVec.subtract(blockCenter); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/freecam/MixinExperienceBar_freeCam.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.freecam; 2 | 3 | import org.spongepowered.asm.mixin.Mixin; 4 | import org.spongepowered.asm.mixin.injection.At; 5 | import org.spongepowered.asm.mixin.injection.Inject; 6 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 7 | 8 | import fi.dy.masa.tweakeroo.config.Configs; 9 | import fi.dy.masa.tweakeroo.config.FeatureToggle; 10 | import net.minecraft.client.DeltaTracker; 11 | import net.minecraft.client.gui.GuiGraphics; 12 | import net.minecraft.client.gui.contextualbar.ExperienceBarRenderer; 13 | 14 | @Mixin(value = ExperienceBarRenderer.class, priority = 999) 15 | public class MixinExperienceBar_freeCam 16 | { 17 | @Inject(method = "renderBackground", at = @At("HEAD"), cancellable = true) 18 | private void tweakeroo_disableExperienceBar(GuiGraphics context, DeltaTracker tickCounter, CallbackInfo ci) 19 | { 20 | if (FeatureToggle.TWEAK_FREE_CAMERA.getBooleanValue() && 21 | !Configs.Generic.FREE_CAMERA_SHOW_STATUS_BARS.getBooleanValue()) 22 | { 23 | ci.cancel(); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/freecam/MixinClientPlayerInteractionManager_freeCam.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.freecam; 2 | 3 | import org.spongepowered.asm.mixin.Mixin; 4 | import org.spongepowered.asm.mixin.injection.At; 5 | import org.spongepowered.asm.mixin.injection.Inject; 6 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 7 | 8 | import fi.dy.masa.tweakeroo.config.Configs; 9 | import fi.dy.masa.tweakeroo.config.FeatureToggle; 10 | import net.minecraft.client.multiplayer.MultiPlayerGameMode; 11 | 12 | @Mixin(value = MultiPlayerGameMode.class, priority = 1005) 13 | public class MixinClientPlayerInteractionManager_freeCam 14 | { 15 | @Inject(method = "hasExperience", at = @At("RETURN"), cancellable = true) 16 | private void tweakeroo_disableExpLevel(CallbackInfoReturnable cir) 17 | { 18 | // This disables the "Exp Level" number (We can't Mixin into an Interface class) 19 | if (FeatureToggle.TWEAK_FREE_CAMERA.getBooleanValue() && 20 | !Configs.Generic.FREE_CAMERA_SHOW_STATUS_BARS.getBooleanValue()) 21 | { 22 | cir.setReturnValue(false); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/world/MixinClientWorld_Properties.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.world; 2 | 3 | import org.spongepowered.asm.mixin.Mixin; 4 | import org.spongepowered.asm.mixin.injection.At; 5 | import org.spongepowered.asm.mixin.injection.Inject; 6 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 7 | import fi.dy.masa.tweakeroo.config.Configs; 8 | import net.minecraft.client.multiplayer.ClientLevel; 9 | import net.minecraft.world.level.LevelHeightAccessor; 10 | 11 | @Mixin(ClientLevel.ClientLevelData.class) 12 | public class MixinClientWorld_Properties 13 | { 14 | @Inject(method = "getHorizonHeight", at = @At("HEAD"), cancellable = true) 15 | private void tweakeroo_overrideSkyDarknessHeight(LevelHeightAccessor world, CallbackInfoReturnable cir) 16 | { 17 | // Disable the dark sky effect in normal situations 18 | // by moving the y threshold below the bottom of the world 19 | if (Configs.Disable.DISABLE_SKY_DARKNESS.getBooleanValue()) 20 | { 21 | cir.setReturnValue(world.getMinY() - 2.0); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/network/MixinDataQueryHandler.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.network; 2 | 3 | import org.spongepowered.asm.mixin.Mixin; 4 | import org.spongepowered.asm.mixin.injection.At; 5 | import org.spongepowered.asm.mixin.injection.Inject; 6 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 7 | 8 | import fi.dy.masa.tweakeroo.config.Configs; 9 | import fi.dy.masa.tweakeroo.data.EntityDataManager; 10 | import net.minecraft.client.DebugQueryHandler; 11 | import net.minecraft.nbt.CompoundTag; 12 | 13 | @Mixin(DebugQueryHandler.class) 14 | public class MixinDataQueryHandler 15 | { 16 | @Inject( 17 | method = "handleResponse", 18 | at = @At("HEAD") 19 | ) 20 | private void tweakeroo_queryResponse(int transactionId, CompoundTag nbt, CallbackInfoReturnable cir) 21 | { 22 | if (Configs.Generic.ENTITY_DATA_SYNC.getBooleanValue() || 23 | Configs.Generic.ENTITY_DATA_SYNC_BACKUP.getBooleanValue()) 24 | { 25 | EntityDataManager.getInstance().handleVanillaQueryNbt(transactionId, nbt); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/resources/fabric.mod.json: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": 1, 3 | "id": "tweakeroo", 4 | "name": "Tweakeroo", 5 | "version": "${mod_version}", 6 | 7 | "description": "Adds a bunch of configurable client-side tweaks", 8 | "authors": [ 9 | "masa" 10 | ], 11 | "contact": { 12 | "homepage": "https://www.curseforge.com/minecraft/mc-mods/tweakeroo", 13 | "issues": "https://github.com/maruohon/tweakeroo/issues", 14 | "sources": "https://github.com/maruohon/tweakeroo", 15 | "twitter": "https://twitter.com/maruohon", 16 | "discord": "https://discordapp.com/channels/211786369951989762/453662800460644354/" 17 | }, 18 | 19 | "license": "LGPLv3", 20 | "icon": "assets/tweakeroo/icon.png", 21 | "environment": "client", 22 | "entrypoints": { 23 | "main": [ 24 | "fi.dy.masa.tweakeroo.Tweakeroo" 25 | ], 26 | "modmenu": [ 27 | "fi.dy.masa.tweakeroo.compat.modmenu.ModMenuImpl" 28 | ] 29 | }, 30 | 31 | "mixins": [ 32 | "mixins.tweakeroo.json" 33 | ], 34 | "accessWidener": "tweakeroo.accesswidener", 35 | 36 | "depends": { 37 | "minecraft": "1.21.11", 38 | "malilib": ">=0.27.2- <0.28.0-" 39 | }, 40 | "breaks": { 41 | "malilib": "<0.27.2-" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/hud/MixinStatusEffectsDisplay.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.hud; 2 | 3 | import java.util.Collection; 4 | import net.minecraft.client.gui.GuiGraphics; 5 | import net.minecraft.client.gui.screens.inventory.EffectsInInventory; 6 | import net.minecraft.world.effect.MobEffectInstance; 7 | import org.spongepowered.asm.mixin.Mixin; 8 | import org.spongepowered.asm.mixin.injection.At; 9 | import org.spongepowered.asm.mixin.injection.Inject; 10 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 11 | 12 | import fi.dy.masa.tweakeroo.config.Configs; 13 | 14 | @Mixin(value = EffectsInInventory.class, priority = 1001) 15 | public abstract class MixinStatusEffectsDisplay 16 | { 17 | @Inject(method = "renderEffects", at = @At("HEAD"), cancellable = true) 18 | private void tweakeroo_disableStatusEffectRendering1(GuiGraphics context, Collection effects, int x, int height, int mouseX, int mouseY, int width, CallbackInfo ci) 19 | { 20 | if (Configs.Disable.DISABLE_INVENTORY_EFFECTS.getBooleanValue()) 21 | { 22 | ci.cancel(); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/block/MixinScaffoldingBlock.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.block; 2 | 3 | import javax.annotation.Nonnull; 4 | import net.minecraft.world.level.block.Block; 5 | import net.minecraft.world.level.block.Blocks; 6 | import net.minecraft.world.level.block.RenderShape; 7 | import net.minecraft.world.level.block.ScaffoldingBlock; 8 | import net.minecraft.world.level.block.state.BlockState; 9 | import org.spongepowered.asm.mixin.Mixin; 10 | import fi.dy.masa.tweakeroo.config.Configs; 11 | 12 | 13 | @Mixin(ScaffoldingBlock.class) 14 | public abstract class MixinScaffoldingBlock extends Block 15 | { 16 | private MixinScaffoldingBlock(Properties settings) 17 | { 18 | super(settings); 19 | } 20 | 21 | @Deprecated 22 | @Override 23 | public @Nonnull RenderShape getRenderShape(@Nonnull BlockState state) 24 | { 25 | if (Configs.Disable.DISABLE_RENDERING_SCAFFOLDING.getBooleanValue() && 26 | state.getBlock() == Blocks.SCAFFOLDING) 27 | { 28 | return RenderShape.INVISIBLE; 29 | } 30 | 31 | return super.getRenderShape(state); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/render/MixinMobSpawnerBlockEntityRenderer.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.render; 2 | 3 | import org.spongepowered.asm.mixin.Mixin; 4 | import org.spongepowered.asm.mixin.injection.At; 5 | import org.spongepowered.asm.mixin.injection.Inject; 6 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 7 | import fi.dy.masa.tweakeroo.config.Configs; 8 | import net.minecraft.client.renderer.blockentity.SpawnerRenderer; 9 | 10 | @Mixin(SpawnerRenderer.class) 11 | public abstract class MixinMobSpawnerBlockEntityRenderer 12 | { 13 | @Inject(method = "submitEntityInSpawner(Lcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/SubmitNodeCollector;Lnet/minecraft/client/renderer/entity/state/EntityRenderState;Lnet/minecraft/client/renderer/entity/EntityRenderDispatcher;FFLnet/minecraft/client/renderer/state/CameraRenderState;)V", 14 | at = @At("HEAD"), cancellable = true) 15 | private static void cancelRender(CallbackInfo ci) 16 | { 17 | if (Configs.Disable.DISABLE_MOB_SPAWNER_MOB_RENDER.getBooleanValue()) 18 | { 19 | ci.cancel(); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/entity/MixinTradeOffer.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.entity; 2 | 3 | import org.spongepowered.asm.mixin.Final; 4 | import org.spongepowered.asm.mixin.Mixin; 5 | import org.spongepowered.asm.mixin.Mutable; 6 | import org.spongepowered.asm.mixin.Shadow; 7 | import org.spongepowered.asm.mixin.injection.At; 8 | import org.spongepowered.asm.mixin.injection.Inject; 9 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 10 | import fi.dy.masa.tweakeroo.config.Configs; 11 | import net.minecraft.world.item.trading.MerchantOffer; 12 | 13 | @Mixin(MerchantOffer.class) 14 | public abstract class MixinTradeOffer 15 | { 16 | @Shadow @Mutable @Final private int maxUses; 17 | 18 | @Inject(method = "increaseUses", at = @At("RETURN")) 19 | private void preventTradeLocking(CallbackInfo ci) 20 | { 21 | if (Configs.Disable.DISABLE_VILLAGER_TRADE_LOCKING.getBooleanValue()) 22 | { 23 | // Prevents the trade from getting locked, by also incrementing 24 | // the max uses every time the trade use count is incremented. 25 | ++this.maxUses; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/entity/MixinPlayerAbilities.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.entity; 2 | 3 | import org.spongepowered.asm.mixin.Mixin; 4 | import org.spongepowered.asm.mixin.injection.At; 5 | import org.spongepowered.asm.mixin.injection.Inject; 6 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 7 | import fi.dy.masa.tweakeroo.config.Configs; 8 | import fi.dy.masa.tweakeroo.config.FeatureToggle; 9 | import net.minecraft.client.Minecraft; 10 | import net.minecraft.world.entity.player.Abilities; 11 | import net.minecraft.world.entity.player.Player; 12 | 13 | @Mixin(Abilities.class) 14 | public abstract class MixinPlayerAbilities 15 | { 16 | @Inject(method = "getFlyingSpeed", at = @At("HEAD"), cancellable = true) 17 | private void overrideFlySpeed(CallbackInfoReturnable cir) 18 | { 19 | Player player = Minecraft.getInstance().player; 20 | 21 | if (FeatureToggle.TWEAK_FLY_SPEED.getBooleanValue() && 22 | player != null && player.getAbilities().mayfly) 23 | { 24 | cir.setReturnValue((float) Configs.getActiveFlySpeedConfig().getDoubleValue()); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/render/MixinExplosionEmitterParticle.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.render; 2 | 3 | import net.minecraft.client.multiplayer.ClientLevel; 4 | import net.minecraft.client.particle.HugeExplosionSeedParticle; 5 | import net.minecraft.client.particle.NoRenderParticle; 6 | import org.spongepowered.asm.mixin.Mixin; 7 | import org.spongepowered.asm.mixin.injection.Constant; 8 | import org.spongepowered.asm.mixin.injection.ModifyConstant; 9 | 10 | import fi.dy.masa.tweakeroo.config.FeatureToggle; 11 | 12 | @Mixin(HugeExplosionSeedParticle.class) 13 | public class MixinExplosionEmitterParticle extends NoRenderParticle 14 | { 15 | protected MixinExplosionEmitterParticle(ClientLevel clientWorld, double d, double e, double f) 16 | { 17 | super(clientWorld, d, e, f); 18 | } 19 | 20 | @ModifyConstant(method = "tick", constant = @Constant(intValue = 6)) 21 | private int addParticleModify(int constant) 22 | { 23 | if (FeatureToggle.TWEAK_EXPLOSION_REDUCED_PARTICLES.getBooleanValue()) 24 | { 25 | this.age = 1; 26 | this.lifetime = 2; 27 | return 1; 28 | } 29 | 30 | return constant; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/render/MixinGameRenderer_ViewBob.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.render; 2 | 3 | import org.spongepowered.asm.mixin.Mixin; 4 | import org.spongepowered.asm.mixin.Shadow; 5 | import org.spongepowered.asm.mixin.injection.At; 6 | import org.spongepowered.asm.mixin.injection.Redirect; 7 | import com.mojang.blaze3d.vertex.PoseStack; 8 | import fi.dy.masa.tweakeroo.config.Configs; 9 | import net.minecraft.client.renderer.GameRenderer; 10 | 11 | /** 12 | * Separated out for Iris compatibility by adjusting the Mixin Priority 13 | */ 14 | @Mixin(value = GameRenderer.class, priority = 999) 15 | public abstract class MixinGameRenderer_ViewBob 16 | { 17 | @Shadow protected abstract void bobView(PoseStack matrices, float tickDelta); 18 | 19 | @Redirect(method = "renderLevel", require = 0, at = @At(value = "INVOKE", 20 | target = "Lnet/minecraft/client/renderer/GameRenderer;bobView(Lcom/mojang/blaze3d/vertex/PoseStack;F)V")) 21 | private void tweakeroo_disableWorldViewBob(GameRenderer renderer, PoseStack matrices, float tickDelta) 22 | { 23 | if (!Configs.Disable.DISABLE_WORLD_VIEW_BOB.getBooleanValue()) 24 | { 25 | this.bobView(matrices, tickDelta); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/block/MixinPistonBlock.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.block; 2 | 3 | import net.fabricmc.api.EnvType; 4 | import net.fabricmc.api.Environment; 5 | import net.minecraft.core.BlockPos; 6 | import net.minecraft.world.level.Level; 7 | import net.minecraft.world.level.block.piston.PistonBaseBlock; 8 | import net.minecraft.world.level.block.state.BlockState; 9 | import org.spongepowered.asm.mixin.Mixin; 10 | import org.spongepowered.asm.mixin.injection.At; 11 | import org.spongepowered.asm.mixin.injection.Inject; 12 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 13 | 14 | import fi.dy.masa.tweakeroo.tweaks.RenderTweaks; 15 | 16 | /** 17 | * Copied From Tweak Fork by Andrew54757 18 | */ 19 | @Mixin(PistonBaseBlock.class) 20 | public class MixinPistonBlock 21 | { 22 | @Environment(EnvType.CLIENT) 23 | @Inject(method = "triggerEvent", at = @At("HEAD")) 24 | private void onSyncedBlockEventInject(BlockState state, Level world, BlockPos pos, int type, int data, CallbackInfoReturnable ci) 25 | { 26 | if (!world.isClientSide()) 27 | { 28 | return; 29 | } 30 | 31 | RenderTweaks.onPistonEvent(state, world, pos, type, data); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/block/MixinNetherPortalBlock.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.block; 2 | 3 | import org.spongepowered.asm.mixin.Mixin; 4 | import org.spongepowered.asm.mixin.injection.At; 5 | import org.spongepowered.asm.mixin.injection.Redirect; 6 | import fi.dy.masa.tweakeroo.config.Configs; 7 | import net.minecraft.sounds.SoundEvent; 8 | import net.minecraft.sounds.SoundSource; 9 | import net.minecraft.world.level.Level; 10 | import net.minecraft.world.level.block.NetherPortalBlock; 11 | 12 | @Mixin(NetherPortalBlock.class) 13 | public abstract class MixinNetherPortalBlock 14 | { 15 | @Redirect(method = "animateTick", at = @At(value = "INVOKE", 16 | target = "Lnet/minecraft/world/level/Level;playLocalSound(DDDLnet/minecraft/sounds/SoundEvent;Lnet/minecraft/sounds/SoundSource;FFZ)V")) 17 | private void tweakeroo_disablePortalSound(Level instance, double x, double y, double z, SoundEvent sound, 18 | SoundSource category, float volume, float pitch, boolean useDistance) 19 | { 20 | if (Configs.Disable.DISABLE_NETHER_PORTAL_SOUND.getBooleanValue() == false) 21 | { 22 | instance.playLocalSound(x, y, z, sound, category, volume, pitch, useDistance); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/hud/MixinBossBarHud.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.hud; 2 | 3 | import org.spongepowered.asm.mixin.Mixin; 4 | import org.spongepowered.asm.mixin.injection.At; 5 | import org.spongepowered.asm.mixin.injection.Inject; 6 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 7 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 8 | 9 | import fi.dy.masa.tweakeroo.config.Configs; 10 | import net.minecraft.client.gui.GuiGraphics; 11 | import net.minecraft.client.gui.components.BossHealthOverlay; 12 | 13 | @Mixin(BossHealthOverlay.class) 14 | public abstract class MixinBossBarHud 15 | { 16 | @Inject(method = "render", at = @At("HEAD"), cancellable = true) 17 | private void tweakeroo_disableBossBarRendering(GuiGraphics drawContext, CallbackInfo ci) 18 | { 19 | if (Configs.Disable.DISABLE_BOSS_BAR.getBooleanValue()) 20 | { 21 | ci.cancel(); 22 | } 23 | } 24 | 25 | @Inject(method = "shouldCreateWorldFog", at = @At("RETURN"), cancellable = true) 26 | private void tweakeroo_disableBossFog(CallbackInfoReturnable cir) 27 | { 28 | if (Configs.Disable.DISABLE_BOSS_FOG.getBooleanValue()) 29 | { 30 | cir.setReturnValue(false); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/network/MixinClientCommonNetworkHandler.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.network; 2 | 3 | import org.spongepowered.asm.mixin.Mixin; 4 | import org.spongepowered.asm.mixin.injection.At; 5 | import org.spongepowered.asm.mixin.injection.Inject; 6 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 7 | 8 | import fi.dy.masa.tweakeroo.data.DataManager; 9 | import net.minecraft.client.multiplayer.ClientCommonPacketListenerImpl; 10 | import net.minecraft.network.protocol.common.ClientboundCustomPayloadPacket; 11 | 12 | @Mixin(ClientCommonPacketListenerImpl.class) 13 | public class MixinClientCommonNetworkHandler 14 | { 15 | @Inject(method = "handleCustomPayload(Lnet/minecraft/network/protocol/common/ClientboundCustomPayloadPacket;)V", at = @At("HEAD")) 16 | private void tweakeroo_onCustomPayload(ClientboundCustomPayloadPacket packet, CallbackInfo ci) 17 | { 18 | if (packet.payload().type().id().equals(DataManager.CARPET_HELLO)) 19 | { 20 | DataManager.getInstance().setHasCarpetServer(true); 21 | } 22 | else if (packet.payload().type().id().getNamespace().equals("servux")) 23 | { 24 | DataManager.getInstance().setHasServuxServer(true); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/util/EntityRestriction.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.util; 2 | 3 | import java.util.List; 4 | import java.util.Optional; 5 | import java.util.Set; 6 | import net.minecraft.core.Holder; 7 | import net.minecraft.core.registries.BuiltInRegistries; 8 | import net.minecraft.resources.Identifier; 9 | import net.minecraft.world.entity.EntityType; 10 | import fi.dy.masa.malilib.util.restrictions.UsageRestriction; 11 | import fi.dy.masa.tweakeroo.Tweakeroo; 12 | 13 | public class EntityRestriction extends UsageRestriction> 14 | { 15 | @Override 16 | protected void setValuesForList(Set> set, List names) 17 | { 18 | for (String name : names) 19 | { 20 | try 21 | { 22 | Identifier id = Identifier.tryParse(name); 23 | 24 | if (id != null) 25 | { 26 | Optional>> opt = BuiltInRegistries.ENTITY_TYPE.get(id); 27 | 28 | if (opt.isPresent()) 29 | { 30 | set.add(opt.get().value()); 31 | continue; 32 | } 33 | } 34 | } 35 | catch (Exception ignore) {} 36 | 37 | Tweakeroo.LOGGER.warn("Invalid entity name in a black- or whitelist: '{}'", name); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/block/MixinAbstractBlockState.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.block; 2 | 3 | import net.minecraft.world.level.block.state.BlockBehaviour; 4 | import org.spongepowered.asm.mixin.Mixin; 5 | 6 | @Mixin(BlockBehaviour.BlockStateBase.class) 7 | public class MixinAbstractBlockState 8 | { 9 | // todo this has the same effect as noClip; and causes your player to fall through the world. 10 | // @Inject(method = "getCollisionShape(Lnet/minecraft/world/BlockView;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/ShapeContext;)Lnet/minecraft/util/shape/VoxelShape;", 11 | // at = @At("HEAD"), cancellable = true) 12 | // private void tweakeroo_checkCollisionState(BlockView world, BlockPos pos, ShapeContext context, CallbackInfoReturnable cir) 13 | // { 14 | // if (FeatureToggle.TWEAK_FREE_CAMERA.getBooleanValue()) 15 | // { 16 | // if (context instanceof EntityShapeContext ctx && ctx.getEntity() instanceof ClientPlayerEntity cli) 17 | // { 18 | // Tweakeroo.LOGGER.warn("tweakeroo_checkCollisionState(): pos [{}], instanceof [{}]", pos.toShortString(), (cli instanceof CameraEntity)); 19 | //// cir.setReturnValue(VoxelShapes.empty()); 20 | // } 21 | // } 22 | // } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/fog/MixinAtmosphericFogModifier.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.fog; 2 | 3 | import org.spongepowered.asm.mixin.Mixin; 4 | import org.spongepowered.asm.mixin.injection.At; 5 | import org.spongepowered.asm.mixin.injection.Inject; 6 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 7 | 8 | import fi.dy.masa.tweakeroo.config.Configs; 9 | import net.minecraft.client.Camera; 10 | import net.minecraft.client.DeltaTracker; 11 | import net.minecraft.client.multiplayer.ClientLevel; 12 | import net.minecraft.client.renderer.fog.FogData; 13 | import net.minecraft.client.renderer.fog.environment.AtmosphericFogEnvironment; 14 | 15 | @Mixin(AtmosphericFogEnvironment.class) 16 | public class MixinAtmosphericFogModifier 17 | { 18 | @Inject(method = "setupFog", at = @At("RETURN")) 19 | private void tweakeroo_redirectAtmosphericFog(FogData data, Camera camera, ClientLevel clientWorld, float f, 20 | DeltaTracker renderTickCounter, CallbackInfo ci) 21 | { 22 | if (Configs.Disable.DISABLE_ATMOSPHERIC_FOG.getBooleanValue()) 23 | { 24 | float limit = data.cloudEnd; 25 | data.environmentalStart = limit - 4.0F; 26 | data.environmentalEnd = limit; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/block/MixinObserverBlock.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.block; 2 | 3 | import org.spongepowered.asm.mixin.Mixin; 4 | import org.spongepowered.asm.mixin.injection.At; 5 | import org.spongepowered.asm.mixin.injection.Inject; 6 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 7 | 8 | import fi.dy.masa.tweakeroo.config.Configs; 9 | import net.minecraft.core.BlockPos; 10 | import net.minecraft.world.level.LevelReader; 11 | import net.minecraft.world.level.ScheduledTickAccess; 12 | import net.minecraft.world.level.block.DirectionalBlock; 13 | import net.minecraft.world.level.block.ObserverBlock; 14 | import net.minecraft.world.level.block.state.BlockBehaviour; 15 | 16 | @Mixin(value = ObserverBlock.class, priority = 1001) 17 | public abstract class MixinObserverBlock extends DirectionalBlock 18 | { 19 | public MixinObserverBlock(BlockBehaviour.Properties builder) 20 | { 21 | super(builder); 22 | } 23 | 24 | @Inject(method = "startSignal", at = @At("HEAD"), cancellable = true) 25 | private void preventTrigger(LevelReader world, ScheduledTickAccess tickView, BlockPos pos, CallbackInfo ci) 26 | { 27 | if (Configs.Disable.DISABLE_OBSERVER.getBooleanValue()) 28 | { 29 | ci.cancel(); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/world/MixinServerChunkLoadingManager.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.world; 2 | 3 | import java.util.function.BooleanSupplier; 4 | import org.objectweb.asm.Opcodes; 5 | 6 | import net.minecraft.server.level.ChunkMap; 7 | import org.spongepowered.asm.mixin.Mixin; 8 | import org.spongepowered.asm.mixin.injection.At; 9 | import org.spongepowered.asm.mixin.injection.Inject; 10 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 11 | import fi.dy.masa.tweakeroo.config.Configs; 12 | 13 | /** 14 | * The "Moonrise" mod breaks this mixin. 15 | */ 16 | @Mixin(value = ChunkMap.class, priority = 990) 17 | public abstract class MixinServerChunkLoadingManager 18 | { 19 | @Inject(method = "saveChunksEagerly", 20 | cancellable = true, 21 | at = @At(value = "FIELD", 22 | target = "Lnet/minecraft/server/level/ChunkMap;visibleChunkMap:Lit/unimi/dsi/fastutil/longs/Long2ObjectLinkedOpenHashMap;", 23 | opcode = Opcodes.GETFIELD) 24 | ) 25 | private void tweakeroo_disableSaving20ChunksEveryTick(BooleanSupplier shouldKeepTicking, CallbackInfo ci) 26 | { 27 | if (Configs.Disable.DISABLE_CONSTANT_CHUNK_SAVING.getBooleanValue()) 28 | { 29 | ci.cancel(); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | # Automatically build the project and run any configured tests for every push 2 | # and submitted pull request. This can help catch issues that only occur on 3 | # certain platforms or Java versions, and provides a first line of defence 4 | # against bad commits. 5 | 6 | name: build 7 | on: [ pull_request, push ] 8 | 9 | jobs: 10 | build: 11 | strategy: 12 | matrix: 13 | # Use these Java versions 14 | java: [ 21 ] 15 | distro: [ temurin ] 16 | # and run on both Linux and Windows 17 | os: [ ubuntu-latest ] 18 | runs-on: ${{ matrix.os }} 19 | steps: 20 | - name: checkout repository 21 | uses: actions/checkout@v4 22 | - name: validate gradle wrapper 23 | uses: gradle/actions/wrapper-validation@v4 24 | - name: setup jdk ${{ matrix.java }} 25 | uses: actions/setup-java@v4 26 | with: 27 | distribution: ${{ matrix.distro }} 28 | java-version: ${{ matrix.java }} 29 | - name: make gradle wrapper executable 30 | if: ${{ runner.os != 'Windows' }} 31 | run: chmod +x ./gradlew 32 | - name: build 33 | run: ./gradlew build 34 | - name: capture build artifacts 35 | if: ${{ runner.os == 'Linux' }} 36 | uses: actions/upload-artifact@v4 37 | with: 38 | name: Artifacts 39 | path: build/libs/ 40 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/util/PotionRestriction.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.util; 2 | 3 | import java.util.List; 4 | import java.util.Optional; 5 | import java.util.Set; 6 | import net.minecraft.core.Holder; 7 | import net.minecraft.core.registries.BuiltInRegistries; 8 | import net.minecraft.resources.Identifier; 9 | import net.minecraft.world.effect.MobEffect; 10 | import fi.dy.masa.malilib.util.restrictions.UsageRestriction; 11 | import fi.dy.masa.tweakeroo.Tweakeroo; 12 | 13 | public class PotionRestriction extends UsageRestriction 14 | { 15 | @Override 16 | protected void setValuesForList(Set set, List names) 17 | { 18 | for (String name : names) 19 | { 20 | Identifier rl = null; 21 | 22 | try 23 | { 24 | rl = Identifier.tryParse(name); 25 | } 26 | catch (Exception ignored) { } 27 | 28 | if (rl != null) 29 | { 30 | //StatusEffect effect = rl != null ? Registries.STATUS_EFFECT.get(rl) : null; 31 | Optional> opt = BuiltInRegistries.MOB_EFFECT.get(rl); 32 | 33 | if (opt.isPresent()) 34 | { 35 | set.add(opt.get().value()); 36 | } 37 | else 38 | { 39 | Tweakeroo.LOGGER.warn("Invalid potion effect name '{}'", name); 40 | } 41 | } 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/world/MixinLightingProvider.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.world; 2 | 3 | import org.jetbrains.annotations.Nullable; 4 | import org.spongepowered.asm.mixin.Final; 5 | import org.spongepowered.asm.mixin.Mixin; 6 | import org.spongepowered.asm.mixin.Shadow; 7 | import org.spongepowered.asm.mixin.injection.At; 8 | import org.spongepowered.asm.mixin.injection.Inject; 9 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 10 | import fi.dy.masa.tweakeroo.config.Configs; 11 | import net.minecraft.client.Minecraft; 12 | import net.minecraft.core.BlockPos; 13 | import net.minecraft.world.level.lighting.LevelLightEngine; 14 | import net.minecraft.world.level.lighting.LightEngine; 15 | 16 | @Mixin(LevelLightEngine.class) 17 | public abstract class MixinLightingProvider 18 | { 19 | @Shadow @Final @Nullable private LightEngine blockEngine; 20 | 21 | @Inject(method = "checkBlock", at = @At("HEAD"), cancellable = true) 22 | private void disableLightUpdates(BlockPos pos, CallbackInfo ci) 23 | { 24 | if (Configs.Disable.DISABLE_CLIENT_LIGHT_UPDATES.getBooleanValue() && 25 | this.blockEngine != null && 26 | ((IMixinChunkLightProvider) this.blockEngine).tweakeroo_getChunkProvider().getLevel() == Minecraft.getInstance().level) 27 | { 28 | ci.cancel(); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/render/MixinBeaconBlockEntityRenderer.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.render; 2 | 3 | import org.spongepowered.asm.mixin.Mixin; 4 | import org.spongepowered.asm.mixin.injection.At; 5 | import org.spongepowered.asm.mixin.injection.Inject; 6 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 7 | import com.mojang.blaze3d.vertex.PoseStack; 8 | import fi.dy.masa.tweakeroo.config.Configs; 9 | import net.minecraft.client.renderer.SubmitNodeCollector; 10 | import net.minecraft.client.renderer.blockentity.BeaconRenderer; 11 | import net.minecraft.resources.Identifier; 12 | 13 | @Mixin(BeaconRenderer.class) 14 | public abstract class MixinBeaconBlockEntityRenderer 15 | { 16 | @Inject(method = "submitBeaconBeam(Lcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/SubmitNodeCollector;Lnet/minecraft/resources/Identifier;FFIIIFF)V", 17 | at = @At("HEAD"), cancellable = true) 18 | private static void tweakeroo_disableBeamRendering(PoseStack matrices, SubmitNodeCollector queue, Identifier textureId, 19 | float beamHeight, float beamRotationDegrees, int minHeight, int maxHeight, 20 | int color, float innerScale, float outerScale, CallbackInfo ci) 21 | { 22 | if (Configs.Disable.DISABLE_BEACON_BEAM_RENDERING.getBooleanValue()) 23 | { 24 | ci.cancel(); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/input/MixinCloneCommand.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.input; 2 | 3 | import org.spongepowered.asm.mixin.Mixin; 4 | import org.spongepowered.asm.mixin.injection.At; 5 | import org.spongepowered.asm.mixin.injection.Redirect; 6 | import fi.dy.masa.tweakeroo.config.Configs; 7 | import fi.dy.masa.tweakeroo.config.FeatureToggle; 8 | import net.minecraft.server.commands.CloneCommands; 9 | import net.minecraft.world.level.gamerules.GameRule; 10 | import net.minecraft.world.level.gamerules.GameRuleType; 11 | import net.minecraft.world.level.gamerules.GameRules; 12 | 13 | @Mixin(value = CloneCommands.class, priority = 999) 14 | public abstract class MixinCloneCommand 15 | { 16 | @SuppressWarnings("unchecked") 17 | @Redirect(method = "clone", require = 0, 18 | at = @At(value = "INVOKE", 19 | target = "Lnet/minecraft/world/level/gamerules/GameRules;get(Lnet/minecraft/world/level/gamerules/GameRule;)Ljava/lang/Object;")) 20 | private static T tweakeroo_overrideBlockLimit(GameRules instance, GameRule rule) 21 | { 22 | if (FeatureToggle.TWEAK_FILL_CLONE_LIMIT.getBooleanValue() && 23 | rule.gameRuleType() == GameRuleType.INT) // Ensure it's an Integer 24 | { 25 | return (T) (Object) Configs.Generic.FILL_CLONE_LIMIT.getIntegerValue(); 26 | } 27 | 28 | return instance.get(rule); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/input/MixinFillCommand.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.input; 2 | 3 | import org.spongepowered.asm.mixin.Mixin; 4 | import org.spongepowered.asm.mixin.injection.At; 5 | import org.spongepowered.asm.mixin.injection.Redirect; 6 | import fi.dy.masa.tweakeroo.config.Configs; 7 | import fi.dy.masa.tweakeroo.config.FeatureToggle; 8 | import net.minecraft.server.commands.FillCommand; 9 | import net.minecraft.world.level.gamerules.GameRule; 10 | import net.minecraft.world.level.gamerules.GameRuleType; 11 | import net.minecraft.world.level.gamerules.GameRules; 12 | 13 | @Mixin(value = FillCommand.class, priority = 1001) 14 | public abstract class MixinFillCommand 15 | { 16 | @SuppressWarnings("unchecked") 17 | @Redirect(method = "fillBlocks", require = 0, 18 | at = @At(value = "INVOKE", 19 | target = "Lnet/minecraft/world/level/gamerules/GameRules;get(Lnet/minecraft/world/level/gamerules/GameRule;)Ljava/lang/Object;")) 20 | private static T tweakeroo_overrideBlockLimit(GameRules instance, GameRule rule) 21 | { 22 | if (FeatureToggle.TWEAK_FILL_CLONE_LIMIT.getBooleanValue() && 23 | rule.gameRuleType() == GameRuleType.INT) // Ensure it's an Integer type 24 | { 25 | return (T) (Object) Configs.Generic.FILL_CLONE_LIMIT.getIntegerValue(); 26 | } 27 | 28 | return instance.get(rule); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/freecam/MixinPlayerEntity_freeCam.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.freecam; 2 | 3 | import org.spongepowered.asm.mixin.Mixin; 4 | import org.spongepowered.asm.mixin.injection.At; 5 | import org.spongepowered.asm.mixin.injection.Inject; 6 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 7 | 8 | import fi.dy.masa.tweakeroo.config.FeatureToggle; 9 | import fi.dy.masa.tweakeroo.util.CameraUtils; 10 | import net.minecraft.client.player.LocalPlayer; 11 | import net.minecraft.world.entity.EntityType; 12 | import net.minecraft.world.entity.LivingEntity; 13 | import net.minecraft.world.entity.player.Player; 14 | import net.minecraft.world.level.Level; 15 | 16 | @Mixin(value = Player.class, priority = 1005) 17 | public abstract class MixinPlayerEntity_freeCam extends LivingEntity 18 | { 19 | protected MixinPlayerEntity_freeCam(EntityType entityType_1, Level world_1) 20 | { 21 | super(entityType_1, world_1); 22 | } 23 | 24 | @Inject(method = "isSpectator", at = @At("HEAD"), cancellable = true) 25 | private void tweakeroo_overrideIsSpectator(CallbackInfoReturnable cir) 26 | { 27 | if (FeatureToggle.TWEAK_FREE_CAMERA.getBooleanValue() && 28 | CameraUtils.getFreeCameraSpectator() && 29 | (Player) (Object) this instanceof LocalPlayer) 30 | { 31 | cir.setReturnValue(true); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/block/MixinSlimeBlock.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.block; 2 | 3 | import org.spongepowered.asm.mixin.Mixin; 4 | import org.spongepowered.asm.mixin.injection.At; 5 | import org.spongepowered.asm.mixin.injection.Inject; 6 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 7 | import fi.dy.masa.tweakeroo.config.Configs; 8 | import net.minecraft.core.BlockPos; 9 | import net.minecraft.world.entity.Entity; 10 | import net.minecraft.world.entity.player.Player; 11 | import net.minecraft.world.level.Level; 12 | import net.minecraft.world.level.block.HalfTransparentBlock; 13 | import net.minecraft.world.level.block.SlimeBlock; 14 | import net.minecraft.world.level.block.state.BlockBehaviour; 15 | import net.minecraft.world.level.block.state.BlockState; 16 | 17 | @Mixin(SlimeBlock.class) 18 | public abstract class MixinSlimeBlock extends HalfTransparentBlock 19 | { 20 | public MixinSlimeBlock(BlockBehaviour.Properties settings) 21 | { 22 | super(settings); 23 | } 24 | 25 | @Inject(method = "stepOn", at = @At("HEAD"), cancellable = true) 26 | private void onEntityWalkOnSlime(Level worldIn, BlockPos pos, BlockState state, Entity entityIn, CallbackInfo ci) 27 | { 28 | if (Configs.Disable.DISABLE_SLIME_BLOCK_SLOWDOWN.getBooleanValue() && entityIn instanceof Player) 29 | { 30 | super.stepOn(worldIn, pos, state, entityIn); 31 | ci.cancel(); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/freecam/MixinLocatorBar_freeCam.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.freecam; 2 | 3 | import org.spongepowered.asm.mixin.Mixin; 4 | import org.spongepowered.asm.mixin.injection.At; 5 | import org.spongepowered.asm.mixin.injection.Inject; 6 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 7 | 8 | import fi.dy.masa.tweakeroo.config.Configs; 9 | import fi.dy.masa.tweakeroo.config.FeatureToggle; 10 | import net.minecraft.client.DeltaTracker; 11 | import net.minecraft.client.gui.GuiGraphics; 12 | import net.minecraft.client.gui.contextualbar.LocatorBarRenderer; 13 | 14 | @Mixin(value = LocatorBarRenderer.class, priority = 999) 15 | public class MixinLocatorBar_freeCam 16 | { 17 | @Inject(method = "renderBackground", at = @At("HEAD"), cancellable = true) 18 | private void tweakeroo_disableLocatorBar(GuiGraphics context, DeltaTracker tickCounter, CallbackInfo ci) 19 | { 20 | if (FeatureToggle.TWEAK_FREE_CAMERA.getBooleanValue() && 21 | !Configs.Generic.FREE_CAMERA_SHOW_STATUS_BARS.getBooleanValue()) 22 | { 23 | ci.cancel(); 24 | } 25 | } 26 | 27 | @Inject(method = "render", at = @At("HEAD"), cancellable = true) 28 | private void tweakeroo_disableLocatorBarAddons(GuiGraphics context, DeltaTracker tickCounter, CallbackInfo ci) 29 | { 30 | if (FeatureToggle.TWEAK_FREE_CAMERA.getBooleanValue() && 31 | !Configs.Generic.FREE_CAMERA_SHOW_STATUS_BARS.getBooleanValue()) 32 | { 33 | ci.cancel(); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/item/MixinBundleItem.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.item; 2 | 3 | import java.util.Optional; 4 | import net.minecraft.world.inventory.tooltip.TooltipComponent; 5 | import net.minecraft.world.item.BundleItem; 6 | import net.minecraft.world.item.ItemStack; 7 | import org.spongepowered.asm.mixin.Mixin; 8 | import org.spongepowered.asm.mixin.injection.At; 9 | import org.spongepowered.asm.mixin.injection.Inject; 10 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 11 | 12 | import fi.dy.masa.malilib.gui.GuiBase; 13 | import fi.dy.masa.tweakeroo.config.Configs; 14 | import fi.dy.masa.tweakeroo.config.FeatureToggle; 15 | 16 | @Mixin(BundleItem.class) 17 | public class MixinBundleItem 18 | { 19 | @Inject(method = "getTooltipImage", at = @At("HEAD"), cancellable = true) 20 | private void tweakeroo_getTooltipData(ItemStack stack, CallbackInfoReturnable> cir) 21 | { 22 | if (FeatureToggle.TWEAK_BUNDLE_DISPLAY.getBooleanValue() && 23 | Configs.Generic.BUNDLE_DISPLAY_REQUIRE_SHIFT.getBooleanValue() && 24 | GuiBase.isShiftDown()) 25 | { 26 | cir.setReturnValue(Optional.empty()); 27 | } 28 | else if (FeatureToggle.TWEAK_BUNDLE_DISPLAY.getBooleanValue() && 29 | !Configs.Generic.BUNDLE_DISPLAY_REQUIRE_SHIFT.getBooleanValue()) 30 | { 31 | cir.setReturnValue(Optional.empty()); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/render/MixinBlockEntityRenderManager.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.render; 2 | 3 | import org.spongepowered.asm.mixin.Mixin; 4 | import org.spongepowered.asm.mixin.injection.At; 5 | import org.spongepowered.asm.mixin.injection.Inject; 6 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 7 | 8 | import fi.dy.masa.tweakeroo.config.Configs; 9 | import net.minecraft.client.renderer.blockentity.BlockEntityRenderDispatcher; 10 | import net.minecraft.client.renderer.blockentity.state.BlockEntityRenderState; 11 | import net.minecraft.client.renderer.feature.ModelFeatureRenderer; 12 | import net.minecraft.world.level.block.entity.BlockEntity; 13 | 14 | @Mixin(BlockEntityRenderDispatcher.class) 15 | public abstract class MixinBlockEntityRenderManager 16 | { 17 | @Inject(method = "tryExtractRenderState(Lnet/minecraft/world/level/block/entity/BlockEntity;FLnet/minecraft/client/renderer/feature/ModelFeatureRenderer$CrumblingOverlay;)Lnet/minecraft/client/renderer/blockentity/state/BlockEntityRenderState;", 18 | at = @At("HEAD"), cancellable = true) 19 | private void tweakeroo_preventTileEntityRendering( 20 | E blockEntity, float f, 21 | ModelFeatureRenderer.CrumblingOverlay crumblingOverlay, 22 | CallbackInfoReturnable cir) 23 | { 24 | if (Configs.Disable.DISABLE_TILE_ENTITY_RENDERING.getBooleanValue()) 25 | { 26 | cir.setReturnValue(null); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/screen/MixinPresetsScreen.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.screen; 2 | 3 | import net.minecraft.client.gui.screens.PresetFlatWorldScreen; 4 | import org.spongepowered.asm.mixin.Mixin; 5 | 6 | @Mixin(PresetFlatWorldScreen.class) 7 | public abstract class MixinPresetsScreen 8 | { 9 | //@Shadow @Final private static RegistryKey BIOME_KEY; 10 | //@Shadow @Final private CustomizeFlatLevelScreen parent; 11 | 12 | /* 13 | @Inject(method = "init", at = @At("HEAD")) 14 | private void tweakeroo_addCustomEntries(CallbackInfo ci) 15 | { 16 | // FIXME 17 | if (FeatureToggle.TWEAK_CUSTOM_FLAT_PRESETS.getBooleanValue()) 18 | { 19 | ** 20 | int vanillaEntries = 9; 21 | int toRemove = PRESETS.size() - vanillaEntries; 22 | 23 | if (toRemove > 0) 24 | { 25 | PRESETS.subList(0, toRemove).clear(); 26 | } 27 | 28 | List presetStrings = Configs.Lists.FLAT_WORLD_PRESETS.getStrings(); 29 | 30 | for (int i = presetStrings.size() - 1; i >= 0; --i) 31 | { 32 | String str = presetStrings.get(i); 33 | 34 | if (this.registerPresetFromString(str) && PRESETS.size() > vanillaEntries) 35 | { 36 | Object o = PRESETS.remove(PRESETS.size() - 1); 37 | PRESETS.add(0, o); 38 | } 39 | } 40 | ** 41 | } 42 | } 43 | */ 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/fog/MixinWaterFogModifier.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.fog; 2 | 3 | import org.spongepowered.asm.mixin.Mixin; 4 | import org.spongepowered.asm.mixin.injection.At; 5 | import org.spongepowered.asm.mixin.injection.Inject; 6 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 7 | 8 | import fi.dy.masa.tweakeroo.config.FeatureToggle; 9 | import fi.dy.masa.tweakeroo.renderer.RenderUtils; 10 | import net.minecraft.client.Camera; 11 | import net.minecraft.client.DeltaTracker; 12 | import net.minecraft.client.multiplayer.ClientLevel; 13 | import net.minecraft.client.renderer.fog.FogData; 14 | import net.minecraft.client.renderer.fog.environment.WaterFogEnvironment; 15 | 16 | @Mixin(WaterFogEnvironment.class) 17 | public class MixinWaterFogModifier 18 | { 19 | @Inject(method = "setupFog", at = @At("RETURN")) 20 | private void tweakeroo_redirectWaterFog(FogData data, Camera camera, ClientLevel clientWorld, float f, DeltaTracker renderTickCounter, CallbackInfo ci) 21 | { 22 | if (FeatureToggle.TWEAK_WATER_VISIBILITY.getBooleanValue()) 23 | { 24 | if (data.environmentalStart > 0.0F) 25 | { 26 | data.environmentalStart = -8.0F; 27 | } 28 | 29 | final float adjusted = RenderUtils.calculateLiquidFogDistance(camera.entity(), data.environmentalEnd, true); 30 | 31 | if (data.environmentalEnd != adjusted) 32 | { 33 | data.environmentalEnd = adjusted; 34 | } 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/fog/MixinLavaFogModifier.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.fog; 2 | 3 | import org.spongepowered.asm.mixin.Mixin; 4 | import org.spongepowered.asm.mixin.injection.At; 5 | import org.spongepowered.asm.mixin.injection.Inject; 6 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 7 | 8 | import fi.dy.masa.tweakeroo.config.FeatureToggle; 9 | import fi.dy.masa.tweakeroo.renderer.RenderUtils; 10 | import net.minecraft.client.Camera; 11 | import net.minecraft.client.DeltaTracker; 12 | import net.minecraft.client.multiplayer.ClientLevel; 13 | import net.minecraft.client.renderer.fog.FogData; 14 | import net.minecraft.client.renderer.fog.environment.LavaFogEnvironment; 15 | 16 | @Mixin(LavaFogEnvironment.class) 17 | public class MixinLavaFogModifier 18 | { 19 | @Inject(method = "setupFog", at = @At("RETURN")) 20 | private void tweakeroo_redirectLavaFog(FogData data, Camera camera, ClientLevel clientWorld, float f, 21 | DeltaTracker renderTickCounter, CallbackInfo ci) 22 | { 23 | if (FeatureToggle.TWEAK_LAVA_VISIBILITY.getBooleanValue()) 24 | { 25 | if (data.environmentalStart == 0.25F) 26 | { 27 | data.environmentalStart = 0.0F; 28 | } 29 | 30 | final float adjusted = RenderUtils.calculateLiquidFogDistance(camera.entity(), data.environmentalEnd, false); 31 | 32 | if (data.environmentalEnd != adjusted) 33 | { 34 | data.environmentalEnd = adjusted; 35 | } 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/hud/MixinTeleportSpectatorMenu.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.hud; 2 | 3 | import java.util.Collection; 4 | import java.util.Comparator; 5 | import java.util.List; 6 | import net.minecraft.client.gui.spectator.PlayerMenuItem; 7 | import net.minecraft.client.gui.spectator.SpectatorMenuItem; 8 | import net.minecraft.client.gui.spectator.categories.TeleportToPlayerMenuCategory; 9 | import net.minecraft.client.multiplayer.PlayerInfo; 10 | import org.spongepowered.asm.mixin.Final; 11 | import org.spongepowered.asm.mixin.Mixin; 12 | import org.spongepowered.asm.mixin.Mutable; 13 | import org.spongepowered.asm.mixin.Shadow; 14 | import org.spongepowered.asm.mixin.injection.At; 15 | import org.spongepowered.asm.mixin.injection.Inject; 16 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 17 | import fi.dy.masa.tweakeroo.config.FeatureToggle; 18 | 19 | @Mixin(TeleportToPlayerMenuCategory.class) 20 | public abstract class MixinTeleportSpectatorMenu 21 | { 22 | @Shadow @Final private static Comparator PROFILE_ORDER; 23 | @Shadow @Final @Mutable private List items; 24 | 25 | @Inject(method = "(Ljava/util/Collection;)V", at = @At("RETURN")) 26 | private void allowSpectatorTeleport(Collection profiles, CallbackInfo ci) 27 | { 28 | if (FeatureToggle.TWEAK_SPECTATOR_TELEPORT.getBooleanValue()) 29 | { 30 | this.items = profiles.stream().sorted(PROFILE_ORDER).map( 31 | entry -> (SpectatorMenuItem) new PlayerMenuItem(entry)).toList(); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/entity/MixinBatEntity.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.entity; 2 | 3 | import org.spongepowered.asm.mixin.Mixin; 4 | import org.spongepowered.asm.mixin.injection.At; 5 | import org.spongepowered.asm.mixin.injection.Inject; 6 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 7 | import fi.dy.masa.tweakeroo.config.Configs; 8 | import net.minecraft.core.BlockPos; 9 | import net.minecraft.util.RandomSource; 10 | import net.minecraft.world.entity.EntitySpawnReason; 11 | import net.minecraft.world.entity.EntityType; 12 | import net.minecraft.world.entity.ambient.Bat; 13 | import net.minecraft.world.level.LevelAccessor; 14 | 15 | @Mixin(Bat.class) 16 | public abstract class MixinBatEntity 17 | { 18 | @Inject(method = "checkBatSpawnRules(Lnet/minecraft/world/entity/EntityType;Lnet/minecraft/world/level/LevelAccessor;Lnet/minecraft/world/entity/EntitySpawnReason;Lnet/minecraft/core/BlockPos;Lnet/minecraft/util/RandomSource;)Z", at = @At("HEAD"), cancellable = true) 19 | private static void tweakeroo_disableBatSpawning(EntityType type, 20 | LevelAccessor world, 21 | EntitySpawnReason spawnReason, 22 | BlockPos pos, 23 | RandomSource random, 24 | CallbackInfoReturnable cir) 25 | { 26 | if (Configs.Disable.DISABLE_BAT_SPAWNING.getBooleanValue()) 27 | { 28 | cir.setReturnValue(false); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/render/MixinWeatherRendering.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.render; 2 | 3 | import fi.dy.masa.tweakeroo.config.Configs; 4 | import net.minecraft.client.Camera; 5 | import net.minecraft.client.multiplayer.ClientLevel; 6 | import net.minecraft.client.renderer.WeatherEffectRenderer; 7 | import net.minecraft.client.renderer.state.WeatherRenderState; 8 | import net.minecraft.server.level.ParticleStatus; 9 | import net.minecraft.world.level.Level; 10 | import net.minecraft.world.phys.Vec3; 11 | import org.spongepowered.asm.mixin.Mixin; 12 | import org.spongepowered.asm.mixin.injection.At; 13 | import org.spongepowered.asm.mixin.injection.Inject; 14 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 15 | 16 | @Mixin(WeatherEffectRenderer.class) 17 | public class MixinWeatherRendering 18 | { 19 | @Inject(method = "extractRenderState", at = @At("HEAD"), cancellable = true) 20 | private void tweakeroo_cancelWeatherRender(Level world, int ticks, float tickProgress, Vec3 vec3d, 21 | WeatherRenderState weatherRenderState, CallbackInfo ci) 22 | { 23 | if (Configs.Disable.DISABLE_RAIN_EFFECTS.getBooleanValue()) 24 | { 25 | ci.cancel(); 26 | } 27 | } 28 | 29 | @Inject(method = "tickRainParticles", at = @At("HEAD"), cancellable = true) 30 | private void tweakeroo_cancelParticlesAndSounds(ClientLevel world, Camera camera, int ticks, ParticleStatus particlesMode, int weatherRadius, CallbackInfo ci) 31 | { 32 | if (Configs.Disable.DISABLE_RAIN_EFFECTS.getBooleanValue()) 33 | { 34 | ci.cancel(); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/screen/MixinCreativeInventoryScreen.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.screen; 2 | 3 | import org.spongepowered.asm.mixin.Mixin; 4 | import org.spongepowered.asm.mixin.injection.At; 5 | import org.spongepowered.asm.mixin.injection.Inject; 6 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 7 | import fi.dy.masa.tweakeroo.config.Configs; 8 | import fi.dy.masa.tweakeroo.util.CreativeExtraItems; 9 | import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; 10 | import net.minecraft.client.gui.screens.inventory.CreativeModeInventoryScreen; 11 | import net.minecraft.network.chat.Component; 12 | import net.minecraft.world.entity.player.Inventory; 13 | 14 | @Mixin(CreativeModeInventoryScreen.class) 15 | public abstract class MixinCreativeInventoryScreen extends AbstractContainerScreen 16 | { 17 | private MixinCreativeInventoryScreen(CreativeModeInventoryScreen.ItemPickerMenu screenHandler, Inventory playerInventory, Component text) 18 | { 19 | super(screenHandler, playerInventory, text); 20 | } 21 | 22 | // This needs to happen before the `this.handler.scrollItems(0.0F);` call. 23 | @Inject(method = "refreshSearchResults", at = @At(value = "INVOKE", 24 | target = "Lnet/minecraft/client/gui/screens/inventory/CreativeModeInventoryScreen$ItemPickerMenu;scrollTo(F)V")) 25 | private void tweakeroo_removeInfestedStoneFromCreativeSearchInventory(CallbackInfo ci) 26 | { 27 | if (Configs.Disable.DISABLE_CREATIVE_INFESTED_BLOCKS.getBooleanValue()) 28 | { 29 | CreativeExtraItems.removeInfestedBlocks(this.menu.items); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/config/ConfigBooleanClient.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.config; 2 | 3 | import java.util.Objects; 4 | 5 | import fi.dy.masa.malilib.config.options.ConfigBooleanHotkeyed; 6 | import fi.dy.masa.malilib.gui.GuiBase; 7 | import fi.dy.masa.malilib.util.StringUtils; 8 | 9 | public class ConfigBooleanClient extends ConfigBooleanHotkeyed 10 | { 11 | public ConfigBooleanClient(String name, boolean defaultValue, String defaultHotkey) 12 | { 13 | this(name, defaultValue, defaultHotkey, name+" Comment!", StringUtils.splitCamelCase(name), name); 14 | } 15 | 16 | public ConfigBooleanClient(String name, boolean defaultValue, String defaultHotkey, String comment) 17 | { 18 | this(name, defaultValue, defaultHotkey, comment, StringUtils.splitCamelCase(name), name); 19 | } 20 | 21 | public ConfigBooleanClient(String name, boolean defaultValue, String defaultHotkey, String comment, String prettyName, String translatedName) 22 | { 23 | super(name, defaultValue, defaultHotkey, comment, prettyName, translatedName); 24 | } 25 | 26 | @Override 27 | public String getComment() 28 | { 29 | // String comment = super.getComment(); 30 | String comment = StringUtils.getTranslatedOrFallback(Objects.requireNonNull(super.getComment()), super.getComment()); 31 | if (comment == null) 32 | { 33 | return ""; 34 | } 35 | 36 | return comment + "\n" + StringUtils.translate("tweakeroo.label.config_comment.single_player_only"); 37 | } 38 | 39 | @Override 40 | public String getConfigGuiDisplayName() 41 | { 42 | return GuiBase.TXT_GOLD + super.getConfigGuiDisplayName() + GuiBase.TXT_RST; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/world/MixinUpdateStructureBlockC2SPacket.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.world; 2 | 3 | import org.objectweb.asm.Opcodes; 4 | import org.spongepowered.asm.mixin.Mixin; 5 | import org.spongepowered.asm.mixin.injection.At; 6 | import org.spongepowered.asm.mixin.injection.Constant; 7 | import org.spongepowered.asm.mixin.injection.ModifyConstant; 8 | import org.spongepowered.asm.mixin.injection.Slice; 9 | import fi.dy.masa.tweakeroo.config.Configs; 10 | import fi.dy.masa.tweakeroo.config.FeatureToggle; 11 | import net.minecraft.network.protocol.game.ServerboundSetStructureBlockPacket; 12 | 13 | @Mixin(value = ServerboundSetStructureBlockPacket.class, priority = 999) 14 | public abstract class MixinUpdateStructureBlockC2SPacket 15 | { 16 | @ModifyConstant(method = "(Lnet/minecraft/network/FriendlyByteBuf;)V", 17 | slice = @Slice(from = @At(value = "FIELD", opcode = Opcodes.PUTFIELD, 18 | target = "Lnet/minecraft/network/protocol/game/ServerboundSetStructureBlockPacket;name:Ljava/lang/String;"), 19 | to = @At(value = "FIELD", opcode = Opcodes.PUTFIELD, 20 | target = "Lnet/minecraft/network/protocol/game/ServerboundSetStructureBlockPacket;mirror:Lnet/minecraft/world/level/block/Mirror;")), 21 | constant = { @Constant(intValue = -48), @Constant(intValue = 48) }, require = 0) 22 | private int tweakeroo_overrideStructureBlockSizeLimit(int original) 23 | { 24 | if (FeatureToggle.TWEAK_STRUCTURE_BLOCK_LIMIT.getBooleanValue()) 25 | { 26 | int overridden = Configs.Generic.STRUCTURE_BLOCK_MAX_SIZE.getIntegerValue(); 27 | return original == -48 ? -overridden : overridden; 28 | } 29 | 30 | return original; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/item/MixinBlockItem.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.item; 2 | 3 | import org.spongepowered.asm.mixin.Mixin; 4 | import org.spongepowered.asm.mixin.Shadow; 5 | import org.spongepowered.asm.mixin.injection.At; 6 | import org.spongepowered.asm.mixin.injection.Inject; 7 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 8 | import fi.dy.masa.tweakeroo.config.Configs; 9 | import fi.dy.masa.tweakeroo.tweaks.PlacementHandler; 10 | import fi.dy.masa.tweakeroo.tweaks.PlacementHandler.UseContext; 11 | import net.minecraft.world.item.BlockItem; 12 | import net.minecraft.world.item.Item; 13 | import net.minecraft.world.item.context.BlockPlaceContext; 14 | import net.minecraft.world.level.block.Block; 15 | import net.minecraft.world.level.block.state.BlockState; 16 | 17 | @Mixin(BlockItem.class) 18 | public abstract class MixinBlockItem extends Item 19 | { 20 | private MixinBlockItem(Item.Properties builder) 21 | { 22 | super(builder); 23 | } 24 | 25 | @Shadow protected abstract boolean canPlace(BlockPlaceContext context, BlockState state); 26 | @Shadow public abstract Block getBlock(); 27 | 28 | @Inject(method = "getPlacementState", at = @At("HEAD"), cancellable = true) 29 | private void tweakeroo_modifyPlacementState(BlockPlaceContext ctx, CallbackInfoReturnable cir) 30 | { 31 | if (Configs.Generic.CLIENT_PLACEMENT_ROTATION.getBooleanValue()) 32 | { 33 | BlockState stateOrig = this.getBlock().getStateForPlacement(ctx); 34 | 35 | if (stateOrig != null) 36 | { 37 | if (!Configs.Generic.CLIENT_PLACEMENT_VALIDATION.getBooleanValue() || this.canPlace(ctx, stateOrig)) 38 | { 39 | UseContext context = UseContext.from(ctx, ctx.getHand()); 40 | cir.setReturnValue(PlacementHandler.applyPlacementProtocolToPlacementState(stateOrig, context)); 41 | } 42 | } 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/render/MixinParticleManager.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.render; 2 | 3 | import fi.dy.masa.tweakeroo.tweaks.RenderTweaks; 4 | import net.minecraft.client.particle.Particle; 5 | import net.minecraft.client.particle.ParticleEngine; 6 | import net.minecraft.core.BlockPos; 7 | import net.minecraft.core.particles.ParticleOptions; 8 | import org.spongepowered.asm.mixin.Mixin; 9 | import org.spongepowered.asm.mixin.injection.At; 10 | import org.spongepowered.asm.mixin.injection.Inject; 11 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 12 | 13 | import fi.dy.masa.tweakeroo.config.Configs; 14 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 15 | 16 | @Mixin(ParticleEngine.class) 17 | public abstract class MixinParticleManager 18 | { 19 | @Inject(method = "add(Lnet/minecraft/client/particle/Particle;)V", at = @At("HEAD"), cancellable = true) 20 | private void disableAllParticles(Particle effect, CallbackInfo ci) 21 | { 22 | if (Configs.Disable.DISABLE_PARTICLES.getBooleanValue()) 23 | { 24 | ci.cancel(); 25 | } 26 | } 27 | 28 | /** 29 | * Copied From Tweak Fork by Andrew54757 30 | */ 31 | @Inject(method = "createParticle(Lnet/minecraft/core/particles/ParticleOptions;DDDDDD)Lnet/minecraft/client/particle/Particle;", 32 | at = @At("HEAD"), cancellable = true) 33 | private void tweakeroo_spawnParticleInject(ParticleOptions parameters, double x, double y, double z, 34 | double velocityX, double velocityY, double velocityZ, 35 | CallbackInfoReturnable cir) 36 | { 37 | if (Configs.Generic.SELECTIVE_BLOCKS_HIDE_PARTICLES.getBooleanValue()) 38 | { 39 | if (!RenderTweaks.isPositionValidForRendering(BlockPos.containing(x, y, z))) 40 | { 41 | cir.setReturnValue(null); 42 | } 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/render/MixinHeldItemRenderer.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.render; 2 | 3 | import org.spongepowered.asm.mixin.Mixin; 4 | import org.spongepowered.asm.mixin.injection.At; 5 | import org.spongepowered.asm.mixin.injection.Inject; 6 | import org.spongepowered.asm.mixin.injection.Redirect; 7 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 8 | import com.mojang.blaze3d.vertex.PoseStack; 9 | import fi.dy.masa.tweakeroo.config.Configs; 10 | import net.minecraft.client.player.AbstractClientPlayer; 11 | import net.minecraft.client.player.LocalPlayer; 12 | import net.minecraft.client.renderer.ItemInHandRenderer; 13 | import net.minecraft.client.renderer.SubmitNodeCollector; 14 | import net.minecraft.world.InteractionHand; 15 | import net.minecraft.world.item.ItemStack; 16 | 17 | @Mixin(ItemInHandRenderer.class) 18 | public abstract class MixinHeldItemRenderer 19 | { 20 | @Redirect(method = "tick()V", at = @At( 21 | value = "INVOKE", 22 | target = "Lnet/minecraft/client/player/LocalPlayer;getItemSwapScale(F)F")) 23 | public float tweakeroo_redirectedGetCooledAttackStrength(LocalPlayer player, float adjustTicks) 24 | { 25 | return Configs.Disable.DISABLE_ITEM_SWITCH_COOLDOWN.getBooleanValue() ? 1.0F : player.getItemSwapScale(adjustTicks); 26 | } 27 | 28 | @Inject(method = "renderArmWithItem", at = @At("HEAD"), cancellable = true) 29 | private void tweakeroo_preventOffhandRendering(AbstractClientPlayer player, 30 | float tickProgress, float pitch, 31 | InteractionHand hand, 32 | float swingProgress, ItemStack item, 33 | float equipProgress, PoseStack matrices, 34 | SubmitNodeCollector orderedRenderCommandQueue, 35 | int light, CallbackInfo ci) 36 | { 37 | if (hand == InteractionHand.OFF_HAND && Configs.Disable.DISABLE_OFFHAND_RENDERING.getBooleanValue()) 38 | { 39 | ci.cancel(); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/util/SnapAimMode.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.util; 2 | 3 | import fi.dy.masa.malilib.config.IConfigOptionListEntry; 4 | import fi.dy.masa.malilib.util.StringUtils; 5 | 6 | public enum SnapAimMode implements IConfigOptionListEntry 7 | { 8 | YAW ("yaw", "tweakeroo.label.snap_aim_mode.yaw"), 9 | PITCH ("pitch", "tweakeroo.label.snap_aim_mode.pitch"), 10 | BOTH ("both", "tweakeroo.label.snap_aim_mode.both"); 11 | 12 | private final String configString; 13 | private final String translationKey; 14 | 15 | SnapAimMode(String configString, String translationKey) 16 | { 17 | this.configString = configString; 18 | this.translationKey = translationKey; 19 | } 20 | 21 | @Override 22 | public String getStringValue() 23 | { 24 | return this.configString; 25 | } 26 | 27 | @Override 28 | public String getDisplayName() 29 | { 30 | return StringUtils.translate(this.translationKey); 31 | } 32 | 33 | @Override 34 | public IConfigOptionListEntry cycle(boolean forward) 35 | { 36 | int id = this.ordinal(); 37 | 38 | if (forward) 39 | { 40 | if (++id >= values().length) 41 | { 42 | id = 0; 43 | } 44 | } 45 | else 46 | { 47 | if (--id < 0) 48 | { 49 | id = values().length - 1; 50 | } 51 | } 52 | 53 | return values()[id % values().length]; 54 | } 55 | 56 | @Override 57 | public SnapAimMode fromString(String name) 58 | { 59 | return fromStringStatic(name); 60 | } 61 | 62 | public static SnapAimMode fromStringStatic(String name) 63 | { 64 | for (SnapAimMode mode : SnapAimMode.values()) 65 | { 66 | if (mode.configString.equalsIgnoreCase(name)) 67 | { 68 | return mode; 69 | } 70 | } 71 | 72 | return SnapAimMode.YAW; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/fog/MixinDarknessEffectFogModifier.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.fog; 2 | 3 | import org.spongepowered.asm.mixin.Mixin; 4 | import org.spongepowered.asm.mixin.injection.At; 5 | import org.spongepowered.asm.mixin.injection.Inject; 6 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 7 | 8 | import fi.dy.masa.tweakeroo.config.FeatureToggle; 9 | import net.minecraft.client.Camera; 10 | import net.minecraft.client.DeltaTracker; 11 | import net.minecraft.client.multiplayer.ClientLevel; 12 | import net.minecraft.client.renderer.fog.FogData; 13 | import net.minecraft.client.renderer.fog.environment.DarknessFogEnvironment; 14 | 15 | @Mixin(DarknessFogEnvironment.class) 16 | public class MixinDarknessEffectFogModifier 17 | { 18 | @Inject(method = "setupFog", at = @At("RETURN")) 19 | private void tweakeroo_redirectDarknessFog(FogData data, Camera camera, ClientLevel clientWorld, float f, 20 | DeltaTracker renderTickCounter, CallbackInfo ci) 21 | { 22 | if (FeatureToggle.TWEAK_DARKNESS_VISIBILITY.getBooleanValue()) 23 | { 24 | // Trying not to make this overpowered... 25 | // To me, this should suffice to 26 | // improve a players' Quality of Life of they also 27 | // change the Accessibility Setting Pulse Strength. 28 | // I wanted to make this bound to some enchantment if I could; 29 | // but I couldn't think of a good one to counter this effect. 30 | // The actual strength value returned by Vanilla here 31 | // tends to be somewhat random and unpredictable and varies. 32 | // Someone could remove the fog by changing the 'adj' value higher, but 33 | // that would be no fun; now would it? :) 34 | final float adj = data.skyEnd * 3.0F; 35 | 36 | data.environmentalStart = adj * 0.75F; 37 | data.environmentalEnd = adj; 38 | data.skyEnd = adj; 39 | data.cloudEnd = adj; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/input/MixinKeyboardInput.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.input; 2 | 3 | import org.objectweb.asm.Opcodes; 4 | 5 | import org.spongepowered.asm.mixin.Final; 6 | import org.spongepowered.asm.mixin.Mixin; 7 | import org.spongepowered.asm.mixin.Shadow; 8 | import org.spongepowered.asm.mixin.injection.At; 9 | import org.spongepowered.asm.mixin.injection.At.Shift; 10 | import org.spongepowered.asm.mixin.injection.Inject; 11 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 12 | import fi.dy.masa.malilib.util.GuiUtils; 13 | import fi.dy.masa.tweakeroo.config.Configs; 14 | import fi.dy.masa.tweakeroo.config.FeatureToggle; 15 | import fi.dy.masa.tweakeroo.event.InputHandler; 16 | import net.minecraft.client.Options; 17 | import net.minecraft.client.player.ClientInput; 18 | import net.minecraft.client.player.KeyboardInput; 19 | import net.minecraft.world.entity.player.Input; 20 | 21 | @Mixin(KeyboardInput.class) 22 | public abstract class MixinKeyboardInput extends ClientInput 23 | { 24 | @Shadow @Final private Options options; 25 | 26 | @Inject(method = "tick", at = @At( 27 | value = "FIELD", 28 | target = "Lnet/minecraft/client/player/KeyboardInput;keyPresses:Lnet/minecraft/world/entity/player/Input;", 29 | ordinal = 0, 30 | shift = Shift.AFTER, 31 | opcode = Opcodes.PUTFIELD)) 32 | private void customMovement(CallbackInfo ci) 33 | { 34 | if (FeatureToggle.TWEAK_MOVEMENT_KEYS.getBooleanValue()) 35 | { 36 | InputHandler.getInstance().handleMovementKeys(this); 37 | } 38 | 39 | if (FeatureToggle.TWEAK_PERMANENT_SNEAK.getBooleanValue() && 40 | (Configs.Generic.PERMANENT_SNEAK_ALLOW_IN_GUIS.getBooleanValue() || GuiUtils.getCurrentScreen() == null)) 41 | { 42 | this.keyPresses = new Input(this.options.keyUp.isDown(), this.options.keyDown.isDown(), this.options.keyLeft.isDown(), this.options.keyRight.isDown(), this.options.keyJump.isDown(), true, this.options.keySprint.isDown()); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/freecam/MixinHeldItemRenderer_freeCam.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.freecam; 2 | 3 | import org.spongepowered.asm.mixin.Mixin; 4 | import org.spongepowered.asm.mixin.injection.At; 5 | import org.spongepowered.asm.mixin.injection.Inject; 6 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 7 | import com.mojang.blaze3d.vertex.PoseStack; 8 | import fi.dy.masa.tweakeroo.config.Configs; 9 | import fi.dy.masa.tweakeroo.config.FeatureToggle; 10 | import net.minecraft.client.player.LocalPlayer; 11 | import net.minecraft.client.renderer.ItemInHandRenderer; 12 | import net.minecraft.client.renderer.SubmitNodeCollector; 13 | import net.minecraft.world.entity.LivingEntity; 14 | import net.minecraft.world.item.ItemDisplayContext; 15 | import net.minecraft.world.item.ItemStack; 16 | 17 | @Mixin(value = ItemInHandRenderer.class, priority = 1005) 18 | public abstract class MixinHeldItemRenderer_freeCam 19 | { 20 | @Inject(method = "renderItem(Lnet/minecraft/world/entity/LivingEntity;Lnet/minecraft/world/item/ItemStack;Lnet/minecraft/world/item/ItemDisplayContext;Lcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/SubmitNodeCollector;I)V", 21 | at = @At("HEAD"), cancellable = true) 22 | private void tweakeroo_cancelHandRendering1(LivingEntity entity, ItemStack stack, ItemDisplayContext renderMode, PoseStack matrices, SubmitNodeCollector orderedRenderCommandQueue, int light, CallbackInfo ci) 23 | { 24 | if (FeatureToggle.TWEAK_FREE_CAMERA.getBooleanValue() && 25 | !Configs.Generic.FREE_CAMERA_SHOW_HANDS.getBooleanValue()) 26 | { 27 | ci.cancel(); 28 | } 29 | } 30 | 31 | @Inject(method = "renderHandsWithItems(FLcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/SubmitNodeCollector;Lnet/minecraft/client/player/LocalPlayer;I)V", 32 | at = @At("HEAD"), cancellable = true) 33 | private void tweakeroo_cancelHandRendering2(float tickProgress, PoseStack matrices, SubmitNodeCollector orderedRenderCommandQueue, LocalPlayer player, int light, CallbackInfo ci) 34 | { 35 | if (FeatureToggle.TWEAK_FREE_CAMERA.getBooleanValue() && 36 | !Configs.Generic.FREE_CAMERA_SHOW_HANDS.getBooleanValue()) 37 | { 38 | ci.cancel(); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/fog/MixinFogRenderer.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.fog; 2 | 3 | import org.spongepowered.asm.mixin.Mixin; 4 | import org.spongepowered.asm.mixin.injection.*; 5 | 6 | import fi.dy.masa.tweakeroo.config.Configs; 7 | import net.minecraft.client.Minecraft; 8 | import net.minecraft.client.multiplayer.ClientLevel; 9 | import net.minecraft.client.renderer.fog.FogRenderer; 10 | import net.minecraft.util.Mth; 11 | 12 | @Mixin(FogRenderer.class) 13 | public class MixinFogRenderer 14 | { 15 | @Redirect(method = "computeFogColor", 16 | at = @At(value = "INVOKE", 17 | target = "Lnet/minecraft/client/multiplayer/ClientLevel$ClientLevelData;voidDarknessOnsetRange()F")) 18 | private float tweakeroo_disableSkyDarkness(ClientLevel.ClientLevelData instance) 19 | { 20 | return Configs.Disable.DISABLE_SKY_DARKNESS.getBooleanValue() ? 1.0F : instance.voidDarknessOnsetRange(); 21 | } 22 | 23 | @ModifyConstant(method = "setupFog(Lnet/minecraft/client/Camera;ILnet/minecraft/client/DeltaTracker;FLnet/minecraft/client/multiplayer/ClientLevel;)Lorg/joml/Vector4f;", 24 | constant = { @Constant(intValue = 16) }) 25 | private int tweakeroo_tweakRenderDistanceFog_DistanceMultiplier(int constant) 26 | { 27 | if (Configs.Disable.DISABLE_RENDER_DISTANCE_FOG.getBooleanValue()) 28 | { 29 | Minecraft mc = Minecraft.getInstance(); 30 | 31 | final int viewDistance = mc.options.getEffectiveRenderDistance(); 32 | final float blocksDistance = Math.max(512.0F, mc.gameRenderer.getRenderDistance()); 33 | 34 | // 42 is the answer :) 35 | return (int) (blocksDistance / viewDistance); 36 | } 37 | 38 | return constant; 39 | } 40 | 41 | @Redirect(method = "setupFog(Lnet/minecraft/client/Camera;ILnet/minecraft/client/DeltaTracker;FLnet/minecraft/client/multiplayer/ClientLevel;)Lorg/joml/Vector4f;", 42 | at = @At(value = "INVOKE", 43 | target = "Lnet/minecraft/util/Mth;clamp(FFF)F")) 44 | private float tweakeroo_tweakRenderDistanceFog_StartDiff(float value, float min, float max) 45 | { 46 | if (Configs.Disable.DISABLE_RENDER_DISTANCE_FOG.getBooleanValue()) 47 | { 48 | return min; 49 | } 50 | 51 | return Mth.clamp(value, min, max); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/util/ItemRestriction.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.util; 2 | 3 | import java.util.HashSet; 4 | import java.util.List; 5 | import java.util.Optional; 6 | import net.minecraft.core.Holder; 7 | import net.minecraft.core.registries.BuiltInRegistries; 8 | import net.minecraft.resources.Identifier; 9 | import net.minecraft.world.item.Item; 10 | import net.minecraft.world.item.ItemStack; 11 | import net.minecraft.world.item.Items; 12 | import fi.dy.masa.malilib.util.restrictions.UsageRestriction.ListType; 13 | import fi.dy.masa.tweakeroo.Tweakeroo; 14 | 15 | public class ItemRestriction 16 | { 17 | private ListType type = ListType.NONE; 18 | private final HashSet blackList = new HashSet<>(); 19 | private final HashSet whiteList = new HashSet<>(); 20 | 21 | public void setValues(ListType type, List namesBlacklist, List namesWhitelist) 22 | { 23 | this.type = type; 24 | this.setValuesForList(ListType.BLACKLIST, namesBlacklist); 25 | this.setValuesForList(ListType.WHITELIST, namesWhitelist); 26 | } 27 | 28 | protected void setValuesForList(ListType type, List names) 29 | { 30 | HashSet set = type == ListType.WHITELIST ? this.whiteList : this.blackList; 31 | set.clear(); 32 | 33 | for (String name : names) 34 | { 35 | try 36 | { 37 | //Item item = Registries.ITEM.get(Identifier.tryParse(name)); 38 | Identifier id = Identifier.tryParse(name); 39 | 40 | if (id != null) 41 | { 42 | Optional> opt = BuiltInRegistries.ITEM.get(id); 43 | 44 | if (opt.isPresent() && opt.get().value() != Items.AIR) 45 | { 46 | set.add(opt.get().value()); 47 | } 48 | else 49 | { 50 | Tweakeroo.LOGGER.warn("Invalid item name in a black- or whitelist: '{}", name); 51 | } 52 | } 53 | } 54 | catch (Exception e) 55 | { 56 | Tweakeroo.LOGGER.warn("Invalid item name in a black- or whitelist: '{}", name, e); 57 | } 58 | } 59 | } 60 | 61 | public boolean isItemAllowed(ItemStack stack) 62 | { 63 | return switch (this.type) 64 | { 65 | case BLACKLIST -> !this.blackList.contains(stack.getItem()); 66 | case WHITELIST -> this.whiteList.contains(stack.getItem()); 67 | default -> true; 68 | }; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/util/PlacementRestrictionMode.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.util; 2 | 3 | import fi.dy.masa.malilib.config.IConfigOptionListEntry; 4 | import fi.dy.masa.malilib.util.StringUtils; 5 | 6 | public enum PlacementRestrictionMode implements IConfigOptionListEntry 7 | { 8 | PLANE ("plane", "tweakeroo.label.placement_restriction_mode.plane"), 9 | FACE ("face", "tweakeroo.label.placement_restriction_mode.face"), 10 | COLUMN ("column", "tweakeroo.label.placement_restriction_mode.column"), 11 | LINE ("line", "tweakeroo.label.placement_restriction_mode.line"), 12 | LAYER ("layer", "tweakeroo.label.placement_restriction_mode.layer"), 13 | DIAGONAL ("diagonal", "tweakeroo.label.placement_restriction_mode.diagonal"); 14 | 15 | private final String configString; 16 | private final String unlocName; 17 | 18 | PlacementRestrictionMode(String configString, String unlocName) 19 | { 20 | this.configString = configString; 21 | this.unlocName = unlocName; 22 | } 23 | 24 | @Override 25 | public String getStringValue() 26 | { 27 | return this.configString; 28 | } 29 | 30 | @Override 31 | public String getDisplayName() 32 | { 33 | return StringUtils.translate(this.unlocName); 34 | } 35 | 36 | @Override 37 | public IConfigOptionListEntry cycle(boolean forward) 38 | { 39 | int id = this.ordinal(); 40 | 41 | if (forward) 42 | { 43 | if (++id >= values().length) 44 | { 45 | id = 0; 46 | } 47 | } 48 | else 49 | { 50 | if (--id < 0) 51 | { 52 | id = values().length - 1; 53 | } 54 | } 55 | 56 | return values()[id % values().length]; 57 | } 58 | 59 | @Override 60 | public PlacementRestrictionMode fromString(String name) 61 | { 62 | return fromStringStatic(name); 63 | } 64 | 65 | public static PlacementRestrictionMode fromStringStatic(String name) 66 | { 67 | for (PlacementRestrictionMode mode : PlacementRestrictionMode.values()) 68 | { 69 | if (mode.configString.equalsIgnoreCase(name)) 70 | { 71 | return mode; 72 | } 73 | } 74 | 75 | return PlacementRestrictionMode.FACE; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/hud/MixinChatHud.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.hud; 2 | 3 | import org.spongepowered.asm.mixin.Mixin; 4 | import org.spongepowered.asm.mixin.injection.At; 5 | import org.spongepowered.asm.mixin.injection.ModifyVariable; 6 | import org.spongepowered.asm.mixin.injection.Redirect; 7 | 8 | import fi.dy.masa.tweakeroo.config.FeatureToggle; 9 | import fi.dy.masa.tweakeroo.util.MiscUtils; 10 | import net.minecraft.client.GuiMessageTag; 11 | import net.minecraft.client.gui.components.ChatComponent; 12 | import net.minecraft.network.chat.Component; 13 | import net.minecraft.network.chat.MessageSignature; 14 | import net.minecraft.network.chat.MutableComponent; 15 | import net.minecraft.util.ARGB; 16 | 17 | @Mixin(value = ChatComponent.class, priority = 1100) 18 | public abstract class MixinChatHud 19 | { 20 | @ModifyVariable(method = "addMessage(Lnet/minecraft/network/chat/Component;Lnet/minecraft/network/chat/MessageSignature;Lnet/minecraft/client/GuiMessageTag;)V", 21 | at = @At("HEAD"), argsOnly = true) 22 | private Component tweakeroo_addMessageTimestamp(Component componentIn, Component parameterMessage, MessageSignature data, GuiMessageTag indicator) 23 | { 24 | if (FeatureToggle.TWEAK_CHAT_TIMESTAMP.getBooleanValue()) 25 | { 26 | MutableComponent newComponent = Component.literal(MiscUtils.getChatTimestamp() + " "); 27 | newComponent.append(componentIn); 28 | return newComponent; 29 | } 30 | 31 | return componentIn; 32 | } 33 | 34 | // 1.21.10: 35 | // method_71992(Lnet/minecraft/client/gui/GuiGraphics;IFFIIIIILnet/minecraft/client/GuiMessage$Line;IF)V // ARGB;color 36 | // 25w46a: 37 | // method_75802(IILnet/minecraft/client/gui/hud/ChatHud$Backend;IFLnet/minecraft/client/gui/hud/ChatHudLine$Visible;IF)V 38 | // 39 | // INVOKEVIRTUAL Bytecode Mixin 40 | @Redirect(method = "method_75802(IILnet/minecraft/client/gui/components/ChatComponent$ChatGraphicsAccess;IFLnet/minecraft/client/GuiMessage$Line;IF)V", 41 | at = @At(value = "INVOKE", 42 | target = "Lnet/minecraft/util/ARGB;black(F)I", 43 | ordinal = 0)) 44 | private static int tweakeroo_overrideChatBackgroundColor(float alpha) 45 | { 46 | if (FeatureToggle.TWEAK_CHAT_BACKGROUND_COLOR.getBooleanValue()) 47 | { 48 | return MiscUtils.getChatBackgroundColor(ARGB.black(alpha)); 49 | } 50 | 51 | // return ColorHelper.withAlpha(alpha, rgb); 52 | return ARGB.black(alpha); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/util/EasyPlacementProtocol.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.util; 2 | 3 | import com.google.common.collect.ImmutableList; 4 | 5 | import fi.dy.masa.malilib.config.IConfigOptionListEntry; 6 | import fi.dy.masa.malilib.util.StringUtils; 7 | 8 | public enum EasyPlacementProtocol implements IConfigOptionListEntry 9 | { 10 | AUTO ("auto", "tweakeroo.gui.label.easy_place_protocol.auto"), 11 | V3 ("v3", "tweakeroo.gui.label.easy_place_protocol.v3"), 12 | V2 ("v2", "tweakeroo.gui.label.easy_place_protocol.v2"), 13 | SLAB_ONLY ("slabs_only", "tweakeroo.gui.label.easy_place_protocol.slabs_only"), 14 | NONE ("none", "tweakeroo.gui.label.easy_place_protocol.none"); 15 | 16 | public static final ImmutableList VALUES = ImmutableList.copyOf(values()); 17 | 18 | private final String configString; 19 | private final String translationKey; 20 | 21 | EasyPlacementProtocol(String configString, String translationKey) 22 | { 23 | this.configString = configString; 24 | this.translationKey = translationKey; 25 | } 26 | 27 | @Override 28 | public String getStringValue() 29 | { 30 | return this.configString; 31 | } 32 | 33 | @Override 34 | public String getDisplayName() 35 | { 36 | return StringUtils.translate(this.translationKey); 37 | } 38 | 39 | @Override 40 | public IConfigOptionListEntry cycle(boolean forward) 41 | { 42 | int id = this.ordinal(); 43 | 44 | if (forward) 45 | { 46 | if (++id >= values().length) 47 | { 48 | id = 0; 49 | } 50 | } 51 | else 52 | { 53 | if (--id < 0) 54 | { 55 | id = values().length - 1; 56 | } 57 | } 58 | 59 | return values()[id % values().length]; 60 | } 61 | 62 | @Override 63 | public EasyPlacementProtocol fromString(String name) 64 | { 65 | return fromStringStatic(name); 66 | } 67 | 68 | public static EasyPlacementProtocol fromStringStatic(String name) 69 | { 70 | for (EasyPlacementProtocol val : VALUES) 71 | { 72 | if (val.configString.equalsIgnoreCase(name)) 73 | { 74 | return val; 75 | } 76 | } 77 | 78 | return EasyPlacementProtocol.AUTO; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/block/MixinHopperBlockEntity.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.block; 2 | 3 | import com.llamalad7.mixinextras.injector.wrapoperation.Operation; 4 | import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; 5 | import org.spongepowered.asm.mixin.Mixin; 6 | import org.spongepowered.asm.mixin.injection.At; 7 | import org.spongepowered.asm.mixin.injection.Inject; 8 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 9 | 10 | import fi.dy.masa.tweakeroo.config.Configs; 11 | import fi.dy.masa.tweakeroo.util.MiscUtils; 12 | import net.minecraft.world.item.ItemStack; 13 | import net.minecraft.world.level.block.entity.HopperBlockEntity; 14 | 15 | /** 16 | * ... by KikuGie 17 | * Priority 999 if installed with stackable-shulkers-fix 18 | */ 19 | @Mixin(value = HopperBlockEntity.class, priority = 999) 20 | public class MixinHopperBlockEntity 21 | { 22 | @WrapOperation( 23 | method = "inventoryFull", 24 | at = @At(value = "INVOKE", target = "Lnet/minecraft/world/item/ItemStack;getMaxStackSize()I") 25 | ) 26 | private int modifyShulkerMaxCount(ItemStack instance, Operation original) 27 | { 28 | if (Configs.Fixes.STACKABLE_SHULKERS_IN_HOPPER_FIX.getBooleanValue()) 29 | { 30 | return MiscUtils.isShulkerBox(instance) ? instance.getCount() : original.call(instance); 31 | } 32 | 33 | return original.call(instance); 34 | } 35 | 36 | @WrapOperation( 37 | method = "isFullContainer", 38 | at = @At(value = "INVOKE", target = "Lnet/minecraft/world/item/ItemStack;getMaxStackSize()I") 39 | ) 40 | private static int modifyShulkerMaxCountStatic(ItemStack instance, Operation original) 41 | { 42 | if (Configs.Fixes.STACKABLE_SHULKERS_IN_HOPPER_FIX.getBooleanValue()) 43 | { 44 | return MiscUtils.isShulkerBox(instance) ? 1 : original.call(instance); 45 | } 46 | 47 | return original.call(instance); 48 | } 49 | 50 | @Inject( 51 | method = "canMergeItems", 52 | at = @At("HEAD"), 53 | cancellable = true 54 | ) 55 | private static void cancelItemMerging(ItemStack first, ItemStack second, CallbackInfoReturnable cir) 56 | { 57 | if (Configs.Fixes.STACKABLE_SHULKERS_IN_HOPPER_FIX.getBooleanValue()) 58 | { 59 | if (MiscUtils.isShulkerBox(first) || MiscUtils.isShulkerBox(second)) cir.setReturnValue(false); 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/screen/MixinChatScreen.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.screen; 2 | 3 | import org.spongepowered.asm.mixin.Mixin; 4 | import org.spongepowered.asm.mixin.Mutable; 5 | import org.spongepowered.asm.mixin.Shadow; 6 | import org.spongepowered.asm.mixin.injection.*; 7 | import org.spongepowered.asm.mixin.injection.At.Shift; 8 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 9 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 10 | 11 | import fi.dy.masa.tweakeroo.config.Configs; 12 | import fi.dy.masa.tweakeroo.config.FeatureToggle; 13 | import fi.dy.masa.tweakeroo.util.MiscUtils; 14 | import net.minecraft.client.gui.components.EditBox; 15 | import net.minecraft.client.gui.screens.ChatScreen; 16 | import net.minecraft.client.input.KeyEvent; 17 | 18 | @Mixin(ChatScreen.class) 19 | public abstract class MixinChatScreen 20 | { 21 | @Shadow protected EditBox input; 22 | @Mutable @Shadow protected String initial; 23 | 24 | @Inject(method = "removed", at = @At("HEAD")) 25 | private void tweakeroo_storeChatText(CallbackInfo ci) 26 | { 27 | if (FeatureToggle.TWEAK_CHAT_PERSISTENT_TEXT.getBooleanValue()) 28 | { 29 | MiscUtils.setLastChatText(this.input.getValue()); 30 | } 31 | } 32 | 33 | @Inject(method = "", at = @At("RETURN")) 34 | private void tweakeroo_restoreText(String text, boolean draft, CallbackInfo ci) 35 | { 36 | if (FeatureToggle.TWEAK_CHAT_PERSISTENT_TEXT.getBooleanValue() && 37 | MiscUtils.getLastChatText().isEmpty() == false) 38 | { 39 | this.initial = MiscUtils.getLastChatText(); 40 | } 41 | } 42 | 43 | @Inject(method = "keyPressed(Lnet/minecraft/client/input/KeyEvent;)Z", 44 | slice = @Slice( 45 | from = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screens/ChatScreen;handleChatInput(Ljava/lang/String;Z)V")), 46 | at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Minecraft;setScreen(Lnet/minecraft/client/gui/screens/Screen;)V", shift = Shift.AFTER)) 47 | private void tweakeroo_onSendMessage(KeyEvent input, CallbackInfoReturnable cir) 48 | { 49 | MiscUtils.setLastChatText(""); 50 | } 51 | 52 | @ModifyConstant(method = "render", constant = @Constant(intValue = Integer.MIN_VALUE)) 53 | private int overrideChatBackgroundColor(int original) 54 | { 55 | if (FeatureToggle.TWEAK_CHAT_BACKGROUND_COLOR.getBooleanValue()) 56 | { 57 | return Configs.Generic.CHAT_BACKGROUND_COLOR.getIntegerValue(); 58 | } 59 | 60 | return original; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/block/MixinSignBlockEntity.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.block; 2 | 3 | import org.spongepowered.asm.mixin.Mixin; 4 | import org.spongepowered.asm.mixin.Shadow; 5 | import org.spongepowered.asm.mixin.injection.At; 6 | import org.spongepowered.asm.mixin.injection.Inject; 7 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 8 | 9 | import fi.dy.masa.tweakeroo.config.FeatureToggle; 10 | import fi.dy.masa.tweakeroo.util.IGuiEditSign; 11 | import fi.dy.masa.tweakeroo.util.ISignTextAccess; 12 | import fi.dy.masa.tweakeroo.util.MiscUtils; 13 | import net.minecraft.client.Minecraft; 14 | import net.minecraft.client.gui.screens.inventory.HangingSignEditScreen; 15 | import net.minecraft.client.gui.screens.inventory.SignEditScreen; 16 | import net.minecraft.core.BlockPos; 17 | import net.minecraft.world.level.block.entity.BlockEntity; 18 | import net.minecraft.world.level.block.entity.BlockEntityType; 19 | import net.minecraft.world.level.block.entity.SignBlockEntity; 20 | import net.minecraft.world.level.block.entity.SignText; 21 | import net.minecraft.world.level.block.state.BlockState; 22 | import net.minecraft.world.level.storage.ValueInput; 23 | 24 | @Mixin(SignBlockEntity.class) 25 | public abstract class MixinSignBlockEntity extends BlockEntity implements ISignTextAccess 26 | { 27 | @Shadow private SignText frontText; 28 | @Shadow private SignText backText; 29 | 30 | private MixinSignBlockEntity(BlockEntityType blockEntityType, BlockPos blockPos, BlockState blockState) 31 | { 32 | super(blockEntityType, blockPos, blockState); 33 | } 34 | 35 | @Inject(method = "loadAdditional", at = @At("RETURN")) 36 | private void tweakeroo_restoreCopiedText(ValueInput view, CallbackInfo ci) 37 | { 38 | // Restore the copied/pasted text after the TileEntity sync overrides it with empty lines 39 | if (FeatureToggle.TWEAK_SIGN_COPY.getBooleanValue() && this.getLevel() != null && this.getLevel().isClientSide()) 40 | { 41 | Minecraft mc = Minecraft.getInstance(); 42 | 43 | if (mc.screen instanceof SignEditScreen || mc.screen instanceof HangingSignEditScreen) 44 | { 45 | if (((IGuiEditSign) mc.screen).tweakeroo$getTile() == (Object) this) 46 | { 47 | MiscUtils.applyPreviousTextToSign((SignBlockEntity) (Object) this, null, ((SignBlockEntity) (Object) this).isFacingFrontText(mc.player)); 48 | } 49 | } 50 | } 51 | } 52 | 53 | @Override 54 | public SignText tweakeroo$getText(boolean front) 55 | { 56 | return front ? this.frontText : this.backText; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/hud/MixinInGameHud.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.hud; 2 | 3 | import org.spongepowered.asm.mixin.Final; 4 | import org.spongepowered.asm.mixin.Mixin; 5 | import org.spongepowered.asm.mixin.Shadow; 6 | import org.spongepowered.asm.mixin.injection.At; 7 | import org.spongepowered.asm.mixin.injection.Inject; 8 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 9 | 10 | import fi.dy.masa.tweakeroo.config.Configs; 11 | import fi.dy.masa.tweakeroo.config.FeatureToggle; 12 | import net.minecraft.client.DeltaTracker; 13 | import net.minecraft.client.Minecraft; 14 | import net.minecraft.client.gui.Gui; 15 | import net.minecraft.client.gui.GuiGraphics; 16 | import net.minecraft.client.gui.components.PlayerTabOverlay; 17 | import net.minecraft.world.scores.DisplaySlot; 18 | import net.minecraft.world.scores.Objective; 19 | import net.minecraft.world.scores.Scoreboard; 20 | 21 | @Mixin(value = Gui.class, priority = 1001) 22 | public abstract class MixinInGameHud 23 | { 24 | @Shadow @Final private PlayerTabOverlay tabList; 25 | @Shadow @Final private Minecraft minecraft; 26 | 27 | @Inject(method = "renderTabList", 28 | at = @At(value = "INVOKE", 29 | target = "Lnet/minecraft/client/gui/components/PlayerTabOverlay;setVisible(Z)V", 30 | ordinal = 1, shift = At.Shift.AFTER)) 31 | private void tweakeroo_alwaysRenderPlayerList(GuiGraphics context, DeltaTracker tickCounter, CallbackInfo ci) 32 | { 33 | if (FeatureToggle.TWEAK_PLAYER_LIST_ALWAYS_ON.getBooleanValue() && this.minecraft.level != null) 34 | { 35 | Scoreboard scoreboard = this.minecraft.level.getScoreboard(); 36 | Objective objective = scoreboard.getDisplayObjective(DisplaySlot.LIST); 37 | 38 | this.tabList.setVisible(true); 39 | this.tabList.render(context, context.guiWidth(), scoreboard, objective); 40 | } 41 | } 42 | 43 | @Inject(method = "displayScoreboardSidebar(Lnet/minecraft/client/gui/GuiGraphics;Lnet/minecraft/world/scores/Objective;)V", 44 | at = @At("HEAD"), cancellable = true) 45 | private void tweakeroo_disableScoreboardRendering(CallbackInfo ci) 46 | { 47 | if (Configs.Disable.DISABLE_SCOREBOARD_RENDERING.getBooleanValue()) 48 | { 49 | ci.cancel(); 50 | } 51 | } 52 | 53 | @Inject(method = "renderEffects", at = @At("HEAD"), cancellable = true) 54 | private void tweakeroo_disableStatusEffectHudRendering(CallbackInfo ci) 55 | { 56 | if (Configs.Disable.DISABLE_STATUS_EFFECT_HUD.getBooleanValue()) 57 | { 58 | ci.cancel(); 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/world/MixinWorld.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.world; 2 | 3 | import java.util.function.Consumer; 4 | import net.minecraft.client.Minecraft; 5 | import net.minecraft.core.BlockPos; 6 | import net.minecraft.world.entity.Entity; 7 | import net.minecraft.world.entity.player.Player; 8 | import net.minecraft.world.level.Level; 9 | import net.minecraft.world.level.block.state.BlockState; 10 | import org.spongepowered.asm.mixin.Final; 11 | import org.spongepowered.asm.mixin.Mixin; 12 | import org.spongepowered.asm.mixin.Shadow; 13 | import org.spongepowered.asm.mixin.injection.At; 14 | import org.spongepowered.asm.mixin.injection.Inject; 15 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 16 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 17 | import fi.dy.masa.tweakeroo.config.Configs; 18 | import fi.dy.masa.tweakeroo.tweaks.RenderTweaks; 19 | 20 | @Mixin(Level.class) 21 | public abstract class MixinWorld 22 | { 23 | @Shadow @Final private boolean isClientSide; 24 | 25 | @Inject(method = "tickBlockEntities", at = @At("HEAD"), cancellable = true) 26 | private void disableBlockEntityTicking(CallbackInfo ci) 27 | { 28 | if (Configs.Disable.DISABLE_TILE_ENTITY_TICKING.getBooleanValue()) 29 | { 30 | ci.cancel(); 31 | } 32 | } 33 | 34 | @Inject(method = "guardEntityTick(Ljava/util/function/Consumer;Lnet/minecraft/world/entity/Entity;)V", at = @At("HEAD"), cancellable = true) 35 | private void preventEntityTicking(Consumer consumer, T entityIn, CallbackInfo ci) 36 | { 37 | if (Configs.Disable.DISABLE_ENTITY_TICKING.getBooleanValue() && (entityIn instanceof Player) == false) 38 | { 39 | ci.cancel(); 40 | } 41 | } 42 | 43 | /** 44 | * Copied From Tweak Fork by Andrew54757 45 | */ 46 | @Inject(method = "setBlock(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;II)Z", at = @At("HEAD"), cancellable = true) 47 | private void setBlockStateInject(BlockPos pos, BlockState state, int flags, int maxUpdateDepth, CallbackInfoReturnable ci) 48 | { 49 | if (!this.isClientSide) 50 | { 51 | return; 52 | } 53 | 54 | if (!RenderTweaks.isPositionValidForRendering(pos)) 55 | { 56 | if ((flags & RenderTweaks.PASSTHROUGH) != 0) 57 | { 58 | return; 59 | } 60 | 61 | Minecraft mc = Minecraft.getInstance(); 62 | RenderTweaks.setFakeBlockState(mc.level, pos, state, null); 63 | ci.setReturnValue(false); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/render/MixinWindow.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.render; 2 | 3 | import org.spongepowered.asm.mixin.Mixin; 4 | import org.spongepowered.asm.mixin.Shadow; 5 | import org.spongepowered.asm.mixin.injection.At; 6 | import org.spongepowered.asm.mixin.injection.Inject; 7 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 8 | import com.mojang.blaze3d.platform.Window; 9 | import fi.dy.masa.tweakeroo.config.Configs; 10 | import fi.dy.masa.tweakeroo.config.FeatureToggle; 11 | import net.minecraft.client.Minecraft; 12 | import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; 13 | 14 | @Mixin(Window.class) 15 | public abstract class MixinWindow 16 | { 17 | @Shadow public abstract int getScreenWidth(); 18 | @Shadow public abstract int getScreenHeight(); 19 | 20 | @Inject(method = "getGuiScale", at = @At("HEAD"), cancellable = true) 21 | private void tweakeroo_customGuiScaleGetScale(CallbackInfoReturnable cir) 22 | { 23 | if (FeatureToggle.TWEAK_CUSTOM_INVENTORY_GUI_SCALE.getBooleanValue() && 24 | Minecraft.getInstance().screen instanceof AbstractContainerScreen) 25 | { 26 | int scale = Configs.Generic.CUSTOM_INVENTORY_GUI_SCALE.getIntegerValue(); 27 | 28 | if (scale > 0) 29 | { 30 | cir.setReturnValue(scale); 31 | } 32 | } 33 | } 34 | 35 | @Inject(method = "getGuiScaledWidth", at = @At("HEAD"), cancellable = true) 36 | private void tweakeroo_customGuiScaleGetWidth(CallbackInfoReturnable cir) 37 | { 38 | if (FeatureToggle.TWEAK_CUSTOM_INVENTORY_GUI_SCALE.getBooleanValue() && 39 | Minecraft.getInstance().screen instanceof AbstractContainerScreen) 40 | { 41 | int scale = Configs.Generic.CUSTOM_INVENTORY_GUI_SCALE.getIntegerValue(); 42 | 43 | if (scale > 0) 44 | { 45 | cir.setReturnValue((int) Math.ceil((double) this.getScreenWidth() / scale)); 46 | } 47 | } 48 | } 49 | 50 | @Inject(method = "getGuiScaledHeight", at = @At("HEAD"), cancellable = true) 51 | private void tweakeroo_customGuiScaleGetHeight(CallbackInfoReturnable cir) 52 | { 53 | if (FeatureToggle.TWEAK_CUSTOM_INVENTORY_GUI_SCALE.getBooleanValue() && 54 | Minecraft.getInstance().screen instanceof AbstractContainerScreen) 55 | { 56 | int scale = Configs.Generic.CUSTOM_INVENTORY_GUI_SCALE.getIntegerValue(); 57 | 58 | if (scale > 0) 59 | { 60 | cir.setReturnValue((int) Math.ceil((double) this.getScreenHeight() / scale)); 61 | } 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/item/MixinItemStack.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.item; 2 | 3 | import java.util.function.Consumer; 4 | import net.minecraft.core.component.DataComponentMap; 5 | import net.minecraft.core.component.DataComponentType; 6 | import net.minecraft.core.component.DataComponents; 7 | import net.minecraft.network.chat.Component; 8 | import net.minecraft.world.item.BlockItem; 9 | import net.minecraft.world.item.Item; 10 | import net.minecraft.world.item.ItemStack; 11 | import net.minecraft.world.item.TooltipFlag; 12 | import net.minecraft.world.item.component.TooltipDisplay; 13 | import net.minecraft.world.level.block.ShulkerBoxBlock; 14 | import org.spongepowered.asm.mixin.Mixin; 15 | import org.spongepowered.asm.mixin.Shadow; 16 | import org.spongepowered.asm.mixin.injection.At; 17 | import org.spongepowered.asm.mixin.injection.Inject; 18 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 19 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 20 | 21 | import fi.dy.masa.malilib.util.InventoryUtils; 22 | import fi.dy.masa.tweakeroo.config.Configs; 23 | import fi.dy.masa.tweakeroo.config.FeatureToggle; 24 | 25 | @Mixin(ItemStack.class) 26 | public abstract class MixinItemStack 27 | { 28 | @Shadow public abstract Item getItem(); 29 | @Shadow public abstract DataComponentMap getComponents(); 30 | 31 | @Inject(method = "getMaxStackSize", at = @At("RETURN"), cancellable = true) 32 | public void tweakeroo_getMaxStackSizeStackSensitive(CallbackInfoReturnable cir) 33 | { 34 | if (FeatureToggle.TWEAK_SHULKERBOX_STACKING.getBooleanValue() && 35 | this.getItem() instanceof BlockItem block && 36 | block.getBlock() instanceof ShulkerBoxBlock && 37 | InventoryUtils.shulkerBoxHasItems((ItemStack) (Object) this) == false) 38 | { 39 | if (this.getComponents().getOrDefault(DataComponents.MAX_STACK_SIZE, 1) < Configs.Internal.SHULKER_MAX_STACK_SIZE.getIntegerValue()) 40 | { 41 | cir.setReturnValue(Configs.Internal.SHULKER_MAX_STACK_SIZE.getIntegerValue()); 42 | } 43 | } 44 | } 45 | 46 | @Inject(method = "addToTooltip", at = @At("HEAD"), cancellable = true) 47 | private void tweakeroo_removeVanillaTooltip(DataComponentType componentType, Item.TooltipContext context, TooltipDisplay displayComponent, Consumer textConsumer, TooltipFlag type, CallbackInfo ci) 48 | { 49 | if (this.getItem() instanceof BlockItem block && 50 | block.getBlock() instanceof ShulkerBoxBlock && 51 | componentType == DataComponents.CONTAINER && 52 | Configs.Disable.DISABLE_SHULKER_BOX_TOOLTIP.getBooleanValue()) 53 | { 54 | ci.cancel(); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/InitHandler.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo; 2 | 3 | import fi.dy.masa.malilib.command.ClientCommandHandler; 4 | import fi.dy.masa.malilib.config.ConfigManager; 5 | import fi.dy.masa.malilib.event.*; 6 | import fi.dy.masa.malilib.interfaces.IInitializationHandler; 7 | import fi.dy.masa.malilib.interfaces.IRenderer; 8 | import fi.dy.masa.malilib.interfaces.IWorldLoadListener; 9 | import fi.dy.masa.malilib.registry.Registry; 10 | import fi.dy.masa.malilib.util.data.ModInfo; 11 | import fi.dy.masa.tweakeroo.command.FcCommand; 12 | import fi.dy.masa.tweakeroo.config.Callbacks; 13 | import fi.dy.masa.tweakeroo.config.Configs; 14 | import fi.dy.masa.tweakeroo.data.DataManager; 15 | import fi.dy.masa.tweakeroo.data.EntityDataManager; 16 | import fi.dy.masa.tweakeroo.event.ClientTickHandler; 17 | import fi.dy.masa.tweakeroo.event.InputHandler; 18 | import fi.dy.masa.tweakeroo.event.RenderHandler; 19 | import fi.dy.masa.tweakeroo.event.WorldLoadListener; 20 | import fi.dy.masa.tweakeroo.gui.GuiConfigs; 21 | import net.minecraft.client.Minecraft; 22 | 23 | public class InitHandler implements IInitializationHandler 24 | { 25 | @Override 26 | public void registerModHandlers() 27 | { 28 | ConfigManager.getInstance().registerConfigHandler(Reference.MOD_ID, new Configs()); 29 | Registry.CONFIG_SCREEN.registerConfigScreenFactory( 30 | new ModInfo(Reference.MOD_ID, Reference.MOD_NAME, GuiConfigs::new) 31 | ); 32 | EntityDataManager.getInstance().onGameInit(); 33 | 34 | InputEventHandler.getKeybindManager().registerKeybindProvider(InputHandler.getInstance()); 35 | InputEventHandler.getInputManager().registerKeyboardInputHandler(InputHandler.getInstance()); 36 | InputEventHandler.getInputManager().registerMouseInputHandler(InputHandler.getInstance()); 37 | 38 | IRenderer renderer = new RenderHandler(); 39 | RenderEventHandler.getInstance().registerGameOverlayRenderer(renderer); 40 | RenderEventHandler.getInstance().registerTooltipLastRenderer(renderer); 41 | RenderEventHandler.getInstance().registerWorldLastRenderer(renderer); 42 | 43 | IWorldLoadListener worldListener = new WorldLoadListener(); 44 | WorldLoadHandler.getInstance().registerWorldLoadPreHandler(worldListener); 45 | WorldLoadHandler.getInstance().registerWorldLoadPostHandler(worldListener); 46 | 47 | ServerHandler.getInstance().registerServerHandler(DataManager.getInstance()); 48 | 49 | TickHandler.getInstance().registerClientTickHandler(new ClientTickHandler()); 50 | TickHandler.getInstance().registerClientTickHandler(EntityDataManager.getInstance()); 51 | 52 | ClientCommandHandler.INSTANCE.registerCommand(new FcCommand()); 53 | Callbacks.init(Minecraft.getInstance()); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/input/MixinClientCommandSource.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.input; 2 | 3 | import java.util.Collection; 4 | import java.util.Collections; 5 | import java.util.Locale; 6 | import net.minecraft.client.Minecraft; 7 | import net.minecraft.client.multiplayer.ClientSuggestionProvider; 8 | import net.minecraft.commands.SharedSuggestionProvider; 9 | import net.minecraft.core.BlockPos; 10 | import net.minecraft.world.phys.HitResult; 11 | import org.spongepowered.asm.mixin.Mixin; 12 | import org.spongepowered.asm.mixin.Unique; 13 | import org.spongepowered.asm.mixin.injection.At; 14 | import org.spongepowered.asm.mixin.injection.Inject; 15 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 16 | import fi.dy.masa.malilib.util.position.PositionUtils; 17 | import fi.dy.masa.tweakeroo.config.FeatureToggle; 18 | 19 | @Mixin(ClientSuggestionProvider.class) 20 | public abstract class MixinClientCommandSource 21 | { 22 | @Inject(method = "getRelevantCoordinates", at = @At("HEAD"), cancellable = true) 23 | private void onGetBlockPositionSuggestions(CallbackInfoReturnable> cir) 24 | { 25 | Minecraft mc = Minecraft.getInstance(); 26 | 27 | if (FeatureToggle.TWEAK_TAB_COMPLETE_COORDINATE.getBooleanValue() && 28 | mc.player != null && (mc.hitResult == null || mc.hitResult.getType() == HitResult.Type.MISS)) 29 | { 30 | BlockPos pos = PositionUtils.getEntityBlockPos(mc.player); 31 | //System.out.printf("onGetBlockPositionSuggestions(): suggestedPos: [%s]\n", pos.toShortString()); 32 | cir.setReturnValue(Collections.singleton(new SharedSuggestionProvider.TextCoordinates(formatInt(pos.getX()), formatInt(pos.getY()), formatInt(pos.getZ())))); 33 | } 34 | } 35 | 36 | @Inject(method = "getAbsoluteCoordinates", at = @At("HEAD"), cancellable = true) 37 | private void onGetPositionSuggestions(CallbackInfoReturnable> cir) 38 | { 39 | Minecraft mc = Minecraft.getInstance(); 40 | 41 | if (FeatureToggle.TWEAK_TAB_COMPLETE_COORDINATE.getBooleanValue() && 42 | mc.player != null && (mc.hitResult == null || mc.hitResult.getType() == HitResult.Type.MISS)) 43 | { 44 | cir.setReturnValue(Collections.singleton(new SharedSuggestionProvider.TextCoordinates(formatDouble(mc.player.getX()), formatDouble(mc.player.getY()), formatDouble(mc.player.getZ())))); 45 | } 46 | } 47 | 48 | @Unique 49 | private static String formatDouble(double val) 50 | { 51 | return String.format(Locale.ROOT, "%.2f", val); 52 | } 53 | 54 | @Unique 55 | private static String formatInt(int val) 56 | { 57 | return Integer.toString(val); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/freecam/MixinClientPlayerEntity_freeCam.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.freecam; 2 | 3 | import com.mojang.authlib.GameProfile; 4 | import org.spongepowered.asm.mixin.Mixin; 5 | import org.spongepowered.asm.mixin.Shadow; 6 | import org.spongepowered.asm.mixin.Unique; 7 | import org.spongepowered.asm.mixin.injection.At; 8 | import org.spongepowered.asm.mixin.injection.Inject; 9 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 10 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 11 | 12 | import fi.dy.masa.tweakeroo.config.FeatureToggle; 13 | import fi.dy.masa.tweakeroo.util.CameraEntity; 14 | import fi.dy.masa.tweakeroo.util.CameraUtils; 15 | import fi.dy.masa.tweakeroo.util.DummyMovementInput; 16 | 17 | import net.minecraft.client.Options; 18 | import net.minecraft.client.multiplayer.ClientLevel; 19 | import net.minecraft.client.player.AbstractClientPlayer; 20 | import net.minecraft.client.player.ClientInput; 21 | import net.minecraft.client.player.LocalPlayer; 22 | import net.minecraft.world.InteractionHand; 23 | 24 | @Mixin(value = LocalPlayer.class, priority = 1005) 25 | public abstract class MixinClientPlayerEntity_freeCam extends AbstractClientPlayer 26 | { 27 | @Shadow public ClientInput input; 28 | 29 | @Unique private final DummyMovementInput dummyMovementInput = new DummyMovementInput(null); 30 | @Unique private ClientInput realInput; 31 | 32 | private MixinClientPlayerEntity_freeCam(ClientLevel world, GameProfile profile) 33 | { 34 | super(world, profile); 35 | } 36 | 37 | @Inject(method = "tick", at = @At("HEAD")) 38 | private void tweakeroo_disableMovementInputsPre(CallbackInfo ci) 39 | { 40 | if (CameraUtils.shouldPreventPlayerMovement()) 41 | { 42 | this.realInput = this.input; 43 | this.input = this.dummyMovementInput; 44 | } 45 | } 46 | 47 | @Inject(method = "tick", at = @At("RETURN")) 48 | private void tweakeroo_disableMovementInputsPost(CallbackInfo ci) 49 | { 50 | if (this.realInput != null) 51 | { 52 | this.input = this.realInput; 53 | this.realInput = null; 54 | } 55 | } 56 | 57 | @Inject(method = "isControlledCamera", at = @At("HEAD"), cancellable = true) 58 | private void tweakeroo_allowPlayerMovementInFreeCameraMode(CallbackInfoReturnable cir) 59 | { 60 | if (FeatureToggle.TWEAK_FREE_CAMERA.getBooleanValue() && CameraEntity.originalCameraWasPlayer()) 61 | { 62 | cir.setReturnValue(true); 63 | } 64 | } 65 | 66 | @Inject(method = "swing", at = @At("HEAD"), cancellable = true) 67 | private void tweakeroo_preventHandSwing(InteractionHand hand, CallbackInfo ci) 68 | { 69 | if (CameraUtils.shouldPreventPlayerInputs()) 70 | { 71 | ci.cancel(); 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/freecam/MixinGameRenderer_freeCam.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.freecam; 2 | 3 | import com.llamalad7.mixinextras.injector.ModifyExpressionValue; 4 | import org.spongepowered.asm.mixin.Final; 5 | import org.spongepowered.asm.mixin.Mixin; 6 | import org.spongepowered.asm.mixin.Shadow; 7 | import org.spongepowered.asm.mixin.injection.At; 8 | import org.spongepowered.asm.mixin.injection.Inject; 9 | import org.spongepowered.asm.mixin.injection.ModifyVariable; 10 | import org.spongepowered.asm.mixin.injection.Redirect; 11 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 12 | 13 | import fi.dy.masa.tweakeroo.config.Configs; 14 | import fi.dy.masa.tweakeroo.config.FeatureToggle; 15 | import net.minecraft.client.Minecraft; 16 | import net.minecraft.client.renderer.GameRenderer; 17 | import net.minecraft.world.entity.Entity; 18 | 19 | @Mixin(value = GameRenderer.class, priority = 1005) 20 | public abstract class MixinGameRenderer_freeCam 21 | { 22 | @Shadow @Final private Minecraft minecraft; 23 | 24 | @ModifyExpressionValue(method = "getFov", at = @At(value = "CONSTANT", args = "floatValue=70.0")) 25 | private float tweakeroo_applyFreeCameraFov(float original) 26 | { 27 | if (FeatureToggle.TWEAK_FREE_CAMERA.getBooleanValue()) 28 | { 29 | return ((float) this.minecraft.options.fov().get()); 30 | } 31 | 32 | return original; 33 | } 34 | 35 | @ModifyVariable(method = "getFov", at = @At(value = "LOAD", ordinal = 0), argsOnly = true) 36 | private boolean tweakeroo_freezeFovOnFreeCamera(boolean value) 37 | { 38 | return !FeatureToggle.TWEAK_FREE_CAMERA.getBooleanValue() && value; 39 | } 40 | 41 | @Redirect(method = "pick(F)V", at = @At(value = "INVOKE", 42 | target = "Lnet/minecraft/client/Minecraft;getCameraEntity()Lnet/minecraft/world/entity/Entity;")) 43 | private Entity tweakeroo_overrideCameraEntityForRayTrace(Minecraft mc) 44 | { 45 | // Return the real player for the hit target ray tracing if the 46 | // player inputs option is enabled in Free Camera mode. 47 | // Normally in Free Camera mode the Tweakeroo CameraEntity is set as the 48 | // render view/camera entity, which would then also ray trace from the camera point of view. 49 | if (FeatureToggle.TWEAK_FREE_CAMERA.getBooleanValue() && 50 | Configs.Generic.FREE_CAMERA_PLAYER_INPUTS.getBooleanValue() && 51 | !FeatureToggle.TWEAK_AREA_SELECTOR.getBooleanValue() && 52 | mc.player != null) 53 | { 54 | return mc.player; 55 | } 56 | 57 | return mc.getCameraEntity(); 58 | } 59 | 60 | @Inject(method = "renderItemInHand", at = @At("HEAD"), cancellable = true) 61 | private void tweakeroo_removeHandRendering(CallbackInfo ci) 62 | { 63 | if (FeatureToggle.TWEAK_FREE_CAMERA.getBooleanValue() && 64 | !Configs.Generic.FREE_CAMERA_SHOW_HANDS.getBooleanValue()) 65 | { 66 | ci.cancel(); 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | @rem SPDX-License-Identifier: Apache-2.0 17 | @rem 18 | 19 | @if "%DEBUG%"=="" @echo off 20 | @rem ########################################################################## 21 | @rem 22 | @rem Gradle startup script for Windows 23 | @rem 24 | @rem ########################################################################## 25 | 26 | @rem Set local scope for the variables with windows NT shell 27 | if "%OS%"=="Windows_NT" setlocal 28 | 29 | set DIRNAME=%~dp0 30 | if "%DIRNAME%"=="" set DIRNAME=. 31 | @rem This is normally unused 32 | set APP_BASE_NAME=%~n0 33 | set APP_HOME=%DIRNAME% 34 | 35 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 36 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 37 | 38 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 39 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 40 | 41 | @rem Find java.exe 42 | if defined JAVA_HOME goto findJavaFromJavaHome 43 | 44 | set JAVA_EXE=java.exe 45 | %JAVA_EXE% -version >NUL 2>&1 46 | if %ERRORLEVEL% equ 0 goto execute 47 | 48 | echo. 1>&2 49 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 50 | echo. 1>&2 51 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2 52 | echo location of your Java installation. 1>&2 53 | 54 | goto fail 55 | 56 | :findJavaFromJavaHome 57 | set JAVA_HOME=%JAVA_HOME:"=% 58 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 59 | 60 | if exist "%JAVA_EXE%" goto execute 61 | 62 | echo. 1>&2 63 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 64 | echo. 1>&2 65 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2 66 | echo location of your Java installation. 1>&2 67 | 68 | goto fail 69 | 70 | :execute 71 | @rem Setup the command line 72 | 73 | 74 | 75 | @rem Execute Gradle 76 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* 77 | 78 | :end 79 | @rem End local scope for the variables with windows NT shell 80 | if %ERRORLEVEL% equ 0 goto mainEnd 81 | 82 | :fail 83 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 84 | rem the _cmd.exe /c_ return code! 85 | set EXIT_CODE=%ERRORLEVEL% 86 | if %EXIT_CODE% equ 0 set EXIT_CODE=1 87 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% 88 | exit /b %EXIT_CODE% 89 | 90 | :mainEnd 91 | if "%OS%"=="Windows_NT" endlocal 92 | 93 | :omega 94 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/util/CreativeExtraItems.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.util; 2 | 3 | import java.util.HashMap; 4 | import java.util.List; 5 | import javax.annotation.Nullable; 6 | import com.google.common.collect.ArrayListMultimap; 7 | 8 | import net.minecraft.core.NonNullList; 9 | import net.minecraft.network.chat.ComponentContents; 10 | import net.minecraft.network.chat.contents.TranslatableContents; 11 | import net.minecraft.world.item.*; 12 | import net.minecraft.world.level.block.InfestedBlock; 13 | 14 | import fi.dy.masa.malilib.util.InventoryUtils; 15 | import fi.dy.masa.tweakeroo.Tweakeroo; 16 | 17 | public class CreativeExtraItems 18 | { 19 | private static final ArrayListMultimap ADDED_ITEMS = ArrayListMultimap.create(); 20 | private static final HashMap OVERRIDDEN_GROUPS = new HashMap<>(); 21 | 22 | @Nullable 23 | public static CreativeModeTab getGroupFor(Item item) 24 | { 25 | return OVERRIDDEN_GROUPS.get(item); 26 | } 27 | 28 | public static List getExtraStacksForGroup(CreativeModeTab group) 29 | { 30 | return ADDED_ITEMS.get(group); 31 | } 32 | 33 | public static void setCreativeExtraItems(List items) 34 | { 35 | // The references are private without Fabric API module fabric-item-group-api-v1 36 | // So use an ugly workaround for now to find the correct group, to avoid the API 37 | // dependency and an extra Mixin accessor. 38 | // TODO 1.19.3+ ? 39 | for (CreativeModeTab group : CreativeModeTabs.allTabs()) 40 | { 41 | ComponentContents content = group.getDisplayName().getContents(); 42 | 43 | if (content instanceof TranslatableContents translatableTextContent && 44 | translatableTextContent.getKey().equals("itemGroup.op")) 45 | { 46 | setCreativeExtraItems(group, items); 47 | break; 48 | } 49 | } 50 | } 51 | 52 | private static void setCreativeExtraItems(CreativeModeTab group, List items) 53 | { 54 | ADDED_ITEMS.clear(); 55 | OVERRIDDEN_GROUPS.clear(); 56 | 57 | if (items.isEmpty()) 58 | { 59 | return; 60 | } 61 | 62 | Tweakeroo.LOGGER.info("Adding extra items to creative inventory group '{}'", group.getDisplayName().getString()); 63 | 64 | for (String str : items) 65 | { 66 | ItemStack stack = InventoryUtils.getItemStackFromString(str); 67 | 68 | if (stack != null && stack.isEmpty() == false) 69 | { 70 | if (stack.getComponents().isEmpty() == false) 71 | { 72 | ADDED_ITEMS.put(group, stack); 73 | } 74 | else 75 | { 76 | OVERRIDDEN_GROUPS.put(stack.getItem(), group); 77 | } 78 | } 79 | } 80 | } 81 | 82 | public static void removeInfestedBlocks(NonNullList stacks) 83 | { 84 | stacks.removeIf((stack) -> stack.getItem() instanceof BlockItem && 85 | ((BlockItem) stack.getItem()).getBlock() instanceof InfestedBlock); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/render/MixinGameRenderer.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.render; 2 | 3 | import org.spongepowered.asm.mixin.Final; 4 | import org.spongepowered.asm.mixin.Mixin; 5 | import org.spongepowered.asm.mixin.Shadow; 6 | import org.spongepowered.asm.mixin.Unique; 7 | import org.spongepowered.asm.mixin.injection.At; 8 | import org.spongepowered.asm.mixin.injection.At.Shift; 9 | import org.spongepowered.asm.mixin.injection.Inject; 10 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 11 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 12 | 13 | import fi.dy.masa.tweakeroo.config.Callbacks; 14 | import fi.dy.masa.tweakeroo.config.Configs; 15 | import fi.dy.masa.tweakeroo.config.FeatureToggle; 16 | import fi.dy.masa.tweakeroo.config.Hotkeys; 17 | import fi.dy.masa.tweakeroo.util.CameraUtils; 18 | import fi.dy.masa.tweakeroo.util.MiscUtils; 19 | import net.minecraft.client.Camera; 20 | import net.minecraft.client.Minecraft; 21 | import net.minecraft.client.renderer.GameRenderer; 22 | import net.minecraft.world.entity.Entity; 23 | 24 | @Mixin(value = GameRenderer.class, priority = 1001) 25 | public abstract class MixinGameRenderer 26 | { 27 | @Shadow @Final private Minecraft minecraft; 28 | 29 | @Unique private float realYaw; 30 | @Unique private float realPitch; 31 | 32 | @Inject(method = "renderLevel", at = @At("HEAD"), cancellable = true) 33 | private void tweakeroo_onRenderWorld(CallbackInfo ci) 34 | { 35 | if (Callbacks.skipWorldRendering) 36 | { 37 | ci.cancel(); 38 | } 39 | } 40 | 41 | @Inject(method = "getFov", at = @At("HEAD"), cancellable = true) 42 | private void tweakeroo_applyZoom(Camera camera, float tickDelta, boolean changingFov, CallbackInfoReturnable cir) 43 | { 44 | if (MiscUtils.isZoomActive()) 45 | { 46 | cir.setReturnValue((float) Configs.Generic.ZOOM_FOV.getDoubleValue()); 47 | } 48 | } 49 | 50 | @Inject(method = "renderLevel", at = @At( 51 | value = "INVOKE", shift = Shift.AFTER, 52 | target = "Lnet/minecraft/client/renderer/GameRenderer;pick(F)V")) 53 | private void tweakeroo_overrideRenderViewEntityPre(CallbackInfo ci) 54 | { 55 | if (FeatureToggle.TWEAK_ELYTRA_CAMERA.getBooleanValue() && Hotkeys.ELYTRA_CAMERA.getKeybind().isKeybindHeld()) 56 | { 57 | Entity entity = this.minecraft.getCameraEntity(); 58 | 59 | if (entity != null) 60 | { 61 | this.realYaw = entity.getYRot(); 62 | this.realPitch = entity.getXRot(); 63 | MiscUtils.setEntityRotations(entity, CameraUtils.getCameraYaw(), CameraUtils.getCameraPitch()); 64 | } 65 | } 66 | } 67 | 68 | @Inject(method = "renderLevel", at = @At("RETURN")) 69 | private void tweakeroo_overrideRenderViewEntityPost(CallbackInfo ci) 70 | { 71 | if (FeatureToggle.TWEAK_ELYTRA_CAMERA.getBooleanValue() && Hotkeys.ELYTRA_CAMERA.getKeybind().isKeybindHeld()) 72 | { 73 | Entity entity = this.minecraft.getCameraEntity(); 74 | 75 | if (entity != null) 76 | { 77 | MiscUtils.setEntityRotations(entity, this.realYaw, this.realPitch); 78 | } 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/screen/MixinAbstractSignEditScreen.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.screen; 2 | 3 | import org.spongepowered.asm.mixin.Final; 4 | import org.spongepowered.asm.mixin.Mixin; 5 | import org.spongepowered.asm.mixin.Shadow; 6 | import org.spongepowered.asm.mixin.injection.At; 7 | import org.spongepowered.asm.mixin.injection.Inject; 8 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 9 | import com.mojang.blaze3d.platform.InputConstants; 10 | import fi.dy.masa.malilib.gui.GuiBase; 11 | import fi.dy.masa.malilib.hotkeys.KeybindMulti; 12 | import fi.dy.masa.tweakeroo.config.Configs; 13 | import fi.dy.masa.tweakeroo.config.FeatureToggle; 14 | import fi.dy.masa.tweakeroo.util.IGuiEditSign; 15 | import fi.dy.masa.tweakeroo.util.MiscUtils; 16 | import net.minecraft.client.KeyMapping; 17 | import net.minecraft.client.Minecraft; 18 | import net.minecraft.client.gui.screens.Screen; 19 | import net.minecraft.client.gui.screens.inventory.AbstractSignEditScreen; 20 | import net.minecraft.network.chat.Component; 21 | import net.minecraft.world.level.block.entity.SignBlockEntity; 22 | import net.minecraft.world.level.block.entity.SignText; 23 | 24 | @Mixin(AbstractSignEditScreen.class) 25 | public abstract class MixinAbstractSignEditScreen extends Screen implements IGuiEditSign 26 | { 27 | protected MixinAbstractSignEditScreen(Component textComponent) 28 | { 29 | super(textComponent); 30 | } 31 | 32 | @Shadow @Final protected SignBlockEntity sign; 33 | @Shadow private SignText text; 34 | @Shadow @Final private boolean isFrontText; 35 | @Shadow @Final private String[] messages; 36 | 37 | @Override 38 | public SignBlockEntity tweakeroo$getTile() 39 | { 40 | return this.sign; 41 | } 42 | 43 | @Inject(method = "removed", at = @At("HEAD")) 44 | private void storeText(CallbackInfo ci) 45 | { 46 | if (FeatureToggle.TWEAK_SIGN_COPY.getBooleanValue()) 47 | { 48 | MiscUtils.copyTextFromSign(this.sign, this.isFrontText); 49 | } 50 | } 51 | 52 | @Inject(method = "init", at = @At("RETURN")) 53 | private void preventGuiOpen(CallbackInfo ci) 54 | { 55 | if (FeatureToggle.TWEAK_SIGN_COPY.getBooleanValue()) 56 | { 57 | MiscUtils.applyPreviousTextToSign(this.sign, ((AbstractSignEditScreen) (Object) this), this.isFrontText); 58 | } 59 | 60 | if (Configs.Disable.DISABLE_SIGN_GUI.getBooleanValue()) 61 | { 62 | // Update the keybind state, because opening a GUI resets them all. 63 | // Also, KeyBinding.updateKeyBindState() only works for keyboard keys 64 | KeyMapping keybind = Minecraft.getInstance().options.keyUse; 65 | InputConstants.Key input = InputConstants.getKey(keybind.saveString()); 66 | 67 | if (input != null) 68 | { 69 | KeyMapping.set(input, KeybindMulti.isKeyDown(KeybindMulti.getKeyCode(keybind))); 70 | } 71 | 72 | GuiBase.openGui(null); 73 | } 74 | } 75 | 76 | @Override 77 | public void tweakeroo$applyText(SignText text) 78 | { 79 | this.text = text; 80 | 81 | for (int i = 0; i < this.messages.length; i++) 82 | { 83 | this.messages[i] = text.getMessage(i, false).getString(); 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/data/DataManager.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.data; 2 | 3 | import javax.annotation.Nullable; 4 | import net.minecraft.client.server.IntegratedServer; 5 | import net.minecraft.resources.Identifier; 6 | import com.google.gson.JsonElement; 7 | import com.google.gson.JsonObject; 8 | import fi.dy.masa.malilib.interfaces.IServerListener; 9 | import fi.dy.masa.tweakeroo.Tweakeroo; 10 | 11 | public class DataManager implements IServerListener 12 | { 13 | private static final DataManager INSTANCE = new DataManager(); 14 | public static DataManager getInstance() { return INSTANCE; } 15 | 16 | private boolean hasCarpetServer; 17 | private boolean hasServuxServer; 18 | public static final Identifier CARPET_HELLO = Identifier.fromNamespaceAndPath("carpet", "hello"); 19 | public static final Identifier SERVUX_LITEMATIC_DATA = Identifier.fromNamespaceAndPath("servux", "litematics"); 20 | //private IntegratedServer integratedServer; 21 | //private DynamicRegistryManager.Immutable registryManager = DynamicRegistryManager.EMPTY; 22 | private boolean hasIntegratedServer; 23 | 24 | private DataManager() { } 25 | 26 | public void reset(boolean isLogout) 27 | { 28 | if (isLogout) 29 | { 30 | Tweakeroo.debugLog("DataManager#reset() - log-out"); 31 | this.hasCarpetServer = false; 32 | this.hasServuxServer = false; 33 | //this.registryManager = DynamicRegistryManager.EMPTY; 34 | this.setHasIntegratedServer(false, null); 35 | } 36 | //else 37 | //{ 38 | //Tweakeroo.logger.info("DataManager#reset() - dimension change or log-in"); 39 | //} 40 | } 41 | 42 | public void setHasCarpetServer(boolean toggle) 43 | { 44 | this.hasCarpetServer = toggle; 45 | } 46 | 47 | public boolean hasCarpetServer() 48 | { 49 | return this.hasCarpetServer; 50 | } 51 | 52 | public void setHasServuxServer(boolean toggle) 53 | { 54 | this.hasServuxServer = toggle; 55 | } 56 | 57 | public boolean hasServuxServer() 58 | { 59 | return this.hasServuxServer; 60 | } 61 | 62 | @Override 63 | public void onServerIntegratedSetup(IntegratedServer server) 64 | { 65 | this.setHasIntegratedServer(true, server); 66 | } 67 | 68 | public boolean hasIntegratedServer() { return this.hasIntegratedServer; } 69 | 70 | public void setHasIntegratedServer(boolean toggle, @Nullable IntegratedServer server) 71 | { 72 | this.hasIntegratedServer = toggle; 73 | //this.integratedServer = server; 74 | } 75 | 76 | /* 77 | public IntegratedServer getIntegratedServer() 78 | { 79 | return this.integratedServer; 80 | } 81 | */ 82 | 83 | /* 84 | public void setRegistryManager(DynamicRegistryManager.Immutable immutable) 85 | { 86 | this.registryManager = immutable; 87 | } 88 | 89 | public DynamicRegistryManager.Immutable getRegistryManager() 90 | { 91 | return this.registryManager; 92 | } 93 | */ 94 | 95 | public JsonElement toJson() 96 | { 97 | return new JsonObject(); 98 | } 99 | 100 | public void fromJson(JsonElement ele) 101 | { 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/freecam/MixinInGameHud_freeCam.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.freecam; 2 | 3 | import fi.dy.masa.tweakeroo.config.Configs; 4 | import org.spongepowered.asm.mixin.Final; 5 | import org.spongepowered.asm.mixin.Mixin; 6 | import org.spongepowered.asm.mixin.Shadow; 7 | import org.spongepowered.asm.mixin.injection.At; 8 | import org.spongepowered.asm.mixin.injection.Inject; 9 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 10 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 11 | 12 | import fi.dy.masa.tweakeroo.config.FeatureToggle; 13 | import net.minecraft.client.DeltaTracker; 14 | import net.minecraft.client.Minecraft; 15 | import net.minecraft.client.gui.Gui; 16 | import net.minecraft.client.gui.GuiGraphics; 17 | import net.minecraft.world.entity.player.Player; 18 | 19 | @Mixin(value = Gui.class, priority = 1005) 20 | public abstract class MixinInGameHud_freeCam 21 | { 22 | @Shadow @Final private Minecraft minecraft; 23 | 24 | @Inject(method = "getCameraPlayer", at = @At("HEAD"), cancellable = true) 25 | private void tweakeroo_overridePlayerForRendering(CallbackInfoReturnable cir) 26 | { 27 | // Fix the hotbar rendering in the Free Camera mode by using the actual player 28 | if (FeatureToggle.TWEAK_FREE_CAMERA.getBooleanValue() && 29 | this.minecraft.player != null) 30 | { 31 | cir.setReturnValue(this.minecraft.player); 32 | } 33 | } 34 | 35 | @Inject(method = "renderItemHotbar", at = @At("HEAD"), cancellable = true) 36 | public void tweakeroo_overrideHotbarRendering(GuiGraphics context, DeltaTracker tickCounter, CallbackInfo ci) 37 | { 38 | // This turns off rendering of the hotbar 39 | if (FeatureToggle.TWEAK_FREE_CAMERA.getBooleanValue() && 40 | !Configs.Generic.FREE_CAMERA_SHOW_HOTBAR.getBooleanValue()) 41 | { 42 | ci.cancel(); 43 | } 44 | } 45 | 46 | @Inject(method = "renderSelectedItemName", at = @At("HEAD"), cancellable = true) 47 | public void tweakeroo_overrideHeldItemTooltipRendering(GuiGraphics context, CallbackInfo ci) 48 | { 49 | // This turns off rendering of the item "tooltips" when selecting hotbar items 50 | if (FeatureToggle.TWEAK_FREE_CAMERA.getBooleanValue() && 51 | !Configs.Generic.FREE_CAMERA_SHOW_HOTBAR.getBooleanValue() && 52 | !Configs.Generic.FREE_CAMERA_SHOW_HANDS.getBooleanValue()) 53 | { 54 | ci.cancel(); 55 | } 56 | } 57 | 58 | @Inject(method = "renderPlayerHealth", at = @At("HEAD"), cancellable = true) 59 | public void tweakeroo_overrideStatusBarRendering1(GuiGraphics context, CallbackInfo ci) 60 | { 61 | // This turns off all status bars 62 | if (FeatureToggle.TWEAK_FREE_CAMERA.getBooleanValue() && 63 | !Configs.Generic.FREE_CAMERA_SHOW_STATUS_BARS.getBooleanValue()) 64 | { 65 | ci.cancel(); 66 | } 67 | } 68 | 69 | @Inject(method = "renderVehicleHealth", at = @At("HEAD"), cancellable = true) 70 | public void tweakeroo_overrideStatusBarRendering2(GuiGraphics context, CallbackInfo ci) 71 | { 72 | // This turns off the "mount health" status bar 73 | if (FeatureToggle.TWEAK_FREE_CAMERA.getBooleanValue() && 74 | !Configs.Generic.FREE_CAMERA_SHOW_STATUS_BARS.getBooleanValue()) 75 | { 76 | ci.cancel(); 77 | } 78 | } 79 | 80 | @Inject(method = "nextContextualInfoState", at = @At("HEAD"), cancellable = true) 81 | public void tweakeroo_overrideExpBarRendering(CallbackInfoReturnable cir) 82 | { 83 | // This turns off all status bars 84 | if (FeatureToggle.TWEAK_FREE_CAMERA.getBooleanValue() && 85 | !Configs.Generic.FREE_CAMERA_SHOW_STATUS_BARS.getBooleanValue()) 86 | { 87 | cir.setReturnValue(Gui.ContextualInfo.EMPTY); 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/render/MixinEntityRenderManager.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.render; 2 | 3 | import org.spongepowered.asm.mixin.Mixin; 4 | import org.spongepowered.asm.mixin.injection.At; 5 | import org.spongepowered.asm.mixin.injection.Inject; 6 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 7 | import fi.dy.masa.tweakeroo.Tweakeroo; 8 | import fi.dy.masa.tweakeroo.config.Configs; 9 | import fi.dy.masa.tweakeroo.config.FeatureToggle; 10 | import fi.dy.masa.tweakeroo.tweaks.RenderTweaks; 11 | import fi.dy.masa.tweakeroo.util.IDecorationEntity; 12 | import net.minecraft.client.renderer.culling.Frustum; 13 | import net.minecraft.client.renderer.entity.EntityRenderDispatcher; 14 | import net.minecraft.world.entity.Entity; 15 | import net.minecraft.world.entity.ExperienceOrb; 16 | import net.minecraft.world.entity.LivingEntity; 17 | import net.minecraft.world.entity.decoration.ArmorStand; 18 | import net.minecraft.world.entity.decoration.HangingEntity; 19 | import net.minecraft.world.entity.item.FallingBlockEntity; 20 | import net.minecraft.world.entity.item.ItemEntity; 21 | import net.minecraft.world.entity.player.Player; 22 | 23 | @Mixin(EntityRenderDispatcher.class) 24 | public abstract class MixinEntityRenderManager 25 | { 26 | @Inject(method = "shouldRender", at = @At("HEAD"), cancellable = true) 27 | private void onShouldRender(Entity entityIn, Frustum frustum, double camX, double camY, double camZ, CallbackInfoReturnable cir) 28 | { 29 | boolean isPlayer = (entityIn instanceof Player); 30 | 31 | if (entityIn instanceof HangingEntity) 32 | { 33 | if (!RenderTweaks.isPositionValidForRendering(((IDecorationEntity) entityIn).tweakeroo$getAttached())) 34 | { 35 | cir.setReturnValue(false); 36 | } 37 | } 38 | 39 | if (!isPlayer && Configs.Generic.SELECTIVE_BLOCKS_HIDE_ENTITIES.getBooleanValue()) 40 | { 41 | if (!RenderTweaks.isPositionValidForRendering(entityIn.blockPosition())) 42 | { 43 | cir.setReturnValue(false); 44 | } 45 | } 46 | 47 | if (Configs.Disable.DISABLE_ENTITY_RENDERING.getBooleanValue() && (entityIn instanceof Player) == false) 48 | { 49 | cir.setReturnValue(false); 50 | } 51 | 52 | if (entityIn instanceof FallingBlockEntity && Configs.Disable.DISABLE_FALLING_BLOCK_RENDER.getBooleanValue()) 53 | { 54 | cir.setReturnValue(false); 55 | } 56 | else if (entityIn instanceof ArmorStand && Configs.Disable.DISABLE_ARMOR_STAND_RENDERING.getBooleanValue()) 57 | { 58 | cir.setReturnValue(false); 59 | } 60 | else if (entityIn instanceof ExperienceOrb) 61 | { 62 | if (FeatureToggle.TWEAK_RENDER_LIMIT_ENTITIES.getBooleanValue()) 63 | { 64 | int max = Configs.Generic.RENDER_LIMIT_XP_ORB.getIntegerValue(); 65 | 66 | if (max >= 0 && ++Tweakeroo.renderCountXPOrbs > max) 67 | { 68 | cir.setReturnValue(false); 69 | } 70 | } 71 | } 72 | else if (entityIn instanceof ItemEntity) 73 | { 74 | if (FeatureToggle.TWEAK_RENDER_LIMIT_ENTITIES.getBooleanValue()) 75 | { 76 | int max = Configs.Generic.RENDER_LIMIT_ITEM.getIntegerValue(); 77 | 78 | if (max >= 0 && ++Tweakeroo.renderCountItems > max) 79 | { 80 | cir.setReturnValue(false); 81 | } 82 | } 83 | } 84 | else if (Configs.Disable.DISABLE_DEAD_MOB_RENDERING.getBooleanValue() && 85 | entityIn instanceof LivingEntity && ((LivingEntity) entityIn).getHealth() <= 0f) 86 | { 87 | cir.setReturnValue(false); 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/world/FakeChunk.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.world; 2 | 3 | import javax.annotation.Nonnull; 4 | import net.minecraft.core.BlockPos; 5 | import net.minecraft.world.level.ChunkPos; 6 | import net.minecraft.world.level.block.Block; 7 | import net.minecraft.world.level.block.Blocks; 8 | import net.minecraft.world.level.block.state.BlockState; 9 | import net.minecraft.world.level.chunk.LevelChunk; 10 | import net.minecraft.world.level.chunk.LevelChunkSection; 11 | 12 | /** 13 | * Copied From Tweak Fork by Andrew54757 14 | */ 15 | public class FakeChunk extends LevelChunk 16 | { 17 | private static final BlockState AIR = Blocks.AIR.defaultBlockState(); 18 | private final int bottomY; 19 | private final int topY; 20 | private boolean isEmpty = true; 21 | 22 | public FakeChunk(FakeWorld world, ChunkPos pos) 23 | { 24 | super(world, pos); 25 | this.bottomY = world.getMinY(); 26 | this.topY = world.getMaxY(); 27 | } 28 | 29 | @Override 30 | public @Nonnull BlockState getBlockState(BlockPos pos) 31 | { 32 | int x = pos.getX() & 0xF; 33 | int y = pos.getY(); 34 | int z = pos.getZ() & 0xF; 35 | int cy = this.getSectionIndex(y); 36 | y &= 0xF; 37 | 38 | LevelChunkSection[] sections = this.getSections(); 39 | 40 | if (cy >= 0 && cy < sections.length) 41 | { 42 | LevelChunkSection chunkSection = sections[cy]; 43 | 44 | if (!chunkSection.hasOnlyAir()) 45 | { 46 | return chunkSection.getBlockState(x, y, z); 47 | } 48 | } 49 | 50 | return AIR; 51 | } 52 | 53 | @Override 54 | public BlockState setBlockState(@Nonnull BlockPos pos, @Nonnull BlockState state, int flags) 55 | { 56 | BlockState stateOld = this.getBlockState(pos); 57 | int y = pos.getY(); 58 | 59 | if (stateOld == state || y >= this.topY || y < this.bottomY) 60 | { 61 | return null; 62 | } 63 | else 64 | { 65 | int x = pos.getX() & 15; 66 | int z = pos.getZ() & 15; 67 | int cy = this.getSectionIndex(y); 68 | 69 | Block blockNew = state.getBlock(); 70 | Block blockOld = stateOld.getBlock(); 71 | LevelChunkSection section = this.getSections()[cy]; 72 | 73 | if (section.hasOnlyAir() && state.isAir()) 74 | { 75 | return null; 76 | } 77 | 78 | y &= 0xF; 79 | 80 | if (state.isAir() == false) 81 | { 82 | this.isEmpty = false; 83 | } 84 | 85 | section.setBlockState(x, y, z, state); 86 | 87 | if (blockOld != blockNew) 88 | { 89 | this.getLevel().removeBlockEntity(pos); 90 | } 91 | 92 | if (section.getBlockState(x, y, z).getBlock() != blockNew) 93 | { 94 | return null; 95 | } 96 | else 97 | { 98 | // if (state.hasBlockEntity() && blockNew instanceof BlockEntityProvider) 99 | // { 100 | // BlockEntity te = this.getBlockEntity(pos, WorldChunk.CreationType.CHECK); 101 | 102 | // if (te == null) 103 | // { 104 | // te = ((BlockEntityProvider) blockNew).createBlockEntity(pos, state); 105 | 106 | // if (te != null) 107 | // { 108 | // this.getWorld().getWorldChunk(pos).setBlockEntity(te); 109 | // } 110 | // } 111 | // } 112 | 113 | this.isUnsaved(); 114 | return stateOld; 115 | } 116 | } 117 | } 118 | 119 | 120 | @Override 121 | public boolean isEmpty() 122 | { 123 | return this.isEmpty; 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/entity/MixinPlayerEntity.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.entity; 2 | 3 | import org.spongepowered.asm.mixin.Mixin; 4 | import org.spongepowered.asm.mixin.Shadow; 5 | import org.spongepowered.asm.mixin.injection.At; 6 | import org.spongepowered.asm.mixin.injection.Inject; 7 | import org.spongepowered.asm.mixin.injection.Redirect; 8 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 9 | 10 | import fi.dy.masa.tweakeroo.config.Configs; 11 | import fi.dy.masa.tweakeroo.config.FeatureToggle; 12 | import fi.dy.masa.tweakeroo.data.DataManager; 13 | import net.minecraft.client.Minecraft; 14 | import net.minecraft.client.player.LocalPlayer; 15 | import net.minecraft.world.entity.EntityType; 16 | import net.minecraft.world.entity.LivingEntity; 17 | import net.minecraft.world.entity.player.Player; 18 | import net.minecraft.world.level.Level; 19 | 20 | @Mixin(Player.class) 21 | public abstract class MixinPlayerEntity extends LivingEntity 22 | { 23 | @Shadow protected abstract boolean isStayingOnGroundSurface(); 24 | @Shadow public abstract boolean isAlwaysTicking(); 25 | 26 | protected MixinPlayerEntity(EntityType entityType_1, Level world_1) 27 | { 28 | super(entityType_1, world_1); 29 | } 30 | 31 | @Inject(method = "isAboveGround", at = @At("HEAD"), cancellable = true) 32 | private void tweakeroo_restore_1_15_2_sneaking(CallbackInfoReturnable cir) 33 | { 34 | if (FeatureToggle.TWEAK_SNEAK_1_15_2.getBooleanValue()) 35 | { 36 | cir.setReturnValue(this.onGround()); 37 | } 38 | } 39 | 40 | @Redirect(method = "maybeBackOffFromEdge", at = @At(value = "INVOKE", 41 | target = "Lnet/minecraft/world/entity/player/Player;isStayingOnGroundSurface()Z", ordinal = 0)) 42 | private boolean tweakeroo_fakeSneaking(Player entity) 43 | { 44 | if (FeatureToggle.TWEAK_FAKE_SNEAKING.getBooleanValue() && ((Object) this) instanceof LocalPlayer) 45 | { 46 | return true; 47 | } 48 | 49 | return this.isStayingOnGroundSurface(); 50 | } 51 | 52 | @Inject(method = "blockInteractionRange", at = @At("RETURN"), cancellable = true) 53 | private void tweakeroo_overrideBlockReachDistance(CallbackInfoReturnable cir) 54 | { 55 | if (FeatureToggle.TWEAK_BLOCK_REACH_OVERRIDE.getBooleanValue()) 56 | { 57 | if (Minecraft.getInstance().hasSingleplayerServer() || Configs.Generic.BLOCK_REACH_DISTANCE.getDoubleValue() < cir.getReturnValue()) 58 | { 59 | cir.setReturnValue(Configs.Generic.BLOCK_REACH_DISTANCE.getDoubleValue()); 60 | } 61 | else 62 | { 63 | if (DataManager.getInstance().hasCarpetServer()) 64 | { 65 | // When using Carpet server, the server-side reach check might be disabled. 66 | cir.setReturnValue(Configs.Generic.BLOCK_REACH_DISTANCE.getDoubleValue()); 67 | } 68 | else 69 | { 70 | // Calculate a "safe" range for servers 71 | double rangeRealMax = cir.getReturnValue() + 1.0; 72 | cir.setReturnValue(Math.min(Configs.Generic.BLOCK_REACH_DISTANCE.getDoubleValue(), rangeRealMax)); 73 | } 74 | } 75 | } 76 | } 77 | 78 | @Inject(method = "entityInteractionRange", at = @At("RETURN"), cancellable = true) 79 | private void tweakeroo_overrideEntityReachDistance(CallbackInfoReturnable cir) 80 | { 81 | if (FeatureToggle.TWEAK_ENTITY_REACH_OVERRIDE.getBooleanValue()) 82 | { 83 | if (Minecraft.getInstance().hasSingleplayerServer()) 84 | { 85 | cir.setReturnValue(Configs.Generic.ENTITY_REACH_DISTANCE.getDoubleValue()); 86 | } 87 | else 88 | { 89 | // Calculate a "safe" range for servers 90 | double rangeRealMax = cir.getReturnValue() + 1.0; 91 | cir.setReturnValue(Math.min(Configs.Generic.ENTITY_REACH_DISTANCE.getDoubleValue(), rangeRealMax)); 92 | } 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/world/MixinClientWorld.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.world; 2 | 3 | import fi.dy.masa.tweakeroo.config.Configs; 4 | import net.minecraft.client.multiplayer.ClientLevel; 5 | import net.minecraft.core.BlockPos; 6 | import net.minecraft.core.Holder; 7 | import net.minecraft.core.RegistryAccess; 8 | import net.minecraft.resources.ResourceKey; 9 | import net.minecraft.world.entity.Entity; 10 | import net.minecraft.world.entity.player.Player; 11 | import net.minecraft.world.level.Level; 12 | import net.minecraft.world.level.block.state.BlockState; 13 | import net.minecraft.world.level.dimension.DimensionType; 14 | import net.minecraft.world.level.storage.WritableLevelData; 15 | import org.spongepowered.asm.mixin.Mixin; 16 | import org.spongepowered.asm.mixin.injection.At; 17 | import org.spongepowered.asm.mixin.injection.Inject; 18 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 19 | 20 | @Mixin(ClientLevel.class) 21 | public abstract class MixinClientWorld extends Level 22 | { 23 | private MixinClientWorld(WritableLevelData properties, 24 | ResourceKey registryRef, 25 | RegistryAccess registryManager, 26 | Holder dimension, 27 | boolean isClient, boolean debugWorld, long seed, int maxChainedNeighborUpdates) 28 | { 29 | super(properties, registryRef, registryManager, dimension, isClient, debugWorld, seed, maxChainedNeighborUpdates); 30 | } 31 | 32 | @Inject(method = "tickNonPassenger(Lnet/minecraft/world/entity/Entity;)V", at = @At("HEAD"), cancellable = true) 33 | private void disableClientEntityTicking(Entity entity, CallbackInfo ci) 34 | { 35 | if (Configs.Disable.DISABLE_CLIENT_ENTITY_UPDATES.getBooleanValue() && 36 | (entity instanceof Player) == false) 37 | { 38 | ci.cancel(); 39 | } 40 | } 41 | 42 | /* TODO 1.17 is this still needed? 43 | @Inject(method = "addEntitiesToChunk", at = @At("HEAD"), cancellable = true) 44 | private void fixChunkEntityLeak(WorldChunk chunk, CallbackInfo ci) 45 | { 46 | if (Configs.Fixes.CLIENT_CHUNK_ENTITY_DUPE.getBooleanValue()) 47 | { 48 | for (int y = 0; y < 16; ++y) 49 | { 50 | // The chunk already has entities, which means it's a re-used existing chunk, 51 | // in such a case we don't want to add the from the world entities again, otherwise 52 | // they are basically duped within the Chunk. 53 | if (chunk.getEntitySectionArray()[y].size() > 0) 54 | { 55 | ci.cancel(); 56 | return; 57 | } 58 | } 59 | } 60 | } 61 | */ 62 | 63 | @Inject(method = "setBlocksDirty", at = @At("HEAD"), cancellable = true) 64 | private void disableChunkReRenders(BlockPos pos, BlockState old, BlockState updated, CallbackInfo ci) 65 | { 66 | if (Configs.Disable.DISABLE_CHUNK_RENDERING.getBooleanValue()) 67 | { 68 | ci.cancel(); 69 | } 70 | } 71 | 72 | @Inject(method = "setSectionDirtyWithNeighbors", at = @At("HEAD"), cancellable = true) 73 | private void disableChunkReRenders(int x, int y, int z, CallbackInfo ci) 74 | { 75 | if (Configs.Disable.DISABLE_CHUNK_RENDERING.getBooleanValue()) 76 | { 77 | ci.cancel(); 78 | } 79 | } 80 | 81 | @Inject(method = "sendBlockUpdated", at = @At("HEAD"), cancellable = true) 82 | private void disableChunkReRenders(BlockPos pos, BlockState oldState, BlockState newState, int flags, CallbackInfo ci) 83 | { 84 | if (Configs.Disable.DISABLE_CHUNK_RENDERING.getBooleanValue()) 85 | { 86 | ci.cancel(); 87 | } 88 | } 89 | 90 | @Inject(method = "addDestroyBlockEffect(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;)V", 91 | at = @At("HEAD"), cancellable = true) 92 | private void tweakeroo_onAddBlockBreakParticles(BlockPos pos, BlockState state, CallbackInfo ci) 93 | { 94 | if (Configs.Disable.DISABLE_BLOCK_BREAK_PARTICLES.getBooleanValue()) 95 | { 96 | ci.cancel(); 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/main/resources/mixins.tweakeroo.json: -------------------------------------------------------------------------------- 1 | { 2 | "required": true, 3 | "package": "fi.dy.masa.tweakeroo.mixin", 4 | "minVersion": "0.8", 5 | "compatibilityLevel": "JAVA_21", 6 | "mixins": [ 7 | "block.IMixinAbstractBlock", 8 | "block.IMixinCommandBlockExecutor", 9 | "block.IMixinPistonBlock", 10 | "block.MixinAbstractBlockState", 11 | "block.MixinHopperBlockEntity", 12 | "block.MixinMobSpawnerLogic", 13 | "block.MixinNetherPortalBlock", 14 | "block.MixinObserverBlock", 15 | "block.MixinPistonBlock", 16 | "block.MixinScaffoldingBlock", 17 | "block.MixinSculkSensor", 18 | "block.MixinSignBlockEntity", 19 | "block.MixinSlimeBlock", 20 | "block.MixinStructureBlockBlockEntity", 21 | "entity.MixinBatEntity", 22 | "entity.MixinBlockAttachedEntity", 23 | "entity.MixinEntity", 24 | "entity.MixinLivingEntity", 25 | "entity.MixinPlayerAbilities", 26 | "entity.MixinPlayerEntity", 27 | "entity.MixinRavagerEntity", 28 | "entity.MixinTradeOffer", 29 | "freecam.MixinPlayerEntity_freeCam", 30 | "input.MixinCloneCommand", 31 | "input.MixinFillCommand", 32 | "item.IMixinAxeItem", 33 | "item.IMixinShovelItem", 34 | "item.MixinBlockItem", 35 | "item.MixinBundleItem", 36 | "item.MixinItem", 37 | "item.MixinItemGroup", 38 | "item.MixinItemStack", 39 | "network.MixinServerPlayNetworkHandler", 40 | "world.IMixinChunkLightProvider", 41 | "world.MixinLightingProvider", 42 | "world.MixinServerChunkLoadingManager", 43 | "world.MixinUpdateStructureBlockC2SPacket", 44 | "world.MixinWorld" 45 | ], 46 | "client": [ 47 | "client.MixinMinecraftClient", 48 | "entity.MixinClientPlayerEntity", 49 | "fog.MixinAtmosphericFogModifier", 50 | "fog.MixinDarknessEffectFogModifier", 51 | "fog.MixinFogRenderer", 52 | "fog.MixinLavaFogModifier", 53 | "fog.MixinWaterFogModifier", 54 | "freecam.MixinCamera_freeCam", 55 | "freecam.MixinClientPlayerEntity_freeCam", 56 | "freecam.MixinClientPlayerInteractionManager_freeCam", 57 | "freecam.MixinExperienceBar_freeCam", 58 | "freecam.MixinGameRenderer_freeCam", 59 | "freecam.MixinHeldItemRenderer_freeCam", 60 | "freecam.MixinInGameHud_freeCam", 61 | "freecam.MixinJumpBar_freeCam", 62 | "freecam.MixinLocatorBar_freeCam", 63 | "freecam.MixinWorldRenderer_freeCam", 64 | "hud.MixinBossBarHud", 65 | "hud.MixinChatHud", 66 | "hud.MixinClientBossBar", 67 | "hud.MixinInGameHud", 68 | "hud.MixinStatusEffectsDisplay", 69 | "hud.MixinTeleportSpectatorMenu", 70 | "input.MixinClientCommandSource", 71 | "input.MixinKeyboardInput", 72 | "input.MixinMouse", 73 | "network.MixinClientCommonNetworkHandler", 74 | "network.MixinClientPlayerInteractionManager", 75 | "network.MixinClientPlayNetworkHandler", 76 | "network.MixinDataQueryHandler", 77 | "option.IMixinSimpleOption", 78 | "option.MixinGameOptions", 79 | "render.MixinBeaconBlockEntityRenderer", 80 | "render.MixinBlockEntityRenderManager", 81 | "render.MixinEntityRenderManager", 82 | "render.MixinExplosionEmitterParticle", 83 | "render.MixinGameRenderer", 84 | "render.MixinGameRenderer_ViewBob", 85 | "render.MixinHeldItemRenderer", 86 | "render.MixinMobSpawnerBlockEntityRenderer", 87 | "render.MixinParticleManager", 88 | "render.MixinWeatherRendering", 89 | "render.MixinWindow", 90 | "screen.IMixinCustomizeFlatLevelScreen", 91 | "screen.MixinAbstractSignEditScreen", 92 | "screen.MixinChatScreen", 93 | "screen.MixinCommandBlockScreen", 94 | "screen.MixinCreativeInventoryScreen", 95 | "screen.MixinPresetsScreen", 96 | "screen.MixinScreen", 97 | "world.IMixinClientWorld", 98 | "world.MixinBuiltChunk", 99 | "world.MixinChunkBuilder_BuiltChunk", 100 | "world.MixinClientWorld", 101 | "world.MixinClientWorld_Properties" 102 | ], 103 | "server": [], 104 | "mixinPriority": 990, 105 | "injectors": { 106 | "defaultRequire": 0 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/gui/widgets/WidgetCameraPresetList.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.gui.widgets; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collection; 5 | import java.util.Collections; 6 | import java.util.List; 7 | import net.minecraft.client.input.KeyEvent; 8 | import net.minecraft.resources.ResourceKey; 9 | import net.minecraft.world.level.Level; 10 | import org.jetbrains.annotations.Nullable; 11 | import fi.dy.masa.malilib.gui.LeftRight; 12 | import fi.dy.masa.malilib.gui.MaLiLibIcons; 13 | import fi.dy.masa.malilib.gui.widgets.WidgetListBase; 14 | import fi.dy.masa.malilib.gui.widgets.WidgetSearchBar; 15 | import fi.dy.masa.malilib.render.GuiContext; 16 | import fi.dy.masa.malilib.util.KeyCodes; 17 | import fi.dy.masa.tweakeroo.data.CameraPresetManager; 18 | import fi.dy.masa.tweakeroo.gui.GuiCameraPresetEditor; 19 | import fi.dy.masa.tweakeroo.util.CameraPreset; 20 | 21 | public class WidgetCameraPresetList extends WidgetListBase 22 | { 23 | private final GuiCameraPresetEditor parent; 24 | private List presets; 25 | private final ResourceKey dimKey; 26 | private static int lastScrollbarPosition; 27 | private boolean scrollbarRestored; 28 | 29 | public WidgetCameraPresetList(int x, int y, int width, int height, 30 | @Nullable ResourceKey dimKey, 31 | @Nullable GuiCameraPresetEditor parent) 32 | { 33 | super(x, y, width, height, parent); 34 | this.parent = parent; 35 | this.widgetSearchBar = new WidgetSearchBar(x + 2, y + 8, width - 14, 14, 0, MaLiLibIcons.SEARCH, LeftRight.LEFT); 36 | this.widgetSearchBar.setZLevel(1); 37 | this.dimKey = dimKey; 38 | this.browserEntriesOffsetY = 17; 39 | this.browserEntryHeight = 22; 40 | this.presets = new ArrayList<>(); 41 | this.updatePresets(); 42 | } 43 | 44 | private void updatePresets() 45 | { 46 | this.presets.clear(); 47 | 48 | if (this.dimKey == null || this.parent.shouldShowAll()) 49 | { 50 | this.presets = CameraPresetManager.getInstance().toList(); 51 | } 52 | else 53 | { 54 | this.presets = CameraPresetManager.getInstance().toList(this.dimKey); 55 | } 56 | } 57 | 58 | public GuiCameraPresetEditor getPresetEditorGui() 59 | { 60 | return this.parent; 61 | } 62 | 63 | @Override 64 | public boolean onKeyTyped(KeyEvent input) 65 | { 66 | if (input.key() == KeyCodes.KEY_ESCAPE) 67 | { 68 | this.parent.onClose(); 69 | } 70 | 71 | return super.onKeyTyped(input); 72 | } 73 | 74 | @Override 75 | public void drawContents(GuiContext ctx, int mouseX, int mouseY, float partialTicks) 76 | { 77 | super.drawContents(ctx, mouseX, mouseY, partialTicks); 78 | lastScrollbarPosition = this.scrollBar.getValue(); 79 | } 80 | 81 | @Override 82 | protected void offsetSelectionOrScrollbar(int amount, boolean changeSelection) 83 | { 84 | super.offsetSelectionOrScrollbar(amount, changeSelection); 85 | lastScrollbarPosition = this.scrollBar.getValue(); 86 | } 87 | 88 | @Override 89 | protected Collection getAllEntries() 90 | { 91 | return this.presets; 92 | } 93 | 94 | @Override 95 | protected List getEntryStringsForFilter(CameraPreset entry) 96 | { 97 | List list = new ArrayList<>(); 98 | 99 | if (entry != null) 100 | { 101 | list.add(Integer.toString(entry.getId())); 102 | list.add(entry.getName().toLowerCase()); 103 | list.add(entry.getDim().getPath().toLowerCase()); 104 | 105 | return list; 106 | } 107 | else 108 | { 109 | return Collections.emptyList(); 110 | } 111 | } 112 | 113 | @Override 114 | protected void refreshBrowserEntries() 115 | { 116 | super.refreshBrowserEntries(); 117 | 118 | if (this.scrollbarRestored == false && lastScrollbarPosition <= this.scrollBar.getMaxValue()) 119 | { 120 | // This needs to happen after the setMaxValue() has been called in reCreateListEntryWidgets() 121 | this.scrollBar.setValue(lastScrollbarPosition); 122 | this.scrollbarRestored = true; 123 | this.reCreateListEntryWidgets(); 124 | } 125 | } 126 | 127 | @Override 128 | protected void reCreateListEntryWidgets() 129 | { 130 | this.updatePresets(); 131 | super.reCreateListEntryWidgets(); 132 | } 133 | 134 | @Override 135 | protected WidgetCameraPresetEntry createListEntryWidget(int x, int y, int listIndex, boolean isOdd, 136 | CameraPreset entry) 137 | { 138 | return new WidgetCameraPresetEntry(x, y, this.browserEntryWidth, 139 | this.getBrowserEntryHeightFor(entry), 140 | isOdd, entry, listIndex, this); 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/entity/MixinLivingEntity.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.entity; 2 | 3 | import java.util.Collection; 4 | import net.minecraft.client.CameraType; 5 | import net.minecraft.client.Minecraft; 6 | import net.minecraft.world.InteractionHand; 7 | import net.minecraft.world.effect.MobEffectInstance; 8 | import net.minecraft.world.effect.MobEffects; 9 | import net.minecraft.world.entity.Entity; 10 | import net.minecraft.world.entity.EntityType; 11 | import net.minecraft.world.entity.LivingEntity; 12 | import net.minecraft.world.entity.player.Player; 13 | import net.minecraft.world.level.Level; 14 | import org.spongepowered.asm.mixin.Mixin; 15 | import org.spongepowered.asm.mixin.Shadow; 16 | import org.spongepowered.asm.mixin.Unique; 17 | import org.spongepowered.asm.mixin.injection.At; 18 | import org.spongepowered.asm.mixin.injection.Inject; 19 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 20 | 21 | import fi.dy.masa.tweakeroo.config.Configs; 22 | import fi.dy.masa.tweakeroo.config.FeatureToggle; 23 | import fi.dy.masa.tweakeroo.tweaks.PlacementTweaks; 24 | import fi.dy.masa.tweakeroo.util.MiscUtils; 25 | 26 | @Mixin(LivingEntity.class) 27 | public abstract class MixinLivingEntity extends Entity 28 | { 29 | @Shadow public abstract InteractionHand getUsedItemHand(); 30 | @Unique private boolean wasGammaOverriden = false; 31 | 32 | private MixinLivingEntity(EntityType type, Level worldIn) 33 | { 34 | super(type, worldIn); 35 | } 36 | 37 | // TODO 1.21.2+ - it seems that Mojang fixed this. 38 | /* 39 | @Redirect(method = "method_61417", at = @At(value = "FIELD", ordinal = 1, 40 | target = "Lnet/minecraft/world/World;isClient:Z")) 41 | private boolean fixElytraLanding() 42 | { 43 | return this.getWorld().isClient && (Configs.Fixes.ELYTRA_FIX.getBooleanValue() == false || ((Object) this instanceof ClientPlayerEntity) == false); 44 | } 45 | */ 46 | 47 | @Inject(method = "tickEffects", at = @At(value = "INVOKE", ordinal = 0, 48 | target = "Lnet/minecraft/network/syncher/SynchedEntityData;get(Lnet/minecraft/network/syncher/EntityDataAccessor;)Ljava/lang/Object;"), 49 | cancellable = true) 50 | private void tweakeroo_removeOwnPotionEffects(CallbackInfo ci) 51 | { 52 | Minecraft mc = Minecraft.getInstance(); 53 | 54 | if (Configs.Disable.DISABLE_FP_EFFECT_PARTICLES.getBooleanValue() && 55 | ((Object) this) == mc.player && 56 | mc.options.getCameraType() == CameraType.FIRST_PERSON) 57 | { 58 | ci.cancel(); 59 | } 60 | } 61 | 62 | @Inject(method = "aiStep", at = @At(value = "INVOKE", 63 | target = "Lnet/minecraft/world/entity/LivingEntity;isFallFlying()Z")) 64 | private void tweakeroo_applyCustomDeceleration(CallbackInfo ci) 65 | { 66 | if (FeatureToggle.TWEAK_CUSTOM_FLY_DECELERATION.getBooleanValue() && 67 | ((Entity) this) == Minecraft.getInstance().player) 68 | { 69 | MiscUtils.handlePlayerDeceleration(); 70 | } 71 | } 72 | 73 | @Inject(method = "completeUsingItem", at = @At("RETURN")) 74 | private void tweakeroo_onItemConsumed(CallbackInfo ci) 75 | { 76 | if (FeatureToggle.TWEAK_HAND_RESTOCK.getBooleanValue()) 77 | { 78 | if ((Object) this instanceof Player player) 79 | { 80 | PlacementTweaks.onProcessRightClickPost(player, this.getUsedItemHand()); 81 | } 82 | } 83 | } 84 | 85 | // Save and restore the Gamma Override while Night Vision is activated. 86 | @Inject(method = "onEffectAdded", at = @At("HEAD")) 87 | private void tweakeroo$onStatusEffectApplied(MobEffectInstance effect, Entity source, CallbackInfo ci) 88 | { 89 | if (FeatureToggle.TWEAK_GAMMA_OVERRIDE.getBooleanValue() && 90 | effect.getEffect() == MobEffects.NIGHT_VISION) 91 | { 92 | MiscUtils.toggleGammaOverrideWithMessage(); 93 | this.wasGammaOverriden = true; 94 | } 95 | } 96 | 97 | @Inject(method = "onEffectUpdated", at = @At("HEAD")) 98 | private void tweakeroo$onStatusEffectUpgraded(MobEffectInstance effect, boolean reapplyEffect, Entity source, CallbackInfo ci) 99 | { 100 | if (FeatureToggle.TWEAK_GAMMA_OVERRIDE.getBooleanValue() && 101 | effect.getEffect() == MobEffects.NIGHT_VISION) 102 | { 103 | MiscUtils.toggleGammaOverrideWithMessage(); 104 | this.wasGammaOverriden = true; 105 | } 106 | } 107 | 108 | @Inject(method = "onEffectsRemoved", at = @At("HEAD")) 109 | private void tweakeroo$onStatusEffectRemoved(Collection effects, CallbackInfo ci) 110 | { 111 | if (this.wasGammaOverriden) 112 | { 113 | for (MobEffectInstance entry : effects) 114 | { 115 | if (entry.getEffect() == MobEffects.NIGHT_VISION) 116 | { 117 | if (!FeatureToggle.TWEAK_GAMMA_OVERRIDE.getBooleanValue()) 118 | { 119 | MiscUtils.toggleGammaOverrideWithMessage(); 120 | } 121 | 122 | this.wasGammaOverriden = false; 123 | break; 124 | } 125 | } 126 | } 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/block/MixinStructureBlockBlockEntity.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.block; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collection; 5 | import java.util.List; 6 | import java.util.Objects; 7 | import java.util.stream.Stream; 8 | import org.objectweb.asm.Opcodes; 9 | 10 | import net.minecraft.core.BlockPos; 11 | import net.minecraft.world.level.Level; 12 | import net.minecraft.world.level.block.entity.BlockEntity; 13 | import net.minecraft.world.level.block.entity.BlockEntityType; 14 | import net.minecraft.world.level.block.entity.StructureBlockEntity; 15 | import net.minecraft.world.level.block.state.BlockState; 16 | import net.minecraft.world.level.block.state.properties.StructureMode; 17 | import net.minecraft.world.level.chunk.LevelChunk; 18 | import org.spongepowered.asm.mixin.Mixin; 19 | import org.spongepowered.asm.mixin.injection.At; 20 | import org.spongepowered.asm.mixin.injection.Constant; 21 | import org.spongepowered.asm.mixin.injection.Inject; 22 | import org.spongepowered.asm.mixin.injection.ModifyConstant; 23 | import org.spongepowered.asm.mixin.injection.Slice; 24 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 25 | import fi.dy.masa.tweakeroo.config.Configs; 26 | import fi.dy.masa.tweakeroo.config.FeatureToggle; 27 | 28 | @Mixin(value = StructureBlockEntity.class, priority = 999) 29 | public abstract class MixinStructureBlockBlockEntity extends BlockEntity 30 | { 31 | private MixinStructureBlockBlockEntity(BlockEntityType blockEntityType, BlockPos blockPos, BlockState blockState) 32 | { 33 | super(blockEntityType, blockPos, blockState); 34 | } 35 | 36 | @ModifyConstant(method = "loadAdditional", 37 | slice = @Slice(from = @At(value = "FIELD", 38 | target = "Lnet/minecraft/world/level/block/entity/StructureBlockEntity;metaData:Ljava/lang/String;", 39 | opcode = Opcodes.PUTFIELD), 40 | to = @At(value = "FIELD", 41 | target = "Lnet/minecraft/world/level/block/entity/StructureBlockEntity;structureSize:Lnet/minecraft/core/Vec3i;", 42 | opcode = Opcodes.PUTFIELD)), 43 | constant = { @Constant(intValue = -48), @Constant(intValue = 48) }, require = 0) 44 | private int overrideMaxSize(int original) 45 | { 46 | if (FeatureToggle.TWEAK_STRUCTURE_BLOCK_LIMIT.getBooleanValue()) 47 | { 48 | int overridden = Configs.Generic.STRUCTURE_BLOCK_MAX_SIZE.getIntegerValue(); 49 | return original == -48 ? -overridden : overridden; 50 | } 51 | 52 | return original; 53 | } 54 | 55 | @Inject(method = "getRelatedCorners", at = @At("HEAD"), cancellable = true) 56 | private void overrideCornerBlockScan(BlockPos start, BlockPos end, CallbackInfoReturnable> cir) 57 | { 58 | if (FeatureToggle.TWEAK_STRUCTURE_BLOCK_LIMIT.getBooleanValue()) 59 | { 60 | BlockPos pos = this.getBlockPos(); 61 | Level world = this.getLevel(); 62 | String name = ((StructureBlockEntity) (Object) this).getStructureName(); 63 | int maxSize = Configs.Generic.STRUCTURE_BLOCK_MAX_SIZE.getIntegerValue(); 64 | int maxOffset = 48; 65 | 66 | // Expand by the maximum position/offset and a bit of margin 67 | final int minX = pos.getX() - maxSize - maxOffset - 2; 68 | final int minZ = pos.getZ() - maxSize - maxOffset - 2; 69 | final int maxX = pos.getX() + maxSize + maxOffset + 2; 70 | final int maxZ = pos.getZ() + maxSize + maxOffset + 2; 71 | 72 | final int minY = Math.max(world.getMinY() , pos.getY() - maxSize - maxOffset - 2); 73 | final int maxY = Math.min(world.getMaxY(), pos.getY() + maxSize + maxOffset + 2); 74 | List positions = new ArrayList<>(); 75 | 76 | for (int cz = minZ >> 4; cz <= (maxZ >> 4); ++cz) 77 | { 78 | for (int cx = minX >> 4; cx <= (maxX >> 4); ++cx) 79 | { 80 | LevelChunk chunk = world.getChunk(cx, cz); 81 | 82 | if (chunk == null) 83 | { 84 | continue; 85 | } 86 | 87 | Collection list = chunk.getBlockEntities().values(); 88 | 89 | for (BlockEntity te : list) 90 | { 91 | if (te instanceof StructureBlockEntity) 92 | { 93 | StructureBlockEntity tes = (StructureBlockEntity) te; 94 | BlockPos p = te.getBlockPos(); 95 | 96 | if (tes.getMode() == StructureMode.CORNER && 97 | Objects.equals(tes.getStructureName(), name) && 98 | p.getX() >= minX && p.getX() <= maxX && 99 | p.getY() >= minY && p.getY() <= maxY && 100 | p.getZ() >= minZ && p.getZ() <= maxZ) 101 | { 102 | positions.add(p); 103 | } 104 | } 105 | } 106 | } 107 | } 108 | 109 | cir.setReturnValue(positions.stream()); 110 | } 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/mixin/freecam/MixinWorldRenderer_freeCam.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.mixin.freecam; 2 | 3 | import org.joml.Matrix4f; 4 | import org.joml.Vector4f; 5 | import org.objectweb.asm.Opcodes; 6 | 7 | import com.mojang.blaze3d.buffers.GpuBufferSlice; 8 | import com.mojang.blaze3d.resource.GraphicsResourceAllocator; 9 | import org.spongepowered.asm.mixin.Mixin; 10 | import org.spongepowered.asm.mixin.Shadow; 11 | import org.spongepowered.asm.mixin.Unique; 12 | import org.spongepowered.asm.mixin.injection.At; 13 | import org.spongepowered.asm.mixin.injection.Inject; 14 | import org.spongepowered.asm.mixin.injection.Redirect; 15 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 16 | 17 | import fi.dy.masa.tweakeroo.config.FeatureToggle; 18 | import fi.dy.masa.tweakeroo.util.CameraUtils; 19 | import net.minecraft.client.Camera; 20 | import net.minecraft.client.DeltaTracker; 21 | import net.minecraft.client.Minecraft; 22 | import net.minecraft.client.renderer.LevelRenderer; 23 | import net.minecraft.client.renderer.culling.Frustum; 24 | import net.minecraft.util.Mth; 25 | import net.minecraft.world.entity.Entity; 26 | 27 | @Mixin(value = LevelRenderer.class, priority = 1005) 28 | public abstract class MixinWorldRenderer_freeCam 29 | { 30 | @Shadow private int lastCameraSectionX; 31 | @Shadow private int lastCameraSectionZ; 32 | 33 | @Unique private int lastUpdatePosX; 34 | @Unique private int lastUpdatePosZ; 35 | 36 | @Inject(method = "renderLevel", at = @At(value = "INVOKE_STRING", 37 | target = "Lnet/minecraft/util/profiling/ProfilerFiller;popPush(Ljava/lang/String;)V", args = "ldc=cullTerrain")) 38 | private void tweakeroo_preSetupTerrain(GraphicsResourceAllocator allocator, DeltaTracker tickCounter, boolean renderBlockOutline, 39 | Camera camera, Matrix4f matrix4f, Matrix4f projectionMatrix, Matrix4f matrix4f2, 40 | GpuBufferSlice gpuBufferSlice, Vector4f vector4f, boolean bl, CallbackInfo ci) 41 | { 42 | if (FeatureToggle.TWEAK_FREE_CAMERA.getBooleanValue()) 43 | { 44 | CameraUtils.setFreeCameraSpectator(true); 45 | } 46 | } 47 | 48 | @Inject(method = "renderLevel", at = @At(value = "INVOKE_STRING", 49 | target = "Lnet/minecraft/util/profiling/ProfilerFiller;popPush(Ljava/lang/String;)V", args = "ldc=compileSections")) 50 | private void tweakeroo_postSetupTerrain(GraphicsResourceAllocator allocator, DeltaTracker tickCounter, boolean renderBlockOutline, 51 | Camera camera, Matrix4f matrix4f, Matrix4f projectionMatrix, Matrix4f matrix4f2, 52 | GpuBufferSlice gpuBufferSlice, Vector4f vector4f, boolean bl, CallbackInfo ci) 53 | { 54 | CameraUtils.setFreeCameraSpectator(false); 55 | } 56 | 57 | // Allow rendering the client player entity by spoofing one of the entity rendering conditions while in Free Camera mode 58 | @Redirect(method = "extractVisibleEntities", require = 0, at = @At(value = "INVOKE", 59 | target = "Lnet/minecraft/client/Camera;entity()Lnet/minecraft/world/entity/Entity;", ordinal = 3)) 60 | private Entity tweakeroo_allowRenderingClientPlayerInFreeCameraMode(Camera camera) 61 | { 62 | if (FeatureToggle.TWEAK_FREE_CAMERA.getBooleanValue()) 63 | { 64 | return Minecraft.getInstance().player; 65 | } 66 | 67 | return camera.entity(); 68 | } 69 | 70 | // cullTerrain -> method_74752 71 | // These injections will fail when Sodium is present, but the Free Camera 72 | // rendering seems to work fine with Sodium without these anyway 73 | @Inject(method = "cullTerrain", require = 0, 74 | at = @At(value = "FIELD", opcode = Opcodes.PUTFIELD, 75 | target = "Lnet/minecraft/client/renderer/LevelRenderer;prevCamX:D")) 76 | private void tweakeroo_rebuildChunksAroundCamera1( 77 | Camera camera, Frustum frustum, boolean bl, CallbackInfo ci) 78 | { 79 | if (FeatureToggle.TWEAK_FREE_CAMERA.getBooleanValue()) 80 | { 81 | // Hold on to the previous update position before it gets updated 82 | this.lastUpdatePosX = this.lastCameraSectionX; 83 | this.lastUpdatePosZ = this.lastCameraSectionZ; 84 | } 85 | } 86 | 87 | // cullTerrain -> method_74752 88 | // These injections will fail when Sodium is present, but the Free Camera 89 | // rendering seems to work fine with Sodium without these anyway 90 | @Inject(method = "cullTerrain", require = 0, 91 | at = @At(value = "INVOKE", shift = At.Shift.AFTER, 92 | target = "Lnet/minecraft/client/renderer/ViewArea;repositionCamera(Lnet/minecraft/core/SectionPos;)V")) 93 | private void tweakeroo_rebuildChunksAroundCamera2(Camera camera, Frustum frustum, boolean bl, CallbackInfo ci) 94 | { 95 | // Mark the chunks at the edge of the free camera's render range for rebuilding 96 | // when the camera moves around. 97 | // Normally these rebuilds would happen when the server sends chunks to the client when the player moves around. 98 | // But in Free Camera mode moving the ViewFrustum/BuiltChunkStorage would cause the terrain 99 | // to disappear because of no dirty marking calls from chunk loading. 100 | if (FeatureToggle.TWEAK_FREE_CAMERA.getBooleanValue()) 101 | { 102 | int x = Mth.floor(camera.position().x) >> 4; 103 | int z = Mth.floor(camera.position().z) >> 4; 104 | CameraUtils.markChunksForRebuild(x, z, this.lastUpdatePosX, this.lastUpdatePosZ); 105 | // Could send this to Servux in the future 106 | } 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /src/main/java/fi/dy/masa/tweakeroo/util/CameraPreset.java: -------------------------------------------------------------------------------- 1 | package fi.dy.masa.tweakeroo.util; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import net.minecraft.core.BlockPos; 6 | import net.minecraft.resources.Identifier; 7 | import net.minecraft.world.entity.Entity; 8 | import net.minecraft.world.level.Level; 9 | import net.minecraft.world.phys.Vec3; 10 | import org.jetbrains.annotations.NotNull; 11 | import org.jetbrains.annotations.Nullable; 12 | 13 | import com.mojang.serialization.Codec; 14 | import com.mojang.serialization.codecs.PrimitiveCodec; 15 | import com.mojang.serialization.codecs.RecordCodecBuilder; 16 | import fi.dy.masa.malilib.gui.Message; 17 | import fi.dy.masa.malilib.gui.interfaces.IMessageConsumer; 18 | import fi.dy.masa.malilib.util.StringUtils; 19 | 20 | public class CameraPreset 21 | { 22 | public static final Codec CODEC = RecordCodecBuilder.create( 23 | inst -> inst.group( 24 | PrimitiveCodec.INT.fieldOf("id").forGetter(get -> get.id), 25 | PrimitiveCodec.STRING.fieldOf("name").forGetter(get -> get.name), 26 | Identifier.CODEC.fieldOf("dim").forGetter(get -> get.dim), 27 | Vec3.CODEC.fieldOf("pos").forGetter(get -> get.pos), 28 | PrimitiveCodec.FLOAT.fieldOf("yaw").forGetter(get -> get.yaw), 29 | PrimitiveCodec.FLOAT.fieldOf("pitch").forGetter(get -> get.pitch) 30 | ).apply(inst, CameraPreset::new) 31 | ); 32 | public static final CameraPreset EMPTY = new CameraPreset(-1, "EMPTY", Level.OVERWORLD.identifier(), Vec3.ZERO, 0.0f, 0.0f); 33 | private final int id; 34 | private String name; 35 | private final Identifier dim; 36 | private Vec3 pos; 37 | private float yaw; 38 | private float pitch; 39 | 40 | public CameraPreset(final int id, String name, Identifier dim, Vec3 pos, float yaw, float pitch) 41 | { 42 | this.id = id; 43 | this.name = name; 44 | this.dim = dim; 45 | this.pos = pos; 46 | this.yaw = yaw; 47 | this.pitch = pitch; 48 | } 49 | 50 | public int getId() 51 | { 52 | return this.id; 53 | } 54 | 55 | public String getName() 56 | { 57 | return this.name; 58 | } 59 | 60 | public Identifier getDim() 61 | { 62 | return this.dim; 63 | } 64 | 65 | public Vec3 getPos() 66 | { 67 | return this.pos; 68 | } 69 | 70 | public float getYaw() 71 | { 72 | return this.yaw; 73 | } 74 | 75 | public float getPitch() 76 | { 77 | return this.pitch; 78 | } 79 | 80 | public void setName(String name) 81 | { 82 | this.name = name; 83 | } 84 | 85 | public void setPos(Vec3 pos, float yaw, float pitch) 86 | { 87 | this.pos = pos; 88 | this.yaw = yaw; 89 | this.pitch = pitch; 90 | } 91 | 92 | public boolean renamePreset(String newName, @Nullable IMessageConsumer feedback) 93 | { 94 | String oldName = this.name; 95 | this.setName(newName); 96 | 97 | if (feedback != null) 98 | { 99 | feedback.addMessage(Message.MessageType.SUCCESS, "tweakeroo.message.free_cam.preset_renamed", oldName, newName); 100 | } 101 | 102 | return true; 103 | } 104 | 105 | /** 106 | * Format this as a String. 107 | * @return () 108 | */ 109 | @Override 110 | public @NotNull String toString() 111 | { 112 | return "CameraPreset["+ 113 | "{id=\""+this.id+"\"}"+ 114 | ",{name=\""+this.name+"\"}"+ 115 | ",{dim=\""+this.dim.toString()+"\"}"+ 116 | ",{pos=\""+this.pos.toString()+"\"}"+ 117 | ",{yaw=\""+this.yaw+"\"}"+ 118 | ",{pitch=\""+this.pitch+"\"}"+ 119 | "]"; 120 | } 121 | 122 | /** 123 | * Standard 'equals' that ignores a presets' name and id 124 | * 125 | * @param o (Preset|Camera Entity) 126 | * @return (True|False) 127 | */ 128 | @Override 129 | public boolean equals(Object o) 130 | { 131 | if (o instanceof CameraPreset other) 132 | { 133 | // Should match the exact position. 134 | return this.dim.equals(other.dim) && 135 | this.pos.equals(other.pos) && 136 | this.yaw == other.yaw && 137 | this.pitch == other.pitch; 138 | } 139 | else if (o instanceof Entity camera) 140 | { 141 | // Should match a relative position. Need to dial this in. 142 | return this.dim.equals(camera.level().dimension().identifier()) && 143 | (this.pos.closerThan(camera.getEyePosition(), 0.75d, 0.75d) || // 3/4-block offset ? 144 | this.pos.closerThan(camera.position(), 0.75d, 0.75d)) && 145 | Math.abs(this.yaw - camera.getYRot()) < 35.0f && // 35 deg offset ? 146 | Math.abs(this.pitch - camera.getXRot()) < 35.0f; 147 | } 148 | 149 | return false; 150 | } 151 | 152 | public String toIdName() 153 | { 154 | return String.format("%02d", this.id)+", "+this.name; 155 | } 156 | 157 | public List getWidgetHoverLines() 158 | { 159 | List lines = new ArrayList<>(); 160 | 161 | lines.add(StringUtils.translate("tweakeroo.gui.hover.camera_preset.id", String.format("%02d", this.id))); 162 | lines.add(StringUtils.translate("tweakeroo.gui.hover.camera_preset.name", this.name)); 163 | lines.add(StringUtils.translate("tweakeroo.gui.hover.camera_preset.dim", this.dim.toString())); 164 | lines.add(StringUtils.translate("tweakeroo.gui.hover.camera_preset.pos", String.format("%.3f", this.pos.x), String.format("%.3f", this.pos.y), String.format("%.3f", this.pos.z))); 165 | lines.add(StringUtils.translate("tweakeroo.gui.hover.camera_preset.yaw_pitch", String.format("%.3f", this.yaw), String.format("%.3f", this.pitch))); 166 | 167 | return lines; 168 | } 169 | 170 | /** 171 | * Format this in a less complex format. 172 | * @return () 173 | */ 174 | public String toShortString() 175 | { 176 | return "[#"+this.toIdName()+"]"+ 177 | " "+this.dim.getPath()+":"+ 178 | " ("+BlockPos.containing(this.pos.x, this.pos.y, this.pos.z).toShortString()+")"; 179 | } 180 | 181 | public String toShortStringStyled() 182 | { 183 | BlockPos pos = BlockPos.containing(this.pos.x, this.pos.y, this.pos.z); 184 | 185 | return "[§b#"+String.format("%02d", this.id)+"§r, §a"+this.name+"§r]"+ 186 | " §e"+this.dim.getPath()+":§r"+ 187 | " ("+pos.getX()+", "+pos.getY()+", "+pos.getZ()+")"; 188 | } 189 | } 190 | --------------------------------------------------------------------------------