soul2/wc3word
soul2 2 years ago
parent bc96eaa91a
commit 057fcdf401
  1. 30
      src/utils/StringUtils.js
  2. 201
      src/utils/storageHelper.ts
  3. 2
      src/views/wc3word/dialog/SpellBuilder.vue
  4. 108
      src/views/wc3word/dialog/load.vue
  5. 51
      src/views/wc3word/dialog/updateRecord.vue
  6. 26
      src/views/wc3word/dialog/version.js
  7. 13
      src/views/wc3word/index.vue
  8. 55
      src/views/wc3word/updateRecord.vue
  9. 8
      src/views/word_builder/tools/tools.js
  10. 153
      src/views/word_builder/wc3data/json.js
  11. 2
      src/views/word_builder/wc3data/temp.js

@ -31,6 +31,36 @@ String.prototype.format = function (args) {
}
}
// chatGPT的 2.0 改进建议
// String.prototype.format = function (...args) {
// const pattern = /\{(\d*|\w*)\}/g;
// return this.replace(pattern, (match, p1) => {
// if (p1 === '') {
// throw new Error('占位符不能为空');
// }
//
// if (isNaN(p1)) {
// if (!args[0] || typeof args[0] !== 'object') {
// throw new Error('需要传入一个对象作为参数');
// }
//
// const value = args[0][p1];
// if (value === undefined) {
// throw new Error(`对象中没有名为${p1}的属性`);
// }
//
// return value;
// }
//
// const index = parseInt(p1);
// if (index >= args.length) {
// throw new Error(`占位符{${p1}}没有对应的参数`);
// }
//
// return args[index];
// });
// };
/**
* 取出所有a到b中间的字符串
*

@ -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

@ -108,7 +108,7 @@ export default {
handleSave() {
},
dyeing(str, color) {
const prefix = '|cfff'
const prefix = '|cff'
const suffix = '|r'
return color ? (prefix + color.replace('#', "") + str + suffix) : str
},

@ -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

@ -14,6 +14,10 @@
<color :color-default-config="colorConfig" style="padding-left: 3%;padding-right: 3%;"
@updateCfg="updateCfg"/>
</el-tab-pane>
<el-tab-pane>
<span slot="label"><i class="el-icon-tickets"></i>更新日志</span>
<update-record/>
</el-tab-pane>
</el-tabs>
</div>
</template>
@ -22,15 +26,17 @@
import Color from "@/views/wc3word/color";
import Edit from "@/views/wc3word/edit";
import {defaultColorConfig} from '@/utils/tools'
import UpdateRecord from "@/views/wc3word/updateRecord";
import version from '@/views/wc3word/dialog/version';
export default {
name: 'Word',
components: {Edit, Color},
components: {UpdateRecord, Edit, Color},
data() {
return {
colorConfig: Object.assign({}, defaultColorConfig),
version: '1.0.3'
version: '1.0.0'
}
},
computed: {},
@ -38,6 +44,9 @@ export default {
created() {
},
mounted() {
const latestVersion = Object.entries(version).pop() //
const latestSubVersion = Object.keys(latestVersion[1]).pop() //
this.version = `${latestVersion[0]}.${latestSubVersion}`
const h = this.$createElement;
this.$notify({
title: '来自Soul2的提示',

@ -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秒眩晕
*/
],
}
Loading…
Cancel
Save