commit
3a63f8965b
10 changed files with 226 additions and 191 deletions
|
@ -78,9 +78,6 @@ public class DDLoot {
|
||||||
//because the items in that category have strange weights that are incompatible with all other
|
//because the items in that category have strange weights that are incompatible with all other
|
||||||
//chest categories.
|
//chest categories.
|
||||||
|
|
||||||
//This function has a flaw. It treats items with the same item ID but different damage values as
|
|
||||||
//the same item. For instance, it cannot distinguish between different types of wood. That shouldn't
|
|
||||||
//matter for most chest loot, though. This could be fixed if we cared enough.
|
|
||||||
Random random = new Random();
|
Random random = new Random();
|
||||||
HashMap<Integer, WeightedRandomChestContent> container = new HashMap<Integer, WeightedRandomChestContent>();
|
HashMap<Integer, WeightedRandomChestContent> container = new HashMap<Integer, WeightedRandomChestContent>();
|
||||||
|
|
||||||
|
@ -89,7 +86,9 @@ public class DDLoot {
|
||||||
WeightedRandomChestContent[] items = ChestGenHooks.getItems(category, random);
|
WeightedRandomChestContent[] items = ChestGenHooks.getItems(category, random);
|
||||||
for (WeightedRandomChestContent item : items)
|
for (WeightedRandomChestContent item : items)
|
||||||
{
|
{
|
||||||
int id = item.theItemId.itemID;
|
ItemStack stack = item.theItemId;
|
||||||
|
int id = stack.itemID;
|
||||||
|
int subtype = stack.getItem().getHasSubtypes() ? stack.getItemDamage() : 0;
|
||||||
|
|
||||||
//Correct the weights of Vanilla dungeon chests (DUNGEON_CHEST)
|
//Correct the weights of Vanilla dungeon chests (DUNGEON_CHEST)
|
||||||
//Comparing by String references is valid here since they should match!
|
//Comparing by String references is valid here since they should match!
|
||||||
|
@ -100,20 +99,25 @@ public class DDLoot {
|
||||||
item.itemWeight /= DUNGEON_CHEST_WEIGHT_INFLATION;
|
item.itemWeight /= DUNGEON_CHEST_WEIGHT_INFLATION;
|
||||||
if (item.itemWeight == 0)
|
if (item.itemWeight == 0)
|
||||||
item.itemWeight = 1;
|
item.itemWeight = 1;
|
||||||
}
|
}
|
||||||
if (!container.containsKey(id))
|
|
||||||
|
//Generate an identifier for this item using its item ID and damage value,
|
||||||
|
//if it has subtypes. This solves the issue of matching items that have
|
||||||
|
//the same item ID but different subtypes (e.g. wood planks, dyes).
|
||||||
|
int key = ((subtype & 0xFFFF) << 16) + ((id & 0xFFFF) << 16);
|
||||||
|
WeightedRandomChestContent other = container.get(key);
|
||||||
|
if (other == null)
|
||||||
{
|
{
|
||||||
//This item has not been seen before. Simply add it to the container.
|
//This item has not been seen before. Simply add it to the container.
|
||||||
container.put(id, item);
|
container.put(key, item);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//This item conflicts with an existing entry. Replace that entry
|
//This item conflicts with an existing entry. Replace that entry
|
||||||
//if our current item has a lower weight.
|
//if our current item has a lower weight.
|
||||||
WeightedRandomChestContent other = container.get(id);
|
|
||||||
if (item.itemWeight < other.itemWeight)
|
if (item.itemWeight < other.itemWeight)
|
||||||
{
|
{
|
||||||
container.put(id, item);
|
container.put(key, item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -127,7 +131,7 @@ public class DDLoot {
|
||||||
{
|
{
|
||||||
if (item.theItemId.itemID == enchantedBookID)
|
if (item.theItemId.itemID == enchantedBookID)
|
||||||
{
|
{
|
||||||
item.itemWeight = 3;
|
item.itemWeight = 4;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,14 +94,12 @@ 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 RiftBladeRiftCreationEnabled;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Other
|
* Other
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public final int NonTntWeight;
|
public final int NonTntWeight;
|
||||||
public final int RiftSpreadModifier;
|
|
||||||
public final int ClusterGenerationChance;
|
public final int ClusterGenerationChance;
|
||||||
public final int GatewayGenerationChance;
|
public final int GatewayGenerationChance;
|
||||||
public final int MonolithSpawningChance;
|
public final int MonolithSpawningChance;
|
||||||
|
@ -166,9 +164,6 @@ public class DDProperties
|
||||||
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 Limbo can send you upon returning to the Overworld").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);
|
||||||
RiftBladeRiftCreationEnabled = config.get(Configuration.CATEGORY_GENERAL, "Enable Rift Creation with Rift Blade", true,
|
|
||||||
"Sets whether Rift Blades can create new rifts. If set to false, " +
|
|
||||||
"they will only be able to create transient doors on existing rifts.").getBoolean(true);
|
|
||||||
|
|
||||||
TNFREAKINGT_Enabled = config.get(Configuration.CATEGORY_GENERAL, "EXPLOSIONS!!???!!!?!?!!", false).getBoolean(false);
|
TNFREAKINGT_Enabled = config.get(Configuration.CATEGORY_GENERAL, "EXPLOSIONS!!???!!!?!?!!", false).getBoolean(false);
|
||||||
NonTntWeight = config.get(Configuration.CATEGORY_GENERAL, "HOWMUCHTNT", 25,
|
NonTntWeight = config.get(Configuration.CATEGORY_GENERAL, "HOWMUCHTNT", 25,
|
||||||
|
@ -218,10 +213,6 @@ public class DDProperties
|
||||||
GatewayGenerationChance = config.get(Configuration.CATEGORY_GENERAL, "Gateway Generation Chance", 10,
|
GatewayGenerationChance = config.get(Configuration.CATEGORY_GENERAL, "Gateway Generation Chance", 10,
|
||||||
"Sets the chance (out of " + GatewayGenerator.MAX_GATEWAY_GENERATION_CHANCE + ") that a Rift Gateway will " +
|
"Sets the chance (out of " + GatewayGenerator.MAX_GATEWAY_GENERATION_CHANCE + ") that a Rift Gateway will " +
|
||||||
"generate in a given chunk. The default chance is 10.").getInt();
|
"generate in a given chunk. The default chance is 10.").getInt();
|
||||||
|
|
||||||
RiftSpreadModifier = config.get(Configuration.CATEGORY_GENERAL, "Rift Spread Modifier", 3,
|
|
||||||
"Sets the number of times a rift can spread. 0 prevents rifts from spreading at all. " +
|
|
||||||
"A value greater than 5 is not recommended as the growth is exponential.").getInt();
|
|
||||||
|
|
||||||
LimboBiomeID = config.get(CATEGORY_BIOME, "Limbo Biome ID", 251).getInt();
|
LimboBiomeID = config.get(CATEGORY_BIOME, "Limbo Biome ID", 251).getInt();
|
||||||
PocketBiomeID = config.get(CATEGORY_BIOME, "Pocket Biome ID", 250).getInt();
|
PocketBiomeID = config.get(CATEGORY_BIOME, "Pocket Biome ID", 250).getInt();
|
||||||
|
|
|
@ -30,7 +30,11 @@ import cpw.mods.fml.common.registry.GameRegistry;
|
||||||
public class DDTeleporter
|
public class DDTeleporter
|
||||||
{
|
{
|
||||||
private static final Random random = new Random();
|
private static final Random random = new Random();
|
||||||
private static int END_DIMENSION_ID = 1;
|
private static final int END_DIMENSION_ID = 1;
|
||||||
|
private static final int MAX_ROOT_SHIFT_CHANCE = 100;
|
||||||
|
private static final int START_ROOT_SHIFT_CHANCE = 0;
|
||||||
|
private static final int ROOT_SHIFT_CHANCE_PER_LEVEL = 5;
|
||||||
|
|
||||||
public static int cooldown = 0;
|
public static int cooldown = 0;
|
||||||
|
|
||||||
private DDTeleporter() { }
|
private DDTeleporter() { }
|
||||||
|
@ -465,16 +469,26 @@ public class DDTeleporter
|
||||||
// A dungeon exit acts the same as a safe exit, but has the chance of
|
// A dungeon exit acts the same as a safe exit, but has the chance of
|
||||||
// taking the user to any non-pocket dimension, excluding Limbo and The End.
|
// taking the user to any non-pocket dimension, excluding Limbo and The End.
|
||||||
|
|
||||||
|
NewDimData current = PocketManager.getDimensionData(link.source.getDimension());
|
||||||
ArrayList<NewDimData> roots = PocketManager.getRootDimensions();
|
ArrayList<NewDimData> roots = PocketManager.getRootDimensions();
|
||||||
for (int attempts = 0; attempts < 10; attempts++)
|
int shiftChance = START_ROOT_SHIFT_CHANCE + ROOT_SHIFT_CHANCE_PER_LEVEL * (current.packDepth() - 1);
|
||||||
|
|
||||||
|
if (random.nextInt(MAX_ROOT_SHIFT_CHANCE) < shiftChance)
|
||||||
{
|
{
|
||||||
NewDimData selection = roots.get( random.nextInt(roots.size()) );
|
for (int attempts = 0; attempts < 10; attempts++)
|
||||||
if (selection.id() != END_DIMENSION_ID && selection.id() != properties.LimboDimensionID)
|
|
||||||
{
|
{
|
||||||
return generateSafeExit(selection, link, properties);
|
NewDimData selection = roots.get( random.nextInt(roots.size()) );
|
||||||
|
if (selection.id() != END_DIMENSION_ID &&
|
||||||
|
selection.id() != properties.LimboDimensionID &&
|
||||||
|
selection != current.root())
|
||||||
|
{
|
||||||
|
return generateSafeExit(selection, link, properties);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
|
// Yes, this could lead you back into Limbo. That's intentional.
|
||||||
|
return generateSafeExit(current.root(), link, properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean generateSafeExit(NewDimData destinationDim, DimLink link, DDProperties properties)
|
private static boolean generateSafeExit(NewDimData destinationDim, DimLink link, DDProperties properties)
|
||||||
|
@ -482,16 +496,9 @@ public class DDTeleporter
|
||||||
// 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
|
||||||
// some precautions to protect the player. The X and Z coordinates
|
// some precautions to protect the player. The X and Z coordinates
|
||||||
// are fixed to match the source (mostly - may be shifted a little),
|
// are fixed to match the source (mostly - may be shifted a little),
|
||||||
// but the Y coordinate is chosen by searching for a safe location
|
// but the Y coordinate is chosen by searching for the nearest
|
||||||
// to place the door.
|
// a safe location to place the door.
|
||||||
|
|
||||||
// The direction of the vertical search is away from the map boundary
|
|
||||||
// closest to the source Y. In other words, if a player is really
|
|
||||||
// high up, the search goes down. If a player is near the bottom
|
|
||||||
// of the map, the search goes up. If a safe destination cannot be
|
|
||||||
// found, then we return false and the source-side door slams shut.
|
|
||||||
|
|
||||||
Point3D destination;
|
|
||||||
Point4D source = link.source();
|
Point4D source = link.source();
|
||||||
World world = PocketManager.loadDimension(destinationDim.id());
|
World world = PocketManager.loadDimension(destinationDim.id());
|
||||||
if (world == null)
|
if (world == null)
|
||||||
|
@ -499,11 +506,26 @@ public class DDTeleporter
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean searchDown = (source.getY() >= world.getActualHeight() / 2);
|
int startY = source.getY() - 2;
|
||||||
destination = yCoordHelper.findSafeCube(world, source.getX(), source.getY() - 2, source.getZ(), searchDown);
|
Point3D destination;
|
||||||
if (destination == null)
|
Point3D locationUp = yCoordHelper.findSafeCubeUp(world, source.getX(), startY, source.getZ());
|
||||||
|
Point3D locationDown = yCoordHelper.findSafeCubeDown(world, source.getX(), startY, source.getZ());
|
||||||
|
|
||||||
|
if (locationUp == null)
|
||||||
{
|
{
|
||||||
destination = yCoordHelper.findSafeCube(world, source.getX(), source.getY() - 2, source.getZ(), !searchDown);
|
destination = locationDown;
|
||||||
|
}
|
||||||
|
else if (locationDown == null)
|
||||||
|
{
|
||||||
|
destination = locationUp;
|
||||||
|
}
|
||||||
|
else if (locationUp.getY() - startY <= startY - locationDown.getY())
|
||||||
|
{
|
||||||
|
destination = locationUp;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
destination = locationDown;
|
||||||
}
|
}
|
||||||
if (destination != null)
|
if (destination != null)
|
||||||
{
|
{
|
||||||
|
|
|
@ -447,7 +447,7 @@ public abstract class NewDimData
|
||||||
this.packDepth = calculatePackDepth(parent, dungeon);
|
this.packDepth = calculatePackDepth(parent, dungeon);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int calculatePackDepth(NewDimData parent, DungeonData current)
|
public static int calculatePackDepth(NewDimData parent, DungeonData current)
|
||||||
{
|
{
|
||||||
DungeonData predecessor = parent.dungeon();
|
DungeonData predecessor = parent.dungeon();
|
||||||
if (current == null)
|
if (current == null)
|
||||||
|
|
|
@ -27,6 +27,7 @@ import StevenDimDoors.mod_pocketDim.schematic.InvalidSchematicException;
|
||||||
import StevenDimDoors.mod_pocketDim.schematic.ReplacementFilter;
|
import StevenDimDoors.mod_pocketDim.schematic.ReplacementFilter;
|
||||||
import StevenDimDoors.mod_pocketDim.schematic.Schematic;
|
import StevenDimDoors.mod_pocketDim.schematic.Schematic;
|
||||||
import StevenDimDoors.mod_pocketDim.ticking.MobMonolith;
|
import StevenDimDoors.mod_pocketDim.ticking.MobMonolith;
|
||||||
|
import StevenDimDoors.mod_pocketDim.ticking.MonolithSpawner;
|
||||||
import StevenDimDoors.mod_pocketDim.util.Point4D;
|
import StevenDimDoors.mod_pocketDim.util.Point4D;
|
||||||
|
|
||||||
public class DungeonSchematic extends Schematic {
|
public class DungeonSchematic extends Schematic {
|
||||||
|
@ -248,13 +249,14 @@ public class DungeonSchematic extends Schematic {
|
||||||
//Set up link data for exit door
|
//Set up link data for exit door
|
||||||
for (Point3D location : exitDoorLocations)
|
for (Point3D location : exitDoorLocations)
|
||||||
{
|
{
|
||||||
createExitDoorLink(dimension, location, entranceDoorLocation, turnAngle, pocketCenter);
|
createExitDoorLink(world, dimension, location, entranceDoorLocation, turnAngle, pocketCenter);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Remove end portal frames and spawn Monoliths
|
//Remove end portal frames and spawn Monoliths, if allowed
|
||||||
|
boolean canSpawn = MonolithSpawner.isMobSpawningAllowed();
|
||||||
for (Point3D location : monolithSpawnLocations)
|
for (Point3D location : monolithSpawnLocations)
|
||||||
{
|
{
|
||||||
spawnMonolith(world, location, entranceDoorLocation, turnAngle, pocketCenter);
|
spawnMonolith(world, location, entranceDoorLocation, turnAngle, pocketCenter, canSpawn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -291,12 +293,22 @@ public class DungeonSchematic extends Schematic {
|
||||||
prevDim.setDestination(reverseLink, destination.getX(), destination.getY(), destination.getZ());
|
prevDim.setDestination(reverseLink, destination.getX(), destination.getY(), destination.getZ());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void createExitDoorLink(NewDimData dimension, Point3D point, Point3D entrance, int rotation, Point3D pocketCenter)
|
private static void createExitDoorLink(World world, NewDimData dimension, Point3D point, Point3D entrance, int rotation, Point3D pocketCenter)
|
||||||
{
|
{
|
||||||
//Transform the door's location to the pocket coordinate system
|
//Transform the door's location to the pocket coordinate system
|
||||||
Point3D location = point.clone();
|
Point3D location = point.clone();
|
||||||
BlockRotator.transformPoint(location, entrance, rotation, pocketCenter);
|
BlockRotator.transformPoint(location, entrance, rotation, pocketCenter);
|
||||||
dimension.createLink(location.getX(), location.getY(), location.getZ(), LinkTypes.DUNGEON_EXIT);
|
dimension.createLink(location.getX(), location.getY(), location.getZ(), LinkTypes.DUNGEON_EXIT);
|
||||||
|
//Replace the sandstone block under the exit door with the same block as the one underneath it
|
||||||
|
int x = location.getX();
|
||||||
|
int y = location.getY() - 3;
|
||||||
|
int z = location.getZ();
|
||||||
|
if (y >= 0)
|
||||||
|
{
|
||||||
|
int blockID = world.getBlockId(x, y, z);
|
||||||
|
int metadata = world.getBlockMetadata(x, y, z);
|
||||||
|
setBlockDirectly(world, x, y + 1, z, blockID, metadata);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void createDimensionalDoorLink(NewDimData dimension, Point3D point, Point3D entrance, int rotation, Point3D pocketCenter)
|
private static void createDimensionalDoorLink(NewDimData dimension, Point3D point, Point3D entrance, int rotation, Point3D pocketCenter)
|
||||||
|
@ -307,7 +319,7 @@ public class DungeonSchematic extends Schematic {
|
||||||
dimension.createLink(location.getX(), location.getY(), location.getZ(), LinkTypes.DUNGEON);
|
dimension.createLink(location.getX(), location.getY(), location.getZ(), LinkTypes.DUNGEON);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void spawnMonolith(World world, Point3D point, Point3D entrance, int rotation, Point3D pocketCenter)
|
private static void spawnMonolith(World world, Point3D point, Point3D entrance, int rotation, Point3D pocketCenter, boolean canSpawn)
|
||||||
{
|
{
|
||||||
//Transform the frame block's location to the pocket coordinate system
|
//Transform the frame block's location to the pocket coordinate system
|
||||||
Point3D location = point.clone();
|
Point3D location = point.clone();
|
||||||
|
@ -315,8 +327,11 @@ public class DungeonSchematic extends Schematic {
|
||||||
//Remove frame block
|
//Remove frame block
|
||||||
setBlockDirectly(world, location.getX(), location.getY(), location.getZ(), 0, 0);
|
setBlockDirectly(world, location.getX(), location.getY(), location.getZ(), 0, 0);
|
||||||
//Spawn Monolith
|
//Spawn Monolith
|
||||||
Entity mob = new MobMonolith(world);
|
if (canSpawn)
|
||||||
mob.setLocationAndAngles(location.getX(), location.getY(), location.getZ(), 1, 1);
|
{
|
||||||
world.spawnEntityInWorld(mob);
|
Entity mob = new MobMonolith(world);
|
||||||
|
mob.setLocationAndAngles(location.getX(), location.getY(), location.getZ(), 1, 1);
|
||||||
|
world.spawnEntityInWorld(mob);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import net.minecraft.block.material.Material;
|
||||||
import net.minecraft.util.MathHelper;
|
import net.minecraft.util.MathHelper;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraft.world.chunk.Chunk;
|
import net.minecraft.world.chunk.Chunk;
|
||||||
|
import net.minecraft.world.chunk.IChunkProvider;
|
||||||
import StevenDimDoors.mod_pocketDim.Point3D;
|
import StevenDimDoors.mod_pocketDim.Point3D;
|
||||||
|
|
||||||
public class yCoordHelper
|
public class yCoordHelper
|
||||||
|
@ -70,7 +71,7 @@ public class yCoordHelper
|
||||||
return (material.isLiquid() || !material.isReplaceable());
|
return (material.isLiquid() || !material.isReplaceable());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Point3D findSafeCube(World world, int x, int startY, int z, boolean searchDown)
|
public static Point3D findSafeCubeUp(World world, int x, int startY, int z)
|
||||||
{
|
{
|
||||||
// Search for a 3x3x3 cube of air with blocks underneath
|
// Search for a 3x3x3 cube of air with blocks underneath
|
||||||
// We can also match against a 3x2x3 box with
|
// We can also match against a 3x2x3 box with
|
||||||
|
@ -84,62 +85,139 @@ public class yCoordHelper
|
||||||
localX = MathHelper.clamp_int(localX, 1, 14);
|
localX = MathHelper.clamp_int(localX, 1, 14);
|
||||||
localZ = MathHelper.clamp_int(localZ, 1, 14);
|
localZ = MathHelper.clamp_int(localZ, 1, 14);
|
||||||
|
|
||||||
Chunk chunk = world.getChunkProvider().loadChunk(x >> 4, z >> 4);
|
Chunk chunk = initializeChunkArea(world, x >> 4, z >> 4);
|
||||||
|
|
||||||
int layers = 0;
|
|
||||||
int height = world.getActualHeight();
|
int height = world.getActualHeight();
|
||||||
int y, dx, dz, blockID;
|
int y, dx, dz, blockID;
|
||||||
boolean filled;
|
boolean isSafe;
|
||||||
Block block;
|
Block block;
|
||||||
Point3D location = null;
|
|
||||||
|
// Initialize layers to a huge negative number so that we won't
|
||||||
if (searchDown)
|
// consider an area as usable unless it gets reset to 0 first
|
||||||
|
// when we find a foundation upon which to build.
|
||||||
|
int layers = -1000000;
|
||||||
|
|
||||||
|
// Check if a 3x3 layer of blocks is empty
|
||||||
|
// If we find a layer that contains replaceable blocks, it can
|
||||||
|
// serve as the base where we'll place the player and door.
|
||||||
|
for (y = Math.max(startY - 1, 0); y < height; y++)
|
||||||
{
|
{
|
||||||
/*for (y = startY; y >= 0; y--)
|
isSafe = true;
|
||||||
|
for (dx = -1; dx <= 1 && isSafe; dx++)
|
||||||
{
|
{
|
||||||
blockID = chunk.getBlockID(localX, y, localZ);
|
for (dz = -1; dz <= 1 && isSafe; dz++)
|
||||||
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Check if a 3x3 layer of blocks is empty
|
|
||||||
// If we find a layer that contains replaceable blocks, it can
|
|
||||||
// serve as the base where we'll place the player and door.
|
|
||||||
for (y = Math.max(startY, 0); y < height; y++)
|
|
||||||
{
|
|
||||||
filled = false;
|
|
||||||
for (dx = -1; dx <= 1 && !filled; dx++)
|
|
||||||
{
|
{
|
||||||
for (dz = -1; dz <= 1 && !filled; dz++)
|
blockID = chunk.getBlockID(localX + dx, y, localZ + dz);
|
||||||
|
if (blockID != 0)
|
||||||
{
|
{
|
||||||
blockID = chunk.getBlockID(localX + dx, y, localZ + dz);
|
block = Block.blocksList[blockID];
|
||||||
if (blockID != 0)
|
if (!block.blockMaterial.isReplaceable())
|
||||||
{
|
{
|
||||||
block = Block.blocksList[blockID];
|
isSafe = false;
|
||||||
if (block != null && !block.blockMaterial.isReplaceable())
|
|
||||||
{
|
|
||||||
filled = true;
|
|
||||||
}
|
|
||||||
layers = 0;
|
|
||||||
}
|
}
|
||||||
}
|
layers = 0;
|
||||||
}
|
|
||||||
if (!filled)
|
|
||||||
{
|
|
||||||
layers++;
|
|
||||||
if (layers == 3)
|
|
||||||
{
|
|
||||||
location = new Point3D(localX + cornerX, y - 2, localZ + cornerZ);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (isSafe)
|
||||||
|
{
|
||||||
|
layers++;
|
||||||
|
if (layers == 3)
|
||||||
|
{
|
||||||
|
return new Point3D(localX + cornerX, y - 2, localZ + cornerZ);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
return location;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Point3D findSafeCubeDown(World world, int x, int startY, int z)
|
||||||
|
{
|
||||||
|
// Search for a 3x3x3 cube of air with blocks underneath
|
||||||
|
// We can also match against a 3x2x3 box with
|
||||||
|
// We shift the search area into the bounds of a chunk for the sake of simplicity,
|
||||||
|
// so that we don't need to worry about working across chunks.
|
||||||
|
|
||||||
|
int localX = x < 0 ? (x % 16) + 16 : (x % 16);
|
||||||
|
int localZ = z < 0 ? (z % 16) + 16 : (z % 16);
|
||||||
|
int cornerX = x - localX;
|
||||||
|
int cornerZ = z - localZ;
|
||||||
|
localX = MathHelper.clamp_int(localX, 1, 14);
|
||||||
|
localZ = MathHelper.clamp_int(localZ, 1, 14);
|
||||||
|
|
||||||
|
Chunk chunk = initializeChunkArea(world, x >> 4, z >> 4);
|
||||||
|
|
||||||
|
int height = world.getActualHeight();
|
||||||
|
int y, dx, dz, blockID;
|
||||||
|
boolean isSafe;
|
||||||
|
boolean hasBlocks;
|
||||||
|
Block block;
|
||||||
|
int layers = 0;
|
||||||
|
|
||||||
|
// Check if a 3x3 layer of blocks is empty
|
||||||
|
// If we find a layer that contains replaceable blocks, it can
|
||||||
|
// serve as the base where we'll place the player and door.
|
||||||
|
for (y = Math.min(startY + 2, height - 1); y >= 0; y--)
|
||||||
|
{
|
||||||
|
isSafe = true;
|
||||||
|
hasBlocks = false;
|
||||||
|
for (dx = -1; dx <= 1 && isSafe; dx++)
|
||||||
|
{
|
||||||
|
for (dz = -1; dz <= 1 && isSafe; dz++)
|
||||||
|
{
|
||||||
|
blockID = chunk.getBlockID(localX + dx, y, localZ + dz);
|
||||||
|
if (blockID != 0)
|
||||||
|
{
|
||||||
|
block = Block.blocksList[blockID];
|
||||||
|
if (!block.blockMaterial.isReplaceable())
|
||||||
|
{
|
||||||
|
if (layers >= 3)
|
||||||
|
{
|
||||||
|
return new Point3D(localX + cornerX, y + 1, localZ + cornerZ);
|
||||||
|
}
|
||||||
|
isSafe = false;
|
||||||
|
}
|
||||||
|
hasBlocks = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isSafe)
|
||||||
|
{
|
||||||
|
layers++;
|
||||||
|
if (hasBlocks)
|
||||||
|
{
|
||||||
|
if (layers >= 3)
|
||||||
|
{
|
||||||
|
return new Point3D(localX + cornerX, y, localZ + cornerZ);
|
||||||
|
}
|
||||||
|
layers = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Chunk initializeChunkArea(World world, int chunkX, int chunkZ)
|
||||||
|
{
|
||||||
|
// We initialize a 3x3 area of chunks instead of just initializing
|
||||||
|
// the target chunk because things generated in adjacent chunks
|
||||||
|
// (e.g. trees) might intrude into the target chunk.
|
||||||
|
|
||||||
|
IChunkProvider provider = world.getChunkProvider();
|
||||||
|
Chunk target = provider.loadChunk(chunkX, chunkZ);
|
||||||
|
for (int dx = -1; dx <= 1; dx++)
|
||||||
|
{
|
||||||
|
for (int dz = -1; dz <= 1; dz++)
|
||||||
|
{
|
||||||
|
if (!provider.chunkExists(chunkX + dx, chunkZ + dz))
|
||||||
|
{
|
||||||
|
provider.loadChunk(chunkX, chunkZ);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
public static int adjustDestinationY(int y, int worldHeight, int entranceY, int dungeonHeight)
|
public static int adjustDestinationY(int y, int worldHeight, int entranceY, int dungeonHeight)
|
||||||
{
|
{
|
||||||
//The goal here is to guarantee that the dungeon fits within the vertical bounds
|
//The goal here is to guarantee that the dungeon fits within the vertical bounds
|
||||||
|
|
|
@ -9,7 +9,6 @@ import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.EntityLiving;
|
import net.minecraft.entity.EntityLiving;
|
||||||
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.EnumAction;
|
|
||||||
import net.minecraft.item.EnumToolMaterial;
|
import net.minecraft.item.EnumToolMaterial;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.item.ItemSword;
|
import net.minecraft.item.ItemSword;
|
||||||
|
@ -20,8 +19,6 @@ import net.minecraft.util.Vec3;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import StevenDimDoors.mod_pocketDim.DDProperties;
|
import StevenDimDoors.mod_pocketDim.DDProperties;
|
||||||
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
|
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
|
||||||
import StevenDimDoors.mod_pocketDim.core.LinkTypes;
|
|
||||||
import StevenDimDoors.mod_pocketDim.core.NewDimData;
|
|
||||||
import StevenDimDoors.mod_pocketDim.core.PocketManager;
|
import StevenDimDoors.mod_pocketDim.core.PocketManager;
|
||||||
import cpw.mods.fml.relauncher.Side;
|
import cpw.mods.fml.relauncher.Side;
|
||||||
import cpw.mods.fml.relauncher.SideOnly;
|
import cpw.mods.fml.relauncher.SideOnly;
|
||||||
|
@ -62,8 +59,14 @@ public class ItemRiftBlade extends ItemSword
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SideOnly(Side.CLIENT)
|
|
||||||
@Override
|
@Override
|
||||||
|
public int getDamageVsEntity(Entity par1Entity)
|
||||||
|
{
|
||||||
|
return 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SideOnly(Side.CLIENT)
|
||||||
public boolean hasEffect(ItemStack par1ItemStack)
|
public boolean hasEffect(ItemStack par1ItemStack)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
|
@ -76,12 +79,6 @@ public class ItemRiftBlade extends ItemSword
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getDamageVsEntity(Entity par1Entity)
|
|
||||||
{
|
|
||||||
return 7;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MovingObjectPosition getMovingObjectPositionFromPlayer(World par1World, EntityPlayer par2EntityPlayer, boolean par3)
|
public MovingObjectPosition getMovingObjectPositionFromPlayer(World par1World, EntityPlayer par2EntityPlayer, boolean par3)
|
||||||
{
|
{
|
||||||
|
@ -139,61 +136,6 @@ public class ItemRiftBlade extends ItemSword
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* How long it takes to use or consume an item
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public int getMaxItemUseDuration(ItemStack par1ItemStack)
|
|
||||||
{
|
|
||||||
return 72000;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EnumAction getItemUseAction(ItemStack stack)
|
|
||||||
{
|
|
||||||
return properties.RiftBladeRiftCreationEnabled ? EnumAction.bow : EnumAction.block;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPlayerStoppedUsing(ItemStack stack, World world, EntityPlayer player, int itemInUseCount)
|
|
||||||
{
|
|
||||||
//Condition for disabling rift creation
|
|
||||||
if (!properties.RiftBladeRiftCreationEnabled)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (world.isRemote)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Vec3 var2 = player.getLook(1.0F);
|
|
||||||
|
|
||||||
double cooef = -2;
|
|
||||||
var2.xCoord *= cooef;
|
|
||||||
var2.yCoord *= cooef;
|
|
||||||
var2.zCoord *= cooef;
|
|
||||||
double var5 = player.posX - var2.xCoord;
|
|
||||||
double var9 = player.posZ - var2.zCoord;
|
|
||||||
double var7 = player.posY - var2.yCoord + 2;
|
|
||||||
|
|
||||||
int x = MathHelper.floor_double(var5);
|
|
||||||
int y = MathHelper.floor_double(var7);
|
|
||||||
int z = MathHelper.floor_double(var9);
|
|
||||||
|
|
||||||
int orientation = (int) (MathHelper.floor_double((double) ((player.rotationYaw + 90) * 4.0F / 360.0F) + 0.5D) & 3);
|
|
||||||
|
|
||||||
//TODO: This looks weird. Shouldn't we aim to only create rifts on maxed-out usage time? i.e. "<= 0"
|
|
||||||
if (this.getMaxItemUseDuration(stack) - itemInUseCount > 12 &&
|
|
||||||
ItemDimensionalDoor.canPlace(world, x, y, z) && ItemDimensionalDoor.canPlace(world, x, y + 1, z))
|
|
||||||
{
|
|
||||||
NewDimData dimension = PocketManager.getDimensionData(world);
|
|
||||||
if (!dimension.isPocketDimension() && dimension.getLink(x, y + 1, z) == null)
|
|
||||||
{
|
|
||||||
dimension.createLink(x, y + 1, z, LinkTypes.POCKET);
|
|
||||||
player.worldObj.playSoundAtEntity(player,"mods.DimDoors.sfx.riftDoor", 0.6f, 1);
|
|
||||||
ItemDimensionalDoor.placeDoorBlock(world, x, y, z, orientation, mod_pocketDim.transientDoor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ItemStack onItemRightClick(ItemStack stack, World world, EntityPlayer player)
|
public ItemStack onItemRightClick(ItemStack stack, World world, EntityPlayer player)
|
||||||
{
|
{
|
||||||
|
@ -212,7 +154,8 @@ public class ItemRiftBlade extends ItemSword
|
||||||
double var7 = var3.dotProduct(var4);
|
double var7 = var3.dotProduct(var4);
|
||||||
if( (var7+.1) > 1.0D - 0.025D / var5 ? player.canEntityBeSeen(ent) : false)
|
if( (var7+.1) > 1.0D - 0.025D / var5 ? player.canEntityBeSeen(ent) : false)
|
||||||
{
|
{
|
||||||
((ItemRiftBlade) stack.getItem()).teleportToEntity(stack, ent, player);
|
teleportToEntity(stack, ent, player);
|
||||||
|
stack.damageItem(3, player);
|
||||||
return stack;
|
return stack;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -220,36 +163,33 @@ public class ItemRiftBlade extends ItemSword
|
||||||
MovingObjectPosition hit = this.getMovingObjectPositionFromPlayer(world, player, false);
|
MovingObjectPosition hit = this.getMovingObjectPositionFromPlayer(world, player, false);
|
||||||
if (hit != null)
|
if (hit != null)
|
||||||
{
|
{
|
||||||
if (world.getBlockId(hit.blockX, hit.blockY, hit.blockZ) == properties.RiftBlockID)
|
int x = hit.blockX;
|
||||||
|
int y = hit.blockY;
|
||||||
|
int z = hit.blockZ;
|
||||||
|
if (world.getBlockId(x, y, z) == properties.RiftBlockID)
|
||||||
{
|
{
|
||||||
if (PocketManager.getLink(hit.blockX, hit.blockY, hit.blockZ, world) != null)
|
if (PocketManager.getLink(x, y, z, world) != null)
|
||||||
{
|
{
|
||||||
Block block = mod_pocketDim.transientDoor;
|
if (player.canPlayerEdit(x, y, z, hit.sideHit, stack) &&
|
||||||
int x = hit.blockX;
|
player.canPlayerEdit(x, y + 1, z, hit.sideHit, stack))
|
||||||
int y = hit.blockY;
|
|
||||||
int z = hit.blockZ;
|
|
||||||
|
|
||||||
if (player.canPlayerEdit(x, y, z, hit.sideHit, stack) && player.canPlayerEdit(x, y + 1, z, hit.sideHit, stack) && !world.isRemote)
|
|
||||||
{
|
{
|
||||||
int orientation = MathHelper.floor_double((double)((player.rotationYaw + 180.0F) * 4.0F / 360.0F) - 0.5D) & 3;
|
int orientation = MathHelper.floor_double((double)((player.rotationYaw + 180.0F) * 4.0F / 360.0F) - 0.5D) & 3;
|
||||||
|
|
||||||
if (BaseItemDoor.canPlace(world, x, y, z) &&
|
if (BaseItemDoor.canPlace(world, x, y, z) &&
|
||||||
BaseItemDoor.canPlace(world, x, y - 1, z))
|
BaseItemDoor.canPlace(world, x, y - 1, z))
|
||||||
{
|
{
|
||||||
ItemDimensionalDoor.placeDoorBlock(world, x, y - 1, z, orientation, block);
|
ItemDimensionalDoor.placeDoorBlock(world, x, y - 1, z, orientation, mod_pocketDim.transientDoor);
|
||||||
player.worldObj.playSoundAtEntity(player,"mods.DimDoors.sfx.riftDoor", 0.6f, 1);
|
player.worldObj.playSoundAtEntity(player,"mods.DimDoors.sfx.riftDoor", 0.6f, 1);
|
||||||
stack.damageItem(10, player);
|
stack.damageItem(3, player);
|
||||||
|
return stack;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return stack;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//FIXME: Should this be inside or after this IF?
|
|
||||||
player.setItemInUse(stack, this.getMaxItemUseDuration(stack));
|
player.setItemInUse(stack, this.getMaxItemUseDuration(stack));
|
||||||
}
|
}
|
||||||
|
|
||||||
return stack;
|
return stack;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -269,21 +209,6 @@ public class ItemRiftBlade extends ItemSword
|
||||||
//That would cause this sword to accept gold as a repair material (since we set material = Gold).
|
//That would cause this sword to accept gold as a repair material (since we set material = Gold).
|
||||||
return mod_pocketDim.itemStableFabric.itemID == par2ItemStack.itemID ? true : false;
|
return mod_pocketDim.itemStableFabric.itemID == par2ItemStack.itemID ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onItemUse(ItemStack stack, EntityPlayer player, World world, int x, int y,
|
|
||||||
int z, int side, float hitX, float hitY, float hitZ)
|
|
||||||
{
|
|
||||||
if (BaseItemDoor.tryItemUse(mod_pocketDim.transientDoor, stack, player, world, x, y, z, side, true, false))
|
|
||||||
{
|
|
||||||
world.playSoundAtEntity(player,"mods.DimDoors.sfx.riftDoor", 0.6f, 1);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
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
|
||||||
|
@ -292,8 +217,8 @@ 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("Opens a temporary door, has");
|
par3List.add("Creates temporary doors");
|
||||||
par3List.add("a special teleport attack,");
|
par3List.add("on rifts, rotates doors,");
|
||||||
par3List.add("and rotates existing doors.");
|
par3List.add("and has a teleport attack.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ import net.minecraft.block.BlockRedstoneRepeater;
|
||||||
import net.minecraft.block.BlockStairs;
|
import net.minecraft.block.BlockStairs;
|
||||||
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.DimensionalDoor;
|
import StevenDimDoors.mod_pocketDim.blocks.BaseDimDoor;
|
||||||
|
|
||||||
public class BlockRotator
|
public class BlockRotator
|
||||||
{
|
{
|
||||||
|
@ -379,7 +379,7 @@ public class BlockRotator
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(Block.blocksList[blockID] instanceof BlockRedstoneRepeater || Block.blocksList[blockID] instanceof BlockDoor || Block.blocksList[blockID] instanceof DimensionalDoor || blockID== Block.tripWireSource.blockID || Block.blocksList[blockID] instanceof BlockComparator)
|
else if(Block.blocksList[blockID] instanceof BlockRedstoneRepeater || Block.blocksList[blockID] instanceof BlockDoor || Block.blocksList[blockID] instanceof BaseDimDoor || blockID== Block.tripWireSource.blockID || Block.blocksList[blockID] instanceof BlockComparator)
|
||||||
{
|
{
|
||||||
switch (metadata)
|
switch (metadata)
|
||||||
{
|
{
|
||||||
|
|
|
@ -194,7 +194,7 @@ public class MonolithSpawner implements IRegularTickReceiver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isMobSpawningAllowed()
|
public static boolean isMobSpawningAllowed()
|
||||||
{
|
{
|
||||||
//This function is used to retrieve the value of doMobSpawning. The code is the same
|
//This function is used to retrieve the value of doMobSpawning. The code is the same
|
||||||
//as the code used by Minecraft. Jaitsu requested this to make testing easier. ~SenseiKiwi
|
//as the code used by Minecraft. Jaitsu requested this to make testing easier. ~SenseiKiwi
|
||||||
|
|
|
@ -87,7 +87,7 @@ public class PocketBuilder
|
||||||
|
|
||||||
if (packConfig != null && packConfig.doDistortDoorCoordinates())
|
if (packConfig != null && packConfig.doDistortDoorCoordinates())
|
||||||
{
|
{
|
||||||
destination = calculateNoisyDestination(source, dimension, orientation);
|
destination = calculateNoisyDestination(source, dimension, dungeon, orientation);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -111,9 +111,9 @@ public class PocketBuilder
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Point3D calculateNoisyDestination(Point4D source, NewDimData dimension, int orientation)
|
private static Point3D calculateNoisyDestination(Point4D source, NewDimData dimension, DungeonData dungeon, int orientation)
|
||||||
{
|
{
|
||||||
int depth = dimension.packDepth();
|
int depth = NewDimData.calculatePackDepth(dimension.parent(), dungeon);
|
||||||
int forwardNoise = MathHelper.getRandomIntegerInRange(random, -50 * depth, 150 * depth);
|
int forwardNoise = MathHelper.getRandomIntegerInRange(random, -50 * depth, 150 * depth);
|
||||||
int sidewaysNoise = MathHelper.getRandomIntegerInRange(random, -10 * depth, 10 * depth);
|
int sidewaysNoise = MathHelper.getRandomIntegerInRange(random, -10 * depth, 10 * depth);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue