This mod is something designed to add small features, but still keeping that vanilla flavour on your game. Since most of those features are related to villagers, I named it "Villager Tweaks".
Every feature can be enabled or disabled on the config file, so you only use what you want.
Version 2.2 - The Persistence Update!
- Added achievements;
- Iron golem skin display how damaged they are - 2 overlays added, applied over the regular skin;
- Named pumpkins creates named iron/snow golems;
- Villager that gets zombified will keep custom name (and persistence);
- Villager that gets zombified will keep keep profession - 5 new skins added;
- Cured zombie villagers preserve custom name and profession;
Version 2.3 Preview
"Mighty" Enchanted Iron Golem
Screenshots
Download
Full list of features
- Zombie villagers may drop emeralds
- Villagers can be named by shift-clicking with a name tag
Witches can spawn on swamps at new moon nights- Regular zombies may drop feathers
- Iron golem skin displays how damaged they are
- Named pumpkins creates named (iron and snow) golems
- Villagers that gets zombified keeps their custom name and profession - 5 new zombie skins to match!
- Zombie villagers that gets cured will keep their custom name and profession
Credits
Many current and upcoming features of this mod are heavily inspired by suggestions from the community. I'll add the names here every time I implement something new:
- Iron golem skin shows damage - Inspired by Raduloket's suggestion (Iron Golems Show Cracks When Damaged);
- Zombie villager clothes - Inspired by CursedGhast's suggestion (Zombie Villagers Now Have Actual Villager Clothes!)
Changelog
v2.1 - Fixed server crash
v2.0 - Updated to Minecraft 1.8; - Current Features: - Zombie Villagers may drop emeralds (15% chance + 5% per looting level); - Regular zombies may drop feathers (5% chance); - Villagers can be named by sneaking + right-clicking on them with a name tag; - Removed requiring player kill to drop emeralds, the chance is low enough; - Removed Witches spawning on swamps since vanilla added that a while ago;
Open Source
I learned a lot doing Minecraft mods, and a great part of that was done seeing other people's work.
For that reason, my mods are open source, under GPL v3 licence. You can check it on GitHub.
7
The goals of these mods are just things that I would like to have in minecraft that I see other mods implementing, but the other mods either over kills them or over complicates them.
Also this is just a chance for me to learn how to mod minecraft.
I'm sharing them just in case other people might find them useful.
These mods all require Forge 9.10.0 to be installed.
And they are for Minecraft 1.6.2
Just drop the jar files in the mods directory.
SpawnEggDropsMod
This little mod adds an enchantment Drop Egg that can be applied to Books and Weapons.
Once you enchant a weapon with this enchantment and kill mob, there will be a 50% chance that the drops will include the mob spawn egg.
There's also a 50% chance that creepers drop raw fish along with it's normal drops. This can be disabled from the config file.
You can adjust the drop chances in the config file.
Download
CreeperBurnCore
This mod makes Creepers sensitive to sunlight just like the Skeletons and Zombies.
They will burn when under direct sunlight.
Download
ExplosionDropsCore
This mod forces all blocks that are blown with an explosion to be returned as drops.
Download
StandInMod
This is a WIP mod. So far it copies some of mDiyo and Pahmiars code.
This mod adds a Hammer item similar to the hammer in tinker construct.
Wooden Hammer: Digs (1X3) (low durability)
Cobblestone Hammer: Digs (3X3) (low durability)
Iron Hammer: Digs (3X3) (much better durability and allows mining diamonds)
Gold Hammer: Digs (3X3)
Diamond Hammer: Digs (5X5)
Setting the clearAllBlocks config option to true makes all hammers dig up any material including dirt, gravel and sand.
It also adds a Paddle item that is the shovel equivalent of the hammer.
Wooden Paddle: Digs (1X3) (low durability)
Cobblestone Paddle: Digs (3X3) (low durability)
Iron Paddle: Digs (3X3) (much better durability and allows mining diamonds)
Gold Paddle: Digs (3X3)
Diamond Paddle: Digs (5X5)
Item Fill Wand:
The Fill wand fills an empty area with a block.
To use sneak and right click on the first block. Then go to the second block that forms your area and right click again on that block.
The area will be filled with blocks making up the first selection. the blocks in your inventory of the first selection will be used.
It will only fill air blocks. if there's already a block in the way it won't be replaced.
There are many targets that I'm planning on implementing. some might make it other won't, but so far it makes a good early game tools.
Download
All of these mods are opensource under the GPL/LGPL licenses.
The source code can be found here
I don't plan on using adfly and github doesn't show the number of downloads so please drop a line in this thread if you're using any of these mods or leave a like.
For an explanation of the code behind these mods, check my tutorial on events and coremods here
38
In this tutorial I will try to cover some of the concepts of event handling and runtime bytecode manipulation with the help of the ASM API in forge.
Both of these techniques allow us to change the behavior of vanilla minecraft without editing the minecraft base classes directly.
This should work for 1.5.2 and 1.6.1, with the only difference so far being changing the @PreInit @Init and @PostInit with @EventHandler, and a couple of import changes. Use Ctrl+Shift+o (Oh) in eclipse to fix those.
Handling Events
-----------------
Event handling is a feature that is added by forge that allows us to hook into certain vanilla functionallity once a specific action takes place.
For the entire list of which events Forge can handle, take a look at the net.minecraftforge.event.* package.
To setup event callbacks we need to start with our main mod class and register an event handler class that we'd like to use.
In this example we are telling forge that we'd like for the class EntityLivingHandler to be the handler of specific event. You don't have to create a seperate class to handle events. You can define your main mod class to do the handling for example:
But we'll use the class EntityLivingHandler for clarity.
Moving on....
Inside the EntityLivingHandler class we declare the methods that handle events like so:
First we tell forge that we want this method to be an event handler using the @ForgeSubscribe annotation.
The name of the method does not matter. It can be anything you like, what matters is the type of the parameter passed in the method. In this case it's the LivingDeathEvent class which is triggered whenever an entity dies.
So whenever an entity dies, we are passed full control by this event handler and we can go on to do whatever we like.
Examples:
SpawnEggDropsMod
This mod adds to what entities drop once killed.
CreeperBurnMod
This mod traps the LivingSpawnEvent which is called whenever an entity spawns in the world and we use it to replace the creeper with another entity.
Coremods
-----------
Prerequisite:
-------------
Make sure you download the Javadoc and documentation for ASM from
http://asm.ow2.org/
And grab the ASM bytcode plugin for eclipse http://asm.ow2.org/eclipse/index.html
You must also be familiar with JVM Bytecode
To work with ASM we need to declare two classes. One that implements the IFMLLoadingPlugin interface, and the other that implements the IClassTransformer interface.
Look at the "Running the coremod in your development enviroment" section below to learn how to run a coremod
From there we can go ahead and modify vanilla with two approaches that I will explain here:
The first being patching some method from vanilla using bytecode instructions at runtime.
The second being replacing the whole vanilla class with a copy that we have stored in our jar file at runtime.
Patching a vanilla method:
----------------------------
To start we need to tell forge which class will handle the bytecode manipulation by registering the *NAME* of the transformer class.
The class that will handle the actual transformations is the class that implements IClassTransformer
This class implements the method transform that takes 3 parameters:
with arg0 being the name of the class forge is about to work with at the JVM level
arg1 is the new name of the class (not sure what this is tbh)
arg2 you can look at it as the chuck of bytecode that's about to be loaded into JVM.
From here we check the name of arg0 and trap the one that interest us.
In this example we are interested in the net.minecraft.world.Explosion
which once it's obfuscated it's called "abq".
Note: use the files in forge/mcp/conf to see what the names are!
Once we get to the traget class we call our own little method that does the modifications:
What we want to modfy in net.minecraft.world.Explosion is the method
buried inside this method a call to drop blocks after an explosion happens is issued.
by default the number of items dropped is dependent on the explosionSize variable.
We want to alter this to make it look like this instead:
If you install the ASM bytcode plugin for eclipse, you can see how it looks like in bytecode ASM instruction. at least the 1.0F / this.explosionSize, 0); part.
Read this as a stack:
So let's set it up in our patchClassASM method:
(Note: once Explosion.class is obfuscated, the name of the method doExplosionB becomes "a"
This is done in multiple steps.
First we loop over the method names until we come across our target method.
Then we loop over the instructions inside that method until we come across an instruction that interests us.
Example:
The full code for this example can be found here:
ExplosionDropsCore
Replacing a vanilla class:
--------------------------
In this example we will replace the *WHOLE* EntityCreeper.class with one that has the following modifications:
After we modify the base class run forge/mcp commands to compile and obfuscate:
recompile.bat
reobfuscate.bat --> gives the obfuscated class
reobfuscate_srg.bat --> gives the unobfuscated class
This will give us the class files:
net.minecraft.entity.monster.EntityCreeper.class
and
te.class
Note: If you have in-game runtime crash errors after applying the patch in the deobfuscated version only.
Copy the class file directly from the mcp/bin instead and not from mcp/reobf.
Example: forge/mcp/bin/minecraft/net/minecraft/entity/monster/EntityCreeper.class
open the file CreeperBurnCore_dummy.jar with winzip or 7zip and put those classes inside the jar.
the structure should end up looking like so
Once again we need to implement the IFMLLoadingPlugin and IClassTransformer interfaces
For this example, we don't want the transformer to modify a specific base method, instead we want to replace the entire class.
The full code for this example can be found here:
CreeperBurnCore
Making the coremod appear in the mods list
----------------------------------------------
This section is just how to make the core mod appear in the lists of mods when you click on "Mods" on the main page
Going back to the class that implements IFMLLoadingPlugin add the following:
Then create a class that extends cpw.mods.fml.common.DummyModContainer
Running the coremod in your development enviroment
--------------------------------------------------------
This is how I run coremods in my development enviroment. There is another way using the argument fml.coreMods.load, but I never tried that. I use the approach I'm explaining here since I could also include the class patches to it as in the example of CreeperBurnCore discussed earlier.
If you still want to use the fml.coreMods.load argument, then just type the following in your VM arguments of your run configuration. If you have multiple coremods you seperate them with a comma.
Here's how to create the dummy jar:
First create a directory called META-INF.
Inside the META-INF folder create a file called MANIFEST.MF
Edit the file and for the line FMLCorePlugin write the fully qualified name of the class that implements the IFMLLoadingPlugin interface.
Make sure to include the other 2 lines as well.
Compress the directory into a zip using winrar or 7zip and rename the file to have the extension .jar instead of .zip (Don't compress into a .rar format!)
In the end the final jar should look like this:
Now copy the new jar file to the directory /forge/mcp/jars/mods
Access Transformers
----------------------
A very quick guide to access transformers. I wasn't planning on writing one this early since I don't have a practical example to show.
Instead we'll just look at Forge itself and how it uses it.
This section as with this whole tutorial might not be 100% accurate.
Prerequisite:
-------------
You must be familliar with java reflection and that this also exists as an alternative that you can exploit.
What are they?
To describe it in the most simple terms, they are just a way of changing the access levels of vanilla classes/methods/fields
so if in vanilla you find:
and you want to be able to access that var and modify it, then run AccessTransformer on it so it becomes:
How it's done?
As with all the other coremods we need to implement the IFMLLoadingPlugin and IClassTransformer interfaces.
But in the case of AccessTransformers, cpw already implemented the IClassTransformer and it's called cpw.mods.fml.common.asm.transformers.AccessTransformer
So instead of implementing your own version, you can just extend AccessTransformer!
Let's get back to the IFMLLoadingPlugin implementation in forge:
And the implementation of ForgeAccessTransformer is very straight forward:
So it's letting AccessTransformer worry about the full implementation and it's just passing the _at.cfg file.
How is the _at.cfg written?
You can use the files in mcp/conf to find the mapping of the variables and fields that you need.
just add the access level and the field or method you want to change. To change if the field is final add the flag -f +f depending on the situation.
Look at the forge_at.cfg for examples.
But let's say you want to change the visibility of a class and it's constructor.
in the fml_cfg there's this example:
You can find from the joined.srg the following about CallableMinecraftVersion and CrashReport:
CL: c net/minecraft/src/CallableMinecraftVersion
CL: b net/minecraft/src/CrashReport
But what about this <init>?
c.<init> is another way of saying the constructor of c
You can look at the joined.exc and see
net/minecraft/src/CallableMinecraftVersion.<init>(Lnet/minecraft/src/CrashReport;)V=|p_i1338_1_
so our target is:
net/minecraft/src/CallableMinecraftVersion.<init>(Lnet/minecraft/src/CrashReport;)V
and replacing CallableMinecraftVersion and CrashReport with the obfuscated counterparts we end up with this:
c.<init>(Lb;)V
Just to make sure that what we are doing is correct, grab the mincraft server jar minecraft_server.1.6.2.jar
and extract it to some folder.
inside where all the classes are run this command from the command line:
The output should be like so:
So that shows us that the constructor which takes a parameter c( b ) has the signature (Lb;)V
ASMifier and javap run configuration in Eclipse
=====================================
These launch scripts allow you to run javap and ASMifier on your source code inside of eclipse. The results are displayed in the Console tab in eclipse.
just copy the *.launch files to
forge/mcp/eclipse/.metadata/.plugins/org.eclipse.debug.core/.launches/
the launch configuration can be downloaded from here:
EclipseLaunchers
Special thanks the following people who I used their code as the basis of this tutorial:
AtomicStryker
Pahimar
denoflions
Full code for this tutorial can be found at my
github repo
1
Well it gets a little bit more complicated then.
Always consult the ASM javadocs. You MUST go back to it to get the codes numbers.
I'll show you how it can be done for the Explosion example:
first add the imports:
The log looked like this:
Then you do string comparison on owner, name and desc.
You're welcome
1
make the MANIFEST.MF be *exactly* like this:
and the jar looking like this:
then copy this file to forge/mcp/jars/mods
it should work then
1
Ok guys here's my second tutorial and second mod. this will be insanly advanced!!! it's bordering on cracking code!!
So as I said in my previous post, I want to recreate what the Practical TNT mod does but without modifying any minecraft base files.
What the mod does is very simple, when an explosion happens, dropBlockAsItemWithChance is called with item qty chance of 1/explosionSize
we don't want that, instead we want to force to call dropBlockAsItemWithChance with qty chance of 1, meaning you'll get all of the items.
but how can we do that without modifing the Explosion class? the answer is ASM!
forge comes with ASM which allows modifying the base classes in bytecode at runtime!!
the modification does not happen at compile time.
very cool!
but regular mods cannot do that, it has to be a coremod in order to be able to do the runtime modifications of the code.
*thanks to Stalkercreeper mod for the code*
to create a coremod we need two classes.
a class the implements IFMLLoadingPlugin and another that implements IClassTransformer interfaces
The second file where the java bytecode modifcations happens.
i used eclipse bytecode plugin and javap to try and figure out which section of code i needed to modify.
Basically we need to identify the method, then we need to find a the bytecode instruction that we need either to alter or add to. and then do our own bytecode modification or injection!
when the explosion happens the method is called as follows in bytecode in minecraft
*NOTE I DIDN'T WRITE THIS, IT'S WHAT MINECRAFT ALREADY DOES IN ASM FORMAT
you read this as a stack!
what the above basically says is 1 divided by explosionSize.
on my first try i tried to inject code after the FDIV to POP the stack. that resulted in a crash. the second approach was to copy over each instruction, then tell ASM to remove them from the instruction list with the command m.instructions.remove()
and that's it!
*Note this will only work on unobfuscated minecraft, in order to make it work on obfuscated minecraft you have to find the obfuscated name of the class Explosion and it's method doExplosionB and run the code on those instead. use mcp/conf folder to see what links to what
1
*For the coremod tutorial see the second post!*
Hello! this is my first tutorial and my first mod! I'm not very good at doing this so be patient with me.
In this tutorial we will be overriding the Zombies and the Creepers from vanilla.
Optionally we will create a whole new mob entity that looks like Steve.
We will make the zombies be villager zombies whenever they spawn, and the creepers be sensitive to daylight and burn whenever they are in direct sunlight. Kinda similar to the CreepersNoCreeping mod by MorpheusZero
ALSO! we will be adding to what the skeleton mob drops and make it drop something if killed with a sword and something else if killed with a bow, and all of that without overriding the skeleton class!
So here goes nothing!
The Zombie is very simple we want our zombie to do everything that the vanilla zombie does except to be always a villager zombie, it's only a constructor call!
The Creeper code. once again we want it to be the same as a vanilla creeper, except they behave the same as zombies and skeletons when exposed to direct sunlight. the code was copied from the SkeletonEntity
EntityLivingHandler.
This is where we will kill the vanilla creeper and zombie and spawn our version of zombie and creeper.
here we will alter the drops of vanilla skeletons. you can set it to any entity if you want!
Note that the name of the class and the name of the methods doesn't matter, what matters is the type of parameter passed!
*thanks to EE3 and PetBat for the code*
Add this code to create the optional steve entity! dude doesn't do much, just chilling
Steve's code TutEntity
Well that's it folks!
hope that made sense.
If you know how to make the code look better please let me know.
Links
CreepersNoCreeping by MorpheusZero
http://www.minecraft...ads-april-2013/
An Excellet tutorial to get you started, heavily based on EE3 code
http://www.minecraft...aking-requests/
An Excellent tutorial for changing block behavior without editing base classes
http://www.minecraft...classes-simple/
Mob drop technic discussed in this tutorial comes directly from EE3
http://www.minecraft...change-3-pre1h/
Mob overriding comes from the nifty mod PetBat
http://www.minecraft...y-hang-get-him/
I'll try to figure out how they work and also try to implement something similar to the practical TNT mod without modifying the base classes.
I'll post everything for you when it's done.
for the mean time practical TNT mod can be found here http://www.minecraft...-practical-tnt/
1
so if the block is placed while sneaking (holding shift key) it will trigger one event and if placed while standing (without holding shift) it will trigger a different event.
any ideas?