Browse Source

initial commit

1870-zone-sprite-atlas
Shaun 2 years ago
parent
commit
0fccff867d
42 changed files with 1126 additions and 354 deletions
  1. +1
    -0
      .gitignore
  2. +65
    -55
      src/client/js/rendering/renderer.js
  3. +27
    -0
      src/client/js/rendering/textures.js
  4. +14
    -17
      src/client/js/rendering/tileOpacity.js
  5. +1
    -1
      src/server/components/aggro.js
  6. +1
    -1
      src/server/components/chest.js
  7. +2
    -2
      src/server/components/effects.js
  8. +10
    -10
      src/server/components/equipment.js
  9. +2
    -2
      src/server/components/gatherer.js
  10. +9
    -9
      src/server/components/inventory.js
  11. +3
    -3
      src/server/components/inventory/getItem.js
  12. +1
    -1
      src/server/components/inventory/useItem.js
  13. +1
    -1
      src/server/components/sound.js
  14. +5
    -5
      src/server/components/spellbook.js
  15. +2
    -2
      src/server/components/stats.js
  16. +1
    -1
      src/server/components/syncer.js
  17. +2
    -2
      src/server/components/trade.js
  18. +1
    -1
      src/server/components/wardrobe.js
  19. +2
    -2
      src/server/components/workbench.js
  20. +2
    -2
      src/server/components/workbench/buildNeedItems.js
  21. +6
    -27
      src/server/config/clientConfig.js
  22. +1
    -1
      src/server/config/quests/templates/questKillX.js
  23. +1
    -1
      src/server/config/serverConfig.js
  24. +1
    -1
      src/server/config/spells/spellTemplate.js
  25. +1
    -1
      src/server/events/events.js
  26. +1
    -1
      src/server/items/generators/quality.js
  27. +1
    -1
      src/server/items/salvager.js
  28. +1
    -1
      src/server/misc/helpers.js
  29. +1
    -3
      src/server/mods/class-necromancer/index.js
  30. +0
    -5
      src/server/mods/feature-cards/index.js
  31. +2
    -2
      src/server/objects/objBase.js
  32. +579
    -0
      src/server/package-lock.json
  33. +1
    -0
      src/server/package.json
  34. +2
    -2
      src/server/security/connections.js
  35. +18
    -14
      src/server/world/instancer.js
  36. +21
    -173
      src/server/world/map.js
  37. +157
    -0
      src/server/world/map/builders/object.js
  38. +42
    -0
      src/server/world/map/builders/tile.js
  39. +17
    -0
      src/server/world/map/getObjectifiedProperties.js
  40. +2
    -2
      src/server/world/mobBuilder.js
  41. +117
    -0
      src/server/world/spriteBuilder/index.js
  42. +2
    -2
      src/server/world/worker.js

+ 1
- 0
.gitignore View File

@@ -1,5 +1,6 @@
node_modules
package-lock.json
src/client/images/temp

storage.db
*.sublime-project


+ 65
- 55
src/client/js/rendering/renderer.js View File

@@ -9,7 +9,8 @@ define([
'js/rendering/spritePool',
'js/system/globals',
'js/rendering/renderLoginBackground',
'js/rendering/helpers/resetRenderer'
'js/rendering/helpers/resetRenderer',
'js/rendering/textures'
], function (
resources,
events,
@@ -21,7 +22,8 @@ define([
spritePool,
globals,
renderLoginBackground,
resetRenderer
resetRenderer,
textures
) {
const mRandom = Math.random.bind(Math);

@@ -120,6 +122,7 @@ define([
textureList.forEach(t => {
this.textures[t] = new PIXI.BaseTexture(sprites[t]);
this.textures[t].scaleMode = PIXI.SCALE_MODES.NEAREST;
this.textures[t].size = this.textures[t].width / 8;
});

particleLayers.forEach(p => {
@@ -132,39 +135,6 @@ define([

particleEngines[p] = engine;
});

this.buildSpritesTexture();
},

buildSpritesTexture: function () {
const { clientConfig: { atlasTextureDimensions, atlasTextures } } = globals;

let container = new PIXI.Container();

let totalHeight = 0;
atlasTextures.forEach(t => {
let texture = this.textures[t];
let tile = new PIXI.Sprite(new PIXI.Texture(texture));
tile.width = texture.width;
tile.height = texture.height;
tile.x = 0;
tile.y = totalHeight;

atlasTextureDimensions[t] = {
w: texture.width / 8,
h: texture.height / 8
};

container.addChild(tile);

totalHeight += tile.height;
});

let renderTexture = PIXI.RenderTexture.create(this.textures.tiles.width, totalHeight);
this.renderer.render(container, renderTexture);

this.textures.sprites = renderTexture;
this.textures.scaleMult = PIXI.SCALE_MODES.NEAREST;
},

toggleScreen: function () {
@@ -184,7 +154,7 @@ define([
buildTitleScreen: function () {
this.titleScreen = true;

renderLoginBackground(this);
//renderLoginBackground(this);
},

onResize: function () {
@@ -213,22 +183,28 @@ define([
events.emit('onResize');
},

getTexture: function (baseTex, cell, size) {
size = size || 8;
let textureName = baseTex + '_' + cell;
getTexture: function (baseTex, cell) {
try {
let textureName = baseTex + '_' + cell;

let textureCache = this.textureCache;
let textureCache = this.textureCache;

let cached = textureCache[textureName];
let cached = textureCache[textureName];

if (!cached) {
let y = ~~(cell / 8);
let x = cell - (y * 8);
cached = new PIXI.Texture(this.textures[baseTex], new PIXI.Rectangle(x * size, y * size, size, size));
textureCache[textureName] = cached;
}
if (!cached) {
let y = ~~(cell / 8);
let x = cell - (y * 8);
const texture = this.textures[baseTex];
const size = texture.size;

return cached;
cached = new PIXI.Texture(texture, new PIXI.Rectangle(x * size, y * size, size, size));
textureCache[textureName] = cached;
}

return cached;
} catch (e) {
console.log(e, baseTex, cell);
}
},

clean: function () {
@@ -240,7 +216,7 @@ define([
let container = this.layers.tileSprites;
this.stage.removeChild(container);

this.layers.tileSprites = container = new PIXI.Container();
this.layers.tileSprites = container = new PIXI.ParticleContainer(30000);
container.layer = 'tiles';
this.stage.addChild(container);

@@ -255,6 +231,8 @@ define([
return 1;
return 0;
});

this.textureCache = {};
},

buildTile: function (c, i, j) {
@@ -277,7 +255,23 @@ define([
return tile;
},

onGetMap: function (msg) {
onGetMap: async function (msg) {
tileOpacity.initMap(msg);

//Load sprite atlas
let spriteAtlas = null;
await new Promise(res => {
spriteAtlas = new Image();
spriteAtlas.onload = res;
spriteAtlas.src = msg.spriteAtlasPath;
});

//Build sprite texture
this.textures.sprites = new PIXI.BaseTexture(spriteAtlas);
this.textures.sprites.scaleMode = PIXI.SCALE_MODES.NEAREST;
this.textures.sprites.size = 8;

//Misc
this.titleScreen = false;
physics.init(msg.collisionMap);

@@ -793,20 +787,36 @@ define([
particleEngine.destroyEmitter(emitter);
},

setSprite: function (obj) {
loadTexture: async function (textureName, texturePath) {
texturePath = texturePath ?? textureName;

if (!texturePath.includes('.png'))
texturePath = `images/${texturePath}.png`;

const image = await textures.getLoader(texturePath);

//Build sprite texture
this.textures[textureName] = new PIXI.BaseTexture(image);
this.textures[textureName].scaleMode = PIXI.SCALE_MODES.NEAREST;
this.textures[textureName].size = this.textures[textureName].width / 8;
},

setSprite: async function (obj) {
const { sprite, sheetName, cell } = obj;

const bigSheets = globals.clientConfig.bigTextures;
const isBigSheet = bigSheets.includes(sheetName);
const textureExists = this.textures.hasOwnProperty(sheetName);
if (!textureExists)
await this.loadTexture(sheetName);

sprite.texture = this.getTexture(sheetName, cell);

const newSize = isBigSheet ? 24 : 8;
const newSize = sprite.texture.width;

obj.w = newSize * scaleMult;
obj.h = obj.w;

sprite.width = obj.w;
sprite.height = obj.h;
sprite.texture = this.getTexture(sheetName, cell, newSize);

if (newSize !== sprite.size) {
sprite.size = newSize;


+ 27
- 0
src/client/js/rendering/textures.js View File

@@ -0,0 +1,27 @@
define([
], function (
) {
const loaders = {};

return {
getLoader: async path => {
if (loaders[path])
return loaders[path];

loaders[path] = new Promise(async resOuter => {
let image = null;
await new Promise(resInner => {
image = new Image();
image.onload = resInner;
image.src = path;
});

resOuter(image);
});

return loaders[path];
}
};
});

+ 14
- 17
src/client/js/rendering/tileOpacity.js View File

@@ -3,7 +3,15 @@ define([
], function (
globals
) {
let noFlipTiles = null;
let tileOpacities = null;

return {
initMap: function (msg) {
noFlipTiles = msg.noFlipTiles;
tileOpacities = msg.tileOpacities;
},

getSheetNum: function (tile) {
if (tile < 224)
return 0;
@@ -47,15 +55,13 @@ define([
},

map: function (tile) {
const { clientConfig: { tileOpacities } } = globals;

const { offset, sheetName } = this.getOffsetAndSheet(tile);
const mappedTile = tile - offset;
if (tileOpacities[tile] === undefined)
return 1;

const opacityConfig = tileOpacities[sheetName] || tileOpacities.default;
const { max, opacity } = tileOpacities[tile];

let alpha = (opacityConfig[mappedTile] || opacityConfig.default);
if (opacityConfig.max !== null) {
let alpha = opacity;
if (max !== undefined) {
alpha = alpha + (Math.random() * (alpha * 0.2));
alpha = Math.min(1, alpha);
}
@@ -64,16 +70,7 @@ define([
},

canFlip: function (tile) {
const { clientConfig: { tilesNoFlip } } = globals;

const { offset, sheetName } = this.getOffsetAndSheet(tile);
const mappedTile = tile - offset;

const noFlipTiles = tilesNoFlip[sheetName];
if (!noFlipTiles)
return true;

return !noFlipTiles.includes(mappedTile);
return !noFlipTiles.includes(tile + 1);
}
};
});

+ 1
- 1
src/server/components/aggro.js View File

@@ -31,7 +31,7 @@ module.exports = {
this.faction = blueprint.faction;

//TODO: Why don't we move if faction is null?
if (!this.has('faction'))
if (!this.isDefined('faction'))
return;

if (this.physics.width > 0)


+ 1
- 1
src/server/components/chest.js View File

@@ -6,7 +6,7 @@ module.exports = {
ttl: -1,

init: function (blueprint) {
if (blueprint.has('ownerName'))
if (blueprint.isDefined('ownerName'))
this.ownerName = blueprint.ownerName;

if (blueprint.ttl)


+ 2
- 2
src/server/components/effects.js View File

@@ -126,7 +126,7 @@ module.exports = {
},

canApplyEffect: function (type) {
if (!this.ccResistances.has(type))
if (!this.ccResistances.isDefined(type))
return true;

let ccResistances = this.ccResistances;
@@ -138,7 +138,7 @@ module.exports = {

addEffect: function (options, source) {
//Skip 0-duration effects
if ((options.has('ttl')) && (options.ttl === 0))
if ((options.isDefined('ttl')) && (options.ttl === 0))
return;

options.caster = options.caster || source;


+ 10
- 10
src/server/components/equipment.js View File

@@ -29,7 +29,7 @@ module.exports = {
},

isSlotEmpty: function (slot) {
return !this.eq.has(slot);
return !this.eq.isDefined(slot);
},

autoEquip: function (itemId) {
@@ -44,7 +44,7 @@ module.exports = {
return;
}

if (!this.eq.has(item.slot)) {
if (!this.eq.isDefined(item.slot)) {
this.equip(itemId);
return true;
}
@@ -71,12 +71,12 @@ module.exports = {
if (!slot)
slot = item.equipSlot || item.slot;
if (slot === 'twoHanded') {
if (this.eq.has('offHand'))
if (this.eq.isDefined('offHand'))
this.unequip(this.eq.offHand, true);

slot = 'oneHanded';
} else if (slot === 'offHand') {
if (this.eq.has('oneHanded')) {
if (this.eq.isDefined('oneHanded')) {
let oneHandedEq = inventory.findItem(this.eq.oneHanded);
if (oneHandedEq.slot === 'twoHanded')
this.unequip(this.eq.oneHanded, true);
@@ -98,8 +98,8 @@ module.exports = {
delete item.pos;

if (slot === 'finger') {
let f1 = (this.eq.has('finger-1'));
let f2 = (this.eq.has('finger-2'));
let f1 = (this.eq.isDefined('finger-1'));
let f2 = (this.eq.isDefined('finger-2'));

if ((f1) && (f2))
slot = 'finger-1';
@@ -109,7 +109,7 @@ module.exports = {
slot = 'finger-2';
}

if (this.eq.has(slot)) {
if (this.eq.isDefined(slot)) {
if (this.eq[slot] === item.id)
return;

@@ -142,7 +142,7 @@ module.exports = {
let obj = this.obj;
let inventory = obj.inventory;

if (typeof(item) !== 'object' || !item.has('id'))
if (typeof(item) !== 'object' || !item.isDefined('id'))
item = inventory.findItem(itemId);

if (!item)
@@ -186,7 +186,7 @@ module.exports = {
let obj = this.obj;
const inventory = obj.inventory;

if (!msg.has('itemId') && this.quickSlots.has(msg.slot)) {
if (!msg.isDefined('itemId') && this.quickSlots.isDefined(msg.slot)) {
let currentQuickItem = inventory.findItem(this.quickSlots[msg.slot]);
if (!currentQuickItem)
return;
@@ -218,7 +218,7 @@ module.exports = {
},

useQuickSlot: function (msg) {
if (!this.quickSlots.has(msg.slot))
if (!this.quickSlots.isDefined(msg.slot))
return;

const inventory = this.obj.inventory;


+ 2
- 2
src/server/components/gatherer.js View File

@@ -219,7 +219,7 @@ module.exports = {
let nodeType = node.resourceNode.nodeType;

if (nodeType === 'fish') {
if (!obj.equipment.eq.has('tool')) {
if (!obj.equipment.eq.isDefined('tool')) {
this.sendAnnouncement('You need a fishing rod to fish');

return;
@@ -318,7 +318,7 @@ module.exports = {
continue;

if (node.resourceNode.nodeType === 'fish') {
if (!this.obj.equipment.eq.has('tool')) {
if (!this.obj.equipment.eq.isDefined('tool')) {
this.sendAnnouncement('You need a fishing rod to fish');

if (this.gathering === node) {


+ 9
- 9
src/server/components/inventory.js View File

@@ -25,8 +25,8 @@ module.exports = {

//Spells should be sorted so they're EQ'd in the right order
items.sort(function (a, b) {
let aId = a.has('spellId') ? ~~a.spellId : 9999;
let bId = b.has('spellId') ? ~~b.spellId : 9999;
let aId = a.isDefined('spellId') ? ~~a.spellId : 9999;
let bId = b.isDefined('spellId') ? ~~b.spellId : 9999;
return (aId - bId);
});

@@ -49,7 +49,7 @@ module.exports = {

for (let i = 0; i < iLen; i++) {
let item = items[i];
let pos = item.has('pos') ? item.pos : null;
let pos = item.isDefined('pos') ? item.pos : null;

let newItem = this.getItem(item, true, true);
newItem.pos = pos;
@@ -146,7 +146,7 @@ module.exports = {
},

learnAbility: function (itemId, runeSlot) {
if (itemId.has('itemId')) {
if (itemId.isDefined('itemId')) {
let msg = itemId;
itemId = msg.itemId;
runeSlot = msg.slot;
@@ -252,7 +252,7 @@ module.exports = {
},

unlearnAbility: function (itemId) {
if (itemId.has('itemId'))
if (itemId.isDefined('itemId'))
itemId = itemId.itemId;

let item = this.findItem(itemId);
@@ -348,7 +348,7 @@ module.exports = {
if ((!item) || (item.noDrop) || (item.quest))
return;

if (item.has('quickSlot')) {
if (item.isDefined('quickSlot')) {
this.obj.equipment.setQuickSlot({
itemId: null,
slot: item.quickSlot
@@ -416,7 +416,7 @@ module.exports = {
});
}

if (!item.has('pos') && !item.eq) {
if (!item.isDefined('pos') && !item.eq) {
let pos = i;
for (let j = 0; j < iLen; j++) {
if (!items.some(fj => (fj.pos === j))) {
@@ -478,7 +478,7 @@ module.exports = {
},

resolveCallback: function (msg, result) {
let callbackId = msg.has('callbackId') ? msg.callbackId : msg;
let callbackId = msg.isDefined('callbackId') ? msg.callbackId : msg;
result = result || [];

if (!callbackId)
@@ -506,7 +506,7 @@ module.exports = {
return (
i.spell &&
i.spell.rolls &&
i.spell.rolls.has('damage') &&
i.spell.rolls.isDefined('damage') &&
(
i.slot === 'twoHanded' ||
i.slot === 'oneHanded'


+ 3
- 3
src/server/components/inventory/getItem.js View File

@@ -33,7 +33,7 @@ module.exports = (cpnInv, item, hideMessage, noStack, hideAlert, createBagIfFull
//We need to know if a mob dropped it for quest purposes
let fromMob = item.fromMob;

if (!item.has('quality'))
if (!item.isDefined('quality'))
item.quality = 0;

//Store the quantity to send to the player
@@ -69,7 +69,7 @@ module.exports = (cpnInv, item, hideMessage, noStack, hideAlert, createBagIfFull
if (item.eq)
delete item.pos;

if (!item.has('pos') && !item.eq) {
if (!item.isDefined('pos') && !item.eq) {
const iLen = items.length;
let pos = iLen;
for (let i = 0; i < iLen; i++) {
@@ -129,7 +129,7 @@ module.exports = (cpnInv, item, hideMessage, noStack, hideAlert, createBagIfFull
delete item.eq;
obj.equipment.equip(item.id);
}
} else if (item.has('quickSlot')) {
} else if (item.isDefined('quickSlot')) {
obj.equipment.setQuickSlot({
itemId: item.id,
slot: item.quickSlot


+ 1
- 1
src/server/components/inventory/useItem.js View File

@@ -108,7 +108,7 @@ module.exports = async (cpnInv, itemId) => {
}

cpnInv.destroyItem(itemId, 1);
if (item.has('quickSlot'))
if (item.isDefined('quickSlot'))
cpnInv.obj.equipment.replaceQuickSlot(item);
}
};

+ 1
- 1
src/server/components/sound.js View File

@@ -14,7 +14,7 @@ module.exports = {
const s = Object.fromEntries(
serializeProps
.map(p => {
if (!this.has(p))
if (!this.isDefined(p))
return null;

return [p, this[p]];


+ 5
- 5
src/server/components/spellbook.js View File

@@ -146,7 +146,7 @@ module.exports = {
this.furthestRange = builtSpell.range;
}

if ((!options.has('id')) && (spellId === -1)) {
if ((!options.isDefined('id')) && (spellId === -1)) {
spellId = 0;
this.spells.forEach(function (s) {
if (s.id >= spellId)
@@ -154,7 +154,7 @@ module.exports = {
});
}

builtSpell.id = !options.has('id') ? spellId : options.id;
builtSpell.id = !options.isDefined('id') ? spellId : options.id;

//Mobs don't get abilities put on CD when they learn them
if (!this.obj.mob && builtSpell.cdMax)
@@ -322,7 +322,7 @@ module.exports = {
},

canCast: function (action) {
if (!action.has('spell'))
if (!action.isDefined('spell'))
return false;

let spell = this.spells.find(s => (s.id === action.spell));
@@ -336,7 +336,7 @@ module.exports = {
},

cast: function (action, isAuto) {
if (!action.has('spell')) {
if (!action.isDefined('spell')) {
const isCasting = this.isCasting();
this.stopCasting();

@@ -368,7 +368,7 @@ module.exports = {
if (!isAuto)
this.sendAnnouncement('Insufficient mana to cast spell');
success = false;
} else if (spell.has('range')) {
} else if (spell.isDefined('range')) {
let distance = Math.max(Math.abs(action.target.x - this.obj.x), Math.abs(action.target.y - this.obj.y));
let range = spell.range;
if ((spell.useWeaponRange) && (this.obj.player)) {


+ 2
- 2
src/server/components/stats.js View File

@@ -453,7 +453,7 @@ module.exports = {
for (let i = 0; i < aLen; i++) {
let a = aggroList[i];

if (a.damage <= 0 || !a.obj.has('serverId'))
if (a.damage <= 0 || !a.obj.isDefined('serverId'))
continue;

obj.inventory.dropBag(a.obj.name, killSource);
@@ -602,7 +602,7 @@ module.exports = {
return;

let threatMult = heal.threatMult;
if (!heal.has('threatMult'))
if (!heal.isDefined('threatMult'))
threatMult = 1;

let values = this.values;


+ 1
- 1
src/server/components/syncer.js View File

@@ -163,7 +163,7 @@ module.exports = {
if (self)
o = this.oSelf;

if (!o.has(property))
if (!o.isDefined(property))
o[property] = [];

o[property].push(value);


+ 2
- 2
src/server/components/trade.js View File

@@ -111,7 +111,7 @@ module.exports = {
},

startBuy: function (msg) {
if (!msg.has('target') && !msg.targetName)
if (!msg.isDefined('target') && !msg.targetName)
return false;

let target = msg.target;
@@ -353,7 +353,7 @@ module.exports = {
},

resolveCallback: function (msg, result) {
let callbackId = msg.has('callbackId') ? msg.callbackId : msg;
let callbackId = msg.isDefined('callbackId') ? msg.callbackId : msg;
result = result || [];

if (!callbackId)


+ 1
- 1
src/server/components/wardrobe.js View File

@@ -77,7 +77,7 @@ module.exports = {
},

open: function (msg) {
if (!msg.has('sourceId'))
if (!msg.isDefined('sourceId'))
return;

let obj = this.obj.instance.objects.objects.find(o => o.serverId === msg.sourceId);


+ 2
- 2
src/server/components/workbench.js View File

@@ -79,7 +79,7 @@ module.exports = {
},

open: async function (msg) {
if (!msg.has('sourceId'))
if (!msg.isDefined('sourceId'))
return;

let obj = this.obj.instance.objects.objects.find(o => o.serverId === msg.sourceId);
@@ -121,7 +121,7 @@ module.exports = {
},

resolveCallback: function (msg, result) {
let callbackId = (msg.has('callbackId')) ? msg.callbackId : msg;
let callbackId = (msg.isDefined('callbackId')) ? msg.callbackId : msg;
result = result || [];

if (!callbackId)


+ 2
- 2
src/server/components/workbench/buildNeedItems.js View File

@@ -8,8 +8,8 @@ module.exports = ({ inventory: { items } }, { needItems }) => {
const allowedItemIds = items
.filter(item => {
const isValidItem = (
withProps.every(p => item.has(p)) &&
withoutProps.every(p => !item.has(p)) &&
withProps.every(p => item.isDefined(p)) &&
withoutProps.every(p => !item.isDefined(p)) &&
checks.every(c => c(item))
);



+ 6
- 27
src/server/config/clientConfig.js View File

@@ -9,36 +9,15 @@ const config = {
loginBgGeneratorPath: null,
resourceList: [],
textureList: [
'tiles',
'walls',
'mobs',
'bosses',
'animBigObjects',
'bigObjects',
'objects',
'characters',
'attacks',
'ui',
'auras',
'animChar',
'animMob',
'animBoss',
'white',
'ray'

],
//Textures that are 24x24. The renderer needs to know this
bigTextures: [
'animBigObjects',
'animBoss',
'bigObjects',
'bosses',
'auras'

],
atlasTextureDimensions: {},
atlasTextures: [
'tiles',
'walls',
'objects'

],
spriteSizes: {
'images/tiles.png': 8,
@@ -46,9 +25,9 @@ const config = {
'images/objects.png': 8,
'images/mobs.png': 8
},
blockingTileIndices: [
6, 7, 54, 55, 62, 63, 154, 189, 190, 192, 193, 194, 195, 196, 197
],
blockingTileIndices: {
tiles: [6, 7, 54, 55, 62, 63, 154, 189, 190, 192, 193, 194, 195, 196, 197]
},
tileOpacities: {
default: {
default: 0.4,


+ 1
- 1
src/server/config/quests/templates/questKillX.js View File

@@ -28,7 +28,7 @@ module.exports = {
!mobBlueprint.noQuest &&
(
mobBlueprint.attackable ||
!mobBlueprint.has('attackable')
!mobBlueprint.isDefined('attackable')
) &&
mobBlueprint.level <= ~~(this.obj.stats.values.level * 1.35) &&
mobCounts[m] > 1


+ 1
- 1
src/server/config/serverConfig.js View File

@@ -8,7 +8,7 @@ module.exports = {
// sqlite
// rethink
//eslint-disable-next-line no-process-env
db: process.env.IWD_DB || 'sqlite',
db: process.env.IWD_DB || 'rethink',
//eslint-disable-next-line no-process-env
dbHost: process.env.IWD_DB_HOST || 'localhost',
//eslint-disable-next-line no-process-env


+ 1
- 1
src/server/config/spells/spellTemplate.js View File

@@ -27,7 +27,7 @@ module.exports = {
return true;
let inRange = true;
if (this.has('range')) {
if (this.isDefined('range')) {
let obj = this.obj;
let distance = Math.max(Math.abs(target.x - obj.x), Math.abs(target.y - obj.y));
inRange = (distance <= this.range);


+ 1
- 1
src/server/events/events.js View File

@@ -383,7 +383,7 @@ module.exports = {
phase.destroyed = true;
continue;
} else {
if (phase.has('ttl')) {
if (phase.isDefined('ttl')) {
if (phase.ttl === 0) {
phase.end = true;
continue;


+ 1
- 1
src/server/items/generators/quality.js View File

@@ -10,7 +10,7 @@ module.exports = {
magicFindMult: 7,

generate: function (item, blueprint) {
if (blueprint.has('quality')) {
if (blueprint.isDefined('quality')) {
item.quality = ~~blueprint.quality;
return;
}


+ 1
- 1
src/server/items/salvager.js View File

@@ -146,7 +146,7 @@ module.exports = {
if (m.qualityName) {
newItem.quality = item.quality;
newItem.name = m.qualityName[item.quality];
} else if (m.has('quality'))
} else if (m.isDefined('quality'))
newItem.quality = m.quality;

newItem.sprite = materialItems[newItem.name].sprite;


+ 1
- 1
src/server/misc/helpers.js View File

@@ -51,7 +51,7 @@ Object.defineProperty(Array.prototype, 'spliceFirstWhere', {
});

//eslint-disable-next-line no-extend-native
Object.defineProperty(Object.prototype, 'has', {
Object.defineProperty(Object.prototype, 'isDefined', {
enumerable: false,
value: function (prop) {
//eslint-disable-next-line no-undefined


+ 1
- 3
src/server/mods/class-necromancer/index.js View File

@@ -75,10 +75,8 @@ module.exports = {
};
},

onBeforeGetClientConfig: function ({ resourceList, textureList }) {
onBeforeGetClientConfig: function ({ resourceList }) {
resourceList.push(`${this.folderName}/images/abilityIcons.png`);

textureList.push(`${this.folderName}/images/mobs.png`);
},

beforeGetSpellTemplate: function (spell) {


+ 0
- 5
src/server/mods/feature-cards/index.js View File

@@ -6,17 +6,12 @@ module.exports = {
name: 'Feature: Cards',

init: function () {
this.events.on('onBeforeGetClientConfig', this.onBeforeGetClientConfig.bind(this));
this.events.on('onBeforeDropBag', this.onBeforeDropBag.bind(this));
this.events.on('onBeforeGetRecipes', this.onBeforeGetRecipes.bind(this));
this.events.on('onAfterGetZone', this.onAfterGetZone.bind(this));
this.events.on('onAfterGetLayerObjects', this.onAfterGetLayerObjects.bind(this));
},

onBeforeGetClientConfig: function (config) {
config.textureList.push(`${this.folderName}/images/mobs.png`);
},

onAfterGetZone: function (zoneName, config) {
const { zoneName: dealerZoneName, zoneConfig } = dealer;
const dealerName = zoneConfig.name.toLowerCase();


+ 2
- 2
src/server/objects/objBase.js View File

@@ -24,7 +24,7 @@ module.exports = {
this[cpn.type] = cpn;
}

if (cpn.init && this.has('instance'))
if (cpn.init && this.isDefined('instance'))
cpn.init(blueprint || {}, isTransfer);
else {
for (let p in blueprint)
@@ -220,7 +220,7 @@ module.exports = {
},

clearQueue: function () {
if (this.has('serverId')) {
if (this.isDefined('serverId')) {
this.instance.syncer.queue('onClearQueue', {
id: this.id
}, [this.serverId]);


+ 579
- 0
src/server/package-lock.json View File

@@ -85,6 +85,14 @@
"integrity": "sha512-bC49otXX6N0/VYhgOMh4gnP26E9xnDZK3TmbNpxYzzz9BQLBosQwfyOe9/cXUU3txYhTzLCbcqd5c8y/OmCjHA==",
"dev": true
},
"@babel/runtime": {
"version": "7.16.7",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.7.tgz",
"integrity": "sha512-9E9FJowqAsytyOY6LG+1KuueckRL+aQW+mKvXRXnuFGyRAyepJPmEo9vgMfXUA6O9u3IeEdv9MAkppFcaQwogQ==",
"requires": {
"regenerator-runtime": "^0.13.4"
}
},
"@babel/template": {
"version": "7.8.6",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz",
@@ -230,6 +238,327 @@
"integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==",
"dev": true
},
"@jimp/bmp": {
"version": "0.16.1",
"resolved": "https://registry.npmjs.org/@jimp/bmp/-/bmp-0.16.1.tgz",
"integrity": "sha512-iwyNYQeBawrdg/f24x3pQ5rEx+/GwjZcCXd3Kgc+ZUd+Ivia7sIqBsOnDaMZdKCBPlfW364ekexnlOqyVa0NWg==",
"requires": {
"@babel/runtime": "^7.7.2",
"@jimp/utils": "^0.16.1",
"bmp-js": "^0.1.0"
}
},
"@jimp/core": {
"version": "0.16.1",
"resolved": "https://registry.npmjs.org/@jimp/core/-/core-0.16.1.tgz",
"integrity": "sha512-la7kQia31V6kQ4q1kI/uLimu8FXx7imWVajDGtwUG8fzePLWDFJyZl0fdIXVCL1JW2nBcRHidUot6jvlRDi2+g==",
"requires": {
"@babel/runtime": "^7.7.2",
"@jimp/utils": "^0.16.1",
"any-base": "^1.1.0",
"buffer": "^5.2.0",
"exif-parser": "^0.1.12",
"file-type": "^9.0.0",
"load-bmfont": "^1.3.1",
"mkdirp": "^0.5.1",
"phin": "^2.9.1",
"pixelmatch": "^4.0.2",
"tinycolor2": "^1.4.1"
}
},
"@jimp/custom": {
"version": "0.16.1",
"resolved": "https://registry.npmjs.org/@jimp/custom/-/custom-0.16.1.tgz",
"integrity": "sha512-DNUAHNSiUI/j9hmbatD6WN/EBIyeq4AO0frl5ETtt51VN1SvE4t4v83ZA/V6ikxEf3hxLju4tQ5Pc3zmZkN/3A==",
"requires": {
"@babel/runtime": "^7.7.2",
"@jimp/core": "^0.16.1"
}
},
"@jimp/gif": {
"version": "0.16.1",
"resolved": "https://registry.npmjs.org/@jimp/gif/-/gif-0.16.1.tgz",
"integrity": "sha512-r/1+GzIW1D5zrP4tNrfW+3y4vqD935WBXSc8X/wm23QTY9aJO9Lw6PEdzpYCEY+SOklIFKaJYUAq/Nvgm/9ryw==",
"requires": {
"@babel/runtime": "^7.7.2",
"@jimp/utils": "^0.16.1",
"gifwrap": "^0.9.2",
"omggif": "^1.0.9"
}
},
"@jimp/jpeg": {
"version": "0.16.1",
"resolved": "https://registry.npmjs.org/@jimp/jpeg/-/jpeg-0.16.1.tgz",
"integrity": "sha512-8352zrdlCCLFdZ/J+JjBslDvml+fS3Z8gttdml0We759PnnZGqrnPRhkOEOJbNUlE+dD4ckLeIe6NPxlS/7U+w==",
"requires": {
"@babel/runtime": "^7.7.2",
"@jimp/utils": "^0.16.1",
"jpeg-js": "0.4.2"
}
},
"@jimp/plugin-blit": {
"version": "0.16.1",
"resolved": "https://registry.npmjs.org/@jimp/plugin-blit/-/plugin-blit-0.16.1.tgz",
"integrity": "sha512-fKFNARm32RoLSokJ8WZXHHH2CGzz6ire2n1Jh6u+XQLhk9TweT1DcLHIXwQMh8oR12KgjbgsMGvrMVlVknmOAg==",
"requires": {
"@babel/runtime": "^7.7.2",
"@jimp/utils": "^0.16.1"
}
},
"@jimp/plugin-blur": {
"version": "0.16.1",
"resolved": "https://registry.npmjs.org/@jimp/plugin-blur/-/plugin-blur-0.16.1.tgz",
"integrity": "sha512-1WhuLGGj9MypFKRcPvmW45ht7nXkOKu+lg3n2VBzIB7r4kKNVchuI59bXaCYQumOLEqVK7JdB4glaDAbCQCLyw==",
"requires": {
"@babel/runtime": "^7.7.2",
"@jimp/utils": "^0.16.1"
}
},
"@jimp/plugin-circle": {
"version": "0.16.1",
"resolved": "https://registry.npmjs.org/@jimp/plugin-circle/-/plugin-circle-0.16.1.tgz",
"integrity": "sha512-JK7yi1CIU7/XL8hdahjcbGA3V7c+F+Iw+mhMQhLEi7Q0tCnZ69YJBTamMiNg3fWPVfMuvWJJKOBRVpwNTuaZRg==",
"requires": {
"@babel/runtime": "^7.7.2",
"@jimp/utils": "^0.16.1"
}
},
"@jimp/plugin-color": {
"version": "0.16.1",
"resolved": "https://registry.npmjs.org/@jimp/plugin-color/-/plugin-color-0.16.1.tgz",
"integrity": "sha512-9yQttBAO5SEFj7S6nJK54f+1BnuBG4c28q+iyzm1JjtnehjqMg6Ljw4gCSDCvoCQ3jBSYHN66pmwTV74SU1B7A==",
"requires": {
"@babel/runtime": "^7.7.2",
"@jimp/utils": "^0.16.1",
"tinycolor2": "^1.4.1"
}
},
"@jimp/plugin-contain": {
"version": "0.16.1",
"resolved": "https://registry.npmjs.org/@jimp/plugin-contain/-/plugin-contain-0.16.1.tgz",
"integrity": "sha512-44F3dUIjBDHN+Ym/vEfg+jtjMjAqd2uw9nssN67/n4FdpuZUVs7E7wadKY1RRNuJO+WgcD5aDQcsvurXMETQTg==",
"requires": {
"@babel/runtime": "^7.7.2",
"@jimp/utils": "^0.16.1"
}
},
"@jimp/plugin-cover": {
"version": "0.16.1",
"resolved": "https://registry.npmjs.org/@jimp/plugin-cover/-/plugin-cover-0.16.1.tgz",
"integrity": "sha512-YztWCIldBAVo0zxcQXR+a/uk3/TtYnpKU2CanOPJ7baIuDlWPsG+YE4xTsswZZc12H9Kl7CiziEbDtvF9kwA/Q==",
"requires": {
"@babel/runtime": "^7.7.2",
"@jimp/utils": "^0.16.1"
}
},
"@jimp/plugin-crop": {
"version": "0.16.1",
"resolved": "https://registry.npmjs.org/@jimp/plugin-crop/-/plugin-crop-0.16.1.tgz",
"integrity": "sha512-UQdva9oQzCVadkyo3T5Tv2CUZbf0klm2cD4cWMlASuTOYgaGaFHhT9st+kmfvXjKL8q3STkBu/zUPV6PbuV3ew==",
"requires": {
"@babel/runtime": "^7.7.2",
"@jimp/utils": "^0.16.1"
}
},
"@jimp/plugin-displace": {
"version": "0.16.1",
"resolved": "https://registry.npmjs.org/@jimp/plugin-displace/-/plugin-displace-0.16.1.tgz",
"integrity": "sha512-iVAWuz2+G6Heu8gVZksUz+4hQYpR4R0R/RtBzpWEl8ItBe7O6QjORAkhxzg+WdYLL2A/Yd4ekTpvK0/qW8hTVw==",
"requires": {
"@babel/runtime": "^7.7.2",
"@jimp/utils": "^0.16.1"
}
},
"@jimp/plugin-dither": {
"version": "0.16.1",
"resolved": "https://registry.npmjs.org/@jimp/plugin-dither/-/plugin-dither-0.16.1.tgz",
"integrity": "sha512-tADKVd+HDC9EhJRUDwMvzBXPz4GLoU6s5P7xkVq46tskExYSptgj5713J5Thj3NMgH9Rsqu22jNg1H/7tr3V9Q==",
"requires": {
"@babel/runtime": "^7.7.2",
"@jimp/utils": "^0.16.1"
}
},
"@jimp/plugin-fisheye": {
"version": "0.16.1",
"resolved": "https://registry.npmjs.org/@jimp/plugin-fisheye/-/plugin-fisheye-0.16.1.tgz",
"integrity": "sha512-BWHnc5hVobviTyIRHhIy9VxI1ACf4CeSuCfURB6JZm87YuyvgQh5aX5UDKtOz/3haMHXBLP61ZBxlNpMD8CG4A==",
"requires": {
"@babel/runtime": "^7.7.2",
"@jimp/utils": "^0.16.1"
}
},
"@jimp/plugin-flip": {
"version": "0.16.1",
"resolved": "https://registry.npmjs.org/@jimp/plugin-flip/-/plugin-flip-0.16.1.tgz",
"integrity": "sha512-KdxTf0zErfZ8DyHkImDTnQBuHby+a5YFdoKI/G3GpBl3qxLBvC+PWkS2F/iN3H7wszP7/TKxTEvWL927pypT0w==",
"requires": {
"@babel/runtime": "^7.7.2",
"@jimp/utils": "^0.16.1"
}
},
"@jimp/plugin-gaussian": {
"version": "0.16.1",
"resolved": "https://registry.npmjs.org/@jimp/plugin-gaussian/-/plugin-gaussian-0.16.1.tgz",
"integrity": "sha512-u9n4wjskh3N1mSqketbL6tVcLU2S5TEaFPR40K6TDv4phPLZALi1Of7reUmYpVm8mBDHt1I6kGhuCJiWvzfGyg==",
"requires": {
"@babel/runtime": "^7.7.2",
"@jimp/utils": "^0.16.1"
}
},
"@jimp/plugin-invert": {
"version": "0.16.1",
"resolved": "https://registry.npmjs.org/@jimp/plugin-invert/-/plugin-invert-0.16.1.tgz",
"integrity": "sha512-2DKuyVXANH8WDpW9NG+PYFbehzJfweZszFYyxcaewaPLN0GxvxVLOGOPP1NuUTcHkOdMFbE0nHDuB7f+sYF/2w==",
"requires": {
"@babel/runtime": "^7.7.2",
"@jimp/utils": "^0.16.1"
}
},
"@jimp/plugin-mask": {
"version": "0.16.1",
"resolved": "https://registry.npmjs.org/@jimp/plugin-mask/-/plugin-mask-0.16.1.tgz",
"integrity": "sha512-snfiqHlVuj4bSFS0v96vo2PpqCDMe4JB+O++sMo5jF5mvGcGL6AIeLo8cYqPNpdO6BZpBJ8MY5El0Veckhr39Q==",
"requires": {
"@babel/runtime": "^7.7.2",
"@jimp/utils": "^0.16.1"
}
},
"@jimp/plugin-normalize": {
"version": "0.16.1",
"resolved": "https://registry.npmjs.org/@jimp/plugin-normalize/-/plugin-normalize-0.16.1.tgz",
"integrity": "sha512-dOQfIOvGLKDKXPU8xXWzaUeB0nvkosHw6Xg1WhS1Z5Q0PazByhaxOQkSKgUryNN/H+X7UdbDvlyh/yHf3ITRaw==",
"requires": {
"@babel/runtime": "^7.7.2",
"@jimp/utils": "^0.16.1"
}
},
"@jimp/plugin-print": {
"version": "0.16.1",
"resolved": "https://registry.npmjs.org/@jimp/plugin-print/-/plugin-print-0.16.1.tgz",
"integrity": "sha512-ceWgYN40jbN4cWRxixym+csyVymvrryuKBQ+zoIvN5iE6OyS+2d7Mn4zlNgumSczb9GGyZZESIgVcBDA1ezq0Q==",
"requires": {
"@babel/runtime": "^7.7.2",
"@jimp/utils": "^0.16.1",
"load-bmfont": "^1.4.0"
}
},
"@jimp/plugin-resize": {
"version": "0.16.1",
"resolved": "https://registry.npmjs.org/@jimp/plugin-resize/-/plugin-resize-0.16.1.tgz",
"integrity": "sha512-u4JBLdRI7dargC04p2Ha24kofQBk3vhaf0q8FwSYgnCRwxfvh2RxvhJZk9H7Q91JZp6wgjz/SjvEAYjGCEgAwQ==",
"requires": {
"@babel/runtime": "^7.7.2",
"@jimp/utils": "^0.16.1"
}
},
"@jimp/plugin-rotate": {
"version": "0.16.1",
"resolved": "https://registry.npmjs.org/@jimp/plugin-rotate/-/plugin-rotate-0.16.1.tgz",
"integrity": "sha512-ZUU415gDQ0VjYutmVgAYYxC9Og9ixu2jAGMCU54mSMfuIlmohYfwARQmI7h4QB84M76c9hVLdONWjuo+rip/zg==",
"requires": {
"@babel/runtime": "^7.7.2",
"@jimp/utils": "^0.16.1"
}
},
"@jimp/plugin-scale": {
"version": "0.16.1",
"resolved": "https://registry.npmjs.org/@jimp/plugin-scale/-/plugin-scale-0.16.1.tgz",
"integrity": "sha512-jM2QlgThIDIc4rcyughD5O7sOYezxdafg/2Xtd1csfK3z6fba3asxDwthqPZAgitrLgiKBDp6XfzC07Y/CefUw==",
"requires": {
"@babel/runtime": "^7.7.2",
"@jimp/utils": "^0.16.1"
}
},
"@jimp/plugin-shadow": {
"version": "0.16.1",
"resolved": "https://registry.npmjs.org/@jimp/plugin-shadow/-/plugin-shadow-0.16.1.tgz",
"integrity": "sha512-MeD2Is17oKzXLnsphAa1sDstTu6nxscugxAEk3ji0GV1FohCvpHBcec0nAq6/czg4WzqfDts+fcPfC79qWmqrA==",
"requires": {
"@babel/runtime": "^7.7.2",
"@jimp/utils": "^0.16.1"
}
},
"@jimp/plugin-threshold": {
"version": "0.16.1",
"resolved": "https://registry.npmjs.org/@jimp/plugin-threshold/-/plugin-threshold-0.16.1.tgz",
"integrity": "sha512-iGW8U/wiCSR0+6syrPioVGoSzQFt4Z91SsCRbgNKTAk7D+XQv6OI78jvvYg4o0c2FOlwGhqz147HZV5utoSLxA==",
"requires": {
"@babel/runtime": "^7.7.2",
"@jimp/utils": "^0.16.1"
}
},
"@jimp/plugins": {
"version": "0.16.1",
"resolved": "https://registry.npmjs.org/@jimp/plugins/-/plugins-0.16.1.tgz",
"integrity": "sha512-c+lCqa25b+4q6mJZSetlxhMoYuiltyS+ValLzdwK/47+aYsq+kcJNl+TuxIEKf59yr9+5rkbpsPkZHLF/V7FFA==",
"requires": {
"@babel/runtime": "^7.7.2",
"@jimp/plugin-blit": "^0.16.1",
"@jimp/plugin-blur": "^0.16.1",
"@jimp/plugin-circle": "^0.16.1",
"@jimp/plugin-color": "^0.16.1",
"@jimp/plugin-contain": "^0.16.1",
"@jimp/plugin-cover": "^0.16.1",
"@jimp/plugin-crop": "^0.16.1",
"@jimp/plugin-displace": "^0.16.1",
"@jimp/plugin-dither": "^0.16.1",
"@jimp/plugin-fisheye": "^0.16.1",
"@jimp/plugin-flip": "^0.16.1",
"@jimp/plugin-gaussian": "^0.16.1",
"@jimp/plugin-invert": "^0.16.1",
"@jimp/plugin-mask": "^0.16.1",
"@jimp/plugin-normalize": "^0.16.1",
"@jimp/plugin-print": "^0.16.1",
"@jimp/plugin-resize": "^0.16.1",
"@jimp/plugin-rotate": "^0.16.1",
"@jimp/plugin-scale": "^0.16.1",
"@jimp/plugin-shadow": "^0.16.1",
"@jimp/plugin-threshold": "^0.16.1",
"timm": "^1.6.1"
}
},
"@jimp/png": {
"version": "0.16.1",
"resolved": "https://registry.npmjs.org/@jimp/png/-/png-0.16.1.tgz",
"integrity": "sha512-iyWoCxEBTW0OUWWn6SveD4LePW89kO7ZOy5sCfYeDM/oTPLpR8iMIGvZpZUz1b8kvzFr27vPst4E5rJhGjwsdw==",
"requires": {
"@babel/runtime": "^7.7.2",
"@jimp/utils": "^0.16.1",
"pngjs": "^3.3.3"
}
},
"@jimp/tiff": {
"version": "0.16.1",
"resolved": "https://registry.npmjs.org/@jimp/tiff/-/tiff-0.16.1.tgz",
"integrity": "sha512-3K3+xpJS79RmSkAvFMgqY5dhSB+/sxhwTFA9f4AVHUK0oKW+u6r52Z1L0tMXHnpbAdR9EJ+xaAl2D4x19XShkQ==",
"requires": {
"@babel/runtime": "^7.7.2",
"utif": "^2.0.1"
}
},
"@jimp/types": {
"version": "0.16.1",
"resolved": "https://registry.npmjs.org/@jimp/types/-/types-0.16.1.tgz",
"integrity": "sha512-g1w/+NfWqiVW4CaXSJyD28JQqZtm2eyKMWPhBBDCJN9nLCN12/Az0WFF3JUAktzdsEC2KRN2AqB1a2oMZBNgSQ==",
"requires": {
"@babel/runtime": "^7.7.2",
"@jimp/bmp": "^0.16.1",
"@jimp/gif": "^0.16.1",
"@jimp/jpeg": "^0.16.1",
"@jimp/png": "^0.16.1",
"@jimp/tiff": "^0.16.1",
"timm": "^1.6.1"
}
},
"@jimp/utils": {
"version": "0.16.1",
"resolved": "https://registry.npmjs.org/@jimp/utils/-/utils-0.16.1.tgz",
"integrity": "sha512-8fULQjB0x4LzUSiSYG6ZtQl355sZjxbv8r9PPAuYHzS9sGiSHJQavNqK/nKnpDsVkU88/vRGcE7t3nMU0dEnVw==",
"requires": {
"@babel/runtime": "^7.7.2",
"regenerator-runtime": "^0.13.3"
}
},
"@types/component-emitter": {
"version": "1.2.10",
"resolved": "https://registry.npmjs.org/@types/component-emitter/-/component-emitter-1.2.10.tgz",
@@ -304,6 +633,11 @@
"color-convert": "^1.9.0"
}
},
"any-base": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/any-base/-/any-base-1.1.0.tgz",
"integrity": "sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg=="
},
"argparse": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
@@ -357,6 +691,11 @@
"resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz",
"integrity": "sha1-mBjHngWbE1X5fgQooBfIOOkLqBI="
},
"base64-js": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="
},
"base64id": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz",
@@ -372,6 +711,11 @@
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
"integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg=="
},
"bmp-js": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/bmp-js/-/bmp-js-0.1.0.tgz",
"integrity": "sha1-4Fpj95amwf8l9Hcex62twUjAcjM="
},
"body-parser": {
"version": "1.19.0",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz",
@@ -406,6 +750,20 @@
"concat-map": "0.0.1"
}
},
"buffer": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
"integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
"requires": {
"base64-js": "^1.3.1",
"ieee754": "^1.1.13"
}
},
"buffer-equal": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-0.0.1.tgz",
"integrity": "sha1-kbx0sR6kBbyRa8aqkI+q+ltKrEs="
},
"bytes": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
@@ -565,6 +923,11 @@
"esutils": "^2.0.2"
}
},
"dom-walk": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz",
"integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w=="
},
"ee-first": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
@@ -958,6 +1321,11 @@
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
"integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
},
"exif-parser": {
"version": "0.1.12",
"resolved": "https://registry.npmjs.org/exif-parser/-/exif-parser-0.1.12.tgz",
"integrity": "sha1-WKnS1ywCwfbwKg70qRZicrd2CSI="
},
"express": {
"version": "4.17.1",
"resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz",
@@ -1038,6 +1406,11 @@
"flat-cache": "^3.0.4"
}
},
"file-type": {
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/file-type/-/file-type-9.0.0.tgz",
"integrity": "sha512-Qe/5NJrgIOlwijpq3B7BEpzPFcgzggOTagZmkXQY4LA6bsXKTUstK7Wp12lEJ/mLKTpvIZxmIuRcLYWT6ov9lw=="
},
"finalhandler": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
@@ -1095,6 +1468,15 @@
"integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
"dev": true
},
"gifwrap": {
"version": "0.9.2",
"resolved": "https://registry.npmjs.org/gifwrap/-/gifwrap-0.9.2.tgz",
"integrity": "sha512-fcIswrPaiCDAyO8xnWvHSZdWChjKXUanKKpAiWWJ/UTkEi/aYKn5+90e7DE820zbEaVR9CE2y4z9bzhQijZ0BA==",
"requires": {
"image-q": "^1.1.1",
"omggif": "^1.0.10"
}
},
"glob": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
@@ -1118,6 +1500,15 @@
"is-glob": "^4.0.1"
}
},
"global": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz",
"integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==",
"requires": {
"min-document": "^2.19.0",
"process": "^0.11.10"
}
},
"globals": {
"version": "11.12.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
@@ -1150,12 +1541,22 @@
"safer-buffer": ">= 2.1.2 < 3"
}
},
"ieee754": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="
},
"ignore": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
"integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
"dev": true
},
"image-q": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/image-q/-/image-q-1.1.1.tgz",
"integrity": "sha1-/IQJlmRGC5DKhi2TALa/u7+/gFY="
},
"image-size": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/image-size/-/image-size-1.0.0.tgz",
@@ -1212,6 +1613,11 @@
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
"dev": true
},
"is-function": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz",
"integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ=="
},
"is-glob": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
@@ -1227,6 +1633,23 @@
"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
"dev": true
},
"jimp": {
"version": "0.16.1",
"resolved": "https://registry.npmjs.org/jimp/-/jimp-0.16.1.tgz",
"integrity": "sha512-+EKVxbR36Td7Hfd23wKGIeEyHbxShZDX6L8uJkgVW3ESA9GiTEPK08tG1XI2r/0w5Ch0HyJF5kPqF9K7EmGjaw==",
"requires": {
"@babel/runtime": "^7.7.2",
"@jimp/custom": "^0.16.1",
"@jimp/plugins": "^0.16.1",
"@jimp/types": "^0.16.1",
"regenerator-runtime": "^0.13.3"
}
},
"jpeg-js": {
"version": "0.4.2",
"resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.2.tgz",
"integrity": "sha512-+az2gi/hvex7eLTMTlbRLOhH6P6WFdk2ITI8HJsaH2VqYO0I594zXSYEP+tf4FW+8Cy68ScDXoAsQdyQanv3sw=="
},
"js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -1271,6 +1694,21 @@
"type-check": "~0.4.0"
}
},
"load-bmfont": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/load-bmfont/-/load-bmfont-1.4.1.tgz",
"integrity": "sha512-8UyQoYmdRDy81Brz6aLAUhfZLwr5zV0L3taTQ4hju7m6biuwiWiJXjPhBJxbUQJA8PrkvJ/7Enqmwk2sM14soA==",
"requires": {
"buffer-equal": "0.0.1",
"mime": "^1.3.4",
"parse-bmfont-ascii": "^1.0.3",
"parse-bmfont-binary": "^1.0.5",
"parse-bmfont-xml": "^1.1.4",
"phin": "^2.9.1",
"xhr": "^2.0.1",
"xtend": "^4.0.0"
}
},
"lodash": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
@@ -1337,6 +1775,14 @@
"mime-db": "1.43.0"
}
},
"min-document": {
"version": "2.19.0",
"resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz",
"integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=",
"requires": {
"dom-walk": "^0.1.0"
}
},
"minimatch": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
@@ -1346,6 +1792,19 @@
"brace-expansion": "^1.1.7"
}
},
"minimist": {
"version": "1.2.5",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
},
"mkdirp": {
"version": "0.5.5",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
"integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
"requires": {
"minimist": "^1.2.5"
}
},
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
@@ -1367,6 +1826,11 @@
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
},
"omggif": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/omggif/-/omggif-1.0.10.tgz",
"integrity": "sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw=="
},
"on-finished": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
@@ -1403,6 +1867,11 @@
"word-wrap": "^1.2.3"
}
},
"pako": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
"integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="
},
"parent-module": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
@@ -1412,6 +1881,30 @@
"callsites": "^3.0.0"
}
},
"parse-bmfont-ascii": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/parse-bmfont-ascii/-/parse-bmfont-ascii-1.0.6.tgz",
"integrity": "sha1-Eaw8P/WPfCAgqyJ2kHkQjU36AoU="
},
"parse-bmfont-binary": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/parse-bmfont-binary/-/parse-bmfont-binary-1.0.6.tgz",
"integrity": "sha1-0Di0dtPp3Z2x4RoLDlOiJ5K2kAY="
},
"parse-bmfont-xml": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/parse-bmfont-xml/-/parse-bmfont-xml-1.1.4.tgz",
"integrity": "sha512-bjnliEOmGv3y1aMEfREMBJ9tfL3WR0i0CKPj61DnSLaoxWR3nLrsQrEbCId/8rF4NyRF0cCqisSVXyQYWM+mCQ==",
"requires": {
"xml-parse-from-string": "^1.0.0",
"xml2js": "^0.4.5"
}
},
"parse-headers": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.4.tgz",
"integrity": "sha512-psZ9iZoCNFLrgRjZ1d8mn0h9WRqJwFxM9q3x7iUjN/YT2OksthDJ5TiPCu2F38kS4zutqfW+YdVVkBZZx3/1aw=="
},
"parseurl": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
@@ -1440,6 +1933,24 @@
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
"integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
},
"phin": {
"version": "2.9.3",
"resolved": "https://registry.npmjs.org/phin/-/phin-2.9.3.tgz",
"integrity": "sha512-CzFr90qM24ju5f88quFC/6qohjC144rehe5n6DH900lgXmUe86+xCKc10ev56gRKC4/BkHUoG4uSiQgBiIXwDA=="
},
"pixelmatch": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/pixelmatch/-/pixelmatch-4.0.2.tgz",
"integrity": "sha1-j0fc7FARtHe2fbA8JDvB8wheiFQ=",
"requires": {
"pngjs": "^3.0.0"
}
},
"pngjs": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz",
"integrity": "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w=="
},
"prelude-ls": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
@@ -1455,6 +1966,11 @@
"fast-diff": "^1.1.2"
}
},
"process": {
"version": "0.11.10",
"resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
"integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI="
},
"progress": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
@@ -1512,6 +2028,11 @@
}
}
},
"regenerator-runtime": {
"version": "0.13.9",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz",
"integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA=="
},
"regexpp": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz",
@@ -1566,6 +2087,11 @@
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
"sax": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
},
"semver": {
"version": "7.3.5",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
@@ -1822,6 +2348,16 @@
"integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
"dev": true
},
"timm": {
"version": "1.7.1",
"resolved": "https://registry.npmjs.org/timm/-/timm-1.7.1.tgz",
"integrity": "sha512-IjZc9KIotudix8bMaBW6QvMuq64BrJWFs1+4V0lXwWGQZwH+LnX87doAYhem4caOEusRP9/g6jVDQmZ8XOk1nw=="
},
"tinycolor2": {
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.4.2.tgz",
"integrity": "sha512-vJhccZPs965sV/L2sU4oRQVAos0pQXwsvTLkWYdqJ+a8Q5kPFzJTuOFwy7UniPli44NKQGAglksjvOcpo95aZA=="
},
"to-fast-properties": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
@@ -1904,6 +2440,14 @@
"punycode": "^2.1.0"
}
},
"utif": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/utif/-/utif-2.0.1.tgz",
"integrity": "sha512-Z/S1fNKCicQTf375lIP9G8Sa1H/phcysstNrrSdZKj1f9g58J4NMgb5IgiEZN9/nLMPDwF0W7hdOe9Qq2IYoLg==",
"requires": {
"pako": "^1.0.5"
}
},
"utils-merge": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
@@ -1951,6 +2495,41 @@
"resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz",
"integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A=="
},
"xhr": {
"version": "2.6.0",
"resolved": "https://registry.npmjs.org/xhr/-/xhr-2.6.0.tgz",
"integrity": "sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA==",
"requires": {
"global": "~4.4.0",
"is-function": "^1.0.1",
"parse-headers": "^2.0.0",
"xtend": "^4.0.0"
}
},
"xml-parse-from-string": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/xml-parse-from-string/-/xml-parse-from-string-1.0.1.tgz",
"integrity": "sha1-qQKekp09vN7RafPG4oI42VpdWig="
},
"xml2js": {
"version": "0.4.23",
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz",
"integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==",
"requires": {
"sax": ">=0.6.0",
"xmlbuilder": "~11.0.0"
}
},
"xmlbuilder": {
"version": "11.0.1",
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
"integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA=="
},
"xtend": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="
},
"yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",


+ 1
- 0
src/server/package.json View File

@@ -9,6 +9,7 @@
"express": "^4.17.1",
"express-minify": "^1.0.0",
"image-size": "^1.0.0",
"jimp": "^0.16.1",
"rethinkdbdash": "^2.3.31",
"socket.io": "^4.2.0",
"universal-analytics": "^0.5.1"


+ 2
- 2
src/server/security/connections.js View File

@@ -25,7 +25,7 @@ module.exports = {

let sessionDuration = 0;

if (player.has('id')) {
if (player.isDefined('id')) {
if (player.social)
player.social.dc();
sessionDuration = ~~(((+new Date()) - player.player.sessionStart) / 1000);
@@ -49,7 +49,7 @@ module.exports = {
onGetDisconnectedPlayer: [player.name]
});

if (player.has('id'))
if (player.isDefined('id'))
this.modifyPlayerCount(-1);
}



+ 18
- 14
src/server/world/instancer.js View File

@@ -1,17 +1,18 @@
let map = require('./map');
let syncer = require('./syncer');
let objects = require('../objects/objects');
let spawners = require('./spawners');
let physics = require('./physics');
let resourceSpawner = require('./resourceSpawner');
let spellCallbacks = require('../config/spells/spellCallbacks');
let questBuilder = require('../config/quests/questBuilder');
let events = require('../events/events');
let scheduler = require('../misc/scheduler');
let herbs = require('../config/herbs');
let eventEmitter = require('../misc/events');
const map = require('./map');
const syncer = require('./syncer');
const objects = require('../objects/objects');
const spawners = require('./spawners');
const physics = require('./physics');
const resourceSpawner = require('./resourceSpawner');
const spellCallbacks = require('../config/spells/spellCallbacks');
const questBuilder = require('../config/quests/questBuilder');
const events = require('../events/events');
const scheduler = require('../misc/scheduler');
const herbs = require('../config/herbs');
const eventEmitter = require('../misc/events');
const mods = require('../misc/mods');
const transactions = require('../security/transactions');
const spriteBuilder = require('./spriteBuilder/index');

//Own helpers
const { stageZoneIn, unstageZoneIn, clientAck } = require('./instancer/handshakes');
@@ -26,11 +27,12 @@ module.exports = {

lastTime: 0,

init: function (args) {
init: async function (args) {
this.zoneId = args.zoneId;

spellCallbacks.init();
herbs.init();
spriteBuilder.init(args.name);
map.init(args);

const fakeInstance = {
@@ -67,6 +69,8 @@ module.exports = {

[resourceSpawner, syncer, objects, questBuilder, events].forEach(i => i.init(fakeInstance));

await spriteBuilder.finalize();

this.tick();

this.clientAck = clientAck;
@@ -208,7 +212,7 @@ module.exports = {
if (msg.keepPos && (!physics.isValid(obj.x, obj.y) || !map.canPathFromPos(obj)))
msg.keepPos = false;

if (!msg.keepPos || !obj.has('x') || (map.mapFile.properties.isRandom && obj.instanceId !== map.seed)) {
if (!msg.keepPos || !obj.isDefined('x') || (map.mapFile.properties.isRandom && obj.instanceId !== map.seed)) {
obj.x = spawnPos.x;
obj.y = spawnPos.y;
}


+ 21
- 173
src/server/world/map.js View File

@@ -1,31 +1,23 @@
let objects = require('../objects/objects');
let physics = require('./physics');
let spawners = require('./spawners');
let resourceSpawner = require('./resourceSpawner');
let globalZone = require('../config/zoneBase');
let randomMap = require('./randomMap/randomMap');
const physics = require('./physics');
const resourceSpawner = require('./resourceSpawner');
const globalZone = require('../config/zoneBase');
const randomMap = require('./randomMap/randomMap');
const generateMappings = require('./randomMap/generateMappings');
let events = require('../misc/events');
const events = require('../misc/events');
const spriteBuilder = require('./spriteBuilder/index');

const mapObjects = require('./map/mapObjects');
//Builders
const buildTile = require('./map/builders/tile');
const buildObject = require('./map/builders/object');

//Helpers
const canPathFromPos = require('./map/canPathFromPos');
const getObjectifiedProperties = require('./map/getObjectifiedProperties');

let mapFile = null;
let mapScale = null;
let padding = null;

const objectifyProperties = oldProperties => {
if (!oldProperties || !oldProperties.push)
return oldProperties || {};

let newProperties = {};
oldProperties.forEach(p => {
newProperties[p.name] = p.value;
});
return newProperties;
};

module.exports = {
name: null,
path: null,
@@ -105,9 +97,10 @@ module.exports = {
mapFile = require('../' + this.path + '/' + this.name + '/map');
this.mapFile = mapFile;
//Fix for newer versions of Tiled
this.mapFile.properties = objectifyProperties(this.mapFile.properties);
this.mapFile.properties = getObjectifiedProperties(this.mapFile.properties);

mapScale = mapFile.tilesets[0].tileheight;
this.mapScale = mapScale;

this.custom = mapFile.properties.custom;

@@ -126,7 +119,10 @@ module.exports = {
collisionMap: this.collisionMap,
clientObjects: this.objBlueprints,
padding: padding,
hiddenRooms: this.hiddenRooms
hiddenRooms: this.hiddenRooms,
spriteAtlasPath: spriteBuilder.getPath(),
noFlipTiles: spriteBuilder.getNoFlipTiles(),
tileOpacities: spriteBuilder.getTileOpacities()
};
},

@@ -196,7 +192,7 @@ module.exports = {
//Fix for newer versions of Tiled
this.randomMap.templates
.forEach(r => {
r.properties = objectifyProperties(r.properties);
r.properties = getObjectifiedProperties(r.properties);
});

this.randomMap.templates
@@ -381,159 +377,11 @@ module.exports = {

builders: {
tile: function (info) {
let { x, y, cell, layer: layerName, sheetName } = info;

if (cell === 0) {
if (layerName === 'tiles')
this.collisionMap[x][y] = 1;

return;
}

let cellInfo = this.getCellInfo(cell, x, y, layerName);
if (!sheetName) {
info.sheetName = cellInfo.sheetName;
sheetName = cellInfo.sheetName;
}

const offsetCell = this.getOffsetCellPos(sheetName, cellInfo.cell);

const isHiddenLayer = layerName.indexOf('hidden') === 0;

if (isHiddenLayer)
this[layerName][x][y] = offsetCell;
else {
const layer = this.layers;

if (this.oldLayers[layerName])
this.oldLayers[layerName][x][y] = offsetCell;

layer[x][y] = (layer[x][y] === null) ? offsetCell : layer[x][y] + ',' + offsetCell;

if (layerName.indexOf('walls') > -1)
this.collisionMap[x][y] = 1;
else if (clientConfig.config.blockingTileIndices.includes(offsetCell))
this.collisionMap[x][y] = 1;
}
buildTile(this, info);
},

object: function (layerName, cell) {
//Fixes for newer versions of tiled
cell.properties = objectifyProperties(cell.properties);
cell.polyline = cell.polyline || cell.polygon;

const x = cell.x / mapScale;
const y = (cell.y / mapScale) - 1;

let clientObj = (layerName === 'clientObjects');
let cellInfo = this.getCellInfo(cell.gid, x, y, layerName);

let name = (cell.name || '');
let objZoneName = name;
if (name.indexOf('|') > -1) {
let split = name.split('|');
name = split[0];
objZoneName = split[1];
}

let blueprint = {
id: cell.properties.id,
clientObj: clientObj,
sheetName: cell.has('sheetName') ? cell.sheetName : cellInfo.sheetName,
cell: cell.has('cell') ? cell.cell : cellInfo.cell - 1,
x,
y,
name: name,
properties: cell.properties || {},
layerName: layerName
};

if (objZoneName !== name)
blueprint.objZoneName = objZoneName;

if (this.zone) {
if ((this.zone.objects) && (this.zone.objects[objZoneName.toLowerCase()]))
extend(blueprint, this.zone.objects[objZoneName.toLowerCase()]);
else if ((this.zone.objects) && (this.zone.mobs[objZoneName.toLowerCase()]))
extend(blueprint, this.zone.mobs[objZoneName.toLowerCase()]);
}

if (blueprint.blocking)
this.collisionMap[blueprint.x][blueprint.y] = 1;

if ((blueprint.properties.cpnNotice) || (blueprint.properties.cpnLightPatch) || (layerName === 'rooms') || (layerName === 'hiddenRooms')) {
blueprint.y++;
blueprint.width = cell.width / mapScale;
blueprint.height = cell.height / mapScale;
} else if (cell.width === 24)
blueprint.x++;

if (cell.polyline)
mapObjects.polyline(this.size, blueprint, cell, mapScale);

if (layerName === 'rooms') {
if (blueprint.properties.exit) {
let room = this.rooms.find(function (r) {
return (!(
(blueprint.x + blueprint.width < r.x) ||
(blueprint.y + blueprint.height < r.y) ||
(blueprint.x >= r.x + r.width) ||
(blueprint.y >= r.y + r.height)
));
});

room.exits.push(blueprint);
} else if (blueprint.properties.resource)
resourceSpawner.register(blueprint.properties.resource, blueprint);
else {
blueprint.exits = [];
blueprint.objects = [];
this.rooms.push(blueprint);
}
} else if (layerName === 'hiddenRooms') {
blueprint.fog = (cell.properties || {}).fog;
blueprint.interior = (cell.properties || {}).interior;
blueprint.discoverable = (cell.properties || {}).discoverable;
blueprint.layer = ~~((cell.properties || {}).layer || 0);

if (!mapFile.properties.isRandom)
this.hiddenRooms.push(blueprint);
else {
let room = this.rooms.find(r => {
return !(
blueprint.x < r.x ||
blueprint.y < r.y ||
blueprint.x >= r.x + r.width ||
blueprint.y >= r.y + r.height
);
});

room.objects.push(blueprint);
}
} else if (!clientObj) {
if (!mapFile.properties.isRandom)
spawners.register(blueprint, blueprint.spawnCd || mapFile.properties.spawnCd);
else {
let room = this.rooms.find(r => {
return !(
blueprint.x < r.x ||
blueprint.y < r.y ||
blueprint.x >= r.x + r.width ||
blueprint.y >= r.y + r.height
);
});

room.objects.push(blueprint);
}
} else {
if ((cell.width) && (!cell.polyline)) {
blueprint.width = cell.width / mapScale;
blueprint.height = cell.height / mapScale;
}

let obj = objects.buildObjects([blueprint], true).getSimple(true);
this.objBlueprints.push(obj);
}
buildObject(this, layerName, cell);
}
},



+ 157
- 0
src/server/world/map/builders/object.js View File

@@ -0,0 +1,157 @@
//Imports
const objects = require('../../../objects/objects');
const spawners = require('./../../spawners');
const resourceSpawner = require('../../resourceSpawner');

const mapObjects = require('../mapObjects');
const getObjectifiedProperties = require('../getObjectifiedProperties');

const spriteBuilder = require('../../spriteBuilder/index');

//Helpers
const buildRoom = (mapModule, blueprint) => {
if (blueprint.properties.exit) {
const room = mapModule.rooms.find(r => {
return (!(
(blueprint.x + blueprint.width < r.x) ||
(blueprint.y + blueprint.height < r.y) ||
(blueprint.x >= r.x + r.width) ||
(blueprint.y >= r.y + r.height)
));
});

room.exits.push(blueprint);
} else if (blueprint.properties.resource)
resourceSpawner.register(blueprint.properties.resource, blueprint);
else {
blueprint.exits = [];
blueprint.objects = [];
mapModule.rooms.push(blueprint);
}
};

const buildHiddenRoom = (mapModule, blueprint) => {
const { mapFile } = mapModule;
const { cell } = blueprint;

blueprint.fog = (cell.properties || {}).fog;
blueprint.interior = (cell.properties || {}).interior;
blueprint.discoverable = (cell.properties || {}).discoverable;
blueprint.layer = ~~((cell.properties || {}).layer || 0);

if (!mapFile.properties.isRandom)
mapModule.hiddenRooms.push(blueprint);
else {
const room = mapModule.rooms.find(r => {
return !(
blueprint.x < r.x ||
blueprint.y < r.y ||
blueprint.x >= r.x + r.width ||
blueprint.y >= r.y + r.height
);
});

room.objects.push(blueprint);
}
};

const buildRegularObject = (mapModule, blueprint) => {
const { mapFile } = mapModule;

if (!mapFile.properties.isRandom)
spawners.register(blueprint, blueprint.spawnCd || mapFile.properties.spawnCd);
else {
const room = mapModule.rooms.find(r => {
return !(
blueprint.x < r.x ||
blueprint.y < r.y ||
blueprint.x >= r.x + r.width ||
blueprint.y >= r.y + r.height
);
});

room.objects.push(blueprint);
}
};

const buildClientObject = (mapModule, blueprint) => {
const { mapScale } = mapModule;

const { cell } = blueprint;

if ((cell.width) && (!cell.polyline)) {
blueprint.width = cell.width / mapScale;
blueprint.height = cell.height / mapScale;
}

const obj = objects.buildObjects([blueprint], true).getSimple(true);
mapModule.objBlueprints.push(obj);
};

//Builder
const buildObject = (mapModule, layerName, cell) => {
const { mapScale } = mapModule;

cell.properties = getObjectifiedProperties(cell.properties);
cell.polyline = cell.polyline || cell.polygon;

const x = cell.x / mapScale;
const y = (cell.y / mapScale) - 1;

const clientObj = (layerName === 'clientObjects');
const cellInfo = mapModule.getCellInfo(cell.gid, x, y, layerName);

let name = (cell.name || '');
let objZoneName = name;
if (name.indexOf('|') > -1) {
const split = name.split('|');
name = split[0];
objZoneName = split[1];
}

const blueprint = {
id: cell.properties.id,
clientObj: clientObj,
sheetName: cell.isDefined('sheetName') ? cell.sheetName : cellInfo.sheetName,
cell: cell.isDefined('cell') ? cell.cell : cellInfo.cell - 1,
x,
y,
name: name,
properties: cell.properties || {},
layerName: layerName
};

if (objZoneName !== name)
blueprint.objZoneName = objZoneName;

if (mapModule.zone) {
if ((mapModule.zone.objects) && (mapModule.zone.objects[objZoneName.toLowerCase()]))
extend(blueprint, mapModule.zone.objects[objZoneName.toLowerCase()]);
else if ((mapModule.zone.objects) && (mapModule.zone.mobs[objZoneName.toLowerCase()]))
extend(blueprint, mapModule.zone.mobs[objZoneName.toLowerCase()]);
}

if (blueprint.blocking)
mapModule.collisionMap[blueprint.x][blueprint.y] = 1;

if ((blueprint.properties.cpnNotice) || (blueprint.properties.cpnLightPatch) || (layerName === 'rooms') || (layerName === 'hiddenRooms')) {
blueprint.y++;
blueprint.width = cell.width / mapScale;
blueprint.height = cell.height / mapScale;
} else if (cell.width === 24)
blueprint.x++;

if (cell.polyline)
mapObjects.polyline(mapModule.size, blueprint, cell, mapScale);

if (layerName === 'rooms')
buildRoom(mapModule, blueprint);
else if (layerName === 'hiddenRooms')
buildHiddenRoom(mapModule, blueprint);
else if (!clientObj)
buildRegularObject(mapModule, blueprint);
else
buildClientObject(mapModule, blueprint);
};

module.exports = buildObject;

+ 42
- 0
src/server/world/map/builders/tile.js View File

@@ -0,0 +1,42 @@
//Imports
const spriteBuilder = require('../../spriteBuilder/index');

//Builder
const buildTile = (mapModule, tileInfo) => {
const { x, y, cell, layer: layerName } = tileInfo;

if (cell === 0) {
if (layerName === 'tiles')
mapModule.collisionMap[x][y] = 1;

return;
}

const cellInfo = mapModule.getCellInfo(cell, x, y, layerName);
if (!tileInfo.sheetName)
tileInfo.sheetName = cellInfo.sheetName;

const offsetCell = spriteBuilder.track(cellInfo);

//const offsetCell = mapModule.getOffsetCellPos(tileInfo.sheetName, cellInfo.cell);

const isHiddenLayer = layerName.indexOf('hidden') === 0;

if (isHiddenLayer)
mapModule[layerName][x][y] = offsetCell;
else {
const layer = mapModule.layers;

if (mapModule.oldLayers[layerName])
mapModule.oldLayers[layerName][x][y] = offsetCell;

layer[x][y] = (layer[x][y] === null) ? offsetCell : layer[x][y] + ',' + offsetCell;

if (layerName.indexOf('walls') > -1)
mapModule.collisionMap[x][y] = 1;
else if (clientConfig.config.blockingTileIndices?.[cellInfo.sheetName]?.includes(cellInfo.cell))
mapModule.collisionMap[x][y] = 1;
}
};

module.exports = buildTile;

+ 17
- 0
src/server/world/map/getObjectifiedProperties.js View File

@@ -0,0 +1,17 @@
//In older versions of the Tiled map editor, properties are stored as an object
// whereas newer versions store them as as an array. This helper converts the array
// version in to an object version.

const getObjectifiedProperties = oldProperties => {
if (!oldProperties || !oldProperties.push)
return oldProperties || {};

let newProperties = {};
oldProperties.forEach(p => {
newProperties[p.name] = p.value;
});
return newProperties;
};

module.exports = getObjectifiedProperties;

+ 2
- 2
src/server/world/mobBuilder.js View File

@@ -27,7 +27,7 @@ module.exports = {
if (typeDefinition.sheetName)
mob.sheetName = typeDefinition.sheetName;

if (typeDefinition.has('cell'))
if (typeDefinition.isDefined('cell'))
mob.cell = typeDefinition.cell;

mob.addComponent('stats', {
@@ -63,7 +63,7 @@ module.exports = {
dmgMult: typeDefinition.dmgMult
});

if (!blueprint.has('attackable') || blueprint.attackable === true) {
if (!blueprint.isDefined('attackable') || blueprint.attackable === true) {
mob.addComponent('aggro', {
faction: blueprint.faction
});


+ 117
- 0
src/server/world/spriteBuilder/index.js View File

@@ -0,0 +1,117 @@
//Imports
const jimp = require('jimp');

//System
let mapName = null;
let stage = null;
let noFlipTiles = null;
let tileOpacities = null;

//Methods
const init = _mapName => {
mapName = _mapName;
stage = [];
noFlipTiles = [];
tileOpacities = [];
};

const track = tileInfo => {
const { cell, sheetName } = tileInfo;

if (!sheetName || cell === undefined)
return cell;

const existIndex = stage.findIndex(s => s.cell === cell && s.sheetName === sheetName);
if (existIndex !== -1)
return existIndex + 1;

stage.push({
cell,
sheetName
});

const { config: { tilesNoFlip: noFlip, tileOpacities: opacities } } = clientConfig;

if (noFlip?.[sheetName]?.includes(cell - 1))
noFlipTiles.push(stage.length);

tileOpacities.push({
max: opacities?.[sheetName]?.max ?? opacities.default.max,
opacity: opacities?.[sheetName]?.[cell - 1] ?? opacities?.[sheetName]?.default ?? opacities.default.default
});

return stage.length;
};

const getPath = () => {
const path = `images/temp/${mapName}.png`;

return path;
};

const finalize = async () => {
const pathMaps = {};

const paths = [];
stage.forEach(s => {
const sheetName = s.sheetName;

const path = sheetName.includes('.png') ? `../${sheetName}` : `../client/images/${sheetName}.png`;

if (paths.includes(path))
return;

pathMaps[sheetName] = path;

paths.push(path);
});

const loaders = await Promise.all(paths.map(p => jimp.read(p)));

//Load images
const images = await Promise.all(loaders);

const w = 8 * 8;
const h = Math.ceil(stage.length / 8) * 8;

//Create new
const res = new jimp(w, h, async (err, image) => {
stage.forEach(({ sheetName, cell }, i) => {
const mappedPath = pathMaps[sheetName];
const imageIndex = paths.findIndex(p => p === mappedPath);
const sourceImage = images[imageIndex];

const y = ~~(i / 8);
const x = i - (y * 8);

const sy = ~~((cell - 1) / 8);
const sx = cell - 1 - (sy * 8);

image.blit(sourceImage, x * 8, y * 8, sx * 8, sy * 8, 8, 8);
});

const path = `../client/${getPath()}`;

image.writeAsync(path);
});

return res;
};

const getNoFlipTiles = () => {
return noFlipTiles;
};

const getTileOpacities = () => {
return tileOpacities;
};

//Exports
module.exports = {
init,
track,
getPath,
getNoFlipTiles,
getTileOpacities,
finalize
};

+ 2
- 2
src/server/world/worker.js View File

@@ -78,7 +78,7 @@ let onDbReady = async function () {

io.init(onDbReady);

process.on('message', m => {
process.on('message', async m => {
if (m.module) {
let instances = instancer.instances;
let iLen = instances.length;
@@ -103,7 +103,7 @@ process.on('message', m => {
} else if (m.threadModule)
global[m.threadModule][m.method](m.data);
else if (m.method)
instancer[m.method](m.args);
await instancer[m.method](m.args);
else if (m.event)
eventEmitter.emit(m.event, m.data);
});

Loading…
Cancel
Save