soul2/wc3word
parent
bc96eaa91a
commit
057fcdf401
11 changed files with 595 additions and 54 deletions
@ -0,0 +1,201 @@ |
||||
/** |
||||
* chatGPT改进版 |
||||
*/ |
||||
interface StorageItem { |
||||
value: any; |
||||
lostTime?: Date; |
||||
} |
||||
|
||||
const storageHelper = { |
||||
/** |
||||
* |
||||
* @param name 保存名称 |
||||
* @param key 保存的key |
||||
* @param value 保存的值 |
||||
* @param time 失活时间,默认无限 |
||||
*/ |
||||
set: function (name: string, key: string, value: any, time?: Date): void { |
||||
const str = localStorage.getItem(name); |
||||
let storage: { [key: string]: StorageItem }; |
||||
try { |
||||
storage = JSON.parse(str || '{}') |
||||
} catch (e) { |
||||
console.error(`无法解析数据名称 "${name}" ,该数据可能已损坏。`) |
||||
console.error('目标数据:\n' + str) |
||||
return; |
||||
} |
||||
storage[key] = { |
||||
value, |
||||
lostTime: time, |
||||
} |
||||
localStorage.setItem(name, JSON.stringify(storage)) |
||||
}, |
||||
/** |
||||
* 读取数据 |
||||
* @param name |
||||
* @param key |
||||
*/ |
||||
get: function (name: string, key: string): any { |
||||
const str = localStorage.getItem(name); |
||||
let storage: { [key: string]: StorageItem }; |
||||
try { |
||||
storage = JSON.parse(str) |
||||
} catch (e) { |
||||
console.error(`无法解析数据名称 "${name}" ,该数据可能已损坏。`) |
||||
console.error('目标数据:\n' + str) |
||||
return; |
||||
} |
||||
this.clearLostTimeData(name) |
||||
return storage[key]?.value; |
||||
}, |
||||
/** |
||||
* 删除目标数据 |
||||
* @param name |
||||
* @param key |
||||
*/ |
||||
remove: function (name: string, key?: string | string[]) { |
||||
if (!name) return; |
||||
const str = localStorage.getItem(name); |
||||
let storage: { [key: string]: StorageItem }; |
||||
try { |
||||
storage = JSON.parse(str || '{}') |
||||
} catch (e) { |
||||
console.error(`无法解析数据名称 "${name}" ,该数据可能已损坏。`) |
||||
console.error('目标数据:\n' + str) |
||||
return; |
||||
} |
||||
if (!key) { |
||||
localStorage.removeItem(name); |
||||
return; |
||||
} |
||||
const keys = Array.isArray(key) ? key : [key]; |
||||
for (const k of keys) { |
||||
if (storage[k]) { |
||||
storage[k] = undefined; |
||||
} |
||||
} |
||||
localStorage.setItem(name, JSON.stringify(storage)); |
||||
}, |
||||
/** |
||||
* 清除失活的数据 |
||||
* @param name |
||||
*/ |
||||
clearLostTimeData: function (name: string): boolean { |
||||
const str = localStorage.getItem(name); |
||||
let storage: { [key: string]: StorageItem }; |
||||
try { |
||||
storage = JSON.parse(str || '{}'); |
||||
} catch (e) { |
||||
return false; |
||||
} |
||||
const keys = Object.keys(storage); |
||||
const now = new Date().getTime(); |
||||
let changed = false; |
||||
for (const k of keys) { |
||||
if (storage[k].lostTime && storage[k].lostTime.getTime() < now) { |
||||
storage[k] = undefined; |
||||
changed = true; |
||||
} |
||||
} |
||||
if (changed) { |
||||
const remainingKeys = Object.keys(storage).filter(k => storage[k]); |
||||
if (remainingKeys.length > 0) { |
||||
localStorage.setItem(name, JSON.stringify(storage)); |
||||
} else { |
||||
localStorage.removeItem(name); |
||||
} |
||||
} |
||||
return changed; |
||||
}, |
||||
}; |
||||
|
||||
export default storageHelper; |
||||
|
||||
|
||||
/** |
||||
* 原始版本 |
||||
*/ |
||||
// const storageHelper = {
|
||||
// /**
|
||||
// *
|
||||
// * @param name 保存名称
|
||||
// * @param key 保存的key
|
||||
// * @param value 保存的值
|
||||
// * @param time 失活时间,默认无限
|
||||
// */
|
||||
// set: function (name: string, key: string, value: any, time: Date = undefined) {
|
||||
// const str = localStorage.getItem(name);
|
||||
// let storage: object;
|
||||
// try {
|
||||
// storage = JSON.parse(str || '{}')
|
||||
// } catch (e) {
|
||||
// console.error(`无法解析数据名称 "${name}" ,该数据可能已损坏。`)
|
||||
// console.error('目标数据:\n' + str)
|
||||
// return;
|
||||
// }
|
||||
// storage[key] = {
|
||||
// value,
|
||||
// lostTime: time,
|
||||
// }
|
||||
// localStorage.setItem(name, JSON.stringify(storage))
|
||||
// },
|
||||
// get: function (name: string, key: string): any {
|
||||
// const str = localStorage.getItem(name);
|
||||
// let storage: object;
|
||||
// try {
|
||||
// storage = JSON.parse(str)
|
||||
// } catch (e) {
|
||||
// console.error(`无法解析数据名称 "${name}" ,该数据可能已损坏。`)
|
||||
// console.error('目标数据:\n' + str)
|
||||
// return;
|
||||
// }
|
||||
// this.clearLostTimeData(name)
|
||||
// return storage[key].data
|
||||
// },
|
||||
// remove: function (name: string, key: any) {
|
||||
// if (name) {
|
||||
// if (key) {
|
||||
// const str = localStorage.getItem(name);
|
||||
// let storage: object;
|
||||
// try {
|
||||
// storage = JSON.parse(str)
|
||||
// } catch (e) {
|
||||
// console.error(`无法解析数据名称 "${name}" ,该数据可能已损坏。`)
|
||||
// console.error('目标数据:\n' + str)
|
||||
// return;
|
||||
// }
|
||||
// if (Array.isArray(key)) {
|
||||
//
|
||||
// }
|
||||
// } else {
|
||||
// localStorage.removeItem(name)
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
// clearLostTimeData: function (name: string) {
|
||||
// const str = localStorage.getItem(name);
|
||||
// let storage: object;
|
||||
// try {
|
||||
// storage = JSON.parse(str);
|
||||
// } catch (e) {
|
||||
// return false;
|
||||
// }
|
||||
// let keys = Object.keys(storage)
|
||||
// let now = new Date().getTime()
|
||||
// keys.forEach((key, i) => {
|
||||
// if (storage[key].lostTime && storage[key].lostTime.getTime() < now) {
|
||||
// storage[key] = undefined
|
||||
// }
|
||||
// })
|
||||
// keys = Object.keys(storage)
|
||||
// if (keys.length == 0) {
|
||||
// localStorage.removeItem(name)
|
||||
// return false;
|
||||
// } else {
|
||||
// return true;
|
||||
// }
|
||||
// },
|
||||
// }
|
||||
//
|
||||
// export default storageHelper
|
||||
|
@ -0,0 +1,108 @@ |
||||
<template> |
||||
<el-dialog ref="dialogForm" width="30%" :title="title" :visible.sync="visible" @close="closeDialog" |
||||
:append-to-body="true"> |
||||
<div style="padding-left: 10%;padding-right: 10%;"> |
||||
<el-radio-group v-model="checked" size="mini"> |
||||
<el-radio v-for="(e,i) in spellLoadList" :label="e" border> |
||||
{{ e !== spellMap[e].name ? e + `<${spellMap[e].name}>` : e }} |
||||
</el-radio> |
||||
</el-radio-group> |
||||
</div> |
||||
<div slot="footer" class="dialog-footer"> |
||||
<el-button size="mini" @click="visible = false">取消</el-button> |
||||
<el-button size="mini" type="primary" @click="handleLoad">读取</el-button> |
||||
<el-button size="mini" type="warning" @click="handleRemove">删除</el-button> |
||||
<el-button size="mini" type="danger" @click="handleRemoveAll">删除全部</el-button> |
||||
</div> |
||||
</el-dialog> |
||||
</template> |
||||
|
||||
<script> |
||||
export default { |
||||
name: 'LoadSpellDialog', |
||||
props: { |
||||
spellMap: { |
||||
type: Object, |
||||
require: true |
||||
}, |
||||
spellList: { |
||||
type: Array |
||||
}, |
||||
show: { |
||||
type: Boolean, |
||||
default: () => false |
||||
} |
||||
}, |
||||
components: {}, |
||||
data() { |
||||
return { |
||||
visible: this.show, |
||||
checked: null |
||||
} |
||||
}, |
||||
computed: { |
||||
title() { |
||||
return '你要读取哪个' |
||||
}, |
||||
spellLoadList() { |
||||
return this.spellList || Object.keys(this.spellMap) |
||||
}, |
||||
}, |
||||
watch: { |
||||
visible() { |
||||
this.$emit('update:show', false) |
||||
} |
||||
}, |
||||
created() { |
||||
|
||||
}, |
||||
mounted() { |
||||
}, |
||||
methods: { |
||||
closeDialog() { |
||||
// 关闭 |
||||
}, |
||||
handleLoad() { |
||||
if (this.checked) { |
||||
this.$emit('load', this.spellMap[this.checked]) |
||||
// console.log('checked -> ', this.checked) |
||||
this.visible = false |
||||
} else { |
||||
this.$message({type: 'info', message: '你还没选择!'}); |
||||
} |
||||
}, |
||||
handleRemove() { |
||||
if (this.checked) { |
||||
this.$confirm('此操作将永久删除这个记录, 是否继续?', '提示', { |
||||
confirmButtonText: '确定', |
||||
cancelButtonText: '取消', |
||||
type: 'warning' |
||||
}).then(() => { |
||||
this.$emit('remove', this.checked) |
||||
// console.log('checked -> ', this.checked) |
||||
this.visible = false |
||||
}).catch(() => { |
||||
}) |
||||
} else { |
||||
this.$message({type: 'info', message: '你还没选择!'}); |
||||
} |
||||
}, |
||||
handleRemoveAll() { |
||||
this.$confirm('此操作将永久删除所有保存记录, 是否继续?', '提示', { |
||||
confirmButtonText: '确定', |
||||
cancelButtonText: '取消', |
||||
type: 'danger' |
||||
}).then(() => { |
||||
localStorage.removeItem('spell-list') |
||||
this.$message({type: 'success', message: '记录已清空!'}); |
||||
this.visible = false |
||||
}).catch(() => { |
||||
}) |
||||
}, |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<style scoped lang="scss"> |
||||
|
||||
</style> |
@ -1,51 +0,0 @@ |
||||
<template> |
||||
<el-dialog ref="dialogForm" width="45%" :title="title" :visible.sync="visible" @close="closeDialog" |
||||
:append-to-body="true" :show-close="false"> |
||||
<!-- <div slot="footer" class="dialog-footer">--> |
||||
<!-- <el-button @click="visible = false">取消</el-button>--> |
||||
<!-- <el-button type="primary" @click="handleSave">保存</el-button>--> |
||||
<!-- </div>--> |
||||
</el-dialog> |
||||
</template> |
||||
|
||||
<script> |
||||
export default { |
||||
name: 'UpdateRecordDialog', |
||||
props: { |
||||
show: { |
||||
type: Boolean, |
||||
default: () => false |
||||
} |
||||
}, |
||||
components: {}, |
||||
data() { |
||||
return { |
||||
visible: this.show, |
||||
} |
||||
}, |
||||
computed: { |
||||
title() { |
||||
return '更新记录' |
||||
} |
||||
}, |
||||
watch: { |
||||
visible() { |
||||
this.$emit('update:show', false) |
||||
} |
||||
}, |
||||
created() { |
||||
|
||||
}, |
||||
mounted() { |
||||
}, |
||||
methods: { |
||||
closeDialog() { |
||||
// 关闭 |
||||
}, |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<style scoped lang="scss"> |
||||
|
||||
</style> |
@ -0,0 +1,26 @@ |
||||
const version = { |
||||
'1.0': { |
||||
7: [ |
||||
{type: '完成', value: '更新日志'}, |
||||
{type: '修复', value: '技能文本恢复默认时没有清空数值的bug'}, |
||||
], |
||||
6: [ |
||||
{type: '新', value: '导出导入技能'}, |
||||
], |
||||
5: [ |
||||
{type: '完成', value: '技能文本的保存能力'}, |
||||
{type: '修复', value: '新的技能数值输入方法'}, |
||||
], |
||||
3: [ |
||||
{type: '完成', value: '生成器文本实时同步'}, |
||||
{type: '完成', value: '色彩及生成器恢复默认按钮'}, |
||||
{type: '完成', value: '保存色彩方案'}, |
||||
], |
||||
2: [ |
||||
{type: '完成', value: '色彩'}, |
||||
{type: '完成', value: '编辑'}, |
||||
], |
||||
} |
||||
} |
||||
|
||||
export default version |
@ -0,0 +1,55 @@ |
||||
<template> |
||||
<el-collapse v-model="activeNames"> |
||||
<el-collapse-item class="version" v-for="v in versionList('1.0')" :name="v.v"> |
||||
<div slot="title" class="version-title">{{ v.v }}</div> |
||||
<div class="version-line" v-for="line in v.l">[{{ line.type }}]{{ line.value }}</div> |
||||
</el-collapse-item> |
||||
</el-collapse> |
||||
</template> |
||||
|
||||
<script> |
||||
import version from '@/views/wc3word/dialog/version' |
||||
|
||||
export default { |
||||
name: 'UpdateRecord', |
||||
props: { |
||||
version: String |
||||
}, |
||||
components: {}, |
||||
data() { |
||||
return { |
||||
activeNames: [], |
||||
} |
||||
}, |
||||
computed: {}, |
||||
watch: {}, |
||||
created() { |
||||
this.activeNames.push(this.versionList('1.0')[0].v) |
||||
}, |
||||
mounted() { |
||||
}, |
||||
methods: { |
||||
versionList(pv) { |
||||
let keys = Object.keys(version[pv]).sort((a, b) => b - a) |
||||
return keys.map(e => ({v: pv + '.' + e, l: version[pv][e]})) |
||||
} |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<style scoped lang="scss"> |
||||
.version { |
||||
&-title { |
||||
font-size: 16px; |
||||
font-weight: bold; |
||||
} |
||||
|
||||
&-line { |
||||
padding-left: 5%; |
||||
padding-right: 5%; |
||||
text-align: left; |
||||
font-size: 16px; |
||||
font-weight: bold; |
||||
} |
||||
} |
||||
</style> |
@ -0,0 +1,8 @@ |
||||
const wwbTools = { |
||||
dyeing: (str, color) => { |
||||
const prefix = '|cfff' |
||||
const suffix = '|r' |
||||
return color ? (prefix + color.replace('#', "") + str + suffix) : str |
||||
}, |
||||
} |
||||
export default wwbTools |
@ -0,0 +1,153 @@ |
||||
import wwbTools from '@/views/word_builder/tools/tools' |
||||
/* Spell */ |
||||
const default_spell_module = { |
||||
name: null, // 技能名称
|
||||
hotKey: null, // 热键
|
||||
learn: { // 学习文本设置
|
||||
title: null, // 学习标题
|
||||
tip: { // 学习扩展文本
|
||||
effect: null, // 效果描述
|
||||
attr: () => this.attrData.filter(e => !Array.isArray(e)), // 属性
|
||||
lvEffect: [ // 每个等级的效果描述
|
||||
// { text: '造成{a}点伤害和{b}秒眩晕', data: [100,3] }
|
||||
], |
||||
}, |
||||
}, |
||||
attrData: [ |
||||
/** |
||||
* { name: '法力消耗', value: null } |
||||
* or |
||||
* { name: '法力消耗', value: [] } |
||||
*/ |
||||
], |
||||
normal: { // 普通技能文本
|
||||
attr: () => this.attrData.filter(e => e.name !== '法力消耗'), |
||||
title: null, // 标题
|
||||
tip: [ |
||||
/** { text: '造成{a}点伤害和{b}秒眩晕', data: [100,3] } */ |
||||
] |
||||
}, |
||||
nature: null, // 特点
|
||||
toWord: (color, module, lv) => { |
||||
let result = '' |
||||
if (module) { |
||||
if (module === 'title') { |
||||
if (lv) { |
||||
result += `${this.name}(${wwbTools.dyeing(this.hotKey, color.hotKey)})` |
||||
result += ` - [${wwbTools.dyeing(lv + '级', color.level)}]` |
||||
} else { |
||||
lv = '%d' |
||||
result += `学习 ${wwbTools.dyeing(lv + '级', color.level)} ${this.name}(${wwbTools.dyeing(this.hotKey, color.hotKey)})` |
||||
} |
||||
} else if (module === 'uberTip') { |
||||
if (lv) { // 有lv,返回普通文本
|
||||
lv = Math.min(lv, this.normal.tip.length) |
||||
let d = this.normal.tip[lv] |
||||
result += d.text.format(...d.data) |
||||
result += this.nature ? ('\n\n' + wwbTools.dyeing(this.nature, color.nature)) : '' |
||||
if (this.normal.attr().length > 0) { |
||||
result += ('\n') |
||||
this.normal.attr().forEach((e) => { |
||||
result += ('\n' + wwbTools.dyeing(e.name, color.property) + ':') |
||||
try { |
||||
result += (Array.isArray(e.value) ? e.value[lv] : e.value) |
||||
} catch (e) { |
||||
result += e.value[e.value.length - 1] |
||||
} |
||||
}) |
||||
} |
||||
} else { // 无lv,返回学习文本
|
||||
result += (this.learn.tip.effect) |
||||
result += this.nature ? ('\n\n' + wwbTools.dyeing(this.nature, color.nature)) : '' |
||||
if (this.learn.tip.attr().length > 0) { |
||||
result += '\n' |
||||
this.learn.tip.attr().forEach((e) => { |
||||
result += ('\n' + wwbTools.dyeing(e.name, color.property) + ':') |
||||
try { |
||||
result += (Array.isArray(e.value) ? e.value[lv] : e.value) |
||||
} catch (e) { |
||||
result += e.value[e.value.length - 1] |
||||
} |
||||
}) |
||||
} |
||||
if (this.learn.tip.lvEffect?.length > 0) { |
||||
result += '\n' |
||||
this.learn.tip.lvEffect.forEach((e, i) => { |
||||
result += ('\n' + wwbTools.dyeing((i + 1) + '级 - ', color.learnUpdateLevel)) |
||||
result += (e.text.format(...e.data)) |
||||
}) |
||||
} |
||||
} |
||||
} |
||||
} |
||||
return result |
||||
}, |
||||
} |
||||
|
||||
|
||||
/* Unit */ |
||||
const default_unit_module = { |
||||
name: null, // 单位名称
|
||||
desc: null, // 单位描述,可填充数据项
|
||||
descValues: null, // 单位描述数据
|
||||
hotKey: null, // 热键
|
||||
spells: [ // 技能列表,可以是对象列表,也可以是字符串列表
|
||||
{ |
||||
name: null, // 技能名称
|
||||
desc: null, // 技能简述,不可填充数据,可选项
|
||||
}, { |
||||
name: null, // 技能名称
|
||||
desc: null, // 技能简述,不可填充数据,可选项
|
||||
}, |
||||
], |
||||
nature: null, // 特点
|
||||
attack: { // 攻击力设置
|
||||
max: null, // 攻击力上限
|
||||
min: null, // 攻击力下限
|
||||
dice: { // 骰子设置
|
||||
count: null, // 骰子个数
|
||||
sides: null, // 骰子面数
|
||||
}, |
||||
type: null, // 攻击力类型
|
||||
range: null, // 射程
|
||||
}, |
||||
hp: null, // 最大生命值
|
||||
mp: null, // 最大法力值
|
||||
armor: { // 护甲设置
|
||||
value: null, // 护甲值
|
||||
type: null // 护甲类型
|
||||
}, |
||||
} |
||||
|
||||
/* item */ |
||||
const default_item_module = { |
||||
overlapping: false, // 是否可叠加,默认否
|
||||
hotKey: null, // 热键
|
||||
uses: 0, // 使用次数,默认是0
|
||||
price: 125, // 价格,默认是125
|
||||
desc: { // 说明设置
|
||||
tip: null, // 放地上鼠标点击显示的文本提示
|
||||
title: null, // 标题
|
||||
uberTip: null, // 扩展
|
||||
}, |
||||
cd: { // 冷却时间,默认不显示
|
||||
show: false, |
||||
value: 0 |
||||
}, |
||||
beLost: true, // 可以被丢弃
|
||||
beSold: true, // 可卖给商店
|
||||
attributes: [ // 属性
|
||||
{ |
||||
type: 'gain', // gain=增益;reduce=减损;spell=技能
|
||||
name: null, // 属性名称,类型为spell时为技能名
|
||||
tip: null, // 技能描述,类型是spell时显示
|
||||
value: null, // 属性值,类型是spell时不显示
|
||||
}, |
||||
/** |
||||
* example: { type: gain, name: 力量, value: 3} -> result: 力量+3 |
||||
* example: { type: reduce, name: 力量, value: 3} -> result: |cffff0000力量-3|r |
||||
* example: { type: spell, name: 能量冲击, tip: 召唤能量光柱攻击敌人,造成100点伤害和3秒眩晕。} -> |
||||
* result: |cff00ff00能量冲击|r|n召唤能量光柱攻击敌人,造成100点伤害和3秒眩晕。 |
||||
*/ |
||||
], |
||||
} |
@ -0,0 +1,2 @@ |
||||
|
||||
|
Loading…
Reference in new issue