diff --git a/AquaNet/src/components/settings/ChuniSettings.svelte b/AquaNet/src/components/settings/ChuniSettings.svelte
index 2a5f2c33..e945f9b5 100644
--- a/AquaNet/src/components/settings/ChuniSettings.svelte
+++ b/AquaNet/src/components/settings/ChuniSettings.svelte
@@ -99,6 +99,7 @@
let USERBOX_SETUP_TEXT = t("userbox.new.setup");
let USERBOX_ENABLED = useLocalStorage("userboxNew", false);
+ let USERBOX_PROFILE_ENABLED = useLocalStorage("userboxNewProfile", false);
let USERBOX_INSTALLED = false;
let USERBOX_SUPPORT = "webkitGetAsEntry" in DataTransferItem.prototype;
@@ -155,9 +156,9 @@
{:else}
- userboxSelected = "nameplateId"} chuniCharacter={userbox.characterId} chuniLevel={userbox.level} chuniRating={userbox.playerRating / 100}
+ userboxSelected = "nameplateId"} chuniCharacter={userbox.characterId} chuniLevel={userbox.level.toString()} chuniRating={userbox.playerRating / 100}
chuniNameplate={userbox.nameplateId} chuniName={userbox.userName} chuniTrophyName={allItems.trophy[userbox.trophyId].name}>
-
@@ -219,6 +220,13 @@
{t(`userbox.new.activate_desc`)}
+
+
+
+
{/if}
{#if USERBOX_SUPPORT}
diff --git a/AquaNet/src/components/settings/userbox/ChuniPenguin.svelte b/AquaNet/src/components/settings/userbox/ChuniPenguin.svelte
index ed9730c6..a5207fcc 100644
--- a/AquaNet/src/components/settings/userbox/ChuniPenguin.svelte
+++ b/AquaNet/src/components/settings/userbox/ChuniPenguin.svelte
@@ -29,10 +29,10 @@
{/await}
- {#await DDSreader.getFileFromSheet("surfboard:CHU_UI_Common_Avatar_body_00.dds", 0, 0, 85, 160, 0.75) then imageURL}
+ {#await DDSreader.getFileFromSheet("surfboard:CHU_UI_Common_Avatar_body_00.dds", 80, 0, 110, 100, 0.75) then imageURL}
{/await}
- {#await DDSreader.getFileFromSheet("surfboard:CHU_UI_Common_Avatar_body_00.dds", 0, 0, 85, 160, 0.75) then imageURL}
+ {#await DDSreader.getFileFromSheet("surfboard:CHU_UI_Common_Avatar_body_00.dds", 80, 0, 110, 100, 0.75) then imageURL}
{/await}
@@ -77,8 +77,11 @@
- {#await DDSreader.getFileFromSheet(`avatarAccessory:${chuniSkin.toString().padStart(8, "0")}`, 0, 410, 167, 80, 0.75) then imageURL}
-

+ {#await DDSreader.getFileFromSheet(`avatarAccessory:${chuniSkin.toString().padStart(8, "0")}`, 0, 410, 85, 80, 0.75) then imageURL}
+

+ {/await}
+ {#await DDSreader.getFileFromSheet(`avatarAccessory:${chuniSkin.toString().padStart(8, "0")}`, 85, 410, 85, 80, 0.75) then imageURL}
+

{/await}
@@ -88,7 +91,7 @@
0%
transform: translate(-50%, 0%) translate(0%, -50%)
50%
- transform: translate(-50%, 10px) translate(0%, -50%)
+ transform: translate(-50%, 5px) translate(0%, -50%)
100%
transform: translate(-50%, 0%) translate(0%, -50%)
@keyframes chuniPenguinArmLeft
@@ -108,11 +111,19 @@
img
-webkit-user-drag: none
+ user-select: none
.chuni-penguin
height: 512px
aspect-ratio: 1/2
position: relative
+ pointer-events: none
+
+ &.chuni-penguin-float
+ position: absolute
+ top: 50%
+ left: 50%
+ transform: translate(-50%, -50%)
.chuni-penguin-body, .chuni-penguin-feet
transform: translate(-50%, -50%)
@@ -122,21 +133,31 @@
.chuni-penguin-body
top: 50%
z-index: 1
- animation: chuniPenguinBodyBob 2s infinite cubic-bezier(0.45, 0, 0.55, 1)
+ animation: chuniPenguinBodyBob 1s infinite cubic-bezier(0.45, 0, 0.55, 1)
.chuni-penguin-feet
- top: 82.5%
+ top: 80%
z-index: 0
+ width: 175px
+ display: flex
+ justify-content: center
+
+ img
+ margin-left: auto
+ margin-right: auto
.chuni-penguin-arm
- transform-origin: 95% 10%
+ transform-origin: 40% 10%
position: absolute
top: 40%
+ z-index: 2
.chuni-penguin-arm-left
- left: 0%
- animation: chuniPenguinArmLeft 1.5s infinite cubic-bezier(0.45, 0, 0.55, 1)
+ left: 15%
+ transform: translate(-50%, 0)
+ animation: chuniPenguinArmLeft 1s infinite cubic-bezier(0.45, 0, 0.55, 1) 0.5s
.chuni-penguin-arm-right
- left: 70%
- animation: chuniPenguinArmRight 1.5s infinite cubic-bezier(0.45, 0, 0.55, 1)
+ left: 95%
+ transform: translate(-50%, 0) scaleX(-1)
+ animation: chuniPenguinArmRight 1s infinite cubic-bezier(0.45, 0, 0.55, 1) 0.5s
.chuni-penguin-accessory
transform: translate(-50%, -50%)
@@ -149,7 +170,7 @@
.chuni-penguin-beak
top: 29.5%
.chuni-penguin-wear
- top: 57.5%
+ top: 60%
.chuni-penguin-head
top: 7.5%
z-index: 10
diff --git a/AquaNet/src/components/settings/userbox/ChuniUserplate.svelte b/AquaNet/src/components/settings/userbox/ChuniUserplate.svelte
index 37d485c7..2cebf430 100644
--- a/AquaNet/src/components/settings/userbox/ChuniUserplate.svelte
+++ b/AquaNet/src/components/settings/userbox/ChuniUserplate.svelte
@@ -4,25 +4,25 @@
const DDSreader = new DDS(ddsDB);
- export var chuniLevel: number = 1
+ export var chuniLevel: string = "╳"
export var chuniName: string = "AquaDX"
export var chuniRating: number = 1.23
export var chuniNameplate: number = 1
export var chuniCharacter: number = 0
export var chuniTrophyName: string = "NEWCOMER"
-{#await DDSreader?.getFile(`nameplate:${chuniNameplate.toString().padStart(8, "0")}`) then nameplateURL}
+{#await DDSreader?.getFile(`nameplate:${chuniNameplate.toString().padStart(8, "0")}`, `nameplate:00000001`) then nameplateURL}
- {#await DDSreader?.getFile(`characterThumbnail:${chuniCharacter.toString().padStart(6, "0")}`) then characterThumbnailURL}
+ {#await DDSreader?.getFile(`characterThumbnail:${chuniCharacter.toString().padStart(6, "0")}`, `characterThumbnail:000000`) then characterThumbnailURL}

{/await}
{#await DDSreader?.getFileFromSheet("surfboard:CHU_UI_title_rank_00_v10.dds", 5, 5 + (75 * 2), 595, 64) then trophyURL}
{chuniTrophyName}
-
+

{/await}
@@ -57,7 +57,7 @@
cursor: pointer
.chuni-trophy
- width: 410px
+ width: 390px
height: 45px
background-position: center
background-size: cover
@@ -74,14 +74,21 @@
font-family: sans-serif
font-weight: bold
+ overflow-x: hidden
+ white-space: nowrap
+ text-overflow: ellipsis
+
z-index: 1
text-shadow: 0 1px white
+ margin: 0 10px
- img
- width: 100%
- height: 100%
- position: absolute
- z-index: -1
+ img.chuni-trophy-bg
+ width: 410px
+ height: 45px
+ position: absolute
+ top: 40px
+ right: 25px
+ z-index: -1
.chuni-character
position: absolute
@@ -115,9 +122,11 @@
.chuni-user-name
flex: 1 0 65%
box-shadow: 0 1px 0 #ccc
+ white-space: nowrap
+ text-overflow: ellipsis
.chuni-user-level
- font-size: 2em
+ font-size: 1.5em
margin-left: 10px
.chuni-user-name-text
diff --git a/AquaNet/src/libs/i18n/en_ref.ts b/AquaNet/src/libs/i18n/en_ref.ts
index 40a07673..4538ed7f 100644
--- a/AquaNet/src/libs/i18n/en_ref.ts
+++ b/AquaNet/src/libs/i18n/en_ref.ts
@@ -189,6 +189,8 @@ export const EN_REF_USERBOX = {
'userbox.new.activate_update': 'Update AquaBox (game files required)',
'userbox.new.activate': 'Use AquaBox',
'userbox.new.activate_desc': 'Enable displaying UserBoxes with their nameplate & avatar',
+ 'userbox.new.activate_profile': 'Use AquaBox on profiles',
+ 'userbox.new.activate_profile_desc': 'Enable displaying UserBoxes with their nameplate & avatar on profile pages',
'userbox.new.error.invalidFolder': 'The folder you selected is invalid. Ensure that your game\'s version is Lumi or newer and that the "A001" option pack is present.'
}
diff --git a/AquaNet/src/libs/sdk.ts b/AquaNet/src/libs/sdk.ts
index b6363c5f..9b495f76 100644
--- a/AquaNet/src/libs/sdk.ts
+++ b/AquaNet/src/libs/sdk.ts
@@ -266,6 +266,8 @@ export const USERBOX = {
get('/api/v2/game/chu3/user-box', {}),
setUserBox: (d: { field: string, value: number | string }) =>
post(`/api/v2/game/chu3/user-detail-set`, d),
+ getUserProfile: (username: string): Promise =>
+ get(`/api/v2/game/chu3/user-detail`, {username})
}
export const CARD = {
diff --git a/AquaNet/src/libs/userbox/userbox.ts b/AquaNet/src/libs/userbox/userbox.ts
index 2b3e7343..bed119aa 100644
--- a/AquaNet/src/libs/userbox/userbox.ts
+++ b/AquaNet/src/libs/userbox/userbox.ts
@@ -174,6 +174,7 @@ export async function userboxFileProcess(folder: FileSystemEntry, progressUpdate
if (dataFolder)
await scanOptionFolder(dataFolder, progressUpdate);
useLocalStorage("userboxNew", false).value = true;
+ useLocalStorage("userboxNewProfile", false).value = true;
location.reload();
return null
diff --git a/AquaNet/src/pages/UserHome.svelte b/AquaNet/src/pages/UserHome.svelte
index ab506021..7e5a00f4 100644
--- a/AquaNet/src/pages/UserHome.svelte
+++ b/AquaNet/src/pages/UserHome.svelte
@@ -105,6 +105,41 @@
d!.user.rival = isAdd
}).catch(e => error = e.message).finally(() => isLoading = false)
}
+
+ /* Aquabox */
+
+ import { userboxFileProcess, ddsDB, initializeDb } from "../libs/userbox/userbox"
+ import ChuniPenguinComponent from "../components/settings/userbox/ChuniPenguin.svelte"
+ import ChuniUserplateComponent from "../components/settings/userbox/ChuniUserplate.svelte";
+ import {
+ type UserBox,
+ type UserItem,
+ } from "../libs/generalTypes";
+ import { USERBOX } from "../libs/sdk";
+
+ let USERBOX_ACTIVE = useLocalStorage("userboxNewProfile", false);
+ let USERBOX_INSTALLED = false;
+
+ let userbox: UserBox;
+ let allItems: Record> = {};
+
+ if (game == "chu3" && USERBOX_ACTIVE.value) {
+ indexedDB.databases().then(async (dbi) => {
+ let databaseExists = dbi.some(db => db.name == "userboxChusanDDS");
+ if (databaseExists) {
+ await initializeDb();
+ const profile = await USERBOX.getUserProfile(username).catch(_ => null)
+ if (!profile) return;
+ userbox = profile;
+ console.log(userbox);
+
+ allItems = await DATA.allItems('chu3').catch(_ => {
+ error = t("userbox.error.nodata")
+ }) as typeof allItems
+ USERBOX_INSTALLED = databaseExists;
+ }
+ })
+ }
@@ -132,6 +167,18 @@
+ {#if USERBOX_ACTIVE.value && USERBOX_INSTALLED && game == "chu3"}
+
+ {/if}
+
{titleText} {t('UserHome.Statistics')}
@@ -576,4 +623,18 @@
&:before
content: "+"
color: vars.$c-good
+
+.chuni-userbox-container
+ display: flex
+ align-items: center
+ justify-content: center
+
+ .chuni-penguin-container
+ height: 256px
+ aspect-ratio: 1
+ position: relative
+
+@media (max-width: 1000px)
+ .chuni-userbox-container
+ flex-wrap: wrap