mirror of
https://github.com/unanmed/HumanBreak.git
synced 2026-11-02 00:14:30 +08:00
完善装备栏、怪物手册,更新样板
This commit is contained in:
1 parent
bde0a4d1c0
commit
2f88272df8
37 files changed
+10569
-2558
No files matched your search
+3
-2
@@ -44,7 +44,8 @@ import BookDetail from './bookDetail.vue';
|
||||
import { LeftOutlined } from '@ant-design/icons-vue';
|
||||
import { KeyCode } from '../plugin/keyCodes';
|
||||
|
||||
const floorId = core.floorIds[core.status.event?.ui] ?? core.status.floorId;
|
||||
const floorId =
|
||||
core.floorIds[core.status.event?.ui as number] ?? core.status.floorId;
|
||||
const enemy = core.getCurrentEnemys(floorId);
|
||||
|
||||
const scroll = ref(0);
|
||||
@@ -65,7 +66,7 @@ enemy.forEach(v => {
|
||||
if (typeof v === 'string') return v;
|
||||
else return core.arrayToRGBA(v);
|
||||
});
|
||||
v.damageColor = getDamageColor(v.damage);
|
||||
v.damageColor = getDamageColor(v.damage!);
|
||||
});
|
||||
|
||||
/**
|
||||
|
||||
+180
-34
@@ -41,9 +41,10 @@
|
||||
><div
|
||||
class="equip selectable"
|
||||
v-for="([id, num], i) of toShow"
|
||||
:selected="selected === i"
|
||||
@mousedown="selected = i"
|
||||
@touchstart="selected = i"
|
||||
:selected="selected === i && !isCol"
|
||||
@mousedown="select(i)"
|
||||
@touchstart="select(i)"
|
||||
@click="clickList(i)"
|
||||
>
|
||||
<div class="equip-icon">
|
||||
<BoxAnimate
|
||||
@@ -71,10 +72,17 @@
|
||||
style="width: 100%; height: 30vh"
|
||||
:type="isMobile ? 'horizontal' : 'vertical'"
|
||||
>
|
||||
<div id="equip-now-div">
|
||||
<div id="equip-now-div" @touchmove="dragout">
|
||||
<div
|
||||
v-for="(name, i) of equipCol"
|
||||
class="equip-now-one"
|
||||
class="equip-now-one draginable selectable"
|
||||
:draged="draged"
|
||||
:access="canDragin(i)"
|
||||
:selected="isCol && selected === i"
|
||||
@mouseenter="dragin($event, i)"
|
||||
@touchmove="dragin($event, i)"
|
||||
@mouseleave="dragout"
|
||||
@click="select(i, true)"
|
||||
>
|
||||
<BoxAnimate
|
||||
:id="equiped[i] ?? 'none'"
|
||||
@@ -112,7 +120,13 @@
|
||||
</div>
|
||||
<div id="equip-desc">
|
||||
<div id="equip-icon">
|
||||
<BoxAnimate :id="toShow[selected]?.[0]"></BoxAnimate>
|
||||
<BoxAnimate
|
||||
:id="
|
||||
isCol
|
||||
? equiped[selected] ?? 'none'
|
||||
: toShow[selected]?.[0] ?? 'none'
|
||||
"
|
||||
></BoxAnimate>
|
||||
<span>{{ equip.name }}</span>
|
||||
</div>
|
||||
<div id="equip-type">
|
||||
@@ -135,15 +149,25 @@
|
||||
<div id="equip-desc-text">
|
||||
<span style="font-size: 3vh" id="title">装备介绍</span>
|
||||
<Scroll id="desc-text" style="height: 100%; width: 100%">
|
||||
<div v-if="!descText.value.startsWith('!!html')">
|
||||
<div v-if="!descText.value!.startsWith('!!html')">
|
||||
{{ descText.value }}
|
||||
</div>
|
||||
<div v-else v-html="descText.value.slice(6)"></div>
|
||||
<div v-else v-html="descText.value!.slice(6)"></div>
|
||||
</Scroll>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="icon-drag">
|
||||
<BoxAnimate
|
||||
class="drag-icon"
|
||||
v-if="draged"
|
||||
:id="toShow[selected]?.[0] ?? 'none'"
|
||||
:width="48"
|
||||
:height="48"
|
||||
noborder
|
||||
></BoxAnimate>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
@@ -153,26 +177,30 @@ import {
|
||||
SortAscendingOutlined,
|
||||
SortDescendingOutlined
|
||||
} from '@ant-design/icons-vue';
|
||||
import { computed, onMounted, onUnmounted, ref, watch } from 'vue';
|
||||
import { computed, onMounted, onUnmounted, reactive, ref, watch } from 'vue';
|
||||
import Scroll from '../components/scroll.vue';
|
||||
import { getAddStatus, getEquips, getNowStatus } from '../plugin/ui/equipbox';
|
||||
import BoxAnimate from '../components/boxAnimate.vue';
|
||||
import { has, type } from '../plugin/utils';
|
||||
import { cancelGlobalDrag, isMobile, useDrag } from '../plugin/use';
|
||||
import { hyper } from 'mutate-animate';
|
||||
import { message } from 'ant-design-vue';
|
||||
|
||||
const equips = getEquips();
|
||||
const equips = ref(getEquips());
|
||||
const col = ref('all');
|
||||
const all = core.material.items;
|
||||
const selected = ref(0);
|
||||
const isCol = ref(false); // 是否是选中的已装备的装备
|
||||
const equipCol = core.status.globalAttribute.equipName;
|
||||
const equiped = core.status.hero.equipment;
|
||||
const equiped = ref(core.status.hero.equipment);
|
||||
const listClicked = ref(false);
|
||||
|
||||
const draged = ref(false);
|
||||
const toEquipType = ref(-1); // 要穿至的装备孔,-1表示不穿
|
||||
|
||||
/** 排序方式,down表示下面大上面小 */
|
||||
const sort = ref<'up' | 'down'>('down');
|
||||
const norm = ref('none');
|
||||
const norm = ref<keyof SelectType<HeroStatus, number> | 'none'>('none');
|
||||
const sType = ref<'value' | 'percentage'>('value');
|
||||
|
||||
// 攻击 防御 回血 额外攻击
|
||||
@@ -197,38 +225,46 @@ watch(sType, n => {
|
||||
*/
|
||||
const equip = computed(() => {
|
||||
const index = toShow.value[selected.value];
|
||||
if (!has(index))
|
||||
return {
|
||||
name: '没有选择装备',
|
||||
cls: 'equip',
|
||||
text: '没有选择装备',
|
||||
equip: { type: '无', value: {}, percentage: {}, animate: '' }
|
||||
};
|
||||
const none = {
|
||||
name: '没有选择装备',
|
||||
cls: 'equip',
|
||||
text: '没有选择装备',
|
||||
equip: { type: '无', value: {}, percentage: {}, animate: '' }
|
||||
};
|
||||
if (isCol.value) {
|
||||
const id = equiped.value[selected.value];
|
||||
const e = core.material.items[id];
|
||||
if (!has(e)) return none;
|
||||
return e;
|
||||
}
|
||||
if (!has(index)) return none;
|
||||
return all[index[0]];
|
||||
});
|
||||
|
||||
const addStatus = computed(() => {
|
||||
return getAddStatus(equip.value.equip!);
|
||||
// @ts-ignore
|
||||
return getAddStatus(equip.value.equip!, isCol.value);
|
||||
});
|
||||
|
||||
const descText = computed(() => {
|
||||
if (equip.value.text.startsWith('!!html')) return ref(equip.value.text);
|
||||
return type(equip.value.text, 25, hyper('sin', 'out'), true);
|
||||
if (equip.value.text!.startsWith('!!html')) return ref(equip.value.text);
|
||||
return type(equip.value.text!, 25, hyper('sin', 'out'), true);
|
||||
});
|
||||
|
||||
const nowStatus = computed(() => {
|
||||
return getNowStatus(equip.value.equip);
|
||||
// @ts-ignore
|
||||
return getNowStatus(equip.value.equip, isCol.value);
|
||||
});
|
||||
|
||||
/**
|
||||
* 需要展示的装备,需要排序等操作
|
||||
* 需要展示的装备,已进行排序等操作
|
||||
*/
|
||||
const toShow = computed(() => {
|
||||
const sortType = sort.value;
|
||||
const sortNorm = norm.value;
|
||||
const sortBy = sType.value;
|
||||
|
||||
const res = equips.filter(v => {
|
||||
const res = equips.value.filter(v => {
|
||||
const e = all[v[0]].equip!;
|
||||
const t = e.type;
|
||||
if (sortNorm !== 'none') {
|
||||
@@ -268,15 +304,78 @@ function exit() {
|
||||
core.plugin.equipOpened.value = false;
|
||||
}
|
||||
|
||||
// ----- 交互函数
|
||||
let [fx, fy] = [0, 0];
|
||||
function dragEquip(x: number, y: number) {
|
||||
if ((x - fx) ** 2 + (y - fy) ** 2 > 10 ** 2) {
|
||||
draged.value = true;
|
||||
function clickList(i: number) {
|
||||
if (i === selected.value && listClicked.value) {
|
||||
const id = toShow.value[selected.value]?.[0];
|
||||
if (!core.canEquip(id)) {
|
||||
message.warn({
|
||||
content: '无法装备!',
|
||||
class: 'antdv-message'
|
||||
});
|
||||
return;
|
||||
}
|
||||
core.loadEquip(id);
|
||||
update();
|
||||
listClicked.value = false;
|
||||
}
|
||||
listClicked.value = true;
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
/**
|
||||
* 选择某个装备
|
||||
*/
|
||||
function select(i: number, col: boolean = false) {
|
||||
if (i !== selected.value && !col) {
|
||||
listClicked.value = false;
|
||||
}
|
||||
if (col) listClicked.value = false;
|
||||
if (col && isCol.value === col && selected.value === i) {
|
||||
core.unloadEquip(i);
|
||||
update();
|
||||
}
|
||||
isCol.value = col;
|
||||
selected.value = i;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否可以将当前装备拖入该栏
|
||||
* @param type 装备栏
|
||||
*/
|
||||
function canDragin(type: number) {
|
||||
if (type < 0) return false;
|
||||
const et = equip.value.equip?.type;
|
||||
if (!core.canEquip(toShow.value[selected.value]?.[0])) return false;
|
||||
if (!has(et)) return false;
|
||||
if (typeof et === 'number') return type === et;
|
||||
return equipCol[type] === et;
|
||||
}
|
||||
|
||||
/**
|
||||
* 穿上某个装备
|
||||
*/
|
||||
function loadEquip() {
|
||||
const num = toEquipType.value;
|
||||
if (num < 0) return;
|
||||
if (!canDragin(num)) {
|
||||
message.warn({
|
||||
content: '无法装备!',
|
||||
class: 'antdv-message'
|
||||
});
|
||||
return;
|
||||
}
|
||||
const now = equiped.value[num];
|
||||
const to = toShow.value[selected.value]?.[0];
|
||||
core.items._realLoadEquip(num, to, now);
|
||||
update();
|
||||
}
|
||||
|
||||
function update() {
|
||||
equiped.value = core.status.hero.equipment;
|
||||
equips.value = getEquips();
|
||||
}
|
||||
|
||||
// ----- 绑定函数
|
||||
function bind() {
|
||||
const equips = Array.from(
|
||||
document.querySelectorAll('.equip')
|
||||
) as HTMLDivElement[];
|
||||
@@ -289,9 +388,46 @@ onMounted(() => {
|
||||
fx = x;
|
||||
fy = y;
|
||||
},
|
||||
void 0,
|
||||
() => {
|
||||
if (draged.value) {
|
||||
draged.value = false;
|
||||
loadEquip();
|
||||
console.log(toEquipType.value);
|
||||
}
|
||||
},
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
// ----- 交互函数
|
||||
let [fx, fy] = [0, 0];
|
||||
function dragEquip(x: number, y: number, e: TouchEvent | MouseEvent) {
|
||||
if ((x - fx) ** 2 + (y - fy) ** 2 > 10 ** 2 && !draged.value) {
|
||||
draged.value = true;
|
||||
}
|
||||
if (draged.value) {
|
||||
const target = document.getElementById('icon-drag') as HTMLDivElement;
|
||||
target.style.left = `${x - 24}px`;
|
||||
target.style.top = `${y - 24}px`;
|
||||
}
|
||||
}
|
||||
|
||||
function dragin(e: Event, type: number) {
|
||||
e.stopPropagation();
|
||||
toEquipType.value = type;
|
||||
}
|
||||
|
||||
function dragout(e: Event) {
|
||||
e.stopPropagation();
|
||||
toEquipType.value = -1;
|
||||
}
|
||||
|
||||
watch(toShow, n => {
|
||||
bind();
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
bind();
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
@@ -442,11 +578,12 @@ onUnmounted(() => {
|
||||
padding-left: 5%;
|
||||
|
||||
.equip-now-one {
|
||||
flex-basis: 33.3%;
|
||||
flex-basis: 30%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
margin: 3% 0 3% 0;
|
||||
margin: 3% 3.3% 3% 0;
|
||||
padding-left: 0.5%;
|
||||
|
||||
span {
|
||||
margin-left: 10%;
|
||||
@@ -520,6 +657,15 @@ onUnmounted(() => {
|
||||
}
|
||||
}
|
||||
|
||||
#icon-drag {
|
||||
position: fixed;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 600px) {
|
||||
#equipbox {
|
||||
padding: 5%;
|
||||
|
||||
+16
-10
@@ -78,11 +78,15 @@
|
||||
></BoxAnimate>
|
||||
<div id="basic-info">
|
||||
<span style="border-bottom: 1px solid #ddd4">{{
|
||||
all[selected]?.name ?? '没有道具'
|
||||
selected === 'none'
|
||||
? '没有道具'
|
||||
: all[selected].name
|
||||
}}</span>
|
||||
<span>{{
|
||||
getClsName(all[selected]?.cls as ItemMode) ??
|
||||
'永久道具'
|
||||
selected === 'none'
|
||||
? '永久道具'
|
||||
: getClsName(all[selected].cls as ItemMode) ??
|
||||
'永久道具'
|
||||
}}</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -91,10 +95,10 @@
|
||||
<div id="desc">
|
||||
<span style="border-bottom: 1px solid #ddd4">道具描述</span>
|
||||
<Scroll id="desc-text">
|
||||
<div v-if="!descText.value.startsWith('!!html')">
|
||||
<div v-if="!descText.value!.startsWith('!!html')">
|
||||
{{ descText.value }}
|
||||
</div>
|
||||
<div v-else v-html="descText.value.slice(6)"></div>
|
||||
<div v-else v-html="descText.value!.slice(6)"></div>
|
||||
</Scroll>
|
||||
</div>
|
||||
</div>
|
||||
@@ -115,6 +119,7 @@ import { message } from 'ant-design-vue';
|
||||
import { KeyCode } from '../plugin/keyCodes';
|
||||
|
||||
type ItemMode = 'tools' | 'constants';
|
||||
type ShowItemIds = ItemIdOf<'constants' | 'tools'> | 'none';
|
||||
|
||||
const mode = ref<ItemMode>('tools');
|
||||
|
||||
@@ -126,7 +131,7 @@ const toShow = computed<ItemMode[]>(() => {
|
||||
|
||||
const all = core.material.items;
|
||||
|
||||
const selected = ref(items[toShow.value[0]][0]?.[0] ?? 'none');
|
||||
const selected = ref<ShowItemIds>(items[toShow.value[0]][0]?.[0] ?? 'none');
|
||||
const index = ref(0);
|
||||
|
||||
watch(index, n => {
|
||||
@@ -144,15 +149,15 @@ watch(mode, n => {
|
||||
const descText = computed(() => {
|
||||
const s = selected.value;
|
||||
if (s === 'none') return ref('没有选择道具');
|
||||
if (all[s].text.startsWith('!!html')) return ref(all[s].text);
|
||||
return type(all[s].text, 25, hyper('sin', 'out'), true);
|
||||
if (all[s].text!.startsWith('!!html')) return ref(all[s].text);
|
||||
return type(all[s].text!, 25, hyper('sin', 'out'), true);
|
||||
});
|
||||
|
||||
/**
|
||||
* 选择一个道具时
|
||||
* @param id 道具id
|
||||
*/
|
||||
async function select(id: string, nouse: boolean = false) {
|
||||
async function select(id: ShowItemIds, nouse: boolean = false) {
|
||||
if (selected.value === id && !nouse) {
|
||||
use(id);
|
||||
}
|
||||
@@ -164,7 +169,8 @@ function exit() {
|
||||
core.plugin.toolOpened.value = false;
|
||||
}
|
||||
|
||||
async function use(id: string) {
|
||||
async function use(id: ShowItemIds) {
|
||||
if (id === 'none') return;
|
||||
if (core.canUseItem(id)) {
|
||||
// 应该暂时把动画去掉
|
||||
core.plugin.transition.value = false;
|
||||
|
||||
Reference in new issue
Block a user