Note: After publishing, you may have to bypass your browser's cache to see the changes.
- Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (โ-R on a Mac)
- Google Chrome: Press Ctrl-Shift-R (โ-Shift-R on a Mac)
- Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5.
( function ( mw, $ ) {
'use strict';
// ------------------------ Configurable ------------------------- //
const JSON_PAGE = 'MediaWiki:Vault_altar_ingredients.json';
const PLACEHOLDER_SELECTOR = '.js-vault-altar#vault-altar-component';
// ---------------------- Helper Functions ----------------------- //
function nearestLevel ( levels, val ) {
let chosen = levels[ 0 ];
for ( const lv of levels ) {
if ( val >= lv ) {
chosen = lv;
} else {
break;
}
}
return chosen;
}
/** Return canonical fileโpath URL for a given filename. */
function filePath ( filename ) {
return mw.util.getUrl( 'Special:FilePath/' + filename );
}
/** Convert an item id like "iron_ingot" โ "Iron_Ingot" */
function toIconName ( id ) {
return id.split( '_' ).map( w => w.charAt( 0 ).toUpperCase() + w.slice( 1 ) ).join( '_' );
}
/**
* Render the output tables for a particular vault level.
* @param {Object} data โ Parsed JSON object (the entire file).
* @param {string} levelKey โ The exact level key to show (e.g. "10").
* @param {jQuery} $out โ jQuery node where HTML will be injected.
*/
function renderLevel ( data, levelKey, $out ) {
$out.empty();
const levelData = data.LEVELS[ levelKey ];
if ( !levelData ) {
$out.append( $( '<p>' ).text( 'No data found for level ' + levelKey + '.' ) );
return;
}
Object.entries( levelData ).forEach( ( [ catName, entries ] ) => {
const $details = $( '<details>' ).addClass( 'vault-altar-cat' );
$details.append( $( '<summary>' ).text( catName.charAt( 0 ).toUpperCase() + catName.slice( 1 ) ) );
const $table = $( '<table>' )
.addClass( 'wikitable sortable' )
.append( $( '<thead>' ).append( $( '<tr>' )
.append( $( '<th>' ).text( 'Items' ) )
.append( $( '<th>' ).text( 'Amount (minโmax)' ) )
.append( $( '<th>' ).text( 'Scale' ) )
.append( $( '<th>' ).text( 'Weight' ) )
) );
entries.forEach( entry => {
// Build the text list (e.g. "iron ingot, gold ingot")
const itemNames = entry.value.items.map( o => o.item.replace( /^minecraft:/, '' ).replace( /_/g, ' ' ) );
const itemsText = itemNames.join( ', ' );
// Use the first item for the icon
const firstId = entry.value.items[ 0 ].item.replace( /^minecraft:/, '' );
const iconFile = 'Invicon_' + toIconName( firstId ) + '.png';
const $img = $( '<img>' )
.attr( 'src', filePath( iconFile ) )
.attr( {
width: 20,
height: 20,
loading: 'lazy'
} )
.css( {
'vertical-align': 'middle',
'margin-right' : '0.25em'
} );
const amt = entry.value.amount.min + 'โ' + entry.value.amount.max;
const scale = entry.value.scale;
const weight= entry.weight;
const $itemCell = $( '<td>' ).append( $img ).append( document.createTextNode( ' ' + itemsText ) );
$table.append( $( '<tr>' )
.append( $itemCell )
.append( $( '<td>' ).text( amt ) )
.append( $( '<td>' ).text( scale ) )
.append( $( '<td>' ).text( weight ) )
);
} );
$details.append( $table );
$out.append( $details );
} );
}
// -------------------------- Main ------------------------------- //
function init () {
const host = document.querySelector( PLACEHOLDER_SELECTOR );
if ( !host ) return; // Only activate where template is present
const $wrapper = $( '<div>' ).addClass( 'vault-altar-wrapper' );
const $sliderRow = $( '<div>' ).addClass( 'vault-altar-slider' );
const $label = $( '<label>' ).attr( 'for', 'vault-altar-level' ).text( 'Vault Level: ' );
const $valDisplay = $( '<span>' ).attr( 'id', 'vault-altar-level-val' ).text( '0' );
const $input = $( '<input>' ).attr( {
id : 'vault-altar-level',
type : 'range',
min : 0,
max : 100,
step : 1,
value: 0
} ).css( 'width', '100%' );
$sliderRow.append( $label, $valDisplay, $input );
$wrapper.append( $sliderRow );
const $output = $( '<div>' ).attr( 'id', 'vault-altar-output' );
$wrapper.append( $output );
$( host ).empty().append( $wrapper );
$.getJSON( mw.util.wikiScript( 'index' ), {
title : JSON_PAGE,
action: 'raw',
ctype : 'application/json'
} ).done( function ( data ) {
const levels = Object.keys( data.LEVELS ).map( Number ).sort( ( a, b ) => a - b );
$input.attr( { min: levels[ 0 ], max: levels[ levels.length - 1 ] } );
function update () {
const userVal = parseInt( $input.val(), 10 );
const lvl = nearestLevel( levels, userVal );
$valDisplay.text( userVal + ' (showing ' + lvl + ')' );
renderLevel( data, String( lvl ), $output );
}
$input.on( 'input change', update );
update();
} ).fail( function () {
$output.text( 'Failed to load Vault Altar data โ please check that ' + JSON_PAGE + ' exists and is valid JSON.' );
} );
}
$( init );
} )( mediaWiki, jQuery );