Gridarta Editor
ExitConnectorActions.java
Go to the documentation of this file.
1 /*
2  * Gridarta MMORPG map editor for Crossfire, Daimonin and similar games.
3  * Copyright (C) 2000-2015 The Gridarta Developers.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 
20 package net.sf.gridarta.actions;
21 
22 import java.awt.Point;
23 import java.io.IOException;
39 import org.jetbrains.annotations.NotNull;
40 import org.jetbrains.annotations.Nullable;
41 
47 public class ExitConnectorActions<G extends GameObject<G, A, R>, A extends MapArchObject<A>, R extends Archetype<G, A, R>> {
48 
52  @NotNull
54 
58  @NotNull
60 
64  @NotNull
66 
70  @NotNull
72 
76  @NotNull
78 
82  @NotNull
84 
94  public ExitConnectorActions(@NotNull final ExitConnectorModel exitConnectorModel, @NotNull final ExitMatcher<G, A, R> exitMatcher, @NotNull final ArchetypeSet<G, A, R> archetypeSet, @NotNull final MapManager<G, A, R> mapManager, @NotNull final FileControl<G, A, R> fileControl, @NotNull final InsertionModeSet<G, A, R> insertionModeSet) {
95  this.exitConnectorModel = exitConnectorModel;
96  this.exitMatcher = exitMatcher;
97  this.archetypeSet = archetypeSet;
98  this.mapManager = mapManager;
99  this.fileControl = fileControl;
100  this.insertionModeSet = insertionModeSet;
101  }
102 
110  public boolean doExitCopy(final boolean performAction, @NotNull final MapControl<G, A, R> mapControl, @NotNull final Point location) {
111  final MapModel<G, A, R> mapModel = mapControl.getMapModel();
112  final MapFile mapFile = mapModel.getMapFile();
113  if (mapFile == null) {
114  // unsaved maps do not have a map path ==> no location to remember
115  return false;
116  }
117 
118  if (performAction) {
119  final ExitLocation exitLocation = new ExitLocation(mapFile, location, mapModel.getMapArchObject().getMapName());
120  exitConnectorModel.setExitLocation(exitLocation);
121  }
122 
123  return true;
124  }
125 
133  public boolean doExitPaste(final boolean performAction, @NotNull final MapControl<G, A, R> mapControl, @NotNull final Point targetLocation) {
134  final ExitLocation sourceExitLocation = exitConnectorModel.getExitLocation();
135  if (sourceExitLocation == null) {
136  return false;
137  }
138 
139  final MapModel<G, A, R> targetMapModel = mapControl.getMapModel();
140  @Nullable final BaseObject<G, A, R, ?> targetExit;
141  //XXX final G selectedExit = exitMatcher.getValidExit(selectedSquareModel.getSelectedGameObject());
142  //XXX if (selectedExit != null) {
143  //XXX targetExit = selectedExit;
144  //XXX } else {
145  final BaseObject<G, A, R, ?> cursorExit = exitMatcher.getExit(targetMapModel, targetLocation);
146  if (cursorExit != null) {
147  targetExit = cursorExit;
148  } else if (exitConnectorModel.isAutoCreateExit()) {
149  targetExit = null;
150  } else {
151  return false;
152  }
153 
154  final MapFile targetMapFile = targetMapModel.getMapFile();
155 
156  if (targetExit != null) {
157  // paste into existing exit
158 
159  if (performAction) {
160  pasteExit(targetExit, targetMapModel, sourceExitLocation, targetMapFile);
161  }
162  } else {
163  // paste into newly created exit game object
164 
165  final BaseObject<G, A, R, ?> targetArchetype;
166  try {
167  targetArchetype = archetypeSet.getArchetype(exitConnectorModel.getExitArchetypeName());
168  } catch (final UndefinedArchetypeException ignored) {
169  return false;
170  }
171 
172  if (performAction) {
173  if (!pasteExit(targetLocation, targetMapModel, targetArchetype, sourceExitLocation, targetMapFile)) {
174  return false;
175  }
176  }
177  }
178 
179  return true;
180  }
181 
189  public boolean doExitConnect(final boolean performAction, @NotNull final MapControl<G, A, R> mapControl, @NotNull final Point targetLocation) {
190  final ExitLocation sourceExitLocation = exitConnectorModel.getExitLocation();
191  if (sourceExitLocation == null) {
192  return false;
193  }
194 
195  final MapModel<G, A, R> targetMapModel = mapControl.getMapModel();
196  final MapFile targetMapFile = targetMapModel.getMapFile();
197  if (targetMapFile == null) {
198  // target map file is unsaved ==> no location to connect
199  return false;
200  }
201 
202  @Nullable final BaseObject<G, A, R, ?> targetExit;
203  @Nullable final BaseObject<G, A, R, ?> targetArchetype;
204  //XXX final G selectedExit = exitMatcher.getValidExit(selectedSquareModel.getSelectedGameObject());
205  //XXX if (selectedExit != null) {
206  //XXX targetExit = selectedExit;
207  //XXX targetArchetype = null;
208  //XXX } else {
209  final BaseObject<G, A, R, ?> cursorExit = exitMatcher.getExit(targetMapModel, targetLocation);
210  if (cursorExit != null) {
211  targetExit = cursorExit;
212  targetArchetype = null;
213  } else if (exitConnectorModel.isAutoCreateExit()) {
214  targetExit = null;
215  try {
216  targetArchetype = archetypeSet.getArchetype(exitConnectorModel.getExitArchetypeName());
217  } catch (final UndefinedArchetypeException ignored) {
218  return false;
219  }
220  } else {
221  return false;
222  }
223 
224  final MapControl<G, A, R> sourceMapControl;
225  try {
226  sourceMapControl = mapManager.openMapFile(sourceExitLocation.getMapFile(), false);
227  } catch (final IOException ex) {
228  fileControl.reportLoadError(sourceExitLocation.getMapFile().getFile(), ex.getMessage());
229  return false;
230  }
231  try {
232  return doExitConnect(performAction, targetExit, targetArchetype, targetMapModel, targetLocation, targetMapFile, sourceMapControl.getMapModel(), sourceExitLocation);
233  } finally {
234  try {
235  // XXX: remove hack when MapManager automatically saves released maps
236  if (sourceMapControl.getMapModel().isModified() && sourceMapControl.getUseCounter() <= 1) {
237  try {
238  sourceMapControl.save();
239  } catch (final IOException ex) {
240  fileControl.reportSaveError(sourceMapControl, ex.getMessage());
241  }
242  }
243  } finally {
244  mapManager.release(sourceMapControl);
245  }
246  }
247  }
248 
263  private boolean doExitConnect(final boolean performAction, @Nullable final BaseObject<?, ?, ?, ?> targetExit, @Nullable final BaseObject<G, A, R, ?> targetArchetype, @NotNull final MapModel<G, A, R> targetMapModel, @NotNull final Point targetLocation, @NotNull final MapFile targetMapFile, @NotNull final MapModel<G, A, R> sourceMapModel, @NotNull final ExitLocation sourceExitLocation) {
264  final MapFile sourceMapFile = sourceMapModel.getMapFile();
265  if (sourceMapFile == null) {
266  // source map is unsaved ==> cannot connect
267  return false;
268  }
269 
270  final Point sourceLocation = sourceExitLocation.getMapCoordinate();
271 
272  @Nullable final BaseObject<G, A, R, ?> sourceExit;
273  @Nullable final BaseObject<G, A, R, ?> sourceArchetype;
274  final BaseObject<G, A, R, ?> exit = exitMatcher.getExit(sourceMapModel, sourceLocation);
275  if (exit != null) {
276  sourceExit = exit;
277  sourceArchetype = null;
278  } else if (exitConnectorModel.isAutoCreateExit()) {
279  sourceExit = null;
280  try {
281  sourceArchetype = archetypeSet.getArchetype(exitConnectorModel.getExitArchetypeName());
282  } catch (final UndefinedArchetypeException ignored) {
283  return false;
284  }
285  } else {
286  return false;
287  }
288 
289  if (performAction) {
290  final ExitLocation targetExitLocation = new ExitLocation(targetMapFile, targetLocation, targetMapModel.getMapArchObject().getMapName());
291  if (sourceExit != null) {
292  pasteExit(sourceExit, sourceMapModel, targetExitLocation, sourceMapFile);
293  } else {
294  if (!pasteExit(sourceLocation, sourceMapModel, sourceArchetype, targetExitLocation, sourceMapFile)) {
295  return false;
296  }
297  }
298 
299  if (targetExit != null) {
300  pasteExit(targetExit, targetMapModel, sourceExitLocation, targetMapFile);
301  } else {
302  assert targetArchetype != null;
303  if (!pasteExit(targetLocation, targetMapModel, targetArchetype, sourceExitLocation, targetMapFile)) {
304  return false;
305  }
306  }
307  }
308 
309  return true;
310  }
311 
320  private void pasteExit(@NotNull final BaseObject<?, ?, ?, ?> gameObject, @NotNull final MapModel<G, A, R> mapModel, @NotNull final ExitLocation exitLocation, @Nullable final MapFile gameObjectMapFile) {
321  mapModel.beginTransaction("paste exit");
322  try {
323  exitLocation.updateExitObject(gameObject, exitConnectorModel.isPasteExitName(), gameObjectMapFile);
324  } finally {
325  mapModel.endTransaction();
326  }
327  }
328 
339  private boolean pasteExit(@NotNull final Point location, @NotNull final MapModel<G, A, R> mapModel, @NotNull final BaseObject<G, A, R, ?> archetype, @NotNull final ExitLocation exitLocation, @Nullable final MapFile mapFile) {
340  mapModel.beginTransaction("paste exit");
341  try {
342  final BaseObject<G, A, R, ?> newExit = mapModel.insertBaseObject(archetype, location, true, false, insertionModeSet.getTopmostInsertionMode());
343  if (newExit == null) {
344  return false;
345  }
346 
347  exitLocation.updateExitObject(newExit, exitConnectorModel.isPasteExitName(), mapFile);
348  } finally {
349  mapModel.endTransaction();
350  }
351 
352  return true;
353  }
354 
355 }
void save()
Saves the map to a file.
void reportSaveError(@NotNull MapControl< G, A, R > mapControl, @NotNull String message)
Reports an error while saving a map file to the user.
boolean pasteExit(@NotNull final Point location, @NotNull final MapModel< G, A, R > mapModel, @NotNull final BaseObject< G, A, R, ?> archetype, @NotNull final ExitLocation exitLocation, @Nullable final MapFile mapFile)
Creates a new exit game object.
void setExitLocation(@Nullable ExitLocation exitLocation)
Sets the remembered exit location.
A MapModel reflects the data of a map.
Definition: MapModel.java:75
A MapManager manages all opened maps.
Definition: MapManager.java:37
void release(@NotNull MapControl< G, A, R > mapControl)
Releases a MapControl instance.
G getExit(@NotNull final MapModel< G, A, R > mapModel, @Nullable final Point point)
Returns an exit game object on a given map square.
int getUseCounter()
Returns the use counter.
boolean isModified()
Return whether the map has been modified from the on-disk state.
MapModel< G, A, R > getMapModel()
Returns the map model.
final ExitConnectorModel exitConnectorModel
The ExitConnectorModel to use.
Base package of all Gridarta classes.
boolean isAutoCreateExit()
Returns whether exit game objects should be auto-created when needed.
Reflects a game object (object on a map).
Definition: GameObject.java:36
void reportLoadError(@Nullable File file, @NotNull String message)
R getArchetype(@NotNull String archetypeName)
Returns an Archetype by its name.
boolean doExitConnect(final boolean performAction, @NotNull final MapControl< G, A, R > mapControl, @NotNull final Point targetLocation)
Executes the "exit connect" action.
final MapManager< G, A, R > mapManager
The MapManager for loading maps.
Selects valid exit game objects from maps.
InsertionMode< G, A, R > getTopmostInsertionMode()
Returns the "topmost" insertion mode.
GameObjects are the objects based on Archetypes found on maps.
final FileControl< G, A, R > fileControl
The FileControl to use.
void pasteExit(@NotNull final BaseObject<?, ?, ?, ?> gameObject, @NotNull final MapModel< G, A, R > mapModel, @NotNull final ExitLocation exitLocation, @Nullable final MapFile gameObjectMapFile)
Pastes exit information into an exit game object.
final ExitMatcher< G, A, R > exitMatcher
The ExitMatcher to use.
ExitLocation getExitLocation()
Returns the remembered exit location.
Utility class implementing actions that operate on ExitConnectorModels.
String getExitArchetypeName()
Returns the archetype name when creating exit game objects.
ExitConnectorActions(@NotNull final ExitConnectorModel exitConnectorModel, @NotNull final ExitMatcher< G, A, R > exitMatcher, @NotNull final ArchetypeSet< G, A, R > archetypeSet, @NotNull final MapManager< G, A, R > mapManager, @NotNull final FileControl< G, A, R > fileControl, @NotNull final InsertionModeSet< G, A, R > insertionModeSet)
Creates a new instance.
Stores information needed by the exit connector.
A getMapArchObject()
Returns the Map Arch Object with the meta information about the map.
Stores information about a remembered exit location.
boolean doExitCopy(final boolean performAction, @NotNull final MapControl< G, A, R > mapControl, @NotNull final Point location)
Executes the "exit copy" action.
Currently nothing more than a marker interface for unification.
Definition: MapControl.java:35
boolean isPasteExitName()
Returns whether the exit name should be updated.
MapFile getMapFile()
Returns the map file.
File getFile()
Returns a File for this map file.
Definition: MapFile.java:102
Interface that captures similarities between different ArchetypeSet implementations.
MapFile getMapFile()
Returns the file of the map that contains the remembered exit.
final ArchetypeSet< G, A, R > archetypeSet
The ArchetypeSet to use.
MapControl< G, A, R > openMapFile(@NotNull MapFile mapFile, boolean interactive)
Loads a map file.
boolean doExitPaste(final boolean performAction, @NotNull final MapControl< G, A, R > mapControl, @NotNull final Point targetLocation)
Executes the "exit paste" action.
boolean doExitConnect(final boolean performAction, @Nullable final BaseObject<?, ?, ?, ?> targetExit, @Nullable final BaseObject< G, A, R, ?> targetArchetype, @NotNull final MapModel< G, A, R > targetMapModel, @NotNull final Point targetLocation, @NotNull final MapFile targetMapFile, @NotNull final MapModel< G, A, R > sourceMapModel, @NotNull final ExitLocation sourceExitLocation)
Executes part of the "exit connect" action.
The location of a map file with a map directory.
Definition: MapFile.java:31
final InsertionModeSet< G, A, R > insertionModeSet
The InsertionModeSet to use.