Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.
 
 
 

400 righe
9.6 KiB

  1. let objects = require('../objects/objects');
  2. let physics = require('./physics');
  3. let spawners = require('./spawners');
  4. let resourceSpawner = require('./resourceSpawner');
  5. let globalZone = require('../config/zoneBase');
  6. let randomMap = require('./randomMap');
  7. let events = require('../misc/events');
  8. let mapFile = null;
  9. let mapScale = null;
  10. let padding = null;
  11. let ex = require('extend');
  12. module.exports = {
  13. name: null,
  14. layers: [],
  15. mapFile: null,
  16. size: {
  17. w: 0,
  18. h: 0
  19. },
  20. instanced: false,
  21. custom: null,
  22. collisionMap: null,
  23. clientMap: null,
  24. oldLayers: {
  25. tiles: null,
  26. walls: null,
  27. doodads: null
  28. },
  29. objBlueprints: [],
  30. spawn: {
  31. x: 0,
  32. y: 0
  33. },
  34. rooms: [],
  35. hiddenRooms: [],
  36. hiddenWalls: null,
  37. hiddenTiles: null,
  38. zone: null,
  39. init: function (args) {
  40. this.name = args.name;
  41. try {
  42. this.zone = require('../config/maps/' + this.name + '/zone');
  43. } catch (e) {
  44. this.zone = globalZone;
  45. }
  46. events.emit('onAfterGetZone', this.name, this.zone);
  47. let chats = null;
  48. try {
  49. chats = require('../config/maps/' + this.name + '/chats');
  50. } catch (e) {}
  51. if (chats)
  52. this.zone.chats = chats;
  53. let dialogues = null;
  54. try {
  55. dialogues = require('../config/maps/' + this.name + '/dialogues');
  56. } catch (e) {}
  57. events.emit('onBeforeGetDialogue', this.name, dialogues);
  58. if (dialogues)
  59. this.zone.dialogues = dialogues;
  60. this.zone = extend({}, globalZone, this.zone);
  61. let resources = this.zone.resources || {};
  62. for (let r in resources)
  63. resourceSpawner.register(r, resources[r]);
  64. mapFile = require('../config/maps/' + this.name + '/map');
  65. this.mapFile = mapFile;
  66. this.mapFile.properties = this.mapFile.properties || {};
  67. mapScale = mapFile.tilesets[0].tileheight;
  68. this.custom = mapFile.properties.custom;
  69. if (mapFile.properties.spawn) {
  70. this.spawn = JSON.parse(mapFile.properties.spawn);
  71. if (!this.spawn.push)
  72. this.spawn = [this.spawn];
  73. }
  74. },
  75. create: function () {
  76. this.getMapFile();
  77. this.clientMap = {
  78. zoneId: -1,
  79. map: this.layers,
  80. hiddenWalls: this.hiddenWalls,
  81. hiddenTiles: this.hiddenTiles,
  82. collisionMap: this.collisionMap,
  83. clientObjects: this.objBlueprints,
  84. padding: padding,
  85. hiddenRooms: this.hiddenRooms
  86. };
  87. },
  88. getMapFile: function () {
  89. this.build();
  90. randomMap = extend({}, randomMap);
  91. this.oldMap = this.layers;
  92. randomMap.templates = extend([], this.rooms);
  93. randomMap.generateMappings(this);
  94. for (let i = 0; i < this.size.w; i++) {
  95. let row = this.layers[i];
  96. for (let j = 0; j < this.size.h; j++) {
  97. let cell = row[j];
  98. if (!cell)
  99. continue;
  100. cell = cell.split(',');
  101. let cLen = cell.length;
  102. let newCell = '';
  103. for (let k = 0; k < cLen; k++) {
  104. let c = cell[k];
  105. let newC = randomMap.randomizeTile(c);
  106. newCell += newC;
  107. //Wall?
  108. if ((c >= 160) && (c <= 352) && (newC === 0))
  109. this.collisionMap[i][j] = 0;
  110. if (k < cLen - 1)
  111. newCell += ',';
  112. }
  113. if (this.hiddenWalls[i][j])
  114. this.hiddenWalls[i][j] = randomMap.randomizeTile(this.hiddenWalls[i][j]);
  115. if (this.hiddenTiles[i][j])
  116. this.hiddenTiles[i][j] = randomMap.randomizeTile(this.hiddenTiles[i][j]);
  117. row[j] = newCell;
  118. }
  119. }
  120. randomMap.templates
  121. .filter(r => r.properties.mapping)
  122. .forEach(function (m) {
  123. let x = m.x;
  124. let y = m.y;
  125. let w = m.width;
  126. let h = m.height;
  127. for (let i = x; i < x + w; i++) {
  128. let row = this.layers[i];
  129. for (let j = y; j < y + h; j++)
  130. row[j] = '';
  131. }
  132. }, this);
  133. physics.init(this.collisionMap);
  134. padding = mapFile.properties.padding;
  135. mapFile = null;
  136. _.log('(M ' + this.name + '): Ready');
  137. },
  138. build: function () {
  139. this.size.w = mapFile.width;
  140. this.size.h = mapFile.height;
  141. this.layers = _.get2dArray(this.size.w, this.size.h, null);
  142. this.hiddenWalls = _.get2dArray(this.size.w, this.size.h, null);
  143. this.hiddenTiles = _.get2dArray(this.size.w, this.size.h, null);
  144. this.oldLayers.tiles = _.get2dArray(this.size.w, this.size.h, 0);
  145. this.oldLayers.walls = _.get2dArray(this.size.w, this.size.h, 0);
  146. this.oldLayers.objects = _.get2dArray(this.size.w, this.size.h, 0);
  147. let builders = {
  148. tile: this.builders.tile.bind(this),
  149. object: this.builders.object.bind(this)
  150. };
  151. this.collisionMap = _.get2dArray(this.size.w, this.size.h);
  152. //Rooms need to be ahead of exits
  153. mapFile.layers.rooms = (mapFile.layers.rooms || [])
  154. .sort(function (a, b) {
  155. if ((a.exit) && (!b.exit))
  156. return 1;
  157. return 0;
  158. });
  159. for (let i = 0; i < mapFile.layers.length; i++) {
  160. let layer = mapFile.layers[i];
  161. let layerName = layer.name;
  162. if (!layer.visible)
  163. continue;
  164. let data = layer.data || layer.objects;
  165. let firstItem = data[0];
  166. if (firstItem && firstItem.width) {
  167. let info = {
  168. map: this.name,
  169. layer: layerName,
  170. objects: data
  171. };
  172. events.emit('onAfterGetLayerObjects', info);
  173. }
  174. let len = data.length;
  175. for (let j = 0; j < len; j++) {
  176. let cell = data[j];
  177. if ((cell.gid) || (cell.id))
  178. builders.object(layerName, cell, j);
  179. else {
  180. let y = ~~(j / this.size.w);
  181. let x = j - (y * this.size.w);
  182. let info = {
  183. map: this.name,
  184. layer: layerName,
  185. cell: cell,
  186. x: x,
  187. y: y
  188. };
  189. events.emit('onBeforeBuildLayerTile', info);
  190. builders.tile(layerName, info.cell, j);
  191. }
  192. }
  193. }
  194. },
  195. builders: {
  196. getCellInfo: function (cell) {
  197. let flipX = null;
  198. if ((cell ^ 0x80000000) > 0) {
  199. flipX = true;
  200. cell = cell ^ 0x80000000;
  201. }
  202. let firstGid = 0;
  203. let sheetName = null;
  204. for (let s = 0; s < mapFile.tilesets.length; s++) {
  205. let tileset = mapFile.tilesets[s];
  206. if (tileset.firstgid <= cell) {
  207. sheetName = tileset.name;
  208. firstGid = tileset.firstgid;
  209. }
  210. }
  211. cell = cell - firstGid + 1;
  212. return {
  213. sheetName: sheetName,
  214. cell: cell,
  215. flipX: flipX
  216. };
  217. },
  218. tile: function (layerName, cell, i) {
  219. let y = ~~(i / this.size.w);
  220. let x = i - (y * this.size.w);
  221. if (cell === 0) {
  222. if (layerName === 'tiles')
  223. this.collisionMap[x][y] = 1;
  224. return;
  225. }
  226. let cellInfo = this.builders.getCellInfo(cell);
  227. let sheetName = cellInfo.sheetName;
  228. cell = cellInfo.cell;
  229. if (sheetName === 'walls')
  230. cell += 192;
  231. else if (sheetName === 'objects')
  232. cell += 448;
  233. if ((layerName !== 'hiddenWalls') && (layerName !== 'hiddenTiles')) {
  234. let layer = this.layers;
  235. if (this.oldLayers[layerName])
  236. this.oldLayers[layerName][x][y] = cell;
  237. layer[x][y] = (layer[x][y] === null) ? cell : layer[x][y] + ',' + cell;
  238. } else if (layerName === 'hiddenWalls')
  239. this.hiddenWalls[x][y] = cell;
  240. else if (layerName === 'hiddenTiles')
  241. this.hiddenTiles[x][y] = cell;
  242. if (layerName.indexOf('walls') > -1)
  243. this.collisionMap[x][y] = 1;
  244. else if (sheetName.toLowerCase().indexOf('tiles') > -1) {
  245. //Check for water and water-like tiles
  246. if ([6, 7, 54, 55, 62, 63, 154, 189, 190].indexOf(cell) > -1)
  247. this.collisionMap[x][y] = 1;
  248. }
  249. },
  250. object: function (layerName, cell) {
  251. let clientObj = (layerName === 'clientObjects');
  252. let cellInfo = this.builders.getCellInfo(cell.gid);
  253. let name = (cell.name || '');
  254. let objZoneName = name;
  255. if (name.indexOf('|') > -1) {
  256. let split = name.split('|');
  257. name = split[0];
  258. objZoneName = split[1];
  259. }
  260. let blueprint = {
  261. clientObj: clientObj,
  262. sheetName: cellInfo.sheetName,
  263. cell: cellInfo.cell - 1,
  264. x: cell.x / mapScale,
  265. y: (cell.y / mapScale) - 1,
  266. name: name,
  267. properties: cell.properties || {}
  268. };
  269. if (objZoneName !== name)
  270. blueprint.objZoneName = objZoneName;
  271. if (this.zone) {
  272. if ((this.zone.objects) && (this.zone.objects[objZoneName.toLowerCase()]))
  273. extend(blueprint, this.zone.objects[objZoneName.toLowerCase()]);
  274. else if ((this.zone.objects) && (this.zone.mobs[objZoneName.toLowerCase()]))
  275. extend(blueprint, this.zone.mobs[objZoneName.toLowerCase()]);
  276. }
  277. if (blueprint.blocking)
  278. this.collisionMap[blueprint.x][blueprint.y] = 1;
  279. if ((blueprint.properties.cpnNotice) || (blueprint.properties.cpnLightPatch) || (layerName === 'rooms') || (layerName === 'hiddenRooms')) {
  280. blueprint.y++;
  281. blueprint.width = cell.width / mapScale;
  282. blueprint.height = cell.height / mapScale;
  283. } else if (cell.width === 24)
  284. blueprint.x++;
  285. if (layerName === 'rooms') {
  286. if (blueprint.properties.exit) {
  287. let room = this.rooms.find(function (r) {
  288. return (!(
  289. (blueprint.x + blueprint.width < r.x) ||
  290. (blueprint.y + blueprint.height < r.y) ||
  291. (blueprint.x >= r.x + r.width) ||
  292. (blueprint.y >= r.y + r.height)
  293. ));
  294. });
  295. room.exits.push(blueprint);
  296. } else if (blueprint.properties.resource)
  297. resourceSpawner.register(blueprint.properties.resource, blueprint);
  298. else {
  299. blueprint.exits = [];
  300. blueprint.objects = [];
  301. this.rooms.push(blueprint);
  302. }
  303. } else if (layerName === 'hiddenRooms')
  304. this.hiddenRooms.push(blueprint);
  305. else if (!clientObj) {
  306. if (!mapFile.properties.isRandom)
  307. spawners.register(blueprint, blueprint.spawnCd || mapFile.properties.spawnCd);
  308. else {
  309. let room = this.rooms.find(function (r) {
  310. return (!(
  311. (blueprint.x < r.x) ||
  312. (blueprint.y < r.y) ||
  313. (blueprint.x >= r.x + r.width) ||
  314. (blueprint.y >= r.y + r.height)
  315. ));
  316. });
  317. room.objects.push(blueprint);
  318. }
  319. } else {
  320. let obj = objects.buildObjects([blueprint], true).getSimple(true);
  321. this.objBlueprints.push(obj);
  322. }
  323. }
  324. },
  325. getSpawnPos: function (obj) {
  326. let stats = obj.components.find(c => (c.type === 'stats'));
  327. let level = stats.values.level;
  328. let spawns = this.spawn.filter(s => (((s.maxLevel) && (s.maxLevel >= level)) || (!s.maxLevel)));
  329. return spawns[0];
  330. }
  331. };