Need help finding a workaround for a respawn issue. I have a plugin (SpawnControl) that needs to intercept player respawns on death. Intercepting onPlayerTeleport seems like it would be the best way to do this, but I can't get it to work. Specifically, I'm encountering a few issues that have stymied any attempt to halt or redirect the respawn: The teleport event cannot be cancelled (you can call setCancelled, but it doesn't do anything) Modifying the 'to' portion of the event does nothing Teleporting the player during the respawn teleport event incurs the wrath of PLAYER MOVED WRONGLY (which I would expect, since the initial event has not been cancelled) When I built this plugin in hMod, I ended up using the onHealthChange event, because the player's health is changed from <= 0 to > 0 after the respawn has been completed. This was a very reliable method for detecting a player respawn. This event is either unavailable in Bukkit or I can't find it. Is anyone aware of a good workaround for any of these issues? I could probably spawn another thread, wait a second, and then teleport the player, but that seems error-prone and ugly in the extreme.
No, spawn them at the SpawnControl spawn (or user home). ENTITY_DEATH can't be used for this because the server will just respawn them normally after anything you do in the ENTITY_DEATH event.
use onEntityDamage, check if its a player, check if health is less or equal to than 0 and do your magic.
Also doesn't work. ENTITY_DAMAGED is only triggered when the player takes damage, not when health is restored. So you get the event that killed them, but you don't get the post-respawn health restoration, which is where you need to be to successfully teleport them. Thanks for the suggestions, btw. I don't want to sound too negative, this problem just seems to be a brick wall.
Make a timer that checks if player is less than >0 health, add the player to an array list and check when their health is more than 1?
Yeah, I'm thinking I may have to do something like that. It's the ugly solution I mentioned in the OP, but it would work. The other ugly workaround I'm considering is cancelling the damage event outright, then manually dropping the player's inventory and teleporting them to spawn. They wouldn't get the death cam, so it could be a bit jarring, but it would be a more direct way of handling the situation.
Timberjaw, I'm also working on this. Right now I had an idea to run it during the next onPlayerMove() after onEntityDeath(). Keep track of the fact they died. Worst case, they will respawn normally, then try to move. At that point, you do what you needed to.
Yeah, this would probably work. It might confuse the player a bit since they'd find themselves at regular spawn for a moment, take one step, then get teleported across the world. I'm leaning towards cancelling the death/damage event, manually dumping their items, and then teleporting them. It skips the death screen, but it doesn't require any other weirdness and it results in 1 teleport total instead of 2.
Actually, when you respawn most times the onPlayerMove is already called. The only problem I'm getting is [WARNING] azoundria moved wrongly, since you apparently can't teleport in the middle of onPlayerMove. But other than that it works fairly decently.
like I posted in the other thread, use event.setFrom(block.getLocation()); (obviously set the location to where you want to teleport to) so you dont get those errors.
I think I tried this earlier with no success. You mean I should setFrom(player's destination), right?
Don't know if this can help you or not, but I noticed while trying to debug some problems with my plugin, you trigger FALL damage right after you spawn. So what if you wait until someone triggered ENTITY_DEATH and then wait for that same player to trigger the FALL damage, then teleport them? May not work, but it's worth a shot.
The solution to this nowadays is to use the event: @Override public void onPlayerRespawn(PlayerRespawnEvent event) { // TODO Auto-generated method stub super.onPlayerRespawn(event); }