Carpet

Carpet

2M Downloads

Setting a player's inventory in the __on_player_respawns event doesn't work

Xendergo opened this issue ยท 5 comments

commented

Doing this doesn't do anything:

__on_player_respawns(player)->(
   inventory_set(player, 0, 64, 'dirt');
);

If you were to schedule a tick, the items would appear in the player's inventory, but if the player is in survival, the items would disappear when the player clicks on the item or tries to place the item.

__on_player_respawns(player)->(
  schedule(1, 'giveItem', player);
);

giveItem(player) -> (
  inventory_set(player, 0, 64, 'dirt'); // Item doesn't really exist
);

If anyone else is having this problem, doing this works for me:

__on_player_respawns(player)->(
  schedule(1, 'giveItem', player);
);

giveItem(player) -> (
  inventory_set(player(player ~ 'name'), 0, 64, 'dirt');
);
commented

try this?

__on_player_respawns(player)->(
  schedule(1, _(outer(player))->giveItem(player));
);
commented

Fixed it in local. Meanwhile, as another, more inline and faster workaround until this is fixed you can also use:

__on_player_respawns(player) -> (
  schedule(0, _(outer(player)) -> (
    inventory_set(player(player ~ 'name'), 0, 64, 'dirt');
  ));
);

Here the schedule is 0, so it runs at the end of the same tick. The workaround of reassigning the player still needs to be used for some reason. You can also use Ghoulboy's workaround (also works with schedule 0) if you prefer not to reassign it, depending on whether you prefer it inline or not.

commented

You can test the fix by getting the PR build artifacts from here.

commented

That seems to work! I'm surprised it's such a simple fix

commented

its actually changes the intended behaviour, and changes rather massively, since the intention for events is to catch them right at when they happen not right after.

The problem in this case is that game actually replaces player entity with a new one for some unknown reason (doesn't do that with dimension change for example, so that's not the problem of changing the world). And while replacing it, it even copies previous player id, which is even wierder.

Also inventory is copied only with keep-inventory rule set or when the reason of respawn is not death (returning from the end), so your inventory actions will work in these cases.

Its rather unfortunate that it happens this way, but I would rather pass player name instead (to the event), making a clear note in the docs that any manipulations of the player object is gonna be lost, unless its a player scoped app, in that case you don't need to pass the player object.

I would rather explain all these cases and break the previous event signature, then changing the event to post.

for now, especially if you made a default, player scoped app, this solves the problem:

__on_player_respawns(player) -> 
(
   schedule(0, _() -> inventory_set(player(), 0, 64, 'stone'));
);