Destination system and registry rewrite
- Major simplifincations to the TileEntityRift class and destination classes - Use a graph in the RiftRegistry for simpler tracking of rift sources and targets
This commit is contained in:
parent
a9a780c64c
commit
27cec3bcad
52 changed files with 1033 additions and 918 deletions
|
@ -64,6 +64,7 @@ configurations {
|
|||
|
||||
dependencies {
|
||||
embed 'com.flowpowered:flow-math:1.0.3'
|
||||
embed 'org.jgrapht:jgrapht-core:1.1.0'
|
||||
compile 'com.github.DimensionalDevelopment:AnnotatedNBT:-SNAPSHOT'
|
||||
}
|
||||
|
||||
|
|
|
@ -7,9 +7,11 @@ import net.minecraft.entity.item.EntityItem;
|
|||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.projectile.*;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public final class EntityUtils {
|
||||
|
||||
public static String getEntityOwnerUUID(Entity entity) { // TODO: make this recursive
|
||||
public static UUID 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;
|
||||
|
@ -25,8 +27,8 @@ public final class EntityUtils {
|
|||
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 :)
|
||||
if (entity instanceof IEntityOwnable && ((IEntityOwnable) entity).getOwnerId() != null) return ((IEntityOwnable) entity).getOwnerId();
|
||||
if (entity instanceof EntityPlayer) return entity.getUniqueID(); // 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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ import org.dimdev.annotatednbt.Saved;
|
|||
import org.dimdev.annotatednbt.NBTSerializable;
|
||||
|
||||
@ToString @AllArgsConstructor @NoArgsConstructor
|
||||
@NBTSerializable public class RotatedLocation implements INBTStorable {
|
||||
@NBTSerializable public class RotatedLocation implements INBTStorable { // TODO: extend Location
|
||||
@Getter @Saved /*private*/ Location location;
|
||||
@Getter @Saved /*private*/ float yaw;
|
||||
@Getter @Saved /*private*/ float pitch;
|
||||
|
|
17
src/main/java/org/dimdev/ddutils/TypeFilter.java
Normal file
17
src/main/java/org/dimdev/ddutils/TypeFilter.java
Normal file
|
@ -0,0 +1,17 @@
|
|||
package org.dimdev.ddutils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public final class TypeFilter {
|
||||
public static <T extends U, U> List<T> filter(Collection<U> list, Class<T> filterClass) {
|
||||
List<T> filtered = new ArrayList<>();
|
||||
for (U e : list) {
|
||||
if (filterClass.isAssignableFrom(e.getClass())) {
|
||||
filtered.add(filterClass.cast(e));
|
||||
}
|
||||
}
|
||||
return filtered;
|
||||
}
|
||||
}
|
|
@ -19,7 +19,7 @@ public final class NBTUtils {
|
|||
}
|
||||
}
|
||||
|
||||
public static void readFromNBT(Object obj, NBTTagCompound nbt) {
|
||||
public static <T> T readFromNBT(T obj, NBTTagCompound nbt) {
|
||||
try {
|
||||
Class<?> callingClass = Class.forName(new Exception().getStackTrace()[1].getClassName());
|
||||
Class<?> nbtWriter = Class.forName(callingClass.getPackage().getName() + "." + callingClass.getSimpleName() + "NBTWriter");
|
||||
|
@ -28,5 +28,6 @@ public final class NBTUtils {
|
|||
} catch (ClassNotFoundException|NoSuchMethodException|IllegalAccessException|InvocationTargetException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
|
20
src/main/java/org/dimdev/dimdoors/ddutils/GraphUtils.java
Normal file
20
src/main/java/org/dimdev/dimdoors/ddutils/GraphUtils.java
Normal file
|
@ -0,0 +1,20 @@
|
|||
package org.dimdev.dimdoors.ddutils;
|
||||
|
||||
import org.jgrapht.Graph;
|
||||
|
||||
public final class GraphUtils {
|
||||
public static <V, E> void replaceVertex(Graph<V, E> graph, V vertex, V replace) {
|
||||
graph.addVertex(replace);
|
||||
for (E edge : graph.outgoingEdgesOf(vertex)) graph.addEdge(replace, graph.getEdgeTarget(edge), edge);
|
||||
for (E edge : graph.incomingEdgesOf(vertex)) graph.addEdge(graph.getEdgeSource(edge), replace, edge);
|
||||
graph.removeVertex(vertex);
|
||||
}
|
||||
|
||||
public static <V, E> V followPointer(Graph<V, E> graph, V pointer) {
|
||||
if (pointer != null) {
|
||||
E edge = graph.outgoingEdgesOf(pointer).stream().findFirst().orElse(null);
|
||||
return graph.getEdgeTarget(edge);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -7,6 +7,7 @@ import org.dimdev.dimdoors.DimDoors;
|
|||
import org.dimdev.dimdoors.shared.blocks.ModBlocks;
|
||||
import org.dimdev.dimdoors.shared.entities.EntityMonolith;
|
||||
import org.dimdev.dimdoors.shared.items.ModItems;
|
||||
import org.dimdev.dimdoors.shared.pockets.SchematicHandler;
|
||||
import org.dimdev.dimdoors.shared.rifts.*;
|
||||
import org.dimdev.dimdoors.shared.rifts.destinations.*;
|
||||
import org.dimdev.dimdoors.shared.sound.ModSounds;
|
||||
|
@ -44,7 +45,7 @@ public abstract class CommonProxy {
|
|||
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("public_pocket", PublicPocketDestination.class);
|
||||
RiftDestination.destinationRegistry.put("pocket_entrance", PocketEntranceDestination.class);
|
||||
RiftDestination.destinationRegistry.put("pocket_exit", PocketExitDestination.class);
|
||||
RiftDestination.destinationRegistry.put("private", PrivateDestination.class);
|
||||
|
|
|
@ -10,7 +10,7 @@ import net.minecraftforge.fml.common.eventhandler.EventPriority;
|
|||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.gameevent.PlayerEvent;
|
||||
import org.dimdev.dimdoors.shared.pockets.PocketRegistry;
|
||||
import org.dimdev.dimdoors.shared.rifts.RiftRegistry;
|
||||
import org.dimdev.dimdoors.shared.rifts.registry.RiftRegistry;
|
||||
import org.dimdev.dimdoors.shared.world.ModDimensions;
|
||||
|
||||
public final class EventHandler {
|
||||
|
@ -34,7 +34,7 @@ public final class EventHandler {
|
|||
if (!world.isRemote
|
||||
&& !player.isDead
|
||||
&& ModDimensions.isDimDoorsPocketDimension(world)
|
||||
&& !PocketRegistry.getForDim(dim).isPlayerAllowedToBeHere(player, player.getPosition())) {
|
||||
&& !PocketRegistry.instance(dim).isPlayerAllowedToBeHere(player, player.getPosition())) {
|
||||
// TODO: make the world circular
|
||||
}
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ public final class EventHandler {
|
|||
public static void onDimensionChange(PlayerEvent.PlayerChangedDimensionEvent event) {
|
||||
// TODO: PocketLib compatibility
|
||||
if (ModDimensions.isDimDoorsPocketDimension(event.fromDim) && !ModDimensions.isDimDoorsPocketDimension(event.toDim)) {
|
||||
RiftRegistry.setOverworldRift(event.player.getCachedUniqueIdString(), null);
|
||||
RiftRegistry.instance().setOverworldRift(event.player.getUniqueID(), null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,11 +25,11 @@ import org.dimdev.dimdoors.shared.world.limbodimension.WorldProviderLimbo;
|
|||
public static VirtualLocation fromLocation(Location location) {
|
||||
VirtualLocation virtualLocation = null;
|
||||
if (ModDimensions.isDimDoorsPocketDimension(location.getDim())) {
|
||||
Pocket pocket = PocketRegistry.getForDim(location.getDim()).getPocketAt(location.getPos());
|
||||
Pocket pocket = PocketRegistry.instance(location.getDim()).getPocketAt(location.getPos());
|
||||
if (pocket != null) {
|
||||
virtualLocation = pocket.getVirtualLocation(); // TODO: pocket-relative coordinates
|
||||
} else {
|
||||
virtualLocation = new VirtualLocation(0, 0, 0, 0); // TODO: door was placed in a pocket dim but outside of a pocket...
|
||||
virtualLocation = null; // TODO: door was placed in a pocket dim but outside of a pocket...
|
||||
}
|
||||
} else if (location.getWorld().provider instanceof WorldProviderLimbo) {
|
||||
virtualLocation = new VirtualLocation(location.getDim(), location.getX(), location.getZ(), Config.getMaxDungeonDepth());
|
||||
|
|
|
@ -15,7 +15,8 @@ import net.minecraft.util.EnumFacing;
|
|||
import net.minecraft.util.EnumHand;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import org.dimdev.dimdoors.shared.rifts.RiftRegistry;
|
||||
import org.dimdev.ddutils.Location;
|
||||
import org.dimdev.dimdoors.shared.rifts.registry.RiftRegistry;
|
||||
import org.dimdev.dimdoors.shared.tileentities.TileEntityEntranceRift;
|
||||
import org.dimdev.dimdoors.shared.tileentities.TileEntityFloatingRift;
|
||||
|
||||
|
@ -130,7 +131,7 @@ public abstract class BlockDimensionalDoor extends BlockDoor implements IRiftPro
|
|||
TileEntityEntranceRift rift = getRift(world, pos, state);
|
||||
super.breakBlock(world, pos, state);
|
||||
if (world.isRemote) return;
|
||||
if (rift.isPlaceRiftOnBreak() || rift.isRegistered() && RiftRegistry.getRiftInfo(rift.getLocation()).getSources().size() > 0 && !rift.isAlwaysDelete()) {
|
||||
if (rift.isPlaceRiftOnBreak() || rift.isRegistered() && RiftRegistry.instance().getSources(new Location(rift.getWorld(), rift.getPos())).size() > 0 && !rift.isAlwaysDelete()) {
|
||||
world.setBlockState(rift.getPos(), ModBlocks.RIFT.getDefaultState());
|
||||
TileEntityFloatingRift newRift = (TileEntityFloatingRift) world.getTileEntity(pos);
|
||||
newRift.copyFrom(rift);
|
||||
|
|
|
@ -3,10 +3,8 @@ package org.dimdev.dimdoors.shared.blocks;
|
|||
import net.minecraft.block.state.IBlockState;
|
||||
import org.dimdev.dimdoors.DimDoors;
|
||||
import org.dimdev.dimdoors.shared.items.ModItems;
|
||||
import org.dimdev.dimdoors.shared.rifts.AvailableLink;
|
||||
import org.dimdev.dimdoors.shared.rifts.WeightedRiftDestination;
|
||||
import org.dimdev.dimdoors.shared.rifts.registry.LinkProperties;
|
||||
import org.dimdev.dimdoors.shared.rifts.destinations.AvailableLinkDestination;
|
||||
import org.dimdev.dimdoors.shared.rifts.destinations.NewPublicDestination;
|
||||
import org.dimdev.dimdoors.shared.tileentities.TileEntityEntranceRift;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.item.Item;
|
||||
|
@ -37,21 +35,19 @@ public class BlockDimensionalDoorGold extends BlockDimensionalDoor {
|
|||
|
||||
@Override
|
||||
public void setupRift(TileEntityEntranceRift rift) {
|
||||
AvailableLink link = AvailableLink.builder()
|
||||
rift.setProperties(LinkProperties.builder()
|
||||
.groups(new HashSet<>(Arrays.asList(0, 1)))
|
||||
.linksRemaining(1)
|
||||
.replaceDestination(UUID.randomUUID()).build();
|
||||
rift.addAvailableLink(link);
|
||||
AvailableLinkDestination destination = AvailableLinkDestination.builder()
|
||||
.replaceDestination(UUID.randomUUID()).build());
|
||||
rift.setDestination(AvailableLinkDestination.builder()
|
||||
.acceptedGroups(Collections.singleton(0))
|
||||
.coordFactor(1)
|
||||
.negativeDepthFactor(10000)
|
||||
.positiveDepthFactor(80)
|
||||
.weightMaximum(100)
|
||||
.linkId(link.id)
|
||||
.noLink(false)
|
||||
.newRiftWeight(1).build();
|
||||
rift.addWeightedDestination(new WeightedRiftDestination(destination, 1, 0, null, link.replaceDestination));
|
||||
.noLinkBack(false)
|
||||
.newRiftWeight(1).build());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -4,7 +4,7 @@ import net.minecraft.block.state.IBlockState;
|
|||
import net.minecraft.init.Blocks;
|
||||
import org.dimdev.dimdoors.DimDoors;
|
||||
import org.dimdev.dimdoors.shared.items.ModItems;
|
||||
import org.dimdev.dimdoors.shared.rifts.destinations.NewPublicDestination;
|
||||
import org.dimdev.dimdoors.shared.rifts.destinations.PublicPocketDestination;
|
||||
import org.dimdev.dimdoors.shared.tileentities.TileEntityEntranceRift;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.item.Item;
|
||||
|
@ -36,8 +36,8 @@ public class BlockDimensionalDoorIron extends BlockDimensionalDoor {
|
|||
|
||||
@Override
|
||||
public void setupRift(TileEntityEntranceRift rift) {
|
||||
NewPublicDestination destination = NewPublicDestination.builder().build();
|
||||
rift.setSingleDestination(destination);
|
||||
PublicPocketDestination destination = PublicPocketDestination.builder().build();
|
||||
rift.setDestination(destination);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -37,11 +37,10 @@ public class BlockDimensionalDoorPersonal extends BlockDimensionalDoor {
|
|||
@Override
|
||||
public void setupRift(TileEntityEntranceRift rift) {
|
||||
if (rift.getWorld().provider instanceof WorldProviderPersonalPocket) {
|
||||
rift.setSingleDestination(new PrivatePocketExitDestination()); // exit
|
||||
rift.setDestination(new PrivatePocketExitDestination()); // exit
|
||||
} else {
|
||||
rift.setSingleDestination(new PrivateDestination()); // entrances
|
||||
rift.setDestination(new PrivateDestination()); // entrances
|
||||
}
|
||||
rift.setChaosWeight(0); // TODO: generated schematic exits too
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -32,7 +32,7 @@ public class BlockDimensionalTrapdoorWood extends BlockDimensionalTrapdoor {
|
|||
|
||||
@Override
|
||||
public void setupRift(TileEntityEntranceRift rift) {
|
||||
rift.setSingleDestination(new EscapeDestination());
|
||||
rift.setDestination(new EscapeDestination());
|
||||
}
|
||||
|
||||
@Override public boolean canBePlacedOnRift() {
|
||||
|
|
|
@ -25,9 +25,6 @@ public interface IRiftProvider<T extends TileEntityRift> extends ITileEntityProv
|
|||
if (world.isRemote) return;
|
||||
T rift = getRift(world, pos, state);
|
||||
|
||||
// Set the rift's virtual position
|
||||
rift.setVirtualLocation(VirtualLocation.fromLocation(new Location(world, pos)));
|
||||
|
||||
// Configure the rift to its default functionality
|
||||
setupRift(rift);
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ import net.minecraft.util.math.BlockPos;
|
|||
import net.minecraft.util.text.TextComponentString;
|
||||
import net.minecraftforge.common.DimensionManager;
|
||||
|
||||
public class CommandDimTeleport extends CommandBase { // TODO: localization
|
||||
public class CommandDimTeleport extends CommandBase { // TODO: localization, CommandException
|
||||
|
||||
private final List<String> aliases;
|
||||
|
||||
|
@ -47,7 +47,7 @@ public class CommandDimTeleport extends CommandBase { // TODO: localization
|
|||
|
||||
@Override
|
||||
public void execute(MinecraftServer server, ICommandSender sender, String[] args) throws CommandException {
|
||||
// Check correct number of arguments
|
||||
// Check that the number of arguments is correct
|
||||
if (args.length < 4 || args.length > 6) {
|
||||
sender.sendMessage(new TextComponentString("[DimDoors] Usage: /" + getUsage(sender)));
|
||||
return;
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
package org.dimdev.dimdoors.shared.commands;
|
||||
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import org.dimdev.dimdoors.DimDoors;
|
||||
import org.dimdev.dimdoors.shared.*;
|
||||
import org.dimdev.dimdoors.shared.pockets.*;
|
||||
import org.dimdev.dimdoors.shared.rifts.TileEntityRift;
|
||||
import org.dimdev.ddutils.Location;
|
||||
|
@ -48,7 +46,7 @@ public class CommandPocket extends CommandBase {
|
|||
|
||||
@Override
|
||||
public void execute(MinecraftServer server, ICommandSender sender, String[] args) throws CommandException { // TODO: more pocket commands (replace pocket, get ID, teleport to pocket, etc.)
|
||||
// Check correct number of arguments
|
||||
// Check that the number of arguments is correct
|
||||
if (args.length < 2 || args.length > 3) {
|
||||
sender.sendMessage(new TextComponentString("[DimDoors] Usage: /" + getUsage(sender)));
|
||||
return;
|
||||
|
|
|
@ -7,7 +7,6 @@ import org.dimdev.dimdoors.shared.blocks.BlockDimensionalDoorGold;
|
|||
import org.dimdev.dimdoors.shared.blocks.ModBlocks;
|
||||
import org.dimdev.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;
|
||||
|
|
|
@ -65,7 +65,7 @@ public class ItemRiftSignature extends Item {
|
|||
World sourceWorld = target.getLocation().getWorld();
|
||||
sourceWorld.setBlockState(target.getLocation().getPos(), ModBlocks.RIFT.getDefaultState());
|
||||
TileEntityRift rift1 = (TileEntityRift) target.getLocation().getTileEntity();
|
||||
rift1.setSingleDestination(new GlobalDestination(new Location(world, pos)));
|
||||
rift1.setDestination(new GlobalDestination(new Location(world, pos)));
|
||||
rift1.register();
|
||||
rift1.setRotation(target.getYaw(), 0);
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ public class ItemRiftSignature extends Item {
|
|||
// Place a rift at the target point
|
||||
world.setBlockState(pos, ModBlocks.RIFT.getDefaultState());
|
||||
TileEntityRift rift2 = (TileEntityRift) world.getTileEntity(pos);
|
||||
rift2.setSingleDestination(new GlobalDestination(target.getLocation()));
|
||||
rift2.setDestination(new GlobalDestination(target.getLocation()));
|
||||
rift2.setRotation(player.rotationYaw, 0);
|
||||
rift2.register();
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@ public class ItemStabilizedRiftSignature extends Item { // TODO: common supercla
|
|||
// Place a rift at the source point
|
||||
world.setBlockState(pos, ModBlocks.RIFT.getDefaultState());
|
||||
TileEntityRift rift2 = (TileEntityRift) world.getTileEntity(pos);
|
||||
rift2.setSingleDestination(new GlobalDestination(target.getLocation()));
|
||||
rift2.setDestination(new GlobalDestination(target.getLocation()));
|
||||
rift2.setRotation(player.rotationYaw, 0);
|
||||
rift2.register();
|
||||
|
||||
|
|
|
@ -1,34 +1,37 @@
|
|||
package org.dimdev.dimdoors.shared.pockets;
|
||||
|
||||
import org.dimdev.ddutils.nbt.INBTStorable;
|
||||
import org.dimdev.ddutils.nbt.NBTUtils;
|
||||
import org.dimdev.annotatednbt.Saved;
|
||||
import org.dimdev.annotatednbt.NBTSerializable;
|
||||
import org.dimdev.dimdoors.shared.VirtualLocation;
|
||||
import org.dimdev.dimdoors.shared.rifts.*;
|
||||
import org.dimdev.dimdoors.shared.rifts.destinations.PocketEntranceDestination;
|
||||
import org.dimdev.dimdoors.shared.rifts.destinations.PocketExitDestination;
|
||||
import org.dimdev.dimdoors.shared.tileentities.TileEntityEntranceRift;
|
||||
import org.dimdev.ddutils.Location;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import org.dimdev.ddutils.math.MathUtils;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import net.minecraft.nbt.*;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import org.dimdev.annotatednbt.NBTSerializable;
|
||||
import org.dimdev.annotatednbt.Saved;
|
||||
import org.dimdev.ddutils.Location;
|
||||
import org.dimdev.ddutils.math.MathUtils;
|
||||
import org.dimdev.ddutils.nbt.INBTStorable;
|
||||
import org.dimdev.ddutils.nbt.NBTUtils;
|
||||
import org.dimdev.dimdoors.shared.VirtualLocation;
|
||||
import org.dimdev.dimdoors.shared.rifts.RiftDestination;
|
||||
import org.dimdev.dimdoors.shared.rifts.TileEntityRift;
|
||||
import org.dimdev.dimdoors.shared.rifts.destinations.PocketEntranceDestination;
|
||||
import org.dimdev.dimdoors.shared.rifts.destinations.PocketExitDestination;
|
||||
import org.dimdev.dimdoors.shared.rifts.registry.LinkProperties;
|
||||
import org.dimdev.dimdoors.shared.tileentities.TileEntityEntranceRift;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
@NBTSerializable public class Pocket implements INBTStorable { // TODO: better visibilities
|
||||
|
||||
@Saved @Getter /*package-private*/ int id;
|
||||
@Saved @Getter /*package-private*/ int x; // Grid x TODO: rename to gridX and gridY
|
||||
@Saved @Getter /*package-private*/ int z; // Grid y
|
||||
@Saved @Getter @Setter /*package-private*/ int size; // In chunks TODO: non chunk-based size, better bounds such as minX, minZ, maxX, maxZ, etc.
|
||||
@Saved @Getter @Setter /*package-private*/ VirtualLocation virtualLocation; // The non-pocket dimension from which this dungeon was created
|
||||
@Saved @Getter @Setter /*package-private*/ Location entrance;
|
||||
@Saved @Getter /*package-private*/ List<Location> riftLocations;
|
||||
@Saved @Getter protected int id;
|
||||
@Saved @Getter protected int x; // Grid x TODO: rename to gridX and gridY, or just convert to non-grid dependant coordinates
|
||||
@Saved @Getter protected int z; // Grid y
|
||||
@Saved @Getter @Setter protected int size; // In chunks TODO: non chunk-based size, better bounds such as minX, minZ, maxX, maxZ, etc.
|
||||
@Saved @Getter @Setter protected VirtualLocation virtualLocation;
|
||||
@Saved @Getter @Setter protected Location entrance; // TODO: move this to the rift registry (pocketlib)
|
||||
@Saved @Getter protected List<Location> riftLocations; // TODO: convert to a list of all tile entities (for chests, and to make it independant of pocketlib)
|
||||
|
||||
@Getter int dim; // Not saved
|
||||
|
||||
|
@ -44,11 +47,12 @@ import net.minecraft.util.math.BlockPos;
|
|||
|
||||
// TODO: make these static?
|
||||
@Override public void readFromNBT(NBTTagCompound nbt) { NBTUtils.readFromNBT(this, nbt); }
|
||||
|
||||
@Override public NBTTagCompound writeToNBT(NBTTagCompound nbt) { return NBTUtils.writeToNBT(this, nbt); }
|
||||
|
||||
boolean isInBounds(BlockPos pos) {
|
||||
// pocket bounds
|
||||
int gridSize = PocketRegistry.getForDim(dim).getGridSize();
|
||||
int gridSize = PocketRegistry.instance(dim).getGridSize();
|
||||
int minX = x * gridSize;
|
||||
int minZ = z * gridSize;
|
||||
int maxX = minX + (size + 1) * 16;
|
||||
|
@ -72,89 +76,57 @@ import net.minecraft.util.math.BlockPos;
|
|||
public void setup() { // Always call after creating a pocket except when building the pocket
|
||||
List<TileEntityRift> rifts = getRifts();
|
||||
|
||||
HashMap<Integer, Float> entranceIndexWeights = new HashMap<>();
|
||||
HashMap<TileEntityRift, Float> entranceIndexWeights = new HashMap<>();
|
||||
|
||||
int index = 0;
|
||||
for (TileEntityRift rift : rifts) { // Find an entrance
|
||||
for (WeightedRiftDestination weightedPocketEntranceDest : rift.getDestinations()) {
|
||||
if (weightedPocketEntranceDest.getDestination() instanceof PocketEntranceDestination) {
|
||||
entranceIndexWeights.put(index, weightedPocketEntranceDest.getWeight());
|
||||
rift.markDirty();
|
||||
index++;
|
||||
}
|
||||
if (rift.getDestination() instanceof PocketEntranceDestination) {
|
||||
entranceIndexWeights.put(rift, ((PocketEntranceDestination) rift.getDestination()).getWeight());
|
||||
rift.markDirty();
|
||||
}
|
||||
}
|
||||
|
||||
if (entranceIndexWeights.size() == 0) return;
|
||||
int selectedEntranceIndex = MathUtils.weightedRandom(entranceIndexWeights);
|
||||
TileEntityRift selectedEntrance = MathUtils.weightedRandom(entranceIndexWeights);
|
||||
|
||||
// Replace entrances with appropriate destinations
|
||||
index = 0;
|
||||
for (TileEntityRift rift : rifts) {
|
||||
ListIterator<WeightedRiftDestination> destIterator = rift.getDestinations().listIterator();
|
||||
while (destIterator.hasNext()) {
|
||||
WeightedRiftDestination wdest = destIterator.next();
|
||||
RiftDestination dest = wdest.getDestination();
|
||||
if (dest instanceof PocketEntranceDestination) {
|
||||
destIterator.remove();
|
||||
if (index == selectedEntranceIndex) {
|
||||
entrance = new Location(rift.getWorld(), rift.getPos());
|
||||
PocketRegistry.getForDim(dim).markDirty();
|
||||
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 = ((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
|
||||
}
|
||||
}
|
||||
index++;
|
||||
RiftDestination dest = rift.getDestination();
|
||||
if (dest instanceof PocketEntranceDestination) {
|
||||
if (rift == selectedEntrance) {
|
||||
entrance = new Location(rift.getWorld(), rift.getPos());
|
||||
PocketRegistry.instance(dim).markDirty();
|
||||
rift.setDestination(((PocketEntranceDestination) dest).getIfDestination());
|
||||
} else {
|
||||
rift.setDestination(((PocketEntranceDestination) dest).getOtherwiseDestination());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// set virtual locations and register rifts
|
||||
// register the rifts
|
||||
for (TileEntityRift rift : rifts) {
|
||||
rift.setVirtualLocation(virtualLocation);
|
||||
rift.register();
|
||||
}
|
||||
}
|
||||
|
||||
public void linkPocketTo(RiftDestination linkTo, RiftDestination oldDest, AvailableLink availableLink) {
|
||||
public void linkPocketTo(RiftDestination linkTo, LinkProperties linkProperties) {
|
||||
List<TileEntityRift> rifts = getRifts();
|
||||
|
||||
// Link pocket exits back
|
||||
for (TileEntityRift rift : rifts) {
|
||||
ListIterator<WeightedRiftDestination> destIterator = rift.getDestinations().listIterator();
|
||||
while (destIterator.hasNext()) {
|
||||
WeightedRiftDestination wdest = destIterator.next();
|
||||
RiftDestination dest = wdest.getDestination();
|
||||
if (dest instanceof PocketExitDestination) {
|
||||
destIterator.remove();
|
||||
if (rift.isRegistered()) dest.unregister(rift);
|
||||
if (availableLink != null) rift.addAvailableLink(availableLink.toBuilder().build());
|
||||
if (linkTo != null) destIterator.add(new WeightedRiftDestination(linkTo, wdest.getWeight(), wdest.getGroup(), oldDest));
|
||||
if (rift.isRegistered()) linkTo.register(rift);
|
||||
if (rift instanceof TileEntityEntranceRift && !rift.isAlwaysDelete()) {
|
||||
((TileEntityEntranceRift) rift).setPlaceRiftOnBreak(true); // We modified the door's state
|
||||
}
|
||||
rift.markDirty();
|
||||
RiftDestination dest = rift.getDestination();
|
||||
if (dest instanceof PocketExitDestination) {
|
||||
if (linkProperties != null) rift.setProperties(linkProperties);
|
||||
rift.setDestination(linkTo);
|
||||
if (rift instanceof TileEntityEntranceRift && !rift.isAlwaysDelete()) {
|
||||
((TileEntityEntranceRift) rift).setPlaceRiftOnBreak(true); // We modified the door's state
|
||||
}
|
||||
rift.markDirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void unlinkPocket() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
public BlockPos getOrigin() {
|
||||
int gridSize = PocketRegistry.getForDim(dim).getGridSize();
|
||||
int gridSize = PocketRegistry.instance(dim).getGridSize();
|
||||
return new BlockPos(x * gridSize * 16, 0, z * gridSize * 16); // TODO: configurable yBase?
|
||||
}
|
||||
|
||||
// TODO: method to erase a pocket
|
||||
}
|
||||
|
|
|
@ -11,9 +11,9 @@ public final class PocketGenerator {
|
|||
public static Pocket generatePocketFromTemplate(int dim, PocketTemplate pocketTemplate, VirtualLocation virtualLocation) {
|
||||
DimDoors.log.info("Generating pocket from template " + pocketTemplate.getName() + " at virtual location " + virtualLocation);
|
||||
|
||||
PocketRegistry registry = PocketRegistry.getForDim(dim);
|
||||
PocketRegistry registry = PocketRegistry.instance(dim);
|
||||
Pocket pocket = registry.newPocket();
|
||||
pocketTemplate.place(pocket, 0); // TODO: config option for yBase
|
||||
pocketTemplate.place(pocket);
|
||||
pocket.setVirtualLocation(virtualLocation);
|
||||
return pocket;
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ import org.dimdev.dimdoors.shared.world.ModDimensions;
|
|||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import lombok.Getter;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
|
@ -21,7 +22,8 @@ import net.minecraft.util.math.BlockPos;
|
|||
import net.minecraft.world.storage.MapStorage;
|
||||
import net.minecraft.world.storage.WorldSavedData;
|
||||
|
||||
@NBTSerializable public class PocketRegistry extends WorldSavedData { // TODO: unregister pocket entrances, private pocket entrances/exits
|
||||
@NBTSerializable public class
|
||||
PocketRegistry extends WorldSavedData { // TODO: unregister pocket entrances, private pocket entrances/exits
|
||||
|
||||
private static final String DATA_NAME = DimDoors.MODID + "_pockets";
|
||||
@Getter private static final int DATA_VERSION = 0; // IMPORTANT: Update this and upgradeRegistry when making changes.
|
||||
|
@ -30,7 +32,7 @@ import net.minecraft.world.storage.WorldSavedData;
|
|||
@Saved @Getter /*package-private*/ int maxPocketSize;
|
||||
@Saved @Getter /*package-private*/ int privatePocketSize;
|
||||
@Saved @Getter /*package-private*/ int publicPocketSize;
|
||||
@Saved /*package-private*/ BiMap<String, Integer> privatePocketMap; // Player UUID -> Pocket ID, in pocket dim only
|
||||
@Saved /*package-private*/ BiMap<UUID, Integer> privatePocketMap; // Player UUID -> Pocket ID, in pocket dim only TODO: move this out of pocketlib
|
||||
@Saved @Getter /*package-private*/ Map<Integer, Pocket> pockets; // TODO: remove getter?
|
||||
@Saved @Getter /*package-private*/ int nextID;
|
||||
|
||||
|
@ -44,7 +46,7 @@ import net.minecraft.world.storage.WorldSavedData;
|
|||
super(s);
|
||||
}
|
||||
|
||||
public static PocketRegistry getForDim(int dim) {
|
||||
public static PocketRegistry instance(int dim) {
|
||||
if (!ModDimensions.isDimDoorsPocketDimension(dim)) throw new UnsupportedOperationException("PocketRegistry is only available for pocket dimensions!");
|
||||
|
||||
MapStorage storage = WorldUtils.getWorld(dim).getPerWorldStorage();
|
||||
|
@ -155,17 +157,17 @@ import net.minecraft.world.storage.WorldSavedData;
|
|||
}
|
||||
|
||||
// TODO: these should be per-map rather than per-world
|
||||
public int getPrivatePocketID(String playerUUID) {
|
||||
public int getPrivatePocketID(UUID playerUUID) {
|
||||
Integer id = privatePocketMap.get(playerUUID);
|
||||
if (id == null) return -1;
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getPrivatePocketOwner(int id) {
|
||||
public UUID getPrivatePocketOwner(int id) {
|
||||
return privatePocketMap.inverse().get(id);
|
||||
}
|
||||
|
||||
public void setPrivatePocketID(String playerUUID, int id) {
|
||||
public void setPrivatePocketID(UUID playerUUID, int id) {
|
||||
privatePocketMap.put(playerUUID, id);
|
||||
markDirty();
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@ import net.minecraft.util.math.BlockPos;
|
|||
import net.minecraft.world.WorldServer;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Robijnvogel
|
||||
*/
|
||||
@AllArgsConstructor @RequiredArgsConstructor// TODO: use @Builder?
|
||||
|
@ -33,22 +32,23 @@ public class PocketTemplate {
|
|||
|
||||
public float getWeight(int depth) {
|
||||
if (depth < 0) return 100; // TODO: get rid of this later
|
||||
if (maxDepth - minDepth + 1 != weights.length) throw new IllegalStateException("This PocetTemplate wasn't set up correctly!");
|
||||
if (maxDepth - minDepth + 1 != weights.length) throw new IllegalStateException("This PocketTemplate wasn't set up correctly!");
|
||||
if (depth < minDepth) return 0;
|
||||
if (depth > maxDepth) return weights[weights.length - 1];
|
||||
return weights[depth - minDepth];
|
||||
}
|
||||
|
||||
public void place(Pocket pocket, int yBase) {
|
||||
public void place(Pocket pocket) {
|
||||
pocket.setSize(size);
|
||||
int gridSize = PocketRegistry.getForDim(pocket.dim).getGridSize();
|
||||
int gridSize = PocketRegistry.instance(pocket.dim).getGridSize();
|
||||
int dim = pocket.dim;
|
||||
int xBase = pocket.getX() * gridSize * 16;
|
||||
int yBase = 0;
|
||||
int zBase = pocket.getZ() * gridSize * 16;
|
||||
DimDoors.log.info("Placing new pocket using schematic " + schematic.schematicName + " at x = " + xBase + ", z = " + zBase);
|
||||
|
||||
WorldServer world = WorldUtils.getWorld(dim);
|
||||
Schematic.place(schematic, world, xBase, yBase, zBase);
|
||||
Schematic.place(schematic, world, xBase, 0, zBase);
|
||||
|
||||
// Set pocket riftLocations
|
||||
pocket.riftLocations = new ArrayList<>();
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package org.dimdev.dimdoors.shared;
|
||||
package org.dimdev.dimdoors.shared.pockets;
|
||||
|
||||
import org.dimdev.dimdoors.shared.pockets.PocketTemplate;
|
||||
import org.dimdev.dimdoors.shared.Config;
|
||||
import org.dimdev.ddutils.math.MathUtils;
|
||||
import org.dimdev.ddutils.schem.Schematic;
|
||||
import com.google.gson.JsonArray;
|
|
@ -3,23 +3,23 @@ package org.dimdev.dimdoors.shared.rifts;
|
|||
import com.google.common.collect.BiMap;
|
||||
import com.google.common.collect.HashBiMap;
|
||||
import org.dimdev.ddutils.Location;
|
||||
import org.dimdev.ddutils.RGBA;
|
||||
import org.dimdev.ddutils.RotatedLocation;
|
||||
import org.dimdev.ddutils.nbt.INBTStorable;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import lombok.*; // Don't change import order! (Gradle bug): https://stackoverflow.com/questions/26557133/
|
||||
import org.dimdev.dimdoors.shared.rifts.registry.RiftRegistry;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.Set;
|
||||
|
||||
@Getter @EqualsAndHashCode @ToString
|
||||
@EqualsAndHashCode @ToString
|
||||
public abstract class RiftDestination implements INBTStorable {
|
||||
|
||||
/*private*/ public static final BiMap<String, Class<? extends RiftDestination>> destinationRegistry = HashBiMap.create(); // TODO: move to RiftDestinationRegistry
|
||||
//private String type;
|
||||
protected WeightedRiftDestination weightedDestination;
|
||||
public static final BiMap<String, Class<? extends RiftDestination>> destinationRegistry = HashBiMap.create(); // TODO: move to RiftDestinationRegistry
|
||||
|
||||
public RiftDestination() {
|
||||
//type = destinationRegistry.inverse().get(getClass());
|
||||
}
|
||||
public RiftDestination() {}
|
||||
|
||||
public static RiftDestination readDestinationNBT(NBTTagCompound nbt) {
|
||||
String type = nbt.getString("type");
|
||||
|
@ -28,7 +28,6 @@ public abstract class RiftDestination implements INBTStorable {
|
|||
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);
|
||||
|
@ -38,7 +37,7 @@ public abstract class RiftDestination implements INBTStorable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void readFromNBT(NBTTagCompound nbt) { }
|
||||
public void readFromNBT(NBTTagCompound nbt) {}
|
||||
|
||||
@Override
|
||||
public NBTTagCompound writeToNBT(NBTTagCompound nbt) {
|
||||
|
@ -48,19 +47,30 @@ public abstract class RiftDestination implements INBTStorable {
|
|||
return nbt;
|
||||
}
|
||||
|
||||
public Location getReferencedRift(Location rift) { // TODO: change to getReferencedRifts
|
||||
public abstract boolean teleport(RotatedLocation rift, Entity entity);
|
||||
|
||||
public Location getFixedTarget(Location location) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void register(TileEntityRift rift) {
|
||||
Location loc = getReferencedRift(rift.getLocation());
|
||||
if (loc != null) RiftRegistry.addLink(rift.getLocation(), loc);
|
||||
public void register(Location location) {
|
||||
RiftRegistry.instance().addLink(location, getFixedTarget(location));
|
||||
}
|
||||
|
||||
public void unregister(TileEntityRift rift) {
|
||||
Location loc = getReferencedRift(rift.getLocation());
|
||||
if (loc != null) RiftRegistry.removeLink(rift.getLocation(), loc);
|
||||
public void unregister(Location location) {
|
||||
RiftRegistry.instance().removeLink(location, getFixedTarget(location));
|
||||
}
|
||||
|
||||
public abstract boolean teleport(TileEntityRift rift, Entity entity);
|
||||
public boolean keepAfterTargetGone(Location location) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public RGBA getColor(Location location) {
|
||||
Location target = getFixedTarget(location);
|
||||
if (target != null && RiftRegistry.instance().isRiftAt(target)) {
|
||||
Set<Location> otherRiftTargets = RiftRegistry.instance().getTargets(target);
|
||||
if (otherRiftTargets.size() == 1 && otherRiftTargets.contains(location)) return new RGBA(0, 1, 0, 1);
|
||||
}
|
||||
return new RGBA(1, 0, 0, 1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,292 +0,0 @@
|
|||
package org.dimdev.dimdoors.shared.rifts;
|
||||
|
||||
import com.google.common.collect.ConcurrentHashMultiset;
|
||||
import com.google.common.collect.Multiset;
|
||||
import lombok.*;
|
||||
import lombok.experimental.Wither;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.storage.MapStorage;
|
||||
import net.minecraft.world.storage.WorldSavedData;
|
||||
import net.minecraftforge.common.DimensionManager;
|
||||
import org.dimdev.ddutils.Location;
|
||||
import org.dimdev.ddutils.WorldUtils;
|
||||
import org.dimdev.ddutils.nbt.INBTStorable;
|
||||
import org.dimdev.ddutils.nbt.NBTUtils;
|
||||
import org.dimdev.annotatednbt.Saved;
|
||||
import org.dimdev.annotatednbt.NBTSerializable;
|
||||
import org.dimdev.dimdoors.DimDoors;
|
||||
import org.dimdev.dimdoors.shared.VirtualLocation;
|
||||
import org.dimdev.dimdoors.shared.world.ModDimensions;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@NBTSerializable 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.
|
||||
|
||||
@Saved @Getter protected /*final*/ Map<Location, RiftInfo> rifts = new HashMap<>(); // TODO: convert to a static directed graph, but store links per-world
|
||||
|
||||
@Saved @Getter protected /*final*/ Map<String, Location> privatePocketEntrances = new HashMap<>(); // Player UUID -> last rift used to exit pocket TODO: split into PrivatePocketRiftRegistry subclass
|
||||
@Saved @Getter protected /*final*/ Map<String, List<Location>> privatePocketEntranceLists = new HashMap<>(); // Player UUID -> private pocket entrances TODO: split into PrivatePocketRiftRegistry subclass
|
||||
@Saved @Getter protected /*final*/ Map<String, Location> privatePocketExits = new HashMap<>(); // Player UUID -> last rift used to enter pocket
|
||||
@Saved @Getter protected /*final*/ Map<String, Location> overworldRifts = new HashMap<>();
|
||||
|
||||
@Getter private int dim;
|
||||
private World world;
|
||||
|
||||
@AllArgsConstructor @EqualsAndHashCode @Builder(toBuilder = true)
|
||||
@NBTSerializable public static class RiftInfo implements INBTStorable {
|
||||
// IntelliJ warnings are wrong, Builder needs these initializers!
|
||||
@Saved @Getter public VirtualLocation virtualLocation;
|
||||
@Saved @Getter @Wither public Location location;
|
||||
@Saved @Getter public boolean isEntrance;
|
||||
@Builder.Default @Getter public Set<AvailableLink> availableLinks = new HashSet<>();
|
||||
@Builder.Default @Getter public Multiset<Location> sources = ConcurrentHashMultiset.create();
|
||||
@Builder.Default @Getter public Multiset<Location> destinations = ConcurrentHashMultiset.create();
|
||||
|
||||
public RiftInfo() {
|
||||
availableLinks = new HashSet<>();
|
||||
sources = ConcurrentHashMultiset.create();
|
||||
destinations = ConcurrentHashMultiset.create();
|
||||
}
|
||||
|
||||
@Override public void readFromNBT(NBTTagCompound nbt) { NBTUtils.readFromNBT(this, nbt); }
|
||||
@Override public NBTTagCompound writeToNBT(NBTTagCompound nbt) { return NBTUtils.writeToNBT(this, nbt); }
|
||||
}
|
||||
|
||||
public RiftRegistry() {
|
||||
super(DATA_NAME);
|
||||
}
|
||||
|
||||
public RiftRegistry(String s) {
|
||||
super(s);
|
||||
}
|
||||
|
||||
public static RiftRegistry getForDim(int dim) {
|
||||
MapStorage storage = WorldUtils.getWorld(dim).getPerWorldStorage();
|
||||
RiftRegistry instance = (RiftRegistry) storage.getOrLoadData(RiftRegistry.class, DATA_NAME);
|
||||
|
||||
if (instance == null) {
|
||||
instance = new RiftRegistry();
|
||||
instance.initNewRegistry();
|
||||
storage.setData(DATA_NAME, instance);
|
||||
}
|
||||
|
||||
instance.world = WorldUtils.getWorld(dim);
|
||||
instance.dim = dim;
|
||||
return instance;
|
||||
}
|
||||
|
||||
public void initNewRegistry() {
|
||||
// Nothing to do
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromNBT(NBTTagCompound nbt) {
|
||||
Integer version = nbt.getInteger("version");
|
||||
if (version == null || version != DATA_VERSION) {
|
||||
if (upgradeRegistry(nbt, version == null ? -1 : version)) {
|
||||
markDirty();
|
||||
} else {
|
||||
DimDoors.log.warn("Failed to upgrade the pocket registry, you'll have to recreate your world!");
|
||||
throw new RuntimeException("Couldn't upgrade registry"); // TODO: better exceptions
|
||||
}
|
||||
}
|
||||
|
||||
NBTUtils.readFromNBT(this, nbt);
|
||||
}
|
||||
|
||||
private static boolean upgradeRegistry(@SuppressWarnings("unused") NBTTagCompound nbt, int oldVersion) {
|
||||
if (oldVersion > DATA_VERSION) throw new RuntimeException("Upgrade the mod!"); // TODO: better exceptions
|
||||
switch (oldVersion) {
|
||||
case -1: // No version tag
|
||||
return false;
|
||||
case 0:
|
||||
// Upgrade to 1 or return false
|
||||
case 1:
|
||||
// Upgrade to 2 or return false
|
||||
case 2:
|
||||
// Upgrade to 3 or return false
|
||||
// ...
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NBTTagCompound writeToNBT(NBTTagCompound nbt) {
|
||||
nbt.setInteger("version", DATA_VERSION);
|
||||
return NBTUtils.writeToNBT(this, nbt);
|
||||
}
|
||||
|
||||
public static RiftInfo getRiftInfo(Location rift) {
|
||||
return getRegistry(rift).rifts.get(rift);
|
||||
}
|
||||
|
||||
public static void addRift(Location rift) {
|
||||
DimDoors.log.info("Rift added at " + rift);
|
||||
RiftRegistry registry = getRegistry(rift);
|
||||
registry.rifts.computeIfAbsent(rift, k -> new RiftInfo());
|
||||
registry.markDirty();
|
||||
}
|
||||
|
||||
public static void removeRift(Location rift) {
|
||||
DimDoors.log.info("Rift removed at " + rift);
|
||||
RiftRegistry registry = getRegistry(rift);
|
||||
RiftInfo oldRift = registry.rifts.remove(rift);
|
||||
if (oldRift == null) return;
|
||||
List<TileEntityRift> updateQueue = new ArrayList<>();
|
||||
for (Location source : oldRift.sources) {
|
||||
RiftRegistry sourceRegistry = getRegistry(source);
|
||||
sourceRegistry.rifts.get(source).destinations.remove(rift);
|
||||
sourceRegistry.markDirty();
|
||||
TileEntityRift riftEntity = (TileEntityRift) sourceRegistry.world.getTileEntity(source.getPos());
|
||||
riftEntity.destinationGone(rift);
|
||||
updateQueue.add(riftEntity);
|
||||
}
|
||||
for (Location destination : oldRift.destinations) {
|
||||
RiftRegistry destinationRegistry = getRegistry(destination);
|
||||
destinationRegistry.rifts.get(destination).sources.remove(rift);
|
||||
destinationRegistry.markDirty();
|
||||
TileEntityRift riftEntity = (TileEntityRift) destinationRegistry.world.getTileEntity(destination.getPos());
|
||||
updateQueue.add(riftEntity);
|
||||
//riftEntity.allSourcesGone(); // TODO
|
||||
}
|
||||
for (TileEntityRift riftEntity : updateQueue) {
|
||||
//riftEntity.updateColor();
|
||||
riftEntity.markDirty();
|
||||
}
|
||||
getForDim(ModDimensions.getPrivateDim()).privatePocketEntrances.entrySet().removeIf(e -> e.getValue().equals(rift));
|
||||
getForDim(0).overworldRifts.entrySet().removeIf(e -> e.getValue().equals(rift));
|
||||
registry.markDirty();
|
||||
}
|
||||
|
||||
public static void addLink(Location from, Location to) {
|
||||
DimDoors.log.info("Link added " + from + " -> " + to);
|
||||
RiftRegistry registryFrom = getRegistry(from);
|
||||
RiftRegistry registryTo = getRegistry(to);
|
||||
RiftInfo riftInfoFrom = registryFrom.rifts.computeIfAbsent(from, k -> new RiftInfo());
|
||||
RiftInfo riftInfoTo = registryTo.rifts.computeIfAbsent(to, k -> new RiftInfo());
|
||||
riftInfoFrom.destinations.add(to);
|
||||
registryFrom.markDirty();
|
||||
riftInfoTo.sources.add(from);
|
||||
registryTo.markDirty();
|
||||
if (to.getTileEntity() instanceof TileEntityRift) ((TileEntityRift) to.getTileEntity()).updateColor();
|
||||
if (from.getTileEntity() instanceof TileEntityRift) ((TileEntityRift) from.getTileEntity()).updateColor();
|
||||
}
|
||||
|
||||
public static void removeLink(Location from, Location to) {
|
||||
DimDoors.log.info("Link removed " + from + " -> " + to);
|
||||
RiftRegistry registryFrom = getRegistry(from);
|
||||
RiftRegistry registryTo = getRegistry(to);
|
||||
registryFrom.rifts.get(from).destinations.remove(to);
|
||||
registryTo.rifts.get(to).sources.remove(from);
|
||||
registryFrom.markDirty();
|
||||
registryTo.markDirty();
|
||||
if (to.getTileEntity() instanceof TileEntityRift) ((TileEntityRift) to.getTileEntity()).updateColor();
|
||||
if (from.getTileEntity() instanceof TileEntityRift) ((TileEntityRift) from.getTileEntity()).updateColor();
|
||||
}
|
||||
|
||||
public static void addAvailableLink(Location rift, AvailableLink link) { // TODO cache rifts with availableLinks
|
||||
DimDoors.log.info("AvailableLink added at " + rift);
|
||||
RiftRegistry registry = getRegistry(rift);
|
||||
registry.rifts.get(rift).availableLinks.add(link);
|
||||
registry.markDirty();
|
||||
}
|
||||
|
||||
public static void removeAvailableLink(Location rift, AvailableLink link) {
|
||||
DimDoors.log.info("AvailableLink removed at " + rift);
|
||||
RiftRegistry registry = getRegistry(rift);
|
||||
registry.rifts.get(rift).availableLinks.remove(link);
|
||||
registry.markDirty();
|
||||
}
|
||||
|
||||
public static void clearAvailableLinks(Location rift) {
|
||||
DimDoors.log.info("AvailableLink cleared at " + rift);
|
||||
RiftRegistry registry = getRegistry(rift);
|
||||
registry.rifts.get(rift).availableLinks.clear();
|
||||
registry.markDirty();
|
||||
}
|
||||
|
||||
/*
|
||||
public static void removeAvailableLinkByID(Location rift, int id) {
|
||||
DimDoors.log.info("AvailableLink with id " + id + " removed at " + rift);
|
||||
RiftRegistry registry = getRegistry(rift);
|
||||
for (AvailableLinkInfo link : registry.rifts.get(rift).availableLinks) {
|
||||
if (link.id.equals(id)) {
|
||||
removeAvailableLink(rift, link);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
public static RiftRegistry getRegistry(Location rift) {
|
||||
return getForDim(rift.getDim());
|
||||
}
|
||||
|
||||
public Location getPrivatePocketEntrance(String playerUUID) {
|
||||
Location entrance = privatePocketEntrances.get(playerUUID);
|
||||
List<Location> entrances = privatePocketEntranceLists.computeIfAbsent(playerUUID, k -> new ArrayList<>());
|
||||
while ((entrance == null || !(entrance.getTileEntity() instanceof TileEntityRift)) && entrances.size() > 0) {
|
||||
if (entrance != null) entrances.remove(entrance);
|
||||
if (entrances.size() > 0) entrance = entrances.get(0);
|
||||
}
|
||||
privatePocketEntrances.put(playerUUID, entrance);
|
||||
return entrance;
|
||||
}
|
||||
|
||||
public void addPrivatePocketEntrance(String playerUUID, Location rift) {
|
||||
DimDoors.log.info("Private pocket entrance added for " + playerUUID + " at " + rift);
|
||||
privatePocketEntranceLists.computeIfAbsent(playerUUID, k -> new ArrayList<>()).add(rift);
|
||||
}
|
||||
|
||||
public void setPrivatePocketEntrance(String playerUUID, Location rift) {
|
||||
DimDoors.log.info("Last private pocket entrance set for " + playerUUID + " at " + rift);
|
||||
privatePocketEntrances.put(playerUUID, rift);
|
||||
markDirty();
|
||||
}
|
||||
|
||||
public Location getPrivatePocketExit(String playerUUID) {
|
||||
return privatePocketExits.get(playerUUID);
|
||||
}
|
||||
|
||||
public void setPrivatePocketExit(String playerUUID, Location rift) {
|
||||
DimDoors.log.info("Last private pocket exit set for " + playerUUID + " at " + rift);
|
||||
if (rift != null) {
|
||||
privatePocketExits.put(playerUUID, rift);
|
||||
} else {
|
||||
privatePocketExits.remove(playerUUID);
|
||||
}
|
||||
markDirty();
|
||||
}
|
||||
|
||||
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 setOverworldRift(String playerUUID, Location rift) {
|
||||
DimDoors.log.info("Overworld rift set for " + playerUUID + " at " + rift);
|
||||
if (rift != null) {
|
||||
getForDim(0).overworldRifts.put(playerUUID, rift);
|
||||
} else {
|
||||
getForDim(0).overworldRifts.remove(playerUUID);
|
||||
}
|
||||
getForDim(0).markDirty();
|
||||
}
|
||||
|
||||
public static List<AvailableLink> getAvailableLinks() { // TODO: cache this
|
||||
List<AvailableLink> availableLinks = new ArrayList<>();
|
||||
for (int dim: DimensionManager.getStaticDimensionIDs()) { // TODO: don't create worlds
|
||||
RiftRegistry registry = getForDim(dim);
|
||||
for (Map.Entry<Location, RiftInfo> rift : registry.rifts.entrySet()) {
|
||||
for (AvailableLink availableLink : rift.getValue().availableLinks) {
|
||||
availableLinks.add(availableLink.withRift(rift.getKey()));
|
||||
}
|
||||
}
|
||||
}
|
||||
return availableLinks;
|
||||
}
|
||||
|
||||
// TODO: rebuildRifts() function that scans the world and rebuilds the rift regestry
|
||||
}
|
|
@ -1,22 +1,5 @@
|
|||
package org.dimdev.dimdoors.shared.rifts;
|
||||
|
||||
import org.dimdev.ddutils.nbt.NBTUtils;
|
||||
import org.dimdev.annotatednbt.Saved;
|
||||
import org.dimdev.annotatednbt.NBTSerializable;
|
||||
import org.dimdev.ddutils.RGBA;
|
||||
import org.dimdev.dimdoors.DimDoors;
|
||||
import org.dimdev.dimdoors.shared.VirtualLocation;
|
||||
import org.dimdev.dimdoors.shared.blocks.BlockDimensionalDoor;
|
||||
import org.dimdev.dimdoors.shared.blocks.BlockFloatingRift;
|
||||
import org.dimdev.dimdoors.shared.pockets.Pocket;
|
||||
import org.dimdev.dimdoors.shared.pockets.PocketRegistry;
|
||||
import org.dimdev.ddutils.EntityUtils;
|
||||
import org.dimdev.ddutils.Location;
|
||||
import org.dimdev.ddutils.math.MathUtils;
|
||||
import org.dimdev.ddutils.TeleportUtils;
|
||||
import org.dimdev.ddutils.WorldUtils;
|
||||
import org.dimdev.dimdoors.shared.rifts.destinations.*;
|
||||
import org.dimdev.dimdoors.shared.world.ModDimensions;
|
||||
import lombok.Getter;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.entity.Entity;
|
||||
|
@ -30,55 +13,53 @@ import net.minecraft.util.math.BlockPos;
|
|||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
import org.dimdev.annotatednbt.NBTSerializable;
|
||||
import org.dimdev.annotatednbt.Saved;
|
||||
import org.dimdev.ddutils.*;
|
||||
import org.dimdev.ddutils.nbt.NBTUtils;
|
||||
import org.dimdev.dimdoors.DimDoors;
|
||||
import org.dimdev.dimdoors.shared.blocks.BlockDimensionalDoor;
|
||||
import org.dimdev.dimdoors.shared.blocks.BlockFloatingRift;
|
||||
import org.dimdev.dimdoors.shared.rifts.registry.LinkProperties;
|
||||
import org.dimdev.dimdoors.shared.rifts.registry.Rift;
|
||||
import org.dimdev.dimdoors.shared.rifts.registry.RiftRegistry;
|
||||
import org.dimdev.dimdoors.shared.world.ModDimensions;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.*;
|
||||
|
||||
@NBTSerializable public abstract class TileEntityRift extends TileEntity implements ITickable { // TODO: implement ITeleportSource and ITeleportDestination
|
||||
|
||||
@Saved@Getter protected VirtualLocation virtualLocation;
|
||||
@Saved @Nonnull @Getter protected List<WeightedRiftDestination> destinations; // Not using a set because we can have duplicate destinations. Maybe use Multiset from Guava?
|
||||
@Saved @Getter protected boolean makeDestinationPermanent;
|
||||
@Saved @Getter protected boolean preserveRotation;
|
||||
@Saved @Nonnull @Getter protected RiftDestination destination;
|
||||
@Saved @Getter protected boolean relativeRotation;
|
||||
@Saved @Getter protected float yaw;
|
||||
@Saved @Getter protected float pitch;
|
||||
@Saved @Getter protected boolean alwaysDelete; // Delete the rift when an entrances rift is broken even if the state was changed or destinations link there.
|
||||
@Saved @Getter protected float chaosWeight;
|
||||
@Saved @Getter protected boolean forcedColor;
|
||||
@Saved @Getter protected RGBA color = null; // TODO: update AnnotatedNBT to be able to save these
|
||||
@Saved @Getter protected Set<AvailableLink> availableLinks;
|
||||
// TODO: option to convert to door on teleportTo?
|
||||
@Saved @Getter protected RGBA color = null;
|
||||
@Saved @Getter protected LinkProperties properties;
|
||||
|
||||
protected boolean riftStateChanged; // not saved
|
||||
|
||||
public TileEntityRift() {
|
||||
destinations = new ArrayList<>();
|
||||
makeDestinationPermanent = true;
|
||||
preserveRotation = true;
|
||||
relativeRotation = true;
|
||||
pitch = 0;
|
||||
alwaysDelete = false;
|
||||
chaosWeight = 1;
|
||||
availableLinks = new HashSet<>();
|
||||
}
|
||||
|
||||
public void copyFrom(TileEntityRift oldRift) {
|
||||
virtualLocation = oldRift.virtualLocation;
|
||||
destinations = oldRift.destinations;
|
||||
makeDestinationPermanent = oldRift.makeDestinationPermanent;
|
||||
preserveRotation = oldRift.preserveRotation;
|
||||
relativeRotation = oldRift.relativeRotation;
|
||||
yaw = oldRift.yaw;
|
||||
pitch = oldRift.pitch;
|
||||
chaosWeight = oldRift.chaosWeight;
|
||||
properties = oldRift.properties;
|
||||
if (oldRift.isFloating() != isFloating()) updateType();
|
||||
|
||||
markDirty();
|
||||
}
|
||||
|
||||
// NBT
|
||||
@Override public void readFromNBT(NBTTagCompound nbt) { super.readFromNBT(nbt); NBTUtils.readFromNBT(this, nbt); }
|
||||
@Override public NBTTagCompound writeToNBT(NBTTagCompound nbt) {
|
||||
nbt = super.writeToNBT(nbt);
|
||||
return NBTUtils.writeToNBT(this, nbt);
|
||||
}
|
||||
|
||||
@Override public NBTTagCompound writeToNBT(NBTTagCompound nbt) { nbt = super.writeToNBT(nbt); return NBTUtils.writeToNBT(this, nbt); }
|
||||
|
||||
@Override
|
||||
public NBTTagCompound getUpdateTag() {
|
||||
|
@ -101,6 +82,7 @@ import java.util.*;
|
|||
deserializeNBT(pkt.getNbtCompound());
|
||||
}
|
||||
|
||||
// Tile entity properties
|
||||
|
||||
// Use vanilla behavior of refreshing only when block changes, not state (otherwise, opening the door would destroy the tile entity)
|
||||
@Override
|
||||
|
@ -108,71 +90,30 @@ import java.util.*;
|
|||
// newState is not accurate if we change the state during onBlockBreak
|
||||
newSate = world.getBlockState(pos);
|
||||
return oldState.getBlock() != newSate.getBlock() &&
|
||||
!(oldState.getBlock() instanceof BlockDimensionalDoor
|
||||
&& newSate.getBlock() instanceof BlockFloatingRift);
|
||||
!(oldState.getBlock() instanceof BlockDimensionalDoor
|
||||
&& newSate.getBlock() instanceof BlockFloatingRift);
|
||||
}
|
||||
|
||||
// Modification functions
|
||||
public void setVirtualLocation(VirtualLocation virtualLocation) {
|
||||
this.virtualLocation = virtualLocation;
|
||||
updateType();
|
||||
// TODO: update available link virtual locations
|
||||
markDirty();
|
||||
}
|
||||
|
||||
public void setRotation(float yaw, float pitch) {
|
||||
this.yaw = yaw;
|
||||
this.pitch = pitch;
|
||||
preserveRotation = false;
|
||||
markDirty();
|
||||
}
|
||||
|
||||
public void clearRotation() {
|
||||
preserveRotation = true;
|
||||
}
|
||||
|
||||
public void addWeightedDestination(WeightedRiftDestination destination) {
|
||||
destinations.add(destination);
|
||||
public void setRelativeRotation(boolean relativeRotation) {
|
||||
this.relativeRotation = relativeRotation;
|
||||
markDirty();
|
||||
}
|
||||
|
||||
public void addDestination(RiftDestination destination, float weight, int group) {
|
||||
riftStateChanged = true;
|
||||
destinations.add(new WeightedRiftDestination(destination, weight, group));
|
||||
if (isRegistered()) destination.register(this);
|
||||
markDirty();
|
||||
}
|
||||
|
||||
public void addDestination(RiftDestination destination, float weight, int group, RiftDestination oldDestination) {
|
||||
riftStateChanged = true;
|
||||
destinations.add(new WeightedRiftDestination(destination, weight, group, oldDestination));
|
||||
if (isRegistered()) destination.register(this);
|
||||
markDirty();
|
||||
}
|
||||
|
||||
public void removeDestination(WeightedRiftDestination dest) {
|
||||
riftStateChanged = true;
|
||||
destinations.remove(dest);
|
||||
if (isRegistered()) dest.getDestination().unregister(this);
|
||||
markDirty();
|
||||
}
|
||||
|
||||
public void clearDestinations() {
|
||||
if (isRegistered()) for (WeightedRiftDestination wdest : destinations) {
|
||||
wdest.getDestination().unregister(this);
|
||||
public void setDestination(RiftDestination destination) {
|
||||
if (this.destination != null) {
|
||||
this.destination.unregister(new Location(world, pos));
|
||||
}
|
||||
destinations.clear();
|
||||
markDirty();
|
||||
}
|
||||
|
||||
public void setSingleDestination(RiftDestination destination) {
|
||||
clearDestinations();
|
||||
addDestination(destination, 1, 0);
|
||||
}
|
||||
|
||||
public void setChaosWeight(float chaosWeight) {
|
||||
this.chaosWeight = chaosWeight;
|
||||
this.destination = destination;
|
||||
markDirty();
|
||||
updateColor();
|
||||
}
|
||||
|
||||
public void setColor(RGBA color) {
|
||||
|
@ -181,15 +122,9 @@ import java.util.*;
|
|||
markDirty();
|
||||
}
|
||||
|
||||
public void registerAvailableLink(AvailableLink link) {
|
||||
if (!isRegistered()) return;
|
||||
RiftRegistry.addAvailableLink(getLocation(), link);
|
||||
}
|
||||
|
||||
public void addAvailableLink(AvailableLink link) {
|
||||
availableLinks.add(link);
|
||||
link.rift = getLocation();
|
||||
registerAvailableLink(link);
|
||||
public void setProperties(LinkProperties properties) {
|
||||
this.properties = properties;
|
||||
updateProperties();
|
||||
markDirty();
|
||||
}
|
||||
|
||||
|
@ -198,107 +133,65 @@ import java.util.*;
|
|||
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);
|
||||
}
|
||||
removeDestination(weightedDestination);
|
||||
addDestination(newDest, weightedDestination.getWeight(), weightedDestination.getGroup(), weightedDestination.getDestination());
|
||||
markDirty();
|
||||
}
|
||||
// Registry TODO: merge most of these into one single updateRegistry() method
|
||||
|
||||
// Registry
|
||||
public boolean isRegistered() {
|
||||
return world != null && RiftRegistry.getRiftInfo(new Location(world, pos)) != null;
|
||||
return RiftRegistry.instance().isRiftAt(new Location(world, pos));
|
||||
}
|
||||
|
||||
public void register() {
|
||||
if (isRegistered()) return;
|
||||
Location loc = new Location(world, pos);
|
||||
RiftRegistry.addRift(loc);
|
||||
RiftRegistry.getRiftInfo(loc).virtualLocation = virtualLocation;
|
||||
for (WeightedRiftDestination weightedDest : destinations) {
|
||||
weightedDest.getDestination().register(this);
|
||||
}
|
||||
for (AvailableLink link : availableLinks) {
|
||||
registerAvailableLink(link);
|
||||
}
|
||||
RiftRegistry.instance().addRift(loc);
|
||||
destination.register(new Location(world, pos));
|
||||
updateProperties();
|
||||
updateColor();
|
||||
}
|
||||
|
||||
public void updateProperties() {
|
||||
if (isRegistered()) RiftRegistry.instance().setProperties(new Location(world, pos), properties);
|
||||
markDirty();
|
||||
}
|
||||
|
||||
public void unregister() {
|
||||
if (!isRegistered()) return;
|
||||
RiftRegistry.removeRift(new Location(world, pos)); // TODO: unregister destinations
|
||||
if (ModDimensions.isDimDoorsPocketDimension(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();
|
||||
}
|
||||
if (isRegistered()) {
|
||||
RiftRegistry.instance().removeRift(new Location(world, pos));
|
||||
}
|
||||
// TODO: inform pocket that entrances was destroyed (we'll probably need an isPrivate field on the pocket)
|
||||
}
|
||||
|
||||
public void updateType() {
|
||||
if (!isRegistered()) return;
|
||||
RiftRegistry.getRiftInfo(getLocation()).isEntrance = !isFloating();
|
||||
RiftRegistry.getForDim(getLocation().getDim()).markDirty();
|
||||
Rift rift = RiftRegistry.instance().getRift(new Location(world, pos));
|
||||
rift.isFloating = isFloating();
|
||||
rift.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(dest.getReferencedRift(getLocation()))) {
|
||||
wdestIterator.remove(); // TODO: unregister*
|
||||
RiftDestination oldDest = wdest.getOldDestination();
|
||||
if (oldDest != null) {
|
||||
wdestIterator.add(new WeightedRiftDestination(oldDest, wdest.getWeight(), wdest.getGroup()));
|
||||
if (isRegistered()) oldDest.register(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
destinations.removeIf(weightedRiftDestination -> loc.equals(weightedRiftDestination.getDestination().getReferencedRift(getLocation())));
|
||||
markDirty();
|
||||
public void targetGone(Location loc) {
|
||||
if (!destination.keepAfterTargetGone(loc)) setDestination(null);
|
||||
updateColor();
|
||||
}
|
||||
|
||||
public void sourceGone(Location loc) {
|
||||
updateColor();
|
||||
}
|
||||
|
||||
// Teleport logic
|
||||
public boolean teleport(Entity entity) {
|
||||
riftStateChanged = false;
|
||||
|
||||
// Check that the rift has destinations
|
||||
if (destinations.size() == 0) {
|
||||
DimDoors.chat(entity, "This rift has no destinations!");
|
||||
// Check that the rift has as destination
|
||||
if (destination == null) {
|
||||
DimDoors.chat(entity, "This rift has no destination!");
|
||||
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: What about player-owned entities? We should store their exit rift separately to avoid having problems if they enter different rifts
|
||||
// TODO: use entity UUID rather than player UUID!
|
||||
if (entity instanceof EntityPlayer && !ModDimensions.isDimDoorsPocketDimension(WorldUtils.getDim(world))) {
|
||||
RiftRegistry.setOverworldRift(EntityUtils.getEntityOwnerUUID(entity), new Location(world, pos));
|
||||
if (destination.teleport(new RotatedLocation(new Location(world, pos), yaw, pitch), entity)) {
|
||||
// Set last used rift for players (don't set for other entities to avoid filling the registry too much)
|
||||
// TODO: it should maybe be set for some non-player entities too
|
||||
if (!ModDimensions.isDimDoorsPocketDimension(WorldUtils.getDim(world)) && entity instanceof EntityPlayer) {
|
||||
RiftRegistry.instance().setOverworldRift(entity.getUniqueID(), new Location(world, pos));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -309,45 +202,30 @@ import java.util.*;
|
|||
return false;
|
||||
}
|
||||
|
||||
public void teleportTo(Entity entity) { // TODO: new velocity angle if !preserveRotation?
|
||||
float newYaw = entity.rotationYaw;
|
||||
float newPitch = entity.rotationYaw;
|
||||
if (!preserveRotation) {
|
||||
newYaw = yaw;
|
||||
newPitch = pitch;
|
||||
public void teleportTo(Entity entity, float fromYaw, float fromPitch) {
|
||||
if (relativeRotation) {
|
||||
TeleportUtils.teleport(entity, new Location(world, pos), yaw + entity.rotationYaw - fromYaw, pitch + entity.rotationPitch - fromPitch);
|
||||
} else {
|
||||
TeleportUtils.teleport(entity, new Location(world, pos), yaw, pitch);
|
||||
}
|
||||
TeleportUtils.teleport(entity, new Location(world, pos), newYaw, newPitch);
|
||||
}
|
||||
|
||||
public void updateColor() { // TODO: have the registry call this method too
|
||||
public void teleportTo(Entity entity) {
|
||||
TeleportUtils.teleport(entity, new Location(world, pos), yaw, pitch);
|
||||
}
|
||||
|
||||
public void updateColor() {
|
||||
if (forcedColor) return;
|
||||
if (!isRegistered()) {
|
||||
color = new RGBA(0, 0, 0, 1);
|
||||
return;
|
||||
}
|
||||
if (destinations.size() == 0) {
|
||||
} else if (destination == null) {
|
||||
color = new RGBA(0.7f, 0.7f, 0.7f, 1);
|
||||
return;
|
||||
}
|
||||
boolean safe = true;
|
||||
for (WeightedRiftDestination weightedDestination : destinations) {
|
||||
boolean destSafe = false;
|
||||
RiftDestination destination = weightedDestination.getDestination();
|
||||
if (destination instanceof PrivateDestination
|
||||
|| destination instanceof PocketExitDestination
|
||||
|| destination instanceof PrivatePocketExitDestination) destSafe = true;
|
||||
|
||||
if (!destSafe && destination.getReferencedRift(getLocation()) != null) {
|
||||
RiftRegistry.RiftInfo riftInfo = RiftRegistry.getRiftInfo(destination.getReferencedRift(getLocation()));
|
||||
destSafe = riftInfo != null
|
||||
&& riftInfo.destinations.size() == 1
|
||||
&& riftInfo.destinations.iterator().next().equals(getLocation());
|
||||
}
|
||||
safe &= destSafe;
|
||||
}
|
||||
if (safe) {
|
||||
color = new RGBA(0, 1, 0, 1);
|
||||
} else {
|
||||
color = new RGBA(1, 0, 0, 1);
|
||||
RGBA newColor = destination.getColor(new Location(world, pos));
|
||||
if (!color.equals(newColor)) {
|
||||
color = newColor;
|
||||
markDirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -358,25 +236,5 @@ import java.util.*;
|
|||
}
|
||||
|
||||
// Info
|
||||
protected abstract boolean isFloating(); // TODO: make non-abstract?
|
||||
|
||||
public Location getLocation() {
|
||||
return new Location(world, pos);
|
||||
}
|
||||
|
||||
public WeightedRiftDestination getDestination(UUID id) {
|
||||
for (WeightedRiftDestination wdest : destinations) {
|
||||
if (wdest.getId().equals(id)) {
|
||||
return wdest;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public AvailableLink getAvailableLink(UUID linkId) {
|
||||
for (AvailableLink link : availableLinks) {
|
||||
if (link.id.equals(linkId)) return link;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
protected abstract boolean isFloating();
|
||||
}
|
||||
|
|
|
@ -1,58 +0,0 @@
|
|||
package org.dimdev.dimdoors.shared.rifts;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.dimdev.ddutils.nbt.INBTStorable;
|
||||
import lombok.Getter;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
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?
|
||||
@Getter private UUID id;
|
||||
|
||||
public WeightedRiftDestination() {
|
||||
id = UUID.randomUUID();
|
||||
}
|
||||
|
||||
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, RiftDestination oldDestination, UUID id) {
|
||||
this(destination, weight, group, oldDestination);
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
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
|
||||
public NBTTagCompound writeToNBT(NBTTagCompound nbt) {
|
||||
nbt = destination.writeToNBT(nbt);
|
||||
nbt.setFloat("weight", weight);
|
||||
nbt.setInteger("group", group);
|
||||
if (oldDestination != null) nbt.setTag("oldDestination", oldDestination.writeToNBT(new NBTTagCompound()));
|
||||
return nbt;
|
||||
}
|
||||
}
|
|
@ -11,6 +11,8 @@ import net.minecraft.util.math.BlockPos;
|
|||
import net.minecraft.world.World;
|
||||
import org.dimdev.annotatednbt.NBTSerializable;
|
||||
import org.dimdev.annotatednbt.Saved;
|
||||
import org.dimdev.ddutils.Location;
|
||||
import org.dimdev.ddutils.RotatedLocation;
|
||||
import org.dimdev.ddutils.WorldUtils;
|
||||
import org.dimdev.ddutils.math.MathUtils;
|
||||
import org.dimdev.ddutils.nbt.NBTUtils;
|
||||
|
@ -18,10 +20,10 @@ import org.dimdev.dimdoors.shared.VirtualLocation;
|
|||
import org.dimdev.dimdoors.shared.blocks.ModBlocks;
|
||||
import org.dimdev.dimdoors.shared.pockets.Pocket;
|
||||
import org.dimdev.dimdoors.shared.pockets.PocketGenerator;
|
||||
import org.dimdev.dimdoors.shared.rifts.AvailableLink;
|
||||
import org.dimdev.dimdoors.shared.rifts.RiftDestination;
|
||||
import org.dimdev.dimdoors.shared.rifts.RiftRegistry;
|
||||
import org.dimdev.dimdoors.shared.rifts.TileEntityRift;
|
||||
import org.dimdev.dimdoors.shared.rifts.*;
|
||||
import org.dimdev.dimdoors.shared.rifts.registry.LinkProperties;
|
||||
import org.dimdev.dimdoors.shared.rifts.registry.Rift;
|
||||
import org.dimdev.dimdoors.shared.rifts.registry.RiftRegistry;
|
||||
import org.dimdev.dimdoors.shared.tileentities.TileEntityFloatingRift;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
@ -30,7 +32,7 @@ import java.util.Set;
|
|||
import java.util.UUID;
|
||||
|
||||
@Getter @AllArgsConstructor @Builder(toBuilder = true) @ToString
|
||||
@NBTSerializable public class AvailableLinkDestination extends RiftDestination { // TODO: increase link count on unregister
|
||||
@NBTSerializable public class AvailableLinkDestination extends RiftDestination {
|
||||
@Saved protected float newRiftWeight;
|
||||
@Saved protected double weightMaximum;
|
||||
@Saved protected double coordFactor;
|
||||
|
@ -39,7 +41,7 @@ import java.util.UUID;
|
|||
@Saved protected Set<Integer> acceptedGroups; // TODO: this should be immutable
|
||||
@Saved protected boolean noLink;
|
||||
@Builder.Default @Saved protected boolean noLinkBack;
|
||||
@Builder.Default @Saved protected UUID linkId = UUID.randomUUID();
|
||||
// TODO: better depth calculation
|
||||
|
||||
public AvailableLinkDestination() {}
|
||||
|
||||
|
@ -47,25 +49,23 @@ import java.util.UUID;
|
|||
@Override public NBTTagCompound writeToNBT(NBTTagCompound nbt) { nbt = super.writeToNBT(nbt); return NBTUtils.writeToNBT(this, nbt); }
|
||||
|
||||
@Override
|
||||
public boolean teleport(TileEntityRift rift, Entity entity) {
|
||||
if (rift.getVirtualLocation() == null) return false;
|
||||
AvailableLink thisLink = rift.getAvailableLink(linkId);
|
||||
thisLink.linksRemaining--;
|
||||
RiftRegistry.getRegistry(rift.getLocation()).markDirty();
|
||||
Map<AvailableLink, Float> possibleDestWeightMap = new HashMap<>();
|
||||
if (newRiftWeight > 0) possibleDestWeightMap.put(null, newRiftWeight);
|
||||
public boolean teleport(RotatedLocation location, Entity entity) {
|
||||
VirtualLocation virtualLocationHere = VirtualLocation.fromLocation(location.getLocation());
|
||||
|
||||
for (AvailableLink link : RiftRegistry.getAvailableLinks()) {
|
||||
RiftRegistry.RiftInfo otherRift = RiftRegistry.getRiftInfo(link.rift);
|
||||
double otherWeight = otherRift.isEntrance ? link.entranceWeight : link.floatingWeight;
|
||||
if (otherWeight == 0 || Sets.intersection(acceptedGroups, link.groups).isEmpty()) continue;
|
||||
Map<Location, Float> riftWeights = new HashMap<>();
|
||||
if (newRiftWeight > 0) riftWeights.put(null, newRiftWeight);
|
||||
|
||||
for (Rift otherRift : RiftRegistry.instance().getRifts()) {
|
||||
VirtualLocation otherVirtualLocation = VirtualLocation.fromLocation(otherRift.location);
|
||||
double otherWeight = otherRift.isFloating ? otherRift.properties.floatingWeight : otherRift.properties.entranceWeight;
|
||||
if (otherWeight == 0 || Sets.intersection(acceptedGroups, otherRift.properties.groups).isEmpty()) continue;
|
||||
|
||||
// Calculate the distance as sqrt((coordFactor * coordDistance)^2 + (depthFactor * depthDifference)^2)
|
||||
if (otherRift.virtualLocation == null || link.linksRemaining == 0) continue;
|
||||
double depthDifference = otherRift.virtualLocation.getDepth() - rift.getVirtualLocation().getDepth();
|
||||
double coordDistance = Math.sqrt(sq(rift.getVirtualLocation().getX() - otherRift.virtualLocation.getX())
|
||||
+ sq(rift.getVirtualLocation().getZ() - otherRift.virtualLocation.getZ()));
|
||||
double depthFactor = depthDifference > 0 ? positiveDepthFactor : negativeDepthFactor; // TODO: (|depthDiff| - depthFavor * depthDiff)?
|
||||
if (otherVirtualLocation == null || otherRift.properties.linksRemaining == 0) continue;
|
||||
double depthDifference = otherVirtualLocation.getDepth() - virtualLocationHere.getDepth();
|
||||
double coordDistance = Math.sqrt(sq(otherVirtualLocation.getX() - virtualLocationHere.getX())
|
||||
+ sq(otherVirtualLocation.getZ() - virtualLocationHere.getZ()));
|
||||
double depthFactor = depthDifference > 0 ? positiveDepthFactor : negativeDepthFactor;
|
||||
double distance = sq(coordFactor * coordDistance) + sq(depthFactor * depthDifference);
|
||||
|
||||
// Calculate the weight as 4m/pi w/(m^2/d + d)^2. This is similar to how gravitational/electromagnetic attraction
|
||||
|
@ -77,18 +77,18 @@ import java.util.UUID;
|
|||
// of 1 is equivalent to having a total link weight of 1 distributed equally across all layers.
|
||||
// TODO: We might want an a larger than 1 to make the function closer to 1/d^2
|
||||
double weight = 4 * weightMaximum / Math.PI * otherWeight / sq(sq(weightMaximum) / distance + distance);
|
||||
possibleDestWeightMap.put(link, (float) weight);
|
||||
riftWeights.put(otherRift.location, (float) weight);
|
||||
}
|
||||
|
||||
AvailableLink selectedLink;
|
||||
if (possibleDestWeightMap.size() == 0) {
|
||||
Location selectedLink;
|
||||
if (riftWeights.size() == 0) {
|
||||
if (newRiftWeight == -1) {
|
||||
selectedLink = null;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
selectedLink = MathUtils.weightedRandom(possibleDestWeightMap);
|
||||
selectedLink = MathUtils.weightedRandom(riftWeights);
|
||||
}
|
||||
|
||||
// Check if we have to generate a new rift
|
||||
|
@ -121,10 +121,10 @@ import java.util.UUID;
|
|||
depth /= depth > 0 ? positiveDepthFactor : negativeDepthFactor;
|
||||
double x = Math.cos(theta) * Math.cos(phi) * distance / coordFactor;
|
||||
double z = Math.cos(theta) * Math.sin(phi) * distance / coordFactor;
|
||||
VirtualLocation virtualLocation = new VirtualLocation(rift.getVirtualLocation().getDim(),
|
||||
rift.getVirtualLocation().getX() + (int) Math.round(x),
|
||||
rift.getVirtualLocation().getZ() + (int) Math.round(z),
|
||||
rift.getVirtualLocation().getDepth() + (int) Math.round(depth));
|
||||
VirtualLocation virtualLocation = new VirtualLocation(virtualLocationHere.getDim(),
|
||||
virtualLocationHere.getX() + (int) Math.round(x),
|
||||
virtualLocationHere.getZ() + (int) Math.round(z),
|
||||
virtualLocationHere.getDepth() + (int) Math.round(depth));
|
||||
|
||||
if (virtualLocation.getDepth() <= 0) {
|
||||
// This will lead to the overworld
|
||||
|
@ -132,43 +132,51 @@ import java.util.UUID;
|
|||
BlockPos pos = world.getTopSolidOrLiquidBlock(new BlockPos(virtualLocation.getX(), 0, virtualLocation.getZ()));
|
||||
world.setBlockState(pos, ModBlocks.RIFT.getDefaultState());
|
||||
|
||||
TileEntityRift thisRift = (TileEntityRift) location.getLocation().getTileEntity();
|
||||
TileEntityFloatingRift riftEntity = (TileEntityFloatingRift) world.getTileEntity(pos);
|
||||
// TODO: Should the rift not be configured like the other link
|
||||
rift.markDirty();
|
||||
AvailableLink newLink = thisLink.toBuilder().linksRemaining(0).id(UUID.randomUUID()).build();
|
||||
riftEntity.addAvailableLink(newLink);
|
||||
if (!noLinkBack) riftEntity.addDestination(new GlobalDestination(rift.getLocation()), 1, 0, toBuilder().linkId(newLink.id).build());
|
||||
if (!noLink) rift.makeDestinationPermanent(weightedDestination, riftEntity.getLocation());
|
||||
riftEntity.teleportTo(entity);
|
||||
riftEntity.setProperties(thisRift.getProperties().toBuilder().linksRemaining(1).id(UUID.randomUUID()).build());
|
||||
|
||||
if (!noLinkBack && !riftEntity.getProperties().oneWay) linkRifts(selectedLink, location.getLocation());
|
||||
if (!noLink) linkRifts(location.getLocation(), selectedLink);
|
||||
riftEntity.teleportTo(entity, thisRift.getYaw(), thisRift.getPitch());
|
||||
} else {
|
||||
// Make a new dungeon pocket
|
||||
//Pocket pocket = PocketGenerator.generateDungeonPocket(virtualLocation);
|
||||
Pocket pocket = PocketGenerator.generatePublicPocket(virtualLocation);
|
||||
pocket.setup();
|
||||
rift.markDirty();
|
||||
AvailableLink newLink = thisLink.toBuilder().linksRemaining(0).build();
|
||||
pocket.linkPocketTo(new GlobalDestination(/*noLinkBack ? null :*/ rift.getLocation()), toBuilder().linkId(newLink.id).build(), newLink); // TODO: linkId
|
||||
if (!noLink) rift.makeDestinationPermanent(weightedDestination, pocket.getEntrance());
|
||||
((TileEntityRift) pocket.getEntrance().getTileEntity()).teleportTo(entity);
|
||||
|
||||
// Link the pocket back
|
||||
TileEntityRift thisRift = (TileEntityRift) location.getLocation().getTileEntity();
|
||||
TileEntityRift riftEntity = (TileEntityRift) pocket.getEntrance().getTileEntity();
|
||||
LinkProperties newLink = thisRift.getProperties().toBuilder().linksRemaining(0).id(UUID.randomUUID()).build();
|
||||
pocket.linkPocketTo(new GlobalDestination(!noLinkBack && !riftEntity.getProperties().oneWay ? location.getLocation() : null), newLink); // TODO: linkId
|
||||
|
||||
// Link the rift if necessary and teleport the entity
|
||||
if (!noLink) linkRifts(location.getLocation(), selectedLink);
|
||||
((TileEntityRift) pocket.getEntrance().getTileEntity()).teleportTo(entity, location.getYaw(), location.getPitch());
|
||||
}
|
||||
} else {
|
||||
// An existing rift was selected
|
||||
TileEntityRift riftEntity = (TileEntityRift) selectedLink.rift.getTileEntity();
|
||||
TileEntityRift riftEntity = (TileEntityRift) selectedLink.getTileEntity();
|
||||
|
||||
selectedLink.linksRemaining--;
|
||||
RiftRegistry.getRegistry(riftEntity.getLocation()).markDirty();
|
||||
|
||||
// Link the selected rift back if necessary
|
||||
if (selectedLink.replaceDestination != null) {
|
||||
riftEntity.makeDestinationPermanent(riftEntity.getDestination(selectedLink.replaceDestination), rift.getLocation());
|
||||
}
|
||||
|
||||
// Link this rift if necessary and teleport the entity
|
||||
if (!noLink) rift.makeDestinationPermanent(weightedDestination, selectedLink.rift);
|
||||
riftEntity.teleportTo(entity);
|
||||
// Link the rifts if necessary and teleport the entity
|
||||
if (!noLink) linkRifts(location.getLocation(), selectedLink);
|
||||
if (!noLinkBack && !riftEntity.getProperties().oneWay) linkRifts(selectedLink, location.getLocation());
|
||||
riftEntity.teleportTo(entity, location.getYaw(), location.getPitch());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void linkRifts(Location from, Location to) {
|
||||
TileEntityRift tileEntityFrom = (TileEntityRift) from.getTileEntity();
|
||||
TileEntityRift tileEntityTo = (TileEntityRift) to.getTileEntity();
|
||||
tileEntityFrom.setDestination(new GlobalDestination(to)); // TODO: local if possible
|
||||
tileEntityTo.getProperties().linksRemaining--;
|
||||
tileEntityTo.updateProperties();
|
||||
tileEntityFrom.markDirty();
|
||||
tileEntityTo.markDirty();
|
||||
}
|
||||
|
||||
private double sq(double a) { return a * a; }
|
||||
}
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
package org.dimdev.dimdoors.shared.rifts.destinations;
|
||||
|
||||
import org.dimdev.ddutils.RotatedLocation;
|
||||
import org.dimdev.dimdoors.DimDoors;
|
||||
import org.dimdev.dimdoors.shared.rifts.RiftDestination;
|
||||
import org.dimdev.dimdoors.shared.rifts.RiftRegistry;
|
||||
import org.dimdev.dimdoors.shared.rifts.registry.RiftRegistry;
|
||||
import org.dimdev.dimdoors.shared.rifts.TileEntityRift;
|
||||
import org.dimdev.dimdoors.shared.world.ModDimensions;
|
||||
import org.dimdev.dimdoors.shared.world.limbodimension.WorldProviderLimbo;
|
||||
|
@ -15,6 +16,8 @@ import lombok.ToString;
|
|||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@Getter @AllArgsConstructor @Builder(toBuilder = true) @ToString
|
||||
public class EscapeDestination extends RiftDestination {
|
||||
//public EscapeDestination() {}
|
||||
|
@ -31,14 +34,14 @@ public class EscapeDestination extends RiftDestination {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean teleport(TileEntityRift rift, Entity entity) {
|
||||
public boolean teleport(RotatedLocation loc, Entity entity) {
|
||||
if (!ModDimensions.isDimDoorsPocketDimension(entity.world)) {
|
||||
DimDoors.chat(entity, "Can't escape from a non-pocket dimension!");
|
||||
return false;
|
||||
}
|
||||
String uuid = entity.getCachedUniqueIdString();
|
||||
UUID uuid = entity.getUniqueID();
|
||||
if (uuid != null) {
|
||||
Location destLoc = RiftRegistry.getOverworldRift(uuid);
|
||||
Location destLoc = RiftRegistry.instance().getOverworldRift(uuid);
|
||||
if (destLoc != null && destLoc.getTileEntity() instanceof TileEntityRift) {
|
||||
//TeleportUtils.teleport(entity, new VirtualLocation(destLoc, rift.virtualLocation.getDepth()).projectToWorld()); // TODO
|
||||
// TODO
|
||||
|
|
|
@ -7,6 +7,7 @@ import lombok.Getter;
|
|||
import lombok.ToString;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import org.dimdev.ddutils.RotatedLocation;
|
||||
import org.dimdev.ddutils.nbt.NBTUtils;
|
||||
import org.dimdev.annotatednbt.Saved;
|
||||
import org.dimdev.annotatednbt.NBTSerializable;
|
||||
|
@ -15,7 +16,7 @@ import org.dimdev.dimdoors.shared.rifts.TileEntityRift;
|
|||
|
||||
@Getter @AllArgsConstructor @Builder(toBuilder = true) @ToString
|
||||
@NBTSerializable public class GlobalDestination extends RiftDestination { // TODO: location directly in nbt like minecraft?
|
||||
@Saved @Getter protected Location loc;
|
||||
@Saved protected Location loc;
|
||||
|
||||
public GlobalDestination() {}
|
||||
|
||||
|
@ -23,13 +24,13 @@ import org.dimdev.dimdoors.shared.rifts.TileEntityRift;
|
|||
@Override public NBTTagCompound writeToNBT(NBTTagCompound nbt) { nbt = super.writeToNBT(nbt); return NBTUtils.writeToNBT(this, nbt); }
|
||||
|
||||
@Override
|
||||
public boolean teleport(TileEntityRift rift, Entity entity) {
|
||||
((TileEntityRift) loc.getTileEntity()).teleportTo(entity);
|
||||
public boolean teleport(RotatedLocation loc, Entity entity) {
|
||||
((TileEntityRift) this.loc.getTileEntity()).teleportTo(entity, loc.getYaw(), loc.getPitch());
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location getReferencedRift(Location rift) {
|
||||
public Location getFixedTarget(Location location) {
|
||||
return loc;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package org.dimdev.dimdoors.shared.rifts.destinations;
|
||||
|
||||
import org.dimdev.ddutils.RotatedLocation;
|
||||
import org.dimdev.dimdoors.shared.rifts.RiftDestination;
|
||||
import org.dimdev.dimdoors.shared.rifts.TileEntityRift;
|
||||
import org.dimdev.dimdoors.shared.world.limbodimension.WorldProviderLimbo;
|
||||
import org.dimdev.ddutils.TeleportUtils;
|
||||
import lombok.AllArgsConstructor;
|
||||
|
@ -27,7 +27,7 @@ public class LimboDestination extends RiftDestination {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean teleport(TileEntityRift rift, Entity entity) {
|
||||
public boolean teleport(RotatedLocation loc, Entity entity) {
|
||||
TeleportUtils.teleport(entity, WorldProviderLimbo.getLimboSkySpawn(entity)); // TODO: do we really want to spam Limbo with items?
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
package org.dimdev.dimdoors.shared.rifts.destinations;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import org.dimdev.ddutils.Location;
|
||||
import org.dimdev.ddutils.RGBA;
|
||||
import org.dimdev.ddutils.RotatedLocation;
|
||||
import org.dimdev.dimdoors.shared.rifts.RiftDestination;
|
||||
|
||||
public abstract class LinkingDestination extends RiftDestination {
|
||||
|
||||
private RiftDestination wrappedDestination;
|
||||
|
||||
@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(RotatedLocation loc, Entity entity) {
|
||||
if (wrappedDestination != null) wrappedDestination.teleport(loc, entity);
|
||||
|
||||
Location linkTarget = makeLinkTarget(loc, entity);
|
||||
if (linkTarget != null) {
|
||||
wrappedDestination = new GlobalDestination();
|
||||
wrappedDestination.register(loc.getLocation());
|
||||
|
||||
wrappedDestination.teleport(loc, entity);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean keepAfterTargetGone(Location location) {
|
||||
if (!wrappedDestination.keepAfterTargetGone(location)) {
|
||||
wrappedDestination.unregister(location);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregister(Location location) {
|
||||
if (wrappedDestination != null) wrappedDestination.unregister(location);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RGBA getColor(Location location) {
|
||||
if (wrappedDestination != null) {
|
||||
return wrappedDestination.getColor(location);
|
||||
} else {
|
||||
return getUnlinkedColor(location);
|
||||
}
|
||||
}
|
||||
|
||||
protected RGBA getUnlinkedColor(Location location) {
|
||||
return new RGBA(0, 1, 1, 1);
|
||||
}
|
||||
|
||||
public abstract Location makeLinkTarget(RotatedLocation rift, Entity entity);
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package org.dimdev.dimdoors.shared.rifts.destinations;
|
||||
|
||||
import org.dimdev.ddutils.Location;
|
||||
import org.dimdev.ddutils.RotatedLocation;
|
||||
import org.dimdev.ddutils.nbt.NBTUtils;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
|
@ -24,13 +25,13 @@ import org.dimdev.dimdoors.shared.rifts.TileEntityRift;
|
|||
@Override public NBTTagCompound writeToNBT(NBTTagCompound nbt) { nbt = super.writeToNBT(nbt); return NBTUtils.writeToNBT(this, nbt); }
|
||||
|
||||
@Override
|
||||
public boolean teleport(TileEntityRift rift, Entity entity) {
|
||||
((TileEntityRift) rift.getWorld().getTileEntity(pos)).teleportTo(entity);
|
||||
public boolean teleport(RotatedLocation loc, Entity entity) {
|
||||
((TileEntityRift) loc.getLocation().getWorld().getTileEntity(pos)).teleportTo(entity, loc.getYaw(), loc.getPitch());
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location getReferencedRift(Location rift) {
|
||||
return new Location(rift.getDim(), pos);
|
||||
public Location getFixedTarget(Location location) {
|
||||
return new Location(location.getDim(), pos);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,45 +0,0 @@
|
|||
package org.dimdev.dimdoors.shared.rifts.destinations;
|
||||
|
||||
import org.dimdev.dimdoors.shared.VirtualLocation;
|
||||
import org.dimdev.dimdoors.shared.pockets.Pocket;
|
||||
import org.dimdev.dimdoors.shared.pockets.PocketGenerator;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.ToString;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import org.dimdev.dimdoors.shared.rifts.RiftDestination;
|
||||
import org.dimdev.dimdoors.shared.rifts.TileEntityRift;
|
||||
|
||||
@Getter @AllArgsConstructor @Builder(toBuilder = true) @ToString
|
||||
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) {
|
||||
VirtualLocation newVirtualLocation = null;
|
||||
if (rift.getVirtualLocation() != null) {
|
||||
int depth = rift.getVirtualLocation().getDepth();
|
||||
if (depth == 0) depth++;
|
||||
newVirtualLocation = rift.getVirtualLocation().toBuilder().depth(depth).build();
|
||||
}
|
||||
Pocket pocket = PocketGenerator.generatePublicPocket(newVirtualLocation);
|
||||
pocket.setup();
|
||||
pocket.linkPocketTo(new GlobalDestination(rift.getLocation()), null, null);
|
||||
rift.makeDestinationPermanent(weightedDestination, pocket.getEntrance());
|
||||
((TileEntityRift) pocket.getEntrance().getTileEntity()).teleportTo(entity);
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
package org.dimdev.dimdoors.shared.rifts.destinations;
|
||||
|
||||
import org.dimdev.ddutils.RotatedLocation;
|
||||
import org.dimdev.ddutils.nbt.NBTUtils;
|
||||
import org.dimdev.annotatednbt.Saved;
|
||||
import org.dimdev.annotatednbt.NBTSerializable;
|
||||
|
@ -12,17 +13,13 @@ import net.minecraft.entity.Entity;
|
|||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import org.dimdev.dimdoors.shared.rifts.RiftDestination;
|
||||
import org.dimdev.dimdoors.shared.rifts.TileEntityRift;
|
||||
import org.dimdev.dimdoors.shared.rifts.WeightedRiftDestination;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
@Getter @AllArgsConstructor @Builder(toBuilder = true) @ToString
|
||||
@NBTSerializable public class PocketEntranceDestination extends RiftDestination {
|
||||
@Saved protected float weight;
|
||||
@Saved @SuppressWarnings({"UnusedAssignment", "RedundantSuppression"}) @Builder.Default protected List<WeightedRiftDestination> ifDestinations = new LinkedList<>(); // TODO addIfDestination method in builder
|
||||
@Saved @SuppressWarnings({"UnusedAssignment", "RedundantSuppression"}) @Builder.Default protected List<WeightedRiftDestination> otherwiseDestinations = new LinkedList<>(); // TODO addOtherwiseDestination method in builder
|
||||
@NBTSerializable public class PocketEntranceDestination extends RiftDestination { // TODO: not exactly a destination
|
||||
@Builder.Default @Saved protected float weight = 1;
|
||||
@Saved protected RiftDestination ifDestination;
|
||||
@Saved protected RiftDestination otherwiseDestination;
|
||||
@Saved boolean hasBeenChosen;
|
||||
|
||||
public PocketEntranceDestination() {}
|
||||
|
||||
|
@ -30,7 +27,7 @@ import java.util.List;
|
|||
@Override public NBTTagCompound writeToNBT(NBTTagCompound nbt) { nbt = super.writeToNBT(nbt); return NBTUtils.writeToNBT(this, nbt); }
|
||||
|
||||
@Override
|
||||
public boolean teleport(TileEntityRift rift, Entity entity) {
|
||||
public boolean teleport(RotatedLocation loc, Entity entity) {
|
||||
if (entity instanceof EntityPlayer) DimDoors.chat(entity, "The entrances of this dungeon has not been linked. Either this is a bug or you are in dungeon-building mode.");
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package org.dimdev.dimdoors.shared.rifts.destinations;
|
||||
|
||||
import org.dimdev.ddutils.RotatedLocation;
|
||||
import org.dimdev.dimdoors.DimDoors;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
|
@ -9,10 +10,9 @@ import net.minecraft.entity.Entity;
|
|||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import org.dimdev.dimdoors.shared.rifts.RiftDestination;
|
||||
import org.dimdev.dimdoors.shared.rifts.TileEntityRift;
|
||||
|
||||
@Getter @AllArgsConstructor @Builder(toBuilder = true) @ToString
|
||||
public class PocketExitDestination extends RiftDestination {
|
||||
public class PocketExitDestination extends RiftDestination { // TODO: not exactly a destination
|
||||
//public PocketExitDestination() {}
|
||||
|
||||
@Override
|
||||
|
@ -27,7 +27,7 @@ public class PocketExitDestination extends RiftDestination {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean teleport(TileEntityRift rift, Entity entity) {
|
||||
public boolean teleport(RotatedLocation loc, Entity entity) {
|
||||
if (entity instanceof EntityPlayer) DimDoors.chat(entity, "The exit of this dungeon has not been linked. Either this is a bug or you are in dungeon-building mode.");
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
package org.dimdev.dimdoors.shared.rifts.destinations;
|
||||
|
||||
import org.dimdev.ddutils.RGBA;
|
||||
import org.dimdev.ddutils.RotatedLocation;
|
||||
import org.dimdev.dimdoors.DimDoors;
|
||||
import org.dimdev.dimdoors.shared.VirtualLocation;
|
||||
import org.dimdev.dimdoors.shared.pockets.Pocket;
|
||||
import org.dimdev.dimdoors.shared.pockets.PocketGenerator;
|
||||
import org.dimdev.dimdoors.shared.pockets.PocketRegistry;
|
||||
import org.dimdev.dimdoors.shared.rifts.RiftDestination;
|
||||
import org.dimdev.dimdoors.shared.rifts.RiftRegistry;
|
||||
import org.dimdev.dimdoors.shared.rifts.registry.RiftRegistry;
|
||||
import org.dimdev.dimdoors.shared.rifts.TileEntityRift;
|
||||
import org.dimdev.dimdoors.shared.world.ModDimensions;
|
||||
import org.dimdev.ddutils.EntityUtils;
|
||||
|
@ -17,51 +20,51 @@ import lombok.ToString;
|
|||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@Getter @AllArgsConstructor @Builder(toBuilder = true) @ToString
|
||||
public class PrivateDestination extends RiftDestination {
|
||||
//public PrivateDestination() {}
|
||||
|
||||
@Override
|
||||
public void readFromNBT(NBTTagCompound nbt) {
|
||||
super.readFromNBT(nbt);
|
||||
}
|
||||
@Override public void readFromNBT(NBTTagCompound nbt) { super.readFromNBT(nbt); }
|
||||
@Override public NBTTagCompound writeToNBT(NBTTagCompound nbt) { nbt = super.writeToNBT(nbt); return 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);
|
||||
public boolean teleport(RotatedLocation loc, Entity entity) {
|
||||
UUID uuid = EntityUtils.getEntityOwnerUUID(entity);
|
||||
VirtualLocation virtualLocation = VirtualLocation.fromLocation(loc.getLocation());
|
||||
if (uuid != null) {
|
||||
PocketRegistry privatePocketRegistry = PocketRegistry.getForDim(ModDimensions.getPrivateDim());
|
||||
RiftRegistry privateRiftRegistry = RiftRegistry.getForDim(ModDimensions.getPrivateDim());
|
||||
PocketRegistry privatePocketRegistry = PocketRegistry.instance(ModDimensions.getPrivateDim());
|
||||
Pocket pocket = privatePocketRegistry.getPocket(privatePocketRegistry.getPrivatePocketID(uuid));
|
||||
if (pocket == null) { // generate the private pocket and get its entrances
|
||||
pocket = PocketGenerator.generatePrivatePocket(rift.getVirtualLocation() != null ? rift.getVirtualLocation().toBuilder().depth(-1).build() : null); // set to where the pocket was first created
|
||||
// set to where the pocket was first created
|
||||
pocket = PocketGenerator.generatePrivatePocket(virtualLocation != null ? virtualLocation.toBuilder().depth(-1).build() : null);
|
||||
pocket.setup();
|
||||
privatePocketRegistry.setPrivatePocketID(uuid, pocket.getId());
|
||||
((TileEntityRift) pocket.getEntrance().getTileEntity()).teleportTo(entity);
|
||||
privateRiftRegistry.setPrivatePocketExit(uuid, rift.getLocation());
|
||||
((TileEntityRift) pocket.getEntrance().getTileEntity()).teleportTo(entity, loc.getYaw(), loc.getPitch());
|
||||
RiftRegistry.instance().setLastPrivatePocketExit(uuid, loc.getLocation());
|
||||
return true;
|
||||
} else {
|
||||
Location destLoc = privateRiftRegistry.getPrivatePocketEntrance(uuid); // get the last used entrances
|
||||
Location destLoc = RiftRegistry.instance().getPrivatePocketEntrance(uuid); // get the last used entrances
|
||||
if (destLoc == null) destLoc = pocket.getEntrance(); // if there's none, then set the target to the main entrances
|
||||
if (destLoc == null) { // if the pocket entrances is gone, then create a new private pocket
|
||||
DimDoors.log.info("All entrances are gone, creating a new private pocket!");
|
||||
pocket = PocketGenerator.generatePrivatePocket(rift.getVirtualLocation() != null ? rift.getVirtualLocation().toBuilder().depth(-1).build() : null);
|
||||
pocket = PocketGenerator.generatePrivatePocket(virtualLocation != null ? virtualLocation.toBuilder().depth(-1).build() : null);
|
||||
pocket.setup();
|
||||
privatePocketRegistry.setPrivatePocketID(uuid, pocket.getId());
|
||||
destLoc = pocket.getEntrance();
|
||||
}
|
||||
((TileEntityRift) destLoc.getTileEntity()).teleportTo(entity);
|
||||
privateRiftRegistry.setPrivatePocketExit(uuid, rift.getLocation());
|
||||
((TileEntityRift) destLoc.getTileEntity()).teleportTo(entity, loc.getYaw(), loc.getPitch());
|
||||
RiftRegistry.instance().setLastPrivatePocketExit(uuid, loc.getLocation());
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
return false; // TODO: There should be a way to get other entities into your private pocket, though. Add API for other mods.
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public RGBA getColor(Location location) {
|
||||
return new RGBA(0, 1, 0, 1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,26 +1,26 @@
|
|||
package org.dimdev.dimdoors.shared.rifts.destinations;
|
||||
|
||||
import org.dimdev.dimdoors.DimDoors;
|
||||
import org.dimdev.dimdoors.shared.pockets.Pocket;
|
||||
import org.dimdev.dimdoors.shared.pockets.PocketRegistry;
|
||||
import org.dimdev.dimdoors.shared.rifts.RiftDestination;
|
||||
import org.dimdev.dimdoors.shared.rifts.RiftRegistry;
|
||||
import org.dimdev.dimdoors.shared.rifts.TileEntityRift;
|
||||
import org.dimdev.dimdoors.shared.world.ModDimensions;
|
||||
import org.dimdev.dimdoors.shared.world.limbodimension.WorldProviderLimbo;
|
||||
import org.dimdev.dimdoors.shared.world.pocketdimension.WorldProviderPersonalPocket;
|
||||
import org.dimdev.ddutils.EntityUtils;
|
||||
import org.dimdev.ddutils.Location;
|
||||
import org.dimdev.ddutils.TeleportUtils;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.ToString;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import org.dimdev.ddutils.*;
|
||||
import org.dimdev.dimdoors.DimDoors;
|
||||
import org.dimdev.dimdoors.shared.pockets.Pocket;
|
||||
import org.dimdev.dimdoors.shared.pockets.PocketRegistry;
|
||||
import org.dimdev.dimdoors.shared.rifts.RiftDestination;
|
||||
import org.dimdev.dimdoors.shared.rifts.TileEntityRift;
|
||||
import org.dimdev.dimdoors.shared.rifts.registry.RiftRegistry;
|
||||
import org.dimdev.dimdoors.shared.world.ModDimensions;
|
||||
import org.dimdev.dimdoors.shared.world.limbodimension.WorldProviderLimbo;
|
||||
import org.dimdev.dimdoors.shared.world.pocketdimension.WorldProviderPersonalPocket;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@Getter @AllArgsConstructor @Builder(toBuilder = true) @ToString
|
||||
public class PrivatePocketExitDestination extends RiftDestination { // TODO: merge into PocketExit or Escape?
|
||||
public class PrivatePocketExitDestination extends RiftDestination {
|
||||
//public PrivatePocketExitDestination() {}
|
||||
|
||||
@Override
|
||||
|
@ -35,15 +35,14 @@ public class PrivatePocketExitDestination extends RiftDestination { // TODO: mer
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean teleport(TileEntityRift rift, Entity entity) {
|
||||
public boolean teleport(RotatedLocation loc, Entity entity) {
|
||||
Location destLoc;
|
||||
String uuid = EntityUtils.getEntityOwnerUUID(entity);
|
||||
UUID uuid = EntityUtils.getEntityOwnerUUID(entity);
|
||||
if (uuid != null) {
|
||||
PocketRegistry privatePocketRegistry = PocketRegistry.getForDim(ModDimensions.getPrivateDim());
|
||||
RiftRegistry privateRiftRegistry = RiftRegistry.getForDim(ModDimensions.getPrivateDim());
|
||||
destLoc = privateRiftRegistry.getPrivatePocketExit(uuid);
|
||||
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
|
||||
PocketRegistry privatePocketRegistry = PocketRegistry.instance(ModDimensions.getPrivateDim());
|
||||
destLoc = RiftRegistry.instance().getPrivatePocketExit(uuid);
|
||||
if (loc.getLocation().getWorld().provider instanceof WorldProviderPersonalPocket && privatePocketRegistry.getPrivatePocketID(uuid) == privatePocketRegistry.posToID(loc.getLocation().getPos())) {
|
||||
RiftRegistry.instance().setLastPrivatePocketEntrance(uuid, loc.getLocation()); // Remember which exit was used for next time the pocket is entered
|
||||
}
|
||||
if (destLoc == null || !(destLoc.getTileEntity() instanceof TileEntityRift)) {
|
||||
if (destLoc == null) {
|
||||
|
@ -54,7 +53,7 @@ public class PrivatePocketExitDestination extends RiftDestination { // TODO: mer
|
|||
TeleportUtils.teleport(entity, WorldProviderLimbo.getLimboSkySpawn(entity));
|
||||
return false;
|
||||
} else {
|
||||
((TileEntityRift) destLoc.getTileEntity()).teleportTo(entity);
|
||||
((TileEntityRift) destLoc.getTileEntity()).teleportTo(entity, loc.getYaw(), loc.getPitch());
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
|
@ -63,14 +62,15 @@ public class PrivatePocketExitDestination extends RiftDestination { // TODO: mer
|
|||
}
|
||||
|
||||
@Override
|
||||
public void register(TileEntityRift rift) {
|
||||
PocketRegistry privatePocketRegistry = PocketRegistry.getForDim(rift.getLocation().getDim());
|
||||
Pocket pocket = privatePocketRegistry.getPocketAt(rift.getPos());
|
||||
String uuid = privatePocketRegistry.getPrivatePocketOwner(pocket.getId());
|
||||
if (uuid != null) {
|
||||
RiftRegistry.getForDim(ModDimensions.getPrivateDim()).addPrivatePocketEntrance(uuid, rift.getLocation());
|
||||
}
|
||||
public void register(Location location) {
|
||||
super.register(location);
|
||||
PocketRegistry privatePocketRegistry = PocketRegistry.instance(location.getDim());
|
||||
Pocket pocket = privatePocketRegistry.getPocketAt(location.getPos());
|
||||
RiftRegistry.instance().addPocketEntrance(pocket, location);
|
||||
}
|
||||
|
||||
// TODO: unregister
|
||||
@Override
|
||||
public RGBA getColor(Location location) {
|
||||
return new RGBA(0, 1, 0, 1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
package org.dimdev.dimdoors.shared.rifts.destinations;
|
||||
|
||||
import lombok.*;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import org.dimdev.ddutils.Location;
|
||||
import org.dimdev.ddutils.RotatedLocation;
|
||||
import org.dimdev.dimdoors.shared.VirtualLocation;
|
||||
import org.dimdev.dimdoors.shared.pockets.Pocket;
|
||||
import org.dimdev.dimdoors.shared.pockets.PocketGenerator;
|
||||
|
||||
@Getter @AllArgsConstructor @NoArgsConstructor @Builder(toBuilder = true) @ToString
|
||||
public class PublicPocketDestination extends LinkingDestination {
|
||||
|
||||
@Override public void readFromNBT(NBTTagCompound nbt) { super.readFromNBT(nbt); }
|
||||
@Override public NBTTagCompound writeToNBT(NBTTagCompound nbt) { nbt = super.writeToNBT(nbt); return nbt; }
|
||||
|
||||
@Override
|
||||
public Location makeLinkTarget(RotatedLocation loc, Entity entity) {
|
||||
VirtualLocation riftVirtualLocation = VirtualLocation.fromLocation(loc.getLocation());
|
||||
VirtualLocation newVirtualLocation = null;
|
||||
if (riftVirtualLocation != null) {
|
||||
int depth = Math.min(riftVirtualLocation.getDepth(), 1);
|
||||
newVirtualLocation = riftVirtualLocation.toBuilder().depth(depth).build();
|
||||
}
|
||||
Pocket pocket = PocketGenerator.generatePublicPocket(newVirtualLocation);
|
||||
pocket.setup();
|
||||
|
||||
pocket.linkPocketTo(new GlobalDestination(loc.getLocation()), null);
|
||||
|
||||
return pocket.getEntrance();
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package org.dimdev.dimdoors.shared.rifts.destinations;
|
||||
|
||||
import org.dimdev.ddutils.Location;
|
||||
import org.dimdev.ddutils.RotatedLocation;
|
||||
import org.dimdev.ddutils.nbt.NBTUtils;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
|
@ -24,13 +25,13 @@ import org.dimdev.dimdoors.shared.rifts.TileEntityRift;
|
|||
@Override public NBTTagCompound writeToNBT(NBTTagCompound nbt) { nbt = super.writeToNBT(nbt); return NBTUtils.writeToNBT(this, nbt); }
|
||||
|
||||
@Override
|
||||
public boolean teleport(TileEntityRift rift, Entity entity) {
|
||||
rift.getWorld().getTileEntity(rift.getPos().add(offset));
|
||||
public boolean teleport(RotatedLocation loc, Entity entity) {
|
||||
((TileEntityRift) loc.getLocation().getWorld().getTileEntity(loc.getLocation().getPos().add(offset))).teleportTo(entity, loc.getPitch(), loc.getYaw());
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location getReferencedRift(Location rift) {
|
||||
return new Location(rift.getDim(), rift.getPos().add(offset));
|
||||
public Location getFixedTarget(Location location) {
|
||||
return new Location(location.getDim(), location.getPos().add(offset));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package org.dimdev.dimdoors.shared.rifts;
|
||||
package org.dimdev.dimdoors.shared.rifts.registry;
|
||||
|
||||
import lombok.*;
|
||||
import lombok.experimental.Wither;
|
||||
|
@ -14,7 +14,7 @@ import java.util.Set;
|
|||
import java.util.UUID;
|
||||
|
||||
@NBTSerializable @AllArgsConstructor @NoArgsConstructor @EqualsAndHashCode @Builder(toBuilder = true) @ToString
|
||||
public class AvailableLink implements INBTStorable {
|
||||
public class LinkProperties implements INBTStorable {
|
||||
@Wither public Location rift;
|
||||
|
||||
@Saved @Builder.Default public UUID id = UUID.randomUUID();
|
||||
|
@ -23,6 +23,7 @@ public class AvailableLink implements INBTStorable {
|
|||
@Saved @Builder.Default public Set<Integer> groups = new HashSet<>();
|
||||
@Saved public UUID replaceDestination;
|
||||
@Saved @Builder.Default public int linksRemaining = 1;
|
||||
@Saved @Builder.Default public boolean oneWay = false;
|
||||
|
||||
@Override public void readFromNBT(NBTTagCompound nbt) { NBTUtils.readFromNBT(this, nbt); }
|
||||
@Override public NBTTagCompound writeToNBT(NBTTagCompound nbt) { return NBTUtils.writeToNBT(this, nbt); }
|
|
@ -0,0 +1,13 @@
|
|||
package org.dimdev.dimdoors.shared.rifts.registry;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.dimdev.annotatednbt.NBTSerializable;
|
||||
import org.dimdev.annotatednbt.Saved;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@AllArgsConstructor @NoArgsConstructor
|
||||
@NBTSerializable public class PlayerRiftPointer extends RegistryVertex {
|
||||
@Saved public UUID player;
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package org.dimdev.dimdoors.shared.rifts.registry;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.dimdev.annotatednbt.NBTSerializable;
|
||||
import org.dimdev.annotatednbt.Saved;
|
||||
|
||||
@AllArgsConstructor @NoArgsConstructor @NBTSerializable
|
||||
public class PocketEntrancePointer extends RegistryVertex { // TODO: PocketRiftPointer superclass?
|
||||
@Saved public int pocketDim;
|
||||
@Saved public int pocketId;
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package org.dimdev.dimdoors.shared.rifts.registry;
|
||||
|
||||
import org.dimdev.annotatednbt.Saved;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public abstract class RegistryVertex {
|
||||
public int dim; // The dimension to store this object in. Links are stored in both registries.
|
||||
@Saved public UUID id = UUID.randomUUID(); // Used to create pointers to registry vertices. Should not be used for anything other than saving.
|
||||
|
||||
public void sourceGone(RegistryVertex source) {
|
||||
RiftRegistry.instance().markSubregistryDirty(dim);
|
||||
}
|
||||
|
||||
public void targetGone(RegistryVertex target) {
|
||||
RiftRegistry.instance().markSubregistryDirty(dim);
|
||||
}
|
||||
|
||||
public void sourceAdded(RegistryVertex to) {
|
||||
RiftRegistry.instance().markSubregistryDirty(dim);
|
||||
}
|
||||
|
||||
public void targetAdded(RegistryVertex to) {
|
||||
RiftRegistry.instance().markSubregistryDirty(dim);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
package org.dimdev.dimdoors.shared.rifts.registry;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.dimdev.annotatednbt.NBTSerializable;
|
||||
import org.dimdev.annotatednbt.Saved;
|
||||
import org.dimdev.ddutils.Location;
|
||||
import org.dimdev.dimdoors.shared.rifts.TileEntityRift;
|
||||
|
||||
@NoArgsConstructor @AllArgsConstructor
|
||||
@NBTSerializable public class Rift extends RegistryVertex {
|
||||
public @Saved Location location;
|
||||
public @Saved boolean isFloating;
|
||||
public @Saved LinkProperties properties;
|
||||
// TODO: receiveDungeonLink
|
||||
|
||||
public Rift(Location location) {
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sourceGone(RegistryVertex source) {
|
||||
super.sourceGone(source);
|
||||
TileEntityRift riftTileEntity = (TileEntityRift) location.getTileEntity();
|
||||
if (source instanceof Rift) {
|
||||
riftTileEntity.sourceGone(((Rift) source).location);
|
||||
}
|
||||
riftTileEntity.updateColor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void targetGone(RegistryVertex target) {
|
||||
super.targetGone(target);
|
||||
TileEntityRift riftTileEntity = (TileEntityRift) location.getTileEntity();
|
||||
if (target instanceof Rift) {
|
||||
riftTileEntity.targetGone(((Rift) target).location);
|
||||
}
|
||||
riftTileEntity.updateColor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sourceAdded(RegistryVertex source) {
|
||||
super.sourceAdded(source);
|
||||
((TileEntityRift) location.getTileEntity()).updateColor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void targetAdded(RegistryVertex target) {
|
||||
super.targetAdded(target);
|
||||
((TileEntityRift) location.getTileEntity()).updateColor();
|
||||
}
|
||||
|
||||
public void markDirty() {
|
||||
RiftRegistry.instance().markSubregistryDirty(dim);
|
||||
((TileEntityRift) location.getTileEntity()).updateColor();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
package org.dimdev.dimdoors.shared.rifts.registry;
|
||||
|
||||
public class RiftPlaceholder extends Rift {} // TODO: don't extend rift
|
|
@ -0,0 +1,416 @@
|
|||
package org.dimdev.dimdoors.shared.rifts.registry;
|
||||
|
||||
import net.minecraft.nbt.NBTBase;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.nbt.NBTTagList;
|
||||
import net.minecraft.world.storage.MapStorage;
|
||||
import net.minecraft.world.storage.WorldSavedData;
|
||||
import net.minecraftforge.common.DimensionManager;
|
||||
import org.dimdev.ddutils.Location;
|
||||
import org.dimdev.ddutils.WorldUtils;
|
||||
import org.dimdev.ddutils.nbt.NBTUtils;
|
||||
import org.dimdev.dimdoors.DimDoors;
|
||||
import org.dimdev.dimdoors.ddutils.GraphUtils;
|
||||
import org.dimdev.dimdoors.shared.pockets.Pocket;
|
||||
import org.dimdev.dimdoors.shared.pockets.PocketRegistry;
|
||||
import org.dimdev.dimdoors.shared.world.ModDimensions;
|
||||
import org.jgrapht.graph.DefaultDirectedGraph;
|
||||
import org.jgrapht.graph.DefaultEdge;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class RiftRegistry extends WorldSavedData {
|
||||
|
||||
private static final String DATA_NAME = DimDoors.MODID + "_global_rifts"; // TODO: can we use the same name as subregistries?
|
||||
private static final String SUBREGISTRY_DATA_NAME = DimDoors.MODID + "_rifts";
|
||||
|
||||
protected Map<Integer, RiftSubregistry> subregistries = new HashMap<>();
|
||||
protected DefaultDirectedGraph<RegistryVertex, DefaultEdge> graph = new DefaultDirectedGraph<>(DefaultEdge.class);
|
||||
// TODO: add methods that automatically add vertices/edges and mark appropriate subregistries as dirty
|
||||
|
||||
// Caches to avoid looping through vertices to find specific vertices
|
||||
protected Map<Location, Rift> locationMap = new HashMap<>();
|
||||
protected Map<Pocket, PocketEntrancePointer> pocketEntranceMap = new HashMap<>(); // TODO: We're going to want to move all pocket entrance info to the rift registry later to make PocketLib independent of DimDoors.
|
||||
protected Map<UUID, RegistryVertex> uuidMap = new HashMap<>();
|
||||
|
||||
// These are stored in the main registry
|
||||
protected Map<UUID, PlayerRiftPointer> lastPrivatePocketEntrances = new HashMap<>(); // Player UUID -> last rift used to exit pocket
|
||||
protected Map<UUID, PlayerRiftPointer> lastPrivatePocketExits = new HashMap<>(); // Player UUID -> last rift used to enter pocket
|
||||
protected Map<UUID, PlayerRiftPointer> overworldRifts = new HashMap<>(); // Player UUID -> rift used to exit the overworld
|
||||
|
||||
// <editor-fold defaultstate="collapsed" desc="Code for reading/writing/getting the registry">
|
||||
|
||||
public class RiftSubregistry extends WorldSavedData {
|
||||
private int dim;
|
||||
|
||||
public RiftSubregistry() {
|
||||
super(SUBREGISTRY_DATA_NAME);
|
||||
}
|
||||
|
||||
public RiftSubregistry(String s) {
|
||||
super(s);
|
||||
}
|
||||
|
||||
@Override public void readFromNBT(NBTTagCompound nbt) {
|
||||
// Registry is already loaded
|
||||
if (subregistries.get(dim) != null) return;
|
||||
|
||||
// Read rifts in this dimension
|
||||
NBTTagList riftsNBT = (NBTTagList) nbt.getTag("rifts");
|
||||
for (NBTBase riftNBT : riftsNBT) {
|
||||
Rift rift = NBTUtils.readFromNBT(new Rift(), (NBTTagCompound) riftNBT);
|
||||
rift.dim = dim;
|
||||
graph.addVertex(rift);
|
||||
uuidMap.put(rift.id, rift);
|
||||
locationMap.put(rift.location, rift);
|
||||
}
|
||||
|
||||
NBTTagList pocketsNBT = (NBTTagList) nbt.getTag("pockets");
|
||||
for (NBTBase pocketNBT : pocketsNBT) {
|
||||
PocketEntrancePointer pocket = NBTUtils.readFromNBT(new PocketEntrancePointer(), (NBTTagCompound) pocketNBT);
|
||||
pocket.dim = dim;
|
||||
graph.addVertex(pocket);
|
||||
uuidMap.put(pocket.id, pocket);
|
||||
pocketEntranceMap.put(PocketRegistry.instance(pocket.dim).getPocket(pocket.pocketId), pocket);
|
||||
}
|
||||
|
||||
// Read the connections between links that have a source or destination in this dimension
|
||||
NBTTagList linksNBT = (NBTTagList) nbt.getTag("links");
|
||||
for (NBTBase linkNBT : linksNBT) {
|
||||
RegistryVertex from = uuidMap.get(((NBTTagCompound) linkNBT).getUniqueId("from"));
|
||||
RegistryVertex to = uuidMap.get(((NBTTagCompound) linkNBT).getUniqueId("to"));
|
||||
if (from != null && to != null) {
|
||||
graph.addEdge(from, to);
|
||||
// We need a system for detecting links that are incomplete after processing them in the other subregistry too
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Even though it seems like we could loop only once over the vertices and edges (in the RiftRegistry's writeToNBT
|
||||
// method rather than RiftSubregistry) and save each in the appropriate registry, we can't do this because it is not
|
||||
// always the case that all worlds will be saved at once.
|
||||
@Override public NBTTagCompound writeToNBT(NBTTagCompound nbt) {
|
||||
// Write rifts in this dimension
|
||||
NBTTagList riftsNBT = new NBTTagList();
|
||||
NBTTagList pocketsNBT = new NBTTagList();
|
||||
for (RegistryVertex vertex : graph.vertexSet()) {
|
||||
if (vertex.dim == dim) {
|
||||
NBTTagCompound vertexNBT = NBTUtils.writeToNBT(vertex, new NBTTagCompound());
|
||||
if (vertex instanceof Rift) {
|
||||
riftsNBT.appendTag(vertexNBT);
|
||||
} else if (vertex instanceof PocketEntrancePointer) {
|
||||
pocketsNBT.appendTag(vertexNBT);
|
||||
} else if (!(vertex instanceof PlayerRiftPointer)) {
|
||||
throw new RuntimeException("Unsupported registry vertex type " + vertex.getClass().getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
nbt.setTag("rifts", riftsNBT);
|
||||
nbt.setTag("pockets", pocketsNBT);
|
||||
|
||||
// Write the connections between links that have a source or destination in this dimension
|
||||
NBTTagList linksNBT = new NBTTagList();
|
||||
for (DefaultEdge edge : graph.edgeSet()) {
|
||||
RegistryVertex from = graph.getEdgeSource(edge);
|
||||
RegistryVertex to = graph.getEdgeTarget(edge);
|
||||
if (from.dim == dim || to.dim == dim && !(from instanceof PlayerRiftPointer)) {
|
||||
NBTTagCompound linkNBT = new NBTTagCompound();
|
||||
linkNBT.setUniqueId("from", from.id);
|
||||
linkNBT.setUniqueId("to", to.id);
|
||||
NBTUtils.writeToNBT(edge, linkNBT); // Write in both registries, we might want to notify when there's a missing world later
|
||||
linksNBT.appendTag(linkNBT);
|
||||
}
|
||||
}
|
||||
nbt.setTag("links", riftsNBT);
|
||||
|
||||
return nbt;
|
||||
}
|
||||
}
|
||||
|
||||
public RiftRegistry() {
|
||||
super(DATA_NAME);
|
||||
}
|
||||
|
||||
public RiftRegistry(String s) {
|
||||
super(s);
|
||||
}
|
||||
|
||||
public static RiftRegistry instance() {
|
||||
MapStorage storage = WorldUtils.getWorld(0).getMapStorage();
|
||||
RiftRegistry instance = (RiftRegistry) storage.getOrLoadData(RiftRegistry.class, DATA_NAME);
|
||||
|
||||
if (instance == null) {
|
||||
instance = new RiftRegistry();
|
||||
storage.setData(DATA_NAME, instance);
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromNBT(NBTTagCompound nbt) {
|
||||
// Trigger the subregistry reading code for all dimensions. It would be better if there was some way of forcing
|
||||
// them to be read from somewhere else, since this is technically more than just reading the NBT. This has to be
|
||||
// done last since links are only in the subregistries.
|
||||
// TODO: If non-dirty but new WorldSavedDatas aren't automatically saved, then create the subregistries here
|
||||
// TODO: rather then in the markSubregistryDirty method.
|
||||
for (int dim : DimensionManager.getStaticDimensionIDs()) {
|
||||
MapStorage storage = WorldUtils.getWorld(dim).getPerWorldStorage();
|
||||
RiftSubregistry instance = (RiftSubregistry) storage.getOrLoadData(RiftSubregistry.class, SUBREGISTRY_DATA_NAME);
|
||||
if (instance != null) {
|
||||
instance.dim = dim;
|
||||
subregistries.put(dim, instance);
|
||||
}
|
||||
}
|
||||
|
||||
// Read player to rift maps (this has to be done after the uuidMap has been filled by the subregistry code)
|
||||
lastPrivatePocketEntrances = readPlayerRiftPointers((NBTTagList) nbt.getTag("lastPrivatePocketEntrances"));
|
||||
lastPrivatePocketExits = readPlayerRiftPointers((NBTTagList) nbt.getTag("lastPrivatePocketExits"));
|
||||
overworldRifts = readPlayerRiftPointers((NBTTagList) nbt.getTag("overworldRifts"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public NBTTagCompound writeToNBT(NBTTagCompound nbt) {
|
||||
// Subregistries are written automatically when the worlds are saved.
|
||||
nbt.setTag("lastPrivatePocketEntrances", writePlayerRiftPointers(lastPrivatePocketEntrances));
|
||||
nbt.setTag("lastPrivatePocketExits", writePlayerRiftPointers(lastPrivatePocketExits));
|
||||
nbt.setTag("overworldRifts", writePlayerRiftPointers(overworldRifts));
|
||||
return nbt;
|
||||
}
|
||||
|
||||
private Map<UUID, PlayerRiftPointer> readPlayerRiftPointers(NBTTagList playerRiftPointersNBT) {
|
||||
Map<UUID, PlayerRiftPointer> pointerMap = new HashMap<>();
|
||||
for (NBTBase entryNBT : playerRiftPointersNBT) {
|
||||
UUID player = ((NBTTagCompound) entryNBT).getUniqueId("player");
|
||||
UUID rift = ((NBTTagCompound) entryNBT).getUniqueId("rift");
|
||||
PlayerRiftPointer pointer = new PlayerRiftPointer(player);
|
||||
pointerMap.put(player, pointer);
|
||||
uuidMap.put(pointer.id, pointer);
|
||||
graph.addVertex(pointer);
|
||||
graph.addEdge(pointer, uuidMap.get(rift));
|
||||
}
|
||||
return pointerMap;
|
||||
}
|
||||
|
||||
private NBTTagList writePlayerRiftPointers(Map<UUID, PlayerRiftPointer> playerRiftPointerMap) {
|
||||
NBTTagList pointers = new NBTTagList();
|
||||
for (Map.Entry<UUID, PlayerRiftPointer> entry : playerRiftPointerMap.entrySet()) {
|
||||
NBTTagCompound entryNBT = new NBTTagCompound();
|
||||
entryNBT.setUniqueId("player", entry.getKey());
|
||||
int count = 0;
|
||||
for (DefaultEdge edge : graph.outgoingEdgesOf(entry.getValue())) {
|
||||
entryNBT.setUniqueId("rift", graph.getEdgeTarget(edge).id);
|
||||
count++;
|
||||
}
|
||||
if (count != 1) throw new RuntimeException("PlayerRiftPointer points to more than one rift");
|
||||
pointers.appendTag(entryNBT);
|
||||
}
|
||||
return pointers;
|
||||
}
|
||||
|
||||
public void markSubregistryDirty(int dim) {
|
||||
RiftSubregistry subregistry = subregistries.get(dim);
|
||||
if (subregistry != null) {
|
||||
subregistry.markDirty();
|
||||
} else {
|
||||
// Create the subregistry
|
||||
MapStorage storage = WorldUtils.getWorld(dim).getPerWorldStorage();
|
||||
RiftSubregistry instance = new RiftSubregistry();
|
||||
instance.dim = dim;
|
||||
instance.markDirty();
|
||||
storage.setData(SUBREGISTRY_DATA_NAME, instance);
|
||||
subregistries.put(dim, instance);
|
||||
}
|
||||
}
|
||||
|
||||
// </editor-fold>
|
||||
|
||||
public boolean isRiftAt(Location location) {
|
||||
return locationMap.get(location) != null;
|
||||
}
|
||||
|
||||
public Rift getRift(Location location) {
|
||||
Rift rift = locationMap.get(location);
|
||||
if (rift == null) throw new IllegalArgumentException("There is no rift registered at " + location);
|
||||
return rift;
|
||||
}
|
||||
|
||||
public void addRift(Location location) {
|
||||
DimDoors.log.info("Adding rift at " + location);
|
||||
RegistryVertex currentRift = getRift(location);
|
||||
Rift rift;
|
||||
if (currentRift instanceof RiftPlaceholder) {
|
||||
rift = new Rift(location);
|
||||
rift.dim = location.getDim();
|
||||
rift.id = currentRift.id;
|
||||
GraphUtils.replaceVertex(graph, currentRift, rift);
|
||||
} else if (currentRift == null) {
|
||||
rift = new Rift(location);
|
||||
rift.dim = location.getDim();
|
||||
graph.addVertex(rift);
|
||||
} else {
|
||||
throw new IllegalArgumentException("There is already a rift registered at " + location);
|
||||
}
|
||||
uuidMap.put(rift.id, rift);
|
||||
locationMap.put(location, rift);
|
||||
rift.markDirty();
|
||||
}
|
||||
|
||||
public void removeRift(Location location) {
|
||||
DimDoors.log.info("Removing rift at " + location);
|
||||
|
||||
Rift rift = getRift(location);
|
||||
|
||||
// Notify the adjacent vertices of the change
|
||||
for (DefaultEdge edge : graph.incomingEdgesOf(rift)) graph.getEdgeSource(edge).targetGone(rift);
|
||||
for (DefaultEdge edge : graph.outgoingEdgesOf(rift)) graph.getEdgeTarget(edge).sourceGone(rift);
|
||||
|
||||
graph.removeVertex(rift);
|
||||
locationMap.remove(location);
|
||||
uuidMap.remove(rift.id);
|
||||
rift.markDirty();
|
||||
}
|
||||
|
||||
private void addEdge(RegistryVertex from, RegistryVertex to) {
|
||||
graph.addEdge(from, to);
|
||||
if (from instanceof PlayerRiftPointer) {
|
||||
markDirty();
|
||||
} else {
|
||||
markSubregistryDirty(from.dim);
|
||||
}
|
||||
markSubregistryDirty(to.dim);
|
||||
}
|
||||
|
||||
public void addLink(Location locationFrom, Location locationTo) {
|
||||
DimDoors.log.info("Adding link " + locationFrom + " -> " + locationTo);
|
||||
Rift from = getRift(locationFrom);
|
||||
|
||||
Rift to = getRift(locationTo);
|
||||
|
||||
addEdge(from, to);
|
||||
|
||||
// Notify the linked vertices of the change
|
||||
from.targetAdded(to);
|
||||
to.sourceAdded(from);
|
||||
}
|
||||
|
||||
public void removeLink(Location locationFrom, Location locationTo) {
|
||||
DimDoors.log.info("Removing link " + locationFrom + " -> " + locationTo);
|
||||
|
||||
Rift from = getRift(locationFrom);
|
||||
Rift to = getRift(locationTo);
|
||||
|
||||
addEdge(from, to);
|
||||
|
||||
// Notify the linked vertices of the change
|
||||
from.targetGone(to);
|
||||
to.sourceGone(from);
|
||||
}
|
||||
|
||||
public void setProperties(Location location, LinkProperties properties) {
|
||||
DimDoors.log.info("Setting DungeonLinkProperties for rift at " + location + " to " + properties);
|
||||
Rift rift = getRift(location);
|
||||
rift.properties = properties;
|
||||
rift.markDirty();
|
||||
}
|
||||
|
||||
public Set<Location> getPocketEntrances(Pocket pocket) {
|
||||
PocketEntrancePointer pointer = pocketEntranceMap.get(pocket);
|
||||
if (pointer == null) {
|
||||
return Collections.emptySet();
|
||||
} else {
|
||||
return graph.outgoingEdgesOf(pointer).stream()
|
||||
.map(graph::getEdgeTarget)
|
||||
.map(Rift.class::cast)
|
||||
.map(rift -> rift.location)
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
}
|
||||
|
||||
public void addPocketEntrance(Pocket pocket, Location location) {
|
||||
DimDoors.log.info("Adding pocket entrance for pocket " + pocket.getId() + " in dimension " + pocket.getDim() + " at " + location);
|
||||
PocketEntrancePointer pointer = pocketEntranceMap.get(pocket);
|
||||
if (pointer == null) {
|
||||
pointer = new PocketEntrancePointer(pocket.getDim(), pocket.getId());
|
||||
pointer.dim = pocket.getDim();
|
||||
graph.addVertex(pointer);
|
||||
pocketEntranceMap.put(pocket, pointer);
|
||||
uuidMap.put(pointer.id, pointer);
|
||||
}
|
||||
Rift rift = getRift(location);
|
||||
addEdge(pointer, rift);
|
||||
}
|
||||
|
||||
public Location getPrivatePocketEntrance(UUID playerUUID) {
|
||||
// Try to get the last used entrance
|
||||
PlayerRiftPointer entrancePointer = lastPrivatePocketEntrances.get(playerUUID);
|
||||
Rift entrance = (Rift) GraphUtils.followPointer(graph, entrancePointer);
|
||||
if (entrance != null) return entrance.location;
|
||||
|
||||
// If there was no last used private entrance, get one of the player's private pocket entrances
|
||||
PocketRegistry privatePocketRegistry = PocketRegistry.instance(ModDimensions.getPrivateDim());
|
||||
Pocket pocket = privatePocketRegistry.getPocket(privatePocketRegistry.getPrivatePocketID(playerUUID));
|
||||
return getPocketEntrances(pocket).stream().findFirst().orElse(null);
|
||||
}
|
||||
|
||||
private void setPlayerRiftPointer(UUID playerUUID, Location rift, Map<UUID, PlayerRiftPointer> map) {
|
||||
PlayerRiftPointer pointer = map.get(playerUUID);
|
||||
if (pointer == null) {
|
||||
pointer = new PlayerRiftPointer(playerUUID);
|
||||
graph.addVertex(pointer);
|
||||
map.put(playerUUID, pointer);
|
||||
uuidMap.put(pointer.id, pointer);
|
||||
} else {
|
||||
graph.removeAllEdges(graph.outgoingEdgesOf(pointer));
|
||||
}
|
||||
addEdge(pointer, getRift(rift));
|
||||
}
|
||||
|
||||
public void setLastPrivatePocketEntrance(UUID playerUUID, Location rift) {
|
||||
DimDoors.log.info("Setting last used private pocket entrance for " + playerUUID + " at " + rift);
|
||||
setPlayerRiftPointer(playerUUID, rift, lastPrivatePocketEntrances);
|
||||
}
|
||||
|
||||
public Location getPrivatePocketExit(UUID playerUUID) {
|
||||
PlayerRiftPointer entrancePointer = lastPrivatePocketExits.get(playerUUID);
|
||||
Rift entrance = (Rift) GraphUtils.followPointer(graph, entrancePointer);
|
||||
return entrance.location;
|
||||
}
|
||||
|
||||
public void setLastPrivatePocketExit(UUID playerUUID, Location rift) {
|
||||
DimDoors.log.info("Setting last used private pocket entrance for " + playerUUID + " at " + rift);
|
||||
setPlayerRiftPointer(playerUUID, rift, lastPrivatePocketExits);
|
||||
}
|
||||
|
||||
public Location getOverworldRift(UUID playerUUID) {
|
||||
PlayerRiftPointer entrancePointer = overworldRifts.get(playerUUID);
|
||||
Rift entrance = (Rift) GraphUtils.followPointer(graph, entrancePointer);
|
||||
return entrance.location;
|
||||
}
|
||||
|
||||
public void setOverworldRift(UUID playerUUID, Location rift) {
|
||||
DimDoors.log.info("Setting last used private pocket entrance for " + playerUUID + " at " + rift);
|
||||
setPlayerRiftPointer(playerUUID, rift, overworldRifts);
|
||||
}
|
||||
|
||||
public Collection<Rift> getRifts() {
|
||||
return locationMap.values();
|
||||
}
|
||||
|
||||
public Set<Location> getTargets(Location location) {
|
||||
return graph.outgoingEdgesOf(locationMap.get(location)).stream()
|
||||
.map(graph::getEdgeTarget)
|
||||
.map(Rift.class::cast)
|
||||
.map(rift -> rift.location)
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
public Set<Location> getSources(Location location) {
|
||||
return graph.incomingEdgesOf(locationMap.get(location)).stream()
|
||||
.map(graph::getEdgeTarget)
|
||||
.map(Rift.class::cast)
|
||||
.map(rift -> rift.location)
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
}
|
|
@ -10,6 +10,7 @@ import org.dimdev.dimdoors.shared.rifts.*;
|
|||
import org.dimdev.dimdoors.shared.rifts.destinations.PocketEntranceDestination;
|
||||
import org.dimdev.dimdoors.shared.rifts.destinations.PocketExitDestination;
|
||||
import org.dimdev.dimdoors.shared.rifts.destinations.PrivatePocketExitDestination;
|
||||
import org.dimdev.dimdoors.shared.rifts.registry.LinkProperties;
|
||||
import org.dimdev.dimdoors.shared.tileentities.TileEntityEntranceRift;
|
||||
import org.dimdev.ddutils.schem.Schematic;
|
||||
import net.minecraft.block.BlockDoor;
|
||||
|
@ -30,10 +31,7 @@ import java.io.DataOutputStream;
|
|||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author Robijnvogel
|
||||
|
@ -158,10 +156,15 @@ public final class PocketSchematicGenerator {
|
|||
// Generate the rift TileEntities
|
||||
schematic.tileEntities = new ArrayList<>();
|
||||
TileEntityEntranceRift rift = (TileEntityEntranceRift) doorBlock.createTileEntity(null, doorBlock.getDefaultState());
|
||||
rift.setSingleDestination(PocketEntranceDestination.builder()
|
||||
.ifDestinations(Collections.singletonList(new WeightedRiftDestination(exitDest, 1, 0)))
|
||||
rift.setDestination(PocketEntranceDestination.builder()
|
||||
.ifDestination(exitDest)
|
||||
.build());
|
||||
rift.setProperties(LinkProperties.builder()
|
||||
.groups(Collections.singleton(1))
|
||||
.linksRemaining(1)
|
||||
.entranceWeight(chaosWeight)
|
||||
.floatingWeight(chaosWeight)
|
||||
.build());
|
||||
rift.setChaosWeight(chaosWeight);
|
||||
|
||||
rift.setPlaceRiftOnBreak(true);
|
||||
NBTTagCompound tileNBT = rift.serializeNBT();
|
||||
|
|
|
@ -4,7 +4,6 @@ import org.dimdev.dimdoors.shared.entities.EntityMonolith;
|
|||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
import net.minecraft.world.biome.BiomeDecorator;
|
||||
import net.minecraft.world.chunk.ChunkPrimer;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package org.dimdev.dimdoors.shared.world.pocketdimension;
|
||||
|
||||
import org.dimdev.dimdoors.shared.entities.EntityMonolith;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
|
Loading…
Reference in a new issue