Added solar systems support
Added configuration for breathing and gravity in other mods dimensions Added configuration for groups world generation ratios in space Added world border knockback with chat warnings Added world border tolerance before entity kill Fixed non-ship transitions from hyperspace Fixed non-ship transitions when outside the overworld orbit Improved /space and /debug command supported aliases Removed chest teleportation from ship core
This commit is contained in:
parent
e269118b1e
commit
369bbc746f
25 changed files with 1023 additions and 776 deletions
|
@ -27,7 +27,7 @@ import net.minecraftforge.common.util.FakePlayerFactory;
|
|||
import net.minecraftforge.event.world.BlockEvent;
|
||||
|
||||
|
||||
public class CommonProxy {
|
||||
public abstract class CommonProxy {
|
||||
private static final WeakHashMap<GameProfile, WeakReference<EntityPlayer>> fakePlayers = new WeakHashMap<>(100);
|
||||
|
||||
void registerEntities() {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package cr0s.warpdrive;
|
||||
|
||||
|
||||
import cr0s.warpdrive.config.Dictionary;
|
||||
import cr0s.warpdrive.data.StarMapRegistry;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.item.EntityItem;
|
||||
|
@ -24,9 +24,10 @@ public class GravityManager {
|
|||
|
||||
public static double getGravityForEntity(Entity entity) {
|
||||
|
||||
if (WarpDrive.starMap.isLowGravity(entity.worldObj)) {
|
||||
final double gravity = StarMapRegistry.getGravity(entity);
|
||||
if (gravity < 1.0D) {
|
||||
// Is entity in hyper-space?
|
||||
boolean inHyperspace = WarpDrive.starMap.isInHyperspace(entity.worldObj);
|
||||
boolean inHyperspace = gravity > 0.4D;
|
||||
|
||||
if (isEntityInGraviField(entity)) {
|
||||
if (inHyperspace) {
|
||||
|
@ -62,7 +63,8 @@ public class GravityManager {
|
|||
}
|
||||
|
||||
public static double getItemGravity(EntityItem entity) {
|
||||
if (WarpDrive.starMap.isLowGravity(entity.worldObj)) {
|
||||
final double gravity = StarMapRegistry.getGravity(entity);
|
||||
if (gravity < 1.0D) {
|
||||
if (isEntityInGraviField(entity)) {
|
||||
return SPACE_FIELD_ITEM_GRAVITY;
|
||||
} else {
|
||||
|
@ -74,7 +76,8 @@ public class GravityManager {
|
|||
}
|
||||
|
||||
public static double getItemGravity2(EntityItem entity) {
|
||||
if (WarpDrive.starMap.isLowGravity(entity.worldObj)) {
|
||||
final double gravity = StarMapRegistry.getGravity(entity);
|
||||
if (gravity < 1.0D) {
|
||||
if (isEntityInGraviField(entity)) {
|
||||
return SPACE_FIELD_ITEM_GRAVITY2;
|
||||
} else {
|
||||
|
|
|
@ -11,6 +11,7 @@ import cr0s.warpdrive.block.TileEntityChunkLoader;
|
|||
import cr0s.warpdrive.block.TileEntityLaser;
|
||||
import cr0s.warpdrive.block.TileEntityLaserMedium;
|
||||
import cr0s.warpdrive.block.atomic.BlockAcceleratorControlPoint;
|
||||
import cr0s.warpdrive.block.atomic.BlockAcceleratorController;
|
||||
import cr0s.warpdrive.block.atomic.BlockChiller;
|
||||
import cr0s.warpdrive.block.atomic.BlockElectromagnetGlass;
|
||||
import cr0s.warpdrive.block.atomic.BlockElectromagnetPlain;
|
||||
|
@ -19,6 +20,7 @@ import cr0s.warpdrive.block.atomic.BlockParticlesInjector;
|
|||
import cr0s.warpdrive.block.atomic.BlockVoidShellGlass;
|
||||
import cr0s.warpdrive.block.atomic.BlockVoidShellPlain;
|
||||
import cr0s.warpdrive.block.atomic.TileEntityAcceleratorControlPoint;
|
||||
import cr0s.warpdrive.block.atomic.TileEntityAcceleratorController;
|
||||
import cr0s.warpdrive.block.atomic.TileEntityParticlesInjector;
|
||||
import cr0s.warpdrive.block.building.BlockShipScanner;
|
||||
import cr0s.warpdrive.block.building.TileEntityShipScanner;
|
||||
|
@ -95,6 +97,7 @@ import cr0s.warpdrive.damage.DamageShock;
|
|||
import cr0s.warpdrive.damage.DamageTeleportation;
|
||||
import cr0s.warpdrive.damage.DamageWarm;
|
||||
import cr0s.warpdrive.data.CamerasRegistry;
|
||||
import cr0s.warpdrive.data.CelestialObject;
|
||||
import cr0s.warpdrive.data.CloakManager;
|
||||
import cr0s.warpdrive.data.JumpgatesRegistry;
|
||||
import cr0s.warpdrive.data.StarMapRegistry;
|
||||
|
@ -624,10 +627,22 @@ public class WarpDrive implements LoadingCallback {
|
|||
spaceBiome = (new BiomeSpace(WarpDriveConfig.G_SPACE_BIOME_ID)).setColor(0).setDisableRain().setBiomeName("Space");
|
||||
BiomeDictionary.registerBiomeType(spaceBiome, BiomeDictionary.Type.DEAD, BiomeDictionary.Type.WASTELAND);
|
||||
DimensionManager.registerProviderType(WarpDriveConfig.G_SPACE_PROVIDER_ID, SpaceWorldProvider.class, true);
|
||||
DimensionManager.registerDimension(WarpDriveConfig.G_SPACE_DIMENSION_ID, WarpDriveConfig.G_SPACE_PROVIDER_ID);
|
||||
|
||||
DimensionManager.registerProviderType(WarpDriveConfig.G_HYPERSPACE_PROVIDER_ID, HyperSpaceWorldProvider.class, true);
|
||||
DimensionManager.registerDimension(WarpDriveConfig.G_HYPERSPACE_DIMENSION_ID, WarpDriveConfig.G_HYPERSPACE_PROVIDER_ID);
|
||||
|
||||
// only create dimensions if we own them
|
||||
for (CelestialObject celestialObject : WarpDriveConfig.celestialObjects) {
|
||||
if (celestialObject.isWarpDrive) {
|
||||
if (celestialObject.isSpace()) {
|
||||
DimensionManager.registerDimension(celestialObject.dimensionId, WarpDriveConfig.G_SPACE_PROVIDER_ID);
|
||||
} else if (celestialObject.isHyperspace()) {
|
||||
DimensionManager.registerDimension(celestialObject.dimensionId, WarpDriveConfig.G_HYPERSPACE_PROVIDER_ID);
|
||||
} else {
|
||||
WarpDrive.logger.error(String.format("Only space and hyperspace dimensions can be provided by WarpDrive. Dimension %d is not what of those.",
|
||||
celestialObject.dimensionId));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (FMLCommonHandler.instance().getEffectiveSide().isClient()) {
|
||||
creativeTabWarpDrive.setBackgroundImageName("items.png");
|
||||
|
@ -636,8 +651,12 @@ public class WarpDrive implements LoadingCallback {
|
|||
|
||||
@EventHandler
|
||||
public void onFMLPostInitialization(FMLPostInitializationEvent event) {
|
||||
DimensionManager.getWorld(WarpDriveConfig.G_SPACE_DIMENSION_ID);
|
||||
DimensionManager.getWorld(WarpDriveConfig.G_HYPERSPACE_DIMENSION_ID);
|
||||
// load all owned dimensions at boot
|
||||
for (CelestialObject celestialObject : WarpDriveConfig.celestialObjects) {
|
||||
if (celestialObject.isWarpDrive) {
|
||||
DimensionManager.getWorld(celestialObject.dimensionId);
|
||||
}
|
||||
}
|
||||
|
||||
WarpDriveConfig.onFMLPostInitialization();
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ public class TileEntityAirGenerator extends TileEntityAbstractEnergy {
|
|||
}
|
||||
|
||||
// Air generator works only in space & hyperspace
|
||||
if (WarpDrive.starMap.hasAtmosphere(worldObj)) {
|
||||
if (WarpDrive.starMap.hasAtmosphere(worldObj, xCoord, zCoord)) {
|
||||
if (getBlockMetadata() != 0) {
|
||||
worldObj.setBlockMetadataWithNotify(xCoord, yCoord, zCoord, 0, 2); // set disabled texture
|
||||
}
|
||||
|
|
|
@ -435,7 +435,7 @@ public class TileEntityLaser extends TileEntityAbstractLaser implements IBeamFre
|
|||
return 1.0D;
|
||||
}
|
||||
double attenuation;
|
||||
if (WarpDrive.starMap.hasAtmosphere(worldObj)) {
|
||||
if (WarpDrive.starMap.hasAtmosphere(worldObj, xCoord, zCoord)) {
|
||||
attenuation = WarpDriveConfig.LASER_CANNON_ENERGY_ATTENUATION_PER_AIR_BLOCK;
|
||||
} else {
|
||||
attenuation = WarpDriveConfig.LASER_CANNON_ENERGY_ATTENUATION_PER_VOID_BLOCK;
|
||||
|
|
|
@ -87,7 +87,7 @@ public class TileEntityMiningLaser extends TileEntityAbstractMiner {
|
|||
return;
|
||||
}
|
||||
|
||||
boolean isOnPlanet = WarpDrive.starMap.isPlanet(worldObj);
|
||||
boolean isOnPlanet = WarpDrive.starMap.hasAtmosphere(worldObj, xCoord, zCoord);
|
||||
|
||||
delayTicks--;
|
||||
if (currentState == STATE_WARMUP) {
|
||||
|
|
|
@ -566,13 +566,13 @@ public class TileEntityShipController extends TileEntityAbstractInterfaced {
|
|||
@Callback
|
||||
@Optional.Method(modid = "OpenComputers")
|
||||
public Object[] isInSpace(Context context, Arguments arguments) {
|
||||
return new Boolean[] { WarpDrive.starMap.isInSpace(worldObj) };
|
||||
return new Boolean[] { WarpDrive.starMap.isInSpace(worldObj, xCoord, zCoord) };
|
||||
}
|
||||
|
||||
@Callback
|
||||
@Optional.Method(modid = "OpenComputers")
|
||||
public Object[] isInHyperspace(Context context, Arguments arguments) {
|
||||
return new Boolean[] { WarpDrive.starMap.isInHyperspace(worldObj) };
|
||||
return new Boolean[] { WarpDrive.starMap.isInHyperspace(worldObj, xCoord, zCoord) };
|
||||
}
|
||||
|
||||
@Callback
|
||||
|
@ -792,82 +792,81 @@ public class TileEntityShipController extends TileEntityAbstractInterfaced {
|
|||
switch (methodName) {
|
||||
case "dim_positive": // dim_positive (front, right, up)
|
||||
return dim_positive(arguments);
|
||||
|
||||
|
||||
case "dim_negative": // dim_negative (back, left, down)
|
||||
return dim_negative(arguments);
|
||||
|
||||
|
||||
case "mode": // mode (mode)
|
||||
return mode(arguments);
|
||||
|
||||
|
||||
case "distance": // distance (distance)
|
||||
return distance(arguments);
|
||||
|
||||
|
||||
case "direction": // direction (direction)
|
||||
return direction(arguments);
|
||||
|
||||
|
||||
case "getAttachedPlayers":
|
||||
return getAttachedPlayers();
|
||||
|
||||
|
||||
case "summon":
|
||||
return summon(arguments);
|
||||
|
||||
|
||||
case "summon_all":
|
||||
setSummonAllFlag(true);
|
||||
|
||||
break;
|
||||
|
||||
case "position":
|
||||
if (core == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Object[] { core.xCoord, core.yCoord, core.zCoord };
|
||||
|
||||
|
||||
case "energy":
|
||||
if (core == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return core.energy();
|
||||
|
||||
|
||||
case "getEnergyRequired": // getEnergyRequired(distance)
|
||||
return getEnergyRequired(arguments);
|
||||
|
||||
|
||||
case "jump":
|
||||
doJump();
|
||||
|
||||
break;
|
||||
|
||||
case "getShipSize":
|
||||
return getShipSize();
|
||||
|
||||
|
||||
case "beaconFrequency":
|
||||
return beaconFrequency(arguments);
|
||||
|
||||
|
||||
case "getOrientation":
|
||||
if (core != null) {
|
||||
return new Object[] { core.dx, 0, core.dz };
|
||||
}
|
||||
return null;
|
||||
|
||||
|
||||
case "coreFrequency":
|
||||
return shipName(arguments);
|
||||
|
||||
|
||||
case "isInSpace":
|
||||
return new Boolean[] { WarpDrive.starMap.isInSpace(worldObj) };
|
||||
|
||||
return new Boolean[] { WarpDrive.starMap.isInSpace(worldObj, xCoord, zCoord) };
|
||||
|
||||
case "isInHyperspace":
|
||||
return new Boolean[] { WarpDrive.starMap.isInHyperspace(worldObj) };
|
||||
|
||||
return new Boolean[] { WarpDrive.starMap.isInHyperspace(worldObj, xCoord, zCoord) };
|
||||
|
||||
case "targetJumpgate":
|
||||
return targetJumpgate(arguments);
|
||||
|
||||
case "isAttached": // isAttached
|
||||
|
||||
case "isAttached":
|
||||
if (core != null) {
|
||||
return new Object[] { core.controller != null };
|
||||
}
|
||||
break;
|
||||
|
||||
case "movement":
|
||||
return movement(arguments);
|
||||
|
||||
|
||||
case "rotationSteps":
|
||||
return rotationSteps(arguments);
|
||||
|
||||
|
|
|
@ -16,11 +16,9 @@ import java.util.List;
|
|||
import java.util.UUID;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.network.NetworkManager;
|
||||
import net.minecraft.network.Packet;
|
||||
|
@ -29,12 +27,10 @@ import net.minecraft.potion.Potion;
|
|||
import net.minecraft.potion.PotionEffect;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.tileentity.TileEntityChest;
|
||||
import net.minecraft.util.AxisAlignedBB;
|
||||
import net.minecraft.util.MathHelper;
|
||||
import net.minecraft.util.StatCollector;
|
||||
import net.minecraft.util.Vec3;
|
||||
import net.minecraft.world.WorldServer;
|
||||
|
||||
import net.minecraftforge.common.DimensionManager;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
|
@ -55,7 +51,7 @@ public class TileEntityShipCore extends TileEntityAbstractEnergy implements ISta
|
|||
IDLE(0),
|
||||
BASIC_JUMP(1), // 0-128
|
||||
LONG_JUMP(2), // 0-12800
|
||||
TELEPORT(3),
|
||||
// TELEPORT(3),
|
||||
BEACON_JUMP(4), // Jump ship by beacon
|
||||
HYPERSPACE(5), // Jump to/from Hyperspace
|
||||
GATE_JUMP(6); // Jump via jumpgate
|
||||
|
@ -76,7 +72,6 @@ public class TileEntityShipCore extends TileEntityAbstractEnergy implements ISta
|
|||
private boolean isCooldownReported = false;
|
||||
protected int randomWarmupAddition = 0;
|
||||
|
||||
private int chestTeleportUpdateTicks = 0;
|
||||
private final int registryUpdateInterval_ticks = 20 * WarpDriveConfig.STARMAP_REGISTRY_UPDATE_INTERVAL_SECONDS;
|
||||
private int registryUpdateTicks = 0;
|
||||
private int bootTicks = 20;
|
||||
|
@ -209,22 +204,6 @@ public class TileEntityShipCore extends TileEntityAbstractEnergy implements ISta
|
|||
}
|
||||
|
||||
switch (currentMode) {
|
||||
case TELEPORT:
|
||||
if (worldObj.isBlockIndirectlyGettingPowered(xCoord, yCoord, zCoord)) {
|
||||
if (isChestSummonMode()) {
|
||||
chestTeleportUpdateTicks++;
|
||||
if (chestTeleportUpdateTicks >= 20) {
|
||||
summonPlayersByChestCode();
|
||||
chestTeleportUpdateTicks = 0;
|
||||
}
|
||||
} else {
|
||||
teleportPlayersToSpace();
|
||||
}
|
||||
} else {
|
||||
chestTeleportUpdateTicks = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case BASIC_JUMP:
|
||||
case LONG_JUMP:
|
||||
case BEACON_JUMP:
|
||||
|
@ -586,7 +565,8 @@ public class TileEntityShipCore extends TileEntityAbstractEnergy implements ISta
|
|||
if ( (shipBack + shipFront) > WarpDriveConfig.SHIP_MAX_SIDE_SIZE
|
||||
|| (shipLeft + shipRight) > WarpDriveConfig.SHIP_MAX_SIDE_SIZE
|
||||
|| (shipDown + shipUp) > WarpDriveConfig.SHIP_MAX_SIDE_SIZE) {
|
||||
reason.append("Ship is too big (max is " + WarpDriveConfig.SHIP_MAX_SIDE_SIZE + " per side)");
|
||||
reason.append(String.format("Ship is too big (max is %d per side)",
|
||||
WarpDriveConfig.SHIP_MAX_SIDE_SIZE));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -607,8 +587,9 @@ public class TileEntityShipCore extends TileEntityAbstractEnergy implements ISta
|
|||
updateShipMassAndVolume();
|
||||
if ( !isUnlimited
|
||||
&& shipMass > WarpDriveConfig.SHIP_VOLUME_MAX_ON_PLANET_SURFACE
|
||||
&& WarpDrive.starMap.isPlanet(worldObj) ) {
|
||||
reason.append("Ship is too big for a planet (max is " + WarpDriveConfig.SHIP_VOLUME_MAX_ON_PLANET_SURFACE + " blocks)");
|
||||
&& WarpDrive.starMap.isPlanet(worldObj, xCoord, zCoord) ) {
|
||||
reason.append(String.format("Ship is too big for a planet (max is %d blocks)",
|
||||
WarpDriveConfig.SHIP_VOLUME_MAX_ON_PLANET_SURFACE));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -712,10 +693,12 @@ public class TileEntityShipCore extends TileEntityAbstractEnergy implements ISta
|
|||
if (percent > 80F) {
|
||||
return true;
|
||||
} else if (percent <= 0.001) {
|
||||
reason.append("Ship is not inside a jumpgate. Jump rejected. Nearest jumpgate is " + jumpgate.toNiceString());
|
||||
reason.append(String.format("Ship is not inside a jumpgate. Jump rejected. Nearest jumpgate is %s",
|
||||
jumpgate.toNiceString()));
|
||||
return false;
|
||||
} else {
|
||||
reason.append("Ship is only " + percent + "% inside a jumpgate. Sorry, we'll loose too much crew as is, jump rejected.");
|
||||
reason.append(String.format("Ship is only %.1f%% inside a jumpgate. Sorry, we'll loose too much crew as is, jump rejected.",
|
||||
percent));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -883,7 +866,7 @@ public class TileEntityShipCore extends TileEntityAbstractEnergy implements ISta
|
|||
controller.getUp() + 1 + controller.getDown(),
|
||||
controller.getRight() + 1 + controller.getLeft());
|
||||
int maxDistance = WarpDriveConfig.SHIP_MAX_JUMP_DISTANCE;
|
||||
if (WarpDrive.starMap.isInHyperspace(worldObj)) {
|
||||
if (WarpDrive.starMap.isInHyperspace(worldObj, xCoord, zCoord)) {
|
||||
maxDistance *= 100;
|
||||
}
|
||||
if (Math.abs(movement.x) - shipSize.x > maxDistance) {
|
||||
|
@ -919,123 +902,6 @@ public class TileEntityShipCore extends TileEntityAbstractEnergy implements ISta
|
|||
}
|
||||
}
|
||||
|
||||
private void teleportPlayersToSpace() {
|
||||
if (!WarpDrive.starMap.isInSpace(worldObj)) {
|
||||
AxisAlignedBB axisalignedbb = AxisAlignedBB.getBoundingBox(xCoord - 2, yCoord - 1, zCoord - 2, xCoord + 2, yCoord + 4, zCoord + 2);
|
||||
List list = worldObj.getEntitiesWithinAABBExcludingEntity(null, axisalignedbb);
|
||||
|
||||
final int dimensionIdSpace = WarpDriveConfig.G_SPACE_DIMENSION_ID;
|
||||
WorldServer spaceWorld = MinecraftServer.getServer().worldServerForDimension(dimensionIdSpace);
|
||||
if (spaceWorld == null) {
|
||||
String msg = "Unable to load Space dimension " + dimensionIdSpace + ", aborting teleportation.";
|
||||
messageToAllPlayersOnShip(msg);
|
||||
return;
|
||||
}
|
||||
for (Object o : list) {
|
||||
if (!energy_consume(WarpDriveConfig.SHIP_TELEPORT_ENERGY_PER_ENTITY, false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Entity entity = (Entity) o;
|
||||
int x = MathHelper.floor_double(entity.posX);
|
||||
int z = MathHelper.floor_double(entity.posZ);
|
||||
// int y = MathHelper.floor_double(entity.posY);
|
||||
int newY;
|
||||
|
||||
for (newY = 254; newY > 0; newY--) {
|
||||
if (spaceWorld.getBlock(x, newY, z).isAssociatedBlock(Blocks.wool)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (newY <= 0) {
|
||||
newY = 254;
|
||||
}
|
||||
|
||||
if (entity instanceof EntityPlayerMP) {
|
||||
((EntityPlayerMP) entity).mcServer.getConfigurationManager().transferPlayerToDimension(((EntityPlayerMP) entity),
|
||||
dimensionIdSpace,
|
||||
new SpaceTeleporter(DimensionManager.getWorld(dimensionIdSpace), 0, x, 256, z));
|
||||
|
||||
if (spaceWorld.isAirBlock(x, newY, z)) {
|
||||
spaceWorld.setBlock(x, newY, z, Blocks.stone, 0, 2);
|
||||
spaceWorld.setBlock(x + 1, newY, z, Blocks.stone, 0, 2);
|
||||
spaceWorld.setBlock(x - 1, newY, z, Blocks.stone, 0, 2);
|
||||
spaceWorld.setBlock(x, newY, z + 1, Blocks.stone, 0, 2);
|
||||
spaceWorld.setBlock(x, newY, z - 1, Blocks.stone, 0, 2);
|
||||
spaceWorld.setBlock(x + 1, newY, z + 1, Blocks.stone, 0, 2);
|
||||
spaceWorld.setBlock(x - 1, newY, z - 1, Blocks.stone, 0, 2);
|
||||
spaceWorld.setBlock(x + 1, newY, z - 1, Blocks.stone, 0, 2);
|
||||
spaceWorld.setBlock(x - 1, newY, z + 1, Blocks.stone, 0, 2);
|
||||
}
|
||||
|
||||
((EntityPlayerMP) entity).setPositionAndUpdate(x + 0.5D, newY + 2.0D, z + 0.5D);
|
||||
((EntityPlayerMP) entity).sendPlayerAbilities();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void summonPlayersByChestCode() {
|
||||
if (worldObj.getTileEntity(xCoord, yCoord + 1, zCoord) == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
TileEntityChest chest = (TileEntityChest) worldObj.getTileEntity(xCoord, yCoord + 1, zCoord);
|
||||
EntityPlayerMP player;
|
||||
|
||||
for (int i = 0; i < MinecraftServer.getServer().getConfigurationManager().playerEntityList.size(); i++) {
|
||||
player = (EntityPlayerMP) MinecraftServer.getServer().getConfigurationManager().playerEntityList.get(i);
|
||||
|
||||
if (checkPlayerInventory(chest, player)) {
|
||||
WarpDrive.logger.info(this + " Summoning " + player.getDisplayName());
|
||||
summonPlayer(player, xCoord, yCoord + 2, zCoord);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean checkPlayerInventory(TileEntityChest chest, EntityPlayerMP player) {
|
||||
Boolean result = false;
|
||||
final int MIN_KEY_LENGTH = 5;
|
||||
int keyLength = 0;
|
||||
|
||||
for (int index = 0; index < chest.getSizeInventory(); index++) {
|
||||
ItemStack chestItem = chest.getStackInSlot(index);
|
||||
ItemStack playerItem = player.inventory.getStackInSlot(9 + index);
|
||||
|
||||
if (chestItem == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (playerItem == null || chestItem != playerItem
|
||||
|| chestItem.getItemDamage() != playerItem.getItemDamage()
|
||||
|| chestItem.stackSize != playerItem.stackSize) {
|
||||
return false;
|
||||
} else {
|
||||
result = true;
|
||||
}
|
||||
|
||||
keyLength++;
|
||||
}
|
||||
|
||||
if (keyLength < MIN_KEY_LENGTH) {
|
||||
WarpDrive.logger.info("[ChestCode] Key is too short: " + keyLength + " < " + MIN_KEY_LENGTH);
|
||||
return false;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private Boolean isChestSummonMode() {
|
||||
TileEntity tileEntity = worldObj.getTileEntity(xCoord, yCoord + 1, zCoord);
|
||||
|
||||
if (tileEntity != null) {
|
||||
return (tileEntity instanceof TileEntityChest);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean isOutsideBB(AxisAlignedBB axisalignedbb, int x, int y, int z) {
|
||||
return axisalignedbb.minX > x || axisalignedbb.maxX < x
|
||||
|| axisalignedbb.minY > y || axisalignedbb.maxY < y
|
||||
|
@ -1051,9 +917,6 @@ public class TileEntityShipCore extends TileEntityAbstractEnergy implements ISta
|
|||
|
||||
public static int calculateRequiredEnergy(EnumShipCoreMode enumShipCoreMode, int shipVolume, int jumpDistance) {
|
||||
switch (enumShipCoreMode) {
|
||||
case TELEPORT:
|
||||
return WarpDriveConfig.SHIP_TELEPORT_ENERGY_PER_ENTITY;
|
||||
|
||||
case BASIC_JUMP:
|
||||
return (WarpDriveConfig.SHIP_NORMALJUMP_ENERGY_PER_BLOCK * shipVolume) + (WarpDriveConfig.SHIP_NORMALJUMP_ENERGY_PER_DISTANCE * jumpDistance);
|
||||
|
||||
|
|
|
@ -134,7 +134,7 @@ public class BlockAir extends Block {
|
|||
}
|
||||
|
||||
int concentration = world.getBlockMetadata(x, y, z);
|
||||
boolean hasAtmosphere = WarpDrive.starMap.hasAtmosphere(world);
|
||||
boolean hasAtmosphere = WarpDrive.starMap.hasAtmosphere(world, x, z);
|
||||
|
||||
// Remove air block to vacuum block
|
||||
if (concentration <= 0 || hasAtmosphere) {
|
||||
|
@ -394,7 +394,7 @@ public class BlockAir extends Block {
|
|||
|
||||
@Override
|
||||
public void onBlockAdded(World world, int x, int y, int z) {
|
||||
if (!WarpDrive.starMap.hasAtmosphere(world)) {
|
||||
if (!WarpDrive.starMap.hasAtmosphere(world, x, z)) {
|
||||
world.scheduleBlockUpdate(x, y, z, this, tickRate(world));
|
||||
} else {
|
||||
world.setBlockToAir(x, y, z);
|
||||
|
|
|
@ -112,7 +112,7 @@ public class BlockGas extends Block {
|
|||
@Override
|
||||
public void onBlockAdded(World world, int x, int y, int z) {
|
||||
// Gas blocks are only allowed in space
|
||||
if (WarpDrive.starMap.hasAtmosphere(world)) {
|
||||
if (WarpDrive.starMap.hasAtmosphere(world, x, z)) {
|
||||
world.setBlockToAir(x, y, z);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,11 +2,12 @@ package cr0s.warpdrive.command;
|
|||
|
||||
import cr0s.warpdrive.Commons;
|
||||
import cr0s.warpdrive.WarpDrive;
|
||||
import cr0s.warpdrive.config.WarpDriveConfig;
|
||||
import cr0s.warpdrive.data.StarMapRegistry;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.command.CommandBase;
|
||||
import net.minecraft.command.ICommandSender;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.world.World;
|
||||
|
@ -46,43 +47,15 @@ public class CommandDebug extends CommandBase
|
|||
int dim, x, y, z, metadata;
|
||||
int block;
|
||||
String actions;
|
||||
try
|
||||
{
|
||||
String par = params[0].toLowerCase();
|
||||
switch (par) {
|
||||
case "world":
|
||||
case "overworld":
|
||||
case "0":
|
||||
dim = 0;
|
||||
break;
|
||||
case "nether":
|
||||
case "thenether":
|
||||
case "-1":
|
||||
dim = -1;
|
||||
break;
|
||||
case "s":
|
||||
case "space":
|
||||
dim = WarpDriveConfig.G_SPACE_DIMENSION_ID;
|
||||
break;
|
||||
case "h":
|
||||
case "hyper":
|
||||
case "hyperspace":
|
||||
dim = WarpDriveConfig.G_HYPERSPACE_DIMENSION_ID;
|
||||
break;
|
||||
default:
|
||||
dim = Integer.parseInt(par);
|
||||
break;
|
||||
}
|
||||
|
||||
try {
|
||||
dim = StarMapRegistry.getDimensionId(params[0], (EntityPlayer) icommandsender);
|
||||
x = Integer.parseInt(params[1]);
|
||||
y = Integer.parseInt(params[2]);
|
||||
z = Integer.parseInt(params[3]);
|
||||
block = Integer.parseInt(params[4]);
|
||||
metadata = Integer.parseInt(params[5]);
|
||||
actions = params[6];
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
} catch (Exception exception) {
|
||||
exception.printStackTrace();
|
||||
Commons.addChatMessage(player, getCommandUsage(icommandsender));
|
||||
return;
|
||||
|
|
|
@ -60,7 +60,7 @@ public class CommandGenerate extends CommandBase {
|
|||
String structure = params[0];
|
||||
|
||||
// Reject command, if player is not in space
|
||||
if (!WarpDrive.starMap.isInSpace(world) && (!"ship".equals(structure))) {
|
||||
if (!WarpDrive.starMap.isInSpace(world, x, z) && (!"ship".equals(structure))) {
|
||||
Commons.addChatMessage(commandSender, "* generate: this structure is only allowed in space!");
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,9 @@ package cr0s.warpdrive.command;
|
|||
|
||||
import cr0s.warpdrive.Commons;
|
||||
import cr0s.warpdrive.WarpDrive;
|
||||
import cr0s.warpdrive.config.WarpDriveConfig;
|
||||
import cr0s.warpdrive.data.CelestialObject;
|
||||
import cr0s.warpdrive.data.StarMapRegistry;
|
||||
import cr0s.warpdrive.data.VectorI;
|
||||
import cr0s.warpdrive.world.SpaceTeleporter;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -54,7 +56,7 @@ public class CommandSpace extends CommandBase {
|
|||
if (entityPlayerMPs_found != null) {
|
||||
entityPlayerMPs = entityPlayerMPs_found;
|
||||
} else if (sender instanceof EntityPlayer) {
|
||||
targetDimensionId = getDimensionId(params[0]);
|
||||
targetDimensionId = StarMapRegistry.getDimensionId(params[0], (EntityPlayer) sender);
|
||||
} else {
|
||||
Commons.addChatMessage(sender, "/space: player not found '" + params[0] + "'");
|
||||
return;
|
||||
|
@ -68,7 +70,7 @@ public class CommandSpace extends CommandBase {
|
|||
Commons.addChatMessage(sender, "/space: player not found '" + params[0] + "'");
|
||||
return;
|
||||
}
|
||||
targetDimensionId = getDimensionId(params[1]);
|
||||
targetDimensionId = StarMapRegistry.getDimensionId(params[1], entityPlayerMPs[0]);
|
||||
|
||||
} else {
|
||||
Commons.addChatMessage(sender, "/space: too many arguments " + params.length);
|
||||
|
@ -83,14 +85,54 @@ public class CommandSpace extends CommandBase {
|
|||
|
||||
for (EntityPlayerMP entityPlayerMP : entityPlayerMPs) {
|
||||
// toggle between overworld and space if no dimension was provided
|
||||
int newX = MathHelper.floor_double(entityPlayerMP.posX);
|
||||
int newY = Math.min(255, Math.max(0, MathHelper.floor_double(entityPlayerMP.posY)));
|
||||
int newZ = MathHelper.floor_double(entityPlayerMP.posZ);
|
||||
if (targetDimensionId == Integer.MAX_VALUE) {
|
||||
if (WarpDrive.starMap.isInSpace(entityPlayerMP.worldObj)) {
|
||||
targetDimensionId = 0;
|
||||
CelestialObject celestialObject = StarMapRegistry.getCelestialObject(entityPlayerMP.worldObj.provider.dimensionId, (int) entityPlayerMP.posX, (int) entityPlayerMP.posZ);
|
||||
if (celestialObject.isSpace() || celestialObject.isHyperspace()) {
|
||||
// in space or hyperspace => move to closest child
|
||||
celestialObject = StarMapRegistry.getClosestChildCelestialObject(entityPlayerMP.worldObj.provider.dimensionId, (int) entityPlayerMP.posX, (int) entityPlayerMP.posZ);
|
||||
if (celestialObject == null) {
|
||||
targetDimensionId = 0;
|
||||
} else {
|
||||
targetDimensionId = celestialObject.dimensionId;
|
||||
VectorI vEntry = celestialObject.getEntryOffset();
|
||||
newX += vEntry.x;
|
||||
newY += vEntry.y;
|
||||
newZ += vEntry.z;
|
||||
}
|
||||
} else {
|
||||
targetDimensionId = WarpDriveConfig.G_SPACE_DIMENSION_ID;
|
||||
// on a planet => move to space
|
||||
celestialObject = StarMapRegistry.getClosestParentCelestialObject(entityPlayerMP.worldObj.provider.dimensionId, (int) entityPlayerMP.posX, (int) entityPlayerMP.posZ);
|
||||
if (celestialObject == null) {
|
||||
targetDimensionId = 0;
|
||||
|
||||
} else {
|
||||
VectorI vEntry = celestialObject.getEntryOffset();
|
||||
newX -= vEntry.x;
|
||||
newY -= vEntry.y;
|
||||
newZ -= vEntry.z;
|
||||
if (celestialObject.isSpace()) {
|
||||
targetDimensionId = celestialObject.dimensionId;
|
||||
} else {
|
||||
targetDimensionId = celestialObject.parentDimensionId;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// get target celestial object
|
||||
final CelestialObject celestialObject = StarMapRegistry.getCelestialObject(targetDimensionId, newX, newZ);
|
||||
|
||||
// force to center if we're outside the border
|
||||
if ( celestialObject != null
|
||||
&& celestialObject.getSquareDistanceOutsideBorder(targetDimensionId, newX, newZ) > 0 ) {
|
||||
// outside
|
||||
newX = celestialObject.dimensionCenterX;
|
||||
newZ = celestialObject.dimensionCenterZ;
|
||||
}
|
||||
|
||||
// get target world
|
||||
WorldServer targetWorld = server.worldServerForDimension(targetDimensionId);
|
||||
if (targetWorld == null) {
|
||||
|
@ -107,9 +149,6 @@ public class CommandSpace extends CommandBase {
|
|||
}
|
||||
|
||||
// find a good spot
|
||||
int newX = MathHelper.floor_double(entityPlayerMP.posX);
|
||||
int newY = Math.min(255, Math.max(0, MathHelper.floor_double(entityPlayerMP.posY)));
|
||||
int newZ = MathHelper.floor_double(entityPlayerMP.posZ);
|
||||
|
||||
if ( (targetWorld.isAirBlock(newX, newY - 1, newZ) && !entityPlayerMP.capabilities.allowFlying)
|
||||
|| !targetWorld.isAirBlock(newX, newY, newZ)
|
||||
|
@ -158,25 +197,4 @@ public class CommandSpace extends CommandBase {
|
|||
|
||||
return null;
|
||||
}
|
||||
|
||||
private int getDimensionId(String stringDimension) {
|
||||
if (stringDimension.equalsIgnoreCase("overworld")) {
|
||||
return 0;
|
||||
} else if (stringDimension.equalsIgnoreCase("nether")) {
|
||||
return -1;
|
||||
} else if (stringDimension.equalsIgnoreCase("end") || stringDimension.equalsIgnoreCase("theend")) {
|
||||
return 1;
|
||||
} else if (stringDimension.equalsIgnoreCase("space")) {
|
||||
return WarpDriveConfig.G_SPACE_DIMENSION_ID;
|
||||
} else if (stringDimension.equalsIgnoreCase("hyper") || stringDimension.equalsIgnoreCase("hyperspace")) {
|
||||
return WarpDriveConfig.G_HYPERSPACE_DIMENSION_ID;
|
||||
}
|
||||
try {
|
||||
return Integer.parseInt(stringDimension);
|
||||
} catch(Exception exception) {
|
||||
// exception.printStackTrace();
|
||||
WarpDrive.logger.info("/space: invalid dimension '" + stringDimension + "', expecting integer or overworld/nether/end/theend/space/hyper/hyperspace");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ import cr0s.warpdrive.compat.CompatWarpDrive;
|
|||
import cr0s.warpdrive.config.filler.FillerManager;
|
||||
import cr0s.warpdrive.config.structures.StructureManager;
|
||||
import cr0s.warpdrive.config.structures.StructureReference;
|
||||
import cr0s.warpdrive.data.Planet;
|
||||
import cr0s.warpdrive.data.CelestialObject;
|
||||
import org.xml.sax.ErrorHandler;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.SAXParseException;
|
||||
|
@ -99,10 +99,7 @@ public class WarpDriveConfig {
|
|||
// General
|
||||
public static int G_SPACE_BIOME_ID = 95;
|
||||
public static int G_SPACE_PROVIDER_ID = 14;
|
||||
public static int G_SPACE_DIMENSION_ID = -2;
|
||||
public static int G_HYPERSPACE_PROVIDER_ID = 15;
|
||||
public static int G_HYPERSPACE_DIMENSION_ID = -3;
|
||||
public static int G_SPACE_WORLDBORDER_BLOCKS = 100000;
|
||||
public static int G_ENTITY_SPHERE_GENERATOR_ID = 241;
|
||||
public static int G_ENTITY_STAR_CORE_ID = 242;
|
||||
public static int G_ENTITY_CAMERA_ID = 243;
|
||||
|
@ -146,7 +143,7 @@ public class WarpDriveConfig {
|
|||
public static boolean LOGGING_ACCELERATOR = false;
|
||||
|
||||
// Starmap
|
||||
public static Planet[] PLANETS = null;
|
||||
public static CelestialObject[] celestialObjects = null;
|
||||
public static int STARMAP_REGISTRY_UPDATE_INTERVAL_SECONDS = 10;
|
||||
|
||||
// Space generator
|
||||
|
@ -378,14 +375,8 @@ public class WarpDriveConfig {
|
|||
config.get("general", "space_biome_id", G_SPACE_BIOME_ID, "Space biome ID").getInt());
|
||||
G_SPACE_PROVIDER_ID = Commons.clamp(Integer.MIN_VALUE, Integer.MAX_VALUE,
|
||||
config.get("general", "space_provider_id", G_SPACE_PROVIDER_ID, "Space dimension provider ID").getInt());
|
||||
G_SPACE_DIMENSION_ID = Commons.clamp(Integer.MIN_VALUE, Integer.MAX_VALUE,
|
||||
config.get("general", "space_dimension_id", G_SPACE_DIMENSION_ID, "Space dimension world ID").getInt());
|
||||
G_HYPERSPACE_PROVIDER_ID = Commons.clamp(Integer.MIN_VALUE, Integer.MAX_VALUE,
|
||||
config.get("general", "hyperspace_provider_id", G_HYPERSPACE_PROVIDER_ID, "Hyperspace dimension provider ID").getInt());
|
||||
G_HYPERSPACE_DIMENSION_ID = Commons.clamp(Integer.MIN_VALUE, Integer.MAX_VALUE,
|
||||
config.get("general", "hyperspace_dimension_id", G_HYPERSPACE_DIMENSION_ID, "Hyperspace dimension world ID").getInt());
|
||||
G_SPACE_WORLDBORDER_BLOCKS = Commons.clamp(0, 3000000,
|
||||
config.get("general", "space_worldborder_blocks", G_SPACE_WORLDBORDER_BLOCKS, "World border applied to hyperspace & space, set to 0 to disable it").getInt());
|
||||
|
||||
G_ENTITY_SPHERE_GENERATOR_ID = Commons.clamp(Integer.MIN_VALUE, Integer.MAX_VALUE,
|
||||
config.get("general", "entity_sphere_generator_id", G_ENTITY_SPHERE_GENERATOR_ID, "Entity sphere generator ID").getInt());
|
||||
|
@ -443,30 +434,80 @@ public class WarpDriveConfig {
|
|||
LOGGING_FORCEFIELD_REGISTRY = config.get("logging", "enable_forcefield_registry_logs", LOGGING_FORCEFIELD_REGISTRY, "ForceField registry logs, enable it to dump forcefield registry updates").getBoolean(false);
|
||||
LOGGING_ACCELERATOR = config.get("logging", "enable_accelerator_logs", LOGGING_ACCELERATOR, "Detailed accelerator logs to help debug the mod, enable it before reporting a bug").getBoolean(false);
|
||||
|
||||
// Planets
|
||||
// Celestial objects
|
||||
{
|
||||
config.addCustomCategoryComment("planets",
|
||||
"Planets are other dimensions connected through the Space dimension. Default is overworld with 100k radius.\n"
|
||||
+ "Each planet orbit is square shaped and defined as a list of 7 integers (all measured in blocks).");
|
||||
|
||||
ConfigCategory categoryPlanets = config.getCategory("planets");
|
||||
String[] planetsName = categoryPlanets.getValues().keySet().toArray(new String[0]);
|
||||
if (planetsName.length == 0) {
|
||||
planetsName = new String[] { "overworld" };
|
||||
config.addCustomCategoryComment("celestial_objects",
|
||||
"Celestial objects are generally planets. They can also be a solar system (space) or the all mighty hyperspace.\n"
|
||||
+ "Each celestial object is defined with a list of 14 integers in the following exact order:\n"
|
||||
+ "- dimensionId : this is the id of the dimension. 0 is the Overworld, -1 is the Nether, 1 is the End."
|
||||
+ "- dimensionCenterX, dimensionCenterZ: those are the center coordinate of that dimension world border.\n"
|
||||
+ " This is measured in blocks. For convenience, it's usually 0, 0\n"
|
||||
+ "- radiusX, radiusZ: this is the world border radius, measured in blocks. The total size is twice that.\n"
|
||||
+ " This is also the size of the orbit area in space, so don't go too big\n"
|
||||
+ "- parentDimensionId: this is the id of the parent dimension. For planets, this is the space dimension id.\n"
|
||||
+ "- parentCenterX, parentCenterZ: this is the center coordinates in the parent dimension. For a planet, it needs to be different than 0, 0.\n"
|
||||
+ "- isWarpDrive: this is a boolean flag defining if WarpDrive provides this dimension or not.\n"
|
||||
+ " Currently only Space and Hyperspace can be provided: use other mods to generate planet world.\n"
|
||||
+ " Set this to 0 to use another mod Space dimension.\n"
|
||||
+ "- moonRatio: this is the chance for a moon to generate in a chunk.\n"
|
||||
+ "- asteroidRatio: this is the chance for a lone asteroid to generate in a chunk.\n"
|
||||
+ "- asteroidFieldRatio: this is the chance for an asteroid field to generate in a chunk.\n"
|
||||
+ " All 3 ratios work the same way: 100000 is 100% chance, 0 will disable it. Those only works in WarpDrive dimensions, they're ignored otherwise.\n"
|
||||
+ "- gravity: this is the gravity simulation type. 0 is vanilla, 1 is space, 2 is hyperspace.\n"
|
||||
+ "- isBreathable: this is a boolean flag defining if ambient atmosphere is breathable.\n"
|
||||
+ "Hyperspace is a dimension which is its own parent. In other words, hyperspace.dimensionId = hyperspace.parentDimensionId. There can be only one.\n"
|
||||
+ "A Space is a dimension with Hyperspace as its parent.\n"
|
||||
+ "In theory, multiple planets can exists in the same minecraft world.");
|
||||
final String commentDimension = "dimensionId, dimensionCenterX, dimensionCenterZ, radiusX, radiusZ,\n"
|
||||
+ "parentDimensionId, parentCenterX, parentCenterZ, isWarpDrive,\n"
|
||||
+ "moonRatio, asteroidRatio, asteroidFieldRatio, gravity, isBreathable";
|
||||
ConfigCategory categoryDimensions = config.getCategory("celestial_objects");
|
||||
String[] nameDimensions = categoryDimensions.getValues().keySet().toArray(new String[0]);
|
||||
if (nameDimensions.length == 0) {
|
||||
nameDimensions = new String[] { "overworld", "nether", "end", "space", "hyperspace" };
|
||||
int[][] defaultDimensions = {
|
||||
// id x z radiusX radiusZ id parentX parentZ W moon ast astF g air
|
||||
{ 0, 0, 0, 10000, 10000, -2, 0, 0, 0, 0, 0, 0, 0, 1 },
|
||||
{ -1, 0, 0, 2500, 2500, -2, 30000, -50000, 0, 0, 0, 0, 0, 1 },
|
||||
{ 1, 0, 0, 1000, 1000, -2, -80000, 60000, 0, 0, 0, 0, 0, 1 },
|
||||
{ -2, 0, 0, 100000, 100000, -3, 0, 0, 1, 125, 666, 166, 1, 0 },
|
||||
{ -3, 0, 0, 100000, 100000, -3, 0, 0, 1, 0, 0, 0, 2, 0 }
|
||||
};
|
||||
for (int index = 0; index < nameDimensions.length; index++) {
|
||||
config.get("celestial_objects", nameDimensions[index], defaultDimensions[index], commentDimension).getIntList();
|
||||
}
|
||||
}
|
||||
|
||||
int[] defaultPlanet = { 0, 0, 0, 100000, 100000, 0, 0 }; // 30000000 is Minecraft limit for SetBlock
|
||||
PLANETS = new Planet[planetsName.length];
|
||||
int[] intDefaultDimension = { 0, 0, 0, 10000, 10000, -2, 0, 0, 0, 0, 0, 0, 0, 1 }; // 30000000 is Minecraft limit for SetBlock
|
||||
celestialObjects = new CelestialObject[nameDimensions.length];
|
||||
int index = 0;
|
||||
for (String name : planetsName) {
|
||||
int[] planetInts = config.get("planets", name, defaultPlanet, "dimensionId, dimensionCenterX, dimensionCenterZ, radiusX, radiusZ, spaceCenterX, spaceCenterZ").getIntList();
|
||||
if (planetInts.length != 7) {
|
||||
WarpDrive.logger.warn("Invalid planet definition '" + name + "' (exactly 7 integers are expected), using default instead");
|
||||
planetInts = defaultPlanet.clone();
|
||||
for (String name : nameDimensions) {
|
||||
int[] intDimension = config.get("celestial_objects", name, intDefaultDimension, commentDimension).getIntList();
|
||||
if (intDimension.length != 14) {
|
||||
WarpDrive.logger.warn("Invalid dimension definition '" + name + "' (exactly 8 integers are expected), using default instead");
|
||||
intDimension = intDefaultDimension.clone();
|
||||
}
|
||||
Planet planet = new Planet(planetInts[0], planetInts[1], planetInts[2], planetInts[3], planetInts[4], planetInts[5], planetInts[6]);
|
||||
WarpDrive.logger.info("Adding '" + name + "' as " + planet);
|
||||
PLANETS[index] = planet;
|
||||
CelestialObject celestialObject = new CelestialObject(intDimension[0], intDimension[1], intDimension[2], intDimension[3], intDimension[4],
|
||||
intDimension[5], intDimension[6], intDimension[7]);
|
||||
celestialObject.setSelfProvider(intDimension[8] != 0);
|
||||
celestialObject.addGenerationRatio(intDimension[ 9] / 100000.0D, "moon");
|
||||
celestialObject.addGenerationRatio(intDimension[10] / 100000.0D, "asteroid");
|
||||
celestialObject.addGenerationRatio(intDimension[11] / 100000.0D, "asteroidField");
|
||||
switch(intDimension[12]) {
|
||||
case 0:
|
||||
default:
|
||||
celestialObject.setGravity(1.0D);
|
||||
break;
|
||||
case 1:
|
||||
celestialObject.setGravity(0.3D);
|
||||
break;
|
||||
case 2:
|
||||
celestialObject.setGravity(0.45D);
|
||||
break;
|
||||
}
|
||||
celestialObject.setBreathable(intDimension[13] != 0);
|
||||
WarpDrive.logger.info("Adding '" + name + "' as " + celestialObject);
|
||||
celestialObjects[index] = celestialObject;
|
||||
index++;
|
||||
}
|
||||
// FIXME: check planets aren't overlapping
|
||||
|
@ -927,9 +968,10 @@ public class WarpDriveConfig {
|
|||
|
||||
public static void onFMLPostInitialization() {
|
||||
// unpack default XML files if none are defined
|
||||
File[] files = configDirectory.listFiles((file_notUsed, name) -> {
|
||||
return name.endsWith(".xml");
|
||||
});
|
||||
File[] files = configDirectory.listFiles((file_notUsed, name) -> name.endsWith(".xml"));
|
||||
if (files == null) {
|
||||
throw new RuntimeException("Critical error accessing configuration directory, searching for *.xml files: " + configDirectory);
|
||||
}
|
||||
if (files.length == 0) {
|
||||
for (String defaultXMLfilename : defaultXMLfilenames) {
|
||||
unpackResourceToFolder(defaultXMLfilename, "config", configDirectory);
|
||||
|
|
271
src/main/java/cr0s/warpdrive/data/CelestialObject.java
Normal file
271
src/main/java/cr0s/warpdrive/data/CelestialObject.java
Normal file
|
@ -0,0 +1,271 @@
|
|||
package cr0s.warpdrive.data;
|
||||
|
||||
import cr0s.warpdrive.WarpDrive;
|
||||
|
||||
import java.util.NavigableMap;
|
||||
import java.util.Random;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.util.AxisAlignedBB;
|
||||
|
||||
/**
|
||||
* Celestial objects are area in space. They can be a planet or solar system (space dimension) or the all mighty hyperspace.
|
||||
*
|
||||
* @author LemADEC
|
||||
*/
|
||||
public class CelestialObject implements Cloneable {
|
||||
public int dimensionId;
|
||||
public int dimensionCenterX, dimensionCenterZ;
|
||||
public int borderRadiusX, borderRadiusZ;
|
||||
public int parentDimensionId;
|
||||
public int parentCenterX, parentCenterZ;
|
||||
public boolean isWarpDrive;
|
||||
public double gravity;
|
||||
public boolean isBreathable;
|
||||
|
||||
// @TODO replace with RandomCollection once we switch to XML
|
||||
private final NavigableMap<Double, String> mapGenerationRatios = new TreeMap<>();
|
||||
private double totalRatio;
|
||||
|
||||
public CelestialObject() {
|
||||
this(0, 0, 0, 5000, 5000, -2, 0, 0);
|
||||
}
|
||||
|
||||
public CelestialObject(final int parDimensionId, final int parDimensionCenterX, final int parDimensionCenterZ,
|
||||
final int parBorderRadiusX, final int parBorderRadiusZ,
|
||||
final int parParentDimensionId, final int parParentCenterX, final int parParentCenterZ) {
|
||||
dimensionId = parDimensionId;
|
||||
dimensionCenterX = parDimensionCenterX;
|
||||
dimensionCenterZ = parDimensionCenterZ;
|
||||
borderRadiusX = parBorderRadiusX;
|
||||
borderRadiusZ = parBorderRadiusZ;
|
||||
parentDimensionId = parParentDimensionId;
|
||||
parentCenterX = parParentCenterX;
|
||||
parentCenterZ = parParentCenterZ;
|
||||
}
|
||||
|
||||
public CelestialObject(NBTTagCompound nbt) {
|
||||
readFromNBT(nbt);
|
||||
}
|
||||
|
||||
@SuppressWarnings("CloneDoesntCallSuperClone")
|
||||
@Override
|
||||
public CelestialObject clone() {
|
||||
return new CelestialObject(dimensionId, dimensionCenterX, dimensionCenterZ, borderRadiusX, borderRadiusZ, parentDimensionId, parentCenterX, parentCenterZ);
|
||||
}
|
||||
|
||||
public void setSelfProvider(final boolean isWarpDrive) {
|
||||
this.isWarpDrive = isWarpDrive;
|
||||
}
|
||||
|
||||
public void setGravity(final double gravity) {
|
||||
this.gravity = gravity;
|
||||
}
|
||||
|
||||
public void setBreathable(final boolean isBreathable) {
|
||||
this.isBreathable = isBreathable;
|
||||
}
|
||||
|
||||
public void addGenerationRatio(final double ratio, final String name) {
|
||||
if (ratio <= 0 || ratio >= 1.0) {
|
||||
WarpDrive.logger.warn("Ratio isn't in ]0, 1.0] bounds, skipping " + name + " with ratio " + ratio);
|
||||
return;
|
||||
}
|
||||
if (mapGenerationRatios.containsValue(name)) {
|
||||
WarpDrive.logger.warn("Object already has a ratio defined, skipping " + name + " with ratio " + ratio);
|
||||
return;
|
||||
}
|
||||
|
||||
if (totalRatio + ratio > 1.0) {
|
||||
WarpDrive.logger.warn("Total ratio is greater than 1.0, skipping " + name + " with ratio " + ratio);
|
||||
return;
|
||||
}
|
||||
totalRatio += ratio;
|
||||
mapGenerationRatios.put(totalRatio, name);
|
||||
}
|
||||
|
||||
public String getRandomGeneration(Random random) {
|
||||
double value = random.nextDouble();
|
||||
|
||||
if (value >= totalRatio) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return mapGenerationRatios.ceilingEntry(value).getValue();
|
||||
}
|
||||
|
||||
public AxisAlignedBB getWorldBorderArea() {
|
||||
return AxisAlignedBB.getBoundingBox(
|
||||
(dimensionCenterX - borderRadiusX), 0, (dimensionCenterZ - borderRadiusZ),
|
||||
(dimensionCenterX + borderRadiusX), 255, (dimensionCenterZ + borderRadiusZ) );
|
||||
}
|
||||
|
||||
public AxisAlignedBB getAreaToReachParent() {
|
||||
return AxisAlignedBB.getBoundingBox(
|
||||
(dimensionCenterX - borderRadiusX), 250, (dimensionCenterZ - borderRadiusZ),
|
||||
(dimensionCenterX + borderRadiusX), 255, (dimensionCenterZ + borderRadiusZ) );
|
||||
}
|
||||
|
||||
public AxisAlignedBB getAreaInParent() {
|
||||
return AxisAlignedBB.getBoundingBox(
|
||||
(parentCenterX - borderRadiusX), 0, (parentCenterZ - borderRadiusZ),
|
||||
(parentCenterX + borderRadiusX), 8, (parentCenterZ + borderRadiusZ) );
|
||||
}
|
||||
|
||||
// offset vector when moving from parent to this dimension
|
||||
public VectorI getEntryOffset() {
|
||||
return new VectorI(dimensionCenterX - parentCenterX, 0, dimensionCenterZ - parentCenterZ);
|
||||
}
|
||||
|
||||
public boolean isSpace() {
|
||||
if (isHyperspace()) {
|
||||
return false;
|
||||
}
|
||||
CelestialObject celestialObjectParent = StarMapRegistry.getCelestialObject(parentDimensionId, parentCenterX, parentCenterZ);
|
||||
return celestialObjectParent != null && celestialObjectParent.isHyperspace();
|
||||
}
|
||||
|
||||
public boolean isHyperspace() {
|
||||
return parentDimensionId == dimensionId;
|
||||
}
|
||||
|
||||
public boolean hasAtmosphere() {
|
||||
return isBreathable && !isHyperspace() && !isSpace();
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute distance from border to further point in an area.
|
||||
* It's up to caller to verify if this celestial object is matched.
|
||||
*
|
||||
* @param aabb bounding box that should fit within border
|
||||
* @return distance to transition borders, 0 if take off is possible
|
||||
*/
|
||||
public double getSquareDistanceOutsideBorder(final int dimensionId, final AxisAlignedBB aabb) {
|
||||
if (dimensionId != this.dimensionId) {
|
||||
return Double.POSITIVE_INFINITY;
|
||||
}
|
||||
final double rangeX = Math.max(Math.abs(aabb.minX - dimensionCenterX), Math.abs(aabb.maxX - dimensionCenterX));
|
||||
final double rangeZ = Math.max(Math.abs(aabb.minZ - dimensionCenterZ), Math.abs(aabb.maxZ - dimensionCenterZ));
|
||||
final double dX = rangeX - borderRadiusX;
|
||||
final double dZ = rangeZ - borderRadiusZ;
|
||||
if ((rangeX <= borderRadiusX) && (rangeZ <= borderRadiusZ)) {
|
||||
return - (dX * dX + dZ * dZ);
|
||||
}
|
||||
return (dX * dX + dZ * dZ);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute distance to reach closest border, while inside the same dimension.
|
||||
*
|
||||
* @param dimensionId dimension id
|
||||
* @param x coordinates inside the celestial object
|
||||
* @param z coordinates inside the celestial object
|
||||
* @return 'square' distance to the closest border,
|
||||
* <=0 if we're inside, > 0 if we're outside,
|
||||
* +INF if we're in the wrong dimension
|
||||
*/
|
||||
public double getSquareDistanceOutsideBorder(final int dimensionId, final double x, final double z) {
|
||||
if (dimensionId != this.dimensionId) {
|
||||
return Double.POSITIVE_INFINITY;
|
||||
}
|
||||
final double rangeX = Math.abs(x - dimensionCenterX);
|
||||
final double rangeZ = Math.abs(z - dimensionCenterZ);
|
||||
final double dX = rangeX - borderRadiusX;
|
||||
final double dZ = rangeZ - borderRadiusZ;
|
||||
if ( (rangeX <= borderRadiusX)
|
||||
&& (rangeZ <= borderRadiusZ) ) {
|
||||
// inside: both dX and dZ are negative, so the max is actually the closest to zero
|
||||
final double dMax = Math.max(dX, dZ);
|
||||
return - (dMax * dMax);
|
||||
} else if ( (rangeX > borderRadiusX)
|
||||
&& (rangeZ > borderRadiusZ) ) {
|
||||
// outside in a diagonal
|
||||
return (dX * dX + dZ * dZ);
|
||||
}
|
||||
// outside aligned: one is negative (inside), the other is positive (outside), so the max is the outside one
|
||||
final double dMax = Math.max(dX, dZ);
|
||||
return dMax * dMax;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if current space coordinates allow to enter this dimension atmosphere from space.
|
||||
*
|
||||
* @param dimensionId current position in parent dimension
|
||||
* @param x current position in parent dimension
|
||||
* @param z current position in parent dimension
|
||||
* @return square distance to transition borders, 0 if we're in orbit of the object
|
||||
*/
|
||||
public double getSquareDistanceInParent(final int dimensionId, final double x, final double z) {
|
||||
if (dimensionId != parentDimensionId) {
|
||||
return Double.POSITIVE_INFINITY;
|
||||
}
|
||||
if ( (Math.abs(x - parentCenterX) <= borderRadiusX)
|
||||
&& (Math.abs(z - parentCenterZ) <= borderRadiusZ) ) {
|
||||
return 0.0D;
|
||||
}
|
||||
final double dx = Math.max(0.0D, Math.abs(x - parentCenterX) - borderRadiusX);
|
||||
final double dz = Math.max(0.0D, Math.abs(z - parentCenterZ) - borderRadiusZ);
|
||||
return dx * dx + dz * dz;
|
||||
}
|
||||
|
||||
public void readFromNBT(NBTTagCompound tag) {
|
||||
dimensionId = tag.getInteger("dimensionId");
|
||||
dimensionCenterX = tag.getInteger("dimensionCenterX");
|
||||
dimensionCenterZ = tag.getInteger("dimensionCenterZ");
|
||||
borderRadiusX = tag.getInteger("borderSizeX");
|
||||
borderRadiusZ = tag.getInteger("borderSizeZ");
|
||||
parentDimensionId = tag.getInteger("parentDimensionId");
|
||||
parentCenterX = tag.getInteger("parentCenterX");
|
||||
parentCenterZ = tag.getInteger("parentCenterZ");
|
||||
isWarpDrive = tag.getBoolean("isWarpDrive");
|
||||
gravity = tag.getDouble("gravity");
|
||||
isBreathable = tag.getBoolean("isBreathable");
|
||||
// @TODO: mapGenerationRatios
|
||||
}
|
||||
|
||||
public void writeToNBT(NBTTagCompound tag) {
|
||||
tag.setInteger("dimensionId", dimensionId);
|
||||
tag.setInteger("dimensionCenterX", dimensionCenterX);
|
||||
tag.setInteger("dimensionCenterZ", dimensionCenterZ);
|
||||
tag.setInteger("borderRadiusX", borderRadiusX);
|
||||
tag.setInteger("borderRadiusZ", borderRadiusZ);
|
||||
tag.setInteger("parentDimensionId", parentDimensionId);
|
||||
tag.setInteger("parentCenterX", parentCenterX);
|
||||
tag.setInteger("parentCenterZ", parentCenterZ);
|
||||
tag.setBoolean("isWarpDrive", isWarpDrive);
|
||||
tag.setDouble("gravity", gravity);
|
||||
tag.setBoolean("isBreathable", isBreathable);
|
||||
// @TODO: mapGenerationRatios
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return dimensionId << 16 + (dimensionCenterX >> 10) << 8 + (dimensionCenterZ >> 10);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
if (object instanceof CelestialObject) {
|
||||
CelestialObject celestialObject = (CelestialObject) object;
|
||||
return dimensionId == celestialObject.dimensionId
|
||||
&& dimensionCenterX == celestialObject.dimensionCenterX
|
||||
&& dimensionCenterZ == celestialObject.dimensionCenterZ
|
||||
&& borderRadiusX == celestialObject.borderRadiusX
|
||||
&& borderRadiusZ == celestialObject.borderRadiusZ
|
||||
&& parentDimensionId == celestialObject.parentDimensionId
|
||||
&& parentCenterX == celestialObject.parentCenterX
|
||||
&& parentCenterZ == celestialObject.parentCenterZ;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CelestialObject [Dimension " + dimensionId + " @ (" + dimensionCenterX + " " + dimensionCenterZ + ")"
|
||||
+ " Border(" + borderRadiusX + " " + borderRadiusZ + ")"
|
||||
+ " Parent(" + parentDimensionId + " @ (" + parentCenterX + " " + parentCenterZ + "))]"
|
||||
+ " isWarpDrive + " + isWarpDrive + " gravity " + gravity + " isBreathable " + isBreathable;
|
||||
}
|
||||
}
|
|
@ -1,8 +1,5 @@
|
|||
package cr0s.warpdrive.data;
|
||||
|
||||
import cr0s.warpdrive.WarpDrive;
|
||||
import cr0s.warpdrive.config.WarpDriveConfig;
|
||||
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.world.ChunkCoordIntPair;
|
||||
import net.minecraft.world.WorldServer;
|
||||
|
@ -55,24 +52,19 @@ public class GlobalPosition {
|
|||
}
|
||||
|
||||
public VectorI getSpaceCoordinates() {
|
||||
if (WarpDrive.starMap.isInSpace(dimensionId)) {
|
||||
return new VectorI(x, y + 256, z);
|
||||
CelestialObject celestialObject = StarMapRegistry.getCelestialObject(dimensionId, x, z);
|
||||
if (celestialObject == null) {
|
||||
// not a registered area
|
||||
return null;
|
||||
}
|
||||
if (WarpDrive.starMap.isInHyperspace(dimensionId)) {
|
||||
if (celestialObject.isHyperspace()) {
|
||||
return new VectorI(x, y + 512, z);
|
||||
}
|
||||
for (Planet planet : WarpDriveConfig.PLANETS) {
|
||||
if (planet.dimensionId == dimensionId) {
|
||||
if ( (Math.abs(x - planet.dimensionCenterX) <= planet.borderSizeX)
|
||||
&& (Math.abs(z - planet.dimensionCenterZ) <= planet.borderSizeZ)) {
|
||||
return new VectorI(
|
||||
x - planet.dimensionCenterX + planet.spaceCenterX,
|
||||
y,
|
||||
z - planet.dimensionCenterZ + planet.spaceCenterZ);
|
||||
}
|
||||
}
|
||||
if (celestialObject.isSpace()) {
|
||||
return new VectorI(x, y + 256, z);
|
||||
}
|
||||
return null;
|
||||
VectorI vEntry = celestialObject.getEntryOffset();
|
||||
return new VectorI(x - vEntry.x, y, z - vEntry.z);
|
||||
}
|
||||
|
||||
public boolean equals(final TileEntity tileEntity) {
|
||||
|
|
|
@ -1,140 +0,0 @@
|
|||
package cr0s.warpdrive.data;
|
||||
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.util.AxisAlignedBB;
|
||||
|
||||
/**
|
||||
* Transition planes between dimensions to land on a planet or take off from it to reach space.
|
||||
*
|
||||
* @author LemADEC
|
||||
*/
|
||||
public class Planet implements Cloneable {
|
||||
public int dimensionId;
|
||||
public int dimensionCenterX, dimensionCenterZ;
|
||||
public int borderSizeX, borderSizeZ;
|
||||
public int spaceCenterX, spaceCenterZ;
|
||||
|
||||
public Planet() {
|
||||
this(0, 0, 0, 5000, 5000, 0, 0);
|
||||
}
|
||||
|
||||
public Planet(int parDimensionId, int parDimensionCenterX, int parDimensionCenterZ, int parBorderSizeX, int parBorderSizeZ, int parSpaceCenterX, int parSpaceCenterZ) {
|
||||
dimensionId = parDimensionId;
|
||||
spaceCenterX = parSpaceCenterX;
|
||||
spaceCenterZ = parSpaceCenterZ;
|
||||
dimensionCenterX = parDimensionCenterX;
|
||||
dimensionCenterZ = parDimensionCenterZ;
|
||||
borderSizeX = parBorderSizeX;
|
||||
borderSizeZ = parBorderSizeZ;
|
||||
}
|
||||
|
||||
public Planet(NBTTagCompound nbt) {
|
||||
readFromNBT(nbt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a new copy of this TransitionPlane. Prevents variable referencing problems.
|
||||
*/
|
||||
@SuppressWarnings("CloneDoesntCallSuperClone")
|
||||
@Override
|
||||
public Planet clone() {
|
||||
return new Planet(dimensionId, dimensionCenterX, dimensionCenterZ, borderSizeX, borderSizeZ, spaceCenterX, spaceCenterZ);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if given bounding box is inside borders. It's up to caller to verify if this transition plane match current dimension.
|
||||
*
|
||||
* @param aabb bounding box that should fit within border
|
||||
* @return distance to transition borders, 0 if take off is possible
|
||||
*/
|
||||
public int isInsideBorder(AxisAlignedBB aabb) {
|
||||
double rangeX = Math.max(Math.abs(aabb.minX - dimensionCenterX), Math.abs(aabb.maxX - dimensionCenterX));
|
||||
double rangeZ = Math.max(Math.abs(aabb.minZ - dimensionCenterZ), Math.abs(aabb.maxZ - dimensionCenterZ));
|
||||
if ((rangeX <= borderSizeX) && (rangeZ <= borderSizeZ)) {
|
||||
return 0;
|
||||
}
|
||||
return (int) Math.sqrt(
|
||||
Math.pow(Math.max(0D, rangeX - borderSizeX), 2.0D)
|
||||
+ Math.pow(Math.max(0D, rangeZ - borderSizeZ), 2.0D));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if current coordinates allow to take off from this dimension to reach space. It's up to caller to verify if this transition plane match current dimension.
|
||||
*
|
||||
* @param currentPosition current position in the planet/dimension
|
||||
* @return distance to transition borders, 0 if take off is possible
|
||||
*/
|
||||
public int isValidToSpace(VectorI currentPosition) {
|
||||
if ((Math.abs(currentPosition.x - dimensionCenterX) <= borderSizeX) && (Math.abs(currentPosition.z - dimensionCenterZ) <= borderSizeZ)) {
|
||||
return 0;
|
||||
}
|
||||
return (int) Math.sqrt(
|
||||
Math.pow(Math.max(0D, Math.abs(currentPosition.x - dimensionCenterX) - borderSizeX), 2.0D)
|
||||
+ Math.pow(Math.max(0D, Math.abs(currentPosition.z - dimensionCenterZ) - borderSizeZ), 2.0D));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if current space coordinates allow to enter this dimension atmosphere from space. It's up to caller to verify if we're actually in space.
|
||||
*
|
||||
* @param currentPosition current position in space
|
||||
* @return distance to transition borders, 0 if entry is possible
|
||||
*/
|
||||
public int isValidFromSpace(final VectorI currentPosition) {
|
||||
return isValidFromSpace(currentPosition.x, currentPosition.z);
|
||||
}
|
||||
public int isValidFromSpace(final int x, final int z) {
|
||||
if ((Math.abs(x - spaceCenterX) <= borderSizeX) && (Math.abs(z - spaceCenterZ) <= borderSizeZ)) {
|
||||
return 0;
|
||||
}
|
||||
return (int) Math.sqrt( Math.pow(Math.max(0D, Math.abs(x - spaceCenterX) - borderSizeX), 2.0D)
|
||||
+ Math.pow(Math.max(0D, Math.abs(z - spaceCenterZ) - borderSizeZ), 2.0D));
|
||||
}
|
||||
|
||||
public void readFromNBT(NBTTagCompound tag) {
|
||||
dimensionId = tag.getInteger("dimensionId");
|
||||
dimensionCenterX = tag.getInteger("dimensionCenterX");
|
||||
dimensionCenterZ = tag.getInteger("dimensionCenterZ");
|
||||
borderSizeX = tag.getInteger("borderSizeX");
|
||||
borderSizeZ = tag.getInteger("borderSizeZ");
|
||||
spaceCenterX = tag.getInteger("spaceCenterX");
|
||||
spaceCenterZ = tag.getInteger("spaceCenterZ");
|
||||
}
|
||||
|
||||
public void writeToNBT(NBTTagCompound tag) {
|
||||
tag.setInteger("dimensionId", dimensionId);
|
||||
tag.setInteger("dimensionCenterX", dimensionCenterX);
|
||||
tag.setInteger("dimensionCenterZ", dimensionCenterZ);
|
||||
tag.setInteger("borderSizeX", borderSizeX);
|
||||
tag.setInteger("borderSizeZ", borderSizeZ);
|
||||
tag.setInteger("spaceCenterX", spaceCenterX);
|
||||
tag.setInteger("spaceCenterZ", spaceCenterZ);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return dimensionId << 16 + (dimensionCenterX >> 10) << 8 + (dimensionCenterZ >> 10);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
if (object instanceof Planet) {
|
||||
Planet planet = (Planet) object;
|
||||
return dimensionId == planet.dimensionId
|
||||
&& dimensionCenterX == planet.dimensionCenterX
|
||||
&& dimensionCenterZ == planet.dimensionCenterZ
|
||||
&& borderSizeX == planet.borderSizeX
|
||||
&& borderSizeZ == planet.borderSizeZ
|
||||
&& spaceCenterX == planet.spaceCenterX
|
||||
&& spaceCenterZ == planet.spaceCenterZ;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Planet [Dimension " + dimensionId + "(" + dimensionCenterX + ", " + dimensionCenterZ + ")"
|
||||
+ " Border(" + borderSizeX + ", " + borderSizeZ + ")"
|
||||
+ " Space(" + spaceCenterX + ", " + spaceCenterZ + ")]";
|
||||
}
|
||||
}
|
|
@ -15,6 +15,7 @@ import java.util.Set;
|
|||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.AxisAlignedBB;
|
||||
import net.minecraft.world.ChunkCoordIntPair;
|
||||
|
@ -105,8 +106,126 @@ public class StarMapRegistry {
|
|||
}
|
||||
}
|
||||
|
||||
public static CelestialObject getCelestialObject(World world, final int x, final int z) {
|
||||
return getCelestialObject(world.provider.dimensionId, x, z);
|
||||
}
|
||||
|
||||
public static CelestialObject getCelestialObject(final int dimensionId, final int x, final int z) {
|
||||
double distanceClosest = Double.POSITIVE_INFINITY;
|
||||
CelestialObject celestialObjectClosest = null;
|
||||
for (CelestialObject celestialObject : WarpDriveConfig.celestialObjects) {
|
||||
if (dimensionId == celestialObject.dimensionId) {
|
||||
final double distanceSquared = celestialObject.getSquareDistanceOutsideBorder(dimensionId, x, z);
|
||||
if (distanceSquared <= 0) {
|
||||
return celestialObject;
|
||||
} else if (distanceClosest > distanceSquared) {
|
||||
distanceClosest = distanceSquared;
|
||||
celestialObjectClosest = celestialObject;
|
||||
}
|
||||
}
|
||||
}
|
||||
return celestialObjectClosest;
|
||||
}
|
||||
|
||||
public static double getGravity(final Entity entity) {
|
||||
final CelestialObject celestialObject = getCelestialObject(entity.worldObj, (int) entity.posX, (int) entity.posZ);
|
||||
return celestialObject == null ? 1.0D : celestialObject.gravity;
|
||||
}
|
||||
|
||||
public static CelestialObject getClosestParentCelestialObject(final int dimensionId, final int x, final int z) {
|
||||
double closestPlanetDistance = Double.POSITIVE_INFINITY;
|
||||
CelestialObject celestialObjectClosest = null;
|
||||
for (CelestialObject celestialObject : WarpDriveConfig.celestialObjects) {
|
||||
final double distanceSquared = celestialObject.getSquareDistanceOutsideBorder(dimensionId, x, z);
|
||||
if (distanceSquared <= 0) {
|
||||
return celestialObject;
|
||||
} else if (closestPlanetDistance > distanceSquared) {
|
||||
closestPlanetDistance = distanceSquared;
|
||||
celestialObjectClosest = celestialObject;
|
||||
}
|
||||
}
|
||||
return celestialObjectClosest;
|
||||
}
|
||||
|
||||
public static CelestialObject getClosestChildCelestialObject(final int dimensionId, final int x, final int z) {
|
||||
double closestPlanetDistance = Double.POSITIVE_INFINITY;
|
||||
CelestialObject celestialObjectClosest = null;
|
||||
for (CelestialObject celestialObject : WarpDriveConfig.celestialObjects) {
|
||||
final double distanceSquared = celestialObject.getSquareDistanceInParent(dimensionId, x, z);
|
||||
if (distanceSquared <= 0.0D) {
|
||||
return celestialObject;
|
||||
} else if (closestPlanetDistance > distanceSquared) {
|
||||
closestPlanetDistance = distanceSquared;
|
||||
celestialObjectClosest = celestialObject;
|
||||
}
|
||||
}
|
||||
return celestialObjectClosest;
|
||||
}
|
||||
|
||||
public static int getSpaceDimensionId(World world, final int x, final int z) {
|
||||
CelestialObject celestialObject = getCelestialObject(world, x, z);
|
||||
// already in space?
|
||||
if (celestialObject.isSpace()) {
|
||||
return celestialObject.dimensionId;
|
||||
}
|
||||
// coming from hyperspace?
|
||||
if (celestialObject.isHyperspace()) {
|
||||
celestialObject = getClosestChildCelestialObject(world.provider.dimensionId, x, z);
|
||||
return celestialObject == null ? 0 : celestialObject.dimensionId;
|
||||
}
|
||||
// coming from a planet?
|
||||
celestialObject = getClosestParentCelestialObject(world.provider.dimensionId, x, z);
|
||||
return celestialObject == null ? 0 : (celestialObject.isSpace() ? celestialObject.dimensionId : celestialObject.parentDimensionId);
|
||||
}
|
||||
|
||||
public static int getHyperspaceDimensionId(World world, final int x, final int z) {
|
||||
CelestialObject celestialObject = getCelestialObject(world, x, z);
|
||||
// already in hyperspace?
|
||||
if (celestialObject.isHyperspace()) {
|
||||
return celestialObject.dimensionId;
|
||||
}
|
||||
// coming from space?
|
||||
if (celestialObject.isSpace()) {
|
||||
return celestialObject.parentDimensionId;
|
||||
}
|
||||
// coming from a planet?
|
||||
celestialObject = getClosestParentCelestialObject(world.provider.dimensionId, x, z);
|
||||
if (celestialObject != null && !celestialObject.isHyperspace()) {
|
||||
celestialObject = getClosestParentCelestialObject(world.provider.dimensionId, x, z);
|
||||
}
|
||||
return celestialObject == null ? 0 : celestialObject.parentDimensionId;
|
||||
}
|
||||
|
||||
public static int getDimensionId(final String stringDimension, Entity entity) {
|
||||
switch (stringDimension.toLowerCase()) {
|
||||
case "world":
|
||||
case "overworld":
|
||||
case "0":
|
||||
return 0;
|
||||
case "nether":
|
||||
case "thenether":
|
||||
case "-1":
|
||||
return -1;
|
||||
case "s":
|
||||
case "space":
|
||||
return getSpaceDimensionId(entity.worldObj, (int) entity.posX, (int) entity.posZ);
|
||||
case "h":
|
||||
case "hyper":
|
||||
case "hyperspace":
|
||||
return getHyperspaceDimensionId(entity.worldObj, (int) entity.posX, (int) entity.posZ);
|
||||
default:
|
||||
try {
|
||||
return Integer.parseInt(stringDimension);
|
||||
} catch(Exception exception) {
|
||||
// exception.printStackTrace();
|
||||
WarpDrive.logger.info("Invalid dimension '" + stringDimension + "', expecting integer or overworld/nether/end/theend/space/hyper/hyperspace");
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public ArrayList<StarMapRegistryItem> radarScan(TileEntity tileEntity, final int radius) {
|
||||
ArrayList<StarMapRegistryItem> res = new ArrayList<>(registry.size());
|
||||
ArrayList<StarMapRegistryItem> starMapRegistryItems = new ArrayList<>(registry.size());
|
||||
cleanup();
|
||||
|
||||
// printRegistry();
|
||||
|
@ -121,40 +240,33 @@ public class StarMapRegistry {
|
|||
if (distance2 <= radius2
|
||||
&& (entry.isolationRate == 0.0D || tileEntity.getWorldObj().rand.nextDouble() >= entry.isolationRate)
|
||||
&& (entry.getSpaceCoordinates() != null)) {
|
||||
res.add(entry);
|
||||
starMapRegistryItems.add(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
return starMapRegistryItems;
|
||||
}
|
||||
|
||||
public boolean isInSpace(final int dimensionId) {
|
||||
return dimensionId == WarpDriveConfig.G_SPACE_DIMENSION_ID;
|
||||
public boolean isInSpace(final World world, final int x, final int z) {
|
||||
CelestialObject celestialObject = getCelestialObject(world.provider.dimensionId, x, z);
|
||||
return celestialObject != null && celestialObject.isSpace();
|
||||
}
|
||||
|
||||
public boolean isInHyperspace(final int dimensionId) {
|
||||
return dimensionId == WarpDriveConfig.G_HYPERSPACE_DIMENSION_ID;
|
||||
public boolean isInHyperspace(final World world, final int x, final int z) {
|
||||
CelestialObject celestialObject = getCelestialObject(world.provider.dimensionId, x, z);
|
||||
return celestialObject != null && celestialObject.isHyperspace();
|
||||
}
|
||||
|
||||
public boolean isInSpace(final World world) {
|
||||
return isInSpace(world.provider.dimensionId);
|
||||
public boolean hasAtmosphere(final World world, final int x, final int z) {
|
||||
CelestialObject celestialObject = getCelestialObject(world, x, z);
|
||||
return celestialObject == null || celestialObject.hasAtmosphere();
|
||||
}
|
||||
|
||||
public boolean isInHyperspace(final World world) {
|
||||
return isInHyperspace(world.provider.dimensionId);
|
||||
}
|
||||
|
||||
public boolean hasAtmosphere(final World world) {
|
||||
return !isInSpace(world) && !isInHyperspace(world);
|
||||
}
|
||||
|
||||
public boolean isPlanet(final World world) {
|
||||
return !isInSpace(world) && !isInHyperspace(world);
|
||||
}
|
||||
|
||||
public boolean isLowGravity(final World world) {
|
||||
return isInSpace(world) || isInHyperspace(world);
|
||||
public boolean isPlanet(final World world, final int x, final int z) {
|
||||
CelestialObject celestialObject = getCelestialObject(world, x, z);
|
||||
return celestialObject == null
|
||||
|| (!celestialObject.isSpace() && !celestialObject.isHyperspace());
|
||||
}
|
||||
|
||||
public void printRegistry(final String trigger) {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package cr0s.warpdrive.event;
|
||||
|
||||
import cr0s.warpdrive.CommonProxy;
|
||||
import cr0s.warpdrive.LocalProfiler;
|
||||
import cr0s.warpdrive.WarpDrive;
|
||||
import cr0s.warpdrive.api.IBlockTransformer;
|
||||
|
@ -7,10 +8,11 @@ import cr0s.warpdrive.api.ITransformation;
|
|||
import cr0s.warpdrive.block.movement.TileEntityShipCore;
|
||||
import cr0s.warpdrive.config.Dictionary;
|
||||
import cr0s.warpdrive.config.WarpDriveConfig;
|
||||
import cr0s.warpdrive.data.CelestialObject;
|
||||
import cr0s.warpdrive.data.JumpBlock;
|
||||
import cr0s.warpdrive.data.JumpShip;
|
||||
import cr0s.warpdrive.data.MovingEntity;
|
||||
import cr0s.warpdrive.data.Planet;
|
||||
import cr0s.warpdrive.data.StarMapRegistry;
|
||||
import cr0s.warpdrive.data.Transformation;
|
||||
import cr0s.warpdrive.data.Vector3;
|
||||
import cr0s.warpdrive.data.VectorI;
|
||||
|
@ -274,7 +276,7 @@ public class JumpSequencer extends AbstractSequencer {
|
|||
}
|
||||
sourceWorldTicket = ForgeChunkManager.requestTicket(WarpDrive.instance, sourceWorld, Type.NORMAL);
|
||||
if (sourceWorldTicket == null) {
|
||||
reason.append("Chunkloading rejected in source world " + sourceWorld.getWorldInfo().getWorldName() + ". Aborting.");
|
||||
reason.append(String.format("Chunkloading rejected in source world %s. Aborting.", sourceWorld.getWorldInfo().getWorldName()));
|
||||
return false;
|
||||
}
|
||||
int x1 = ship.minX >> 4;
|
||||
|
@ -286,7 +288,8 @@ public class JumpSequencer extends AbstractSequencer {
|
|||
for (int z = z1; z <= z2; z++) {
|
||||
chunkCount++;
|
||||
if (chunkCount > sourceWorldTicket.getMaxChunkListDepth()) {
|
||||
reason.append("Ship is extending over too many chunks in source world. Max is currently set to " + sourceWorldTicket.getMaxChunkListDepth() + " in forgeChunkLoading.cfg. Aborting.");
|
||||
reason.append(String.format("Ship is extending over too many chunks in source world. Max is currently set to %d in forgeChunkLoading.cfg. Aborting.",
|
||||
sourceWorldTicket.getMaxChunkListDepth()));
|
||||
return false;
|
||||
}
|
||||
ForgeChunkManager.forceChunk(sourceWorldTicket, new ChunkCoordIntPair(x, z));
|
||||
|
@ -302,7 +305,8 @@ public class JumpSequencer extends AbstractSequencer {
|
|||
}
|
||||
targetWorldTicket = ForgeChunkManager.requestTicket(WarpDrive.instance, targetWorld, Type.NORMAL);
|
||||
if (targetWorldTicket == null) {
|
||||
reason.append("Chunkloading rejected in target world " + sourceWorld.getWorldInfo().getWorldName() + ". Aborting.");
|
||||
reason.append(String.format("Chunkloading rejected in target world %s. Aborting.",
|
||||
sourceWorld.getWorldInfo().getWorldName()));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -317,7 +321,8 @@ public class JumpSequencer extends AbstractSequencer {
|
|||
for (int z = z1; z <= z2; z++) {
|
||||
chunkCount++;
|
||||
if (chunkCount > targetWorldTicket.getMaxChunkListDepth()) {
|
||||
reason.append("Ship is extending over too many chunks in target world. Max is currently set to " + targetWorldTicket.getMaxChunkListDepth() + " in forgeChunkLoading.cfg. Aborting.");
|
||||
reason.append(String.format("Ship is extending over too many chunks in target world. Max is currently set to %d in forgeChunkLoading.cfg. Aborting.",
|
||||
targetWorldTicket.getMaxChunkListDepth()));
|
||||
return false;
|
||||
}
|
||||
ForgeChunkManager.forceChunk(targetWorldTicket, new ChunkCoordIntPair(x, z));
|
||||
|
@ -451,8 +456,8 @@ public class JumpSequencer extends AbstractSequencer {
|
|||
ship.writeToNBT(tagCompoundShip);
|
||||
schematic.setTag("ship", tagCompoundShip);
|
||||
writeNBTToFile(schematicFileName, schematic);
|
||||
if (WarpDriveConfig.LOGGING_JUMP) {
|
||||
// WarpDrive.logger.info(this + " Ship saved as " + schematicFileName);
|
||||
if (WarpDriveConfig.LOGGING_JUMP && WarpDrive.isDev) {
|
||||
WarpDrive.logger.info(this + " Ship saved as " + schematicFileName);
|
||||
}
|
||||
} catch (Exception exception) {
|
||||
exception.printStackTrace();
|
||||
|
@ -490,142 +495,30 @@ public class JumpSequencer extends AbstractSequencer {
|
|||
|
||||
StringBuilder reason = new StringBuilder();
|
||||
|
||||
boolean isInSpace = WarpDrive.starMap.isInSpace(sourceWorld);
|
||||
boolean isInHyperSpace = WarpDrive.starMap.isInHyperspace(sourceWorld);
|
||||
final CelestialObject celestialObjectSource = StarMapRegistry.getCelestialObject(
|
||||
sourceWorld.provider.dimensionId, ship.coreX, ship.coreZ);
|
||||
final boolean isInSpace = celestialObjectSource.isSpace();
|
||||
final boolean isInHyperSpace = celestialObjectSource.isHyperspace();
|
||||
|
||||
boolean toSpace = (moveY > 0) && (ship.maxY + moveY > 255) && (!isInSpace) && (!isInHyperSpace);
|
||||
boolean fromSpace = (moveY < 0) && (ship.minY + moveY < 0) && isInSpace;
|
||||
final boolean toSpace = (moveY > 0) && (ship.maxY + moveY > 255) && (!isInSpace) && (!isInHyperSpace);
|
||||
final boolean fromSpace = (moveY < 0) && (ship.minY + moveY < 0) && isInSpace;
|
||||
betweenWorlds = fromSpace || toSpace || isHyperspaceJump;
|
||||
|
||||
if (isHyperspaceJump) {
|
||||
if (isInHyperSpace) {
|
||||
final int dimensionIdSpace = WarpDriveConfig.G_SPACE_DIMENSION_ID;
|
||||
targetWorld = MinecraftServer.getServer().worldServerForDimension(dimensionIdSpace);
|
||||
if (targetWorld == null) {
|
||||
LocalProfiler.stop();
|
||||
String msg = "Unable to load Space dimension " + dimensionIdSpace + ", aborting jump.";
|
||||
ship.messageToAllPlayersOnShip(msg);
|
||||
disable(msg);
|
||||
return;
|
||||
}
|
||||
} else if (isInSpace) {
|
||||
final int dimensionIdHyperspace = WarpDriveConfig.G_HYPERSPACE_DIMENSION_ID;
|
||||
targetWorld = MinecraftServer.getServer().worldServerForDimension(dimensionIdHyperspace);
|
||||
if (targetWorld == null) {
|
||||
LocalProfiler.stop();
|
||||
String msg = "Unable to load Hyperspace dimension " + dimensionIdHyperspace + ", aborting jump.";
|
||||
ship.messageToAllPlayersOnShip(msg);
|
||||
disable(msg);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
String msg = "Unable to reach hyperspace from a planet";
|
||||
disable(msg);
|
||||
ship.messageToAllPlayersOnShip(msg);
|
||||
{// compute targetWorld and movement vector (moveX, moveY, moveZ)
|
||||
String message = computeTargetWorld(celestialObjectSource, isInSpace, isInHyperSpace, toSpace, fromSpace);
|
||||
if (message != null) {
|
||||
LocalProfiler.stop();
|
||||
ship.messageToAllPlayersOnShip(message);
|
||||
disable(message);
|
||||
return;
|
||||
}
|
||||
|
||||
} else if (toSpace) {
|
||||
Boolean planetFound = false;
|
||||
Boolean planetValid = false;
|
||||
int closestPlanetDistance = Integer.MAX_VALUE;
|
||||
Planet closestPlanet = null;
|
||||
for (int indexPlanet = 0; (!planetValid) && indexPlanet < WarpDriveConfig.PLANETS.length; indexPlanet++) {
|
||||
Planet planet = WarpDriveConfig.PLANETS[indexPlanet];
|
||||
if (sourceWorld.provider.dimensionId == planet.dimensionId) {
|
||||
planetFound = true;
|
||||
int planetDistance = planet.isValidToSpace(new VectorI(ship.coreX, ship.coreY, ship.coreZ));
|
||||
if (planetDistance == 0) {
|
||||
planetValid = true;
|
||||
moveX = planet.spaceCenterX - planet.dimensionCenterX;
|
||||
moveZ = planet.spaceCenterZ - planet.dimensionCenterZ;
|
||||
final int dimensionIdSpace = WarpDriveConfig.G_SPACE_DIMENSION_ID;
|
||||
targetWorld = MinecraftServer.getServer().worldServerForDimension(dimensionIdSpace);
|
||||
if (targetWorld == null) {
|
||||
LocalProfiler.stop();
|
||||
String msg = "Unable to load Space dimension " + dimensionIdSpace + ", aborting jump.";
|
||||
ship.messageToAllPlayersOnShip(msg);
|
||||
disable(msg);
|
||||
return;
|
||||
}
|
||||
} else if (closestPlanetDistance > planetDistance) {
|
||||
closestPlanetDistance = planetDistance;
|
||||
closestPlanet = planet;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!planetFound) {
|
||||
LocalProfiler.stop();
|
||||
String msg = "Unable to reach space!\nThere's no planet defined for current dimension " + sourceWorld.provider.getDimensionName() + " ("
|
||||
+ sourceWorld.provider.dimensionId + ")";
|
||||
ship.messageToAllPlayersOnShip(msg);
|
||||
disable(msg);
|
||||
return;
|
||||
}
|
||||
if (!planetValid) {
|
||||
LocalProfiler.stop();
|
||||
assert(closestPlanet != null);
|
||||
@SuppressWarnings("null") // Eclipse derp, don't remove
|
||||
String msg = "Ship is outside planet border, unable to reach space!\nClosest transition plane is ~" + closestPlanetDistance + " m away ("
|
||||
+ (closestPlanet.dimensionCenterX - closestPlanet.borderSizeX) + " 250 "
|
||||
+ (closestPlanet.dimensionCenterZ - closestPlanet.borderSizeZ) + ") to ("
|
||||
+ (closestPlanet.dimensionCenterX + closestPlanet.borderSizeX) + " 255 "
|
||||
+ (closestPlanet.dimensionCenterZ + closestPlanet.borderSizeZ) + ")";
|
||||
ship.messageToAllPlayersOnShip(msg);
|
||||
disable(msg);
|
||||
return;
|
||||
}
|
||||
|
||||
} else if (fromSpace) {
|
||||
Boolean planetFound = false;
|
||||
int closestPlaneDistance = Integer.MAX_VALUE;
|
||||
Planet closestTransitionPlane = null;
|
||||
for (int indexPlanet = 0; (!planetFound) && indexPlanet < WarpDriveConfig.PLANETS.length; indexPlanet++) {
|
||||
Planet planet = WarpDriveConfig.PLANETS[indexPlanet];
|
||||
int planeDistance = planet.isValidFromSpace(new VectorI(ship.coreX, ship.coreY, ship.coreZ));
|
||||
if (planeDistance == 0) {
|
||||
planetFound = true;
|
||||
moveX = planet.dimensionCenterX - planet.spaceCenterX;
|
||||
moveZ = planet.dimensionCenterZ - planet.spaceCenterZ;
|
||||
targetWorld = MinecraftServer.getServer().worldServerForDimension(planet.dimensionId);
|
||||
if (targetWorld == null) {
|
||||
LocalProfiler.stop();
|
||||
String msg = "Undefined dimension " + planet.dimensionId + ", aborting jump. Check your server configuration!";
|
||||
ship.messageToAllPlayersOnShip(msg);
|
||||
disable(msg);
|
||||
return;
|
||||
}
|
||||
} else if (closestPlaneDistance > planeDistance) {
|
||||
closestPlaneDistance = planeDistance;
|
||||
closestTransitionPlane = planet;
|
||||
}
|
||||
}
|
||||
if (!planetFound) {
|
||||
LocalProfiler.stop();
|
||||
String msg;
|
||||
if (closestTransitionPlane == null) {
|
||||
msg = "No planet defined, unable to enter atmosphere!";
|
||||
} else {
|
||||
msg = "No planet in range, unable to enter atmosphere!\nClosest planet is " + closestPlaneDistance + " m away ("
|
||||
+ (closestTransitionPlane.spaceCenterX - closestTransitionPlane.borderSizeX) + " 250 "
|
||||
+ (closestTransitionPlane.spaceCenterZ - closestTransitionPlane.borderSizeZ) + ") to ("
|
||||
+ (closestTransitionPlane.spaceCenterX + closestTransitionPlane.borderSizeX) + " 255 "
|
||||
+ (closestTransitionPlane.spaceCenterZ + closestTransitionPlane.borderSizeZ) + ")";
|
||||
}
|
||||
ship.messageToAllPlayersOnShip(msg);
|
||||
disable(msg);
|
||||
return;
|
||||
}
|
||||
|
||||
} else {
|
||||
targetWorld = sourceWorld;
|
||||
}
|
||||
|
||||
// Check mass constrains
|
||||
if ( WarpDrive.starMap.isPlanet(sourceWorld)
|
||||
|| WarpDrive.starMap.isPlanet(targetWorld) ) {
|
||||
if ( WarpDrive.starMap.isPlanet(sourceWorld, ship.coreX, ship.coreZ)
|
||||
|| WarpDrive.starMap.isPlanet(targetWorld, ship.coreX + moveX, ship.coreZ + moveZ) ) {
|
||||
if (!ship.isUnlimited() && ship.actualMass > WarpDriveConfig.SHIP_VOLUME_MAX_ON_PLANET_SURFACE) {
|
||||
LocalProfiler.stop();
|
||||
String msg = "Ship is too big for a planet (max is " + WarpDriveConfig.SHIP_VOLUME_MAX_ON_PLANET_SURFACE + " blocks)";
|
||||
ship.messageToAllPlayersOnShip(msg);
|
||||
disable(msg);
|
||||
|
@ -698,54 +591,26 @@ public class JumpSequencer extends AbstractSequencer {
|
|||
}
|
||||
|
||||
// Check world border
|
||||
if ( (targetWorld.provider.dimensionId == WarpDriveConfig.G_SPACE_DIMENSION_ID)
|
||||
|| (targetWorld.provider.dimensionId == WarpDriveConfig.G_HYPERSPACE_DIMENSION_ID)) {
|
||||
if (WarpDriveConfig.G_SPACE_WORLDBORDER_BLOCKS > 0) {// Space world border is enabled
|
||||
if ( Math.abs(aabbTarget.minX) > WarpDriveConfig.G_SPACE_WORLDBORDER_BLOCKS
|
||||
|| Math.abs(aabbTarget.minZ) > WarpDriveConfig.G_SPACE_WORLDBORDER_BLOCKS
|
||||
|| Math.abs(aabbTarget.maxX) > WarpDriveConfig.G_SPACE_WORLDBORDER_BLOCKS
|
||||
|| Math.abs(aabbTarget.maxZ) > WarpDriveConfig.G_SPACE_WORLDBORDER_BLOCKS ) {
|
||||
// cancel jump
|
||||
String msg = "Space border reach, max is " + WarpDriveConfig.G_SPACE_WORLDBORDER_BLOCKS;
|
||||
disable(msg);
|
||||
ship.messageToAllPlayersOnShip(msg);
|
||||
LocalProfiler.stop();
|
||||
return;
|
||||
}
|
||||
CelestialObject celestialObjectTarget = StarMapRegistry.getCelestialObject(targetWorld.provider.dimensionId, (int) aabbTarget.minX, (int) aabbTarget.minZ);
|
||||
if (celestialObjectTarget == null) {
|
||||
if (WarpDriveConfig.LOGGING_JUMP) {
|
||||
WarpDrive.logger.error(String.format("There's no world border defined for dimension %s (%d)",
|
||||
targetWorld.provider.getDimensionName(), targetWorld.provider.dimensionId));
|
||||
}
|
||||
|
||||
} else {
|
||||
Boolean planetFound = false;
|
||||
Boolean planetValid = false;
|
||||
int closestPlanetDistance = Integer.MAX_VALUE;
|
||||
Planet closestPlanet = null;
|
||||
for (int indexPlanet = 0; (!planetValid) && indexPlanet < WarpDriveConfig.PLANETS.length; indexPlanet++) {
|
||||
Planet planet = WarpDriveConfig.PLANETS[indexPlanet];
|
||||
if (targetWorld.provider.dimensionId == planet.dimensionId) {
|
||||
planetFound = true;
|
||||
int planetDistance = planet.isInsideBorder(aabbTarget);
|
||||
if (planetDistance == 0) {
|
||||
planetValid = true;
|
||||
} else if (closestPlanetDistance > planetDistance) {
|
||||
closestPlanetDistance = planetDistance;
|
||||
closestPlanet = planet;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!planetFound) {
|
||||
if (WarpDriveConfig.LOGGING_JUMP) {
|
||||
WarpDrive.logger.error("There's no world border defined for dimension " + targetWorld.provider.getDimensionName());
|
||||
}
|
||||
} else if (!planetValid) {
|
||||
// are we in range?
|
||||
final double distanceSquared = celestialObjectTarget.getSquareDistanceOutsideBorder(targetWorld.provider.dimensionId, aabbTarget);
|
||||
if (distanceSquared > 0) {
|
||||
AxisAlignedBB axisAlignedBB = celestialObjectTarget.getWorldBorderArea();
|
||||
String message = String.format(
|
||||
"Target ship position is outside planet border, unable to jump!\n"
|
||||
+ "World borders are (%d %d %d) to (%d %d %d).",
|
||||
(int) axisAlignedBB.minX, (int) axisAlignedBB.minY, (int) axisAlignedBB.minZ,
|
||||
(int) axisAlignedBB.maxX, (int) axisAlignedBB.maxY, (int) axisAlignedBB.maxZ );
|
||||
LocalProfiler.stop();
|
||||
assert (closestPlanet != null);
|
||||
String msg = "Target ship position is outside planet border, unable to jump!\nPlanet borders are ("
|
||||
+ (closestPlanet.dimensionCenterX - closestPlanet.borderSizeX) + " 0 "
|
||||
+ (closestPlanet.dimensionCenterZ - closestPlanet.borderSizeZ) + ") to ("
|
||||
+ (closestPlanet.dimensionCenterX + closestPlanet.borderSizeX) + " 255 "
|
||||
+ (closestPlanet.dimensionCenterZ + closestPlanet.borderSizeZ) + ")";
|
||||
ship.messageToAllPlayersOnShip(msg);
|
||||
disable(msg);
|
||||
ship.messageToAllPlayersOnShip(message);
|
||||
disable(message);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -811,6 +676,120 @@ public class JumpSequencer extends AbstractSequencer {
|
|||
}
|
||||
}
|
||||
|
||||
private String computeTargetWorld(CelestialObject celestialObjectSource, boolean isInSpace, boolean isInHyperSpace, boolean toSpace, boolean fromSpace) {
|
||||
if (isHyperspaceJump) {
|
||||
if (isInHyperSpace) {
|
||||
CelestialObject celestialObject = StarMapRegistry.getClosestChildCelestialObject(sourceWorld.provider.dimensionId, ship.coreX, ship.coreZ);
|
||||
// anything defined?
|
||||
if (celestialObject == null) {
|
||||
return String.format("Unable to reach space from this location!\nThere's no celestial object defined for current dimension %s (%d).",
|
||||
sourceWorld.provider.getDimensionName(), sourceWorld.provider.dimensionId);
|
||||
}
|
||||
|
||||
// are we clear for transit?
|
||||
final double distanceSquared = celestialObject.getSquareDistanceInParent(sourceWorld.provider.dimensionId, ship.coreX, ship.coreZ);
|
||||
if (distanceSquared > 0.0D) {
|
||||
AxisAlignedBB axisAlignedBB = celestialObject.getAreaInParent();
|
||||
return String.format(
|
||||
"Ship is outside any solar system, unable to reach space!\n"
|
||||
+ "Closest transition area is ~%d m away (%d %d %d) to (%d %d %d).",
|
||||
(int) Math.sqrt(distanceSquared),
|
||||
(int) axisAlignedBB.minX, (int) axisAlignedBB.minY, (int) axisAlignedBB.minZ,
|
||||
(int) axisAlignedBB.maxX, (int) axisAlignedBB.maxY, (int) axisAlignedBB.maxZ );
|
||||
}
|
||||
|
||||
// is world available?
|
||||
final int dimensionIdSpace = celestialObject.dimensionId;
|
||||
targetWorld = MinecraftServer.getServer().worldServerForDimension(dimensionIdSpace);
|
||||
if (targetWorld == null) {
|
||||
return String.format("Unable to load Space dimension %d, aborting jump.",
|
||||
dimensionIdSpace);
|
||||
}
|
||||
|
||||
} else if (isInSpace) {
|
||||
// (target world border is checked systematically after movement checks)
|
||||
|
||||
// is world available?
|
||||
final int dimensionIdHyperspace = celestialObjectSource.parentDimensionId;
|
||||
targetWorld = MinecraftServer.getServer().worldServerForDimension(dimensionIdHyperspace);
|
||||
if (targetWorld == null) {
|
||||
return String.format("Unable to load Hyperspace dimension %d, aborting jump.",
|
||||
dimensionIdHyperspace);
|
||||
}
|
||||
|
||||
} else {
|
||||
return "Unable to reach hyperspace from a planet";
|
||||
}
|
||||
|
||||
} else if (toSpace) {
|
||||
CelestialObject celestialObject = StarMapRegistry.getClosestParentCelestialObject(sourceWorld.provider.dimensionId, ship.coreX, ship.coreZ);
|
||||
// anything defined?
|
||||
if (celestialObject == null) {
|
||||
return String.format("Unable to reach space!\nThere's no planet defined for current dimension %s (%d).",
|
||||
sourceWorld.provider.getDimensionName(), sourceWorld.provider.dimensionId);
|
||||
}
|
||||
|
||||
// are we clear for transit?
|
||||
final double distanceSquared = celestialObject.getSquareDistanceOutsideBorder(sourceWorld.provider.dimensionId, ship.coreX, ship.coreZ);
|
||||
if (distanceSquared > 0) {
|
||||
AxisAlignedBB axisAlignedBB = celestialObject.getAreaToReachParent();
|
||||
return String.format(
|
||||
"Ship is outside planet border, unable to reach space!\n"
|
||||
+ "Closest transition area is ~%d m away (%d %d %d) to (%d %d %d).",
|
||||
(int) Math.sqrt(distanceSquared),
|
||||
(int) axisAlignedBB.minX, (int) axisAlignedBB.minY, (int) axisAlignedBB.minZ,
|
||||
(int) axisAlignedBB.maxX, (int) axisAlignedBB.maxY, (int) axisAlignedBB.maxZ );
|
||||
}
|
||||
|
||||
// is world available?
|
||||
final int dimensionIdSpace = celestialObject.parentDimensionId;
|
||||
targetWorld = MinecraftServer.getServer().worldServerForDimension(dimensionIdSpace);
|
||||
if (targetWorld == null) {
|
||||
return "Unable to load Space dimension " + dimensionIdSpace + ", aborting jump.";
|
||||
}
|
||||
|
||||
// update movement vector
|
||||
VectorI vEntry = celestialObject.getEntryOffset();
|
||||
moveX = -vEntry.x;
|
||||
moveZ = -vEntry.z;
|
||||
|
||||
} else if (fromSpace) {
|
||||
CelestialObject celestialObject = StarMapRegistry.getClosestChildCelestialObject(sourceWorld.provider.dimensionId, ship.coreX, ship.coreZ);
|
||||
// anything defined?
|
||||
if (celestialObject == null) {
|
||||
return "No planet exists in this dimension, there's nowhere to land!";
|
||||
}
|
||||
|
||||
// are we in orbit?
|
||||
final double distanceSquared = celestialObject.getSquareDistanceInParent(sourceWorld.provider.dimensionId, ship.coreX, ship.coreZ);
|
||||
if (distanceSquared > 0.0D) {
|
||||
AxisAlignedBB axisAlignedBB = celestialObject.getAreaInParent();
|
||||
return String.format(
|
||||
"No planet in range, unable to enter atmosphere!\n"
|
||||
+ "Closest planet is %d m away (%d %d %d) to (%d %d %d).",
|
||||
(int) Math.sqrt(distanceSquared),
|
||||
(int) axisAlignedBB.minX, (int) axisAlignedBB.minY, (int) axisAlignedBB.minZ,
|
||||
(int) axisAlignedBB.maxX, (int) axisAlignedBB.maxY, (int) axisAlignedBB.maxZ );
|
||||
}
|
||||
|
||||
// validate world availability
|
||||
targetWorld = MinecraftServer.getServer().worldServerForDimension(celestialObject.dimensionId);
|
||||
if (targetWorld == null) {
|
||||
return String.format("Sorry, we can't land here. Dimension %d isn't defined. It might be a decorative planet or a server misconfiguration",
|
||||
celestialObject.dimensionId);
|
||||
}
|
||||
|
||||
// update movement vector
|
||||
VectorI vEntry = celestialObject.getEntryOffset();
|
||||
moveX = vEntry.x;
|
||||
moveZ = vEntry.z;
|
||||
|
||||
} else {
|
||||
targetWorld = sourceWorld;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void state_moveBlocks() {
|
||||
LocalProfiler.start("Jump.moveBlocks");
|
||||
int blocksToMove = Math.min(WarpDriveConfig.G_BLOCKS_PER_TICK, ship.jumpBlocks.length - actualIndexInShip);
|
||||
|
@ -1263,7 +1242,7 @@ public class JumpSequencer extends AbstractSequencer {
|
|||
}
|
||||
}
|
||||
|
||||
if (blockSource != Blocks.air && WarpDrive.proxy.isBlockPlaceCanceled(null, coordCoreAtTarget.posX, coordCoreAtTarget.posY, coordCoreAtTarget.posZ,
|
||||
if (blockSource != Blocks.air && CommonProxy.isBlockPlaceCanceled(null, coordCoreAtTarget.posX, coordCoreAtTarget.posY, coordCoreAtTarget.posZ,
|
||||
targetWorld, coordTarget.posX, coordTarget.posY, coordTarget.posZ, blockSource, 0)) {
|
||||
result.add(x, y, z,
|
||||
coordTarget.posX,
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
package cr0s.warpdrive.event;
|
||||
|
||||
import cr0s.warpdrive.Commons;
|
||||
import cr0s.warpdrive.WarpDrive;
|
||||
import cr0s.warpdrive.api.IAirCanister;
|
||||
import cr0s.warpdrive.api.IBreathingHelmet;
|
||||
import cr0s.warpdrive.config.Dictionary;
|
||||
import cr0s.warpdrive.config.WarpDriveConfig;
|
||||
import cr0s.warpdrive.data.CelestialObject;
|
||||
import cr0s.warpdrive.data.StarMapRegistry;
|
||||
import cr0s.warpdrive.data.VectorI;
|
||||
import cr0s.warpdrive.item.ItemEnergyWrapper;
|
||||
import cr0s.warpdrive.world.SpaceTeleporter;
|
||||
|
@ -23,6 +26,7 @@ import net.minecraft.item.ItemStack;
|
|||
import net.minecraft.util.DamageSource;
|
||||
import net.minecraft.util.MathHelper;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.WorldServer;
|
||||
|
||||
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
|
||||
import net.minecraftforge.common.DimensionManager;
|
||||
|
@ -35,6 +39,12 @@ public class LivingHandler {
|
|||
private final HashMap<String, Integer> player_cloakTicks;
|
||||
|
||||
private static final int CLOAK_CHECK_TIMEOUT_TICKS = 100;
|
||||
|
||||
private static final int BORDER_WARNING_RANGE_BLOCKS_SQUARED = 20 * 20;
|
||||
private static final int BORDER_BYPASS_RANGE_BLOCKS_SQUARED = 32 * 32;
|
||||
private static final int BORDER_BYPASS_PULL_BACK_BLOCKS = 16;
|
||||
private static final int BORDER_BYPASS_DAMAGES_PER_TICK = 9000;
|
||||
|
||||
private static final int AIR_BLOCK_TICKS = 20;
|
||||
private static final int AIR_TANK_TICKS = 300;
|
||||
private static final int AIR_DROWN_TICKS = 20;
|
||||
|
@ -56,21 +66,70 @@ public class LivingHandler {
|
|||
}
|
||||
|
||||
EntityLivingBase entity = event.entityLiving;
|
||||
int x = MathHelper.floor_double(entity.posX);
|
||||
int y = MathHelper.floor_double(entity.posY);
|
||||
int z = MathHelper.floor_double(entity.posZ);
|
||||
final int x = MathHelper.floor_double(entity.posX);
|
||||
final int y = MathHelper.floor_double(entity.posY);
|
||||
final int z = MathHelper.floor_double(entity.posZ);
|
||||
|
||||
// Instant kill if entity exceeds world's limit
|
||||
if (WarpDriveConfig.G_SPACE_WORLDBORDER_BLOCKS > 0
|
||||
&& (Math.abs(x) > WarpDriveConfig.G_SPACE_WORLDBORDER_BLOCKS || Math.abs(z) > WarpDriveConfig.G_SPACE_WORLDBORDER_BLOCKS)) {
|
||||
CelestialObject celestialObject = StarMapRegistry.getCelestialObject(entity.worldObj, x, z);
|
||||
if (celestialObject == null) {
|
||||
// unregistered dimension => exit
|
||||
return;
|
||||
}
|
||||
final double distanceSquared = celestialObject.getSquareDistanceOutsideBorder(entity.worldObj.provider.dimensionId, x, z);
|
||||
if (distanceSquared <= 0.0D) {
|
||||
// are we close to the border?
|
||||
if ( Math.abs(distanceSquared) <= BORDER_WARNING_RANGE_BLOCKS_SQUARED
|
||||
&& entity instanceof EntityPlayer
|
||||
&& entity.ticksExisted % 40 == 0) {
|
||||
Commons.addChatMessage((EntityPlayer) entity,
|
||||
String.format("§cProximity alert: world border is only %d m away!",
|
||||
(int) Math.sqrt(Math.abs(distanceSquared))));
|
||||
}
|
||||
} else {
|
||||
if (entity instanceof EntityPlayerMP) {
|
||||
if (((EntityPlayerMP) entity).capabilities.isCreativeMode) {
|
||||
if (entity.ticksExisted % 100 == 0) {
|
||||
Commons.addChatMessage((EntityPlayer) entity,
|
||||
String.format("§cYou're %d m outside the world border...",
|
||||
(int) Math.sqrt(Math.abs(distanceSquared))));
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
entity.attackEntityFrom(DamageSource.outOfWorld, 9000);
|
||||
return;
|
||||
// pull back the entity
|
||||
final double relativeX = entity.posX - celestialObject.dimensionCenterX;
|
||||
final double relativeZ = entity.posZ - celestialObject.dimensionCenterZ;
|
||||
final double newAbsoluteX = Math.min(Math.abs(relativeX), Math.max(0.0D, celestialObject.borderRadiusX - BORDER_BYPASS_PULL_BACK_BLOCKS));
|
||||
final double newAbsoluteZ = Math.min(Math.abs(relativeZ), Math.max(0.0D, celestialObject.borderRadiusZ - BORDER_BYPASS_PULL_BACK_BLOCKS));
|
||||
final double newEntityX = celestialObject.dimensionCenterX + Math.signum(relativeX) * newAbsoluteX;
|
||||
final double newEntityY = entity.posY + 0.1D;
|
||||
final double newEntityZ = celestialObject.dimensionCenterX + Math.signum(relativeZ) * newAbsoluteZ;
|
||||
// entity.isAirBorne = true;
|
||||
// @TODO: force client refresh of non-player entities
|
||||
if (entity instanceof EntityPlayerMP) {
|
||||
EntityPlayerMP player = (EntityPlayerMP) entity;
|
||||
player.setPositionAndUpdate(newEntityX, newEntityY, newEntityZ);
|
||||
} else {
|
||||
entity.setPosition(newEntityX, newEntityY, newEntityZ);
|
||||
}
|
||||
|
||||
// spam chat if it's a player
|
||||
if (entity instanceof EntityPlayer && !entity.isDead && entity.deathTime <= 0) {
|
||||
Commons.addChatMessage((EntityPlayer) entity,
|
||||
String.format("§4You've reached the world border..."));
|
||||
}
|
||||
|
||||
// delay damage for 'fast moving' players
|
||||
if (distanceSquared < BORDER_BYPASS_RANGE_BLOCKS_SQUARED) {
|
||||
// just set on fire
|
||||
entity.setFire(1);
|
||||
} else {
|
||||
// full damage
|
||||
entity.attackEntityFrom(DamageSource.outOfWorld, BORDER_BYPASS_DAMAGES_PER_TICK);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (entity instanceof EntityPlayerMP) {
|
||||
updatePlayerCloakState(entity);
|
||||
|
@ -87,76 +146,98 @@ public class LivingHandler {
|
|||
}
|
||||
|
||||
// If entity is in vacuum, check and start consuming air cells
|
||||
if (!WarpDrive.starMap.hasAtmosphere(entity.worldObj)) {
|
||||
// find an air block
|
||||
VectorI vAirBlock = null;
|
||||
Block block;
|
||||
for (VectorI vOffset : vAirOffsets) {
|
||||
VectorI vPosition = new VectorI(x + vOffset.x, y + vOffset.y, z + vOffset.z);
|
||||
block = entity.worldObj.getBlock(vPosition.x, vPosition.y, vPosition.z);
|
||||
if (block.isAssociatedBlock(WarpDrive.blockAir)) {
|
||||
vAirBlock = vPosition;
|
||||
break;
|
||||
if (!celestialObject.hasAtmosphere()) {
|
||||
if (updateBreathing(entity, x, y, z)) return;
|
||||
}
|
||||
|
||||
// If player falling down, teleport on earth
|
||||
if (entity.posY < -10.0D) {
|
||||
CelestialObject celestialObjectChild = StarMapRegistry.getClosestChildCelestialObject(
|
||||
entity.worldObj.provider.dimensionId, x, z);
|
||||
// are we actually in orbit?
|
||||
if ( celestialObjectChild != null
|
||||
&& !celestialObject.isHyperspace()
|
||||
&& celestialObjectChild.getSquareDistanceInParent(entity.worldObj.provider.dimensionId, x, z) <= 0.0D ) {
|
||||
|
||||
WorldServer worldTarget = DimensionManager.getWorld(celestialObjectChild.dimensionId);
|
||||
if (worldTarget != null) {
|
||||
final int yTarget = worldTarget.getActualHeight() + 5;
|
||||
|
||||
if (entity instanceof EntityPlayerMP) {
|
||||
EntityPlayerMP player = (EntityPlayerMP) entity;
|
||||
player.mcServer.getConfigurationManager().transferPlayerToDimension(player, celestialObjectChild.dimensionId,
|
||||
new SpaceTeleporter(worldTarget, 0, x, yTarget, z));
|
||||
if (celestialObjectChild.hasAtmosphere()) {
|
||||
player.setFire(30);
|
||||
}
|
||||
player.setPositionAndUpdate(entity.posX, yTarget, entity.posZ);
|
||||
player.sendPlayerAbilities();
|
||||
}
|
||||
}
|
||||
|
||||
} else if (celestialObject.isHyperspace() || celestialObject.isSpace()) {
|
||||
// player is in space or hyperspace, let's roll around
|
||||
entity.setPositionAndUpdate(entity.posX, 260.0D, entity.posZ);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean updateBreathing(EntityLivingBase entity, final int x, final int y, final int z) {
|
||||
// find an air block
|
||||
VectorI vAirBlock = null;
|
||||
Block block;
|
||||
for (VectorI vOffset : vAirOffsets) {
|
||||
VectorI vPosition = new VectorI(x + vOffset.x, y + vOffset.y, z + vOffset.z);
|
||||
block = entity.worldObj.getBlock(vPosition.x, vPosition.y, vPosition.z);
|
||||
if (block.isAssociatedBlock(WarpDrive.blockAir)) {
|
||||
vAirBlock = vPosition;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
final boolean notInVacuum = vAirBlock != null;
|
||||
Integer air;
|
||||
if (notInVacuum) {// No atmosphere with air blocks
|
||||
air = entity_airBlock.get(entity.getEntityId());
|
||||
if (air == null) {
|
||||
entity_airBlock.put(entity.getEntityId(), AIR_BLOCK_TICKS);
|
||||
} else if (air <= 1) {// time elapsed => consume air block
|
||||
entity_airBlock.put(entity.getEntityId(), AIR_BLOCK_TICKS);
|
||||
|
||||
int metadata = entity.worldObj.getBlockMetadata(vAirBlock.x, vAirBlock.y, vAirBlock.z);
|
||||
if (metadata > 0 && metadata < 15) {
|
||||
entity.worldObj.setBlockMetadataWithNotify(vAirBlock.x, vAirBlock.y, vAirBlock.z, metadata - 1, 2);
|
||||
}
|
||||
} else {
|
||||
entity_airBlock.put(entity.getEntityId(), air - 1);
|
||||
}
|
||||
|
||||
boolean notInVacuum = vAirBlock != null;
|
||||
Integer air;
|
||||
if (notInVacuum) {// In space with air blocks
|
||||
} else {// No atmosphere without air blocks
|
||||
// Damage entity if in vacuum without protection
|
||||
if (entity instanceof EntityPlayerMP) {
|
||||
air = entity_airBlock.get(entity.getEntityId());
|
||||
if (air == null) {
|
||||
entity_airBlock.put(entity.getEntityId(), AIR_BLOCK_TICKS);
|
||||
} else if (air <= 1) {// time elapsed => consume air block
|
||||
entity_airBlock.put(entity.getEntityId(), AIR_BLOCK_TICKS);
|
||||
|
||||
int metadata = entity.worldObj.getBlockMetadata(vAirBlock.x, vAirBlock.y, vAirBlock.z);
|
||||
if (metadata > 0 && metadata < 15) {
|
||||
entity.worldObj.setBlockMetadataWithNotify(vAirBlock.x, vAirBlock.y, vAirBlock.z, metadata - 1, 2);
|
||||
}
|
||||
} else {
|
||||
if (air != null && air > 0) {
|
||||
entity_airBlock.put(entity.getEntityId(), air - 1);
|
||||
return true;
|
||||
}
|
||||
} else {// In space without air blocks
|
||||
// Damage entity if in vacuum without protection
|
||||
if (entity instanceof EntityPlayerMP) {
|
||||
air = entity_airBlock.get(entity.getEntityId());
|
||||
if (air != null && air > 0) {
|
||||
entity_airBlock.put(entity.getEntityId(), air - 1);
|
||||
return;
|
||||
}
|
||||
EntityPlayerMP player = (EntityPlayerMP) entity;
|
||||
String playerName = player.getCommandSenderName();
|
||||
air = player_airTank.get(playerName);
|
||||
|
||||
boolean hasHelmet = false;
|
||||
ItemStack helmetStack = player.getCurrentArmor(3);
|
||||
if (helmetStack != null) {
|
||||
Item itemHelmet = helmetStack.getItem();
|
||||
if (itemHelmet instanceof IBreathingHelmet) {
|
||||
IBreathingHelmet breathingHelmet = (IBreathingHelmet) itemHelmet;
|
||||
int airTicks = breathingHelmet.ticksPerCanDamage();
|
||||
if (breathingHelmet.canBreath(player)) {
|
||||
hasHelmet = true;
|
||||
if (air == null) {// new player in space => grace period
|
||||
player_airTank.put(playerName, airTicks);
|
||||
} else if (air <= 1) {
|
||||
if (breathingHelmet.removeAir(player) || consumeAirCanister(player)) {
|
||||
player_airTank.put(playerName, airTicks);
|
||||
} else {
|
||||
hasHelmet = false;
|
||||
}
|
||||
} else {
|
||||
player_airTank.put(playerName, air - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Dictionary.ITEMS_BREATHING_HELMET.contains(itemHelmet)) {
|
||||
EntityPlayerMP player = (EntityPlayerMP) entity;
|
||||
String playerName = player.getCommandSenderName();
|
||||
air = player_airTank.get(playerName);
|
||||
|
||||
boolean hasHelmet = false;
|
||||
ItemStack helmetStack = player.getCurrentArmor(3);
|
||||
if (helmetStack != null) {
|
||||
Item itemHelmet = helmetStack.getItem();
|
||||
if (itemHelmet instanceof IBreathingHelmet) {
|
||||
IBreathingHelmet breathingHelmet = (IBreathingHelmet) itemHelmet;
|
||||
int airTicks = breathingHelmet.ticksPerCanDamage();
|
||||
if (breathingHelmet.canBreath(player)) {
|
||||
hasHelmet = true;
|
||||
if (air == null) {// new player in space => grace period
|
||||
player_airTank.put(playerName, AIR_TANK_TICKS);
|
||||
player_airTank.put(playerName, airTicks);
|
||||
} else if (air <= 1) {
|
||||
if (consumeAirCanister(player)) {
|
||||
player_airTank.put(playerName, AIR_TANK_TICKS);
|
||||
if (breathingHelmet.removeAir(player) || consumeAirCanister(player)) {
|
||||
player_airTank.put(playerName, airTicks);
|
||||
} else {
|
||||
hasHelmet = false;
|
||||
}
|
||||
|
@ -165,32 +246,39 @@ public class LivingHandler {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasHelmet) {
|
||||
if (Dictionary.ITEMS_BREATHING_HELMET.contains(itemHelmet)) {
|
||||
hasHelmet = true;
|
||||
if (air == null) {// new player in space => grace period
|
||||
player_airTank.put(playerName, AIR_TANK_TICKS);
|
||||
} else if (air <= 1) {
|
||||
player_airTank.put(playerName, AIR_DROWN_TICKS);
|
||||
entity.attackEntityFrom(WarpDrive.damageAsphyxia, 2.0F);
|
||||
if (consumeAirCanister(player)) {
|
||||
player_airTank.put(playerName, AIR_TANK_TICKS);
|
||||
} else {
|
||||
hasHelmet = false;
|
||||
}
|
||||
} else {
|
||||
player_airTank.put(playerName, air - 1);
|
||||
}
|
||||
}
|
||||
|
||||
// If player falling down, teleport on earth
|
||||
if (entity.posY < -10.0D) {
|
||||
player.mcServer.getConfigurationManager().transferPlayerToDimension(player, 0,
|
||||
new SpaceTeleporter(DimensionManager.getWorld(WarpDriveConfig.G_SPACE_DIMENSION_ID), 0, x, 250, z));
|
||||
player.setFire(30);
|
||||
player.setPositionAndUpdate(entity.posX, 250.0D, entity.posZ);
|
||||
player.sendPlayerAbilities();
|
||||
}
|
||||
} else {// (in space, no air block and not a player)
|
||||
entity_airBlock.put(entity.getEntityId(), 0);
|
||||
entity.attackEntityFrom(WarpDrive.damageAsphyxia, 2.0F);
|
||||
}
|
||||
|
||||
if (!hasHelmet) {
|
||||
if (air == null) {// new player in space => grace period
|
||||
player_airTank.put(playerName, AIR_TANK_TICKS);
|
||||
} else if (air <= 1) {
|
||||
player_airTank.put(playerName, AIR_DROWN_TICKS);
|
||||
entity.attackEntityFrom(WarpDrive.damageAsphyxia, 2.0F);
|
||||
} else {
|
||||
player_airTank.put(playerName, air - 1);
|
||||
}
|
||||
}
|
||||
|
||||
} else {// (in space, no air block and not a player)
|
||||
entity_airBlock.put(entity.getEntityId(), 0);
|
||||
entity.attackEntityFrom(WarpDrive.damageAsphyxia, 2.0F);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void updatePlayerCloakState(EntityLivingBase entity) {
|
||||
|
|
|
@ -2,7 +2,7 @@ package cr0s.warpdrive.render;
|
|||
|
||||
import cr0s.warpdrive.WarpDrive;
|
||||
import cr0s.warpdrive.config.WarpDriveConfig;
|
||||
import cr0s.warpdrive.data.Planet;
|
||||
import cr0s.warpdrive.data.CelestialObject;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
|
@ -30,9 +30,11 @@ public class RenderSpaceSky extends IRenderHandler {
|
|||
}
|
||||
|
||||
private static final ResourceLocation[] texturePlanets = {
|
||||
new ResourceLocation("warpdrive:textures/celestial/planet_green.png"),
|
||||
new ResourceLocation("warpdrive:textures/celestial/planet_yellow.png"),
|
||||
new ResourceLocation("warpdrive:textures/celestial/planet_red.png")
|
||||
new ResourceLocation("warpdrive:textures/celestial/planet_icy.png"),
|
||||
new ResourceLocation("warpdrive:textures/celestial/planet_magma.png"),
|
||||
new ResourceLocation("warpdrive:textures/celestial/planet_metallic.png"),
|
||||
new ResourceLocation("warpdrive:textures/celestial/planet_oceanic.png"),
|
||||
new ResourceLocation("warpdrive:textures/celestial/planet_temperate.png")
|
||||
};
|
||||
private static final ResourceLocation textureStar = new ResourceLocation("warpdrive:textures/celestial/star_yellow.png");
|
||||
|
||||
|
@ -84,7 +86,9 @@ public class RenderSpaceSky extends IRenderHandler {
|
|||
|
||||
@Override
|
||||
public void render(float partialTicks, WorldClient world, Minecraft mc) {
|
||||
boolean isSpace = world.provider == null || WarpDrive.starMap.isInSpace(world);
|
||||
final Vec3 playerCoordinates = mc.thePlayer.getPosition(partialTicks);
|
||||
final boolean isSpace = world.provider == null
|
||||
|| WarpDrive.starMap.isInSpace(world, (int) playerCoordinates.xCoord, (int) playerCoordinates.zCoord);
|
||||
|
||||
final Tessellator tessellator = Tessellator.instance;
|
||||
|
||||
|
@ -160,7 +164,7 @@ public class RenderSpaceSky extends IRenderHandler {
|
|||
GL11.glPopMatrix();
|
||||
}
|
||||
|
||||
// Planet
|
||||
// CelestialObject
|
||||
/*
|
||||
{
|
||||
GL11.glPushMatrix();
|
||||
|
@ -187,9 +191,8 @@ public class RenderSpaceSky extends IRenderHandler {
|
|||
/**/
|
||||
|
||||
// Planets
|
||||
Vec3 playerCoordinates = mc.thePlayer.getPosition(partialTicks);
|
||||
for(Planet planet : WarpDriveConfig.PLANETS) {
|
||||
renderPlanet(tessellator, planet, isSpace, playerCoordinates);
|
||||
for(CelestialObject celestialObject : WarpDriveConfig.celestialObjects) {
|
||||
renderCelestialObject(tessellator, celestialObject, isSpace, mc.thePlayer.getEntityWorld().provider.dimensionId, playerCoordinates);
|
||||
}
|
||||
|
||||
// final double playerAltitude = mc.thePlayer.getPosition(partialTicks).yCoord - world.getHorizon();
|
||||
|
@ -256,11 +259,16 @@ public class RenderSpaceSky extends IRenderHandler {
|
|||
static final double PLANET_FAR = 1786.0D;
|
||||
static final double PLANET_APPROACHING = 512.0D;
|
||||
static final double PLANET_ORBIT = 128.0D;
|
||||
private static void renderPlanet(Tessellator tessellator, final Planet planet, final boolean isSpace, final Vec3 vec3Player) {
|
||||
final double planetX = planet.spaceCenterX - vec3Player.xCoord;
|
||||
final double planetZ = planet.spaceCenterZ - vec3Player.zCoord;
|
||||
final double distanceToBorder = planet.isValidFromSpace((int) vec3Player.xCoord, (int) vec3Player.zCoord);
|
||||
final double distanceToCenter = Math.sqrt(planetX * planetX + planetZ * planetZ);
|
||||
private static void renderCelestialObject(Tessellator tessellator, final CelestialObject celestialObject, final boolean isSpace, final int dimensionId, final Vec3 vec3Player) {
|
||||
// @TODO compute relative coordinates for rendering on celestialObject
|
||||
if (dimensionId != celestialObject.parentDimensionId) {
|
||||
return;
|
||||
}
|
||||
|
||||
final double distanceToCenterX = celestialObject.parentCenterX - vec3Player.xCoord;
|
||||
final double distanceToCenterZ = celestialObject.parentCenterZ - vec3Player.zCoord;
|
||||
final double distanceToBorder = Math.sqrt(Math.max(0, celestialObject.getSquareDistanceInParent(dimensionId, vec3Player.xCoord, vec3Player.zCoord)));
|
||||
final double distanceToCenter = Math.sqrt(distanceToCenterX * distanceToCenterX + distanceToCenterZ * distanceToCenterZ);
|
||||
|
||||
// transition values
|
||||
// distance far approaching orbit
|
||||
|
@ -273,33 +281,33 @@ public class RenderSpaceSky extends IRenderHandler {
|
|||
final double transitionApproaching = (Math.max(PLANET_ORBIT, Math.min(PLANET_APPROACHING, distanceToBorder)) - PLANET_ORBIT) / (PLANET_APPROACHING - PLANET_ORBIT);
|
||||
final double transitionOrbit = Math.max(0.0D, Math.min(PLANET_ORBIT, distanceToBorder)) / PLANET_ORBIT;
|
||||
|
||||
// relative position above planet
|
||||
final double offsetX = (1.0 - transitionOrbit) * (planet.borderSizeX - planetX) / planet.borderSizeX;
|
||||
final double offsetZ = (1.0 - transitionOrbit) * (planet.borderSizeZ - planetZ) / planet.borderSizeZ;
|
||||
// relative position above celestialObject
|
||||
final double offsetX = (1.0 - transitionOrbit) * (celestialObject.borderRadiusX - distanceToCenterX) / celestialObject.borderRadiusX;
|
||||
final double offsetZ = (1.0 - transitionOrbit) * (celestialObject.borderRadiusZ - distanceToCenterZ) / celestialObject.borderRadiusZ;
|
||||
|
||||
// simulating a non-planar universe...
|
||||
final double planetY_far = (planet.dimensionId + 99 % 100 - 50) * Math.log(distanceToCenter) / 4.0D;
|
||||
final double planetY_far = (celestialObject.dimensionId + 99 % 100 - 50) * Math.log(distanceToCenter) / 4.0D;
|
||||
final double planetY = planetY_far * transitionApproaching;
|
||||
|
||||
// render range is only used for Z-ordering
|
||||
final double renderRange = 180.0D + 10.0D * (distanceToCenter / WarpDriveConfig.G_SPACE_WORLDBORDER_BLOCKS);
|
||||
final double renderRange = 180.0D + 10.0D * (distanceToCenter / Math.max(celestialObject.borderRadiusX, celestialObject.borderRadiusZ));
|
||||
|
||||
// render size is 1 at space border range
|
||||
// render size is 10 at approaching range
|
||||
// render size is 90 at orbit range
|
||||
// render size is min(1000, planet border) at orbit range
|
||||
final double renderSize = 100.0D / 1000.0D * Math.min(1000.0D, Math.max(planet.borderSizeX, planet.borderSizeZ)) * (1.0D - transitionOrbit)
|
||||
// render size is min(1000, celestialObject border) at orbit range
|
||||
final double renderSize = 100.0D / 1000.0D * Math.min(1000.0D, Math.max(celestialObject.borderRadiusX, celestialObject.borderRadiusZ)) * (1.0D - transitionOrbit)
|
||||
+ 50.0D * (transitionOrbit < 1.0D ? transitionOrbit : (1.0D - transitionApproaching))
|
||||
+ 5.0D * (transitionApproaching < 1.0D ? transitionApproaching : (1.0D - transitionFar))
|
||||
+ 1.0D * transitionFar;
|
||||
|
||||
// angles
|
||||
@SuppressWarnings("SuspiciousNameCombination")
|
||||
final double angleH = Math.atan2(planetX, planetZ);
|
||||
final double angleH = Math.atan2(distanceToCenterX, distanceToCenterZ);
|
||||
@SuppressWarnings("SuspiciousNameCombination")
|
||||
final double angleV_far = Math.atan2(Math.sqrt(planetX * planetX + planetZ * planetZ), planetY);
|
||||
final double angleV_far = Math.atan2(Math.sqrt(distanceToCenterX * distanceToCenterX + distanceToCenterZ * distanceToCenterZ), planetY);
|
||||
final double angleV = Math.PI * (1.0D - transitionOrbit) + angleV_far * transitionOrbit;
|
||||
final double angleS = 0.15D * planet.dimensionId * transitionApproaching; // + (world.getTotalWorldTime() + partialTicks) * Math.PI / 6000.0D;
|
||||
final double angleS = 0.15D * celestialObject.dimensionId * transitionApproaching; // + (world.getTotalWorldTime() + partialTicks) * Math.PI / 6000.0D;
|
||||
|
||||
// pre-computations
|
||||
final double sinH = Math.sin(angleH);
|
||||
|
@ -311,7 +319,7 @@ public class RenderSpaceSky extends IRenderHandler {
|
|||
|
||||
GL11.glPushMatrix();
|
||||
GL11.glColor4f(1.0F, 1.0F, 1.0F, isSpace ? 1.0F : 0.2F);
|
||||
FMLClientHandler.instance().getClient().renderEngine.bindTexture(texturePlanets[Math.abs(planet.dimensionId) % 3]);
|
||||
FMLClientHandler.instance().getClient().renderEngine.bindTexture(texturePlanets[Math.abs(celestialObject.dimensionId) % texturePlanets.length]);
|
||||
tessellator.startDrawingQuads();
|
||||
for (int indexVertex = 0; indexVertex < 4; indexVertex++) {
|
||||
final double offset1 = ((indexVertex & 2) - 1) * renderSize;
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
package cr0s.warpdrive.world;
|
||||
|
||||
import cr0s.warpdrive.config.WarpDriveConfig;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import net.minecraft.world.World;
|
||||
|
@ -9,11 +7,10 @@ import net.minecraft.world.chunk.IChunkProvider;
|
|||
|
||||
import cpw.mods.fml.common.IWorldGenerator;
|
||||
|
||||
|
||||
public class HyperSpaceWorldGenerator implements IWorldGenerator {
|
||||
@Override
|
||||
public void generate(Random random, int chunkX, int chunkZ, World world, IChunkProvider chunkGenerator, IChunkProvider chunkProvider) {
|
||||
if (world.provider.dimensionId != WarpDriveConfig.G_HYPERSPACE_DIMENSION_ID) {
|
||||
if (world.provider.dimensionId != 0) {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
package cr0s.warpdrive.world;
|
||||
|
||||
|
||||
import cr0s.warpdrive.WarpDrive;
|
||||
import cr0s.warpdrive.config.WarpDriveConfig;
|
||||
import cr0s.warpdrive.data.StarMapRegistry;
|
||||
import cr0s.warpdrive.render.RenderBlank;
|
||||
import cr0s.warpdrive.render.RenderSpaceSky;
|
||||
|
||||
|
@ -129,7 +128,11 @@ public class HyperSpaceWorldProvider extends WorldProvider {
|
|||
|
||||
@Override
|
||||
public int getRespawnDimension(EntityPlayerMP player) {
|
||||
return WarpDriveConfig.G_HYPERSPACE_DIMENSION_ID;
|
||||
if (player == null || player.worldObj == null) {
|
||||
WarpDrive.logger.error("Invalid player passed to getRespawnDimension: " + player);
|
||||
return 0;
|
||||
}
|
||||
return StarMapRegistry.getHyperspaceDimensionId(player.worldObj, (int) player.posX, (int) player.posZ);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -8,6 +8,8 @@ import cr0s.warpdrive.config.structures.AbstractStructure;
|
|||
import cr0s.warpdrive.config.structures.Orb.OrbShell;
|
||||
import cr0s.warpdrive.config.structures.OrbInstance;
|
||||
import cr0s.warpdrive.config.structures.StructureManager;
|
||||
import cr0s.warpdrive.data.CelestialObject;
|
||||
import cr0s.warpdrive.data.StarMapRegistry;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
|
@ -21,28 +23,42 @@ public class SpaceWorldGenerator implements IWorldGenerator {
|
|||
@Override
|
||||
public void generate(Random random, int chunkX, int chunkZ, World world, IChunkProvider chunkGenerator, IChunkProvider chunkProvider) {
|
||||
try {
|
||||
if (!WarpDrive.starMap.isInSpace(world)) {
|
||||
final int x = (chunkX * 16) + (5 - random.nextInt(10));
|
||||
final int z = (chunkZ * 16) + (5 - random.nextInt(10));
|
||||
CelestialObject celestialObject = StarMapRegistry.getCelestialObject(world, x, z);
|
||||
if (celestialObject == null) {
|
||||
// as observed on 1.7.10: during world transition, the generator from the previous world is still called
|
||||
return;
|
||||
}
|
||||
int x = (chunkX * 16) + (5 - random.nextInt(10));
|
||||
int z = (chunkZ * 16) + (5 - random.nextInt(10));
|
||||
if (WarpDriveConfig.G_SPACE_WORLDBORDER_BLOCKS > 0 && (Math.abs(x) > WarpDriveConfig.G_SPACE_WORLDBORDER_BLOCKS || Math.abs(z) > WarpDriveConfig.G_SPACE_WORLDBORDER_BLOCKS)) {
|
||||
if ( celestialObject.borderRadiusX > 0
|
||||
&& ( Math.abs(x - celestialObject.dimensionCenterX) > celestialObject.borderRadiusX
|
||||
|| Math.abs(z - celestialObject.dimensionCenterZ) > celestialObject.borderRadiusZ ) ) {
|
||||
return;
|
||||
}
|
||||
int y = WarpDriveConfig.SPACE_GENERATOR_Y_MIN_CENTER + random.nextInt(WarpDriveConfig.SPACE_GENERATOR_Y_MAX_CENTER - WarpDriveConfig.SPACE_GENERATOR_Y_MIN_CENTER);
|
||||
// Moon setup
|
||||
if (random.nextInt(800) == 1) {
|
||||
int y = WarpDriveConfig.SPACE_GENERATOR_Y_MIN_CENTER
|
||||
+ random.nextInt(WarpDriveConfig.SPACE_GENERATOR_Y_MAX_CENTER - WarpDriveConfig.SPACE_GENERATOR_Y_MIN_CENTER);
|
||||
|
||||
String group = celestialObject.getRandomGeneration(random);
|
||||
if (group == null) {
|
||||
return;
|
||||
}
|
||||
switch (group) {
|
||||
case "moon":
|
||||
AbstractStructure moon = StructureManager.getStructure(world.rand, StructureManager.GROUP_MOONS, null);
|
||||
moon.generate(world, world.rand, x, y, z);
|
||||
break;
|
||||
|
||||
// Simple asteroids
|
||||
} else if (random.nextInt(150) == 1) {
|
||||
AbstractStructure moon = StructureManager.getStructure(world.rand, StructureManager.GROUP_ASTEROIDS, null);
|
||||
moon.generate(world, world.rand, x, y, z);
|
||||
case "asteroid":
|
||||
AbstractStructure asteroid = StructureManager.getStructure(world.rand, StructureManager.GROUP_ASTEROIDS, null);
|
||||
asteroid.generate(world, world.rand, x, y, z);
|
||||
break;
|
||||
|
||||
// Random asteroid of block
|
||||
} else if (random.nextInt(600) == 1) {// Asteroid field
|
||||
case "asteroidField":
|
||||
generateAsteroidField(world, x, y, z);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
} catch (Exception exception) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package cr0s.warpdrive.world;
|
||||
|
||||
|
||||
import cr0s.warpdrive.WarpDrive;
|
||||
import cr0s.warpdrive.data.StarMapRegistry;
|
||||
import cr0s.warpdrive.render.RenderBlank;
|
||||
import cr0s.warpdrive.render.RenderSpaceSky;
|
||||
|
||||
|
@ -128,7 +128,11 @@ public class SpaceWorldProvider extends WorldProvider {
|
|||
|
||||
@Override
|
||||
public int getRespawnDimension(EntityPlayerMP player) {
|
||||
return 0; // re-spawn on Earth
|
||||
if (player == null || player.worldObj == null) {
|
||||
WarpDrive.logger.error("Invalid player passed to getRespawnDimension: " + player);
|
||||
return 0;
|
||||
}
|
||||
return StarMapRegistry.getSpaceDimensionId(player.worldObj, (int) player.posX, (int) player.posZ);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Loading…
Reference in a new issue