/**
* License
* THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS
* CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE").
* THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW.
* ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR
* COPYRIGHT LAW IS PROHIBITED.
*
* BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND
* AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE
* MAY BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED
* HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS.
*
*/
package l1j.server.server.model.map;
import l1j.server.server.ActionCodes;
import l1j.server.server.datatables.DoorTable;
import l1j.server.server.model.Instance.L1DoorInstance;
import l1j.server.server.types.Point;
public class L1V2Map extends L1Map {
private final int _id;
private final int _xLoc;
private final int _yLoc;
private final int _width;
private final int _height;
private final byte _map[];
private boolean _isUnderwater;
private boolean _isMarkable;
private boolean _isTeleportable;
private boolean _isEscapable;
private boolean _isUseResurrection;
private boolean _isUsePainwand;
private boolean _isEnabledDeathPenalty;
private boolean _isTakePets;
private boolean _isRecallPets;
private boolean _isUsableItem;
private boolean _isUsableSkill;
/**
* Mobなどの通行不可能になるオブジェクトがタイル上に存在するかを示すビットフラグ
*/
private static final byte BITFLAG_IS_IMPASSABLE = (byte) 128; // 1000 0000
private int offset(int x, int y) {
return ((y - _yLoc) * _width * 2) + ((x - _xLoc) * 2);
}
private int accessOriginalTile(int x, int y) {
return _map[offset(x, y)] & (~BITFLAG_IS_IMPASSABLE);
}
public L1V2Map(int id, byte map[], int xLoc, int yLoc, int width,
int height, boolean underwater, boolean markable,
boolean teleportable, boolean escapable, boolean useResurrection,
boolean usePainwand, boolean enabledDeathPenalty, boolean takePets,
boolean recallPets, boolean usableItem, boolean usableSkill) {
_id = id;
_map = map;
_xLoc = xLoc;
_yLoc = yLoc;
_width = width;
_height = height;
_isUnderwater = underwater;
_isMarkable = markable;
_isTeleportable = teleportable;
_isEscapable = escapable;
_isUseResurrection = useResurrection;
_isUsePainwand = usePainwand;
_isEnabledDeathPenalty = enabledDeathPenalty;
_isTakePets = takePets;
_isRecallPets = recallPets;
_isUsableItem = usableItem;
_isUsableSkill = usableSkill;
}
@Override
public int getHeight() {
return _height;
}
@Override
public int getId() {
return _id;
}
@Override
public int getOriginalTile(int x, int y) {
int lo = _map[offset(x, y)];
int hi = _map[offset(x, y) + 1];
return (lo | ((hi << 8) & 0xFF00));
}
@Override
public int getTile(int x, int y) {
return _map[offset(x, y)];
}
@Override
public int getWidth() {
return _width;
}
@Override
public int getX() {
return _xLoc;
}
@Override
public int getY() {
return _yLoc;
}
@Override
public boolean isArrowPassable(Point pt) {
return isArrowPassable(pt.getX(), pt.getY());
}
@Override
public boolean isArrowPassable(int x, int y) {
return (accessOriginalTile(x, y) != 1);
}
@Override
public boolean isArrowPassable(Point pt, int heading) {
return isArrowPassable(pt.getX(), pt.getY(), heading);
}
@Override
public boolean isArrowPassable(int x, int y, int heading) {
int tile;
// 移動予定の座標
int newX;
int newY;
if (heading == 0) {
tile = accessOriginalTile(x, y - 1);
newX = x;
newY = y - 1;
} else if (heading == 1) {
tile = accessOriginalTile(x + 1, y - 1);
newX = x + 1;
newY = y - 1;
} else if (heading == 2) {
tile = accessOriginalTile(x + 1, y);
newX = x + 1;
newY = y;
} else if (heading == 3) {
tile = accessOriginalTile(x + 1, y + 1);
newX = x + 1;
newY = y + 1;
} else if (heading == 4) {
tile = accessOriginalTile(x, y + 1);
newX = x;
newY = y + 1;
} else if (heading == 5) {
tile = accessOriginalTile(x - 1, y + 1);
newX = x - 1;
newY = y + 1;
} else if (heading == 6) {
tile = accessOriginalTile(x - 1, y);
newX = x - 1;
newY = y;
} else if (heading == 7) {
tile = accessOriginalTile(x - 1, y - 1);
newX = x - 1;
newY = y - 1;
} else {
return false;
}
if (isExistDoor(newX, newY)) {
return false;
}
return (tile != 1);
}
@Override
public boolean isCombatZone(Point pt) {
return isCombatZone(pt.getX(), pt.getY());
}
@Override
public boolean isCombatZone(int x, int y) {
return (accessOriginalTile(x, y) == 8);
}
@Override
public boolean isInMap(Point pt) {
return isInMap(pt.getX(), pt.getY());
}
@Override
public boolean isInMap(int x, int y) {
return (_xLoc <= x && x < _xLoc + _width && _yLoc <= y && y < _yLoc
+ _height);
}
@Override
public boolean isNormalZone(Point pt) {
return isNormalZone(pt.getX(), pt.getY());
}
@Override
public boolean isNormalZone(int x, int y) {
return (!isCombatZone(x, y) && !isSafetyZone(x, y));
}
@Override
public boolean isPassable(Point pt) {
return isPassable(pt.getX(), pt.getY());
}
@Override
public boolean isPassable(int x, int y) {
int tile = accessOriginalTile(x, y);
if (tile == 1 || tile == 9 || tile == 65 || tile == 69 || tile == 73) {
return false;
}
if (0 != (_map[offset(x, y)] & BITFLAG_IS_IMPASSABLE)) {
return false;
}
return true;
}
@Override
public boolean isPassable(Point pt, int heading) {
return isPassable(pt.getX(), pt.getY(), heading);
}
@Override
public boolean isPassable(int x, int y, int heading) {
int tile;
if (heading == 0) {
tile = accessOriginalTile(x, y - 1);
} else if (heading == 1) {
tile = accessOriginalTile(x + 1, y - 1);
} else if (heading == 2) {
tile = accessOriginalTile(x + 1, y);
} else if (heading == 3) {
tile = accessOriginalTile(x + 1, y + 1);
} else if (heading == 4) {
tile = accessOriginalTile(x, y + 1);
} else if (heading == 5) {
tile = accessOriginalTile(x - 1, y + 1);
} else if (heading == 6) {
tile = accessOriginalTile(x - 1, y);
} else if (heading == 7) {
tile = accessOriginalTile(x - 1, y - 1);
} else {
return false;
}
if (tile == 1 || tile == 9 || tile == 65 || tile == 69 || tile == 73) {
return false;
}
if (0 != (_map[offset(x, y)] & BITFLAG_IS_IMPASSABLE)) {
return false;
}
return true;
}
@Override
public boolean isSafetyZone(Point pt) {
return isSafetyZone(pt.getX(), pt.getY());
}
@Override
public boolean isSafetyZone(int x, int y) {
return accessOriginalTile(x, y) == 4;
}
@Override
public void setPassable(Point pt, boolean isPassable) {
setPassable(pt.getX(), pt.getY(), isPassable);
}
@Override
public void setPassable(int x, int y, boolean isPassable) {
if (isPassable) {
_map[offset(x, y)] &= (~BITFLAG_IS_IMPASSABLE);
} else {
_map[offset(x, y)] |= BITFLAG_IS_IMPASSABLE;
}
}
@Override
public boolean isUnderwater() {
return _isUnderwater;
}
@Override
public boolean isMarkable() {
return _isMarkable;
}
@Override
public boolean isTeleportable() {
return _isTeleportable;
}
@Override
public boolean isEscapable() {
return _isEscapable;
}
@Override
public boolean isUseResurrection() {
return _isUseResurrection;
}
@Override
public boolean isUsePainwand() {
return _isUsePainwand;
}
@Override
public boolean isEnabledDeathPenalty() {
return _isEnabledDeathPenalty;
}
@Override
public boolean isTakePets() {
return _isTakePets;
}
@Override
public boolean isRecallPets() {
return _isRecallPets;
}
@Override
public boolean isUsableItem() {
return _isUsableItem;
}
@Override
public boolean isUsableSkill() {
return _isUsableSkill;
}
@Override
public boolean isFishingZone(int x, int y) {
return accessOriginalTile(x, y) == 28; // 3.3C 釣魚池可釣魚區域
}
@Override
public boolean isExistDoor(int x, int y) {
for (L1DoorInstance door : DoorTable.getInstance().getDoorList()) {
if (door.getOpenStatus() == ActionCodes.ACTION_Open) {
continue;
}
if (door.isDead()) {
continue;
}
int leftEdgeLocation = door.getLeftEdgeLocation();
int rightEdgeLocation = door.getRightEdgeLocation();
int size = rightEdgeLocation - leftEdgeLocation;
if (size == 0) { // 1マス分の幅のドア
if (x == door.getX() && y == door.getY()) {
return true;
}
} else { // 2マス分以上の幅があるドア
if (door.getDirection() == 0) { // /向き
for (int doorX = leftEdgeLocation;
doorX <= rightEdgeLocation; doorX++) {
if (x == doorX && y == door.getY()) {
return true;
}
}
} else { // \向き
for (int doorY = leftEdgeLocation;
doorY <= rightEdgeLocation; doorY++) {
if (x == door.getX() && y == doorY) {
return true;
}
}
}
}
}
return false;
}
@Override
public String toString(Point pt) {
int tile = getOriginalTile(pt.getX(), pt.getY());
return (tile & 0xFF) + " " + ((tile >> 8) & 0xFF);
}
}