Jump to content

felinoid

Members
  • Posts

    36
  • Joined

  • Last visited

Posts posted by felinoid

  1. If you mean once every block update tick (about the time it takes wheat to grow a stage, iirc), override the block's updateTick() function with your code to put the item in the chest. If you mean once every game tick, I don't know an easy way to do that. You can call this.worldIn.getBlockState(pos.down(3)).getBlock() where 'this' is the block class to get the chest three blocks down. I don't know how to put items in a chest, but you if you look through the minecraft source code, you should be able to at least figure out which functions to use. Good luck!

  2. I wanted to make my own textures for horses, so I made my own mob that is basically a horse but with the texture code changed. The trouble is, it's not behaving exactly like vanilla horses. Vanilla horses walk for at least a few steps at a time, whereas mine will walk a step, stop, and walk some more. This doesn't sound like much, I know, but it really looks silly. I'm really confused as to why there's any difference, though. Vanilla horses inherit from AbstractHorse, which sets the AI, and then don't change the AI at all. Mine too inherit from AbstractHorse and don't change the AI. How come they're different?

     

    Here's my horse class:

    Spoiler
    
    package felinoid.horse_colors;
    
    import java.util.UUID;
    import javax.annotation.Nullable;
    import net.minecraft.block.SoundType;
    import net.minecraft.entity.EntityAgeable;
    import net.minecraft.entity.IEntityLivingData;
    import net.minecraft.entity.SharedMonsterAttributes;
    import net.minecraft.entity.ai.attributes.AttributeModifier;
    import net.minecraft.entity.passive.AbstractHorse;
    import net.minecraft.entity.passive.EntityAnimal;
    import net.minecraft.entity.passive.EntityDonkey;
    import net.minecraft.entity.passive.EntityMule;
    import net.minecraft.entity.passive.HorseArmorType;
    import net.minecraft.entity.player.EntityPlayer;
    import net.minecraft.init.Items;
    import net.minecraft.item.Item;
    import net.minecraft.init.SoundEvents;
    import net.minecraft.inventory.IInventory;
    import net.minecraft.item.ItemStack;
    import net.minecraft.nbt.NBTTagCompound;
    import net.minecraft.network.datasync.DataParameter;
    import net.minecraft.network.datasync.DataSerializers;
    import net.minecraft.network.datasync.EntityDataManager;
    import net.minecraft.util.DamageSource;
    import net.minecraft.util.EnumHand;
    import net.minecraft.util.ResourceLocation;
    import net.minecraft.util.SoundEvent;
    import net.minecraft.util.datafix.DataFixer;
    import net.minecraft.util.datafix.FixTypes;
    import net.minecraft.util.datafix.walkers.ItemStackData;
    import net.minecraft.world.DifficultyInstance;
    import net.minecraft.world.World;
    import net.minecraft.world.storage.loot.LootTableList;
    import net.minecraftforge.fml.relauncher.Side;
    import net.minecraftforge.fml.relauncher.SideOnly;
    
    public class EntityHorseFelinoid extends AbstractHorse
    {
        private static final UUID ARMOR_MODIFIER_UUID = UUID.fromString("556E1665-8B10-40C8-8F9D-CF9B1667F295");
        private static final DataParameter<Integer> HORSE_VARIANT = EntityDataManager.<Integer>createKey(EntityHorseFelinoid.class, DataSerializers.VARINT);
        private static final DataParameter<Integer> HORSE_ARMOR = EntityDataManager.<Integer>createKey(EntityHorseFelinoid.class, DataSerializers.VARINT);
        private static final DataParameter<ItemStack> HORSE_ARMOR_STACK = EntityDataManager.<ItemStack>createKey(EntityHorseFelinoid.class, DataSerializers.ITEM_STACK);
        private static final String[] HORSE_TEXTURES = new String[] {"chestnut", "bay", "black_original", "seal_brown", "sorrel", "liver_chestnut", "grullo", "light_gray", "dappled_gray_mixed_mane"};
        private static final String[] HORSE_TEXTURES_ABBR = new String[] {"cht", "bay", "blk", "brw", "sor", "liv", "gru", "lgr", "dgm"};
        private static final String[] HORSE_MARKING_TEXTURES = new String[] {null, "textures/entity/horse/horse_markings_white.png", "textures/entity/horse/horse_markings_whitefield.png", "textures/entity/horse/horse_markings_blackdots.png"};
        private static final String[] HORSE_MARKING_TEXTURES_ABBR = new String[] {"", "wo_", "wmo", "bdo"};
        private String texturePrefix;
        private final String[] horseTexturesArray = new String[3];
    
        // Some constants
        private static final int NUM_TEXTURES = HORSE_TEXTURES.length;
        private static final int NUM_MARKINGS = HORSE_MARKING_TEXTURES.length;
    
        public EntityHorseFelinoid(World worldIn)
        {
            super(worldIn);
        }
    
        @Override
        protected void entityInit()
        {
            super.entityInit();
            this.dataManager.register(HORSE_VARIANT, Integer.valueOf(0));
            this.dataManager.register(HORSE_ARMOR, Integer.valueOf(HorseArmorType.NONE.getOrdinal()));
            this.dataManager.register(HORSE_ARMOR_STACK, ItemStack.EMPTY);
        }
    
        public static void registerFixesHorse(DataFixer fixer)
        {
            AbstractHorse.registerFixesAbstractHorse(fixer, EntityHorseFelinoid.class);
            fixer.registerWalker(FixTypes.ENTITY, new ItemStackData(EntityHorseFelinoid.class, new String[] {"ArmorItem"}));
        }
    
        /**
         * (abstract) Protected helper method to write subclass entity data to NBT.
         */
        @Override
        public void writeEntityToNBT(NBTTagCompound compound)
        {
            super.writeEntityToNBT(compound);
            compound.setInteger("Variant", this.getHorseVariant());
    
            if (!this.horseChest.getStackInSlot(1).isEmpty())
            {
                compound.setTag("ArmorItem", this.horseChest.getStackInSlot(1).writeToNBT(new NBTTagCompound()));
            }
        }
    
        /**
         * (abstract) Protected helper method to read subclass entity data from NBT.
         */
        @Override
        public void readEntityFromNBT(NBTTagCompound compound)
        {
            super.readEntityFromNBT(compound);
            this.setHorseVariant(compound.getInteger("Variant"));
    
            if (compound.hasKey("ArmorItem", 10))
            {
                ItemStack itemstack = new ItemStack(compound.getCompoundTag("ArmorItem"));
    
                if (!itemstack.isEmpty() && isArmor(itemstack))
                {
                    this.horseChest.setInventorySlotContents(1, itemstack);
                }
            }
    
            this.updateHorseSlots();
        }
    
        public void setHorseVariant(int variant)
        {
            this.dataManager.set(HORSE_VARIANT, Integer.valueOf(variant));
            this.resetTexturePrefix();
        }
    
        public int getHorseVariant()
        {
            return ((Integer)this.dataManager.get(HORSE_VARIANT)).intValue();
        }
    
        private void resetTexturePrefix()
        {
            this.texturePrefix = null;
        }
    
        @SideOnly(Side.CLIENT)
        private void setHorseTexturePaths()
        {
            int i = this.getHorseVariant();
            int j = (i & 255) % NUM_TEXTURES;
            int k = ((i & 65280) >> 8) % NUM_MARKINGS;
            ItemStack armorStack = this.dataManager.get(HORSE_ARMOR_STACK);
            String texture = !armorStack.isEmpty() ? armorStack.getItem().getHorseArmorTexture(this, armorStack) : HorseArmorType.getByOrdinal(this.dataManager.get(HORSE_ARMOR)).getTextureName(); //If armorStack is empty, the server is vanilla so the texture should be determined the vanilla way
            if (HORSE_TEXTURES[j].contains(".png")) {
                this.horseTexturesArray[0] = HORSE_TEXTURES[j];
            }
            else {
                this.horseTexturesArray[0] = "horse_colors:textures/entity/horse/" 
                                             + HORSE_TEXTURES[j] +".png";
            }
            this.horseTexturesArray[1] = HORSE_MARKING_TEXTURES[k];
            this.horseTexturesArray[2] = texture;
            this.texturePrefix = "horse/" + HORSE_TEXTURES_ABBR[j] + HORSE_MARKING_TEXTURES_ABBR[k] + texture;
        }
    
        @SideOnly(Side.CLIENT)
        public String getHorseTexture()
        {
            if (this.texturePrefix == null)
            {
                this.setHorseTexturePaths();
            }
    
            return this.texturePrefix;
        }
    
        @SideOnly(Side.CLIENT)
        public String[] getVariantTexturePaths()
        {
            if (this.texturePrefix == null)
            {
                this.setHorseTexturePaths();
            }
    
            return this.horseTexturesArray;
        }
    
        /**
         * Updates the items in the saddle and armor slots of the horse's inventory.
         */
        @Override
        protected void updateHorseSlots()
        {
            super.updateHorseSlots();
            this.setHorseArmorStack(this.horseChest.getStackInSlot(1));
        }
    
        /**
         * Set horse armor stack (for example: new ItemStack(Items.iron_horse_armor))
         */
        public void setHorseArmorStack(ItemStack itemStackIn)
        {
            HorseArmorType horsearmortype = HorseArmorType.getByItemStack(itemStackIn);
            this.dataManager.set(HORSE_ARMOR, Integer.valueOf(horsearmortype.getOrdinal()));
            this.dataManager.set(HORSE_ARMOR_STACK, itemStackIn);
            this.resetTexturePrefix();
    
            if (!this.world.isRemote)
            {
                this.getEntityAttribute(SharedMonsterAttributes.ARMOR).removeModifier(ARMOR_MODIFIER_UUID);
                int i = horsearmortype.getProtection();
    
                if (i != 0)
                {
                    this.getEntityAttribute(SharedMonsterAttributes.ARMOR).applyModifier((new AttributeModifier(ARMOR_MODIFIER_UUID, "Horse armor bonus", (double)i, 0)).setSaved(false));
                }
            }
        }
    
        public HorseArmorType getHorseArmorType()
        {
            HorseArmorType armor = HorseArmorType.getByItemStack(this.dataManager.get(HORSE_ARMOR_STACK)); //First check the Forge armor DataParameter
            if (armor == HorseArmorType.NONE) armor = HorseArmorType.getByOrdinal(this.dataManager.get(HORSE_ARMOR)); //If the Forge armor DataParameter returns NONE, fallback to the vanilla armor DataParameter. This is necessary to prevent issues with Forge clients connected to vanilla servers.
            return armor;
        }
    
        /**
         * Called by InventoryBasic.onInventoryChanged() on a array that is never filled.
         */
        @Override
        public void onInventoryChanged(IInventory invBasic)
        {
            HorseArmorType horsearmortype = this.getHorseArmorType();
            super.onInventoryChanged(invBasic);
            HorseArmorType horsearmortype1 = this.getHorseArmorType();
    
            if (this.ticksExisted > 20 && horsearmortype != horsearmortype1 && horsearmortype1 != HorseArmorType.NONE)
            {
                this.playSound(SoundEvents.ENTITY_HORSE_ARMOR, 0.5F, 1.0F);
            }
        }
    
        @Override
        protected void playGallopSound(SoundType p_190680_1_)
        {
            super.playGallopSound(p_190680_1_);
    
            if (this.rand.nextInt(10) == 0)
            {
                this.playSound(SoundEvents.ENTITY_HORSE_BREATHE, p_190680_1_.getVolume() * 0.6F, p_190680_1_.getPitch());
            }
        }
    
        @Override
        protected void applyEntityAttributes()
        {
            super.applyEntityAttributes();
            this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue((double)this.getModifiedMaxHealth());
            this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(this.getModifiedMovementSpeed());
            this.getEntityAttribute(JUMP_STRENGTH).setBaseValue(this.getModifiedJumpStrength());
        }
    
        /**
         * Called to update the entity's position/logic.
         */
        @Override
        public void onUpdate()
        {
            super.onUpdate();
    
            if (this.world.isRemote && this.dataManager.isDirty())
            {
                this.dataManager.setClean();
                this.resetTexturePrefix();
            }
            ItemStack armor = this.horseChest.getStackInSlot(1);
            if (isArmor(armor)) armor.getItem().onHorseArmorTick(world, this, armor);
        }
    
        @Override
        protected SoundEvent getAmbientSound()
        {
            super.getAmbientSound();
            return SoundEvents.ENTITY_HORSE_AMBIENT;
        }
    
        @Override
        protected SoundEvent getDeathSound()
        {
            super.getDeathSound();
            return SoundEvents.ENTITY_HORSE_DEATH;
        }
    
        @Override
        protected SoundEvent getHurtSound(DamageSource damageSourceIn)
        {
            super.getHurtSound(damageSourceIn);
            return SoundEvents.ENTITY_HORSE_HURT;
        }
    
        @Override
        protected SoundEvent getAngrySound()
        {
            super.getAngrySound();
            return SoundEvents.ENTITY_HORSE_ANGRY;
        }
    
        protected ResourceLocation getLootTable()
        {
            return LootTableList.ENTITIES_HORSE;
        }
    
        @Override
        public boolean processInteract(EntityPlayer player, EnumHand hand)
        {
            ItemStack itemstack = player.getHeldItem(hand);
            boolean flag = !itemstack.isEmpty();
    
            if (flag && itemstack.getItem() == Items.SPAWN_EGG)
            {
                return super.processInteract(player, hand);
            }
            else
            {
                if (!this.isChild())
                {
                    if (this.isTame() && player.isSneaking())
                    {
                        this.openGUI(player);
                        return true;
                    }
    
                    if (this.isBeingRidden())
                    {
                        return super.processInteract(player, hand);
                    }
                }
    
                if (flag)
                {
                    if (this.handleEating(player, itemstack))
                    {
                        if (!player.capabilities.isCreativeMode)
                        {
                            itemstack.shrink(1);
                        }
    
                        return true;
                    }
    
                    if (itemstack.interactWithEntity(player, this, hand))
                    {
                        return true;
                    }
    
                    if (!this.isTame())
                    {
                        this.makeMad();
                        return true;
                    }
    
                    boolean flag1 = HorseArmorType.getByItemStack(itemstack) != HorseArmorType.NONE;
                    boolean flag2 = !this.isChild() && !this.isHorseSaddled() && itemstack.getItem() == Items.SADDLE;
    
                    if (flag1 || flag2)
                    {
                        this.openGUI(player);
                        return true;
                    }
                }
    
                if (this.isChild())
                {
                    return super.processInteract(player, hand);
                }
                else
                {
                    this.mountTo(player);
                    return true;
                }
            }
        }
    
        /**
         * Returns true if the mob is currently able to mate with the specified mob.
         */
        @Override
        public boolean canMateWith(EntityAnimal otherAnimal)
        {
            if (otherAnimal == this)
            {
                return false;
            }
            // If I make my own donkey I should change this so they can make mules
            else if (!(otherAnimal instanceof EntityHorseFelinoid))
            {
                return false;
            }
            else
            {
                return this.canMate() && ((EntityHorseFelinoid)otherAnimal).canMate();
            }
        }
    
        @Override
        public EntityAgeable createChild(EntityAgeable ageable)
        {
            AbstractHorse abstracthorse;
    
            if (ageable instanceof EntityDonkey)
            {
                abstracthorse = new EntityMule(this.world);
            }
            else
            {
                EntityHorseFelinoid entityhorse = (EntityHorseFelinoid)ageable;
                abstracthorse = new EntityHorseFelinoid(this.world);
                int j = this.rand.nextInt(9);
                int i;
    
                if (j < 4)
                {
                    i = this.getHorseVariant() & 255;
                }
                else if (j < 8)
                {
                    i = entityhorse.getHorseVariant() & 255;
                }
                else
                {
                    i = this.rand.nextInt(NUM_TEXTURES);
                }
    
                int k = this.rand.nextInt(5);
    
                if (k < 2)
                {
                    i = i | this.getHorseVariant() & 65280;
                }
                else if (k < 4)
                {
                    i = i | entityhorse.getHorseVariant() & 65280;
                }
                else
                {
                    i = i | this.rand.nextInt(NUM_MARKINGS) << 8 & 65280;
                }
    
                ((EntityHorseFelinoid)abstracthorse).setHorseVariant(i);
            }
    
            this.setOffspringAttributes(ageable, abstracthorse);
            return abstracthorse;
        }
    
        @Override
        public boolean wearsArmor()
        {
            return true;
        }
    
        @Override
        public boolean isArmor(ItemStack stack)
        {
            return HorseArmorType.isHorseArmor(stack);
        }
    
        /**
         * Called only once on an entity when first time spawned, via egg, mob spawner, natural spawning etc, but not called
         * when entity is reloaded from nbt. Mainly used for initializing attributes and inventory
         */
        @Nullable
        public IEntityLivingData onInitialSpawn(DifficultyInstance difficulty, @Nullable IEntityLivingData livingdata)
        {
            livingdata = super.onInitialSpawn(difficulty, livingdata);
            int i;
    
            if (livingdata instanceof EntityHorseFelinoid.GroupData)
            {
                i = ((EntityHorseFelinoid.GroupData)livingdata).variant;
            }
            else
            {
                i = this.rand.nextInt(NUM_TEXTURES);
                livingdata = new EntityHorseFelinoid.GroupData(i);
            }
    
            this.setHorseVariant(i | this.rand.nextInt(NUM_MARKINGS) << 8);
            return livingdata;
        }
    
        public static class GroupData implements IEntityLivingData
            {
                public int variant;
    
                public GroupData(int variantIn)
                {
                    this.variant = variantIn;
                }
            }
    }

     

     

    And here's the rest of my classes, just in case:

    Spoiler

    ModEntities.java:

    
    package felinoid.horse_colors;
    
    import net.minecraft.client.renderer.block.model.ModelResourceLocation;
    import net.minecraftforge.client.model.ModelLoader;
    import net.minecraftforge.client.event.ModelRegistryEvent;
    import net.minecraftforge.fml.common.Mod;
    import net.minecraft.item.Item;
    import net.minecraftforge.event.RegistryEvent;
    import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
    import net.minecraftforge.registries.*;
    import net.minecraftforge.fml.common.registry.EntityEntry;
    import net.minecraftforge.fml.common.registry.EntityEntryBuilder;
    import net.minecraft.util.ResourceLocation;
    import net.minecraft.client.renderer.entity.RenderLiving;
    import net.minecraft.entity.Entity;
    
    
    public class ModEntities {
        private static int ID = 0;
    
    	@SubscribeEvent
    	public static void registerEntites(RegistryEvent.Register<EntityEntry> event) {
            String horse_name = "horse_felinoid";
    		EntityEntry entry = EntityEntryBuilder.create()
                .entity(EntityHorseFelinoid.class)
                // Last parameter is network ID, which needs to be unique per mod.
                .id(new ResourceLocation(HorseColors.MODID, horse_name), ID++)
                .name(horse_name)
                .egg(0xFFFFFF, 0xAAAAAA)
                .tracker(64, 20, false)
                .build();
            event.getRegistry().register(entry);
    	}
    }

     

    RenderHorseFelinoid.java:

    
    package felinoid.horse_colors;
    
    import com.google.common.collect.Maps;
    import java.util.Map;
    import net.minecraft.client.Minecraft;
    import net.minecraft.client.model.ModelHorse;
    import net.minecraft.client.renderer.texture.LayeredTexture;
    import net.minecraft.entity.passive.EntityHorse;
    import net.minecraft.util.ResourceLocation;
    import net.minecraftforge.fml.relauncher.Side;
    import net.minecraftforge.fml.relauncher.SideOnly;
    import net.minecraft.client.renderer.entity.RenderManager;
    import net.minecraft.client.renderer.entity.RenderLiving;
    import net.minecraft.client.renderer.entity.Render;
    
    @SideOnly(Side.CLIENT)
    public class RenderHorseFelinoid extends RenderLiving<EntityHorseFelinoid>
    {
        private static final Map<String, ResourceLocation> LAYERED_LOCATION_CACHE = Maps.<String, ResourceLocation>newHashMap();
    
        public RenderHorseFelinoid(RenderManager renderManager)
        {
            super(renderManager, new ModelHorse(), 0.75F);
        }
    
        /**
         * Returns the location of an entity's texture. Doesn't seem to be called unless you call Render.bindEntityTexture.
         */
        @Override
        protected ResourceLocation getEntityTexture(EntityHorseFelinoid entity)
        {
            String s = entity.getHorseTexture();
            ResourceLocation resourcelocation = LAYERED_LOCATION_CACHE.get(s);
    
            if (resourcelocation == null)
            {
                resourcelocation = new ResourceLocation(s);
                Minecraft.getMinecraft().getTextureManager().loadTexture(resourcelocation, new LayeredTexture(entity.getVariantTexturePaths()));
                LAYERED_LOCATION_CACHE.put(s, resourcelocation);
            }
    
            return resourcelocation;
        }
    }

     

    Main mod class, HorseColors.java:

    
    package felinoid.horse_colors;
    
    import net.minecraftforge.event.RegistryEvent;
    import net.minecraftforge.fml.common.Mod;
    import net.minecraftforge.fml.common.Mod.EventHandler;
    import net.minecraftforge.fml.common.Mod.Instance;
    import net.minecraftforge.fml.common.event.*;
    import net.minecraft.block.Block;
    import net.minecraftforge.common.MinecraftForge;
    import net.minecraftforge.fml.common.SidedProxy;
    
    
    @Mod(modid = HorseColors.MODID, name = HorseColors.NAME, version = HorseColors.VERSION)
    
    public class HorseColors
    {
        public static final String NAME = "Realistic Horse Colors";
        public static final String MODID = "horse_colors";
        public static final String VERSION = "1.12.2-1.0.0";
    
    
        @SidedProxy(clientSide="felinoid.horse_colors.ClientProxy",  serverSide="felinoid.horse_colors.CommonProxy")
        public static CommonProxy proxy;
        
        @Mod.Instance("horse_colors")
        public static HorseColors instance;
        
        @Mod.EventHandler
        public void preInit(final FMLPreInitializationEvent event) 
        {
            MinecraftForge.EVENT_BUS.register(ModEntities.class);
        }
        
        @Mod.EventHandler
        public void init(final FMLInitializationEvent event) 
        {
            proxy.registerRenderers();
        }
        
        @Mod.EventHandler
        public void postInit(final FMLPostInitializationEvent event) {}
    }

     

    ClientProxy.java:

    
    package felinoid.horse_colors;
    
    import net.minecraft.util.ResourceLocation;
    import net.minecraftforge.fml.client.registry.RenderingRegistry;
    import net.minecraftforge.fml.relauncher.SideOnly;
    import net.minecraftforge.fml.relauncher.Side;
    import net.minecraft.client.Minecraft;
    import net.minecraft.client.renderer.entity.Render;
    import net.minecraft.client.renderer.entity.RenderManager;
    import net.minecraft.client.renderer.entity.RenderLiving;
    import net.minecraft.entity.Entity;
    import net.minecraft.client.model.ModelHorse;
    
    public class ClientProxy extends CommonProxy {
    
        @SideOnly(Side.CLIENT)
        @Override
        public void registerRenderers() {
            RenderHorseFelinoid horseRender = new RenderHorseFelinoid(Minecraft.getMinecraft().getRenderManager());
            RenderingRegistry.registerEntityRenderingHandler(EntityHorseFelinoid.class, horseRender);
    	}
    }

     

    CommonProxy.java:

    
    package felinoid.horse_colors;
    
    // Highly unimpressive class.
    public class CommonProxy
    {
        public void registerRenderers() {}
    }

     

     

    Any help figuring this out would be greatly appreciated!

     

    Edit: Found the solution here. Turns out my update frequency was way too high.

  3. 4 hours ago, diesieben07 said:

    You must explicitly register an ItemBlock.

    Thanks! That did the trick.

     

    3 hours ago, Draco18s said:

    As null is a perfectly valid value, all objects are initialized to null.

    Yeah, I guess I mostly forgot everything's a pointer in Java.

     

    So now I have an item for it, and I fixed the missing texture for the block (it needed to be ore_reeds:blocks/ore_essence, not just blocks/ore_essence), but the item still has a missing texture and the lang file isn't working.

     

    My lang file is at src/main/resources/assets/ore_reeds/lang/en_us.lang and looks like:

    tile.ore_essence.name=Ore Essence

    I've also tried

    tile.ore_reeds:ore_essence.name=Ore Essence

    but in both cases my block shows up in-game as tile.ore_reeds:ore_essence.name.

     

    For my json files I've got

    src/main/resources/assets/ore_reeds/blockstates/ore_essence.json:

    {
        "variants": {
            "normal": { "model": "ore_reeds:ore_essence" }
        }
    }

     

    src/main/resources/assets/ore_reeds/models/item/ore_essence.json:

    {
        "parent": "ore_reeds:block/ore_essence"
    }

     

    and src/main/resources/assets/ore_reeds/models/block/ore_essence.json:

    {
        "parent": "block/cube_all",
        "textures": {
            "all": "ore_reeds:blocks/ore_essence"
        }
    }

     

    Thanks again for helping me get this far!

  4. Oh, and running with --stacktrace gets me:

    :runClient FAILED
    
    FAILURE: Build failed with an exception.
    
    * What went wrong:
    Execution failed for task ':runClient'.
    > Process 'command '/usr/lib/jvm/java-8-openjdk-amd64/bin/java'' finished with non-zero exit value 255
    
    * Try:
    Run with --info or --debug option to get more log output.
    
    * Exception is:
    org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':runClient'.
            at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:69)
            at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:46)
            at org.gradle.api.internal.tasks.execution.PostExecutionAnalysisTaskExecuter.execute(PostExecutionAnalysisTaskExecuter.java:35)
            at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:66)
            at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:58)
            at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:52)
            at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:52)
            at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:53)
            at org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(ExecuteAtMostOnceTaskExecuter.java:43)
            at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:203)
            at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:185)
            at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.processTask(AbstractTaskPlanExecutor.java:66)
            at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.run(AbstractTaskPlanExecutor.java:50)
            at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor.process(DefaultTaskPlanExecutor.java:25)
            at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter.execute(DefaultTaskGraphExecuter.java:110)
            at org.gradle.execution.SelectedTaskExecutionAction.execute(SelectedTaskExecutionAction.java:37)
            at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:37)
            at org.gradle.execution.DefaultBuildExecuter.access$000(DefaultBuildExecuter.java:23)
            at org.gradle.execution.DefaultBuildExecuter$1.proceed(DefaultBuildExecuter.java:43)
            at org.gradle.execution.DryRunBuildExecutionAction.execute(DryRunBuildExecutionAction.java:32)
            at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:37)
            at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:30)
            at org.gradle.initialization.DefaultGradleLauncher$4.run(DefaultGradleLauncher.java:153)
            at org.gradle.internal.Factories$1.create(Factories.java:22)
            at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:91)
            at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:53)
            at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:150)
            at org.gradle.initialization.DefaultGradleLauncher.access$200(DefaultGradleLauncher.java:32)
            at org.gradle.initialization.DefaultGradleLauncher$1.create(DefaultGradleLauncher.java:98)
            at org.gradle.initialization.DefaultGradleLauncher$1.create(DefaultGradleLauncher.java:92)
            at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:91)
            at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:63)
            at org.gradle.initialization.DefaultGradleLauncher.doBuild(DefaultGradleLauncher.java:92)
            at org.gradle.initialization.DefaultGradleLauncher.run(DefaultGradleLauncher.java:83)
            at org.gradle.launcher.exec.InProcessBuildActionExecuter$DefaultBuildController.run(InProcessBuildActionExecuter.java:99)
            at org.gradle.tooling.internal.provider.ExecuteBuildActionRunner.run(ExecuteBuildActionRunner.java:28)
            at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
            at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:48)
            at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:30)
            at org.gradle.launcher.exec.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:81)
            at org.gradle.launcher.exec.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:46)
            at org.gradle.launcher.exec.DaemonUsageSuggestingBuildActionExecuter.execute(DaemonUsageSuggestingBuildActionExecuter.java:51)
            at org.gradle.launcher.exec.DaemonUsageSuggestingBuildActionExecuter.execute(DaemonUsageSuggestingBuildActionExecuter.java:28)
            at org.gradle.launcher.cli.RunBuildAction.run(RunBuildAction.java:43)
            at org.gradle.internal.Actions$RunnableActionAdapter.execute(Actions.java:173)
            at org.gradle.launcher.cli.CommandLineActionFactory$ParseAndBuildAction.execute(CommandLineActionFactory.java:239)
            at org.gradle.launcher.cli.CommandLineActionFactory$ParseAndBuildAction.execute(CommandLineActionFactory.java:212)
            at org.gradle.launcher.cli.JavaRuntimeValidationAction.execute(JavaRuntimeValidationAction.java:35)
            at org.gradle.launcher.cli.JavaRuntimeValidationAction.execute(JavaRuntimeValidationAction.java:24)
            at org.gradle.launcher.cli.ExceptionReportingAction.execute(ExceptionReportingAction.java:33)
            at org.gradle.launcher.cli.ExceptionReportingAction.execute(ExceptionReportingAction.java:22)
            at org.gradle.launcher.cli.CommandLineActionFactory$WithLogging.execute(CommandLineActionFactory.java:205)
            at org.gradle.launcher.cli.CommandLineActionFactory$WithLogging.execute(CommandLineActionFactory.java:169)
            at org.gradle.launcher.Main.doAction(Main.java:33)
            at org.gradle.launcher.bootstrap.EntryPoint.run(EntryPoint.java:45)
            at org.gradle.launcher.bootstrap.ProcessBootstrap.runNoExit(ProcessBootstrap.java:55)
            at org.gradle.launcher.bootstrap.ProcessBootstrap.run(ProcessBootstrap.java:36)
            at org.gradle.launcher.GradleMain.main(GradleMain.java:23)
            at org.gradle.wrapper.BootstrapMainStarter.start(BootstrapMainStarter.java:30)
            at org.gradle.wrapper.WrapperExecutor.execute(WrapperExecutor.java:127)
            at org.gradle.wrapper.GradleWrapperMain.main(GradleWrapperMain.java:61)
    Caused by: org.gradle.process.internal.ExecException: Process 'command '/usr/lib/jvm/java-8-openjdk-amd64/bin/java'' finished with non-zero exit value 255
            at org.gradle.process.internal.DefaultExecHandle$ExecResultImpl.assertNormalExitValue(DefaultExecHandle.java:367)
            at org.gradle.process.internal.DefaultJavaExecAction.execute(DefaultJavaExecAction.java:31)
            at org.gradle.api.tasks.JavaExec.exec(JavaExec.java:74)
            at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:75)
            at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.doExecute(AnnotationProcessingTaskFactory.java:228)
            at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.execute(AnnotationProcessingTaskFactory.java:221)
            at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.execute(AnnotationProcessingTaskFactory.java:210)
            at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:621)
            at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:604)
            at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:80)
            at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:61)
            ... 60 more
    
    
    BUILD FAILED
    
    Total time: 22.061 secs

    I thought knowing C++ would be enough to get me by, but I guess I'll have to figure out all this weird reflection stuff Java has.

     

    Edit: Okay, I'm a dumbo who should have read the crash log, which is much more helpful than the error message. Namely,

    Time: 8/24/18 3:01 PM
    Description: Initializing game
    
    java.lang.NullPointerException: Can't use a null-name for the registry, object null.
    	at com.google.common.base.Preconditions.checkNotNull(Preconditions.java:864)
    	at net.minecraftforge.registries.ForgeRegistry.add(ForgeRegistry.java:272)
    	at net.minecraftforge.registries.ForgeRegistry.add(ForgeRegistry.java:266)
    	at net.minecraftforge.registries.ForgeRegistry.register(ForgeRegistry.java:110)
    	at felinoid.ore_reeds.ModBlocks.registerBlock(ModBlocks.java:28)

    (followed by more stack tracing). So it looks like I'm trying to resister it to a null registry? How do I specify a registry that is not null?

  5. Ok, so I made those methods static:

    	@SubscribeEvent
    	public static void registerBlock(RegistryEvent.Register<Block> event) {
    		event.getRegistry().register(ore_essence);
    	}
    	
    	@SubscribeEvent
    	public static void registerItemBlocks(RegistryEvent.Register<Item> event) {
    		event.getRegistry().register(item_ore_essence);
    	}

    Now it crashes Minecraft while Forge is loading. Progress!

     

    The error is:

    :runClient FAILED
    
    FAILURE: Build failed with an exception.
    
    * What went wrong:
    Execution failed for task ':runClient'.
    > Process 'command '/usr/lib/jvm/java-8-openjdk-amd64/bin/java'' finished with non-zero exit value 255
    
    * Try:
    Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
    
    BUILD FAILED
    
    Total time: 22.074 secs
    

    On rerunning with --debug I get:

    13:50:58.488 [LIFECYCLE] [class org.gradle.TaskExecutionLogger] :runClient FAILED
    13:50:58.488 [INFO] [org.gradle.execution.taskgraph.AbstractTaskPlanExecutor] :runClient (Thread[main,5,main]) completed. Took 11.07 secs.
    13:50:58.488 [DEBUG] [org.gradle.execution.taskgraph.AbstractTaskPlanExecutor] Task worker [Thread[main,5,main]] finished, busy: 14.985 secs, idle: 0.04 secs
    13:50:58.497 [ERROR] [org.gradle.BuildExceptionReporter] 
    13:50:58.497 [ERROR] [org.gradle.BuildExceptionReporter] FAILURE: Build failed with an exception.
    13:50:58.498 [ERROR] [org.gradle.BuildExceptionReporter] 
    13:50:58.498 [ERROR] [org.gradle.BuildExceptionReporter] * What went wrong:
    13:50:58.498 [ERROR] [org.gradle.BuildExceptionReporter] Execution failed for task ':runClient'.
    13:50:58.498 [ERROR] [org.gradle.BuildExceptionReporter] > Process 'command '/usr/lib/jvm/java-8-openjdk-amd64/bin/java'' finished with non-zero exit value 255
    13:50:58.498 [ERROR] [org.gradle.BuildExceptionReporter] 
    13:50:58.498 [ERROR] [org.gradle.BuildExceptionReporter] * Try:
    13:50:58.498 [ERROR] [org.gradle.BuildExceptionReporter] Run with --stacktrace option to get the stack trace. 
    13:50:58.498 [LIFECYCLE] [org.gradle.BuildResultLogger] 
    13:50:58.499 [LIFECYCLE] [org.gradle.BuildResultLogger] BUILD FAILED
    13:50:58.499 [LIFECYCLE] [org.gradle.BuildResultLogger] 
    13:50:58.499 [LIFECYCLE] [org.gradle.BuildResultLogger] Total time: 21.477 secs
    13:50:58.517 [DEBUG] [org.gradle.cache.internal.btree.BTreePersistentIndexedCache] Closing cache fileSnapshotsToTreeSnapshotsIndex.bin (/media/tiffany/4cf1084a-2b89-44a4-b210-3d6bac12ca8e/tiffany/test/minecraft_mod/.gradle/2.14/taskArtifacts/fileSnapshotsToTreeSnapshotsIndex.bin)
    13:50:58.517 [DEBUG] [org.gradle.cache.internal.btree.BTreePersistentIndexedCache] Closing cache treeSnapshots.bin (/media/tiffany/4cf1084a-2b89-44a4-b210-3d6bac12ca8e/tiffany/test/minecraft_mod/.gradle/2.14/taskArtifacts/treeSnapshots.bin)
    13:50:58.518 [DEBUG] [org.gradle.cache.internal.btree.BTreePersistentIndexedCache] Closing cache treeSnapshotUsage.bin (/media/tiffany/4cf1084a-2b89-44a4-b210-3d6bac12ca8e/tiffany/test/minecraft_mod/.gradle/2.14/taskArtifacts/treeSnapshotUsage.bin)
    13:50:58.518 [DEBUG] [org.gradle.cache.internal.btree.BTreePersistentIndexedCache] Closing cache taskArtifacts.bin (/media/tiffany/4cf1084a-2b89-44a4-b210-3d6bac12ca8e/tiffany/test/minecraft_mod/.gradle/2.14/taskArtifacts/taskArtifacts.bin)
    13:50:58.518 [DEBUG] [org.gradle.cache.internal.btree.BTreePersistentIndexedCache] Closing cache fileSnapshots.bin (/media/tiffany/4cf1084a-2b89-44a4-b210-3d6bac12ca8e/tiffany/test/minecraft_mod/.gradle/2.14/taskArtifacts/fileSnapshots.bin)
    13:50:58.518 [DEBUG] [org.gradle.cache.internal.btree.BTreePersistentIndexedCache] Closing cache fileHashes.bin (/media/tiffany/4cf1084a-2b89-44a4-b210-3d6bac12ca8e/tiffany/test/minecraft_mod/.gradle/2.14/taskArtifacts/fileHashes.bin)
    13:50:58.519 [DEBUG] [org.gradle.cache.internal.DefaultFileLockManager] Releasing lock on task history cache (/media/tiffany/4cf1084a-2b89-44a4-b210-3d6bac12ca8e/tiffany/test/minecraft_mod/.gradle/2.14/taskArtifacts).
    13:50:58.520 [DEBUG] [org.gradle.api.internal.artifacts.ivyservice.ivyresolve.memcache.InMemoryCachedRepositoryFactory] In-memory dependency metadata cache closed. Repos cached: 45, cache instances: 6, modules served from cache: 14, artifacts: 5
    13:50:58.520 [DEBUG] [org.gradle.cache.internal.DefaultCacheAccess] Cache Generated Gradle JARs cache (/home/tiffany/.gradle/caches/2.14/generated-gradle-jars) was closed 0 times.
    13:50:58.521 [DEBUG] [org.gradle.cache.internal.btree.BTreePersistentIndexedCache] Closing cache artifact-at-repository.bin (/home/tiffany/.gradle/caches/modules-2/metadata-2.16/artifact-at-repository.bin)
    13:50:58.521 [DEBUG] [org.gradle.cache.internal.btree.BTreePersistentIndexedCache] Closing cache module-metadata.bin (/home/tiffany/.gradle/caches/modules-2/metadata-2.16/module-metadata.bin)
    13:50:58.521 [DEBUG] [org.gradle.cache.internal.DefaultFileLockManager] Releasing lock on artifact cache (/home/tiffany/.gradle/caches/modules-2).
    13:50:58.521 [DEBUG] [org.gradle.api.internal.artifacts.ivyservice.resolveengine.store.CachedStoreFactory] Resolution result cache closed. Cache reads: 1, disk reads: 1 (avg: 0.012 secs, total: 0.012 secs)
    13:50:58.522 [DEBUG] [org.gradle.api.internal.artifacts.ivyservice.resolveengine.store.CachedStoreFactory] Resolution result cache closed. Cache reads: 0, disk reads: 0 (avg: 0.0 secs, total: 0.0 secs)
    13:50:58.522 [DEBUG] [org.gradle.api.internal.artifacts.ivyservice.resolveengine.store.ResolutionResultsStoreFactory] Deleted 2 resolution results binary files in 0.001 secs
    13:50:58.524 [DEBUG] [org.gradle.cache.internal.DefaultCacheAccess] Cache Plugin Resolution Cache (/home/tiffany/.gradle/caches/2.14/plugin-resolution) was closed 0 times.
    13:50:58.524 [DEBUG] [org.gradle.api.internal.tasks.compile.daemon.CompilerDaemonManager] Stopping 0 compiler daemon(s).
    13:50:58.525 [INFO] [org.gradle.api.internal.tasks.compile.daemon.CompilerDaemonManager] Stopped 0 compiler daemon(s).

     

  6. I haven't found a good tutorial for 1.12, so I've been using a mix of tutorials for older versions, looking at the Minecraft source, looking at the java output of MCreator, and reading random forum posts. Unfortunately the only one of those that really describes how to register events the new way was a random forum post.

     

    Ok, so the preinit function in OreReeds.java now looks like this:

    	@Mod.EventHandler
    	public void preInit(final FMLPreInitializationEvent event) 
    	{
    		MinecraftForge.EVENT_BUS.register(ModBlocks.class);
    	}

    However, the block is still not showing up.

     

    And my BlockOreEssence.java now looks like:

    package felinoid.ore_reeds;
    
    import net.minecraft.block.Block;
    import net.minecraft.block.material.MapColor;
    import net.minecraft.block.material.Material;
    import net.minecraft.block.state.IBlockState;
    import net.minecraft.world.IBlockAccess;
    import net.minecraft.util.math.BlockPos;
    import net.minecraft.creativetab.CreativeTabs;
    import net.minecraft.util.BlockRenderLayer;
    import net.minecraft.util.EnumBlockRenderType;
    import net.minecraftforge.fml.relauncher.Side;
    import net.minecraftforge.fml.relauncher.SideOnly;
    import net.minecraft.block.material.Material;
    import net.minecraft.block.state.IBlockState;
    import net.minecraft.creativetab.CreativeTabs;
    
    public class BlockOreEssence extends Block
    {
        protected BlockOreEssence()
        {
            super(Material.ROCK);
            setUnlocalizedName("ore_reeds_ore_essence");
            setRegistryName("ore_essence");
            this.setCreativeTab(CreativeTabs.BUILDING_BLOCKS);
        }
    
        /**
         * Get the MapColor for this Block and the given BlockState
         */
        @Override
        public MapColor getMapColor(IBlockState state, IBlockAccess worldIn, BlockPos pos)
        {
            return MapColor.BLACK;
        }
        
    }

    @diesieben07, is that the correct way to solve the other problems?

  7. I'm trying to make a mod that adds a block. I've got three java files:


    src/main/java/ore_reeds/OreReeds.java:

    package felinoid.ore_reeds;
    
    import net.minecraftforge.event.RegistryEvent;
    import net.minecraftforge.fml.common.Mod;
    import net.minecraftforge.fml.common.Mod.EventHandler;
    import net.minecraftforge.fml.common.Mod.Instance;
    import net.minecraftforge.fml.common.event.*;
    import net.minecraft.block.Block;
    
    
    @Mod(modid = OreReeds.MODID, name = OreReeds.NAME, version = OreReeds.VERSION)
    
    public class OreReeds
    {
    	public static final String NAME = "Ore Reeds";
    	public static final String MODID = "ore_reeds";
    	public static final String VERSION = "1.12.2-1.0.0";
    	
    	@Mod.Instance("ore_reeds")
    	public static OreReeds instance;
    	
    	@Mod.EventHandler
    	public void preInit(final FMLPreInitializationEvent event) {}
    	
    	@Mod.EventHandler
    	public void init(final FMLInitializationEvent event) {}
    	
    	@Mod.EventHandler
    	public void postInit(final FMLPostInitializationEvent event) {}
    }



    src/main/java/ore_reeds/blocks/ModBlocks.java:

    package felinoid.ore_reeds;
    
    import net.minecraft.block.Block;
    import net.minecraft.item.Item;
    import net.minecraft.block.material.Material;
    import net.minecraft.block.state.IBlockState;
    import net.minecraft.creativetab.CreativeTabs;
    import net.minecraft.util.BlockRenderLayer;
    import net.minecraft.util.EnumBlockRenderType;
    import net.minecraftforge.event.RegistryEvent;
    import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
    import net.minecraftforge.registries.IForgeRegistryEntry;
    import net.minecraftforge.registries.*;
    
    public class ModBlocks {
    	public static Block ore_essence;
    	
    	public static Item item_ore_essence = Item.getItemFromBlock(ore_essence);
    
    	public static void preInit() {}
    
    	public static void init() {}
    
    	
    	@SubscribeEvent
    	public void registerBlock(RegistryEvent.Register<Block> event) {
    		event.getRegistry().register(ore_essence);
    	}
    	
    	@SubscribeEvent
    	public void registerItemBlocks(RegistryEvent.Register<Item> event) {
    		event.getRegistry().register(item_ore_essence);
    	}
        
    }

    (I'm pretty much entirely guessing at how to register things here, so maybe that's the problem.)

    and src/main/java/blocks/OreEssence.java:

    package felinoid.ore_reeds;
    
    import net.minecraft.block.Block;
    import net.minecraft.block.material.Material;
    import net.minecraft.block.state.IBlockState;
    import net.minecraft.creativetab.CreativeTabs;
    import net.minecraft.util.BlockRenderLayer;
    import net.minecraft.util.EnumBlockRenderType;
    import net.minecraftforge.fml.relauncher.Side;
    import net.minecraftforge.fml.relauncher.SideOnly;
    import net.minecraft.block.material.Material;
    import net.minecraft.block.state.IBlockState;
    import net.minecraft.creativetab.CreativeTabs;
    
    public class BlockOreEssence extends Block
    {
        protected BlockOreEssence()
        {
            super(Material.ROCK);
            setUnlocalizedName("ore_essence");
            setRegistryName("ore_essence");
            this.setCreativeTab(CreativeTabs.BUILDING_BLOCKS);
        }
    
        /**
         * Get the MapColor for this Block and the given BlockState
         */
        public MapColor getMapColor(IBlockState state, IBlockAccess worldIn, BlockPos pos)
        {
            return MapColor.BLACK;
        }
        
    }



    There's also some json files, a texture, and a lang, but from what I understand it should at least show up even without those. My block is not showing up in the creative mode inventory, and if I try to use /give or /setblock, it tells me ore_reeds:ore_essence isn't a real block. Any idea what could be going wrong?

×
×
  • Create New...

Important Information

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