Перейти к содержимому


Фотография

[РАЗРАБОТКА] Факело-мёт


  • Авторизуйтесь для ответа в теме
Сообщений в теме: 18

#1 LordKmon

LordKmon

    Странник

  • Пользователи
  • Сообщений: 24

Написал 17.05.2011 - 17:56

разработка забавного, и в тоже время полезного предмета - Факелометного ружья.

Стреляет оно факелам, которые при попадании в блок "устанавливаются" на него. Здесь стоит отметить существенное отличие от стрел, которые просто в произвольном порядке втыкаются в объект.
Здесь речь пойдет именно об корректной установки факела на блок. То же самое что и рукой, но только на расстоянии выстрела.

Как оно принципиально устроено?

ItemTorchGun ( аналог лука) стреляет снарядами EntityFlyTorch (аналог EntityArrow)
Но в отличие от обычной стрелы , у EntityFlyTorch в методе onUpdate
в окрестности этого куска кода:

xTile = movingobjectposition[paste][/paste]blockX;                yTile = movingobjectposition[paste][/paste]blockY;                zTile = movingobjectposition[paste][/paste]blockZ;                inTile = worldObj[paste][/paste]getBlockId(xTile, yTile, zTile);                motionX = (float)(movingobjectposition[paste][/paste]hitVec[paste][/paste]xCoord - posX);                motionY = (float)(movingobjectposition[paste][/paste]hitVec[paste][/paste]yCoord - posY);                motionZ = (float)(movingobjectposition[paste][/paste]hitVec[paste][/paste]zCoord - posZ);                float f1 = MathHelper[paste][/paste]sqrt_double(motionX * motionX + motionY * motionY + motionZ * motionZ);                posX -= (motionX / (double)f1) * 0[paste][/paste]05000000074505806D;                posY -= (motionY / (double)f1) * 0[paste][/paste]05000000074505806D;                posZ -= (motionZ / (double)f1) * 0[paste][/paste]05000000074505806D;                worldObj[paste][/paste]playSoundAtEntity(this, "random[paste][/paste]drr", 1[paste][/paste]0F, 1[paste][/paste]2F / (rand[paste][/paste]nextFloat() * 0[paste][/paste]2F + 0[paste][/paste]9F));                inGround = true;                arrowShake = 7;
произведено существенное изменение - а именно :

1. inTile = worldObj.getBlockId(xTile, yTile, zTile); - эта строчка говорит о том, что мы с легкостью можем получить ID блока на который нам надо установить факел.
Следовательно, прямо в этот блок мы можем дописать команду которая создает блок BlockTorch и ставит его на указанный ID блока в которого воткнулся наш EntityFlyTorch

2. В конце этого куска нам необходимо дописать setEntityDead();, чтобы наш факел исчез как снаряд, и остался только блок BlockTorch (установленный факел на стене)


В принципе всё просто и легко, НО сложности возникают с первым пунктом - какими командами установить блок ?

Давайте обратимся классу ItemBolck. там есть такая функция :

public boolean onItemUse(ItemStack itemstack, EntityPlayer entityplayer, World world, int i, int j, int k, int l)    {        if(world[paste][/paste]getBlockId(i, j, k) == Block[paste][/paste]snow[paste][/paste]blockID)        {            l = 0;        } else        {            if(l == 0)            {                j--;            }            if(l == 1)            {                j++;            }            if(l == 2)            {                k--;            }            if(l == 3)            {                k++;            }            if(l == 4)            {                i--;            }            if(l == 5)            {                i++;            }        }        if(itemstack[paste][/paste]stackSize == 0)        {            return false;        }        if(world[paste][/paste]canBlockBePlacedAt(blockID, i, j, k, false))        {            Block block = Block[paste][/paste]blocksList[blockID];            if(world[paste][/paste]setBlockAndMetadataWithNotify(i, j, k, blockID, func_21012_a(itemstack[paste][/paste]getItemDamage())))            {                Block[paste][/paste]blocksList[blockID][paste][/paste]onBlockPlaced(world, i, j, k, l);                Block[paste][/paste]blocksList[blockID][paste][/paste]onBlockPlacedBy(world, i, j, k, entityplayer);                world[paste][/paste]playSoundEffect((float)i + 0[paste][/paste]5F, (float)j + 0[paste][/paste]5F, (float)k + 0[paste][/paste]5F, block[paste][/paste]stepSound[paste][/paste]func_1145_d(), (block[paste][/paste]stepSound[paste][/paste]func_1147_b() + 1[paste][/paste]0F) / 2[paste][/paste]0F, block[paste][/paste]stepSound[paste][/paste]func_1144_c() * 0[paste][/paste]8F);                itemstack[paste][/paste]stackSize--;            }            return true;        } else        {            return false;        }    }

первая часть кода мне не известна, а вот во второй - происходит проверка можно ли в заданных координатах поставить блок, затем блок ставится и проигрывается звук установки блока.

Следовательно наш EntityFlyTorch должен проверить if(world.canBlockBePlacedAt(blockID, i, j, k, false)) можно ли там поставить BlockTorch , где i,j,k соответственно равны xTile, yTile, zTile, мне очень хочется надеяться что это именно те координаты которые нужны.

Для того чтобы поставить BlockTorch мы воспользуемся его методом
public void onBlockPlaced(World world, int i, int j, int k, int l)
int i, int j, int k эти параметры мы знаем, а вот откуда взять int l я честно не знаю... эта переменная сильно напоминает на сторону блока,

я пытался лазить по всем java файлам МК, пытаясь найти кто-же передает эти четыре переменные -
самый крайний метод, который я нашел это

public boolean sendPlaceBlock(EntityPlayer entityplayer, World world, ItemStack itemstack, int i, int j, int k, int l)


в классе playerController , мне так и не известно откуда он получает эти int i, int j, int k, int - если кто-нить найдет способ обойтись без них, то плиз отпишитесь в тему.

#2 WDkun

WDkun

    Зачарователь

  • Пользователи
  • Сообщений: 1939

Написал 17.05.2011 - 17:58

Попробуй поставить 0, например.

#3 Dan4eg

Dan4eg

    Добытчик дерева

  • Пользователи
  • Сообщений: 193

Написал 18.05.2011 - 12:07

Что ты объясняешь этой дерёвне?Всё равно они нифига не поняли.
Нотч знает яву.Нотч любит Яву.Нотч ничего и не знает кроме явы.Нотч пишет игры.Получаются неплохие игры, но на яве.Кто виноват и что делать?

#4 MetroiD

MetroiD

    Добытчик светокамня

  • Пользователи
  • Сообщений: 3300
  • Откуда: FROM ZEBES

Написал 18.05.2011 - 14:41

ну почему я понимаюint l помоему это ид блока ну если смотреть команду удаления то это действитьно ид блока который ставитсяи вообще код заманчив попробую реализоватьесли хочешь свяжись я немного обьясню как можно реализовать установку блоказа три дня работы с явой я понял достаточно много чтобы этот код понять

Obscurell - скайп, вк...
Личность успешно существует...
 


#5 Dan4eg

Dan4eg

    Добытчик дерева

  • Пользователи
  • Сообщений: 193

Написал 18.05.2011 - 15:47

Metroid.Я про тебя не говорю.Я говорю почти про весь остальной форум.
Нотч знает яву.Нотч любит Яву.Нотч ничего и не знает кроме явы.Нотч пишет игры.Получаются неплохие игры, но на яве.Кто виноват и что делать?

#6 LordKmon

LordKmon

    Странник

  • Пользователи
  • Сообщений: 24

Написал 19.05.2011 - 17:41

Ребята вы не поверите!!! Мне удалось создать этот факело-мет Нотч
Кстати, спасибо за поддержку, а то я думал, что на этом форуме вообще никого нет кроме WDkun'a =)

Такс, теперь всё по-порядку:

1. Создаем само устройство - TorchGun
в файле item.png подрисовываем картинку факеломета - я на правах автора выбрал такую =)

просто лук, как пусковое устройство и две палки в качестве лотка для факела - делается легко и быстро =)

Создаем класс itemTorhgun.java - за основу берем itemBow.java, переименовываем там все Bow на Torhgun.
Звук можно оставить тот же bow, так как там действительно лук используется.

изменяем строчку, которая проверяет есть ли в инвентаре снаряды:

if(entityplayer[paste][/paste]inventory[paste][/paste]consumeInventoryItem(50))
// почему 50? заместо 50 раньше стояло что-то типа getId(Item.Arrow) но факел на самом деле у нас типа блока, и я не смогу найти функцию которая у блоков определяет id , да и зачем она нам, и так понятно что у факела ид=50. Кстати отсюда становится понятно, что факеломет стреляем факела, которые берет из инвентаря игрока.

изменяем еще одну строчку на
world[paste][/paste]entityJoinedWorld(new EntityFlyTorch(world, entityplayer));
здесь мы говорим что пулям мы будем entityFlyTorch.

с этим файлом вроде всё.

Открываем item.java

добавляем строчку:
public static Item torchgun = (new ItemTorchgun(106))[paste][/paste]setIconCoord(5, 8)[paste][/paste]setItemName("torchgun");
у нашего нового предмета Ид=106 , а в игре будет 106+256 = 362

Вроде бы само ружье сделали. Теперь приступаем к его снарядам и процессу стрельбы.


Создаем класс EntityFlyTorch.java за основу берем EntityArrow.java

Меняем везде названия EntityArrow на EntityFlyTorch, хотя переменную arrowSnake я не трогал) побоялся - просто создание модов очень нервное дело, но приятное. Кстати если узнаете, то отпишитесь зачем она нужна и за что отвечает.

Так вот, поменяли названия. Теперь нам нужен кусок кода в этой окрестности:

} else            {                xTile = movingobjectposition[paste][/paste]blockX;                yTile = movingobjectposition[paste][/paste]blockY;                zTile = movingobjectposition[paste][/paste]blockZ;                inTile = worldObj[paste][/paste]getBlockId(xTile, yTile, zTile);                motionX = (float)(movingobjectposition[paste][/paste]hitVec[paste][/paste]xCoord - posX);                motionY = (float)(movingobjectposition[paste][/paste]hitVec[paste][/paste]yCoord - posY);                motionZ = (float)(movingobjectposition[paste][/paste]hitVec[paste][/paste]zCoord - posZ);                float f1 = MathHelper[paste][/paste]sqrt_double(motionX * motionX + motionY * motionY + motionZ * motionZ);                posX -= (motionX / (double)f1) * 0[paste][/paste]05000000074505806D;                posY -= (motionY / (double)f1) * 0[paste][/paste]05000000074505806D;                posZ -= (motionZ / (double)f1) * 0[paste][/paste]05000000074505806D;
для ориентировки это со строчки 201

здесь и дальше по-смыслу написано - что делать когда стрела воткнулась в стенку, описан ее процесс замирания, и воспроизведение звука Дррр

вот после этой последней строчки

posZ -= (motionZ / (double)f1) * 0.05000000074505806D;

и до закрытия фигурной скобки нам надо вставить вот этот кусок кода:
if(worldObj[paste][/paste]canBlockBePlacedAt(50, (int)posX, (int)posY, (int)posZ, false))					{						worldObj[paste][/paste]playSoundAtEntity(this, "random[paste][/paste]drr", 1[paste][/paste]0F, 1[paste][/paste]2F / (rand[paste][/paste]nextFloat() * 0[paste][/paste]2F + 0[paste][/paste]9F));																		if(worldObj[paste][/paste]setBlockAndMetadataWithNotify((int)posX, (int)posY, (int)posZ, 50, 0))							{								Block[paste][/paste]blocksList[50][paste][/paste]onBlockPlaced(worldObj,(int)posX, (int)posY, (int)posZ, 0);								//Block[paste][/paste]blocksList[50][paste][/paste]onBlockPlacedBy(worldObj,(int)posX, (int)posY, (int)posZ, entityplayer);							}								}				setEntityDead();

чтобы вы лишний раз не волновались, правильно ли всё вставили, вот фрагмент того что должно получиться:


prevRotationYaw += 180F;                    ticksInAir = 0;                }            } else            {                xTile = movingobjectposition[paste][/paste]blockX;                yTile = movingobjectposition[paste][/paste]blockY;                zTile = movingobjectposition[paste][/paste]blockZ;                inTile = worldObj[paste][/paste]getBlockId(xTile, yTile, zTile);                motionX = (float)(movingobjectposition[paste][/paste]hitVec[paste][/paste]xCoord - posX);                motionY = (float)(movingobjectposition[paste][/paste]hitVec[paste][/paste]yCoord - posY);                motionZ = (float)(movingobjectposition[paste][/paste]hitVec[paste][/paste]zCoord - posZ);                float f1 = MathHelper[paste][/paste]sqrt_double(motionX * motionX + motionY * motionY + motionZ * motionZ);                posX -= (motionX / (double)f1) * 0[paste][/paste]05000000074505806D;                posY -= (motionY / (double)f1) * 0[paste][/paste]05000000074505806D;                posZ -= (motionZ / (double)f1) * 0[paste][/paste]05000000074505806D;				                															if(worldObj[paste][/paste]canBlockBePlacedAt(50, (int)posX, (int)posY, (int)posZ, false))					{						worldObj[paste][/paste]playSoundAtEntity(this, "random[paste][/paste]drr", 1[paste][/paste]0F, 1[paste][/paste]2F / (rand[paste][/paste]nextFloat() * 0[paste][/paste]2F + 0[paste][/paste]9F));																		if(worldObj[paste][/paste]setBlockAndMetadataWithNotify((int)posX, (int)posY, (int)posZ, 50, 0))							{								Block[paste][/paste]blocksList[50][paste][/paste]onBlockPlaced(worldObj,(int)posX, (int)posY, (int)posZ, 0);								//Block[paste][/paste]blocksList[50][paste][/paste]onBlockPlacedBy(worldObj,(int)posX, (int)posY, (int)posZ, entityplayer);							}								}				setEntityDead();				                //inGround = true;                //arrowShake = 7;            }
теперь построчно разберем что же такого нового добавилось:

if(worldObj[paste][/paste]canBlockBePlacedAt(50, (int)posX, (int)posY, (int)posZ, false))
это я взял из BlockItem , проверка что в пространства с координатами posX, posY, posZ можно вставить кубик ( типа ничто не загромождает, не перекрывает)
Откуда я взял эти координаты? Я долго над этим бился кстати, а всё оказалось просто. Эти координаты я взял с пару строчек повыше, те координаты где застряла стрела. Но я их из значения float передаю как int, то есть округленные до целых ( так как координаты кубиков только целые числа)

За одно скажу ,что нашел откуда берется параметр L из прошлого поста - в своем сообщении я про него спрашивал - типа значение с какой стороны игрок смотрит на куб, если кому-то оно понадобится оно берется и определятся в первый раз в файле crs/client/minecraft.java и называется
objectMouseOver.sideHit 757ая строчка.


Теперь снова возвращаюсь к делу, мы прописали проверку что в этих координатах куда воткнулась стрела можно ставить куб.

worldObj[paste][/paste]playSoundAtEntity(this, "random[paste][/paste]drr", 1[paste][/paste]0F, 1[paste][/paste]2F / (rand[paste][/paste]nextFloat() * 0[paste][/paste]2F + 0[paste][/paste]9F));
проигрывает звук застревания стрелы, т.е он прозвучит только в том случае если там можно будет поставить факел

if(worldObj[paste][/paste]setBlockAndMetadataWithNotify((int)posX, (int)posY, (int)posZ, 50, 0))							{
какая еще одна проверка, что именно туда можно поставить наш факел
Block[paste][/paste]blocksList[50][paste][/paste]onBlockPlaced(worldObj,(int)posX, (int)posY, (int)posZ, 0);


ставим факел, где 0 это и есть переменная l - взгляд игрока, я не знал что написать, и поставил 0 - так меня учил мой начальник ))) если не знаешь, что за параметр то ставь Null
//Block[paste][/paste]blocksList[50][paste][/paste]onBlockPlacedBy(worldObj,(int)posX, (int)posY, (int)posZ, entityplayer);  							}


закомментирована функция которая кажется приписывает что этот куб поставил именно этот игрок. Что-то такое...

Ну вот кажется с этим файлом мы закончили, теперь осталось самое простое-

в файле EntityList.java
прописать
addMapping(net[paste][/paste]minecraft[paste][/paste]src[paste][/paste]EntityFlyTorch[paste][/paste]class, "FlyTorch", 97);
где 97 я взял произвольно , главное чтобы с другими в этом списке не совпадало.


создать RenderFlyTorch.java по аналогии с RenderArrow,
так же переименовать там Arrow в FlyTorch

дописать в RenderManager.java:

entityRenderMap.put(net.minecraft.src.EntityFlyTorch.class, new RenderFlyTorch());

Изменяем RecipesWeapons.java
просто докидываем там рядом с другими

craftingmanager[paste][/paste]addRecipe(new ItemStack(Item[paste][/paste]torchgun, 1), new Object[] {            "   ", "X#X", "   ", Character[paste][/paste]valueOf('#'), Item[paste][/paste]bow, Character[paste][/paste]valueOf('X'), Item[paste][/paste]stick        });

Ну теперь вроде бы действительно всё.

КСТАТИ, иногда бывает - делаешь мод а потом у тебя МК не запускается, просто черный экран, ХОТЯ файл META удален. Одна из причин ошибки, в файле рецептов между двумя кавычками поставили не три пробела, а всего лишь два.. типа не " ", а " " на глаз это практически не заметно...


Немного о факеломете. Если не трогать, то в качестве летящих снарядов используются текстуры стрел. + если факел не смог "воткнуться" (т.е место для блока не подходящее) то факел исчезает. В скором времени я попытаюсь исправить это. Пусть в этом случае он как предмет падает на землю. Хотя это доделать вы и так сможете.

Изображение

Если будут какие-то вопросы по факеломёту, то пишите =)

#7 WDkun

WDkun

    Зачарователь

  • Пользователи
  • Сообщений: 1939

Написал 19.05.2011 - 17:52

Перенеси на модлоадер же. С ним всё это гораздо удобнее.

#8 LordKmon

LordKmon

    Странник

  • Пользователи
  • Сообщений: 24

Написал 19.05.2011 - 19:12

[sheep] А как пользоваться модлоадером? =) Конечно звучит глупо, но в инете только про его установку написано ... Установка модлоадера вполне понятна, как везде пишут - закинуть его файлы в minecraft.jar и удалить METAА как им пользоваться? Созданные java файлы в какую-то особенную папку модлоадера засовывать надо ? или прописать их куда-то ? ) Что особенного он делает?и можно по подробней, так как скорее всего все русскоязычные запросы про то как пользоваться modloader попадут сюда =) А то на других форумах вообще ничего про это не написано [skeleton]

#9 WDkun

WDkun

    Зачарователь

  • Пользователи
  • Сообщений: 1939

Написал 19.05.2011 - 19:52

Я планирую запилить туториал по модлоадеру. http://www.minecraft... ... e13042011/ Вот тут неплохой туториал.

#10 Trylyly

Trylyly

    Странник

  • Пользователи
  • Сообщений: 69

Написал 19.05.2011 - 19:54

Мод лоадер:

#11 MetroiD

MetroiD

    Добытчик светокамня

  • Пользователи
  • Сообщений: 3300
  • Откуда: FROM ZEBES

Написал 19.05.2011 - 22:06

Молодец, же. Быстро сделал. Мне понравилось. И тутор понятный, и всё по полочкам разложил. Ты не будешь против если я возьму его код и переделаю?

Obscurell - скайп, вк...
Личность успешно существует...
 


#12 LordKmon

LordKmon

    Странник

  • Пользователи
  • Сообщений: 24

Написал 22.05.2011 - 17:13

Я для этого и выкладывал, чтобы обогатить наши общие знания по моддингу =)

#13 kiborgs

kiborgs

    Странник

  • Пользователи
  • Сообщений: 6

Написал 23.05.2011 - 16:58

Ток факело мет уже был изобретен)В моде 2 by 2 z cfv njrf dxthf pfvtnbk/

#14 Dan4eg

Dan4eg

    Добытчик дерева

  • Пользователи
  • Сообщений: 193

Написал 23.05.2011 - 17:07

Это не факеломёт,а стрелы с факелами.
Нотч знает яву.Нотч любит Яву.Нотч ничего и не знает кроме явы.Нотч пишет игры.Получаются неплохие игры, но на яве.Кто виноват и что делать?

#15 SuperNintendo

SuperNintendo

    Добытчик обсидиана

  • Пользователи
  • Сообщений: 1413
  • Откуда: Scotland~

Написал 24.05.2011 - 21:48

Это не факеломёт,а стрелы с факелами.

Стрелысфакеламиомёт? -.-
ИзображениеИзображениеИзображение

#16 Dimaz

Dimaz

    Странник

  • Пользователи
  • Сообщений: 64

Написал 02.06.2011 - 20:50

Былобы просто охренительно, если бы можно было кидать все что душе угодно. Можно сделать либо побольше разных луков типа Гряземет, Камнемет, Свветищийсяблокизадамет и тд. и тп.. Или просто добавить в настройки нужный блок и сделать, там, Блокомет. А так как лук стреляет Entity'ми то можно сделать свино мет, работающий от поросятины! :DАлсо, покупаю книженку по джава.
Скрытый текст

#17 WDkun

WDkun

    Зачарователь

  • Пользователи
  • Сообщений: 1939

Написал 02.06.2011 - 20:59

Книженция не нужна. Джаве можно научится по пути, если ковырять сырцы.

#18 Dimaz

Dimaz

    Странник

  • Пользователи
  • Сообщений: 64

Написал 03.06.2011 - 08:21

Классно, купить не успел :D *с радосной рожей бегу качать MCP*Столько идей...
Скрытый текст

#19 Heroman

Heroman

    Добытчик алмазов

  • Пользователи
  • Сообщений: 897
  • Откуда: Бронивилль

Написал 05.06.2011 - 05:18

Выложи сам мод на факеломёт.
Изображение


Количество пользователей, читающих эту тему: 0

0 пользователей, 0 гостей, 0 анонимных