Projectile clipping, PassDoor fix (#176)

* Numbered packet sizes.
Corrected sound packet length to 6 from 5.
Corrected sound packet in server.
Teleport sound now plays correctly.
Corrected modern teleport animation playthrough.
Removed redundant teleport delay.

* Changed sendSound packet size back to 5 and removed type attribute to maintain compatibility with Parabot.

* After running around an object to attack the player will no longer wait a number of ticks to start attacking again.
Fixed an issue where walkTo being called from CycleEvents would not execute correctly.
Player will no longer face a killed npc after it respawns.
Added projectile clipping.
Added a new algorithm for player->player/npc following that accounts for projectile clipping.
This commit is contained in:
mikeysasse
2019-11-11 14:20:02 -06:00
committed by Daniel Ginovker
parent a4e4b89d99
commit c827d46ca0
66 changed files with 1293 additions and 480 deletions
@@ -3,6 +3,7 @@ package redone.world.clip;
import java.util.LinkedList;
import redone.game.players.Client;
import redone.util.Misc;
public class PathFinder {
@@ -209,6 +210,207 @@ public class PathFinder {
}
}
public int getRegionCoordinate(int x) {
return (x >> 3) - 6;
}
public int getLocalCoordinate(int x) {
return x - 8 * getRegionCoordinate(x);
}
public boolean accessible(int x, int y, int heightLevel, int destX, int destY) {
destX = destX - 8 * getRegionCoordinate(x);
destY = destY - 8 * getRegionCoordinate(y);
int[][] via = new int[104][104];
int[][] cost = new int[104][104];
LinkedList<Integer> tileQueueX = new LinkedList<Integer>();
LinkedList<Integer> tileQueueY = new LinkedList<Integer>();
for (int xx = 0; xx < 104; xx++) {
for (int yy = 0; yy < 104; yy++) {
cost[xx][yy] = 99999999;
}
}
int curX = getLocalCoordinate(x);
int curY = getLocalCoordinate(y);
via[curX][curY] = 99;
cost[curX][curY] = 0;
int tail = 0;
tileQueueX.add(curX);
tileQueueY.add(curY);
boolean foundPath = false;
int pathLength = 4000;
while (tail != tileQueueX.size() && tileQueueX.size() < pathLength) {
curX = tileQueueX.get(tail);
curY = tileQueueY.get(tail);
int curAbsX = getRegionCoordinate(x) * 8 + curX;
int curAbsY = getRegionCoordinate(y) * 8 + curY;
if (curX == destX && curY == destY) {
foundPath = true;
break;
}
tail = (tail + 1) % pathLength;
int thisCost = cost[curX][curY] + 1;
if (curY > 0
&& via[curX][curY - 1] == 0
&& (Region.getClipping(curAbsX, curAbsY - 1, heightLevel) & 0x1280102) == 0) {
tileQueueX.add(curX);
tileQueueY.add(curY - 1);
via[curX][curY - 1] = 1;
cost[curX][curY - 1] = thisCost;
}
if (curX > 0
&& via[curX - 1][curY] == 0
&& (Region.getClipping(curAbsX - 1, curAbsY, heightLevel) & 0x1280108) == 0) {
tileQueueX.add(curX - 1);
tileQueueY.add(curY);
via[curX - 1][curY] = 2;
cost[curX - 1][curY] = thisCost;
}
if (curY < 104 - 1
&& via[curX][curY + 1] == 0
&& (Region.getClipping(curAbsX, curAbsY + 1, heightLevel) & 0x1280120) == 0) {
tileQueueX.add(curX);
tileQueueY.add(curY + 1);
via[curX][curY + 1] = 4;
cost[curX][curY + 1] = thisCost;
}
if (curX < 104 - 1
&& via[curX + 1][curY] == 0
&& (Region.getClipping(curAbsX + 1, curAbsY, heightLevel) & 0x1280180) == 0) {
tileQueueX.add(curX + 1);
tileQueueY.add(curY);
via[curX + 1][curY] = 8;
cost[curX + 1][curY] = thisCost;
}
if (curX > 0
&& curY > 0
&& via[curX - 1][curY - 1] == 0
&& (Region.getClipping(curAbsX - 1, curAbsY - 1,
heightLevel) & 0x128010e) == 0
&& (Region.getClipping(curAbsX - 1, curAbsY, heightLevel) & 0x1280108) == 0
&& (Region.getClipping(curAbsX, curAbsY - 1, heightLevel) & 0x1280102) == 0) {
tileQueueX.add(curX - 1);
tileQueueY.add(curY - 1);
via[curX - 1][curY - 1] = 3;
cost[curX - 1][curY - 1] = thisCost;
}
if (curX > 0
&& curY < 104 - 1
&& via[curX - 1][curY + 1] == 0
&& (Region.getClipping(curAbsX - 1, curAbsY + 1,
heightLevel) & 0x1280138) == 0
&& (Region.getClipping(curAbsX - 1, curAbsY, heightLevel) & 0x1280108) == 0
&& (Region.getClipping(curAbsX, curAbsY + 1, heightLevel) & 0x1280120) == 0) {
tileQueueX.add(curX - 1);
tileQueueY.add(curY + 1);
via[curX - 1][curY + 1] = 6;
cost[curX - 1][curY + 1] = thisCost;
}
if (curX < 104 - 1
&& curY > 0
&& via[curX + 1][curY - 1] == 0
&& (Region.getClipping(curAbsX + 1, curAbsY - 1,
heightLevel) & 0x1280183) == 0
&& (Region.getClipping(curAbsX + 1, curAbsY, heightLevel) & 0x1280180) == 0
&& (Region.getClipping(curAbsX, curAbsY - 1, heightLevel) & 0x1280102) == 0) {
tileQueueX.add(curX + 1);
tileQueueY.add(curY - 1);
via[curX + 1][curY - 1] = 9;
cost[curX + 1][curY - 1] = thisCost;
}
if (curX < 104 - 1
&& curY < 104 - 1
&& via[curX + 1][curY + 1] == 0
&& (Region.getClipping(curAbsX + 1, curAbsY + 1,
heightLevel) & 0x12801e0) == 0
&& (Region.getClipping(curAbsX + 1, curAbsY, heightLevel) & 0x1280180) == 0
&& (Region.getClipping(curAbsX, curAbsY + 1, heightLevel) & 0x1280120) == 0) {
tileQueueX.add(curX + 1);
tileQueueY.add(curY + 1);
via[curX + 1][curY + 1] = 12;
cost[curX + 1][curY + 1] = thisCost;
}
}
return foundPath;
}
public static boolean isProjectilePathClear(int x0, int y0, int z, int x1, int y1) {
int deltaX = x1 - x0;
int deltaY = y1 - y0;
double error = 0;
final double deltaError = Math.abs(
(deltaY) / (deltaX == 0
? ((double) deltaY)
: ((double) deltaX)));
int x = x0;
int y = y0;
int pX = x;
int pY = y;
boolean incrX = x0 < x1;
boolean incrY = y0 < y1;
while (true) {
if (x != x1) {
x += (incrX ? 1 : -1);
}
if (y != y1) {
error += deltaError;
if (error >= 0.5) {
y += (incrY ? 1 : -1);
error -= 1;
}
}
if (!shootable(x, y, z, pX, pY)) {
return false;
}
if (incrX && incrY
&& x >= x1 && y >= y1) {
break;
} else if (!incrX && !incrY
&& x <= x1 && y <= y1) {
break;
} else if (!incrX && incrY
&& x <= x1 && y >= y1) {
break;
} else if (incrX && !incrY
&& x >= x1 && y <= y1) {
break;
}
pX = x;
pY = y;
}
return true;
}
private static boolean shootable(int x, int y, int z, int px, int py) {
if (x == px && y == py) {
return true;
}
int[] delta1 = Misc.delta(x, y, px, py);
int[] delta2 = Misc.delta(px, py, x, y);
int dir = Misc.directionFromDelta(delta1[0], delta1[1]);
int dir2 = Misc.directionFromDelta(delta2[0], delta2[1]);
if (dir == -1 || dir2 == -1) {
return false;
}
return Region.canMove(x, y, z, dir) && Region.canMove(px, py, z, dir2)
|| Region.canShoot(x, y, z, dir) && Region.canShoot(px, py, z, dir2);
}
public int localize(int x, int mapRegion) {
return x - 8 * mapRegion;
}