diff --git a/src/server/config/maps/cave/zone.js b/src/server/config/maps/cave/zone.js index 1502cbb3..f7feef52 100644 --- a/src/server/config/maps/cave/zone.js +++ b/src/server/config/maps/cave/zone.js @@ -1,8 +1,6 @@ module.exports = { name: 'The Crystal Caves', level: [14, 16], - addLevel: 0, - resources: {}, mobs: { default: { spells: [{ diff --git a/src/server/config/maps/estuary/zone.js b/src/server/config/maps/estuary/zone.js index 40f52eb3..273a049b 100644 --- a/src/server/config/maps/estuary/zone.js +++ b/src/server/config/maps/estuary/zone.js @@ -1,8 +1,6 @@ module.exports = { name: 'The Estuary', level: [15, 18], - addLevel: 0, - resources: {}, mobs: { default: { faction: 'hostile', diff --git a/src/server/config/maps/fjolarok/events/fishingTournament.js b/src/server/config/maps/fjolarok/events/fishingTournament.js deleted file mode 100644 index c9fa862c..00000000 --- a/src/server/config/maps/fjolarok/events/fishingTournament.js +++ /dev/null @@ -1,429 +0,0 @@ -module.exports = { - name: 'Fishing Tournament', - description: 'Catch the heaviest Ancient Carp for a chance to win Angler\'s Marks. Speak with Angler Nayla for more info.', - distance: -1, - cron: '0 7,19 * * *', - - notifications: [{ - mark: 0, - msg: 'Angler Nayla: The Fishing Tournament begins in 10 minutes.', - desc: 'Begins in 10 minutes.' - }, { - mark: 857, - msg: 'Angler Nayla: The Fishing Tournament begins in 5 minutes.', - desc: 'Begins in 5 minutes.' - }, { - mark: 1543, - msg: 'Angler Nayla: The Fishing Tournament begins in 1 minute.', - desc: 'Begins in 1 minute.' - }, { - mark: 1714, - msg: 'Angler Nayla: The Fishing Tournament has begun!', - desc: '' - }, { - mark: 2571, - msg: 'Angler Nayla: The Fishing Tournament ends in 5 minutes.', - desc: 'Ends in 5 minutes.' - }, { - mark: 3256, - msg: 'Angler Nayla: The Fishing Tournament ends in 1 minute.', - desc: 'Ends in 1 minute.' - }, { - mark: 3428, - msg: 'Angler Nayla: The Fishing Tournament is over.' - }], - - duration: 4285, - prizeTime: 3428, - - descBase: 'Catch the heaviest Ancient Carp for a chance to win Angler\'s Marks. Speak with Angler Nayla for more info.', - descLeaderboard: null, - descTimer: null, - - events: { - afterGiveRewards: function (events) { - let event = events.getEvent('Fishing Tournament'); - event.descBase = 'The tournament has ended.'; - event.descLeaderboard = null; - event.descTimer = null; - - events.setEventDescription('Fishing Tournament', this.description); - }, - - beforeSetDescription: function (events) { - let event = events.getEvent('Fishing Tournament'); - - event.description = event.descBase; - if (event.descLeaderboard) - event.description += '

' + event.descLeaderboard; - if (event.descTimer) - event.description += '

' + event.descTimer; - } - }, - - helpers: { - updateRewards: function (event, anglerNayla) { - event.ranks = {}; - event.rewards = {}; - event.weights = {}; - - let tempFish = anglerNayla.inventory.items - .filter(i => (i.name.indexOf('Ancient Carp') > -1)) - .sort((a, b) => (b.stats.weight - a.stats.weight)); - - let fish = []; - tempFish.forEach(function (t) { - if (!fish.some(f => (f.owner === t.owner))) - fish.push(t); - }); - - let rewardCounts = [25, 15, 7]; - let tpl = { - name: 'Angler\'s Mark', - sprite: [12, 9], - noDrop: true, - noDestroy: true, - noSalvage: true - }; - let consolationQty = 2; - - let rank = 0; - let lastWeight = fish[0].stats.weight; - for (let i = 0; i < fish.length; i++) { - let f = fish[i]; - if (event.rewards[f.owner]) - continue; - - if (f.stats.weight < lastWeight) { - lastWeight = f.stats.weight; - rank++; - } - - event.ranks[f.owner] = rank + 1; - event.weights[f.owner] = f.stats.weight; - - let rewardQty = rewardCounts[rank] || consolationQty; - - event.rewards[f.owner] = [extend({ - quantity: rewardQty - }, tpl)]; - } - }, - - updateDescription: function (event, events) { - let ranks = event.ranks; - let weights = event.weights; - - let desc = 'Leaderboard:
'; - for (let playerName in ranks) - desc += `${ranks[playerName]}: ${playerName} (${weights[playerName]})
`; - - desc = desc.substr(0, desc.length - 6); - - event.config.descLeaderboard = desc; - events.setEventDescription('Fishing Tournament'); - }, - - updateWinText: function (event, events) { - let ranks = event.ranks; - - let winText = 'Angler Nayla: '; - let winners = Object.keys(ranks).filter(r => (ranks[r] === 1)); - let wLen = winners.length; - winners.forEach(function (w, i) { - winText += ((wLen > 1) && (i === wLen - 1)) ? `and ${w} ` : `${w} `; - }); - - winText += 'won!'; - - events.setWinText('Fishing Tournament', winText); - }, - - giveFish: function (source, target) { - let srcInventory = source.inventory; - let tgtInventory = target.inventory; - - srcInventory.items - .filter(i => (i.name.indexOf('Ancient Carp') > -1)) - .sort((a, b) => (b.stats.weight - a.stats.weight)) - .forEach(function (f, i) { - if (i === 0) { - f.owner = source.name; - tgtInventory.getItem(extend({}, f)); - } - - srcInventory.destroyItem(f.id); - }); - }, - - getRank: function (event, playerName) { - let ranks = event.ranks; - if (!ranks) - return -1; - - return (ranks[playerName] || -1); - } - }, - - phases: [{ - type: 'spawnMob', - endMark: 1714, - mobs: { - name: 'Angler Nayla', - attackable: false, - level: 20, - cell: 69, - id: 'anglerNayla', - hpMult: 1, - pos: { - x: 140, - y: 46 - }, - dialogue: { - auto: true, - config: { - 1: { - msg: [{ - msg: 'Hi there, are you here to compete?', - options: [1.1, 1.2, 1.3] - }], - options: { - 1.1: { - msg: 'What\'s happening here?', - goto: 2 - }, - 1.2: { - msg: 'Could I please have a Competition Rod?', - goto: 5 - }, - 1.3: { - msg: 'I would like to trade some Angler\'s Marks.', - goto: 'tradeBuy' - } - } - }, - 2: { - msg: 'Why, the Grand Fishing Tournament, of course! Anglers come from all over to compete in this esteemed event.', - options: { - 2.1: { - msg: 'How does it work?', - goto: 3 - } - } - }, - 3: { - msg: 'Simply catch fish during the tournament. If you\'re lucky, you\'ll catch an Ancient Carp. Bring them to me and if you catch the heaviest one, you win!', - options: { - 3.1: { - msg: 'What are the prizes?', - goto: 4 - } - } - }, - 4: { - msg: 'The top three participants will win Angler\'s Marks that can be exchanged for Fishing Rods and Cerulean Pearls.', - options: { - 4.1: { - msg: 'I would like to ask something else.', - goto: 1 - } - } - }, - 5: { - msg: [{ - msg: '', - options: [1.1, 1.2, 1.3, 1.4] - }], - cpn: 'dialogue', - method: 'getItem', - args: [{ - item: { - name: 'Competition Rod', - slot: 'tool', - sprite: [11, 1], - type: 'Fishing Rod', - worth: 0, - noSalvage: true, - noAugment: true, - stats: { - catchSpeed: 50, - catchChance: 25 - } - }, - successMsg: 'May it cast true.', - existsMsg: 'Oh, it seems that you already have one.' - }] - }, - tradeBuy: { - cpn: 'trade', - method: 'startBuy', - args: [{ - targetName: 'angler nayla' - }] - } - } - }, - trade: { - items: { - min: 0, - max: 0 - }, - forceItems: [{ - name: 'Cerulean Pearl', - material: true, - sprite: [11, 9], - infinite: true, - quality: 3, - worth: { - currency: 'Angler\'s Mark', - amount: 4 - } - }, { - name: 'Common Fishing Rod', - type: 'Fishing Rod', - slot: 'tool', - quality: 0, - worth: { - currency: 'Angler\'s Mark', - amount: 5 - }, - sprite: [11, 0], - infinite: true, - stats: { - stats: '???' - } - }, { - name: 'Magic Fishing Rod', - type: 'Fishing Rod', - slot: 'tool', - quality: 1, - worth: { - currency: 'Angler\'s Mark', - amount: 15 - }, - sprite: [11, 0], - infinite: true, - stats: { - stats: '???' - } - }, { - name: 'Rare Fishing Rod', - type: 'Fishing Rod', - slot: 'tool', - quality: 2, - worth: { - currency: 'Angler\'s Mark', - amount: 45 - }, - sprite: [11, 0], - infinite: true, - stats: { - stats: '???' - } - }], - faction: { - id: 'anglers' - }, - level: { - min: 1, - max: 5 - }, - markup: { - buy: 0.25, - sell: 2.5 - } - } - } - }, { - type: 'hookEvents', - endMark: 3428, - auto: true, - events: { - beforeGatherResource: function (gatherResult, gatherer) { - if (gatherResult.nodeType !== 'fish') - return; - - let hasCompRod = gatherer.inventory.items.some(i => ((i.name === 'Competition Rod') && (i.eq))); - if (!hasCompRod) - return; - - gatherResult.items.forEach(function (g) { - extend(g, { - name: 'Ancient Carp', - sprite: [11, 4], - noDrop: true, - worth: 0 - }); - }); - }, - - beforeEnterPool: function (gatherResult, gatherer) { - if (gatherResult.nodeName === 'Sun Carp') - gatherResult.nodeName = 'Ancient Carp'; - } - } - }, { - type: 'modifyDialogue', - endMark: 3428, - mobId: 'anglerNayla', - dialogue: { - add: { - 1: { - 1.4: { - msg: 'I\'d like to hand in some fish.', - prereq: function (obj) { - let fishies = obj.inventory.items.find(i => (i.name.indexOf('Ancient Carp') > -1)); - return !!fishies; - }, - goto: 'giveFish' - } - }, - giveFish: { - msg: [{ - msg: '', - options: [1.1, 1.2, 1.3, 1.4] - }], - method: function (obj) { - let eventConfig = this.instance.events.getEvent('Fishing Tournament'); - if (!eventConfig) - return; - - let helpers = eventConfig.helpers; - let event = eventConfig.event; - - let oldRank = helpers.getRank(event, obj.name); - - helpers.giveFish(obj, this); - helpers.updateRewards(event, this); - - let newRank = helpers.getRank(event, obj.name); - helpers.updateDescription(event, this.instance.events); - - if (oldRank !== newRank) { - helpers.updateWinText(event, this.instance.events); - - return { - 1: 'Wow, that one\'s huge. You took first place!', - 2: 'Nice catch. You took second place!', - 3: 'Not bad at all. You took third place!' - }[newRank]; - } else if (newRank === 1) - return 'Great, you\'re still in first place!'; - return 'Not quite heavy enough, keep trying!'; - } - } - } - } - }, { - type: 'modifyDialogue', - mobId: 'anglerNayla', - dialogue: { - remove: { - 1: { - 1.4: null - }, - giveFish: null - } - } - }] -}; diff --git a/src/server/config/maps/fjolarok/zone.js b/src/server/config/maps/fjolarok/zone.js index d2ab7577..522b5245 100644 --- a/src/server/config/maps/fjolarok/zone.js +++ b/src/server/config/maps/fjolarok/zone.js @@ -1,22 +1,6 @@ module.exports = { name: 'Fjolarok', level: [1, 10], - resources: { - Skyblossom: { - type: 'herb', - max: 4 - }, - Emberleaf: { - type: 'herb', - max: 1, - cdMax: 1710 - }, - 'Sun Carp School': { - max: 900, - type: 'fish', - quantity: [6, 12] - } - }, objects: { shopestrid: { properties: { diff --git a/src/server/config/resourceNodes.js b/src/server/config/resourceNodes.js deleted file mode 100644 index ddffa61a..00000000 --- a/src/server/config/resourceNodes.js +++ /dev/null @@ -1,40 +0,0 @@ -let events = require('../misc/events'); - -module.exports = { - init: function () { - events.emit('onBeforeGetResourceNodeConfig', this); - }, - - Moonbell: { - sheetName: 'tiles', - cell: 50, - itemSprite: [1, 1] - }, - Skyblossom: { - sheetName: 'tiles', - cell: 52, - itemSprite: [1, 2] - }, - Emberleaf: { - sheetName: 'tiles', - cell: 51, - itemSprite: [1, 0] - }, - 'Sun Carp School': { - sheetName: 'objects', - itemSprite: [11, 2], - baseWeight: 3, - ttl: 30 - }, - Stinkcap: { - sheetName: 'tiles', - cell: 57, - itemSprite: [2, 0] - }, - Mudfish: { - sheetName: 'objects', - itemSprite: [11, 3], - baseWeight: 5, - ttl: 30 - } -}; diff --git a/src/server/events/events.js b/src/server/events/events.js index 93b59d48..1b55254c 100644 --- a/src/server/events/events.js +++ b/src/server/events/events.js @@ -220,26 +220,21 @@ module.exports = { }, giveRewards: function (config) { - let event = config.event; + const { event: { rewards = {} } } = config; - config.event.participators.forEach(function (p) { - let rList = [{ - nameLike: 'Ancient Carp', - removeAll: true - }]; - - let rewards = event.rewards; - if ((rewards) && (rewards[p.name])) { - rewards[p.name].forEach(r => rList.push(r)); - if (rList.length > 1) - rList[1].msg = `${event.config.name} reward:`; - } + Object.entries(rewards).forEach(e => { + const { name, rList } = e; - this.instance.mail.sendMail(p.name, rList); - }, this); + if (!rList.length) + return; + + rList[0].msg = `${config.name} reward:`; + + this.instance.mail.sendMail(name, rList); + }); if ((config.events) && (config.events.afterGiveRewards)) - config.events.afterGiveRewards(this); + config.events.afterGiveRewards(this, config); }, stopEvent: function (config) { @@ -452,12 +447,8 @@ module.exports = { event.participators.push(obj); result.push(event); - let rList = [{ - nameLike: 'Ancient Carp', - removeAll: true - }]; - - this.instance.mail.sendMail(obj.name, rList); + if (event.config.events && event.config.events.onParticipantJoin) + event.config.events.onParticipantJoin(this, obj); continue; } @@ -478,12 +469,8 @@ module.exports = { event.participators.push(obj); result.push(event); - let rList = [{ - nameLike: 'Ancient Carp', - removeAll: true - }]; - - this.instance.mail.sendMail(obj.name, rList); + if (event.config.events && event.config.events.onParticipantJoin) + event.config.events.onParticipantJoin(this, obj); break; } diff --git a/src/server/index.js b/src/server/index.js index c4776e0b..e19e3a8e 100644 --- a/src/server/index.js +++ b/src/server/index.js @@ -9,11 +9,15 @@ let factions = require('./config/factions'); let classes = require('./config/spirits'); let spellsConfig = require('./config/spellsConfig'); let spells = require('./config/spells'); -let itemTypes = require('./items/config/types'); let mapList = require('./config/maps/mapList'); let sheets = require('./security/sheets'); let fixes = require('./fixes/fixes'); let profanities = require('./misc/profanities'); + +const itemTypes = require('./items/config/types'); +const itemPrefixes = require('./items/config/prefixes'); +const itemSuffixes = require('./items/config/suffixes'); + const routerConfig = require('./security/routerConfig'); let startup = { @@ -36,7 +40,11 @@ let startup = { classes.init(); spellsConfig.init(); spells.init(); + itemTypes.init(); + itemPrefixes.init(); + itemSuffixes.init(); + profanities.init(); mapList.init(); components.init(this.onComponentsReady.bind(this)); diff --git a/src/server/items/config/prefixes.js b/src/server/items/config/prefixes.js index 06dad53b..f0c68f3a 100644 --- a/src/server/items/config/prefixes.js +++ b/src/server/items/config/prefixes.js @@ -1,4 +1,6 @@ -module.exports = { +const events = require('../../misc/events'); + +const prefixes = { generic: [ 'aether', 'abyssal', @@ -202,11 +204,14 @@ module.exports = { head: [ 'masked' ], - tool: [ - 'angler%', - 'fisherman%', - 'linesman%', - 'trawler%' - ] + tool: [] + } +}; + +module.exports = { + prefixes, + + init: function () { + events.emit('onBeforeGetItemNamePrefixes', prefixes); } }; diff --git a/src/server/items/config/suffixes.js b/src/server/items/config/suffixes.js index 62570ba6..1784e04d 100644 --- a/src/server/items/config/suffixes.js +++ b/src/server/items/config/suffixes.js @@ -1,4 +1,6 @@ -module.exports = { +const events = require('../../misc/events'); + +const suffixes = { generic: [ 'absence', 'abomination', @@ -187,23 +189,14 @@ module.exports = { 'chain', 'noose' ], - tool: [ - 'angler', - 'bait-caster', - 'baiter', - 'branch', - 'fish-catcher', - 'fish-stick', - 'fisher', - 'hook', - 'line', - 'lure', - 'pole', - 'reel', - 'rod', - 'stick', - 'tackle', - 'twig' - ] + tool: [] + } +}; + +module.exports = { + suffixes, + + init: function () { + events.emit('onBeforeGetItemNameSuffixes', suffixes); } }; diff --git a/src/server/items/config/types.js b/src/server/items/config/types.js index 05f0ac55..284d7902 100644 --- a/src/server/items/config/types.js +++ b/src/server/items/config/types.js @@ -476,15 +476,11 @@ let types = { } } }, - tool: { - 'Fishing Rod': { - sprite: [11, 0] - } - } + tool: {} }; module.exports = { - types: types, + types, init: function () { events.emit('onBeforeGetItemTypes', types); } diff --git a/src/server/items/generator.js b/src/server/items/generator.js index 8822efd4..d767b809 100644 --- a/src/server/items/generator.js +++ b/src/server/items/generator.js @@ -1,3 +1,5 @@ +const events = require('../misc/events'); + let g1 = require('./generators/level'); let g2 = require('./generators/quality'); let g3 = require('./generators/slots'); @@ -31,6 +33,16 @@ module.exports = { let item = {}; + const generateEvent = { + blueprint, + item, + ignore: false + }; + + events.emit('onBeforeGenerateItem', generateEvent); + if (generateEvent.ignore) + return item; + const dropChancesEvent = { blueprint, spellChance: this.spellChance, @@ -98,6 +110,8 @@ module.exports = { if (blueprint.uses) item.uses = blueprint.uses; + events.emit('onAfterGenerateItem', generateEvent); + return item; }, diff --git a/src/server/items/generators/names.js b/src/server/items/generators/names.js index 3656a2f8..971b9f71 100644 --- a/src/server/items/generators/names.js +++ b/src/server/items/generators/names.js @@ -1,5 +1,5 @@ -let prefixes = require('../config/prefixes'); -let suffixes = require('../config/suffixes'); +const { prefixes } = require('../config/prefixes'); +const { suffixes } = require('../config/suffixes'); module.exports = { generators: [ diff --git a/src/server/items/generators/stats.js b/src/server/items/generators/stats.js index a3f92605..894e0e5b 100644 --- a/src/server/items/generators/stats.js +++ b/src/server/items/generators/stats.js @@ -1,4 +1,4 @@ -let statsFishingRod = require('./statsFishingRod'); +const events = require('../../misc/events'); module.exports = { generators: { @@ -494,14 +494,19 @@ module.exports = { }, generate: function (item, blueprint, result) { - if (item.slot === 'tool') { - statsFishingRod.generate(item, blueprint, result); - return; - } - if (!blueprint.statCount) item.stats = {}; + const eventMsg = { + item, + blueprint, + result, + ignore: false + }; + events.emit('onBeforeGenerateItemStats', eventMsg); + if (eventMsg.ignore) + return; + if (blueprint.noStats) return; diff --git a/src/server/items/generators/statsFishingRod.js b/src/server/items/generators/statsFishingRod.js deleted file mode 100644 index b16a7a25..00000000 --- a/src/server/items/generators/statsFishingRod.js +++ /dev/null @@ -1,57 +0,0 @@ -module.exports = { - generators: { - catchChance: function (item, blueprint) { - return random.expNorm(0, 60); - }, - - catchSpeed: function (item, blueprint) { - return random.expNorm(0, 150); - }, - - fishRarity: function (item, blueprint) { - return random.expNorm(0, 100); - }, - - fishWeight: function (item, blueprint) { - return random.expNorm(0, 75); - }, - - fishItems: function (item, blueprint) { - return random.expNorm(0, 50); - } - }, - - generate: function (item, blueprint, result) { - let statCount = blueprint.statCount || (item.quality + 1); - let stats = Object.keys(this.generators); - - if (!item.stats) - item.stats = {}; - - for (let i = 0; i < statCount; i++) { - let stat = stats[~~(Math.random() * stats.length)]; - let value = Math.ceil(this.generators[stat].call(this, item, blueprint)); - - if (result) { - result.addStatMsgs.push({ - stat: stat, - value: value - }); - } - - if (!item.stats[stat]) - item.stats[stat] = 0; - - item.stats[stat] += value; - - if (blueprint.statCount) { - if (!item.enchantedStats) - item.enchantedStats = {}; - if (item.enchantedStats[stat]) - item.enchantedStats[stat] += value; - else - item.enchantedStats[stat] = value; - } - } - } -}; diff --git a/src/server/world/instancer.js b/src/server/world/instancer.js index bebd2399..39962e6b 100644 --- a/src/server/world/instancer.js +++ b/src/server/world/instancer.js @@ -9,7 +9,6 @@ let randomMap = require('./randomMap'); let events = require('../events/events'); let scheduler = require('../misc/scheduler'); let mail = require('../mail/mail'); -let resourceNodes = require('../config/resourceNodes'); let eventEmitter = require('../misc/events'); const transactions = require('../security/transactions'); @@ -24,7 +23,6 @@ module.exports = { this.zoneId = args.zoneId; spellCallbacks.init(); - resourceNodes.init(); map.init(args); const fakeInstance = { diff --git a/src/server/world/worker.js b/src/server/world/worker.js index 262ce562..08801c88 100644 --- a/src/server/world/worker.js +++ b/src/server/world/worker.js @@ -14,11 +14,14 @@ let factions = require('../config/factions'); let classes = require('../config/spirits'); let spellsConfig = require('../config/spellsConfig'); let spells = require('../config/spells'); -let itemTypes = require('../items/config/types'); let mapList = require('../config/maps/mapList'); let sheets = require('../security/sheets'); let itemEffects = require('../items/itemEffects'); +const itemTypes = require('../items/config/types'); +const itemPrefixes = require('../items/config/prefixes'); +const itemSuffixes = require('../items/config/suffixes'); + let onCpnsReady = function () { factions.init(); skins.init(); @@ -27,7 +30,11 @@ let onCpnsReady = function () { classes.init(); spellsConfig.init(); spells.init(); + itemTypes.init(); + itemPrefixes.init(); + itemSuffixes.init(); + mapList.init(); sheets.init(); itemEffects.init();