Spaces:
Build error
Build error
File size: 7,358 Bytes
d46f4a3 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
package net.minecraft.world.damagesource;
import com.google.common.collect.Lists;
import java.util.List;
import java.util.Objects;
import javax.annotation.Nullable;
import net.minecraft.core.component.DataComponents;
import net.minecraft.network.chat.ClickEvent;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.ComponentUtils;
import net.minecraft.network.chat.HoverEvent;
import net.minecraft.network.chat.Style;
import net.minecraft.tags.DamageTypeTags;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.item.ItemStack;
public class CombatTracker {
public static final int RESET_DAMAGE_STATUS_TIME = 100;
public static final int RESET_COMBAT_STATUS_TIME = 300;
private static final Style INTENTIONAL_GAME_DESIGN_STYLE = Style.EMPTY
.withClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, "https://bugs.mojang.com/browse/MCPE-28723"))
.withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Component.literal("MCPE-28723")));
private final List<CombatEntry> entries = Lists.newArrayList();
private final LivingEntity mob;
private int lastDamageTime;
private int combatStartTime;
private int combatEndTime;
private boolean inCombat;
private boolean takingDamage;
public CombatTracker(LivingEntity p_19285_) {
this.mob = p_19285_;
}
public void recordDamage(DamageSource p_289533_, float p_289559_) {
this.recheckStatus();
FallLocation falllocation = FallLocation.getCurrentFallLocation(this.mob);
CombatEntry combatentry = new CombatEntry(p_289533_, p_289559_, falllocation, this.mob.fallDistance);
this.entries.add(combatentry);
this.lastDamageTime = this.mob.tickCount;
this.takingDamage = true;
if (!this.inCombat && this.mob.isAlive() && shouldEnterCombat(p_289533_)) {
this.inCombat = true;
this.combatStartTime = this.mob.tickCount;
this.combatEndTime = this.combatStartTime;
this.mob.onEnterCombat();
}
}
private static boolean shouldEnterCombat(DamageSource p_289554_) {
return p_289554_.getEntity() instanceof LivingEntity;
}
private Component getMessageForAssistedFall(Entity p_289547_, Component p_289532_, String p_289555_, String p_289548_) {
ItemStack itemstack = p_289547_ instanceof LivingEntity livingentity ? livingentity.getMainHandItem() : ItemStack.EMPTY;
return !itemstack.isEmpty() && itemstack.has(DataComponents.CUSTOM_NAME)
? Component.translatable(p_289555_, this.mob.getDisplayName(), p_289532_, itemstack.getDisplayName())
: Component.translatable(p_289548_, this.mob.getDisplayName(), p_289532_);
}
private Component getFallMessage(CombatEntry p_289570_, @Nullable Entity p_289561_) {
DamageSource damagesource = p_289570_.source();
if (!damagesource.is(DamageTypeTags.IS_FALL) && !damagesource.is(DamageTypeTags.ALWAYS_MOST_SIGNIFICANT_FALL)) {
Component component1 = getDisplayName(p_289561_);
Entity entity = damagesource.getEntity();
Component component = getDisplayName(entity);
if (component != null && !component.equals(component1)) {
return this.getMessageForAssistedFall(entity, component, "death.fell.assist.item", "death.fell.assist");
} else {
return (Component)(component1 != null
? this.getMessageForAssistedFall(p_289561_, component1, "death.fell.finish.item", "death.fell.finish")
: Component.translatable("death.fell.killer", this.mob.getDisplayName()));
}
} else {
FallLocation falllocation = Objects.requireNonNullElse(p_289570_.fallLocation(), FallLocation.GENERIC);
return Component.translatable(falllocation.languageKey(), this.mob.getDisplayName());
}
}
@Nullable
private static Component getDisplayName(@Nullable Entity p_289557_) {
return p_289557_ == null ? null : p_289557_.getDisplayName();
}
public Component getDeathMessage() {
if (this.entries.isEmpty()) {
return Component.translatable("death.attack.generic", this.mob.getDisplayName());
} else {
CombatEntry combatentry = this.entries.get(this.entries.size() - 1);
DamageSource damagesource = combatentry.source();
CombatEntry combatentry1 = this.getMostSignificantFall();
DeathMessageType deathmessagetype = damagesource.type().deathMessageType();
if (deathmessagetype == DeathMessageType.FALL_VARIANTS && combatentry1 != null) {
return this.getFallMessage(combatentry1, damagesource.getEntity());
} else if (deathmessagetype == DeathMessageType.INTENTIONAL_GAME_DESIGN) {
String s = "death.attack." + damagesource.getMsgId();
Component component = ComponentUtils.wrapInSquareBrackets(Component.translatable(s + ".link")).withStyle(INTENTIONAL_GAME_DESIGN_STYLE);
return Component.translatable(s + ".message", this.mob.getDisplayName(), component);
} else {
return damagesource.getLocalizedDeathMessage(this.mob);
}
}
}
@Nullable
private CombatEntry getMostSignificantFall() {
CombatEntry combatentry = null;
CombatEntry combatentry1 = null;
float f = 0.0F;
float f1 = 0.0F;
for (int i = 0; i < this.entries.size(); i++) {
CombatEntry combatentry2 = this.entries.get(i);
CombatEntry combatentry3 = i > 0 ? this.entries.get(i - 1) : null;
DamageSource damagesource = combatentry2.source();
boolean flag = damagesource.is(DamageTypeTags.ALWAYS_MOST_SIGNIFICANT_FALL);
float f2 = flag ? Float.MAX_VALUE : combatentry2.fallDistance();
if ((damagesource.is(DamageTypeTags.IS_FALL) || flag) && f2 > 0.0F && (combatentry == null || f2 > f1)) {
if (i > 0) {
combatentry = combatentry3;
} else {
combatentry = combatentry2;
}
f1 = f2;
}
if (combatentry2.fallLocation() != null && (combatentry1 == null || combatentry2.damage() > f)) {
combatentry1 = combatentry2;
f = combatentry2.damage();
}
}
if (f1 > 5.0F && combatentry != null) {
return combatentry;
} else {
return f > 5.0F && combatentry1 != null ? combatentry1 : null;
}
}
public int getCombatDuration() {
return this.inCombat ? this.mob.tickCount - this.combatStartTime : this.combatEndTime - this.combatStartTime;
}
public void recheckStatus() {
int i = this.inCombat ? 300 : 100;
if (this.takingDamage && (!this.mob.isAlive() || this.mob.tickCount - this.lastDamageTime > i)) {
boolean flag = this.inCombat;
this.takingDamage = false;
this.inCombat = false;
this.combatEndTime = this.mob.tickCount;
if (flag) {
this.mob.onLeaveCombat();
}
this.entries.clear();
}
}
} |