Signed-off-by: yoyosource <yoyosource@nidido.de>
Dieser Commit ist enthalten in:
Ursprung
fb3db5d4dd
Commit
8f54fa1ef0
@ -103,7 +103,7 @@ public class AxisMovementLimiter {
|
|||||||
|
|
||||||
Double collision = null;
|
Double collision = null;
|
||||||
for (Vector vector : vectors) {
|
for (Vector vector : vectors) {
|
||||||
VoxelShape voxelShape = Simulator19.getVoxelShape(vector.getBlockX(), vector.getBlockY(), vector.getBlockZ());
|
VoxelShape voxelShape = Simulator19.getVoxelShape(vector);
|
||||||
for (BoundingBox boundingBox : voxelShape.getBoundingBoxes()) {
|
for (BoundingBox boundingBox : voxelShape.getBoundingBoxes()) {
|
||||||
boundingBox = boundingBox.clone().shift(vector);
|
boundingBox = boundingBox.clone().shift(vector);
|
||||||
boolean collides = boundingBox.overlaps(movementBoundingBox);
|
boolean collides = boundingBox.overlaps(movementBoundingBox);
|
||||||
|
@ -19,17 +19,36 @@
|
|||||||
|
|
||||||
package de.steamwar.bausystem.features.simulator;
|
package de.steamwar.bausystem.features.simulator;
|
||||||
|
|
||||||
|
import org.bukkit.Material;
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
import org.bukkit.block.data.Waterlogged;
|
import org.bukkit.block.data.Waterlogged;
|
||||||
import org.bukkit.util.Vector;
|
import org.bukkit.util.Vector;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.*;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Random;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
public class Explosion {
|
public class Explosion {
|
||||||
|
|
||||||
|
private static final double[] FACE_BLOCKS = new double[(16 * 16 * 2 + 14 * 16 * 2 + 14 * 14 * 2) * 3];
|
||||||
|
|
||||||
|
static {
|
||||||
|
int index = 0;
|
||||||
|
for (int x = 0; x < 16; ++x) {
|
||||||
|
for (int y = 0; y < 16; ++y) {
|
||||||
|
for (int z = 0; z < 16; ++z) {
|
||||||
|
if (x == 0 || x == 15 || y == 0 || y == 15 || z == 0 || z == 15) {
|
||||||
|
double dX = x / 15.0F * 2.0F - 1.0F;
|
||||||
|
double dY = y / 15.0F * 2.0F - 1.0F;
|
||||||
|
double dZ = z / 15.0F * 2.0F - 1.0F;
|
||||||
|
double length = Math.sqrt(dX * dX + dY * dY + dZ * dZ);
|
||||||
|
FACE_BLOCKS[index++] = dX / length;
|
||||||
|
FACE_BLOCKS[index++] = dY / length;
|
||||||
|
FACE_BLOCKS[index++] = dZ / length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static final Random RANDOM = new Random();
|
private static final Random RANDOM = new Random();
|
||||||
private static final float POWER = 4.0F;
|
private static final float POWER = 4.0F;
|
||||||
|
|
||||||
@ -50,53 +69,141 @@ public class Explosion {
|
|||||||
|
|
||||||
public void calculate() {
|
public void calculate() {
|
||||||
Set<Vector> affectedBlocks = new HashSet<>();
|
Set<Vector> affectedBlocks = new HashSet<>();
|
||||||
for (int i = 0; i < 16; ++i) {
|
for (int i = 0; i < FACE_BLOCKS.length; i += 3) {
|
||||||
for (int j = 0; j < 16; ++j) {
|
double d = FACE_BLOCKS[i + 0];
|
||||||
for (int k = 0; k < 16; ++k) {
|
double e = FACE_BLOCKS[i + 1];
|
||||||
if (i == 0 || i == 15 || j == 0 || j == 15 || k == 0 || k == 15) {
|
double f = FACE_BLOCKS[i + 2];
|
||||||
double d = i / 15.0F * 2.0F - 1.0F;
|
|
||||||
double e = j / 15.0F * 2.0F - 1.0F;
|
|
||||||
double f = k / 15.0F * 2.0F - 1.0F;
|
|
||||||
double g = Math.sqrt(d * d + e * e + f * f);
|
|
||||||
d /= g;
|
|
||||||
e /= g;
|
|
||||||
f /= g;
|
|
||||||
|
|
||||||
float h = POWER * (0.7F + RANDOM.nextFloat() * 0.6F);
|
float h = POWER * (0.7F + RANDOM.nextFloat() * 0.6F);
|
||||||
double m = x;
|
double m = x;
|
||||||
double n = y;
|
double n = y;
|
||||||
double o = z;
|
double o = z;
|
||||||
|
|
||||||
for (; h > 0.0F; h -= 0.22500001F) {
|
for (; h > 0.0F; h -= 0.22500001F) {
|
||||||
int x = TNT.floor(m);
|
int x = TNT.floor(m);
|
||||||
int y = TNT.floor(n);
|
int y = TNT.floor(n);
|
||||||
int z = TNT.floor(o);
|
int z = TNT.floor(o);
|
||||||
|
|
||||||
BlockData blockData = Simulator19.getBlockData(x, y, z);
|
BlockData blockData = Simulator19.getBlockData(x, y, z);
|
||||||
if (blockData != null) {
|
if (blockData != null) {
|
||||||
h -= (blockData.getMaterial().getBlastResistance() + 0.3F) * 0.3F;
|
h -= (blockData.getMaterial().getBlastResistance() + 0.3F) * 0.3F;
|
||||||
}
|
}
|
||||||
if (blockData instanceof Waterlogged) {
|
if (blockData instanceof Waterlogged) {
|
||||||
Waterlogged waterlogged = (Waterlogged) blockData;
|
Waterlogged waterlogged = (Waterlogged) blockData;
|
||||||
if (waterlogged.isWaterlogged()) {
|
if (waterlogged.isWaterlogged()) {
|
||||||
h = 0.0F;
|
h = 0.0F;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (h > 0.0F) {
|
|
||||||
affectedBlocks.add(new Vector(x, y, z));
|
|
||||||
}
|
|
||||||
|
|
||||||
m += d * 0.30000001192092896;
|
|
||||||
n += e * 0.30000001192092896;
|
|
||||||
o += f * 0.30000001192092896;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (h > 0.0F) {
|
||||||
|
affectedBlocks.add(new Vector(x, y, z));
|
||||||
|
}
|
||||||
|
|
||||||
|
m += d * 0.30000001192092896;
|
||||||
|
n += e * 0.30000001192092896;
|
||||||
|
o += f * 0.30000001192092896;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
affectedBlocks.forEach(Simulator19::clearBlock);
|
||||||
|
|
||||||
|
float q = POWER * 2.0F;
|
||||||
|
int k = floor(x - q - 1.0D);
|
||||||
|
int l = floor(x + q + 1.0D);
|
||||||
|
int r = floor(y - q - 1.0D);
|
||||||
|
int s = floor(y + q + 1.0D);
|
||||||
|
int t = floor(z - q - 1.0D);
|
||||||
|
int u = floor(z + q + 1.0D);
|
||||||
|
|
||||||
|
for (TNT currentTNT : entities) {
|
||||||
|
if (currentTNT == tnt) continue;
|
||||||
|
if (!(currentTNT.getX() >= k && currentTNT.getY() >= r && currentTNT.getZ() >= t && currentTNT.getX() <= l && currentTNT.getY() <= s && currentTNT.getZ() <= u)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
double x = currentTNT.getX() - this.x;
|
||||||
|
double y = currentTNT.getY() - this.y;
|
||||||
|
double z = currentTNT.getZ() - this.z;
|
||||||
|
double aa = Math.sqrt(x * x + y * y + z * z);
|
||||||
|
double w = aa / q;
|
||||||
|
if (w > 1.0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (aa == 0.0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
x /= aa;
|
||||||
|
y /= aa;
|
||||||
|
z /= aa;
|
||||||
|
|
||||||
|
double ab = getExposure(this.x, this.y, this.z);
|
||||||
|
double ac = (1.0 - w) * ab;
|
||||||
|
currentTNT.setVx(currentTNT.getVx() + x * ac);
|
||||||
|
currentTNT.setVy(currentTNT.getVy() + y * ac);
|
||||||
|
currentTNT.setVz(currentTNT.getVz() + z * ac);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int floor(double value) {
|
||||||
|
int i = (int) value;
|
||||||
|
return value < (double) i ? i - 1 : i;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final double SIZE = 0.98;
|
||||||
|
private static final double MIN_POINT = 0.01;
|
||||||
|
private static final double MAX_POINT = SIZE + MIN_POINT;
|
||||||
|
private static final double EXPOSURE_CONSTANT_1 = 1.0 / (SIZE * 2 + 1.0);
|
||||||
|
private static final double EXPOSURE_CONSTANT_2 = (1.0 - Math.floor(1.0 / EXPOSURE_CONSTANT_1) * EXPOSURE_CONSTANT_1) / 2.0;
|
||||||
|
|
||||||
|
private static float getExposure(double x, double y, double z) {
|
||||||
|
float blockMisses = 0;
|
||||||
|
float blockTotal = 0;
|
||||||
|
|
||||||
|
for (double k = 0.0; k <= 1.0; k += EXPOSURE_CONSTANT_1) {
|
||||||
|
for (double l = 0.0; l <= 1.0; l += EXPOSURE_CONSTANT_1) {
|
||||||
|
for (double m = 0.0; m <= 1.0; m += EXPOSURE_CONSTANT_1) {
|
||||||
|
double dx = lerp(k, MIN_POINT, MAX_POINT) + EXPOSURE_CONSTANT_2;
|
||||||
|
double dy = lerp(l, 0.0, SIZE);
|
||||||
|
double dz = lerp(m, MIN_POINT, MAX_POINT) + EXPOSURE_CONSTANT_2;
|
||||||
|
|
||||||
|
if (rayTrace(x, y, z, dx, dy, dz)) {
|
||||||
|
blockMisses++;
|
||||||
|
}
|
||||||
|
blockTotal++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Add velocity change of other tnt entities
|
return blockMisses / blockTotal;
|
||||||
// System.out.println(affectedBlocks.size());
|
}
|
||||||
|
|
||||||
|
public static double lerp(double delta, double start, double end) {
|
||||||
|
return start + delta * (end - start);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean rayTrace(double sX, double sY, double sZ, double dX, double dY, double dZ) {
|
||||||
|
double x = sX;
|
||||||
|
double y = sY;
|
||||||
|
double z = sZ;
|
||||||
|
int oX = sX > dX ? -1 : 1;
|
||||||
|
int oY = sY > dY ? -1 : 1;
|
||||||
|
int oZ = sZ > dZ ? -1 : 1;
|
||||||
|
while (true) {
|
||||||
|
if (Simulator19.getBlockType(floor(x), floor(y), floor(z)) != Material.AIR) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
double cX = x - (floor(x) + oX);
|
||||||
|
double cY = y - (floor(y) + oY);
|
||||||
|
double cZ = z - (floor(z) + oZ);
|
||||||
|
|
||||||
|
double maxChange = Math.min(Math.abs(cX), Math.min(Math.abs(cY), Math.abs(cZ)));
|
||||||
|
x += Math.signum(cX) * maxChange;
|
||||||
|
y += Math.signum(cY) * maxChange;
|
||||||
|
z += Math.signum(cZ) * maxChange;
|
||||||
|
|
||||||
|
if (floor(x) == floor(dX) && floor(y) == floor(dY) && floor(z) == floor(dZ)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,19 @@ public class Simulator19 implements Simulator {
|
|||||||
|
|
||||||
protected static final World WORLD = Bukkit.getWorlds().get(0);
|
protected static final World WORLD = Bukkit.getWorlds().get(0);
|
||||||
|
|
||||||
|
private static final BlockData AIR_BLOCK_DATA = Material.AIR.createBlockData();
|
||||||
|
private static final VoxelShape AIR_VOXEL_SHAPE = new VoxelShape() {
|
||||||
|
@Override
|
||||||
|
public Collection<BoundingBox> getBoundingBoxes() {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean overlaps(BoundingBox boundingBox) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
private static final Map<Vector, Material> BLOCK_TYPES_MAP = new HashMap<>();
|
private static final Map<Vector, Material> BLOCK_TYPES_MAP = new HashMap<>();
|
||||||
private static final Map<Vector, BlockData> BLOCK_DATA_MAP = new HashMap<>();
|
private static final Map<Vector, BlockData> BLOCK_DATA_MAP = new HashMap<>();
|
||||||
private static final Map<Vector, VoxelShape> COLLISION_DATA_MAP = new HashMap<>();
|
private static final Map<Vector, VoxelShape> COLLISION_DATA_MAP = new HashMap<>();
|
||||||
@ -47,11 +60,9 @@ public class Simulator19 implements Simulator {
|
|||||||
while (!tntList.isEmpty()) {
|
while (!tntList.isEmpty()) {
|
||||||
List<TNT> remove = new ArrayList<>();
|
List<TNT> remove = new ArrayList<>();
|
||||||
for (TNT tnt : tntList) {
|
for (TNT tnt : tntList) {
|
||||||
if (tnt.getFuse() == 0) {
|
if (tnt.tick()) {
|
||||||
remove.add(tnt);
|
remove.add(tnt);
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
tnt.tick();
|
|
||||||
}
|
}
|
||||||
tntList.removeAll(remove);
|
tntList.removeAll(remove);
|
||||||
}
|
}
|
||||||
@ -72,25 +83,13 @@ public class Simulator19 implements Simulator {
|
|||||||
return BLOCK_DATA_MAP.computeIfAbsent(vector, v -> WORLD.getBlockAt(v.getBlockX(), v.getBlockY(), v.getBlockZ()).getBlockData());
|
return BLOCK_DATA_MAP.computeIfAbsent(vector, v -> WORLD.getBlockAt(v.getBlockX(), v.getBlockY(), v.getBlockZ()).getBlockData());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static VoxelShape getVoxelShape(int x, int y, int z) {
|
public static VoxelShape getVoxelShape(Vector vector) {
|
||||||
Vector vector = new Vector(x, y, z);
|
|
||||||
return COLLISION_DATA_MAP.computeIfAbsent(vector, v -> WORLD.getBlockAt(v.getBlockX(), v.getBlockY(), v.getBlockZ()).getCollisionShape());
|
return COLLISION_DATA_MAP.computeIfAbsent(vector, v -> WORLD.getBlockAt(v.getBlockX(), v.getBlockY(), v.getBlockZ()).getCollisionShape());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void clearBlock(int x, int y, int z) {
|
public static void clearBlock(Vector vector) {
|
||||||
Vector vector = new Vector(x, y, z);
|
|
||||||
BLOCK_TYPES_MAP.put(vector, Material.AIR);
|
BLOCK_TYPES_MAP.put(vector, Material.AIR);
|
||||||
BLOCK_DATA_MAP.put(vector, Material.AIR.createBlockData());
|
BLOCK_DATA_MAP.put(vector, AIR_BLOCK_DATA);
|
||||||
COLLISION_DATA_MAP.put(vector, new VoxelShape() {
|
COLLISION_DATA_MAP.put(vector, AIR_VOXEL_SHAPE);
|
||||||
@Override
|
|
||||||
public Collection<BoundingBox> getBoundingBoxes() {
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean overlaps(BoundingBox other) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,7 @@ import org.bukkit.block.data.type.*;
|
|||||||
import org.bukkit.craftbukkit.v1_19_R2.CraftWorld;
|
import org.bukkit.craftbukkit.v1_19_R2.CraftWorld;
|
||||||
import org.bukkit.util.Vector;
|
import org.bukkit.util.Vector;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@ -81,7 +82,7 @@ public class TNT {
|
|||||||
|
|
||||||
this.fuse--;
|
this.fuse--;
|
||||||
if (this.fuse <= 0) {
|
if (this.fuse <= 0) {
|
||||||
Explosion explosion = new Explosion(this, x, y + 0.98 * 0.0625, z);
|
Explosion explosion = new Explosion(this, x, y + 0.98 * 0.0625, z, new ArrayList<>());
|
||||||
explosion.calculate();
|
explosion.calculate();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
In neuem Issue referenzieren
Einen Benutzer sperren