Jump to content

  • Curse Sites
Become a Premium Member! Help
Latest News Article

[Creating Mods] Modding tutorials [21/5/11]


  • Please log in to reply
5201 replies to this topic

#641

jms_gears1

Posted 20 January 2011 - 12:43 AM

bna1987 said:

I am having issues with the decompiling procedure. I copy my c:\users\blahblah\appdata\roaming\.mincraft\bin and c:\users\blahblah\appdata\roaming\.mincraft\resources directories to my d:\applications\mcp26\jar directory, run the decompile batch file and I get the following output.

Decompile.bat Output
*** Minecraft Coder Pack Version 2.6 ***
MCP 2.6 running in D:\Applications\mcp26
Deobfuscating minecraft.jar
Unpacking minecraft.jar
Fixing minecraft classes
Decompiling minecraft classes
Repackage minecraft sources
Patching minecraft sources
2 out of 5 hunks FAILED -- saving rejects to file 'net\minecraft\client\Minecraf
t.jav#'
1 out of 2 hunks FAILED -- saving rejects to file 'net\minecraft\client\Minecraf
tAppl#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\CanvasMinecr
a#'
3 out of 3 hunks FAILED -- saving rejects to file 'net\minecraft\src\ChunkLoader
.j#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\CodecMus.jav
a#'
4 out of 4 hunks FAILED -- saving rejects to file 'net\minecraft\src\CompressedS
tr#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\EntitySorter
.#'
3 out of 4 hunks FAILED -- saving rejects to file 'net\minecraft\src\EnumArt.jav
a#'
2 out of 3 hunks FAILED -- saving rejects to file 'net\minecraft\src\EnumCreatur
eT#'
3 out of 3 hunks FAILED -- saving rejects to file 'net\minecraft\src\EnumMobType
.j#'
5 out of 6 hunks FAILED -- saving rejects to file 'net\minecraft\src\EnumOptions
.j#'
2 out of 3 hunks FAILED -- saving rejects to file 'net\minecraft\src\EnumOS1.jav
a#'
2 out of 3 hunks FAILED -- saving rejects to file 'net\minecraft\src\EnumOS2.jav
a#'
3 out of 3 hunks FAILED -- saving rejects to file 'net\minecraft\src\EnumSkyBloc
k.#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\GameWindowLi
s#'
2 out of 2 hunks FAILED -- saving rejects to file 'net\minecraft\src\GuiChat.jav
a#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\GuiEditSign.
j#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\GuiMainMenu.
j#'
2 out of 2 hunks FAILED -- saving rejects to file 'net\minecraft\src\GuiMultipla
ye#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\IChunkLoader
.#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\LogoEffectRa
n#'
3 out of 3 hunks FAILED -- saving rejects to file 'net\minecraft\src\MapGenCaves
.j#'
3 out of 3 hunks FAILED -- saving rejects to file 'net\minecraft\src\MapGenCaves
He#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\MinecartTrac
k#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\MinecraftApp
l#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\MinecraftImp
l#'
2 out of 2 hunks FAILED -- saving rejects to file 'net\minecraft\src\MusInputStr
ea#'
3 out of 3 hunks FAILED -- saving rejects to file 'net\minecraft\src\NBTBase.jav
a#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\NBTTagByte.j
a#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\NBTTagByteAr
r#'
2 out of 2 hunks FAILED -- saving rejects to file 'net\minecraft\src\NBTTagCompo
un#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\NBTTagDouble
.#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\NBTTagEnd.ja
v#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\NBTTagFloat.
j#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\NBTTagInt.ja
v#'
2 out of 2 hunks FAILED -- saving rejects to file 'net\minecraft\src\NBTTagList.
ja#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\NBTTagLong.j
a#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\NBTTagShort.
j#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\NBTTagString
.#'
2 out of 2 hunks FAILED -- saving rejects to file 'net\minecraft\src\NetClientHa
nd#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\NetworkManag
e#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\NetworkMaste
r#'
2 out of 2 hunks FAILED -- saving rejects to file 'net\minecraft\src\NetworkRead
er#'
2 out of 2 hunks FAILED -- saving rejects to file 'net\minecraft\src\NetworkWrit
er#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\NextTickList
E#'
2 out of 2 hunks FAILED -- saving rejects to file 'net\minecraft\src\Packet.java
#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\Packet0KeepA
l#'
2 out of 2 hunks FAILED -- saving rejects to file 'net\minecraft\src\Packet100.j
av#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\Packet101.ja
v#'
2 out of 2 hunks FAILED -- saving rejects to file 'net\minecraft\src\Packet102.j
av#'
2 out of 2 hunks FAILED -- saving rejects to file 'net\minecraft\src\Packet103.j
av#'
2 out of 2 hunks FAILED -- saving rejects to file 'net\minecraft\src\Packet104.j
av#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\Packet105.ja
v#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\Packet106.ja
v#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\Packet10Flyi
n#'
2 out of 2 hunks FAILED -- saving rejects to file 'net\minecraft\src\Packet11Pla
ye#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\Packet12Play
e#'
2 out of 2 hunks FAILED -- saving rejects to file 'net\minecraft\src\Packet130.j
av#'
2 out of 2 hunks FAILED -- saving rejects to file 'net\minecraft\src\Packet13Pla
ye#'
2 out of 2 hunks FAILED -- saving rejects to file 'net\minecraft\src\Packet14Blo
ck#'
2 out of 2 hunks FAILED -- saving rejects to file 'net\minecraft\src\Packet15Pla
ce#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\Packet16Bloc
k#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\Packet18ArmA
n#'
2 out of 2 hunks FAILED -- saving rejects to file 'net\minecraft\src\Packet20Nam
ed#'
2 out of 2 hunks FAILED -- saving rejects to file 'net\minecraft\src\Packet21Pic
ku#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\Packet22Coll
e#'
2 out of 2 hunks FAILED -- saving rejects to file 'net\minecraft\src\Packet23Veh
ic#'
2 out of 2 hunks FAILED -- saving rejects to file 'net\minecraft\src\Packet24Mob
Sp#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\Packet255Kic
k#'
2 out of 2 hunks FAILED -- saving rejects to file 'net\minecraft\src\Packet28.ja
va#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\Packet29Dest
r#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\Packet2Hands
h#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\Packet30Enti
t#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\Packet32Enti
t#'
2 out of 2 hunks FAILED -- saving rejects to file 'net\minecraft\src\Packet33Rel
En#'
2 out of 2 hunks FAILED -- saving rejects to file 'net\minecraft\src\Packet34Ent
it#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\Packet38.jav
a#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\Packet39.jav
a#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\Packet3Chat.
j#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\Packet4Updat
e#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\Packet50PreC
h#'
2 out of 2 hunks FAILED -- saving rejects to file 'net\minecraft\src\Packet51Map
Ch#'
2 out of 2 hunks FAILED -- saving rejects to file 'net\minecraft\src\Packet52Mul
ti#'
2 out of 2 hunks FAILED -- saving rejects to file 'net\minecraft\src\Packet53Blo
ck#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\Packet5Playe
r#'
2 out of 2 hunks FAILED -- saving rejects to file 'net\minecraft\src\Packet60.ja
va#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\Packet6Spawn
P#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\Packet8.java
#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\Packet9.java
#'
2 out of 2 hunks FAILED -- saving rejects to file 'net\minecraft\src\RecipeSorte
r.#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\RenderArrow.
j#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\RenderBoat.j
a#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\RenderChicke
n#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\RenderCow.ja
v#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\RenderCreepe
r#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\RenderEngine
.#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\RenderFallin
g#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\RenderFireba
l#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\RenderFish.j
a#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\RenderGhast.
j#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\RenderGlobal
.#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\RenderItem.j
a#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\RenderLiving
.#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\RenderMineca
r#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\RenderPainti
n#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\RenderPig.ja
v#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\RenderPlayer
.#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\RenderSheep.
j#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\RenderSlime.
j#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\RenderSorter
.#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\RenderSpider
.#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\RenderTNTPri
m#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\RenderZombie
S#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\SlotArmor.ja
v#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\SpawnerAnima
l#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\TexturePackC
u#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\ThreadConnec
t#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\ThreadDownlo
a#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\ThreadDownlo
a#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\ThreadRunIso
C#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\ThreadSleepF
o#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\TileEntityMo
b#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\TileEntitySi
g#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\WorldBlockPo
s#'
1 out of 1 hunk FAILED -- saving rejects to file 'net\minecraft\src\WorldIso.jav
a#'
*** minecraft_server.jar was not found, skipping
Renaming methods and fields
=== MCP 2.6 decompile script finished ===
Press any key to continue . . .

I went ahead and tried to follow the block example with these decompile errors. I viewed the block class file and didn't see any block variable declarations.

Block.java
package net.minecraft.src;
// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.kpdus.com/jad.html
// Decompiler options: packimports(3) braces deadcode 


public class Block extends MinecraftError
{

	protected Block(int i, int j)
	{
		super(i, j);
		float f = 0.2F;
		func_20262_a(0.5F - f, 0.0F, 0.5F - f, 0.5F + f, f * 2.0F, 0.5F + f);
	}

	protected boolean func_20446_c(int i)
	{
		return EntityFlying.field_20325_o[i];
	}

	public boolean func_20279_g(EnumOptionsMappingHelper enumoptionsmappinghelper, int i, int j, int k)
	{
		return enumoptionsmappinghelper.func_21558_l(i, j, k) <= 13 && func_20446_c(enumoptionsmappinghelper.func_21457_a(i, j - 1, k));
	}
}

Thanks in advance.
Im having this exact same problem.

What version were you trying to decompile?

Register or log in to remove.

#642

Sploder
    Sploder

    Coal Miner

  • Members
  • 118 posts

Posted 20 January 2011 - 01:13 AM

That's definitely due to decompiling an incompatible version of minecraft.jar. Block.java shouldn't look anything like that, and it certainly doesn't extend MinecraftError (it doesn't extend anything, actually).

#643

jms_gears1

Posted 20 January 2011 - 01:19 AM

Sploder said:

That's definitely due to decompiling an incompatible version of minecraft.jar. Block.java shouldn't look anything like that, and it certainly doesn't extend MinecraftError (it doesn't extend anything, actually).
Thats what i thought. I tried decompiling the latest version (I knew that MCP said it wouldnt work but i decided to try anyway)

So since there is no MCP for the newest version, I would have to figure out whats what and go from there?

#644

Sploder
    Sploder

    Coal Miner

  • Members
  • 118 posts

Posted 20 January 2011 - 01:25 AM

Essentially, yes. However, it does help if you have a previous version to look through. Of course, if you don't, you can also look through some fellow modder's decompiled code for some hints to what a few of the classes are.

Also, since the real block and item class contain a bunch of variables with the names of the blocks and items (as well as the classes for all of these, if they have unique classes), so it's certainly a relatively easy file to find (btw, I think the block class is currently pj, so look around there if you want to find that one).

#645

pwned
    pwned

    Gold Miner

  • Members
  • 420 posts

Posted 20 January 2011 - 01:28 AM

hey should this change the spawn point to the players position?
public void onBlockClicked(World world, int x ,int y , int z, EntityPlayer entityplayer)
	{
	   world.spawnX=MathHelper.floor_double(entityplayer.posX);
	   world.spawnY=MathHelper.floor_double(entityplayer.posY);
	   world.spawnZ=MathHelper.floor_double(entityplayer.posZ);
	}


#646

jms_gears1

Posted 20 January 2011 - 02:01 AM

Sploder said:

Essentially, yes. However, it does help if you have a previous version to look through. Of course, if you don't, you can also look through some fellow modder's decompiled code for some hints to what a few of the classes are.

Also, since the real block and item class contain a bunch of variables with the names of the blocks and items (as well as the classes for all of these, if they have unique classes), so it's certainly a relatively easy file to find (btw, I think the block class is currently pj, so look around there if you want to find that one).
Thanks for your help so far.


Where could i find previous versions of minecraft?

#647

pwned
    pwned

    Gold Miner

  • Members
  • 420 posts

Posted 20 January 2011 - 02:38 AM

jms_gears1 said:

Sploder said:

Essentially, yes. However, it does help if you have a previous version to look through. Of course, if you don't, you can also look through some fellow modder's decompiled code for some hints to what a few of the classes are.

Also, since the real block and item class contain a bunch of variables with the names of the blocks and items (as well as the classes for all of these, if they have unique classes), so it's certainly a relatively easy file to find (btw, I think the block class is currently pj, so look around there if you want to find that one).
Thanks for your help so far.


Where could i find previous versions of minecraft?
Unless you have a backup of the previous versions the only thing u can do is use this program that reverts it i forget its name tho. Its the only legal way to do it because downloading a torrent of it is illegal.
Someone should no the name.

#648

Anselm
    Anselm

    Carpenter

  • Members
  • 41 posts
  • Location: Columbus, Ohio.

Posted 20 January 2011 - 02:39 AM

Would this code work? (also, a couple questions about Java commands, I'm new to Java, though I do have programming experience.)

Basically, I want (on a certain key press) the code to look through the inventory for armor, and equip the best armor in your inventory. (essentially checking each inventory slot, checking if it's armor, then if so checking what type of armor it is. After going through each slot, equip armor H C L F (Head, Chest, Legs, Feet. Respectively.))

(this is the code specifically for the head slot. The code will be repeated for each slot.)
h = 0
for (i = 0, i <= 35, i += 1) {
getBlocktype.i;
if (blockType = 1){
getArmortype;
for (a = 1, a <=5, a+=1){
if (armortype = a && a > h){
h = i
}
}
}
}
(Equipping code here.)

My question is, would that code (repeated) do what I said above? Also, how would I equip the armor to the slot (I was thinking something like H storing the inventory slot carrying the highest armor, then telling the code to equip whatever is in slot H)

#649

Toq
    Toq

    Out of the Water

  • Members
  • 8 posts

Posted 20 January 2011 - 02:42 AM

I have been playing around with Jd-gui for a bit looking through the class files. Yesterday i decided to play around with making changes and recompiling Minecraft.java. I used both netbeans with the lwjgl and the minecraft.jar as libraries. Had some issues most were understandable as decompile on any platform is never perfect. But how do you get around java not wanting to reference class files in the default package? (deprecated after jkd 1.4)

Returning to java after a very long hiatus.  Thought i might try to make a parachute mod.

#650

jms_gears1

Posted 20 January 2011 - 02:56 AM

pwned said:

jms_gears1 said:

Sploder said:

Essentially, yes. However, it does help if you have a previous version to look through. Of course, if you don't, you can also look through some fellow modder's decompiled code for some hints to what a few of the classes are.

Also, since the real block and item class contain a bunch of variables with the names of the blocks and items (as well as the classes for all of these, if they have unique classes), so it's certainly a relatively easy file to find (btw, I think the block class is currently pj, so look around there if you want to find that one).
Thanks for your help so far.


Where could i find previous versions of minecraft?
Unless you have a backup of the previous versions the only thing u can do is use this program that reverts it i forget its name tho. Its the only legal way to do it because downloading a torrent of it is illegal.
Someone should no the name.
I found an older version of the actual .jar file on my computer. I just replaced the .jar file in the /bin file. Would that work?

#651

blahthing

Posted 20 January 2011 - 02:56 AM

Hey simo



Ughh

Can u tell me what the  new class files for

Items
Blocks
RenderManager
CraftingManager
RecipesWeapons
TileFurnace
MobSpawnerBase

and i think thats about it
Im having so much trouble doing it i dont even think i can update my mod

If you do answer Thank You So Much !
The Shadow Gems Prevail!
Posted Image

#652

blahpers
    blahpers

    Tree Puncher

  • Members
  • 22 posts

Posted 20 January 2011 - 03:23 AM

blahthing said:

Hey simo



Ughh

Can u tell me what the  new class files for

Items
Blocks
RenderManager
CraftingManager
RecipesWeapons
TileFurnace
MobSpawnerBase

and i think thats about it
Im having so much trouble doing it i dont even think i can update my mod

If you do answer Thank You So Much !

Check here.
https://spreadsheets... ... 4skP#gid=2

#653

pwned
    pwned

    Gold Miner

  • Members
  • 420 posts

Posted 20 January 2011 - 04:05 AM

jms_gears1 said:

pwned said:

jms_gears1 said:





Where could i find previous versions of minecraft?
Unless you have a backup of the previous versions the only thing u can do is use this program that reverts it i forget its name tho. Its the only legal way to do it because downloading a torrent of it is illegal.
Someone should no the name.
I found an older version of the actual .jar file on my computer. I just replaced the .jar file in the /bin file. Would that work?
Yer that should work

#654

nohero
    nohero

    Redstone Miner

  • Members
  • 592 posts
  • Minecraft: Eddieboy987

Posted 20 January 2011 - 04:38 AM

Hey Simo, is there anyway to spawn something on the underside of a block? Cuz I may be making a bat entity that hopefully will rest upside down, clinging onto the ceiling. WIth some coding I could probably get it to find a "ceiling" block that then finds the space underneath (it will check if a block is there) then the bat is added in that location (meaning more code for the bat so it is not affected by gravity). You have any tips on what I should do?
Check out my Youtube Channel! http://www.youtube.com/user/EiDeHua Right now I'm doing a let's play of Sleeping Dogs! Working on updating my Luck's Edge mod, a LOT of new content! Also I've got another mod idea in mind! -Updated 8/16/12

#655

pwned
    pwned

    Gold Miner

  • Members
  • 420 posts

Posted 20 January 2011 - 05:36 AM

Has anyone made a mod that if a certain block exists it becomes the spawn point?

#656

Sploder
    Sploder

    Coal Miner

  • Members
  • 118 posts

Posted 20 January 2011 - 06:07 AM

I'm currently working on modifying my Spawn Totem mod to do that.

#657

pwned
    pwned

    Gold Miner

  • Members
  • 420 posts

Posted 20 January 2011 - 06:18 AM

Sploder said:

I'm currently working on modifying my Spawn Totem mod to do that.
o cause so far i've made a block that when clicked changes the spawn point to there.

#658

pwned
    pwned

    Gold Miner

  • Members
  • 420 posts

Posted 20 January 2011 - 06:25 AM

pwned said:

Sploder said:

I'm currently working on modifying my Spawn Totem mod to do that.
o cause so far i've made a block that when clicked changes the spawn point to there.
i guess i wont bother finishing mine then since urs is better lol

#659

OgreSean

Posted 20 January 2011 - 06:38 AM

I figured I'd try contributing a tutorial.  Hope you guys like it:

Advanced NPC Tutorial: Controlling NPC movement.
Last Updated February 16, 2011

This tutorial will explore multiple methods for modders to control NPC movement.  This tutorial is currently meant for Beta 1.2_02 and the java code shown in this tutorial uses MCP 2.7's de-obfuscated names.  For now, this tutorial only details 2 methods of controlling NPC movement, but I will add more methods in the future.

Method 1: Overriding EntityCreature's getBlockPathWeight() function

When an NPC is idle, it will randomly move around.  The NPC does this by occasionally randomly selecting 10 nearby blocks, and checking their Block Path Weights (BPW).  The block with the highest BPW will be selected as the destination for the NPC to move to.  

The getBlockPathWeight() function is called for each of the 10 blocks and returns a block's BPW.  This function influences how certain NPCs wander around while idle (as in not attacking anything).

default
protected float getBlockPathWeight(int i, int j, int k)
	{
		return 0.0F;
	}

The default function of EntityCreature gives the NPC no preference for any specific location.

Animals
protected float getBlockPathWeight(int i, int j, int k)
	{
		if(worldObj.getBlockId(i, j - 1, k) == Block.grass.blockID)
		{
			return 10F;
		} else
		{
			return worldObj.getLightBrightness(i, j, k) - 0.5F;
		}
	}
Animals will favor moving toward blocks above grass.  Otherwise, Animals will move toward lighted locations.

Monsters
protected float getBlockPathWeight(int i, int j, int k)
	{
		return 0.5F - worldObj.getLightBrightness(i, j, k);
	}
Monsters prefer moving toward dark locations.

By modifying or overriding the getBlockPathWeight function, you can change what locations a type of NPC will prefer to wander to.

For example, suppose I am creating a Mountain Goat NPC.  I want Mountain Goats to prefer high locations, thus I would use this getBlockPathWeight function:

protected float getBlockPathWeight(int i, int j, int k)
	{
		return (float) j;
	}
This simple getBlockPathWeight function makes the highest randomly selected block the Mountain Goat's destination.  Thus, Mountain Goats would have slightly better odds of traveling up hills, mountains, etc.

Now if I wanted to make Mountain Goats wander differently depending on the circumstances, I could try a getBlockPathWeight function like this:

protected float getBlockPathWeight(int i, int j, int k)
	{
		if(health < 5)
			return MathHelper.floor_double(getDistance(i, j, k));
		else if(!worldObj.isDaytime())
			return -(MathHelper.floor_double(getDistance(i, j, k)));
		else
			return (float) j;
	}
This function expands Goats to move differently depending on the circumstances.  
:Sheep: When they are low on hp, they will move much farther distances at a time.
:Sheep: During night time, they will move very short distances at a time.
:Sheep: During the day time, while they have high hp, they will prefer higher altitudes.

As a final example, let's say that I also wanted to make the Mountain Goat have no preference while swimming.  Then I would change my function to this:
protected float getBlockPathWeight(int i, int j, int k)
	{
		if(inWater)
			return 0.0F;
		else{
			if(health < 5)
				return MathHelper.floor_double(getDistance(i, j, k));
			else if(!worldObj.isDaytime())
				return -(MathHelper.floor_double(getDistance(i, j, k)));
			else
				return (float) j;
		}
	}
This getBlockPathWeight function would make my Mountain Goat wander with no preferences while in water.

Thus, overriding or changing this function presents a fairly easy way for you to influence what places NPCs prefer moving toward.  You could make specific NPCs prefer moving toward other specific NPCs or even the player.  You could also have NPCs prefer moving toward specific coordinates.  Why not make NPCs that wander differently depending on the block they are standing on? The possibilities are endless!

PS:  It is advised that you make sure the getBPW function does not return a negative number before your NPC spawns.  EntityLiving's canSpawnHere() function calls the getBPW function and will prevent your NPC from spawning if the BPW is less than 0.

-----

Method 2: Setting EntityCreature's playerToAttack variable

Each NPC extended from the EntityCreature class has a single playerToAttack variable which holds an entity.
When this variable is set to any entity, the NPC will set its next destination to the position of this playerToAttack entity.
By changing this playerToAttack variable, you can make an NPC move toward almost any entity.

However, there are some additional rules that must be considered when trying to do this:
1. While the playerToAttack variable is null, the NPC will regularly call the findPlayerToAttack()* function until the playerToAttack is no longer null.
2. Once an NPC sets its playerToAttack variable, by default, this variable will only change when the playerToAttack entity is dead.
3. The NPC will only move toward the playerToAttack entity if the playerToAttack is within a distance of 16.
4. The NPC will only move toward the playerToAttack entity if there are no obstacles blocking all possible paths to the playerToAttack.
5. While either rule 3 or 4 is violated, the NPC will be idle and wander around until both conditions are met.
6. NPCs extended from the EntityMobs class have additional coding that makes them damage their target when close, and change their target under additional circumstances.

*EntityCreature's default findPlayerToAttack() function always returns null.

So, how should you change this variable?  Well, you have almost unlimited options.  You can simply set or nullify this variable like any other variable.  You can change this variable at any time by using overwritten functions.  The most obvious function to overwrite would be the findPlayerToAttack() function.

Let's look back at my Mountain Goat example from Movement Control Method 1.  Here's what overwritten findPlayerToAttack() function I would use if I wanted Goats to follow the nearest sheep:
protected Entity findPlayerToAttack()
	{
		double d1 = -1D;
		EntitySheep sheep = null;
		
		//check each entity that is in the world
		for(int i = 0; i < worldObj.loadedEntityList.size(); i++)
		{
			Entity entity1 = (Entity)worldObj.loadedEntityList.get(i);
			
			//if entity is not a sheep, check next entity on entityList
			if(!(entity1 instanceof EntitySheep))
			{
				continue;
			}
			
			//if sheep, check how far it is from goat.
			//The closest "seen" sheep within a distance of 16 will be identified by the sheep variable.
			double d2 = entity1.getDistance(posX, posY, posZ);
			if((d2 < 16) && (d1 == -1D || d2 < d1) && ((EntitySheep)entity1).canEntityBeSeen(this))
			{
				d1 = d2;
				sheep = (EntitySheep)entity1;
			}
		}

		return sheep; //returns the closest sheep to the goat
	}
This function will make Mountain Goats regularly check for nearby sheep when they have no playerToAttack set.  If they find a nearby sheep, they will set that sheep as their permanent target and follow it for as long as it lives.

Not satisfied with just moving your own NPC?  Well, there's more!
Since all NPCs have a public playerToAttack variable, you can change the playerToAttack of any creature at any time.
For example, instead of having my Mountain Goats follow sheep, lets have the sheep follow my goats.  
To do this, I will no longer need a modified findPlayerToAttack() function.  Instead I will use this overwritten onUpdate() function:
public void onUpdate()
	{
		super.onUpdate();
		
		//check each entity that is in the world
		for(int i = 0; i < worldObj.loadedEntityList.size(); i++)
		{
			Entity entity1 = (Entity)worldObj.loadedEntityList.get(i);
			
			//if entity is not a sheep, check next entity on entityList
			if(!(entity1 instanceof EntitySheep))
			{
				continue;
			}
			
			//if nearby "seen" sheep's playerToAttack is null, set it to this goat
			double d2 = entity1.getDistance(posX, posY, posZ);
			EntitySheep sheep = (EntitySheep)entity1;
			if((d2 < 16) && sheep.canEntityBeSeen(this) && sheep.playerToAttack == null)
			{
				sheep.playerToAttack = this;
			}
		}
	}
This function will make goats regularly check for nearby idle sheep.  Any idle sheep near a goat will follow that goat.

Finally, there is one more trick for using the playerToAttack variable.  Instead of setting the playerToAttack variable to existing creatures, you can also set the playerToAttack variable to a newly created entity altogether.  If you never call worldObj's entityJoinedWorld() function for this entity, it will be completely invisible and "frozen".  Since the entity never joins the world, its OnUpdate function will never be called, thus preventing it from moving and being interacted with.  If you are creative, you can use this for a variety of "Orders" that your NPC will follow.

For example, suppose I want my Mountain Goats to continuously patrol between location A and location B.  Assuming I have already set the coordinates for these locations, I could overwrite my Goat's onUpdate function as follows:
public void onUpdate()
	{
		super.onUpdate();
		
		//if Goat is near location A, order it to move to location B
		if(this.getDistance(locAX, locAY, locAZ) < 4){
			//create new Entity at location B for Goat to move toward
			playerToAttack = (Entity) new EntityItem(worldObj);
			playerToAttack.setPosition(locBX, locBY, locBZ);
		}
		//if Goat is near location B or has no playerToAttack set, order it to move to location A
		else if(this.getDistance(locBX, locBY, locBZ) < 4 || playerToAttack == null){
			//create new Entity at location A for Goat to move toward
			playerToAttack = (Entity) new EntityItem(worldObj);
			playerToAttack.setPosition(locAX, locAY, locAZ);
		}
	}
This onUpdate() function would cause the Goat to continiously walk back and forth between locations A and B.  Since I have to consider the rules of the playerToAttack variable, the distance between locations A and B must be less than 16, and there has to be no major obstacles between them.  If I added more locations, I could have my Goats patrol farther distances.

In conclusion, the playerToAttack variable is very versatile, provided you keep in mind the rules of its use.  I encourage you to experiment with it.  Enjoy!
-----

I will update this post with an additional NPC movement control method eventually, involving setting the creature's private pathEntity using ModLoader's setPrivateField method.

Note: I am unsure of whether it is animals or monsters that prefer bright places.  The code for that GetLightBrightness function is really complicated.  Can anyone verify which one prefers bright places?
Check out the mod I'm making!
Builder Mobs 0.53
Posted Image
My Other Mods Here

#660

velvokay
  • Location: West coast

Posted 20 January 2011 - 07:06 AM

That's some very helpful code there OgreSean. I'll be sure to use these in my crab, thank you.
Posted Image