Split teleportation logic and make it extensible by other mods

This commit is contained in:
Runemoro 2017-12-25 23:27:21 -05:00
parent c4560a78ba
commit ffd8c6ed3c
77 changed files with 938 additions and 825 deletions

View file

@ -7,7 +7,6 @@ import com.zixiken.dimdoors.shared.DDProxyCommon;
import com.zixiken.dimdoors.shared.items.ModItems; import com.zixiken.dimdoors.shared.items.ModItems;
import com.zixiken.dimdoors.shared.world.gateways.GatewayGenerator; import com.zixiken.dimdoors.shared.world.gateways.GatewayGenerator;
import lombok.Getter; import lombok.Getter;
import net.minecraft.client.resources.I18n;
import net.minecraft.creativetab.CreativeTabs; import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
@ -20,8 +19,6 @@ import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly; import net.minecraftforge.fml.relauncher.SideOnly;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import java.util.List;
@Mod(modid = DimDoors.MODID, name = "Dimensional Doors", @Mod(modid = DimDoors.MODID, name = "Dimensional Doors",
version = DimDoors.VERSION, version = DimDoors.VERSION,
dependencies = "required-after:forge@[14.23.0.2517,)") dependencies = "required-after:forge@[14.23.0.2517,)")

View file

@ -16,7 +16,7 @@ import net.minecraftforge.fml.relauncher.SideOnly;
import static net.minecraft.item.Item.getItemFromBlock; import static net.minecraft.item.Item.getItemFromBlock;
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public class ModelManager { public final class ModelManager {
public static void registerModels() { public static void registerModels() {
//ItemBlock registration //ItemBlock registration

View file

@ -14,8 +14,7 @@ import net.minecraft.entity.Entity;
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public class ModelMonolith extends ModelBase { public class ModelMonolith extends ModelBase {
ModelRenderer wholeMonolith; private final ModelRenderer wholeMonolith;
Random rand = new Random();
public ModelMonolith() { public ModelMonolith() {
textureWidth = 256; textureWidth = 256;

View file

@ -1,7 +1,6 @@
package com.zixiken.dimdoors.client; package com.zixiken.dimdoors.client;
import com.zixiken.dimdoors.DimDoors; import com.zixiken.dimdoors.DimDoors;
import com.zixiken.dimdoors.client.ModelMonolith;
import com.zixiken.dimdoors.shared.entities.EntityMonolith; import com.zixiken.dimdoors.shared.entities.EntityMonolith;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.OpenGlHelper; import net.minecraft.client.renderer.OpenGlHelper;

View file

@ -24,11 +24,11 @@ import static org.lwjgl.opengl.GL11.*;
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public class TileEntityEntranceRiftRenderer extends TileEntitySpecialRenderer<TileEntityEntranceRift> { // TODO: see TileEntityEndGatewayRenderer public class TileEntityEntranceRiftRenderer extends TileEntitySpecialRenderer<TileEntityEntranceRift> { // TODO: see TileEntityEndGatewayRenderer
private FloatBuffer buffer = GLAllocation.createDirectFloatBuffer(16); private final FloatBuffer buffer = GLAllocation.createDirectFloatBuffer(16);
private ResourceLocation warpPath = new ResourceLocation(DimDoors.MODID + ":textures/other/warp.png"); private final ResourceLocation warpPath = new ResourceLocation(DimDoors.MODID + ":textures/other/warp.png");
private ResourceLocation keyPath = new ResourceLocation(DimDoors.MODID + ":textures/other/keyhole.png"); private final ResourceLocation keyPath = new ResourceLocation(DimDoors.MODID + ":textures/other/keyhole.png");
private ResourceLocation keyholeLight = new ResourceLocation(DimDoors.MODID + ":textures/other/keyhole_light.png"); private final ResourceLocation keyholeLight = new ResourceLocation(DimDoors.MODID + ":textures/other/keyhole_light.png");
Map<TileEntityEntranceRift, RGBA[]> colorMap = new HashMap<>(); private final Map<TileEntityEntranceRift, RGBA[]> colorMap = new HashMap<>();
// TODO: allow any angle, make static and in a separate class // TODO: allow any angle, make static and in a separate class
public void renderDimensionalWall(double x, double y, double z, RGBA[] colors, EnumFacing orientation, double extendUp, double extendDown, double extendLeft, double extendRight, double pushIn) { public void renderDimensionalWall(double x, double y, double z, RGBA[] colors, EnumFacing orientation, double extendUp, double extendDown, double extendLeft, double extendRight, double pushIn) {

View file

@ -17,9 +17,9 @@ import org.lwjgl.opengl.GL11;
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public class TileEntityFloatingRiftRenderer extends TileEntitySpecialRenderer<TileEntityFloatingRift> { public class TileEntityFloatingRiftRenderer extends TileEntitySpecialRenderer<TileEntityFloatingRift> {
private static ResourceLocation tesseract_path = new ResourceLocation(DimDoors.MODID + ":textures/other/tesseract.png"); private static final ResourceLocation tesseract_path = new ResourceLocation(DimDoors.MODID + ":textures/other/tesseract.png");
private static Vector4f[] tesseract = { private static final Vector4f[] tesseract = {
new Vector4f(-0.5f,-0.5f,-0.5f,-0.5f), new Vector4f(-0.5f,-0.5f,-0.5f,-0.5f),
new Vector4f(0.5f,-0.5f,-0.5f,-0.5f), new Vector4f(0.5f,-0.5f,-0.5f,-0.5f),
new Vector4f(0.5f,-0.5f,0.5f,-0.5f), new Vector4f(0.5f,-0.5f,0.5f,-0.5f),

View file

@ -14,7 +14,7 @@ import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.oredict.ShapedOreRecipe; import net.minecraftforge.oredict.ShapedOreRecipe;
public class CraftingManager { public final class CraftingManager {
public static ResourceLocation getNameForRecipe(ItemStack output) { public static ResourceLocation getNameForRecipe(ItemStack output) {
ResourceLocation baseLoc = new ResourceLocation(DimDoors.MODID, output.getItem().getRegistryName().getResourcePath()); ResourceLocation baseLoc = new ResourceLocation(DimDoors.MODID, output.getItem().getRegistryName().getResourcePath());

View file

@ -15,7 +15,7 @@ import scala.actors.threadpool.Arrays;
* *
* @author Robijnvogel * @author Robijnvogel
*/ */
public class DDConfig { public final class DDConfig {
public static final boolean HAVE_CONFIG_DEFAULTS_BEEN_CHECKED_FOR_CORRECTNESS = false; //@todo check this at each non-alpha release. This field does not have a use in the mod itself, but should ensure that the developers of this mod, don't forget to resetToConfigDefaults the config defaults to the right values before releasing a non-alpha release public static final boolean HAVE_CONFIG_DEFAULTS_BEEN_CHECKED_FOR_CORRECTNESS = false; //@todo check this at each non-alpha release. This field does not have a use in the mod itself, but should ensure that the developers of this mod, don't forget to resetToConfigDefaults the config defaults to the right values before releasing a non-alpha release

View file

@ -4,6 +4,7 @@ import com.zixiken.dimdoors.DimDoors;
import com.zixiken.dimdoors.shared.blocks.ModBlocks; import com.zixiken.dimdoors.shared.blocks.ModBlocks;
import com.zixiken.dimdoors.shared.entities.EntityMonolith; import com.zixiken.dimdoors.shared.entities.EntityMonolith;
import com.zixiken.dimdoors.shared.items.ModItems; import com.zixiken.dimdoors.shared.items.ModItems;
import com.zixiken.dimdoors.shared.rifts.*;
import com.zixiken.dimdoors.shared.sound.ModSounds; import com.zixiken.dimdoors.shared.sound.ModSounds;
import com.zixiken.dimdoors.shared.tileentities.*; import com.zixiken.dimdoors.shared.tileentities.*;
import com.zixiken.dimdoors.shared.world.DimDoorDimensions; import com.zixiken.dimdoors.shared.world.DimDoorDimensions;
@ -31,6 +32,21 @@ public abstract class DDProxyCommon implements IDDProxy {
EntityRegistry.registerModEntity(new ResourceLocation(DimDoors.MODID, "mob_monolith"), EntityMonolith.class, "monolith", 0, DimDoors.instance, 70, 1, true); EntityRegistry.registerModEntity(new ResourceLocation(DimDoors.MODID, "mob_monolith"), EntityMonolith.class, "monolith", 0, DimDoors.instance, 70, 1, true);
EntityRegistry.registerEgg(new ResourceLocation(DimDoors.MODID, "mob_monolith"), 0, 0xffffff); EntityRegistry.registerEgg(new ResourceLocation(DimDoors.MODID, "mob_monolith"), 0, 0xffffff);
registerRiftDestinations();
}
public void registerRiftDestinations() {
RiftDestination.destinationRegistry.put("available_link", AvailableLinkDestination.class);
RiftDestination.destinationRegistry.put("escape", EscapeDestination.class);
RiftDestination.destinationRegistry.put("global", GlobalDestination.class);
RiftDestination.destinationRegistry.put("limbo", LimboDestination.class);
RiftDestination.destinationRegistry.put("local", LocalDestination.class);
RiftDestination.destinationRegistry.put("new_public", NewPublicDestination.class);
RiftDestination.destinationRegistry.put("pocket_entrance", PocketEntranceDestination.class);
RiftDestination.destinationRegistry.put("pocket_exit", PocketExitDestination.class);
RiftDestination.destinationRegistry.put("private", PrivateDestination.class);
RiftDestination.destinationRegistry.put("private_pocket_exit", PrivatePocketExitDestination.class);
RiftDestination.destinationRegistry.put("relative", RelativeDestination.class);
} }
@Override @Override

View file

@ -14,7 +14,7 @@ import net.minecraftforge.event.entity.living.LivingHurtEvent;
import net.minecraftforge.fml.common.eventhandler.EventPriority; import net.minecraftforge.fml.common.eventhandler.EventPriority;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
public class EventHandler { public final class EventHandler {
@SubscribeEvent @SubscribeEvent
public static void onPlayerJoinWorld(EntityJoinWorldEvent event) { public static void onPlayerJoinWorld(EntityJoinWorldEvent event) {

View file

@ -6,7 +6,7 @@ import net.minecraft.entity.EntityLivingBase;
import net.minecraft.util.math.RayTraceResult; import net.minecraft.util.math.RayTraceResult;
import net.minecraft.world.World; import net.minecraft.world.World;
public class RayTraceHelper { public final class RayTraceHelper {
public static boolean isRift(RayTraceResult hit, World world) { public static boolean isRift(RayTraceResult hit, World world) {
return isNotNull(hit) && hit.typeOfHit == RayTraceResult.Type.BLOCK && world.getTileEntity(hit.getBlockPos()) instanceof TileEntityFloatingRift; return isNotNull(hit) && hit.typeOfHit == RayTraceResult.Type.BLOCK && world.getTileEntity(hit.getBlockPos()) instanceof TileEntityFloatingRift;
} }

View file

@ -3,7 +3,6 @@ package com.zixiken.dimdoors.shared;
import com.zixiken.dimdoors.shared.pockets.Pocket; import com.zixiken.dimdoors.shared.pockets.Pocket;
import com.zixiken.dimdoors.shared.pockets.PocketRegistry; import com.zixiken.dimdoors.shared.pockets.PocketRegistry;
import ddutils.Location; import ddutils.Location;
import ddutils.WorldUtils;
import com.zixiken.dimdoors.shared.world.DimDoorDimensions; import com.zixiken.dimdoors.shared.world.DimDoorDimensions;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;
@ -80,6 +79,6 @@ public class VirtualLocation { // TODO: use BlockPos/Location
} }
public Location projectToWorld() { public Location projectToWorld() {
return transformDepth(0).getLocation(); return transformDepth(0).location;
} }
} }

View file

@ -113,7 +113,7 @@ public abstract class BlockDimensionalDoor extends BlockDoor implements IRiftPro
if (!hasTileEntity(state)) return; if (!hasTileEntity(state)) return;
TileEntityEntranceRift rift = getRift(worldIn, pos, state); TileEntityEntranceRift rift = getRift(worldIn, pos, state);
super.breakBlock(worldIn, pos, state); super.breakBlock(worldIn, pos, state);
if (rift.isPlaceRiftOnBreak() || rift.isRegistered() && RiftRegistry.getRiftInfo(new Location(worldIn, pos)).getSources().size() > 0 && !rift.isAlwaysDelete()) { if (rift.isPlaceRiftOnBreak() || rift.isRegistered() && RiftRegistry.getRiftInfo(rift.getLocation()).getSources().size() > 0 && !rift.isAlwaysDelete()) {
TileEntityRift newRift = new TileEntityFloatingRift(); TileEntityRift newRift = new TileEntityFloatingRift();
newRift.copyFrom(rift); newRift.copyFrom(rift);
newRift.updateAvailableLinks(); newRift.updateAvailableLinks();
@ -126,15 +126,11 @@ public abstract class BlockDimensionalDoor extends BlockDoor implements IRiftPro
@Override @Override
public TileEntityEntranceRift getRift(World world, BlockPos pos, IBlockState state) { public TileEntityEntranceRift getRift(World world, BlockPos pos, IBlockState state) {
TileEntity tileEntity;
if (state.getValue(BlockDoor.HALF) == EnumDoorHalf.LOWER) { if (state.getValue(BlockDoor.HALF) == EnumDoorHalf.LOWER) {
tileEntity = world.getTileEntity(pos); return (TileEntityEntranceRift) world.getTileEntity(pos);
if (!(tileEntity instanceof TileEntityRift)) tileEntity = world.getTileEntity(pos.up());
} else { } else {
tileEntity = world.getTileEntity(pos); return (TileEntityEntranceRift) world.getTileEntity(pos.down());
if (!(tileEntity instanceof TileEntityRift)) tileEntity = world.getTileEntity(pos.down());
} }
return (TileEntityEntranceRift) tileEntity;
} }
public abstract Item getItem(); public abstract Item getItem();

View file

@ -2,7 +2,7 @@ package com.zixiken.dimdoors.shared.blocks;
import com.zixiken.dimdoors.DimDoors; import com.zixiken.dimdoors.DimDoors;
import com.zixiken.dimdoors.shared.items.ModItems; import com.zixiken.dimdoors.shared.items.ModItems;
import com.zixiken.dimdoors.shared.rifts.RiftDestination; import com.zixiken.dimdoors.shared.rifts.NewPublicDestination;
import com.zixiken.dimdoors.shared.tileentities.TileEntityEntranceRift; import com.zixiken.dimdoors.shared.tileentities.TileEntityEntranceRift;
import net.minecraft.block.material.Material; import net.minecraft.block.material.Material;
import net.minecraft.item.Item; import net.minecraft.item.Item;
@ -27,7 +27,7 @@ public class BlockDimensionalDoorIron extends BlockDimensionalDoor {
@Override @Override
public void setupRift(TileEntityEntranceRift rift) { public void setupRift(TileEntityEntranceRift rift) {
RiftDestination.NewPublicDestination destination = RiftDestination.NewPublicDestination.builder().build(); NewPublicDestination destination = NewPublicDestination.builder().build();
rift.setSingleDestination(destination); rift.setSingleDestination(destination);
} }
} }

View file

@ -2,8 +2,11 @@ package com.zixiken.dimdoors.shared.blocks;
import com.zixiken.dimdoors.DimDoors; import com.zixiken.dimdoors.DimDoors;
import com.zixiken.dimdoors.shared.items.ModItems; import com.zixiken.dimdoors.shared.items.ModItems;
import com.zixiken.dimdoors.shared.rifts.PrivateDestination;
import com.zixiken.dimdoors.shared.rifts.PrivatePocketExitDestination;
import com.zixiken.dimdoors.shared.rifts.RiftDestination; import com.zixiken.dimdoors.shared.rifts.RiftDestination;
import com.zixiken.dimdoors.shared.tileentities.TileEntityEntranceRift; import com.zixiken.dimdoors.shared.tileentities.TileEntityEntranceRift;
import com.zixiken.dimdoors.shared.world.pocketdimension.WorldProviderPersonalPocket;
import net.minecraft.block.material.Material; import net.minecraft.block.material.Material;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
@ -26,9 +29,13 @@ public class BlockDimensionalDoorPersonal extends BlockDimensionalDoor {
@Override @Override
public void setupRift(TileEntityEntranceRift rift) { public void setupRift(TileEntityEntranceRift rift) {
DimDoors.log.info("Setting up the rift!"); RiftDestination destination;
RiftDestination.PrivateDestination destination = RiftDestination.PrivateDestination.builder().build(); if (rift.getWorld().provider instanceof WorldProviderPersonalPocket) {
destination = PrivatePocketExitDestination.builder().build(); // exit
} else {
destination = PrivateDestination.builder().build(); // entrance
}
rift.setSingleDestination(destination); rift.setSingleDestination(destination);
rift.setChaosWeight(0); rift.setChaosWeight(0); // TODO: generated schematic exits too
} }
} }

View file

@ -22,6 +22,7 @@ public interface IRiftProvider<T extends TileEntityRift> extends ITileEntityProv
// Call only once per structure (on item place)! // Call only once per structure (on item place)!
public default void handleRiftSetup(World world, BlockPos pos, IBlockState state) { public default void handleRiftSetup(World world, BlockPos pos, IBlockState state) {
if (world.isRemote) return;
T rift = getRift(world, pos, state); T rift = getRift(world, pos, state);
// Set the rift's virtual position // Set the rift's virtual position
@ -31,8 +32,9 @@ public interface IRiftProvider<T extends TileEntityRift> extends ITileEntityProv
setupRift(rift); setupRift(rift);
// Set the tile entity and register it // Set the tile entity and register it
world.setTileEntity(pos, rift); //world.setTileEntity(pos, rift);
rift.markDirty(); rift.markDirty();
rift.register(); rift.register();
T rift2 = getRift(world, pos, state);
} }
} }

View file

@ -4,7 +4,7 @@ import net.minecraft.block.Block;
import net.minecraftforge.event.RegistryEvent; import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
public class ModBlocks { public final class ModBlocks {
// Regular doors // Regular doors
public static final BlockDoorGold GOLD_DOOR = new BlockDoorGold(); public static final BlockDoorGold GOLD_DOOR = new BlockDoorGold();

View file

@ -77,11 +77,10 @@ public class CommandDimTeleport extends CommandBase { // TODO: localization
@Override @Override
public List<String> getTabCompletions(MinecraftServer server, ICommandSender sender, String[] args, @Nullable BlockPos targetPos) { public List<String> getTabCompletions(MinecraftServer server, ICommandSender sender, String[] args, @Nullable BlockPos targetPos) {
List<String> list = new ArrayList<>();
if (args.length == 1) { if (args.length == 1) {
list = StringUtils.getAsStringList(DimensionManager.getIDs()); List<String> list = StringUtils.getAsStringList(DimensionManager.getIDs());
list = StringUtils.getMatchingStrings(args[0], list, false); return StringUtils.getMatchingStrings(args[0], list, false);
} }
return list; return new ArrayList<>();
} }
} }

View file

@ -244,7 +244,7 @@ public class EntityMonolith extends EntityFlying implements IMob {
private void facePlayer(EntityPlayer player) { private void facePlayer(EntityPlayer player) {
double d0 = player.posX - posX; double d0 = player.posX - posX;
double d1 = player.posZ - posZ; double d1 = player.posZ - posZ;
double d2 = player.posY + player.getEyeHeight() - (posY + getEyeHeight()); double d2 = player.posY + player.getEyeHeight() - (posY + EYE_HEIGHT);
double d3 = MathHelper.sqrt(d0 * d0 + d1 * d1); double d3 = MathHelper.sqrt(d0 * d0 + d1 * d1);
float f2 = (float) (Math.atan2(d1, d0) * 180.0D / Math.PI) - 90.0F; float f2 = (float) (Math.atan2(d1, d0) * 180.0D / Math.PI) - 90.0F;
pitchLevel = (float) -(Math.atan(d2 / d3) * 180.0D / Math.PI); pitchLevel = (float) -(Math.atan(d2 / d3) * 180.0D / Math.PI);

View file

@ -7,7 +7,6 @@ import com.zixiken.dimdoors.shared.blocks.BlockDimensionalDoorWarp;
import com.zixiken.dimdoors.shared.blocks.ModBlocks; import com.zixiken.dimdoors.shared.blocks.ModBlocks;
import ddutils.I18nUtils; import ddutils.I18nUtils;
import net.minecraft.client.util.ITooltipFlag; import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.item.ItemDoor;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World; import net.minecraft.world.World;

View file

@ -6,7 +6,7 @@ import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import com.zixiken.dimdoors.shared.blocks.ModBlocks; import com.zixiken.dimdoors.shared.blocks.ModBlocks;
public class ModItems { public final class ModItems {
// Regular doors // Regular doors
public static final ItemDoorGold GOLD_DOOR = new ItemDoorGold(); public static final ItemDoorGold GOLD_DOOR = new ItemDoorGold();

View file

@ -1,9 +1,8 @@
package com.zixiken.dimdoors.shared.pockets; package com.zixiken.dimdoors.shared.pockets;
import com.zixiken.dimdoors.shared.VirtualLocation; import com.zixiken.dimdoors.shared.VirtualLocation;
import com.zixiken.dimdoors.shared.rifts.RiftDestination; import com.zixiken.dimdoors.shared.rifts.*;
import com.zixiken.dimdoors.shared.rifts.TileEntityRift; import com.zixiken.dimdoors.shared.tileentities.TileEntityEntranceRift;
import com.zixiken.dimdoors.shared.rifts.WeightedRiftDestination;
import ddutils.Location; import ddutils.Location;
import java.util.*; import java.util.*;
@ -22,7 +21,7 @@ public class Pocket { // TODO: better visibilities
@Getter private int z; // Grid y @Getter private int z; // Grid y
@Getter @Setter private int size; // In chunks TODO: non chunk-based size, better bounds such as minX, minZ, maxX, maxZ, etc. @Getter @Setter private int size; // In chunks TODO: non chunk-based size, better bounds such as minX, minZ, maxX, maxZ, etc.
@Getter @Setter private VirtualLocation virtualLocation; // The non-pocket dimension from which this dungeon was created @Getter @Setter private VirtualLocation virtualLocation; // The non-pocket dimension from which this dungeon was created
@Getter Location entrance; @Getter @Setter Location entrance; // TODO: multiple entrances
@Getter List<Location> riftLocations; @Getter List<Location> riftLocations;
@Getter int dimID; // Not saved @Getter int dimID; // Not saved
@ -104,7 +103,7 @@ public class Pocket { // TODO: better visibilities
int index = 0; int index = 0;
for (TileEntityRift rift : rifts) { // Find an entrance for (TileEntityRift rift : rifts) { // Find an entrance
for (WeightedRiftDestination weightedPocketEntranceDest : rift.getDestinations()) { for (WeightedRiftDestination weightedPocketEntranceDest : rift.getDestinations()) {
if (weightedPocketEntranceDest.getDestination().getType() == RiftDestination.EnumType.POCKET_ENTRANCE) { if (weightedPocketEntranceDest.getDestination() instanceof PocketEntranceDestination) {
entranceIndexWeights.put(index, weightedPocketEntranceDest.getWeight()); entranceIndexWeights.put(index, weightedPocketEntranceDest.getWeight());
rift.markDirty(); rift.markDirty();
index++; index++;
@ -121,18 +120,18 @@ public class Pocket { // TODO: better visibilities
while (destIterator.hasNext()) { while (destIterator.hasNext()) {
WeightedRiftDestination wdest = destIterator.next(); WeightedRiftDestination wdest = destIterator.next();
RiftDestination dest = wdest.getDestination(); RiftDestination dest = wdest.getDestination();
if (dest.getType() == RiftDestination.EnumType.POCKET_ENTRANCE) { if (dest instanceof PocketEntranceDestination) {
destIterator.remove(); destIterator.remove();
if (index == selectedEntranceIndex) { if (index == selectedEntranceIndex) {
entrance = new Location(rift.getWorld(), rift.getPos()); entrance = new Location(rift.getWorld(), rift.getPos());
PocketRegistry.getForDim(dimID).markDirty(); PocketRegistry.getForDim(dimID).markDirty();
List<WeightedRiftDestination> ifDestinations = ((RiftDestination.PocketEntranceDestination) dest).getIfDestinations(); List<WeightedRiftDestination> ifDestinations = ((PocketEntranceDestination) dest).getIfDestinations();
for (WeightedRiftDestination ifDestination : ifDestinations) { for (WeightedRiftDestination ifDestination : ifDestinations) {
destIterator.add(new WeightedRiftDestination(ifDestination.getDestination(), ifDestination.getWeight() / wdest.getWeight(), ifDestination.getGroup())); destIterator.add(new WeightedRiftDestination(ifDestination.getDestination(), ifDestination.getWeight() / wdest.getWeight(), ifDestination.getGroup()));
destIterator.previous(); // An entrance destination shouldn't be in an if/otherwise destination, but just in case, pass over it too destIterator.previous(); // An entrance destination shouldn't be in an if/otherwise destination, but just in case, pass over it too
} }
} else { } else {
List<WeightedRiftDestination> otherwiseDestinations = ((RiftDestination.PocketEntranceDestination) dest).getOtherwiseDestinations(); List<WeightedRiftDestination> otherwiseDestinations = ((PocketEntranceDestination) dest).getOtherwiseDestinations();
for (WeightedRiftDestination otherwiseDestination : otherwiseDestinations) { for (WeightedRiftDestination otherwiseDestination : otherwiseDestinations) {
destIterator.add(new WeightedRiftDestination(otherwiseDestination.getDestination(), otherwiseDestination.getWeight() / wdest.getWeight(), otherwiseDestination.getGroup())); destIterator.add(new WeightedRiftDestination(otherwiseDestination.getDestination(), otherwiseDestination.getWeight() / wdest.getWeight(), otherwiseDestination.getGroup()));
destIterator.previous(); // An entrance destination shouldn't be in an if/otherwise destination, but just in case, pass over it too destIterator.previous(); // An entrance destination shouldn't be in an if/otherwise destination, but just in case, pass over it too
@ -146,7 +145,6 @@ public class Pocket { // TODO: better visibilities
// set virtual locations and register rifts // set virtual locations and register rifts
for (TileEntityRift rift : rifts) { for (TileEntityRift rift : rifts) {
rift.setVirtualLocation(virtualLocation); rift.setVirtualLocation(virtualLocation);
rift.markStateChanged();
rift.register(); rift.register();
} }
} }
@ -160,10 +158,10 @@ public class Pocket { // TODO: better visibilities
while (destIterator.hasNext()) { while (destIterator.hasNext()) {
WeightedRiftDestination wdest = destIterator.next(); WeightedRiftDestination wdest = destIterator.next();
RiftDestination dest = wdest.getDestination(); RiftDestination dest = wdest.getDestination();
if (dest.getType() == RiftDestination.EnumType.POCKET_EXIT) { if (dest instanceof PocketExitDestination) {
destIterator.remove(); destIterator.remove();
destIterator.add(new WeightedRiftDestination(linkTo.withOldDestination(dest), wdest.getWeight(), wdest.getGroup())); destIterator.add(new WeightedRiftDestination(linkTo, wdest.getWeight(), wdest.getGroup(), dest));
rift.markStateChanged(); if (rift instanceof TileEntityEntranceRift) ((TileEntityEntranceRift) rift).setPlaceRiftOnBreak(true);
rift.markDirty(); rift.markDirty();
} }
} }

View file

@ -0,0 +1,131 @@
package com.zixiken.dimdoors.shared.rifts;
import com.zixiken.dimdoors.shared.VirtualLocation;
import ddutils.Location;
import ddutils.math.MathUtils;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import net.minecraft.entity.Entity;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.math.BlockPos;
import java.util.HashMap;
import java.util.ListIterator;
import java.util.Map;
import java.util.UUID;
@Getter @AllArgsConstructor @Builder(toBuilder = true)
public class AvailableLinkDestination extends RiftDestination { // TODO
private float newDungeonRiftProbability;
private float depthPenalization; // TODO: these make the equation assymetric
private float distancePenalization;
private float closenessPenalization;
private boolean dungeonRiftsOnly;
private boolean overworldRifts;
private boolean unstable;
private float nonFloatingRiftWeight;
private float floatingRiftWeight;
private boolean noLinkBack;
// private int maxLinks;
@Builder.Default private UUID uuid = UUID.randomUUID();
// TODO: add a "safe" option to link only to a rift destination that has a non-zero weight
AvailableLinkDestination() {}
@Override
public void readFromNBT(NBTTagCompound nbt) {
super.readFromNBT(nbt);
newDungeonRiftProbability = nbt.getFloat("newDungeonRiftProbability");
depthPenalization = nbt.getFloat("depthPenalization");
distancePenalization = nbt.getFloat("distancePenalization");
closenessPenalization = nbt.getFloat("closenessPenalization");
dungeonRiftsOnly = nbt.getBoolean("dungeonRiftsOnly");
overworldRifts = nbt.getBoolean("overworldRifts");
unstable = nbt.getBoolean("unstable");
noLinkBack = nbt.getBoolean("noLinkBack");
nonFloatingRiftWeight = nbt.getFloat("nonFloatingRiftWeight");
floatingRiftWeight = nbt.getFloat("floatingRiftWeight");
// maxLinks = nbt.getInteger("maxLinks");
uuid = nbt.getUniqueId("uuid");
}
@Override
public NBTTagCompound writeToNBT(NBTTagCompound nbt) {
nbt = super.writeToNBT(nbt);
nbt.setFloat("newDungeonRiftProbability", newDungeonRiftProbability);
nbt.setFloat("depthPenalization", depthPenalization);
nbt.setFloat("distancePenalization", distancePenalization);
nbt.setFloat("closenessPenalization", closenessPenalization);
nbt.setBoolean("dungeonRiftsOnly", dungeonRiftsOnly);
nbt.setBoolean("overworldRifts", overworldRifts);
nbt.setBoolean("unstable", unstable);
nbt.setBoolean("noLinkBack", noLinkBack);
nbt.setFloat("nonFloatingRiftWeight", nonFloatingRiftWeight);
nbt.setFloat("floatingRiftWeight", floatingRiftWeight);
// nbt.setInteger("maxLinks", maxLinks);
nbt.setUniqueId("uuid", uuid);
return nbt;
}
@Override
public boolean teleport(TileEntityRift rift, Entity entity) {
Map<RiftRegistry.RiftInfo.AvailableLinkInfo, Float> possibleDestWeightMap = new HashMap<>();
for (RiftRegistry.RiftInfo.AvailableLinkInfo link : RiftRegistry.getAvailableLinks()) {
VirtualLocation otherVLoc = link.getVirtualLocation();
float weight2 = link.getWeight();
if (weight2 == 0) continue;
double depthDiff = Math.abs(rift.virtualLocation.getDepth() - otherVLoc.getDepth());
double distanceSq = new BlockPos(rift.virtualLocation.getX(), rift.virtualLocation.getY(), rift.virtualLocation.getZ())
.distanceSq(new BlockPos(otherVLoc.getX(), otherVLoc.getY(), otherVLoc.getZ()));
float distanceExponent = distancePenalization;
float depthExponent = depthPenalization;
float closenessExponent = closenessPenalization;
float weight = (float) Math.abs(weight2/(Math.pow(depthDiff, depthExponent) * Math.pow(distanceSq, 0.5 * distanceExponent))); // TODO: fix formula
float currentWeight = possibleDestWeightMap.get(link);
possibleDestWeightMap.put(link, currentWeight + weight);
}
RiftRegistry.RiftInfo.AvailableLinkInfo selectedLink = MathUtils.weightedRandom(possibleDestWeightMap);
Location destLoc = selectedLink.getLocation();
if (!unstable) rift.makeDestinationPermanent(weightedDestination, destLoc);
TileEntityRift destRift = (TileEntityRift) destLoc.getWorld().getTileEntity(destLoc.getPos()); // Link the other rift back if necessary
ListIterator<WeightedRiftDestination> wdestIterator = destRift.destinations.listIterator();
WeightedRiftDestination selectedWDest = null;
while (wdestIterator.hasNext()) {
WeightedRiftDestination wdest = wdestIterator.next();
RiftDestination otherDest = wdest.getDestination();
if (otherDest instanceof AvailableLinkDestination && ((AvailableLinkDestination) otherDest).uuid == selectedLink.getUuid()) {
selectedWDest = wdest;
wdestIterator.remove();
break;
}
}
AvailableLinkDestination selectedAvailableLinkDest = (AvailableLinkDestination) selectedWDest.getDestination();
if (!selectedAvailableLinkDest.noLinkBack) {
destRift.makeDestinationPermanent(selectedWDest, rift.getLocation());
}
((TileEntityRift) destLoc.getTileEntity()).teleportTo(entity);
return true;
}
@Override
public void register(TileEntityRift rift) {
RiftRegistry.RiftInfo.AvailableLinkInfo linkInfo = RiftRegistry.RiftInfo.AvailableLinkInfo.builder()
.weight(rift.isFloating() ? floatingRiftWeight : nonFloatingRiftWeight)
.virtualLocation(rift.virtualLocation)
.uuid(uuid)
.build();
RiftRegistry.addAvailableLink(rift.getLocation(), linkInfo);
}
@Override
public void unregister(TileEntityRift rift) {
RiftRegistry.removeAvailableLinkByUUID(rift.getLocation(), uuid);
}
}

View file

@ -0,0 +1,38 @@
package com.zixiken.dimdoors.shared.rifts;
import ddutils.EntityUtils;
import ddutils.Location;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import net.minecraft.entity.Entity;
import net.minecraft.nbt.NBTTagCompound;
@Getter @AllArgsConstructor @Builder(toBuilder = true)
public class EscapeDestination extends RiftDestination {
//public EscapeDestination() {}
@Override
public void readFromNBT(NBTTagCompound nbt) {
super.readFromNBT(nbt);
}
@Override
public NBTTagCompound writeToNBT(NBTTagCompound nbt) {
nbt = super.writeToNBT(nbt);
return nbt;
}
@Override
public boolean teleport(TileEntityRift rift, Entity entity) {
String uuid = EntityUtils.getEntityOwnerUUID(entity);
if (uuid != null) {
Location destLoc = RiftRegistry.getOverworldRift(uuid);
RiftRegistry.setOverworldRift(uuid, null); // forget the last used escape rift
// TODO: teleport the player to random coordinates based on depth around destLoc
return true;
} else {
return false; // Non-player/owned entity tried to escape/leave private pocket
}
}
}

View file

@ -0,0 +1,39 @@
package com.zixiken.dimdoors.shared.rifts;
import ddutils.Location;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import net.minecraft.entity.Entity;
import net.minecraft.nbt.NBTTagCompound;
@Getter @AllArgsConstructor @Builder(toBuilder = true)
public class GlobalDestination extends RiftDestination { // TODO: location directly in nbt like minecraft?
private Location loc;
public GlobalDestination() {}
@Override
public void readFromNBT(NBTTagCompound nbt) {
super.readFromNBT(nbt);
loc = Location.readFromNBT(nbt.getCompoundTag("loc"));
}
@Override
public NBTTagCompound writeToNBT(NBTTagCompound nbt) {
nbt = super.writeToNBT(nbt);
nbt.setTag("loc", Location.writeToNBT(loc));
return nbt;
}
@Override
public boolean teleport(TileEntityRift rift, Entity entity) {
((TileEntityRift) loc.getTileEntity()).teleportTo(entity);
return true;
}
@Override
public Location getReferencedRift(Location rift) {
return loc;
}
}

View file

@ -0,0 +1,28 @@
package com.zixiken.dimdoors.shared.rifts;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import net.minecraft.entity.Entity;
import net.minecraft.nbt.NBTTagCompound;
@Getter @AllArgsConstructor @Builder(toBuilder = true)
public class LimboDestination extends RiftDestination {
//public LimboDestination() {}
@Override
public void readFromNBT(NBTTagCompound nbt) {
super.readFromNBT(nbt);
}
@Override
public NBTTagCompound writeToNBT(NBTTagCompound nbt) {
nbt = super.writeToNBT(nbt);
return nbt;
}
@Override
public boolean teleport(TileEntityRift rift, Entity entity) {
throw new RuntimeException("Not yet implemented!");
}
}

View file

@ -0,0 +1,41 @@
package com.zixiken.dimdoors.shared.rifts;
import ddutils.Location;
import ddutils.nbt.NBTUtils;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import net.minecraft.entity.Entity;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.math.BlockPos;
@Getter @AllArgsConstructor @Builder(toBuilder = true)
public class LocalDestination extends RiftDestination { // TODO: use BlockPos
private BlockPos pos;
public LocalDestination() {}
@Override
public void readFromNBT(NBTTagCompound nbt) {
super.readFromNBT(nbt);
pos = new BlockPos(NBTUtils.readVec3i(nbt.getCompoundTag("pos")));
}
@Override
public NBTTagCompound writeToNBT(NBTTagCompound nbt) {
nbt = super.writeToNBT(nbt);
nbt.setTag("pos", NBTUtils.writeVec3i(pos));
return nbt;
}
@Override
public boolean teleport(TileEntityRift rift, Entity entity) {
((TileEntityRift) rift.getWorld().getTileEntity(pos)).teleportTo(entity);
return true;
}
@Override
public Location getReferencedRift(Location rift) {
return new Location(rift.getDim(), pos);
}
}

View file

@ -0,0 +1,35 @@
package com.zixiken.dimdoors.shared.rifts;
import com.zixiken.dimdoors.shared.pockets.Pocket;
import com.zixiken.dimdoors.shared.pockets.PocketGenerator;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import net.minecraft.entity.Entity;
import net.minecraft.nbt.NBTTagCompound;
@Getter @AllArgsConstructor @Builder(toBuilder = true)
public class NewPublicDestination extends RiftDestination { // TODO: more config options such as non-default size, etc.
//public NewPublicDestination() {}
@Override
public void readFromNBT(NBTTagCompound nbt) {
super.readFromNBT(nbt);
}
@Override
public NBTTagCompound writeToNBT(NBTTagCompound nbt) {
nbt = super.writeToNBT(nbt);
return nbt;
}
@Override
public boolean teleport(TileEntityRift rift, Entity entity) {
Pocket pocket = PocketGenerator.generatePublicPocket(rift.virtualLocation != null ? rift.virtualLocation.toBuilder().depth(-1).build() : null); // TODO: random transform
pocket.setup();
pocket.linkPocketTo(new GlobalDestination(rift.getLocation()));
rift.makeDestinationPermanent(weightedDestination, pocket.getEntrance());
((TileEntityRift) pocket.getEntrance().getTileEntity()).teleportTo(entity);
return true;
}
}

View file

@ -0,0 +1,71 @@
package com.zixiken.dimdoors.shared.rifts;
import com.zixiken.dimdoors.DimDoors;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import java.util.LinkedList;
import java.util.List;
@Getter @AllArgsConstructor @Builder(toBuilder = true)
public class PocketEntranceDestination extends RiftDestination {
private float weight;
@SuppressWarnings({"UnusedAssignment", "RedundantSuppression"}) @Builder.Default private List<WeightedRiftDestination> ifDestinations = new LinkedList<>(); // TODO addIfDestination method in builder
@SuppressWarnings({"UnusedAssignment", "RedundantSuppression"}) @Builder.Default private List<WeightedRiftDestination> otherwiseDestinations = new LinkedList<>(); // TODO addOtherwiseDestination method in builder
public PocketEntranceDestination() {}
@Override
public void readFromNBT(NBTTagCompound nbt) {
super.readFromNBT(nbt);
weight = nbt.getFloat("weight");
ifDestinations = new LinkedList<>();
NBTTagList ifDestinationsNBT = (NBTTagList) nbt.getTag("ifDestinations");
for (NBTBase ifDestinationNBT : ifDestinationsNBT) {
WeightedRiftDestination ifDestination = new WeightedRiftDestination();
ifDestination.readFromNBT((NBTTagCompound) ifDestinationNBT);
ifDestinations.add(ifDestination);
}
otherwiseDestinations = new LinkedList<>();
NBTTagList otherwiseDestinationsNBT = (NBTTagList) nbt.getTag("otherwiseDestinations");
for (NBTBase otherwiseDestinationNBT : otherwiseDestinationsNBT) {
WeightedRiftDestination otherwiseDestination = new WeightedRiftDestination();
otherwiseDestination.readFromNBT((NBTTagCompound) otherwiseDestinationNBT);
otherwiseDestinations.add(otherwiseDestination);
}
}
@Override
public NBTTagCompound writeToNBT(NBTTagCompound nbt) {
nbt = super.writeToNBT(nbt);
nbt.setFloat("weight", weight);
NBTTagList ifDestinationsNBT = new NBTTagList();
for (WeightedRiftDestination ifDestination : ifDestinations) {
ifDestinationsNBT.appendTag(ifDestination.writeToNBT(new NBTTagCompound()));
}
nbt.setTag("ifDestinations", ifDestinationsNBT);
NBTTagList otherwiseDestinationsNBT = new NBTTagList();
for (WeightedRiftDestination otherwiseDestination : otherwiseDestinations) {
otherwiseDestinationsNBT.appendTag(otherwiseDestination.writeToNBT(new NBTTagCompound()));
}
nbt.setTag("otherwiseDestinations", otherwiseDestinationsNBT);
return nbt;
}
@Override
public boolean teleport(TileEntityRift rift, Entity entity) {
if (entity instanceof EntityPlayer) DimDoors.chat((EntityPlayer) entity, "The entrance of this dungeon has not been linked. Either this is a bug or you are in dungeon-building mode.");
return false;
}
}

View file

@ -0,0 +1,31 @@
package com.zixiken.dimdoors.shared.rifts;
import com.zixiken.dimdoors.DimDoors;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.NBTTagCompound;
@Getter @AllArgsConstructor @Builder(toBuilder = true)
public class PocketExitDestination extends RiftDestination {
//public PocketExitDestination() {}
@Override
public void readFromNBT(NBTTagCompound nbt) {
super.readFromNBT(nbt);
}
@Override
public NBTTagCompound writeToNBT(NBTTagCompound nbt) {
nbt = super.writeToNBT(nbt);
return nbt;
}
@Override
public boolean teleport(TileEntityRift rift, Entity entity) {
if (entity instanceof EntityPlayer) DimDoors.chat((EntityPlayer) entity, "The exit of this dungeon has not been linked. Either this is a bug or you are in dungeon-building mode.");
return false;
}
}

View file

@ -0,0 +1,61 @@
package com.zixiken.dimdoors.shared.rifts;
import com.zixiken.dimdoors.shared.pockets.Pocket;
import com.zixiken.dimdoors.shared.pockets.PocketGenerator;
import com.zixiken.dimdoors.shared.pockets.PocketRegistry;
import com.zixiken.dimdoors.shared.world.DimDoorDimensions;
import ddutils.EntityUtils;
import ddutils.Location;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.ToString;
import net.minecraft.entity.Entity;
import net.minecraft.nbt.NBTTagCompound;
@Getter @AllArgsConstructor @Builder(toBuilder = true) @ToString
public class PrivateDestination extends RiftDestination {
//public PrivateDestination() {}
@Override
public void readFromNBT(NBTTagCompound nbt) {
super.readFromNBT(nbt);
}
@Override
public NBTTagCompound writeToNBT(NBTTagCompound nbt) {
nbt = super.writeToNBT(nbt);
return nbt;
}
@Override
public boolean teleport(TileEntityRift rift, Entity entity) {
String uuid = EntityUtils.getEntityOwnerUUID(entity);
if (uuid != null) {
PocketRegistry privatePocketRegistry = PocketRegistry.getForDim(DimDoorDimensions.getPrivateDimID());
RiftRegistry privateRiftRegistry = RiftRegistry.getForDim(DimDoorDimensions.getPrivateDimID());
Pocket pocket = privatePocketRegistry.getPocket(privatePocketRegistry.getPrivatePocketID(uuid));
if (pocket == null) { // generate the private pocket and get its entrance // TODO: use VirtualLocation.fromLoc vvv
pocket = PocketGenerator.generatePrivatePocket(rift.virtualLocation != null ? rift.virtualLocation.toBuilder().depth(-2).build() : null); // set to where the pocket was first created
pocket.setup();
privatePocketRegistry.setPrivatePocketID(uuid, pocket.getId());
((TileEntityRift) pocket.getEntrance().getTileEntity()).teleportTo(entity);
return true;
} else {
Location destLoc = privateRiftRegistry.getPrivatePocketEntrance(uuid); // get the last used entrance
if (destLoc == null) destLoc = pocket.getEntrance(); // if there's none, then set the target to the main entrance
if (destLoc == null) { // if the pocket entrance is gone, then create a new private pocket
pocket = PocketGenerator.generatePrivatePocket(rift.virtualLocation != null ? rift.virtualLocation.toBuilder().depth(-2).build() : null);
pocket.setup();
privatePocketRegistry.setPrivatePocketID(uuid, pocket.getId());
destLoc = pocket.getEntrance();
}
((TileEntityRift) destLoc.getTileEntity()).teleportTo(entity);
return true;
}
// privateRiftRegistry.setPrivatePocketEntrance(uuid, null); // --forget the last entered entrance-- Actually, remember it. We'll eventually store it only in the rift registry, not in the pocket.
} else {
return false; // TODO: There should be a way to get other entities into your private pocket, though. Add API for other mods.
}
}
}

View file

@ -0,0 +1,53 @@
package com.zixiken.dimdoors.shared.rifts;
import com.zixiken.dimdoors.DimDoors;
import com.zixiken.dimdoors.shared.pockets.PocketRegistry;
import com.zixiken.dimdoors.shared.world.DimDoorDimensions;
import com.zixiken.dimdoors.shared.world.pocketdimension.WorldProviderPersonalPocket;
import ddutils.EntityUtils;
import ddutils.Location;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.NBTTagCompound;
@Getter @AllArgsConstructor @Builder(toBuilder = true)
public class PrivatePocketExitDestination extends RiftDestination { // TODO: merge into PocketExit or Escape?
//public PrivatePocketExitDestination() {}
@Override
public void readFromNBT(NBTTagCompound nbt) {
super.readFromNBT(nbt);
}
@Override
public NBTTagCompound writeToNBT(NBTTagCompound nbt) {
nbt = super.writeToNBT(nbt);
return nbt;
}
@Override
public boolean teleport(TileEntityRift rift, Entity entity) { // TODO: don't use overworld rift, use last used entrance rift
Location destLoc;
String uuid = EntityUtils.getEntityOwnerUUID(entity);
if (uuid != null) {
PocketRegistry privatePocketRegistry = PocketRegistry.getForDim(DimDoorDimensions.getPrivateDimID());
RiftRegistry privateRiftRegistry = RiftRegistry.getForDim(DimDoorDimensions.getPrivateDimID());
destLoc = RiftRegistry.getOverworldRift(uuid);
RiftRegistry.setOverworldRift(uuid, null); // forget the last used overworld rift TODO: move this on dimension change event
if (rift.getWorld().provider instanceof WorldProviderPersonalPocket && privatePocketRegistry.getPrivatePocketID(uuid) == privatePocketRegistry.posToID(rift.getPos())) {
privateRiftRegistry.setPrivatePocketEntrance(uuid, rift.getLocation()); // Remember which exit was used for next time the pocket is entered
}
if (destLoc == null || !(destLoc.getTileEntity() instanceof TileEntityRift)) {
if (entity instanceof EntityPlayer) DimDoors.chat((EntityPlayer) entity, "Either you did not enter using a rift or the rift you entered through no longer exists!");
return false; // TODO: send to limbo
}
} else {
return false; // Non-player/owned entity tried to escape/leave private pocket
}
((TileEntityRift) destLoc.getTileEntity()).teleportTo(entity);
return true;
}
}

View file

@ -0,0 +1,41 @@
package com.zixiken.dimdoors.shared.rifts;
import ddutils.Location;
import ddutils.nbt.NBTUtils;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import net.minecraft.entity.Entity;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.math.Vec3i;
@Getter @AllArgsConstructor @Builder(toBuilder = true)
public class RelativeDestination extends RiftDestination { // TODO: use Vec3i
private Vec3i offset;
public RelativeDestination() {}
@Override
public void readFromNBT(NBTTagCompound nbt) {
super.readFromNBT(nbt);
offset = NBTUtils.readVec3i(nbt.getCompoundTag("offset"));
}
@Override
public NBTTagCompound writeToNBT(NBTTagCompound nbt) {
nbt = super.writeToNBT(nbt);
nbt.setTag("offset", NBTUtils.writeVec3i(offset));
return nbt;
}
@Override
public boolean teleport(TileEntityRift rift, Entity entity) {
rift.getWorld().getTileEntity(rift.getPos().add(offset));
return true;
}
@Override
public Location getReferencedRift(Location rift) {
return new Location(rift.getDim(), rift.getPos().add(offset));
}
}

View file

@ -1,410 +1,66 @@
package com.zixiken.dimdoors.shared.rifts; package com.zixiken.dimdoors.shared.rifts;
import ddutils.nbt.INBTStorable; import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import ddutils.Location; import ddutils.Location;
import ddutils.nbt.NBTUtils; import ddutils.nbt.INBTStorable;
import net.minecraft.nbt.NBTBase; import net.minecraft.entity.Entity;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3i;
import lombok.*; // Don't change import order! (Gradle bug): https://stackoverflow.com/questions/26557133/ import lombok.*; // Don't change import order! (Gradle bug): https://stackoverflow.com/questions/26557133/
import java.util.LinkedList; import java.lang.reflect.InvocationTargetException;
import java.util.List;
import java.util.UUID;
@SuppressWarnings("EmptyMethod") @Getter @ToString @EqualsAndHashCode
@Getter @ToString @EqualsAndHashCode @AllArgsConstructor(access = AccessLevel.PRIVATE) public abstract class RiftDestination implements INBTStorable {
public /*abstract*/ class RiftDestination implements INBTStorable { // TODO: fix lombok and make this abstract
@Getter private EnumType type;
@Getter protected RiftDestination oldDestination;
public enum EnumType { /*private*/ public static final BiMap<String, Class<? extends RiftDestination>> destinationRegistry = HashBiMap.create(); // TODO: move to RiftDestinationRegistry
RELATIVE, LOCAL, GLOBAL, NEW_PUBLIC, PRIVATE, LIMBO, AVAILABLE_LINK, POCKET_ENTRANCE, POCKET_EXIT, PRIVATE_POCKET_EXIT, ESCAPE //private String type;
/*package-private*/ WeightedRiftDestination weightedDestination;
public RiftDestination() {
//type = destinationRegistry.inverse().get(getClass());
} }
private RiftDestination() { public static RiftDestination readDestinationNBT(NBTTagCompound nbt) {
if (this instanceof RelativeDestination) { String type = nbt.getString("type");
type = EnumType.RELATIVE; Class<? extends RiftDestination> destinationClass = destinationRegistry.get(type);
} else if (this instanceof LocalDestination) { if (destinationClass == null) throw new RuntimeException("Unknown type '" + type + "'.");
type = EnumType.LOCAL; try {
} else if (this instanceof GlobalDestination) { RiftDestination destination = destinationClass.getConstructor().newInstance();
type = EnumType.GLOBAL;
} else if (this instanceof NewPublicDestination) {
type = EnumType.NEW_PUBLIC;
} else if (this instanceof PrivateDestination) {
type = EnumType.PRIVATE;
} else if (this instanceof LimboDestination) {
type = EnumType.LIMBO;
} else if (this instanceof AvailableLinkDestination) {
type = EnumType.AVAILABLE_LINK;
} else if (this instanceof PocketEntranceDestination) {
type = EnumType.POCKET_ENTRANCE;
} else if (this instanceof PocketExitDestination) {
type = EnumType.POCKET_EXIT;
} else if (this instanceof PrivatePocketExitDestination) {
type = EnumType.PRIVATE_POCKET_EXIT;
} else if (this instanceof EscapeDestination) {
type = EnumType.ESCAPE;
}
}
public static RiftDestination readDestinationNBT(NBTTagCompound nbt) { // TODO: store old AVAILABLE_LINK
RiftDestination destination = null;
EnumType type = EnumType.valueOf(nbt.getString("type"));
switch (type) {
case RELATIVE:
destination = new RelativeDestination();
break;
case LOCAL:
destination = new LocalDestination();
break;
case GLOBAL:
destination = new GlobalDestination();
break;
case NEW_PUBLIC:
destination = new NewPublicDestination();
break;
case PRIVATE:
destination = new PrivateDestination();
break;
case LIMBO:
destination = new LimboDestination();
break;
case AVAILABLE_LINK:
destination = new AvailableLinkDestination();
break;
case POCKET_ENTRANCE:
destination = new PocketEntranceDestination();
break;
case POCKET_EXIT:
destination = new PocketExitDestination();
break;
case PRIVATE_POCKET_EXIT:
destination = new PrivatePocketExitDestination();
break;
case ESCAPE:
destination = new EscapeDestination();
break;
}
destination.type = type;
destination.readFromNBT(nbt); destination.readFromNBT(nbt);
//destination.type = type;
return destination; return destination;
} catch (NoSuchMethodException | IllegalAccessException e) {
throw new RuntimeException("The class registered for type " + type + " must have a public no-args constructor.", e);
} catch (InstantiationException | InvocationTargetException e) {
throw new RuntimeException(e);
} }
public RiftDestination withOldDestination(RiftDestination oldDestination) {
RiftDestination dest = null;
if (this instanceof RelativeDestination) { // TODO: use type switch
dest = ((RelativeDestination) this).toBuilder().build();
dest.oldDestination = oldDestination;
} else if (this instanceof LocalDestination) {
dest = ((LocalDestination) this).toBuilder().build();
dest.oldDestination = oldDestination;
} else if (this instanceof GlobalDestination) {
dest = ((GlobalDestination) this).toBuilder().build();
dest.oldDestination = oldDestination;
} else if (this instanceof NewPublicDestination) {
dest = ((NewPublicDestination) this).toBuilder().build();
dest.oldDestination = oldDestination;
} else if (this instanceof PrivateDestination) {
dest = ((PrivateDestination) this).toBuilder().build();
dest.oldDestination = oldDestination;
} else if (this instanceof LimboDestination) {
dest = ((LimboDestination) this).toBuilder().build();
dest.oldDestination = oldDestination;
} else if (this instanceof AvailableLinkDestination) {
dest = ((AvailableLinkDestination) this).toBuilder().build();
dest.oldDestination = oldDestination;
} else if (this instanceof PocketEntranceDestination) {
dest = ((PocketEntranceDestination) this).toBuilder().build();
dest.oldDestination = oldDestination;
} else if (this instanceof PocketExitDestination) {
dest = ((PocketExitDestination) this).toBuilder().build();
dest.oldDestination = oldDestination;
} else if (this instanceof PrivatePocketExitDestination) {
dest = ((PrivatePocketExitDestination) this).toBuilder().build();
dest.oldDestination = oldDestination;
} else if (this instanceof EscapeDestination) {
dest = ((EscapeDestination) this).toBuilder().build();
dest.oldDestination = oldDestination;
}
return dest;
} }
@Override @Override
public void readFromNBT(NBTTagCompound nbt) { public void readFromNBT(NBTTagCompound nbt) { }
if (nbt.hasKey("oldDestination")) oldDestination = readDestinationNBT(nbt.getCompoundTag("oldDestination"));
}
@Override @Override
public NBTTagCompound writeToNBT(NBTTagCompound nbt) { public NBTTagCompound writeToNBT(NBTTagCompound nbt) {
if (oldDestination != null) nbt.setTag("oldDestination", oldDestination.writeToNBT(new NBTTagCompound())); String type = destinationRegistry.inverse().get(getClass());
nbt.setString("type", type.name()); if (type == null) throw new RuntimeException("No type has been registered for class" + getClass().getName() + " yet!");
nbt.setString("type", type);
return nbt; return nbt;
} }
public Location getReferencedRift(Location rift) { // TODO: change to getReferencedRifts
@Getter @AllArgsConstructor @Builder(toBuilder = true) return null;
public static class RelativeDestination extends RiftDestination { // TODO: use Vec3i
private Vec3i offset;
private RelativeDestination() {}
@Override
public void readFromNBT(NBTTagCompound nbt) {
super.readFromNBT(nbt);
offset = NBTUtils.readVec3i(nbt.getCompoundTag("offset"));
} }
@Override public void register(TileEntityRift rift) {
public NBTTagCompound writeToNBT(NBTTagCompound nbt) { Location loc = getReferencedRift(rift.getLocation());
nbt = super.writeToNBT(nbt); if (loc != null) RiftRegistry.addLink(rift.getLocation(), loc);
nbt.setTag("offset", NBTUtils.writeVec3i(offset));
return nbt;
}
} }
@Getter @AllArgsConstructor @Builder(toBuilder = true) public void unregister(TileEntityRift rift) {
public static class LocalDestination extends RiftDestination { // TODO: use BlockPos Location loc = getReferencedRift(rift.getLocation());
private BlockPos pos; if (loc != null) RiftRegistry.removeLink(rift.getLocation(), loc);
private LocalDestination() {}
@Override
public void readFromNBT(NBTTagCompound nbt) {
super.readFromNBT(nbt);
pos = new BlockPos(NBTUtils.readVec3i(nbt.getCompoundTag("pos")));
} }
@Override public abstract boolean teleport(TileEntityRift rift, Entity entity);
public NBTTagCompound writeToNBT(NBTTagCompound nbt) {
nbt = super.writeToNBT(nbt);
nbt.setTag("pos", NBTUtils.writeVec3i(pos));
return nbt;
}
}
@Getter @AllArgsConstructor @Builder(toBuilder = true)
public static class GlobalDestination extends RiftDestination { // TODO: location directly in nbt like minecraft?
private Location loc;
private GlobalDestination() {}
@Override
public void readFromNBT(NBTTagCompound nbt) {
super.readFromNBT(nbt);
loc = Location.readFromNBT(nbt.getCompoundTag("loc"));
}
@Override
public NBTTagCompound writeToNBT(NBTTagCompound nbt) {
nbt = super.writeToNBT(nbt);
nbt.setTag("loc", Location.writeToNBT(loc));
return nbt;
}
}
@Getter @AllArgsConstructor @Builder(toBuilder = true)
public static class NewPublicDestination extends RiftDestination { // TODO: more config options such as non-default size, etc.
//private NewPublicDestination() {}
@Override
public void readFromNBT(NBTTagCompound nbt) {
super.readFromNBT(nbt);
}
@Override
public NBTTagCompound writeToNBT(NBTTagCompound nbt) {
nbt = super.writeToNBT(nbt);
return nbt;
}
}
@Getter @AllArgsConstructor @Builder(toBuilder = true)
public static class PrivateDestination extends RiftDestination {
//private PrivateDestination() {}
@Override
public void readFromNBT(NBTTagCompound nbt) {
super.readFromNBT(nbt);
}
@Override
public NBTTagCompound writeToNBT(NBTTagCompound nbt) {
nbt = super.writeToNBT(nbt);
return nbt;
}
}
@Getter @AllArgsConstructor @Builder(toBuilder = true)
public static class LimboDestination extends RiftDestination {
//private LimboDestination() {}
@Override
public void readFromNBT(NBTTagCompound nbt) {
super.readFromNBT(nbt);
}
@Override
public NBTTagCompound writeToNBT(NBTTagCompound nbt) {
nbt = super.writeToNBT(nbt);
return nbt;
}
}
@Getter @AllArgsConstructor @Builder(toBuilder = true)
public static class AvailableLinkDestination extends RiftDestination { // TODO
private float newDungeonRiftProbability;
private float depthPenalization; // TODO: these make the equation assymetric
private float distancePenalization;
private float closenessPenalization;
private boolean dungeonRiftsOnly;
private boolean overworldRifts;
private boolean unstable;
private float entranceLinkWeight;
private float floatingRiftWeight;
private boolean noLinkBack;
// private int maxLinks;
@Builder.Default private UUID uuid = UUID.randomUUID();
// TODO: add a "safe" option to link only to a rift destination that has a non-zero weight
private AvailableLinkDestination() {}
@Override
public void readFromNBT(NBTTagCompound nbt) {
super.readFromNBT(nbt);
newDungeonRiftProbability = nbt.getFloat("newDungeonRiftProbability");
depthPenalization = nbt.getFloat("depthPenalization");
distancePenalization = nbt.getFloat("distancePenalization");
closenessPenalization = nbt.getFloat("closenessPenalization");
dungeonRiftsOnly = nbt.getBoolean("dungeonRiftsOnly");
overworldRifts = nbt.getBoolean("overworldRifts");
unstable = nbt.getBoolean("unstable");
noLinkBack = nbt.getBoolean("noLinkBack");
// maxLinks = nbt.getInteger("maxLinks");
uuid = nbt.getUniqueId("uuid");
}
@Override
public NBTTagCompound writeToNBT(NBTTagCompound nbt) {
nbt = super.writeToNBT(nbt);
nbt.setFloat("newDungeonRiftProbability", newDungeonRiftProbability);
nbt.setFloat("depthPenalization", depthPenalization);
nbt.setFloat("distancePenalization", distancePenalization);
nbt.setFloat("closenessPenalization", closenessPenalization);
nbt.setBoolean("dungeonRiftsOnly", dungeonRiftsOnly);
nbt.setBoolean("overworldRifts", overworldRifts);
nbt.setBoolean("unstable", unstable);
nbt.setBoolean("noLinkBack", noLinkBack);
// nbt.setInteger("maxLinks", maxLinks);
nbt.setUniqueId("uuid", uuid);
return nbt;
}
}
@Getter @AllArgsConstructor @Builder(toBuilder = true)
public static class PocketEntranceDestination extends RiftDestination {
private float weight;
@Builder.Default private List<WeightedRiftDestination> ifDestinations = new LinkedList<>(); // TODO addIfDestination method in builder
@Builder.Default private List<WeightedRiftDestination> otherwiseDestinations = new LinkedList<>(); // TODO addIfDestination method in builder
private PocketEntranceDestination() {}
@Override
public void readFromNBT(NBTTagCompound nbt) {
super.readFromNBT(nbt);
weight = nbt.getFloat("weight");
ifDestinations = new LinkedList<>();
NBTTagList ifDestinationsNBT = (NBTTagList) nbt.getTag("ifDestinations");
for (NBTBase ifDestinationNBT : ifDestinationsNBT) {
WeightedRiftDestination ifDestination = new WeightedRiftDestination();
ifDestination.readFromNBT((NBTTagCompound) ifDestinationNBT);
ifDestinations.add(ifDestination);
}
otherwiseDestinations = new LinkedList<>();
NBTTagList otherwiseDestinationsNBT = (NBTTagList) nbt.getTag("otherwiseDestinations");
for (NBTBase otherwiseDestinationNBT : otherwiseDestinationsNBT) {
WeightedRiftDestination otherwiseDestination = new WeightedRiftDestination();
otherwiseDestination.readFromNBT((NBTTagCompound) otherwiseDestinationNBT);
otherwiseDestinations.add(otherwiseDestination);
}
}
@Override
public NBTTagCompound writeToNBT(NBTTagCompound nbt) {
nbt = super.writeToNBT(nbt);
nbt.setFloat("weight", weight);
NBTTagList ifDestinationsNBT = new NBTTagList();
for (WeightedRiftDestination ifDestination : ifDestinations) {
ifDestinationsNBT.appendTag(ifDestination.writeToNBT(new NBTTagCompound()));
}
nbt.setTag("ifDestinations", ifDestinationsNBT);
NBTTagList otherwiseDestinationsNBT = new NBTTagList();
for (WeightedRiftDestination otherwiseDestination : otherwiseDestinations) {
otherwiseDestinationsNBT.appendTag(otherwiseDestination.writeToNBT(new NBTTagCompound()));
}
nbt.setTag("otherwiseDestinations", otherwiseDestinationsNBT);
return nbt;
}
}
@Getter @AllArgsConstructor @Builder(toBuilder = true)
public static class PocketExitDestination extends RiftDestination {
//private PocketExitDestination() {}
@Override
public void readFromNBT(NBTTagCompound nbt) {
super.readFromNBT(nbt);
}
@Override
public NBTTagCompound writeToNBT(NBTTagCompound nbt) {
nbt = super.writeToNBT(nbt);
return nbt;
}
}
@Getter @AllArgsConstructor @Builder(toBuilder = true)
public static class PrivatePocketExitDestination extends RiftDestination { // TODO: merge into PocketExit or Escape?
//private PrivatePocketExitDestination() {}
@Override
public void readFromNBT(NBTTagCompound nbt) {
super.readFromNBT(nbt);
}
@Override
public NBTTagCompound writeToNBT(NBTTagCompound nbt) {
nbt = super.writeToNBT(nbt);
return nbt;
}
}
@Getter @AllArgsConstructor @Builder(toBuilder = true)
public static class EscapeDestination extends RiftDestination {
@Override
public void readFromNBT(NBTTagCompound nbt) {
super.readFromNBT(nbt);
}
@Override
public NBTTagCompound writeToNBT(NBTTagCompound nbt) {
nbt = super.writeToNBT(nbt);
return nbt;
}
}
} }

View file

@ -1,5 +1,8 @@
package com.zixiken.dimdoors.shared.rifts; package com.zixiken.dimdoors.shared.rifts;
import com.google.common.collect.ConcurrentHashMultiset;
import com.google.common.collect.Multiset;
import com.zixiken.dimdoors.shared.world.DimDoorDimensions;
import ddutils.nbt.INBTStorable; // Don't change imports order! (Gradle bug): https://stackoverflow.com/questions/26557133/ import ddutils.nbt.INBTStorable; // Don't change imports order! (Gradle bug): https://stackoverflow.com/questions/26557133/
import ddutils.Location; import ddutils.Location;
import ddutils.WorldUtils; import ddutils.WorldUtils;
@ -23,9 +26,9 @@ public class RiftRegistry extends WorldSavedData {
private static final String DATA_NAME = DimDoors.MODID + "_rifts"; private static final String DATA_NAME = DimDoors.MODID + "_rifts";
@Getter private static final int DATA_VERSION = 0; // IMPORTANT: Update this and upgradeRegistry when making changes. @Getter private static final int DATA_VERSION = 0; // IMPORTANT: Update this and upgradeRegistry when making changes.
@Getter private Map<Location, RiftInfo> rifts = new HashMap<>(); // TODO: store relative locations too (better location class supporting relative, etc) @Getter private final Map<Location, RiftInfo> rifts = new HashMap<>(); // TODO: store relative locations too (better location class supporting relative, etc)
@Getter private Map<String, Location> privatePocketEntrances = new HashMap<>(); // TODO: more general group-group linking @Getter private final Map<String, Location> privatePocketEntrances = new HashMap<>(); // TODO: more general group-group linking
@Getter private Map<String, Location> escapeRifts = new HashMap<>(); @Getter private final Map<String, Location> overworldRifts = new HashMap<>();
@Getter private int dim; @Getter private int dim;
private World world; private World world;
@ -33,9 +36,9 @@ public class RiftRegistry extends WorldSavedData {
@AllArgsConstructor @EqualsAndHashCode @Builder(toBuilder = true) @AllArgsConstructor @EqualsAndHashCode @Builder(toBuilder = true)
public static class RiftInfo implements INBTStorable { public static class RiftInfo implements INBTStorable {
// IntelliJ warnings are wrong, Builder needs these initializers! // IntelliJ warnings are wrong, Builder needs these initializers!
@SuppressWarnings("UnusedAssignment") @Builder.Default @Getter private Set<AvailableLinkInfo> availableLinks = new HashSet<>(); @SuppressWarnings({"UnusedAssignment", "RedundantSuppression"}) @Builder.Default @Getter private Set<AvailableLinkInfo> availableLinks = new HashSet<>(); // TODO: multiset?
@SuppressWarnings("UnusedAssignment") @Builder.Default @Getter private Set<Location> sources = new HashSet<>(); @SuppressWarnings({"UnusedAssignment", "RedundantSuppression"}) @Builder.Default @Getter private Multiset<Location> sources = ConcurrentHashMultiset.create();
@SuppressWarnings("UnusedAssignment") @Builder.Default @Getter private Set<Location> destinations = new HashSet<>(); @SuppressWarnings({"UnusedAssignment", "RedundantSuppression"}) @Builder.Default @Getter private Multiset<Location> destinations = ConcurrentHashMultiset.create();
@AllArgsConstructor @NoArgsConstructor @EqualsAndHashCode @Builder(toBuilder = true) @AllArgsConstructor @NoArgsConstructor @EqualsAndHashCode @Builder(toBuilder = true)
public static class AvailableLinkInfo implements INBTStorable { public static class AvailableLinkInfo implements INBTStorable {
@ -62,8 +65,8 @@ public class RiftRegistry extends WorldSavedData {
public RiftInfo() { public RiftInfo() {
availableLinks = new HashSet<>(); availableLinks = new HashSet<>();
sources = new HashSet<>(); sources = ConcurrentHashMultiset.create();
destinations = new HashSet<>(); destinations = ConcurrentHashMultiset.create();
} }
@Override @Override
@ -166,12 +169,12 @@ public class RiftRegistry extends WorldSavedData {
privatePocketEntrances.put(uuid, rift); privatePocketEntrances.put(uuid, rift);
} }
NBTTagList escapeRiftsNBT = (NBTTagList) nbt.getTag("escapeRifts"); NBTTagList overworldRiftsNBT = (NBTTagList) nbt.getTag("overworldRifts");
for (NBTBase escapeRiftNBT : escapeRiftsNBT) { // TODO: move to NBTUtils for (NBTBase overworldRiftNBT : overworldRiftsNBT) { // TODO: move to NBTUtils
NBTTagCompound escapeRiftNBTC = (NBTTagCompound) escapeRiftNBT; NBTTagCompound overworldRiftNBTC = (NBTTagCompound) overworldRiftNBT;
String uuid = escapeRiftNBTC.getString("uuid"); String uuid = overworldRiftNBTC.getString("uuid");
Location rift = Location.readFromNBT(escapeRiftNBTC.getCompoundTag("location")); Location rift = Location.readFromNBT(overworldRiftNBTC.getCompoundTag("location"));
escapeRifts.put(uuid, rift); overworldRifts.put(uuid, rift);
} }
} }
@ -215,15 +218,15 @@ public class RiftRegistry extends WorldSavedData {
} }
nbt.setTag("privatePocketEntrances", privatePocketEntrancesNBT); nbt.setTag("privatePocketEntrances", privatePocketEntrancesNBT);
NBTTagList escapeRiftsNBT = new NBTTagList(); NBTTagList overworldRiftsNBT = new NBTTagList();
for (HashMap.Entry<String, Location> escapeRift : escapeRifts.entrySet()) { for (HashMap.Entry<String, Location> overworldRift : overworldRifts.entrySet()) {
if (escapeRift.getValue() == null) continue; if (overworldRift.getValue() == null) continue;
NBTTagCompound escapeRiftNBT = new NBTTagCompound(); NBTTagCompound overworldRiftNBT = new NBTTagCompound();
escapeRiftNBT.setString("uuid", escapeRift.getKey()); overworldRiftNBT.setString("uuid", overworldRift.getKey());
escapeRiftNBT.setTag("location", Location.writeToNBT(escapeRift.getValue())); overworldRiftNBT.setTag("location", Location.writeToNBT(overworldRift.getValue()));
escapeRiftsNBT.appendTag(escapeRiftNBT); overworldRiftsNBT.appendTag(overworldRiftNBT);
} }
nbt.setTag("escapeRifts", escapeRiftsNBT); nbt.setTag("overworldRifts", overworldRiftsNBT);
return nbt; return nbt;
} }
@ -253,9 +256,11 @@ public class RiftRegistry extends WorldSavedData {
RiftRegistry destinationRegistry = getRegistry(destination); RiftRegistry destinationRegistry = getRegistry(destination);
destinationRegistry.rifts.get(destination).sources.remove(rift); destinationRegistry.rifts.get(destination).sources.remove(rift);
destinationRegistry.markDirty(); destinationRegistry.markDirty();
TileEntityRift riftEntity = (TileEntityRift) destinationRegistry.world.getTileEntity(destination.getPos()); //TileEntityRift riftEntity = (TileEntityRift) destinationRegistry.world.getTileEntity(destination.getPos());
riftEntity.allSourcesGone(); //riftEntity.allSourcesGone(); // TODO
} }
getForDim(DimDoorDimensions.getPrivateDimID()).privatePocketEntrances.entrySet().removeIf(e -> e.getValue().equals(rift));
getForDim(0).overworldRifts.entrySet().removeIf(e -> e.getValue().equals(rift));
registry.markDirty(); registry.markDirty();
} }
@ -318,12 +323,12 @@ public class RiftRegistry extends WorldSavedData {
markDirty(); markDirty();
} }
public static Location getEscapeRift(String playerUUID) { // TODO: since this is per-world, move to different registry? public static Location getOverworldRift(String playerUUID) { // TODO: since this is per-world, move to different registry?
return getForDim(0).escapeRifts.get(playerUUID); // store in overworld, since that's where per-world player data is stored return getForDim(0).overworldRifts.get(playerUUID); // store in overworld, since that's where per-world player data is stored
} }
public static void setEscapeRift(String playerUUID, Location rift) { public static void setOverworldRift(String playerUUID, Location rift) {
getForDim(0).escapeRifts.put(playerUUID, rift); getForDim(0).overworldRifts.put(playerUUID, rift);
getForDim(0).markDirty(); getForDim(0).markDirty();
} }

View file

@ -3,10 +3,8 @@ package com.zixiken.dimdoors.shared.rifts;
import com.zixiken.dimdoors.DimDoors; import com.zixiken.dimdoors.DimDoors;
import com.zixiken.dimdoors.shared.VirtualLocation; import com.zixiken.dimdoors.shared.VirtualLocation;
import com.zixiken.dimdoors.shared.pockets.Pocket; import com.zixiken.dimdoors.shared.pockets.Pocket;
import com.zixiken.dimdoors.shared.pockets.PocketGenerator;
import com.zixiken.dimdoors.shared.pockets.PocketRegistry; import com.zixiken.dimdoors.shared.pockets.PocketRegistry;
import com.zixiken.dimdoors.shared.rifts.RiftDestination.*; import ddutils.EntityUtils;
import com.zixiken.dimdoors.shared.rifts.RiftRegistry.RiftInfo.AvailableLinkInfo;
import ddutils.Location; import ddutils.Location;
import ddutils.math.MathUtils; import ddutils.math.MathUtils;
import ddutils.TeleportUtils; import ddutils.TeleportUtils;
@ -15,11 +13,7 @@ import com.zixiken.dimdoors.shared.world.DimDoorDimensions;
import lombok.Getter; import lombok.Getter;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.IEntityOwnable;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.projectile.*;
import net.minecraft.nbt.NBTBase; import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList; import net.minecraft.nbt.NBTTagList;
@ -65,10 +59,12 @@ public abstract class TileEntityRift extends TileEntity implements ITickable { /
preserveRotation = oldRift.preserveRotation; preserveRotation = oldRift.preserveRotation;
yaw = oldRift.yaw; yaw = oldRift.yaw;
pitch = oldRift.pitch; pitch = oldRift.pitch;
if (oldRift.isFloating() != isFloating()) updateAvailableLinks();
markDirty(); markDirty();
} }
// Reading/writing to NBT
@Override @Override
public void readFromNBT(NBTTagCompound nbt) { public void readFromNBT(NBTTagCompound nbt) {
super.readFromNBT(nbt); super.readFromNBT(nbt);
@ -113,6 +109,35 @@ public abstract class TileEntityRift extends TileEntity implements ITickable { /
return nbt; return nbt;
} }
@Override
public NBTTagCompound getUpdateTag() {
return serializeNBT();
}
@Override
public void handleUpdateTag(NBTTagCompound tag) {
deserializeNBT(tag);
}
@Override
public SPacketUpdateTileEntity getUpdatePacket() {
return new SPacketUpdateTileEntity(getPos(), 1, serializeNBT());
}
@Override
@SideOnly(Side.CLIENT)
public void onDataPacket(NetworkManager net, SPacketUpdateTileEntity pkt) {
deserializeNBT(pkt.getNbtCompound());
}
// Use vanilla behavior of refreshing only when block changes, not state (otherwise, opening the door would destroy the tile entity)
@Override
public boolean shouldRefresh(World world, BlockPos pos, IBlockState oldState, IBlockState newSate) {
return oldState.getBlock() != newSate.getBlock();
}
// Modification functions
public void setVirtualLocation(VirtualLocation virtualLocation) { public void setVirtualLocation(VirtualLocation virtualLocation) {
this.virtualLocation = virtualLocation; this.virtualLocation = virtualLocation;
updateAvailableLinks(); updateAvailableLinks();
@ -129,31 +154,20 @@ public abstract class TileEntityRift extends TileEntity implements ITickable { /
public void addDestination(RiftDestination destination, float weight, int group) { public void addDestination(RiftDestination destination, float weight, int group) {
riftStateChanged = true; riftStateChanged = true;
destinations.add(new WeightedRiftDestination(destination, weight, group)); destinations.add(new WeightedRiftDestination(destination, weight, group));
registerDest(destination); if (isRegistered()) destination.register(this);
markDirty(); markDirty();
} }
public void removeDestination(int index) { public void removeDestination(int index) {
riftStateChanged = true; riftStateChanged = true;
unregisterDest(destinations.remove(index).getDestination()); RiftDestination dest = destinations.remove(index).getDestination();
markDirty(); if (isRegistered()) dest.unregister(this);
}
public void removeDestinationLoc(Location location) {
Iterator<WeightedRiftDestination> destinationIterator = destinations.iterator();
while (destinationIterator.hasNext()) {
RiftDestination dest = destinationIterator.next().getDestination();
if (destinationToLocation(dest).equals(location)) {
destinationIterator.remove();
unregisterDest(dest);
}
}
markDirty(); markDirty();
} }
public void clearDestinations() { public void clearDestinations() {
for (WeightedRiftDestination wdest : destinations) { if (isRegistered()) for (WeightedRiftDestination wdest : destinations) {
unregisterDest(wdest.getDestination()); wdest.getDestination().unregister(this);
} }
destinations.clear(); destinations.clear();
markDirty(); markDirty();
@ -164,78 +178,124 @@ public abstract class TileEntityRift extends TileEntity implements ITickable { /
addDestination(destination, 1, 0); addDestination(destination, 1, 0);
} }
public Location destinationToLocation(RiftDestination dest) { public void setChaosWeight(int chaosWeight) {
switch (dest.getType()) { // TODO: these need a superclass and a single translation method this.chaosWeight = chaosWeight;
case RELATIVE: markDirty();
RelativeDestination relativeDest = (RelativeDestination) dest;
return new Location(world, pos.add(relativeDest.getOffset()));
case LOCAL:
LocalDestination localDest = (LocalDestination) dest;
return new Location(world, localDest.getPos());
case GLOBAL:
GlobalDestination globalDest = (GlobalDestination) dest;
return globalDest.getLoc();
}
return null;
} }
public void registerDest(RiftDestination dest) { public void markStateChanged() {
if (!isRegistered()) return; riftStateChanged = true;
Location destLoc = destinationToLocation(dest); markDirty();
if (destLoc != null) RiftRegistry.addLink(new Location(world, pos), destLoc);
if (dest.getType() == EnumType.AVAILABLE_LINK) {
AvailableLinkDestination linkDest = (AvailableLinkDestination) dest;
AvailableLinkInfo linkInfo = AvailableLinkInfo.builder()
.weight(isEntrance() ? linkDest.getEntranceLinkWeight() : linkDest.getFloatingRiftWeight())
.virtualLocation(virtualLocation)
.uuid(linkDest.getUuid())
.build();
RiftRegistry.addAvailableLink(new Location(world, pos), linkInfo);
}
} }
public void updateAvailableLinks() { public void makeDestinationPermanent(WeightedRiftDestination weightedDestination, Location destLoc) {
if (!isRegistered()) return; riftStateChanged = true;
RiftRegistry.clearAvailableLinks(new Location(world, pos)); RiftDestination newDest;
for (WeightedRiftDestination wdest : destinations) { if (WorldUtils.getDim(world) == destLoc.getDim()) {
RiftDestination dest = wdest.getDestination(); newDest = new LocalDestination(destLoc.getPos()); // TODO: RelativeDestination instead?
if (dest.getType() == EnumType.AVAILABLE_LINK) { } else {
AvailableLinkDestination linkDest = (AvailableLinkDestination) dest; newDest = new GlobalDestination(destLoc);
AvailableLinkInfo linkInfo = AvailableLinkInfo.builder()
.weight(isEntrance() ? linkDest.getEntranceLinkWeight() : linkDest.getFloatingRiftWeight())
.virtualLocation(virtualLocation)
.uuid(linkDest.getUuid())
.build();
RiftRegistry.addAvailableLink(new Location(world, pos), linkInfo);
}
} }
destinations.remove(weightedDestination);
destinations.add(new WeightedRiftDestination(newDest, weightedDestination.getWeight(), weightedDestination.getGroup(), weightedDestination.getDestination()));
markDirty();
} }
public void unregisterDest(RiftDestination dest) { // Registry
if (!isRegistered()) return;
Location destLoc = destinationToLocation(dest);
if (destLoc != null) RiftRegistry.removeLink(new Location(world, pos), destLoc);
}
public boolean isRegistered() { public boolean isRegistered() {
return world != null && RiftRegistry.getRiftInfo(new Location(world, pos)) != null; return world != null && RiftRegistry.getRiftInfo(new Location(world, pos)) != null;
} }
// Make sure virtualLocation != null before calling! public void register() {
public void register() { // registers or reregisters the rift TODO: what if it's already registered? if (isRegistered()) return;
Location loc = new Location(world, pos); Location loc = new Location(world, pos);
RiftRegistry.addRift(loc); RiftRegistry.addRift(loc);
for (WeightedRiftDestination weightedDest : destinations) { for (WeightedRiftDestination weightedDest : destinations) {
registerDest(weightedDest.getDestination()); weightedDest.getDestination().register(this);
} }
} }
public void unregister() { public void unregister() {
if (!isRegistered()) return; if (!isRegistered()) return;
RiftRegistry.removeRift(new Location(world, pos)); RiftRegistry.removeRift(new Location(world, pos));
if (DimDoorDimensions.isPocketDimension(WorldUtils.getDim(world))) {
PocketRegistry pocketRegistry = PocketRegistry.getForDim(WorldUtils.getDim(world));
Pocket pocket = pocketRegistry.getPocketAt(pos);
if (pocket != null && pocket.getEntrance() != null && pocket.getEntrance().getPos().equals(pos)) {
pocket.setEntrance(null);
pocketRegistry.markDirty();
}
}
// TODO: inform pocket that entrance was destroyed (we'll probably need an isPrivate field on the pocket) // TODO: inform pocket that entrance was destroyed (we'll probably need an isPrivate field on the pocket)
} }
public void updateAvailableLinks() { // Update available link info on rift type change or on virtualLocation change
if (!isRegistered()) return;
RiftRegistry.clearAvailableLinks(new Location(world, pos));
for (WeightedRiftDestination wdest : destinations) {
RiftDestination dest = wdest.getDestination();
if (dest instanceof AvailableLinkDestination) {
dest.register(this);
}
}
}
public void destinationGone(Location loc) {
ListIterator<WeightedRiftDestination> wdestIterator = destinations.listIterator();
while (wdestIterator.hasNext()) {
WeightedRiftDestination wdest = wdestIterator.next();
RiftDestination dest = wdest.getDestination();
if (loc.equals(dest.getReferencedRift(getLocation()))) {
wdestIterator.remove();
RiftDestination oldDest = wdest.getOldDestination();
if (oldDest != null) {
wdestIterator.add(new WeightedRiftDestination(oldDest, wdest.getWeight(), wdest.getGroup()));
}
}
}
destinations.removeIf(weightedRiftDestination -> loc.equals(weightedRiftDestination.getDestination().getReferencedRift(getLocation())));
}
// Teleport logic
public boolean teleport(Entity entity) {
riftStateChanged = false;
// Check that the rift has destinations
if (destinations.size() == 0) {
if (entity instanceof EntityPlayer) DimDoors.chat((EntityPlayer) entity, "This rift has no destinations!");
return false;
}
// Get a random destination based on the weights
Map<WeightedRiftDestination, Float> weightMap = new HashMap<>(); // TODO: cache this, faster implementation of single rift
for (WeightedRiftDestination destination : destinations) {
weightMap.put(destination, destination.getWeight());
}
WeightedRiftDestination weightedDestination = MathUtils.weightedRandom(weightMap);
// Remove destinations from other groups if makeDestinationPermanent is true
if(makeDestinationPermanent) {
destinations.removeIf(wdest -> wdest.getGroup() != weightedDestination.getGroup());
markDirty();
}
// Attempt a teleport
try {
if (weightedDestination.getDestination().teleport(this, entity)) {
// Set last used rift if necessary
// TODO: use entity UUID rather than player UUID!
if (entity instanceof EntityPlayer && !DimDoorDimensions.isPocketDimension(WorldUtils.getDim(world))) { // TODO: What about player-owned entities? We should store their exit rift separately to avoid having problems if they enter different rifts
RiftRegistry.setOverworldRift(EntityUtils.getEntityOwnerUUID(entity), new Location(world, pos));
}
return true;
}
} catch (Exception e) {
if (entity instanceof EntityPlayer) DimDoors.chat((EntityPlayer) entity, "There was an exception while teleporting!");
DimDoors.log.error("Teleporting failed with the following exception: ", e);
}
return false;
}
public void teleportTo(Entity entity) { // TODO: new velocity angle if !preserveRotation? public void teleportTo(Entity entity) { // TODO: new velocity angle if !preserveRotation?
float newYaw = entity.rotationYaw; float newYaw = entity.rotationYaw;
float newPitch = entity.rotationYaw; float newPitch = entity.rotationYaw;
@ -246,245 +306,10 @@ public abstract class TileEntityRift extends TileEntity implements ITickable { /
TeleportUtils.teleport(entity, new Location(world, pos), newPitch, newYaw); TeleportUtils.teleport(entity, new Location(world, pos), newPitch, newYaw);
} }
public boolean teleport(Entity entity) { try { // TODO: return failiure message string rather than boolean // Info
riftStateChanged = false; protected abstract boolean isFloating(); // TODO: make non-abstract?
if (destinations.size() == 0) {
if (entity instanceof EntityPlayer) DimDoors.chat((EntityPlayer) entity, "This rift has no destinations!");
return false;
}
Map<WeightedRiftDestination, Float> weightMap = new HashMap<>(); // TODO: cache this, faster implementation of single rift public Location getLocation() {
for (WeightedRiftDestination destination : destinations) { return new Location(world, pos);
weightMap.put(destination, destination.getWeight());
} }
WeightedRiftDestination weightedDestination = MathUtils.weightedRandom(weightMap);
int group = weightedDestination.getGroup();
if(makeDestinationPermanent) {
destinations.removeIf(wdest -> wdest.getGroup() != group);
markDirty();
}
RiftDestination dest = weightedDestination.getDestination();
Location destLoc;
GlobalDestination destHere = new GlobalDestination(new Location(world, pos)); // TODO: local if possible
String uuid = getEntityOwnerUUID(entity);
switch (dest.getType()) {
case RELATIVE:
case LOCAL:
case GLOBAL:
destLoc = destinationToLocation(dest);
break;
case NEW_PUBLIC:
Pocket pocket = PocketGenerator.generatePublicPocket(virtualLocation != null ? virtualLocation.toBuilder().depth(-1).build() : null); // TODO: random transform
pocket.setup();
pocket.linkPocketTo(destHere);
destLoc = pocket.getEntrance();
if (destLoc != null) makeDestinationPermanent(weightedDestination, destLoc);
break;
case PRIVATE: // TODO: move logic to PrivatePocketTeleportDestination
if (uuid != null) {
PocketRegistry privatePocketRegistry = PocketRegistry.getForDim(DimDoorDimensions.getPrivateDimID());
RiftRegistry privateRiftRegistry = RiftRegistry.getForDim(DimDoorDimensions.getPrivateDimID());
/*Pocket*/ pocket = privatePocketRegistry.getPocket(privatePocketRegistry.getPrivatePocketID(uuid));
if (pocket == null) { // generate the private pocket and get its entrance
pocket = PocketGenerator.generatePrivatePocket(virtualLocation != null ? virtualLocation.toBuilder().depth(-2).build() : null); // set to where the pocket was first created
pocket.setup();
privatePocketRegistry.setPrivatePocketID(uuid, pocket.getId());
destLoc = pocket.getEntrance();
} else {
destLoc = privateRiftRegistry.getPrivatePocketEntrance(uuid); // get the last used entrance
if (destLoc == null) destLoc = pocket.getEntrance(); // if there's none, then set the target to the main entrance
if (destLoc == null) { // if the pocket entrance is gone, then create a new private pocket
pocket = PocketGenerator.generatePrivatePocket(virtualLocation != null ? virtualLocation.toBuilder().depth(-2).build() : null);
pocket.setup();
privatePocketRegistry.setPrivatePocketID(uuid, pocket.getId());
destLoc = pocket.getEntrance();
}
}
// privateRiftRegistry.setPrivatePocketEntrance(uuid, null); // --forget the last entered entrance-- Actually, remember it. We'll eventually store it only in the rift registry, not in the pocket.
} else {
return false; // TODO: There should be a way to get other entities into your private pocket, though. Add API for other mods.
}
break;
case ESCAPE:
case PRIVATE_POCKET_EXIT:
if (uuid != null) {
RiftRegistry privateRiftRegistry = RiftRegistry.getForDim(DimDoorDimensions.getPrivateDimID());
destLoc = RiftRegistry.getEscapeRift(uuid);
RiftRegistry.setEscapeRift(uuid, null); // forget the last used escape rift
if (dest.getType() == EnumType.PRIVATE_POCKET_EXIT) {
privateRiftRegistry.setPrivatePocketEntrance(uuid, new Location(world, pos)); // Remember which exit was used for next time the pocket is entered
} else if (dest.getType() == EnumType.ESCAPE) {
// TODO: teleport the player to random coordinates based on depth around destLoc
return true;
}
if (destLoc == null) {
if (entity instanceof EntityPlayer) DimDoors.chat((EntityPlayer) entity, "You tried to escape a pocket or leave your private pocket, but you teleported into it!");
return false; // TODO: limbo?
}
} else {
return false; // Non-player/owned entity tried to escape/leave private pocket
}
break;
case LIMBO: // TODO: move logic to LimboTeleportDestination
throw new RuntimeException("Not yet implemented!"); // TODO: random coordinates based on VirtualLocation
case AVAILABLE_LINK: // TODO: chaos door
AvailableLinkDestination linkDest = (AvailableLinkDestination) dest;
Map<AvailableLinkInfo, Float> possibleDestWeightMap = new HashMap<>();
for (AvailableLinkInfo link : RiftRegistry.getAvailableLinks()) {
VirtualLocation otherVLoc = link.getVirtualLocation();
float weight2 = link.getWeight();
if (weight2 == 0) continue;
double depthDiff = Math.abs(virtualLocation.getDepth() - otherVLoc.getDepth());
double distanceSq = new BlockPos(virtualLocation.getX(), virtualLocation.getY(), virtualLocation.getZ())
.distanceSq(new BlockPos(otherVLoc.getX(), otherVLoc.getY(), otherVLoc.getZ()));
float distanceExponent = linkDest.getDistancePenalization();
float depthExponent = linkDest.getDepthPenalization();
float closenessExponent = linkDest.getClosenessPenalization();
float weight = (float) Math.abs(weight2/(Math.pow(depthDiff, depthExponent) * Math.pow(distanceSq, 0.5 * distanceExponent))); // TODO: fix formula
float currentWeight = possibleDestWeightMap.get(link);
possibleDestWeightMap.put(link, currentWeight + weight);
}
AvailableLinkInfo selectedLink = MathUtils.weightedRandom(possibleDestWeightMap);
destLoc = selectedLink.getLocation();
if (!linkDest.isUnstable()) makeDestinationPermanent(weightedDestination, destLoc);
TileEntityRift destRift = (TileEntityRift) destLoc.getWorld().getTileEntity(destLoc.getPos()); // Link the other rift back if necessary
ListIterator<WeightedRiftDestination> wdestIterator = destRift.destinations.listIterator();
WeightedRiftDestination selectedWDest = null;
while (wdestIterator.hasNext()) {
WeightedRiftDestination wdest = wdestIterator.next();
RiftDestination otherDest = wdest.getDestination();
if (otherDest.getType() == EnumType.AVAILABLE_LINK && ((AvailableLinkDestination) otherDest).getUuid() == selectedLink.getUuid()) {
selectedWDest = wdest;
wdestIterator.remove();
break;
}
}
AvailableLinkDestination selectedAvailableLinkDest = (AvailableLinkDestination) selectedWDest.getDestination();
if (!selectedAvailableLinkDest.isNoLinkBack()) {
destRift.makeDestinationPermanent(selectedWDest, new Location(world, pos));
}
break;
case POCKET_ENTRANCE:
case POCKET_EXIT:
if (entity instanceof EntityPlayer) DimDoors.chat((EntityPlayer) entity, "The entrance/exit of this dungeon has not been linked. Either this is a bug or you are in dungeon-building mode.");
return false;
default:
throw new RuntimeException("That rift type is not implemented in TileRiftEntity.teleport, this is a bug.");
}
if (destLoc == null) {
if (entity instanceof EntityPlayer) DimDoors.chat((EntityPlayer) entity, "The destination was null. Either this is a bug in TileEntityRift.java, or the pocket does not have an entrance!");
return false;
}
TileEntity tileEntityAtLoc = destLoc.getWorld().getTileEntity(destLoc.getPos());
if (!(tileEntityAtLoc instanceof TileEntityRift)) throw new RuntimeException("The rift referenced by this rift does not exist, this is a bug.");
TileEntityRift destRift = (TileEntityRift) tileEntityAtLoc;
if (entity instanceof EntityPlayer && !DimDoorDimensions.isPocketDimension(WorldUtils.getDim(world))) { // TODO: What about player-owned entities? We should store their exit rift separately to avoid having problems if they enter different rifts
RiftRegistry.setEscapeRift(uuid, new Location(world, pos));
}
destRift.teleportTo(entity);
return true;
} catch (Exception e) {
if (entity instanceof EntityPlayer) DimDoors.chat((EntityPlayer) entity, "There was an exception while teleporting!");
DimDoors.log.error("Teleporting failed with the following exception: ", e);
return false;
}
}
public String getEntityOwnerUUID(Entity entity) { // TODO: make this recursive, move to utils
if (entity instanceof EntityThrowable) entity = ((EntityThrowable) entity).getThrower();
if (entity instanceof EntityArrow) entity = ((EntityArrow) entity).shootingEntity;
if (entity instanceof EntityFireball) entity = ((EntityFireball) entity).shootingEntity;
if (entity instanceof EntityLlamaSpit) entity = ((EntityLlamaSpit) entity).owner; // Llamas are ownable
if (entity.getControllingPassenger() != null && !(entity instanceof EntityPlayer)) entity = entity.getControllingPassenger();
if (entity.getPassengers().size() > 0) entity.getPassengers().get(0);
if (entity instanceof EntityFishHook) entity = ((EntityFishHook) entity).getAngler();
if (entity instanceof EntityLiving && ((EntityLiving) entity).getLeashed()) entity = ((EntityLiving) entity).getLeashHolder();
if (entity instanceof EntityItem) {
String playerName = ((EntityItem) entity).getThrower();
EntityPlayer player = null;
if (playerName != null) player = entity.world.getPlayerEntityByName(((EntityItem) entity).getThrower());
if (player != null) entity = player;
}
if (entity instanceof IEntityOwnable && ((IEntityOwnable) entity).getOwnerId() != null) return ((IEntityOwnable) entity).getOwnerId().toString();
if (entity instanceof EntityPlayer) return entity.getUniqueID().toString(); // ownable players shouldn't be a problem, but just in case we have a slave mod, check their owner's uuid first to send them to their owner's pocket :)
return null;
}
private void makeDestinationPermanent(WeightedRiftDestination weightedDestination, Location destLoc) {
riftStateChanged = true;
RiftDestination newDest;
if (WorldUtils.getDim(world) == destLoc.getDim()) {
newDest = new LocalDestination(destLoc.getPos()); // TODO: RelativeDestination instead?
} else {
newDest = new GlobalDestination(destLoc);
}
newDest = newDest.withOldDestination(weightedDestination.getDestination());
destinations.remove(weightedDestination);
destinations.add(new WeightedRiftDestination(newDest, weightedDestination.getWeight(), weightedDestination.getGroup()));
markDirty();
}
public void destinationGone(Location loc) {
ListIterator<WeightedRiftDestination> wdestIterator = destinations.listIterator();
while (wdestIterator.hasNext()) {
WeightedRiftDestination wdest = wdestIterator.next();
RiftDestination dest = wdest.getDestination();
if (loc.equals(destinationToLocation(dest))) {
wdestIterator.remove();
RiftDestination oldDest = dest.getOldDestination();
if (oldDest != null) {
wdestIterator.add(new WeightedRiftDestination(oldDest, wdest.getWeight(), wdest.getGroup()));
}
}
}
destinations.removeIf(weightedRiftDestination -> loc.equals(destinationToLocation(weightedRiftDestination.getDestination())));
}
public void allSourcesGone() {
// TODO
}
@Override
public boolean shouldRefresh(World world, BlockPos pos, IBlockState oldState, IBlockState newSate) {
return oldState.getBlock() != newSate.getBlock();
}
@Override
public NBTTagCompound getUpdateTag() {
return serializeNBT();
}
@Override
public void handleUpdateTag(NBTTagCompound tag) {
deserializeNBT(tag);
}
public void markStateChanged() {
riftStateChanged = true;
markDirty();
}
@Override
public SPacketUpdateTileEntity getUpdatePacket() {
return new SPacketUpdateTileEntity(getPos(), 1, serializeNBT());
}
@Override
@SideOnly(Side.CLIENT)
public void onDataPacket(NetworkManager net, SPacketUpdateTileEntity pkt) {
deserializeNBT(pkt.getNbtCompound());
}
public void setChaosWeight(int chaosWeight) {
this.chaosWeight = chaosWeight;
markDirty();
}
public abstract boolean isEntrance(); // TODO: replace with chooseWeight function
} }

View file

@ -1,23 +1,39 @@
package com.zixiken.dimdoors.shared.rifts; package com.zixiken.dimdoors.shared.rifts;
import ddutils.nbt.INBTStorable; import ddutils.nbt.INBTStorable;
import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagCompound;
@NoArgsConstructor @AllArgsConstructor @NoArgsConstructor
public class public class WeightedRiftDestination implements INBTStorable { // TODO: generics
WeightedRiftDestination implements INBTStorable { // TODO: generics
@Getter private RiftDestination destination; @Getter private RiftDestination destination;
@Getter private float weight; @Getter private float weight;
@Getter private int group; @Getter private int group;
@Getter private RiftDestination oldDestination; // TODO: move to RiftDestination?
public WeightedRiftDestination(RiftDestination destination, float weight, int group, RiftDestination oldDestination) {
this();
this.destination = destination;
this.weight = weight;
this.group = group;
this.oldDestination = oldDestination;
if (destination != null) destination.weightedDestination = this;
if (oldDestination != null) oldDestination.weightedDestination = this;
}
public WeightedRiftDestination(RiftDestination destination, float weight, int group) {
this(destination, weight, group, null);
}
@Override @Override
public void readFromNBT(NBTTagCompound nbt) { public void readFromNBT(NBTTagCompound nbt) {
destination = RiftDestination.readDestinationNBT(nbt); // TODO: subtag? destination = RiftDestination.readDestinationNBT(nbt); // TODO: subtag?
weight = nbt.getFloat("weight"); weight = nbt.getFloat("weight");
group = nbt.getInteger("group"); group = nbt.getInteger("group");
if (nbt.hasKey("oldDestination")) oldDestination = RiftDestination.readDestinationNBT(nbt.getCompoundTag("oldDestination"));
if (destination != null) destination.weightedDestination = this;
if (oldDestination != null) oldDestination.weightedDestination = this;
} }
@Override @Override
@ -25,6 +41,7 @@ WeightedRiftDestination implements INBTStorable { // TODO: generics
nbt = destination.writeToNBT(nbt); nbt = destination.writeToNBT(nbt);
nbt.setFloat("weight", weight); nbt.setFloat("weight", weight);
nbt.setInteger("group", group); nbt.setInteger("group", group);
if (oldDestination != null) nbt.setTag("oldDestination", oldDestination.writeToNBT(new NBTTagCompound()));
return nbt; return nbt;
} }
} }

View file

@ -6,7 +6,7 @@ import net.minecraft.util.SoundEvent;
import net.minecraftforge.event.RegistryEvent; import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
public class ModSounds { public final class ModSounds {
// Don't forget to change sounds.json too if you're changing an ID! // Don't forget to change sounds.json too if you're changing an ID!
public static final SoundEvent CRACK = create("crack"); public static final SoundEvent CRACK = create("crack");

View file

@ -1,15 +1,11 @@
package com.zixiken.dimdoors.shared.tileentities; package com.zixiken.dimdoors.shared.tileentities;
import com.zixiken.dimdoors.shared.pockets.PocketRegistry;
import com.zixiken.dimdoors.shared.rifts.TileEntityRift; import com.zixiken.dimdoors.shared.rifts.TileEntityRift;
import ddutils.Location; import ddutils.Location;
import ddutils.render.RGBA; import ddutils.render.RGBA;
import ddutils.TeleportUtils; import ddutils.TeleportUtils;
import ddutils.WorldUtils;
import com.zixiken.dimdoors.shared.world.DimDoorDimensions;
import lombok.Getter; import lombok.Getter;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumFacing;
@ -117,7 +113,7 @@ public class TileEntityEntranceRift extends TileEntityRift {
} }
@Override @Override
public boolean isEntrance() { public boolean isFloating() {
return true; return false;
} }
} }

View file

@ -126,7 +126,7 @@ public class TileEntityFloatingRift extends TileEntityRift implements ITickable
} }
@Override @Override
public boolean isEntrance() { public boolean isFloating() {
return false; return true;
} }
} }

View file

@ -4,9 +4,7 @@ import com.zixiken.dimdoors.DimDoors;
import com.zixiken.dimdoors.server.DDProxyServer; import com.zixiken.dimdoors.server.DDProxyServer;
import com.zixiken.dimdoors.shared.blocks.BlockFabric; import com.zixiken.dimdoors.shared.blocks.BlockFabric;
import com.zixiken.dimdoors.shared.blocks.ModBlocks; import com.zixiken.dimdoors.shared.blocks.ModBlocks;
import com.zixiken.dimdoors.shared.rifts.RiftDestination; import com.zixiken.dimdoors.shared.rifts.*;
import com.zixiken.dimdoors.shared.rifts.TileEntityRift;
import com.zixiken.dimdoors.shared.rifts.WeightedRiftDestination;
import ddutils.schem.Schematic; import ddutils.schem.Schematic;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockDoor; import net.minecraft.block.BlockDoor;
@ -22,7 +20,6 @@ import net.minecraftforge.fml.common.ModContainer;
import net.minecraftforge.fml.common.ModMetadata; import net.minecraftforge.fml.common.ModMetadata;
import net.minecraftforge.registries.GameData; import net.minecraftforge.registries.GameData;
import net.minecraftforge.registries.RegistryManager; import net.minecraftforge.registries.RegistryManager;
import ddutils.math.MathUtils;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.File; import java.io.File;
@ -36,7 +33,7 @@ import java.util.List;
/** /**
* @author Robijnvogel * @author Robijnvogel
*/ */
public class PocketSchematicGenerator { public final class PocketSchematicGenerator {
// Run "gradlew generatePocketSchematics" to generate the pocket schematics // Run "gradlew generatePocketSchematics" to generate the pocket schematics
@SuppressWarnings("UseOfSystemOutOrSystemErr") @SuppressWarnings("UseOfSystemOutOrSystemErr")
@ -50,6 +47,7 @@ public class PocketSchematicGenerator {
Loader.instance().setActiveModContainer(mc); Loader.instance().setActiveModContainer(mc);
ModBlocks.registerBlocks(new RegistryEvent.Register(GameData.BLOCKS, RegistryManager.ACTIVE.getRegistry(GameData.BLOCKS))); ModBlocks.registerBlocks(new RegistryEvent.Register(GameData.BLOCKS, RegistryManager.ACTIVE.getRegistry(GameData.BLOCKS)));
new DDProxyServer().registerTileEntities(); new DDProxyServer().registerTileEntities();
new DDProxyServer().registerRiftDestinations();
Loader.instance().setActiveModContainer(null); Loader.instance().setActiveModContainer(null);
// Parse arguments // Parse arguments
@ -94,19 +92,21 @@ public class PocketSchematicGenerator {
ModBlocks.FABRIC.getDefaultState().withProperty(BlockFabric.TYPE, BlockFabric.EnumType.ANCIENT), // outer wall ModBlocks.FABRIC.getDefaultState().withProperty(BlockFabric.TYPE, BlockFabric.EnumType.ANCIENT), // outer wall
ModBlocks.FABRIC.getDefaultState().withProperty(BlockFabric.TYPE, BlockFabric.EnumType.REALITY), // inner wall ModBlocks.FABRIC.getDefaultState().withProperty(BlockFabric.TYPE, BlockFabric.EnumType.REALITY), // inner wall
ModBlocks.DIMENSIONAL_DOOR, // door ModBlocks.DIMENSIONAL_DOOR, // door
RiftDestination.PocketExitDestination.builder().build())); // exit rift destination PocketExitDestination.builder().build(),
1)); // exit rift destination
schematics.add(generatePocketSchematic( schematics.add(generatePocketSchematic(
"private_pocket", // base name "private_pocket", // base name
pocketSize, // size pocketSize, // size
ModBlocks.FABRIC.getDefaultState().withProperty(BlockFabric.TYPE, BlockFabric.EnumType.ANCIENT_ALTERED), // outer wall ModBlocks.FABRIC.getDefaultState().withProperty(BlockFabric.TYPE, BlockFabric.EnumType.ANCIENT_ALTERED), // outer wall
ModBlocks.FABRIC.getDefaultState().withProperty(BlockFabric.TYPE, BlockFabric.EnumType.ALTERED), // inner wall ModBlocks.FABRIC.getDefaultState().withProperty(BlockFabric.TYPE, BlockFabric.EnumType.ALTERED), // inner wall
ModBlocks.PERSONAL_DIMENSIONAL_DOOR, // door ModBlocks.PERSONAL_DIMENSIONAL_DOOR, // door
RiftDestination.PrivatePocketExitDestination.builder().build())); // exit rift destination PrivatePocketExitDestination.builder().build(),
0)); // exit rift destination
} }
return schematics; return schematics;
} }
private static Schematic generatePocketSchematic(String baseName, int pocketSize, IBlockState outerWallBlockState, IBlockState innerWallBlockState, Block doorBlock, RiftDestination exitDest) { private static Schematic generatePocketSchematic(String baseName, int pocketSize, IBlockState outerWallBlockState, IBlockState innerWallBlockState, Block doorBlock, RiftDestination exitDest, float chaosWeight) {
int size = (pocketSize + 1) * 16 - 1; // -1 so that the door can be centered int size = (pocketSize + 1) * 16 - 1; // -1 so that the door can be centered
// Set schematic info // Set schematic info
@ -153,9 +153,10 @@ public class PocketSchematicGenerator {
// Generate the rift TileEntities // Generate the rift TileEntities
schematic.tileEntities = new ArrayList<>(); schematic.tileEntities = new ArrayList<>();
TileEntityRift rift = (TileEntityRift) doorBlock.createTileEntity(null, doorBlock.getDefaultState()); TileEntityRift rift = (TileEntityRift) doorBlock.createTileEntity(null, doorBlock.getDefaultState());
rift.setSingleDestination(RiftDestination.PocketEntranceDestination.builder() rift.setSingleDestination(PocketEntranceDestination.builder()
.ifDestinations(Collections.singletonList(new WeightedRiftDestination(exitDest, 1, 0))) .ifDestinations(Collections.singletonList(new WeightedRiftDestination(exitDest, 1, 0)))
.build()); .build());
rift.setChaosWeight(0);
NBTTagCompound tileNBT = rift.serializeNBT(); NBTTagCompound tileNBT = rift.serializeNBT();
tileNBT.setInteger("x", (size - 1) / 2); tileNBT.setInteger("x", (size - 1) / 2);
tileNBT.setInteger("y", 5); tileNBT.setInteger("y", 5);

View file

@ -17,7 +17,7 @@ import java.util.Map;
/** /**
* @author Robijnvogel * @author Robijnvogel
*/ */
public class SchematicConverter { public final class SchematicConverter {
private static final Map<String, IBlockState> stateMap = new HashMap<>(); private static final Map<String, IBlockState> stateMap = new HashMap<>();
static { static {

View file

@ -15,7 +15,7 @@ import lombok.Getter;
import net.minecraft.world.DimensionType; import net.minecraft.world.DimensionType;
import net.minecraftforge.common.DimensionManager; import net.minecraftforge.common.DimensionManager;
public class DimDoorDimensions { public final class DimDoorDimensions {
public static DimensionType limbo = null; public static DimensionType limbo = null;
@Getter private static int minPocketDimID; @Getter private static int minPocketDimID;
@ -59,7 +59,7 @@ public class DimDoorDimensions {
return pocketDimensionTypes.get(pocketType); return pocketDimensionTypes.get(pocketType);
} }
public static boolean isPocketDimension(int id) { // TODO: also add isPocketDimension(World)? public static boolean isPocketDimension(int id) { // TODO: convert some calls to world.provider instanceof (compatibility with other mods that will use PocketLib), and rename to isDimDoorsPoketDimension
return id >= minPocketDimID && id <= maxPocketDimID; return id >= minPocketDimID && id <= maxPocketDimID;
} }

View file

@ -9,7 +9,8 @@ import net.minecraftforge.common.BiomeDictionary;
import net.minecraftforge.event.RegistryEvent; import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
public class ModBiomes { public final class ModBiomes {
public static final BiomeLimbo LIMBO = new BiomeLimbo(); public static final BiomeLimbo LIMBO = new BiomeLimbo();
public static final BiomeBlank WHITE_VOID = new BiomeBlank(true, false); public static final BiomeBlank WHITE_VOID = new BiomeBlank(true, false);
public static final BiomeBlank BLACK_VOID = new BiomeBlank(false, false); public static final BiomeBlank BLACK_VOID = new BiomeBlank(false, false);

View file

@ -5,7 +5,8 @@ import com.google.common.collect.RangeSet;
import com.google.common.collect.TreeRangeSet; import com.google.common.collect.TreeRangeSet;
public class DimensionFilter { public class DimensionFilter {
private RangeSet<Integer> blacklist;
private final RangeSet<Integer> blacklist;
private DimensionFilter(RangeSet<Integer> blacklist) { private DimensionFilter(RangeSet<Integer> blacklist) {
this.blacklist = blacklist; this.blacklist = blacklist;

View file

@ -18,7 +18,7 @@ import java.util.Random;
* Provides methods for applying Limbo decay. Limbo decay refers to the effect that most blocks placed in Limbo * Provides methods for applying Limbo decay. Limbo decay refers to the effect that most blocks placed in Limbo
* naturally change into stone, then cobble, then gravel, and finally Unraveled Fabric as time passes. * naturally change into stone, then cobble, then gravel, and finally Unraveled Fabric as time passes.
*/ */
public class LimboDecay { public final class LimboDecay {
private static final int MAX_DECAY_SPREAD_CHANCE = 100; private static final int MAX_DECAY_SPREAD_CHANCE = 100;
private static final int DECAY_SPREAD_CHANCE = 50; private static final int DECAY_SPREAD_CHANCE = 50;

View file

@ -14,7 +14,7 @@ import java.util.Random;
public class BiomeBlank extends Biome { public class BiomeBlank extends Biome {
private boolean white; private final boolean white;
public BiomeBlank(boolean white, boolean monoliths) { // TODO: split this class public BiomeBlank(boolean white, boolean monoliths) { // TODO: split this class
super(new BiomeProperties((monoliths ? "Dangerous " : "") + (white ? "White" : "Black") + " Void") super(new BiomeProperties((monoliths ? "Dangerous " : "") + (white ? "White" : "Black") + " Void")

View file

@ -13,7 +13,7 @@ import java.util.List;
public class ChunkGeneratorBlank implements IChunkGenerator { public class ChunkGeneratorBlank implements IChunkGenerator {
private World world; private final World world;
public ChunkGeneratorBlank(World world, long seed) { public ChunkGeneratorBlank(World world, long seed) {
this.world = world; this.world = world;

View file

@ -0,0 +1,32 @@
package ddutils;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.IEntityOwnable;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.projectile.*;
public final class EntityUtils {
public static String getEntityOwnerUUID(Entity entity) { // TODO: make this recursive
if (entity instanceof EntityThrowable) entity = ((EntityThrowable) entity).getThrower();
if (entity instanceof EntityArrow) entity = ((EntityArrow) entity).shootingEntity;
if (entity instanceof EntityFireball) entity = ((EntityFireball) entity).shootingEntity;
if (entity instanceof EntityLlamaSpit) entity = ((EntityLlamaSpit) entity).owner; // Llamas are ownable
if (entity.getControllingPassenger() != null && !(entity instanceof EntityPlayer)) entity = entity.getControllingPassenger();
if (entity.getPassengers().size() > 0) entity.getPassengers().get(0);
if (entity instanceof EntityFishHook) entity = ((EntityFishHook) entity).getAngler();
if (entity instanceof EntityLiving && ((EntityLiving) entity).getLeashed()) entity = ((EntityLiving) entity).getLeashHolder();
if (entity instanceof EntityItem) {
String playerName = ((EntityItem) entity).getThrower();
EntityPlayer player = null;
if (playerName != null) player = entity.world.getPlayerEntityByName(((EntityItem) entity).getThrower());
if (player != null) entity = player;
}
if (entity instanceof IEntityOwnable && ((IEntityOwnable) entity).getOwnerId() != null) return ((IEntityOwnable) entity).getOwnerId().toString();
if (entity instanceof EntityPlayer) return entity.getUniqueID().toString(); // ownable players shouldn't be a problem, but just in case we have a slave mod, check their owner's uuid first to send them to their owner's pocket :)
return null;
}
}

View file

@ -6,7 +6,7 @@ import net.minecraftforge.fml.relauncher.SideOnly;
import java.util.List; import java.util.List;
public class I18nUtils { public final class I18nUtils {
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public static void translateAndAdd(String key, List<String> list) { // TODO: move to utils? public static void translateAndAdd(String key, List<String> list) { // TODO: move to utils?
int i = 0; int i = 0;

View file

@ -48,7 +48,7 @@ public class Location implements Serializable {
} }
public IBlockState getBlockState() { public IBlockState getBlockState() {
return getWorld().getBlockState(getPos()); return getWorld().getBlockState(this.pos);
} }
public WorldServer getWorld() { public WorldServer getWorld() {

View file

@ -6,7 +6,7 @@ import java.lang.reflect.Field;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
public class MCPReflection { public final class MCPReflection {
public static Field getMCPField(Class<?> class0, String deobfuscatedName, String obfuscatedName) throws NoSuchFieldException { public static Field getMCPField(Class<?> class0, String deobfuscatedName, String obfuscatedName) throws NoSuchFieldException {
Field field; Field field;
try { try {
@ -20,11 +20,10 @@ public class MCPReflection {
Field modifiers = Field.class.getDeclaredField("modifiers"); Field modifiers = Field.class.getDeclaredField("modifiers");
modifiers.setAccessible(true); modifiers.setAccessible(true);
modifiers.setInt(field, field.getModifiers() & ~Modifier.FINAL); modifiers.setInt(field, field.getModifiers() & ~Modifier.FINAL);
return field;
} catch (IllegalAccessException e) { } catch (IllegalAccessException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
return field;
} }
public static Method getMCPMethod(Class<?> class0, String deobfuscatedName, String obfuscatedName, Class<?> args) throws NoSuchMethodException { public static Method getMCPMethod(Class<?> class0, String deobfuscatedName, String obfuscatedName, Class<?> args) throws NoSuchMethodException {

View file

@ -6,7 +6,7 @@ import java.util.List;
/** /**
* @author Robijnvogel * @author Robijnvogel
*/ */
public class StringUtils { public final class StringUtils {
public static char flipCase(char in) { public static char flipCase(char in) {
if (Character.isUpperCase(in)) { if (Character.isUpperCase(in)) {
@ -19,7 +19,7 @@ public class StringUtils {
public static List<String> getAsStringList(Integer[] integers) { public static List<String> getAsStringList(Integer[] integers) {
List<String> list = new ArrayList<>(); List<String> list = new ArrayList<>();
for (int integer : integers) { for (int integer : integers) {
list.add("" + integer); list.add(String.valueOf(integer));
} }
return list; return list;
} }

View file

@ -17,7 +17,7 @@ import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.EnumSet; import java.util.EnumSet;
public class TeleportUtils { public final class TeleportUtils {
public static Entity teleport(Entity entity, Location location) { public static Entity teleport(Entity entity, Location location) {
return teleport(entity, location, entity.rotationYaw, entity.rotationPitch); return teleport(entity, location, entity.rotationYaw, entity.rotationPitch);
@ -65,7 +65,7 @@ public class TeleportUtils {
} }
entity.setRotationYawHead(yaw); entity.setRotationYawHead(yaw);
return entity; return entity;
} else { // Based on Entity.changeDimension } else { // Based on EntityUtils.changeDimension
MinecraftServer server = entity.getServer(); MinecraftServer server = entity.getServer();
WorldServer oldServer = server.getWorld(oldDimension); WorldServer oldServer = server.getWorld(oldDimension);
WorldServer newServer = server.getWorld(newDimension); WorldServer newServer = server.getWorld(newDimension);

View file

@ -4,7 +4,7 @@ import net.minecraft.world.World;
import net.minecraft.world.WorldServer; import net.minecraft.world.WorldServer;
import net.minecraftforge.common.DimensionManager; import net.minecraftforge.common.DimensionManager;
public class WorldUtils { public final class WorldUtils {
public static WorldServer getWorld(int dim) { public static WorldServer getWorld(int dim) {
return DimensionManager.getWorld(0).getMinecraftServer().getWorld(dim); return DimensionManager.getWorld(0).getMinecraftServer().getWorld(dim);
} }

View file

@ -54,7 +54,7 @@ public abstract class BlockSpecialAir extends Block { // TODO: make water and pi
@Override @Override
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public EnumBlockRenderType getRenderType(IBlockState state) { public EnumBlockRenderType getRenderType(IBlockState state) {
return EnumBlockRenderType.INVISIBLE; // Tile Entity Special Renderer return EnumBlockRenderType.INVISIBLE; // Tile EntityUtils Special Renderer
} }
@Override @Override

View file

@ -2,7 +2,7 @@ package ddutils.math;
import lombok.Value; import lombok.Value;
public class GridUtils { public final class GridUtils {
@Value @Value
public static class GridPos { public static class GridPos {
private int x; private int x;

View file

@ -3,7 +3,7 @@ package ddutils.math;
import java.util.Map; import java.util.Map;
import java.util.Random; import java.util.Random;
public class MathUtils { public final class MathUtils {
public static <T> T weightedRandom(Map<T, Float> weights) { public static <T> T weightedRandom(Map<T, Float> weights) {
if (weights.size() == 0) return null; if (weights.size() == 0) return null;

View file

@ -5,7 +5,7 @@ import java.util.Random;
/** /**
* @author Robijnvogel * @author Robijnvogel
*/ */
public class RandomUtils { // These utils aren't being used by DimDoors! public final class RandomUtils { // These utils aren't being used by DimDoors!
/** /**
* Compares the integers in two arrays and returns true if any integer in * Compares the integers in two arrays and returns true if any integer in

View file

@ -6,7 +6,7 @@ import net.minecraft.util.math.Vec3i;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
public class NBTUtils { public final class NBTUtils {
public static Map<String, Integer> readMapStringInteger(NBTTagCompound nbt) { public static Map<String, Integer> readMapStringInteger(NBTTagCompound nbt) {
HashMap<String, Integer> map = new HashMap<>(); HashMap<String, Integer> map = new HashMap<>();
for (String str : nbt.getKeySet()) { for (String str : nbt.getKeySet()) {

View file

@ -203,7 +203,7 @@ public class Schematic {
private static String getBlockStateStringFromState(IBlockState state) { private static String getBlockStateStringFromState(IBlockState state) {
Block block = state.getBlock(); Block block = state.getBlock();
String blockNameString = "" + Block.REGISTRY.getNameForObject(block); String blockNameString = String.valueOf(Block.REGISTRY.getNameForObject(block));
StringBuilder blockStateString = new StringBuilder(); StringBuilder blockStateString = new StringBuilder();
String totalString; String totalString;
IBlockState defaultState = block.getDefaultState(); IBlockState defaultState = block.getDefaultState();