mirror of
https://github.com/Minestom/Minestom.git
synced 2024-09-27 14:13:24 +02:00
Improvement for the DamageType code
This commit is contained in:
parent
c7f8ae7536
commit
47677766ca
@ -567,6 +567,7 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Each entity has an unique id which will change after a restart.
|
* Each entity has an unique id which will change after a restart.
|
||||||
|
* <p>
|
||||||
* All entities can be retrieved by calling {@link Entity#getEntity(int)}.
|
* All entities can be retrieved by calling {@link Entity#getEntity(int)}.
|
||||||
*
|
*
|
||||||
* @return the unique entity id
|
* @return the unique entity id
|
||||||
@ -576,18 +577,18 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the entity type id, can convert using {@link EntityType#fromId(int)}.
|
* Returns the entity type.
|
||||||
*
|
*
|
||||||
* @return the entity type id
|
* @return the entity type
|
||||||
*/
|
*/
|
||||||
public EntityType getEntityType() {
|
public EntityType getEntityType() {
|
||||||
return entityType;
|
return entityType;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the entity UUID.
|
* Gets the entity {@link UUID}.
|
||||||
*
|
*
|
||||||
* @return the entity UUID
|
* @return the entity unique id
|
||||||
*/
|
*/
|
||||||
public UUID getUuid() {
|
public UUID getUuid() {
|
||||||
return uuid;
|
return uuid;
|
||||||
@ -634,7 +635,7 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convenience method to get the entity current chunk
|
* Convenient method to get the entity current chunk.
|
||||||
*
|
*
|
||||||
* @return the entity chunk
|
* @return the entity chunk
|
||||||
*/
|
*/
|
||||||
@ -810,7 +811,7 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Entity statuses can be find <a href="https://wiki.vg/Entity_statuses">here</a>.
|
* Entity statuses can be found <a href="https://wiki.vg/Entity_statuses">here</a>.
|
||||||
*
|
*
|
||||||
* @param status the status to trigger
|
* @param status the status to trigger
|
||||||
*/
|
*/
|
||||||
|
@ -20,6 +20,7 @@ import net.minestom.server.sound.SoundCategory;
|
|||||||
import net.minestom.server.utils.Position;
|
import net.minestom.server.utils.Position;
|
||||||
import net.minestom.server.utils.binary.BinaryWriter;
|
import net.minestom.server.utils.binary.BinaryWriter;
|
||||||
import net.minestom.server.utils.time.TimeUnit;
|
import net.minestom.server.utils.time.TimeUnit;
|
||||||
|
import net.minestom.server.utils.validate.Check;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
@ -228,6 +229,7 @@ public abstract class LivingEntity extends Entity implements EquipmentHandler {
|
|||||||
*
|
*
|
||||||
* @param duration duration of the effect
|
* @param duration duration of the effect
|
||||||
* @param unit unit used to express the duration
|
* @param unit unit used to express the duration
|
||||||
|
* @see #setOnFire(boolean) if you want it to be permanent without any event callback
|
||||||
*/
|
*/
|
||||||
public void setFireForDuration(int duration, TimeUnit unit) {
|
public void setFireForDuration(int duration, TimeUnit unit) {
|
||||||
EntityFireEvent entityFireEvent = new EntityFireEvent(this, duration, unit);
|
EntityFireEvent entityFireEvent = new EntityFireEvent(this, duration, unit);
|
||||||
@ -235,7 +237,7 @@ public abstract class LivingEntity extends Entity implements EquipmentHandler {
|
|||||||
// Do not start fire event if the fire needs to be removed (< 0 duration)
|
// Do not start fire event if the fire needs to be removed (< 0 duration)
|
||||||
if (duration > 0) {
|
if (duration > 0) {
|
||||||
callCancellableEvent(EntityFireEvent.class, entityFireEvent, () -> {
|
callCancellableEvent(EntityFireEvent.class, entityFireEvent, () -> {
|
||||||
long fireTime = entityFireEvent.getFireTime(TimeUnit.MILLISECOND);
|
final long fireTime = entityFireEvent.getFireTime(TimeUnit.MILLISECOND);
|
||||||
setOnFire(true);
|
setOnFire(true);
|
||||||
fireExtinguishTime = System.currentTimeMillis() + fireTime;
|
fireExtinguishTime = System.currentTimeMillis() + fireTime;
|
||||||
});
|
});
|
||||||
@ -245,13 +247,14 @@ public abstract class LivingEntity extends Entity implements EquipmentHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Damage the entity by a value, the type of the damage also has to be specified
|
* Damages the entity by a value, the type of the damage also has to be specified.
|
||||||
*
|
*
|
||||||
* @param type the damage type
|
* @param type the damage type
|
||||||
* @param value the amount of damage
|
* @param value the amount of damage
|
||||||
* @return true if damage has been applied, false if it didn't
|
* @return true if damage has been applied, false if it didn't
|
||||||
*/
|
*/
|
||||||
public boolean damage(DamageType type, float value) {
|
public boolean damage(DamageType type, float value) {
|
||||||
|
Check.notNull(type, "The damage type cannot be null!o");
|
||||||
if (isDead())
|
if (isDead())
|
||||||
return false;
|
return false;
|
||||||
if (isInvulnerable() || isImmune(type)) {
|
if (isInvulnerable() || isImmune(type)) {
|
||||||
@ -260,7 +263,10 @@ public abstract class LivingEntity extends Entity implements EquipmentHandler {
|
|||||||
|
|
||||||
EntityDamageEvent entityDamageEvent = new EntityDamageEvent(this, type, value);
|
EntityDamageEvent entityDamageEvent = new EntityDamageEvent(this, type, value);
|
||||||
callCancellableEvent(EntityDamageEvent.class, entityDamageEvent, () -> {
|
callCancellableEvent(EntityDamageEvent.class, entityDamageEvent, () -> {
|
||||||
float damage = entityDamageEvent.getDamage();
|
// Set the last damage type since the event is not cancelled
|
||||||
|
this.lastDamageSource = entityDamageEvent.getDamageType();
|
||||||
|
|
||||||
|
float remainingDamage = entityDamageEvent.getDamage();
|
||||||
|
|
||||||
EntityAnimationPacket entityAnimationPacket = new EntityAnimationPacket();
|
EntityAnimationPacket entityAnimationPacket = new EntityAnimationPacket();
|
||||||
entityAnimationPacket.entityId = getEntityId();
|
entityAnimationPacket.entityId = getEntityId();
|
||||||
@ -272,18 +278,18 @@ public abstract class LivingEntity extends Entity implements EquipmentHandler {
|
|||||||
final Player player = (Player) this;
|
final Player player = (Player) this;
|
||||||
final float additionalHearts = player.getAdditionalHearts();
|
final float additionalHearts = player.getAdditionalHearts();
|
||||||
if (additionalHearts > 0) {
|
if (additionalHearts > 0) {
|
||||||
if (damage > additionalHearts) {
|
if (remainingDamage > additionalHearts) {
|
||||||
damage -= additionalHearts;
|
remainingDamage -= additionalHearts;
|
||||||
player.setAdditionalHearts(0);
|
player.setAdditionalHearts(0);
|
||||||
} else {
|
} else {
|
||||||
player.setAdditionalHearts(additionalHearts - damage);
|
player.setAdditionalHearts(additionalHearts - remainingDamage);
|
||||||
damage = 0;
|
remainingDamage = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the final entity health
|
// Set the final entity health
|
||||||
setHealth(getHealth() - damage);
|
setHealth(getHealth() - remainingDamage);
|
||||||
|
|
||||||
// play damage sound
|
// play damage sound
|
||||||
final Sound sound = type.getSound(this);
|
final Sound sound = type.getSound(this);
|
||||||
@ -299,9 +305,6 @@ public abstract class LivingEntity extends Entity implements EquipmentHandler {
|
|||||||
SoundEffectPacket damageSoundPacket = SoundEffectPacket.create(soundCategory, sound, getPosition().getX(), getPosition().getY(), getPosition().getZ(), 1.0f, 1.0f);
|
SoundEffectPacket damageSoundPacket = SoundEffectPacket.create(soundCategory, sound, getPosition().getX(), getPosition().getY(), getPosition().getZ(), 1.0f, 1.0f);
|
||||||
sendPacketToViewersAndSelf(damageSoundPacket);
|
sendPacketToViewersAndSelf(damageSoundPacket);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the last damage type since the event is not cancelled
|
|
||||||
this.lastDamageSource = entityDamageEvent.getDamageType();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return !entityDamageEvent.isCancelled();
|
return !entityDamageEvent.isCancelled();
|
||||||
@ -508,6 +511,7 @@ public abstract class LivingEntity extends Entity implements EquipmentHandler {
|
|||||||
* Gets the time in ms between two fire damage applications.
|
* Gets the time in ms between two fire damage applications.
|
||||||
*
|
*
|
||||||
* @return the time in ms
|
* @return the time in ms
|
||||||
|
* @see #setFireDamagePeriod(long, TimeUnit)
|
||||||
*/
|
*/
|
||||||
public long getFireDamagePeriod() {
|
public long getFireDamagePeriod() {
|
||||||
return fireDamagePeriod;
|
return fireDamagePeriod;
|
||||||
@ -552,7 +556,7 @@ public abstract class LivingEntity extends Entity implements EquipmentHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the {@link Team} of the entity.¬
|
* Gets the {@link Team} of the entity.
|
||||||
*
|
*
|
||||||
* @return the {@link Team}
|
* @return the {@link Team}
|
||||||
*/
|
*/
|
||||||
|
@ -454,34 +454,43 @@ public class Player extends LivingEntity implements CommandSender {
|
|||||||
@Override
|
@Override
|
||||||
public void kill() {
|
public void kill() {
|
||||||
if (!isDead()) {
|
if (!isDead()) {
|
||||||
// send death message to player
|
// send death screen text to the killed player
|
||||||
ColoredText deathMessage;
|
{
|
||||||
if (lastDamageSource != null) {
|
ColoredText deathText;
|
||||||
deathMessage = lastDamageSource.buildDeathScreenMessage(this);
|
if (lastDamageSource != null) {
|
||||||
} else { // may happen if killed by the server without applying damage
|
deathText = lastDamageSource.buildDeathScreenText(this);
|
||||||
deathMessage = ColoredText.of("Killed by poor programming.");
|
} else { // may happen if killed by the server without applying damage
|
||||||
|
deathText = ColoredText.of("Killed by poor programming.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// #buildDeathScreenText can return null, check here
|
||||||
|
if (deathText != null) {
|
||||||
|
CombatEventPacket deathPacket = CombatEventPacket.death(this, Optional.empty(), deathText);
|
||||||
|
playerConnection.sendPacket(deathPacket);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
CombatEventPacket deathPacket = CombatEventPacket.death(this, Optional.empty(), deathMessage);
|
|
||||||
playerConnection.sendPacket(deathPacket);
|
|
||||||
|
|
||||||
// send death message to chat
|
// send death message to chat
|
||||||
RichMessage chatMessage;
|
{
|
||||||
if (lastDamageSource != null) {
|
JsonMessage chatMessage;
|
||||||
chatMessage = lastDamageSource.buildChatMessage(this);
|
if (lastDamageSource != null) {
|
||||||
} else { // may happen if killed by the server without applying damage
|
chatMessage = lastDamageSource.buildDeathMessage(this);
|
||||||
ColoredText coloredChatMessage =
|
} else { // may happen if killed by the server without applying damage
|
||||||
ColoredText.of(getUsername() + " was killed by poor programming.");
|
chatMessage = ColoredText.of(getUsername() + " was killed by poor programming.");
|
||||||
chatMessage = RichMessage.of(coloredChatMessage);
|
}
|
||||||
|
|
||||||
|
// #buildDeathMessage can return null, check here
|
||||||
|
if (chatMessage != null) {
|
||||||
|
MinecraftServer.getConnectionManager().broadcastMessage(chatMessage);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
MinecraftServer.getConnectionManager().getOnlinePlayers()
|
|
||||||
.forEach(player -> player.sendMessage(chatMessage));
|
|
||||||
}
|
}
|
||||||
super.kill();
|
super.kill();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Respawn the player by sending a {@link RespawnPacket} to the player and teleporting him
|
* Respawns the player by sending a {@link RespawnPacket} to the player and teleporting him
|
||||||
* to {@link #getRespawnPoint()}. It also reset fire and his health
|
* to {@link #getRespawnPoint()}. It also resetso fire and his health
|
||||||
*/
|
*/
|
||||||
public void respawn() {
|
public void respawn() {
|
||||||
if (!isDead())
|
if (!isDead())
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package net.minestom.server.entity.damage;
|
package net.minestom.server.entity.damage;
|
||||||
|
|
||||||
import net.minestom.server.chat.ColoredText;
|
import net.minestom.server.chat.ColoredText;
|
||||||
|
import net.minestom.server.chat.JsonMessage;
|
||||||
import net.minestom.server.chat.RichMessage;
|
import net.minestom.server.chat.RichMessage;
|
||||||
import net.minestom.server.data.Data;
|
import net.minestom.server.data.Data;
|
||||||
import net.minestom.server.data.DataContainer;
|
import net.minestom.server.data.DataContainer;
|
||||||
@ -10,7 +11,12 @@ import net.minestom.server.entity.Player;
|
|||||||
import net.minestom.server.sound.Sound;
|
import net.minestom.server.sound.Sound;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a type of damage
|
* Represents a type of damage, required when calling {@link LivingEntity#damage(DamageType, float)}
|
||||||
|
* and retrieved in {@link net.minestom.server.event.entity.EntityDamageEvent}.
|
||||||
|
* <p>
|
||||||
|
* This class can be extended if you need to include custom fields and/or methods.
|
||||||
|
* Be aware that this class implements {@link DataContainer}
|
||||||
|
* so you can add your own data to an already existing damage type without any wrapper.
|
||||||
*/
|
*/
|
||||||
public class DamageType implements DataContainer {
|
public class DamageType implements DataContainer {
|
||||||
|
|
||||||
@ -25,32 +31,78 @@ public class DamageType implements DataContainer {
|
|||||||
private final String identifier;
|
private final String identifier;
|
||||||
private Data data;
|
private Data data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new damage type.
|
||||||
|
*
|
||||||
|
* @param identifier the identifier of this damage type,
|
||||||
|
* does not need to be unique
|
||||||
|
*/
|
||||||
public DamageType(String identifier) {
|
public DamageType(String identifier) {
|
||||||
this.identifier = identifier;
|
this.identifier = identifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the identifier of this damage type.
|
||||||
|
* <p>
|
||||||
|
* It does not have to be unique to this object.o
|
||||||
|
*
|
||||||
|
* @return the damage type identifier
|
||||||
|
*/
|
||||||
public String getIdentifier() {
|
public String getIdentifier() {
|
||||||
return identifier;
|
return identifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds the death message linked to this damage type.
|
||||||
|
* <p>
|
||||||
|
* Used in {@link Player#kill()} to broadcast the proper message.
|
||||||
|
*
|
||||||
|
* @param killed the player who has been killed
|
||||||
|
* @return the death message, null to do not send anything.
|
||||||
|
* Can be for instance, of type {@link ColoredText} or {@link RichMessage}.
|
||||||
|
*/
|
||||||
|
public JsonMessage buildDeathMessage(Player killed) {
|
||||||
|
return ColoredText.of("{@death." + identifier + "," + killed.getUsername() + "}");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convenient method to create an {@link EntityProjectileDamage}.
|
||||||
|
*
|
||||||
|
* @param shooter the shooter
|
||||||
|
* @param projectile the actual projectile
|
||||||
|
* @return a new {@link EntityProjectileDamage}
|
||||||
|
*/
|
||||||
public static DamageType fromProjectile(Entity shooter, Entity projectile) {
|
public static DamageType fromProjectile(Entity shooter, Entity projectile) {
|
||||||
return new EntityProjectileDamage(shooter, projectile);
|
return new EntityProjectileDamage(shooter, projectile);
|
||||||
}
|
}
|
||||||
|
|
||||||
public RichMessage buildChatMessage(Player killed) {
|
/**
|
||||||
RichMessage richMessage = RichMessage.of(ColoredText.of("{@death." + identifier + "," + killed.getUsername() + "}"));
|
* Convenient method to create an {@link EntityDamage}.
|
||||||
return richMessage;
|
*
|
||||||
}
|
* @param player the player damager
|
||||||
|
* @return a new {@link EntityDamage}
|
||||||
|
*/
|
||||||
public static EntityDamage fromPlayer(Player player) {
|
public static EntityDamage fromPlayer(Player player) {
|
||||||
return new EntityDamage(player);
|
return new EntityDamage(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convenient method to create an {@link EntityDamage}.
|
||||||
|
*
|
||||||
|
* @param entity the entity damager
|
||||||
|
* @return a new {@link EntityDamage}
|
||||||
|
*/
|
||||||
public static EntityDamage fromEntity(Entity entity) {
|
public static EntityDamage fromEntity(Entity entity) {
|
||||||
return new EntityDamage(entity);
|
return new EntityDamage(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ColoredText buildDeathScreenMessage(Player killed) {
|
/**
|
||||||
|
* Builds the text sent to a player in his death screen.
|
||||||
|
*
|
||||||
|
* @param killed the player who has been killed
|
||||||
|
* @return the death screen text, null to do not send anything
|
||||||
|
*/
|
||||||
|
public ColoredText buildDeathScreenText(Player killed) {
|
||||||
return ColoredText.of("{@death." + identifier + "}");
|
return ColoredText.of("{@death." + identifier + "}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ package net.minestom.server.entity.damage;
|
|||||||
import net.minestom.server.entity.Entity;
|
import net.minestom.server.entity.Entity;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents damage inflicted by an entity.
|
* Represents damage inflicted by an {@link Entity}.
|
||||||
*/
|
*/
|
||||||
public class EntityDamage extends DamageType {
|
public class EntityDamage extends DamageType {
|
||||||
|
|
||||||
|
@ -3,7 +3,9 @@ package net.minestom.server.event;
|
|||||||
import net.minestom.server.event.handler.EventHandler;
|
import net.minestom.server.event.handler.EventHandler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Object which can be listened to by an {@link EventHandler}
|
* Object which can be listened to by an {@link EventHandler}.
|
||||||
|
* <p>
|
||||||
|
* Called using {@link EventHandler#callEvent(Class, Event)}.
|
||||||
*/
|
*/
|
||||||
public class Event {
|
public class Event {
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user