Skip to content

Commit

Permalink
feat: Add portal 2-like loading screen
Browse files Browse the repository at this point in the history
  • Loading branch information
JJL772 committed Mar 18, 2024
1 parent 26a50aa commit 6d6a05d
Show file tree
Hide file tree
Showing 3 changed files with 164 additions and 93 deletions.
44 changes: 27 additions & 17 deletions layout/pages/loading-screen.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,34 @@
</scripts>

<Panel class="loadingscreen">
<Image id="BackgroundImageDefault" class="full" src="file://{materials}/panorama/bg_00.vtf" />
<Image id="BackgroundImage" class="full hide" scaling="stretch-to-cover-preserve-aspect" />
<Image
id="BackgroundMapImage1"
class="loadingscreen__background loadingscreen__background-image1"
src=""
scaling="stretch"
/>
<Image
id="BackgroundMapImage2"
class="loadingscreen__background loadingscreen__background-image4"
src=""
scaling="stretch"
/>

<Panel class="full flow-down">
<Panel class="loadingscreen__details">
<Panel class="loadingscreen__left-details">
<Label id="MapName" class="text-h1" text="{s:mapname}" />
<Label id="Author" class="text-h2" text="#LoadingScreen_Author" />
</Panel>
<Panel class="loadingscreen__right-details">
<Label id="TierAndType" class="text-h1 loadingscreen__right-label" text="#LoadingScreen_TierAndType" />
<Label id="NumZones" class="text-h2 loadingscreen__right-label" text="#LoadingScreen_NumZones" />
</Panel>
<!--Label id="GameModeTip" class="text-l loadingscreen__tip" text="{s:tip}" /-->
<Label id="ProgressStatusText" class="text-h1 loadingscreen__status-label" text="#LoadingScreen_Loading" />
<Label id="PercentText" class="text-h1 loadingscreen__percentage-label" text="{d:percent}%" />
</Panel>
<ProgressBar id="ProgressBar" class="loadingscreen__progressbar progressbar" />
<!-- todo: set the logo dynamically -->
<Image
id="Logo"
class="loadingscreen__logo"
src=""
defaultsrc="file://{images}/menu/p2ce/logo.png"
scaling="stretch-to-cover-preserve-aspect"
/>

<Panel class="loadingscreen__fade--dark" />
<Panel id="LoadingScreenContents" class="loadingscreen__contents" />

<Panel id="" class="full-width full-height">
</Panel>

<ProgressBar id="ProgressBar" class="loadingscreen__progressbar" />
</Panel>
</root>
129 changes: 65 additions & 64 deletions scripts/pages/loading-screen.js
Original file line number Diff line number Diff line change
@@ -1,80 +1,81 @@
'use strict';

class LoadingScreen {
static panels = {
/** @type {Panel} @static */
cp: $.GetContextPanel(),
/** @type {Image} @static */
backgroundImage: $('#BackgroundImage'),
/** @type {ProgressBar} @static */
progressBar: $('#ProgressBar'),
/** @type {Label} @static */
mapName: $('#MapName'),
/** @type {Label} @static */
author: $('#Author'),
/** @type {Label} @static */
tierAndType: $('#TierAndType'),
/** @type {Label} @static */
numZones: $('#NumZones')
};

static {
$.RegisterForUnhandledEvent('UnloadLoadingScreenAndReinit', this.init.bind(this));

$.RegisterEventHandler(
'PanelLoaded',
this.panels.backgroundImage,
() => (this.panels.backgroundImage.visible = true)
);
$.RegisterEventHandler(
'ImageFailedLoad',
this.panels.backgroundImage,
() => (this.panels.backgroundImage.visible = false)
);
}
class LoadingScreenController {
static lastLoadedMapName = '';

static init() {
this.panels.progressBar.value = 0;
this.panels.mapName.visible = false;
this.panels.author.visible = false;
this.panels.tierAndType.visible = false;
this.panels.numZones.visible = false;
this.panels.backgroundImage.visible = false;
$('#ProgressBar').value = 0;
$.GetContextPanel()
.FindChildInLayoutFile('BackgroundMapImage1')
.RemoveClass('loadingscreen__backgroundhideanim');
$.GetContextPanel().FindChildInLayoutFile('BackgroundMapImage2').visible = false;
}

static updateLoadingScreenInfo(mapName) {
if (!mapName) return;

const mapData = MapCacheAPI.GetCurrentMapData();
static updateLoadingScreenInfoRepeater() {
// Progress bar will be 1.0 when loading finishes and is then reset to 0.0
if ($.GetContextPanel().FindChildInLayoutFile('BackgroundMapImage2').visible) return;

if (!mapData) {
// No data to go off of, just set the map name and hide the rest
this.panels.cp.SetDialogVariable('mapname', mapName);
this.panels.mapName.visible = true;
if ($('#ProgressBar').value > 0.35) {
$.GetContextPanel()
.FindChildInLayoutFile('BackgroundMapImage1')
.AddClass('loadingscreen__backgroundhideanim');
$.GetContextPanel().FindChildInLayoutFile('BackgroundMapImage2').visible = true;
return;
}

this.panels.author.visible = false;
this.panels.tierAndType.visible = false;
this.panels.numZones.visible = false;
this.panels.backgroundImage.SetImage('');
// Rechecking every 8th of a second is OK, it doesn't need to be anything crazy
$.Schedule(0.125, LoadingScreenController.updateLoadingScreenInfoRepeater);
}

return;
static updateLoadingScreenInfo(mapName) {
function getMapImage(map, number) {
const base = 'file://{materials}/vgui/loading_screens/loadingscreen_';
if (map.startsWith('e1912')) return base + 'e1912_1_widescreen.vtf';
else if (map.startsWith('sp_a1')) return base + 'a1_' + number + '_widescreen.vtf';
else if (map.startsWith('sp_a2')) return base + 'a2_' + number + '_widescreen.vtf';
else if (map.startsWith('sp_a3')) return base + 'a3_' + number + '_widescreen.vtf';
else if (map.startsWith('sp_a4')) return base + 'a4_' + number + '_widescreen.vtf';
else if (map.startsWith('sp_a5')) return base + 'a5_1_widescreen.vtf';
else if (map.startsWith('mp')) return base + 'coop_' + number + '_widescreen.vtf';
// if map is empty, we are reloading the current map
// todo: the aperture logo loading screens don't map exactly to the acts,
// act 3 in particular has two different aperture logo loading screens.
// fixing this will probably involve making a variable storing every
// map name in the game to map it to the right loading screen.
// in the meantime, this looks pretty good
else if (LoadingScreenController.lastLoadedMapName.startsWith('sp_a1'))
return base + 'default_a_' + number + '_widescreen.vtf';
else if (LoadingScreenController.lastLoadedMapName.startsWith('sp_a2'))
return base + 'default_b_' + number + '_widescreen.vtf';
else if (LoadingScreenController.lastLoadedMapName.startsWith('sp_a3'))
return base + 'default_c_' + number + '_widescreen.vtf';
else if (LoadingScreenController.lastLoadedMapName.startsWith('sp_a4'))
return base + 'default_e_' + number + '_widescreen.vtf';
else if (LoadingScreenController.lastLoadedMapName.startsWith('sp_a5')) return base + 'a5_1_widescreen.vtf';
else return base + 'default_b_' + number + '_widescreen.vtf';
}

this.panels.cp.SetDialogVariable('mapname', mapData.name);
this.panels.cp.SetDialogVariableInt('tier', mapData.mainTrack.difficulty);
this.panels.cp.SetDialogVariableInt('numzones', mapData.mainTrack.numZones);
this.panels.cp.SetDialogVariable('tracktype', mapData.mainTrack.isLinear ? 'Linear' : 'Staged');
if (mapName.length > 0) LoadingScreenController.lastLoadedMapName = mapName;

let authorString = '';
for (const [i, item] of mapData.credits.filter((x) => x.type === 'author').entries())
authorString += (i > 0 ? ', ' : '') + item.user.alias;
this.panels.cp.SetDialogVariable('author', authorString);
let imageNumber1, imageNumber2;
if (mapName.startsWith('mp')) {
imageNumber1 = Math.floor(Math.random() * 3) + 1;
imageNumber2 = imageNumber1 + 1;
} else {
imageNumber1 = 1;
imageNumber2 = 4;
}

this.panels.mapName.visible = true;
this.panels.author.visible = true;
this.panels.tierAndType.visible = true;
this.panels.numZones.visible = true;
const bgImage1 = $.GetContextPanel().FindChildInLayoutFile('BackgroundMapImage1');
bgImage1.SetImage(getMapImage(mapName, imageNumber1));
bgImage1.visible = true;
$.GetContextPanel().FindChildInLayoutFile('BackgroundMapImage2').SetImage(getMapImage(mapName, imageNumber2));

this.panels.backgroundImage.SetImage(mapData.thumbnail.urlLarge);
$.Schedule(0.125, LoadingScreenController.updateLoadingScreenInfoRepeater);
}

static {
$.RegisterForUnhandledEvent('UnloadLoadingScreenAndReinit', LoadingScreenController.init);
$.RegisterForUnhandledEvent('PopulateLoadingScreen', LoadingScreenController.updateLoadingScreenInfo);
}
}
84 changes: 72 additions & 12 deletions styles/pages/loading-screen.scss
Original file line number Diff line number Diff line change
@@ -1,6 +1,63 @@
.loadingscreen {
width: 100%;
height: 100%;
background-color: rgba(255, 255, 255, 0.01);
transform: scale3d(1, 1, 1);
opacity: 1;

&__background {
width: 100%;
height: 100%;
}

&__background-image1 {
z-index: -1;
}

&__background-image4 {
z-index: -4;
}

&__contents {
opacity: 1;

transition-property: height, opacity;
transition-duration: 0.5s;
transition-timing-function: ease-in-out;
}

&__show {
animation-name: loadingscreen__show-animation;
animation-duration: 0.65s;
animation-timing-function: ease-in-out;
animation-iteration-count: 1;
animation-fill-mode: both;
}

&__logo {
vertical-align: top;
horizontal-align: right;
width: 100px;
margin-right: 52px;
margin-top: 52px;
}

&__backgroundhideanim {
animation-name: loading-screen-background-hide-anim;
animation-duration: 0.8s;
animation-timing-function: linear;
animation-iteration-count: 1;
animation-fill-mode: forwards;
}

&__progressbar {
width: 45%;
height: 10px;
background-color: #00a2ff44;
vertical-align: bottom;
margin-bottom: 52px;
horizontal-align: center;
}

&__details {
flow-children: none;
Expand Down Expand Up @@ -28,18 +85,6 @@
horizontal-align: right;
}

&__tip {
vertical-align: bottom;
horizontal-align: center;
margin-bottom: 100px;
}

&__progressbar {
width: 100%;
height: 20px;
box-shadow: none;
}

&__status-label {
vertical-align: bottom;
horizontal-align: left;
Expand Down Expand Up @@ -78,3 +123,18 @@
opacity: 0;
}
}

@keyframes loading-screen-background-hide-anim {
0% {
opacity: 1;
}

100% {
opacity: 0;
}
}

// Assigned to the progress bar by Panorama internally
.ProgressBarLeft {
background-color: #ff9a00;
}

0 comments on commit 6d6a05d

Please sign in to comment.