@@ -0,0 +1,8 @@ | |||
var extend = require('extend'); | |||
var requirejs = require('requirejs'); | |||
global.extend = extend; | |||
requirejs(['sim'], function (sim) { | |||
sim.init(); | |||
}); |
@@ -0,0 +1,23 @@ | |||
{ | |||
"restartable": "rs", | |||
"ignore": [ | |||
".git", | |||
"node_modules/**/node_modules" | |||
], | |||
"verbose": true, | |||
"execMap": { | |||
"js": "node --harmony" | |||
}, | |||
"events": { | |||
}, | |||
"watch": [ | |||
"*.*", | |||
"../../src/server/config/spellsConfig.js", | |||
"../../src/server/combat/combat.js" | |||
], | |||
"env": { | |||
"NODE_ENV": "development" | |||
}, | |||
"ext": "js json" | |||
} |
@@ -0,0 +1,18 @@ | |||
{ | |||
"name": "isleward-tests", | |||
"version": "0.0.1", | |||
"lockfileVersion": 1, | |||
"requires": true, | |||
"dependencies": { | |||
"extend": { | |||
"version": "3.0.1", | |||
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", | |||
"integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=" | |||
}, | |||
"requirejs": { | |||
"version": "2.3.5", | |||
"resolved": "https://registry.npmjs.org/requirejs/-/requirejs-2.3.5.tgz", | |||
"integrity": "sha512-svnO+aNcR/an9Dpi44C7KSAy5fFGLtmPbaaCeQaklUz8BQhS64tWWIIlvEA5jrWICzlO/X9KSzSeXFnZdBu8nw==" | |||
} | |||
} | |||
} |
@@ -0,0 +1,10 @@ | |||
{ | |||
"name": "isleward-tests", | |||
"version": "0.0.1", | |||
"description": "isleward-tests", | |||
"dependencies": { | |||
"extend": "^3.0.0", | |||
"requirejs": "^2.3.5" | |||
}, | |||
"devDependencies": {} | |||
} |
@@ -0,0 +1,188 @@ | |||
define([ | |||
'../../src/server/config/spellsConfig', | |||
'../../src/server/combat/combat' | |||
], function ( | |||
config, | |||
combat | |||
) { | |||
var spells = config.spells; | |||
var max = true; | |||
var maxTarget = false; | |||
spells['harvest life'] = { | |||
statType: ['str', 'int'], | |||
statMult: 1.34, | |||
element: 'physical', | |||
auto: true, | |||
cdMax: 6, | |||
manaCost: 0, | |||
range: 1, | |||
random: { | |||
damage: [1.5, 5.7], | |||
healPercent: [5, 15] | |||
} | |||
}; | |||
var bloodBarrierMult = 1.25; | |||
spells['skeleton melee'] = { | |||
statType: ['str', 'int'], | |||
statMult: 0.46 * bloodBarrierMult, | |||
element: 'physical', | |||
auto: true, | |||
cdMax: 5, | |||
manaCost: 0, | |||
range: 1, | |||
random: { | |||
damage: [1, 3.8] | |||
} | |||
}; | |||
var level = 5; | |||
var hp = [ | |||
30.07, | |||
30.58, | |||
31.94, | |||
34.61, | |||
39, | |||
45.55, | |||
54.70, | |||
66.86, | |||
82.49, | |||
102, | |||
125.83, | |||
154.42, | |||
188.18, | |||
227.57, | |||
273, | |||
324.91, | |||
383.74, | |||
449.90, | |||
523.85, | |||
606 | |||
]; | |||
var hpMax = [ | |||
91.25, | |||
96.50, | |||
110.75, | |||
138.50, | |||
184.25, | |||
252.50, | |||
347.75, | |||
474.50, | |||
637.25, | |||
840.50, | |||
1088.75, | |||
1386.50, | |||
1738.25, | |||
2148.50, | |||
2621.75, | |||
3162.50, | |||
3775.25, | |||
4464.50, | |||
5234.75, | |||
6090.50 | |||
]; | |||
return { | |||
init: function () { | |||
var res = []; | |||
for (var s in spells) { | |||
var c = spells[s]; | |||
var d = c.random.damage || c.random.healing; | |||
if (!d) | |||
continue; | |||
var damage = d[0]; | |||
if (max) | |||
damage = d[1]; | |||
var config = { | |||
statType: c.statType, | |||
statMult: c.statMult, | |||
element: c.element, | |||
cd: c.cdMax, | |||
damage: damage, | |||
noCrit: true, | |||
noMitigate: !!c.random.healing, | |||
source: { | |||
stats: { | |||
values: { | |||
level: level, | |||
dmgPercent: max ? 20 : 0, | |||
elementArcanePercent: 0, | |||
elementFrostPercent: 0, | |||
elementPoisonPercent: 0, | |||
elementPhysicalPercent: 0, | |||
elementHolyPercent: 0, | |||
elementFirePercent: 0 | |||
} | |||
}, | |||
}, | |||
target: { | |||
stats: { | |||
values: { | |||
armor: maxTarget ? (level * 50) : (level * 20), | |||
elementAllResist: maxTarget ? 100 : 0, | |||
elementArcaneResist: 0, | |||
elementFrostResist: 0, | |||
elementPoisonResist: 0, | |||
elementPhysicalResist: 0, | |||
elementHolyResist: 0, | |||
elementFireResist: 0 | |||
} | |||
} | |||
} | |||
}; | |||
var stat = c.statType; | |||
if (!stat.push) | |||
stat = [stat]; | |||
var minStat = 1 + (0.00477 * Math.pow(level, 2.8)); | |||
var maxStat = 3 + (0.3825 * Math.pow(level, 1.83)); | |||
var mult = (stat.length == 1) ? 1 : 0.5; | |||
stat.forEach(s => config.source.stats.values[s] = (max ? maxStat : minStat) * mult); | |||
var amount = combat.getDamage(config).amount; | |||
var duration = c.random.i_duration; | |||
if (duration) { | |||
amount *= max ? duration[1] : duration[0]; | |||
} | |||
amount /= c.cdMax; | |||
var critChance = max ? 0.5 : 0.05; | |||
var critMult = max ? 3 : 1.5; | |||
amount = (amount * (1 - critChance)) + (amount * critChance * critMult); | |||
res.push({ | |||
name: s, | |||
dpt: (~~(amount * 10) / 10), | |||
cd: c.cdMax, | |||
mana: c.manaCost || '', | |||
tpk: ~~((maxTarget ? hpMax : hp)[level - 1] / amount), | |||
amount: amount | |||
}); | |||
} | |||
res = res.sort((a, b) => (b.dpt - a.dpt)); | |||
console.log(); | |||
console.log('ability dpt'); | |||
console.log(); | |||
res.forEach(function (r) { | |||
var gap = new Array(20 - r.name.length); | |||
console.log(r.name + ': ' + gap.join(' ') + r.dpt + ' ' + r.tpk + ' ticks ' + (~~((r.tpk / 2.85) * 10) / 10) + ' seconds'); | |||
}); | |||
console.log(); | |||
} | |||
}; | |||
}); |
@@ -2,7 +2,7 @@ define([ | |||
'js/system/client', | |||
'js/system/events', | |||
'js/misc/physics' | |||
], function( | |||
], function ( | |||
client, | |||
events, | |||
physics | |||
@@ -11,11 +11,12 @@ define([ | |||
type: 'gatherer', | |||
effect: null, | |||
init: function() { | |||
init: function () { | |||
this.obj.on('onKeyDown', this.onKeyDown.bind(this)); | |||
events.on('onRezone', this.onRezone.bind(this)); | |||
}, | |||
extend: function(msg) { | |||
extend: function (msg) { | |||
if ((msg.width) && (msg.progress != 100)) { | |||
if (this.effect) | |||
this.effect.destroyed = true; | |||
@@ -54,7 +55,14 @@ define([ | |||
} | |||
}, | |||
onKeyDown: function(key) { | |||
onRezone: function () { | |||
this.extend({ | |||
progress: 100, | |||
action: 'Fishing' | |||
}); | |||
}, | |||
onKeyDown: function (key) { | |||
if (key != 'g') | |||
return; | |||
@@ -68,4 +76,4 @@ define([ | |||
}); | |||
} | |||
}; | |||
}); | |||
}); |
@@ -13,6 +13,8 @@ define([ | |||
'int': 'intellect', | |||
'dex': 'dexterity', | |||
'armor': 'armor', | |||
'blockAttackChance': 'chance to block attacks', | |||
'blockSpellChance': 'chance to block spells', | |||
'addCritChance': 'increased crit chance', | |||
'addCritMultiplier': 'increased crit multiplier', | |||
'magicFind': 'increased item quality', | |||
@@ -2,7 +2,7 @@ define([ | |||
'js/system/events', | |||
'js/objects/objects', | |||
'js/rendering/renderer' | |||
], function( | |||
], function ( | |||
events, | |||
objects, | |||
renderer | |||
@@ -13,12 +13,14 @@ define([ | |||
return { | |||
list: [], | |||
init: function() { | |||
init: function () { | |||
events.on('onGetDamage', this.onGetDamage.bind(this)); | |||
}, | |||
onGetDamage: function(msg) { | |||
var target = objects.objects.find(function(o) { return (o.id == msg.id); }); | |||
onGetDamage: function (msg) { | |||
var target = objects.objects.find(function (o) { | |||
return (o.id == msg.id); | |||
}); | |||
if (!target) | |||
return; | |||
@@ -37,19 +39,21 @@ define([ | |||
text: msg.text, | |||
crit: msg.crit, | |||
heal: msg.heal | |||
}; | |||
}; | |||
if (numberObj.event) { | |||
numberObj.y += (scale / 2); | |||
} | |||
else if (numberObj.heal) | |||
} else if (numberObj.heal) | |||
numberObj.x -= scale; | |||
else | |||
numberObj.x += scale; | |||
var text = numberObj.text; | |||
if (!numberObj.event) | |||
text = (numberObj.heal ? '+' : '') + (~~(numberObj.amount * 10) / 10); | |||
if (!numberObj.event) { | |||
var amount = numberObj.amount; | |||
var div = ((~~(amount * 10) / 10) > 0) ? 10 : 100; | |||
text = (numberObj.heal ? '+' : '') + (~~(amount * div) / div); | |||
} | |||
numberObj.sprite = renderer.buildText({ | |||
fontSize: numberObj.crit ? 22 : 18, | |||
@@ -62,7 +66,7 @@ define([ | |||
this.list.push(numberObj); | |||
}, | |||
render: function() { | |||
render: function () { | |||
var list = this.list; | |||
var lLen = list.length; | |||
@@ -94,4 +98,4 @@ define([ | |||
} | |||
} | |||
}; | |||
}); | |||
}); |
@@ -1,5 +1,5 @@ | |||
<div class="uiCharacters"> | |||
<img class="logo" src="images/logo_4.png"ii alt=""> | |||
<img class="logo" src="images/logo_0.png"ii alt=""> | |||
<div class="left"> | |||
<div class="character">loading characters...</div> | |||
</div> | |||
@@ -1,5 +1,5 @@ | |||
<div class="uiCreateCharacter"> | |||
<img class="logo" src="images/logo_4.png" alt=""> | |||
<img class="logo" src="images/logo_0.png" alt=""> | |||
<div class="box-left"> | |||
<div class="left"> | |||
<input type="text" class="el textbox txtName" placeholder="name" maxlength="12"> | |||
@@ -348,6 +348,8 @@ define([ | |||
}, | |||
defense: { | |||
armor: stats.armor, | |||
'chance to block attacks': stats.blockAttackChance + '%', | |||
'chance to block spells': stats.blockSpellChance + '%', | |||
gap1: '', | |||
'arcane resist': stats.elementArcaneResist, | |||
'fire resist': stats.elementFireResist, | |||
@@ -206,7 +206,7 @@ define([ | |||
var hoverCellItem = this.hoverCell.data('item'); | |||
if (hoverCellItem) { | |||
if (hoverCellItem.name != this.dragItem.data('item').name) { | |||
if ((hoverCellItem.name != this.dragItem.data('item').name) || (!hoverCellItem.quantity)) { | |||
msgs.push({ | |||
id: hoverCellItem.id, | |||
pos: this.hoverCell.index() | |||
@@ -1,5 +1,5 @@ | |||
<div class="uiLogin"> | |||
<img class="logo" src="images/logo_4.png" alt=""> | |||
<img class="logo" src="images/logo_0.png" alt=""> | |||
<div class="right"> | |||
<div class="label">username</div> | |||
<input type="text" class="el textbox txtUsername" placeholder="username"> | |||
@@ -17,5 +17,5 @@ | |||
<div class="el button btnPaypal" location="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=BR2CC82WUAVEA">Donate on Paypal</div> | |||
<div class="el button btnWiki" location="http://wiki.isleward.com/Main_Page">Access the Wiki</div> | |||
</div> | |||
<div class="version" location="https://gitlab.com/Isleward/isleward/issues/418">v0.1.9</div> | |||
<div class="version" location="https://gitlab.com/Isleward/isleward/issues/418">v0.1.10</div> | |||
</div> |
@@ -160,6 +160,10 @@ define([ | |||
if (msg.item.spell) | |||
reforge.removeClass('disabled'); | |||
var reslot = this.find('[action="reslot"]').addClass('disabled'); | |||
if (!msg.item.effects) | |||
reslot.removeClass('disabled'); | |||
this.offEvent(this.eventClickInv); | |||
$('.uiInventory').data('ui').toggle(); | |||
@@ -17,6 +17,8 @@ define([ | |||
'sprintChance', | |||
'dmgPercent', | |||
'xpIncrease', | |||
'blockAttackChance', | |||
'blockSpellChance', | |||
'attackSpeed', | |||
'castSpeed', | |||
'itemQuantity', | |||
@@ -24,37 +24,28 @@ define([ | |||
statValue = max(1, statValue); | |||
var dmgPercent = srcValues.dmgPercent; | |||
var resist = srcValues.elementAllResist; | |||
var dmgPercent = 100 + srcValues.dmgPercent; | |||
var resist = tgtValues.elementAllResist; | |||
if (config.element) { | |||
var elementName = 'element' + config.element[0].toUpperCase() + config.element.substr(1); | |||
dmgPercent += srcValues[elementName + 'Percent']; | |||
resist += (tgtValues[elementName + 'Resist'] || 0); | |||
} | |||
dmgPercent /= 100; | |||
var statMult = config.statMult || 1; | |||
var dps = ( | |||
(statMult * statValue * config.damage) * | |||
max((0.5 + (dmgPercent / 100)), 0.5) | |||
); | |||
var amount = config.damage * statValue * statMult * dmgPercent; | |||
//Don't mitigate heals | |||
if (!config.noMitigate) { | |||
dps = ( | |||
dps * | |||
max(0.5 + max((1 - ((tgtValues.armor || 0) / (srcValues.level * 51.2))) / 2, -0.5), 0.5) * | |||
max(0.5 + max((1 - (resist / 75)) / 2, -0.5), 0.5) | |||
amount = ( | |||
amount * | |||
max(0.5 + max((1 - ((tgtValues.armor || 0) / (srcValues.level * 50))) / 2, -0.5), 0.5) * | |||
max(0.5 + max((1 - (resist / 100)) / 2, -0.5), 0.5) | |||
); | |||
} | |||
var amount = dps; | |||
if ((config.source.mob) || (config.cd)) { | |||
var cd = config.source.mob ? 1 : config.cd; | |||
amount *= cd * 0.3; | |||
} | |||
var isCrit = false; | |||
if (!config.noCrit) { | |||
var critChance = srcValues.critChance; | |||
@@ -65,8 +56,16 @@ define([ | |||
} | |||
} | |||
var blocked = false; | |||
var blockChance = config.isAttack ? tgtValues.blockAttackChance : tgtValues.blockSpellChance; | |||
if (Math.random() * 100 < blockChance) { | |||
blocked = true; | |||
amount = 0; | |||
} | |||
return { | |||
amount: amount, | |||
blocked: blocked, | |||
crit: isCrit, | |||
element: config.element | |||
}; | |||
@@ -60,7 +60,7 @@ define([ | |||
var social = simple.components.find(c => c.type == 'social'); | |||
delete social.party; | |||
delete social.customChannelsl | |||
delete social.customChannels; | |||
var statKeys = Object.keys(stats.values); | |||
var sLen = statKeys.length; | |||
@@ -145,8 +145,12 @@ define([ | |||
}, | |||
getCharacter: function (data) { | |||
var name = data.data.name; | |||
if (!this.characterList.some(c => ((c.name == name) || (c == name)))) | |||
return; | |||
io.get({ | |||
ent: data.data.name, | |||
ent: name, | |||
field: 'character', | |||
callback: this.onGetCharacter.bind(this, data) | |||
}); | |||
@@ -160,9 +164,9 @@ define([ | |||
var character = JSON.parse(result || '{}'); | |||
//Hack for old characters | |||
if (!character.skinId) { | |||
if (!character.skinId) | |||
character.skinId = character.class + ' 1'; | |||
} | |||
character.cell = skins.getCell(character.skinId); | |||
character.sheetName = skins.getSpritesheet(character.skinId); | |||
@@ -207,27 +211,30 @@ define([ | |||
onGetStash: function (data, character, result) { | |||
this.stash = JSON.parse(result || '[]'); | |||
if (this.skins != null) | |||
if (this.skins != null) { | |||
this.verifySkin(character); | |||
data.callback(character); | |||
else { | |||
} else { | |||
data.callback = data.callback.bind(null, character); | |||
this.getSkins(data); | |||
this.getSkins(data, character); | |||
} | |||
}, | |||
getSkins: function (msg) { | |||
getSkins: function (msg, character) { | |||
io.get({ | |||
ent: this.username, | |||
field: 'skins', | |||
callback: this.onGetSkins.bind(this, msg) | |||
callback: this.onGetSkins.bind(this, msg, character) | |||
}); | |||
}, | |||
onGetSkins: function (msg, result) { | |||
onGetSkins: function (msg, character, result) { | |||
this.skins = JSON.parse(result || '[]'); | |||
var list = [...this.skins, ...roles.getSkins(this.username)]; | |||
var skinList = skins.getSkinList(list); | |||
this.verifySkin(character); | |||
msg.callback(skinList); | |||
}, | |||
@@ -254,6 +261,21 @@ define([ | |||
}, | |||
verifySkin: function (character) { | |||
if (!character) | |||
return; | |||
var list = [...this.skins, ...roles.getSkins(this.username)]; | |||
var skinList = skins.getSkinList(list); | |||
if (!skinList[character.class].some(s => (s.id == character.skinId))) { | |||
character.skinId = character.class + ' 1'; | |||
character.cell = skins.getCell(character.skinId); | |||
character.sheetName = skins.getSpritesheet(character.skinId); | |||
} | |||
}, | |||
doesOwnSkin: function (skinId) { | |||
return this.skins.some(s => s == skinId); | |||
}, | |||
@@ -26,7 +26,8 @@ define([ | |||
clearInventory: 10, | |||
completeQuests: 10, | |||
getReputation: 10, | |||
loseReputation: 10 | |||
loseReputation: 10, | |||
setStat: 10 | |||
}; | |||
var localCommands = [ | |||
@@ -230,6 +231,9 @@ define([ | |||
var safe = config.safe; | |||
delete config.safe; | |||
var eq = config.eq; | |||
delete config.eq; | |||
var item = generator.generate(config); | |||
if (safe) { | |||
@@ -255,7 +259,10 @@ define([ | |||
if (spritesheet) | |||
item.spritesheet = spritesheet; | |||
this.obj.inventory.getItem(item); | |||
var newItem = this.obj.inventory.getItem(item); | |||
if (eq) | |||
this.obj.equipment.equip(newItem.id); | |||
}, | |||
getGold: function (amount) { | |||
@@ -345,6 +352,10 @@ define([ | |||
return; | |||
this.obj.reputation.getReputation(faction, -50000); | |||
}, | |||
setStat: function (config) { | |||
this.obj.stats.values[config.stat] = ~~config.value; | |||
} | |||
}; | |||
}); |
@@ -262,6 +262,10 @@ define([ | |||
}, | |||
events: { | |||
beforeRezone: function () { | |||
this.events.beforeMove.call(this); | |||
}, | |||
beforeMove: function () { | |||
if (!this.gathering) | |||
return; | |||
@@ -79,7 +79,7 @@ define([ | |||
newItem.pos = pos; | |||
} | |||
if ((this.obj.player) && (!isTransfer)) | |||
if ((this.obj.player) && (!isTransfer) && (this.obj.stats.values.level == 1)) | |||
this.getDefaultAbilities(); | |||
delete blueprint.items; | |||
@@ -403,9 +403,6 @@ define([ | |||
this.obj.syncer.setArray(true, 'inventory', 'destroyItems', id); | |||
} | |||
if (this.obj.player) | |||
this.getDefaultAbilities(); | |||
this.obj.fireEvent('afterDestroyItem', item, amount); | |||
return item; | |||
@@ -413,7 +410,7 @@ define([ | |||
dropItem: function (id) { | |||
var item = this.findItem(id); | |||
if ((!item) || (item.noDrop)) | |||
if ((!item) || (item.noDrop) || (item.quest)) | |||
return; | |||
delete item.pos; | |||
@@ -447,7 +444,7 @@ define([ | |||
mailItem: function (msg) { | |||
var item = this.findItem(msg.itemId); | |||
if (!item) { | |||
if ((!item) || (item.noDrop) || (item.quest)) { | |||
this.resolveCallback(msg); | |||
return; | |||
} | |||
@@ -528,7 +525,7 @@ define([ | |||
var item = generator.generate({ | |||
type: classes.weapons[this.obj.class], | |||
quality: 0, | |||
spellQuality: 'mid' | |||
spellQuality: 'basic' | |||
}); | |||
item.eq = true; | |||
item.noSalvage = true; | |||
@@ -839,7 +836,7 @@ define([ | |||
var rolls = blueprint.rolls; | |||
var itemQuantity = killSource.stats.values.itemQuantity; | |||
rolls += ~~(itemQuantity / 100); | |||
if ((Math.random() * 100) < (itemQuantity * 100)) | |||
if ((Math.random() * 100) < (itemQuantity % 100)) | |||
rolls++; | |||
for (var i = 0; i < rolls; i++) { | |||
@@ -57,7 +57,9 @@ define([ | |||
faction = this.list.find(l => l.id == factionId); | |||
} | |||
return faction.tier; | |||
return (faction || { | |||
tier: 3 | |||
}).tier; | |||
}, | |||
canEquipItem: function (item) { | |||
@@ -157,6 +159,9 @@ define([ | |||
var fullSync = (this.factions[factionId] == null); | |||
var blueprint = this.getBlueprint(factionId); | |||
if (!blueprint) | |||
return; | |||
this.list.push({ | |||
id: factionId, | |||
rep: blueprint.initialRep, | |||
@@ -9,8 +9,8 @@ define([ | |||
type: 'stats', | |||
values: { | |||
mana: 10, | |||
manaMax: 10, | |||
mana: 20, | |||
manaMax: 20, | |||
manaReservePercent: 0, | |||
@@ -26,7 +26,7 @@ define([ | |||
magicFind: 0, | |||
itemQuantity: 0, | |||
regenHp: 0, | |||
regenMana: 10, | |||
regenMana: 5, | |||
addCritChance: 0, | |||
addCritMultiplier: 0, | |||
critChance: 5, | |||
@@ -34,6 +34,9 @@ define([ | |||
armor: 0, | |||
dmgPercent: 0, | |||
blockAttackChance: 0, | |||
blockSpellChance: 0, | |||
attackSpeed: 0, | |||
castSpeed: 0, | |||
@@ -130,7 +133,7 @@ define([ | |||
var regenHp = 0; | |||
var regenMana = 0; | |||
regenMana = (manaMax / 200) + (values.regenMana / 200); | |||
regenMana = values.regenMana / 50; | |||
if (!isInCombat) | |||
regenHp = values.hpMax / 100; | |||
@@ -191,7 +194,7 @@ define([ | |||
calcXpMax: function () { | |||
var level = this.values.level; | |||
this.values.xpMax = ~~(level * 10 * Math.pow(level, 1.75)); | |||
this.values.xpMax = ~~(level * 10 * Math.pow(level, 2.2)); | |||
this.obj.syncer.setObject(true, 'stats', 'values', 'xpMax', this.values.xpMax); | |||
}, | |||
@@ -200,6 +203,9 @@ define([ | |||
var obj = this.obj; | |||
var values = this.values; | |||
if (values.level == 20) | |||
return; | |||
amount = ~~(amount * (1 + (values.xpIncrease / 100))); | |||
values.xpTotal = ~~(values.xpTotal + amount); | |||
@@ -219,7 +225,10 @@ define([ | |||
values.xp -= values.xpMax; | |||
values.level++; | |||
values.hpMax += 40; | |||
if (values.level == 20) | |||
values.xp = 0; | |||
values.hpMax += 50; | |||
this.syncer.queue('onGetDamage', { | |||
id: obj.id, | |||
@@ -347,12 +356,21 @@ define([ | |||
recipients.push(this.obj.follower.master.serverId); | |||
if (recipients.length > 0) { | |||
this.syncer.queue('onGetDamage', { | |||
id: this.obj.id, | |||
source: source.id, | |||
crit: damage.crit, | |||
amount: amount | |||
}, recipients); | |||
if (!damage.blocked) { | |||
this.syncer.queue('onGetDamage', { | |||
id: this.obj.id, | |||
source: source.id, | |||
crit: damage.crit, | |||
amount: amount | |||
}, recipients); | |||
} else { | |||
this.syncer.queue('onGetDamage', { | |||
id: this.obj.id, | |||
source: source.id, | |||
event: true, | |||
text: 'blocked' | |||
}, recipients); | |||
} | |||
} | |||
this.obj.aggro.tryEngage(source, amount, threatMult); | |||
@@ -219,6 +219,9 @@ define([ | |||
if (clonedItem.generate) { | |||
clonedItem = generator.generate(clonedItem); | |||
delete clonedItem.generate; | |||
if (item.factions) | |||
clonedItem.factions = item.factions; | |||
} | |||
this.obj.inventory.getItem(clonedItem); | |||
@@ -31,25 +31,25 @@ define([ | |||
stats: { | |||
wizard: { | |||
values: { | |||
hpMax: 80 | |||
hpMax: 50 | |||
}, | |||
vitScale: 10, | |||
}, | |||
cleric: { | |||
values: { | |||
hpMax: 90 | |||
hpMax: 60 | |||
}, | |||
vitScale: 10 | |||
}, | |||
warrior: { | |||
values: { | |||
hpMax: 110 | |||
hpMax: 80 | |||
}, | |||
vitScale: 10 | |||
}, | |||
thief: { | |||
values: { | |||
hpMax: 100 | |||
hpMax: 70 | |||
}, | |||
vitScale: 10 | |||
} | |||
@@ -2,7 +2,7 @@ define([ | |||
'world/spawners', | |||
'world/mobBuilder', | |||
'combat/combat' | |||
], function( | |||
], function ( | |||
spawners, | |||
mobBuilder, | |||
combat | |||
@@ -20,7 +20,7 @@ define([ | |||
max: 45 | |||
}, | |||
generate: function(item) { | |||
generate: function (item) { | |||
var chance = this.chance; | |||
var chanceRoll = ~~(random.norm(chance.min, chance.max) * 10) / 10; | |||
@@ -35,7 +35,7 @@ define([ | |||
result = { | |||
factionId: 'akarei', | |||
chance: chanceRoll, | |||
text: chanceRoll + '% chance on to cast a lightning bolt when you critically hit an enemy', | |||
text: chanceRoll + '% chance on crit to cast a lightning bolt', | |||
events: {} | |||
}; | |||
@@ -53,7 +53,7 @@ define([ | |||
}, | |||
events: { | |||
beforeDealDamage: function(item, damage, target) { | |||
beforeDealDamage: function (item, damage, target) { | |||
if (!damage.crit) | |||
return; | |||
@@ -63,7 +63,7 @@ define([ | |||
if (roll >= effect.chance) | |||
return; | |||
var cbExplode = function(target) { | |||
var cbExplode = function (target) { | |||
if ((this.destroyed) || (target.destroyed)) | |||
return; | |||
@@ -96,4 +96,4 @@ define([ | |||
} | |||
}; | |||
}); | |||
}); |
@@ -5,6 +5,12 @@ module.exports = { | |||
resources: {}, | |||
mobs: { | |||
default: { | |||
spells: [{ | |||
type: 'melee', | |||
statMult: 0.1356, | |||
element: 'arcane' | |||
}], | |||
regular: { | |||
drops: { | |||
chance: 35, | |||
@@ -42,7 +48,7 @@ module.exports = { | |||
range: 2, | |||
selfCast: 0.2, | |||
statMult: 1, | |||
damage: 0.225, | |||
damage: 0.325, | |||
element: 'arcane', | |||
cdMax: 5, | |||
particles: { | |||
@@ -119,7 +125,7 @@ module.exports = { | |||
range: 2, | |||
selfCast: 0.2, | |||
statMult: 1, | |||
damage: 0.2, | |||
damage: 0.45, | |||
element: 'arcane', | |||
cdMax: 5, | |||
particles: { | |||
@@ -212,7 +218,7 @@ module.exports = { | |||
range: 6, | |||
selfCast: 0.25, | |||
statMult: 1, | |||
damage: 0.15, | |||
damage: 0.55, | |||
element: 'arcane', | |||
cdMax: 8, | |||
particles: { | |||
@@ -5,14 +5,20 @@ module.exports = { | |||
resources: {}, | |||
mobs: { | |||
default: { | |||
faction: 2, | |||
faction: 'hostile', | |||
grantRep: { | |||
gaekatla: 15 | |||
}, | |||
spells: [{ | |||
type: 'melee', | |||
statMult: 0.1356, | |||
element: 'poison' | |||
}], | |||
regular: { | |||
hpMult: 1.5, | |||
dmgMult: 2, | |||
hpMult: 4, | |||
dmgMult: 2.2, | |||
drops: { | |||
chance: 45, | |||
@@ -22,44 +28,153 @@ module.exports = { | |||
} | |||
}, | |||
'giant gull': { | |||
level: 6, | |||
level: 15, | |||
questItem: { | |||
name: 'Gull Feather', | |||
sprite: [0, 0] | |||
} | |||
}, | |||
'fanged rabbit': { | |||
level: 7 | |||
level: 15 | |||
}, | |||
'ghastly toad': { | |||
level: 8 | |||
level: 16 | |||
}, | |||
'overgrown beaver': { | |||
level: 16 | |||
}, | |||
'huge flamingo': { | |||
level: 9, | |||
level: 17, | |||
questItem: { | |||
name: 'Gull Feather', | |||
name: 'Flamingo Feather', | |||
sprite: [0, 0] | |||
} | |||
}, | |||
'overgrown beaver': { | |||
level: 10 | |||
}, | |||
'ironskull goat': { | |||
level: 10 | |||
}, | |||
'king gator': { | |||
level: 12 | |||
level: 18 | |||
}, | |||
"m'ogresh": { | |||
level: 12, | |||
isChampion: true, | |||
level: 20, | |||
grantRep: { | |||
gaekatla: 120 | |||
}, | |||
regular: { | |||
hpMult: 10, | |||
dmgMult: 3, | |||
drops: { | |||
chance: 100, | |||
rolls: 3, | |||
magicFind: [2000, 125] | |||
} | |||
}, | |||
spells: [{ | |||
type: 'melee', | |||
range: 2, | |||
animation: 'basic' | |||
}, { | |||
type: 'warnBlast', | |||
range: 2, | |||
animation: 'basic', | |||
statMult: 0.01, | |||
particles: { | |||
color: { | |||
start: ['c0c3cf', '929398'], | |||
end: ['929398', 'c0c3cf'] | |||
}, | |||
scale: { | |||
start: { | |||
min: 4, | |||
max: 10 | |||
}, | |||
end: { | |||
min: 0, | |||
max: 4 | |||
} | |||
}, | |||
speed: { | |||
start: { | |||
min: 2, | |||
max: 16 | |||
}, | |||
end: { | |||
min: 0, | |||
max: 8 | |||
} | |||
}, | |||
lifetime: { | |||
min: 1, | |||
max: 1 | |||
}, | |||
spawnType: 'circle', | |||
spawnCircle: { | |||
x: 0, | |||
y: 0, | |||
r: 12 | |||
}, | |||
randomScale: true, | |||
randomSpeed: true, | |||
chance: 0.075, | |||
randomColor: true | |||
} | |||
}, { | |||
statMult: 0.2, | |||
type: 'projectile', | |||
row: 5, | |||
col: 4, | |||
shootAll: true, | |||
particles: { | |||
color: { | |||
start: ['a24eff', '7a3ad3'], | |||
end: ['7a3ad3', '533399'] | |||
}, | |||
scale: { | |||
start: { | |||
min: 2, | |||
max: 12 | |||
}, | |||
end: { | |||
min: 0, | |||
max: 6 | |||
} | |||
}, | |||
lifetime: { | |||
min: 2, | |||
max: 4 | |||
}, | |||
alpha: { | |||
start: 0.7, | |||
end: 0 | |||
}, | |||
speed: { | |||
start: { | |||
min: 4, | |||
max: 24 | |||
}, | |||
end: { | |||
min: 0, | |||
max: 12 | |||
} | |||
}, | |||
startRotation: { | |||
min: 0, | |||
max: 360 | |||
}, | |||
rotationSpeed: { | |||
min: 0, | |||
max: 360 | |||
}, | |||
randomScale: true, | |||
randomColor: true, | |||
randomSpeed: true, | |||
chance: 0.55, | |||
spawnType: 'circle', | |||
spawnCircle: { | |||
x: 0, | |||
y: 0, | |||
r: 8 | |||
} | |||
} | |||
}] | |||
} | |||
}, | |||
@@ -59,7 +59,7 @@ define([ | |||
}, | |||
lifetime: { | |||
min: 1, | |||
max: 4 | |||
max: 2 | |||
}, | |||
alpha: { | |||
start: 0.8, | |||
@@ -78,6 +78,11 @@ define([ | |||
if (effect) | |||
return; | |||
if (!obj.effects) { | |||
console.log('No Effects ', obj.name); | |||
return; | |||
} | |||
effects[obj.serverId] = obj.effects.addEffect({ | |||
type: this.effect, | |||
amount: amount, | |||
@@ -62,8 +62,6 @@ define([ | |||
noMsg: true | |||
}); | |||
var ttl = 350; | |||
var targetPos = { | |||
x: m.x, | |||
y: m.y | |||
@@ -99,6 +97,9 @@ define([ | |||
} | |||
} | |||
var distance = Math.max(Math.abs(m.x - targetPos.x), Math.abs(m.y - targetPos.y)); | |||
var ttl = distance * 125; | |||
m.clearQueue(); | |||
this.sendAnimation({ | |||
@@ -78,13 +78,15 @@ define([ | |||
var critChance = this.obj.stats.values.critChance; | |||
var critMultiplier = this.obj.stats.values.critMultiplier; | |||
var attackSpeed = (this.obj.stats.values.attackSpeed / 100); | |||
attackSpeed += 1; | |||
dmg = ((dmg / 100) * (100 - critChance)) + (((dmg / 100) * critChance) * (critMultiplier / 100)); | |||
dmg = (((dmg / 100) * (100 - critChance)) + (((dmg / 100) * critChance) * (critMultiplier / 100))) * attackSpeed; | |||
if (this.damage) { | |||
this.values.dmg = ~~(dmg * 10) / 10 + '/tick'; | |||
this.values.dmg = ~~(dmg * 100) / 100 + '/tick'; | |||
} else | |||
this.values.heal = ~~(dmg * 10) / 10 + '/tick'; | |||
this.values.heal = ~~(dmg * 100) / 100 + '/tick'; | |||
if (!noSync) | |||
this.obj.syncer.setArray(true, 'spellbook', 'getSpells', this.simplify()); | |||
@@ -164,6 +166,7 @@ define([ | |||
element: this.element, | |||
statType: this.statType, | |||
statMult: this.statMult, | |||
isAttack: (this.type == 'melee'), | |||
noMitigate: noMitigate | |||
}; | |||
@@ -6,45 +6,43 @@ define([ | |||
var spells = { | |||
'magic missile': { | |||
statType: 'int', | |||
statMult: 0.216, | |||
statMult: 0.59, | |||
element: 'arcane', | |||
auto: true, | |||
cdMax: 7, | |||
manaCost: 0, | |||
range: 9, | |||
random: { | |||
damage: [2, 4] | |||
damage: [2, 7.6] | |||
} | |||
}, | |||
'ice spear': { | |||
statType: 'int', | |||
statMult: 0.076, | |||
statMult: 0.42, | |||
element: 'frost', | |||
cdMax: 10, | |||
manaCost: 5, | |||
cdMax: 12, | |||
manaCost: 4, | |||
range: 9, | |||
dmgMult: 0.8, | |||
random: { | |||
damage: [4, 8], | |||
damage: [4, 15.2], | |||
i_freezeDuration: [6, 10] | |||
} | |||
}, | |||
'fireblast': { | |||
statType: 'int', | |||
statMult: 0.03, | |||
statMult: 0.25, | |||
element: 'fire', | |||
cdMax: 15, | |||
cdMax: 6, | |||
manaCost: 5, | |||
dmgMult: 1.1, | |||
random: { | |||
damage: [6.7, 13.3], | |||
damage: [6, 22.9], | |||
i_radius: [1, 2.2], | |||
i_pushback: [1, 4] | |||
} | |||
}, | |||
'smite': { | |||
statType: 'int', | |||
statMult: 0.378, | |||
statMult: 0.84, | |||
element: 'holy', | |||
auto: true, | |||
needLos: true, | |||
@@ -52,19 +50,19 @@ define([ | |||
manaCost: 0, | |||
range: 9, | |||
random: { | |||
damage: [1.4, 2.6] | |||
damage: [4, 15.2] | |||
} | |||
}, | |||
'healing circle': { | |||
statType: 'int', | |||
statMult: 0.454, | |||
statMult: 0.055, | |||
element: 'holy', | |||
cdMax: 10, | |||
manaCost: 10, | |||
manaCost: 8, | |||
range: 9, | |||
radius: 3, | |||
random: { | |||
healing: [0.7, 1.3], | |||
healing: [3.5, 4], | |||
i_duration: [7, 13] | |||
} | |||
}, | |||
@@ -80,28 +78,27 @@ define([ | |||
},*/ | |||
'slash': { | |||
statType: 'str', | |||
statMult: 0.303, | |||
statMult: 0.745, | |||
element: 'physical', | |||
threatMult: 4, | |||
auto: true, | |||
cdMax: 5, | |||
useWeaponRange: true, | |||
random: { | |||
damage: [2, 4] | |||
damage: [3, 11.4] | |||
} | |||
}, | |||
'charge': { | |||
statType: 'str', | |||
statMult: 0.151, | |||
statMult: 0.48, | |||
element: 'physical', | |||
threatMult: 3, | |||
cdMax: 5, | |||
cdMax: 15, | |||
range: 10, | |||
manaCost: 5, | |||
dmgMult: 0.9, | |||
manaCost: 3, | |||
random: { | |||
damage: [4, 8], | |||
i_stunDuration: [3, 7] | |||
damage: [3.5, 13.3], | |||
i_stunDuration: [6, 10] | |||
} | |||
}, | |||
/*'reflect damage': { | |||
@@ -116,24 +113,23 @@ define([ | |||
},*/ | |||
'double slash': { | |||
statType: 'dex', | |||
statMult: 0.757, | |||
statMult: 0.84, | |||
element: 'physical', | |||
cdMax: 3, | |||
useWeaponRange: true, | |||
auto: true, | |||
random: { | |||
damage: [1, 3] | |||
damage: [1, 3.8] | |||
} | |||
}, | |||
'smokebomb': { | |||
statType: 'dex', | |||
statMult: 1.817, | |||
statMult: 0.335, | |||
element: 'poison', | |||
cdMax: 5, | |||
cdMax: 3, | |||
manaCost: 6, | |||
dmgMult: 1.2, | |||
random: { | |||
damage: [0.3, 0.7], | |||
damage: [0.25, 0.73], | |||
i_radius: [1, 3], | |||
i_duration: [7, 13] | |||
} | |||
@@ -147,15 +143,15 @@ define([ | |||
},*/ | |||
'crystal spikes': { | |||
statType: ['dex', 'int'], | |||
statMult: 0.0205, | |||
statMult: 3.18, | |||
element: 'physical', | |||
manaCost: 5, | |||
manaCost: 22, | |||
needLos: true, | |||
cdMax: 10, | |||
cdMax: 20, | |||
range: 9, | |||
random: { | |||
damage: [9.3, 18.6], | |||
i_delay: [4, 8] | |||
damage: [7, 26.5], | |||
i_delay: [1, 4] | |||
}, | |||
negativeStats: [ | |||
'i_delay' | |||
@@ -186,7 +182,7 @@ define([ | |||
auraRange: 9, | |||
effect: 'regenMana', | |||
random: { | |||
regenPercentage: [5, 18] | |||
regenPercentage: [4, 10] | |||
} | |||
}, | |||
'swiftness': { | |||
@@ -189,10 +189,20 @@ define([ | |||
}, | |||
offHand: { | |||
'Wooden Shield': { | |||
sprite: [13, 0] | |||
sprite: [13, 0], | |||
armorMult: 0.3, | |||
blockAttackMult: 1 | |||
}, | |||
'Gilded Shield': { | |||
sprite: [13, 1] | |||
sprite: [13, 1], | |||
armorMult: 0.6, | |||
blockAttackMult: 0.5 | |||
}, | |||
'Brittle Tome': { | |||
sprite: [13, 2] | |||
}, | |||
'Ancient Tome': { | |||
sprite: [13, 3] | |||
} | |||
}, | |||
tool: { | |||
@@ -73,6 +73,9 @@ define([ | |||
offset = Math.abs(offset); | |||
item.level = Math.max(1, item.level + offset); | |||
} else if (msg.action == 'reslot') { | |||
if (item.effects) | |||
return; | |||
var newItem = generator.generate({ | |||
slot: configSlots.getRandomSlot(item.slot), | |||
level: item.level, | |||
@@ -132,7 +135,8 @@ define([ | |||
addStat: function (item, result) { | |||
generatorStats.generate(item, { | |||
statCount: 1 | |||
statCount: 1, | |||
}, result); | |||
}, | |||
@@ -38,7 +38,7 @@ define([ | |||
item.name = 'Rune of ' + spellAesthetic.name; | |||
item.ability = true; | |||
item.sprite = sprite; | |||
} else if (spellQuality == 'mid') | |||
} else if (spellQuality == 'basic') | |||
item.stats = {}; | |||
item.spell = { | |||
@@ -55,7 +55,10 @@ define([ | |||
for (var r in randomProperties) { | |||
var negativeStat = (negativeStats.indexOf(r) > -1); | |||
var range = randomProperties[r]; | |||
var roll = random.norm(0, 1); | |||
var max = Math.min(20, item.level) / 20; | |||
var roll = random.expNorm(0, max); | |||
if (spellQuality == 'basic') | |||
roll = 0; | |||
else if (spellQuality == 'mid') | |||
@@ -73,9 +76,7 @@ define([ | |||
item.spell.values[r] = val; | |||
if (roll <= 0.5) | |||
propertyPerfection.push(0); | |||
else if (negativeStat) | |||
if (negativeStat) | |||
propertyPerfection.push(1 - roll); | |||
else | |||
propertyPerfection.push(roll) | |||
@@ -5,13 +5,56 @@ define([ | |||
) { | |||
return { | |||
generators: { | |||
dmgPercent: function (item, level, blueprint, perfection) { | |||
var max = (level / 2); | |||
if (perfection == null) | |||
return random.norm(1, max) * (blueprint.statMult.dmgPercent || 1); | |||
else | |||
return max * perfection * (blueprint.statMult.dmgPercent || 1); | |||
}, | |||
elementDmgPercent: function (item, level, blueprint, perfection) { | |||
var max = (level / 6.7); | |||
if (perfection == null) | |||
return random.norm(1, max) * (blueprint.statMult.elementDmgPercent || 1); | |||
else | |||
return max * perfection * (blueprint.statMult.elementDmgPercent || 1); | |||
}, | |||
addCritMultiplier: function (item, level, blueprint, perfection) { | |||
var div = 1 / 11; | |||
if (item.slot == 'twoHanded') | |||
div *= 2; | |||
var max = (level * 15) * div; | |||
if (perfection == null) | |||
return random.norm(1, max) * (blueprint.statMult.addCritMultiplier || 1); | |||
else | |||
return max * perfection * (blueprint.statMult.addCritMultiplier || 1); | |||
}, | |||
addCritChance: function (item, level, blueprint, perfection) { | |||
var div = 1 / 11; | |||
if (item.slot == 'twoHanded') | |||
div *= 2; | |||
var max = (level - 3) * 50 * div; | |||
if (perfection == null) | |||
return random.norm(1, max) * (blueprint.statMult.addCritChance || 1); | |||
else | |||
return max * perfection * (blueprint.statMult.addCritChance || 1); | |||
}, | |||
hpMax: function (item, level, blueprint, perfection) { | |||
var div = 1 / 11; | |||
if (item.slot == 'twoHanded') | |||
div *= 2; | |||
if (item.slot) | |||
var max = ((level * 15) + level) * div; | |||
var max = (((90.5 + (Math.pow(level, 3) * 0.75)) - (30 + (Math.pow(level, 3) * 0.072))) / 10) * div; | |||
if (perfection == null) | |||
return random.norm(1, max) * (blueprint.statMult.hpMax || 1); | |||
@@ -23,8 +66,8 @@ define([ | |||
if (item.slot == 'twoHanded') | |||
div *= 2; | |||
var min = ((level * 6.05) - ((level - 1) * 1.2)) * div; | |||
var max = ((level * 14.9) + ((level - 1) * 31.49)) * div; | |||
var min = (1 + (0.00477 * Math.pow(level, 2.8))) * div; | |||
var max = (3 + (0.3825 * Math.pow(level, 1.83))) * div; | |||
if (perfection == null) | |||
return random.norm(min, max) * (blueprint.statMult.mainStat || 1); | |||
@@ -33,7 +76,7 @@ define([ | |||
}, | |||
armor: function (item, level, blueprint, perfection) { | |||
var min = (level * 20); | |||
var max = (level * 51.2); | |||
var max = (level * 50); | |||
if (perfection == null) | |||
return random.norm(min, max) * blueprint.statMult.armor; | |||
@@ -41,17 +84,21 @@ define([ | |||
return (min + ((max - min) * perfection)) * (blueprint.statMult.armor || 1); | |||
}, | |||
elementResist: function (item, level, blueprint, perfection) { | |||
var div = 1 / 11; | |||
if (item.slot == 'twoHanded') | |||
div *= 2; | |||
if (perfection == null) | |||
return random.norm(1, 7.5) * (blueprint.statMult.elementResist || 1); | |||
return random.norm(1, 100) * (blueprint.statMult.elementResist || 1) * div; | |||
else | |||
return (1 + (6.5 * perfection)) * (blueprint.statMult.elementResist || 1); | |||
return (1 + (99 * perfection)) * (blueprint.statMult.elementResist || 1) * div; | |||
}, | |||
regenHp: function (item, level, blueprint, perfection) { | |||
var div = 1 / 11; | |||
if (item.slot == 'twoHanded') | |||
div *= 2; | |||
var max = (((10 + (level * 200)) / 20) / 2) * div; | |||
var max = (3 + (0.0364 * Math.pow(level, 2.8))) * div; | |||
if (perfection == null) | |||
return random.norm(1, max) * (blueprint.statMult.regenHp || 1); | |||
@@ -78,12 +125,12 @@ define([ | |||
manaMax: { | |||
min: 1, | |||
max: 5 | |||
max: 8 | |||
}, | |||
regenMana: { | |||
min: 1, | |||
max: 7 | |||
max: 5 | |||
}, | |||
lvlRequire: { | |||
@@ -126,39 +173,32 @@ define([ | |||
}, | |||
dmgPercent: { | |||
min: 1, | |||
max: 5, | |||
ignore: true | |||
ignore: true, | |||
generator: 'dmgPercent' | |||
}, | |||
elementArcanePercent: { | |||
min: 1, | |||
max: 5, | |||
ignore: true | |||
ignore: true, | |||
generator: 'elementDmgPercent' | |||
}, | |||
elementFrostPercent: { | |||
min: 1, | |||
max: 5, | |||
ignore: true | |||
ignore: true, | |||
generator: 'elementDmgPercent' | |||
}, | |||
elementFirePercent: { | |||
min: 1, | |||
max: 5, | |||
ignore: true | |||
ignore: true, | |||
generator: 'elementDmgPercent' | |||
}, | |||
elementHolyPercent: { | |||
min: 1, | |||
max: 5, | |||
ignore: true | |||
ignore: true, | |||
generator: 'elementDmgPercent' | |||
}, | |||
elementPhysicalPercent: { | |||
min: 1, | |||
max: 5, | |||
ignore: true | |||
ignore: true, | |||
generator: 'elementDmgPercent' | |||
}, | |||
elementPoisonPercent: { | |||
min: 1, | |||
max: 5, | |||
ignore: true | |||
ignore: true, | |||
generator: 'elementDmgPercent' | |||
}, | |||
allAttributes: { | |||
generator: 'mainStat', | |||
@@ -166,6 +206,14 @@ define([ | |||
}, | |||
attackSpeed: { | |||
min: 1, | |||
max: 8.75, | |||
ignore: true | |||
}, | |||
castSpeed: { | |||
min: 1, | |||
max: 8.75, | |||
ignore: true | |||
}, | |||
@@ -174,13 +222,26 @@ define([ | |||
ignore: true | |||
}, | |||
addCritChance: { | |||
blockAttackChance: { | |||
min: 1, | |||
max: 90 | |||
max: 10, | |||
ignore: true | |||
}, | |||
blockSpellChance: { | |||
min: 1, | |||
max: 10, | |||
ignore: true | |||
}, | |||
addCritChance: { | |||
generator: 'addCritChance', | |||
level: { | |||
min: 3 | |||
} | |||
}, | |||
addCritMultiplier: { | |||
min: 5, | |||
max: 50 | |||
generator: 'addCritMultiplier' | |||
}, | |||
magicFind: { | |||
@@ -207,71 +268,85 @@ define([ | |||
} | |||
}, | |||
finger: { | |||
dmgPercent: { | |||
offHand: { | |||
}, | |||
trinket: { | |||
attackSpeed: { | |||
min: 1, | |||
max: 5 | |||
max: 8.75, | |||
}, | |||
elementArcanePercent: { | |||
castSpeed: { | |||
min: 1, | |||
max: 5 | |||
max: 8.75, | |||
} | |||
}, | |||
finger: { | |||
elementArcanePercent: { | |||
generator: 'elementDmgPercent' | |||
}, | |||
elementFrostPercent: { | |||
min: 1, | |||
max: 5 | |||
generator: 'elementDmgPercent' | |||
}, | |||
elementFirePercent: { | |||
min: 1, | |||
max: 5 | |||
generator: 'elementDmgPercent' | |||
}, | |||
elementHolyPercent: { | |||
min: 1, | |||
max: 5 | |||
generator: 'elementDmgPercent' | |||
}, | |||
elementPhysicalPercent: { | |||
min: 1, | |||
max: 5 | |||
generator: 'elementDmgPercent' | |||
}, | |||
elementPoisonPercent: { | |||
min: 1, | |||
max: 5 | |||
generator: 'elementDmgPercent' | |||
}, | |||
allAttributes: { | |||
generator: 'mainStat' | |||
}, | |||
attackSpeed: { | |||
min: 1, | |||
max: 8.75 | |||
}, | |||
castSpeed: { | |||
min: 1, | |||
max: 8.75 | |||
} | |||
}, | |||
neck: { | |||
dmgPercent: { | |||
min: 1, | |||
max: 10 | |||
generator: 'dmgPercent' | |||
}, | |||
elementArcanePercent: { | |||
min: 1, | |||
max: 10 | |||
generator: 'elementDmgPercent' | |||
}, | |||
elementFrostPercent: { | |||
min: 1, | |||
max: 10 | |||
generator: 'elementDmgPercent' | |||
}, | |||
elementFirePercent: { | |||
min: 1, | |||
max: 10 | |||
generator: 'elementDmgPercent' | |||
}, | |||
elementHolyPercent: { | |||
min: 1, | |||
max: 10 | |||
generator: 'elementDmgPercent' | |||
}, | |||
elementPhysicalPercent: { | |||
min: 1, | |||
max: 10 | |||
generator: 'elementDmgPercent' | |||
}, | |||
elementPoisonPercent: { | |||
min: 1, | |||
max: 10 | |||
generator: 'elementDmgPercent' | |||
}, | |||
allAttributes: { | |||
generator: 'mainStat' | |||
}, | |||
attackSpeed: { | |||
min: 1, | |||
max: 8.75 | |||
}, | |||
castSpeed: { | |||
min: 1, | |||
max: 8.75 | |||
} | |||
} | |||
}, | |||
@@ -292,8 +367,9 @@ define([ | |||
//If we enchant something we don't add armor | |||
if (!blueprint.statMult) | |||
blueprint.statMult = {}; | |||
if (blueprint.statMult.armor) | |||
this.buildStat(item, blueprint, 'armor'); | |||
for (var s in blueprint.statMult) { | |||
this.buildStat(item, blueprint, s); | |||
} | |||
var statCount = blueprint.statCount || (item.quality + 1); | |||
@@ -328,7 +404,16 @@ define([ | |||
}, | |||
buildStat: function (item, blueprint, stat, result) { | |||
var statOptions = extend(true, {}, this.stats, this.slots[item.slot] || {}); | |||
var slotStats = this.slots[item.slot] || {}; | |||
var statOptions = extend(true, {}, this.stats, slotStats || {}); | |||
for (var p in statOptions) { | |||
if ((!slotStats[p]) || (slotStats[p].ignore)) | |||
continue; | |||
delete statOptions[p].ignore; | |||
} | |||
var statBlueprint = null; | |||
var value = null; | |||
@@ -26,6 +26,15 @@ define([ | |||
if ((typeBlueprint.material) && (blueprint.statMult.armor)) | |||
blueprint.statMult.armor *= armorMaterials[typeBlueprint.material].statMult.armor; | |||
if (typeBlueprint.armorMult) | |||
blueprint.statMult.armor = typeBlueprint.armorMult; | |||
if (typeBlueprint.blockAttackMult) | |||
blueprint.statMult.blockAttackChance = typeBlueprint.blockAttackMult; | |||
if (typeBlueprint.blockSpellMult) | |||
blueprint.statMult.blockSpellChance = typeBlueprint.blockSpellMult; | |||
} | |||
} | |||
}); |
@@ -133,14 +133,14 @@ define([ | |||
beforeGetSpellsConfig: function (spells) { | |||
spells['harvest life'] = { | |||
statType: ['str', 'int'], | |||
statMult: 0.1, | |||
statMult: 1.34, | |||
element: 'physical', | |||
auto: true, | |||
cdMax: 6, | |||
manaCost: 0, | |||
range: 1, | |||
random: { | |||
damage: [2.2, 4.1], | |||
damage: [1.5, 5.7], | |||
healPercent: [5, 15] | |||
} | |||
}; | |||
@@ -153,8 +153,8 @@ define([ | |||
manaCost: 5, | |||
range: 9, | |||
random: { | |||
damagePercent: [80, 120], | |||
hpPercent: [65, 85] | |||
damagePercent: [100, 380], | |||
hpPercent: [40, 60] | |||
} | |||
}; | |||
@@ -162,13 +162,13 @@ define([ | |||
statType: ['str', 'int'], | |||
statMult: 0.1, | |||
element: 'physical', | |||
cdMax: 7, | |||
cdMax: 20, | |||
manaCost: 5, | |||
range: 9, | |||
random: { | |||
i_drainPercentage: [10, 50], | |||
shieldMultiplier: [2, 5], | |||
i_frenzyDuration: [10, 20] | |||
i_frenzyDuration: [5, 15] | |||
} | |||
}; | |||
}, | |||
@@ -137,11 +137,13 @@ define([ | |||
}, | |||
'Level 15 Legendary Weapon': function () { | |||
var slot = ['oneHanded', 'twoHanded'][~~(Math.random() * 2)]; | |||
return itemGenerator.generate({ | |||
level: 15, | |||
quality: 4, | |||
noSpell: true, | |||
slot: 'twoHanded' | |||
slot: slot | |||
}); | |||
}, | |||
@@ -259,15 +259,21 @@ define([ | |||
return true; | |||
} | |||
if (!action.isDouble) { | |||
var deltaX = Math.abs(this.x - data.x); | |||
var deltaY = Math.abs(this.y - data.y); | |||
if ( | |||
((deltaX > 1) || (deltaY > 1)) || | |||
((deltaX == 0) && (deltaY == 0)) | |||
var maxDistance = action.isDouble ? 2 : 1; | |||
var deltaX = Math.abs(this.x - data.x); | |||
var deltaY = Math.abs(this.y - data.y); | |||
if ( | |||
( | |||
(deltaX > maxDistance) || | |||
(deltaY > maxDistance) | |||
) || | |||
( | |||
(deltaX == 0) && | |||
(deltaY == 0) | |||
) | |||
return false; | |||
} | |||
) | |||
return false; | |||
} | |||
//Don't allow mob overlap during combat | |||
@@ -10,7 +10,7 @@ | |||
"mysql": "^2.13.0", | |||
"requirejs": "^2.2.0", | |||
"socket.io": "^1.3.6", | |||
"sqlite3": "^3.1.8", | |||
"sqlite3": "^3.1.13", | |||
"unirest": "^0.4.2" | |||
}, | |||
"devDependencies": {} | |||
@@ -1,6 +1,6 @@ | |||
define([ | |||
'fs' | |||
], function( | |||
], function ( | |||
fs | |||
) { | |||
return { | |||
@@ -17,19 +17,20 @@ define([ | |||
leaderboard: null, | |||
customMap: null, | |||
mail: null, | |||
customChannels: null | |||
customChannels: null, | |||
error: null | |||
}, | |||
init: function(cbReady) { | |||
init: function (cbReady) { | |||
var sqlite = require('sqlite3').verbose(); | |||
this.exists = fs.existsSync(this.file); | |||
this.db = new sqlite.Database(this.file, this.onDbCreated.bind(this, cbReady)); | |||
}, | |||
onDbCreated: function(cbReady) { | |||
onDbCreated: function (cbReady) { | |||
var db = this.db; | |||
var tables = this.tables; | |||
var scope = this; | |||
db.serialize(function() { | |||
db.serialize(function () { | |||
for (var t in tables) { | |||
db.run(` | |||
@@ -42,12 +43,12 @@ define([ | |||
this.exists = true; | |||
}, | |||
onTableCreated: function() { | |||
onTableCreated: function () { | |||
}, | |||
//ent, field | |||
get: function(options) { | |||
get: function (options) { | |||
var key = options.ent; | |||
var table = options.field; | |||
@@ -56,7 +57,7 @@ define([ | |||
this.db.get(options.query, this.done.bind(this, options)); | |||
}, | |||
delete: function(options) { | |||
delete: function (options) { | |||
var key = options.ent; | |||
var table = options.field; | |||
@@ -66,13 +67,13 @@ define([ | |||
}, | |||
//ent, field, value | |||
set: function(options) { | |||
set: function (options) { | |||
var key = options.ent; | |||
var table = options.field; | |||
this.db.get(`SELECT 1 FROM ${table} where key = '${key}'`, this.doesExist.bind(this, options)); | |||
}, | |||
doesExist: function(options, err, result) { | |||
doesExist: function (options, err, result) { | |||
var key = options.ent; | |||
var table = options.field; | |||
@@ -84,7 +85,7 @@ define([ | |||
this.db.run(query, this.done.bind(this, options)); | |||
}, | |||
done: function(options, err, result) { | |||
done: function (options, err, result) { | |||
result = result || { | |||
value: null | |||
}; | |||
@@ -93,4 +94,4 @@ define([ | |||
options.callback(result.value); | |||
} | |||
}; | |||
}); | |||
}); |
@@ -41,9 +41,12 @@ define([ | |||
global.gc(); | |||
}, 60000); | |||
process.on('uncaughtException', this.onError.bind(this)); | |||
animations.init(); | |||
mods.init(this.onModsLoaded.bind(this)); | |||
}, | |||
onModsLoaded: function () { | |||
globals.init(); | |||
classes.init(); | |||
@@ -52,14 +55,32 @@ define([ | |||
itemTypes.init(); | |||
components.init(this.onComponentsReady.bind(this)); | |||
}, | |||
onComponentsReady: function () { | |||
skins.init(); | |||
factions.init(); | |||
server.init(this.onServerReady.bind(this)); | |||
}, | |||
onServerReady: function () { | |||
atlas.init(); | |||
leaderboard.init(); | |||
}, | |||
onError: function (e) { | |||
if (e.toString().indexOf('ERR_IPC_CHANNEL_CLOSED') > -1) | |||
return; | |||
console.log('Error Logged: ' + e.toString()); | |||
io.set({ | |||
ent: new Date(), | |||
field: 'error', | |||
value: e.toString() + ' | ' + e.stack.toString(), | |||
callback: function () { | |||
process.exit(); | |||
} | |||
}); | |||
} | |||
}; | |||
}); |
@@ -147,7 +147,10 @@ define([ | |||
onMessage: function (thread, message) { | |||
if (message.module) | |||
global[message.module][message.method](message); | |||
else | |||
else if (message.event == 'onCrashed') { | |||
thread.worker.kill(); | |||
process.exit(); | |||
} else | |||
this.thread[message.method].call(this, thread, message); | |||
}, | |||
thread: { | |||
@@ -365,7 +365,6 @@ define([ | |||
obj.y = spawnPos.y; | |||
} | |||
obj.instance.spawners.scale(obj.stats.values.level); | |||
obj.instance.questBuilder.obtain(obj); | |||
if (obj.player) | |||
@@ -516,7 +515,6 @@ define([ | |||
obj.y = spawnPos.y; | |||
instance.questBuilder.obtain(obj); | |||
obj.instance.spawners.scale(obj.stats.values.level); | |||
} | |||
process.send({ | |||
@@ -116,7 +116,7 @@ define([ | |||
mob.equipment.unequipAll(); | |||
mob.inventory.clear(); | |||
var hp = 10 + (level * 120); | |||
var hp = ~~(30 + (Math.pow(level, 3) * 0.072)); | |||
statValues.hpMax = hp; | |||
statValues.level = level; | |||
@@ -163,8 +163,6 @@ define([ | |||
spell: true | |||
}); | |||
rune.eq = true; | |||
if (i == 0) | |||
rune.spell.cdMult = 5; | |||
mob.inventory.getItem(rune); | |||
} | |||
@@ -172,8 +170,8 @@ define([ | |||
var hpMult = 1 * mob.mob.hpMult; | |||
if (level < 10) { | |||
hpMult *= [0.0077, 0.01, 0.035, 0.08, 0.16, 0.28, 0.43, 0.62, 0.8][level - 1]; | |||
dmgMult *= [0.1, 0.2, 0.4, 0.7, 1, 1, 1, 1, 1][level - 1]; | |||
statValues.hpMax = ~~(statValues.hpMax * (level / 10)); | |||
//dmgMult *= [0.1, 0.2, 0.4, 0.7, 1, 1, 1, 1, 1][level - 1]; | |||
} | |||
if (mob.isRare) { | |||
@@ -195,18 +193,6 @@ define([ | |||
s.statType = preferStat; | |||
s.element = elementType; | |||
s.manaCost = 0; | |||
/*var damage = combat.getDamage({ | |||
source: mob, | |||
target: mob, | |||
damage: (s.damage || s.healing) * (s.dmgMult || 1), | |||
cd: s.cdMax, | |||
element: s.element, | |||
statType: s.statType, | |||
statMult: s.statMult, | |||
noMitigate: false, | |||
noCrit: true | |||
});*/ | |||
}, this); | |||
['hp', 'hpMax', 'mana', 'manaMax', 'level'].forEach(function (s) { | |||
@@ -1,6 +1,6 @@ | |||
define([ | |||
], function( | |||
], function ( | |||
) { | |||
return { | |||
@@ -15,7 +15,7 @@ define([ | |||
bounds: [0, 0, 0, 0], | |||
generate: function(instance) { | |||
generate: function (instance) { | |||
this.rooms = []; | |||
this.exitAreas = []; | |||
this.tileMappings = {}; | |||
@@ -38,7 +38,7 @@ define([ | |||
} | |||
}, | |||
isValidDungeon: function() { | |||
isValidDungeon: function () { | |||
var endRooms = this.rooms.filter(r => r.connections.length == 0); | |||
var endDistanceReached = endRooms.find(r => r.distance == this.maxDistance, this); | |||
@@ -48,7 +48,7 @@ define([ | |||
var valid = true; | |||
endRooms | |||
.forEach(function(r) { | |||
.forEach(function (r) { | |||
if (r.distance < this.minDistance) | |||
valid = false; | |||
else if (r.distance > this.maxDistance) | |||
@@ -58,8 +58,8 @@ define([ | |||
return valid; | |||
}, | |||
setupTemplates: function(map) { | |||
this.templates.forEach(function(r, typeId) { | |||
setupTemplates: function (map) { | |||
this.templates.forEach(function (r, typeId) { | |||
if (r.properties.mapping) | |||
return; | |||
@@ -77,7 +77,7 @@ define([ | |||
rotate: !!k | |||
}, r); | |||
flipped.exits.forEach(function(e) { | |||
flipped.exits.forEach(function (e) { | |||
var direction = JSON.parse(e.properties.exit); | |||
if (flipped.flipX) { | |||
@@ -101,7 +101,7 @@ define([ | |||
e.properties.exit = JSON.stringify(direction); | |||
}); | |||
flipped.objects.forEach(function(o) { | |||
flipped.objects.forEach(function (o) { | |||
if (flipped.flipX) | |||
o.x = r.x + r.width - (o.x - r.x) - 1; | |||
if (flipped.flipY) | |||
@@ -125,7 +125,7 @@ define([ | |||
} | |||
}, this); | |||
this.templates.forEach(function(r) { | |||
this.templates.forEach(function (r) { | |||
var rotate = r.rotate; | |||
var w = rotate ? r.height : r.width; | |||
var h = rotate ? r.width : r.height; | |||
@@ -151,12 +151,12 @@ define([ | |||
}); | |||
}, | |||
generateMappings: function(map) { | |||
generateMappings: function (map) { | |||
var oldMap = map.oldMap; | |||
this.templates | |||
.filter(r => r.properties.mapping) | |||
.forEach(function(m) { | |||
.forEach(function (m) { | |||
var x = m.x; | |||
var y = m.y; | |||
var w = m.width; | |||
@@ -189,7 +189,7 @@ define([ | |||
}, this); | |||
}, | |||
buildMap: function(instance, startRoom) { | |||
buildMap: function (instance, startRoom) { | |||
var w = this.bounds[2] - this.bounds[0]; | |||
var h = this.bounds[3] - this.bounds[1]; | |||
@@ -214,7 +214,7 @@ define([ | |||
this.spawnObjects(instance, startRoom); | |||
}, | |||
fillGaps: function(instance) { | |||
fillGaps: function (instance) { | |||
var map = instance.map.clientMap.map; | |||
var oldMap = instance.map.oldMap; | |||
var w = map.length; | |||
@@ -248,7 +248,7 @@ define([ | |||
} | |||
}, | |||
randomizeTile: function(tile, floorTile, gapMapping) { | |||
randomizeTile: function (tile, floorTile, gapMapping) { | |||
var mapping = gapMapping ? this.gapMappings[tile] : this.tileMappings[tile]; | |||
if (!mapping) | |||
return tile; | |||
@@ -264,7 +264,7 @@ define([ | |||
return tile; | |||
}, | |||
drawRoom: function(instance, room) { | |||
drawRoom: function (instance, room) { | |||
var map = instance.map.clientMap.map; | |||
var template = room.template; | |||
var collisionMap = instance.map.clientMap.collisionMap; | |||
@@ -288,7 +288,7 @@ define([ | |||
continue; | |||
} else { | |||
//Remove objects from this position since it falls in another room | |||
template.objects.spliceWhere(function(o) { | |||
template.objects.spliceWhere(function (o) { | |||
var ox = o.x - template.x + room.x; | |||
var oy = o.y - template.y + room.y; | |||
return ((ox == x) && (oy == y)); | |||
@@ -298,11 +298,11 @@ define([ | |||
var didCollide = collisionMap[x][y]; | |||
if (collides) { | |||
if (didCollide) { | |||
var isExitTile = this.exitAreas.find(function(e) { | |||
var isExitTile = this.exitAreas.find(function (e) { | |||
return (!((x < e.x) || (y < e.y) || (x >= e.x + e.width) || (y >= e.y + e.height))); | |||
}); | |||
if (isExitTile) { | |||
var isThisExit = template.oldExits.find(function(e) { | |||
var isThisExit = template.oldExits.find(function (e) { | |||
var ex = room.x + (e.x - template.x); | |||
var ey = room.y + (e.y - template.y); | |||
return (!((x < ex) || (y < ey) || (x >= ex + e.width) || (y >= ey + e.height))); | |||
@@ -321,7 +321,7 @@ define([ | |||
} | |||
} | |||
template.oldExits.forEach(function(e) { | |||
template.oldExits.forEach(function (e) { | |||
this.exitAreas.push({ | |||
x: room.x + (e.x - template.x), | |||
y: room.y + (e.y - template.y), | |||
@@ -333,14 +333,14 @@ define([ | |||
room.connections.forEach(c => this.drawRoom(instance, c), this); | |||
}, | |||
spawnObjects: function(instance, room) { | |||
spawnObjects: function (instance, room) { | |||
var template = room.template; | |||
var spawners = instance.spawners; | |||
var spawnCd = instance.map.mapFile.properties.spawnCd; | |||
var collisionMap = instance.map.clientMap.collisionMap; | |||
template.objects.forEach(function(o) { | |||
template.objects.forEach(function (o) { | |||
o.x = o.x - template.x + room.x; | |||
o.y = o.y - template.y + room.y; | |||
@@ -354,7 +354,7 @@ define([ | |||
room.connections.forEach(c => this.spawnObjects(instance, c), this); | |||
}, | |||
buildRoom: function(template, connectTo, templateExit, connectToExit, isHallway) { | |||
buildRoom: function (template, connectTo, templateExit, connectToExit, isHallway) { | |||
var room = { | |||
x: 0, | |||
y: 0, | |||
@@ -397,13 +397,13 @@ define([ | |||
return room; | |||
}, | |||
setupConnection: function(fromRoom, isHallway) { | |||
setupConnection: function (fromRoom, isHallway) { | |||
if (fromRoom.template.exits.length == 0) | |||
return true; | |||
var fromExit = fromRoom.template.exits.splice(this.randInt(0, fromRoom.template.exits.length), 1)[0]; | |||
var exitDirection = JSON.parse(fromExit.properties.exit); | |||
var templates = this.templates.filter(function(t) { | |||
var templates = this.templates.filter(function (t) { | |||
if ( | |||
(t.properties.mapping) || | |||
(!!t.properties.hallway != isHallway) || | |||
@@ -415,7 +415,7 @@ define([ | |||
) | |||
return false; | |||
else { | |||
var isValid = t.exits.some(function(e) { | |||
var isValid = t.exits.some(function (e) { | |||
var direction = JSON.parse(e.properties.exit); | |||
return ((direction[0] == -exitDirection[0]) && (direction[1] == -exitDirection[1])); | |||
}); | |||
@@ -429,7 +429,7 @@ define([ | |||
if ((isValid) && (fromRoom.distance + 1 == this.maxDistance)) { | |||
//If there is an exit available, rather use that | |||
if (!t.properties.end) { | |||
var endsAvailable = this.templates.filter(function(tt) { | |||
var endsAvailable = this.templates.filter(function (tt) { | |||
if (!tt.properties.end) | |||
return false; | |||
else if (!~~tt.properties.maxOccur) | |||
@@ -454,7 +454,7 @@ define([ | |||
var template = extend(true, {}, templates[this.randInt(0, templates.length)]); | |||
var templateExit = template.exits.filter(function(e) { | |||
var templateExit = template.exits.filter(function (e) { | |||
var direction = JSON.parse(e.properties.exit); | |||
return ((direction[0] == -exitDirection[0]) && (direction[1] == -exitDirection[1])); | |||
}); | |||
@@ -472,7 +472,7 @@ define([ | |||
return true; | |||
}, | |||
offsetRooms: function(room) { | |||
offsetRooms: function (room) { | |||
var bounds = this.bounds; | |||
var dx = (this.bounds[0] < 0) ? -bounds[0] : 0; | |||
var dy = (this.bounds[1] < 0) ? -bounds[1] : 0; | |||
@@ -482,21 +482,21 @@ define([ | |||
this.bounds = [bounds[0] + dx, bounds[1] + dy, bounds[2] + dx, bounds[3] + dy]; | |||
}, | |||
performOffset: function(room, dx, dy) { | |||
performOffset: function (room, dx, dy) { | |||
room.x += dx; | |||
room.y += dy; | |||
room.connections.forEach(c => this.performOffset(c, dx, dy), this); | |||
}, | |||
updateBounds: function(room) { | |||
updateBounds: function (room) { | |||
this.bounds[0] = Math.min(this.bounds[0], room.x); | |||
this.bounds[1] = Math.min(this.bounds[1], room.y); | |||
this.bounds[2] = Math.max(this.bounds[2], room.x + room.template.width); | |||
this.bounds[3] = Math.max(this.bounds[3], room.y + room.template.height); | |||
}, | |||
doesCollide: function(room, ignore) { | |||
doesCollide: function (room, ignore) { | |||
for (var i = 0; i < this.rooms.length; i++) { | |||
var r = this.rooms[i]; | |||
if (r == ignore) | |||
@@ -515,8 +515,8 @@ define([ | |||
return false; | |||
}, | |||
randInt: function(min, max) { | |||
randInt: function (min, max) { | |||
return ~~(Math.random() * (max - min)) + min; | |||
} | |||
}; | |||
}); | |||
}); |
@@ -62,6 +62,24 @@ requirejs([ | |||
setInterval(function () { | |||
global.gc(); | |||
}, 60000); | |||
process.on('uncaughtException', function (e) { | |||
if (e.toString().indexOf('ERR_IPC_CHANNEL_CLOSED') > -1) | |||
return; | |||
console.log('Error Logged: ' + e.toString()); | |||
io.set({ | |||
ent: new Date(), | |||
field: 'error', | |||
value: e.toString() + ' | ' + e.stack.toString(), | |||
callback: function () { | |||
process.send({ | |||
event: 'onCrashed' | |||
}); | |||
} | |||
}); | |||
}); | |||
}; | |||
var onCpnsReady = function () { | |||