Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 53 additions & 30 deletions src/components/building/Base.vue
Original file line number Diff line number Diff line change
@@ -1,43 +1,66 @@
<script setup lang="ts">
defineProps<{
title: string
import type { ResidentCharacter } from '~/types'
import { storeToRefs } from 'pinia'
import { BUILDING_TYPE_NAME_MAPPING, type BuildingState, BuildingStateProvider } from '~/composables/buildings'
import { useAccountsStore } from '~/store/account'

const props = defineProps<{
level: number
color: string
type: BuildingState['type']
characters: ResidentCharacter[]
}>()

const { info } = storeToRefs(useAccountsStore())

const state = computed(() => {
const characters = toRaw(props.characters).map((resident) => {
const char = info.value!.chars.find(i => i.charId === resident.charId)
return {
...resident,
...char,
}
})
return {
type: props.type,
level: props.level,
characters,
} as BuildingState
})

const title = computed(() => BUILDING_TYPE_NAME_MAPPING[props.type])
</script>

<template>
<div flex="~ col gap-4px" w-full>
<div flex="~ items-center gap-10px" border="l-3" pl-6px :style="{ borderColor: color }">
<span>{{ title }}</span>
<div flex="inline items-center gap-1px">
<svg
v-for="i in level"
:key="i"
:style="{ color }" width="6" height="16" viewBox="0 0 6 16" fill="none" xmlns="http://www.w3.org/2000/svg"
>
<path d="M0 3V13L3 16L6 13V3L3 0L0 3Z" fill="currentColor" />
</svg>
</div>
</div>
<div
border="~ border" relative h-62px w-full
bg-background p="x-8px y-4px"
>
<div v-if="$slots.icon" absolute left-0 top-0 z-0>
<slot name="icon" />
</div>
<div flex="~ items-center" relative size-full>
<div v-if="$slots.info || $slots.extra" h-full w-72px flex="~ col justify-end gap-4px">
<slot name="info" />
<BuildingStateProvider :state="state">
<div flex="~ col gap-4px" w-full>
<div flex="~ items-center gap-10px" border="l-3" pl-6px :style="{ borderColor: color }">
<span>{{ title }}</span>
<div flex="inline items-center gap-1px">
<svg
v-for="i in level" :key="i" :style="{ color }" width="6" height="16" viewBox="0 0 6 16" fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M0 3V13L3 16L6 13V3L3 0L0 3Z" fill="currentColor" />
</svg>
</div>
<div v-if="$slots.extra" h-full flex-1>
<slot name="extra" />
</div>
<div border="~ border" relative h-62px w-full bg-background p="x-8px y-4px">
<div v-if="$slots.icon" absolute left-0 top-0 z-0>
<slot name="icon" />
</div>
<div flex="~ items-center gap-4px" ml-auto>
<slot />
<div flex="~ items-center" relative size-full>
<div v-if="$slots.info || $slots.extra" h-full w-72px flex="~ col justify-end gap-4px">
<slot name="info" />
</div>
<div v-if="$slots.extra" h-full flex-1>
<slot name="extra" />
</div>
<div flex="~ items-center gap-4px" ml-auto>
<slot />
</div>
</div>
</div>
</div>
</div>
</BuildingStateProvider>
</template>
7 changes: 6 additions & 1 deletion src/components/building/Control.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@ defineProps<{ data: BuildingControl }>()
</script>

<template>
<Base title="控制中枢" :level="data.level" color="white">
<Base
color="white"
type="control"
:level="data.level"
:characters="data.chars"
>
<template #icon>
<svg width="60" height="60" viewBox="0 0 60 60" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_502_1357)">
Expand Down
7 changes: 6 additions & 1 deletion src/components/building/Dormitory.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@ defineProps<{ data: BuildingDormitory }>()
</script>

<template>
<Base title="宿舍" :level="data.level" color="white">
<Base
color="white"
type="dormitory"
:level="data.level"
:characters="data.chars"
>
<template #icon>
<svg width="60" height="60" viewBox="0 0 60 60" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_502_976)">
Expand Down
7 changes: 6 additions & 1 deletion src/components/building/Hire.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@ defineProps<{ data: BuildingHire }>()
</script>

<template>
<Base title="人力办公室" :level="data.level" color="white">
<Base
color="white"
type="hire"
:level="data.level"
:characters="data.chars"
>
<template #icon>
<svg width="60" height="60" viewBox="0 0 60 60" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_502_960)">
Expand Down
7 changes: 6 additions & 1 deletion src/components/building/Manufacture.vue
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,12 @@ const currentWeight = computed(() => {
</script>

<template>
<Base title="制造站" :level="data.level" color="#FFD800">
<Base
color="#FFD800"
type="manufacture"
:level="data.level"
:characters="data.chars"
>
<template #icon>
<svg width="60" height="60" viewBox="0 0 60 60" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_502_882)">
Expand Down
7 changes: 6 additions & 1 deletion src/components/building/Meeting.vue
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,12 @@ function inClueBoard(index: number) {
</script>

<template>
<Base title="会客室" :level="data.level" color="white">
<Base
color="white"
type="meeting"
:level="data.level"
:characters="data.chars"
>
<template #icon>
<svg width="60" height="60" viewBox="0 0 60 60" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_502_927)">
Expand Down
7 changes: 6 additions & 1 deletion src/components/building/Power.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,12 @@ const power = computed(() => {
</script>

<template>
<Base title="发电站" :level="data.level" color="#d1eb64">
<Base
color="#d1eb64"
type="power"
:level="data.level"
:characters="data.chars"
>
<template #icon>
<svg width="60" height="60" viewBox="0 0 60 60" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_502_946)">
Expand Down
7 changes: 7 additions & 0 deletions src/components/building/ResidentCharacter.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import ApHigh from '~/assets/icons/ap-high.svg'
import ApLow from '~/assets/icons/ap-low.svg'
import StatusWorking from '~/assets/icons/status-working.svg'
import CharacterAvatar from '~/components/CharacterAvatar.vue'
import { useBuildingState } from '~/composables/buildings'
import { useAccountsStore } from '~/store/account'

const props = defineProps<{
Expand Down Expand Up @@ -37,6 +38,12 @@ const ApStatus = computed(() => {
}
return ApHigh
})
const buildingState = useBuildingState()

watch(buildingState, () => {
// eslint-disable-next-line no-console
console.log(buildingState.value)
}, { immediate: true })
</script>

<template>
Expand Down
7 changes: 6 additions & 1 deletion src/components/building/Trading.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@ defineProps<{ data: BuildingTrading }>()
</script>

<template>
<Base title="贸易站" :level="data.level" color="#5ab8f9">
<Base
color="#5ab8f9"
type="trading"
:level="data.level"
:characters="data.chars"
>
<template #icon>
<svg width="60" height="60" viewBox="0 0 60 60" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_502_914)">
Expand Down
7 changes: 6 additions & 1 deletion src/components/building/Training.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,12 @@ const chars = computed(() => {
</script>

<template>
<Base title="训练室" :level="data.level" color="white">
<Base
color="white"
type="training"
:level="data.level"
:characters="chars"
>
<template #icon>
<svg width="60" height="60" viewBox="0 0 60 60" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_502_989)">
Expand Down
7 changes: 7 additions & 0 deletions src/composables/buildings/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# 基建

## 思考

我们来讨论如何实现这个项目内依赖 Building 的一些过时数据,该如何实现显示游戏中的实时数据
首先我们有 @building.ts 提供的接口数据类型信息,其中building是有不同的分类的,其中大多数都会有进驻干员即 @ResidentCharacter 数组类型
对于不同的building类型,干员在其中消耗ap的速率不同,同时一栋building中进驻的干员也会影响ap消耗速率,所以我该怎么去实现计算干员ap消耗速率呢
49 changes: 49 additions & 0 deletions src/composables/buildings/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import type { Character, ResidentCharacter } from '~/types'
import { Fragment } from 'vue'

export { }

export const BUILDING_TYPE_NAME_MAPPING = {
control: '控制室',
dormitory: '宿舍',
hire: '人力办公室',
manufacture: '制造站',
meeting: '会客室',
power: '发电站',
trading: '贸易站',
training: '训练室',
}

export interface BuildingState {
type: keyof typeof BUILDING_TYPE_NAME_MAPPING
level: number
characters: (Character & ResidentCharacter)[]
}

const BuildingStateInjectKey = Symbol('BuildingInjectKey') as InjectionKey<ComputedRef<BuildingState>>

/**
* 用于消费对于注入的基建建筑数据的 composable
*/
export function useBuildingState() {
const ctx = inject(BuildingStateInjectKey, null)
if (!ctx)
throw new Error('BuildingState is not provided')
return ctx
}

export const BuildingStateProvider = defineComponent(
(props, { slots }) => {
const state = computed(() => props.state)
provide(BuildingStateInjectKey, state)
return () => h(Fragment, slots.default?.())
},
{
props: {
state: {
type: Object as PropType<BuildingState>,
required: true,
},
},
},
)