22 package com.realtime.crossfire.jxclient.map;
27 import java.util.Collection;
28 import java.util.HashMap;
29 import java.util.HashSet;
32 import org.jetbrains.annotations.NotNull;
33 import org.jetbrains.annotations.Nullable;
133 public void reset(
final int mapWidth,
final int mapHeight) {
145 dirtyMapSquares.clear();
146 pendingFaceSquares.clear();
159 public void setDarkness(
final int x,
final int y,
final int darkness) {
160 assert Thread.holdsLock(
this);
176 assert Thread.holdsLock(
this);
188 public void setSmooth(
final int x,
final int y,
final int layer,
final int smooth) {
190 if ((result&1) != 0) {
195 if ((result&2) != 0) {
196 for (
int dx = -1; dx <= +1; dx++) {
197 for (
int dy = -1; dy <= +1; dy++) {
211 public int getSmooth(
final int x,
final int y,
final int layer) {
223 public void setMagicMap(
final int x0,
final int y0,
final byte[][] data) {
224 assert Thread.holdsLock(
this);
225 for (
int y = 0; y < data.length; y++) {
226 for (
int x = 0; x < data[y].length; x++) {
228 if (
expandTo(x0+x, y0+y).setColor(ox, oy, color)) {
244 assert Thread.holdsLock(
this);
257 public void setFace(
final int x,
final int y,
final int layer, @Nullable
final Face face) {
258 assert Thread.holdsLock(
this);
259 if (
expandTo(x, y).resetFogOfWar(ox, oy)) {
281 if (oldFace != null) {
282 expandFace(x, y, layer, oldFace, headMapSquare, null);
284 headMapSquare.
setFace(layer, face);
286 expandFace(x, y, layer, face, headMapSquare, headMapSquare);
301 final int sx = face.getTileWidth();
302 final int sy = face.getTileHeight();
303 for (
int dx = 0; dx < sx; dx++) {
304 for (
int dy = 0; dy < sy; dy++) {
305 if (dx > 0 || dy > 0) {
306 if (newMapSquare != null) {
324 private void dirtyFace(
final int x,
final int y,
final int layer, @NotNull
final Face face) {
325 final int sx = face.getTileWidth();
326 final int sy = face.getTileHeight();
327 for (
int dx = 0; dx < sx; dx++) {
328 for (
int dy = 0; dy < sy; dy++) {
329 if (dx > 0 || dy > 0) {
349 assert Thread.holdsLock(
this);
379 assert Thread.holdsLock(
this);
391 assert Thread.holdsLock(
this);
407 public void dirty(
final int x,
final int y) {
408 assert Thread.holdsLock(
this);
419 assert Thread.holdsLock(
this);
421 return mapPatch != null && mapPatch.
isFogOfWar(ox, oy);
434 if (x < minX || x > maxX || y < minY || y > maxY) {
442 assert px <= maxPx-
minPx;
443 assert py <= maxPy-
minPy;
451 assert patch != null;
452 assert patch[px] != null;
454 if (mapPatch != null) {
458 patch[px][py] =
new CfMapPatch(
this, x-patchX-ox, y-patchY-oy);
459 assert patch != null;
460 assert patch[px] != null;
461 return patch[px][py];
469 private void scroll(
final int dx,
final int dy) {
470 assert Thread.holdsLock(
this);
471 if (dx == 0 && dy == 0) {
492 if (minX > maxX || minY > maxY) {
521 assert result != null;
532 private void increase(
final int dx,
final int dy) {
534 final int newMinX = minX+dx;
536 final int diffPw = minPx-newMinPx;
546 final int newPw =
size(newMinPx, maxPx);
547 final int newPh =
size(minPy, maxPy);
548 assert patch != null;
549 final int oldPw = patch.length;
550 final int oldPh = patch[0].length;
553 assert newPw > oldPw;
554 assert newPw == oldPw+diffPw;
555 assert newPh == oldPh;
559 patch =
copyPatches(newPw, newPh, diffPw, 0, oldPw, oldPh);
562 final int newMaxX = maxX+dx;
564 final int diffPw = newMaxPx-maxPx;
574 final int newPw =
size(minPx, newMaxPx);
575 final int newPh =
size(minPy, maxPy);
576 assert patch != null;
577 final int oldPw = patch.length;
578 final int oldPh = patch[0].length;
581 assert newPw > oldPw;
582 assert newPw == oldPw+diffPw;
583 assert newPh == oldPh;
587 patch =
copyPatches(newPw, newPh, 0, 0, oldPw, oldPh);
592 final int newMinY = minY+dy;
594 final int diffPh = minPy-newMinPy;
604 final int newPw =
size(minPx, maxPx);
605 final int newPh =
size(newMinPy, maxPy);
606 assert patch != null;
607 final int oldPw = patch.length;
608 final int oldPh = patch[0].length;
611 assert newPh > oldPh;
612 assert newPh == oldPh+diffPh;
613 assert newPw == oldPw;
617 patch =
copyPatches(newPw, newPh, 0, diffPh, oldPw, oldPh);
620 final int newMaxY = maxY+dy;
622 final int diffPh = newMaxPy-maxPy;
632 final int newPw =
size(minPx, maxPx);
633 final int newPh =
size(minPy, newMaxPy);
634 assert patch != null;
635 final int oldPw = patch.length;
636 final int oldPh = patch[0].length;
639 assert newPh > oldPh;
640 assert newPh == oldPh+diffPh;
641 assert newPw == oldPw;
645 patch =
copyPatches(newPw, newPh, 0, 0, oldPw, oldPh);
657 private static int size(
final int min,
final int max) {
669 assert Thread.holdsLock(
this);
681 assert Thread.holdsLock(
this);
683 return dirtyMapSquares.contains(mapSquare) ? null : mapSquare;
692 assert Thread.holdsLock(
this);
702 assert Thread.holdsLock(
this);
717 private CfMapPatch[][]
copyPatches(
final int newWidth,
final int newHeight,
final int offsetX,
final int offsetY,
final int height,
final int width) {
718 assert patch != null;
720 for (
int y = 0; y < width; y++) {
721 for (
int x = 0; x < height; x++) {
722 newPatch[offsetX+x][offsetY+y] = patch[x][y];
733 assert Thread.holdsLock(
this);
734 dirtyMapSquares.add(mapSquare);
744 assert Thread.holdsLock(
this);
745 final Integer tmpFaceNum = faceNum;
746 Collection<CfMapSquare> mapSquares = pendingFaceSquares.get(tmpFaceNum);
747 if (mapSquares == null) {
748 mapSquares =
new HashSet<>();
749 pendingFaceSquares.put(tmpFaceNum, mapSquares);
760 assert Thread.holdsLock(
this);
762 dirtyMapSquares.clear();
772 public void updateFace(
final int faceNum,
final int width,
final int height) {
773 for (
int y = 0; y < height; y++) {
774 for (
int x = 0; x < width; x++) {
777 if (face != null && face.
getFaceNum() == faceNum) {
785 final Collection<CfMapSquare> mapSquares = pendingFaceSquares.remove(faceNum);
786 if (mapSquares != null) {
787 dirtyMapSquares.addAll(mapSquares);
799 public boolean processMapScroll(
final int dx,
final int dy,
final int width,
final int height) {
800 if (Math.abs(dx) >= width || Math.abs(dy) >= height) {
802 for (
int y = 0; y < height; y++) {
803 for (
int x = 0; x < width; x++) {
814 for (
int y = 0; y < height; y++) {
822 for (
int y = 0; y < height; y++) {
832 for (
int x = 0; x < width; x++) {
840 for (
int x = 0; x <= width; x++) {
int maxX
The right edge of the defined tiles.
void squarePendingFace(final int x, final int y, final int faceNum)
Marks a CfMapSquare as containing a pending face.
int maxY
The bottom edge of the defined tiles.
CfMapSquare getSquare(final int x, final int y)
Returns one map square.
void setFace(final int x, final int y, final int layer, @Nullable final Face face)
Sets the face of one square.
void setDarkness(final int x, final int y, final int darkness)
Sets the darkness value of one square.
Represents a square in a CfMap.
int oy
Result values for getMapPatch(int, int) and expandTo(int, int).
static final int DEFAULT_DARKNESS
The default darkness value for newly created squares.
Represents a map (as seen by the client).
Face getFace(final int x, final int y, final int layer)
Determines the face of one square.
static final int SIZE
Size of patches in x- and y-direction.
void clearSquare(final int x, final int y)
Clears the content of one square.
void setFace(final int layer, @Nullable final Face face)
Sets the face of a layer.
int getOffsetX()
Returns the offset to convert an absolute x-coordinate of a map square (CfMapSquare#getX() to a relat...
void setHeadMapSquare(final int x, final int y, final int layer, @Nullable final CfMapSquare mapSquare, final boolean setAlways)
Sets the map square containing the head face for a layer.
void setHeadMapSquare(final int x, final int y, final int layer, @Nullable final CfMapSquare mapSquare, final boolean setAlways)
Sets the map square containing the head face for a layer.
int getDarkness(final int x, final int y)
Returns the darkness value of one square.
void scroll(final int dx, final int dy)
Scrolls the map.
void clearSquare(final int x, final int y)
Clears the content of one square.
CfMapSquare getMapSquare(final int x, final int y)
Returns a map square.
Set< CfMapSquare > getDirtyMapSquares()
Returns the dirty map squares.
void dirty(final int x, final int y)
Marks a square as dirty.
CfMapSquare getHeadMapSquare(final int x, final int y, final int layer)
Returns the map square of the head of a multi-square object.
int minY
The top edge of the defined tiles.
Face getFace(final int x, final int y, final int layer)
Determines the face of one square.
final Set< CfMapSquare > dirtyMapSquares
The "dirty" map squares that have been modified.
Manages image information ("faces") needed to display the map view, items, and spell icons...
CfMapSquare getHeadMapSquare(final int x, final int y, final int layer)
Returns the map square of the head of a multi-square object.
CfMapSquare getMapSquareUnlessDirty(final int x, final int y)
Returns a map square.
int NUM_LAYERS
The total number of map layers to display.
void expandFace(final int x, final int y, final int layer, @NotNull final Face face, @NotNull final CfMapSquare oldMapSquare, @Nullable final CfMapSquare newMapSquare)
Adds or removes "head" pointer to/from tail-parts of a face.
boolean processMapScroll(final int dx, final int dy, final int width, final int height)
Processes a map scroll command.
CfMapPatch getMapPatch(final int x, final int y)
Checks if a given position is within the defined map area.
int maxPy
The bottom edge of the defined patches in patch.
void reset(final int mapWidth, final int mapHeight)
Clears the map contents.
void setFaceInternal(final int x, final int y, final int layer, @Nullable final Face face)
Sets the face of one square.
void dirtyFace(final int x, final int y, final int layer, @NotNull final Face face)
Marks one face as "dirty".
static final int DEFAULT_COLOR
The default magic map color for newly created squares.
int FACE_COLOR_MASK
Bitmask in magic map information to extract the color information of a tile.
int ox
Result values for getMapPatch(int, int) and expandTo(int, int).
void updateFace(final int faceNum, final int width, final int height)
Processes an updated face image.
void increase(final int dx, final int dy)
Increases the defined area of the map.
Interface defining constants for the "map2" Crossfire protocol message.
CfMapPatch expandTo(final int x, final int y)
(Possibly) expands the defined area of the map to a given position.
int maxPx
The right edge of the defined patches in patch.
void setMagicMap(final int x0, final int y0, final byte[][] data)
Sets the magic map color of one square.
static final int DEFAULT_SMOOTH
The default smooth value for newly created squares.
int getColor(final int x, final int y)
Determines the magic map color value of one square.
int getDarkness(final int x, final int y)
Determines the darkness value of one square.
static int size(final int min, final int max)
Calculates the number of patches needed to hold tiles between two patch coordinates.
final Map< Integer, Collection< CfMapSquare > > pendingFaceSquares
The map squares containing pending faces.
void squareModified(@NotNull final CfMapSquare mapSquare)
Marks a CfMapSquare as dirty.
boolean isFogOfWar(final int x, final int y)
Determines if a square is not up-to-date.
CfMapPatch [][] copyPatches(final int newWidth, final int newHeight, final int offsetX, final int offsetY, final int height, final int width)
Returns a copy of a rectangular area of patch.
int minPy
The top edge of the defined patches in patch.
int getSmooth(final int x, final int y, final int layer)
Returns the smooth value of one square.
static final Face DEFAULT_FACE
The default face value for newly creates squares.
Represents a square area of CfMapSquares.
CfMapPatch [][] patch
Array of (possibly) defined squares.
int minPx
The left edge of the defined patches in patch.
void dirty(final int x, final int y)
Marks a single square as dirty.
Face getFace(final int layer)
Returns the face of a layer.
int getOffsetY()
Returns the offset to convert an absolute y-coordinate of a map square (CfMapSquare#getY() to a relat...
int patchY
Top edge of viewable area.
Interface defining constants for the "magicmap" Crossfire protocol message.
int patchX
Left edge of viewable area.
int setSmooth(final int x, final int y, final int layer, final int smooth)
Sets the smooth value of one square.
int getFaceNum()
Returns the unique face id.
static final int SIZE_LOG
Log2 of SIZE.
boolean isFogOfWar(final int x, final int y)
Determines if the tile is not up-to-date.
int getSmooth(final int x, final int y, final int layer)
Determines the smooth value of one square.
void setSmooth(final int x, final int y, final int layer, final int smooth)
Sets the smooth value of one square.
int minX
The left edge of the defined tiles.
int getColor(final int x, final int y)
Returns the magic map color value of one square.