UPDATE: FIx bug
All checks were successful
Gitea Auto Deploy / Deploy-Container (push) Successful in 43s
All checks were successful
Gitea Auto Deploy / Deploy-Container (push) Successful in 43s
This commit is contained in:
@@ -8,17 +8,8 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Check out latest code
|
- uses: actions/checkout@v4
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Stop and remove old containers
|
- name: Deploy to Container
|
||||||
run: |
|
run: |
|
||||||
docker compose down || true
|
docker compose up -d --build --remove-orphans
|
||||||
|
|
||||||
- name: Remove unused Docker resources
|
|
||||||
run: |
|
|
||||||
docker system prune -a --volumes -f
|
|
||||||
|
|
||||||
- name: Build and restart containers
|
|
||||||
run: |
|
|
||||||
docker compose up -d
|
|
||||||
Binary file not shown.
Binary file not shown.
@@ -51,7 +51,7 @@ export default function Home() {
|
|||||||
setMapEnemy(monsterMap)
|
setMapEnemy(monsterMap)
|
||||||
};
|
};
|
||||||
fetchData();
|
fetchData();
|
||||||
}, [setListAvatar, setListEnemy]);
|
}, [setListAvatar, setListEnemy, setMapAvatar, setMapEnemy]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
window.dispatchEvent(new Event('resize'));
|
window.dispatchEvent(new Event('resize'));
|
||||||
|
|||||||
@@ -42,9 +42,9 @@ export default function CharacterCard({ data }: CharacterCardProps) {
|
|||||||
height={48}
|
height={48}
|
||||||
unoptimized
|
unoptimized
|
||||||
crossOrigin="anonymous"
|
crossOrigin="anonymous"
|
||||||
src={`/icon/${data.damageType.toLowerCase()}.webp`}
|
src={`/icon/${data?.damageType?.toLowerCase()}.webp`}
|
||||||
className="absolute top-0 left-0 w-6 h-6"
|
className="absolute top-0 left-0 w-6 h-6"
|
||||||
alt={data.damageType.toLowerCase()}
|
alt={data?.damageType?.toLowerCase()}
|
||||||
/>
|
/>
|
||||||
<Image
|
<Image
|
||||||
width={48}
|
width={48}
|
||||||
|
|||||||
@@ -29,8 +29,8 @@ export default function LineupBar() {
|
|||||||
const totalTurn = useCalcTotalTurnAvatar(selectedCharacter ? Number(selectedCharacter.id) : 0)
|
const totalTurn = useCalcTotalTurnAvatar(selectedCharacter ? Number(selectedCharacter.id) : 0)
|
||||||
|
|
||||||
|
|
||||||
const lineupAvatars = listAvatar.filter(item =>
|
const lineupAvatars = listAvatar?.filter(item =>
|
||||||
lineup.some(av => av.avatarId.toString() === item.id)
|
lineup?.some(av => av?.avatarId?.toString() === item.id)
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleShow = (modalId: string, item: CharacterBasic) => {
|
const handleShow = (modalId: string, item: CharacterBasic) => {
|
||||||
@@ -103,7 +103,7 @@ export default function LineupBar() {
|
|||||||
) : (
|
) : (
|
||||||
<div className="h-full w-full overflow-x-auto md:overflow-x-hidden md:overflow-y-auto rounded-lg">
|
<div className="h-full w-full overflow-x-auto md:overflow-x-hidden md:overflow-y-auto rounded-lg">
|
||||||
<div className="flex flex-nowrap md:grid md:grid-cols-1 w-fit md:w-full justify-items-center items-start gap-2">
|
<div className="flex flex-nowrap md:grid md:grid-cols-1 w-fit md:w-full justify-items-center items-start gap-2">
|
||||||
{lineupAvatars.map((item, index) => {
|
{lineupAvatars?.map((item, index) => {
|
||||||
const lastTurnAvatarId = turnHistory.findLast(i => i?.avatarId)?.avatarId || -1;
|
const lastTurnAvatarId = turnHistory.findLast(i => i?.avatarId)?.avatarId || -1;
|
||||||
const isLastTurn = item.id === lastTurnAvatarId.toString();
|
const isLastTurn = item.id === lastTurnAvatarId.toString();
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { useMemo } from "react";
|
|||||||
type Mode = 0 | 1 | 2;
|
type Mode = 0 | 1 | 2;
|
||||||
|
|
||||||
export function useDamagePerCycleForOne(avatarId: number, mode: Mode) {
|
export function useDamagePerCycleForOne(avatarId: number, mode: Mode) {
|
||||||
const { skillHistory, turnHistory, maxCycle } = useBattleDataStore.getState();
|
const { skillHistory, turnHistory } = useBattleDataStore.getState();
|
||||||
const transI18n = useTranslations("DataAnalysisPage");
|
const transI18n = useTranslations("DataAnalysisPage");
|
||||||
return useMemo(() => {
|
return useMemo(() => {
|
||||||
const damageMap = new Map<string, number>();
|
const damageMap = new Map<string, number>();
|
||||||
@@ -19,9 +19,9 @@ export function useDamagePerCycleForOne(avatarId: number, mode: Mode) {
|
|||||||
|
|
||||||
let key = '';
|
let key = '';
|
||||||
if (mode === 0) {
|
if (mode === 0) {
|
||||||
key = `${transI18n('cycle')} ${maxCycle-turn.cycleIndex} - ${transI18n('wave')} ${turn.waveIndex}`;
|
key = `${transI18n('cycle')} ${turn.cycleIndex} - ${transI18n('wave')} ${turn.waveIndex}`;
|
||||||
} else if (mode === 1) {
|
} else if (mode === 1) {
|
||||||
key = `${transI18n('cycle')} ${maxCycle-turn.cycleIndex}`;
|
key = `${transI18n('cycle')} ${turn.cycleIndex}`;
|
||||||
} else if (mode === 2) {
|
} else if (mode === 2) {
|
||||||
key = `${transI18n('wave')} ${turn.waveIndex}`;
|
key = `${transI18n('wave')} ${turn.waveIndex}`;
|
||||||
}
|
}
|
||||||
@@ -39,7 +39,7 @@ export function useDamagePerCycleForOne(avatarId: number, mode: Mode) {
|
|||||||
|
|
||||||
|
|
||||||
export function useDamagePerCycleForAll(mode: Mode) {
|
export function useDamagePerCycleForAll(mode: Mode) {
|
||||||
const { skillHistory, turnHistory, maxCycle } = useBattleDataStore.getState();
|
const { skillHistory, turnHistory } = useBattleDataStore.getState();
|
||||||
const transI18n = useTranslations("DataAnalysisPage");
|
const transI18n = useTranslations("DataAnalysisPage");
|
||||||
return useMemo(() => {
|
return useMemo(() => {
|
||||||
const damageMap = new Map<string, number>();
|
const damageMap = new Map<string, number>();
|
||||||
@@ -50,9 +50,9 @@ export function useDamagePerCycleForAll(mode: Mode) {
|
|||||||
|
|
||||||
let key = '';
|
let key = '';
|
||||||
if (mode === 0) {
|
if (mode === 0) {
|
||||||
key = `${transI18n('cycle')} ${maxCycle-turn.cycleIndex} - ${transI18n('wave')} ${turn.waveIndex}`;
|
key = `${transI18n('cycle')} ${turn.cycleIndex} - ${transI18n('wave')} ${turn.waveIndex}`;
|
||||||
} else if (mode === 1) {
|
} else if (mode === 1) {
|
||||||
key = `${transI18n('cycle')} ${maxCycle-turn.cycleIndex}`;
|
key = `${transI18n('cycle')} ${turn.cycleIndex}`;
|
||||||
} else if (mode === 2) {
|
} else if (mode === 2) {
|
||||||
key = `${transI18n('wave')} ${turn.waveIndex}`;
|
key = `${transI18n('wave')} ${turn.waveIndex}`;
|
||||||
}
|
}
|
||||||
@@ -66,4 +66,4 @@ export function useDamagePerCycleForAll(mode: Mode) {
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
}, [mode, skillHistory, turnHistory, transI18n]);
|
}, [mode, skillHistory, turnHistory, transI18n]);
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { DamageType, AvatarAnalysisJson, UseSkillType, BattleBeginType, BattleEndType, DamageDetailType, EntityDefeatedType, SetBattleLineupType, TurnBeginType, TurnEndType, UpdateCycleType, UpdateWaveType, VersionType, StatChangeType, UpdateTeamFormationType, Team } from '@/types';
|
import { DamageType, AvatarAnalysisJson, UseSkillType, BattleBeginType, BattleEndType, DamageDetailType, EntityDefeatedType, SetBattleLineupType, TurnBeginType, TurnEndType, UpdateCycleType, UpdateWaveType, VersionType, StatChangeType, UpdateTeamFormationType, Team, ParseAttackType } from '@/types';
|
||||||
import { InitializeEnemyType } from '@/types/enemy';
|
import { InitializeEnemyType } from '@/types/enemy';
|
||||||
import { AvatarBattleInfo, AvatarInfo, BattleDataStateJson, EnemyInfo, SkillBattleInfo, TurnBattleInfo } from '@/types/mics';
|
import { AvatarBattleInfo, AvatarInfo, BattleDataStateJson, EnemyInfo, SkillBattleInfo, TurnBattleInfo } from '@/types/mics';
|
||||||
import { create } from 'zustand'
|
import { create } from 'zustand'
|
||||||
@@ -54,10 +54,19 @@ const useBattleDataStore = create<BattleDataState>((set, get) => ({
|
|||||||
avatarDetail: undefined,
|
avatarDetail: undefined,
|
||||||
enemyDetail: undefined,
|
enemyDetail: undefined,
|
||||||
loadBattleDataFromJSON: (data: BattleDataStateJson) => {
|
loadBattleDataFromJSON: (data: BattleDataStateJson) => {
|
||||||
|
const skillHistory = data.skillHistory.map(it => {
|
||||||
|
it.damageDetail = it.damageDetail.map(it => {
|
||||||
|
return {
|
||||||
|
...it,
|
||||||
|
damage_type: ParseAttackType(it.damage_type)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return it
|
||||||
|
})
|
||||||
set({
|
set({
|
||||||
lineup: data.lineup,
|
lineup: data.lineup,
|
||||||
turnHistory: data.turnHistory,
|
turnHistory: data.turnHistory,
|
||||||
skillHistory: data.skillHistory,
|
skillHistory: skillHistory,
|
||||||
dataAvatar: data.dataAvatar,
|
dataAvatar: data.dataAvatar,
|
||||||
totalAV: data.totalAV,
|
totalAV: data.totalAV,
|
||||||
totalDamage: data.totalDamage,
|
totalDamage: data.totalDamage,
|
||||||
@@ -82,38 +91,36 @@ const useBattleDataStore = create<BattleDataState>((set, get) => ({
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
onBattleBeginService: (data: BattleBeginType) => {
|
onBattleBeginService: (data: BattleBeginType) => {
|
||||||
const current = get()
|
|
||||||
const updatedHistory = current.turnHistory.map(it => ({
|
|
||||||
...it,
|
|
||||||
cycleIndex: data.max_cycles
|
|
||||||
}))
|
|
||||||
set({
|
set({
|
||||||
maxWave: data.max_waves,
|
maxWave: data.max_waves,
|
||||||
maxCycle: data.max_cycles,
|
maxCycle: data.max_cycles
|
||||||
turnHistory: updatedHistory
|
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
onSetBattleLineupService: (data: SetBattleLineupType) => {
|
onSetBattleLineupService: (data: SetBattleLineupType) => {
|
||||||
const lineups: AvatarBattleInfo[] = []
|
const lineups: AvatarBattleInfo[] = []
|
||||||
for (const avatar of data.avatars) {
|
for (const avatar of data.avatars) {
|
||||||
lineups.push({ avatarId: avatar.id, isDie: false } as AvatarBattleInfo)
|
lineups.push({ avatarId: avatar.id, isDie: false } as AvatarBattleInfo)
|
||||||
}
|
}
|
||||||
set((state) => ({
|
set(() => ({
|
||||||
lineup: lineups,
|
lineup: lineups,
|
||||||
turnHistory: [{
|
turnHistory: [{
|
||||||
avatarId: -1,
|
avatarId: -1,
|
||||||
actionValue: 0,
|
actionValue: 0,
|
||||||
waveIndex: 1,
|
waveIndex: 1,
|
||||||
cycleIndex: state.maxCycle,
|
cycleIndex: 0,
|
||||||
} as TurnBattleInfo],
|
} as TurnBattleInfo],
|
||||||
skillHistory: [],
|
skillHistory: [],
|
||||||
totalAV: 0,
|
totalAV: 0,
|
||||||
totalDamage: 0,
|
totalDamage: 0,
|
||||||
damagePerAV: 0,
|
damagePerAV: 0,
|
||||||
cycleIndex: state.maxCycle,
|
cycleIndex: 0,
|
||||||
|
maxWave: Infinity,
|
||||||
|
maxCycle: Infinity,
|
||||||
waveIndex: 1,
|
waveIndex: 1,
|
||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
|
|
||||||
onDamageService: (data: DamageType) => {
|
onDamageService: (data: DamageType) => {
|
||||||
const skillHistory = get().skillHistory
|
const skillHistory = get().skillHistory
|
||||||
|
|
||||||
@@ -122,7 +129,11 @@ const useBattleDataStore = create<BattleDataState>((set, get) => ({
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
const newTh = [...skillHistory]
|
const newTh = [...skillHistory]
|
||||||
newTh[skillIdx].damageDetail.push({damage: data.damage, damage_type: data?.damage_type} as DamageDetailType)
|
newTh[skillIdx].damageDetail.push({
|
||||||
|
damage: data.damage,
|
||||||
|
overkill_damage: data.overkill_damage,
|
||||||
|
damage_type: ParseAttackType(data.damage_type ? data.damage_type : data.type),
|
||||||
|
} as DamageDetailType)
|
||||||
newTh[skillIdx].totalDamage += data.damage
|
newTh[skillIdx].totalDamage += data.damage
|
||||||
set({
|
set({
|
||||||
skillHistory: newTh,
|
skillHistory: newTh,
|
||||||
@@ -130,6 +141,7 @@ const useBattleDataStore = create<BattleDataState>((set, get) => ({
|
|||||||
damagePerAV: (get().totalDamage + data.damage) / (get().totalAV === 0 ? 1 : get().totalAV)
|
damagePerAV: (get().totalDamage + data.damage) / (get().totalAV === 0 ? 1 : get().totalAV)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
onTurnBeginService: (data: TurnBeginType) => {
|
onTurnBeginService: (data: TurnBeginType) => {
|
||||||
set((state) => ({
|
set((state) => ({
|
||||||
totalAV: data.action_value,
|
totalAV: data.action_value,
|
||||||
@@ -142,6 +154,7 @@ const useBattleDataStore = create<BattleDataState>((set, get) => ({
|
|||||||
} as TurnBattleInfo]
|
} as TurnBattleInfo]
|
||||||
}))
|
}))
|
||||||
},
|
},
|
||||||
|
|
||||||
onTurnEndService: (data: TurnEndType) => {
|
onTurnEndService: (data: TurnEndType) => {
|
||||||
set((state) => ({
|
set((state) => ({
|
||||||
totalDamage: state.totalDamage === data.turn_info.total_damage ? data.turn_info.total_damage : state.totalDamage,
|
totalDamage: state.totalDamage === data.turn_info.total_damage ? data.turn_info.total_damage : state.totalDamage,
|
||||||
@@ -150,6 +163,7 @@ const useBattleDataStore = create<BattleDataState>((set, get) => ({
|
|||||||
/ (data.turn_info.action_value === 0 ? 1 : data.turn_info.action_value)
|
/ (data.turn_info.action_value === 0 ? 1 : data.turn_info.action_value)
|
||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
|
|
||||||
onEntityDefeatedService: (data: EntityDefeatedType) => {
|
onEntityDefeatedService: (data: EntityDefeatedType) => {
|
||||||
let avatarDetail = get().avatarDetail
|
let avatarDetail = get().avatarDetail
|
||||||
let enemyDetail = get().enemyDetail
|
let enemyDetail = get().enemyDetail
|
||||||
@@ -165,38 +179,38 @@ const useBattleDataStore = create<BattleDataState>((set, get) => ({
|
|||||||
} else if (data.killer.team === "Enemy" && avatarDetail[data.entity_defeated.uid]) {
|
} else if (data.killer.team === "Enemy" && avatarDetail[data.entity_defeated.uid]) {
|
||||||
avatarDetail[data.entity_defeated.uid].isDie = true
|
avatarDetail[data.entity_defeated.uid].isDie = true
|
||||||
avatarDetail[data.entity_defeated.uid].killer_uid = data.killer.uid
|
avatarDetail[data.entity_defeated.uid].killer_uid = data.killer.uid
|
||||||
} else {
|
|
||||||
console.error("onEntityDefeatedService", data)
|
|
||||||
console.error("onEntityDefeatedService", enemyDetail)
|
|
||||||
console.error("onEntityDefeatedService", avatarDetail)
|
|
||||||
}
|
}
|
||||||
set({
|
set({
|
||||||
avatarDetail: avatarDetail,
|
avatarDetail: avatarDetail,
|
||||||
enemyDetail: enemyDetail
|
enemyDetail: enemyDetail
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
onUseSkillService: (data: UseSkillType) => {
|
onUseSkillService: (data: UseSkillType) => {
|
||||||
set((state) => ({
|
set((state) => ({
|
||||||
skillHistory: [...state.skillHistory, {
|
skillHistory: [...state.skillHistory, {
|
||||||
avatarId: data.avatar.uid,
|
avatarId: data.avatar.uid,
|
||||||
damageDetail: [],
|
damageDetail: [],
|
||||||
totalDamage: 0,
|
totalDamage: 0,
|
||||||
skillType: data.skill.type,
|
skillType: ParseAttackType(data.skill.type),
|
||||||
skillName: data.skill.name,
|
skillName: data.skill.name,
|
||||||
turnBattleId: state.turnHistory.length-1
|
turnBattleId: state.turnHistory.length - 1
|
||||||
} as SkillBattleInfo]
|
} as SkillBattleInfo]
|
||||||
}))
|
}))
|
||||||
},
|
},
|
||||||
|
|
||||||
onUpdateWaveService: (data: UpdateWaveType) => {
|
onUpdateWaveService: (data: UpdateWaveType) => {
|
||||||
set({
|
set({
|
||||||
waveIndex: data.wave
|
waveIndex: data.wave
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
onUpdateCycleService: (data: UpdateCycleType) => {
|
onUpdateCycleService: (data: UpdateCycleType) => {
|
||||||
set({
|
set({
|
||||||
cycleIndex: data.cycle
|
cycleIndex: data.cycle
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
onStatChange: (data: StatChangeType) => {
|
onStatChange: (data: StatChangeType) => {
|
||||||
let avatarDetail = get().avatarDetail
|
let avatarDetail = get().avatarDetail
|
||||||
let enemyDetail = get().enemyDetail
|
let enemyDetail = get().enemyDetail
|
||||||
@@ -206,8 +220,34 @@ const useBattleDataStore = create<BattleDataState>((set, get) => ({
|
|||||||
if (!avatarDetail) {
|
if (!avatarDetail) {
|
||||||
avatarDetail = {} as Record<number, AvatarInfo>
|
avatarDetail = {} as Record<number, AvatarInfo>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let key: string;
|
||||||
|
let value: number;
|
||||||
|
if (data.property) {
|
||||||
|
key = data.property.type;
|
||||||
|
value = data.property.value;
|
||||||
|
} else if (data.stat) {
|
||||||
|
if (
|
||||||
|
data.stat &&
|
||||||
|
typeof data.stat === 'object' &&
|
||||||
|
'type' in data.stat &&
|
||||||
|
'value' in data.stat &&
|
||||||
|
typeof data.stat.type === 'string'
|
||||||
|
) {
|
||||||
|
key = data.stat.type;
|
||||||
|
value = Number(data.stat.value);
|
||||||
|
} else {
|
||||||
|
const entries = Object.entries(data.stat);
|
||||||
|
if (entries.length === 0) return;
|
||||||
|
[key, value] = entries[0] as [string, number];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key === "CurrentHP") key = "HP";
|
||||||
|
|
||||||
if (data.entity.team === "Player") {
|
if (data.entity.team === "Player") {
|
||||||
const [key, value] = Object.entries(data.stat)[0]
|
|
||||||
const uid = data.entity.uid;
|
const uid = data.entity.uid;
|
||||||
|
|
||||||
if (!avatarDetail[uid]) {
|
if (!avatarDetail[uid]) {
|
||||||
@@ -221,11 +261,10 @@ const useBattleDataStore = create<BattleDataState>((set, get) => ({
|
|||||||
}
|
}
|
||||||
avatarDetail[uid].stats[key] = value
|
avatarDetail[uid].stats[key] = value
|
||||||
avatarDetail[uid].statsHistory.push({
|
avatarDetail[uid].statsHistory.push({
|
||||||
stats: data.stat,
|
stats: { [key]: value },
|
||||||
turnBattleId: get().turnHistory.length-1
|
turnBattleId: get().turnHistory.length - 1
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
const [key, value] = Object.entries(data.stat)[0]
|
|
||||||
const uid = data.entity.uid;
|
const uid = data.entity.uid;
|
||||||
|
|
||||||
if (!enemyDetail[uid]) {
|
if (!enemyDetail[uid]) {
|
||||||
@@ -244,8 +283,8 @@ const useBattleDataStore = create<BattleDataState>((set, get) => ({
|
|||||||
}
|
}
|
||||||
enemyDetail[uid].stats[key] = value
|
enemyDetail[uid].stats[key] = value
|
||||||
enemyDetail[uid].statsHistory.push({
|
enemyDetail[uid].statsHistory.push({
|
||||||
stats: data.stat,
|
stats: { [key]: value },
|
||||||
turnBattleId: get().turnHistory.length-1
|
turnBattleId: get().turnHistory.length - 1
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
set({
|
set({
|
||||||
@@ -267,7 +306,7 @@ const useBattleDataStore = create<BattleDataState>((set, get) => ({
|
|||||||
if (data.team === Team.Enemy) {
|
if (data.team === Team.Enemy) {
|
||||||
for (let i = 0; i < data.entities.length; i++) {
|
for (let i = 0; i < data.entities.length; i++) {
|
||||||
const entity = data.entities[i];
|
const entity = data.entities[i];
|
||||||
if (entity.team === Team.Enemy && enemyDetail[entity.uid]) {
|
if (entity.team === Team.Enemy && enemyDetail?.[entity.uid]) {
|
||||||
enemyDetail[entity.uid].positionIndex = i
|
enemyDetail[entity.uid].positionIndex = i
|
||||||
enemyDetail[entity.uid].waveIndex = get().waveIndex
|
enemyDetail[entity.uid].waveIndex = get().waveIndex
|
||||||
}
|
}
|
||||||
@@ -280,20 +319,31 @@ const useBattleDataStore = create<BattleDataState>((set, get) => ({
|
|||||||
enemyDetail: enemyDetail
|
enemyDetail: enemyDetail
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
onInitializeEnemyService: (data: InitializeEnemyType) => {
|
onInitializeEnemyService: (data: InitializeEnemyType) => {
|
||||||
const enemyDetail = get().enemyDetail
|
const enemyDetail = get().enemyDetail
|
||||||
if (!enemyDetail) {
|
if (!enemyDetail) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
let maxHP = 0;
|
||||||
|
let level = 0;
|
||||||
|
if ('properties' in data.enemy.base_stats) {
|
||||||
|
maxHP = data.enemy.base_stats.properties["MaxHP"] || 0;
|
||||||
|
level = data.enemy.base_stats.properties["Level"] || 0;
|
||||||
|
} else {
|
||||||
|
maxHP = data.enemy.base_stats.hp || data.enemy.base_stats.CurrentHP || 0;
|
||||||
|
level = data.enemy.base_stats.level;
|
||||||
|
}
|
||||||
|
|
||||||
enemyDetail[data.enemy.uid] = {
|
enemyDetail[data.enemy.uid] = {
|
||||||
id: data.enemy.id,
|
id: data.enemy.id,
|
||||||
isDie: false,
|
isDie: false,
|
||||||
killer_uid: -1,
|
killer_uid: -1,
|
||||||
positionIndex: enemyDetail[data.enemy.uid].positionIndex,
|
positionIndex: enemyDetail?.[data.enemy.uid]?.positionIndex || 0,
|
||||||
waveIndex: enemyDetail[data.enemy.uid].waveIndex,
|
waveIndex: get().waveIndex,
|
||||||
name: data.enemy.name,
|
name: data.enemy.name,
|
||||||
maxHP: data.enemy.base_stats.hp,
|
maxHP: maxHP,
|
||||||
level: data.enemy.base_stats.level,
|
level: level,
|
||||||
stats: {},
|
stats: {},
|
||||||
statsHistory: []
|
statsHistory: []
|
||||||
}
|
}
|
||||||
@@ -301,6 +351,7 @@ const useBattleDataStore = create<BattleDataState>((set, get) => ({
|
|||||||
enemyDetail: enemyDetail
|
enemyDetail: enemyDetail
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
onBattleEndService: (data: BattleEndType) => {
|
onBattleEndService: (data: BattleEndType) => {
|
||||||
const lineups: AvatarBattleInfo[] = []
|
const lineups: AvatarBattleInfo[] = []
|
||||||
for (const avatar of data.avatars) {
|
for (const avatar of data.avatars) {
|
||||||
|
|||||||
@@ -3,12 +3,15 @@ import { EntityType } from "./entity";
|
|||||||
export interface DamageType {
|
export interface DamageType {
|
||||||
attacker: EntityType;
|
attacker: EntityType;
|
||||||
damage: number;
|
damage: number;
|
||||||
damage_type?: AttackType
|
overkill_damage?: number;
|
||||||
|
damage_type?: AttackType | string;
|
||||||
|
type?: AttackType | string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DamageDetailType {
|
export interface DamageDetailType {
|
||||||
damage: number;
|
damage: number;
|
||||||
damage_type?: AttackType
|
overkill_damage?: number;
|
||||||
|
damage_type?: AttackType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -30,10 +33,53 @@ export enum AttackType {
|
|||||||
ElationDamage = 14
|
ElationDamage = 14
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const attackTypeMap: Record<string, AttackType> = {
|
||||||
|
Talent: AttackType.Unknown,
|
||||||
|
Basic: AttackType.Normal,
|
||||||
|
Skill: AttackType.BPSkill,
|
||||||
|
Ultimate: AttackType.Ultra,
|
||||||
|
QTE: AttackType.QTE,
|
||||||
|
DOT: AttackType.DOT,
|
||||||
|
DoT: AttackType.DOT,
|
||||||
|
Pursued: AttackType.Pursued,
|
||||||
|
Additional: AttackType.Pursued,
|
||||||
|
Technique: AttackType.Maze,
|
||||||
|
MazeNormal: AttackType.MazeNormal,
|
||||||
|
"Follow-up": AttackType.Insert,
|
||||||
|
"Follow-Up": AttackType.Insert,
|
||||||
|
"Elemental Damage": AttackType.ElementDamage,
|
||||||
|
Break: AttackType.ElementDamage,
|
||||||
|
Level: AttackType.Level,
|
||||||
|
Servant: AttackType.Servant,
|
||||||
|
"True Damage": AttackType.TrueDamage,
|
||||||
|
True: AttackType.TrueDamage,
|
||||||
|
"Elation Damage": AttackType.ElationDamage,
|
||||||
|
Elation: AttackType.ElationDamage,
|
||||||
|
};
|
||||||
|
|
||||||
|
export function ParseAttackType(type: AttackType | string | undefined): AttackType {
|
||||||
|
if (type === undefined || type === null) {
|
||||||
|
return AttackType.Unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof type === "number") {
|
||||||
|
return type in AttackType ? type : AttackType.Unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
const num = Number(type);
|
||||||
|
if (!isNaN(num)) {
|
||||||
|
return num in AttackType ? num as AttackType : AttackType.Unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
return attackTypeMap[type] ?? AttackType.Unknown;
|
||||||
|
}
|
||||||
|
|
||||||
export function attackTypeToString(type: AttackType | undefined): string {
|
export function attackTypeToString(type: AttackType | undefined): string {
|
||||||
if (type === undefined) {
|
if (type === undefined) {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case AttackType.Unknown: return "Talent";
|
case AttackType.Unknown: return "Talent";
|
||||||
case AttackType.Normal: return "Basic";
|
case AttackType.Normal: return "Basic";
|
||||||
|
|||||||
@@ -1,10 +1,14 @@
|
|||||||
import { StatsType } from "./stat";
|
import { StatsType } from "./stat";
|
||||||
|
|
||||||
|
export interface BattleStatsType {
|
||||||
|
properties: Record<string, number>;
|
||||||
|
}
|
||||||
|
|
||||||
export interface EnemyType {
|
export interface EnemyType {
|
||||||
id: number;
|
id: number;
|
||||||
uid: number;
|
uid: number;
|
||||||
name: string;
|
name: string;
|
||||||
base_stats: StatsType
|
base_stats: BattleStatsType | StatsType;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface InitializeEnemyType {
|
export interface InitializeEnemyType {
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { EntityType } from "./entity";
|
|||||||
|
|
||||||
export interface SkillInfo {
|
export interface SkillInfo {
|
||||||
name: string;
|
name: string;
|
||||||
type: AttackType;
|
type: AttackType | string;
|
||||||
skill_config_id: number;
|
skill_config_id: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,21 @@
|
|||||||
import { EntityType } from "./entity";
|
import { EntityType } from "./entity";
|
||||||
|
|
||||||
export type StatType = Record<string, number>
|
export type StatType = Record<string, number> | { value: number; type: string };
|
||||||
|
|
||||||
|
export interface PropertyType {
|
||||||
|
value: number;
|
||||||
|
type: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface StatsType {
|
export interface StatsType {
|
||||||
level: number;
|
level: number;
|
||||||
hp: number;
|
hp: number;
|
||||||
|
CurrentHP?: number;
|
||||||
|
MaxHP?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface StatChangeType {
|
export interface StatChangeType {
|
||||||
entity: EntityType,
|
entity: EntityType;
|
||||||
stat: StatType,
|
stat?: StatType;
|
||||||
|
property?: PropertyType;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user