인게임 예약 명령과 장수 상태 표시를 바로잡음
This commit is contained in:
@@ -24,9 +24,9 @@ const crewTypes = computed(() => props.info.groups.flatMap((group) => group.valu
|
||||
const selectedCrewType = computed(
|
||||
() => crewTypes.value.find((crewType) => crewType.id === selectedCrewTypeId.value) ?? crewTypes.value[0] ?? null
|
||||
);
|
||||
const valid = computed(
|
||||
() => Boolean(selectedCrewType.value?.available) && Number.isFinite(amount.value) && amount.value >= 1
|
||||
);
|
||||
// 예약 시점에는 아직 조건을 충족하지 않는 병종도 선택할 수 있어야 한다.
|
||||
// 실제 실행 가능 여부는 턴 실행 시점의 기술/국가/장수 상태로 다시 판정한다.
|
||||
const valid = computed(() => Boolean(selectedCrewType.value) && Number.isFinite(amount.value) && amount.value >= 1);
|
||||
const estimatedGold = computed(() =>
|
||||
selectedCrewType.value ? Math.ceil(amount.value * selectedCrewType.value.baseCost * goldCoefficient.value) : 0
|
||||
);
|
||||
@@ -135,7 +135,7 @@ watch(
|
||||
type="button"
|
||||
class="crew-name"
|
||||
:class="availabilityClass(selectedCrewType)"
|
||||
:title="selectedCrewType.available ? '현재 선택 가능' : '현재 선택 불가'"
|
||||
:title="selectedCrewType.available ? '현재 실행 가능' : '현재 실행 불가 · 예약 가능'"
|
||||
>
|
||||
{{ selectedCrewType.name }}<small>{{ selectedCrewType.available ? '가능' : '불가' }}</small>
|
||||
</button>
|
||||
@@ -189,7 +189,7 @@ watch(
|
||||
:class="{ selected: crewType.id === selectedCrewTypeId }"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
:aria-label="`${crewType.name} ${crewType.available ? '선택 가능' : '선택 불가'}`"
|
||||
:aria-label="`${crewType.name} ${crewType.available ? '선택 가능' : '현재 실행 불가, 예약 가능'}`"
|
||||
@click="selectCrewType(crewType)"
|
||||
@keydown.enter="selectCrewType(crewType)"
|
||||
>
|
||||
@@ -256,7 +256,7 @@ watch(
|
||||
</label>
|
||||
</span>
|
||||
<span class="crew-action" @click.stop>
|
||||
<button type="button" :disabled="!crewType.available" @click="submit(crewType)">
|
||||
<button type="button" @click="submit(crewType)">
|
||||
{{ commandName }}
|
||||
</button>
|
||||
</span>
|
||||
|
||||
@@ -59,7 +59,6 @@ const numberText = (value: unknown, grouped = false): string => {
|
||||
};
|
||||
|
||||
const wrap = (value: string): string => `【${value}】`;
|
||||
const withParticle = (value: string, particle: '을' | '으로'): string => `${value}${JosaUtil.pick(value, particle)}`;
|
||||
const wrappedWithParticle = (value: string, particle: '을' | '으로'): string =>
|
||||
`${wrap(value)}${JosaUtil.pick(value, particle)}`;
|
||||
|
||||
@@ -134,7 +133,11 @@ export const formatReservedCommandBrief = (
|
||||
return `${wrap(generalName)}에게 ${args.isGold ? '금' : '쌀'} ${numberText(args.amount)}을 ${commandName}`;
|
||||
}
|
||||
if (action === 'che_징병' || action === 'che_모병') {
|
||||
const crewType = optionLabel(input?.crewTypes ?? [], args.crewType);
|
||||
const crewType =
|
||||
optionLabel(input?.crewTypes ?? [], args.crewType) ??
|
||||
input?.recruitment?.groups
|
||||
.flatMap((group) => group.values)
|
||||
.find((entry) => entry.id === args.crewType)?.name;
|
||||
if (crewType) return `${wrap(crewType)} ${numberText(args.amount)}명 ${commandName}`;
|
||||
}
|
||||
if (action === 'che_숙련전환') {
|
||||
@@ -146,7 +149,7 @@ export const formatReservedCommandBrief = (
|
||||
const itemType = typeof args.itemType === 'string' ? args.itemType : '';
|
||||
if (args.itemCode === 'None') {
|
||||
const itemTypeName = ITEM_TYPE_NAMES[itemType];
|
||||
if (itemTypeName) return `${withParticle(itemTypeName, '을')} 판매`;
|
||||
if (itemTypeName) return `${wrap(itemTypeName)}${JosaUtil.pick(itemTypeName, '을')} 판매.`;
|
||||
}
|
||||
const itemName = optionLabel(input?.items[itemType] ?? [], args.itemCode);
|
||||
if (itemName) {
|
||||
|
||||
@@ -53,6 +53,7 @@ export type CommandInputField = {
|
||||
required: boolean;
|
||||
min?: number;
|
||||
max?: number;
|
||||
legacyWidthMax?: number;
|
||||
step?: number;
|
||||
defaultValue?: string | number | boolean;
|
||||
constValue?: string | number;
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
} from '../command/commandArgumentDraft';
|
||||
import { legacyNationTextColor } from '../../utils/legacyNationColor';
|
||||
import { getNpcColor } from '../../utils/npcColor';
|
||||
import { getLegacyStringWidth } from '@sammo-ts/logic/troop/management.js';
|
||||
import type {
|
||||
CommandInputContext,
|
||||
CommandInputField,
|
||||
@@ -309,6 +310,14 @@ const setNumberPreset = (field: CommandInputField, rawValue: string, tupleIndex?
|
||||
const effectiveMin = (field: CommandInputField): number | undefined => amountPreset.value?.min ?? field.min;
|
||||
const effectiveMax = (field: CommandInputField): number | undefined => amountPreset.value?.max ?? field.max;
|
||||
const effectiveStep = (field: CommandInputField): number | undefined => amountPreset.value?.step ?? field.step;
|
||||
const textFieldError = (field: CommandInputField): string => {
|
||||
const value = values[field.key];
|
||||
if (field.kind !== 'text' || typeof value !== 'string') return '';
|
||||
if (field.legacyWidthMax !== undefined && getLegacyStringWidth(value.trim()) > field.legacyWidthMax) {
|
||||
return `${field.label}은 전각 ${Math.floor(field.legacyWidthMax / 2)}자 또는 반각 ${field.legacyWidthMax}자 이하여야 합니다.`;
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
const OPTION_CARD_COMMANDS = new Set([
|
||||
'che_물자원조',
|
||||
@@ -334,7 +343,8 @@ const isValid = computed(() =>
|
||||
return (
|
||||
(!field.required || length > 0) &&
|
||||
(field.min === undefined || length >= field.min) &&
|
||||
(field.max === undefined || length <= field.max)
|
||||
(field.max === undefined || length <= field.max) &&
|
||||
!textFieldError(field)
|
||||
);
|
||||
}
|
||||
if (field.kind === 'number') {
|
||||
@@ -429,8 +439,18 @@ watch(
|
||||
:value="String(values[field.key] ?? '')"
|
||||
:minlength="field.min"
|
||||
:maxlength="field.max"
|
||||
:aria-invalid="Boolean(textFieldError(field))"
|
||||
:aria-describedby="textFieldError(field) ? `command-arg-${field.key}-error` : undefined"
|
||||
@input="values[field.key] = ($event.target as HTMLInputElement).value"
|
||||
/>
|
||||
<small
|
||||
v-if="field.kind === 'text' && textFieldError(field)"
|
||||
:id="`command-arg-${field.key}-error`"
|
||||
class="argument-error"
|
||||
role="alert"
|
||||
>
|
||||
{{ textFieldError(field) }}
|
||||
</small>
|
||||
<div v-else-if="field.kind === 'number'" class="number-options">
|
||||
<input
|
||||
:id="`command-arg-${field.key}`"
|
||||
@@ -647,6 +667,12 @@ watch(
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.argument-error {
|
||||
grid-column: 2;
|
||||
margin: -2px 6px 5px 0;
|
||||
color: #ff9a9a;
|
||||
}
|
||||
|
||||
.option-detail {
|
||||
grid-column: 2;
|
||||
display: flex;
|
||||
|
||||
@@ -9,6 +9,7 @@ import { legacyExperiencePercent, ratioPercent } from '../../utils/legacyProgres
|
||||
import { DEFAULT_GENERAL_ICON_URL, resolveGeneralIconUrl, useDefaultGeneralIcon } from '../../utils/generalIcon';
|
||||
import { configuredGameAssetUrl } from '../../utils/imageAssets';
|
||||
import { legacyLuminanceTextColor } from '../../utils/legacyNationColor';
|
||||
import { generalInjuryPresentation } from '../../utils/generalInjury';
|
||||
|
||||
interface GeneralStats {
|
||||
leadership: number;
|
||||
@@ -175,14 +176,7 @@ const crewTypeIconBackground = computed(() => {
|
||||
return `url(${JSON.stringify(crewTypeUrl)}), url(${JSON.stringify(DEFAULT_GENERAL_ICON_URL)})`;
|
||||
});
|
||||
|
||||
const injuryInfo = computed(() => {
|
||||
const injury = props.general?.injury ?? 0;
|
||||
if (injury > 60) return { text: '위독', color: '#ff0000' };
|
||||
if (injury > 40) return { text: '심각', color: '#ff00ff' };
|
||||
if (injury > 20) return { text: '중상', color: '#ffa500' };
|
||||
if (injury > 0) return { text: '경상', color: '#ffff00' };
|
||||
return { text: '건강', color: '#ffffff' };
|
||||
});
|
||||
const injuryInfo = computed(() => generalInjuryPresentation(props.general?.injury ?? 0));
|
||||
|
||||
const titleStyle = computed(() => {
|
||||
const backgroundColor = props.nationColor || '#173d27';
|
||||
|
||||
@@ -55,6 +55,7 @@ const destination = computed<MessageTarget>(
|
||||
);
|
||||
|
||||
const invalid = computed(() => props.message.option?.invalid === true);
|
||||
const permissionRedacted = computed(() => props.message.option?.permissionRedacted === true);
|
||||
const hasAction = computed(() => typeof props.message.option?.action === 'string');
|
||||
const nationDirection = computed(() => {
|
||||
if (props.message.src.nationId === destination.value.nationId) {
|
||||
@@ -134,7 +135,12 @@ onBeforeUnmount(() => {
|
||||
<template>
|
||||
<article
|
||||
:id="`msg_${message.id}`"
|
||||
:class="['msg-plate', `msg-plate-${message.msgType}`, `msg-plate-${nationDirection}`]"
|
||||
:class="[
|
||||
'msg-plate',
|
||||
`msg-plate-${message.msgType}`,
|
||||
`msg-plate-${nationDirection}`,
|
||||
{ 'msg-plate-permission-redacted': permissionRedacted },
|
||||
]"
|
||||
:data-id="message.id"
|
||||
>
|
||||
<div class="msg-icon">
|
||||
@@ -262,7 +268,13 @@ onBeforeUnmount(() => {
|
||||
<span class="msg-time"><{{ message.time }}></span>
|
||||
</div>
|
||||
|
||||
<div :class="['msg-content', invalid ? 'msg-invalid' : 'msg-valid']">
|
||||
<div
|
||||
:class="[
|
||||
'msg-content',
|
||||
invalid ? 'msg-invalid' : permissionRedacted ? 'msg-permission-redacted' : 'msg-valid',
|
||||
]"
|
||||
>
|
||||
<strong v-if="permissionRedacted" class="permission-redacted-label">권한 제한</strong>
|
||||
{{ invalid ? '삭제된 메시지입니다' : message.text }}
|
||||
</div>
|
||||
|
||||
@@ -411,6 +423,30 @@ button.msg-target {
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
|
||||
.msg-plate-permission-redacted {
|
||||
outline: 1px dashed #d7b86c;
|
||||
background: #3b3427;
|
||||
}
|
||||
|
||||
.msg-plate-permission-redacted .general-icon {
|
||||
filter: grayscale(1);
|
||||
opacity: 0.55;
|
||||
}
|
||||
|
||||
.msg-permission-redacted {
|
||||
color: rgba(255, 244, 214, 0.72);
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.permission-redacted-label {
|
||||
display: inline-block;
|
||||
margin-right: 6px;
|
||||
border: 1px solid #d7b86c;
|
||||
padding: 1px 4px;
|
||||
color: #ffe0a0;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
.message-response {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
export type GeneralInjuryPresentation = { text: string; color: string };
|
||||
|
||||
export const generalInjuryPresentation = (injury: number): GeneralInjuryPresentation => {
|
||||
if (injury > 60) return { text: '위독', color: '#ff0000' };
|
||||
if (injury > 40) return { text: '심각', color: '#ff00ff' };
|
||||
if (injury > 20) return { text: '중상', color: '#ffa500' };
|
||||
if (injury > 0) return { text: '경상', color: '#ffff00' };
|
||||
return { text: '건강', color: '#ffffff' };
|
||||
};
|
||||
@@ -1052,7 +1052,13 @@ onUnmounted(() => {
|
||||
</div>
|
||||
<form class="npc-card-holder" @submit.prevent>
|
||||
<div v-for="npc in npcCandidates" :key="npc.id" class="npc-card">
|
||||
<h4 class="npc-card-name">{{ npc.name }}</h4>
|
||||
<h4
|
||||
class="npc-card-name"
|
||||
:class="{ 'npc-card-name--long': npc.name.length >= 9 }"
|
||||
:title="npc.name"
|
||||
>
|
||||
{{ npc.name }}
|
||||
</h4>
|
||||
<h4>
|
||||
<img
|
||||
class="npc-card-image"
|
||||
@@ -1723,10 +1729,18 @@ onUnmounted(() => {
|
||||
}
|
||||
|
||||
.npc-card-name {
|
||||
min-height: 25px;
|
||||
box-sizing: border-box;
|
||||
height: 25px;
|
||||
overflow: hidden;
|
||||
border: 1px solid rgba(201, 164, 90, 0.3);
|
||||
font-size: 1rem;
|
||||
line-height: 23px;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.npc-card-name--long {
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
|
||||
.npc-card-image {
|
||||
|
||||
@@ -8,7 +8,7 @@ import PanelCard from '../components/ui/PanelCard.vue';
|
||||
import SkeletonLines from '../components/ui/SkeletonLines.vue';
|
||||
import MapViewer from '../components/main/MapViewer.vue';
|
||||
import CommandListPanel from '../components/main/CommandListPanel.vue';
|
||||
import GeneralBasicCard from '../components/main/GeneralBasicCard.vue';
|
||||
import GeneralInformationPanel from '../components/main/GeneralInformationPanel.vue';
|
||||
import CityBasicCard from '../components/main/CityBasicCard.vue';
|
||||
import NationBasicCard from '../components/main/NationBasicCard.vue';
|
||||
import MessagePanel from '../components/main/MessagePanel.vue';
|
||||
@@ -100,6 +100,43 @@ const nationAccess = computed(() => ({
|
||||
nationLevel: nation.value?.level ?? 0,
|
||||
}));
|
||||
const nationColor = computed(() => nation.value?.color ?? '#000000');
|
||||
const generalPanel = computed(() => {
|
||||
const current = general.value;
|
||||
if (!current) return null;
|
||||
return {
|
||||
...current,
|
||||
progression: {
|
||||
experienceLevel: current.progression?.experienceLevel ?? 0,
|
||||
dedicationLevel: current.progression?.dedicationLevel ?? 0,
|
||||
dedicationText: current.progression?.dedicationText ?? '-',
|
||||
statExperience: current.progression?.statExperience ?? {
|
||||
leadership: 0,
|
||||
strength: 0,
|
||||
intelligence: 0,
|
||||
},
|
||||
statUpgradeLimit: current.progression?.statUpgradeLimit ?? 30,
|
||||
dex: current.progression?.dex ?? [0, 0, 0, 0, 0],
|
||||
},
|
||||
};
|
||||
});
|
||||
const generalSummary = computed(() =>
|
||||
general.value
|
||||
? {
|
||||
available: true,
|
||||
experience: general.value.experience,
|
||||
dedicationText: general.value.progression?.dedicationText,
|
||||
bill: general.value.bill,
|
||||
warnum: general.value.records?.battles,
|
||||
wins: general.value.records?.wins,
|
||||
losses: general.value.records?.losses,
|
||||
strategies: general.value.records?.strategies,
|
||||
serviceYears: general.value.records?.serviceYears,
|
||||
killCrew: general.value.records?.killedCrew,
|
||||
deathCrew: general.value.records?.lostCrew,
|
||||
recentWar: general.value.recentWar,
|
||||
}
|
||||
: null
|
||||
);
|
||||
const voteActive = computed(() => Boolean(frontStatus.value?.latestVote));
|
||||
const profileLabels: Record<string, string> = {
|
||||
che: '체',
|
||||
@@ -183,10 +220,7 @@ const shiftGeneralTurns = (amount: number) => {
|
||||
void dashboard.shiftGeneralTurns(amount);
|
||||
};
|
||||
|
||||
const reserveGeneralTurns = async (
|
||||
entries: CommandPatternEntry[],
|
||||
complete?: (success: boolean) => void
|
||||
) => {
|
||||
const reserveGeneralTurns = async (entries: CommandPatternEntry[], complete?: (success: boolean) => void) => {
|
||||
const success = await dashboard.setGeneralTurns(entries);
|
||||
complete?.(success);
|
||||
};
|
||||
@@ -322,7 +356,7 @@ watch(
|
||||
:command-table="commandTable"
|
||||
:loading="loading"
|
||||
:reserved-general-turns="reservedGeneralTurns"
|
||||
:general="general"
|
||||
:general="generalPanel"
|
||||
:current-year="lobbyInfo?.year"
|
||||
:current-month="lobbyInfo?.month"
|
||||
:turn-term-minutes="lobbyInfo?.turnTerm"
|
||||
@@ -371,7 +405,12 @@ watch(
|
||||
data-mobile-panel-id="general"
|
||||
>
|
||||
<PanelCard title="장수 스탯" hide-header aria-label="장수 정보" data-main-target="general">
|
||||
<GeneralBasicCard :general="general" :loading="loading" :nation-color="nation?.color" />
|
||||
<GeneralInformationPanel
|
||||
:general="generalPanel"
|
||||
:summary="generalSummary"
|
||||
:loading="loading"
|
||||
:nation-color="nation?.color"
|
||||
/>
|
||||
</PanelCard>
|
||||
</div>
|
||||
|
||||
@@ -498,7 +537,7 @@ watch(
|
||||
:command-table="commandTable"
|
||||
:loading="loading"
|
||||
:reserved-general-turns="reservedGeneralTurns"
|
||||
:general="general"
|
||||
:general="generalPanel"
|
||||
:current-year="lobbyInfo?.year"
|
||||
:current-month="lobbyInfo?.month"
|
||||
:turn-term-minutes="lobbyInfo?.turnTerm"
|
||||
@@ -528,7 +567,12 @@ watch(
|
||||
<NationBasicCard :nation="nation" :loading="loading" />
|
||||
</PanelCard>
|
||||
<PanelCard title="장수 스탯" hide-header aria-label="장수 정보" data-main-target="general">
|
||||
<GeneralBasicCard :general="general" :loading="loading" :nation-color="nation?.color" />
|
||||
<GeneralInformationPanel
|
||||
:general="generalPanel"
|
||||
:summary="generalSummary"
|
||||
:loading="loading"
|
||||
:nation-color="nation?.color"
|
||||
/>
|
||||
</PanelCard>
|
||||
<MainNationMenu
|
||||
class="nation-menu-middle"
|
||||
|
||||
@@ -4,7 +4,9 @@ import { computed, onMounted, ref } from 'vue';
|
||||
import { formatReservedCommandBrief } from '../components/command/reservedCommandBrief';
|
||||
import type { CommandTable } from '../components/command/types';
|
||||
import LegacySortControls from '../components/ui/LegacySortControls.vue';
|
||||
import DirectoryTooltip from '../components/directory/DirectoryTooltip.vue';
|
||||
import { getNpcColor } from '../utils/npcColor';
|
||||
import { generalInjuryPresentation } from '../utils/generalInjury';
|
||||
import { trpc } from '../utils/trpc';
|
||||
type Result = Awaited<ReturnType<typeof trpc.nation.getSecretGeneralList.query>>;
|
||||
type ReservedCommand = Result['generals'][number]['reservedCommands'][number];
|
||||
@@ -48,6 +50,18 @@ const generals = computed(() =>
|
||||
const closeWindow = () => window.close();
|
||||
const displayName = (general: { name: string; npcState: number }) =>
|
||||
general.npcState > 0 && !/^[ⓜⓝ㉥]/u.test(general.name) ? `ⓝ${general.name}` : general.name;
|
||||
const injuryInfo = (injury: number) => generalInjuryPresentation(injury);
|
||||
const injuryDescription = (general: Result['generals'][number]): string =>
|
||||
general.injury > 0 ? `부상 ${general.injury}% · ${injuryInfo(general.injury).text}` : '';
|
||||
const statInjuryDescription = (
|
||||
general: Result['generals'][number],
|
||||
label: string,
|
||||
original: number,
|
||||
effective: number
|
||||
): string =>
|
||||
general.injury > 0
|
||||
? `부상 ${general.injury}% · ${injuryInfo(general.injury).text} · 원래 ${label} ${original} → 적용 ${effective}`
|
||||
: '';
|
||||
const commandBrief = (command: ReservedCommand): string =>
|
||||
formatReservedCommandBrief('general', command.action, command.args, commandTable.value);
|
||||
const updateSelectedSort = (value: number): void => {
|
||||
@@ -229,15 +243,72 @@ onMounted(load);
|
||||
:data-npc-state="general.npcState"
|
||||
>
|
||||
<td>
|
||||
<span data-general-name :style="{ color: getNpcColor(general.npcState) }">{{
|
||||
displayName(general)
|
||||
}}</span
|
||||
<DirectoryTooltip
|
||||
:title="`부상 · ${injuryInfo(general.injury).text}`"
|
||||
:description="injuryDescription(general)"
|
||||
:test-id="`secret-injury-name-${general.id}`"
|
||||
>
|
||||
<span
|
||||
data-general-name
|
||||
:style="{
|
||||
color:
|
||||
general.injury > 0
|
||||
? injuryInfo(general.injury).color
|
||||
: getNpcColor(general.npcState),
|
||||
}"
|
||||
>{{ displayName(general) }}</span
|
||||
> </DirectoryTooltip
|
||||
><br />Lv {{ general.experienceLevel }}
|
||||
</td>
|
||||
<td>
|
||||
{{ general.stats.leadership
|
||||
}}<span v-if="general.leadershipBonus" class="bonus">+{{ general.leadershipBonus }}</span
|
||||
>∥{{ general.stats.strength }}∥{{ general.stats.intelligence }}
|
||||
<DirectoryTooltip
|
||||
title="통솔 부상"
|
||||
:description="
|
||||
statInjuryDescription(
|
||||
general,
|
||||
'통솔',
|
||||
general.baseStats.leadership,
|
||||
general.stats.leadership
|
||||
)
|
||||
"
|
||||
:test-id="`secret-injury-leadership-${general.id}`"
|
||||
>
|
||||
<span :style="{ color: injuryInfo(general.injury).color }">{{
|
||||
general.stats.leadership
|
||||
}}</span
|
||||
><span v-if="general.leadershipBonus" class="bonus"
|
||||
>+{{ general.leadershipBonus }}</span
|
||||
>
|
||||
</DirectoryTooltip>
|
||||
∥<DirectoryTooltip
|
||||
title="무력 부상"
|
||||
:description="
|
||||
statInjuryDescription(
|
||||
general,
|
||||
'무력',
|
||||
general.baseStats.strength,
|
||||
general.stats.strength
|
||||
)
|
||||
"
|
||||
:test-id="`secret-injury-strength-${general.id}`"
|
||||
><span :style="{ color: injuryInfo(general.injury).color }">{{
|
||||
general.stats.strength
|
||||
}}</span></DirectoryTooltip
|
||||
>∥<DirectoryTooltip
|
||||
title="지력 부상"
|
||||
:description="
|
||||
statInjuryDescription(
|
||||
general,
|
||||
'지력',
|
||||
general.baseStats.intelligence,
|
||||
general.stats.intelligence
|
||||
)
|
||||
"
|
||||
:test-id="`secret-injury-intelligence-${general.id}`"
|
||||
><span :style="{ color: injuryInfo(general.injury).color }">{{
|
||||
general.stats.intelligence
|
||||
}}</span></DirectoryTooltip
|
||||
>
|
||||
</td>
|
||||
<td>{{ general.troopName ?? '-' }}</td>
|
||||
<td>{{ general.gold }}</td>
|
||||
|
||||
Reference in New Issue
Block a user