felinoid
-
Posts
36 -
Joined
-
Last visited
Posts posted by felinoid
-
-
Does Forge crash even with no mods installed? If not, you might want to narrow it down and see which mod is causing it.
-
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:
Spoilerpackage 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:
SpoilerModEntities.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.
-
13 hours ago, Draco18s said:
its en_us if you're using pack_format 3 in your pack.mcmeta file. If a value isn't specified it uses version 2.
Ah, that makes sense.
-
Hooray! It works!
Funny, the only thing I found when searching for why my lang file didn't work was someone saying it needed to be en_us, not en_US, but changing it to en_US fixed it. And now that I also register the model for the item, the item has a texture! Thank you everyone!
-
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!
-
Thank you! I'd thought that declaring the variable automatically called the constructor like in C++, but I guess not in Java. It no longer crashes, and the block now shows up in the game! It has no texture and the item for it still doesn't exist, but I think I might be able to figure those out. Thank you all for all your help!
-
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?
-
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).
-
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?
-
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?
[1.12.2] Putting item in a chest every tick
in Modder Support
Posted
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!