20 package net.sf.gridarta.model.maparchobject;
22 import java.awt.Point;
24 import java.util.Arrays;
25 import java.util.regex.Matcher;
26 import java.util.regex.Pattern;
33 import org.jetbrains.annotations.NotNull;
34 import org.jetbrains.annotations.Nullable;
76 private static final Pattern
MAP_FILE_NAME_PATTERN = Pattern.compile(
"((?:(?!_(?:[\\d-]+))[\\w_])+)_([\\d-]+)_([\\d-]+)(?:_([\\d-]+))?");
82 private final StringBuilder
msgText =
new StringBuilder();
176 tilePaths =
new String[
Direction.values().length];
177 Arrays.fill(tilePaths,
"");
187 msgText.append(mapArchObject.msgText);
188 mapSize = mapArchObject.mapSize;
189 mapName = mapArchObject.mapName;
190 enterX = mapArchObject.enterX;
191 enterY = mapArchObject.enterY;
192 outdoor = mapArchObject.outdoor;
193 resetTimeout = mapArchObject.resetTimeout;
194 swapTime = mapArchObject.swapTime;
195 difficulty = mapArchObject.difficulty;
196 fixedReset = mapArchObject.fixedReset;
197 darkness = mapArchObject.darkness;
198 tilePaths = mapArchObject.tilePaths.clone();
209 if (this.mapSize.equals(mapSize)) {
216 listener.mapSizeChanged(mapSize);
228 final String trimmedName = name.trim();
229 if (mapName.equals(trimmedName)) {
233 mapName = trimmedName;
244 if (this.enterX == enterX) {
259 if (this.enterY == enterY) {
270 return new Point(enterX, enterY);
280 if (this.outdoor == outdoor) {
295 if (this.resetTimeout == resetTimeout) {
310 if (this.swapTime == swapTime) {
325 if (this.difficulty == difficulty) {
340 if (this.fixedReset == fixedReset) {
355 if (this.darkness == darkness) {
365 return tilePaths.length;
371 return tilePaths[direction.ordinal()];
376 if (tilePaths[direction.ordinal()].equals(tilePath)) {
380 tilePaths[direction.ordinal()] = tilePath;
387 if (mapFile == null) {
391 final MapPath mapPath = mapFile.getMapPath().getRelativeMapPathTo(mapFile.getMapPath());
392 final Matcher m = MAP_FILE_NAME_PATTERN.matcher(mapPath.toString());
397 final int x = Integer.parseInt(m.group(2));
398 final int y = Integer.parseInt(m.group(3));
399 final int z = m.group(4) == null ? 0 : Integer.parseInt(m.group(4));
401 final StringBuilder sb =
new StringBuilder(m.group(1));
402 sb.append(String.format(
"_%d_%d", x + direction.getDx(), y + direction.getDy()));
403 if (z + direction.getDz() != 0) {
404 sb.append(String.format(
"_%d", z + direction.getDz()));
406 return sb.toString();
411 if (mapFile == null) {
416 if (!tilePaths[direction.ordinal()].isEmpty()) {
421 if (path.isEmpty()) {
426 final String realPath = mapsDirectory +
"/" + mapPath +
"/" + path;
427 final File file =
new File(realPath);
429 if (file.exists() && file.isFile()) {
441 public void setState(@NotNull
final A mapArchObject) {
460 public boolean equals(@Nullable
final Object obj) {
464 if (obj == null || obj.getClass() != getClass()) {
468 return mapArchObject.
msgText.toString().equals(msgText.toString()) && mapArchObject.
mapSize.equals(mapSize) && mapArchObject.
mapName.equals(mapName) && mapArchObject.
enterX == enterX && mapArchObject.
enterY == enterY && mapArchObject.
outdoor == outdoor && mapArchObject.
resetTimeout == resetTimeout && mapArchObject.
swapTime == swapTime && mapArchObject.
difficulty == difficulty && mapArchObject.
fixedReset == fixedReset && mapArchObject.
darkness == darkness && Arrays.equals(mapArchObject.
tilePaths, tilePaths);
473 return msgText.hashCode() + mapSize.
hashCode() + mapName.hashCode() + enterX + enterY + (outdoor ? 2 : 0) + resetTimeout + swapTime + difficulty + (fixedReset ? 1 : 0) + darkness + Arrays.hashCode(tilePaths);
478 listenerList.
add(listener);
483 listenerList.
remove(listener);
491 attributeHasChanged =
true;
496 if (transactionDepth == 0) {
497 attributeHasChanged =
false;
498 transactionThread = Thread.currentThread();
502 if (transactionThread != Thread.currentThread()) {
503 throw new IllegalStateException(
"A transaction must only be used by one thread.");
516 if (transactionDepth <= 0) {
517 throw new IllegalStateException(
"Tried to end a transaction but no transaction was open.");
520 assert transactionDepth >= 0;
521 if (transactionDepth == 0) {
523 }
else if (fireEvent && transactionDepth > 0) {
524 if (attributeHasChanged) {
535 transactionDepth = 0;
536 transactionThread = null;
537 if (attributeHasChanged) {
539 attributeHasChanged =
false;
548 listener.mapMetaChanged();
553 public void addText(@NotNull
final String text) {
554 if (text.isEmpty()) {
558 msgText.append(text);
564 if (msgText.toString().equals(text)) {
568 msgText.delete(0, msgText.length());
569 msgText.append(text);
576 return msgText.toString();
581 final String modifiedAttribute = MODIFIED_ATTRIBUTE +
" " + String.format(
"%tF", System.currentTimeMillis()) +
" " + userName;
583 final Matcher matcher = MODIFIED_ATTRIBUTE_PATTERN.matcher(msgText);
584 if (!matcher.find()) {
586 msgText.append(
"\n");
587 msgText.append(modifiedAttribute);
589 }
else if (!matcher.group().equals(modifiedAttribute)) {
591 msgText.replace(matcher.start(), matcher.end(), modifiedAttribute);
598 return pos != null && pos.x >= 0 && pos.y >= 0 && pos.x < mapSize.
getWidth() && pos.y < mapSize.
getHeight();
606 protected abstract A
getThis();
void setSwapTime(final int swapTime)
Sets the swap time (in ticks).
String mapName
The name of this map.
void removeMapArchObjectListener(@NotNull final MapArchObjectListener listener)
Unregisters an event listener.
int transactionDepth
The transaction depth.
Interface for listeners listening on map arch object changes.
boolean attributeHasChanged
Set if any attribute has changed inside the current transaction.
int difficulty
The map difficulty.
abstract A getThis()
Returns this map arch object cast to its real type.
void addMapArchObjectListener(@NotNull final MapArchObjectListener listener)
Registers an event listener.
int getDifficulty()
Returns the map's difficulty.
int resetTimeout
The number of ticks that need to elapse before this map will be reset.
T [] getListeners()
Returns an array of all the listeners.
boolean isOutdoor()
Returns whether the map is an "outdoor" map.
void setResetTimeout(final int resetTimeout)
Sets the reset timeout (in seconds).
boolean isTilePathAuto(@NotNull final Direction direction, @Nullable final MapFile mapFile)
Determines whether a tiled map in the specified direction is automatic tiled path or not...
int getDarkness()
Returns the light / darkness of this map.
int enterY
The y coordinate for entering the map.
Base implementation of MapArchObject that covers similarities between Crossfire maps and Daimonin map...
A MapPath that is absolute, that is, it starts with a "/".
void setMapName(@NotNull final String name)
Sets the map name.
static final Size2D ONE
One size object.
void commitTransaction()
Performs ending a transaction.
Represents a maps directory local map path.
void addText(@NotNull final String text)
Appends 'text' to the map text.
int getTilePaths()
Returns the number of tile paths.
static final Pattern MODIFIED_ATTRIBUTE_PATTERN
The pattern to find the MODIFIED_ATTRIBUTE in the message text.
boolean fixedReset
If nonzero, the map reset time will not be updated when someone enters / exits the map...
boolean isFixedReset()
Returns whether this map uses a fixed reset.
boolean outdoor
If set, this is an outdoor map.
boolean isPointValid(@Nullable final Point pos)
Checks whether the given coordinate is within map bounds.
Base package of all Gridarta classes.
AbstractMapArchObject(@NotNull final AbstractMapArchObject< A > mapArchObject)
Creates a new instance as a copy of another map arch object.
int getEnterY()
Returns the enter y coordinate.
void setEnterY(final int enterY)
Sets the enter y coordinate.
Size2D mapSize
The size of the map reflected by this map arch object.
static final Pattern MAP_FILE_NAME_PATTERN
The pattern used to determine the base map name and its x/y/z coordinates from a filename.
void remove(@NotNull final T listener)
Removes a listener.
void setModified()
Marks this map arch object as changed.
Point getEnter()
Returns the enter coordinates.
void beginTransaction()
Starts a new transaction.
void add(@NotNull final T listener)
Adds a listener.
static final String MAP_NAME_UNNAMED
The name of an unnamed map.
int getWidth()
Returns the width of the area.
static final long serialVersionUID
The serial version UID.
void setOutdoor(final boolean outdoor)
Sets whether the map is an "outdoor" map.
String getText()
Returns the message text.
final EventListenerList2< MapArchObjectListener > listenerList
The registered event listeners.
void setText(final String text)
Sets the map text.
Size2D getMapSize()
Returns the map size.
AbstractMapArchObject()
Creates a new instance.
void setDarkness(final int darkness)
Sets the light / darkness of this map.
String calculateTilePath(@NotNull final Direction direction, @Nullable final MapFile mapFile)
Calculate a single tile path in a particular direction.
void setMapSize(@NotNull final Size2D mapSize)
Sets the map size.
void setDifficulty(final int difficulty)
Sets the map's difficulty.
int swapTime
The number of ticks that must elapse after tha map has not been used before it gets swapped out...
void setEnterX(final int enterX)
Sets the enter x coordinate.
final StringBuilder msgText
The map text.
String getMapName()
Returns the map name.
void setFixedReset(final boolean fixedReset)
Sets whether this map uses a fixed reset.
void calculateTilePaths(@Nullable final MapFile mapFile, @NotNull final File mapsDirectory)
Calculates tiled paths for the map automatically.
Type-safe version of EventListenerList.
void endTransaction()
Ends a transaction.
void setState(@NotNull final A mapArchObject)
Resets the state of this object to the state of the given map arch object.
int enterX
The x coordinate for entering the map.
int getSwapTime()
Returns the swap time (in ticks).
int getResetTimeout()
Returns the reset timeout (in seconds).
static final String MODIFIED_ATTRIBUTE
The prefix for the map attribute that is updated with the last modification timestamp.
final String [] tilePaths
The map tile paths used for map tiling.
void endTransaction(final boolean fireEvent)
Ends a transaction.
int getHeight()
Returns the height of the area.
boolean equals(@Nullable final Object obj)
int getEnterX()
Returns the enter x coordinate.
int darkness
The light / darkness of map (overall).
void setTilePath(@NotNull final Direction direction, @NotNull final String tilePath)
Sets a tile path.
void updateModifiedAttribute(@NotNull final String userName)
Updates the "Modified:" attribute in the message text.
The location of a map file with a map directory.
void fireMetaChangedEvent()
Fires a MapMetaChangedEvent.
Interface for MapArchObjects.
The class Size2D represents a 2d rectangular area.
String getTilePath(@NotNull final Direction direction)
Returns a tile path.
transient Thread transactionThread
The thread that performs the current transaction.