Fix the rest of the "easy" compile errors (#5151)

* Add Entity.changeDimension patch and transitively required patches

* Fix throws declaration on CommandSetDimension#execute

* Fix rest of errors in fluid package

* Add PLAYER_REACH attribute

* Fix compile errors in fml.client.config and add GuiButton patch

* Delete unnecessary client.config classes, fix all config errors

* Comment some fluid errors in models

* Fix all errors in common package root, except ForgeHooks

* Mass comment network package

* Experimental conversion of extended states to generic base class

* Fix errors in common.util

* Remove config annotation stuff cuz lex said so

* Make extended state stuff compile fully
This commit is contained in:
tterrag 2018-09-18 00:04:02 -04:00 committed by GitHub
parent 6814cbf0df
commit c4cf950863
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
72 changed files with 610 additions and 5996 deletions

View File

@ -0,0 +1,22 @@
--- a/net/minecraft/client/gui/GuiButton.java
+++ b/net/minecraft/client/gui/GuiButton.java
@@ -22,6 +22,7 @@
public boolean visible;
protected boolean hovered;
private boolean field_194832_o;
+ public int packedFGColor; // FML
public GuiButton(int buttonId, int x, int y, String buttonText) {
this(buttonId, x, y, 200, 20, buttonText);
@@ -66,6 +67,11 @@
this.drawTexturedModalRect(this.x + this.width / 2, this.y, 200 - this.width / 2, 46 + i * 20, this.width / 2, this.height);
this.mouseDragged(minecraft, p_194828_1_, p_194828_2_);
int j = 14737632;
+ if (packedFGColor != 0)
+ {
+ j = packedFGColor;
+ }
+ else
if (!this.enabled) {
j = 10526880;
} else if (this.hovered) {

View File

@ -26,3 +26,60 @@
}
public EntityType<?> func_200600_R() {
@@ -2053,6 +2056,14 @@
@Nullable
public Entity changeDimension(int dimensionIn) {
+ if (this.world.isRemote || this.isDead) return null;
+ return changeDimension(dimensionIn, this.getServer().getWorld(dimensionIn).getDefaultTeleporter());
+ }
+
+ @Nullable // Forge: Entities that require custom handling should override this method, not the other
+ public Entity changeDimension(int dimensionIn, net.minecraftforge.common.util.ITeleporter teleporter)
+ {
+ if (!net.minecraftforge.common.ForgeHooks.onTravelToDimension(this, dimensionIn)) return null;
if (!this.world.isRemote && !this.isDead) {
this.world.profiler.startSection("changeDimension");
MinecraftServer minecraftserver = this.getServer();
@@ -2060,7 +2071,7 @@
WorldServer worldserver = minecraftserver.getWorld(i);
WorldServer worldserver1 = minecraftserver.getWorld(dimensionIn);
this.dimension = dimensionIn;
- if (i == 1 && dimensionIn == 1) {
+ if (i == 1 && dimensionIn == 1 && teleporter.isVanilla()) {
worldserver1 = minecraftserver.func_200667_a(DimensionType.OVERWORLD);
this.dimension = 0;
}
@@ -2069,16 +2080,17 @@
this.isDead = false;
this.world.profiler.startSection("reposition");
BlockPos blockpos;
- if (dimensionIn == 1) {
+ if (dimensionIn == 1 && teleporter.isVanilla()) {
blockpos = worldserver1.getSpawnCoordinate();
} else {
- double d0 = this.posX;
- double d1 = this.posZ;
+ double moveFactor = worldserver.provider.getMovementFactor() / worldserver1.provider.getMovementFactor();
+ double d0 = MathHelper.clamp(this.posX * moveFactor, worldserver1.getWorldBorder().minX() + 16.0D, worldserver1.getWorldBorder().maxX() - 16.0D);
+ double d1 = MathHelper.clamp(this.posZ * moveFactor, worldserver1.getWorldBorder().minZ() + 16.0D, worldserver1.getWorldBorder().maxZ() - 16.0D);
double d2 = 8.0D;
- if (dimensionIn == -1) {
+ if (false && dimensionIn == -1) {
d0 = MathHelper.clamp(d0 / 8.0D, worldserver1.getWorldBorder().minX() + 16.0D, worldserver1.getWorldBorder().maxX() - 16.0D);
d1 = MathHelper.clamp(d1 / 8.0D, worldserver1.getWorldBorder().minZ() + 16.0D, worldserver1.getWorldBorder().maxZ() - 16.0D);
- } else if (dimensionIn == 0) {
+ } else if (false && dimensionIn == 0) {
d0 = MathHelper.clamp(d0 * 8.0D, worldserver1.getWorldBorder().minX() + 16.0D, worldserver1.getWorldBorder().maxX() - 16.0D);
d1 = MathHelper.clamp(d1 * 8.0D, worldserver1.getWorldBorder().minZ() + 16.0D, worldserver1.getWorldBorder().maxZ() - 16.0D);
}
@@ -2087,8 +2099,7 @@
d1 = (double)MathHelper.clamp((int)d1, -29999872, 29999872);
float f = this.rotationYaw;
this.setLocationAndAngles(d0, this.posY, d1, 90.0F, 0.0F);
- Teleporter teleporter = worldserver1.getDefaultTeleporter();
- teleporter.placeInExistingPortal(this, f);
+ teleporter.placeEntity(worldserver1, this, f);
blockpos = new BlockPos(this);
}

View File

@ -0,0 +1,11 @@
--- a/net/minecraft/entity/player/EntityPlayer.java
+++ b/net/minecraft/entity/player/EntityPlayer.java
@@ -97,6 +97,8 @@
import net.minecraftforge.api.distmarker.OnlyIn;
public abstract class EntityPlayer extends EntityLivingBase {
+ public static final net.minecraft.entity.ai.attributes.IAttribute REACH_DISTANCE = new net.minecraft.entity.ai.attributes.RangedAttribute(null, "generic.reachDistance", 5.0D, 0.0D, 1024.0D).setShouldWatch(true);
+
private static final DataParameter<Float> ABSORPTION = EntityDataManager.<Float>createKey(EntityPlayer.class, DataSerializers.FLOAT);
private static final DataParameter<Integer> PLAYER_SCORE = EntityDataManager.<Integer>createKey(EntityPlayer.class, DataSerializers.VARINT);
protected static final DataParameter<Byte> PLAYER_MODEL_FLAG = EntityDataManager.<Byte>createKey(EntityPlayer.class, DataSerializers.BYTE);

View File

@ -0,0 +1,11 @@
--- a/net/minecraft/item/ItemArmor.java
+++ b/net/minecraft/item/ItemArmor.java
@@ -105,4 +105,8 @@
public int func_200881_e() {
return this.damageReduceAmount;
}
+
+ public float getToughness() {
+ return this.toughness;
+ }
}

View File

@ -1,6 +1,34 @@
--- a/net/minecraft/server/MinecraftServer.java
+++ b/net/minecraft/server/MinecraftServer.java
@@ -523,6 +523,7 @@
@@ -130,7 +130,7 @@
private final DataFixer dataFixer;
private String hostname;
private int serverPort = -1;
- public WorldServer[] worlds;
+ public WorldServer[] worlds = new WorldServer[0];
private PlayerList playerList;
private boolean serverRunning = true;
private boolean serverStopped;
@@ -148,7 +148,8 @@
private int buildLimit;
private int maxPlayerIdleMinutes;
public final long[] tickTimeArray = new long[100];
- public long[][] timeOfLastDimensionTick;
+ //public long[][] timeOfLastDimensionTick;
+ public java.util.Hashtable<Integer, long[]> worldTickTimes = new java.util.Hashtable<Integer, long[]>();
private KeyPair serverKeyPair;
private String serverOwner;
private String folderName;
@@ -287,8 +288,6 @@
public void loadAllWorlds(String saveName, String worldNameIn, long seed, WorldType type, JsonElement generatorOptions) {
this.convertMapIfNeeded(saveName);
this.func_200245_b(new TextComponentTranslation("menu.loadingLevel", new Object[0]));
- this.worlds = new WorldServer[3];
- this.timeOfLastDimensionTick = new long[this.worlds.length][100];
ISaveHandler isavehandler = this.anvilConverterForAnvilFile.func_197715_a(saveName, this);
this.setResourcePackFromWorld(this.getFolderName(), isavehandler);
WorldInfo worldinfo = isavehandler.loadWorldInfo();
@@ -523,6 +522,7 @@
public void run() {
try {
if (this.init()) {
@ -8,7 +36,7 @@
this.field_211151_aa = Util.func_211177_b();
this.statusResponse.setServerDescription(new TextComponentString(this.motd));
this.statusResponse.setVersion(new ServerStatusResponse.Version("1.13", 393));
@@ -546,7 +547,10 @@
@@ -546,7 +546,10 @@
this.serverIsRunning = true;
}
@ -19,7 +47,7 @@
this.finalTick((CrashReport)null);
}
} catch (Throwable throwable1) {
@@ -565,6 +569,7 @@
@@ -565,6 +568,7 @@
LOGGER.error("We were unable to save this crash report to disk.");
}
@ -27,7 +55,7 @@
this.finalTick(crashreport);
} finally {
try {
@@ -573,6 +578,7 @@
@@ -573,6 +577,7 @@
} catch (Throwable throwable) {
LOGGER.error("Exception stopping the server", throwable);
} finally {
@ -35,3 +63,28 @@
this.systemExitNow();
}
@@ -686,10 +691,12 @@
this.getFunctionManager().update();
this.profiler.endStartSection("levels");
- for(int i = 0; i < this.worlds.length; ++i) {
+ Integer[] ids = net.minecraftforge.common.DimensionManager.getIDs(this.tickCounter % 200 == 0);
+ for(int x = 0; x < ids.length; ++x) {
+ int id = ids[x];
long j = Util.func_211178_c();
- if (i == 0 || this.getAllowNether()) {
- WorldServer worldserver = this.worlds[i];
+ if (id == 0 || this.getAllowNether()) {
+ WorldServer worldserver = net.minecraftforge.common.DimensionManager.getWorld(id);
this.profiler.func_194340_a(() -> {
return worldserver.getWorldInfo().getWorldName();
});
@@ -724,7 +731,7 @@
this.profiler.endSection();
}
- this.timeOfLastDimensionTick[i][this.tickCounter % 100] = Util.func_211178_c() - j;
+ worldTickTimes.get(id)[this.tickCounter % 100] = Util.func_211178_c() - j;
}
this.profiler.endStartSection("connection");

View File

@ -0,0 +1,25 @@
--- a/net/minecraft/world/Teleporter.java
+++ b/net/minecraft/world/Teleporter.java
@@ -15,7 +15,7 @@
import net.minecraft.util.math.ChunkPos;
import net.minecraft.util.math.MathHelper;
-public class Teleporter {
+public class Teleporter implements net.minecraftforge.common.util.ITeleporter {
private static final BlockPortal field_196236_a = (BlockPortal)Blocks.PORTAL;
protected final WorldServer world;
protected final Random random;
@@ -334,4 +334,13 @@
this.lastUpdateTime = lastUpdate;
}
}
+
+ @Override
+ public void placeEntity(World world, Entity entity, float yaw)
+ {
+ if (entity instanceof EntityPlayerMP)
+ placeInPortal(entity, yaw);
+ else
+ placeInExistingPortal(entity, yaw);
+ }
}

View File

@ -1,5 +1,14 @@
--- a/net/minecraft/world/WorldServer.java
+++ b/net/minecraft/world/WorldServer.java
@@ -85,7 +85,7 @@
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
-public class WorldServer extends World implements IThreadListener {
+public class WorldServer extends World implements IThreadListener, net.minecraftforge.common.extensions.IForgeWorldServer {
private static final Logger LOGGER = LogManager.getLogger();
private final MinecraftServer server;
private final EntityTracker entityTracker;
@@ -150,6 +150,7 @@
this.getWorldBorder().setTransition(this.worldInfo.getBorderSize());
}

View File

@ -0,0 +1,34 @@
--- a/net/minecraft/world/dimension/DimensionType.java
+++ b/net/minecraft/world/dimension/DimensionType.java
@@ -11,12 +11,19 @@
private final String name;
private final String suffix;
private final Supplier<? extends Dimension> field_201038_g;
+ private final boolean shouldLoadSpawn;
private DimensionType(int p_i48278_3_, String p_i48278_4_, String p_i48278_5_, Supplier<? extends Dimension> p_i48278_6_) {
+ this(p_i48278_3_, p_i48278_4_, p_i48278_5_, p_i48278_6_, p_i48278_3_ == 0);
+ }
+
+ private DimensionType(int p_i48278_3_, String p_i48278_4_, String p_i48278_5_, Supplier<? extends Dimension> p_i48278_6_, boolean shouldLoadSpawn)
+ {
this.id = p_i48278_3_;
this.name = p_i48278_4_;
this.suffix = p_i48278_5_;
this.field_201038_g = p_i48278_6_;
+ this.shouldLoadSpawn = shouldLoadSpawn;
}
public int getId() {
@@ -54,4 +61,11 @@
throw new IllegalArgumentException("Invalid dimension " + nameIn);
}
+
+ public boolean shouldLoadSpawn(){ return this.shouldLoadSpawn; }
+
+ public static DimensionType create(int id, String name, String suffix, Supplier<? extends Dimension> provider, boolean shouldLoadSpawn)
+ {
+ return null;
+ }
}

View File

@ -18,7 +18,7 @@
*/
package net.minecraftforge.client.gui;
/*
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
@ -93,6 +93,7 @@ import static net.minecraftforge.common.ForgeMod.VERSION_CHECK_CAT;
* ForgeChunkManager.syncConfigDefaults()
* ForgeChunkManager.loadConfiguration()
*/
/* TODO Config gui
public class ForgeGuiFactory implements IModGuiFactory
{
@Override
@ -125,10 +126,10 @@ public class ForgeGuiFactory implements IModGuiFactory
return list;
}
/**
*//**
* This custom list entry provides the General Settings entry on the Minecraft Forge Configuration screen.
* It extends the base Category entry class and defines the IConfigElement objects that will be used to build the child screen.
*/
*//*
public static class GeneralEntry extends CategoryEntry
{
public GeneralEntry(GuiConfig owningScreen, GuiConfigEntries owningEntryList, IConfigElement prop)
@ -149,10 +150,10 @@ public class ForgeGuiFactory implements IModGuiFactory
}
}
/**
*//**
* This custom list entry provides the Client only Settings entry on the Minecraft Forge Configuration screen.
* It extends the base Category entry class and defines the IConfigElement objects that will be used to build the child screen.
*/
*//*
public static class ClientEntry extends CategoryEntry
{
public ClientEntry(GuiConfig owningScreen, GuiConfigEntries owningEntryList, IConfigElement prop)
@ -173,10 +174,10 @@ public class ForgeGuiFactory implements IModGuiFactory
}
}
/**
*//**
* This custom list entry provides the Forge Chunk Manager Config entry on the Minecraft Forge Configuration screen.
* It extends the base Category entry class and defines the IConfigElement objects that will be used to build the child screen.
*/
*//*
public static class ChunkLoaderEntry extends CategoryEntry
{
public ChunkLoaderEntry(GuiConfig owningScreen, GuiConfigEntries owningEntryList, IConfigElement prop)
@ -203,10 +204,10 @@ public class ForgeGuiFactory implements IModGuiFactory
}
}
/**
*//**
* This custom list entry provides the Forge Version Checking Config entry on the Minecraft Forge Configuration screen.
* It extends the base Category entry class and defines the IConfigElement objects that will be used to build the child screen.
*/
*//*
public static class VersionCheckEntry extends CategoryEntry
{
public VersionCheckEntry(GuiConfig owningScreen, GuiConfigEntries owningEntryList, IConfigElement prop)
@ -225,13 +226,13 @@ public class ForgeGuiFactory implements IModGuiFactory
List<Property> props = new ArrayList<Property>();
// TODO
/*
for (ModContainer mod : ForgeVersion.gatherMods().keySet())
{
values.remove(mod.getModId());
props.add(ForgeMod.getConfig().get(VERSION_CHECK_CAT, mod.getModId(), true)); //Get or make the value in the config
}
*/
props.addAll(values.values()); // Add any left overs from the config
props.sort(Comparator.comparing(Property::getName));
@ -251,11 +252,11 @@ public class ForgeGuiFactory implements IModGuiFactory
}
}
/**
*//**
* This custom list entry provides the Mod Overrides entry on the Forge Chunk Loading config screen.
* It extends the base Category entry class and defines the IConfigElement objects that will be used to build the child screen.
* In this case it adds the custom entry for adding a new mod override and lists the existing mod overrides.
*/
*//*
public static class ModOverridesEntry extends CategoryEntry
{
public ModOverridesEntry(GuiConfig owningScreen, GuiConfigEntries owningEntryList, IConfigElement prop)
@ -263,9 +264,9 @@ public class ForgeGuiFactory implements IModGuiFactory
super(owningScreen, owningEntryList, prop);
}
/**
*//**
* This method is called in the constructor and is used to set the childScreen field.
*/
*//*
@Override
protected GuiScreen buildChildScreen()
{
@ -282,10 +283,10 @@ public class ForgeGuiFactory implements IModGuiFactory
I18n.format("forge.configgui.ctgy.forgeChunkLoadingModConfig"));
}
/**
*//**
* By overriding the enabled() method and checking the value of the "enabled" entry this entry is enabled/disabled based on the value of
* the other entry.
*/
*//*
@Override
public boolean enabled()
{
@ -300,9 +301,9 @@ public class ForgeGuiFactory implements IModGuiFactory
return true;
}
/**
*//**
* Check to see if the child screen's entry list has changed.
*/
*//*
@Override
public boolean isChanged()
{
@ -314,10 +315,10 @@ public class ForgeGuiFactory implements IModGuiFactory
return false;
}
/**
*//**
* Since adding a new entry to the child screen is what constitutes a change here, reset the child
* screen listEntries to the saved list.
*/
*//*
@Override
public void undoChanges()
{
@ -333,9 +334,9 @@ public class ForgeGuiFactory implements IModGuiFactory
}
}
/**
*//**
* This custom list entry provides a button that will open to a screen that will allow a user to define a new mod override.
*/
*//*
public static class AddModOverrideEntry extends CategoryEntry
{
public AddModOverrideEntry(GuiConfig owningScreen, GuiConfigEntries owningEntryList, IConfigElement prop)
@ -365,10 +366,10 @@ public class ForgeGuiFactory implements IModGuiFactory
}
}
/**
*//**
* This custom list entry provides a Mod ID selector. The control is a button that opens a list of values to select from.
* This entry also overrides onGuiClosed() to run code to save the data to a new ConfigCategory when the user is done.
*/
*//*
public static class ModIDEntry extends SelectValueEntry
{
public ModIDEntry(GuiConfig owningScreen, GuiConfigEntries owningEntryList, IConfigElement prop)
@ -382,21 +383,21 @@ public class ForgeGuiFactory implements IModGuiFactory
{
Map<Object, String> selectableValues = new TreeMap<Object, String>();
// TODO
/*
for (ModContainer mod : Loader.instance().getActiveModList())
// only add mods to the list that have a non-immutable ModContainer
if (!mod.isImmutable() && mod.getMod() != null)
selectableValues.put(mod.getModId(), mod.getName());
*/
return selectableValues;
}
/**
*//**
* By overriding onGuiClosed() for this entry we can perform additional actions when the user is done such as saving
* a new ConfigCategory object to the Configuration object.
*/
*//*
@Override
public void onGuiClosed()
{
@ -437,4 +438,4 @@ public class ForgeGuiFactory implements IModGuiFactory
}
}
}
}
}*/

View File

@ -198,7 +198,7 @@ public final class ModelDynBucket implements IUnbakedModel
public ModelDynBucket process(ImmutableMap<String, String> customData)
{
String fluidName = customData.get("fluid");
Fluid fluid = FluidRegistry.getFluid(fluidName);
Fluid fluid = null; // TODO fluids FluidRegistry.getFluid(fluidName);
if (fluid == null) fluid = this.fluid;

View File

@ -49,7 +49,6 @@ import net.minecraftforge.common.ForgeVersion;
import net.minecraftforge.common.model.IModelState;
import net.minecraftforge.common.model.TRSRTransformation;
import net.minecraftforge.common.property.IExtendedBlockState;
import net.minecraftforge.fluids.BlockFluidBase;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidRegistry;
@ -69,8 +68,8 @@ import com.google.gson.JsonParser;
public final class ModelFluid implements IUnbakedModel
{
private static final Logger LOGGER = LogManager.getLogger();
public static final ModelFluid WATER = new ModelFluid(FluidRegistry.WATER);
public static final ModelFluid LAVA = new ModelFluid(FluidRegistry.LAVA);
public static final ModelFluid WATER = null; // TODO fluids new ModelFluid(FluidRegistry.WATER);
public static final ModelFluid LAVA = null; // TODO fluids new ModelFluid(FluidRegistry.LAVA);
private final Fluid fluid;
@ -180,7 +179,7 @@ public final class ModelFluid implements IUnbakedModel
IExtendedBlockState state = stateOption.get();
for (int i = 0; i < 4; i++)
{
Float level = state.getValue(BlockFluidBase.LEVEL_CORNERS[i]);
Float level = null; // TODO fluids state.getValue(BlockFluidBase.LEVEL_CORNERS[i]);
cornerRound[i] = Math.round((level == null ? 8f / 9f : level) * 864);
}
}
@ -199,7 +198,7 @@ public final class ModelFluid implements IUnbakedModel
Float flow = -1000f;
if (stateOption.isPresent())
{
flow = stateOption.get().getValue(BlockFluidBase.FLOW_DIRECTION);
flow = null; // TODO fluids stateOption.get().getValue(BlockFluidBase.FLOW_DIRECTION);
if (flow == null) flow = -1000f;
}
int flowRound = (int) Math.round(Math.toDegrees(flow));
@ -222,7 +221,7 @@ public final class ModelFluid implements IUnbakedModel
IExtendedBlockState state = stateOption.get();
for (int i = 0; i < 4; i++)
{
Boolean overlay = state.getValue(BlockFluidBase.SIDE_OVERLAYS[i]);
Boolean overlay = null; // TODO fluids state.getValue(BlockFluidBase.SIDE_OVERLAYS[i]);
if (overlay != null) overlaySides[i] = overlay;
}
}
@ -510,12 +509,13 @@ public final class ModelFluid implements IUnbakedModel
String fluidStr = customData.get("fluid");
JsonElement e = new JsonParser().parse(fluidStr);
String fluid = e.getAsString();
String fluid = e.getAsString();/* TODO fluids
if(!FluidRegistry.isFluidRegistered(fluid))
{
LOGGER.fatal("fluid '{}' not found", fluid);
return WATER;
}
return new ModelFluid(FluidRegistry.getFluid(fluid));
return new ModelFluid(FluidRegistry.getFluid(fluid));*/
return this;
}
}

View File

@ -523,7 +523,7 @@ public final class ModelLoader extends ModelBakery
if(exState.getUnlistedNames().contains(Properties.AnimationProperty))
{
IModelState newState = exState.getValue(Properties.AnimationProperty);
IExtendedBlockState newExState = exState.withProperty(Properties.AnimationProperty, null);
IExtendedBlockState newExState = (IExtendedBlockState) exState.withProperty(Properties.AnimationProperty, null);
if(newState != null)
{
return VanillaModelWrapper.this.bake(modelGetter, bakedTextureGetter, new ModelStateComposition(modelState, newState), uvlock, format).func_200117_a(newExState, side, rand);

View File

@ -77,7 +77,7 @@ public class AnimationTESR<T extends TileEntity> extends FastTESR<T> implements
// TODO: caching?
IBakedModel model = blockRenderer.getBlockModelShapes().getModelForState(exState.getClean());
IExtendedBlockState animState = exState.withProperty(Properties.AnimationProperty, pair.getLeft());
IExtendedBlockState animState = (IExtendedBlockState) exState.withProperty(Properties.AnimationProperty, pair.getLeft());
renderer.setTranslation(x - pos.getX(), y - pos.getY(), z - pos.getZ());

View File

@ -67,7 +67,6 @@ import net.minecraftforge.common.model.TRSRTransformation;
import net.minecraftforge.common.model.animation.IClip;
import net.minecraftforge.common.model.animation.IJoint;
import net.minecraftforge.common.property.IExtendedBlockState;
import net.minecraftforge.common.property.IUnlistedProperty;
import net.minecraftforge.common.property.Properties;
import org.apache.commons.io.IOUtils;
@ -81,7 +80,6 @@ import com.google.common.base.Objects;
import java.util.Optional;
import java.util.Random;
import com.google.common.base.Predicate;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;

View File

@ -411,7 +411,7 @@ public class DimensionManager
finally
{
MinecraftForge.EVENT_BUS.post(new WorldEvent.Unload(w));
w.flush();
w.close();
setWorld(id, null, w.getMinecraftServer());
}
}

View File

@ -56,6 +56,7 @@ import net.minecraftforge.common.config.Property;
import net.minecraftforge.common.util.Constants;
import net.minecraftforge.fml.server.ServerLifecycleHooks;
import net.minecraftforge.fml.ModContainer;
import net.minecraftforge.fml.ModList;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
@ -505,7 +506,7 @@ public class ForgeChunkManager
String modId = ticketHolder.getString("Owner");
boolean isPlayer = ForgeVersion.MOD_ID.equals(modId);
if (!isPlayer && !Loader.isModLoaded(modId))
if (!isPlayer && !ModList.get().isLoaded(modId))
{
LOGGER.warn(CHUNK_MANAGER, "Found chunkloading data for mod {} which is currently not available or active - it will be removed from the world save", modId);
continue;
@ -678,7 +679,7 @@ public class ForgeChunkManager
private static ModContainer getContainer(Object mod)
{
ModContainer container = Loader.instance().getModObjectList().inverse().get(mod);
ModContainer container = ModList.get().getModContainerByObject(mod).orElse(null);
return container;
}
@ -1036,7 +1037,7 @@ public class ForgeChunkManager
NBTTagList tileEntities = nbt.getTagList("TileEntities", Constants.NBT.TAG_COMPOUND);
for (int i = 0; i < tileEntities.size(); ++i)
{
TileEntity tileEntity = TileEntity.create(world, tileEntities.getCompoundTagAt(i));
TileEntity tileEntity = TileEntity.func_203403_c(tileEntities.getCompoundTagAt(i));
if (tileEntity != null) chunk.addTileEntity(tileEntity);
}
}

View File

@ -77,6 +77,7 @@ import net.minecraft.item.ItemMonsterPlacer;
import net.minecraft.item.ItemPickaxe;
import net.minecraft.item.ItemPotion;
import net.minecraft.item.ItemSpade;
import net.minecraft.item.ItemSpawnEgg;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemTippedArrow;
import net.minecraft.item.ItemUseContext;
@ -120,6 +121,7 @@ import net.minecraft.world.storage.loot.LootEntry;
import net.minecraft.world.storage.loot.LootTable;
import net.minecraft.world.storage.loot.LootTableManager;
import net.minecraft.world.storage.loot.conditions.LootCondition;
import net.minecraftforge.common.crafting.CraftingHelper;
import net.minecraftforge.common.util.BlockSnapshot;
import net.minecraftforge.event.AnvilUpdateEvent;
import net.minecraftforge.event.DifficultyChangeEvent;
@ -1283,21 +1285,6 @@ public class ForgeHooks
MinecraftForge.EVENT_BUS.post(new BlockEvent.CropGrowEvent.Post(worldIn, pos, state, worldIn.getBlockState(pos)));
}
private static final ClassValue<String> registryNames = new ClassValue<String>()
{
@Override
@SuppressWarnings("unchecked")
protected String computeValue(Class<?> type)
{
return String.valueOf(TileEntity.getKey((Class<? extends TileEntity>) type));
}
};
public static String getRegistryName(Class<? extends TileEntity> type)
{
return registryNames.get(type);
}
public static boolean loadAdvancements(Map<ResourceLocation, Advancement.Builder> map)
{
boolean errored = false;
@ -1370,7 +1357,7 @@ public class ForgeHooks
true, true
);
}
/* TODO this should be unnecessary now?
public static void sendRecipeBook(NetHandlerPlayServer connection, State state, List<IRecipe> recipes, List<IRecipe> display, boolean isGuiOpen, boolean isFilteringCraftable)
{
NetworkDispatcher disp = NetworkDispatcher.get(connection.getNetworkManager());
@ -1386,7 +1373,7 @@ public class ForgeHooks
if (!recipes.isEmpty() || !display.isEmpty())
connection.sendPacket(new SPacketRecipeBook(state, recipes, display, isGuiOpen, isFilteringCraftable));
}
*/
public static void onAdvancement(EntityPlayerMP player, Advancement advancement)
{
MinecraftForge.EVENT_BUS.post(new AdvancementEvent(player, advancement));
@ -1406,7 +1393,7 @@ public class ForgeHooks
if (item instanceof ItemEnchantedBook)
{
NBTTagList enchantmentsNbt = ItemEnchantedBook.getEnchantments(itemStack);
if (enchantmentsNbt.tagCount() == 1)
if (enchantmentsNbt.size() == 1)
{
NBTTagCompound nbttagcompound = enchantmentsNbt.getCompoundTagAt(0);
Enchantment enchantment = Enchantment.getEnchantmentByID(nbttagcompound.getShort("id"));
@ -1429,9 +1416,9 @@ public class ForgeHooks
return resourceLocation.getNamespace();
}
}
else if (item instanceof ItemMonsterPlacer)
else if (item instanceof ItemSpawnEgg)
{
ResourceLocation resourceLocation = ItemMonsterPlacer.getNamedIdFrom(itemStack);
ResourceLocation resourceLocation = ((ItemSpawnEgg)item).func_208076_b(null).getRegistryName();
if (resourceLocation != null)
{
return resourceLocation.getNamespace();

View File

@ -428,7 +428,7 @@ public class ForgeMod implements WorldPersistenceHooks.WorldPersistenceHook
NBTTagCompound forgeData = new NBTTagCompound();
NBTTagCompound dimData = DimensionManager.saveDimensionDataMap();
forgeData.setTag("DimensionData", dimData);
FluidRegistry.writeDefaultFluidList(forgeData);
// TODO fluids FluidRegistry.writeDefaultFluidList(forgeData);
return forgeData;
}
@ -436,7 +436,7 @@ public class ForgeMod implements WorldPersistenceHooks.WorldPersistenceHook
public void readData(SaveHandler handler, WorldInfo info, NBTTagCompound tag)
{
DimensionManager.loadDimensionDataMap(tag.hasKey("DimensionData") ? tag.getCompoundTag("DimensionData") : null);
FluidRegistry.loadFluidDefaults(tag);
// TODO fluids FluidRegistry.loadFluidDefaults(tag);
}
public void mappingChanged(FMLModIdMappingEvent evt)

View File

@ -169,8 +169,8 @@ public interface ISpecialArmor
{
ItemArmor armor = (ItemArmor)stack.getItem();
prop = new ArmorProperties(0, 0, Integer.MAX_VALUE);
prop.Armor = armor.damageReduceAmount;
prop.Toughness = armor.toughness;
prop.Armor = armor.func_200881_e();
prop.Toughness = armor.getToughness();
}
if (prop != null)
{

View File

@ -85,7 +85,7 @@ public class MinecraftForge
UsernameCache.load();
// Load before all the mods, so MC owns the MC fluids
FluidRegistry.validateFluidRegistry();
// TODO Fluids FluidRegistry.validateFluidRegistry();
ForgeHooks.initTools();
//For all the normal CrashReport classes to be defined. We're in MC's classloader so this should all be fine

View File

@ -34,6 +34,7 @@ import net.minecraft.world.dimension.Dimension;
import net.minecraft.world.gen.feature.template.TemplateManager;
import net.minecraft.world.storage.IPlayerFileData;
import net.minecraft.world.storage.ISaveHandler;
import net.minecraft.world.storage.SessionLockException;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.storage.WorldInfo;
import net.minecraft.world.WorldServer;
@ -55,7 +56,7 @@ public class WorldSpecificSaveHandler implements ISaveHandler
}
@Override public WorldInfo loadWorldInfo() { return parent.loadWorldInfo(); }
@Override public void checkSessionLock() throws MinecraftException { parent.checkSessionLock(); }
@Override public void checkSessionLock() throws SessionLockException { parent.checkSessionLock(); }
@Override public IChunkLoader getChunkLoader(Dimension var1) { return parent.getChunkLoader(var1); }
@Override public void saveWorldInfoWithPlayer(WorldInfo var1, NBTTagCompound var2) { parent.saveWorldInfoWithPlayer(var1, var2); }
@Override public void saveWorldInfo(WorldInfo var1){ parent.saveWorldInfo(var1); }

View File

@ -37,7 +37,7 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import net.minecraftforge.fml.client.config.GuiConfigEntries.IConfigEntry;
import net.minecraftforge.fml.client.config.IConfigEntry;
public class ConfigCategory implements Map<String, Property>
{

View File

@ -30,8 +30,8 @@ import com.google.common.collect.Lists;
import net.minecraftforge.fml.client.config.ConfigGuiType;
import net.minecraftforge.fml.client.config.DummyConfigElement.DummyCategoryElement;
import net.minecraftforge.fml.client.config.GuiConfigEntries.IConfigEntry;
import net.minecraftforge.fml.client.config.GuiEditArrayEntries.IArrayEntry;
import net.minecraftforge.fml.client.config.IConfigEntry;
import net.minecraftforge.fml.client.config.IArrayEntry;
import net.minecraftforge.fml.client.config.IConfigElement;
/**
@ -360,59 +360,4 @@ public class ConfigElement implements IConfigElement
{
return isProperty ? prop.getMaxValue() : null;
}
/**
* Provides a ConfigElement derived from the annotation-based config system
* @param configClass the class which contains the configuration
* @return A ConfigElement based on the described category.
*/
public static IConfigElement from(Class<?> configClass)
{
Config annotation = configClass.getAnnotation(Config.class);
if (annotation == null)
throw new RuntimeException(String.format("The class '%s' has no @Config annotation!", configClass.getName()));
Configuration config = ConfigManager.getConfiguration(annotation.modid(), annotation.name());
if (config == null)
{
String error = String.format("The configuration '%s' of mod '%s' isn't loaded with the ConfigManager!", annotation.name(), annotation.modid());
throw new RuntimeException(error);
}
String name = Strings.isNullOrEmpty(annotation.name()) ? annotation.modid() : annotation.name();
String langKey = name;
Config.LangKey langKeyAnnotation = configClass.getAnnotation(Config.LangKey.class);
if (langKeyAnnotation != null)
{
langKey = langKeyAnnotation.value();
}
if (annotation.category().isEmpty())
{
List<IConfigElement> elements = Lists.newArrayList();
Set<String> catNames = config.getCategoryNames();
for (String catName : catNames)
{
if (catName.isEmpty())
continue;
ConfigCategory category = config.getCategory(catName);
if (category.isChild())
continue;
DummyCategoryElement element = new DummyCategoryElement(category.getName(), category.getLanguagekey(), new ConfigElement(category).getChildElements());
element.setRequiresMcRestart(category.requiresMcRestart());
element.setRequiresWorldRestart(category.requiresWorldRestart());
elements.add(element);
}
return new DummyCategoryElement(name, langKey, elements);
}
else
{
ConfigCategory category = config.getCategory(annotation.category());
DummyCategoryElement element = new DummyCategoryElement(name, langKey, new ConfigElement(category).getChildElements());
element.setRequiresMcRestart(category.requiresMcRestart());
element.setRequiresWorldRestart(category.requiresWorldRestart());
return element;
}
}
}

View File

@ -1,383 +0,0 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2018.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.common.config;
import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import com.google.common.base.Joiner;
import com.google.common.base.Strings;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import com.google.common.collect.Sets;
import net.minecraftforge.common.config.Config.Comment;
import net.minecraftforge.common.config.Config.LangKey;
import net.minecraftforge.common.config.Config.Name;
import net.minecraftforge.fml.common.FMLPaths;
import net.minecraftforge.fml.common.Loader;
import net.minecraftforge.fml.common.LoaderException;
import net.minecraftforge.fml.loading.moddiscovery.ModAnnotation.EnumHolder;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class ConfigManager
{
private static final Logger LOGGER = LogManager.getLogger();
private static Map<String, Multimap<Config.Type, ASMData>> asm_data = Maps.newHashMap();
static Map<Class<?>, ITypeAdapter> ADAPTERS = Maps.newHashMap();
static Map<Class<?>, Class<?>> ARRAY_REMAP = Maps.newHashMap();
private static Map<String, Configuration> CONFIGS = Maps.newHashMap();
private static Map<String, Set<Class<?>>> MOD_CONFIG_CLASSES = Maps.newHashMap();
static
{
register(boolean.class, TypeAdapters.bool);
register(boolean[].class, TypeAdapters.boolA);
register(Boolean.class, TypeAdapters.Bool);
register(Boolean[].class, TypeAdapters.BoolA);
register(float.class, TypeAdapters.flt);
register(float[].class, TypeAdapters.fltA);
register(Float.class, TypeAdapters.Flt);
register(Float[].class, TypeAdapters.FltA);
register(double.class, TypeAdapters.dbl);
register(double[].class, TypeAdapters.dblA);
register(Double.class, TypeAdapters.Dbl);
register(Double[].class, TypeAdapters.DblA);
register(byte.class, TypeAdapters.byt);
register(byte[].class, TypeAdapters.bytA);
register(Byte.class, TypeAdapters.Byt);
register(Byte[].class, TypeAdapters.BytA);
register(char.class, TypeAdapters.chr);
register(char[].class, TypeAdapters.chrA);
register(Character.class, TypeAdapters.Chr);
register(Character[].class, TypeAdapters.ChrA);
register(short.class, TypeAdapters.shrt);
register(short[].class, TypeAdapters.shrtA);
register(Short.class, TypeAdapters.Shrt);
register(Short[].class, TypeAdapters.ShrtA);
register(int.class, TypeAdapters.int_);
register(int[].class, TypeAdapters.intA);
register(Integer.class, TypeAdapters.Int);
register(Integer[].class, TypeAdapters.IntA);
register(String.class, TypeAdapters.Str);
register(String[].class, TypeAdapters.StrA);
ARRAY_REMAP.put(Boolean.class, Boolean[].class );
ARRAY_REMAP.put(Float.class, Float[].class );
ARRAY_REMAP.put(Double.class, Double[].class );
ARRAY_REMAP.put(Byte.class, Byte[].class );
ARRAY_REMAP.put(Character.class, Character[].class);
ARRAY_REMAP.put(Short.class, Short[].class );
ARRAY_REMAP.put(Integer.class, Integer[].class );
ARRAY_REMAP.put(String.class, String[].class );
}
private static void register(Class<?> cls, ITypeAdapter adpt)
{
ADAPTERS.put(cls, adpt);
}
public static void loadData(ASMDataTable data)
{
LOGGER.debug("Loading @Config anotation data");
for (ASMData target : data.getAll(Config.class.getName()))
{
String modid = (String)target.getAnnotationInfo().get("modid");
Multimap<Config.Type, ASMData> map = asm_data.computeIfAbsent(modid, k -> ArrayListMultimap.create());
EnumHolder tholder = (EnumHolder)target.getAnnotationInfo().get("type");
Config.Type type = tholder == null ? Config.Type.INSTANCE : Config.Type.valueOf(tholder.getValue());
map.put(type, target);
}
}
/**
* Bounces to sync().
* TODO: remove
*/
public static void load(String modid, Config.Type type)
{
sync(modid, type);
}
/**
* Synchronizes configuration data between the file on disk, the {@code Configuration} object and the annotated
* mod classes containing the configuration variables.
*
* When first called, this method will try to load the configuration from disk. If this fails, because the file
* does not exist, it will be created with default values derived from the mods config classes variable default values
* and comments and ranges, as well as configuration names based on the appropriate annotations found in {@code @Config}.
*
* Note, that this method is being called by the {@link FMLModContaier}, so the mod needn't call it in init().
*
* If this method is called after the initial load, it will check whether the values in the Configuration object differ
* from the values in the corresponding variables. If they differ, it will either overwrite the variables if the Configuration
* object is marked as changed (e.g. if it was changed with the ConfigGui) or otherwise overwrite the Configuration object's values.
* It then proceeds to saving the changes to disk.
* @param modid the mod's ID for which the configuration shall be loaded
* @param type the configuration type, currently always {@code Config.Type.INSTANCE}
*/
public static void sync(String modid, Config.Type type)
{
LOGGER.debug("Attempting to inject @Config classes into {} for type {}", modid, type);
ClassLoader mcl = Loader.instance().getModClassLoader();
File configDir = FMLPaths.FMLCONFIG.get().toFile();
Multimap<Config.Type, ASMData> map = asm_data.get(modid);
if (map == null)
return;
for (ASMData targ : map.get(type))
{
try
{
Class<?> cls = Class.forName(targ.getClassName(), true, mcl);
Set<Class<?>> modConfigClasses = MOD_CONFIG_CLASSES.computeIfAbsent(modid, k -> Sets.<Class<?>>newHashSet());
modConfigClasses.add(cls);
String name = (String)targ.getAnnotationInfo().get("name");
if (name == null)
name = modid;
String category = (String)targ.getAnnotationInfo().get("category");
if (category == null)
category = "general";
File file = new File(configDir, name + ".cfg");
boolean loading = false;
Configuration cfg = CONFIGS.get(file.getAbsolutePath());
if (cfg == null)
{
cfg = new Configuration(file);
cfg.load();
CONFIGS.put(file.getAbsolutePath(), cfg);
loading = true;
}
sync(cfg, cls, modid, category, loading, null);
cfg.save();
}
catch (Exception e)
{
LOGGER.error("An error occurred trying to load a config for {} into {}", targ.getClassName(), e);
throw new LoaderException(e);
}
}
}
public static Class<?>[] getModConfigClasses(String modid)
{
return (MOD_CONFIG_CLASSES.containsKey(modid) ? MOD_CONFIG_CLASSES.get(modid).toArray(new Class<?>[0]) : new Class<?>[0]);
}
public static boolean hasConfigForMod(String modid)
{
return asm_data.containsKey(modid);
}
// =======================================================
// INTERNAL
// =======================================================
static Configuration getConfiguration(String modid, String name) {
if (Strings.isNullOrEmpty(name))
name = modid;
File configDir = FMLPaths.FMLCONFIG.get().toFile();
File configFile = new File(configDir, name + ".cfg");
return CONFIGS.get(configFile.getAbsolutePath());
}
private static void sync(Configuration cfg, Class<?> cls, String modid, String category, boolean loading, Object instance)
{
for (Field f : cls.getDeclaredFields())
{
if (!Modifier.isPublic(f.getModifiers()))
continue;
//Only the root class may have static fields. Otherwise category tree nodes of the same type would share the
//contained value messing up the sync
if (Modifier.isStatic(f.getModifiers()) != (instance == null))
continue;
if (f.isAnnotationPresent(Config.Ignore.class))
continue;
String comment = null;
Comment ca = f.getAnnotation(Comment.class);
if (ca != null)
comment = NEW_LINE.join(ca.value());
String langKey = modid + "." + (category.isEmpty() ? "" : category + Configuration.CATEGORY_SPLITTER) + f.getName().toLowerCase(Locale.ENGLISH);
LangKey la = f.getAnnotation(LangKey.class);
if (la != null)
langKey = la.value();
boolean requiresMcRestart = f.isAnnotationPresent(Config.RequiresMcRestart.class);
boolean requiresWorldRestart = f.isAnnotationPresent(Config.RequiresWorldRestart.class);
if (FieldWrapper.hasWrapperFor(f)) //Wrappers exist for primitives, enums, maps and arrays
{
if (Strings.isNullOrEmpty(category))
throw new RuntimeException("An empty category may not contain anything but objects representing categories!");
try
{
IFieldWrapper wrapper = FieldWrapper.get(instance, f, category);
ITypeAdapter adapt = wrapper.getTypeAdapter();
Property.Type propType = adapt.getType();
for (String key : wrapper.getKeys()) //Iterate the fully qualified property names the field provides
{
String suffix = StringUtils.replaceOnce(key, wrapper.getCategory() + Configuration.CATEGORY_SPLITTER, "");
boolean existed = exists(cfg, wrapper.getCategory(), suffix);
if (!existed || loading) //Creates keys in category specified by the wrapper if new ones are programaticaly added
{
Property property = property(cfg, wrapper.getCategory(), suffix, propType, adapt.isArrayAdapter());
adapt.setDefaultValue(property, wrapper.getValue(key));
if (!existed)
adapt.setValue(property, wrapper.getValue(key));
else
wrapper.setValue(key, adapt.getValue(property));
}
else //If the key is not new, sync according to shouldReadFromVar()
{
Property property = property(cfg, wrapper.getCategory(), suffix, propType, adapt.isArrayAdapter());
Object propVal = adapt.getValue(property);
Object mapVal = wrapper.getValue(key);
if (shouldReadFromVar(property, propVal, mapVal))
adapt.setValue(property, mapVal);
else
wrapper.setValue(key, propVal);
}
}
ConfigCategory confCat = cfg.getCategory(wrapper.getCategory());
for (Property property : confCat.getOrderedValues()) //Iterate the properties to check for new data from the config side
{
String key = confCat.getQualifiedName() + Configuration.CATEGORY_SPLITTER + property.getName();
if (!wrapper.handlesKey(key))
continue;
if (loading || !wrapper.hasKey(key))
{
Object value = wrapper.getTypeAdapter().getValue(property);
wrapper.setValue(key, value);
}
}
if (loading)
wrapper.setupConfiguration(cfg, comment, langKey, requiresMcRestart, requiresWorldRestart);
}
catch (Exception e)
{
String format = "Error syncing field '%s' of class '%s'!";
String error = String.format(format, f.getName(), cls.getName());
throw new RuntimeException(error, e);
}
}
else if (f.getType().getSuperclass() != null && f.getType().getSuperclass().equals(Object.class))
{ //If the field extends Object directly, descend the object tree and access the objects members
Object newInstance = null;
try
{
newInstance = f.get(instance);
}
catch (IllegalAccessException e)
{
throw new RuntimeException(e);
}
//Setup the sub category with its respective name, comment, language key, etc.
String sub = (category.isEmpty() ? "" : category + Configuration.CATEGORY_SPLITTER) + getName(f).toLowerCase(Locale.ENGLISH);
ConfigCategory confCat = cfg.getCategory(sub);
confCat.setComment(comment);
confCat.setLanguageKey(langKey);
confCat.setRequiresMcRestart(requiresMcRestart);
confCat.setRequiresWorldRestart(requiresWorldRestart);
sync(cfg, f.getType(), modid, sub, loading, newInstance);
}
else
{
String format = "Can't handle field '%s' of class '%s': Unknown type.";
String error = String.format(format, f.getName(), cls.getCanonicalName());
throw new RuntimeException(error);
}
}
}
static final Joiner NEW_LINE = Joiner.on('\n');
static final Joiner PIPE = Joiner.on('|');
private static Property property(Configuration cfg, String category, String property, Property.Type type, boolean isList)
{
Property prop = cfg.getCategory(category).get(property);
if (prop == null)
{
if (isList)
prop = new Property(property, new String[0], type);
else
prop = new Property(property, (String)null, type);
cfg.getCategory(category).put(property, prop);
}
return prop;
}
private static boolean exists(Configuration cfg, String category, String property)
{
return cfg.hasCategory(category) && cfg.getCategory(category).containsKey(property);
}
private static boolean shouldReadFromVar(Property property, Object propValue, Object fieldValue)
{
if (!propValue.equals(fieldValue))
{
if (property.hasChanged())
return false;
else
return true;
}
return false;
}
private static String getName(Field f)
{
if (f.isAnnotationPresent(Name.class))
return f.getAnnotation(Name.class).value();
return f.getName();
}
}

View File

@ -51,12 +51,7 @@ import com.google.common.base.CharMatcher;
import com.google.common.collect.ImmutableSet;
import com.google.common.primitives.Floats;
import net.minecraftforge.fml.client.config.GuiConfig;
import net.minecraftforge.fml.client.config.GuiConfigEntries;
import net.minecraftforge.fml.client.config.GuiConfigEntries.IConfigEntry;
import net.minecraftforge.fml.client.config.IConfigElement;
import net.minecraftforge.fml.common.FMLPaths;
import net.minecraftforge.fml.common.Loader;
import org.apache.commons.io.IOUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@ -112,7 +107,7 @@ public class Configuration
/**
* Create a configuration file for the file given in parameter with the provided config version number.
*/
* /
private void runConfiguration(File file, String configVersion)
{
this.file = file;
@ -143,16 +138,16 @@ public class Configuration
}
}
}
*/
public Configuration(File file, String configVersion)
{
runConfiguration(file, configVersion);
// runConfiguration(file, configVersion);
}
public Configuration(File file, String configVersion, boolean caseSensitiveCustomCategories)
{
this.caseSensitiveCustomCategories = caseSensitiveCustomCategories;
runConfiguration(file, configVersion);
// runConfiguration(file, configVersion);
}
public Configuration(File file, boolean caseSensitiveCustomCategories)
@ -1233,13 +1228,13 @@ public class Configuration
* @see GuiConfigEntries.BooleanEntry
* @see GuiConfigEntries.DoubleEntry
* @see GuiConfigEntries.IntegerEntry
*/
* /
public Configuration setCategoryConfigEntryClass(String category, Class<? extends IConfigEntry> clazz)
{
getCategory(category).setConfigEntryClass(clazz);
return this;
}
*/
/**
* Sets the flag for whether or not this category can be edited while a world is running. Care should be taken to ensure
* that only properties that are truly dynamic can be changed from the in-game options menu. Only set this flag to

View File

@ -1,432 +0,0 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2018.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.common.config;
import java.lang.reflect.Field;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.*;
import java.util.Map.Entry;
import java.util.regex.Pattern;
import com.google.common.collect.Lists;
import net.minecraftforge.common.config.Config.RangeDouble;
import net.minecraftforge.common.config.Config.RangeInt;
import org.apache.commons.lang3.StringUtils;
import static net.minecraftforge.common.config.ConfigManager.*;
public abstract class FieldWrapper implements IFieldWrapper
{
protected String category, name;
protected Field field;
protected Object instance;
public FieldWrapper(String category, Field field, Object instance)
{
this.instance = instance;
this.field = field;
this.category = category;
this.name = field.getName();
if (field.isAnnotationPresent(Config.Name.class))
this.name = field.getAnnotation(Config.Name.class).value();
this.field.setAccessible(true); // Just in case
}
public static IFieldWrapper get(Object instance, Field field, String category)
{
if (ADAPTERS.get(field.getType()) != null)
return new PrimitiveWrapper(category, field, instance);
else if (Enum.class.isAssignableFrom(field.getType()))
return new EnumWrapper(category, field, instance);
else if (Map.class.isAssignableFrom(field.getType()))
return new MapWrapper(category, field, instance);
else if (field.getType().getSuperclass().equals(Object.class))
throw new RuntimeException("Objects should not be handled by field wrappers");
else
throw new IllegalArgumentException(String.format("Fields of type '%s' are not supported!", field.getType().getCanonicalName()));
}
public static boolean hasWrapperFor(Field field)
{
if (ADAPTERS.get(field.getType()) != null)
return true;
else if (Enum.class.isAssignableFrom(field.getType()))
return true;
else if (Map.class.isAssignableFrom(field.getType()))
return true;
return false;
}
private static class MapWrapper extends FieldWrapper
{
private Map<String, Object> theMap = null;
private Type mType;
private final String baseName;
ITypeAdapter adapter;
@SuppressWarnings("unchecked")
private MapWrapper(String category, Field field, Object instance)
{
super(category, field, instance);
this.baseName = (this.category == null) ? "" : (this.category + ".") + this.name.toLowerCase(Locale.ENGLISH) + ".";
try
{
theMap = (Map<String, Object>) field.get(instance);
}
catch (ClassCastException cce)
{
throw new IllegalArgumentException(String.format("The map '%s' of class '%s' must have the key type String!", field.getName(),
field.getDeclaringClass().getCanonicalName()), cce);
}
catch (IllegalAccessException e)
{
throw new RuntimeException(e);
}
ParameterizedType type = (ParameterizedType) field.getGenericType();
mType = type.getActualTypeArguments()[1];
this.adapter = ADAPTERS.get(mType);
if (this.adapter == null && mType instanceof GenericArrayType)
{
this.adapter = ADAPTERS.get(ARRAY_REMAP.get(((GenericArrayType)mType).getGenericComponentType())); //J6 seems to have issues, Need to find a better way to translate this. We don't have access to array depth.
}
if (mType instanceof Class && Enum.class.isAssignableFrom((Class<?>)mType))
{
this.adapter = TypeAdapters.Str;
}
if (this.adapter == null)
throw new IllegalArgumentException(String.format("The map '%s' of class '%s' has target values which are neither primitive nor an enum!",
field.getName(), field.getDeclaringClass().getCanonicalName()));
}
@Override
public ITypeAdapter getTypeAdapter()
{
return adapter;
}
@Override
public String[] getKeys()
{
Set<String> keys = theMap.keySet();
String[] keyArray = new String[keys.size()];
Iterator<String> it = keys.iterator();
for (int i = 0; i < keyArray.length; i++)
{
keyArray[i] = this.baseName + it.next();
}
return keyArray;
}
@Override
public Object getValue(String key)
{
return theMap.get(getSuffix(key));
}
@Override
public void setValue(String key, Object value)
{
theMap.put(getSuffix(key), value);
}
@Override
public boolean hasKey(String key)
{
return theMap.containsKey(getSuffix(key));
}
@Override
public boolean handlesKey(String key)
{
if (key == null)
return false;
return key.startsWith(this.baseName);
}
@Override
public void setupConfiguration(Configuration cfg, String desc, String langKey, boolean reqMCRestart, boolean reqWorldRestart)
{
ConfigCategory confCat = cfg.getCategory(getCategory());
confCat.setComment(desc);
confCat.setLanguageKey(langKey);
confCat.setRequiresMcRestart(reqMCRestart);
confCat.setRequiresWorldRestart(reqWorldRestart);
}
@Override
public String getCategory()
{
return (this.category == null) ? "" : (this.category + ".") + this.name.toLowerCase(Locale.ENGLISH);
}
/**
* Removes the {@code this.baseName} prefix from the key
* @param key the key to be edited
* @return the keys suffix
*/
private String getSuffix(String key)
{
return StringUtils.replaceOnce(key, this.baseName, "");
}
}
private static class EnumWrapper extends SingleValueFieldWrapper
{
private EnumWrapper(String category, Field field, Object instance)
{
super(category, field, instance);
}
@Override
public ITypeAdapter getTypeAdapter()
{
return TypeAdapters.Str;
}
@Override
public Object getValue(String key)
{
if (!hasKey(key))
throw new IllegalArgumentException("Unsupported Key!");
try
{
@SuppressWarnings("rawtypes")
Enum enu = (Enum) field.get(instance);
return enu.name();
}
catch (IllegalAccessException e)
{
throw new RuntimeException(e);
}
}
@Override
public void setValue(String key, Object value)
{
if (!hasKey(key))
throw new IllegalArgumentException("Unsupported Key!");
@SuppressWarnings({ "unchecked", "rawtypes" })
Enum enu = Enum.valueOf((Class<? extends Enum>) field.getType(), (String) value);
try
{
field.set(instance, enu);
}
catch (IllegalAccessException e)
{
throw new RuntimeException(e);
}
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public void setupConfiguration(Configuration cfg, String desc, String langKey, boolean reqMCRestart, boolean reqWorldRestart)
{
super.setupConfiguration(cfg, desc, langKey, reqMCRestart, reqWorldRestart);
Property prop = cfg.getCategory(this.category).get(this.name); // Will be setup in general by ConfigManager
List<String> lst = Lists.newArrayList();
for (Enum e : ((Class<? extends Enum>) field.getType()).getEnumConstants())
lst.add(e.name());
prop.setValidationPattern(Pattern.compile(PIPE.join(lst)));
prop.setValidValues(lst.toArray(new String[0]));
String validValues = NEW_LINE.join(lst);
if (desc != null)
prop.setComment(NEW_LINE.join(new String[] { desc, "Valid values:" }) + "\n" + validValues);
else
prop.setComment("Valid values:" + "\n" + validValues);
}
}
private static class PrimitiveWrapper extends SingleValueFieldWrapper
{
private PrimitiveWrapper(String category, Field field, Object instance)
{
super(category, field, instance);
}
@Override
public ITypeAdapter getTypeAdapter()
{
return ADAPTERS.get(field.getType());
}
@Override
public Object getValue(String key)
{
if (!hasKey(key))
throw new IllegalArgumentException("Unknown key!");
try
{
return field.get(instance);
}
catch (IllegalAccessException e)
{
throw new RuntimeException(e);
}
}
@Override
public void setValue(String key, Object value)
{
if (!hasKey(key))
throw new IllegalArgumentException("Unknown key: " + key);
try
{
field.set(instance, value);
}
catch (IllegalAccessException e)
{
throw new RuntimeException(e);
}
}
@Override
public void setupConfiguration(Configuration cfg, String desc, String langKey, boolean reqMCRestart, boolean reqWorldRestart)
{
super.setupConfiguration(cfg, desc, langKey, reqMCRestart, reqWorldRestart);
Property prop = cfg.getCategory(this.category).get(this.name);
RangeInt ia = field.getAnnotation(RangeInt.class);
if (ia != null)
{
prop.setMinValue(ia.min());
prop.setMaxValue(ia.max());
if (desc != null)
prop.setComment(NEW_LINE.join(new String[] { desc, "Min: " + ia.min(), "Max: " + ia.max() }));
else
prop.setComment(NEW_LINE.join(new String[] { "Min: " + ia.min(), "Max: " + ia.max() }));
}
RangeDouble da = field.getAnnotation(RangeDouble.class);
if (da != null)
{
prop.setMinValue(da.min());
prop.setMaxValue(da.max());
if (desc != null)
prop.setComment(NEW_LINE.join(new String[] { desc, "Min: " + da.min(), "Max: " + da.max() }));
else
prop.setComment(NEW_LINE.join(new String[] { "Min: " + da.min(), "Max: " + da.max() }));
}
}
}
private static abstract class SingleValueFieldWrapper extends FieldWrapper
{
private SingleValueFieldWrapper(String category, Field field, Object instance)
{
super(category, field, instance);
}
@Override
public String[] getKeys()
{
return asArray(this.category + "." + this.name);
}
@Override
public boolean hasKey(String key)
{
return (this.category + "." + this.name).equals(key);
}
@Override
public boolean handlesKey(String key)
{
return hasKey(key);
}
@Override
public void setupConfiguration(Configuration cfg, String desc, String langKey, boolean reqMCRestart, boolean reqWorldRestart)
{
Property prop = cfg.getCategory(this.category).get(this.name); // Will be setup in general by ConfigManager
prop.setComment(desc);
prop.setLanguageKey(langKey);
prop.setRequiresMcRestart(reqMCRestart);
prop.setRequiresWorldRestart(reqWorldRestart);
}
@Override
public String getCategory()
{
return this.category;
}
}
private static <T> T[] asArray(T... in)
{
return in;
}
public static class BeanEntry<K, V> implements Entry<K, V>
{
private K key;
private V value;
public BeanEntry(K key, V value)
{
this.key = key;
this.value = value;
}
@Override
public K getKey()
{
return key;
}
@Override
public V getValue()
{
return value;
}
@Override
public V setValue(V value)
{
throw new UnsupportedOperationException("This is a static bean.");
}
}
}

View File

@ -1,78 +0,0 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2018.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.common.config;
/**
* The objects are expected to get their wrapped field, the owning class, instance and category string on initialization.
* In general: The key is the fully qualified property name, where each subcategory is appended with a dot.
* i.e: general.map.isPresent
*/
public interface IFieldWrapper
{
/**
* @return The type adapter to serialize the values returned by getValue. Null if non-primitive.
*/
ITypeAdapter getTypeAdapter();
/**
* @return a list of fully qualified property keys handled by this field
*/
String[] getKeys();
/**
* @param key the fully qualified property key
* @return the value the wrapped field associates with the given key
*/
Object getValue(String key);
/**
* @param key the fully qualified property key
* @param value the target value of the property associated with the key
*/
void setValue(String key, Object value);
/**
* @param key a fully qualified property key
* @return true if the wrapped field contains a property associated with the given key
*/
boolean hasKey(String key);
/**
* @param key a fully qualified property key
* @return true if the wrapped field can save information associated with the given key, false otherwise
*/
boolean handlesKey(String key);
/**
* @param cfg The configuration object holding the properties
* @param desc The properties description
* @param langKey The languageKey of the property, used in GUI
* @param reqMCRestart True, if a change in this property requires a restart of Minecraft
* @param reqWorldRestart True, if the world needs to be reloaded after changes to this property
*/
void setupConfiguration(Configuration cfg, String desc, String langKey, boolean reqMCRestart, boolean reqWorldRestart);
/**
* i.e. general.map in the example above
* @return the category name in which the entries should be saved. This includes the parent categories
*/
String getCategory();
}

View File

@ -1,53 +0,0 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2018.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.common.config;
import net.minecraftforge.common.config.Property.Type;
/**
* Abstracts the types of properties away. Higher level logic must prevent invalid data types.
*/
interface ITypeAdapter
{
/**
* Assigns the default value to the property
* @param property the property whose default value will be assigned
* @param value the default value
*/
void setDefaultValue(Property property, Object value);
/**
* Sets the properties value.
* @param property the property whose value will be set
* @param value the set value
*/
void setValue(Property property, Object value);
/**
* Retrieves the properties value
* @param prop the property whose value will be retrieved
* @return the properties value
*/
Object getValue(Property prop);
Type getType();
boolean isArrayAdapter();
}

View File

@ -23,13 +23,9 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.regex.Pattern;
import net.minecraftforge.fml.client.config.GuiConfig;
import net.minecraftforge.fml.client.config.GuiConfigEntries;
import net.minecraftforge.fml.client.config.GuiConfigEntries.IConfigEntry;
import net.minecraftforge.fml.client.config.GuiEditArray;
import net.minecraftforge.fml.client.config.GuiEditArrayEntries;
import net.minecraftforge.fml.client.config.GuiEditArrayEntries.IArrayEntry;
import net.minecraftforge.fml.client.config.IArrayEntry;
import net.minecraftforge.fml.client.config.IConfigElement;
import net.minecraftforge.fml.client.config.IConfigEntry;
public class Property
{

View File

@ -1,869 +0,0 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2018.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.common.config;
//=========================================================
// Run away thar' be dragons!
//=========================================================
import java.util.Arrays;
import com.google.common.primitives.Booleans;
import com.google.common.primitives.Bytes;
import com.google.common.primitives.Doubles;
import com.google.common.primitives.Floats;
import com.google.common.primitives.Ints;
import com.google.common.primitives.Shorts;
import net.minecraftforge.common.config.Property.Type;
class TypeAdapters
{
/*
* boolean, boolean[], Boolean, Boolean[]
* float, float[], Float, Float[]
* double, double[], Double, Double[]
* byte, byte[], Byte, Byte[]
* char, char[], Character, Character[]
* short, short[], Short, Short[]
* int, int[], Integer, Integer[]
* String, String[]
*/
static ITypeAdapter bool = new ITypeAdapter() {
@Override
public Object getValue(Property prop) {
return prop.getBoolean();
}
@Override
public void setDefaultValue(Property property, Object value)
{
property.setDefaultValue((Boolean)value);
}
@Override
public void setValue(Property property, Object value)
{
property.setValue((Boolean)value);
}
@Override
public Type getType()
{
return Type.BOOLEAN;
}
@Override
public boolean isArrayAdapter()
{
return false;
}
};
static ITypeAdapter boolA = new ITypeAdapter() {
@Override
public Object getValue(Property prop) {
return prop.getBooleanList();
}
@Override
public void setDefaultValue(Property property, Object value)
{
property.setDefaultValues((boolean[])value);
}
@Override
public void setValue(Property property, Object value)
{
property.setValues((boolean[])value);
}
@Override
public Type getType()
{
return Type.BOOLEAN;
}
@Override
public boolean isArrayAdapter()
{
return true;
}
};
static ITypeAdapter Bool = new ITypeAdapter() {
@Override
public Object getValue(Property prop) {
return Boolean.valueOf(prop.getBoolean());
}
@Override
public void setDefaultValue(Property property, Object value)
{
property.setDefaultValue((Boolean)value);
}
@Override
public void setValue(Property property, Object value)
{
property.setValue((Boolean)value);
}
@Override
public Type getType()
{
return Type.BOOLEAN;
}
@Override
public boolean isArrayAdapter()
{
return false;
}
};
static ITypeAdapter BoolA = new ITypeAdapter() {
@Override
public Object getValue(Property prop) {
return Booleans.asList(prop.getBooleanList()).toArray(new Boolean[prop.getBooleanList().length]);
}
@Override
public void setDefaultValue(Property property, Object value)
{
property.setDefaultValues(Booleans.toArray(Arrays.asList((Boolean[]) value)));
}
@Override
public void setValue(Property property, Object value)
{
property.setValues(Booleans.toArray(Arrays.asList((Boolean[]) value)));
}
@Override
public Type getType()
{
return Type.BOOLEAN;
}
@Override
public boolean isArrayAdapter()
{
return true;
}
};
static ITypeAdapter flt = new ITypeAdapter() {
@Override
public Object getValue(Property prop) {
return (float)prop.getDouble();
}
@Override
public void setDefaultValue(Property property, Object value)
{
property.setDefaultValue((Float)value);
}
@Override
public void setValue(Property property, Object value)
{
property.setValue((Float)value);
}
@Override
public Type getType()
{
return Type.DOUBLE;
}
@Override
public boolean isArrayAdapter()
{
return false;
}
};
static ITypeAdapter fltA = new ITypeAdapter() {
@Override
public Object getValue(Property prop) {
return Floats.toArray(Doubles.asList(prop.getDoubleList()));
}
@Override
public void setDefaultValue(Property property, Object value)
{
property.setDefaultValues(Doubles.toArray(Floats.asList((float[])value)));
}
@Override
public void setValue(Property property, Object value)
{
property.setValues(Doubles.toArray(Floats.asList((float[])value)));
}
@Override
public Type getType()
{
return Type.DOUBLE;
}
@Override
public boolean isArrayAdapter()
{
return true;
}
};
static ITypeAdapter Flt = new ITypeAdapter() {
@Override
public Object getValue(Property prop) {
return Float.valueOf((float)prop.getDouble());
}
@Override
public void setDefaultValue(Property property, Object value)
{
property.setDefaultValue((Float)value);
}
@Override
public void setValue(Property property, Object value)
{
property.setValue((Float)value);
}
@Override
public Type getType()
{
return Type.DOUBLE;
}
@Override
public boolean isArrayAdapter()
{
return false;
}
};
static ITypeAdapter FltA = new ITypeAdapter() {
@Override
public Object getValue(Property prop) {
return Floats.asList(Floats.toArray(Doubles.asList(prop.getDoubleList()))).toArray(new Float[prop.getDoubleList().length]);
}
@Override
public void setDefaultValue(Property property, Object value)
{
property.setDefaultValues(Doubles.toArray(Arrays.asList((Float[])value)));
}
@Override
public void setValue(Property property, Object value)
{
property.setValues(Doubles.toArray(Arrays.asList((Float[])value)));
}
@Override
public Type getType()
{
return Type.DOUBLE;
}
@Override
public boolean isArrayAdapter()
{
return true;
}
};
static ITypeAdapter dbl = new ITypeAdapter() {
@Override
public Object getValue(Property prop)
{
return prop.getDouble();
}
@Override
public void setDefaultValue(Property property, Object value)
{
property.setDefaultValue((Double)value);
}
@Override
public void setValue(Property property, Object value)
{
property.setValue((Double)value);
}
@Override
public Type getType()
{
return Type.DOUBLE;
}
@Override
public boolean isArrayAdapter()
{
return false;
}
};
static ITypeAdapter dblA = new ITypeAdapter() {
@Override
public Object getValue(Property prop) {
return prop.getDoubleList();
}
@Override
public void setDefaultValue(Property property, Object value)
{
property.setDefaultValues((double[])value);
}
@Override
public void setValue(Property property, Object value)
{
property.setValues((double[])value);
}
@Override
public Type getType()
{
return Type.DOUBLE;
}
@Override
public boolean isArrayAdapter()
{
return true;
}
};
static ITypeAdapter Dbl = new ITypeAdapter() {
@Override
public Object getValue(Property prop) {
return Double.valueOf(prop.getDouble());
}
@Override
public void setDefaultValue(Property property, Object value)
{
property.setDefaultValue((Double)value);
}
@Override
public void setValue(Property property, Object value)
{
property.setValue((Double) value);
}
@Override
public Type getType()
{
return Type.DOUBLE;
}
@Override
public boolean isArrayAdapter()
{
return false;
}
};
static ITypeAdapter DblA = new ITypeAdapter() {
@Override
public Object getValue(Property prop) {
return Doubles.asList(prop.getDoubleList()).toArray(new Double[prop.getDoubleList().length]);
}
@Override
public void setDefaultValue(Property property, Object value)
{
property.setDefaultValues(Doubles.toArray(Arrays.asList((Double[])value)));
}
@Override
public void setValue(Property property, Object value)
{
property.setValues(Doubles.toArray(Arrays.asList((Double[])value)));
}
@Override
public Type getType()
{
return Type.DOUBLE;
}
@Override
public boolean isArrayAdapter()
{
return true;
}
};
static ITypeAdapter byt = new ITypeAdapter() {
@Override
public Object getValue(Property prop)
{
return (byte)prop.getInt();
}
@Override
public void setDefaultValue(Property property, Object value)
{
property.setDefaultValue((Byte)value);
}
@Override
public void setValue(Property property, Object value)
{
property.setValue((Byte)value);
}
@Override
public Type getType()
{
return Type.INTEGER;
}
@Override
public boolean isArrayAdapter()
{
return false;
}
};
static ITypeAdapter bytA = new ITypeAdapter() {
@Override
public Object getValue(Property prop) {
return Bytes.toArray(Ints.asList(prop.getIntList()));
}
@Override
public void setDefaultValue(Property property, Object value)
{
property.setDefaultValues(Ints.toArray(Bytes.asList((byte[])value)));
}
@Override
public void setValue(Property property, Object value)
{
property.setValues(Ints.toArray(Bytes.asList((byte[])value)));
}
@Override
public Type getType()
{
return Type.INTEGER;
}
@Override
public boolean isArrayAdapter()
{
return true;
}
};
static ITypeAdapter Byt = new ITypeAdapter() {
@Override
public Object getValue(Property prop) {
return Byte.valueOf((byte)prop.getInt());
}
@Override
public void setDefaultValue(Property property, Object value)
{
property.setDefaultValue((Byte)value);
}
@Override
public void setValue(Property property, Object value)
{
property.setValue((Byte)value);
}
@Override
public Type getType()
{
return Type.INTEGER;
}
@Override
public boolean isArrayAdapter()
{
return false;
}
};
static ITypeAdapter BytA = new ITypeAdapter() {
@Override
public Object getValue(Property prop) {
return Bytes.asList(Bytes.toArray(Ints.asList(prop.getIntList()))).toArray(new Byte[prop.getIntList().length]);
}
@Override
public void setDefaultValue(Property property, Object value)
{
property.setDefaultValues(Ints.toArray(Arrays.asList((Byte[]) value)));
}
@Override
public void setValue(Property property, Object value)
{
property.setValues(Ints.toArray(Arrays.asList((Byte[]) value)));
}
@Override
public Type getType()
{
return Type.INTEGER;
}
@Override
public boolean isArrayAdapter()
{
return true;
}
};
static ITypeAdapter chr = new ITypeAdapter() {
@Override
public Object getValue(Property prop) {
return (char)prop.getInt();
}
@Override
public void setDefaultValue(Property property, Object value)
{
property.setDefaultValue((Character)value);
}
@Override
public void setValue(Property property, Object value)
{
property.setValue((Character)value);
}
@Override
public Type getType()
{
return Type.INTEGER;
}
@Override
public boolean isArrayAdapter()
{
return false;
}
};
static ITypeAdapter chrA = new ITypeAdapter() {
private int[] toPrim(char[] v) {
if (v == null) return new int[0];
int[] ret = new int[v.length];
for (int x = 0; x < v.length; x++)
ret[x] = v[x];
return ret;
}
@Override
public Object getValue(Property prop) {
int[] v = prop.getIntList();
char[] ret = new char[v.length];
for (int x = 0; x < v.length; x++)
ret[x] = (char)v[x];
return ret;
}
@Override
public void setDefaultValue(Property property, Object value)
{
property.setDefaultValues(toPrim((char[])value));
}
@Override
public void setValue(Property property, Object value)
{
property.setValues(toPrim((char[])value));
}
@Override
public Type getType()
{
return Type.INTEGER;
}
@Override
public boolean isArrayAdapter()
{
return true;
}
};
static ITypeAdapter Chr = new ITypeAdapter() {
@Override
public Object getValue(Property prop) {
return Character.valueOf((char)prop.getInt());
}
@Override
public void setDefaultValue(Property property, Object value)
{
property.setDefaultValue((Character)value);
}
@Override
public void setValue(Property property, Object value)
{
property.setValue((Character)value);
}
@Override
public Type getType()
{
return Type.INTEGER;
}
@Override
public boolean isArrayAdapter()
{
return false;
}
};
static ITypeAdapter ChrA = new ITypeAdapter() {
private int[] toPrim(Character[] v) {
if (v == null) return new int[0];
int[] ret = new int[v.length];
for (int x = 0; x < v.length; x++)
ret[x] = v[x] == null ? 0 : v[x];
return ret;
}
@Override
public Object getValue(Property prop) {
int[] v = prop.getIntList();
Character[] ret = new Character[v.length];
for (int x = 0; x < v.length; x++)
ret[x] = Character.valueOf((char)v[x]);
return ret;
}
@Override
public void setDefaultValue(Property property, Object value)
{
property.setDefaultValues(toPrim((Character[])value));
}
@Override
public void setValue(Property property, Object value)
{
property.setValues(toPrim((Character[]) value));
}
@Override
public Type getType()
{
return Type.INTEGER;
}
@Override
public boolean isArrayAdapter()
{
return true;
}
};
static ITypeAdapter shrt = new ITypeAdapter() {
@Override
public Object getValue(Property prop) {
return (short)prop.getInt();
}
@Override
public void setDefaultValue(Property property, Object value)
{
property.setDefaultValue((Short)value);
}
@Override
public void setValue(Property property, Object value)
{
property.setValue((Short)value);
}
@Override
public Type getType()
{
return Type.INTEGER;
}
@Override
public boolean isArrayAdapter()
{
return false;
}
};
static ITypeAdapter shrtA = new ITypeAdapter() {
@Override
public Object getValue(Property prop) {
return Shorts.toArray(Ints.asList(prop.getIntList()));
}
@Override
public void setDefaultValue(Property property, Object value)
{
property.setDefaultValues(Ints.toArray(Shorts.asList((short[])value)));
}
@Override
public void setValue(Property property, Object value)
{
property.setValues(Ints.toArray(Shorts.asList((short[])value)));
}
@Override
public Type getType()
{
return Type.INTEGER;
}
@Override
public boolean isArrayAdapter()
{
return true;
}
};
static ITypeAdapter Shrt = new ITypeAdapter() {
@Override
public Object getValue(Property prop) {
return Short.valueOf((short)prop.getInt());
}
@Override
public void setDefaultValue(Property property, Object value)
{
property.setDefaultValue((Short)value);
}
@Override
public void setValue(Property property, Object value)
{
property.setValue((Short)value);
}
@Override
public Type getType()
{
return Type.INTEGER;
}
@Override
public boolean isArrayAdapter()
{
return false;
}
};
static ITypeAdapter ShrtA = new ITypeAdapter() {
@Override
public Object getValue(Property prop) {
int[] v = prop.getIntList();
Short[] ret = new Short[v.length];
for (int x = 0; x < ret.length; x++)
ret[x] = Short.valueOf((short)v[x]);
return ret;
}
@Override
public void setDefaultValue(Property property, Object value)
{
property.setDefaultValues(Ints.toArray(Arrays.asList((Short[])value)));
}
@Override
public void setValue(Property property, Object value)
{
property.setValues(Ints.toArray(Arrays.asList((Short[])value)));
}
@Override
public Type getType()
{
return Type.INTEGER;
}
@Override
public boolean isArrayAdapter()
{
return true;
}
};
static ITypeAdapter int_ = new ITypeAdapter() {
@Override
public Object getValue(Property prop) {
return prop.getInt();
}
@Override
public void setDefaultValue(Property property, Object value)
{
property.setDefaultValue((Integer)value);
}
@Override
public void setValue(Property property, Object value)
{
property.setValue((Integer)value);
}
@Override
public Type getType()
{
return Type.INTEGER;
}
@Override
public boolean isArrayAdapter()
{
return false;
}
};
static ITypeAdapter intA = new ITypeAdapter() {
@Override
public Object getValue(Property prop) {
return prop.getIntList();
}
@Override
public void setDefaultValue(Property property, Object value)
{
property.setDefaultValues((int[])value);
}
@Override
public void setValue(Property property, Object value)
{
property.setValues((int[])value);
}
@Override
public Type getType()
{
return Type.INTEGER;
}
@Override
public boolean isArrayAdapter()
{
return true;
}
};
static ITypeAdapter Int = new ITypeAdapter() {
@Override
public Object getValue(Property prop) {
return (Integer)prop.getInt();
}
@Override
public void setDefaultValue(Property property, Object value)
{
property.setDefaultValue((Integer)value);
}
@Override
public void setValue(Property property, Object value)
{
property.setValue((Integer)value);
}
@Override
public Type getType()
{
return Type.INTEGER;
}
@Override
public boolean isArrayAdapter()
{
return false;
}
};
static ITypeAdapter IntA = new ITypeAdapter() {
@Override
public Object getValue(Property prop) {
return Ints.asList(prop.getIntList()).toArray(new Integer[prop.getIntList().length]);
}
@Override
public void setDefaultValue(Property property, Object value)
{
property.setDefaultValues(Ints.toArray(Arrays.asList((Integer[])value)));
}
@Override
public void setValue(Property property, Object value)
{
property.setValues(Ints.toArray(Arrays.asList((Integer[])value)));
}
@Override
public Type getType()
{
return Type.INTEGER;
}
@Override
public boolean isArrayAdapter()
{
return true;
}
};
static ITypeAdapter Str = new ITypeAdapter() {
@Override
public Object getValue(Property prop) {
return prop.getString();
}
@Override
public void setDefaultValue(Property property, Object value)
{
property.setDefaultValue((String)value);
}
@Override
public void setValue(Property property, Object value)
{
property.setValue((String)value);
}
@Override
public Type getType()
{
return Type.STRING;
}
@Override
public boolean isArrayAdapter()
{
return false;
}
};
static ITypeAdapter StrA = new ITypeAdapter() {
@Override
public Object getValue(Property prop) {
return prop.getStringList();
}
@Override
public void setDefaultValue(Property property, Object value)
{
property.setDefaultValues((String[])value);
}
@Override
public void setValue(Property property, Object value)
{
property.setValues((String[])value);
}
@Override
public Type getType()
{
return Type.STRING;
}
@Override
public boolean isArrayAdapter()
{
return true;
}
};
}

View File

@ -3,12 +3,16 @@ package net.minecraftforge.common.extensions;
import javax.annotation.Nullable;
import net.minecraft.world.World;
import net.minecraft.world.dimension.Dimension;
import net.minecraft.world.dimension.NetherDimension;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.client.IRenderHandler;
public interface IForgeDimension
{
default Dimension getDimension() { return (Dimension) this; }
/**
* Called from {@link World#initCapabilities()}, to gather capabilities for this
* world. It's safe to access world here since this is called after world is
@ -26,6 +30,22 @@ public interface IForgeDimension
return null;
}
/**
* 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.
* @return The movement factor
*/
default double getMovementFactor()
{
if (getDimension() instanceof NetherDimension)
{
return 8.0;
}
return 1.0;
}
/**
* Sets the providers current dimension ID, used in default getSaveFolder()
* Added to allow default providers to be registered for multiple dimensions.

View File

@ -0,0 +1,16 @@
package net.minecraftforge.common.extensions;
import java.io.File;
import net.minecraft.world.WorldServer;
import net.minecraft.world.chunk.storage.AnvilChunkLoader;
public interface IForgeWorldServer extends IForgeWorld
{
default WorldServer getWorldServer() { return (WorldServer) this; }
default File getChunkSaveLocation()
{
return ((AnvilChunkLoader) getWorldServer().getChunkProvider().chunkLoader).chunkSaveLocation;
}
}

View File

@ -27,7 +27,7 @@ import org.apache.logging.log4j.Logger;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
/* TODO fluids
public class FluidIdRegistryMessageHandler extends SimpleChannelInboundHandler<ForgeMessage.FluidIdMapMessage> {
private static final Logger LOGGER = LogManager.getLogger();
@ -44,3 +44,4 @@ public class FluidIdRegistryMessageHandler extends SimpleChannelInboundHandler<F
}
}
*/

View File

@ -70,7 +70,7 @@ public abstract class ForgeMessage {
providerId = new String(data, StandardCharsets.UTF_8);
}
}
/* TODO fluids
public static class FluidIdMapMessage extends ForgeMessage {
BiMap<Fluid, Integer> fluidIds = HashBiMap.create();
Set<String> defaultFluids = Sets.newHashSet();
@ -117,7 +117,7 @@ public abstract class ForgeMessage {
}
}
}
*/
abstract void toBytes(ByteBuf bytes);
abstract void fromBytes(ByteBuf bytes);
}

View File

@ -18,7 +18,7 @@
*/
package net.minecraftforge.common.network;
/* TODO handshake
import java.util.EnumMap;
import net.minecraftforge.api.distmarker.OnlyIn;
@ -56,3 +56,4 @@ public class ForgeNetworkHandler
clientChannel.pipeline().addAfter(handlerName, "FluidIdRegistryHandler", new FluidIdRegistryMessageHandler());
}
}
*/

View File

@ -18,7 +18,7 @@
*/
package net.minecraftforge.common.network;
/* TODO handshake
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import net.minecraftforge.fml.common.network.FMLIndexedMessageToMessageCodec;
@ -41,3 +41,4 @@ public class ForgeRuntimeCodec extends FMLIndexedMessageToMessageCodec<ForgeMess
msg.fromBytes(source);
}
}
*/

View File

@ -18,7 +18,7 @@
*/
package net.minecraftforge.common.network;
/* TODO handshake
import net.minecraftforge.fml.common.network.NetworkHandshakeEstablished;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
@ -36,3 +36,4 @@ public class ServerToClientConnectionEstablishedHandler extends ChannelInboundHa
ctx.fireUserEventTriggered(evt);
}
}
*/

View File

@ -38,15 +38,16 @@ import net.minecraft.block.state.BlockState;
import net.minecraft.block.state.IBlockState;
import net.minecraft.state.AbstractStateHolder;
import net.minecraft.state.IProperty;
import net.minecraft.state.IStateHolder;
import net.minecraft.state.StateContainer;
public class ExtendedBlockState extends StateContainer<Block, IBlockState>
// TODO Extended states gotta go, I doubt this works at all
public class ExtendedStateContainer<O, S extends IExtendedState<S>> extends StateContainer<O, S>
{
private final ImmutableSet<IUnlistedProperty<?>> unlistedProperties;
public <A extends AbstractStateHolder<Block, IBlockState>> ExtendedBlockState(Block blockIn, StateContainer.IFactory<Block, IBlockState, ?> stateFactory, net.minecraft.state.IProperty<?>[] properties, IUnlistedProperty<?>[] unlistedProperties)
public <A extends AbstractStateHolder<O, S>> ExtendedStateContainer(O blockIn, StateContainer.IFactory<O, S, A> stateFactory, net.minecraft.state.IProperty<?>[] properties, IUnlistedProperty<?>[] unlistedProperties)
{
super(blockIn, stateFactory, buildListedMap(properties));// TODO Unlisted properties?, buildUnlistedMap(unlistedProperties));
super(blockIn, getProxyFactory(unlistedProperties, stateFactory), buildListedMap(properties));// TODO Unlisted properties?, buildUnlistedMap(unlistedProperties));
ImmutableSet.Builder<IUnlistedProperty<?>> builder = ImmutableSet.builder();
for(IUnlistedProperty<?> property : unlistedProperties)
{
@ -54,6 +55,15 @@ public class ExtendedBlockState extends StateContainer<Block, IBlockState>
}
this.unlistedProperties = builder.build();
}
private static <O, S extends IExtendedState<S>, A extends AbstractStateHolder<O, S>>
StateContainer.IFactory<O, S, AbstractStateHolder<O,S>> getProxyFactory(IUnlistedProperty<?>[] unlistedProperties, StateContainer.IFactory<O, S, A> proxy)
{
return (o, props) -> {
if (unlistedProperties == null || unlistedProperties.length == 0) return proxy.create(o, props);
return new ExtendedStateHolder<O, S>(o, props, buildUnlistedMap(unlistedProperties), null);
};
}
public Collection<IUnlistedProperty<?>> getUnlistedProperties()
{
@ -75,33 +85,25 @@ public class ExtendedBlockState extends StateContainer<Block, IBlockState>
return builder.build();
}
@Override
@Nonnull
protected StateImplementation createState(@Nonnull Block block, @Nonnull ImmutableMap<IProperty<?>, Comparable<?>> properties, @Nullable ImmutableMap<IUnlistedProperty<?>, Optional<?>> unlistedProperties)
{
if (unlistedProperties == null || unlistedProperties.isEmpty()) return super.createState(block, properties, unlistedProperties);
return new ExtendedStateImplementation(block, properties, unlistedProperties, null, null);
}
protected static class ExtendedStateImplementation extends StateImplementation implements IExtendedBlockState
protected static class ExtendedStateHolder<O, S extends IExtendedState<S>> extends AbstractStateHolder<O, S> implements IExtendedState<S>
{
private final ImmutableMap<IUnlistedProperty<?>, Optional<?>> unlistedProperties;
private IBlockState cleanState;
private S cleanState;
protected ExtendedStateImplementation(Block block, ImmutableMap<IProperty<?>, Comparable<?>> properties, ImmutableMap<IUnlistedProperty<?>, Optional<?>> unlistedProperties, @Nullable ImmutableTable<IProperty<?>, Comparable<?>, IBlockState> table, IBlockState clean)
protected ExtendedStateHolder(O block, ImmutableMap<IProperty<?>, Comparable<?>> properties, ImmutableMap<IUnlistedProperty<?>, Optional<?>> unlistedProperties, S clean)
{
super(block, properties, table);
super(block, properties);
this.unlistedProperties = unlistedProperties;
this.cleanState = clean == null ? this : clean;
this.cleanState = clean == null ? (S) this : clean;
}
@Override
@Nonnull
public <T extends Comparable<T>, V extends T> IBlockState withProperty(@Nonnull IProperty<T> property, @Nonnull V value)
public <T extends Comparable<T>, V extends T> S func_206870_a(@Nonnull IProperty<T> property, @Nonnull V value)
{
IBlockState clean = super.withProperty(property, value);
S clean = super.func_206870_a(property, value);
if (clean == this.cleanState) {
return this;
return (S) this;
}
if (this == this.cleanState)
@ -109,24 +111,24 @@ public class ExtendedBlockState extends StateContainer<Block, IBlockState>
return clean;
}
return new ExtendedStateImplementation(getBlock(), clean.getProperties(), unlistedProperties, ((StateImplementation)clean).getPropertyValueTable(), this.cleanState);
return (S) new ExtendedStateHolder(field_206876_a, ((BlockState)clean).func_206871_b(), unlistedProperties, this.cleanState);
}
@Override
public <V> IExtendedBlockState withProperty(IUnlistedProperty<V> property, @Nullable V value)
public <V> S withProperty(IUnlistedProperty<V> property, @Nullable V value)
{
Optional<?> oldValue = unlistedProperties.get(property);
if (oldValue == null)
{
throw new IllegalArgumentException("Cannot set unlisted property " + property + " as it does not exist in " + getBlock().getBlockState());
throw new IllegalArgumentException("Cannot set unlisted property " + property + " as it does not exist in " + this);
}
if (Objects.equals(oldValue.orElse(null), value))
{
return this;
return (S) this;
}
if (!property.isValid(value))
{
throw new IllegalArgumentException("Cannot set unlisted property " + property + " to " + value + " on block " + Block.REGISTRY.getNameForObject(getBlock()) + ", it is not an allowed value");
throw new IllegalArgumentException("Cannot set unlisted property " + property + " to " + value + " on object " + field_206876_a + ", it is not an allowed value");
}
boolean clean = true;
ImmutableMap.Builder<IUnlistedProperty<?>, Optional<?>> builder = ImmutableMap.builder();
@ -139,9 +141,9 @@ public class ExtendedBlockState extends StateContainer<Block, IBlockState>
}
if (clean)
{ // no dynamic properties, lookup normal state
return (IExtendedBlockState) cleanState;
return (S) cleanState;
}
return new ExtendedStateImplementation(getBlock(), getProperties(), builder.build(), propertyValueTable, this.cleanState);
return (S) new ExtendedStateHolder(field_206876_a, func_206871_b(), builder.build(), this.cleanState);
}
@Override
@ -157,7 +159,7 @@ public class ExtendedBlockState extends StateContainer<Block, IBlockState>
Optional<?> value = unlistedProperties.get(property);
if (value == null)
{
throw new IllegalArgumentException("Cannot get unlisted property " + property + " as it does not exist in " + getBlock().getBlockState());
throw new IllegalArgumentException("Cannot get unlisted property " + property + " as it does not exist in " + this);
}
return property.getType().cast(value.orElse(null));
}
@ -168,7 +170,7 @@ public class ExtendedBlockState extends StateContainer<Block, IBlockState>
}
@Override
public IBlockState getClean()
public S getClean()
{
return cleanState;
}

View File

@ -1,40 +1,8 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2018.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.common.property;
import java.util.Collection;
import net.minecraft.block.state.IBlockState;
import java.util.Optional;
import com.google.common.collect.ImmutableMap;
public interface IExtendedBlockState extends IBlockState
public interface IExtendedBlockState extends IExtendedState<IBlockState>, IBlockState
{
Collection<IUnlistedProperty<?>> getUnlistedNames();
<V>V getValue(IUnlistedProperty<V> property);
<V>IExtendedBlockState withProperty(IUnlistedProperty<V> property, V value);
ImmutableMap<IUnlistedProperty<?>, Optional<?>> getUnlistedProperties();
IBlockState getClean();
}

View File

@ -17,11 +17,25 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.common.util;
package net.minecraftforge.common.property;
import net.minecraft.util.datafix.IDataFixer;
import java.util.Collection;
public interface IDataFixerData extends IDataFixer
import net.minecraft.block.state.IBlockState;
import net.minecraft.state.IStateHolder;
import java.util.Optional;
import com.google.common.collect.ImmutableMap;
public interface IExtendedState<C> extends IStateHolder<C>
{
int getVersion(String mod);
Collection<IUnlistedProperty<?>> getUnlistedNames();
<V>V getValue(IUnlistedProperty<V> property);
<V>C withProperty(IUnlistedProperty<V> property, V value);
ImmutableMap<IUnlistedProperty<?>, Optional<?>> getUnlistedProperties();
C getClean();
}

View File

@ -28,7 +28,6 @@ import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.fml.common.FMLCommonHandler;
import net.minecraftforge.registries.ForgeRegistries;
import javax.annotation.Nullable;
@ -54,7 +53,7 @@ public class BlockSnapshot
@Nullable
private WeakReference<World> world;
private final ResourceLocation registryName;
private final int meta;
private final int meta = 0; // TODO BlockSnapshot needs a total refactor for the absence of metadata
public BlockSnapshot(World world, BlockPos pos, IBlockState state)
{
@ -68,7 +67,6 @@ public class BlockSnapshot
this.pos = pos.toImmutable();
this.setReplacedBlock(state);
this.registryName = state.getBlock().getRegistryName();
this.meta = state.getBlock().getMetaFromState(state);
this.setFlag(3);
this.nbt = nbt;
if (DEBUG)
@ -99,7 +97,6 @@ public class BlockSnapshot
this.pos = pos.toImmutable();
this.setFlag(flag);
this.registryName = registryName;
this.meta = meta;
this.nbt = nbt;
}
@ -143,7 +140,7 @@ public class BlockSnapshot
World world = this.world != null ? this.world.get() : null;
if (world == null)
{
world = FMLCommonHandler.instance().getMinecraftServerInstance().getWorld(getDimId());
world = null; // TODO Server static access? FMLCommonHandler.instance().getMinecraftServerInstance().getWorld(getDimId());
this.world = new WeakReference<World>(world);
}
return world;
@ -153,7 +150,7 @@ public class BlockSnapshot
{
if (this.replacedBlock == null)
{
this.replacedBlock = ForgeRegistries.BLOCKS.getValue(getRegistryName()).getStateFromMeta(getMeta());
this.replacedBlock = ForgeRegistries.BLOCKS.getValue(getRegistryName()).func_196257_b(getMeta());
}
return this.replacedBlock;
}
@ -161,7 +158,7 @@ public class BlockSnapshot
@Nullable
public TileEntity getTileEntity()
{
return getNbt() != null ? TileEntity.create(getWorld(), getNbt()) : null;
return getNbt() != null ? TileEntity.func_203403_c(getNbt()) : null;
}
public boolean restore()
@ -184,7 +181,7 @@ public class BlockSnapshot
IBlockState current = getCurrentBlock();
IBlockState replaced = getReplacedBlock();
if (current.getBlock() != replaced.getBlock() || current.getBlock().getMetaFromState(current) != replaced.getBlock().getMetaFromState(replaced))
if (current != replaced)
{
if (force)
{
@ -212,15 +209,15 @@ public class BlockSnapshot
if (DEBUG)
{
System.out.printf("Restored BlockSnapshot with data [World: %s ][Location: %d,%d,%d ][Meta: %d ][Block: %s ][TileEntity: %s ][force: %s ][notifyNeighbors: %s]", world.getWorldInfo().getWorldName(), pos.getX(), pos.getY(), pos.getZ(), replaced.getBlock().getMetaFromState(replaced), replaced.getBlock().delegate.name(), te, force, notifyNeighbors);
System.out.printf("Restored BlockSnapshot with data [World: %s ][Location: %d,%d,%d ][State: %s ][Block: %s ][TileEntity: %s ][force: %s ][notifyNeighbors: %s]", world.getWorldInfo().getWorldName(), pos.getX(), pos.getY(), pos.getZ(), replaced, replaced.getBlock().delegate.name(), te, force, notifyNeighbors);
}
return true;
}
public void writeToNBT(NBTTagCompound compound)
{
compound.setString("blockMod", getRegistryName().getResourceDomain());
compound.setString("blockName", getRegistryName().getResourcePath());
compound.setString("blockMod", getRegistryName().getNamespace());
compound.setString("blockName", getRegistryName().getPath());
compound.setInteger("posX", getPos().getX());
compound.setInteger("posY", getPos().getY());
compound.setInteger("posZ", getPos().getZ());

View File

@ -1,185 +0,0 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2018.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.common.util;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.datafix.DataFixer;
import net.minecraft.util.datafix.FixTypes;
import net.minecraft.util.datafix.IDataWalker;
import net.minecraft.util.datafix.IFixType;
import net.minecraft.util.datafix.IFixableData;
public class CompoundDataFixer extends DataFixer
{
private final ModFixs vanilla;
private final Map<String, ModFixs> modFixers = Maps.newHashMap();
private final Map<IFixType, List<IDataWalker>> walkers = Maps.newHashMap();
public CompoundDataFixer(DataFixer vanilla)
{
super(0);
this.vanilla = init("minecraft", vanilla.version);
}
@Override
public NBTTagCompound process(IFixType type, NBTTagCompound nbt)
{
final Map<String, Integer>versions = getVersions(nbt);
final int mcversion = versions.get("minecraft") == null ? -1 : versions.get("minecraft");
final IDataFixerData holder = new IDataFixerData()
{
@Override
public NBTTagCompound process(IFixType type, NBTTagCompound nbt, int version)
{
for (Entry<String, ModFixs> e : modFixers.entrySet())
{
// This is a potential performance hot spot. As it walks all the data for all
// of the fixers... But with the vanilla api there isn't a way to pass down
// the mod specific version numbers, so redundant.. but not hacky...
//Actually, this wont work as the data walkers take versions into account...
ModFixs fixer = e.getValue();
int ver = getVersion(e.getKey());
if (ver < fixer.version)
{
for (IFixableData fix : fixer.getFixes(type))
{
if (fix.getFixVersion() > ver)
nbt = fix.fixTagCompound(nbt);
}
for (IDataWalker walker : getWalkers(type))
nbt = walker.process(this, nbt, version); //We pass in the holder, in case a walker wants to know a mod version
}
}
return nbt;
}
@Override
public int getVersion(String mod)
{
Integer ret = versions.get(mod);
return ret == null ? -1 : ret;
}
};
return holder.process(type, nbt, mcversion);
}
@Override
@Deprecated //MODDERS DO NOT CALL DIRECTLY! Only use from DataWalker!
public NBTTagCompound process(IFixType type, NBTTagCompound nbt, int mcversion)
{
if (type != FixTypes.OPTIONS) //Options are vanilla only
throw new IllegalStateException("Do not call recursive process directly on DataFixer!");
for (IFixableData fix : vanilla.getFixes(type))
{
if (fix.getFixVersion() > mcversion)
nbt = fix.fixTagCompound(nbt);
}
//Options is a hack, and doesn't have any nested components
//for (IDataWalker walker : getWalkers(type))
// nbt = walker.process(this, nbt, version);
return nbt;
}
private List<IDataWalker> getWalkers(IFixType type)
{
return walkers.computeIfAbsent(type, k -> Lists.newArrayList());
}
@Override
@Deprecated //Modders do not use this, this will register you as vanilla. Use the ModID version below.
public void registerFix(IFixType type, IFixableData fixable)
{
vanilla.registerFix(type, fixable);
}
@Override
@Deprecated //Modders do not use this, use add below, To better allow custom fix types.
public void registerWalker(FixTypes type, IDataWalker walker)
{
registerVanillaWalker(type, walker);
}
@Override
public void registerVanillaWalker(IFixType type, IDataWalker walker)
{
getWalkers(type).add(walker);
}
private void validateModId(String mod)
{
//String current = Loader.instance().activeModContainer() == null ? "minecraft" : Loader.instance().activeModContainer().getModId();
//Test active modid?
if (!mod.equals(mod.toLowerCase(Locale.ENGLISH)))
throw new IllegalArgumentException("Mod ID is not lower case: " + mod);
if (mod.length() > 64)
throw new IllegalArgumentException("Mod ID is to long: " + mod);
}
/**
* Initialize your mod specific data fixer.
*
* @param modid You mod id, must be lower case.
* @param version The current data version of your mod
*/
public ModFixs init(String modid, int version)
{
validateModId(modid);
if (modFixers.containsKey(modid))
throw new IllegalStateException("Attempted to initalize DataFixer for " + modid + " twice");
ModFixs ret = new ModFixs(modid, version);
modFixers.put(modid, ret);
return ret;
}
private Map<String, Integer> getVersions(NBTTagCompound nbt)
{
Map<String, Integer> ret = Maps.newHashMap();
ret.put("minecraft", nbt.hasKey("DataVersion", 99) ? nbt.getInteger("DataVersion") : -1);
if (nbt.hasKey("ForgeDataVersion", 10))
{
NBTTagCompound sub = nbt.getCompoundTag("ForgeDataVersion");
for (String key : sub.getKeySet())
{
ret.put(key, sub.hasKey(key, 99) ? sub.getInteger(key) : -1);
}
}
return ret;
}
public void writeVersionData(NBTTagCompound nbt)
{
//nbt.setInteger("DataVersion", vanilla.version);
NBTTagCompound sub = new NBTTagCompound();
nbt.setTag("ForgeDataVersion", sub);
for (ModFixs mod : modFixers.values())
sub.setInteger(mod.mod, mod.version);
}
}

View File

@ -1,85 +0,0 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2018.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.common.util;
import java.lang.reflect.*;
import java.util.*;
import java.util.function.BiPredicate;
import com.google.common.base.Predicate;
import com.google.common.collect.Lists;
import net.minecraftforge.fml.common.EnhancedRuntimeException;
import org.apache.commons.lang3.ArrayUtils;
import javax.annotation.Nullable;
public class EnumHelper
{
/*
* Everything below this is found at the site below, and updated to be able to compile in Eclipse/Java 1.6+
* Also modified for use in decompiled code.
* Found at: http://niceideas.ch/roller2/badtrash/entry/java_create_enum_instances_dynamically
*/
private static < T extends Enum<? >> T makeEnum(Class<T> enumClass, @Nullable String value, int ordinal, Class<?>[] additionalTypes, @Nullable Object[] additionalValues) throws Exception
{
//new Enum(name, values.size() + 1, params)
}
private static void blankField(Class<?> enumClass, String fieldName) throws Exception
{
for (Field field : Class.class.getDeclaredFields())
{
if (field.getName().contains(fieldName))
{
field.setAccessible(true);
field.set(enumClass, null);
break;
}
}
}
//Class holds caches of the enum constants used for Enum.valueOf() and reflection magic. So we need to invalidate those caches when we add something new. They will automtically be re-built.
public static void cleanEnumCache(Class<?> enumClass) throws Exception
{
blankField(enumClass, "enumConstantDirectory");
blankField(enumClass, "enumConstants");
}
@SuppressWarnings({ "unchecked", "serial" })
@Nullable
private static <T extends Enum<?> & IExpandableEnum<?>> T addEnum(boolean test, final Class<T> enumType, T newValue)
{
try
{
T[] previousValues = enumType.getEnumConstants();
T newValue = makeEnum(enumType, enumName, previousValues.length, paramTypes, paramValues);
newValue.__set_values__(ArrayUtils.add(previousValues, newValue));
cleanEnumCache(enumType);
return newValue;
}
catch (Exception e)
{
throw new RuntimeException(e);
}
}
}

View File

@ -22,7 +22,6 @@ package net.minecraftforge.common.util;
import com.mojang.authlib.GameProfile;
import net.minecraft.entity.Entity;
import net.minecraftforge.fml.common.FMLCommonHandler;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.network.play.client.CPacketClientSettings;
@ -39,11 +38,10 @@ public class FakePlayer extends EntityPlayerMP
{
public FakePlayer(WorldServer world, GameProfile name)
{
super(FMLCommonHandler.instance().getMinecraftServerInstance(), world, name, new PlayerInteractionManager(world));
super(world.getMinecraftServer(), world, name, new PlayerInteractionManager(world));
}
@Override public Vec3d getPositionVector(){ return new Vec3d(0, 0, 0); }
@Override public boolean canUseCommand(int i, String s){ return false; }
@Override public void sendStatusMessage(ITextComponent chatComponent, boolean actionBar){}
@Override public void sendMessage(ITextComponent component) {}
@Override public void addStat(StatBase par1StatBase, int par2){}

View File

@ -22,7 +22,6 @@ package net.minecraftforge.common.util;
import net.minecraft.entity.Entity;
import net.minecraft.world.Teleporter;
import net.minecraft.world.World;
import net.minecraft.world.WorldProvider;
/**
* Interface for handling the placement of entities during dimension change.

View File

@ -36,8 +36,9 @@ import com.google.gson.JsonParseException;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import com.google.gson.JsonSyntaxException;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import net.minecraft.nbt.JsonToNBT;
import net.minecraft.nbt.NBTException;
import net.minecraft.nbt.NBTTagCompound;
import javax.annotation.Nullable;
@ -103,7 +104,7 @@ public class JsonUtils
try
{
return JsonToNBT.getTagFromJson(net.minecraft.util.JsonUtils.getString(json, key));
} catch (NBTException e)
} catch (CommandSyntaxException e)
{
throw new JsonSyntaxException("Malformed NBT tag", e);
}

View File

@ -1,78 +0,0 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2018.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.common.util;
import java.util.List;
import java.util.Map;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import net.minecraft.util.datafix.IFixType;
import net.minecraft.util.datafix.IFixableData;
public class ModFixs
{
private static final Logger LOGGER = LogManager.getLogger();
final String mod;
final int version;
private final Map<IFixType, List<IFixableData>> fixes = Maps.newHashMap();
ModFixs(String mod, int version)
{
this.mod = mod;
this.version = version;
}
public List<IFixableData> getFixes(IFixType type)
{
return this.fixes.computeIfAbsent(type, k -> Lists.newArrayList());
}
public void registerFix(IFixType type, IFixableData fixer)
{
List<IFixableData> list = getFixes(type);
int ver = fixer.getFixVersion();
if (ver > this.version)
{
LOGGER.warn("[{}] Ignored fix registered for version: {} as the DataVersion of the game is: {}", mod, ver, this.version);
return;
}
if (!list.isEmpty() && list.get(list.size()-1).getFixVersion() > ver)
{
for (int x = 0; x < list.size(); ++x)
{
if (list.get(x).getFixVersion() > ver)
{
list.add(x, fixer);
break;
}
}
}
else
list.add(fixer);
}
}

View File

@ -45,7 +45,6 @@ public class PacketUtil
{
buffer.writeShort(Item.getIdFromItem(stack.getItem()));
buffer.writeByte(stack.getCount());
buffer.writeShort(stack.getMetadata());
NBTTagCompound nbttagcompound = null;
if (stack.getItem().isDamageable() || stack.getItem().getShareTag())

View File

@ -67,7 +67,7 @@ public class DispenseFluidContainer extends BehaviorDefaultDispenseItem
@Nonnull
private ItemStack fillContainer(@Nonnull IBlockSource source, @Nonnull ItemStack stack)
{
World world = source.getWorld();
World world = source.func_197524_h();
EnumFacing dispenserFacing = source.getBlockState().getValue(BlockDispenser.FACING);
BlockPos blockpos = source.getBlockPos().offset(dispenserFacing);
@ -101,7 +101,7 @@ public class DispenseFluidContainer extends BehaviorDefaultDispenseItem
{
ItemStack singleStack = stack.copy();
singleStack.setCount(1);
IFluidHandlerItem fluidHandler = FluidUtil.getFluidHandler(singleStack);
IFluidHandlerItem fluidHandler = null; // TODO fluids FluidUtil.getFluidHandler(singleStack);
if (fluidHandler == null)
{
return super.dispenseStack(source, stack);
@ -110,7 +110,7 @@ public class DispenseFluidContainer extends BehaviorDefaultDispenseItem
FluidStack fluidStack = fluidHandler.drain(Fluid.BUCKET_VOLUME, false);
EnumFacing dispenserFacing = source.getBlockState().getValue(BlockDispenser.FACING);
BlockPos blockpos = source.getBlockPos().offset(dispenserFacing);
FluidActionResult result = fluidStack != null ? FluidUtil.tryPlaceFluid(null, source.getWorld(), blockpos, stack, fluidStack) : FluidActionResult.FAILURE;
FluidActionResult result = fluidStack != null ? FluidUtil.tryPlaceFluid(null, source.func_197524_h(), blockpos, stack, fluidStack) : FluidActionResult.FAILURE;
if (result.isSuccess())
{

View File

@ -29,10 +29,12 @@ import java.util.Locale;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Particles;
import net.minecraft.init.SoundEvents;
import net.minecraft.util.SoundCategory;
import net.minecraft.util.SoundEvent;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.translation.LanguageMap;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;
import net.minecraft.item.EnumRarity;
@ -308,7 +310,7 @@ public class Fluid
for (int l = 0; l < 8; ++l)
{
worldIn.spawnParticle(EnumParticleTypes.SMOKE_LARGE, (double) pos.getX() + Math.random(), (double) pos.getY() + Math.random(), (double) pos.getZ() + Math.random(), 0.0D, 0.0D, 0.0D);
worldIn.func_195589_b(Particles.field_197594_E, (double) pos.getX() + Math.random(), (double) pos.getY() + Math.random(), (double) pos.getZ() + Math.random(), 0.0D, 0.0D, 0.0D);
}
}
@ -318,7 +320,7 @@ public class Fluid
public String getLocalizedName(FluidStack stack)
{
String s = this.getUnlocalizedName();
return s == null ? "" : I18n.translateToLocal(s);
return s == null ? "" : LanguageMap.getInstance().translateKey(s); // TODO Server translation
}
/**

View File

@ -26,6 +26,9 @@ import net.minecraftforge.registries.IRegistryDelegate;
import javax.annotation.Nullable;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
/**
* ItemStack substitute for Fluids.
*
@ -36,6 +39,8 @@ import javax.annotation.Nullable;
*/
public class FluidStack
{
private static final Logger LOGGER = LogManager.getLogger();
public int amount;
public NBTTagCompound tag;
private IRegistryDelegate<Fluid> fluidDelegate;
@ -44,15 +49,15 @@ public class FluidStack
{
if (fluid == null)
{
FMLLog.bigWarning("Null fluid supplied to fluidstack. Did you try and create a stack for an unregistered fluid?");
LOGGER.fatal("Null fluid supplied to fluidstack. Did you try and create a stack for an unregistered fluid?");
throw new IllegalArgumentException("Cannot create a fluidstack from a null fluid");
}
}/* TODO fluids
else if (!FluidRegistry.isFluidRegistered(fluid))
{
FMLLog.bigWarning("Failed attempt to create a FluidStack for an unregistered Fluid {} (type {})", fluid.getName(), fluid.getClass().getName());
LOGGER.fatal("Failed attempt to create a FluidStack for an unregistered Fluid {} (type {})", fluid.getName(), fluid.getClass().getName());
throw new IllegalArgumentException("Cannot create a fluidstack from an unregistered fluid");
}
this.fluidDelegate = FluidRegistry.makeDelegate(fluid);
} */
this.fluidDelegate = null; // TODO fluids FluidRegistry.makeDelegate(fluid);
this.amount = amount;
}
@ -88,22 +93,22 @@ public class FluidStack
}
String fluidName = nbt.getString("FluidName");
if (FluidRegistry.getFluid(fluidName) == null)
// TODO fluids if (FluidRegistry.getFluid(fluidName) == null)
{
return null;
}
}/*
FluidStack stack = new FluidStack(FluidRegistry.getFluid(fluidName), nbt.getInteger("Amount"));
if (nbt.hasKey("Tag"))
{
stack.tag = nbt.getCompoundTag("Tag");
}
return stack;
return stack;*/
}
public NBTTagCompound writeToNBT(NBTTagCompound nbt)
{
nbt.setString("FluidName", FluidRegistry.getFluidName(getFluid()));
// TODO fluids bt.setString("FluidName", FluidRegistry.getFluidName(getFluid()));
nbt.setInteger("Amount", amount);
if (tag != null)
@ -199,7 +204,7 @@ public class FluidStack
return false;
}
return isFluidEqual(FluidUtil.getFluidContained(other));
return FluidUtil.getFluidContained(other).map(this::isFluidEqual).orElse(false);
}
@Override

View File

@ -704,7 +704,7 @@ public class FluidUtil
*/
@Nonnull
public static ItemStack getFilledBucket(@Nonnull FluidStack fluidStack)
{
{/* TODO fluids
Fluid fluid = fluidStack.getFluid();
if (fluidStack.tag == null || fluidStack.tag.isEmpty())
@ -735,7 +735,7 @@ public class FluidUtil
return filledBucket;
}
*/
return ItemStack.EMPTY;
}
}

View File

@ -20,10 +20,10 @@
package net.minecraftforge.fluids;
import net.minecraft.block.BlockDispenser;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Items;
import net.minecraft.item.Item;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.stats.StatList;
@ -33,7 +33,9 @@ import net.minecraft.util.EnumHand;
import net.minecraft.util.NonNullList;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.text.translation.I18n;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TextComponentTranslation;
import net.minecraft.util.text.translation.LanguageMap;
import net.minecraft.world.World;
import net.minecraftforge.common.capabilities.ICapabilityProvider;
import net.minecraftforge.event.entity.player.FillBucketEvent;
@ -59,9 +61,9 @@ public class UniversalBucket extends Item
private final ItemStack empty; // empty item to return and recognize when filling
private final boolean nbtSensitive;
public UniversalBucket()
public UniversalBucket(Builder builder)
{
this(Fluid.BUCKET_VOLUME, new ItemStack(Items.BUCKET), false);
this(builder, Fluid.BUCKET_VOLUME, new ItemStack(Items.BUCKET), false);
}
/**
@ -69,17 +71,19 @@ public class UniversalBucket extends Item
* @param empty Item used for filling with the bucket event and returned when emptied
* @param nbtSensitive Whether the empty item is NBT sensitive (usually true if empty and full are the same items)
*/
public UniversalBucket(int capacity, @Nonnull ItemStack empty, boolean nbtSensitive)
public UniversalBucket(Builder builder, int capacity, @Nonnull ItemStack empty, boolean nbtSensitive)
{
super(builder);
this.capacity = capacity;
this.empty = empty;
this.nbtSensitive = nbtSensitive;
/* TODO move to builder construction
this.setMaxStackSize(1);
this.setCreativeTab(CreativeTabs.MISC);
BlockDispenser.DISPENSE_BEHAVIOR_REGISTRY.putObject(this, DispenseFluidContainer.getInstance());
*/
BlockDispenser.func_199774_a(this, DispenseFluidContainer.getInstance());
}
@Override
@ -101,10 +105,10 @@ public class UniversalBucket extends Item
}
@Override
public void getSubItems(@Nullable CreativeTabs tab, @Nonnull NonNullList<ItemStack> subItems)
public void getSubItems(@Nullable ItemGroup tab, @Nonnull NonNullList<ItemStack> subItems)
{
if (!this.isInCreativeTab(tab))
return;
return;/* TODO fluids
for (Fluid fluid : FluidRegistry.getRegisteredFluids().values())
{
if (fluid != FluidRegistry.WATER && fluid != FluidRegistry.LAVA && !fluid.getName().equals("milk"))
@ -119,31 +123,32 @@ public class UniversalBucket extends Item
subItems.add(filled);
}
}
}
}*/
}
@Override
@Nonnull
public String getItemStackDisplayName(@Nonnull ItemStack stack)
public ITextComponent func_200295_i(@Nonnull ItemStack stack)
{
FluidStack fluidStack = getFluid(stack);
if (fluidStack == null)
{
if(!getEmpty().isEmpty())
{
return getEmpty().getDisplayName();
return getEmpty().func_200301_q();
}
return super.getItemStackDisplayName(stack);
return super.func_200295_i(stack);
}
String unloc = this.getUnlocalizedNameInefficiently(stack);
String unloc = this.getTranslationKey();
if (I18n.canTranslate(unloc + "." + fluidStack.getFluid().getName()))
// TODO this is not reliable on the server
if (LanguageMap.getInstance().func_210813_b(unloc + "." + fluidStack.getFluid().getName()))
{
return I18n.translateToLocal(unloc + "." + fluidStack.getFluid().getName());
return new TextComponentTranslation(unloc + "." + fluidStack.getFluid().getName());
}
return I18n.translateToLocalFormatted(unloc + ".name", fluidStack.getLocalizedName());
return new TextComponentTranslation(unloc + ".name", fluidStack.getLocalizedName());
}
@Override
@ -291,7 +296,7 @@ public class UniversalBucket extends Item
public String getCreatorModId(@Nonnull ItemStack itemStack)
{
FluidStack fluidStack = getFluid(itemStack);
String modId = FluidRegistry.getModId(fluidStack);
String modId = null; // TODO fluids FluidRegistry.getModId(fluidStack);
return modId != null ? modId : super.getCreatorModId(itemStack);
}

View File

@ -64,18 +64,19 @@ public class FluidBucketWrapper implements IFluidHandlerItem, ICapabilityProvide
}
public boolean canFillFluidType(FluidStack fluid)
{
{/* TODO fluids
if (fluid.getFluid() == FluidRegistry.WATER || fluid.getFluid() == FluidRegistry.LAVA || fluid.getFluid().getName().equals("milk"))
{
return true;
}
return FluidRegistry.isUniversalBucketEnabled() && FluidRegistry.getBucketFluids().contains(fluid.getFluid());
*/ return false;
}
@Nullable
public FluidStack getFluid()
{
Item item = container.getItem();
Item item = container.getItem();/* TODO fluids
if (item == Items.WATER_BUCKET)
{
return new FluidStack(FluidRegistry.WATER, Fluid.BUCKET_VOLUME);
@ -88,7 +89,7 @@ public class FluidBucketWrapper implements IFluidHandlerItem, ICapabilityProvide
{
return FluidRegistry.getFluidStack("milk", Fluid.BUCKET_VOLUME);
}
else if (item == ForgeMod.getInstance().universalBucket)
else*/ if (item == ForgeMod.getInstance().universalBucket)
{
return ForgeMod.getInstance().universalBucket.getFluid(container);
}

View File

@ -126,6 +126,11 @@ public class ModList
{
return Optional.ofNullable(this.indexedMods.get(modId));
}
public Optional<? extends ModContainer> getModContainerByObject(Object obj)
{
return mods.stream().filter(mc -> mc.getMod() == obj).findFirst();
}
public List<ModInfo> getMods()
{

View File

@ -16,7 +16,7 @@
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/* TODO is this ded?
package net.minecraftforge.fml.client;
import java.util.ArrayList;
@ -147,3 +147,4 @@ public class FMLConfigGuiFactory implements IModGuiFactory
return fmlCategories;
}
}
*/

View File

@ -24,12 +24,10 @@ import java.util.Arrays;
import java.util.List;
import java.util.regex.Pattern;
import net.minecraft.client.resources.I18n;
import net.minecraftforge.fml.client.config.GuiConfigEntries.IConfigEntry;
import net.minecraftforge.fml.client.config.GuiEditArrayEntries.IArrayEntry;
import javax.annotation.Nullable;
import net.minecraft.client.resources.I18n;
/**
* This class's main purpose is to provide the necessary objects for a sample Config GUI for FML, although

View File

@ -59,9 +59,9 @@ public class GuiButtonExt extends GuiButton
this.mouseDragged(mc, mouseX, mouseY);
int color = 14737632;
if (packedFGColour != 0)
if (packedFGColor != 0)
{
color = packedFGColour;
color = packedFGColor;
}
else if (!this.enabled)
{

View File

@ -42,18 +42,19 @@ public class GuiCheckBox extends GuiButton
}
@Override
public void drawButton(Minecraft mc, int mouseX, int mouseY, float partial)
public void func_194828_a(int mouseX, int mouseY, float partial)
{
if (this.visible)
{
Minecraft mc = Minecraft.getMinecraft();
this.hovered = mouseX >= this.x && mouseY >= this.y && mouseX < this.x + this.boxWidth && mouseY < this.y + this.height;
GuiUtils.drawContinuousTexturedBox(BUTTON_TEXTURES, this.x, this.y, 0, 46, this.boxWidth, this.height, 200, 20, 2, 3, 2, 2, this.zLevel);
this.mouseDragged(mc, mouseX, mouseY);
int color = 14737632;
if (packedFGColour != 0)
if (packedFGColor != 0)
{
color = packedFGColour;
color = packedFGColor;
}
else if (!this.enabled)
{
@ -68,15 +69,9 @@ public class GuiCheckBox extends GuiButton
}
@Override
public boolean mousePressed(Minecraft mc, int mouseX, int mouseY)
public void func_194829_a(double mouseX, double mouseY)
{
if (this.enabled && this.visible && mouseX >= this.x && mouseY >= this.y && mouseX < this.x + this.width && mouseY < this.y + this.height)
{
this.isChecked = !this.isChecked;
return true;
}
return false;
this.isChecked = !this.isChecked;
}
public boolean isChecked()

View File

@ -1,386 +0,0 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2018.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.fml.client.config;
import static net.minecraftforge.fml.client.config.GuiUtils.RESET_CHAR;
import static net.minecraftforge.fml.client.config.GuiUtils.UNDO_CHAR;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.resources.I18n;
import net.minecraft.util.text.TextComponentString;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.client.config.GuiConfigEntries.IConfigEntry;
import net.minecraftforge.fml.client.event.ConfigChangedEvent;
import net.minecraftforge.fml.client.event.ConfigChangedEvent.OnConfigChangedEvent;
import net.minecraftforge.fml.client.event.ConfigChangedEvent.PostConfigChangedEvent;
import net.minecraftforge.fml.common.Loader;
import net.minecraftforge.eventbus.api.Event.Result;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.lwjgl.input.Keyboard;
import javax.annotation.Nullable;
/**
* This class is the base GuiScreen for all config GUI screens. It can be extended by mods to provide the top-level config screen
* that will be called when the Config button is clicked from the Main Menu Mods list.
*
* @author bspkrs
*/
public class GuiConfig extends GuiScreen
{
private static final Logger LOGGER = LogManager.getLogger();
/**
* A reference to the screen object that created this. Used for navigating between screens.
*/
public final GuiScreen parentScreen;
public String title = "Config GUI";
@Nullable
public String titleLine2;
public final List<IConfigElement> configElements;
public final List<IConfigEntry> initEntries;
public GuiConfigEntries entryList;
protected GuiButtonExt btnDefaultAll;
protected GuiButtonExt btnUndoAll;
protected GuiCheckBox chkApplyGlobally;
public final String modID;
/**
* When set to a non-null value the OnConfigChanged and PostConfigChanged events will be posted when the Done button is pressed
* if any configElements were changed (includes child screens). If not defined, the events will be posted if the parent gui is null
* or if the parent gui is not an instance of GuiConfig.
*/
@Nullable
public final String configID;
public final boolean isWorldRunning;
public final boolean allRequireWorldRestart;
public final boolean allRequireMcRestart;
public boolean needsRefresh = true;
protected HoverChecker undoHoverChecker;
protected HoverChecker resetHoverChecker;
protected HoverChecker checkBoxHoverChecker;
/**
* GuiConfig constructor that will use ConfigChangedEvent when editing is concluded. If a non-null value is passed for configID,
* the OnConfigChanged and PostConfigChanged events will be posted when the Done button is pressed if any configElements were changed
* (includes child screens). If configID is not defined, the events will be posted if the parent gui is null or if the parent gui
* is not an instance of GuiConfig.
*
* @param parentScreen the parent GuiScreen object
* @param configElements a List of IConfigElement objects
* @param modID the mod ID for the mod whose config settings will be edited
* @param configID an identifier that will be passed to the OnConfigChanged and PostConfigChanged events. Setting this value will force
* the save action to be called when the Done button is pressed on this screen if any configElements were changed.
* @param allRequireWorldRestart send true if all configElements on this screen require a world restart
* @param allRequireMcRestart send true if all configElements on this screen require MC to be restarted
* @param title the desired title for this screen. For consistency it is recommended that you pass the path of the config file being
* edited.
*/
public GuiConfig(GuiScreen parentScreen, List<IConfigElement> configElements, String modID, String configID,
boolean allRequireWorldRestart, boolean allRequireMcRestart, String title)
{
this(parentScreen, configElements, modID, configID, allRequireWorldRestart, allRequireMcRestart, title, null);
}
/**
* GuiConfig constructor that will use ConfigChangedEvent when editing is concluded. This constructor passes null for configID.
* If configID is not defined, the events will be posted if the parent gui is null or if the parent gui is not an instance of GuiConfig.
*
* @param parentScreen the parent GuiScreen object
* @param configElements a List of IConfigElement objects
* @param modID the mod ID for the mod whose config settings will be edited
* @param allRequireWorldRestart send true if all configElements on this screen require a world restart
* @param allRequireMcRestart send true if all configElements on this screen require MC to be restarted
* @param title the desired title for this screen. For consistency it is recommended that you pass the path of the config file being
* edited.
*/
public GuiConfig(GuiScreen parentScreen, List<IConfigElement> configElements, String modID,
boolean allRequireWorldRestart, boolean allRequireMcRestart, String title)
{
this(parentScreen, configElements, modID, null, allRequireWorldRestart, allRequireMcRestart, title, null);
}
/**
* GuiConfig constructor that will use ConfigChangedEvent when editing is concluded. This constructor passes null for configID.
* If configID is not defined, the events will be posted if the parent gui is null or if the parent gui is not an instance of GuiConfig.
*
* @param parentScreen the parent GuiScreen object
* @param configElements a List of IConfigElement objects
* @param modID the mod ID for the mod whose config settings will be edited
* @param allRequireWorldRestart send true if all configElements on this screen require a world restart
* @param allRequireMcRestart send true if all configElements on this screen require MC to be restarted
* @param title the desired title for this screen. For consistency it is recommended that you pass the path of the config file being
* edited.
* @param titleLine2 the desired title second line for this screen. Typically this is used to send the category name of the category
* currently being edited.
*/
public GuiConfig(GuiScreen parentScreen, List<IConfigElement> configElements, String modID,
boolean allRequireWorldRestart, boolean allRequireMcRestart, String title, String titleLine2)
{
this(parentScreen, configElements, modID, null, allRequireWorldRestart, allRequireMcRestart, title, titleLine2);
}
/**
* GuiConfig constructor that will use ConfigChangedEvent when editing is concluded. titleLine2 is specified in this constructor.
* If a non-null value is passed for configID, the OnConfigChanged and PostConfigChanged events will be posted when the Done button is
* pressed if any configElements were changed (includes child screens). If configID is not defined, the events will be posted if the parent
* gui is null or if the parent gui is not an instance of GuiConfig.
*
* @param parentScreen the parent GuiScreen object
* @param configElements a List of IConfigElement objects
* @param modID the mod ID for the mod whose config settings will be edited
* @param configID an identifier that will be passed to the OnConfigChanged and PostConfigChanged events
* @param allRequireWorldRestart send true if all configElements on this screen require a world restart
* @param allRequireMcRestart send true if all configElements on this screen require MC to be restarted
* @param title the desired title for this screen. For consistency it is recommended that you pass the path of the config file being
* edited.
* @param titleLine2 the desired title second line for this screen. Typically this is used to send the category name of the category
* currently being edited.
*/
public GuiConfig(GuiScreen parentScreen, List<IConfigElement> configElements, String modID, @Nullable String configID,
boolean allRequireWorldRestart, boolean allRequireMcRestart, String title, @Nullable String titleLine2)
{
this.mc = Minecraft.getMinecraft();
this.parentScreen = parentScreen;
this.configElements = configElements;
this.entryList = new GuiConfigEntries(this, mc);
this.initEntries = new ArrayList<>(entryList.listEntries);
this.allRequireWorldRestart = allRequireWorldRestart;
IF:if (!allRequireWorldRestart)
{
for (IConfigElement element : configElements)
{
if (!element.requiresWorldRestart());
break IF;
}
allRequireWorldRestart = true;
}
this.allRequireMcRestart = allRequireMcRestart;
IF:if (!allRequireMcRestart)
{
for (IConfigElement element : configElements)
{
if (!element.requiresMcRestart());
break IF;
}
allRequireMcRestart = true;
}
this.modID = modID;
this.configID = configID;
this.isWorldRunning = mc.world != null;
if (title != null)
this.title = title;
this.titleLine2 = titleLine2;
if (this.titleLine2 != null && this.titleLine2.startsWith(" > "))
this.titleLine2 = this.titleLine2.replaceFirst(" > ", "");
}
public static String getAbridgedConfigPath(String path)
{
Minecraft mc = Minecraft.getMinecraft();
if (mc.mcDataDir.getAbsolutePath().endsWith("."))
return path.replace("\\", "/").replace(mc.mcDataDir.getAbsolutePath().replace("\\", "/").substring(0, mc.mcDataDir.getAbsolutePath().length() - 1), "/.minecraft/");
else
return path.replace("\\", "/").replace(mc.mcDataDir.getAbsolutePath().replace("\\", "/"), "/.minecraft");
}
@Override
public void initGui()
{
Keyboard.enableRepeatEvents(true);
if (this.entryList == null || this.needsRefresh)
{
this.entryList = new GuiConfigEntries(this, mc);
this.needsRefresh = false;
}
int undoGlyphWidth = mc.fontRenderer.getStringWidth(UNDO_CHAR) * 2;
int resetGlyphWidth = mc.fontRenderer.getStringWidth(RESET_CHAR) * 2;
int doneWidth = Math.max(mc.fontRenderer.getStringWidth(I18n.format("gui.done")) + 20, 100);
int undoWidth = mc.fontRenderer.getStringWidth(" " + I18n.format("fml.configgui.tooltip.undoChanges")) + undoGlyphWidth + 20;
int resetWidth = mc.fontRenderer.getStringWidth(" " + I18n.format("fml.configgui.tooltip.resetToDefault")) + resetGlyphWidth + 20;
int checkWidth = mc.fontRenderer.getStringWidth(I18n.format("fml.configgui.applyGlobally")) + 13;
int buttonWidthHalf = (doneWidth + 5 + undoWidth + 5 + resetWidth + 5 + checkWidth) / 2;
this.buttonList.add(new GuiButtonExt(2000, this.width / 2 - buttonWidthHalf, this.height - 29, doneWidth, 20, I18n.format("gui.done")));
this.buttonList.add(this.btnDefaultAll = new GuiUnicodeGlyphButton(2001, this.width / 2 - buttonWidthHalf + doneWidth + 5 + undoWidth + 5,
this.height - 29, resetWidth, 20, " " + I18n.format("fml.configgui.tooltip.resetToDefault"), RESET_CHAR, 2.0F));
this.buttonList.add(btnUndoAll = new GuiUnicodeGlyphButton(2002, this.width / 2 - buttonWidthHalf + doneWidth + 5,
this.height - 29, undoWidth, 20, " " + I18n.format("fml.configgui.tooltip.undoChanges"), UNDO_CHAR, 2.0F));
this.buttonList.add(chkApplyGlobally = new GuiCheckBox(2003, this.width / 2 - buttonWidthHalf + doneWidth + 5 + undoWidth + 5 + resetWidth + 5,
this.height - 24, I18n.format("fml.configgui.applyGlobally"), false));
this.undoHoverChecker = new HoverChecker(this.btnUndoAll, 800);
this.resetHoverChecker = new HoverChecker(this.btnDefaultAll, 800);
this.checkBoxHoverChecker = new HoverChecker(chkApplyGlobally, 800);
this.entryList.initGui();
}
@Override
public void onGuiClosed()
{
this.entryList.onGuiClosed();
if (this.configID != null && this.parentScreen instanceof GuiConfig)
{
GuiConfig parentGuiConfig = (GuiConfig) this.parentScreen;
parentGuiConfig.needsRefresh = true;
parentGuiConfig.initGui();
}
if (!(this.parentScreen instanceof GuiConfig))
Keyboard.enableRepeatEvents(false);
}
@Override
protected void actionPerformed(GuiButton button)
{
if (button.id == 2000)
{
boolean flag = true;
try
{
if ((configID != null || this.parentScreen == null || !(this.parentScreen instanceof GuiConfig))
&& (this.entryList.hasChangedEntry(true)))
{
boolean requiresMcRestart = this.entryList.saveConfigElements();
if (Loader.isModLoaded(modID))
{
ConfigChangedEvent event = new OnConfigChangedEvent(modID, configID, isWorldRunning, requiresMcRestart);
MinecraftForge.EVENT_BUS.post(event);
if (!event.getResult().equals(Result.DENY))
MinecraftForge.EVENT_BUS.post(new PostConfigChangedEvent(modID, configID, isWorldRunning, requiresMcRestart));
if (requiresMcRestart)
{
flag = false;
mc.displayGuiScreen(new GuiMessageDialog(parentScreen, "fml.configgui.gameRestartTitle",
new TextComponentString(I18n.format("fml.configgui.gameRestartRequired")), "fml.configgui.confirmRestartMessage"));
}
if (this.parentScreen instanceof GuiConfig)
((GuiConfig) this.parentScreen).needsRefresh = true;
}
}
}
catch (Throwable e)
{
LOGGER.error("Error performing GuiConfig action:", e);
}
if (flag)
this.mc.displayGuiScreen(this.parentScreen);
}
else if (button.id == 2001)
{
this.entryList.setAllToDefault(this.chkApplyGlobally.isChecked());
}
else if (button.id == 2002)
{
this.entryList.undoAllChanges(this.chkApplyGlobally.isChecked());
}
}
@Override
public void handleMouseInput() throws IOException
{
super.handleMouseInput();
this.entryList.handleMouseInput();
}
@Override
protected void mouseClicked(int x, int y, int mouseEvent) throws IOException
{
if (mouseEvent != 0 || !this.entryList.mouseClicked(x, y, mouseEvent))
{
this.entryList.mouseClickedPassThru(x, y, mouseEvent);
super.mouseClicked(x, y, mouseEvent);
}
}
@Override
protected void mouseReleased(int x, int y, int mouseEvent)
{
if (mouseEvent != 0 || !this.entryList.mouseReleased(x, y, mouseEvent))
{
super.mouseReleased(x, y, mouseEvent);
}
}
@Override
protected void keyTyped(char eventChar, int eventKey)
{
if (eventKey == Keyboard.KEY_ESCAPE)
this.mc.displayGuiScreen(parentScreen);
else
this.entryList.keyTyped(eventChar, eventKey);
}
@Override
public void updateScreen()
{
super.updateScreen();
this.entryList.updateScreen();
}
@Override
public void drawScreen(int mouseX, int mouseY, float partialTicks)
{
this.drawDefaultBackground();
this.entryList.drawScreen(mouseX, mouseY, partialTicks);
this.drawCenteredString(this.fontRenderer, this.title, this.width / 2, 8, 16777215);
String title2 = this.titleLine2;
if (title2 != null)
{
int strWidth = mc.fontRenderer.getStringWidth(title2);
int ellipsisWidth = mc.fontRenderer.getStringWidth("...");
if (strWidth > width - 6 && strWidth > ellipsisWidth)
title2 = mc.fontRenderer.trimStringToWidth(title2, width - 6 - ellipsisWidth).trim() + "...";
this.drawCenteredString(this.fontRenderer, title2, this.width / 2, 18, 16777215);
}
this.btnUndoAll.enabled = this.entryList.areAnyEntriesEnabled(this.chkApplyGlobally.isChecked()) && this.entryList.hasChangedEntry(this.chkApplyGlobally.isChecked());
this.btnDefaultAll.enabled = this.entryList.areAnyEntriesEnabled(this.chkApplyGlobally.isChecked()) && !this.entryList.areAllEntriesDefault(this.chkApplyGlobally.isChecked());
super.drawScreen(mouseX, mouseY, partialTicks);
this.entryList.drawScreenPost(mouseX, mouseY, partialTicks);
if (this.undoHoverChecker.checkHover(mouseX, mouseY))
this.drawToolTip(Arrays.asList(I18n.format("fml.configgui.tooltip.undoAll").split("\n")), mouseX, mouseY);
if (this.resetHoverChecker.checkHover(mouseX, mouseY))
this.drawToolTip(Arrays.asList(I18n.format("fml.configgui.tooltip.resetAll").split("\n")), mouseX, mouseY);
if (this.checkBoxHoverChecker.checkHover(mouseX, mouseY))
this.drawToolTip(Arrays.asList(I18n.format("fml.configgui.tooltip.applyGlobally").split("\n")), mouseX, mouseY);
}
public void drawToolTip(List<String> stringList, int x, int y)
{
GuiUtils.drawHoveringText(stringList, x, y, width, height, 300, fontRenderer);
}
}

View File

@ -1,225 +0,0 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2018.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.fml.client.config;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.resources.I18n;
import net.minecraft.util.text.TextFormatting;
import static net.minecraftforge.fml.client.config.GuiUtils.RESET_CHAR;
import static net.minecraftforge.fml.client.config.GuiUtils.UNDO_CHAR;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.lwjgl.input.Keyboard;
/**
* This class is the base screen used for editing an array-type property. It provides a list of array entries for the user to edit.
* This screen is invoked from a GuiConfig screen by controls that use the EditListPropEntry IGuiConfigListEntry object.
*
* @author bspkrs
*/
public class GuiEditArray extends GuiScreen
{
private static final Logger LOGGER = LogManager.getLogger();
protected GuiScreen parentScreen;
protected IConfigElement configElement;
protected GuiEditArrayEntries entryList;
protected GuiButtonExt btnUndoChanges, btnDefault, btnDone;
protected String title;
protected String titleLine2;
protected String titleLine3;
protected int slotIndex;
protected final Object[] beforeValues;
protected Object[] currentValues;
protected HoverChecker tooltipHoverChecker;
protected List<String> toolTip;
protected boolean enabled;
public GuiEditArray(GuiScreen parentScreen, IConfigElement configElement, int slotIndex, Object[] currentValues, boolean enabled)
{
this.mc = Minecraft.getMinecraft();
this.parentScreen = parentScreen;
this.configElement = configElement;
this.slotIndex = slotIndex;
this.beforeValues = currentValues;
this.currentValues = currentValues;
this.toolTip = new ArrayList<String>();
this.enabled = enabled;
String propName = I18n.format(configElement.getLanguageKey());
String comment;
comment = I18n.format(configElement.getLanguageKey() + ".tooltip",
"\n" + TextFormatting.AQUA, configElement.getDefault(), configElement.getMinValue(), configElement.getMaxValue());
if (!comment.equals(configElement.getLanguageKey() + ".tooltip"))
Collections.addAll(toolTip, (TextFormatting.GREEN + propName + "\n" + TextFormatting.YELLOW + comment).split("\n"));
else if (configElement.getComment() != null && !configElement.getComment().trim().isEmpty())
Collections.addAll(toolTip, (TextFormatting.GREEN + propName + "\n" + TextFormatting.YELLOW + configElement.getComment()).split("\n"));
else
Collections.addAll(toolTip, (TextFormatting.GREEN + propName + "\n" + TextFormatting.RED + "No tooltip defined.").split("\n"));
if (parentScreen instanceof GuiConfig)
{
this.title = ((GuiConfig) parentScreen).title;
if (((GuiConfig) parentScreen).titleLine2 != null)
{
this.titleLine2 = ((GuiConfig) parentScreen).titleLine2;
this.titleLine3 = I18n.format(configElement.getLanguageKey());
}
else
this.titleLine2 = I18n.format(configElement.getLanguageKey());
this.tooltipHoverChecker = new HoverChecker(28, 37, 0, parentScreen.width, 800);
}
else
{
this.title = I18n.format(configElement.getLanguageKey());
this.tooltipHoverChecker = new HoverChecker(8, 17, 0, parentScreen.width, 800);
}
}
@Override
public void initGui()
{
this.entryList = createEditArrayEntries();
int undoGlyphWidth = mc.fontRenderer.getStringWidth(UNDO_CHAR) * 2;
int resetGlyphWidth = mc.fontRenderer.getStringWidth(RESET_CHAR) * 2;
int doneWidth = Math.max(mc.fontRenderer.getStringWidth(I18n.format("gui.done")) + 20, 100);
int undoWidth = mc.fontRenderer.getStringWidth(" " + I18n.format("fml.configgui.tooltip.undoChanges")) + undoGlyphWidth + 20;
int resetWidth = mc.fontRenderer.getStringWidth(" " + I18n.format("fml.configgui.tooltip.resetToDefault")) + resetGlyphWidth + 20;
int buttonWidthHalf = (doneWidth + 5 + undoWidth + 5 + resetWidth) / 2;
this.buttonList.add(btnDone = new GuiButtonExt(2000, this.width / 2 - buttonWidthHalf, this.height - 29, doneWidth, 20, I18n.format("gui.done")));
this.buttonList.add(btnDefault = new GuiUnicodeGlyphButton(2001, this.width / 2 - buttonWidthHalf + doneWidth + 5 + undoWidth + 5,
this.height - 29, resetWidth, 20, " " + I18n.format("fml.configgui.tooltip.resetToDefault"), RESET_CHAR, 2.0F));
this.buttonList.add(btnUndoChanges = new GuiUnicodeGlyphButton(2002, this.width / 2 - buttonWidthHalf + doneWidth + 5,
this.height - 29, undoWidth, 20, " " + I18n.format("fml.configgui.tooltip.undoChanges"), UNDO_CHAR, 2.0F));
}
@Override
protected void actionPerformed(GuiButton button)
{
if (button.id == 2000)
{
try
{
this.entryList.saveListChanges();
}
catch (Throwable e)
{
LOGGER.error("Error performing GuiEditArray action:", e);
}
this.mc.displayGuiScreen(this.parentScreen);
}
else if (button.id == 2001)
{
this.currentValues = configElement.getDefaults();
this.entryList = createEditArrayEntries();
}
else if (button.id == 2002)
{
this.currentValues = Arrays.copyOf(beforeValues, beforeValues.length);
this.entryList = createEditArrayEntries();
}
}
protected GuiEditArrayEntries createEditArrayEntries()
{
return new GuiEditArrayEntries(this, this.mc, this.configElement, this.beforeValues, this.currentValues);
}
@Override
public void handleMouseInput() throws IOException
{
super.handleMouseInput();
this.entryList.handleMouseInput();
}
@Override
protected void mouseClicked(int x, int y, int mouseEvent) throws IOException
{
if (mouseEvent != 0 || !this.entryList.mouseClicked(x, y, mouseEvent))
{
this.entryList.mouseClickedPassThru(x, y, mouseEvent);
super.mouseClicked(x, y, mouseEvent);
}
}
@Override
protected void mouseReleased(int x, int y, int mouseEvent)
{
if (mouseEvent != 0 || !this.entryList.mouseReleased(x, y, mouseEvent))
{
super.mouseReleased(x, y, mouseEvent);
}
}
@Override
protected void keyTyped(char eventChar, int eventKey)
{
if (eventKey == Keyboard.KEY_ESCAPE)
this.mc.displayGuiScreen(parentScreen);
else
this.entryList.keyTyped(eventChar, eventKey);
}
@Override
public void updateScreen()
{
super.updateScreen();
this.entryList.updateScreen();
}
@Override
public void drawScreen(int par1, int par2, float par3)
{
this.drawDefaultBackground();
this.entryList.drawScreen(par1, par2, par3);
this.drawCenteredString(this.fontRenderer, this.title, this.width / 2, 8, 16777215);
if (this.titleLine2 != null)
this.drawCenteredString(this.fontRenderer, this.titleLine2, this.width / 2, 18, 16777215);
if (this.titleLine3 != null)
this.drawCenteredString(this.fontRenderer, this.titleLine3, this.width / 2, 28, 16777215);
this.btnDone.enabled = this.entryList.isListSavable();
this.btnDefault.enabled = enabled && !this.entryList.isDefault();
this.btnUndoChanges.enabled = enabled && this.entryList.isChanged();
super.drawScreen(par1, par2, par3);
this.entryList.drawScreenPost(par1, par2, par3);
if (this.tooltipHoverChecker != null && this.tooltipHoverChecker.checkHover(par1, par2))
drawToolTip(this.toolTip, par1, par2);
}
public void drawToolTip(List<String> stringList, int x, int y)
{
GuiUtils.drawHoveringText(stringList, x, y, width, height, 300, fontRenderer);
}
}

View File

@ -1,709 +0,0 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2018.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.fml.client.config;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiListExtended;
import net.minecraft.client.gui.GuiTextField;
import net.minecraft.client.resources.I18n;
import net.minecraft.util.text.TextFormatting;
import net.minecraftforge.fml.client.config.GuiConfigEntries.ArrayEntry;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.lwjgl.input.Keyboard;
import static net.minecraftforge.fml.client.config.GuiUtils.INVALID;
import static net.minecraftforge.fml.client.config.GuiUtils.VALID;
/**
* This class implements the scrolling list functionality of the GuiEditList screen. It also provides all the default controls
* for editing array-type properties.
*/
public class GuiEditArrayEntries extends GuiListExtended
{
private static final Logger LOGGER = LogManager.getLogger();
protected GuiEditArray owningGui;
public IConfigElement configElement;
public List<IArrayEntry> listEntries;
public boolean isDefault;
public boolean isChanged;
public boolean canAddMoreEntries;
public final int controlWidth;
public final Object[] beforeValues;
public Object[] currentValues;
public GuiEditArrayEntries(GuiEditArray parent, Minecraft mc, IConfigElement configElement, Object[] beforeValues, Object[] currentValues)
{
super(mc, parent.width, parent.height, parent.titleLine2 != null ? (parent.titleLine3 != null ? 43 : 33) : 23, parent.height - 32, 20);
this.owningGui = parent;
this.configElement = configElement;
this.beforeValues = beforeValues;
this.currentValues = currentValues;
this.setShowSelectionBox(false);
this.isChanged = !Arrays.deepEquals(beforeValues, currentValues);
this.isDefault = Arrays.deepEquals(currentValues, configElement.getDefaults());
this.canAddMoreEntries = !configElement.isListLengthFixed() && (configElement.getMaxListLength() == -1 || currentValues.length < configElement.getMaxListLength());
listEntries = new ArrayList<IArrayEntry>();
controlWidth = (parent.width / 2) - (configElement.isListLengthFixed() ? 0 : 48);
if (configElement.isList() && configElement.getArrayEntryClass() != null)
{
Class<? extends IArrayEntry> clazz = configElement.getArrayEntryClass();
for (Object value : currentValues)
{
try
{
listEntries.add(clazz.getConstructor(GuiEditArray.class, GuiEditArrayEntries.class, IConfigElement.class, Object.class)
.newInstance(this.owningGui, this, configElement, value));
}
catch (Throwable e)
{
LOGGER.error("There was a critical error instantiating the custom IGuiEditListEntry for property {}.", configElement.getName(), e);
}
}
}
else if (configElement.isList() && configElement.getType().equals(ConfigGuiType.BOOLEAN))
for (Object value : currentValues)
listEntries.add(new BooleanEntry(this.owningGui, this, configElement, Boolean.valueOf(value.toString())));
else if (configElement.isList() && configElement.getType().equals(ConfigGuiType.INTEGER))
for (Object value : currentValues)
listEntries.add(new IntegerEntry(this.owningGui, this, configElement, Integer.parseInt(value.toString())));
else if (configElement.isList() && configElement.getType().equals(ConfigGuiType.DOUBLE))
for (Object value : currentValues)
listEntries.add(new DoubleEntry(this.owningGui, this, configElement, Double.parseDouble(value.toString())));
else if (configElement.isList())
for (Object value : currentValues)
listEntries.add(new StringEntry(this.owningGui, this, configElement, value.toString()));
if (!configElement.isListLengthFixed())
listEntries.add(new BaseEntry(this.owningGui, this, configElement));
}
@Override
protected int getScrollBarX()
{
return width - (width / 4);
}
/**
* Gets the width of the list
*/
@Override
public int getListWidth()
{
return owningGui.width;
}
@Override
public IArrayEntry getListEntry(int index)
{
return listEntries.get(index);
}
@Override
protected int getSize()
{
return listEntries.size();
}
public void addNewEntry(int index)
{
if (configElement.isList() && configElement.getArrayEntryClass() != null)
{
Class<? extends IArrayEntry> clazz = configElement.getArrayEntryClass();
try
{
Object value;
switch (configElement.getType())
{
case BOOLEAN:
value = true;
break;
case INTEGER:
value = 0;
break;
case DOUBLE:
value = 0.0D;
break;
default:
value = "";
}
listEntries.add(index, clazz.getConstructor(GuiEditArray.class, GuiEditArrayEntries.class, IConfigElement.class, Object.class).newInstance(this.owningGui, this, configElement, value));
}
catch (Throwable e)
{
LOGGER.error("There was a critical error instantiating the custom IGuiEditListEntry for property {}.", configElement.getName(), e);
}
}
else if (configElement.isList() && configElement.getType() == ConfigGuiType.BOOLEAN)
listEntries.add(index, new BooleanEntry(this.owningGui, this, this.configElement, true));
else if (configElement.isList() && configElement.getType() == ConfigGuiType.INTEGER)
listEntries.add(index, new IntegerEntry(this.owningGui, this, this.configElement, 0));
else if (configElement.isList() && configElement.getType() == ConfigGuiType.DOUBLE)
listEntries.add(index, new DoubleEntry(this.owningGui, this, this.configElement, 0.0D));
else if (configElement.isList())
listEntries.add(index, new StringEntry(this.owningGui, this, this.configElement, ""));
this.canAddMoreEntries = !configElement.isListLengthFixed()
&& (configElement.getMaxListLength() == -1 || this.listEntries.size() - 1 < configElement.getMaxListLength());
keyTyped((char) Keyboard.CHAR_NONE, Keyboard.KEY_END);
}
public void removeEntry(int index)
{
this.listEntries.remove(index);
this.canAddMoreEntries = !configElement.isListLengthFixed()
&& (configElement.getMaxListLength() == -1 || this.listEntries.size() - 1 < configElement.getMaxListLength());
keyTyped((char) Keyboard.CHAR_NONE, Keyboard.KEY_END);
}
public boolean isChanged()
{
return isChanged;
}
public boolean isDefault()
{
return isDefault;
}
public void recalculateState()
{
isDefault = true;
isChanged = false;
int listLength = configElement.isListLengthFixed() ? listEntries.size() : listEntries.size() - 1;
if (listLength != configElement.getDefaults().length)
{
isDefault = false;
}
if (listLength != beforeValues.length)
{
isChanged = true;
}
if (isDefault)
for (int i = 0; i < listLength; i++)
if (!configElement.getDefaults()[i].equals(listEntries.get(i).getValue()))
isDefault = false;
if (!isChanged)
for (int i = 0; i < listLength; i++)
if (!beforeValues[i].equals(listEntries.get(i).getValue()))
isChanged = true;
}
protected void keyTyped(char eventChar, int eventKey)
{
for (IArrayEntry entry : this.listEntries)
entry.keyTyped(eventChar, eventKey);
recalculateState();
}
protected void updateScreen()
{
for (IArrayEntry entry : this.listEntries)
entry.updateCursorCounter();
}
protected void mouseClickedPassThru(int x, int y, int mouseEvent)
{
for (IArrayEntry entry : this.listEntries)
entry.mouseClicked(x, y, mouseEvent);
}
protected boolean isListSavable()
{
for (IArrayEntry entry : this.listEntries)
if (!entry.isValueSavable())
return false;
return true;
}
protected void saveListChanges()
{
int listLength = configElement.isListLengthFixed() ? listEntries.size() : listEntries.size() - 1;
if (owningGui.slotIndex != -1 && owningGui.parentScreen != null
&& owningGui.parentScreen instanceof GuiConfig
&& ((GuiConfig) owningGui.parentScreen).entryList.getListEntry(owningGui.slotIndex) instanceof ArrayEntry)
{
ArrayEntry entry = (ArrayEntry) ((GuiConfig) owningGui.parentScreen).entryList.getListEntry(owningGui.slotIndex);
Object[] ao = new Object[listLength];
for (int i = 0; i < listLength; i++)
ao[i] = listEntries.get(i).getValue();
entry.setListFromChildScreen(ao);
}
else
{
if (configElement.isList() && configElement.getType() == ConfigGuiType.BOOLEAN)
{
Boolean[] abol = new Boolean[listLength];
for (int i = 0; i < listLength; i++)
abol[i] = Boolean.valueOf(listEntries.get(i).getValue().toString());
configElement.set(abol);
}
else if (configElement.isList() && configElement.getType() == ConfigGuiType.INTEGER)
{
Integer[] ai = new Integer[listLength];
for (int i = 0; i < listLength; i++)
ai[i] = Integer.valueOf(listEntries.get(i).getValue().toString());
configElement.set(ai);
}
else if (configElement.isList() && configElement.getType() == ConfigGuiType.DOUBLE)
{
Double[] ad = new Double[listLength];
for (int i = 0; i < listLength; i++)
ad[i] = Double.valueOf(listEntries.get(i).getValue().toString());
configElement.set(ad);
}
else if (configElement.isList())
{
String[] as = new String[listLength];
for (int i = 0; i < listLength; i++)
as[i] = listEntries.get(i).getValue().toString();
configElement.set(as);
}
}
}
protected void drawScreenPost(int mouseX, int mouseY, float f)
{
for (IArrayEntry entry : this.listEntries)
entry.drawToolTip(mouseX, mouseY);
}
public Minecraft getMC()
{
return this.mc;
}
/**
* IGuiListEntry Inner Classes
*/
public static class DoubleEntry extends StringEntry
{
public DoubleEntry(GuiEditArray owningScreen, GuiEditArrayEntries owningEntryList, IConfigElement configElement, Double value)
{
super(owningScreen, owningEntryList, configElement, value);
this.isValidated = true;
}
@Override
public void keyTyped(char eventChar, int eventKey)
{
if (owningScreen.enabled || eventKey == Keyboard.KEY_LEFT || eventKey == Keyboard.KEY_RIGHT
|| eventKey == Keyboard.KEY_HOME || eventKey == Keyboard.KEY_END)
{
String validChars = "0123456789";
String before = this.textFieldValue.getText();
if (validChars.contains(String.valueOf(eventChar)) ||
(!before.startsWith("-") && this.textFieldValue.getCursorPosition() == 0 && eventChar == '-')
|| (!before.contains(".") && eventChar == '.')
|| eventKey == Keyboard.KEY_BACK || eventKey == Keyboard.KEY_DELETE || eventKey == Keyboard.KEY_LEFT || eventKey == Keyboard.KEY_RIGHT
|| eventKey == Keyboard.KEY_HOME || eventKey == Keyboard.KEY_END)
this.textFieldValue.textboxKeyTyped((owningScreen.enabled ? eventChar : Keyboard.CHAR_NONE), eventKey);
if (!textFieldValue.getText().trim().isEmpty() && !textFieldValue.getText().trim().equals("-"))
{
try
{
double value = Double.parseDouble(textFieldValue.getText().trim());
if (value < Double.valueOf(configElement.getMinValue().toString()) || value > Double.valueOf(configElement.getMaxValue().toString()))
this.isValidValue = false;
else
this.isValidValue = true;
}
catch (Throwable e)
{
this.isValidValue = false;
}
}
else
this.isValidValue = false;
}
}
@Override
public Double getValue()
{
try
{
return Double.valueOf(this.textFieldValue.getText().trim());
}
catch (Throwable e)
{
return Double.MAX_VALUE;
}
}
}
public static class IntegerEntry extends StringEntry
{
public IntegerEntry(GuiEditArray owningScreen, GuiEditArrayEntries owningEntryList, IConfigElement configElement, Integer value)
{
super(owningScreen, owningEntryList, configElement, value);
this.isValidated = true;
}
@Override
public void keyTyped(char eventChar, int eventKey)
{
if (owningScreen.enabled || eventKey == Keyboard.KEY_LEFT || eventKey == Keyboard.KEY_RIGHT
|| eventKey == Keyboard.KEY_HOME || eventKey == Keyboard.KEY_END)
{
String validChars = "0123456789";
String before = this.textFieldValue.getText();
if (validChars.contains(String.valueOf(eventChar))
|| (!before.startsWith("-") && this.textFieldValue.getCursorPosition() == 0 && eventChar == '-')
|| eventKey == Keyboard.KEY_BACK || eventKey == Keyboard.KEY_DELETE
|| eventKey == Keyboard.KEY_LEFT || eventKey == Keyboard.KEY_RIGHT || eventKey == Keyboard.KEY_HOME || eventKey == Keyboard.KEY_END)
this.textFieldValue.textboxKeyTyped((owningScreen.enabled ? eventChar : Keyboard.CHAR_NONE), eventKey);
if (!textFieldValue.getText().trim().isEmpty() && !textFieldValue.getText().trim().equals("-"))
{
try
{
long value = Long.parseLong(textFieldValue.getText().trim());
if (value < Integer.valueOf(configElement.getMinValue().toString()) || value > Integer.valueOf(configElement.getMaxValue().toString()))
this.isValidValue = false;
else
this.isValidValue = true;
}
catch (Throwable e)
{
this.isValidValue = false;
}
}
else
this.isValidValue = false;
}
}
@Override
public Integer getValue()
{
try
{
return Integer.valueOf(this.textFieldValue.getText().trim());
}
catch (Throwable e)
{
return Integer.MAX_VALUE;
}
}
}
public static class StringEntry extends BaseEntry
{
protected final GuiTextField textFieldValue;
public StringEntry(GuiEditArray owningScreen, GuiEditArrayEntries owningEntryList, IConfigElement configElement, Object value)
{
super(owningScreen, owningEntryList, configElement);
this.textFieldValue = new GuiTextField(0, owningEntryList.getMC().fontRenderer, owningEntryList.width / 4 + 1, 0, owningEntryList.controlWidth - 3, 16);
this.textFieldValue.setMaxStringLength(10000);
this.textFieldValue.setText(value.toString());
this.isValidated = configElement.getValidationPattern() != null;
if (configElement.getValidationPattern() != null)
{
if (configElement.getValidationPattern().matcher(this.textFieldValue.getText().trim()).matches())
isValidValue = true;
else
isValidValue = false;
}
}
@Override
public void drawEntry(int slotIndex, int x, int y, int listWidth, int slotHeight, int mouseX, int mouseY, boolean isSelected, float partial)
{
super.drawEntry(slotIndex, x, y, listWidth, slotHeight, mouseX, mouseY, isSelected, partial);
if (configElement.isListLengthFixed() || slotIndex != owningEntryList.listEntries.size() - 1)
{
this.textFieldValue.setVisible(true);
this.textFieldValue.y = y + 1;
this.textFieldValue.drawTextBox();
}
else
this.textFieldValue.setVisible(false);
}
@Override
public void keyTyped(char eventChar, int eventKey)
{
if (owningScreen.enabled || eventKey == Keyboard.KEY_LEFT || eventKey == Keyboard.KEY_RIGHT
|| eventKey == Keyboard.KEY_HOME || eventKey == Keyboard.KEY_END)
{
this.textFieldValue.textboxKeyTyped((owningScreen.enabled ? eventChar : Keyboard.CHAR_NONE), eventKey);
if (configElement.getValidationPattern() != null)
{
if (configElement.getValidationPattern().matcher(this.textFieldValue.getText().trim()).matches())
isValidValue = true;
else
isValidValue = false;
}
}
}
@Override
public void updateCursorCounter()
{
this.textFieldValue.updateCursorCounter();
}
@Override
public void mouseClicked(int x, int y, int mouseEvent)
{
this.textFieldValue.mouseClicked(x, y, mouseEvent);
}
@Override
public Object getValue()
{
return this.textFieldValue.getText().trim();
}
}
public static class BooleanEntry extends BaseEntry
{
protected final GuiButtonExt btnValue;
private boolean value;
public BooleanEntry(GuiEditArray owningScreen, GuiEditArrayEntries owningEntryList, IConfigElement configElement, boolean value)
{
super(owningScreen, owningEntryList, configElement);
this.value = value;
this.btnValue = new GuiButtonExt(0, 0, 0, owningEntryList.controlWidth, 18, I18n.format(String.valueOf(value)));
this.btnValue.enabled = owningScreen.enabled;
this.isValidated = false;
}
@Override
public void drawEntry(int slotIndex, int x, int y, int listWidth, int slotHeight, int mouseX, int mouseY, boolean isSelected, float partial)
{
super.drawEntry(slotIndex, x, y, listWidth, slotHeight, mouseX, mouseY, isSelected, partial);
this.btnValue.x = listWidth / 4;
this.btnValue.y = y;
String trans = I18n.format(String.valueOf(value));
if (!trans.equals(String.valueOf(value)))
this.btnValue.displayString = trans;
else
this.btnValue.displayString = String.valueOf(value);
btnValue.packedFGColour = value ? GuiUtils.getColorCode('2', true) : GuiUtils.getColorCode('4', true);
this.btnValue.drawButton(owningEntryList.getMC(), mouseX, mouseY, partial);
}
@Override
public boolean mousePressed(int index, int x, int y, int mouseEvent, int relativeX, int relativeY)
{
if (this.btnValue.mousePressed(owningEntryList.getMC(), x, y))
{
btnValue.playPressSound(owningEntryList.getMC().getSoundHandler());
value = !value;
owningEntryList.recalculateState();
return true;
}
return super.mousePressed(index, x, y, mouseEvent, relativeX, relativeY);
}
@Override
public void mouseReleased(int index, int x, int y, int mouseEvent, int relativeX, int relativeY)
{
this.btnValue.mouseReleased(x, y);
super.mouseReleased(index, x, y, mouseEvent, relativeX, relativeY);
}
@Override
public Object getValue()
{
return value;
}
}
public static class BaseEntry extends GuiListExtended.IGuiListEntry implements IArrayEntry
{
protected final GuiEditArray owningScreen;
protected final GuiEditArrayEntries owningEntryList;
protected final IConfigElement configElement;
protected final GuiButtonExt btnAddNewEntryAbove;
private final HoverChecker addNewEntryAboveHoverChecker;
protected final GuiButtonExt btnRemoveEntry;
private final HoverChecker removeEntryHoverChecker;
private List<String> addNewToolTip, removeToolTip;
protected boolean isValidValue = true;
protected boolean isValidated = false;
public BaseEntry(GuiEditArray owningScreen, GuiEditArrayEntries owningEntryList, IConfigElement configElement)
{
this.owningScreen = owningScreen;
this.owningEntryList = owningEntryList;
this.configElement = configElement;
this.btnAddNewEntryAbove = new GuiButtonExt(0, 0, 0, 18, 18, "+");
this.btnAddNewEntryAbove.packedFGColour = GuiUtils.getColorCode('2', true);
this.btnAddNewEntryAbove.enabled = owningScreen.enabled;
this.btnRemoveEntry = new GuiButtonExt(0, 0, 0, 18, 18, "x");
this.btnRemoveEntry.packedFGColour = GuiUtils.getColorCode('c', true);
this.btnRemoveEntry.enabled = owningScreen.enabled;
this.addNewEntryAboveHoverChecker = new HoverChecker(this.btnAddNewEntryAbove, 800);
this.removeEntryHoverChecker = new HoverChecker(this.btnRemoveEntry, 800);
this.addNewToolTip = new ArrayList<String>();
this.removeToolTip = new ArrayList<String>();
addNewToolTip.add(I18n.format("fml.configgui.tooltip.addNewEntryAbove"));
removeToolTip.add(I18n.format("fml.configgui.tooltip.removeEntry"));
}
@Override
public void func_194999_a(int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isHovered, float partial)
{
if (this.getValue() != null && this.isValidated)
owningEntryList.getMC().fontRenderer.func_211126_b(
isValidValue ? TextFormatting.GREEN + VALID : TextFormatting.RED + INVALID,
entryWidth / 4 - owningEntryList.getMC().fontRenderer.getStringWidth(VALID) - 2,
entryHeight / 2 - owningEntryList.getMC().fontRenderer.FONT_HEIGHT / 2,
16777215);
int half = entryWidth / 2;
if (owningEntryList.canAddMoreEntries)
{
this.btnAddNewEntryAbove.visible = true;
this.btnAddNewEntryAbove.x = half + ((half / 2) - 44);
this.btnAddNewEntryAbove.y = this.func_195001_c();
this.btnAddNewEntryAbove.drawButton(owningEntryList.getMC(), mouseX, mouseY, partial);
}
else
this.btnAddNewEntryAbove.visible = false;
if (!configElement.isListLengthFixed() && this.field_195005_b != owningEntryList.listEntries.size() - 1)
{
this.btnRemoveEntry.visible = true;
this.btnRemoveEntry.x = half + ((half / 2) - 22);
this.btnRemoveEntry.y = this.func_195001_c();
this.btnRemoveEntry.drawButton(owningEntryList.getMC(), mouseX, mouseY, partial);
}
else
this.btnRemoveEntry.visible = false;
}
@Override
public void drawToolTip(int mouseX, int mouseY)
{
boolean canHover = mouseY < owningEntryList.bottom && mouseY > owningEntryList.top;
if (this.btnAddNewEntryAbove.visible && this.addNewEntryAboveHoverChecker.checkHover(mouseX, mouseY, canHover))
owningScreen.drawToolTip(this.addNewToolTip, mouseX, mouseY);
if (this.btnRemoveEntry.visible && this.removeEntryHoverChecker.checkHover(mouseX, mouseY, canHover))
owningScreen.drawToolTip(this.removeToolTip, mouseX, mouseY);
}
@Override
public boolean mousePressed(int index, int x, int y, int mouseEvent, int relativeX, int relativeY)
{
if (this.btnAddNewEntryAbove.mousePressed(owningEntryList.getMC(), x, y))
{
btnAddNewEntryAbove.playPressSound(owningEntryList.getMC().getSoundHandler());
owningEntryList.addNewEntry(index);
owningEntryList.recalculateState();
return true;
}
else if (this.btnRemoveEntry.mousePressed(owningEntryList.getMC(), x, y))
{
btnRemoveEntry.playPressSound(owningEntryList.getMC().getSoundHandler());
owningEntryList.removeEntry(index);
owningEntryList.recalculateState();
return true;
}
return false;
}
@Override
public void mouseReleased(int index, int x, int y, int mouseEvent, int relativeX, int relativeY)
{
this.btnAddNewEntryAbove.mouseReleased(x, y);
this.btnRemoveEntry.mouseReleased(x, y);
}
@Override
public void keyTyped(char eventChar, int eventKey)
{}
@Override
public void updateCursorCounter()
{}
@Override
public void mouseClicked(int x, int y, int mouseEvent)
{}
@Override
public boolean isValueSavable()
{
return isValidValue;
}
@Override
public Object getValue()
{
return null;
}
@Override
public void updatePosition(int p_178011_1_, int p_178011_2_, int p_178011_3_, float partial){}
}
public static interface IArrayEntry
{
void keyTyped(char eventChar, int eventKey);
void updateCursorCounter();
void mouseClicked(int x, int y, int mouseEvent);
void drawToolTip(int mouseX, int mouseY);
boolean isValueSavable();
Object getValue();
}
}

View File

@ -1,194 +0,0 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2018.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.fml.client.config;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.resources.I18n;
import net.minecraft.util.text.TextFormatting;
import static net.minecraftforge.fml.client.config.GuiUtils.RESET_CHAR;
import static net.minecraftforge.fml.client.config.GuiUtils.UNDO_CHAR;
/**
* This class provides a screen that allows the user to select a value from a list.
*
* @author bspkrs
*/
public class GuiSelectString extends GuiScreen
{
private static final Logger LOGGER = LogManager.getLogger();
protected GuiScreen parentScreen;
protected IConfigElement configElement;
protected GuiSelectStringEntries entryList;
protected GuiButtonExt btnUndoChanges, btnDefault, btnDone;
protected String title;
protected String titleLine2;
protected String titleLine3;
protected int slotIndex;
protected final Map<Object, String> selectableValues;
public final Object beforeValue;
public Object currentValue;
protected HoverChecker tooltipHoverChecker;
protected List<String> toolTip;
protected boolean enabled;
public GuiSelectString(GuiScreen parentScreen, IConfigElement configElement, int slotIndex, Map<Object, String> selectableValues, Object currentValue, boolean enabled)
{
this.mc = Minecraft.getMinecraft();
this.parentScreen = parentScreen;
this.configElement = configElement;
this.slotIndex = slotIndex;
this.selectableValues = selectableValues;
this.beforeValue = currentValue;
this.currentValue = currentValue;
this.toolTip = new ArrayList<String>();
this.enabled = enabled;
String propName = I18n.format(configElement.getLanguageKey());
String comment;
comment = I18n.format(configElement.getLanguageKey() + ".tooltip",
"\n" + TextFormatting.AQUA, configElement.getDefault(), configElement.getMinValue(), configElement.getMaxValue());
if (!comment.equals(configElement.getLanguageKey() + ".tooltip"))
Collections.addAll(toolTip, (TextFormatting.GREEN + propName + "\n" + TextFormatting.YELLOW + comment).split("\n"));
else if (configElement.getComment() != null && !configElement.getComment().trim().isEmpty())
Collections.addAll(toolTip, (TextFormatting.GREEN + propName + "\n" + TextFormatting.YELLOW + configElement.getComment()).split("\n"));
else
Collections.addAll(toolTip, (TextFormatting.GREEN + propName + "\n" + TextFormatting.RED + "No tooltip defined.").split("\n"));
if (parentScreen instanceof GuiConfig)
{
this.title = ((GuiConfig) parentScreen).title;
this.titleLine2 = ((GuiConfig) parentScreen).titleLine2;
this.titleLine3 = I18n.format(configElement.getLanguageKey());
this.tooltipHoverChecker = new HoverChecker(28, 37, 0, parentScreen.width, 800);
if(titleLine3 != null && titleLine2 == null)
{
((GuiConfig) parentScreen).titleLine2 = "";
this.titleLine2 = "";
}
}
else
{
this.title = I18n.format(configElement.getLanguageKey());
this.tooltipHoverChecker = new HoverChecker(8, 17, 0, parentScreen.width, 800);
}
}
@Override
public void initGui()
{
this.entryList = new GuiSelectStringEntries(this, this.mc, this.configElement, this.selectableValues);
int undoGlyphWidth = mc.fontRenderer.getStringWidth(UNDO_CHAR) * 2;
int resetGlyphWidth = mc.fontRenderer.getStringWidth(RESET_CHAR) * 2;
int doneWidth = Math.max(mc.fontRenderer.getStringWidth(I18n.format("gui.done")) + 20, 100);
int undoWidth = mc.fontRenderer.getStringWidth(" " + I18n.format("fml.configgui.tooltip.undoChanges")) + undoGlyphWidth + 20;
int resetWidth = mc.fontRenderer.getStringWidth(" " + I18n.format("fml.configgui.tooltip.resetToDefault")) + resetGlyphWidth + 20;
int buttonWidthHalf = (doneWidth + 5 + undoWidth + 5 + resetWidth) / 2;
this.buttonList.add(btnDone = new GuiButtonExt(2000, this.width / 2 - buttonWidthHalf, this.height - 29, doneWidth, 20, I18n.format("gui.done")));
this.buttonList.add(btnDefault = new GuiUnicodeGlyphButton(2001, this.width / 2 - buttonWidthHalf + doneWidth + 5 + undoWidth + 5,
this.height - 29, resetWidth, 20, " " + I18n.format("fml.configgui.tooltip.resetToDefault"), RESET_CHAR, 2.0F));
this.buttonList.add(btnUndoChanges = new GuiUnicodeGlyphButton(2002, this.width / 2 - buttonWidthHalf + doneWidth + 5,
this.height - 29, undoWidth, 20, " " + I18n.format("fml.configgui.tooltip.undoChanges"), UNDO_CHAR, 2.0F));
}
@Override
protected void actionPerformed(GuiButton button)
{
if (button.id == 2000)
{
try
{
this.entryList.saveChanges();
}
catch (Throwable e)
{
LOGGER.error("Error performing GuiSelectString action:", e);
}
this.mc.displayGuiScreen(this.parentScreen);
}
else if (button.id == 2001)
{
this.currentValue = configElement.getDefault();
this.entryList = new GuiSelectStringEntries(this, this.mc, this.configElement, this.selectableValues);
}
else if (button.id == 2002)
{
this.currentValue = beforeValue;
this.entryList = new GuiSelectStringEntries(this, this.mc, this.configElement, this.selectableValues);
}
}
@Override
public void handleMouseInput() throws IOException
{
super.handleMouseInput();
this.entryList.handleMouseInput();
}
@Override
protected void mouseReleased(int x, int y, int mouseEvent)
{
if (mouseEvent != 0 || !this.entryList.mouseReleased(x, y, mouseEvent))
{
super.mouseReleased(x, y, mouseEvent);
}
}
@Override
public void drawScreen(int par1, int par2, float par3)
{
this.drawDefaultBackground();
this.entryList.drawScreen(par1, par2, par3);
this.drawCenteredString(this.fontRenderer, this.title, this.width / 2, 8, 16777215);
if (this.titleLine2 != null)
this.drawCenteredString(this.fontRenderer, this.titleLine2, this.width / 2, 18, 16777215);
if (this.titleLine3 != null)
this.drawCenteredString(this.fontRenderer, this.titleLine3, this.width / 2, 28, 16777215);
this.btnDone.enabled = currentValue != null;
this.btnDefault.enabled = enabled && !this.entryList.isDefault();
this.btnUndoChanges.enabled = enabled && this.entryList.isChanged();
super.drawScreen(par1, par2, par3);
if (this.tooltipHoverChecker != null && this.tooltipHoverChecker.checkHover(par1, par2))
drawToolTip(this.toolTip, par1, par2);
}
public void drawToolTip(List<String> stringList, int x, int y)
{
GuiUtils.drawHoveringText(stringList, x, y, width, height, 300, fontRenderer);
}
}

View File

@ -1,205 +0,0 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2018.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.fml.client.config;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiListExtended;
import net.minecraftforge.fml.client.config.GuiConfigEntries.SelectValueEntry;
/**
* This class implements the scrolling list functionality of the GuiSelectString screen.
*
* @author bspkrs
*/
public class GuiSelectStringEntries extends GuiListExtended
{
public GuiSelectString owningScreen;
public Minecraft mc;
public IConfigElement configElement;
public List<IGuiSelectStringListEntry> listEntries;
public final Map<Object, String> selectableValues;
public int selectedIndex = -1;
public int maxEntryWidth = 0;
public GuiSelectStringEntries(GuiSelectString owningScreen, Minecraft mc, IConfigElement configElement, Map<Object, String> selectableValues)
{
super(mc, owningScreen.width, owningScreen.height, owningScreen.titleLine2 != null ? (owningScreen.titleLine3 != null ? 43 : 33) : 23,
owningScreen.height - 32, 11);
this.owningScreen = owningScreen;
this.mc = mc;
this.configElement = configElement;
this.selectableValues = selectableValues;
this.setShowSelectionBox(true);
listEntries = new ArrayList<IGuiSelectStringListEntry>();
int index = 0;
List<Entry<Object, String>> sortedList = new ArrayList<Entry<Object, String>>(selectableValues.entrySet());
Collections.sort(sortedList, new EntryComparator());
for (Entry<Object, String> entry : sortedList)
{
listEntries.add(new ListEntry(this, entry));
if (mc.fontRenderer.getStringWidth(entry.getValue()) > maxEntryWidth)
maxEntryWidth = mc.fontRenderer.getStringWidth(entry.getValue());
if (owningScreen.currentValue.equals(entry.getKey()))
{
this.selectedIndex = index;
}
index++;
}
}
public static class EntryComparator implements Comparator<Entry<Object, String>>
{
@Override
public int compare(Entry<Object, String> o1, Entry<Object, String> o2)
{
int compare = o1.getValue().toLowerCase(Locale.US).compareTo(o2.getValue().toLowerCase(Locale.US));
if (compare == 0)
compare = o1.getKey().toString().toLowerCase(Locale.US).compareTo(o2.getKey().toString().toLowerCase(Locale.US));
return compare;
}
}
/**
* The element in the slot that was clicked, boolean for whether it was double clicked or not
*/
@Override
protected void elementClicked(int index, boolean doubleClick, int mouseX, int mouseY)
{
selectedIndex = index;
owningScreen.currentValue = listEntries.get(index).getValue();
}
/**
* Returns true if the element passed in is currently selected
*/
@Override
protected boolean isSelected(int index)
{
return index == selectedIndex;
}
@Override
protected int getScrollBarX()
{
return width / 2 + this.maxEntryWidth / 2 + 5;
}
/**
* Gets the width of the list
*/
@Override
public int getListWidth()
{
return maxEntryWidth + 5;
}
@Override
public IGuiSelectStringListEntry getListEntry(int index)
{
return listEntries.get(index);
}
@Override
protected int getSize()
{
return listEntries.size();
}
public boolean isChanged()
{
return owningScreen.beforeValue != null ? !owningScreen.beforeValue.equals(owningScreen.currentValue) : owningScreen.currentValue != null;
}
public boolean isDefault()
{
return owningScreen.currentValue != null ? owningScreen.currentValue.equals(configElement.getDefault()) : configElement.getDefault() == null;
}
public void saveChanges()
{
if (owningScreen.slotIndex != -1 && owningScreen.parentScreen != null
&& owningScreen.parentScreen instanceof GuiConfig
&& ((GuiConfig) owningScreen.parentScreen).entryList.getListEntry(owningScreen.slotIndex) instanceof SelectValueEntry)
{
SelectValueEntry entry = (SelectValueEntry) ((GuiConfig) owningScreen.parentScreen).entryList.getListEntry(owningScreen.slotIndex);
entry.setValueFromChildScreen(owningScreen.currentValue);
}
else
configElement.set(owningScreen.currentValue);
}
public static class ListEntry implements IGuiSelectStringListEntry
{
protected final GuiSelectStringEntries owningList;
protected final Entry<Object, String> value;
public ListEntry(GuiSelectStringEntries owningList, Entry<Object, String> value)
{
this.owningList = owningList;
this.value = value;
}
@Override
public void drawEntry(int slotIndex, int x, int y, int listWidth, int slotHeight, int mouseX, int mouseY, boolean isSelected, float partial)
{
owningList.mc.fontRenderer.drawString(value.getValue(), x + 1, y, slotIndex == owningList.selectedIndex ? 16777215 : 14737632);
}
@Override
public boolean mousePressed(int index, int x, int y, int mouseEvent, int relativeX, int relativeY)
{
return false;
}
@Override
public void mouseReleased(int index, int x, int y, int mouseEvent, int relativeX, int relativeY)
{}
@Override
public Object getValue()
{
return value.getKey();
}
@Override
public void updatePosition(int p_192633_1_, int p_192633_2_, int p_192633_3_, float p_192633_4_){}
}
public static interface IGuiSelectStringListEntry extends GuiListExtended.IGuiListEntry
{
Object getValue();
}
}

View File

@ -128,19 +128,11 @@ public class GuiSlider extends GuiButtonExt
* e).
*/
@Override
public boolean mousePressed(Minecraft par1Minecraft, int par2, int par3)
public void func_194829_a(double mouseX, double mouseY)
{
if (super.mousePressed(par1Minecraft, par2, par3))
{
this.sliderValue = (float)(par2 - (this.x + 4)) / (float)(this.width - 8);
updateSlider();
this.dragging = true;
return true;
}
else
{
return false;
}
this.sliderValue = (mouseX - (this.x + 4)) / (this.width - 8);
updateSlider();
this.dragging = true;
}
public void updateSlider()
@ -198,7 +190,7 @@ public class GuiSlider extends GuiButtonExt
* Fired when the mouse button is released. Equivalent of MouseListener.mouseReleased(MouseEvent e).
*/
@Override
public void mouseReleased(int par1, int par2)
public void func_194831_b(double mouseX, double mouseY)
{
this.dragging = false;
}

View File

@ -41,19 +41,20 @@ public class GuiUnicodeGlyphButton extends GuiButtonExt
}
@Override
public void drawButton(Minecraft mc, int mouseX, int mouseY, float partial)
public void func_194828_a(int mouseX, int mouseY, float partial)
{
if (this.visible)
{
Minecraft mc = Minecraft.getMinecraft();
this.hovered = mouseX >= this.x && mouseY >= this.y && mouseX < this.x + this.width && mouseY < this.y + this.height;
int k = this.getHoverState(this.hovered);
GuiUtils.drawContinuousTexturedBox(GuiButton.BUTTON_TEXTURES, this.x, this.y, 0, 46 + k * 20, this.width, this.height, 200, 20, 2, 3, 2, 2, this.zLevel);
this.mouseDragged(mc, mouseX, mouseY);
int color = 14737632;
if (packedFGColour != 0)
if (packedFGColor != 0)
{
color = packedFGColour;
color = packedFGColor;
}
else if (!this.enabled)
{

View File

@ -0,0 +1,16 @@
package net.minecraftforge.fml.client.config;
public interface IArrayEntry
{
void keyTyped(char eventChar, int eventKey);
void updateCursorCounter();
void mouseClicked(int x, int y, int mouseEvent);
void drawToolTip(int mouseX, int mouseY);
boolean isValueSavable();
Object getValue();
}

View File

@ -22,9 +22,6 @@ package net.minecraftforge.fml.client.config;
import java.util.List;
import java.util.regex.Pattern;
import net.minecraftforge.fml.client.config.GuiConfigEntries.IConfigEntry;
import net.minecraftforge.fml.client.config.GuiEditArrayEntries.IArrayEntry;
/**
* This interface provides the information needed by GuiConfig and GuiConfigEntries to display config elements for editing.
*

View File

@ -0,0 +1,105 @@
package net.minecraftforge.fml.client.config;
import net.minecraft.client.gui.GuiTextField;
/**
* Provides an interface for defining GuiConfigEntry.listEntry objects.
*/
public interface IConfigEntry
{
/**
* Gets the IConfigElement object owned by this entry.
* @return
*/
IConfigElement getConfigElement();
/**
* Gets the name of the ConfigElement owned by this entry.
*/
String getName();
/**
* Gets the current value of this entry.
*/
Object getCurrentValue();
/**
* Gets the current values of this list entry.
*/
Object[] getCurrentValues();
/**
* Is this list entry enabled?
*
* @return true if this entry's controls should be enabled, false otherwise.
*/
boolean enabled();
/**
* Handles user keystrokes for any GuiTextField objects in this entry. Call {@link GuiTextField#textboxKeyTyped(char, int)} for any GuiTextField
* objects that should receive the input provided.
*/
void keyTyped(char eventChar, int eventKey);
/**
* Call {@link GuiTextField#updateCursorCounter()} for any GuiTextField objects in this entry.
*/
void updateCursorCounter();
/**
* Call {@link GuiTextField#mouseClicked(int, int, int)} for and GuiTextField objects in this entry.
*/
void mouseClicked(int x, int y, int mouseEvent);
/**
* Is this entry's value equal to the default value? Generally true should be returned if this entry is not a property or category
* entry.
*
* @return true if this entry's value is equal to this entry's default value.
*/
boolean isDefault();
/**
* Sets this entry's value to the default value.
*/
void setToDefault();
/**
* Handles reverting any changes that have occurred to this entry.
*/
void undoChanges();
/**
* Has the value of this entry changed?
*
* @return true if changes have been made to this entry's value, false otherwise.
*/
boolean isChanged();
/**
* Handles saving any changes that have been made to this entry back to the underlying object. It is a good practice to check
* isChanged() before performing the save action. This method should return true if the element has changed AND REQUIRES A RESTART.
*/
boolean saveConfigElement();
/**
* Handles drawing any tooltips that apply to this entry. This method is called after all other GUI elements have been drawn to the
* screen, so it could also be used to draw any GUI element that needs to be drawn after all entries have had drawEntry() called.
*/
void drawToolTip(int mouseX, int mouseY);
/**
* Gets this entry's label width.
*/
int getLabelWidth();
/**
* Gets this entry's right-hand x boundary. This value is used to control where the scroll bar is placed.
*/
int getEntryRightBound();
/**
* This method is called when the parent GUI is closed. Most handlers won't need this; it is provided for special cases.
*/
void onGuiClosed();
}

View File

@ -16,27 +16,23 @@
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/* TODO error GUIs
package net.minecraftforge.fml.client.gui;
import java.io.File;
import java.io.IOException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.gui.GuiYesNo;
import net.minecraft.client.gui.GuiYesNoCallback;
import net.minecraftforge.fml.client.FMLClientHandler;
import net.minecraftforge.fml.common.FMLLog;
import net.minecraftforge.fml.StartupQuery;
import net.minecraftforge.fml.common.ZipperUtil;
public class GuiOldSaveLoadConfirm extends GuiYesNo implements GuiYesNoCallback {
private static final Logger LOGGER = LogManager.getLogger();
private String dirName;
private String saveName;
private File zip;
@ -111,3 +107,4 @@ public class GuiOldSaveLoadConfirm extends GuiYesNo implements GuiYesNoCallback
}
}
}
*/

View File

@ -39,6 +39,7 @@ import javax.annotation.Nullable;
import com.mojang.brigadier.arguments.IntegerArgumentType;
import com.mojang.brigadier.builder.ArgumentBuilder;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.brigadier.exceptions.DynamicCommandExceptionType;
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
@ -68,7 +69,7 @@ public class CommandSetDimension
);
}
private static int execute(CommandSource sender, Collection<? extends Entity> entities, int dim, BlockPos pos) throws CommandException
private static int execute(CommandSource sender, Collection<? extends Entity> entities, int dim, BlockPos pos) throws CommandSyntaxException
{
entities.removeIf(CommandSetDimension::checkEntity);
if (entities.isEmpty())