UNPKG

discord-dungeon

Version:

Add inventories, enemies, and items to your Discord bot.

256 lines (227 loc) 8.16 kB
const fs = require('fs') const xlsx = require('xlsx') const { Skills } = require('../skills/Skills') if(!fs.existsSync('./discord-dungeon')) { fs.mkdirSync('./discord-dungeon') } if(!fs.existsSync('./discord-dungeon/items.xlsx')) { const data = [ { name:"Wood", sellPrice:10, buyPrice:0, quality: "common", type: "material", slot:"", class: "", skill: "", add: "{}", remove: "{}", craft: "{}" }, { name:"Sword", sellPrice:20, buyPrice:10, quality: "common", type: "equipment", slot:"weapon", class: "warrior", skill: "1", add: '{"health_max":20}', remove: '{"armor":2}', craft: '{"1": 4}' } ] const newWB = xlsx.utils.book_new() const newData = xlsx.utils.json_to_sheet(data) xlsx.utils.book_append_sheet(newWB, newData, "Items") xlsx.writeFile(newWB, './discord-dungeon/items.xlsx') } const wb = xlsx.readFile('./discord-dungeon/items.xlsx') const ws = wb.Sheets["Items"] let data = xlsx.utils.sheet_to_json(ws) const items = data.map((_item, i) => { let item = _item item.id = i+1 return item }) let names = [] class Item { constructor(data = {}){ this.id = data.id this.name = data.name this.sellPrice = data.sellPrice this.buyPrice = data.buyPrice this.quality = data.quality this.type = data.type if (data.type === 'equipment') { this.class = data.class this.skill = data.skill this.slot = data.slot this.add = JSON.parse(data.add) this.remove = JSON.parse(data.remove) } if (data.craft !== "{}") { this.craft = JSON.parse(data.craft) } } } class Items { /** * Get the item by ID * @param {number} itemid Item ID * @returns {(Item|false)} Returns {@link Item}: * ```json * {id: 0, price: 123} * ``` * if not found returns false */ static GetItemWithID(itemid) { if(isNaN(itemid) || Number(itemid) < 0) { return new Error("Invalid item id") } for (const _item of items) { if (_item.id === parseInt(itemid)) return new Item(_item) } return false } /** * Get the item by name * @param {string} itemname Item name * @returns {(Item|false)} Returns {@link Item}: * ```json * {id: 0, price: 123} * ``` * if not found returns false */ static GetItemWithName(itemname) { if(typeof itemname !== 'string' || !itemname || itemname === "") { return new Error("Null item name") } for (const _item of items) { if (_item.name.toLowerCase() === itemname.toLowerCase()) return new Item(_item) } return false } /** * Get all items in the dictionary * @param {string} sort Sort type ('alphabet', 'id', 'quality', 'price') * @returns {Item[]} Item removed successfully */ static GetAllItems(sort='alphabet') { if (!['alphabet', 'id', 'quality', 'price'].includes(sort)) { const err = new Error('Wrong type sort') return err; } let Items = [] for (const _item of items) { Items.push(new Item(_item)) } if(sort === 'id') { Items.sort((a, b) => a.id - b.id) } if(sort === 'quality') { Items.sort((a, b) => b.quality - a.quality) } if(sort === 'price') { Items.sort((a, b) => b.sellPrice - a.sellPrice) } return Items } } for (const _item of items) { const item = new Item(_item) if (!item.name || typeof item.name !== 'string' || item.name.length > 20) { const err = new Error(`Invalid item name. line: ${item.id+1}`) throw err; } if (item.sellPrice !== 0) { if (isNaN(item.sellPrice) || Number(item.sellPrice) <= 0) { const err = new Error(`Invalid item price sell. line: ${item.id+1}`) throw err; } } if (item.buyPrice !== 0) { if (isNaN(item.buyPrice) || Number(item.buyPrice) <= 0) { const err = new Error(`Invalid item price buy. line: ${item.id+1}`) throw err; } } if (!item.quality || !['common', 'uncommon', 'special', 'rare', 'very_rare', 'mythical'].includes(item.quality)) { const err = new Error(`Invalid item quality. line: ${item.id+1}`) throw err; } if (!['material', 'equipment'].includes(item.type)) { const err = new Error(`Invalid item type. line: ${item.id+1}`) throw err; } if(item.type === 'equipment') { if (!item.slot || !['weapon', 'helmet', 'chestplate'].includes(item.slot) ) { const err = new Error(`Invalid item slot. line: ${item.id+1}`) throw err; } if (!item.class || !['warrior', 'magician', 'tank', 'mechanic', 'trainer'].includes(item.class) ) { const err = new Error(`Invalid item class. line: ${item.id+1}`) throw err; } if (!item.skill || !Skills.GetSkillWithID(item.skill) ) { const err = new Error(`Invalid Item skill id. line: ${item.id+1}`) throw err; } if (item.add) { for (const key in item.add) { if (!['health_max', 'armor'].includes(key)) { const err = new Error(`Invalid item add stat ${key}. line: ${item.id+1}`) throw err; } else { if (isNaN(item.add[`${key}`]) || Number(item.add[`${key}`]) <= -1 || !Number.isInteger(Number(item.add[`${key}`]))) { const err = new Error(`Invalid item add value stat ${key}. line: ${item.id+1}`) throw err; } } } } if (item.remove) { for (const key in item.remove) { if (!['health_max', 'armor'].includes(key)) { const err = new Error(`Invalid item add stat ${key}. line: ${item.id+1}`) throw err; } else { if (isNaN(item.remove[`${key}`]) || Number(item.remove[`${key}`]) < 0 || !Number.isInteger(Number(item.remove[`${key}`]))) { const err = new Error(`Invalid item add value stat ${key}. line: ${item.id+1}`) throw err; } } } } if (item.craft) { for (const key in item.craft) { if (!Items.GetItemWithID(key)) { const err = new Error(`Invalid material id craft ${key}. line: ${item.id+1}`) throw err; } else { if (isNaN(item.craft[`${key}`]) || Number(item.craft[`${key}`]) <= -1 || !Number.isInteger(Number(item.craft[`${key}`]))) { const err = new Error(`Invalid material amount craft ${key}. line: ${item.id+1}`) throw err; } } } } } names.push(item.name) } let findDuplicates = arr => arr.filter((item, index) => arr.indexOf(item) != index) findDuplicates(names).forEach(name => { for (const _item of items) { const item = new Item(_item) if (item.name.toLowerCase().trim() === name.toLowerCase().trim()) { const err = new Error(`Duplicated item name. line: ${item.id+1}`) throw err; } } }); module.exports = {Items}