Jump to content

AntonBespoiasov

Members
  • Posts

    41
  • Joined

  • Last visited

Everything posted by AntonBespoiasov

  1. I need to execute code when my block is destroyed but before its tile entity and state are removed. I need this because I need to replace the block with other block, and the data required for this is spread across the blockstate and the tile entity. When the code is executed the getBlockState and getTileEntity methods of the world object must return the correct blockstate and tile entity of the old block(not the new one that the old block is replaced with).
  2. Forge version: 28.0.17 Minecraft version: 1.14.4 Java: 1.8 64-bit OS: Windows 10 64-bit What I did: 1. I installed Forge installer from Forge's site. 2. Ran it and installed "forged" server in an empty folder. 3. I launched vanilla server jar(*minecraft_server.1.14.4.jar*), stopped it, accepted the EULA and ran the server again. 4. Then I ran the "forged" server jar(*forge-1.14.4-28.0.17.jar*) with the arguments shown in the console output below. It fails with the *java.lang.UnsupportedOperationException* exception. It was supposed to open the Minecraft server GUI I guess. I think the problem is in compatibility of my environment and the Forge server. Earlier I tried to setup 1.12.2 modded server. I tried 3 versions of Forge all were failing on the same stage with a different exception, I reported it on GitHub, they redirected me to Forge forum. Before that I tried installing vanilla server, it worked fine, I could join the server. Thanks in advance! Output:
  3. Creating multiblock system I decided that I will store original blockstate in TEs of blocks of a multiblock because my multiblocks are pretty dynamic and some 3-dimensional array storing their structure wouldn't work. This blockstate will replace corresponding block of the multiblock with itself when the multiblock is dissassembled(some of its blocks are destroyed). But I don't know if each block in the world is unique blockstate or just reference to certain blockstate. Doing some researches I came across StateContainer that is filled with blockstates in constructor of Block and stored there. This is a proof of blockstates being created only once for each combination of properties. Do blockstates have fixed indexes? Because I want to store the indexes in unloaded chunks instead of map of properties and values(since O(1) is better than O(n)). "Fixed indexes" means that the same blockstate will have the same index each time game loads.
  4. The multiblocks are pretty similar to those ones in Immersive Engineering. They can be rotated(but not mirrored yet), they look like solid machine and blocks of resulting multiblock mostly don't look similar to blocks that have stood on their places before the multiblock was formed. Clicking on different blocks of multiblock may trigger different actions. There will also be different additions to multiblock: items input/output block, pattern chest and pattern creator(they allow you to put some recipe in the machine they attached to and then perform this recipe automatically, like that crafting table from BuildCraft) and probably more. Some of them will be dynamic(e.g. altar that may have different amount of pedestals, pillars that may have different length), the look of the dynamic parts will mostly blend with entire multiblock. System that is used to form multiblocks is already done and is based on events that will make some method iterate through multimap of multiblock creators(factories) instances associated with class of the event and call trigger method of the multiblock creators passing the event as a parameter. Things that will happen in the trigger method are all based on utils for scanning possible multiblock structure. Briefly: weird mix of Vanilla recipes system and Forge events system. So when a player builds structure needed to form multiblock he will need to click(or perform some other key action in formation of multiblock) on certain block of the multiblock to trigger its creation.
  5. My mod uses master-slave multiblock system. But I still don't know how should the multiblock be rendered. I have some possible solutions for this problem: Each block of a multiblock stores ID of its model as property of block state. Then using blockstate JSON files I can map corresponding models to corresponding block of multiblock. Here comes another question: should each multiblock have its own implementation of slave and master, just its own instances of an existing implementation of slave and master or one instance of each implementation of slave and master will be used for all multiblocks. I will create my own implementation of IBakedModel. Where one block will render entire multiblock while all other blocks in the multiblock will have no model and render nothing. But I'm not sure if IBakedModel is allowed to render something outside of its block. I will use TER to render entire multiblock like in previous solution but using TER instead of implementation of IBakedModel. Each block of a multiblock will be separate block instance, have its own registry name and therefore its own blockstate JSON where I will be able to map corresponding model. If you have some other ideas share them. If its possible could you attach some example implementations and explain the solution better because I'm not really good at rendering and implementing IBakedModel.
  6. public class UnderInstrumentsConstructionTileEntity extends ModTileEntity { public static TileEntityType<UnderInstrumentsConstructionTileEntity> TYPE; public BlockState state; public UnderInstrumentsConstructionTileEntity(TileEntityType<?> tileEntityTypeIn) { super(TYPE); } @Override public CompoundNBT writeData(CompoundNBT nbt) { // TODO Auto-generated method stub return null; } @Override public void readData(CompoundNBT nbt) { // TODO Auto-generated method stub } class ThisTER extends TileEntityRenderer<UnderInstrumentsConstructionTileEntity> { public ThisTER(TileEntityRendererDispatcher p_i226006_1_) { super(p_i226006_1_); } @Override public void func_225616_a_(UnderInstrumentsConstructionTileEntity te, float f, MatrixStack matrix, IRenderTypeBuffer buf, int i, int i2) { Minecraft.getInstance().getBlockRendererDispatcher().renderBlock(te.state, matrix, buf, i, OverlayTexture.field_229196_a_, EmptyModelData.INSTANCE); // TODO: Find right 4th param } } } I want to create a block that will store information about another block needed to render it(e.g. this block will store block state of a fence block and then using this block state to render right model of fence). Also I want the block to be layered with some texture. Writing above code I was stuck finding a way to render the texture(I haven't written static field storing it yet) and make it wrap around cube in the world. I thing that using TER in this case probably isn't the right way and I should do something with my own implementation of IBakedModel.
  7. Some methods, classes, fields and etc.(symbols) names are replaced with unreadable names that look like combination of symbol type and its number. Below I listed some of them(there are much more) : com.mojang.blaze3d.matrix.MatrixStack: net.minecraft.block.Block: And my favorite one that turns rendering into hell and where all method and field names are wrong - com.mojang.blaze3d.platform.GLStateManager: How to fix this? I have already written some code using the wrong symbol names can I automatically replace references to them in my code with normal when I fix the problem? Sorry if this is Java problem and is not related to Forge.
  8. assets/uc_auramagic/recipes/experience_shard.json: { "type": "uc_auramagic:experience_shard" }
  9. public class RecipeExperienceShard extends SpecialRecipe { public static SpecialRecipeSerializer<RecipeExperienceShard> SERIALIZER = IRecipeSerializer.register(Auramagic.prefix("experience_shard"), new SpecialRecipeSerializer<RecipeExperienceShard>(RecipeExperienceShard::new)); public RecipeExperienceShard(ResourceLocation idIn) { super(idIn); } @Override public boolean matches(CraftingInventory inv, World worldIn) { EnumExperienceColor kind = null; int j = 0; for (int i = 0; i < inv.getSizeInventory(); i++) { ItemStack cur = inv.getStackInSlot(i); if (cur.getItem() instanceof ItemExperienceGem) { if (kind == null) kind = ((ItemExperienceGem)cur.getItem()).kind; else if (((ItemExperienceGem)cur.getItem()).kind != kind) return false; else j++; } else return false; } return j == 8; } @Override public ItemStack getCraftingResult(CraftingInventory inv) { return new ItemStack(((ItemExperienceGem)inv.getStackInSlot(0).getItem()).kind.shard); } @Override public boolean canFit(int width, int height) { return width * height >= 9; } @Override public IRecipeSerializer<?> getSerializer() { return SERIALIZER; } } I have a implementation of special recipe that requires player to fill crafting grid with item of class ItemExperienceGem and gives item of class ItemExperienceShard as a result. The instance of resulting item depends on kind field of input items(ItemExperienceGem). I looked into vanilla code and found vanilla registering special recipes through IRecipeSerializer.register(...) . But doing this with my recipe doesn't work. Code doesn't pause on breakpoint in beginning of the implementation of matches(...) method. I also created recipe json file in assets/uc_auramagic/recipes: { "type": "uc_auramagic:experience_shard" } uc_auramagic is mod-id of the mod.
  10. I have a bunch of items where all items must use the same model but each item in this bunch has different registry name. In 1.15 an item automatically gets model location assigned to it(by registry name of the item), but I would want to change the model location assigned to the item by default.
  11. Before 1.14 I could simply click debug button in Eclipse and it would run Minecraft with my mod, in this case I could do step debugging, pause everything, view threads and etc. But in new version to run Minecraft with my mod I need to run gradlew runClient. It runs perfectly but I can't debug it. Maybe I need to attach Minecraft process to Java debugger somehow.
  12. I overrode getRemainingItems with code from net.minecraft.item.crafting.RecipeRepairItem. The code simply tries to get container from items that lie on the crafting grid. But it didn't help. Also I solved the NBT problem. New code is in the first post of the topic with the implementation of getRemainingItems and new NBT setting code.
  13. public class OreFinderBindOre extends IForgeRegistryEntry.Impl<IRecipe> implements IRecipe { public OreFinderBindOre() { setRegistryName(References.MOD_ID + ":ore_finder_bind_ore"); } @Override public boolean matches(InventoryCrafting inv, World worldIn) { ItemStack oreFinder = null; ItemStack ore = null; for (int i = 0; i < inv.getSizeInventory(); i++) { ItemStack cur = inv.getStackInSlot(i); if (cur.getItem() == Main.ORE_FINDER) { if (oreFinder != null) return false; oreFinder = cur; } else if (cur.getItem() instanceof ItemBlock) { if (ore == null) ore = new ItemStack(cur.getItem(), 1, cur.getItemDamage()); else if (ore.isItemEqual(cur)) ore.grow(1); else return false; } else { return false; } } return ore.getCount() == 8 && oreFinder.getTagCompound() == null; } @Override public ItemStack getCraftingResult(InventoryCrafting inv) { ItemStack oreFinder = null; ItemBlock ore = null; Main.LOGGER.info("Executed the line"); for (int i = 0; i < inv.getSizeInventory(); i++) // Fetches ingredients { ItemStack cur = inv.getStackInSlot(i); if (cur.getItem() == Main.ORE_FINDER) { oreFinder = cur; } else if (cur.getItem() instanceof ItemBlock) { ore = (ItemBlock)cur.getItem(); } } NBTTagCompound nbt = oreFinder.getTagCompound(); if (nbt == null || !nbt.hasKey("Ore")) { nbt = new NBTTagCompound(); nbt.setInteger("Ore", Block.getIdFromBlock(ore.getBlock())); // Set the ore in the ore finder } oreFinder.setTagCompound(nbt); return oreFinder; } @Override public boolean canFit(int width, int height) { return width * height >= 9; } public boolean isDynamic() { return true; } @Override public ItemStack getRecipeOutput() { return ItemStack.EMPTY; } public NonNullList<ItemStack> getRemainingItems(InventoryCrafting inv) { NonNullList<ItemStack> nonnulllist = NonNullList.<ItemStack>withSize(inv.getSizeInventory(), ItemStack.EMPTY); for (int i = 0; i < nonnulllist.size(); ++i) { ItemStack itemstack = inv.getStackInSlot(i); nonnulllist.set(i, net.minecraftforge.common.ForgeHooks.getContainerItem(itemstack)); } return nonnulllist; } } The above code is the implementation of IRecipe. The Ore finder has NBT tag "Ore" that stores ore. The ore finder is like compass but it points to closest block which ID is stored in the "Ore" tag. The purpose of the implementation of IRecipe is to say which block to find. You put 8 of the blocks and an Ore finder on the crafting grid. It puts ID of the blocks in the "Ore" tag, consumes blocks and gives as result Ore finder with the new NBT tag. The problem is when the player takes the result from recipe output slot puts it in his inventory and then closes crafting inventory the item disappears. Why does it happen. Maybe server-client async but I checked vanilla implementations of IRecipe and they didn't use any messages and packets. Thanks in advance for solving such a personal problem.
  14. Why does crafting logic happen always in the getCratingResult method? When are they invoked and for what purpose?
  15. After running gradlew eclipse in my project directory Eclipse said me that type String is missing. Removing and adding JRE from buid path didn't help
  16. Redstone uses IBlockColor to change color depending on power. It multiplies color of specified tint index. What's the number of redstone color multiplier per one power unit of redstone?
  17. /** Decreases player's experience properly */ public static void decreaseExp(EntityPlayer player, float amount) { if (player.experienceTotal - amount <= 0) { player.experienceLevel = 0; player.experience = 0; player.experienceTotal = 0; return; } player.experienceTotal -= amount; if (player.experience * (float)player.xpBarCap() <= amount) { amount -= player.experience * (float)player.xpBarCap(); player.experience = 1.0f; player.experienceLevel--; } while (player.xpBarCap() < amount) { amount -= player.xpBarCap(); player.experienceLevel--; } player.experience -= amount / (float)player.xpBarCap(); } 1.12.2
  18. I solved this problem. And I did it in pretty weird way. I add entity = worldIn.getEntityByID(entity.getEntityId()) after getting entity with ModMath.getMouseOver(…). The problem was in ModMath.getMouseOver(…).
  19. Can I just change ModMath.getMouseOver(…) to make it be able to work only on server. And put everything in if (!worldIn.isRemote). Will it work?
  20. public ItemStack onItemUseFinish(ItemStack stack, World worldIn, EntityLivingBase entityLiving) { Entity entity = ModMath.getMouseOver(Minecraft.getMinecraft().getRenderPartialTicks(), 0); // Gets entity that entityLiving is looking at if (entity != null && entity instanceof EntityLiving) { ((EntityLiving)entity).attackEntityFrom(DamageSource.MAGIC, 2.0f); ((EntityLiving)entity).setRevengeTarget(entityLiving); } return stack; } Using item that has the implementation of the method above doesn't damage entity. Debugging it showed that attackEntityFrom() is called, code within if statement is executed but entity isn't attacked. I looked into Minecraft's files that use attackEntityFrom() and observed that they just call attackEntityFrom(), just one line of code(I assume that something else that can affect entity attacking process was called before attackEntityFrom() in that files). How can I solve this problem? How can I deal damage to entity?
  21. Playing with Thaumcraft I noticed that non-vanilla and non-Thaumcraft items and blocks can be smelt in Alchemical Furnace to make liquid aspects. So how can I add this feature to items and blocks from my mod? Or aspects of non-vanilla and non-Thaumcraft items and blocks are only defined in Thaumcraft?
  22. I have a block that mustn't be counted when piston counts blocks for pushing limit.But I don't know how to implement this feature. I've got an idea that I can move block using methods of block. I.e if there is a method that is called right before piston pushes blocks and that receives information about the push I can move block from this method before the piston. That means that piston won't count this block while trying to push the blocks. Another idea isn't related to "method that is triggered when piston pushes blocks". This idea is about overriding piston and its behavior. I can somehow remove instance of old implementation of piston from registry and add mine one. But I think that it can cause mods conflicts and etc.
  23. Your project path mustn't contain spaces. Also run gradlew cleancache --refresh-dependencies setupDecompWorkspace eclipse in folder of the project. To do that create new .txt file, paste this command there and save this .txt file in the project folder as .bat file and run. Or use command prompt in folder to run the command. Then run gradlew.bat file again(this file must be in project folder by default). Don't forget to specify *project folder*/eclipse as workspace when you launch Eclipse(or whatever IDE you use).
  24. Some food from some mods have different speed of being eaten. How can I make this feature?
  25. How can I override IForgeItem#getAttributeModifiers(EquipmentSlotType, ItemStack) if Minecraft will still return common ItemStack. And I didn't find IForgeItem in Forge with C+SHIFT+H.
×
×
  • Create New...

Important Information

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