Server Minecraft

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » Server Minecraft » Архив » Моддинг Без МодЛоадера


Моддинг Без МодЛоадера

Сообщений 1 страница 4 из 4

Опрос

Продолжать ли писать туторы по моддингу
Да

100% - 1 Нет

0% - 0
Да

100% - 1 Нет

0% - 0
Голосов: 1; Проголосовали: 3

1

Я всё же решился начать писать мод без использования сторонних модов типо ModLoader и Forge.

Данный туториал пишется для клиента версии 1.2.5. Все коды рабочие, сам использую их в своём моде.

1. Добавление своего блока в игру

1. Вам нужно создать новый файл под именем BlockNew.java в папке src.

2. Вот пример:
package net.minecraft.src;
import java.util.Random;
public class BlockNew extends Block
{
        public BlockNew(int par1, int par2)
        {
                super(par1, par2, Material.rock);
        }
        /**
         * Returns the ID of the items to drop on destruction.
         */
        public int idDropped(int par1, Random par2Random, int par3)
        {
                return Block.new.blockID;
        }
}
3. Теперь нужно добавить ваш блок непосредственно в Block.java

Ищем строчку
        public static final Block redstoneLampActive;
Добавляем после неё
        public static final Block new;
Теперь идём в конец файла и ищем Item. ...
Item.itemsList[cloth.blockID] = (new ItemCloth(cloth.blockID - 256)).setItemName("cloth");
Над ним вставляем:
mramor = (new BlockNew(161, 8)).setHardness(2.0F).setResistance(4F).setStepSound(soundGlassFootstep).setBlockName("new").setRequiresSelfNotify();Где:
161 - ID блока (свободные номера начинаются с 160)
8 - номер текстуры в terrain.png
setHardness(2.0F) - прочность ()
.setResistance(4F) - сопротивление
.setStepSound(soundGlassFootstep) - звук при разбиении
.setBlockName("new") - имя блока (для перевода через lang-файл)
.setLightValue(1.0F) - свечение блока

2. Создание нового рецепта крафтинга

1. Откройте CraftingManager.java

Ищем что-то похожее на(вверху):
                addRecipe(new ItemStack(Item.paper, 3), new Object[]
                                {
                                        "###", '#', Item.reed
                                });
Добавляем после него рецепт для нашего только что созданного блока
                addRecipe(new ItemStack(Block.new, 1), new Object[]
                                {
                                        "###","###","###", '#', Block.dirt
                                });Где 1 - кол-во получаемого блока после крафта

3. Добавление блока в лист креативного режима

Открываем файл ContainerCreative.java
В самом верху видим:
                itemList = new ArrayList();
                Block ablock[] =
                {
                        Block.cobblestone, Block.stone, Block.oreDiamond, Block.oreGold, Block.oreIron, Block.oreCoal, Block.oreLapis, Block.oreRedstone, Block.stoneBrick, Block.stoneBrick,
                        Block.stoneBrick, Block.stoneBrick, Block.blockClay, Block.blockDiamond, Block.blockGold, Block.blockSteel, Block.bedrock, Block.blockLapis, Block.brick, Block.cobblestoneMossy,
                        Block.stairSingle, Block.stairSingle, Block.stairSingle, Block.stairSingle, Block.stairSingle, Block.stairSingle, Block.obsidian, Block.netherrack, Block.slowSand, Block.glowStone,
                        Block.wood, Block.wood, Block.wood, Block.wood, Block.leaves, Block.leaves, Block.leaves, Block.leaves, Block.dirt, Block.grass,
                        Block.sand, Block.sandStone, Block.sandStone, Block.sandStone, Block.gravel, Block.web, Block.planks, Block.planks, Block.planks, Block.planks,
                        Block.sapling, Block.sapling, Block.sapling, Block.sapling, Block.deadBush, Block.sponge, Block.ice, Block.blockSnow, Block.plantYellow, Block.plantRed,
                        Block.mushroomBrown, Block.mushroomRed, Block.cactus, Block.melon, Block.pumpkin, Block.pumpkinLantern, Block.vine, Block.fenceIron, Block.thinGlass, Block.netherBrick,
                        Block.netherFence, Block.stairsNetherBrick, Block.whiteStone, Block.mycelium, Block.waterlily, Block.tallGrass, Block.tallGrass, Block.chest, Block.workbench, Block.glass,
                        Block.tnt, Block.bookShelf, Block.cloth, Block.cloth, Block.cloth, Block.cloth, Block.cloth, Block.cloth, Block.cloth, Block.cloth,
                        Block.cloth, Block.cloth, Block.cloth, Block.cloth, Block.cloth, Block.cloth, Block.cloth, Block.cloth, Block.dispenser, Block.stoneOvenIdle,
                        Block.music, Block.jukebox, Block.pistonStickyBase, Block.pistonBase, Block.fence, Block.fenceGate, Block.ladder, Block.rail, Block.railPowered, Block.railDetector,
                        Block.torchWood, Block.stairCompactPlanks, Block.stairCompactCobblestone, Block.stairsBrick, Block.stairsStoneBrickSmooth, Block.lever, Block.pressurePlateStone, Block.pressurePlatePlanks, Block.torchRedstoneActive, Block.button,
                        Block.trapdoor, Block.enchantmentTable, Block.redstoneLampIdle
                };
И добавляем в этот список наш блок (или предмет)

, Block.new

4. Добавление блока в генерацию мира

1. Открываем файл BiomeDecorator.java
Ищем
protected WorldGenerator dirtGen;
Добавляем после
protected WorldGenerator newGen;
Ищем
dirtGen = new WorldGenMinable(Block.dirt.blockID, 32);
Добавляем после
mramorGen = new WorldGenMinable(Block.new.blockID, 2); //Кол-во блоков в одном месторождении
Идём в самый конец файла и ищем
genStandardOre1(20, dirtGen, 0, 128);
Вставляем после:
genStandardOre1(20, mramorGen, 0, 128);Где 0 минимальная высота, а 128 - максимальная, до куда будет генерироваться блок. Т.е с нулевой высоты по 128 будет генерироваться наш блок

5. Добавление имени блоку

Скрытый текст 

Открываем minecraft.jar, папку lang и нужный файл языка. К примеру ru_RU.lang
Листаем ниже и находим такой код:
tile.waterlily.name=Кувшинка
tile.dragonEgg.name=Яйцо дракона
tile.redstoneLight.name=Лампа
И добавляем по аналогии наше название блока! В title.*** пишутся имена блоков!

tile.new.name=Новый блокtile.new.name - имя блока, которое мы использовали тут (когда создавами сам блок):
Цитата
.setBlockName("new").
Теперь припишем имя к предмету (внизу описан предмет - роза, ну для него и напишем имя)
Чуть ниже ищем строки:
item.shovelIron.name=Железная лопата
item.pickaxeIron.name=Железная кирка
item.hatchetIron.name=Железный топорИ добавляем по аналогии наше название предмета! В item.*** пишутся имена редметов!

item.rose.name=Колючая розаitem.rose.name - имя предмета, которое мы использовали при создании предмета (тут)
Цитата
.setItemName("rose")
Самое важное забыл сказать!
Удаляем из minecraft.jar папку META-INF так как в ней хренится кеш файлов lang.
Если не удалите её, то будет много ошибок!

Как только напишу тутор как создать свой предмет - опишу присвоение имени.

6. Добавление своего файла крафтинга

1. Открываем файл CraftingManager.java
Ищем
(new RecipesDyes()).addRecipes(this);
Добавляем после
(new RecipesMyRecipes()).addRecipes(this);

2. Создаём файл с таким же именем как указали выше - RecipesMyRecipes.java

3. Добавляем в файл следующие строки

package net.minecraft.src;

public class RecipesMyRecipes
{
        public RecipesMyRecipes()
        {
        }

        /**
         * Adds the food recipes to the CraftingManager.
         */
        public void addRecipes(CraftingManager CraftingManager)
        {
                CraftingManager.addRecipe(new ItemStack(Block.new, 6), new Object[]
                                {
                                        "###", "###", "###", '#', Block.dirt
                                });
        }
}
Думаю, если вы читали уроки по созданию модов на ModLoader, там описывался крафтинг

7. Создание своего растения

1. Открываем файл Block.java

2. Добавляем новый блок как описано выше
Пример
roseblock = new BlockRose(162, 168).setHardness(0.5F).setResistance(0.3F).setLightValue(0F).setBlockName("rose");
3. Создаём файл с названием BlockRose (в нашем случае)

4. Добавляем в файл следующие строки

package net.minecraft.src;

import java.util.Random;

public class BlockRose extends Block
{
         protected BlockRose(int par1, int par2)
         {
                 super(par1, Material.plants);//материал растение
                 blockIndexInTexture = par2;
                 float f = 0.375F;
                 setBlockBounds(0.5F - f, 0.0F, 0.5F - f, 0.5F + f, 1.0F, 0.5F + f);
                 setTickRandomly(true);
         }

        /**
         * Ticks the block if it's been scheduled
         */
        public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random)//Это сам алгоритм роста.
        {
                if (par1World.isAirBlock(par2, par3 + 1, par4))
                {
                        int i;

                        for (i = 1; par1World.getBlockId(par2, par3 - i, par4) == blockID; i++) { }

                        if (i < 5)//Вырастает до 4-х блоков
                        {
                                int j = par1World.getBlockMetadata(par2, par3, par4);

                                if (j == 15)
                                {
                                        par1World.setBlockWithNotify(par2, par3 + 1, par4, blockID);
                                        par1World.setBlockMetadataWithNotify(par2, par3, par4, 0);
                                }
                                else
                                {
                                        par1World.setBlockMetadataWithNotify(par2, par3, par4, j + 1);
                                }
                        }
                }
        }

        /**
         * Checks to see if its valid to put this block at the specified coordinates. Args: world, x, y, z
         */
        public boolean canPlaceBlockAt(World par1World, int x, int y, int z)//можно ли ставить блок
        {
         int i = par1World.getBlockId(x, y - 1, z);

         if((par1World.getBlockId(x, y-1, z) == blockID)||(par1World.getBlockId(x, y-1, z) == Block.dirt.blockID)||(par1World.getBlockId(x, y-1, z) == Block.grass.blockID))
                return true;
         
         return false;//да
        }

        /**
         * Lets the block know when one of its neighbor changes. Doesn't know which neighbor changed (coordinates passed are
         * their own) Args: x, y, z, neighbor blockID
         */
        public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5)
        {
                checkBlockCoordValid(par1World, par2, par3, par4);
        }

        /**
         * Checks if current block pos is valid, if not, breaks the block as dropable item. Used for reed and cactus.
         */
        protected final void checkBlockCoordValid(World par1World, int par2, int par3, int par4)
        {
                if (!canBlockStay(par1World, par2, par3, par4))
                {
                        dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0);
                        par1World.setBlockWithNotify(par2, par3, par4, 0);
                }
        }

        /**
         * Can this block stay at this position.  Similar to canPlaceBlockAt except gets checked often with plants.
         */
        public boolean canBlockStay(World par1World, int x, int y, int z) //где можно будет посадить растение
        {
                if((par1World.getBlockId(x, y-1, z) == blockID)||(par1World.getBlockId(x, y-1, z) == Block.dirt.blockID)||(par1World.getBlockId(x, y-1, z) == Block.grass.blockID))
                        return true;
                 
                        return false;
        }
        public void onEntityCollidedWithBlock(World par1World, int x, int y, int z, Entity par5Entity)
        {
                 par5Entity.attackEntityFrom(DamageSource.cactus, 1);//атака игрока
                 
        }
        /**
         * Returns a bounding box from the pool of bounding boxes (this means this box can change after the pool has been
         * cleared to be reused)
         */
        public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int i)//оптическая рамка
        {
                return null;
        }

        /**
         * Returns the ID of the items to drop on destruction.
         */
        public int idDropped(int par1, Random par2Random, int par3)//выбрасываем по id
        {
                return Item.rose.shiftedIndex;
        }

        public boolean isOpaqueCube()//делаем блок непрозрачным
        {
                return false;
        }

        /**
         * If this block doesn't render as an ordinary block it will return False (examples: signs, buttons, stairs, etc)
         */
        public boolean renderAsNormalBlock()
        {
                return false;
        }

        /**
         * The type of render function that is called for this block
         */
        public int getRenderType()
        {
                return 1;
        }
}

8. Создание моба (враждебный и дружелюбный)

Создаём файл EntityMobNew.java
package net.minecraft.src;

import java.util.Random;

public class EntityMobNew extends EntityMob // если хотите мирного моба, то пишите - public class EntityMobNew extends EntityCreature
{
        /** The ItemStack that any Skeleton holds (a bow). */
        private static final ItemStack defaultHeldItem;

        public EntityMobNew(World par1World)
        {
                super(par1World);
                texture = "/mob/new.png";//скин для моба
                moveSpeed = 0.2F;//скорость перемещения
                attackStrength = 4; //атака игрока //только для враждебного моба (если мирный, то удалите)
                getNavigator().func_48664_a(true);
                tasks.addTask(0, new EntityAISwimming(this));
                tasks.addTask(1, new EntityAIBreakDoor(this));
                tasks.addTask(2, new EntityAIAttackOnCollide(this, net.minecraft.src.EntityPlayer.class, moveSpeed, false)); //только для враждебного моба (если мирный, то удалите)
                //tasks.addTask(2, new EntityAIRestrictSun(this));//горит на солнце
                //tasks.addTask(3, new EntityAIFleeSun(this, moveSpeed));//бежит от солнца
                tasks.addTask(3, new EntityAIWander(this, moveSpeed));
                tasks.addTask(4, new EntityAIWatchClosest(this, net.minecraft.src.EntityPlayer.class, 8F));
                tasks.addTask(5, new EntityAILookIdle(this));
                targetTasks.addTask(1, new EntityAIHurtByTarget(this, false));
                targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, net.minecraft.src.EntityPlayer.class, 16F, 0, true));//только для враждебного моба (если мирный, то удалите)
                tasks.addTask(3, new EntityAIAttackOnCollide(this, net.minecraft.src.EntityZombie.class, moveSpeed, true));//атакует зомби только для враждебного моба (если мирный, то удалите)
                targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, net.minecraft.src.EntityZombie.class, 16F, 0, false)); //только для враждебного моба (если мирный, то удалите)
                tasks.addTask(3, new EntityAIAttackOnCollide(this, net.minecraft.src.EntitySkeleton.class, moveSpeed, true));//атакует скелетов только для враждебного моба (если мирный, то удалите)
                targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, net.minecraft.src.EntitySkeleton.class, 16F, 0, false));//только для враждебного моба (если мирный, то удалите)
                tasks.addTask(3, new EntityAIAttackOnCollide(this, net.minecraft.src.EntitySpider.class, moveSpeed, true));//атакует пауков только для враждебного моба (если мирный, то удалите)
                targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, net.minecraft.src.EntitySpider.class, 16F, 0, false));//только для враждебного моба (если мирный, то удалите)
        }

        /**
         * Returns true if the newer Entity AI code should be run
         */
        public boolean isAIEnabled()
        {
                return true;
        }

        public int getMaxHealth()
        {
                return 100; //ХП моба
        }

        /**
         * Returns the sound this mob makes while it's alive.
         */
        protected String getLivingSound()
        {
                return "mob.zombie"; //постоянное издевание звуков
        }

        /**
         * Returns the sound this mob makes when it is hurt.
         */
        protected String getHurtSound()
        {
                return "mob.zombiehurt";//звук при получении урона
        }

        /**
         * Returns the sound this mob makes on death.
         */
        protected String getDeathSound()
        {
                return "mob.zombiedeath";//звук при смерти
        }
         
        /**
         * Get this Entity's EnumCreatureAttribute
         */
        public EnumCreatureAttribute getCreatureAttribute()
        {
                return EnumCreatureAttribute.UNDEAD;
        }

        /**
         * Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons
         * use this to react to sunlight and start to burn.
         */
        public void onLivingUpdate()
        {
                super.onLivingUpdate();
        }

        /**
         * Returns the item ID for the item the mob drops on death.
         */
        protected int getDropItemId() //обязательный дроп той или иной вещи
        {
                return Item.arrow.shiftedIndex;
        }

        protected void dropRareDrop(int par1)//рандомный дроп вещей после смерти моба
        {
                switch (rand.nextInt(4))
                {
                        case 0:
                                dropItem(Item.swordSteel.shiftedIndex, 1);
                                break;

                        case 1:
                                dropItem(Item.helmetSteel.shiftedIndex, 1);
                                break;

                        case 2:
                                dropItem(Item.ingotIron.shiftedIndex, 1);
                                break;

                        case 3:
                                dropItem(Item.shovelSteel.shiftedIndex, 1);
                                break;
                }
        }

        static
        {
        }
}Идём в файлик EntityList.java (тут создаём яйцо для моба)
Ищем:
addMapping(net.minecraft.src.EntityEnderCrystal.class, "EnderCrystal", 200);Добавляем ниже:
addMapping(net.minecraft.src.EntityMobNew.class, "MobNew", 101, 0xc1c1c1, 0x7FFF00);Где 0xc1c1c1 - основной цвет яйца; 0x7FFF00 - цвет внешней части яйца. Везде 0x - обязательно оставляйте. Всё что после - обычная цветовая гамма HTML
Теперь идём в файл генерации мира BiomeGenForest.java (указываем где будет спавниться моб. В нашем случае в лесу)
Ищем:
spawnableCreatureList.add(new SpawnListEntry(net.minecraft.src.EntityWolf.class, 5, 4, 4));Ниже добавляем:
spawnableCreatureList.add(new SpawnListEntry(net.minecraft.src.EntityMobNew.class, 2, 1, 1));Если моб у нас враждебный, то меняем CreatureList на MonsterList (моб будет спавниться ночью)
Если вы хотите, что бы моб спавнился везде, то идём в BiomeGenBase.java
Ищем:
spawnableMonsterList.add(new SpawnListEntry(net.minecraft.src.EntitySkeleton.class, 10, 4, 4));Ниже добавляем:
spawnableCreatureList.add(new SpawnListEntry(net.minecraft.src.EntityMobNew.class, 4, 2, 5));опять же, если моб у нас враждебный, то меняем CreatureList на MonsterList (моб будет спавниться ночью)


!!! Не забываем добавить сам скин моба в папку mob !!!

Если у вас сделан моб, не похожий на человека или любого другого прямоходящего, то вам придётся соединить все части моба. Но перед тем как делать всё по тутору, вы должны создать файл ModelMobNew.java (по аналогии к примеру даже с тем же Ocelot)
Скрытый текст 
Идем в файл RenderManager.java
Ищем:
entityRenderMap.put(net.minecraft.src.EntityLightningBolt.class, new RenderLightningBolt());Дописываем ниже:
entityRenderMap.put(net.minecraft.src.EntityMobNew.class, new RenderMobNew(new ModelMobNew(), 0.4F));

9. Создание своего биома (Добавлено)

 
1. Вам нужно создать новый файл под именем BiomeGenNewBiome.java

Пример файла:
package net.minecraft.src;

import java.util.List;

public class BiomeGenNewBiome extends BiomeGenBase
{
        public BiomeGenNewBiome(int par1)
        {
                super(par1);
                spawnableCreatureList.clear();//либо запрещаем спавнится мобам, либо удаляем и вставляем то, что ниже
                spawnableCreatureList.add(new SpawnListEntry(net.minecraft.src.EntityWolf.class, 5, 4, 4));//Разрешаем спавнится волку в этом биоме (или удалите, тогда оставьте то, что выше)
                topBlock = (byte)Block.blockGold.blockID; //это верхний слой блоков, первое что вы увидите, будет этот блок
                fillerBlock = (byte)Block.blockGold.blockID;//слой толщиной 3-5 блоков под topBlock
                biomeDecorator.treesPerChunk = 10; //количество деревьев на 1 чанк
                biomeDecorator.grassPerChunk = 2; //количество травы на 1 чанк
        }
}
3. Теперь нужно добавить ваш новый биом в BiomeGenBase.java

Ищем строчку
        public static final BiomeGenBase jungleHills = (new BiomeGenJungle(22)).setColor(0x2c4205).setBiomeName("JungleHills").func_4124_a(0x537b09).setTemperatureRainfall(1.2F, 0.9F).setMinMaxHeight(1.8F, 0.2F);
Добавляем после неё
        public static final BiomeGenBase newBiome = (new BiomeGenNewBiome(23)).setColor(0xfade55).setBiomeName("NewBiome").setTemperatureRainfall(0.8F, 0.4F).setMinMaxHeight(0.0F, 0.1F);Где:
newBiome - само название биома
23 - ID биома (Пишите свободные номера, по стандарту свободные начинаются с 23)
setColor - цвет биома (0x обязательно должно быть, всё остальное - код цвета HTML)
setTemperatureRainfall - температура на биоме
setMinMaxHeight - минимальная и максимальная высота биома

4. Теперь идём в файл GenLayerBiome (в нём прописываем, что бы ваш биом появился в мире)
Ищем:
BiomeGenBase.taiga,
После, вставляем:
BiomeGenBase.newBiomeТам две строчки похожие, вставляем и там и там


Коды все рабочие и протестированные!

P.S Тема будет пополняться со временем, так как я сначала делаю, потом выкладываю.

 


--------------------------------------------------------------------------------
Важно! "Большинство модов после этого изменения клиента работать уже не будет" и "Если обновите клиент, то ваши модификации удалятся"

И не делайте всё под Copy-Paste пытайтесь сами понять что к чему!
--------------------------------------------------------------------------------

Отредактировано Дмитрий (2012-07-22 10:57:51)

0

2

отличный туториал! ты занимаешся профессионально программированием?
мне по душе такие туториалы!

0

3

Спасибо

0

4

administrator написал(а):

отличный туториал! ты занимаешся профессионально программированием?
мне по душе такие туториалы!

Нет не занимаюсь профессионально просто хобби
Скоро будет как создать новую жидкость (С мод лоадером)

0


Вы здесь » Server Minecraft » Архив » Моддинг Без МодЛоадера