Jump to content

[1.8.9]How to tell when an item is removed from the players inventory?


Recommended Posts

Posted

You can't.

 

No.

 

No, not even then.

 

No, you can't.  Its impossible.  There are so many ways an item can leave the player's inventory that you cannot know that it even has as some of them don't fire any sort of event or notification to any other system that it has removed the item.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Posted

ItemDropEvent

and no.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Posted

Hmm I'm not sure if you understand what I meant because I just used ItemTossEvent and that:

 

* Event that is fired whenever a player tosses (Q) an item or drag-n-drops a

* stack of items outside the inventory GUI screens. Canceling the event will

* stop the items from entering the world, but will not prevent them being

* removed from the inventory - and thus removed from the system.

 

However the throwing outside the player gui works but the dropping on the ground only works on one side and i need it on both client and server.

BioWarfare Mod: http://goo.gl/BYWQty

Posted

If you are familiar with the mod baubles it is an api that allows you to add "rings" and "amulets". I am calling the methods that these items use when they need to be activated if they are in my custom inventory. But i need to turn these attributes off if the item inventory is removed from the players inventory.

TickHandler


public class TatEventHandler {

@SubscribeEvent
public void PlayerEvent(PlayerEvent event) {

	EntityPlayer player = event.entityPlayer;

	if (player instanceof EntityPlayer) {
		if (player.isDead) {
			for (int a = 0; a < player.inventory.mainInventory.length; a++) {
				if (player.inventory.getStackInSlot(a) == new ItemStack(TatItems.itemBaublesBag)) {
					ItemStack baublesbag = player.inventory.getStackInSlot(a);
					InventoryBaublesBag inventorybaublesbag = (InventoryBaublesBag) BaublesBag.getInventory(baublesbag, player);
					for (int b = 0; b < inventorybaublesbag.inventory.length; b++) {
						if (inventorybaublesbag.getStackInSlot(b) != null && inventorybaublesbag.getStackInSlot(b).getItem() instanceof IBauble) {
							((IBauble) inventorybaublesbag.getStackInSlot(b).getItem()).onUnequipped(inventorybaublesbag.getStackInSlot(b), player);

						}
					}

				}
			}

		}
	}
}

@SubscribeEvent
public void ItemTossEvent(ItemTossEvent event) {
	EntityPlayer player = event.player;
	if (event.entityItem.getEntityItem().getItem() == TatItems.itemBaublesBag) {
		ItemStack baublesbag = event.entityItem.getEntityItem();
		InventoryBaublesBag inventorybaublesbag = (InventoryBaublesBag) BaublesBag.getInventory(baublesbag, player);
		for (int a = 0; a < inventorybaublesbag.inventory.length; a++) {
			if (inventorybaublesbag.getStackInSlot(a) != null && inventorybaublesbag.getStackInSlot(a).getItem() instanceof IBauble) {
				((IBauble) inventorybaublesbag.getStackInSlot(a).getItem()).onUnequipped(inventorybaublesbag.getStackInSlot(a), player);


			}
		}
	}
}

}

BioWarfare Mod: http://goo.gl/BYWQty

Posted

Yes I do that but their inventory is not an item inventory and so I need to make sure when the player dies (which ive done) or when the player tosses the item that the unequipped method is called.Becasue decrStackSize does not get called when this happens.

BioWarfare Mod: http://goo.gl/BYWQty

Posted

When you're done, try shoving your item into an Item Frame.

 

Good luck solving that.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Posted

When you're done, try shoving your item into an Item Frame.

 

Good luck solving that.

Very good point. Not to mention every other mod that takes the item out of the players inventory. Is there anyway to tell when the items stacksize has been decreased?Otherwise I may have to use a different approach with this whole thing but for now il continue on.

 

Use a debugger to find out what is happening. From what I can see the code paths for "press q" and "drop item outside inventory" are the same thing.

 

Well I thought it was a server client issue because throwing the item didn't stop my flight but i still took damage and so with this:

@SubscribeEvent
public void ItemTossEvent(ItemTossEvent event) {
	EntityPlayer player = event.player;
	if (event.entityItem.getEntityItem().getItem() == TatItems.itemBaublesBag) {
		ItemStack baublesbag = event.entityItem.getEntityItem();
		InventoryBaublesBag inventorybaublesbag = (InventoryBaublesBag) BaublesBag.getInventory(baublesbag, player);
		for (int a = 0; a < inventorybaublesbag.inventory.length; a++) {
			if (inventorybaublesbag.getStackInSlot(a) != null && inventorybaublesbag.getStackInSlot(a).getItem() instanceof IBauble) {
				if(player.worldObj.isRemote){
					System.out.println("client");
				}
				if(!player.worldObj.isRemote){
					System.out.println("server");
				}
				((IBauble) inventorybaublesbag.getStackInSlot(a).getItem()).onUnequipped(inventorybaublesbag.getStackInSlot(a), player);


			}
		}
	}
}

Putting the item outside the inventory prints both client and server whereas pressing "q" only prints server. So I think I am right in saying I need to send a packet from the server to the client then? Not an expert.

BioWarfare Mod: http://goo.gl/BYWQty

Posted

When you're done, try shoving your item into an Item Frame.

 

Good luck solving that.

Very good point. Not to mention every other mod that takes the item out of the players inventory. Is there anyway to tell when the items stacksize has been decreased?Otherwise I may have to use a different approach with this whole thing but for now il continue on.

 

As I said, there is NO event, NO notification, NO function that is called when this occurs.  The item stack's direct property object

stacksize

is decremented.  You can't even ASM that.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Posted

I am here just to reassure (second others) you that tracking items (itemstacks) in: inventories (mobs, players, blocks) and world itself - while possible for some of those parties - will NEVER be fully safe/working. It is simply impossible to do that using any standard approach.

 

As to non-standard apporach - it won't end well (been there, done that), and again will never be "exact" and safe.

 

You can only track few things about items, but not all.

1.7.10 is no longer supported by forge, you are on your own.

Posted

I'm confused as to why you are going about things the way your are ...

 

It sounds like you have a bauble that gives the user some buff as long as they have some other "fuel" item in their inventory.

Can't you achieve what you want by using the baubles ontick event. Every x ticks look at the players inventory and if they have the item, give the buff for x ticks. If they don't have the item then the buff won't get refreshed.

Current Project: Armerger 

Planned mods: Light Drafter  | Ore Swords

Looking for help getting a mod off the ground? Coding  | Textures

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.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • Version 1.19 - Forge 41.0.63 I want to create a wolf entity that I can ride, so far it seems to be working, but the problem is that when I get on the wolf, I can’t control it. I then discovered that the issue is that the server doesn’t detect that I’m riding the wolf, so I’m struggling with synchronization. However, it seems to not be working properly. As I understand it, the server receives the packet but doesn’t register it correctly. I’m a bit new to Java, and I’ll try to provide all the relevant code and prints *The comments and prints are translated by chatgpt since they were originally in Spanish* Thank you very much in advance No player is mounted, or the passenger is not a player. No player is mounted, or the passenger is not a player. No player is mounted, or the passenger is not a player. No player is mounted, or the passenger is not a player. No player is mounted, or the passenger is not a player. MountableWolfEntity package com.vals.valscraft.entity; import com.vals.valscraft.network.MountSyncPacket; import com.vals.valscraft.network.NetworkHandler; import net.minecraft.client.Minecraft; import net.minecraft.network.syncher.EntityDataAccessor; import net.minecraft.network.syncher.EntityDataSerializers; import net.minecraft.network.syncher.SynchedEntityData; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.Mob; import net.minecraft.world.entity.ai.attributes.AttributeSupplier; import net.minecraft.world.entity.ai.attributes.Attributes; import net.minecraft.world.entity.animal.Wolf; import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.Entity; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import net.minecraft.world.level.Level; import net.minecraft.world.phys.Vec3; import net.minecraftforge.event.TickEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.network.PacketDistributor; public class MountableWolfEntity extends Wolf { private boolean hasSaddle; private static final EntityDataAccessor<Byte> DATA_ID_FLAGS = SynchedEntityData.defineId(MountableWolfEntity.class, EntityDataSerializers.BYTE); public MountableWolfEntity(EntityType<? extends Wolf> type, Level level) { super(type, level); this.hasSaddle = false; } @Override protected void defineSynchedData() { super.defineSynchedData(); this.entityData.define(DATA_ID_FLAGS, (byte)0); } public static AttributeSupplier.Builder createAttributes() { return Wolf.createAttributes() .add(Attributes.MAX_HEALTH, 20.0) .add(Attributes.MOVEMENT_SPEED, 0.3); } @Override public InteractionResult mobInteract(Player player, InteractionHand hand) { ItemStack itemstack = player.getItemInHand(hand); if (itemstack.getItem() == Items.SADDLE && !this.hasSaddle()) { if (!player.isCreative()) { itemstack.shrink(1); } this.setSaddle(true); return InteractionResult.SUCCESS; } else if (!level.isClientSide && this.hasSaddle()) { player.startRiding(this); MountSyncPacket packet = new MountSyncPacket(true); // 'true' means the player is mounted NetworkHandler.CHANNEL.sendToServer(packet); // Ensure the server handles the packet return InteractionResult.SUCCESS; } return InteractionResult.PASS; } @Override public void travel(Vec3 travelVector) { if (this.isVehicle() && this.getControllingPassenger() instanceof Player) { System.out.println("The wolf has a passenger."); System.out.println("The passenger is a player."); Player player = (Player) this.getControllingPassenger(); // Ensure the player is the controller this.setYRot(player.getYRot()); this.yRotO = this.getYRot(); this.setXRot(player.getXRot() * 0.5F); this.setRot(this.getYRot(), this.getXRot()); this.yBodyRot = this.getYRot(); this.yHeadRot = this.yBodyRot; float forward = player.zza; float strafe = player.xxa; if (forward <= 0.0F) { forward *= 0.25F; } this.flyingSpeed = this.getSpeed() * 0.1F; this.setSpeed((float) this.getAttributeValue(Attributes.MOVEMENT_SPEED) * 1.5F); this.setDeltaMovement(new Vec3(strafe, travelVector.y, forward).scale(this.getSpeed())); this.calculateEntityAnimation(this, false); } else { // The wolf does not have a passenger or the passenger is not a player System.out.println("No player is mounted, or the passenger is not a player."); super.travel(travelVector); } } public boolean hasSaddle() { return this.hasSaddle; } public void setSaddle(boolean hasSaddle) { this.hasSaddle = hasSaddle; } @Override protected void dropEquipment() { super.dropEquipment(); if (this.hasSaddle()) { this.spawnAtLocation(Items.SADDLE); this.setSaddle(false); } } @SubscribeEvent public static void onServerTick(TickEvent.ServerTickEvent event) { if (event.phase == TickEvent.Phase.START) { MinecraftServer server = net.minecraftforge.server.ServerLifecycleHooks.getCurrentServer(); if (server != null) { for (ServerPlayer player : server.getPlayerList().getPlayers()) { if (player.isPassenger() && player.getVehicle() instanceof MountableWolfEntity) { MountableWolfEntity wolf = (MountableWolfEntity) player.getVehicle(); System.out.println("Tick: " + player.getName().getString() + " is correctly mounted on " + wolf); } } } } } private boolean lastMountedState = false; @Override public void tick() { super.tick(); if (!this.level.isClientSide) { // Only on the server boolean isMounted = this.isVehicle() && this.getControllingPassenger() instanceof Player; // Only print if the state changed if (isMounted != lastMountedState) { if (isMounted) { Player player = (Player) this.getControllingPassenger(); // Verify the passenger is a player System.out.println("Server: Player " + player.getName().getString() + " is now mounted."); } else { System.out.println("Server: The wolf no longer has a passenger."); } lastMountedState = isMounted; } } } @Override public void addPassenger(Entity passenger) { super.addPassenger(passenger); if (passenger instanceof Player) { Player player = (Player) passenger; if (!this.level.isClientSide && player instanceof ServerPlayer) { // Send the packet to the server to indicate the player is mounted NetworkHandler.CHANNEL.send(PacketDistributor.PLAYER.with(() -> (ServerPlayer) player), new MountSyncPacket(true)); } } } @Override public void removePassenger(Entity passenger) { super.removePassenger(passenger); if (passenger instanceof Player) { Player player = (Player) passenger; if (!this.level.isClientSide && player instanceof ServerPlayer) { // Send the packet to the server to indicate the player is no longer mounted NetworkHandler.CHANNEL.send(PacketDistributor.PLAYER.with(() -> (ServerPlayer) player), new MountSyncPacket(false)); } } } @Override public boolean isControlledByLocalInstance() { Entity entity = this.getControllingPassenger(); return entity instanceof Player; } @Override public void positionRider(Entity passenger) { if (this.hasPassenger(passenger)) { double xOffset = Math.cos(Math.toRadians(this.getYRot() + 90)) * 0.4; double zOffset = Math.sin(Math.toRadians(this.getYRot() + 90)) * 0.4; passenger.setPos(this.getX() + xOffset, this.getY() + this.getPassengersRidingOffset() + passenger.getMyRidingOffset(), this.getZ() + zOffset); } } } MountSyncPacket package com.vals.valscraft.network; import com.vals.valscraft.entity.MountableWolfEntity; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; import net.minecraftforge.network.NetworkEvent; import java.util.function.Supplier; public class MountSyncPacket { private final boolean isMounted; public MountSyncPacket(boolean isMounted) { this.isMounted = isMounted; } public void encode(FriendlyByteBuf buffer) { buffer.writeBoolean(isMounted); } public static MountSyncPacket decode(FriendlyByteBuf buffer) { return new MountSyncPacket(buffer.readBoolean()); } public void handle(NetworkEvent.Context context) { context.enqueueWork(() -> { ServerPlayer player = context.getSender(); // Get the player from the context if (player != null) { // Verifies if the player has dismounted if (!isMounted) { Entity vehicle = player.getVehicle(); if (vehicle instanceof MountableWolfEntity wolf) { // Logic to remove the player as a passenger wolf.removePassenger(player); System.out.println("Server: Player " + player.getName().getString() + " is no longer mounted."); } } } }); context.setPacketHandled(true); // Marks the packet as handled } } networkHandler package com.vals.valscraft.network; import com.vals.valscraft.valscraft; import net.minecraft.resources.ResourceLocation; import net.minecraftforge.network.NetworkRegistry; import net.minecraftforge.network.simple.SimpleChannel; import net.minecraftforge.network.NetworkEvent; import java.util.function.Supplier; public class NetworkHandler { private static final String PROTOCOL_VERSION = "1"; public static final SimpleChannel CHANNEL = NetworkRegistry.newSimpleChannel( new ResourceLocation(valscraft.MODID, "main"), () -> PROTOCOL_VERSION, PROTOCOL_VERSION::equals, PROTOCOL_VERSION::equals ); public static void init() { int packetId = 0; // Register the mount synchronization packet CHANNEL.registerMessage( packetId++, MountSyncPacket.class, MountSyncPacket::encode, MountSyncPacket::decode, (msg, context) -> msg.handle(context.get()) // Get the context with context.get() ); } }  
    • Do you use features of inventory profiles next (ipnext) or is there a change without it?
    • Remove rubidium - you are already using embeddium, which is a fork of rubidium
  • Topics

×
×
  • Create New...

Important Information

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