Implement VirtualLocation and AvailableLink logic
This commit is contained in:
parent
75c2e5439f
commit
70922ceae1
33 changed files with 388 additions and 232 deletions
|
@ -64,7 +64,7 @@ configurations {
|
|||
|
||||
dependencies {
|
||||
embed 'com.flowpowered:flow-math:1.0.3'
|
||||
compile 'com.github.DimensionalDevelopment:AnnotatedNBT:master-SNAPSHOT'
|
||||
compile 'com.github.DimensionalDevelopment:AnnotatedNBT:-SNAPSHOT'
|
||||
}
|
||||
|
||||
jar {
|
||||
|
@ -96,7 +96,3 @@ task generatePocketSchematics(dependsOn: jar, type: JavaExec, group: "dimdoors")
|
|||
//noinspection GroovyAssignabilityCheck (IntelliJ is wrong)
|
||||
args "src/main/resources/assets/dimdoors/pockets/schematic"
|
||||
}
|
||||
|
||||
runClient {
|
||||
args '--username', 'Runemoro'
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import org.dimdev.dimdoors.shared.blocks.ModBlocks;
|
|||
import org.dimdev.dimdoors.shared.entities.EntityMonolith;
|
||||
import org.dimdev.dimdoors.shared.items.ModItems;
|
||||
import org.dimdev.dimdoors.shared.rifts.*;
|
||||
import org.dimdev.dimdoors.shared.rifts.destinations.*;
|
||||
import org.dimdev.dimdoors.shared.sound.ModSounds;
|
||||
import org.dimdev.dimdoors.shared.tileentities.*;
|
||||
import org.dimdev.dimdoors.shared.world.ModDimensions;
|
||||
|
|
|
@ -1,37 +1,26 @@
|
|||
package org.dimdev.dimdoors.shared;
|
||||
|
||||
import lombok.*;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import org.dimdev.annotatednbt.NBTSerializable;
|
||||
import org.dimdev.annotatednbt.Saved;
|
||||
import org.dimdev.ddutils.nbt.INBTStorable;
|
||||
import org.dimdev.ddutils.nbt.NBTUtils;
|
||||
import org.dimdev.dimdoors.shared.pockets.Pocket;
|
||||
import org.dimdev.dimdoors.shared.pockets.PocketRegistry;
|
||||
import org.dimdev.ddutils.Location;
|
||||
import org.dimdev.dimdoors.shared.world.ModDimensions;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.ToString;
|
||||
import lombok.Value;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import org.dimdev.dimdoors.shared.world.limbodimension.WorldProviderLimbo;
|
||||
|
||||
import java.util.Random;
|
||||
/*@Value*/ @ToString @AllArgsConstructor @NoArgsConstructor @Builder(toBuilder = true)
|
||||
@NBTSerializable public class VirtualLocation implements INBTStorable { // TODO: fix AnnotatedNBT and rename this class back to VirtualLocation
|
||||
@Saved @Getter protected int dim;
|
||||
@Saved @Getter protected int x;
|
||||
@Saved @Getter protected int z;
|
||||
@Saved @Getter protected int depth; // TODO: convert to doubles
|
||||
|
||||
@Value @ToString @AllArgsConstructor @Builder(toBuilder = true)
|
||||
public class VirtualLocation {
|
||||
Location location;
|
||||
int depth;
|
||||
|
||||
public VirtualLocation(int dim, BlockPos pos, int depth) {
|
||||
this(new Location(dim, pos), depth);
|
||||
}
|
||||
|
||||
public VirtualLocation(int dim, int x, int y, int z, int depth) {
|
||||
this(new Location(dim, x, y, z), depth);
|
||||
}
|
||||
|
||||
public int getDim() { return location.getDim(); }
|
||||
public BlockPos getPos() { return location.getPos(); }
|
||||
public int getX() { return location.getX(); }
|
||||
public int getY() { return location.getY(); }
|
||||
public int getZ() { return location.getZ(); }
|
||||
@Override public void readFromNBT(NBTTagCompound nbt) { NBTUtils.readFromNBT(this, nbt); }
|
||||
@Override public NBTTagCompound writeToNBT(NBTTagCompound nbt) { return NBTUtils.writeToNBT(this, nbt); }
|
||||
|
||||
public static VirtualLocation fromLocation(Location location) {
|
||||
VirtualLocation virtualLocation = null;
|
||||
|
@ -40,18 +29,18 @@ public class VirtualLocation {
|
|||
if (pocket != null) {
|
||||
virtualLocation = pocket.getVirtualLocation(); // TODO: pocket-relative coordinates
|
||||
} else {
|
||||
virtualLocation = new VirtualLocation(0, 0, 0, 0, 0); // TODO: door was placed in a pocket dim but outside of a pocket...
|
||||
virtualLocation = new VirtualLocation(0, 0, 0, 0); // TODO: door was placed in a pocket dim but outside of a pocket...
|
||||
}
|
||||
} else if (location.getWorld().provider instanceof WorldProviderLimbo) {
|
||||
virtualLocation = new VirtualLocation(location, Config.getMaxDungeonDepth());
|
||||
virtualLocation = new VirtualLocation(location.getDim(), location.getX(), location.getZ(), Config.getMaxDungeonDepth());
|
||||
}
|
||||
if (virtualLocation == null) {
|
||||
virtualLocation = new VirtualLocation(location, 0);
|
||||
virtualLocation = new VirtualLocation(location.getDim(), location.getX(), location.getZ(), 0);
|
||||
}
|
||||
return virtualLocation;
|
||||
}
|
||||
|
||||
// TODO: world-seed based transformations and pocket selections
|
||||
/*// 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);
|
||||
|
@ -60,23 +49,5 @@ public class VirtualLocation {
|
|||
int xOffset = random.nextInt((int) Math.pow(base * (depthDiff + 1), power)) * (random.nextBoolean() ? 1 : -1);
|
||||
int zOffset = random.nextInt((int) Math.pow(base * (depthDiff + 1), power)) * (random.nextBoolean() ? 1 : -1);
|
||||
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 new Location(0, transformDepth(0).getPos());
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
|
|
@ -133,7 +133,7 @@ public abstract class BlockDimensionalDoor extends BlockDoor implements IRiftPro
|
|||
world.setBlockState(rift.getPos(), ModBlocks.RIFT.getDefaultState());
|
||||
TileEntityFloatingRift newRift = (TileEntityFloatingRift) world.getTileEntity(pos);
|
||||
newRift.copyFrom(rift);
|
||||
newRift.updateAvailableLinks();
|
||||
newRift.updateType();
|
||||
world.notifyBlockUpdate(rift.getPos(), state, world.getBlockState(pos), 0); // TODO: does this work?
|
||||
} else {
|
||||
rift.unregister();
|
||||
|
|
|
@ -3,12 +3,16 @@ package org.dimdev.dimdoors.shared.blocks;
|
|||
import net.minecraft.block.state.IBlockState;
|
||||
import org.dimdev.dimdoors.DimDoors;
|
||||
import org.dimdev.dimdoors.shared.items.ModItems;
|
||||
import org.dimdev.dimdoors.shared.rifts.AvailableLink;
|
||||
import org.dimdev.dimdoors.shared.rifts.WeightedRiftDestination;
|
||||
import org.dimdev.dimdoors.shared.rifts.destinations.AvailableLinkDestination;
|
||||
import org.dimdev.dimdoors.shared.rifts.destinations.NewPublicDestination;
|
||||
import org.dimdev.dimdoors.shared.tileentities.TileEntityEntranceRift;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.*;
|
||||
|
||||
public class BlockDimensionalDoorGold extends BlockDimensionalDoor {
|
||||
|
||||
|
@ -33,7 +37,21 @@ public class BlockDimensionalDoorGold extends BlockDimensionalDoor {
|
|||
|
||||
@Override
|
||||
public void setupRift(TileEntityEntranceRift rift) {
|
||||
// TODO
|
||||
AvailableLink link = AvailableLink.builder()
|
||||
.groups(new HashSet<>(Arrays.asList(0, 1)))
|
||||
.linksRemaining(1)
|
||||
.replaceDestination(UUID.randomUUID()).build();
|
||||
rift.addAvailableLink(link);
|
||||
AvailableLinkDestination destination = AvailableLinkDestination.builder()
|
||||
.acceptedGroups(Collections.singleton(0))
|
||||
.coordFactor(1)
|
||||
.negativeDepthFactor(10000)
|
||||
.positiveDepthFactor(80)
|
||||
.weightMaximum(100)
|
||||
.linkId(link.id)
|
||||
.noLink(false)
|
||||
.newRiftWeight(1).build();
|
||||
rift.addWeightedDestination(new WeightedRiftDestination(destination, 1, 0, null, link.replaceDestination));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -4,7 +4,7 @@ import net.minecraft.block.state.IBlockState;
|
|||
import net.minecraft.init.Blocks;
|
||||
import org.dimdev.dimdoors.DimDoors;
|
||||
import org.dimdev.dimdoors.shared.items.ModItems;
|
||||
import org.dimdev.dimdoors.shared.rifts.NewPublicDestination;
|
||||
import org.dimdev.dimdoors.shared.rifts.destinations.NewPublicDestination;
|
||||
import org.dimdev.dimdoors.shared.tileentities.TileEntityEntranceRift;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.item.Item;
|
||||
|
|
|
@ -3,8 +3,8 @@ package org.dimdev.dimdoors.shared.blocks;
|
|||
import net.minecraft.block.state.IBlockState;
|
||||
import org.dimdev.dimdoors.DimDoors;
|
||||
import org.dimdev.dimdoors.shared.items.ModItems;
|
||||
import org.dimdev.dimdoors.shared.rifts.PrivateDestination;
|
||||
import org.dimdev.dimdoors.shared.rifts.PrivatePocketExitDestination;
|
||||
import org.dimdev.dimdoors.shared.rifts.destinations.PrivateDestination;
|
||||
import org.dimdev.dimdoors.shared.rifts.destinations.PrivatePocketExitDestination;
|
||||
import org.dimdev.dimdoors.shared.tileentities.TileEntityEntranceRift;
|
||||
import org.dimdev.dimdoors.shared.world.pocketdimension.WorldProviderPersonalPocket;
|
||||
import net.minecraft.block.material.Material;
|
||||
|
|
|
@ -4,7 +4,7 @@ import net.minecraft.block.state.IBlockState;
|
|||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.item.Item;
|
||||
import org.dimdev.dimdoors.DimDoors;
|
||||
import org.dimdev.dimdoors.shared.rifts.EscapeDestination;
|
||||
import org.dimdev.dimdoors.shared.rifts.destinations.EscapeDestination;
|
||||
import org.dimdev.dimdoors.shared.tileentities.TileEntityEntranceRift;
|
||||
import net.minecraft.block.*;
|
||||
import net.minecraft.block.material.Material;
|
||||
|
|
|
@ -173,6 +173,8 @@ public class BlockFabric extends Block {
|
|||
return false;
|
||||
}
|
||||
|
||||
// TODO
|
||||
/*
|
||||
@Override
|
||||
public void onEntityWalk(World world, BlockPos pos, Entity entity) {
|
||||
IBlockState state = world.getBlockState(pos);
|
||||
|
@ -183,6 +185,7 @@ public class BlockFabric extends Block {
|
|||
TeleportUtils.teleport(entity, new Location(loc.getDim(), correctedPos), random.nextFloat() * 360, random.nextFloat() * 360);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
@Override
|
||||
public void updateTick(World world, BlockPos pos, IBlockState state, Random rand) {
|
||||
|
|
|
@ -91,7 +91,7 @@ public class CommandPocket extends CommandBase {
|
|||
// Generate the schematic
|
||||
DimDoors.chat(player, "Generating schematic " + name);
|
||||
PocketTemplate template = SchematicHandler.INSTANCE.getTemplate(group, name);
|
||||
Pocket pocket = PocketGenerator.generatePocketFromTemplate(WorldUtils.getDim(player.world), template, new VirtualLocation(0, 0, 0, 0,0));
|
||||
Pocket pocket = PocketGenerator.generatePocketFromTemplate(WorldUtils.getDim(player.world), template, null);
|
||||
if (setup) pocket.setup();
|
||||
|
||||
// Teleport the player there
|
||||
|
|
|
@ -43,7 +43,7 @@ public abstract class ItemDimensionalDoor extends ItemDoor {
|
|||
// Copy from the old rift
|
||||
TileEntityEntranceRift newRift = (TileEntityEntranceRift) world.getTileEntity(pos);
|
||||
newRift.copyFrom(rift);
|
||||
newRift.updateAvailableLinks();
|
||||
newRift.updateType();
|
||||
}
|
||||
} else if (rift != null) {
|
||||
rift.setUnregisterDisabled(false);
|
||||
|
|
|
@ -14,7 +14,7 @@ import net.minecraft.world.World;
|
|||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
|
||||
public class ItemDimensionalDoorGold extends ItemDoor {
|
||||
public class ItemDimensionalDoorGold extends ItemDimensionalDoor {
|
||||
|
||||
public ItemDimensionalDoorGold() {
|
||||
super(ModBlocks.GOLD_DIMENSIONAL_DOOR);
|
||||
|
|
|
@ -17,7 +17,7 @@ import net.minecraft.item.ItemStack;
|
|||
import net.minecraft.world.World;
|
||||
import org.dimdev.ddutils.RotatedLocation;
|
||||
import org.dimdev.dimdoors.shared.blocks.ModBlocks;
|
||||
import org.dimdev.dimdoors.shared.rifts.GlobalDestination;
|
||||
import org.dimdev.dimdoors.shared.rifts.destinations.GlobalDestination;
|
||||
import org.dimdev.dimdoors.shared.rifts.TileEntityRift;
|
||||
import org.dimdev.dimdoors.shared.sound.ModSounds;
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ import org.dimdev.ddutils.Location;
|
|||
import org.dimdev.dimdoors.DimDoors;
|
||||
import org.dimdev.ddutils.RotatedLocation;
|
||||
import org.dimdev.dimdoors.shared.blocks.ModBlocks;
|
||||
import org.dimdev.dimdoors.shared.rifts.GlobalDestination;
|
||||
import org.dimdev.dimdoors.shared.rifts.destinations.GlobalDestination;
|
||||
import org.dimdev.dimdoors.shared.rifts.TileEntityRift;
|
||||
import org.dimdev.dimdoors.shared.sound.ModSounds;
|
||||
|
||||
|
|
|
@ -6,6 +6,8 @@ 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;
|
||||
|
||||
|
@ -121,7 +123,7 @@ import net.minecraft.util.math.BlockPos;
|
|||
}
|
||||
}
|
||||
|
||||
public void linkPocketTo(RiftDestination linkTo) {
|
||||
public void linkPocketTo(RiftDestination linkTo, RiftDestination oldDest, AvailableLink availableLink) {
|
||||
List<TileEntityRift> rifts = getRifts();
|
||||
|
||||
// Link pocket exits back
|
||||
|
@ -133,7 +135,8 @@ import net.minecraft.util.math.BlockPos;
|
|||
if (dest instanceof PocketExitDestination) {
|
||||
destIterator.remove();
|
||||
if (rift.isRegistered()) dest.unregister(rift);
|
||||
destIterator.add(new WeightedRiftDestination(linkTo, wdest.getWeight(), wdest.getGroup(), dest));
|
||||
if (linkTo != 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
|
||||
|
|
|
@ -6,7 +6,7 @@ import org.dimdev.dimdoors.shared.world.ModDimensions;
|
|||
|
||||
import java.util.Random;
|
||||
|
||||
public class PocketGenerator {
|
||||
public final class PocketGenerator {
|
||||
|
||||
public static Pocket generatePocketFromTemplate(int dim, PocketTemplate pocketTemplate, VirtualLocation virtualLocation) {
|
||||
DimDoors.log.info("Generating pocket from template " + pocketTemplate.getName() + " at virtual location " + virtualLocation);
|
||||
|
@ -34,7 +34,7 @@ public class PocketGenerator {
|
|||
* @param virtualLocation The virtual location of the pocket
|
||||
* @return The newly-generated dungeon pocket
|
||||
*/
|
||||
public Pocket generateDungeonPocket(VirtualLocation virtualLocation) {
|
||||
public static Pocket generateDungeonPocket(VirtualLocation virtualLocation) {
|
||||
int depth = virtualLocation.getDepth();
|
||||
float netherProbability = virtualLocation.getDim() == -1 ? 1 : (float) depth / 50; // TODO: improve nether probability
|
||||
Random random = new Random();
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
package org.dimdev.dimdoors.shared.rifts;
|
||||
|
||||
import lombok.*;
|
||||
import lombok.experimental.Wither;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import org.dimdev.annotatednbt.NBTSerializable;
|
||||
import org.dimdev.annotatednbt.Saved;
|
||||
import org.dimdev.ddutils.Location;
|
||||
import org.dimdev.ddutils.nbt.INBTStorable;
|
||||
import org.dimdev.ddutils.nbt.NBTUtils;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
@NBTSerializable @AllArgsConstructor @NoArgsConstructor @EqualsAndHashCode @Builder(toBuilder = true) @ToString
|
||||
public class AvailableLink implements INBTStorable {
|
||||
@Wither public Location rift;
|
||||
|
||||
@Saved @Builder.Default public UUID id = UUID.randomUUID();
|
||||
@Saved @Builder.Default public float floatingWeight = 1;
|
||||
@Saved @Builder.Default public float entranceWeight = 1;
|
||||
@Saved @Builder.Default public Set<Integer> groups = new HashSet<>();
|
||||
@Saved public UUID replaceDestination;
|
||||
@Saved @Builder.Default public int linksRemaining = 1;
|
||||
|
||||
@Override public void readFromNBT(NBTTagCompound nbt) { NBTUtils.readFromNBT(this, nbt); }
|
||||
@Override public NBTTagCompound writeToNBT(NBTTagCompound nbt) { return NBTUtils.writeToNBT(this, nbt); }
|
||||
}
|
|
@ -1,103 +0,0 @@
|
|||
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.dimdoors.shared.VirtualLocation;
|
||||
import org.dimdev.ddutils.Location;
|
||||
import org.dimdev.ddutils.math.MathUtils;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.ToString;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
@Getter @AllArgsConstructor @Builder(toBuilder = true) @ToString
|
||||
@NBTSerializable public class AvailableLinkDestination extends RiftDestination { // TODO
|
||||
@Saved protected float newDungeonRiftProbability;
|
||||
@Saved protected float depthPenalization; // TODO: these make the equation assymetric
|
||||
@Saved protected float distancePenalization;
|
||||
@Saved protected float closenessPenalization;
|
||||
|
||||
@Saved protected boolean dungeonRiftsOnly;
|
||||
@Saved protected boolean overworldRifts;
|
||||
@Saved protected boolean unstable;
|
||||
@Saved protected float nonFloatingRiftWeight;
|
||||
@Saved protected float floatingRiftWeight;
|
||||
|
||||
@Saved protected boolean noLinkBack;
|
||||
// private int maxLinks;
|
||||
|
||||
@Builder.Default private UUID uuid = UUID.randomUUID();
|
||||
// TODO: add a "safe" option to link only to a rift destination that has a non-zero weight
|
||||
|
||||
AvailableLinkDestination() {}
|
||||
|
||||
@Override public void readFromNBT(NBTTagCompound nbt) { super.readFromNBT(nbt); NBTUtils.readFromNBT(this, nbt); }
|
||||
@Override public NBTTagCompound writeToNBT(NBTTagCompound nbt) { nbt = super.writeToNBT(nbt); return NBTUtils.writeToNBT(this, nbt); }
|
||||
|
||||
@Override
|
||||
public boolean teleport(TileEntityRift rift, Entity entity) {
|
||||
Map<RiftRegistry.RiftInfo.AvailableLinkInfo, Float> possibleDestWeightMap = new HashMap<>();
|
||||
|
||||
for (RiftRegistry.RiftInfo.AvailableLinkInfo link : RiftRegistry.getAvailableLinks()) {
|
||||
VirtualLocation otherVLoc = link.getVirtualLocation();
|
||||
float weight2 = link.getWeight();
|
||||
if (weight2 == 0) continue;
|
||||
double depthDiff = Math.abs(rift.virtualLocation.getDepth() - otherVLoc.getDepth());
|
||||
double distanceSq = new BlockPos(rift.virtualLocation.getX(), rift.virtualLocation.getY(), rift.virtualLocation.getZ())
|
||||
.distanceSq(new BlockPos(otherVLoc.getX(), otherVLoc.getY(), otherVLoc.getZ()));
|
||||
float distanceExponent = distancePenalization;
|
||||
float depthExponent = depthPenalization;
|
||||
float closenessExponent = closenessPenalization;
|
||||
float weight = (float) Math.abs(weight2/(Math.pow(depthDiff, depthExponent) * Math.pow(distanceSq, 0.5 * distanceExponent))); // TODO: fix formula
|
||||
float currentWeight = possibleDestWeightMap.get(link);
|
||||
possibleDestWeightMap.put(link, currentWeight + weight);
|
||||
}
|
||||
|
||||
RiftRegistry.RiftInfo.AvailableLinkInfo selectedLink = MathUtils.weightedRandom(possibleDestWeightMap);
|
||||
Location destLoc = selectedLink.getLocation();
|
||||
if (!unstable) rift.makeDestinationPermanent(weightedDestination, destLoc);
|
||||
|
||||
TileEntityRift destRift = (TileEntityRift) destLoc.getWorld().getTileEntity(destLoc.getPos()); // Link the other rift back if necessary
|
||||
ListIterator<WeightedRiftDestination> wdestIterator = destRift.destinations.listIterator();
|
||||
WeightedRiftDestination selectedWDest = null;
|
||||
while (wdestIterator.hasNext()) {
|
||||
WeightedRiftDestination wdest = wdestIterator.next();
|
||||
RiftDestination otherDest = wdest.getDestination();
|
||||
if (otherDest instanceof AvailableLinkDestination && ((AvailableLinkDestination) otherDest).uuid == selectedLink.getUuid()) {
|
||||
selectedWDest = wdest;
|
||||
wdestIterator.remove();
|
||||
break;
|
||||
}
|
||||
}
|
||||
AvailableLinkDestination selectedAvailableLinkDest = (AvailableLinkDestination) selectedWDest.getDestination();
|
||||
if (!selectedAvailableLinkDest.noLinkBack) {
|
||||
destRift.makeDestinationPermanent(selectedWDest, rift.getLocation());
|
||||
}
|
||||
((TileEntityRift) destLoc.getTileEntity()).teleportTo(entity);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(TileEntityRift rift) {
|
||||
RiftRegistry.RiftInfo.AvailableLinkInfo linkInfo = RiftRegistry.RiftInfo.AvailableLinkInfo.builder()
|
||||
.weight(rift.isFloating() ? floatingRiftWeight : nonFloatingRiftWeight)
|
||||
.virtualLocation(rift.virtualLocation)
|
||||
.uuid(uuid)
|
||||
.build();
|
||||
RiftRegistry.addAvailableLink(rift.getLocation(), linkInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregister(TileEntityRift rift) {
|
||||
RiftRegistry.removeAvailableLinkByUUID(rift.getLocation(), uuid);
|
||||
}
|
||||
}
|
|
@ -17,7 +17,6 @@ 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.rifts.RiftRegistry.RiftInfo.AvailableLinkInfo;
|
||||
import org.dimdev.dimdoors.shared.world.ModDimensions;
|
||||
|
||||
import java.util.*;
|
||||
|
@ -28,6 +27,7 @@ import java.util.*;
|
|||
@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
|
||||
|
@ -39,21 +39,12 @@ import java.util.*;
|
|||
@AllArgsConstructor @EqualsAndHashCode @Builder(toBuilder = true)
|
||||
@NBTSerializable public static class RiftInfo implements INBTStorable {
|
||||
// IntelliJ warnings are wrong, Builder needs these initializers!
|
||||
@Saved @SuppressWarnings({"UnusedAssignment", "RedundantSuppression"}) @Builder.Default @Getter /*package-private*/ Set<AvailableLinkInfo> availableLinks = new HashSet<>(); // TODO: multiset?
|
||||
@Saved @SuppressWarnings({"UnusedAssignment", "RedundantSuppression"}) @Builder.Default @Getter /*package-private*/ Multiset<Location> sources = ConcurrentHashMultiset.create();
|
||||
@Saved @SuppressWarnings({"UnusedAssignment", "RedundantSuppression"}) @Builder.Default @Getter /*package-private*/ Multiset<Location> destinations = ConcurrentHashMultiset.create();
|
||||
|
||||
@NBTSerializable @AllArgsConstructor @NoArgsConstructor @EqualsAndHashCode @Builder(toBuilder = true)
|
||||
public static class AvailableLinkInfo implements INBTStorable {
|
||||
@Saved @Getter @Setter /*package-private*/ float weight;
|
||||
@Saved @Getter /*package-private*/ VirtualLocation virtualLocation;
|
||||
@Saved @Getter @Wither /*package-private*/ Location location;
|
||||
@Saved @Getter /*package-private*/ UUID uuid;
|
||||
|
||||
@Override public void readFromNBT(NBTTagCompound nbt) { NBTUtils.readFromNBT(this, nbt); }
|
||||
|
||||
@Override public NBTTagCompound writeToNBT(NBTTagCompound nbt) { return NBTUtils.writeToNBT(this, nbt); }
|
||||
}
|
||||
@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<>();
|
||||
|
@ -62,7 +53,6 @@ import java.util.*;
|
|||
}
|
||||
|
||||
@Override public void readFromNBT(NBTTagCompound nbt) { NBTUtils.readFromNBT(this, nbt); }
|
||||
|
||||
@Override public NBTTagCompound writeToNBT(NBTTagCompound nbt) { return NBTUtils.writeToNBT(this, nbt); }
|
||||
}
|
||||
|
||||
|
@ -198,14 +188,14 @@ import java.util.*;
|
|||
if (from.getTileEntity() instanceof TileEntityRift) ((TileEntityRift) from.getTileEntity()).updateColor();
|
||||
}
|
||||
|
||||
public static void addAvailableLink(Location rift, AvailableLinkInfo link) { // TODO cache rifts with availableLinks
|
||||
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, AvailableLinkInfo link) {
|
||||
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);
|
||||
|
@ -219,16 +209,17 @@ import java.util.*;
|
|||
registry.markDirty();
|
||||
}
|
||||
|
||||
public static void removeAvailableLinkByUUID(Location rift, UUID uuid) {
|
||||
DimDoors.log.info("AvailableLink with uuid " + uuid + " removed at " + rift);
|
||||
/*
|
||||
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.uuid.equals(uuid)) {
|
||||
if (link.id.equals(id)) {
|
||||
removeAvailableLink(rift, link);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
public static RiftRegistry getRegistry(Location rift) {
|
||||
return getForDim(rift.getDim());
|
||||
|
@ -284,13 +275,13 @@ import java.util.*;
|
|||
getForDim(0).markDirty();
|
||||
}
|
||||
|
||||
public static List<AvailableLinkInfo> getAvailableLinks() { // TODO: cache this
|
||||
List<AvailableLinkInfo> availableLinks = new ArrayList<>();
|
||||
for (World world : DimensionManager.getWorlds()) {
|
||||
RiftRegistry registry = getForDim(WorldUtils.getDim(world));
|
||||
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 (AvailableLinkInfo availableLink : rift.getValue().availableLinks) {
|
||||
availableLinks.add(availableLink.withLocation(rift.getKey()));
|
||||
for (AvailableLink availableLink : rift.getValue().availableLinks) {
|
||||
availableLinks.add(availableLink.withRift(rift.getKey()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ import org.dimdev.ddutils.Location;
|
|||
import org.dimdev.ddutils.math.MathUtils;
|
||||
import org.dimdev.ddutils.TeleportUtils;
|
||||
import org.dimdev.ddutils.WorldUtils;
|
||||
import org.dimdev.dimdoors.shared.rifts.destinations.*;
|
||||
import org.dimdev.dimdoors.shared.world.ModDimensions;
|
||||
import lombok.Getter;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
|
@ -35,7 +36,7 @@ import java.util.*;
|
|||
|
||||
@NBTSerializable public abstract class TileEntityRift extends TileEntity implements ITickable { // TODO: implement ITeleportSource and ITeleportDestination
|
||||
|
||||
@Saved @Getter protected VirtualLocation virtualLocation;
|
||||
@Saved@Getter protected VirtualLocation virtualLocation;
|
||||
@Saved @Nonnull @Getter protected List<WeightedRiftDestination> destinations; // Not using a set because we can have duplicate destinations. Maybe use Multiset from Guava?
|
||||
@Saved @Getter protected boolean makeDestinationPermanent;
|
||||
@Saved @Getter protected boolean preserveRotation;
|
||||
|
@ -45,6 +46,7 @@ import java.util.*;
|
|||
@Saved @Getter protected float chaosWeight;
|
||||
@Saved @Getter protected boolean forcedColor;
|
||||
@Saved @Getter protected RGBA color = null; // TODO: update AnnotatedNBT to be able to save these
|
||||
@Saved @Getter protected Set<AvailableLink> availableLinks;
|
||||
// TODO: option to convert to door on teleportTo?
|
||||
|
||||
protected boolean riftStateChanged; // not saved
|
||||
|
@ -56,6 +58,7 @@ import java.util.*;
|
|||
pitch = 0;
|
||||
alwaysDelete = false;
|
||||
chaosWeight = 1;
|
||||
availableLinks = new HashSet<>();
|
||||
}
|
||||
|
||||
public void copyFrom(TileEntityRift oldRift) {
|
||||
|
@ -66,7 +69,7 @@ import java.util.*;
|
|||
yaw = oldRift.yaw;
|
||||
pitch = oldRift.pitch;
|
||||
chaosWeight = oldRift.chaosWeight;
|
||||
if (oldRift.isFloating() != isFloating()) updateAvailableLinks();
|
||||
if (oldRift.isFloating() != isFloating()) updateType();
|
||||
|
||||
markDirty();
|
||||
}
|
||||
|
@ -112,7 +115,7 @@ import java.util.*;
|
|||
// Modification functions
|
||||
public void setVirtualLocation(VirtualLocation virtualLocation) {
|
||||
this.virtualLocation = virtualLocation;
|
||||
updateAvailableLinks();
|
||||
updateType();
|
||||
// TODO: update available link virtual locations
|
||||
markDirty();
|
||||
}
|
||||
|
@ -128,6 +131,11 @@ import java.util.*;
|
|||
preserveRotation = true;
|
||||
}
|
||||
|
||||
public void addWeightedDestination(WeightedRiftDestination destination) {
|
||||
destinations.add(destination);
|
||||
markDirty();
|
||||
}
|
||||
|
||||
public void addDestination(RiftDestination destination, float weight, int group) {
|
||||
riftStateChanged = true;
|
||||
destinations.add(new WeightedRiftDestination(destination, weight, group));
|
||||
|
@ -173,6 +181,18 @@ import java.util.*;
|
|||
markDirty();
|
||||
}
|
||||
|
||||
public void registerAvailableLink(AvailableLink link) {
|
||||
if (!isRegistered()) return;
|
||||
RiftRegistry.addAvailableLink(getLocation(), link);
|
||||
}
|
||||
|
||||
public void addAvailableLink(AvailableLink link) {
|
||||
availableLinks.add(link);
|
||||
link.rift = getLocation();
|
||||
registerAvailableLink(link);
|
||||
markDirty();
|
||||
}
|
||||
|
||||
public void markStateChanged() {
|
||||
riftStateChanged = true;
|
||||
markDirty();
|
||||
|
@ -200,9 +220,13 @@ import java.util.*;
|
|||
if (isRegistered()) return;
|
||||
Location loc = new Location(world, pos);
|
||||
RiftRegistry.addRift(loc);
|
||||
RiftRegistry.getRiftInfo(loc).virtualLocation = virtualLocation;
|
||||
for (WeightedRiftDestination weightedDest : destinations) {
|
||||
weightedDest.getDestination().register(this);
|
||||
}
|
||||
for (AvailableLink link : availableLinks) {
|
||||
registerAvailableLink(link);
|
||||
}
|
||||
updateColor();
|
||||
}
|
||||
|
||||
|
@ -220,15 +244,10 @@ import java.util.*;
|
|||
// 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
|
||||
public void updateType() {
|
||||
if (!isRegistered()) return;
|
||||
RiftRegistry.clearAvailableLinks(new Location(world, pos));
|
||||
for (WeightedRiftDestination wdest : destinations) {
|
||||
RiftDestination dest = wdest.getDestination();
|
||||
if (dest instanceof AvailableLinkDestination) {
|
||||
dest.register(this);
|
||||
}
|
||||
}
|
||||
RiftRegistry.getRiftInfo(getLocation()).isEntrance = !isFloating();
|
||||
RiftRegistry.getForDim(getLocation().getDim()).markDirty();
|
||||
}
|
||||
|
||||
public void destinationGone(Location loc) {
|
||||
|
@ -344,4 +363,20 @@ import java.util.*;
|
|||
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,16 +1,22 @@
|
|||
package org.dimdev.dimdoors.shared.rifts;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.dimdev.ddutils.nbt.INBTStorable;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
|
||||
@NoArgsConstructor
|
||||
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();
|
||||
|
@ -22,6 +28,11 @@ public class WeightedRiftDestination implements INBTStorable { // TODO: generics
|
|||
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);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,174 @@
|
|||
package org.dimdev.dimdoors.shared.rifts.destinations;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.ToString;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import org.dimdev.annotatednbt.NBTSerializable;
|
||||
import org.dimdev.annotatednbt.Saved;
|
||||
import org.dimdev.ddutils.WorldUtils;
|
||||
import org.dimdev.ddutils.math.MathUtils;
|
||||
import org.dimdev.ddutils.nbt.NBTUtils;
|
||||
import org.dimdev.dimdoors.shared.VirtualLocation;
|
||||
import org.dimdev.dimdoors.shared.blocks.ModBlocks;
|
||||
import org.dimdev.dimdoors.shared.pockets.Pocket;
|
||||
import org.dimdev.dimdoors.shared.pockets.PocketGenerator;
|
||||
import org.dimdev.dimdoors.shared.rifts.AvailableLink;
|
||||
import org.dimdev.dimdoors.shared.rifts.RiftDestination;
|
||||
import org.dimdev.dimdoors.shared.rifts.RiftRegistry;
|
||||
import org.dimdev.dimdoors.shared.rifts.TileEntityRift;
|
||||
import org.dimdev.dimdoors.shared.tileentities.TileEntityFloatingRift;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
@Getter @AllArgsConstructor @Builder(toBuilder = true) @ToString
|
||||
@NBTSerializable public class AvailableLinkDestination extends RiftDestination { // TODO: increase link count on unregister
|
||||
@Saved protected float newRiftWeight;
|
||||
@Saved protected double weightMaximum;
|
||||
@Saved protected double coordFactor;
|
||||
@Saved protected double positiveDepthFactor;
|
||||
@Saved protected double negativeDepthFactor;
|
||||
@Saved protected Set<Integer> acceptedGroups; // TODO: this should be immutable
|
||||
@Saved protected boolean noLink;
|
||||
@Builder.Default @Saved protected boolean noLinkBack;
|
||||
@Builder.Default @Saved protected UUID linkId = UUID.randomUUID();
|
||||
|
||||
public AvailableLinkDestination() {}
|
||||
|
||||
@Override public void readFromNBT(NBTTagCompound nbt) { super.readFromNBT(nbt); NBTUtils.readFromNBT(this, nbt); }
|
||||
@Override public NBTTagCompound writeToNBT(NBTTagCompound nbt) { nbt = super.writeToNBT(nbt); return NBTUtils.writeToNBT(this, nbt); }
|
||||
|
||||
@Override
|
||||
public boolean teleport(TileEntityRift rift, Entity entity) {
|
||||
if (rift.getVirtualLocation() == null) return false;
|
||||
AvailableLink thisLink = rift.getAvailableLink(linkId);
|
||||
thisLink.linksRemaining--;
|
||||
RiftRegistry.getRegistry(rift.getLocation()).markDirty();
|
||||
Map<AvailableLink, Float> possibleDestWeightMap = new HashMap<>();
|
||||
if (newRiftWeight > 0) possibleDestWeightMap.put(null, newRiftWeight);
|
||||
|
||||
for (AvailableLink link : RiftRegistry.getAvailableLinks()) {
|
||||
RiftRegistry.RiftInfo otherRift = RiftRegistry.getRiftInfo(link.rift);
|
||||
double otherWeight = otherRift.isEntrance ? link.entranceWeight : link.floatingWeight;
|
||||
if (otherWeight == 0 || Sets.intersection(acceptedGroups, link.groups).isEmpty()) continue;
|
||||
|
||||
// Calculate the distance as sqrt((coordFactor * coordDistance)^2 + (depthFactor * depthDifference)^2)
|
||||
if (otherRift.virtualLocation == null || link.linksRemaining == 0) continue;
|
||||
double depthDifference = otherRift.virtualLocation.getDepth() - rift.getVirtualLocation().getDepth();
|
||||
double coordDistance = Math.sqrt(sq(rift.getVirtualLocation().getX() - otherRift.virtualLocation.getX())
|
||||
+ sq(rift.getVirtualLocation().getZ() - otherRift.virtualLocation.getZ()));
|
||||
double depthFactor = depthDifference > 0 ? positiveDepthFactor : negativeDepthFactor; // TODO: (|depthDiff| - depthFavor * depthDiff)?
|
||||
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
|
||||
// works in physics (G m1 m2/d^2 and k_e m1 m2/d^2). Even though we add a depth dimension to the world, we keep
|
||||
// the weight inversly proportionally to the area of a sphere (the square of the distance) rather than a
|
||||
// hypersphere (the cube of the area) because the y coordinate does not matter for now. We use m^2/d + d
|
||||
// rather than d such that the probability near 0 tends to 0 rather than infinity. f(m^2/d) is a special case
|
||||
// of f((m^(a+1)/a)/d^a). m is the location of f's maximum. The constant 4m/pi makes it such that a newRiftWeight
|
||||
// of 1 is equivalent to having a total link weight of 1 distributed equally across all layers.
|
||||
// TODO: We might want an a larger than 1 to make the function closer to 1/d^2
|
||||
double weight = 4 * weightMaximum / Math.PI * otherWeight / sq(sq(weightMaximum) / distance + distance);
|
||||
possibleDestWeightMap.put(link, (float) weight);
|
||||
}
|
||||
|
||||
AvailableLink selectedLink;
|
||||
if (possibleDestWeightMap.size() == 0) {
|
||||
if (newRiftWeight == -1) {
|
||||
selectedLink = null;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
selectedLink = MathUtils.weightedRandom(possibleDestWeightMap);
|
||||
}
|
||||
|
||||
// Check if we have to generate a new rift
|
||||
if (selectedLink == null) {
|
||||
// Randomly select a distance from the distribution f(x) = 1/(m^2/x + x)^2. We use the same distribution as the
|
||||
// weighting function. The idea is that there is some kind of "field" formed by the rift, with the field's
|
||||
// intensity decreasing proportionally to the area of the sphere. The product of the area of the sphere and
|
||||
// the intesity of the field at that radius is therefore constant, so the infinitsimal weight of any layer
|
||||
// will be constant and its weight will therefore simply be the original weight function at that value.
|
||||
//
|
||||
// The inverse of the normalized distribution function can be generated by this Mathematica code:
|
||||
// distribution = 1/(m^2/x + x)^2
|
||||
// totalDistributionIntegral = Integrate[distribution, {x, 0, Infinity}, Assumptions -> m > 0];
|
||||
// normalizedDistribution = Simplify[distribution/totalDistributionIntegral]
|
||||
// cummulativeNormalizedDistribution = Simplify[Integrate[normalizedDistribution, x] - (Integrate[normalizedDistribution, x] /. x -> 0)]
|
||||
//
|
||||
// m = 1; (*Doesn't matter which m you use, it's proportional*)
|
||||
// table = Table[{r, x /. FindRoot[cummulativeNormalizedDistribution - r, {x, m}]}, {r, 0.01, 0.99, 0.01}];
|
||||
// fit = NonlinearModelFit[table, m (2 Tan[Pi/2 x] + a Log[x] Sqrt[x]), {a}, x]
|
||||
// Show[ListPlot[table], Plot[fit[x], {x, 0, 1}]]
|
||||
// Clear[m];
|
||||
// inverseCummulativeNormalizedDistribution = Normal[fit]
|
||||
double r = Math.random();
|
||||
double distance = weightMaximum * (2 * Math.tan(Math.PI / 2 * r) - 0.5578284481138029 * Math.sqrt(r) * Math.log(r));
|
||||
|
||||
// Randomly split the vector into depth, x, and z components
|
||||
double theta = Math.random() * Math.PI; // Angle between vector and xz plane
|
||||
double phi = Math.random() * Math.PI; // Angle of the vector on the xz plane relative to the x axis
|
||||
double depth = distance * Math.sin(theta);
|
||||
depth /= depth > 0 ? positiveDepthFactor : negativeDepthFactor;
|
||||
double x = Math.cos(theta) * Math.cos(phi) * distance / coordFactor;
|
||||
double z = Math.cos(theta) * Math.sin(phi) * distance / coordFactor;
|
||||
VirtualLocation virtualLocation = new VirtualLocation(rift.getVirtualLocation().getDim(),
|
||||
rift.getVirtualLocation().getX() + (int) Math.round(x),
|
||||
rift.getVirtualLocation().getZ() + (int) Math.round(z),
|
||||
rift.getVirtualLocation().getDepth() + (int) Math.round(depth));
|
||||
|
||||
if (virtualLocation.getDepth() <= 0) {
|
||||
// This will lead to the overworld
|
||||
World world = WorldUtils.getWorld(virtualLocation.getDim());
|
||||
BlockPos pos = world.getTopSolidOrLiquidBlock(new BlockPos(virtualLocation.getX(), 0, virtualLocation.getZ()));
|
||||
world.setBlockState(pos, ModBlocks.RIFT.getDefaultState());
|
||||
|
||||
TileEntityFloatingRift riftEntity = (TileEntityFloatingRift) world.getTileEntity(pos);
|
||||
// TODO: Should the rift not be configured like the other link
|
||||
rift.markDirty();
|
||||
AvailableLink newLink = thisLink.toBuilder().linksRemaining(0).id(UUID.randomUUID()).build();
|
||||
riftEntity.addAvailableLink(newLink);
|
||||
if (!noLinkBack) riftEntity.addDestination(new GlobalDestination(rift.getLocation()), 1, 0, toBuilder().linkId(newLink.id).build());
|
||||
if (!noLink) rift.makeDestinationPermanent(weightedDestination, riftEntity.getLocation());
|
||||
riftEntity.teleportTo(entity);
|
||||
} else {
|
||||
// Make a new dungeon pocket
|
||||
//Pocket pocket = PocketGenerator.generateDungeonPocket(virtualLocation);
|
||||
Pocket pocket = PocketGenerator.generatePublicPocket(virtualLocation);
|
||||
pocket.setup();
|
||||
rift.markDirty();
|
||||
AvailableLink newLink = thisLink.toBuilder().linksRemaining(0).build();
|
||||
pocket.linkPocketTo(new GlobalDestination(/*noLinkBack ? null :*/ rift.getLocation()), toBuilder().linkId(newLink.id).build(), newLink); // TODO: linkId
|
||||
if (!noLink) rift.makeDestinationPermanent(weightedDestination, pocket.getEntrance());
|
||||
((TileEntityRift) pocket.getEntrance().getTileEntity()).teleportTo(entity);
|
||||
}
|
||||
} else {
|
||||
// An existing rift was selected
|
||||
TileEntityRift riftEntity = (TileEntityRift) selectedLink.rift.getTileEntity();
|
||||
|
||||
selectedLink.linksRemaining--;
|
||||
RiftRegistry.getRegistry(riftEntity.getLocation()).markDirty();
|
||||
|
||||
// Link the selected rift back if necessary
|
||||
if (selectedLink.replaceDestination != null) {
|
||||
riftEntity.makeDestinationPermanent(riftEntity.getDestination(selectedLink.replaceDestination), rift.getLocation());
|
||||
}
|
||||
|
||||
// Link this rift if necessary and teleport the entity
|
||||
if (!noLink) rift.makeDestinationPermanent(weightedDestination, selectedLink.rift);
|
||||
riftEntity.teleportTo(entity);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private double sq(double a) { return a * a; }
|
||||
}
|
|
@ -1,7 +1,9 @@
|
|||
package org.dimdev.dimdoors.shared.rifts;
|
||||
package org.dimdev.dimdoors.shared.rifts.destinations;
|
||||
|
||||
import org.dimdev.dimdoors.DimDoors;
|
||||
import org.dimdev.dimdoors.shared.VirtualLocation;
|
||||
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.ddutils.Location;
|
||||
|
@ -38,7 +40,8 @@ public class EscapeDestination extends RiftDestination {
|
|||
if (uuid != null) {
|
||||
Location destLoc = RiftRegistry.getOverworldRift(uuid);
|
||||
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
|
||||
return true;
|
||||
} else {
|
||||
if (destLoc == null) {
|
|
@ -1,4 +1,4 @@
|
|||
package org.dimdev.dimdoors.shared.rifts;
|
||||
package org.dimdev.dimdoors.shared.rifts.destinations;
|
||||
|
||||
import org.dimdev.ddutils.Location;
|
||||
import lombok.AllArgsConstructor;
|
||||
|
@ -10,6 +10,8 @@ import net.minecraft.nbt.NBTTagCompound;
|
|||
import org.dimdev.ddutils.nbt.NBTUtils;
|
||||
import org.dimdev.annotatednbt.Saved;
|
||||
import org.dimdev.annotatednbt.NBTSerializable;
|
||||
import org.dimdev.dimdoors.shared.rifts.RiftDestination;
|
||||
import org.dimdev.dimdoors.shared.rifts.TileEntityRift;
|
||||
|
||||
@Getter @AllArgsConstructor @Builder(toBuilder = true) @ToString
|
||||
@NBTSerializable public class GlobalDestination extends RiftDestination { // TODO: location directly in nbt like minecraft?
|
|
@ -1,5 +1,7 @@
|
|||
package org.dimdev.dimdoors.shared.rifts;
|
||||
package org.dimdev.dimdoors.shared.rifts.destinations;
|
||||
|
||||
import org.dimdev.dimdoors.shared.rifts.RiftDestination;
|
||||
import org.dimdev.dimdoors.shared.rifts.TileEntityRift;
|
||||
import org.dimdev.dimdoors.shared.world.limbodimension.WorldProviderLimbo;
|
||||
import org.dimdev.ddutils.TeleportUtils;
|
||||
import lombok.AllArgsConstructor;
|
|
@ -1,4 +1,4 @@
|
|||
package org.dimdev.dimdoors.shared.rifts;
|
||||
package org.dimdev.dimdoors.shared.rifts.destinations;
|
||||
|
||||
import org.dimdev.ddutils.Location;
|
||||
import org.dimdev.ddutils.nbt.NBTUtils;
|
||||
|
@ -11,6 +11,8 @@ import net.minecraft.nbt.NBTTagCompound;
|
|||
import net.minecraft.util.math.BlockPos;
|
||||
import org.dimdev.annotatednbt.Saved;
|
||||
import org.dimdev.annotatednbt.NBTSerializable;
|
||||
import org.dimdev.dimdoors.shared.rifts.RiftDestination;
|
||||
import org.dimdev.dimdoors.shared.rifts.TileEntityRift;
|
||||
|
||||
@Getter @AllArgsConstructor @Builder(toBuilder = true) @ToString
|
||||
@NBTSerializable public class LocalDestination extends RiftDestination { // TODO: use BlockPos
|
|
@ -1,4 +1,4 @@
|
|||
package org.dimdev.dimdoors.shared.rifts;
|
||||
package org.dimdev.dimdoors.shared.rifts.destinations;
|
||||
|
||||
import org.dimdev.dimdoors.shared.VirtualLocation;
|
||||
import org.dimdev.dimdoors.shared.pockets.Pocket;
|
||||
|
@ -9,6 +9,8 @@ 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.
|
||||
|
@ -28,14 +30,14 @@ public class NewPublicDestination extends RiftDestination { // TODO: more config
|
|||
@Override
|
||||
public boolean teleport(TileEntityRift rift, Entity entity) {
|
||||
VirtualLocation newVirtualLocation = null;
|
||||
if (rift.virtualLocation != null) {
|
||||
int depth = rift.virtualLocation.getDepth();
|
||||
if (rift.getVirtualLocation() != null) {
|
||||
int depth = rift.getVirtualLocation().getDepth();
|
||||
if (depth == 0) depth++;
|
||||
newVirtualLocation = new VirtualLocation(rift.virtualLocation.getLocation(), depth);
|
||||
newVirtualLocation = rift.getVirtualLocation().toBuilder().depth(depth).build();
|
||||
}
|
||||
Pocket pocket = PocketGenerator.generatePublicPocket(newVirtualLocation);
|
||||
pocket.setup();
|
||||
pocket.linkPocketTo(new GlobalDestination(rift.getLocation()));
|
||||
pocket.linkPocketTo(new GlobalDestination(rift.getLocation()), null, null);
|
||||
rift.makeDestinationPermanent(weightedDestination, pocket.getEntrance());
|
||||
((TileEntityRift) pocket.getEntrance().getTileEntity()).teleportTo(entity);
|
||||
return true;
|
|
@ -1,4 +1,4 @@
|
|||
package org.dimdev.dimdoors.shared.rifts;
|
||||
package org.dimdev.dimdoors.shared.rifts.destinations;
|
||||
|
||||
import org.dimdev.ddutils.nbt.NBTUtils;
|
||||
import org.dimdev.annotatednbt.Saved;
|
||||
|
@ -11,6 +11,9 @@ import lombok.ToString;
|
|||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import org.dimdev.dimdoors.shared.rifts.RiftDestination;
|
||||
import org.dimdev.dimdoors.shared.rifts.TileEntityRift;
|
||||
import org.dimdev.dimdoors.shared.rifts.WeightedRiftDestination;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
|
@ -1,4 +1,4 @@
|
|||
package org.dimdev.dimdoors.shared.rifts;
|
||||
package org.dimdev.dimdoors.shared.rifts.destinations;
|
||||
|
||||
import org.dimdev.dimdoors.DimDoors;
|
||||
import lombok.AllArgsConstructor;
|
||||
|
@ -8,6 +8,8 @@ import lombok.ToString;
|
|||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import org.dimdev.dimdoors.shared.rifts.RiftDestination;
|
||||
import org.dimdev.dimdoors.shared.rifts.TileEntityRift;
|
||||
|
||||
@Getter @AllArgsConstructor @Builder(toBuilder = true) @ToString
|
||||
public class PocketExitDestination extends RiftDestination {
|
|
@ -1,9 +1,12 @@
|
|||
package org.dimdev.dimdoors.shared.rifts;
|
||||
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.PocketGenerator;
|
||||
import org.dimdev.dimdoors.shared.pockets.PocketRegistry;
|
||||
import org.dimdev.dimdoors.shared.rifts.RiftDestination;
|
||||
import org.dimdev.dimdoors.shared.rifts.RiftRegistry;
|
||||
import org.dimdev.dimdoors.shared.rifts.TileEntityRift;
|
||||
import org.dimdev.dimdoors.shared.world.ModDimensions;
|
||||
import org.dimdev.ddutils.EntityUtils;
|
||||
import org.dimdev.ddutils.Location;
|
||||
|
@ -37,7 +40,7 @@ public class PrivateDestination extends RiftDestination {
|
|||
RiftRegistry privateRiftRegistry = RiftRegistry.getForDim(ModDimensions.getPrivateDim());
|
||||
Pocket pocket = privatePocketRegistry.getPocket(privatePocketRegistry.getPrivatePocketID(uuid));
|
||||
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 = PocketGenerator.generatePrivatePocket(rift.getVirtualLocation() != null ? rift.getVirtualLocation().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);
|
||||
|
@ -48,7 +51,7 @@ public class PrivateDestination extends RiftDestination {
|
|||
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 = PocketGenerator.generatePrivatePocket(rift.getVirtualLocation() != null ? rift.getVirtualLocation().toBuilder().depth(-1).build() : null);
|
||||
pocket.setup();
|
||||
privatePocketRegistry.setPrivatePocketID(uuid, pocket.getId());
|
||||
destLoc = pocket.getEntrance();
|
|
@ -1,8 +1,11 @@
|
|||
package org.dimdev.dimdoors.shared.rifts;
|
||||
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;
|
|
@ -1,4 +1,4 @@
|
|||
package org.dimdev.dimdoors.shared.rifts;
|
||||
package org.dimdev.dimdoors.shared.rifts.destinations;
|
||||
|
||||
import org.dimdev.ddutils.Location;
|
||||
import org.dimdev.ddutils.nbt.NBTUtils;
|
||||
|
@ -11,6 +11,8 @@ import net.minecraft.nbt.NBTTagCompound;
|
|||
import net.minecraft.util.math.Vec3i;
|
||||
import org.dimdev.annotatednbt.Saved;
|
||||
import org.dimdev.annotatednbt.NBTSerializable;
|
||||
import org.dimdev.dimdoors.shared.rifts.RiftDestination;
|
||||
import org.dimdev.dimdoors.shared.rifts.TileEntityRift;
|
||||
|
||||
@Getter @AllArgsConstructor @Builder(toBuilder = true) @ToString
|
||||
@NBTSerializable public class RelativeDestination extends RiftDestination { // TODO: use Vec3i
|
|
@ -7,6 +7,9 @@ import org.dimdev.dimdoors.shared.blocks.BlockDimensionalDoor;
|
|||
import org.dimdev.dimdoors.shared.blocks.BlockFabric;
|
||||
import org.dimdev.dimdoors.shared.blocks.ModBlocks;
|
||||
import org.dimdev.dimdoors.shared.rifts.*;
|
||||
import org.dimdev.dimdoors.shared.rifts.destinations.PocketEntranceDestination;
|
||||
import org.dimdev.dimdoors.shared.rifts.destinations.PocketExitDestination;
|
||||
import org.dimdev.dimdoors.shared.rifts.destinations.PrivatePocketExitDestination;
|
||||
import org.dimdev.dimdoors.shared.tileentities.TileEntityEntranceRift;
|
||||
import org.dimdev.ddutils.schem.Schematic;
|
||||
import net.minecraft.block.BlockDoor;
|
||||
|
|
Loading…
Reference in a new issue