mirror of
https://github.com/PaperMC/Paper.git
synced 2025-05-18 21:20:24 -07:00
Add combat tracker API (#11853)
This commit is contained in:
parent
646b80ca53
commit
e663f99982
@ -138,6 +138,11 @@ public net.minecraft.world.BossEvent overlay
|
||||
public net.minecraft.world.CompoundContainer container1
|
||||
public net.minecraft.world.CompoundContainer container2
|
||||
public net.minecraft.world.SimpleContainer items
|
||||
public net.minecraft.world.damagesource.CombatTracker entries
|
||||
public net.minecraft.world.damagesource.CombatTracker getMostSignificantFall()Lnet/minecraft/world/damagesource/CombatEntry;
|
||||
public net.minecraft.world.damagesource.CombatTracker inCombat
|
||||
public net.minecraft.world.damagesource.CombatTracker mob
|
||||
public net.minecraft.world.damagesource.CombatTracker takingDamage
|
||||
public net.minecraft.world.damagesource.DamageSource <init>(Lnet/minecraft/core/Holder;Lnet/minecraft/world/entity/Entity;Lnet/minecraft/world/entity/Entity;Lnet/minecraft/world/phys/Vec3;)V
|
||||
public net.minecraft.world.effect.MobEffect attributeModifiers
|
||||
public net.minecraft.world.effect.MobEffect$AttributeTemplate
|
||||
|
@ -1,10 +1,15 @@
|
||||
package io.papermc.paper;
|
||||
|
||||
import io.papermc.paper.world.damagesource.CombatEntry;
|
||||
import io.papermc.paper.world.damagesource.FallLocationType;
|
||||
import net.kyori.adventure.util.Services;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.damage.DamageEffect;
|
||||
import org.bukkit.damage.DamageSource;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Static bridge to the server internals.
|
||||
@ -45,5 +50,28 @@ public interface InternalAPIBridge {
|
||||
@Deprecated(forRemoval = true, since = "1.21.5")
|
||||
@ApiStatus.ScheduledForRemoval(inVersion = "1.22")
|
||||
Biome constructLegacyCustomBiome();
|
||||
|
||||
/**
|
||||
* Creates a new combat entry.
|
||||
* <p>
|
||||
* The fall location and fall distance will be calculated from the entity's current state.
|
||||
*
|
||||
* @param entity entity
|
||||
* @param damageSource damage source
|
||||
* @param damage damage amount
|
||||
* @return new combat entry
|
||||
*/
|
||||
CombatEntry createCombatEntry(LivingEntity entity, DamageSource damageSource, float damage);
|
||||
|
||||
/**
|
||||
* Creates a new combat entry
|
||||
*
|
||||
* @param damageSource damage source
|
||||
* @param damage damage amount
|
||||
* @param fallLocationType fall location type
|
||||
* @param fallDistance fall distance
|
||||
* @return combat entry
|
||||
*/
|
||||
CombatEntry createCombatEntry(DamageSource damageSource, float damage, @Nullable FallLocationType fallLocationType, float fallDistance);
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,82 @@
|
||||
package io.papermc.paper.world.damagesource;
|
||||
|
||||
import io.papermc.paper.InternalAPIBridge;
|
||||
import org.bukkit.damage.DamageSource;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Represents a combat entry
|
||||
*/
|
||||
@NullMarked
|
||||
@ApiStatus.Experimental
|
||||
@ApiStatus.NonExtendable
|
||||
public interface CombatEntry {
|
||||
|
||||
/**
|
||||
* Gets the damage source.
|
||||
*
|
||||
* @return the damage source
|
||||
*/
|
||||
DamageSource getDamageSource();
|
||||
|
||||
/**
|
||||
* Gets the amount of damage caused.
|
||||
*
|
||||
* @return the amount of damage caused
|
||||
*/
|
||||
float getDamage();
|
||||
|
||||
/**
|
||||
* Gets the fall location type at the time of this damage.
|
||||
*
|
||||
* @return the fall location type
|
||||
*/
|
||||
@Nullable FallLocationType getFallLocationType();
|
||||
|
||||
/**
|
||||
* Gets the fall distance at the time of this damage.
|
||||
*
|
||||
* @return the fall distance
|
||||
*/
|
||||
float getFallDistance();
|
||||
|
||||
/**
|
||||
* Creates a new combat entry.
|
||||
* <p>
|
||||
* The fall location and fall distance will be calculated from the entity's current state.
|
||||
*
|
||||
* @param entity entity
|
||||
* @param damageSource damage source
|
||||
* @param damage damage amount
|
||||
* @return combat entry
|
||||
* @see #combatEntry(DamageSource, float, FallLocationType, float)
|
||||
*/
|
||||
static CombatEntry combatEntry(final LivingEntity entity, final DamageSource damageSource, final float damage) {
|
||||
return InternalAPIBridge.get().createCombatEntry(entity, damageSource, damage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new combat entry
|
||||
*
|
||||
* @param damageSource damage source
|
||||
* @param damage damage amount
|
||||
* @param fallLocationType fall location type
|
||||
* @param fallDistance fall distance
|
||||
* @return a new combat entry
|
||||
* @see CombatTracker#calculateFallLocationType()
|
||||
* @see Entity#getFallDistance()
|
||||
*/
|
||||
static CombatEntry combatEntry(
|
||||
final DamageSource damageSource,
|
||||
final float damage,
|
||||
@Nullable final FallLocationType fallLocationType,
|
||||
final float fallDistance
|
||||
) {
|
||||
return InternalAPIBridge.get().createCombatEntry(damageSource, damage, fallLocationType, fallDistance);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,110 @@
|
||||
package io.papermc.paper.world.damagesource;
|
||||
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Represents entity's combat tracker
|
||||
*/
|
||||
@NullMarked
|
||||
@ApiStatus.Experimental
|
||||
@ApiStatus.NonExtendable
|
||||
public interface CombatTracker {
|
||||
|
||||
/**
|
||||
* Gets the entity behind this combat tracker.
|
||||
*
|
||||
* @return the entity behind this combat tracker
|
||||
*/
|
||||
LivingEntity getEntity();
|
||||
|
||||
/**
|
||||
* Gets the list of recorded combat entries.
|
||||
* <p>
|
||||
* The returned list is a copy, so any modifications
|
||||
* to its contents won't affect this entity's
|
||||
* combat history.
|
||||
*
|
||||
* @return the list of combat entries
|
||||
* @see #setCombatEntries(List)
|
||||
*/
|
||||
List<CombatEntry> getCombatEntries();
|
||||
|
||||
/**
|
||||
* Sets the entity's combat history.
|
||||
* <p>
|
||||
* Note that overriding the entity's combat history won't
|
||||
* affect the entity's current or new combat state.
|
||||
* Reset the current combat state and register new combat entries instead
|
||||
* if you want the new history to affect the combat state.
|
||||
*
|
||||
* @param combatEntries combat entries
|
||||
* @see #resetCombatState()
|
||||
* @see #addCombatEntry(CombatEntry)
|
||||
*/
|
||||
void setCombatEntries(List<CombatEntry> combatEntries);
|
||||
|
||||
/**
|
||||
* Calculates the most significant fall damage entry.
|
||||
*
|
||||
* @return the most significant fall damage entry
|
||||
*/
|
||||
@Nullable CombatEntry computeMostSignificantFall();
|
||||
|
||||
/**
|
||||
* Checks whether the entity is in combat,
|
||||
* i.e. has taken damage from an entity
|
||||
* since the combat tracking has begun.
|
||||
*
|
||||
* @return whether the entity is in combat
|
||||
*/
|
||||
boolean isInCombat();
|
||||
|
||||
/**
|
||||
* Checks whether the entity has started recording damage,
|
||||
* i.e. its combat tracking is active.
|
||||
*
|
||||
* @return whether the entity has started recording damage
|
||||
*/
|
||||
boolean isTakingDamage();
|
||||
|
||||
/**
|
||||
* Gets the last or current combat duration.
|
||||
*
|
||||
* @return the combat duration
|
||||
* @see #isInCombat()
|
||||
*/
|
||||
int getCombatDuration();
|
||||
|
||||
/**
|
||||
* Adds a new entry the pool of combat entries,
|
||||
* updating the entity's combat state.
|
||||
*
|
||||
* @param combatEntry combat entry
|
||||
*/
|
||||
void addCombatEntry(CombatEntry combatEntry);
|
||||
|
||||
/**
|
||||
* Constructs a death message based on the current combat history.
|
||||
*
|
||||
* @return a death message
|
||||
*/
|
||||
Component getDeathMessage();
|
||||
|
||||
/**
|
||||
* Resets entity's combat state, clearing combat history.
|
||||
*/
|
||||
void resetCombatState();
|
||||
|
||||
/**
|
||||
* Calculates the fall location type from the current entity's location.
|
||||
*
|
||||
* @return the fall location type
|
||||
*/
|
||||
@Nullable FallLocationType calculateFallLocationType();
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
package io.papermc.paper.world.damagesource;
|
||||
|
||||
import net.kyori.adventure.translation.Translatable;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
|
||||
/**
|
||||
* Represents a type of location from which the entity fell.
|
||||
*/
|
||||
@NullMarked
|
||||
@ApiStatus.Experimental
|
||||
public sealed interface FallLocationType extends Translatable permits FallLocationTypeImpl {
|
||||
|
||||
/**
|
||||
* Gets the fall location id.
|
||||
*
|
||||
* @return the fall location id
|
||||
*/
|
||||
String id();
|
||||
|
||||
/**
|
||||
* Gets the translation key used for a fall death message
|
||||
* caused by falling from this location
|
||||
*
|
||||
* @return the translation key
|
||||
*/
|
||||
@Override
|
||||
String translationKey();
|
||||
|
||||
/**
|
||||
* The entity was not within a special fall location.
|
||||
*/
|
||||
FallLocationType GENERIC = new FallLocationTypeImpl("generic");
|
||||
/**
|
||||
* The entity was within the ladder.
|
||||
*/
|
||||
FallLocationType LADDER = new FallLocationTypeImpl("ladder");
|
||||
/**
|
||||
* The entity was in vines.
|
||||
*/
|
||||
FallLocationType VINES = new FallLocationTypeImpl("vines");
|
||||
/**
|
||||
* The entity was in weeping wines.
|
||||
*/
|
||||
FallLocationType WEEPING_VINES = new FallLocationTypeImpl("weeping_vines");
|
||||
/**
|
||||
* The entity was in twisting vines.
|
||||
*/
|
||||
FallLocationType TWISTING_VINES = new FallLocationTypeImpl("twisting_vines");
|
||||
/**
|
||||
* The entity was in scaffolding.
|
||||
*/
|
||||
FallLocationType SCAFFOLDING = new FallLocationTypeImpl("scaffolding");
|
||||
/**
|
||||
* The entity was within some other climbable block.
|
||||
*/
|
||||
FallLocationType OTHER_CLIMBABLE = new FallLocationTypeImpl("other_climbable");
|
||||
/**
|
||||
* The entity was in water.
|
||||
*/
|
||||
FallLocationType WATER = new FallLocationTypeImpl("water");
|
||||
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package io.papermc.paper.world.damagesource;
|
||||
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
|
||||
@NullMarked
|
||||
record FallLocationTypeImpl(String id) implements FallLocationType {
|
||||
|
||||
@Override
|
||||
public String translationKey() {
|
||||
// Same as net.minecraft.world.damagesource.FallLocation#languageKey
|
||||
return "death.fell.accident." + this.id;
|
||||
}
|
||||
|
||||
}
|
@ -4,6 +4,8 @@ import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import io.papermc.paper.world.damagesource.CombatTracker;
|
||||
import io.papermc.paper.world.damagesource.FallLocationType;
|
||||
import org.bukkit.FluidCollisionMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
@ -21,6 +23,7 @@ import org.bukkit.scoreboard.Scoreboard;
|
||||
import org.bukkit.scoreboard.Team;
|
||||
import org.bukkit.util.RayTraceResult;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@ -1452,4 +1455,12 @@ public interface LivingEntity extends Attributable, Damageable, ProjectileSource
|
||||
*/
|
||||
boolean canUseEquipmentSlot(org.bukkit.inventory.@NotNull EquipmentSlot slot);
|
||||
// Paper end - Expose canUseSlot
|
||||
|
||||
/**
|
||||
* Gets the entity's combat tracker
|
||||
*
|
||||
* @return the entity's combat tracker
|
||||
*/
|
||||
@ApiStatus.Experimental
|
||||
@NotNull CombatTracker getCombatTracker();
|
||||
}
|
||||
|
@ -0,0 +1,30 @@
|
||||
--- a/net/minecraft/world/damagesource/CombatTracker.java
|
||||
+++ b/net/minecraft/world/damagesource/CombatTracker.java
|
||||
@@ -38,6 +_,13 @@
|
||||
this.recheckStatus();
|
||||
FallLocation currentFallLocation = FallLocation.getCurrentFallLocation(this.mob);
|
||||
CombatEntry combatEntry = new CombatEntry(source, damage, currentFallLocation, (float)this.mob.fallDistance);
|
||||
+ // Paper start - Combat tracker API
|
||||
+ recordDamageAndCheckCombatState(combatEntry);
|
||||
+ }
|
||||
+
|
||||
+ public void recordDamageAndCheckCombatState(final CombatEntry combatEntry) {
|
||||
+ final DamageSource source = combatEntry.source();
|
||||
+ // Paper end - Combat tracker API
|
||||
this.entries.add(combatEntry);
|
||||
this.lastDamageTime = this.mob.tickCount;
|
||||
this.takingDamage = true;
|
||||
@@ -147,6 +_,13 @@
|
||||
public void recheckStatus() {
|
||||
int i = this.inCombat ? 300 : 100;
|
||||
if (this.takingDamage && (!this.mob.isAlive() || this.mob.tickCount - this.lastDamageTime > i)) {
|
||||
+ // Paper start - Combat tracker API
|
||||
+ resetCombatState();
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public void resetCombatState() {{
|
||||
+ // Paper end - Combat tracker API
|
||||
boolean flag = this.inCombat;
|
||||
this.takingDamage = false;
|
||||
this.inCombat = false;
|
@ -1,10 +1,21 @@
|
||||
package io.papermc.paper;
|
||||
|
||||
import io.papermc.paper.world.damagesource.CombatEntry;
|
||||
import io.papermc.paper.world.damagesource.FallLocationType;
|
||||
import io.papermc.paper.world.damagesource.PaperCombatEntryWrapper;
|
||||
import io.papermc.paper.world.damagesource.PaperCombatTrackerWrapper;
|
||||
import net.minecraft.Optionull;
|
||||
import net.minecraft.world.damagesource.FallLocation;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.craftbukkit.block.CraftBiome;
|
||||
import org.bukkit.craftbukkit.damage.CraftDamageEffect;
|
||||
import org.bukkit.craftbukkit.damage.CraftDamageSource;
|
||||
import org.bukkit.craftbukkit.entity.CraftLivingEntity;
|
||||
import org.bukkit.damage.DamageEffect;
|
||||
import org.bukkit.damage.DamageSource;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
@NullMarked
|
||||
public class PaperServerInternalAPIBridge implements InternalAPIBridge {
|
||||
@ -22,4 +33,42 @@ public class PaperServerInternalAPIBridge implements InternalAPIBridge {
|
||||
}
|
||||
return Holder.LEGACY_CUSTOM;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CombatEntry createCombatEntry(final LivingEntity entity, final DamageSource damageSource, final float damage) {
|
||||
final net.minecraft.world.entity.LivingEntity mob = ((CraftLivingEntity) entity).getHandle();
|
||||
final FallLocation fallLocation = FallLocation.getCurrentFallLocation(mob);
|
||||
return createCombatEntry(
|
||||
((CraftDamageSource) damageSource).getHandle(),
|
||||
damage,
|
||||
fallLocation,
|
||||
(float) mob.fallDistance
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CombatEntry createCombatEntry(
|
||||
final DamageSource damageSource,
|
||||
final float damage,
|
||||
@Nullable final FallLocationType fallLocationType,
|
||||
final float fallDistance
|
||||
) {
|
||||
return createCombatEntry(
|
||||
((CraftDamageSource) damageSource).getHandle(),
|
||||
damage,
|
||||
Optionull.map(fallLocationType, PaperCombatTrackerWrapper::paperToMinecraft),
|
||||
fallDistance
|
||||
);
|
||||
}
|
||||
|
||||
private CombatEntry createCombatEntry(
|
||||
final net.minecraft.world.damagesource.DamageSource damageSource,
|
||||
final float damage,
|
||||
final net.minecraft.world.damagesource.@Nullable FallLocation fallLocation,
|
||||
final float fallDistance
|
||||
) {
|
||||
return new PaperCombatEntryWrapper(new net.minecraft.world.damagesource.CombatEntry(
|
||||
damageSource, damage, fallLocation, fallDistance
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,32 @@
|
||||
package io.papermc.paper.world.damagesource;
|
||||
|
||||
import net.minecraft.Optionull;
|
||||
import org.bukkit.craftbukkit.damage.CraftDamageSource;
|
||||
import org.bukkit.damage.DamageSource;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
@NullMarked
|
||||
public record PaperCombatEntryWrapper(net.minecraft.world.damagesource.CombatEntry handle) implements CombatEntry {
|
||||
|
||||
@Override
|
||||
public DamageSource getDamageSource() {
|
||||
return new CraftDamageSource(this.handle.source());
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getDamage() {
|
||||
return this.handle.damage();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable FallLocationType getFallLocationType() {
|
||||
return Optionull.map(this.handle.fallLocation(), PaperCombatTrackerWrapper::minecraftToPaper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getFallDistance() {
|
||||
return this.handle.fallDistance();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,110 @@
|
||||
package io.papermc.paper.world.damagesource;
|
||||
|
||||
import com.google.common.collect.BiMap;
|
||||
import com.google.common.collect.HashBiMap;
|
||||
import io.papermc.paper.adventure.PaperAdventure;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.world.damagesource.FallLocation;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
@NullMarked
|
||||
public record PaperCombatTrackerWrapper(
|
||||
net.minecraft.world.damagesource.CombatTracker handle
|
||||
) implements CombatTracker {
|
||||
|
||||
@Override
|
||||
public LivingEntity getEntity() {
|
||||
return this.handle.mob.getBukkitLivingEntity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CombatEntry> getCombatEntries() {
|
||||
final List<CombatEntry> combatEntries = new ArrayList<>(this.handle.entries.size());
|
||||
this.handle.entries.forEach(combatEntry -> combatEntries.add(new PaperCombatEntryWrapper(combatEntry)));
|
||||
return combatEntries;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCombatEntries(final List<CombatEntry> combatEntries) {
|
||||
this.handle.entries.clear();
|
||||
combatEntries.forEach(combatEntry -> this.handle.entries.add(((PaperCombatEntryWrapper) combatEntry).handle()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable CombatEntry computeMostSignificantFall() {
|
||||
final net.minecraft.world.damagesource.CombatEntry combatEntry = this.handle.getMostSignificantFall();
|
||||
return combatEntry == null ? null : new PaperCombatEntryWrapper(combatEntry);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInCombat() {
|
||||
return this.handle.inCombat;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTakingDamage() {
|
||||
return this.handle.takingDamage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCombatDuration() {
|
||||
return this.handle.getCombatDuration();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addCombatEntry(final CombatEntry combatEntry) {
|
||||
final net.minecraft.world.damagesource.CombatEntry entry = ((PaperCombatEntryWrapper) combatEntry).handle();
|
||||
this.handle.recordDamageAndCheckCombatState(entry);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component getDeathMessage() {
|
||||
return PaperAdventure.asAdventure(this.handle.getDeathMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetCombatState() {
|
||||
this.handle.resetCombatState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FallLocationType calculateFallLocationType() {
|
||||
final FallLocation fallLocation = FallLocation.getCurrentFallLocation(this.handle().mob);
|
||||
return fallLocation == null ? FallLocationType.GENERIC : PaperCombatTrackerWrapper.minecraftToPaper(fallLocation);
|
||||
}
|
||||
|
||||
private static final BiMap<FallLocation, FallLocationType> FALL_LOCATION_MAPPING = Util.make(() -> {
|
||||
final BiMap<FallLocation, FallLocationType> map = HashBiMap.create(8);
|
||||
map.put(FallLocation.GENERIC, FallLocationType.GENERIC);
|
||||
map.put(FallLocation.LADDER, FallLocationType.LADDER);
|
||||
map.put(FallLocation.VINES, FallLocationType.VINES);
|
||||
map.put(FallLocation.WEEPING_VINES, FallLocationType.WEEPING_VINES);
|
||||
map.put(FallLocation.TWISTING_VINES, FallLocationType.TWISTING_VINES);
|
||||
map.put(FallLocation.SCAFFOLDING, FallLocationType.SCAFFOLDING);
|
||||
map.put(FallLocation.OTHER_CLIMBABLE, FallLocationType.OTHER_CLIMBABLE);
|
||||
map.put(FallLocation.WATER, FallLocationType.WATER);
|
||||
return map;
|
||||
});
|
||||
|
||||
public static FallLocation paperToMinecraft(final FallLocationType fallLocationType) {
|
||||
final FallLocation fallLocation = FALL_LOCATION_MAPPING.inverse().get(fallLocationType);
|
||||
if (fallLocation == null) {
|
||||
throw new IllegalArgumentException("Unknown fall location type: " + fallLocationType.id());
|
||||
}
|
||||
return fallLocation;
|
||||
}
|
||||
|
||||
public static FallLocationType minecraftToPaper(final FallLocation fallLocation) {
|
||||
final FallLocationType fallLocationType = FALL_LOCATION_MAPPING.get(fallLocation);
|
||||
if (fallLocationType == null) {
|
||||
throw new IllegalArgumentException("Unknown fall location: " + fallLocation.id());
|
||||
}
|
||||
return fallLocationType;
|
||||
}
|
||||
|
||||
}
|
@ -9,6 +9,9 @@ import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import net.minecraft.Optionull;
|
||||
import io.papermc.paper.world.damagesource.CombatTracker;
|
||||
import io.papermc.paper.world.damagesource.PaperCombatTrackerWrapper;
|
||||
import io.papermc.paper.world.damagesource.FallLocationType;
|
||||
import net.minecraft.core.component.DataComponents;
|
||||
import net.minecraft.network.protocol.game.ClientboundHurtAnimationPacket;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
@ -90,11 +93,15 @@ import org.bukkit.util.RayTraceResult;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class CraftLivingEntity extends CraftEntity implements LivingEntity {
|
||||
|
||||
private final PaperCombatTrackerWrapper combatTracker;
|
||||
private CraftEntityEquipment equipment;
|
||||
|
||||
public CraftLivingEntity(final CraftServer server, final net.minecraft.world.entity.LivingEntity entity) {
|
||||
super(server, entity);
|
||||
|
||||
this.combatTracker = new PaperCombatTrackerWrapper(entity.getCombatTracker());
|
||||
|
||||
if (entity instanceof Mob || entity instanceof ArmorStand) {
|
||||
this.equipment = new CraftEntityEquipment(this);
|
||||
}
|
||||
@ -1167,4 +1174,9 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
|
||||
public boolean canUseEquipmentSlot(org.bukkit.inventory.EquipmentSlot slot) {
|
||||
return this.getHandle().canUseSlot(org.bukkit.craftbukkit.CraftEquipmentSlot.getNMS(slot));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CombatTracker getCombatTracker() {
|
||||
return this.combatTracker;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user