Jump to content

xerca

Members
  • Posts

    25
  • Joined

  • Last visited

Everything posted by xerca

  1. After splitting a mod, many items, blocks, etc. changed registry names due to the new mod id. I can handle blocks, items and entities by remapping in the corresponding MissingMappings event, but I believe this event is not fired for tile entities. I tried doing it with only remapped blocks on a save and the blocks appeared in the world, but they were missing the tile entity data that they had. How can I remap tile entities?
  2. Hello, I have an inhouse mod that is really large and adds a ton of different kinds of things to the game. Lately I thought maybe I should release some of it because some pieces of it might interest other people too, but as it is right now, someone who wants a feature from the mod wouldn't necessarily want the remaining 99% of it. So, what is the best way to make it more modular? Extract pieces to completely separate mods? Or some way to use configuration files to enable/disable features? I still want to be able to easily develop it as a single project. Being able to configure it sounds easier since that would probably require less changes to the architecture and still let separate features to interact, but I'm not sure how other people do it.
  3. I have had this problem with Items and SoundEvents but I assume it happens with other objects as well. The mismatch I'm talking about is that the server will think the item is an item while the client thinks it is another item, or plays the wrong sound, etc. This does not happen with single player worlds but happens reliably with dedicated servers. This basically makes the old multiplayer world save unplayable, so it is pretty annoying. Steps to reproduce it: Create and join a new multiplayer world with a dedicated server using mod that adds Item X Make a new version of the mod to add Item Y. It may need to be registered before X to cause the problem but I'm not sure. Update the mods on client and server Join the same world and be sad
  4. I have the same problem. I only get one chance to connect, if it fails to connect for whatever reason or disconnects during play, I can't reconnect. It only shows NullPointerException and I have to restart the game completely.
  5. Damn, I spent a lot of time for no reason then. I should learn to check the github issues and not just count on google searches.
  6. I have a strange problem where a capability that otherwise works perfectly well doesn't work after changing dimensions, such as going to the nether or back to overworld. I did some debugging and found where the error is but I don't understand why it exists. When an entity is removed (such as when changing dimensions), it's invalidateCaps() method is called, so its valid field becomes false. This means when player.getCapability is called for whichever capability, it returns LazyOptional.empty(): public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable EnumFacing side) { final CapabilityDispatcher disp = getCapabilities(); return !valid || disp == null ? LazyOptional.empty() : disp.getCapability(cap, side); } Entity is also removed when it dies, but upon respawning the AttachCapabilitiesEvent is called again both on the client and the server threads, and the capability works fine. However, when the entity changes dimensions, the AttachCapabilitiesEvent is only called on the client thread. I don't know if this has anything to do with the problem. If anyone knows how to deal with this problem, I would appreciate the help.
  7. Putting it above the mods line actually worked! It's really weird because I just copied and modified the example mod's file. Anyways, thank you for the help!
  8. I tried to explain by text but here is the folder structure: Here is how the mods.toml looks: modLoader="javafml" #mandatory # A version range to match for said mod loader - for regular FML @Mod it will be the forge version loaderVersion="[25,)" #mandatory (24 is current forge version) # A list of mods - how many allowed here is determined by the individual mod loader [[mods]] #mandatory # The modid of the mod modId="xercamod" #mandatory # The version number of the mod - there's a few well known ${} variables useable here or just hardcode it version="1.13.2-2" #mandatory # A display name for the mod displayName="Xerca Mod" #mandatory # A URL to query for updates for this mod. See the JSON update specification <here> #updateJSONURL="http://myurl.me/" #optional # A URL for the "homepage" for this mod, displayed in the mod UI #displayURL="http://example.com/" #optional # A file name (in the root of the mod JAR) containing a logo for display logoFile="logo.png" #optional description=''' Something something ''' And here is how the root of my mod jar looks:
  9. In the mods.toml there is a logoFile key that looks like this: logoFile="examplemod.png" And there is a comment that says "A file name (in the root of the mod JAR) containing a logo for display". In my mod, I put a logo.png file under the resources folder and wrote its name in my mods.toml file (logoFile="logo.png"). I also checked the built jar file and I see logo.png in the root like it says. But the image is not there when I enter the mods tab in game. Everything else seems to work though, name, description, etc. Does anyone know what could be the problem?
  10. Thank you, you're right, it calls matches continously a few lines before getting the output. Assuming the main game code runs in a single thread, hopefully there will be no race conditions. I got away with just remembering the required NBT value of the itemstack. It seems to work for now, although it is one of the more bizarre workarounds I did. I hope forge adds a way to do this normally in the future.
  11. Unfortunately I don't have any way of knowing which furnace is calling getRecipeOutput, so this would probably only work if there is just one active furnace in the whole world at a time .
  12. I have a smelting recipe that needs to copy its input's NBT data to its output. I tried to use a custom IRecipe for that like I did for similar crafting recipes, but the smelting code in TileEntityFurnace does not respect getCraftingResult() at all. It only uses getRecipeOutput() as such (which is normally for display purposes) ItemStack itemstack = this.furnaceItemStacks.get(0); ItemStack itemstack1 = recipe.getRecipeOutput(); ItemStack itemstack2 = this.furnaceItemStacks.get(2); if (itemstack2.isEmpty()) { this.furnaceItemStacks.set(2, itemstack1.copy()); } else if (itemstack2.getItem() == itemstack1.getItem()) { itemstack2.grow(itemstack1.getCount()); } So I cannot set the NBT data of the output ItemStack. I also tried using a PlayerEvent.ItemSmeltedEvent, however that event does not give me any handle to the input, it only has the output. So I cannot read the input's NBT in this way. Is there another way to do what I am trying to achieve other than creating infinite JSONs or editing the vanilla furnace code?
  13. Thank you! I had actually tried registering the serializer with RecipeSerializers.register but it crashed and I assumed that would not work. Apperantly I just called register at the wrong place. Now it works!
  14. I see, so it is a bug. I have some crafting recipes that need NBT manipulation. One of them works very similar to the vanilla book copying (that uses a custom IRecipe) and I found a lot of forum threads from 1.12 where people recommend registering IRecipes, so I emulated the vanilla code and tried registering it only to be disappointed that it doesn't work in 1.13 either. Before 1.13 I used item damage to hold some state that can be used in JSON recipes with the "data" attribute and did the rest of processing in crafting events, but it felt hacky to me. Now the data attribute doesn't work anyway. I don't see any reason why Forge wouldn't allow registering IRecipe's just like vanilla does. I assumed they just forgot to add it yet.
  15. The craftMatrix field of PlayerEvent.ItemCraftedEvent used to be public, but now it seems to be converted to private, and there is a getInventory() method that returns it instead. However, the IInventory you get by calling PlayerEvent.ItemCraftedEvent.getInventory() is not actually the craftMatrix. It returns a size 1 inventory with only air, instead of a size 9 inventory filled with ingredients. Is this a bug on Forge's end or am I doing something wrong? Also IRecipe's became unregisterable without any explanation, so I hope at least one of these problems are fixed so that we can have some way to get non-trivial craftings working.
  16. I managed to solve the problem. Apparently the TileEntity::shouldRefresh() method which returns true if the blockstate is changed, causes the TileEntity to be deleted and recreated. So, whenever I added/removed an item to/from a slot I would change the blockstate to reflect it on the texture, which would cause it to delete the whole inventory. Now I override the method to return false in any case and it works correctly (maybe I should check if the block is completely changed, not sure). Thanks to anyone who tried to help.
  17. Do you have any idea where I should be checking? My first instinct was to put breakpoints in readFromNBT() and writeToNBT() methods, but after comparing with vanilla TileEntityChest, they seem to be called normally (write gets called when I press ESC or sometimes randomly and read gets called once in the beginning) but the data that is written is usually of an empty inventory. It is the data that comes from ItemStackHandler::serializeNBT(). So I don't think it has to do with NBT. But I don't know what it has to do with. So, I don't even know where to step thtough with the debugger ?. Also I don't know what should be happening in the normal case and I don't have a good reference to compare to because the vanilla chest code doesn't use Forge's capability system. Could it be related to server-client communication? I read that it is supposed to be happening in the Container class somewhere, but I don't know where it should be or how it works, and none of the examples use any explicit code for communication either.
  18. Yes. It was in the old version, too (1.9). public class XercaGuiHandler implements IGuiHandler { // Gets the server side element for the given gui id- this should return a container @Override public Object getServerGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) { if (ID == GuiFunctionalBookcase.GUI_ID){ TileEntity tileEntity = world.getTileEntity(new BlockPos(x, y, z)); if (tileEntity instanceof TileEntityFunctionalBookcase) { return new ContainerFunctionalBookcase(player.inventory, (TileEntityFunctionalBookcase) tileEntity); } } ... } // Gets the client side element for the given gui id- this should return a gui @Override public Object getClientGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) { if (ID == GuiFunctionalBookcase.GUI_ID){ TileEntity tileEntity = world.getTileEntity(new BlockPos(x, y, z)); if (tileEntity instanceof TileEntityFunctionalBookcase) { return new GuiFunctionalBookcase(player.inventory, (ContainerFunctionalBookcase) getServerGuiElement(ID, player, world, x, y, z)); } } ... } } public class CommonProxy { ... public void preInit() { ... NetworkRegistry.INSTANCE.registerGuiHandler(XercaMod.instance, new XercaGuiHandler()); ... } ... }
  19. Hello, I am trying to update my mod from 1.9 to 1.12.2, and although I encountered a lot of problems, I was able to solve most of them, except for this one. I read a thousand forum threads, tutorials and repositories like this but I just can't seem to fix it. I have a block with a tile entity that has an inventory, similar to a chest. It only allows certain items to be stored, and changes texture depending on the number of item slots filled inside. The problem is as such: * When I right click the block, gui opens as expected * When I try to put an item in one of the slots, it works as expected (the itemstack is moved in the slot, and only certain item types are allowed) * When I close the gui, I can see that the texture of the block has updated according to the amount of itemstacks put in it as expected. * When I open it back, the item(s) put beforehand are not there anymore. But this is only most of the time. Sometimes the item(s) will remain, but if I put something else, they are gone next time. * After I close the gui, I can see that the texture also reverted to the zero item texture. I updated everything about it that I can. I learned about the IItemHandler stuff and converted all my old IInventory based code into the new system. I used the new registry function for the tile entity and put the function call in the block registry event handler. I stopped extending BlockContainer, etc, etc. I also added an excessive amount of TileEntity::markDirty() calls to make sure that wasn't the problem (it isn't). Here are the relevant files: public class TileEntityFunctionalBookcase extends TileEntity { private final static int NUMBER_OF_SLOTS = 6; private final ItemStackHandler inventory; public TileEntityFunctionalBookcase(){ // Create and initialize the items variable that will store store the items inventory = new ItemStackHandler(NUMBER_OF_SLOTS){ protected void onContentsChanged(int slot) { markDirty(); } }; } public int getSizeInventory() { return NUMBER_OF_SLOTS; } // Return true if the given player is able to use this block. In this case it checks that // 1) the world tileentity hasn't been replaced in the meantime, and // 2) the player isn't too far away from the centre of the block public boolean isUsableByPlayer(EntityPlayer player) { if (this.world.getTileEntity(this.pos) != this) return false; final double X_CENTRE_OFFSET = 0.5; final double Y_CENTRE_OFFSET = 0.5; final double Z_CENTRE_OFFSET = 0.5; final double MAXIMUM_DISTANCE_SQ = 8.0 * 8.0; return player.getDistanceSq(pos.getX() + X_CENTRE_OFFSET, pos.getY() + Y_CENTRE_OFFSET, pos.getZ() + Z_CENTRE_OFFSET) < MAXIMUM_DISTANCE_SQ; } @Override public boolean hasCapability(@Nonnull Capability<?> capability, @Nullable net.minecraft.util.EnumFacing facing){ return capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY || super.hasCapability(capability, facing); } @Override @Nullable public <T> T getCapability(@Nonnull Capability<T> capability, @Nullable net.minecraft.util.EnumFacing facing) { if (capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) { return CapabilityItemHandler.ITEM_HANDLER_CAPABILITY.cast(inventory); } return super.getCapability(capability, facing); } @Nonnull @Override public NBTTagCompound writeToNBT(NBTTagCompound parentNBTTagCompound) { super.writeToNBT(parentNBTTagCompound); // The super call is required to save and load the tileEntity's location NBTTagCompound inventoryTagCompound = this.inventory.serializeNBT(); parentNBTTagCompound.setTag("inventory", inventoryTagCompound); System.out.println("Write to NBT"); System.out.println(inventoryTagCompound); return parentNBTTagCompound; } @Override public void readFromNBT(NBTTagCompound parentNBTTagCompound) { super.readFromNBT(parentNBTTagCompound); // The super call is required to save and load the tiles location NBTTagCompound inventoryTagCompound = parentNBTTagCompound.getCompoundTag("inventory"); this.inventory.deserializeNBT(inventoryTagCompound); System.out.println("Read from NBT"); System.out.println(inventoryTagCompound); } public void closeInventory(EntityPlayer player) { int i = getBookAmount(); IBlockState st = XercaBlocks.blockBookcase.getDefaultState().withProperty(BlockFunctionalBookcase.BOOK_AMOUNT, i); this.world.setBlockState(this.pos, st); this.markDirty(); } @Override public boolean shouldRefresh(World world, BlockPos pos, @Nonnull IBlockState oldState, @Nonnull IBlockState newSate) { return oldState != newSate; } private int getBookAmount(){ int total = 0; for(int i=0; i<this.inventory.getSlots(); i++){ if(!this.inventory.getStackInSlot(i).isEmpty()){ total++; } } return total; } @Override public void markDirty() { super.markDirty(); // System.out.println("Marked dirty"); } } public class BlockFunctionalBookcase extends Block { public static final PropertyInteger BOOK_AMOUNT = PropertyInteger.create("books", 0, 6); public BlockFunctionalBookcase() { super(Material.WOOD); this.setDefaultState(this.blockState.getBaseState().withProperty(BOOK_AMOUNT, 0)); this.setRegistryName("block_bookcase"); this.setUnlocalizedName("block_bookcase"); this.setCreativeTab(CreativeTabs.DECORATIONS); } @Override public boolean hasTileEntity(final IBlockState state) { return true; } @Override public TileEntity createTileEntity(@Nonnull World world, @Nonnull IBlockState state){ return new TileEntityFunctionalBookcase(); } // Called when the block is right clicked // In this block it is used to open the blocks gui when right clicked by a player @Override public boolean onBlockActivated(World worldIn, BlockPos pos, IBlockState state, EntityPlayer playerIn, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ) { if (worldIn.isRemote) return true; playerIn.openGui(XercaMod.instance, GuiFunctionalBookcase.GUI_ID, worldIn, pos.getX(), pos.getY(), pos.getZ()); return true; } // This is where you can do something when the block is broken. In this case drop the inventory's contents @Override public void breakBlock(World worldIn, BlockPos pos, IBlockState state) { TileEntity tent = worldIn.getTileEntity(pos); if(tent.hasCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null)){ IItemHandler inventory = tent.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null); if (inventory != null){ // For each slot in the inventory for (int i = 0; i < inventory.getSlots(); i++){ // If the slot is not empty if (!inventory.getStackInSlot(i).isEmpty()) { // Create a new entity item with the item stack in the slot EntityItem item = new EntityItem(worldIn, pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5, inventory.getStackInSlot(i)); // Apply some random motion to the item float multiplier = 0.1f; float motionX = worldIn.rand.nextFloat() - 0.5f; float motionY = worldIn.rand.nextFloat() - 0.5f; float motionZ = worldIn.rand.nextFloat() - 0.5f; item.motionX = motionX * multiplier; item.motionY = motionY * multiplier; item.motionZ = motionZ * multiplier; // Spawn the item in the world worldIn.spawnEntity(item); } } } } // Super MUST be called last because it removes the tile entity super.breakBlock(worldIn, pos, state); } //--------------------------------------------------------- @Override public IBlockState getStateFromMeta(int meta) { return this.getDefaultState().withProperty(BOOK_AMOUNT, meta); } @Override public int getMetaFromState(IBlockState state) { return state.getValue(BOOK_AMOUNT); } protected BlockStateContainer createBlockState() { return new BlockStateContainer(this, BOOK_AMOUNT); } @Override public EnumBlockRenderType getRenderType(IBlockState state) { return EnumBlockRenderType.MODEL; } } public class ContainerFunctionalBookcase extends Container { private final TileEntityFunctionalBookcase tileEntityInventoryBookcase; public ContainerFunctionalBookcase(InventoryPlayer invPlayer, TileEntityFunctionalBookcase tileEntityInventoryBookcase) { this.tileEntityInventoryBookcase = tileEntityInventoryBookcase; IItemHandler inventory = tileEntityInventoryBookcase.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null); final int SLOT_X_SPACING = 18; final int SLOT_Y_SPACING = 18; final int HOTBAR_XPOS = 8; final int HOTBAR_YPOS = 142; // Add the players hotbar to the gui - the [xpos, ypos] location of each item int HOTBAR_SLOT_COUNT = 9; for (int x = 0; x < HOTBAR_SLOT_COUNT; x++) { addSlotToContainer(new Slot(invPlayer, x, HOTBAR_XPOS + SLOT_X_SPACING * x, HOTBAR_YPOS)); } final int PLAYER_INVENTORY_XPOS = 8; final int PLAYER_INVENTORY_YPOS = 84; // Add the rest of the players inventory to the gui int PLAYER_INVENTORY_ROW_COUNT = 3; for (int y = 0; y < PLAYER_INVENTORY_ROW_COUNT; y++) { int PLAYER_INVENTORY_COLUMN_COUNT = 9; for (int x = 0; x < PLAYER_INVENTORY_COLUMN_COUNT; x++) { int slotNumber = HOTBAR_SLOT_COUNT + y * PLAYER_INVENTORY_COLUMN_COUNT + x; int xpos = PLAYER_INVENTORY_XPOS + x * SLOT_X_SPACING; int ypos = PLAYER_INVENTORY_YPOS + y * SLOT_Y_SPACING; addSlotToContainer(new Slot(invPlayer, slotNumber, xpos, ypos)); } } int TE_INVENTORY_SLOT_COUNT = 6; if (TE_INVENTORY_SLOT_COUNT != tileEntityInventoryBookcase.getSizeInventory()) { System.err.println("Mismatched slot count in ContainerFunctionalBookcase(" + TE_INVENTORY_SLOT_COUNT + ") and TileEntityFunctionalBookcase (" + tileEntityInventoryBookcase.getSizeInventory()+")"); } final int TILE_INVENTORY_XPOS = 61; final int TILE_INVENTORY_YPOS = 17; final int TILE_SLOT_Y_SPACING = 32; final int TILE_ROW_COUNT = 2; final int TILE_COLUMN_COUNT = 3; // Add the tile inventory container to the gui for (int y = 0; y < TILE_ROW_COUNT; y++) { for (int x = 0; x < TILE_COLUMN_COUNT; x++) { int slotNumber = y * TILE_COLUMN_COUNT + x; int xpos = TILE_INVENTORY_XPOS + x * SLOT_X_SPACING; int ypos = TILE_INVENTORY_YPOS + y * TILE_SLOT_Y_SPACING; addSlotToContainer(new SlotBook(inventory, slotNumber, xpos, ypos)); } } } @Override public boolean canInteractWith(@Nonnull EntityPlayer player) { return tileEntityInventoryBookcase.isUsableByPlayer(player); } @Nonnull @Override public ItemStack transferStackInSlot(EntityPlayer player, int sourceSlotIndex) { ItemStack itemstack = ItemStack.EMPTY; Slot slot = inventorySlots.get(sourceSlotIndex); if (slot != null && slot.getHasStack()) { ItemStack itemstack1 = slot.getStack(); itemstack = itemstack1.copy(); int containerSlots = inventorySlots.size() - player.inventory.mainInventory.size(); if (sourceSlotIndex < containerSlots) { if (!this.mergeItemStack(itemstack1, containerSlots, inventorySlots.size(), true)) { return ItemStack.EMPTY; } } else if (!this.mergeItemStack(itemstack1, 0, containerSlots, false)) { return ItemStack.EMPTY; } if (itemstack1.getCount() == 0) { slot.putStack(ItemStack.EMPTY); } else { slot.onSlotChanged(); } if (itemstack1.getCount() == itemstack.getCount()) { return ItemStack.EMPTY; } slot.onTake(player, itemstack1); } return itemstack; } @Override public void onContainerClosed(EntityPlayer playerIn) { super.onContainerClosed(playerIn); this.tileEntityInventoryBookcase.closeInventory(playerIn); } class SlotBook extends SlotItemHandler { SlotBook(IItemHandler itemHandler, int index, int xPosition, int yPosition) { super(itemHandler, index, xPosition, yPosition); } // if this function returns false, the player won't be able to insert the given item into this slot @Override public boolean isItemValid(@Nonnull ItemStack stack) { Item it = stack.getItem(); return it == Items.BOOK || it == Items.WRITABLE_BOOK || it == Items.WRITTEN_BOOK || it == Items.ENCHANTED_BOOK; } @Override public void onSlotChanged() { tileEntityInventoryBookcase.markDirty(); } } } @SideOnly(Side.CLIENT) public class GuiFunctionalBookcase extends GuiContainer { public static final int GUI_ID = 30; private InventoryPlayer playerInv; private static final ResourceLocation texture = new ResourceLocation(XercaMod.MODID, "textures/gui/bookcase.png"); public GuiFunctionalBookcase(InventoryPlayer invPlayer, ContainerFunctionalBookcase container) { super(container); playerInv = invPlayer; // Set the width and height of the gui. Should match the size of the texture! xSize = 176; ySize = 166; } @Override protected void drawGuiContainerBackgroundLayer(float partialTicks, int x, int y) { // Bind the image texture of our custom container Minecraft.getMinecraft().getTextureManager().bindTexture(texture); // Draw the image GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); drawTexturedModalRect(guiLeft, guiTop, 0, 0, xSize, ySize); } @Override protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) { final int LABEL_XPOS = 5; final int LABEL_YPOS = 5; //fontRendererObj.drawString(tileEntityInventoryBookcase.getDisplayName().getUnformattedText(), LABEL_XPOS, LABEL_YPOS, Color.darkGray.getRGB()); } } public class XercaBlocks { public static Block blockBookcase; ... @Mod.EventBusSubscriber(modid = XercaMod.MODID) public static class RegistrationHandler { @SubscribeEvent public static void registerBlocks(final RegistryEvent.Register<Block> event) { event.getRegistry().registerAll(blockBookcase, ...(other blocks)); GameRegistry.registerTileEntity(TileEntityFunctionalBookcase.class, new ResourceLocation(XercaMod.MODID, "tile_functional_bookcase")); } ... } } If anyone can help, I will really appreciate it. There is probably a stupid mistake somewhere that I just can't see, but it has been a few days already and I still can't solve this! Thanks in advance.
  20. Thanks, guys. I learned the very basic things and started remaking the mod starting from the easy parts. And noticed we had waay too many foods, it's taking so long to make model json files and put textures at the right place, edit lang file, etc. and everything with the right name for each of them. Maybe I should have automated this from the begining in some way... I thought maybe I should just leave it but your post gave me a feeling that I can do it, so I'm doing it. We already started playing the latest version (vanilla) in a new world by purchasing a realm. After the realm's time ends, we will upload it to some other host (hopefully with the mod) and continue. I just couldn't handle the sheer amount of errors when I paste the whole code, so I'm copying and fixing it (and writing some of them from scratch) piece by piece. Also it would be pretty bad not to be able to compile it until I remove all the errors, lol. I learned about the json model and texture stuff, seemed a bit laboury at first but now I like the new system. I love how I can change how an item renders just by changing a text file. I didn't touch the blockstates yet, though. It scares me a bit, heard all the metadata is gone out the window now. I do believe in google, but sometimes it just returns so many outdated or irrelevant results. Maybe I'm just bad at searching. Definitely better than the forum's search though, that's right. For some reason all forums have a shitty search function. I usually try to solve problems by reading the code but some of the code is always spagetthi like field_328 p_432432890_3_ without any doc. And sometimes the difference is too subtle to notice, like I pasted the old crafting recipes and everything that has a vanilla item in it referenced like "Item.stick" gives an error. So I check google and find a 1.8 guide that shows it the same way like me, so I say it should have been changed in 1.9 and no one wrote anything about it and tried using "Item.getByNameOrId("minecraft:stick")" until I realize that the 1.8 guide used "Items" instead of "Item". Dammit. Thank you for the long answer.
  21. Learning the unchanged parts from different versions is a good idea. So I can use the old tutorials for most things. I did find tuts but they were all for old versions so I didn't want to waste effort on upgrading old code into less old code. Thanks for the tips.
  22. Hello fellow modders. I used to run a server with my friends and had a custom mod along with it. It had a shit load of items with different uses, blocks, projectiles, particles, all kinds of random stuff. Now we are playing again and I thought of updating the mod to the current version, however the last surviving source of the mod is from 1.4.6. I installed Forge and when I copied the old source (expectedly) literally every single class were filled with errors. I thought maybe I should make it from scratch, but I can't seem to find any comprehensive documentation or tutorial on currently what works how in Forge. I figure this is normal because it hasn't been very long since 1.9 came (and I think there still is not a stable 1.9 Forge version). There are a few tutorials but they are from 1.8.9, which also apperantly has some differences, so I don't want to waste time on learning that. So, my question to you is, what is the best thing to do: Wait until a comprehensive documentation is written, try to figure things out by myself, or just give up I don't know if there ever will be a good doc, because I don't know how things work around here. I'm talking about one that explains what each function that Forge provides does, how/where to use each function/construct/feature/etc. Or at least a tutorial series that explain basic things clearly like creating and registering items, blocks, rendering things, how the resources work (my old version has a spritesheet), etc. If these will be written at some point, how long do you think that would take? Trying to do it by myself seems pretty hard since my java knowledge is quite rusty and the game code looks a lot different than what I remember. Also, if it turns out to be too time/effort consuming I am inclined to just give up, as it isn't that important anyways. Would it be somehow easier to update it incrementally instead of making it from scratch? For example using guides like "Updating from 1.x to 1.(x+1)" one by one. That seems like a crappy idea.
  23. You are welcome, I'm really glad it is helping others.
  24. Hi. After getting no help from the forums, I returned to look deeper for it myself and finally got it to work. Although I am not completely sure of this solution, it works and also makes sense. So, I am explaining it here to help other people with the same problem like F3RULLO14. First of all, change the place of your sound files from wherever they are to "assets/mod_name/sound" (you need to create that folder). If they are records, I think they should go into "assets/mod_name/records" but I haven't tested this. Think of the sounds as another asset just like textures. Then, turn your old code into this: event.manager.addSound("mod_name:sound1.ogg"); (put "addStreaming" instead of "addSound" for a record) The only string parameter inside is supposed to be just like an icon/texture file. Minecraft automatically adds the "sound" directory part, so don't write that. After this is done, your sound should be registered. Playing it is done like this: WorldObject.playSoundAtEntity(EntityPlayerObject, "mod_name:sound1", 1.0F, 1.0F); "playSoundAtEntity" part is just the same example I used in the first post and presumably any other sound playing function should work the same. The important part is "mod_name:sound1". As expected, this also looks like using an icon for an item or a block. Don't use extensions here (.ogg, .wav, ...). I hope this helps.
  25. Hello. I used to use custom sounds and music in my mod but after the 1.6.x update, I can't make it work anymore. I have a class which looks like this: public class ModName_EventSounds { @ForgeSubscribe public void onSound(SoundLoadEvent event) { try { event.manager.soundPoolSounds.addSound("x/sound1.ogg", mod_ModName.class.getResource("/x/sound1.ogg")); event.manager.soundPoolSounds.addSound("x/sound2.ogg", mod_ModName.class.getResource("/x/sound2.ogg")); . . . } catch (Exception e) { System.err.println(error); } } } Then, somewhere else, I have codes like this for playing the sounds: worldObject.playSoundAtEntity(EntityPlayerObject, "x.sound1", 1.0F, 1.0F); I also have this code in the client proxy for registration: @Override public void registerSound() { MinecraftForge.EVENT_BUS.register(new ModName_EventSounds()); } It used to work well but now apperently some changes has been done and the "event.manager.soundPoolSounds.addSound" method only takes one string as a parameter. I couldn't find out how this new one is supposed to work, so I ask for your help. Thanks in advance.
×
×
  • Create New...

Important Information

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