1 package games.stendhal.server.entity.mapstuff.area;
2 
3 import org.apache.log4j.Logger;
4 
5 import marauroa.common.game.Definition.Type;
6 import marauroa.common.game.RPClass;
7 
8 /**
9  * an area which consists of tiled images
10  *
11  * @author hendrik
12  */
13 public class TiledArea extends AreaEntity {
14 	private static Logger logger = Logger.getLogger(TiledArea.class	);
15 
16 	private static final String ATTR_TILESET_NAMES = "tileset_names";
17 	private static final String ATTR_TILESET_INDEX = "tileset_index";
18 	private static final String ATTR_TILE_DATA = "tile_data";
19 	private int[] tilesetRef;
20 	private int[] data;
21 
22 	/**
23 	 * Define the RPClass.
24 	 *
25 	 * @return The configured RPClass.
26 	 */
createRPClass()27 	public static RPClass createRPClass() {
28 		final RPClass rpclass = new RPClass("tiled_entity");
29 		rpclass.isA("area");
30 		rpclass.addAttribute(ATTR_TILESET_NAMES, Type.LONG_STRING);
31 		rpclass.addAttribute(ATTR_TILESET_INDEX, Type.LONG_STRING);
32 		rpclass.addAttribute(ATTR_TILE_DATA, Type.LONG_STRING);
33 		return rpclass;
34 	}
35 
36 	/**
37 	 * sets the tile names
38 	 *
39 	 * @param names comma separated list of tileset names
40 	 */
setTilesetNames(String names)41 	public void setTilesetNames(String names) {
42 		put(ATTR_TILESET_NAMES, names);
43 		notifyWorldAboutChanges();
44 	}
45 
46 	@Override
setSize(int width, int height)47 	public void setSize(int width, int height) {
48 		super.setSize(width, height);
49 		initDataArrays();
50 	}
51 
52 	/**
53 	 * sets the data for the specified coordinate
54 	 *
55 	 * @param x x-coordinate
56 	 * @param y y-coordinate
57 	 * @param tileset tileset index within the tileset names list
58 	 */
setTilesetIndex(int x, int y, int tileset)59 	public void setTilesetIndex(int x, int y, int tileset) {
60 		int index = x + y * (int) super.getWidth();
61 		if (index >= data.length) {
62 			logger.error("Index out of bounds: " + x + ", " + y, new Throwable());
63 			return;
64 		}
65 		tilesetRef[index] = tileset;
66 		put(ATTR_TILESET_INDEX, arrayToString(tilesetRef));
67 	}
68 
69 	/**
70 	 * sets the data for the specified coordinate
71 	 *
72 	 * @param x x-coordinate
73 	 * @param y y-coordinate
74 	 * @param offset offset within the tileset
75 	 */
setData(int x, int y, int offset)76 	public void setData(int x, int y, int offset) {
77 		int index = x + y * (int) super.getWidth();
78 		if (index >= data.length) {
79 			logger.error("Index out of bounds: " + x + ", " + y, new Throwable());
80 			return;
81 		}
82 		data[index] = offset;
83 		put(ATTR_TILE_DATA, arrayToString(data));
84 	}
85 
86 	/**
87 	 * converts an array into a string
88 	 *
89 	 * @param array array to convert
90 	 * @return String
91 	 */
arrayToString(int[] array)92 	private static String arrayToString(int[] array) {
93 		StringBuilder sb = new StringBuilder();
94 		boolean first = true;
95 		for (int i : array) {
96 			if (first) {
97 				first = false;
98 			} else {
99 				sb.append(" ");
100 			}
101 			sb.append(i);
102 		}
103 		return sb.toString();
104 	}
105 
106 	/**
107 	 * Initializes the data arrays based on the size of the entity.
108 	 */
initDataArrays()109 	private void initDataArrays() {
110 		int size = (int) (super.getWidth() * super.getHeight());
111 		tilesetRef = new int[size];
112 		data = new int[size];
113 		for (int i = 0; i < size; i++) {
114 			tilesetRef[i] = 0;
115 			data[i] = -1;
116 		}
117 	}
118 }
119