Jump to content
View in the app

A better way to browse. Learn more.

Forge Forums

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Featured Replies

Posted

(This is re-posted from the ForgeGradle section because I posted it there on accident and don't know how to remove it)
Hey!
I'm making an addon for a mod called KAGIC which adds little fruit people which form their own villages and civilizations.
I had some trouble at first because the Minecraft spawn handler was mixing up entities, but I eventually solved that problem in the main Pepo (the fruit people) class which all the other species, such as watermelon pepo and pumpkin pepo, extend.
After fixing this issue it was all looking good. I had a functional plant that would grow and when harvested, would give back pepo seeds and spawn a pepo creature. Then, however, I began implementing the age feature into the and ever since then, the pepos are stationary (whereas beforehand they were moving about), I can walk through the (whereas before I could not) and when I punch them, they stay in place and their arms and legs begin to move up and down repeatedly.
I even removed the age mechanic afterwards but the problem persisted. Does anyone have any idea on what the problem might be?

Here's the main pepo code: 

package com.androbean.zcp.entity;

import com.androbean.zcp.init.ZModItems;
import io.netty.buffer.ByteBuf;
import mod.akrivus.kagic.init.ModSounds;
import net.minecraft.entity.EntityCreature;
import net.minecraft.entity.IEntityLivingData;
import net.minecraft.entity.INpc;
import net.minecraft.entity.SharedMonsterAttributes;
import net.minecraft.entity.ai.EntityAILookIdle;
import net.minecraft.entity.ai.EntityAIWander;
import net.minecraft.entity.ai.EntityAIWatchClosest;
import net.minecraft.entity.monster.EntityMob;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.IInventoryChangedListener;
import net.minecraft.inventory.InventoryBasic;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.util.DamageSource;
import net.minecraft.util.SoundEvent;
import net.minecraft.world.DifficultyInstance;
import net.minecraft.world.World;
import net.minecraftforge.fml.common.registry.IEntityAdditionalSpawnData;
import net.minecraftforge.items.wrapper.InvWrapper;

public class EntityPepoVillager extends EntityCreature implements IInventoryChangedListener, INpc, IEntityAdditionalSpawnData {
    public Item dropItem;
    public Item eatItem;
    public InventoryBasic storage;
    public InvWrapper storageHandler;
    public boolean cannibal = false;
    public boolean hungry = false;
    public int hunger = 20;
    public int ageTicks = 0;
    public int age = 0;
    public String job = "farmer";

    public EntityPepoVillager(World worldIn) {
        super(worldIn);
        this.setSize(0.5F, 1.5F);
        this.initStorage();

        this.tasks.addTask(7, new EntityAIWander(this, 0.6D));
        this.tasks.addTask(8, new EntityAIWatchClosest(this, EntityPlayer.class, 16.0F));
        this.tasks.addTask(8, new EntityAIWatchClosest(this, EntityMob.class, 16.0F));
        this.tasks.addTask(9, new EntityAILookIdle(this));

        this.getAttributeMap().registerAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).setBaseValue(2.0D);
        this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(20.0D);
        this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.6D);
    }

    public IEntityLivingData onInitialSpawn(DifficultyInstance difficulty, IEntityLivingData livingdata) {
        return super.onInitialSpawn(difficulty, livingdata);
    }

    public boolean canDespawn() {
        return false;
    }

    public void initStorage() {
        InventoryBasic storage = this.storage;
        this.storage = new InventoryBasic("storage", false, 36);
        if (storage != null) {
            storage.removeInventoryChangeListener(this);
            for (int i = 0; i < this.storage.getSizeInventory(); ++i) {
                ItemStack itemstack = storage.getStackInSlot(i);
                this.storage.setInventorySlotContents(i, itemstack.copy());
            }
        }
        this.storage.addInventoryChangeListener(this);
        this.storageHandler = new InvWrapper(this.storage);
        this.setCanPickUpLoot(true);
    }

    public void writeEntityToNBT(NBTTagCompound compound) {
        NBTTagList nbttaglist = new NBTTagList();
        for (int i = 0; i < this.storage.getSizeInventory(); ++i) {
            ItemStack itemstack = this.storage.getStackInSlot(i);
            NBTTagCompound nbttagcompound = new NBTTagCompound();
            nbttagcompound.setByte("slot", (byte)i);
            itemstack.writeToNBT(nbttagcompound);
            nbttaglist.appendTag(nbttagcompound);
        }
        compound.setTag("items", nbttaglist);
        compound.setBoolean("cannibal", this.cannibal);
        compound.setBoolean("hungry", this.hungry);
        compound.setInteger("hunger", this.hunger);
        compound.setInteger("ageTicks", this.ageTicks);
        compound.setInteger("age", this.age);
        compound.setString("job", this.job);
        super.writeEntityToNBT(compound);
    }

    public void readEntityFromNBT(NBTTagCompound compound) {
        NBTTagList nbttaglist = compound.getTagList("items", 10);
        for (int i = 0; i < nbttaglist.tagCount(); ++i) {
            NBTTagCompound nbttagcompound = nbttaglist.getCompoundTagAt(i);
            int j = nbttagcompound.getByte("slot") & 255;
            if (j >= 0 && j < this.storage.getSizeInventory()) {
                this.storage.setInventorySlotContents(j, new ItemStack(nbttagcompound));
            }
        }
        this.cannibal = compound.getBoolean("cannibal");
        this.hungry = compound.getBoolean("hungry");
        this.hunger = compound.getInteger("hunger");
        this.ageTicks = compound.getInteger("ageTicks");
        this.age = compound.getInteger("age");
        this.job = compound.getString("job");
        super.readEntityFromNBT(compound);
    }

    public void Cannibal(){
        this.cannibal = true;
    }

    public void increaseHunger(){
        this.hunger++;
    }

    public int checkForFood(){
        boolean isFood = false;
        for(int i = 0; i < this.storage.getSizeInventory(); i++){
            if(this.storage.getStackInSlot(i).getItem() == this.eatItem){
                isFood = true;
                return i;
            }
        }
        if(!isFood){
            this.hungry = true;
        }
        return 420;
    }

    @Override
    public void onLivingUpdate(){
        if(this.ageTicks >= 16560){
            this.age++;
            this.setSize(.5F, 1.5F);
            this.ageTicks = 0;
        }
        if(this.age == 3){
            this.setHealth(0);
        }
        this.ageTicks++;
    }

    public void writeSpawnData(ByteBuf buffer) {
        buffer.writeFloat(this.width);
        buffer.writeFloat(this.height);
    }

    public void readSpawnData(ByteBuf buffer) {
        this.setSize(buffer.readFloat(), buffer.readFloat());
    }

    public void onDeath(DamageSource cause) {
        ItemStack drop = new ItemStack(this.dropItem);
        if (!this.world.isRemote) {
            this.entityDropItem(drop, 0.0F);
        }
        this.entityDropItem(new ItemStack(ZModItems.MELON_SEEDS, this.rand.nextInt(3)), 0.0F);
        super.onDeath(cause);
    }

    protected SoundEvent getAmbientSound() {
        return ModSounds.PEPO_LIVING;
    }

    protected SoundEvent getHurtSound(DamageSource source) {
        return ModSounds.PEPO_LIVING;
    }

    protected SoundEvent getDeathSound() {
        return ModSounds.PEPO_LIVING;
    }

    @Override
    public void onInventoryChanged(IInventory invBasic) {

    }
}


Here is the melon pepo villager (the only pepo species I have in the game so far, this is what is registered as an entity): 

package com.androbean.zcp.entity;

import com.androbean.zcp.init.ZModItems;
import net.minecraft.entity.SharedMonsterAttributes;
import net.minecraft.entity.ai.EntityAILookIdle;
import net.minecraft.entity.ai.EntityAIWander;
import net.minecraft.entity.ai.EntityAIWatchClosest;
import net.minecraft.entity.monster.EntityMob;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.world.World;

public class EntityMelonPepo extends EntityPepoVillager {

    public EntityMelonPepo(World worldIn) {
        super(worldIn);
        this.setSize(0.5F, 1.5F);
        this.initStorage();

        this.tasks.addTask(7, new EntityAIWander(this, 0.6D));
        this.tasks.addTask(8, new EntityAIWatchClosest(this, EntityPlayer.class, 16.0F));
        this.tasks.addTask(8, new EntityAIWatchClosest(this, EntityMob.class, 16.0F));
        this.tasks.addTask(9, new EntityAILookIdle(this));

        this.getEntityAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).setBaseValue(2.0D);
        this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(20.0D);
        this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.6D);
        this.dropItem = ZModItems.PEPO_MELON;
        this.eatItem = ZModItems.ANIMAL_MELON;
    }
}


Here is the melon pepo render code: 

package com.androbean.zcp.client.render;

import com.androbean.zcp.entity.EntityMelonPepo;
import mod.akrivus.kagic.client.model.ModelPepo;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.entity.RenderLivingBase;
import net.minecraft.client.renderer.entity.layers.LayerArrow;
import net.minecraft.util.ResourceLocation;

public class RenderMelonPepo extends RenderLivingBase<EntityMelonPepo> {

    public RenderMelonPepo(){
        super(Minecraft.getMinecraft().getRenderManager(), new ModelPepo(), 0.25F);
        this.addLayer(new LayerArrow(this));
    }

    @Override
    protected void preRenderCallback(EntityMelonPepo entitylivingbaseIn, float partialTickTime) {
        float age = 0;
        if(entitylivingbaseIn.age <= 0){
            age = 0.7f;
        }
        if(entitylivingbaseIn.age >= 1){
            age = 1f;
        }
        GlStateManager.scale(age, age, age);
    }

    @Override
    protected ResourceLocation getEntityTexture(EntityMelonPepo entity) {
        return new ResourceLocation("zcp:textures/entities/melonpepo/melon.png");
    }
}


And here is my entity registry code just in case: 

package com.androbean.zcp.init;

import com.androbean.zcp.ZCP;
import com.androbean.zcp.entity.EntityMelonPepo;
import net.minecraft.client.renderer.entity.Render;
import net.minecraft.entity.Entity;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fml.client.registry.RenderingRegistry;
import net.minecraftforge.fml.common.FMLCommonHandler;
import net.minecraftforge.fml.common.registry.EntityRegistry;
import net.minecraftforge.fml.relauncher.Side;

public class ZModEntities {
    private static int currentID = 0;

    public static void register(){
        registerMob("melonpepo", EntityMelonPepo.class, 0x51D4A4, 0xF5FFCC);
    }

    @SuppressWarnings({ "unchecked" })
    public static <T extends Entity> void registerMob(String name, Class<T> entity, int back, int fore) {
        EntityRegistry.registerModEntity(new ResourceLocation("zcp:" + name), entity, name, currentID, ZCP.instance, 256, 1, true, back, fore);
        if (FMLCommonHandler.instance().getSide() == Side.CLIENT) {
            try {
                Class<Render<? extends T>> render = (Class<Render<? extends T>>) ZCP.class.getClassLoader().loadClass("com/androbean/zcp/client/render/" + entity.getName().replaceAll(".+?Entity", "Render"));
                RenderingRegistry.registerEntityRenderingHandler(entity, render.newInstance());
            }
            catch (Exception e) {
                e.printStackTrace();
            }
        }
        ++currentID;
    }
}


Any and all help is much appreciated, thank you!

Edited by Androbean

  • Author

If it's any help, mobs (such as slimes, that's what I tested with) do interact with the Pepo's bounding box, as do pistons. It seems to be the player who can't interact with the besides attacking (the Pepo's still can't move)

  • Author

Oh my STARS I'm a fool! This isn't the first time I've forgotten a super call! It works perfectly now, thank you so much! I can re-implement aging now. Thank you so much, I'll be sure to always keep the super method in mind in the future.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

Important Information

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

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.