📄 l1npcinstance.java
字号:
&& !pc.isGm()) {
_hateList.add(pc, 0);
_target = pc;
}
onNpcAI(); // モンスターのAIを開始
startChat(CHAT_TIMING_HIDE);
}
}
// ■■■■■■■■■■■■■ 移動関連 ■■■■■■■■■■■
// 指定された方向に移動させる
public void setDirectionMove(int dir) {
if (dir >= 0) {
int nx = 0;
int ny = 0;
switch (dir) {
case 1:
nx = 1;
ny = -1;
setHeading(1);
break;
case 2:
nx = 1;
ny = 0;
setHeading(2);
break;
case 3:
nx = 1;
ny = 1;
setHeading(3);
break;
case 4:
nx = 0;
ny = 1;
setHeading(4);
break;
case 5:
nx = -1;
ny = 1;
setHeading(5);
break;
case 6:
nx = -1;
ny = 0;
setHeading(6);
break;
case 7:
nx = -1;
ny = -1;
setHeading(7);
break;
case 0:
nx = 0;
ny = -1;
setHeading(0);
break;
default:
break;
}
getMap().setPassable(getLocation(), true);
int nnx = getX() + nx;
int nny = getY() + ny;
setX(nnx);
setY(nny);
getMap().setPassable(getLocation(), false);
broadcastPacket(new S_MoveCharPacket(this));
// movement_distanceマス以上離れたらホームポイントへテレポート
if (getMovementDistance() > 0) {
if (this instanceof L1GuardInstance
|| this instanceof L1MerchantInstance
|| this instanceof L1MonsterInstance) {
if (getLocation().getLineDistance(
new Point(getHomeX(), getHomeY())) > getMovementDistance()) {
teleport(getHomeX(), getHomeY(), getHeading());
}
}
}
// 恨みに満ちたソルジャーゴースト、恨みに満ちたゴースト、恨みに満ちたハメル将軍
if (getNpcTemplate().get_npcId() >= 45912
&& getNpcTemplate().get_npcId() <= 45916) {
if (getX() >= 32591 && getX() <= 32644
&& getY() >= 32643 && getY() <= 32688
&& getMapId() == 4) {
teleport(getHomeX(), getHomeY(), getHeading());
}
}
}
}
public int moveDirection(int x, int y) { // 目標点X 目標点Y
return moveDirection(x, y, getLocation().getLineDistance(
new Point(x, y)));
}
// 目標までの距離に応じて最適と思われるルーチンで進む方向を返す
public int moveDirection(int x, int y, double d) { // 目標点X 目標点Y 目標までの距離
int dir = 0;
if (hasSkillEffect(40) == true && d >= 2D) { // ダークネスが掛かっていて、距離が2以上の場合追跡終了
return -1;
} else if (d > 30D) { // 距離が激しく遠い場合は追跡終了
return -1;
} else if (d > courceRange) { // 距離が遠い場合は単純計算
dir = targetDirection(x, y);
dir = checkObject(getX(), getY(), getMapId(), dir);
} else { // 目標までの最短経路を探索
dir = _serchCource(x, y);
if (dir == -1) { // 目標までの経路がなっかた場合はとりあえず近づいておく
dir = targetDirection(x, y);
if (!isExsistCharacterBetweenTarget(dir)) {
dir = checkObject(getX(), getY(), getMapId(), dir);
}
}
}
return dir;
}
private boolean isExsistCharacterBetweenTarget(int dir) {
if (!(this instanceof L1MonsterInstance)) { // モンスター以外は対象外
return false;
}
if (_target == null) { // ターゲットがいない場合
return false;
}
int locX = getX();
int locY = getY();
int targetX = locX;
int targetY = locY;
if (dir == 1) {
targetX = locX + 1;
targetY = locY - 1;
} else if (dir == 2) {
targetX = locX + 1;
} else if (dir == 3) {
targetX = locX + 1;
targetY = locY + 1;
} else if (dir == 4) {
targetY = locY + 1;
} else if (dir == 5) {
targetX = locX - 1;
targetY = locY + 1;
} else if (dir == 6) {
targetX = locX - 1;
} else if (dir == 7) {
targetX = locX - 1;
targetY = locY - 1;
} else if (dir == 0) {
targetY = locY - 1;
}
for (L1Object object : L1World.getInstance().getVisibleObjects(this,
1)) {
// PC, Summon, Petがいる場合
if (object instanceof L1PcInstance
|| object instanceof L1SummonInstance
|| object instanceof L1PetInstance) {
L1Character cha = (L1Character) object;
// 進行方向に立ちふさがっている場合、ターゲットリストに加える
if (cha.getX() == targetX && cha.getY() == targetY
&& cha.getMapId() == getMapId()) {
if (object instanceof L1PcInstance) {
L1PcInstance pc = (L1PcInstance) object;
if (pc.isGhost()) { // UB観戦中のPCは除く
continue;
}
}
_hateList.add(cha, 0);
_target = cha;
return true;
}
}
}
return false;
}
// 目標の逆方向を返す
public int targetReverseDirection(int tx, int ty) { // 目標点X 目標点Y
int dir = targetDirection(tx, ty);
dir += 4;
if (dir > 7) {
dir -= 8;
}
return dir;
}
// 進みたい方向に障害物がないか確認、ある場合は前方斜め左右も確認後進める方向を返す
// ※従来あった処理に、バックできない仕様を省いて、目標の反対(左右含む)には進まないようにしたもの
public static int checkObject(int x, int y, short m, int d) { // 起点X 起点Y
// マップID
// 進行方向
L1Map map = L1WorldMap.getInstance().getMap(m);
if (d == 1) {
if (map.isPassable(x, y, 1)) {
return 1;
} else if (map.isPassable(x, y, 0)) {
return 0;
} else if (map.isPassable(x, y, 2)) {
return 2;
}
} else if (d == 2) {
if (map.isPassable(x, y, 2)) {
return 2;
} else if (map.isPassable(x, y, 1)) {
return 1;
} else if (map.isPassable(x, y, 3)) {
return 3;
}
} else if (d == 3) {
if (map.isPassable(x, y, 3)) {
return 3;
} else if (map.isPassable(x, y, 2)) {
return 2;
} else if (map.isPassable(x, y, 4)) {
return 4;
}
} else if (d == 4) {
if (map.isPassable(x, y, 4)) {
return 4;
} else if (map.isPassable(x, y, 3)) {
return 3;
} else if (map.isPassable(x, y, 5)) {
return 5;
}
} else if (d == 5) {
if (map.isPassable(x, y, 5)) {
return 5;
} else if (map.isPassable(x, y, 4)) {
return 4;
} else if (map.isPassable(x, y, 6)) {
return 6;
}
} else if (d == 6) {
if (map.isPassable(x, y, 6)) {
return 6;
} else if (map.isPassable(x, y, 5)) {
return 5;
} else if (map.isPassable(x, y, 7)) {
return 7;
}
} else if (d == 7) {
if (map.isPassable(x, y, 7)) {
return 7;
} else if (map.isPassable(x, y, 6)) {
return 6;
} else if (map.isPassable(x, y, 0)) {
return 0;
}
} else if (d == 0) {
if (map.isPassable(x, y, 0)) {
return 0;
} else if (map.isPassable(x, y, 7)) {
return 7;
} else if (map.isPassable(x, y, 1)) {
return 1;
}
}
return -1;
}
// 目標までの最短経路の方向を返す
// ※目標を中心とした探索範囲のマップで探索
private int _serchCource(int x, int y) // 目標点X 目標点Y
{
int i;
int locCenter = courceRange + 1;
int diff_x = x - locCenter; // Xの実際のロケーションとの差
int diff_y = y - locCenter; // Yの実際のロケーションとの差
int[] locBace = { getX() - diff_x, getY() - diff_y, 0, 0 }; // X Y
// 方向
// 初期方向
int[] locNext = new int[4];
int[] locCopy;
int[] dirFront = new int[5];
boolean serchMap[][] = new boolean[locCenter * 2 + 1][locCenter * 2 + 1];
LinkedList<int[]> queueSerch = new LinkedList<int[]>();
// 探索用マップの設定
for (int j = courceRange * 2 + 1; j > 0; j--) {
for (i = courceRange - Math.abs(locCenter - j); i >= 0; i--) {
serchMap[j][locCenter + i] = true;
serchMap[j][locCenter - i] = true;
}
}
// 初期方向の設置
int[] firstCource = { 2, 4, 6, 0, 1, 3, 5, 7 };
for (i = 0; i < 8; i++) {
System.arraycopy(locBace, 0, locNext, 0, 4);
_moveLocation(locNext, firstCource[i]);
if (locNext[0] - locCenter == 0 && locNext[1] - locCenter == 0) {
// 最短経路が見つかった場合:隣
return firstCource[i];
}
if (serchMap[locNext[0]][locNext[1]]) {
int tmpX = locNext[0] + diff_x;
int tmpY = locNext[1] + diff_y;
boolean found = false;
if (i == 0) {
found = getMap().isPassable(tmpX, tmpY + 1, i);
} else if (i == 1) {
found = getMap().isPassable(tmpX - 1, tmpY + 1, i);
} else if (i == 2) {
found = getMap().isPassable(tmpX - 1, tmpY, i);
} else if (i == 3) {
found = getMap().isPassable(tmpX - 1, tmpY - 1, i);
} else if (i == 4) {
found = getMap().isPassable(tmpX, tmpY - 1, i);
} else if (i == 5) {
found = getMap().isPassable(tmpX + 1, tmpY - 1, i);
} else if (i == 6) {
found = getMap().isPassable(tmpX + 1, tmpY, i);
} else if (i == 7) {
found = getMap().isPassable(tmpX + 1, tmpY + 1, i);
}
if (found)// 移動経路があった場合
{
locCopy = new int[4];
System.arraycopy(locNext, 0, locCopy, 0, 4);
locCopy[2] = firstCource[i];
locCopy[3] = firstCource[i];
queueSerch.add(locCopy);
}
serchMap[locNext[0]][locNext[1]] = false;
}
}
locBace = null;
// 最短経路を探索
while (queueSerch.size() > 0) {
locBace = queueSerch.removeFirst();
_getFront(dirFront, locBace[2]);
for (i = 4; i >= 0; i--) {
System.arraycopy(locBace, 0, locNext, 0, 4);
_moveLocation(locNext, dirFront[i]);
if (locNext[0] - locCenter == 0 && locNext[1] - locCenter == 0) {
return locNext[3];
}
if (serchMap[locNext[0]][locNext[1]]) {
int tmpX = locNext[0] + diff_x;
int tmpY = locNext[1] + diff_y;
boolean found = false;
if (i == 0) {
found = getMap().isPassable(tmpX, tmpY + 1, i);
} else if (i == 1) {
found = getMap().isPassable(tmpX - 1, tmpY + 1, i);
} else if (i == 2) {
found = getMap().isPassable(tmpX - 1, tmpY, i);
} else if (i == 3) {
found = getMap().isPassable(tmpX - 1, tmpY - 1, i);
} else if (i == 4) {
found = getMap().isPassable(tmpX, tmpY - 1, i);
}
if (found) // 移動経路があった場合
{
locCopy = new int[4];
System.arraycopy(locNext, 0, locCopy, 0, 4);
locCopy[2] = dirFront[i];
queueSerch.add(locCopy);
}
serchMap[locNext[0]][locNext[1]] = false;
}
}
locBace = null;
}
return -1; // 目標までの経路がない場合
}
private void _moveLocation(int[] ary, int d) {
if (d == 1) {
ary[0] = ary[0] + 1;
ary[1] = ary[1] - 1;
} else if (d == 2) {
ary[0] = ary[0] + 1;
} else if (d == 3) {
ary[0] = ary[0] + 1;
ary[1] = ary[1] + 1;
} else if (d == 4) {
ary[1] = ary[1] + 1;
} else if (d == 5) {
ary[0] = ary[0] - 1;
ary[1] = ary[1] + 1;
} else if (d == 6) {
ary[0] = ary[0] - 1;
} else if (d == 7) {
ary[0] = ary[0] - 1;
ary[1] = ary[1] - 1;
} else if (d == 0) {
ary[1] = ary[1] - 1;
}
ary[2] = d;
}
private void _getFront(int[] ary, int d) {
if (d == 1) {
ary[4] = 2;
ary[3] = 0;
ary[2] = 1;
ary[1] = 3;
ary[0] = 7;
} else if (d == 2) {
ary[4] = 2;
ary[3] = 4;
ary[2] = 0;
ary[1] = 1;
ary[0] = 3;
} else if (d == 3) {
ary[4] = 2;
ary[3] = 4;
ary[2] = 1;
ary[1] = 3;
ary[0] = 5;
} else if (d == 4) {
ary[4] = 2;
ary[3] = 4;
ary[2] = 6;
ary[1] = 3;
ary[0] = 5;
} else if (d == 5) {
ary[4] = 4;
ary[3] = 6;
ary[2] = 3;
ary[1] = 5;
ary[0] = 7;
} else if (d == 6) {
ary[4] = 4;
ary[3] = 6;
ary[2] = 0;
ary[1] = 5;
ary[0] = 7;
} else if (d == 7) {
ary[4] = 6;
ary[3] = 0;
ary[2] = 1;
ary[1] = 5;
ary[0] = 7;
} else if (d == 0) {
ary[4] = 2;
ary[3] = 6;
ary[2] = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -