Teleporting on ITickable.update()

-Delayed teleporting so it gets executed on DDTileEntityBase.update() to
prevent players from randomly not being moved
-Added some fields that need to be saved on worldSave
-Made Personal Pockets and Doors work
This commit is contained in:
Mathijs Riezebos 2017-04-08 00:08:30 +02:00
parent 937a008f95
commit d6f1b6743d
14 changed files with 113 additions and 35 deletions

View file

@ -28,7 +28,10 @@ public class DDConfig {
private static int privatePocketSize = 3;
private static int publicPocketSize = 2;
private static int baseDimID = 684;
private static String[] dungeonSchematicNames = {}; //@todo set default dungeon names
private static String[] dungeonSchematicNames = {
"defaultDungeonNormal",
"defaultDungeonNether"
}; //@todo set default dungeon names
private static int maxDungeonDepth = 8;
private static int owCoordinateOffsetBase = 64;
private static double owCoordinateOffsetPower = 1.3;

View file

@ -172,4 +172,8 @@ public class Pocket {
}
playerUUIDs.add(playerUUID);
}
public void setDepthZeroLocation(Location teleportTargetLocation) {
depthZeroLocation.loadfrom(teleportTargetLocation);
}
}

View file

@ -25,6 +25,7 @@ public class PocketRegistry {
public static final PocketRegistry INSTANCE = new PocketRegistry();
// Privates
//Need to be saved:
private int gridSize; //determines how much pockets in their dimension are spaced
private int maxPocketSize;
private int privatePocketSize;
@ -32,8 +33,7 @@ public class PocketRegistry {
private final Map<EnumPocketType, Integer> nextUnusedIDs;
private final Map<String, Integer> privatePockets; //maps the UUID's of players to their private pocket's ID (ID for EnumPocketType.PRIVATE in pocketLists)
private final Map<EnumPocketType, Map<Integer, Pocket>> pocketLists;
//when adding any new variables, don't forget to add them to the write and load functions
private final List<Map<Integer, Pocket>> pocketListsPerDepth;
private final List<Map<Integer, Pocket>> pocketListsPerDepth; //@todo not being used or saved yet.
// Methods
private PocketRegistry() {
@ -95,6 +95,13 @@ public class PocketRegistry {
}
}
}
if (nbt.hasKey("privatePockets")) {
NBTTagCompound privatePocketsTagCompound = nbt.getCompoundTag("privatePockets");
privatePockets.clear();
for (String UUID : privatePocketsTagCompound.getKeySet()) {
privatePockets.put(UUID, privatePocketsTagCompound.getInteger(UUID));
}
}
if (nbt.hasKey("pocketData")) {
NBTTagCompound pocketsTagCompound = nbt.getCompoundTag("pocketData");
pocketLists.clear();
@ -122,12 +129,18 @@ public class PocketRegistry {
nbt.setInteger("privatePocketSize", privatePocketSize);
nbt.setInteger("publicPocketSize", publicPocketSize);
NBTTagCompound nextUnusedIDTagCompound = new NBTTagCompound(); //@todo do not have to do this, since all pockets re-register on world-load
NBTTagCompound nextUnusedIDTagCompound = new NBTTagCompound();
for (EnumPocketType pocketType : nextUnusedIDs.keySet()) {
nextUnusedIDTagCompound.setInteger(pocketType.toString(), nextUnusedIDs.get(pocketType));
}
nbt.setTag("nextUnusedIDs", nextUnusedIDTagCompound);
NBTTagCompound privatePocketsTagCompound = new NBTTagCompound();
for (String UUID: privatePockets.keySet()) {
privatePocketsTagCompound.setInteger(UUID, privatePockets.get(UUID));
}
nbt.setTag("privatePockets", privatePocketsTagCompound);
NBTTagCompound pocketsTagCompound = new NBTTagCompound();
for (EnumPocketType pocketType : pocketLists.keySet()) {
Map<Integer, Pocket> pocketList = pocketLists.get(pocketType);
@ -178,7 +191,7 @@ public class PocketRegistry {
} else {
depth = 0;
}
//Fetching the pocket template
PocketTemplate pocketTemplate = getRandomPocketTemplate(typeID, depth, maxPocketSize);
@ -195,14 +208,20 @@ public class PocketRegistry {
} else { //PRIVATE
depthZeroLocation = origRiftLocation;
}
Pocket pocket = pocketTemplate.place(shortenedX, 0, shortenedZ, gridSize, dimID, nextUnusedIDs.get(typeID), depth, typeID, depthZeroLocation);
registerNewPocket(pocket, typeID);
return pocket;
}
public int getPrivateDimDoorID(String playerUUID) {
throw new UnsupportedOperationException("Not supported yet."); //@todo
if (!privatePockets.containsKey(playerUUID)) {
//generate a new private pocket
int doorID = getEntranceDoorIDOfNewPocket(EnumPocketType.PRIVATE, 0, new Location(0,0,0,0)); //Location doesn't really matter in this case
privatePockets.put(playerUUID, doorID);
return doorID;
}
return privatePockets.get(playerUUID);
}
private Location getGenerationlocation(int nextUnusedID, EnumPocketType typeID) {

View file

@ -86,6 +86,7 @@ public class PocketTemplate { //there is exactly one pocket placer for each diff
int xBase = shortenedX * gridSize * 16;
int zBase = shortenedZ * gridSize * 16;
DimDoors.log(this.getClass(), "Placing new pocket at x = " + xBase + ", z = " + zBase);
DimDoors.log(this.getClass(), "Name of new pocket schematic is " + schematic.getSchematicName());
if (schematic == null) {
DimDoors.log(this.getClass(), "The schematic for variant " + variantName + " somehow didn't load correctly despite all precautions.");
@ -109,7 +110,7 @@ public class PocketTemplate { //there is exactly one pocket placer for each diff
List<DDTileEntityBase> rifts = new ArrayList();
for (NBTTagCompound tileEntityNBT : schematic.getTileEntities()) {
BlockPos pos = new BlockPos(xBase + tileEntityNBT.getInteger("x"), yBase + tileEntityNBT.getInteger("y"), zBase + tileEntityNBT.getInteger("z"));
DimDoors.log(this.getClass(), "Re-loading rift at blockPos: " + pos.toString());
DimDoors.log(this.getClass(), "Re-loading tile-entity at blockPos: " + pos.toString());
TileEntity tileEntity = world.getTileEntity(pos);
if (tileEntity != null) {
tileEntity.readFromNBT(tileEntityNBT); //this reads in the wrong blockPos
@ -118,6 +119,7 @@ public class PocketTemplate { //there is exactly one pocket placer for each diff
}
if (tileEntity instanceof DDTileEntityBase) {
DimDoors.log(this.getClass(), "Rift found in schematic: " + pos.toString());
DDTileEntityBase rift = (DDTileEntityBase) tileEntity;
rifts.add(rift);
}

View file

@ -150,6 +150,7 @@ public class RiftRegistry {
personalDoors.add(assignedID);
}
} else {
DimDoors.log(this.getClass(), "Registering rift in unpairedRiftRegistry. ID = " + assignedID);
unpairedRifts.add(assignedID);
registerUnpairedRiftAtDepth(assignedID, depth);
}
@ -284,6 +285,7 @@ public class RiftRegistry {
List<Integer> rifts = unpairedRiftsPerDepth.get(depth);
int numberOfUnpairedRifts = rifts.size();
if (numberOfUnpairedRifts > 1) {
DimDoors.log(this.getClass(), "There's more than 1 unpaired rift at this depth.");
Random random = new Random();
int indexOforigRiftID = -1;
int randomRiftIDIndex;
@ -300,6 +302,7 @@ public class RiftRegistry {
returnID = rifts.get(randomRiftIDIndex);
}
}
DimDoors.log(this.getClass(), "Rift to pair to chosen: returnID = " + returnID);
return returnID;
}
@ -399,4 +402,9 @@ public class RiftRegistry {
lastBrokenRift = null;
}
}
public int getPocketID(int riftID) {
DDTileEntityBase rift = (DDTileEntityBase) rifts.get(riftID).getTileEntity();
return rift.getPocketID();
}
}

View file

@ -43,7 +43,7 @@ public class TeleportCommand extends CommandBase {
int id = Integer.parseInt(args[0]);
if (sender instanceof EntityPlayerMP) {
server.getPlayerList().transferPlayerToDimension((EntityPlayerMP) sender, Integer.parseInt(args[0]), TeleporterDimDoors.instance());
server.getPlayerList().transferPlayerToDimension((EntityPlayerMP) sender, id, TeleporterDimDoors.instance());
}
}
}

View file

@ -25,7 +25,7 @@ public class TeleporterDimDoors extends Teleporter {
* Teleporter isn't static, so TeleporterDimDoors can't be static, so we're
* using the the Singleton Design Pattern instead
*/
private static TeleporterDimDoors instance;
private static TeleporterDimDoors INSTANCE;
private TeleporterDimDoors(WorldServer world) {
super(world);
@ -47,10 +47,10 @@ public class TeleporterDimDoors extends Teleporter {
}
public static TeleporterDimDoors instance() {
if (instance == null) {
instance = new TeleporterDimDoors(DimDoors.proxy.getWorldServer(0));
if (INSTANCE == null) {
INSTANCE = new TeleporterDimDoors(DimDoors.proxy.getWorldServer(0));
}
return instance;
return INSTANCE;
}
@Override
@ -138,8 +138,10 @@ public class TeleporterDimDoors extends Teleporter {
private void teleportLocal(Entity entity, BlockPos pos) {
WorldServer worldserver = (WorldServer) entity.world;
if (entity instanceof EntityPlayer) {
DimDoors.log(TeleporterDimDoors.class, "Teleporting Player within same dimension.");
DimDoors.log(TeleporterDimDoors.class,
"Teleporting Player within same dimension.");
EntityPlayerMP player = (EntityPlayerMP) entity;
float playerRotationYaw = player.rotationYaw; //@todo make this a parameter?
@ -149,11 +151,14 @@ public class TeleporterDimDoors extends Teleporter {
worldserver.theProfiler.startSection("moving");
player.setLocationAndAngles(pos.getX() + 0.5, pos.getY() + 0.05, pos.getZ() + 0.5, playerRotationYaw, player.rotationPitch);
//playerList.preparePlayer(player, worldserver); //This makes the player stutter heavily on teleport
player.connection.setPlayerLocation(pos.getX() + 0.5, pos.getY() + 0.05, pos.getZ() + 0.5, playerRotationYaw, player.rotationPitch, EnumSet.<SPacketPlayerPosLook.EnumFlags>noneOf(SPacketPlayerPosLook.EnumFlags.class));
player.connection.setPlayerLocation(pos.getX() + 0.5, pos.getY() + 0.05, pos.getZ() + 0.5, playerRotationYaw, player.rotationPitch, EnumSet.<SPacketPlayerPosLook.EnumFlags>noneOf(SPacketPlayerPosLook.EnumFlags.class
));
worldserver.theProfiler.endSection();
player.connection.sendPacket(new SPacketPlayerAbilities(player.capabilities));
} else {
DimDoors.log(TeleporterDimDoors.class, "Teleporting non-Player within same dimension.");
DimDoors.log(TeleporterDimDoors.class,
"Teleporting non-Player within same dimension.");
entity.setPosition(pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5);
worldserver.resetUpdateEntityTick();

View file

@ -120,15 +120,8 @@ public abstract class BlockDimDoorBase extends BlockDoor implements IDimDoor, IT
@Override
public void enterDimDoor(World world, BlockPos pos, Entity entity) {
DDTileEntityBase riftTile = getRiftTile(world, pos, world.getBlockState(pos));
if (riftTile.tryTeleport(entity)) {
//player is succesfully teleported
} else {
//probably should only happen on personal dimdoors?
if (entity instanceof EntityPlayer) {
EntityPlayer entityPlayer = (EntityPlayer) entity;
DimDoors.chat(entityPlayer, "Teleporting failed, but since mod is still in alpha, stuff like that might simply happen.");
}
}
riftTile.isTeleporting = true; //flick trigger switch
riftTile.teleportingEntity = entity;
}
public boolean isUpperDoorBlock(IBlockState state) {

View file

@ -55,12 +55,11 @@ public class ItemRiftBlade extends ItemSword {
RayTraceResult hit = rayTrace(world, player, true);
if (RayTraceHelper.isRift(hit, world)) {
TileEntityRift rift = (TileEntityRift) world.getTileEntity(hit.getBlockPos());
EnumActionResult teleportResult = rift.tryTeleport(player) ? EnumActionResult.SUCCESS : EnumActionResult.FAIL;
rift.isTeleporting = true;
rift.teleportingEntity = player;
if (teleportResult == EnumActionResult.SUCCESS) {
stack.damageItem(1, player);
}
return new ActionResult(teleportResult, stack);
stack.damageItem(1, player);
return new ActionResult(EnumActionResult.SUCCESS, stack);
} else if (RayTraceHelper.isLivingEntity(hit)) {
EnumActionResult teleportResult = TeleporterDimDoors.instance().teleport(player, new Location(world, hit.getBlockPos())) ? EnumActionResult.SUCCESS : EnumActionResult.FAIL; //@todo teleport to a location 1 or 2 blocks distance from the entity

View file

@ -6,18 +6,27 @@ import com.zixiken.dimdoors.shared.Pocket;
import com.zixiken.dimdoors.shared.PocketRegistry;
import com.zixiken.dimdoors.shared.util.Location;
import com.zixiken.dimdoors.shared.RiftRegistry;
import com.zixiken.dimdoors.shared.blocks.IDimDoor;
import java.util.Random;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ITickable;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
public abstract class DDTileEntityBase extends TileEntity {
public abstract class DDTileEntityBase extends TileEntity implements ITickable {
//Short life fields
public boolean isTeleporting = false;
public Entity teleportingEntity;
//Class specific value fields
protected boolean canRiftBePaired = true;
//Need to be saved:
protected boolean isPaired = false;
protected int riftID = -1; //should not start at 0
protected int pairedRiftID = -1;
@ -67,7 +76,7 @@ public abstract class DDTileEntityBase extends TileEntity {
if (riftID == -1) {
riftID = RiftRegistry.INSTANCE.registerNewRift(this, depth);
DimDoors.log(this.getClass(), "Finished registering rift as ID: " + riftID);
this.markDirty();
}
}
@ -110,6 +119,12 @@ public abstract class DDTileEntityBase extends TileEntity {
isPaired = rift2.isPaired;
riftID = rift2.riftID; //should not start at 0
pairedRiftID = rift2.pairedRiftID;
isInPocket = rift2.isInPocket;
pocketID = rift2.pocketID;
pocketType = rift2.pocketType;
depth = rift2.depth;
this.markDirty();
}
}
@ -160,4 +175,26 @@ public abstract class DDTileEntityBase extends TileEntity {
pocket.validatePlayerEntry(player);
}
}
@Override
public void update() {
if (isTeleporting && teleportingEntity != null) {
IDimDoor door = (IDimDoor) this.world.getBlockState(this.pos).getBlock();
if (tryTeleport(teleportingEntity)) {
//player is succesfully teleported
} else {
//probably should only happen on personal dimdoors?
if (teleportingEntity instanceof EntityPlayer) {
EntityPlayer entityPlayer = (EntityPlayer) teleportingEntity;
DimDoors.chat(entityPlayer, "Teleporting failed, but since mod is still in alpha, stuff like that might simply happen.");
}
}
isTeleporting = false;
teleportingEntity = null;
}
}
public int getPocketID() {
return isInPocket ? pocketID : -1;
}
}

View file

@ -32,6 +32,7 @@ public class TileEntityDimDoor extends DDTileEntityBase {
this.orientation = EnumFacing.getFront(nbt.getInteger("orientation"));
this.lockStatus = nbt.getByte("lockStatus");
} catch (Exception e) {
DimDoors.warn(this.getClass(), "An error occured while trying to read this object from NBT.");
}
}

View file

@ -33,7 +33,10 @@ public class TileEntityDimDoorPersonal extends TileEntityDimDoor {
if (locationOfThisRift.getDimensionID() == DimDoorDimensions.getPocketDimensionType(EnumPocketType.PRIVATE).getId()) {
tpLocation = PocketRegistry.INSTANCE.getPocket(this.pocketID, EnumPocketType.PRIVATE).getDepthZeroLocation();
} else {
tpLocation = RiftRegistry.INSTANCE.getTeleportLocation(PocketRegistry.INSTANCE.getPrivateDimDoorID(entityPlayer.getCachedUniqueIdString()));
int otherDoorID = PocketRegistry.INSTANCE.getPrivateDimDoorID(entityPlayer.getCachedUniqueIdString());
tpLocation = RiftRegistry.INSTANCE.getTeleportLocation(otherDoorID);
int privatePocketID = RiftRegistry.INSTANCE.getPocketID(otherDoorID);
PocketRegistry.INSTANCE.getPocket(privatePocketID, EnumPocketType.PRIVATE).setDepthZeroLocation(this.getTeleportTargetLocation());
}
} else {
return false;

View file

@ -25,11 +25,11 @@ public class TileEntityRift extends DDTileEntityBase implements ITickable {
private static final Random random = new Random();
//Need to be saved:
private int updateTimer;
public BlockPos offset = BlockPos.ORIGIN;
public boolean shouldClose = false;
public int spawnedEndermenID = 0;
public int riftRotation = random.nextInt(360);
public float growth = 0;

View file

@ -102,5 +102,9 @@ public class Location implements Serializable {
public String toString() {
return "Location: dimID: " + this.dimensionID + " position: " + this.pos.toString();
}
public void loadfrom(Location location) {
this.dimensionID = location.dimensionID;
this.pos = location.pos;
}
}