Думаю многие хотели сделать свой измерение наподобие ада. И я решил написать туториал на эту тему туториал думаю многим пригодиться. Я покажу как создать своё измерение с биомов пустыни.
Нам понадобиться:
1. ModLoader - http://minecraftforum.net/topic/75440-v125-risugamis-mods-everything-updated/
2. Pudelhund's Dimension API - http://minecraftforu...ension-api-v13/
Создадим файл mod_TutorialDimension.java напишем следущие:
package net.minecraft.src;
public class mod_TutorialDimension extends BaseMod
{
public static final Block TutorialPortal = new BlockTutorialPortal(220).setHardness(-1F).setStepSound(Block.soundGlassFootstep).setLightValue(0.75F).setBlockName("Tutorial Portal");
public static final Block TutorialCreatePortal = new BlockTutorialCreatePortal(221, 0).setHardness(2.0F).setResistance(5F).setBlockName("Tutorial Create Portal");
public mod_TutorialDimension()
{
//Регистрируем сввоё измерение
DimensionAPI.registerDimension(new WorldProviderTutorial());
}
public void load()
{
//Тут всё понятно регистрация блока, добавление имя блока и создание рецепта
ModLoader.registerBlock(TutorialPortal);
ModLoader.addName(TutorialPortal, "Tutorial Portal");
ModLoader.addRecipe(new ItemStack(TutorialPortal, 10), new Object[] { "X", Character.valueOf('X'), Block.dirt });
ModLoader.registerBlock(TutorialCreatePortal);
ModLoader.addName(TutorialCreatePortal, "Tutorial Create Portal");
TutorialCreatePortal.blockIndexInTexture = ModLoader.addOverride("/terrain.png", "/Tutorial/TutorialCreatePortal.png");
ModLoader.addRecipe(new ItemStack(TutorialCreatePortal, 10), new Object[] { "XX", Character.valueOf('X'), Block.dirt });
}
public String getVersion()
{
return "1.2.4";
}
}
Теперь создадим BlockTutorialPortal.java
package net.minecraft.src;
import java.util.List;
import java.util.ArrayList;
public class BlockTutorialPortal extends BlockPortalBase
{
//Здесь указываем текстуру к блоку
public BlockTutorialPortal(int i)
{
super(i, ModLoader.getUniqueSpriteIndex("/terrain.png"), Material.portal);
}
public WorldProviderBase getDimension()
{
return new WorldProviderTutorial();
}
public Teleporter getTeleporter()
{
return new TeleporterDesert();
}
public List canTeleportFromDimension()
{
ArrayList list = new ArrayList();
list.add(0);
list.add(-1);
return list;
}
//Указываем что блок портала не твердый и сквозь него можно пройти...
public AxisAlignedBB getCollisionBoundingBoxFromPool(World world, int i, int j, int k)
{
return null;
}
// ... и полу прозрачный
public boolean isOpaqueCube()
{
return false;
}
public boolean displayPortalOverlay()
{
return true;
}
public int getOverlayTexture()
{
return blockIndexInTexture;
}
public String getEnteringMessage()
{
return "Текст при телепортаций в мир";
}
public String getLeavingMessage()
{
return "Текст при телепортаций в обычный мир";
}
}
Теперь создадим файл с именем TeleporterDesert.java
Код взят из Teleport.java и немного подредактирован
package net.minecraft.src;
import java.util.Random;
public class TeleporterDesert extends Teleporter
{
private Random random;
public TeleporterDesert()
{
random = new Random();
}
public void placeInPortal(World world, Entity entity)
{
if (placeInExistingPortal(world, entity))
{
return;
}
else
{
createPortal(world, entity);
placeInExistingPortal(world, entity);
return;
}
}
public boolean placeInExistingPortal(World world, Entity entity)
{
char c = '\200';
double d = -1D;
int i = 0;
int j = 0;
int k = 0;
int l = MathHelper.floor_double(entity.posX);
int i1 = MathHelper.floor_double(entity.posZ);
for (int j1 = l - c; j1 <= l + c; j1++)
{
double d1 = ((double)j1 + 0.5D) - entity.posX;
for (int j2 = i1 - c; j2 <= i1 + c; j2++)
{
double d3 = ((double)j2 + 0.5D) - entity.posZ;
for (int k2 = 128 - 1; k2 >= 0; k2--)
{
if (world.getBlockId(j1, k2, j2) != mod_TutorialDimension.TutorialPortal.blockID)
{
continue;
}
for (; world.getBlockId(j1, k2 - 1, j2) == mod_TutorialDimension.TutorialPortal.blockID; k2--) { }
double d5 = ((double)k2 + 0.5D) - entity.posY;
double d7 = d1 * d1 + d5 * d5 + d3 * d3;
if (d < 0.0D || d7 < d)
{
d = d7;
i = j1;
j = k2;
k = j2;
}
}
}
}
if (d >= 0.0D)
{
int k1 = i;
int l1 = j;
int i2 = k;
double d2 = (double)k1 + 0.5D;
double d4 = (double)l1 + 0.5D;
double d6 = (double)i2 + 0.5D;
if (world.getBlockId(k1 - 1, l1, i2) == mod_TutorialDimension.TutorialPortal.blockID)
{
d2 -= 0.5D;
}
if (world.getBlockId(k1 + 1, l1, i2) == mod_TutorialDimension.TutorialPortal.blockID)
{
d2 += 0.5D;
}
if (world.getBlockId(k1, l1, i2 - 1) == mod_TutorialDimension.TutorialPortal.blockID)
{
d6 -= 0.5D;
}
if (world.getBlockId(k1, l1, i2 + 1) == mod_TutorialDimension.TutorialPortal.blockID)
{
d6 += 0.5D;
}
entity.setLocationAndAngles(d2, d4, d6, entity.rotationYaw, 0.0F);
entity.motionX = entity.motionY = entity.motionZ = 0.0D;
return true;
}
else
{
return false;
}
}
public boolean createPortal(World world, Entity entity)
{
byte byte0 = 16;
double d = -1D;
int i = MathHelper.floor_double(entity.posX);
int j = MathHelper.floor_double(entity.posY);
int k = MathHelper.floor_double(entity.posZ);
int l = i;
int i1 = j;
int j1 = k;
int k1 = 0;
int l1 = random.nextInt(4);
for (int i2 = i - byte0; i2 <= i + byte0; i2++)
{
double d1 = ((double)i2 + 0.5D) - entity.posX;
for (int j3 = k - byte0; j3 <= k + byte0; j3++)
{
double d3 = ((double)j3 + 0.5D) - entity.posZ;
for (int k4 = 128 - 1; k4 >= 0; k4--)
{
if (!world.isAirBlock(i2, k4, j3))
{
continue;
}
for (; k4 > 0 && world.isAirBlock(i2, k4 - 1, j3); k4--) { }
label0:
for (int k5 = l1; k5 < l1 + 4; k5++)
{
int l6 = k5 % 2;
int i8 = 1 - l6;
if (k5 % 4 >= 2)
{
l6 = -l6;
i8 = -i8;
}
for (int j9 = 0; j9 < 3; j9++)
{
for (int k10 = 0; k10 < 4; k10++)
{
for (int l11 = -1; l11 < 4; l11++)
{
int j12 = i2 + (k10 - 1) * l6 + j9 * i8;
int l12 = k4 + l11;
int j13 = (j3 + (k10 - 1) * i8) - j9 * l6;
if (l11 < 0 && !world.getBlockMaterial(j12, l12, j13).isSolid() || l11 >= 0 && !world.isAirBlock(j12, l12, j13))
{
break label0;
}
}
}
}
double d5 = ((double)k4 + 0.5D) - entity.posY;
double d7 = d1 * d1 + d5 * d5 + d3 * d3;
if (d < 0.0D || d7 < d)
{
d = d7;
l = i2;
i1 = k4;
j1 = j3;
k1 = k5 % 4;
}
}
}
}
}
if (d < 0.0D)
{
for (int j2 = i - byte0; j2 <= i + byte0; j2++)
{
double d2 = ((double)j2 + 0.5D) - entity.posX;
for (int k3 = k - byte0; k3 <= k + byte0; k3++)
{
double d4 = ((double)k3 + 0.5D) - entity.posZ;
for (int l4 = 128 - 1; l4 >= 0; l4--)
{
if (!world.isAirBlock(j2, l4, k3))
{
continue;
}
for (; l4 > 0 && world.isAirBlock(j2, l4 - 1, k3); l4--) { }
label1:
for (int l5 = l1; l5 < l1 + 2; l5++)
{
int i7 = l5 % 2;
int j8 = 1 - i7;
for (int k9 = 0; k9 < 4; k9++)
{
for (int l10 = -1; l10 < 4; l10++)
{
int i12 = j2 + (k9 - 1) * i7;
int k12 = l4 + l10;
int i13 = k3 + (k9 - 1) * j8;
if (l10 < 0 && !world.getBlockMaterial(i12, k12, i13).isSolid() || l10 >= 0 && !world.isAirBlock(i12, k12, i13))
{
break label1;
}
}
}
double d6 = ((double)l4 + 0.5D) - entity.posY;
double d8 = d2 * d2 + d6 * d6 + d4 * d4;
if (d < 0.0D || d8 < d)
{
d = d8;
l = j2;
i1 = l4;
j1 = k3;
k1 = l5 % 2;
}
}
}
}
}
}
int k2 = k1;
int l2 = l;
int i3 = i1;
int l3 = j1;
int i4 = k2 % 2;
int j4 = 1 - i4;
if (k2 % 4 >= 2)
{
i4 = -i4;
j4 = -j4;
}
if (d < 0.0D)
{
if (i1 < 70)
{
i1 = 70;
}
if (i1 > 128 - 10)
{
i1 = 128 - 10;
}
i3 = i1;
for (int i5 = -1; i5 <= 1; i5++)
{
for (int i6 = 1; i6 < 3; i6++)
{
for (int j7 = -1; j7 < 3; j7++)
{
int k8 = l2 + (i6 - 1) * i4 + i5 * j4;
int l9 = i3 + j7;
int i11 = (l3 + (i6 - 1) * j4) - i5 * i4;
boolean flag = j7 < 0;
// Block.stone.blockID - блок из которого состоит портал
world.setBlockWithNotify(k8, l9, i11, flag ? Block.stone.blockID : 0);
}
}
}
}
for (int j5 = 0; j5 < 4; j5++)
{
world.editingBlocks = true;
for (int j6 = 0; j6 < 4; j6++)
{
for (int k7 = -1; k7 < 4; k7++)
{
int l8 = l2 + (j6 - 1) * i4;
int i10 = i3 + k7;
int j11 = l3 + (j6 - 1) * j4;
boolean flag1 = j6 == 0 || j6 == 3 || k7 == -1 || k7 == 3;
world.setBlockWithNotify(l8, i10, j11, flag1 ? Block.stone.blockID : mod_TutorialDimension.TutorialPortal.blockID);
}
}
world.editingBlocks = false;
for (int k6 = 0; k6 < 4; k6++)
{
for (int l7 = -1; l7 < 4; l7++)
{
int i9 = l2 + (k6 - 1) * i4;
int j10 = i3 + l7;
int k11 = l3 + (k6 - 1) * j4;
world.notifyBlocksOfNeighborChange(i9, j10, k11, world.getBlockId(i9, j10, k11));
}
}
}
return true;
}
}
Теперь создадим WorldProviderTutorial.java
package net.minecraft.src;
import java.util.Random;
public class WorldProviderTutorial extends WorldProviderBase
{
public WorldProviderTutorial()
{
}
//Айди измерение
public int getDimensionID()
{
return 65;
}
//Биом который будет в измерений, если "desert" заменить на "taiga" то будет вместо пустиыни тайга
public void registerWorldChunkManager()
{
worldChunkMgr = new WorldChunkManagerHell(BiomeGenBase.desert, 1.0F, 0.0F);
}
//Здесь можно указать настроики генераций
public IChunkProvider getChunkProvider()
{
return new ChunkProviderTutorial(worldObj, worldObj.getSeed());
}
public boolean canRespawnHere()
{
return false;
}
}
Теперь создадим файл ChunkProviderTutorial.java
Код взят из ChunkProviderDesert.java
package net.minecraft.src;
import java.util.List;
import java.util.Random;
public class ChunkProviderTutorial extends ChunkProviderGenerate
implements IChunkProvider
{
private Random rand;
private World worldObj;
private MapGenBase caveGenerator;
private MapGenBase ravineGenerator;
private BiomeGenBase biomesForGeneration[];
public ChunkProviderTutorial(World world, long l)
{
super(world, l, true);
worldObj = world;
rand = new Random(l);
caveGenerator = new MapGenCaves();
ravineGenerator = new MapGenRavine();
}
//This is necessary to override the structure generator.
public Chunk provideChunk(int par1, int par2)
{
rand.setSeed((long)par1 * 0x4f9939f508L + (long)par2 * 0x1ef1565bd5L);
byte abyte0[] = new byte[32768];
generateTerrain(par1, par2, abyte0);
biomesForGeneration = worldObj.getWorldChunkManager().loadBlockGeneratorData(biomesForGeneration, par1 * 16, par2 * 16, 16, 16);
replaceBlocksForBiome(par1, par2, abyte0, biomesForGeneration);
caveGenerator.generate(this, worldObj, par1, par2, abyte0);
ravineGenerator.generate(this, worldObj, par1, par2, abyte0);
Chunk chunk = new Chunk(worldObj, abyte0, par1, par2);
chunk.generateSkylightMap();
return chunk;
}
public void populate(IChunkProvider ichunkprovider, int i, int j)
{
BlockSand.fallInstantly = true;
int k = i * 16;
int l = j * 16;
BiomeGenBase biomegenbase = worldObj.getWorldChunkManager().getBiomeGenAt(k + 16, l + 16);
rand.setSeed(worldObj.getSeed());
long l1 = (rand.nextLong() / 2L) * 2L + 1L;
long l2 = (rand.nextLong() / 2L) * 2L + 1L;
rand.setSeed((long)i * l1 + (long)j * l2 ^ worldObj.getSeed());
boolean flag = false;
if (!flag && rand.nextInt(4) == 0)
{
int i1 = k + rand.nextInt(16) + 8;
int j2 = rand.nextInt(128);
int k3 = l + rand.nextInt(16) + 8;
(new WorldGenLakes(Block.waterStill.blockID)).generate(worldObj, rand, i1, j2, k3);
}
if (!flag && rand.nextInt(8) == 0)
{
int j1 = k + rand.nextInt(16) + 8;
int k2 = rand.nextInt(rand.nextInt(128 - 8) + 8);
int l3 = l + rand.nextInt(16) + 8;
if (k2 < 63 || rand.nextInt(10) == 0)
{
(new WorldGenLakes(Block.lavaStill.blockID)).generate(worldObj, rand, j1, k2, l3);
}
}
for (int k1 = 0; k1 < 8; k1++)
{
int i3 = k + rand.nextInt(16) + 8;
int i4 = rand.nextInt(128);
int k4 = l + rand.nextInt(16) + 8;
if (!(new WorldGenDungeons()).generate(worldObj, rand, i3, i4, k4));
}
biomegenbase.decorate(worldObj, rand, k, l);
SpawnerAnimals.performWorldGenSpawning(worldObj, biomegenbase, k + 8, l + 8, 16, 16, rand);
k += 8;
l += 8;
BlockSand.fallInstantly = false;
}
public ChunkPosition func_40376_a(World world, String s, int i, int j, int k)
{
return null;
}
}
Так как проблемы с созданием портала я не решил то времено пока сделал так. Если скрафтить блок Tutorial Create Portal и зажечь его появиться портал. В коде нет ничего сложно так что расписывать не стал
BlockTutorialCreatePortal.java
package net.minecraft.src;
import java.util.Random;
import net.minecraft.client.Minecraft;
public class BlockTutorialCreatePortal extends Block
{
protected BlockTutorialCreatePortal(int i, int j)
{
super(i, j, Material.rock);
}
public boolean blockActivated(World world, int i, int j, int k, EntityPlayer entityplayer)
{
if (isOpen(world, i, j, k))
{
destroyPortal(world, i, j, k);
}
else
{
ItemStack itemstack = entityplayer.getCurrentEquippedItem();
if (itemstack == null)
{
return false;
}
if (itemstack.itemID == Item.flintAndSteel.shiftedIndex && createPortal(world, i, j, k))
{
itemstack.damageItem(1, entityplayer);
}
}
return true;
}
private boolean createPortal(World world, int i, int j, int k)
{
Minecraft minecraft = ModLoader.getMinecraftInstance();
int l = minecraft.thePlayer.dimension;
if (l == 0 || l == 5)
{
Portal(world, i, j, k);
return true;
}
else
{
return false;
}
}
public static void Portal(World world, int i, int j, int k)
{
world.setBlock(i, j, k - 1, 1);
world.setBlock(i, j + 1, k - 1, 1);
world.setBlock(i, j + 2, k - 1, 1);
world.setBlock(i, j + 3, k - 1, 1);
world.setBlock(i, j + 4, k - 1, 1);
world.setBlock(i, j, k, 1);
world.setBlock(i, j + 1, k, 220);
world.setBlock(i, j + 2, k, 220);
world.setBlock(i, j + 3, k, 220);
world.setBlock(i, j + 4, k, 1);
world.setBlock(i, j, k + 1, 1);
world.setBlock(i, j + 1, k + 1, 220);
world.setBlock(i, j + 2, k + 1, 220);
world.setBlock(i, j + 3, k + 1, 220);
world.setBlock(i, j + 4, k + 1, 1);
world.setBlock(i, j, k + 2, 1);
world.setBlock(i, j + 1, k + 2, 1);
world.setBlock(i, j + 2, k + 2, 1);
world.setBlock(i, j + 3, k + 2, 1);
world.setBlock(i, j + 4, k + 2, 1);
}
private void destroyPortal(World world, int i, int j, int k)
{
if (!isOpen(world, i, j, k))
{
return;
}
else
{
Portal(world, i, j + 1, k);
return;
}
}
public int quantityDropped(Random random)
{
return 1;
}
public int idDropped(int i, Random random)
{
return mod_TutorialDimension.TutorialCreatePortal.blockID;
}
public boolean isOpen(World world, int i, int j, int k)
{
return world.getBlockMetadata(i, j, k) == 1;
}
}
Ошибок не нашёл если есть пишите исправлю!