Skip to content

Commit

Permalink
弹射物优化
Browse files Browse the repository at this point in the history
  • Loading branch information
wode490390 committed Jul 30, 2023
1 parent c95ff0e commit 6c60f47
Show file tree
Hide file tree
Showing 19 changed files with 213 additions and 66 deletions.
6 changes: 6 additions & 0 deletions src/main/java/cn/nukkit/Player.java
Original file line number Diff line number Diff line change
Expand Up @@ -6164,4 +6164,10 @@ public void playEmote(String emoteId, long entityRuntimeId, int flags) {
*/
protected void sendDeathInfo(TextContainer message) {
}

/**
* @since 1.16.100
*/
public void sendMotionPredictionHints(long entityRuntimeId, Vector3f motion, boolean onGround) {
}
}
16 changes: 15 additions & 1 deletion src/main/java/cn/nukkit/entity/Entity.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import cn.nukkit.block.Block;
import cn.nukkit.block.BlockDripstonePointed;
import cn.nukkit.block.BlockID;
import cn.nukkit.block.BlockLiquid;
import cn.nukkit.block.BlockWater;
import cn.nukkit.blockentity.BlockEntityPistonArm;
import cn.nukkit.entity.data.*;
Expand Down Expand Up @@ -1804,7 +1805,7 @@ public boolean isInsideOfWater(boolean eyeHeight) {
public boolean isInsideOfWater(float heightOffset) {
double y = this.y + heightOffset;
Block block = this.level.getBlock(Mth.floor(this.x), Mth.floor(y), Mth.floor(this.z));
if (!block.isWater()) {
if (!block.isWater() && !block.isAir() && block.canContainWater()) {
block = level.getExtraBlock(block);
}

Expand All @@ -1816,6 +1817,19 @@ public boolean isInsideOfWater(float heightOffset) {
return false;
}

public boolean isInsideOfLiquid() {
Block block = this.level.getBlock(this);
if (!block.isLiquid() && !block.isAir() && block.canContainWater()) {
block = level.getExtraBlock(block);
}

if (!block.isLiquid()) {
return false;
}

return this.y < block.y + 1 - (((BlockLiquid) block).getFluidHeightPercent() - 0.1111111);
}

public boolean isInsideOfSolid() {
double y = this.y + this.getEyeHeight();
Block block = this.level.getBlock(Mth.floor(this.x), Mth.floor(y), Mth.floor(this.z));
Expand Down
10 changes: 6 additions & 4 deletions src/main/java/cn/nukkit/entity/item/EntityFishingHook.java
Original file line number Diff line number Diff line change
Expand Up @@ -264,8 +264,7 @@ public boolean onUpdate(int currentTick) {
}
}

if (nearEntity != null) {
onCollideWithEntity(nearEntity);
if (nearEntity != null && onCollideWithEntity(nearEntity)) {
return true;
}
}
Expand Down Expand Up @@ -468,10 +467,12 @@ public void spawnTo(Player player) {
}

@Override
public void onCollideWithEntity(Entity entity) {
public boolean onCollideWithEntity(Entity entity) {
EntityFishingRodCollideEntityEvent collideEntityEvent = new EntityFishingRodCollideEntityEvent(this, entity);
this.server.getPluginManager().callEvent(collideEntityEvent);
if (collideEntityEvent.isCancelled()) return;
if (collideEntityEvent.isCancelled()) {
return true;
}

this.server.getPluginManager().callEvent(new ProjectileHitEvent(this, MovingObjectPosition.fromEntity(entity)));
float damage = this.getResultDamage();
Expand All @@ -496,6 +497,7 @@ public void onCollideWithEntity(Entity entity) {
} else {
close();
}
return true;
}

public void checkLure() {
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/cn/nukkit/entity/item/EntityPotion.java
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,9 @@ protected float getDrag() {
}

@Override
public void onCollideWithEntity(Entity entity) {
public boolean onCollideWithEntity(Entity entity) {
this.splash(entity);
return true;
}

private void splash(Entity collidedWith) {
Expand Down
19 changes: 15 additions & 4 deletions src/main/java/cn/nukkit/entity/projectile/EntityArrow.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package cn.nukkit.entity.projectile;

import cn.nukkit.Player;
import cn.nukkit.Server;
import cn.nukkit.entity.Entity;
import cn.nukkit.entity.EntityID;
import cn.nukkit.entity.EntitySmite;
Expand All @@ -9,9 +10,11 @@
import cn.nukkit.event.entity.EntityDamageEvent.DamageCause;
import cn.nukkit.event.entity.EntityRegainHealthEvent;
import cn.nukkit.item.Item;
import cn.nukkit.level.MovingObjectPosition;
import cn.nukkit.level.format.FullChunk;
import cn.nukkit.nbt.tag.CompoundTag;
import cn.nukkit.nbt.tag.ListTag;
import cn.nukkit.network.protocol.EntityEventPacket;
import cn.nukkit.network.protocol.LevelSoundEventPacket;
import cn.nukkit.potion.Effect;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
Expand All @@ -30,6 +33,7 @@ public class EntityArrow extends EntityProjectile {
private int auxValue;

protected int pickupMode;

protected boolean playedHitSound = false;

@Override
Expand Down Expand Up @@ -138,10 +142,6 @@ public boolean onUpdate(int currentTick) {
if (this.onGround || this.hadCollision) {
this.setCritical(false);
if (!this.playedHitSound) {
/*EntityEventPacket pk = new EntityEventPacket();
pk.eid = this.getId();
pk.event = EntityEventPacket.ARROW_SHAKE;
Server.broadcastPacket(this.getViewers().values(), pk);*/
this.getLevel().addLevelSoundEvent(this, LevelSoundEventPacket.SOUND_BOW_HIT);
this.playedHitSound = true;
}
Expand All @@ -157,6 +157,17 @@ public boolean onUpdate(int currentTick) {
return hasUpdate;
}

@Override
protected void onHitBlock(MovingObjectPosition blockHitResult) {
super.onHitBlock(blockHitResult);

EntityEventPacket pk = new EntityEventPacket();
pk.eid = this.getId();
pk.event = EntityEventPacket.ARROW_SHAKE;
pk.data = 7;
Server.broadcastPacket(this.getViewers().values(), pk);
}

@Override
public void spawnTo(Player player) {
if (this.hasSpawned.containsKey(player.getLoaderId())) {
Expand Down
12 changes: 12 additions & 0 deletions src/main/java/cn/nukkit/entity/projectile/EntityEgg.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
import cn.nukkit.Player;
import cn.nukkit.entity.Entity;
import cn.nukkit.entity.EntityID;
import cn.nukkit.item.Item;
import cn.nukkit.level.MovingObjectPosition;
import cn.nukkit.level.format.FullChunk;
import cn.nukkit.level.particle.ItemBreakParticle;
import cn.nukkit.nbt.tag.CompoundTag;

/**
Expand Down Expand Up @@ -77,4 +80,13 @@ public void spawnTo(Player player) {

super.spawnTo(player);
}

@Override
protected void onHit(MovingObjectPosition hitResult) {
super.onHit(hitResult);

for (int i = 0; i < 6; i++) {
level.addParticle(new ItemBreakParticle(this, Item.EGG));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,11 @@ public boolean onUpdate(int currentTick) {
}

@Override
public void onCollideWithEntity(Entity entity) {
public boolean onCollideWithEntity(Entity entity) {
if (this.shootingEntity instanceof Player) {
teleport();
}
super.onCollideWithEntity(entity);
return super.onCollideWithEntity(entity);
}

private void teleport() {
Expand Down
97 changes: 60 additions & 37 deletions src/main/java/cn/nukkit/entity/projectile/EntityProjectile.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
import cn.nukkit.entity.Entity;
import cn.nukkit.entity.EntityLiving;
import cn.nukkit.entity.data.LongEntityData;
import cn.nukkit.entity.item.EntityBoat;
import cn.nukkit.entity.item.EntityEndCrystal;
import cn.nukkit.entity.item.EntityMinecartAbstract;
import cn.nukkit.entity.item.EntityPainting;
import cn.nukkit.entity.item.EntityVehicle;
import cn.nukkit.event.entity.*;
import cn.nukkit.event.entity.EntityDamageEvent.DamageCause;
import cn.nukkit.level.MovingObjectPosition;
Expand Down Expand Up @@ -57,8 +57,9 @@ protected double getBaseDamage() {
protected BlockVector3 stuckToBlockPos;

protected int entityHitCount;
protected int piercedCount;
@Nullable
protected LongSet piercingIgnoreEntityIds;
protected LongSet ignoreEntityIds;

public EntityProjectile(FullChunk chunk, CompoundTag nbt) {
this(chunk, nbt, null);
Expand All @@ -76,26 +77,30 @@ public int getResultDamage() {
return Mth.ceil(Math.sqrt(this.motionX * this.motionX + this.motionY * this.motionY + this.motionZ * this.motionZ) * getDamage());
}

@Override
public boolean attack(EntityDamageEvent source) {
return source.getCause() == DamageCause.VOID && super.attack(source);
}

public void onCollideWithEntity(Entity entity) {
public boolean onCollideWithEntity(Entity entity) {
if (ignoreEntityIds == null) {
ignoreEntityIds = new LongOpenHashSet(5);
}
ignoreEntityIds.add(entity.getId());

int entityHitCount = this.entityHitCount;
boolean piercing = entityHitCount > 1;
if (piercing) {
if (piercingIgnoreEntityIds == null) {
piercingIgnoreEntityIds = new LongOpenHashSet(5);
}
if (piercingIgnoreEntityIds.size() < entityHitCount) {
piercingIgnoreEntityIds.add(entity.getId());
if (piercedCount < entityHitCount) {
piercedCount++;
} else {
close();
return;
return true;
}
}

this.server.getPluginManager().callEvent(new ProjectileHitEvent(this, MovingObjectPosition.fromEntity(entity)));
MovingObjectPosition entityHitResult = MovingObjectPosition.fromEntity(entity);
this.server.getPluginManager().callEvent(new ProjectileHitEvent(this, entityHitResult));
float damage = this.getResultDamage();
if (piercing && entity.isBlocking()) {
damage *= (entityHitCount - 1) / 4f;
Expand Down Expand Up @@ -123,8 +128,8 @@ public void onCollideWithEntity(Entity entity) {
}
}

if (piercing && piercingIgnoreEntityIds.size() < entityHitCount) {
return;
if (piercing && piercedCount < entityHitCount) {
return false;
}
} else if (shouldBounce()) {
motionX *= -0.1;
Expand All @@ -133,17 +138,27 @@ public void onCollideWithEntity(Entity entity) {
yaw = (yaw + 180) % 360;

hadCollision = false;
return;
return false;
}

onHit(entityHitResult);
if (closeOnCollide) {
this.close();
}
return true;
}

protected void postHurt(Entity entity) {
}

protected void onHitBlock(MovingObjectPosition blockHitResult) {
this.server.getPluginManager().callEvent(new ProjectileHitEvent(this, blockHitResult));
onHit(blockHitResult);
}

protected void onHit(MovingObjectPosition hitResult) {
}

@Override
protected void initEntity() {
super.initEntity();
Expand Down Expand Up @@ -181,15 +196,22 @@ protected void initEntity() {

@Override
public boolean canCollideWith(Entity entity) {
if (this.onGround) return false;
if (piercingIgnoreEntityIds != null && piercingIgnoreEntityIds.contains(entity.getId())) {
if (this.onGround) {
return false;
}

if (ignoreEntityIds != null && ignoreEntityIds.contains(entity.getId())) {
return false;
}
if (entity instanceof EntityLiving) {
if (entity instanceof Player) {
return !((Player) entity).isSpectator() && !entity.getDataFlag(DATA_FLAG_INVISIBLE);
} else return true;
} else return entity instanceof EntityEndCrystal || entity instanceof EntityMinecartAbstract || entity instanceof EntityBoat;

if (entity instanceof Player) {
return !((Player) entity).isSpectator() && !entity.getDataFlag(DATA_FLAG_INVISIBLE);
}

return entity instanceof EntityLiving
|| entity instanceof EntityPainting
|| entity instanceof EntityEndCrystal
|| entity instanceof EntityVehicle;
}

@Override
Expand Down Expand Up @@ -226,12 +248,15 @@ public boolean onUpdate(int currentTick) {
boolean hasUpdate = this.entityBaseTick(tickDiff);

if (this.isAlive()) {
MovingObjectPosition movingObjectPosition = null;

if (!this.isCollided) {
this.motionY -= this.getGravity();
this.motionX *= 1 - this.getDrag();
this.motionZ *= 1 - this.getDrag();
boolean liquid = isInsideOfLiquid();
float inertia = liquid ? getLiquidInertia() : 1 - getDrag();
this.motionX *= inertia;
this.motionZ *= inertia;
if (liquid) {
this.motionY *= inertia;
}
}

Vector3 moveVector = new Vector3(this.x + this.motionX, this.y + this.motionY, this.z + this.motionZ);
Expand Down Expand Up @@ -300,15 +325,8 @@ public boolean onUpdate(int currentTick) {
}
}

if (nearEntity != null) {
movingObjectPosition = MovingObjectPosition.fromEntity(nearEntity);
}

if (movingObjectPosition != null) {
if (movingObjectPosition.entityHit != null) {
onCollideWithEntity(movingObjectPosition.entityHit);
return true;
}
if (nearEntity != null && onCollideWithEntity(nearEntity)) {
return true;
}

this.move(this.motionX, this.motionY, this.motionZ);
Expand All @@ -322,12 +340,13 @@ public boolean onUpdate(int currentTick) {

this.addMovement(this.x, this.y + this.getBaseOffset(), this.z, this.yaw, this.pitch, this.yaw);

if (this.piercingIgnoreEntityIds != null) {
this.piercingIgnoreEntityIds.clear();
piercedCount = 0;
if (this.ignoreEntityIds != null) {
this.ignoreEntityIds.clear();
}

if (blockHitResult != null) {
this.server.getPluginManager().callEvent(new ProjectileHitEvent(this, blockHitResult));
onHitBlock(blockHitResult);
}
return false;
} else if (!this.isCollided && this.hadCollision) {
Expand Down Expand Up @@ -406,6 +425,10 @@ protected boolean shouldBounce() {
return false;
}

protected float getLiquidInertia() {
return 0.6f;
}

public int getEntityHitCount() {
return entityHitCount;
}
Expand Down
Loading

0 comments on commit 6c60f47

Please sign in to comment.