Jump to content

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

[ModLoader] How to make a guard mob. Archer [19/08/2011]


  • Please log in to reply
15 replies to this topic

#1

HappyConsole
  • Location: Russia
  • Minecraft: FunnyAlien

Posted 19 August 2011 - 03:56 PM

Hi guys,

This article is intended for advanced users who know how to do the simplest mod for minecraft, and here I try to tell you how to make a new mob that will protect you while standing on the spot.

So here we go:
Create a file mod_BowMan.java which we give our defender unit spawn:
package net.minecraft.src;

public class mod_BowMan extends BaseMod
{

public static final Block BowManEgg = (new BlockBowManEgg(164, 0)).setHardness(0.0F).setResistance(0.0F).setBlockName("BowManegg");

	public mod_BowMan()
	{
		ModLoader.RegisterBlock(BowManEgg);
		ModLoader.AddName(BowManEgg, "Bowman Egg");
		BowManEgg.blockIndexInTexture = ModLoader.addOverride("/terrain.png", "/textures/bowmanegg.png");
		ModLoader.AddRecipe(new ItemStack(BowManEgg, 1), new Object[] { "X", Character.valueOf('X'), Block.dirt});
		ModLoader.RegisterEntityID(net.minecraft.src.EntityBowMan.class, "entityBowMan", ModLoader.getUniqueEntityId());
	}

	public String Version()
	{
		return "Guard Mob Tutorial by Perpetual Motion Team";
	}
		
}

Now create a file EntityBowMan.java
Start-such as in the creation of a neutral mob:
package net.minecraft.src;

import java.util.List;
import java.util.Random;

public class EntityBowMan extends EntityAnimal
{

	public EntityBowMan(World world)
	{
		super(world);
		texture = "/mob/char.png";
		moveSpeed = 0.0F;
		health = 50;
		isImmuneToFire = true;
	}

But there is a couple of new lines in the code.
The rate of movement of the mob (0.7F - speed of the player, 0.0F - mob stand still), as we have archer, so the speed of 0.
moveSpeed = 0.0F;

Mob life (1 life - half of the heart, player have - 20 lives).
health = 50;

Immune to fire (and lava).
isImmuneToFire = true;

Now we finish.
So mob is not lost:
protected boolean canDespawn()
	{
		return false;
	}

Now it is necessary so that the archer saw basic enemies.
Here in every variable of type "list" data is written to the enemy mob:
protected void updatePlayerActionState()
	{
		if(playerToAttack == null)
		{
			List list;
			list = worldObj.getEntitiesWithinAABB(net.minecraft.src.EntityMob.class, AxisAlignedBB.getBoundingBoxFromPool(posX - 16.0D, posY - 4.0D, posZ - 16.0D, posX + 17.0D, posY + 5.0D, posZ + 17.0D));
			if(list.isEmpty())
			{
				list = worldObj.getEntitiesWithinAABB(net.minecraft.src.EntityMob.class, AxisAlignedBB.getBoundingBoxFromPool(posX - 16.0D, posY - 12.0D, posZ - 16.0D, posX + 17.0D, posY - 4.0D, posZ + 17.0D));
				if(list.isEmpty())
				{
				list = worldObj.getEntitiesWithinAABB(net.minecraft.src.EntityMob.class, AxisAlignedBB.getBoundingBoxFromPool(posX - 16.0D, posY - 20.0D, posZ - 16.0D, posX + 17.0D, posY - 12.0D, posZ + 17.0D));			 
				}
			}
			if(!list.isEmpty())
			{
				setTarget((Entity)list.get(worldObj.rand.nextInt(list.size())));
			}
		}
		super.updatePlayerActionState();
	}

Now process the event an attack:
protected void attackEntity(Entity entity, float f)
	{
		if(f < 240F)
		{
			double d = entity.posX - posX;
			double d1 = entity.posZ - posZ;
			if(attackTime == 0)
			{
				EntityArrow entityarrow = new EntityArrow(worldObj, this);
				entityarrow.posY += 0.1999999761581421D;
				double d2 = (entity.posY + (double)entity.getEyeHeight()) - 0.20000000298023224D - entityarrow.posY;
				float f1 = MathHelper.sqrt_double(d * d + d1 * d1) * 0.2F;
				worldObj.playSoundAtEntity(this, "random.bow", 1.0F, 1.0F / (rand.nextFloat() * 0.4F + 0.8F));
				worldObj.entityJoinedWorld(entityarrow);
				entityarrow.setArrowHeading(d, d2 + (double)f1, d1, 1.5F, 12F);
				attackTime = 2;
			}
			rotationYaw = (float)((Math.atan2(d1, d) * 180D) / 3.1415927410125732D) - 90F;
			hasAttacked = true;
		}
	}

If you know how to program properly, you can change this code to your treatment.
I am explain only one variable:

Time before the next attack (at the time of the skeleton = 30, and we have about 15 times faster).
attackTime = 2;

And finally we finish the ending:
 protected String getLivingSound()
	{
		return "mob.skeleton";
	}

	protected String getHurtSound()
	{
		return "mob.skeletonhurt";
	}

	protected String getDeathSound()
	{
		return "mob.skeletondeath";
	}

	private int angerLevel;
	private int randomSoundDelay;
}

Now we need to make the file BlockBowManEgg.java:
package net.minecraft.src;

import java.io.PrintStream;
import java.util.Random;

public class BlockBowManEgg extends Block
{

	protected BlockBowManEgg(int i, int j)
	{
		super(i, j, Material.ground);
	}

	public int quantityDropped(Random random)
	{
		return 1;
	}

	public int tickRate()
	{
		return 30;
	}

	public void onBlockClicked(World world, int i, int j, int k, EntityPlayer entityplayer)
	{
		double d = i;
		double d1 = j;
		double d2 = k;
		EntityBowMan entitybowman = new EntityBowMan(world);
		entitybowman.setLocationAndAngles(d, d1, d2, world.rand.nextFloat() * 360F, 0.0F);
		world.entityJoinedWorld(entitybowman);
	}
}

It's simple - by pressing the left mouse button to block break (because that solidity-0) and causing it to spawn an archer.
Only the texture:
The texture of the archer - not needed (the code is entered the standard texture player).
Texture bowmanegg.png - take any file 16 * 16 and throw in a folder in the textures minecraft.jar named bowmanegg.png.

Well, that's the archer ready.

- Valentin.
Sorry for my english, I'm from Russia!
This is vodka, bear and more :iapprove:  
I hope I helped you!

P.S Thanks for the correction BeastGamer!
Posted Image

Register or log in to remove.

#2

jariiscool

Posted 19 August 2011 - 04:01 PM

Impressive!
Posted Image

#3

BeastGamer
  • Minecraft: pivotgamer84

Posted 19 August 2011 - 04:06 PM

Correction:
  • Player moves at 0.7F, not 1.0F
  • Spiders move at 0.8F, and they can keep up to the player, so the above is correct
Also, use this:
		if(playerToAttack == null)
		{
			List list;
			list = worldObj.getEntitiesWithinAABB(net.minecraft.src.EntityMob.class, AxisAlignedBB.getBoundingBoxFromPool(posX - 16.0D, posY - 4.0D, posZ - 16.0D, posX + 17.0D, posY + 5.0D, posZ + 17.0D));
			if(list.isEmpty())
			{
		   	list = worldObj.getEntitiesWithinAABB(net.minecraft.src.EntityMob.class, AxisAlignedBB.getBoundingBoxFromPool(posX - 16.0D, posY - 12.0D, posZ - 16.0D, posX + 17.0D, posY - 4.0D, posZ + 17.0D));
		   	if(list.isEmpty())
		   	{
			 	list = worldObj.getEntitiesWithinAABB(net.minecraft.src.EntityMob.class, AxisAlignedBB.getBoundingBoxFromPool(posX - 16.0D, posY - 20.0D, posZ - 16.0D, posX + 17.0D, posY - 12.0D, posZ + 17.0D));	   	
		   	}
			}
			if(!list.isEmpty())
			{
				setTarget((Entity)list.get(worldObj.rand.nextInt(list.size())));
			}
		}

The code will be smaller.

This code is redundant:
		if(!hasPath() && ridingEntity == null)
		{
			EntityPlayer entityplayer = worldObj.getClosestPlayerToEntity(this, 50D);
			if(entityplayer != null)
			{
				float f = entityplayer.getDistanceToEntity(this);
				if(f > 5F)
				{
  
				}
			}
		}

This is as well:
		super.onBlockClicked(world, i, j, k, entityplayer);

I don't mean to come across as a jerk, but this needs a few corrections. Good job for trying though.
Posted Image

#4

HappyConsole
  • Location: Russia
  • Minecraft: FunnyAlien

Posted 19 August 2011 - 04:31 PM

Many thanks for the correction, you helped me alot!
Tutorial has been modified.

Screenshot:

Posted Image

This is my last post for today: (
Posted Image

#5

FrogBite99
  • Location: Blah-Blah-Blah Land
  • Minecraft: Joshhhhh99

Posted 19 August 2011 - 07:18 PM

Thanks already knew this but awesome...
Posted Image

#6

HockeyPowwa97
  • Minecraft: HockeyPowwa97

Posted 22 August 2011 - 02:55 PM

This thread is already dead? NO WAY!
Posted Image

#7

Mine123crafter

Posted 22 August 2011 - 04:06 PM

awesome, would be nice if you could add some more detailed explanation so that we can also make soldiers for e.g.
Posted Image

#8

dustminerkid

Posted 24 August 2011 - 02:57 AM

hello there

i tried using your code for my mob creation

but it says that

super.updatePlayerActionState();   --> is not identified for the EntityAnimal according to "eclipse suggestion"

any help here?


thanks
Check out my new Mod
link: The Dragon Ball Mod Alpha 1.1

#9

wicked7000

Posted 24 August 2011 - 03:07 PM

Awesome tutorial everything works apart from the arher dosent do anything it just stands there i spawned every mob and i wont shot them :P
Community Modder , Youtube Creator And a Nice Person xD

#10

budwise
    budwise

    Zombie Killer

  • Members
  • 185 posts
  • Location: Ohio USA
  • Minecraft: Darkguardsman
  • Xbox:intaves

Posted 04 November 2011 - 05:01 AM

lol my NPC Guards code looks close to this wish i found this tut first so i didn't have to figure out how to make a Archer Guard on my own.
My Actual username is DarkGuardsman I am the Author of Fluid Mechanics, Assembly Line, ICBM-Sentries, Come Closer, Illus Elements, GSM Empire, and Greater Protection. I don't have time to read forums much any more...

#11

SeptimusH

Posted 04 November 2011 - 01:06 PM

What are the sound files for human sounds? I am also getting this error:

== MCP v4.4 ==
> Recompiling client...
javac.exe -g -source 1.6 -target 1.6 -classpath "lib/;lib/*;jars/bin/minecraft.j
ar;jars/bin/jinput.jar;jars/bin/lwjgl.jar;jars/bin/lwjgl_util.jar" -sourcepath s
rc/minecraft -d bin/minecraft src/minecraft\com\pclewis\mcpatcher\*.java src/min
ecraft\net\minecraft\client\*.java src/minecraft\net\minecraft\isom\*.java src/m
inecraft\net\minecraft\src\*.java  conf/patches/*.java failed.
Return code : 1

== ERRORS FOUND ==

warning: [options] bootstrap class path not set in conjunction with -source 1.6
src\minecraft\net\minecraft\src\EntityBowMan.java:23: error: cannot find symbol
if(playerToAttack == null)
^

symbol:   variable playerToAttack
location: class EntityBowMan
src\minecraft\net\minecraft\src\EntityBowMan.java:37: error: cannot find symbol
setTarget((Entity)list.get(worldObj.rand.nextInt(list.size())));
^

symbol:   method setTarget(Entity)
location: class EntityBowMan
src\minecraft\net\minecraft\src\EntityBowMan.java:40: error: cannot find symbol
super.updatePlayerActionState();
^

symbol: method updatePlayerActionState()
src\minecraft\net\minecraft\src\EntityBowMan.java:50: error: no suitable constru
ctor found for EntityArrow(World,EntityBowMan)
EntityArrow entityarrow = new EntityArrow(worldObj, this);
^

constructor EntityArrow.EntityArrow(World,EntityLiving,float) is not applicable
(actual and formal argument lists differ in length)
constructor EntityArrow.EntityArrow(World,double,double,double) is not applicabl
e
(actual and formal argument lists differ in length)
constructor EntityArrow.EntityArrow(World) is not applicable
(actual and formal argument lists differ in length)
4 errors
1 warning
==================

> Done in 4.97 seconds
> Recompiling server...
!! Can not find server sources !!
Press any key to continue . . .

Posted Image

#12

budwise
    budwise

    Zombie Killer

  • Members
  • 185 posts
  • Location: Ohio USA
  • Minecraft: Darkguardsman
  • Xbox:intaves

Posted 04 November 2011 - 04:57 PM

View PostSeptimusH, on 04 November 2011 - 01:06 PM, said:

What are the sound files for human sounds? I am also getting this error:

== MCP v4.4 ==
> Recompiling client...
javac.exe -g -source 1.6 -target 1.6 -classpath "lib/;lib/*;jars/bin/minecraft.j
ar;jars/bin/jinput.jar;jars/bin/lwjgl.jar;jars/bin/lwjgl_util.jar" -sourcepath s
rc/minecraft -d bin/minecraft src/minecraft\com\pclewis\mcpatcher\*.java src/min
ecraft\net\minecraft\client\*.java src/minecraft\net\minecraft\isom\*.java src/m
inecraft\net\minecraft\src\*.java  conf/patches/*.java failed.
Return code : 1

== ERRORS FOUND ==

warning: [options] bootstrap class path not set in conjunction with -source 1.6
src\minecraft\net\minecraft\src\EntityBowMan.java:23: error: cannot find symbol
if(playerToAttack == null)
^

symbol:   variable playerToAttack
location: class EntityBowMan
src\minecraft\net\minecraft\src\EntityBowMan.java:37: error: cannot find symbol
setTarget((Entity)list.get(worldObj.rand.nextInt(list.size())));
^

symbol:   method setTarget(Entity)
location: class EntityBowMan
src\minecraft\net\minecraft\src\EntityBowMan.java:40: error: cannot find symbol
super.updatePlayerActionState();
^

symbol: method updatePlayerActionState()
src\minecraft\net\minecraft\src\EntityBowMan.java:50: error: no suitable constru
ctor found for EntityArrow(World,EntityBowMan)
EntityArrow entityarrow = new EntityArrow(worldObj, this);
^

constructor EntityArrow.EntityArrow(World,EntityLiving,float) is not applicable
(actual and formal argument lists differ in length)
constructor EntityArrow.EntityArrow(World,double,double,double) is not applicabl
e
(actual and formal argument lists differ in length)
constructor EntityArrow.EntityArrow(World) is not applicable
(actual and formal argument lists differ in length)
4 errors
1 warning
==================

> Done in 4.97 seconds
> Recompiling server...
!! Can not find server sources !!
Press any key to continue . . .

i don't know the sound files for the Player but if you delete the get sound methods it will default to the player's sounds. as for your error you messed something up with the first error the rest are just fall back from the first not working. If i could see code i could better help.
My Actual username is DarkGuardsman I am the Author of Fluid Mechanics, Assembly Line, ICBM-Sentries, Come Closer, Illus Elements, GSM Empire, and Greater Protection. I don't have time to read forums much any more...

#13

SeptimusH

Posted 04 November 2011 - 09:54 PM

code:

package net.minecraft.src;

import java.util.List;
import java.util.Random;

public class EntityBowMan extends EntityAnimal
{

	public EntityBowMan(World world)
	{
		super(world);
		texture = "/archerr.png";
		moveSpeed = 0.2F;
		health = 20;
		isImmuneToFire = false;
	}
	protected boolean canDespawn()
	{
		return false;
	}
	protected void updatePlayerActionState()
	{
		if(playerToAttack == null)
		{
			List list;
			list = worldObj.getEntitiesWithinAABB(net.minecraft.src.EntityMob.class, AxisAlignedBB.getBoundingBoxFromPool(posX - 16.0D, posY - 4.0D, posZ - 16.0D, posX + 17.0D, posY + 5.0D, posZ + 17.0D));
			if(list.isEmpty())
			{
				list = worldObj.getEntitiesWithinAABB(net.minecraft.src.EntityMob.class, AxisAlignedBB.getBoundingBoxFromPool(posX - 16.0D, posY - 12.0D, posZ - 16.0D, posX + 17.0D, posY - 4.0D, posZ + 17.0D));
				if(list.isEmpty())
				{
				list = worldObj.getEntitiesWithinAABB(net.minecraft.src.EntityMob.class, AxisAlignedBB.getBoundingBoxFromPool(posX - 16.0D, posY - 20.0D, posZ - 16.0D, posX + 17.0D, posY - 12.0D, posZ + 17.0D));			 
				}
			}
			if(!list.isEmpty())
			{
				setTarget((Entity)list.get(worldObj.rand.nextInt(list.size())));
			}
		}
		super.updatePlayerActionState();
	}
	protected void attackEntity(Entity entity, float f)
	{
		if(f < 240F)
		{
			double d = entity.posX - posX;
			double d1 = entity.posZ - posZ;
			if(attackTime == 0)
			{
				EntityArrow entityarrow = new EntityArrow(worldObj, this);
				entityarrow.posY += 0.1999999761581421D;
				double d2 = (entity.posY + (double)entity.getEyeHeight()) - 0.20000000298023224D - entityarrow.posY;
				float f1 = MathHelper.sqrt_double(d * d + d1 * d1) * 0.2F;
				worldObj.playSoundAtEntity(this, "random.bow", 1.0F, 1.0F / (rand.nextFloat() * 0.4F + 0.8F));
				worldObj.entityJoinedWorld(entityarrow);
				entityarrow.setArrowHeading(d, d2 + (double)f1, d1, 1.5F, 12F);
				attackTime = 30;
			}
			rotationYaw = (float)((Math.atan2(d1, d) * 180D) / 3.1415927410125732D) - 90F;
			hasAttacked = true;
		}
	}
	 protected String getLivingSound()
	{
		return "mob.skeleton";
	}

	protected String getHurtSound()
	{
		return "mob.skeletonhurt";
	}

	protected String getDeathSound()
	{
		return "mob.skeletondeath";
	}
	
		public ItemStack getHeldItem()
	{
		return defaultHeldItem;
	}

	private static final ItemStack defaultHeldItem;

	static 
	{
		defaultHeldItem = new ItemStack(Item.bow, 1);
	}

	private int angerLevel;
	private int randomSoundDelay;
}

Posted Image

#14

budwise
    budwise

    Zombie Killer

  • Members
  • 185 posts
  • Location: Ohio USA
  • Minecraft: Darkguardsman
  • Xbox:intaves

Posted 05 November 2011 - 01:15 AM

ok i see what is wrong your just using outdated code. looks as if this tutorial was made for an older minecraft/ before 1.8.1

here is newer code for the update player action state for entities. it is simpler than the other code but will cause your npc to attack all mobs near it.
package net.minecraft.src;


		protected void updateEntityActionState() 
		{
			super.updateEntityActionState();
			if(entityToAttack == null) 
			{
				List list = worldObj.getEntitiesWithinAABB(net.minecraft.src.EntityMob.class, AxisAlignedBB.getBoundingBoxFromPool(posX, posY, posZ, posX + 1.0D, posY + 1.0D, posZ + 1.0D).expand(20D, 4D, 20D)); 
				if(!list.isEmpty()) 
				{
					setEntityToAttack((Entity)list.get(worldObj.rand.nextInt(list.size()))); 
				}
			}
		}

	   

also replace your attack entity code with the code the skeleton mob :Skeleton:  uses.
My Actual username is DarkGuardsman I am the Author of Fluid Mechanics, Assembly Line, ICBM-Sentries, Come Closer, Illus Elements, GSM Empire, and Greater Protection. I don't have time to read forums much any more...

#15

SeptimusH

Posted 05 November 2011 - 12:35 PM

View Postbudwise, on 05 November 2011 - 01:15 AM, said:

ok i see what is wrong your just using outdated code. looks as if this tutorial was made for an older minecraft/ before 1.8.1

here is newer code for the update player action state for entities. it is simpler than the other code but will cause your npc to attack all mobs near it.
package net.minecraft.src;


		protected void updateEntityActionState() 
		{
			super.updateEntityActionState();
			if(entityToAttack == null) 
			{
				List list = worldObj.getEntitiesWithinAABB(net.minecraft.src.EntityMob.class, AxisAlignedBB.getBoundingBoxFromPool(posX, posY, posZ, posX + 1.0D, posY + 1.0D, posZ + 1.0D).expand(20D, 4D, 20D)); 
				if(!list.isEmpty()) 
				{
					setEntityToAttack((Entity)list.get(worldObj.rand.nextInt(list.size()))); 
				}
			}
		}

	   

also replace your attack entity code with the code the skeleton mob :Skeleton:  uses.
Hmm... Can I make it only attack monsters, or at least not the player with an if statement?
Posted Image

#16

yorkiebar13

Posted 02 June 2012 - 10:06 AM

Hi,

I had a few errors such as; world.entityJoinWorld which I updated to the 1.2.5 version of world.joinEntityInSurroundings.
However the one that I could not find a replacement for was the "if (playerToAttack == null)" so I removed it and it has a problem so I tried just making a boolean doIT and set it to true then replaced the "if(PlayerToAttack == null)" with "if(doIT == true)" but I still have the same problem.

The problem is I can make the block, I can spawn the entity when I destroy/click the block but he does not attack anything. Please help me asap, thanks