package micdoodle8.mods.galacticraft.planets.asteroids.dimension;
import micdoodle8.mods.galacticraft.api.entity.IRocketType;
import micdoodle8.mods.galacticraft.api.recipe.SchematicRegistry;
import micdoodle8.mods.galacticraft.api.vector.BlockVec3;
import micdoodle8.mods.galacticraft.api.vector.Vector3;
import micdoodle8.mods.galacticraft.api.world.ITeleportType;
import micdoodle8.mods.galacticraft.core.GCItems;
import micdoodle8.mods.galacticraft.core.entities.player.GCPlayerStats;
import micdoodle8.mods.galacticraft.core.util.ConfigManagerCore;
import micdoodle8.mods.galacticraft.core.util.GCLog;
import micdoodle8.mods.galacticraft.planets.asteroids.blocks.AsteroidBlocks;
import micdoodle8.mods.galacticraft.planets.asteroids.entities.EntityEntryPod;
import micdoodle8.mods.galacticraft.planets.asteroids.items.AsteroidsItems;
import micdoodle8.mods.galacticraft.planets.mars.blocks.MarsBlocks;
import micdoodle8.mods.galacticraft.planets.mars.items.MarsItems;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityList;
import net.minecraft.entity.passive.EntityCow;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.item.ItemStack;
import net.minecraft.util.BlockPos;
import net.minecraft.util.MathHelper;
import net.minecraft.world.World;
import net.minecraft.world.WorldServer;
import net.minecraft.world.gen.ChunkProviderServer;
import net.minecraftforge.fml.common.FMLLog;
import java.util.Random;
public class TeleportTypeAsteroids implements ITeleportType
{
@Override
public boolean useParachute()
{
return false;
}
@Override
public Vector3 getPlayerSpawnLocation(WorldServer world, EntityPlayerMP player)
{
if (player != null)
{
GCPlayerStats stats = GCPlayerStats.get(player);
int x = MathHelper.floor_double(stats.getCoordsTeleportedFromX());
int z = MathHelper.floor_double(stats.getCoordsTeleportedFromZ());
int limit = ConfigManagerCore.otherPlanetWorldBorders - 2;
if (limit > 20)
{
if (x > limit)
{
z *= limit / x;
x = limit;
}
else if (x < -limit)
{
z *= -limit / x;
x = -limit;
}
if (z > limit)
{
x *= limit / z;
z = limit;
}
else if (z < -limit)
{
x *= - limit / z;
z = -limit;
}
}
int attemptCount = 0;
//Small pre-generate with a chunk loading radius of 3, to make sure some asteroids get generated
//(if the world is already generated here, this will be very quick)
this.preGenChunks(world, x >> 4, z >> 4);
do
{
BlockVec3 bv3 = null;
if (world.provider instanceof WorldProviderAsteroids)
{
bv3 = ((WorldProviderAsteroids) world.provider).getClosestAsteroidXZ(x, 0, z, true);
}
if (bv3 != null)
{
//Check whether the returned asteroid is too far from the desired entry location in which case, give up
if (bv3.distanceSquared(new BlockVec3(x, 128, z)) > 25600)
{
break;
}
if (ConfigManagerCore.enableDebug)
{
GCLog.info("Testing asteroid at x" + (bv3.x) + " y" + (bv3.y) + " z" + bv3.z);
}
this.loadChunksAround(bv3.x, bv3.z, 2, world.theChunkProviderServer);
this.loadChunksAround(bv3.x, bv3.z, -3, world.theChunkProviderServer);
if (goodAsteroidEntry(world, bv3.x, bv3.y, bv3.z))
{
return new Vector3(bv3.x, 310, bv3.z);
}
if (goodAsteroidEntry(world, bv3.x + 2, bv3.y, bv3.z + 2))
{
return new Vector3(bv3.x + 2, 310, bv3.z + 2);
}
if (goodAsteroidEntry(world, bv3.x + 2, bv3.y, bv3.z - 2))
{
return new Vector3(bv3.x + 2, 310, bv3.z - 2);
}
if (goodAsteroidEntry(world, bv3.x - 2, bv3.y, bv3.z - 2))
{
return new Vector3(bv3.x - 2, 310, bv3.z - 2);
}
if (goodAsteroidEntry(world, bv3.x - 2, bv3.y, bv3.z + 2))
{
return new Vector3(bv3.x - 2, 310, bv3.z + 2);
}
//Failed to find an asteroid even though there should be one there
if (ConfigManagerCore.enableDebug)
{
GCLog.info("Removing drilled out asteroid at x" + (bv3.x) + " z" + (bv3.z));
}
((WorldProviderAsteroids) world.provider).removeAsteroid(bv3.x, bv3.y, bv3.z);
}
attemptCount++;
}
while (attemptCount < 5);
FMLLog.info("Failed to find good large asteroid landing spot! Falling back to making a small one.");
this.makeSmallLandingSpot(world, x, z);
return new Vector3(x, 310, z);
}
FMLLog.severe("Null player when teleporting to Asteroids!");
return new Vector3(0, 310, 0);
}
private boolean goodAsteroidEntry(World world, int x, int yorig, int z)
{
for (int k = 208; k > 48; k--)
{
if (!world.isAirBlock(new BlockPos(x, k, z)))
{
if (Math.abs(k - yorig) > 20)
{
continue;
}
//Clear the downward path of small asteroids and any other asteroid rock
for (int y = k + 2; y < 256; y++)
{
if (world.getBlockState(new BlockPos(x, y, z)).getBlock() == AsteroidBlocks.blockBasic)
{
world.setBlockToAir(new BlockPos(x, y, z));
}
if (world.getBlockState(new BlockPos(x - 1, y, z)).getBlock() == AsteroidBlocks.blockBasic)
{
world.setBlockToAir(new BlockPos(x - 1, y, z));
}
if (world.getBlockState(new BlockPos(x, y, z - 1)).getBlock() == AsteroidBlocks.blockBasic)
{
world.setBlockToAir(new BlockPos(x, y, z - 1));
}
if (world.getBlockState(new BlockPos(x - 1, y, z - 1)).getBlock() == AsteroidBlocks.blockBasic)
{
world.setBlockToAir(new BlockPos(x - 1, y, z - 1));
}
}
if (ConfigManagerCore.enableDebug)
{
GCLog.info("Found asteroid at x" + (x) + " z" + (z));
}
return true;
}
}
return false;
}
private void makeSmallLandingSpot(World world, int x, int z)
{
this.loadChunksAround(x, z, -1, (ChunkProviderServer) world.getChunkProvider());
for (int k = 255; k > 48; k--)
{
if (!world.isAirBlock(new BlockPos(x, k, z)))
{
this.makePlatform(world, x, k - 1, z);
return;
}
if (!world.isAirBlock(new BlockPos(x - 1, k, z)))
{
this.makePlatform(world, x - 1, k - 1, z);
return;
}
if (!world.isAirBlock(new BlockPos(x - 1, k, z - 1)))
{
this.makePlatform(world, x - 1, k - 1, z - 1);
return;
}
if (!world.isAirBlock(new BlockPos(x, k, z - 1)))
{
this.makePlatform(world, x, k - 1, z - 1);
return;
}
}
this.makePlatform(world, x, 48 + world.rand.nextInt(128), z);
return;
}
private void loadChunksAround(int x, int z, int i, ChunkProviderServer cp)
{
cp.loadChunk(x >> 4, z >> 4);
if ((x + i) >> 4 != x >> 4)
{
cp.loadChunk((x + i) >> 4, z >> 4);
if ((z + i) >> 4 != z >> 4)
{
cp.loadChunk(x >> 4, (z + i) >> 4);
cp.loadChunk((x + i) >> 4, (z + i) >> 4);
}
}
else if ((z + i) >> 4 != z >> 4)
{
cp.loadChunk(x >> 4, (z + i) >> 4);
}
}
private void makePlatform(World world, int x, int y, int z)
{
for (int xx = -3; xx < 3; xx++)
{
for (int zz = -3; zz < 3; zz++)
{
if (xx == -3 && (zz == -3 || zz == 2))
{
continue;
}
if (xx == 2 && (zz == -3 || zz == 2))
{
continue;
}
doBlock(world, x + xx, y, z + zz);
}
}
for (int xx = -2; xx < 2; xx++)
{
for (int zz = -2; zz < 2; zz++)
{
doBlock(world, x + xx, y - 1, z + zz);
}
}
doBlock(world, x - 1, y - 2, z - 1);
doBlock(world, x - 1, y - 2, z);
doBlock(world, x, y - 2, z);
doBlock(world, x, y - 2, z - 1);
}
private void doBlock(World world, int x, int y, int z)
{
int meta = (int) (world.rand.nextFloat() * 1.5F);
if (world.isAirBlock(new BlockPos(x, y, z)))
{
world.setBlockState(new BlockPos(x, y, z), AsteroidBlocks.blockBasic.getStateFromMeta(meta), 2);
}
}
@Override
public Vector3 getEntitySpawnLocation(WorldServer world, Entity entity)
{
return new Vector3(entity.posX, ConfigManagerCore.disableLander ? 250.0 : 900.0, entity.posZ);
}
@Override
public Vector3 getParaChestSpawnLocation(WorldServer world, EntityPlayerMP player, Random rand)
{
return null;
}
private void preGenChunks(World w, int cx, int cz)
{
this.preGenChunk(w, cx, cz);
for (int r = 1; r < 3; r++)
{
int xmin = cx - r;
int xmax = cx + r;
int zmin = cz - r;
int zmax = cz + r;
for (int i = -r; i < r; i++)
{
this.preGenChunk(w, xmin, cz + i);
this.preGenChunk(w, xmax, cz - i);
this.preGenChunk(w, cx - i, zmin);
this.preGenChunk(w, cx + i, zmax);
}
}
}
private void preGenChunk(World w, int chunkX, int chunkZ)
{
w.getChunkFromChunkCoords(chunkX, chunkZ);
}
@Override
public void onSpaceDimensionChanged(World newWorld, EntityPlayerMP player, boolean ridingAutoRocket)
{
if (!ridingAutoRocket && player != null)
{
GCPlayerStats stats = GCPlayerStats.get(player);
if (stats.getTeleportCooldown() <= 0)
{
if (player.capabilities.isFlying)
{
player.capabilities.isFlying = false;
}
if (!newWorld.isRemote)
{
EntityEntryPod entryPod = new EntityEntryPod(player);
entryPod.forceSpawn = true;
newWorld.spawnEntityInWorld(entryPod);
}
stats.setTeleportCooldown(10);
}
}
}
@Override
public void setupAdventureSpawn(EntityPlayerMP player)
{
GCPlayerStats stats = GCPlayerStats.get(player);
SchematicRegistry.unlockNewPage(player, new ItemStack(GCItems.schematic, 1, 1)); //Knows how to build T2 rocket
SchematicRegistry.unlockNewPage(player, new ItemStack(MarsItems.schematic, 1, 0)); //Knows how to build T3 rocket
SchematicRegistry.unlockNewPage(player, new ItemStack(MarsItems.schematic, 1, 2)); //Knows how to build Astro Miner
ItemStack[] rocketStacks = new ItemStack[20];
stats.setFuelLevel(1000);
int i = 0;
rocketStacks[i++] = new ItemStack(GCItems.oxMask);
rocketStacks[i++] = new ItemStack(GCItems.oxygenGear);
rocketStacks[i++] = new ItemStack(GCItems.oxTankMedium);
rocketStacks[i++] = new ItemStack(GCItems.oxTankHeavy);
rocketStacks[i++] = new ItemStack(GCItems.oxTankHeavy);
rocketStacks[i++] = new ItemStack(AsteroidsItems.canisterLOX);
rocketStacks[i++] = new ItemStack(AsteroidsItems.canisterLOX);
rocketStacks[i++] = new ItemStack(AsteroidsItems.canisterLOX);
rocketStacks[i++] = new ItemStack(AsteroidsItems.basicItem, 32, 7);
rocketStacks[i++] = new ItemStack(Blocks.glass_pane, 16);
rocketStacks[i++] = new ItemStack(Blocks.planks, 32, 2);
rocketStacks[i++] = new ItemStack(MarsItems.marsItemBasic, 16, 2); //Desh ingot
rocketStacks[i++] = new ItemStack(GCItems.basicItem, 8, 13); //Basic Wafer
rocketStacks[i++] = new ItemStack(GCItems.basicItem, 2, 1); //Solar Panels
rocketStacks[i++] = new ItemStack(GCItems.basicItem, 16, 15); //Canned food
rocketStacks[i++] = new ItemStack(Items.egg, 12);
rocketStacks[i++] = new ItemStack(Items.spawn_egg, 2, EntityList.classToIDMapping.get(EntityCow.class));
rocketStacks[i++] = new ItemStack(Items.potionitem, 4, 8262); //Night Vision Potion
rocketStacks[i++] = new ItemStack(MarsBlocks.machine, 1, 4); //Cryogenic Chamber
rocketStacks[i++] = new ItemStack(MarsItems.rocketMars, 1, IRocketType.EnumRocketType.INVENTORY36.ordinal());
//rocketStacks[15] = new ItemStack(GCBlocks.brightLamp, 4);
//rocketStacks[16] = new ItemStack(GCBlocks.aluminumWire, 32);
stats.setRocketStacks(rocketStacks);
}
}