Fixed player death animation

This commit is contained in:
Felix Cravic 2020-05-25 19:54:36 +02:00
parent c15a795a74
commit a962b83958
4 changed files with 65 additions and 48 deletions

View File

@ -43,6 +43,8 @@ public abstract class EntityCreature extends LivingEntity {
this.chestplate = ItemStack.getAirItem();
this.leggings = ItemStack.getAirItem();
this.boots = ItemStack.getAirItem();
heal();
}
@Override

View File

@ -116,6 +116,7 @@ public abstract class LivingEntity extends Entity implements EquipmentHandler {
return packet -> {
super.getMetadataConsumer().accept(packet);
fillMetadataIndex(packet, 7);
fillMetadataIndex(packet, 8);
// TODO all remaining metadata
};
@ -136,6 +137,10 @@ public abstract class LivingEntity extends Entity implements EquipmentHandler {
activeHandValue += 4;
}
packet.writeByte(activeHandValue);
} else if (index == 8) {
packet.writeByte((byte) 8);
packet.writeByte(METADATA_FLOAT);
packet.writeFloat(health);
}
}
@ -240,6 +245,7 @@ public abstract class LivingEntity extends Entity implements EquipmentHandler {
if (this.health <= 0 && !isDead) {
kill();
}
sendMetadataIndex(8); // Health metadata index
}
public float getMaxHealth() {

View File

@ -86,6 +86,9 @@ public class Player extends LivingEntity {
private long eatingTime;
private boolean isEating;
// Game state (https://wiki.vg/Protocol#Change_Game_State)
private boolean enableRespawnScreen;
// CustomBlock break delay
private CustomBlock targetCustomBlock;
private BlockPosition targetBlockPosition;
@ -161,8 +164,8 @@ public class Player extends LivingEntity {
final float y = 0;
final float z = 0;
refreshDimension(dimension);
refreshGameMode(gameMode);
this.dimension = dimension;
this.gameMode = gameMode;
refreshLevelType(levelType);
refreshPosition(x, y, z);
@ -424,6 +427,26 @@ public class Player extends LivingEntity {
super.kill();
}
public void respawn() {
if (!isDead())
return;
setFireForDuration(0);
setOnFire(false);
refreshHealth();
RespawnPacket respawnPacket = new RespawnPacket();
respawnPacket.dimension = getDimension();
respawnPacket.gameMode = getGameMode();
respawnPacket.levelType = getLevelType();
getPlayerConnection().sendPacket(respawnPacket);
PlayerRespawnEvent respawnEvent = new PlayerRespawnEvent(getRespawnPoint());
callEvent(PlayerRespawnEvent.class, respawnEvent);
refreshIsDead(false);
// Runnable called when teleportation is successful (after loading and sending necessary chunk)
teleport(respawnEvent.getRespawnPosition(), this::refreshAfterTeleport);
}
@Override
public void spawn() {
@ -748,6 +771,33 @@ public class Player extends LivingEntity {
this.defaultEatingTime = defaultEatingTime;
}
/**
* Used to change the player gamemode
*
* @param gameMode the new player gamemode
*/
public void setGameMode(GameMode gameMode) {
Check.notNull(gameMode, "GameMode cannot be null");
this.gameMode = gameMode;
sendChangeGameStatePacket(ChangeGameStatePacket.Reason.CHANGE_GAMEMODE, gameMode.getId());
}
public boolean isEnableRespawnScreen() {
return enableRespawnScreen;
}
public void setEnableRespawnScreen(boolean enableRespawnScreen) {
this.enableRespawnScreen = enableRespawnScreen;
sendChangeGameStatePacket(ChangeGameStatePacket.Reason.ENABLE_RESPAWN_SCREEN, enableRespawnScreen ? 0 : 1);
}
private void sendChangeGameStatePacket(ChangeGameStatePacket.Reason reason, float value) {
ChangeGameStatePacket changeGameStatePacket = new ChangeGameStatePacket();
changeGameStatePacket.reason = reason;
changeGameStatePacket.value = value;
playerConnection.sendPacket(changeGameStatePacket);
}
/**
* @param item the item to drop
* @return true if player can drop the item (event not cancelled), false otherwise
@ -777,26 +827,6 @@ public class Player extends LivingEntity {
this.respawnPoint = respawnPoint;
}
public void respawn() {
if (!isDead())
return;
setFireForDuration(0);
setOnFire(false);
refreshHealth();
RespawnPacket respawnPacket = new RespawnPacket();
respawnPacket.dimension = getDimension();
respawnPacket.gameMode = getGameMode();
respawnPacket.levelType = getLevelType();
getPlayerConnection().sendPacket(respawnPacket);
PlayerRespawnEvent respawnEvent = new PlayerRespawnEvent(getRespawnPoint());
callEvent(PlayerRespawnEvent.class, respawnEvent);
refreshIsDead(false);
// Runnable called when teleportation is successful (after loading and sending necessary chunk)
teleport(respawnEvent.getRespawnPosition(), this::refreshAfterTeleport);
}
public void refreshAfterTeleport() {
getInventory().update();
@ -975,7 +1005,7 @@ public class Player extends LivingEntity {
Check.notNull(dimension, "Dimension cannot be null!");
Check.argCondition(dimension.equals(getDimension()), "The dimension need to be different than the current one!");
refreshDimension(dimension);
this.dimension = dimension;
RespawnPacket respawnPacket = new RespawnPacket();
respawnPacket.dimension = dimension;
respawnPacket.gameMode = gameMode;
@ -998,20 +1028,6 @@ public class Player extends LivingEntity {
return levelType;
}
/**
* Used to change the player gamemode
*
* @param gameMode the new player gamemode
*/
public void setGameMode(GameMode gameMode) {
Check.notNull(gameMode, "GameMode cannot be null");
ChangeGameStatePacket changeGameStatePacket = new ChangeGameStatePacket();
changeGameStatePacket.reason = ChangeGameStatePacket.Reason.CHANGE_GAMEMODE;
changeGameStatePacket.value = gameMode.getId();
playerConnection.sendPacket(changeGameStatePacket);
refreshGameMode(gameMode);
}
/**
* Change the current held slot for the player
*
@ -1340,14 +1356,6 @@ public class Player extends LivingEntity {
sendPacketToViewersAndSelf(playerInfoPacket);
}
public void refreshDimension(Dimension dimension) {
this.dimension = dimension;
}
public void refreshGameMode(GameMode gameMode) {
this.gameMode = gameMode;
}
public void refreshLevelType(LevelType levelType) {
this.levelType = levelType;
}

View File

@ -36,7 +36,7 @@ public class DamageType {
}
public Component buildChatMessage(Player killed) {
return TranslatableComponent.of("death."+identifier, TextComponent.of(killed.getUsername()));
return TranslatableComponent.of("death." + identifier, TextComponent.of(killed.getUsername()));
}
public static DamageType fromPlayer(Player player) {
@ -49,12 +49,13 @@ public class DamageType {
/**
* Sound event to play when the given entity is hit by this damage. Possible to return null if no sound should be played
*
* @param entity the entity hit by this damage
* @return the sound to play when the given entity is hurt by this damage type. Can be null if no sound should play
*/
public Sound getSound(LivingEntity entity) {
if(entity instanceof Player) {
return getPlayerSound((Player)entity);
if (entity instanceof Player) {
return getPlayerSound((Player) entity);
}
return getGenericSound(entity);
}