2023-01-16 22:32:04 +08:00
|
|
|
|
<template>
|
|
|
|
|
<div id="shop">
|
|
|
|
|
<div id="tools">
|
|
|
|
|
<span class="button-text" @click="exit"
|
|
|
|
|
><left-outlined /> 返回游戏</span
|
|
|
|
|
>
|
|
|
|
|
</div>
|
|
|
|
|
<span id="item-name">{{ info.name }}</span>
|
|
|
|
|
<a-divider dashed style="border-color: #ddd4" id="divider"></a-divider>
|
|
|
|
|
<div id="item-info">
|
|
|
|
|
<Scroll id="item-desc" :no-scroll="true">
|
|
|
|
|
<span v-html="desc"></span>
|
|
|
|
|
</Scroll>
|
|
|
|
|
</div>
|
|
|
|
|
<a-divider
|
|
|
|
|
dashed
|
|
|
|
|
style="border-color: #ddd4"
|
|
|
|
|
id="divider-split"
|
|
|
|
|
></a-divider>
|
|
|
|
|
<div id="shop-bottom">
|
|
|
|
|
<div id="item-list">
|
|
|
|
|
<Scroll style="width: 100%; height: 100%">
|
|
|
|
|
<div
|
|
|
|
|
class="selectable item-one"
|
|
|
|
|
v-for="(i, index) of choices"
|
|
|
|
|
:selected="index === selected"
|
|
|
|
|
@click="selected = index"
|
|
|
|
|
>
|
|
|
|
|
<div class="item-icon">
|
|
|
|
|
<BoxAnimate
|
|
|
|
|
:id="i.id"
|
|
|
|
|
:noborder="true"
|
|
|
|
|
></BoxAnimate>
|
|
|
|
|
<span>{{ all[i.id].name }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
<span
|
|
|
|
|
>× {{
|
|
|
|
|
(mode === 'buy'
|
|
|
|
|
? i.number - (f.itemShop[id]?.[i.id] ?? 0)
|
|
|
|
|
: cnt(i.id)) + (update ? 0 : 0)
|
|
|
|
|
}}</span
|
|
|
|
|
>
|
|
|
|
|
</div>
|
|
|
|
|
</Scroll>
|
|
|
|
|
</div>
|
|
|
|
|
<a-divider
|
|
|
|
|
dashed
|
|
|
|
|
style="border-color: #ddd4"
|
2023-04-29 09:49:37 +08:00
|
|
|
|
type="vertical"
|
2023-01-16 22:32:04 +08:00
|
|
|
|
id="divider-vertical"
|
|
|
|
|
></a-divider>
|
|
|
|
|
<div id="item-sell-info">
|
|
|
|
|
<div id="shop-mode">
|
|
|
|
|
<span
|
|
|
|
|
class="button-text mode-button"
|
|
|
|
|
:active="mode === 'buy'"
|
|
|
|
|
@click="mode = 'buy'"
|
|
|
|
|
>购买</span
|
|
|
|
|
>
|
|
|
|
|
<a-divider
|
|
|
|
|
dashed
|
|
|
|
|
type="vertical"
|
|
|
|
|
id="divider-vertical"
|
|
|
|
|
style="border-color: #ddd4"
|
|
|
|
|
></a-divider>
|
|
|
|
|
<span
|
|
|
|
|
class="button-text mode-button"
|
|
|
|
|
:active="mode === 'sell'"
|
|
|
|
|
danger="true"
|
|
|
|
|
@click="mode = 'sell'"
|
|
|
|
|
>售出</span
|
|
|
|
|
>
|
|
|
|
|
</div>
|
|
|
|
|
<a-divider
|
|
|
|
|
dashed
|
|
|
|
|
style="border-color: #ddd4"
|
|
|
|
|
id="divider-mode"
|
|
|
|
|
></a-divider>
|
|
|
|
|
<div
|
|
|
|
|
class="item-sell-info"
|
2023-02-24 15:10:33 +08:00
|
|
|
|
:style="{
|
|
|
|
|
color:
|
|
|
|
|
mode === 'buy'
|
|
|
|
|
? nowMoney >= parseInt(item.money)
|
|
|
|
|
? 'lightgreen'
|
|
|
|
|
: 'lightcoral'
|
|
|
|
|
: 'white'
|
|
|
|
|
}"
|
2023-01-16 22:32:04 +08:00
|
|
|
|
>
|
|
|
|
|
<span>买价</span>
|
|
|
|
|
<span>{{ item.money }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div
|
|
|
|
|
class="item-sell-info"
|
|
|
|
|
:style="{ color: mode === 'sell' ? 'lightcoral' : 'white' }"
|
|
|
|
|
>
|
|
|
|
|
<span>卖价</span>
|
|
|
|
|
<span>{{ item.sell }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="item-sell-info">
|
|
|
|
|
<span>存货</span>
|
|
|
|
|
<span>{{ remain }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="item-sell-info">
|
|
|
|
|
<span>拥有</span>
|
|
|
|
|
<span>{{ cnt(item.id) }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
<a-divider
|
|
|
|
|
dashed
|
|
|
|
|
style="border-color: #ddd4"
|
|
|
|
|
id="divider-mode"
|
|
|
|
|
></a-divider>
|
|
|
|
|
<div id="sell-count">
|
|
|
|
|
<span>{{ mode === 'buy' ? '购买' : '售出' }}数量</span>
|
|
|
|
|
<div id="sell-count-select">
|
|
|
|
|
<double-left-outlined
|
|
|
|
|
class="button-text"
|
|
|
|
|
@click="count -= 10"
|
|
|
|
|
/>
|
|
|
|
|
<left-outlined class="button-text" @click="count--" />
|
|
|
|
|
<span id="fly-now">{{ count }}</span>
|
|
|
|
|
<right-outlined class="button-text" @click="count++" />
|
|
|
|
|
<double-right-outlined
|
|
|
|
|
class="button-text"
|
|
|
|
|
@click="count += 10"
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<a-divider
|
|
|
|
|
dashed
|
|
|
|
|
style="border-color: #ddd4; margin: 2vh 0 2vh 0"
|
|
|
|
|
></a-divider>
|
|
|
|
|
<div id="sell-confirm">
|
|
|
|
|
<span
|
|
|
|
|
id="sell-total"
|
|
|
|
|
:style="{
|
|
|
|
|
color:
|
|
|
|
|
mode === 'buy'
|
|
|
|
|
? nowMoney > cost
|
|
|
|
|
? 'lightgreen'
|
|
|
|
|
: 'lightcoral'
|
|
|
|
|
: 'lightcoral'
|
|
|
|
|
}"
|
|
|
|
|
>总价:{{
|
|
|
|
|
count *
|
|
|
|
|
parseInt(mode === 'buy' ? item.money : item.sell)
|
|
|
|
|
}}</span
|
|
|
|
|
>
|
|
|
|
|
<span
|
|
|
|
|
id="sell-button"
|
|
|
|
|
class="button-text"
|
|
|
|
|
:danger="mode === 'sell'"
|
|
|
|
|
danger-display="true"
|
|
|
|
|
active="true"
|
|
|
|
|
@click="confirm"
|
|
|
|
|
>确认{{ mode === 'buy' ? '购买' : '售出' }}</span
|
|
|
|
|
>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script lang="ts" setup>
|
|
|
|
|
import { computed, onMounted, onUnmounted, ref, watch } from 'vue';
|
|
|
|
|
import {
|
|
|
|
|
LeftOutlined,
|
|
|
|
|
DoubleLeftOutlined,
|
|
|
|
|
RightOutlined,
|
|
|
|
|
DoubleRightOutlined
|
|
|
|
|
} from '@ant-design/icons-vue';
|
|
|
|
|
import { keycode, splitText, tip } from '../plugin/utils';
|
|
|
|
|
import Scroll from '../components/scroll.vue';
|
|
|
|
|
import { isMobile } from '../plugin/use';
|
|
|
|
|
import BoxAnimate from '../components/boxAnimate.vue';
|
|
|
|
|
import { KeyCode } from '../plugin/keyCodes';
|
|
|
|
|
import { sleep } from 'mutate-animate';
|
|
|
|
|
|
|
|
|
|
const id = core.plugin.openedShopId;
|
|
|
|
|
const shop = core.status.shops[core.plugin.openedShopId] as ItemShopEvent;
|
|
|
|
|
if (!shop.item) {
|
|
|
|
|
throw new TypeError(
|
|
|
|
|
`Wrong global shop type delivered in opening item shop.`
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
flags.itemShop ??= {};
|
|
|
|
|
|
|
|
|
|
const f = flags;
|
|
|
|
|
|
|
|
|
|
const choices = shop.choices;
|
|
|
|
|
const selected = ref(0);
|
|
|
|
|
const mode = ref<'sell' | 'buy'>('buy');
|
|
|
|
|
const all = core.material.items;
|
|
|
|
|
const cnt = core.itemCount;
|
|
|
|
|
const count = ref(0);
|
|
|
|
|
const nowMoney = ref(core.status.hero.money);
|
|
|
|
|
const update = ref(false);
|
|
|
|
|
|
|
|
|
|
let bought = false;
|
|
|
|
|
|
|
|
|
|
watch(count, n => {
|
|
|
|
|
if (n < 0) n = 0;
|
|
|
|
|
if (mode.value === 'buy') {
|
|
|
|
|
if (n > remain.value) n = remain.value;
|
|
|
|
|
} else {
|
|
|
|
|
const c = cnt(item.value.id);
|
|
|
|
|
if (n > c) n = c;
|
|
|
|
|
}
|
|
|
|
|
count.value = n;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const item = computed(() => {
|
|
|
|
|
return choices[selected.value];
|
|
|
|
|
});
|
|
|
|
|
const remain = computed(() => {
|
|
|
|
|
update.value;
|
|
|
|
|
return item.value.number - (flags.itemShop[id]?.[item.value.id] ?? 0);
|
|
|
|
|
});
|
|
|
|
|
const info = computed(() => {
|
|
|
|
|
return core.material.items[item.value.id];
|
|
|
|
|
});
|
|
|
|
|
const desc = computed(() => {
|
|
|
|
|
const text = info.value.text!;
|
|
|
|
|
const res = splitText([text.startsWith('!!html') ? text.slice(6) : text]);
|
|
|
|
|
return res;
|
|
|
|
|
});
|
|
|
|
|
const cost = computed(() => {
|
|
|
|
|
return (
|
|
|
|
|
count.value *
|
|
|
|
|
parseInt(mode.value === 'buy' ? item.value.money : item.value.sell)
|
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
watch(remain, n => {
|
|
|
|
|
if (n < count.value) {
|
|
|
|
|
count.value = n;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
function confirm() {
|
2023-02-24 15:10:33 +08:00
|
|
|
|
if (count.value === 0) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2023-01-16 22:32:04 +08:00
|
|
|
|
const money = core.status.hero.money;
|
|
|
|
|
bought = true;
|
|
|
|
|
if (mode.value === 'buy') {
|
|
|
|
|
if (cost.value <= money) {
|
|
|
|
|
core.getItem(item.value.id, count.value);
|
|
|
|
|
core.status.hero.money -= cost.value;
|
|
|
|
|
nowMoney.value -= cost.value;
|
|
|
|
|
flags.itemShop[id] ??= {};
|
|
|
|
|
flags.itemShop[id][item.value.id] ??= 0;
|
|
|
|
|
flags.itemShop[id][item.value.id] += count.value;
|
|
|
|
|
tip('success', `成功购买${count.value}个${info.value.name}!`);
|
|
|
|
|
core.status.route.push(`buy:${item.value.id}:${count.value}`);
|
|
|
|
|
} else {
|
|
|
|
|
tip('error', '你的金币不够!');
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
core.addItem(item.value.id, -count.value);
|
|
|
|
|
core.status.hero.money += cost.value;
|
|
|
|
|
nowMoney.value += cost.value;
|
|
|
|
|
flags.itemShop[id] ??= {};
|
|
|
|
|
flags.itemShop[id][item.value.id] ??= 0;
|
|
|
|
|
flags.itemShop[id][item.value.id] -= count.value;
|
|
|
|
|
tip('success', `成功卖出${count.value}个${info.value.name}!`);
|
|
|
|
|
core.status.route.push(`sell:${item.value.id}:${count.value}`);
|
|
|
|
|
}
|
|
|
|
|
count.value = 0;
|
|
|
|
|
update.value = !update.value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function keyup(e: KeyboardEvent) {
|
|
|
|
|
const c = keycode(e.keyCode);
|
|
|
|
|
if (c === KeyCode.KeyX || c === KeyCode.Escape || c === KeyCode.KeyV) {
|
|
|
|
|
exit();
|
|
|
|
|
}
|
|
|
|
|
if (c === KeyCode.UpArrow) {
|
|
|
|
|
if (selected.value >= 1) {
|
|
|
|
|
selected.value--;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (c === KeyCode.DownArrow) {
|
|
|
|
|
if (selected.value <= choices.length - 2) {
|
|
|
|
|
selected.value++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (c === KeyCode.KeyC || c === KeyCode.Space || c === KeyCode.Enter) {
|
|
|
|
|
confirm();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function keydown(e: KeyboardEvent) {
|
|
|
|
|
const c = keycode(e.keyCode);
|
|
|
|
|
if (c === KeyCode.LeftArrow) {
|
|
|
|
|
count.value--;
|
|
|
|
|
}
|
|
|
|
|
if (c === KeyCode.RightArrow) {
|
|
|
|
|
count.value++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function exit() {
|
|
|
|
|
if (bought) core.status.route.push('closeShop');
|
|
|
|
|
core.plugin.shopOpened.value = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
onMounted(async () => {
|
|
|
|
|
await sleep(50);
|
|
|
|
|
if (core.plugin.transition.value) await sleep(600);
|
|
|
|
|
document.addEventListener('keyup', keyup);
|
|
|
|
|
document.addEventListener('keydown', keydown);
|
2023-04-24 17:27:36 +08:00
|
|
|
|
core.status.route.push(`openShop:${id}`);
|
2023-01-16 22:32:04 +08:00
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
onUnmounted(() => {
|
|
|
|
|
document.removeEventListener('keyup', keyup);
|
|
|
|
|
document.removeEventListener('keydown', keydown);
|
|
|
|
|
});
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<style lang="less" scoped>
|
|
|
|
|
#shop {
|
|
|
|
|
width: 90vh;
|
|
|
|
|
height: 90vh;
|
|
|
|
|
font-family: 'normal';
|
|
|
|
|
font-size: 2.8vh;
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
user-select: none;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#tools {
|
|
|
|
|
height: 5vh;
|
|
|
|
|
font-size: 3.2vh;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#item-name {
|
|
|
|
|
width: 100%;
|
|
|
|
|
text-align: center;
|
|
|
|
|
font-size: 4vh;
|
|
|
|
|
height: 5vh;
|
|
|
|
|
line-height: 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#item-info {
|
|
|
|
|
height: 24vh;
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#divider {
|
|
|
|
|
width: 100%;
|
|
|
|
|
margin: 1vh 0 1vh 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#divider-split {
|
|
|
|
|
margin: 1vh 0 0 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#divider-vertical {
|
|
|
|
|
height: 100%;
|
|
|
|
|
margin: 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#shop-bottom {
|
|
|
|
|
height: 53vh;
|
|
|
|
|
width: 100%;
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: row;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#item-list {
|
|
|
|
|
height: 53vh;
|
|
|
|
|
width: 53vh;
|
|
|
|
|
padding: 1vh 0 1vh 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#item-sell-info {
|
|
|
|
|
width: 47vh;
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
align-items: center;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.item-icon {
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: row;
|
|
|
|
|
align-items: center;
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
|
|
|
|
span {
|
|
|
|
|
margin-left: 5%;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.item-one {
|
|
|
|
|
display: flex;
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
flex-direction: row;
|
|
|
|
|
margin-bottom: 1vh;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#shop-mode {
|
|
|
|
|
width: 100%;
|
|
|
|
|
display: flex;
|
|
|
|
|
justify-content: space-around;
|
|
|
|
|
align-items: center;
|
|
|
|
|
height: 5vh;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.mode-button {
|
|
|
|
|
width: 100%;
|
|
|
|
|
text-align: center;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#divider-mode {
|
|
|
|
|
margin: 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.item-sell-info {
|
|
|
|
|
width: 60%;
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: row;
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
margin: 1vh 0 1vh 0;
|
|
|
|
|
transition: color 0.2s linear;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#sell-count {
|
|
|
|
|
width: 100%;
|
|
|
|
|
padding-top: 1vh;
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
align-items: center;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#sell-count-select {
|
|
|
|
|
margin-top: 1vh;
|
|
|
|
|
width: 90%;
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: row;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: space-around;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#sell-confirm {
|
|
|
|
|
width: 100%;
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: row;
|
|
|
|
|
justify-content: space-around;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#sell-total {
|
|
|
|
|
transition: color 0.2s linear;
|
|
|
|
|
}
|
2023-04-29 09:49:37 +08:00
|
|
|
|
|
|
|
|
|
@media screen and (max-width: 600px) {
|
|
|
|
|
#shop {
|
|
|
|
|
width: 90vw;
|
|
|
|
|
padding-top: 5vh;
|
|
|
|
|
font-size: 3.8vw;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#item-list {
|
|
|
|
|
width: 40vw;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#shop-bottom {
|
|
|
|
|
width: 90vw;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#item-sell-info {
|
|
|
|
|
width: 50vw;
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-01-16 22:32:04 +08:00
|
|
|
|
</style>
|