All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cn.nukkit.entity.projectile.SlenderProjectile Maven / Gradle / Ivy

There is a newer version: 1.20.40-r1
Show newest version
package cn.nukkit.entity.projectile;

import cn.nukkit.entity.Entity;
import cn.nukkit.level.format.FullChunk;
import cn.nukkit.math.Vector3;
import cn.nukkit.nbt.tag.CompoundTag;
import co.aikar.timings.Timings;

/**
 * 这个抽象类代表较为细长的投射物实体(例如弓箭,三叉戟),它通过重写{@link Entity#move}方法实现这些实体较为准确的碰撞箱计算。
 * 

* This abstract class represents slender projectile entities (e.g.arrow, trident), and it realized a more accurate collision box calculation for these entities by overriding the {@link Entity#move} method. */ public abstract class SlenderProjectile extends EntityProjectile { public SlenderProjectile(FullChunk chunk, CompoundTag nbt) { super(chunk, nbt); } public SlenderProjectile(FullChunk chunk, CompoundTag nbt, Entity shootingEntity) { super(chunk, nbt, shootingEntity); } //对于SlenderProjectile你不应该把Width设置太大,如果没必要请使用默认值. @Override public float getWidth() { return 0.1f; } //对于SlenderProjectile你不应该把Height设置太大,如果没必要请使用默认值. @Override public float getHeight() { return 0.1f; } /* * 经过测试这个算法在大多数情况下效果不错。 */ @Override public boolean move(double dx, double dy, double dz) { if (dx == 0 && dz == 0 && dy == 0) { return true; } Timings.entityMoveTimer.startTiming(); this.ySize *= 0.4; double movX = dx; double movY = dy; double movZ = dz; var currentAABB = this.boundingBox.clone(); var dirVector = new Vector3(dx, dy, dz).multiply(1 / (double) 15); boolean isCollision = false; for (int i = 0; i < 15; ++i) { var collisionResult = this.level.fastCollisionCubes(this, currentAABB.offset(dirVector.x, dirVector.y, dirVector.z), false); if (!collisionResult.isEmpty()) { //debug // System.out.println("碰撞结果"); // System.out.println(collisionResult); isCollision = true; break; } } // System.out.println(dx); // System.out.println(dy); // System.out.println(dz); // System.out.println("---"); if (isCollision) { if (dy > 0) { double y1 = currentAABB.getMinY() - this.boundingBox.getMaxY(); if (y1 < dy) { dy = y1; } } if (dy < 0) { double y2 = currentAABB.getMaxY() - this.boundingBox.getMinY(); if (y2 > dy) { dy = y2; } } if (dx > 0) { double x1 = currentAABB.getMinX() - this.boundingBox.getMaxX(); if (x1 < dx) { dx = x1; } } if (dx < 0) { double x2 = currentAABB.getMaxX() - this.boundingBox.getMinX(); if (x2 > dx) { dx = x2; } } if (dz > 0) { double z1 = currentAABB.getMinZ() - this.boundingBox.getMaxZ(); if (z1 < dz) { dz = z1; } } if (dz < 0) { double z2 = currentAABB.getMaxZ() - this.boundingBox.getMinZ(); if (z2 > dz) { dz = z2; } } } // System.out.println(dx); // System.out.println(dy); // System.out.println(dz); // System.out.println("---"); this.boundingBox.offset(0, dy, 0); this.boundingBox.offset(dx, 0, 0); this.boundingBox.offset(0, 0, dz); this.x = (this.boundingBox.getMinX() + this.boundingBox.getMaxX()) / 2; this.y = this.boundingBox.getMinY() - this.ySize; this.z = (this.boundingBox.getMinZ() + this.boundingBox.getMaxZ()) / 2; this.checkChunks(); this.checkGroundState(movX, movY, movZ, dx, dy, dz); this.updateFallState(this.onGround); if (movX != dx) { this.motionX = 0; } if (movY != dy) { this.motionY = 0; } if (movZ != dz) { this.motionZ = 0; } //TODO: vehicle collision events (first we need to spawn them!) Timings.entityMoveTimer.stopTiming(); return true; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy