update wave, cycle, damage type ...
This commit is contained in:
@@ -2,13 +2,13 @@ import useBattleDataStore from "@/stores/battleDataStore";
|
||||
import { useMemo } from "react";
|
||||
|
||||
export function useCalcTotalDmgAvatar(avatarId: number) {
|
||||
const { turnHistory } = useBattleDataStore.getState();
|
||||
const { skillHistory } = useBattleDataStore.getState();
|
||||
|
||||
return useMemo(() => {
|
||||
return turnHistory
|
||||
return skillHistory
|
||||
.filter(t => t.avatarId === avatarId)
|
||||
.reduce((sum, turn) => sum + turn.totalDamage, 0);
|
||||
}, [avatarId, turnHistory]);
|
||||
}, [avatarId, skillHistory]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -2,16 +2,16 @@ import useBattleDataStore from "@/stores/battleDataStore";
|
||||
import { useMemo } from "react";
|
||||
|
||||
export function useDamageLineForOne(avatarId: number, mode: 0 | 1 = 0) {
|
||||
const { turnHistory } = useBattleDataStore.getState();
|
||||
const { skillHistory, turnHistory } = useBattleDataStore.getState();
|
||||
|
||||
return useMemo(() => {
|
||||
const map = new Map<number, number>();
|
||||
|
||||
for (const turn of turnHistory) {
|
||||
if (turn.avatarId !== avatarId) continue;
|
||||
|
||||
const prev = map.get(turn.actionValue) || 0;
|
||||
map.set(turn.actionValue, prev + turn.totalDamage);
|
||||
for (const skill of skillHistory) {
|
||||
if (skill.avatarId !== avatarId) continue;
|
||||
const actionValue = turnHistory[skill.turnBattleId].actionValue
|
||||
const prev = map.get(actionValue) || 0;
|
||||
map.set(actionValue, prev + skill.totalDamage);
|
||||
}
|
||||
|
||||
const points = Array.from(map.entries())
|
||||
@@ -27,5 +27,5 @@ export function useDamageLineForOne(avatarId: number, mode: 0 | 1 = 0) {
|
||||
}
|
||||
|
||||
return points.map(p => ({ x: p.x, y: Number(p.y.toFixed(2)) }));
|
||||
}, [avatarId, turnHistory, mode]);
|
||||
}, [avatarId, skillHistory, turnHistory, mode]);
|
||||
}
|
||||
|
||||
@@ -1,20 +1,21 @@
|
||||
import useBattleDataStore from "@/stores/battleDataStore";
|
||||
import { useMemo } from "react";
|
||||
|
||||
export function useDamageLinesForAll(mode: 0 | 1 = 0) {
|
||||
const { turnHistory } = useBattleDataStore.getState();
|
||||
export function useDamageLinesForAll(mode: 1 | 2 = 1) {
|
||||
const { turnHistory, skillHistory } = useBattleDataStore.getState();
|
||||
|
||||
return useMemo(() => {
|
||||
const avatarMap = new Map<number, Map<number, number>>();
|
||||
|
||||
for (const turn of turnHistory) {
|
||||
if (!avatarMap.has(turn.avatarId)) {
|
||||
avatarMap.set(turn.avatarId, new Map());
|
||||
for (const skill of skillHistory) {
|
||||
if (!avatarMap.has(skill.avatarId)) {
|
||||
avatarMap.set(skill.avatarId, new Map());
|
||||
}
|
||||
|
||||
const charMap = avatarMap.get(turn.avatarId)!;
|
||||
const prev = charMap.get(turn.actionValue) || 0;
|
||||
charMap.set(turn.actionValue, prev + turn.totalDamage);
|
||||
const charMap = avatarMap.get(skill.avatarId)!;
|
||||
const actionValue = turnHistory[skill.turnBattleId].actionValue
|
||||
const prev = charMap.get(actionValue) || 0;
|
||||
charMap.set(actionValue, prev + skill.totalDamage);
|
||||
}
|
||||
|
||||
const result: Record<number, { x: number; y: number }[]> = {};
|
||||
@@ -27,7 +28,7 @@ export function useDamageLinesForAll(mode: 0 | 1 = 0) {
|
||||
if (mode === 1) {
|
||||
let cumulative = 0;
|
||||
result[avatarId] = points.map(p => {
|
||||
cumulative += p.y;
|
||||
cumulative += Number(p.y);
|
||||
return { x: p.x, y: Number(cumulative.toFixed(2)) };
|
||||
});
|
||||
} else {
|
||||
@@ -39,5 +40,5 @@ export function useDamageLinesForAll(mode: 0 | 1 = 0) {
|
||||
}
|
||||
|
||||
return result;
|
||||
}, [turnHistory, mode]);
|
||||
}, [turnHistory, skillHistory, mode]);
|
||||
}
|
||||
|
||||
@@ -1,79 +1,69 @@
|
||||
import useBattleDataStore from "@/stores/battleDataStore";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { useMemo } from "react";
|
||||
|
||||
|
||||
type Mode = 0 | 1 | 2;
|
||||
|
||||
function getChunkIndex(av: number, mode: Mode): number {
|
||||
let sum = 0;
|
||||
let idx = 0;
|
||||
|
||||
if (mode === 0) {
|
||||
while (sum <= av) {
|
||||
sum += 100;
|
||||
idx++;
|
||||
}
|
||||
} else if (mode === 1) {
|
||||
if (av < 150) return 0;
|
||||
sum = 150;
|
||||
idx = 1;
|
||||
while (sum <= av) {
|
||||
sum += 100;
|
||||
idx++;
|
||||
}
|
||||
} else {
|
||||
if (av < 150) return 0;
|
||||
if (av < 300) return 1;
|
||||
sum = 300;
|
||||
idx = 2;
|
||||
while (sum <= av) {
|
||||
sum += 100;
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
|
||||
return idx - 1;
|
||||
}
|
||||
|
||||
export function useDamagePerCycleForOne(avatarId: number, mode: Mode) {
|
||||
const { turnHistory } = useBattleDataStore.getState();
|
||||
const { skillHistory, turnHistory, maxCycle } = useBattleDataStore.getState();
|
||||
const transI18n = useTranslations("DataAnalysisPage");
|
||||
return useMemo(() => {
|
||||
const damageMap = new Map<string, number>();
|
||||
|
||||
skillHistory
|
||||
.filter(s => s.avatarId === avatarId)
|
||||
.forEach(s => {
|
||||
const turn = turnHistory[s.turnBattleId];
|
||||
if (!turn) return;
|
||||
|
||||
return useMemo(() => {
|
||||
const damageMap = new Map<number, number>();
|
||||
let key = '';
|
||||
if (mode === 0) {
|
||||
key = `${transI18n('cycle')} ${maxCycle-turn.cycleIndex} - ${transI18n('wave')} ${turn.waveIndex}`;
|
||||
} else if (mode === 1) {
|
||||
key = `${transI18n('cycle')} ${maxCycle-turn.cycleIndex}`;
|
||||
} else if (mode === 2) {
|
||||
key = `${transI18n('wave')} ${turn.waveIndex}`;
|
||||
}
|
||||
|
||||
turnHistory
|
||||
.filter(t => t.avatarId === avatarId)
|
||||
.forEach(t => {
|
||||
const idx = getChunkIndex(t.actionValue, mode);
|
||||
damageMap.set(idx, (damageMap.get(idx) || 0) + t.totalDamage);
|
||||
});
|
||||
damageMap.set(key, (damageMap.get(key) || 0) + s.totalDamage);
|
||||
});
|
||||
|
||||
const maxIndex = Math.max(...Array.from(damageMap.keys()), 0);
|
||||
const result = Array.from(damageMap.entries())
|
||||
.map(([x, y]) => ({ x, y }))
|
||||
.sort((a, b) => a.x.localeCompare(b.x, undefined, { numeric: true }));
|
||||
|
||||
return Array.from({ length: maxIndex + 1 }).map((_, i) => ({
|
||||
x: `${i + 1}`,
|
||||
y: damageMap.get(i) || 0,
|
||||
}));
|
||||
}, [avatarId, mode, turnHistory]);
|
||||
return result;
|
||||
}, [avatarId, mode, skillHistory, turnHistory, transI18n]);
|
||||
}
|
||||
|
||||
|
||||
export function useDamagePerCycleForAll(mode: Mode) {
|
||||
const { turnHistory } = useBattleDataStore.getState();
|
||||
|
||||
const { skillHistory, turnHistory, maxCycle } = useBattleDataStore.getState();
|
||||
const transI18n = useTranslations("DataAnalysisPage");
|
||||
return useMemo(() => {
|
||||
const damageMap = new Map<number, number>();
|
||||
|
||||
turnHistory.forEach(t => {
|
||||
const idx = getChunkIndex(t.actionValue, mode);
|
||||
damageMap.set(idx, (damageMap.get(idx) || 0) + t.totalDamage);
|
||||
});
|
||||
|
||||
const maxIndex = Math.max(...Array.from(damageMap.keys()), 0);
|
||||
|
||||
return Array.from({ length: maxIndex + 1 }).map((_, i) => ({
|
||||
x: `${i + 1}`,
|
||||
y: damageMap.get(i) || 0,
|
||||
}));
|
||||
}, [mode, turnHistory]);
|
||||
}
|
||||
const damageMap = new Map<string, number>();
|
||||
|
||||
skillHistory.forEach(s => {
|
||||
const turn = turnHistory[s.turnBattleId];
|
||||
if (!turn) return;
|
||||
|
||||
let key = '';
|
||||
if (mode === 0) {
|
||||
key = `${transI18n('cycle')} ${maxCycle-turn.cycleIndex} - ${transI18n('wave')} ${turn.waveIndex}`;
|
||||
} else if (mode === 1) {
|
||||
key = `${transI18n('cycle')} ${maxCycle-turn.cycleIndex}`;
|
||||
} else if (mode === 2) {
|
||||
key = `${transI18n('wave')} ${turn.waveIndex}`;
|
||||
}
|
||||
|
||||
damageMap.set(key, (damageMap.get(key) || 0) + s.totalDamage);
|
||||
});
|
||||
|
||||
const result = Array.from(damageMap.entries())
|
||||
.map(([x, y]) => ({ x, y }))
|
||||
.sort((a, b) => a.x.localeCompare(b.x, undefined, { numeric: true }));
|
||||
|
||||
return result;
|
||||
}, [mode, skillHistory, turnHistory, transI18n]);
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import { useMemo } from "react";
|
||||
import useBattleDataStore from "@/stores/battleDataStore";
|
||||
import {attackTypeToString} from "@/types";
|
||||
|
||||
export function useDamagePercentByType() {
|
||||
const { skillHistory } = useBattleDataStore.getState();
|
||||
|
||||
return useMemo(() => {
|
||||
const dmgByType = new Map<string, number>();
|
||||
|
||||
skillHistory.forEach(skill => {
|
||||
skill.damageDetail.forEach(detail => {
|
||||
const type = detail.damage_type;
|
||||
if (!type) return;
|
||||
dmgByType.set(attackTypeToString(type), (dmgByType.get(attackTypeToString(type)) || 0) + detail.damage);
|
||||
});
|
||||
});
|
||||
|
||||
const totalDmg = Array.from(dmgByType.values()).reduce((sum, val) => sum + val, 0);
|
||||
|
||||
return Array.from(dmgByType.entries()).map(([type, dmg]) => ({
|
||||
type,
|
||||
percent: totalDmg > 0 ? (dmg / totalDmg) * 100 : 0,
|
||||
}));
|
||||
}, [skillHistory]);
|
||||
}
|
||||
@@ -2,12 +2,12 @@ import useBattleDataStore from "@/stores/battleDataStore";
|
||||
import { useMemo } from "react";
|
||||
|
||||
export function useDamagePercentPerAvatar() {
|
||||
const { turnHistory } = useBattleDataStore.getState();
|
||||
const { skillHistory } = useBattleDataStore.getState();
|
||||
|
||||
return useMemo(() => {
|
||||
const dmgByAvatar = new Map<number, number>();
|
||||
|
||||
turnHistory.forEach(t => {
|
||||
skillHistory.forEach(t => {
|
||||
dmgByAvatar.set(t.avatarId, (dmgByAvatar.get(t.avatarId) || 0) + t.totalDamage);
|
||||
});
|
||||
|
||||
@@ -17,5 +17,5 @@ export function useDamagePercentPerAvatar() {
|
||||
avatarId,
|
||||
percent: totalDmg > 0 ? (dmg / totalDmg) * 100 : 0,
|
||||
}));
|
||||
}, [turnHistory]);
|
||||
}, [skillHistory]);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
"use client";
|
||||
import { useMemo } from "react";
|
||||
import useBattleDataStore from "@/stores/battleDataStore";
|
||||
import {attackTypeToString} from "@/types";
|
||||
|
||||
export function useDamageByTypeForAvatar(avatarId: number) {
|
||||
const { skillHistory } = useBattleDataStore.getState();
|
||||
|
||||
return useMemo(() => {
|
||||
const dmgMap = new Map<string, number>();
|
||||
|
||||
for (const skill of skillHistory) {
|
||||
if (skill.avatarId !== avatarId) continue;
|
||||
|
||||
for (const damage of skill.damageDetail) {
|
||||
const type = attackTypeToString(damage?.damage_type)?.toLowerCase() || "";
|
||||
dmgMap.set(type, (dmgMap.get(type) || 0) + damage.damage);
|
||||
}
|
||||
}
|
||||
|
||||
const labels = Array.from(dmgMap.keys());
|
||||
const damageValues = Array.from(dmgMap.values());
|
||||
|
||||
return { labels, damageValues };
|
||||
}, [avatarId, skillHistory]);
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
"use client";
|
||||
import { useMemo } from "react";
|
||||
import useBattleDataStore from "@/stores/battleDataStore";
|
||||
import {attackTypeToString} from "@/types";
|
||||
|
||||
export function useSkillDamageForAvatar(avatarId: number) {
|
||||
const { skillHistory } = useBattleDataStore.getState();
|
||||
|
||||
return useMemo(() => {
|
||||
const dmgMap = new Map<string, number>();
|
||||
|
||||
for (const skill of skillHistory) {
|
||||
if (skill.avatarId !== avatarId) continue;
|
||||
|
||||
const type = attackTypeToString(skill.skillType).toLowerCase();
|
||||
dmgMap.set(type, (dmgMap.get(type) || 0) + skill.totalDamage);
|
||||
}
|
||||
|
||||
const labels = Array.from(dmgMap.keys());
|
||||
const damageValues = Array.from(dmgMap.values());
|
||||
|
||||
return { labels, damageValues };
|
||||
}, [avatarId, skillHistory]);
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
"use client";
|
||||
import { useMemo } from "react";
|
||||
import useBattleDataStore from "@/stores/battleDataStore";
|
||||
|
||||
export function useSkillDamageByAvatar(avatarId: number) {
|
||||
const { turnHistory } = useBattleDataStore.getState();
|
||||
|
||||
return useMemo(() => {
|
||||
const skillTypes = ['technique', 'talent', 'basic', 'skill', 'ultimate', 'servant'];
|
||||
const dmgMap = new Map<string, number>();
|
||||
skillTypes.forEach((type) => dmgMap.set(type, 0));
|
||||
|
||||
for (const turn of turnHistory) {
|
||||
const type = turn.skillType.toLowerCase();
|
||||
if (turn.avatarId === avatarId && dmgMap.has(type)) {
|
||||
dmgMap.set(type, dmgMap.get(type)! + turn.totalDamage);
|
||||
}
|
||||
}
|
||||
|
||||
const labels = Array.from(dmgMap.keys());
|
||||
const damageValues = Array.from(dmgMap.values());
|
||||
|
||||
return { labels, damageValues };
|
||||
}, [avatarId, turnHistory]);
|
||||
}
|
||||
Reference in New Issue
Block a user