120 lines
3.9 KiB
Java
120 lines
3.9 KiB
Java
package net.minecraft.world.entity;
|
|
|
|
import java.util.Objects;
|
|
import java.util.UUID;
|
|
import net.minecraft.core.UUIDUtil;
|
|
import net.minecraft.nbt.CompoundTag;
|
|
import net.minecraft.server.level.ServerLevel;
|
|
import net.minecraft.world.entity.player.Player;
|
|
import net.minecraft.world.level.GameRules;
|
|
import net.minecraft.world.level.Level;
|
|
import org.jetbrains.annotations.Nullable;
|
|
|
|
public interface NeutralMob {
|
|
String TAG_ANGER_TIME = "AngerTime";
|
|
String TAG_ANGRY_AT = "AngryAt";
|
|
|
|
int getRemainingPersistentAngerTime();
|
|
|
|
void setRemainingPersistentAngerTime(int remainingPersistentAngerTime);
|
|
|
|
@Nullable
|
|
UUID getPersistentAngerTarget();
|
|
|
|
void setPersistentAngerTarget(@Nullable UUID persistentAngerTarget);
|
|
|
|
void startPersistentAngerTimer();
|
|
|
|
default void addPersistentAngerSaveData(CompoundTag nbt) {
|
|
nbt.putInt("AngerTime", this.getRemainingPersistentAngerTime());
|
|
nbt.storeNullable("AngryAt", UUIDUtil.CODEC, this.getPersistentAngerTarget());
|
|
}
|
|
|
|
default void readPersistentAngerSaveData(Level level, CompoundTag tag) {
|
|
this.setRemainingPersistentAngerTime(tag.getIntOr("AngerTime", 0));
|
|
if (level instanceof ServerLevel serverLevel) {
|
|
UUID uUID = (UUID)tag.read("AngryAt", UUIDUtil.CODEC).orElse(null);
|
|
this.setPersistentAngerTarget(uUID);
|
|
if ((uUID != null ? serverLevel.getEntity(uUID) : null) instanceof LivingEntity livingEntity) {
|
|
this.setTarget(livingEntity);
|
|
}
|
|
}
|
|
}
|
|
|
|
default void updatePersistentAnger(ServerLevel serverLevel, boolean updateAnger) {
|
|
LivingEntity livingEntity = this.getTarget();
|
|
UUID uUID = this.getPersistentAngerTarget();
|
|
if ((livingEntity == null || livingEntity.isDeadOrDying()) && uUID != null && serverLevel.getEntity(uUID) instanceof Mob) {
|
|
this.stopBeingAngry();
|
|
} else {
|
|
if (livingEntity != null && !Objects.equals(uUID, livingEntity.getUUID())) {
|
|
this.setPersistentAngerTarget(livingEntity.getUUID());
|
|
this.startPersistentAngerTimer();
|
|
}
|
|
|
|
if (this.getRemainingPersistentAngerTime() > 0 && (livingEntity == null || livingEntity.getType() != EntityType.PLAYER || !updateAnger)) {
|
|
this.setRemainingPersistentAngerTime(this.getRemainingPersistentAngerTime() - 1);
|
|
if (this.getRemainingPersistentAngerTime() == 0) {
|
|
this.stopBeingAngry();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
default boolean isAngryAt(LivingEntity entity, ServerLevel level) {
|
|
if (!this.canAttack(entity)) {
|
|
return false;
|
|
} else {
|
|
return entity.getType() == EntityType.PLAYER && this.isAngryAtAllPlayers(level) ? true : entity.getUUID().equals(this.getPersistentAngerTarget());
|
|
}
|
|
}
|
|
|
|
default boolean isAngryAtAllPlayers(ServerLevel level) {
|
|
return level.getGameRules().getBoolean(GameRules.RULE_UNIVERSAL_ANGER) && this.isAngry() && this.getPersistentAngerTarget() == null;
|
|
}
|
|
|
|
default boolean isAngry() {
|
|
return this.getRemainingPersistentAngerTime() > 0;
|
|
}
|
|
|
|
default void playerDied(ServerLevel level, Player player) {
|
|
if (level.getGameRules().getBoolean(GameRules.RULE_FORGIVE_DEAD_PLAYERS)) {
|
|
if (player.getUUID().equals(this.getPersistentAngerTarget())) {
|
|
this.stopBeingAngry();
|
|
}
|
|
}
|
|
}
|
|
|
|
default void forgetCurrentTargetAndRefreshUniversalAnger() {
|
|
this.stopBeingAngry();
|
|
this.startPersistentAngerTimer();
|
|
}
|
|
|
|
default void stopBeingAngry() {
|
|
this.setLastHurtByMob(null);
|
|
this.setPersistentAngerTarget(null);
|
|
this.setTarget(null);
|
|
this.setRemainingPersistentAngerTime(0);
|
|
}
|
|
|
|
@Nullable
|
|
LivingEntity getLastHurtByMob();
|
|
|
|
/**
|
|
* Hint to AI tasks that we were attacked by the passed EntityLivingBase and should retaliate. Is not guaranteed to change our actual active target (for example if we are currently busy attacking someone else)
|
|
*/
|
|
void setLastHurtByMob(@Nullable LivingEntity livingEntity);
|
|
|
|
/**
|
|
* Sets the active target the Task system uses for tracking
|
|
*/
|
|
void setTarget(@Nullable LivingEntity livingEntity);
|
|
|
|
boolean canAttack(LivingEntity entity);
|
|
|
|
/**
|
|
* Gets the active target the Task system uses for tracking
|
|
*/
|
|
@Nullable
|
|
LivingEntity getTarget();
|
|
}
|