Gridarta Editor
FillUtils.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.model.floodfill;
21 
22 import java.awt.Point;
23 import java.util.Collection;
24 import java.util.HashSet;
25 import java.util.List;
26 import java.util.Set;
36 import org.jetbrains.annotations.NotNull;
37 import org.jetbrains.annotations.Nullable;
38 
43 public class FillUtils {
44 
48  private FillUtils() {
49  }
50 
61  public static <G extends GameObject<G, A, R>, A extends MapArchObject<A>, R extends Archetype<G, A, R>> void fill(@NotNull final MapModel<G, A, R> mapModel, @NotNull final Collection<MapSquare<G, A, R>> selection, @NotNull final InsertionMode<G, A, R> insertionMode, @NotNull final List<? extends BaseObject<G, A, R, ?>> gameObjects, final int density, final boolean noAdjacent) {
62  if (selection.isEmpty()) {
63  return;
64  }
65 
66  if (gameObjects.isEmpty()) {
67  return;
68  }
69 
70  @Nullable final Set<String> archetypeNames;
71  if (noAdjacent) {
72  archetypeNames = new HashSet<>();
73  for (final BaseObject<?, ?, ?, ?> baseObject : gameObjects) {
74  archetypeNames.add(baseObject.getArchetype().getArchetypeName());
75  }
76  } else {
77  archetypeNames = null;
78  }
79 
80  mapModel.beginTransaction("Fill"); // TODO; I18N/L10N
81  try {
82  for (final MapSquare<G, A, R> mapSquare : selection) {
83  if (density != -1 && density != 100 && density < RandomUtils.RND.nextInt(100) + 1) {
84  continue;
85  }
86  final BaseObject<G, A, R, ?> gameObject = gameObjects.get(RandomUtils.RND.nextInt(gameObjects.size()));
87  if (archetypeNames != null) {
88  final Archetype<G, A, R> archetype = gameObject.getArchetype();
89  final int w = archetype.getSizeX();
90  final int h = archetype.getSizeY();
91  if (containsArchetype(mapModel, archetypeNames, mapSquare, w, h)) {
92  continue;
93  }
94  }
95  mapModel.insertBaseObject(gameObject, mapSquare.getMapLocation(), false, false, insertionMode);
96  }
97  } finally {
98  mapModel.endTransaction();
99  }
100  }
101 
112  private static <G extends GameObject<G, A, R>, A extends MapArchObject<A>, R extends Archetype<G, A, R>> boolean containsArchetype(@NotNull final MapModel<G, A, R> mapModel, @NotNull final Collection<String> archetypeNames, @NotNull final MapSquare<G, A, R> topLeftMapSquare, final int w, final int h) {
113  final Point pos = new Point();
114  for (int dy = -1; dy < h + 1; dy++) {
115  for (int dx = -1; dx < w + 1; dx++) {
116  topLeftMapSquare.getMapLocation(pos, dx, dy);
117  final MapSquare<G, A, R> mapSquare;
118  try {
119  mapSquare = mapModel.getMapSquare(pos);
120  } catch (final IndexOutOfBoundsException ignored) {
121  continue;
122  }
123 
124  for (final GameObject<G, A, R> gameObject : mapSquare) {
125  if (archetypeNames.contains(gameObject.getHead().getArchetype().getArchetypeName())) {
126  return true;
127  }
128  }
129  }
130  }
131  return false;
132  }
133 
141  public static <G extends GameObject<G, A, R>, A extends MapArchObject<A>, R extends Archetype<G, A, R>> void floodFill(@NotNull final MapModel<G, A, R> mapModel, @NotNull final Point start, @NotNull final List<? extends BaseObject<G, A, R, ?>> gameObjects, @NotNull final InsertionModeSet<G, A, R> insertionModeSet) {
142  if (gameObjects.isEmpty()) {
143  return;
144  }
145 
146  if (!mapModel.getMapArchObject().isPointValid(start) || !mapModel.getMapSquare(start).isEmpty()) {
147  return;
148  }
149 
150  mapModel.beginTransaction("Flood-fill"); // TODO: I18N/L10N
151  try {
152  new FloodFill<G, A, R>().floodFill(mapModel, start, gameObjects, insertionModeSet);
153  } finally {
154  mapModel.endTransaction();
155  }
156  }
157 
158 }
A MapModel reflects the data of a map.
Definition: MapModel.java:75
Random number utilities.
FillUtils()
Private constructor to prevent instantiation.
Definition: FillUtils.java:48
int getSizeY()
Determines the vertical extent in squares.
Base package of all Gridarta classes.
Reflects a game object (object on a map).
Definition: GameObject.java:36
int getSizeX()
Determines the horizontal extent in squares.
GameObjects are the objects based on Archetypes found on maps.
static final Random RND
Global random number generator.
Point getMapLocation()
Returns the coordinate of this GameObject on its map.
R getArchetype()
Returns the Archetype this GameObject is based on.
Utility class implementing fill operations on map instances.
Definition: FillUtils.java:43