UPDATE: New monster data
All checks were successful
Gitea Auto Deploy / Deploy-Container (push) Successful in 1m20s

This commit is contained in:
2026-03-17 00:45:23 +07:00
parent d27b96d023
commit 319ad79233
125 changed files with 2718 additions and 917593 deletions

View File

@@ -2,115 +2,117 @@
import { useEffect, useMemo } from "react";
import SelectCustomText from "../select/customSelectText";
import useEventStore from "@/stores/eventStore";
import { getLocaleName, replaceByParam } from "@/helper";
import { calcMonsterStats, getLocaleName, replaceByParam } from "@/helper";
import useLocaleStore from "@/stores/localeStore";
import useUserDataStore from "@/stores/userDataStore";
import useMonsterStore from "@/stores/monsterStore";
import Image from "next/image";
import useMazeStore from "@/stores/mazeStore";
import { useTranslations } from "next-intl";
import { MonsterStore } from "@/types";
import useDetailDataStore from "@/stores/detailDataStore";
export default function MocBar() {
const { MOCEvent, mapMOCInfo } = useEventStore()
const { mapMonster } = useMonsterStore()
const { locale } = useLocaleStore()
const {
moc_config,
setMocConfig
} = useUserDataStore()
const { MOC } = useMazeStore()
const { mapMonster, mapMoc, damageType, hardLevelConfig, eliteConfig } = useDetailDataStore()
const transI18n = useTranslations("DataPage")
const challengeSelected = useMemo(() => {
return mapMOCInfo[moc_config.event_id.toString()]?.find((moc) => moc.Id === moc_config.challenge_id)
}, [moc_config, mapMOCInfo])
return mapMoc[moc_config.event_id.toString()]?.Level.find((moc) => moc.ID === moc_config.challenge_id)
}, [moc_config, mapMoc])
const eventSelected = useMemo(() => {
return mapMoc[moc_config.event_id.toString()]
}, [moc_config, mapMoc])
useEffect(() => {
const challenge = mapMOCInfo[moc_config.event_id.toString()]?.find((moc) => moc.Id === moc_config.challenge_id)
if (moc_config.event_id !== 0 && moc_config.challenge_id !== 0 && challenge) {
const newBattleConfig = structuredClone(moc_config)
newBattleConfig.cycle_count = 0
if (moc_config.use_cycle_count) {
newBattleConfig.cycle_count = challenge.Countdown
}
newBattleConfig.blessings = []
if (moc_config.use_turbulence_buff && MOC[moc_config.challenge_id.toString()]) {
if (!challengeSelected || moc_config.event_id === 0 || moc_config.challenge_id === 0) return
const newBattleConfig = structuredClone(moc_config)
newBattleConfig.cycle_count = 0
if (moc_config.use_cycle_count) {
newBattleConfig.cycle_count = challengeSelected.TurnLimit
}
newBattleConfig.blessings = []
if (moc_config.use_turbulence_buff && challengeSelected) {
challengeSelected.MazeBuff.map((item) => {
newBattleConfig.blessings.push({
id: Number(MOC[moc_config.challenge_id.toString()].maze_buff),
id: item.ID,
level: 1
})
}
newBattleConfig.monsters = []
newBattleConfig.stage_id = 0
if ((moc_config.floor_side === "Upper" || moc_config.floor_side === "Upper -> Lower") && challenge.EventIDList1.length > 0) {
newBattleConfig.stage_id = challenge.EventIDList1[0].StageID
for (const wave of challenge.EventIDList1[0].MonsterList) {
const newWave: MonsterStore[] = []
for (const value of Object.values(wave)) {
newWave.push({
monster_id: Number(value),
level: challenge.EventIDList1[0].Level,
amount: 1,
})
}
newBattleConfig.monsters.push(newWave)
}
}
if ((moc_config.floor_side === "Lower" || moc_config.floor_side === "Lower -> Upper") && challenge.EventIDList2.length > 0) {
newBattleConfig.stage_id = challenge.EventIDList2[0].StageID
for (const wave of challenge.EventIDList2[0].MonsterList) {
const newWave: MonsterStore[] = []
for (const value of Object.values(wave)) {
newWave.push({
monster_id: Number(value),
level: challenge.EventIDList2[0].Level,
amount: 1,
})
}
newBattleConfig.monsters.push(newWave)
}
}
if (moc_config.floor_side === "Lower -> Upper" && challenge.EventIDList1.length > 0) {
for (const wave of challenge.EventIDList1[0].MonsterList) {
const newWave: MonsterStore[] = []
for (const value of Object.values(wave)) {
newWave.push({
monster_id: Number(value),
level: challenge.EventIDList1[0].Level,
amount: 1,
})
}
newBattleConfig.monsters.push(newWave)
}
} else if (moc_config.floor_side === "Upper -> Lower" && challenge.EventIDList2.length > 0) {
for (const wave of challenge.EventIDList2[0].MonsterList) {
const newWave: MonsterStore[] = []
for (const value of Object.values(wave)) {
newWave.push({
monster_id: Number(value),
level: challenge.EventIDList2[0].Level,
amount: 1,
})
}
newBattleConfig.monsters.push(newWave)
}
}
setMocConfig(newBattleConfig)
})
}
newBattleConfig.monsters = []
newBattleConfig.stage_id = 0
if ((moc_config.floor_side === "Upper" || moc_config.floor_side === "Upper -> Lower") && challengeSelected.EventList1.length > 0) {
newBattleConfig.stage_id = challengeSelected.EventList1[0].ID
for (const wave of challengeSelected.EventList1[0].MonsterList) {
const newWave: MonsterStore[] = []
for (const value of Object.values(wave)) {
newWave.push({
monster_id: value,
level: challengeSelected.EventList1[0].Level,
amount: 1,
})
}
newBattleConfig.monsters.push(newWave)
}
}
if ((moc_config.floor_side === "Lower" || moc_config.floor_side === "Lower -> Upper") && challengeSelected.EventList2.length > 0) {
newBattleConfig.stage_id = challengeSelected.EventList2[0].ID
for (const wave of challengeSelected.EventList2[0].MonsterList) {
const newWave: MonsterStore[] = []
for (const value of Object.values(wave)) {
newWave.push({
monster_id: value,
level: challengeSelected.EventList2[0].Level,
amount: 1,
})
}
newBattleConfig.monsters.push(newWave)
}
}
if (moc_config.floor_side === "Lower -> Upper" && challengeSelected.EventList1.length > 0) {
for (const wave of challengeSelected.EventList1[0].MonsterList) {
const newWave: MonsterStore[] = []
for (const value of Object.values(wave)) {
newWave.push({
monster_id: value,
level: challengeSelected.EventList1[0].Level,
amount: 1,
})
}
newBattleConfig.monsters.push(newWave)
}
} else if (moc_config.floor_side === "Upper -> Lower" && challengeSelected.EventList2.length > 0) {
for (const wave of challengeSelected.EventList2[0].MonsterList) {
const newWave: MonsterStore[] = []
for (const value of Object.values(wave)) {
newWave.push({
monster_id: value,
level: challengeSelected.EventList2[0].Level,
amount: 1,
})
}
newBattleConfig.monsters.push(newWave)
}
}
setMocConfig(newBattleConfig)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [
moc_config.event_id,
moc_config.challenge_id,
moc_config.floor_side,
mapMOCInfo,
MOC,
moc_config.use_cycle_count,
moc_config.use_turbulence_buff,
mapMoc,
])
if (!MOCEvent) return null
if (!mapMoc) return null
return (
<div className="py-8 relative">
@@ -118,10 +120,10 @@ export default function MocBar() {
<div className="rounded-xl p-4 mb-2 border border-warning">
<div className="mb-4 w-full">
<SelectCustomText
customSet={MOCEvent.map((moc) => ({
id: moc.id,
name: getLocaleName(locale, moc),
time: `${moc.begin} - ${moc.end}`,
customSet={Object.values(mapMoc).sort((a, b) => b.ID - a.ID).map((moc) => ({
id: moc.ID.toString(),
name: getLocaleName(locale, moc.Name),
time: `${moc.BeginTime} - ${moc.EndTime}`,
}))}
excludeSet={[]}
selectedCustomSet={moc_config.event_id.toString()}
@@ -129,7 +131,7 @@ export default function MocBar() {
setSelectedCustomSet={(id) => setMocConfig({
...moc_config,
event_id: Number(id),
challenge_id: mapMOCInfo[Number(id)]?.slice(-1)[0]?.Id || 0,
challenge_id: mapMoc[Number(id)]?.Level.at(-1)?.ID || 0,
})}
/>
</div>
@@ -149,8 +151,8 @@ export default function MocBar() {
})}
>
<option value={0} disabled={true}>Select a Floor</option>
{mapMOCInfo[moc_config.event_id.toString()]?.map((moc) => (
<option key={moc.Id} value={moc.Id}>{moc.Id % 100}</option>
{eventSelected?.Level?.map((moc) => (
<option key={moc.ID} value={moc.ID}>{getLocaleName(locale, moc.Name)}</option>
))}
</select>
</div>
@@ -205,16 +207,19 @@ export default function MocBar() {
{transI18n("useTurbulenceBuff")}
</span>
</div>
{challengeSelected && challengeSelected?.Desc ? (
<div
className="text-base"
dangerouslySetInnerHTML={{
__html: replaceByParam(
challengeSelected?.Desc || "",
challengeSelected?.Param || []
)
}}
/>
{challengeSelected ? (
challengeSelected.MazeBuff.map((buff, i) => (
<div
key={i}
className="text-base"
dangerouslySetInnerHTML={{
__html: replaceByParam(
getLocaleName(locale, buff?.Desc) || "",
buff?.Param || []
)
}}
/>
))
) : (
<div className="text-base">{transI18n("noTurbulenceBuff")}</div>
)}
@@ -228,48 +233,85 @@ export default function MocBar() {
<div className="rounded-xl p-4 mt-2 border border-warning">
<h2 className="text-2xl font-bold mb-6 text-info">{transI18n("firstHalfEnemies")}</h2>
{challengeSelected && challengeSelected?.EventIDList1?.length > 0 && challengeSelected?.EventIDList1[0].MonsterList.map((wave, waveIndex) => (
{challengeSelected && challengeSelected?.EventList1?.length > 0 && challengeSelected?.EventList1?.[0]?.MonsterList?.map((wave, waveIndex) => (
<div key={waveIndex} className="mb-6">
<h3 className="text-lg font-semibold mb-t">{transI18n("wave")} {waveIndex + 1}</h3>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
{Object.values(wave).map((waveValue, enemyIndex) => (
<div
key={enemyIndex}
className="rounded-xl p-2 border border-white/10 shadow-md hover:border-white/20 hover:shadow-lg transition"
>
<div className="flex items-center space-x-3">
<div className="relative w-20 h-20 rounded-full overflow-hidden shrink-0 border border-white/10 shadow-sm">
{mapMonster?.[waveValue.toString()]?.icon && <Image
unoptimized
crossOrigin="anonymous"
src={`${process.env.CDN_URL}/${mapMonster?.[waveValue.toString()]?.icon}`}
alt="Enemy Icon"
width={376}
height={512}
className="w-full h-full object-cover"
/>}
<h3 className="text-lg font-semibold">{transI18n("wave")} {waveIndex + 1}</h3>
<div className="flex flex-wrap gap-2 mt-2">
{Object.values(wave).map((waveValue, enemyIndex) => {
const monsterStats = calcMonsterStats(
mapMonster?.[waveValue.toString()],
challengeSelected?.EventList1?.[0]?.EliteGroup,
challengeSelected?.EventList1?.[0]?.HardLevelGroup,
challengeSelected?.EventList1?.[0]?.Level,
hardLevelConfig,
eliteConfig
);
return (
<div
key={enemyIndex}
className="group relative flex flex-col w-40 bg-base-100 rounded-2xl border border-base-300 shadow-md"
>
<div className="badge badge-warning badge-sm font-bold absolute top-2 right-2 z-10 shadow-sm">
Lv. {challengeSelected?.EventList1[0].Level}
</div>
<div className="flex flex-col">
<div className="text-sm font-semibold">Lv. {challengeSelected?.EventIDList1[0].Level}</div>
<div className="flex items-center space-x-1 mt-1">
{mapMonster?.[waveValue.toString()]?.weak?.map((icon, iconIndex) => (
<div className="relative w-full h-20 bg-base-200 flex items-center justify-center p-4 rounded-t-2xl">
{mapMonster?.[waveValue.toString()]?.Image?.IconPath && (
<div className="relative w-16 h-16 rounded-full border-2 border-base-300 shadow-md overflow-hidden group-hover:scale-110 transition-transform duration-300 bg-base-100">
<Image
unoptimized
crossOrigin="anonymous"
src={`/icon/${icon.toLowerCase()}.webp`}
alt={icon}
className="h-7 w-7 2xl:h-10 2xl:w-10 object-contain rounded-md border border-white/20 shadow-sm"
width={200}
height={200}
key={iconIndex}
src={`${process.env.CDN_URL}/${mapMonster?.[waveValue.toString()]?.Image?.IconPath}`}
alt="Enemy Icon"
width={150}
height={150}
className="w-full h-full object-cover"
/>
))}
</div>
)}
</div>
<div className="flex flex-col px-1 pb-2 pt-2">
<div className="flex flex-col space-y-1.5">
<div className="flex justify-between items-center bg-base-200 px-2.5 py-1.5 rounded-lg">
<span className="text-xs font-semibold text-error">HP</span>
<span className="text-sm font-bold text-base-content">{monsterStats.hp.toLocaleString(undefined, { maximumFractionDigits: 0 })}</span>
</div>
<div className="flex justify-between items-center bg-base-200 px-2.5 py-1.5 rounded-lg">
<span className="text-xs font-semibold text-info">Speed</span>
<span className="text-sm font-bold text-base-content">{monsterStats.spd.toLocaleString(undefined, { maximumFractionDigits: 0 })}</span>
</div>
<div className="flex justify-between items-center bg-base-200 px-2.5 py-1.5 rounded-lg">
<span className="text-xs font-semibold text-base-content/70">Toughness</span>
<span className="text-sm font-bold text-base-content">{monsterStats.stance.toLocaleString(undefined, { maximumFractionDigits: 0 })}</span>
</div>
</div>
<div className="mt-2 pt-2 border-t border-base-300 flex flex-col items-center">
<span className="text-[10px] text-base-content/60 font-bold uppercase tracking-widest mb-1.5">
Weakness
</span>
<div className="flex items-center justify-center gap-1.5 flex-wrap">
{mapMonster?.[waveValue.toString()]?.StanceWeakList?.map((icon, iconIndex) => (
<Image
key={iconIndex}
unoptimized
crossOrigin="anonymous"
src={`${process.env.CDN_URL}/${damageType[icon]?.Icon}`}
alt={icon}
width={40}
height={40}
className="h-6 w-6 object-contain rounded-full bg-base-300 border border-base-content/10 p-0.5 shadow-sm hover:scale-110 transition-transform"
/>
))}
</div>
</div>
</div>
</div>
</div>
))}
)
})}
</div>
</div>
))}
@@ -279,49 +321,85 @@ export default function MocBar() {
<div className="rounded-xl p-4 mt-2 border border-warning">
<h2 className="text-2xl font-bold mb-6 text-info">{transI18n("secondHalfEnemies")}</h2>
{challengeSelected && challengeSelected?.EventIDList2?.length > 0 && challengeSelected?.EventIDList2[0].MonsterList.map((wave, waveIndex) => (
{challengeSelected && challengeSelected?.EventList2?.length > 0 && challengeSelected?.EventList2?.[0]?.MonsterList?.map((wave, waveIndex) => (
<div key={waveIndex} className="mb-6">
<h3 className="text-lg font-semibold mb-t">{transI18n("wave")} {waveIndex + 1}</h3>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
{Object.values(wave).map((waveValue, enemyIndex) => (
<div
key={enemyIndex}
className="rounded-xl p-2 border border-white/10 shadow-md hover:border-white/20 hover:shadow-lg transition"
>
<div className="flex items-center space-x-3">
<div className="relative w-20 h-20 rounded-full overflow-hidden shrink-0 border border-white/10 shadow-sm">
{mapMonster?.[waveValue.toString()]?.icon && <Image
unoptimized
crossOrigin="anonymous"
src={`${process.env.CDN_URL}/${mapMonster?.[waveValue.toString()]?.icon}`}
alt="Enemy Icon"
width={376}
height={512}
className="w-full h-full object-cover"
/>}
<h3 className="text-lg font-semibold">{transI18n("wave")} {waveIndex + 1}</h3>
<div className="flex flex-wrap gap-2 mt-2">
{Object.values(wave).map((waveValue, enemyIndex) => {
const monsterStats = calcMonsterStats(
mapMonster?.[waveValue.toString()],
challengeSelected?.EventList2?.[0]?.EliteGroup,
challengeSelected?.EventList2?.[0]?.HardLevelGroup,
challengeSelected?.EventList2?.[0]?.Level,
hardLevelConfig,
eliteConfig
);
return (
<div
key={enemyIndex}
className="group relative flex flex-col w-40 bg-base-100 rounded-2xl border border-base-300 shadow-md"
>
<div className="badge badge-warning badge-sm font-bold absolute top-2 right-2 z-10 shadow-sm">
Lv. {challengeSelected?.EventList2[0].Level}
</div>
<div className="flex flex-col">
<div className="text-sm font-semibold">Lv. {challengeSelected?.EventIDList1[0].Level}</div>
<div className="flex items-center space-x-1 mt-1">
{mapMonster?.[waveValue.toString()]?.weak?.map((icon, iconIndex) => (
<div className="relative w-full h-20 bg-base-200 flex items-center justify-center p-4 rounded-t-2xl">
{mapMonster?.[waveValue.toString()]?.Image?.IconPath && (
<div className="relative w-16 h-16 rounded-full border-2 border-base-300 shadow-md overflow-hidden group-hover:scale-110 transition-transform duration-300 bg-base-100">
<Image
unoptimized
crossOrigin="anonymous"
src={`/icon/${icon.toLowerCase()}.webp`}
alt={icon}
className="h-7 w-7 2xl:h-10 2xl:w-10 object-contain rounded-md border border-white/20 shadow-sm"
width={200}
height={200}
key={iconIndex}
src={`${process.env.CDN_URL}/${mapMonster?.[waveValue.toString()]?.Image?.IconPath}`}
alt="Enemy Icon"
width={150}
height={150}
className="w-full h-full object-cover"
/>
))}
</div>
)}
</div>
<div className="flex flex-col px-1 pb-2 pt-2">
<div className="flex flex-col space-y-1.5">
<div className="flex justify-between items-center bg-base-200 px-2.5 py-1.5 rounded-lg">
<span className="text-xs font-semibold text-error">HP</span>
<span className="text-sm font-bold text-base-content">{monsterStats.hp.toLocaleString(undefined, { maximumFractionDigits: 0 })}</span>
</div>
<div className="flex justify-between items-center bg-base-200 px-2.5 py-1.5 rounded-lg">
<span className="text-xs font-semibold text-info">Speed</span>
<span className="text-sm font-bold text-base-content">{monsterStats.spd.toLocaleString(undefined, { maximumFractionDigits: 0 })}</span>
</div>
<div className="flex justify-between items-center bg-base-200 px-2.5 py-1.5 rounded-lg">
<span className="text-xs font-semibold text-base-content/70">Toughness</span>
<span className="text-sm font-bold text-base-content">{monsterStats.stance.toLocaleString(undefined, { maximumFractionDigits: 0 })}</span>
</div>
</div>
<div className="mt-2 pt-2 border-t border-base-300 flex flex-col items-center">
<span className="text-[10px] text-base-content/60 font-bold uppercase tracking-widest mb-1.5">
Weakness
</span>
<div className="flex items-center justify-center gap-1.5 flex-wrap">
{mapMonster?.[waveValue.toString()]?.StanceWeakList?.map((icon, iconIndex) => (
<Image
key={iconIndex}
unoptimized
crossOrigin="anonymous"
src={`${process.env.CDN_URL}/${damageType[icon]?.Icon}`}
alt={icon}
width={40}
height={40}
className="h-6 w-6 object-contain rounded-full bg-base-300 border border-base-content/10 p-0.5 shadow-sm hover:scale-110 transition-transform"
/>
))}
</div>
</div>
</div>
</div>
</div>
))}
)
})}
</div>
</div>
))}