mirror of
https://github.com/PaperMC/Paper.git
synced 2025-01-15 14:13:56 +01:00
Entity Activation Range
This feature gives 3 new configurable ranges that if an entity of the matching type is outside of this radius of any player, will tick at 5% of its normal rate. This will drastically cut down on tick timings for entities that are not in range of a user to actually be "used". This change can have dramatic impact on gameplay if configured too low. Balance according to your servers desired gameplay. By: Aikar <aikar@aikar.co>
This commit is contained in:
parent
54a84c6c79
commit
28c8009a16
12 changed files with 730 additions and 262 deletions
|
@ -79,7 +79,7 @@
|
|||
+ // CraftBukkit start
|
||||
+ public final LevelStorageSource.LevelStorageAccess convertable;
|
||||
+ public final UUID uuid;
|
||||
+
|
||||
|
||||
+ public LevelChunk getChunkIfLoaded(int x, int z) {
|
||||
+ return this.chunkSource.getChunk(x, z, false);
|
||||
+ }
|
||||
|
@ -103,7 +103,7 @@
|
|||
+ ChunkGenerator chunkgenerator = worlddimension.generator();
|
||||
+ // CraftBukkit start
|
||||
+ this.serverLevelData.setWorld(this);
|
||||
|
||||
+
|
||||
+ if (biomeProvider != null) {
|
||||
+ BiomeSource worldChunkManager = new CustomWorldChunkManager(this.getWorld(), biomeProvider, this.server.registryAccess().lookupOrThrow(Registries.BIOME));
|
||||
+ if (chunkgenerator instanceof NoiseBasedChunkGenerator cga) {
|
||||
|
@ -230,7 +230,7 @@
|
|||
|
||||
if (flag1) {
|
||||
this.resetEmptyTime();
|
||||
@@ -353,12 +413,14 @@
|
||||
@@ -353,12 +413,15 @@
|
||||
|
||||
if (flag1 || this.emptyTime++ < 300) {
|
||||
gameprofilerfiller.push("entities");
|
||||
|
@ -241,11 +241,12 @@
|
|||
gameprofilerfiller.pop();
|
||||
}
|
||||
|
||||
+ org.spigotmc.ActivationRange.activateEntities(this); // Spigot
|
||||
+ this.timings.entityTick.startTiming(); // Spigot
|
||||
this.entityTickList.forEach((entity) -> {
|
||||
if (!entity.isRemoved()) {
|
||||
if (!tickratemanager.isEntityFrozen(entity)) {
|
||||
@@ -383,6 +445,8 @@
|
||||
@@ -383,6 +446,8 @@
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -254,7 +255,7 @@
|
|||
gameprofilerfiller.pop();
|
||||
this.tickBlockEntities();
|
||||
}
|
||||
@@ -429,7 +493,7 @@
|
||||
@@ -429,7 +494,7 @@
|
||||
|
||||
private void wakeUpAllPlayers() {
|
||||
this.sleepStatus.removeAllSleepers();
|
||||
|
@ -263,7 +264,7 @@
|
|||
entityplayer.stopSleepInBed(false, false);
|
||||
});
|
||||
}
|
||||
@@ -456,7 +520,7 @@
|
||||
@@ -456,7 +521,7 @@
|
||||
entityhorseskeleton.setTrap(true);
|
||||
entityhorseskeleton.setAge(0);
|
||||
entityhorseskeleton.setPos((double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ());
|
||||
|
@ -272,7 +273,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
@@ -465,7 +529,7 @@
|
||||
@@ -465,7 +530,7 @@
|
||||
if (entitylightning != null) {
|
||||
entitylightning.moveTo(Vec3.atBottomCenterOf(blockposition));
|
||||
entitylightning.setVisualOnly(flag1);
|
||||
|
@ -281,7 +282,7 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
@@ -521,7 +585,7 @@
|
||||
@@ -521,7 +586,7 @@
|
||||
Biome biomebase = (Biome) this.getBiome(blockposition1).value();
|
||||
|
||||
if (biomebase.shouldFreeze(this, blockposition2)) {
|
||||
|
@ -290,7 +291,7 @@
|
|||
}
|
||||
|
||||
if (this.isRaining()) {
|
||||
@@ -537,10 +601,10 @@
|
||||
@@ -537,10 +602,10 @@
|
||||
BlockState iblockdata1 = (BlockState) iblockdata.setValue(SnowLayerBlock.LAYERS, j + 1);
|
||||
|
||||
Block.pushEntitiesUp(iblockdata, iblockdata1, this, blockposition1);
|
||||
|
@ -303,7 +304,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
@@ -701,33 +765,67 @@
|
||||
@@ -701,33 +766,67 @@
|
||||
this.rainLevel = Mth.clamp(this.rainLevel, 0.0F, 1.0F);
|
||||
}
|
||||
|
||||
|
@ -379,15 +380,22 @@
|
|||
}
|
||||
|
||||
public void resetEmptyTime() {
|
||||
@@ -754,6 +852,7 @@
|
||||
@@ -754,6 +853,14 @@
|
||||
}
|
||||
|
||||
public void tickNonPassenger(Entity entity) {
|
||||
+ // Spigot start
|
||||
+ if (!org.spigotmc.ActivationRange.checkIfActive(entity)) {
|
||||
+ entity.tickCount++;
|
||||
+ entity.inactiveTick();
|
||||
+ return;
|
||||
+ }
|
||||
+ // Spigot end
|
||||
+ entity.tickTimer.startTiming(); // Spigot
|
||||
entity.setOldPosAndRot();
|
||||
ProfilerFiller gameprofilerfiller = Profiler.get();
|
||||
|
||||
@@ -763,6 +862,7 @@
|
||||
@@ -763,6 +870,7 @@
|
||||
});
|
||||
gameprofilerfiller.incrementCounter("tickNonPassenger");
|
||||
entity.tick();
|
||||
|
@ -395,7 +403,7 @@
|
|||
gameprofilerfiller.pop();
|
||||
Iterator iterator = entity.getPassengers().iterator();
|
||||
|
||||
@@ -771,6 +871,7 @@
|
||||
@@ -771,6 +879,7 @@
|
||||
|
||||
this.tickPassenger(entity, entity1);
|
||||
}
|
||||
|
@ -403,7 +411,7 @@
|
|||
|
||||
}
|
||||
|
||||
@@ -786,6 +887,7 @@
|
||||
@@ -786,6 +895,7 @@
|
||||
});
|
||||
gameprofilerfiller.incrementCounter("tickPassenger");
|
||||
passenger.rideTick();
|
||||
|
@ -411,7 +419,7 @@
|
|||
gameprofilerfiller.pop();
|
||||
Iterator iterator = passenger.getPassengers().iterator();
|
||||
|
||||
@@ -810,6 +912,7 @@
|
||||
@@ -810,6 +920,7 @@
|
||||
ServerChunkCache chunkproviderserver = this.getChunkSource();
|
||||
|
||||
if (!savingDisabled) {
|
||||
|
@ -419,7 +427,7 @@
|
|||
if (progressListener != null) {
|
||||
progressListener.progressStartNoAbort(Component.translatable("menu.savingLevel"));
|
||||
}
|
||||
@@ -827,11 +930,19 @@
|
||||
@@ -827,11 +938,19 @@
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -440,7 +448,7 @@
|
|||
}
|
||||
|
||||
DimensionDataStorage worldpersistentdata = this.getChunkSource().getDataStorage();
|
||||
@@ -903,18 +1014,40 @@
|
||||
@@ -903,18 +1022,40 @@
|
||||
|
||||
@Override
|
||||
public boolean addFreshEntity(Entity entity) {
|
||||
|
@ -484,7 +492,7 @@
|
|||
}
|
||||
|
||||
}
|
||||
@@ -939,24 +1072,38 @@
|
||||
@@ -939,24 +1080,38 @@
|
||||
this.entityManager.addNewEntity(player);
|
||||
}
|
||||
|
||||
|
@ -527,7 +535,7 @@
|
|||
return true;
|
||||
}
|
||||
}
|
||||
@@ -967,13 +1114,35 @@
|
||||
@@ -967,13 +1122,35 @@
|
||||
}
|
||||
|
||||
public void removePlayerImmediately(ServerPlayer player, Entity.RemovalReason reason) {
|
||||
|
@ -564,7 +572,7 @@
|
|||
while (iterator.hasNext()) {
|
||||
ServerPlayer entityplayer = (ServerPlayer) iterator.next();
|
||||
|
||||
@@ -982,6 +1151,12 @@
|
||||
@@ -982,6 +1159,12 @@
|
||||
double d1 = (double) pos.getY() - entityplayer.getY();
|
||||
double d2 = (double) pos.getZ() - entityplayer.getZ();
|
||||
|
||||
|
@ -577,7 +585,7 @@
|
|||
if (d0 * d0 + d1 * d1 + d2 * d2 < 1024.0D) {
|
||||
entityplayer.connection.send(new ClientboundBlockDestructionPacket(entityId, pos, progress));
|
||||
}
|
||||
@@ -1060,7 +1235,18 @@
|
||||
@@ -1060,7 +1243,18 @@
|
||||
Iterator iterator = this.navigatingMobs.iterator();
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
|
@ -597,7 +605,7 @@
|
|||
PathNavigation navigationabstract = entityinsentient.getNavigation();
|
||||
|
||||
if (navigationabstract.shouldRecomputePath(pos)) {
|
||||
@@ -1126,9 +1312,15 @@
|
||||
@@ -1126,9 +1320,15 @@
|
||||
|
||||
@Override
|
||||
public void explode(@Nullable Entity entity, @Nullable DamageSource damageSource, @Nullable ExplosionDamageCalculator behavior, double x, double y, double z, float power, boolean createFire, Level.ExplosionInteraction explosionSourceType, ParticleOptions smallParticle, ParticleOptions largeParticle, Holder<SoundEvent> soundEvent) {
|
||||
|
@ -614,7 +622,7 @@
|
|||
case NONE:
|
||||
explosion_effect = Explosion.BlockInteraction.KEEP;
|
||||
break;
|
||||
@@ -1144,16 +1336,26 @@
|
||||
@@ -1144,16 +1344,26 @@
|
||||
case TRIGGER:
|
||||
explosion_effect = Explosion.BlockInteraction.TRIGGER_BLOCK;
|
||||
break;
|
||||
|
@ -644,7 +652,7 @@
|
|||
Iterator iterator = this.players.iterator();
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
@@ -1162,10 +1364,11 @@
|
||||
@@ -1162,10 +1372,11 @@
|
||||
if (entityplayer.distanceToSqr(vec3d) < 4096.0D) {
|
||||
Optional<Vec3> optional = Optional.ofNullable((Vec3) serverexplosion.getHitPlayers().get(entityplayer));
|
||||
|
||||
|
@ -657,7 +665,7 @@
|
|||
}
|
||||
|
||||
private Explosion.BlockInteraction getDestroyType(GameRules.Key<GameRules.BooleanValue> decayRule) {
|
||||
@@ -1226,17 +1429,24 @@
|
||||
@@ -1226,17 +1437,24 @@
|
||||
}
|
||||
|
||||
public <T extends ParticleOptions> int sendParticles(T parameters, double x, double y, double z, int count, double offsetX, double offsetY, double offsetZ, double speed) {
|
||||
|
@ -685,7 +693,7 @@
|
|||
++j;
|
||||
}
|
||||
}
|
||||
@@ -1292,7 +1502,7 @@
|
||||
@@ -1292,7 +1510,7 @@
|
||||
|
||||
@Nullable
|
||||
public BlockPos findNearestMapStructure(TagKey<Structure> structureTag, BlockPos pos, int radius, boolean skipReferencedStructures) {
|
||||
|
@ -694,7 +702,7 @@
|
|||
return null;
|
||||
} else {
|
||||
Optional<HolderSet.Named<Structure>> optional = this.registryAccess().lookupOrThrow(Registries.STRUCTURE).get(structureTag);
|
||||
@@ -1334,11 +1544,22 @@
|
||||
@@ -1334,11 +1552,22 @@
|
||||
@Nullable
|
||||
@Override
|
||||
public MapItemSavedData getMapData(MapId id) {
|
||||
|
@ -718,7 +726,7 @@
|
|||
this.getServer().overworld().getDataStorage().set(id.key(), state);
|
||||
}
|
||||
|
||||
@@ -1649,6 +1870,11 @@
|
||||
@@ -1649,6 +1878,11 @@
|
||||
@Override
|
||||
public void blockUpdated(BlockPos pos, Block block) {
|
||||
if (!this.isDebug()) {
|
||||
|
@ -730,7 +738,7 @@
|
|||
this.updateNeighborsAt(pos, block);
|
||||
}
|
||||
|
||||
@@ -1668,12 +1894,12 @@
|
||||
@@ -1668,12 +1902,12 @@
|
||||
}
|
||||
|
||||
public boolean isFlat() {
|
||||
|
@ -745,7 +753,7 @@
|
|||
}
|
||||
|
||||
@Nullable
|
||||
@@ -1696,7 +1922,7 @@
|
||||
@@ -1696,7 +1930,7 @@
|
||||
private static <T> String getTypeCount(Iterable<T> items, Function<T, String> classifier) {
|
||||
try {
|
||||
Object2IntOpenHashMap<String> object2intopenhashmap = new Object2IntOpenHashMap();
|
||||
|
@ -754,7 +762,7 @@
|
|||
|
||||
while (iterator.hasNext()) {
|
||||
T t0 = iterator.next();
|
||||
@@ -1705,7 +1931,7 @@
|
||||
@@ -1705,7 +1939,7 @@
|
||||
object2intopenhashmap.addTo(s, 1);
|
||||
}
|
||||
|
||||
|
@ -763,7 +771,7 @@
|
|||
String s1 = (String) entry.getKey();
|
||||
|
||||
return s1 + ":" + entry.getIntValue();
|
||||
@@ -1717,6 +1943,7 @@
|
||||
@@ -1717,6 +1951,7 @@
|
||||
|
||||
@Override
|
||||
public LevelEntityGetter<Entity> getEntities() {
|
||||
|
@ -771,7 +779,7 @@
|
|||
return this.entityManager.getEntityGetter();
|
||||
}
|
||||
|
||||
@@ -1836,6 +2063,7 @@
|
||||
@@ -1836,6 +2071,7 @@
|
||||
}
|
||||
|
||||
public void onTrackingStart(Entity entity) {
|
||||
|
@ -779,7 +787,7 @@
|
|||
ServerLevel.this.getChunkSource().addEntity(entity);
|
||||
if (entity instanceof ServerPlayer entityplayer) {
|
||||
ServerLevel.this.players.add(entityplayer);
|
||||
@@ -1864,9 +2092,12 @@
|
||||
@@ -1864,9 +2100,12 @@
|
||||
}
|
||||
|
||||
entity.updateDynamicGameEventListener(DynamicGameEventListener::add);
|
||||
|
@ -792,7 +800,7 @@
|
|||
ServerLevel.this.getChunkSource().removeEntity(entity);
|
||||
if (entity instanceof ServerPlayer entityplayer) {
|
||||
ServerLevel.this.players.remove(entityplayer);
|
||||
@@ -1895,6 +2126,14 @@
|
||||
@@ -1895,6 +2134,14 @@
|
||||
}
|
||||
|
||||
entity.updateDynamicGameEventListener(DynamicGameEventListener::remove);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
--- a/net/minecraft/world/entity/AgeableMob.java
|
||||
+++ b/net/minecraft/world/entity/AgeableMob.java
|
||||
@@ -21,6 +21,7 @@
|
||||
@@ -21,12 +21,38 @@
|
||||
protected int age;
|
||||
protected int forcedAge;
|
||||
protected int forcedAgeTimer;
|
||||
|
@ -8,7 +8,38 @@
|
|||
|
||||
protected AgeableMob(EntityType<? extends AgeableMob> type, Level world) {
|
||||
super(type, world);
|
||||
@@ -104,6 +105,7 @@
|
||||
}
|
||||
|
||||
+ // Spigot start
|
||||
@Override
|
||||
+ public void inactiveTick()
|
||||
+ {
|
||||
+ super.inactiveTick();
|
||||
+ if ( this.level().isClientSide || this.ageLocked )
|
||||
+ { // CraftBukkit
|
||||
+ this.refreshDimensions();
|
||||
+ } else
|
||||
+ {
|
||||
+ int i = this.getAge();
|
||||
+
|
||||
+ if ( i < 0 )
|
||||
+ {
|
||||
+ ++i;
|
||||
+ this.setAge( i );
|
||||
+ } else if ( i > 0 )
|
||||
+ {
|
||||
+ --i;
|
||||
+ this.setAge( i );
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ // Spigot end
|
||||
+
|
||||
+ @Override
|
||||
public SpawnGroupData finalizeSpawn(ServerLevelAccessor world, DifficultyInstance difficulty, EntitySpawnReason spawnReason, @Nullable SpawnGroupData entityData) {
|
||||
if (entityData == null) {
|
||||
entityData = new AgeableMob.AgeableMobGroupData(true);
|
||||
@@ -104,6 +130,7 @@
|
||||
super.addAdditionalSaveData(nbt);
|
||||
nbt.putInt("Age", this.getAge());
|
||||
nbt.putInt("ForcedAge", this.forcedAge);
|
||||
|
@ -16,7 +47,7 @@
|
|||
}
|
||||
|
||||
@Override
|
||||
@@ -111,6 +113,7 @@
|
||||
@@ -111,6 +138,7 @@
|
||||
super.readAdditionalSaveData(nbt);
|
||||
this.setAge(nbt.getInt("Age"));
|
||||
this.forcedAge = nbt.getInt("ForcedAge");
|
||||
|
@ -24,7 +55,7 @@
|
|||
}
|
||||
|
||||
@Override
|
||||
@@ -125,7 +128,7 @@
|
||||
@@ -125,7 +153,7 @@
|
||||
@Override
|
||||
public void aiStep() {
|
||||
super.aiStep();
|
||||
|
|
|
@ -22,7 +22,27 @@
|
|||
@Nullable
|
||||
public UUID ownerUUID;
|
||||
|
||||
@@ -200,7 +206,7 @@
|
||||
@@ -145,7 +151,19 @@
|
||||
this.duration = duration;
|
||||
}
|
||||
|
||||
+ // Spigot start - copied from below
|
||||
@Override
|
||||
+ public void inactiveTick() {
|
||||
+ super.inactiveTick();
|
||||
+
|
||||
+ if (this.tickCount >= this.waitTime + this.duration) {
|
||||
+ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+ // Spigot end
|
||||
+
|
||||
+ @Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
Level world = this.level();
|
||||
@@ -200,7 +218,7 @@
|
||||
|
||||
private void serverTick(ServerLevel world) {
|
||||
if (this.tickCount >= this.waitTime + this.duration) {
|
||||
|
@ -31,7 +51,7 @@
|
|||
} else {
|
||||
boolean flag = this.isWaiting();
|
||||
boolean flag1 = this.tickCount < this.waitTime;
|
||||
@@ -215,7 +221,7 @@
|
||||
@@ -215,7 +233,7 @@
|
||||
if (this.radiusPerTick != 0.0F) {
|
||||
f += this.radiusPerTick;
|
||||
if (f < 0.5F) {
|
||||
|
@ -40,7 +60,7 @@
|
|||
return;
|
||||
}
|
||||
|
||||
@@ -244,16 +250,17 @@
|
||||
@@ -244,16 +262,17 @@
|
||||
}
|
||||
|
||||
list.addAll(this.potionContents.customEffects());
|
||||
|
@ -61,7 +81,7 @@
|
|||
|
||||
Objects.requireNonNull(entityliving);
|
||||
if (!stream.noneMatch(entityliving::canBeAffected)) {
|
||||
@@ -262,6 +269,19 @@
|
||||
@@ -262,6 +281,19 @@
|
||||
double d2 = d0 * d0 + d1 * d1;
|
||||
|
||||
if (d2 <= (double) (f * f)) {
|
||||
|
@ -81,7 +101,7 @@
|
|||
this.victims.put(entityliving, this.tickCount + this.reapplicationDelay);
|
||||
Iterator iterator2 = list.iterator();
|
||||
|
||||
@@ -271,14 +291,14 @@
|
||||
@@ -271,14 +303,14 @@
|
||||
if (((MobEffect) mobeffect1.getEffect().value()).isInstantenous()) {
|
||||
((MobEffect) mobeffect1.getEffect().value()).applyInstantenousEffect(world, this, this.getOwner(), entityliving, mobeffect1.getAmplifier(), 0.5D);
|
||||
} else {
|
||||
|
@ -98,7 +118,7 @@
|
|||
return;
|
||||
}
|
||||
|
||||
@@ -288,7 +308,7 @@
|
||||
@@ -288,7 +320,7 @@
|
||||
if (this.durationOnUse != 0) {
|
||||
this.duration += this.durationOnUse;
|
||||
if (this.duration <= 0) {
|
||||
|
@ -107,7 +127,7 @@
|
|||
return;
|
||||
}
|
||||
}
|
||||
@@ -336,14 +356,14 @@
|
||||
@@ -336,14 +368,14 @@
|
||||
this.waitTime = waitTime;
|
||||
}
|
||||
|
||||
|
@ -124,7 +144,7 @@
|
|||
if (this.owner != null && !this.owner.isRemoved()) {
|
||||
return this.owner;
|
||||
} else {
|
||||
@@ -353,10 +373,10 @@
|
||||
@@ -353,10 +385,10 @@
|
||||
if (world instanceof ServerLevel) {
|
||||
ServerLevel worldserver = (ServerLevel) world;
|
||||
Entity entity = worldserver.getEntity(this.ownerUUID);
|
||||
|
|
|
@ -96,7 +96,7 @@
|
|||
private static final EntityDataAccessor<Integer> DATA_TICKS_FROZEN = SynchedEntityData.defineId(Entity.class, EntityDataSerializers.INT);
|
||||
private EntityInLevelCallback levelCallback;
|
||||
private final VecDeltaCodec packetPositionCodec;
|
||||
@@ -253,7 +312,32 @@
|
||||
@@ -253,6 +312,37 @@
|
||||
private final List<Entity.Movement> movementThisTick;
|
||||
private final Set<BlockState> blocksInside;
|
||||
private final LongSet visitedBlocks;
|
||||
|
@ -116,7 +116,13 @@
|
|||
+ // Main use case currently is for SPIGOT-7487, preventing dropping of leash when leash is removed
|
||||
+ public boolean pluginRemoved = false;
|
||||
+ public CustomTimingsHandler tickTimer = org.bukkit.craftbukkit.SpigotTimings.getEntityTimings(this); // Spigot
|
||||
|
||||
+ // Spigot start
|
||||
+ public final org.spigotmc.ActivationRange.ActivationType activationType = org.spigotmc.ActivationRange.initializeEntityActivationType(this);
|
||||
+ public final boolean defaultActivationState;
|
||||
+ public long activatedTick = Integer.MIN_VALUE;
|
||||
+ public void inactiveTick() { }
|
||||
+ // Spigot end
|
||||
+
|
||||
+ public float getBukkitYaw() {
|
||||
+ return this.yRot;
|
||||
+ }
|
||||
|
@ -125,11 +131,24 @@
|
|||
+ return this.level.hasChunk((int) Math.floor(this.getX()) >> 4, (int) Math.floor(this.getZ()) >> 4);
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
|
||||
public Entity(EntityType<?> type, Level world) {
|
||||
this.id = Entity.ENTITY_COUNTER.incrementAndGet();
|
||||
this.passengers = ImmutableList.of();
|
||||
@@ -292,7 +376,7 @@
|
||||
@@ -284,6 +374,13 @@
|
||||
this.position = Vec3.ZERO;
|
||||
this.blockPosition = BlockPos.ZERO;
|
||||
this.chunkPosition = ChunkPos.ZERO;
|
||||
+ // Spigot start
|
||||
+ if (world != null) {
|
||||
+ this.defaultActivationState = org.spigotmc.ActivationRange.initializeEntityActivationState(this, world.spigotConfig);
|
||||
+ } else {
|
||||
+ this.defaultActivationState = false;
|
||||
+ }
|
||||
+ // Spigot end
|
||||
SynchedEntityData.Builder datawatcher_a = new SynchedEntityData.Builder(this);
|
||||
|
||||
datawatcher_a.define(Entity.DATA_SHARED_FLAGS_ID, (byte) 0);
|
||||
@@ -292,7 +389,7 @@
|
||||
datawatcher_a.define(Entity.DATA_CUSTOM_NAME, Optional.empty());
|
||||
datawatcher_a.define(Entity.DATA_SILENT, false);
|
||||
datawatcher_a.define(Entity.DATA_NO_GRAVITY, false);
|
||||
|
@ -138,7 +157,7 @@
|
|||
datawatcher_a.define(Entity.DATA_TICKS_FROZEN, 0);
|
||||
this.defineSynchedData(datawatcher_a);
|
||||
this.entityData = datawatcher_a.build();
|
||||
@@ -362,20 +446,36 @@
|
||||
@@ -362,20 +459,36 @@
|
||||
}
|
||||
|
||||
public void kill(ServerLevel world) {
|
||||
|
@ -177,7 +196,7 @@
|
|||
public boolean equals(Object object) {
|
||||
return object instanceof Entity ? ((Entity) object).id == this.id : false;
|
||||
}
|
||||
@@ -385,22 +485,34 @@
|
||||
@@ -385,22 +498,34 @@
|
||||
}
|
||||
|
||||
public void remove(Entity.RemovalReason reason) {
|
||||
|
@ -217,7 +236,7 @@
|
|||
return this.getPose() == pose;
|
||||
}
|
||||
|
||||
@@ -417,6 +529,33 @@
|
||||
@@ -417,6 +542,33 @@
|
||||
}
|
||||
|
||||
public void setRot(float yaw, float pitch) {
|
||||
|
@ -251,7 +270,7 @@
|
|||
this.setYRot(yaw % 360.0F);
|
||||
this.setXRot(pitch % 360.0F);
|
||||
}
|
||||
@@ -462,6 +601,15 @@
|
||||
@@ -462,6 +614,15 @@
|
||||
this.baseTick();
|
||||
}
|
||||
|
||||
|
@ -267,7 +286,7 @@
|
|||
public void baseTick() {
|
||||
ProfilerFiller gameprofilerfiller = Profiler.get();
|
||||
|
||||
@@ -475,7 +623,7 @@
|
||||
@@ -475,7 +636,7 @@
|
||||
--this.boardingCooldown;
|
||||
}
|
||||
|
||||
|
@ -276,7 +295,7 @@
|
|||
if (this.canSpawnSprintParticle()) {
|
||||
this.spawnSprintParticle();
|
||||
}
|
||||
@@ -514,6 +662,10 @@
|
||||
@@ -514,6 +675,10 @@
|
||||
if (this.isInLava()) {
|
||||
this.lavaHurt();
|
||||
this.fallDistance *= 0.5F;
|
||||
|
@ -287,7 +306,7 @@
|
|||
}
|
||||
|
||||
this.checkBelowWorld();
|
||||
@@ -525,7 +677,7 @@
|
||||
@@ -525,7 +690,7 @@
|
||||
world = this.level();
|
||||
if (world instanceof ServerLevel worldserver) {
|
||||
if (this instanceof Leashable) {
|
||||
|
@ -296,7 +315,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
@@ -568,15 +720,32 @@
|
||||
@@ -568,15 +733,32 @@
|
||||
|
||||
public void lavaHurt() {
|
||||
if (!this.fireImmune()) {
|
||||
|
@ -331,7 +350,7 @@
|
|||
}
|
||||
|
||||
}
|
||||
@@ -587,9 +756,25 @@
|
||||
@@ -587,9 +769,25 @@
|
||||
}
|
||||
|
||||
public final void igniteForSeconds(float seconds) {
|
||||
|
@ -358,7 +377,7 @@
|
|||
public void igniteForTicks(int ticks) {
|
||||
if (this.remainingFireTicks < ticks) {
|
||||
this.setRemainingFireTicks(ticks);
|
||||
@@ -610,7 +795,7 @@
|
||||
@@ -610,7 +808,7 @@
|
||||
}
|
||||
|
||||
protected void onBelowWorld() {
|
||||
|
@ -367,7 +386,7 @@
|
|||
}
|
||||
|
||||
public boolean isFree(double offsetX, double offsetY, double offsetZ) {
|
||||
@@ -672,6 +857,7 @@
|
||||
@@ -672,6 +870,7 @@
|
||||
}
|
||||
|
||||
public void move(MoverType type, Vec3 movement) {
|
||||
|
@ -375,10 +394,13 @@
|
|||
if (this.noPhysics) {
|
||||
this.setPos(this.getX() + movement.x, this.getY() + movement.y, this.getZ() + movement.z);
|
||||
} else {
|
||||
@@ -750,6 +936,28 @@
|
||||
}
|
||||
}
|
||||
@@ -747,8 +946,30 @@
|
||||
|
||||
if (movement.y != vec3d1.y) {
|
||||
block.updateEntityMovementAfterFallOn(this.level(), this);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ // CraftBukkit start
|
||||
+ if (this.horizontalCollision && this.getBukkitEntity() instanceof Vehicle) {
|
||||
+ Vehicle vehicle = (Vehicle) this.getBukkitEntity();
|
||||
|
@ -392,19 +414,18 @@
|
|||
+ bl = bl.getRelative(BlockFace.SOUTH);
|
||||
+ } else if (movement.z < vec3d1.z) {
|
||||
+ bl = bl.getRelative(BlockFace.NORTH);
|
||||
+ }
|
||||
}
|
||||
+
|
||||
+ if (!bl.getType().isAir()) {
|
||||
+ VehicleBlockCollisionEvent event = new VehicleBlockCollisionEvent(vehicle, bl);
|
||||
+ this.level.getCraftServer().getPluginManager().callEvent(event);
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
|
||||
if (!this.level().isClientSide() || this.isControlledByLocalInstance()) {
|
||||
Entity.MovementEmission entity_movementemission = this.getMovementEmission();
|
||||
|
||||
@@ -764,6 +972,7 @@
|
||||
@@ -764,6 +985,7 @@
|
||||
gameprofilerfiller.pop();
|
||||
}
|
||||
}
|
||||
|
@ -412,10 +433,11 @@
|
|||
}
|
||||
|
||||
private void applyMovementEmissionAndPlaySound(Entity.MovementEmission moveEffect, Vec3 movement, BlockPos landingPos, BlockState landingState) {
|
||||
@@ -1132,6 +1341,20 @@
|
||||
@@ -1131,8 +1353,22 @@
|
||||
|
||||
protected SoundEvent getSwimHighSpeedSplashSound() {
|
||||
return SoundEvents.GENERIC_SPLASH;
|
||||
}
|
||||
+ }
|
||||
+
|
||||
+ // CraftBukkit start - Add delegate methods
|
||||
+ public SoundEvent getSwimSound0() {
|
||||
|
@ -424,16 +446,17 @@
|
|||
+
|
||||
+ public SoundEvent getSwimSplashSound0() {
|
||||
+ return this.getSwimSplashSound();
|
||||
+ }
|
||||
+
|
||||
}
|
||||
|
||||
+ public SoundEvent getSwimHighSpeedSplashSound0() {
|
||||
+ return this.getSwimHighSpeedSplashSound();
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
|
||||
+
|
||||
public void recordMovementThroughBlocks(Vec3 oldPos, Vec3 newPos) {
|
||||
this.movementThisTick.add(new Entity.Movement(oldPos, newPos));
|
||||
@@ -1609,6 +1832,7 @@
|
||||
}
|
||||
@@ -1609,6 +1845,7 @@
|
||||
this.yo = y;
|
||||
this.zo = d4;
|
||||
this.setPos(d3, y, d4);
|
||||
|
@ -441,20 +464,21 @@
|
|||
}
|
||||
|
||||
public void moveTo(Vec3 pos) {
|
||||
@@ -1861,6 +2085,12 @@
|
||||
return false;
|
||||
}
|
||||
@@ -1859,7 +2096,13 @@
|
||||
|
||||
public boolean isPushable() {
|
||||
return false;
|
||||
+ }
|
||||
+
|
||||
+ // CraftBukkit start - collidable API
|
||||
+ public boolean canCollideWithBukkit(Entity entity) {
|
||||
+ return this.isPushable();
|
||||
+ }
|
||||
}
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
|
||||
public void awardKillScore(Entity entityKilled, DamageSource damageSource) {
|
||||
if (entityKilled instanceof ServerPlayer) {
|
||||
CriteriaTriggers.ENTITY_KILLED_PLAYER.trigger((ServerPlayer) entityKilled, this, damageSource);
|
||||
@@ -1889,16 +2119,22 @@
|
||||
@@ -1889,16 +2132,22 @@
|
||||
}
|
||||
|
||||
public boolean saveAsPassenger(CompoundTag nbt) {
|
||||
|
@ -480,7 +504,7 @@
|
|||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1909,54 +2145,97 @@
|
||||
@@ -1909,54 +2158,97 @@
|
||||
}
|
||||
|
||||
public CompoundTag saveWithoutId(CompoundTag nbt) {
|
||||
|
@ -598,7 +622,7 @@
|
|||
}
|
||||
|
||||
ListTag nbttaglist;
|
||||
@@ -1972,10 +2251,10 @@
|
||||
@@ -1972,10 +2264,10 @@
|
||||
nbttaglist.add(StringTag.valueOf(s));
|
||||
}
|
||||
|
||||
|
@ -611,7 +635,7 @@
|
|||
if (this.isVehicle()) {
|
||||
nbttaglist = new ListTag();
|
||||
iterator = this.getPassengers().iterator();
|
||||
@@ -1984,17 +2263,22 @@
|
||||
@@ -1984,17 +2276,22 @@
|
||||
Entity entity = (Entity) iterator.next();
|
||||
CompoundTag nbttagcompound1 = new CompoundTag();
|
||||
|
||||
|
@ -637,7 +661,7 @@
|
|||
} catch (Throwable throwable) {
|
||||
CrashReport crashreport = CrashReport.forThrowable(throwable, "Saving entity NBT");
|
||||
CrashReportCategory crashreportsystemdetails = crashreport.addCategory("Entity being saved");
|
||||
@@ -2080,6 +2364,45 @@
|
||||
@@ -2080,6 +2377,45 @@
|
||||
} else {
|
||||
throw new IllegalStateException("Entity has invalid position");
|
||||
}
|
||||
|
@ -683,7 +707,7 @@
|
|||
} catch (Throwable throwable) {
|
||||
CrashReport crashreport = CrashReport.forThrowable(throwable, "Loading entity NBT");
|
||||
CrashReportCategory crashreportsystemdetails = crashreport.addCategory("Entity being loaded");
|
||||
@@ -2101,6 +2424,12 @@
|
||||
@@ -2101,6 +2437,12 @@
|
||||
return entitytypes.canSerialize() && minecraftkey != null ? minecraftkey.toString() : null;
|
||||
}
|
||||
|
||||
|
@ -696,7 +720,7 @@
|
|||
protected abstract void readAdditionalSaveData(CompoundTag nbt);
|
||||
|
||||
protected abstract void addAdditionalSaveData(CompoundTag nbt);
|
||||
@@ -2153,9 +2482,22 @@
|
||||
@@ -2153,9 +2495,22 @@
|
||||
if (stack.isEmpty()) {
|
||||
return null;
|
||||
} else {
|
||||
|
@ -719,7 +743,7 @@
|
|||
world.addFreshEntity(entityitem);
|
||||
return entityitem;
|
||||
}
|
||||
@@ -2184,6 +2526,12 @@
|
||||
@@ -2184,6 +2539,12 @@
|
||||
if (this.isAlive() && this instanceof Leashable leashable) {
|
||||
if (leashable.getLeashHolder() == player) {
|
||||
if (!this.level().isClientSide()) {
|
||||
|
@ -732,7 +756,7 @@
|
|||
if (player.hasInfiniteMaterials()) {
|
||||
leashable.removeLeash();
|
||||
} else {
|
||||
@@ -2200,6 +2548,13 @@
|
||||
@@ -2200,6 +2561,13 @@
|
||||
|
||||
if (itemstack.is(Items.LEAD) && leashable.canHaveALeashAttachedToIt()) {
|
||||
if (!this.level().isClientSide()) {
|
||||
|
@ -746,7 +770,7 @@
|
|||
leashable.setLeashedTo(player, true);
|
||||
}
|
||||
|
||||
@@ -2265,7 +2620,7 @@
|
||||
@@ -2265,7 +2633,7 @@
|
||||
}
|
||||
|
||||
public boolean showVehicleHealth() {
|
||||
|
@ -755,7 +779,7 @@
|
|||
}
|
||||
|
||||
public boolean startRiding(Entity entity, boolean force) {
|
||||
@@ -2273,7 +2628,7 @@
|
||||
@@ -2273,7 +2641,7 @@
|
||||
return false;
|
||||
} else if (!entity.couldAcceptPassenger()) {
|
||||
return false;
|
||||
|
@ -764,7 +788,7 @@
|
|||
return false;
|
||||
} else {
|
||||
for (Entity entity1 = entity; entity1.vehicle != null; entity1 = entity1.vehicle) {
|
||||
@@ -2285,11 +2640,32 @@
|
||||
@@ -2285,11 +2653,32 @@
|
||||
if (!force && (!this.canRide(entity) || !entity.canAddPassenger(this))) {
|
||||
return false;
|
||||
} else {
|
||||
|
@ -798,7 +822,7 @@
|
|||
this.vehicle = entity;
|
||||
this.vehicle.addPassenger(this);
|
||||
entity.getIndirectPassengersStream().filter((entity2) -> {
|
||||
@@ -2318,7 +2694,7 @@
|
||||
@@ -2318,7 +2707,7 @@
|
||||
Entity entity = this.vehicle;
|
||||
|
||||
this.vehicle = null;
|
||||
|
@ -807,7 +831,7 @@
|
|||
}
|
||||
|
||||
}
|
||||
@@ -2349,21 +2725,50 @@
|
||||
@@ -2349,21 +2738,50 @@
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -864,7 +888,7 @@
|
|||
}
|
||||
|
||||
protected boolean canAddPassenger(Entity passenger) {
|
||||
@@ -2464,7 +2869,7 @@
|
||||
@@ -2464,7 +2882,7 @@
|
||||
if (teleporttransition != null) {
|
||||
ServerLevel worldserver1 = teleporttransition.newLevel();
|
||||
|
||||
|
@ -873,7 +897,7 @@
|
|||
this.teleport(teleporttransition);
|
||||
}
|
||||
}
|
||||
@@ -2547,7 +2952,7 @@
|
||||
@@ -2547,7 +2965,7 @@
|
||||
}
|
||||
|
||||
public boolean isCrouching() {
|
||||
|
@ -882,7 +906,7 @@
|
|||
}
|
||||
|
||||
public boolean isSprinting() {
|
||||
@@ -2563,7 +2968,7 @@
|
||||
@@ -2563,7 +2981,7 @@
|
||||
}
|
||||
|
||||
public boolean isVisuallySwimming() {
|
||||
|
@ -891,7 +915,7 @@
|
|||
}
|
||||
|
||||
public boolean isVisuallyCrawling() {
|
||||
@@ -2571,6 +2976,13 @@
|
||||
@@ -2571,6 +2989,13 @@
|
||||
}
|
||||
|
||||
public void setSwimming(boolean swimming) {
|
||||
|
@ -905,7 +929,7 @@
|
|||
this.setSharedFlag(4, swimming);
|
||||
}
|
||||
|
||||
@@ -2624,8 +3036,12 @@
|
||||
@@ -2624,8 +3049,12 @@
|
||||
return this.getTeam() != null ? this.getTeam().isAlliedTo(team) : false;
|
||||
}
|
||||
|
||||
|
@ -919,7 +943,7 @@
|
|||
}
|
||||
|
||||
public boolean getSharedFlag(int index) {
|
||||
@@ -2644,7 +3060,7 @@
|
||||
@@ -2644,7 +3073,7 @@
|
||||
}
|
||||
|
||||
public int getMaxAirSupply() {
|
||||
|
@ -928,7 +952,7 @@
|
|||
}
|
||||
|
||||
public int getAirSupply() {
|
||||
@@ -2652,7 +3068,18 @@
|
||||
@@ -2652,7 +3081,18 @@
|
||||
}
|
||||
|
||||
public void setAirSupply(int air) {
|
||||
|
@ -948,7 +972,7 @@
|
|||
}
|
||||
|
||||
public int getTicksFrozen() {
|
||||
@@ -2679,11 +3106,40 @@
|
||||
@@ -2679,11 +3119,40 @@
|
||||
|
||||
public void thunderHit(ServerLevel world, LightningBolt lightning) {
|
||||
this.setRemainingFireTicks(this.remainingFireTicks + 1);
|
||||
|
@ -991,7 +1015,7 @@
|
|||
}
|
||||
|
||||
public void onAboveBubbleCol(boolean drag) {
|
||||
@@ -2713,7 +3169,7 @@
|
||||
@@ -2713,7 +3182,7 @@
|
||||
this.resetFallDistance();
|
||||
}
|
||||
|
||||
|
@ -1000,7 +1024,7 @@
|
|||
return true;
|
||||
}
|
||||
|
||||
@@ -2852,6 +3308,18 @@
|
||||
@@ -2852,6 +3321,18 @@
|
||||
|
||||
if (world instanceof ServerLevel worldserver) {
|
||||
if (!this.isRemoved()) {
|
||||
|
@ -1019,7 +1043,7 @@
|
|||
ServerLevel worldserver1 = teleportTarget.newLevel();
|
||||
boolean flag = worldserver1.dimension() != worldserver.dimension();
|
||||
|
||||
@@ -2920,8 +3388,12 @@
|
||||
@@ -2920,8 +3401,12 @@
|
||||
} else {
|
||||
entity.restoreFrom(this);
|
||||
this.removeAfterChangingDimensions();
|
||||
|
@ -1033,7 +1057,7 @@
|
|||
Iterator iterator1 = list1.iterator();
|
||||
|
||||
while (iterator1.hasNext()) {
|
||||
@@ -2947,7 +3419,7 @@
|
||||
@@ -2947,7 +3432,7 @@
|
||||
}
|
||||
|
||||
private void sendTeleportTransitionToRidingPlayers(TeleportTransition teleportTarget) {
|
||||
|
@ -1042,7 +1066,7 @@
|
|||
Iterator iterator = this.getIndirectPassengers().iterator();
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
@@ -2995,8 +3467,9 @@
|
||||
@@ -2995,8 +3480,9 @@
|
||||
}
|
||||
|
||||
protected void removeAfterChangingDimensions() {
|
||||
|
@ -1053,12 +1077,10 @@
|
|||
leashable.removeLeash();
|
||||
}
|
||||
|
||||
@@ -3004,7 +3477,21 @@
|
||||
|
||||
public Vec3 getRelativePortalPosition(Direction.Axis portalAxis, BlockUtil.FoundRectangle portalRect) {
|
||||
@@ -3006,6 +3492,20 @@
|
||||
return PortalShape.getRelativePosition(portalRect, portalAxis, this.position(), this.getDimensions(this.getPose()));
|
||||
+ }
|
||||
+
|
||||
}
|
||||
|
||||
+ // CraftBukkit start
|
||||
+ public CraftPortalEvent callPortalEvent(Entity entity, Location exit, PlayerTeleportEvent.TeleportCause cause, int searchRadius, int creationRadius) {
|
||||
+ org.bukkit.entity.Entity bukkitEntity = entity.getBukkitEntity();
|
||||
|
@ -1070,12 +1092,13 @@
|
|||
+ return null;
|
||||
+ }
|
||||
+ return new CraftPortalEvent(event);
|
||||
}
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
|
||||
+
|
||||
public boolean canUsePortal(boolean allowVehicles) {
|
||||
return (allowVehicles || !this.isPassenger()) && this.isAlive();
|
||||
@@ -3134,10 +3621,16 @@
|
||||
}
|
||||
@@ -3134,9 +3634,15 @@
|
||||
return (Boolean) this.entityData.get(Entity.DATA_CUSTOM_NAME_VISIBLE);
|
||||
}
|
||||
|
||||
|
@ -1086,16 +1109,15 @@
|
|||
+ public final boolean teleportTo(ServerLevel world, double destX, double destY, double destZ, Set<Relative> flags, float yaw, float pitch, boolean resetCamera) {
|
||||
+ return this.teleportTo(world, destX, destY, destZ, flags, yaw, pitch, resetCamera, PlayerTeleportEvent.TeleportCause.UNKNOWN);
|
||||
+ }
|
||||
|
||||
+
|
||||
+ public boolean teleportTo(ServerLevel worldserver, double d0, double d1, double d2, Set<Relative> set, float f, float f1, boolean flag, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause cause) {
|
||||
+ float f2 = Mth.clamp(f1, -90.0F, 90.0F);
|
||||
+ Entity entity = this.teleport(new TeleportTransition(worldserver, new Vec3(d0, d1, d2), Vec3.ZERO, f, f2, set, TeleportTransition.DO_NOTHING, cause));
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
|
||||
return entity != null;
|
||||
}
|
||||
|
||||
@@ -3187,7 +3680,7 @@
|
||||
@@ -3187,7 +3693,7 @@
|
||||
/** @deprecated */
|
||||
@Deprecated
|
||||
protected void fixupDimensions() {
|
||||
|
@ -1104,7 +1126,7 @@
|
|||
EntityDimensions entitysize = this.getDimensions(entitypose);
|
||||
|
||||
this.dimensions = entitysize;
|
||||
@@ -3196,7 +3689,7 @@
|
||||
@@ -3196,7 +3702,7 @@
|
||||
|
||||
public void refreshDimensions() {
|
||||
EntityDimensions entitysize = this.dimensions;
|
||||
|
@ -1113,7 +1135,7 @@
|
|||
EntityDimensions entitysize1 = this.getDimensions(entitypose);
|
||||
|
||||
this.dimensions = entitysize1;
|
||||
@@ -3258,10 +3751,29 @@
|
||||
@@ -3258,10 +3764,29 @@
|
||||
}
|
||||
|
||||
public final void setBoundingBox(AABB boundingBox) {
|
||||
|
@ -1145,7 +1167,7 @@
|
|||
return this.getDimensions(pose).eyeHeight();
|
||||
}
|
||||
|
||||
@@ -3335,7 +3847,7 @@
|
||||
@@ -3335,7 +3860,7 @@
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
@ -1154,7 +1176,7 @@
|
|||
return null;
|
||||
}
|
||||
|
||||
@@ -3435,7 +3947,7 @@
|
||||
@@ -3435,7 +3960,7 @@
|
||||
}
|
||||
|
||||
public boolean isControlledByLocalInstance() {
|
||||
|
@ -1163,7 +1185,7 @@
|
|||
|
||||
if (entityliving instanceof Player entityhuman) {
|
||||
return entityhuman.isLocalPlayer();
|
||||
@@ -3445,7 +3957,7 @@
|
||||
@@ -3445,7 +3970,7 @@
|
||||
}
|
||||
|
||||
public boolean isControlledByClient() {
|
||||
|
@ -1172,7 +1194,7 @@
|
|||
|
||||
return entityliving != null && entityliving.isControlledByClient();
|
||||
}
|
||||
@@ -3463,7 +3975,7 @@
|
||||
@@ -3463,7 +3988,7 @@
|
||||
return new Vec3((double) f1 * d2 / (double) f3, 0.0D, (double) f2 * d2 / (double) f3);
|
||||
}
|
||||
|
||||
|
@ -1181,7 +1203,7 @@
|
|||
return new Vec3(this.getX(), this.getBoundingBox().maxY, this.getZ());
|
||||
}
|
||||
|
||||
@@ -3489,8 +4001,37 @@
|
||||
@@ -3489,8 +4014,37 @@
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -1220,19 +1242,20 @@
|
|||
}
|
||||
|
||||
public void lookAt(EntityAnchorArgument.Anchor anchorPoint, Vec3 target) {
|
||||
@@ -3551,6 +4092,11 @@
|
||||
@@ -3550,7 +4104,12 @@
|
||||
|
||||
vec3d = vec3d.add(vec3d1);
|
||||
++k1;
|
||||
}
|
||||
+ }
|
||||
+ // CraftBukkit start - store last lava contact location
|
||||
+ if (tag == FluidTags.LAVA) {
|
||||
+ this.lastLavaContact = blockposition_mutableblockposition.immutable();
|
||||
+ }
|
||||
}
|
||||
+ // CraftBukkit end
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3613,7 +4159,7 @@
|
||||
@@ -3613,7 +4172,7 @@
|
||||
return new ClientboundAddEntityPacket(this, entityTrackerEntry);
|
||||
}
|
||||
|
||||
|
@ -1241,7 +1264,7 @@
|
|||
return this.type.getDimensions();
|
||||
}
|
||||
|
||||
@@ -3818,8 +4364,16 @@
|
||||
@@ -3818,8 +4377,16 @@
|
||||
|
||||
@Override
|
||||
public final void setRemoved(Entity.RemovalReason reason) {
|
||||
|
@ -1259,7 +1282,7 @@
|
|||
}
|
||||
|
||||
if (this.removalReason.shouldDestroy()) {
|
||||
@@ -3827,8 +4381,8 @@
|
||||
@@ -3827,8 +4394,8 @@
|
||||
}
|
||||
|
||||
this.getPassengers().forEach(Entity::stopRiding);
|
||||
|
@ -1270,7 +1293,7 @@
|
|||
}
|
||||
|
||||
public void unsetRemoved() {
|
||||
@@ -3887,7 +4441,7 @@
|
||||
@@ -3887,7 +4454,7 @@
|
||||
}
|
||||
|
||||
public Vec3 getKnownMovement() {
|
||||
|
|
|
@ -17,10 +17,11 @@
|
|||
import net.minecraft.world.entity.projectile.AbstractArrow;
|
||||
import net.minecraft.world.entity.projectile.Projectile;
|
||||
import net.minecraft.world.item.AxeItem;
|
||||
@@ -136,6 +137,32 @@
|
||||
@@ -135,6 +136,32 @@
|
||||
import net.minecraft.world.scores.PlayerTeam;
|
||||
import net.minecraft.world.scores.Scoreboard;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
+
|
||||
+// CraftBukkit start
|
||||
+import java.util.ArrayList;
|
||||
+import java.util.HashSet;
|
||||
|
@ -46,10 +47,9 @@
|
|||
+// CraftBukkit end
|
||||
+
|
||||
+import org.bukkit.craftbukkit.SpigotTimings; // Spigot
|
||||
+
|
||||
|
||||
public abstract class LivingEntity extends Entity implements Attackable {
|
||||
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
@@ -174,7 +201,7 @@
|
||||
public static final float DEFAULT_BABY_SCALE = 0.5F;
|
||||
public static final String ATTRIBUTES_FIELD = "attributes";
|
||||
|
@ -68,7 +68,7 @@
|
|||
public int lastHurtByPlayerTime;
|
||||
protected boolean dead;
|
||||
protected int noActionTime;
|
||||
@@ -260,7 +287,20 @@
|
||||
@@ -260,7 +287,27 @@
|
||||
protected boolean skipDropExperience;
|
||||
private final EnumMap<EquipmentSlot, Reference2ObjectMap<Enchantment, Set<EnchantmentLocationBasedEffect>>> activeLocationDependentEnchantments;
|
||||
protected float appliedScale;
|
||||
|
@ -85,11 +85,18 @@
|
|||
+ return this.getYHeadRot();
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+ // Spigot start
|
||||
+ public void inactiveTick()
|
||||
+ {
|
||||
+ super.inactiveTick();
|
||||
+ ++this.noActionTime; // Above all the floats
|
||||
+ }
|
||||
+ // Spigot end
|
||||
+
|
||||
protected LivingEntity(EntityType<? extends LivingEntity> type, Level world) {
|
||||
super(type, world);
|
||||
this.lastHandItemStacks = NonNullList.withSize(2, ItemStack.EMPTY);
|
||||
@@ -276,7 +316,9 @@
|
||||
@@ -276,7 +323,9 @@
|
||||
this.activeLocationDependentEnchantments = new EnumMap(EquipmentSlot.class);
|
||||
this.appliedScale = 1.0F;
|
||||
this.attributes = new AttributeMap(DefaultAttributes.getSupplier(type));
|
||||
|
@ -100,7 +107,7 @@
|
|||
this.blocksBuilding = true;
|
||||
this.rotA = (float) ((Math.random() + 1.0D) * 0.009999999776482582D);
|
||||
this.reapplyPosition();
|
||||
@@ -356,7 +398,13 @@
|
||||
@@ -356,7 +405,13 @@
|
||||
double d8 = Math.min((double) (0.2F + f / 15.0F), 2.5D);
|
||||
int i = (int) (150.0D * d8);
|
||||
|
||||
|
@ -115,7 +122,7 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
@@ -402,7 +450,7 @@
|
||||
@@ -402,7 +457,7 @@
|
||||
}
|
||||
|
||||
if (this.isAlive()) {
|
||||
|
@ -124,7 +131,7 @@
|
|||
Level world1 = this.level();
|
||||
ServerLevel worldserver1;
|
||||
double d0;
|
||||
@@ -424,7 +472,7 @@
|
||||
@@ -424,7 +479,7 @@
|
||||
}
|
||||
|
||||
if (this.isEyeInFluid(FluidTags.WATER) && !this.level().getBlockState(BlockPos.containing(this.getX(), this.getEyeY(), this.getZ())).is(Blocks.BUBBLE_COLUMN)) {
|
||||
|
@ -133,7 +140,7 @@
|
|||
|
||||
if (flag1) {
|
||||
this.setAirSupply(this.decreaseAirSupply(this.getAirSupply()));
|
||||
@@ -573,7 +621,7 @@
|
||||
@@ -573,7 +628,7 @@
|
||||
++this.deathTime;
|
||||
if (this.deathTime >= 20 && !this.level().isClientSide() && !this.isRemoved()) {
|
||||
this.level().broadcastEntityEvent(this, (byte) 60);
|
||||
|
@ -142,7 +149,7 @@
|
|||
}
|
||||
|
||||
}
|
||||
@@ -629,7 +677,7 @@
|
||||
@@ -629,7 +684,7 @@
|
||||
return this.lastHurtByMobTimestamp;
|
||||
}
|
||||
|
||||
|
@ -151,27 +158,28 @@
|
|||
this.lastHurtByPlayer = attacking;
|
||||
this.lastHurtByPlayerTime = this.tickCount;
|
||||
}
|
||||
@@ -679,17 +727,23 @@
|
||||
@@ -679,17 +734,23 @@
|
||||
}
|
||||
|
||||
public void onEquipItem(EquipmentSlot slot, ItemStack oldStack, ItemStack newStack) {
|
||||
- if (!this.level().isClientSide() && !this.isSpectator()) {
|
||||
- boolean flag = newStack.isEmpty() && oldStack.isEmpty();
|
||||
+ // CraftBukkit start
|
||||
+ this.onEquipItem(slot, oldStack, newStack, false);
|
||||
+ }
|
||||
+
|
||||
+ public void onEquipItem(EquipmentSlot enumitemslot, ItemStack itemstack, ItemStack itemstack1, boolean silent) {
|
||||
+ // CraftBukkit end
|
||||
if (!this.level().isClientSide() && !this.isSpectator()) {
|
||||
- boolean flag = newStack.isEmpty() && oldStack.isEmpty();
|
||||
+ boolean flag = itemstack1.isEmpty() && itemstack.isEmpty();
|
||||
|
||||
- if (!flag && !ItemStack.isSameItemSameComponents(oldStack, newStack) && !this.firstTick) {
|
||||
- Equippable equippable = (Equippable) newStack.get(DataComponents.EQUIPPABLE);
|
||||
+ if (!flag && !ItemStack.isSameItemSameComponents(itemstack, itemstack1) && !this.firstTick) {
|
||||
+ Equippable equippable = (Equippable) itemstack1.get(DataComponents.EQUIPPABLE);
|
||||
+ public void onEquipItem(EquipmentSlot enumitemslot, ItemStack itemstack, ItemStack itemstack1, boolean silent) {
|
||||
+ // CraftBukkit end
|
||||
+ if (!this.level().isClientSide() && !this.isSpectator()) {
|
||||
+ boolean flag = itemstack1.isEmpty() && itemstack.isEmpty();
|
||||
|
||||
- if (!this.isSilent() && equippable != null && slot == equippable.slot()) {
|
||||
- this.level().playSeededSound((Player) null, this.getX(), this.getY(), this.getZ(), equippable.equipSound(), this.getSoundSource(), 1.0F, 1.0F, this.random.nextLong());
|
||||
+ if (!flag && !ItemStack.isSameItemSameComponents(itemstack, itemstack1) && !this.firstTick) {
|
||||
+ Equippable equippable = (Equippable) itemstack1.get(DataComponents.EQUIPPABLE);
|
||||
+
|
||||
+ if (!this.isSilent() && equippable != null && enumitemslot == equippable.slot() && !silent) { // CraftBukkit
|
||||
+ this.level().playSeededSound((net.minecraft.world.entity.player.Player) null, this.getX(), this.getY(), this.getZ(), equippable.equipSound(), this.getSoundSource(), 1.0F, 1.0F, this.random.nextLong());
|
||||
}
|
||||
|
@ -181,7 +189,7 @@
|
|||
this.gameEvent(equippable != null ? GameEvent.EQUIP : GameEvent.UNEQUIP);
|
||||
}
|
||||
|
||||
@@ -699,17 +753,24 @@
|
||||
@@ -699,17 +760,24 @@
|
||||
|
||||
@Override
|
||||
public void remove(Entity.RemovalReason reason) {
|
||||
|
@ -209,7 +217,7 @@
|
|||
this.brain.clearMemories();
|
||||
}
|
||||
|
||||
@@ -722,6 +783,7 @@
|
||||
@@ -722,6 +790,7 @@
|
||||
mobeffect.onMobRemoved(world, this, reason);
|
||||
}
|
||||
|
||||
|
@ -217,7 +225,7 @@
|
|||
this.activeEffects.clear();
|
||||
}
|
||||
|
||||
@@ -781,6 +843,17 @@
|
||||
@@ -781,6 +850,17 @@
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -235,7 +243,7 @@
|
|||
if (nbt.contains("Health", 99)) {
|
||||
this.setHealth(nbt.getFloat("Health"));
|
||||
}
|
||||
@@ -819,9 +892,32 @@
|
||||
@@ -819,9 +899,32 @@
|
||||
|
||||
}
|
||||
|
||||
|
@ -268,7 +276,7 @@
|
|||
try {
|
||||
while (iterator.hasNext()) {
|
||||
Holder<MobEffect> holder = (Holder) iterator.next();
|
||||
@@ -831,6 +927,12 @@
|
||||
@@ -831,6 +934,12 @@
|
||||
this.onEffectUpdated(mobeffect, true, (Entity) null);
|
||||
})) {
|
||||
if (!this.level().isClientSide) {
|
||||
|
@ -281,7 +289,7 @@
|
|||
iterator.remove();
|
||||
this.onEffectsRemoved(List.of(mobeffect));
|
||||
}
|
||||
@@ -841,6 +943,17 @@
|
||||
@@ -841,6 +950,17 @@
|
||||
} catch (ConcurrentModificationException concurrentmodificationexception) {
|
||||
;
|
||||
}
|
||||
|
@ -299,7 +307,7 @@
|
|||
|
||||
if (this.effectsDirty) {
|
||||
if (!this.level().isClientSide) {
|
||||
@@ -921,7 +1034,7 @@
|
||||
@@ -921,7 +1041,7 @@
|
||||
}
|
||||
|
||||
public boolean canAttack(LivingEntity target) {
|
||||
|
@ -308,7 +316,7 @@
|
|||
}
|
||||
|
||||
public boolean canBeSeenAsEnemy() {
|
||||
@@ -952,17 +1065,36 @@
|
||||
@@ -952,17 +1072,36 @@
|
||||
this.entityData.set(LivingEntity.DATA_EFFECT_PARTICLES, List.of());
|
||||
}
|
||||
|
||||
|
@ -349,7 +357,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
@@ -987,24 +1119,55 @@
|
||||
@@ -987,24 +1126,55 @@
|
||||
return this.addEffect(effect, (Entity) null);
|
||||
}
|
||||
|
||||
|
@ -378,9 +386,6 @@
|
|||
+ MobEffectInstance mobeffect1 = (MobEffectInstance) this.activeEffects.get(mobeffect.getEffect());
|
||||
boolean flag = false;
|
||||
|
||||
- if (mobeffect1 == null) {
|
||||
- this.activeEffects.put(effect.getEffect(), effect);
|
||||
- this.onEffectAdded(effect, source);
|
||||
+ // CraftBukkit start
|
||||
+ boolean override = false;
|
||||
+ if (mobeffect1 != null) {
|
||||
|
@ -393,7 +398,9 @@
|
|||
+ }
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
+ if (mobeffect1 == null) {
|
||||
if (mobeffect1 == null) {
|
||||
- this.activeEffects.put(effect.getEffect(), effect);
|
||||
- this.onEffectAdded(effect, source);
|
||||
+ this.activeEffects.put(mobeffect.getEffect(), mobeffect);
|
||||
+ this.onEffectAdded(mobeffect, entity);
|
||||
flag = true;
|
||||
|
@ -414,7 +421,7 @@
|
|||
return flag;
|
||||
}
|
||||
}
|
||||
@@ -1031,14 +1194,40 @@
|
||||
@@ -1031,14 +1201,40 @@
|
||||
return this.getType().is(EntityTypeTags.INVERTED_HEALING_AND_HARM);
|
||||
}
|
||||
|
||||
|
@ -457,7 +464,7 @@
|
|||
if (mobeffect != null) {
|
||||
this.onEffectsRemoved(List.of(mobeffect));
|
||||
return true;
|
||||
@@ -1142,20 +1331,55 @@
|
||||
@@ -1142,20 +1338,55 @@
|
||||
|
||||
}
|
||||
|
||||
|
@ -514,7 +521,7 @@
|
|||
this.entityData.set(LivingEntity.DATA_HEALTH_ID, Mth.clamp(health, 0.0F, this.getMaxHealth()));
|
||||
}
|
||||
|
||||
@@ -1167,7 +1391,7 @@
|
||||
@@ -1167,7 +1398,7 @@
|
||||
public boolean hurtServer(ServerLevel world, DamageSource source, float amount) {
|
||||
if (this.isInvulnerableTo(world, source)) {
|
||||
return false;
|
||||
|
@ -523,7 +530,7 @@
|
|||
return false;
|
||||
} else if (source.is(DamageTypeTags.IS_FIRE) && this.hasEffect(MobEffects.FIRE_RESISTANCE)) {
|
||||
return false;
|
||||
@@ -1182,10 +1406,11 @@
|
||||
@@ -1182,10 +1413,11 @@
|
||||
}
|
||||
|
||||
float f1 = amount;
|
||||
|
@ -537,7 +544,7 @@
|
|||
this.hurtCurrentlyUsedShield(amount);
|
||||
f2 = amount;
|
||||
amount = 0.0F;
|
||||
@@ -1202,15 +1427,26 @@
|
||||
@@ -1202,15 +1434,26 @@
|
||||
flag = true;
|
||||
}
|
||||
|
||||
|
@ -566,7 +573,7 @@
|
|||
this.walkAnimation.setSpeed(1.5F);
|
||||
if (Float.isNaN(amount) || Float.isInfinite(amount)) {
|
||||
amount = Float.MAX_VALUE;
|
||||
@@ -1218,18 +1454,27 @@
|
||||
@@ -1218,18 +1461,27 @@
|
||||
|
||||
boolean flag1 = true;
|
||||
|
||||
|
@ -598,7 +605,7 @@
|
|||
this.hurtDuration = 10;
|
||||
this.hurtTime = this.hurtDuration;
|
||||
}
|
||||
@@ -1243,7 +1488,7 @@
|
||||
@@ -1243,7 +1495,7 @@
|
||||
world.broadcastDamageEvent(this, source);
|
||||
}
|
||||
|
||||
|
@ -607,7 +614,7 @@
|
|||
this.markHurt();
|
||||
}
|
||||
|
||||
@@ -1263,7 +1508,7 @@
|
||||
@@ -1263,7 +1515,7 @@
|
||||
d1 = source.getSourcePosition().z() - this.getZ();
|
||||
}
|
||||
|
||||
|
@ -616,7 +623,7 @@
|
|||
if (!flag) {
|
||||
this.indicateDamage(d0, d1);
|
||||
}
|
||||
@@ -1282,7 +1527,7 @@
|
||||
@@ -1282,7 +1534,7 @@
|
||||
this.playHurtSound(source);
|
||||
}
|
||||
|
||||
|
@ -625,7 +632,7 @@
|
|||
|
||||
if (flag2) {
|
||||
this.lastDamageSource = source;
|
||||
@@ -1329,10 +1574,10 @@
|
||||
@@ -1329,10 +1581,10 @@
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
@ -638,7 +645,7 @@
|
|||
this.lastHurtByPlayerTime = 100;
|
||||
this.lastHurtByPlayer = entityhuman;
|
||||
return entityhuman;
|
||||
@@ -1342,8 +1587,8 @@
|
||||
@@ -1342,8 +1594,8 @@
|
||||
this.lastHurtByPlayerTime = 100;
|
||||
LivingEntity entityliving = entitywolf.getOwner();
|
||||
|
||||
|
@ -649,7 +656,7 @@
|
|||
|
||||
this.lastHurtByPlayer = entityhuman1;
|
||||
} else {
|
||||
@@ -1363,7 +1608,7 @@
|
||||
@@ -1363,7 +1615,7 @@
|
||||
}
|
||||
|
||||
protected void blockedByShield(LivingEntity target) {
|
||||
|
@ -658,7 +665,7 @@
|
|||
}
|
||||
|
||||
private boolean checkTotemDeathProtection(DamageSource source) {
|
||||
@@ -1375,20 +1620,33 @@
|
||||
@@ -1375,20 +1627,33 @@
|
||||
InteractionHand[] aenumhand = InteractionHand.values();
|
||||
int i = aenumhand.length;
|
||||
|
||||
|
@ -696,7 +703,7 @@
|
|||
ServerPlayer entityplayer = (ServerPlayer) this;
|
||||
|
||||
entityplayer.awardStat(Stats.ITEM_USED.get(itemstack.getItem()));
|
||||
@@ -1512,14 +1770,22 @@
|
||||
@@ -1512,14 +1777,22 @@
|
||||
BlockState iblockdata = Blocks.WITHER_ROSE.defaultBlockState();
|
||||
|
||||
if (this.level().getBlockState(blockposition).isAir() && iblockdata.canSurvive(this.level(), blockposition)) {
|
||||
|
@ -721,7 +728,7 @@
|
|||
this.level().addFreshEntity(entityitem);
|
||||
}
|
||||
}
|
||||
@@ -1530,22 +1796,37 @@
|
||||
@@ -1530,24 +1803,39 @@
|
||||
protected void dropAllDeathLoot(ServerLevel world, DamageSource damageSource) {
|
||||
boolean flag = this.lastHurtByPlayerTime > 0;
|
||||
|
||||
|
@ -751,8 +758,8 @@
|
|||
}
|
||||
|
||||
+ return 0; // CraftBukkit
|
||||
+ }
|
||||
+
|
||||
}
|
||||
|
||||
+ protected void dropExperience(ServerLevel world, @Nullable Entity attacker) {
|
||||
+ // CraftBukkit start - Update getExpReward() above if the removed if() changes!
|
||||
+ if (!(this instanceof net.minecraft.world.entity.boss.enderdragon.EnderDragon)) { // CraftBukkit - SPIGOT-2420: Special case ender dragon will drop the xp over time
|
||||
|
@ -760,10 +767,12 @@
|
|||
+ this.expToDrop = 0;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
}
|
||||
|
||||
+ }
|
||||
+
|
||||
protected void dropCustomDeathLoot(ServerLevel world, DamageSource source, boolean causedByPlayer) {}
|
||||
@@ -1612,19 +1893,31 @@
|
||||
|
||||
public long getLootTableSeed() {
|
||||
@@ -1612,19 +1900,31 @@
|
||||
}
|
||||
|
||||
public void knockback(double strength, double x, double z) {
|
||||
|
@ -802,7 +811,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
@@ -1683,6 +1976,20 @@
|
||||
@@ -1683,6 +1983,20 @@
|
||||
return new LivingEntity.Fallsounds(SoundEvents.GENERIC_SMALL_FALL, SoundEvents.GENERIC_BIG_FALL);
|
||||
}
|
||||
|
||||
|
@ -823,7 +832,7 @@
|
|||
public Optional<BlockPos> getLastClimbablePos() {
|
||||
return this.lastClimbablePos;
|
||||
}
|
||||
@@ -1757,9 +2064,14 @@
|
||||
@@ -1757,9 +2071,14 @@
|
||||
int i = this.calculateFallDamage(fallDistance, damageMultiplier);
|
||||
|
||||
if (i > 0) {
|
||||
|
@ -839,7 +848,7 @@
|
|||
return true;
|
||||
} else {
|
||||
return flag;
|
||||
@@ -1830,7 +2142,7 @@
|
||||
@@ -1830,7 +2149,7 @@
|
||||
|
||||
protected float getDamageAfterArmorAbsorb(DamageSource source, float amount) {
|
||||
if (!source.is(DamageTypeTags.BYPASSES_ARMOR)) {
|
||||
|
@ -848,7 +857,7 @@
|
|||
amount = CombatRules.getDamageAfterAbsorb(this, amount, source, (float) this.getArmorValue(), (float) this.getAttributeValue(Attributes.ARMOR_TOUGHNESS));
|
||||
}
|
||||
|
||||
@@ -1841,7 +2153,8 @@
|
||||
@@ -1841,7 +2160,8 @@
|
||||
if (source.is(DamageTypeTags.BYPASSES_EFFECTS)) {
|
||||
return amount;
|
||||
} else {
|
||||
|
@ -858,7 +867,7 @@
|
|||
int i = (this.getEffect(MobEffects.DAMAGE_RESISTANCE).getAmplifier() + 1) * 5;
|
||||
int j = 25 - i;
|
||||
float f1 = amount * (float) j;
|
||||
@@ -1884,18 +2197,144 @@
|
||||
@@ -1884,18 +2204,144 @@
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1012,7 +1021,7 @@
|
|||
|
||||
if (entity instanceof ServerPlayer) {
|
||||
ServerPlayer entityplayer = (ServerPlayer) entity;
|
||||
@@ -1904,13 +2343,48 @@
|
||||
@@ -1904,13 +2350,48 @@
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1065,7 +1074,7 @@
|
|||
}
|
||||
|
||||
public CombatTracker getCombatTracker() {
|
||||
@@ -1935,8 +2409,18 @@
|
||||
@@ -1935,8 +2416,18 @@
|
||||
}
|
||||
|
||||
public final void setArrowCount(int stuckArrowCount) {
|
||||
|
@ -1085,7 +1094,7 @@
|
|||
|
||||
public final int getStingerCount() {
|
||||
return (Integer) this.entityData.get(LivingEntity.DATA_STINGER_COUNT_ID);
|
||||
@@ -1999,7 +2483,7 @@
|
||||
@@ -1999,7 +2490,7 @@
|
||||
this.playSound(soundeffect, this.getSoundVolume(), (this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 1.0F);
|
||||
}
|
||||
|
||||
|
@ -1094,20 +1103,20 @@
|
|||
this.setHealth(0.0F);
|
||||
this.die(this.damageSources().generic());
|
||||
}
|
||||
@@ -2182,6 +2666,12 @@
|
||||
@@ -2181,6 +2672,12 @@
|
||||
public abstract Iterable<ItemStack> getArmorSlots();
|
||||
|
||||
public abstract ItemStack getItemBySlot(EquipmentSlot slot);
|
||||
|
||||
+
|
||||
+ // CraftBukkit start
|
||||
+ public void setItemSlot(EquipmentSlot enumitemslot, ItemStack itemstack, boolean silent) {
|
||||
+ this.setItemSlot(enumitemslot, itemstack);
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
|
||||
public abstract void setItemSlot(EquipmentSlot slot, ItemStack stack);
|
||||
|
||||
public Iterable<ItemStack> getHandSlots() {
|
||||
@@ -2494,7 +2984,7 @@
|
||||
@@ -2494,7 +2991,7 @@
|
||||
|
||||
}
|
||||
|
||||
|
@ -1116,7 +1125,7 @@
|
|||
Vec3 vec3d1 = this.getRiddenInput(controllingPlayer, movementInput);
|
||||
|
||||
this.tickRidden(controllingPlayer, vec3d1);
|
||||
@@ -2507,13 +2997,13 @@
|
||||
@@ -2507,13 +3004,13 @@
|
||||
|
||||
}
|
||||
|
||||
|
@ -1133,7 +1142,7 @@
|
|||
return this.getSpeed();
|
||||
}
|
||||
|
||||
@@ -2571,7 +3061,7 @@
|
||||
@@ -2571,7 +3068,7 @@
|
||||
double d1 = Mth.clamp(motion.z, -0.15000000596046448D, 0.15000000596046448D);
|
||||
double d2 = Math.max(motion.y, -0.15000000596046448D);
|
||||
|
||||
|
@ -1142,7 +1151,7 @@
|
|||
d2 = 0.0D;
|
||||
}
|
||||
|
||||
@@ -2586,7 +3076,7 @@
|
||||
@@ -2586,7 +3083,7 @@
|
||||
}
|
||||
|
||||
protected float getFlyingSpeed() {
|
||||
|
@ -1151,7 +1160,7 @@
|
|||
}
|
||||
|
||||
public float getSpeed() {
|
||||
@@ -2604,6 +3094,7 @@
|
||||
@@ -2604,6 +3101,7 @@
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
|
@ -1159,7 +1168,7 @@
|
|||
super.tick();
|
||||
this.updatingUsingItem();
|
||||
this.updateSwimAmount();
|
||||
@@ -2634,7 +3125,7 @@
|
||||
@@ -2634,7 +3132,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1168,7 +1177,7 @@
|
|||
if (this.tickCount % 20 == 0) {
|
||||
this.getCombatTracker().recheckStatus();
|
||||
}
|
||||
@@ -2645,7 +3136,9 @@
|
||||
@@ -2645,7 +3143,9 @@
|
||||
}
|
||||
|
||||
if (!this.isRemoved()) {
|
||||
|
@ -1178,7 +1187,7 @@
|
|||
}
|
||||
|
||||
double d0 = this.getX() - this.xo;
|
||||
@@ -2739,9 +3232,10 @@
|
||||
@@ -2739,9 +3239,10 @@
|
||||
}
|
||||
|
||||
this.elytraAnimationState.tick();
|
||||
|
@ -1190,7 +1199,7 @@
|
|||
Map<EquipmentSlot, ItemStack> map = this.collectEquipmentChanges();
|
||||
|
||||
if (map != null) {
|
||||
@@ -2945,6 +3439,7 @@
|
||||
@@ -2945,6 +3446,7 @@
|
||||
ProfilerFiller gameprofilerfiller = Profiler.get();
|
||||
|
||||
gameprofilerfiller.push("ai");
|
||||
|
@ -1198,7 +1207,7 @@
|
|||
if (this.isImmobile()) {
|
||||
this.jumping = false;
|
||||
this.xxa = 0.0F;
|
||||
@@ -2954,6 +3449,7 @@
|
||||
@@ -2954,6 +3456,7 @@
|
||||
this.serverAiStep();
|
||||
gameprofilerfiller.pop();
|
||||
}
|
||||
|
@ -1206,7 +1215,7 @@
|
|||
|
||||
gameprofilerfiller.pop();
|
||||
gameprofilerfiller.push("jump");
|
||||
@@ -2996,11 +3492,12 @@
|
||||
@@ -2996,11 +3499,12 @@
|
||||
this.resetFallDistance();
|
||||
}
|
||||
|
||||
|
@ -1220,7 +1229,7 @@
|
|||
if (this.isAlive()) {
|
||||
this.travelRidden(entityhuman, vec3d1);
|
||||
break label112;
|
||||
@@ -3009,6 +3506,7 @@
|
||||
@@ -3009,6 +3513,7 @@
|
||||
|
||||
this.travel(vec3d1);
|
||||
}
|
||||
|
@ -1228,7 +1237,7 @@
|
|||
|
||||
if (!this.level().isClientSide() || this.isControlledByLocalInstance()) {
|
||||
this.applyEffectsFromBlocks();
|
||||
@@ -3044,7 +3542,9 @@
|
||||
@@ -3044,7 +3549,9 @@
|
||||
this.checkAutoSpinAttack(axisalignedbb, this.getBoundingBox());
|
||||
}
|
||||
|
||||
|
@ -1238,7 +1247,7 @@
|
|||
gameprofilerfiller.pop();
|
||||
world = this.level();
|
||||
if (world instanceof ServerLevel worldserver) {
|
||||
@@ -3063,6 +3563,7 @@
|
||||
@@ -3063,6 +3570,7 @@
|
||||
this.checkSlowFallDistance();
|
||||
if (!this.level().isClientSide) {
|
||||
if (!this.canGlide()) {
|
||||
|
@ -1246,7 +1255,7 @@
|
|||
this.setSharedFlag(7, false);
|
||||
return;
|
||||
}
|
||||
@@ -3113,7 +3614,7 @@
|
||||
@@ -3113,7 +3621,7 @@
|
||||
Level world = this.level();
|
||||
|
||||
if (!(world instanceof ServerLevel worldserver)) {
|
||||
|
@ -1255,7 +1264,7 @@
|
|||
} else {
|
||||
List list = this.level().getEntities((Entity) this, this.getBoundingBox(), EntitySelector.pushableBy(this));
|
||||
|
||||
@@ -3305,15 +3806,22 @@
|
||||
@@ -3305,15 +3813,22 @@
|
||||
|
||||
@Override
|
||||
public boolean isPickable() {
|
||||
|
@ -1280,7 +1289,7 @@
|
|||
public float getYHeadRot() {
|
||||
return this.yHeadRot;
|
||||
}
|
||||
@@ -3483,8 +3991,31 @@
|
||||
@@ -3483,8 +3998,31 @@
|
||||
this.releaseUsingItem();
|
||||
} else {
|
||||
if (!this.useItem.isEmpty() && this.isUsingItem()) {
|
||||
|
@ -1313,7 +1322,7 @@
|
|||
if (itemstack != this.useItem) {
|
||||
this.setItemInHand(enumhand, itemstack);
|
||||
}
|
||||
@@ -3568,12 +4099,18 @@
|
||||
@@ -3568,12 +4106,18 @@
|
||||
}
|
||||
|
||||
public boolean randomTeleport(double x, double y, double z, boolean particleEffects) {
|
||||
|
@ -1334,7 +1343,7 @@
|
|||
Level world = this.level();
|
||||
|
||||
if (world.hasChunkAt(blockposition)) {
|
||||
@@ -3592,18 +4129,43 @@
|
||||
@@ -3592,18 +4136,43 @@
|
||||
}
|
||||
|
||||
if (flag2) {
|
||||
|
@ -1382,7 +1391,7 @@
|
|||
world.broadcastEntityEvent(this, (byte) 46);
|
||||
}
|
||||
|
||||
@@ -3613,7 +4175,7 @@
|
||||
@@ -3613,7 +4182,7 @@
|
||||
entitycreature.getNavigation().stop();
|
||||
}
|
||||
|
||||
|
@ -1391,7 +1400,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
@@ -3706,7 +4268,7 @@
|
||||
@@ -3706,7 +4275,7 @@
|
||||
}
|
||||
|
||||
public void stopSleeping() {
|
||||
|
@ -1400,7 +1409,7 @@
|
|||
Level world = this.level();
|
||||
|
||||
java.util.Objects.requireNonNull(world);
|
||||
@@ -3718,9 +4280,9 @@
|
||||
@@ -3718,9 +4287,9 @@
|
||||
|
||||
this.level().setBlock(blockposition, (BlockState) iblockdata.setValue(BedBlock.OCCUPIED, false), 3);
|
||||
Vec3 vec3d = (Vec3) BedBlock.findStandUpPosition(this.getType(), this.level(), blockposition, enumdirection, this.getYRot()).orElseGet(() -> {
|
||||
|
@ -1412,7 +1421,7 @@
|
|||
});
|
||||
Vec3 vec3d1 = Vec3.atBottomCenterOf(blockposition).subtract(vec3d).normalize();
|
||||
float f = (float) Mth.wrapDegrees(Mth.atan2(vec3d1.z, vec3d1.x) * 57.2957763671875D - 90.0D);
|
||||
@@ -3740,7 +4302,7 @@
|
||||
@@ -3740,7 +4309,7 @@
|
||||
|
||||
@Nullable
|
||||
public Direction getBedOrientation() {
|
||||
|
@ -1421,7 +1430,7 @@
|
|||
|
||||
return blockposition != null ? BedBlock.getBedOrientation(this.level(), blockposition) : null;
|
||||
}
|
||||
@@ -3905,7 +4467,7 @@
|
||||
@@ -3905,7 +4474,7 @@
|
||||
public float maxUpStep() {
|
||||
float f = (float) this.getAttributeValue(Attributes.STEP_HEIGHT);
|
||||
|
||||
|
|
|
@ -94,7 +94,7 @@
|
|||
|
||||
this.hasImpulse |= this.updateInWaterStateAndDoFluidPushing();
|
||||
if (!this.level().isClientSide) {
|
||||
@@ -201,8 +214,14 @@
|
||||
@@ -201,12 +214,40 @@
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -110,8 +110,34 @@
|
|||
+ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
|
||||
}
|
||||
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ // Spigot start - copied from above
|
||||
+ @Override
|
||||
+ public void inactiveTick() {
|
||||
+ // CraftBukkit start - Use wall time for pickup and despawn timers
|
||||
+ int elapsedTicks = MinecraftServer.currentTick - this.lastTick;
|
||||
+ if (this.pickupDelay != 32767) this.pickupDelay -= elapsedTicks;
|
||||
+ if (this.age != -32768) this.age += elapsedTicks;
|
||||
+ this.lastTick = MinecraftServer.currentTick;
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
+ if (!this.level().isClientSide && this.age >= this.level().spigotConfig.itemDespawnRate) { // Spigot
|
||||
+ // CraftBukkit start - fire ItemDespawnEvent
|
||||
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callItemDespawnEvent(this).isCancelled()) {
|
||||
+ this.age = 0;
|
||||
+ return;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
|
||||
}
|
||||
@@ -229,7 +248,10 @@
|
||||
}
|
||||
+ // Spigot end
|
||||
|
||||
@Override
|
||||
public BlockPos getBlockPosBelowThatAffectsMyMovement() {
|
||||
@@ -229,7 +270,10 @@
|
||||
|
||||
private void mergeWithNeighbours() {
|
||||
if (this.isMergable()) {
|
||||
|
@ -123,7 +149,7 @@
|
|||
return entityitem != this && entityitem.isMergable();
|
||||
});
|
||||
Iterator iterator = list.iterator();
|
||||
@@ -259,7 +281,7 @@
|
||||
@@ -259,7 +303,7 @@
|
||||
ItemStack itemstack1 = other.getItem();
|
||||
|
||||
if (Objects.equals(this.target, other.target) && ItemEntity.areMergable(itemstack, itemstack1)) {
|
||||
|
@ -132,7 +158,7 @@
|
|||
ItemEntity.merge(this, itemstack, other, itemstack1);
|
||||
} else {
|
||||
ItemEntity.merge(other, itemstack1, this, itemstack);
|
||||
@@ -287,11 +309,16 @@
|
||||
@@ -287,11 +331,16 @@
|
||||
}
|
||||
|
||||
private static void merge(ItemEntity targetEntity, ItemStack targetStack, ItemEntity sourceEntity, ItemStack sourceStack) {
|
||||
|
@ -150,7 +176,7 @@
|
|||
}
|
||||
|
||||
}
|
||||
@@ -320,12 +347,17 @@
|
||||
@@ -320,12 +369,17 @@
|
||||
} else if (!this.getItem().canBeHurtBy(source)) {
|
||||
return false;
|
||||
} else {
|
||||
|
@ -169,7 +195,7 @@
|
|||
}
|
||||
|
||||
return true;
|
||||
@@ -382,22 +414,62 @@
|
||||
@@ -382,22 +436,62 @@
|
||||
}
|
||||
|
||||
if (this.getItem().isEmpty()) {
|
||||
|
@ -186,7 +212,7 @@
|
|||
ItemStack itemstack = this.getItem();
|
||||
Item item = itemstack.getItem();
|
||||
int i = itemstack.getCount();
|
||||
+
|
||||
|
||||
+ // CraftBukkit start - fire PlayerPickupItemEvent
|
||||
+ int canHold = player.getInventory().canHold(itemstack);
|
||||
+ int remaining = i - canHold;
|
||||
|
@ -201,7 +227,7 @@
|
|||
+ itemstack.setCount(i); // SPIGOT-5294 - restore count
|
||||
+ return;
|
||||
+ }
|
||||
|
||||
+
|
||||
+ // Call newer event afterwards
|
||||
+ EntityPickupItemEvent entityEvent = new EntityPickupItemEvent((Player) player.getBukkitEntity(), (org.bukkit.entity.Item) this.getBukkitEntity(), remaining);
|
||||
+ entityEvent.setCancelled(!entityEvent.getEntity().getCanPickupItems());
|
||||
|
@ -235,7 +261,7 @@
|
|||
itemstack.setCount(i);
|
||||
}
|
||||
|
||||
@@ -492,7 +564,7 @@
|
||||
@@ -492,7 +586,7 @@
|
||||
|
||||
public void makeFakeItem() {
|
||||
this.setNeverPickUp();
|
||||
|
|
|
@ -24,7 +24,26 @@
|
|||
}
|
||||
|
||||
@Override
|
||||
@@ -235,7 +243,7 @@
|
||||
@@ -216,7 +224,18 @@
|
||||
return this.assignProfessionWhenSpawned;
|
||||
}
|
||||
|
||||
+ // Spigot Start
|
||||
@Override
|
||||
+ public void inactiveTick() {
|
||||
+ // SPIGOT-3874, SPIGOT-3894, SPIGOT-3846, SPIGOT-5286 :(
|
||||
+ if (this.level().spigotConfig.tickInactiveVillagers && this.isEffectiveAi()) {
|
||||
+ this.customServerAiStep((ServerLevel) this.level());
|
||||
+ }
|
||||
+ super.inactiveTick();
|
||||
+ }
|
||||
+ // Spigot End
|
||||
+
|
||||
+ @Override
|
||||
protected void customServerAiStep(ServerLevel world) {
|
||||
ProfilerFiller gameprofilerfiller = Profiler.get();
|
||||
|
||||
@@ -235,7 +254,7 @@
|
||||
this.increaseProfessionLevelOnUpdate = false;
|
||||
}
|
||||
|
||||
|
@ -33,7 +52,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
@@ -360,7 +368,13 @@
|
||||
@@ -360,7 +379,13 @@
|
||||
while (iterator.hasNext()) {
|
||||
MerchantOffer merchantrecipe = (MerchantOffer) iterator.next();
|
||||
|
||||
|
@ -48,7 +67,7 @@
|
|||
}
|
||||
|
||||
this.resendOffersToTradingPlayer();
|
||||
@@ -429,7 +443,13 @@
|
||||
@@ -429,7 +454,13 @@
|
||||
while (iterator.hasNext()) {
|
||||
MerchantOffer merchantrecipe = (MerchantOffer) iterator.next();
|
||||
|
||||
|
@ -63,7 +82,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
@@ -489,7 +509,7 @@
|
||||
@@ -489,7 +520,7 @@
|
||||
@Override
|
||||
public void addAdditionalSaveData(CompoundTag nbt) {
|
||||
super.addAdditionalSaveData(nbt);
|
||||
|
@ -72,7 +91,7 @@
|
|||
Logger logger = Villager.LOGGER;
|
||||
|
||||
Objects.requireNonNull(logger);
|
||||
@@ -512,7 +532,7 @@
|
||||
@@ -512,7 +543,7 @@
|
||||
public void readAdditionalSaveData(CompoundTag nbt) {
|
||||
super.readAdditionalSaveData(nbt);
|
||||
if (nbt.contains("VillagerData", 10)) {
|
||||
|
@ -81,7 +100,7 @@
|
|||
Logger logger = Villager.LOGGER;
|
||||
|
||||
Objects.requireNonNull(logger);
|
||||
@@ -808,7 +828,7 @@
|
||||
@@ -808,7 +839,7 @@
|
||||
entitywitch1.finalizeSpawn(world, world.getCurrentDifficultyAt(entitywitch1.blockPosition()), EntitySpawnReason.CONVERSION, (SpawnGroupData) null);
|
||||
entitywitch1.setPersistenceRequired();
|
||||
this.releaseAllPois();
|
||||
|
@ -90,7 +109,7 @@
|
|||
|
||||
if (entitywitch == null) {
|
||||
super.thunderHit(world, lightning);
|
||||
@@ -906,7 +926,7 @@
|
||||
@@ -906,7 +937,7 @@
|
||||
}).limit(5L).toList();
|
||||
|
||||
if (list1.size() >= requiredCount) {
|
||||
|
@ -99,7 +118,7 @@
|
|||
list.forEach(GolemSensor::golemDetected);
|
||||
}
|
||||
}
|
||||
@@ -963,7 +983,7 @@
|
||||
@@ -963,7 +994,7 @@
|
||||
@Override
|
||||
public void startSleeping(BlockPos pos) {
|
||||
super.startSleeping(pos);
|
||||
|
@ -108,7 +127,7 @@
|
|||
this.brain.eraseMemory(MemoryModuleType.WALK_TARGET);
|
||||
this.brain.eraseMemory(MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE);
|
||||
}
|
||||
@@ -971,7 +991,7 @@
|
||||
@@ -971,7 +1002,7 @@
|
||||
@Override
|
||||
public void stopSleeping() {
|
||||
super.stopSleeping();
|
||||
|
|
|
@ -19,7 +19,26 @@
|
|||
|
||||
public abstract class AbstractArrow extends Projectile {
|
||||
|
||||
@@ -88,23 +93,30 @@
|
||||
@@ -78,6 +83,18 @@
|
||||
@Nullable
|
||||
public ItemStack firedFromWeapon;
|
||||
|
||||
+ // Spigot Start
|
||||
+ @Override
|
||||
+ public void inactiveTick()
|
||||
+ {
|
||||
+ if ( this.isInGround() )
|
||||
+ {
|
||||
+ this.life += 1;
|
||||
+ }
|
||||
+ super.inactiveTick();
|
||||
+ }
|
||||
+ // Spigot End
|
||||
+
|
||||
protected AbstractArrow(EntityType<? extends AbstractArrow> type, Level world) {
|
||||
super(type, world);
|
||||
this.pickup = AbstractArrow.Pickup.DISALLOWED;
|
||||
@@ -88,23 +105,30 @@
|
||||
}
|
||||
|
||||
protected AbstractArrow(EntityType<? extends AbstractArrow> type, double x, double y, double z, Level world, ItemStack stack, @Nullable ItemStack weapon) {
|
||||
|
@ -30,7 +49,7 @@
|
|||
+ // CraftBukkit start - handle the owner before the rest of things
|
||||
+ this(type, x, y, z, world, stack, weapon, null);
|
||||
+ }
|
||||
|
||||
+
|
||||
+ protected AbstractArrow(EntityType<? extends AbstractArrow> entitytypes, double d0, double d1, double d2, Level world, ItemStack itemstack, @Nullable ItemStack itemstack1, @Nullable LivingEntity ownerEntity) {
|
||||
+ this(entitytypes, world);
|
||||
+ this.setOwner(ownerEntity);
|
||||
|
@ -38,7 +57,7 @@
|
|||
+ this.pickupItemStack = itemstack.copy();
|
||||
+ this.setCustomName((Component) itemstack.get(DataComponents.CUSTOM_NAME));
|
||||
+ Unit unit = (Unit) itemstack.remove(DataComponents.INTANGIBLE_PROJECTILE);
|
||||
+
|
||||
|
||||
if (unit != null) {
|
||||
this.pickup = AbstractArrow.Pickup.CREATIVE_ONLY;
|
||||
}
|
||||
|
@ -59,7 +78,7 @@
|
|||
|
||||
if (i > 0) {
|
||||
this.setPierceLevel((byte) i);
|
||||
@@ -114,8 +126,8 @@
|
||||
@@ -114,8 +138,8 @@
|
||||
}
|
||||
|
||||
protected AbstractArrow(EntityType<? extends AbstractArrow> type, LivingEntity owner, Level world, ItemStack stack, @Nullable ItemStack shotFrom) {
|
||||
|
@ -70,7 +89,7 @@
|
|||
}
|
||||
|
||||
public void setSoundEvent(SoundEvent sound) {
|
||||
@@ -282,7 +294,7 @@
|
||||
@@ -282,7 +306,7 @@
|
||||
|
||||
if (movingobjectpositionentity == null) {
|
||||
if (this.isAlive() && blockHitResult.getType() != HitResult.Type.MISS) {
|
||||
|
@ -79,7 +98,7 @@
|
|||
this.hasImpulse = true;
|
||||
}
|
||||
} else {
|
||||
@@ -290,7 +302,7 @@
|
||||
@@ -290,7 +314,7 @@
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -88,7 +107,7 @@
|
|||
|
||||
this.hasImpulse = true;
|
||||
if (this.getPierceLevel() > 0 && projectiledeflection == ProjectileDeflection.NONE) {
|
||||
@@ -357,7 +369,7 @@
|
||||
@@ -357,7 +381,7 @@
|
||||
protected void tickDespawn() {
|
||||
++this.life;
|
||||
if (this.life >= 1200) {
|
||||
|
@ -97,7 +116,7 @@
|
|||
}
|
||||
|
||||
}
|
||||
@@ -423,7 +435,7 @@
|
||||
@@ -423,7 +447,7 @@
|
||||
}
|
||||
|
||||
if (this.piercingIgnoreEntityIds.size() >= this.getPierceLevel() + 1) {
|
||||
|
@ -106,7 +125,7 @@
|
|||
return;
|
||||
}
|
||||
|
||||
@@ -444,7 +456,13 @@
|
||||
@@ -444,7 +468,13 @@
|
||||
int k = entity.getRemainingFireTicks();
|
||||
|
||||
if (this.isOnFire() && !flag) {
|
||||
|
@ -121,7 +140,7 @@
|
|||
}
|
||||
|
||||
if (entity.hurtOrSimulate(damagesource, (float) i)) {
|
||||
@@ -490,7 +508,7 @@
|
||||
@@ -490,7 +520,7 @@
|
||||
|
||||
this.playSound(this.soundEvent, 1.0F, 1.2F / (this.random.nextFloat() * 0.2F + 0.9F));
|
||||
if (this.getPierceLevel() <= 0) {
|
||||
|
@ -130,7 +149,7 @@
|
|||
}
|
||||
} else {
|
||||
entity.setRemainingFireTicks(k);
|
||||
@@ -506,7 +524,7 @@
|
||||
@@ -506,7 +536,7 @@
|
||||
this.spawnAtLocation(worldserver2, this.getPickupItem(), 0.1F);
|
||||
}
|
||||
|
||||
|
@ -139,7 +158,7 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
@@ -675,7 +693,7 @@
|
||||
@@ -675,7 +705,7 @@
|
||||
}
|
||||
|
||||
if (nbt.contains("weapon", 10)) {
|
||||
|
@ -148,7 +167,7 @@
|
|||
} else {
|
||||
this.firedFromWeapon = null;
|
||||
}
|
||||
@@ -688,34 +706,31 @@
|
||||
@@ -688,34 +718,31 @@
|
||||
Entity entity1 = entity;
|
||||
byte b0 = 0;
|
||||
|
||||
|
@ -195,7 +214,7 @@
|
|||
}
|
||||
|
||||
this.pickup = entityarrow_pickupstatus;
|
||||
@@ -724,9 +739,24 @@
|
||||
@@ -724,9 +751,24 @@
|
||||
@Override
|
||||
public void playerTouch(Player player) {
|
||||
if (!this.level().isClientSide && (this.isInGround() || this.isNoPhysics()) && this.shakeTime <= 0) {
|
||||
|
|
|
@ -10,7 +10,37 @@
|
|||
|
||||
public class FireworkRocketEntity extends Projectile implements ItemSupplier {
|
||||
|
||||
@@ -152,7 +155,7 @@
|
||||
@@ -84,7 +87,29 @@
|
||||
this.setOwner(entity);
|
||||
}
|
||||
|
||||
+ // Spigot Start - copied from tick
|
||||
@Override
|
||||
+ public void inactiveTick() {
|
||||
+ this.life += 1;
|
||||
+
|
||||
+ if (this.life > this.lifetime) {
|
||||
+ Level world = this.level();
|
||||
+
|
||||
+ if (world instanceof ServerLevel) {
|
||||
+ ServerLevel worldserver = (ServerLevel) world;
|
||||
+
|
||||
+ // CraftBukkit start
|
||||
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callFireworkExplodeEvent(this).isCancelled()) {
|
||||
+ this.explode(worldserver);
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+ }
|
||||
+ }
|
||||
+ super.inactiveTick();
|
||||
+ }
|
||||
+ // Spigot End
|
||||
+
|
||||
+ @Override
|
||||
protected void defineSynchedData(SynchedEntityData.Builder builder) {
|
||||
builder.define(FireworkRocketEntity.DATA_ID_FIREWORKS_ITEM, FireworkRocketEntity.getDefaultItem());
|
||||
builder.define(FireworkRocketEntity.DATA_ATTACHED_TO_TARGET, OptionalInt.empty());
|
||||
@@ -152,7 +177,7 @@
|
||||
}
|
||||
|
||||
if (!this.noPhysics && this.isAlive() && movingobjectposition.getType() != HitResult.Type.MISS) {
|
||||
|
@ -19,7 +49,7 @@
|
|||
this.hasImpulse = true;
|
||||
}
|
||||
|
||||
@@ -172,7 +175,11 @@
|
||||
@@ -172,7 +197,11 @@
|
||||
if (world instanceof ServerLevel) {
|
||||
ServerLevel worldserver = (ServerLevel) world;
|
||||
|
||||
|
@ -32,7 +62,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
@@ -182,7 +189,7 @@
|
||||
@@ -182,7 +211,7 @@
|
||||
world.broadcastEntityEvent(this, (byte) 17);
|
||||
this.gameEvent(GameEvent.EXPLODE, this.getOwner());
|
||||
this.dealExplosionDamage(world);
|
||||
|
@ -41,7 +71,7 @@
|
|||
}
|
||||
|
||||
@Override
|
||||
@@ -191,7 +198,11 @@
|
||||
@@ -191,7 +220,11 @@
|
||||
Level world = this.level();
|
||||
|
||||
if (world instanceof ServerLevel worldserver) {
|
||||
|
@ -54,7 +84,7 @@
|
|||
}
|
||||
|
||||
}
|
||||
@@ -205,7 +216,11 @@
|
||||
@@ -205,7 +238,11 @@
|
||||
|
||||
if (world instanceof ServerLevel worldserver) {
|
||||
if (this.hasExplosion()) {
|
||||
|
|
|
@ -39,6 +39,9 @@ public class SpigotTimings {
|
|||
|
||||
public static final CustomTimingsHandler playerCommandTimer = new CustomTimingsHandler("** playerCommand");
|
||||
|
||||
public static final CustomTimingsHandler entityActivationCheckTimer = new CustomTimingsHandler("entityActivationCheck");
|
||||
public static final CustomTimingsHandler checkIfActiveTimer = new CustomTimingsHandler("** checkIfActive");
|
||||
|
||||
public static final HashMap<String, CustomTimingsHandler> entityTypeTimingMap = new HashMap<String, CustomTimingsHandler>();
|
||||
public static final HashMap<String, CustomTimingsHandler> tileEntityTypeTimingMap = new HashMap<String, CustomTimingsHandler>();
|
||||
public static final HashMap<String, CustomTimingsHandler> pluginTaskTimingMap = new HashMap<String, CustomTimingsHandler>();
|
||||
|
|
263
paper-server/src/main/java/org/spigotmc/ActivationRange.java
Normal file
263
paper-server/src/main/java/org/spigotmc/ActivationRange.java
Normal file
|
@ -0,0 +1,263 @@
|
|||
package org.spigotmc;
|
||||
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.ExperienceOrb;
|
||||
import net.minecraft.world.entity.LightningBolt;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.entity.PathfinderMob;
|
||||
import net.minecraft.world.entity.ambient.AmbientCreature;
|
||||
import net.minecraft.world.entity.animal.Animal;
|
||||
import net.minecraft.world.entity.animal.Sheep;
|
||||
import net.minecraft.world.entity.boss.EnderDragonPart;
|
||||
import net.minecraft.world.entity.boss.enderdragon.EndCrystal;
|
||||
import net.minecraft.world.entity.boss.enderdragon.EnderDragon;
|
||||
import net.minecraft.world.entity.boss.wither.WitherBoss;
|
||||
import net.minecraft.world.entity.item.ItemEntity;
|
||||
import net.minecraft.world.entity.item.PrimedTnt;
|
||||
import net.minecraft.world.entity.monster.Creeper;
|
||||
import net.minecraft.world.entity.monster.Monster;
|
||||
import net.minecraft.world.entity.monster.Slime;
|
||||
import net.minecraft.world.entity.npc.Villager;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.entity.projectile.AbstractArrow;
|
||||
import net.minecraft.world.entity.projectile.AbstractHurtingProjectile;
|
||||
import net.minecraft.world.entity.projectile.FireworkRocketEntity;
|
||||
import net.minecraft.world.entity.projectile.ThrowableProjectile;
|
||||
import net.minecraft.world.entity.projectile.ThrownTrident;
|
||||
import net.minecraft.world.entity.raid.Raider;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
import org.bukkit.craftbukkit.SpigotTimings;
|
||||
|
||||
public class ActivationRange
|
||||
{
|
||||
|
||||
public enum ActivationType
|
||||
{
|
||||
MONSTER,
|
||||
ANIMAL,
|
||||
RAIDER,
|
||||
MISC;
|
||||
|
||||
AABB boundingBox = new AABB( 0, 0, 0, 0, 0, 0 );
|
||||
}
|
||||
|
||||
static AABB maxBB = new AABB( 0, 0, 0, 0, 0, 0 );
|
||||
|
||||
/**
|
||||
* Initializes an entities type on construction to specify what group this
|
||||
* entity is in for activation ranges.
|
||||
*
|
||||
* @param entity
|
||||
* @return group id
|
||||
*/
|
||||
public static ActivationType initializeEntityActivationType(Entity entity)
|
||||
{
|
||||
if ( entity instanceof Raider )
|
||||
{
|
||||
return ActivationType.RAIDER;
|
||||
} else if ( entity instanceof Monster || entity instanceof Slime )
|
||||
{
|
||||
return ActivationType.MONSTER;
|
||||
} else if ( entity instanceof PathfinderMob || entity instanceof AmbientCreature )
|
||||
{
|
||||
return ActivationType.ANIMAL;
|
||||
} else
|
||||
{
|
||||
return ActivationType.MISC;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* These entities are excluded from Activation range checks.
|
||||
*
|
||||
* @param entity
|
||||
* @param config
|
||||
* @return boolean If it should always tick.
|
||||
*/
|
||||
public static boolean initializeEntityActivationState(Entity entity, SpigotWorldConfig config)
|
||||
{
|
||||
if ( ( entity.activationType == ActivationType.MISC && config.miscActivationRange == 0 )
|
||||
|| ( entity.activationType == ActivationType.RAIDER && config.raiderActivationRange == 0 )
|
||||
|| ( entity.activationType == ActivationType.ANIMAL && config.animalActivationRange == 0 )
|
||||
|| ( entity.activationType == ActivationType.MONSTER && config.monsterActivationRange == 0 )
|
||||
|| entity instanceof Player
|
||||
|| entity instanceof ThrowableProjectile
|
||||
|| entity instanceof EnderDragon
|
||||
|| entity instanceof EnderDragonPart
|
||||
|| entity instanceof WitherBoss
|
||||
|| entity instanceof AbstractHurtingProjectile
|
||||
|| entity instanceof LightningBolt
|
||||
|| entity instanceof PrimedTnt
|
||||
|| entity instanceof EndCrystal
|
||||
|| entity instanceof FireworkRocketEntity
|
||||
|| entity instanceof ThrownTrident )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find what entities are in range of the players in the world and set
|
||||
* active if in range.
|
||||
*
|
||||
* @param world
|
||||
*/
|
||||
public static void activateEntities(Level world)
|
||||
{
|
||||
SpigotTimings.entityActivationCheckTimer.startTiming();
|
||||
final int miscActivationRange = world.spigotConfig.miscActivationRange;
|
||||
final int raiderActivationRange = world.spigotConfig.raiderActivationRange;
|
||||
final int animalActivationRange = world.spigotConfig.animalActivationRange;
|
||||
final int monsterActivationRange = world.spigotConfig.monsterActivationRange;
|
||||
|
||||
int maxRange = Math.max( monsterActivationRange, animalActivationRange );
|
||||
maxRange = Math.max( maxRange, raiderActivationRange );
|
||||
maxRange = Math.max( maxRange, miscActivationRange );
|
||||
maxRange = Math.min( ( world.spigotConfig.simulationDistance << 4 ) - 8, maxRange );
|
||||
|
||||
for ( Player player : world.players() )
|
||||
{
|
||||
player.activatedTick = MinecraftServer.currentTick;
|
||||
if ( world.spigotConfig.ignoreSpectatorActivation && player.isSpectator() )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ActivationRange.maxBB = player.getBoundingBox().inflate( maxRange, 256, maxRange );
|
||||
ActivationType.MISC.boundingBox = player.getBoundingBox().inflate( miscActivationRange, 256, miscActivationRange );
|
||||
ActivationType.RAIDER.boundingBox = player.getBoundingBox().inflate( raiderActivationRange, 256, raiderActivationRange );
|
||||
ActivationType.ANIMAL.boundingBox = player.getBoundingBox().inflate( animalActivationRange, 256, animalActivationRange );
|
||||
ActivationType.MONSTER.boundingBox = player.getBoundingBox().inflate( monsterActivationRange, 256, monsterActivationRange );
|
||||
|
||||
world.getEntities().get(ActivationRange.maxBB, ActivationRange::activateEntity);
|
||||
}
|
||||
SpigotTimings.entityActivationCheckTimer.stopTiming();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks for the activation state of all entities in this chunk.
|
||||
*
|
||||
* @param chunk
|
||||
*/
|
||||
private static void activateEntity(Entity entity)
|
||||
{
|
||||
if ( MinecraftServer.currentTick > entity.activatedTick )
|
||||
{
|
||||
if ( entity.defaultActivationState )
|
||||
{
|
||||
entity.activatedTick = MinecraftServer.currentTick;
|
||||
return;
|
||||
}
|
||||
if ( entity.activationType.boundingBox.intersects( entity.getBoundingBox() ) )
|
||||
{
|
||||
entity.activatedTick = MinecraftServer.currentTick;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If an entity is not in range, do some more checks to see if we should
|
||||
* give it a shot.
|
||||
*
|
||||
* @param entity
|
||||
* @return
|
||||
*/
|
||||
public static boolean checkEntityImmunities(Entity entity)
|
||||
{
|
||||
// quick checks.
|
||||
if ( entity.wasTouchingWater || entity.getRemainingFireTicks() > 0 )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if ( !( entity instanceof AbstractArrow ) )
|
||||
{
|
||||
if ( !entity.onGround() || !entity.passengers.isEmpty() || entity.isPassenger() )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
} else if ( !( (AbstractArrow) entity ).isInGround() )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
// special cases.
|
||||
if ( entity instanceof LivingEntity )
|
||||
{
|
||||
LivingEntity living = (LivingEntity) entity;
|
||||
if ( /*TODO: Missed mapping? living.attackTicks > 0 || */ living.hurtTime > 0 || living.activeEffects.size() > 0 )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if ( entity instanceof PathfinderMob && ( (PathfinderMob) entity ).getTarget() != null )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if ( entity instanceof Villager && ( (Villager) entity ).canBreed() )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if ( entity instanceof Animal )
|
||||
{
|
||||
Animal animal = (Animal) entity;
|
||||
if ( animal.isBaby() || animal.isInLove() )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if ( entity instanceof Sheep && ( (Sheep) entity ).isSheared() )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (entity instanceof Creeper && ((Creeper) entity).isIgnited()) { // isExplosive
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// SPIGOT-6644: Otherwise the target refresh tick will be missed
|
||||
if (entity instanceof ExperienceOrb) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the entity is active for this tick.
|
||||
*
|
||||
* @param entity
|
||||
* @return
|
||||
*/
|
||||
public static boolean checkIfActive(Entity entity)
|
||||
{
|
||||
SpigotTimings.checkIfActiveTimer.startTiming();
|
||||
// Never safe to skip fireworks or item gravity
|
||||
if (entity instanceof FireworkRocketEntity || (entity instanceof ItemEntity && (entity.tickCount + entity.getId() + 1) % 4 == 0)) {
|
||||
SpigotTimings.checkIfActiveTimer.stopTiming();
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean isActive = entity.activatedTick >= MinecraftServer.currentTick || entity.defaultActivationState;
|
||||
|
||||
// Should this entity tick?
|
||||
if ( !isActive )
|
||||
{
|
||||
if ( ( MinecraftServer.currentTick - entity.activatedTick - 1 ) % 20 == 0 )
|
||||
{
|
||||
// Check immunities every 20 ticks.
|
||||
if ( ActivationRange.checkEntityImmunities( entity ) )
|
||||
{
|
||||
// Triggered some sort of immunity, give 20 full ticks before we check again.
|
||||
entity.activatedTick = MinecraftServer.currentTick + 20;
|
||||
}
|
||||
isActive = true;
|
||||
}
|
||||
// Add a little performance juice to active entities. Skip 1/4 if not immune.
|
||||
} else if ( !entity.defaultActivationState && entity.tickCount % 4 == 0 && !ActivationRange.checkEntityImmunities( entity ) )
|
||||
{
|
||||
isActive = false;
|
||||
}
|
||||
SpigotTimings.checkIfActiveTimer.stopTiming();
|
||||
return isActive;
|
||||
}
|
||||
}
|
|
@ -194,4 +194,21 @@ public class SpigotWorldConfig
|
|||
this.itemDespawnRate = this.getInt( "item-despawn-rate", 6000 );
|
||||
this.log( "Item Despawn Rate: " + this.itemDespawnRate );
|
||||
}
|
||||
|
||||
public int animalActivationRange = 32;
|
||||
public int monsterActivationRange = 32;
|
||||
public int raiderActivationRange = 48;
|
||||
public int miscActivationRange = 16;
|
||||
public boolean tickInactiveVillagers = true;
|
||||
public boolean ignoreSpectatorActivation = false;
|
||||
private void activationRange()
|
||||
{
|
||||
this.animalActivationRange = this.getInt( "entity-activation-range.animals", this.animalActivationRange );
|
||||
this.monsterActivationRange = this.getInt( "entity-activation-range.monsters", this.monsterActivationRange );
|
||||
this.raiderActivationRange = this.getInt( "entity-activation-range.raiders", this.raiderActivationRange );
|
||||
this.miscActivationRange = this.getInt( "entity-activation-range.misc", this.miscActivationRange );
|
||||
this.tickInactiveVillagers = this.getBoolean( "entity-activation-range.tick-inactive-villagers", this.tickInactiveVillagers );
|
||||
this.ignoreSpectatorActivation = this.getBoolean( "entity-activation-range.ignore-spectators", this.ignoreSpectatorActivation );
|
||||
this.log( "Entity Activation Range: An " + this.animalActivationRange + " / Mo " + this.monsterActivationRange + " / Ra " + this.raiderActivationRange + " / Mi " + this.miscActivationRange + " / Tiv " + this.tickInactiveVillagers + " / Isa " + this.ignoreSpectatorActivation );
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue