diff --git a/messages/cn.json b/messages/cn.json index 9d41bd8..7c6d4ef 100644 --- a/messages/cn.json +++ b/messages/cn.json @@ -59,7 +59,7 @@ "knight": "存护", "mage": "智识", "priest": "丰饶", - "rouge": "巡猎", + "rogue": "巡猎", "shaman": "同协", "warlock": "虚无", "memory": "记忆", diff --git a/messages/en.json b/messages/en.json index ebabbd3..ef7c04b 100644 --- a/messages/en.json +++ b/messages/en.json @@ -59,7 +59,7 @@ "knight": "Preservation", "mage": "Erudition", "priest": "Abundance", - "rouge": "The Hunt", + "rogue": "The Hunt", "shaman": "Harmony", "warlock": "Nihility", "memory": "Remembrance", diff --git a/messages/ja.json b/messages/ja.json index 6dbabd6..005d6fd 100644 --- a/messages/ja.json +++ b/messages/ja.json @@ -59,7 +59,7 @@ "knight": "存護", "mage": "知恵", "priest": "豊穣", - "rouge": "巡狩", + "rogue": "巡狩", "shaman": "調和", "warlock": "虚無", "memory": "記憶", diff --git a/messages/ko.json b/messages/ko.json index 173b486..e5c3efa 100644 --- a/messages/ko.json +++ b/messages/ko.json @@ -59,7 +59,7 @@ "knight": "보존", "mage": "지혜", "priest": "풍요", - "rouge": "사냥", + "rogue": "사냥", "shaman": "조화", "warlock": "허무", "memory": "기억", diff --git a/messages/vi.json b/messages/vi.json index df0049d..8b158fa 100644 --- a/messages/vi.json +++ b/messages/vi.json @@ -13,7 +13,7 @@ "actionValue": "Giá trị hành động", "character": "Nhân vật", "id": "ID", - "path": "Đường dẫn", + "path": "Vận mệnh", "rarity": "Số sao", "element": "Nguyên tố", "totalTurn": "Tổng lượt", @@ -59,7 +59,7 @@ "knight": "Bảo Hộ", "mage": "Tri Thức", "priest": "Phong Phú", - "rouge": "Săn Bắn", + "rogue": "Săn Bắn", "shaman": "Hài Hòa", "warlock": "Hư Vô", "memory": "Ký Ức", diff --git a/messages/zh.json b/messages/zh.json index 9d41bd8..7c6d4ef 100644 --- a/messages/zh.json +++ b/messages/zh.json @@ -59,7 +59,7 @@ "knight": "存护", "mage": "智识", "priest": "丰饶", - "rouge": "巡猎", + "rogue": "巡猎", "shaman": "同协", "warlock": "虚无", "memory": "记忆", diff --git a/src/app/page.tsx b/src/app/page.tsx index 5b3769c..4e71dfd 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -10,6 +10,7 @@ import DamagePerAvatarForAll from "@/components/chart/damagePerAvatarForAll"; import MultiCharLineChart from "@/components/chart/damageLineForAll"; import DamagePerCycleForAll from "@/components/chart/damagePerCycleForAll"; import DamagePercentChartForAll from "@/components/chart/damagePercentForAll"; +import EnemyBar from "@/components/enemybar"; export default function Home() { const transI18n = useTranslations("DataAnalysisPage"); @@ -18,7 +19,8 @@ export default function Home() { totalAV, totalDamage, damagePerAV, - turnHistory + turnHistory, + enemyDetail } = useBattleDataStore(); const [expandedCharts, setExpandedCharts] = useState([]); @@ -55,22 +57,22 @@ export default function Home() {
{transI18n("totalDamage")} -
{Number(totalDamage).toFixed(2)}
+
{Number(totalDamage).toLocaleString(undefined, { minimumFractionDigits: 1, maximumFractionDigits: 1 })}
{transI18n("totalAV")} -
{Number(totalAV).toFixed(2)}
+
{Number(totalAV).toLocaleString(undefined, { minimumFractionDigits: 1, maximumFractionDigits: 1 })}
{transI18n("damagePerAV")} -
{Number(damagePerAV).toFixed(2)}
+
{Number(damagePerAV).toLocaleString(undefined, { minimumFractionDigits: 1, maximumFractionDigits: 1 })}
{transI18n("totalTurn")}
{turnHistory.filter(it => it.avatarId && it.avatarId != -1).length}
- + {enemyDetail && }
diff --git a/src/components/actionbar/index.tsx b/src/components/actionbar/index.tsx index 4240307..26e6f3d 100644 --- a/src/components/actionbar/index.tsx +++ b/src/components/actionbar/index.tsx @@ -140,7 +140,7 @@ export default function ActionBar() { {`${transI18n("useSkill")}: ${transI18n(attackTypeToString(turn.skillType).toLowerCase())}`}
- {`${transI18n("totalDamage")}: ${turn.totalDamage.toFixed(2)}`} + {`${transI18n("totalDamage")}: ${Number(turn.totalDamage).toLocaleString(undefined, { minimumFractionDigits: 1, maximumFractionDigits: 1 })}`}
@@ -234,11 +234,11 @@ export default function ActionBar() {

{transI18n("actionValue")}

-

{turnHistory[selectTurn?.turnBattleId].actionValue.toFixed(2)}

+

{Number(turnHistory[selectTurn?.turnBattleId].actionValue).toLocaleString(undefined, { minimumFractionDigits: 1, maximumFractionDigits: 1 })}

{transI18n("totalDamage")}

-

{selectTurn?.totalDamage.toFixed(2)}

+

{Number(selectTurn?.totalDamage).toLocaleString(undefined, { minimumFractionDigits: 1, maximumFractionDigits: 1 })}

@@ -252,7 +252,7 @@ export default function ActionBar() { className="flex flex-col items-start gap-1 p-3 rounded-lg shadow bg-base-200" > - {detail.damage.toFixed(2)} + {Number(detail.damage).toLocaleString(undefined, { minimumFractionDigits: 1, maximumFractionDigits: 1 })} {transI18n(attackTypeToString(detail?.damage_type).toLowerCase())} diff --git a/src/components/card/characterCard.tsx b/src/components/card/characterCard.tsx index b2017c9..512cff1 100644 --- a/src/components/card/characterCard.tsx +++ b/src/components/card/characterCard.tsx @@ -4,6 +4,9 @@ import { getNameChar } from '@/helper'; import useLocaleStore from '@/stores/localeStore'; import { AvatarHakushiType } from '@/types'; import NameAvatar from '../nameAvatar'; +import useBattleDataStore from '@/stores/battleDataStore'; +import { useEffect, useMemo, useState } from 'react'; +import { AvatarInfo } from '@/types/mics'; interface CharacterCardProps { data: AvatarHakushiType @@ -14,12 +17,14 @@ interface CharacterCardProps { export default function CharacterCard({ data }: CharacterCardProps) { const { locale } = useLocaleStore(); const text = getNameChar(locale, data) + const { avatarDetail } = useBattleDataStore() + return (
  • @@ -50,6 +55,36 @@ export default function CharacterCard({ data }: CharacterCardProps) { text={text} className="mt-2 text-center text-base font-normal leading-tight" /> + {avatarDetail && ( +
    +
    + HP: + + + {Number(avatarDetail?.[Number(data.id)]?.stats?.HP ?? 0).toLocaleString(undefined, { maximumFractionDigits: 0 })} + + / + + {Number(avatarDetail?.[Number(data.id)]?.stats?.MaxHP ?? 100).toLocaleString(undefined, { maximumFractionDigits: 0 })} + + +
    + +
    +
    + + {Math.round(((avatarDetail?.[Number(data.id)]?.stats?.HP || 0) / (avatarDetail?.[Number(data.id)]?.stats?.MaxHP || 100)) * 100)}% + +
    + +
    + )} +
  • ); diff --git a/src/components/enemybar/index.tsx b/src/components/enemybar/index.tsx new file mode 100644 index 0000000..a7fb916 --- /dev/null +++ b/src/components/enemybar/index.tsx @@ -0,0 +1,71 @@ +"use client" + +import useBattleDataStore from "@/stores/battleDataStore"; +import Image from "next/image"; + +function formatEnemyIdForURL(id?: number): string { + const n = id ?? 0; + const adjusted = n.toString().length === 9 ? n / 100 : n; + return adjusted.toFixed(0); +} + +export default function EnemyBar() { + const { enemyDetail } = useBattleDataStore() + + return ( +
    +
    + {enemyDetail && Object.values(enemyDetail).filter((enemy) => (enemy.stats?.AV > 0 + && enemy.stats.HP <= enemy.maxHP)).map((enemy, uid) => ( +
    +
    +
    + {enemy.name} +
    +

    + {enemy.name} +

    +

    Level {enemy.level || 1}

    +
    +
    +
    + +
    +
    +
    HP:
    +
    +
    + {Number(enemy?.stats?.HP ?? 0).toLocaleString(undefined, { maximumFractionDigits: 0 })} +
    +
    /
    +
    + {Number(enemy?.maxHP ?? 100).toLocaleString(undefined, { maximumFractionDigits: 0 })} +
    +
    +
    + +
    +
    +
    + {Math.round(((enemy.stats?.HP || 0) / (enemy.maxHP || 100)) * 100)}% +
    +
    + +
    +
    + ))} +
    +
    + ) +} \ No newline at end of file diff --git a/src/components/header/index.tsx b/src/components/header/index.tsx index c2e7ba3..9e84ebd 100644 --- a/src/components/header/index.tsx +++ b/src/components/header/index.tsx @@ -23,7 +23,7 @@ const themes = [ export default function Header() { const { changeTheme } = useChangeTheme() const { locale, setLocale } = useLocaleStore() - const { loadBattleDataFromJSON } = useBattleDataStore() + const { loadBattleDataFromJSON, version } = useBattleDataStore() const router = useRouter() const transI18n = useTranslations("DataAnalysisPage") const { host, port, status, connectionType, setHost, setPort, setStatus, setConnectionType } = useSocketStore(); @@ -219,6 +219,16 @@ export default function Header() {

    For Veritas

    + {version && ( +
    +
    +
    +
    + {version} +
    +
    +
    + )}
    diff --git a/src/components/lineupbar/index.tsx b/src/components/lineupbar/index.tsx index 4b18267..4069d20 100644 --- a/src/components/lineupbar/index.tsx +++ b/src/components/lineupbar/index.tsx @@ -209,7 +209,7 @@ export default function LineupBar() {

    {transI18n("eidolons")}: {avatar?.data?.rank}

    -

    +

    {transI18n("lightcones")}: -

    -

    +

    +
    {transI18n("relics")}:
    {relicIds.map(it => ( @@ -233,7 +233,7 @@ export default function LineupBar() { /> ))}
    -

    +
    ); })()} @@ -256,10 +256,10 @@ export default function LineupBar() { */}
    -

    {transI18n("totalTurn")}: {totalTurn.toFixed(2)}

    +

    {transI18n("totalTurn")}: {Number(totalTurn).toLocaleString(undefined, { minimumFractionDigits: 1, maximumFractionDigits: 1 })}

    -

    {transI18n("totalDamage")}: {totalDamage.toFixed(2)}

    +

    {transI18n("totalDamage")}: {Number(totalDamage).toLocaleString(undefined, { minimumFractionDigits: 1, maximumFractionDigits: 1 })}

    diff --git a/src/helper/exportDataBattle.ts b/src/helper/exportDataBattle.ts index d4ca205..ac599fd 100644 --- a/src/helper/exportDataBattle.ts +++ b/src/helper/exportDataBattle.ts @@ -14,7 +14,10 @@ export const exportBattleData = ( waveIndex, dataAvatar, maxWave, - maxCycle + maxCycle, + version, + avatarDetail, + enemyDetail } = useBattleDataStore.getState(); const data: BattleDataStateJson = { @@ -28,7 +31,10 @@ export const exportBattleData = ( cycleIndex, waveIndex, maxWave, - maxCycle + maxCycle, + version, + avatarDetail, + enemyDetail } const dataStr = JSON.stringify(data, null, 2); diff --git a/src/lib/api.ts b/src/lib/api.ts index 950a3d8..b854297 100644 --- a/src/lib/api.ts +++ b/src/lib/api.ts @@ -5,7 +5,7 @@ import axios from 'axios'; export async function checkConnectTcpApi(): Promise { const { host, port, connectionType } = useSocketStore.getState() let url = `${host}:${port}/check-tcp` - if (connectionType === "FireflyPSLocal") { + if (connectionType === "PS") { url = "http://localhost:21000/check-tcp" } const response = await fetch(url, { diff --git a/src/lib/socket.ts b/src/lib/socket.ts index 838dfa4..1f51b74 100644 --- a/src/lib/socket.ts +++ b/src/lib/socket.ts @@ -25,18 +25,22 @@ function safeParse(json: unknown | string) { export const connectSocket = (): Socket => { const { host, port, connectionType, setStatus } = useSocketStore.getState(); - const { - onSetBattleLineupService, - onTurnEndService, - onUseSkillService, - onKillService, - onDamageService, - onBattleEndService, - onTurnBeginService, + const { + onConnectedService, onBattleBeginService, - onCreateBattleService, + onSetBattleLineupService, + onDamageService, + onTurnBeginService, + onTurnEndService, + onEntityDefeatedService, + onUseSkillService, + onUpdateWaveService, onUpdateCycleService, - OnUpdateWaveService + onStatChange, + onUpdateTeamFormation, + onInitializeEnemyService, + onBattleEndService, + onCreateBattleService, } = useBattleDataStore.getState(); let url = `${host}:${port}`; @@ -86,68 +90,73 @@ export const connectSocket = (): Socket => { setStatus(true); notify(`Kết nối thành công với Socket ID: ${socket?.id}`, 'success'); }; + const onBattleBegin = (data: BattleBeginType) => { notify("Battle Started!", "info") onBattleBeginService(data) } if (isSocketConnected()) onConnect(); - - socket.on("OnSetBattleLineup", (json) => { + socket.on("Connected", (json) => { const data = safeParse(json); - if (data) onSetBattleLineupService(data); + if (data) onConnectedService(data); }); - - socket.on("OnTurnEnd", (json) => { - const data = safeParse(json); - if (data) onTurnEndService(data); - }); - - socket.on("OnUseSkill", (json) => { - const data = safeParse(json); - if (data) onUseSkillService(data); - }); - - socket.on("OnKill", (json) => { - const data = safeParse(json); - if (data) onKillService(data); - }); - - socket.on("OnDamage", (json) => { - const data = safeParse(json); - if (data) onDamageService(data); - }); - socket.on("OnBattleBegin", (json) => { const data = safeParse(json); if (data) onBattleBegin(data); }); - + socket.on("OnSetBattleLineup", (json) => { + const data = safeParse(json); + if (data) onSetBattleLineupService(data); + }); + socket.on("OnDamage", (json) => { + const data = safeParse(json); + if (data) onDamageService(data); + }); socket.on("OnTurnBegin", (json) => { const data = safeParse(json); if (data) onTurnBeginService(data); }); - - socket.on("OnBattleEnd", (json) => { + socket.on("OnTurnEnd", (json) => { const data = safeParse(json); - if (data) onBattleEndService(data); + if (data) onTurnEndService(data); + }); + socket.on("OnEntityDefeated", (json) => { + const data = safeParse(json); + if (data) onEntityDefeatedService(data); + }); + socket.on("OnUseSkill", (json) => { + const data = safeParse(json); + if (data) onUseSkillService(data); + }); + socket.on("OnUpdateWave", (json) => { + const data = safeParse(json); + if (data) onUpdateWaveService(data); }); - socket.on("OnUpdateCycle", (json) => { const data = safeParse(json); if (data) onUpdateCycleService(data); }); - - socket.on("OnUpdateWave", (json) => { + socket.on("OnStatChange", (json) => { const data = safeParse(json); - if (data) OnUpdateWaveService(data); + if (data) onStatChange(data); + }); + socket.on("OnUpdateTeamFormation", (json) => { + const data = safeParse(json); + if (data) onUpdateTeamFormation(data); + }); + socket.on("OnInitializeEnemy", (json) => { + const data = safeParse(json); + if (data) onInitializeEnemyService(data); + }); + socket.on("OnBattleEnd", (json) => { + const data = safeParse(json); + if (data) onBattleEndService(data); }); - socket.on("OnCreateBattle", (json) => { const data = safeParse(json); if (data) onCreateBattleService(data); }); - socket.on("Error", (msg: string) => { console.error("Server Error:", msg); }); @@ -157,34 +166,42 @@ export const connectSocket = (): Socket => { export const disconnectSocket = (): void => { const { - onSetBattleLineupService, - onTurnEndService, - onUseSkillService, - onKillService, - onDamageService, - onBattleEndService, - onTurnBeginService, + onConnectedService, onBattleBeginService, - onCreateBattleService, + onSetBattleLineupService, + onDamageService, + onTurnBeginService, + onTurnEndService, + onEntityDefeatedService, + onUseSkillService, + onUpdateWaveService, onUpdateCycleService, - OnUpdateWaveService + onStatChange, + onUpdateTeamFormation, + onInitializeEnemyService, + onBattleEndService, + onCreateBattleService, } = useBattleDataStore.getState(); const onBattleBegin = (data: BattleBeginType) => { notify("Battle Started!", "info") onBattleBeginService(data) } if (socket) { + socket.off("Connected", (json) => onConnectedService(JSON.parse(json))); + socket.off("OnBattleBegin", (json) => onBattleBegin(JSON.parse(json))); socket.off("OnSetBattleLineup", (json) => onSetBattleLineupService(JSON.parse(json))); socket.off("OnTurnEnd", (json) => onTurnEndService(JSON.parse(json))); socket.off("OnUseSkill", (json) => onUseSkillService(JSON.parse(json))); - socket.off("OnKill", (json) => onKillService(JSON.parse(json))); + socket.off("OnEntityDefeated", (json) => onEntityDefeatedService(JSON.parse(json))); socket.off("OnDamage", (json) => onDamageService(JSON.parse(json))); - socket.off('OnBattleBegin', (json) => onBattleBegin(JSON.parse(json))); socket.off('OnTurnBegin', (json) => onTurnBeginService(JSON.parse(json))); socket.off('OnBattleEnd', (json) => onBattleEndService(JSON.parse(json))); socket.off('OnUpdateCycle', (json) => onUpdateCycleService(JSON.parse(json))); - socket.off('OnUpdateWave', (json) => OnUpdateWaveService(JSON.parse(json))); + socket.off('OnUpdateWave', (json) => onUpdateWaveService(JSON.parse(json))); socket.off('OnCreateBattle', (json) => onCreateBattleService(JSON.parse(json))); + socket.off('OnStatChange', (json) => onStatChange(JSON.parse(json))); + socket.off('OnUpdateTeamFormation', (json) => onUpdateTeamFormation(JSON.parse(json))); + socket.off('OnInitializeEnemy', (json) => onInitializeEnemyService(JSON.parse(json))); socket.offAny(); socket.disconnect(); useSocketStore.getState().setStatus(false); diff --git a/src/stores/battleDataStore.ts b/src/stores/battleDataStore.ts index 38537f2..56e9256 100644 --- a/src/stores/battleDataStore.ts +++ b/src/stores/battleDataStore.ts @@ -1,5 +1,6 @@ -import { AttackResultType, AvatarAnalysisJson, AvatarSkillType, BattleBeginType, BattleEndType, DamageDetailType, KillType, LineUpType, TurnBeginType, TurnEndType, UpdateCycleType, UpdateWaveType } from '@/types'; -import { AvatarBattleInfo, BattleDataStateJson, SkillBattleInfo, TurnBattleInfo } from '@/types/mics'; +import { DamageType, AvatarAnalysisJson, UseSkillType, BattleBeginType, BattleEndType, DamageDetailType, EntityDefeatedType, SetBattleLineupType, TurnBeginType, TurnEndType, UpdateCycleType, UpdateWaveType, VersionType, StatType, StatChangeType, UpdateTeamFormationType } from '@/types'; +import { InitializeEnemyType } from '@/types/enemy'; +import { AvatarBattleInfo, AvatarInfo, BattleDataStateJson, EnemyInfo, SkillBattleInfo, TurnBattleInfo } from '@/types/mics'; import { create } from 'zustand' @@ -14,19 +15,26 @@ interface BattleDataState { cycleIndex: number; waveIndex: number; maxWave: number; - maxCycle: number + maxCycle: number; + version?: string; + avatarDetail?: Record; + enemyDetail?: Record; - onSetBattleLineupService: (data: LineUpType) => void; - onTurnEndService: (data: TurnEndType) => void; - onBattleEndService: (data: BattleEndType) => void; - onUseSkillService: (data: AvatarSkillType) => void; - onKillService: (data: KillType) => void - onDamageService: (data: AttackResultType) => void; + onConnectedService: (data: VersionType) => void onBattleBeginService: (data: BattleBeginType) => void; + onSetBattleLineupService: (data: SetBattleLineupType) => void; + onDamageService: (data: DamageType) => void; onTurnBeginService: (data: TurnBeginType) => void; - onCreateBattleService: (data: AvatarAnalysisJson[]) => void; - OnUpdateWaveService: (data: UpdateWaveType) => void; + onTurnEndService: (data: TurnEndType) => void; + onEntityDefeatedService: (data: EntityDefeatedType) => void; + onUseSkillService: (data: UseSkillType) => void; + onUpdateWaveService: (data: UpdateWaveType) => void; onUpdateCycleService: (data: UpdateCycleType) => void; + onStatChange: (data: StatChangeType) => void; + onUpdateTeamFormation: (data: UpdateTeamFormationType) => void; + onInitializeEnemyService: (data: InitializeEnemyType) => void; + onBattleEndService: (data: BattleEndType) => void; + onCreateBattleService: (data: AvatarAnalysisJson[]) => void; loadBattleDataFromJSON: (data: BattleDataStateJson) => void; } @@ -42,7 +50,9 @@ const useBattleDataStore = create((set, get) => ({ waveIndex: 1, maxWave: Infinity, maxCycle: Infinity, - + version: undefined, + avatarDetail: undefined, + enemyDetail: undefined, loadBattleDataFromJSON: (data: BattleDataStateJson) => { set({ lineup: data.lineup, @@ -55,7 +65,15 @@ const useBattleDataStore = create((set, get) => ({ cycleIndex: data.cycleIndex, waveIndex: data.waveIndex, maxWave: data.maxWave, - maxCycle: data.maxCycle + maxCycle: data.maxCycle, + version: data.version, + avatarDetail: data.avatarDetail, + enemyDetail: data.enemyDetail + }) + }, + onConnectedService: (data: VersionType) => { + set({ + version: data.version }) }, onCreateBattleService: (data: AvatarAnalysisJson[]) => { @@ -75,36 +93,7 @@ const useBattleDataStore = create((set, get) => ({ turnHistory: updatedHistory }) }, - onDamageService: (data: AttackResultType) => { - const skillHistory = get().skillHistory - - const skillIdx = skillHistory.findLastIndex(it => it.avatarId === data.attacker.id) - if (skillIdx === -1) { - return - } - const newTh = [...skillHistory] - newTh[skillIdx].damageDetail.push({damage: data.damage, damage_type: data?.damage_type} as DamageDetailType) - newTh[skillIdx].totalDamage += data.damage - set({ - skillHistory: newTh, - totalDamage: get().totalDamage + data.damage, - damagePerAV: (get().totalDamage + data.damage) / (get().totalAV === 0 ? 1 : get().totalAV) - }) - }, - - onKillService: (data: KillType) => { - const lineups = get().lineup - const avatarIdx = lineups.findIndex(it => it.avatarId === data.attacker.id) - if (avatarIdx === -1) { - return - } - const newLn = [...lineups] - newLn[avatarIdx].isDie = true - set({ - lineup: newLn - }) - }, - onSetBattleLineupService: (data: LineUpType) => { + onSetBattleLineupService: (data: SetBattleLineupType) => { const lineups: AvatarBattleInfo[] = [] for (const avatar of data.avatars) { lineups.push({ avatarId: avatar.id, isDie: false } as AvatarBattleInfo) @@ -125,13 +114,28 @@ const useBattleDataStore = create((set, get) => ({ waveIndex: 1, })); }, + onDamageService: (data: DamageType) => { + const skillHistory = get().skillHistory + + const skillIdx = skillHistory.findLastIndex(it => it.avatarId === data.attacker.uid) + if (skillIdx === -1) { + return + } + const newTh = [...skillHistory] + newTh[skillIdx].damageDetail.push({damage: data.damage, damage_type: data?.damage_type} as DamageDetailType) + newTh[skillIdx].totalDamage += data.damage + set({ + skillHistory: newTh, + totalDamage: get().totalDamage + data.damage, + damagePerAV: (get().totalDamage + data.damage) / (get().totalAV === 0 ? 1 : get().totalAV) + }) + }, onTurnBeginService: (data: TurnBeginType) => { - set((state) => ({ totalAV: data.action_value, damagePerAV: state.totalDamage / (data.action_value === 0 ? 1 : data.action_value), turnHistory: [...state.turnHistory, { - avatarId: data?.turn_owner?.id, + avatarId: data?.turn_owner?.uid, actionValue: data.action_value, waveIndex: state.waveIndex, cycleIndex: state.cycleIndex @@ -146,19 +150,157 @@ const useBattleDataStore = create((set, get) => ({ / (data.turn_info.action_value === 0 ? 1 : data.turn_info.action_value) })); }, - onUseSkillService: (data: AvatarSkillType) => { - + onEntityDefeatedService: (data: EntityDefeatedType) => { + let avatarDetail = get().avatarDetail + let enemyDetail = get().enemyDetail + if (!enemyDetail) { + enemyDetail = {} as Record + } + if (!avatarDetail) { + avatarDetail = {} as Record + } + if (data.killer.team === "Player" && enemyDetail[data.entity_defeated.uid]) { + enemyDetail[data.entity_defeated.uid].isDie = true + enemyDetail[data.entity_defeated.uid].killer_uid = data.killer.uid + } else if (data.killer.team === "Enemy" && avatarDetail[data.entity_defeated.uid]) { + avatarDetail[data.entity_defeated.uid].isDie = true + avatarDetail[data.entity_defeated.uid].killer_uid = data.killer.uid + } else { + console.error("onEntityDefeatedService", data) + console.error("onEntityDefeatedService", enemyDetail) + console.error("onEntityDefeatedService", avatarDetail) + } + set({ + avatarDetail: avatarDetail, + enemyDetail: enemyDetail + }) + }, + onUseSkillService: (data: UseSkillType) => { set((state) => ({ skillHistory: [...state.skillHistory, { - avatarId: data.avatar.id, + avatarId: data.avatar.uid, damageDetail: [], totalDamage: 0, skillType: data.skill.type, skillName: data.skill.name, - turnBattleId: state.turnHistory.length-1 + turnBattleId: state.turnHistory.length-1 } as SkillBattleInfo] })) }, + onUpdateWaveService: (data: UpdateWaveType) => { + set({ + waveIndex: data.wave + }) + }, + onUpdateCycleService: (data: UpdateCycleType) => { + set({ + cycleIndex: data.cycle + }) + }, + onStatChange: (data: StatChangeType) => { + let avatarDetail = get().avatarDetail + let enemyDetail = get().enemyDetail + if (!enemyDetail) { + enemyDetail = {} as Record + } + if (!avatarDetail) { + avatarDetail = {} as Record + } + if (data.entity.team === "Player") { + const [key, value] = Object.entries(data.stat)[0] + const uid = data.entity.uid; + + if (!avatarDetail[uid]) { + avatarDetail[uid] = { + id: uid, + isDie: false, + killer_uid: -1, + stats: {}, + statsHistory: [] + }; + } + avatarDetail[uid].stats[key] = value + avatarDetail[uid].statsHistory.push({ + stats: data.stat, + turnBattleId: get().turnHistory.length-1 + }) + } else { + const [key, value] = Object.entries(data.stat)[0] + const uid = data.entity.uid; + + if (!enemyDetail[uid]) { + enemyDetail[uid] = { + id: uid, + isDie: false, + killer_uid: -1, + name: "", + positionIndex: Object.keys(get().enemyDetail || {}).length, + maxHP: 0, + waveIndex: 0, + level: 0, + stats: {}, + statsHistory: [] + }; + } + enemyDetail[uid].stats[key] = value + enemyDetail[uid].statsHistory.push({ + stats: data.stat, + turnBattleId: get().turnHistory.length-1 + }) + } + set({ + avatarDetail: avatarDetail, + enemyDetail: enemyDetail + }) + }, + + onUpdateTeamFormation: (data: UpdateTeamFormationType) => { + let avatarDetail = get().avatarDetail + let enemyDetail = get().enemyDetail + if (!avatarDetail) { + avatarDetail = {} as Record + for (const entity of data.entities) { + if (entity.team === "Player" && avatarDetail[entity.uid]) { + + } + } + } + if (!enemyDetail) { + enemyDetail = {} as Record + for (let i = 0; i < data.entities.length; i++) { + const entity = data.entities[i]; + if (entity.team === "Enemy" && enemyDetail[entity.uid]) { + enemyDetail[entity.uid].positionIndex = i + } + } + } + + set({ + avatarDetail: avatarDetail, + enemyDetail: enemyDetail + }) + }, + onInitializeEnemyService: (data: InitializeEnemyType) => { + const enemyDetail = get().enemyDetail + if (!enemyDetail) { + return + } + enemyDetail[data.enemy.uid] = { + id: data.enemy.id, + isDie: false, + killer_uid: -1, + positionIndex: enemyDetail[data.enemy.uid].positionIndex, + waveIndex: get().waveIndex, + name: data.enemy.name, + maxHP: data.enemy.base_stats.hp, + level: data.enemy.base_stats.level, + stats: {}, + statsHistory: [] + } + set({ + enemyDetail: enemyDetail + }) + }, onBattleEndService: (data: BattleEndType) => { const lineups: AvatarBattleInfo[] = [] for (const avatar of data.avatars) { @@ -171,16 +313,6 @@ const useBattleDataStore = create((set, get) => ({ damagePerAV: data.total_damage / (data.action_value === 0 ? 1 : data.action_value) }) }, - OnUpdateWaveService: (data: UpdateWaveType) => { - set({ - waveIndex: data.wave - }) - }, - onUpdateCycleService: (data: UpdateCycleType) => { - set({ - cycleIndex: data.cycle - }) - } })); export default useBattleDataStore; \ No newline at end of file diff --git a/src/types/attack.ts b/src/types/attack.ts index 09a443d..4419758 100644 --- a/src/types/attack.ts +++ b/src/types/attack.ts @@ -1,7 +1,7 @@ -import { AvatarType } from "./lineup"; +import { EntityType } from "./entity"; -export interface AttackResultType { - attacker: AvatarType; +export interface DamageType { + attacker: EntityType; damage: number; damage_type?: AttackType } diff --git a/src/types/battle.ts b/src/types/battle.ts index e73521d..79b7bdc 100644 --- a/src/types/battle.ts +++ b/src/types/battle.ts @@ -10,9 +10,6 @@ export interface BattleEndType { action_value: number; stage_id: number; } -export interface KillType { - attacker: AvatarType; -} export interface BattleBeginType { max_waves: number diff --git a/src/types/enemy.ts b/src/types/enemy.ts new file mode 100644 index 0000000..785d2a5 --- /dev/null +++ b/src/types/enemy.ts @@ -0,0 +1,12 @@ +import { StatsType } from "./stat"; + +export interface EnemyType { + id: number; + uid: number; + name: string; + base_stats: StatsType +} + +export interface InitializeEnemyType { + enemy: EnemyType +} \ No newline at end of file diff --git a/src/types/entity.ts b/src/types/entity.ts new file mode 100644 index 0000000..dd9202a --- /dev/null +++ b/src/types/entity.ts @@ -0,0 +1,9 @@ +export interface EntityType { + uid: number; + team: "Player" | "Enemy"; +} + +export interface EntityDefeatedType { + killer: EntityType, + entity_defeated: EntityType +} \ No newline at end of file diff --git a/src/types/error.ts b/src/types/error.ts new file mode 100644 index 0000000..ac8fd6f --- /dev/null +++ b/src/types/error.ts @@ -0,0 +1,3 @@ +export interface ErrorType { + msg: string +} \ No newline at end of file diff --git a/src/types/index.ts b/src/types/index.ts index 5007d25..dbc8c09 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -5,4 +5,7 @@ export * from "./lineup" export * from "./skill" export * from "./turn" export * from "./waveAndCycle" -export * from "./srtools" \ No newline at end of file +export * from "./srtools" +export * from "./version" +export * from "./entity" +export * from "./stat" diff --git a/src/types/lineup.ts b/src/types/lineup.ts index 1db91c0..91d5491 100644 --- a/src/types/lineup.ts +++ b/src/types/lineup.ts @@ -1,8 +1,16 @@ +import { EntityType } from "./entity"; + export interface AvatarType{ id: number; name: string; } -export interface LineUpType { +export interface SetBattleLineupType { avatars: AvatarType[]; +} + + +export interface UpdateTeamFormationType { + entities: EntityType[], + team: "Player" | "Enemy" } \ No newline at end of file diff --git a/src/types/mics.ts b/src/types/mics.ts index 69abfb8..5529134 100644 --- a/src/types/mics.ts +++ b/src/types/mics.ts @@ -1,9 +1,11 @@ import {AttackType, DamageDetailType} from "./attack"; import { AvatarAnalysisJson } from "./srtools"; +import { StatType } from "./stat"; + export interface AvatarBattleInfo { avatarId: number; - isDie: boolean; + isDie?: boolean; } export interface SkillBattleInfo { @@ -33,5 +35,34 @@ export interface BattleDataStateJson { maxWave: number; cycleIndex: number, waveIndex: number, - maxCycle: number -} \ No newline at end of file + maxCycle: number, + version?: string, + avatarDetail?: Record; + enemyDetail?: Record; +} + +export interface StatsHistoryType { + stats: StatType + turnBattleId: number; +} + +export interface EnemyInfo { + id: number; + name: string; + maxHP: number; + level: number; + isDie: boolean; + positionIndex: number; + waveIndex: number; + killer_uid: number; + stats: Record; + statsHistory: StatsHistoryType[]; +} +export interface AvatarInfo { + id: number; + isDie: boolean; + killer_uid: number; + stats: Record; + statsHistory: StatsHistoryType[]; +} + diff --git a/src/types/skill.ts b/src/types/skill.ts index 2cb957d..3e14b9f 100644 --- a/src/types/skill.ts +++ b/src/types/skill.ts @@ -1,12 +1,14 @@ -import { AvatarType } from "./lineup"; + import { AttackType } from "@/types/attack"; +import { EntityType } from "./entity"; export interface SkillInfo { name: string; type: AttackType; + skill_config_id: number; } -export interface AvatarSkillType { - avatar: AvatarType; +export interface UseSkillType { + avatar: EntityType; skill: SkillInfo; } \ No newline at end of file diff --git a/src/types/stat.ts b/src/types/stat.ts new file mode 100644 index 0000000..f17df4e --- /dev/null +++ b/src/types/stat.ts @@ -0,0 +1,13 @@ +import { EntityType } from "./entity"; + +export type StatType = Record + +export interface StatsType { + level: number; + hp: number; +} + +export interface StatChangeType { + entity: EntityType, + stat: StatType, +} \ No newline at end of file diff --git a/src/types/turn.ts b/src/types/turn.ts index 3b7d1b5..a69badd 100644 --- a/src/types/turn.ts +++ b/src/types/turn.ts @@ -1,5 +1,4 @@ -import { AvatarType } from "./lineup"; - +import { EntityType } from "./entity"; export interface TurnInfoType { avatars_turn_damage: number[]; @@ -11,10 +10,9 @@ export interface TurnInfoType { export interface TurnBeginType { action_value: number; - turn_owner?: AvatarType + turn_owner?: EntityType | null } export interface TurnEndType { - avatars: AvatarType[]; turn_info: TurnInfoType } \ No newline at end of file diff --git a/src/types/version.ts b/src/types/version.ts new file mode 100644 index 0000000..dd25046 --- /dev/null +++ b/src/types/version.ts @@ -0,0 +1,3 @@ +export interface VersionType { + version: string +} \ No newline at end of file