Преглед на файлове

replaced extend with deepclone on the server

tags/v0.2.1^2
big bad waffle преди 5 години
родител
ревизия
aec71f823e
променени са 55 файла, в които са добавени 504 реда и са изтрити 127 реда
  1. +2
    -2
      src/server/components/auth.js
  2. +1
    -1
      src/server/components/chatter.js
  3. +1
    -1
      src/server/components/components.js
  4. +328
    -0
      src/server/components/cpnAggro.js
  5. +4
    -4
      src/server/components/dialogue.js
  6. +1
    -1
      src/server/components/effects.js
  7. +2
    -2
      src/server/components/equipment.js
  8. +2
    -2
      src/server/components/extensions/factionVendor.js
  9. +1
    -1
      src/server/components/extensions/socialCommands.js
  10. +2
    -2
      src/server/components/gatherer.js
  11. +7
    -7
      src/server/components/inventory.js
  12. +2
    -2
      src/server/components/player.js
  13. +1
    -1
      src/server/components/prophecies.js
  14. +3
    -3
      src/server/components/reputation.js
  15. +3
    -3
      src/server/components/spellbook.js
  16. +1
    -1
      src/server/components/stats.js
  17. +4
    -4
      src/server/components/trade.js
  18. +2
    -2
      src/server/components/workbench.js
  19. +1
    -1
      src/server/config/eventPhases/phaseKillMob.js
  20. +1
    -1
      src/server/config/eventPhases/phaseModifyDialogue.js
  21. +1
    -1
      src/server/config/factions/anglers.js
  22. +1
    -1
      src/server/config/loginRewards.js
  23. +3
    -3
      src/server/config/maps/fjolarok/events/fishingTournament.js
  24. +2
    -2
      src/server/config/quests/questBuilder.js
  25. +1
    -1
      src/server/config/recipes/cooking.js
  26. +1
    -1
      src/server/config/skins.js
  27. +3
    -3
      src/server/events/events.js
  28. +1
    -1
      src/server/globals.js
  29. +1
    -1
      src/server/items/config/currencies.js
  30. +2
    -2
      src/server/items/enchanter.js
  31. +1
    -1
      src/server/items/generator.js
  32. +1
    -1
      src/server/items/generators/currency.js
  33. +1
    -1
      src/server/items/generators/oldSlots.js
  34. +2
    -2
      src/server/items/generators/quality.js
  35. +3
    -3
      src/server/items/generators/spellbook.js
  36. +3
    -3
      src/server/items/generators/stats.js
  37. +1
    -1
      src/server/items/generators/types.js
  38. +1
    -1
      src/server/items/salvager.js
  39. +48
    -0
      src/server/misc/clone.js
  40. +1
    -1
      src/server/misc/mail.js
  41. +1
    -1
      src/server/misc/random.js
  42. +5
    -5
      src/server/mods/event-halloween/index.js
  43. +6
    -6
      src/server/mods/event-xmas/index.js
  44. +2
    -2
      src/server/mods/event-xmas/maps/fjolarok/events/xmas.js
  45. +2
    -2
      src/server/mods/feature-cards/cards.js
  46. +3
    -3
      src/server/objects/objBase.js
  47. +2
    -2
      src/server/objects/objects.js
  48. +0
    -1
      src/server/package.json
  49. +13
    -13
      src/server/world/instancer.js
  50. +7
    -5
      src/server/world/map.js
  51. +3
    -3
      src/server/world/mobBuilder.js
  52. +5
    -5
      src/server/world/randomMap.js
  53. +3
    -3
      src/server/world/resourceSpawner.js
  54. +4
    -4
      src/server/world/spawners.js
  55. +1
    -1
      src/server/world/worker.js

+ 2
- 2
src/server/components/auth.js Целия файл

@@ -101,7 +101,7 @@ module.exports = {
simple.components.spliceWhere(c => c.type === 'stash');

let stats = simple.components.find(c => c.type === 'stats');
stats.values = extend(true, {}, stats.values);
stats.values = extend({}, stats.values);

let social = simple.components.find(c => c.type === 'social');
delete social.party;
@@ -140,7 +140,7 @@ module.exports = {
delete extensionObj.callback;
}

extend(true, simple, extensionObj);
extend(simple, extensionObj);

io.set({
ent: this.charname,


+ 1
- 1
src/server/components/chatter.js Целия файл

@@ -9,7 +9,7 @@ module.exports = {
global: false,

init: function (blueprint) {
this.chats = extend(true, [], blueprint.chats);
this.chats = extend([], blueprint.chats);
this.cd = ~~(Math.random() * this.cdMax);

for (let p in blueprint) {


+ 1
- 1
src/server/components/components.js Целия файл

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

onGetComponent: function (template) {
template = extend(true, {}, componentBase, template);
template = extend({}, componentBase, template);
this.components[template.type] = template;
}
};

+ 328
- 0
src/server/components/cpnAggro.js Целия файл

@@ -0,0 +1,328 @@
module.exports = class Aggro {
constructor () {
this.type = 'aggro';
this.range = 7;
this.faction = null;
this.physics = null;
this.list = [];
this.ignoreList = [];
}

init (blueprint) {
this.physics = this.obj.instance.physics;

blueprint = blueprint || {};

if (blueprint.faction)
this.faction = blueprint.faction;

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

if (this.physics.width > 0)
this.move();
}

simplify (self) {
return {
type: 'aggro',
faction: this.faction
};
}

move () {
if (this.obj.dead)
return;

let result = {
success: true
};
this.obj.fireEvent('beforeAggro', result);
if (!result.success)
return;

let obj = this.obj;

//If we're attacking something, don't try and look for more trouble. SAVE THE CPU!
// this only counts for mobs, players can have multiple attackers
let list = this.list;
if (obj.isMob) {
let lLen = list.length;
for (let i = 0; i < lLen; i++) {
let l = list[i];

let lThreat = l.obj.aggro.getHighest();
if (lThreat) {
l.obj.aggro.list.forEach(function (a) {
a.obj.aggro.unIgnore(lThreat);
});
}

l.obj.aggro.unIgnore(obj);
if (l.threat > 0)
return;
}
} else {
let lLen = list.length;
for (let i = 0; i < lLen; i++) {
let targetAggro = list[i].obj.aggro;
//Maybe the aggro component has been removed?
if (targetAggro)
targetAggro.unIgnore(obj);
}
}

let x = obj.x;
let y = obj.y;

//find mobs in range
let range = this.range;
let inRange = this.physics.getArea(x - range, y - range, x + range, y + range, (c => (((!c.player) || (!obj.player)) && (!obj.dead) && (c.aggro) && (c.aggro.willAutoAttack(obj)))));

if (inRange.length === 0)
return;

let iLen = inRange.length;
for (let i = 0; i < iLen; i++) {
let enemy = inRange[i];

//The length could change
let lLen = list.length;
for (let j = 0; j < lLen; j++) {
//Set the enemy to null so we need we need to continue
if (list[j].obj === enemy)
enemy = null;
}
if (!enemy)
continue;

//Do we have LoS?
if (!this.physics.hasLos(x, y, enemy.x, enemy.y))
continue;

if (enemy.aggro.tryEngage(obj))
this.tryEngage(enemy, 0);
}
}

canAttack (target) {
let obj = this.obj;
if (target === obj)
return false;
else if ((target.player) && (obj.player)) {
let hasButcher = (obj.prophecies.hasProphecy('butcher')) && (target.prophecies.hasProphecy('butcher'));

if ((!target.social.party) || (!obj.social.party))
return hasButcher;
else if (target.social.partyLeaderId !== obj.social.partyLeaderId)
return hasButcher;
return false;
} else if ((target.follower) && (target.follower.master.player) && (obj.player))
return false;
else if (obj.player)
return true;
else if (target.aggro.faction !== obj.aggro.faction)
return true;
else if (!!target.player !== !!obj.player)
return true;
}

willAutoAttack (target) {
if (this.obj === target)
return false;

let faction = target.aggro.faction;
if (!faction || !this.faction)
return false;

let rep = this.obj.reputation;
if (!rep) {
let targetRep = target.reputation;
if (!targetRep)
return false;
return (targetRep.getTier(this.faction) < 3);
}

return (rep.getTier(faction) < 3);
}

ignore (obj) {
this.ignoreList.spliceWhere(o => o === obj);
this.ignoreList.push(obj);
}

unIgnore (obj) {
this.ignoreList.spliceWhere(o => o === obj);
}

tryEngage (obj, amount, threatMult) {
//Don't aggro yourself, stupid
if (obj === this.obj)
return;

let result = {
success: true
};
this.obj.fireEvent('beforeAggro', result);
if (!result.success)
return false;

//Mobs shouldn't aggro players that are too far from their home
let mob = this.obj.mob;
if (!mob)
mob = obj.mob;
if (mob) {
let notMob = (obj === mob) ? this.obj : obj;
if (!mob.canChase(notMob))
return false;
}

let oId = obj.id;
let list = this.list;

amount = amount || 0;
threatMult = threatMult || 1;

let exists = list.find(l => l.obj.id === oId);
if (exists) {
exists.damage += amount;
exists.threat += amount * threatMult;
} else {
let l = {
obj: obj,
damage: amount,
threat: amount * threatMult
};

list.push(l);
}

//this.sortThreat();

return true;
}

getFirstAttacker () {
let first = this.list.find(l => ((l.obj.player) && (l.damage > 0)));
if (first)
return first.obj;
return null;
}

die () {
let list = this.list;
let lLen = list.length;

for (let i = 0; i < lLen; i++) {
let l = list[i];
if (!l) {
lLen--;
continue;
}
//Maybe the aggro component was removed?
let targetAggro = l.obj.aggro;
if (targetAggro) {
targetAggro.unAggro(this.obj);
i--;
lLen--;
}
}

this.list = [];
}

unAggro (obj, amount) {
let list = this.list;
let lLen = list.length;

for (let i = 0; i < lLen; i++) {
let l = list[i];

if (l.obj !== obj)
continue;

if (!amount) {
list.splice(i, 1);
obj.aggro.unAggro(this.obj);
break;
} else {
l.threat -= amount;
if (l.threat <= 0) {
list.splice(i, 1);
obj.aggro.unAggro(this.obj);
break;
}
}
}

this.ignoreList.spliceWhere(o => o === obj);

//Stuff like cocoons don't have spellbooks
if (this.obj.spellbook)
this.obj.spellbook.unregisterCallback(obj.id, true);

if ((this.list.length === 0) && (this.obj.mob) && (!this.obj.follower))
this.obj.stats.resetHp();
}

sortThreat () {
this.list.sort(function (a, b) {
return (b.threat - a.threat);
});
}

getHighest () {
if (this.list.length === 0)
return null;

let list = this.list;
let lLen = list.length;

let highest = null;
let closest = 99999;

let thisObj = this.obj;
let x = thisObj.x;
let y = thisObj.y;

for (let i = 0; i < lLen; i++) {
let l = list[i];
let obj = l.obj;

if (this.ignoreList.some(o => o === obj))
continue;

if (!highest || l.threat > highest.threat) {
highest = l;
closest = Math.max(Math.abs(x - obj.x), Math.abs(y - obj.y));
} else if (l.threat === highest.threat) {
let distance = Math.max(Math.abs(x - obj.x), Math.abs(y - obj.y));
if (distance < closest) {
highest = l;
closest = distance;
}
}
}

if (highest)
return highest.obj;
//We have aggro but can't reach our target. Don't let the mob run away as if not in combat!
return true;
}

update () {
let list = this.list;
let lLen = list.length;

for (let i = 0; i < lLen; i++) {
let l = list[i];
if (l.obj.destroyed) {
this.unAggro(l.obj);
i--;
lLen--;
}
}
}
};

+ 4
- 4
src/server/components/dialogue.js Целия файл

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

if (stateConfig.cpn) {
let cpn = sourceObj[stateConfig.cpn];
let newArgs = extend(true, [], stateConfig.args);
let newArgs = extend([], stateConfig.args);
newArgs.push(this.obj);
result = cpn[stateConfig.method].apply(cpn, newArgs);

@@ -102,14 +102,14 @@ module.exports = {
return this.getState(sourceObj, stateConfig.goto.failure);
}
if (result) {
useMsg = extend(true, [], useMsg);
useMsg = extend([], useMsg);
useMsg[0].msg = result;
} else
return null;
} else if (stateConfig.method) {
let methodResult = stateConfig.method.call(this.obj, sourceObj);
if (methodResult) {
useMsg = extend(true, [], useMsg);
useMsg = extend([], useMsg);
useMsg[0].msg = methodResult;
}

@@ -191,7 +191,7 @@ module.exports = {
teleport: function (msg) {
this.obj.syncer.set(true, 'dialogue', 'state', null);

let portal = extend(true, {}, require('./portal'), msg);
let portal = extend({}, require('./portal'), msg);
portal.collisionEnter(this.obj);
},



+ 1
- 1
src/server/components/effects.js Целия файл

@@ -159,7 +159,7 @@ module.exports = {
typeTemplate = require('../' + result.url);
}

let builtEffect = extend(true, {}, effectTemplate, typeTemplate);
let builtEffect = extend({}, effectTemplate, typeTemplate);
for (let p in options)
builtEffect[p] = options[p];


+ 2
- 2
src/server/components/equipment.js Целия файл

@@ -136,7 +136,7 @@ module.exports = {
else {
let result = item;
if (item.effects) {
result = extend(true, {}, item);
result = extend({}, item);
result.effects = result.effects.map(e => ({
factionId: e.factionId,
text: e.text,
@@ -204,7 +204,7 @@ module.exports = {
} else if (!item.effects)
this.obj.syncer.setArray(true, 'inventory', 'getItems', item);
else {
let result = extend(true, {}, item);
let result = extend({}, item);
result.effects = result.effects.map(e => ({
factionId: e.factionId,
text: e.text,


+ 2
- 2
src/server/components/extensions/factionVendor.js Целия файл

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

let result = list.items
.map(function (i) {
let item = extend(true, {}, i);
let item = extend({}, i);

if (item.effects) {
item.stats = {
@@ -146,7 +146,7 @@ module.exports = {
for (let i = 0; i < eLen; i++) {
let e = extra[i];

let item = extend(true, {}, e);
let item = extend({}, e);

if (item.type === 'skin') {
let skinBlueprint = skins.getBlueprint(item.id);


+ 1
- 1
src/server/components/extensions/socialCommands.js Целия файл

@@ -304,7 +304,7 @@ module.exports = {
if (s === 'tool')
return;

let newConfig = extend(true, {}, config, {
let newConfig = extend({}, config, {
slot: s
});



+ 2
- 2
src/server/components/gatherer.js Целия файл

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

let resourceNode = gathering.resourceNode;
let gatherResult = extend(true, {
let gatherResult = extend({
obj: gathering
}, {
nodeType: resourceNode.nodeType,
@@ -210,7 +210,7 @@ module.exports = {
},

enter: function (node) {
let gatherResult = extend(true, {
let gatherResult = extend({
nodeName: node.name
});
this.obj.instance.eventEmitter.emitNoSticky('beforeEnterPool', gatherResult, this.obj);


+ 7
- 7
src/server/components/inventory.js Целия файл

@@ -76,7 +76,7 @@ module.exports = {
type: 'inventory',
items: this.items
.map(function (i) {
let item = extend(true, {}, i);
let item = extend({}, i);

if (item.effects) {
item.effects = item.effects.map(e => ({
@@ -237,7 +237,7 @@ module.exports = {
else if ((!item.quantity) || (item.quantity <= msg.stackSize) || (msg.stackSize < 1))
return;

let newItem = extend(true, {}, item);
let newItem = extend({}, item);
item.quantity -= msg.stackSize;
newItem.quantity = msg.stackSize;

@@ -372,7 +372,7 @@ module.exports = {
if (!stash.active)
return;

let clonedItem = extend(true, {}, item);
let clonedItem = extend({}, item);
this.destroyItem(id, null, true);
stash.deposit(clonedItem);
},
@@ -501,7 +501,7 @@ module.exports = {
return;
}

this.obj.instance.mail.sendMail(msg.recipient, [extend(true, {}, item)]);
this.obj.instance.mail.sendMail(msg.recipient, [extend({}, item)]);

this.destroyItem(item.id);

@@ -675,7 +675,7 @@ module.exports = {
ttl: this.obj.instance.instanced ? -1 : 1710
},
cpnInventory: {
items: extend(true, [], items)
items: extend([], items)
}
}
}]);
@@ -843,7 +843,7 @@ module.exports = {
} else if (!item.effects)
this.obj.syncer.setArray(true, 'inventory', 'getItems', item, true);
else {
let result = extend(true, {}, item);
let result = extend({}, item);
result.effects = result.effects.map(e => ({
factionId: e.factionId,
text: e.text,
@@ -913,7 +913,7 @@ module.exports = {
let blueprint = this.blueprint;
let magicFind = (blueprint.magicFind || 0);

let savedItems = extend(true, [], this.items);
let savedItems = extend([], this.items);
this.items = [];

let dropEvent = {


+ 2
- 2
src/server/components/player.js Целия файл

@@ -24,7 +24,7 @@ module.exports = {
if (character.dead)
obj.dead = true;

extend(true, obj, {
extend(obj, {
layerName: 'mobs',
cell: character.cell,
sheetName: character.sheetName,
@@ -44,7 +44,7 @@ module.exports = {
roles.onBeforePlayerEnterGame(obj, character);

let blueprintStats = character.components.find(c => c.type === 'stats') || {};
extend(true, blueprintStats, classes.stats[obj.class]);
extend(blueprintStats, classes.stats[obj.class]);
blueprintStats.values.hpMax = (blueprintStats.values.level || 1) * 32.7;
if (!blueprintStats.values.hp)
blueprintStats.values.hp = blueprintStats.values.hpMax;


+ 1
- 1
src/server/components/prophecies.js Целия файл

@@ -15,7 +15,7 @@ module.exports = {
else if (this.list.some(l => (l.type === p)))
return;

let prophecy = extend(true, {}, template);
let prophecy = extend({}, template);
prophecy.obj = this.obj;
prophecy.init();



+ 3
- 3
src/server/components/reputation.js Целия файл

@@ -39,7 +39,7 @@ module.exports = {
if (!factionBlueprint)
return;

factionBlueprint = extend(true, {}, factionBase, factionBlueprint);
factionBlueprint = extend({}, factionBase, factionBlueprint);

this.factions[factionBlueprint.id] = factionBlueprint;

@@ -195,7 +195,7 @@ module.exports = {
.map(function (l) {
let result = {};
let blueprint = this.getBlueprint(l.id);
extend(true, result, l, blueprint);
extend(result, l, blueprint);

return result;
}, this);
@@ -216,7 +216,7 @@ module.exports = {

if (full) {
let blueprint = this.getBlueprint(factionId);
extend(true, faction, l, blueprint);
extend(faction, l, blueprint);
}

this.obj.syncer.setArray(true, 'reputation', 'modifyRep', faction);


+ 3
- 3
src/server/components/spellbook.js Целия файл

@@ -86,7 +86,7 @@ module.exports = {
if (!typeTemplate.template)
typeTemplate.template = require('../config/spells/spell' + type);

let builtSpell = extend(true, {}, spellTemplate, typeTemplate.template, options);
let builtSpell = extend({}, spellTemplate, typeTemplate.template, options);
builtSpell.obj = this.obj;
builtSpell.baseDamage = builtSpell.damage;
builtSpell.damage += (options.damageAdd || 0);
@@ -108,7 +108,7 @@ module.exports = {
animation = animations.classes;

if ((animation) && (animation[this.obj.cell]) && (animation[this.obj.cell][animationName])) {
builtSpell.animation = extend(true, {}, animation[this.obj.cell][animationName]);
builtSpell.animation = extend({}, animation[this.obj.cell][animationName]);
builtSpell.animation.name = animationName;
} else
builtSpell.animation = null;
@@ -155,7 +155,7 @@ module.exports = {

runeSpell.values = {};

let builtSpell = extend(true, {
let builtSpell = extend({
type: runeSpell.type,
values: {}
}, playerSpell, playerSpellConfig, runeSpell);


+ 1
- 1
src/server/components/stats.js Целия файл

@@ -640,7 +640,7 @@ module.exports = {
delete this.sessionDuration;
}

let values = extend(true, {}, this.values);
let values = extend({}, this.values);
values.hp = this.values.hp;
values.mana = this.values.mana;



+ 4
- 4
src/server/components/trade.js Целия файл

@@ -23,7 +23,7 @@ module.exports = {
this.gold = blueprint.gold;

(blueprint.forceItems || []).forEach(function (f, i) {
let item = extend(true, {}, f);
let item = extend({}, f);

let id = 0;
this.items.forEach(function (checkItem) {
@@ -201,7 +201,7 @@ module.exports = {
if (!item.infinite)
this.obj.syncer.setArray(true, 'trade', 'removeItems', item.id);

let clonedItem = extend(true, {}, item);
let clonedItem = extend({}, item);
if (item.worth.currency)
clonedItem.worth = 0;
if ((item.stats) && (item.stats.stats)) {
@@ -295,7 +295,7 @@ module.exports = {

let itemList = this.obj.inventory.items
.filter(i => ((i.worth > 0) && (!i.eq)));
itemList = extend(true, [], itemList);
itemList = extend([], itemList);

this.obj.syncer.set(true, 'trade', 'sellList', {
markup: target.trade.markup.buy,
@@ -341,7 +341,7 @@ module.exports = {
let reputation = requestedBy.reputation;

let items = this.items.map(function (i) {
let item = extend(true, {}, i);
let item = extend({}, i);

if (item.factions) {
item.factions = item.factions.map(function (f) {


+ 2
- 2
src/server/components/workbench.js Целия файл

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

const items = crafter.inventory.items;

let sendRecipe = extend(true, {}, recipe);
let sendRecipe = extend({}, recipe);
(sendRecipe.materials || []).forEach(function (m) {
m.need = !items.some(i => (
(
@@ -156,7 +156,7 @@ module.exports = {
obj.inventory.destroyItem(findItem.id, m.quantity);
});

let item = extend(true, {}, recipe.item);
let item = extend({}, recipe.item);
item.description += `<br /><br />(Crafted by ${obj.name})`;

obj.inventory.getItem(item);


+ 1
- 1
src/server/config/eventPhases/phaseKillMob.js Целия файл

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

if (percentage) {
let cpn = extend(true, cpnDeathStopper, {
let cpn = extend(cpnDeathStopper, {
percentage: percentage
});
o.components.push(cpn);


+ 1
- 1
src/server/config/eventPhases/phaseModifyDialogue.js Целия файл

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

addStates: function (dialogue, states) {
for (let s in states) {
let source = extend(true, {}, states[s]);
let source = extend({}, states[s]);
let target = dialogue[s];
if (!target) {
dialogue[s] = source;


+ 1
- 1
src/server/config/factions/anglers.js Целия файл

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

let pick = gatherResult.items[~~(Math.random() * gatherResult.items.length)];
gatherResult.items.push(extend(true, {}, pick));
gatherResult.items.push(extend({}, pick));
}
}
},


+ 1
- 1
src/server/config/loginRewards.js Целия файл

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

let item = items.find(f => (f.name === pick.name));
if (!item) {
item = extend(true, {
item = extend({
material: true,
quality: p
}, pick);


+ 3
- 3
src/server/config/maps/fjolarok/events/fishingTournament.js Целия файл

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

let rewardQty = rewardCounts[rank] || consolationQty;

event.rewards[f.owner] = [extend(true, {
event.rewards[f.owner] = [extend({
quantity: rewardQty
}, tpl)];
}
@@ -149,7 +149,7 @@ module.exports = {
.forEach(function (f, i) {
if (i === 0) {
f.owner = source.name;
tgtInventory.getItem(extend(true, {}, f));
tgtInventory.getItem(extend({}, f));
}

srcInventory.destroyItem(f.id);
@@ -348,7 +348,7 @@ module.exports = {
return;

gatherResult.items.forEach(function (g) {
extend(true, g, {
extend(g, {
name: 'Ancient Carp',
sprite: [11, 4],
noDrop: true


+ 2
- 2
src/server/config/quests/questBuilder.js Целия файл

@@ -24,7 +24,7 @@ module.exports = {
if (!zoneTemplate)
zoneTemplate = globalQuests;

let config = extend(true, {}, zoneTemplate);
let config = extend({}, zoneTemplate);
this.instance.eventEmitter.emit('onBeforeGetQuests', config);
if (config.infini.length === 0)
return;
@@ -38,7 +38,7 @@ module.exports = {
let pickType = pickQuest.type[0].toUpperCase() + pickQuest.type.substr(1);
let questClass = require('../../config/quests/templates/quest' + pickType);

let quest = extend(true, {}, pickQuest, questTemplate, questClass, template);
let quest = extend({}, pickQuest, questTemplate, questClass, template);

if (template)
quest.xp = template.xp;


+ 1
- 1
src/server/config/recipes/cooking.js Целия файл

@@ -26,7 +26,7 @@ const baseRecipes = {
};

const buildRecipe = function (recipeName, itemName, effectAmount, materialName) {
return extend(true, {}, baseRecipes[recipeName], {
return extend({}, baseRecipes[recipeName], {
item: {
name: itemName,
effects: [{


+ 1
- 1
src/server/config/skins.js Целия файл

@@ -120,7 +120,7 @@ module.exports = {
return ((config[s].default) || (skins.some(f => ((f === s) || (f === '*')))));
})
.map(function (s) {
let res = extend(true, {}, config[s]);
let res = extend({}, config[s]);
res.id = s;
return res;
});


+ 3
- 3
src/server/events/events.js Целия файл

@@ -20,7 +20,7 @@ module.exports = {
files.forEach(function (f) {
let e = require(f);
if (!e.disabled)
this.configs.push(extend(true, {}, e));
this.configs.push(extend({}, e));
}, this);
},

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

let event = {
id: this.nextId++,
config: extend(true, {}, config),
config: extend({}, config),
phases: [],
participators: [],
objects: [],
@@ -237,7 +237,7 @@ module.exports = {

let phaseFile = 'phase' + p.type[0].toUpperCase() + p.type.substr(1);
let typeTemplate = require('../config/eventPhases/' + phaseFile);
let phase = extend(true, {
let phase = extend({
instance: this.instance,
event: event
}, phaseTemplate, typeTemplate, p);


+ 1
- 1
src/server/globals.js Целия файл

@@ -1,7 +1,7 @@
/* global io, extend, cons, _, atlas, leaderboard, clientConfig */

global.io = require('./security/io');
global.extend = require('extend');
global.extend = require('./misc/clone');
global.cons = require('./security/connections');
global._ = require('./misc/helpers');
global.atlas = require('./world/atlas');


+ 1
- 1
src/server/items/config/currencies.js Целия файл

@@ -54,7 +54,7 @@ module.exports = {
let currencies = this.currencies;
let pick = Object.keys(currencies).find(o => (currencies[o].action === action));

return extend(true, {
return extend({
name: pick
}, currencies[pick]);
}


+ 2
- 2
src/server/items/enchanter.js Целия файл

@@ -122,7 +122,7 @@ module.exports = {
}
newItem.enchantedStats = enchantedStats;

extend(true, item, newItem);
extend(item, newItem);
} else if (msg.action === 'reforge') {
if (!item.spell)
return;
@@ -134,7 +134,7 @@ module.exports = {
generatorSpells.generate(item, {
spellName: spellName
});
item.spell = extend(true, oldSpell, item.spell);
item.spell = extend(oldSpell, item.spell);
} else if (msg.action === 'scour') {
if (!item.power)
return;


+ 1
- 1
src/server/items/generator.js Целия файл

@@ -58,7 +58,7 @@ module.exports = {
item.noDestroy = blueprint.noDestroy;
materialGenerators.forEach(g => g.generate(item, blueprint));
} else if (blueprint.type === 'mtx') {
item = extend(true, {}, blueprint);
item = extend({}, blueprint);
delete item.chance;
} else {
generators.forEach(g => g.generate(item, blueprint));


+ 1
- 1
src/server/items/generators/currency.js Целия файл

@@ -17,6 +17,6 @@ module.exports = {
pick = Object.keys(configCurrencies.currencies).find(c => (c.toLowerCase().indexOf(blueprint.name.toLowerCase()) > -1));

item.name = pick;
extend(true, item, configCurrencies.currencies[pick]);
extend(item, configCurrencies.currencies[pick]);
}
};

+ 1
- 1
src/server/items/generators/oldSlots.js Целия файл

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

let extraStats = this.slots[item.slot].extraStats;
if (extraStats) {
extraStats = extend(true, {}, extraStats);
extraStats = extend({}, extraStats);
if (!(extraStats instanceof Array))
extraStats = [extraStats];



+ 2
- 2
src/server/items/generators/quality.js Целия файл

@@ -15,13 +15,13 @@ module.exports = {
return;
}

let qualities = extend(true, [], this.qualities);
let qualities = extend([], this.qualities);

let magicFind = (blueprint.magicFind || 0);
if (!(magicFind instanceof Array))
magicFind = [magicFind];
else
magicFind = extend(true, [], magicFind);
magicFind = extend([], magicFind);

let bonusMagicFind = blueprint.bonusMagicFind || 0;



+ 3
- 3
src/server/items/generators/spellbook.js Целия файл

@@ -37,7 +37,7 @@ module.exports = {
item.stats = {};

if (blueprint.spellConfig)
spellAesthetic = extend(true, {}, spellAesthetic, blueprint.spellConfig);
spellAesthetic = extend({}, spellAesthetic, blueprint.spellConfig);

item.spell = {
name: spellAesthetic.name || 'Weapon Damage',
@@ -47,12 +47,12 @@ module.exports = {
};

if (blueprint.spellConfig)
extend(true, item.spell, blueprint.spellConfig);
extend(item.spell, blueprint.spellConfig);

if (item.type) {
let typeConfig = configTypes.types[item.slot][item.type];
if (typeConfig)
spell = extend(true, {}, spell, typeConfig.spellConfig);
spell = extend({}, spell, typeConfig.spellConfig);
}

let propertyPerfection = [];


+ 3
- 3
src/server/items/generators/stats.js Целия файл

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

if (blueprint.stats) {
let useStats = extend(true, [], blueprint.stats);
let useStats = extend([], blueprint.stats);
let addStats = Math.min(statCount, blueprint.stats.length);
for (let i = 0; i < addStats; i++) {
let choice = useStats[~~(Math.random() * useStats.length)];
@@ -521,7 +521,7 @@ module.exports = {

buildStat: function (item, blueprint, stat, result, isImplicit) {
let slotStats = this.slots[item.slot] || {};
let statOptions = extend(true, {}, this.stats, slotStats || {});
let statOptions = extend({}, this.stats, slotStats || {});

for (let p in statOptions) {
if ((!slotStats[p]) || (slotStats[p].ignore))
@@ -595,7 +595,7 @@ module.exports = {

rescale: function (item, level) {
let stats = item.stats;
let nStats = extend(true, {}, stats);
let nStats = extend({}, stats);
let bpt = {
statMult: {}
};


+ 1
- 1
src/server/items/generators/types.js Целия файл

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

item.type = type;
item.sprite = extend(true, [], blueprint.sprite || typeBlueprint.sprite);
item.sprite = extend([], blueprint.sprite || typeBlueprint.sprite);
if (typeBlueprint.spritesheet)
item.spritesheet = typeBlueprint.spritesheet;



+ 1
- 1
src/server/items/salvager.js Целия файл

@@ -119,7 +119,7 @@ module.exports = {
exists.quantity = Math.max(exists.quantity, m.quantity);
exists.qualityMult = Math.max(exists.qualityMult, m.qualityMult);
} else
materials.push(extend(true, {}, m));
materials.push(extend({}, m));
});
});



+ 48
- 0
src/server/misc/clone.js Целия файл

@@ -0,0 +1,48 @@
const oArray = '[object Array]';

let cloneRecursive = function (o, newO) {
let i;
if (typeof o !== 'object')
return o;
if (!o)
return o;
if (Object.prototype.toString.apply(o) === oArray) {
if (!newO)
newO = [];

let oLen = o.length;
for (i = 0; i < oLen; i++) {
if (newO[i] === undefined)
newO[i] = cloneRecursive(o[i]);
else
cloneRecursive(o[i], newO[i]);
}
return newO;
}

if (!newO)
newO = {};
for (i in o) {
if (o.hasOwnProperty(i)) {
if (newO[i] === undefined)
newO[i] = cloneRecursive(o[i]);
else
newO[i] = cloneRecursive(o[i], newO[i]);
}
}
return newO;
};

let clone = function (o) {
let aLen = arguments.length;
for (let i = 1; i < aLen; i++)
cloneRecursive(arguments[i], o);

return o;
};

module.exports = clone;

+ 1
- 1
src/server/misc/mail.js Целия файл

@@ -108,7 +108,7 @@ module.exports = {
queue = this.queue[playerName] = [];
items.forEach(function (i) {
queue.push(extend(true, {}, i));
queue.push(extend({}, i));
});

return;


+ 1
- 1
src/server/misc/random.js Целия файл

@@ -11,7 +11,7 @@ a-1))break}else if(d<=Math.exp(-h))break;return h*c}};Random.prototype.normal=fu
Random.prototype.triangular=function(a,c,b){var f=(b-a)/(c-a),e=this.random();return e<=f?a+Math.sqrt(e*(c-a)*(b-a)):c-Math.sqrt((1-e)*(c-a)*(c-b))};Random.prototype.uniform=function(a,c){return a+this.random()*(c-a)};Random.prototype.weibull=function(a,c){var b=1-this.random();return a*Math.pow(-Math.log(b),1/c)};

global.random = new Random();
extend(true, random, {
extend(random, {
norm: function(low, high) {
var mid = low + ((high - low) / 2);
var range = mid - low;


+ 5
- 5
src/server/mods/event-halloween/index.js Целия файл

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

onBeforeGetFactions: function (mappings) {
extend(true, mappings, {
extend(mappings, {
pumpkinSailor: './factions/pumpkinSailor'
});
},
@@ -106,7 +106,7 @@ module.exports = {
},

onBeforeGetHerbConfig: function (herbs) {
extend(true, herbs, {
extend(herbs, {
'Tiny Pumpkin': {
sheetName: 'objects',
cell: 167,
@@ -189,7 +189,7 @@ module.exports = {
let mapScale = this.mapFile.tilesets[0].tileheight;

layer.objects.forEach(function (l) {
let newO = extend(true, {}, l);
let newO = extend({}, l);
newO.x += (offset.x * mapScale);
newO.y += (offset.y * mapScale);

@@ -227,7 +227,7 @@ module.exports = {
onAfterGetZone: function (zone, config) {
try {
let modZone = require('./maps/' + zone + '/zone.js');
extend(true, config, modZone);
extend(config, modZone);
} catch (e) {

}
@@ -236,7 +236,7 @@ module.exports = {
onBeforeGetDialogue: function (zone, config) {
try {
let modDialogue = require('./maps/' + zone + '/dialogues.js');
extend(true, config, modDialogue);
extend(config, modDialogue);
} catch (e) {

}


+ 6
- 6
src/server/mods/event-xmas/index.js Целия файл

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

onBeforeGetCardsConfig: function (config) {
extend(true, config, {
extend(config, {
'Cheer and Spear': {
chance: 40,
reward: 'Rare Festive Spear',
@@ -202,7 +202,7 @@ module.exports = {
},

onBeforeGetFactions: function (mappings) {
extend(true, mappings, {
extend(mappings, {
theWinterMan: `${this.relativeFolderName}/factions/theWinterMan`
});
},
@@ -217,7 +217,7 @@ module.exports = {
let mapScale = this.mapFile.tilesets[0].tileheight;

layer.objects.forEach(function (l) {
let newO = extend(true, {}, l);
let newO = extend({}, l);
newO.x += (offset.x * mapScale);
newO.y += (offset.y * mapScale);

@@ -250,14 +250,14 @@ module.exports = {
onAfterGetZone: function (zone, config) {
try {
let modZone = require('./maps/' + zone + '/zone.js');
extend(true, config, modZone);
extend(config, modZone);
} catch (e) {

}
},

onBeforeGetHerbConfig: function (herbs) {
extend(true, herbs, {
extend(herbs, {
'Festive Gift': {
sheetName: 'objects',
cell: 166,
@@ -332,7 +332,7 @@ module.exports = {
onBeforeGetDialogue: function (zone, config) {
try {
let modDialogue = require('./maps/' + zone + '/dialogues.js');
extend(true, config, modDialogue);
extend(config, modDialogue);
} catch (e) {

}


+ 2
- 2
src/server/mods/event-xmas/maps/fjolarok/events/xmas.js Целия файл

@@ -152,7 +152,7 @@ module.exports = {
let pick = pool[~~(Math.random() * pool.length)];
let blueprint = rewards.find(r => (r.name === pick));

inventory.getItem(extend(true, {}, blueprint));
inventory.getItem(extend({}, blueprint));

inventory.destroyItem(snowflakes.id, 15);
}
@@ -242,7 +242,7 @@ module.exports = {
let zoneFile = require('../../' + zone + '/zone.js');
let override = _.getDeepProperty(zoneFile, ['mobs', mobName]);
if (override)
extend(true, blueprint, override);
extend(blueprint, override);
} catch (e) {}
},



+ 2
- 2
src/server/mods/feature-cards/cards.js Целия файл

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

let mobLevel = mob.stats.values.level;

let configs = extend(true, {}, config);
let configs = extend({}, config);
looter.instance.eventEmitter.emit('onBeforeGetCardsConfig', configs);

Object.keys(configs).forEach(function (c) {
@@ -110,7 +110,7 @@ module.exports = {
},

getReward: function (looter, set) {
let configs = extend(true, {}, config);
let configs = extend({}, config);
looter.instance.eventEmitter.emit('onBeforeGetCardsConfig', configs);

let reward = configs[set].reward;


+ 3
- 3
src/server/objects/objBase.js Целия файл

@@ -10,12 +10,12 @@ module.exports = {
if (!cpn) {
let template = components.components[type];
if (!template) {
template = extend(true, {
template = extend({
type: type
}, blueprint || {});
}

cpn = extend(true, {}, template);
cpn = extend({}, template);
cpn.obj = this;

this.components.push(cpn);
@@ -44,7 +44,7 @@ module.exports = {
let template = require('../components/extensions/' + type);
let cpn = this[ext];

extend(true, cpn, template);
extend(cpn, template);

if (template.init)
cpn.init(blueprint);


+ 2
- 2
src/server/objects/objects.js Целия файл

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

build: function (skipPush, clientObj) {
let o = extend(true, {}, objBase);
let o = extend({}, objBase);

if (clientObj)
o.update = null;
@@ -81,7 +81,7 @@ module.exports = {

//Add components (certain ones need to happen first)
//TODO: Clean this part up
let properties = extend(true, {}, l.properties);
let properties = extend({}, l.properties);
['cpnMob'].forEach(function (c) {
let blueprint = properties[c] || null;
if ((blueprint) && (typeof (blueprint) === 'string'))


+ 0
- 1
src/server/package.json Целия файл

@@ -5,7 +5,6 @@
"dependencies": {
"bcrypt-nodejs": "0.0.3",
"express": "^4.13.1",
"extend": "^3.0.0",
"google-spreadsheet": "^2.0.4",
"less-middleware": "^2.0.1",
"mysql": "^2.13.0",


+ 13
- 13
src/server/world/instancer.js Целия файл

@@ -451,33 +451,33 @@ module.exports = {
createInstance: function (objToAdd, transfer) {
let newMap = {
name: map.name,
spawn: extend(true, [], map.spawn),
clientMap: extend(true, {}, map.clientMap)
spawn: extend([], map.spawn),
clientMap: extend({}, map.clientMap)
};
newMap.getSpawnPos = map.getSpawnPos.bind(newMap);

//Hack: We need to actually just always use the instanced eventEmitter
let eventQueue = eventEmitter.queue;
delete eventEmitter.queue;
let newEventEmitter = extend(true, {
let newEventEmitter = extend({
queue: []
}, eventEmitter);
eventEmitter.queue = eventQueue;

let instance = {
id: objToAdd.name + '_' + (+new Date()),
objects: extend(true, {}, objects),
spawners: extend(true, {}, spawners),
syncer: extend(true, {}, syncer),
physics: extend(true, {}, physics),
resourceSpawner: extend(true, {}, resourceSpawner),
objects: extend({}, objects),
spawners: extend({}, spawners),
syncer: extend({}, syncer),
physics: extend({}, physics),
resourceSpawner: extend({}, resourceSpawner),
zoneId: this.zoneId,
zone: map.zone,
closeTtl: null,
questBuilder: extend(true, {}, questBuilder),
events: extend(true, {}, events),
scheduler: extend(true, {}, scheduler),
mail: extend(true, {}, mail),
questBuilder: extend({}, questBuilder),
events: extend({}, events),
scheduler: extend({}, scheduler),
mail: extend({}, mail),
map: newMap,
eventEmitter: newEventEmitter,
instanced: true
@@ -490,7 +490,7 @@ module.exports = {
let onDone = this.instanced.onCreateInstance.bind(this, instance, objToAdd, transfer);

if (map.custom) {
instance.customMap = extend(true, {}, customMap);
instance.customMap = extend({}, customMap);
instance.customMap.load(instance, objToAdd, onDone);
} else
onDone();


+ 7
- 5
src/server/world/map.js Целия файл

@@ -10,6 +10,8 @@ let mapFile = null;
let mapScale = null;
let padding = null;

let ex = require('extend');

module.exports = {
name: null,
layers: [],
@@ -73,7 +75,7 @@ module.exports = {
if (dialogues)
this.zone.dialogues = dialogues;

this.zone = extend(true, {}, globalZone, this.zone);
this.zone = extend({}, globalZone, this.zone);

let resources = this.zone.resources || {};
for (let r in resources)
@@ -112,9 +114,9 @@ module.exports = {
getMapFile: function () {
this.build();

randomMap = extend(true, {}, randomMap);
randomMap = extend({}, randomMap);
this.oldMap = this.layers;
randomMap.templates = extend(true, [], this.rooms);
randomMap.templates = extend([], this.rooms);
randomMap.generateMappings(this);

for (let i = 0; i < this.size.w; i++) {
@@ -333,9 +335,9 @@ module.exports = {

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

if (blueprint.blocking)


+ 3
- 3
src/server/world/mobBuilder.js Целия файл

@@ -42,7 +42,7 @@ module.exports = {
});

let cpnMob = mob.addComponent('mob');
extend(true, cpnMob, {
extend(cpnMob, {
walkDistance: blueprint.walkDistance,
hpMult: blueprint.hpMult || typeDefinition.hpMult,
dmgMult: blueprint.dmgMult || typeDefinition.dmgMult,
@@ -50,7 +50,7 @@ module.exports = {
deathRep: blueprint.deathRep
});

let spells = extend(true, [], blueprint.spells);
let spells = extend([], blueprint.spells);
spells.forEach(function (s) {
if (!s.animation) {
if ((mob.sheetName === 'mobs') && (animations.mobs[mob.cell]))
@@ -143,7 +143,7 @@ module.exports = {
} else {
//TODO: Don't give the mob these items: he'll drop them anyway
drops.blueprints.forEach(function (d) {
let drop = extend(true, {}, d);
let drop = extend({}, d);
d.level = level;
if (drop.type === 'key')
return;


+ 5
- 5
src/server/world/randomMap.js Целия файл

@@ -15,7 +15,7 @@ module.exports = {
this.exitAreas = [];
this.tileMappings = {};
this.bounds = [0, 0, 0, 0];
this.templates = extend(true, [], instance.map.rooms);
this.templates = extend([], instance.map.rooms);

this.setupTemplates(instance.map);
this.generateMappings(instance.map);
@@ -66,7 +66,7 @@ module.exports = {
if (i + j + k === 0)
continue;

let flipped = extend(true, {
let flipped = extend({
flipX: !!i,
flipY: !!j,
rotate: !!k
@@ -128,7 +128,7 @@ module.exports = {
r.map = _.get2dArray(r.width, r.height);
r.tiles = _.get2dArray(r.width, r.height);
r.collisionMap = _.get2dArray(r.width, r.height);
r.oldExits = extend(true, [], r.exits);
r.oldExits = extend([], r.exits);

for (let i = 0; i < w; i++) {
for (let j = 0; j < h; j++) {
@@ -352,7 +352,7 @@ module.exports = {
y: 0,
distance: 0,
isHallway: isHallway,
template: extend(true, {}, template),
template: extend({}, template),
connections: []
};

@@ -442,7 +442,7 @@ module.exports = {
return false;
}

let template = extend(true, {}, templates[this.randInt(0, templates.length)]);
let template = extend({}, templates[this.randInt(0, templates.length)]);

let templateExit = template.exits.filter(function (e) {
let direction = JSON.parse(e.properties.exit);


+ 3
- 3
src/server/world/resourceSpawner.js Целия файл

@@ -42,7 +42,7 @@ module.exports = {
return;
}

blueprint = extend(true, {}, blueprint, herbs[name], {
blueprint = extend({}, blueprint, herbs[name], {
name: name
});

@@ -109,13 +109,13 @@ module.exports = {
if (blueprint.quantity)
quantity = blueprint.quantity[0] + ~~(Math.random() * (blueprint.quantity[1] - blueprint.quantity[0]));

let objBlueprint = extend(true, {}, blueprint, position);
let objBlueprint = extend({}, blueprint, position);
objBlueprint.properties = {
cpnResourceNode: {
nodeType: blueprint.type,
ttl: blueprint.ttl,
xp: this.zone.level * this.zone.level,
blueprint: extend(true, {}, blueprint),
blueprint: extend({}, blueprint),
quantity: quantity
}
};


+ 4
- 4
src/server/world/spawners.js Целия файл

@@ -10,7 +10,7 @@ module.exports = {
this.objects = msg.objects;
this.syncer = msg.syncer;
this.zone = msg.zone;
this.mobBuilder = extend(true, {
this.mobBuilder = extend({
zone: this.zone
}, mobBuilder);
},
@@ -21,7 +21,7 @@ module.exports = {
},

register: function (blueprint, cdMax) {
let spawner = extend(true, {
let spawner = extend({
cdMax: cdMax || 171,
cron: blueprint.cron,
lifetime: blueprint.lifetime,
@@ -40,7 +40,7 @@ module.exports = {
else
this.mobTypes[name]++;

spawner.zonePrint = extend(true, {}, this.zone.mobs.default, this.zone.mobs[name] || {});
spawner.zonePrint = extend({}, this.zone.mobs.default, this.zone.mobs[name] || {});
},

spawn: function (spawner) {
@@ -152,7 +152,7 @@ module.exports = {
if ((l.blueprint.sheetName === 'mobs') || (l.blueprint.sheetName === 'bosses'))
this.setupMob(mob, l.zonePrint, l.blueprint.scaleDrops);
else {
let blueprint = extend(true, {}, this.zone.objects.default, this.zone.objects[name] || {});
let blueprint = extend({}, this.zone.objects.default, this.zone.objects[name] || {});
this.setupObj(mob, blueprint);
}



+ 1
- 1
src/server/world/worker.js Целия файл

@@ -1,4 +1,4 @@
global.extend = require('extend');
global.extend = require('../misc/clone');
global.io = require('../security/io');
global._ = require('../misc/helpers');
global.instancer = require('./instancer');


Зареждане…
Отказ
Запис