@@ -312,7 +312,9 @@ define([ | |||||
config.push(menuItems.learn); | config.push(menuItems.learn); | ||||
else if (item.type === 'mtx') | else if (item.type === 'mtx') | ||||
config.push(menuItems.activate); | config.push(menuItems.activate); | ||||
else if (item.type === 'toy' || item.type === 'consumable') { | |||||
else if (item.type === 'toy' || item.type === 'consumable' || item.useText) { | |||||
if (item.useText) | |||||
menuItems.use.text = item.useText; | |||||
config.push(menuItems.use); | config.push(menuItems.use); | ||||
if (!item.has('quickSlot')) | if (!item.has('quickSlot')) | ||||
config.push(menuItems.quickSlot); | config.push(menuItems.quickSlot); | ||||
@@ -285,7 +285,7 @@ define([ | |||||
this.tooltip.find('.worth').html(item.worthText ? ('<br />value: ' + item.worthText) : ''); | this.tooltip.find('.worth').html(item.worthText ? ('<br />value: ' + item.worthText) : ''); | ||||
if ((item.effects) && (item.type !== 'mtx')) { | |||||
if (item.effects && item.effects[0].text && item.type !== 'mtx') { | |||||
let htmlEffects = ''; | let htmlEffects = ''; | ||||
item.effects.forEach(function (e, i) { | item.effects.forEach(function (e, i) { | ||||
@@ -38,7 +38,7 @@ module.exports = { | |||||
let e = { | let e = { | ||||
type: 'effects', | type: 'effects', | ||||
effects: this.effects | effects: this.effects | ||||
.map(f => f.save()) | |||||
.map(f => f.save ? f.save() : f) | |||||
.filter(f => !!f) | .filter(f => !!f) | ||||
}; | }; | ||||
@@ -222,6 +222,10 @@ module.exports = { | |||||
effect.destroy(); | effect.destroy(); | ||||
this.syncRemove(effect.id, effect.type, noMsg || effect.noMsg); | this.syncRemove(effect.id, effect.type, noMsg || effect.noMsg); | ||||
effects.splice(i, 1); | effects.splice(i, 1); | ||||
if (effect.destroy) | |||||
effect.destroy(); | |||||
return; | return; | ||||
} | } | ||||
} | } | ||||
@@ -234,7 +238,11 @@ module.exports = { | |||||
if (effect.type === effectName) { | if (effect.type === effectName) { | ||||
this.syncRemove(effect.id, effect.type, noMsg || effects.noMsg); | this.syncRemove(effect.id, effect.type, noMsg || effects.noMsg); | ||||
effects.splice(i, 1); | effects.splice(i, 1); | ||||
return; | |||||
if (effect.destroy) | |||||
effect.destroy(); | |||||
return effect; | |||||
} | } | ||||
} | } | ||||
}, | }, | ||||
@@ -252,7 +260,7 @@ module.exports = { | |||||
continue; | continue; | ||||
} | } | ||||
if (e.ttl <= 0) | |||||
if (e.ttl === 0) | |||||
continue; | continue; | ||||
let events = e.events; | let events = e.events; | ||||
if (!events) | if (!events) | ||||
@@ -307,6 +307,8 @@ module.exports = { | |||||
let eLen = effects.length; | let eLen = effects.length; | ||||
for (let j = 0; j < eLen; j++) { | for (let j = 0; j < eLen; j++) { | ||||
let effect = effects[j]; | let effect = effects[j]; | ||||
if (!effect.events) | |||||
continue; | |||||
let effectEvent = effect.events.onConsumeItem; | let effectEvent = effect.events.onConsumeItem; | ||||
if (!effectEvent) | if (!effectEvent) | ||||
@@ -536,9 +538,10 @@ module.exports = { | |||||
statGenerator.generate(item); | statGenerator.generate(item); | ||||
} else { | } else { | ||||
let effectUrl = itemEffects.get(e.type); | let effectUrl = itemEffects.get(e.type); | ||||
let effectModule = require('../' + effectUrl); | |||||
e.events = effectModule.events; | |||||
try { | |||||
let effectModule = require('../' + effectUrl); | |||||
e.events = effectModule.events; | |||||
} catch (error) {} | |||||
} | } | ||||
}); | }); | ||||
} | } | ||||
@@ -812,11 +815,11 @@ module.exports = { | |||||
e.events = mtxModule.events; | e.events = mtxModule.events; | ||||
} else if (e.type) { | } else if (e.type) { | ||||
let effectUrl = itemEffects.get(e.type); | let effectUrl = itemEffects.get(e.type); | ||||
let effectModule = require('../' + effectUrl); | |||||
e.text = effectModule.events.onGetText(item, e); | |||||
e.events = effectModule.events; | |||||
try { | |||||
let effectModule = require('../' + effectUrl); | |||||
e.text = effectModule.events.onGetText(item, e); | |||||
e.events = effectModule.events; | |||||
} catch (error) {} | |||||
} | } | ||||
}); | }); | ||||
} | } | ||||
@@ -12,8 +12,8 @@ module.exports = { | |||||
values[p] = value; | values[p] = value; | ||||
} | } | ||||
if (!this.expire) | |||||
this.expire = (+new Date()) + (this.ttl * 350); | |||||
if (!values.expire) | |||||
values.expire = (+new Date()) + (this.ttl * 350); | |||||
return values; | return values; | ||||
}, | }, | ||||
@@ -0,0 +1,44 @@ | |||||
module.exports = { | |||||
type: 'mounted', | |||||
oldCell: null, | |||||
oldSheetName: null, | |||||
init: function () { | |||||
let obj = this.obj; | |||||
this.oldCell = obj.cell; | |||||
this.oldSheetName = obj.sheetName; | |||||
obj.cell = 35; | |||||
obj.sheetName = 'mobs'; | |||||
let syncer = obj.syncer; | |||||
syncer.set(false, null, 'cell', obj.cell); | |||||
syncer.set(false, null, 'sheetName', obj.sheetName); | |||||
}, | |||||
simplify: function () { | |||||
return { | |||||
type: 'mounted', | |||||
ttl: this.ttl | |||||
}; | |||||
}, | |||||
destroy: function () { | |||||
let obj = this.obj; | |||||
obj.cell = this.oldCell; | |||||
obj.sheetName = this.oldSheetName; | |||||
let syncer = obj.syncer; | |||||
syncer.set(false, null, 'cell', obj.cell); | |||||
syncer.set(false, null, 'sheetName', obj.sheetName); | |||||
}, | |||||
events: { | |||||
onBeforeTryMove: function (moveEvent) { | |||||
moveEvent.sprintChance = 200; | |||||
} | |||||
} | |||||
}; |
@@ -0,0 +1,66 @@ | |||||
/* | |||||
Example of a mount: | |||||
{ | |||||
name: 'Brown Horse\'s Reins', | |||||
type: 'mount', | |||||
quality: 2, | |||||
noDrop: true, | |||||
noDestroy: true, | |||||
noSalvage: true, | |||||
cdMax: 10, | |||||
sprite: [0, 9], | |||||
spritesheet: 'images/questItems.png', | |||||
useText: 'mount', | |||||
description: 'Stout, dependable and at least faster than you', | |||||
effects: [{ | |||||
type: 'mount', | |||||
rolls: { | |||||
speed: 150, | |||||
cell: 5, | |||||
sheetName: 'mobs' | |||||
} | |||||
}] | |||||
} | |||||
*/ | |||||
module.exports = { | |||||
name: 'Feature: Mounts', | |||||
init: function () { | |||||
this.events.on('onBeforeUseItem', this.onBeforeUseItem.bind(this)); | |||||
this.events.on('onBeforeGetEffect', this.onBeforeGetEffect.bind(this)); | |||||
}, | |||||
onBeforeUseItem: function (obj, item, result) { | |||||
if (item.type !== 'mount') | |||||
return; | |||||
let syncer = obj.syncer; | |||||
let currentEffect = obj.effects.removeEffectByName('mounted', true); | |||||
if (currentEffect) { | |||||
let currentItem = currentEffect.source; | |||||
currentItem.useText = 'mount'; | |||||
currentItem.cdMax = 0; | |||||
syncer.setArray(true, 'inventory', 'getItems', currentItem); | |||||
if (currentItem === item) | |||||
return; | |||||
} | |||||
let builtEffect = obj.effects.addEffect({ | |||||
type: 'mounted', | |||||
ttl: -1 | |||||
}); | |||||
builtEffect.source = item; | |||||
item.useText = 'unmount'; | |||||
syncer.setArray(true, 'inventory', 'getItems', item); | |||||
}, | |||||
onBeforeGetEffect: function (result) { | |||||
if (result.type.toLowerCase() === 'mounted') | |||||
result.url = `${this.relativeFolderName}/effects/effectMounted.js`; | |||||
} | |||||
}; |
@@ -219,14 +219,24 @@ module.exports = { | |||||
return; | return; | ||||
if (q.action === 'move') { | if (q.action === 'move') { | ||||
let maxDistance = 1; | |||||
if ((this.actionQueue[0]) && (this.actionQueue[0].action === 'move')) { | if ((this.actionQueue[0]) && (this.actionQueue[0].action === 'move')) { | ||||
let sprintChance = this.stats.values.sprintChance || 0; | |||||
let moveEvent = { | |||||
sprintChance: this.stats.values.sprintChance || 0 | |||||
}; | |||||
this.fireEvent('onBeforeTryMove', moveEvent); | |||||
let physics = this.instance.physics; | let physics = this.instance.physics; | ||||
if ((~~(Math.random() * 100) < sprintChance) && (!physics.isTileBlocking(q.data.x, q.data.y))) { | |||||
q = this.dequeue(); | |||||
q.isDouble = true; | |||||
} | |||||
let sprintChance = moveEvent.sprintChance; | |||||
do { | |||||
if ((~~(Math.random() * 100) < sprintChance) && (!physics.isTileBlocking(q.data.x, q.data.y))) { | |||||
q = this.dequeue(); | |||||
maxDistance++; | |||||
} | |||||
sprintChance -= 100; | |||||
} while (sprintChance > 0 && this.actionQueue.length > 0); | |||||
} | } | ||||
q.maxDistance = maxDistance; | |||||
let success = this.performMove(q); | let success = this.performMove(q); | ||||
if (!success) | if (!success) | ||||
this.clearQueue(); | this.clearQueue(); | ||||
@@ -255,7 +265,7 @@ module.exports = { | |||||
return true; | return true; | ||||
} | } | ||||
let maxDistance = action.isDouble ? 2 : 1; | |||||
let maxDistance = action.maxDistance || 1; | |||||
let deltaX = Math.abs(this.x - data.x); | let deltaX = Math.abs(this.x - data.x); | ||||
let deltaY = Math.abs(this.y - data.y); | let deltaY = Math.abs(this.y - data.y); | ||||
@@ -1,24 +1 @@ | |||||
* Client side debuff icons aren't being removed | * Client side debuff icons aren't being removed | ||||
Old | |||||
* The `Pumpkin Sailor` and his ship spawn south of the `Crab Ruins` | |||||
* New gather nodes: `Tiny Pumpkin`, `Pumpkin` and `Giant Pumpkin` that drop `Candy Corn` | |||||
* Pumpkins have a chance to spawn `Soul Nibblers` that drop extra `Candy Corn` | |||||
* `Soul Nibblers` also have a small chance to drop the `Summon Pumpkin Skeleton` | |||||
* Killing `Soul Nibblers` grants reputation with the `Pumpkin Sailor` | |||||
* Every few hours, `Lord Squash` spawns | |||||
* `Lord Squash` has a few lines he'll speak globally | |||||
* Killing `Lord Squash` grants a lot of reputation with the `Pumpkin Sailor` | |||||
* `Lord Squash` drops a lot of `Candy Corn` and has a small chance to drop `Haunted Ice Spear` | |||||
* `Lord Squash` has two abilities: `Scatter Pumpkin Pieces` and a 'target-all' `Projectile` | |||||
* The `Pumpkin Sailor` has dialogue options that explain his backstory a bit | |||||
* The `Pumpkin Sailor` has four rings for sale for different spirits. They each cost 400 `Candy Corn` and require you to be Friendly with his faction | |||||
* The `Pumpkin Sailor` has the `Pumpkin-Head Necromancer` skin for sale which costs 1200 `Candy Corn` and requires you to be Honored with his faction | |||||
New | |||||
* Purchasable `Some Non Combat Pet` for x `Candy Corn` at y reputation from the `Pumpkin Sailor` | |||||
* Purchasable `100% Sprint Chance Mount` for x `Candy Corn` at y reputation from the `Pumpkin Sailor` | |||||
* `Lord Squash` has a small chance to drop a `Some Slot Item` that causes `Some Aura` to not reserve mana | |||||
* The `Hermit's House` and houses in `Fjolgard` should be decorated festively | |||||
* It should be possible to rarely fish up `Ghoslty Carp` that can be combined with `Emberleaf` to create a `Ghostly Elixir` which grants the player a ghostly aura | |||||
* A rare version of `Some Mob` should spawn in the `The Estuary` which has a chance to drop `Some Belt` |