Fix crash on exiting personal pocket dimension #185

Closed
notabadminer wants to merge 67 commits from master into master
262 changed files with 13535 additions and 4251 deletions
Showing only changes of commit fe04c99890 - Show all commits

View File

@@ -13,14 +13,15 @@ buildscript {
apply plugin: 'forge' apply plugin: 'forge'
version = "2.2.4-" + System.getenv("BUILD_NUMBER")
version = "2.2.2RC1-" + System.getenv("BUILD_NUMBER")
group = "com.stevenrs11.dimdoors" // http://maven.apache.org/guides/mini/guide-naming-conventions.html group = "com.stevenrs11.dimdoors" // http://maven.apache.org/guides/mini/guide-naming-conventions.html
archivesBaseName = "DimensionalDoors" archivesBaseName = "DimensionalDoors"
minecraft { minecraft {
version = "1.6.4-9.11.1.964" version = "1.6.4-9.11.1.964"
replaceIn "mod_pocketDim.java"
replace "@VERSION@", project.version
} }
targetCompatibility = '1.6' targetCompatibility = '1.6'
@@ -28,15 +29,15 @@ sourceCompatibility = '1.6'
processResources processResources
{ {
// replace stuff in mcmod.info, nothing else // Replace stuff $version and $mcversion in mcmod.info
from(sourceSets.main.resources.srcDirs) { from(sourceSets.main.resources.srcDirs) {
include 'mcmod.info' include 'mcmod.info'
// replace version and mcversion // Replace version and mcversion
expand 'version':project.version, 'mcversion':project.minecraft.version expand 'version':project.version, 'mcversion':project.minecraft.version
} }
// copy everything else, thats not the mcmod.info // Copy everything else
from(sourceSets.main.resources.srcDirs) { from(sourceSets.main.resources.srcDirs) {
exclude 'mcmod.info' exclude 'mcmod.info'
} }

View File

@@ -12,8 +12,8 @@ import net.minecraft.tileentity.TileEntityChest;
import net.minecraft.tileentity.TileEntityDispenser; import net.minecraft.tileentity.TileEntityDispenser;
import net.minecraft.world.World; import net.minecraft.world.World;
import StevenDimDoors.mod_pocketDim.DDLoot; import StevenDimDoors.mod_pocketDim.DDLoot;
import StevenDimDoors.mod_pocketDim.DDProperties;
import StevenDimDoors.mod_pocketDim.Point3D; import StevenDimDoors.mod_pocketDim.Point3D;
import StevenDimDoors.mod_pocketDim.config.DDProperties;
import StevenDimDoors.mod_pocketDim.schematic.WorldOperation; import StevenDimDoors.mod_pocketDim.schematic.WorldOperation;
/** /**

View File

@@ -1,11 +1,14 @@
package StevenDimDoors.mod_pocketDim; package StevenDimDoors.mod_pocketDim;
import java.io.File; import java.io.File;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import StevenDimDoors.mod_pocketDim.blocks.BaseDimDoor;
import StevenDimDoors.mod_pocketDim.tileentities.TileEntityDimDoor;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.CompressedStreamTools; import net.minecraft.nbt.CompressedStreamTools;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World; import net.minecraft.world.World;
import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.network.IGuiHandler; import cpw.mods.fml.common.network.IGuiHandler;
@@ -18,7 +21,6 @@ public class CommonProxy implements IGuiHandler
public static String WARP_PNG = "/WARP.png"; public static String WARP_PNG = "/WARP.png";
public void registerRenderers() public void registerRenderers()
{ {
} }
public void registerEntity(Class <? extends Entity > entity, String entityname, int id, Object mod, int trackingrange, int updateFreq, boolean updatevelo) public void registerEntity(Class <? extends Entity > entity, String entityname, int id, Object mod, int trackingrange, int updateFreq, boolean updatevelo)
@@ -130,6 +132,20 @@ public class CommonProxy implements IGuiHandler
{ {
} }
public void updateDoorTE(BaseDimDoor door, World world, int x, int y, int z)
{
TileEntity tile = world.getBlockTileEntity(x, y, z);
if (tile instanceof TileEntityDimDoor)
{
int metadata = world.getBlockMetadata(x, y, z);
TileEntityDimDoor dimTile = (TileEntityDimDoor) tile;
dimTile.openOrClosed = door.isDoorOnRift(world, x, y, z)&&door.isUpperDoorBlock(metadata);
dimTile.orientation = door.getFullMetadata(world, x, y, z) & 7;
dimTile.lockStatus = door.getLockStatus(world, x, y, z);
}
}
} }

View File

@@ -1,17 +1,11 @@
package StevenDimDoors.mod_pocketDim; package StevenDimDoors.mod_pocketDim;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.network.INetworkManager; import net.minecraft.network.INetworkManager;
import net.minecraft.network.NetLoginHandler; import net.minecraft.network.NetLoginHandler;
import net.minecraft.network.packet.NetHandler; import net.minecraft.network.packet.NetHandler;
import net.minecraft.network.packet.Packet1Login; import net.minecraft.network.packet.Packet1Login;
import net.minecraft.network.packet.Packet250CustomPayload; import net.minecraft.network.packet.Packet250CustomPayload;
import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
import net.minecraft.server.integrated.IntegratedServer;
import net.minecraftforge.common.DimensionManager; import net.minecraftforge.common.DimensionManager;
import net.minecraftforge.common.network.ForgePacket; import net.minecraftforge.common.network.ForgePacket;
import net.minecraftforge.common.network.packet.DimensionRegisterPacket; import net.minecraftforge.common.network.packet.DimensionRegisterPacket;
@@ -65,7 +59,8 @@ public class ConnectionHandler implements IConnectionHandler
@Override @Override
public void playerLoggedIn(Player player, NetHandler netHandler, INetworkManager manager) public void playerLoggedIn(Player player, NetHandler netHandler, INetworkManager manager)
{ {
PocketManager.getDimwatcher().onCreated(new ClientDimData(PocketManager.getDimensionData(0))); // Hax... please don't do this! >_<
PocketManager.getDimwatcher().onCreated(new ClientDimData(PocketManager.createDimensionDataDangerously(0)));
} }
} }

View File

@@ -1,97 +1,170 @@
package StevenDimDoors.mod_pocketDim; package StevenDimDoors.mod_pocketDim;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockDispenser;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraftforge.oredict.ShapedOreRecipe;
import StevenDimDoors.mod_pocketDim.config.DDProperties;
import StevenDimDoors.mod_pocketDim.core.DDLock;
import StevenDimDoors.mod_pocketDim.items.ItemDDKey;
import StevenDimDoors.mod_pocketDim.items.behaviors.DispenserBehaviorStabilizedRS;
import cpw.mods.fml.common.ICraftingHandler;
import cpw.mods.fml.common.registry.GameRegistry; import cpw.mods.fml.common.registry.GameRegistry;
import static StevenDimDoors.mod_pocketDim.mod_pocketDim.*;
public class CraftingManager public class CraftingManager implements ICraftingHandler
{ {
CraftingManager() { }
public static void registerRecipes(DDProperties properties) public static void registerRecipes(DDProperties properties)
{ {
if (properties.CraftingStableFabricAllowed)
{
switch (properties.WorldThreadRequirementLevel)
{
case 1:
GameRegistry.addShapelessRecipe(new ItemStack(mod_pocketDim.itemStableFabric, 1),
Item.enderPearl, mod_pocketDim.itemWorldThread);
break;
case 2:
GameRegistry.addRecipe(new ItemStack(mod_pocketDim.itemStableFabric, 1),
"yxy", 'x', Item.enderPearl, 'y', mod_pocketDim.itemWorldThread);
break;
case 3:
GameRegistry.addRecipe(new ItemStack(mod_pocketDim.itemStableFabric, 1),
" y ", "yxy", " y ", 'x', Item.enderPearl, 'y', mod_pocketDim.itemWorldThread);
break;
default:
GameRegistry.addRecipe(new ItemStack(mod_pocketDim.itemStableFabric, 1),
"yyy", "yxy", "yyy", 'x', Item.enderPearl, 'y', mod_pocketDim.itemWorldThread);
break;
}
}
if (properties.CraftingDimensionalDoorAllowed) if (properties.CraftingDimensionalDoorAllowed)
{ {
GameRegistry.addRecipe(new ItemStack(itemDimensionalDoor, 1), new Object[] GameRegistry.addRecipe(new ItemStack(mod_pocketDim.itemDimensionalDoor, 1),
{ "yxy", 'x', mod_pocketDim.itemStableFabric, 'y', Item.doorIron);
" ", "yxy", " ", 'x', mod_pocketDim.itemStableFabric, 'y', Item.doorIron
});
} }
if (properties.CraftingUnstableDoorAllowed) if (properties.CraftingUnstableDoorAllowed)
{ {
GameRegistry.addRecipe(new ItemStack(itemUnstableDoor, 1), new Object[] GameRegistry.addRecipe(new ItemStack(mod_pocketDim.itemUnstableDoor, 1),
{ "yxy", 'x', Item.eyeOfEnder, 'y', mod_pocketDim.itemDimensionalDoor);
" ", "yxy", " ", 'x', Item.eyeOfEnder, 'y', mod_pocketDim.itemDimensionalDoor
});
} }
if (properties.CraftingWarpDoorAllowed) if (properties.CraftingWarpDoorAllowed)
{ {
GameRegistry.addRecipe(new ItemStack(itemWarpDoor, 1), new Object[]
{ GameRegistry.addRecipe(new ItemStack(mod_pocketDim.itemWarpDoor, 1),
" ", "yxy", " ", 'x', mod_pocketDim.itemStableFabric, 'y', Item.doorWood "yxy", 'x', Item.enderPearl, 'y', Item.doorWood);
});
} }
if (properties.CraftingTransTrapdoorAllowed) if (properties.CraftingTransTrapdoorAllowed)
{ {
GameRegistry.addRecipe(new ItemStack(transTrapdoor, 1), new Object[]
{ GameRegistry.addRecipe(new ItemStack(mod_pocketDim.transTrapdoor, 1),
" y ", " x ", " y ", 'x', mod_pocketDim.itemStableFabric, 'y', Block.trapdoor "y", "x", "y", 'x', Item.enderPearl, 'y', Block.trapdoor);
});
} }
if (properties.CraftingRiftSignatureAllowed) if (properties.CraftingRiftSignatureAllowed)
{ {
GameRegistry.addRecipe(new ItemStack(itemRiftSignature, 1), new Object[]
{
" y ", "yxy", " y ", 'x', mod_pocketDim.itemStableFabric, 'y', Item.ingotIron
});
}
GameRegistry.addRecipe(new ItemStack(mod_pocketDim.itemRiftSignature, 1),
" y ", "yxy", " y ", 'x', Item.enderPearl, 'y', Item.ingotIron);
}
if (properties.CraftingRiftRemoverAllowed) if (properties.CraftingRiftRemoverAllowed)
{ {
GameRegistry.addRecipe(new ItemStack(itemRiftRemover, 1), new Object[]
{
"yyy", "yxy", "yyy", 'x', mod_pocketDim.itemStableFabric, 'y', Item.ingotGold
});
}
GameRegistry.addRecipe(new ItemStack(mod_pocketDim.itemRiftRemover, 1),
"yyy", "yxy", "yyy", 'x', Item.enderPearl, 'y', Item.ingotGold);
}
if (properties.CraftingRiftBladeAllowed) if (properties.CraftingRiftBladeAllowed)
{ {
GameRegistry.addRecipe(new ItemStack(itemRiftBlade, 1), new Object[] GameRegistry.addRecipe(new ItemStack(mod_pocketDim.itemRiftBlade, 1),
{ "x", "x", "y", 'x', mod_pocketDim.itemStableFabric, 'y', Item.blazeRod);
" x ", " x ", " y ", 'x', mod_pocketDim.itemStableFabric, 'y', Item.blazeRod
});
} }
if (properties.CraftingStableFabricAllowed)
{
GameRegistry.addRecipe(new ItemStack(itemStableFabric, 1), new Object[]
{
"yyy", "yxy", "yyy", 'x', Item.enderPearl, 'y', mod_pocketDim.itemWorldThread
});
}
if (properties.CraftingStabilizedRiftSignatureAllowed) if (properties.CraftingStabilizedRiftSignatureAllowed)
{ {
GameRegistry.addRecipe(new ItemStack(mod_pocketDim.itemStabilizedLinkSignature,1), new Object[]
{ GameRegistry.addRecipe(new ItemStack(mod_pocketDim.itemStabilizedRiftSignature, 1),
" y ", "yxy", " y ", 'x', mod_pocketDim.itemRiftSignature, 'y', mod_pocketDim.itemStableFabric " y ", "yxy", " y ", 'x', mod_pocketDim.itemStableFabric, 'y', Item.ingotIron);
});
} }
if (properties.CraftingGoldenDimensionalDoorAllowed) if (properties.CraftingGoldenDimensionalDoorAllowed)
{ {
GameRegistry.addRecipe(new ItemStack(mod_pocketDim.itemGoldenDimensionalDoor,1), new Object[] GameRegistry.addRecipe(new ItemStack(mod_pocketDim.itemGoldenDimensionalDoor, 1),
{ "yxy", 'x', mod_pocketDim.itemStableFabric, 'y', mod_pocketDim.itemGoldenDoor);
" ", "xyx", " ", 'x', mod_pocketDim.itemGoldenDoor, 'y', Item.eyeOfEnder
});
} }
if (properties.CraftingGoldenDoorAllowed) if (properties.CraftingGoldenDoorAllowed)
{ {
GameRegistry.addRecipe(new ItemStack(mod_pocketDim.itemGoldenDoor, 1), new Object[] GameRegistry.addRecipe(new ItemStack(mod_pocketDim.itemGoldenDoor, 1),
{ "yy", "yy", "yy", 'y', Item.ingotGold);
"yy ", "yy ", "yy ", 'y', Item.ingotGold
});
} }
if (properties.CraftingPersonalDimDoorAllowed)
{
GameRegistry.addRecipe(new ItemStack(mod_pocketDim.itemPersonalDoor,1),
"yxy", 'y', mod_pocketDim.itemGoldenDoor, 'x', mod_pocketDim.itemStableFabric);
}
if (properties.CraftingQuartzDoorAllowed)
{
GameRegistry.addRecipe(new ShapedOreRecipe(mod_pocketDim.itemQuartzDoor, new Object[]{
"yy", "yy", "yy", Character.valueOf('y'), "oreQuartz"}));
}
if (properties.CraftingDDKeysAllowed)
{
GameRegistry.addRecipe(new ItemStack(mod_pocketDim.itemDDKey, 1),
" z", " y ", "y ", 'y', Item.ingotGold, 'z', Item.enderPearl);
GameRegistry.addRecipe(new ItemStack(mod_pocketDim.itemDDKey, 1),
"z", "z", 'z', mod_pocketDim.itemDDKey);
} }
} }
@Override
public void onCrafting(EntityPlayer player, ItemStack item, IInventory craftMatrix)
{
if(item.getItem() instanceof ItemDDKey)
{
ItemDDKey keyItem = (ItemDDKey) item.getItem();
ItemStack topKey = null;
ItemStack bottomKey = null;
int topKeySlot = 0;
for(int i = 0; i<craftMatrix.getSizeInventory();i++)
{
ItemStack slot = craftMatrix.getStackInSlot(i);
if(slot!=null)
{
if(topKey==null)
{
topKey = slot;
topKeySlot = i;
}
else
{
bottomKey = slot;
break;
}
}
}
DDLock.addKeys(bottomKey, DDLock.getKeys(topKey));
item.setTagCompound(bottomKey.getTagCompound());
player.inventory.addItemStackToInventory(topKey);
}
}
@Override
public void onSmelting(EntityPlayer player, ItemStack item)
{
// TODO Auto-generated method stub
}
public static void registerDispenserBehaviors()
{
// Register the dispenser behaviors for certain DD items
BlockDispenser.dispenseBehaviorRegistry.putObject(mod_pocketDim.itemStabilizedRiftSignature, new DispenserBehaviorStabilizedRS());
}
}

View File

@@ -12,6 +12,7 @@ import net.minecraft.util.MathHelper;
import net.minecraft.util.WeightedRandom; import net.minecraft.util.WeightedRandom;
import net.minecraft.util.WeightedRandomChestContent; import net.minecraft.util.WeightedRandomChestContent;
import net.minecraftforge.common.ChestGenHooks; import net.minecraftforge.common.ChestGenHooks;
import StevenDimDoors.mod_pocketDim.config.DDProperties;
import StevenDimDoors.mod_pocketDim.util.WeightedContainer; import StevenDimDoors.mod_pocketDim.util.WeightedContainer;
/* /*
@@ -19,7 +20,7 @@ import StevenDimDoors.mod_pocketDim.util.WeightedContainer;
*/ */
public class DDLoot { public class DDLoot {
private static final String[] SPECIAL_SKULL_OWNERS = new String[] { "stevenrs11", "kamikazekiwi3", "Jaitsu", "XCompWiz", "skyboy026", "Wylker" }; private static final String[] SPECIAL_SKULL_OWNERS = new String[] { "stevenrs11", "kamikazekiwi3", "fbt", "Jaitsu", "XCompWiz", "skyboy026", "Wylker" };
private static final double MIN_ITEM_DAMAGE = 0.3; private static final double MIN_ITEM_DAMAGE = 0.3;
private static final double MAX_ITEM_DAMAGE = 0.9; private static final double MAX_ITEM_DAMAGE = 0.9;
@@ -30,7 +31,7 @@ public class DDLoot {
public static final String DIMENSIONAL_DUNGEON_CHEST = "dimensionalDungeonChest"; public static final String DIMENSIONAL_DUNGEON_CHEST = "dimensionalDungeonChest";
public static ChestGenHooks DungeonChestInfo = null; public static ChestGenHooks DungeonChestInfo = null;
private static final int CHEST_SIZE = 5; private static final int CHEST_SIZE = 6;
private DDLoot() { } private DDLoot() { }
@@ -55,7 +56,7 @@ public class DDLoot {
addContent(true, items, Item.appleGold.itemID, 10); addContent(true, items, Item.appleGold.itemID, 10);
addContent(properties.FabricOfRealityLootEnabled, items, mod_pocketDim.blockDimWall.blockID, 20, 16, 64); addContent(properties.FabricOfRealityLootEnabled, items, mod_pocketDim.blockDimWall.blockID, 20, 16, 64);
addContent(properties.WorldThreadLootEnabled, items, mod_pocketDim.itemWorldThread.itemID, 80, 2, 8); addContent(properties.WorldThreadLootEnabled, items, mod_pocketDim.itemWorldThread.itemID, 80, 2, 12);
// Add all the items to our dungeon chest // Add all the items to our dungeon chest
addItemsToContainer(DungeonChestInfo, items); addItemsToContainer(DungeonChestInfo, items);

View File

@@ -8,6 +8,8 @@ import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import StevenDimDoors.mod_pocketDim.config.DDProperties;
import net.minecraft.util.MathHelper; import net.minecraft.util.MathHelper;
import net.minecraft.world.World; import net.minecraft.world.World;
@Deprecated @Deprecated

View File

@@ -1,15 +1,14 @@
package StevenDimDoors.mod_pocketDim; package StevenDimDoors.mod_pocketDim;
import net.minecraft.block.Block;
import net.minecraft.client.audio.SoundManager; import net.minecraft.client.audio.SoundManager;
import net.minecraft.client.audio.SoundPoolEntry; import net.minecraft.client.audio.SoundPoolEntry;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemDoor;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.ChunkCoordinates; import net.minecraft.util.DamageSource;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraft.world.WorldProvider;
import net.minecraft.world.chunk.Chunk;
import net.minecraftforge.client.event.sound.PlayBackgroundMusicEvent; import net.minecraftforge.client.event.sound.PlayBackgroundMusicEvent;
import net.minecraftforge.client.event.sound.SoundLoadEvent; import net.minecraftforge.client.event.sound.SoundLoadEvent;
import net.minecraftforge.event.EventPriority; import net.minecraftforge.event.EventPriority;
@@ -17,11 +16,20 @@ import net.minecraftforge.event.ForgeSubscribe;
import net.minecraftforge.event.entity.living.LivingDeathEvent; import net.minecraftforge.event.entity.living.LivingDeathEvent;
import net.minecraftforge.event.entity.living.LivingFallEvent; import net.minecraftforge.event.entity.living.LivingFallEvent;
import net.minecraftforge.event.entity.player.PlayerInteractEvent; import net.minecraftforge.event.entity.player.PlayerInteractEvent;
import net.minecraftforge.event.entity.player.PlayerInteractEvent.Action;
import net.minecraftforge.event.terraingen.InitMapGenEvent; import net.minecraftforge.event.terraingen.InitMapGenEvent;
import net.minecraftforge.event.world.ChunkEvent;
import net.minecraftforge.event.world.WorldEvent; import net.minecraftforge.event.world.WorldEvent;
import StevenDimDoors.mod_pocketDim.config.DDProperties;
import StevenDimDoors.mod_pocketDim.config.DDWorldProperties;
import StevenDimDoors.mod_pocketDim.core.DDTeleporter; import StevenDimDoors.mod_pocketDim.core.DDTeleporter;
import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.DimensionType;
import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager; import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.items.BaseItemDoor; import StevenDimDoors.mod_pocketDim.items.BaseItemDoor;
import StevenDimDoors.mod_pocketDim.items.ItemWarpDoor;
import StevenDimDoors.mod_pocketDim.ticking.RiftRegenerator;
import StevenDimDoors.mod_pocketDim.util.Point4D; import StevenDimDoors.mod_pocketDim.util.Point4D;
import StevenDimDoors.mod_pocketDim.world.LimboProvider; import StevenDimDoors.mod_pocketDim.world.LimboProvider;
import StevenDimDoors.mod_pocketDim.world.PocketProvider; import StevenDimDoors.mod_pocketDim.world.PocketProvider;
@@ -31,24 +39,37 @@ import cpw.mods.fml.relauncher.SideOnly;
public class EventHookContainer public class EventHookContainer
{ {
private static final int MAX_FOOD_LEVEL = 20;
private final DDProperties properties; private final DDProperties properties;
private DDWorldProperties worldProperties;
private RiftRegenerator regenerator;
public EventHookContainer(DDProperties properties) public EventHookContainer(DDProperties properties)
{ {
this.properties = properties; this.properties = properties;
} }
@ForgeSubscribe(priority = EventPriority.LOW) public void setSessionFields(DDWorldProperties worldProperties, RiftRegenerator regenerator)
public void onMapGen(InitMapGenEvent event)
{ {
// Replace the Nether fortress generator with our own only if any gateways would ever generate. // SenseiKiwi:
// This allows admins to disable our fortress overriding without disabling all gateways. // Why have a setter rather than accessing mod_pocketDim directly?
/* // I want to make this dependency explicit in our code.
if (properties.FortressGatewayGenerationChance > 0 && properties.WorldRiftGenerationEnabled && this.worldProperties = worldProperties;
event.type == InitMapGenEvent.EventType.NETHER_BRIDGE) this.regenerator = regenerator;
{
event.newGen = new DDNetherFortressGenerator();
} }
@ForgeSubscribe(priority = EventPriority.LOW)
public void onInitMapGen(InitMapGenEvent event)
{
// Replace the Nether fortress generator with our own only if any
// gateways would ever generate. This allows admins to disable our
// fortress overriding without disabling all gateways.
/*
* if (properties.FortressGatewayGenerationChance > 0 &&
* properties.WorldRiftGenerationEnabled && event.type ==
* InitMapGenEvent.EventType.NETHER_BRIDGE) { event.newGen = new
* DDNetherFortressGenerator(); }
*/ */
} }
@@ -56,6 +77,10 @@ public class EventHookContainer
@ForgeSubscribe @ForgeSubscribe
public void onSoundLoad(SoundLoadEvent event) public void onSoundLoad(SoundLoadEvent event)
{ {
event.manager.addSound(mod_pocketDim.modid + ":doorLockRemoved.ogg");
event.manager.addSound(mod_pocketDim.modid + ":doorLocked.ogg");
event.manager.addSound(mod_pocketDim.modid + ":keyLock.ogg");
event.manager.addSound(mod_pocketDim.modid + ":keyUnlock.ogg");
event.manager.addSound(mod_pocketDim.modid + ":monk.ogg"); event.manager.addSound(mod_pocketDim.modid + ":monk.ogg");
event.manager.addSound(mod_pocketDim.modid + ":crack.ogg"); event.manager.addSound(mod_pocketDim.modid + ":crack.ogg");
event.manager.addSound(mod_pocketDim.modid + ":tearing.ogg"); event.manager.addSound(mod_pocketDim.modid + ":tearing.ogg");
@@ -71,7 +96,7 @@ public class EventHookContainer
@ForgeSubscribe @ForgeSubscribe
public void onSoundEffectResult(PlayBackgroundMusicEvent event) public void onSoundEffectResult(PlayBackgroundMusicEvent event)
{ {
if (FMLClientHandler.instance().getClient().thePlayer.worldObj.provider.dimensionId==mod_pocketDim.properties.LimboDimensionID); if (FMLClientHandler.instance().getClient().thePlayer.worldObj.provider.dimensionId == mod_pocketDim.properties.LimboDimensionID)
{ {
this.playMusicForDim(FMLClientHandler.instance().getClient().thePlayer.worldObj); this.playMusicForDim(FMLClientHandler.instance().getClient().thePlayer.worldObj);
} }
@@ -80,54 +105,43 @@ public class EventHookContainer
@ForgeSubscribe @ForgeSubscribe
public void onPlayerEvent(PlayerInteractEvent event) public void onPlayerEvent(PlayerInteractEvent event)
{ {
//Handle placement of vanilla doors on rifts // Handle all door placement here
if(!event.entity.worldObj.isRemote) if (event.action == Action.LEFT_CLICK_BLOCK)
{ {
return;
}
World world = event.entity.worldObj; World world = event.entity.worldObj;
ItemStack item = event.entityPlayer.inventory.getCurrentItem(); ItemStack stack = event.entityPlayer.inventory.getCurrentItem();
if(item!=null) if (stack != null)
{ {
if(item.getItem() instanceof ItemDoor&&!(item.getItem() instanceof BaseItemDoor)) if(stack.getItem() instanceof ItemWarpDoor)
{ {
Block doorToPlace = null; NewDimData data = PocketManager.getDimensionData(world);
if(item.itemID == Item.doorIron.itemID)
if(data.type() == DimensionType.PERSONAL)
{ {
doorToPlace =mod_pocketDim.dimensionalDoor; mod_pocketDim.sendChat(event.entityPlayer,("Something prevents the Warp Door from tunneling out here"));
event.setCanceled(true);
return;
} }
else if(item.itemID == Item.doorWood.itemID)
{
doorToPlace =mod_pocketDim.warpDoor;
} }
else if(item.itemID == mod_pocketDim.itemGoldenDoor.itemID) if (BaseItemDoor.tryToPlaceDoor(stack, event.entityPlayer, world,
{ event.x, event.y, event.z, event.face))
doorToPlace =mod_pocketDim.goldenDimensionalDoor;
}
if(((BaseItemDoor) mod_pocketDim.itemDimensionalDoor).tryPlacingDoor(doorToPlace, world, event.entityPlayer,item))
{
if(!event.entityPlayer.capabilities.isCreativeMode)
{
item.stackSize--;
}
if(!event.entity.worldObj.isRemote)
{ {
// Cancel the event so that we don't get two doors from vanilla doors
event.setCanceled(true); event.setCanceled(true);
} }
} }
else
{
BaseItemDoor.tryItemUse(doorToPlace, item, event.entityPlayer, world, event.x, event.y, event.z, event.face, true, true);
}
}
}
}
} }
@ForgeSubscribe @ForgeSubscribe
public void onWorldLoad(WorldEvent.Load event) public void onWorldLoad(WorldEvent.Load event)
{ {
// We need to initialize PocketManager here because onServerAboutToStart fires before we can // We need to initialize PocketManager here because onServerAboutToStart
// use DimensionManager and onServerStarting fires after the game tries to generate terrain. // fires before we can use DimensionManager and onServerStarting fires
// If a gateway tries to generate before PocketManager has initialized, we get a crash. // after the game tries to generate terrain. If a gateway tries to
// generate before PocketManager has initialized, we get a crash.
if (!PocketManager.isLoaded()) if (!PocketManager.isLoaded())
{ {
PocketManager.load(); PocketManager.load();
@@ -148,14 +162,17 @@ public class EventHookContainer
@ForgeSubscribe(priority = EventPriority.HIGHEST) @ForgeSubscribe(priority = EventPriority.HIGHEST)
public boolean onDeathWithHighPriority(LivingDeathEvent event) public boolean onDeathWithHighPriority(LivingDeathEvent event)
{ {
// Teleport the entity to Limbo if it's a player in a pocket dimension and // Teleport the entity to Limbo if it's a player in a pocket dimension
// if Limbo preserves player inventories. We'll check again in a low-priority event handler // and if Limbo preserves player inventories. We'll check again in a
// to give other mods a chance to save the player if Limbo does _not_ preserve inventories. // low-priority event handler to give other mods a chance to save the
// player if Limbo does _not_ preserve inventories.
Entity entity = event.entity; Entity entity = event.entity;
if (entity instanceof EntityPlayer && properties.LimboEnabled && if (properties.LimboEnabled && properties.LimboReturnsInventoryEnabled &&
entity.worldObj.provider instanceof PocketProvider && properties.LimboReturnsInventoryEnabled) entity instanceof EntityPlayer && isValidSourceForLimbo(entity.worldObj.provider))
{
if(entity.worldObj.provider instanceof PocketProvider)
{ {
EntityPlayer player = (EntityPlayer) entity; EntityPlayer player = (EntityPlayer) entity;
mod_pocketDim.deathTracker.addUsername(player.username); mod_pocketDim.deathTracker.addUsername(player.username);
@@ -163,19 +180,30 @@ public class EventHookContainer
event.setCanceled(true); event.setCanceled(true);
return false; return false;
} }
else if(entity.worldObj.provider instanceof LimboProvider && event.source == DamageSource.outOfWorld)
{
EntityPlayer player = (EntityPlayer) entity;
revivePlayerInLimbo(player);
mod_pocketDim.sendChat(player, "Search for the dark red pools which accumulate in the lower reaches of Limbo");
event.setCanceled(true);
return false;
}
}
return true; return true;
} }
@ForgeSubscribe(priority = EventPriority.LOWEST) @ForgeSubscribe(priority = EventPriority.LOWEST)
public boolean onDeathWithLowPriority(LivingDeathEvent event) public boolean onDeathWithLowPriority(LivingDeathEvent event)
{ {
// This low-priority handler gives mods a chance to save a player from death before we apply // This low-priority handler gives mods a chance to save a player from
// teleporting them to Limbo _without_ preserving their inventory. We also check if the player // death before we apply teleporting them to Limbo _without_ preserving
// died in a pocket dimension and record it, regardless of whether the player will be sent to Limbo. // their inventory. We also check if the player died in a pocket
// dimension and record it, regardless of whether the player will be
// sent to Limbo.
Entity entity = event.entity; Entity entity = event.entity;
if (entity instanceof EntityPlayer && entity.worldObj.provider instanceof PocketProvider) if (entity instanceof EntityPlayer && isValidSourceForLimbo(entity.worldObj.provider))
{ {
EntityPlayer player = (EntityPlayer) entity; EntityPlayer player = (EntityPlayer) entity;
mod_pocketDim.deathTracker.addUsername(player.username); mod_pocketDim.deathTracker.addUsername(player.username);
@@ -191,13 +219,24 @@ public class EventHookContainer
return true; return true;
} }
private boolean isValidSourceForLimbo(WorldProvider provider)
{
// Returns whether a given world is a valid place for sending a player
// to Limbo. We can send someone to Limbo from a certain dimension if
// Universal Limbo is enabled and the source dimension is not Limbo, or
// if the source dimension is a pocket dimension.
return (worldProperties.UniversalLimboEnabled && provider.dimensionId != properties.LimboDimensionID) ||
(provider instanceof PocketProvider);
}
private void revivePlayerInLimbo(EntityPlayer player) private void revivePlayerInLimbo(EntityPlayer player)
{ {
player.extinguish(); player.extinguish();
player.clearActivePotions(); player.clearActivePotions();
player.setHealth(player.getMaxHealth()); player.setHealth(player.getMaxHealth());
ChunkCoordinates coords = LimboProvider.getLimboSkySpawn(player.worldObj.rand); player.getFoodStats().addStats(MAX_FOOD_LEVEL, 0);
Point4D destination = new Point4D((int) (coords.posX + player.posX), coords.posY, (int) (coords.posZ + player.posZ ), mod_pocketDim.properties.LimboDimensionID); Point4D destination = LimboProvider.getLimboSkySpawn(player, properties);
DDTeleporter.teleportEntity(player, destination, false); DDTeleporter.teleportEntity(player, destination, false);
} }
@@ -206,7 +245,7 @@ public class EventHookContainer
{ {
if (event.world.provider.dimensionId == 0) if (event.world.provider.dimensionId == 0)
{ {
PocketManager.save(); PocketManager.save(true);
if (mod_pocketDim.deathTracker != null && mod_pocketDim.deathTracker.isModified()) if (mod_pocketDim.deathTracker != null && mod_pocketDim.deathTracker.isModified())
{ {
@@ -215,12 +254,36 @@ public class EventHookContainer
} }
} }
@ForgeSubscribe
public void onChunkLoad(ChunkEvent.Load event)
{
// Schedule rift regeneration for any links located in this chunk.
// This event runs on both the client and server. Allow server only.
// Also, check that PocketManager is loaded, because onChunkLoad() can
// fire while chunks are being initialized in a new world, before
// onWorldLoad() fires.
Chunk chunk = event.getChunk();
if (!chunk.worldObj.isRemote && PocketManager.isLoaded())
{
NewDimData dimension = PocketManager.createDimensionData(chunk.worldObj);
for (DimLink link : dimension.getChunkLinks(chunk.xPosition, chunk.zPosition))
{
regenerator.scheduleSlowRegeneration(link);
}
}
}
public void playMusicForDim(World world) public void playMusicForDim(World world)
{ {
if (world.isRemote) if (world.isRemote)
{ {
SoundManager sndManager = FMLClientHandler.instance().getClient().sndManager; SoundManager sndManager = FMLClientHandler.instance().getClient().sndManager;
// SenseiKiwi: I've added the following check as a quick fix for a
// reported crash. This needs to work without a hitch or we have to
// stop trying to replace the background music...
if (sndManager != null && sndManager.sndSystem != null)
{
if (world.provider instanceof LimboProvider) if (world.provider instanceof LimboProvider)
{ {
sndManager.sndSystem.stop("BgMusic"); sndManager.sndSystem.stop("BgMusic");
@@ -238,3 +301,4 @@ public class EventHookContainer
} }
} }
} }
}

View File

@@ -4,5 +4,6 @@ import net.minecraftforge.common.ForgeChunkManager.Ticket;
public interface IChunkLoader public interface IChunkLoader
{ {
public void forceChunkLoading(Ticket ticket,int x, int z); public boolean isInitialized();
public void initialize(Ticket ticket);
} }

View File

@@ -12,5 +12,6 @@ public class PacketConstants
public static final byte CREATE_LINK_PACKET_ID = 4; public static final byte CREATE_LINK_PACKET_ID = 4;
public static final byte DELETE_LINK_PACKET_ID = 5; public static final byte DELETE_LINK_PACKET_ID = 5;
public static final byte CLIENT_LOGIN_DIM_REGISTER = 6; public static final byte CLIENT_LOGIN_DIM_REGISTER = 6;
public static final byte UPDATE_LINK_PACKET_ID = 7;
} }

View File

@@ -39,6 +39,13 @@ public class ServerPacketHandler implements IPacketHandler
{ {
sendDimPacket(PacketConstants.DELETE_DIM_PACKET_ID, message); sendDimPacket(PacketConstants.DELETE_DIM_PACKET_ID, message);
} }
@Override
public void update(ClientDimData message)
{
// TODO Auto-generated method stub
}
} }
private static class LinkWatcher implements IUpdateWatcher<ClientLinkData> private static class LinkWatcher implements IUpdateWatcher<ClientLinkData>
@@ -54,6 +61,12 @@ public class ServerPacketHandler implements IPacketHandler
{ {
sendLinkPacket(PacketConstants.DELETE_LINK_PACKET_ID, message); sendLinkPacket(PacketConstants.DELETE_LINK_PACKET_ID, message);
} }
@Override
public void update(ClientLinkData message)
{
sendLinkPacket(PacketConstants.UPDATE_LINK_PACKET_ID, message);
}
} }
public static Packet250CustomPayload createLinkPacket(ClientLinkData data) public static Packet250CustomPayload createLinkPacket(ClientLinkData data)

View File

@@ -1,26 +1,28 @@
package StevenDimDoors.mod_pocketDim.blocks; package StevenDimDoors.mod_pocketDim.blocks;
import java.util.Random; import java.util.Random;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockDoor; import net.minecraft.block.BlockDoor;
import net.minecraft.block.ITileEntityProvider; import net.minecraft.block.ITileEntityProvider;
import net.minecraft.block.material.Material; import net.minecraft.block.material.Material;
import net.minecraft.client.renderer.IconFlipped;
import net.minecraft.client.renderer.texture.IconRegister; import net.minecraft.client.renderer.texture.IconRegister;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemDoor;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Icon; import net.minecraft.util.Icon;
import net.minecraft.util.MathHelper; import net.minecraft.util.MathHelper;
import net.minecraft.world.IBlockAccess; import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World; import net.minecraft.world.World;
import StevenDimDoors.mod_pocketDim.DDProperties;
import StevenDimDoors.mod_pocketDim.mod_pocketDim; import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.config.DDProperties;
import StevenDimDoors.mod_pocketDim.core.DDTeleporter; import StevenDimDoors.mod_pocketDim.core.DDTeleporter;
import StevenDimDoors.mod_pocketDim.core.DimLink; import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.PocketManager; import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.schematic.BlockRotator; import StevenDimDoors.mod_pocketDim.items.ItemDDKey;
import StevenDimDoors.mod_pocketDim.tileentities.TileEntityDimDoor; import StevenDimDoors.mod_pocketDim.tileentities.TileEntityDimDoor;
import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly; import cpw.mods.fml.relauncher.SideOnly;
@@ -28,7 +30,11 @@ import cpw.mods.fml.relauncher.SideOnly;
public abstract class BaseDimDoor extends BlockDoor implements IDimDoor, ITileEntityProvider public abstract class BaseDimDoor extends BlockDoor implements IDimDoor, ITileEntityProvider
{ {
protected final DDProperties properties; protected final DDProperties properties;
private Icon blockIconBottom;
@SideOnly(Side.CLIENT)
protected Icon[] upperTextures;
@SideOnly(Side.CLIENT)
protected Icon[] lowerTextures;
public BaseDimDoor(int blockID, Material material, DDProperties properties) public BaseDimDoor(int blockID, Material material, DDProperties properties)
{ {
@@ -38,10 +44,15 @@ public abstract class BaseDimDoor extends BlockDoor implements IDimDoor, ITileEn
} }
@Override @Override
public void registerIcons(IconRegister par1IconRegister) @SideOnly(Side.CLIENT)
public void registerIcons(IconRegister iconRegister)
{ {
this.blockIcon = par1IconRegister.registerIcon(mod_pocketDim.modid + ":" + this.getUnlocalizedName()+"_top"); upperTextures = new Icon[2];
this.blockIconBottom = par1IconRegister.registerIcon(mod_pocketDim.modid + ":" + this.getUnlocalizedName()+"_bottom"); lowerTextures = new Icon[2];
upperTextures[0] = iconRegister.registerIcon(mod_pocketDim.modid + ":" + this.getUnlocalizedName() + "_upper");
lowerTextures[0] = iconRegister.registerIcon(mod_pocketDim.modid + ":" + this.getUnlocalizedName() + "_lower");
upperTextures[1] = new IconFlipped(upperTextures[0], true, false);
lowerTextures[1] = new IconFlipped(lowerTextures[0], true, false);
} }
/** /**
@@ -49,9 +60,9 @@ public abstract class BaseDimDoor extends BlockDoor implements IDimDoor, ITileEn
*/ */
@Override @Override
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public Icon getIcon(int par1, int par2) public Icon getIcon(int side, int metadata)
{ {
return this.blockIcon; return this.upperTextures[0];
} }
@Override @Override
@@ -63,22 +74,37 @@ public abstract class BaseDimDoor extends BlockDoor implements IDimDoor, ITileEn
@Override @Override
public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int side, float hitX, float hitY, float hitZ) public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int side, float hitX, float hitY, float hitZ)
{ {
int var10 = this.getFullMetadata(world, x, y, z);
int var11 = var10 & 7;
var11 ^= 4;
if ((var10 & 8) == 0) ItemStack stack = player.inventory.getCurrentItem();
if (stack != null && stack.getItem() instanceof ItemDDKey)
{ {
world.setBlockMetadataWithNotify(x, y, z, var11,2); return false;
world.markBlockRangeForRenderUpdate(x, y, z, x, y, z); }
if(!checkCanOpen(world, x, y, z, player))
{
return false;
}
final int MAGIC_CONSTANT = 1003;
int metadata = this.getFullMetadata(world, x, y, z);
int lowMeta = metadata & 7;
lowMeta ^= 4;
if (isUpperDoorBlock(metadata))
{
world.setBlockMetadataWithNotify(x, y - 1, z, lowMeta, 2);
world.markBlockRangeForRenderUpdate(x, y - 1, z, x, y, z);
} }
else else
{ {
world.setBlockMetadataWithNotify(x, y - 1, z, var11,2); world.setBlockMetadataWithNotify(x, y, z, lowMeta, 2);
world.markBlockRangeForRenderUpdate(x, y - 1, z, x, y, z); world.markBlockRangeForRenderUpdate(x, y, z, x, y, z);
} }
world.playAuxSFXAtEntity(player, 1003, x, y, z, 0); world.playAuxSFXAtEntity(player, MAGIC_CONSTANT, x, y, z, 0);
return true; return true;
} }
@@ -90,38 +116,119 @@ public abstract class BaseDimDoor extends BlockDoor implements IDimDoor, ITileEn
this.updateAttachedTile(world, x, y, z); this.updateAttachedTile(world, x, y, z);
} }
/** /**
* Retrieves the block texture to use based on the display side. Args: iBlockAccess, x, y, z, side * Retrieves the block texture to use based on the display side. Args: iBlockAccess, x, y, z, side
*/ */
@Override @Override
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public Icon getBlockTexture(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) public Icon getBlockTexture(IBlockAccess blockAccess, int x, int y, int z, int side)
{ {
if(par1IBlockAccess.getBlockId(par2, par3-1, par4) == this.blockID) if (side != 1 && side != 0)
{ {
return this.blockIcon; int fullMetadata = this.getFullMetadata(blockAccess, x, y, z);
int orientation = fullMetadata & 3;
boolean reversed = false;
if (isDoorOpen(fullMetadata))
{
if (orientation == 0 && side == 2)
{
reversed = !reversed;
}
else if (orientation == 1 && side == 5)
{
reversed = !reversed;
}
else if (orientation == 2 && side == 3)
{
reversed = !reversed;
}
else if (orientation == 3 && side == 4)
{
reversed = !reversed;
}
} }
else else
{ {
return blockIconBottom; if (orientation == 0 && side == 5)
{
reversed = !reversed;
} }
else if (orientation == 1 && side == 3)
{
reversed = !reversed;
}
else if (orientation == 2 && side == 4)
{
reversed = !reversed;
}
else if (orientation == 3 && side == 2)
{
reversed = !reversed;
}
if ((fullMetadata & 16) != 0)
{
reversed = !reversed;
}
}
if (isUpperDoorBlock(fullMetadata))
{
return this.upperTextures[reversed ? 1 : 0];
}
return this.lowerTextures[reversed ? 1 : 0];
}
return this.lowerTextures[0];
} }
//Called to update the render information on the tile entity. Could probably implement a data watcher, //Called to update the render information on the tile entity. Could probably implement a data watcher,
//but this works fine and is more versatile I think. //but this works fine and is more versatile I think.
public BaseDimDoor updateAttachedTile(World world, int x, int y, int z) public BaseDimDoor updateAttachedTile(World world, int x, int y, int z)
{ {
mod_pocketDim.proxy.updateDoorTE(this, world, x, y, z);
TileEntity tile = world.getBlockTileEntity(x, y, z); TileEntity tile = world.getBlockTileEntity(x, y, z);
if (tile instanceof TileEntityDimDoor) if (tile instanceof TileEntityDimDoor)
{ {
int metadata = world.getBlockMetadata(x, y, z);
TileEntityDimDoor dimTile = (TileEntityDimDoor) tile; TileEntityDimDoor dimTile = (TileEntityDimDoor) tile;
dimTile.openOrClosed = PocketManager.getLink(x, y, z, world.provider.dimensionId) != null; dimTile.openOrClosed = isDoorOnRift(world, x, y, z) && isUpperDoorBlock(metadata);
dimTile.orientation = this.getFullMetadata(world, x, y, z) & 7; dimTile.orientation = this.getFullMetadata(world, x, y, z) & 7;
} }
return this; return this;
} }
public boolean isDoorOnRift(World world, int x, int y, int z)
{
return this.getLink(world, x, y, z) != null;
}
public DimLink getLink(World world, int x, int y, int z)
{
DimLink link= PocketManager.getLink(x, y, z, world.provider.dimensionId);
if(link!=null)
{
return link;
}
if(isUpperDoorBlock( world.getBlockMetadata(x, y, z)))
{
link = PocketManager.getLink(x, y-1, z, world.provider.dimensionId);
if(link!=null)
{
return link;
}
}
else
{
link = PocketManager.getLink(x, y+1, z, world.provider.dimensionId);
if(link != null)
{
return link;
}
}
return null;
}
/** /**
* Is this block (a) opaque and (b) a full 1m cube? This determines whether or not to render the shared face of two * Is this block (a) opaque and (b) a full 1m cube? This determines whether or not to render the shared face of two
* adjacent blocks and also whether the player can attach torches, redstone wire, etc to this block. * adjacent blocks and also whether the player can attach torches, redstone wire, etc to this block.
@@ -129,9 +236,7 @@ public abstract class BaseDimDoor extends BlockDoor implements IDimDoor, ITileEn
@Override @Override
public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random)
{ {
TileEntityDimDoor tile = (TileEntityDimDoor) par1World.getBlockTileEntity(par2, par3, par4); this.updateAttachedTile(par1World, par2, par3, par4);
tile.openOrClosed = this.isDoorOpen( par1World, par2, par3, par4);
tile.orientation = this.getFullMetadata(par1World, par2, par3, par4) & 7;
} }
@Override @Override
@@ -229,60 +334,38 @@ public abstract class BaseDimDoor extends BlockDoor implements IDimDoor, ITileEn
* their own) Args: x, y, z, neighbor blockID * their own) Args: x, y, z, neighbor blockID
*/ */
@Override @Override
public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) public void onNeighborBlockChange(World world, int x, int y, int z, int neighborID)
{ {
int var6 = par1World.getBlockMetadata(par2, par3, par4);
if ((var6 & 8) == 0) int metadata = world.getBlockMetadata(x, y, z);
if (isUpperDoorBlock(metadata))
{ {
boolean var7 = false; if (world.getBlockId(x, y - 1, z) != this.blockID)
if (par1World.getBlockId(par2, par3 + 1, par4) != this.blockID)
{ {
par1World.setBlock(par2, par3, par4, 0); world.setBlockToAir(x, y, z);
var7 = true;
} }
if (neighborID > 0 && neighborID != this.blockID)
/**
if (!par1World.doesBlockHaveSolidTopSurface(par2, par3 - 1, par4))
{ {
par1World.setBlockWithNotify(par2, par3, par4, 0); this.onNeighborBlockChange(world, x, y - 1, z, neighborID);
var7 = true;
if (par1World.getBlockId(par2, par3 + 1, par4) == this.blockID)
{
par1World.setBlockWithNotify(par2, par3 + 1, par4, 0);
}
}
**/
if (var7)
{
if (!par1World.isRemote)
{
this.dropBlockAsItem(par1World, par2, par3, par4, properties.DimensionalDoorID, 0);
} }
} }
else else
{ {
boolean var8 = par1World.isBlockIndirectlyGettingPowered(par2, par3, par4) || par1World.isBlockIndirectlyGettingPowered(par2, par3 + 1, par4); if (world.getBlockId(x, y + 1, z) != this.blockID)
if ((var8 || par5 > 0 && Block.blocksList[par5].canProvidePower()) && par5 != this.blockID)
{ {
this.onPoweredBlockChange(par1World, par2, par3, par4, var8); world.setBlockToAir(x, y, z);
if (!world.isRemote)
{
this.dropBlockAsItem(world, x, y, z, metadata, 0);
} }
} }
else if(this.getLockStatus(world, x, y, z)<=1)
{
boolean powered = world.isBlockIndirectlyGettingPowered(x, y, z) || world.isBlockIndirectlyGettingPowered(x, y + 1, z);
if ((powered || neighborID > 0 && Block.blocksList[neighborID].canProvidePower()) && neighborID != this.blockID)
{
this.onPoweredBlockChange(world, x, y, z, powered);
} }
else
{
if (par1World.getBlockId(par2, par3 - 1, par4) != this.blockID)
{
par1World.setBlock(par2, par3, par4, 0);
}
if (par5 > 0 && par5 != this.blockID)
{
this.onNeighborBlockChange(par1World, par2, par3 - 1, par4, par5);
} }
} }
} }
@@ -292,32 +375,18 @@ public abstract class BaseDimDoor extends BlockDoor implements IDimDoor, ITileEn
*/ */
@Override @Override
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public int idPicked(World par1World, int par2, int par3, int par4) public int idPicked(World world, int x, int y, int z)
{ {
return this.getDrops(); return this.getDoorItem();
}
@Override
public int idDropped(int par1, Random par2Random, int par3)
{
//I have no idea, but sometimes this is returned as the blockID instead of metadata.
if(par1>100)
{
return this.getDrops();
}
return (par1 & 8) != 0 ? 0 :getDrops();
} }
/** /**
* Called when the block is attempted to be harvested * Returns the ID of the items to drop on destruction.
*/ */
@Override @Override
public void onBlockHarvested(World par1World, int par2, int par3, int par4, int par5, EntityPlayer par6EntityPlayer) public int idDropped(int metadata, Random random, int fortune)
{ {
if (par6EntityPlayer.capabilities.isCreativeMode && (par5 & 8) != 0 && par1World.getBlockId(par2, par3 - 1, par4) == this.blockID) return isUpperDoorBlock(metadata) ? 0 : this.getDrops();
{
par1World.setBlock(par2, par3 - 1, par4, 0);
}
} }
@Override @Override
@@ -365,7 +434,6 @@ public abstract class BaseDimDoor extends BlockDoor implements IDimDoor, ITileEn
// Close the door only after the entity goes through // Close the door only after the entity goes through
// so players don't have it slam in their faces. // so players don't have it slam in their faces.
this.onPoweredBlockChange(world, x, y, z, false); this.onPoweredBlockChange(world, x, y, z, false);
} }
} }
else if (world.getBlockId(x, y + 1, z) == this.blockID) else if (world.getBlockId(x, y + 1, z) == this.blockID)
@@ -374,17 +442,77 @@ public abstract class BaseDimDoor extends BlockDoor implements IDimDoor, ITileEn
} }
} }
@Override public boolean isUpperDoorBlock(int metadata)
public int getDrops()
{ {
return this.blockID; return (metadata & 8) != 0;
} }
protected static boolean isDoorOpen(int metadata) public boolean isDoorOpen(int metadata)
{ {
return (metadata & 4) != 0; return (metadata & 4) != 0;
} }
/**
* 0 if link is no lock;
* 1 if there is a lock;
* 2 if the lock is locked.
* @param world
* @param x
* @param y
* @param z
* @return
*/
public byte getLockStatus(World world, int x, int y, int z)
{
byte status = 0;
DimLink link = getLink(world, x, y, z);
if(link!=null&&link.hasLock())
{
status++;
if(link.getLockState())
{
status++;
}
}
return status;
}
public boolean checkCanOpen(World world, int x, int y, int z)
{
return this.checkCanOpen(world, x, y, z, null);
}
public boolean checkCanOpen(World world, int x, int y, int z, EntityPlayer player)
{
DimLink link = getLink(world, x, y, z);
if(link==null||player==null)
{
return link==null;
}
if(!link.getLockState())
{
return true;
}
for(ItemStack item : player.inventory.mainInventory)
{
if(item != null)
{
if(item.getItem() instanceof ItemDDKey)
{
if(link.tryToOpen(item))
{
return true;
}
}
}
}
player.playSound(mod_pocketDim.modid + ":doorLocked", 1F, 1F);
return false;
}
protected static boolean isEntityFacingDoor(int metadata, EntityLivingBase entity) protected static boolean isEntityFacingDoor(int metadata, EntityLivingBase entity)
{ {
// Although any entity has the proper fields for this check, // Although any entity has the proper fields for this check,
@@ -401,4 +529,18 @@ public abstract class BaseDimDoor extends BlockDoor implements IDimDoor, ITileEn
world.setBlockTileEntity(x, y, z, te); world.setBlockTileEntity(x, y, z, te);
return te; return te;
} }
@Override
public void breakBlock(World world, int x, int y, int z, int oldBlockID, int oldMeta)
{
// This function runs on the server side after a block is replaced
// We MUST call super.breakBlock() since it involves removing tile entities
super.breakBlock(world, x, y, z, oldBlockID, oldMeta);
// Schedule rift regeneration for this block if it was replaced
if (world.getBlockId(x, y, z) != oldBlockID)
{
mod_pocketDim.riftRegenerator.scheduleFastRegeneration(x, y, z, world);
}
}
} }

View File

@@ -14,8 +14,10 @@ import net.minecraft.item.Item;
import net.minecraft.item.ItemBlock; import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.Icon; import net.minecraft.util.Icon;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World; import net.minecraft.world.World;
import StevenDimDoors.mod_pocketDim.mod_pocketDim; import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDimClient.PrivatePocketRender;
import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly; import cpw.mods.fml.relauncher.SideOnly;
@@ -23,18 +25,18 @@ public class BlockDimWall extends Block
{ {
private static final float SUPER_HIGH_HARDNESS = 10000000000000F; private static final float SUPER_HIGH_HARDNESS = 10000000000000F;
private static final float SUPER_EXPLOSION_RESISTANCE = 18000000F; private static final float SUPER_EXPLOSION_RESISTANCE = 18000000F;
private Icon[] blockIcon = new Icon[2]; private Icon[] blockIcon = new Icon[3];
public BlockDimWall(int blockID, int j, Material par2Material) public BlockDimWall(int blockID, int j, Material par2Material)
{ {
super(blockID, Material.ground); super(blockID, par2Material);
this.setCreativeTab(mod_pocketDim.dimDoorsCreativeTab); this.setCreativeTab(mod_pocketDim.dimDoorsCreativeTab);
} }
@Override @Override
public float getBlockHardness(World world, int x, int y, int z) public float getBlockHardness(World world, int x, int y, int z)
{ {
if (world.getBlockMetadata(x, y, z) == 0) if (world.getBlockMetadata(x, y, z) != 1)
{ {
return this.blockHardness; return this.blockHardness;
} }
@@ -47,7 +49,7 @@ public class BlockDimWall extends Block
@Override @Override
public float getExplosionResistance(Entity entity, World world, int x, int y, int z, double explosionX, double explosionY, double explosionZ) public float getExplosionResistance(Entity entity, World world, int x, int y, int z, double explosionX, double explosionY, double explosionZ)
{ {
if (world.getBlockMetadata(x, y, z) == 0) if (world.getBlockMetadata(x, y, z) != 1)
{ {
return super.getExplosionResistance(entity, world, x, y, z, explosionX, explosionY, explosionZ); return super.getExplosionResistance(entity, world, x, y, z, explosionX, explosionY, explosionZ);
} }
@@ -57,25 +59,41 @@ public class BlockDimWall extends Block
} }
} }
public int getRenderType()
{
return PrivatePocketRender.renderID;
}
@Override @Override
public void registerIcons(IconRegister par1IconRegister) public void registerIcons(IconRegister par1IconRegister)
{ {
this.blockIcon[0] = par1IconRegister.registerIcon(mod_pocketDim.modid + ":" + this.getUnlocalizedName()); this.blockIcon[0] = par1IconRegister.registerIcon(mod_pocketDim.modid + ":" + this.getUnlocalizedName());
this.blockIcon[1] = par1IconRegister.registerIcon(mod_pocketDim.modid + ":" + this.getUnlocalizedName() + "Perm"); this.blockIcon[1] = par1IconRegister.registerIcon(mod_pocketDim.modid + ":" + this.getUnlocalizedName() + "Perm");
this.blockIcon[2] = par1IconRegister.registerIcon(mod_pocketDim.modid + ":" + this.getUnlocalizedName() + "Personal");
} }
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
@Override @Override
public Icon getIcon(int par1, int par2) public Icon getIcon(int par1, int par2)
{ {
return (par2 != 1) ? blockIcon[0] : blockIcon[1]; switch(par2)
{
case 0:
return blockIcon[0];
case 1:
return blockIcon[1];
case 2:
return blockIcon[2];
default:
return blockIcon[0];
}
} }
@Override @Override
public int damageDropped(int metadata) public int damageDropped(int metadata)
{ {
//Return 0 to avoid dropping Ancient Fabric even if the player somehow manages to break it //Return 0 to avoid dropping Ancient Fabric even if the player somehow manages to break it
return 0; return metadata == 1 ? 0 : metadata;
} }
@Override @Override
@@ -83,11 +101,12 @@ public class BlockDimWall extends Block
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public void getSubBlocks(int unknown, CreativeTabs tab, List subItems) public void getSubBlocks(int unknown, CreativeTabs tab, List subItems)
{ {
for (int ix = 0; ix < 2; ix++) for (int ix = 0; ix < 3; ix++)
{ {
subItems.add(new ItemStack(this, 1, ix)); subItems.add(new ItemStack(this, 1, ix));
} }
} }
@Override @Override
public void onBlockDestroyedByPlayer(World par1World, int par2, int par3, int par4, int par5) {} public void onBlockDestroyedByPlayer(World par1World, int par2, int par3, int par4, int par5) {}
@@ -110,7 +129,7 @@ public class BlockDimWall extends Block
public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer entityPlayer, int par6, float par7, float par8, float par9) public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer entityPlayer, int par6, float par7, float par8, float par9)
{ {
//Check if the metadata value is 0 -- we don't want the user to replace Ancient Fabric //Check if the metadata value is 0 -- we don't want the user to replace Ancient Fabric
if (entityPlayer.getCurrentEquippedItem() != null && world.getBlockMetadata(x, y, z) == 0) if (entityPlayer.getCurrentEquippedItem() != null && world.getBlockMetadata(x, y, z) != 1)
{ {
Item playerEquip = entityPlayer.getCurrentEquippedItem().getItem(); Item playerEquip = entityPlayer.getCurrentEquippedItem().getItem();

View File

@@ -11,8 +11,8 @@ import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.util.MathHelper; import net.minecraft.util.MathHelper;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.common.DimensionManager; import net.minecraftforge.common.DimensionManager;
import StevenDimDoors.mod_pocketDim.DDProperties;
import StevenDimDoors.mod_pocketDim.mod_pocketDim; import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.config.DDProperties;
import StevenDimDoors.mod_pocketDim.core.DDTeleporter; import StevenDimDoors.mod_pocketDim.core.DDTeleporter;
import StevenDimDoors.mod_pocketDim.helpers.yCoordHelper; import StevenDimDoors.mod_pocketDim.helpers.yCoordHelper;
import StevenDimDoors.mod_pocketDim.util.Point4D; import StevenDimDoors.mod_pocketDim.util.Point4D;
@@ -51,7 +51,8 @@ public class BlockDimWallPerm extends Block
@Override @Override
public void onEntityWalking(World world, int x, int y, int z, Entity entity) public void onEntityWalking(World world, int x, int y, int z, Entity entity)
{ {
if (!world.isRemote && world.provider.dimensionId == properties.LimboDimensionID) if (!world.isRemote && world.provider.dimensionId == properties.LimboDimensionID
&& mod_pocketDim.worldProperties.LimboEscapeEnabled)
{ {
World overworld = DimensionManager.getWorld(0); World overworld = DimensionManager.getWorld(0);
if (overworld != null && entity instanceof EntityPlayerMP) if (overworld != null && entity instanceof EntityPlayerMP)

View File

@@ -2,56 +2,34 @@ package StevenDimDoors.mod_pocketDim.blocks;
import java.util.Random; import java.util.Random;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import StevenDimDoors.mod_pocketDim.DDProperties;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import net.minecraft.block.BlockDoor; import net.minecraft.block.BlockDoor;
import net.minecraft.block.material.Material; import net.minecraft.block.material.Material;
import net.minecraft.client.renderer.IconFlipped;
import net.minecraft.client.renderer.texture.IconRegister; import net.minecraft.client.renderer.texture.IconRegister;
import net.minecraft.item.Item;
import net.minecraft.util.Icon; import net.minecraft.util.Icon;
import net.minecraft.world.IBlockAccess; import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
public class BlockDoorGold extends BlockDoor public class BlockDoorGold extends BlockDoor
{ {
private Icon blockIconBottom;
public BlockDoorGold(int par1, Material par2Material) public BlockDoorGold(int par1, Material par2Material)
{ {
super(par1, par2Material); super(par1, par2Material);
} }
@Override @SideOnly(Side.CLIENT)
public void registerIcons(IconRegister par1IconRegister) protected String getTextureName()
{ {
this.blockIcon = par1IconRegister.registerIcon(mod_pocketDim.modid + ":" + this.getUnlocalizedName()+"_top"); return mod_pocketDim.modid + ":" + this.getUnlocalizedName();
this.blockIconBottom = par1IconRegister.registerIcon(mod_pocketDim.modid + ":" + this.getUnlocalizedName()+"_bottom");
} }
@Override @Override
public int idDropped(int par1, Random par2Random, int par3) public int idDropped(int par1, Random par2Random, int par3)
{ {
return (par1 & 8) != 0 ? 0 : mod_pocketDim.itemGoldenDoor.itemID; return (par1 & 8) != 0 ? 0 : mod_pocketDim.itemGoldenDoor.itemID;
} }
@Override
public Icon getIcon(int par1, int par2)
{
return this.blockIcon;
}
@Override
@SideOnly(Side.CLIENT)
public Icon getBlockTexture(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5)
{
if (par1IBlockAccess.getBlockId(par2, par3-1, par4) == this.blockID)
{
return this.blockIcon;
}
else
{
return blockIconBottom;
}
}
} }

View File

@@ -0,0 +1,28 @@
package StevenDimDoors.mod_pocketDim.blocks;
import java.util.Random;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.block.BlockDoor;
import net.minecraft.block.material.Material;
public class BlockDoorQuartz extends BlockDoor
{
public BlockDoorQuartz(int par1, Material par2Material)
{
super(par1, par2Material);
}
@SideOnly(Side.CLIENT)
protected String getTextureName()
{
return mod_pocketDim.modid + ":" + this.getUnlocalizedName();
}
@Override
public int idDropped(int par1, Random par2Random, int par3)
{
return (par1 & 8) != 0 ? 0 : mod_pocketDim.itemGoldenDoor.itemID;
}
}

View File

@@ -1,9 +1,9 @@
package StevenDimDoors.mod_pocketDim.blocks; package StevenDimDoors.mod_pocketDim.blocks;
import StevenDimDoors.mod_pocketDim.DDProperties;
import StevenDimDoors.mod_pocketDim.mod_pocketDim; import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.config.DDProperties;
import StevenDimDoors.mod_pocketDim.core.DimLink; import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.LinkTypes; import StevenDimDoors.mod_pocketDim.core.LinkType;
import StevenDimDoors.mod_pocketDim.core.NewDimData; import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager; import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.tileentities.TileEntityDimDoorGold; import StevenDimDoors.mod_pocketDim.tileentities.TileEntityDimDoorGold;
@@ -25,15 +25,21 @@ public class BlockGoldDimDoor extends BaseDimDoor
{ {
if (!world.isRemote && world.getBlockId(x, y - 1, z) == this.blockID) if (!world.isRemote && world.getBlockId(x, y - 1, z) == this.blockID)
{ {
NewDimData dimension = PocketManager.getDimensionData(world); NewDimData dimension = PocketManager.createDimensionData(world);
DimLink link = dimension.getLink(x, y, z); DimLink link = dimension.getLink(x, y, z);
if (link == null) if (link == null)
{ {
dimension.createLink(x, y, z, LinkTypes.POCKET,world.getBlockMetadata(x, y - 1, z)); dimension.createLink(x, y, z, LinkType.POCKET,world.getBlockMetadata(x, y - 1, z));
}
} }
} }
@Override
public int getDoorItem()
{
return mod_pocketDim.itemGoldenDimensionalDoor.itemID;
} }
@Override @Override
public int getDrops() public int getDrops()
{ {

View File

@@ -9,7 +9,7 @@ import net.minecraft.util.Icon;
import net.minecraft.world.IBlockAccess; import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World; import net.minecraft.world.World;
import StevenDimDoors.mod_pocketDim.mod_pocketDim; import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.ticking.LimboDecay; import StevenDimDoors.mod_pocketDim.world.LimboDecay;
import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly; import cpw.mods.fml.relauncher.SideOnly;

View File

@@ -7,7 +7,6 @@ import java.util.Queue;
import java.util.Random; import java.util.Random;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockContainer;
import net.minecraft.block.BlockFlowing; import net.minecraft.block.BlockFlowing;
import net.minecraft.block.BlockFluid; import net.minecraft.block.BlockFluid;
import net.minecraft.block.ITileEntityProvider; import net.minecraft.block.ITileEntityProvider;
@@ -20,13 +19,14 @@ import net.minecraft.util.AxisAlignedBB;
import net.minecraft.world.IBlockAccess; import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.fluids.IFluidBlock; import net.minecraftforge.fluids.IFluidBlock;
import StevenDimDoors.mod_pocketDim.DDProperties;
import StevenDimDoors.mod_pocketDim.Point3D; import StevenDimDoors.mod_pocketDim.Point3D;
import StevenDimDoors.mod_pocketDim.mod_pocketDim; import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.config.DDProperties;
import StevenDimDoors.mod_pocketDim.core.DimLink; import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.NewDimData; import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager; import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.tileentities.TileEntityRift; import StevenDimDoors.mod_pocketDim.tileentities.TileEntityRift;
import StevenDimDoors.mod_pocketDim.util.Point4D;
import StevenDimDoors.mod_pocketDimClient.ClosingRiftFX; import StevenDimDoors.mod_pocketDimClient.ClosingRiftFX;
import StevenDimDoors.mod_pocketDimClient.GoggleRiftFX; import StevenDimDoors.mod_pocketDimClient.GoggleRiftFX;
import StevenDimDoors.mod_pocketDimClient.RiftFX; import StevenDimDoors.mod_pocketDimClient.RiftFX;
@@ -38,23 +38,37 @@ public class BlockRift extends Block implements ITileEntityProvider
{ {
private static final float MIN_IMMUNE_RESISTANCE = 5000.0F; private static final float MIN_IMMUNE_RESISTANCE = 5000.0F;
private static final int BLOCK_DESTRUCTION_RANGE = 4; private static final int BLOCK_DESTRUCTION_RANGE = 4;
private static final int BLOCK_DESTRUCTION_VOLUME = (int) Math.pow(2 * BLOCK_DESTRUCTION_RANGE + 1, 3); private static final int RIFT_SPREAD_RANGE = 5;
private static final int MAX_BLOCK_SEARCH_CHANCE = 100; private static final int MAX_BLOCK_SEARCH_CHANCE = 100;
private static final int BLOCK_SEARCH_CHANCE = 50; private static final int BLOCK_SEARCH_CHANCE = 50;
private static final int MAX_BLOCK_DESTRUCTION_CHANCE = 100; private static final int MAX_BLOCK_DESTRUCTION_CHANCE = 100;
private static final int BLOCK_DESTRUCTION_CHANCE = 50; private static final int BLOCK_DESTRUCTION_CHANCE = 50;
private static final int WORLD_THREAD_CHANCE = 5;
private static final int MAX_WORLD_THREAD_CHANCE = 100; public static final int MAX_WORLD_THREAD_DROP_CHANCE = 1000;
private final DDProperties properties; private final DDProperties properties;
private final ArrayList<Integer> blocksImmuneToRift; private final ArrayList<Integer> blocksImmuneToRift; // List of Vanilla blocks immune to rifts
private final ArrayList<Integer> modBlocksImmuneToRift; // List of DD blocks immune to rifts
public BlockRift(int i, int j, Material par2Material, DDProperties properties) public BlockRift(int i, int j, Material par2Material, DDProperties properties)
{ {
super(i, par2Material); super(i, par2Material);
this.setTickRandomly(true); this.setTickRandomly(true);
this.properties = properties; this.properties = properties;
this.modBlocksImmuneToRift = new ArrayList<Integer>();
this.modBlocksImmuneToRift.add(properties.FabricBlockID);
this.modBlocksImmuneToRift.add(properties.PermaFabricBlockID);
this.modBlocksImmuneToRift.add(properties.DimensionalDoorID);
this.modBlocksImmuneToRift.add(properties.WarpDoorID);
this.modBlocksImmuneToRift.add(properties.TransTrapdoorID);
this.modBlocksImmuneToRift.add(properties.UnstableDoorID);
this.modBlocksImmuneToRift.add(properties.RiftBlockID);
this.modBlocksImmuneToRift.add(properties.TransientDoorID);
this.modBlocksImmuneToRift.add(properties.GoldenDimensionalDoorID);
this.modBlocksImmuneToRift.add(properties.GoldenDoorID);
this.blocksImmuneToRift = new ArrayList<Integer>(); this.blocksImmuneToRift = new ArrayList<Integer>();
this.blocksImmuneToRift.add(properties.FabricBlockID); this.blocksImmuneToRift.add(properties.FabricBlockID);
this.blocksImmuneToRift.add(properties.PermaFabricBlockID); this.blocksImmuneToRift.add(properties.PermaFabricBlockID);
this.blocksImmuneToRift.add(properties.DimensionalDoorID); this.blocksImmuneToRift.add(properties.DimensionalDoorID);
@@ -65,7 +79,7 @@ public class BlockRift extends Block implements ITileEntityProvider
this.blocksImmuneToRift.add(properties.TransientDoorID); this.blocksImmuneToRift.add(properties.TransientDoorID);
this.blocksImmuneToRift.add(properties.GoldenDimensionalDoorID); this.blocksImmuneToRift.add(properties.GoldenDimensionalDoorID);
this.blocksImmuneToRift.add(properties.GoldenDoorID); this.blocksImmuneToRift.add(properties.GoldenDoorID);
this.blocksImmuneToRift.add(properties.PersonalDimDoorID);
this.blocksImmuneToRift.add(Block.blockLapis.blockID); this.blocksImmuneToRift.add(Block.blockLapis.blockID);
this.blocksImmuneToRift.add(Block.blockIron.blockID); this.blocksImmuneToRift.add(Block.blockIron.blockID);
this.blocksImmuneToRift.add(Block.blockGold.blockID); this.blocksImmuneToRift.add(Block.blockGold.blockID);
@@ -85,9 +99,6 @@ public class BlockRift extends Block implements ITileEntityProvider
return false; return false;
} }
@Override
public void onBlockDestroyedByPlayer(World par1World, int par2, int par3, int par4, int par5) {}
@Override @Override
public boolean isOpaqueCube() public boolean isOpaqueCube()
{ {
@@ -113,10 +124,10 @@ public class BlockRift extends Block implements ITileEntityProvider
return true; return true;
} }
//this doesnt do anything yet.
@Override @Override
public int getRenderType() public int getRenderType()
{ {
// This doesn't do anything yet
if (mod_pocketDim.isPlayerWearingGoogles) if (mod_pocketDim.isPlayerWearingGoogles)
{ {
return 0; return 0;
@@ -164,11 +175,30 @@ public class BlockRift extends Block implements ITileEntityProvider
private void destroyNearbyBlocks(World world, int x, int y, int z, Random random) private void destroyNearbyBlocks(World world, int x, int y, int z, Random random)
{ {
HashMap<Point3D, Integer> pointDistances = new HashMap<Point3D, Integer>(BLOCK_DESTRUCTION_VOLUME); // Find reachable blocks that are vulnerable to rift damage (ignoring air, of course)
Queue<Point3D> points = new LinkedList<Point3D>(); ArrayList<Point3D> targets = findReachableBlocks(world, x, y, z, BLOCK_DESTRUCTION_RANGE, false);
//Perform a breadth-first search outwards from the point at which the rift is located. Record the distances // For each block, randomly decide whether to destroy it.
//of the points we visit to stop the search at its maximum range. // The randomness makes it so the destroyed area appears "noisy" if the rift is exposed to a large surface.
for (Point3D target : targets)
{
if (random.nextInt(MAX_BLOCK_DESTRUCTION_CHANCE) < BLOCK_DESTRUCTION_CHANCE)
{
dropWorldThread(world.getBlockId(target.getX(), target.getY(), target.getZ()), world, x, y, z, random);
world.destroyBlock(target.getX(), target.getY(), target.getZ(), false);
}
}
}
private ArrayList<Point3D> findReachableBlocks(World world, int x, int y, int z, int range, boolean includeAir)
{
int searchVolume = (int) Math.pow(2 * range + 1, 3);
HashMap<Point3D, Integer> pointDistances = new HashMap<Point3D, Integer>(searchVolume);
Queue<Point3D> points = new LinkedList<Point3D>();
ArrayList<Point3D> targets = new ArrayList<Point3D>();
// Perform a breadth-first search outwards from the point at which the rift is located.
// Record the distances of the points we visit to stop the search at its maximum range.
pointDistances.put(new Point3D(x, y, z), 0); pointDistances.put(new Point3D(x, y, z), 0);
addAdjacentBlocks(x, y, z, 0, pointDistances, points); addAdjacentBlocks(x, y, z, 0, pointDistances, points);
while (!points.isEmpty()) while (!points.isEmpty())
@@ -176,9 +206,13 @@ public class BlockRift extends Block implements ITileEntityProvider
Point3D current = points.remove(); Point3D current = points.remove();
int distance = pointDistances.get(current); int distance = pointDistances.get(current);
//If the current block is air, continue searching. Otherwise, try destroying the block. // If the current block is air, continue searching. Otherwise, add the block to our list.
if (world.isAirBlock(current.getX(), current.getY(), current.getZ())) if (world.isAirBlock(current.getX(), current.getY(), current.getZ()))
{ {
if (includeAir)
{
targets.add(current);
}
// Make sure we stay within the search range // Make sure we stay within the search range
if (distance < BLOCK_DESTRUCTION_RANGE) if (distance < BLOCK_DESTRUCTION_RANGE)
{ {
@@ -187,21 +221,19 @@ public class BlockRift extends Block implements ITileEntityProvider
} }
else else
{ {
//Check if the current block is immune to destruction by rifts. If not, randomly decide whether to destroy it. // Check if the current block is immune to destruction by rifts. If not, add it to our list.
//The randomness makes it so the destroyed area appears "noisy" if the rift is exposed to a large surface. if (!isBlockImmune(world, current.getX(), current.getY(), current.getZ()))
if (!isBlockImmune(world, current.getX(), current.getY(), current.getZ()) &&
random.nextInt(MAX_BLOCK_DESTRUCTION_CHANCE) < BLOCK_DESTRUCTION_CHANCE)
{ {
this.spawnWorldThread(world.getBlockId(current.getX(), current.getY(), current.getZ()), world, x, y, z, random); targets.add(current);
world.destroyBlock(current.getX(), current.getY(), current.getZ(), false);
} }
} }
} }
return targets;
} }
private void spawnWorldThread(int blockID, World world, int x, int y, int z, Random random) public void dropWorldThread(int blockID, World world, int x, int y, int z, Random random)
{ {
if (blockID != 0 && (random.nextInt(MAX_WORLD_THREAD_CHANCE) < WORLD_THREAD_CHANCE) if (blockID != 0 && (random.nextInt(MAX_WORLD_THREAD_DROP_CHANCE) < properties.WorldThreadDropChance)
&& !(Block.blocksList[blockID] instanceof BlockFlowing || && !(Block.blocksList[blockID] instanceof BlockFlowing ||
Block.blocksList[blockID] instanceof BlockFluid || Block.blocksList[blockID] instanceof BlockFluid ||
Block.blocksList[blockID] instanceof IFluidBlock)) Block.blocksList[blockID] instanceof IFluidBlock))
@@ -211,7 +243,7 @@ public class BlockRift extends Block implements ITileEntityProvider
} }
} }
private void addAdjacentBlocks(int x, int y, int z, int distance, HashMap<Point3D, Integer> pointDistances, Queue<Point3D> points) private static void addAdjacentBlocks(int x, int y, int z, int distance, HashMap<Point3D, Integer> pointDistances, Queue<Point3D> points)
{ {
Point3D[] neighbors = new Point3D[] { Point3D[] neighbors = new Point3D[] {
new Point3D(x - 1, y, z), new Point3D(x - 1, y, z),
@@ -231,15 +263,34 @@ public class BlockRift extends Block implements ITileEntityProvider
} }
} }
public void regenerateRift(World world, int x, int y, int z, Random random) public boolean spreadRift(NewDimData dimension, DimLink parent, World world, Random random)
{ {
if (!this.isBlockImmune(world, x, y, z) && world.getChunkProvider().chunkExists(x >> 4, z >> 4)) int x, y, z, blockID;
Point4D source = parent.source();
// Find reachable blocks that are vulnerable to rift damage and include air
ArrayList<Point3D> targets = findReachableBlocks(world, source.getX(), source.getY(), source.getZ(),
RIFT_SPREAD_RANGE, true);
if (!targets.isEmpty())
{ {
int blockID = world.getBlockId(x, y, z); // Choose randomly from among the possible locations where we can spawn a new rift
world.setBlock(x, y, z, properties.RiftBlockID); Point3D target = targets.get( random.nextInt(targets.size()) );
this.spawnWorldThread(blockID, world, x, y, z, random); x = target.getX();
y = target.getY();
z = target.getZ();
// Create a child, replace the block with a rift, and consider dropping World Thread
blockID = world.getBlockId(x, y, z);
if (world.setBlock(x, y, z, properties.RiftBlockID))
{
dimension.createChildLink(x, y, z, parent);
dropWorldThread(blockID, world, x, y, z, random);
return true;
} }
} }
return false;
}
/** /**
* Lets pistons push through rifts, destroying them * Lets pistons push through rifts, destroying them
@@ -256,111 +307,37 @@ public class BlockRift extends Block implements ITileEntityProvider
@Override @Override
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public void randomDisplayTick(World par1World, int par2, int par3, int par4, Random rand) public void randomDisplayTick(World world, int x, int y, int z, Random rand)
{ {
int count;
//growth in the direction towards the nearby rift
float xGrowth=0;
float yGrowth=0;
float zGrowth=0;
//growth away from the nearby rift
float xGrowthn=0;
float yGrowthn=0;
float zGrowthn=0;
//how far the particles are away from original rift. Used to decrease noise the farther they are away.
float xChange = 0;
float yChange = 0;
float zChange = 0;
TileEntityRift tile = (TileEntityRift)par1World.getBlockTileEntity(par2, par3, par4); ArrayList<Point3D> targets=findReachableBlocks(world, x, y, z, 2, false);
float Xoffset=0;
float Yoffset=0;
float Zoffset=0;
for (count = 0; count < 12 && tile!=null; ++count)
{
//TODO change to a switch statement for clarity
if(tile.xOffset>0)
{
if(rand.nextInt(tile.xOffset)==0)
{
xGrowth =xGrowth+.15F*tile.xOffset;
}
}
else if(tile.xOffset<0)
{
if(rand.nextInt(-tile.xOffset)==0)
{
xGrowthn =xGrowthn-.15F*-tile.xOffset;
}
}
if(tile.yOffset>0)
{
if(rand.nextInt(tile.yOffset)==0)
{
yGrowth =yGrowth+.15F*tile.yOffset;
}
}
else if(tile.yOffset<0)
{
if(rand.nextInt(-tile.yOffset)==0)
{
yGrowthn =yGrowthn-.15F*-tile.yOffset;
}
}
if(tile.zOffset>0)
{
if(rand.nextInt(tile.zOffset)==0)
{
zGrowth =zGrowth+.15F*tile.zOffset;
}
}
else if(tile.zOffset<0)
{
if(rand.nextInt(-tile.zOffset)==0)
{
zGrowthn =zGrowthn-.15F*-tile.zOffset;
}
}
xChange=(float) ((xGrowth+xGrowthn)+rand.nextGaussian()*.05F); TileEntityRift tile = (TileEntityRift)world.getBlockTileEntity(x, y, z);
yChange=(float) ((yGrowth+yGrowthn)+rand.nextGaussian()*.05F);
zChange=(float) ((zGrowth+zGrowthn)+rand.nextGaussian()*.05F);
Xoffset= ((0.25F/(1+Math.abs(xChange))));
Yoffset= ((0.25F/(1+Math.abs(yChange))));
Zoffset= ((0.25F/(1+Math.abs(zChange))));
FMLClientHandler.instance().getClient().effectRenderer.addEffect(new RiftFX(par1World,par2+.5+xChange+Xoffset*rand.nextGaussian(), par3+.5+yChange+Yoffset*rand.nextGaussian() , par4+.5+zChange+Zoffset*rand.nextGaussian(), rand.nextGaussian() * 0.001D, rand.nextGaussian() * 0.001D, rand.nextGaussian() * 0.001D, FMLClientHandler.instance().getClient().effectRenderer));
FMLClientHandler.instance().getClient().effectRenderer.addEffect(new RiftFX(par1World,par2+.5-xChange-Xoffset*rand.nextGaussian(), par3+.5-yChange-Yoffset*rand.nextGaussian() , par4+.5-zChange-Zoffset*rand.nextGaussian(), rand.nextGaussian() * 0.001D, rand.nextGaussian() * 0.001D, rand.nextGaussian() * 0.001D, FMLClientHandler.instance().getClient().effectRenderer));
if(rand.nextBoolean()) if(rand.nextBoolean())
{ {
//renders an extra little blob on top of the actual rift location so its easier to find. Eventually will only render if the player has the goggles. //renders an extra little blob on top of the actual rift location so its easier to find. Eventually will only render if the player has the goggles.
FMLClientHandler.instance().getClient().effectRenderer.addEffect(new GoggleRiftFX(par1World,par2+.5, par3+.5, par4+.5, rand.nextGaussian() * 0.01D, rand.nextGaussian() * 0.01D, rand.nextGaussian() * 0.01D, FMLClientHandler.instance().getClient().effectRenderer)); FMLClientHandler.instance().getClient().effectRenderer.addEffect(new GoggleRiftFX(world,x+.5, y+.5, z+.5, rand.nextGaussian() * 0.01D, rand.nextGaussian() * 0.01D, rand.nextGaussian() * 0.01D, FMLClientHandler.instance().getClient().effectRenderer));
} }
if(tile.shouldClose) if(tile.shouldClose)
{ {
//renders an opposite color effect if it is being closed by the rift remover //renders an opposite color effect if it is being closed by the rift remover
FMLClientHandler.instance().getClient().effectRenderer.addEffect(new ClosingRiftFX(par1World,par2+.5, par3+.5, par4+.5, rand.nextGaussian() * 0.01D, rand.nextGaussian() * 0.01D, rand.nextGaussian() * 0.01D, FMLClientHandler.instance().getClient().effectRenderer)); FMLClientHandler.instance().getClient().effectRenderer.addEffect(new ClosingRiftFX(world,x+.5, y+.5, z+.5, rand.nextGaussian() * 0.01D, rand.nextGaussian() * 0.01D, rand.nextGaussian() * 0.01D, FMLClientHandler.instance().getClient().effectRenderer));
} }
} }
public boolean tryPlacingRift(World world, int x, int y, int z)
{
if (world != null && !isBlockImmune(world, x, y, z))
{
return world.setBlock(x, y, z, mod_pocketDim.blockRift.blockID);
}
return false;
} }
public boolean isBlockImmune(World world, int x, int y, int z) public boolean isBlockImmune(World world, int x, int y, int z)
@@ -374,7 +351,21 @@ public class BlockRift extends Block implements ITileEntityProvider
// is designed to receive an entity, the source of the blast. We have no entity so // is designed to receive an entity, the source of the blast. We have no entity so
// I've set this to access blockResistance directly. Might need changing later. // I've set this to access blockResistance directly. Might need changing later.
return (block.blockResistance >= MIN_IMMUNE_RESISTANCE || blocksImmuneToRift.contains(block.blockID)); return (block.blockResistance >= MIN_IMMUNE_RESISTANCE ||
modBlocksImmuneToRift.contains(block.blockID) ||
blocksImmuneToRift.contains(block.blockID));
}
return false;
}
public boolean isModBlockImmune(World world, int x, int y, int z)
{
// Check whether the block at the specified location is one of the
// rift-resistant blocks from DD.
Block block = Block.blocksList[world.getBlockId(x, y, z)];
if (block != null)
{
return modBlocksImmuneToRift.contains(block.blockID);
} }
return false; return false;
} }
@@ -396,4 +387,18 @@ public class BlockRift extends Block implements ITileEntityProvider
{ {
return new TileEntityRift(); return new TileEntityRift();
} }
@Override
public void breakBlock(World world, int x, int y, int z, int oldBlockID, int oldMeta)
{
// This function runs on the server side after a block is replaced
// We MUST call super.breakBlock() since it involves removing tile entities
super.breakBlock(world, x, y, z, oldBlockID, oldMeta);
// Schedule rift regeneration for this block if it was changed
if (world.getBlockId(x, y, z) != oldBlockID)
{
mod_pocketDim.riftRegenerator.scheduleSlowRegeneration(x, y, z, world);
}
}
} }

View File

@@ -3,16 +3,15 @@ package StevenDimDoors.mod_pocketDim.blocks;
import net.minecraft.block.material.Material; import net.minecraft.block.material.Material;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.world.World; import net.minecraft.world.World;
import StevenDimDoors.mod_pocketDim.DDProperties; import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.config.DDProperties;
import StevenDimDoors.mod_pocketDim.core.DimLink; import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.LinkTypes; import StevenDimDoors.mod_pocketDim.core.LinkType;
import StevenDimDoors.mod_pocketDim.core.NewDimData; import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager; import StevenDimDoors.mod_pocketDim.core.PocketManager;
@SuppressWarnings("deprecation")
public class DimensionalDoor extends BaseDimDoor public class DimensionalDoor extends BaseDimDoor
{ {
public DimensionalDoor(int blockID, Material material, DDProperties properties) public DimensionalDoor(int blockID, Material material, DDProperties properties)
{ {
super(blockID, material, properties); super(blockID, material, properties);
@@ -23,14 +22,21 @@ public class DimensionalDoor extends BaseDimDoor
{ {
if (!world.isRemote && world.getBlockId(x, y - 1, z) == this.blockID) if (!world.isRemote && world.getBlockId(x, y - 1, z) == this.blockID)
{ {
NewDimData dimension = PocketManager.getDimensionData(world); NewDimData dimension = PocketManager.createDimensionData(world);
DimLink link = dimension.getLink(x, y, z); DimLink link = dimension.getLink(x, y, z);
if (link == null) if (link == null)
{ {
dimension.createLink(x, y, z, LinkTypes.POCKET,world.getBlockMetadata(x, y - 1, z)); dimension.createLink(x, y, z, LinkType.POCKET,world.getBlockMetadata(x, y - 1, z));
} }
} }
} }
@Override
public int getDoorItem()
{
return mod_pocketDim.itemDimensionalDoor.itemID;
}
@Override @Override
public int getDrops() public int getDrops()
{ {

View File

@@ -6,11 +6,39 @@ import net.minecraft.world.World;
public interface IDimDoor public interface IDimDoor
{ {
/**
* A function to enter a dim door and traverse its link, called when a player collides with an open door
* @param world
* @param x
* @param y
* @param z
* @param entity
*/
public void enterDimDoor(World world, int x, int y, int z, Entity entity); public void enterDimDoor(World world, int x, int y, int z, Entity entity);
/**
* called when a door is placed to determine how it will place a link
* @param world
* @param x
* @param y
* @param z
*/
public void placeLink(World world, int x, int y, int z); public void placeLink(World world, int x, int y, int z);
public int getDrops(); public int getDrops();
public int getDoorItem();
public TileEntity initDoorTE(World world, int x, int y, int z); public TileEntity initDoorTE(World world, int x, int y, int z);
/**
* checks if any of this doors blocks are overlapping with a rift
* @param world
* @param x
* @param y
* @param z
* @return
*/
public boolean isDoorOnRift(World world, int x, int y, int z);
} }

View File

@@ -0,0 +1,47 @@
package StevenDimDoors.mod_pocketDim.blocks;
import net.minecraft.block.material.Material;
import net.minecraft.world.World;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.config.DDProperties;
import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.LinkType;
import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
public class PersonalDimDoor extends BaseDimDoor
{
public PersonalDimDoor(int blockID, Material material, DDProperties properties)
{
super(blockID, material, properties);
// TODO Auto-generated constructor stub
}
@Override
public void placeLink(World world, int x, int y, int z)
{
if (!world.isRemote && world.getBlockId(x, y - 1, z) == this.blockID)
{
NewDimData dimension = PocketManager.getDimensionData(world);
DimLink link = dimension.getLink(x, y, z);
if (link == null)
{
dimension.createLink(x, y, z, LinkType.PERSONAL, world.getBlockMetadata(x, y - 1, z));
}
}
}
@Override
public int getDrops()
{
return mod_pocketDim.itemQuartzDoor.itemID;
}
@Override
public int getDoorItem()
{
return mod_pocketDim.itemPersonalDoor.itemID;
}
}

View File

@@ -2,23 +2,28 @@ package StevenDimDoors.mod_pocketDim.blocks;
import java.util.Random; import java.util.Random;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockTrapDoor; import net.minecraft.block.BlockTrapDoor;
import net.minecraft.block.ITileEntityProvider; import net.minecraft.block.ITileEntityProvider;
import net.minecraft.block.material.Material; import net.minecraft.block.material.Material;
import net.minecraft.client.renderer.texture.IconRegister; import net.minecraft.client.renderer.texture.IconRegister;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World; import net.minecraft.world.World;
import StevenDimDoors.mod_pocketDim.mod_pocketDim; import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.core.DDTeleporter; import StevenDimDoors.mod_pocketDim.core.DDTeleporter;
import StevenDimDoors.mod_pocketDim.core.DimLink; import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.LinkTypes; import StevenDimDoors.mod_pocketDim.core.LinkType;
import StevenDimDoors.mod_pocketDim.core.NewDimData; import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager; import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.items.ItemDDKey;
import StevenDimDoors.mod_pocketDim.tileentities.TileEntityTransTrapdoor; import StevenDimDoors.mod_pocketDim.tileentities.TileEntityTransTrapdoor;
@SuppressWarnings("deprecation")
public class TransTrapdoor extends BlockTrapDoor implements IDimDoor, ITileEntityProvider public class TransTrapdoor extends BlockTrapDoor implements IDimDoor, ITileEntityProvider
{ {
@@ -41,18 +46,66 @@ public class TransTrapdoor extends BlockTrapDoor implements IDimDoor, ITileEntit
enterDimDoor(world, x, y, z, entity); enterDimDoor(world, x, y, z, entity);
} }
public boolean checkCanOpen(World world, int x, int y, int z)
{
return this.checkCanOpen(world, x, y, z, null);
}
public boolean checkCanOpen(World world, int x, int y, int z, EntityPlayer player)
{
DimLink link = PocketManager.getLink( x, y, z, world);
if(link==null||player==null)
{
return link==null;
}
if(!link.getLockState())
{
return true;
}
for(ItemStack item : player.inventory.mainInventory)
{
if(item != null)
{
if(item.getItem() instanceof ItemDDKey)
{
if(link.tryToOpen(item))
{
return true;
}
}
}
}
return false;
}
public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9)
{
if(this.checkCanOpen(par1World, par2, par3, par4, par5EntityPlayer))
{
return super.onBlockActivated(par1World, par2, par3, par4, par5EntityPlayer, par6, par7, par8, par9);
}
return false;
}
public void onPoweredBlockChange(World par1World, int par2, int par3, int par4, boolean par5)
{
if(this.checkCanOpen(par1World, par2, par3, par4))
{
super.onPoweredBlockChange(par1World, par2, par3, par4, par5);
}
}
@Override @Override
public void enterDimDoor(World world, int x, int y, int z, Entity entity) public void enterDimDoor(World world, int x, int y, int z, Entity entity)
{ {
if (!world.isRemote && isTrapdoorOpen(world.getBlockMetadata(x, y, z))) if (!world.isRemote && isTrapdoorOpen(world.getBlockMetadata(x, y, z)))
{ {
this.onPoweredBlockChange(world, x, y, z, false);
DimLink link = PocketManager.getLink(x, y, z, world); DimLink link = PocketManager.getLink(x, y, z, world);
if (link != null) if (link != null)
{ {
DDTeleporter.traverseDimDoor(world, link, entity,this); DDTeleporter.traverseDimDoor(world, link, entity,this);
} }
super.onPoweredBlockChange(world, x, y, z, false);
} }
} }
@@ -61,14 +114,6 @@ public class TransTrapdoor extends BlockTrapDoor implements IDimDoor, ITileEntit
{ {
this.placeLink(world, x, y, z); this.placeLink(world, x, y, z);
world.setBlockTileEntity(x, y, z, this.createNewTileEntity(world)); world.setBlockTileEntity(x, y, z, this.createNewTileEntity(world));
this.updateAttachedTile(world, x, y, z);
}
@Override
public void updateTick(World world, int x, int y, int z, Random random)
{
TileEntityTransTrapdoor tile = (TileEntityTransTrapdoor) world.getBlockTileEntity(x, y, z);
tile.hasRift = PocketManager.getLink(x, y, z, world) != null;
} }
@Override @Override
@@ -77,35 +122,37 @@ public class TransTrapdoor extends BlockTrapDoor implements IDimDoor, ITileEntit
return new TileEntityTransTrapdoor(); return new TileEntityTransTrapdoor();
} }
public void updateAttachedTile(World world, int x, int y, int z)
{
TileEntity tile = world.getBlockTileEntity(x, y, z);
if (tile instanceof TileEntityTransTrapdoor)
{
TileEntityTransTrapdoor trapdoorTile = (TileEntityTransTrapdoor) tile;
trapdoorTile.hasRift = (PocketManager.getLink(x, y, z, world) != null);
}
}
@Override @Override
public void placeLink(World world, int x, int y, int z) public void placeLink(World world, int x, int y, int z)
{ {
if (!world.isRemote) if (!world.isRemote)
{ {
NewDimData dimension = PocketManager.getDimensionData(world); NewDimData dimension = PocketManager.createDimensionData(world);
DimLink link = dimension.getLink(x, y, z); DimLink link = dimension.getLink(x, y, z);
if (link == null && dimension.isPocketDimension()) if (link == null && dimension.isPocketDimension())
{ {
dimension.createLink(x, y, z, LinkTypes.UNSAFE_EXIT,0); dimension.createLink(x, y, z, LinkType.UNSAFE_EXIT,0);
} }
} }
} }
@Override
@SideOnly(Side.CLIENT)
public int idPicked(World world, int x, int y, int z)
{
return this.getDoorItem();
}
@Override @Override
public int idDropped(int metadata, Random random, int fortuneLevel) public int idDropped(int metadata, Random random, int fortuneLevel)
{ {
return getDrops(); return this.getDrops();
}
@Override
public int getDoorItem()
{
return mod_pocketDim.transTrapdoor.blockID;
} }
@Override @Override
@@ -126,4 +173,24 @@ public class TransTrapdoor extends BlockTrapDoor implements IDimDoor, ITileEntit
world.setBlockTileEntity(x, y, z, te); world.setBlockTileEntity(x, y, z, te);
return te; return te;
} }
@Override
public boolean isDoorOnRift(World world, int x, int y, int z)
{
return PocketManager.getLink(x, y, z, world)!=null;
}
@Override
public void breakBlock(World world, int x, int y, int z, int oldBlockID, int oldMeta)
{
// This function runs on the server side after a block is replaced
// We MUST call super.breakBlock() since it involves removing tile entities
super.breakBlock(world, x, y, z, oldBlockID, oldMeta);
// Schedule rift regeneration for this block if it was replaced
if (world.getBlockId(x, y, z) != oldBlockID)
{
mod_pocketDim.riftRegenerator.scheduleFastRegeneration(x, y, z, world);
}
}
} }

View File

@@ -1,19 +1,17 @@
package StevenDimDoors.mod_pocketDim.blocks; package StevenDimDoors.mod_pocketDim.blocks;
import StevenDimDoors.mod_pocketDim.DDProperties;
import StevenDimDoors.mod_pocketDim.core.DDTeleporter;
import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.LinkTypes;
import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
import net.minecraft.block.material.Material; import net.minecraft.block.material.Material;
import net.minecraft.client.particle.EntityFX;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.AxisAlignedBB;
import net.minecraft.world.World; import net.minecraft.world.World;
import StevenDimDoors.mod_pocketDim.config.DDProperties;
import StevenDimDoors.mod_pocketDim.core.DDTeleporter;
import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.LinkType;
import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
public class TransientDoor extends BaseDimDoor public class TransientDoor extends BaseDimDoor
{ {
@@ -66,15 +64,21 @@ public class TransientDoor extends BaseDimDoor
{ {
if (!world.isRemote && world.getBlockId(x, y - 1, z) == this.blockID) if (!world.isRemote && world.getBlockId(x, y - 1, z) == this.blockID)
{ {
NewDimData dimension = PocketManager.getDimensionData(world); NewDimData dimension = PocketManager.createDimensionData(world);
DimLink link = dimension.getLink(x, y, z); DimLink link = dimension.getLink(x, y, z);
if (link == null && dimension.isPocketDimension()) if (link == null && dimension.isPocketDimension())
{ {
dimension.createLink(x, y, z, LinkTypes.SAFE_EXIT,world.getBlockMetadata(x, y - 1, z)); dimension.createLink(x, y, z, LinkType.SAFE_EXIT,world.getBlockMetadata(x, y - 1, z));
} }
} }
} }
@Override
public int getDoorItem()
{
return 0;
}
@Override @Override
public int getDrops() public int getDrops()
{ {

View File

@@ -3,8 +3,9 @@ package StevenDimDoors.mod_pocketDim.blocks;
import net.minecraft.block.material.Material; import net.minecraft.block.material.Material;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.world.World; import net.minecraft.world.World;
import StevenDimDoors.mod_pocketDim.DDProperties; import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.core.LinkTypes; import StevenDimDoors.mod_pocketDim.config.DDProperties;
import StevenDimDoors.mod_pocketDim.core.LinkType;
import StevenDimDoors.mod_pocketDim.core.NewDimData; import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager; import StevenDimDoors.mod_pocketDim.core.PocketManager;
@@ -21,9 +22,16 @@ public class UnstableDoor extends BaseDimDoor
if (!world.isRemote && world.getBlockId(x, y - 1, z) == this.blockID) if (!world.isRemote && world.getBlockId(x, y - 1, z) == this.blockID)
{ {
NewDimData dimension = PocketManager.getDimensionData(world); NewDimData dimension = PocketManager.getDimensionData(world);
dimension.createLink(x, y, z, LinkTypes.RANDOM,world.getBlockMetadata(x, y - 1, z)); dimension.createLink(x, y, z, LinkType.RANDOM,world.getBlockMetadata(x, y - 1, z));
} }
} }
@Override
public int getDoorItem()
{
return mod_pocketDim.itemUnstableDoor.itemID;
}
@Override @Override
public int getDrops() public int getDrops()
{ {

View File

@@ -3,13 +3,13 @@ package StevenDimDoors.mod_pocketDim.blocks;
import net.minecraft.block.material.Material; import net.minecraft.block.material.Material;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.world.World; import net.minecraft.world.World;
import StevenDimDoors.mod_pocketDim.DDProperties; import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.config.DDProperties;
import StevenDimDoors.mod_pocketDim.core.DimLink; import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.LinkTypes; import StevenDimDoors.mod_pocketDim.core.LinkType;
import StevenDimDoors.mod_pocketDim.core.NewDimData; import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager; import StevenDimDoors.mod_pocketDim.core.PocketManager;
@SuppressWarnings("deprecation")
public class WarpDoor extends BaseDimDoor public class WarpDoor extends BaseDimDoor
{ {
public WarpDoor(int blockID, Material material, DDProperties properties) public WarpDoor(int blockID, Material material, DDProperties properties)
@@ -22,15 +22,21 @@ public class WarpDoor extends BaseDimDoor
{ {
if (!world.isRemote && world.getBlockId(x, y - 1, z) == this.blockID) if (!world.isRemote && world.getBlockId(x, y - 1, z) == this.blockID)
{ {
NewDimData dimension = PocketManager.getDimensionData(world); NewDimData dimension = PocketManager.createDimensionData(world);
DimLink link = dimension.getLink(x, y, z); DimLink link = dimension.getLink(x, y, z);
if (link == null && dimension.isPocketDimension()) if (link == null && dimension.isPocketDimension())
{ {
dimension.createLink(x, y, z, LinkTypes.SAFE_EXIT,world.getBlockMetadata(x, y - 1, z)); dimension.createLink(x, y, z, LinkType.SAFE_EXIT,world.getBlockMetadata(x, y - 1, z));
} }
} }
} }
@Override
public int getDoorItem()
{
return mod_pocketDim.itemWarpDoor.itemID;
}
@Override @Override
public int getDrops() public int getDrops()
{ {

View File

@@ -1,27 +1,25 @@
package StevenDimDoors.mod_pocketDim.commands; package StevenDimDoors.mod_pocketDim.commands;
import java.util.Collection;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.MathHelper;
import StevenDimDoors.mod_pocketDim.mod_pocketDim; import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.core.DimLink; import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.LinkTypes; import StevenDimDoors.mod_pocketDim.core.LinkType;
import StevenDimDoors.mod_pocketDim.core.NewDimData; import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager; import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.dungeon.DungeonData; import StevenDimDoors.mod_pocketDim.dungeon.DungeonData;
import StevenDimDoors.mod_pocketDim.helpers.DungeonHelper; import StevenDimDoors.mod_pocketDim.helpers.DungeonHelper;
import StevenDimDoors.mod_pocketDim.world.PocketBuilder; import StevenDimDoors.mod_pocketDim.world.PocketBuilder;
import java.util.Collection;
import net.minecraft.command.ICommandSender;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.MathHelper;
public class CommandCreateDungeonRift extends DDCommandBase public class CommandCreateDungeonRift extends DDCommandBase
{ {
private static CommandCreateDungeonRift instance = null; private static CommandCreateDungeonRift instance = null;
private CommandCreateDungeonRift() private CommandCreateDungeonRift()
{ {
super("dd-rift", "<dungeon name | 'list' | 'random'>"); super("dd-rift", "<dungeon name>");
} }
public static CommandCreateDungeonRift instance() public static CommandCreateDungeonRift instance()
@@ -32,24 +30,12 @@ public class CommandCreateDungeonRift extends DDCommandBase
return instance; return instance;
} }
@Override
public String getCommandUsage(ICommandSender sender)
{
return "Usage: /dd-rift <dungeon name>\r\n" +
" /dd-rift list\r\n" +
" /dd-rift random";
}
@Override @Override
protected DDCommandResult processCommand(EntityPlayer sender, String[] command) protected DDCommandResult processCommand(EntityPlayer sender, String[] command)
{ {
NewDimData dimension; NewDimData dimension;
DungeonHelper dungeonHelper = DungeonHelper.instance(); DungeonHelper dungeonHelper = DungeonHelper.instance();
if (sender.worldObj.isRemote)
{
return DDCommandResult.SUCCESS;
}
if (command.length == 0) if (command.length == 0)
{ {
return DDCommandResult.TOO_FEW_ARGUMENTS; return DDCommandResult.TOO_FEW_ARGUMENTS;
@@ -59,17 +45,6 @@ public class CommandCreateDungeonRift extends DDCommandBase
return DDCommandResult.TOO_MANY_ARGUMENTS; return DDCommandResult.TOO_MANY_ARGUMENTS;
} }
if (command[0].equals("list"))
{
Collection<String> dungeonNames = dungeonHelper.getDungeonNames();
for (String name : dungeonNames)
{
sendChat(sender, name);
}
sendChat(sender, "");
}
else
{
DimLink link; DimLink link;
DungeonData result; DungeonData result;
int x = MathHelper.floor_double(sender.posX); int x = MathHelper.floor_double(sender.posX);
@@ -77,42 +52,40 @@ public class CommandCreateDungeonRift extends DDCommandBase
int z = MathHelper.floor_double (sender.posZ); int z = MathHelper.floor_double (sender.posZ);
int orientation = MathHelper.floor_double((sender.rotationYaw + 180.0F) * 4.0F / 360.0F - 0.5D) & 3; int orientation = MathHelper.floor_double((sender.rotationYaw + 180.0F) * 4.0F / 360.0F - 0.5D) & 3;
if (command[0].equals("random"))
{
dimension = PocketManager.getDimensionData(sender.worldObj);
link = dimension.createLink(x, y + 1, z, LinkTypes.DUNGEON, orientation);
sender.worldObj.setBlock(x, y + 1, z,mod_pocketDim.blockRift.blockID, 0, 3);
sendChat(sender, "Created a rift to a random dungeon.");
}
else
{
result = findDungeonByPartialName(command[0], dungeonHelper.getRegisteredDungeons()); result = findDungeonByPartialName(command[0], dungeonHelper.getRegisteredDungeons());
if (result == null) if (result == null)
{ {
result = findDungeonByPartialName(command[0], dungeonHelper.getUntaggedDungeons()); result = findDungeonByPartialName(command[0], dungeonHelper.getUntaggedDungeons());
} }
// Check if we found any matches // Check if we found any matches
if (result != null) if (result != null)
{ {
//Create a rift to our selected dungeon and notify the player
dimension = PocketManager.getDimensionData(sender.worldObj); dimension = PocketManager.getDimensionData(sender.worldObj);
link = dimension.createLink(x, y + 1, z, LinkTypes.DUNGEON, orientation); link = dimension.createLink(x, y + 1, z, LinkType.DUNGEON, orientation);
PocketBuilder.generateSelectedDungeonPocket(link, mod_pocketDim.properties, result);
if (PocketBuilder.generateSelectedDungeonPocket(link, mod_pocketDim.properties, result))
{
// Create a rift to our selected dungeon and notify the player
sender.worldObj.setBlock(x, y + 1, z, mod_pocketDim.blockRift.blockID, 0, 3); sender.worldObj.setBlock(x, y + 1, z, mod_pocketDim.blockRift.blockID, 0, 3);
sendChat(sender, "Created a rift to \"" + result.schematicName() + "\" dungeon (Dimension ID = " + link.destination().getDimension() + ")."); sendChat(sender, "Created a rift to \"" + result.schematicName() + "\" dungeon (Dimension ID = " + link.destination().getDimension() + ").");
} }
else else
{
// Dungeon generation failed somehow. Notify the user and remove the useless link.
dimension.deleteLink(link);
sendChat(sender, "Dungeon generation failed unexpectedly!");
}
}
else
{ {
//No matches! //No matches!
return new DDCommandResult("Error: The specified dungeon was not found. Use 'list' to see a list of the available dungeons."); return new DDCommandResult("Error: The specified dungeon was not found. Use 'dd-list' to see a list of the available dungeons.");
}
}
} }
return DDCommandResult.SUCCESS; return DDCommandResult.SUCCESS;
} }
private DungeonData findDungeonByPartialName(String query, Collection<DungeonData> dungeons) private static DungeonData findDungeonByPartialName(String query, Collection<DungeonData> dungeons)
{ {
//Search for the shortest dungeon name that contains the lowercase query string. //Search for the shortest dungeon name that contains the lowercase query string.
String dungeonName; String dungeonName;

View File

@@ -1,6 +1,5 @@
package StevenDimDoors.mod_pocketDim.commands; package StevenDimDoors.mod_pocketDim.commands;
import net.minecraft.command.ICommandSender;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import StevenDimDoors.mod_pocketDim.helpers.DungeonHelper; import StevenDimDoors.mod_pocketDim.helpers.DungeonHelper;
@@ -21,18 +20,8 @@ public class CommandCreatePocket extends DDCommandBase
return instance; return instance;
} }
@Override
public String getCommandUsage(ICommandSender sender) {
return "Usage: /dd-create";
}
@Override @Override
protected DDCommandResult processCommand(EntityPlayer sender, String[] command) protected DDCommandResult processCommand(EntityPlayer sender, String[] command)
{
//TODO: Some commands have isRemote checks, some do not. Why? Can commands even run locally anyway?
//What does it mean when you run a command locally? ~SenseiKiwi
if (!sender.worldObj.isRemote)
{ {
if (command.length > 0) if (command.length > 0)
{ {
@@ -47,8 +36,8 @@ public class CommandCreatePocket extends DDCommandBase
DungeonHelper.instance().createCustomDungeonDoor(sender.worldObj, x, y, z); DungeonHelper.instance().createCustomDungeonDoor(sender.worldObj, x, y, z);
//Notify the player //Notify the player
sendChat(sender,("Created a door to a pocket dimension. Please build your dungeon there.")); sendChat(sender, "Created a door to a pocket dimension. Please build your dungeon there.");
}
return DDCommandResult.SUCCESS; return DDCommandResult.SUCCESS;
} }
} }

View File

@@ -0,0 +1,121 @@
package StevenDimDoors.mod_pocketDim.commands;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Random;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.MathHelper;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.LinkType;
import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.dungeon.DungeonData;
import StevenDimDoors.mod_pocketDim.helpers.DungeonHelper;
import StevenDimDoors.mod_pocketDim.world.PocketBuilder;
public class CommandCreateRandomRift extends DDCommandBase
{
private static CommandCreateRandomRift instance = null;
private static Random random = new Random();
private CommandCreateRandomRift()
{
super("dd-random", "<dungeon name>");
}
public static CommandCreateRandomRift instance()
{
if (instance == null)
instance = new CommandCreateRandomRift();
return instance;
}
@Override
protected DDCommandResult processCommand(EntityPlayer sender, String[] command)
{
NewDimData dimension;
DungeonHelper dungeonHelper = DungeonHelper.instance();
if (command.length > 1)
{
return DDCommandResult.TOO_MANY_ARGUMENTS;
}
DimLink link;
DungeonData result;
int x = MathHelper.floor_double(sender.posX);
int y = MathHelper.floor_double(sender.posY);
int z = MathHelper.floor_double (sender.posZ);
int orientation = MathHelper.floor_double((sender.rotationYaw + 180.0F) * 4.0F / 360.0F - 0.5D) & 3;
if (command.length == 0)
{
dimension = PocketManager.getDimensionData(sender.worldObj);
link = dimension.createLink(x, y + 1, z, LinkType.DUNGEON, orientation);
sender.worldObj.setBlock(x, y + 1, z,mod_pocketDim.blockRift.blockID, 0, 3);
sendChat(sender, "Created a rift to a random dungeon.");
}
else
{
result = getRandomDungeonByPartialName(command[0], dungeonHelper.getRegisteredDungeons());
if (result == null)
{
result = getRandomDungeonByPartialName(command[0], dungeonHelper.getUntaggedDungeons());
}
// Check if we found any matches
if (result != null)
{
dimension = PocketManager.getDimensionData(sender.worldObj);
link = dimension.createLink(x, y + 1, z, LinkType.DUNGEON, orientation);
if (PocketBuilder.generateSelectedDungeonPocket(link, mod_pocketDim.properties, result))
{
// Create a rift to our selected dungeon and notify the player
sender.worldObj.setBlock(x, y + 1, z, mod_pocketDim.blockRift.blockID, 0, 3);
sendChat(sender, "Created a rift to \"" + result.schematicName() + "\" dungeon (Dimension ID = " + link.destination().getDimension() + ").");
}
else
{
// Dungeon generation failed somehow. Notify the user and remove the useless link.
dimension.deleteLink(link);
sendChat(sender, "Dungeon generation failed unexpectedly!");
}
}
else
{
//No matches!
return new DDCommandResult("Error: The specified dungeon was not found. Use 'list' to see a list of the available dungeons.");
}
}
return DDCommandResult.SUCCESS;
}
private static DungeonData getRandomDungeonByPartialName(String query, Collection<DungeonData> dungeons)
{
// Search for all dungeons that contain the lowercase query string.
String dungeonName;
String normalQuery = query.toLowerCase();
ArrayList<DungeonData> matches = new ArrayList<DungeonData>();
for (DungeonData dungeon : dungeons)
{
// We need to extract the file's name. Comparing against schematicPath could
// yield false matches if the query string is contained within the path.
dungeonName = dungeon.schematicName().toLowerCase();
if (dungeonName.contains(normalQuery))
{
matches.add(dungeon);
}
}
if (matches.isEmpty())
{
return null;
}
return matches.get( random.nextInt(matches.size()) );
}
}

View File

@@ -1,74 +0,0 @@
package StevenDimDoors.mod_pocketDim.commands;
import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
import java.util.ArrayList;
import net.minecraft.command.ICommandSender;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.world.World;
@SuppressWarnings("deprecation")
public class CommandDeleteAllLinks extends DDCommandBase
{
private static CommandDeleteAllLinks instance = null;
private CommandDeleteAllLinks()
{
super("dd-deletelinks", "???");
}
public static CommandDeleteAllLinks instance()
{
if (instance == null)
instance = new CommandDeleteAllLinks();
return instance;
}
@Override
public String getCommandUsage(ICommandSender sender) {
return "Usage: /dd-deletelinks <targetDimensionID>";
}
@Override
protected DDCommandResult processCommand(EntityPlayer sender, String[] command)
{
int linksRemoved=0;
int targetDim;
boolean shouldGo= true;
if(command.length==1)
{
targetDim = parseInt(sender, command[0]);
}
else
{
targetDim=0;
shouldGo=false;
sendChat(sender, ("Error-Invalid argument, delete_all_links <targetDimID>"));
}
if(shouldGo)
{
NewDimData dim = PocketManager.getDimensionData(targetDim);
ArrayList<DimLink> linksInDim = dim.getAllLinks();
for (DimLink link : linksInDim)
{
World targetWorld = PocketManager.loadDimension(targetDim);
targetWorld.setBlock(link.source().getX(), link.source().getY(), link.source().getZ(), 0);
dim.deleteLink(link);
//TODO Probably should check what the block is, but thats annoying so Ill do it later.
linksRemoved++;
}
sendChat(sender,("Removed " + linksRemoved + " links."));
}
return DDCommandResult.SUCCESS; //TEMPORARY HACK
}
}

View File

@@ -2,22 +2,21 @@ package StevenDimDoors.mod_pocketDim.commands;
import java.util.ArrayList; import java.util.ArrayList;
import net.minecraft.command.ICommandSender;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.world.World; import net.minecraft.world.World;
import StevenDimDoors.mod_pocketDim.mod_pocketDim; import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.core.DimLink; import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.NewDimData; import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager; import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.util.Point4D;
@SuppressWarnings("deprecation")
public class CommandDeleteRifts extends DDCommandBase public class CommandDeleteRifts extends DDCommandBase
{ {
private static CommandDeleteRifts instance = null; private static CommandDeleteRifts instance = null;
private CommandDeleteRifts() private CommandDeleteRifts()
{ {
super("dd-???", "???"); super("dd-deleterifts", "[dimension number]");
} }
public static CommandDeleteRifts instance() public static CommandDeleteRifts instance()
@@ -28,55 +27,67 @@ public class CommandDeleteRifts extends DDCommandBase
return instance; return instance;
} }
@Override
public String getCommandUsage(ICommandSender sender) {
return "Usage: /dd-??? <dimension ID>";
}
@Override @Override
protected DDCommandResult processCommand(EntityPlayer sender, String[] command) protected DDCommandResult processCommand(EntityPlayer sender, String[] command)
{ {
int linksRemoved = 0; int linksRemoved = 0;
int targetDim; int targetDimension;
boolean shouldGo= true;
if(command.length==1) if (command.length > 1)
{ {
targetDim = parseInt(sender, command[0]); return DDCommandResult.TOO_MANY_ARGUMENTS;
}
if (command.length == 0)
{
targetDimension = sender.worldObj.provider.dimensionId;
} }
else else
{ {
targetDim=0; try
shouldGo=false; {
sendChat(sender,("Error-Invalid argument, delete_all_links <targetDimID>")); targetDimension = Integer.parseInt(command[0]);
}
catch (NumberFormatException e)
{
return DDCommandResult.INVALID_DIMENSION_ID;
}
} }
if(shouldGo) World world = PocketManager.loadDimension(targetDimension);
if (world == null)
{ {
return DDCommandResult.UNREGISTERED_DIMENSION;
}
NewDimData dim = PocketManager.getDimensionData(targetDim); int x;
ArrayList<DimLink> linksInDim = dim.getAllLinks(); int y;
int z;
for (DimLink link : linksInDim) Point4D location;
NewDimData dimension = PocketManager.createDimensionData(world);
ArrayList<DimLink> links = dimension.getAllLinks();
for (DimLink link : links)
{ {
World targetWorld = PocketManager.loadDimension(targetDim); location = link.source();
x = location.getX();
if(!mod_pocketDim.blockRift.isBlockImmune(sender.worldObj,link.source().getX(), link.source().getY(), link.source().getZ())|| y = location.getY();
(targetWorld.getBlockId(link.source().getX(), link.source().getY(), link.source().getZ())==mod_pocketDim.blockRift.blockID)) z = location.getZ();
if (world.getBlockId(x, y, z) == mod_pocketDim.blockRift.blockID)
{ {
// Remove the rift and its link
world.setBlockToAir(x, y, z);
dimension.deleteLink(link);
linksRemoved++; linksRemoved++;
targetWorld.setBlock(link.source().getX(), link.source().getY(), link.source().getZ(), 0);
dim.deleteLink(link);
} }
//TODO Probably should check what the block is, but thats annoying so Ill do it later. else if (!mod_pocketDim.blockRift.isBlockImmune(world, x, y, z))
{
// If a block is not immune, then it must not be a DD block.
} // The link would regenerate into a rift eventually.
sendChat(sender,("Removed " + linksRemoved + " links.")); // We only need to remove the link.
dimension.deleteLink(link);
} linksRemoved++;
return DDCommandResult.SUCCESS; //TEMPORARY HACK }
}
sendChat(sender, "Removed " + linksRemoved + " links.");
return DDCommandResult.SUCCESS;
} }
} }

View File

@@ -2,9 +2,8 @@ package StevenDimDoors.mod_pocketDim.commands;
import java.io.File; import java.io.File;
import net.minecraft.command.ICommandSender;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import StevenDimDoors.mod_pocketDim.DDProperties; import StevenDimDoors.mod_pocketDim.config.DDProperties;
import StevenDimDoors.mod_pocketDim.helpers.DungeonHelper; import StevenDimDoors.mod_pocketDim.helpers.DungeonHelper;
public class CommandExportDungeon extends DDCommandBase public class CommandExportDungeon extends DDCommandBase
@@ -26,13 +25,6 @@ public class CommandExportDungeon extends DDCommandBase
return instance; return instance;
} }
@Override
public String getCommandUsage(ICommandSender sender) {
return "Usage: /dd-export <dungeon type> <dungeon name> open <weight>\r\n" +
" /dd-export <dungeon type> <dungeon name> closed <weight>\r\n" +
" /dd-export <schematic name> override";
}
@Override @Override
protected DDCommandResult processCommand(EntityPlayer sender, String[] command) protected DDCommandResult processCommand(EntityPlayer sender, String[] command)
{ {
@@ -67,25 +59,15 @@ public class CommandExportDungeon extends DDCommandBase
//Export the schematic //Export the schematic
return exportDungeon(sender, command[0]); return exportDungeon(sender, command[0]);
} }
else
{
//The schematic name contains illegal characters. Inform the user. //The schematic name contains illegal characters. Inform the user.
return new DDCommandResult("Error: Invalid schematic name. Please use only letters, numbers, dashes, and underscores."); return new DDCommandResult("Error: Invalid schematic name. Please use only letters, numbers, dashes, and underscores.");
} }
}
else
{
//The command is malformed in some way. Assume that the user meant to use //The command is malformed in some way. Assume that the user meant to use
//the 3-argument version and report an error. //the 3-argument version and report an error.
return DDCommandResult.TOO_FEW_ARGUMENTS; return DDCommandResult.TOO_FEW_ARGUMENTS;
} }
}
//The user must have used the 3-argument version of this command //The user must have used the 3-argument version of this command
//TODO: Why do we check remoteness here but not before? And why not for the other export case?
//Something feels wrong... ~SenseiKiwi
if (!sender.worldObj.isRemote)
{
//TODO: This validation should be in DungeonHelper or in another class. We should move it //TODO: This validation should be in DungeonHelper or in another class. We should move it
//during the save file format rewrite. ~SenseiKiwi //during the save file format rewrite. ~SenseiKiwi
@@ -107,8 +89,7 @@ public class CommandExportDungeon extends DDCommandBase
{ {
return exportDungeon(sender, join(command, "_", 0, 3)); return exportDungeon(sender, join(command, "_", 0, 3));
} }
else
{
//Validate the weight argument //Validate the weight argument
try try
{ {
@@ -119,16 +100,12 @@ public class CommandExportDungeon extends DDCommandBase
} }
} }
catch (Exception e) { } catch (Exception e) { }
}
//If we've reached this point, then we must have an invalid weight. //If we've reached this point, then we must have an invalid weight.
return new DDCommandResult("Invalid dungeon weight. Please specify a weight between " return new DDCommandResult("Invalid dungeon weight. Please specify a weight between "
+ DungeonHelper.MIN_DUNGEON_WEIGHT + " and " + DungeonHelper.MAX_DUNGEON_WEIGHT + ", inclusive."); + DungeonHelper.MIN_DUNGEON_WEIGHT + " and " + DungeonHelper.MAX_DUNGEON_WEIGHT + ", inclusive.");
} }
return DDCommandResult.SUCCESS;
}
private static DDCommandResult exportDungeon(EntityPlayer player, String name) private static DDCommandResult exportDungeon(EntityPlayer player, String name)
{ {
DDProperties properties = DDProperties.instance(); DDProperties properties = DDProperties.instance();
@@ -144,11 +121,8 @@ public class CommandExportDungeon extends DDCommandBase
dungeonHelper.registerDungeon(exportPath, dungeonHelper.getDungeonPack("ruins"), false, true); dungeonHelper.registerDungeon(exportPath, dungeonHelper.getDungeonPack("ruins"), false, true);
return DDCommandResult.SUCCESS; return DDCommandResult.SUCCESS;
} }
else
{
return new DDCommandResult("Error: Failed to save dungeon schematic!"); return new DDCommandResult("Error: Failed to save dungeon schematic!");
} }
}
private static String join(String[] source, String delimiter, int start, int end) private static String join(String[] source, String delimiter, int start, int end)
{ {

View File

@@ -0,0 +1,70 @@
package StevenDimDoors.mod_pocketDim.commands;
import java.util.ArrayList;
import net.minecraft.entity.player.EntityPlayer;
import StevenDimDoors.mod_pocketDim.helpers.DungeonHelper;
public class CommandListDungeons extends DDCommandBase
{
private static CommandListDungeons instance = null;
private CommandListDungeons()
{
super("dd-list", "<page>");
}
public static CommandListDungeons instance()
{
if (instance == null)
instance = new CommandListDungeons();
return instance;
}
@Override
protected DDCommandResult processCommand(EntityPlayer sender, String[] command)
{
int page;
int index;
int limit;
int pageCount;
ArrayList<String> dungeonNames;
if (command.length > 1)
{
return DDCommandResult.TOO_MANY_ARGUMENTS;
}
if (command.length == 0)
{
page = 1;
}
else
{
try
{
page = Integer.parseInt(command[0]);
}
catch (NumberFormatException e)
{
return DDCommandResult.INVALID_ARGUMENTS;
}
}
dungeonNames = DungeonHelper.instance().getDungeonNames();
pageCount = (dungeonNames.size() - 1) / 10 + 1;
if (page < 1 || page > pageCount)
{
return DDCommandResult.INVALID_ARGUMENTS;
}
sendChat(sender, "List of dungeons (page " + page + " of " + pageCount + "):");
index = (page - 1) * 10;
limit = Math.min(index + 10, dungeonNames.size());
for (; index < limit; index++)
{
sendChat(sender, dungeonNames.get(index));
}
sendChat(sender, "");
return DDCommandResult.SUCCESS;
}
}

View File

@@ -1,16 +1,14 @@
package StevenDimDoors.mod_pocketDim.commands; package StevenDimDoors.mod_pocketDim.commands;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet;
import net.minecraft.command.ICommandSender;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraftforge.common.DimensionManager;
import StevenDimDoors.mod_pocketDim.core.DimLink; import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.LinkTypes; import StevenDimDoors.mod_pocketDim.core.DimensionType;
import StevenDimDoors.mod_pocketDim.core.LinkType;
import StevenDimDoors.mod_pocketDim.core.NewDimData; import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager; import StevenDimDoors.mod_pocketDim.core.PocketManager;
@SuppressWarnings("deprecation")
public class CommandResetDungeons extends DDCommandBase public class CommandResetDungeons extends DDCommandBase
{ {
private static CommandResetDungeons instance = null; private static CommandResetDungeons instance = null;
@@ -28,68 +26,80 @@ public class CommandResetDungeons extends DDCommandBase
return instance; return instance;
} }
@Override
public String getCommandUsage(ICommandSender sender) {
return "/dd-resetdungeons";
}
@Override @Override
protected DDCommandResult processCommand(EntityPlayer sender, String[] command) protected DDCommandResult processCommand(EntityPlayer sender, String[] command)
{ {
if(sender.worldObj.isRemote)
{
return DDCommandResult.SUCCESS;
}
if (command.length > 0) if (command.length > 0)
{ {
return DDCommandResult.TOO_FEW_ARGUMENTS; return DDCommandResult.TOO_MANY_ARGUMENTS;
} }
int dungeonCount = 0; int id;
int resetCount = 0; int resetCount = 0;
ArrayList<Integer> dimsToDelete = new ArrayList<Integer>(); int dungeonCount = 0;
ArrayList<Integer> dimsToFix = new ArrayList<Integer>(); HashSet<Integer> deletedDimensions = new HashSet<Integer>();
ArrayList<NewDimData> loadedDungeons = new ArrayList<NewDimData>();
for (NewDimData data : PocketManager.getDimensions()) // Copy the list of dimensions to iterate over the copy. Otherwise,
// we would trigger an exception by modifying the original list.
ArrayList<NewDimData> dimensions = new ArrayList<NewDimData>();
for (NewDimData dimension : PocketManager.getDimensions())
{ {
if(DimensionManager.getWorld(data.id())==null&&data.isDungeon()) dimensions.add(dimension);
}
// Iterate over the list of dimensions. Check which ones are dungeons.
// If a dungeon is found, try to delete it. If it can't be deleted,
// then it must be loaded and needs to be updated to prevent bugs.
for (NewDimData dimension : dimensions)
{
if (dimension.type() == DimensionType.DUNGEON)
{
dungeonCount++;
id = dimension.id();
if (PocketManager.deletePocket(dimension, true))
{ {
resetCount++; resetCount++;
dungeonCount++; deletedDimensions.add(id);
dimsToDelete.add(data.id());
} }
else if(data.isDungeon()) else
{ {
dimsToFix.add(data.id()); loadedDungeons.add(dimension);
dungeonCount++;
for(DimLink link : data.links())
{
if(link.linkType()==LinkTypes.REVERSE)
{
data.createLink(link.source(), LinkTypes.DUNGEON_EXIT, link.orientation());
} }
if(link.linkType()==LinkTypes.DUNGEON) }
}
// Modify the loaded dungeons to prevent bugs
for (NewDimData dungeon : loadedDungeons)
{ {
data.createLink(link.source(), LinkTypes.DUNGEON, link.orientation()); // Find top-most loaded dungeons and update their parents.
// They will automatically update their children.
// Dungeons with non-dungeon parents don't need to be fixed.
if (dungeon.parent() == null)
{
dungeon.setParentToRoot();
}
// Links to any deleted dungeons must be replaced
for (DimLink link : dungeon.links())
{
if (link.hasDestination() && deletedDimensions.contains(link.destination().getDimension()))
{
if (link.linkType() == LinkType.DUNGEON)
{
dungeon.createLink(link.source(), LinkType.DUNGEON, link.orientation(), null);
}
else if (link.linkType() == LinkType.REVERSE)
{
dungeon.createLink(link.source(), LinkType.DUNGEON_EXIT, link.orientation(), null);
} }
} }
} }
} }
for(Integer dimID:dimsToDelete)
{
PocketManager.deletePocket(PocketManager.getDimensionData(dimID), true);
}
/**
* temporary workaround
*/
for(Integer dimID: dimsToFix)
{
PocketManager.getDimensionData(dimID).setParentToRoot();
}
//TODO- for some reason the parent field of loaded dimenions get reset to null if I call .setParentToRoot() before I delete the pockets.
//TODO implement blackList
// Notify the user of the results // Notify the user of the results
sendChat(sender,("Reset complete. " + resetCount + " out of " + dungeonCount + " dungeons were reset.")); sendChat(sender,("Reset complete. " + resetCount + " out of " + dungeonCount + " dungeons were reset."));
return DDCommandResult.SUCCESS; return DDCommandResult.SUCCESS;

View File

@@ -1,133 +1,137 @@
package StevenDimDoors.mod_pocketDim.commands; package StevenDimDoors.mod_pocketDim.commands;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.server.MinecraftServer;
import net.minecraft.world.World;
import StevenDimDoors.mod_pocketDim.core.DDTeleporter; import StevenDimDoors.mod_pocketDim.core.DDTeleporter;
import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager; import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.util.Point4D; import StevenDimDoors.mod_pocketDim.util.Point4D;
import java.util.Arrays;
import java.util.List;
import net.minecraft.command.ICommandSender;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraftforge.common.DimensionManager;
public class CommandTeleportPlayer extends DDCommandBase public class CommandTeleportPlayer extends DDCommandBase
{ {
private static CommandTeleportPlayer instance = null; private static CommandTeleportPlayer instance = null;
private CommandTeleportPlayer() private CommandTeleportPlayer()
{ {
super("dd-tp", new String[] {"<Player Name> <Dimension ID> <X Coord> <Y Coord> <Z Coord>","<Player Name> <Dimension ID>"} ); super("dd-tp", new String[] {
"<player name> <dimension number>",
"<player name> <x> <y> <z>",
"<player name> <dimension number> <x> <y> <z>"} );
} }
public static CommandTeleportPlayer instance() public static CommandTeleportPlayer instance()
{ {
if (instance == null) if (instance == null)
{
instance = new CommandTeleportPlayer(); instance = new CommandTeleportPlayer();
}
return instance; return instance;
} }
@Override
public String getCommandUsage(ICommandSender sender) {
return "Usage: /dd-tp <player name> <dimension id> <x> <y> <z>";
}
/**
* TODO- Change to accept variety of input, like just coords, just dim ID, or two player names.
*/
@Override @Override
protected DDCommandResult processCommand(EntityPlayer sender, String[] command) protected DDCommandResult processCommand(EntityPlayer sender, String[] command)
{ {
EntityPlayer targetPlayer = sender; int x;
int dimDestinationID = sender.worldObj.provider.dimensionId; int y;
int z;
World world;
int dimensionID;
Point4D destination;
NewDimData dimension;
boolean checkOrientation;
EntityPlayer targetPlayer;
if(command.length == 5) if (command.length < 2)
{ {
for(int i= 1; i <5;i++) return DDCommandResult.TOO_FEW_ARGUMENTS;
}
if (command.length > 5)
{ {
if(!isInteger(command[i])) return DDCommandResult.TOO_MANY_ARGUMENTS;
}
if (command.length == 3)
{
return DDCommandResult.INVALID_ARGUMENTS;
}
// Check that all arguments after the username are integers
for (int k = 1; k < command.length; k++)
{
if (!isInteger(command[k]))
{ {
return DDCommandResult.INVALID_ARGUMENTS; return DDCommandResult.INVALID_ARGUMENTS;
} }
} }
if(sender.worldObj.getPlayerEntityByName(command[0])!=null) //Gets the targeted player // Check if the target player is logged in
targetPlayer = MinecraftServer.getServer().getConfigurationManager().getPlayerForUsername(command[0]);
if (targetPlayer == null)
{ {
targetPlayer = sender.worldObj.getPlayerEntityByName(command[0]); return DDCommandResult.PLAYER_OFFLINE;
}
// If a dimension ID was provided, try to load it
if (command.length != 4)
{
dimensionID = Integer.parseInt(command[1]);
world = PocketManager.loadDimension(dimensionID);
if (world == null)
{
return DDCommandResult.UNREGISTERED_DIMENSION;
}
} }
else else
{ {
return DDCommandResult.INVALID_ARGUMENTS; dimensionID = targetPlayer.worldObj.provider.dimensionId;
} world = targetPlayer.worldObj;
dimDestinationID=Integer.parseInt(command[1]);//gets the target dim ID from the command string
if(!DimensionManager.isDimensionRegistered(dimDestinationID))
{
return DDCommandResult.INVALID_DIMENSION_ID;
} }
PocketManager.loadDimension(dimDestinationID); // If we teleport to a pocket dimension, set checkOrientation to true
Point4D destination = new Point4D(Integer.parseInt(command[2]),Integer.parseInt(command[3]),Integer.parseInt(command[4]),dimDestinationID); // so the player is placed correctly relative to the entrance door.
DDTeleporter.teleportEntity(targetPlayer, destination, false); checkOrientation = false;
}
else if(command.length == 2 && isInteger(command[1])) // Parse or calculate the destination as necessary
// The Y coordinate must be increased by 1 because of the way that
// DDTeleporter considers destination points. It assumes that the
// point provided is the upper block of a door.
if (command.length == 2)
{ {
if(sender.worldObj.getPlayerEntityByName(command[0])!=null) //Gets the targeted player // Check if the destination is a pocket dimension
dimension = PocketManager.createDimensionData(world);
if (dimension.isPocketDimension())
{ {
targetPlayer = sender.worldObj.getPlayerEntityByName(command[0]); // The destination is a pocket dimension.
// Teleport the player to its original entrance (the origin).
destination = dimension.origin();
checkOrientation = true;
} }
else else
{ {
return DDCommandResult.INVALID_ARGUMENTS; // The destination is not a pocket dimension, which means we
// don't automatically know a safe location where we can send
// the player. Send the player to (0, Y, 0), where Y is chosen
// by searching. Add 2 to place the player ABOVE the top block.
y = world.getTopSolidOrLiquidBlock(0, 0) + 2;
destination = new Point4D(0, y, 0, dimensionID);
} }
dimDestinationID=Integer.parseInt(command[1]);//gets the target dim ID from the command string }
else if (command.length == 4)
if(!DimensionManager.isDimensionRegistered(dimDestinationID))
{ {
return DDCommandResult.INVALID_DIMENSION_ID; x = Integer.parseInt(command[1]);
} y = Integer.parseInt(command[2]) + 1; // Correct the Y value
z = Integer.parseInt(command[3]);
destination = new Point4D(x, y, z, dimensionID);
Point4D destination = PocketManager.getDimensionData(dimDestinationID).origin();
if(!PocketManager.getDimensionData(dimDestinationID).isPocketDimension())
{
destination = new Point4D(destination.getX(),PocketManager.loadDimension(dimDestinationID).getTopSolidOrLiquidBlock(
destination.getX(), destination.getZ()),
destination.getZ(),destination.getDimension());
}
DDTeleporter.teleportEntity(targetPlayer, destination, false);
}
else if(command.length == 1 && isInteger(command[0]))
{
targetPlayer = sender;
dimDestinationID=Integer.parseInt(command[0]);//gets the target dim ID from the command string
if(!DimensionManager.isDimensionRegistered(dimDestinationID))
{
return DDCommandResult.INVALID_DIMENSION_ID;
}
Point4D destination = PocketManager.getDimensionData(dimDestinationID).origin();
if(!PocketManager.getDimensionData(dimDestinationID).isPocketDimension())
{
destination = new Point4D(destination.getX(),PocketManager.loadDimension(dimDestinationID).getTopSolidOrLiquidBlock(
destination.getX(), destination.getZ()),
destination.getZ(),destination.getDimension());
}
DDTeleporter.teleportEntity(targetPlayer, destination, false);
} }
else else
{ {
return DDCommandResult.INVALID_ARGUMENTS; x = Integer.parseInt(command[2]);
y = Integer.parseInt(command[3]) + 1; // Correct the Y value
z = Integer.parseInt(command[4]);
destination = new Point4D(x, y, z, dimensionID);
} }
// Teleport!
DDTeleporter.teleportEntity(targetPlayer, destination, checkOrientation);
return DDCommandResult.SUCCESS; return DDCommandResult.SUCCESS;
} }
public boolean isInteger( String input ) private static boolean isInteger(String input)
{ {
try try
{ {
@@ -139,5 +143,4 @@ public class CommandTeleportPlayer extends DDCommandBase
return false; return false;
} }
} }
} }

View File

@@ -5,7 +5,6 @@ import net.minecraft.command.ICommand;
import net.minecraft.command.ICommandSender; import net.minecraft.command.ICommandSender;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.ChatMessageComponent; import net.minecraft.util.ChatMessageComponent;
import cpw.mods.fml.common.event.FMLServerStartingEvent;
/* /*
* An abstract base class for our Dimensional Doors commands. This cleans up the code a little and provides * An abstract base class for our Dimensional Doors commands. This cleans up the code a little and provides
@@ -40,12 +39,22 @@ public abstract class DDCommandBase extends CommandBase
return name; return name;
} }
/* @Override
* Registers the command at server startup. public final String getCommandUsage(ICommandSender sender)
*/
public void register(FMLServerStartingEvent event)
{ {
event.registerServerCommand(this); StringBuilder builder = new StringBuilder();
builder.append('/');
builder.append(name);
builder.append(' ');
builder.append(formats[0]);
for (int index = 1; index < formats.length; index++)
{
builder.append(" OR /");
builder.append(name);
builder.append(' ');
builder.append(formats[index]);
}
return builder.toString();
} }
/* /*
@@ -67,10 +76,10 @@ public abstract class DDCommandBase extends CommandBase
//Send the argument formats for this command //Send the argument formats for this command
for (String format : formats) for (String format : formats)
{ {
sendChat(player,("Usage: " + name + " " + format)); sendChat(player, "Usage: " + name + " " + format);
} }
} }
sendChat(player,(result.getMessage())); sendChat(player, result.getMessage());
} }
} }
@@ -79,12 +88,22 @@ public abstract class DDCommandBase extends CommandBase
ChatMessageComponent cmp = new ChatMessageComponent(); ChatMessageComponent cmp = new ChatMessageComponent();
cmp.addText(message); cmp.addText(message);
player.sendChatToPlayer(cmp); player.sendChatToPlayer(cmp);
}
/*
* The following two compareTo() methods are copied from CommandBase because it seems
* that Dryware and Technic Jenkins don't have those functions defined. How in the world?
* I have no idea. But it's breaking our builds. -_- ~SenseiKiwi
*/
@Override
public int compareTo(ICommand command)
{
return this.getCommandName().compareTo(command.getCommandName());
} }
@Override @Override
public int compareTo(Object par1Obj) public int compareTo(Object other)
{ {
return this.getCommandName().compareTo(((ICommand)par1Obj).getCommandName()); return this.compareTo((ICommand) other);
} }
} }

View File

@@ -8,7 +8,8 @@ public class DDCommandResult {
public static final DDCommandResult TOO_MANY_ARGUMENTS = new DDCommandResult(2, "Error: Too many arguments passed to the command", true); public static final DDCommandResult TOO_MANY_ARGUMENTS = new DDCommandResult(2, "Error: Too many arguments passed to the command", true);
public static final DDCommandResult INVALID_DIMENSION_ID = new DDCommandResult(3, "Error: Invalid dimension ID", true); public static final DDCommandResult INVALID_DIMENSION_ID = new DDCommandResult(3, "Error: Invalid dimension ID", true);
public static final DDCommandResult UNREGISTERED_DIMENSION = new DDCommandResult(4, "Error: Dimension is not registered", false); public static final DDCommandResult UNREGISTERED_DIMENSION = new DDCommandResult(4, "Error: Dimension is not registered", false);
public static final DDCommandResult INVALID_ARGUMENTS = new DDCommandResult(5, "Error: Invalid arguments passed to the command.", true); public static final DDCommandResult INVALID_ARGUMENTS = new DDCommandResult(5, "Error: Invalid arguments passed to the command", true);
public static final DDCommandResult PLAYER_OFFLINE = new DDCommandResult(6, "Error: Player is not online", false);
public static final int CUSTOM_ERROR_CODE = -1; public static final int CUSTOM_ERROR_CODE = -1;

View File

@@ -1,8 +1,9 @@
package StevenDimDoors.mod_pocketDim; package StevenDimDoors.mod_pocketDim.config;
import java.io.File; import java.io.File;
import net.minecraftforge.common.Configuration; import net.minecraftforge.common.Configuration;
import StevenDimDoors.mod_pocketDim.blocks.BlockRift;
import StevenDimDoors.mod_pocketDim.ticking.CustomLimboPopulator; import StevenDimDoors.mod_pocketDim.ticking.CustomLimboPopulator;
import StevenDimDoors.mod_pocketDim.world.fortresses.DDStructureNetherBridgeStart; import StevenDimDoors.mod_pocketDim.world.fortresses.DDStructureNetherBridgeStart;
import StevenDimDoors.mod_pocketDim.world.gateways.GatewayGenerator; import StevenDimDoors.mod_pocketDim.world.gateways.GatewayGenerator;
@@ -22,6 +23,9 @@ public class DDProperties
public final int TransientDoorID; public final int TransientDoorID;
public final int FabricBlockID; public final int FabricBlockID;
public final int RiftBlockID; public final int RiftBlockID;
public final int QuartzDoorID;
public final int PersonalDimDoorID;
/** /**
* World Generation Block IDs * World Generation Block IDs
@@ -45,7 +49,9 @@ public class DDProperties
public final int UnstableDoorItemID; public final int UnstableDoorItemID;
public final int WarpDoorItemID; public final int WarpDoorItemID;
public final int WorldThreadItemID; public final int WorldThreadItemID;
public final int DDKeyItemID;
public final int ItemQuartzDoorID;
public final int ItemPersonalDimDoorID;
/** /**
* Other IDs * Other IDs
@@ -56,6 +62,7 @@ public class DDProperties
public final int LimboDimensionID; public final int LimboDimensionID;
public final int LimboProviderID; public final int LimboProviderID;
public final int PocketProviderID; public final int PocketProviderID;
public final int PersonalPocketProviderID;
public final int DoorRenderEntityID; public final int DoorRenderEntityID;
public final int MonolithEntityID; public final int MonolithEntityID;
@@ -74,6 +81,9 @@ public class DDProperties
public final boolean CraftingStableFabricAllowed; public final boolean CraftingStableFabricAllowed;
public final boolean CraftingGoldenDimensionalDoorAllowed; public final boolean CraftingGoldenDimensionalDoorAllowed;
public final boolean CraftingGoldenDoorAllowed; public final boolean CraftingGoldenDoorAllowed;
public final boolean CraftingDDKeysAllowed;
public final boolean CraftingQuartzDoorAllowed;
public final boolean CraftingPersonalDimDoorAllowed;
/** /**
* Loot Flags * Loot Flags
@@ -87,7 +97,6 @@ public class DDProperties
* Other Flags * Other Flags
*/ */
public final boolean WorldRiftGenerationEnabled;
public final boolean RiftSpreadEnabled; public final boolean RiftSpreadEnabled;
public final boolean RiftGriefingEnabled; public final boolean RiftGriefingEnabled;
public final boolean RiftsSpawnEndermenEnabled; public final boolean RiftsSpawnEndermenEnabled;
@@ -96,6 +105,7 @@ public class DDProperties
public final boolean LimboReturnsInventoryEnabled; public final boolean LimboReturnsInventoryEnabled;
public final boolean DoorRenderingEnabled; public final boolean DoorRenderingEnabled;
public final boolean TNFREAKINGT_Enabled; public final boolean TNFREAKINGT_Enabled;
public final boolean MonolithTeleportationEnabled;
/** /**
@@ -107,7 +117,10 @@ public class DDProperties
public final int GatewayGenerationChance; public final int GatewayGenerationChance;
public final int FortressGatewayGenerationChance; public final int FortressGatewayGenerationChance;
public final int MonolithSpawningChance; public final int MonolithSpawningChance;
public final int WorldThreadDropChance;
public final int LimboEntryRange;
public final int LimboReturnRange; public final int LimboReturnRange;
public final int WorldThreadRequirementLevel;
public final String CustomSchematicDirectory; public final String CustomSchematicDirectory;
@@ -143,6 +156,13 @@ public class DDProperties
CraftingStableFabricAllowed = config.get(CATEGORY_CRAFTING, "Allow Crafting Stable Fabric", true).getBoolean(true); CraftingStableFabricAllowed = config.get(CATEGORY_CRAFTING, "Allow Crafting Stable Fabric", true).getBoolean(true);
CraftingGoldenDoorAllowed = config.get(CATEGORY_CRAFTING, "Allow Crafting Golden Door", true).getBoolean(true); CraftingGoldenDoorAllowed = config.get(CATEGORY_CRAFTING, "Allow Crafting Golden Door", true).getBoolean(true);
CraftingGoldenDimensionalDoorAllowed = config.get(CATEGORY_CRAFTING, "Allow Crafting Golden Dimensional Door", true).getBoolean(true); CraftingGoldenDimensionalDoorAllowed = config.get(CATEGORY_CRAFTING, "Allow Crafting Golden Dimensional Door", true).getBoolean(true);
CraftingDDKeysAllowed = config.get(CATEGORY_CRAFTING, "Allow Crafting Rift Keys", true).getBoolean(true);
CraftingQuartzDoorAllowed = config.get(CATEGORY_CRAFTING, "Allow Crafting Quartz Doors", true).getBoolean(true);
CraftingPersonalDimDoorAllowed = config.get(CATEGORY_CRAFTING, "Allow Crafting Personal Dim Doors", true).getBoolean(true);
WorldThreadRequirementLevel = config.get(CATEGORY_CRAFTING, "World Thread Requirement Level", 4,
"Controls the amount of World Thread needed to craft Stable Fabric. The number must be an " +
"integer from 1 to 4. The levels change the recipe to use 1, 2, 4, or 8 threads, respectively. The default level is 4.").getInt();
RiftBladeLootEnabled = config.get(CATEGORY_LOOT, "Enable Rift Blade Loot", true).getBoolean(true); RiftBladeLootEnabled = config.get(CATEGORY_LOOT, "Enable Rift Blade Loot", true).getBoolean(true);
FabricOfRealityLootEnabled = config.get(CATEGORY_LOOT, "Enable Fabric of Reality Loot", true).getBoolean(true); FabricOfRealityLootEnabled = config.get(CATEGORY_LOOT, "Enable Fabric of Reality Loot", true).getBoolean(true);
@@ -156,13 +176,15 @@ public class DDProperties
"Sets whether groups of connected rifts will spawn Endermen").getBoolean(true); "Sets whether groups of connected rifts will spawn Endermen").getBoolean(true);
LimboEnabled = config.get(Configuration.CATEGORY_GENERAL, "Enable Limbo", true, LimboEnabled = config.get(Configuration.CATEGORY_GENERAL, "Enable Limbo", true,
"Sets whether the Limbo dimension is activated").getBoolean(true); "Sets whether players are teleported to Limbo when they die in any pocket dimension").getBoolean(true);
LimboReturnsInventoryEnabled = config.get(Configuration.CATEGORY_GENERAL, "Enable Limbo Returns Inventory", true, LimboReturnsInventoryEnabled = config.get(Configuration.CATEGORY_GENERAL, "Enable Limbo Returns Inventory", true,
"Sets whether players keep their inventories upon dying and respawning in Limbo").getBoolean(true); "Sets whether players keep their inventories upon dying and respawning in Limbo").getBoolean(true);
HardcoreLimboEnabled = config.get(Configuration.CATEGORY_GENERAL, "Enable Hardcore Limbo", false, HardcoreLimboEnabled = config.get(Configuration.CATEGORY_GENERAL, "Enable Hardcore Limbo", false,
"Sets whether players that die in Limbo will respawn there").getBoolean(false); "Sets whether players that die in Limbo will respawn there").getBoolean(false);
LimboEntryRange = config.get(Configuration.CATEGORY_GENERAL, "Limbo Entry Range", 500,
"Sets the farthest distance that players may be moved at random when sent to Limbo. Must be greater than or equal to 0.").getInt();
LimboReturnRange = config.get(Configuration.CATEGORY_GENERAL, "Limbo Return Range", 500, LimboReturnRange = config.get(Configuration.CATEGORY_GENERAL, "Limbo Return Range", 500,
"Sets the farthest distance that Limbo can send you upon returning to the Overworld").getInt(); "Sets the farthest distance that players may be moved at random when sent from Limbo to the Overworld. Must be greater than or equal to 0.").getInt();
DoorRenderingEnabled = config.get(Configuration.CATEGORY_GENERAL, "Enable Door Rendering", true).getBoolean(true); DoorRenderingEnabled = config.get(Configuration.CATEGORY_GENERAL, "Enable Door Rendering", true).getBoolean(true);
TNFREAKINGT_Enabled = config.get(Configuration.CATEGORY_GENERAL, "EXPLOSIONS!!???!!!?!?!!", false).getBoolean(false); TNFREAKINGT_Enabled = config.get(Configuration.CATEGORY_GENERAL, "EXPLOSIONS!!???!!!?!?!!", false).getBoolean(false);
@@ -182,6 +204,8 @@ public class DDProperties
TransientDoorID = config.getBlock("Transient Door Block ID", 1979).getInt(); TransientDoorID = config.getBlock("Transient Door Block ID", 1979).getInt();
GoldenDoorID = config.getBlock("Gold Door Block ID", 1980).getInt(); GoldenDoorID = config.getBlock("Gold Door Block ID", 1980).getInt();
GoldenDimensionalDoorID = config.getBlock("Gold Dim Door Block ID", 1981).getInt(); GoldenDimensionalDoorID = config.getBlock("Gold Dim Door Block ID", 1981).getInt();
QuartzDoorID = config.getBlock("Quartz Door Block ID", 1982).getInt();
PersonalDimDoorID = config.getBlock("Personal Dim Door ID", 1983).getInt();
WarpDoorItemID = config.getItem("Warp Door Item ID", 5670).getInt(); WarpDoorItemID = config.getItem("Warp Door Item ID", 5670).getInt();
RiftRemoverItemID = config.getItem("Rift Remover Item ID", 5671).getInt(); RiftRemoverItemID = config.getItem("Rift Remover Item ID", 5671).getInt();
@@ -194,6 +218,9 @@ public class DDProperties
GoldenDoorItemID = config.getItem("Gold Door Item ID", 5678).getInt(); GoldenDoorItemID = config.getItem("Gold Door Item ID", 5678).getInt();
GoldenDimensionalDoorItemID = config.getItem("Gold Dim Door Item ID", 5679).getInt(); GoldenDimensionalDoorItemID = config.getItem("Gold Dim Door Item ID", 5679).getInt();
WorldThreadItemID = config.getItem("World Thread Item ID", 5680).getInt(); WorldThreadItemID = config.getItem("World Thread Item ID", 5680).getInt();
DDKeyItemID = config.getItem("Rift Key Item ID", 5681).getInt();
ItemQuartzDoorID = config.getItem("Quartz Door Item ID", 5681).getInt();
ItemPersonalDimDoorID = config.getItem("Personal Dim Door ID", 5681).getInt();
LimboBlockID = config.getTerrainBlock("World Generation Block IDs - must be less than 256", "Limbo Block ID", 217, LimboBlockID = config.getTerrainBlock("World Generation Block IDs - must be less than 256", "Limbo Block ID", 217,
"Blocks used for the terrain in Limbo").getInt(); "Blocks used for the terrain in Limbo").getInt();
@@ -201,11 +228,12 @@ public class DDProperties
"Perma Fabric Block ID", 220, "Blocks used for enclosing pocket dimensions").getInt(); "Perma Fabric Block ID", 220, "Blocks used for enclosing pocket dimensions").getInt();
LimboDimensionID = config.get(CATEGORY_DIMENSION, "Limbo Dimension ID", -23).getInt(); LimboDimensionID = config.get(CATEGORY_DIMENSION, "Limbo Dimension ID", -23).getInt();
PocketProviderID = config.get(CATEGORY_PROVIDER, "Pocket Provider ID", 24).getInt(); PocketProviderID = config.get(CATEGORY_PROVIDER, "Pocket Provider ID", 124).getInt();
LimboProviderID = config.get(CATEGORY_PROVIDER, "Limbo Provider ID", 13).getInt(); LimboProviderID = config.get(CATEGORY_PROVIDER, "Limbo Provider ID", 113).getInt();
PersonalPocketProviderID = config.get(CATEGORY_PROVIDER, "Personal Pocket Provider ID", 125).getInt();
WorldRiftGenerationEnabled = config.get(Configuration.CATEGORY_GENERAL, "Enable Rift World Generation", true, MonolithTeleportationEnabled = config.get(Configuration.CATEGORY_GENERAL, "Enable Monolith Teleportation", true,
"Sets whether dungeon rifts generate in dimensions other than Limbo").getBoolean(true); "Sets whether Monoliths can teleport players").getBoolean(true);
MonolithSpawningChance = config.get(Configuration.CATEGORY_GENERAL, "Monolith Spawning Chance", 28, MonolithSpawningChance = config.get(Configuration.CATEGORY_GENERAL, "Monolith Spawning Chance", 28,
"Sets the chance (out of " + CustomLimboPopulator.MAX_MONOLITH_SPAWNING_CHANCE + ") that Monoliths will " + "Sets the chance (out of " + CustomLimboPopulator.MAX_MONOLITH_SPAWNING_CHANCE + ") that Monoliths will " +
@@ -223,8 +251,12 @@ public class DDProperties
"Sets the chance (out of " + DDStructureNetherBridgeStart.MAX_GATEWAY_GENERATION_CHANCE + ") that a Rift Gateway will " + "Sets the chance (out of " + DDStructureNetherBridgeStart.MAX_GATEWAY_GENERATION_CHANCE + ") that a Rift Gateway will " +
"generate as part of a Nether Fortress. The default chance is 33.").getInt(); "generate as part of a Nether Fortress. The default chance is 33.").getInt();
LimboBiomeID = config.get(CATEGORY_BIOME, "Limbo Biome ID", 251).getInt(); WorldThreadDropChance = config.get(Configuration.CATEGORY_GENERAL, "World Thread Drop Chance", 50,
PocketBiomeID = config.get(CATEGORY_BIOME, "Pocket Biome ID", 250).getInt(); "Sets the chance (out of " + BlockRift.MAX_WORLD_THREAD_DROP_CHANCE + ") that a rift will " +
"drop World Thread when it destroys a block. The default chance is 50.").getInt();
LimboBiomeID = config.get(CATEGORY_BIOME, "Limbo Biome ID", 148).getInt();
PocketBiomeID = config.get(CATEGORY_BIOME, "Pocket Biome ID", 149).getInt();
config.save(); config.save();

View File

@@ -0,0 +1,84 @@
package StevenDimDoors.mod_pocketDim.config;
import java.io.File;
import net.minecraftforge.common.Configuration;
public class DDWorldProperties
{
/**
* World Generation Settings
*/
public final DimensionFilter RiftClusterDimensions;
public final DimensionFilter RiftGatewayDimensions;
/**
* General Flags
*/
public final boolean LimboEscapeEnabled;
public final boolean UniversalLimboEnabled;
//Names of categories
private static final String CATEGORY_WORLD_GENERATION = "world generation";
public DDWorldProperties(File configFile)
{
// TODO: For the next major update (e.g. to MC 1.7), please move all world-specific settings
// into this config file instead of using the global ID file.
Configuration config = new Configuration(configFile);
config.load();
config.addCustomCategoryComment(CATEGORY_WORLD_GENERATION,
"The following settings require lists of dimensions in a specific format. " +
"A list must consist of ranges separated by commas. A range may be a single number to indicate " +
"just one dimension or two numbers in the form \"X - Y\". Spaces are permitted " +
"but not required. Example: -100, -10 - -1, 20 - 30");
RiftClusterDimensions = loadFilter(config, "Rift Cluster", "Rift Clusters");
RiftGatewayDimensions = loadFilter(config, "Rift Gateway", "Rift Gateways");
LimboEscapeEnabled = config.get(Configuration.CATEGORY_GENERAL, "Enable Limbo Escape", true,
"Sets whether players are teleported out of Limbo when walking over the Eternal Fabric that " +
"generates near the bottom of the dimension. If disabled, players could still leave through " +
"dungeons in Limbo or by dying (if Hardcore Limbo is disabled). The default value is true.").getBoolean(true);
UniversalLimboEnabled = config.get(Configuration.CATEGORY_GENERAL, "Enable Universal Limbo", false,
"Sets whether players are teleported to Limbo when they die in any dimension (except Limbo). " +
"Normally, players only go to Limbo if they die in a pocket dimension. This setting will not " +
"affect deaths in Limbo, which can be set with the Hardcore Limbo option. " +
"The default value is false.").getBoolean(false);
config.save();
}
private static DimensionFilter loadFilter(Configuration config, String prefix, String description)
{
boolean enableBlacklist = config.get(CATEGORY_WORLD_GENERATION, "Enable " + prefix + " Blacklist", true,
"Sets whether " + description + " will not generate in certain blacklisted dimensions. " +
"If set to false, then " + description + " will follow a whitelist instead.").getBoolean(true);
String whitelist = config.get(CATEGORY_WORLD_GENERATION, prefix + " Whitelist", "",
"A list of the only dimensions in which " + description + " may generate.").getString();
String blacklist = config.get(CATEGORY_WORLD_GENERATION, prefix + " Blacklist", "",
"A list of dimensions in which " + description + " may not generate.").getString();
try
{
if (enableBlacklist)
{
return DimensionFilter.parseBlacklist(blacklist);
}
else
{
return DimensionFilter.parseWhitelist(whitelist);
}
}
catch (Exception inner)
{
throw new RuntimeException("An error occurred while loading a whitelist or blacklist setting for " +
description + ". Please make sure that your configuration file is set up correctly.", inner);
}
}
}

View File

@@ -0,0 +1,93 @@
package StevenDimDoors.mod_pocketDim.config;
import com.google.common.collect.Range;
import com.google.common.collect.RangeSet;
import com.google.common.collect.TreeRangeSet;
public class DimensionFilter
{
private RangeSet<Integer> blacklist;
private DimensionFilter(RangeSet<Integer> blacklist)
{
this.blacklist = blacklist;
}
public boolean isAccepted(int dimensionID)
{
return !blacklist.contains(dimensionID);
}
public boolean isRejected(int dimensionID)
{
return blacklist.contains(dimensionID);
}
private static RangeSet<Integer> parseRangeSet(String list)
{
int index;
int start;
int end;
String startPart;
String endPart;
String[] intervals;
RangeSet<Integer> ranges = TreeRangeSet.create();
// Strip out all whitespace characters
list = list.replaceAll("\\s", "");
if (list.isEmpty())
{
return ranges;
}
intervals = list.split(",");
// Iterate over all the interval strings
for (String interval : intervals)
{
// Check if the interval contains a minus sign after the first character
// That indicates that we're dealing with an interval and not a single number
if (interval.length() > 1)
{
index = interval.indexOf("-", 1);
}
else
{
index = -1;
}
try
{
if (index >= 0)
{
// Parse this as a range with two values as endpoints
startPart = interval.substring(0, index);
endPart = interval.substring(index + 1);
start = Integer.parseInt(startPart);
end = Integer.parseInt(endPart);
}
else
{
// Parse this as a single value
start = Integer.parseInt(interval);
end = start;
}
// Add the interval to the set of intervals
ranges.add( Range.closed(start, end) );
}
catch (Exception e)
{
throw new IllegalArgumentException("\"" + interval + "\" is not a valid value or range for dimension IDs");
}
}
return ranges;
}
public static DimensionFilter parseWhitelist(String list)
{
return new DimensionFilter(parseRangeSet(list).complement());
}
public static DimensionFilter parseBlacklist(String list)
{
return new DimensionFilter(parseRangeSet(list));
}
}

View File

@@ -0,0 +1,169 @@
package StevenDimDoors.mod_pocketDim.core;
import java.io.IOException;
import com.google.gson.stream.JsonReader;
import StevenDimDoors.mod_pocketDim.items.ItemDDKey;
import StevenDimDoors.mod_pocketDim.saving.IPackable;
import StevenDimDoors.mod_pocketDim.saving.PackedDimData;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagIntArray;
import net.minecraft.nbt.NBTTagList;
public class DDLock
{
private boolean lockState;
private final int lockKey;
public DDLock(boolean isLocked, int lockKey)
{
this.lockState = isLocked;
this.lockKey = lockKey;
}
public int getLockKey()
{
return this.lockKey;
}
/**
* See if the lock is currently locked. False if there is no lock.
* @return
*/
public boolean getLockState()
{
return this.lockState;
}
/**
* set the state of the lock. Returns false if there is no lock to set,
* otherwise returns true
* @param flag
*/
protected void setLockState(boolean flag)
{
this.lockState = flag;
}
/**
* see if we could unlock this door if it where locked.
* @param link
* @param itemStack
* @return
*/
public boolean doesKeyUnlock(ItemStack itemStack)
{
for(int key :getKeys(itemStack))
{
if(this.lockKey == key)
{
return true;
}
}
return false;
}
/**
* Tries to open this lock
* @param item
* @return
*/
public boolean tryToOpen(ItemStack itemStack)
{
return (!this.lockState)||this.doesKeyUnlock(itemStack);
}
/**
* sets the key/s to the given key/s
* @return
* @return
*/
/**
* gets all the keys stored on a single key item
* @return
*/
public static int[] getKeys(ItemStack itemStack)
{
if (!itemStack.hasTagCompound())
{
initNBTTags(itemStack);
}
return itemStack.getTagCompound().getIntArray("DDKeys");
}
/**
* adds the key/s to the given key
* @return
* @return
*/
public static void addKeys(ItemStack itemStack, int[] keysToAdd)
{
int[] oldKeys = DDLock.getKeys(itemStack);
int[] newKeys = new int[keysToAdd.length+oldKeys.length];
System.arraycopy(oldKeys, 0, newKeys, 0, oldKeys.length);
System.arraycopy(keysToAdd, 0, newKeys, oldKeys.length, keysToAdd.length);
setKeys(itemStack,newKeys);
}
/**
* sets the key/s to the given key/s
* @return
* @return
*/
public static void setKeys(ItemStack itemStack, int[] keys)
{
if (!itemStack.hasTagCompound())
{
initNBTTags(itemStack);
}
NBTTagCompound tag = itemStack.getTagCompound();
tag.setIntArray("DDKeys", keys);
itemStack.setTagCompound(tag);
}
/**
* Gives the key a new NBTTag
* @param itemStack
*/
public static void initNBTTags(ItemStack itemStack)
{
itemStack.setTagCompound(new NBTTagCompound());
NBTTagCompound tag = itemStack.getTagCompound();
tag.setIntArray("DDKeys", new int[0]);
tag.setBoolean("HasCreatedLock", false);
itemStack.setTagCompound(tag);
}
public static boolean hasCreatedLock(ItemStack key)
{
if(isItemKey(key))
{
if(key.hasTagCompound())
{
return key.getTagCompound().getBoolean("HasCreatedLock");
}
initNBTTags(key);
}
return false;
}
public static boolean isItemKey(ItemStack key)
{
return key.getItem() instanceof ItemDDKey;
}
protected static DDLock generateLockKeyPair(ItemStack itemStack, int lockKey2)
{
itemStack.getTagCompound().setBoolean("HasCreatedLock", true);
DDLock.setKeys(itemStack, new int[]{lockKey2});
return new DDLock(true, lockKey2);
}
}

View File

@@ -2,15 +2,14 @@ package StevenDimDoors.mod_pocketDim.core;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Random; import java.util.Random;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityList; import net.minecraft.entity.EntityList;
import net.minecraft.entity.item.EntityMinecart; import net.minecraft.entity.item.EntityMinecart;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.item.ItemDoor;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.packet.Packet250CustomPayload;
import net.minecraft.network.packet.Packet41EntityEffect; import net.minecraft.network.packet.Packet41EntityEffect;
import net.minecraft.network.packet.Packet43Experience; import net.minecraft.network.packet.Packet43Experience;
import net.minecraft.network.packet.Packet9Respawn; import net.minecraft.network.packet.Packet9Respawn;
@@ -20,15 +19,12 @@ import net.minecraft.util.MathHelper;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraft.world.WorldServer; import net.minecraft.world.WorldServer;
import net.minecraftforge.common.DimensionManager; import net.minecraftforge.common.DimensionManager;
import net.minecraftforge.common.network.ForgePacket;
import net.minecraftforge.common.network.packet.DimensionRegisterPacket;
import StevenDimDoors.mod_pocketDim.DDProperties;
import StevenDimDoors.mod_pocketDim.Point3D; import StevenDimDoors.mod_pocketDim.Point3D;
import StevenDimDoors.mod_pocketDim.mod_pocketDim; import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.blocks.BaseDimDoor; import StevenDimDoors.mod_pocketDim.blocks.BaseDimDoor;
import StevenDimDoors.mod_pocketDim.blocks.IDimDoor;
import StevenDimDoors.mod_pocketDim.config.DDProperties;
import StevenDimDoors.mod_pocketDim.helpers.yCoordHelper; import StevenDimDoors.mod_pocketDim.helpers.yCoordHelper;
import StevenDimDoors.mod_pocketDim.items.BaseItemDoor;
import StevenDimDoors.mod_pocketDim.items.ItemDimensionalDoor;
import StevenDimDoors.mod_pocketDim.schematic.BlockRotator; import StevenDimDoors.mod_pocketDim.schematic.BlockRotator;
import StevenDimDoors.mod_pocketDim.tileentities.TileEntityDimDoor; import StevenDimDoors.mod_pocketDim.tileentities.TileEntityDimDoor;
import StevenDimDoors.mod_pocketDim.util.Point4D; import StevenDimDoors.mod_pocketDim.util.Point4D;
@@ -40,52 +36,46 @@ public class DDTeleporter
{ {
private static final Random random = new Random(); private static final Random random = new Random();
private static final int NETHER_DIMENSION_ID = -1; private static final int NETHER_DIMENSION_ID = -1;
private static final int OVERWORLD_DIMENSION_ID = 0;
private static final int END_DIMENSION_ID = 1; private static final int END_DIMENSION_ID = 1;
private static final int MAX_NETHER_EXIT_CHANCE = 100; private static final int MAX_NETHER_EXIT_CHANCE = 100;
private static final int NETHER_EXIT_CHANCE = 20; //20% chance to compensate for frequent exit failures - the Nether often doesn't have enough space for an exit private static final int NETHER_EXIT_CHANCE = 20; //20% chance to compensate for frequent exit failures - the Nether often doesn't have enough space for an exit
private static final int MAX_OVERWORLD_EXIT_CHANCE = 100;
private static final int OVERWORLD_EXIT_CHANCE = 15;
private static final int MAX_ROOT_SHIFT_CHANCE = 100; private static final int MAX_ROOT_SHIFT_CHANCE = 100;
private static final int START_ROOT_SHIFT_CHANCE = 0; private static final int START_ROOT_SHIFT_CHANCE = 0;
private static final int ROOT_SHIFT_CHANCE_PER_LEVEL = 5; private static final int ROOT_SHIFT_CHANCE_PER_LEVEL = 5;
private static final String SPIRIT_WORLD_NAME = "Spirit World";
public static int cooldown = 0; public static int cooldown = 0;
private DDTeleporter() { } private DDTeleporter() { }
/**Checks if the destination supplied is valid, ie, filled by any non-replaceable block. /**
* * Checks if the destination supplied is safe (i.e. filled by any replaceable or non-opaque blocks)
* @param entity
* @param world
* @param destination
* @param properties
* @return
*/ */
private static boolean checkDestination(Entity entity, WorldServer world, Point4D destination,DDProperties properties) private static boolean checkDestination(WorldServer world, Point4D destination, int orientation)
{ {
int x = destination.getX(); int x = destination.getX();
int y = destination.getY(); int y = destination.getY();
int z = destination.getZ(); int z = destination.getZ();
int blockIDTop; int blockIDTop;
int blockIDBottom; int blockIDBottom;
Point3D point; Point3D point;
int orientation;
orientation = getDestinationOrientation(destination, properties);
entity.rotationYaw = (orientation * 90) + 90;
switch (orientation) switch (orientation)
{ {
case 0: case 0:
point = new Point3D(MathHelper.floor_double(x - 0.5), y - 1, MathHelper.floor_double(z + 0.5)); point = new Point3D(x - 1, y - 1, z);
break; break;
case 1: case 1:
point = new Point3D(MathHelper.floor_double(x + 0.5), y - 1, MathHelper.floor_double(z - 0.5)); point = new Point3D(x, y - 1, z - 1);
break; break;
case 2: case 2:
point = new Point3D(MathHelper.floor_double(x + 1.5), y - 1, MathHelper.floor_double(z + 0.5)); point = new Point3D(x + 1, y - 1, z);
break; break;
case 3: case 3:
point = new Point3D(MathHelper.floor_double(x + 0.5), y - 1, MathHelper.floor_double(z + 1.5)); point = new Point3D(x, y - 1, z + 1);
break; break;
default: default:
point = new Point3D(x, y - 1, z); point = new Point3D(x, y - 1, z);
@@ -129,35 +119,11 @@ public class DDTeleporter
orientation = -1; orientation = -1;
} }
if (!checkDestination(entity, world, destination, properties)) if (entity instanceof EntityPlayer)
{
if (entity instanceof EntityPlayerMP)
{ {
EntityPlayer player = (EntityPlayer) entity; EntityPlayer player = (EntityPlayer) entity;
player.rotationYaw = (orientation * 90) + 90; if (checkDestination(world, destination, orientation))
switch (orientation)
{ {
case 0:
player.setPositionAndUpdate(x + 0.5, y - 1, z + 0.5);
break;
case 1:
player.setPositionAndUpdate(x + 0.5, y - 1, z + 0.5);
break;
case 2:
player.setPositionAndUpdate(x + 0.5, y - 1, z + 0.5);
break;
case 3:
player.setPositionAndUpdate(x + 0.5, y - 1, z + 0.5);
break;
default:
player.setPositionAndUpdate(x, y - 1, z);
break;
}
}
}
else if (entity instanceof EntityPlayer)
{
EntityPlayer player = (EntityPlayer) entity;
switch (orientation) switch (orientation)
{ {
case 0: case 0:
@@ -177,6 +143,11 @@ public class DDTeleporter
break; break;
} }
} }
else
{
player.setPositionAndUpdate(x + 0.5, y - 1, z + 0.5);
}
}
else if (entity instanceof EntityMinecart) else if (entity instanceof EntityMinecart)
{ {
entity.motionX = 0; entity.motionX = 0;
@@ -250,15 +221,14 @@ public class DDTeleporter
} }
//Check if the block below that point is actually a door //Check if the block below that point is actually a door
int blockID = world.getBlockId(door.getX(), door.getY() - 1, door.getZ()); Block block = Block.blocksList[world.getBlockId(door.getX(), door.getY() - 1, door.getZ())];
if (blockID != properties.DimensionalDoorID && blockID != properties.WarpDoorID && if (block==null || !(block instanceof IDimDoor))
blockID != properties.TransientDoorID && blockID != properties.UnstableDoorID
&& blockID != properties.GoldenDimensionalDoorID)
{ {
//Return the pocket's orientation instead //Return the pocket's orientation instead
return PocketManager.getDimensionData(door.getDimension()).orientation(); return PocketManager.createDimensionData(world).orientation();
} }
//Return the orientation portion of its metadata //Return the orientation portion of its metadata
return world.getBlockMetadata(door.getX(), door.getY() - 1, door.getZ()) & 3; return world.getBlockMetadata(door.getX(), door.getY() - 1, door.getZ()) & 3;
} }
@@ -323,7 +293,7 @@ public class DDTeleporter
// to prevent us from doing bad things. Moreover, no dimension is being created, so if we ever // to prevent us from doing bad things. Moreover, no dimension is being created, so if we ever
// tie code to that, it could cause confusing bugs. // tie code to that, it could cause confusing bugs.
// No hacky for you! ~SenseiKiwi // No hacky for you! ~SenseiKiwi
PocketManager.getDimwatcher().onCreated(new ClientDimData(PocketManager.getDimensionData(destination.getDimension()))); PocketManager.getDimwatcher().onCreated(new ClientDimData(PocketManager.createDimensionData(newWorld)));
// Set the new dimension and inform the client that it's moving to a new world. // Set the new dimension and inform the client that it's moving to a new world.
player.dimension = destination.getDimension(); player.dimension = destination.getDimension();
@@ -457,11 +427,11 @@ public class DDTeleporter
return; return;
} }
if (!initializeDestination(link, DDProperties.instance(),door)) if (!initializeDestination(link, DDProperties.instance(),entity,door))
{ {
return; return;
} }
if (link.linkType() == LinkTypes.RANDOM) if (link.linkType() == LinkType.RANDOM)
{ {
Point4D randomDestination = getRandomDestination(); Point4D randomDestination = getRandomDestination();
if (randomDestination != null) if (randomDestination != null)
@@ -473,18 +443,43 @@ public class DDTeleporter
else else
{ {
buildExitDoor(door, link, DDProperties.instance()); buildExitDoor(door, link, DDProperties.instance());
entity = teleportEntity(entity, link.destination(), link.linkType() != LinkTypes.UNSAFE_EXIT); entity = teleportEntity(entity, link.destination(), link.linkType() != LinkType.UNSAFE_EXIT);
entity.worldObj.playSoundEffect(entity.posX, entity.posY, entity.posZ, "mob.endermen.portal", 1.0F, 1.0F); entity.worldObj.playSoundEffect(entity.posX, entity.posY, entity.posZ, "mob.endermen.portal", 1.0F, 1.0F);
} }
} }
private static boolean initializeDestination(DimLink link, DDProperties properties, Block door) private static boolean initializeDestination(DimLink link, DDProperties properties, Entity entity, Block door)
{ {
if (link.hasDestination()) if (link.hasDestination()&&link.linkType()!=LinkType.PERSONAL)
{ {
if (PocketManager.isBlackListed(link.destination().getDimension())) if (PocketManager.isBlackListed(link.destination().getDimension()))
{ {
link=PocketManager.getDimensionData(link.source().getDimension()).createLink(link.link.point,LinkTypes.SAFE_EXIT,link.link.orientation);
// This link leads to a dimension that has been blacklisted.
// That means that it was a pocket and it was deleted.
// Depending on the link type, we must overwrite it or cancel
// the teleport operation. We don't need to assign 'link' with
// a different value. NewDimData will overwrite it in-place.
NewDimData start = PocketManager.getDimensionData(link.source().getDimension());
if (link.linkType() == LinkType.DUNGEON)
{
// Ovewrite the link into a dungeon link with no destination
start.createLink(link.source(), LinkType.DUNGEON, link.orientation(), null);
}
else
{
if (start.isPocketDimension())
{
// Ovewrite the link into a safe exit link, because
// this could be the only way out from a pocket.
start.createLink(link.source(), LinkType.SAFE_EXIT, link.orientation(), null);
}
else
{
// Cancel the teleport attempt
return false;
}
}
} }
else else
{ {
@@ -495,25 +490,50 @@ public class DDTeleporter
// Check the destination type and respond accordingly // Check the destination type and respond accordingly
switch (link.linkType()) switch (link.linkType())
{ {
case LinkTypes.DUNGEON: case DUNGEON:
return PocketBuilder.generateNewDungeonPocket(link, properties); return PocketBuilder.generateNewDungeonPocket(link, properties);
case LinkTypes.POCKET: case POCKET:
return PocketBuilder.generateNewPocket(link, properties,door); return PocketBuilder.generateNewPocket(link, properties, door, DimensionType.POCKET);
case LinkTypes.SAFE_EXIT: case PERSONAL:
return setupPersonalLink(link, properties, entity, door);
case SAFE_EXIT:
return generateSafeExit(link, properties); return generateSafeExit(link, properties);
case LinkTypes.DUNGEON_EXIT: case DUNGEON_EXIT:
return generateDungeonExit(link, properties); return generateDungeonExit(link, properties);
case LinkTypes.UNSAFE_EXIT: case UNSAFE_EXIT:
return generateUnsafeExit(link); return generateUnsafeExit(link);
case LinkTypes.NORMAL: case NORMAL:
case LinkTypes.REVERSE: case REVERSE:
case LinkTypes.RANDOM: case RANDOM:
return true; return true;
default: default:
throw new IllegalArgumentException("link has an unrecognized link type."); throw new IllegalArgumentException("link has an unrecognized link type.");
} }
} }
private static boolean setupPersonalLink(DimLink link, DDProperties properties,Entity player, Block door)
{
if(!(player instanceof EntityPlayer))
{
return false;
}
NewDimData dim = PocketManager.getPersonalDimensionForPlayer(player.getEntityName());
if(dim == null)
{
return PocketBuilder.generateNewPersonalPocket(link, properties, player, door);
}
DimLink personalHomeLink = dim.getLink(dim.origin());
if(personalHomeLink!=null)
{
PocketManager.getDimensionData(link.source().getDimension()).setLinkDestination(personalHomeLink, link.source().getX(), link.source().getY(), link.source().getZ());
}
dim.setLinkDestination(link, dim.origin.getX(), dim.origin.getY(), dim.origin.getZ());
return true;
}
private static Point4D getRandomDestination() private static Point4D getRandomDestination()
{ {
// Our aim is to return a random link's source point // Our aim is to return a random link's source point
@@ -531,7 +551,7 @@ public class DDTeleporter
{ {
for (DimLink link : dimension.getAllLinks()) for (DimLink link : dimension.getAllLinks())
{ {
if (link.linkType() != LinkTypes.RANDOM) if (link.linkType() != LinkType.RANDOM)
{ {
matches.add(link.source()); matches.add(link.source());
} }
@@ -543,11 +563,8 @@ public class DDTeleporter
{ {
return matches.get( random.nextInt(matches.size()) ); return matches.get( random.nextInt(matches.size()) );
} }
else
{
return null; return null;
} }
}
private static boolean generateUnsafeExit(DimLink link) private static boolean generateUnsafeExit(DimLink link)
{ {
@@ -560,7 +577,8 @@ public class DDTeleporter
// To avoid loops, don't generate a destination if the player is // To avoid loops, don't generate a destination if the player is
// already in a non-pocket dimension. // already in a non-pocket dimension.
NewDimData current = PocketManager.getDimensionData(link.link.point.getDimension()); NewDimData current = PocketManager.getDimensionData(link.point.getDimension());
if (current.isPocketDimension()) if (current.isPocketDimension())
{ {
Point4D source = link.source(); Point4D source = link.source();
@@ -573,7 +591,7 @@ public class DDTeleporter
Point3D destination = yCoordHelper.findDropPoint(world, source.getX(), source.getY() + 1, source.getZ()); Point3D destination = yCoordHelper.findDropPoint(world, source.getX(), source.getY() + 1, source.getZ());
if (destination != null) if (destination != null)
{ {
current.root().setDestination(link, destination.getX(), destination.getY(), destination.getZ()); current.root().setLinkDestination(link, destination.getX(), destination.getY(), destination.getZ());
return true; return true;
} }
} }
@@ -584,7 +602,7 @@ public class DDTeleporter
{ {
World startWorld = PocketManager.loadDimension(link.source().getDimension()); World startWorld = PocketManager.loadDimension(link.source().getDimension());
World destWorld = PocketManager.loadDimension(link.destination().getDimension()); World destWorld = PocketManager.loadDimension(link.destination().getDimension());
TileEntity doorTE = startWorld.getBlockTileEntity(link.source().getX(), link.source().getY(), link.link.point.getZ()); TileEntity doorTE = startWorld.getBlockTileEntity(link.source().getX(), link.source().getY(), link.point.getZ());
if(doorTE instanceof TileEntityDimDoor) if(doorTE instanceof TileEntityDimDoor)
{ {
if((TileEntityDimDoor.class.cast(doorTE).hasGennedPair)) if((TileEntityDimDoor.class.cast(doorTE).hasGennedPair))
@@ -602,7 +620,7 @@ public class DDTeleporter
} }
} }
BaseItemDoor.placeDoorBlock(destWorld, link.destination().getX(), link.destination().getY()-1, link.destination().getZ(),link.getDestinationOrientation(), door); ItemDoor.placeDoorBlock(destWorld, link.destination().getX(), link.destination().getY()-1, link.destination().getZ(),link.getDestinationOrientation(), door);
TileEntity doorDestTE = ((BaseDimDoor)door).initDoorTE(destWorld, link.destination().getX(), link.destination().getY(), link.destination().getZ()); TileEntity doorDestTE = ((BaseDimDoor)door).initDoorTE(destWorld, link.destination().getX(), link.destination().getY(), link.destination().getZ());
@@ -614,9 +632,10 @@ public class DDTeleporter
} }
} }
} }
private static boolean generateSafeExit(DimLink link, DDProperties properties) private static boolean generateSafeExit(DimLink link, DDProperties properties)
{ {
NewDimData current = PocketManager.getDimensionData(link.link.point.getDimension()); NewDimData current = PocketManager.getDimensionData(link.point.getDimension());
return generateSafeExit(current.root(), link, properties); return generateSafeExit(current.root(), link, properties);
} }
@@ -627,22 +646,25 @@ public class DDTeleporter
// There is a chance of choosing the Nether first before other root dimensions // There is a chance of choosing the Nether first before other root dimensions
// to compensate for servers with many Mystcraft ages or other worlds. // to compensate for servers with many Mystcraft ages or other worlds.
NewDimData current = PocketManager.getDimensionData(link.link.point.getDimension()); NewDimData current = PocketManager.getDimensionData(link.point.getDimension());
ArrayList<NewDimData> roots = PocketManager.getRootDimensions(); ArrayList<NewDimData> roots = PocketManager.getRootDimensions();
int shiftChance = START_ROOT_SHIFT_CHANCE + ROOT_SHIFT_CHANCE_PER_LEVEL * (current.packDepth() - 1); int shiftChance = START_ROOT_SHIFT_CHANCE + ROOT_SHIFT_CHANCE_PER_LEVEL * (current.packDepth() - 1);
if (random.nextInt(MAX_ROOT_SHIFT_CHANCE) < shiftChance) if (random.nextInt(MAX_ROOT_SHIFT_CHANCE) < shiftChance)
{ {
if (random.nextInt(MAX_NETHER_EXIT_CHANCE) < NETHER_EXIT_CHANCE) if (current.root().id() != OVERWORLD_DIMENSION_ID && random.nextInt(MAX_OVERWORLD_EXIT_CHANCE) < OVERWORLD_EXIT_CHANCE)
{ {
return generateSafeExit(PocketManager.getDimensionData(NETHER_DIMENSION_ID), link, properties); return generateSafeExit(PocketManager.createDimensionDataDangerously(OVERWORLD_DIMENSION_ID), link, properties);
}
if (current.root().id() != NETHER_DIMENSION_ID && random.nextInt(MAX_NETHER_EXIT_CHANCE) < NETHER_EXIT_CHANCE)
{
return generateSafeExit(PocketManager.createDimensionDataDangerously(NETHER_DIMENSION_ID), link, properties);
} }
for (int attempts = 0; attempts < 10; attempts++) for (int attempts = 0; attempts < 10; attempts++)
{ {
NewDimData selection = roots.get( random.nextInt(roots.size()) ); NewDimData selection = roots.get( random.nextInt(roots.size()) );
if (selection.id() != END_DIMENSION_ID && if (selection != current.root() && isValidForDungeonExit(selection, properties))
selection.id() != properties.LimboDimensionID &&
selection != current.root())
{ {
return generateSafeExit(selection, link, properties); return generateSafeExit(selection, link, properties);
} }
@@ -653,6 +675,19 @@ public class DDTeleporter
return generateSafeExit(current.root(), link, properties); return generateSafeExit(current.root(), link, properties);
} }
private static boolean isValidForDungeonExit(NewDimData destination, DDProperties properties)
{
// Prevent exits to The End and Limbo
if (destination.id() == END_DIMENSION_ID || destination.id() == properties.LimboDimensionID)
{
return false;
}
// Prevent exits to Witchery's Spirit World; we need to load the dimension to retrieve its name.
// This is okay because the dimension would have to be loaded subsequently by generateSafeExit().
World world = PocketManager.loadDimension(destination.id());
return (world != null && !SPIRIT_WORLD_NAME.equals(world.provider.getDimensionName()));
}
private static boolean generateSafeExit(NewDimData destinationDim, DimLink link, DDProperties properties) private static boolean generateSafeExit(NewDimData destinationDim, DimLink link, DDProperties properties)
{ {
// A safe exit attempts to place a Warp Door in a dimension with // A safe exit attempts to place a Warp Door in a dimension with
@@ -728,16 +763,17 @@ public class DDTeleporter
// Create a reverse link for returning // Create a reverse link for returning
int orientation = getDestinationOrientation(source, properties); int orientation = getDestinationOrientation(source, properties);
NewDimData sourceDim = PocketManager.getDimensionData(link.source().getDimension()); NewDimData sourceDim = PocketManager.getDimensionData(link.source().getDimension());
DimLink reverse = destinationDim.createLink(x, y + 2, z, LinkTypes.REVERSE,orientation); DimLink reverse = destinationDim.createLink(x, y + 2, z, LinkType.REVERSE,orientation);
sourceDim.setDestination(reverse, source.getX(), source.getY(), source.getZ());
sourceDim.setLinkDestination(reverse, source.getX(), source.getY(), source.getZ());
// Set up the warp door at the destination // Set up the warp door at the destination
orientation = BlockRotator.transformMetadata(orientation, 2, properties.WarpDoorID); orientation = BlockRotator.transformMetadata(orientation, 2, properties.WarpDoorID);
ItemDimensionalDoor.placeDoorBlock(world, x, y + 1, z, orientation, mod_pocketDim.warpDoor); ItemDoor.placeDoorBlock(world, x, y + 1, z, orientation, mod_pocketDim.warpDoor);
// Complete the link to the destination // Complete the link to the destination
// This comes last so the destination isn't set unless everything else works first // This comes last so the destination isn't set unless everything else works first
destinationDim.setDestination(link, x, y + 2, z); destinationDim.setLinkDestination(link, x, y + 2, z);
} }
return (destination != null); return (destination != null);

View File

@@ -2,73 +2,99 @@ package StevenDimDoors.mod_pocketDim.core;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import net.minecraft.item.ItemStack;
import net.minecraft.world.ChunkCoordIntPair;
import StevenDimDoors.mod_pocketDim.util.Point4D; import StevenDimDoors.mod_pocketDim.util.Point4D;
import StevenDimDoors.mod_pocketDim.watcher.ClientLinkData;
public abstract class DimLink public abstract class DimLink
{ {
protected ClientLinkData link; protected Point4D point;
protected int orientation;
protected DDLock lock;
protected DimLink parent; protected DimLink parent;
protected LinkTail tail; protected LinkTail tail;
protected List<DimLink> children; protected List<DimLink> children;
protected DimLink(ClientLinkData link, DimLink parent) protected DimLink(Point4D point, int orientation, DDLock lock, DimLink parent)
{ {
if (parent.link.point.getDimension() != link.point.getDimension()) if (parent.point.getDimension() != point.getDimension())
{ {
// Ban having children in other dimensions to avoid serialization issues with cross-dimensional tails // Ban having children in other dimensions to avoid serialization issues with cross-dimensional tails
throw new IllegalArgumentException("source and parent.source must have the same dimension."); throw new IllegalArgumentException("source and parent.source must have the same dimension.");
} }
this.lock = lock;
this.parent = parent; this.parent = parent;
this.link = link; this.point = point;
this.tail = parent.tail; this.tail = parent.tail;
this.orientation = orientation;
this.children = new LinkedList<DimLink>(); this.children = new LinkedList<DimLink>();
parent.children.add(this); parent.children.add(this);
} }
protected DimLink(ClientLinkData link, int linkType) protected DimLink(Point4D point, int orientation, DDLock lock, LinkType linkType)
{ {
/**This really cant happen anymore, I guess.
*
if ((linkType < LinkTypes.ENUM_MIN || linkType > LinkTypes.ENUM_MAX) && linkType != LinkTypes.CLIENT_SIDE) if ((linkType < LinkTypes.ENUM_MIN || linkType > LinkTypes.ENUM_MAX) && linkType != LinkTypes.CLIENT_SIDE)
{ {
throw new IllegalArgumentException("The specified link type is invalid."); throw new IllegalArgumentException("The specified link type is invalid.");
} }
**/
this.lock = lock;
this.parent = null; this.parent = null;
this.link = link; this.point = point;
this.orientation = orientation;
this.tail = new LinkTail(linkType, null); this.tail = new LinkTail(linkType, null);
this.children = new LinkedList<DimLink>(); this.children = new LinkedList<DimLink>();
} }
public Point4D source() public Point4D source()
{ {
return link.point; return point;
}
public void clear()
{
//Release children
for (DimLink child : children)
{
child.parent = null;
}
children.clear();
//Release parent
if (parent != null)
{
parent.children.remove(this);
}
parent = null;
point = null;
tail = new LinkTail(LinkType.NORMAL, null);
} }
public int orientation() public int orientation()
{ {
return link.orientation; return orientation;
}
public ClientLinkData link()
{
return link;
} }
public Point4D destination() public Point4D destination()
{ {
return tail.getDestination(); return tail.getDestination();
} }
public int getDestinationOrientation() public int getDestinationOrientation()
{ {
DimLink link = PocketManager.getLink(this.destination().getX(), this.destination().getY(), this.destination().getZ(), this.destination().getDimension()); DimLink destinationLink = PocketManager.getLink(tail.getDestination());
if(link !=null) if (destinationLink != null)
{ {
return link.orientation(); return destinationLink.orientation();
} }
return (this.orientation()+2)%4; return (orientation + 2) % 4;
} }
public boolean hasDestination() public boolean hasDestination()
{ {
return (tail.getDestination() != null); return (tail.getDestination() != null);
@@ -89,13 +115,65 @@ public abstract class DimLink
return parent; return parent;
} }
public int linkType() public LinkType linkType()
{ {
return tail.getLinkType(); return tail.getLinkType();
} }
/**
* Tries to open this lock. Returns true if the lock is open or if the key can open it
* @return
*/
public boolean tryToOpen(ItemStack item)
{
return lock.tryToOpen(item);
}
/**
* Tests if the given key item fits this lock
* @return
*/
public boolean doesKeyUnlock(ItemStack item)
{
return lock.doesKeyUnlock(item);
}
/**
* test if there is a lock, regardless if it is locked or not.
* @return
*/
public boolean hasLock()
{
return this.lock!=null;
}
/**
* Tests if the lock is open or not
*
*/
public boolean getLockState()
{
return this.hasLock()&&this.lock.getLockState();
}
/**
* gets the actual lock object
* @return
*/
public DDLock getLock()
{
return this.lock;
}
public ChunkCoordIntPair getChunkCoordinates()
{
return new ChunkCoordIntPair(point.getX() >> 4, point.getZ() >> 4);
}
@Override
public String toString() public String toString()
{ {
return link.point + " -> " + (hasDestination() ? destination() : ""); return point + " -> " + (hasDestination() ? destination() : "()");
} }
} }

View File

@@ -0,0 +1,41 @@
package StevenDimDoors.mod_pocketDim.core;
public enum DimensionType
{
// WARNING: Don't modify these values carelessly or you'll risk breaking existing worlds!
ROOT(0,false),
POCKET(1,true),
DUNGEON(2,true),
PERSONAL(3,true);
DimensionType(int index, boolean isPocket)
{
this.index = index;
this.isPocket = isPocket;
}
public final int index;
public final boolean isPocket;
/**
* Get the DimensionType given an index. I feel like there should be a better way to do this.
* @param index
* @return
*/
public static DimensionType getTypeFromIndex(int index)
{
for(DimensionType type : DimensionType.values())
{
if(type.index == index)
{
return type;
}
}
return null;
}
public boolean isPocketDimension()
{
return this.isPocket;
}
}

View File

@@ -2,5 +2,5 @@ package StevenDimDoors.mod_pocketDim.core;
public interface IDimRegistrationCallback public interface IDimRegistrationCallback
{ {
public NewDimData registerDimension(int dimensionID, int rootID); public NewDimData registerDimension(int dimensionID, int rootID, DimensionType type);
} }

View File

@@ -5,9 +5,9 @@ import StevenDimDoors.mod_pocketDim.util.Point4D;
class LinkTail class LinkTail
{ {
private Point4D destination; private Point4D destination;
private int linkType; private LinkType linkType;
public LinkTail(int linkType, Point4D destination) public LinkTail(LinkType linkType, Point4D destination)
{ {
this.linkType = linkType; this.linkType = linkType;
this.destination = destination; this.destination = destination;
@@ -21,12 +21,11 @@ class LinkTail
this.destination = destination; this.destination = destination;
} }
public int getLinkType() { public LinkType getLinkType() {
return linkType; return linkType;
} }
public void setLinkType(int linkType) { public void setLinkType(LinkType linkType) {
this.linkType = linkType; this.linkType = linkType;
} }
} }

View File

@@ -0,0 +1,42 @@
package StevenDimDoors.mod_pocketDim.core;
import java.util.HashMap;
public enum LinkType
{
// WARNING: Don't modify these values carelessly or you'll risk breaking links in existing worlds!
NORMAL(0),
POCKET(1),
DUNGEON(2),
RANDOM(3),
DUNGEON_EXIT(4),
SAFE_EXIT(5),
UNSAFE_EXIT(6),
REVERSE(7),
PERSONAL(8),
CLIENT(-1337);
LinkType(int index)
{
this.index = index;
}
public final int index;
/**
* Get the LinkType given an index. I feel like there should be a better way to do this.
* @param index
* @return
*/
public static LinkType getLinkTypeFromIndex(int index)
{
for(LinkType type : LinkType.values())
{
if(type.index == index)
{
return type;
}
}
return null;
}
}

View File

@@ -1,21 +0,0 @@
package StevenDimDoors.mod_pocketDim.core;
public class LinkTypes
{
private LinkTypes() { }
public static final int ENUM_MIN = 0;
public static final int ENUM_MAX = 7;
public static final int CLIENT_SIDE = -1337;
// WARNING: Don't modify these values carelessly or you'll risk breaking links in existing worlds!
public static final int NORMAL = 0;
public static final int POCKET = 1;
public static final int DUNGEON = 2;
public static final int RANDOM = 3;
public static final int DUNGEON_EXIT = 4;
public static final int SAFE_EXIT = 5;
public static final int UNSAFE_EXIT = 6;
public static final int REVERSE = 7;
}

View File

@@ -1,33 +1,42 @@
package StevenDimDoors.mod_pocketDim.core; package StevenDimDoors.mod_pocketDim.core;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Random; import java.util.Random;
import java.util.Stack;
import java.util.TreeMap; import java.util.TreeMap;
import StevenDimDoors.mod_pocketDim.watcher.ClientLinkData; import StevenDimDoors.mod_pocketDim.watcher.ClientLinkData;
import net.minecraft.item.ItemStack;
import net.minecraft.world.ChunkCoordIntPair;
import net.minecraft.world.World; import net.minecraft.world.World;
import StevenDimDoors.mod_pocketDim.DDProperties;
import StevenDimDoors.mod_pocketDim.Point3D; import StevenDimDoors.mod_pocketDim.Point3D;
import StevenDimDoors.mod_pocketDim.config.DDProperties;
import StevenDimDoors.mod_pocketDim.dungeon.DungeonData; import StevenDimDoors.mod_pocketDim.dungeon.DungeonData;
import StevenDimDoors.mod_pocketDim.dungeon.pack.DungeonPack; import StevenDimDoors.mod_pocketDim.dungeon.pack.DungeonPack;
import StevenDimDoors.mod_pocketDim.saving.IPackable;
import StevenDimDoors.mod_pocketDim.saving.PackedDimData;
import StevenDimDoors.mod_pocketDim.saving.PackedDungeonData;
import StevenDimDoors.mod_pocketDim.saving.PackedLinkData;
import StevenDimDoors.mod_pocketDim.saving.PackedLinkTail;
import StevenDimDoors.mod_pocketDim.util.Point4D; import StevenDimDoors.mod_pocketDim.util.Point4D;
import StevenDimDoors.mod_pocketDim.watcher.ClientLinkData;
import StevenDimDoors.mod_pocketDim.watcher.IUpdateWatcher; import StevenDimDoors.mod_pocketDim.watcher.IUpdateWatcher;
@SuppressWarnings("deprecation") public abstract class NewDimData implements IPackable<PackedDimData>
public abstract class NewDimData
{ {
private static class InnerDimLink extends DimLink private static class InnerDimLink extends DimLink
{ {
public InnerDimLink(Point4D source, DimLink parent,int orientation) public InnerDimLink(Point4D source, DimLink parent, int orientation, DDLock lock)
{ {
super(new ClientLinkData(source, orientation), parent); super(source, orientation, lock, parent);
} }
public InnerDimLink(Point4D source, int linkType, int orientation) public InnerDimLink(Point4D source, LinkType linkType, int orientation, DDLock lock)
{ {
super(new ClientLinkData(source, orientation), linkType); super(source, orientation, lock, linkType);
} }
public void setDestination(int x, int y, int z, NewDimData dimension) public void setDestination(int x, int y, int z, NewDimData dimension)
@@ -35,26 +44,6 @@ public abstract class NewDimData
tail.setDestination(new Point4D(x, y, z, dimension.id())); tail.setDestination(new Point4D(x, y, z, dimension.id()));
} }
public void clear()
{
//Release children
for (DimLink child : children)
{
((InnerDimLink) child).parent = null;
}
children.clear();
//Release parent
if (parent != null)
{
parent.children.remove(this);
}
parent = null;
link = null;
tail = new LinkTail(0, null);
}
public boolean overwrite(InnerDimLink nextParent,int orientation) public boolean overwrite(InnerDimLink nextParent,int orientation)
{ {
if (nextParent == null) if (nextParent == null)
@@ -66,7 +55,7 @@ public abstract class NewDimData
//Ignore this request silently //Ignore this request silently
return false; return false;
} }
if (nextParent.link.point.getDimension() != link.point.getDimension()) if (nextParent.point.getDimension() != point.getDimension())
{ {
// Ban having children in other dimensions to avoid serialization issues with cross-dimensional tails // Ban having children in other dimensions to avoid serialization issues with cross-dimensional tails
throw new IllegalArgumentException("source and parent.source must have the same dimension."); throw new IllegalArgumentException("source and parent.source must have the same dimension.");
@@ -89,11 +78,11 @@ public abstract class NewDimData
parent = nextParent; parent = nextParent;
tail = nextParent.tail; tail = nextParent.tail;
nextParent.children.add(this); nextParent.children.add(this);
this.link.orientation=orientation; this.orientation=orientation;
return true; return true;
} }
public void overwrite(int linkType, int orientation) public void overwrite(LinkType linkType, int orientation)
{ {
//Release children //Release children
for (DimLink child : children) for (DimLink child : children)
@@ -112,39 +101,73 @@ public abstract class NewDimData
parent = null; parent = null;
tail = new LinkTail(linkType, null); tail = new LinkTail(linkType, null);
//Set new orientation //Set new orientation
this.link.orientation=orientation; this.orientation=orientation;
}
/**
* only use this on the client to update errything
* @param lock
*/
public void setLock(DDLock lock)
{
this.lock = lock;
}
/**
* create a lock from a key. Returns false if this door already has a lock, or if they has already locked a door
* @param itemStack
* @return
*/
public boolean createLock(ItemStack itemStack, int lockKey)
{
if(this.hasLock()||DDLock.hasCreatedLock(itemStack))
{
return false;
}
this.lock = DDLock.generateLockKeyPair(itemStack, lockKey);
return true;
}
public void removeLock(ItemStack itemStack, InnerDimLink link)
{
if(link.doesKeyUnlock(itemStack))
{
link.lock = null;
} }
} }
}
private static int EXPECTED_LINKS_PER_CHUNK = 2;
protected static Random random = new Random(); protected static Random random = new Random();
protected int id; protected int id;
protected Map<Point4D, InnerDimLink> linkMapping; protected Map<Point4D, InnerDimLink> linkMapping;
protected List<InnerDimLink> linkList; protected List<InnerDimLink> linkList;
protected boolean isDungeon;
protected boolean isFilled; protected boolean isFilled;
protected int depth; protected int depth;
protected int packDepth; protected int packDepth;
protected DimensionType type;
protected NewDimData parent; protected NewDimData parent;
protected NewDimData root; protected NewDimData root;
protected List<NewDimData> children; protected List<NewDimData> children;
protected Point4D origin; protected Point4D origin;
protected int orientation; protected int orientation;
protected DungeonData dungeon; protected DungeonData dungeon;
protected boolean modified;
public IUpdateWatcher<ClientLinkData> linkWatcher; public IUpdateWatcher<ClientLinkData> linkWatcher;
protected NewDimData(int id, NewDimData parent, boolean isPocket, boolean isDungeon,
IUpdateWatcher<ClientLinkData> linkWatcher) // Don't write this field to a file - it should be recreated on startup
private Map<ChunkCoordIntPair, List<InnerDimLink>> chunkMapping;
protected NewDimData(int id, NewDimData parent, DimensionType type, IUpdateWatcher<ClientLinkData> linkWatcher)
{ {
// The isPocket flag is redundant. It's meant as an integrity safeguard. if (type != DimensionType.ROOT && (parent == null))
if (isPocket && (parent == null))
{ {
throw new NullPointerException("Dimensions can be pocket dimensions if and only if they have a parent dimension."); throw new NullPointerException("Dimensions can be pocket dimensions if and only if they have a parent dimension.");
} }
if (isDungeon && !isPocket)
{
throw new IllegalArgumentException("A dimensional dungeon must also be a pocket dimension.");
}
this.id = id; this.id = id;
this.linkMapping = new TreeMap<Point4D, InnerDimLink>(); //Should be stored in oct tree -- temporary solution this.linkMapping = new TreeMap<Point4D, InnerDimLink>(); //Should be stored in oct tree -- temporary solution
@@ -152,12 +175,14 @@ public abstract class NewDimData
this.children = new ArrayList<NewDimData>(); this.children = new ArrayList<NewDimData>();
this.parent = parent; this.parent = parent;
this.packDepth = 0; this.packDepth = 0;
this.isDungeon = isDungeon; this.type = type;
this.isFilled = false; this.isFilled = false;
this.orientation = 0; this.orientation = 0;
this.origin = null; this.origin = null;
this.dungeon = null; this.dungeon = null;
this.linkWatcher = linkWatcher; this.linkWatcher = linkWatcher;
this.chunkMapping = new HashMap<ChunkCoordIntPair, List<InnerDimLink>>();
this.modified = true;
//Register with parent //Register with parent
if (parent != null) if (parent != null)
@@ -166,6 +191,7 @@ public abstract class NewDimData
this.root = parent.root; this.root = parent.root;
this.depth = parent.depth + 1; this.depth = parent.depth + 1;
parent.children.add(this); parent.children.add(this);
parent.modified = true;
} }
else else
{ {
@@ -174,7 +200,7 @@ public abstract class NewDimData
} }
} }
protected NewDimData(int id, NewDimData root) protected NewDimData(int id, NewDimData root, DimensionType type)
{ {
// This constructor is meant for client-side code only // This constructor is meant for client-side code only
if (root == null) if (root == null)
@@ -188,7 +214,7 @@ public abstract class NewDimData
this.children = new ArrayList<NewDimData>(); this.children = new ArrayList<NewDimData>();
this.parent = null; this.parent = null;
this.packDepth = 0; this.packDepth = 0;
this.isDungeon = false; this.type = type;
this.isFilled = false; this.isFilled = false;
this.orientation = 0; this.orientation = 0;
this.origin = null; this.origin = null;
@@ -196,28 +222,26 @@ public abstract class NewDimData
this.linkWatcher = null; this.linkWatcher = null;
this.depth = 0; this.depth = 0;
this.root = root; this.root = root;
this.chunkMapping = null;
} }
public DimLink findNearestRift(World world, int range, int x, int y, int z) public DimLink findNearestRift(World world, int range, int x, int y, int z)
{ {
//TODO: Rewrite this later to use an octtree
// Sanity check... // Sanity check...
if (world.provider.dimensionId != id) if (world.provider.dimensionId != id)
{ {
throw new IllegalArgumentException("Attempted to search for links in a World instance for a different dimension!"); throw new IllegalArgumentException("Attempted to search for links in a World instance for a different dimension!");
} }
//Note: Only detect rifts at a distance > 1, so we ignore the rift // Note: Only detect rifts at a distance > 0, so we ignore the rift
//that called this function and any adjacent rifts. // at the center of the search space.
DimLink nearest = null;
DimLink link; DimLink link;
DimLink nearest = null;
int i, j, k;
int distance; int distance;
int minDistance = Integer.MAX_VALUE; int minDistance = Integer.MAX_VALUE;
int i, j, k;
DDProperties properties = DDProperties.instance(); DDProperties properties = DDProperties.instance();
for (i = -range; i <= range; i++) for (i = -range; i <= range; i++)
@@ -245,23 +269,19 @@ public abstract class NewDimData
public ArrayList<DimLink> findRiftsInRange(World world, int range, int x, int y, int z) public ArrayList<DimLink> findRiftsInRange(World world, int range, int x, int y, int z)
{ {
ArrayList<DimLink> links = new ArrayList<DimLink>();
//TODO: Rewrite this later to use an octtree
// Sanity check... // Sanity check...
if (world.provider.dimensionId != id) if (world.provider.dimensionId != id)
{ {
throw new IllegalArgumentException("Attempted to search for links in a World instance for a different dimension!"); throw new IllegalArgumentException("Attempted to search for links in a World instance for a different dimension!");
} }
//Note: Only detect rifts at a distance > 1, so we ignore the rift // Note: Only detect rifts at a distance > 0, so we ignore the rift
//that called this function and any adjacent rifts. // at the center of the search space.
DimLink link;
int distance;
int i, j, k; int i, j, k;
int distance;
DimLink link;
DDProperties properties = DDProperties.instance(); DDProperties properties = DDProperties.instance();
ArrayList<DimLink> links = new ArrayList<DimLink>();
for (i = -range; i <= range; i++) for (i = -range; i <= range; i++)
{ {
@@ -289,66 +309,98 @@ public abstract class NewDimData
{ {
return Math.abs(i) + Math.abs(j) + Math.abs(k); return Math.abs(i) + Math.abs(j) + Math.abs(k);
} }
public DimLink createLink(int x, int y, int z, int linkType,int orientation)
public DimLink createLink(int x, int y, int z, LinkType linkType, int orientation)
{ {
return createLink(new Point4D(x, y, z, id), linkType,orientation); return createLink(new Point4D(x, y, z, id), linkType, orientation, null);
} }
public DimLink createLink(Point4D source, int linkType,int orientation) public DimLink createLink(Point4D source, LinkType linkType, int orientation, DDLock locked)
{ {
// Return an existing link if there is one to avoid creating multiple links starting at the same point. // Return an existing link if there is one to avoid creating multiple links starting at the same point.
InnerDimLink link = linkMapping.get(source); InnerDimLink link = linkMapping.get(source);
if (link == null) if (link == null)
{ {
link = new InnerDimLink(source, linkType,orientation); link = new InnerDimLink(source, linkType, orientation, locked);
linkMapping.put(source, link); linkMapping.put(source, link);
linkList.add(link); linkList.add(link);
// If this code is running on the server side, add this link to chunkMapping.
if (linkType != LinkType.CLIENT)
{
ChunkCoordIntPair chunk = link.getChunkCoordinates();
List<InnerDimLink> chunkLinks = chunkMapping.get(chunk);
if (chunkLinks == null)
{
chunkLinks = new ArrayList<InnerDimLink>(EXPECTED_LINKS_PER_CHUNK);
chunkMapping.put(chunk, chunkLinks);
}
chunkLinks.add(link);
}
} }
else else
{ {
link.overwrite(linkType, orientation); link.overwrite(linkType, orientation);
} }
modified = true;
//Link created! //Link created!
if(linkType!=LinkTypes.CLIENT_SIDE) if (linkType != LinkType.CLIENT)
{ {
linkWatcher.onCreated(link.link); linkWatcher.onCreated(new ClientLinkData(link));
} }
return link; return link;
} }
public DimLink createChildLink(int x, int y, int z, DimLink parent) public DimLink createChildLink(int x, int y, int z, DimLink parent)
{ {
if (parent == null) return createChildLink(new Point4D(x, y, z, id), (InnerDimLink) parent, null);
{
throw new IllegalArgumentException("parent cannot be null.");
} }
return createChildLink(new Point4D(x, y, z, id), (InnerDimLink) parent); public DimLink createChildLink(Point4D source, DimLink parent, DDLock locked)
}
private DimLink createChildLink(Point4D source, InnerDimLink parent)
{ {
// To avoid having multiple links at a single point, if we find an existing link then we overwrite // To avoid having multiple links at a single point, if we find an existing link then we overwrite
// its destination data instead of creating a new instance. // its destination data instead of creating a new instance.
if (parent == null)
{
throw new IllegalArgumentException("parent cannot be null.");
}
InnerDimLink link = linkMapping.get(source); InnerDimLink link = linkMapping.get(source);
if (link == null) if (link == null)
{ {
link = new InnerDimLink(source, parent, parent.link.orientation); link = new InnerDimLink(source, parent, parent.orientation, locked);
linkMapping.put(source, link); linkMapping.put(source, link);
linkList.add(link); linkList.add(link);
// If this code is running on the server side, add this link to chunkMapping.
// Granted, the client side code should never create child links anyway...
if (link.linkType() != LinkType.CLIENT)
{
ChunkCoordIntPair chunk = link.getChunkCoordinates();
List<InnerDimLink> chunkLinks = chunkMapping.get(chunk);
if (chunkLinks == null)
{
chunkLinks = new ArrayList<InnerDimLink>(EXPECTED_LINKS_PER_CHUNK);
chunkMapping.put(chunk, chunkLinks);
}
chunkLinks.add(link);
}
// Link created! // Link created!
linkWatcher.onCreated(link.link); linkWatcher.onCreated(new ClientLinkData(link));
} }
else else
{ {
if (link.overwrite(parent, parent.link.orientation)) if (link.overwrite((InnerDimLink) parent, parent.orientation))
{ {
//Link created! //Link created!
linkWatcher.onCreated(link.link); linkWatcher.onCreated(new ClientLinkData(link));
} }
} }
modified = true;
return link; return link;
} }
@@ -362,16 +414,32 @@ public abstract class NewDimData
if (target != null) if (target != null)
{ {
linkList.remove(target); linkList.remove(target);
// If this code is running on the server side, remove this link to chunkMapping.
if (link.linkType() != LinkType.CLIENT)
{
ChunkCoordIntPair chunk = target.getChunkCoordinates();
List<InnerDimLink> chunkLinks = chunkMapping.get(chunk);
if (chunkLinks != null)
{
chunkLinks.remove(target);
}
}
// Raise deletion event // Raise deletion event
linkWatcher.onDeleted(target.link); linkWatcher.onDeleted(new ClientLinkData(link));
target.clear(); target.clear();
modified = true;
} }
return (target != null); return (target != null);
} }
public boolean deleteLink(int x, int y, int z) public boolean deleteLink(int x, int y, int z)
{ {
Point4D location = new Point4D(x, y, z, id); return this.deleteLink(this.getLink(x, y, z));
}
public boolean deleteLink(Point4D location)
{
return this.deleteLink(this.getLink(location)); return this.deleteLink(this.getLink(location));
} }
@@ -406,11 +474,10 @@ public abstract class NewDimData
return (root != this); return (root != this);
} }
public boolean isDungeon() public DimensionType type()
{ {
return isDungeon; return this.type;
} }
public boolean isFilled() public boolean isFilled()
{ {
return isFilled; return isFilled;
@@ -419,6 +486,7 @@ public abstract class NewDimData
public void setFilled(boolean isFilled) public void setFilled(boolean isFilled)
{ {
this.isFilled = isFilled; this.isFilled = isFilled;
this.modified = true;
} }
public int id() public int id()
@@ -483,7 +551,7 @@ public abstract class NewDimData
public void initializeDungeon(int originX, int originY, int originZ, int orientation, DimLink incoming, DungeonData dungeon) public void initializeDungeon(int originX, int originY, int originZ, int orientation, DimLink incoming, DungeonData dungeon)
{ {
if (!isDungeon) if (this.type != DimensionType.DUNGEON)
{ {
throw new IllegalStateException("Cannot invoke initializeDungeon() on a non-dungeon dimension."); throw new IllegalStateException("Cannot invoke initializeDungeon() on a non-dungeon dimension.");
} }
@@ -495,21 +563,55 @@ public abstract class NewDimData
{ {
throw new IllegalArgumentException("orientation must be between 0 and 3, inclusive."); throw new IllegalArgumentException("orientation must be between 0 and 3, inclusive.");
} }
setDestination(incoming, originX, originY, originZ); setLinkDestination(incoming, originX, originY, originZ);
this.origin = incoming.destination(); this.origin = incoming.destination();
this.orientation = orientation; this.orientation = orientation;
this.dungeon = dungeon; this.dungeon = dungeon;
this.packDepth = calculatePackDepth(parent, dungeon); this.packDepth = calculatePackDepth(parent, dungeon);
this.modified = true;
} }
/** /**
* effectivly moves the dungeon to the 'top' of a chain as far as dungeon generation is concerend. * Effectively moves the dungeon to the 'top' of a chain as far as dungeon generation is concerned.
*/ */
public void setParentToRoot() public void setParentToRoot()
{ {
// Update this dimension's information
if (parent != null)
{
parent.children.remove(this);
}
this.depth = 1; this.depth = 1;
this.parent = this.root; this.parent = this.root;
this.root.children.add(this); this.root.children.add(this);
this.root.modified = true;
this.modified = true;
if (this.type == DimensionType.DUNGEON)
{
this.packDepth = calculatePackDepth(this.parent, this.dungeon);
}
// Update the depths for child dimensions using a depth-first traversal
Stack<NewDimData> ordering = new Stack<NewDimData>();
ordering.addAll(this.children);
while (!ordering.isEmpty())
{
NewDimData current = ordering.pop();
current.resetDepth();
ordering.addAll(current.children);
}
}
private void resetDepth()
{
// We assume that this is only applied to dimensions with parents
this.depth = this.parent.depth + 1;
if (this.type == DimensionType.DUNGEON)
{
this.packDepth = calculatePackDepth(this.parent, this.dungeon);
}
this.modified = true;
} }
public static int calculatePackDepth(NewDimData parent, DungeonData current) public static int calculatePackDepth(NewDimData parent, DungeonData current)
@@ -538,11 +640,8 @@ public abstract class NewDimData
{ {
return parent.packDepth + 1; return parent.packDepth + 1;
} }
else
{
return 1; return 1;
} }
}
public void initializePocket(int originX, int originY, int originZ, int orientation, DimLink incoming) public void initializePocket(int originX, int originY, int originZ, int orientation, DimLink incoming)
{ {
@@ -555,15 +654,45 @@ public abstract class NewDimData
throw new IllegalStateException("The dimension has already been initialized."); throw new IllegalStateException("The dimension has already been initialized.");
} }
setDestination(incoming, originX, originY, originZ); setLinkDestination(incoming, originX, originY, originZ);
this.origin = incoming.destination(); this.origin = incoming.destination();
this.orientation = orientation; this.orientation = orientation;
this.modified = true;
} }
public void setDestination(DimLink incoming, int x, int y, int z) public void setLinkDestination(DimLink incoming, int x, int y, int z)
{ {
InnerDimLink link = (InnerDimLink) incoming; InnerDimLink link = (InnerDimLink) incoming;
link.setDestination(x, y, z, this); link.setDestination(x, y, z, this);
this.modified = true;
}
public void lock(DimLink link, boolean locked)
{
InnerDimLink innerLink = (InnerDimLink)link;
innerLink.lock.setLockState(locked);
modified = true;
}
public void setLock(DimLink link, DDLock lock)
{
InnerDimLink innerLink = (InnerDimLink)link;
innerLink.setLock(lock);
modified = true;
}
public void createLock(DimLink link, ItemStack item, int lockKey)
{
InnerDimLink innerLink = (InnerDimLink)link;
innerLink.createLock(item, lockKey);
modified = true;
}
public void removeLock(DimLink link, ItemStack item)
{
InnerDimLink innerLink = (InnerDimLink)link;
innerLink.removeLock(item, innerLink);
modified = true;
} }
public DimLink getRandomLink() public DimLink getRandomLink()
@@ -576,12 +705,124 @@ public abstract class NewDimData
{ {
return linkList.get(random.nextInt(linkList.size())); return linkList.get(random.nextInt(linkList.size()));
} }
else
{
return linkList.get(0); return linkList.get(0);
} }
public Iterable<? extends DimLink> getChunkLinks(int chunkX, int chunkZ)
{
List<InnerDimLink> chunkLinks = chunkMapping.get(new ChunkCoordIntPair(chunkX, chunkZ));
if (chunkLinks != null)
{
return chunkLinks;
}
return new ArrayList<InnerDimLink>(0);
} }
public boolean isModified()
{
return modified;
}
public void clearModified()
{
this.modified = false;
}
public void clear()
{
// If this dimension has a parent, remove it from its parent's list of children
if (parent != null)
{
parent.children.remove(this);
}
// Remove this dimension as the parent of its children
for (NewDimData child : children)
{
child.parent = null;
}
// Clear all fields
id = Integer.MIN_VALUE;
linkMapping.clear();
linkMapping = null;
linkList.clear();
linkList = null;
children.clear();
children = null;
type = null;
isFilled = false;
depth = Integer.MIN_VALUE;
packDepth = Integer.MIN_VALUE;
origin = null;
orientation = Integer.MIN_VALUE;
dungeon = null;
linkWatcher = null;
}
public PackedDimData pack()
{
ArrayList<Integer> ChildIDs = new ArrayList<Integer>();
ArrayList<PackedLinkData> Links = new ArrayList<PackedLinkData>();
ArrayList<PackedLinkTail> Tails = new ArrayList<PackedLinkTail>();
PackedDungeonData packedDungeon=null;
if(this.dungeon!=null)
{
packedDungeon= new PackedDungeonData(dungeon.weight(), dungeon.isOpen(), dungeon.isInternal(),
dungeon.schematicPath(), dungeon.schematicName(), dungeon.dungeonType().Name,
dungeon.dungeonType().Owner.getName());
}
//Make a list of children
for(NewDimData data : this.children)
{
ChildIDs.add(data.id);
}
for(DimLink link:this.links())
{
ArrayList<Point3D> children = new ArrayList<Point3D>();
Point3D parentPoint = new Point3D(-1,-1,-1);
if(link.parent!=null)
{
parentPoint=link.parent.point.toPoint3D();
}
for(DimLink childLink : link.children)
{
children.add(childLink.source().toPoint3D());
}
PackedLinkTail tail = new PackedLinkTail(link.tail.getDestination(),link.tail.getLinkType());
Links.add(new PackedLinkData(link.point,parentPoint,tail,link.orientation,children,link.lock));
PackedLinkTail tempTail = new PackedLinkTail(link.tail.getDestination(),link.tail.getLinkType());
if(Tails.contains(tempTail))
{
Tails.add(tempTail);
}
}
int parentID=this.id;
Point3D originPoint=new Point3D(0,0,0);
if(this.parent!=null)
{
parentID = this.parent.id;
}
if(this.origin!=null)
{
originPoint=this.origin.toPoint3D();
}
return new PackedDimData(this.id, depth, this.packDepth, parentID, this.root().id(), orientation,
type, isFilled,packedDungeon, originPoint, ChildIDs, Links, Tails);
// FIXME: IMPLEMENTATION PLZTHX
//I tried
}
@Override
public String name()
{
return String.valueOf(id);
}
@Override
public String toString() public String toString()
{ {
return "DimID= " + this.id; return "DimID= " + this.id;

View File

@@ -7,154 +7,57 @@ import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import net.minecraft.entity.player.EntityPlayer;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraft.world.WorldServer; import net.minecraft.world.WorldServer;
import net.minecraftforge.common.DimensionManager; import net.minecraftforge.common.DimensionManager;
import StevenDimDoors.mod_pocketDim.DDProperties;
import StevenDimDoors.mod_pocketDim.Point3D;
import StevenDimDoors.mod_pocketDim.mod_pocketDim; import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.config.DDProperties;
import StevenDimDoors.mod_pocketDim.helpers.Compactor; import StevenDimDoors.mod_pocketDim.helpers.Compactor;
import StevenDimDoors.mod_pocketDim.helpers.DeleteFolder; import StevenDimDoors.mod_pocketDim.helpers.DeleteFolder;
import StevenDimDoors.mod_pocketDim.saving.DDSaveHandler; import StevenDimDoors.mod_pocketDim.saving.DDSaveHandler;
import StevenDimDoors.mod_pocketDim.saving.IPackable;
import StevenDimDoors.mod_pocketDim.saving.OldSaveImporter; import StevenDimDoors.mod_pocketDim.saving.OldSaveImporter;
import StevenDimDoors.mod_pocketDim.saving.PackedDimData; import StevenDimDoors.mod_pocketDim.saving.PackedDimData;
import StevenDimDoors.mod_pocketDim.saving.PackedDungeonData;
import StevenDimDoors.mod_pocketDim.saving.PackedLinkData;
import StevenDimDoors.mod_pocketDim.saving.PackedLinkTail;
import StevenDimDoors.mod_pocketDim.util.Point4D; import StevenDimDoors.mod_pocketDim.util.Point4D;
import StevenDimDoors.mod_pocketDim.watcher.ClientDimData; import StevenDimDoors.mod_pocketDim.watcher.ClientDimData;
import StevenDimDoors.mod_pocketDim.watcher.ClientLinkData; import StevenDimDoors.mod_pocketDim.watcher.ClientLinkData;
import StevenDimDoors.mod_pocketDim.watcher.IUpdateSource; import StevenDimDoors.mod_pocketDim.watcher.IUpdateSource;
import StevenDimDoors.mod_pocketDim.watcher.IUpdateWatcher; import StevenDimDoors.mod_pocketDim.watcher.IUpdateWatcher;
import StevenDimDoors.mod_pocketDim.watcher.UpdateWatcherProxy; import StevenDimDoors.mod_pocketDim.watcher.UpdateWatcherProxy;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
/** /**
* This class regulates all the operations involving the storage and manipulation of dimensions. * This class regulates all the operations involving the storage and
* It handles saving dim data, teleporting the player, and creating/registering new dimensions as * manipulation of dimensions. It handles saving dim data, teleporting the
* well as loading old dimensions on startup * player, and creating/registering new dimensions as well as loading old
* dimensions on startup
*/ */
public class PocketManager public class PocketManager
{ {
private static class InnerDimData extends NewDimData implements IPackable<PackedDimData> private static class InnerDimData extends NewDimData
{ {
// This class allows us to instantiate NewDimData indirectly without exposing // This class allows us to instantiate NewDimData indirectly without
// a public constructor from NewDimData. It's meant to stop us from constructing // exposing
// instances of NewDimData going through PocketManager. In turn, that enforces // a public constructor from NewDimData. It's meant to stop us from
// that any link destinations must be real dimensions controlled by PocketManager. // constructing
// instances of NewDimData going through PocketManager. In turn, that
// enforces
// that any link destinations must be real dimensions controlled by
// PocketManager.
public InnerDimData(int id, InnerDimData parent, boolean isPocket, boolean isDungeon, public InnerDimData(int id, InnerDimData parent, DimensionType type, IUpdateWatcher<ClientLinkData> linkWatcher)
IUpdateWatcher<ClientLinkData> linkWatcher)
{ {
super(id, parent, isPocket, isDungeon, linkWatcher); super(id, parent, type, linkWatcher);
} }
public InnerDimData(int id, InnerDimData root) public InnerDimData(int id, NewDimData root, DimensionType type)
{ {
// This constructor is meant for client-side code only // This constructor is meant for client-side code only
super(id, root); super(id, root, type);
} }
public void clear()
{
// If this dimension has a parent, remove it from its parent's list of children
if (parent != null)
{
parent.children.remove(this);
}
// Remove this dimension as the parent of its children
for (NewDimData child : children)
{
child.parent = null;
}
// Clear all fields
id = Integer.MIN_VALUE;
linkMapping.clear();
linkMapping = null;
linkList.clear();
linkList = null;
children.clear();
children = null;
isDungeon = false;
isFilled = false;
depth = Integer.MIN_VALUE;
packDepth = Integer.MIN_VALUE;
origin = null;
orientation = Integer.MIN_VALUE;
dungeon = null;
linkWatcher = null;
}
@Override
public String name()
{
return String.valueOf(id);
}
@Override
public PackedDimData pack()
{
ArrayList<Integer> ChildIDs = new ArrayList<Integer>();
ArrayList<PackedLinkData> Links = new ArrayList<PackedLinkData>();
ArrayList<PackedLinkTail> Tails = new ArrayList<PackedLinkTail>();
PackedDungeonData packedDungeon=null;
if(this.dungeon!=null)
{
packedDungeon= new PackedDungeonData(dungeon.weight(), dungeon.isOpen(), dungeon.isInternal(),
dungeon.schematicPath(), dungeon.schematicName(), dungeon.dungeonType().Name,
dungeon.dungeonType().Owner.getName());
}
//Make a list of children
for(NewDimData data : this.children)
{
ChildIDs.add(data.id);
}
for(DimLink link:this.links())
{
ArrayList<Point3D> children = new ArrayList<Point3D>();
Point3D parentPoint = new Point3D(-1,-1,-1);
if(link.parent!=null)
{
parentPoint=link.parent.link.point.toPoint3D();
}
for(DimLink childLink : link.children)
{
children.add(childLink.source().toPoint3D());
}
PackedLinkTail tail = new PackedLinkTail(link.tail.getDestination(),link.tail.getLinkType());
Links.add(new PackedLinkData(link.link.point,parentPoint,tail,link.link.orientation,children));
PackedLinkTail tempTail = new PackedLinkTail(link.tail.getDestination(),link.tail.getLinkType());
if(Tails.contains(tempTail))
{
Tails.add(tempTail);
}
}
int parentID=this.id;
Point3D originPoint=new Point3D(0,0,0);
if(this.parent!=null)
{
parentID = this.parent.id;
}
if(this.origin!=null)
{
originPoint=this.origin.toPoint3D();
}
return new PackedDimData(this.id, depth, this.packDepth, parentID, this.root().id(), orientation,
isDungeon, isFilled,packedDungeon, originPoint, ChildIDs, Links, Tails);
// FIXME: IMPLEMENTATION PLZTHX
//I tried
}
} }
private static class ClientLinkWatcher implements IUpdateWatcher<ClientLinkData> private static class ClientLinkWatcher implements IUpdateWatcher<ClientLinkData>
@@ -164,7 +67,7 @@ public class PocketManager
{ {
Point4D source = link.point; Point4D source = link.point;
NewDimData dimension = getDimensionData(source.getDimension()); NewDimData dimension = getDimensionData(source.getDimension());
dimension.createLink(source.getX(), source.getY(), source.getZ(), LinkTypes.CLIENT_SIDE,link.orientation); dimension.createLink(source, LinkType.CLIENT, 0, link.lock);
} }
@Override @Override
@@ -174,6 +77,16 @@ public class PocketManager
NewDimData dimension = getDimensionData(source.getDimension()); NewDimData dimension = getDimensionData(source.getDimension());
dimension.deleteLink(source.getX(), source.getY(), source.getZ()); dimension.deleteLink(source.getX(), source.getY(), source.getZ());
} }
@Override
public void update(ClientLinkData link)
{
Point4D source = link.point;
NewDimData dimension = getDimensionData(source.getDimension());
DimLink dLink = dimension.getLink(source);
dLink.lock = link.lock;
}
} }
private static class ClientDimWatcher implements IUpdateWatcher<ClientDimData> private static class ClientDimWatcher implements IUpdateWatcher<ClientDimData>
@@ -181,7 +94,7 @@ public class PocketManager
@Override @Override
public void onCreated(ClientDimData data) public void onCreated(ClientDimData data)
{ {
registerClientDimension(data.ID, data.RootID); registerClientDimension(data.ID, data.rootID, data.type);
} }
@Override @Override
@@ -189,19 +102,28 @@ public class PocketManager
{ {
deletePocket(getDimensionData(data.ID), false); deletePocket(getDimensionData(data.ID), false);
} }
@Override
public void update(ClientDimData message)
{
// TODO Auto-generated method stub
}
} }
private static class DimRegistrationCallback implements IDimRegistrationCallback private static class DimRegistrationCallback implements IDimRegistrationCallback
{ {
// We use this class to provide Compactor with the ability to send us dim data without // We use this class to provide Compactor with the ability to send us
// having to instantiate a bunch of data containers and without exposing an "unsafe" // dim data without
// creation method for anyone to call. Integrity protection for the win! It's like // having to instantiate a bunch of data containers and without exposing
// an "unsafe"
// creation method for anyone to call. Integrity protection for the win!
// It's like
// exposing a private constructor ONLY to a very specific trusted class. // exposing a private constructor ONLY to a very specific trusted class.
@Override @Override
public NewDimData registerDimension(int dimensionID, int rootID) public NewDimData registerDimension(int dimensionID, int rootID, DimensionType type)
{ {
return registerClientDimension(dimensionID, rootID); return registerClientDimension(dimensionID, rootID, type);
} }
} }
@@ -218,18 +140,25 @@ public class PocketManager
private static final UpdateWatcherProxy<ClientDimData> dimWatcher = new UpdateWatcherProxy<ClientDimData>(); private static final UpdateWatcherProxy<ClientDimData> dimWatcher = new UpdateWatcherProxy<ClientDimData>();
private static ArrayList<NewDimData> rootDimensions = null; private static ArrayList<NewDimData> rootDimensions = null;
//HashMap that maps all the dimension IDs registered with DimDoors to their DD data. // HashMap that maps all the dimension IDs registered with DimDoors to their
// DD data.
private static HashMap<Integer, InnerDimData> dimensionData = null; private static HashMap<Integer, InnerDimData> dimensionData = null;
//ArrayList that stores the dimension IDs of any dimension that has been deleted. // ArrayList that stores the dimension IDs of any dimension that has been
// deleted.
private static ArrayList<Integer> dimensionIDBlackList = null; private static ArrayList<Integer> dimensionIDBlackList = null;
// Stores all the personal pocket mappings
private static HashMap<String, NewDimData> personalPocketsMapping = null;
public static boolean isLoaded() public static boolean isLoaded()
{ {
return isLoaded; return isLoaded;
} }
/** /**
* simple method called on startup to register all dims saved in the dim list. Only tries to register pocket dims, though. Also calls load() * simple method called on startup to register all dims saved in the dim
* list. Only tries to register pocket dims, though. Also calls load()
*
* @return * @return
*/ */
public static void load() public static void load()
@@ -247,6 +176,7 @@ public class PocketManager
dimensionData = new HashMap<Integer, InnerDimData>(); dimensionData = new HashMap<Integer, InnerDimData>();
rootDimensions = new ArrayList<NewDimData>(); rootDimensions = new ArrayList<NewDimData>();
dimensionIDBlackList = new ArrayList<Integer>(); dimensionIDBlackList = new ArrayList<Integer>();
personalPocketsMapping = new HashMap<String, NewDimData>();
if (FMLCommonHandler.instance().getEffectiveSide().isClient()) if (FMLCommonHandler.instance().getEffectiveSide().isClient())
{ {
@@ -258,7 +188,7 @@ public class PocketManager
} }
// Register Limbo // Register Limbo
DDProperties properties = DDProperties.instance(); DDProperties properties = DDProperties.instance();
registerDimension(properties.LimboDimensionID, null, false, false); registerDimension(properties.LimboDimensionID, null, DimensionType.ROOT);
loadInternal(); loadInternal();
@@ -271,12 +201,16 @@ public class PocketManager
public static boolean registerPackedDimData(PackedDimData packedData) public static boolean registerPackedDimData(PackedDimData packedData)
{ {
InnerDimData dimData; InnerDimData dimData;
DimensionType type = DimensionType.getTypeFromIndex(packedData.DimensionType);
if (type == null)
{
throw new IllegalArgumentException("Invalid dimension type");
}
// register roots // register roots
if (packedData.ID == packedData.ParentID) if (packedData.ID == packedData.ParentID)
{ {
dimData = new InnerDimData(packedData.ID, null, false, false, linkWatcher); dimData = new InnerDimData(packedData.ID, null, type, linkWatcher);
dimData.root = dimData; dimData.root = dimData;
dimData.parent = dimData; dimData.parent = dimData;
dimData.depth = packedData.Depth; dimData.depth = packedData.Depth;
@@ -285,13 +219,14 @@ public class PocketManager
PocketManager.rootDimensions.add(dimData); PocketManager.rootDimensions.add(dimData);
} }
else //register children else
// register children
{ {
InnerDimData test = PocketManager.dimensionData.get(packedData.ParentID); InnerDimData test = PocketManager.dimensionData.get(packedData.ParentID);
dimData = new InnerDimData(packedData.ID, test,true, packedData.IsDungeon, linkWatcher); dimData = new InnerDimData(packedData.ID, test, type, linkWatcher);
dimData.isFilled = packedData.IsFilled; dimData.isFilled = packedData.IsFilled;
dimData.origin = new Point4D(packedData.Origin.getX(), packedData.Origin.getY(), packedData.Origin.getZ(), packedData.ID); dimData.origin = new Point4D(packedData.Origin.getX(), packedData.Origin.getY(), packedData.Origin.getZ(), packedData.ID);
dimData.root=PocketManager.getDimensionData(packedData.RootID); dimData.root = PocketManager.createDimensionData(packedData.RootID);
if (packedData.DungeonData != null) if (packedData.DungeonData != null)
{ {
@@ -304,49 +239,61 @@ public class PocketManager
return true; return true;
} }
public static boolean deletePocket(NewDimData target, boolean deleteFolder) public static boolean deletePocket(NewDimData target, boolean deleteFolder)
{ {
// We can't delete the dimension if it's currently loaded or if it's not actually a pocket. // We can't delete the dimension if it's currently loaded or if it's not
// We cast to InnerDimData so that if anyone tries to be a smartass and create their // actually a pocket.
// We cast to InnerDimData so that if anyone tries to be a smartass and
// create their
// own version of NewDimData, this will throw an exception. // own version of NewDimData, this will throw an exception.
InnerDimData dimension = (InnerDimData) target; InnerDimData dimension = (InnerDimData) target;
if (dimension.isPocketDimension() && DimensionManager.getWorld(dimension.id()) == null) if (dimension.isPocketDimension() && DimensionManager.getWorld(dimension.id()) == null)
{ {
if (deleteFolder) if (deleteFolder)
{ {
deleteDimensionFolder(target); deleteDimensionFiles(dimension);
} }
// Note: We INTENTIONALLY don't unregister the dimensions that we
// delete with Forge. Instead, we keep them registered to stop Forge
// from reallocating those IDs to other mods such as Mystcraft. This
// is to prevent bugs. Blacklisted dimensions are still properly
// unregistered when the server shuts down.
dimensionIDBlackList.add(dimension.id); dimensionIDBlackList.add(dimension.id);
deleteDimensionData(dimension.id); deleteDimensionData(dimension);
return true; return true;
} }
return false; return false;
} }
private static boolean deleteDimensionFolder(NewDimData target)
{
InnerDimData dimension = (InnerDimData) target;
if (dimension.isPocketDimension() && DimensionManager.getWorld(dimension.id()) == null)
{
File saveDirectory = new File(DimensionManager.getCurrentSaveRootDirectory() + "/DimensionalDoors/pocketDimID" + dimension.id());
DeleteFolder.deleteFolder(saveDirectory);
return true;
}
return false;
}
private static boolean deleteDimensionData(int dimensionID)
{
if(dimensionData.containsKey(dimensionID)&& DimensionManager.getWorld(dimensionID) == null)
{
NewDimData target = PocketManager.getDimensionData(dimensionID);
InnerDimData dimension = (InnerDimData) target;
dimensionData.remove(dimensionID); private static void deleteDimensionFiles(InnerDimData dimension)
{
// We assume that the caller checks if the dimension is loaded, for the
// sake of efficiency. Don't call this on a loaded dimension or bad
// things will happen!
String saveRootPath = DimensionManager.getCurrentSaveRootDirectory().getAbsolutePath();
File saveDirectory = new File(saveRootPath + "/DimensionalDoors/pocketDimID" + dimension.id());
DeleteFolder.deleteFolder(saveDirectory);
File dataFile = new File(saveRootPath + "/DimensionalDoors/data/dim_" + dimension.id() + ".txt");
dataFile.delete();
}
private static void deleteDimensionData(InnerDimData dimension)
{
// We assume that the caller checks if the dimension is loaded, for the
// sake of efficiency. Don't call this on a loaded dimension or bad
// things will happen!
if (dimensionData.remove(dimension.id()) != null)
{
// Raise the dim deleted event // Raise the dim deleted event
getDimwatcher().onDeleted(new ClientDimData(dimension)); getDimwatcher().onDeleted(new ClientDimData(dimension));
dimension.clear(); dimension.clear();
return true;
} }
return false; else
{
// This should never happen. A simple sanity check.
throw new IllegalArgumentException("The specified dimension is not listed with PocketManager.");
}
} }
private static void registerPockets(DDProperties properties) private static void registerPockets(DDProperties properties)
@@ -356,12 +303,20 @@ public class PocketManager
if (dimension.isPocketDimension()) if (dimension.isPocketDimension())
{ {
try try
{
if (personalPocketsMapping.containsValue(dimension))
{
DimensionManager.registerDimension(dimension.id(), properties.PersonalPocketProviderID);
}
else
{ {
DimensionManager.registerDimension(dimension.id(), properties.PocketProviderID); DimensionManager.registerDimension(dimension.id(), properties.PocketProviderID);
} }
}
catch (Exception e) catch (Exception e)
{ {
System.err.println("Could not register pocket dimension #" + dimension.id() + ". Probably caused by a version update/save data corruption/other mods."); System.err.println("Could not register pocket dimension #" + dimension.id()
+ ". Probably caused by a version update/save data corruption/other mods.");
e.printStackTrace(); e.printStackTrace();
} }
} }
@@ -400,12 +355,11 @@ public class PocketManager
} }
/** /**
* loads the dim data from the saved hashMap. Also handles compatibility with old saves, see OldSaveHandler * loads the dim data from the saved hashMap. Also handles compatibility
* with old saves, see OldSaveHandler
*/ */
private static void loadInternal() private static void loadInternal()
{ {
//System.out.println(!FMLCommonHandler.instance().getSide().isClient());
File saveDir = DimensionManager.getCurrentSaveRootDirectory(); File saveDir = DimensionManager.getCurrentSaveRootDirectory();
if (saveDir != null) if (saveDir != null)
{ {
@@ -418,7 +372,8 @@ public class PocketManager
{ {
System.out.println("Importing old DD save data..."); System.out.println("Importing old DD save data...");
OldSaveImporter.importOldSave(oldSaveData); OldSaveImporter.importOldSave(oldSaveData);
oldSaveData.delete();
oldSaveData.renameTo(new File(oldSaveData.getAbsolutePath() + "_IMPORTED"));
System.out.println("Import Succesful!"); System.out.println("Import Succesful!");
} }
@@ -440,17 +395,12 @@ public class PocketManager
} }
} }
public static void save() public static void save(boolean checkModified)
{ {
if (!isLoaded) if (!isLoaded)
{ {
return; return;
} }
World world = DimensionManager.getWorld(OVERWORLD_DIMENSION_ID);
if (world == null || world.isRemote || DimensionManager.getCurrentSaveRootDirectory() == null)
{
return;
}
// Check this last to make sure we set the flag shortly after. // Check this last to make sure we set the flag shortly after.
if (isSaving) if (isSaving)
{ {
@@ -460,7 +410,7 @@ public class PocketManager
try try
{ {
DDSaveHandler.saveAll(dimensionData.values(), dimensionIDBlackList); DDSaveHandler.saveAll(dimensionData.values(), dimensionIDBlackList, checkModified);
} }
catch (Exception e) catch (Exception e)
{ {
@@ -477,6 +427,11 @@ public class PocketManager
public static WorldServer loadDimension(int id) public static WorldServer loadDimension(int id)
{ {
if (!DimensionManager.isDimensionRegistered(id))
{
return null;
}
WorldServer world = DimensionManager.getWorld(id); WorldServer world = DimensionManager.getWorld(id);
if (world == null) if (world == null)
{ {
@@ -493,10 +448,18 @@ public class PocketManager
public static NewDimData registerDimension(World world) public static NewDimData registerDimension(World world)
{ {
return registerDimension(world.provider.dimensionId, null, false, false); return registerDimension(world.provider.dimensionId, null, DimensionType.ROOT);
} }
public static NewDimData registerPocket(NewDimData parent, boolean isDungeon) /**
* method to register a new pocket with DD and with forge.
*
* @param parent
* @param type
* @param playername
* @return
*/
public static NewDimData registerPocket(NewDimData parent, DimensionType type, String playername)
{ {
if (parent == null) if (parent == null)
{ {
@@ -505,18 +468,51 @@ public class PocketManager
DDProperties properties = DDProperties.instance(); DDProperties properties = DDProperties.instance();
int dimensionID = DimensionManager.getNextFreeDimId(); int dimensionID = DimensionManager.getNextFreeDimId();
DimensionManager.registerDimension(dimensionID, properties.PocketProviderID);
return registerDimension(dimensionID, (InnerDimData) parent, true, isDungeon); // register a personal pocket
if (type == DimensionType.PERSONAL)
{
if (playername == null)
{
throw new IllegalArgumentException("A personal pocket must be attached to a playername");
} }
DimensionManager.registerDimension(dimensionID, properties.PersonalPocketProviderID);
NewDimData data = registerDimension(dimensionID, (InnerDimData) parent, type);
personalPocketsMapping.put(playername, data);
return data;
}
else
{ // register a pocket as personal if its parents are personal, but
// without a mapping.
if (parent.type == DimensionType.PERSONAL)
{
DimensionManager.registerDimension(dimensionID, properties.PersonalPocketProviderID);
NewDimData data = registerDimension(dimensionID, (InnerDimData) parent, DimensionType.PERSONAL);
return data;
}
// register a standard pocket
DimensionManager.registerDimension(dimensionID, properties.PocketProviderID);
return registerDimension(dimensionID, (InnerDimData) parent, type);
}
}
public static NewDimData registerPocket(NewDimData parent, DimensionType type)
{
return registerPocket(parent, type, null);
}
/** /**
* Registers a dimension with DD but NOT with forge. * Registers a dimension with DD but NOT with forge.
*
* @param dimensionID * @param dimensionID
* @param parent * @param parent
* @param isPocket * @param isPocket
* @param isDungeon * @param isDungeon
* @return * @return
*/ */
private static NewDimData registerDimension(int dimensionID, InnerDimData parent, boolean isPocket, boolean isDungeon) private static NewDimData registerDimension(int dimensionID, InnerDimData parent, DimensionType type)
{ {
if (dimensionData.containsKey(dimensionID)) if (dimensionData.containsKey(dimensionID))
{ {
@@ -526,7 +522,7 @@ public class PocketManager
} }
throw new IllegalArgumentException("Cannot register a dimension with ID = " + dimensionID + " because it has already been registered."); throw new IllegalArgumentException("Cannot register a dimension with ID = " + dimensionID + " because it has already been registered.");
} }
InnerDimData dimension = new InnerDimData(dimensionID, parent, isPocket, isDungeon, linkWatcher); InnerDimData dimension = new InnerDimData(dimensionID, parent, type, linkWatcher);
dimensionData.put(dimensionID, dimension); dimensionData.put(dimensionID, dimension);
if (!dimension.isPocketDimension()) if (!dimension.isPocketDimension())
{ {
@@ -538,16 +534,18 @@ public class PocketManager
} }
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
private static NewDimData registerClientDimension(int dimensionID, int rootID) private static NewDimData registerClientDimension(int dimensionID, int rootID, DimensionType type)
{
System.out.println("Registered dim "+dimensionID+" on the client.");
// No need to raise events heres since this code should only run on the client side
// getDimensionData() always handles root dimensions properly, even if the weren't defined before
// SenseiKiwi: I'm a little worried about how getDimensionData will raise {
// No need to raise events heres since this code should only run on the
// client side. createDimensionData() always handles root dimensions
// properly, even if they weren't defined before.
// SenseiKiwi: I'm a little worried about how createDimensionData will
// raise
// an event when it creates any root dimensions... Needs checking later. // an event when it creates any root dimensions... Needs checking later.
InnerDimData root = (InnerDimData) getDimensionData(rootID); InnerDimData root = (InnerDimData) createDimensionData(rootID);
InnerDimData dimension; InnerDimData dimension;
if (rootID != dimensionID) if (rootID != dimensionID)
@@ -555,7 +553,7 @@ public class PocketManager
dimension = dimensionData.get(dimensionID); dimension = dimensionData.get(dimensionID);
if (dimension == null) if (dimension == null)
{ {
dimension = new InnerDimData(dimensionID, root); dimension = new InnerDimData(dimensionID, root, type);
dimensionData.put(dimension.id(), dimension); dimensionData.put(dimension.id(), dimension);
} }
} }
@@ -565,39 +563,56 @@ public class PocketManager
} }
if (dimension.isPocketDimension() && !DimensionManager.isDimensionRegistered(dimension.id())) if (dimension.isPocketDimension() && !DimensionManager.isDimensionRegistered(dimension.id()))
{ {
//Im registering pocket dims here. I *think* we can assume that if its a pocket and we are // Im registering pocket dims here. I *think* we can assume that if
// its a pocket and we are
// registering its dim data, we also need to register it with forge. // registering its dim data, we also need to register it with forge.
//New packet stuff prevents this from always being true, unfortuantly. I send the dimdata to the client when they teleport. // New packet stuff prevents this from always being true,
// unfortuantly. I send the dimdata to the client when they
// teleport.
// Steven // Steven
DimensionManager.registerDimension(dimensionID, mod_pocketDim.properties.PocketProviderID); DimensionManager.registerDimension(dimensionID, mod_pocketDim.properties.PocketProviderID);
} }
return dimension; return dimension;
} }
public static NewDimData getDimensionData(World world)
{
return getDimensionData(world.provider.dimensionId);
}
public static NewDimData getDimensionData(int dimensionID) public static NewDimData getDimensionData(int dimensionID)
{ {
//Retrieve the data for a dimension. If we don't have a record for that dimension, return PocketManager.dimensionData.get(dimensionID);
//assume it's a non-pocket dimension that hasn't been initialized with us before
//and create a NewDimData instance for it.
//Any pocket dimension must be listed with PocketManager to have a dimension ID
//assigned, so it's safe to assume that any unknown dimensions don't belong to us.
//FIXME: What's the point of this condition? Most calls to this function will crash anyway! ~SenseiKiwi
if(PocketManager.dimensionData == null)
{
System.out.println("Something odd happend during shutdown");
return null;
} }
public static NewDimData getDimensionData(World dimension)
{
return PocketManager.dimensionData.get(dimension.provider.dimensionId);
}
public static NewDimData createDimensionData(World world)
{
return createDimensionData(world.provider.dimensionId);
}
public static NewDimData createDimensionDataDangerously(int dimensionID)
{
// Same as createDimensionData(int), but public. Meant to discourage
// anyone from
// using it unless absolutely needed! We'll probably phase this out
// eventually.
return createDimensionData(dimensionID);
}
protected static NewDimData createDimensionData(int dimensionID)
{
// Retrieve the data for a dimension. If we don't have a record for that
// dimension,
// assume it's a non-pocket dimension that hasn't been initialized with
// us before
// and create a NewDimData instance for it.
NewDimData dimension = PocketManager.dimensionData.get(dimensionID); NewDimData dimension = PocketManager.dimensionData.get(dimensionID);
// if we do not have a record of it, then it must be a root
if (dimension == null) if (dimension == null)
{ {
dimension = registerDimension(dimensionID, null, false, false); dimension = registerDimension(dimensionID, null, DimensionType.ROOT);
} }
return dimension; return dimension;
} }
@@ -621,9 +636,9 @@ public class PocketManager
throw new IllegalStateException("Pocket dimensions have already been unloaded!"); throw new IllegalStateException("Pocket dimensions have already been unloaded!");
} }
save();
unregisterPockets(); unregisterPockets();
dimensionData = null; dimensionData = null;
personalPocketsMapping = null;
rootDimensions = null; rootDimensions = null;
isLoaded = false; isLoaded = false;
isConnected = false; isConnected = false;
@@ -646,20 +661,19 @@ public class PocketManager
{ {
return dimension.getLink(x, y, z); return dimension.getLink(x, y, z);
} }
else
{
return null; return null;
} }
}
public static boolean isBlackListed(int dimensionID) public static boolean isBlackListed(int dimensionID)
{ {
return PocketManager.dimensionIDBlackList.contains(dimensionID); return PocketManager.dimensionIDBlackList.contains(dimensionID);
} }
public static void registerDimWatcher(IUpdateWatcher<ClientDimData> watcher) public static void registerDimWatcher(IUpdateWatcher<ClientDimData> watcher)
{ {
getDimwatcher().registerReceiver(watcher); getDimwatcher().registerReceiver(watcher);
} }
public static boolean unregisterDimWatcher(IUpdateWatcher<ClientDimData> watcher) public static boolean unregisterDimWatcher(IUpdateWatcher<ClientDimData> watcher)
{ {
return getDimwatcher().unregisterReceiver(watcher); return getDimwatcher().unregisterReceiver(watcher);
@@ -682,7 +696,8 @@ public class PocketManager
public static void writePacket(DataOutputStream output) throws IOException public static void writePacket(DataOutputStream output) throws IOException
{ {
// Write a very compact description of our dimensions and links to be sent to a client // Write a very compact description of our dimensions and links to be
// sent to a client
Compactor.write(dimensionData.values(), output); Compactor.write(dimensionData.values(), output);
} }
@@ -700,6 +715,7 @@ public class PocketManager
DimensionManager.registerDimension(dimID, DDProperties.instance().PocketProviderID); DimensionManager.registerDimension(dimID, DDProperties.instance().PocketProviderID);
} }
} }
public static void readPacket(DataInputStream input) throws IOException public static void readPacket(DataInputStream input) throws IOException
{ {
// TODO- figure out why this is getting called so frequently // TODO- figure out why this is getting called so frequently
@@ -715,9 +731,6 @@ public class PocketManager
load(); load();
Compactor.readDimensions(input, new DimRegistrationCallback()); Compactor.readDimensions(input, new DimRegistrationCallback());
// Register pocket dimensions
DDProperties properties = DDProperties.instance();
isLoaded = true; isLoaded = true;
isLoading = false; isLoading = false;
isConnected = true; isConnected = true;
@@ -727,4 +740,29 @@ public class PocketManager
{ {
return dimWatcher; return dimWatcher;
} }
public static UpdateWatcherProxy<ClientLinkData> getLinkWatcher()
{
return linkWatcher;
}
public static NewDimData getPersonalDimensionForPlayer(String name)
{
if (personalPocketsMapping.containsKey(name))
{
return personalPocketsMapping.get(name);
}
return null;
}
public static void setPersonalPocketsMapping(HashMap<String, NewDimData> ppMap)
{
personalPocketsMapping = ppMap;
}
public static HashMap<String, NewDimData> getPersonalPocketMapping()
{
// TODO Auto-generated method stub
return personalPocketsMapping;
}
} }

View File

@@ -9,18 +9,17 @@ import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Random; import java.util.Random;
import java.util.TreeMap; import java.util.TreeMap;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.TileEntitySign; import net.minecraft.tileentity.TileEntitySign;
import net.minecraft.world.World; import net.minecraft.world.World;
import StevenDimDoors.mod_pocketDim.DDProperties;
import StevenDimDoors.mod_pocketDim.Point3D; import StevenDimDoors.mod_pocketDim.Point3D;
import StevenDimDoors.mod_pocketDim.blocks.IDimDoor; import StevenDimDoors.mod_pocketDim.blocks.IDimDoor;
import StevenDimDoors.mod_pocketDim.config.DDProperties;
import StevenDimDoors.mod_pocketDim.core.DimLink; import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.LinkTypes; import StevenDimDoors.mod_pocketDim.core.LinkType;
import StevenDimDoors.mod_pocketDim.core.NewDimData; import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager; import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.schematic.BlockRotator; import StevenDimDoors.mod_pocketDim.schematic.BlockRotator;
@@ -162,7 +161,7 @@ public class DungeonSchematic extends Schematic {
applyFilter(standardizer); applyFilter(standardizer);
} }
private Map<Short, Short> getAssignedToStandardIDMapping(DDProperties properties) private static Map<Short, Short> getAssignedToStandardIDMapping(DDProperties properties)
{ {
//If we ever need this broadly or support other mods, this should be moved to a separate class //If we ever need this broadly or support other mods, this should be moved to a separate class
TreeMap<Short, Short> mapping = new TreeMap<Short, Short>(); TreeMap<Short, Short> mapping = new TreeMap<Short, Short>();
@@ -184,11 +183,11 @@ public class DungeonSchematic extends Schematic {
{ {
if (notifyClients) if (notifyClients)
{ {
copyToWorld(world, pocketCenter, targetOrientation, entryLink, random, properties, new WorldBlockSetter(false, true)); copyToWorld(world, pocketCenter, targetOrientation, entryLink, random, properties, new WorldBlockSetter(false, true, false));
} }
else else
{ {
copyToWorld(world, pocketCenter, targetOrientation, entryLink, random, properties, new ChunkBlockSetter()); copyToWorld(world, pocketCenter, targetOrientation, entryLink, random, properties, new ChunkBlockSetter(false));
} }
} }
@@ -247,7 +246,7 @@ public class DungeonSchematic extends Schematic {
world.setBlockTileEntity(pocketPoint.getX(), pocketPoint.getY(), pocketPoint.getZ(), TileEntity.createAndLoadEntity(tileTag)); world.setBlockTileEntity(pocketPoint.getX(), pocketPoint.getY(), pocketPoint.getZ(), TileEntity.createAndLoadEntity(tileTag));
} }
setUpDungeon(PocketManager.getDimensionData(world), world, pocketCenter, turnAngle, entryLink, random, properties, blockSetter); setUpDungeon(PocketManager.createDimensionData(world), world, pocketCenter, turnAngle, entryLink, random, properties, blockSetter);
} }
private void setUpDungeon(NewDimData dimension, World world, Point3D pocketCenter, int turnAngle, DimLink entryLink, Random random, DDProperties properties, IBlockSetter blockSetter) private void setUpDungeon(NewDimData dimension, World world, Point3D pocketCenter, int turnAngle, DimLink entryLink, Random random, DDProperties properties, IBlockSetter blockSetter)
@@ -322,10 +321,10 @@ public class DungeonSchematic extends Schematic {
private static void createEntranceReverseLink(World world, NewDimData dimension, Point3D pocketCenter, DimLink entryLink) private static void createEntranceReverseLink(World world, NewDimData dimension, Point3D pocketCenter, DimLink entryLink)
{ {
int orientation = world.getBlockMetadata(pocketCenter.getX(), pocketCenter.getY() - 1, pocketCenter.getZ()); int orientation = world.getBlockMetadata(pocketCenter.getX(), pocketCenter.getY() - 1, pocketCenter.getZ());
DimLink reverseLink = dimension.createLink(pocketCenter.getX(), pocketCenter.getY(), pocketCenter.getZ(), LinkTypes.REVERSE, orientation); DimLink reverseLink = dimension.createLink(pocketCenter.getX(), pocketCenter.getY(), pocketCenter.getZ(), LinkType.REVERSE, orientation);
Point4D destination = entryLink.source(); Point4D destination = entryLink.source();
NewDimData prevDim = PocketManager.getDimensionData(destination.getDimension()); NewDimData prevDim = PocketManager.getDimensionData(destination.getDimension());
prevDim.setDestination(reverseLink, destination.getX(), destination.getY(), destination.getZ()); prevDim.setLinkDestination(reverseLink, destination.getX(), destination.getY(), destination.getZ());
initDoorTileEntity(world, pocketCenter); initDoorTileEntity(world, pocketCenter);
} }
@@ -335,7 +334,7 @@ public class DungeonSchematic extends Schematic {
Point3D location = point.clone(); Point3D location = point.clone();
BlockRotator.transformPoint(location, entrance, rotation, pocketCenter); BlockRotator.transformPoint(location, entrance, rotation, pocketCenter);
int orientation = world.getBlockMetadata(location.getX(), location.getY() - 1, location.getZ()); int orientation = world.getBlockMetadata(location.getX(), location.getY() - 1, location.getZ());
dimension.createLink(location.getX(), location.getY(), location.getZ(), LinkTypes.DUNGEON_EXIT, orientation); dimension.createLink(location.getX(), location.getY(), location.getZ(), LinkType.DUNGEON_EXIT, orientation);
//Replace the sandstone block under the exit door with the same block as the one underneath it //Replace the sandstone block under the exit door with the same block as the one underneath it
int x = location.getX(); int x = location.getX();
int y = location.getY() - 3; int y = location.getY() - 3;
@@ -356,7 +355,7 @@ public class DungeonSchematic extends Schematic {
BlockRotator.transformPoint(location, entrance, rotation, pocketCenter); BlockRotator.transformPoint(location, entrance, rotation, pocketCenter);
int orientation = world.getBlockMetadata(location.getX(), location.getY() - 1, location.getZ()); int orientation = world.getBlockMetadata(location.getX(), location.getY() - 1, location.getZ());
dimension.createLink(location.getX(), location.getY(), location.getZ(), LinkTypes.DUNGEON, orientation); dimension.createLink(location.getX(), location.getY(), location.getZ(), LinkType.DUNGEON, orientation);
initDoorTileEntity(world, location); initDoorTileEntity(world, location);
} }

View File

@@ -12,7 +12,7 @@ import net.minecraft.tileentity.TileEntityChest;
import net.minecraft.tileentity.TileEntityDispenser; import net.minecraft.tileentity.TileEntityDispenser;
import net.minecraft.world.World; import net.minecraft.world.World;
import StevenDimDoors.mod_pocketDim.DDLoot; import StevenDimDoors.mod_pocketDim.DDLoot;
import StevenDimDoors.mod_pocketDim.DDProperties; import StevenDimDoors.mod_pocketDim.config.DDProperties;
import StevenDimDoors.mod_pocketDim.schematic.WorldOperation; import StevenDimDoors.mod_pocketDim.schematic.WorldOperation;
public class FillContainersOperation extends WorldOperation public class FillContainersOperation extends WorldOperation
@@ -20,8 +20,8 @@ public class FillContainersOperation extends WorldOperation
private Random random; private Random random;
private DDProperties properties; private DDProperties properties;
private static final int GRAVE_CHEST_CHANCE = 100; private static final int GRAVE_CHEST_CHANCE = 1;
private static final int MAX_GRAVE_CHEST_CHANCE = 700; private static final int MAX_GRAVE_CHEST_CHANCE = 6;
public FillContainersOperation(Random random, DDProperties properties) public FillContainersOperation(Random random, DDProperties properties)
{ {
@@ -57,16 +57,6 @@ public class FillContainersOperation extends WorldOperation
} }
} }
} }
// Fill dispensers
if (tileEntity instanceof TileEntityDispenser)
{
TileEntityDispenser dispenser = (TileEntityDispenser) tileEntity;
if (isInventoryEmpty(dispenser))
{
dispenser.addItem(new ItemStack(Item.arrow, 64));
}
}
} }
return true; return true;
} }

View File

@@ -21,6 +21,7 @@ public class DungeonPack
//FIXME: Do not release this code as an update without dealing with disowned types! //FIXME: Do not release this code as an update without dealing with disowned types!
private static final int MAX_HISTORY_LENGTH = 30; private static final int MAX_HISTORY_LENGTH = 30;
private static final int MAX_SUBTREE_LIST_SIZE = 30;
private final String name; private final String name;
private final HashMap<String, DungeonType> nameToTypeMapping; private final HashMap<String, DungeonType> nameToTypeMapping;
@@ -122,7 +123,7 @@ public class DungeonPack
} }
} }
public DungeonData getNextDungeon(NewDimData dimension, Random random) public DungeonData getNextDungeon(NewDimData parent, Random random)
{ {
if (allDungeons.isEmpty()) if (allDungeons.isEmpty())
{ {
@@ -135,16 +136,36 @@ public class DungeonPack
//for dungeon packs that can extend arbitrarily deep. We should probably set a reasonable limit anyway. //for dungeon packs that can extend arbitrarily deep. We should probably set a reasonable limit anyway.
int maxSearchLength = config.allowDuplicatesInChain() ? maxRuleLength : MAX_HISTORY_LENGTH; int maxSearchLength = config.allowDuplicatesInChain() ? maxRuleLength : MAX_HISTORY_LENGTH;
ArrayList<DungeonData> history = DungeonHelper.getDungeonChainHistory(dimension, this, maxSearchLength); ArrayList<DungeonData> history = DungeonHelper.getDungeonChainHistory(parent, this, maxSearchLength);
return getNextDungeon(history, random);
ArrayList<DungeonData> subtreeHistory = null;
if (config.getDuplicateSearchLevels() > 0)
{
// Search over (DuplicateSearchLevels - 1); zero means don't search at all,
// one means search only up to the level of the immediate parent, and so on.
// Since we start with the parent, we need to drop the max levels by one.
NewDimData ancestor = DungeonHelper.getAncestor(parent, this, config.getDuplicateSearchLevels() - 1);
if (ancestor != null)
{
subtreeHistory = DungeonHelper.listDungeonsInTree(ancestor, this, MAX_SUBTREE_LIST_SIZE);
}
}
if (subtreeHistory == null)
{
subtreeHistory = new ArrayList<DungeonData>();
}
subtreeHistory = new ArrayList<DungeonData>();
return getNextDungeon(history, subtreeHistory, random);
} }
private DungeonData getNextDungeon(ArrayList<DungeonData> history, Random random) private DungeonData getNextDungeon(ArrayList<DungeonData> history, ArrayList<DungeonData> subtreeHistory, Random random)
{ {
//Extract the dungeon types that have been used from history and convert them into an array of IDs //Extract the dungeon types that have been used from history and convert them into an array of IDs
int index; int index;
int[] typeHistory = new int[history.size()]; int[] typeHistory = new int[history.size()];
HashSet<DungeonData> excludedDungeons = null; HashSet<DungeonData> excludedDungeons = null;
boolean doExclude = !config.allowDuplicatesInChain() || !subtreeHistory.isEmpty();
for (index = 0; index < typeHistory.length; index++) for (index = 0; index < typeHistory.length; index++)
{ {
typeHistory[index] = history.get(index).dungeonType().ID; typeHistory[index] = history.get(index).dungeonType().ID;
@@ -163,9 +184,19 @@ public class DungeonPack
if (nextType != null) if (nextType != null)
{ {
//Initialize the set of excluded dungeons if needed //Initialize the set of excluded dungeons if needed
if (excludedDungeons == null && !config.allowDuplicatesInChain()) if (excludedDungeons == null && doExclude)
{ {
excludedDungeons = new HashSet<DungeonData>(history); if (config.allowDuplicatesInChain())
{
excludedDungeons = new HashSet<DungeonData>(subtreeHistory);
excludedDungeons.addAll(subtreeHistory);
}
else
{
excludedDungeons = new HashSet<DungeonData>(2 * (history.size() + subtreeHistory.size()));
excludedDungeons.addAll(history);
excludedDungeons.addAll(subtreeHistory);
}
} }
//List which dungeons are allowed //List which dungeons are allowed
@@ -267,4 +298,9 @@ public class DungeonPack
WeightedContainer<DungeonData> resultContainer = (WeightedContainer<DungeonData>) WeightedRandom.getRandomItem(random, weights); WeightedContainer<DungeonData> resultContainer = (WeightedContainer<DungeonData>) WeightedRandom.getRandomItem(random, weights);
return (resultContainer != null) ? resultContainer.getData() : null; return (resultContainer != null) ? resultContainer.getData() : null;
} }
@Override
public String toString()
{
return this.name;
}
} }

View File

@@ -11,6 +11,7 @@ public class DungeonPackConfig
private boolean allowPackChangeOut; private boolean allowPackChangeOut;
private boolean distortDoorCoordinates; private boolean distortDoorCoordinates;
private int packWeight; private int packWeight;
private int duplicateSearchLevels;
private ArrayList<DungeonChainRuleDefinition> rules; private ArrayList<DungeonChainRuleDefinition> rules;
public DungeonPackConfig() { } public DungeonPackConfig() { }
@@ -25,6 +26,7 @@ public class DungeonPackConfig
this.allowPackChangeOut = source.allowPackChangeOut; this.allowPackChangeOut = source.allowPackChangeOut;
this.distortDoorCoordinates = source.distortDoorCoordinates; this.distortDoorCoordinates = source.distortDoorCoordinates;
this.packWeight = source.packWeight; this.packWeight = source.packWeight;
this.duplicateSearchLevels = source.duplicateSearchLevels;
this.rules = (source.rules != null) ? (ArrayList<DungeonChainRuleDefinition>) source.rules.clone() : null; this.rules = (source.rules != null) ? (ArrayList<DungeonChainRuleDefinition>) source.rules.clone() : null;
} }
@@ -114,6 +116,16 @@ public class DungeonPackConfig
this.packWeight = packWeight; this.packWeight = packWeight;
} }
public int getDuplicateSearchLevels()
{
return duplicateSearchLevels;
}
public void setDuplicateSearchLevels(int duplicateSearchLevels)
{
this.duplicateSearchLevels = duplicateSearchLevels;
}
public boolean doDistortDoorCoordinates() public boolean doDistortDoorCoordinates()
{ {
return distortDoorCoordinates; return distortDoorCoordinates;

View File

@@ -35,6 +35,8 @@ public class DungeonPackConfigReader extends BaseConfigurationProcessor<DungeonP
private final int DEFAULT_PRODUCT_WEIGHT = 100; private final int DEFAULT_PRODUCT_WEIGHT = 100;
private final int MAX_DUNGEON_PACK_WEIGHT = 10000; private final int MAX_DUNGEON_PACK_WEIGHT = 10000;
private final int MIN_DUNGEON_PACK_WEIGHT = 1; private final int MIN_DUNGEON_PACK_WEIGHT = 1;
private final int MAX_DUPLICATE_SEARCH_LEVELS = 5;
private final int MIN_DUPLICATE_SEARCH_LEVELS = 0;
private final int DEFAULT_DUNGEON_PACK_WEIGHT = 100; private final int DEFAULT_DUNGEON_PACK_WEIGHT = 100;
private final int MAX_CONDITION_LENGTH = 20; private final int MAX_CONDITION_LENGTH = 20;
private final int MAX_PRODUCT_COUNT = MAX_CONDITION_LENGTH; private final int MAX_PRODUCT_COUNT = MAX_CONDITION_LENGTH;
@@ -80,6 +82,7 @@ public class DungeonPackConfigReader extends BaseConfigurationProcessor<DungeonP
config.setAllowPackChangeOut(true); config.setAllowPackChangeOut(true);
config.setDistortDoorCoordinates(false); config.setDistortDoorCoordinates(false);
config.setPackWeight(DEFAULT_DUNGEON_PACK_WEIGHT); config.setPackWeight(DEFAULT_DUNGEON_PACK_WEIGHT);
config.setDuplicateSearchLevels(MIN_DUPLICATE_SEARCH_LEVELS);
//Read the settings section //Read the settings section
if (findSection("Settings", reader)) if (findSection("Settings", reader))
@@ -273,6 +276,18 @@ public class DungeonPackConfigReader extends BaseConfigurationProcessor<DungeonP
valid = false; valid = false;
} }
} }
else if (name.equalsIgnoreCase("DuplicateSearchLevels"))
{
int levels = Integer.parseInt(value);
if (levels >= MIN_DUPLICATE_SEARCH_LEVELS && levels <= MAX_DUPLICATE_SEARCH_LEVELS)
{
config.setDuplicateSearchLevels(levels);
}
else
{
valid = false;
}
}
else else
{ {
valid = false; valid = false;

View File

@@ -45,4 +45,9 @@ public class DungeonType implements Comparable<DungeonType>
final int prime = 2039; final int prime = 2039;
return prime * ID; return prime * ID;
} }
@Override
public String toString()
{
return this.Name+" owned by "+this.Owner;
}
} }

View File

@@ -1,45 +1,89 @@
package StevenDimDoors.mod_pocketDim.helpers; package StevenDimDoors.mod_pocketDim.helpers;
import StevenDimDoors.mod_pocketDim.IChunkLoader;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
import cpw.mods.fml.common.event.FMLServerStartingEvent;
import java.io.File; import java.io.File;
import java.util.List; import java.util.List;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.ChunkCoordIntPair;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.common.DimensionManager; import net.minecraftforge.common.DimensionManager;
import net.minecraftforge.common.ForgeChunkManager; import net.minecraftforge.common.ForgeChunkManager;
import net.minecraftforge.common.ForgeChunkManager.LoadingCallback; import net.minecraftforge.common.ForgeChunkManager.LoadingCallback;
import net.minecraftforge.common.ForgeChunkManager.Ticket; import net.minecraftforge.common.ForgeChunkManager.Ticket;
import net.minecraftforge.common.ForgeChunkManager.Type;
import StevenDimDoors.experimental.BoundingBox;
import StevenDimDoors.mod_pocketDim.IChunkLoader;
import StevenDimDoors.mod_pocketDim.Point3D;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.world.PocketBuilder;
import cpw.mods.fml.common.event.FMLServerStartingEvent;
public class ChunkLoaderHelper implements LoadingCallback public class ChunkLoaderHelper implements LoadingCallback
{ {
@Override @Override
public void ticketsLoaded(List<Ticket> tickets, World world) public void ticketsLoaded(List<Ticket> tickets, World world)
{ {
for (Ticket ticket : tickets) for (Ticket ticket : tickets)
{ {
int goldDimDoorX = ticket.getModData().getInteger("goldDimDoorX"); boolean loaded = false;
int goldDimDoorY = ticket.getModData().getInteger("goldDimDoorY"); int x = ticket.getModData().getInteger("goldDimDoorX");
int goldDimDoorZ = ticket.getModData().getInteger("goldDimDoorZ"); int y = ticket.getModData().getInteger("goldDimDoorY");
if(world.getBlockId(goldDimDoorX, goldDimDoorY, goldDimDoorZ) != mod_pocketDim.properties.GoldenDimensionalDoorID) int z = ticket.getModData().getInteger("goldDimDoorZ");
if (world.getBlockId(x, y, z) == mod_pocketDim.properties.GoldenDimensionalDoorID)
{
IChunkLoader loader = (IChunkLoader) world.getBlockTileEntity(x, y, z);
if (!loader.isInitialized())
{
loader.initialize(ticket);
loaded = true;
}
}
if (!loaded)
{ {
ForgeChunkManager.releaseTicket(ticket); ForgeChunkManager.releaseTicket(ticket);
} }
else
{
IChunkLoader tile = (IChunkLoader) world.getBlockTileEntity(goldDimDoorX, goldDimDoorY, goldDimDoorZ);
tile.forceChunkLoading(ticket,goldDimDoorX,goldDimDoorZ);
}
} }
} }
public static void loadChunkForcedWorlds(FMLServerStartingEvent event) public static Ticket createTicket(int x, int y, int z, World world)
{
NBTTagCompound data;
Ticket ticket = ForgeChunkManager.requestTicket(mod_pocketDim.instance, world, Type.NORMAL);
if (ticket != null)
{
data = ticket.getModData();
data.setInteger("goldDimDoorX", x);
data.setInteger("goldDimDoorY", y);
data.setInteger("goldDimDoorZ", z);
}
return ticket;
}
public static void forcePocketChunks(NewDimData pocket, Ticket ticket)
{
BoundingBox bounds = PocketBuilder.calculateDefaultBounds(pocket);
Point3D minCorner = bounds.minCorner();
Point3D maxCorner = bounds.maxCorner();
int minX = minCorner.getX() >> 4;
int minZ = minCorner.getZ() >> 4;
int maxX = maxCorner.getX() >> 4;
int maxZ = maxCorner.getZ() >> 4;
int chunkX;
int chunkZ;
for (chunkX = minX; chunkX <= maxX; chunkX++)
{
for (chunkZ = minZ; chunkZ <= maxZ; chunkZ++)
{
ForgeChunkManager.forceChunk(ticket, new ChunkCoordIntPair(chunkX, chunkZ));
}
}
}
public static void loadForcedChunkWorlds(FMLServerStartingEvent event)
{ {
for (NewDimData data : PocketManager.getDimensions()) for (NewDimData data : PocketManager.getDimensions())
{ {

View File

@@ -6,10 +6,10 @@ import java.io.IOException;
import java.util.Collection; import java.util.Collection;
import java.util.Comparator; import java.util.Comparator;
import java.util.HashSet; import java.util.HashSet;
import StevenDimDoors.mod_pocketDim.core.DimLink; import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.DimensionType;
import StevenDimDoors.mod_pocketDim.core.IDimRegistrationCallback; import StevenDimDoors.mod_pocketDim.core.IDimRegistrationCallback;
import StevenDimDoors.mod_pocketDim.core.LinkTypes; import StevenDimDoors.mod_pocketDim.core.LinkType;
import StevenDimDoors.mod_pocketDim.core.NewDimData; import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.util.Point4D; import StevenDimDoors.mod_pocketDim.util.Point4D;
import StevenDimDoors.mod_pocketDim.watcher.ClientLinkData; import StevenDimDoors.mod_pocketDim.watcher.ClientLinkData;
@@ -68,19 +68,20 @@ public class Compactor
{ {
int id = input.readInt(); int id = input.readInt();
int rootID = input.readInt(); int rootID = input.readInt();
DimensionType type = DimensionType.getTypeFromIndex(input.readInt());
if (rootIDs.add(rootID)) if (rootIDs.add(rootID))
{ {
callback.registerDimension(rootID, rootID); callback.registerDimension(rootID, rootID, type);
} }
// Don't check if (id != rootID) - we want to retrieve the reference anyway // Don't check if (id != rootID) - we want to retrieve the reference anyway
NewDimData dimension = callback.registerDimension(id, rootID); NewDimData dimension = callback.registerDimension(id, rootID, type);
int linkCount = input.readInt(); int linkCount = input.readInt();
for (int h = 0; h < linkCount; h++) for (int h = 0; h < linkCount; h++)
{ {
ClientLinkData link = ClientLinkData.read(input); ClientLinkData link = ClientLinkData.read(input);
Point4D source = link.point; Point4D source = link.point;
dimension.createLink(source.getX(), source.getY(), source.getZ(), LinkTypes.CLIENT_SIDE,link.orientation); dimension.createLink(source.getX(), source.getY(), source.getZ(), LinkType.CLIENT,0);
} }
} }
} }

View File

@@ -2,31 +2,33 @@ package StevenDimDoors.mod_pocketDim.helpers;
import java.io.File; import java.io.File;
public class DeleteFolder public class DeleteFolder
{ {
public static boolean deleteFolder(File file) public static boolean deleteFolder(File directory)
{ {
try try
{ {
File[] files = file.listFiles(); File[] contents = directory.listFiles();
if (contents != null)
if(files==null)
{ {
file.delete(); for (File entry : contents)
return true;
}
for(File inFile : files)
{ {
DeleteFolder.deleteFolder(inFile); if (entry.isDirectory())
{
deleteFolder(entry);
} }
else
{
entry.delete();
}
}
}
return directory.delete();
} }
catch (Exception e) catch (Exception e)
{ {
e.printStackTrace(); e.printStackTrace();
return false; return false;
} }
return true;
} }
} }

View File

@@ -4,10 +4,10 @@ import java.io.BufferedReader;
import java.io.File; import java.io.File;
import java.io.FileFilter; import java.io.FileFilter;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
@@ -16,13 +16,12 @@ import java.util.List;
import java.util.Queue; import java.util.Queue;
import java.util.Random; import java.util.Random;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import net.minecraft.util.WeightedRandom; import net.minecraft.util.WeightedRandom;
import net.minecraft.world.World; import net.minecraft.world.World;
import StevenDimDoors.mod_pocketDim.DDProperties;
import StevenDimDoors.mod_pocketDim.mod_pocketDim; import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.config.DDProperties;
import StevenDimDoors.mod_pocketDim.core.DimLink; import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.LinkTypes; import StevenDimDoors.mod_pocketDim.core.LinkType;
import StevenDimDoors.mod_pocketDim.core.NewDimData; import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager; import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.dungeon.DungeonData; import StevenDimDoors.mod_pocketDim.dungeon.DungeonData;
@@ -32,7 +31,6 @@ import StevenDimDoors.mod_pocketDim.dungeon.pack.DungeonPackConfig;
import StevenDimDoors.mod_pocketDim.dungeon.pack.DungeonPackConfigReader; import StevenDimDoors.mod_pocketDim.dungeon.pack.DungeonPackConfigReader;
import StevenDimDoors.mod_pocketDim.dungeon.pack.DungeonType; import StevenDimDoors.mod_pocketDim.dungeon.pack.DungeonType;
import StevenDimDoors.mod_pocketDim.items.ItemDimensionalDoor; import StevenDimDoors.mod_pocketDim.items.ItemDimensionalDoor;
import StevenDimDoors.mod_pocketDim.util.ConfigurationProcessingException;
import StevenDimDoors.mod_pocketDim.util.FileFilters; import StevenDimDoors.mod_pocketDim.util.FileFilters;
import StevenDimDoors.mod_pocketDim.util.WeightedContainer; import StevenDimDoors.mod_pocketDim.util.WeightedContainer;
@@ -47,11 +45,8 @@ public class DungeonHelper
public static final String SCHEMATIC_FILE_EXTENSION = ".schematic"; public static final String SCHEMATIC_FILE_EXTENSION = ".schematic";
private static final String DEFAULT_ERROR_SCHEMATIC_PATH = "/schematics/core/somethingBroke.schematic"; private static final String DEFAULT_ERROR_SCHEMATIC_PATH = "/schematics/core/somethingBroke.schematic";
private static final String DUNGEON_CREATION_GUIDE_SOURCE_PATH = "/mods/DimDoors/text/How_to_add_dungeons.txt"; private static final String DUNGEON_CREATION_GUIDE_SOURCE_PATH = "/assets/dimdoors/text/How_to_add_dungeons.txt";
private static final String RUINS_PACK_PATH = "/schematics/ruins"; private static final String BUNDLED_PACK_BASE_PATH = "/schematics/";
private static final String BUNDLED_RUINS_LIST_PATH = "/schematics/ruins.txt";
private static final String NETHER_PACK_PATH = "/schematics/nether";
private static final String BUNDLED_NETHER_LIST_PATH = "/schematics/nether.txt";
private static final String STANDARD_CONFIG_FILE_NAME = "rules.txt"; private static final String STANDARD_CONFIG_FILE_NAME = "rules.txt";
private static final int NETHER_DIMENSION_ID = -1; private static final int NETHER_DIMENSION_ID = -1;
@@ -158,7 +153,7 @@ public class DungeonHelper
return null; return null;
} }
private void registerDungeonPack(String directory, Iterable<String> schematics, boolean isInternal, boolean verbose, DungeonPackConfigReader reader) private DungeonPack registerDungeonPack(String directory, Iterable<String> schematics, boolean isInternal, boolean verbose, DungeonPackConfigReader reader)
{ {
//First determine the pack's name and validate it //First determine the pack's name and validate it
File packDirectory = new File(directory); File packDirectory = new File(directory);
@@ -187,7 +182,7 @@ public class DungeonHelper
if (config == null) if (config == null)
{ {
System.err.println("Could not load config file: " + configPath); System.err.println("Could not load config file: " + configPath);
return; return null;
} }
//Register the pack //Register the pack
@@ -208,6 +203,7 @@ public class DungeonHelper
{ {
registerDungeon(schematicPath, pack, isInternal, verbose); registerDungeon(schematicPath, pack, isInternal, verbose);
} }
return pack;
} }
public List<DungeonData> getRegisteredDungeons() public List<DungeonData> getRegisteredDungeons()
@@ -231,10 +227,14 @@ public class DungeonHelper
return dungeonPackMapping.get(name.toUpperCase()); return dungeonPackMapping.get(name.toUpperCase());
} }
private DungeonPack getDimDungeonPack(NewDimData data) private DungeonPack getDimDungeonPack(NewDimData dimension)
{ {
// TODO: Drop support for dim-based packs and switch to embedding the pack
// in the link data itself. That would solve the dungeon pre-generation issue.
// Gateways should dictate which packs are being used, not the dimensions.
DungeonPack pack; DungeonPack pack;
DungeonData dungeon = data.dungeon(); DungeonData dungeon = dimension.dungeon();
if (dungeon != null) if (dungeon != null)
{ {
pack = dungeon.dungeonType().Owner; pack = dungeon.dungeonType().Owner;
@@ -247,7 +247,7 @@ public class DungeonHelper
} }
else else
{ {
if (data.id() == NETHER_DIMENSION_ID) if (dimension.id() == NETHER_DIMENSION_ID)
{ {
pack = NetherPack; pack = NetherPack;
} }
@@ -263,7 +263,7 @@ public class DungeonHelper
{ {
//Create a link above the specified position. Link to a new pocket dimension. //Create a link above the specified position. Link to a new pocket dimension.
NewDimData dimension = PocketManager.getDimensionData(world); NewDimData dimension = PocketManager.getDimensionData(world);
DimLink link = dimension.createLink(x, y + 1, z, LinkTypes.POCKET, 3); DimLink link = dimension.createLink(x, y + 1, z, LinkType.POCKET, 3);
//Place a Warp Door linked to that pocket //Place a Warp Door linked to that pocket
ItemDimensionalDoor.placeDoorBlock(world, x, y, z, 3, mod_pocketDim.warpDoor); ItemDimensionalDoor.placeDoorBlock(world, x, y, z, 3, mod_pocketDim.warpDoor);
@@ -433,32 +433,30 @@ public class DungeonHelper
defaultError = new DungeonData(DEFAULT_ERROR_SCHEMATIC_PATH, true, DungeonType.UNKNOWN_TYPE, true, DEFAULT_DUNGEON_WEIGHT); defaultError = new DungeonData(DEFAULT_ERROR_SCHEMATIC_PATH, true, DungeonType.UNKNOWN_TYPE, true, DEFAULT_DUNGEON_WEIGHT);
//Open the list of dungeons packaged with our mod and register their schematics //Open the list of dungeons packaged with our mod and register their schematics
registerBundledPack(BUNDLED_RUINS_LIST_PATH, RUINS_PACK_PATH, "Ruins", reader); RuinsPack = registerBundledPack("Ruins", reader);
RuinsPack = getDungeonPack("Ruins"); NetherPack = registerBundledPack("Nether", reader);
registerBundledPack(BUNDLED_NETHER_LIST_PATH, NETHER_PACK_PATH, "Nether", reader);
NetherPack = getDungeonPack("Nether");
System.out.println("Finished registering bundled dungeon packs"); System.out.println("Finished registering bundled dungeon packs");
} }
private void registerBundledPack(String listPath, String packPath, String name, DungeonPackConfigReader reader) private DungeonPack registerBundledPack(String name, DungeonPackConfigReader reader)
{ {
System.out.println("Registering bundled dungeon pack: " + name); System.out.println("Registering bundled dungeon pack: " + name);
String packPath = BUNDLED_PACK_BASE_PATH + name.toLowerCase();
String listPath = packPath + ".txt";
InputStream listStream = this.getClass().getResourceAsStream(listPath); InputStream listStream = this.getClass().getResourceAsStream(listPath);
// chance of leak?
if (listStream == null) if (listStream == null)
{ {
System.err.println("Unable to open list of bundled dungeon schematics for " + name); throw new IllegalStateException("Failed to open the list of bundled dungeon schematics for " + name);
return;
} }
ArrayList<String> schematics = new ArrayList<String>();
try try
{ {
// Read the list of schematics that come with a bundled pack // Read the list of schematics that come with a bundled pack
BufferedReader listReader = new BufferedReader(new InputStreamReader(listStream)); BufferedReader listReader = new BufferedReader(new InputStreamReader(listStream));
ArrayList<String> schematics = new ArrayList<String>();
String schematicPath = listReader.readLine(); String schematicPath = listReader.readLine();
while (schematicPath != null) while (schematicPath != null)
{ {
@@ -470,15 +468,19 @@ public class DungeonHelper
schematicPath = listReader.readLine(); schematicPath = listReader.readLine();
} }
listReader.close(); listReader.close();
}
catch (IOException e)
{
throw new RuntimeException("An unexpected error occured while trying to read the list of schematics for the " + name + " bundled dungeon pack. This would inevitably cause Dimensional Doors to crash during runtime.", e);
}
// Register the pack // Register the pack
registerDungeonPack(packPath, schematics, true, false, reader); DungeonPack pack = registerDungeonPack(packPath, schematics, true, false, reader);
} if (pack == null)
catch (Exception e)
{ {
System.err.println("An exception occurred while reading the list of bundled dungeon schematics for " + name); throw new RuntimeException("Failed to load the " + name + " bundled dungeon pack. This would inevitably cause Dimensional Doors to crash during runtime.");
e.printStackTrace();
} }
return pack;
} }
public boolean exportDungeon(World world, int centerX, int centerY, int centerZ, String exportPath) public boolean exportDungeon(World world, int centerX, int centerY, int centerZ, String exportPath)
@@ -500,9 +502,9 @@ public class DungeonHelper
} }
} }
public DungeonData selectDungeon(NewDimData dimension, Random random) public DungeonData selectNextDungeon(NewDimData parent, Random random)
{ {
DungeonPack pack = getDimDungeonPack(dimension.parent()); DungeonPack pack = getDimDungeonPack(parent);
DungeonData selection; DungeonData selection;
DungeonPackConfig config; DungeonPackConfig config;
DungeonPack selectedPack; DungeonPack selectedPack;
@@ -517,13 +519,13 @@ public class DungeonHelper
{ {
// Calculate the chance of switching to a different pack type // Calculate the chance of switching to a different pack type
int packSwitchChance; int packSwitchChance;
if (dimension.depth() == 1) if (parent.isPocketDimension())
{ {
packSwitchChance = START_PACK_SWITCH_CHANCE; packSwitchChance = MIN_PACK_SWITCH_CHANCE + parent.packDepth() * PACK_SWITCH_CHANCE_PER_LEVEL;
} }
else else
{ {
packSwitchChance = MIN_PACK_SWITCH_CHANCE + dimension.parent().packDepth() * PACK_SWITCH_CHANCE_PER_LEVEL; packSwitchChance = START_PACK_SWITCH_CHANCE;
} }
// Decide randomly whether to switch packs or not // Decide randomly whether to switch packs or not
@@ -535,7 +537,7 @@ public class DungeonHelper
} }
//Pick the next dungeon //Pick the next dungeon
selection = selectedPack.getNextDungeon(dimension, random); selection = selectedPack.getNextDungeon(parent, random);
} }
catch (Exception e) catch (Exception e)
{ {
@@ -577,8 +579,8 @@ public class DungeonHelper
return selection; return selection;
} }
public Collection<String> getDungeonNames() { public ArrayList<String> getDungeonNames()
{
// Use a HashSet to guarantee that all dungeon names will be distinct. // Use a HashSet to guarantee that all dungeon names will be distinct.
// This shouldn't be necessary if we keep proper lists without repetitions, // This shouldn't be necessary if we keep proper lists without repetitions,
// but it's a fool-proof workaround. // but it's a fool-proof workaround.
@@ -609,59 +611,95 @@ public class DungeonHelper
return names; return names;
} }
public static ArrayList<DungeonData> getDungeonChainHistory(NewDimData dimension, DungeonPack pack, int maxSize) /**
* Lists all of the dungeons found by iterating through a dimension's ancestors. The search stops when a non-dungeon dimension is found or when the pack of a dungeon differs from the specified pack.
* @param start - the first dimension to include in the history
* @param pack - the pack to which any dungeons must belong in order to be listed
* @param maxSize - the maximum number of dungeons that can be listed
* @return a list of dungeons used in a given chain
*/
public static ArrayList<DungeonData> getDungeonChainHistory(NewDimData start, DungeonPack pack, int maxSize)
{ {
if (dimension == null) if (start == null)
{ {
throw new IllegalArgumentException("dimension cannot be null."); throw new IllegalArgumentException("dimension cannot be null.");
} }
if(dimension.parent()==null)
{
return new ArrayList<DungeonData>();
}
int count = 0; int count = 0;
NewDimData tail = dimension.parent(); NewDimData current = start;
DungeonData dungeon = tail.dungeon(); DungeonData dungeon = current.dungeon();
ArrayList<DungeonData> history = new ArrayList<DungeonData>(); ArrayList<DungeonData> history = new ArrayList<DungeonData>();
while (count < maxSize && dungeon != null && dungeon.dungeonType().Owner == pack) while (count < maxSize && dungeon != null && dungeon.dungeonType().Owner == pack)
{ {
history.add(dungeon); history.add(dungeon);
tail = tail.parent(); current = current.parent();
dungeon = tail.dungeon(); dungeon = current.dungeon();
count++; count++;
} }
return history; return history;
} }
public static ArrayList<DungeonData> getFlatDungeonTree(NewDimData dimension, int maxSize) /**
* Performs a breadth-first listing of all dungeons rooted at a specified dimension. Only dungeons from the specified pack will be included.
* @param root - the pocket dimension that serves as the root for the dungeon tree
* @param pack - the pack to which any dungeons must belong in order to be listed
* @param maxSize - the maximum number of dungeons that can be listed
* @return a list of the dungeons used in a given dungeon tree
*/
public static ArrayList<DungeonData> listDungeonsInTree(NewDimData root, DungeonPack pack, int maxSize)
{ {
NewDimData root = dimension; int count = 0;
NewDimData current;
DungeonData dungeon;
ArrayList<DungeonData> dungeons = new ArrayList<DungeonData>(); ArrayList<DungeonData> dungeons = new ArrayList<DungeonData>();
Queue<NewDimData> pendingDimensions = new LinkedList<NewDimData>(); Queue<NewDimData> pendingDimensions = new LinkedList<NewDimData>();
if (root.dungeon() == null)
{
return dungeons;
}
pendingDimensions.add(root); pendingDimensions.add(root);
// Perform a breadth-first search through the dungeon graph
while (dungeons.size() < maxSize && !pendingDimensions.isEmpty()) while (dungeons.size() < maxSize && !pendingDimensions.isEmpty())
{ {
NewDimData current = pendingDimensions.remove(); current = pendingDimensions.remove();
dungeon = current.dungeon();
// Check that this is a dungeon, and if so, that it belongs to the pack that we want
if (dungeon != null && dungeon.dungeonType().Owner == pack)
{
dungeons.add(dungeon);
// Add all child dungeons for checking later
for (NewDimData child : current.children()) for (NewDimData child : current.children())
{ {
if (child.dungeon() != null)
{
dungeons.add(child.dungeon());
pendingDimensions.add(child); pendingDimensions.add(child);
} }
if (dungeons.size() == maxSize) }
}
return dungeons;
}
/**
* Gets the highest ancestor of a dimension with a dungeon that belongs to the specified pack.
* @param dimension - the first dimension to include in the search
* @param pack - the pack to which the ancestors must belong
* @param maxLevels - the maximum number of ancestors to check
* @return the highest ancestor that belongs to the specified pack within the specified levels, or <code>null</code> if none exists
*/
public static NewDimData getAncestor(NewDimData dimension, DungeonPack pack, int maxLevels)
{
// Find the ancestor of a dimension located a specified number of levels up.
NewDimData parent = dimension;
NewDimData current = null;
// We solve this inductively. We begin with null as the first valid ancestor,
// like a kind of virtual child dimension. Then "current" references the
// highest valid ancestor found so far and "parent" references its parent
for (int levels = 0; levels <= maxLevels; levels++)
{
if (parent == null || parent.dungeon() == null ||
parent.dungeon().dungeonType().Owner != pack)
{ {
break; break;
} }
} current = parent;
} parent = parent.parent();
return dungeons; }
return current;
} }
} }

View File

@@ -0,0 +1,6 @@
package StevenDimDoors.mod_pocketDim.helpers;
public class PersonalPocketHelper
{
}

View File

@@ -214,13 +214,10 @@ public class yCoordHelper
for (int dx = -1; dx <= 1; dx++) for (int dx = -1; dx <= 1; dx++)
{ {
for (int dz = -1; dz <= 1; dz++) for (int dz = -1; dz <= 1; dz++)
{
if (!provider.chunkExists(chunkX + dx, chunkZ + dz))
{ {
provider.loadChunk(chunkX, chunkZ); provider.loadChunk(chunkX, chunkZ);
} }
} }
}
return target; return target;
} }

View File

@@ -1,34 +1,53 @@
package StevenDimDoors.mod_pocketDim.items; package StevenDimDoors.mod_pocketDim.items;
import java.util.HashMap;
import java.util.List; import java.util.List;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.material.Material; import net.minecraft.block.material.Material;
import net.minecraft.client.renderer.texture.IconRegister; import net.minecraft.client.renderer.texture.IconRegister;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.item.Item;
import net.minecraft.item.ItemDoor; import net.minecraft.item.ItemDoor;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.MathHelper; import net.minecraft.util.MathHelper;
import net.minecraft.util.MovingObjectPosition; import net.minecraft.util.MovingObjectPosition;
import net.minecraft.util.Vec3;
import net.minecraft.world.World; import net.minecraft.world.World;
import StevenDimDoors.mod_pocketDim.DDProperties;
import StevenDimDoors.mod_pocketDim.mod_pocketDim; import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.blocks.BaseDimDoor;
import StevenDimDoors.mod_pocketDim.config.DDProperties;
import StevenDimDoors.mod_pocketDim.core.DimLink; import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.PocketManager; import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.tileentities.TileEntityDimDoor; import StevenDimDoors.mod_pocketDim.tileentities.TileEntityDimDoor;
public abstract class BaseItemDoor extends ItemDoor public abstract class BaseItemDoor extends ItemDoor
{ {
// Maps non-dimensional door items to their corresponding dimensional door item
// Also maps dimensional door items to themselves for simplicity
private static HashMap<ItemDoor, BaseItemDoor> doorItemMapping = new HashMap<ItemDoor, BaseItemDoor>();
private static DDProperties properties = null; private static DDProperties properties = null;
public BaseItemDoor(int itemID, Material material) /**
* door represents the non-dimensional door this item is associated with. Leave null for none.
* @param itemID
* @param material
* @param door
*/
public BaseItemDoor(int itemID, Material material, ItemDoor vanillaDoor)
{ {
super(itemID, material); super(itemID, material);
this.setMaxStackSize(64); this.setMaxStackSize(64);
this.setCreativeTab(mod_pocketDim.dimDoorsCreativeTab); this.setCreativeTab(mod_pocketDim.dimDoorsCreativeTab);
if (properties == null) if (properties == null)
properties = DDProperties.instance(); properties = DDProperties.instance();
doorItemMapping.put(this, this);
if (vanillaDoor != null)
{
doorItemMapping.put(vanillaDoor, this);
}
} }
@Override @Override
@@ -41,12 +60,78 @@ public abstract class BaseItemDoor extends ItemDoor
@Override @Override
public abstract void addInformation(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, List par3List, boolean par4); public abstract void addInformation(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, List par3List, boolean par4);
@Override /**
public abstract boolean onItemUse(ItemStack stack, EntityPlayer player, World world, int x, int y, int z, int side, float hitX, float hitY, float hitZ); * Overriden in subclasses to specify which door block that door item will
* place
*
* @return
*/
protected abstract BaseDimDoor getDoorBlock();
public static boolean tryItemUse(Block doorBlock, ItemStack stack, EntityPlayer player, World world, int x, int y, int z, int side, boolean requireLink, boolean reduceStack) /**
* Overriden here to remove vanilla block placement functionality from
* dimensional doors, we handle this in the EventHookContainer
*/
@Override
public boolean onItemUse(ItemStack stack, EntityPlayer player, World world, int x, int y, int z, int side, float hitX, float hitY, float hitZ)
{ {
// Only place doors on top of blocks - check if we're targeting the top side return false;
}
/**
* Tries to place a door as a dimensional door
*
* @param stack
* @param player
* @param world
* @param x
* @param y
* @param z
* @param side
* @return
*/
public static boolean tryToPlaceDoor(ItemStack stack, EntityPlayer player, World world, int x, int y, int z, int side)
{
if (world.isRemote)
{
return false;
}
// Retrieve the actual door type that we want to use here.
// It's okay if stack isn't an ItemDoor. In that case, the lookup will
// return null, just as if the item was an unrecognized door type.
BaseItemDoor mappedItem = doorItemMapping.get(stack.getItem());
if (mappedItem == null)
{
return false;
}
BaseDimDoor doorBlock = mappedItem.getDoorBlock();
if (BaseItemDoor.placeDoorOnBlock(doorBlock, stack, player, world, x, y, z, side))
{
return true;
}
return BaseItemDoor.placeDoorOnRift(doorBlock, world, player, stack);
}
/**
* try to place a door block on a block
* @param doorBlock
* @param stack
* @param player
* @param world
* @param x
* @param y
* @param z
* @param side
* @return
*/
public static boolean placeDoorOnBlock(Block doorBlock, ItemStack stack, EntityPlayer player, World world, int x, int y, int z, int side)
{
if (world.isRemote)
{
return false;
}
// Only place doors on top of blocks - check if we're targeting the top
// side
if (side == 1 && !world.isRemote) if (side == 1 && !world.isRemote)
{ {
int blockID = world.getBlockId(x, y, z); int blockID = world.getBlockId(x, y, z);
@@ -58,14 +143,14 @@ public abstract class BaseItemDoor extends ItemDoor
} }
} }
if (canPlace(world, x, y, z) && canPlace(world, x, y + 1, z) && if (canPlace(world, x, y, z) && canPlace(world, x, y + 1, z) && player.canPlayerEdit(x, y, z, side, stack)
player.canPlayerEdit(x, y, z, side, stack) && player.canPlayerEdit(x, y + 1, z, side, stack) && && (player.canPlayerEdit(x, y + 1, z, side, stack) && stack.stackSize > 0)
(!requireLink || PocketManager.getLink(x, y + 1, z, world) != null)&&stack.stackSize>0) &&((stack.getItem() instanceof BaseItemDoor) || PocketManager.getLink(x, y + 1, z, world) != null))
{ {
int orientation = MathHelper.floor_double((player.rotationYaw + 180.0F) * 4.0F / 360.0F - 0.5D) & 3; int orientation = MathHelper.floor_double((player.rotationYaw + 180.0F) * 4.0F / 360.0F - 0.5D) & 3;
placeDoorBlock(world, x, y, z, orientation, doorBlock); placeDoorBlock(world, x, y, z, orientation, doorBlock);
if (!player.capabilities.isCreativeMode && reduceStack) if (!player.capabilities.isCreativeMode)
{ {
stack.stackSize--; stack.stackSize--;
} }
@@ -75,17 +160,23 @@ public abstract class BaseItemDoor extends ItemDoor
return false; return false;
} }
@Override /**
public abstract ItemStack onItemRightClick(ItemStack stack, World world, EntityPlayer player); * uses a raytrace to try and place a door on a rift
*
public boolean tryPlacingDoor(Block doorBlock, World world, EntityPlayer player, ItemStack item) * @param doorBlock
* @param world
* @param player
* @param stack
* @return
*/
public static boolean placeDoorOnRift(Block doorBlock, World world, EntityPlayer player, ItemStack stack)
{ {
if (world.isRemote) if (world.isRemote)
{ {
return false; return false;
} }
MovingObjectPosition hit = getMovingObjectPositionFromPlayer(player.worldObj, player, true); MovingObjectPosition hit = BaseItemDoor.doRayTrace(player.worldObj, player, true);
if (hit != null) if (hit != null)
{ {
if (world.getBlockId(hit.blockX, hit.blockY, hit.blockZ) == properties.RiftBlockID) if (world.getBlockId(hit.blockX, hit.blockY, hit.blockZ) == properties.RiftBlockID)
@@ -97,16 +188,20 @@ public abstract class BaseItemDoor extends ItemDoor
int y = hit.blockY; int y = hit.blockY;
int z = hit.blockZ; int z = hit.blockZ;
if (player.canPlayerEdit(x, y, z, hit.sideHit, item) && player.canPlayerEdit(x, y - 1, z, hit.sideHit, item)) if (player.canPlayerEdit(x, y, z, hit.sideHit, stack) && player.canPlayerEdit(x, y - 1, z, hit.sideHit, stack))
{ {
if (canPlace(world, x, y, z) && canPlace(world, x, y - 1, z)) if (canPlace(world, x, y, z) && canPlace(world, x, y - 1, z))
{ {
int orientation = MathHelper.floor_double(((player.rotationYaw + 180.0F) * 4.0F / 360.0F) - 0.5D) & 3; int orientation = MathHelper.floor_double(((player.rotationYaw + 180.0F) * 4.0F / 360.0F) - 0.5D) & 3;
placeDoorBlock(world, x, y - 1, z, orientation, doorBlock); placeDoorBlock(world, x, y - 1, z, orientation, doorBlock);
if(!(item.getItem() instanceof BaseItemDoor)) if (!(stack.getItem() instanceof BaseItemDoor))
{ {
((TileEntityDimDoor) world.getBlockTileEntity(x, y, z)).hasGennedPair = true; ((TileEntityDimDoor) world.getBlockTileEntity(x, y, z)).hasGennedPair = true;
} }
if (!player.capabilities.isCreativeMode)
{
stack.stackSize--;
}
return true; return true;
} }
} }
@@ -122,4 +217,38 @@ public abstract class BaseItemDoor extends ItemDoor
return (id == properties.RiftBlockID || id == 0 || Block.blocksList[id].blockMaterial.isReplaceable()); return (id == properties.RiftBlockID || id == 0 || Block.blocksList[id].blockMaterial.isReplaceable());
} }
/**
* Copied from minecraft Item.class
* TODO we probably can improve this
*
* @param par1World
* @param par2EntityPlayer
* @param par3
* @return
*/
protected static MovingObjectPosition doRayTrace(World par1World, EntityPlayer par2EntityPlayer, boolean par3)
{
float f = 1.0F;
float f1 = par2EntityPlayer.prevRotationPitch + (par2EntityPlayer.rotationPitch - par2EntityPlayer.prevRotationPitch) * f;
float f2 = par2EntityPlayer.prevRotationYaw + (par2EntityPlayer.rotationYaw - par2EntityPlayer.prevRotationYaw) * f;
double d0 = par2EntityPlayer.prevPosX + (par2EntityPlayer.posX - par2EntityPlayer.prevPosX) * (double) f;
double d1 = par2EntityPlayer.prevPosY + (par2EntityPlayer.posY - par2EntityPlayer.prevPosY) * (double) f
+ (double) (par1World.isRemote ? par2EntityPlayer.getEyeHeight() - par2EntityPlayer.getDefaultEyeHeight() : par2EntityPlayer.getEyeHeight());
double d2 = par2EntityPlayer.prevPosZ + (par2EntityPlayer.posZ - par2EntityPlayer.prevPosZ) * (double) f;
Vec3 vec3 = par1World.getWorldVec3Pool().getVecFromPool(d0, d1, d2);
float f3 = MathHelper.cos(-f2 * 0.017453292F - (float) Math.PI);
float f4 = MathHelper.sin(-f2 * 0.017453292F - (float) Math.PI);
float f5 = -MathHelper.cos(-f1 * 0.017453292F);
float f6 = MathHelper.sin(-f1 * 0.017453292F);
float f7 = f4 * f5;
float f8 = f3 * f5;
double d3 = 5.0D;
if (par2EntityPlayer instanceof EntityPlayerMP)
{
d3 = ((EntityPlayerMP) par2EntityPlayer).theItemInWorldManager.getBlockReachDistance();
}
Vec3 vec31 = vec3.addVector((double) f7 * d3, (double) f6 * d3, (double) f8 * d3);
return par1World.rayTraceBlocks_do_do(vec3, vec31, par3, !par3);
}
} }

View File

@@ -7,7 +7,7 @@ import StevenDimDoors.mod_pocketDim.mod_pocketDim;
public class ItemBlockDimWall extends ItemBlock public class ItemBlockDimWall extends ItemBlock
{ {
private final static String[] subNames = {"Fabric of Reality", "Ancient Fabric"}; private final static String[] subNames = {"Fabric of Reality", "Ancient Fabric" , "Altered Fabric"};
public ItemBlockDimWall(int par1) public ItemBlockDimWall(int par1)
{ {

View File

@@ -0,0 +1,213 @@
package StevenDimDoors.mod_pocketDim.items;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.block.Block;
import net.minecraft.client.renderer.texture.IconRegister;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.EnumAction;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.util.EnumMovingObjectType;
import net.minecraft.util.MovingObjectPosition;
import net.minecraft.util.StatCollector;
import net.minecraft.world.World;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.blocks.IDimDoor;
import StevenDimDoors.mod_pocketDim.core.DDLock;
import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.watcher.ClientLinkData;
public class ItemDDKey extends Item
{
public static final int TIME_TO_UNLOCK = 30;
public ItemDDKey(int itemID)
{
super(itemID);
this.setCreativeTab(mod_pocketDim.dimDoorsCreativeTab);
this.setMaxStackSize(1);
}
public void onCreated(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer)
{
}
public void addInformation(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, List par3List, boolean par4)
{
if (DDLock.hasCreatedLock(par1ItemStack))
{
par3List.add("Bound");
}
else
{
par3List.add("Unbound");
}
}
@Override
public void registerIcons(IconRegister par1IconRegister)
{
this.itemIcon = par1IconRegister.registerIcon(mod_pocketDim.modid + ":" + this.getUnlocalizedName().replace("item.", ""));
}
@Override
@SideOnly(Side.CLIENT)
public boolean hasEffect(ItemStack par1ItemStack)
{
return !DDLock.hasCreatedLock(par1ItemStack);
}
public boolean onItemUse(ItemStack itemStack, EntityPlayer player, World par3World, int par4, int par5, int par6, int par7, float par8, float par9,
float par10)
{
player.setItemInUse(itemStack, this.getMaxItemUseDuration(itemStack));
return false;
}
public boolean onItemUseFirst(ItemStack itemStack, EntityPlayer player, World world, int x, int y, int z, int side, float playerX, float playerY,
float playerZ)
{
if (world.isRemote)
{
return false;
}
if (player.getItemInUse() != null)
{
return true;
}
int blockID = world.getBlockId(x, y, z);
// make sure we are dealing with a door
if (!(Block.blocksList[blockID] instanceof IDimDoor))
{
return false;
}
DimLink link = PocketManager.getLink(x, y, z, world);
// dont do anything to doors without links
if (link == null)
{
return false;
}
// what to do if the door has a lock already
if (link.hasLock())
{
if (link.doesKeyUnlock(itemStack))
{
if (link.getLockState())
{
world.playSoundAtEntity(player, mod_pocketDim.modid + ":keyUnlock", 1F, 1F);
}
else
{
world.playSoundAtEntity(player, mod_pocketDim.modid + ":keyLock", 1F, 1F);
}
PocketManager.getDimensionData(world).lock(link, !link.getLockState());
PocketManager.getLinkWatcher().update(new ClientLinkData(link));
}
else
{
world.playSoundAtEntity(player, mod_pocketDim.modid + ":doorLocked", 1F, 1F);
}
}
else
{
if (!DDLock.hasCreatedLock(itemStack))
{
world.playSoundAtEntity(player, mod_pocketDim.modid + ":keyLock", 1F, 1F);
PocketManager.getDimensionData(world).createLock(link, itemStack, world.rand.nextInt(Integer.MAX_VALUE));
PocketManager.getLinkWatcher().update(new ClientLinkData(link));
}
}
return false;
}
/**
* Handle removal of locks here
*/
@Override
public void onPlayerStoppedUsing(ItemStack itemStack, World world, EntityPlayer player, int heldTime)
{
int j = this.getMaxItemUseDuration(itemStack) - heldTime;
if (j >= TIME_TO_UNLOCK)
{
//Raytrace to make sure we are still looking at a door
MovingObjectPosition pos = getMovingObjectPositionFromPlayer(player.worldObj, player, true);
if (pos != null && pos.typeOfHit == EnumMovingObjectType.TILE)
{
//make sure we have a link and it has a lock
DimLink link = PocketManager.getLink(pos.blockX, pos.blockY, pos.blockZ, player.worldObj);
if (link != null && link.hasLock())
{
//make sure the given key is able to access the lock
if (link.doesKeyUnlock(itemStack) && !world.isRemote)
{
PocketManager.getDimensionData(world).removeLock(link, itemStack);
world.playSoundAtEntity(player, mod_pocketDim.modid + ":doorLockRemoved", 1F, 1F);
}
}
}
}
player.clearItemInUse();
}
/**
* Raytrace to make sure we are still looking at the right block while preparing to remove the lock
*/
@Override
public void onUsingItemTick(ItemStack stack, EntityPlayer player, int count)
{
// no need to check every tick, twice a second instead
if (count % 10 == 0)
{
MovingObjectPosition pos = getMovingObjectPositionFromPlayer(player.worldObj, player, true);
if (pos != null && pos.typeOfHit == EnumMovingObjectType.TILE)
{
DimLink link = PocketManager.getLink(pos.blockX, pos.blockY, pos.blockZ, player.worldObj);
if (link != null && link.hasLock())
{
if (link.doesKeyUnlock(stack))
{
return;
}
}
}
player.clearItemInUse();
}
}
public EnumAction getItemUseAction(ItemStack par1ItemStack)
{
return EnumAction.bow;
}
public ItemStack onEaten(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer)
{
return par1ItemStack;
}
public int getMaxItemUseDuration(ItemStack par1ItemStack)
{
return 72000;
}
public String getItemStackDisplayName(ItemStack par1ItemStack)
{
return StatCollector.translateToLocal(this.getUnlocalizedName(par1ItemStack));
}
}

View File

@@ -4,15 +4,17 @@ import java.util.List;
import net.minecraft.block.material.Material; import net.minecraft.block.material.Material;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemDoor;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.world.World; import net.minecraft.world.World;
import StevenDimDoors.mod_pocketDim.mod_pocketDim; import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.blocks.BaseDimDoor;
public class ItemDimensionalDoor extends BaseItemDoor public class ItemDimensionalDoor extends BaseItemDoor
{ {
public ItemDimensionalDoor(int itemID, Material material) public ItemDimensionalDoor(int itemID, Material material, ItemDoor door)
{ {
super(itemID, material); super(itemID, material, door);
} }
@SuppressWarnings({ "rawtypes", "unchecked" }) @SuppressWarnings({ "rawtypes", "unchecked" })
@@ -26,23 +28,8 @@ public class ItemDimensionalDoor extends BaseItemDoor
} }
@Override @Override
public ItemStack onItemRightClick(ItemStack stack, World world, EntityPlayer player) protected BaseDimDoor getDoorBlock()
{ {
if (!world.isRemote) return (BaseDimDoor) mod_pocketDim.dimensionalDoor;
{
if (tryPlacingDoor(mod_pocketDim.dimensionalDoor, world, player, stack) &&
!player.capabilities.isCreativeMode)
{
stack.stackSize--;
}
}
return stack;
}
@Override
public boolean onItemUse(ItemStack stack, EntityPlayer player, World world, int x, int y,
int z, int par7, float par8, float par9, float par10)
{
return tryItemUse(mod_pocketDim.dimensionalDoor, stack, player, world, x, y, z, par7, false, true);
} }
} }

View File

@@ -4,19 +4,20 @@ import java.util.List;
import net.minecraft.block.material.Material; import net.minecraft.block.material.Material;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemDoor;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.world.World; import net.minecraft.world.World;
import StevenDimDoors.mod_pocketDim.mod_pocketDim; import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.blocks.BaseDimDoor;
public class ItemGoldDimDoor extends BaseItemDoor public class ItemGoldDimDoor extends BaseItemDoor
{ {
public ItemGoldDimDoor(int itemID, Material material) { public ItemGoldDimDoor(int itemID, Material material, ItemDoor door)
super(itemID, material); {
// TODO Auto-generated constructor stub super(itemID, material, door);
} }
@SuppressWarnings({ "rawtypes", "unchecked" }) @SuppressWarnings({ "rawtypes", "unchecked" })
@Override @Override
public void addInformation(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, List par3List, boolean par4) public void addInformation(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, List par3List, boolean par4)
@@ -27,26 +28,8 @@ public class ItemGoldDimDoor extends BaseItemDoor
} }
@Override @Override
public boolean onItemUse(ItemStack stack, EntityPlayer player, World world, int x, int y, protected BaseDimDoor getDoorBlock()
int z, int par7, float par8, float par9, float par10)
{ {
return tryItemUse(mod_pocketDim.goldenDimensionalDoor, stack, player, world, x, y, z, par7, false, true); return (BaseDimDoor) mod_pocketDim.goldenDimensionalDoor;
}
@Override
public ItemStack onItemRightClick(ItemStack stack, World world, EntityPlayer player)
{
if (!world.isRemote)
{
if (tryPlacingDoor(mod_pocketDim.goldenDimensionalDoor, world, player, stack) &&
!player.capabilities.isCreativeMode)
{
stack.stackSize--;
} }
} }
return stack;
}
}

View File

@@ -15,6 +15,7 @@ public class ItemGoldDoor extends ItemDoor
public ItemGoldDoor(int par1, Material par2Material) public ItemGoldDoor(int par1, Material par2Material)
{ {
super(par1, par2Material); super(par1, par2Material);
this.setMaxStackSize(16);
} }
@Override @Override

View File

@@ -0,0 +1,35 @@
package StevenDimDoors.mod_pocketDim.items;
import java.util.List;
import net.minecraft.block.material.Material;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemDoor;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.blocks.BaseDimDoor;
public class ItemPersonalDoor extends BaseItemDoor
{
public ItemPersonalDoor(int itemID, Material material, ItemDoor door)
{
super(itemID, material, door);
}
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public void addInformation(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, List par3List, boolean par4)
{
par3List.add("Creates a pathway to");
par3List.add("Your personal pocket");
}
@Override
protected BaseDimDoor getDoorBlock()
{
return (BaseDimDoor) mod_pocketDim.personalDimDoor;
}
}

View File

@@ -0,0 +1,58 @@
package StevenDimDoors.mod_pocketDim.items;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.client.renderer.texture.IconRegister;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemDoor;
import net.minecraft.item.ItemStack;
import net.minecraft.util.MathHelper;
import net.minecraft.world.World;
public class ItemQuartzDoor extends ItemDoor
{
public ItemQuartzDoor(int par1, Material par2Material)
{
super(par1, par2Material);
}
@Override
public void registerIcons(IconRegister par1IconRegister)
{
this.itemIcon = par1IconRegister.registerIcon(mod_pocketDim.modid + ":" + this.getUnlocalizedName().replace("item.", ""));
}
@Override
public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, int par5, int par6, int par7, float par8, float par9, float par10)
{
if (par7 != 1)
{
return false;
}
else
{
++par5;
Block block = mod_pocketDim.quartzDoor;
if (par2EntityPlayer.canPlayerEdit(par4, par5, par6, par7, par1ItemStack) && par2EntityPlayer.canPlayerEdit(par4, par5 + 1, par6, par7, par1ItemStack))
{
if (!block.canPlaceBlockAt(par3World, par4, par5, par6))
{
return false;
}
else
{
int i1 = MathHelper.floor_double((par2EntityPlayer.rotationYaw + 180.0F) * 4.0F / 360.0F - 0.5D) & 3;
placeDoorBlock(par3World, par4, par5, par6, i1, block);
--par1ItemStack.stackSize;
return true;
}
}
else
{
return false;
}
}
}
}

View File

@@ -20,8 +20,8 @@ import net.minecraft.util.MathHelper;
import net.minecraft.util.MovingObjectPosition; import net.minecraft.util.MovingObjectPosition;
import net.minecraft.util.Vec3; import net.minecraft.util.Vec3;
import net.minecraft.world.World; import net.minecraft.world.World;
import StevenDimDoors.mod_pocketDim.DDProperties;
import StevenDimDoors.mod_pocketDim.mod_pocketDim; import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.config.DDProperties;
import StevenDimDoors.mod_pocketDim.core.PocketManager; import StevenDimDoors.mod_pocketDim.core.PocketManager;
import com.google.common.collect.Multimap; import com.google.common.collect.Multimap;
import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.Side;
@@ -36,41 +36,9 @@ public class ItemRiftBlade extends ItemSword
super(itemID, EnumToolMaterial.EMERALD); super(itemID, EnumToolMaterial.EMERALD);
this.setCreativeTab(mod_pocketDim.dimDoorsCreativeTab); this.setCreativeTab(mod_pocketDim.dimDoorsCreativeTab);
this.setMaxStackSize(1);
this.setMaxDamage(500);
this.hasSubtypes = false;
this.properties = properties; this.properties = properties;
} }
@Override
@SideOnly(Side.CLIENT)
public boolean isFull3D()
{
return true;
}
@Override
public float getStrVsBlock(ItemStack par1ItemStack, Block par2Block)
{
if (par2Block.blockID == Block.web.blockID)
{
return 15.0F;
}
else
{
Material material = par2Block.blockMaterial;
return material != Material.plants && material != Material.vine && material != Material.coral && material != Material.leaves && material != Material.pumpkin ? 1.0F : 1.5F;
}
}
@Override
public Multimap getItemAttributeModifiers()
{
Multimap multimap = super.getItemAttributeModifiers();
multimap.put(SharedMonsterAttributes.attackDamage.getAttributeUnlocalizedName(), new AttributeModifier(field_111210_e, "Weapon modifier", (double)7, 0));
return multimap;
}
@Override @Override
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public boolean hasEffect(ItemStack par1ItemStack) public boolean hasEffect(ItemStack par1ItemStack)
@@ -78,13 +46,6 @@ public class ItemRiftBlade extends ItemSword
return true; return true;
} }
@Override
public boolean hitEntity(ItemStack par1ItemStack, EntityLivingBase par2EntityLiving, EntityLivingBase par3EntityLiving)
{
par1ItemStack.damageItem(1, par3EntityLiving);
return true;
}
@Override @Override
public MovingObjectPosition getMovingObjectPositionFromPlayer(World par1World, EntityPlayer par2EntityPlayer, boolean par3) public MovingObjectPosition getMovingObjectPositionFromPlayer(World par1World, EntityPlayer par2EntityPlayer, boolean par3)
{ {
@@ -147,7 +108,7 @@ public class ItemRiftBlade extends ItemSword
if (!world.isRemote) if (!world.isRemote)
{ {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
List<EntityLiving> list = world.getEntitiesWithinAABB(EntityLiving.class, AxisAlignedBB.getBoundingBox(player.posX-8,player.posY-8, player.posZ-8, player.posX+8,player.posY+8, player.posZ+8)); List<EntityLiving> list = world.getEntitiesWithinAABB(EntityLiving.class, AxisAlignedBB.getBoundingBox(player.posX-10,player.posY-10, player.posZ-10, player.posX+10,player.posY+10, player.posZ+10));
list.remove(player); list.remove(player);
for (EntityLiving ent : list) for (EntityLiving ent : list)
@@ -223,8 +184,7 @@ public class ItemRiftBlade extends ItemSword
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public void addInformation(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, List par3List, boolean par4) public void addInformation(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, List par3List, boolean par4)
{ {
par3List.add("Creates temporary doors"); par3List.add("Opens temporary doors on rifts");
par3List.add("on rifts, rotates doors,");
par3List.add("and has a teleport attack."); par3List.add("and has a teleport attack.");
} }
} }

View File

@@ -1,7 +1,6 @@
package StevenDimDoors.mod_pocketDim.items; package StevenDimDoors.mod_pocketDim.items;
import java.util.List; import java.util.List;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.client.renderer.texture.IconRegister; import net.minecraft.client.renderer.texture.IconRegister;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
@@ -14,7 +13,7 @@ import net.minecraftforge.common.DimensionManager;
import StevenDimDoors.mod_pocketDim.mod_pocketDim; import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.blocks.BaseDimDoor; import StevenDimDoors.mod_pocketDim.blocks.BaseDimDoor;
import StevenDimDoors.mod_pocketDim.core.DimLink; import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.LinkTypes; import StevenDimDoors.mod_pocketDim.core.LinkType;
import StevenDimDoors.mod_pocketDim.core.NewDimData; import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager; import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.util.Point4D; import StevenDimDoors.mod_pocketDim.util.Point4D;
@@ -34,12 +33,13 @@ public class ItemRiftSignature extends Item
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
@Override @Override
public boolean hasEffect(ItemStack stack) public boolean hasEffect(ItemStack stack, int pass)
{ {
//Make the item glow if it has one endpoint stored //Make the item glow if it has one endpoint stored
return (stack.getItemDamage() != 0); return (stack.getItemDamage() != 0);
} }
@Override
public void registerIcons(IconRegister par1IconRegister) public void registerIcons(IconRegister par1IconRegister)
{ {
this.itemIcon = par1IconRegister.registerIcon(mod_pocketDim.modid + ":" + this.getUnlocalizedName().replace("item.", "")); this.itemIcon = par1IconRegister.registerIcon(mod_pocketDim.modid + ":" + this.getUnlocalizedName().replace("item.", ""));
@@ -60,50 +60,47 @@ public class ItemRiftSignature extends Item
return false; return false;
} }
y += 2; //Increase y by 2 to place the rift at head level //Increase y by 2 to place the rift at head level
if (!player.canPlayerEdit(x, y, z, side, stack)) int adjustedY = adjustYForSpecialBlocks(world, x, y + 2, z);
if (!player.canPlayerEdit(x, adjustedY, z, side, stack))
{ {
return true; return true;
} }
int adjustedY = adjustYForSpecialBlocks(world,x,y,z);
Point4DOrientation source = getSource(stack); Point4DOrientation source = getSource(stack);
int orientation = MathHelper.floor_double((double) ((player.rotationYaw + 180.0F) * 4.0F / 360.0F) - 0.5D) & 3; int orientation = MathHelper.floor_double(((player.rotationYaw + 180.0F) * 4.0F / 360.0F) - 0.5D) & 3;
if (source != null) if (source != null)
{ {
//The link was used before and already has an endpoint stored. Create links connecting the two endpoints. // The link was used before and already has an endpoint stored.
// Create links connecting the two endpoints.
NewDimData sourceDimension = PocketManager.getDimensionData(source.getDimension()); NewDimData sourceDimension = PocketManager.getDimensionData(source.getDimension());
NewDimData destinationDimension = PocketManager.getDimensionData(world); NewDimData destinationDimension = PocketManager.getDimensionData(world);
DimLink link = sourceDimension.createLink(source.getX(), source.getY(), source.getZ(), LinkTypes.NORMAL,source.getOrientation());
DimLink reverse = destinationDimension.createLink(x, adjustedY, z, LinkTypes.NORMAL,orientation); DimLink link = sourceDimension.createLink(source.getX(), source.getY(), source.getZ(), LinkType.NORMAL,source.getOrientation());
destinationDimension.setDestination(link, x, adjustedY, z); DimLink reverse = destinationDimension.createLink(x, adjustedY, z, LinkType.NORMAL,orientation);
sourceDimension.setDestination(reverse, source.getX(), source.getY(), source.getZ());
destinationDimension.setLinkDestination(link, x, adjustedY, z);
sourceDimension.setLinkDestination(reverse, source.getX(), source.getY(), source.getZ());
// Try placing a rift at the destination point // Try placing a rift at the destination point
if (!mod_pocketDim.blockRift.isBlockImmune(world, x, adjustedY, z)) mod_pocketDim.blockRift.tryPlacingRift(world, x, adjustedY, z);
{
world.setBlock(x, adjustedY, z, mod_pocketDim.blockRift.blockID);
}
//Try placing a rift at the source point, but check if its world is loaded first // Try placing a rift at the source point
// We don't need to check if sourceWorld is null - that's already handled.
World sourceWorld = DimensionManager.getWorld(sourceDimension.id()); World sourceWorld = DimensionManager.getWorld(sourceDimension.id());
if (sourceWorld != null && mod_pocketDim.blockRift.tryPlacingRift(sourceWorld, source.getX(), source.getY(), source.getZ());
!mod_pocketDim.blockRift.isBlockImmune(sourceWorld, source.getX(), source.getY(), source.getZ()))
{
sourceWorld.setBlock(source.getX(), source.getY(), source.getZ(), mod_pocketDim.blockRift.blockID);
}
if (!player.capabilities.isCreativeMode) if (!player.capabilities.isCreativeMode)
{ {
stack.stackSize--; stack.stackSize--;
} }
clearSource(stack); clearSource(stack);
mod_pocketDim.sendChat(player,("Rift Created")); mod_pocketDim.sendChat(player, "Rift Created");
world.playSoundAtEntity(player, mod_pocketDim.modid + ":riftEnd", 0.6f, 1); world.playSoundAtEntity(player, mod_pocketDim.modid + ":riftEnd", 0.6f, 1);
} }
else else
{ {
//The link signature has not been used. Store its current target as the first location. //The link signature has not been used. Store its current target as the first location.
setSource(stack, x, adjustedY, z,orientation, PocketManager.getDimensionData(world)); setSource(stack, x, adjustedY, z, orientation, PocketManager.createDimensionData(world));
mod_pocketDim.sendChat(player,("Location Stored in Rift Signature")); mod_pocketDim.sendChat(player,("Location Stored in Rift Signature"));
world.playSoundAtEntity(player,mod_pocketDim.modid+":riftStart", 0.6f, 1); world.playSoundAtEntity(player,mod_pocketDim.modid+":riftStart", 0.6f, 1);
} }
@@ -113,6 +110,7 @@ public class ItemRiftSignature extends Item
/** /**
* allows items to add custom lines of information to the mouseover description * allows items to add custom lines of information to the mouseover description
*/ */
@Override
@SuppressWarnings({ "unchecked", "rawtypes" }) @SuppressWarnings({ "unchecked", "rawtypes" })
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public void addInformation(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, List par3List, boolean par4) public void addInformation(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, List par3List, boolean par4)
@@ -140,22 +138,28 @@ public class ItemRiftSignature extends Item
*/ */
public static int adjustYForSpecialBlocks(World world, int x, int y, int z) public static int adjustYForSpecialBlocks(World world, int x, int y, int z)
{ {
y=y-2;//get the block the player actually clicked on int targetY = y - 2; // Get the block the player actually clicked on
Block block = Block.blocksList[world.getBlockId(x, y, z)]; Block block = Block.blocksList[world.getBlockId(x, targetY, z)];
if(block.isBlockReplaceable(world, x, y, z)) if (block == null)
{ {
return y+1;//move block placement down (-2+1) one so its directly over things like snow return targetY + 2;
}
if (block.isBlockReplaceable(world, x, targetY, z))
{
return targetY + 1; // Move block placement down (-2+1) one so its directly over things like snow
} }
if (block instanceof BaseDimDoor) if (block instanceof BaseDimDoor)
{ {
if(world.getBlockId(x, y-1, z)==block.blockID&&world.getBlockMetadata(x, y, z)==8) if (((BaseDimDoor) block).isUpperDoorBlock(world.getBlockMetadata(x, targetY, z)))
{ {
return y;//move rift placement down two so its in the right place on the door. return targetY; // Move rift placement down two so its in the right place on the door.
} }
return y+1; // Move rift placement down one so its in the right place on the door.
return targetY + 1;
} }
return y+2; return targetY + 2;
} }
public static void setSource(ItemStack itemStack, int x, int y, int z, int orientation, NewDimData dimension) public static void setSource(ItemStack itemStack, int x, int y, int z, int orientation, NewDimData dimension)
{ {
NBTTagCompound tag = new NBTTagCompound(); NBTTagCompound tag = new NBTTagCompound();
@@ -196,11 +200,12 @@ public class ItemRiftSignature extends Item
Integer orientation = tag.getInteger("orientation"); Integer orientation = tag.getInteger("orientation");
Integer dimID = tag.getInteger("linkDimID"); Integer dimID = tag.getInteger("linkDimID");
if (x != null && y != null && z != null && dimID != null) if (x != null && y != null && z != null && orientation != null && dimID != null)
{ {
return new Point4DOrientation(x, y, z, orientation, dimID); return new Point4DOrientation(x, y, z, orientation, dimID);
} }
} }
// Mark the item as uninitialized if its source couldn't be read
itemStack.setItemDamage(0); itemStack.setItemDamage(0);
} }
return null; return null;
@@ -210,6 +215,7 @@ public class ItemRiftSignature extends Item
{ {
private Point4D point; private Point4D point;
private int orientation; private int orientation;
Point4DOrientation(int x, int y, int z, int orientation, int dimID) Point4DOrientation(int x, int y, int z, int orientation, int dimID)
{ {
this.point = new Point4D(x, y, z, dimID); this.point = new Point4D(x, y, z, dimID);
@@ -235,10 +241,16 @@ public class ItemRiftSignature extends Item
{ {
return point.getDimension(); return point.getDimension();
} }
int getOrientation() int getOrientation()
{ {
return orientation; return orientation;
} }
Point4D getPoint()
{
return point;
}
} }
} }

View File

@@ -1,7 +1,6 @@
package StevenDimDoors.mod_pocketDim.items; package StevenDimDoors.mod_pocketDim.items;
import java.util.List; import java.util.List;
import net.minecraft.client.renderer.texture.IconRegister; import net.minecraft.client.renderer.texture.IconRegister;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item; import net.minecraft.item.Item;
@@ -11,10 +10,9 @@ import net.minecraft.world.World;
import net.minecraftforge.common.DimensionManager; import net.minecraftforge.common.DimensionManager;
import StevenDimDoors.mod_pocketDim.mod_pocketDim; import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.core.DimLink; import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.LinkTypes; import StevenDimDoors.mod_pocketDim.core.LinkType;
import StevenDimDoors.mod_pocketDim.core.NewDimData; import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager; import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.util.Point4D;
import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly; import cpw.mods.fml.relauncher.SideOnly;
@@ -40,69 +38,124 @@ public class ItemStabilizedRiftSignature extends ItemRiftSignature
return false; return false;
} }
// We don't check for replaceable blocks. The user can deal with that. <_< // Adjust Y so the rift is at head level, depending on the presence of certain blocks
y += 2; //Increase y by 2 to place the rift at head level int adjustedY = adjustYForSpecialBlocks(world, x, y + 2, z);
if (!player.canPlayerEdit(x, y, z, side, stack)) if (!player.canPlayerEdit(x, adjustedY, z, side, stack))
{ {
return true; return true;
} }
Point4DOrientation source = getSource(stack); int orientation = MathHelper.floor_double((player.rotationYaw + 180.0F) * 4.0F / 360.0F - 0.5D) & 3;
int adjustedY = adjustYForSpecialBlocks(world,x,y,z);
// Check if the Stabilized Rift Signature has been initialized // Check if the Stabilized Rift Signature has been initialized
int orientation = MathHelper.floor_double((player.rotationYaw + 180.0F) * 4.0F / 360.0F - 0.5D) & 3; Point4DOrientation source = getSource(stack);
if (source != null) if (source != null)
{ {
// Yes, it's initialized. Check if the player is in creative
// or if the player can pay with Stable Fabric to create a rift. // Yes, it's initialized.
if (!player.capabilities.isCreativeMode && !player.inventory.hasItem(mod_pocketDim.itemStableFabric.itemID)) NewDimData sourceDimension = PocketManager.getDimensionData(source.getDimension());
NewDimData destinationDimension = PocketManager.createDimensionData(world);
DimLink reverse = destinationDimension.getLink(x, adjustedY, z);
DimLink link;
// Check whether the SRS is being used to restore one of its previous
// link pairs. In other words, the SRS is being used on a location
// that already has a link pointing to the SRS's source, with the
// intention of overwriting the source-side link to point there.
// Those benign redirection operations will be handled for free.
if (reverse != null && source.getPoint().equals(reverse.destination()))
{ {
mod_pocketDim.sendChat(player, "You don't have any Stable Fabric!"); // Only the source-to-destination link is needed.
link = sourceDimension.createLink(source.getX(), source.getY(), source.getZ(), LinkType.NORMAL, source.getOrientation());
destinationDimension.setLinkDestination(link, x, adjustedY, z);
}
else
{
// Check if the player is in creative mode,
// or if the player can pay with an Ender Pearl to create a rift.
if (!player.capabilities.isCreativeMode &&
!player.inventory.consumeInventoryItem(Item.enderPearl.itemID))
{
mod_pocketDim.sendChat(player, "You don't have any Ender Pearls!");
// I won't do this, but this is the chance to localize chat // I won't do this, but this is the chance to localize chat
// messages sent to the player; look at ChatMessageComponent // messages sent to the player; look at ChatMessageComponent
// and how MFR does it with items like the safari net launcher // and how MFR does it with items like the safari net launcher
return true; return true;
} }
//The link was used before and already has an endpoint stored. Create links connecting the two endpoints. // Create links connecting the two endpoints.
NewDimData sourceDimension = PocketManager.getDimensionData(source.getDimension()); link = sourceDimension.createLink(source.getX(), source.getY(), source.getZ(), LinkType.NORMAL, source.getOrientation());
NewDimData destinationDimension = PocketManager.getDimensionData(world); reverse = destinationDimension.createLink(x, adjustedY, z, LinkType.NORMAL, orientation);
DimLink link = sourceDimension.createLink(source.getX(), source.getY(), source.getZ(), LinkTypes.NORMAL,source.getOrientation()); destinationDimension.setLinkDestination(link, x, adjustedY, z);
DimLink reverse = destinationDimension.createLink(x, adjustedY, z, LinkTypes.NORMAL,orientation); sourceDimension.setLinkDestination(reverse, source.getX(), source.getY(), source.getZ());
destinationDimension.setDestination(link, x, adjustedY, z);
sourceDimension.setDestination(reverse, source.getX(), source.getY(), source.getZ());
// Try placing a rift at the destination point // Try placing a rift at the destination point
if (!mod_pocketDim.blockRift.isBlockImmune(world, x, adjustedY, z)) mod_pocketDim.blockRift.tryPlacingRift(world, x, adjustedY, z);
{
world.setBlock(x, adjustedY, z, mod_pocketDim.blockRift.blockID);
} }
//Try placing a rift at the source point, but check if its world is loaded first // Try placing a rift at the source point
// We don't need to check if sourceWorld is null - that's already handled.
World sourceWorld = DimensionManager.getWorld(sourceDimension.id()); World sourceWorld = DimensionManager.getWorld(sourceDimension.id());
if (sourceWorld != null &&
!mod_pocketDim.blockRift.isBlockImmune(sourceWorld, source.getX(), source.getY(), source.getZ()))
{
sourceWorld.setBlock(source.getX(), source.getY(), source.getZ(), mod_pocketDim.blockRift.blockID);
}
if (!player.capabilities.isCreativeMode) mod_pocketDim.blockRift.tryPlacingRift(sourceWorld, source.getX(), source.getY(), source.getZ());
{
player.inventory.consumeInventoryItem(mod_pocketDim.itemStableFabric.itemID);
}
mod_pocketDim.sendChat(player, "Rift Created"); mod_pocketDim.sendChat(player, "Rift Created");
world.playSoundAtEntity(player, "mods.DimDoors.sfx.riftEnd", 0.6f, 1); world.playSoundAtEntity(player, "mods.DimDoors.sfx.riftEnd", 0.6f, 1);
} }
else else
{ {
// The link signature has not been used. Store its current target as the first location. // The link signature has not been used. Store its current target as the first location.
setSource(stack, x, adjustedY, z, orientation, PocketManager.getDimensionData(world)); setSource(stack, x, adjustedY, z, orientation, PocketManager.createDimensionData(world));
mod_pocketDim.sendChat(player, "Location Stored in Stabilized Rift Signature"); mod_pocketDim.sendChat(player, "Location Stored in Stabilized Rift Signature");
world.playSoundAtEntity(player, "mods.DimDoors.sfx.riftStart", 0.6f, 1); world.playSoundAtEntity(player, "mods.DimDoors.sfx.riftStart", 0.6f, 1);
} }
return true; return true;
} }
public static boolean useFromDispenser(ItemStack stack, World world, int x, int y, int z)
{
// Stabilized Rift Signatures can only be used from dispensers to restore
// a previous link pair. The operation would be free for a player, so
// dispensers can also perform it for free. Otherwise, the item does nothing.
if (world.isRemote)
{
return false;
}
// Adjust Y so the rift is at head level, depending on the presence of certain blocks
int adjustedY = adjustYForSpecialBlocks(world, x, y + 2, z);
Point4DOrientation source = getSource(stack);
// The SRS must have been initialized
if (source != null)
{
NewDimData sourceDimension = PocketManager.getDimensionData(source.getDimension());
NewDimData destinationDimension = PocketManager.createDimensionData(world);
DimLink reverse = destinationDimension.getLink(x, adjustedY, z);
DimLink link;
// Check whether the SRS is being used to restore one of its previous
// link pairs. In other words, the SRS is being used on a location
// that already has a link pointing to the SRS's source, with the
// intention of overwriting the source-side link to point there.
if (reverse != null && source.getPoint().equals(reverse.destination()))
{
// Only the source-to-destination link is needed.
link = sourceDimension.createLink(source.getX(), source.getY(), source.getZ(), LinkType.NORMAL, source.getOrientation());
destinationDimension.setLinkDestination(link, x, adjustedY, z);
// Try placing a rift at the source point
// We don't need to check if sourceWorld is null - that's already handled.
World sourceWorld = DimensionManager.getWorld(sourceDimension.id());
mod_pocketDim.blockRift.tryPlacingRift(sourceWorld, source.getX(), source.getY(), source.getZ());
// This call doesn't seem to be working...
world.playSoundEffect(x + 0.5, adjustedY + 0.5, z + 0.5, "mods.DimDoors.sfx.riftEnd", 0.6f, 1);
return true;
}
}
return false;
}
/** /**
* allows items to add custom lines of information to the mouseover description * allows items to add custom lines of information to the mouseover description
*/ */
@@ -119,8 +172,8 @@ public class ItemStabilizedRiftSignature extends ItemRiftSignature
else else
{ {
par3List.add("First click stores a location,"); par3List.add("First click stores a location,");
par3List.add("second click creates two rifts"); par3List.add("other clicks create rifts linking");
par3List.add("that link the locations together."); par3List.add("the first and last locations together.");
} }
} }
} }

View File

@@ -4,15 +4,17 @@ import java.util.List;
import net.minecraft.block.material.Material; import net.minecraft.block.material.Material;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemDoor;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.world.World; import net.minecraft.world.World;
import StevenDimDoors.mod_pocketDim.mod_pocketDim; import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.blocks.BaseDimDoor;
public class ItemUnstableDoor extends BaseItemDoor public class ItemUnstableDoor extends BaseItemDoor
{ {
public ItemUnstableDoor(int itemID, Material material) public ItemUnstableDoor(int itemID, Material material, ItemDoor door)
{ {
super(itemID, material); super(itemID, material, door);
} }
@SuppressWarnings({ "unchecked", "rawtypes" }) @SuppressWarnings({ "unchecked", "rawtypes" })
@@ -23,23 +25,8 @@ public class ItemUnstableDoor extends BaseItemDoor
} }
@Override @Override
public ItemStack onItemRightClick(ItemStack stack, World world, EntityPlayer player) protected BaseDimDoor getDoorBlock()
{ {
if (!world.isRemote) return (BaseDimDoor) mod_pocketDim.unstableDoor;
{
if (tryPlacingDoor(mod_pocketDim.unstableDoor, world, player, stack) &&
!player.capabilities.isCreativeMode)
{
stack.stackSize--;
}
}
return stack;
}
@Override
public boolean onItemUse(ItemStack stack, EntityPlayer player, World world, int x, int y,
int z, int par7, float par8, float par9, float par10)
{
return tryItemUse(mod_pocketDim.unstableDoor, stack, player, world, x, y, z, par7, false, true);
} }
} }

View File

@@ -4,15 +4,17 @@ import java.util.List;
import net.minecraft.block.material.Material; import net.minecraft.block.material.Material;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemDoor;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.world.World; import net.minecraft.world.World;
import StevenDimDoors.mod_pocketDim.mod_pocketDim; import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.blocks.BaseDimDoor;
public class ItemWarpDoor extends BaseItemDoor public class ItemWarpDoor extends BaseItemDoor
{ {
public ItemWarpDoor(int itemID, Material material) public ItemWarpDoor(int itemID, Material material, ItemDoor door)
{ {
super(itemID, material); super(itemID, material, door);
} }
@SuppressWarnings({ "unchecked", "rawtypes" }) @SuppressWarnings({ "unchecked", "rawtypes" })
@@ -26,23 +28,8 @@ public class ItemWarpDoor extends BaseItemDoor
} }
@Override @Override
public ItemStack onItemRightClick(ItemStack stack, World world, EntityPlayer player) protected BaseDimDoor getDoorBlock()
{ {
if (!world.isRemote) return (BaseDimDoor) mod_pocketDim.warpDoor;
{
if (tryPlacingDoor(mod_pocketDim.warpDoor, world, player, stack) &&
!player.capabilities.isCreativeMode)
{
stack.stackSize--;
}
}
return stack;
}
@Override
public boolean onItemUse(ItemStack stack, EntityPlayer player, World world, int x, int y,
int z, int par7, float par8, float par9, float par10)
{
return tryItemUse(mod_pocketDim.warpDoor, stack, player, world, x, y, z, par7, false, true);
} }
} }

View File

@@ -0,0 +1,42 @@
package StevenDimDoors.mod_pocketDim.items.behaviors;
import net.minecraft.block.BlockDispenser;
import net.minecraft.dispenser.BehaviorDefaultDispenseItem;
import net.minecraft.dispenser.IBlockSource;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing;
import net.minecraft.world.World;
import StevenDimDoors.mod_pocketDim.items.ItemStabilizedRiftSignature;
public class DispenserBehaviorStabilizedRS extends BehaviorDefaultDispenseItem
{
@Override
public ItemStack dispenseStack(IBlockSource dispenser, ItemStack stack)
{
// Search for a non-air block up to 3 blocks in front of a dispenser.
// If it's found, call ItemStabilizedRiftSignature.useFromDispenser().
int x = dispenser.getXInt();
int y = dispenser.getYInt();
int z = dispenser.getZInt();
EnumFacing facing = BlockDispenser.getFacing(dispenser.getBlockMetadata());
int dx = facing.getFrontOffsetX();
int dy = facing.getFrontOffsetY();
int dz = facing.getFrontOffsetZ();
World world = dispenser.getWorld();
for (int k = 1; k <= 3; k++)
{
x += dx;
y += dy;
z += dz;
if (!world.isAirBlock(x, y, z))
{
// Found a block. Activate the item.
ItemStabilizedRiftSignature.useFromDispenser(stack, world, x, y, z);
break;
}
}
// The item stack isn't modified
return stack;
}
}

View File

@@ -54,7 +54,7 @@ public class itemRiftRemover extends Item
int hx = hit.blockX; int hx = hit.blockX;
int hy = hit.blockY; int hy = hit.blockY;
int hz = hit.blockZ; int hz = hit.blockZ;
NewDimData dimension = PocketManager.getDimensionData(world); NewDimData dimension = PocketManager.createDimensionData(world);
DimLink link = dimension.getLink(hx, hy, hz); DimLink link = dimension.getLink(hx, hy, hz);
if (world.getBlockId(hx, hy, hz) == mod_pocketDim.blockRift.blockID && link != null && if (world.getBlockId(hx, hy, hz) == mod_pocketDim.blockRift.blockID && link != null &&
player.canPlayerEdit(hx, hy, hz, hit.sideHit, stack)) player.canPlayerEdit(hx, hy, hz, hit.sideHit, stack))
@@ -85,7 +85,7 @@ public class itemRiftRemover extends Item
y = hit.blockY; y = hit.blockY;
z = hit.blockZ; z = hit.blockZ;
NewDimData dimension = PocketManager.getDimensionData(world); NewDimData dimension = PocketManager.createDimensionData(world);
DimLink link = dimension.getLink(x, y, z); DimLink link = dimension.getLink(x, y, z);
if (world.getBlockId(x, y, z) == mod_pocketDim.blockRift.blockID && link != null && if (world.getBlockId(x, y, z) == mod_pocketDim.blockRift.blockID && link != null &&
player.canPlayerEdit(x, y, z, side, stack)) player.canPlayerEdit(x, y, z, side, stack))

View File

@@ -1,7 +1,6 @@
package StevenDimDoors.mod_pocketDim; package StevenDimDoors.mod_pocketDim;
import java.io.File; import java.io.File;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.material.Material; import net.minecraft.block.material.Material;
import net.minecraft.creativetab.CreativeTabs; import net.minecraft.creativetab.CreativeTabs;
@@ -9,38 +8,46 @@ import net.minecraft.entity.EntityEggInfo;
import net.minecraft.entity.EntityList; import net.minecraft.entity.EntityList;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.item.ItemDoor;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.ChatMessageComponent; import net.minecraft.util.ChatMessageComponent;
import net.minecraft.world.biome.BiomeGenBase; import net.minecraft.world.biome.BiomeGenBase;
import net.minecraftforge.common.DimensionManager; import net.minecraftforge.common.DimensionManager;
import net.minecraftforge.common.ForgeChunkManager; import net.minecraftforge.common.ForgeChunkManager;
import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fluids.Fluid;
import StevenDimDoors.mod_pocketDim.blocks.BlockDimWall; import StevenDimDoors.mod_pocketDim.blocks.BlockDimWall;
import StevenDimDoors.mod_pocketDim.blocks.BlockDimWallPerm; import StevenDimDoors.mod_pocketDim.blocks.BlockDimWallPerm;
import StevenDimDoors.mod_pocketDim.blocks.BlockDoorGold; import StevenDimDoors.mod_pocketDim.blocks.BlockDoorGold;
import StevenDimDoors.mod_pocketDim.blocks.BlockDoorQuartz;
import StevenDimDoors.mod_pocketDim.blocks.BlockGoldDimDoor; import StevenDimDoors.mod_pocketDim.blocks.BlockGoldDimDoor;
import StevenDimDoors.mod_pocketDim.blocks.BlockLimbo; import StevenDimDoors.mod_pocketDim.blocks.BlockLimbo;
import StevenDimDoors.mod_pocketDim.blocks.BlockRift; import StevenDimDoors.mod_pocketDim.blocks.BlockRift;
import StevenDimDoors.mod_pocketDim.blocks.DimensionalDoor; import StevenDimDoors.mod_pocketDim.blocks.DimensionalDoor;
import StevenDimDoors.mod_pocketDim.blocks.PersonalDimDoor;
import StevenDimDoors.mod_pocketDim.blocks.TransTrapdoor; import StevenDimDoors.mod_pocketDim.blocks.TransTrapdoor;
import StevenDimDoors.mod_pocketDim.blocks.TransientDoor; import StevenDimDoors.mod_pocketDim.blocks.TransientDoor;
import StevenDimDoors.mod_pocketDim.blocks.UnstableDoor; import StevenDimDoors.mod_pocketDim.blocks.UnstableDoor;
import StevenDimDoors.mod_pocketDim.blocks.WarpDoor; import StevenDimDoors.mod_pocketDim.blocks.WarpDoor;
import StevenDimDoors.mod_pocketDim.commands.CommandCreateDungeonRift; import StevenDimDoors.mod_pocketDim.commands.CommandCreateDungeonRift;
import StevenDimDoors.mod_pocketDim.commands.CommandCreatePocket; import StevenDimDoors.mod_pocketDim.commands.CommandCreatePocket;
import StevenDimDoors.mod_pocketDim.commands.CommandDeleteAllLinks; import StevenDimDoors.mod_pocketDim.commands.CommandCreateRandomRift;
import StevenDimDoors.mod_pocketDim.commands.CommandDeleteRifts; import StevenDimDoors.mod_pocketDim.commands.CommandDeleteRifts;
import StevenDimDoors.mod_pocketDim.commands.CommandExportDungeon; import StevenDimDoors.mod_pocketDim.commands.CommandExportDungeon;
import StevenDimDoors.mod_pocketDim.commands.CommandListDungeons;
import StevenDimDoors.mod_pocketDim.commands.CommandResetDungeons; import StevenDimDoors.mod_pocketDim.commands.CommandResetDungeons;
import StevenDimDoors.mod_pocketDim.commands.CommandTeleportPlayer; import StevenDimDoors.mod_pocketDim.commands.CommandTeleportPlayer;
import StevenDimDoors.mod_pocketDim.config.DDProperties;
import StevenDimDoors.mod_pocketDim.config.DDWorldProperties;
import StevenDimDoors.mod_pocketDim.core.PocketManager; import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.helpers.ChunkLoaderHelper; import StevenDimDoors.mod_pocketDim.helpers.ChunkLoaderHelper;
import StevenDimDoors.mod_pocketDim.helpers.DungeonHelper; import StevenDimDoors.mod_pocketDim.helpers.DungeonHelper;
import StevenDimDoors.mod_pocketDim.items.ItemBlockDimWall; import StevenDimDoors.mod_pocketDim.items.ItemBlockDimWall;
import StevenDimDoors.mod_pocketDim.items.ItemDDKey;
import StevenDimDoors.mod_pocketDim.items.ItemDimensionalDoor; import StevenDimDoors.mod_pocketDim.items.ItemDimensionalDoor;
import StevenDimDoors.mod_pocketDim.items.ItemGoldDimDoor; import StevenDimDoors.mod_pocketDim.items.ItemGoldDimDoor;
import StevenDimDoors.mod_pocketDim.items.ItemGoldDoor; import StevenDimDoors.mod_pocketDim.items.ItemGoldDoor;
import StevenDimDoors.mod_pocketDim.items.ItemPersonalDoor;
import StevenDimDoors.mod_pocketDim.items.ItemQuartzDoor;
import StevenDimDoors.mod_pocketDim.items.ItemRiftBlade; import StevenDimDoors.mod_pocketDim.items.ItemRiftBlade;
import StevenDimDoors.mod_pocketDim.items.ItemRiftSignature; import StevenDimDoors.mod_pocketDim.items.ItemRiftSignature;
import StevenDimDoors.mod_pocketDim.items.ItemStabilizedRiftSignature; import StevenDimDoors.mod_pocketDim.items.ItemStabilizedRiftSignature;
@@ -49,23 +56,25 @@ import StevenDimDoors.mod_pocketDim.items.ItemUnstableDoor;
import StevenDimDoors.mod_pocketDim.items.ItemWarpDoor; import StevenDimDoors.mod_pocketDim.items.ItemWarpDoor;
import StevenDimDoors.mod_pocketDim.items.ItemWorldThread; import StevenDimDoors.mod_pocketDim.items.ItemWorldThread;
import StevenDimDoors.mod_pocketDim.items.itemRiftRemover; import StevenDimDoors.mod_pocketDim.items.itemRiftRemover;
import StevenDimDoors.mod_pocketDim.ticking.CommonTickHandler;
import StevenDimDoors.mod_pocketDim.ticking.CustomLimboPopulator; import StevenDimDoors.mod_pocketDim.ticking.CustomLimboPopulator;
import StevenDimDoors.mod_pocketDim.ticking.FastRiftRegenerator; import StevenDimDoors.mod_pocketDim.ticking.LimboDecayScheduler;
import StevenDimDoors.mod_pocketDim.ticking.LimboDecay;
import StevenDimDoors.mod_pocketDim.ticking.MobMonolith; import StevenDimDoors.mod_pocketDim.ticking.MobMonolith;
import StevenDimDoors.mod_pocketDim.ticking.RiftRegenerator; import StevenDimDoors.mod_pocketDim.ticking.RiftRegenerator;
import StevenDimDoors.mod_pocketDim.ticking.ServerTickHandler;
import StevenDimDoors.mod_pocketDim.tileentities.TileEntityDimDoor; import StevenDimDoors.mod_pocketDim.tileentities.TileEntityDimDoor;
import StevenDimDoors.mod_pocketDim.tileentities.TileEntityDimDoorGold; import StevenDimDoors.mod_pocketDim.tileentities.TileEntityDimDoorGold;
import StevenDimDoors.mod_pocketDim.tileentities.TileEntityRift; import StevenDimDoors.mod_pocketDim.tileentities.TileEntityRift;
import StevenDimDoors.mod_pocketDim.tileentities.TileEntityTransTrapdoor; import StevenDimDoors.mod_pocketDim.tileentities.TileEntityTransTrapdoor;
import StevenDimDoors.mod_pocketDim.util.l_systems.LSystem;
import StevenDimDoors.mod_pocketDim.world.BiomeGenLimbo; import StevenDimDoors.mod_pocketDim.world.BiomeGenLimbo;
import StevenDimDoors.mod_pocketDim.world.BiomeGenPocket; import StevenDimDoors.mod_pocketDim.world.BiomeGenPocket;
import StevenDimDoors.mod_pocketDim.world.DDBiomeGenBase;
import StevenDimDoors.mod_pocketDim.world.LimboDecay;
import StevenDimDoors.mod_pocketDim.world.LimboProvider; import StevenDimDoors.mod_pocketDim.world.LimboProvider;
import StevenDimDoors.mod_pocketDim.world.PersonalPocketProvider;
import StevenDimDoors.mod_pocketDim.world.PocketProvider; import StevenDimDoors.mod_pocketDim.world.PocketProvider;
import StevenDimDoors.mod_pocketDim.world.gateways.GatewayGenerator; import StevenDimDoors.mod_pocketDim.world.gateways.GatewayGenerator;
import StevenDimDoors.mod_pocketDimClient.ClientPacketHandler; import StevenDimDoors.mod_pocketDimClient.ClientPacketHandler;
import StevenDimDoors.mod_pocketDimClient.ClientTickHandler;
import cpw.mods.fml.common.Mod; import cpw.mods.fml.common.Mod;
import cpw.mods.fml.common.Mod.EventHandler; import cpw.mods.fml.common.Mod.EventHandler;
import cpw.mods.fml.common.Mod.Instance; import cpw.mods.fml.common.Mod.Instance;
@@ -73,8 +82,9 @@ import cpw.mods.fml.common.SidedProxy;
import cpw.mods.fml.common.event.FMLInitializationEvent; import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.event.FMLPostInitializationEvent; import cpw.mods.fml.common.event.FMLPostInitializationEvent;
import cpw.mods.fml.common.event.FMLPreInitializationEvent; import cpw.mods.fml.common.event.FMLPreInitializationEvent;
import cpw.mods.fml.common.event.FMLServerAboutToStartEvent;
import cpw.mods.fml.common.event.FMLServerStartingEvent; import cpw.mods.fml.common.event.FMLServerStartingEvent;
import cpw.mods.fml.common.event.FMLServerStoppingEvent; import cpw.mods.fml.common.event.FMLServerStoppedEvent;
import cpw.mods.fml.common.network.NetworkMod; import cpw.mods.fml.common.network.NetworkMod;
import cpw.mods.fml.common.network.NetworkMod.SidedPacketHandler; import cpw.mods.fml.common.network.NetworkMod.SidedPacketHandler;
import cpw.mods.fml.common.registry.EntityRegistry; import cpw.mods.fml.common.registry.EntityRegistry;
@@ -92,16 +102,21 @@ serverPacketHandlerSpec =
@SidedPacketHandler(channels = {PacketConstants.CHANNEL_NAME}, packetHandler = ServerPacketHandler.class)) @SidedPacketHandler(channels = {PacketConstants.CHANNEL_NAME}, packetHandler = ServerPacketHandler.class))
public class mod_pocketDim public class mod_pocketDim
{ {
public static final String version = "1.6.4R2.2.2RC1"; public static final String version = "@VERSION@";
public static final String modid = "dimdoors"; public static final String modid = "dimdoors";
//TODO need a place to stick all these constants
public static final int NETHER_DIMENSION_ID = -1;
//need to clean up //need to clean up
@SidedProxy(clientSide = "StevenDimDoors.mod_pocketDimClient.ClientProxy", serverSide = "StevenDimDoors.mod_pocketDim.CommonProxy") @SidedProxy(clientSide = "StevenDimDoors.mod_pocketDimClient.ClientProxy", serverSide = "StevenDimDoors.mod_pocketDim.CommonProxy")
public static CommonProxy proxy; public static CommonProxy proxy;
@Instance("PocketDimensions") @Instance(mod_pocketDim.modid)
public static mod_pocketDim instance = new mod_pocketDim(); public static mod_pocketDim instance;
public static Block quartzDoor;
public static Block personalDimDoor;
public static Block transientDoor; public static Block transientDoor;
public static Block warpDoor; public static Block warpDoor;
public static Block goldenDoor; public static Block goldenDoor;
@@ -119,13 +134,16 @@ public class mod_pocketDim
public static Item itemWorldThread; public static Item itemWorldThread;
public static Item itemRiftBlade; public static Item itemRiftBlade;
public static Item itemDimensionalDoor; public static ItemDimensionalDoor itemDimensionalDoor;
public static Item itemWarpDoor; public static Item itemWarpDoor;
public static Item itemRiftRemover; public static Item itemRiftRemover;
public static Item itemRiftSignature; public static Item itemRiftSignature;
public static Item itemStableFabric; public static Item itemStableFabric;
public static Item itemUnstableDoor; public static Item itemUnstableDoor;
public static Item itemStabilizedLinkSignature; public static Item itemDDKey;
public static Item itemQuartzDoor;
public static Item itemPersonalDoor;
public static Item itemStabilizedRiftSignature;
public static BiomeGenBase limboBiome; public static BiomeGenBase limboBiome;
public static BiomeGenBase pocketBiome; public static BiomeGenBase pocketBiome;
@@ -133,10 +151,18 @@ public class mod_pocketDim
public static boolean isPlayerWearingGoogles = false; public static boolean isPlayerWearingGoogles = false;
public static DDProperties properties; public static DDProperties properties;
public static DDWorldProperties worldProperties;
public static CustomLimboPopulator spawner; //Added this field temporarily. Will be refactored out later. public static CustomLimboPopulator spawner; //Added this field temporarily. Will be refactored out later.
public static FastRiftRegenerator fastRiftRegenerator; public static RiftRegenerator riftRegenerator;
public static GatewayGenerator gatewayGenerator; public static GatewayGenerator gatewayGenerator;
public static DeathTracker deathTracker; public static DeathTracker deathTracker;
private static ServerTickHandler serverTickHandler;
private static LimboDecayScheduler limboDecayScheduler;
private static LimboDecay limboDecay;
private static EventHookContainer hooks;
//TODO this is a temporary workaround for saving data
private String currrentSaveRootDirectory;
public static CreativeTabs dimDoorsCreativeTab = new CreativeTabs("dimDoorsCreativeTab") public static CreativeTabs dimDoorsCreativeTab = new CreativeTabs("dimDoorsCreativeTab")
{ {
@@ -156,14 +182,13 @@ public class mod_pocketDim
@EventHandler @EventHandler
public void onPreInitialization(FMLPreInitializationEvent event) public void onPreInitialization(FMLPreInitializationEvent event)
{ {
instance = this;
//This should be the FIRST thing that gets done. //This should be the FIRST thing that gets done.
String path = event.getSuggestedConfigurationFile().getAbsolutePath().replace(modid, "DimDoors"); String path = event.getSuggestedConfigurationFile().getAbsolutePath().replace(modid, "DimDoors");
properties = DDProperties.initialize(new File(path)); properties = DDProperties.initialize(new File(path));
//Now do other stuff //Now do other stuff
EventHookContainer hooks = new EventHookContainer(properties); hooks = new EventHookContainer(properties);
MinecraftForge.EVENT_BUS.register(hooks); MinecraftForge.EVENT_BUS.register(hooks);
MinecraftForge.TERRAIN_GEN_BUS.register(hooks); MinecraftForge.TERRAIN_GEN_BUS.register(hooks);
} }
@@ -171,45 +196,55 @@ public class mod_pocketDim
@EventHandler @EventHandler
public void onInitialization(FMLInitializationEvent event) public void onInitialization(FMLInitializationEvent event)
{ {
CommonTickHandler commonTickHandler = new CommonTickHandler(); // Initialize ServerTickHandler instance
TickRegistry.registerTickHandler(new ClientTickHandler(), Side.CLIENT); serverTickHandler = new ServerTickHandler();
TickRegistry.registerTickHandler(commonTickHandler, Side.SERVER); TickRegistry.registerTickHandler(serverTickHandler, Side.SERVER);
//MonolithSpawner should be initialized before any provider instances are created // Initialize LimboDecay instance: required for BlockLimbo
//Register the other regular tick receivers as well limboDecay = new LimboDecay(properties);
spawner = new CustomLimboPopulator(commonTickHandler, properties);
new RiftRegenerator(commonTickHandler); //No need to store the reference
LimboDecay decay = new LimboDecay(commonTickHandler, properties);
fastRiftRegenerator = new FastRiftRegenerator(commonTickHandler);
// Initialize blocks and items
transientDoor = new TransientDoor(properties.TransientDoorID, Material.iron, properties).setHardness(1.0F) .setUnlocalizedName("transientDoor"); transientDoor = new TransientDoor(properties.TransientDoorID, Material.iron, properties).setHardness(1.0F) .setUnlocalizedName("transientDoor");
goldenDimensionalDoor = new BlockGoldDimDoor(properties.GoldenDimensionalDoorID, Material.iron, properties).setHardness(1.0F) .setUnlocalizedName("dimDoorGold"); goldenDimensionalDoor = new BlockGoldDimDoor(properties.GoldenDimensionalDoorID, Material.iron, properties).setHardness(1.0F) .setUnlocalizedName("dimDoorGold");
quartzDoor = new BlockDoorQuartz(properties.QuartzDoorID, Material.rock).setHardness(0.1F).setUnlocalizedName("doorQuartz");
personalDimDoor = new PersonalDimDoor(properties.PersonalDimDoorID, Material.rock,properties).setHardness(0.1F).setUnlocalizedName("dimDoorPersonal");
goldenDoor = new BlockDoorGold(properties.GoldenDoorID, Material.iron).setHardness(0.1F).setUnlocalizedName("doorGold"); goldenDoor = new BlockDoorGold(properties.GoldenDoorID, Material.iron).setHardness(0.1F).setUnlocalizedName("doorGold");
blockDimWall = new BlockDimWall(properties.FabricBlockID, 0, Material.iron).setLightValue(1.0F).setHardness(0.1F).setUnlocalizedName("blockDimWall"); blockDimWall = new BlockDimWall(properties.FabricBlockID, 0, Material.iron).setLightValue(1.0F).setHardness(0.1F).setUnlocalizedName("blockDimWall");
blockDimWallPerm = (new BlockDimWallPerm(properties.PermaFabricBlockID, 0, Material.iron)).setLightValue(1.0F).setBlockUnbreakable().setResistance(6000000.0F).setUnlocalizedName("blockDimWallPerm"); blockDimWallPerm = (new BlockDimWallPerm(properties.PermaFabricBlockID, 0, Material.iron)).setLightValue(1.0F).setBlockUnbreakable().setResistance(6000000.0F).setUnlocalizedName("blockDimWallPerm");
warpDoor = new WarpDoor(properties.WarpDoorID, Material.wood, properties).setHardness(1.0F) .setUnlocalizedName("dimDoorWarp"); warpDoor = new WarpDoor(properties.WarpDoorID, Material.wood, properties).setHardness(1.0F) .setUnlocalizedName("dimDoorWarp");
blockRift = (BlockRift) (new BlockRift(properties.RiftBlockID, 0, Material.air, properties).setHardness(1.0F) .setUnlocalizedName("rift")); blockRift = (BlockRift) (new BlockRift(properties.RiftBlockID, 0, Material.air, properties).setHardness(1.0F) .setUnlocalizedName("rift"));
blockLimbo = new BlockLimbo(properties.LimboBlockID, 15, Material.iron, properties.LimboDimensionID, decay).setHardness(.2F).setUnlocalizedName("BlockLimbo").setLightValue(.0F); blockLimbo = new BlockLimbo(properties.LimboBlockID, 15, Material.iron, properties.LimboDimensionID, limboDecay).setHardness(.2F).setUnlocalizedName("BlockLimbo").setLightValue(.0F);
unstableDoor = (new UnstableDoor(properties.UnstableDoorID, Material.iron, properties).setHardness(.2F).setUnlocalizedName("chaosDoor").setLightValue(.0F) ); unstableDoor = (new UnstableDoor(properties.UnstableDoorID, Material.iron, properties).setHardness(.2F).setUnlocalizedName("chaosDoor").setLightValue(.0F) );
dimensionalDoor = (DimensionalDoor) (new DimensionalDoor(properties.DimensionalDoorID, Material.iron, properties).setHardness(1.0F).setResistance(2000.0F) .setUnlocalizedName("dimDoor")); dimensionalDoor = (DimensionalDoor) (new DimensionalDoor(properties.DimensionalDoorID, Material.iron, properties).setHardness(1.0F).setResistance(2000.0F) .setUnlocalizedName("dimDoor"));
transTrapdoor = (TransTrapdoor) (new TransTrapdoor(properties.TransTrapdoorID, Material.wood).setHardness(1.0F) .setUnlocalizedName("dimHatch")); transTrapdoor = (TransTrapdoor) (new TransTrapdoor(properties.TransTrapdoorID, Material.wood).setHardness(1.0F) .setUnlocalizedName("dimHatch"));
itemGoldenDimensionalDoor = (new ItemGoldDimDoor(properties.GoldenDimensionalDoorItemID, Material.iron)).setUnlocalizedName("itemGoldDimDoor"); itemDDKey = (new ItemDDKey(properties.DDKeyItemID)).setUnlocalizedName("itemDDKey");
itemGoldenDoor = (new ItemGoldDoor(properties.GoldenDoorID, Material.wood)).setUnlocalizedName("itemGoldDoor"); itemQuartzDoor = (new ItemQuartzDoor(properties.QuartzDoorID, Material.rock)).setUnlocalizedName("itemQuartzDoor");
itemDimensionalDoor = (new ItemDimensionalDoor(properties.DimensionalDoorItemID, Material.iron)).setUnlocalizedName("itemDimDoor"); itemPersonalDoor = (new ItemPersonalDoor(properties.PersonalDimDoorID, Material.rock, (ItemDoor)this.itemQuartzDoor)).setUnlocalizedName("itemQuartzDimDoor");
itemWarpDoor = (new ItemWarpDoor(properties.WarpDoorItemID, Material.wood)).setUnlocalizedName("itemDimDoorWarp"); itemGoldenDoor = (new ItemGoldDoor(properties.GoldenDoorItemID, Material.wood)).setUnlocalizedName("itemGoldDoor");
itemGoldenDimensionalDoor = (new ItemGoldDimDoor(properties.GoldenDimensionalDoorItemID, Material.iron, (ItemDoor)this.itemGoldenDoor)).setUnlocalizedName("itemGoldDimDoor");
itemDimensionalDoor = (ItemDimensionalDoor) (new ItemDimensionalDoor(properties.DimensionalDoorItemID, Material.iron, (ItemDoor)Item.doorIron)).setUnlocalizedName("itemDimDoor");
itemWarpDoor = (new ItemWarpDoor(properties.WarpDoorItemID, Material.wood,(ItemDoor)Item.doorWood)).setUnlocalizedName("itemDimDoorWarp");
itemRiftSignature = (new ItemRiftSignature(properties.RiftSignatureItemID)).setUnlocalizedName("itemLinkSignature"); itemRiftSignature = (new ItemRiftSignature(properties.RiftSignatureItemID)).setUnlocalizedName("itemLinkSignature");
itemRiftRemover = (new itemRiftRemover(properties.RiftRemoverItemID, Material.wood)).setUnlocalizedName("itemRiftRemover"); itemRiftRemover = (new itemRiftRemover(properties.RiftRemoverItemID, Material.wood)).setUnlocalizedName("itemRiftRemover");
itemStableFabric = (new ItemStableFabric(properties.StableFabricItemID, 0)).setUnlocalizedName("itemStableFabric"); itemStableFabric = (new ItemStableFabric(properties.StableFabricItemID, 0)).setUnlocalizedName("itemStableFabric");
itemUnstableDoor = (new ItemUnstableDoor(properties.UnstableDoorItemID, Material.iron)).setUnlocalizedName("itemChaosDoor"); itemUnstableDoor = (new ItemUnstableDoor(properties.UnstableDoorItemID, Material.iron, null)).setUnlocalizedName("itemChaosDoor");
itemRiftBlade = (new ItemRiftBlade(properties.RiftBladeItemID, properties)).setUnlocalizedName("ItemRiftBlade"); itemRiftBlade = (new ItemRiftBlade(properties.RiftBladeItemID, properties)).setUnlocalizedName("ItemRiftBlade");
itemStabilizedLinkSignature = (new ItemStabilizedRiftSignature(properties.StabilizedRiftSignatureItemID)).setUnlocalizedName("itemStabilizedRiftSig"); itemStabilizedRiftSignature = (new ItemStabilizedRiftSignature(properties.StabilizedRiftSignatureItemID)).setUnlocalizedName("itemStabilizedRiftSig");
itemWorldThread = (new ItemWorldThread(properties.WorldThreadItemID)).setUnlocalizedName("itemWorldThread"); itemWorldThread = (new ItemWorldThread(properties.WorldThreadItemID)).setUnlocalizedName("itemWorldThread");
// Check if other biomes have been registered with the same IDs we want. If so, crash Minecraft
// to notify the user instead of letting it pass and conflicting with Biomes o' Plenty.
DDBiomeGenBase.checkBiomes( new int[] { properties.LimboBiomeID, properties.PocketBiomeID } );
// Initialize our biomes
mod_pocketDim.limboBiome = (new BiomeGenLimbo(properties.LimboBiomeID)); mod_pocketDim.limboBiome = (new BiomeGenLimbo(properties.LimboBiomeID));
mod_pocketDim.pocketBiome = (new BiomeGenPocket(properties.PocketBiomeID)); mod_pocketDim.pocketBiome = (new BiomeGenPocket(properties.PocketBiomeID));
GameRegistry.registerBlock(quartzDoor, "Quartz Door");
GameRegistry.registerBlock(personalDimDoor, "Personal Dimensional Door");
GameRegistry.registerBlock(goldenDoor, "Golden Door"); GameRegistry.registerBlock(goldenDoor, "Golden Door");
GameRegistry.registerBlock(goldenDimensionalDoor, "Golden Dimensional Door"); GameRegistry.registerBlock(goldenDimensionalDoor, "Golden Dimensional Door");
GameRegistry.registerBlock(unstableDoor, "Unstable Door"); GameRegistry.registerBlock(unstableDoor, "Unstable Door");
@@ -223,8 +258,13 @@ public class mod_pocketDim
GameRegistry.registerBlock(blockDimWall, ItemBlockDimWall.class, "Fabric of Reality"); GameRegistry.registerBlock(blockDimWall, ItemBlockDimWall.class, "Fabric of Reality");
DimensionManager.registerProviderType(properties.PocketProviderID, PocketProvider.class, false); if (!DimensionManager.registerProviderType(properties.PocketProviderID, PocketProvider.class, false))
DimensionManager.registerProviderType(properties.LimboProviderID, LimboProvider.class, false); throw new IllegalStateException("There is a provider ID conflict between PocketProvider from Dimensional Doors and another provider type. Fix your configuration!");
if (!DimensionManager.registerProviderType(properties.LimboProviderID, LimboProvider.class, false))
throw new IllegalStateException("There is a provider ID conflict between LimboProvider from Dimensional Doors and another provider type. Fix your configuration!");
if (!DimensionManager.registerProviderType(properties.PersonalPocketProviderID, PersonalPocketProvider.class, false))
throw new IllegalStateException("There is a provider ID conflict between PersonalPocketProvider from Dimensional Doors and another provider type. Fix your configuration!");
DimensionManager.registerDimension(properties.LimboDimensionID, properties.LimboProviderID); DimensionManager.registerDimension(properties.LimboDimensionID, properties.LimboProviderID);
LanguageRegistry.addName(goldenDoor, "Golden Door"); LanguageRegistry.addName(goldenDoor, "Golden Door");
@@ -243,19 +283,24 @@ public class mod_pocketDim
LanguageRegistry.addName(itemRiftSignature, "Rift Signature"); LanguageRegistry.addName(itemRiftSignature, "Rift Signature");
LanguageRegistry.addName(itemGoldenDoor, "Golden Door"); LanguageRegistry.addName(itemGoldenDoor, "Golden Door");
LanguageRegistry.addName(itemGoldenDimensionalDoor, "Golden Dimensional Door"); LanguageRegistry.addName(itemGoldenDimensionalDoor, "Golden Dimensional Door");
LanguageRegistry.addName(itemStabilizedLinkSignature, "Stabilized Rift Signature"); LanguageRegistry.addName(itemStabilizedRiftSignature, "Stabilized Rift Signature");
LanguageRegistry.addName(itemRiftRemover, "Rift Remover"); LanguageRegistry.addName(itemRiftRemover, "Rift Remover");
LanguageRegistry.addName(itemStableFabric, "Stable Fabric"); LanguageRegistry.addName(itemStableFabric, "Stable Fabric");
LanguageRegistry.addName(itemUnstableDoor, "Unstable Door"); LanguageRegistry.addName(itemUnstableDoor, "Unstable Door");
LanguageRegistry.addName(itemDimensionalDoor, "Dimensional Door"); LanguageRegistry.addName(itemDimensionalDoor, "Dimensional Door");
LanguageRegistry.addName(itemRiftBlade, "Rift Blade"); LanguageRegistry.addName(itemRiftBlade, "Rift Blade");
LanguageRegistry.addName(itemWorldThread, "World Thread"); LanguageRegistry.addName(itemWorldThread, "World Thread");
LanguageRegistry.addName(itemDDKey, "Rift Key");
LanguageRegistry.addName(itemQuartzDoor, "Quartz Door");
LanguageRegistry.addName(itemPersonalDoor, "Personal Dimensional Door");
/** /**
* Add names for multiblock inventory item * Add names for multiblock inventory item
*/ */
LanguageRegistry.addName(new ItemStack(blockDimWall, 1, 0), "Fabric of Reality"); LanguageRegistry.addName(new ItemStack(blockDimWall, 1, 0), "Fabric of Reality");
LanguageRegistry.addName(new ItemStack(blockDimWall, 1, 1), "Ancient Fabric"); LanguageRegistry.addName(new ItemStack(blockDimWall, 1, 1), "Ancient Fabric");
LanguageRegistry.addName(new ItemStack(blockDimWall, 1, 2), "Altered Fabric");
LanguageRegistry.instance().addStringLocalization("itemGroup.dimDoorsCustomTab", "en_US", "Dimensional Doors Items"); LanguageRegistry.instance().addStringLocalization("itemGroup.dimDoorsCustomTab", "en_US", "Dimensional Doors Items");
@@ -267,9 +312,12 @@ public class mod_pocketDim
EntityRegistry.registerModEntity(MobMonolith.class, "Monolith", properties.MonolithEntityID, this, 70, 1, true); EntityRegistry.registerModEntity(MobMonolith.class, "Monolith", properties.MonolithEntityID, this, 70, 1, true);
EntityList.IDtoClassMapping.put(properties.MonolithEntityID, MobMonolith.class); EntityList.IDtoClassMapping.put(properties.MonolithEntityID, MobMonolith.class);
EntityList.entityEggs.put(properties.MonolithEntityID, new EntityEggInfo(properties.MonolithEntityID, 0, 0xffffff)); EntityList.entityEggs.put(properties.MonolithEntityID, new EntityEggInfo(properties.MonolithEntityID, 0, 0xffffff));
LanguageRegistry.instance().addStringLocalization("entity.DimDoors.Obelisk.name", "Monolith"); LanguageRegistry.instance().addStringLocalization("entity.dimdoors.Monolith.name", "Monolith");
CraftingManager.registerRecipes(properties); CraftingManager.registerRecipes(properties);
CraftingManager.registerDispenserBehaviors();
GameRegistry.registerCraftingHandler(new CraftingManager());
DungeonHelper.initialize(); DungeonHelper.initialize();
gatewayGenerator = new GatewayGenerator(properties); gatewayGenerator = new GatewayGenerator(properties);
GameRegistry.registerWorldGenerator(mod_pocketDim.gatewayGenerator); GameRegistry.registerWorldGenerator(mod_pocketDim.gatewayGenerator);
@@ -278,22 +326,64 @@ public class mod_pocketDim
DDLoot.registerInfo(properties); DDLoot.registerInfo(properties);
proxy.loadTextures(); proxy.loadTextures();
proxy.registerRenderers(); proxy.registerRenderers();
LSystem.generateLSystem("terdragon", LSystem.TERDRAGON, 4);
LSystem.generateLSystem("terdragon", LSystem.TERDRAGON, 5);
// LSystem.generateLSystem("terdragon", LSystem.TERDRAGON, 6); //degenerate
LSystem.generateLSystem("terdragon", LSystem.TERDRAGON, 7);
// LSystem.generateLSystem("terdragon", LSystem.TERDRAGON, 8);
// LSystem.generateLSystem("terdragon", LSystem.TERDRAGON, 9);
// LSystem.generateLSystem("vortex", LSystem.VORTEX, 8);
LSystem.generateLSystem("vortex", LSystem.VORTEX, 9);
LSystem.generateLSystem("vortex", LSystem.VORTEX, 10);
LSystem.generateLSystem("vortex", LSystem.VORTEX, 11);
// LSystem.generateLSystem("vortex", LSystem.VORTEX, 12);
LSystem.generateLSystem("twindragon", LSystem.TWINDRAGON, 7);
LSystem.generateLSystem("twindragon", LSystem.TWINDRAGON, 8);
LSystem.generateLSystem("twindragon", LSystem.TWINDRAGON, 9);
LSystem.generateLSystem("twindragon", LSystem.TWINDRAGON, 10);
// LSystem.generateLSystem("twindragon", LSystem.TWINDRAGON, 11);
LSystem.generateLSystem("dragon", LSystem.DRAGON, 8);
LSystem.generateLSystem("dragon", LSystem.DRAGON, 9);
LSystem.generateLSystem("dragon", LSystem.DRAGON, 10);
LSystem.generateLSystem("dragon", LSystem.DRAGON, 11);
// LSystem.generateLSystem("dragon", LSystem.DRAGON, 12);
// LSystem.generateLSystem("dragon", LSystem.DRAGON, 13);
} }
@EventHandler @EventHandler
public void onPostInitialization(FMLPostInitializationEvent event) public void onPostInitialization(FMLPostInitializationEvent event)
{ {
// Check in case other mods have registered over our biome IDs
DDBiomeGenBase.checkBiomes( new int[] { properties.LimboBiomeID, properties.PocketBiomeID } );
ForgeChunkManager.setForcedChunkLoadingCallback(instance, new ChunkLoaderHelper()); ForgeChunkManager.setForcedChunkLoadingCallback(instance, new ChunkLoaderHelper());
} }
@EventHandler @EventHandler
public void onServerStopping(FMLServerStoppingEvent event) public void onServerStopped(FMLServerStoppedEvent event)
{ {
try try
{ {
PocketManager.unload(); PocketManager.unload();
deathTracker.writeToFile(); deathTracker.writeToFile();
deathTracker = null; deathTracker = null;
worldProperties = null;
currrentSaveRootDirectory = null;
// Unregister all tick receivers from serverTickHandler to avoid leaking
// scheduled tasks between single-player game sessions
serverTickHandler.unregisterReceivers();
spawner = null;
riftRegenerator = null;
limboDecayScheduler = null;
} }
catch (Exception e) catch (Exception e)
{ {
@@ -302,36 +392,54 @@ public class mod_pocketDim
} }
@EventHandler @EventHandler
public void onServerStarting(FMLServerStartingEvent event) public void onServerAboutToStart(FMLServerAboutToStartEvent event)
{ {
//TODO- load dims with forced chunks on server startup here currrentSaveRootDirectory = DimensionManager.getCurrentSaveRootDirectory().getAbsolutePath();
// Register commands with the server // Load the config file that's specific to this world
CommandResetDungeons.instance().register(event); worldProperties = new DDWorldProperties(new File(currrentSaveRootDirectory + "/DimensionalDoors/DimDoorsWorld.cfg"));
CommandCreateDungeonRift.instance().register(event);
CommandDeleteAllLinks.instance().register(event);
//CommandDeleteDimensionData.instance().register(event);
CommandDeleteRifts.instance().register(event);
CommandExportDungeon.instance().register(event);
//CommandPrintDimensionData.instance().register(event);
//CommandPruneDimensions.instance().register(event);
CommandCreatePocket.instance().register(event);
CommandTeleportPlayer.instance().register(event);
// Initialize a new DeathTracker // Initialize a new DeathTracker
String deathTrackerFile = DimensionManager.getCurrentSaveRootDirectory() + "/DimensionalDoors/data/deaths.txt"; deathTracker = new DeathTracker(currrentSaveRootDirectory + "/DimensionalDoors/data/deaths.txt");
deathTracker = new DeathTracker(deathTrackerFile);
// Register regular tick receivers
// CustomLimboPopulator should be initialized before any provider instances are created
spawner = new CustomLimboPopulator(serverTickHandler, properties);
riftRegenerator = new RiftRegenerator(serverTickHandler, blockRift);
limboDecayScheduler = new LimboDecayScheduler(serverTickHandler, limboDecay);
hooks.setSessionFields(worldProperties, riftRegenerator);
}
@EventHandler
public void onServerStarting(FMLServerStartingEvent event)
{
// Register commands with the server
event.registerServerCommand( CommandResetDungeons.instance() );
event.registerServerCommand( CommandCreateDungeonRift.instance() );
event.registerServerCommand( CommandListDungeons.instance() );
event.registerServerCommand( CommandCreateRandomRift.instance() );
event.registerServerCommand( CommandDeleteRifts.instance() );
event.registerServerCommand( CommandExportDungeon.instance() );
event.registerServerCommand( CommandCreatePocket.instance() );
event.registerServerCommand( CommandTeleportPlayer.instance() );
try try
{ {
ChunkLoaderHelper.loadChunkForcedWorlds(event); ChunkLoaderHelper.loadForcedChunkWorlds(event);
} }
catch (Exception e) catch (Exception e)
{ {
System.out.println("Loading chunkloaders failed"); System.err.println("Failed to load chunk loaders for Dimensional Doors. The following error occurred:");
System.err.println(e.toString());
} }
} }
public String getCurrentSavePath()
{
return this.currrentSaveRootDirectory;
}
public static void sendChat(EntityPlayer player, String message) public static void sendChat(EntityPlayer player, String message)
{ {
ChatMessageComponent cmp = new ChatMessageComponent(); ChatMessageComponent cmp = new ChatMessageComponent();

View File

@@ -2,29 +2,25 @@ package StevenDimDoors.mod_pocketDim.saving;
import java.io.File; import java.io.File;
import java.io.FileFilter; import java.io.FileFilter;
import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Deque;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map.Entry;
import net.minecraftforge.common.DimensionManager; import net.minecraftforge.common.DimensionManager;
import StevenDimDoors.mod_pocketDim.Point3D; import StevenDimDoors.mod_pocketDim.Point3D;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.core.DimLink; import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.LinkTypes; import StevenDimDoors.mod_pocketDim.core.DimensionType;
import StevenDimDoors.mod_pocketDim.core.LinkType;
import StevenDimDoors.mod_pocketDim.core.NewDimData; import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager; import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.dungeon.DungeonData; import StevenDimDoors.mod_pocketDim.dungeon.DungeonData;
import StevenDimDoors.mod_pocketDim.dungeon.pack.DungeonPack;
import StevenDimDoors.mod_pocketDim.dungeon.pack.DungeonType;
import StevenDimDoors.mod_pocketDim.helpers.DungeonHelper; import StevenDimDoors.mod_pocketDim.helpers.DungeonHelper;
import StevenDimDoors.mod_pocketDim.util.ConfigurationProcessingException; import StevenDimDoors.mod_pocketDim.util.DDLogger;
import StevenDimDoors.mod_pocketDim.util.FileFilters; import StevenDimDoors.mod_pocketDim.util.FileFilters;
import StevenDimDoors.mod_pocketDim.util.Point4D; import StevenDimDoors.mod_pocketDim.util.Point4D;
import com.google.common.io.Files; import com.google.common.io.Files;
public class DDSaveHandler public class DDSaveHandler
@@ -42,6 +38,8 @@ public class DDSaveHandler
// Don't surround this code with try-catch. Our mod should crash if an error // Don't surround this code with try-catch. Our mod should crash if an error
// occurs at this level, since it could lead to some nasty problems. // occurs at this level, since it could lead to some nasty problems.
DDLogger.startTimer("Loading data");
String basePath = DimensionManager.getCurrentSaveRootDirectory() + "/DimensionalDoors/data/"; String basePath = DimensionManager.getCurrentSaveRootDirectory() + "/DimensionalDoors/data/";
File dataDirectory = new File(basePath); File dataDirectory = new File(basePath);
@@ -61,6 +59,15 @@ public class DDSaveHandler
PocketManager.createAndRegisterBlacklist(blacklist); PocketManager.createAndRegisterBlacklist(blacklist);
} }
// Load the personal pockets mapping
File personalPocketMap = new File(basePath+"personalPockets.txt");
HashMap<String, Integer> ppMap = new HashMap<String, Integer>();
if(personalPocketMap.exists())
{
PersonalPocketMappingProcessor ppMappingProcessor = new PersonalPocketMappingProcessor();
ppMap = readPersonalPocketsMapping(personalPocketMap,ppMappingProcessor);
}
// List any dimension data files and read each dimension // List any dimension data files and read each dimension
DimDataProcessor reader = new DimDataProcessor(); DimDataProcessor reader = new DimDataProcessor();
HashMap<Integer, PackedDimData> packedDims = new HashMap<Integer, PackedDimData>(); HashMap<Integer, PackedDimData> packedDims = new HashMap<Integer, PackedDimData>();
@@ -70,7 +77,12 @@ public class DDSaveHandler
for (File dataFile : dataFiles) for (File dataFile : dataFiles)
{ {
PackedDimData packedDim = readDimension(dataFile, reader); PackedDimData packedDim = readDimension(dataFile, reader);
if(packedDim == null)
{
throw new IllegalStateException("The DD data for "+dataFile.getName().replace(".txt", "")+" at "+dataFile.getPath()+" is corrupted. Please report this on the MCF or on the DD github issues tracker.");
}
packedDims.put(packedDim.ID,packedDim); packedDims.put(packedDim.ID,packedDim);
} }
List<PackedLinkData> linksToUnpack = new ArrayList<PackedLinkData>(); List<PackedLinkData> linksToUnpack = new ArrayList<PackedLinkData>();
@@ -79,7 +91,17 @@ public class DDSaveHandler
{ {
linksToUnpack.addAll(packedDim.Links); linksToUnpack.addAll(packedDim.Links);
} }
return unpackDimData(packedDims)&&unpackLinkData(linksToUnpack); unpackDimData(packedDims);
unpackLinkData(linksToUnpack);
HashMap<String, NewDimData> personalPocketsMap = new HashMap<String, NewDimData>();
for(Entry<String, Integer> pair : ppMap.entrySet())
{
personalPocketsMap.put(pair.getKey(), PocketManager.getDimensionData(pair.getValue()));
}
PocketManager.setPersonalPocketsMapping(personalPocketsMap);
return true;
} }
/** /**
@@ -136,7 +158,7 @@ public class DDSaveHandler
} }
if(isMissing) if(isMissing)
{ {
packedDim=(new PackedDimData(packedDim.ID, packedDim.Depth, packedDim.PackDepth, packedDim.ParentID, packedDim.RootID, packedDim.Orientation, packedDim.IsDungeon, packedDim.IsFilled, packedDim.DungeonData, packedDim.Origin, children, packedDim.Links, packedDim.Tails)); packedDim=(new PackedDimData(packedDim.ID, packedDim.Depth, packedDim.PackDepth, packedDim.ParentID, packedDim.RootID, packedDim.Orientation, DimensionType.getTypeFromIndex(packedDim.DimensionType), packedDim.IsFilled, packedDim.DungeonData, packedDim.Origin, children, packedDim.Links, packedDim.Tails));
packedDims.put(packedDim.ID, packedDim); packedDims.put(packedDim.ID, packedDim);
} }
return children; return children;
@@ -154,12 +176,12 @@ public class DDSaveHandler
{ {
ArrayList<Integer> fosterChildren = new ArrayList<Integer>(); ArrayList<Integer> fosterChildren = new ArrayList<Integer>();
fosterChildren.add(packedDim.ID); fosterChildren.add(packedDim.ID);
DimensionType type = DimensionType.getTypeFromIndex(packedDim.DimensionType);
//fix pockets without parents //fix pockets without parents
if(!packedDims.containsKey(packedDim.ParentID)) if(!packedDims.containsKey(packedDim.ParentID))
{ {
//Fix the orphan by changing its root to its parent, re-connecting it to the list //Fix the orphan by changing its root to its parent, re-connecting it to the list
packedDim=(new PackedDimData(packedDim.ID, 1, packedDim.PackDepth, packedDim.RootID, packedDim.RootID, packedDim.Orientation, packedDim.IsDungeon, packedDim.IsFilled, packedDim.DungeonData, packedDim.Origin, packedDim.ChildIDs, packedDim.Links, packedDim.Tails)); packedDim=(new PackedDimData(packedDim.ID, 1, packedDim.PackDepth, packedDim.RootID, packedDim.RootID, packedDim.Orientation,type, packedDim.IsFilled, packedDim.DungeonData, packedDim.Origin, packedDim.ChildIDs, packedDim.Links, packedDim.Tails));
packedDims.put(packedDim.ID, packedDim); packedDims.put(packedDim.ID, packedDim);
} }
//fix pockets whose parents have forgotten about them //fix pockets whose parents have forgotten about them
@@ -168,7 +190,7 @@ public class DDSaveHandler
{ {
//find the root, and fix it by adding the orphan's ID to its children //find the root, and fix it by adding the orphan's ID to its children
fosterChildren.addAll(fosterParent.ChildIDs); fosterChildren.addAll(fosterParent.ChildIDs);
fosterParent=(new PackedDimData(fosterParent.ID, fosterParent.Depth, fosterParent.PackDepth, fosterParent.ParentID, fosterParent.RootID, fosterParent.Orientation, fosterParent.IsDungeon, fosterParent.IsFilled, fosterParent.DungeonData, fosterParent.Origin, fosterChildren, fosterParent.Links, fosterParent.Tails)); fosterParent=(new PackedDimData(fosterParent.ID, fosterParent.Depth, fosterParent.PackDepth, fosterParent.ParentID, fosterParent.RootID, fosterParent.Orientation, type, fosterParent.IsFilled, fosterParent.DungeonData, fosterParent.Origin, fosterChildren, fosterParent.Links, fosterParent.Tails));
packedDims.put(fosterParent.ID, fosterParent); packedDims.put(fosterParent.ID, fosterParent);
} }
@@ -187,18 +209,14 @@ public class DDSaveHandler
if(packedLink.parent.equals(fakePoint)) if(packedLink.parent.equals(fakePoint))
{ {
NewDimData data = PocketManager.getDimensionData(packedLink.source.getDimension()); NewDimData data = PocketManager.getDimensionData(packedLink.source.getDimension());
int linkType = packedLink.tail.linkType; LinkType linkType = LinkType.getLinkTypeFromIndex(packedLink.tail.linkType);
if((linkType < LinkTypes.ENUM_MIN || linkType > LinkTypes.ENUM_MAX) && linkType != LinkTypes.CLIENT_SIDE)
{
linkType = LinkTypes.NORMAL;
}
DimLink link = data.createLink(packedLink.source, linkType, packedLink.orientation); DimLink link = data.createLink(packedLink.source, linkType, packedLink.orientation, packedLink.lock);
Point4D destination = packedLink.tail.destination; Point4D destination = packedLink.tail.destination;
if(destination!=null) if(destination!=null)
{ {
PocketManager.getDimensionData(destination.getDimension()).setDestination(link, destination.getX(),destination.getY(),destination.getZ()); PocketManager.createDimensionDataDangerously(destination.getDimension()).setLinkDestination(link, destination.getX(),destination.getY(),destination.getZ());
} }
unpackedLinks.add(packedLink); unpackedLinks.add(packedLink);
} }
@@ -210,10 +228,10 @@ public class DDSaveHandler
{ {
for(PackedLinkData packedLink : linksToUnpack) for(PackedLinkData packedLink : linksToUnpack)
{ {
NewDimData data = PocketManager.getDimensionData(packedLink.source.getDimension()); NewDimData data = PocketManager.createDimensionDataDangerously(packedLink.source.getDimension());
if(data.getLink(packedLink.parent)!=null) if(data.getLink(packedLink.parent)!=null)
{ {
data.createChildLink(packedLink.source.getX(), packedLink.source.getY(), packedLink.source.getZ(), data.getLink(packedLink.parent)); data.createChildLink(packedLink.source, data.getLink(packedLink.parent), packedLink.lock);
} }
unpackedLinks.add(packedLink); unpackedLinks.add(packedLink);
} }
@@ -238,48 +256,67 @@ public class DDSaveHandler
} }
} }
public static boolean saveAll(Iterable<? extends IPackable<PackedDimData>> dimensions, List<Integer> blacklist) throws IOException public static boolean saveAll(Iterable<? extends IPackable<PackedDimData>> dimensions,
List<Integer> blacklist, boolean checkModified) throws IOException
{ {
// Create the data directory for our dimensions // Create the data directory for our dimensions
// Don't catch exceptions here. If we can't create this folder, // Don't catch exceptions here. If we can't create this folder,
// the mod should crash to let the user know early on. // the mod should crash to let the user know early on.
String basePath = DimensionManager.getCurrentSaveRootDirectory() + "/DimensionalDoors/data/"; // Get the save directory path
File basePathFile = new File(basePath); File saveDirectory = new File(mod_pocketDim.instance.getCurrentSavePath() + "/DimensionalDoors/data/");
Files.createParentDirs(basePathFile); String savePath = saveDirectory.getAbsolutePath();
basePathFile.mkdir(); String baseSavePath = savePath + "/dim_";
File backupDirectory = new File(savePath + "/backup");
String baseBackupPath = backupDirectory.getAbsolutePath() + "/dim_";
BlacklistProcessor blacklistReader = new BlacklistProcessor(); if (!saveDirectory.exists())
writeBlacklist(blacklist, blacklistReader,basePath);
FileFilter dataFileFilter = new FileFilters.RegexFileFilter("dim_-?\\d+\\.txt");
//TODO Deal with temp files correctly
File[] dataFiles = basePathFile.listFiles(dataFileFilter);
for (File dataFile : dataFiles)
{ {
dataFile.delete(); // Create the save directory
Files.createParentDirs(saveDirectory);
saveDirectory.mkdir();
}
if (!backupDirectory.exists())
{
// Create the backup directory
backupDirectory.mkdir();
} }
// Create and write the blackList
writeBlacklist(blacklist, savePath);
basePathFile = null; //create and write personal pocket mapping
basePath += "dim_"; writePersonalPocketMap(PocketManager.getPersonalPocketMapping(), savePath);
// Write the dimension save data
boolean succeeded = true; boolean succeeded = true;
DimDataProcessor writer = new DimDataProcessor(); DimDataProcessor writer = new DimDataProcessor();
for (IPackable<PackedDimData> dimension : dimensions) for (IPackable<PackedDimData> dimension : dimensions)
{ {
succeeded &= writeDimension(dimension, writer, basePath); // Check if the dimension should be saved
if (!checkModified || dimension.isModified())
{
if (writeDimension(dimension, writer, baseSavePath, baseBackupPath))
{
dimension.clearModified();
} }
else
{
succeeded = false;
}
}
}
return succeeded; return succeeded;
} }
private static boolean writeBlacklist(List<Integer> blacklist, BlacklistProcessor writer, String basePath) private static boolean writeBlacklist(List<Integer> blacklist, String savePath)
{ {
try try
{ {
File tempFile = new File(basePath + "blacklist.tmp"); BlacklistProcessor writer = new BlacklistProcessor();
File saveFile = new File(basePath + "blacklist.txt"); File tempFile = new File(savePath + "/blacklist.tmp");
File saveFile = new File(savePath + "/blacklist.txt");
writer.writeToFile(tempFile, blacklist); writer.writeToFile(tempFile, blacklist);
saveFile.delete(); saveFile.delete();
tempFile.renameTo(saveFile); tempFile.renameTo(saveFile);
@@ -291,20 +328,50 @@ public class DDSaveHandler
printException(e, true); printException(e, true);
return false; return false;
} }
} }
private static boolean writeDimension(IPackable<PackedDimData> dimension, DimDataProcessor writer, String basePath)
private static boolean writePersonalPocketMap(HashMap<String, NewDimData> hashMap, String savePath)
{ {
try try
{ {
File tempFile = new File(basePath + (dimension.name() + ".tmp")); HashMap<String, Integer> ppMap = new HashMap<String, Integer>();
File saveFile = new File(basePath + (dimension.name() + ".txt"));
writer.writeToFile(tempFile, dimension.pack()); for(Entry<String, NewDimData> pair : hashMap.entrySet())
{
ppMap.put(pair.getKey(), pair.getValue().id());
}
PersonalPocketMappingProcessor writer = new PersonalPocketMappingProcessor();
File tempFile = new File(savePath + "/personalPockets.tmp");
File saveFile = new File(savePath + "/personalPockets.txt");
writer.writeToFile(tempFile, ppMap);
saveFile.delete(); saveFile.delete();
tempFile.renameTo(saveFile); tempFile.renameTo(saveFile);
return true; return true;
} }
catch (Exception e) catch (Exception e)
{
System.err.println("Could not save personal pockets mapping. The following error occurred:");
printException(e, true);
return false;
}
}
private static boolean writeDimension(IPackable<PackedDimData> dimension, DimDataProcessor writer, String basePath, String backupPath)
{
try
{
File saveFile = new File(basePath + dimension.name() + ".txt");
// If the save file already exists, back it up.
if (saveFile.exists())
{
Files.move(saveFile, new File(backupPath + dimension.name() + ".txt"));
}
writer.writeToFile(saveFile, dimension.pack());
return true;
}
catch (Exception e)
{ {
System.err.println("Could not save data for dimension #" + dimension.name() + ". The following error occurred:"); System.err.println("Could not save data for dimension #" + dimension.name() + ". The following error occurred:");
printException(e, true); printException(e, true);
@@ -355,7 +422,6 @@ public class DDSaveHandler
public static List<Integer> readBlacklist(File blacklistFile, BlacklistProcessor reader) public static List<Integer> readBlacklist(File blacklistFile, BlacklistProcessor reader)
{ {
try try
{ {
return reader.readFromFile(blacklistFile); return reader.readFromFile(blacklistFile);
@@ -365,6 +431,18 @@ public class DDSaveHandler
e.printStackTrace(); e.printStackTrace();
return null; return null;
} }
}
public static HashMap<String,Integer> readPersonalPocketsMapping(File ppMap, PersonalPocketMappingProcessor reader)
{
try
{
return reader.readFromFile(ppMap);
}
catch (Exception e)
{
e.printStackTrace();
return null;
}
} }
} }

View File

@@ -4,33 +4,60 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.ArrayList; import java.util.HashMap;
import java.util.List; import StevenDimDoors.mod_pocketDim.core.DimensionType;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import StevenDimDoors.mod_pocketDim.Point3D;
import StevenDimDoors.mod_pocketDim.util.BaseConfigurationProcessor; import StevenDimDoors.mod_pocketDim.util.BaseConfigurationProcessor;
import StevenDimDoors.mod_pocketDim.util.ConfigurationProcessingException; import StevenDimDoors.mod_pocketDim.util.ConfigurationProcessingException;
import StevenDimDoors.mod_pocketDim.util.Point4D; import StevenDimDoors.mod_pocketDim.util.JSONValidator;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.stream.JsonReader;
public class DimDataProcessor extends BaseConfigurationProcessor<PackedDimData> public class DimDataProcessor extends BaseConfigurationProcessor<PackedDimData>
{ {
//The name of the version ID where it is stored in the JSON
public final String JSON_VERSION_PROPERTY_NAME = "SAVE_DATA_VERSION_ID_INSTANCE";
//mapping of version IDs to their corresponding schema. Prevents reloading of schema during save/load cycles
private HashMap<Integer, JsonObject> SAVE_DATA_SCHEMA;
//The parser used to read in the JSON Files
private static final JsonParser jsonParser = new JsonParser();
//The directory for JSON schema files
public static final String BASE_SCHEMA_PATH = "/assets/dimdoors/text/";
/**
* Need to manually include a schema defintion for every save file version currently supported
*/
public DimDataProcessor()
{
SAVE_DATA_SCHEMA = new HashMap<Integer, JsonObject>();
//Load the old schema/s
SAVE_DATA_SCHEMA.put(982405775, loadSchema(BASE_SCHEMA_PATH+"Dim_Data_Schema_v982405775.json"));
//load the schema representing the current save data format
SAVE_DATA_SCHEMA.put(PackedDimData.SAVE_DATA_VERSION_ID, loadSchema(BASE_SCHEMA_PATH+"Dim_Data_Schema_v1-0-0.json"));
}
@Override @Override
public PackedDimData readFromStream(InputStream inputStream) public PackedDimData readFromStream(InputStream inputStream)
throws ConfigurationProcessingException throws ConfigurationProcessingException
{ {
try try
{ {
//read in the json save file represeting a single dimension
JsonReader reader = new JsonReader(new InputStreamReader(inputStream, "UTF-8")); JsonReader reader = new JsonReader(new InputStreamReader(inputStream, "UTF-8"));
PackedDimData data = this.createDImDataFromJson(reader); PackedDimData data = this.readDimDataJson(reader);
reader.close(); reader.close();
return data; return data;
} }
catch (IOException e) catch (Exception e)
{ {
e.printStackTrace(); e.printStackTrace();
throw new ConfigurationProcessingException("Could not read packedDimData"); throw new ConfigurationProcessingException("Could not read packedDimData");
@@ -42,259 +69,143 @@ public class DimDataProcessor extends BaseConfigurationProcessor<PackedDimData>
public void writeToStream(OutputStream outputStream, PackedDimData data) public void writeToStream(OutputStream outputStream, PackedDimData data)
throws ConfigurationProcessingException throws ConfigurationProcessingException
{ {
/** Print out dimData using the GSON built in serializer. I dont feel bad doing this because //create a json object from a packedDimData instance
* 1- We can read it
* 2- We are manually reading the data in.
* 3- The error messages tell us exactly where its failing, so its easy to fix
*/
GsonBuilder gsonBuilder = new GsonBuilder(); GsonBuilder gsonBuilder = new GsonBuilder();
Gson gson = gsonBuilder.setPrettyPrinting().create(); gsonBuilder.setPrettyPrinting();
Gson gson = gsonBuilder.create();
JsonElement ele = gson.toJsonTree(data);
try try
{ {
outputStream.write(gson.toJson(data).getBytes("UTF-8")); //ensure our json object corresponds to our schema
JSONValidator.validate(getSaveDataSchema(ele.getAsJsonObject()), ele);
outputStream.write(gson.toJson(ele).getBytes("UTF-8"));
outputStream.close(); outputStream.close();
} }
catch (IOException e) catch (Exception e)
{ {
// not sure if this is kosher, we need it to explode, but not by throwing the IO exception. // not sure if this is kosher, we need it to explode, but not by throwing the IO exception.
throw new ConfigurationProcessingException("Incorrectly formatted save data"); throw new ConfigurationProcessingException("Could not access save data");
} }
} }
/** /**
* Nightmare method that takes a JsonReader pointed at a serialized instance of PackedDimData * validates the save file against it's current version, then updates and validates it again if it needs it
* then it loads it
* @param reader * @param reader
* @return * @return
* @throws IOException * @throws IOException
*/ */
public PackedDimData createDImDataFromJson(JsonReader reader) throws IOException public PackedDimData readDimDataJson(JsonReader reader) throws IOException
{ {
int ID; //read the save file into a Json element
boolean IsDungeon; JsonElement ele = jsonParser.parse(reader);
boolean IsFilled;
int Depth;
int PackDepth;
int ParentID;
int RootID;
PackedDungeonData Dungeon = null;
Point3D Origin;
int Orientation;
List<Integer> ChildIDs;
List<PackedLinkData> Links;
List<PackedLinkTail> Tails = new ArrayList<PackedLinkTail>();
reader.beginObject(); //get the schema that corresponds to the save file's listed version number
JsonObject schema = this.getSaveDataSchema(ele.getAsJsonObject());
reader.nextName(); //validate the save file against its schema
if (reader.nextLong() != PackedDimData.SAVE_DATA_VERSION_ID) JSONValidator.validate(schema, ele);
//handle updating old save data
ele = processSaveData(schema, ele.getAsJsonObject());
//convert the updated and verified json into an instance of PackedDimData
GsonBuilder gsonBuilder = new GsonBuilder();
return gsonBuilder.create().fromJson(ele, PackedDimData.class);
}
/**
* Gets the schema that corresponds to a version of our save data
* @param obj
* @return
* @throws IOException
*/
public JsonObject getSaveDataSchema(JsonObject obj)
{ {
throw new IOException("Save data version mismatch"); JsonObject schema = this.SAVE_DATA_SCHEMA.get(obj.get(JSON_VERSION_PROPERTY_NAME).getAsInt());
}
reader.nextName(); if(schema == null)
ID = reader.nextInt();
reader.nextName();
IsDungeon = reader.nextBoolean();
reader.nextName();
IsFilled = reader.nextBoolean();
reader.nextName();
Depth = reader.nextInt();
reader.nextName();
PackDepth = reader.nextInt();
reader.nextName();
ParentID=reader.nextInt();
reader.nextName();
RootID= reader.nextInt();
if(reader.nextName().equals("DungeonData"))
{ {
Dungeon = createDungeonDataFromJson(reader); throw new IllegalStateException("Invalid save data version");
reader.nextName();
} }
Origin = createPointFromJson(reader); return schema;
reader.nextName();
Orientation = reader.nextInt();
reader.nextName();
ChildIDs = this.createIntListFromJson(reader);
reader.nextName();
Links = this.createLinksListFromJson(reader);
return new PackedDimData(ID, Depth, PackDepth, ParentID, RootID, Orientation, IsDungeon, IsFilled, Dungeon, Origin, ChildIDs, Links, Tails);
} }
private Point3D createPointFromJson(JsonReader reader) throws IOException /**
* Internally load the save data schema so we dont load them every single time we validate save data
* @param path
* @return
*/
private JsonObject loadSchema(String path)
{ {
reader.beginObject(); InputStream in = this.getClass().getResourceAsStream(path);
JsonReader reader = new JsonReader(new InputStreamReader(in));
reader.nextName(); JsonObject schema = jsonParser.parse(reader).getAsJsonObject();
int x = reader.nextInt(); try
reader.nextName();
int y = reader.nextInt();
reader.nextName();
int z = reader.nextInt();
reader.endObject();
return new Point3D(x,y,z);
}
private Point4D createPoint4DFromJson(JsonReader reader) throws IOException
{ {
reader.beginObject(); reader.close();
in.close();
reader.nextName();
int x = reader.nextInt();
reader.nextName();
int y = reader.nextInt();
reader.nextName();
int z = reader.nextInt();
reader.nextName();
int dimension = reader.nextInt();
reader.endObject();
return new Point4D(x,y,z,dimension);
} }
catch (IOException e)
private List<Integer> createIntListFromJson(JsonReader reader) throws IOException
{ {
List<Integer> list = new ArrayList<Integer>(); System.err.println("Could not load Json Save Data definitions");
reader.beginArray(); e.printStackTrace();
throw new IllegalStateException("Could not load Json Save Data definitions");
}
while (reader.peek() != JsonToken.END_ARRAY) return schema;
}
/**
* I use this method to update old save data files to the new format before actually loading them.
* @return
*/
public JsonObject processSaveData(JsonObject schema, JsonObject save)
{ {
list.add(reader.nextInt()); int incomingSaveVersionID = save.get(JSON_VERSION_PROPERTY_NAME).getAsInt();
} // Handle save data versions that are current
reader.endArray(); if(incomingSaveVersionID == PackedDimData.SAVE_DATA_VERSION_ID)
return list;
}
private List<PackedLinkData> createLinksListFromJson(JsonReader reader) throws IOException
{ {
List<PackedLinkData> list = new ArrayList<PackedLinkData>(); JSONValidator.validate(this.getSaveDataSchema(save), save);
return save;
}
reader.beginArray(); // Handle save data versions that are older, starting with the random one.
// We have to
while (reader.peek() != JsonToken.END_ARRAY) if(incomingSaveVersionID== 982405775)
{ {
list.add(createLinkDataFromJson(reader)); DimensionType type;
}
reader.endArray();
return list;
}
private PackedLinkData createLinkDataFromJson(JsonReader reader) throws IOException //see if the dim is a pocket
if(save.get("RootID").getAsInt() != save.get("ID").getAsInt())
{ {
Point4D source; if(save.get("IsDungeon").getAsBoolean())
Point3D parent;
PackedLinkTail tail;
int orientation;
List<Point3D> children = new ArrayList<Point3D>();
reader.beginObject();
reader.nextName();
source = this.createPoint4DFromJson(reader);
reader.nextName();
parent = this.createPointFromJson(reader);
reader.nextName();
tail = this.createLinkTailFromJson(reader);
reader.nextName();
orientation = reader.nextInt();
reader.nextName();
reader.beginArray();
while (reader.peek() != JsonToken.END_ARRAY)
{ {
children.add(this.createPointFromJson(reader)); type = DimensionType.DUNGEON;
} }
reader.endArray(); else
reader.endObject();
return new PackedLinkData(source, parent, tail, orientation, children);
}
private PackedDungeonData createDungeonDataFromJson(JsonReader reader) throws IOException
{ {
int Weight; type = DimensionType.POCKET;
boolean IsOpen; }
boolean IsInternal; }
String SchematicPath; else
String SchematicName;
String DungeonTypeName;
String DungeonPackName;
reader.beginObject();
@SuppressWarnings("unused")
JsonToken test = reader.peek();
if(reader.peek() == JsonToken.END_OBJECT)
{ {
return null; type = DimensionType.ROOT;
} }
reader.nextName(); save.remove("IsDungeon");
Weight=reader.nextInt(); save.addProperty("DimensionType",type.index);
save.remove(this.JSON_VERSION_PROPERTY_NAME);
reader.nextName(); //Need to hardcode the version number here, so if we change the current version then this still updates to the proper version
IsOpen=reader.nextBoolean(); save.addProperty(this.JSON_VERSION_PROPERTY_NAME, 100);
reader.nextName();
IsInternal=reader.nextBoolean();
reader.nextName();
SchematicPath=reader.nextString();
reader.nextName();
SchematicName=reader.nextString();
reader.nextName();
DungeonTypeName=reader.nextString();
reader.nextName();
DungeonPackName=reader.nextString();
reader.endObject();
return new PackedDungeonData(Weight, IsOpen, IsInternal, SchematicPath, SchematicName, DungeonTypeName, DungeonPackName);
}
private PackedLinkTail createLinkTailFromJson(JsonReader reader) throws IOException
{
Point4D destination = null;
int linkType;
reader.beginObject();
reader.nextName();
@SuppressWarnings("unused")
JsonToken test = reader.peek();
if (reader.peek() == JsonToken.BEGIN_OBJECT)
{
destination = this.createPoint4DFromJson(reader);
reader.nextName();
} }
linkType = reader.nextInt(); return processSaveData(this.getSaveDataSchema(save), save);
reader.endObject();
return new PackedLinkTail(destination, linkType);
} }
} }

View File

@@ -4,4 +4,6 @@ public interface IPackable<T>
{ {
public String name(); public String name();
public T pack(); public T pack();
public boolean isModified();
public void clearModified();
} }

View File

@@ -2,17 +2,16 @@ package StevenDimDoors.mod_pocketDim.saving;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import StevenDimDoors.mod_pocketDim.DimData; import StevenDimDoors.mod_pocketDim.DimData;
import StevenDimDoors.mod_pocketDim.LinkData; import StevenDimDoors.mod_pocketDim.LinkData;
import StevenDimDoors.mod_pocketDim.Point3D;
import StevenDimDoors.mod_pocketDim.ObjectSaveInputStream; import StevenDimDoors.mod_pocketDim.ObjectSaveInputStream;
import StevenDimDoors.mod_pocketDim.Point3D;
import StevenDimDoors.mod_pocketDim.core.DimensionType;
import StevenDimDoors.mod_pocketDim.core.LinkType;
import StevenDimDoors.mod_pocketDim.util.Point4D; import StevenDimDoors.mod_pocketDim.util.Point4D;
public class OldSaveImporter public class OldSaveImporter
@@ -39,35 +38,83 @@ public class OldSaveImporter
return; return;
} }
//build the child list
HashMap<Integer, ArrayList<Integer>> parentChildMapping = new HashMap<Integer, ArrayList<Integer>>();
for(DimData data : dimMap.values())
{
if(data.isPocket)
{
LinkData link = data.exitDimLink;
if(parentChildMapping.containsKey(link.destDimID))
{
parentChildMapping.get(link.destDimID).add(data.dimID);
}
else
{
parentChildMapping.put(link.destDimID, new ArrayList<Integer>());
parentChildMapping.get(link.destDimID).add(data.dimID);
}
parentChildMapping.remove(data.dimID);
}
}
for(DimData data : dimMap.values()) for(DimData data : dimMap.values())
{ {
List<PackedLinkData> newPackedLinkData = new ArrayList<PackedLinkData>(); List<PackedLinkData> newPackedLinkData = new ArrayList<PackedLinkData>();
List<Integer> childDims = new ArrayList<Integer>(); List<Integer> childDims;
if(parentChildMapping.containsKey(data.dimID))
{
childDims =parentChildMapping.get(data.dimID);
}
else
{
childDims = new ArrayList<Integer>();
}
for(LinkData link : data.getLinksInDim()) for(LinkData link : data.getLinksInDim())
{ {
Point4D source = new Point4D(link.locXCoord,link.locYCoord,link.locZCoord,link.locDimID); Point4D source = new Point4D(link.locXCoord,link.locYCoord,link.locZCoord,link.locDimID);
Point4D destintion = new Point4D(link.destXCoord,link.destYCoord,link.destZCoord,link.destDimID); Point4D destintion = new Point4D(link.destXCoord,link.destYCoord,link.destZCoord,link.destDimID);
PackedLinkTail tail = new PackedLinkTail(destintion, link.linkOrientation); PackedLinkTail tail = new PackedLinkTail(destintion, LinkType.NORMAL);
List<Point3D> children = new ArrayList<Point3D>(); List<Point3D> children = new ArrayList<Point3D>();
PackedLinkData newPackedLink = new PackedLinkData(source, new Point3D(-1,-1,-1), tail, link.linkOrientation,children); PackedLinkData newPackedLink = new PackedLinkData(source, new Point3D(-1,-1,-1), tail, link.linkOrientation,children, null);
newPackedLinkData.add(newPackedLink); newPackedLinkData.add(newPackedLink);
allPackedLinks.add(newPackedLink); allPackedLinks.add(newPackedLink);
} }
PackedDimData dim;
DimensionType type;
PackedDimData dim = new PackedDimData(data.dimID, data.depth, data.depth, data.exitDimLink.locDimID, data.exitDimLink.locDimID, 0, data.dungeonGenerator!=null, data.hasBeenFilled, null, new Point3D(0,64,0), childDims, newPackedLinkData, null); if(data.isPocket)
{
if(data.dungeonGenerator!=null)
{
type = DimensionType.DUNGEON;
}
else
{
type = DimensionType.POCKET;
}
}
else
{
type = DimensionType.ROOT;
}
if(data.isPocket)
{
dim = new PackedDimData(data.dimID, data.depth, data.depth, data.exitDimLink.locDimID, data.exitDimLink.locDimID, 0, type, data.hasBeenFilled, null, new Point3D(0,64,0), childDims, newPackedLinkData, null);
}
else
{
dim = new PackedDimData(data.dimID, data.depth, data.depth, data.dimID, data.dimID, 0, type, data.hasBeenFilled, null, new Point3D(0,64,0), childDims, newPackedLinkData, null);
}
newPackedDimData.put(dim.ID,dim); newPackedDimData.put(dim.ID,dim);
}
DDSaveHandler.unpackDimData(newPackedDimData); DDSaveHandler.unpackDimData(newPackedDimData);
DDSaveHandler.unpackLinkData(allPackedLinks); DDSaveHandler.unpackLinkData(allPackedLinks);
}
} }
} }

View File

@@ -3,14 +3,15 @@ package StevenDimDoors.mod_pocketDim.saving;
import java.util.List; import java.util.List;
import StevenDimDoors.mod_pocketDim.Point3D; import StevenDimDoors.mod_pocketDim.Point3D;
import StevenDimDoors.mod_pocketDim.core.DimensionType;
public class PackedDimData public class PackedDimData
{ {
// These fields will be public since this is a simple data container // These fields will be public since this is a simple data container
public final static long SAVE_DATA_VERSION_ID = 982405775L; public final static int SAVE_DATA_VERSION_ID = 100;
public final long SAVE_DATA_VERSION_ID_INSTANCE = SAVE_DATA_VERSION_ID; public final long SAVE_DATA_VERSION_ID_INSTANCE = SAVE_DATA_VERSION_ID;
public final int ID; public final int ID;
public final boolean IsDungeon; public final int DimensionType;
public final boolean IsFilled; public final boolean IsFilled;
public final int Depth; public final int Depth;
public final int PackDepth; public final int PackDepth;
@@ -26,7 +27,7 @@ public class PackedDimData
// FIXME Missing dungeon data, not sure how to include it // FIXME Missing dungeon data, not sure how to include it
public PackedDimData(int id, int depth, int packDepth, int parentID, int rootID, int orientation, public PackedDimData(int id, int depth, int packDepth, int parentID, int rootID, int orientation,
boolean isDungeon, boolean isFilled,PackedDungeonData dungeonData, Point3D origin, List<Integer> childIDs, List<PackedLinkData> links, DimensionType type, boolean isFilled,PackedDungeonData dungeonData, Point3D origin, List<Integer> childIDs, List<PackedLinkData> links,
List<PackedLinkTail> tails) List<PackedLinkTail> tails)
{ {
ID = id; ID = id;
@@ -35,7 +36,7 @@ public class PackedDimData
ParentID = parentID; ParentID = parentID;
RootID = rootID; RootID = rootID;
Orientation = orientation; Orientation = orientation;
IsDungeon = isDungeon; DimensionType = type.index;
IsFilled = isFilled; IsFilled = isFilled;
DungeonData = dungeonData; DungeonData = dungeonData;
Origin = origin; Origin = origin;
@@ -49,4 +50,6 @@ public class PackedDimData
{ {
return "ID= "+this.ID; return "ID= "+this.ID;
} }
} }

View File

@@ -3,6 +3,7 @@ package StevenDimDoors.mod_pocketDim.saving;
import java.util.List; import java.util.List;
import StevenDimDoors.mod_pocketDim.Point3D; import StevenDimDoors.mod_pocketDim.Point3D;
import StevenDimDoors.mod_pocketDim.core.DDLock;
import StevenDimDoors.mod_pocketDim.util.Point4D; import StevenDimDoors.mod_pocketDim.util.Point4D;
public class PackedLinkData public class PackedLinkData
@@ -12,13 +13,15 @@ public class PackedLinkData
public final PackedLinkTail tail; public final PackedLinkTail tail;
public final int orientation; public final int orientation;
public final List<Point3D> children; public final List<Point3D> children;
public final DDLock lock;
public PackedLinkData(Point4D source, Point3D parent, PackedLinkTail tail, int orientation, List<Point3D> children) public PackedLinkData(Point4D source, Point3D parent, PackedLinkTail tail, int orientation, List<Point3D> children, DDLock lock)
{ {
this.source=source; this.source=source;
this.parent=parent; this.parent=parent;
this.tail=tail; this.tail=tail;
this.orientation=orientation; this.orientation=orientation;
this.children=children; this.children=children;
this.lock = lock;
} }
} }

View File

@@ -1,5 +1,6 @@
package StevenDimDoors.mod_pocketDim.saving; package StevenDimDoors.mod_pocketDim.saving;
import StevenDimDoors.mod_pocketDim.core.LinkType;
import StevenDimDoors.mod_pocketDim.util.Point4D; import StevenDimDoors.mod_pocketDim.util.Point4D;
public class PackedLinkTail public class PackedLinkTail
@@ -7,10 +8,10 @@ public class PackedLinkTail
public final Point4D destination; public final Point4D destination;
public final int linkType; public final int linkType;
public PackedLinkTail(Point4D destination, int linkType) public PackedLinkTail(Point4D destination, LinkType linkType)
{ {
this.destination=destination; this.destination=destination;
this.linkType=linkType; this.linkType=linkType.index;
} }
} }

View File

@@ -0,0 +1,79 @@
package StevenDimDoors.mod_pocketDim.saving;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import StevenDimDoors.mod_pocketDim.util.BaseConfigurationProcessor;
import StevenDimDoors.mod_pocketDim.util.ConfigurationProcessingException;
public class PersonalPocketMappingProcessor extends BaseConfigurationProcessor<HashMap<String, Integer>>
{
@Override
public HashMap<String, Integer> readFromStream(InputStream inputStream) throws ConfigurationProcessingException
{
try
{
JsonReader reader = new JsonReader(new InputStreamReader(inputStream, "UTF-8"));
HashMap<String, Integer> data = this.createPersonalPocketsMapFromJson(reader);
reader.close();
return data;
}
catch (IOException e)
{
e.printStackTrace();
throw new ConfigurationProcessingException("Could not read personal pocket mapping");
}
}
private HashMap<String, Integer> createPersonalPocketsMapFromJson(JsonReader reader) throws IOException
{
HashMap<String, Integer> ppMap;
ppMap = this.createMapFromJson(reader);
return ppMap;
}
private HashMap<String, Integer> createMapFromJson(JsonReader reader) throws IOException
{
HashMap<String, Integer> map = new HashMap<String, Integer>();
reader.beginObject();
while(reader.peek()!= JsonToken.END_OBJECT)
{
map.put(reader.nextName(), reader.nextInt());
}
reader.endObject();
return map;
}
@Override
public void writeToStream(OutputStream outputStream, HashMap<String, Integer> data) throws ConfigurationProcessingException
{
GsonBuilder gsonBuilder = new GsonBuilder();
Gson gson = gsonBuilder.setPrettyPrinting().create();
try
{
outputStream.write(gson.toJson(data).getBytes("UTF-8"));
outputStream.close();
}
catch (IOException e)
{
// not sure if this is kosher, we need it to explode, but not by throwing the IO exception.
throw new ConfigurationProcessingException("Incorrectly formatted save data");
}
}
}

View File

@@ -22,6 +22,7 @@ public class BlockRotator
static static
{ {
hasOrientations[Block.dispenser.blockID] = true; hasOrientations[Block.dispenser.blockID] = true;
hasOrientations[Block.dropper.blockID] = true;
hasOrientations[Block.stairsStoneBrick.blockID] = true; hasOrientations[Block.stairsStoneBrick.blockID] = true;
hasOrientations[Block.lever.blockID] = true; hasOrientations[Block.lever.blockID] = true;
hasOrientations[Block.stoneButton.blockID] = true; hasOrientations[Block.stoneButton.blockID] = true;
@@ -69,6 +70,8 @@ public class BlockRotator
hasOrientations[mod_pocketDim.dimensionalDoor.blockID] = true; hasOrientations[mod_pocketDim.dimensionalDoor.blockID] = true;
hasOrientations[mod_pocketDim.warpDoor.blockID] = true; hasOrientations[mod_pocketDim.warpDoor.blockID] = true;
hasOrientations[mod_pocketDim.goldenDimensionalDoor.blockID] = true;
hasOrientations[mod_pocketDim.personalDimDoor.blockID] = true;
} }
@@ -241,7 +244,7 @@ public class BlockRotator
break; break;
} }
} }
else if (blockID == Block.chest.blockID || blockID == Block.chestTrapped.blockID || blockID == Block.ladder.blockID || blockID == Block.hopperBlock.blockID|| blockID == Block.furnaceBurning.blockID|| blockID == Block.furnaceIdle.blockID) else if (blockID == Block.chest.blockID || blockID == Block.chestTrapped.blockID || blockID == Block.ladder.blockID || blockID == Block.furnaceBurning.blockID|| blockID == Block.furnaceIdle.blockID)
{ {
switch (metadata) switch (metadata)
{ {
@@ -258,7 +261,36 @@ public class BlockRotator
metadata = 3; metadata = 3;
break; break;
} }
}
else if (blockID == Block.hopperBlock.blockID)
{
switch (metadata)
{
case 2:
metadata = 5;
break;
case 3:
metadata = 4;
break;
case 4:
metadata = 2;
break;
case 5:
metadata = 3;
break;
case 10:
metadata = 13;
break;
case 11:
metadata = 12;
break;
case 12:
metadata = 10;
break;
case 13:
metadata = 11;
break;
}
} }
else if (blockID==Block.vine.blockID) else if (blockID==Block.vine.blockID)
{ {
@@ -352,7 +384,7 @@ public class BlockRotator
break; break;
} }
} }
else if(blockID== Block.lever.blockID||blockID== Block.stoneButton.blockID||blockID== Block.stoneButton.blockID||blockID== Block.woodenButton.blockID||blockID== Block.torchWood.blockID||blockID== Block.torchRedstoneIdle.blockID||blockID== Block.torchRedstoneActive.blockID) else if(blockID== Block.lever.blockID || blockID == Block.stoneButton.blockID || blockID == Block.woodenButton.blockID || blockID== Block.torchWood.blockID||blockID== Block.torchRedstoneIdle.blockID||blockID== Block.torchRedstoneActive.blockID)
{ {
switch (metadata) switch (metadata)
{ {

View File

@@ -7,11 +7,16 @@ import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
public class ChunkBlockSetter implements IBlockSetter public class ChunkBlockSetter implements IBlockSetter
{ {
public ChunkBlockSetter() { } private boolean ignoreAir;
public ChunkBlockSetter(boolean ignoreAir)
{
this.ignoreAir = ignoreAir;
}
public void setBlock(World world, int x, int y, int z, int blockID, int metadata) public void setBlock(World world, int x, int y, int z, int blockID, int metadata)
{ {
if (blockID != 0 && Block.blocksList[blockID] == null) if ((blockID == 0 && ignoreAir) || (blockID != 0 && Block.blocksList[blockID] == null))
{ {
return; return;
} }

View File

@@ -362,15 +362,15 @@ public class Schematic {
return filter.apply(this, this.blocks, this.metadata); return filter.apply(this, this.blocks, this.metadata);
} }
public void copyToWorld(World world, int x, int y, int z, boolean notifyClients) public void copyToWorld(World world, int x, int y, int z, boolean notifyClients, boolean ignoreAir)
{ {
if (notifyClients) if (notifyClients)
{ {
copyToWorld(world, x, y, z, new WorldBlockSetter(false, true)); copyToWorld(world, x, y, z, new WorldBlockSetter(false, true, ignoreAir));
} }
else else
{ {
copyToWorld(world, x, y, z, new ChunkBlockSetter()); copyToWorld(world, x, y, z, new ChunkBlockSetter(ignoreAir));
} }
} }

View File

@@ -11,16 +11,21 @@ public class WorldBlockSetter implements IBlockSetter
public final int NOTIFY_CLIENT_FLAG = 2; public final int NOTIFY_CLIENT_FLAG = 2;
private int flags; private int flags;
private boolean ignoreAir;
public WorldBlockSetter(boolean doBlockUpdates, boolean notifyClients) public WorldBlockSetter(boolean doBlockUpdates, boolean notifyClients, boolean ignoreAir)
{ {
flags = 0; this.flags = 0;
flags += doBlockUpdates ? BLOCK_UPDATES_FLAG : 0; this.flags += doBlockUpdates ? BLOCK_UPDATES_FLAG : 0;
flags += notifyClients ? NOTIFY_CLIENT_FLAG : 0; this.flags += notifyClients ? NOTIFY_CLIENT_FLAG : 0;
this.ignoreAir = ignoreAir;
} }
public void setBlock(World world, int x, int y, int z, int blockID, int metadata) public void setBlock(World world, int x, int y, int z, int blockID, int metadata)
{
if (!ignoreAir || blockID != 0)
{ {
world.setBlock(x, y, z, blockID, metadata, flags); world.setBlock(x, y, z, blockID, metadata, flags);
} }
} }
}

View File

@@ -1,6 +1,5 @@
package StevenDimDoors.mod_pocketDim.ticking; package StevenDimDoors.mod_pocketDim.ticking;
import java.util.ArrayList;
import java.util.Random; import java.util.Random;
import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ConcurrentLinkedQueue;
@@ -9,8 +8,8 @@ import net.minecraft.server.MinecraftServer;
import net.minecraft.world.GameRules; import net.minecraft.world.GameRules;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.common.DimensionManager; import net.minecraftforge.common.DimensionManager;
import StevenDimDoors.mod_pocketDim.DDProperties;
import StevenDimDoors.mod_pocketDim.mod_pocketDim; import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.config.DDProperties;
import StevenDimDoors.mod_pocketDim.core.NewDimData; import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager; import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.helpers.yCoordHelper; import StevenDimDoors.mod_pocketDim.helpers.yCoordHelper;
@@ -31,12 +30,14 @@ public class CustomLimboPopulator implements IRegularTickReceiver {
{ {
this.properties = properties; this.properties = properties;
this.locations = new ConcurrentLinkedQueue<ChunkLocation>(); this.locations = new ConcurrentLinkedQueue<ChunkLocation>();
sender.registerForTicking(this, MONOLITH_SPAWNING_INTERVAL, false); sender.registerReceiver(this, MONOLITH_SPAWNING_INTERVAL, false);
} }
@Override @Override
public void notifyTick() { public void notifyTick() {
World limboWorld = null;
// Check if any new spawning requests have come in // Check if any new spawning requests have come in
if (!locations.isEmpty()) if (!locations.isEmpty())
{ {
@@ -50,11 +51,21 @@ public class CustomLimboPopulator implements IRegularTickReceiver {
if (location.DimensionID == properties.LimboDimensionID) if (location.DimensionID == properties.LimboDimensionID)
{ {
// Limbo chunk // Limbo chunk
placeMonolithsInLimbo(location.DimensionID, location.ChunkX, location.ChunkZ);
World world = DimensionManager.getWorld(location.DimensionID); // SenseiKiwi: Check if we haven't loaded Limbo for another request in this request
// cycle. If so, try to load Limbo up. This solves a strange issue with ChickenChunks
// where CC somehow forces chunks to generate in Limbo if LimboProvider.canRespawnHere()
// is true, yet when execution reaches this point, Limbo isn't loaded anymore! My theory
// is that CC force-loads a chunk for some reason, but since there are no players around,
// Limbo immediately unloads after standard world gen runs, and before this code can run.
mod_pocketDim.instance.gatewayGenerator.generate(world.rand, location.ChunkX, location.ChunkZ,world, world.getChunkProvider(), world.getChunkProvider()); if (limboWorld == null)
{
limboWorld = PocketManager.loadDimension(properties.LimboDimensionID);
}
placeMonolithsInLimbo(limboWorld, location.ChunkX, location.ChunkZ);
mod_pocketDim.gatewayGenerator.generate(limboWorld.rand, location.ChunkX, location.ChunkZ,
limboWorld, limboWorld.getChunkProvider(), limboWorld.getChunkProvider());
} }
else else
{ {
@@ -145,15 +156,8 @@ public class CustomLimboPopulator implements IRegularTickReceiver {
while (sanity < 5 && !didSpawn); while (sanity < 5 && !didSpawn);
} }
private void placeMonolithsInLimbo(int dimensionID, int chunkX, int chunkZ) private void placeMonolithsInLimbo(World limbo, int chunkX, int chunkZ)
{ {
World limbo = DimensionManager.getWorld(dimensionID);
if (limbo == null)
{
return;
}
//The following initialization code is based on code from ChunkProviderGenerate. //The following initialization code is based on code from ChunkProviderGenerate.
//It makes our generation depend on the world seed. //It makes our generation depend on the world seed.
Random random = new Random(limbo.getSeed() ^ 0xB5130C4ACC71A822L); Random random = new Random(limbo.getSeed() ^ 0xB5130C4ACC71A822L);

View File

@@ -1,53 +0,0 @@
package StevenDimDoors.mod_pocketDim.ticking;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import net.minecraft.world.World;
import net.minecraftforge.common.DimensionManager;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.util.Point4D;
public class FastRiftRegenerator implements IRegularTickReceiver {
private static final int RIFT_REGENERATION_INTERVAL = 10; //Regenerate scheduled rifts every 10 ticks
private static Random random = new Random();
private ArrayList<Point4D> locationsToRegen = new ArrayList<Point4D>();
public FastRiftRegenerator(IRegularTickSender sender)
{
sender.registerForTicking(this, RIFT_REGENERATION_INTERVAL, false);
}
@Override
public void notifyTick()
{
regenerateScheduledRifts();
}
public void regenerateScheduledRifts()
{
if (!locationsToRegen.isEmpty())
{
List<Integer> loadedWorlds = (List<Integer>) Arrays.asList(DimensionManager.getIDs());
for (Point4D point: locationsToRegen)
{
if (loadedWorlds.contains(point.getDimension()) && PocketManager.getLink(point) != null)
{
World world = DimensionManager.getWorld(point.getDimension());
mod_pocketDim.blockRift.regenerateRift(world, point.getX(), point.getY(), point.getZ(), random);
}
}
locationsToRegen.clear();
}
}
public void registerRiftForRegen(int x, int y, int z, int dimID)
{
this.locationsToRegen.add(new Point4D(x, y, z, dimID));
}
}

View File

@@ -3,6 +3,7 @@ package StevenDimDoors.mod_pocketDim.ticking;
public interface IRegularTickSender { public interface IRegularTickSender {
public void registerForTicking(IRegularTickReceiver receiver, int interval, boolean onTickStart); public void registerReceiver(IRegularTickReceiver receiver, int interval, boolean onTickStart);
public void unregisterReceivers();
} }

View File

@@ -0,0 +1,28 @@
package StevenDimDoors.mod_pocketDim.ticking;
import StevenDimDoors.mod_pocketDim.world.LimboDecay;
/**
* Handles scheduling of periodic fast Limbo decay operations.
*/
public class LimboDecayScheduler implements IRegularTickReceiver {
private static final int LIMBO_DECAY_INTERVAL = 10; //Apply fast decay every 10 ticks
private LimboDecay decay;
public LimboDecayScheduler(IRegularTickSender tickSender, LimboDecay decay)
{
this.decay = decay;
tickSender.registerReceiver(this, LIMBO_DECAY_INTERVAL, false);
}
/**
* Applies fast Limbo decay periodically.
*/
@Override
public void notifyTick()
{
decay.applyRandomFastDecay();
}
}

View File

@@ -2,24 +2,18 @@ package StevenDimDoors.mod_pocketDim.ticking;
import java.util.List; import java.util.List;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.entity.DataWatcher;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityFlying; import net.minecraft.entity.EntityFlying;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.SharedMonsterAttributes; import net.minecraft.entity.SharedMonsterAttributes;
import net.minecraft.entity.monster.IMob; import net.minecraft.entity.monster.IMob;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.ChunkCoordinates;
import net.minecraft.util.DamageSource; import net.minecraft.util.DamageSource;
import net.minecraft.util.MathHelper; import net.minecraft.util.MathHelper;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.common.ForgeHooks;
import StevenDimDoors.mod_pocketDim.DDProperties;
import StevenDimDoors.mod_pocketDim.mod_pocketDim; import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.config.DDProperties;
import StevenDimDoors.mod_pocketDim.core.DDTeleporter; import StevenDimDoors.mod_pocketDim.core.DDTeleporter;
import StevenDimDoors.mod_pocketDim.util.Point4D; import StevenDimDoors.mod_pocketDim.util.Point4D;
import StevenDimDoors.mod_pocketDim.world.LimboProvider; import StevenDimDoors.mod_pocketDim.world.LimboProvider;
@@ -27,21 +21,31 @@ import StevenDimDoors.mod_pocketDim.world.PocketProvider;
public class MobMonolith extends EntityFlying implements IMob public class MobMonolith extends EntityFlying implements IMob
{ {
public int aggro = 0; private static final short MAX_AGGRO = 250;
private float soundTime = 0; private static final short MAX_AGGRO_CAP = 100;
private byte textureState = 0; private static final short MIN_AGGRO_CAP = 25;
private float scaleFactor = 0; private static final int MAX_TEXTURE_STATE = 18;
private int aggroMax; private static final int MAX_SOUND_COOLDOWN = 200;
private static final int MAX_AGGRO_RANGE = 35;
private static final int AGGRO_WATCHER_INDEX = 16;
private static final float WIDTH = 3f;
private static final float HEIGHT = 3f;
private static final float EYE_HEIGHT = HEIGHT / 2;
public float pitchLevel;
private short aggro = 0;
private int soundTime = 0;
private final short aggroCap;
private static DDProperties properties = null; private static DDProperties properties = null;
public MobMonolith(World par1World) public MobMonolith(World world)
{ {
super(par1World); super(world);
this.setSize(3F, 9.0F); this.setSize(WIDTH, HEIGHT);
this.noClip = true; this.noClip = true;
this.scaleFactor = (float) ((rand.nextDouble()/2)+1); this.aggroCap = (short) MathHelper.getRandomIntegerInRange(this.rand, MIN_AGGRO_CAP, MAX_AGGRO_CAP);
this.aggroMax = rand.nextInt(245)+200;
if (properties == null) if (properties == null)
properties = DDProperties.instance(); properties = DDProperties.instance();
} }
@@ -55,8 +59,19 @@ public class MobMonolith extends EntityFlying implements IMob
@Override @Override
public boolean attackEntityFrom(DamageSource par1DamageSource, float par2) public boolean attackEntityFrom(DamageSource par1DamageSource, float par2)
{ {
if (par1DamageSource != DamageSource.inWall)
{
this.aggro = MAX_AGGRO;
}
return false; return false;
} }
@Override
public boolean canBreatheUnderwater()
{
return true;
}
@Override @Override
public AxisAlignedBB getBoundingBox() public AxisAlignedBB getBoundingBox()
{ {
@@ -79,62 +94,29 @@ public class MobMonolith extends EntityFlying implements IMob
protected void applyEntityAttributes() protected void applyEntityAttributes()
{ {
super.applyEntityAttributes(); super.applyEntityAttributes();
this.getAttributeMap().getAttributeInstance(SharedMonsterAttributes.maxHealth).setAttribute(10); this.getAttributeMap().getAttributeInstance(SharedMonsterAttributes.maxHealth).setAttribute(57005);
} }
@Override
public boolean canBePushed() public boolean canBePushed()
{ {
return false; return false;
} }
@Override @Override
public float getRenderSizeModifier() public float getEyeHeight()
{ {
return this.scaleFactor; return EYE_HEIGHT;
}
public void setEntityPosition(Entity entity, double x, double y, double z)
{
entity.lastTickPosX = entity.prevPosX = entity.posX = x;
entity.lastTickPosY = entity.prevPosY = entity.posY = y + entity.yOffset;
entity.lastTickPosZ = entity.prevPosZ = entity.posZ = z;
entity.setPosition(x, y, z);
} }
@Override @Override
protected void entityInit() protected void entityInit()
{ {
super.entityInit(); super.entityInit();
this.dataWatcher.addObject(16, Byte.valueOf((byte)0)); // Add a short for the aggro level
this.dataWatcher.addObject(AGGRO_WATCHER_INDEX, Short.valueOf((short) 0));
} }
public boolean isClipping()
{
int i = MathHelper.floor_double(this.boundingBox.minX);
int j = MathHelper.floor_double(this.boundingBox.maxX + 1.0D);
int k = MathHelper.floor_double(this.boundingBox.minY);
int l = MathHelper.floor_double(this.boundingBox.maxY + 1.0D);
int i1 = MathHelper.floor_double(this.boundingBox.minZ);
int j1 = MathHelper.floor_double(this.boundingBox.maxZ + 1.0D);
for (int k1 = i; k1 < j; ++k1)
{
for (int l1 = k; l1 < l; ++l1)
{
for (int i2 = i1; i2 < j1; ++i2)
{
if(!this.worldObj.isAirBlock(k1, l1, i2))
{
return true;
}
}
}
}
return false;
}
@Override @Override
public boolean isEntityAlive() public boolean isEntityAlive()
{ {
@@ -144,186 +126,177 @@ public class MobMonolith extends EntityFlying implements IMob
@Override @Override
public void onEntityUpdate() public void onEntityUpdate()
{ {
// Remove this Monolith if it's not in Limbo or in a pocket dimension
if (!(this.worldObj.provider instanceof LimboProvider || this.worldObj.provider instanceof PocketProvider)) if (!(this.worldObj.provider instanceof LimboProvider || this.worldObj.provider instanceof PocketProvider))
{ {
this.setDead(); this.setDead();
super.onEntityUpdate();
return;
} }
super.onEntityUpdate(); super.onEntityUpdate();
if(this.isClipping())
// Check for players and update aggro levels even if there are no players in range
EntityPlayer player = this.worldObj.getClosestPlayerToEntity(this, MAX_AGGRO_RANGE);
boolean visibility = (player != null) ? player.canEntityBeSeen(this) : false;
this.updateAggroLevel(player, visibility);
// Change orientation and face a player if one is in range
if (player != null)
{ {
this.moveEntity(0, .1, 0); this.facePlayer(player);
if (!this.worldObj.isRemote && !(this.worldObj.provider instanceof LimboProvider))
{
// Play sounds on the server side, if the player isn't in Limbo.
// Limbo is excluded to avoid drowning out its background music.
// Also, since it's a large open area with many Monoliths, some
// of the sounds that would usually play for a moment would
// keep playing constantly and would get very annoying.
this.playSounds(player);
} }
EntityPlayer entityPlayer = this.worldObj.getClosestPlayerToEntity(this, 35); if (visibility)
if (entityPlayer != null)
{ {
// Only spawn particles on the client side and outside Limbo
if (this.worldObj.isRemote && !(this.worldObj.provider instanceof LimboProvider))
{
this.spawnParticles(player);
}
// Teleport the target player if various conditions are met
if (aggro >= MAX_AGGRO && !this.worldObj.isRemote &&
properties.MonolithTeleportationEnabled && !player.capabilities.isCreativeMode &&
!(this.worldObj.provider instanceof LimboProvider))
{
this.aggro = 0;
Point4D destination = LimboProvider.getLimboSkySpawn(player, properties);
DDTeleporter.teleportEntity(player, destination, false);
player.worldObj.playSoundAtEntity(player, mod_pocketDim.modid + ":crack", 13, 1);
}
}
}
}
private void updateAggroLevel(EntityPlayer player, boolean visibility)
{
// If we're working on the server side, adjust aggro level
// If we're working on the client side, retrieve aggro level from dataWatcher
if (!this.worldObj.isRemote)
{
// Server side...
// Rapidly increase the aggro level if this Monolith can see the player
if (visibility)
{
if (this.worldObj.provider instanceof LimboProvider)
{
aggro++;
}
else
{
// Aggro increases faster outside of Limbo
aggro += 3;
}
}
else
{
if (aggro > aggroCap)
{
// Decrease aggro over time
aggro--;
}
else if (player != null && (aggro < aggroCap))
{
// Increase aggro if a player is within range and aggro < aggroCap
aggro++;
}
}
// Clamp the aggro level
aggro = (short) MathHelper.clamp_int(aggro, 0, MAX_AGGRO);
this.dataWatcher.updateObject(AGGRO_WATCHER_INDEX, Short.valueOf(aggro));
}
else
{
// Client side...
aggro = this.dataWatcher.getWatchableObjectShort(AGGRO_WATCHER_INDEX);
}
}
public int getTextureState()
{
// Determine texture state from aggro progress
return MathHelper.clamp_int(MAX_TEXTURE_STATE * aggro / MAX_AGGRO, 0, MAX_TEXTURE_STATE);
}
/**
* Plays sounds at different levels of aggro, using soundTime to prevent too many sounds at once.
* @param entityPlayer
*/
private void playSounds(EntityPlayer entityPlayer)
{
float aggroPercent = this.getAggroProgress();
if (this.soundTime <= 0) if (this.soundTime <= 0)
{ {
this.playSound(mod_pocketDim.modid + ":monk", 1F, 1F); this.playSound(mod_pocketDim.modid + ":monk", 1F, 1F);
this.soundTime = 100; this.soundTime = 100;
} }
if ((aggroPercent > 0.70) && this.soundTime < 100)
{
this.worldObj.playSoundEffect(entityPlayer.posX, entityPlayer.posY, entityPlayer.posZ, mod_pocketDim.modid + ":tearing", 1F, (float) (1 + this.rand.nextGaussian()));
this.soundTime = 100 + this.rand.nextInt(75);
}
if ((aggroPercent > 0.80) && this.soundTime < 200)
{
this.worldObj.playSoundEffect(entityPlayer.posX, entityPlayer.posY, entityPlayer.posZ, mod_pocketDim.modid + ":tearing", 7, 1F);
this.soundTime = 250;
}
this.soundTime--;
}
this.faceEntity(entityPlayer, 1, 1); private void spawnParticles(EntityPlayer player)
if (shouldAttackPlayer(entityPlayer))
{ {
if (aggro<470) int count = 10 * aggro / MAX_AGGRO;
for (int i = 1; i < count; ++i)
{ {
if (rand.nextInt(11)>this.textureState||this.aggro>=300||rand.nextInt(13)>this.textureState&&this.aggroMax>this.aggro) player.worldObj.spawnParticle("portal", player.posX + (this.rand.nextDouble() - 0.5D) * this.width,
{ player.posY + this.rand.nextDouble() * player.height - 0.75D,
aggro++; player.posZ + (this.rand.nextDouble() - 0.5D) * player.width,
aggro++; (this.rand.nextDouble() - 0.5D) * 2.0D, -this.rand.nextDouble(),
(this.rand.nextDouble() - 0.5D) * 2.0D);
}
if (this.worldObj.provider instanceof PocketProvider||this.worldObj.getClosestPlayerToEntity(this, 5)!=null)
{
aggro++;
}
if (aggro>430&&this.soundTime<100)
{
this.worldObj.playSoundEffect(entityPlayer.posX, entityPlayer.posY, entityPlayer.posZ,mod_pocketDim.modid+":tearing",2F, 1F);
this.soundTime=100;
}
if (aggro>445&&this.soundTime<200)
{
this.worldObj.playSoundEffect(entityPlayer.posX, entityPlayer.posY, entityPlayer.posZ,mod_pocketDim.modid+":tearing",5F, 1F);
this.soundTime=200;
}
}
else if (!this.worldObj.isRemote && !entityPlayer.capabilities.isCreativeMode)
{
ChunkCoordinates coords = LimboProvider.getLimboSkySpawn(entityPlayer.worldObj.rand);
Point4D destination = new Point4D((int) (coords.posX+entityPlayer.posX), coords.posY, (int) (coords.posZ+entityPlayer.posZ ), mod_pocketDim.properties.LimboDimensionID);
DDTeleporter.teleportEntity(entityPlayer, destination, false);
this.aggro = 0;
entityPlayer.worldObj.playSoundAtEntity(entityPlayer,mod_pocketDim.modid+":crack",13, 1);
}
if (!(this.worldObj.provider instanceof LimboProvider || this.worldObj.getClosestPlayerToEntity(this, 5) != null) || this.aggro > 300)
{
for (int i = 0; i < -1+this.textureState/2; ++i)
{
entityPlayer.worldObj.spawnParticle("portal", entityPlayer.posX + (this.rand.nextDouble() - 0.5D) * this.width, entityPlayer.posY + this.rand.nextDouble() * entityPlayer.height - 0.75D, entityPlayer.posZ + (this.rand.nextDouble() - 0.5D) * entityPlayer.width, (this.rand.nextDouble() - 0.5D) * 2.0D, -this.rand.nextDouble(), (this.rand.nextDouble() - 0.5D) * 2.0D);
}
}
}
else if(this.worldObj.provider instanceof PocketProvider)
{
if(aggro<this.aggroMax/2)
{
if(rand.nextInt(3)==0)
{
aggro++;
}
}
else
{
if(aggro>0)
{
aggro--;
}
}
}
}
else
{
if(aggro>0)
{
aggro--;
if(rand.nextBoolean())
{
aggro--;
}
}
}
if (soundTime>=0)
{
soundTime--;
}
this.textureState= (byte) (this.aggro/25);
if (!this.worldObj.isRemote)
{
this.dataWatcher.updateObject(16, Byte.valueOf(this.textureState));
} }
} }
public float getAggroProgress()
private boolean shouldAttackPlayer(EntityPlayer par1EntityPlayer)
{ {
return par1EntityPlayer.canEntityBeSeen(this); return ((float) aggro) / MAX_AGGRO;
} }
public boolean attackEntityFrom(DamageSource par1DamageSource, int par2) private void facePlayer(EntityPlayer player)
{ {
if (par1DamageSource == DamageSource.inWall) double d0 = player.posX - this.posX;
{ double d1 = player.posZ - this.posZ;
this.posY = posY + 1; double d2 = (player.posY + player.getEyeHeight()) - (this.posY + this.getEyeHeight());
}
else
{
this.aggro = this.aggroMax;
}
return false;
}
@Override
public void faceEntity(Entity par1Entity, float par2, float par3)
{
double d0 = par1Entity.posX - this.posX;
double d1 = par1Entity.posZ - this.posZ;
double d2;
if (par1Entity instanceof EntityLiving)
{
EntityLiving entityliving = (EntityLiving)par1Entity;
d2 = entityliving.posY + entityliving.getEyeHeight() - (this.posY + this.getEyeHeight());
}
else
{
d2 = (par1Entity.boundingBox.minY + par1Entity.boundingBox.maxY) - (this.posY + this.getEyeHeight());
}
double d3 = MathHelper.sqrt_double(d0 * d0 + d1 * d1); double d3 = MathHelper.sqrt_double(d0 * d0 + d1 * d1);
float f2 = (float)(Math.atan2(d1, d0) * 180.0D / Math.PI) - 90.0F; float f2 = (float)(Math.atan2(d1, d0) * 180.0D / Math.PI) - 90.0F;
float f3 = (float)(-(Math.atan2(d2, d3) * 180.0D / Math.PI)); this.pitchLevel = (float) -((Math.atan(d2/d3) )* 180.0D / Math.PI);
this.rotationPitch = f3;
this.rotationYaw = f2;
this.rotationYaw = f2; this.rotationYaw = f2;
this.rotationYawHead = f2; this.rotationYawHead = f2;
this.renderYawOffset = this.rotationYaw; this.renderYawOffset = this.rotationYaw;
} }
@Override @Override
public float getRotationYawHead() public void writeEntityToNBT(NBTTagCompound rootTag)
{ {
return 0.0F; super.writeEntityToNBT(rootTag);
rootTag.setInteger("Aggro", this.aggro);
} }
@Override @Override
public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) public void readEntityFromNBT(NBTTagCompound rootTag)
{ {
super.writeEntityToNBT(par1NBTTagCompound); super.readEntityFromNBT(rootTag);
par1NBTTagCompound.setFloat("soundTime", this.soundTime);
par1NBTTagCompound.setInteger("aggro", this.aggro);
par1NBTTagCompound.setInteger("aggroMax", this.aggroMax);
par1NBTTagCompound.setByte("textureState", this.textureState);
par1NBTTagCompound.setFloat("scaleFactor", this.scaleFactor);
}
@Override // Load Monoliths with half aggro so they don't teleport players instantly
public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) this.aggro = (short) (rootTag.getInteger("Aggro") / 2);
{
super.readEntityFromNBT(par1NBTTagCompound);
this.soundTime = par1NBTTagCompound.getFloat("soundTime");
this.aggro = par1NBTTagCompound.getInteger("aggro");
this.aggroMax = par1NBTTagCompound.getInteger("aggroMax");
this.textureState = par1NBTTagCompound.getByte("textureState");
this.scaleFactor = par1NBTTagCompound.getFloat("scaleFactor");
} }
@Override @Override
@@ -352,9 +325,4 @@ public class MobMonolith extends EntityFlying implements IMob
this.worldObj.getCollidingBoundingBoxes(this, this.boundingBox).isEmpty() && this.worldObj.getCollidingBoundingBoxes(this, this.boundingBox).isEmpty() &&
!this.worldObj.isAnyLiquid(this.boundingBox); !this.worldObj.isAnyLiquid(this.boundingBox);
} }
public DataWatcher getDataWatcher()
{
return this.dataWatcher;
}
} }

View File

@@ -1,56 +1,121 @@
package StevenDimDoors.mod_pocketDim.ticking; package StevenDimDoors.mod_pocketDim.ticking;
import java.util.Arrays; import java.util.PriorityQueue;
import java.util.List;
import java.util.Random; import java.util.Random;
import net.minecraft.util.MathHelper;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.common.DimensionManager; import net.minecraftforge.common.DimensionManager;
import StevenDimDoors.mod_pocketDim.mod_pocketDim; import StevenDimDoors.mod_pocketDim.blocks.BlockRift;
import StevenDimDoors.mod_pocketDim.core.DimLink; import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager; import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.util.Point4D; import StevenDimDoors.mod_pocketDim.util.Point4D;
public class RiftRegenerator implements IRegularTickReceiver { public class RiftRegenerator implements IRegularTickReceiver {
private static final int RIFT_REGENERATION_INTERVAL = 200; //Regenerate random rifts every 200 ticks // Ranges of regeneration delays, in seconds
private static final int RIFTS_REGENERATED_PER_DIMENSION = 5; private static final int MIN_FAST_DELAY = 1;
private static final int MAX_FAST_DELAY = 3;
private static final int MIN_SLOW_DELAY = 5;
private static final int MAX_SLOW_DELAY = 15;
private static final int MIN_RESCHEDULE_DELAY = 4 * 60;
private static final int MAX_RESCHEDULE_DELAY = 6 * 60;
private static final int TICKS_PER_SECOND = 20;
private static final int RIFT_REGENERATION_INTERVAL = 1; // Check the regeneration queue every tick
private static Random random = new Random(); private static Random random = new Random();
public RiftRegenerator(IRegularTickSender sender) private long tickCount = 0;
private PriorityQueue<RiftTicket> ticketQueue;
private BlockRift blockRift;
public RiftRegenerator(IRegularTickSender sender, BlockRift blockRift)
{ {
sender.registerForTicking(this, RIFT_REGENERATION_INTERVAL, false); this.ticketQueue = new PriorityQueue<RiftTicket>();
this.blockRift = blockRift;
sender.registerReceiver(this, RIFT_REGENERATION_INTERVAL, false);
} }
@Override @Override
public void notifyTick() public void notifyTick()
{ {
regenerateRiftsInLoadedWorlds(); processTicketQueue();
tickCount++;
} }
private static void regenerateRiftsInLoadedWorlds() public void scheduleSlowRegeneration(DimLink link)
{ {
// Regenerate rifts that have been replaced (not permanently removed) by players scheduleRegeneration(link, MIN_SLOW_DELAY, MAX_SLOW_DELAY);
// Only do this in dimensions that are currently loaded }
List<Integer> loadedWorlds = (List<Integer>) Arrays.asList(DimensionManager.getIDs());
for (Integer dimensionID : loadedWorlds)
{
NewDimData dimension = PocketManager.getDimensionData(dimensionID);
if (dimension.linkCount() > 0)
{
World world = DimensionManager.getWorld(dimension.id());
if (world != null) public void scheduleSlowRegeneration(int x, int y, int z, World world)
{ {
for (int count = 0; count < RIFTS_REGENERATED_PER_DIMENSION; count++) scheduleRegeneration(PocketManager.getLink(x, y, z, world), MIN_SLOW_DELAY, MAX_SLOW_DELAY);
}
public void scheduleFastRegeneration(int x, int y, int z, World world)
{ {
DimLink link = dimension.getRandomLink(); scheduleRegeneration(PocketManager.getLink(x, y, z, world), MIN_FAST_DELAY, MAX_FAST_DELAY);
Point4D source = link.source(); }
mod_pocketDim.blockRift.regenerateRift(world, source.getX(), source.getY(), source.getZ(), random);
private void scheduleRegeneration(DimLink link, int minDelay, int maxDelay)
{
if (link != null)
{
int tickDelay = MathHelper.getRandomIntegerInRange(random, minDelay * TICKS_PER_SECOND, maxDelay * TICKS_PER_SECOND);
ticketQueue.add(new RiftTicket(link.source(), tickCount + tickDelay));
} }
} }
private void processTicketQueue()
{
RiftTicket ticket;
while (!ticketQueue.isEmpty() && ticketQueue.peek().timestamp() <= tickCount)
{
ticket = ticketQueue.remove();
regenerateRift(ticket.location());
} }
} }
private void regenerateRift(Point4D location)
{
int x = location.getX();
int y = location.getY();
int z = location.getZ();
// Try to regenerate a rift, or possibly reschedule its regeneration.
// The world for the given location must be loaded.
World world = DimensionManager.getWorld(location.getDimension());
if (world == null)
return;
// There must be a link at the given location.
DimLink link = PocketManager.getLink(location);
if (link == null)
return;
// The chunk at the given location must be loaded.
// Note: ChunkProviderServer.chunkExists() returns whether a chunk is
// loaded, not whether it has already been created.
if (!world.getChunkProvider().chunkExists(x >> 4, z >> 4))
return;
// If the location is occupied by an immune DD block, then don't regenerate.
if (blockRift.isModBlockImmune(world, x, y, z))
return;
// If the location is occupied by an immune block, then reschedule.
if (blockRift.isBlockImmune(world, x, y, z))
{
scheduleRegeneration(link, MIN_RESCHEDULE_DELAY, MAX_RESCHEDULE_DELAY);
}
else
{
// All of the necessary conditions have been met. Restore the rift!
int blockID = world.getBlockId(x, y, z);
if (world.setBlock(x, y, z, blockRift.blockID))
blockRift.dropWorldThread(blockID, world, x, y, z, random);
} }
} }
}

View File

@@ -0,0 +1,40 @@
package StevenDimDoors.mod_pocketDim.ticking;
import StevenDimDoors.mod_pocketDim.util.Point4D;
public class RiftTicket implements Comparable<RiftTicket> {
private long timestamp;
private Point4D location;
public RiftTicket(Point4D location, long timestamp)
{
this.timestamp = timestamp;
this.location = location;
}
@Override
public int compareTo(RiftTicket other)
{
if (this.timestamp < other.timestamp)
{
return -1;
}
else if (this.timestamp > other.timestamp)
{
return 1;
}
return 0;
}
public long timestamp()
{
return timestamp;
}
public Point4D location()
{
return location;
}
}

View File

@@ -7,26 +7,31 @@ import StevenDimDoors.mod_pocketDim.core.DDTeleporter;
import cpw.mods.fml.common.ITickHandler; import cpw.mods.fml.common.ITickHandler;
import cpw.mods.fml.common.TickType; import cpw.mods.fml.common.TickType;
public class CommonTickHandler implements ITickHandler, IRegularTickSender public class ServerTickHandler implements ITickHandler, IRegularTickSender
{ {
private static final String PROFILING_LABEL = "Dimensional Doors: Common Tick"; private static final String PROFILING_LABEL = "Dimensional Doors: Server Tick";
private int tickCount = 0; private int tickCount = 0;
private ArrayList<RegularTickReceiverInfo> receivers; private ArrayList<RegularTickReceiverInfo> receivers;
public ServerTickHandler()
public CommonTickHandler()
{ {
this.receivers = new ArrayList<RegularTickReceiverInfo>(); this.receivers = new ArrayList<RegularTickReceiverInfo>();
} }
@Override @Override
public void registerForTicking(IRegularTickReceiver receiver, int interval, boolean onTickStart) public void registerReceiver(IRegularTickReceiver receiver, int interval, boolean onTickStart)
{ {
RegularTickReceiverInfo info = new RegularTickReceiverInfo(receiver, interval, onTickStart); RegularTickReceiverInfo info = new RegularTickReceiverInfo(receiver, interval, onTickStart);
receivers.add(info); receivers.add(info);
} }
@Override
public void unregisterReceivers()
{
receivers.clear();
}
@Override @Override
public void tickStart(EnumSet<TickType> type, Object... tickData) public void tickStart(EnumSet<TickType> type, Object... tickData)
{ {

View File

@@ -0,0 +1,13 @@
package StevenDimDoors.mod_pocketDim.tileentities;
import java.util.Random;
import net.minecraft.tileentity.TileEntity;
public abstract class DDTileEntityBase extends TileEntity
{
/**
*
* @return an array of floats representing RGBA color where 1.0 = 255.
*/
public abstract float[] getRenderColor(Random rand);
}

View File

@@ -1,9 +1,15 @@
package StevenDimDoors.mod_pocketDim.tileentities; package StevenDimDoors.mod_pocketDim.tileentities;
import java.util.Random;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.packet.Packet;
import StevenDimDoors.mod_pocketDim.ServerPacketHandler; import StevenDimDoors.mod_pocketDim.ServerPacketHandler;
import StevenDimDoors.mod_pocketDim.mod_pocketDim; import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.blocks.IDimDoor; import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.PocketManager; import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.watcher.ClientLinkData;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.packet.Packet; import net.minecraft.network.packet.Packet;
@@ -11,47 +17,33 @@ import net.minecraft.network.packet.Packet130UpdateSign;
import net.minecraft.network.packet.Packet250CustomPayload; import net.minecraft.network.packet.Packet250CustomPayload;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
public class TileEntityDimDoor extends TileEntity
public class TileEntityDimDoor extends DDTileEntityBase
{ {
public boolean openOrClosed; public boolean openOrClosed;
public int orientation; public int orientation;
public boolean hasExit; public boolean hasExit;
public byte lockStatus;
public boolean isDungeonChainLink; public boolean isDungeonChainLink;
public boolean hasGennedPair=false; public boolean hasGennedPair=false;
@Override @Override
public boolean canUpdate() public boolean canUpdate()
{ {
return true; return false;
} }
@Override
public void updateEntity()
{
}
@Override @Override
public Packet getDescriptionPacket() public Packet getDescriptionPacket()
{ {
if(PocketManager.getLink(xCoord, yCoord, zCoord, worldObj)!=null) if(PocketManager.getLink(xCoord, yCoord, zCoord, worldObj)!=null)
{ {
return ServerPacketHandler.createLinkPacket(PocketManager.getLink(xCoord, yCoord, zCoord, worldObj).link()); return ServerPacketHandler.createLinkPacket(new ClientLinkData(PocketManager.getLink(xCoord, yCoord, zCoord, worldObj)));
} }
return null; return null;
} }
public void invalidate()
{
this.tileEntityInvalid = true;
if(this.worldObj.getBlockId(xCoord, yCoord, zCoord)==0&&!this.worldObj.isRemote)
{
if(PocketManager.getLink(xCoord, yCoord, zCoord, worldObj)!=null)
{
mod_pocketDim.instance.fastRiftRegenerator.registerRiftForRegen(xCoord, yCoord, zCoord, this.worldObj.provider.dimensionId);
}
}
}
@Override @Override
public void readFromNBT(NBTTagCompound nbt) public void readFromNBT(NBTTagCompound nbt)
{ {
@@ -83,5 +75,22 @@ public class TileEntityDimDoor extends TileEntity
nbt.setBoolean("hasGennedPair", hasGennedPair); nbt.setBoolean("hasGennedPair", hasGennedPair);
} }
@Override
public float[] getRenderColor(Random rand)
{
float[] rgbaColor = {1,1,1,1};
if (this.worldObj.provider.dimensionId == mod_pocketDim.NETHER_DIMENSION_ID)
{
rgbaColor[0] = rand.nextFloat() * 0.5F + 0.4F;
rgbaColor[1] = rand.nextFloat() * 0.05F;
rgbaColor[2] = rand.nextFloat() * 0.05F;
}
else
{
rgbaColor[0] = rand.nextFloat() * 0.5F + 0.1F;
rgbaColor[1] = rand.nextFloat() * 0.4F + 0.4F;
rgbaColor[2] = rand.nextFloat() * 0.6F + 0.5F;
}
return rgbaColor;
}
} }

Some files were not shown because too many files have changed in this diff Show More