diff --git a/src/client/js/rendering/numbers.js b/src/client/js/rendering/numbers.js index 1be60b29..b1ac81ba 100644 --- a/src/client/js/rendering/numbers.js +++ b/src/client/js/rendering/numbers.js @@ -24,20 +24,28 @@ define([ var addY = msg.event ? scale : -(scale * 0.75); - var ttl = 30 * (msg.crit ? 1 : 1); + var ttl = 35; var numberObj = { obj: target, amount: msg.amount, - x: (target.x * scale) + ~~(Math.random() * scale - (scale / 2)), - y: (target.y * scale) + addY, + x: (target.x * scale), + y: (target.y * scale) + scale - (scale / 4), ttl: ttl, ttlMax: ttl, event: msg.event, text: msg.text, crit: msg.crit, heal: msg.heal - }; + }; + + if (numberObj.event) { + numberObj.y += (scale / 2); + } + else if (numberObj.heal) + numberObj.x -= scale; + else + numberObj.x += scale; var text = numberObj.text; if (!numberObj.event) @@ -74,9 +82,9 @@ define([ } if (l.event) - l.y += 0.75; + l.y += 1; else - l.y -= 0.75; + l.y -= 1; var alpha = l.ttl / l.ttlMax; diff --git a/src/server/components/aggro.js b/src/server/components/aggro.js index 3d9eadbd..44feaaf4 100644 --- a/src/server/components/aggro.js +++ b/src/server/components/aggro.js @@ -151,6 +151,10 @@ define([ }, tryEngage: function(obj, amount, threatMult) { + //Don't aggro yourself, stupid + if (obj == this.obj) + return; + var result = { success: true }; @@ -293,7 +297,7 @@ define([ for (var i = 0; i < lLen; i++) { var l = list[i]; if (l.obj.destroyed) { - list.splice(i, 1); + this.unAggro(l.obj); i--; lLen--; } diff --git a/src/server/components/follower.js b/src/server/components/follower.js index 9a8ce8f8..c8418d59 100644 --- a/src/server/components/follower.js +++ b/src/server/components/follower.js @@ -11,13 +11,22 @@ define([ lifetime: -1, maxDistance: 10, + lastMasterPos: { + x: 0, + y: 0 + }, + fGetHighest: { inCombat: null, outOfCombat: null }, bindEvents: function() { - this.fGetHighest.inCombat = this.master.aggro.getHighest.bind(this.master.aggro); + var master = this.master; + this.lastMasterPos.x = master.x; + this.lastMasterPos.y = master.y; + + this.fGetHighest.inCombat = master.aggro.getHighest.bind(master.aggro); this.fGetHighest.outOfCombat = this.returnNoAggro.bind(this); }, @@ -47,6 +56,35 @@ define([ }); }, + teleport: function() { + var obj = this.obj; + var physics = obj.instance.physics; + var syncer = obj.syncer; + var master = this.master; + + var newPosition = physics.getOpenCellInArea(master.x - 1, master.y - 1, master.x + 1, master.y + 1); + + physics.removeObject(obj, obj.x, obj.y); + + obj.x = newPosition.x; + obj.y = newPosition.y; + + syncer.o.x = obj.x; + syncer.o.y = obj.y; + + physics.addObject(obj, obj.x, obj.y); + + obj.instance.syncer.queue('onGetObject', { + x: obj.x, + y: obj.y, + components: [{ + type: 'attackAnimation', + row: 0, + col: 4 + }] + }); + }, + update: function() { if (this.lifetime > 0) { this.lifetime--; @@ -65,17 +103,32 @@ define([ } var maxDistance = this.maxDistance; + var distance = Math.max(Math.abs(obj.x - master.x), Math.abs(obj.y - master.y)); - var doMove = ( - (Math.abs(obj.x - master.x) >= maxDistance) || - (Math.abs(obj.y - master.y) >= maxDistance) - ); + var doMove = (distance >= maxDistance); + //When we're too far, just teleport + if (distance >= maxDistance * 2) { + this.teleport(); + return; + } - if (doMove) { - if (obj.aggro.getHighest == this.fGetHighest.inCombat) - obj.mob.target = obj; + var doMove = false; + //If we're not too far from the master but the master is not in combat, move anyway + var attacker = this.fGetHighest.inCombat(); + if (!attacker) { + var lastMasterPos = this.lastMasterPos; + + if ((master.x != lastMasterPos.x) || (master.y != lastMasterPos.y)) { + doMove = true; + lastMasterPos.x = master.x; + lastMasterPos.y = master.y; + } } + if (doMove) { + this.obj.clearQueue(); + obj.mob.target = obj; + } obj.aggro.getHighest = doMove ? this.fGetHighest.outOfCombat : this.fGetHighest.inCombat; }, diff --git a/src/server/components/mob.js b/src/server/components/mob.js index dd84cc37..76a18e6f 100644 --- a/src/server/components/mob.js +++ b/src/server/components/mob.js @@ -34,7 +34,7 @@ define([ if ((target) && (target != this.obj) && ((!this.obj.follower) || (this.obj.follower.master != target))) { this.fight(target); return; - } else if (this.target) { + } else if ((!target) && (this.target)) { this.target = null; this.obj.clearQueue(); goHome = true; diff --git a/src/server/components/stats.js b/src/server/components/stats.js index 8e025351..345190b2 100644 --- a/src/server/components/stats.js +++ b/src/server/components/stats.js @@ -77,7 +77,7 @@ define([ }, update: function() { - if ((this.obj.mob) || (this.dead)) + if (((this.obj.mob) && (!this.obj.follower)) || (this.dead)) return; var regen = { @@ -302,6 +302,11 @@ define([ recipients.push(this.obj.serverId); if (source.serverId != null) recipients.push(source.serverId); + if ((source.follower) && (source.follower.master.serverId)) + recipients.push(source.follower.master.serverId); + if ((this.obj.follower) && (this.obj.follower.master.serverId)) + recipients.push(this.obj.follower.master.serverId); + if (recipients.length > 0) { this.syncer.queue('onGetDamage', { id: this.obj.id, diff --git a/src/server/mods/class-necromancer/index.js b/src/server/mods/class-necromancer/index.js index 96d45a2c..dcdd3e64 100644 --- a/src/server/mods/class-necromancer/index.js +++ b/src/server/mods/class-necromancer/index.js @@ -82,10 +82,10 @@ define([ auto: true, cdMax: 7, manaCost: 0, - range: 9, + range: 1, random: { damage: [2, 4], - healPercent: [10, 20] + healPercent: [25, 75] } }; @@ -110,8 +110,8 @@ define([ manaCost: 0, range: 9, random: { - damage: [2, 4], - shieldPercentage: [50, 150] + i_drainPercentage: [10, 50], + shieldMultiplier: [2, 5] } }; }, diff --git a/src/server/mods/class-necromancer/spells/spellBloodBarrier.js b/src/server/mods/class-necromancer/spells/spellBloodBarrier.js index 812fe2c9..4b3c0470 100644 --- a/src/server/mods/class-necromancer/spells/spellBloodBarrier.js +++ b/src/server/mods/class-necromancer/spells/spellBloodBarrier.js @@ -33,12 +33,13 @@ define([ if ((this.obj.destroyed) || (target.destroyed)) return; - var amount = this.obj.stats.values.hpMax / 10; + var amount = this.obj.stats.values.hpMax / 100 * this.drainPercentage; var damage = { amount: amount }; this.obj.stats.takeDamage(damage, 0, this.obj); + amount = amount * this.shieldMultiplier; var heal = { amount: amount }; diff --git a/src/server/mods/class-necromancer/spells/spellSummonSkeleton.js b/src/server/mods/class-necromancer/spells/spellSummonSkeleton.js index 2a67971f..12a0870f 100644 --- a/src/server/mods/class-necromancer/spells/spellSummonSkeleton.js +++ b/src/server/mods/class-necromancer/spells/spellSummonSkeleton.js @@ -23,7 +23,7 @@ define([ currentMinion.destroyed = true; this.minions = []; - this.obj.syncer.queue('onGetObject', { + this.obj.instance.syncer.queue('onGetObject', { x: currentMinion.x, y: currentMinion.y, components: [{ @@ -60,20 +60,22 @@ define([ }); mobBuilder.build(mob, { - level: 1, + level: obj.stats.values.level, faction: obj.aggro.faction, walkDistance: 2, regular: { drops: 0, - hpMult: 0.1, - dmgMult: 1 + hpMult: 0.5, + dmgMult: 0.01 }, spells: [{ type: 'melee', damage: 1, - statMult: 0.000001 + statMult: 1 }] }, false, 'regular'); + mob.stats.values.regenHp = mob.stats.values.hpMax / 100; + mob.spellbook.spells[0].threatMult *= 10; mob.follower.bindEvents(); diff --git a/src/server/world/mobBuilder.js b/src/server/world/mobBuilder.js index bcc2e368..f33846b9 100644 --- a/src/server/world/mobBuilder.js +++ b/src/server/world/mobBuilder.js @@ -39,8 +39,8 @@ define([ var cpnMob = mob.addComponent('mob'); cpnMob.walkDistance = blueprint.walkDistance; - cpnMob.hpMult = typeDefinition.hpMult; - cpnMob.dmgMult = typeDefinition.dmgMult; + cpnMob.hpMult = blueprint.hpMult || typeDefinition.hpMult; + cpnMob.dmgMult = blueprint.dmgMult || typeDefinition.dmgMult; cpnMob.grantRep = blueprint.grantRep; cpnMob.deathRep = blueprint.deathRep; @@ -53,7 +53,7 @@ define([ } }); - mob.addComponent('spellbook', { + mob.addComponent('spellbook', { spells: spells, dmgMult: typeDefinition.dmgMult }); @@ -152,30 +152,8 @@ define([ mob.inventory.getItem(rune); } - /*var rune = itemGenerator.generate({ - spell: true, - spellName: 'crystal spikes', - spellProperties: { - radius: 4, - attackTemplate: '0 x x x x x x x 0 x 1 x x x x x 1 x x x 2 x x x 2 x x x x x 3 x 3 x x x x x x x 4 x x x x x x x 3 x 3 x x x x x 2 x x x 2 x x x 1 x x x x x 1 x 0 x x x x x x x 0' - } - }); - rune.eq = true; - if (i == 0) - rune.spell.cdMult = 1; - mob.inventory.getItem(rune); - - rune = itemGenerator.generate({ - spell: true, - spellName: 'magic missile' - }); - rune.eq = true; - if (i == 0) - rune.spell.cdMult = 1; - mob.inventory.getItem(rune);*/ - - var dmgMult = 4; - var hpMult = 1; + var dmgMult = 4 * mob.mob.dmgMult; + var hpMult = 1 * mob.mob.hpMult; if (level < 10) { hpMult *= [0.005, 0.01, 0.1, 0.2, 0.5, 0.65, 0.75, 0.85, 0.95][level - 1];