Split teleportation logic and make it extensible by other mods
This commit is contained in:
parent
c4560a78ba
commit
ffd8c6ed3c
77 changed files with 938 additions and 825 deletions
|
@ -7,7 +7,6 @@ import com.zixiken.dimdoors.shared.DDProxyCommon;
|
|||
import com.zixiken.dimdoors.shared.items.ModItems;
|
||||
import com.zixiken.dimdoors.shared.world.gateways.GatewayGenerator;
|
||||
import lombok.Getter;
|
||||
import net.minecraft.client.resources.I18n;
|
||||
import net.minecraft.creativetab.CreativeTabs;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
@ -20,8 +19,6 @@ import net.minecraftforge.fml.relauncher.Side;
|
|||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mod(modid = DimDoors.MODID, name = "Dimensional Doors",
|
||||
version = DimDoors.VERSION,
|
||||
dependencies = "required-after:forge@[14.23.0.2517,)")
|
||||
|
|
|
@ -16,7 +16,7 @@ import net.minecraftforge.fml.relauncher.SideOnly;
|
|||
import static net.minecraft.item.Item.getItemFromBlock;
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public class ModelManager {
|
||||
public final class ModelManager {
|
||||
|
||||
public static void registerModels() {
|
||||
//ItemBlock registration
|
||||
|
|
|
@ -14,8 +14,7 @@ import net.minecraft.entity.Entity;
|
|||
@SideOnly(Side.CLIENT)
|
||||
public class ModelMonolith extends ModelBase {
|
||||
|
||||
ModelRenderer wholeMonolith;
|
||||
Random rand = new Random();
|
||||
private final ModelRenderer wholeMonolith;
|
||||
|
||||
public ModelMonolith() {
|
||||
textureWidth = 256;
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package com.zixiken.dimdoors.client;
|
||||
|
||||
import com.zixiken.dimdoors.DimDoors;
|
||||
import com.zixiken.dimdoors.client.ModelMonolith;
|
||||
import com.zixiken.dimdoors.shared.entities.EntityMonolith;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.OpenGlHelper;
|
||||
|
|
|
@ -24,11 +24,11 @@ import static org.lwjgl.opengl.GL11.*;
|
|||
@SideOnly(Side.CLIENT)
|
||||
public class TileEntityEntranceRiftRenderer extends TileEntitySpecialRenderer<TileEntityEntranceRift> { // TODO: see TileEntityEndGatewayRenderer
|
||||
|
||||
private FloatBuffer buffer = GLAllocation.createDirectFloatBuffer(16);
|
||||
private ResourceLocation warpPath = new ResourceLocation(DimDoors.MODID + ":textures/other/warp.png");
|
||||
private ResourceLocation keyPath = new ResourceLocation(DimDoors.MODID + ":textures/other/keyhole.png");
|
||||
private ResourceLocation keyholeLight = new ResourceLocation(DimDoors.MODID + ":textures/other/keyhole_light.png");
|
||||
Map<TileEntityEntranceRift, RGBA[]> colorMap = new HashMap<>();
|
||||
private final FloatBuffer buffer = GLAllocation.createDirectFloatBuffer(16);
|
||||
private final ResourceLocation warpPath = new ResourceLocation(DimDoors.MODID + ":textures/other/warp.png");
|
||||
private final ResourceLocation keyPath = new ResourceLocation(DimDoors.MODID + ":textures/other/keyhole.png");
|
||||
private final ResourceLocation keyholeLight = new ResourceLocation(DimDoors.MODID + ":textures/other/keyhole_light.png");
|
||||
private final Map<TileEntityEntranceRift, RGBA[]> colorMap = new HashMap<>();
|
||||
|
||||
// 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) {
|
||||
|
|
|
@ -17,9 +17,9 @@ import org.lwjgl.opengl.GL11;
|
|||
|
||||
@SideOnly(Side.CLIENT)
|
||||
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),
|
||||
|
|
|
@ -14,7 +14,7 @@ import net.minecraftforge.event.RegistryEvent;
|
|||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||
import net.minecraftforge.oredict.ShapedOreRecipe;
|
||||
|
||||
public class CraftingManager {
|
||||
public final class CraftingManager {
|
||||
|
||||
public static ResourceLocation getNameForRecipe(ItemStack output) {
|
||||
ResourceLocation baseLoc = new ResourceLocation(DimDoors.MODID, output.getItem().getRegistryName().getResourcePath());
|
||||
|
|
|
@ -15,7 +15,7 @@ import scala.actors.threadpool.Arrays;
|
|||
*
|
||||
* @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
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import com.zixiken.dimdoors.DimDoors;
|
|||
import com.zixiken.dimdoors.shared.blocks.ModBlocks;
|
||||
import com.zixiken.dimdoors.shared.entities.EntityMonolith;
|
||||
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.tileentities.*;
|
||||
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.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
|
||||
|
|
|
@ -14,7 +14,7 @@ import net.minecraftforge.event.entity.living.LivingHurtEvent;
|
|||
import net.minecraftforge.fml.common.eventhandler.EventPriority;
|
||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||
|
||||
public class EventHandler {
|
||||
public final class EventHandler {
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onPlayerJoinWorld(EntityJoinWorldEvent event) {
|
||||
|
|
|
@ -6,7 +6,7 @@ import net.minecraft.entity.EntityLivingBase;
|
|||
import net.minecraft.util.math.RayTraceResult;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class RayTraceHelper {
|
||||
public final class RayTraceHelper {
|
||||
public static boolean isRift(RayTraceResult hit, World world) {
|
||||
return isNotNull(hit) && hit.typeOfHit == RayTraceResult.Type.BLOCK && world.getTileEntity(hit.getBlockPos()) instanceof TileEntityFloatingRift;
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@ package com.zixiken.dimdoors.shared;
|
|||
import com.zixiken.dimdoors.shared.pockets.Pocket;
|
||||
import com.zixiken.dimdoors.shared.pockets.PocketRegistry;
|
||||
import ddutils.Location;
|
||||
import ddutils.WorldUtils;
|
||||
import com.zixiken.dimdoors.shared.world.DimDoorDimensions;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
|
@ -80,6 +79,6 @@ public class VirtualLocation { // TODO: use BlockPos/Location
|
|||
}
|
||||
|
||||
public Location projectToWorld() {
|
||||
return transformDepth(0).getLocation();
|
||||
return transformDepth(0).location;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -113,7 +113,7 @@ public abstract class BlockDimensionalDoor extends BlockDoor implements IRiftPro
|
|||
if (!hasTileEntity(state)) return;
|
||||
TileEntityEntranceRift rift = getRift(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();
|
||||
newRift.copyFrom(rift);
|
||||
newRift.updateAvailableLinks();
|
||||
|
@ -126,15 +126,11 @@ public abstract class BlockDimensionalDoor extends BlockDoor implements IRiftPro
|
|||
|
||||
@Override
|
||||
public TileEntityEntranceRift getRift(World world, BlockPos pos, IBlockState state) {
|
||||
TileEntity tileEntity;
|
||||
if (state.getValue(BlockDoor.HALF) == EnumDoorHalf.LOWER) {
|
||||
tileEntity = world.getTileEntity(pos);
|
||||
if (!(tileEntity instanceof TileEntityRift)) tileEntity = world.getTileEntity(pos.up());
|
||||
return (TileEntityEntranceRift) world.getTileEntity(pos);
|
||||
} else {
|
||||
tileEntity = world.getTileEntity(pos);
|
||||
if (!(tileEntity instanceof TileEntityRift)) tileEntity = world.getTileEntity(pos.down());
|
||||
return (TileEntityEntranceRift) world.getTileEntity(pos.down());
|
||||
}
|
||||
return (TileEntityEntranceRift) tileEntity;
|
||||
}
|
||||
|
||||
public abstract Item getItem();
|
||||
|
|
|
@ -2,7 +2,7 @@ package com.zixiken.dimdoors.shared.blocks;
|
|||
|
||||
import com.zixiken.dimdoors.DimDoors;
|
||||
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 net.minecraft.block.material.Material;
|
||||
import net.minecraft.item.Item;
|
||||
|
@ -27,7 +27,7 @@ public class BlockDimensionalDoorIron extends BlockDimensionalDoor {
|
|||
|
||||
@Override
|
||||
public void setupRift(TileEntityEntranceRift rift) {
|
||||
RiftDestination.NewPublicDestination destination = RiftDestination.NewPublicDestination.builder().build();
|
||||
NewPublicDestination destination = NewPublicDestination.builder().build();
|
||||
rift.setSingleDestination(destination);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,8 +2,11 @@ package com.zixiken.dimdoors.shared.blocks;
|
|||
|
||||
import com.zixiken.dimdoors.DimDoors;
|
||||
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.tileentities.TileEntityEntranceRift;
|
||||
import com.zixiken.dimdoors.shared.world.pocketdimension.WorldProviderPersonalPocket;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
@ -26,9 +29,13 @@ public class BlockDimensionalDoorPersonal extends BlockDimensionalDoor {
|
|||
|
||||
@Override
|
||||
public void setupRift(TileEntityEntranceRift rift) {
|
||||
DimDoors.log.info("Setting up the rift!");
|
||||
RiftDestination.PrivateDestination destination = RiftDestination.PrivateDestination.builder().build();
|
||||
RiftDestination destination;
|
||||
if (rift.getWorld().provider instanceof WorldProviderPersonalPocket) {
|
||||
destination = PrivatePocketExitDestination.builder().build(); // exit
|
||||
} else {
|
||||
destination = PrivateDestination.builder().build(); // entrance
|
||||
}
|
||||
rift.setSingleDestination(destination);
|
||||
rift.setChaosWeight(0);
|
||||
rift.setChaosWeight(0); // TODO: generated schematic exits too
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ public interface IRiftProvider<T extends TileEntityRift> extends ITileEntityProv
|
|||
|
||||
// Call only once per structure (on item place)!
|
||||
public default void handleRiftSetup(World world, BlockPos pos, IBlockState state) {
|
||||
if (world.isRemote) return;
|
||||
T rift = getRift(world, pos, state);
|
||||
|
||||
// Set the rift's virtual position
|
||||
|
@ -31,8 +32,9 @@ public interface IRiftProvider<T extends TileEntityRift> extends ITileEntityProv
|
|||
setupRift(rift);
|
||||
|
||||
// Set the tile entity and register it
|
||||
world.setTileEntity(pos, rift);
|
||||
//world.setTileEntity(pos, rift);
|
||||
rift.markDirty();
|
||||
rift.register();
|
||||
T rift2 = getRift(world, pos, state);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ import net.minecraft.block.Block;
|
|||
import net.minecraftforge.event.RegistryEvent;
|
||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||
|
||||
public class ModBlocks {
|
||||
public final class ModBlocks {
|
||||
|
||||
// Regular doors
|
||||
public static final BlockDoorGold GOLD_DOOR = new BlockDoorGold();
|
||||
|
|
|
@ -77,11 +77,10 @@ public class CommandDimTeleport extends CommandBase { // TODO: localization
|
|||
|
||||
@Override
|
||||
public List<String> getTabCompletions(MinecraftServer server, ICommandSender sender, String[] args, @Nullable BlockPos targetPos) {
|
||||
List<String> list = new ArrayList<>();
|
||||
if (args.length == 1) {
|
||||
list = StringUtils.getAsStringList(DimensionManager.getIDs());
|
||||
list = StringUtils.getMatchingStrings(args[0], list, false);
|
||||
List<String> list = StringUtils.getAsStringList(DimensionManager.getIDs());
|
||||
return StringUtils.getMatchingStrings(args[0], list, false);
|
||||
}
|
||||
return list;
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -244,7 +244,7 @@ public class EntityMonolith extends EntityFlying implements IMob {
|
|||
private void facePlayer(EntityPlayer player) {
|
||||
double d0 = player.posX - posX;
|
||||
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);
|
||||
float f2 = (float) (Math.atan2(d1, d0) * 180.0D / Math.PI) - 90.0F;
|
||||
pitchLevel = (float) -(Math.atan(d2 / d3) * 180.0D / Math.PI);
|
||||
|
|
|
@ -7,7 +7,6 @@ import com.zixiken.dimdoors.shared.blocks.BlockDimensionalDoorWarp;
|
|||
import com.zixiken.dimdoors.shared.blocks.ModBlocks;
|
||||
import ddutils.I18nUtils;
|
||||
import net.minecraft.client.util.ITooltipFlag;
|
||||
import net.minecraft.item.ItemDoor;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.world.World;
|
||||
|
|
|
@ -6,7 +6,7 @@ import net.minecraftforge.event.RegistryEvent;
|
|||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||
import com.zixiken.dimdoors.shared.blocks.ModBlocks;
|
||||
|
||||
public class ModItems {
|
||||
public final class ModItems {
|
||||
|
||||
// Regular doors
|
||||
public static final ItemDoorGold GOLD_DOOR = new ItemDoorGold();
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
package com.zixiken.dimdoors.shared.pockets;
|
||||
|
||||
import com.zixiken.dimdoors.shared.VirtualLocation;
|
||||
import com.zixiken.dimdoors.shared.rifts.RiftDestination;
|
||||
import com.zixiken.dimdoors.shared.rifts.TileEntityRift;
|
||||
import com.zixiken.dimdoors.shared.rifts.WeightedRiftDestination;
|
||||
import com.zixiken.dimdoors.shared.rifts.*;
|
||||
import com.zixiken.dimdoors.shared.tileentities.TileEntityEntranceRift;
|
||||
import ddutils.Location;
|
||||
|
||||
import java.util.*;
|
||||
|
@ -22,7 +21,7 @@ public class Pocket { // TODO: better visibilities
|
|||
@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 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 int dimID; // Not saved
|
||||
|
@ -104,7 +103,7 @@ public class Pocket { // TODO: better visibilities
|
|||
int index = 0;
|
||||
for (TileEntityRift rift : rifts) { // Find an entrance
|
||||
for (WeightedRiftDestination weightedPocketEntranceDest : rift.getDestinations()) {
|
||||
if (weightedPocketEntranceDest.getDestination().getType() == RiftDestination.EnumType.POCKET_ENTRANCE) {
|
||||
if (weightedPocketEntranceDest.getDestination() instanceof PocketEntranceDestination) {
|
||||
entranceIndexWeights.put(index, weightedPocketEntranceDest.getWeight());
|
||||
rift.markDirty();
|
||||
index++;
|
||||
|
@ -121,18 +120,18 @@ public class Pocket { // TODO: better visibilities
|
|||
while (destIterator.hasNext()) {
|
||||
WeightedRiftDestination wdest = destIterator.next();
|
||||
RiftDestination dest = wdest.getDestination();
|
||||
if (dest.getType() == RiftDestination.EnumType.POCKET_ENTRANCE) {
|
||||
if (dest instanceof PocketEntranceDestination) {
|
||||
destIterator.remove();
|
||||
if (index == selectedEntranceIndex) {
|
||||
entrance = new Location(rift.getWorld(), rift.getPos());
|
||||
PocketRegistry.getForDim(dimID).markDirty();
|
||||
List<WeightedRiftDestination> ifDestinations = ((RiftDestination.PocketEntranceDestination) dest).getIfDestinations();
|
||||
List<WeightedRiftDestination> ifDestinations = ((PocketEntranceDestination) dest).getIfDestinations();
|
||||
for (WeightedRiftDestination ifDestination : ifDestinations) {
|
||||
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
|
||||
}
|
||||
} else {
|
||||
List<WeightedRiftDestination> otherwiseDestinations = ((RiftDestination.PocketEntranceDestination) dest).getOtherwiseDestinations();
|
||||
List<WeightedRiftDestination> otherwiseDestinations = ((PocketEntranceDestination) dest).getOtherwiseDestinations();
|
||||
for (WeightedRiftDestination otherwiseDestination : otherwiseDestinations) {
|
||||
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
|
||||
|
@ -146,7 +145,6 @@ public class Pocket { // TODO: better visibilities
|
|||
// set virtual locations and register rifts
|
||||
for (TileEntityRift rift : rifts) {
|
||||
rift.setVirtualLocation(virtualLocation);
|
||||
rift.markStateChanged();
|
||||
rift.register();
|
||||
}
|
||||
}
|
||||
|
@ -160,10 +158,10 @@ public class Pocket { // TODO: better visibilities
|
|||
while (destIterator.hasNext()) {
|
||||
WeightedRiftDestination wdest = destIterator.next();
|
||||
RiftDestination dest = wdest.getDestination();
|
||||
if (dest.getType() == RiftDestination.EnumType.POCKET_EXIT) {
|
||||
if (dest instanceof PocketExitDestination) {
|
||||
destIterator.remove();
|
||||
destIterator.add(new WeightedRiftDestination(linkTo.withOldDestination(dest), wdest.getWeight(), wdest.getGroup()));
|
||||
rift.markStateChanged();
|
||||
destIterator.add(new WeightedRiftDestination(linkTo, wdest.getWeight(), wdest.getGroup(), dest));
|
||||
if (rift instanceof TileEntityEntranceRift) ((TileEntityEntranceRift) rift).setPlaceRiftOnBreak(true);
|
||||
rift.markDirty();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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!");
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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.
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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));
|
||||
}
|
||||
}
|
|
@ -1,410 +1,66 @@
|
|||
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.nbt.NBTUtils;
|
||||
import net.minecraft.nbt.NBTBase;
|
||||
import ddutils.nbt.INBTStorable;
|
||||
import net.minecraft.entity.Entity;
|
||||
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 java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
@SuppressWarnings("EmptyMethod")
|
||||
@Getter @ToString @EqualsAndHashCode @AllArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public /*abstract*/ class RiftDestination implements INBTStorable { // TODO: fix lombok and make this abstract
|
||||
@Getter private EnumType type;
|
||||
@Getter protected RiftDestination oldDestination;
|
||||
@Getter @ToString @EqualsAndHashCode
|
||||
public abstract class RiftDestination implements INBTStorable {
|
||||
|
||||
public enum EnumType {
|
||||
RELATIVE, LOCAL, GLOBAL, NEW_PUBLIC, PRIVATE, LIMBO, AVAILABLE_LINK, POCKET_ENTRANCE, POCKET_EXIT, PRIVATE_POCKET_EXIT, ESCAPE
|
||||
/*private*/ public static final BiMap<String, Class<? extends RiftDestination>> destinationRegistry = HashBiMap.create(); // TODO: move to RiftDestinationRegistry
|
||||
//private String type;
|
||||
/*package-private*/ WeightedRiftDestination weightedDestination;
|
||||
|
||||
public RiftDestination() {
|
||||
//type = destinationRegistry.inverse().get(getClass());
|
||||
}
|
||||
|
||||
private RiftDestination() {
|
||||
if (this instanceof RelativeDestination) {
|
||||
type = EnumType.RELATIVE;
|
||||
} else if (this instanceof LocalDestination) {
|
||||
type = EnumType.LOCAL;
|
||||
} else if (this instanceof GlobalDestination) {
|
||||
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) {
|
||||
String type = nbt.getString("type");
|
||||
Class<? extends RiftDestination> destinationClass = destinationRegistry.get(type);
|
||||
if (destinationClass == null) throw new RuntimeException("Unknown type '" + type + "'.");
|
||||
try {
|
||||
RiftDestination destination = destinationClass.getConstructor().newInstance();
|
||||
destination.readFromNBT(nbt);
|
||||
//destination.type = type;
|
||||
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 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);
|
||||
return destination;
|
||||
}
|
||||
|
||||
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
|
||||
public void readFromNBT(NBTTagCompound nbt) {
|
||||
if (nbt.hasKey("oldDestination")) oldDestination = readDestinationNBT(nbt.getCompoundTag("oldDestination"));
|
||||
}
|
||||
public void readFromNBT(NBTTagCompound nbt) { }
|
||||
|
||||
@Override
|
||||
public NBTTagCompound writeToNBT(NBTTagCompound nbt) {
|
||||
if (oldDestination != null) nbt.setTag("oldDestination", oldDestination.writeToNBT(new NBTTagCompound()));
|
||||
nbt.setString("type", type.name());
|
||||
String type = destinationRegistry.inverse().get(getClass());
|
||||
if (type == null) throw new RuntimeException("No type has been registered for class" + getClass().getName() + " yet!");
|
||||
nbt.setString("type", type);
|
||||
return nbt;
|
||||
}
|
||||
|
||||
|
||||
@Getter @AllArgsConstructor @Builder(toBuilder = true)
|
||||
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 NBTTagCompound writeToNBT(NBTTagCompound nbt) {
|
||||
nbt = super.writeToNBT(nbt);
|
||||
nbt.setTag("offset", NBTUtils.writeVec3i(offset));
|
||||
return nbt;
|
||||
}
|
||||
public Location getReferencedRift(Location rift) { // TODO: change to getReferencedRifts
|
||||
return null;
|
||||
}
|
||||
|
||||
@Getter @AllArgsConstructor @Builder(toBuilder = true)
|
||||
public static class LocalDestination extends RiftDestination { // TODO: use BlockPos
|
||||
private BlockPos pos;
|
||||
|
||||
private 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;
|
||||
}
|
||||
public void register(TileEntityRift rift) {
|
||||
Location loc = getReferencedRift(rift.getLocation());
|
||||
if (loc != null) RiftRegistry.addLink(rift.getLocation(), loc);
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
public void unregister(TileEntityRift rift) {
|
||||
Location loc = getReferencedRift(rift.getLocation());
|
||||
if (loc != null) RiftRegistry.removeLink(rift.getLocation(), loc);
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
}
|
||||
public abstract boolean teleport(TileEntityRift rift, Entity entity);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
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.Location;
|
||||
import ddutils.WorldUtils;
|
||||
|
@ -23,9 +26,9 @@ public class RiftRegistry extends WorldSavedData {
|
|||
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 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 Map<String, Location> escapeRifts = new HashMap<>();
|
||||
@Getter private final Map<Location, RiftInfo> rifts = new HashMap<>(); // TODO: store relative locations too (better location class supporting relative, etc)
|
||||
@Getter private final Map<String, Location> privatePocketEntrances = new HashMap<>(); // TODO: more general group-group linking
|
||||
@Getter private final Map<String, Location> overworldRifts = new HashMap<>();
|
||||
|
||||
@Getter private int dim;
|
||||
private World world;
|
||||
|
@ -33,9 +36,9 @@ public class RiftRegistry extends WorldSavedData {
|
|||
@AllArgsConstructor @EqualsAndHashCode @Builder(toBuilder = true)
|
||||
public static class RiftInfo implements INBTStorable {
|
||||
// IntelliJ warnings are wrong, Builder needs these initializers!
|
||||
@SuppressWarnings("UnusedAssignment") @Builder.Default @Getter private Set<AvailableLinkInfo> availableLinks = new HashSet<>();
|
||||
@SuppressWarnings("UnusedAssignment") @Builder.Default @Getter private Set<Location> sources = new HashSet<>();
|
||||
@SuppressWarnings("UnusedAssignment") @Builder.Default @Getter private Set<Location> destinations = new HashSet<>();
|
||||
@SuppressWarnings({"UnusedAssignment", "RedundantSuppression"}) @Builder.Default @Getter private Set<AvailableLinkInfo> availableLinks = new HashSet<>(); // TODO: multiset?
|
||||
@SuppressWarnings({"UnusedAssignment", "RedundantSuppression"}) @Builder.Default @Getter private Multiset<Location> sources = ConcurrentHashMultiset.create();
|
||||
@SuppressWarnings({"UnusedAssignment", "RedundantSuppression"}) @Builder.Default @Getter private Multiset<Location> destinations = ConcurrentHashMultiset.create();
|
||||
|
||||
@AllArgsConstructor @NoArgsConstructor @EqualsAndHashCode @Builder(toBuilder = true)
|
||||
public static class AvailableLinkInfo implements INBTStorable {
|
||||
|
@ -62,8 +65,8 @@ public class RiftRegistry extends WorldSavedData {
|
|||
|
||||
public RiftInfo() {
|
||||
availableLinks = new HashSet<>();
|
||||
sources = new HashSet<>();
|
||||
destinations = new HashSet<>();
|
||||
sources = ConcurrentHashMultiset.create();
|
||||
destinations = ConcurrentHashMultiset.create();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -166,12 +169,12 @@ public class RiftRegistry extends WorldSavedData {
|
|||
privatePocketEntrances.put(uuid, rift);
|
||||
}
|
||||
|
||||
NBTTagList escapeRiftsNBT = (NBTTagList) nbt.getTag("escapeRifts");
|
||||
for (NBTBase escapeRiftNBT : escapeRiftsNBT) { // TODO: move to NBTUtils
|
||||
NBTTagCompound escapeRiftNBTC = (NBTTagCompound) escapeRiftNBT;
|
||||
String uuid = escapeRiftNBTC.getString("uuid");
|
||||
Location rift = Location.readFromNBT(escapeRiftNBTC.getCompoundTag("location"));
|
||||
escapeRifts.put(uuid, rift);
|
||||
NBTTagList overworldRiftsNBT = (NBTTagList) nbt.getTag("overworldRifts");
|
||||
for (NBTBase overworldRiftNBT : overworldRiftsNBT) { // TODO: move to NBTUtils
|
||||
NBTTagCompound overworldRiftNBTC = (NBTTagCompound) overworldRiftNBT;
|
||||
String uuid = overworldRiftNBTC.getString("uuid");
|
||||
Location rift = Location.readFromNBT(overworldRiftNBTC.getCompoundTag("location"));
|
||||
overworldRifts.put(uuid, rift);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -215,15 +218,15 @@ public class RiftRegistry extends WorldSavedData {
|
|||
}
|
||||
nbt.setTag("privatePocketEntrances", privatePocketEntrancesNBT);
|
||||
|
||||
NBTTagList escapeRiftsNBT = new NBTTagList();
|
||||
for (HashMap.Entry<String, Location> escapeRift : escapeRifts.entrySet()) {
|
||||
if (escapeRift.getValue() == null) continue;
|
||||
NBTTagCompound escapeRiftNBT = new NBTTagCompound();
|
||||
escapeRiftNBT.setString("uuid", escapeRift.getKey());
|
||||
escapeRiftNBT.setTag("location", Location.writeToNBT(escapeRift.getValue()));
|
||||
escapeRiftsNBT.appendTag(escapeRiftNBT);
|
||||
NBTTagList overworldRiftsNBT = new NBTTagList();
|
||||
for (HashMap.Entry<String, Location> overworldRift : overworldRifts.entrySet()) {
|
||||
if (overworldRift.getValue() == null) continue;
|
||||
NBTTagCompound overworldRiftNBT = new NBTTagCompound();
|
||||
overworldRiftNBT.setString("uuid", overworldRift.getKey());
|
||||
overworldRiftNBT.setTag("location", Location.writeToNBT(overworldRift.getValue()));
|
||||
overworldRiftsNBT.appendTag(overworldRiftNBT);
|
||||
}
|
||||
nbt.setTag("escapeRifts", escapeRiftsNBT);
|
||||
nbt.setTag("overworldRifts", overworldRiftsNBT);
|
||||
|
||||
return nbt;
|
||||
}
|
||||
|
@ -253,9 +256,11 @@ public class RiftRegistry extends WorldSavedData {
|
|||
RiftRegistry destinationRegistry = getRegistry(destination);
|
||||
destinationRegistry.rifts.get(destination).sources.remove(rift);
|
||||
destinationRegistry.markDirty();
|
||||
TileEntityRift riftEntity = (TileEntityRift) destinationRegistry.world.getTileEntity(destination.getPos());
|
||||
riftEntity.allSourcesGone();
|
||||
//TileEntityRift riftEntity = (TileEntityRift) destinationRegistry.world.getTileEntity(destination.getPos());
|
||||
//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();
|
||||
}
|
||||
|
||||
|
@ -318,12 +323,12 @@ public class RiftRegistry extends WorldSavedData {
|
|||
markDirty();
|
||||
}
|
||||
|
||||
public static Location getEscapeRift(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
|
||||
public static Location getOverworldRift(String playerUUID) { // TODO: since this is per-world, move to different registry?
|
||||
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) {
|
||||
getForDim(0).escapeRifts.put(playerUUID, rift);
|
||||
public static void setOverworldRift(String playerUUID, Location rift) {
|
||||
getForDim(0).overworldRifts.put(playerUUID, rift);
|
||||
getForDim(0).markDirty();
|
||||
}
|
||||
|
||||
|
|
|
@ -3,10 +3,8 @@ package com.zixiken.dimdoors.shared.rifts;
|
|||
import com.zixiken.dimdoors.DimDoors;
|
||||
import com.zixiken.dimdoors.shared.VirtualLocation;
|
||||
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.rifts.RiftDestination.*;
|
||||
import com.zixiken.dimdoors.shared.rifts.RiftRegistry.RiftInfo.AvailableLinkInfo;
|
||||
import ddutils.EntityUtils;
|
||||
import ddutils.Location;
|
||||
import ddutils.math.MathUtils;
|
||||
import ddutils.TeleportUtils;
|
||||
|
@ -15,11 +13,7 @@ import com.zixiken.dimdoors.shared.world.DimDoorDimensions;
|
|||
import lombok.Getter;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
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.*;
|
||||
import net.minecraft.nbt.NBTBase;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.nbt.NBTTagList;
|
||||
|
@ -65,10 +59,12 @@ public abstract class TileEntityRift extends TileEntity implements ITickable { /
|
|||
preserveRotation = oldRift.preserveRotation;
|
||||
yaw = oldRift.yaw;
|
||||
pitch = oldRift.pitch;
|
||||
if (oldRift.isFloating() != isFloating()) updateAvailableLinks();
|
||||
|
||||
markDirty();
|
||||
}
|
||||
|
||||
// Reading/writing to NBT
|
||||
@Override
|
||||
public void readFromNBT(NBTTagCompound nbt) {
|
||||
super.readFromNBT(nbt);
|
||||
|
@ -113,6 +109,35 @@ public abstract class TileEntityRift extends TileEntity implements ITickable { /
|
|||
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) {
|
||||
this.virtualLocation = virtualLocation;
|
||||
updateAvailableLinks();
|
||||
|
@ -129,31 +154,20 @@ public abstract class TileEntityRift extends TileEntity implements ITickable { /
|
|||
public void addDestination(RiftDestination destination, float weight, int group) {
|
||||
riftStateChanged = true;
|
||||
destinations.add(new WeightedRiftDestination(destination, weight, group));
|
||||
registerDest(destination);
|
||||
if (isRegistered()) destination.register(this);
|
||||
markDirty();
|
||||
}
|
||||
|
||||
public void removeDestination(int index) {
|
||||
riftStateChanged = true;
|
||||
unregisterDest(destinations.remove(index).getDestination());
|
||||
markDirty();
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
RiftDestination dest = destinations.remove(index).getDestination();
|
||||
if (isRegistered()) dest.unregister(this);
|
||||
markDirty();
|
||||
}
|
||||
|
||||
public void clearDestinations() {
|
||||
for (WeightedRiftDestination wdest : destinations) {
|
||||
unregisterDest(wdest.getDestination());
|
||||
if (isRegistered()) for (WeightedRiftDestination wdest : destinations) {
|
||||
wdest.getDestination().unregister(this);
|
||||
}
|
||||
destinations.clear();
|
||||
markDirty();
|
||||
|
@ -164,78 +178,124 @@ public abstract class TileEntityRift extends TileEntity implements ITickable { /
|
|||
addDestination(destination, 1, 0);
|
||||
}
|
||||
|
||||
public Location destinationToLocation(RiftDestination dest) {
|
||||
switch (dest.getType()) { // TODO: these need a superclass and a single translation method
|
||||
case RELATIVE:
|
||||
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();
|
||||
public void setChaosWeight(int chaosWeight) {
|
||||
this.chaosWeight = chaosWeight;
|
||||
markDirty();
|
||||
}
|
||||
|
||||
public void markStateChanged() {
|
||||
riftStateChanged = true;
|
||||
markDirty();
|
||||
}
|
||||
|
||||
public 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);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void registerDest(RiftDestination dest) {
|
||||
if (!isRegistered()) return;
|
||||
Location destLoc = destinationToLocation(dest);
|
||||
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() {
|
||||
if (!isRegistered()) return;
|
||||
RiftRegistry.clearAvailableLinks(new Location(world, pos));
|
||||
for (WeightedRiftDestination wdest : destinations) {
|
||||
RiftDestination dest = wdest.getDestination();
|
||||
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 unregisterDest(RiftDestination dest) {
|
||||
if (!isRegistered()) return;
|
||||
Location destLoc = destinationToLocation(dest);
|
||||
if (destLoc != null) RiftRegistry.removeLink(new Location(world, pos), destLoc);
|
||||
destinations.remove(weightedDestination);
|
||||
destinations.add(new WeightedRiftDestination(newDest, weightedDestination.getWeight(), weightedDestination.getGroup(), weightedDestination.getDestination()));
|
||||
markDirty();
|
||||
}
|
||||
|
||||
// Registry
|
||||
public boolean isRegistered() {
|
||||
return world != null && RiftRegistry.getRiftInfo(new Location(world, pos)) != null;
|
||||
}
|
||||
|
||||
// Make sure virtualLocation != null before calling!
|
||||
public void register() { // registers or reregisters the rift TODO: what if it's already registered?
|
||||
public void register() {
|
||||
if (isRegistered()) return;
|
||||
Location loc = new Location(world, pos);
|
||||
RiftRegistry.addRift(loc);
|
||||
for (WeightedRiftDestination weightedDest : destinations) {
|
||||
registerDest(weightedDest.getDestination());
|
||||
weightedDest.getDestination().register(this);
|
||||
}
|
||||
}
|
||||
|
||||
public void unregister() {
|
||||
if (!isRegistered()) return;
|
||||
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)
|
||||
}
|
||||
|
||||
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?
|
||||
float newYaw = 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);
|
||||
}
|
||||
|
||||
public boolean teleport(Entity entity) { try { // TODO: return failiure message string rather than boolean
|
||||
riftStateChanged = false;
|
||||
if (destinations.size() == 0) {
|
||||
if (entity instanceof EntityPlayer) DimDoors.chat((EntityPlayer) entity, "This rift has no destinations!");
|
||||
return false;
|
||||
}
|
||||
// Info
|
||||
protected abstract boolean isFloating(); // TODO: make non-abstract?
|
||||
|
||||
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);
|
||||
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 Location getLocation() {
|
||||
return new Location(world, pos);
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
|
|
@ -1,23 +1,39 @@
|
|||
package com.zixiken.dimdoors.shared.rifts;
|
||||
|
||||
import ddutils.nbt.INBTStorable;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
|
||||
@NoArgsConstructor @AllArgsConstructor
|
||||
public class
|
||||
WeightedRiftDestination implements INBTStorable { // TODO: generics
|
||||
@NoArgsConstructor
|
||||
public class WeightedRiftDestination implements INBTStorable { // TODO: generics
|
||||
@Getter private RiftDestination destination;
|
||||
@Getter private float weight;
|
||||
@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
|
||||
public void readFromNBT(NBTTagCompound nbt) {
|
||||
destination = RiftDestination.readDestinationNBT(nbt); // TODO: subtag?
|
||||
weight = nbt.getFloat("weight");
|
||||
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
|
||||
|
@ -25,6 +41,7 @@ WeightedRiftDestination implements INBTStorable { // TODO: generics
|
|||
nbt = destination.writeToNBT(nbt);
|
||||
nbt.setFloat("weight", weight);
|
||||
nbt.setInteger("group", group);
|
||||
if (oldDestination != null) nbt.setTag("oldDestination", oldDestination.writeToNBT(new NBTTagCompound()));
|
||||
return nbt;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ import net.minecraft.util.SoundEvent;
|
|||
import net.minecraftforge.event.RegistryEvent;
|
||||
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!
|
||||
public static final SoundEvent CRACK = create("crack");
|
||||
|
|
|
@ -1,15 +1,11 @@
|
|||
package com.zixiken.dimdoors.shared.tileentities;
|
||||
|
||||
import com.zixiken.dimdoors.shared.pockets.PocketRegistry;
|
||||
import com.zixiken.dimdoors.shared.rifts.TileEntityRift;
|
||||
import ddutils.Location;
|
||||
import ddutils.render.RGBA;
|
||||
import ddutils.TeleportUtils;
|
||||
import ddutils.WorldUtils;
|
||||
import com.zixiken.dimdoors.shared.world.DimDoorDimensions;
|
||||
import lombok.Getter;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
|
||||
|
@ -117,7 +113,7 @@ public class TileEntityEntranceRift extends TileEntityRift {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean isEntrance() {
|
||||
return true;
|
||||
public boolean isFloating() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -126,7 +126,7 @@ public class TileEntityFloatingRift extends TileEntityRift implements ITickable
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean isEntrance() {
|
||||
return false;
|
||||
public boolean isFloating() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,9 +4,7 @@ import com.zixiken.dimdoors.DimDoors;
|
|||
import com.zixiken.dimdoors.server.DDProxyServer;
|
||||
import com.zixiken.dimdoors.shared.blocks.BlockFabric;
|
||||
import com.zixiken.dimdoors.shared.blocks.ModBlocks;
|
||||
import com.zixiken.dimdoors.shared.rifts.RiftDestination;
|
||||
import com.zixiken.dimdoors.shared.rifts.TileEntityRift;
|
||||
import com.zixiken.dimdoors.shared.rifts.WeightedRiftDestination;
|
||||
import com.zixiken.dimdoors.shared.rifts.*;
|
||||
import ddutils.schem.Schematic;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockDoor;
|
||||
|
@ -22,7 +20,6 @@ import net.minecraftforge.fml.common.ModContainer;
|
|||
import net.minecraftforge.fml.common.ModMetadata;
|
||||
import net.minecraftforge.registries.GameData;
|
||||
import net.minecraftforge.registries.RegistryManager;
|
||||
import ddutils.math.MathUtils;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
|
@ -36,7 +33,7 @@ import java.util.List;
|
|||
/**
|
||||
* @author Robijnvogel
|
||||
*/
|
||||
public class PocketSchematicGenerator {
|
||||
public final class PocketSchematicGenerator {
|
||||
|
||||
// Run "gradlew generatePocketSchematics" to generate the pocket schematics
|
||||
@SuppressWarnings("UseOfSystemOutOrSystemErr")
|
||||
|
@ -50,6 +47,7 @@ public class PocketSchematicGenerator {
|
|||
Loader.instance().setActiveModContainer(mc);
|
||||
ModBlocks.registerBlocks(new RegistryEvent.Register(GameData.BLOCKS, RegistryManager.ACTIVE.getRegistry(GameData.BLOCKS)));
|
||||
new DDProxyServer().registerTileEntities();
|
||||
new DDProxyServer().registerRiftDestinations();
|
||||
Loader.instance().setActiveModContainer(null);
|
||||
|
||||
// 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.REALITY), // inner wall
|
||||
ModBlocks.DIMENSIONAL_DOOR, // door
|
||||
RiftDestination.PocketExitDestination.builder().build())); // exit rift destination
|
||||
PocketExitDestination.builder().build(),
|
||||
1)); // exit rift destination
|
||||
schematics.add(generatePocketSchematic(
|
||||
"private_pocket", // base name
|
||||
pocketSize, // size
|
||||
ModBlocks.FABRIC.getDefaultState().withProperty(BlockFabric.TYPE, BlockFabric.EnumType.ANCIENT_ALTERED), // outer wall
|
||||
ModBlocks.FABRIC.getDefaultState().withProperty(BlockFabric.TYPE, BlockFabric.EnumType.ALTERED), // inner wall
|
||||
ModBlocks.PERSONAL_DIMENSIONAL_DOOR, // door
|
||||
RiftDestination.PrivatePocketExitDestination.builder().build())); // exit rift destination
|
||||
PrivatePocketExitDestination.builder().build(),
|
||||
0)); // exit rift destination
|
||||
}
|
||||
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
|
||||
|
||||
// Set schematic info
|
||||
|
@ -153,9 +153,10 @@ public class PocketSchematicGenerator {
|
|||
// Generate the rift TileEntities
|
||||
schematic.tileEntities = new ArrayList<>();
|
||||
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)))
|
||||
.build());
|
||||
rift.setChaosWeight(0);
|
||||
NBTTagCompound tileNBT = rift.serializeNBT();
|
||||
tileNBT.setInteger("x", (size - 1) / 2);
|
||||
tileNBT.setInteger("y", 5);
|
||||
|
|
|
@ -17,7 +17,7 @@ import java.util.Map;
|
|||
/**
|
||||
* @author Robijnvogel
|
||||
*/
|
||||
public class SchematicConverter {
|
||||
public final class SchematicConverter {
|
||||
|
||||
private static final Map<String, IBlockState> stateMap = new HashMap<>();
|
||||
static {
|
||||
|
|
|
@ -15,7 +15,7 @@ import lombok.Getter;
|
|||
import net.minecraft.world.DimensionType;
|
||||
import net.minecraftforge.common.DimensionManager;
|
||||
|
||||
public class DimDoorDimensions {
|
||||
public final class DimDoorDimensions {
|
||||
|
||||
public static DimensionType limbo = null;
|
||||
@Getter private static int minPocketDimID;
|
||||
|
@ -59,7 +59,7 @@ public class DimDoorDimensions {
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,8 @@ import net.minecraftforge.common.BiomeDictionary;
|
|||
import net.minecraftforge.event.RegistryEvent;
|
||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||
|
||||
public class ModBiomes {
|
||||
public final class ModBiomes {
|
||||
|
||||
public static final BiomeLimbo LIMBO = new BiomeLimbo();
|
||||
public static final BiomeBlank WHITE_VOID = new BiomeBlank(true, false);
|
||||
public static final BiomeBlank BLACK_VOID = new BiomeBlank(false, false);
|
||||
|
|
|
@ -5,7 +5,8 @@ import com.google.common.collect.RangeSet;
|
|||
import com.google.common.collect.TreeRangeSet;
|
||||
|
||||
public class DimensionFilter {
|
||||
private RangeSet<Integer> blacklist;
|
||||
|
||||
private final RangeSet<Integer> blacklist;
|
||||
|
||||
private DimensionFilter(RangeSet<Integer> blacklist) {
|
||||
this.blacklist = blacklist;
|
||||
|
|
|
@ -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
|
||||
* 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 DECAY_SPREAD_CHANCE = 50;
|
||||
|
|
|
@ -14,7 +14,7 @@ import java.util.Random;
|
|||
|
||||
public class BiomeBlank extends Biome {
|
||||
|
||||
private boolean white;
|
||||
private final boolean white;
|
||||
|
||||
public BiomeBlank(boolean white, boolean monoliths) { // TODO: split this class
|
||||
super(new BiomeProperties((monoliths ? "Dangerous " : "") + (white ? "White" : "Black") + " Void")
|
||||
|
|
|
@ -13,7 +13,7 @@ import java.util.List;
|
|||
|
||||
public class ChunkGeneratorBlank implements IChunkGenerator {
|
||||
|
||||
private World world;
|
||||
private final World world;
|
||||
|
||||
public ChunkGeneratorBlank(World world, long seed) {
|
||||
this.world = world;
|
||||
|
|
32
src/main/java/ddutils/EntityUtils.java
Normal file
32
src/main/java/ddutils/EntityUtils.java
Normal 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;
|
||||
}
|
||||
}
|
|
@ -6,7 +6,7 @@ import net.minecraftforge.fml.relauncher.SideOnly;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
public class I18nUtils {
|
||||
public final class I18nUtils {
|
||||
@SideOnly(Side.CLIENT)
|
||||
public static void translateAndAdd(String key, List<String> list) { // TODO: move to utils?
|
||||
int i = 0;
|
||||
|
|
|
@ -48,7 +48,7 @@ public class Location implements Serializable {
|
|||
}
|
||||
|
||||
public IBlockState getBlockState() {
|
||||
return getWorld().getBlockState(getPos());
|
||||
return getWorld().getBlockState(this.pos);
|
||||
}
|
||||
|
||||
public WorldServer getWorld() {
|
||||
|
|
|
@ -6,7 +6,7 @@ import java.lang.reflect.Field;
|
|||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
|
||||
public class MCPReflection {
|
||||
public final class MCPReflection {
|
||||
public static Field getMCPField(Class<?> class0, String deobfuscatedName, String obfuscatedName) throws NoSuchFieldException {
|
||||
Field field;
|
||||
try {
|
||||
|
@ -20,11 +20,10 @@ public class MCPReflection {
|
|||
Field modifiers = Field.class.getDeclaredField("modifiers");
|
||||
modifiers.setAccessible(true);
|
||||
modifiers.setInt(field, field.getModifiers() & ~Modifier.FINAL);
|
||||
return field;
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
return field;
|
||||
}
|
||||
|
||||
public static Method getMCPMethod(Class<?> class0, String deobfuscatedName, String obfuscatedName, Class<?> args) throws NoSuchMethodException {
|
||||
|
|
|
@ -6,7 +6,7 @@ import java.util.List;
|
|||
/**
|
||||
* @author Robijnvogel
|
||||
*/
|
||||
public class StringUtils {
|
||||
public final class StringUtils {
|
||||
|
||||
public static char flipCase(char in) {
|
||||
if (Character.isUpperCase(in)) {
|
||||
|
@ -19,7 +19,7 @@ public class StringUtils {
|
|||
public static List<String> getAsStringList(Integer[] integers) {
|
||||
List<String> list = new ArrayList<>();
|
||||
for (int integer : integers) {
|
||||
list.add("" + integer);
|
||||
list.add(String.valueOf(integer));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ import java.lang.reflect.InvocationTargetException;
|
|||
import java.lang.reflect.Method;
|
||||
import java.util.EnumSet;
|
||||
|
||||
public class TeleportUtils {
|
||||
public final class TeleportUtils {
|
||||
|
||||
public static Entity teleport(Entity entity, Location location) {
|
||||
return teleport(entity, location, entity.rotationYaw, entity.rotationPitch);
|
||||
|
@ -65,7 +65,7 @@ public class TeleportUtils {
|
|||
}
|
||||
entity.setRotationYawHead(yaw);
|
||||
return entity;
|
||||
} else { // Based on Entity.changeDimension
|
||||
} else { // Based on EntityUtils.changeDimension
|
||||
MinecraftServer server = entity.getServer();
|
||||
WorldServer oldServer = server.getWorld(oldDimension);
|
||||
WorldServer newServer = server.getWorld(newDimension);
|
||||
|
|
|
@ -4,7 +4,7 @@ import net.minecraft.world.World;
|
|||
import net.minecraft.world.WorldServer;
|
||||
import net.minecraftforge.common.DimensionManager;
|
||||
|
||||
public class WorldUtils {
|
||||
public final class WorldUtils {
|
||||
public static WorldServer getWorld(int dim) {
|
||||
return DimensionManager.getWorld(0).getMinecraftServer().getWorld(dim);
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ public abstract class BlockSpecialAir extends Block { // TODO: make water and pi
|
|||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public EnumBlockRenderType getRenderType(IBlockState state) {
|
||||
return EnumBlockRenderType.INVISIBLE; // Tile Entity Special Renderer
|
||||
return EnumBlockRenderType.INVISIBLE; // Tile EntityUtils Special Renderer
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -2,7 +2,7 @@ package ddutils.math;
|
|||
|
||||
import lombok.Value;
|
||||
|
||||
public class GridUtils {
|
||||
public final class GridUtils {
|
||||
@Value
|
||||
public static class GridPos {
|
||||
private int x;
|
||||
|
|
|
@ -3,7 +3,7 @@ package ddutils.math;
|
|||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
public class MathUtils {
|
||||
public final class MathUtils {
|
||||
|
||||
public static <T> T weightedRandom(Map<T, Float> weights) {
|
||||
if (weights.size() == 0) return null;
|
||||
|
|
|
@ -5,7 +5,7 @@ import java.util.Random;
|
|||
/**
|
||||
* @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
|
||||
|
|
|
@ -6,7 +6,7 @@ import net.minecraft.util.math.Vec3i;
|
|||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class NBTUtils {
|
||||
public final class NBTUtils {
|
||||
public static Map<String, Integer> readMapStringInteger(NBTTagCompound nbt) {
|
||||
HashMap<String, Integer> map = new HashMap<>();
|
||||
for (String str : nbt.getKeySet()) {
|
||||
|
|
|
@ -203,7 +203,7 @@ public class Schematic {
|
|||
|
||||
private static String getBlockStateStringFromState(IBlockState state) {
|
||||
Block block = state.getBlock();
|
||||
String blockNameString = "" + Block.REGISTRY.getNameForObject(block);
|
||||
String blockNameString = String.valueOf(Block.REGISTRY.getNameForObject(block));
|
||||
StringBuilder blockStateString = new StringBuilder();
|
||||
String totalString;
|
||||
IBlockState defaultState = block.getDefaultState();
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Add table
Reference in a new issue