From 4176621b057dbd65d56c074544a556f7ab633157 Mon Sep 17 00:00:00 2001 From: tobspr Date: Fri, 14 Jan 2022 12:34:02 +0100 Subject: [PATCH] Proper mods ui --- res/ui/icons/mods.png | Bin 0 -> 4450 bytes res/ui/icons/mods_white.png | Bin 0 -> 4455 bytes src/css/main.scss | 1 + src/css/states/main_menu.scss | 57 ++++++++--- src/css/states/mods.scss | 131 +++++++++++++++++++++++++ src/css/states/settings.scss | 48 +++++++-- src/css/variables.scss | 1 + src/js/application.js | 2 + src/js/mods/demo_mod.nobuild/index.js | 15 +-- src/js/mods/mod.js | 5 +- src/js/states/main_menu.js | 50 ++++------ src/js/states/mods.js | 135 ++++++++++++++++++++++++++ src/js/states/settings.js | 23 +++++ translations/base-en.yaml | 26 +++-- 14 files changed, 431 insertions(+), 63 deletions(-) create mode 100644 res/ui/icons/mods.png create mode 100644 res/ui/icons/mods_white.png create mode 100644 src/css/states/mods.scss create mode 100644 src/js/states/mods.js diff --git a/res/ui/icons/mods.png b/res/ui/icons/mods.png new file mode 100644 index 0000000000000000000000000000000000000000..1b3cb477aff032e4770ee2c8010e2d919c9fc5c7 GIT binary patch literal 4450 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 literal 0 HcmV?d00001 diff --git a/res/ui/icons/mods_white.png b/res/ui/icons/mods_white.png new file mode 100644 index 0000000000000000000000000000000000000000..1cb34f27dc90aaec243ce98e1b387f56cd7a2c46 GIT binary patch literal 4455 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 .headerBar { + display: grid; + grid-template-columns: 1fr auto; + align-items: center; + + > h1 { + justify-self: start; + } + + .openModsFolder { + background-color: $modsColor; + } + } + + .noModSupport { + display: flex; + align-items: center; + justify-content: center; + height: 100%; + flex-direction: column; + + .steamLink { + @include S(height, 50px); + @include S(width, 220px); + background: #171a23 center center / contain no-repeat; + overflow: hidden; + display: block; + text-indent: -999em; + cursor: pointer; + @include S(margin-top, 30px); + pointer-events: all; + transition: all 0.12s ease-in; + transition-property: opacity, transform; + + @include S(border-radius, $globalBorderRadius); + + &:hover { + opacity: 0.9; + } + } + } + + .modsStats { + @include PlainText; + color: $accentColorDark; + + &.noMods { + @include S(width, 400px); + align-self: center; + justify-self: center; + text-align: center; + display: flex; + flex-direction: column; + align-items: center; + @include Text; + @include S(margin-top, 100px); + color: lighten($accentColorDark, 15); + + &::before { + @include S(margin-bottom, 15px); + content: ""; + @include S(width, 50px); + @include S(height, 50px); + background-position: center center; + background-size: contain; + opacity: 0.2; + } + &::before { + /* @load-async */ + background-image: uiResource("res/ui/icons/mods.png") !important; + } + } + } + + .modsList { + @include S(margin-top, 10px); + overflow-y: scroll; + pointer-events: all; + @include S(padding-right, 5px); + flex-grow: 1; + + .mod { + @include S(border-radius, $globalBorderRadius); + background: $accentColorBright; + @include S(margin-bottom, 4px); + @include S(padding, 7px); + @include S(grid-gap, 5px); + display: grid; + grid-template-columns: 1fr D(100px) D(100px) D(100px); + + .checkbox { + align-self: center; + justify-self: center; + } + + .mainInfo { + display: flex; + flex-direction: column; + + .description { + @include SuperSmallText; + @include S(margin-top, 5px); + color: $accentColorDark; + } + .website { + text-transform: uppercase; + align-self: start; + @include SuperSmallText; + @include S(margin-top, 5px); + } + } + + .version, + .author { + display: flex; + flex-direction: column; + strong { + text-transform: uppercase; + color: $accentColorDark; + @include SuperSmallText; + } + } + } + } +} diff --git a/src/css/states/settings.scss b/src/css/states/settings.scss index 5b36c677..75ef6b85 100644 --- a/src/css/states/settings.scss +++ b/src/css/states/settings.scss @@ -15,20 +15,21 @@ } .sidebar { - display: grid; + display: flex; @include S(min-width, 210px); @include S(max-width, 320px); - @include S(grid-gap, 3px); - grid-template-rows: auto auto auto auto auto 1fr; + flex-direction: column; @include StyleBelowWidth($layoutBreak) { - grid-template-rows: 1fr 1fr; - grid-template-columns: auto auto; + display: grid; + grid-template-columns: 1fr 1fr 1fr; + @include S(grid-gap, 5px); max-width: unset !important; } button { text-align: left; + @include S(margin-bottom, 3px); &::after { content: unset; } @@ -37,15 +38,26 @@ @include StyleBelowWidth($layoutBreak) { text-align: center; + height: D(30px) !important; + padding: D(5px) !important; } } .other { - @include S(margin-top, 10px); align-self: end; + margin-top: auto; @include StyleBelowWidth($layoutBreak) { margin-top: 0; + display: grid; + grid-template-columns: 1fr 1fr; + @include S(grid-gap, 5px); + max-width: unset !important; + grid-column: 1 / 3; + + button { + margin: 0 !important; + } } } @@ -69,6 +81,30 @@ } } + button.manageMods { + background-color: lighten($modsColor, 38); + color: $modsColor; + display: flex; + @include S(padding-right, 5px); + .newBadge { + color: #fff; + @include S(border-radius, $globalBorderRadius); + background: $modsColor; + margin-left: auto; + @include S(padding, 0, 3px, 0, 3px); + + @include InlineAnimation(1.3s ease-in-out infinite) { + 50% { + transform: rotate(0deg) scale(1.1); + } + } + } + + &.active { + background-color: $colorGreenBright; + } + } + button.privacy { @include S(margin-top, 4px); } diff --git a/src/css/variables.scss b/src/css/variables.scss index c7b7c17c..fe1fa864 100644 --- a/src/css/variables.scss +++ b/src/css/variables.scss @@ -38,6 +38,7 @@ $colorRedBright: #ef5072; $colorOrangeBright: #ef9d50; $themeColor: #393747; $ingameHudBg: rgba(#333438, 0.9); +$modsColor: rgb(214, 60, 228); $text3dColor: #f4ffff; diff --git a/src/js/application.js b/src/js/application.js index 67e9c353..44207e4d 100644 --- a/src/js/application.js +++ b/src/js/application.js @@ -37,6 +37,7 @@ import { LoginState } from "./states/login"; import { WegameSplashState } from "./states/wegame_splash"; import { MODS } from "./mods/modloader"; import { MOD_SIGNALS } from "./mods/mod_signals"; +import { ModsState } from "./states/mods"; /** * @typedef {import("./platform/achievement_provider").AchievementProviderInterface} AchievementProviderInterface @@ -171,6 +172,7 @@ export class Application { ChangelogState, PuzzleMenuState, LoginState, + ModsState, ]; for (let i = 0; i < states.length; ++i) { diff --git a/src/js/mods/demo_mod.nobuild/index.js b/src/js/mods/demo_mod.nobuild/index.js index b636dace..2188defc 100644 --- a/src/js/mods/demo_mod.nobuild/index.js +++ b/src/js/mods/demo_mod.nobuild/index.js @@ -16,11 +16,12 @@ registerMod(shapez => { super( app, { - authorContact: "tobias@tobspr.io", - authorName: "tobspr", + website: "https://tobspr.io", + author: "tobspr", name: "Demo Mod", version: "1", id: "demo-mod", + description: "A simple mod to demonstrate the capatibilities of the mod loader.", }, modLoader ); @@ -28,11 +29,11 @@ registerMod(shapez => { init() { // Add some custom css - this.modInterface.registerCss(` - * { - font-family: "Comic Sans", "Comic Sans MS", Tahoma !important; - } - `); + // this.modInterface.registerCss(` + // * { + // font-family: "Comic Sans", "Comic Sans MS", Tahoma !important; + // } + // `); // Replace a builtin sprite ["red", "green", "blue", "yellow", "purple", "cyan", "white"].forEach(color => { diff --git a/src/js/mods/mod.js b/src/js/mods/mod.js index b9018b68..4e14bfe2 100644 --- a/src/js/mods/mod.js +++ b/src/js/mods/mod.js @@ -12,8 +12,9 @@ export class Mod { * @param {object} metadata * @param {string} metadata.name * @param {string} metadata.version - * @param {string} metadata.authorName - * @param {string} metadata.authorContact + * @param {string} metadata.author + * @param {string} metadata.website + * @param {string} metadata.description * @param {string} metadata.id * * @param {ModLoader} modLoader diff --git a/src/js/states/main_menu.js b/src/js/states/main_menu.js index a6bb940a..91142c3b 100644 --- a/src/js/states/main_menu.js +++ b/src/js/states/main_menu.js @@ -155,36 +155,22 @@ export class MainMenuState extends GameState { ? `
-

${T.mainMenu.mods.title} - -

- +
+

${T.mods.title}

+ +
${MODS.mods .map(mod => { return ` -
- ${mod.metadata.name} - ${T.mainMenu.mods.version.replace( - "", - mod.metadata.version - )} - ${T.mainMenu.mods.author.replace( - "", - mod.metadata.authorName - )} -
+
${mod.metadata.name} @ v${mod.metadata.version}
`; }) .join("")}
- ${T.mainMenu.modsWarningPuzzleDLC} - - + ${T.mainMenu.mods.warningPuzzleDLC}
@@ -381,7 +367,7 @@ export class MainMenuState extends GameState { ".puzzleDlcPlayButton": this.onPuzzleModeButtonClicked, ".puzzleDlcGetButton": this.onPuzzleWishlistButtonClicked, ".wegameDisclaimer > .rating": this.onWegameRatingClicked, - ".modsOpenFolder": this.openModsFolder, + ".editMods": this.onModsClicked, }; for (const key in clickHandling) { @@ -430,6 +416,14 @@ export class MainMenuState extends GameState { this.trackClicks(playBtn, this.onPlayButtonClicked); buttonContainer.appendChild(importButtonElement); } + + // Mods + const modsBtn = makeButton( + this.htmlElement.querySelector(".mainContainer .outer"), + ["modsButton", "styledButton"], + " " + ); + this.trackClicks(modsBtn, this.onModsClicked); } onPuzzleModeButtonClicked(force = false) { @@ -742,6 +736,12 @@ export class MainMenuState extends GameState { ); } + onModsClicked() { + this.moveToState("ModsState", { + backToStateId: "MainMenuState", + }); + } + onContinueButtonClicked() { let latestLastUpdate = 0; let latestInternalId; @@ -763,14 +763,6 @@ export class MainMenuState extends GameState { }); } - openModsFolder() { - if (!G_IS_STANDALONE) { - this.dialogs.showWarning(T.global.error, T.mainMenu.mods.folderOnlyStandalone); - return; - } - getIPCRenderer().send("open-mods-folder"); - } - onLeave() { this.dialogs.cleanup(); } diff --git a/src/js/states/mods.js b/src/js/states/mods.js new file mode 100644 index 00000000..d746434d --- /dev/null +++ b/src/js/states/mods.js @@ -0,0 +1,135 @@ +import { THIRDPARTY_URLS } from "../core/config"; +import { TextualGameState } from "../core/textual_game_state"; +import { getIPCRenderer } from "../core/utils"; +import { MODS } from "../mods/modloader"; +import { T } from "../translations"; + +export class ModsState extends TextualGameState { + constructor() { + super("ModsState"); + } + + getStateHeaderTitle() { + return T.mods.title; + } + + internalGetFullHtml() { + let headerHtml = ` +
+

${this.getStateHeaderTitle()}

+ +
+ ${ + G_IS_STANDALONE || G_IS_DEV + ? `` + : "" + } +
+ +
`; + + return ` + ${headerHtml} +
+ ${this.getInnerHTML()} +
+ `; + } + + getMainContentHTML() { + if (!G_IS_STANDALONE && !G_IS_DEV) { + return ` +
+ +

${T.mods.noModSupport}

+ + Get the shapez.io standalone! + + +
+ `; + } + + if (MODS.mods.length === 0) { + return ` + +
+ + ${T.mods.modsInfo} +
+ + `; + } + + let modsHtml = ``; + + MODS.mods.forEach(mod => { + modsHtml += ` +
+
+ ${mod.metadata.name} + ${mod.metadata.description} + Website +
+ ${T.mods.version}${mod.metadata.version} + ${T.mods.author}${mod.metadata.author} +
+ +
+ +
+ `; + }); + return ` + +
+ ${T.mods.modsInfo} +
+ +
+ ${modsHtml} +
+ `; + } + + onEnter() { + const steamLink = this.htmlElement.querySelector(".steamLink"); + if (steamLink) { + this.trackClicks(steamLink, this.onSteamLinkClicked); + } + const openModsFolder = this.htmlElement.querySelector(".openModsFolder"); + if (openModsFolder) { + this.trackClicks(openModsFolder, this.openModsFolder); + } + + const checkboxes = this.htmlElement.querySelectorAll(".checkbox"); + Array.from(checkboxes).forEach(checkbox => { + this.trackClicks(checkbox, this.showModTogglingComingSoon); + }); + } + + showModTogglingComingSoon() { + this.dialogs.showWarning(T.mods.togglingComingSoon.title, T.mods.togglingComingSoon.description); + } + + openModsFolder() { + if (!G_IS_STANDALONE) { + this.dialogs.showWarning(T.global.error, T.mods.folderOnlyStandalone); + return; + } + getIPCRenderer().send("open-mods-folder"); + } + + onSteamLinkClicked() { + this.app.analytics.trackUiClick("mods_steam_link"); + this.app.platformWrapper.openExternalLink( + THIRDPARTY_URLS.stanaloneCampaignLink + "/shapez_modsettings" + ); + + return false; + } + + getDefaultPreviousState() { + return "SettingsState"; + } +} diff --git a/src/js/states/settings.js b/src/js/states/settings.js index 352e0153..b28a4136 100644 --- a/src/js/states/settings.js +++ b/src/js/states/settings.js @@ -19,6 +19,8 @@ export class SettingsState extends TextualGameState {