Improved world border usability

- use action bar to reduce chat spamming
- inform player when cancelling nether portal opening
- render the celestia object border using vanilla renderer
This commit is contained in:
Unknown 2019-08-31 13:52:43 +02:00
parent 7dc6567b5e
commit d5a8b5e18d
12 changed files with 241 additions and 9 deletions

View file

@ -36,6 +36,7 @@ public class ClassTransformer implements net.minecraft.launchwrapper.IClassTrans
private static final String GRAVITY_MANAGER_CLASS = "cr0s/warpdrive/data/GravityManager";
private static final String CLOAK_MANAGER_CLASS = "cr0s/warpdrive/data/CloakManager";
private static final String CELESTIAL_OBJECT_MANAGER_CLASS = "cr0s/warpdrive/data/CelestialObjectManager";
private static final boolean debugLog = false;
private static final String ASM_DUMP_BEFORE = "asm/warpdrive.before";
@ -69,6 +70,12 @@ public class ClassTransformer implements net.minecraft.launchwrapper.IClassTrans
nodeMap.put("ForgeHooks.class", "ForgeHooks");
nodeMap.put("loadAdvancements.name", "lambda$loadAdvancements$0");
nodeMap.put("loadAdvancements.desc", "(Lnet/minecraftforge/fml/common/ModContainer;Ljava/util/Map;Ljava/nio/file/Path;Ljava/nio/file/Path;)Ljava/lang/Boolean;");
nodeMap.put("RenderGlobal.class", "buw");
nodeMap.put("renderWorldBorder.name", "func_180449_a");
nodeMap.put("renderWorldBorder.desc", "(Lnet/minecraft/entity/Entity;F)V");
nodeMap.put("getWorldBorder.name", "func_175723_af");
nodeMap.put("getWorldBorder.desc", "()Lnet/minecraft/world/border/WorldBorder;");
}
@Override
@ -119,6 +126,10 @@ public class ClassTransformer implements net.minecraft.launchwrapper.IClassTrans
bytesNew = transformMinecraftForgeHooks(bytesOld);
break;
case "net.minecraft.client.renderer.RenderGlobal":
bytesNew = transformMinecraftRenderGlobal(bytesOld);
break;
default:
bytesNew = null;
}
@ -743,6 +754,62 @@ public class ClassTransformer implements net.minecraft.launchwrapper.IClassTrans
return bytesNew;
}
private byte[] transformMinecraftRenderGlobal(@Nonnull final byte[] bytes) {
final ClassNode classNode = new ClassNode();
final ClassReader classReader = new ClassReader(bytes);
classReader.accept(classNode, 0);
final int countExpected = 1;
int countTransformed = 0;
for (final MethodNode methodNode : classNode.methods) {
// if (debugLog) { FMLLoadingPlugin.logger.info(String.format("- Method %s %s", methodNode.name, methodNode.desc)); }
if ( (methodNode.name.equals(nodeMap.get("renderWorldBorder.name")) || methodNode.name.equals("renderWorldBorder"))
&& methodNode.desc.equals(nodeMap.get("renderWorldBorder.desc")) ) {
FMLLoadingPlugin.logger.debug(String.format("Found method to transform: %s %s",
methodNode.name, methodNode.desc));
int indexInstruction = 0;
while (indexInstruction < methodNode.instructions.size()) {
final AbstractInsnNode abstractNode = methodNode.instructions.get(indexInstruction);
if (debugLog) { decompile(abstractNode); }
// change WorldBorder worldborder = this.field_72769_h.func_175723_af();
// into WorldBorder worldborder = CelestiaObjectManager.getWorldBorder(world);
if (abstractNode instanceof MethodInsnNode) {
final MethodInsnNode nodeAt = (MethodInsnNode) abstractNode;
if (nodeAt.name.equals(nodeMap.get("getWorldBorder.name")) || nodeAt.name.equals("getWorldBorder")) {
final MethodInsnNode overwriteNode = new MethodInsnNode(
Opcodes.INVOKESTATIC,
CELESTIAL_OBJECT_MANAGER_CLASS,
"World_getWorldBorder",
"(Lnet/minecraft/world/World;)Lnet/minecraft/world/border/WorldBorder;",
false);
methodNode.instructions.set(nodeAt, overwriteNode);
if (debugLog) { FMLLoadingPlugin.logger.info(String.format("Injecting into %s.%s %s", classNode.name, methodNode.name, methodNode.desc)); }
countTransformed++;
}
}
indexInstruction++;
}
}
}
if (countTransformed != countExpected) {
FMLLoadingPlugin.logger.error(String.format("Transformation failed for %s (%d/%d), aborting...", classNode.name, countTransformed, countExpected));
return bytes;
}
final ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS); // | ClassWriter.COMPUTE_FRAMES);
classNode.accept(writer);
final byte[] bytesNew = writer.toByteArray();
FMLLoadingPlugin.logger.info(String.format("Successful injection in %s", classNode.name));
return bytesNew;
}
private void removeInstruction(@Nonnull final MethodNode methodNode, final int indexInstruction) {
final AbstractInsnNode abstractNodeToRemove = methodNode.instructions.get(indexInstruction);
if (debugLog) {

View file

@ -0,0 +1,113 @@
package cr0s.warpdrive.data;
import javax.annotation.Nonnull;
import net.minecraft.world.border.EnumBorderStatus;
import net.minecraft.world.border.WorldBorder;
/**
* An overloaded world border to allow rectangular shapes.
*
* @author LemADEC
*/
public class CelestialBorder extends WorldBorder {
public int centerX, centerZ;
public int radiusX, radiusZ;
public CelestialBorder(final int centerX, final int centerZ,
final int radiusX, final int radiusZ) {
this.centerX = centerX;
this.centerZ = centerZ;
this.radiusX = radiusX;
this.radiusZ = radiusZ;
}
@Nonnull
@Override
public EnumBorderStatus getStatus() {
return EnumBorderStatus.STATIONARY;
}
@Override
public double minX() {
return centerX - radiusX;
}
@Override
public double minZ() {
return centerZ - radiusZ;
}
@Override
public double maxX() {
return centerX + radiusX;
}
@Override
public double maxZ() {
return centerZ + radiusZ;
}
@Override
public double getCenterX()
{
return centerX;
}
@Override
public double getCenterZ()
{
return centerZ;
}
@Override
public void setCenter(final double x, final double z) {
assert false;
}
@Override
public double getDiameter() {
assert false;
return super.getDiameter();
}
@Override
public long getTimeUntilTarget() {
assert false;
return 0L;
}
@Override
public double getTargetSize() {
return 2 * Math.max(radiusX, radiusZ);
}
@Override
public void setTransition(final double newSize) {
super.setTransition(newSize);
}
@Override
public void setTransition(final double oldSize, final double newSize, final long time) {
super.setTransition(oldSize, newSize, time);
}
@Override
public void setSize(final int size) {
// no operation
}
@Override
public int getSize() {
return 2 * Math.max(radiusX, radiusZ);
}
@Override
public String toString() {
return String.format("CelestialBorder [@ %d %d Border(%d %d)]",
centerX, centerZ,
2 * radiusX, 2 * radiusZ );
}
}

View file

@ -24,6 +24,7 @@ import net.minecraft.nbt.NBTTagList;
import net.minecraft.util.IStringSerializable;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.world.border.WorldBorder;
import net.minecraftforge.common.util.Constants.NBT;
@ -81,6 +82,7 @@ public class CelestialObject implements Cloneable, IStringSerializable, ICelesti
public CelestialObject parent;
private boolean isHyperspace;
private WorldBorder cache_worldBorder;
private AxisAlignedBB cache_aabbWorldBorder;
private AxisAlignedBB cache_aabbAreaToReachParent;
private AxisAlignedBB cache_aabbAreaInParent;
@ -485,6 +487,13 @@ public class CelestialObject implements Cloneable, IStringSerializable, ICelesti
return new VectorI(dimensionCenterX - parentCenterX, 0, dimensionCenterZ - parentCenterZ);
}
public WorldBorder getWorldBorder() {
if (cache_worldBorder == null) {
cache_worldBorder = new CelestialBorder(dimensionCenterX, dimensionCenterZ, borderRadiusX, borderRadiusZ);
}
return cache_worldBorder;
}
@Override
public AxisAlignedBB getWorldBorderArea() {
if (cache_aabbWorldBorder == null) {

View file

@ -2,11 +2,14 @@ package cr0s.warpdrive.data;
import cr0s.warpdrive.Commons;
import cr0s.warpdrive.WarpDrive;
import cr0s.warpdrive.api.WarpDriveText;
import cr0s.warpdrive.config.InvalidXmlException;
import cr0s.warpdrive.config.XmlFileManager;
import javax.annotation.Nonnull;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
@ -22,6 +25,7 @@ import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.border.WorldBorder;
import net.minecraftforge.common.DimensionManager;
@ -172,6 +176,14 @@ public class CelestialObjectManager extends XmlFileManager {
final CelestialObject celestialObjectPortal = get(world, blockPos.getX(), blockPos.getZ());
if (celestialObjectPortal != null) {
if (!celestialObjectPortal.isInsideBorder(blockPos.getX(), blockPos.getZ()) ) {
final EntityPlayer entityPlayer = world.getClosestPlayer(blockPos.getX(), blockPos.getY(), blockPos.getZ(), 10.0D, false);
if (entityPlayer != null) {
entityPlayer.sendStatusMessage(
new WarpDriveText(Commons.getStyleWarning(), "warpdrive.world_border.portal_denied"), true);
}
WarpDrive.logger.info(String.format("Nether portal opening cancelled %s for player %s: portal entry is outside the world border",
entityPlayer == null ? "-null-" : entityPlayer.getName(),
Commons.format(world, blockPos) ));
return false;
}
@ -187,6 +199,14 @@ public class CelestialObjectManager extends XmlFileManager {
final int zExit = (int) Math.floor(blockPos.getZ() * factor);
if ( Math.abs(xExit - celestialObjectExit.dimensionCenterX) > celestialObjectExit.borderRadiusX
|| Math.abs(zExit - celestialObjectExit.dimensionCenterZ) > celestialObjectExit.borderRadiusZ ) {
final EntityPlayer entityPlayer = world.getClosestPlayer(blockPos.getX(), blockPos.getY(), blockPos.getZ(), 10.0D, false);
if (entityPlayer != null) {
entityPlayer.sendStatusMessage(
new WarpDriveText(Commons.getStyleWarning(), "warpdrive.world_border.portal_denied"), true);
}
WarpDrive.logger.info(String.format("Nether portal opening cancelled for player %s %s: portal exit is outside the world border",
entityPlayer == null ? "-null-" : entityPlayer.getName(),
Commons.format(world, blockPos) ));
return false;
}
}
@ -218,6 +238,22 @@ public class CelestialObjectManager extends XmlFileManager {
return CLIENT.celestialObjects;
}
@SuppressWarnings("unused") // Core mod
@SideOnly(Side.CLIENT)
public static WorldBorder World_getWorldBorder(@Nonnull final World world) {
final WorldBorder worldBorder = world.getWorldBorder();
final EntityPlayer entityPlayer = Minecraft.getMinecraft().player;
if ( entityPlayer == null
|| entityPlayer.world != world ) {
return worldBorder;
}
final CelestialObject celestialObject = get(world, (int) entityPlayer.posX, (int) entityPlayer.posZ);
if (celestialObject == null) {
return worldBorder;
}
return celestialObject.getWorldBorder();
}
// *** non-static methods ***
private void addOrUpdateInRegistry(@Nonnull final CelestialObject celestialObject, final boolean isUpdating) {

View file

@ -112,17 +112,17 @@ public class LivingHandler {
if ( Math.abs(distanceSquared) <= BORDER_WARNING_RANGE_BLOCKS_SQUARED
&& entityLivingBase instanceof EntityPlayer
&& entityLivingBase.ticksExisted % 40 == 0) {
Commons.addChatMessage( entityLivingBase,
new WarpDriveText(Commons.getStyleWarning(), "warpdrive.world_border.in_range",
(int) Math.sqrt(Math.abs(distanceSquared))) );
((EntityPlayer) entityLivingBase).sendStatusMessage(
new WarpDriveText(Commons.getStyleWarning(), "warpdrive.world_border.in_range",
(int) Math.sqrt(Math.abs(distanceSquared))), true );
}
} else {
if (entityLivingBase instanceof EntityPlayerMP) {
if (((EntityPlayerMP) entityLivingBase).capabilities.isCreativeMode) {
if (entityLivingBase.ticksExisted % 100 == 0) {
Commons.addChatMessage( entityLivingBase,
new WarpDriveText(Commons.getStyleWarning(), "warpdrive.world_border.outside",
(int) Math.sqrt(Math.abs(distanceSquared))) );
((EntityPlayer) entityLivingBase).sendStatusMessage(
new WarpDriveText(Commons.getStyleWarning(), "warpdrive.world_border.outside",
(int) Math.sqrt(Math.abs(distanceSquared))), true );
}
return;
}

View file

@ -980,4 +980,5 @@ warpdrive.transporter_signature.set=Transporter room is now linked to %1$s.
warpdrive.world_border.in_range=Proximity alert: world border is only %1$d m away!
warpdrive.world_border.outside=You're %1$d m outside the world border...
warpdrive.world_border.portal_denied=Portal opening cancelled to prevent a certain death!
warpdrive.world_border.reached=You've reached the world border...

View file

@ -980,4 +980,5 @@ warpdrive.transporter_signature.set=Transporter room is now linked to %1$s.
warpdrive.world_border.in_range=Proximity alert: world border is only %1$d m away!
warpdrive.world_border.outside=You're %1$d m outside the world border...
warpdrive.world_border.portal_denied=Portal opening cancelled to prevent a certain death!
warpdrive.world_border.reached=You've reached the world border...

View file

@ -978,6 +978,7 @@ warpdrive.transporter_signature.set_self=Transporter room can't target itself!
warpdrive.transporter_signature.set_same=Transporter room is already linked to %1$s.
warpdrive.transporter_signature.set=Transporter room is now linked to %1$s.
warpdrive.world_border.in_range=Proximity alert: world border is only %1$d m away!
warpdrive.world_border.outside=You're %1$d m outside the world border...
warpdrive.world_border.reached=You've reached the world border...
warpdrive.world_border.in_range=Alerte de proximité: frontière du monde à %1$d m!
warpdrive.world_border.outside=Tu es %1$d m au-delà de la frontière du monde...
warpdrive.world_border.portal_denied=Ouverture du portail annulée pour éviter une mort certaine!
warpdrive.world_border.reached=Tu as atteint la frontière du monde...

View file

@ -979,4 +979,5 @@ warpdrive.transporter_signature.set=Transporter room is now linked to %1$s.
warpdrive.world_border.in_range=Proximity alert: world border is only %1$d m away!
warpdrive.world_border.outside=You're %1$d m outside the world border...
warpdrive.world_border.portal_denied=Portal opening cancelled to prevent a certain death!
warpdrive.world_border.reached=You've reached the world border...

View file

@ -980,4 +980,5 @@ warpdrive.transporter_signature.set=Transporter room is now linked to %1$s.
warpdrive.world_border.in_range=Proximity alert: world border is only %1$d m away!
warpdrive.world_border.outside=You're %1$d m outside the world border...
warpdrive.world_border.portal_denied=Portal opening cancelled to prevent a certain death!
warpdrive.world_border.reached=You've reached the world border...

View file

@ -985,4 +985,5 @@ warpdrive.transporter_signature.set=Transporter room is now linked to %1$s.
warpdrive.world_border.in_range=Proximity alert: world border is only %1$d m away!
warpdrive.world_border.outside=You're %1$d m outside the world border...
warpdrive.world_border.portal_denied=Portal opening cancelled to prevent a certain death!
warpdrive.world_border.reached=You've reached the world border...

View file

@ -979,4 +979,5 @@ warpdrive.transporter_signature.set=Transporter room is now linked to %1$s.
warpdrive.world_border.in_range=Proximity alert: world border is only %1$d m away!
warpdrive.world_border.outside=You're %1$d m outside the world border...
warpdrive.world_border.portal_denied=Portal opening cancelled to prevent a certain death!
warpdrive.world_border.reached=You've reached the world border...