fix: mind stone creates an infinite ray
This commit is contained in:
parent
2b11633ced
commit
81cbec5348
@ -176,6 +176,10 @@ public class GameLogic {
|
|||||||
throw new InvalidRequestException("Invalid soul stone target (same as origin)");
|
throw new InvalidRequestException("Invalid soul stone target (same as origin)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(data.originField.distanceChebyshev(data.targetField) != 1) {
|
||||||
|
throw new InvalidRequestException("Invalid soul stone target distance");
|
||||||
|
}
|
||||||
|
|
||||||
if(target.isAlive()) {
|
if(target.isAlive()) {
|
||||||
throw new InvalidRequestException("Invalid soul stone target (already alive)");
|
throw new InvalidRequestException("Invalid soul stone target (already alive)");
|
||||||
}
|
}
|
||||||
@ -403,8 +407,7 @@ public class GameLogic {
|
|||||||
}
|
}
|
||||||
case MindStone -> {
|
case MindStone -> {
|
||||||
EntityType target = data.originEntity.type == EntityType.P1 ? EntityType.P2 : EntityType.P1;
|
EntityType target = data.originEntity.type == EntityType.P1 ? EntityType.P2 : EntityType.P1;
|
||||||
//todo: extend to infinity
|
for(IntVector2 pos: rasterizeInfinity(data.originField, data.targetField, state.mapSize, false)) {
|
||||||
for(IntVector2 pos: rasterize(data.originField, data.targetField, false, true)) {
|
|
||||||
for(Entity entity: state.entities.findByPosition(pos)) {
|
for(Entity entity: state.entities.findByPosition(pos)) {
|
||||||
if(entity.id.isSameType(target)) {
|
if(entity.id.isSameType(target)) {
|
||||||
result.add(new EventBuilder(EventType.TakenDamageEvent)
|
result.add(new EventBuilder(EventType.TakenDamageEvent)
|
||||||
@ -1292,6 +1295,62 @@ public class GameLogic {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes all fields which intersect the ray between the center points of the given two fields extending past the second one.
|
||||||
|
* @param size The size of the map
|
||||||
|
* @param includeA Whether to include point a in the result
|
||||||
|
* @return The list of intersecting positions
|
||||||
|
*/
|
||||||
|
public static ArrayList<IntVector2> rasterizeInfinity(IntVector2 a, IntVector2 b, IntVector2 size, boolean includeA) {
|
||||||
|
ArrayList<IntVector2> result = new ArrayList<>();
|
||||||
|
|
||||||
|
if(includeA) {
|
||||||
|
result.add(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
int x1 = a.getX();
|
||||||
|
int y1 = a.getY();
|
||||||
|
int x2 = b.getX();
|
||||||
|
int y2 = b.getY();
|
||||||
|
|
||||||
|
Line2D line = new Line2D.Float(x1 + 0.5f, y1 + 0.5f, x2 + 0.5f, y2 + 0.5f);
|
||||||
|
double l = line.getP1().distance(line.getP2());
|
||||||
|
|
||||||
|
for(int i = 0; i < size.getX(); i++) {
|
||||||
|
for(int j = 0; j < size.getY(); j++) {
|
||||||
|
HashSet<Point2D.Float> intersections = new HashSet<>();
|
||||||
|
for(Line2D.Float part: getWireframe(new Rectangle.Float(i, j, 1, 1))) {
|
||||||
|
Point2D.Float intersection = calculateInterceptionPoint(line.getP1(), line.getP2(), part.getP1(), part.getP2());
|
||||||
|
if(intersection != null) {
|
||||||
|
double dPa = intersection.distance(part.getP1());
|
||||||
|
double dPb = intersection.distance(part.getP2());
|
||||||
|
// sum of distances to points of the rectangle part == 1 => point lies on line segment
|
||||||
|
// -----a---x----b-----
|
||||||
|
// --x--a--------b-----
|
||||||
|
if(dPa + dPb == 1) {
|
||||||
|
double da = intersection.distance(line.getP1());
|
||||||
|
double db = intersection.distance(line.getP2());
|
||||||
|
// distance to a greater than to b => point lies on the ray from a over b
|
||||||
|
// sum of distances analog to rectangle part => point lies between a and b
|
||||||
|
// 0.000000005 because computers suck (missing precision)
|
||||||
|
if(da > db || da + db <= l + 0.000000005) {
|
||||||
|
intersections.add(intersection);
|
||||||
|
if(intersections.size() > 1) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(intersections.size() > 1) {
|
||||||
|
result.add(new IntVector2(i, j));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
//https://rosettacode.org/wiki/Find_the_intersection_of_two_lines#Java
|
//https://rosettacode.org/wiki/Find_the_intersection_of_two_lines#Java
|
||||||
public static Point2D.Float calculateInterceptionPoint(Point2D s1, Point2D s2, Point2D d1, Point2D d2) {
|
public static Point2D.Float calculateInterceptionPoint(Point2D s1, Point2D s2, Point2D d1, Point2D d2) {
|
||||||
double a1 = s2.getY() - s1.getY();
|
double a1 = s2.getY() - s1.getY();
|
||||||
@ -1303,6 +1362,9 @@ public class GameLogic {
|
|||||||
double c2 = a2 * d1.getX() + b2 * d1.getY();
|
double c2 = a2 * d1.getX() + b2 * d1.getY();
|
||||||
|
|
||||||
double delta = a1 * b2 - a2 * b1;
|
double delta = a1 * b2 - a2 * b1;
|
||||||
|
if(delta == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
return new Point2D.Float((float) ((b2 * c1 - b1 * c2) / delta), (float) ((a1 * c2 - a2 * c1) / delta));
|
return new Point2D.Float((float) ((b2 * c1 - b1 * c2) / delta), (float) ((a1 * c2 - a2 * c1) / delta));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user