Fixes to teleportation logic

This commit is contained in:
Runemoro 2017-12-26 04:17:24 -05:00
parent ffd8c6ed3c
commit 07d6e48647
20 changed files with 209 additions and 69 deletions

View file

@ -8,6 +8,7 @@ import com.zixiken.dimdoors.shared.items.ModItems;
import com.zixiken.dimdoors.shared.world.gateways.GatewayGenerator;
import lombok.Getter;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.util.text.TextComponentString;
@ -78,7 +79,7 @@ public class DimDoors {
return !isClient();
}
public static void chat(EntityPlayer player, String text) {
player.sendMessage(new TextComponentString("[DimDoors] " + text));
public static void chat(Entity entity, String text) {
entity.sendMessage(new TextComponentString("[DimDoors] " + text));
}
}

View file

@ -12,13 +12,10 @@ import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
import scala.actors.threadpool.Arrays;
/**
*
* @author Robijnvogel
*/
public final class DDConfig {
public static final boolean HAVE_CONFIG_DEFAULTS_BEEN_CHECKED_FOR_CORRECTNESS = false; //@todo check this at each non-alpha release. This field does not have a use in the mod itself, but should ensure that the developers of this mod, don't forget to resetToConfigDefaults the config defaults to the right values before releasing a non-alpha release
public static File configurationFolder;
@Getter private static int pocketGridSize = 32;
@Getter private static int maxPocketSize = 15;

View file

@ -2,32 +2,21 @@ package com.zixiken.dimdoors.shared;
import com.zixiken.dimdoors.DimDoors;
import com.zixiken.dimdoors.shared.pockets.PocketRegistry;
import com.zixiken.dimdoors.shared.rifts.RiftRegistry;
import com.zixiken.dimdoors.shared.world.DimDoorDimensions;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.util.DamageSource;
import net.minecraft.world.World;
import net.minecraftforge.event.entity.EntityEvent;
import net.minecraftforge.event.entity.EntityJoinWorldEvent;
import net.minecraftforge.event.entity.living.LivingHurtEvent;
import net.minecraftforge.fml.common.eventhandler.EventPriority;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.PlayerEvent;
public final class EventHandler {
@SubscribeEvent
public static void onPlayerJoinWorld(EntityJoinWorldEvent event) {
Entity entity = event.getEntity();
if(entity instanceof EntityPlayer && !entity.world.isRemote) { // check that it's a player first to avoid calling String.contains for every entity
if (!DDConfig.HAVE_CONFIG_DEFAULTS_BEEN_CHECKED_FOR_CORRECTNESS && !DimDoors.VERSION.contains("a")) { // default values were not checked in non-alpha version
EntityPlayer player = (EntityPlayer) entity;
DimDoors.chat(player, "The default values for the config files for this non-alpha version of DimDoors have not been sufficiently checked on correctness. Please notify the developer about this ONLY IF no newer version of this mod is available.");
}
}
}
@SubscribeEvent(priority = EventPriority.LOWEST) // don't let other mods do something based on the event
@SubscribeEvent(priority = EventPriority.HIGHEST) // don't let other mods do something based on the event
public static void onLivingHurt(LivingHurtEvent event) {
Entity entity = event.getEntity();
if (entity.dimension == DimDoorDimensions.limbo.getId() && event.getSource() == DamageSource.FALL) {
@ -50,4 +39,11 @@ public final class EventHandler {
}
}
}
@SubscribeEvent(priority=EventPriority.LOWEST)
public static void onDimensionChange(PlayerEvent.PlayerChangedDimensionEvent event) {
if (DimDoorDimensions.isPocketDimension(event.fromDim) && !DimDoorDimensions.isPocketDimension(event.toDim)) {
RiftRegistry.setOverworldRift(event.player.getCachedUniqueIdString(), null);
}
}
}

View file

@ -68,6 +68,7 @@ public class VirtualLocation { // TODO: use BlockPos/Location
return virtualLocation;
}
// TODO: world-seed based transformations and pocket selections?
public VirtualLocation transformDepth(int depth) { // TODO: Config option for block ratio between depths (see video of removed features)
Random random = new Random();
int depthDiff = Math.abs(this.depth - depth);
@ -78,6 +79,20 @@ public class VirtualLocation { // TODO: use BlockPos/Location
return new VirtualLocation(getDim(), getPos().offset(EnumFacing.EAST, xOffset).offset(EnumFacing.SOUTH, zOffset), depth);
}
public VirtualLocation randomTransformDepth() {
float r = new Random().nextFloat();
int newDepth;
if (r > 0.9) { // TODO: per-rift probabilities
newDepth = depth - 1;
} else if (r > 0.75) {
newDepth = depth;
} else {
newDepth = depth + 1;
}
if (newDepth < 1) newDepth = 1;
return transformDepth(newDepth);
}
public Location projectToWorld() {
return transformDepth(0).location;
}

View file

@ -33,7 +33,7 @@ public class BlockDimensionalDoorPersonal extends BlockDimensionalDoor {
if (rift.getWorld().provider instanceof WorldProviderPersonalPocket) {
destination = PrivatePocketExitDestination.builder().build(); // exit
} else {
destination = PrivateDestination.builder().build(); // entrance
destination = PrivateDestination.builder().build(); // entrances
}
rift.setSingleDestination(destination);
rift.setChaosWeight(0); // TODO: generated schematic exits too

View file

@ -6,7 +6,7 @@ import net.minecraft.block.material.Material;
import net.minecraft.item.Item;
import net.minecraft.util.ResourceLocation;
public class BlockDimensionalDoorTransient extends BlockDimensionalDoor { // TODO: convert to a more general entrance block (like nether portals)
public class BlockDimensionalDoorTransient extends BlockDimensionalDoor { // TODO: convert to a more general entrances block (like nether portals)
public static final String ID = "transient_dimensional_door";

View file

@ -21,7 +21,7 @@ public class Pocket { // TODO: better visibilities
@Getter private int z; // Grid y
@Getter @Setter private int size; // In chunks TODO: non chunk-based size, better bounds such as minX, minZ, maxX, maxZ, etc.
@Getter @Setter private VirtualLocation virtualLocation; // The non-pocket dimension from which this dungeon was created
@Getter @Setter Location entrance; // TODO: multiple entrances
@Getter @Setter Location entrance;
@Getter List<Location> riftLocations;
@Getter int dimID; // Not saved
@ -161,7 +161,9 @@ public class Pocket { // TODO: better visibilities
if (dest instanceof PocketExitDestination) {
destIterator.remove();
destIterator.add(new WeightedRiftDestination(linkTo, wdest.getWeight(), wdest.getGroup(), dest));
if (rift instanceof TileEntityEntranceRift) ((TileEntityEntranceRift) rift).setPlaceRiftOnBreak(true);
if (rift instanceof TileEntityEntranceRift && !rift.isAlwaysDelete()) {
((TileEntityEntranceRift) rift).setPlaceRiftOnBreak(true); // We modified the door's state
}
rift.markDirty();
}
}

View file

@ -1,5 +1,7 @@
package com.zixiken.dimdoors.shared.pockets;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import com.zixiken.dimdoors.shared.DDConfig;
import ddutils.math.GridUtils;
import com.zixiken.dimdoors.DimDoors;
@ -19,7 +21,7 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.world.storage.MapStorage;
import net.minecraft.world.storage.WorldSavedData;
public class PocketRegistry extends WorldSavedData {
public class PocketRegistry extends WorldSavedData { // TODO: unregister pocket entrances, private pocket entrances/exits
private static final String DATA_NAME = DimDoors.MODID + "_pockets";
@Getter private static final int DATA_VERSION = 0; // IMPORTANT: Update this and upgradeRegistry when making changes.
@ -28,7 +30,7 @@ public class PocketRegistry extends WorldSavedData {
@Getter private int maxPocketSize;
@Getter private int privatePocketSize;
@Getter private int publicPocketSize;
private Map<String, Integer> privatePocketMap; // Player UUID -> Pocket ID, in pocket dim only
private BiMap<String, Integer> privatePocketMap; // Player UUID -> Pocket ID, in pocket dim only
@Getter private Map<Integer, Pocket> pockets; // TODO: remove getter?
@Getter private int nextID;
@ -66,7 +68,7 @@ public class PocketRegistry extends WorldSavedData {
nextID = 0;
pockets = new HashMap<>();
privatePocketMap = new HashMap<>();
privatePocketMap = HashBiMap.create();
}
@Override
@ -85,7 +87,7 @@ public class PocketRegistry extends WorldSavedData {
maxPocketSize = nbt.getInteger("maxPocketSize");
privatePocketSize = nbt.getInteger("privatePocketSize");
publicPocketSize = nbt.getInteger("publicPocketSize");
privatePocketMap = NBTUtils.readMapStringInteger(nbt.getCompoundTag("privatePocketMap"));
privatePocketMap = NBTUtils.readBiMapStringInteger(nbt.getCompoundTag("privatePocketMap"));
nextID = nbt.getInteger("nextID");
pockets = new HashMap<>();
@ -189,6 +191,10 @@ public class PocketRegistry extends WorldSavedData {
return id;
}
public String getPrivatePocketOwner(int id) {
return privatePocketMap.inverse().get(id);
}
public void setPrivatePocketID(String playerUUID, int id) {
privatePocketMap.put(playerUUID, id);
markDirty();

View file

@ -1,7 +1,10 @@
package com.zixiken.dimdoors.shared.rifts;
import ddutils.EntityUtils;
import com.zixiken.dimdoors.DimDoors;
import com.zixiken.dimdoors.shared.VirtualLocation;
import com.zixiken.dimdoors.shared.world.limbodimension.WorldProviderLimbo;
import ddutils.Location;
import ddutils.TeleportUtils;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
@ -25,14 +28,23 @@ public class EscapeDestination extends RiftDestination {
@Override
public boolean teleport(TileEntityRift rift, Entity entity) {
String uuid = EntityUtils.getEntityOwnerUUID(entity);
String uuid = entity.getCachedUniqueIdString();
if (uuid != null) {
Location destLoc = RiftRegistry.getOverworldRift(uuid);
RiftRegistry.setOverworldRift(uuid, null); // forget the last used escape rift
// TODO: teleport the player to random coordinates based on depth around destLoc
if (destLoc != null && destLoc.getTileEntity() instanceof TileEntityRift) {
TeleportUtils.teleport(entity, new VirtualLocation(destLoc, rift.virtualLocation.getDepth()).projectToWorld()); // TODO
return true;
} else {
return false; // Non-player/owned entity tried to escape/leave private pocket
if (destLoc == null) {
DimDoors.chat(entity, "You didn't use a rift to enter so you ended up in Limbo!"); // TODO: better messages, localization
} else {
DimDoors.chat(entity, "The rift you used to enter has closed so you ended up in Limbo!");
}
TeleportUtils.teleport(entity, WorldProviderLimbo.getLimboSkySpawn(entity)); // TODO: do we really want to spam limbo with items?
return true;
}
} else {
return false; // No escape info for that entity
}
}
}

View file

@ -1,5 +1,7 @@
package com.zixiken.dimdoors.shared.rifts;
import com.zixiken.dimdoors.shared.world.limbodimension.WorldProviderLimbo;
import ddutils.TeleportUtils;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
@ -23,6 +25,7 @@ public class LimboDestination extends RiftDestination {
@Override
public boolean teleport(TileEntityRift rift, Entity entity) {
throw new RuntimeException("Not yet implemented!");
TeleportUtils.teleport(entity, WorldProviderLimbo.getLimboSkySpawn(entity)); // TODO: do we really want to spam Limbo with items?
return false;
}
}

View file

@ -25,7 +25,7 @@ public class NewPublicDestination extends RiftDestination { // TODO: more config
@Override
public boolean teleport(TileEntityRift rift, Entity entity) {
Pocket pocket = PocketGenerator.generatePublicPocket(rift.virtualLocation != null ? rift.virtualLocation.toBuilder().depth(-1).build() : null); // TODO: random transform
Pocket pocket = PocketGenerator.generatePublicPocket(rift.virtualLocation != null ? rift.virtualLocation.randomTransformDepth() : null); // TODO: random transform
pocket.setup();
pocket.linkPocketTo(new GlobalDestination(rift.getLocation()));
rift.makeDestinationPermanent(weightedDestination, pocket.getEntrance());

View file

@ -65,7 +65,7 @@ public class PocketEntranceDestination extends RiftDestination {
@Override
public boolean teleport(TileEntityRift rift, Entity entity) {
if (entity instanceof EntityPlayer) DimDoors.chat((EntityPlayer) entity, "The entrance of this dungeon has not been linked. Either this is a bug or you are in dungeon-building mode.");
if (entity instanceof EntityPlayer) DimDoors.chat((EntityPlayer) entity, "The entrances of this dungeon has not been linked. Either this is a bug or you are in dungeon-building mode.");
return false;
}
}

View file

@ -1,5 +1,6 @@
package com.zixiken.dimdoors.shared.rifts;
import com.zixiken.dimdoors.DimDoors;
import com.zixiken.dimdoors.shared.pockets.Pocket;
import com.zixiken.dimdoors.shared.pockets.PocketGenerator;
import com.zixiken.dimdoors.shared.pockets.PocketRegistry;
@ -35,25 +36,27 @@ public class PrivateDestination extends RiftDestination {
PocketRegistry privatePocketRegistry = PocketRegistry.getForDim(DimDoorDimensions.getPrivateDimID());
RiftRegistry privateRiftRegistry = RiftRegistry.getForDim(DimDoorDimensions.getPrivateDimID());
Pocket pocket = privatePocketRegistry.getPocket(privatePocketRegistry.getPrivatePocketID(uuid));
if (pocket == null) { // generate the private pocket and get its entrance // TODO: use VirtualLocation.fromLoc vvv
pocket = PocketGenerator.generatePrivatePocket(rift.virtualLocation != null ? rift.virtualLocation.toBuilder().depth(-2).build() : null); // set to where the pocket was first created
if (pocket == null) { // generate the private pocket and get its entrances
pocket = PocketGenerator.generatePrivatePocket(rift.virtualLocation != null ? rift.virtualLocation.toBuilder().depth(-1).build() : null); // set to where the pocket was first created
pocket.setup();
privatePocketRegistry.setPrivatePocketID(uuid, pocket.getId());
((TileEntityRift) pocket.getEntrance().getTileEntity()).teleportTo(entity);
privateRiftRegistry.setPrivatePocketExit(uuid, rift.getLocation());
return true;
} else {
Location destLoc = privateRiftRegistry.getPrivatePocketEntrance(uuid); // get the last used entrance
if (destLoc == null) destLoc = pocket.getEntrance(); // if there's none, then set the target to the main entrance
if (destLoc == null) { // if the pocket entrance is gone, then create a new private pocket
pocket = PocketGenerator.generatePrivatePocket(rift.virtualLocation != null ? rift.virtualLocation.toBuilder().depth(-2).build() : null);
Location destLoc = privateRiftRegistry.getPrivatePocketEntrance(uuid); // get the last used entrances
if (destLoc == null) destLoc = pocket.getEntrance(); // if there's none, then set the target to the main entrances
if (destLoc == null) { // if the pocket entrances is gone, then create a new private pocket
DimDoors.log.info("All entrances are gone, creating a new private pocket!");
pocket = PocketGenerator.generatePrivatePocket(rift.virtualLocation != null ? rift.virtualLocation.toBuilder().depth(-1).build() : null);
pocket.setup();
privatePocketRegistry.setPrivatePocketID(uuid, pocket.getId());
destLoc = pocket.getEntrance();
}
((TileEntityRift) destLoc.getTileEntity()).teleportTo(entity);
privateRiftRegistry.setPrivatePocketExit(uuid, rift.getLocation());
return true;
}
// privateRiftRegistry.setPrivatePocketEntrance(uuid, null); // --forget the last entered entrance-- Actually, remember it. We'll eventually store it only in the rift registry, not in the pocket.
} else {
return false; // TODO: There should be a way to get other entities into your private pocket, though. Add API for other mods.
}

View file

@ -1,11 +1,14 @@
package com.zixiken.dimdoors.shared.rifts;
import com.zixiken.dimdoors.DimDoors;
import com.zixiken.dimdoors.shared.pockets.Pocket;
import com.zixiken.dimdoors.shared.pockets.PocketRegistry;
import com.zixiken.dimdoors.shared.world.DimDoorDimensions;
import com.zixiken.dimdoors.shared.world.limbodimension.WorldProviderLimbo;
import com.zixiken.dimdoors.shared.world.pocketdimension.WorldProviderPersonalPocket;
import ddutils.EntityUtils;
import ddutils.Location;
import ddutils.TeleportUtils;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
@ -29,25 +32,42 @@ public class PrivatePocketExitDestination extends RiftDestination { // TODO: mer
}
@Override
public boolean teleport(TileEntityRift rift, Entity entity) { // TODO: don't use overworld rift, use last used entrance rift
public boolean teleport(TileEntityRift rift, Entity entity) {
Location destLoc;
String uuid = EntityUtils.getEntityOwnerUUID(entity);
if (uuid != null) {
PocketRegistry privatePocketRegistry = PocketRegistry.getForDim(DimDoorDimensions.getPrivateDimID());
RiftRegistry privateRiftRegistry = RiftRegistry.getForDim(DimDoorDimensions.getPrivateDimID());
destLoc = RiftRegistry.getOverworldRift(uuid);
RiftRegistry.setOverworldRift(uuid, null); // forget the last used overworld rift TODO: move this on dimension change event
destLoc = privateRiftRegistry.getPrivatePocketExit(uuid);
if (rift.getWorld().provider instanceof WorldProviderPersonalPocket && privatePocketRegistry.getPrivatePocketID(uuid) == privatePocketRegistry.posToID(rift.getPos())) {
privateRiftRegistry.setPrivatePocketEntrance(uuid, rift.getLocation()); // Remember which exit was used for next time the pocket is entered
}
if (destLoc == null || !(destLoc.getTileEntity() instanceof TileEntityRift)) {
if (entity instanceof EntityPlayer) DimDoors.chat((EntityPlayer) entity, "Either you did not enter using a rift or the rift you entered through no longer exists!");
return false; // TODO: send to limbo
if (destLoc == null) {
DimDoors.chat(entity, "You did not use a rift to enter this pocket so you ended up in limbo!");
} else {
DimDoors.chat(entity, "The rift you entered through no longer exists so you ended up in limbo!");
}
TeleportUtils.teleport(entity, WorldProviderLimbo.getLimboSkySpawn(entity));
return false;
} else {
((TileEntityRift) destLoc.getTileEntity()).teleportTo(entity);
return true;
}
} else {
return false; // Non-player/owned entity tried to escape/leave private pocket
}
((TileEntityRift) destLoc.getTileEntity()).teleportTo(entity);
return true;
}
@Override
public void register(TileEntityRift rift) {
PocketRegistry privatePocketRegistry = PocketRegistry.getForDim(rift.getLocation().getDim());
Pocket pocket = privatePocketRegistry.getPocketAt(rift.getPos());
String uuid = privatePocketRegistry.getPrivatePocketOwner(pocket.getId());
if (uuid != null) {
RiftRegistry.getForDim(DimDoorDimensions.getPrivateDimID()).addPrivatePocketEntrance(uuid, rift.getLocation());
}
}
// TODO: unregister
}

View file

@ -27,7 +27,9 @@ public class RiftRegistry extends WorldSavedData {
@Getter private static final int DATA_VERSION = 0; // IMPORTANT: Update this and upgradeRegistry when making changes.
@Getter private final Map<Location, RiftInfo> rifts = new HashMap<>(); // TODO: store relative locations too (better location class supporting relative, etc)
@Getter private final Map<String, Location> privatePocketEntrances = new HashMap<>(); // TODO: more general group-group linking
@Getter private final Map<String, Location> privatePocketEntrances = new HashMap<>(); // Player UUID -> last rift used to exit pocket TODO: split into PrivatePocketRiftRegistry subclass
@Getter private final Map<String, List<Location>> privatePocketEntranceLists = new HashMap<>(); // Player UUID -> private pocket entrances TODO: split into PrivatePocketRiftRegistry subclass
@Getter private final Map<String, Location> privatePocketExits = new HashMap<>(); // Player UUID -> last rift used to enter pocket
@Getter private final Map<String, Location> overworldRifts = new HashMap<>();
@Getter private int dim;
@ -169,6 +171,26 @@ public class RiftRegistry extends WorldSavedData {
privatePocketEntrances.put(uuid, rift);
}
NBTTagList privatePocketEntranceListsNBT = (NBTTagList) nbt.getTag("privatePocketEntranceLists");
for (NBTBase privatePocketEntranceListNBT : privatePocketEntranceListsNBT) { // TODO: move to NBTUtils
NBTTagCompound privatePocketEntranceListNBTC = (NBTTagCompound) privatePocketEntranceListNBT;
String uuid = privatePocketEntranceListNBTC.getString("uuid");
NBTTagList entrancesNBT = (NBTTagList) privatePocketEntranceListNBTC.getTag("locationList");
for (NBTBase entranceNBT : entrancesNBT) {
NBTTagCompound entranceNBTC = (NBTTagCompound) entranceNBT;
Location rift = Location.readFromNBT(entranceNBTC);
privatePocketEntranceLists.get(uuid).add(rift);
}
}
NBTTagList privatePocketExitsNBT = (NBTTagList) nbt.getTag("privatePocketExits");
for (NBTBase privatePocketExitNBT : privatePocketExitsNBT) { // TODO: move to NBTUtils
NBTTagCompound privatePocketExitNBTC = (NBTTagCompound) privatePocketExitNBT;
String uuid = privatePocketExitNBTC.getString("uuid");
Location rift = Location.readFromNBT(privatePocketExitNBTC.getCompoundTag("location"));
privatePocketExits.put(uuid, rift);
}
NBTTagList overworldRiftsNBT = (NBTTagList) nbt.getTag("overworldRifts");
for (NBTBase overworldRiftNBT : overworldRiftsNBT) { // TODO: move to NBTUtils
NBTTagCompound overworldRiftNBTC = (NBTTagCompound) overworldRiftNBT;
@ -178,8 +200,7 @@ public class RiftRegistry extends WorldSavedData {
}
}
@SuppressWarnings("unused")
private static boolean upgradeRegistry(NBTTagCompound nbt, int oldVersion) {
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
@ -218,6 +239,30 @@ public class RiftRegistry extends WorldSavedData {
}
nbt.setTag("privatePocketEntrances", privatePocketEntrancesNBT);
NBTTagList privatePocketEntranceListsNBT = new NBTTagList();
for (HashMap.Entry<String, List<Location>> privatePocketEntranceList : privatePocketEntranceLists.entrySet()) { // TODO: move to NBTUtils
if (privatePocketEntranceList.getValue() == null) continue;
NBTTagCompound privatePocketEntranceListNBT = new NBTTagCompound();
privatePocketEntranceListNBT.setString("uuid", privatePocketEntranceList.getKey());
NBTTagList entranceListNBT = new NBTTagList();
for (Location entrance : privatePocketEntranceList.getValue()) {
entranceListNBT.appendTag(Location.writeToNBT(entrance));
}
privatePocketEntranceListNBT.setTag("locationList", entranceListNBT);
privatePocketEntranceListsNBT.appendTag(privatePocketEntranceListNBT);
}
nbt.setTag("privatePocketEntranceLists", privatePocketEntranceListsNBT);
NBTTagList privatePocketExitsNBT = new NBTTagList();
for (HashMap.Entry<String, Location> privatePocketExit : privatePocketExits.entrySet()) { // TODO: move to NBTUtils
if (privatePocketExit.getValue() == null) continue;
NBTTagCompound privatePocketExitNBT = new NBTTagCompound();
privatePocketExitNBT.setString("uuid", privatePocketExit.getKey());
privatePocketExitNBT.setTag("location", Location.writeToNBT(privatePocketExit.getValue()));
privatePocketExitsNBT.appendTag(privatePocketExitNBT);
}
nbt.setTag("privatePocketExits", privatePocketExitsNBT);
NBTTagList overworldRiftsNBT = new NBTTagList();
for (HashMap.Entry<String, Location> overworldRift : overworldRifts.entrySet()) {
if (overworldRift.getValue() == null) continue;
@ -315,7 +360,18 @@ public class RiftRegistry extends WorldSavedData {
}
public Location getPrivatePocketEntrance(String playerUUID) {
return privatePocketEntrances.get(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);
entrance = entrances.get(0);
}
privatePocketEntrances.put(playerUUID, entrance);
return entrance;
}
public void addPrivatePocketEntrance(String playerUUID, Location rift) {
privatePocketEntranceLists.computeIfAbsent(playerUUID, k -> new ArrayList<>()).add(rift);
}
public void setPrivatePocketEntrance(String playerUUID, Location rift) {
@ -323,12 +379,29 @@ public class RiftRegistry extends WorldSavedData {
markDirty();
}
public Location getPrivatePocketExit(String playerUUID) {
return privatePocketExits.get(playerUUID);
}
public void setPrivatePocketExit(String playerUUID, Location 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) {
if (rift != null) {
getForDim(0).overworldRifts.put(playerUUID, rift);
} else {
getForDim(0).overworldRifts.remove(playerUUID);
}
getForDim(0).markDirty();
}

View file

@ -37,7 +37,7 @@ public abstract class TileEntityRift extends TileEntity implements ITickable { /
@Getter protected boolean preserveRotation;
@Getter protected float yaw;
@Getter protected float pitch;
@Getter protected boolean alwaysDelete; // Delete the rift when an entrance rift is broken even if the state was changed or destinations link there.
@Getter protected boolean alwaysDelete; // Delete the rift when an entrances rift is broken even if the state was changed or destinations link there.
@Getter protected float chaosWeight;
// TODO: option to convert to door on teleportTo?
@ -178,7 +178,7 @@ public abstract class TileEntityRift extends TileEntity implements ITickable { /
addDestination(destination, 1, 0);
}
public void setChaosWeight(int chaosWeight) {
public void setChaosWeight(float chaosWeight) {
this.chaosWeight = chaosWeight;
markDirty();
}
@ -226,7 +226,7 @@ public abstract class TileEntityRift extends TileEntity implements ITickable { /
pocketRegistry.markDirty();
}
}
// TODO: inform pocket that entrance was destroyed (we'll probably need an isPrivate field on the pocket)
// TODO: inform pocket that entrances was destroyed (we'll probably need an isPrivate field on the pocket)
}
public void updateAvailableLinks() { // Update available link info on rift type change or on virtualLocation change

View file

@ -2,11 +2,12 @@ package com.zixiken.dimdoors.shared.tools;
import com.zixiken.dimdoors.DimDoors;
import com.zixiken.dimdoors.server.DDProxyServer;
import com.zixiken.dimdoors.shared.blocks.BlockDimensionalDoor;
import com.zixiken.dimdoors.shared.blocks.BlockFabric;
import com.zixiken.dimdoors.shared.blocks.ModBlocks;
import com.zixiken.dimdoors.shared.rifts.*;
import com.zixiken.dimdoors.shared.tileentities.TileEntityEntranceRift;
import ddutils.schem.Schematic;
import net.minecraft.block.Block;
import net.minecraft.block.BlockDoor;
import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks;
@ -106,7 +107,7 @@ public final class PocketSchematicGenerator {
return schematics;
}
private static Schematic generatePocketSchematic(String baseName, int pocketSize, IBlockState outerWallBlockState, IBlockState innerWallBlockState, Block doorBlock, RiftDestination exitDest, float chaosWeight) {
private static Schematic generatePocketSchematic(String baseName, int pocketSize, IBlockState outerWallBlockState, IBlockState innerWallBlockState, BlockDimensionalDoor doorBlock, RiftDestination exitDest, float chaosWeight) {
int size = (pocketSize + 1) * 16 - 1; // -1 so that the door can be centered
// Set schematic info
@ -152,11 +153,13 @@ public final class PocketSchematicGenerator {
// Generate the rift TileEntities
schematic.tileEntities = new ArrayList<>();
TileEntityRift rift = (TileEntityRift) doorBlock.createTileEntity(null, doorBlock.getDefaultState());
TileEntityEntranceRift rift = (TileEntityEntranceRift) doorBlock.createTileEntity(null, doorBlock.getDefaultState());
rift.setSingleDestination(PocketEntranceDestination.builder()
.ifDestinations(Collections.singletonList(new WeightedRiftDestination(exitDest, 1, 0)))
.build());
rift.setChaosWeight(0);
rift.setChaosWeight(chaosWeight);
rift.setPlaceRiftOnBreak(true);
NBTTagCompound tileNBT = rift.serializeNBT();
tileNBT.setInteger("x", (size - 1) / 2);
tileNBT.setInteger("y", 5);

View file

@ -82,9 +82,9 @@ public class WorldProviderLimbo extends WorldProvider {
return new LimboGenerator(world, world.getSeed());
}
public static Location getLimboSkySpawn(EntityPlayer player) {
int x = (int) player.posX + MathHelper.clamp(player.world.rand.nextInt(), -100, 100); // TODO: -properties.LimboEntryRange, properties.LimboEntryRange);
int z = (int) player.posZ + MathHelper.clamp(player.world.rand.nextInt(), -100, 100); // TODO: -properties.LimboEntryRange, properties.LimboEntryRange);
public static Location getLimboSkySpawn(Entity entity) { // TODO: move this into projectToLimbo
int x = (int) entity.posX + MathHelper.clamp(entity.world.rand.nextInt(), -100, 100); // TODO: -properties.LimboEntryRange, properties.LimboEntryRange);
int z = (int) entity.posZ + MathHelper.clamp(entity.world.rand.nextInt(), -100, 100); // TODO: -properties.LimboEntryRange, properties.LimboEntryRange);
return new Location(DimDoorDimensions.limbo.getId(), x, 700, z);
}
@ -100,7 +100,6 @@ public class WorldProviderLimbo extends WorldProvider {
return DimDoorDimensions.limbo;
}
@SideOnly(Side.CLIENT)
@Override
public Vec3d getSkyColor(Entity cameraEntity, float partialTicks) {

View file

@ -52,7 +52,7 @@ public class Location implements Serializable {
}
public WorldServer getWorld() {
return DimensionManager.getWorld(dim);
return WorldUtils.getWorld(dim);
}
public static Location getLocation(TileEntity tileEntity) {

View file

@ -1,12 +1,14 @@
package ddutils.nbt;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.math.Vec3i;
import java.util.HashMap;
import java.util.Map;
public final class NBTUtils {
public final class NBTUtils { // TODO: make these fill rather than return a map
public static Map<String, Integer> readMapStringInteger(NBTTagCompound nbt) {
HashMap<String, Integer> map = new HashMap<>();
for (String str : nbt.getKeySet()) {
@ -15,6 +17,14 @@ public final class NBTUtils {
return map;
}
public static BiMap<String, Integer> readBiMapStringInteger(NBTTagCompound nbt) {
BiMap<String, Integer> map = HashBiMap.create();
for (String str : nbt.getKeySet()) {
map.put(str, nbt.getInteger(str));
}
return map;
}
public static NBTTagCompound writeMapStringInteger(Map<String, Integer> map) {
NBTTagCompound tagCompound = new NBTTagCompound();
for (String str : map.keySet()) {