@@ -81,17 +99,14 @@ const injuredStat = (value: number, injury: number): number => Math.trunc((value
:aria-sort="ariaSort(header)"
>
{{ header.label }}
@@ -132,11 +147,30 @@ const injuredStat = (value: number, injury: number): number => Math.trunc((value
| {{ general.age }}세 |
- {{ general.personality.name }}
+
+ {{ general.personality.name }}
+
|
- {{ general.specialDomestic.name }} /
- {{ general.specialWar.name }}
+
+ {{ general.specialDomestic.name }}
+
+ /
+
+ {{ general.specialWar.name }}
+
|
Lv {{ general.experienceLevel }} |
{{ general.nationName }} |
@@ -144,22 +178,29 @@ const injuredStat = (value: number, injury: number): number => Math.trunc((value
{{ general.dedicationText }} |
{{ formatOfficerLevelText(general.officerLevel, general.nationLevel) }} |
- {{
- general.injury > 0 ? injuredStat(general.leadership, general.injury) : general.leadership
- }}+{{ general.leadershipBonus }}
+
|
- {{
- general.injury > 0 ? injuredStat(general.strength, general.injury) : general.strength
- }}
+
|
- {{
- general.injury > 0 ? injuredStat(general.intelligence, general.injury) : general.intelligence
- }}
+
|
{{ general.killturn }} |
{{ general.refreshScoreTotal }} 【{{ general.refreshText }}】 |
@@ -207,13 +248,33 @@ const injuredStat = (value: number, injury: number): number => Math.trunc((value
성격
- {{ general.personality.name }}
+
+ {{ general.personality.name }}
+
특기
- {{ general.specialDomestic.name }} / {{ general.specialWar.name }}
+
+
+ {{ general.specialDomestic.name }}
+
+ /
+
+ {{ general.specialWar.name }}
+
+
레벨Lv {{ general.experienceLevel }}
@@ -233,26 +294,31 @@ const injuredStat = (value: number, injury: number): number => Math.trunc((value
통솔
-
- {{
- general.injury > 0 ? injuredStat(general.leadership, general.injury) : general.leadership
- }}+{{ general.leadershipBonus }}
-
+
무력
- {{
- general.injury > 0 ? injuredStat(general.strength, general.injury) : general.strength
- }}
+
지력
- {{
- general.injury > 0 ? injuredStat(general.intelligence, general.injury) : general.intelligence
- }}
+
벌점
@@ -298,12 +364,6 @@ const injuredStat = (value: number, injury: number): number => Math.trunc((value
.center {
text-align: center;
}
-.wounded {
- color: red;
-}
-.leadership-bonus {
- color: cyan;
-}
.loading-cell {
height: 64px;
text-align: center;
diff --git a/app/game-frontend/src/components/ui/RichTooltip.vue b/app/game-frontend/src/components/ui/RichTooltip.vue
index d8818f14..96edc160 100644
--- a/app/game-frontend/src/components/ui/RichTooltip.vue
+++ b/app/game-frontend/src/components/ui/RichTooltip.vue
@@ -113,7 +113,7 @@ watch(
background: #101010;
box-shadow: 0 3px 12px rgb(0 0 0 / 65%);
color: #f5f5f5;
- font-family: Pretendard, sans-serif;
+ font-family: var(--sammo-font-sans);
font-size: 12.5px;
line-height: 1.45;
text-align: left;
diff --git a/app/game-frontend/src/utils/generalDirectorySort.ts b/app/game-frontend/src/utils/generalDirectorySort.ts
new file mode 100644
index 00000000..bcacbd5f
--- /dev/null
+++ b/app/game-frontend/src/utils/generalDirectorySort.ts
@@ -0,0 +1,100 @@
+export type GeneralDirectorySortKey = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15;
+export type GeneralDirectorySortDirection = 'ascending' | 'descending';
+
+export type GeneralDirectorySortCriterion = {
+ key: GeneralDirectorySortKey;
+ direction: GeneralDirectorySortDirection;
+};
+
+type TraitValue = { key: string };
+
+export type GeneralDirectorySortable = {
+ name: string;
+ nationId: number;
+ leadership: number;
+ strength: number;
+ intelligence: number;
+ experience: number;
+ dedication: number;
+ officerLevel: number;
+ killturn: number;
+ refreshScoreTotal: number;
+ personality: TraitValue;
+ specialDomestic: TraitValue;
+ specialWar: TraitValue;
+ age: number;
+ npcState: number;
+};
+
+const koreanNameCollator = new Intl.Collator('ko-KR', { numeric: true, sensitivity: 'base' });
+
+const compareString = (left: string, right: string): number => {
+ if (left === right) return 0;
+ return left < right ? -1 : 1;
+};
+
+const compareByKey = (left: T, right: T, key: GeneralDirectorySortKey): number => {
+ switch (key) {
+ case 0:
+ return koreanNameCollator.compare(left.name, right.name);
+ case 1:
+ return left.nationId - right.nationId;
+ case 2:
+ return left.leadership - right.leadership;
+ case 3:
+ return left.strength - right.strength;
+ case 4:
+ return left.intelligence - right.intelligence;
+ case 5:
+ case 10:
+ return left.experience - right.experience;
+ case 6:
+ return left.dedication - right.dedication;
+ case 7:
+ return left.officerLevel - right.officerLevel;
+ case 8:
+ return left.killturn - right.killturn;
+ case 9:
+ return left.refreshScoreTotal - right.refreshScoreTotal;
+ case 11:
+ return compareString(left.personality.key, right.personality.key);
+ case 12:
+ return compareString(left.specialDomestic.key, right.specialDomestic.key);
+ case 13:
+ return compareString(left.specialWar.key, right.specialWar.key);
+ case 14:
+ return left.age - right.age;
+ case 15:
+ return left.npcState - right.npcState;
+ }
+};
+
+export const advanceGeneralDirectorySort = (
+ current: readonly GeneralDirectorySortCriterion[],
+ key: GeneralDirectorySortKey
+): GeneralDirectorySortCriterion[] => {
+ const existing = current.find((criterion) => criterion.key === key);
+ const remaining = current.filter((criterion) => criterion.key !== key);
+
+ if (!existing) return [{ key, direction: 'descending' }, ...remaining];
+ if (existing.direction === 'descending') return [{ key, direction: 'ascending' }, ...remaining];
+ return remaining;
+};
+
+export const sortGeneralDirectory = (
+ source: readonly T[],
+ criteria: readonly GeneralDirectorySortCriterion[]
+): T[] => {
+ if (criteria.length === 0) return [...source];
+
+ return source
+ .map((general, originalIndex) => ({ general, originalIndex }))
+ .sort((left, right) => {
+ for (const criterion of criteria) {
+ const compared = compareByKey(left.general, right.general, criterion.key);
+ if (compared !== 0) return criterion.direction === 'ascending' ? compared : -compared;
+ }
+ return left.originalIndex - right.originalIndex;
+ })
+ .map(({ general }) => general);
+};
diff --git a/app/game-frontend/src/views/GeneralListView.vue b/app/game-frontend/src/views/GeneralListView.vue
index 9ba1e5fc..2e24f344 100644
--- a/app/game-frontend/src/views/GeneralListView.vue
+++ b/app/game-frontend/src/views/GeneralListView.vue
@@ -1,15 +1,21 @@