From fe3478f233e9b3934ddc80330cb0f333b0a7ea1a Mon Sep 17 00:00:00 2001 From: Ben Staddon Date: Sun, 1 Apr 2018 09:55:45 +0100 Subject: [PATCH] New ITeleporter interface making dimensional teleportation easier. (#4602) --- .../net/minecraft/entity/Entity.java.patch | 52 +++++++- .../entity/item/EntityEnderPearl.java.patch | 16 +++ .../entity/item/EntityItem.java.patch | 12 ++ .../item/EntityMinecartContainer.java.patch | 13 ++ .../entity/player/EntityPlayerMP.java.patch | 25 +++- .../server/management/PlayerList.java.patch | 42 ++++-- .../net/minecraft/world/Teleporter.java.patch | 25 ++++ .../world/WorldProviderEnd.java.patch | 23 ++++ .../world/end/DragonFightManager.java.patch | 25 ++++ .../common/util/FakePlayer.java | 2 +- .../common/util/ITeleporter.java | 60 +++++++++ .../server/command/CommandSetDimension.java | 120 ++++++++++++++++++ .../server/command/ForgeCommand.java | 1 + .../resources/assets/forge/lang/en_US.lang | 4 + src/main/resources/forge.exc | 9 ++ 15 files changed, 410 insertions(+), 19 deletions(-) create mode 100644 patches/minecraft/net/minecraft/world/Teleporter.java.patch create mode 100644 patches/minecraft/net/minecraft/world/end/DragonFightManager.java.patch create mode 100644 src/main/java/net/minecraftforge/common/util/ITeleporter.java create mode 100644 src/main/java/net/minecraftforge/server/command/CommandSetDimension.java diff --git a/patches/minecraft/net/minecraft/entity/Entity.java.patch b/patches/minecraft/net/minecraft/entity/Entity.java.patch index 2e0416efb..91c210713 100644 --- a/patches/minecraft/net/minecraft/entity/Entity.java.patch +++ b/patches/minecraft/net/minecraft/entity/Entity.java.patch @@ -146,15 +146,40 @@ this.field_184239_as = null; entity.func_184225_p(this); } -@@ -2511,6 +2538,7 @@ +@@ -2509,8 +2536,16 @@ + @Nullable + public Entity func_184204_a(int p_184204_1_) { ++ if (this.field_70170_p.field_72995_K || this.field_70128_L) return null; ++ return changeDimension(p_184204_1_, this.func_184102_h().func_71218_a(p_184204_1_).func_85176_s()); ++ } ++ ++ @Nullable // Forge: Entities that require custom handling should override this method, not the other ++ public Entity changeDimension(int p_184204_1_, net.minecraftforge.common.util.ITeleporter teleporter) ++ { if (!this.field_70170_p.field_72995_K && !this.field_70128_L) { + if (!net.minecraftforge.common.ForgeHooks.onTravelToDimension(this, p_184204_1_)) return null; this.field_70170_p.field_72984_F.func_76320_a("changeDimension"); MinecraftServer minecraftserver = this.func_184102_h(); int i = this.field_71093_bK; -@@ -2535,16 +2563,17 @@ +@@ -2518,7 +2553,7 @@ + WorldServer worldserver1 = minecraftserver.func_71218_a(p_184204_1_); + this.field_71093_bK = p_184204_1_; + +- if (i == 1 && p_184204_1_ == 1) ++ if (i == 1 && p_184204_1_ == 1 && teleporter.isVanilla()) + { + worldserver1 = minecraftserver.func_71218_a(0); + this.field_71093_bK = 0; +@@ -2529,22 +2564,23 @@ + this.field_70170_p.field_72984_F.func_76320_a("reposition"); + BlockPos blockpos; + +- if (p_184204_1_ == 1) ++ if (p_184204_1_ == 1 && teleporter.isVanilla()) + { + blockpos = worldserver1.func_180504_m(); } else { @@ -176,7 +201,26 @@ { d0 = MathHelper.func_151237_a(d0 * 8.0D, worldserver1.func_175723_af().func_177726_b() + 16.0D, worldserver1.func_175723_af().func_177728_d() - 16.0D); d1 = MathHelper.func_151237_a(d1 * 8.0D, worldserver1.func_175723_af().func_177736_c() + 16.0D, worldserver1.func_175723_af().func_177733_e() - 16.0D); -@@ -2604,7 +2633,7 @@ +@@ -2554,8 +2590,7 @@ + d1 = (double)MathHelper.func_76125_a((int)d1, -29999872, 29999872); + float f = this.field_70177_z; + this.func_70012_b(d0, this.field_70163_u, d1, 90.0F, 0.0F); +- Teleporter teleporter = worldserver1.func_85176_s(); +- teleporter.func_180620_b(this, f); ++ teleporter.placeEntity(worldserver1, this, f); + blockpos = new BlockPos(this); + } + +@@ -2567,7 +2602,7 @@ + { + entity.func_180432_n(this); + +- if (i == 1 && p_184204_1_ == 1) ++ if (i == 1 && p_184204_1_ == 1 && teleporter.isVanilla()) + { + BlockPos blockpos1 = worldserver1.func_175672_r(worldserver1.func_175694_M()); + entity.func_174828_a(blockpos1, entity.field_70177_z, entity.field_70125_A); +@@ -2604,7 +2639,7 @@ public float func_180428_a(Explosion p_180428_1_, World p_180428_2_, BlockPos p_180428_3_, IBlockState p_180428_4_) { @@ -185,7 +229,7 @@ } public boolean func_174816_a(Explosion p_174816_1_, World p_174816_2_, BlockPos p_174816_3_, IBlockState p_174816_4_, float p_174816_5_) -@@ -2901,6 +2930,183 @@ +@@ -2901,6 +2936,183 @@ EnchantmentHelper.func_151385_b(p_174815_1_, p_174815_2_); } diff --git a/patches/minecraft/net/minecraft/entity/item/EntityEnderPearl.java.patch b/patches/minecraft/net/minecraft/entity/item/EntityEnderPearl.java.patch index d3c802e93..46afa1b57 100644 --- a/patches/minecraft/net/minecraft/entity/item/EntityEnderPearl.java.patch +++ b/patches/minecraft/net/minecraft/entity/item/EntityEnderPearl.java.patch @@ -23,3 +23,19 @@ } } else if (entitylivingbase != null) +@@ -141,13 +145,13 @@ + } + + @Nullable +- public Entity func_184204_a(int p_184204_1_) ++ public Entity changeDimension(int p_184204_1_, net.minecraftforge.common.util.ITeleporter teleporter) + { + if (this.field_70192_c.field_71093_bK != p_184204_1_) + { + this.field_70192_c = null; + } + +- return super.func_184204_a(p_184204_1_); ++ return super.changeDimension(p_184204_1_, teleporter); + } + } diff --git a/patches/minecraft/net/minecraft/entity/item/EntityItem.java.patch b/patches/minecraft/net/minecraft/entity/item/EntityItem.java.patch index cadbee02d..b86590467 100644 --- a/patches/minecraft/net/minecraft/entity/item/EntityItem.java.patch +++ b/patches/minecraft/net/minecraft/entity/item/EntityItem.java.patch @@ -117,6 +117,18 @@ this.func_70106_y(); itemstack.func_190920_e(i); } +@@ -394,9 +425,9 @@ + } + + @Nullable +- public Entity func_184204_a(int p_184204_1_) ++ public Entity changeDimension(int p_184204_1_, net.minecraftforge.common.util.ITeleporter teleporter) + { +- Entity entity = super.func_184204_a(p_184204_1_); ++ Entity entity = super.changeDimension(p_184204_1_, teleporter); + + if (!this.field_70170_p.field_72995_K && entity instanceof EntityItem) + { @@ -476,6 +507,6 @@ public void func_174870_v() { diff --git a/patches/minecraft/net/minecraft/entity/item/EntityMinecartContainer.java.patch b/patches/minecraft/net/minecraft/entity/item/EntityMinecartContainer.java.patch index 794653dad..c1ef384ed 100644 --- a/patches/minecraft/net/minecraft/entity/item/EntityMinecartContainer.java.patch +++ b/patches/minecraft/net/minecraft/entity/item/EntityMinecartContainer.java.patch @@ -1,5 +1,18 @@ --- ../src-base/minecraft/net/minecraft/entity/item/EntityMinecartContainer.java +++ ../src-work/minecraft/net/minecraft/entity/item/EntityMinecartContainer.java +@@ -138,10 +138,10 @@ + } + + @Nullable +- public Entity func_184204_a(int p_184204_1_) ++ public Entity changeDimension(int p_184204_1_, net.minecraftforge.common.util.ITeleporter teleporter) + { + this.field_94112_b = false; +- return super.func_184204_a(p_184204_1_); ++ return super.changeDimension(p_184204_1_, teleporter); + } + + public void func_70106_y() @@ -202,6 +202,7 @@ public boolean func_184230_a(EntityPlayer p_184230_1_, EnumHand p_184230_2_) diff --git a/patches/minecraft/net/minecraft/entity/player/EntityPlayerMP.java.patch b/patches/minecraft/net/minecraft/entity/player/EntityPlayerMP.java.patch index 98df4442f..e374ae690 100644 --- a/patches/minecraft/net/minecraft/entity/player/EntityPlayerMP.java.patch +++ b/patches/minecraft/net/minecraft/entity/player/EntityPlayerMP.java.patch @@ -50,14 +50,35 @@ } for (ScoreObjective scoreobjective : this.field_70170_p.func_96441_U().func_96520_a(IScoreCriteria.field_96642_c)) -@@ -647,6 +660,7 @@ +@@ -645,8 +658,9 @@ + } + @Nullable - public Entity func_184204_a(int p_184204_1_) +- public Entity func_184204_a(int p_184204_1_) ++ public Entity changeDimension(int p_184204_1_, net.minecraftforge.common.util.ITeleporter teleporter) { + if (!net.minecraftforge.common.ForgeHooks.onTravelToDimension(this, p_184204_1_)) return this; this.field_184851_cj = true; if (this.field_71093_bK == 0 && p_184204_1_ == -1) +@@ -658,7 +672,7 @@ + this.field_193110_cw = null; + } + +- if (this.field_71093_bK == 1 && p_184204_1_ == 1) ++ if (this.field_71093_bK == 1 && p_184204_1_ == 1 && teleporter.isVanilla()) + { + this.field_70170_p.func_72900_e(this); + +@@ -678,7 +692,7 @@ + p_184204_1_ = 1; + } + +- this.field_71133_b.func_184103_al().func_187242_a(this, p_184204_1_); ++ this.field_71133_b.func_184103_al().transferPlayerToDimension(this, p_184204_1_, teleporter); + this.field_71135_a.func_147359_a(new SPacketEffect(1032, BlockPos.field_177992_a, 0, false)); + this.field_71144_ck = -1; + this.field_71149_ch = -1.0F; @@ -808,7 +822,7 @@ BlockPos blockpos = new BlockPos(i, j, k); IBlockState iblockstate = this.field_70170_p.func_180495_p(blockpos); diff --git a/patches/minecraft/net/minecraft/server/management/PlayerList.java.patch b/patches/minecraft/net/minecraft/server/management/PlayerList.java.patch index 480680f8f..62d2911a6 100644 --- a/patches/minecraft/net/minecraft/server/management/PlayerList.java.patch +++ b/patches/minecraft/net/minecraft/server/management/PlayerList.java.patch @@ -146,14 +146,20 @@ return entityplayermp; } -@@ -556,15 +601,20 @@ +@@ -556,15 +601,26 @@ public void func_187242_a(EntityPlayerMP p_187242_1_, int p_187242_2_) { + transferPlayerToDimension(p_187242_1_, p_187242_2_, field_72400_f.func_71218_a(p_187242_2_).func_85176_s()); + } + ++ // TODO: Remove (1.13) + public void transferPlayerToDimension(EntityPlayerMP p_187242_1_, int p_187242_2_, net.minecraft.world.Teleporter teleporter) ++ { ++ transferPlayerToDimension(p_187242_1_, p_187242_2_, (net.minecraftforge.common.util.ITeleporter) teleporter); ++ } ++ ++ public void transferPlayerToDimension(EntityPlayerMP p_187242_1_, int p_187242_2_, net.minecraftforge.common.util.ITeleporter teleporter) + { int i = p_187242_1_.field_71093_bK; WorldServer worldserver = this.field_72400_f.func_71218_a(p_187242_1_.field_71093_bK); @@ -169,7 +175,7 @@ this.func_72375_a(p_187242_1_, worldserver); p_187242_1_.field_71135_a.func_147364_a(p_187242_1_.field_70165_t, p_187242_1_.field_70163_u, p_187242_1_.field_70161_v, p_187242_1_.field_70177_z, p_187242_1_.field_70125_A); p_187242_1_.field_71134_c.func_73080_a(worldserver1); -@@ -576,17 +626,27 @@ +@@ -576,17 +632,30 @@ { p_187242_1_.field_71135_a.func_147359_a(new SPacketEntityEffect(p_187242_1_.func_145782_y(), potioneffect)); } @@ -183,12 +189,15 @@ + transferEntityToWorld(p_82448_1_, p_82448_2_, p_82448_3_, p_82448_4_, p_82448_4_.func_85176_s()); + } + -+ @SuppressWarnings("unused") ++ // TODO: Remove (1.13) + public void transferEntityToWorld(Entity p_82448_1_, int p_82448_2_, WorldServer p_82448_3_, WorldServer p_82448_4_, net.minecraft.world.Teleporter teleporter) + { -+ net.minecraft.world.WorldProvider pOld = p_82448_3_.field_73011_w; -+ net.minecraft.world.WorldProvider pNew = p_82448_4_.field_73011_w; -+ double moveFactor = pOld.getMovementFactor() / pNew.getMovementFactor(); ++ transferEntityToWorld(p_82448_1_, p_82448_2_, p_82448_3_, p_82448_4_, (net.minecraftforge.common.util.ITeleporter) teleporter); ++ } ++ ++ public void transferEntityToWorld(Entity p_82448_1_, int p_82448_2_, WorldServer p_82448_3_, WorldServer p_82448_4_, net.minecraftforge.common.util.ITeleporter teleporter) ++ { ++ double moveFactor = p_82448_3_.field_73011_w.getMovementFactor() / p_82448_4_.field_73011_w.getMovementFactor(); + double d0 = MathHelper.func_151237_a(p_82448_1_.field_70165_t * moveFactor, p_82448_4_.func_175723_af().func_177726_b() + 16.0D, p_82448_4_.func_175723_af().func_177728_d() - 16.0D); + double d1 = MathHelper.func_151237_a(p_82448_1_.field_70161_v * moveFactor, p_82448_4_.func_175723_af().func_177736_c() + 16.0D, p_82448_4_.func_175723_af().func_177733_e() - 16.0D); double d2 = 8.0D; @@ -200,7 +209,7 @@ { d0 = MathHelper.func_151237_a(d0 / 8.0D, p_82448_4_.func_175723_af().func_177726_b() + 16.0D, p_82448_4_.func_175723_af().func_177728_d() - 16.0D); d1 = MathHelper.func_151237_a(d1 / 8.0D, p_82448_4_.func_175723_af().func_177736_c() + 16.0D, p_82448_4_.func_175723_af().func_177733_e() - 16.0D); -@@ -597,7 +657,7 @@ +@@ -597,7 +666,7 @@ p_82448_3_.func_72866_a(p_82448_1_, false); } } @@ -209,22 +218,31 @@ { d0 = MathHelper.func_151237_a(d0 * 8.0D, p_82448_4_.func_175723_af().func_177726_b() + 16.0D, p_82448_4_.func_175723_af().func_177728_d() - 16.0D); d1 = MathHelper.func_151237_a(d1 * 8.0D, p_82448_4_.func_175723_af().func_177736_c() + 16.0D, p_82448_4_.func_175723_af().func_177733_e() - 16.0D); -@@ -608,7 +668,8 @@ +@@ -608,7 +677,7 @@ p_82448_3_.func_72866_a(p_82448_1_, false); } } - else -+ -+ if (p_82448_1_.field_71093_bK == 1) ++ if (p_82448_1_.field_71093_bK == 1 && teleporter.isVanilla()) { BlockPos blockpos; -@@ -643,7 +704,7 @@ +@@ -634,7 +703,7 @@ + + p_82448_3_.field_72984_F.func_76319_b(); + +- if (p_82448_2_ != 1) ++ if (p_82448_2_ != 1 || !teleporter.isVanilla()) + { + p_82448_3_.field_72984_F.func_76320_a("placing"); + d0 = (double)MathHelper.func_76125_a((int)d0, -29999872, 29999872); +@@ -643,7 +712,8 @@ if (p_82448_1_.func_70089_S()) { p_82448_1_.func_70012_b(d0, p_82448_1_.field_70163_u, d1, p_82448_1_.field_70177_z, p_82448_1_.field_70125_A); - p_82448_4_.func_85176_s().func_180266_a(p_82448_1_, f); -+ teleporter.func_180266_a(p_82448_1_, f); ++ p_82448_3_.func_72866_a(p_82448_1_, false); ++ teleporter.placeEntity(p_82448_4_, p_82448_1_, f); p_82448_4_.func_72838_d(p_82448_1_); p_82448_4_.func_72866_a(p_82448_1_, false); } diff --git a/patches/minecraft/net/minecraft/world/Teleporter.java.patch b/patches/minecraft/net/minecraft/world/Teleporter.java.patch new file mode 100644 index 000000000..8b5983a4d --- /dev/null +++ b/patches/minecraft/net/minecraft/world/Teleporter.java.patch @@ -0,0 +1,25 @@ +--- ../src-base/minecraft/net/minecraft/world/Teleporter.java ++++ ../src-work/minecraft/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 + { + protected final WorldServer field_85192_a; + protected final Random field_77187_a; +@@ -428,4 +428,13 @@ + this.field_85087_d = p_i45747_3_; + } + } ++ ++ @Override ++ public void placeEntity(World world, Entity entity, float yaw) ++ { ++ if (entity instanceof EntityPlayerMP) ++ func_180266_a(entity, yaw); ++ else ++ func_180620_b(entity, yaw); ++ } + } diff --git a/patches/minecraft/net/minecraft/world/WorldProviderEnd.java.patch b/patches/minecraft/net/minecraft/world/WorldProviderEnd.java.patch index f9795ebd0..8281c449f 100644 --- a/patches/minecraft/net/minecraft/world/WorldProviderEnd.java.patch +++ b/patches/minecraft/net/minecraft/world/WorldProviderEnd.java.patch @@ -18,3 +18,26 @@ } public void func_186059_r() +@@ -129,4 +129,22 @@ + { + return this.field_186064_g; + } ++ ++ @Override ++ public void func_186061_a(net.minecraft.entity.player.EntityPlayerMP player) ++ { ++ if (this.field_186064_g != null) ++ { ++ this.field_186064_g.addPlayer(player); ++ } ++ } ++ ++ @Override ++ public void func_186062_b(net.minecraft.entity.player.EntityPlayerMP player) ++ { ++ if (this.field_186064_g != null) ++ { ++ this.field_186064_g.removePlayer(player); ++ } ++ } + } diff --git a/patches/minecraft/net/minecraft/world/end/DragonFightManager.java.patch b/patches/minecraft/net/minecraft/world/end/DragonFightManager.java.patch new file mode 100644 index 000000000..a1e5b7b78 --- /dev/null +++ b/patches/minecraft/net/minecraft/world/end/DragonFightManager.java.patch @@ -0,0 +1,25 @@ +--- ../src-base/minecraft/net/minecraft/world/end/DragonFightManager.java ++++ ../src-work/minecraft/net/minecraft/world/end/DragonFightManager.java +@@ -72,6 +72,7 @@ + public DragonFightManager(WorldServer p_i46669_1_, NBTTagCompound p_i46669_2_) + { + this.field_186110_d = p_i46669_1_; ++ this.field_186120_n = p_i46669_2_.func_82582_d(); // Forge: fix MC-105080 + + if (p_i46669_2_.func_150297_b("DragonKilled", 99)) + { +@@ -582,4 +583,14 @@ + } + } + } ++ ++ public void addPlayer(EntityPlayerMP player) ++ { ++ this.field_186109_c.func_186760_a(player); ++ } ++ ++ public void removePlayer(EntityPlayerMP player) ++ { ++ this.field_186109_c.func_186761_b(player); ++ } + } diff --git a/src/main/java/net/minecraftforge/common/util/FakePlayer.java b/src/main/java/net/minecraftforge/common/util/FakePlayer.java index 967636112..522b8457c 100644 --- a/src/main/java/net/minecraftforge/common/util/FakePlayer.java +++ b/src/main/java/net/minecraftforge/common/util/FakePlayer.java @@ -52,6 +52,6 @@ public class FakePlayer extends EntityPlayerMP @Override public boolean canAttackPlayer(EntityPlayer player){ return false; } @Override public void onDeath(DamageSource source){ return; } @Override public void onUpdate(){ return; } - @Override public Entity changeDimension(int dim){ return this; } + @Override public Entity changeDimension(int dim, ITeleporter teleporter){ return this; } @Override public void handleClientSettings(CPacketClientSettings pkt){ return; } } diff --git a/src/main/java/net/minecraftforge/common/util/ITeleporter.java b/src/main/java/net/minecraftforge/common/util/ITeleporter.java new file mode 100644 index 000000000..c9952bafd --- /dev/null +++ b/src/main/java/net/minecraftforge/common/util/ITeleporter.java @@ -0,0 +1,60 @@ +/* + * Minecraft Forge + * Copyright (c) 2017. + * + * 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 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. + * + * An implementation of this interface can be used to place the entity + * in a safe location, or generate a return portal, for instance. + * + * See the {@link net.minecraft.world.Teleporter} class, which has + * been patched to implement this interface, for a vanilla example. + */ +public interface ITeleporter +{ + /** + * Called to handle placing the entity in the new world. + * + * The initial position of the entity will be its + * position in the origin world, multiplied horizontally + * by the computed cross-dimensional movement factor + * (see {@link WorldProvider#getMovementFactor()}). + * + * Note that the supplied entity has not yet been spawned + * in the destination world at the time. + * + * @param world the entity's destination + * @param entity the entity to be placed + * @param yaw the suggested yaw value to apply + */ + void placeEntity(World world, Entity entity, float yaw); + + // used internally to handle vanilla hardcoding + default boolean isVanilla() + { + return getClass() == Teleporter.class; + } +} diff --git a/src/main/java/net/minecraftforge/server/command/CommandSetDimension.java b/src/main/java/net/minecraftforge/server/command/CommandSetDimension.java new file mode 100644 index 000000000..5d3ee147b --- /dev/null +++ b/src/main/java/net/minecraftforge/server/command/CommandSetDimension.java @@ -0,0 +1,120 @@ +/* + * Minecraft Forge + * Copyright (c) 2017. + * + * 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.server.command; + +import net.minecraft.command.CommandBase; +import net.minecraft.command.CommandException; +import net.minecraft.command.ICommandSender; +import net.minecraft.command.WrongUsageException; +import net.minecraft.entity.Entity; +import net.minecraft.server.MinecraftServer; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraftforge.common.DimensionManager; +import net.minecraftforge.common.util.ITeleporter; + +import javax.annotation.Nullable; +import java.util.Collections; +import java.util.List; + +public class CommandSetDimension extends CommandBase +{ + @Override + public String getName() + { + return "setdimension"; + } + + @Override + public List getAliases() + { + return Collections.singletonList("setdim"); + } + + @Override + public String getUsage(ICommandSender sender) + { + return "commands.forge.setdim.usage"; + } + + @Override + public List getTabCompletions(MinecraftServer server, ICommandSender sender, String[] args, @Nullable BlockPos targetPos) + { + if (args.length > 2 && args.length <= 5) + { + return getTabCompletionCoordinate(args, 2, targetPos); + } + return Collections.emptyList(); + } + + @Override + public int getRequiredPermissionLevel() + { + return 2; + } + + @Override + public void execute(MinecraftServer server, ICommandSender sender, String[] args) throws CommandException + { + // args: [ ] + if (args.length != 2 && args.length != 5) + { + throw new WrongUsageException("commands.forge.setdim.usage"); + } + Entity entity = getEntity(server, sender, args[0]); + if (!checkEntity(entity)) + { + throw new CommandException("commands.forge.setdim.invalid.entity", entity.getName()); + } + int dimension = parseInt(args[1]); + if (!DimensionManager.isDimensionRegistered(dimension)) + { + throw new CommandException("commands.forge.setdim.invalid.dim", dimension); + } + if (dimension == entity.dimension) + { + throw new CommandException("commands.forge.setdim.invalid.nochange", entity.getName(), dimension); + } + BlockPos pos = args.length == 5 ? parseBlockPos(sender, args, 2, false) : sender.getPosition(); + entity.changeDimension(dimension, new CommandTeleporter(pos)); + } + + private static boolean checkEntity(Entity entity) + { + // use vanilla portal logic, try to avoid doing anything too silly + return !entity.isRiding() && !entity.isBeingRidden() && entity.isNonBoss(); + } + + private static class CommandTeleporter implements ITeleporter + { + private final BlockPos targetPos; + + private CommandTeleporter(BlockPos targetPos) + { + this.targetPos = targetPos; + } + + @Override + public void placeEntity(World world, Entity entity, float yaw) + { + entity.moveToBlockPosAndAngles(targetPos, yaw, entity.rotationPitch); + } + } +} diff --git a/src/main/java/net/minecraftforge/server/command/ForgeCommand.java b/src/main/java/net/minecraftforge/server/command/ForgeCommand.java index 7473e72cb..fda3560f1 100644 --- a/src/main/java/net/minecraftforge/server/command/ForgeCommand.java +++ b/src/main/java/net/minecraftforge/server/command/ForgeCommand.java @@ -32,6 +32,7 @@ public class ForgeCommand extends CommandTreeBase super.addSubcommand(new CommandTrack()); super.addSubcommand(new CommandGenerate()); super.addSubcommand(new CommandEntity()); + super.addSubcommand(new CommandSetDimension()); super.addSubcommand(new CommandTreeHelp(this)); } diff --git a/src/main/resources/assets/forge/lang/en_US.lang b/src/main/resources/assets/forge/lang/en_US.lang index ba6b6c64b..58efbf388 100644 --- a/src/main/resources/assets/forge/lang/en_US.lang +++ b/src/main/resources/assets/forge/lang/en_US.lang @@ -15,6 +15,10 @@ commands.forge.entity.list.invalidworld=Could not load world for dimension %d. P commands.forge.entity.list.none=No entities found. commands.forge.entity.list.single.header=Entity: %s Total: %d commands.forge.entity.list.multiple.header=Total: %d +commands.forge.setdim.usage=Use /forge setdim [ ] +commands.forge.setdim.invalid.entity=The entity selected (%s) is not valid. +commands.forge.setdim.invalid.dim=The dimension ID specified (%d) is not valid. +commands.forge.setdim.invalid.nochange=The entity selected (%s) is already in the dimension specified (%d). commands.forge.tracking.te.enabled=Tile Entity tracking enabled for %d seconds. commands.forge.tracking.entity.enabled=Entity tracking enabled for %d seconds. diff --git a/src/main/resources/forge.exc b/src/main/resources/forge.exc index 140927f13..3cbcfe114 100644 --- a/src/main/resources/forge.exc +++ b/src/main/resources/forge.exc @@ -3,8 +3,17 @@ net/minecraft/client/renderer/ItemRenderer.renderItem(Lnet/minecraft/entity/Enti net/minecraft/client/renderer/RenderGlobal.drawBlockDamageTexture(Lnet/minecraft/client/renderer/Tessellator;Lnet/minecraft/entity/EntityLivingBase;F)V=|p_72717_1_,p_72717_2_,p_72717_3_ net/minecraft/client/renderer/entity/RenderItem.renderDroppedItem(Lnet/minecraft/entity/item/EntityItem;Lnet/minecraft/util/IIcon;IFFFFI)V=|p_77020_1_,p_77020_2_,p_77020_3_,p_77020_4_,p_77020_5_,p_77020_6_,p_77020_7_,pass net/minecraft/client/renderer/entity/RenderItem.renderItemIntoGUI(Lnet/minecraft/client/gui/FontRenderer;Lnet/minecraft/client/renderer/texture/TextureManager;Lnet/minecraft/item/ItemStack;IIZ)V=|p_77015_1_,p_77015_2_,p_77015_3_,p_77015_4_,p_77015_5_,renderEffect + +net/minecraft/entity/Entity.changeDimension(ILnet/minecraftforge/common/util/ITeleporter;)Lnet/minecraft/entity/Entity;=|p_184204_1_,teleporter +net/minecraft/entity/item/EntityEnderPearl.changeDimension(ILnet/minecraftforge/common/util/ITeleporter;)Lnet/minecraft/entity/Entity;=|p_184204_1_,teleporter +net/minecraft/entity/item/EntityItem.changeDimension(ILnet/minecraftforge/common/util/ITeleporter;)Lnet/minecraft/entity/Entity;=|p_184204_1_,teleporter +net/minecraft/entity/item/EntityMinecartContainer.changeDimension(ILnet/minecraftforge/common/util/ITeleporter;)Lnet/minecraft/entity/Entity;=|p_184204_1_,teleporter +net/minecraft/entity/player/EntityPlayerMP.changeDimension(ILnet/minecraftforge/common/util/ITeleporter;)Lnet/minecraft/entity/Entity;=|p_184204_1_,teleporter net/minecraft/server/management/PlayerList.transferPlayerToDimension(Lnet/minecraft/entity/player/EntityPlayerMP;ILnet/minecraft/world/Teleporter;)V=|p_187242_1_,p_187242_2_,teleporter +net/minecraft/server/management/PlayerList.transferPlayerToDimension(Lnet/minecraft/entity/player/EntityPlayerMP;ILnet/minecraftforge/common/util/ITeleporter;)V=|p_187242_1_,p_187242_2_,teleporter net/minecraft/server/management/PlayerList.transferEntityToWorld(Lnet/minecraft/entity/Entity;ILnet/minecraft/world/WorldServer;Lnet/minecraft/world/WorldServer;Lnet/minecraft/world/Teleporter;)V=|p_82448_1_,p_82448_2_,p_82448_3_,p_82448_4_,teleporter +net/minecraft/server/management/PlayerList.transferEntityToWorld(Lnet/minecraft/entity/Entity;ILnet/minecraft/world/WorldServer;Lnet/minecraft/world/WorldServer;Lnet/minecraftforge/common/util/ITeleporter;)V=|p_82448_1_,p_82448_2_,p_82448_3_,p_82448_4_,teleporter + net/minecraft/world/World.getBiomeGenForCoordsBody(II)Lnet/minecraft/world/biome/Biome;=|p_72807_1_,p_72807_2_ net/minecraft/world/World.getSunBrightnessFactor(F)F=|p_72967_1_ net/minecraft/world/World.getSunBrightnessBody(F)F=|p_72971_1_