Jump to content

Triphion

Members
  • Posts

    122
  • Joined

  • Last visited

Posts posted by Triphion

  1. 17 minutes ago, diesieben07 said:

    ItemPickupEvent fires after the stack has already been picked up, you cannot modify it anymore.

    You can use EntityItemPickupEvent, which fires before the stack has been added to the player's inventory and thus you can modify the stack. Note however that if the item is stackable, only parts may be picked up. And also note that EntityItemPickupEvent fires even if the item doesn't actually fit in the player's inventory. Check ItemEntity#playerTouch for details of how this works.

    That seems to have done the trick! Thanks!

  2. 3 minutes ago, diesieben07 said:

    Where do you set the stack as active?

    In ItemPickupEvent.

        @SubscribeEvent
        public static void onItemPickup(PlayerEvent.ItemPickupEvent event){
            if (event.getPlayer() instanceof ServerPlayerEntity){
                if (event.getStack().getItem().getItem() == TnwItems.WISP_BOTTLE.get()){
                    ServerPlayerEntity serverPlayer = (ServerPlayerEntity) event.getPlayer();
                    WispBottleItem item = (WispBottleItem) event.getStack().getItem();
    
                    boolean flag = false;
    
                    Iterator<ItemStack> iterator = WispBottleItem.getWispsOnPlayer(serverPlayer).iterator();
    
                    for (Iterator<ItemStack> it = iterator; it.hasNext(); ) {
                        ItemStack stack = it.next();
    
                        if (((WispBottleItem)stack.getItem()).GetIsActiveStack(stack)){
                            flag = true;
                        }
                    }
    
                    if (!flag){
                        item.SetIsActiveStack(event.getStack(), true);
                        LogManager.getLogger().info("Picked up!" + item.GetIsActiveStack(event.getStack()));
                    }
                }
            }
        }

    The logger at the end always reports as true since the value never saves.

  3. 5 minutes ago, diesieben07 said:

    Why is your ModID "tnw"? That is way too short, it should be something unique. Do not use abbrevations.

    The ModID is not permanent in this scenario. I don't yet have a good name for the mod, so tnw is just temporary. 

        @Override
        public void inventoryTick(ItemStack itemStack, World world, Entity entity, int p_77663_4_, boolean p_77663_5_)
        {
            super.inventoryTick(itemStack, world, entity, p_77663_4_, p_77663_5_);
    
            if (entity instanceof ServerPlayerEntity)
            {
                LogManager.getLogger().info(GetIsActiveStack(itemStack));
                LogManager.getLogger().info(getNextPotionTime(itemStack));
    
                if (GetIsActiveStack(itemStack)){
                    ServerPlayerEntity serverPlayer = (ServerPlayerEntity) entity;
    
                    if (hasTimeBeenReached(itemStack))
                    {
                        setNextPotionTime(itemStack, (int) (world.getGameTime() + deterInterval + random.nextInt(50)));
                        int deterValue = random.nextInt(5) + 1;
    
                        addPositivePotionEffect(positiveEffects, serverPlayer);
    
                        itemStack.hurt(deterValue, random, serverPlayer);
    
                        if (itemStack.getMaxDamage() - itemStack.getDamageValue() <= 0){
                            SetIsActiveStack(itemStack, false);
    
                            SetNewActiveStack(itemStack, serverPlayer);
                        }
                    }
                }
            }
        }
        private boolean hasTimeBeenReached(ItemStack itemStack){
            if (itemStack.getEntityRepresentation().level.getGameTime() >= getNextPotionTime(itemStack)){
                LogManager.getLogger().info(getNextPotionTime(itemStack));
                return true;
            }
            return false;
        }

     

  4. 9 minutes ago, diesieben07 said:

    Yes, except you need to realize that the ItemStack tag is global ground. You should store your data either prefixed with your ModID or store it in a sub-compound named after your ModID.

    So, like this?

        public boolean GetIsActiveStack(ItemStack itemStack)
        {
            CompoundNBT nbt = itemStack.getTag();
            if (nbt == null){
                SetIsActiveStack(itemStack, false);
            }
    
            return nbt.getBoolean("tnw.active");
        }
    
        public void SetIsActiveStack(ItemStack itemStack, boolean active){
            CompoundNBT nbt = itemStack.getOrCreateTag();
            nbt.putBoolean("tnw.active", active);
            itemStack.setTag(nbt);
        }

    I log this every tick, only for testing this specific occurence, this will be removed promptly after I have this working. 

                LogManager.getLogger().info(GetIsActiveStack(itemStack));
                LogManager.getLogger().info(getNextPotionTime(itemStack));

    They both log false and 0 respectively.

  5. 3 hours ago, diesieben07 said:

    You cannot store data in your Item class like that. There is only one instance of your item class, as such you cannot store stack-specific data as instance fields.

    Ah, right. So like this?

        public boolean GetIsActiveStack(ItemStack itemStack)
        {
            CompoundNBT nbt = itemStack.getTag();
            if (nbt == null){
                SetIsActiveStack(itemStack, false);
            }
    
            return nbt.getBoolean("active");
        }
    
        public void SetIsActiveStack(ItemStack itemStack, boolean active){
            CompoundNBT nbt = itemStack.getOrCreateTag();
            nbt.putBoolean("active", active);
            itemStack.setTag(nbt);
        }

     

    3 hours ago, diesieben07 said:

    Additionally you should really avoid modifying the stack NBT every single tick. Instead of counting down a value in the stack, you can store a target "game time" (World#getGameTime) and then check if it has been reached. This was you do not need to modify the NBT.

    Ahh, that is a very solid suggestion!

        private int getNextPotionTime(ItemStack itemStack){
            CompoundNBT nbt = itemStack.getTag();
            if (nbt == null){
                setNextPotionTime(itemStack, (int) itemStack.getEntityRepresentation().level.getGameTime() + deterInterval + random.nextInt(50));
            }
    
            return nbt.getInt("time");
        }
    
        private void setNextPotionTime(ItemStack itemStack, int time){
            CompoundNBT nbt = itemStack.getOrCreateTag();
            nbt.putInt("time", time);
            itemStack.setTag(nbt);
        }

    This still doesn't seem to work. Through my logging, all the values are as default and doesn't seem to get saved.

  6. I have created an item which ticks when it is in a player inventory. It has a timer that applies a potion effect to the player whenever a certain time has been exceeded. And so it loops. 

    This item has 2 important variables, a timer, as well as a boolean which is used to determine the item that should be ticking whenever a player has more than one instance in the inventory. I determine this value everytime a player drops or picks this item up.

    The problem now is that the data doesn't seem to be saving. Any help would be very much appreciated.

        @Override
        public void inventoryTick(ItemStack itemStack, World world, Entity entity, int p_77663_4_, boolean p_77663_5_)
        {
            super.inventoryTick(itemStack, world, entity, p_77663_4_, p_77663_5_);
    
            if (entity instanceof ServerPlayerEntity)
            {
                readItemStackInfo(itemStack);
    
                if (GetIsActiveStack(itemStack)){
                    ServerPlayerEntity serverPlayer = (ServerPlayerEntity) entity;
                    incrementCurrentTime(itemStack);
    
                    if (this.currentTime >= deterInterval + random.nextInt(50))
                    {
                        resetCurrentTime(itemStack);
                        int deterValue = random.nextInt(5) + 1;
    
                        addPositivePotionEffect(positiveEffects, serverPlayer);
    
                        itemStack.hurt(deterValue, random, serverPlayer);
    
                        if (itemStack.getMaxDamage() - itemStack.getDamageValue() <= 0){
                            SetIsActiveStack(itemStack, false);
    
                            SetNewActiveStack(itemStack, serverPlayer);
                        }
                    }
                }
            }
        }
        public boolean GetIsActiveStack(ItemStack itemStack)
        {
            readItemStackInfo(itemStack);
    
            return this.isActiveStack;
        }
    
        public void SetIsActiveStack(ItemStack itemStack, boolean active){
            this.isActiveStack = active;
            writeItemStackInfo(itemStack);
        }
    
        public void readItemStackInfo(ItemStack itemStack){
            CompoundNBT nbt = itemStack.getTag();
    
            if (nbt == null){
                writeItemStackInfo(itemStack);
            }
    
            this.isActiveStack = nbt.getBoolean("active");
        }
    
        public CompoundNBT writeItemStackInfo(ItemStack itemStack){
            CompoundNBT nbt = itemStack.getOrCreateTag();
            nbt.putBoolean("active", this.isActiveStack);
            itemStack.setTag(nbt);
    
            return nbt;
        }

     

  7. 1 hour ago, diesieben07 said:
    
    modifiableMap = LinkedHashMultimap.create(originalMap);
    // do your modifications on modifiableMap
    
    return modifiableMap;

     

    Thank you so much! With all my researching I didn't come across LinkedHash anywhere. I feel like Java is harder to find solutions and documentations on. C# has complete docs with references, examples and very detailed explanations and scenarios.

    Sidenote: Do you know if there are any good docs where I can read up a bit more on Java in general?

  8. 23 hours ago, diesieben07 said:

    Make a new Multimap from the existing one and mutate it.

    Alright, I've researched this since yesterday and I simply cannot figure this out. What do you mean by "mutate" it? What I was thinking was to create a copy of the old multimap, change a few values in there, and then replace the old one. But this doesn't work since i'm getting an unsupportedOperationException: null. Which is confusing since if I cannot remove and add values from the copy I made and replace the old ones, how am I supposed to change the values? 

  9. 11 minutes ago, diesieben07 said:

    The event is for changing the attributes of other items. If the Item is yours, simply override getAttributeModifiers in your Item class.

     

    getOriginalModifiers gives you the modifiers that are actually present on the stack (and that are produced by its Item). getModifiers are the modifiers after they have been modified by anyone using the event (using removeAttribute, removeModifier or addModifier).

    Oh, okay! But i'm still having a hard time understanding how i'm gonna modify the values. I had an old way of doing this, but this doesn't work anymore due to it being an immutable list now. 

    	@Override
    	public Multimap<Attribute, AttributeModifier> getAttributeModifiers(EquipmentSlotType slot, ItemStack stack)
    	{
    		final Multimap<Attribute, AttributeModifier> modifiers = super.getAttributeModifiers(slot, stack);
    
    		if (slot == EquipmentSlotType.MAINHAND && getBurning(stack) == true)
    		{
    			replaceModifier(modifiers, Attributes.ATTACK_DAMAGE, BASE_ATTACK_DAMAGE_UUID, 1.75D);
    			replaceModifier(modifiers, Attributes.ATTACK_SPEED, BASE_ATTACK_SPEED_UUID, 1.332D);
    		}
    		else if (slot == EquipmentSlotType.MAINHAND && getBurning(stack) == false)
    		{
    			replaceModifier(modifiers, Attributes.ATTACK_DAMAGE, BASE_ATTACK_DAMAGE_UUID, 1D);
    			replaceModifier(modifiers, Attributes.ATTACK_SPEED, BASE_ATTACK_SPEED_UUID, 1D);
    		}
    
    		return modifiers;
    	}
    
    	private void replaceModifier(Multimap<Attribute, AttributeModifier> modifierMultimap, Attribute attribute, UUID id, double multiplier)
    	{
    		// Get the modifiers for the specified attribute
    		final Collection<AttributeModifier> modifiers = modifierMultimap.get((attribute));
    
    		// Find the modifier with the specified ID, if any
    		final Optional<AttributeModifier> modifierOptional = modifiers.stream().filter(attributeModifier -> attributeModifier.getId().equals(id)).findFirst();
    
    		if (modifierOptional.isPresent()) { // If it exists,
    			final AttributeModifier modifier = modifierOptional.get();
    			modifiers.remove(modifier); // Remove it
    			modifiers.add(new AttributeModifier(modifier.getId(), modifier.getName(), modifier.getAmount() * multiplier, modifier.getOperation())); // Add the new modifier
    		}
    	}

    What would be the correct way to do this now? 

    Note: This may be due to my limited experience with Java, although I use C# very often and these languages are pretty similiar, this is still pretty hard lol.

  10. 18 minutes ago, diesieben07 said:

    ItemAttributeModifierEvent is not a mod bus event.

    Alright, thanks! I moved it into my general EventHandler and it seems to work fine now. As a sidenote, I seem to have a hard time understanding the new way of changing attributes. I had a way of changing attributes based on different modes on items. I have an event that fires every time a player presses a certain keybinding, and that works fine. But to add the attributes through the event after the maps got changed to immutable has been quite hard.

    	@SubscribeEvent
    	public static void updateItemAttributes(ItemAttributeModifierEvent event)
    	{
    		Utils.getLogger().info("ItemStackModifierEvent called!");
    
    		ItemStack itemStack = event.getItemStack();
    		Item item = itemStack.getItem();
    
    		if (item == EtauricItems.SCORCHER_BLADE.get())
    		{
    			if (((ScorcherBlade) item).getBurning(event.getItemStack()) == true)
    			{
    				event.addModifier(Attributes.ATTACK_DAMAGE, new AttributeModifier("damage", 4.0D, AttributeModifier.Operation.MULTIPLY_BASE));
    				event.addModifier(Attributes.ATTACK_SPEED, new AttributeModifier("speed", 4.0D, AttributeModifier.Operation.MULTIPLY_BASE));
    			}
    			else
    			{
    				event.addModifier(Attributes.ATTACK_DAMAGE, new AttributeModifier("damage", 1.0D, AttributeModifier.Operation.MULTIPLY_BASE));
    				event.addModifier(Attributes.ATTACK_SPEED, new AttributeModifier("speed", 1.0D, AttributeModifier.Operation.MULTIPLY_BASE));
    			}
    		}
    	}

    But this only continues to add attribute in every single way possible. From what i've read, the addModifier adds values if the modifier doesn't exist, and so I thought this would work. Something that also puzzled me is the two different attributeMultimaps methods, getOriginalModifiers() and getModifiers(). How do I make this work?

  11. I was trying to add the ItemAttributeModifierEvent so that I could change values depending on different circumstances. But I ran into a weird error which i've never seen before and I can't really make out what it means. Any help would be appreciated.

    This is my event handler and main class for reference.

    	public MainClass() 
    	{
    		instance = this;
    
    		final IEventBus modBus = FMLJavaModLoadingContext.get().getModEventBus();
    
    		modBus.addListener(this::commonSetup);
    		modBus.addListener(this::clientSetup);
    		modBus.addListener(this::onLoadComplete);
    		
    		EtauricBlocks.BLOCKS.register(modBus);
    		EtauricItems.ITEMS.register(modBus);
    		
    		EtauricEntities.ENTITIES.register(modBus);
    		
    		//EtauricBiomes.BIOMES.register(modBus);
    		
    		MinecraftForge.EVENT_BUS.register(this);
    	}
    	@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD)
    	private static class EventHandler
    	{
    		@SubscribeEvent
    		public static void registerItems(final RegistryEvent.Register<Item> event) 
    		{
    			final IForgeRegistry<Item> registry = event.getRegistry();
    			
    			EtauricBlocks.BLOCKS.getEntries().stream().map(RegistryObject::get).forEach(block -> {
    				final Item.Properties properties = new Item.Properties().tab(EtauricBlocks.getBlockGroup(block));
    				final BlockItem blockItem = new BlockItem(block, properties);
    				blockItem.setRegistryName(block.getRegistryName());
    				
    				if (!EtauricBlocks.ignoreBlocks().contains(block)) 
    				{
    					registry.register(blockItem);
    				}
    			});
    			
    			Utils.getLogger().info("All BlockItems successfully registered! ");
    		}
    		
    		@SubscribeEvent
    		public static void registerBiomes(final RegistryEvent.Register<Biome> event) 
    		{
    			//EtauricBiomes.registerBiomes();
    			
    			Utils.getLogger().info("Register Biomes. ");
    		}
    
    		@SubscribeEvent
    		public static void registerEntityAttributes(final EntityAttributeCreationEvent event)
    		{
    			event.put(EtauricEntities.CHUPNUT.get(), ChupnutEntity.createAttributes().build());
    			event.put(EtauricEntities.DEATH_BITER.get(), DeathBiterEntity.createAttributes().build());
    			event.put(EtauricEntities.OGRE.get(), OgreEntity.createAttibutes().build());
    			event.put(EtauricEntities.LUNAR_LUNATIC.get(), LunarLunaticEntity.createAttributes().build());
    			event.put(EtauricEntities.TARANTULA.get(), TarantulaEntity.createAttributes().build());
    			event.put(EtauricEntities.WRATHFUL_OGRE.get(), WrathfulOgreEntity.createAttributes().build());
    
    			event.put(EtauricEntities.BEAST_KING.get(), BeastKingEntity.createAttributes().build());
    			event.put(EtauricEntities.MOON_CRAWLER.get(), MoonCrawlerEntity.createAttributes().build());
    		}
    
    		@SubscribeEvent
    		public static void updateItemAttributes(ItemAttributeModifierEvent event)
    		{
    			Utils.getLogger().info("ItemStackModifierEvent called!");
    
    			ItemStack itemStack = event.getItemStack();
    			Item item = itemStack.getItem();
    
    			if (item == EtauricItems.SCORCHER_BLADE.get())
    			{
    				if (((ScorcherBlade) item).getBurning(event.getItemStack()) == true)
    				{
    					event.addModifier(Attributes.ATTACK_DAMAGE, new AttributeModifier("damage", 4.0D, AttributeModifier.Operation.MULTIPLY_BASE));
    					event.addModifier(Attributes.ATTACK_SPEED, new AttributeModifier("speed", 4.0D, AttributeModifier.Operation.MULTIPLY_BASE));
    				}
    				else
    				{
    					event.addModifier(Attributes.ATTACK_DAMAGE, new AttributeModifier("damage", 1.0D, AttributeModifier.Operation.MULTIPLY_BASE));
    					event.addModifier(Attributes.ATTACK_SPEED, new AttributeModifier("speed", 1.0D, AttributeModifier.Operation.MULTIPLY_BASE));
    				}
    			}
    		}

    My event handler is an internal class of the MainClass. I have another event handler for Client as well as another EventHandler that is not a static one. 

    Note: These are two different code snippets, but they for some reason became just one.

  12. Simple question, I started to update my 1.12 mod to 1.16.5 and a whole lot of functions and methods are renamed and reworked. One such function is the addPropertyOverride function. I looked through vanilla code for Bow and Elytra and the call function is not even there.

    What is the new way of doing propertyOverrides?

    		this.addPropertyOverride(new ResourceLocation(Reference.MODID + ":stalking"), new IItemPropertyGetter() 
    		{
    			@Override
    			public float call(ItemStack p_call_1_, World p_call_2_, LivingEntity p_call_3_) 
    			{
    				return stalking ? 1.0F : 0.0F;
    			}
    		});

    This was how I did it in the past.

  13. I've managed to add entities to the mod, but not with spawn eggs and natural spawns. To start off with, I don't know when to add the entity spawns. Secondly, I don't know if my current spawn code actually works since I haven't tried it, but if you see some problem with it, please point that out. And lastly, the spawn eggs. I know how to add a spawn egg, unfortunately, since i'm using deferred registries for the entities etc. the normal "Entitytype.MYENTITY" does not work, and neither does "Entitytype.MYENTITY.get()" nor "RegistryObject.of(Entitytype.MYENTITY.getId(), ForgeRegistries.ENTITIES)". So to fix this, i decided to pretty much copy the original spawnEggItem class, and change it so it can work with deferred registries. But, some problem has arisen there as well. Specifically, the coloring of the egg; it's always white and grey. 

     

     

     

    	public static void registerSpawns() 
    	{
    		spawnEntities(RegistryObject.of(EtauricEntities.CHUPNUT.getId(), ForgeRegistries.ENTITIES), 25, 1, 3, Biome.Category.FOREST);
    		spawnEntities(RegistryObject.of(EntityType.IRON_GOLEM.getRegistryName(), ForgeRegistries.ENTITIES), 25, 1, 3, Biome.Category.FOREST);
    	}
    	
    	private static void spawnEntities(RegistryObject<? extends EntityType<? extends LivingEntity>> entityType, int weightIn, int minGroupCountIn, int maxGroupCountIn, Biome.Category...biomes) 
    	{
    		Utils.getLogger().info("EntityType: " + entityType);
    		
    		for (int i = 0; i < biomes.length; i++)
    		{
    			for (Biome biome : ForgeRegistries.BIOMES)
    			{
    				if (biome.getCategory() == biomes[i])
    				{
    					biome.getSpawns(EntityClassification.MONSTER).add(new Biome.SpawnListEntry(entityType.get(), weightIn, minGroupCountIn, maxGroupCountIn));
    				}
    			}
    		}
    	}

    This is my entity spawn method. 

     

    public class EtauricSpawnEggItem extends Item
    {
    	private static final Map<RegistryObject<? extends EntityType<?>>, EtauricSpawnEggItem> EGGS = Maps.newIdentityHashMap();
    	private final int primaryColor;
    	private final int secondaryColor;
    	private final RegistryObject<? extends EntityType<?>> typeIn;
    	
    	public EtauricSpawnEggItem(RegistryObject<? extends EntityType<?>> typeIn, int primaryColorIn, int secondaryColorIn, Properties builder) 
    	{
    		super(builder);
    		this.typeIn = typeIn;
    		this.primaryColor = primaryColorIn;
    		this.secondaryColor = secondaryColorIn;
    		EGGS.put(typeIn, this);
    	}
    	
    	public ActionResultType onItemUse(ItemUseContext context) 
    	{
    		World world = context.getWorld();
    		if (world.isRemote) 
    		{
    			return ActionResultType.SUCCESS;
    		} 
    		else 
    		{
    			ItemStack itemstack = context.getItem();
    			BlockPos blockpos = context.getPos();
    			Direction direction = context.getFace();
    			BlockState blockstate = world.getBlockState(blockpos);
    			Block block = blockstate.getBlock();
    			if (block == Blocks.SPAWNER) 
    			{
    				TileEntity tileentity = world.getTileEntity(blockpos);
    				if (tileentity instanceof MobSpawnerTileEntity) 
    				{
    					AbstractSpawner abstractspawner = ((MobSpawnerTileEntity)tileentity).getSpawnerBaseLogic();
    					RegistryObject<? extends EntityType<?>> entitytype1 = this.getType(itemstack.getTag());
    					abstractspawner.setEntityType(entitytype1.get());
    					tileentity.markDirty();
    					world.notifyBlockUpdate(blockpos, blockstate, blockstate, 3);
    					itemstack.shrink(1);
    					return ActionResultType.SUCCESS;
    				}
    			}
    
    			BlockPos blockpos1;
    			if (blockstate.getCollisionShape(world, blockpos).isEmpty()) 
    			{
    				blockpos1 = blockpos;
    			} 
    			else 
    			{
    				blockpos1 = blockpos.offset(direction);
    		    }
    			RegistryObject<? extends EntityType<?>> entitytype = this.getType(itemstack.getTag());
    			if (entitytype.get().spawn(world, itemstack, context.getPlayer(), blockpos1, SpawnReason.SPAWN_EGG, true, !Objects.equals(blockpos, blockpos1) && direction == Direction.UP) != null) 
    			{
    				itemstack.shrink(1);
    		    }
    
    			return ActionResultType.SUCCESS;
    		}
    	}
    
    		   /**
    		    * Called to trigger the item's "innate" right click behavior. To handle when this item is used on a Block, see
    		    * {@link #onItemUse}.
    		    */
    	public ActionResult<ItemStack> onItemRightClick(World worldIn, PlayerEntity playerIn, Hand handIn) 
    	{
    		ItemStack itemstack = playerIn.getHeldItem(handIn);
    		RayTraceResult raytraceresult = rayTrace(worldIn, playerIn, RayTraceContext.FluidMode.SOURCE_ONLY);
    		if (raytraceresult.getType() != RayTraceResult.Type.BLOCK) 
    		{
    			return ActionResult.resultPass(itemstack);
    		} 
    		else if (worldIn.isRemote) 
    		{
    			return ActionResult.resultSuccess(itemstack);
    		} 
    		else 
    		{
    			BlockRayTraceResult blockraytraceresult = (BlockRayTraceResult)raytraceresult;
    			BlockPos blockpos = blockraytraceresult.getPos();
    			if (!(worldIn.getBlockState(blockpos).getBlock() instanceof FlowingFluidBlock)) 
    			{
    				return ActionResult.resultPass(itemstack);
    			} 
    			else if (worldIn.isBlockModifiable(playerIn, blockpos) && playerIn.canPlayerEdit(blockpos, blockraytraceresult.getFace(), itemstack)) 
    			{
    				RegistryObject<? extends EntityType<?>> entitytype = this.getType(itemstack.getTag());
    				if (entitytype.get().spawn(worldIn, itemstack, playerIn, blockpos, SpawnReason.SPAWN_EGG, false, false) == null) 
    				{
    					return ActionResult.resultPass(itemstack);
    				} 
    				else 
    				{
    					if (!playerIn.abilities.isCreativeMode) 
    					{
    						itemstack.shrink(1);
    					}
    					playerIn.addStat(Stats.ITEM_USED.get(this));
    					return ActionResult.resultSuccess(itemstack);
    				}
    			} 
    			else 
    			{
    				return ActionResult.resultFail(itemstack);
    			}
    		}
    	}
    
    	public boolean hasType(@Nullable CompoundNBT p_208077_1_, RegistryObject<? extends EntityType<?>> type) 
    	{
    		return Objects.equals(this.getType(p_208077_1_), type);
    	}
    
    	@OnlyIn(Dist.CLIENT)
    	public int getColor(int tintIndex) 
    	{
    		return tintIndex == 0 ? this.primaryColor : this.secondaryColor;
    	}
    
    	@Nullable
    	@OnlyIn(Dist.CLIENT)
    	public static EtauricSpawnEggItem getEgg(@Nullable RegistryObject<? extends EntityType<?>> type) 
    	{
    		return EGGS.get(type);
    	}
    
    	public static Iterable<EtauricSpawnEggItem> getEggs() 
    	{
    		return Iterables.unmodifiableIterable(EGGS.values());
    	}
    
    	public RegistryObject<? extends EntityType<?>> getType(@Nullable CompoundNBT p_208076_1_) 
    	{
    		if (p_208076_1_ != null && p_208076_1_.contains("EntityTag", 10)) 
    		{
    			CompoundNBT compoundnbt = p_208076_1_.getCompound("EntityTag");
    			if (compoundnbt.contains("id", 8)) 
    			{
    				return RegistryObject.of(new ResourceLocation(compoundnbt.getString("id")), ForgeRegistries.ENTITIES);
    			}
    		}
    		return this.typeIn;
    	}
    }

    This is my spawn egg class. 

     

    	public static final RegistryObject<Item> CHUPNUT_SPAWN_EGG = ITEMS.register("chupnut_spawn_egg", () -> new EtauricSpawnEggItem(RegistryObject.of(EtauricEntities.CHUPNUT.getId(), ForgeRegistries.ENTITIES), 4993583, 12692382, (new Item.Properties().group(ItemGroup.MISC))));

    And this is how I register it in my Items register. 

     

    Any sort of help is very much appreciated. 

  14. 33 minutes ago, Alpvax said:
    
    RegistryObject.of(resourceLocation-of-entitytype, ForgeRegistries.ENTITY);

    If you change it to receive a Supplier<? extends EntityType<? extends LivingEntity>> instead of having to be a RegistryObject, then you could pass in the vanilla types as () -> VANILLA_TYPE.

     

    You could change your existing method to create the registry object or supplier and pass it into the other method.

    Thank you! I changed it to a Supplier instead. I'm gonna have to learn how to use these systems so that I can use them more efficiently in the future.

    Case solved! 

  15. 38 minutes ago, diesieben07 said:

    This is your issue. Store the RegistryObject here, instead of calling get immediately.

    I'm sorry, I don't think I follow. If I were to store it like so:

    		public BossItem.BossProperties setBoss(RegistryObject<? extends EntityType<? extends LivingEntity>> boss) 
    		{
    			this.boss = boss;
    			
    			return this;
    		}

    I have to remove this:

    		private EntityType<? extends LivingEntity> boss;
    		
    		public BossItem.BossProperties setBoss(EntityType<? extends LivingEntity> boss) 
    		{
    			this.boss = boss;
    			
    			return this;
    		}

    And change this: 

    		private EntityType<? extends LivingEntity> boss;

    To this: 

    		private RegistryObject<? extends EntityType<? extends LivingEntity>> boss;

    And that would mean, that if I wanted to use this to spawn some other vanilla creature, it wouldn't work. 

    Or am I wrong here? 

     

    EDIT: It does work, but this does not support vanilla creatures. Do I have to create a second BossItem that does work with vanilla, or is there a way for both methods to coexist in the same BossItem?

  16. 3 minutes ago, diesieben07 said:

    You are still directly using EntityType. You must use the registry object.

    Oh. Well, how would i do that? The registry objects and the suppliers are really new to me so I haven't really figured out how to use them. 

    	public static final RegistryObject<Item> TERROR_FEEDER = ITEMS.register("terror_feeder", () -> new BossItem(new BossItem.BossProperties().setBoss(EtauricEntities.CHUPNUT).setTooltip("A food source for a special water beast...")));
    RegistryObject<EntityType<EtauricEntities.CHUPNUT>>

    This is obviously wrong as i've experienced...

  17. 3 minutes ago, diesieben07 said:

    Generics are invariant by default. So if you want a RegistryObject<something> you need to pass exactly a RegistryObject<something>, not e.g. a RegistryObject<subclass of something>.

    If you want to allow subclasses, you need to use RegistryObject<? extends something>. In your case: RegistryObject<? extends EntityType<? extends LivingEntity>>.

     

    Yes, Java generics suck. Use Kotlin if it really bothers you.

    Wow. Thanks for telling me, that would have been a great pain for me to figure out by my own. Still, the registry_object is not present remains. This is my current code:

    	public static final RegistryObject<Item> TERROR_FEEDER = ITEMS.register("terror_feeder", () -> new BossItem(new BossItem.BossProperties().setBoss(EtauricEntities.CHUPNUT).setTooltip("A food source for a special water beast...")));

    Item register. 

    public class BossItem extends Item
    {
    	private final String tooltip;
    	private final EntityType<? extends LivingEntity> boss;
    	
    	public BossItem(BossItem.BossProperties properties) 
    	{
    		super(properties.group(ItemGroup.MISC).maxStackSize(1));
    		this.boss = properties.boss;
    		this.tooltip = properties.toolTip;
    	}
    	
    	@Override
    	public void addInformation(ItemStack stack, World worldIn, List<ITextComponent> tooltip, ITooltipFlag flagIn) 
    	{
    		if (this.tooltip != null) 
    		{
    			tooltip.add(new StringTextComponent("\u00A7e" + this.tooltip + "\u00A7e"));
    		}
    		
    		tooltip.add(new StringTextComponent("\u00A76" + "Use this to summon " + this.boss.getName().getString() + "\u00A76"));
    	}
    	
    	public static class BossProperties extends Item.Properties
    	{
    		private String toolTip;
    		private EntityType<? extends LivingEntity> boss;
    		
    		public BossItem.BossProperties setBoss(EntityType<? extends LivingEntity> boss) 
    		{
    			this.boss = boss;
    			
    			return this;
    		}
    		
    		public BossItem.BossProperties setBoss(RegistryObject<? extends EntityType<? extends LivingEntity>> boss) 
    		{
    			this.boss = boss.get();
    			
    			return this;
    		}
    		
    		public BossItem.BossProperties setTooltip(String toolTip)
    		{
    			this.toolTip = toolTip;
    			
    			return this;
    		}
    	}
    }

    The BossItem. 

    Did I do it the way you told me? 

  18. 4 minutes ago, diesieben07 said:

    Which errors? Where exactly?

    Quote

    The method setBoss(EntityType<? extends LivingEntity>) in the type BossItem.BossProperties is not applicable for the arguments (RegistryObject<EntityType<ChupnutEntity>>)

    Quote

    The method setBoss(RegistryObject<EntityType<? extends LivingEntity>>) in the type BossItem.BossProperties is not applicable for the arguments (RegistryObject<EntityType<ChupnutEntity>>)

    On the setBoss method. 

    And then it gives me 3 "quick fixes" that all involves I change either the chupnut to livingentity or that the method parameter be changed to chupnutentity. 

  19. Why doesn't this work? 

    	public static final RegistryObject<Item> TERROR_FEEDER = ITEMS.register("terror_feeder", () -> new BossItem(new BossItem.BossProperties().setBoss(EtauricEntities.CHUPNUT).setTooltip("A food source for a special water beast...")));

    It won't work unless i specifically say that the <?> entity is an entity chupnut...

    		public BossItem.BossProperties setBoss(RegistryObject<EntityType<? extends LivingEntity>> boss) 
    		{
    			this.boss = boss.get();
    			
    			return this;
    		}

    I assume that this is what you meant by that?

    47 minutes ago, diesieben07 said:

    Store the RegistryObject (or just a Supplier, which RegistryObject implements) instead of the direct EntityType.

  20. I have registered my entities using Deferred registries and it has been working fine until I tried to create a boss-summoning item. I have tried to use vanilla entities instead of my own entities and they work. But apparently, my own entities are being registered AFTER I register my items and blocks, but this should not be the case since I register my entities BEFORE my items and blocks. 

    The error message states:

    Quote

    Encountered and error during the load_registries event phase. 

    Registry Object not present. 

    Which to me states that it cannot grab the entity since it hasn't been registered yet. 

    		instance = this;
    		
    		final IEventBus modBus = FMLJavaModLoadingContext.get().getModEventBus();
    		
    		modBus.addListener(this::commonSetup);
    		modBus.addListener(this::clientSetup);
    		
    		EtauricEntities.ENTITIES.register(modBus);
    		
    		EtauricItems.ITEMS.register(modBus);
    		EtauricBlocks.BLOCKS.register(modBus);
    		
    		EtauricBiomes.BIOMES.register(modBus);
    		
    		MinecraftForge.EVENT_BUS.register(this);

    This is my Main Class. 

    	public static final RegistryObject<Item> TERROR_FEEDER = ITEMS.register("terror_feeder", () -> new BossItem(new BossItem.BossProperties().setBoss(EtauricEntities.CHUPNUT.get()).setTooltip("A food source for a special water beast...")));

    And this is the Item i'm trying to get to work. 

    public class BossItem extends Item
    {
    	private final String tooltip;
    	private final EntityType<? extends LivingEntity> boss;
    	
    	public BossItem(BossItem.BossProperties properties) 
    	{
    		super(properties.group(ItemGroup.MISC).maxStackSize(1));
    		this.boss = properties.boss;
    		this.tooltip = properties.toolTip;
    	}
    	
    	@Override
    	public void addInformation(ItemStack stack, World worldIn, List<ITextComponent> tooltip, ITooltipFlag flagIn) 
    	{
    		if (this.tooltip != null) 
    		{
    			tooltip.add(new StringTextComponent("\u00A7e" + this.tooltip + "\u00A7e"));
    		}
    		
    		tooltip.add(new StringTextComponent("\u00A76" + "Use this to summon " + this.boss.getName() + "\u00A76"));
    	}
    	
    	public static class BossProperties extends Item.Properties
    	{
    		private String toolTip;
    		private EntityType<? extends LivingEntity> boss;
    		
    		public BossItem.BossProperties setBoss(EntityType<? extends LivingEntity> boss) 
    		{
    			this.boss = boss;
    			
    			return this;
    		}
    		
    		public BossItem.BossProperties setTooltip(String toolTip)
    		{
    			this.toolTip = toolTip;
    			
    			return this;
    		}
    	}
    }

    And lastly, this is the BossItem class. 

×
×
  • Create New...

Important Information

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