Posted May 18, 20232 yr Hellow good days Im remaking this item for 19.4 and this particular item has 3 types or states i store to a capability ih.type = 0 suspension normal unactivated ih.type = 1 suspension shaking ih.type = 3 suspension activated im storing the value of type in the capability on the server side to later retrieve that value in the client side to define what json texture the item gonna use i notice than the values form the capability in the server side are not updating immediately to client side sometimes it does after a while sometimes not , but if close the game and open it again then the values appears as expected in both server and client side this is whats i see in the console //client side this.comment => 0 this.start_time => 0 this.time => 0 this.type => 0 //server side this.comment => 0 this.start_time => 136810 this.time => 21 this.type => 1 ############################## sooo : * could be than capabilities declaration way has been change and just dont mark as error in mi intellij installation but still works coze hooked right to the item NBTtag * in the capability file some flag must be turned on to make it send the data to client side and that flag is missing * Capabiities has violently change whit 19.4 and as this is just copy paste from 19.2 code . i set the capability to the item this way and use a function to get the object and test it using a print function inside on entity swing Spoiler @Nullable @Override public ICapabilityProvider initCapabilities(ItemStack container, @Nullable CompoundTag nbt) { return new item_c_provider(container); } // ########## ########## ########## ########## public static item_handler get_itemhandler(ItemStack helditem) { // item_handler ih = get_itemhandler(helditem); item_handler ih = ((item_handler) helditem.getCapability(ForgeCapabilities.ITEM_HANDLER) .orElseThrow(() -> new RuntimeException("O_O"))); return ih; } // ########## ########## ########## ########## @Override public boolean onEntitySwing(ItemStack helditem, LivingEntity le) { Level warudo = le.level; item_handler ih = get_itemhandler(helditem); //on crounch change the value and save it to capability if( !warudo.isClientSide && le.isCrouching()) { ih.comment = (int)(Math.random() * 10) ; } ih.print(); return true; } the capability Spoiler package mercblk.items.classes; import net.minecraft.core.NonNullList; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.ListTag; import net.minecraft.nbt.Tag; import net.minecraft.world.item.ItemStack; import net.minecraftforge.items.ItemStackHandler; import org.jetbrains.annotations.NotNull; public class item_handler extends ItemStackHandler { ItemStack container = null; public int comment = 0; public Long start_time = 0L; public int time = 0; public int type = 0; public item_handler(ItemStack container) { super(0); this.container = container; } @Override public CompoundTag serializeNBT() { CompoundTag nbt = new CompoundTag(); nbt.putInt("comment", this.comment ); nbt.putLong("start_time", this.start_time ); nbt.putInt("time", this.time ); nbt.putInt("type", this.type ); return nbt; } @Override public void deserializeNBT(CompoundTag nbt) { this.comment = nbt.getInt("comment" ); this.start_time = nbt.getLong("start_time" ); this.time = nbt.getInt("time" ); this.type = nbt.getInt("type"); onLoad(); } public void print() { System.out.println( "this.comment => " + this.comment ); System.out.println( "this.start_time => " + this.start_time ); System.out.println( "this.time => " + this.time ); System.out.println( "this.type => "+ this.type ); } } full item Spoiler package mercblk.items.classes; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; import mercblk.util.Item_helper; import net.minecraft.client.renderer.item.ItemProperties; import net.minecraft.nbt.CompoundTag; import net.minecraft.resources.ResourceLocation; import net.minecraft.sounds.SoundEvents; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; import net.minecraft.world.InteractionResultHolder; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.UseAnim; import net.minecraft.world.item.context.UseOnContext; import net.minecraft.world.level.Level; import mercblk.mercblk; import net.minecraftforge.common.capabilities.ForgeCapabilities; import net.minecraftforge.common.capabilities.ICapabilityProvider; import javax.annotation.Nullable; import java.io.File; import java.io.FileWriter; import java.io.FileReader; import java.io.IOException; import java.nio.file.Path; import java.util.HashMap; public class Solution_Item extends Item { //########## ########## ########## ########## ########## ########## //########## ########## ########## ########## ########## ########## //########## ########## ########## ########## ########## ########## //########## ########## ########## ########## ########## ########## private String json = "{}"; public Solution_Item(Item.Properties propiedades, String json, Boolean crear_archivos) { super(propiedades); try { if(crear_archivos) { this.test_this(json); } } catch (IOException e) { e.printStackTrace(); } } //###### ###### ###### ###### ###### ###### public static void make_solution_shake(Item item) { ItemProperties.register(item, new ResourceLocation("pull"), (helditem, warudo, le, p_174638_) -> { //ItemModelsProperties.register(item, new ResourceLocation("pull"), (helditem, warudo, le) -> { if (le == null) { return 0.0F; } else { item_handler ih = get_itemhandler(helditem); return ih.type; } }); ItemProperties.register(item, new ResourceLocation("pulling"), (helditem, warudo, le, p_174638_) -> { //ItemModelsProperties.register(item, new ResourceLocation("pulling"), (helditem, warudo, le) -> { return (le != null && le.getUseItem() == helditem) ? 1.0F : 0.0F; }); } // ########## ########## ########## ########## public int getContainerSize() { return 9; } @Nullable @Override public ICapabilityProvider initCapabilities(ItemStack container, @Nullable CompoundTag nbt) { return new item_c_provider(container); } // ########## ########## ########## ########## public static item_handler get_itemhandler(ItemStack helditem) { // item_handler ih = get_itemhandler(helditem); item_handler ih = ((item_handler) helditem.getCapability(ForgeCapabilities.ITEM_HANDLER) .orElseThrow(() -> new RuntimeException("O_O"))); return ih; } // ########## ########## ########## ########## // @Override public static float getPowerForTime(int p_40662_) { float f = (float) p_40662_ / 20.0F; f = (f * f + f * 2.0F) / 3.0F; if (f > 1.0F) { f = 1.0F; } return f; } public int getUseDuration(ItemStack helditem) { return 80; } public UseAnim getUseAnimation(ItemStack helditem) { return UseAnim.BOW; } // ########## ########## ########## ########## // ON RIGHT CLICK public InteractionResultHolder<ItemStack> use(Level warudo, Player pe, InteractionHand mano) { ItemStack helditem = pe.getItemInHand(mano); item_handler ih = get_itemhandler(helditem); Long wtick = warudo.dayTime(); if( !warudo.isClientSide && ih.type < 2 ) { ih.type = 1; //inicializar tiempo ih.start_time = wtick; pe.playSound(SoundEvents.AMBIENT_UNDERWATER_ENTER, 2.0F, 2.0F); pe.startUsingItem(mano); return InteractionResultHolder.success(helditem); } return InteractionResultHolder.pass(helditem); } // ########## ########## ########## ########## @Override public boolean onEntitySwing(ItemStack helditem, LivingEntity le) { Level warudo = le.level; item_handler ih = get_itemhandler(helditem); //on crounch change the value and save it to capability if( !warudo.isClientSide && le.isCrouching()) { ih.comment = (int)(Math.random() * 10) ; } ih.print(); return true; } // ########## ########## ########## ########## //@Override public void inventoryTick(ItemStack helditem, Level warudo, Entity en, int slot_index, boolean p_77663_5_) { // System.out.println( String.format( "inventoryTick (%1$s)" , slot_index ) ); } // ########## ########## ########## ########## public int usedtime(ItemStack helditem, int time) { return (getUseDuration(helditem) - time);// war } // ########## ########## ########## ########## @Override public void onUseTick(Level warudo, LivingEntity le, ItemStack helditem, int timeleft) { int tick = usedtime(helditem, timeleft); //System.out.println( "onUseTick = " + tick ); if ((tick % 5 == 0) && le != null) { // PlayerEntity pe = (PlayerEntity) le; le.playSound(SoundEvents.AMBIENT_UNDERWATER_ENTER, 0.5F, 0.5F); } // util.showthis("tick=" +tick , le); } // ########## ########## ########## ########## // ########## ########## ########## ########## @Override public void releaseUsing(ItemStack helditem, Level warudo, LivingEntity le, int p_40670_) { finishUsingItem(helditem, warudo, le); } @Override public ItemStack finishUsingItem(ItemStack helditem, Level warudo, LivingEntity le) { System.out.println( "finishUsingItem"); if (!warudo.isClientSide) { if (helditem.getItem() instanceof Solution_Item) { InteractionHand mano = le.getUsedItemHand(); Long wtick = warudo.dayTime(); item_handler ih = get_itemhandler(helditem); ih.time = (int) ( wtick - ih.start_time ); int tick = ih.time; if( ih.time > 40 ){ ih.type = 2; } else { ih.type = 0; } //helditem = new ItemStack(ItemInit.SOLUTION_REDSTONE_ACTIVATED.get(), 1); //le.setItemInHand(mano, helditem); // helditem = MItems.SOLUTION_REDSTONE_ACTIVATED; } } return helditem; } //########## ########## ########## //escribir un archivo de texto public static void test_this(String json) throws IOException { HashMap<String, String> datamap = new Gson().fromJson(json, new TypeToken<HashMap<String, String>>() { }.getType()); datamap.put("mod_id", mercblk.MOD_ID); String src_path_string = Item_helper.get_src_path_string();//path to the src folder System.out.println("string dir_path: " + src_path_string); File src_path = new File(src_path_string); // for (File file : src_path.listFiles()) { if (file.isDirectory()) { //System.out.println("Directory: " + file.getAbsolutePath());//list all folder inside src } } //%MOD_ID% //%NAME% //%LAYER0% //item/surface/acero-clear //%LAYER1% //%LAYER2% //%LAYER3% //%LAYER4% //%LAYER5% //%PARTICLE% String item_json = ""; String file_path_string = ""; //Modelo para el item item_json = """ { "overrides": [ { "predicate": { "pulling": 0 }, "model": "%MOD_ID%:item/redstone/solution_redstone_deactivated" }, { "predicate": { "pulling": 1 }, "model": "%MOD_ID%:item/redstone/solution_redstone_shaking" }, { "predicate": { "pulling": 2 }, "model": "%MOD_ID%:item/redstone/solution_redstone_activated" } ] } """; if( datamap.containsKey("layer0") ) { file_path_string = src_path_string + "/src/main/resources/assets/" + datamap.get("mod_id") + "/models/item/"; //crear el archivo Item_helper.crear_archivo(file_path_string, datamap.get("name") + ".json", Item_helper.replace_in_json(datamap, item_json) ); } //Modelo para el item desactivado item_json = """ { "parent": "minecraft:item/handheld", "textures": { "layer0": "%MOD_ID%:%LAYER0%", "particle": "%MOD_ID%:%PARTICLE%" } } """; if( datamap.containsKey("layer0") ) { file_path_string = src_path_string + "/src/main/resources/assets/" + datamap.get("mod_id") + "/models/item/redstone/"; //crear el archivo Item_helper.crear_archivo(file_path_string, "solution_redstone_deactivated.json", Item_helper.replace_in_json(datamap, item_json) ); } //Modelo para el item sacudiendo item_json = """ { "parent": "minecraft:item/handheld", "textures": { "layer0": "%MOD_ID%:%LAYER1%", "particle": "%MOD_ID%:%PARTICLE%" } } """; if( datamap.containsKey("layer1") ) { file_path_string = src_path_string + "/src/main/resources/assets/" + datamap.get("mod_id") + "/models/item/redstone/"; //crear el archivo Item_helper.crear_archivo(file_path_string, "solution_redstone_shaking.json", Item_helper.replace_in_json(datamap, item_json)); } //Modelo para el item sacudiendo item_json = """ { "parent": "minecraft:item/handheld", "textures": { "layer0": "%MOD_ID%:%LAYER2%", "particle": "%MOD_ID%:%PARTICLE%" } } """; if( datamap.containsKey("layer2") ) { file_path_string = src_path_string + "/src/main/resources/assets/" + datamap.get("mod_id") + "/models/item/redstone/"; //crear el archivo Item_helper.crear_archivo(file_path_string, "solution_redstone_activated.json", Item_helper.replace_in_json(datamap, item_json)); } //Item Forge tag item_json = """ { "replace": false, "values": [ "%MOD_ID%:%NAME%" ] } """; if( datamap.containsKey("minecraft_tag") ) { file_path_string = src_path_string + "/src/main/resources/data/forge/tags/items/solutions/"; //crear el archivo Item_helper.crear_archivo(file_path_string, datamap.get("minecraft_tag") + ".json", Item_helper.replace_in_json(datamap, item_json)); } //Lang file Ingles if( datamap.containsKey("en_us_lang") ) { file_path_string = src_path_string + "/src/main/resources/assets/" + datamap.get("mod_id") + "/lang/"; HashMap<String, String> lang_data = Item_helper.leer_archivo_map(file_path_string, "en_us.json"); //"item.mercblk.ingot_steel" : "Steel Ingot" String key = "item." + datamap.get("mod_id") + "." + datamap.get("name"); lang_data.put( key, datamap.get("en_us_lang") ); Item_helper.escribir_archivo_map(file_path_string, "en_us.json", lang_data); } //Lang file Ingles if( datamap.containsKey("es_es_lang") ) { file_path_string = src_path_string + "/src/main/resources/assets/" + datamap.get("mod_id") + "/lang/"; HashMap<String, String> lang_data = Item_helper.leer_archivo_map(file_path_string, "es_es.json"); //"item.mercblk.ingot_steel" : "Steel Ingot" String key = "item." + datamap.get("mod_id") + "." + datamap.get("name"); lang_data.put( key, datamap.get("es_es_lang") ); Item_helper.escribir_archivo_map(file_path_string, "es_es.json", lang_data); } } //########## ########## ########## ########## ########## ########## //########## ########## ########## ########## ########## ########## //########## ########## ########## ########## ########## ########## //########## ########## ########## ########## ########## ########## } thanks for your time Edited May 19, 20232 yr by perromercenary00 Solved
May 18, 20232 yr https://forge.gemwire.uk/wiki/Capabilities/Attaching#Synchronizing_Data_with_Clients The game will synchronize items to the client as part of other operations, e.g. opening your inventory or a container But it you want it immediately, you will need to do it yourself. If you look at vanilla, instead of sending network packets, the code will often try to predict what the new value should be on the client. e.g. if you look at EggItem.use() it shrinks the ItemStack count on both the server and client. Boilerplate: If you don't post your logs/debug.log we can't help you. For curseforge you need to enable the forge debug.log in its minecraft settings. You should also post your crash report if you have one. If there is no error in the log file and you don't have a crash report then post the launcher_log.txt from the minecraft folder. Again for curseforge this will be in your curseforge/minecraft/Install Large files should be posted to a file sharing site like https://gist.github.com You should also read the support forum sticky post.
May 18, 20232 yr Author hi thanks i cannot stop noticing i don't have this AttachCapabilitiesEvent<ItemStack>: Fires only for item stacks. where i could find and example of this event declaration ?
May 18, 20232 yr We are not a human search engine. Please do your own research. https://forge.gemwire.uk/wiki/Capabilities/Attaching Boilerplate: If you don't post your logs/debug.log we can't help you. For curseforge you need to enable the forge debug.log in its minecraft settings. You should also post your crash report if you have one. If there is no error in the log file and you don't have a crash report then post the launcher_log.txt from the minecraft folder. Again for curseforge this will be in your curseforge/minecraft/Install Large files should be posted to a file sharing site like https://gist.github.com You should also read the support forum sticky post.
May 19, 20232 yr Author Im currently believing is some kind of bug fireup old 19.2 version and there the capability get the values synced immediately on every change anyway i find a workaround a hacky one if in the capability.class manually force it to save the nbtdata to the item It gets immediately updated to the client side looks like no side effect and brings an opening to made a working onUseTick() function inside the capability // ########## ########## ########## ########## public void save() { if (this.container == null) { System.out.println("\n#this.container is Null at save()#\n"); return; } this.container.setTag(serializeNBT()); } Spoiler package mercblk.items.classes; import net.minecraft.core.NonNullList; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.ListTag; import net.minecraft.nbt.Tag; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.Level; import net.minecraftforge.items.ItemStackHandler; import org.jetbrains.annotations.NotNull; // ########## ########## ########## ########## ########## ########## // ########## ########## ########## ########## ########## ########## // ########## ########## ########## ########## ########## ########## public class item_handler extends ItemStackHandler { public ItemStack container = null; private Long t0 = 0L; private Long t1 = 0L; private int t = 0; public long start_time = 0L; public int time = 0; public int action = 0; public int limit = 40; public float fuel = 0; public int munition = 0; public int type = 0; public int tick = 0; // ########## ########## ########## ########## public item_handler(ItemStack container) { super(0); this.container = container; } // ########## ########## ########## ########## public void start_time() { this.start_time = System.currentTimeMillis(); } // ########## ########## ########## ########## public void stop_time() { this.start_time = 0L; } public Level getLevel(){ //Minecraft mc = new Minecraft(); //Blocks.ACACIA_LEAVES.getName(); return null; } // ########## ########## ########## ########## public void print(Level warudo) { System.out.println("<!-- -->"); //<!-- --> System.out.println("world => " + ((warudo.isClientSide) ? "Mundo Local" : "Mundo Servidor")); print(); } public void print() { System.out.println("this.start_time = " + this.start_time); System.out.println("this.time = " + this.time); System.out.println("this.action = " + this.action); System.out.println("this.limit = " + this.limit); System.out.println("this.fuel = " + this.fuel); System.out.println("this.munition = " + this.munition); System.out.println("this.type = " + this.type); System.out.println("this.tick = " + this.tick); } // ########## ########## ########## ########## @Override public int getSlotLimit(int slot) { return 64; } // ########## ########## ########## ########## @Override public boolean isItemValid(int slot, @NotNull ItemStack stack) { if (stack == null || stack.isEmpty()) // || stack.getItem() instanceof BasketBlockItem { return false; } else { return super.isItemValid(slot, stack); } } // ########## ########## ########## ########## @Override public void setStackInSlot(int slot, @NotNull ItemStack stack) { //// System.out.println("setStackInSlot(" + slot + ")"); validateSlotIndex(slot); this.stacks.set(slot, stack); onContentsChanged(slot); if (this.container != null) { // write_item_to_slot(this.container, slot, stack); } } // ########## ########## ########## ########## // @Override public static NonNullList<ItemStack> read_items_from(ItemStack itemstack) { NonNullList<ItemStack> contained_items = NonNullList.withSize(9, ItemStack.EMPTY);// this.getContainerSize() if (itemstack.hasTag()) { CompoundTag compoundtag = itemstack.getTag(); ListTag listtag = null; int size = 0; if (compoundtag.contains("Items")) { // ListTag listtag = new ListTag(); listtag = compoundtag.getList("Items", 10); size = listtag.size(); // contained_items = NonNullList.withSize(size, ItemStack.EMPTY); for (int i = 0; i < listtag.size(); ++i) { CompoundTag itemstacktag = listtag.getCompound(i); int j = compoundtag.getByte("Slot") & 255; if (j >= 0 && j < contained_items.size()) { contained_items.set(j, ItemStack.of(itemstacktag)); } } } } return contained_items; } // ########## ########## ########## ########## // @Override public void write_item_to_slot(ItemStack container, int slot, @NotNull ItemStack stack) { // , NonNullList<ItemStack> contained_items CompoundTag compoundtag = null; if (container.hasTag()) { compoundtag = container.getTag(); } else { compoundtag = new CompoundTag(); } ListTag listtag = null; if (compoundtag.contains("Items")) { listtag = compoundtag.getList("Items", 10); } else { listtag = new ListTag(); } CompoundTag itemstacktag = null; if (slot < listtag.size()) { itemstacktag = listtag.getCompound(slot); } else { itemstacktag = new CompoundTag(); } itemstacktag.putByte("Slot", (byte) slot); stack.save(itemstacktag); listtag.add(itemstacktag); // aqui tengi una duda, se sobreescrive o crea otra ?? compoundtag.put("Items", listtag); container.setTag(compoundtag); } // ########## ########## ########## ########## public void save() { if (this.container == null) { System.out.println("\n#this.container is Null at save()#\n"); return; } this.container.setTag(serializeNBT()); } // ########## ########## ########## ########## @Override public CompoundTag serializeNBT() { if (this.start_time > 0L) { this.t1 = System.currentTimeMillis(); if (this.t1 > this.t0) { //System.out.println( this.t1 + " > " + this.t0 ); this.t0 = this.t1; this.t = (int) (t1 - this.start_time) / 50; if (this.t > this.time) { //System.out.println( this.t + " > " + this.time ); this.time = this.t; onUseTick(); if (this.time >= this.limit) { this.time = this.limit; finishUsingItem(); this.stop_time(); } } } } ListTag nbtTagList = new ListTag(); for (int i = 0; i < stacks.size(); i++) { if (!stacks.get(i).isEmpty()) { CompoundTag itemTag = new CompoundTag(); itemTag.putInt("Slot", i); stacks.get(i).save(itemTag); nbtTagList.add(itemTag); } } CompoundTag nbt = new CompoundTag(); nbt.put("Items", nbtTagList); nbt.putInt("Size", stacks.size()); nbt.putLong("start_time", this.start_time); nbt.putInt("time", this.time); nbt.putShort("action", (short) this.action); nbt.putShort("limit", (short) this.limit); nbt.putInt("munition", this.munition); nbt.putInt("type", this.type); nbt.putFloat("fuel", this.fuel); //this.tick = 0; //print("serializeNBT()"); //System.out.println("\n#serializeNBT()#\n"); //onSave(); return nbt; } // ########## ########## ########## ########## public void read() { if (this.container == null) { System.out.println("\n#this.container is Null at read()#\n"); return; } deserializeNBT(this.container.getTag()); } // ########## ########## ########## ########## @Override public void deserializeNBT(CompoundTag nbt) { setSize(nbt.contains("Size", Tag.TAG_INT) ? nbt.getInt("Size") : stacks.size()); ListTag tagList = nbt.getList("Items", Tag.TAG_COMPOUND); for (int i = 0; i < tagList.size(); i++) { CompoundTag itemTags = tagList.getCompound(i); int slot = itemTags.getInt("Slot"); if (slot >= 0 && slot < stacks.size()) { stacks.set(slot, ItemStack.of(itemTags)); } } this.start_time = nbt.getLong("start_time"); this.time = nbt.getInt("time"); this.action = nbt.getShort("action"); this.limit = nbt.getShort("limit"); this.munition = nbt.getInt("munition"); this.fuel = nbt.getFloat("fuel"); this.type = nbt.getInt("type"); //System.out.println( "DeserializeNBT()" ); //print("DeserializeNBT()"); onLoad(); } // ########## ########## ########## ########## public void onUseTick() { System.out.println("this.time = " + this.time); this.tick ++; } // ########## ########## ########## ########## public void finishUsingItem() { System.out.println("onlimit = " + this.time); } // ########## ########## ########## ########## ########## ########## // ########## ########## ########## ########## ########## ########## // ########## ########## ########## ########## ########## ########## // ########## ########## ########## ########## ########## ########## }
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.