Skocz do zawartości
  • 👋 Witaj na MPCForum!

    Przeglądasz forum jako gość, co oznacza, że wiele świetnych funkcji jest jeszcze przed Tobą! 😎

    • Pełny dostęp do działów i ukrytych treści
    • Możliwość pisania i odpowiadania w tematach
    • System prywatnych wiadomości
    • Zbieranie reputacji i rozwijanie swojego profilu
    • Członkostwo w jednej z największych społeczności graczy

    👉 Dołączenie zajmie Ci mniej niż minutę – a zyskasz znacznie więcej!

    Zarejestruj się teraz

Zaawansowane Tworzenie Modów


karol202

Rekomendowane odpowiedzi

Opublikowano

Poradnik jak tworzyć mody do minecraft

Wiem że na forum jet pełno tutoriali jak robić mody, ale są albo do starej wersji, albo opisane tylko podstawy. Jesli nie znasz podstaw javy to nie masz co zabierać się za tworzenie modów. Jeśli znasz javę, ale tylko podstawy, to polecam przeczytać jakąś książkę, albo stronę o niej.
Poradnik na wersje minecrafta: 1.5.2 (Już piszę poradnik od nowa)

Tworzenie modów pod Forge

W tym rozdziale będziesz tworzył mody pod Forge. Będzie do tego potrzebna instalacja opisana w rozdziale Instalacja MCP.

1. Klasa moda

W tej części dowiesz się jak stworzyć główny plik moda i jak on wygląda. Włącz eclipsa i udaj się do folderu src w projekcie Minecraft(zresztą jest to jedyny projekt). Są tam wszystkie pliki minecrafta. Utwórz tam paczkę
(PPM na folderze src i New ] Package) o nazwie:

NAZWAAUTORA.NAZWAMODA

Możesz ją nazwać jak chcesz, ale wg. mnie tak jest najlepiej. NAZWAAUTORA zastąp swoim nickiem, a NAZWAMODA nazwą moda. W paczce utwórz nową klasę o nazwie:

ModNAZWAMODA

A oto co ma się w niej znaleźć:

package NAZWAPACZKI; 
import cpw.mods.fml.common.Mod; 
import cpw.mods.fml.common.Mod.Init; 
import cpw.mods.fml.common.network.NetworkMod; 
import cpw.mods.fml.common.event.FMLInitializationEvent; 

@Mod(modid=IDMODA",, version=WERSJA") 
@NetworkMod(clientSideRequired=true, serverSideRequired=false) 
public class NAZWAKLASY { 
	@Init public void init(FMLInitializationEvent e) { 
	} 
}

NAZWAPACZKI to nazwa paczki w której utworzyłeś tą klase. NAZWAKLASY to nazwa klasy. IDMODA to unikalne id moda dzięki któremu FML rozpozna tego moda, wpisz tam co chcesz. WERSJA to wersja. Te linijki @Mod... i @NetworkMod... mówią FML że w tym pliku znajduje się mod i podaje mu informacje o nim. W funkcji init() daj to co ma się dziać przy ładowaniu moda, np. dodawanie receptur, nazw, i innych. Teraz muszę wprowadić nazewnictwo paczek, aby było wiadomo o którą chodzi. Paczkę którą przed chwilą stworzyłeś nazwijmy paczką domyślną. UWAGA! Jeśli skopiujesz niektóre linijki do swojego kodu nie będą one działać! Aby temu zapobiec kliknij LPM + Ctrl na żarówkę z X przy linijce z błędem, następnie kliknij na Import'...'(...). Jeśli masz jakiś inny błąd to rób wszystko do końca mimo błędu, prawdopodobnie zostanie on naprawiony poprzez późniejsze np. dodanie funkcji.


2. Nowy blok

Teraz zrobisz swój własny blok. Do folderu common dodaj nową paczkę o nazwie takiej jak wcześniejsza + .blocks , np jeśli aczka nazywała się

karol202.przykład

to nowa paczka będzie się nazywała

karol202.przykład.blocks

Będzie to paczka bloków, będą w niej wszystkie pliki bloków. Do paczki dodaj klasę BlockNAZWABLOKU o treści:

package NAZWAPACZKI;

public class BlockNAZWABLOKU extends Block {
	public BlockNAZWABLOKU(int id) {
		super(id, 0, Material.MATERIAŁ);
		setCreativeTab(CreativeTabs.NAZWATAB);
	}
}

MATERIAŁ to materiał z jakiego jest blok, w pliku Material są wypisane wszystkie materiały.
NAZWATAB to nazwa zakładki trybu creative(nazwy są w pliku CreativeTabs, jeśli nie chcez aby ten item wyświetlał się w creative to usuń tą linijkę)
Teraz w klasie głównej dodaj zmienne:

public static Block blockNAZWABLOKU;
public int idBlockNAZWABLOKU=ID;

ID to id bloku, musi być większe od 150 i mniejsze od 4096, każdy blok musi mieć inne id.
W funkcji init() dodaj inicializację bloku:

blockNAZWABLOKU=new BlockNAZWABLOKU(idBlockNAZWABLOKU).setUnlocalizedName("NAZWABLOKU").setHardness(TWARDOŚĆ).setResistance(ODPORNOŚĆ);

TWARDOŚĆ to liczba która określa jak długo trzeba zbierać ten blok, sam popróbuj i wpisz tam coś, na końcu musi być litera F. Teraz do funkcji init() dodaj funkcje:

GameRegistry.registerBlock(blockNAZWABLOKU);
LanguageRegistry.addName(blockNAZWABLOKU, "NAZWAWGRZE");

To już koniec tworzenia bloków.


2a. Tekstura bloku

W poprzedniej części zrobiłeś blok, ale bez tekstury, w tej części to zmienisz. W modach na forge każdy mod ma swój własny plik z teksurami, nie trzeba już używać osobnego pliku do każdego bloku. Do paczki domyślnej dodaj klasę ClientProxy o treści:

package NAZWAPACZKI;

public class CommonProxy {
	public void registerRender() {
	}
}

Teraz dodaj klasę ClientProxy o treści:

package NAZWAPACZKI;

public class ClientProxy extends CommonProxy {
	public void registerRender() {
	}
}

NAZWAPACZKI to nazwa paczki w której została utworzona ta klasa.
Tymczasowo w folderze z mcp w /jars/bin w pliku minecraft.jar stwórz folder o mods, a w nim folder o nazwie nazwy moda(czasami przed tym trzeba zapisać moda i wyłączyć eclipse), w nim folder textures. Jeśli chcesz zrobić teksturę bloku, w folderze textures stwórz folder blocks, a w nim plik blockNAZWABLOKU.png. Plik ma mieć 16x16, chyba że każda strona bloku będzie inna, jeśli tak to zrób 96x16(96 jest w poziomie), kolejne boki bloku po sobie. Dla każdego bloku taki plik osobno.
Teraz do klasy głównej moda dodaj to:

@SidedProxy(clientSide=NAZWAPACZKI.ClientProxy", serverSide=NAZWAPACZKI.CommonProxy")

public static CommonProxy proxy;

Dodaj jeszcze funkcje preInit(czyli to co ma się dziać przed załadowaniem moda):

@PreInit

public void preInit(FMLPreInitializationEvent e) {
}

A do funkcji dodaj:

proxy.registerRender();

Teraz do klasy bloku dodaj te funkcje:

public void registerIcons(IconRegister par1IconRegister) {
	this.blockIcon=par1IconRegister.registerIcon("NAZWAMODA:blockNAZWABLOKU");
}

public int getBlockTextureFrom-Side(int sd) {
	return sd;
}

Między From i Side jest myślnik, bo z forum jest coś nie tak i jak zostawię bez myślnika to to się zamienia na MPCforum. Czyli w swoim modzie myślnik usunąć.


2b. Specjalne właściwości bloków

W tej części pokaże specjalne właściwości bloków, np. niezniszczalność(bedrock), świecenie(glowstone).
Przykład:

tv=new BlockTV(idBlockTV, 0).setUnlocalizedName("tv").setHardness(1F).setResistance(10F).setBlockUnbreakable();

Niezniszczalność:

 





.setBlockUnbreakable();

Wkleić do do linijki deklarującej blok na końcu, przed średnikiem.
Sprawia że blok jest nie zniszczalny tak jak bedrock.
Jeśli dajesz to, nie dawaj .setHardness() .


Świecenie:

 

.setLightValue(WARTOŚĆ)

Wkleić do do linijki deklarującej blok na końcu, przed średnikiem.
Blok będzie świecił tak jak glowstone lub pochodnia. WARTOŚĆ zastąp jasnością świecenia, na końcu wartości daj F. Maksymalna wartość to 1F.


Dźwięk chodzenia:

 

.setStepSound(Block.DZWIEK)

Wkleić do do linijki deklarującej blok na końcu, przed średnikiem.
Ustawia dźwięk chodzenia po tym bloku. Dostępne dźwięki to:

  • soundStoneFootstep
  • soundGrassFootstep
  • soundWoodFootstep
  • soundMetalFootstep
  • soundGlassFootstep
  • soundClothFootstep
  • soundSandFootstep
  • soundGravelFootstep

Ich nazwy troche mówią jak brzmią.


Wyłączenie statystyk:

Jeśli zbierzesz lub postawisz taki blok statystyki postawionych/zniszczonych bloków nie zmienią sie, np. woda.

.disableStats()

Wkleić do do linijki deklarującej blok na końcu, przed średnikiem.


Inne wymiary bloku:

W konstruktorze pliku bloku dodaj tą linijkę:

setBlockBounds(mx, my, mz, xx, xy, xz);

mx - x tego gdzie blok się zaczyna
my - y tego gdzie blok się zaczyna
mz - z tego gdzie blok się zaczyna
xx - x tego gdzie blok się kończy
xy - y tego gdzie blok się kończy
xz - z tego gdzie blok się kończy
Oprócz tego musisz dodać funkcje:

public boolean isOpaqueCube() {
	return false;
}

Standardowo dla bloków to:

setBlockBounds(0F, 0F, 0F, 1F, 1F, 1F);

Dla półbloku:

setBlockBounds(0F, 0F, 0F, 1F, 0.5F, 1F);

Dla torów:

setBlockBounds(0F, 0F, 0F, 1F, 0.125F, 1F);

 


Skakanie na bloku:

Jeśli wejdziesz na taki blok podskoczysz.

public void onEntityWalking(World world, int x, int y, int z, Entity entity) {
	entity.motionY += SILA;
}

SILA to moc z jaką będziesz skakał. Niestety nie wiem o ile kratek będzie działała poszczególna siła. Musisz sam eksperymentować, na początek polecam wpisać 1.0F. Na końcu zawsze musi być F.


2c. Atakujący blok

Teraz zrobisz blok który zadaje obrażenia gdy się go dotknie(tak jak kaktus). Do pliku głównego moda dodaj zmienną:

DamageSource NAZWADamage=new DamageSource("NAZWADamage");

NAZWA to nazwa obrażeń(np. cactus).
Teraz do pliku bloku który ma zadawać obrażenia dodaj:

public AxisAlignedBB getCollisionBoundingBoxFromPool(World world, int i, int j, int k) {
	float f=0.0625F;
	return AxisAlignedBB.getBoundingBoxFromPool((float)i + f, j, (float)k + f, (float)(i + 1) - f, (float)(j + 1) - f, (float)(k + 1) - f);
}

public void onEntityCollidedWithBlock(World world, int i, int j, int k, Entity entity, EntityPlayer entityplayer) {
	entity.attackEntityFrom(NAZWAKLASYMODA.NAZWADamage, MOC);
}

MOC to moc z jaką blok atakuje, chyba trzeba wpisać ile żyć(jedno serce u człowieka w GUI to 2 życia, człowiek ma 20 żyć) zabiera na sekundę.

 


2d.Ruda

W tej części dodasz do moda rudę. Stwórz nową klasę o nazwie WorldGeneratorNAZWAMODA w paczce domyślnej. Jej treść:

import java.util.Random;
import net.minecraft.world.World;
import net.minecraft.world.chunk.IChunkProvider;
import net.minecraft.world.gen.feature.WorldGenMinable;
import cpw.mods.fml.common.IWorldGenerator;

public class WorldGeneratorNAZWAMODA implements IWorldGenerator {
	@Override
	public void generate(Random random, int chunkX, int chunkZ, World world,IChunkProvider chunkGenerator, IChunkProvider chunkProvider) {
		switch(world.provider.dimensionId){
			case 1: generateEnd(world, random, chunkX, chunkZ);
			case 0: generateSurface(world, random, chunkX, chunkZ);
			case -1: generateNether(world, random, chunkX, chunkZ);
		}
	}

	private void generateEnd(World world, Random random, int chunkX, int chunkZ) {
	}

	private void generateSurface(World world, Random random, int chunkX,int chunkZ) {
	}

	private void generateNether(World world, Random random, int chunkX, int chunkZ) {
	}
}

Teraz dajesz ten fragment

int freq=(random.nextInt() % ((MAX - MIN) + 1)) + MIN;
for(int i=0; i < freq; i++) {
	int xCoord=chunkX + random.nextInt(16);
	int yCoord=random.nextInt() % ((MAXLEV - MINLEV) + 1) + MINLEV;
	int zCoord=chunkZ + random.nextInt(16);
	(new WorldGenMinable(NAZWAKLASYGLOWNEJ.NAZWABLOKU.blockID, NUM)).generate(world, random, xCoord, yCoord, zCoord);
}

w odpowiednią funkcje. Jeśli ruda ma się generować w:

  • normalnym świecie - daj go do generateSurface
  • nether - daj go do generateNether
  • end - daj go do generateEnd

NAZWABLOKU to nazwa bloku który będzie się generował, a NUM to maksymalna ilość rudy wygenerowana na raz. MAXLEV to maksymalna wysokość na jakiej może się generować ruda, a MINLEV najniższa.
MAX to maksymalna ilość rud(grupa bloków koło siebie) na chunk. MIN minimalna. Jeśli chcesz żeby generowało się więcej rodzajów rud to po prostu w.w. fragment umieść kilka razy(można w innych funkcjach), tylko w zmienianym fragmencie zamień freq na freqNUM gdzie NUM to jakaś dowolna liczba(ważne żeby się nie powtarzały) i zmienną i(tą w petli for) na jakąś inną literę, ważne żeby się nie powtarzały. Teraz do klasy głównej do funkcji init() dodaj:

GameRegistry.registerWorldGenerator(new WorldGeneratorNAZWAMODA());

Przykładowy plik WorldGeNneratorNAZWAMODA:

import java.util.Random;
import net.minecraft.world.World;
import net.minecraft.world.chunk.IChunkProvider;
import net.minecraft.world.gen.feature.WorldGenMinable;
import cpw.mods.fml.common.IWorldGenerator;

public class WorldGeneratorNAZWAMODA implements IWorldGenerator {
	@Override
	public void generate(Random random, int chunkX, int chunkZ, World
	world,IChunkProvider chunkGenerator, IChunkProvider chunkProvider) {
		switch(world.provider.dimensionId){
			case 1: generateEnd(world, random, chunkX, chunkZ);
			case 0: generateSurface(world, random, chunkX, chunkZ);
			case -1: generateNether(world, random, chunkX, chunkZ);
		}
	}

	private void generateEnd(World world, Random random, int chunkX, int chunkZ) {
	}
	
	private void generateSurface(World world, Random random, int chunkX,int chunkZ) {
		int freq=(random.nextInt() % ((7 - 2) + 1)) + 2;
		for(int i=0; i < freq; i++) {
			int xCoord=chunkX + random.nextInt(16);
			int yCoord=random.nextInt(random.nextInt() % ((40 - 5) + 1) + 5);
			int zCoord=chunkZ + random.nextInt(16);
			(new WorldGenMinable(ModTest.oreA.blockID, 7)).generate(world, random, xCoord, yCoord, zCoord);
		}
		int freq2=(random.nextInt() % ((4 - 0) + 1)) + 0;
		for(int j=0; j < freq2; j++) {
			int xCoord=chunkX + random.nextInt(16);
			int yCoord=random.nextInt(random.nextInt() % ((20 - 1) + 1) + 1);
			int zCoord=chunkZ + random.nextInt(16);
			(new WorldGenMinable(ModTest.oreB.blockID, 3)).generate(world, random, xCoord, yCoord, zCoord);
		}
	}

	private void generateNether(World world, Random random, int chunkX, int chunkZ) {
		int freq3=(random.nextInt() % ((7 - 2) + 1)) + 2;
		for(int k=0; k < freq3; k++) {
			int xCoord=chunkX + random.nextInt(16);
			int yCoord=random.nextInt(random.nextInt() % ((100 - 5) + 1) + 5);
			int zCoord=chunkZ + random.nextInt(16);
			(new WorldGenMinable(ModTest.oreC.blockID, 1)).generate(world, random, xCoord, yCoord, zCoord);
		}
	}
}

 


3. Itemy

W tej części zrobisz swój item. Stwórz teraz paczkę itemową, o nazwie paczki domyślnej + .items . Do klasy głównej dodaj zmienne:

public static Item itemNAZWAITEMU;
public int idItemNAZWAITEMU=ID;

W funkcji init() dodaj to:

itemNAZWAITEMU=new ItemNAZWAITEMU(idItemNAZWAITEMU).setItemName("itemNAZWAITEMU");

Dodaj do paczki itemowej klasę ItemNAZWAITEMU o treści:

package NAZWAPACZKI;

public class ItemNAZWAITEMU extends Item {
	public ItemNAZWAITEMU(int id) {
		super(id);
		maxStackSize=MAKSSTAK;
		setCreativeTab(CreativeTabs.NAZWATAB);
	}

	public void registerIcons(IconRegister iconRegister) {
		iconIndex=iconRegister.registerIcon("NAZWAMODA:itemNAZWAITEMU");
	}
}

NAZWAMITEMU to nazwa itemu który ma najmniejsze id w tym modzie. MAKSSTAK zastąp maksymalną ilością przedmiotu w stacku(maksymalnie 64). NAZWATAB to nazwa zakładki trybu creative(nazwy są w pliku CreativeTabs, jeśli nie chcez aby ten item wyświetlał się w creative to usuń tą linijkę). Teraz wejdź do folderu z MCP, a potem jars/bin i otwórz minecraft.jar. Stwórz tam folder mods, w nim folder z nazwą taką jaka jest nazwa moda. Następnie folder textures, a w środku folder item. Tam stwórz plik itemNAZWAITEMU.png z teksturą itemu. Teksturę rób jakimkolwiek programem, byle nie paintem.


3a. Jedzenie

Tworzenie jedzenia różni się od tworzenia itemu, jedynie linijką deklarującą item.
To linijka deklarująca jedzenie:

NAZWAITEMU=new ItemFood(idItemNAZWAITEMU, WARTOSC, ULUBIONE).setItemName("NAZWAITEMU");

WARTOSC zastępujemy ilością odnawianych jednostek jedzenia(2 jednostki to jedna ikonka mięsa, człowiek ma 20 jednostek), jeśli do tego jedzenia będą przychodzić wilki to ULUBIONE zastępujemy true, jeśli nie false.


3b. Efekty mikstur

To dowiesz się jak dodać efekty mikstur po zjedzeniu przedmiotu(jedzenia).
W pliku głównym moda w linijce dodającej jedzenie przed ; dodaj

.setPotionEffect(Potion.EFEKT.id, CZAS, POZIOM, SZANSA)

EFEKT to nazwa efektu mikstury(zobacz w itemach w pliku Item.java).
CZAS to czas działania mikstury podany w sekundach.
POZIOM to poziom ulepszenia mikstury(domyślnie 0).
SZANSA to szansa na wystąpienie efektu po zjedzeniu(na końcu musi być F , jeśli efekt ma wystąpić zawsze po zjedzeniu to daj 1F, jeśli np. połowa to 0.5F).


3c. Narzędzia

Dodaj nowy item do głównej klasy:

public static Item NAZWAITEMU;

I dodaj to do funkcji init():

NAZWAITEMU=new ItemNAZWAITEMU(idItemNAZWAITEMU, enumToolNAZWATYPU).setItemName("itemNAZWATEMU");

Oczywiście trzeba dodać zmienną idItemNAZWAITEMU i przypisać do niej id itemu. NAZWATYPU to nazwa typu narzędzia(np. żelazo, miedź, obsydian).
Teraz stwórz nową klasę itemu(w paczce itemowej) o nazwie ItemNAZWAITEMU . Oto jej treść:

public class ItemNAZWAITEMU extends ItemRODZAJ {
	public ItemNAZWAITEMU(int id, EnumToolMaterial enumtoolmaterial) {
		super(id, enumtoolmaterial);
		maxStackSize=1;
		setCreativeTab(CreativeTabs.tabCombat);
	}
}

RODZAJ to rodzaj narzędzia(np. kilof, miecz, łopata)Jeśli chcesz dodać tekstury zrób to tak jak w części 3.Itemy . Wróć teraz do klasy głównej moda i dodaj tam zmienną:

static EnumToolMaterial enumtoolNAZWATYPU=EnumHelper.addToolMaterial(LEV, UZY, MOC, ODP, 14);

LEV zastąp poziomem narzędzia. Niektóre bloki np. obsydian, ruda diamentu można zniszczyć tylko określonym poziomem narzędzia, albo lepszym, oto poziomy narzędzi:
-drewniane - 0
-kamienne - 1
-żelaznne - 2
-diamentowe - 3
-złote - 0
Nie będę wypisywał wszystkich bloków i minimalnego poziomu narzędzia potrzebnego do ich wydobycia, ale wypisze przykład:
-obsydian - 3
-ruda diamentu 2 i wyżej
UZY zamień na maksymalną ilość użyć.
Szybkość wydobywania bloków zależy od MOC, oto lista wartości MOC w standardowych typach narzędzi:
-drewniane - 2F
-kamienne - 4F
-żelaznne - 6F
-diamentowe - 8F
-złote - 12F
ODP to ilość żyć zabieranych mobowi/graczowi(w multipleyer) przy ataku, jedno serce przy gui z wyborem przedmiotu to 2 życia(człowiek ma 20 żyć).


4. Receptura craftingu

Do funkcji init() dodaj

GameRegistry.addRecipe(new ItemStack(WYNIK, ILOSC), new Object[]{
	UŁOŻENIEDOCRAFTOWANIA
});

W UŁOŻENIEDOCRAFTOWANIA znajduje się ułożenie bloków/przedmiotów do craftowania, np.
-żelazny hełm:

GameRegistry.addRecipe(new ItemStack(Item.helmetSteel, 1), new Object[] {
	"XXX", "X X", 'X', Item.ingotIron
});

-zapalniczka

GameRegistry.addRecipe(new ItemStack(Item.flintAndSteel, 1), new Object[] {
	"S ", " F", 'S', Item.ingotIron, 'F', Item.flint
});

Jeśli blok/przedmiot jest stworzony w modzie w którym dodajesz recepture, nie dawaj przed nim nic. Jeśli nie jest daj przed nim Block. , lub Item. Np.

GameRegistry.addRecipe(new ItemStack(TV, 1), new Object[] {
	"GGG", "GRG", "GGG", 'G', Block.wood, 'R', kineskop
});

Ułożenie spacji w cudzysłowiach jest ważne! Jeśli jest spacja to ma nie być tam żadnego itemu. Jeśli nie rozumiesz receptur to sprawdź te w CraftingManager.java .
Jeśli ten item/blok jest z normalnego minecrafta to przed jego nazwą daj Block. lub Item. w zależności od tego czym on jest. Jeśli jest on z tego moda to nic przed nim nie dawaj.
Przed TV i kineskop nie dałem nic i jest dobrze.


4a. Shapepeless Recipe

Do funcji init() dodaj to

GameRegistry.addShapelessRecipe(new ItemStack(WYNIK, ILOSC), new Object[] {
	SKŁADNIKI
});

SKŁADNIKI to składniki potrzebne dowykonania receptury odzdielone przecinkami.


4b. Receptura przepalania

Do funcji init() dodaj

GameRegstry.addSmelting(ID, new ItemStack(WYNIK, ILOSC), EXP);

 


5. Plik konfiguracyjny

W tej części zrobisz moda który używa pliku konfiguracji, id bloków są zapisane w osobnym pliku. Do klasy CommonProxy dodaj

private Configuration config;

public void loadConfig(File file) {
	config=new Configuration(file);
	config.load();
}

public void saveConfig() {
	config.save();
}

public Configuration getConfig() {
	return config;
}

Do klasy głównej moda dodaj funkcje preInit (jeśli już taką masz, to tylko dodaj do niej co trzeba) i dodaj do niej funkcje ładowania configu:

@PreInit
public void preInit(FMLPreInitializationEvent e) {
	proxy.loadConfig(e.getSuggestedConfigurationFile());
}

Dodaj do niej

idNAZWAPRZYBLOKU=proxy.getConfig().getBlock("NAZWABLOKU", idNAZWAPRZYBLOKU).getInt();

Skopiuj to, ma tego być tyle razy ile bloków jest w modzie. Czyli dla każdego bloku tak linijka.
NAZWAPRZYBLOKU to nazwa bloku do którego będzie przypisane id, w każdej linijce inny blok ma uzyskać id, tak żeby wszystkie bloki miały swoją nazwę w odpowiedniej linijce. DEFID to domyślne id bloku.
Z itemami to samo tylko że zamiast getBlock daj getItem.
Przykład funkcji preInit:

@PreInit
public void preInit(FMLPreInitializationEvent e) {
	proxy.registerRender(); //To z części o teksturze bloku
	proxy.loadConfig();
	idCrystal=proxy.getConfig().getBlock("Crystal", idCrystal).getInt();
	idRedCrystal=proxy.getConfig().getBlock("RedCrystal", idRedCrystal).getInt();
	idGreenCrystal=proxy.getConfig().getBlock("GreenCrystal", idGreenCrystal).getInt();
	proxy.saveConfig();
}

 


6. GUI

W tej części dowiesz się jak zrobić własne GUI do bloku(tak jak np. piec). Podczas robienia gui mogą pojawiać się błędy z powodu brakujących niektórych klas, ale potem błędy znikną bo wszytkie klasy już będą stworzone. Na początku do klasy głównej moda dodaj zmienną instancji:

@Instance
public static NAZWAKLASYMODA instance;

NAZWAKLASYMODA to nazwa klasy głównej moda.
Teraz do funcji init() dodaj funkcje:

GameRegistry.registerTileEntity(TileEntityNAZWAGUI.class, "NAZWAGUI");
NetworkRegistry.instance().registerGuiHandler(this, new GuiHandler());

NAZWAGUI to nazwa gui. Teraz przejdź do klasy bloku(tego bloku, do którego chcesz dodać gui) i dodaj tam takie funkcje:

public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer entityPlayer, int par6, float par7, float par8, float par9) {
	if (entityPlayer.isSneaking()) {
		return false;
	}
	entityPlayer.openGui(NAZWAKLASYMODA.instance, GuiIds.NAZWAGUI, world, x, y, z);
	return true;
}

public void breakBlock(World world, int x, int y, int z, int par5, int par6) {
	Random rand=new Random();
	TileEntity tileEntity=world.getBlockTileEntity(x, y, z);
	if (!(tileEntity instanceof IInventory)) {
		return;
	}
	IInventory inventory=(IInventory) tileEntity;
	for (int i=0; i < inventory.getSizeInventory(); i++) {
		ItemStack stack=inventory.getStackInSlot(i);
		if (stack != null && stack.stackSize ] 0) {
			float f1=0.7F;
			double d=(world.rand.nextFloat() * f1) + (1.0F - f1) * 0.5D;
			double d1=(world.rand.nextFloat() * f1) + (1.0F - f1) * 0.5D;
			double d2=(world.rand.nextFloat() * f1) + (1.0F - f1) * 0.5D;
			EntityItem entityitem=new EntityItem(world, x + d, y + d1, z + d2, stack);
			entityitem.delayBeforeCanPickup=10;
			world.spawnEntityInWorld(entityitem);
		}
	}
	super.breakBlock(world, x, y, z, par5, par6);
}

public boolean hasTileEntity(int metadata) {
	return true;
}

public TileEntity createNewTileEntity(World var1) {
	return new TileEntityNAZWAGUI();
}

I linijkę

public class BlockNAZWABLOKU extends Block

zamień na

public class BlockNAZWABLOKU extends BlockContainer

Teraz stwórz paczkę GUI(nazwa: tak jak domyślna + .gui) i dodaj do niej klasę GuiIds, powinna ona wyglądać tak:

package NAZWAPACZKID.gui;

public class GuiIds {
	public static final int NAZWAGUI=ID;
}

NAZWAPACZKID to nazwa paczki domyślnej.
ID to id gui. Można tam wpisać jakąkolwiek liczbę. Teraz do paczki gui dodaj klasę GuiHandler, powinna wyglądać tak:

package NAZWAPACZKID.gui;

import net.minecraft.src.EntityPlayer;
import net.minecraft.src.TileEntity;
import net.minecraft.src.World;
import cpw.mods.fml.common.network.IGuiHandler;

public class GuiHandler implements IGuiHandler {
	@Override
	public Object getServerGuiElement(int id, EntityPlayer player, World world, int x, int y, int z) {
		TileEntity tileEntity=world.getBlockTileEntity(x, y, z);
		if(tileEntity instanceof TileEntityNAZWAGUI && id == GuiIds.NAZWAGUI) {
			return new ContainerNAZWAGUI(player.inventory, (TileEntityNAZWAGUI) tileEntity);
		}
		return null;
	}
	
	@Override
	public Object getClientGuiElement(int id, EntityPlayer player, World world, int x, int y, int z) {
		TileEntity tileEntity=world.getBlockTileEntity(x, y, z);
		if(tileEntity instanceof TileEntityNAZWAGUI && id == GuiIds.NAZWAGUI) {
			return new GuiNAZWAGUI(player.inventory, (TileEntityNAZWAGUI) tileEntity);
		}
		return null;
	}
}

Teraz w paczce gui stwórz klasę GuiNAZWAGUI:

package NAZWAPACZKID.gui;

import org.lwjgl.opengl.GL11;
import net.minecraft.src.GuiContainer;
import net.minecraft.src.InventoryPlayer;
import net.minecraft.src.StatCollector;
import net.minecraft.src.TileEntity;

public class GuiNAZWAGUI extends GuiContainer {
	public GuiNAZWAGUI (InventoryPlayer inventoryPlayer, TileEntity tileEntity) {
		super(new ContainerNAZWAGUI(inventoryPlayer, tileEntity));
		this.xSize=228;
		this.ySize=221;
	}

	protected void drawGuiContainerForegroundLayer(int par1, int par2) {
		fontRenderer.drawString("TEKSTGUI", 8, 6, 4210752);
		fontRenderer.drawString(StatCollector.translateToLocal("container.inventory"), 8, ySize - 96 + 2, 4210752);
	}

	protected void drawGuiContainerBackgroundLayer(float par1, int par2, int par3) {
		GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
		this.mc.renderEngine.bindTexture("gui/guiNAZWAGUI.png");
		int x=(width - xSize) / 2;
		int y=(height - ySize) / 2;
		this.drawTexturedModalRect(x, y, 0, 0, xSize, ySize);
	}
}

TEKSTGUI to tekst który będzie się wyświetlał na górze okna gui.
Gui nie jest jeszcze gotowe, bo brakuje kilku klas które się różnią w zależności od tego do czego ma służyć gui. Będą one w następnej części.


6a. Skrzynka

Ta część to uzupełnienie do poprzedniej, zrobisz niej skrzynkę. W paczce gui dodaj klasę ContainerNAZWAGUI:

public class ContainerNAZWAGUI extends Container {
	private TileEntity tileEntity;

	public ContainerNAZWAGUI (InventoryPlayer inventoryPlayer, TileEntity te) {
		tileEntity=te;
		for(int i=0; i < 6; i++) {
			for(int j=0; j < 12; j++) {
				addSlotToContainer(new Slot((IInventory)tileEntity, i * 12 + j, 8 + j * 18, 18 + i * 18));
			}
		}
		for (int i=0; i < 3; i++) {
			for (int j=0; j < 9; j++) {
				addSlotToContainer(new Slot(inventoryPlayer, j + i * 9 + 9, 8 + j * 18, 140 + i * 18));
			}
		}
		for (int i=0; i < 9; i++) {
			addSlotToContainer(new Slot(inventoryPlayer, i, 8 + i * 18, 198));
		}
	}

	@Override
	public boolean canInteractWith(EntityPlayer player) {
		return ((IInventory)tileEntity).isUseableByPlayer(player);
	}
	
	public ItemStack transferStackInSlot(int slot) {
		ItemStack stack=null;
		Slot slotObject=(Slot) inventorySlots.get(slot);
		if (slotObject != null && slotObject.getHasStack()) {
			ItemStack stackInSlot=slotObject.getStack();
			stack=stackInSlot.copy();
			if (slot == 0) {
				if (!mergeItemStack(stackInSlot, 1, inventorySlots.size(), true)) {
					return null;
					}
			}
			else if (!mergeItemStack(stackInSlot, 0, 1, false)) {
				return null;
			}
			if (stackInSlot.stackSize == 0) {
				slotObject.putStack(null);
			}
			else {
				slotObject.onSlotChanged();
			}
		}
		return stack;
	}
}

Teraz w paczce gui stwórz klasę TileEntityNAZWAGUI:

public class TileEntityNAZWAGUI extends TileEntity implements IInventory {
	private ItemStack[] inv;

	public TileEntityNAZWAGUI() {
		inv=new ItemStack[72];
	}

	@Override
	public int getSizeInventory() {
		return inv.length;
	}

	@Override
	public ItemStack getStackInSlot(int var1) {
		return inv[var1];
	}

	@Override
	public ItemStack decrStackSize(int slot, int amount) {
		ItemStack stack=getStackInSlot(slot);
		if (stack != null) {
			if (stack.stackSize <= amount) {
				setInventorySlotContents(slot, null);
			}
			else {
				stack=stack.splitStack(amount);
				if (stack.stackSize == 0) {
					setInventorySlotContents(slot, null);
				}
			}
		}
		return stack;
	}

	@Override
	public ItemStack getStackInSlotOnClosing(int slot) {
		ItemStack stack=getStackInSlot(slot);
		if (stack != null) {
			setInventorySlotContents(slot, null);
		}
		return stack;
	}

	@Override
	public void setInventorySlotContents(int slot, ItemStack stack) {
		inv[slot]=stack;
		if (stack != null && stack.stackSize ] getInventoryStackLimit()) {
			stack.stackSize=getInventoryStackLimit();
		}
	}

	@Override
	public String getInvName() {
		return "NAZWAGUI";
	}

	@Override
	public int getInventoryStackLimit() {
		return 64;
	}

	@Override
	public boolean isUseableByPlayer(EntityPlayer player) {
		return worldObj.getBlockTileEntity(xCoord, yCoord, zCoord) == this && player.getDistanceSq(xCoord + 0.5, yCoord + 0.5, zCoord + 0.5) < 64;
	}

	public void writeToNBT(NBTTagCompound par1NBTTagCompound) {
		super.writeToNBT(par1NBTTagCompound);
		NBTTagList lista=new NBTTagList();
		for(int it=0; it < this.inv.length; it++) {
			if (this.inv[it] != null) {
				NBTTagCompound item=new NBTTagCompound();
				item.setByte("Slot", (byte)it);
				this.inv[it].writeToNBT(item);
				lista.appendTag(item);
			}
		}
		par1NBTTagCompound.setTag("Slots", lista);
	}

	public void readFromNBT(NBTTagCompound par1NBTTagCompound) {
		super.readFromNBT(par1NBTTagCompound);
		NBTTagList lista=par1NBTTagCompound.getTagList("Slots");
		this.inv=new ItemStack[this.getSizeInventory()];
		for (int it=0; it < lista.tagCount(); ++it) {
			NBTTagCompound item=(NBTTagCompound)lista.tagAt(it);
			int slot=item.getByte("Slot") & 255;
			if (slot ]= 0 && slot < this.inv.length) {
				this.inv[slot]=ItemStack.loadItemStackFromNBT(item);
			}
		}
	}

	@Override
	public void openChest() {
	}

	@Override
	public void closeChest() {
	}
}

Teraz do paczki teksturowej dodaj plik guiNAZWAGUI.png z wyglądem gui. Koniec.


7.Biom

W tej części zrobisz swój biom. Jeśli w tym biomie będą się generowały bloki z twojego moda to dodaj do moda dwa nowe bloki. Jeden który będzie generował się na samej górze(tak jak trawa) i drugi(taki jak dirt). WAŻNE! Ich id musi być mniejsze od 256! Stwórz teraz paczkę z biomami(nazwa taka jak paczka domyślna + .world.biome) i dodaj do niej klasę BiomeGenNAZWABIOMU. A w niej:

public class BiomeGenNAZWABIOMU extends BiomeGenBase {
	public BiomeGenNAZWABIOMU(int id) {
		super(id);
		topBlock=(byte)BLOKGORA.blockID;
		fillerBlock=(byte)BLOKDIRT.blockID;
	}
}

BLOKGORA to nazwa bloku który będzie się generował tak jak trawa(na górze), a BLOKDIRT to nazwa bloku który będzie generował się pod BLOKGORA, ale nad kamieniem(jak dirt). Jeśli dany blok jest ze zwykłego minecrafta to daj przed nim Block., a jeśli jest on z moda to daj przed nim NAZWAMODA. . Musi być kropka po nazwie moda, lub Block. Teraz do klay głównej dodaj zmienną:

public static int idBiomeNAZWABIOMU=IDBIOMU;

IDBIOMU to id biomu, najlepiej większe od 30(od 0 do 22 zajmuje minecraft) i mniejsze od 128. Id nie mogą się powtarzać.
Dodaj też

public static BiomeGenBase biomeNAZWABIOMU;

W funkcji preInit() przed proxy.saveConfig() daj

idBiomeNAZWABIOMU=proxy.getConfig().get("BiomeNAZWABIOMU", Configuration.CATEGORY_GENERAL, idBiomeNAZWABIOMU).getInt();

Musi być skończony rozdział o pliku konfiguracyjnym. Teraz do funkcji init() dodaj

biomeNAZWABIOMU=new BiomeGenNAZWABIOMU(idBiomeNAZWABIOMU).setBiomeName("NAZWABIOMUWYS");
GameRegistry.addBiome(biomeNAZWABIOMU);

NAZWABIOMUWYS będzie to nazwa biomu która wyświetli się po kliknięciu F3(NAZWABIOMU nie będzie wyświetlana).
W następnej części pokaże jak bardziej zmienić biom(wyłączenie deszcu, kolor nieba, inne potworki spawnujące się, itd.)


7a. Właściwosci biomu

W tej części dowiesz się jak zmienić właściwości biomu. Oto lista rzeczy które opiszę:
1. Wyłączanie deszczu

Aby wyłączyć deszcz, lub śnieg, udaj się do linijki deklarującej twój biom(czyli:

biomeNAZWABIOMU=new BiomeGenNAZWABIOMU(idBiomeNAZWABIOMU).setBiomeName("NAZWABIOMUWYS");

). Na końcu przed średnikiem, dodaj takie coś:

.setDisableRain();

 


Dalsza część zostanie dodana dzisiaj albo jutro.

 


Instalacja

Punkty 8 i 9 wykonujemy tylko jeśli robimy moda pod ModLoader, jesli pod Forge, omijamy je.
1. MCP i JDK

 

  • Pobieramy JDK
     http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.html
    dla odpowiedniego systemu.
  • Instalujemy to co pobraliśmy.
  • Dodajemy zmienną środowiskową dla javy: Komputer > PPM na tle > Właściwości > Zaawansowane ustawienia systemu > Zmienne środowiskowe > Do path dodajemy ścieżkę do javy.
  • Uruchamiamy wiersz poleceń i wpisujemy javac. Jeśli wyświetla się lista to możecie robić dalsze punkty. Jeśli konsola nie rozpozna polecenia, sprawdź czy dobrze dodałeś zmienną środowiskową.
  • Pobieramy najnowszy MCP
     http://mcp.ocean-lab...
  • Tworzymy gdzieś folder(może być na pulpicie) i kopiujemy do niego zawartość pobranego MCP.
  • Włączamy minecrafta i przed logowaniem w opcjach ustawiamy force update (pobierzemy czystego minecrafta), logujemy się.
  • Pobieramy ModLoader
    http://dl.dropbox.co...
  • Wchodzimy w appdata ] .minecraft ] bin ] minecraft.jar, usuwamy META-INF, przenosimy pliki ModLoadera do minecraft.jar.
  • Kopiujemy foldery bin i resources z .minecraft do jars w folderze z MCP.
  • Pobieramy minecraft_server.jar z minecraft.net i kopiujemy go do jars w folderze z MCP.
  • Pobierz Eclipse Classic 4.2
     http://www.eclipse.o...
    Teraz jeśli zamierzasz robić moda pod Forge, przejdź do następnej części.
  • W folderze z MCP uruchamiamy decompile.bat.
  • Uruchom Eclipse i ustaw workspace na folder eclipse w folderze z mcp.

 


Po lewej stronie okna są pliki minecrafta.
Aby sprawdzić czy mod działa zapisz go i włącz Run > Run last launched w górnym menu. Wtedy włączy się minecraft z modem.
Aby zkompilować kod uruchom recompile.bat
Aby uzyskać zkompilowane pliki moda włącz reobfuscate.bat , pliki będą w folderze reobfuscate\minecraft.
2. Forge

Z tej części korzystaj tylko jeśli chcesz tworzyć moda pod Forge, jeśli nie to omiń ją.
W tej częśći dowiesz się jak zainstalować FML do MCP. Najpierw trzeba wykonać punk 1.Instalacja MCP. Jesli ją już wykonasz to pobierz najnowszą wersje Minecraft Forge na 1.5. Teraz skopiuj folder forge z pliku Forge który przed chwilą pobraleś do folderu z MCP. Teraz uruchom instal.cmd w folderze forge, uruchomi się konsola z instalacją Forge, instalacja trwa dosyć długo. Tworzenie, dekompilacja, i wypakowywanie(reobfuscate.bat) niczym się nie różnią od tego bez Forge. Uruchom Eclipse i ustaw workspace na folder eclipse w folderze z mcp.
Części tuta do których potrzebne będzie forge będą oznaczone (F).

 


Tutorial będę rozwijał.
Oto lista rzeczy które zamierzam dodać:

  • Model moba
  • Drzewa
  • Nowy wymiar
  • Struktury
  • Moby
  • Więcej o GUI
  • Kilka GUI w jednym modzie

Proszę o podawanie błędów(jeśli je zrobiłem). Jeśli czegoś nie rozumiesz, lub masz błąd to pisz.

Zabraniam kopiowania tutoriala bez mojej zgody.

 

Poradnik poprawiony przez kondzio0715.

  • Odpowiedzi 1,2 tys.
  • Dodano
  • Ostatniej odpowiedzi
Opublikowano

No no no ładnie ładnie nie moge sie doczekać kiedy wszystko skończysz;]

Zrobie se własnego moda aha byłbym zapomniał leci Like xD

xxx

Opublikowano

Ooo ciekawa rzecz, nie przestawaj tworzyć tutoriala! :)

Oferuję moje usługi webdeveloperskie (HTML, CSS, JavaScript (jQuery, AJAX!), PHP, MySQL, PERL).

Więcej pod PM.

Opublikowano

Zarąbiste, czytalem juz troche takich, ale byly tylko bloki itemy craftingi i przetapianie. Ja czekam na np

narzędzia.

 

 

@edit 1

Dzięki za narzędzia. Dokończ, a bedzie wspaniale!!! Daje plusa. :D

 

@edit 2

Nie moge sie doczekać Gui struktur i roślin

 

@edit 3

Teraz tylko GUI i będzie SUPER!!!!

Halo!

Opublikowano

A ja chętnie bym się dowiedział jak np. tworzyć efekty wizualne, czyli choćby takie rzeczy jak są w łuku zastosowane w łuku (naciąganie cięciwy, zoom przy celowaniu etc.). Jeśli mówisz, że inne poradniki to podstawy to ja chciałbym, abyś poszedł w takim kierunku, ale lajk jak najbardziej leci !

106071453484304291456.jpeg

Opublikowano

Nareszcie ktoś się za to zabrał :) Duży like i czekam na dalszy rozwój !

 

@edit

Dodaj jeszcze jak zrobić aby po skuciu bloku wypadał nam przedmiot :) Albo exp.

 

@edit

Errory :(

 

 

== ERRORS FOUND ==
src\minecraft\net\minecraft\src\mod_Test.java:17: error: <identifier> expected
    ModLoader.addRecipe(new ItemStack(Suprise, 64), new Object[]
					   ^
src\minecraft\net\minecraft\src\mod_Test.java:17: error: illegal start of type
    ModLoader.addRecipe(new ItemStack(Suprise, 64), new Object[]
					    ^
src\minecraft\net\minecraft\src\mod_Test.java:17: error: ')' expected
    ModLoader.addRecipe(new ItemStack(Suprise, 64), new Object[]
						   ^
src\minecraft\net\minecraft\src\mod_Test.java:17: error: ';' expected
    ModLoader.addRecipe(new ItemStack(Suprise, 64), new Object[]
									 ^
src\minecraft\net\minecraft\src\mod_Test.java:17: error: <identifier> expected
    ModLoader.addRecipe(new ItemStack(Suprise, 64), new Object[]
											 ^
src\minecraft\net\minecraft\src\mod_Test.java:17: error: <identifier> expected
    ModLoader.addRecipe(new ItemStack(Suprise, 64), new Object[]
											  ^
src\minecraft\net\minecraft\src\mod_Test.java:17: error: illegal start of type
    ModLoader.addRecipe(new ItemStack(Suprise, 64), new Object[]
												 ^
src\minecraft\net\minecraft\src\mod_Test.java:17: error: <identifier> expected
    ModLoader.addRecipe(new ItemStack(Suprise, 64), new Object[]
												  ^
src\minecraft\net\minecraft\src\mod_Test.java:17: error: ';' expected
    ModLoader.addRecipe(new ItemStack(Suprise, 64), new Object[]
												   ^
src\minecraft\net\minecraft\src\mod_Test.java:17: error: <identifier> expected
    ModLoader.addRecipe(new ItemStack(Suprise, 64), new Object[]
															    ^
src\minecraft\net\minecraft\src\mod_Test.java:19: error: illegal start of type
								    "   ", " X ", "   ", 'X', Item.dirt
								    ^
src\minecraft\net\minecraft\src\mod_Test.java:19: error: <identifier> expected
								    "   ", " X ", "   ", 'X', Item.dirt
										 ^
src\minecraft\net\minecraft\src\mod_Test.java:19: error: ';' expected
								    "   ", " X ", "   ", 'X', Item.dirt
										  ^
src\minecraft\net\minecraft\src\mod_Test.java:19: error: illegal start of type
								    "   ", " X ", "   ", 'X', Item.dirt
											    ^
src\minecraft\net\minecraft\src\mod_Test.java:19: error: <identifier> expected
								    "   ", " X ", "   ", 'X', Item.dirt
												 ^
src\minecraft\net\minecraft\src\mod_Test.java:19: error: <identifier> expected
								    "   ", " X ", "   ", 'X', Item.dirt
													    ^
src\minecraft\net\minecraft\src\mod_Test.java:19: error: illegal start of type
								    "   ", " X ", "   ", 'X', Item.dirt
														    ^
src\minecraft\net\minecraft\src\mod_Test.java:19: error: ';' expected
								    "   ", " X ", "   ", 'X', Item.dirt
																  ^
src\minecraft\net\minecraft\src\mod_Test.java:19: error: <identifier> expected
								    "   ", " X ", "   ", 'X', Item.dirt
																	   ^
src\minecraft\net\minecraft\src\mod_Test.java:20: error: illegal start of type
						    });
							 ^
src\minecraft\net\minecraft\src\mod_Test.java:20: error: <identifier> expected
						    });
							  ^
src\minecraft\net\minecraft\src\mod_Test.java:20: error: ';' expected
						    });
							   ^
src\minecraft\net\minecraft\src\mod_Test.java:21: error: reached end of file whi
le parsing
}
^
23 errors
==================

 

Opublikowano

@up ale to najlepszy poradnik :) ja go nie uzyje ale moj brat tego szuka :D

eJxzSSxKSc1OzVPQVQgpzy9KTlQITi0qzy_nCsgvmca.png


Ten, który z demonami walczy, winien uważać, by samemu nie stać się jednym z nich. - Fryderyk Nietzsche

Opublikowano

@piotrek54PL

 

Nie dałeś na końcu moda }, prawda?

Na pewno dałeś te linijki kodu od craftingu w mod_NAZWAMODA(){} czyli tam gdzie NAZWABLOKU.addName() ?

Opublikowano

zajebiście ziomuś czekałem na to ! Będę spełniony jak napiszesz jak stworzyć moba i jego występowanie :) Zrobię ciebie jako króla w zamku heh :D

 

@edit

 

Pomoże ktoś? Nie wiem jak zrobić tą teksturkę

 

 

53357501279067238885.png

 

Lubie To

fw821y.png
Sygnaturka wykonana przez FailStunt


 

Opublikowano

Nie używaj painta bo on nie obsługuje przezroczystości!

Lepszy Gimp, bo obsługuje przezroczystość i ma więcej funkcji.

Jeśli po gimpie też tak masz to usuń warstwę i zrób nową.

I trzeba zapisywać jako .png .

Opublikowano

A może masz coś na taki problem, że kiedy odpalam Minecrfata z:

-> ModLoader, żeby mody działały

-> TooManyItems, żebym mógł dać sobie nowego itemka

-> Moj mod

 

To minecraft nie startuje. Znaczy jest logo Mojangu, potem szybkie okienko (coś o ModLoaderze) i black screen i sie po pol sekundy wylacza. Nie wiem w czym lezy błąd. Od razu mówię, że TMI i ModLoadera mam na poprawną wersję, dekompilacja pokazuje taki błąd:

'runtime\bin\applydiff.exe -p1 -u -i ..\..	emp	emp.patch -d src\minecraft' fai
led : 1
== ERRORS FOUND ==
When decompiling with ModLoader a single hunk failure in RenderBlocks is expecte
d and is not a problem
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\RenderBlocks
.#'
==================

 

a w czasie rekompilacji żaden błąd się nie pojawia, podobnie jak w czasie reobfuskacji.

 

W czasie dekompilacji w minecraft.jar poza standardowymi plikami znajduje sie tylko ModLoader.

 

Pomóżcie, nie mam pojecia co robie źle :(

Opublikowano

no no ładnie opisany a nie jak inne niezrozumiale :) plusik jest bo się czegoś porządnie dowiedziałem xD

03082059994152820902.jpg

Pomogłem? Jeśli tak daj plusika! Proszę o zdjęcie kilku%!

Opublikowano

@andych1 ten błąd przy dekompilacji może być, też go mam.

Odpal minecrafta przez plik .bat i zobacz co jest w konsoli i napisz tu.

Opublikowano

gdzie wpisać to smelting żeby przepalało? U mnie to wygląda następująco

 

 

package net.minecraft.src;
public class mod_OczyszczonyDiament extends BaseMod
{
	public static Item oczyszczonyDiament = new Item(666).setItemName("oczyszczonyDiament");
	public String getVersion()
	{
			return "1.0";
	}
	public void load(){}
	public mod_OczyszczonyDiament()
	{
oczyszczonyDiament.iconIndex = ModLoader.addOverride("/gui/items.png", "/OczyszczonyDiament/icon.png");
ModLoader.addName(oczyszczonyDiament, "Oczyszczony Diament");
ModLoader.addSmelting(264, new ItemStack(666, 1));
 }
}

 

 

i jest 1 błąd:

 

== MCP 6.2 (data: 6.2, client: 1.2.5, server: 1.2.5) ==

# found jad, jad patches, ff patches, osx patches, srgs, name csvs, doc csvs, pa

ram csvs, astyle, astyle config

== Recompiling client ==

> Cleaning bin

> Recompiling

'"C:\Program Files\Java\jdk1.7.0_04\bin\javac" -Xlint:-options -deprecation -g -

source 1.6 -target 1....' failed : 1

 

== ERRORS FOUND ==

 

src\minecraft\net\minecraft\src\mod_OczyszczonyDiament.java:14: error: no suitab

le constructor found for ItemStack(int,int)

ModLoader.addSmelting(264, new ItemStack(666, 9)

);

^

 

constructor ItemStack.ItemStack() is not applicable

(actual and formal argument lists differ in length)

constructor ItemStack.ItemStack(int,int,int) is not applicable

(actual and formal argument lists differ in length)

constructor ItemStack.ItemStack(Item,int,int) is not applicable

(actual and formal argument lists differ in length)

constructor ItemStack.ItemStack(Item,int) is not applicable

(actual argument int cannot be converted to Item by method invocation conv

ersion)

constructor ItemStack.ItemStack(Item) is not applicable

(actual and formal argument lists differ in length)

constructor ItemStack.ItemStack(Block,int,int) is not applicable

(actual and formal argument lists differ in length)

constructor ItemStack.ItemStack(Block,int) is not applicable

(actual argument int cannot be converted to Block by method invocation con

version)

constructor ItemStack.ItemStack(Block) is not applicable

(actual and formal argument lists differ in length)

1 error

==================

 

== Recompiling server ==

> Cleaning bin

> Recompiling

- Done in 13.00 seconds

Aby kontynuować, naciśnij dowolny klawisz . . .

 

Lubie To

fw821y.png
Sygnaturka wykonana przez FailStunt


 

Opublikowano

ModLoader.addSmelting(264, new ItemStack(666, 1));

W konstruktorze ItemStack, czyli ItemStack(666, 1) zamiast id wyniku dawaj blok.

Czyli:

ModLoader.addSmelting(264, new ItemStack(oczyszczonyDiament, 1));

A miejsce dobre.

 

@Edit Dodałem specjalne właściwości bloków i ulepszyłem tworzenie bloku(dodałem jak zrobić co wypada z bloku).

Zarchiwizowany

Ten temat przebywa obecnie w archiwum. Dodawanie nowych odpowiedzi zostało zablokowane.

×
×
  • Dodaj nową pozycję...