Jump to content

AntonBespoiasov

Members
  • Posts

    41
  • Joined

  • Last visited

Posts 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:

    Quote

    C:\Users\AntonBespoiasov\AppData\Roaming\.minecraft J\localserver\1.14.4_forge>java -server -Xms512M -Xmx1024M -jar forge-1.14.4-28.0.17.jar
    2021-01-10 16:58:29,851 main WARN Disabling terminal, you're running in an unsupported environment.
    [16:58:30.093] [main/INFO] [cp.mo.mo.Launcher/MODLAUNCHER]: ModLauncher running: args [--gameDir, ., --launchTarget, fmlserver, --fml.forgeVersion, 28.0.17, --fml.mcpVersion, 20190719.225934, --fml.mcVersion, 1.14.4, --fml.forgeGroup, net.minecraftforge]
    [16:58:30.099] [main/INFO] [cp.mo.mo.Launcher/MODLAUNCHER]: ModLauncher 3.0.2+57+a2bc918 starting: java version 11.0.8 by AdoptOpenJDK
    [16:58:31.066] [main/INFO] [ne.mi.fm.lo.FixSSL/CORE]: Added Lets Encrypt root certificates as additional trust
    [16:58:31.691] [main/INFO] [STDERR/]: [jdk.nashorn.api.scripting.NashornScriptEngine:<init>:143]: Warning: Nashorn engine is planned to be removed from a future JDK release
    [16:58:32.584] [main/INFO] [cp.mo.mo.LaunchServiceHandler/MODLAUNCHER]: Launching target 'fmlserver' with arguments [--gameDir, .]
    Exception in thread "main" [16:58:32.827] [main/INFO] [STDERR/]: [java.lang.ThreadGroup:uncaughtException:1050]: java.lang.RuntimeException: java.lang.UnsupportedOperationException
    [16:58:32.828] [main/INFO] [STDERR/]: [java.lang.ThreadGroup:uncaughtException:1050]:   at cpw.mods.modlauncher.LaunchServiceHandlerDecorator.launch(LaunchServiceHandlerDecorator.java:39)
    [16:58:32.830] [main/INFO] [STDERR/]: [java.lang.ThreadGroup:uncaughtException:1050]:   at cpw.mods.modlauncher.LaunchServiceHandler.launch(LaunchServiceHandler.java:50)
    [16:58:32.834] [main/INFO] [STDERR/]: [java.lang.ThreadGroup:uncaughtException:1050]:   at cpw.mods.modlauncher.LaunchServiceHandler.launch(LaunchServiceHandler.java:68)
    [16:58:32.836] [main/INFO] [STDERR/]: [java.lang.ThreadGroup:uncaughtException:1050]:   at cpw.mods.modlauncher.Launcher.run(Launcher.java:80)
    [16:58:32.844] [main/INFO] [STDERR/]: [java.lang.ThreadGroup:uncaughtException:1050]:   at cpw.mods.modlauncher.Launcher.main(Launcher.java:65)
    [16:58:32.847] [main/INFO] [STDERR/]: [java.lang.ThreadGroup:uncaughtException:1050]:   at net.minecraftforge.server.ServerMain$Runner.runLauncher(ServerMain.java:63)
    [16:58:32.851] [main/INFO] [STDERR/]: [java.lang.ThreadGroup:uncaughtException:1050]:   at net.minecraftforge.server.ServerMain$Runner.access$100(ServerMain.java:60)
    [16:58:32.856] [main/INFO] [STDERR/]: [java.lang.ThreadGroup:uncaughtException:1050]:   at net.minecraftforge.server.ServerMain.main(ServerMain.java:57)
    [16:58:32.870] [main/INFO] [STDERR/]: [java.lang.ThreadGroup:uncaughtException:1059]: Caused by: java.lang.UnsupportedOperationException
    [16:58:32.874] [main/INFO] [STDERR/]: [java.lang.ThreadGroup:uncaughtException:1059]:   at org.objectweb.asm.ClassVisitor.visitNestMemberExperimental(ClassVisitor.java:248)
    [16:58:32.887] [main/INFO] [STDERR/]: [java.lang.ThreadGroup:uncaughtException:1059]:   at org.objectweb.asm.ClassReader.accept(ClassReader.java:651)
    [16:58:32.891] [main/INFO] [STDERR/]: [java.lang.ThreadGroup:uncaughtException:1059]:   at org.objectweb.asm.ClassReader.accept(ClassReader.java:391)
    [16:58:32.898] [main/INFO] [STDERR/]: [java.lang.ThreadGroup:uncaughtException:1059]:   at cpw.mods.modlauncher.TransformerClassWriter.computeHierarchy(TransformerClassWriter.java:83)
    [16:58:32.903] [main/INFO] [STDERR/]: [java.lang.ThreadGroup:uncaughtException:1059]:   at cpw.mods.modlauncher.TransformerClassWriter.access$100(TransformerClassWriter.java:35)

     

  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. 1 hour ago, TheGreyGhost said:

    If you describe your multiblock structure in more detail (i.e. in gameplay terms - from the point of view of someone playing the game, not from the point of view of what you think the code should look like) then we could make some more concrete suggestions...

    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:

    1. 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.
    2. 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.
    3. I will use TER to render entire multiblock like in previous solution but using TER instead of implementation of IBakedModel
    4. 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:

    f.png.299ad470028c002f89e5d680567e6096.png

    net.minecraft.block.Block:

    sf.png.3781b25dcfdd067c8ac99c57568ae5a2.png

    And my favorite one that turns rendering into hell and where all method and field names are wrong - com.mojang.blaze3d.platform.GLStateManager: 

    gh.png.dc7a35c887c6c6ab0ba4927c9e012a68.png

    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. 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.

  9. 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.

  10. 15 minutes ago, Draco18s said:

    Override getRemainingItems.

    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.

  11. 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.

  12. /** 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

     

  13. 2 hours ago, DavidM said:

    Damaging the Entity (and all Entity related operations in general) must be done on the server side, yet your code is executing on the client (indicated by the usage of Minecraft class).

    You would need to send a packet to the server to inform it about the action, then damage the Entity on the server.

    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?

  14. 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?

  15. 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.

  16. 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).

  17. On ‎11‎/‎6‎/‎2019 at 11:32 AM, diesieben07 said:

    You need to store whatever data you need in the ItemStack. Either through raw NBT (ItemStack#getTag and friends, make sure to include your ModID in your keys to avoid conflicts) or using a capability.

    Then you can override IForgeItem#getAttributeModifiers(EquipmentSlotType, ItemStack), get the data from the stack and return the appropraite modifiers. To then change the modifiers, you just have to change the data in the ItemStack.

     

    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.