Jump to content

kiou.23

Members
  • Posts

    444
  • Joined

  • Last visited

  • Days Won

    5

Posts posted by kiou.23

  1. 1 hour ago, Quaint34 said:
    
    public class tileEntityTypeInit <T extends TileEntity> extends net.minecraftforge.registries.ForgeRegistryEntry<TileEntityType<?>>{
    
        public static final DeferredRegister<TileEntityType<?>> ENTITY_TYPE_DEFERRED_REGISTER = DeferredRegister.create(
                ForgeRegistries.TILE_ENTITIES, SwaysVanilla.modID
        );
    
        public static final TileEntityType<SignTileEntity> SIGN_TILE_ENTITY_TYPE = ENTITY_TYPE_DEFERRED_REGISTER.register(
                "sign", TileEntityType.Builder.create(SignTileEntity::new, blockInit.MAGICA_SIGN, blockInit.WALL_MAGICA_SIGN));
    }

    How do I apply the RegistryObjects in the field above? I have tried the .get() method but it doesn't work for some reason.

    you should call .get() on the registry objects. any time you're dealing with registry objects, and you need the actual thing "inside" the registry object, you use .get() (that's because a registry object is just a fancy supplier)

    the problem is that when registering to a deferred register, you need to pass a supplier which returns the actual object. but in the code you're just passing the object (in your "sign" tile entity registration)

    also, the DeferredRegister::register(string, supplier) returns a RegistryObject, not a TileEntityType

    also, don't name your tile entity type deferred register a "entity type deferred register", entity types are another thing entirely (for entities, and not tile entities)

     

    also also, please properly type your Registry Objects, if it's a SignItem, don't type it to RegistryObject<Item>, but use the more specific RegistryObject<SignItem>, same goes for your blocks

  2. a lot has changed since 1.8.9, like, a lot, almost everything. there isn't a 1 to 1 mapping from 1.8 to 1.16, you're better of just learning the new systems and rewriting the mod entirely.

    as for the list of classes, methods and fields, you can get them directly from your ide.

    the forge docs, and the community docs, has a lot of resources. and if there is something that isn't on the docs, and that you can't figure out by yourself, you can ask for help for that specific problem here in the forum

  3. 7 minutes ago, Anonomys said:

    the problem is that the custom block model makes the block underneath or beside it transparent.

    you need to set your blocks render layer to be cutout during the client setup.

    8 minutes ago, Anonomys said:

    I saw that my latest version of my mod was 1.16.3, so i decided to update it to 1.16.5. Then I found out that they renamed basically everything

    things haven't been renamed. Forge previously used mcp mappings, but recently Mojang relesead the official mappings, and so the newer versions of forge ship with those by default.

    you can cahnge the mappings channel and version in your build.gradle to switch back to mcp

    8 minutes ago, Anonomys said:

    the problem is that its not the same code as in the 1.16.3 because the voxel shapes and facing things dont work in this version.

    they should work, just have different names. you can use of your IDE's auto complete to see what method shares the signature (parameters and return type), that you were using

  4. 7 hours ago, LuccaPossamai said:

    Ok, with an example the things just get so many clear now. Thanks btw. But, I'm confused. How do I register this Capability. I mean, I tried but, with the serialization, there is no IStorage. I looked in your code, and do not find a field that you register the cap. 

    since that's just using an ItemStackHandler, I used the ITEM_HANDLER capability that already exists in CapabilityItemHandler

    Bur for registration you just create a field, in a class like ModCapabilities, of type Capability<Your Capability class>, and use @CapabilityInject()

    and I didn't have to use an attach event because I'm using the capability in a custom Item. but for attaching it's the same thing, just listen to the proper event, and call event.addCapabicall, then give it the cap ID and an instance of the cap provider

  5. 1 hour ago, LuccaPossamai said:

    Ok, I changed some things. But the inventory still resets. I'm calling the registration of the capability in the setup, maybe this is causing the reset.
    The attachEvent:

      Reveal hidden contents
    
    
    
    
    
    
    @Mod.EventBusSubscriber
    public class AltarCapabilitySetup {
    
        @SubscribeEvent
        public static void attachEntityCapabilities(AttachCapabilitiesEvent<Entity> event) {
            if(event.getObject() instanceof  PlayerEntity) {
                event.addCapability(new ResourceLocation(ExampleMod.MOD_ID, "altar_inventory"), new CapabilityInstance());
            }
        }
        
    }

     

    And the Provider/Serializable:

      Reveal hidden contents
    
    
    
    
    
    
    public class CapabilityInstance implements ICapabilityProvider, ICapabilitySerializable {
    
        @CapabilityInject(ItemStackHandler.class)
        public static Capability<ItemStackHandler> ALTAR_CAPABILITY = null;
    
        private final ItemStackHandler ALTAR_HANDLER = new ItemStackHandler(9);
    
        private final LazyOptional<ItemStackHandler> ALTAR_LAZY = LazyOptional.of(()-> ALTAR_HANDLER);
    
        @Nonnull
        @Override
        public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable Direction side) {
            return ALTAR_LAZY.cast();
        }
    
        @Override
        public INBT serializeNBT() {
            if(ALTAR_CAPABILITY == null){
                return new CompoundNBT();
            } else {
                return ALTAR_CAPABILITY.writeNBT(ALTAR_HANDLER, null);
            }
        }
    
        @Override
        public void deserializeNBT(INBT nbt) {
            if(ALTAR_CAPABILITY != null) {
                ALTAR_CAPABILITY.readNBT(ALTAR_HANDLER, null, nbt);
            }
        }
        public static void register() {
            CapabilityManager.INSTANCE.register(CapabilityInstance.class, new Capability.IStorage<CapabilityInstance>() {
                @Nullable
                @Override
                public INBT writeNBT(Capability<CapabilityInstance> capability, CapabilityInstance instance, Direction side) {
                    return instance.serializeNBT();
                }
    
                @Override
                public void readNBT(Capability<CapabilityInstance> capability, CapabilityInstance instance, Direction side, INBT nbt) {
                    instance.serializeNBT();
                }
            }, CapabilityInstance::new);
        }
    
    
    }

     

     

    in the provider's serializeNBT you call the IStorage's writeNBT, but in the IStorage's writeNBT you call the provider's serializeNBT. You never actually serialize your data.

     

    1. You don't need an IStorage, just do the serialization in the provider itself.

    2. your lazy altar isn't actually lazy. google the concept up. don't initialize the the field on instantiation, instead wait until the capability is requested to initialize it, then cache it.

    3. no need to implement ICapabilityProvider, only ICapabilitySerializable, also, you should define the generic parameter of the interface.

    4. don't put your capability instance on the capability provider class. that's separation of concerns 101

    5. on your getCapability, make sure that the capability being requested is the one you're providing!

    Hold on, I have a mod with a private repo that uses capabilities. I'll make it public to share it here so you can see some examples

     

    EDIT: here's some examples https://github.com/jvcmarcenes/skbackpacks

    EDIT2: I had forgot, for serializing ItemStackHandlers you can use of CapabilityItemHandler.ITEM_HANDLER_CAPABILITY write/read method

  6. 38 minutes ago, LuccaPossamai said:

    I use this tile entity for a block, and this block the player use to open the inventory(like an ender chest).

    that doesn't mean you need a tile entity, the data is being stored in the player's capability, not the block

     

    38 minutes ago, LuccaPossamai said:

    The class for ItemStackHandler cap: 

    
    
    public class DefaultAltarCapability extends ItemStackHandler {
    
        public DefaultAltarCapability(){
            super(9);
        }
        
    }

     

    There's no need to extends the ItemStackHandler, just instantiate it

     

    38 minutes ago, LuccaPossamai said:

    The Capability.IStorage:

    
    
    
    public class IStorageInstance implements Capability.IStorage<DefaultAltarCapability> {
    
        @Nullable
        @Override
        public INBT writeNBT(Capability<DefaultAltarCapability> capability, DefaultAltarCapability instance, Direction side) {
            ListNBT listnbt = new ListNBT();
    
            for(int i = 0; i < instance.getSlots(); ++i) {
                ItemStack itemstack = instance.getStackInSlot(i);
                CompoundNBT compoundnbt = new CompoundNBT();
                compoundnbt.putInt("Slot", i);
                itemstack.save(compoundnbt);
                listnbt.add(compoundnbt);
    
            }
            CompoundNBT nbt = new CompoundNBT();
            nbt.put("Items",listnbt);
            nbt.putInt("Size",listnbt.size());
    
            return listnbt;
        }
    
        @Override
        public void readNBT(Capability<DefaultAltarCapability> capability, DefaultAltarCapability instance, Direction side, INBT nbt) {
            if(nbt instanceof  CompoundNBT) {
                System.out.println("É tag");
                CompoundNBT compoundNBT = (CompoundNBT) nbt;
                ListNBT tagList = compoundNBT.getList("Items", Constants.NBT.TAG_COMPOUND);
    
                for (int i = 0; i < tagList.size(); ++i) {
                    instance.insertItem(i, ItemStack.of(tagList.getCompound(i)), false);
                }
            }
        }
    
    }

     

    You don't need to use IStorage, plus they're being removed in the next versions. just do the serialization in the provider

     

    38 minutes ago, LuccaPossamai said:

    The instance of the capability:

    
    
    
    public class CapabilityInstance  {
    
        @CapabilityInject(DefaultAltarCapability.class)
        public static Capability<DefaultAltarCapability> ALTAR_CAPABILITY = null;
    
        public static void register(){
            CapabilityManager.INSTANCE.register(DefaultAltarCapability.class, new IStorageInstance(), DefaultAltarCapability::new );
        }
    
    
    }

     

    and when your CapabilityInstance.register called?

     

    38 minutes ago, LuccaPossamai said:

    I'm using this to load the items, a add them to an inventory:

    
    
    
    private Inventory loadItems(PlayerEntity player){
            Inventory inventory = new Inventory(9);
            player.getCapability(CapabilityInstance.ALTAR_CAPABILITY).ifPresent(inv ->{
                for(int i = 0; i < inv.getSlots(); i++){
                    inventory.setItem(i, inv.getStackInSlot(i));
                }
            });
    
            return inventory;
        }

    And using this, to save the items of the container in the cap:

    
    
    
    @SubscribeEvent
        public static void saveAltarItems(PlayerContainerEvent.Close event){
            PlayerEntity jogador = event.getPlayer();
            if(event.getContainer() instanceof ModAltarContainer) {
                NonNullList<ItemStack> lista = NonNullList.withSize(9, ItemStack.EMPTY);
                Container cont = event.getContainer();
                jogador.getCapability(CapabilityInstance.ALTAR_CAPABILITY).ifPresent( inv ->{
                    for(int i = 0 ; i < inv.getSlots() ; i++){
                        inv.setStackInSlot(i, cont.getItems().get(i));
                        inv.deserializeNBT(inv.serializeNBT());
                    }
                });
                //PlayerEvolution.setStats(lista, jogador);
            }
        }

     

    What are these for? why are you converting the ItemStackHandler to an Inventory, to use the ItemStackHandler

     

    And you didn't show the CapabilityProvider.

    You're over complicating this, I've already explained what it is that you need:

    On 5/26/2021 at 11:58 PM, kiou.23 said:

    1. A capability, and a capability is just a class which holds any arbitrary data you need. Since what you want is an "inventory", forge provides an implementation for that, the ItemStackHandler. If you don't require any custom logic on top of just a holder of ItemStacks, you don't even need to extend it, just use the ItemStackHandler capability.

    2. A capability provider, which will manage the capabilities for your player. in it you'll handle serialization, and on the getCapability method, you'll check if the requested capability matches your capability, and if it does, return the lazy capability

    3. you'll register the capabilities, and attach them on the proper event handler

    4. if you want the inventory to be displayed, and interacted with by the player, you'll need the container and a container screen (not a tile entity, those are for blocks).

    your Capability Provider will provide an ItemStackHandler, in this case, handle serialization in the Provider's serialize and deserialize methods

    and you don't need a TE, at least not for this. the TE is meant to store additional data for blocks, since the data you're storing isn't kept in a block, but in the player, you don't need a Tile entity. to open the container you just need an INamedContainerProvider, which passes any data that the Container needs, to the container. and you'll get this data from the Capability

  7. 3 minutes ago, octa said:

    Read it again, the expression is !(nether || end)

    ohh, my bad then, I'm sorry

     

    4 minutes ago, octa said:

    Then why did registering the feature fix OP's issue? I'm just genuinely curious how this could break his code but not mine. I'll be interested if you find that source.

    I edited the source in. the problem the OP had was possibly a different one, I can't really tell tho

    • Thanks 1
  8. 5 hours ago, octa said:

    Nowhere in my code do I do this, and I also don't tag any of my functions with @SubscribeEvent. Maybe I'm just misunderstanding how registries and events work.

    You don't need to tag the method with @SubscribeEvent because you're manually adding the event listener method in your Main constructor, here:

    FORGE_EVENT_BUS.addListener(EventPriority.HIGH, OreGeneration::generateOres);

    (also, there's no point in setting EventPriority to high)

    the docs goes into the different ways of attaching your event listeners: https://mcforge.readthedocs.io/en/latest/events/intro/

     

    This line

    if (!(event.getCategory().equals(Biome.Category.NETHER) || event.getCategory().equals(Biome.Category.THEEND))) {

    isn't doing s**t, it's flawed logic, you want this to only be true when the biome category is the overwold, right?

    so walk through it, imagine the biome is in the nether, the left part of the || will be evaluated to false, correctly, but then, the biome is in the nether, but not in the end, the right part will evaluate to true, and false || true == true

     

    And about the registering, IIRC you don't "need" to register the feature, but you should, I don't quite remember why, so don't quote me on this. I'll look for where I read this, if I find it I'll add it here as an edit

     

    EDIT: found it:

     

  9. 5 hours ago, Luis_ST said:

    create a new ItemEntity and and it to the world

    It's easier to use InventoryHelper#spawnItemStack

    also note that BlockPos stand for the bottom corner of the block, you need to properly offset the spawning position

  10. 6 hours ago, LuccaPossamai said:

    The tile entity in this context just serves to open the container that allows the player to have acess to this inventory.

    yeah, that's not what tile entities are for. Tile entities are for blocks.

    what you need to open the container, is an INamedContainerProvider

    6 hours ago, LuccaPossamai said:

    I change for the ItemStackHandler and I works. But, when I enter the world the capability resets.

    then you're not properly serializing your data, make sure you properly overrode the serializeNBT and deserializeNBT methods in your Capability Provider.

    and post your new code if you're still with some issues

  11. Why do you have a tile entity? isn't the capability for the player entity?

    What's  the purpose of IStorageInstance? and what's the difference between AltarCapability and DefaultAltarCapability?

    I think you're under some fundamental misconception over the capability system. Here's what you need:

    1. A capability, and a capability is just a class which holds any arbitrary data you need. Since what you want is an "inventory", forge provides an implementation for that, the ItemStackHandler. If you don't require any custom logic on top of just a holder of ItemStacks, you don't even need to extend it, just use the ItemStackHandler capability.

    2. A capability provider, which will manage the capabilities for your player. in it you'll handle serialization, and on the getCapability method, you'll check if the requested capability matches your capability, and if it does, return the lazy capability

    3. you'll register the capabilities, and attach them on the proper event handler

    4. if you want the inventory to be displayed, and interacted with by the player, you'll need the container and a container screen (not a tile entity, those are for blocks).

  12. 6 hours ago, vemerion said:

    Since you are registering an instance of the Main class to the event buss, you need to remove the static keyword on the onEntityInteraction() method. In addition to that, you also need to override canBeCollidedWith() in your entity class. This should resolve both your issues.

    That did it, thanks!

    • Like 1
  13. I have added some entities, and am trying to detect right/hit clicks, and left clicks. however none of them seem to trigger when I click the entity. I can confirm that I was clicking inside the entity hitbox

    Interact Listener:

    @SubscribeEvent
      public static void onEntityInteraction(PlayerInteractEvent.EntityInteract e) {
        if (e.getWorld().isRemote()) return;
    
        if (!(e.getTarget() instanceof DiceEntity)) return;
          
        DiceEntity dice = (DiceEntity)e.getTarget();
        ItemStack diceItem = dice.getItem().copy();
    
        dice.remove();
        
        e.getPlayer().addItemStackToInventory(diceItem);
      }

    Hit Override:

    @Override
      public boolean hitByEntity(Entity entity) {
        Main.LOGGER.info(this.getName().getString() + " was hit by " + entity.getName().getString());
    
        return super.hitByEntity(entity);
      }

     

    repo: github.com/jvcmarcenes/dicehoard

  14. 1 hour ago, aritod said:

    The path of your classes should be src/main/java/com/<MOD_AUTHOR>/<MOD_ID>/...

    That should only be the path if you own the domain <MOD_AUTHOR>.com, which commonly isn't the case

    if  you don't own a website/domain, the recommended package name is io.github.<MOD_AUTHOR>, or some repository hosting service you use.

    The name of the package, however, does not affect the issue

×
×
  • Create New...

Important Information

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