Gridarta Editor
MapArchObjectParser.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.var.atrinik.model.io;
21 
22 import java.io.BufferedReader;
23 import java.io.IOException;
24 import java.util.Formatter;
25 import java.util.regex.Matcher;
26 import java.util.regex.Pattern;
32 import net.sf.gridarta.utils.Size2D;
35 import org.jetbrains.annotations.NotNull;
36 import org.jetbrains.annotations.Nullable;
37 
43 public class MapArchObjectParser extends AbstractMapArchObjectParser<MapArchObject> {
44 
49  @NotNull
50  private static final Pattern TILE_PATH_PATTERN = Pattern.compile("(\\d+) (.+)");
51 
55  private int width;
56 
60  private int height;
61 
62  @Override
63  public void load(@NotNull final BufferedReader reader, @NotNull final MapArchObject mapArchObject) throws IOException {
64  width = 0;
65  height = 0;
66  super.load(reader, mapArchObject);
67  mapArchObject.setMapSize(new Size2D(Math.max(1, width), Math.max(1, height)));
68  }
69 
70  @Override
71  public void save(@NotNull final Appendable appendable, @NotNull final MapArchObject mapArchObject, @Nullable final MapFile mapFile) throws IOException {
72  final Formatter format = new Formatter(appendable);
73  appendable.append("arch map\n");
74  if (!mapArchObject.getMapName().isEmpty()) {
75  format.format("name %s\n", mapArchObject.getMapName());
76  }
77  format.format("msg\n%s%sendmsg\n", mapArchObject.getText().trim(), "\n");
78  format.format("width %d\n", mapArchObject.getMapSize().getWidth());
79  format.format("height %d\n", mapArchObject.getMapSize().getHeight());
80  if (mapArchObject.getEnterX() != 0) {
81  format.format("enter_x %d\n", mapArchObject.getEnterX());
82  }
83  if (mapArchObject.getEnterY() != 0) {
84  format.format("enter_y %d\n", mapArchObject.getEnterY());
85  }
86  if (mapArchObject.getResetTimeout() != 0) {
87  format.format("reset_timeout %d\n", mapArchObject.getResetTimeout());
88  }
89  if (mapArchObject.getSwapTime() != 0) {
90  format.format("swap_time %d\n", mapArchObject.getSwapTime());
91  }
92  if (mapArchObject.getDifficulty() != 0) {
93  format.format("difficulty %d\n", mapArchObject.getDifficulty());
94  }
95  if (mapArchObject.getDarkness() != 0) {
96  format.format("darkness %d\n", mapArchObject.getDarkness());
97  }
98  if (mapArchObject.isFixedReset()) {
99  appendable.append("fixed_resettime 1\n");
100  }
101  if (mapArchObject.isOutdoor()) {
102  appendable.append("outdoor 1\n");
103  }
104  if (mapArchObject.isNoSave()) {
105  appendable.append("no_save 1\n");
106  }
107  if (mapArchObject.isNoMagic()) {
108  appendable.append("no_magic 1\n");
109  }
110  if (mapArchObject.isHeightDiff()) {
111  appendable.append("height_diff 1\n");
112  }
113  if (mapArchObject.isNoSummon()) {
114  appendable.append("no_summon 1\n");
115  }
116  if (mapArchObject.isNoHarm()) {
117  appendable.append("no_harm 1\n");
118  }
119  if (mapArchObject.isFixedLogin()) {
120  appendable.append("fixed_login 1\n");
121  }
122  if (mapArchObject.isUnique()) {
123  appendable.append("unique 1\n");
124  }
125  if (mapArchObject.isFixedResetTime()) {
126  appendable.append("fixed_resettime 1\n");
127  }
128  if (mapArchObject.isPlayerNoSave()) {
129  appendable.append("player_no_save 1\n");
130  }
131  if (mapArchObject.isPvp()) {
132  appendable.append("pvp 1\n");
133  }
134  for (final Direction direction : Direction.values()) {
135  if (!mapArchObject.getTilePath(direction).isEmpty() && !mapArchObject.isTilePathAuto(direction, mapFile)) {
136  format.format("tile_path_%d %s\n", direction.ordinal() + 1, mapArchObject.getTilePath(direction));
137  }
138  }
139  if (mapArchObject.getTilesetId() != 0) {
140  format.format("tileset_id %d\n", mapArchObject.getTilesetId());
141  format.format("tileset_x %d\n", mapArchObject.getTilesetX());
142  format.format("tileset_y %d\n", mapArchObject.getTilesetY());
143  }
144  final String backgroundMusic = mapArchObject.getBackgroundMusic();
145  if (!backgroundMusic.isEmpty()) {
146  format.format("bg_music %s\n", backgroundMusic);
147  }
148  final String region = mapArchObject.getRegion();
149  if (!region.isEmpty()) {
150  format.format("region %s\n", region);
151  }
152  final String weather = mapArchObject.getWeather();
153  if (!weather.isEmpty()) {
154  format.format("weather %s\n", weather);
155  }
156  appendable.append("end\n");
157  }
158 
159  @Override
160  protected boolean parseLine(@NotNull final String line, @NotNull final String key, @NotNull final String value, @NotNull final MapArchObject mapArchObject, @NotNull final BufferedReader reader) throws IOException {
161  if (line.equals("msg")) {
162  while (true) {
163  final String msgLine = reader.readLine();
164  if (msgLine == null) {
165  throw new IOException("unexpected end of file in msg...endmsg field");
166  }
167 
168  final String trimmedMsgLine = StringUtils.removeTrailingWhitespace(msgLine);
169 
170  if (trimmedMsgLine.equals("endmsg")) {
171  break;
172  }
173 
174  if (!mapArchObject.getText().isEmpty()) {
175  mapArchObject.addText("\n");
176  }
177  mapArchObject.addText(trimmedMsgLine);
178  }
179  } else if (line.startsWith("tile_path_")) {
180  final Matcher m = TILE_PATH_PATTERN.matcher(line.substring(10));
181  if (!m.matches()) {
182  throw new InvalidMapFormatException("unexpected map attribute: '" + line + "'");
183  }
184 
185  // get tile path
186  try {
187  final int index = Integer.parseInt(m.group(1));
188  if (index > 0 && index <= Direction.values().length) {
189  mapArchObject.setTilePath(Direction.values()[index - 1], m.group(2));
190  } else {
191  throw new InvalidMapFormatException("unexpected map attribute: '" + line + "'");
192  }
193  } catch (final NumberFormatException ex) {
194  throw new InvalidMapFormatException("unexpected map attribute: '" + line + "'", ex);
195  }
196  } else if (line.equals("end")) {
197  return false;
198  } else {
199  switch (key) {
200  case "no_save":
201  mapArchObject.setNoSave(NumberUtils.parseInt(value) != 0);
202  break;
203 
204  case "no_magic":
205  mapArchObject.setNoMagic(NumberUtils.parseInt(value) != 0);
206  break;
207 
208  case "height_diff":
209  mapArchObject.setHeightDiff(NumberUtils.parseInt(value) != 0);
210  break;
211 
212  case "no_summon":
213  mapArchObject.setNoSummon(NumberUtils.parseInt(value) != 0);
214  break;
215 
216  case "no_harm":
217  mapArchObject.setNoHarm(NumberUtils.parseInt(value) != 0);
218  break;
219 
220  case "fixed_login":
221  mapArchObject.setFixedLogin(NumberUtils.parseInt(value) != 0);
222  break;
223 
224  case "unique":
225  mapArchObject.setUnique(NumberUtils.parseInt(value) != 0);
226  break;
227 
228  case "fixed_resettime":
229  mapArchObject.setFixedResetTime(NumberUtils.parseInt(value) != 0);
230  break;
231 
232  case "player_no_save":
233  mapArchObject.setPlayerNoSave(NumberUtils.parseInt(value) != 0);
234  break;
235 
236  case "pvp":
237  mapArchObject.setPvp(NumberUtils.parseInt(value) != 0);
238  break;
239 
240  case "tileset_id":
241  mapArchObject.setTilesetId(NumberUtils.parseInt(value));
242  break;
243 
244  case "tileset_x":
245  mapArchObject.setTilesetX(NumberUtils.parseInt(value));
246  break;
247 
248  case "tileset_y":
249  mapArchObject.setTilesetY(NumberUtils.parseInt(value));
250  break;
251 
252  case "bg_music":
253  mapArchObject.setBackgroundMusic(value);
254  break;
255 
256  case "region":
257  mapArchObject.setRegion(value);
258  break;
259 
260  case "weather":
261  mapArchObject.setWeather(value);
262  break;
263 
264  case "name":
265  mapArchObject.setMapName(value);
266  break;
267 
268  case "width":
269  width = NumberUtils.parseInt(value);
270  break;
271 
272  case "height":
273  height = NumberUtils.parseInt(value);
274  break;
275 
276  case "enter_x":
277  mapArchObject.setEnterX(NumberUtils.parseInt(value));
278  break;
279 
280  case "enter_y":
281  mapArchObject.setEnterY(NumberUtils.parseInt(value));
282  break;
283 
284  case "reset_timeout":
285  mapArchObject.setResetTimeout(NumberUtils.parseInt(value));
286  break;
287 
288  case "swap_time":
289  mapArchObject.setSwapTime(NumberUtils.parseInt(value));
290  break;
291 
292  case "difficulty":
293  mapArchObject.setDifficulty(NumberUtils.parseInt(value));
294  break;
295 
296  case "darkness":
297  mapArchObject.setDarkness(NumberUtils.parseInt(value));
298  break;
299 
300  case "outdoor":
301  mapArchObject.setOutdoor(NumberUtils.parseInt(value) != 0);
302  break;
303 
304  default:
305  throw new InvalidMapFormatException("unexpected map attribute: '" + line + "'");
306  }
307  }
308 
309  return true;
310  }
311 
312 }
net.sf.gridarta.model.direction.Direction
Definition: Direction.java:28
net.sf.gridarta.utils.NumberUtils.parseInt
static int parseInt(@NotNull final String s)
Definition: NumberUtils.java:41
net.sf.gridarta.var.atrinik.model.io.MapArchObjectParser.load
void load(@NotNull final BufferedReader reader, @NotNull final MapArchObject mapArchObject)
Definition: MapArchObjectParser.java:63
net.sf.gridarta
net.sf.gridarta.var.atrinik.model.io.MapArchObjectParser.TILE_PATH_PATTERN
static final Pattern TILE_PATH_PATTERN
Definition: MapArchObjectParser.java:50
net.sf
net.sf.gridarta.model.mapmodel
Definition: AboveFloorInsertionMode.java:20
net.sf.gridarta.var.atrinik.model.io.MapArchObjectParser.parseLine
boolean parseLine(@NotNull final String line, @NotNull final String key, @NotNull final String value, @NotNull final MapArchObject mapArchObject, @NotNull final BufferedReader reader)
Definition: MapArchObjectParser.java:160
net.sf.gridarta.var.atrinik.model.io.MapArchObjectParser.save
void save(@NotNull final Appendable appendable, @NotNull final MapArchObject mapArchObject, @Nullable final MapFile mapFile)
Definition: MapArchObjectParser.java:71
net.sf.gridarta.var
net.sf.gridarta.var.atrinik.model.io.MapArchObjectParser
Definition: MapArchObjectParser.java:43
net.sf.gridarta.utils.StringUtils.removeTrailingWhitespace
static String removeTrailingWhitespace(@NotNull final CharSequence str)
Definition: StringUtils.java:123
net
net.sf.gridarta.var.atrinik.model.maparchobject.MapArchObject
Definition: MapArchObject.java:39
net.sf.gridarta.model.io.AbstractMapArchObjectParser
Definition: AbstractMapArchObjectParser.java:39
net.sf.gridarta.var.atrinik.model.io.MapArchObjectParser.height
int height
Definition: MapArchObjectParser.java:60
net.sf.gridarta.var.atrinik
net.sf.gridarta.model.io.InvalidMapFormatException
Definition: InvalidMapFormatException.java:31
net.sf.gridarta.utils.StringUtils
Definition: StringUtils.java:31
net.sf.gridarta.model.mapmodel.MapFile
Definition: MapFile.java:31
net.sf.gridarta.model.io
Definition: AbstractArchetypeParser.java:20
net.sf.gridarta.var.atrinik.model.maparchobject
Definition: DefaultMapArchObjectFactory.java:20
net.sf.gridarta.model
net.sf.gridarta.var.atrinik.model
net.sf.gridarta.var.atrinik.model.io.MapArchObjectParser.width
int width
Definition: MapArchObjectParser.java:55
net.sf.gridarta.utils.Size2D
Definition: Size2D.java:30
net.sf.gridarta.utils
Definition: ActionBuilderUtils.java:20
net.sf.gridarta.model.direction
Definition: Direction.java:20
net.sf.gridarta.utils.NumberUtils
Definition: NumberUtils.java:28