From d08f8e1a789552c5ebdae455f860f185d000bc59 Mon Sep 17 00:00:00 2001 From: tterrag Date: Fri, 21 Sep 2018 22:07:48 -0400 Subject: [PATCH] Fix remaining issues preventing compilation, launching, and loading worlds (#5156) Fix duplicate ID for ingredient serializers Fix KeyBinding compile errors. No GuiKeyBindingList patches yet. Implement controls GUI and WorldServer patches --- .../client/gui/GuiControls.java.patch | 26 ++ .../client/gui/GuiKeyBindingList.java.patch | 59 +++++ .../client/settings/KeyBinding.java.patch | 193 ++++++++++++++- .../net/minecraft/init/Bootstrap.java.patch | 8 +- .../minecraft/world/WorldServer.java.patch | 229 +++++++++++++++++- .../world/dimension/Dimension.java.patch | 11 +- .../client/extensions/IForgeKeybinding.java | 53 ++++ .../client/settings/KeyBindingMap.java | 39 +-- .../client/settings/KeyModifier.java | 41 ++-- .../common/DimensionManager.java | 2 +- .../net/minecraftforge/common/ForgeHooks.java | 14 -- .../common/crafting/CraftingHelper.java | 2 +- .../common/extensions/IForgeDimension.java | 35 ++- .../common/extensions/IForgeFluidState.java | 1 - .../resources/assets/forge/lang/en_us.json | 7 +- 15 files changed, 645 insertions(+), 75 deletions(-) create mode 100644 patches/minecraft/net/minecraft/client/gui/GuiControls.java.patch create mode 100644 patches/minecraft/net/minecraft/client/gui/GuiKeyBindingList.java.patch create mode 100644 src/main/java/net/minecraftforge/client/extensions/IForgeKeybinding.java diff --git a/patches/minecraft/net/minecraft/client/gui/GuiControls.java.patch b/patches/minecraft/net/minecraft/client/gui/GuiControls.java.patch new file mode 100644 index 0000000000..484bc153b5 --- /dev/null +++ b/patches/minecraft/net/minecraft/client/gui/GuiControls.java.patch @@ -0,0 +1,26 @@ +--- a/net/minecraft/client/gui/GuiControls.java ++++ b/net/minecraft/client/gui/GuiControls.java +@@ -36,7 +36,7 @@ + this.buttonReset = this.addButton(new GuiButton(201, this.width / 2 - 155, this.height - 29, 150, 20, I18n.format("controls.resetAll")) { + public void func_194829_a(double p_194829_1_, double p_194829_3_) { + for(KeyBinding keybinding : GuiControls.this.mc.gameSettings.keyBindings) { +- keybinding.func_197979_b(keybinding.func_197977_i()); ++ keybinding.setToDefault(); + } + + KeyBinding.resetKeyBindingArrayAndHash(); +@@ -89,11 +89,14 @@ + public boolean keyPressed(int p_keyPressed_1_, int p_keyPressed_2_, int p_keyPressed_3_) { + if (this.buttonId != null) { + if (p_keyPressed_1_ == 256) { ++ this.buttonId.setKeyModifierAndCode(net.minecraftforge.client.settings.KeyModifier.getActiveModifier(), InputMappings.field_197958_a); + this.options.func_198014_a(this.buttonId, InputMappings.field_197958_a); + } else { ++ this.buttonId.setKeyModifierAndCode(net.minecraftforge.client.settings.KeyModifier.getActiveModifier(), InputMappings.func_197954_a(p_keyPressed_1_, p_keyPressed_2_)); + this.options.func_198014_a(this.buttonId, InputMappings.func_197954_a(p_keyPressed_1_, p_keyPressed_2_)); + } + ++ if (!net.minecraftforge.client.settings.KeyModifier.isKeyCodeModifier(this.buttonId.getKey())) + this.buttonId = null; + this.time = Util.func_211177_b(); + KeyBinding.resetKeyBindingArrayAndHash(); diff --git a/patches/minecraft/net/minecraft/client/gui/GuiKeyBindingList.java.patch b/patches/minecraft/net/minecraft/client/gui/GuiKeyBindingList.java.patch new file mode 100644 index 0000000000..1504758562 --- /dev/null +++ b/patches/minecraft/net/minecraft/client/gui/GuiKeyBindingList.java.patch @@ -0,0 +1,59 @@ +--- a/net/minecraft/client/gui/GuiKeyBindingList.java ++++ b/net/minecraft/client/gui/GuiKeyBindingList.java +@@ -41,7 +41,7 @@ + } + + protected int getScrollBarX() { +- return super.getScrollBarX() + 15; ++ return super.getScrollBarX() + 35; + } + + public int getListWidth() { +@@ -77,13 +77,14 @@ + private KeyEntry(final KeyBinding name) { + this.keybinding = name; + this.keyDesc = I18n.format(name.getKeyDescription()); +- this.btnChangeKeyBinding = new GuiButton(0, 0, 0, 75, 20, I18n.format(name.getKeyDescription())) { ++ this.btnChangeKeyBinding = new GuiButton(0, 0, 0, 95, 20, I18n.format(name.func_197978_k())) { + public void func_194829_a(double p_194829_1_, double p_194829_3_) { + GuiKeyBindingList.this.controlsScreen.buttonId = name; + } + }; + this.btnReset = new GuiButton(0, 0, 0, 50, 20, I18n.format("controls.reset")) { + public void func_194829_a(double p_194829_1_, double p_194829_3_) { ++ keybinding.setToDefault(); + GuiKeyBindingList.this.mc.gameSettings.func_198014_a(name, name.func_197977_i()); + KeyBinding.resetKeyBindingArrayAndHash(); + } +@@ -95,7 +96,7 @@ + int j = this.func_195002_d(); + boolean flag = GuiKeyBindingList.this.controlsScreen.buttonId == this.keybinding; + GuiKeyBindingList.this.mc.fontRenderer.func_211126_b(this.keyDesc, (float)(j + 90 - GuiKeyBindingList.this.maxListLabelWidth), (float)(i + p_194999_2_ / 2 - GuiKeyBindingList.this.mc.fontRenderer.FONT_HEIGHT / 2), 16777215); +- this.btnReset.x = j + 190; ++ this.btnReset.x = j + 210; + this.btnReset.y = i; + this.btnReset.enabled = !this.keybinding.func_197985_l(); + this.btnReset.func_194828_a(p_194999_3_, p_194999_4_, p_194999_6_); +@@ -103,11 +104,12 @@ + this.btnChangeKeyBinding.y = i; + this.btnChangeKeyBinding.displayString = this.keybinding.func_197978_k(); + boolean flag1 = false; ++ boolean keyCodeModifierConflict = true; // less severe form of conflict, like SHIFT conflicting with SHIFT+G + if (!this.keybinding.func_197986_j()) { + for(KeyBinding keybinding : GuiKeyBindingList.this.mc.gameSettings.keyBindings) { + if (keybinding != this.keybinding && this.keybinding.func_197983_b(keybinding)) { + flag1 = true; +- break; ++ keyCodeModifierConflict &= keybinding.hasKeyCodeModifierConflict(this.keybinding); + } + } + } +@@ -115,7 +117,7 @@ + if (flag) { + this.btnChangeKeyBinding.displayString = TextFormatting.WHITE + "> " + TextFormatting.YELLOW + this.btnChangeKeyBinding.displayString + TextFormatting.WHITE + " <"; + } else if (flag1) { +- this.btnChangeKeyBinding.displayString = TextFormatting.RED + this.btnChangeKeyBinding.displayString; ++ this.btnChangeKeyBinding.displayString = (keyCodeModifierConflict ? TextFormatting.GOLD : TextFormatting.RED) + this.btnChangeKeyBinding.displayString; + } + + this.btnChangeKeyBinding.func_194828_a(p_194999_3_, p_194999_4_, p_194999_6_); diff --git a/patches/minecraft/net/minecraft/client/settings/KeyBinding.java.patch b/patches/minecraft/net/minecraft/client/settings/KeyBinding.java.patch index b39501f3bb..909aa6b789 100644 --- a/patches/minecraft/net/minecraft/client/settings/KeyBinding.java.patch +++ b/patches/minecraft/net/minecraft/client/settings/KeyBinding.java.patch @@ -1,12 +1,201 @@ --- a/net/minecraft/client/settings/KeyBinding.java +++ b/net/minecraft/client/settings/KeyBinding.java -@@ -163,4 +163,9 @@ +@@ -12,9 +12,9 @@ + import net.minecraftforge.api.distmarker.OnlyIn; + + @OnlyIn(Dist.CLIENT) +-public class KeyBinding implements Comparable { ++public class KeyBinding implements Comparable, net.minecraftforge.client.extensions.IForgeKeybinding { + private static final Map KEYBIND_ARRAY = Maps.newHashMap(); +- private static final Map HASH = Maps.newHashMap(); ++ private static final net.minecraftforge.client.settings.KeyBindingMap HASH = new net.minecraftforge.client.settings.KeyBindingMap(); + private static final Set KEYBIND_SET = Sets.newHashSet(); + private static final Map CATEGORY_ORDER = (Map)Util.func_200696_a(Maps.newHashMap(), (p_205215_0_) -> { + p_205215_0_.put("key.categories.movement", 1); +@@ -33,7 +33,7 @@ + private int pressTime; + + public static void func_197981_a(InputMappings.Input p_197981_0_) { +- KeyBinding keybinding = HASH.get(p_197981_0_); ++ for (KeyBinding keybinding : HASH.lookupAll(p_197981_0_)) + if (keybinding != null) { + ++keybinding.pressTime; + } +@@ -41,7 +41,7 @@ + } + + public static void func_197980_a(InputMappings.Input p_197980_0_, boolean p_197980_1_) { +- KeyBinding keybinding = HASH.get(p_197980_0_); ++ for (KeyBinding keybinding : HASH.lookupAll(p_197980_0_)) + if (keybinding != null) { + keybinding.pressed = p_197980_1_; + } +@@ -65,10 +65,10 @@ + } + + public static void resetKeyBindingArrayAndHash() { +- HASH.clear(); ++ HASH.clearMap(); + + for(KeyBinding keybinding : KEYBIND_ARRAY.values()) { +- HASH.put(keybinding.keyCode, keybinding); ++ HASH.addKey(keybinding.keyCode, keybinding); + } + + } +@@ -83,12 +83,12 @@ + this.keyCodeDefault = this.keyCode; + this.keyCategory = p_i47675_4_; + KEYBIND_ARRAY.put(p_i47675_1_, this); +- HASH.put(this.keyCode, this); ++ HASH.addKey(this.keyCode, this); + KEYBIND_SET.add(p_i47675_4_); + } + + public boolean isKeyDown() { +- return this.pressed; ++ return this.pressed && getKeyConflictContext().isActive() && getKeyModifier().isActive(getKeyConflictContext()); + } + + public String getKeyCategory() { +@@ -122,17 +122,41 @@ + } + + public int compareTo(KeyBinding p_compareTo_1_) { +- return this.keyCategory.equals(p_compareTo_1_.keyCategory) ? I18n.format(this.keyDescription).compareTo(I18n.format(p_compareTo_1_.keyDescription)) : ((Integer)CATEGORY_ORDER.get(this.keyCategory)).compareTo(CATEGORY_ORDER.get(p_compareTo_1_.keyCategory)); ++ if (this.keyCategory.equals(p_compareTo_1_.keyCategory)) return I18n.format(this.keyDescription).compareTo(I18n.format(p_compareTo_1_.keyDescription)); ++ Integer tCat = CATEGORY_ORDER.get(this.keyCategory); ++ Integer oCat = CATEGORY_ORDER.get(p_compareTo_1_.keyCategory); ++ if (tCat == null && oCat != null) return 1; ++ if (tCat != null && oCat == null) return -1; ++ if (tCat == null && oCat == null) return I18n.format(this.keyCategory).compareTo(I18n.format(p_compareTo_1_.keyCategory)); ++ return tCat.compareTo(oCat); + } + + public static Supplier getDisplayString(String key) { + KeyBinding keybinding = KEYBIND_ARRAY.get(key); + return keybinding == null ? () -> { + return key; +- } : keybinding::func_197978_k; ++ } : () -> keybinding.func_197978_k(); + } + + public boolean func_197983_b(KeyBinding p_197983_1_) { ++ if (getKeyConflictContext().conflicts(p_197983_1_.getKeyConflictContext()) || p_197983_1_.getKeyConflictContext().conflicts(getKeyConflictContext())) ++ { ++ net.minecraftforge.client.settings.KeyModifier keyModifier = getKeyModifier(); ++ net.minecraftforge.client.settings.KeyModifier otherKeyModifier = p_197983_1_.getKeyModifier(); ++ if (keyModifier.matches(p_197983_1_.getKey()) || otherKeyModifier.matches(getKey())) ++ { ++ return true; ++ } ++ else if (getKey().equals(p_197983_1_.getKey())) ++ { ++ return keyModifier == otherKeyModifier || ++ // IN_GAME key contexts have a conflict when at least one modifier is NONE. ++ // For example: If you hold shift to crouch, you can still press E to open your inventory. This means that a Shift+E hotkey is in conflict with E. ++ // GUI and other key contexts do not have this limitation. ++ (getKeyConflictContext().conflicts(net.minecraftforge.client.settings.KeyConflictContext.IN_GAME) && ++ (keyModifier == net.minecraftforge.client.settings.KeyModifier.NONE || otherKeyModifier == net.minecraftforge.client.settings.KeyModifier.NONE)); ++ } ++ } + return this.keyCode.equals(p_197983_1_.keyCode); + } + +@@ -153,14 +177,94 @@ + } + + public String func_197978_k() { +- return this.keyCode.func_197936_a(); ++ return getKeyModifier().getLocalizedComboName(this.keyCode); + } + + public boolean func_197985_l() { +- return this.keyCode.equals(this.keyCodeDefault); ++ return getKey().equals(this.keyCodeDefault) && getKeyModifier() == getKeyModifierDefault(); + } + public String func_197982_m() { return this.keyCode.func_197935_d(); } -+ ++ ++ /****************** Forge Start *****************************/ ++ ++ private net.minecraftforge.client.settings.KeyModifier keyModifierDefault = net.minecraftforge.client.settings.KeyModifier.NONE; ++ private net.minecraftforge.client.settings.KeyModifier keyModifier = net.minecraftforge.client.settings.KeyModifier.NONE; ++ private net.minecraftforge.client.settings.IKeyConflictContext keyConflictContext = net.minecraftforge.client.settings.KeyConflictContext.UNIVERSAL; ++ ++ /** ++ * Convenience constructor for creating KeyBindings with keyConflictContext set. ++ */ ++ public KeyBinding(String description, net.minecraftforge.client.settings.IKeyConflictContext keyConflictContext, InputMappings.Input keyCode, String category) ++ { ++ this(description, keyConflictContext, net.minecraftforge.client.settings.KeyModifier.NONE, keyCode, category); ++ } ++ ++ /** ++ * Convenience constructor for creating KeyBindings with keyConflictContext and keyModifier set. ++ */ ++ public KeyBinding(String description, net.minecraftforge.client.settings.IKeyConflictContext keyConflictContext, net.minecraftforge.client.settings.KeyModifier keyModifier, InputMappings.Input keyCode, String category) ++ { ++ this.keyDescription = description; ++ this.keyCode = keyCode; ++ this.keyCodeDefault = keyCode; ++ this.keyCategory = category; ++ this.keyConflictContext = keyConflictContext; ++ this.keyModifier = keyModifier; ++ this.keyModifierDefault = keyModifier; ++ if (this.keyModifier.matches(keyCode)) ++ { ++ this.keyModifier = net.minecraftforge.client.settings.KeyModifier.NONE; ++ } ++ KEYBIND_ARRAY.put(description, this); ++ HASH.addKey(keyCode, this); ++ KEYBIND_SET.add(category); ++ } ++ ++ @Override + public InputMappings.Input getKey() + { + return this.keyCode; + } ++ ++ @Override ++ public void setKeyConflictContext(net.minecraftforge.client.settings.IKeyConflictContext keyConflictContext) ++ { ++ this.keyConflictContext = keyConflictContext; ++ } ++ ++ @Override ++ public net.minecraftforge.client.settings.IKeyConflictContext getKeyConflictContext() ++ { ++ return keyConflictContext; ++ } ++ ++ @Override ++ public net.minecraftforge.client.settings.KeyModifier getKeyModifierDefault() ++ { ++ return keyModifierDefault; ++ } ++ ++ @Override ++ public net.minecraftforge.client.settings.KeyModifier getKeyModifier() ++ { ++ return keyModifier; ++ } ++ ++ @Override ++ public void setKeyModifierAndCode(net.minecraftforge.client.settings.KeyModifier keyModifier, InputMappings.Input keyCode) ++ { ++ this.keyCode = keyCode; ++ if (keyModifier.matches(keyCode)) ++ { ++ keyModifier = net.minecraftforge.client.settings.KeyModifier.NONE; ++ } ++ HASH.removeKey(this); ++ this.keyModifier = keyModifier; ++ HASH.addKey(keyCode, this); ++ } ++ ++ /****************** Forge End *****************************/ } diff --git a/patches/minecraft/net/minecraft/init/Bootstrap.java.patch b/patches/minecraft/net/minecraft/init/Bootstrap.java.patch index 6c5730e42a..8ebdccb99d 100644 --- a/patches/minecraft/net/minecraft/init/Bootstrap.java.patch +++ b/patches/minecraft/net/minecraft/init/Bootstrap.java.patch @@ -1,19 +1,19 @@ --- a/net/minecraft/init/Bootstrap.java +++ b/net/minecraft/init/Bootstrap.java -@@ -75,6 +75,8 @@ +@@ -75,6 +75,7 @@ import net.minecraft.world.biome.Biome; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; -+import net.minecraftforge.registries.ForgeRegistries; + import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -@@ -421,6 +423,7 @@ +@@ -421,6 +422,8 @@ redirectOutputToLog(); } -+ ForgeRegistries.ITEMS.getClass(); // TODO figure out a better way to ensure this is initialized ++ net.minecraftforge.registries.ForgeRegistries.ITEMS.getClass(); // TODO figure out a better way to ensure these are initialized ++ net.minecraft.tileentity.TileEntityType.field_200970_a.getClass(); } } diff --git a/patches/minecraft/net/minecraft/world/WorldServer.java.patch b/patches/minecraft/net/minecraft/world/WorldServer.java.patch index bc33e5d1f6..a973ea567e 100644 --- a/patches/minecraft/net/minecraft/world/WorldServer.java.patch +++ b/patches/minecraft/net/minecraft/world/WorldServer.java.patch @@ -9,7 +9,47 @@ private static final Logger LOGGER = LogManager.getLogger(); private final MinecraftServer server; private final EntityTracker entityTracker; -@@ -150,6 +150,7 @@ +@@ -105,27 +105,36 @@ + protected final VillageSiege villageSiege = new VillageSiege(this); + ObjectLinkedOpenHashSet blockEventQueue = new ObjectLinkedOpenHashSet(); + private boolean field_211159_Q; ++ ++ /** Stores the recently processed (lighting) chunks */ ++ protected java.util.Set doneChunks = new java.util.HashSet(); ++ public List customTeleporters = new java.util.ArrayList(); + + public WorldServer(MinecraftServer server, ISaveHandler saveHandlerIn, WorldInfo info, int dimensionId, Profiler profilerIn) { +- super(saveHandlerIn, info, DimensionType.getById(dimensionId).createDimension(), profilerIn, false); ++ super(saveHandlerIn, info,net.minecraftforge.common.DimensionManager.createProviderFor(dimensionId), profilerIn, false); + this.server = server; + this.entityTracker = new EntityTracker(this); + this.playerChunkMap = new PlayerChunkMap(this); ++ // Guarantee the dimension ID was not reset by the provider ++ int providerDim = this.provider.getId(); + this.provider.setWorld(this); ++ this.provider.setId(providerDim); + this.chunkProvider = this.createChunkProvider(); ++ perWorldStorage = new WorldSavedDataStorage(new net.minecraftforge.common.WorldSpecificSaveHandler((WorldServer)this, saveHandlerIn)); + this.worldTeleporter = new Teleporter(this); + this.calculateInitialSkylight(); + this.calculateInitialWeather(); + this.getWorldBorder().setSize(server.getMaxWorldSize()); ++ net.minecraftforge.common.DimensionManager.setWorld(dimensionId, this, server); + } + + public IWorld init() { + this.mapStorage = new WorldSavedDataStorage(this.saveHandler); + String s = VillageCollection.fileNameForProvider(this.provider); +- VillageCollection villagecollection = (VillageCollection)this.mapStorage.func_201067_a(VillageCollection::new, s); ++ VillageCollection villagecollection = (VillageCollection)this.perWorldStorage.func_201067_a(VillageCollection::new, s); + if (villagecollection == null) { + this.villageCollection = new VillageCollection(this); +- this.mapStorage.setData(s, this.villageCollection); ++ this.perWorldStorage.setData(s, this.villageCollection); + } else { + this.villageCollection = villagecollection; + this.villageCollection.setWorldsForAll(this); +@@ -150,6 +159,7 @@ this.getWorldBorder().setTransition(this.worldInfo.getBorderSize()); } @@ -17,7 +57,192 @@ return this; } -@@ -957,4 +958,12 @@ +@@ -163,8 +173,8 @@ + this.chunkProvider.func_201711_g().func_202090_b().update(); + if (this.areAllPlayersAsleep()) { + if (this.getGameRules().getBoolean("doDaylightCycle")) { +- long i = this.worldInfo.getWorldTime() + 24000L; +- this.worldInfo.setWorldTime(i - i % 24000L); ++ long i = this.getWorldTime() + 24000L; ++ this.setWorldTime(i - i % 24000L); + } + + this.wakeAllPlayers(); +@@ -185,7 +195,7 @@ + + this.worldInfo.setWorldTotalTime(this.worldInfo.getWorldTotalTime() + 1L); + if (this.getGameRules().getBoolean("doDaylightCycle")) { +- this.worldInfo.setWorldTime(this.worldInfo.getWorldTime() + 1L); ++ this.worldInfo.setWorldTime(this.getWorldTime() + 1L); + } + + this.profiler.endStartSection("tickPending"); +@@ -199,6 +209,10 @@ + this.villageSiege.tick(); + this.profiler.endStartSection("portalForcer"); + this.worldTeleporter.removeStalePortalLocations(this.getTotalWorldTime()); ++ for (Teleporter tele : customTeleporters) ++ { ++ tele.removeStalePortalLocations(getTotalWorldTime()); ++ } + this.profiler.endSection(); + this.sendQueuedBlockEvents(); + this.field_211159_Q = false; +@@ -211,11 +225,13 @@ + @Nullable + public Biome.SpawnListEntry getSpawnListEntryForTypeAt(EnumCreatureType creatureType, BlockPos pos) { + List list = this.getChunkProvider().getPossibleCreatures(creatureType, pos); ++ list = net.minecraftforge.event.ForgeEventFactory.getPotentialSpawns(this, creatureType, pos, list); + return list.isEmpty() ? null : (Biome.SpawnListEntry)WeightedRandom.getRandomItem(this.rand, list); + } + + public boolean canCreatureTypeSpawnHere(EnumCreatureType creatureType, Biome.SpawnListEntry spawnListEntry, BlockPos pos) { + List list = this.getChunkProvider().getPossibleCreatures(creatureType, pos); ++ list = net.minecraftforge.event.ForgeEventFactory.getPotentialSpawns(this, creatureType, pos, list); + return list != null && !list.isEmpty() ? list.contains(spawnListEntry) : false; + } + +@@ -256,10 +272,7 @@ + } + + private void resetRainAndThunder() { +- this.worldInfo.setRainTime(0); +- this.worldInfo.setRaining(false); +- this.worldInfo.setThunderTime(0); +- this.worldInfo.setThundering(false); ++ this.provider.resetRainAndThunder(); + } + + public boolean areAllPlayersAsleep() { +@@ -346,7 +359,7 @@ + this.profiler.endStartSection("tickChunk"); + chunk.onTick(false); + this.profiler.endStartSection("thunder"); +- if (flag && flag1 && this.rand.nextInt(100000) == 0) { ++ if (this.provider.canDoLightning(chunk) && flag && flag1 && this.rand.nextInt(100000) == 0) { + this.updateLCG = this.updateLCG * 3 + 1013904223; + int l = this.updateLCG >> 2; + BlockPos blockpos = this.adjustPosToNearbyEntity(new BlockPos(j + (l & 15), 0, k + (l >> 8 & 15))); +@@ -366,12 +379,13 @@ + } + + this.profiler.endStartSection("iceandsnow"); +- if (this.rand.nextInt(16) == 0) { ++ if (this.provider.canDoRainSnowIce(chunk) && this.rand.nextInt(16) == 0) { + this.updateLCG = this.updateLCG * 3 + 1013904223; + int j2 = this.updateLCG >> 2; + BlockPos blockpos1 = this.func_205770_a(Heightmap.Type.MOTION_BLOCKING, new BlockPos(j + (j2 & 15), 0, k + (j2 >> 8 & 15))); + BlockPos blockpos2 = blockpos1.down(); + Biome biome = this.getBiome(blockpos1); ++ if (this.isAreaLoaded(blockpos2, 1, false)) // Forge: check area to avoid loading neighbors in unloaded chunks + if (biome.func_201848_a(this, blockpos2)) { + this.setBlockState(blockpos2, Blocks.ICE.getDefaultState()); + } +@@ -545,6 +559,11 @@ + } + + public boolean isBlockModifiable(EntityPlayer player, BlockPos pos) { ++ return super.isBlockModifiable(player, pos); ++ } ++ ++ public boolean canMineBlockBody(EntityPlayer player, BlockPos pos) ++ { + return !this.server.isBlockProtected(this, pos, player) && this.getWorldBorder().contains(pos); + } + +@@ -594,6 +613,7 @@ + } else if (this.worldInfo.getTerrainType() == WorldType.DEBUG_ALL_BLOCK_STATES) { + this.worldInfo.setSpawn(BlockPos.ORIGIN.up()); + } else { ++ if (net.minecraftforge.event.ForgeEventFactory.onCreateWorldSpawn(this, settings)) return; + BiomeProvider biomeprovider = this.chunkProvider.func_201711_g().func_202090_b(); + List list = biomeprovider.getBiomesToSpawnIn(); + Random random = new Random(this.getSeed()); +@@ -676,6 +696,7 @@ + progressCallback.func_200209_c(new TextComponentTranslation("menu.savingChunks", new Object[0])); + } + ++ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.world.WorldEvent.Save(this)); + chunkproviderserver.saveChunks(all); + + for(Chunk chunk : Lists.newArrayList(chunkproviderserver.getLoadedChunks())) { +@@ -715,6 +736,7 @@ + this.worldInfo.func_201356_c(this.server.func_201300_aS().func_201380_c()); + this.saveHandler.saveWorldInfoWithPlayer(this.worldInfo, this.server.getPlayerList().getHostPlayerData()); + this.mapStorage.saveAllData(); ++ this.perWorldStorage.saveAllData(); + } + + public boolean spawnEntity(Entity entityIn) { +@@ -723,7 +745,7 @@ + + public void loadEntities(Collection entityCollection) { + for(Entity entity : Lists.newArrayList(entityCollection)) { +- if (this.canAddEntity(entity)) { ++ if (this.canAddEntity(entity) && !net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.EntityJoinWorldEvent(entity, this))) { + this.loadedEntityList.add(entity); + this.onEntityAdded(entity); + } +@@ -785,7 +807,7 @@ + + public boolean addWeatherEffect(Entity entityIn) { + if (super.addWeatherEffect(entityIn)) { +- this.server.getPlayerList().sendToAllNearExcept((EntityPlayer)null, entityIn.posX, entityIn.posY, entityIn.posZ, 512.0D, this.provider.getDimensionType().getId(), new SPacketSpawnGlobalEntity(entityIn)); ++ this.server.getPlayerList().sendToAllNearExcept((EntityPlayer)null, entityIn.posX, entityIn.posY, entityIn.posZ, 512.0D, this.provider.getId(), new SPacketSpawnGlobalEntity(entityIn)); + return true; + } else { + return false; +@@ -802,6 +824,7 @@ + + public Explosion func_211529_a(@Nullable Entity p_211529_1_, DamageSource p_211529_2_, double p_211529_3_, double p_211529_5_, double p_211529_7_, float p_211529_9_, boolean p_211529_10_, boolean p_211529_11_) { + Explosion explosion = new Explosion(this, p_211529_1_, p_211529_3_, p_211529_5_, p_211529_7_, p_211529_9_, p_211529_10_, p_211529_11_); ++ if (net.minecraftforge.event.ForgeEventFactory.onExplosionStart(this, explosion)) return explosion; + if (p_211529_2_ != null) { + explosion.func_199592_a(p_211529_2_); + } +@@ -829,7 +852,7 @@ + while(!this.blockEventQueue.isEmpty()) { + BlockEventData blockeventdata = this.blockEventQueue.removeFirst(); + if (this.fireBlockEvent(blockeventdata)) { +- this.server.getPlayerList().sendToAllNearExcept((EntityPlayer)null, (double)blockeventdata.getPosition().getX(), (double)blockeventdata.getPosition().getY(), (double)blockeventdata.getPosition().getZ(), 64.0D, this.provider.getDimensionType().getId(), new SPacketBlockAction(blockeventdata.getPosition(), blockeventdata.getBlock(), blockeventdata.getEventID(), blockeventdata.getEventParameter())); ++ this.server.getPlayerList().sendToAllNearExcept((EntityPlayer)null, (double)blockeventdata.getPosition().getX(), (double)blockeventdata.getPosition().getY(), (double)blockeventdata.getPosition().getZ(), 64.0D, this.provider.getId(), new SPacketBlockAction(blockeventdata.getPosition(), blockeventdata.getBlock(), blockeventdata.getEventID(), blockeventdata.getEventParameter())); + } + } + +@@ -849,22 +872,26 @@ + boolean flag = this.isRaining(); + super.updateWeather(); + if (this.prevRainingStrength != this.rainingStrength) { +- this.server.getPlayerList().sendPacketToAllPlayersInDimension(new SPacketChangeGameState(7, this.rainingStrength), this.provider.getDimensionType().getId()); ++ this.server.getPlayerList().sendPacketToAllPlayersInDimension(new SPacketChangeGameState(7, this.rainingStrength), this.provider.getId()); + } + + if (this.prevThunderingStrength != this.thunderingStrength) { +- this.server.getPlayerList().sendPacketToAllPlayersInDimension(new SPacketChangeGameState(8, this.thunderingStrength), this.provider.getDimensionType().getId()); ++ this.server.getPlayerList().sendPacketToAllPlayersInDimension(new SPacketChangeGameState(8, this.thunderingStrength), this.provider.getId()); + } + ++ /* The function in use here has been replaced in order to only send the weather info to players in the correct dimension, ++ * rather than to all players on the server. This is what causes the client-side rain, as the ++ * client believes that it has started raining locally, rather than in another dimension. ++ */ + if (flag != this.isRaining()) { + if (flag) { +- this.server.getPlayerList().sendPacketToAllPlayers(new SPacketChangeGameState(2, 0.0F)); ++ this.server.getPlayerList().sendPacketToAllPlayersInDimension(new SPacketChangeGameState(2, 0.0F), this.provider.getId()); + } else { +- this.server.getPlayerList().sendPacketToAllPlayers(new SPacketChangeGameState(1, 0.0F)); ++ this.server.getPlayerList().sendPacketToAllPlayersInDimension(new SPacketChangeGameState(1, 0.0F), this.provider.getId()); + } + +- this.server.getPlayerList().sendPacketToAllPlayers(new SPacketChangeGameState(7, this.rainingStrength)); +- this.server.getPlayerList().sendPacketToAllPlayers(new SPacketChangeGameState(8, this.thunderingStrength)); ++ this.server.getPlayerList().sendPacketToAllPlayersInDimension(new SPacketChangeGameState(7, this.rainingStrength), this.provider.getId()); ++ this.server.getPlayerList().sendPacketToAllPlayersInDimension(new SPacketChangeGameState(8, this.thunderingStrength), this.provider.getId()); + } + + } +@@ -957,4 +984,12 @@ public NetworkTagManager func_205772_D() { return this.server.func_199731_aO(); } diff --git a/patches/minecraft/net/minecraft/world/dimension/Dimension.java.patch b/patches/minecraft/net/minecraft/world/dimension/Dimension.java.patch index 7f45a8ad41..d8178bd000 100644 --- a/patches/minecraft/net/minecraft/world/dimension/Dimension.java.patch +++ b/patches/minecraft/net/minecraft/world/dimension/Dimension.java.patch @@ -9,7 +9,7 @@ public static final float[] MOON_PHASE_FACTORS = new float[]{1.0F, 0.75F, 0.5F, 0.25F, 0.0F, 0.25F, 0.5F, 0.75F}; protected World world; protected boolean doesWaterVaporize; -@@ -141,4 +141,67 @@ +@@ -141,4 +141,76 @@ public abstract boolean doesXZShowFog(int x, int z); public abstract DimensionType getDimensionType(); @@ -75,5 +75,14 @@ + public void setWeatherRenderer(net.minecraftforge.client.IRenderHandler renderer) + { + weatherRenderer = renderer; ++ } ++ ++ @Override ++ public void resetRainAndThunder() ++ { ++ world.getWorldInfo().setRainTime(0); ++ world.getWorldInfo().setRaining(false); ++ world.getWorldInfo().setThunderTime(0); ++ world.getWorldInfo().setThundering(false); + } } diff --git a/src/main/java/net/minecraftforge/client/extensions/IForgeKeybinding.java b/src/main/java/net/minecraftforge/client/extensions/IForgeKeybinding.java new file mode 100644 index 0000000000..23fa526516 --- /dev/null +++ b/src/main/java/net/minecraftforge/client/extensions/IForgeKeybinding.java @@ -0,0 +1,53 @@ +package net.minecraftforge.client.extensions; + +import javax.annotation.Nonnull; + +import net.minecraft.client.settings.KeyBinding; +import net.minecraft.client.util.InputMappings; +import net.minecraftforge.client.settings.IKeyConflictContext; +import net.minecraftforge.client.settings.KeyModifier; + +public interface IForgeKeybinding +{ + default KeyBinding getKeyBinding() { return (KeyBinding) this; } + + @Nonnull InputMappings.Input getKey(); + + /** + * Checks that the key conflict context and modifier are active, and that the keyCode matches this binding. + */ + default boolean isActiveAndMatches(InputMappings.Input keyCode) + { + return keyCode.func_197937_c() != 0 && keyCode.equals(getKey()) && getKeyConflictContext().isActive() && getKeyModifier().isActive(getKeyConflictContext()); + } + + default void setToDefault() + { + setKeyModifierAndCode(getKeyModifierDefault(), getKeyBinding().func_197977_i()); + } + + void setKeyConflictContext(IKeyConflictContext keyConflictContext); + + IKeyConflictContext getKeyConflictContext(); + + KeyModifier getKeyModifierDefault(); + + KeyModifier getKeyModifier(); + + void setKeyModifierAndCode(KeyModifier keyModifier, InputMappings.Input keyCode); + + /** + * Returns true when one of the bindings' key codes conflicts with the other's modifier. + */ + default boolean hasKeyCodeModifierConflict(KeyBinding other) + { + if (getKeyConflictContext().conflicts(other.getKeyConflictContext()) || other.getKeyConflictContext().conflicts(getKeyConflictContext())) + { + if (getKeyModifier().matches(other.getKey()) || other.getKeyModifier().matches(getKey())) + { + return true; + } + } + return false; + } +} diff --git a/src/main/java/net/minecraftforge/client/settings/KeyBindingMap.java b/src/main/java/net/minecraftforge/client/settings/KeyBindingMap.java index 263da84e32..61751da9f7 100644 --- a/src/main/java/net/minecraftforge/client/settings/KeyBindingMap.java +++ b/src/main/java/net/minecraftforge/client/settings/KeyBindingMap.java @@ -20,27 +20,30 @@ package net.minecraftforge.client.settings; import net.minecraft.client.settings.KeyBinding; +import net.minecraft.client.util.InputMappings; import net.minecraft.util.IntHashMap; import javax.annotation.Nullable; import java.util.ArrayList; import java.util.Collection; import java.util.EnumMap; +import java.util.HashMap; import java.util.List; +import java.util.Map; public class KeyBindingMap { - private static final EnumMap>> map = new java.util.EnumMap>>(KeyModifier.class); + private static final EnumMap>> map = new EnumMap<>(KeyModifier.class); static { for (KeyModifier modifier : KeyModifier.values()) { - map.put(modifier, new IntHashMap>()); + map.put(modifier, new HashMap<>()); } } @Nullable - public KeyBinding lookupActive(int keyCode) + public KeyBinding lookupActive(InputMappings.Input keyCode) { KeyModifier activeModifier = KeyModifier.getActiveModifier(); if (!activeModifier.matches(keyCode)) @@ -55,9 +58,9 @@ public class KeyBindingMap } @Nullable - private KeyBinding getBinding(int keyCode, KeyModifier keyModifier) + private KeyBinding getBinding(InputMappings.Input keyCode, KeyModifier keyModifier) { - Collection bindings = map.get(keyModifier).lookup(keyCode); + Collection bindings = map.get(keyModifier).get(keyCode); if (bindings != null) { for (KeyBinding binding : bindings) @@ -71,12 +74,12 @@ public class KeyBindingMap return null; } - public List lookupAll(int keyCode) + public List lookupAll(InputMappings.Input keyCode) { List matchingBindings = new ArrayList(); - for (IntHashMap> bindingsMap : map.values()) + for (Map> bindingsMap : map.values()) { - Collection bindings = bindingsMap.lookup(keyCode); + Collection bindings = bindingsMap.get(keyCode); if (bindings != null) { matchingBindings.addAll(bindings); @@ -85,15 +88,15 @@ public class KeyBindingMap return matchingBindings; } - public void addKey(int keyCode, KeyBinding keyBinding) + public void addKey(InputMappings.Input keyCode, KeyBinding keyBinding) { KeyModifier keyModifier = keyBinding.getKeyModifier(); - IntHashMap> bindingsMap = map.get(keyModifier); - Collection bindingsForKey = bindingsMap.lookup(keyCode); + Map> bindingsMap = map.get(keyModifier); + Collection bindingsForKey = bindingsMap.get(keyCode); if (bindingsForKey == null) { bindingsForKey = new ArrayList(); - bindingsMap.addKey(keyCode, bindingsForKey); + bindingsMap.put(keyCode, bindingsForKey); } bindingsForKey.add(keyBinding); } @@ -101,24 +104,24 @@ public class KeyBindingMap public void removeKey(KeyBinding keyBinding) { KeyModifier keyModifier = keyBinding.getKeyModifier(); - int keyCode = keyBinding.getKeyCode(); - IntHashMap> bindingsMap = map.get(keyModifier); - Collection bindingsForKey = bindingsMap.lookup(keyCode); + InputMappings.Input keyCode = keyBinding.getKey(); + Map> bindingsMap = map.get(keyModifier); + Collection bindingsForKey = bindingsMap.get(keyCode); if (bindingsForKey != null) { bindingsForKey.remove(keyBinding); if (bindingsForKey.isEmpty()) { - bindingsMap.removeObject(keyCode); + bindingsMap.remove(keyCode); } } } public void clearMap() { - for (IntHashMap> bindings : map.values()) + for (Map> bindings : map.values()) { - bindings.clearMap(); + bindings.clear(); } } } diff --git a/src/main/java/net/minecraftforge/client/settings/KeyModifier.java b/src/main/java/net/minecraftforge/client/settings/KeyModifier.java index 6fa000e1e9..cb94fe1184 100644 --- a/src/main/java/net/minecraftforge/client/settings/KeyModifier.java +++ b/src/main/java/net/minecraftforge/client/settings/KeyModifier.java @@ -21,18 +21,19 @@ package net.minecraftforge.client.settings; import javax.annotation.Nullable; -import net.minecraft.client.GameSettings; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.resources.I18n; +import net.minecraft.client.util.InputMappings; import org.lwjgl.glfw.GLFW; public enum KeyModifier { CONTROL { @Override - public boolean matches(int keyCode) + public boolean matches(InputMappings.Input key) { + int keyCode = key.func_197937_c(); if (Minecraft.IS_RUNNING_ON_MAC) { return keyCode == GLFW.GLFW_KEY_LEFT_ALT || keyCode == GLFW.GLFW_KEY_RIGHT_ALT; @@ -56,18 +57,18 @@ public enum KeyModifier { } @Override - public String getLocalizedComboName(int keyCode) + public String getLocalizedComboName(InputMappings.Input key) { - String keyName = GLFW.glfwGetKeyName(keyCode, 0); + String keyName = key.func_197936_a(); String localizationFormatKey = Minecraft.IS_RUNNING_ON_MAC ? "forge.controlsgui.control.mac" : "forge.controlsgui.control"; return I18n.format(localizationFormatKey, keyName); } }, SHIFT { @Override - public boolean matches(int keyCode) + public boolean matches(InputMappings.Input key) { - return keyCode == GLFW.GLFW_KEY_LEFT_SHIFT || keyCode == GLFW.GLFW_KEY_RIGHT_SHIFT; + return key.func_197937_c() == GLFW.GLFW_KEY_LEFT_SHIFT || key.func_197937_c() == GLFW.GLFW_KEY_RIGHT_SHIFT; } @Override @@ -83,17 +84,16 @@ public enum KeyModifier { } @Override - public String getLocalizedComboName(int keyCode) + public String getLocalizedComboName(InputMappings.Input key) { - String keyName = GLFW.glfwGetKeyName(keyCode, 0); - return I18n.format("forge.controlsgui.shift", keyName); + return I18n.format("forge.controlsgui.shift", key.func_197936_a()); } }, ALT { @Override - public boolean matches(int keyCode) + public boolean matches(InputMappings.Input key) { - return keyCode == GLFW.GLFW_KEY_LEFT_ALT || keyCode == GLFW.GLFW_KEY_RIGHT_ALT; + return key.func_197937_c() == GLFW.GLFW_KEY_LEFT_ALT || key.func_197937_c() == GLFW.GLFW_KEY_RIGHT_ALT; } @Override @@ -109,15 +109,14 @@ public enum KeyModifier { } @Override - public String getLocalizedComboName(int keyCode) + public String getLocalizedComboName(InputMappings.Input keyCode) { - String keyName = GLFW.glfwGetKeyName(keyCode, 0); - return I18n.format("forge.controlsgui.alt", keyName); + return I18n.format("forge.controlsgui.alt", keyCode.func_197936_a()); } }, NONE { @Override - public boolean matches(int keyCode) + public boolean matches(InputMappings.Input key) { return false; } @@ -145,9 +144,9 @@ public enum KeyModifier { } @Override - public String getLocalizedComboName(int keyCode) + public String getLocalizedComboName(InputMappings.Input key) { - return GLFW.glfwGetKeyName(keyCode, 0); + return key.func_197936_a(); } }; @@ -165,11 +164,11 @@ public enum KeyModifier { return NONE; } - public static boolean isKeyCodeModifier(int keyCode) + public static boolean isKeyCodeModifier(InputMappings.Input key) { for (KeyModifier keyModifier : MODIFIER_VALUES) { - if (keyModifier.matches(keyCode)) + if (keyModifier.matches(key)) { return true; } @@ -189,7 +188,7 @@ public enum KeyModifier { } } - public abstract boolean matches(int keyCode); + public abstract boolean matches(InputMappings.Input key); /** * @deprecated use {@link #isActive(IKeyConflictContext)} @@ -199,5 +198,5 @@ public enum KeyModifier { public abstract boolean isActive(@Nullable IKeyConflictContext conflictContext); - public abstract String getLocalizedComboName(int keyCode); + public abstract String getLocalizedComboName(InputMappings.Input key); } diff --git a/src/main/java/net/minecraftforge/common/DimensionManager.java b/src/main/java/net/minecraftforge/common/DimensionManager.java index b62d5d43c5..1b02c79160 100644 --- a/src/main/java/net/minecraftforge/common/DimensionManager.java +++ b/src/main/java/net/minecraftforge/common/DimensionManager.java @@ -296,7 +296,7 @@ public class DimensionManager dimensions.get(id).ticksWaited = 0; } WorldServer ret = worlds.get(id); - if (ret != null && forceLoad) + if (ret == null && forceLoad) { initDimension(id); ret = worlds.get(id); diff --git a/src/main/java/net/minecraftforge/common/ForgeHooks.java b/src/main/java/net/minecraftforge/common/ForgeHooks.java index 53b2110c77..1dacef2634 100644 --- a/src/main/java/net/minecraftforge/common/ForgeHooks.java +++ b/src/main/java/net/minecraftforge/common/ForgeHooks.java @@ -295,20 +295,6 @@ public class ForgeHooks return ret; } - static - { - seedList.add(new SeedEntry(new ItemStack(Items.WHEAT_SEEDS), 10) - { - @Override - @Nonnull - public ItemStack getStack(Random rand, int fortune) - { - return new ItemStack(Items.WHEAT_SEEDS, 1 + rand.nextInt(fortune * 2 + 1)); - } - }); - initTools(); - } - /** * Called when a player uses 'pick block', calls new Entity and Block hooks. */ diff --git a/src/main/java/net/minecraftforge/common/crafting/CraftingHelper.java b/src/main/java/net/minecraftforge/common/crafting/CraftingHelper.java index af1ae1fba3..66e072318d 100644 --- a/src/main/java/net/minecraftforge/common/crafting/CraftingHelper.java +++ b/src/main/java/net/minecraftforge/common/crafting/CraftingHelper.java @@ -108,7 +108,7 @@ public class CraftingHelper public static final IConditionSerializer CONDITION_FALSE = condition("false", json -> () -> false); public static final IIngredientSerializer INGREDIENT_NBT = register(new ResourceLocation("forge", "nbt"), new IngredientNBT.Serializer()); - public static final IIngredientSerializer INGREDIENT_COMPOUND = register(new ResourceLocation("forge", "nbt"), new CompoundIngredient.Serializer()); + public static final IIngredientSerializer INGREDIENT_COMPOUND = register(new ResourceLocation("forge", "compound"), new CompoundIngredient.Serializer()); public static final IIngredientSerializer INGREDIENT_VANILLA = register(new ResourceLocation("minecraft", "item"), new IIngredientSerializer() { public Ingredient parse(PacketBuffer buffer) { return Ingredient.func_209357_a(Stream.generate(() -> new Ingredient.SingleItemList(buffer.readItemStack())).limit(buffer.readVarInt())); diff --git a/src/main/java/net/minecraftforge/common/extensions/IForgeDimension.java b/src/main/java/net/minecraftforge/common/extensions/IForgeDimension.java index 590e989115..f8bf39172f 100644 --- a/src/main/java/net/minecraftforge/common/extensions/IForgeDimension.java +++ b/src/main/java/net/minecraftforge/common/extensions/IForgeDimension.java @@ -30,7 +30,10 @@ import net.minecraftforge.client.IRenderHandler; public interface IForgeDimension { - default Dimension getDimension() { return (Dimension) this; } + default Dimension getDimension() + { + return (Dimension) this; + } /** * Called from {@link World#initCapabilities()}, to gather capabilities for this @@ -50,19 +53,21 @@ public interface IForgeDimension } /** - * The dimension's movement factor. - * Whenever a player or entity changes dimension from world A to world B, their coordinates are multiplied by + * The dimension's movement factor. Whenever a player or entity changes + * dimension from world A to world B, their coordinates are multiplied by * worldA.provider.getMovementFactor() / worldB.provider.getMovementFactor() - * Example: Overworld factor is 1, nether factor is 8. Traveling from overworld to nether multiplies coordinates by 1/8. + * Example: Overworld factor is 1, nether factor is 8. Traveling from overworld + * to nether multiplies coordinates by 1/8. + * * @return The movement factor */ default double getMovementFactor() { - if (getDimension() instanceof NetherDimension) - { - return 8.0; - } - return 1.0; + if (getDimension() instanceof NetherDimension) + { + return 8.0; + } + return 1.0; } /** @@ -96,4 +101,16 @@ public interface IForgeDimension @OnlyIn(Dist.CLIENT) void setWeatherRenderer(IRenderHandler renderer); + + void resetRainAndThunder(); + + default boolean canDoLightning(net.minecraft.world.chunk.Chunk chunk) + { + return true; + } + + default boolean canDoRainSnowIce(net.minecraft.world.chunk.Chunk chunk) + { + return true; + } } diff --git a/src/main/java/net/minecraftforge/common/extensions/IForgeFluidState.java b/src/main/java/net/minecraftforge/common/extensions/IForgeFluidState.java index 77d7b832b3..5c4a68ae06 100644 --- a/src/main/java/net/minecraftforge/common/extensions/IForgeFluidState.java +++ b/src/main/java/net/minecraftforge/common/extensions/IForgeFluidState.java @@ -47,7 +47,6 @@ public interface IForgeFluidState * @param material to test for. * @param testingHead when true, its testing the entities head for vision, breathing ect... otherwise its testing the body, for swimming and movement adjustment. */ - @Nullable default boolean isEntityInside(IWorldReader world, BlockPos pos, Entity entity, double yToTest, Tag tag, boolean testingHead) { return getFluidState().func_206886_c().isEntityInside(getFluidState(), world, pos, entity, yToTest, tag, testingHead); diff --git a/src/main/resources/assets/forge/lang/en_us.json b/src/main/resources/assets/forge/lang/en_us.json index e48c70a00b..f3d77939b1 100644 --- a/src/main/resources/assets/forge/lang/en_us.json +++ b/src/main/resources/assets/forge/lang/en_us.json @@ -64,6 +64,11 @@ "forge.configgui.alwaysSetupTerrainOffThread": "Force threaded chunk rendering", "forge.configgui.forgeLightPipelineEnabled": "Forge Light Pipeline Enabled", "forge.configgui.selectiveResourceReloadEnabled.tooltip": "When enabled, makes specific reload tasks such as language changing quicker to run.", - "forge.configgui.selectiveResourceReloadEnabled": "Enable Selective Resource Loading" + "forge.configgui.selectiveResourceReloadEnabled": "Enable Selective Resource Loading", + + "forge.controlsgui.shift": "SHIFT + %s", + "forge.controlsgui.control": "CTRL + %s", + "forge.controlsgui.control.mac": "CMD + %s", + "forge.controlsgui.alt": "ALT + %s" }