mirror of
https://github.com/ZZZure/ZZZ-Plugin.git
synced 2025-12-15 12:47:48 +00:00
149 lines
5.4 KiB
JavaScript
149 lines
5.4 KiB
JavaScript
import { aliasToID } from '../../lib/convert/char.js';
|
||
import config from '../../../../lib/config/config.js';
|
||
import { BuffManager } from './BuffManager.js';
|
||
import { pluginPath } from '../../lib/path.js';
|
||
import { elementEnum } from './BuffManager.js';
|
||
import { Calculator } from './Calculator.js';
|
||
import chokidar from 'chokidar';
|
||
import path from 'path';
|
||
import fs from 'fs';
|
||
const damagePath = path.join(pluginPath, 'model', 'damage');
|
||
export const charData = {};
|
||
const calcFnc = {
|
||
character: {},
|
||
weapon: {},
|
||
set: {}
|
||
};
|
||
async function init() {
|
||
const isWatch = config.bot.log_level === 'debug'; // debug模式下监听文件变化
|
||
await Promise.all(fs.readdirSync(path.join(damagePath, 'character')).filter(v => v !== '模板').map(v => importChar(v, isWatch)));
|
||
for (const type of ['weapon', 'set']) {
|
||
await Promise.all(fs.readdirSync(path.join(damagePath, type)).filter(v => v !== '模板.js' && !v.endsWith('_user.js') && v.endsWith('.js'))
|
||
.map(v => importFile(type, v.replace('.js', ''), isWatch)));
|
||
}
|
||
}
|
||
function watchFile(path, fnc) {
|
||
if (!fs.existsSync(path))
|
||
return;
|
||
const watcher = chokidar.watch(path, {
|
||
awaitWriteFinish: {
|
||
stabilityThreshold: 50
|
||
}
|
||
});
|
||
watcher.on('change', (path) => {
|
||
logger.debug('重载' + path);
|
||
fnc();
|
||
});
|
||
}
|
||
async function importChar(charName, isWatch = false) {
|
||
const id = aliasToID(charName);
|
||
if (!id)
|
||
return logger.warn(`未找到角色${charName}的ID`);
|
||
const dir = path.join(damagePath, 'character', charName);
|
||
const calcFile = fs.existsSync(path.join(dir, 'calc_user.js')) ? 'calc_user.js' : 'calc.js';
|
||
const dataPath = path.join(dir, (fs.existsSync(path.join(dir, 'data_user.json')) ? 'data_user.json' : 'data.json'));
|
||
try {
|
||
if (isWatch) {
|
||
watchFile(path.join(dir, calcFile), () => importChar(charName));
|
||
watchFile(dataPath, () => charData[id] = JSON.parse(fs.readFileSync(dataPath, 'utf8')));
|
||
}
|
||
charData[id] = JSON.parse(fs.readFileSync(dataPath, 'utf8'));
|
||
const m = await import(`./character/${charName}/${calcFile}?${Date.now()}`);
|
||
if (!m.calc && (!m.buffs || !m.skills))
|
||
throw new Error('伤害计算文件格式错误');
|
||
calcFnc.character[id] = m;
|
||
}
|
||
catch (e) {
|
||
logger.error(`导入角色${charName}伤害计算错误:`, e);
|
||
}
|
||
}
|
||
async function importFile(type, name, isWatch = false) {
|
||
const defaultFilePath = path.join(damagePath, type, `${name}.js`);
|
||
const userFilePath = path.join(damagePath, type, `${name}_user.js`);
|
||
const isUser = fs.existsSync(userFilePath);
|
||
const filePath = isUser ? userFilePath : defaultFilePath;
|
||
try {
|
||
if (isWatch) {
|
||
watchFile(filePath, () => importFile(type, name));
|
||
}
|
||
const m = await import(`./${type}/${name}${isUser ? '_user' : ''}.js?${Date.now()}`);
|
||
if (!m.calc && !m.buffs)
|
||
throw new Error(type + ' Buff计算文件格式错误');
|
||
calcFnc[type][name] = m;
|
||
}
|
||
catch (e) {
|
||
logger.error(`导入${type}/${name}.js错误:`, e);
|
||
}
|
||
}
|
||
await init();
|
||
/** 角色计算 */
|
||
export function avatar_ability(avatar) {
|
||
const m = calcFnc.character[avatar.id];
|
||
if (!m)
|
||
return [];
|
||
const buffM = new BuffManager(avatar);
|
||
const calc = new Calculator(buffM);
|
||
logger.debug('initial_properties', avatar.initial_properties);
|
||
weapon_buff(avatar.weapon, buffM);
|
||
set_buff(avatar.equip, buffM);
|
||
if (m.buffs)
|
||
buffM.new(m.buffs);
|
||
if (m.skills)
|
||
calc.new(m.skills);
|
||
if (m.calc)
|
||
m.calc(buffM, calc, avatar);
|
||
logger.debug(`Buff*${buffM.buffs.length}:`, buffM.buffs);
|
||
return calc.calc();
|
||
}
|
||
/** 武器加成 */
|
||
export function weapon_buff(equipment, buffM) {
|
||
const name = equipment.name;
|
||
logger.debug('武器:' + name);
|
||
const m = calcFnc.weapon[name];
|
||
if (!m)
|
||
return;
|
||
buffM.default({ name, source: 'Weapon' });
|
||
if (m.buffs)
|
||
buffM.new(m.buffs);
|
||
if (m.calc)
|
||
m.calc(buffM, equipment.star);
|
||
buffM.default({});
|
||
}
|
||
/** 套装加成 */
|
||
export function set_buff(equip, buffM) {
|
||
buffM.default({ name: '', source: 'Set' });
|
||
const setCount = {};
|
||
for (const equip_detail of equip) {
|
||
if (equip_detail.equipment_type == 5) {
|
||
// 属伤加成
|
||
const index = [31503, 31603, 31703, 31803, 31903].indexOf(equip_detail.main_properties[0].property_id);
|
||
if (index > -1 && elementEnum[index]) {
|
||
// @ts-ignore
|
||
buffM.new({
|
||
name: '驱动盘5号位',
|
||
type: '增伤',
|
||
value: Number(equip_detail.main_properties[0].base.replace('%', '')) / 100,
|
||
isForever: true,
|
||
element: elementEnum[index]
|
||
});
|
||
}
|
||
}
|
||
const suit_name = String(equip_detail.equip_suit.name);
|
||
setCount[suit_name] = (setCount[suit_name] || 0) + 1;
|
||
}
|
||
buffM.setCount = setCount;
|
||
for (const [name, count] of Object.entries(setCount)) {
|
||
if (count < 2)
|
||
continue;
|
||
logger.debug(`套装:${name}*${count}`);
|
||
const m = calcFnc.set[name];
|
||
if (!m)
|
||
continue;
|
||
buffM.default('name', name);
|
||
if (m.buffs)
|
||
buffM.new(m.buffs);
|
||
if (m.calc)
|
||
m.calc(buffM, count);
|
||
}
|
||
buffM.default({});
|
||
}
|