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
build.gradle
src/main/java/org/dimdev
ddutils
dimdoors
ddutils
shared
CommonProxy.javaEventHandler.javaVirtualLocation.java
blocks
BlockDimensionalDoor.javaBlockDimensionalDoorGold.javaBlockDimensionalDoorIron.javaBlockDimensionalDoorPersonal.javaBlockDimensionalTrapdoorWood.javaIRiftProvider.java
commands
items
pockets
rifts
RiftDestination.javaRiftRegistry.javaTileEntityRift.javaWeightedRiftDestination.java
destinations
AvailableLinkDestination.javaEscapeDestination.javaGlobalDestination.javaLimboDestination.javaLinkingDestination.javaLocalDestination.javaNewPublicDestination.javaPocketEntranceDestination.javaPocketExitDestination.javaPrivateDestination.javaPrivatePocketExitDestination.javaPublicPocketDestination.javaRelativeDestination.java
registry
tools
world
|
@ -64,6 +64,7 @@ configurations {
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
embed 'com.flowpowered:flow-math:1.0.3'
|
embed 'com.flowpowered:flow-math:1.0.3'
|
||||||
|
embed 'org.jgrapht:jgrapht-core:1.1.0'
|
||||||
compile 'com.github.DimensionalDevelopment:AnnotatedNBT:-SNAPSHOT'
|
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.player.EntityPlayer;
|
||||||
import net.minecraft.entity.projectile.*;
|
import net.minecraft.entity.projectile.*;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public final class EntityUtils {
|
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 EntityThrowable) entity = ((EntityThrowable) entity).getThrower();
|
||||||
if (entity instanceof EntityArrow) entity = ((EntityArrow) entity).shootingEntity;
|
if (entity instanceof EntityArrow) entity = ((EntityArrow) entity).shootingEntity;
|
||||||
if (entity instanceof EntityFireball) entity = ((EntityFireball) entity).shootingEntity;
|
if (entity instanceof EntityFireball) entity = ((EntityFireball) entity).shootingEntity;
|
||||||
|
@ -25,8 +27,8 @@ public final class EntityUtils {
|
||||||
if (player != null) entity = player;
|
if (player != null) entity = player;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entity instanceof IEntityOwnable && ((IEntityOwnable) entity).getOwnerId() != null) return ((IEntityOwnable) entity).getOwnerId().toString();
|
if (entity instanceof IEntityOwnable && ((IEntityOwnable) entity).getOwnerId() != null) return ((IEntityOwnable) entity).getOwnerId();
|
||||||
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 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;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ import org.dimdev.annotatednbt.Saved;
|
||||||
import org.dimdev.annotatednbt.NBTSerializable;
|
import org.dimdev.annotatednbt.NBTSerializable;
|
||||||
|
|
||||||
@ToString @AllArgsConstructor @NoArgsConstructor
|
@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*/ Location location;
|
||||||
@Getter @Saved /*private*/ float yaw;
|
@Getter @Saved /*private*/ float yaw;
|
||||||
@Getter @Saved /*private*/ float pitch;
|
@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 {
|
try {
|
||||||
Class<?> callingClass = Class.forName(new Exception().getStackTrace()[1].getClassName());
|
Class<?> callingClass = Class.forName(new Exception().getStackTrace()[1].getClassName());
|
||||||
Class<?> nbtWriter = Class.forName(callingClass.getPackage().getName() + "." + callingClass.getSimpleName() + "NBTWriter");
|
Class<?> nbtWriter = Class.forName(callingClass.getPackage().getName() + "." + callingClass.getSimpleName() + "NBTWriter");
|
||||||
|
@ -28,5 +28,6 @@ public final class NBTUtils {
|
||||||
} catch (ClassNotFoundException|NoSuchMethodException|IllegalAccessException|InvocationTargetException e) {
|
} catch (ClassNotFoundException|NoSuchMethodException|IllegalAccessException|InvocationTargetException e) {
|
||||||
throw new RuntimeException(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.blocks.ModBlocks;
|
||||||
import org.dimdev.dimdoors.shared.entities.EntityMonolith;
|
import org.dimdev.dimdoors.shared.entities.EntityMonolith;
|
||||||
import org.dimdev.dimdoors.shared.items.ModItems;
|
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.*;
|
||||||
import org.dimdev.dimdoors.shared.rifts.destinations.*;
|
import org.dimdev.dimdoors.shared.rifts.destinations.*;
|
||||||
import org.dimdev.dimdoors.shared.sound.ModSounds;
|
import org.dimdev.dimdoors.shared.sound.ModSounds;
|
||||||
|
@ -44,7 +45,7 @@ public abstract class CommonProxy {
|
||||||
RiftDestination.destinationRegistry.put("global", GlobalDestination.class);
|
RiftDestination.destinationRegistry.put("global", GlobalDestination.class);
|
||||||
RiftDestination.destinationRegistry.put("limbo", LimboDestination.class);
|
RiftDestination.destinationRegistry.put("limbo", LimboDestination.class);
|
||||||
RiftDestination.destinationRegistry.put("local", LocalDestination.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_entrance", PocketEntranceDestination.class);
|
||||||
RiftDestination.destinationRegistry.put("pocket_exit", PocketExitDestination.class);
|
RiftDestination.destinationRegistry.put("pocket_exit", PocketExitDestination.class);
|
||||||
RiftDestination.destinationRegistry.put("private", PrivateDestination.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.eventhandler.SubscribeEvent;
|
||||||
import net.minecraftforge.fml.common.gameevent.PlayerEvent;
|
import net.minecraftforge.fml.common.gameevent.PlayerEvent;
|
||||||
import org.dimdev.dimdoors.shared.pockets.PocketRegistry;
|
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;
|
import org.dimdev.dimdoors.shared.world.ModDimensions;
|
||||||
|
|
||||||
public final class EventHandler {
|
public final class EventHandler {
|
||||||
|
@ -34,7 +34,7 @@ public final class EventHandler {
|
||||||
if (!world.isRemote
|
if (!world.isRemote
|
||||||
&& !player.isDead
|
&& !player.isDead
|
||||||
&& ModDimensions.isDimDoorsPocketDimension(world)
|
&& ModDimensions.isDimDoorsPocketDimension(world)
|
||||||
&& !PocketRegistry.getForDim(dim).isPlayerAllowedToBeHere(player, player.getPosition())) {
|
&& !PocketRegistry.instance(dim).isPlayerAllowedToBeHere(player, player.getPosition())) {
|
||||||
// TODO: make the world circular
|
// TODO: make the world circular
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ public final class EventHandler {
|
||||||
public static void onDimensionChange(PlayerEvent.PlayerChangedDimensionEvent event) {
|
public static void onDimensionChange(PlayerEvent.PlayerChangedDimensionEvent event) {
|
||||||
// TODO: PocketLib compatibility
|
// TODO: PocketLib compatibility
|
||||||
if (ModDimensions.isDimDoorsPocketDimension(event.fromDim) && !ModDimensions.isDimDoorsPocketDimension(event.toDim)) {
|
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) {
|
public static VirtualLocation fromLocation(Location location) {
|
||||||
VirtualLocation virtualLocation = null;
|
VirtualLocation virtualLocation = null;
|
||||||
if (ModDimensions.isDimDoorsPocketDimension(location.getDim())) {
|
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) {
|
if (pocket != null) {
|
||||||
virtualLocation = pocket.getVirtualLocation(); // TODO: pocket-relative coordinates
|
virtualLocation = pocket.getVirtualLocation(); // TODO: pocket-relative coordinates
|
||||||
} else {
|
} 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) {
|
} else if (location.getWorld().provider instanceof WorldProviderLimbo) {
|
||||||
virtualLocation = new VirtualLocation(location.getDim(), location.getX(), location.getZ(), Config.getMaxDungeonDepth());
|
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.EnumHand;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.world.World;
|
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.TileEntityEntranceRift;
|
||||||
import org.dimdev.dimdoors.shared.tileentities.TileEntityFloatingRift;
|
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);
|
TileEntityEntranceRift rift = getRift(world, pos, state);
|
||||||
super.breakBlock(world, pos, state);
|
super.breakBlock(world, pos, state);
|
||||||
if (world.isRemote) return;
|
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());
|
world.setBlockState(rift.getPos(), ModBlocks.RIFT.getDefaultState());
|
||||||
TileEntityFloatingRift newRift = (TileEntityFloatingRift) world.getTileEntity(pos);
|
TileEntityFloatingRift newRift = (TileEntityFloatingRift) world.getTileEntity(pos);
|
||||||
newRift.copyFrom(rift);
|
newRift.copyFrom(rift);
|
||||||
|
|
|
@ -3,10 +3,8 @@ package org.dimdev.dimdoors.shared.blocks;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import org.dimdev.dimdoors.DimDoors;
|
import org.dimdev.dimdoors.DimDoors;
|
||||||
import org.dimdev.dimdoors.shared.items.ModItems;
|
import org.dimdev.dimdoors.shared.items.ModItems;
|
||||||
import org.dimdev.dimdoors.shared.rifts.AvailableLink;
|
import org.dimdev.dimdoors.shared.rifts.registry.LinkProperties;
|
||||||
import org.dimdev.dimdoors.shared.rifts.WeightedRiftDestination;
|
|
||||||
import org.dimdev.dimdoors.shared.rifts.destinations.AvailableLinkDestination;
|
import org.dimdev.dimdoors.shared.rifts.destinations.AvailableLinkDestination;
|
||||||
import org.dimdev.dimdoors.shared.rifts.destinations.NewPublicDestination;
|
|
||||||
import org.dimdev.dimdoors.shared.tileentities.TileEntityEntranceRift;
|
import org.dimdev.dimdoors.shared.tileentities.TileEntityEntranceRift;
|
||||||
import net.minecraft.block.material.Material;
|
import net.minecraft.block.material.Material;
|
||||||
import net.minecraft.item.Item;
|
import net.minecraft.item.Item;
|
||||||
|
@ -37,21 +35,19 @@ public class BlockDimensionalDoorGold extends BlockDimensionalDoor {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setupRift(TileEntityEntranceRift rift) {
|
public void setupRift(TileEntityEntranceRift rift) {
|
||||||
AvailableLink link = AvailableLink.builder()
|
rift.setProperties(LinkProperties.builder()
|
||||||
.groups(new HashSet<>(Arrays.asList(0, 1)))
|
.groups(new HashSet<>(Arrays.asList(0, 1)))
|
||||||
.linksRemaining(1)
|
.linksRemaining(1)
|
||||||
.replaceDestination(UUID.randomUUID()).build();
|
.replaceDestination(UUID.randomUUID()).build());
|
||||||
rift.addAvailableLink(link);
|
rift.setDestination(AvailableLinkDestination.builder()
|
||||||
AvailableLinkDestination destination = AvailableLinkDestination.builder()
|
|
||||||
.acceptedGroups(Collections.singleton(0))
|
.acceptedGroups(Collections.singleton(0))
|
||||||
.coordFactor(1)
|
.coordFactor(1)
|
||||||
.negativeDepthFactor(10000)
|
.negativeDepthFactor(10000)
|
||||||
.positiveDepthFactor(80)
|
.positiveDepthFactor(80)
|
||||||
.weightMaximum(100)
|
.weightMaximum(100)
|
||||||
.linkId(link.id)
|
|
||||||
.noLink(false)
|
.noLink(false)
|
||||||
.newRiftWeight(1).build();
|
.noLinkBack(false)
|
||||||
rift.addWeightedDestination(new WeightedRiftDestination(destination, 1, 0, null, link.replaceDestination));
|
.newRiftWeight(1).build());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -4,7 +4,7 @@ import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.init.Blocks;
|
import net.minecraft.init.Blocks;
|
||||||
import org.dimdev.dimdoors.DimDoors;
|
import org.dimdev.dimdoors.DimDoors;
|
||||||
import org.dimdev.dimdoors.shared.items.ModItems;
|
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 org.dimdev.dimdoors.shared.tileentities.TileEntityEntranceRift;
|
||||||
import net.minecraft.block.material.Material;
|
import net.minecraft.block.material.Material;
|
||||||
import net.minecraft.item.Item;
|
import net.minecraft.item.Item;
|
||||||
|
@ -36,8 +36,8 @@ public class BlockDimensionalDoorIron extends BlockDimensionalDoor {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setupRift(TileEntityEntranceRift rift) {
|
public void setupRift(TileEntityEntranceRift rift) {
|
||||||
NewPublicDestination destination = NewPublicDestination.builder().build();
|
PublicPocketDestination destination = PublicPocketDestination.builder().build();
|
||||||
rift.setSingleDestination(destination);
|
rift.setDestination(destination);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -37,11 +37,10 @@ public class BlockDimensionalDoorPersonal extends BlockDimensionalDoor {
|
||||||
@Override
|
@Override
|
||||||
public void setupRift(TileEntityEntranceRift rift) {
|
public void setupRift(TileEntityEntranceRift rift) {
|
||||||
if (rift.getWorld().provider instanceof WorldProviderPersonalPocket) {
|
if (rift.getWorld().provider instanceof WorldProviderPersonalPocket) {
|
||||||
rift.setSingleDestination(new PrivatePocketExitDestination()); // exit
|
rift.setDestination(new PrivatePocketExitDestination()); // exit
|
||||||
} else {
|
} else {
|
||||||
rift.setSingleDestination(new PrivateDestination()); // entrances
|
rift.setDestination(new PrivateDestination()); // entrances
|
||||||
}
|
}
|
||||||
rift.setChaosWeight(0); // TODO: generated schematic exits too
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -32,7 +32,7 @@ public class BlockDimensionalTrapdoorWood extends BlockDimensionalTrapdoor {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setupRift(TileEntityEntranceRift rift) {
|
public void setupRift(TileEntityEntranceRift rift) {
|
||||||
rift.setSingleDestination(new EscapeDestination());
|
rift.setDestination(new EscapeDestination());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean canBePlacedOnRift() {
|
@Override public boolean canBePlacedOnRift() {
|
||||||
|
|
|
@ -25,9 +25,6 @@ public interface IRiftProvider<T extends TileEntityRift> extends ITileEntityProv
|
||||||
if (world.isRemote) return;
|
if (world.isRemote) return;
|
||||||
T rift = getRift(world, pos, state);
|
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
|
// Configure the rift to its default functionality
|
||||||
setupRift(rift);
|
setupRift(rift);
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.text.TextComponentString;
|
import net.minecraft.util.text.TextComponentString;
|
||||||
import net.minecraftforge.common.DimensionManager;
|
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;
|
private final List<String> aliases;
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ public class CommandDimTeleport extends CommandBase { // TODO: localization
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(MinecraftServer server, ICommandSender sender, String[] args) throws CommandException {
|
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) {
|
if (args.length < 4 || args.length > 6) {
|
||||||
sender.sendMessage(new TextComponentString("[DimDoors] Usage: /" + getUsage(sender)));
|
sender.sendMessage(new TextComponentString("[DimDoors] Usage: /" + getUsage(sender)));
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
package org.dimdev.dimdoors.shared.commands;
|
package org.dimdev.dimdoors.shared.commands;
|
||||||
|
|
||||||
import net.minecraft.util.EnumFacing;
|
|
||||||
import org.dimdev.dimdoors.DimDoors;
|
import org.dimdev.dimdoors.DimDoors;
|
||||||
import org.dimdev.dimdoors.shared.*;
|
|
||||||
import org.dimdev.dimdoors.shared.pockets.*;
|
import org.dimdev.dimdoors.shared.pockets.*;
|
||||||
import org.dimdev.dimdoors.shared.rifts.TileEntityRift;
|
import org.dimdev.dimdoors.shared.rifts.TileEntityRift;
|
||||||
import org.dimdev.ddutils.Location;
|
import org.dimdev.ddutils.Location;
|
||||||
|
@ -48,7 +46,7 @@ public class CommandPocket extends CommandBase {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(MinecraftServer server, ICommandSender sender, String[] args) throws CommandException { // TODO: more pocket commands (replace pocket, get ID, teleport to pocket, etc.)
|
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) {
|
if (args.length < 2 || args.length > 3) {
|
||||||
sender.sendMessage(new TextComponentString("[DimDoors] Usage: /" + getUsage(sender)));
|
sender.sendMessage(new TextComponentString("[DimDoors] Usage: /" + getUsage(sender)));
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -7,7 +7,6 @@ import org.dimdev.dimdoors.shared.blocks.BlockDimensionalDoorGold;
|
||||||
import org.dimdev.dimdoors.shared.blocks.ModBlocks;
|
import org.dimdev.dimdoors.shared.blocks.ModBlocks;
|
||||||
import org.dimdev.ddutils.I18nUtils;
|
import org.dimdev.ddutils.I18nUtils;
|
||||||
import net.minecraft.client.util.ITooltipFlag;
|
import net.minecraft.client.util.ITooltipFlag;
|
||||||
import net.minecraft.item.ItemDoor;
|
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
|
@ -65,7 +65,7 @@ public class ItemRiftSignature extends Item {
|
||||||
World sourceWorld = target.getLocation().getWorld();
|
World sourceWorld = target.getLocation().getWorld();
|
||||||
sourceWorld.setBlockState(target.getLocation().getPos(), ModBlocks.RIFT.getDefaultState());
|
sourceWorld.setBlockState(target.getLocation().getPos(), ModBlocks.RIFT.getDefaultState());
|
||||||
TileEntityRift rift1 = (TileEntityRift) target.getLocation().getTileEntity();
|
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.register();
|
||||||
rift1.setRotation(target.getYaw(), 0);
|
rift1.setRotation(target.getYaw(), 0);
|
||||||
}
|
}
|
||||||
|
@ -73,7 +73,7 @@ public class ItemRiftSignature extends Item {
|
||||||
// Place a rift at the target point
|
// Place a rift at the target point
|
||||||
world.setBlockState(pos, ModBlocks.RIFT.getDefaultState());
|
world.setBlockState(pos, ModBlocks.RIFT.getDefaultState());
|
||||||
TileEntityRift rift2 = (TileEntityRift) world.getTileEntity(pos);
|
TileEntityRift rift2 = (TileEntityRift) world.getTileEntity(pos);
|
||||||
rift2.setSingleDestination(new GlobalDestination(target.getLocation()));
|
rift2.setDestination(new GlobalDestination(target.getLocation()));
|
||||||
rift2.setRotation(player.rotationYaw, 0);
|
rift2.setRotation(player.rotationYaw, 0);
|
||||||
rift2.register();
|
rift2.register();
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,7 @@ public class ItemStabilizedRiftSignature extends Item { // TODO: common supercla
|
||||||
// Place a rift at the source point
|
// Place a rift at the source point
|
||||||
world.setBlockState(pos, ModBlocks.RIFT.getDefaultState());
|
world.setBlockState(pos, ModBlocks.RIFT.getDefaultState());
|
||||||
TileEntityRift rift2 = (TileEntityRift) world.getTileEntity(pos);
|
TileEntityRift rift2 = (TileEntityRift) world.getTileEntity(pos);
|
||||||
rift2.setSingleDestination(new GlobalDestination(target.getLocation()));
|
rift2.setDestination(new GlobalDestination(target.getLocation()));
|
||||||
rift2.setRotation(player.rotationYaw, 0);
|
rift2.setRotation(player.rotationYaw, 0);
|
||||||
rift2.register();
|
rift2.register();
|
||||||
|
|
||||||
|
|
|
@ -1,34 +1,37 @@
|
||||||
package org.dimdev.dimdoors.shared.pockets;
|
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.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import net.minecraft.nbt.*;
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.util.math.BlockPos;
|
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
|
@NBTSerializable public class Pocket implements INBTStorable { // TODO: better visibilities
|
||||||
|
|
||||||
@Saved @Getter /*package-private*/ int id;
|
@Saved @Getter protected int id;
|
||||||
@Saved @Getter /*package-private*/ int x; // Grid x TODO: rename to gridX and gridY
|
@Saved @Getter protected int x; // Grid x TODO: rename to gridX and gridY, or just convert to non-grid dependant coordinates
|
||||||
@Saved @Getter /*package-private*/ int z; // Grid y
|
@Saved @Getter protected 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 protected 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 protected VirtualLocation virtualLocation;
|
||||||
@Saved @Getter @Setter /*package-private*/ Location entrance;
|
@Saved @Getter @Setter protected Location entrance; // TODO: move this to the rift registry (pocketlib)
|
||||||
@Saved @Getter /*package-private*/ List<Location> riftLocations;
|
@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
|
@Getter int dim; // Not saved
|
||||||
|
|
||||||
|
@ -44,11 +47,12 @@ import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
// TODO: make these static?
|
// TODO: make these static?
|
||||||
@Override public void readFromNBT(NBTTagCompound nbt) { NBTUtils.readFromNBT(this, nbt); }
|
@Override public void readFromNBT(NBTTagCompound nbt) { NBTUtils.readFromNBT(this, nbt); }
|
||||||
|
|
||||||
@Override public NBTTagCompound writeToNBT(NBTTagCompound nbt) { return NBTUtils.writeToNBT(this, nbt); }
|
@Override public NBTTagCompound writeToNBT(NBTTagCompound nbt) { return NBTUtils.writeToNBT(this, nbt); }
|
||||||
|
|
||||||
boolean isInBounds(BlockPos pos) {
|
boolean isInBounds(BlockPos pos) {
|
||||||
// pocket bounds
|
// pocket bounds
|
||||||
int gridSize = PocketRegistry.getForDim(dim).getGridSize();
|
int gridSize = PocketRegistry.instance(dim).getGridSize();
|
||||||
int minX = x * gridSize;
|
int minX = x * gridSize;
|
||||||
int minZ = z * gridSize;
|
int minZ = z * gridSize;
|
||||||
int maxX = minX + (size + 1) * 16;
|
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
|
public void setup() { // Always call after creating a pocket except when building the pocket
|
||||||
List<TileEntityRift> rifts = getRifts();
|
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 (TileEntityRift rift : rifts) { // Find an entrance
|
||||||
for (WeightedRiftDestination weightedPocketEntranceDest : rift.getDestinations()) {
|
if (rift.getDestination() instanceof PocketEntranceDestination) {
|
||||||
if (weightedPocketEntranceDest.getDestination() instanceof PocketEntranceDestination) {
|
entranceIndexWeights.put(rift, ((PocketEntranceDestination) rift.getDestination()).getWeight());
|
||||||
entranceIndexWeights.put(index, weightedPocketEntranceDest.getWeight());
|
rift.markDirty();
|
||||||
rift.markDirty();
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entranceIndexWeights.size() == 0) return;
|
if (entranceIndexWeights.size() == 0) return;
|
||||||
int selectedEntranceIndex = MathUtils.weightedRandom(entranceIndexWeights);
|
TileEntityRift selectedEntrance = MathUtils.weightedRandom(entranceIndexWeights);
|
||||||
|
|
||||||
// Replace entrances with appropriate destinations
|
// Replace entrances with appropriate destinations
|
||||||
index = 0;
|
|
||||||
for (TileEntityRift rift : rifts) {
|
for (TileEntityRift rift : rifts) {
|
||||||
ListIterator<WeightedRiftDestination> destIterator = rift.getDestinations().listIterator();
|
RiftDestination dest = rift.getDestination();
|
||||||
while (destIterator.hasNext()) {
|
if (dest instanceof PocketEntranceDestination) {
|
||||||
WeightedRiftDestination wdest = destIterator.next();
|
if (rift == selectedEntrance) {
|
||||||
RiftDestination dest = wdest.getDestination();
|
entrance = new Location(rift.getWorld(), rift.getPos());
|
||||||
if (dest instanceof PocketEntranceDestination) {
|
PocketRegistry.instance(dim).markDirty();
|
||||||
destIterator.remove();
|
rift.setDestination(((PocketEntranceDestination) dest).getIfDestination());
|
||||||
if (index == selectedEntranceIndex) {
|
} else {
|
||||||
entrance = new Location(rift.getWorld(), rift.getPos());
|
rift.setDestination(((PocketEntranceDestination) dest).getOtherwiseDestination());
|
||||||
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++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// set virtual locations and register rifts
|
// register the rifts
|
||||||
for (TileEntityRift rift : rifts) {
|
for (TileEntityRift rift : rifts) {
|
||||||
rift.setVirtualLocation(virtualLocation);
|
|
||||||
rift.register();
|
rift.register();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void linkPocketTo(RiftDestination linkTo, RiftDestination oldDest, AvailableLink availableLink) {
|
public void linkPocketTo(RiftDestination linkTo, LinkProperties linkProperties) {
|
||||||
List<TileEntityRift> rifts = getRifts();
|
List<TileEntityRift> rifts = getRifts();
|
||||||
|
|
||||||
// Link pocket exits back
|
// Link pocket exits back
|
||||||
for (TileEntityRift rift : rifts) {
|
for (TileEntityRift rift : rifts) {
|
||||||
ListIterator<WeightedRiftDestination> destIterator = rift.getDestinations().listIterator();
|
RiftDestination dest = rift.getDestination();
|
||||||
while (destIterator.hasNext()) {
|
if (dest instanceof PocketExitDestination) {
|
||||||
WeightedRiftDestination wdest = destIterator.next();
|
if (linkProperties != null) rift.setProperties(linkProperties);
|
||||||
RiftDestination dest = wdest.getDestination();
|
rift.setDestination(linkTo);
|
||||||
if (dest instanceof PocketExitDestination) {
|
if (rift instanceof TileEntityEntranceRift && !rift.isAlwaysDelete()) {
|
||||||
destIterator.remove();
|
((TileEntityEntranceRift) rift).setPlaceRiftOnBreak(true); // We modified the door's state
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
rift.markDirty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void unlinkPocket() {
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
public BlockPos getOrigin() {
|
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?
|
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) {
|
public static Pocket generatePocketFromTemplate(int dim, PocketTemplate pocketTemplate, VirtualLocation virtualLocation) {
|
||||||
DimDoors.log.info("Generating pocket from template " + pocketTemplate.getName() + " at virtual location " + 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();
|
Pocket pocket = registry.newPocket();
|
||||||
pocketTemplate.place(pocket, 0); // TODO: config option for yBase
|
pocketTemplate.place(pocket);
|
||||||
pocket.setVirtualLocation(virtualLocation);
|
pocket.setVirtualLocation(virtualLocation);
|
||||||
return pocket;
|
return pocket;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ import org.dimdev.dimdoors.shared.world.ModDimensions;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import net.minecraft.entity.player.EntityPlayerMP;
|
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.MapStorage;
|
||||||
import net.minecraft.world.storage.WorldSavedData;
|
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";
|
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.
|
@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 maxPocketSize;
|
||||||
@Saved @Getter /*package-private*/ int privatePocketSize;
|
@Saved @Getter /*package-private*/ int privatePocketSize;
|
||||||
@Saved @Getter /*package-private*/ int publicPocketSize;
|
@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*/ Map<Integer, Pocket> pockets; // TODO: remove getter?
|
||||||
@Saved @Getter /*package-private*/ int nextID;
|
@Saved @Getter /*package-private*/ int nextID;
|
||||||
|
|
||||||
|
@ -44,7 +46,7 @@ import net.minecraft.world.storage.WorldSavedData;
|
||||||
super(s);
|
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!");
|
if (!ModDimensions.isDimDoorsPocketDimension(dim)) throw new UnsupportedOperationException("PocketRegistry is only available for pocket dimensions!");
|
||||||
|
|
||||||
MapStorage storage = WorldUtils.getWorld(dim).getPerWorldStorage();
|
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
|
// 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);
|
Integer id = privatePocketMap.get(playerUUID);
|
||||||
if (id == null) return -1;
|
if (id == null) return -1;
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getPrivatePocketOwner(int id) {
|
public UUID getPrivatePocketOwner(int id) {
|
||||||
return privatePocketMap.inverse().get(id);
|
return privatePocketMap.inverse().get(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPrivatePocketID(String playerUUID, int id) {
|
public void setPrivatePocketID(UUID playerUUID, int id) {
|
||||||
privatePocketMap.put(playerUUID, id);
|
privatePocketMap.put(playerUUID, id);
|
||||||
markDirty();
|
markDirty();
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,6 @@ import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.world.WorldServer;
|
import net.minecraft.world.WorldServer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author Robijnvogel
|
* @author Robijnvogel
|
||||||
*/
|
*/
|
||||||
@AllArgsConstructor @RequiredArgsConstructor// TODO: use @Builder?
|
@AllArgsConstructor @RequiredArgsConstructor// TODO: use @Builder?
|
||||||
|
@ -33,22 +32,23 @@ public class PocketTemplate {
|
||||||
|
|
||||||
public float getWeight(int depth) {
|
public float getWeight(int depth) {
|
||||||
if (depth < 0) return 100; // TODO: get rid of this later
|
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 < minDepth) return 0;
|
||||||
if (depth > maxDepth) return weights[weights.length - 1];
|
if (depth > maxDepth) return weights[weights.length - 1];
|
||||||
return weights[depth - minDepth];
|
return weights[depth - minDepth];
|
||||||
}
|
}
|
||||||
|
|
||||||
public void place(Pocket pocket, int yBase) {
|
public void place(Pocket pocket) {
|
||||||
pocket.setSize(size);
|
pocket.setSize(size);
|
||||||
int gridSize = PocketRegistry.getForDim(pocket.dim).getGridSize();
|
int gridSize = PocketRegistry.instance(pocket.dim).getGridSize();
|
||||||
int dim = pocket.dim;
|
int dim = pocket.dim;
|
||||||
int xBase = pocket.getX() * gridSize * 16;
|
int xBase = pocket.getX() * gridSize * 16;
|
||||||
|
int yBase = 0;
|
||||||
int zBase = pocket.getZ() * gridSize * 16;
|
int zBase = pocket.getZ() * gridSize * 16;
|
||||||
DimDoors.log.info("Placing new pocket using schematic " + schematic.schematicName + " at x = " + xBase + ", z = " + zBase);
|
DimDoors.log.info("Placing new pocket using schematic " + schematic.schematicName + " at x = " + xBase + ", z = " + zBase);
|
||||||
|
|
||||||
WorldServer world = WorldUtils.getWorld(dim);
|
WorldServer world = WorldUtils.getWorld(dim);
|
||||||
Schematic.place(schematic, world, xBase, yBase, zBase);
|
Schematic.place(schematic, world, xBase, 0, zBase);
|
||||||
|
|
||||||
// Set pocket riftLocations
|
// Set pocket riftLocations
|
||||||
pocket.riftLocations = new ArrayList<>();
|
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.math.MathUtils;
|
||||||
import org.dimdev.ddutils.schem.Schematic;
|
import org.dimdev.ddutils.schem.Schematic;
|
||||||
import com.google.gson.JsonArray;
|
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.BiMap;
|
||||||
import com.google.common.collect.HashBiMap;
|
import com.google.common.collect.HashBiMap;
|
||||||
import org.dimdev.ddutils.Location;
|
import org.dimdev.ddutils.Location;
|
||||||
|
import org.dimdev.ddutils.RGBA;
|
||||||
|
import org.dimdev.ddutils.RotatedLocation;
|
||||||
import org.dimdev.ddutils.nbt.INBTStorable;
|
import org.dimdev.ddutils.nbt.INBTStorable;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
import lombok.*; // Don't change import order! (Gradle bug): https://stackoverflow.com/questions/26557133/
|
import lombok.*; // Don't change import order! (Gradle bug): https://stackoverflow.com/questions/26557133/
|
||||||
|
import org.dimdev.dimdoors.shared.rifts.registry.RiftRegistry;
|
||||||
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
@Getter @EqualsAndHashCode @ToString
|
@EqualsAndHashCode @ToString
|
||||||
public abstract class RiftDestination implements INBTStorable {
|
public abstract class RiftDestination implements INBTStorable {
|
||||||
|
|
||||||
/*private*/ public static final BiMap<String, Class<? extends RiftDestination>> destinationRegistry = HashBiMap.create(); // TODO: move to RiftDestinationRegistry
|
public static final BiMap<String, Class<? extends RiftDestination>> destinationRegistry = HashBiMap.create(); // TODO: move to RiftDestinationRegistry
|
||||||
//private String type;
|
|
||||||
protected WeightedRiftDestination weightedDestination;
|
|
||||||
|
|
||||||
public RiftDestination() {
|
public RiftDestination() {}
|
||||||
//type = destinationRegistry.inverse().get(getClass());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static RiftDestination readDestinationNBT(NBTTagCompound nbt) {
|
public static RiftDestination readDestinationNBT(NBTTagCompound nbt) {
|
||||||
String type = nbt.getString("type");
|
String type = nbt.getString("type");
|
||||||
|
@ -28,7 +28,6 @@ public abstract class RiftDestination implements INBTStorable {
|
||||||
try {
|
try {
|
||||||
RiftDestination destination = destinationClass.getConstructor().newInstance();
|
RiftDestination destination = destinationClass.getConstructor().newInstance();
|
||||||
destination.readFromNBT(nbt);
|
destination.readFromNBT(nbt);
|
||||||
//destination.type = type;
|
|
||||||
return destination;
|
return destination;
|
||||||
} catch (NoSuchMethodException | IllegalAccessException e) {
|
} catch (NoSuchMethodException | IllegalAccessException e) {
|
||||||
throw new RuntimeException("The class registered for type " + type + " must have a public no-args constructor.", 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
|
@Override
|
||||||
public void readFromNBT(NBTTagCompound nbt) { }
|
public void readFromNBT(NBTTagCompound nbt) {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NBTTagCompound writeToNBT(NBTTagCompound nbt) {
|
public NBTTagCompound writeToNBT(NBTTagCompound nbt) {
|
||||||
|
@ -48,19 +47,30 @@ public abstract class RiftDestination implements INBTStorable {
|
||||||
return nbt;
|
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;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void register(TileEntityRift rift) {
|
public void register(Location location) {
|
||||||
Location loc = getReferencedRift(rift.getLocation());
|
RiftRegistry.instance().addLink(location, getFixedTarget(location));
|
||||||
if (loc != null) RiftRegistry.addLink(rift.getLocation(), loc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void unregister(TileEntityRift rift) {
|
public void unregister(Location location) {
|
||||||
Location loc = getReferencedRift(rift.getLocation());
|
RiftRegistry.instance().removeLink(location, getFixedTarget(location));
|
||||||
if (loc != null) RiftRegistry.removeLink(rift.getLocation(), loc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
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 lombok.Getter;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
|
@ -30,55 +13,53 @@ import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraftforge.fml.relauncher.Side;
|
import net.minecraftforge.fml.relauncher.Side;
|
||||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
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 javax.annotation.Nonnull;
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
@NBTSerializable public abstract class TileEntityRift extends TileEntity implements ITickable { // TODO: implement ITeleportSource and ITeleportDestination
|
@NBTSerializable public abstract class TileEntityRift extends TileEntity implements ITickable { // TODO: implement ITeleportSource and ITeleportDestination
|
||||||
|
|
||||||
@Saved@Getter protected VirtualLocation virtualLocation;
|
@Saved @Nonnull @Getter protected RiftDestination destination;
|
||||||
@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 relativeRotation;
|
||||||
@Saved @Getter protected boolean makeDestinationPermanent;
|
|
||||||
@Saved @Getter protected boolean preserveRotation;
|
|
||||||
@Saved @Getter protected float yaw;
|
@Saved @Getter protected float yaw;
|
||||||
@Saved @Getter protected float pitch;
|
@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 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 boolean forcedColor;
|
||||||
@Saved @Getter protected RGBA color = null; // TODO: update AnnotatedNBT to be able to save these
|
@Saved @Getter protected RGBA color = null;
|
||||||
@Saved @Getter protected Set<AvailableLink> availableLinks;
|
@Saved @Getter protected LinkProperties properties;
|
||||||
// TODO: option to convert to door on teleportTo?
|
|
||||||
|
|
||||||
protected boolean riftStateChanged; // not saved
|
protected boolean riftStateChanged; // not saved
|
||||||
|
|
||||||
public TileEntityRift() {
|
public TileEntityRift() {
|
||||||
destinations = new ArrayList<>();
|
relativeRotation = true;
|
||||||
makeDestinationPermanent = true;
|
|
||||||
preserveRotation = true;
|
|
||||||
pitch = 0;
|
pitch = 0;
|
||||||
alwaysDelete = false;
|
alwaysDelete = false;
|
||||||
chaosWeight = 1;
|
|
||||||
availableLinks = new HashSet<>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void copyFrom(TileEntityRift oldRift) {
|
public void copyFrom(TileEntityRift oldRift) {
|
||||||
virtualLocation = oldRift.virtualLocation;
|
relativeRotation = oldRift.relativeRotation;
|
||||||
destinations = oldRift.destinations;
|
|
||||||
makeDestinationPermanent = oldRift.makeDestinationPermanent;
|
|
||||||
preserveRotation = oldRift.preserveRotation;
|
|
||||||
yaw = oldRift.yaw;
|
yaw = oldRift.yaw;
|
||||||
pitch = oldRift.pitch;
|
pitch = oldRift.pitch;
|
||||||
chaosWeight = oldRift.chaosWeight;
|
properties = oldRift.properties;
|
||||||
if (oldRift.isFloating() != isFloating()) updateType();
|
if (oldRift.isFloating() != isFloating()) updateType();
|
||||||
|
|
||||||
markDirty();
|
markDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NBT
|
||||||
@Override public void readFromNBT(NBTTagCompound nbt) { super.readFromNBT(nbt); NBTUtils.readFromNBT(this, nbt); }
|
@Override public void readFromNBT(NBTTagCompound nbt) { super.readFromNBT(nbt); NBTUtils.readFromNBT(this, nbt); }
|
||||||
@Override public NBTTagCompound writeToNBT(NBTTagCompound nbt) {
|
|
||||||
nbt = super.writeToNBT(nbt);
|
@Override public NBTTagCompound writeToNBT(NBTTagCompound nbt) { nbt = super.writeToNBT(nbt); return NBTUtils.writeToNBT(this, nbt); }
|
||||||
return NBTUtils.writeToNBT(this, nbt);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NBTTagCompound getUpdateTag() {
|
public NBTTagCompound getUpdateTag() {
|
||||||
|
@ -101,6 +82,7 @@ import java.util.*;
|
||||||
deserializeNBT(pkt.getNbtCompound());
|
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)
|
// Use vanilla behavior of refreshing only when block changes, not state (otherwise, opening the door would destroy the tile entity)
|
||||||
@Override
|
@Override
|
||||||
|
@ -108,71 +90,30 @@ import java.util.*;
|
||||||
// newState is not accurate if we change the state during onBlockBreak
|
// newState is not accurate if we change the state during onBlockBreak
|
||||||
newSate = world.getBlockState(pos);
|
newSate = world.getBlockState(pos);
|
||||||
return oldState.getBlock() != newSate.getBlock() &&
|
return oldState.getBlock() != newSate.getBlock() &&
|
||||||
!(oldState.getBlock() instanceof BlockDimensionalDoor
|
!(oldState.getBlock() instanceof BlockDimensionalDoor
|
||||||
&& newSate.getBlock() instanceof BlockFloatingRift);
|
&& newSate.getBlock() instanceof BlockFloatingRift);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Modification functions
|
// 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) {
|
public void setRotation(float yaw, float pitch) {
|
||||||
this.yaw = yaw;
|
this.yaw = yaw;
|
||||||
this.pitch = pitch;
|
this.pitch = pitch;
|
||||||
preserveRotation = false;
|
|
||||||
markDirty();
|
markDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clearRotation() {
|
public void setRelativeRotation(boolean relativeRotation) {
|
||||||
preserveRotation = true;
|
this.relativeRotation = relativeRotation;
|
||||||
}
|
|
||||||
|
|
||||||
public void addWeightedDestination(WeightedRiftDestination destination) {
|
|
||||||
destinations.add(destination);
|
|
||||||
markDirty();
|
markDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addDestination(RiftDestination destination, float weight, int group) {
|
public void setDestination(RiftDestination destination) {
|
||||||
riftStateChanged = true;
|
if (this.destination != null) {
|
||||||
destinations.add(new WeightedRiftDestination(destination, weight, group));
|
this.destination.unregister(new Location(world, pos));
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
destinations.clear();
|
this.destination = destination;
|
||||||
markDirty();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSingleDestination(RiftDestination destination) {
|
|
||||||
clearDestinations();
|
|
||||||
addDestination(destination, 1, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setChaosWeight(float chaosWeight) {
|
|
||||||
this.chaosWeight = chaosWeight;
|
|
||||||
markDirty();
|
markDirty();
|
||||||
|
updateColor();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setColor(RGBA color) {
|
public void setColor(RGBA color) {
|
||||||
|
@ -181,15 +122,9 @@ import java.util.*;
|
||||||
markDirty();
|
markDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void registerAvailableLink(AvailableLink link) {
|
public void setProperties(LinkProperties properties) {
|
||||||
if (!isRegistered()) return;
|
this.properties = properties;
|
||||||
RiftRegistry.addAvailableLink(getLocation(), link);
|
updateProperties();
|
||||||
}
|
|
||||||
|
|
||||||
public void addAvailableLink(AvailableLink link) {
|
|
||||||
availableLinks.add(link);
|
|
||||||
link.rift = getLocation();
|
|
||||||
registerAvailableLink(link);
|
|
||||||
markDirty();
|
markDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,107 +133,65 @@ import java.util.*;
|
||||||
markDirty();
|
markDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void makeDestinationPermanent(WeightedRiftDestination weightedDestination, Location destLoc) {
|
// Registry TODO: merge most of these into one single updateRegistry() method
|
||||||
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
|
|
||||||
public boolean isRegistered() {
|
public boolean isRegistered() {
|
||||||
return world != null && RiftRegistry.getRiftInfo(new Location(world, pos)) != null;
|
return RiftRegistry.instance().isRiftAt(new Location(world, pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void register() {
|
public void register() {
|
||||||
if (isRegistered()) return;
|
if (isRegistered()) return;
|
||||||
Location loc = new Location(world, pos);
|
Location loc = new Location(world, pos);
|
||||||
RiftRegistry.addRift(loc);
|
RiftRegistry.instance().addRift(loc);
|
||||||
RiftRegistry.getRiftInfo(loc).virtualLocation = virtualLocation;
|
destination.register(new Location(world, pos));
|
||||||
for (WeightedRiftDestination weightedDest : destinations) {
|
updateProperties();
|
||||||
weightedDest.getDestination().register(this);
|
|
||||||
}
|
|
||||||
for (AvailableLink link : availableLinks) {
|
|
||||||
registerAvailableLink(link);
|
|
||||||
}
|
|
||||||
updateColor();
|
updateColor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void updateProperties() {
|
||||||
|
if (isRegistered()) RiftRegistry.instance().setProperties(new Location(world, pos), properties);
|
||||||
|
markDirty();
|
||||||
|
}
|
||||||
|
|
||||||
public void unregister() {
|
public void unregister() {
|
||||||
if (!isRegistered()) return;
|
if (isRegistered()) {
|
||||||
RiftRegistry.removeRift(new Location(world, pos)); // TODO: unregister destinations
|
RiftRegistry.instance().removeRift(new Location(world, pos));
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// TODO: inform pocket that entrances was destroyed (we'll probably need an isPrivate field on the pocket)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateType() {
|
public void updateType() {
|
||||||
if (!isRegistered()) return;
|
if (!isRegistered()) return;
|
||||||
RiftRegistry.getRiftInfo(getLocation()).isEntrance = !isFloating();
|
Rift rift = RiftRegistry.instance().getRift(new Location(world, pos));
|
||||||
RiftRegistry.getForDim(getLocation().getDim()).markDirty();
|
rift.isFloating = isFloating();
|
||||||
|
rift.markDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void destinationGone(Location loc) {
|
public void targetGone(Location loc) {
|
||||||
ListIterator<WeightedRiftDestination> wdestIterator = destinations.listIterator();
|
if (!destination.keepAfterTargetGone(loc)) setDestination(null);
|
||||||
while (wdestIterator.hasNext()) {
|
updateColor();
|
||||||
WeightedRiftDestination wdest = wdestIterator.next();
|
}
|
||||||
RiftDestination dest = wdest.getDestination();
|
|
||||||
if (loc.equals(dest.getReferencedRift(getLocation()))) {
|
public void sourceGone(Location loc) {
|
||||||
wdestIterator.remove(); // TODO: unregister*
|
updateColor();
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Teleport logic
|
// Teleport logic
|
||||||
public boolean teleport(Entity entity) {
|
public boolean teleport(Entity entity) {
|
||||||
riftStateChanged = false;
|
riftStateChanged = false;
|
||||||
|
|
||||||
// Check that the rift has destinations
|
// Check that the rift has as destination
|
||||||
if (destinations.size() == 0) {
|
if (destination == null) {
|
||||||
DimDoors.chat(entity, "This rift has no destinations!");
|
DimDoors.chat(entity, "This rift has no destination!");
|
||||||
return false;
|
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
|
// Attempt a teleport
|
||||||
try {
|
try {
|
||||||
if (weightedDestination.getDestination().teleport(this, entity)) {
|
if (destination.teleport(new RotatedLocation(new Location(world, pos), yaw, pitch), entity)) {
|
||||||
// Set last used rift if necessary
|
// Set last used rift for players (don't set for other entities to avoid filling the registry too much)
|
||||||
// TODO: What about player-owned entities? We should store their exit rift separately to avoid having problems if they enter different rifts
|
// TODO: it should maybe be set for some non-player entities too
|
||||||
// TODO: use entity UUID rather than player UUID!
|
if (!ModDimensions.isDimDoorsPocketDimension(WorldUtils.getDim(world)) && entity instanceof EntityPlayer) {
|
||||||
if (entity instanceof EntityPlayer && !ModDimensions.isDimDoorsPocketDimension(WorldUtils.getDim(world))) {
|
RiftRegistry.instance().setOverworldRift(entity.getUniqueID(), new Location(world, pos));
|
||||||
RiftRegistry.setOverworldRift(EntityUtils.getEntityOwnerUUID(entity), new Location(world, pos));
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -309,45 +202,30 @@ import java.util.*;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void teleportTo(Entity entity) { // TODO: new velocity angle if !preserveRotation?
|
public void teleportTo(Entity entity, float fromYaw, float fromPitch) {
|
||||||
float newYaw = entity.rotationYaw;
|
if (relativeRotation) {
|
||||||
float newPitch = entity.rotationYaw;
|
TeleportUtils.teleport(entity, new Location(world, pos), yaw + entity.rotationYaw - fromYaw, pitch + entity.rotationPitch - fromPitch);
|
||||||
if (!preserveRotation) {
|
} else {
|
||||||
newYaw = yaw;
|
TeleportUtils.teleport(entity, new Location(world, pos), yaw, pitch);
|
||||||
newPitch = 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()) {
|
if (!isRegistered()) {
|
||||||
color = new RGBA(0, 0, 0, 1);
|
color = new RGBA(0, 0, 0, 1);
|
||||||
return;
|
} else if (destination == null) {
|
||||||
}
|
|
||||||
if (destinations.size() == 0) {
|
|
||||||
color = new RGBA(0.7f, 0.7f, 0.7f, 1);
|
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 {
|
} 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
|
// Info
|
||||||
protected abstract boolean isFloating(); // TODO: make non-abstract?
|
protected abstract boolean isFloating();
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 net.minecraft.world.World;
|
||||||
import org.dimdev.annotatednbt.NBTSerializable;
|
import org.dimdev.annotatednbt.NBTSerializable;
|
||||||
import org.dimdev.annotatednbt.Saved;
|
import org.dimdev.annotatednbt.Saved;
|
||||||
|
import org.dimdev.ddutils.Location;
|
||||||
|
import org.dimdev.ddutils.RotatedLocation;
|
||||||
import org.dimdev.ddutils.WorldUtils;
|
import org.dimdev.ddutils.WorldUtils;
|
||||||
import org.dimdev.ddutils.math.MathUtils;
|
import org.dimdev.ddutils.math.MathUtils;
|
||||||
import org.dimdev.ddutils.nbt.NBTUtils;
|
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.blocks.ModBlocks;
|
||||||
import org.dimdev.dimdoors.shared.pockets.Pocket;
|
import org.dimdev.dimdoors.shared.pockets.Pocket;
|
||||||
import org.dimdev.dimdoors.shared.pockets.PocketGenerator;
|
import org.dimdev.dimdoors.shared.pockets.PocketGenerator;
|
||||||
import org.dimdev.dimdoors.shared.rifts.AvailableLink;
|
import org.dimdev.dimdoors.shared.rifts.*;
|
||||||
import org.dimdev.dimdoors.shared.rifts.RiftDestination;
|
import org.dimdev.dimdoors.shared.rifts.registry.LinkProperties;
|
||||||
import org.dimdev.dimdoors.shared.rifts.RiftRegistry;
|
import org.dimdev.dimdoors.shared.rifts.registry.Rift;
|
||||||
import org.dimdev.dimdoors.shared.rifts.TileEntityRift;
|
import org.dimdev.dimdoors.shared.rifts.registry.RiftRegistry;
|
||||||
import org.dimdev.dimdoors.shared.tileentities.TileEntityFloatingRift;
|
import org.dimdev.dimdoors.shared.tileentities.TileEntityFloatingRift;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
@ -30,7 +32,7 @@ import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
@Getter @AllArgsConstructor @Builder(toBuilder = true) @ToString
|
@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 float newRiftWeight;
|
||||||
@Saved protected double weightMaximum;
|
@Saved protected double weightMaximum;
|
||||||
@Saved protected double coordFactor;
|
@Saved protected double coordFactor;
|
||||||
|
@ -39,7 +41,7 @@ import java.util.UUID;
|
||||||
@Saved protected Set<Integer> acceptedGroups; // TODO: this should be immutable
|
@Saved protected Set<Integer> acceptedGroups; // TODO: this should be immutable
|
||||||
@Saved protected boolean noLink;
|
@Saved protected boolean noLink;
|
||||||
@Builder.Default @Saved protected boolean noLinkBack;
|
@Builder.Default @Saved protected boolean noLinkBack;
|
||||||
@Builder.Default @Saved protected UUID linkId = UUID.randomUUID();
|
// TODO: better depth calculation
|
||||||
|
|
||||||
public AvailableLinkDestination() {}
|
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 NBTTagCompound writeToNBT(NBTTagCompound nbt) { nbt = super.writeToNBT(nbt); return NBTUtils.writeToNBT(this, nbt); }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean teleport(TileEntityRift rift, Entity entity) {
|
public boolean teleport(RotatedLocation location, Entity entity) {
|
||||||
if (rift.getVirtualLocation() == null) return false;
|
VirtualLocation virtualLocationHere = VirtualLocation.fromLocation(location.getLocation());
|
||||||
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);
|
|
||||||
|
|
||||||
for (AvailableLink link : RiftRegistry.getAvailableLinks()) {
|
Map<Location, Float> riftWeights = new HashMap<>();
|
||||||
RiftRegistry.RiftInfo otherRift = RiftRegistry.getRiftInfo(link.rift);
|
if (newRiftWeight > 0) riftWeights.put(null, newRiftWeight);
|
||||||
double otherWeight = otherRift.isEntrance ? link.entranceWeight : link.floatingWeight;
|
|
||||||
if (otherWeight == 0 || Sets.intersection(acceptedGroups, link.groups).isEmpty()) continue;
|
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)
|
// Calculate the distance as sqrt((coordFactor * coordDistance)^2 + (depthFactor * depthDifference)^2)
|
||||||
if (otherRift.virtualLocation == null || link.linksRemaining == 0) continue;
|
if (otherVirtualLocation == null || otherRift.properties.linksRemaining == 0) continue;
|
||||||
double depthDifference = otherRift.virtualLocation.getDepth() - rift.getVirtualLocation().getDepth();
|
double depthDifference = otherVirtualLocation.getDepth() - virtualLocationHere.getDepth();
|
||||||
double coordDistance = Math.sqrt(sq(rift.getVirtualLocation().getX() - otherRift.virtualLocation.getX())
|
double coordDistance = Math.sqrt(sq(otherVirtualLocation.getX() - virtualLocationHere.getX())
|
||||||
+ sq(rift.getVirtualLocation().getZ() - otherRift.virtualLocation.getZ()));
|
+ sq(otherVirtualLocation.getZ() - virtualLocationHere.getZ()));
|
||||||
double depthFactor = depthDifference > 0 ? positiveDepthFactor : negativeDepthFactor; // TODO: (|depthDiff| - depthFavor * depthDiff)?
|
double depthFactor = depthDifference > 0 ? positiveDepthFactor : negativeDepthFactor;
|
||||||
double distance = sq(coordFactor * coordDistance) + sq(depthFactor * depthDifference);
|
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
|
// 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.
|
// 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
|
// 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);
|
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;
|
Location selectedLink;
|
||||||
if (possibleDestWeightMap.size() == 0) {
|
if (riftWeights.size() == 0) {
|
||||||
if (newRiftWeight == -1) {
|
if (newRiftWeight == -1) {
|
||||||
selectedLink = null;
|
selectedLink = null;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
selectedLink = MathUtils.weightedRandom(possibleDestWeightMap);
|
selectedLink = MathUtils.weightedRandom(riftWeights);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if we have to generate a new rift
|
// Check if we have to generate a new rift
|
||||||
|
@ -121,10 +121,10 @@ import java.util.UUID;
|
||||||
depth /= depth > 0 ? positiveDepthFactor : negativeDepthFactor;
|
depth /= depth > 0 ? positiveDepthFactor : negativeDepthFactor;
|
||||||
double x = Math.cos(theta) * Math.cos(phi) * distance / coordFactor;
|
double x = Math.cos(theta) * Math.cos(phi) * distance / coordFactor;
|
||||||
double z = Math.cos(theta) * Math.sin(phi) * distance / coordFactor;
|
double z = Math.cos(theta) * Math.sin(phi) * distance / coordFactor;
|
||||||
VirtualLocation virtualLocation = new VirtualLocation(rift.getVirtualLocation().getDim(),
|
VirtualLocation virtualLocation = new VirtualLocation(virtualLocationHere.getDim(),
|
||||||
rift.getVirtualLocation().getX() + (int) Math.round(x),
|
virtualLocationHere.getX() + (int) Math.round(x),
|
||||||
rift.getVirtualLocation().getZ() + (int) Math.round(z),
|
virtualLocationHere.getZ() + (int) Math.round(z),
|
||||||
rift.getVirtualLocation().getDepth() + (int) Math.round(depth));
|
virtualLocationHere.getDepth() + (int) Math.round(depth));
|
||||||
|
|
||||||
if (virtualLocation.getDepth() <= 0) {
|
if (virtualLocation.getDepth() <= 0) {
|
||||||
// This will lead to the overworld
|
// 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()));
|
BlockPos pos = world.getTopSolidOrLiquidBlock(new BlockPos(virtualLocation.getX(), 0, virtualLocation.getZ()));
|
||||||
world.setBlockState(pos, ModBlocks.RIFT.getDefaultState());
|
world.setBlockState(pos, ModBlocks.RIFT.getDefaultState());
|
||||||
|
|
||||||
|
TileEntityRift thisRift = (TileEntityRift) location.getLocation().getTileEntity();
|
||||||
TileEntityFloatingRift riftEntity = (TileEntityFloatingRift) world.getTileEntity(pos);
|
TileEntityFloatingRift riftEntity = (TileEntityFloatingRift) world.getTileEntity(pos);
|
||||||
// TODO: Should the rift not be configured like the other link
|
// TODO: Should the rift not be configured like the other link
|
||||||
rift.markDirty();
|
riftEntity.setProperties(thisRift.getProperties().toBuilder().linksRemaining(1).id(UUID.randomUUID()).build());
|
||||||
AvailableLink newLink = thisLink.toBuilder().linksRemaining(0).id(UUID.randomUUID()).build();
|
|
||||||
riftEntity.addAvailableLink(newLink);
|
if (!noLinkBack && !riftEntity.getProperties().oneWay) linkRifts(selectedLink, location.getLocation());
|
||||||
if (!noLinkBack) riftEntity.addDestination(new GlobalDestination(rift.getLocation()), 1, 0, toBuilder().linkId(newLink.id).build());
|
if (!noLink) linkRifts(location.getLocation(), selectedLink);
|
||||||
if (!noLink) rift.makeDestinationPermanent(weightedDestination, riftEntity.getLocation());
|
riftEntity.teleportTo(entity, thisRift.getYaw(), thisRift.getPitch());
|
||||||
riftEntity.teleportTo(entity);
|
|
||||||
} else {
|
} else {
|
||||||
// Make a new dungeon pocket
|
// Make a new dungeon pocket
|
||||||
//Pocket pocket = PocketGenerator.generateDungeonPocket(virtualLocation);
|
//Pocket pocket = PocketGenerator.generateDungeonPocket(virtualLocation);
|
||||||
Pocket pocket = PocketGenerator.generatePublicPocket(virtualLocation);
|
Pocket pocket = PocketGenerator.generatePublicPocket(virtualLocation);
|
||||||
pocket.setup();
|
pocket.setup();
|
||||||
rift.markDirty();
|
|
||||||
AvailableLink newLink = thisLink.toBuilder().linksRemaining(0).build();
|
// Link the pocket back
|
||||||
pocket.linkPocketTo(new GlobalDestination(/*noLinkBack ? null :*/ rift.getLocation()), toBuilder().linkId(newLink.id).build(), newLink); // TODO: linkId
|
TileEntityRift thisRift = (TileEntityRift) location.getLocation().getTileEntity();
|
||||||
if (!noLink) rift.makeDestinationPermanent(weightedDestination, pocket.getEntrance());
|
TileEntityRift riftEntity = (TileEntityRift) pocket.getEntrance().getTileEntity();
|
||||||
((TileEntityRift) pocket.getEntrance().getTileEntity()).teleportTo(entity);
|
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 {
|
} else {
|
||||||
// An existing rift was selected
|
// An existing rift was selected
|
||||||
TileEntityRift riftEntity = (TileEntityRift) selectedLink.rift.getTileEntity();
|
TileEntityRift riftEntity = (TileEntityRift) selectedLink.getTileEntity();
|
||||||
|
|
||||||
selectedLink.linksRemaining--;
|
// Link the rifts if necessary and teleport the entity
|
||||||
RiftRegistry.getRegistry(riftEntity.getLocation()).markDirty();
|
if (!noLink) linkRifts(location.getLocation(), selectedLink);
|
||||||
|
if (!noLinkBack && !riftEntity.getProperties().oneWay) linkRifts(selectedLink, location.getLocation());
|
||||||
// Link the selected rift back if necessary
|
riftEntity.teleportTo(entity, location.getYaw(), location.getPitch());
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
return true;
|
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; }
|
private double sq(double a) { return a * a; }
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
package org.dimdev.dimdoors.shared.rifts.destinations;
|
package org.dimdev.dimdoors.shared.rifts.destinations;
|
||||||
|
|
||||||
|
import org.dimdev.ddutils.RotatedLocation;
|
||||||
import org.dimdev.dimdoors.DimDoors;
|
import org.dimdev.dimdoors.DimDoors;
|
||||||
import org.dimdev.dimdoors.shared.rifts.RiftDestination;
|
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.rifts.TileEntityRift;
|
||||||
import org.dimdev.dimdoors.shared.world.ModDimensions;
|
import org.dimdev.dimdoors.shared.world.ModDimensions;
|
||||||
import org.dimdev.dimdoors.shared.world.limbodimension.WorldProviderLimbo;
|
import org.dimdev.dimdoors.shared.world.limbodimension.WorldProviderLimbo;
|
||||||
|
@ -15,6 +16,8 @@ import lombok.ToString;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
@Getter @AllArgsConstructor @Builder(toBuilder = true) @ToString
|
@Getter @AllArgsConstructor @Builder(toBuilder = true) @ToString
|
||||||
public class EscapeDestination extends RiftDestination {
|
public class EscapeDestination extends RiftDestination {
|
||||||
//public EscapeDestination() {}
|
//public EscapeDestination() {}
|
||||||
|
@ -31,14 +34,14 @@ public class EscapeDestination extends RiftDestination {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean teleport(TileEntityRift rift, Entity entity) {
|
public boolean teleport(RotatedLocation loc, Entity entity) {
|
||||||
if (!ModDimensions.isDimDoorsPocketDimension(entity.world)) {
|
if (!ModDimensions.isDimDoorsPocketDimension(entity.world)) {
|
||||||
DimDoors.chat(entity, "Can't escape from a non-pocket dimension!");
|
DimDoors.chat(entity, "Can't escape from a non-pocket dimension!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
String uuid = entity.getCachedUniqueIdString();
|
UUID uuid = entity.getUniqueID();
|
||||||
if (uuid != null) {
|
if (uuid != null) {
|
||||||
Location destLoc = RiftRegistry.getOverworldRift(uuid);
|
Location destLoc = RiftRegistry.instance().getOverworldRift(uuid);
|
||||||
if (destLoc != null && destLoc.getTileEntity() instanceof TileEntityRift) {
|
if (destLoc != null && destLoc.getTileEntity() instanceof TileEntityRift) {
|
||||||
//TeleportUtils.teleport(entity, new VirtualLocation(destLoc, rift.virtualLocation.getDepth()).projectToWorld()); // TODO
|
//TeleportUtils.teleport(entity, new VirtualLocation(destLoc, rift.virtualLocation.getDepth()).projectToWorld()); // TODO
|
||||||
// TODO
|
// TODO
|
||||||
|
|
|
@ -7,6 +7,7 @@ import lombok.Getter;
|
||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
|
import org.dimdev.ddutils.RotatedLocation;
|
||||||
import org.dimdev.ddutils.nbt.NBTUtils;
|
import org.dimdev.ddutils.nbt.NBTUtils;
|
||||||
import org.dimdev.annotatednbt.Saved;
|
import org.dimdev.annotatednbt.Saved;
|
||||||
import org.dimdev.annotatednbt.NBTSerializable;
|
import org.dimdev.annotatednbt.NBTSerializable;
|
||||||
|
@ -15,7 +16,7 @@ import org.dimdev.dimdoors.shared.rifts.TileEntityRift;
|
||||||
|
|
||||||
@Getter @AllArgsConstructor @Builder(toBuilder = true) @ToString
|
@Getter @AllArgsConstructor @Builder(toBuilder = true) @ToString
|
||||||
@NBTSerializable public class GlobalDestination extends RiftDestination { // TODO: location directly in nbt like minecraft?
|
@NBTSerializable public class GlobalDestination extends RiftDestination { // TODO: location directly in nbt like minecraft?
|
||||||
@Saved @Getter protected Location loc;
|
@Saved protected Location loc;
|
||||||
|
|
||||||
public GlobalDestination() {}
|
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 NBTTagCompound writeToNBT(NBTTagCompound nbt) { nbt = super.writeToNBT(nbt); return NBTUtils.writeToNBT(this, nbt); }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean teleport(TileEntityRift rift, Entity entity) {
|
public boolean teleport(RotatedLocation loc, Entity entity) {
|
||||||
((TileEntityRift) loc.getTileEntity()).teleportTo(entity);
|
((TileEntityRift) this.loc.getTileEntity()).teleportTo(entity, loc.getYaw(), loc.getPitch());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Location getReferencedRift(Location rift) {
|
public Location getFixedTarget(Location location) {
|
||||||
return loc;
|
return loc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package org.dimdev.dimdoors.shared.rifts.destinations;
|
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.RiftDestination;
|
||||||
import org.dimdev.dimdoors.shared.rifts.TileEntityRift;
|
|
||||||
import org.dimdev.dimdoors.shared.world.limbodimension.WorldProviderLimbo;
|
import org.dimdev.dimdoors.shared.world.limbodimension.WorldProviderLimbo;
|
||||||
import org.dimdev.ddutils.TeleportUtils;
|
import org.dimdev.ddutils.TeleportUtils;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
|
@ -27,7 +27,7 @@ public class LimboDestination extends RiftDestination {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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?
|
TeleportUtils.teleport(entity, WorldProviderLimbo.getLimboSkySpawn(entity)); // TODO: do we really want to spam Limbo with items?
|
||||||
return false;
|
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;
|
package org.dimdev.dimdoors.shared.rifts.destinations;
|
||||||
|
|
||||||
import org.dimdev.ddutils.Location;
|
import org.dimdev.ddutils.Location;
|
||||||
|
import org.dimdev.ddutils.RotatedLocation;
|
||||||
import org.dimdev.ddutils.nbt.NBTUtils;
|
import org.dimdev.ddutils.nbt.NBTUtils;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Builder;
|
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 NBTTagCompound writeToNBT(NBTTagCompound nbt) { nbt = super.writeToNBT(nbt); return NBTUtils.writeToNBT(this, nbt); }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean teleport(TileEntityRift rift, Entity entity) {
|
public boolean teleport(RotatedLocation loc, Entity entity) {
|
||||||
((TileEntityRift) rift.getWorld().getTileEntity(pos)).teleportTo(entity);
|
((TileEntityRift) loc.getLocation().getWorld().getTileEntity(pos)).teleportTo(entity, loc.getYaw(), loc.getPitch());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Location getReferencedRift(Location rift) {
|
public Location getFixedTarget(Location location) {
|
||||||
return new Location(rift.getDim(), pos);
|
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;
|
package org.dimdev.dimdoors.shared.rifts.destinations;
|
||||||
|
|
||||||
|
import org.dimdev.ddutils.RotatedLocation;
|
||||||
import org.dimdev.ddutils.nbt.NBTUtils;
|
import org.dimdev.ddutils.nbt.NBTUtils;
|
||||||
import org.dimdev.annotatednbt.Saved;
|
import org.dimdev.annotatednbt.Saved;
|
||||||
import org.dimdev.annotatednbt.NBTSerializable;
|
import org.dimdev.annotatednbt.NBTSerializable;
|
||||||
|
@ -12,17 +13,13 @@ import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
import org.dimdev.dimdoors.shared.rifts.RiftDestination;
|
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
|
@Getter @AllArgsConstructor @Builder(toBuilder = true) @ToString
|
||||||
@NBTSerializable public class PocketEntranceDestination extends RiftDestination {
|
@NBTSerializable public class PocketEntranceDestination extends RiftDestination { // TODO: not exactly a destination
|
||||||
@Saved protected float weight;
|
@Builder.Default @Saved protected float weight = 1;
|
||||||
@Saved @SuppressWarnings({"UnusedAssignment", "RedundantSuppression"}) @Builder.Default protected List<WeightedRiftDestination> ifDestinations = new LinkedList<>(); // TODO addIfDestination method in builder
|
@Saved protected RiftDestination ifDestination;
|
||||||
@Saved @SuppressWarnings({"UnusedAssignment", "RedundantSuppression"}) @Builder.Default protected List<WeightedRiftDestination> otherwiseDestinations = new LinkedList<>(); // TODO addOtherwiseDestination method in builder
|
@Saved protected RiftDestination otherwiseDestination;
|
||||||
|
@Saved boolean hasBeenChosen;
|
||||||
|
|
||||||
public PocketEntranceDestination() {}
|
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 NBTTagCompound writeToNBT(NBTTagCompound nbt) { nbt = super.writeToNBT(nbt); return NBTUtils.writeToNBT(this, nbt); }
|
||||||
|
|
||||||
@Override
|
@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.");
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package org.dimdev.dimdoors.shared.rifts.destinations;
|
package org.dimdev.dimdoors.shared.rifts.destinations;
|
||||||
|
|
||||||
|
import org.dimdev.ddutils.RotatedLocation;
|
||||||
import org.dimdev.dimdoors.DimDoors;
|
import org.dimdev.dimdoors.DimDoors;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Builder;
|
import lombok.Builder;
|
||||||
|
@ -9,10 +10,9 @@ import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
import org.dimdev.dimdoors.shared.rifts.RiftDestination;
|
import org.dimdev.dimdoors.shared.rifts.RiftDestination;
|
||||||
import org.dimdev.dimdoors.shared.rifts.TileEntityRift;
|
|
||||||
|
|
||||||
@Getter @AllArgsConstructor @Builder(toBuilder = true) @ToString
|
@Getter @AllArgsConstructor @Builder(toBuilder = true) @ToString
|
||||||
public class PocketExitDestination extends RiftDestination {
|
public class PocketExitDestination extends RiftDestination { // TODO: not exactly a destination
|
||||||
//public PocketExitDestination() {}
|
//public PocketExitDestination() {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -27,7 +27,7 @@ public class PocketExitDestination extends RiftDestination {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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.");
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
package org.dimdev.dimdoors.shared.rifts.destinations;
|
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.DimDoors;
|
||||||
|
import org.dimdev.dimdoors.shared.VirtualLocation;
|
||||||
import org.dimdev.dimdoors.shared.pockets.Pocket;
|
import org.dimdev.dimdoors.shared.pockets.Pocket;
|
||||||
import org.dimdev.dimdoors.shared.pockets.PocketGenerator;
|
import org.dimdev.dimdoors.shared.pockets.PocketGenerator;
|
||||||
import org.dimdev.dimdoors.shared.pockets.PocketRegistry;
|
import org.dimdev.dimdoors.shared.pockets.PocketRegistry;
|
||||||
import org.dimdev.dimdoors.shared.rifts.RiftDestination;
|
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.rifts.TileEntityRift;
|
||||||
import org.dimdev.dimdoors.shared.world.ModDimensions;
|
import org.dimdev.dimdoors.shared.world.ModDimensions;
|
||||||
import org.dimdev.ddutils.EntityUtils;
|
import org.dimdev.ddutils.EntityUtils;
|
||||||
|
@ -17,51 +20,51 @@ import lombok.ToString;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
@Getter @AllArgsConstructor @Builder(toBuilder = true) @ToString
|
@Getter @AllArgsConstructor @Builder(toBuilder = true) @ToString
|
||||||
public class PrivateDestination extends RiftDestination {
|
public class PrivateDestination extends RiftDestination {
|
||||||
//public PrivateDestination() {}
|
//public PrivateDestination() {}
|
||||||
|
|
||||||
@Override
|
@Override public void readFromNBT(NBTTagCompound nbt) { super.readFromNBT(nbt); }
|
||||||
public void readFromNBT(NBTTagCompound nbt) {
|
@Override public NBTTagCompound writeToNBT(NBTTagCompound nbt) { nbt = super.writeToNBT(nbt); return nbt; }
|
||||||
super.readFromNBT(nbt);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NBTTagCompound writeToNBT(NBTTagCompound nbt) {
|
public boolean teleport(RotatedLocation loc, Entity entity) {
|
||||||
nbt = super.writeToNBT(nbt);
|
UUID uuid = EntityUtils.getEntityOwnerUUID(entity);
|
||||||
return nbt;
|
VirtualLocation virtualLocation = VirtualLocation.fromLocation(loc.getLocation());
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean teleport(TileEntityRift rift, Entity entity) {
|
|
||||||
String uuid = EntityUtils.getEntityOwnerUUID(entity);
|
|
||||||
if (uuid != null) {
|
if (uuid != null) {
|
||||||
PocketRegistry privatePocketRegistry = PocketRegistry.getForDim(ModDimensions.getPrivateDim());
|
PocketRegistry privatePocketRegistry = PocketRegistry.instance(ModDimensions.getPrivateDim());
|
||||||
RiftRegistry privateRiftRegistry = RiftRegistry.getForDim(ModDimensions.getPrivateDim());
|
|
||||||
Pocket pocket = privatePocketRegistry.getPocket(privatePocketRegistry.getPrivatePocketID(uuid));
|
Pocket pocket = privatePocketRegistry.getPocket(privatePocketRegistry.getPrivatePocketID(uuid));
|
||||||
if (pocket == null) { // generate the private pocket and get its entrances
|
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();
|
pocket.setup();
|
||||||
privatePocketRegistry.setPrivatePocketID(uuid, pocket.getId());
|
privatePocketRegistry.setPrivatePocketID(uuid, pocket.getId());
|
||||||
((TileEntityRift) pocket.getEntrance().getTileEntity()).teleportTo(entity);
|
((TileEntityRift) pocket.getEntrance().getTileEntity()).teleportTo(entity, loc.getYaw(), loc.getPitch());
|
||||||
privateRiftRegistry.setPrivatePocketExit(uuid, rift.getLocation());
|
RiftRegistry.instance().setLastPrivatePocketExit(uuid, loc.getLocation());
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} 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) 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
|
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!");
|
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();
|
pocket.setup();
|
||||||
privatePocketRegistry.setPrivatePocketID(uuid, pocket.getId());
|
privatePocketRegistry.setPrivatePocketID(uuid, pocket.getId());
|
||||||
destLoc = pocket.getEntrance();
|
destLoc = pocket.getEntrance();
|
||||||
}
|
}
|
||||||
((TileEntityRift) destLoc.getTileEntity()).teleportTo(entity);
|
((TileEntityRift) destLoc.getTileEntity()).teleportTo(entity, loc.getYaw(), loc.getPitch());
|
||||||
privateRiftRegistry.setPrivatePocketExit(uuid, rift.getLocation());
|
RiftRegistry.instance().setLastPrivatePocketExit(uuid, loc.getLocation());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return false; // TODO: There should be a way to get other entities into your private pocket, though. Add API for other mods.
|
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;
|
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.AllArgsConstructor;
|
||||||
import lombok.Builder;
|
import lombok.Builder;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
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
|
@Getter @AllArgsConstructor @Builder(toBuilder = true) @ToString
|
||||||
public class PrivatePocketExitDestination extends RiftDestination { // TODO: merge into PocketExit or Escape?
|
public class PrivatePocketExitDestination extends RiftDestination {
|
||||||
//public PrivatePocketExitDestination() {}
|
//public PrivatePocketExitDestination() {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -35,15 +35,14 @@ public class PrivatePocketExitDestination extends RiftDestination { // TODO: mer
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean teleport(TileEntityRift rift, Entity entity) {
|
public boolean teleport(RotatedLocation loc, Entity entity) {
|
||||||
Location destLoc;
|
Location destLoc;
|
||||||
String uuid = EntityUtils.getEntityOwnerUUID(entity);
|
UUID uuid = EntityUtils.getEntityOwnerUUID(entity);
|
||||||
if (uuid != null) {
|
if (uuid != null) {
|
||||||
PocketRegistry privatePocketRegistry = PocketRegistry.getForDim(ModDimensions.getPrivateDim());
|
PocketRegistry privatePocketRegistry = PocketRegistry.instance(ModDimensions.getPrivateDim());
|
||||||
RiftRegistry privateRiftRegistry = RiftRegistry.getForDim(ModDimensions.getPrivateDim());
|
destLoc = RiftRegistry.instance().getPrivatePocketExit(uuid);
|
||||||
destLoc = privateRiftRegistry.getPrivatePocketExit(uuid);
|
if (loc.getLocation().getWorld().provider instanceof WorldProviderPersonalPocket && privatePocketRegistry.getPrivatePocketID(uuid) == privatePocketRegistry.posToID(loc.getLocation().getPos())) {
|
||||||
if (rift.getWorld().provider instanceof WorldProviderPersonalPocket && privatePocketRegistry.getPrivatePocketID(uuid) == privatePocketRegistry.posToID(rift.getPos())) {
|
RiftRegistry.instance().setLastPrivatePocketEntrance(uuid, loc.getLocation()); // Remember which exit was used for next time the pocket is entered
|
||||||
privateRiftRegistry.setPrivatePocketEntrance(uuid, rift.getLocation()); // Remember which exit was used for next time the pocket is entered
|
|
||||||
}
|
}
|
||||||
if (destLoc == null || !(destLoc.getTileEntity() instanceof TileEntityRift)) {
|
if (destLoc == null || !(destLoc.getTileEntity() instanceof TileEntityRift)) {
|
||||||
if (destLoc == null) {
|
if (destLoc == null) {
|
||||||
|
@ -54,7 +53,7 @@ public class PrivatePocketExitDestination extends RiftDestination { // TODO: mer
|
||||||
TeleportUtils.teleport(entity, WorldProviderLimbo.getLimboSkySpawn(entity));
|
TeleportUtils.teleport(entity, WorldProviderLimbo.getLimboSkySpawn(entity));
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
((TileEntityRift) destLoc.getTileEntity()).teleportTo(entity);
|
((TileEntityRift) destLoc.getTileEntity()).teleportTo(entity, loc.getYaw(), loc.getPitch());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -63,14 +62,15 @@ public class PrivatePocketExitDestination extends RiftDestination { // TODO: mer
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void register(TileEntityRift rift) {
|
public void register(Location location) {
|
||||||
PocketRegistry privatePocketRegistry = PocketRegistry.getForDim(rift.getLocation().getDim());
|
super.register(location);
|
||||||
Pocket pocket = privatePocketRegistry.getPocketAt(rift.getPos());
|
PocketRegistry privatePocketRegistry = PocketRegistry.instance(location.getDim());
|
||||||
String uuid = privatePocketRegistry.getPrivatePocketOwner(pocket.getId());
|
Pocket pocket = privatePocketRegistry.getPocketAt(location.getPos());
|
||||||
if (uuid != null) {
|
RiftRegistry.instance().addPocketEntrance(pocket, location);
|
||||||
RiftRegistry.getForDim(ModDimensions.getPrivateDim()).addPrivatePocketEntrance(uuid, rift.getLocation());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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;
|
package org.dimdev.dimdoors.shared.rifts.destinations;
|
||||||
|
|
||||||
import org.dimdev.ddutils.Location;
|
import org.dimdev.ddutils.Location;
|
||||||
|
import org.dimdev.ddutils.RotatedLocation;
|
||||||
import org.dimdev.ddutils.nbt.NBTUtils;
|
import org.dimdev.ddutils.nbt.NBTUtils;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Builder;
|
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 NBTTagCompound writeToNBT(NBTTagCompound nbt) { nbt = super.writeToNBT(nbt); return NBTUtils.writeToNBT(this, nbt); }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean teleport(TileEntityRift rift, Entity entity) {
|
public boolean teleport(RotatedLocation loc, Entity entity) {
|
||||||
rift.getWorld().getTileEntity(rift.getPos().add(offset));
|
((TileEntityRift) loc.getLocation().getWorld().getTileEntity(loc.getLocation().getPos().add(offset))).teleportTo(entity, loc.getPitch(), loc.getYaw());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Location getReferencedRift(Location rift) {
|
public Location getFixedTarget(Location location) {
|
||||||
return new Location(rift.getDim(), rift.getPos().add(offset));
|
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.*;
|
||||||
import lombok.experimental.Wither;
|
import lombok.experimental.Wither;
|
||||||
|
@ -14,7 +14,7 @@ import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
@NBTSerializable @AllArgsConstructor @NoArgsConstructor @EqualsAndHashCode @Builder(toBuilder = true) @ToString
|
@NBTSerializable @AllArgsConstructor @NoArgsConstructor @EqualsAndHashCode @Builder(toBuilder = true) @ToString
|
||||||
public class AvailableLink implements INBTStorable {
|
public class LinkProperties implements INBTStorable {
|
||||||
@Wither public Location rift;
|
@Wither public Location rift;
|
||||||
|
|
||||||
@Saved @Builder.Default public UUID id = UUID.randomUUID();
|
@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 @Builder.Default public Set<Integer> groups = new HashSet<>();
|
||||||
@Saved public UUID replaceDestination;
|
@Saved public UUID replaceDestination;
|
||||||
@Saved @Builder.Default public int linksRemaining = 1;
|
@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 void readFromNBT(NBTTagCompound nbt) { NBTUtils.readFromNBT(this, nbt); }
|
||||||
@Override public NBTTagCompound writeToNBT(NBTTagCompound nbt) { return NBTUtils.writeToNBT(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.PocketEntranceDestination;
|
||||||
import org.dimdev.dimdoors.shared.rifts.destinations.PocketExitDestination;
|
import org.dimdev.dimdoors.shared.rifts.destinations.PocketExitDestination;
|
||||||
import org.dimdev.dimdoors.shared.rifts.destinations.PrivatePocketExitDestination;
|
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.dimdoors.shared.tileentities.TileEntityEntranceRift;
|
||||||
import org.dimdev.ddutils.schem.Schematic;
|
import org.dimdev.ddutils.schem.Schematic;
|
||||||
import net.minecraft.block.BlockDoor;
|
import net.minecraft.block.BlockDoor;
|
||||||
|
@ -30,10 +31,7 @@ import java.io.DataOutputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Robijnvogel
|
* @author Robijnvogel
|
||||||
|
@ -158,10 +156,15 @@ public final class PocketSchematicGenerator {
|
||||||
// Generate the rift TileEntities
|
// Generate the rift TileEntities
|
||||||
schematic.tileEntities = new ArrayList<>();
|
schematic.tileEntities = new ArrayList<>();
|
||||||
TileEntityEntranceRift rift = (TileEntityEntranceRift) doorBlock.createTileEntity(null, doorBlock.getDefaultState());
|
TileEntityEntranceRift rift = (TileEntityEntranceRift) doorBlock.createTileEntity(null, doorBlock.getDefaultState());
|
||||||
rift.setSingleDestination(PocketEntranceDestination.builder()
|
rift.setDestination(PocketEntranceDestination.builder()
|
||||||
.ifDestinations(Collections.singletonList(new WeightedRiftDestination(exitDest, 1, 0)))
|
.ifDestination(exitDest)
|
||||||
|
.build());
|
||||||
|
rift.setProperties(LinkProperties.builder()
|
||||||
|
.groups(Collections.singleton(1))
|
||||||
|
.linksRemaining(1)
|
||||||
|
.entranceWeight(chaosWeight)
|
||||||
|
.floatingWeight(chaosWeight)
|
||||||
.build());
|
.build());
|
||||||
rift.setChaosWeight(chaosWeight);
|
|
||||||
|
|
||||||
rift.setPlaceRiftOnBreak(true);
|
rift.setPlaceRiftOnBreak(true);
|
||||||
NBTTagCompound tileNBT = rift.serializeNBT();
|
NBTTagCompound tileNBT = rift.serializeNBT();
|
||||||
|
|
|
@ -4,7 +4,6 @@ import org.dimdev.dimdoors.shared.entities.EntityMonolith;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraft.world.biome.Biome;
|
import net.minecraft.world.biome.Biome;
|
||||||
import net.minecraft.world.biome.BiomeDecorator;
|
|
||||||
import net.minecraft.world.chunk.ChunkPrimer;
|
import net.minecraft.world.chunk.ChunkPrimer;
|
||||||
import net.minecraftforge.fml.relauncher.Side;
|
import net.minecraftforge.fml.relauncher.Side;
|
||||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package org.dimdev.dimdoors.shared.world.pocketdimension;
|
package org.dimdev.dimdoors.shared.world.pocketdimension;
|
||||||
|
|
||||||
import org.dimdev.dimdoors.shared.entities.EntityMonolith;
|
|
||||||
import net.minecraft.init.Blocks;
|
import net.minecraft.init.Blocks;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
Loading…
Add table
Reference in a new issue