[Solved] How to save the player's inventory at death in HashMap and load it at respawn?

How do I implement this functionality? I wanted to add an inventory saving function for players with privileges. We need the code for the plugin. I try to write on my own, but I still can not make a working version.

Prevent/cancel the drops, and give them directly to the dead player, it will clone their inventory on respawn. No hashmap needed.

If you need further help, Show us what you have tried.

Is this a proper check on the player’s health?

if (player.getHealthData().health().exists()) {
…
}

And I do not understand how to return the player his inventory. Even if I cancel the throwing out of things, then at death they in any case fall out.

  1. Are you aware of /gamerule keepInventory true
  2. I would have expected
@Listener
    public void onDestructEntityDeath(final DropItemEvent.Destruct event, @Root Player player) {
        event.filterEntities((e)->true);
    }

to work,
Also this

@Listener
    public void onDestructEntityDeath(final DropItemEvent.Destruct event, @Root Player player) {
        event.setCancelled(true);
    }

I do not need to keep inventory for all players. Players without privileges must lose items as before. I’m trying to make a plugin similar to this one.

Then add some permission checking logic before modifying the event.

Always stores the player’s inventory, even if he does not have the privilege.
Are you offering me to clean inventory from players without the privilege? This option does not suit me. At the death of a player without privilege, his items must fall to the ground.

No, I was merely trying to make sure you were aware.

I didn’t understand what you meant by privileges at first.

I also don’t understand why you were checking health.

Did either of the two sample listeners I have work? Can you show us what you have tried?

I can save the player’s inventory with this code. But there is still need to add a test for the health of the player. The problem I’m having is if I try to load inventory, or nothing happens, or I get an error in the console and the player does not get their stuff items.

static HashMap <Player, Inventory> inv = new HashMap<Player, Inventory>();

@Listener
public void onDestructEntityDeath(final DropItemEvent.Pre event,
		@Root Player player) {
	if (player.hasPermission("inventory.save")){
		event.setCancelled(true);
		inv.put(player, player.getInventory());
	}
}

Tell me how to give the player his things. I do not understand how. Here is my code.

@Listener
	public void onPlayerRespawn(RespawnPlayerEvent event,
			@Root Player player) {
		if (player.hasPermission("inventory.save")){
		player.getInventory().equals(inv);
		}
	}

First of all: equals() does check if two objects are equal, and does not make them equal. That’s a basic method in java, and let me tell you: It will be really difficult to work with sponge without understanding e.g the difference between equals(), ==, and =.

Now to your problem: instead of equals() you could use player.getInventory().put(inv); to restore, but i doubt that this is really what you want to do… (Edit: Nope, i misunderstood sth., that wont work xd)
Instead of all this, you should just listen to @ryantheleach’s suggestion and - instead of saving and restoring - just prevent the item-dropping. :slight_smile:

I’ve already done to prevent loss of an item by means of changing the rules of the game. Although this decision is not entirely correct, it should help.

I did not meant his suggestion to change the gamerule but his function:

@Listener
public void onDestructEntityDeath(final DropItemEvent.Destruct event, @Root Player player) {
    if (player.hasPermission("inventory.save")){
        event.setCancelled(true);
    }
}

i even added the permission check for you

I made it easier through DestructEntityEvent.Death and RespawnPlayerEvent. I also used timers to prevent possible malfunctions.

Then what is your problem?

The problem was yesterday, today I found a solution.

Using timers seems error prone to me…

You should be able to give/cancel the inventory drops straight back to the dead player. the inventory gets copied on respawn from the dead player, just that it’s normally cleared already.

Anyway, if you have the solution I’d like to see it.

I used the death events of the essence and respawn of the player.
When the player dies with the right to save things, this code is activated.

 if (player.hasPermission("beancore.inventory.save")) {
	world.getProperties().setGameRule("keepInventory", "true");
	player.sendMessage(Text.of(prefix, invsave));
	Sponge.getServer().getConsole().sendMessage(Text.of(prefix, invsave, " ", player.getName()));
	}

When the player is respawned, the following code is used.

    if (player.hasPermission("beancore.inventory.save")) {
		world.getProperties().setGameRule("keepInventory", "true");
		    	try {
		    		  Thread.sleep(10L);
		    		} catch(InterruptedException ie) {
		    	}
		    	world.getProperties().setGameRule("keepInventory", "false");
		} else {
		    	world.getProperties().setGameRule("keepInventory", "false");
		}

I use the timer to prevent malfunctions.

No! No no no! This is an absolutely terrible idea! Calling Thread.sleep on the main server thread is going to freeze up the entire server, and it’s something that should never be attempted. Setting the gamerule like this is also a really bad idea as it’s prone to all kinds of mistakes - for example, what happens if two players die at the same time?

It’s been said already that you should be working directly with the player’s inventory and the drops as a result of the player’s death. I would think you’d be able to do this working only with the death event, so use the suggestions given above by others.

2 Likes

When I try to block the loss of things from the player’s inventory, depending on the event chosen, either there is no change, or the player can not throw the item at all. And at respawn inventory cleaned anyway. With such a small delay, I do not have any problems, besides, it minimizes the likelihood of various bugs. A bug can occur only if 2 different players die and respawn at the same time, and the probability of such an event is almost zero.

If necessary, the delay can be reduced or another method can be used to restore the default game rule parameter, that’s what I am currently working on. I tried to keep the player’s inventory when here died in HashMap, but I can not load it after that.

I apologize for my English, I use Google translator.

Using Java methods, you can create a separate thread and execute the code I wrote above, personally I already use one such method.