update for 3.3.1
This commit is contained in:
@@ -59,7 +59,7 @@
|
||||
"knight": "存护",
|
||||
"mage": "智识",
|
||||
"priest": "丰饶",
|
||||
"rouge": "巡猎",
|
||||
"rogue": "巡猎",
|
||||
"shaman": "同协",
|
||||
"warlock": "虚无",
|
||||
"memory": "记忆",
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
"knight": "Preservation",
|
||||
"mage": "Erudition",
|
||||
"priest": "Abundance",
|
||||
"rouge": "The Hunt",
|
||||
"rogue": "The Hunt",
|
||||
"shaman": "Harmony",
|
||||
"warlock": "Nihility",
|
||||
"memory": "Remembrance",
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
"knight": "存護",
|
||||
"mage": "知恵",
|
||||
"priest": "豊穣",
|
||||
"rouge": "巡狩",
|
||||
"rogue": "巡狩",
|
||||
"shaman": "調和",
|
||||
"warlock": "虚無",
|
||||
"memory": "記憶",
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
"knight": "보존",
|
||||
"mage": "지혜",
|
||||
"priest": "풍요",
|
||||
"rouge": "사냥",
|
||||
"rogue": "사냥",
|
||||
"shaman": "조화",
|
||||
"warlock": "허무",
|
||||
"memory": "기억",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
"knight": "存护",
|
||||
"mage": "智识",
|
||||
"priest": "丰饶",
|
||||
"rouge": "巡猎",
|
||||
"rogue": "巡猎",
|
||||
"shaman": "同协",
|
||||
"warlock": "虚无",
|
||||
"memory": "记忆",
|
||||
|
||||
@@ -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<string[]>([]);
|
||||
|
||||
@@ -55,22 +57,22 @@ export default function Home() {
|
||||
<div className="grid grid-cols-2 gap-2 mb-3">
|
||||
<div className="p-2 text-base lg:text-lg xl:text-xl rounded bg-primary text-primary-content text-center shadow-md">
|
||||
{transI18n("totalDamage")}
|
||||
<div>{Number(totalDamage).toFixed(2)}</div>
|
||||
<div>{Number(totalDamage).toLocaleString(undefined, { minimumFractionDigits: 1, maximumFractionDigits: 1 })}</div>
|
||||
</div>
|
||||
<div className="p-2 text-base lg:text-lg xl:text-xl rounded bg-secondary text-secondary-content text-center shadow-md">
|
||||
{transI18n("totalAV")}
|
||||
<div>{Number(totalAV).toFixed(2)}</div>
|
||||
<div>{Number(totalAV).toLocaleString(undefined, { minimumFractionDigits: 1, maximumFractionDigits: 1 })}</div>
|
||||
</div>
|
||||
<div className="p-2 text-base lg:text-lg xl:text-xl rounded bg-accent text-accent-content text-center shadow-md">
|
||||
{transI18n("damagePerAV")}
|
||||
<div>{Number(damagePerAV).toFixed(2)}</div>
|
||||
<div>{Number(damagePerAV).toLocaleString(undefined, { minimumFractionDigits: 1, maximumFractionDigits: 1 })}</div>
|
||||
</div>
|
||||
<div className="p-2 text-base lg:text-lg xl:text-xl rounded bg-warning text-warning-content text-center shadow-md">
|
||||
{transI18n("totalTurn")}
|
||||
<div>{turnHistory.filter(it => it.avatarId && it.avatarId != -1).length}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{enemyDetail && <EnemyBar />}
|
||||
|
||||
<div className="rounded-lg p-2 shadow-md flex-grow">
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
|
||||
|
||||
@@ -140,7 +140,7 @@ export default function ActionBar() {
|
||||
{`${transI18n("useSkill")}: ${transI18n(attackTypeToString(turn.skillType).toLowerCase())}`}
|
||||
</div>
|
||||
<div className="text-primary text-xs max-w-full">
|
||||
{`${transI18n("totalDamage")}: ${turn.totalDamage.toFixed(2)}`}
|
||||
{`${transI18n("totalDamage")}: ${Number(turn.totalDamage).toLocaleString(undefined, { minimumFractionDigits: 1, maximumFractionDigits: 1 })}`}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -234,11 +234,11 @@ export default function ActionBar() {
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
|
||||
<div className="bg-base-200 rounded-lg p-4 shadow-md">
|
||||
<h4 className="text-lg font-semibold mb-2 text-cyan-500 border-b border-cyan-300/30 pb-1">{transI18n("actionValue")}</h4>
|
||||
<p className="mt-2">{turnHistory[selectTurn?.turnBattleId].actionValue.toFixed(2)}</p>
|
||||
<p className="mt-2">{Number(turnHistory[selectTurn?.turnBattleId].actionValue).toLocaleString(undefined, { minimumFractionDigits: 1, maximumFractionDigits: 1 })}</p>
|
||||
</div>
|
||||
<div className="bg-base-200 rounded-lg p-4 shadow-md">
|
||||
<h4 className="text-lg font-semibold mb-2 text-purple-500 border-b border-purple-300/30 pb-1">{transI18n("totalDamage")}</h4>
|
||||
<p className="mt-2 font-bold text-lg">{selectTurn?.totalDamage.toFixed(2)}</p>
|
||||
<p className="mt-2 font-bold text-lg">{Number(selectTurn?.totalDamage).toLocaleString(undefined, { minimumFractionDigits: 1, maximumFractionDigits: 1 })}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -252,7 +252,7 @@ export default function ActionBar() {
|
||||
className="flex flex-col items-start gap-1 p-3 rounded-lg shadow bg-base-200"
|
||||
>
|
||||
<span className="text-lg font-semibold text-primary">
|
||||
{detail.damage.toFixed(2)}
|
||||
{Number(detail.damage).toLocaleString(undefined, { minimumFractionDigits: 1, maximumFractionDigits: 1 })}
|
||||
</span>
|
||||
<span className="text-xs uppercase text-gray-500 tracking-wide">
|
||||
{transI18n(attackTypeToString(detail?.damage_type).toLowerCase())}
|
||||
|
||||
@@ -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 (
|
||||
<li className="z-10 flex flex-col w-28 items-center p-1 rounded-md shadow-lg bg-gradient-to-b from-customStart to-customEnd transform transition-transform duration-300 hover:scale-105 m-1">
|
||||
<div
|
||||
className={`w-[80px] rounded-md p-[2px] bg-gradient-to-br ${data.rank === "CombatPowerAvatarRarityType5"
|
||||
? "from-yellow-400 via-yellow-300 to-yellow-500"
|
||||
: "from-purple-300 via-purple-200 to-purple-400"
|
||||
? "from-yellow-400 via-yellow-300 to-yellow-500"
|
||||
: "from-purple-300 via-purple-200 to-purple-400"
|
||||
}`}
|
||||
>
|
||||
|
||||
@@ -50,6 +55,36 @@ export default function CharacterCard({ data }: CharacterCardProps) {
|
||||
text={text}
|
||||
className="mt-2 text-center text-base font-normal leading-tight"
|
||||
/>
|
||||
{avatarDetail && (
|
||||
<div className="space-y-2">
|
||||
<div className="flex justify-between items-center">
|
||||
<span className="text-xs text-base-content/70 mx-1">HP:</span>
|
||||
<span className="text-xs font-medium">
|
||||
<span className="text-error">
|
||||
{Number(avatarDetail?.[Number(data.id)]?.stats?.HP ?? 0).toLocaleString(undefined, { maximumFractionDigits: 0 })}
|
||||
</span>
|
||||
<span className="text-base-content/50">/</span>
|
||||
<span className="text-base-content/70">
|
||||
{Number(avatarDetail?.[Number(data.id)]?.stats?.MaxHP ?? 100).toLocaleString(undefined, { maximumFractionDigits: 0 })}
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="relative w-full bg-base-300 rounded-full h-2.5">
|
||||
<div
|
||||
className="bg-error h-2.5 rounded-full transition-all duration-300"
|
||||
style={{
|
||||
width: `${Math.max(0, Math.min(100, ((avatarDetail?.[Number(data.id)]?.stats?.HP || 0) / (avatarDetail?.[Number(data.id)]?.stats?.MaxHP || 100)) * 100))}%`
|
||||
}}
|
||||
/>
|
||||
<span className="absolute inset-0 flex items-center justify-center text-xs text-white font-medium">
|
||||
{Math.round(((avatarDetail?.[Number(data.id)]?.stats?.HP || 0) / (avatarDetail?.[Number(data.id)]?.stats?.MaxHP || 100)) * 100)}%
|
||||
</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
)}
|
||||
|
||||
</li>
|
||||
|
||||
);
|
||||
|
||||
71
src/components/enemybar/index.tsx
Normal file
71
src/components/enemybar/index.tsx
Normal file
@@ -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 (
|
||||
<div className="p-3 w-full">
|
||||
<div className="flex gap-3 overflow-x-auto pb-2">
|
||||
{enemyDetail && Object.values(enemyDetail).filter((enemy) => (enemy.stats?.AV > 0
|
||||
&& enemy.stats.HP <= enemy.maxHP)).map((enemy, uid) => (
|
||||
<div key={uid} className="bg-base-200 rounded-lg p-3 border border-gray-700 w-52 flex-shrink-0">
|
||||
<div className="flex items-center justify-between mb-3">
|
||||
<div className="flex items-center gap-2">
|
||||
<Image
|
||||
src={`https://api.hakush.in/hsr/UI/monstermiddleicon/Monster_${formatEnemyIdForURL(enemy.id)}.webp`}
|
||||
alt={enemy.name}
|
||||
width={40}
|
||||
height={40}
|
||||
className="object-cover w-10 h-10 rounded-lg"
|
||||
/>
|
||||
<div className="flex-1 min-w-0">
|
||||
<h3 className="text-base font-semibold leading-tight truncate overflow-hidden" title={enemy.name}>
|
||||
{enemy.name}
|
||||
</h3>
|
||||
<p className="text-base-content/70 text-xs">Level {enemy.level || 1}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<div className="flex justify-between items-center">
|
||||
<div className="text-xs text-base-content/70">HP:</div>
|
||||
<div className="text-xs font-medium">
|
||||
<div className="text-error">
|
||||
{Number(enemy?.stats?.HP ?? 0).toLocaleString(undefined, { maximumFractionDigits: 0 })}
|
||||
</div>
|
||||
<div className="text-base-content/50 mx-1">/</div>
|
||||
<div className="text-base-content/70">
|
||||
{Number(enemy?.maxHP ?? 100).toLocaleString(undefined, { maximumFractionDigits: 0 })}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="relative w-full bg-base-300 rounded-full h-2.5">
|
||||
<div
|
||||
className="bg-error h-2.5 rounded-full transition-all duration-300"
|
||||
style={{
|
||||
width: `${Math.max(0, Math.min(100, ((enemy.stats?.HP || 0) / (enemy.maxHP || 100)) * 100))}%`
|
||||
}}
|
||||
/>
|
||||
<div className="absolute inset-0 flex items-center justify-center text-xs text-white font-medium">
|
||||
{Math.round(((enemy.stats?.HP || 0) / (enemy.maxHP || 100)) * 100)}%
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -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() {
|
||||
</h1>
|
||||
<p className="text-sm text-gray-500">For Veritas</p>
|
||||
</a>
|
||||
{version && (
|
||||
<div className="px-2">
|
||||
<div className="inline-flex items-center space-x-2 px-3 py-1.5 bg-gradient-to-r from-blue-500 to-purple-600 rounded-full shadow-md hover:shadow-lg transition-all duration-200">
|
||||
<div className="w-1.5 h-1.5 bg-white rounded-full animate-pulse"></div>
|
||||
<div className="text-xs font-semibold text-white">
|
||||
{version}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
@@ -209,7 +209,7 @@ export default function LineupBar() {
|
||||
<p>
|
||||
{transI18n("eidolons")}: <span className="font-bold">{avatar?.data?.rank}</span>
|
||||
</p>
|
||||
<p className="flex items-center space-x-2">
|
||||
<div className="flex items-center space-x-2">
|
||||
<span>{transI18n("lightcones")}:</span>
|
||||
<Image
|
||||
src={`https://api.hakush.in/hsr/UI/lightconemediumicon/${avatar?.Lightcone?.item_id}.webp`}
|
||||
@@ -218,8 +218,8 @@ export default function LineupBar() {
|
||||
width={200}
|
||||
height={200}
|
||||
/>
|
||||
</p>
|
||||
<p className="flex items-center space-x-2 w-full">
|
||||
</div>
|
||||
<div className="flex items-center space-x-2 w-full">
|
||||
<span>{transI18n("relics")}:</span>
|
||||
<div className="grid grid-cols-3 md:flex md:flex-row w-full">
|
||||
{relicIds.map(it => (
|
||||
@@ -233,7 +233,7 @@ export default function LineupBar() {
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</p>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
})()}
|
||||
@@ -256,10 +256,10 @@ export default function LineupBar() {
|
||||
<ShowCaseInfo></ShowCaseInfo>
|
||||
</div> */}
|
||||
<div className="bg-base-200 rounded-lg p-4 shadow-md">
|
||||
<p className="mt-2 font-bold text-lg text-cyan-500">{transI18n("totalTurn")}: <span className="text-base-content">{totalTurn.toFixed(2)}</span></p>
|
||||
<p className="mt-2 font-bold text-lg text-cyan-500">{transI18n("totalTurn")}: <span className="text-base-content">{Number(totalTurn).toLocaleString(undefined, { minimumFractionDigits: 1, maximumFractionDigits: 1 })}</span></p>
|
||||
</div>
|
||||
<div className="bg-base-200 rounded-lg p-4 shadow-md">
|
||||
<h4 className="text-lg font-semibold mb-2 text-purple-500">{transI18n("totalDamage")}: <span className="text-base-content">{totalDamage.toFixed(2)}</span></h4>
|
||||
<h4 className="text-lg font-semibold mb-2 text-purple-500">{transI18n("totalDamage")}: <span className="text-base-content">{Number(totalDamage).toLocaleString(undefined, { minimumFractionDigits: 1, maximumFractionDigits: 1 })}</span></h4>
|
||||
</div>
|
||||
|
||||
<div className="bg-base-200 rounded-lg p-4 shadow-md">
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -5,7 +5,7 @@ import axios from 'axios';
|
||||
export async function checkConnectTcpApi(): Promise<boolean> {
|
||||
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, {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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<number, AvatarInfo>;
|
||||
enemyDetail?: Record<number, EnemyInfo>;
|
||||
|
||||
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<BattleDataState>((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<BattleDataState>((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<BattleDataState>((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<BattleDataState>((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<BattleDataState>((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<number, EnemyInfo>
|
||||
}
|
||||
if (!avatarDetail) {
|
||||
avatarDetail = {} as Record<number, AvatarInfo>
|
||||
}
|
||||
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<number, EnemyInfo>
|
||||
}
|
||||
if (!avatarDetail) {
|
||||
avatarDetail = {} as Record<number, AvatarInfo>
|
||||
}
|
||||
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<number, AvatarInfo>
|
||||
for (const entity of data.entities) {
|
||||
if (entity.team === "Player" && avatarDetail[entity.uid]) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!enemyDetail) {
|
||||
enemyDetail = {} as Record<number, EnemyInfo>
|
||||
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<BattleDataState>((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;
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -10,9 +10,6 @@ export interface BattleEndType {
|
||||
action_value: number;
|
||||
stage_id: number;
|
||||
}
|
||||
export interface KillType {
|
||||
attacker: AvatarType;
|
||||
}
|
||||
|
||||
export interface BattleBeginType {
|
||||
max_waves: number
|
||||
|
||||
12
src/types/enemy.ts
Normal file
12
src/types/enemy.ts
Normal file
@@ -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
|
||||
}
|
||||
9
src/types/entity.ts
Normal file
9
src/types/entity.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
export interface EntityType {
|
||||
uid: number;
|
||||
team: "Player" | "Enemy";
|
||||
}
|
||||
|
||||
export interface EntityDefeatedType {
|
||||
killer: EntityType,
|
||||
entity_defeated: EntityType
|
||||
}
|
||||
3
src/types/error.ts
Normal file
3
src/types/error.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export interface ErrorType {
|
||||
msg: string
|
||||
}
|
||||
@@ -5,4 +5,7 @@ export * from "./lineup"
|
||||
export * from "./skill"
|
||||
export * from "./turn"
|
||||
export * from "./waveAndCycle"
|
||||
export * from "./srtools"
|
||||
export * from "./srtools"
|
||||
export * from "./version"
|
||||
export * from "./entity"
|
||||
export * from "./stat"
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
maxCycle: number,
|
||||
version?: string,
|
||||
avatarDetail?: Record<number, AvatarInfo>;
|
||||
enemyDetail?: Record<number, EnemyInfo>;
|
||||
}
|
||||
|
||||
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<string, number>;
|
||||
statsHistory: StatsHistoryType[];
|
||||
}
|
||||
export interface AvatarInfo {
|
||||
id: number;
|
||||
isDie: boolean;
|
||||
killer_uid: number;
|
||||
stats: Record<string, number>;
|
||||
statsHistory: StatsHistoryType[];
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
13
src/types/stat.ts
Normal file
13
src/types/stat.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { EntityType } from "./entity";
|
||||
|
||||
export type StatType = Record<string, number>
|
||||
|
||||
export interface StatsType {
|
||||
level: number;
|
||||
hp: number;
|
||||
}
|
||||
|
||||
export interface StatChangeType {
|
||||
entity: EntityType,
|
||||
stat: StatType,
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
3
src/types/version.ts
Normal file
3
src/types/version.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export interface VersionType {
|
||||
version: string
|
||||
}
|
||||
Reference in New Issue
Block a user