@@ -13,7 +13,7 @@ define([ | |||||
effect: null, | effect: null, | ||||
ttl: 6000, | |||||
ttl: 6, | |||||
init: function() { | init: function() { | ||||
effects.register(this); | effects.register(this); | ||||
@@ -14,7 +14,6 @@ define([ | |||||
lines: [] | lines: [] | ||||
}; | }; | ||||
var divisions = 20; | |||||
var maxDeviate = scale * 0.3; | var maxDeviate = scale * 0.3; | ||||
var fx = config.fromX * scale; | var fx = config.fromX * scale; | ||||
@@ -25,7 +24,8 @@ define([ | |||||
var angle = Math.atan2(ty - fy, tx - fx); | var angle = Math.atan2(ty - fy, tx - fx); | ||||
var distance = Math.sqrt(Math.pow(tx - fx, 2) + Math.pow(ty - fy, 2)); | var distance = Math.sqrt(Math.pow(tx - fx, 2) + Math.pow(ty - fy, 2)); | ||||
var divDistance = distance / divisions; | |||||
var divDistance = Math.min(20, distance); | |||||
var divisions = Math.max(1, distance / divDistance); | |||||
var x = fx; | var x = fx; | ||||
var y = fy; | var y = fy; | ||||
@@ -12,13 +12,15 @@ define([ | |||||
var tgtValues = config.target.stats.values; | var tgtValues = config.target.stats.values; | ||||
var statValue = 0; | var statValue = 0; | ||||
var statType = config.statType; | |||||
if (!(statType instanceof Array)) | |||||
statType = [statType]; | |||||
var dmg = 0; | |||||
statType.forEach(function(s) { | |||||
statValue += srcValues[s]; | |||||
}); | |||||
if (config.statType) { | |||||
var statType = config.statType; | |||||
if (!(statType instanceof Array)) | |||||
statType = [statType]; | |||||
var dmg = 0; | |||||
statType.forEach(function(s) { | |||||
statValue += srcValues[s]; | |||||
}); | |||||
} | |||||
statValue = max(1, statValue); | statValue = max(1, statValue); | ||||
@@ -30,8 +32,10 @@ define([ | |||||
resist += (tgtValues[elementName + 'Resist'] || 0); | resist += (tgtValues[elementName + 'Resist'] || 0); | ||||
} | } | ||||
var statMult = config.statMult || 1; | |||||
var dps = ( | var dps = ( | ||||
(config.statMult * statValue * config.damage) * | |||||
(statMult * statValue * config.damage) * | |||||
max((0.5 + (dmgPercent / 100)), 0.5) | max((0.5 + (dmgPercent / 100)), 0.5) | ||||
); | ); | ||||
@@ -44,9 +48,12 @@ define([ | |||||
); | ); | ||||
} | } | ||||
var cd = config.source.mob ? 1 : config.cd; | |||||
var amount = dps; | |||||
var amount = dps * cd * 0.3; | |||||
if ((config.source.mob) || (config.cd)) { | |||||
var cd = config.source.mob ? 1 : config.cd; | |||||
amount *= cd * 0.3; | |||||
} | |||||
var isCrit = false; | var isCrit = false; | ||||
if (!config.noCrit) { | if (!config.noCrit) { | ||||
@@ -58,6 +65,13 @@ define([ | |||||
} | } | ||||
} | } | ||||
isCrit = Math.random() < 0.4; | |||||
if (config.target.player) | |||||
amount = 0; | |||||
else | |||||
amount = 99999; | |||||
return { | return { | ||||
amount: amount, | amount: amount, | ||||
crit: isCrit, | crit: isCrit, | ||||
@@ -17,6 +17,9 @@ define([ | |||||
}, | }, | ||||
update: function() { | update: function() { | ||||
if ((this.obj.aggro) && (this.obj.aggro.list.length > 0)) | |||||
return; | |||||
if ((this.cd == 0) && (Math.random() < this.chance)) { | if ((this.cd == 0) && (Math.random() < this.chance)) { | ||||
this.cd = this.cdMax; | this.cd = this.cdMax; | ||||
@@ -612,14 +612,20 @@ define([ | |||||
drop.level = drop.level || level; | drop.level = drop.level || level; | ||||
drop.magicFind = magicFind; | drop.magicFind = magicFind; | ||||
this.getItem(generator.generate(drop), true); | |||||
var item = drop; | |||||
if (!item.quest) | |||||
item = generator.generate(drop); | |||||
this.getItem(item, true); | |||||
} | } | ||||
killSource.fireEvent('beforeTargetDeath', this.obj, this.items); | killSource.fireEvent('beforeTargetDeath', this.obj, this.items); | ||||
if (this.items.length > 0) | if (this.items.length > 0) | ||||
this.createBag(this.obj.x, this.obj.y, this.items, ownerId); | this.createBag(this.obj.x, this.obj.y, this.items, ownerId); | ||||
} else { | |||||
} | |||||
if ((!blueprint.noRandom) || (blueprint.alsoRandom)) { | |||||
var instancedItems = extend(true, [], this.items); | var instancedItems = extend(true, [], this.items); | ||||
var useItems = []; | var useItems = []; | ||||
@@ -731,7 +737,7 @@ define([ | |||||
if (!effectEvent) | if (!effectEvent) | ||||
continue; | continue; | ||||
effectEvent.call(this.obj, item, args[0]); | |||||
effectEvent.apply(this.obj, [item, ...args]); | |||||
} | } | ||||
} | } | ||||
}, | }, | ||||
@@ -34,7 +34,9 @@ define([ | |||||
var factionBlueprint = null; | var factionBlueprint = null; | ||||
try { | try { | ||||
factionBlueprint = require('config/factions/' + factionId); | factionBlueprint = require('config/factions/' + factionId); | ||||
} catch (e) {} | |||||
} catch (e) { | |||||
console.log(e); | |||||
} | |||||
if (factionBlueprint == null) | if (factionBlueprint == null) | ||||
return; | return; | ||||
@@ -1,9 +1,11 @@ | |||||
define([ | define([ | ||||
'world/spawners', | 'world/spawners', | ||||
'world/mobBuilder' | |||||
'world/mobBuilder', | |||||
'combat/combat' | |||||
], function( | ], function( | ||||
spawners, | spawners, | ||||
mobBuilder | |||||
mobBuilder, | |||||
combat | |||||
) { | ) { | ||||
return { | return { | ||||
id: 'akarei', | id: 'akarei', | ||||
@@ -11,9 +13,11 @@ define([ | |||||
description: `The last descendents of the ancient Akarei.`, | description: `The last descendents of the ancient Akarei.`, | ||||
uniqueStat: { | uniqueStat: { | ||||
damage: 1, | |||||
chance: { | chance: { | ||||
min: 3, | |||||
max: 12 | |||||
min: 20, | |||||
max: 45 | |||||
}, | }, | ||||
generate: function(item) { | generate: function(item) { | ||||
@@ -49,17 +53,41 @@ define([ | |||||
}, | }, | ||||
events: { | events: { | ||||
beforeDealDamage: function(damage, target) { | |||||
beforeDealDamage: function(item, damage, target) { | |||||
if (!damage.crit) | if (!damage.crit) | ||||
return; | return; | ||||
var effect = item.effects.find(e => (e.factionId == 'akarei')); | |||||
/*var effect = item.effects.find(e => (e.factionId == 'akarei')); | |||||
var roll = Math.random() * 100; | var roll = Math.random() * 100; | ||||
if (roll >= effect.chance) | if (roll >= effect.chance) | ||||
return; | |||||
return;*/ | |||||
var cbExplode = function(target) { | |||||
if ((this.destroyed) || (target.destroyed)) | |||||
return; | |||||
var damage = combat.getDamage({ | |||||
source: this, | |||||
target: target, | |||||
damage: 1, | |||||
element: 'arcane', | |||||
noCrit: true | |||||
}); | |||||
target.stats.takeDamage(damage, 1, this); | |||||
}; | |||||
this.instance.syncer.queue('onGetObject', { | |||||
id: this.id, | |||||
components: [{ | |||||
type: 'lightningEffect', | |||||
toX: target.x, | |||||
toY: target.y | |||||
}] | |||||
}); | |||||
this.spellbook.registerCallback(this.id, cbExplode.bind(this, target), 1); | |||||
} | } | ||||
} | } | ||||
}, | }, | ||||
@@ -0,0 +1,45 @@ | |||||
module.exports = { | |||||
'cult leader': { | |||||
'1': { | |||||
msg: [{ | |||||
msg: `Is there anything I can help you with today?`, | |||||
options: [1.1, 1.2, 1.3] | |||||
}], | |||||
options: { | |||||
'1.1': { | |||||
msg: `I'd like to browse your wares.`, | |||||
goto: 'tradeBuy' | |||||
}, | |||||
'1.2': { | |||||
msg: `I have some items to sell`, | |||||
goto: 'tradeSell' | |||||
}, | |||||
'1.3': { | |||||
msg: `I want to buy something back`, | |||||
goto: 'tradeBuyback' | |||||
} | |||||
} | |||||
}, | |||||
tradeBuy: { | |||||
cpn: 'trade', | |||||
method: 'startBuy', | |||||
args: [{ | |||||
targetName: 'cult leader' | |||||
}] | |||||
}, | |||||
tradeSell: { | |||||
cpn: 'trade', | |||||
method: 'startSell', | |||||
args: [{ | |||||
targetName: 'cult leader' | |||||
}] | |||||
}, | |||||
tradeBuyback: { | |||||
cpn: 'trade', | |||||
method: 'startBuyback', | |||||
args: [{ | |||||
targetName: 'cult leader' | |||||
}] | |||||
} | |||||
} | |||||
}; |
@@ -720,7 +720,7 @@ | |||||
"gid":320, | "gid":320, | ||||
"height":8, | "height":8, | ||||
"id":867, | "id":867, | ||||
"name":"", | |||||
"name":"cult leader", | |||||
"rotation":0, | "rotation":0, | ||||
"type":"", | "type":"", | ||||
"visible":true, | "visible":true, | ||||
@@ -787,6 +787,17 @@ | |||||
"width":8, | "width":8, | ||||
"x":824, | "x":824, | ||||
"y":240 | "y":240 | ||||
}, | |||||
{ | |||||
"height":24, | |||||
"id":912, | |||||
"name":"shopCultLeader", | |||||
"rotation":0, | |||||
"type":"", | |||||
"visible":true, | |||||
"width":24, | |||||
"x":704, | |||||
"y":224 | |||||
}], | }], | ||||
"opacity":1, | "opacity":1, | ||||
"type":"objectgroup", | "type":"objectgroup", | ||||
@@ -2391,7 +2402,7 @@ | |||||
"x":0, | "x":0, | ||||
"y":0 | "y":0 | ||||
}], | }], | ||||
"nextobjectid":912, | |||||
"nextobjectid":913, | |||||
"orientation":"orthogonal", | "orientation":"orthogonal", | ||||
"properties": | "properties": | ||||
{ | { | ||||
@@ -80,7 +80,22 @@ module.exports = { | |||||
level: 3, | level: 3, | ||||
spells: [{ | spells: [{ | ||||
type: 'melee' | type: 'melee' | ||||
}] | |||||
}], | |||||
regular: { | |||||
drops: { | |||||
chance: 20, | |||||
rolls: 1, | |||||
noRandom: true, | |||||
alsoRandom: true, | |||||
blueprints: [{ | |||||
name: 'Digested Crystal', | |||||
quality: 0, | |||||
quest: true, | |||||
sprite: [1, 1] | |||||
}] | |||||
} | |||||
} | |||||
}, | }, | ||||
pockshell: { | pockshell: { | ||||
@@ -185,7 +200,30 @@ module.exports = { | |||||
}, | }, | ||||
'cult leader': { | 'cult leader': { | ||||
level: 15, | level: 15, | ||||
walkDistance: 0 | |||||
walkDistance: 0, | |||||
deathRep: -15, | |||||
rare: { | |||||
count: 0 | |||||
}, | |||||
properties: { | |||||
cpnTrade: { | |||||
items: { | |||||
min: 5, | |||||
max: 10, | |||||
extra: [] | |||||
}, | |||||
faction: { | |||||
id: 'akarei', | |||||
tier: 0 | |||||
}, | |||||
markup: { | |||||
buy: 0.25, | |||||
sell: 10 | |||||
} | |||||
} | |||||
} | |||||
} | } | ||||
}, | }, | ||||
objects: { | objects: { | ||||
@@ -516,6 +554,26 @@ module.exports = { | |||||
} | } | ||||
} | } | ||||
} | } | ||||
}, | |||||
shopcultleader: { | |||||
properties: { | |||||
cpnNotice: { | |||||
actions: { | |||||
enter: { | |||||
cpn: 'dialogue', | |||||
method: 'talk', | |||||
args: [{ | |||||
targetName: 'cult leader' | |||||
}] | |||||
}, | |||||
exit: { | |||||
cpn: 'dialogue', | |||||
method: 'stopTalk' | |||||
} | |||||
} | |||||
} | |||||
} | |||||
} | } | ||||
} | } | ||||
}; | }; |
@@ -28,8 +28,7 @@ define([ | |||||
}] | }] | ||||
}); | }); | ||||
//this.queueCallback(this.explode.bind(this, target), 1); | |||||
this.explode(target); | |||||
this.queueCallback(this.explode.bind(this, target), 1); | |||||
return true; | return true; | ||||
}, | }, | ||||
@@ -7,7 +7,5 @@ | |||||
* Two cultists dialogue | * Two cultists dialogue | ||||
* Boss cultist dialogue | * Boss cultist dialogue | ||||
* Cultists rep | * Cultists rep | ||||
* Cultists rep item: Shock on crit | |||||
* Portal teleport to entrance | * Portal teleport to entrance | ||||
* Boss snail death teleport to wall | |||||
* | |||||
* Boss snail death teleport to wall |