Jump to content

ninjapancakes87

Members
  • Posts

    81
  • Joined

  • Last visited

Posts posted by ninjapancakes87

  1. Ok, first of all ASM and Reflection are two entirely different things.

    Reflection allows you to access methods & fields you normally don't have access to (they are private for example).

    ASM allows you to dynamically generate java bytecode from within your program. How that works? Well, when you compile your .java files, the java compiler produces .class files. What these contain is called bytecode, which is then executed by the actual JVM. This in-between step is what makes java reasonably fast, because the bytecode has a very limited instruction set and can therefor be executed very fast.

     

    With ASM and the IClassTransformer interface (which is part of the official Mojang launcher btw, so this is theoretically independent from FML/Forge) you can now transform the bytecode of (almost) every class that get's loaded by the JVM. So I would first suggest a tutorial on the basics on bytecode (like this one: http://www.javaworld.com/article/2077233/core-java/bytecode-basics.html) and then learning ASM (for example here: http://www.javacodegeeks.com/2012/02/manipulating-java-class-files-with-asm.html).

     

    Alright, I will check those out, thanks!

  2. Hi all,

     

    Let me just start off by saying I'd like to thank all of the helpful moderators and friendly people on this forum.  I essentially taught myself java by modding, and everybody here has been extremely helpful when I need help.  Now, I can apply what I've learned outside of modding, and It's come a long way.

     

    But now I want to actually start doing more advanced things.  I've heard from another modder there is a way, using java.lang.reflect and ASM transformers to actually put methods into classes without base edits, or things of the sort.  Does anybody know of a page explaining ASM transformers and what I was talking about?  I have a basic idea of what reflect does.

     

    Thanks in advance,

    Ninjapancakes87

  3. But on a side note, in your tutorial it does say you haven't found a use for your Init method. You have figured out what that does, correct?

    It's the same as entityInit in Entity classes; it gets called during entity construction, so you could put the exact same code in your constructor and it would have the same effect. The benefit of the init method in IExtendedEntityProperties is that it provides a world object, but I haven't found it (the extra world parameter) particularly useful because the entity itself isn't yet finished constructing.

    I know, just wanted to make sure :P

  4. You can add datawatcher in either the init or in the constructor, doesn't really matter since init is called during class construction anyway.

    Thanks!

     

    But on a side note, in your tutorial it does say you haven't found a use for your Init method. You have figured out what that does, correct?

  5. You could overlay the texture onto the GUI.  I'm not sure how that would work, but you could render the player skins into the foreground of your GUI, in the drawGuiContainerForeground method, and have the background be just an empty 256 x 256 texture.

  6. If everything is saving and loading properly, then you're fine. The problem is that the client-side data is not automatically synchronized, so you have to do it yourself.

     

    Either:

    a) send a packet to the client with the data and set it manually; this is best done from somewhere like the EntityJoinWorldEvent to avoid NPE of the client-side properties

     

    b) use DataWatcher to store your data instead of class fields; advantage is that everything else is automatic; disadvantage is you are using an extremely limited resource (data watcher slots)

     

    There are tutorials on the Forge wiki about both packets and data watcher, both of which are referenced on this list:

    http://mazetar.com/mctuts/displayTutorials.php

     

    Alternatively, you can check out my tutorial on IExtendedEntityProperties here:

    http://www.minecraftforum.net/topic/1952901-eventhandler-and-iextendedentityproperties/#entry24051513

    I do know how to use datawatcher (never used packets, so I'm going to avoid that route), but thanks for the tip.  I looked at your tutorial, and the only question I have is should I add the watcher in the init method of my ExtendedProperties class?

  7. What do you want the end result to be? When using EnumChatFormatting, whatever format you put will apply to the entire string unless you call EnumChatFormatting.RESET.

     

    His problem is that it isn't effecting the whole string, it's only effecting until a new-line.

    *affecting, sorry, can't help it :P

     

    I don't see why it wouldn't carry over from line to line.  In fact, it shouldn't, so your problem is in the link.

     

    Also, I asked if it was a clickable link because I'm fairly confident the link would reset the chat formatting, so if you put EnumChatFormatting.RED after your link it should show everything but the link in red.

  8. There are no visible attempts I have removed them as it didn't work, I would like to know how to do it because I couldn't work it out

    I don't have my code up now, but I do know how I got it is that you need to

    GameRegistry.registerWorldGenerator(new CustomWorldGenerator)

    and by default your structure will spawn anywhere, including in the air.  I did this with glowstone a while back, and it looks pretty cool.

     

    Here's a tut: http://www.minecraftforge.net/wiki/Adding_World_Generation

  9. What do you want the end result to be? When using EnumChatFormatting, whatever format you put will apply to the entire string unless you call EnumChatFormatting.RESET.

    For example, if you do

    par1EntityPlayer.addChatMessage(EnumChatFormatting.RED + "Red" + EnumChatFormatting.RESET + " White");

    The Red will be colored red, and the white will be colored default.

     

    Also, is that a clickable link?

  10. Hi all,

    I'm trying to add some properties to the player, and it's not correctly working.  Through some system.out.println()'s, I know it is saving, loading, and initializing my properties, it's just not applying them to the player.  I remember reading something old about properties, and packets, but I can't find it anymore and I'm not sure. 

    My properties code:

     

    package ninjapancakes87.civilwar;
    
    import net.minecraft.entity.Entity;
    import net.minecraft.entity.player.EntityPlayer;
    import net.minecraft.nbt.NBTTagCompound;
    import net.minecraft.world.World;
    import net.minecraftforge.common.IExtendedEntityProperties;
    
    public class ExtendedProperties implements IExtendedEntityProperties{
    
    /**The number of soldiers hired by the player*/
    private int armySize;
    
    /**Whether the player has hired a Union or Confederate soldier*/
    private boolean isUnion;
    
    public int getArmySize(){
    	return this.armySize;
    }
    
    public void setArmySize(int par1){
    	this.armySize = par1;
    }
    
    public boolean getIsUnion(){
    	return this.isUnion;
    }
    
    public void setIsUnion(boolean par1){
    	this.isUnion = par1;
    }
    
    @Override
    public void saveNBTData(NBTTagCompound compound) {
    	compound.setBoolean("isUnion", isUnion);
    	compound.setInteger("armySize", armySize);
    }
    
    @Override
    public void loadNBTData(NBTTagCompound compound) {
    	this.isUnion = compound.getBoolean("isUnion");
    	this.armySize = compound.getInteger("armySize");
    }
    
    @Override
    public void init(Entity entity, World world) {
    	if(entity instanceof EntityPlayer){
    		EntityPlayer player = (EntityPlayer)entity;
    	}
    }
    }
    

     

    I previously had it work by calling EntityPlayer.getEntityData(), but that doesn't vary between worlds like I want it to.

  11. Hey ninjapancakes87,

     

    Thanks for playing and especially leaving feedback!!

     

    "Cooca leaves" (not cocoa - perhaps i have to change the name it's already too confusing) can be harvested from Cooca plants.

     

    About the frustration: It even took me several times to finally survive the first days, although i knew all the factors influencing frustration. Once difficulty settings are introduced, the current balancing would certainly be 'hard' and there will be a 'normal' and 'easy' setting and also custom difficulty. Right now, it's set to the difficulty i like to play with.

     

    I know what you mean, talking about those instant kills. They happen by chance, so you will not automatically die when reaching 100 frustration. If you are very careful (read stay out of the dark, use sleeping to reduce frustration) you should be able to avoid frustration levels above 70-80.

    During the games i played alone and with friends, frustration related deaths may have been at approximately 10% of overall deaths.

    When you die/respawn your frustration level and tendency will be reduced, so if you feel like you have accumulated such a high tendency or level that it becomes unplayable, (preventive) suicide may be the answer. But beware: number of deaths correlates to number and chance of gaining negative traits.

    Oh ok, so where do we get cocoa plants? It seems cocoa leaves are one of the best drawgs because (if memory serves) it's only slightly addictive.

    Thanks for the advice about frustration though!

  12. One thing I don't like is how if you reach 100 frustration you are killed by magic.  At the start of the game, it takes a while to just get your feet off the ground.  I don't have any crops for food or sugar, don't have any traits, and gain about 3 frustration every 30 seconds even after respawning.  There should definitely be a dangerous effect at 100 frustration, but death by magic seems a tad overpowered.

  13. So I'm trying to make a portable chest (haversack) that functions the same as the alchemical bag from EE2/EE3.  When held, and right clicked, it opens a GUI.  I'm using a tile entity for this, and I've gotten tile entity's to work before.  However, now, I get this error:

     

    2014-01-04 22:45:48 [iNFO] [sTDERR] java.lang.NullPointerException
    2014-01-04 22:45:48 [iNFO] [sTDERR] 	at ninjapancakes87.civilwar.item.haversack.ContainerHaversack.<init>(ContainerHaversack.java:16)
    

    This is the suspect line:

    this.numRows = par2IInventory.getSizeInventory() / 9;

     

    I have tried fixing this by hardcoding a number in, but this just leads to more problems, all dealing with the TileEntityHaversack class.  I made sure I called

    GameRegistry.registerTileEntity(TileEntityHaversack.class, "Haversack");

    in my load method.

    Here is my TileEntity:

    TileEntityHaversack:

     

    package ninjapancakes87.civilwar.item.haversack;
    
    import net.minecraft.entity.player.EntityPlayer;
    import net.minecraft.inventory.IInventory;
    import net.minecraft.item.ItemStack;
    import net.minecraft.nbt.NBTTagCompound;
    import net.minecraft.nbt.NBTTagList;
    import net.minecraft.tileentity.TileEntity;
    
    public class TileEntityHaversack extends TileEntity implements IInventory{
    private ItemStack[] chestContents = new ItemStack[27];
    
    @Override
    public ItemStack getStackInSlot(int par1) {
    	return this.chestContents[par1];
    }
    
    @Override
    public ItemStack decrStackSize(int par1, int par2) {
    	if (this.chestContents[par1] != null)
            {
                ItemStack itemstack;
    
                if (this.chestContents[par1].stackSize <= par2)
                {
                    itemstack = this.chestContents[par1];
                    this.chestContents[par1] = null;
                    this.onInventoryChanged();
                    return itemstack;
                }
                else
                {
                    itemstack = this.chestContents[par1].splitStack(par2);
    
                    if (this.chestContents[par1].stackSize == 0)
                    {
                        this.chestContents[par1] = null;
                    }
    
                    this.onInventoryChanged();
                    return itemstack;
                }
            }
            else
            {
                return null;
            }
    }
    
    @Override
    public ItemStack getStackInSlotOnClosing(int par1) {
    	if (this.chestContents[par1] != null)
            {
                ItemStack itemstack = this.chestContents[par1];
                this.chestContents[par1] = null;
                return itemstack;
            }
            else
            {
                return null;
            }
    }
    @Override
    public void setInventorySlotContents(int i, ItemStack par2ItemStack) {
    	this.chestContents[i] = par2ItemStack;
    
            if (par2ItemStack != null && par2ItemStack.stackSize > this.getInventoryStackLimit())
            {
                par2ItemStack.stackSize = this.getInventoryStackLimit();
            }
    
            this.onInventoryChanged();		
    }
    
    @Override
    public String getInvName() {
    	return "Haversack";
    }
    
    @Override
    public boolean isInvNameLocalized() {
    	return false;
    }
    
    @Override
    public int getInventoryStackLimit() {
    	return 64;
    }
    
    @Override
    public boolean isUseableByPlayer(EntityPlayer entityplayer) {
    	return true;
    }
    
    @Override
    public void openChest() {		
    }
    
    @Override
    public void closeChest() {	
    }
    
    @Override
    public boolean isItemValidForSlot(int i, ItemStack itemstack) {
    	return true;
    }
    @Override
    public int getSizeInventory() {
    	return 27;
    }
    public void readFromNBT(NBTTagCompound par1NBTTagCompound)
        {
            super.readFromNBT(par1NBTTagCompound);
            NBTTagList nbttaglist = par1NBTTagCompound.getTagList("Items");
            this.chestContents = new ItemStack[this.getSizeInventory()];
    
            for (int i = 0; i < nbttaglist.tagCount(); ++i)
            {
                NBTTagCompound nbttagcompound1 = (NBTTagCompound)nbttaglist.tagAt(i);
                int j = nbttagcompound1.getByte("Slot") & 255;
    
                if (j >= 0 && j < this.chestContents.length)
                {
                    this.chestContents[j] = ItemStack.loadItemStackFromNBT(nbttagcompound1);
                }
            }
        }
    
        /**
         * Writes a tile entity to NBT.
         */
        public void writeToNBT(NBTTagCompound par1NBTTagCompound)
        {
            super.writeToNBT(par1NBTTagCompound);
            NBTTagList nbttaglist = new NBTTagList();
    
            for (int i = 0; i < this.chestContents.length; ++i)
            {
                if (this.chestContents[i] != null)
                {
                    NBTTagCompound nbttagcompound1 = new NBTTagCompound();
                    nbttagcompound1.setByte("Slot", (byte)i);
                    this.chestContents[i].writeToNBT(nbttagcompound1);
                    nbttaglist.appendTag(nbttagcompound1);
                }
            }
    
            par1NBTTagCompound.setTag("Items", nbttaglist);
        }
    }
    

     

  14. Because you're not rotating the model in the TileTotemRenderer class.

     

             double angle = Math.toRadians(entity.rotation); //entity here is my TileEntity.  You can also reference block metadata.
             GL11.glPushMatrix();
             GL11.glRotatef(-1*entity.rotation, 0, 1, 0); //negative because of an assumption made in my TE that was wrong and this was the easier fix

     

    (The angle value was being used for another part of the rendering, not related to the model)

    ^^^ The right way (how I did it)

  15. Try making an item which places the block. Then just remove the block's creative visibility and use the item instead. Use this code:

     

    import cpw.mods.fml.relauncher.Side;
    import cpw.mods.fml.relauncher.SideOnly;
    import net.minecraft.block.Block;
    import net.minecraft.creativetab.CreativeTabs;
    import net.minecraft.entity.player.EntityPlayer;
    import net.minecraft.world.World;
    
    public class ItemBlockPlacer extends Item
    {
        public int blockID;
        public String textureName;
    
        public ItemFlintAndSteel(int par1, String textureName, int blockID)
        {
            super(par1);
            this.blockID = blockID;
        }
    
        /**
         * Callback for item usage. If the item does something special on right clicking, he will have one of those. Return
         * True if something happen and false if it don't. This is for ITEMS, not BLOCKS
         */
        public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, int par5, int par6, int par7, float par8, float par9, float par10)
        {
            if (par7 == 0)
            {
                --par5;
            }
    
            if (par7 == 1)
            {
                ++par5;
            }
    
            if (par7 == 2)
            {
                --par6;
            }
    
            if (par7 == 3)
            {
                ++par6;
            }
    
            if (par7 == 4)
            {
                --par4;
            }
    
            if (par7 == 5)
            {
                ++par4;
            }
    
            if (!par2EntityPlayer.canPlayerEdit(par4, par5, par6, par7, par1ItemStack))
            {
                return false;
            }
            else
            {
                if (par3World.isAirBlock(par4, par5, par6))
                {
                    par3World.playSoundEffect((double)par4 + 0.5D, (double)par5 + 0.5D, (double)par6 + 0.5D, Block.blocksList[blockID].stepSound.getPlaceSound(), 1.0F, itemRand.nextFloat() * 0.4F + 0.8F);
                    par3World.setBlock(par4, par5, par6, blockID);
                }
    
                --par1ItemStack.stackSize;
                return true;
            }
        }
    
    @SideOnly(Side.CLIENT)
    public void registerIcons(IconRegister ir) {
    
    this.itemIcon = ir.registerIcon(textureName);
    
    }
    }
    

     

    and when setting it up in the mod file, type this:

     

    myBlockPlacer = new ItemBlockPlacer(/* TODO item ID */, /* TODO texture name e.g. "mymod:myitemplacer" */, myBlock.blockID)/* .setCreativeTab(CreativeTabs.tabBlock) etc. */;
    

     

    Hope I helped!

     

    Romejanic

    That's what I was hoping to avoid, but ended up using anyway.  Thanks for the help anyway!

  16. Hi all,

    I have a block I'm making, and it has a custom model.  I don't want it to be 3D in the inventory (I know how to do this and have done it before, but don't want to).  Is there any way to bind just a 16x16 texture to a block when it appears in your inventory?

    Thanks,

    Ninjapancakes87

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.