From fe0ec3a2c7364e319dfd60453dc495222edb37d4 Mon Sep 17 00:00:00 2001 From: Stephen Jianu Date: Mon, 12 Sep 2022 23:58:44 -0500 Subject: [PATCH 01/37] Strip out Electron and NodeJS-specific functions to get the game working on a basic level --- README.md | 16 ++++++++++++++++ sources/index.html | 5 ----- sources/scripts/card.js | 1 - sources/scripts/lib/controller.js | 8 -------- 4 files changed, 16 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 9edb616..b64c04f 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,18 @@ # DonsolJavascript Javascript version of Donsol + +### Original authors +The original Javascript+Electron version of Donsol was created by Hundred Rabbits. + +### About this branch +This branch ("web") will be used for development on the web-based version of Donsol, which in turn is heavily based on the main branch, stripping out parts related to Electron and NodeJS. +None of this is official; it's a passion project, so please do not contact Hundred Rabbits regarding issues with this web version of the game. + +### Limitations +In the project's current state, you can play the base game of Donsol, with some limitations. +The following do not currently work: +* Card faces do not render properly, as these were previously loaded with NodeJS functions that aren't available to use in a pure browser-based application (as far as I'm aware). I have an idea on how to accomplish this. +* Aspects of the game that relied on being selected from a menu in the Electron version currently have no way of being toggled. These include things like difficulty selection and themeing support. + +### Contributing +If you wish to contribute to the project, please follow the standard practice of forking this repository and submitting a pull request. diff --git a/sources/index.html b/sources/index.html index 9560a1e..93bb5b4 100644 --- a/sources/index.html +++ b/sources/index.html @@ -44,9 +44,6 @@ diff --git a/sources/scripts/card.js b/sources/scripts/card.js index a2d325e..c253ea5 100644 --- a/sources/scripts/card.js +++ b/sources/scripts/card.js @@ -26,7 +26,6 @@ function Card (sym, value, type, name = 'Unknown') { const graphic = document.createElement('div') graphic.className = 'graphic' - graphic.innerHTML = require('fs').readFileSync(`${__dirname}/media/${this.type}/${this.value}.svg`) face.appendChild(graphic) // Name diff --git a/sources/scripts/lib/controller.js b/sources/scripts/lib/controller.js index 365c368..99c3e5f 100644 --- a/sources/scripts/lib/controller.js +++ b/sources/scripts/lib/controller.js @@ -4,8 +4,6 @@ function Controller () { this.menu = { default: {} } this.mode = 'default' - this.app = require('electron').remote.app - this.start = function () { } @@ -45,10 +43,6 @@ function Controller () { return f } - this.commit = function () { - this.app.inject_menu(this.format()) - } - this.docs = function () { console.log('Generating docs..') const svg = this.generate_svg(this.format()) @@ -181,5 +175,3 @@ function Controller () { { x: 540, y: 240, width: 90, height: 60, name: 'alt' } ] } - -module.exports = new Controller() From ff787f7e64d67119c0da34b9c9f15c72f2d6955c Mon Sep 17 00:00:00 2001 From: Stephen Jianu Date: Wed, 21 Sep 2022 20:15:40 -0500 Subject: [PATCH 02/37] Place SVG in card definitions and load from those --- sources/scripts/card.js | 4 +- sources/scripts/card.monster.js | 4 +- sources/scripts/card.potion.js | 4 +- sources/scripts/card.shield.js | 4 +- sources/scripts/deck.js | 108 ++++++++++++++++---------------- 5 files changed, 63 insertions(+), 61 deletions(-) diff --git a/sources/scripts/card.js b/sources/scripts/card.js index c253ea5..51f12e9 100644 --- a/sources/scripts/card.js +++ b/sources/scripts/card.js @@ -1,10 +1,11 @@ 'use strict' -function Card (sym, value, type, name = 'Unknown') { +function Card (sym, value, type, name = 'Unknown', svg = '') { this.symbol = sym this.value = value this.type = type this.name = name + this.svg = svg this.element = null this.is_flipped = false @@ -26,6 +27,7 @@ function Card (sym, value, type, name = 'Unknown') { const graphic = document.createElement('div') graphic.className = 'graphic' + graphic.innerHTML = this.svg face.appendChild(graphic) // Name diff --git a/sources/scripts/card.monster.js b/sources/scripts/card.monster.js index 2644db7..8382a45 100644 --- a/sources/scripts/card.monster.js +++ b/sources/scripts/card.monster.js @@ -1,7 +1,7 @@ 'use strict' -function Card_Monster (sym, value, type, name = 'Unknown') { - Card.call(this, sym, value, type, name) +function Card_Monster (sym, value, type, name = 'Unknown', svg = '') { + Card.call(this, sym, value, type, name, svg) this.touch = function () { if (this.is_flipped) { console.log('Card is already flipped'); return } diff --git a/sources/scripts/card.potion.js b/sources/scripts/card.potion.js index aa3d600..259f3af 100644 --- a/sources/scripts/card.potion.js +++ b/sources/scripts/card.potion.js @@ -1,7 +1,7 @@ 'use strict' -function Card_Potion (sym, value, type, name = 'Unknown') { - Card.call(this, sym, value, type, name) +function Card_Potion (sym, value, type, name = 'Unknown', svg = '') { + Card.call(this, sym, value, type, name, svg) this.touch = function () { if (this.is_flipped) { console.log('Card is already flipped'); return } diff --git a/sources/scripts/card.shield.js b/sources/scripts/card.shield.js index 19cd345..283ed10 100644 --- a/sources/scripts/card.shield.js +++ b/sources/scripts/card.shield.js @@ -1,7 +1,7 @@ 'use strict' -function Card_Shield (sym, value, type, name = 'Unknown') { - Card.call(this, sym, value, type, name) +function Card_Shield (sym, value, type, name = 'Unknown', svg = '') { + Card.call(this, sym, value, type, name, svg) this.touch = function () { if (this.is_flipped == true) { console.log('Card is already flipped'); return } diff --git a/sources/scripts/deck.js b/sources/scripts/deck.js index acf974e..502ee19 100644 --- a/sources/scripts/deck.js +++ b/sources/scripts/deck.js @@ -2,60 +2,60 @@ function Deck () { this.cards = [ - new Card_Potion('A', 11, HEART, 'White Mage'), - new Card_Potion('2', 2, HEART, 'Small Potion'), - new Card_Potion('3', 3, HEART, 'Small Potion'), - new Card_Potion('4', 4, HEART, 'Medium Potion'), - new Card_Potion('5', 5, HEART, 'Medium Potion'), - new Card_Potion('6', 6, HEART, 'Medium Potion'), - new Card_Potion('7', 7, HEART, 'Medium Potion'), - new Card_Potion('8', 8, HEART, 'Medium Potion'), - new Card_Potion('9', 9, HEART, 'Large Potion'), - new Card_Potion('10', 10, HEART, 'Large Potion'), - new Card_Potion('V', 11, HEART, 'White Mage'), - new Card_Potion('Q', 11, HEART, 'White Mage'), - new Card_Potion('K', 11, HEART, 'White Mage'), - new Card_Shield('A', 11, DIAMOND, 'Red Mage'), - new Card_Shield('2', 2, DIAMOND, 'Buckler'), - new Card_Shield('3', 3, DIAMOND, 'Buckler'), - new Card_Shield('4', 4, DIAMOND, 'Shield'), - new Card_Shield('5', 5, DIAMOND, 'Shield'), - new Card_Shield('6', 6, DIAMOND, 'Shield'), - new Card_Shield('7', 7, DIAMOND, 'Shield'), - new Card_Shield('8', 8, DIAMOND, 'Shield'), - new Card_Shield('9', 9, DIAMOND, 'Large Shield'), - new Card_Shield('10', 10, DIAMOND, 'Large Shield'), - new Card_Shield('V', 11, DIAMOND, 'Red Mage'), - new Card_Shield('Q', 11, DIAMOND, 'Red Mage'), - new Card_Shield('K', 11, DIAMOND, 'Red Mage'), - new Card_Monster('A', 17, CLOVE, 'Empress'), - new Card_Monster('2', 2, CLOVE, 'Rat'), - new Card_Monster('3', 3, CLOVE, 'Bat'), - new Card_Monster('4', 4, CLOVE, 'Imp'), - new Card_Monster('5', 5, CLOVE, 'Goblin'), - new Card_Monster('6', 6, CLOVE, 'Orc'), - new Card_Monster('7', 7, CLOVE, 'Ogre'), - new Card_Monster('8', 8, CLOVE, 'Beholder'), - new Card_Monster('9', 9, CLOVE, 'Medusa'), - new Card_Monster('10', 10, CLOVE, 'Demon'), - new Card_Monster('V', 11, CLOVE, 'Consort'), - new Card_Monster('Q', 13, CLOVE, 'Queen'), - new Card_Monster('K', 15, CLOVE, 'Regnant'), - new Card_Monster('A', 17, SPADE, 'Empress'), - new Card_Monster('2', 2, SPADE, 'Slime'), - new Card_Monster('3', 3, SPADE, 'Tunneler'), - new Card_Monster('4', 4, SPADE, 'Fiend'), - new Card_Monster('5', 5, SPADE, 'Drake'), - new Card_Monster('6', 6, SPADE, 'Specter'), - new Card_Monster('7', 7, SPADE, 'Ghost'), - new Card_Monster('8', 8, SPADE, 'Elemental'), - new Card_Monster('9', 9, SPADE, 'Witch'), - new Card_Monster('10', 10, SPADE, 'Familiar'), - new Card_Monster('V', 11, SPADE, 'Consort'), - new Card_Monster('Q', 13, SPADE, 'Queen'), - new Card_Monster('K', 15, SPADE, 'Regnant'), - new Card_Monster('J', 21, JOKER, 'First Donsol'), - new Card_Monster('J', 21, JOKER, 'Second Donsol') + new Card_Potion('A', 11, HEART, 'White Mage', ''), + new Card_Potion('2', 2, HEART, 'Small Potion', ''), + new Card_Potion('3', 3, HEART, 'Small Potion', ''), + new Card_Potion('4', 4, HEART, 'Medium Potion', ''), + new Card_Potion('5', 5, HEART, 'Medium Potion', ''), + new Card_Potion('6', 6, HEART, 'Medium Potion', ''), + new Card_Potion('7', 7, HEART, 'Medium Potion', ''), + new Card_Potion('8', 8, HEART, 'Medium Potion', ''), + new Card_Potion('9', 9, HEART, 'Large Potion', ''), + new Card_Potion('10', 10, HEART, 'Large Potion', ''), + new Card_Potion('V', 11, HEART, 'White Mage', ''), + new Card_Potion('Q', 11, HEART, 'White Mage', ''), + new Card_Potion('K', 11, HEART, 'White Mage', ''), + new Card_Shield('A', 11, DIAMOND, 'Red Mage', ''), + new Card_Shield('2', 2, DIAMOND, 'Buckler', ''), + new Card_Shield('3', 3, DIAMOND, 'Buckler', ''), + new Card_Shield('4', 4, DIAMOND, 'Shield', ''), + new Card_Shield('5', 5, DIAMOND, 'Shield', ''), + new Card_Shield('6', 6, DIAMOND, 'Shield', ''), + new Card_Shield('7', 7, DIAMOND, 'Shield', ''), + new Card_Shield('8', 8, DIAMOND, 'Shield', ''), + new Card_Shield('9', 9, DIAMOND, 'Large Shield', ''), + new Card_Shield('10', 10, DIAMOND, 'Large Shield', ''), + new Card_Shield('V', 11, DIAMOND, 'Red Mage', ''), + new Card_Shield('Q', 11, DIAMOND, 'Red Mage', ''), + new Card_Shield('K', 11, DIAMOND, 'Red Mage', ''), + new Card_Monster('A', 17, CLOVE, 'Empress', ''), + new Card_Monster('2', 2, CLOVE, 'Rat', ''), + new Card_Monster('3', 3, CLOVE, 'Bat', ''), + new Card_Monster('4', 4, CLOVE, 'Imp', ''), + new Card_Monster('5', 5, CLOVE, 'Goblin', ''), + new Card_Monster('6', 6, CLOVE, 'Orc', ''), + new Card_Monster('7', 7, CLOVE, 'Ogre', ''), + new Card_Monster('8', 8, CLOVE, 'Beholder', ''), + new Card_Monster('9', 9, CLOVE, 'Medusa', ''), + new Card_Monster('10', 10, CLOVE, 'Demon', ''), + new Card_Monster('V', 11, CLOVE, 'Consort', ''), + new Card_Monster('Q', 13, CLOVE, 'Queen', ''), + new Card_Monster('K', 15, CLOVE, 'Regnant', ''), + new Card_Monster('A', 17, SPADE, 'Empress', ''), + new Card_Monster('2', 2, SPADE, 'Slime', ''), + new Card_Monster('3', 3, SPADE, 'Tunneler', ''), + new Card_Monster('4', 4, SPADE, 'Fiend', ''), + new Card_Monster('5', 5, SPADE, 'Drake', ''), + new Card_Monster('6', 6, SPADE, 'Specter', ''), + new Card_Monster('7', 7, SPADE, 'Ghost', ''), + new Card_Monster('8', 8, SPADE, 'Elemental', ''), + new Card_Monster('9', 9, SPADE, 'Witch', ''), + new Card_Monster('10', 10, SPADE, 'Familiar', ''), + new Card_Monster('V', 11, SPADE, 'Consort', ''), + new Card_Monster('Q', 13, SPADE, 'Queen', ''), + new Card_Monster('K', 15, SPADE, 'Regnant', ''), + new Card_Monster('J', 21, JOKER, 'First Donsol', ''), + new Card_Monster('J', 21, JOKER, 'Second Donsol', '') ] let draw_pile = [] From 08ca381a9fef271073860185a709643d72fd2257 Mon Sep 17 00:00:00 2001 From: Stephen Jianu Date: Wed, 21 Sep 2022 20:31:54 -0500 Subject: [PATCH 03/37] Mention that the card face rendering issue has been fixed --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b64c04f..fb62911 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ None of this is official; it's a passion project, so please do not contact Hundr ### Limitations In the project's current state, you can play the base game of Donsol, with some limitations. The following do not currently work: -* Card faces do not render properly, as these were previously loaded with NodeJS functions that aren't available to use in a pure browser-based application (as far as I'm aware). I have an idea on how to accomplish this. +* ~~Card faces do not render properly, as these were previously loaded with NodeJS functions that aren't available to use in a pure browser-based application (as far as I'm aware). I have an idea on how to accomplish this.~~ Fixed in commit ff787f7 * Aspects of the game that relied on being selected from a menu in the Electron version currently have no way of being toggled. These include things like difficulty selection and themeing support. ### Contributing From 729c71fac011c7cb2cea3dead1656f77381332e7 Mon Sep 17 00:00:00 2001 From: Stephen Jianu Date: Sun, 31 Dec 2023 16:29:17 -0600 Subject: [PATCH 04/37] Add Settings panel with a button to change themes Only 2 themes besides the default are implemented for now. More to come! --- sources/index.html | 1 + sources/links/main.css | 8 +++++--- sources/links/theme.css | 4 ++-- sources/scripts/donsol.js | 26 ++++++++++++++++++++++++-- sources/scripts/player.js | 21 ++++++++++++++++++++- sources/scripts/settings.js | 22 ++++++++++++++++++++++ 6 files changed, 74 insertions(+), 8 deletions(-) create mode 100644 sources/scripts/settings.js diff --git a/sources/index.html b/sources/index.html index 93bb5b4..e8ba85a 100644 --- a/sources/index.html +++ b/sources/index.html @@ -18,6 +18,7 @@ + diff --git a/sources/links/main.css b/sources/links/main.css index b127901..e7d4cc6 100644 --- a/sources/links/main.css +++ b/sources/links/main.css @@ -2,15 +2,17 @@ body { background:black; font-family: 'input_mono_regular',monospace; min-width: #wrapper { display: block;max-width: 900px; height: calc(25vw * 1.25 + 90px);max-height:400px;margin:0px auto;position: relative;width:100%; -webkit-app-region: drag;} -#player { display: block; font-size:12px; height:30px; line-height:20px; max-width:890px; -webkit-user-select: none;-webkit-app-region: drag; position: fixed; bottom:30px; width:calc(100% - 60px);} +#player { display: block; font-size:12px; height:30px; line-height:20px; max-width:890px; -webkit-user-select: none;-webkit-app-region: drag; position: fixed; bottom:60px; width:calc(100% - 60px);} #player > * { vertical-align: top } #player .gage { width: 120px;display: block;height:30px;position: relative; float:right; margin-left:2px;width:70px; padding-right: 50px; text-align: right} #player .gage .value { display: inline-block;line-height: 20px;font-family: 'input_mono_medium';padding-left: 5px;} #player .gage .event { display: inline-block;position: absolute;top: -20px;left: 0px; transition: all 250ms; opacity: 0; margin-left:5px; display: none} #player .gage .progress { display: block;width: 40px;position: absolute; top:7px;overflow: hidden;height: 4px;border-radius: 20px;right:0px;} #player .gage .progress .bar{ height:5px; display:block !important; transition: width 300ms} -#player a.escape { -webkit-app-region: no-drag;padding: 0px 8px;border-radius: 20px;display: inline-block;margin-right: 10px;line-height: 20px; border:2px solid white; margin-top:0px; color:white;} -#player a.escape:hover { cursor: pointer; } +#player .button { -webkit-app-region: no-drag;padding: 0px 8px;border-radius: 20px;display: inline-block;margin-right: 10px;line-height: 20px; border:2px solid white; margin-top:0px; color:white;} +#player .button:hover { cursor: pointer; } +#player select.button { appearance: none;-webkit-appearance: none;background-color: transparent; } +#player .settings { text-align: right; } #player div#timeline { display: inline-block;color:white; transition: opacity 250ms; opacity: 0 } #player div#timeline b { font-family: 'input_mono_medium',monospace; } diff --git a/sources/links/theme.css b/sources/links/theme.css index 9430a8b..92ad78c 100644 --- a/sources/links/theme.css +++ b/sources/links/theme.css @@ -29,8 +29,8 @@ svg .fill_grey { opacity:0.25; fill:var(--f_low) !important } /* White */ svg .fill_white { fill:var(--b_high) !important } -#player a.escape { border:2px solid var(--b_high) !important; color: var(--b_high); } -#player a.escape:hover { background-color:var(--b_high) !important; color:var(--background); } +#player .button { border:2px solid var(--b_high) !important; color: var(--b_high); } +#player .button:hover { background-color:var(--b_high) !important; color:var(--background); } #board card .face { background-color:var(--b_high)} .card_11 .face .name,.card_13 .face .name,.card_15 .face .name,.card_17 .face .name { color:var(--b_high);} #player .gage { color:var(--b_high) } diff --git a/sources/scripts/donsol.js b/sources/scripts/donsol.js index 2553a1a..e0e2656 100644 --- a/sources/scripts/donsol.js +++ b/sources/scripts/donsol.js @@ -7,7 +7,7 @@ const SPADE = 'spade' const JOKER = 'joker' function Donsol () { - const defaultTheme = { + this.defaultTheme = { background: '#000000', f_high: '#000000', f_med: '#a93232', @@ -18,8 +18,30 @@ function Donsol () { b_low: '#333333', b_inv: '#a93232' } + this.gameboyTheme = { + background: '#9BBC0F', + f_high: '#0F380F', + f_med: '#0F380F', + f_low: '#306230', + f_inv: '#9BBC0F', + b_high: '#8BAC0F', + b_med: '#8BAC0F', + b_low: '#9BBC0F', + b_inv: '#0F380F' + } + this.nightowlTheme = { + background: '#011627', + f_high: '#7fdbca', + f_med: '#82aaff', + f_low: '#c792ea', + f_inv: '#637777', + b_high: '#5f7e97', + b_med: '#456075', + b_low: '#2f4759', + b_inv: '#7fdbca' + } - this.theme = new Theme(defaultTheme) + this.theme = new Theme(this.defaultTheme) this.deck = new Deck() this.board = new Board() diff --git a/sources/scripts/player.js b/sources/scripts/player.js index bf7ef5e..d787b91 100644 --- a/sources/scripts/player.js +++ b/sources/scripts/player.js @@ -5,6 +5,7 @@ function Player () { this.health = new Gage_Health('Health', 21, '#ff0000') this.shield = new Gage_Shield('Shield', 0, '#72dec2') this.experience = new Gage('Experience', 0, '#ffffff') + this.settings = new Settings() this.can_drink = true this.has_escaped = false @@ -33,11 +34,12 @@ function Player () { } this.install = function () { + this.element.appendChild(this.settings.install()) this.element.appendChild(this.experience.install()) this.element.appendChild(this.shield.install()) this.element.appendChild(this.health.install()) - this.escape_button.setAttribute('class', 'escape') + this.escape_button.setAttribute('class', 'escape button') this.escape_button.innerHTML = 'Escape' this.element.appendChild(this.escape_button) this.timeline_element.setAttribute('class', 'timeline') @@ -145,6 +147,23 @@ function Player () { donsol.timeline.add_event('Escaped the room!') } + this.change_theme = function (theme_value) { + let new_theme = '' + if (theme_value.localeCompare('theme') === 0) { + new_theme = donsol.defaultTheme + } + if (theme_value.localeCompare('gameboy') === 0) { + new_theme = donsol.gameboyTheme + } + if (theme_value.localeCompare('nightowl') === 0) { + new_theme = donsol.nightowlTheme + } + donsol.theme = new Theme(new_theme) + donsol.theme.load(new_theme) + donsol.theme.install(document.body) + donsol.theme.start() + } + this.update = function () { if (this.health.value < 1) { this.escape_button.innerHTML = 'Restart' diff --git a/sources/scripts/settings.js b/sources/scripts/settings.js new file mode 100644 index 0000000..773d6dc --- /dev/null +++ b/sources/scripts/settings.js @@ -0,0 +1,22 @@ +'use strict' + +function Settings () { + this.element = null + this.theme_button = null + + this.install = function () { + this.element = document.createElement('div') + this.element.setAttribute('class', 'settings') + + this.theme_button = document.createElement('select') + this.theme_button.setAttribute('class', 'theme button') + this.theme_button.innerHTML = '' + this.theme_button.innerHTML += '' + this.theme_button.innerHTML += '' + this.theme_button.addEventListener('mousedown', () => { donsol.player.change_theme(this.theme_button.value) }) + + this.element.appendChild(this.theme_button) + + return this.element + } +} From 13bf2d15290102d2e5bc14342daee3d8e8be2f56 Mon Sep 17 00:00:00 2001 From: Stephen Jianu Date: Sun, 31 Dec 2023 16:39:20 -0600 Subject: [PATCH 05/37] Switch themes on