diff --git a/frontend/frontend.js b/frontend/frontend.js new file mode 100644 index 0000000..2cc09b8 --- /dev/null +++ b/frontend/frontend.js @@ -0,0 +1,42 @@ +const updateUi = (state) => { + $('#embed-copy').val(`${location.href}/gfx.html`); + $('#state').text(JSON.stringify(state, null, 2)) + + $('#text-state').text(state.state); + $('#data-state').text(state.dataState); +} + +const updateState = async () => { + const response = await LPTE.request({ + meta: { + namespace: 'rcv-rune-gfx', + type: 'request', + version: 1 + } + }); + + updateUi(response.state); +} + +const nextStep = () => { + LPTE.emit({ + meta: { + namespace: 'rcv-rune-gfx', + type: 'next-step', + version: 1 + } + }) +} + +const prevStep = () => { + LPTE.emit({ + meta: { + namespace: 'rcv-rune-gfx', + type: 'previous-step', + version: 1 + } + }) +} + +updateState(); +setInterval(updateState, 1000); \ No newline at end of file diff --git a/frontend/gfx-script.js b/frontend/gfx-script.js new file mode 100644 index 0000000..fa8119b --- /dev/null +++ b/frontend/gfx-script.js @@ -0,0 +1,98 @@ +let previousState = 'HIDDEN' + +const updateUi = data => { + console.log(data); + + if (data.state === 'HIDDEN') { + $('.blue-box').addClass('hidden'); + $('.red-box').addClass('hidden'); + console.log('state is hidden') + } else { + console.log(previousState, data.state) + if (previousState !== data.state) { + $('.red-box').addClass('hidden'); + $('.blue-box').addClass('hidden'); + previousState = data.state; + return; + } + + const num = parseInt(data.state); + + const championMapping = { + 1: [1, 6], + 2: [2, 7], + 3: [3, 8], + 4: [4, 9], + 5: [5, 10] + } + + const getDDragonPath = clientPath => `/serve/static-league/img/${clientPath}` + + const getDDragonPathsFromRunes = runes => ({ + primary: getDDragonPath(runes[0].icon), + primary1: getDDragonPath(runes[1].icon), + primary2: getDDragonPath(runes[2].icon), + primary3: getDDragonPath(runes[3].icon), + secondary1: getDDragonPath(runes[4].icon), + secondary2: getDDragonPath(runes[5].icon) + }) + + console.log(data.participants[championMapping[num][0] - 1].perks.perkConstants) + + const championLeft = data.participants[championMapping[num][0] - 1].champion + const championRight = data.participants[championMapping[num][1] - 1].champion + const runesLeft = data.participants[championMapping[num][0] - 1].perks.perkConstants + const runesRight = data.participants[championMapping[num][1] - 1].perks.perkConstants + const splashLinkLeft = `/serve/static-league/img/champion/centered/${championLeft.key}.jpg` + const splashLinkRight = `/serve/static-league/img/champion/centered/${championRight.key}.jpg` + // const splashLinkLeft = `https://ddragon.leagueoflegends.com/cdn/img/champion/splash/${championLeft.id}_0.jpg` + // const splashLinkRight = `https://ddragon.leagueoflegends.com/cdn/img/champion/splash/${championRight.id}_0.jpg` + + // https://ddragon.leagueoflegends.com/cdn/img/perk-images/Styles/RunesIcon.png + const runesLeftFull = getDDragonPathsFromRunes(runesLeft) + const runesRightFull = getDDragonPathsFromRunes(runesRight) + + const applyImages = (prefix, runes) => { + $(`#${prefix}-rune-primary`).attr('src', runes.primary); + $(`#${prefix}-rune-primary-1`).attr('src', runes.primary1); + $(`#${prefix}-rune-primary-2`).attr('src', runes.primary2); + $(`#${prefix}-rune-primary-3`).attr('src', runes.primary3); + $(`#${prefix}-rune-secondary-1`).attr('src', runes.secondary1); + $(`#${prefix}-rune-secondary-2`).attr('src', runes.secondary2); + } + + $('.red-box').removeClass('hidden'); + $('.blue-box').removeClass('hidden'); + + $('.blue-box').css('background-image', `url(${splashLinkLeft})`); + $('.red-box').css('background-image', `url(${splashLinkRight})`); + + applyImages('blue', runesLeftFull); + applyImages('red', runesRightFull); + } + + previousState = data.state; +} + +const tick = async () => { + const data = await this.LPTE.request({ + meta: { + namespace: 'rcv-rune-gfx', + type: 'request', + version: 1 + } + }); + updateUi(data.state); +} + +window.LPTE.onready(() => { + tick() + setTimeout(tick, 100) + // setInterval(tick, 1000) + + window.LPTE.on('rcv-rune-gfx', 'update', data => { + const timeout = previousState === 'HIDDEN' ? 1 : 1000 + updateUi(data.state) + setTimeout(() => updateUi(data.state), timeout) + }) +}) diff --git a/frontend/gfx-style.css b/frontend/gfx-style.css new file mode 100644 index 0000000..dc94a85 --- /dev/null +++ b/frontend/gfx-style.css @@ -0,0 +1,65 @@ +.box.hidden { + width: 0 !important; +} + +.box { + position: absolute; + width: 800px; + height: 260px; + + bottom: 109px; + + transition: width 1s ease-in-out; + + background-size: cover; + background-position: top center; +} +.blue-box { + right: calc(50% + 80px); +} +.red-box { + left: calc(50% + 80px); +} + +.box-content { + position: relative; + width: 100%; + height: 100%; + overflow: hidden; +} + +.runes { + position: absolute; + bottom: 0; + + width: 100%; + height: 60px; + background: rgba(0, 0, 0, 0.5); +} + +.runes-content { + width: 500px; + height: 100%; + margin: 0 auto; + + display: flex; + flex-direction: row; + align-items: center; + justify-content: space-between; +} + +.rune { + margin: 0 20px; +} + +.rune.small { + height: 60%; +} + +.rune.primary { + height: 90%; +} + +.rune.spacing { + width: 20px; +} \ No newline at end of file diff --git a/frontend/gfx.html b/frontend/gfx.html new file mode 100644 index 0000000..d18acfa --- /dev/null +++ b/frontend/gfx.html @@ -0,0 +1,43 @@ + + + RCV Rune GFX + + + + + + + + + + + + \ No newline at end of file diff --git a/frontend/index.html b/frontend/index.html new file mode 100644 index 0000000..d5505c8 --- /dev/null +++ b/frontend/index.html @@ -0,0 +1,18 @@ + + +

RCVolus Runes: Operator Cockpit

+

Preview

+
+ +
+ +

State

+

State: LOADING

+

Data state: LOADING

+ + + + + +

Embed

+ \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..fdc632a --- /dev/null +++ b/package.json @@ -0,0 +1,15 @@ +{ + "name": "rcv-rune-gfx", + "version": "1.0.0", + "description": "Module that provides GFX elements for runes (reforged) League of Legends games", + "author": "Larce", + "license": "MIT", + "toolkit": { + "modes": [ + "PLUGIN" + ], + "plugin": { + "main": "plugin.js" + } + } +} diff --git a/plugin.js b/plugin.js new file mode 100644 index 0000000..cc3f356 --- /dev/null +++ b/plugin.js @@ -0,0 +1,118 @@ +const namespace = 'rcv-rune-gfx'; + +const initialState = { + state: 'HIDDEN', + dataState: 'NO_GAME', + participants: [] +} + +module.exports = (ctx) => { + const gfxState = initialState; + + const emitUpdate = () => { + ctx.LPTE.emit({ + meta: { + type: 'update', + namespace, + version: 1 + }, + state: gfxState + }); + } + + // Register new UI page + ctx.LPTE.emit({ + meta: { + type: 'add-pages', + namespace: 'ui', + version: 1 + }, + pages: [{ + name: 'OP: rcv-rune-gfx', + frontend: 'frontend', + id: 'op-rcv-rune-gfx' + }] + }); + + // Answer requests to get state + ctx.LPTE.on(namespace, 'request', e => { + ctx.LPTE.emit({ + meta: { + type: e.meta.reply, + namespace: 'reply', + version: 1 + }, + state: gfxState + }); + }); + + ctx.LPTE.on('state-league', 'live-game-loaded', e => { + gfxState.participants = e.state.web.live.participants; + // console.log(e) + gfxState.dataState = 'READY' + emitUpdate() + }); + + // Move a step forward in animation + ctx.LPTE.on(namespace, 'next-step', async e => { + if (gfxState.dataState !== 'READY') { + return; + } + + if (gfxState.state === 'HIDDEN') { + // Show + gfxState.state = '1'; + } else if (gfxState.state === '5') { + // End + gfxState.state = 'HIDDEN'; + } else { + let number = parseInt(gfxState.state); + number++; + gfxState.state = number.toString(); + } + emitUpdate() + }); + + // Move a step backward in animation + ctx.LPTE.on(namespace, 'previous-step', async e => { + if (gfxState.dataState !== 'READY') { + return; + } + + if (gfxState.state === 'HIDDEN') { + // Show + gfxState.state = '5'; + } else if (gfxState.state === '1') { + // End + gfxState.state = 'HIDDEN'; + } else { + let number = parseInt(gfxState.state); + number--; + gfxState.state = number.toString(); + } + emitUpdate() + }); + + ctx.LPTE.on(namespace, 'reset', e => { + gameState.state = 'UNSET'; + + ctx.LPTE.emit({ + meta: { + namespace: 'reply', + type: e.meta.reply, + version: 1 + } + }); + emitUpdate() + }); + + // Emit event that we're ready to operate + ctx.LPTE.emit({ + meta: { + type: 'plugin-status-change', + namespace: 'lpt', + version: 1 + }, + status: 'RUNNING' + }); +};