@@ -20,13 +20,9 @@ | |||
text-align: center; | |||
color: @white; | |||
font-size: 18px; | |||
background-color: fade(@blackD, 10%); | |||
background-color: fade(@blackD, 15%); | |||
padding: 8px; | |||
text-shadow: 2px 2px 0 @blackD, | |||
-2px -2px 0 @blackD, | |||
2px -2px 0 @blackD, | |||
-2px 2px 0 @blackD, | |||
2px 2px 0 @blackD; | |||
text-shadow: 2px 2px 0 @blackD, -2px -2px 0 @blackD, 2px -2px 0 @blackD, -2px 2px 0 @blackD, 2px 2px 0 @blackD; | |||
animation: 0.5s ease-in-out infinite bounce; | |||
&.success { | |||
@@ -36,12 +32,24 @@ | |||
&.failure { | |||
color: @red; | |||
} | |||
} | |||
} | |||
} | |||
@keyframes bounce { | |||
0% { top: 0px; } | |||
50% { top: 4px; } | |||
100% { top: 0px ;} | |||
} | |||
0% { | |||
top: 0px; | |||
} | |||
50% { | |||
top: 4px; | |||
} | |||
100% { | |||
top: 0px; | |||
} | |||
} |
@@ -1,11 +1,7 @@ | |||
const recipes = require('../config/recipes/recipes'); | |||
const generator = require('../items/generator'); | |||
const { applyItemStats } = require('./equipment/helpers'); | |||
const buildRecipe = require('./workbench/buildRecipe'); | |||
const buildMaterials = require('./workbench/buildMaterials'); | |||
const buildPickedItems = require('./workbench/buildPickedItems'); | |||
const craft = require('./workbench/craft'); | |||
module.exports = { | |||
type: 'workbench', | |||
@@ -115,87 +111,10 @@ module.exports = { | |||
}, | |||
craft: function (msg) { | |||
const { craftType, obj: { instance: { objects: { objects } } } } = this; | |||
const { name: recipeName, sourceId } = msg; | |||
const crafter = objects.find(o => o.serverId === sourceId); | |||
if (!crafter || !crafter.player) | |||
return; | |||
const recipe = recipes.getRecipe(craftType, recipeName); | |||
if (!recipe) | |||
return; | |||
const { needItems } = recipe; | |||
const { syncer, inventory, equipment, spellbook } = crafter; | |||
const materials = buildMaterials(crafter, recipe, msg); | |||
const pickedItems = buildPickedItems(crafter, recipe, msg); | |||
const canCraft = ( | |||
!materials.some(m => m.noHaveEnough) && | |||
pickedItems.length === needItems.length && | |||
!pickedItems.some(i => !i) | |||
); | |||
if (!canCraft) | |||
return; | |||
const result = craft(this, msg); | |||
materials.forEach(m => inventory.destroyItem(m.id, m.needQuantity)); | |||
let resultMsg = null; | |||
if (recipe.craftAction) { | |||
pickedItems.forEach(p => { | |||
if (p.eq) | |||
applyItemStats(crafter, p, false); | |||
}); | |||
const oldSlots = pickedItems.map(p => p.slot); | |||
resultMsg = recipe.craftAction(crafter, pickedItems); | |||
pickedItems.forEach((p, i) => { | |||
if (!p.eq) | |||
return; | |||
applyItemStats(crafter, p, true); | |||
if (p.slot !== oldSlots[i]) | |||
equipment.unequip(p.id); | |||
spellbook.calcDps(); | |||
pickedItems.forEach(item => syncer.setArray(true, 'inventory', 'getItems', inventory.simplifyItem(item))); | |||
}); | |||
equipment.unequipAttrRqrGear(); | |||
} | |||
if (recipe.item || recipe.items) { | |||
const outputItems = recipe.item ? [ recipe.item ] : recipe.items; | |||
outputItems.forEach(itemBpt => { | |||
let item = null; | |||
if (itemBpt.generate) | |||
item = generator.generate(itemBpt); | |||
else | |||
item = extend({}, itemBpt); | |||
if (item.description) | |||
item.description += `<br /><br />(Crafted by ${crafter.name})`; | |||
else | |||
item.description = `<br /><br />(Crafted by ${crafter.name})`; | |||
const quantity = item.quantity; | |||
if (quantity && quantity.push) | |||
item.quantity = quantity[0] + ~~(Math.random() * (quantity[1] - quantity[0])); | |||
crafter.inventory.getItem(item); | |||
}); | |||
} | |||
this.resolveCallback(msg, { | |||
resultMsg, | |||
recipe: buildRecipe(craftType, crafter, msg) | |||
}); | |||
if (result) | |||
this.resolveCallback(msg, result); | |||
}, | |||
resolveCallback: function (msg, result) { | |||
@@ -27,20 +27,12 @@ module.exports = (crafter, recipe, msg) => { | |||
i.name.includes(nameLike) | |||
)); | |||
const noHaveEnough = ( | |||
haveMaterial && | |||
( | |||
haveMaterial.quantity === 1 || | |||
haveMaterial.quantity < quantity | |||
) | |||
); | |||
const id = haveMaterial ? haveMaterial.id : null; | |||
const haveQuantity = haveMaterial ? (haveMaterial.quantity || 1) : 0; | |||
const needQuantity = quantity; | |||
const noHaveEnough = haveQuantity < needQuantity; | |||
const material = { | |||
id, | |||
name, | |||
@@ -0,0 +1,97 @@ | |||
const recipes = require('../../config/recipes/recipes'); | |||
const generator = require('../../items/generator'); | |||
const { applyItemStats } = require('../equipment/helpers'); | |||
const buildRecipe = require('../workbench/buildRecipe'); | |||
const buildMaterials = require('../workbench/buildMaterials'); | |||
const buildPickedItems = require('../workbench/buildPickedItems'); | |||
module.exports = (cpnWorkbench, msg) => { | |||
const { craftType, obj: { instance: { objects: { objects } } } } = cpnWorkbench; | |||
const { name: recipeName, sourceId } = msg; | |||
const crafter = objects.find(o => o.serverId === sourceId); | |||
if (!crafter || !crafter.player) | |||
return null; | |||
const recipe = recipes.getRecipe(craftType, recipeName); | |||
if (!recipe) | |||
return null; | |||
const { needItems = [] } = recipe; | |||
const { syncer, inventory, equipment, spellbook } = crafter; | |||
const materials = buildMaterials(crafter, recipe, msg); | |||
const pickedItems = buildPickedItems(crafter, recipe, msg); | |||
const canCraft = ( | |||
!materials.some(m => m.noHaveEnough) && | |||
pickedItems.length === needItems.length && | |||
!pickedItems.some(i => !i) | |||
); | |||
if (!canCraft) | |||
return null; | |||
materials.forEach(m => inventory.destroyItem(m.id, m.needQuantity)); | |||
let resultMsg = null; | |||
if (recipe.craftAction) { | |||
pickedItems.forEach(p => { | |||
if (p.eq) | |||
applyItemStats(crafter, p, false); | |||
}); | |||
const oldSlots = pickedItems.map(p => p.slot); | |||
resultMsg = recipe.craftAction(crafter, pickedItems); | |||
pickedItems.forEach((p, i) => { | |||
if (!p.eq) { | |||
pickedItems.forEach(item => syncer.setArray(true, 'inventory', 'getItems', inventory.simplifyItem(item))); | |||
return; | |||
} | |||
applyItemStats(crafter, p, true); | |||
if (p.slot !== oldSlots[i]) | |||
equipment.unequip(p.id); | |||
spellbook.calcDps(); | |||
pickedItems.forEach(item => syncer.setArray(true, 'inventory', 'getItems', inventory.simplifyItem(item))); | |||
}); | |||
equipment.unequipAttrRqrGear(); | |||
} | |||
if (recipe.item || recipe.items) { | |||
const outputItems = recipe.item ? [ recipe.item ] : recipe.items; | |||
outputItems.forEach(itemBpt => { | |||
let item = null; | |||
if (itemBpt.generate) | |||
item = generator.generate(itemBpt); | |||
else | |||
item = extend({}, itemBpt); | |||
if (item.description) | |||
item.description += `<br /><br />(Crafted by ${crafter.name})`; | |||
else | |||
item.description = `<br /><br />(Crafted by ${crafter.name})`; | |||
const quantity = item.quantity; | |||
if (quantity && quantity.push) | |||
item.quantity = quantity[0] + ~~(Math.random() * (quantity[1] - quantity[0])); | |||
crafter.inventory.getItem(item); | |||
}); | |||
} | |||
const result = { | |||
resultMsg, | |||
recipe: buildRecipe(craftType, crafter, msg) | |||
}; | |||
return result; | |||
}; |
@@ -17,9 +17,7 @@ module.exports = [{ | |||
withProps: ['slot'], | |||
withoutProps: ['noAugment'], | |||
checks: [ | |||
item => { | |||
return !item.power || item.power < 3; | |||
} | |||
item => !item.power || item.power < 3 | |||
] | |||
}] | |||
}, { | |||
@@ -43,9 +41,12 @@ module.exports = [{ | |||
quantity: 1 | |||
}], | |||
needItems: [{ | |||
info: 'Pick an item to reroll', | |||
info: 'Pick the item you wish to ascend', | |||
withProps: ['slot'], | |||
withoutProps: ['noAugment'] | |||
withoutProps: ['noAugment'], | |||
checks: [ | |||
item => item.level && item.level < consts.maxLevel | |||
] | |||
}], | |||
craftAction: relevel | |||
}, { | |||
@@ -56,7 +57,7 @@ module.exports = [{ | |||
quantity: 1 | |||
}], | |||
needItems: [{ | |||
info: 'Pick an item to reroll', | |||
info: 'Pick an item to reslot', | |||
withProps: ['slot'], | |||
withoutProps: ['noAugment', 'effects'] | |||
}], | |||
@@ -69,22 +70,25 @@ module.exports = [{ | |||
quantity: 1 | |||
}], | |||
needItems: [{ | |||
info: 'Pick an item to reroll', | |||
info: 'Pick an item to reforge', | |||
withProps: ['slot', 'spell'], | |||
withoutProps: ['noAugment'] | |||
}], | |||
craftAction: reforge | |||
}, { | |||
name: 'Scour', | |||
description: 'Rerolls a weapon\'s damage range.', | |||
description: 'Wipe all augments from an item.', | |||
materials: [{ | |||
name: 'Bone Idol', | |||
name: 'Smoldering Idol', | |||
quantity: 1 | |||
}], | |||
needItems: [{ | |||
info: 'Pick an item to reroll', | |||
info: 'Pick an item to scour', | |||
withProps: ['slot', 'power'], | |||
withoutProps: ['noAugment'] | |||
}], | |||
craftAction: scour | |||
craftAction: scour, | |||
checks: [ | |||
item => item.power && item.power >= 1 | |||
] | |||
}]; |
@@ -13,5 +13,8 @@ module.exports = (obj, [item]) => { | |||
}); | |||
item.spell = extend(oldSpell, item.spell); | |||
return { msg: 'Reforge successful' }; | |||
const damage = item.spell.values.damage; | |||
const msg = `Reforged weapon to damage: ${damage}`; | |||
return { msg }; | |||
}; |
@@ -14,5 +14,7 @@ module.exports = (obj, [item]) => { | |||
item.level = Math.min(maxLevel, item.level + offset); | |||
} | |||
return { msg: 'Relevel successful' }; | |||
const msg = `Relevelled item to level ${item.level}`; | |||
return { msg }; | |||
}; |
@@ -30,5 +30,7 @@ module.exports = (obj, [item]) => { | |||
extend(item, newItem); | |||
return { msg: 'Reslot successful' }; | |||
const msg = `Reslotted item to slot: ${item.slot}`; | |||
return { msg }; | |||
}; |