Compare commits
439 Commits
archive/es
...
release/0.
| Author | SHA1 | Date | |
|---|---|---|---|
| d075963a77 | |||
| 1d777b422b | |||
| c5ea76f7de | |||
| 62e5a044c1 | |||
| 459d1a121b | |||
| afcf8530e6 | |||
| 022d4c8a22 | |||
| 985d03c716 | |||
| 88f1973e97 | |||
| 0da6bcad9c | |||
| 8a66bd18f9 | |||
| 734a3a6bc2 | |||
| 33035e29b7 | |||
| 5490162365 | |||
| 4274570e2f | |||
| 9d1b8e069f | |||
| be10ebf97a | |||
| b22be297c4 | |||
| 3085622579 | |||
| 392e042615 | |||
| 22ed3a0fba | |||
| 712c5bc7e2 | |||
| 29ae3ae5ef | |||
| ed0ac3c59f | |||
| 3946947331 | |||
| 27820d6d99 | |||
| cc060d6147 | |||
| fba8c70103 | |||
| 2af4bea9b8 | |||
| d47b4f40cc | |||
| 7aeab80166 | |||
| 0a986268cb | |||
| f86bebd7ca | |||
| eca4cc1d7b | |||
| 372d7cb3fe | |||
| 8432bcd3f8 | |||
| a86ebb6526 | |||
| f90b094fb4 | |||
| 333b6d6824 | |||
| 9bcb4445cc | |||
| 0acd750bf5 | |||
| db03051a8d | |||
| d1dc2d1219 | |||
| d4ff624914 | |||
| 947ecc08f0 | |||
| 20098b250d | |||
| 233723e47e | |||
| 1562bcb4bb | |||
| 07b3208dfc | |||
| 7254168f23 | |||
| 05c88881db | |||
| 50e5402c40 | |||
| 1665d77602 | |||
| f367f31d28 | |||
| c41165c193 | |||
| 537a082f20 | |||
| 5bc0362918 | |||
| 13ec6d6080 | |||
| 2a5a0dfbfb | |||
| 703193513f | |||
| 2c8f2fed4b | |||
| 420a4c5cd2 | |||
| 7d32cbb659 | |||
| 8377181bef | |||
| d7d73351fc | |||
| 369628256e | |||
| 0303316c4b | |||
| ffc5491733 | |||
| cd067dd8b0 | |||
| 77520ddaea | |||
| fa0e43982d | |||
| 3e68c2eeeb | |||
| 43728d8190 | |||
| 8b7ad7fe4a | |||
| b5202e462c | |||
| 78eb9f5235 | |||
| 98ef52a19e | |||
| d1c5d159a5 | |||
| eddd73036e | |||
| 2e5895a36f | |||
| 2a15b5466d | |||
| 784236fe5c | |||
| 378780a5f3 | |||
| 0ef823b500 | |||
| f271d13877 | |||
| ecb266ec34 | |||
| f645e8055c | |||
| c013f5412a | |||
| 00a43ccbdb | |||
| 3430fe2e7c | |||
| 54a8ba491e | |||
| 076f666125 | |||
| 44b1f0b884 | |||
| 1df26a6b28 | |||
| 02dcf8ed64 | |||
| d04cca26f8 | |||
| 3e1bf6a8af | |||
| dcd1082e67 | |||
| 9c435b7777 | |||
| 6c9ab5775a | |||
| c625c15f9d | |||
| d36b5010f9 | |||
| 96b0de7405 | |||
| 5f4ab5354e | |||
| fb8b7541f5 | |||
| 12dcdc4c86 | |||
| 5f58980496 | |||
| fdda79be2d | |||
| e1a74ed87d | |||
| 6230a219fd | |||
| c0bc458440 | |||
| 6b9b57dbd4 | |||
| 33fb914ea0 | |||
| 0c14d68393 | |||
| 5a3feeb5a3 | |||
| 36423bfa54 | |||
| 378e11d8a5 | |||
| c6fcab6b11 | |||
| 1c1f32e2aa | |||
| 325aacaae6 | |||
| 1d4bc3bb6d | |||
| 9d17301d52 | |||
| ab7af66259 | |||
| debf48ad15 | |||
| 57db233d4e | |||
| 016210c1d9 | |||
| 36b8d58d9e | |||
| 81dcfb2bff | |||
| 78350d5533 | |||
| f52ea5d9fd | |||
| c97c49e902 | |||
| 8ebd345dd2 | |||
| 279b427b32 | |||
| a316c1fe60 | |||
| 22c2e40203 | |||
| fc868cf6f7 | |||
| 8a006ac0ff | |||
| d743c77244 | |||
| a01fcfbd8f | |||
| 34d0002af3 | |||
| 9dca9affe3 | |||
| 60dce58ad0 | |||
| 38f6065055 | |||
| 21ed959322 | |||
| 1e67ec9d54 | |||
| 08165cd59d | |||
| f9abe054b2 | |||
| 91fa8cdf6b | |||
| 2f85e28aea | |||
| be1b6a2541 | |||
| 1742cc0f6e | |||
| a52fac3b09 | |||
| 5905309c44 | |||
| 990801a79e | |||
| 10c8d59442 | |||
| 7c528361eb | |||
| 33109267dd | |||
| 84697ca929 | |||
| 4f24c77a39 | |||
| e9a2b67673 | |||
| 45b8c9236c | |||
| 472d936623 | |||
| 128ab47aef | |||
| 2227e58ae3 | |||
| 19820c3d00 | |||
| 257945a5fe | |||
| e6033823cb | |||
| f5e48a95b9 | |||
| 28efc6af3d | |||
| 59044135d5 | |||
| 6b670fd6e5 | |||
| 9ad12a5d8e | |||
| 2d94dbc04d | |||
| 06082fe0ad | |||
| 4071daef78 | |||
| f4c369e744 | |||
| 514307a8ad | |||
| c6abbba1cb | |||
| eaaca3bc34 | |||
| aed598afbe | |||
| b06abcaea3 | |||
| 59136e5295 | |||
| 38da699d25 | |||
| feb6029ee6 | |||
| 83a3d257fd | |||
| 54ebc3222b | |||
| dbbb514963 | |||
| 145142bd64 | |||
| 33c4fda635 | |||
| 07678d7c06 | |||
| 3fb93c35a3 | |||
| 020ce32a06 | |||
| d9c027854d | |||
| 328feea5d8 | |||
| 0af698d76a | |||
| 884db14b39 | |||
| 059c573801 | |||
| 181bb8074c | |||
| 0f54667255 | |||
| 7196ebab75 | |||
| 942c77e996 | |||
| 8f8cfeae0a | |||
| 6bc8dc7321 | |||
| 82c6505a09 | |||
| bef7e48535 | |||
| 1cb61b20b3 | |||
| 6957802020 | |||
| b490f57c0d | |||
| a71727fba5 | |||
| 59b670b9df | |||
| 3b3adbf5cc | |||
| b06040a207 | |||
| 65af07b9d3 | |||
| b63f4b0b12 | |||
| 469441f7c3 | |||
| a142e7f16e | |||
| 28b54607c1 | |||
| bb7bdd7421 | |||
| 5231e3cdfb | |||
| 40fee71ef3 | |||
| 7e7ae506ea | |||
| e98a0e1dab | |||
| 8e4137368a | |||
| e4d01b69bf | |||
| 87f8976fdc | |||
| 6adb6cd67d | |||
| 68fc06ce2a | |||
| b4448c2b72 | |||
| 2d3a05b165 | |||
| 9af76bec8a | |||
| e800a02116 | |||
| b3df127bab | |||
| 13c89d2784 | |||
| 6df0f5e45b | |||
| cd8288427a | |||
| c7f96b9e05 | |||
| 3b28d00a46 | |||
| bf9e745339 | |||
| 53ce951c5a | |||
| fb43ffd17d | |||
| e903e380d4 | |||
| d7de450985 | |||
| 223428147a | |||
| 0cded3aff2 | |||
| 33fcc6a200 | |||
| 02ebee0c6d | |||
| d563ba2aeb | |||
| 41b21daec0 | |||
| 02ebbe4c03 | |||
| 83322d1517 | |||
| 0d9d29786c | |||
| 5c85bbd0f7 | |||
| 6ebb94ee02 | |||
| 0eee2aaee6 | |||
| 4ababd46d3 | |||
| 357a36e873 | |||
| 73ad27cbb0 | |||
| 7ec529ddf9 | |||
| 4fe0c7b4ab | |||
| 60adcefe22 | |||
| 93dfbf3488 | |||
| 8e5c54a4e8 | |||
| db0f023d21 | |||
| b8def1a7f9 | |||
| ff586fe294 | |||
| 2fccf79bb6 | |||
| d95e77f034 | |||
| eb42727f2f | |||
| 01811713a4 | |||
| cc01689116 | |||
| bced7eeba6 | |||
| aab51de647 | |||
| a55ee7e77a | |||
| 328525c8fe | |||
| a624b95f74 | |||
| 951e0e9cd1 | |||
| ef6f448b6c | |||
| 5c11e38a24 | |||
| 8cb9337f05 | |||
| 321c7608be | |||
| be1e9be9d5 | |||
| 3299e6c369 | |||
| 9c200600bb | |||
| aa74656925 | |||
| 13fed6a6ca | |||
| d3eff4e006 | |||
| a88b015faa | |||
| 6c8d542e53 | |||
| d7c00892a3 | |||
| 69c47ccfa2 | |||
| 4ff49696fa | |||
| 121f056d0d | |||
| e7f672ced7 | |||
| 9189fb3a8f | |||
| a4424a3caf | |||
| cc18b0505c | |||
| 08c1a73d02 | |||
| e7e9dbb796 | |||
| 838776d259 | |||
| cbbf507992 | |||
| 9e06ff86c6 | |||
| e2f0105e4d | |||
| f41fc361b8 | |||
| 5e1d88c333 | |||
| 8823132e8e | |||
| 2d74a87b14 | |||
| 365fe26bd1 | |||
| 5e63ef4576 | |||
| 1feef5c5cb | |||
| 359ceed121 | |||
| 77d84d1bfa | |||
| 03b6a9383a | |||
| 7d26982bb8 | |||
| 639551f23c | |||
| 928a1848ef | |||
| 973dcaf37d | |||
| d7055d412e | |||
| 253a23a68a | |||
| 2875cd2507 | |||
| 8d0fb7d395 | |||
| 20efe0465b | |||
| 68048d5562 | |||
| 54653e13f1 | |||
| 51c9e0dd8e | |||
| 4bd417870a | |||
| acffe34023 | |||
| c75601c06d | |||
| 020df3533c | |||
| d7926d64c8 | |||
| ae2276866a | |||
| 1b46372bbf | |||
| d363de412b | |||
| ea1e2cbce5 | |||
| 7c6d7f0729 | |||
| 2b7d57c802 | |||
| d987b6a03c | |||
| 7d7a2a8e9e | |||
| 3d694755c4 | |||
| 1ba6fe4c3f | |||
| f8feee5fd7 | |||
| e068e4160b | |||
| c9a13afbe8 | |||
| 9c2a6cb7e7 | |||
| 11a7724c58 | |||
| 7479320aab | |||
| e580db794d | |||
| 021b5a0491 | |||
| e108de7f0e | |||
| c4e15dcc2f | |||
| 8a7624e807 | |||
| 797ac739d4 | |||
| 66d3416b91 | |||
| 334270582c | |||
| d347b50472 | |||
| ba3634b3cc | |||
| 1b14040025 | |||
| 660a65ba0b | |||
| 6f6cd7fc55 | |||
| bd9665c67d | |||
| 8746be31c4 | |||
| dd16a02508 | |||
| 8fed526fd2 | |||
| 7a113bf151 | |||
| b6e148c2ef | |||
| 80c19824a0 | |||
| 7cdb0f5028 | |||
| 19f4f57987 | |||
| cbc4eb0181 | |||
| 777dafffab | |||
| 86ed25c512 | |||
| 37ab5a4511 | |||
| a38774b4de | |||
| 23188c463f | |||
| 5f9ede68c2 | |||
| c9d090dab8 | |||
| 0993fdb8d6 | |||
| 02c1b28580 | |||
| 86ad5965c2 | |||
| 15ee1e3ba2 | |||
| ddbcf5581e | |||
| b588754f07 | |||
| 166da8ba8e | |||
| eaf16df0c2 | |||
| c91589ec89 | |||
| 2c42dff6e5 | |||
| 4fcc62e176 | |||
| a7aab5dfb5 | |||
| b57f56eb9f | |||
| 97a57d5f3f | |||
| 3676c0ca08 | |||
| 4a1025a43b | |||
| 1d23db63c4 | |||
| 2bb1fa5b31 | |||
| e8d929bab7 | |||
| c08e04f00b | |||
| afb3fc9230 | |||
| 33e4c4c8f7 | |||
| b4dc4691e6 | |||
| 07f2b3b76d | |||
| 82dd13b017 | |||
| 0a859038bf | |||
| 0fb120466b | |||
| 9cbf8d17b2 | |||
| b377f06be0 | |||
| 0e9bb9d2c7 | |||
| d666c9e469 | |||
| 21647df329 | |||
| d706383011 | |||
| ad92def20b | |||
| 4f1e647d56 | |||
| 18cf6822e7 | |||
| d18a9ed102 | |||
| cac9055f64 | |||
| c800f04092 | |||
| 6c772da846 | |||
| 21cb204d9a | |||
| 757792a76b | |||
| 5cb741d8a7 | |||
| d624bda258 | |||
| a03bed73d7 | |||
| 9a124830c5 | |||
| aaa3953b9c | |||
| 6521b2f807 | |||
| a996af25cb | |||
| 09b02a210a | |||
| 93ee35362b | |||
| 95b7a8aa2a | |||
| 42bae89496 | |||
| f538ab07b6 | |||
| 137d696a21 | |||
| 5a5f5466f0 | |||
| 54c6ff85c8 | |||
| 351060c697 | |||
| ee81ffa5fd | |||
| 061c7b1e03 | |||
| 3b2c4855d8 | |||
| a8be2672d1 | |||
| a8c527c3e4 | |||
| f34f96e87f |
3
.editorconfig
Normal file
@@ -0,0 +1,3 @@
|
||||
[*.esc]
|
||||
indent_style = tab
|
||||
indent_size = 2
|
||||
47
.gdlintrc
Normal file
@@ -0,0 +1,47 @@
|
||||
class-definitions-order:
|
||||
- tools
|
||||
- classnames
|
||||
- extends
|
||||
- docstrings
|
||||
- signals
|
||||
- enums
|
||||
- consts
|
||||
- staticvars
|
||||
- exports
|
||||
- pubvars
|
||||
- prvvars
|
||||
- onreadypubvars
|
||||
- onreadyprvvars
|
||||
- others
|
||||
class-load-variable-name: (([A-Z][a-z0-9]*)+|_?[a-z][a-z0-9]*(_[a-z0-9]+)*)
|
||||
class-name: ([A-Z][a-z0-9]*)+
|
||||
class-variable-name: _?[a-z][a-z0-9]*(_[a-z0-9]+)*
|
||||
comparison-with-itself: null
|
||||
constant-name: _?[A-Z][A-Z0-9]*(_[A-Z0-9]+)*
|
||||
disable: []
|
||||
duplicated-load: null
|
||||
enum-element-name: '[A-Z][A-Z0-9]*(_[A-Z0-9]+)*'
|
||||
enum-name: ([A-Z][a-z0-9]*)+
|
||||
excluded_directories: !!set
|
||||
.git: null
|
||||
expression-not-assigned: null
|
||||
function-argument-name: _?[a-z][a-z0-9]*(_[a-z0-9]+)*
|
||||
function-arguments-number: 10
|
||||
function-name: (_on_([A-Z][a-z0-9]*)+(_[a-z0-9]+)*|_?[a-z][a-z0-9]*(_[a-z0-9]+)*)
|
||||
function-preload-variable-name: ([A-Z][a-z0-9]*)+
|
||||
function-variable-name: '[a-z][a-z0-9]*(_[a-z0-9]+)*'
|
||||
load-constant-name: (([A-Z][a-z0-9]*)+|_?[A-Z][A-Z0-9]*(_[A-Z0-9]+)*)
|
||||
loop-variable-name: _?[a-z][a-z0-9]*(_[a-z0-9]+)*
|
||||
max-file-lines: 1000
|
||||
max-line-length: 300
|
||||
max-public-methods: 20
|
||||
max-returns: 6
|
||||
mixed-tabs-and-spaces: null
|
||||
no-elif-return: null
|
||||
no-else-return: null
|
||||
signal-name: '[a-z][a-z0-9]*(_[a-z0-9]+)*'
|
||||
sub-class-name: _?([A-Z][a-z0-9]*)+
|
||||
tab-characters: 1
|
||||
trailing-whitespace: null
|
||||
unnecessary-pass: null
|
||||
unused-argument: null
|
||||
@@ -1,19 +0,0 @@
|
||||
name: Gitea Actions Demo
|
||||
run-name: ${{ gitea.actor }} is testing out Gitea Actions 🚀
|
||||
on: [release]
|
||||
|
||||
jobs:
|
||||
Explore-Gitea-Actions:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- run: echo "🎉 The job was automatically triggered by a ${{ gitea.event_name }} event."
|
||||
- run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by Gitea!"
|
||||
- run: echo "🔎 The name of your branch is ${{ gitea.ref }} and your repository is ${{ gitea.repository }}."
|
||||
- name: Check out repository code
|
||||
uses: actions/checkout@v3
|
||||
- run: echo "💡 The ${{ gitea.repository }} repository has been cloned to the runner."
|
||||
- run: echo "🖥️ The workflow is now ready to test your code on the runner."
|
||||
- name: List files in the repository
|
||||
run: |
|
||||
ls ${{ gitea.workspace }}
|
||||
- run: echo "🍏 This job's status is ${{ job.status }}."
|
||||
41
.gitea/workflows/push-release.yml
Normal file
@@ -0,0 +1,41 @@
|
||||
name: Gymkhana exports
|
||||
run-name: ${{ gitea.actor }} is building Gymkhanikas 🚀
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'release/*'
|
||||
- '!main'
|
||||
env:
|
||||
GODOT_VERSION: 4.5
|
||||
EXPORT_NAME: LasGymkhanikasDeUli
|
||||
PROJECT_PATH: .
|
||||
|
||||
jobs:
|
||||
all-exports:
|
||||
name: All exports
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: oierbravo/godot-ci-with-node:4.5
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
lfs: true
|
||||
- name: Setup
|
||||
run: |
|
||||
git clone https://github.com/godot-escoria/escoria-demo-game $PROJECT_PATH/../escoria-demo-game
|
||||
- name: Setup
|
||||
run: |
|
||||
mkdir -p $PROJECT_PATH/secret
|
||||
echo ${{ secrets.APPWRITE_API_CFG }} > $PROJECT_PATH/secret/api.cfg
|
||||
- name: All builds
|
||||
run: |
|
||||
./apply_patches.sh
|
||||
./build.sh
|
||||
- name: Upload Artifact
|
||||
uses: akkuman/gitea-release-action@v1
|
||||
with:
|
||||
files: |
|
||||
build/**/*.appimage
|
||||
build/**/*.tar.gz
|
||||
build/**/*.zip
|
||||
@@ -1,64 +0,0 @@
|
||||
name: Gymkhana release
|
||||
run-name: ${{ gitea.actor }} is releasing out Gymkhanikas de Uli 🚀
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
|
||||
env:
|
||||
GODOT_VERSION: 3.6
|
||||
EXPORT_NAME: gymkhana
|
||||
jobs:
|
||||
export-linux:
|
||||
name: Linux Export
|
||||
runs-on: act-latest
|
||||
container:
|
||||
image: barichello/godot-ci:3.6
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
lfs: true
|
||||
- name: Setup
|
||||
run: |
|
||||
echo $PATH
|
||||
mkdir -v -p ~/.local/share/godot/templates
|
||||
- name: Linux Build
|
||||
run: |
|
||||
mkdir -v -p build/linux
|
||||
git clone https://github.com/godot-escoria/escoria-demo-game.git
|
||||
cd addons
|
||||
ln -sf ../escoria-demo-game/addons/escoria-core escoria-core
|
||||
cd ..
|
||||
godot -v --export "Linux/X11" build/linux/Gymkhana.x86_64 --no-window
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@v1
|
||||
with:
|
||||
name: linux
|
||||
path: build/linux
|
||||
export-web:
|
||||
name: Web Export
|
||||
runs-on: act-latest
|
||||
container:
|
||||
image: barichello/godot-ci:3.6
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
lfs: true
|
||||
- name: Setup
|
||||
run: |
|
||||
echo $PATH
|
||||
mkdir -v -p ~/.local/share/godot/templates
|
||||
- name: HTML5 Build
|
||||
run: |
|
||||
mkdir -v -p build/web
|
||||
git clone https://github.com/godot-escoria/escoria-demo-game.git
|
||||
cd addons
|
||||
ln -sf ../escoria-demo-game/addons/escoria-core escoria-core
|
||||
cd ..
|
||||
godot -v --export "HTML5" build/web/index.html --no-window
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@v1
|
||||
with:
|
||||
name: web
|
||||
path: build/web
|
||||
10
.gitignore
vendored
@@ -12,4 +12,12 @@ bin
|
||||
addons/escoria-core/default_bus_layout.tres
|
||||
|
||||
.idea/
|
||||
.vscode/settings.json
|
||||
|
||||
# Optional Addons per environment.
|
||||
addons/godot-plugin-refresher/
|
||||
addons/script-ide/
|
||||
build/
|
||||
.env
|
||||
|
||||
# API credentials
|
||||
secret/
|
||||
|
||||
9
.tmp
@@ -1,9 +0,0 @@
|
||||
:look
|
||||
say player "It's a bottle."
|
||||
stop
|
||||
|
||||
:pickup
|
||||
inventory_add r9_bottle true
|
||||
set_active r9_bottle_left false
|
||||
set_active r9_bottle_middle false
|
||||
set_active r9_bottle_right false
|
||||
5
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"editor.tabSize": 4,
|
||||
"editor.insertSpaces": false,
|
||||
"editor.detectIndentation": false
|
||||
}
|
||||
83
Itch_io_publishing.patch
Normal file
@@ -0,0 +1,83 @@
|
||||
Subject: [PATCH] feat(deploy): Itch.io publishing. #203
|
||||
---
|
||||
Index: .gitea/workflows/push-release.yml
|
||||
IDEA additional info:
|
||||
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
|
||||
<+>UTF-8
|
||||
===================================================================
|
||||
diff --git a/.gitea/workflows/push-release.yml b/.gitea/workflows/push-release.yml
|
||||
--- a/.gitea/workflows/push-release.yml (revision 1c1f32e2aa839ccf963326d88f5f21bb3085ba1d)
|
||||
+++ b/.gitea/workflows/push-release.yml (revision 8d2907c071001995b91dc6234ec511729fd49137)
|
||||
@@ -34,16 +34,6 @@
|
||||
files: |
|
||||
build/**/*.appimage
|
||||
build/**/*.tar.gz
|
||||
- - name: Publish AMD to itch.io
|
||||
- uses: yeslayla/butler-publish-itchio-action@master
|
||||
- env:
|
||||
- BUTLER_CREDENTIALS: ${{ secrets.BUTLER_API_KEY }}
|
||||
- CHANNEL: linux
|
||||
- PACKAGE: build/debug/amd64/*.appimage
|
||||
- - name: Publish ARM to itch.io
|
||||
- uses: yeslayla/butler-publish-itchio-action@master
|
||||
- env:
|
||||
- BUTLER_CREDENTIALS: ${{ secrets.BUTLER_API_KEY }}
|
||||
- CHANNEL: linux
|
||||
- PACKAGE: build/debug/arm64/*.appimage
|
||||
- VERSION_FILE: build/version.txt
|
||||
\ No newline at end of file
|
||||
+ - name: Publishing
|
||||
+ run: |
|
||||
+ ./publish.sh
|
||||
\ No newline at end of file
|
||||
Index: bash_colors.sh
|
||||
===================================================================
|
||||
diff --git a/bash_colors.sh b/bash_colors.sh
|
||||
new file mode 100644
|
||||
--- /dev/null (revision 8d2907c071001995b91dc6234ec511729fd49137)
|
||||
+++ b/bash_colors.sh (revision 8d2907c071001995b91dc6234ec511729fd49137)
|
||||
@@ -0,0 +1,6 @@
|
||||
+NOCOLOR='\033[0m' # No Color
|
||||
+BLUE='\e[34m' # BrightBlue
|
||||
+BOLD_BLUE='\033[1;94m' # BrightBlue
|
||||
+GREEN='\e[49;32m' # Green
|
||||
+ORANGE='\033[1;33m'
|
||||
+RED='\033[1;31m'
|
||||
\ No newline at end of file
|
||||
Index: publish.sh
|
||||
===================================================================
|
||||
diff --git a/publish.sh b/publish.sh
|
||||
new file mode 100644
|
||||
--- /dev/null (revision 8d2907c071001995b91dc6234ec511729fd49137)
|
||||
+++ b/publish.sh (revision 8d2907c071001995b91dc6234ec511729fd49137)
|
||||
@@ -0,0 +1,29 @@
|
||||
+#!/bin/bash
|
||||
+source bash_colors.sh
|
||||
+
|
||||
+ITCHIO_ENABLED=true
|
||||
+
|
||||
+VERSION=`cat build/version.txt`
|
||||
+echo -e "Publishing ${GREEN}v${VERSION}${NOCOLOR}"
|
||||
+
|
||||
+# Publish to Itch.io
|
||||
+if [ "$ITCHIO_ENABLED" = true ] ; then
|
||||
+ echo -e "${BLUE}Publishing to Itch.io${NOCOLOR}"
|
||||
+ if ! command -v butler >/dev/null 2>&1
|
||||
+ then
|
||||
+ echo -e "${RED}butler could not be found. Aborting!${NOCOLOR}"
|
||||
+ exit 1
|
||||
+ fi
|
||||
+
|
||||
+
|
||||
+
|
||||
+ echo -e "${ORANGE}Publishing AMD64${NOCOLOR}"
|
||||
+ butler push build/debug/amd64/LasGymkhanikasDeUli--debug.x86_64.appimage uliwood/las-gymkhanikas-de-uli-turno-cocina:linux-amd64 --userversion $VERSION
|
||||
+
|
||||
+ echo -e "${ORANGE}Publishing ARM64${NOCOLOR}"
|
||||
+ butler push build/debug/arm64/LasGymkhanikasDeUli--debug.arm_64.appimage uliwood/las-gymkhanikas-de-uli-turno-cocina:linux-arm64 --userversion $VERSION
|
||||
+
|
||||
+
|
||||
+ else
|
||||
+ echo -e "${ORANGE}Itch.io not enabled.{NOCOLOR}"
|
||||
+fi
|
||||
\ No newline at end of file
|
||||
23
README.md
@@ -3,11 +3,17 @@
|
||||
Point-and-click adventure game developed using Escoria framework and Godot engine.
|
||||
|
||||
## Building from source
|
||||
### Assumed folder structure
|
||||
```
|
||||
any-folder
|
||||
├── gymkhana -> This project.
|
||||
└── escoria-demo-game -> Folder for escoria core.
|
||||
|
||||
```
|
||||
### Steps
|
||||
1) Clone `gymkhana` repo
|
||||
2) Clone `escoria-demo-game` repo (develop branch)
|
||||
3) Create `gymkhana/addons/escoria-core` symlink pointing to `escoria-demo-game/addons/escoria-core`
|
||||
|
||||
2) Clone `escoria-demo-game` repo (main branch)
|
||||
3) Apply patches from the root folder. Run: `./apply_patches.sh`
|
||||
|
||||
## Video export.
|
||||
- 1280 x 720 | 25fps
|
||||
@@ -17,4 +23,13 @@ Point-and-click adventure game developed using Escoria framework and Godot engin
|
||||
## Export
|
||||
- Web: `godot -v --export "HTML5" ../gymkhana-export-html/index.html`
|
||||
- Linux: `godot -v --export "Linux/X11" ../LasGymkhanikasDeUli-1.0-RC1.appimage`
|
||||
- ~~Windows: godot -v --export "Windows Desktop x64" ../LasGymkhanikasDeUli-1.0-RC1.exe~~
|
||||
- ~~Windows: godot -v --export "Windows Desktop x64" ../LasGymkhanikasDeUli-1.0-RC1.exe~~
|
||||
|
||||
|
||||
## Sound attributions:
|
||||
- button_clicking.ogg | Button Clicking 1 by Sheyvan -- https://freesound.org/s/475188/ -- License: Creative Commons 0
|
||||
- menu_button.ogg | Videogame Menu BUTTON CLICK by Christopherderp -- https://freesound.org/s/342200/ -- License: Creative Commons 0
|
||||
- birds_ambient_loop.ogg | https://freesound.org/people/Garuda1982/sounds/691629/ -- License: Creative Commons 0
|
||||
|
||||
## Icon attributions:
|
||||
- Translate button: Noun Project. Public domain
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
:use | TK
|
||||
say current_player "I can't use this!"
|
||||
say($player, "I can't use this!", "action_default_say")
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
uid://dpynhyggey3bb
|
||||
@@ -0,0 +1,9 @@
|
||||
[gd_scene load_steps=3 format=3 uid="uid://v5lk1jcyag2q"]
|
||||
|
||||
[ext_resource type="Theme" uid="uid://bf2eet52fueam" path="res://addons/escoria-ui-return-monkey-island/theme/ui.tres" id="1_k44u5"]
|
||||
[ext_resource type="Script" uid="uid://elqkwjm0r5c7" path="res://addons/escoria-ui-return-monkey-island/menus/rtmi_menu_button.gd" id="2_e65rn"]
|
||||
|
||||
[node name="Button" type="Button"]
|
||||
theme = ExtResource("1_k44u5")
|
||||
script = ExtResource("2_e65rn")
|
||||
with_sound = false
|
||||
@@ -2,9 +2,11 @@
|
||||
# Supports timeout and avatar display
|
||||
extends ESCDialogOptionsChooser
|
||||
|
||||
const chooser_button = preload("res://addons/escoria-ui-return-monkey-island-dialog-simple/chooser/chooser_button.tscn")
|
||||
|
||||
export(Color, RGB) var color_normal = Color(1.0,1.0,1.0,1.0)
|
||||
export(Color, RGB) var color_hover = Color(165.0,42.0,42.0, 1.0)
|
||||
|
||||
@export var color_normal = Color(1.0,1.0,1.0,1.0) # (Color, RGB)
|
||||
@export var color_hover = Color(165.0,42.0,42.0, 1.0) # (Color, RGB)
|
||||
|
||||
|
||||
var _no_more_options: bool = false
|
||||
@@ -13,14 +15,14 @@ var _no_more_options: bool = false
|
||||
# Hide the chooser at the start just to be safe
|
||||
func _ready() -> void:
|
||||
hide_chooser()
|
||||
pause_mode = PAUSE_MODE_STOP
|
||||
escoria.connect("paused", self, "_on_paused")
|
||||
escoria.connect("resumed", self, "_on_resumed")
|
||||
process_mode = PROCESS_MODE_PAUSABLE
|
||||
escoria.connect("paused", Callable(self, "_on_paused"))
|
||||
escoria.connect("resumed", Callable(self, "_on_resumed"))
|
||||
|
||||
|
||||
# Process the timeout display
|
||||
func _process(delta: float) -> void:
|
||||
if $MarginContainer.visible and self.dialog and self.dialog.timeout > 0:
|
||||
if %MarginContainer.visible and self.dialog and self.dialog.timeout > 0:
|
||||
$TimerProgress.value = (
|
||||
self.dialog.timeout - $Timer.time_left
|
||||
) / self.dialog.timeout * 100
|
||||
@@ -28,23 +30,17 @@ func _process(delta: float) -> void:
|
||||
|
||||
# Show the chooser
|
||||
func show_chooser():
|
||||
var _vbox = $MarginContainer/ScrollContainer/VBoxContainer
|
||||
var _vbox = %VBoxContainer
|
||||
for option_node in _vbox.get_children():
|
||||
_vbox.remove_child(option_node)
|
||||
|
||||
_remove_avatar()
|
||||
|
||||
for option in self.dialog.options:
|
||||
if option.is_valid():
|
||||
var _option_node = Button.new()
|
||||
var _option_node = chooser_button.instantiate()
|
||||
_option_node.text = (option as ESCDialogOption).option
|
||||
_option_node.flat = true
|
||||
_option_node.add_color_override("font_color", color_normal)
|
||||
_option_node.add_color_override("font_color_hover", color_hover)
|
||||
_vbox.add_child(_option_node)
|
||||
_option_node.connect("pressed", self, "_on_answer_selected", [
|
||||
option
|
||||
])
|
||||
|
||||
_option_node.pressed.connect(_on_answer_selected.bind(option))
|
||||
|
||||
# If we've no options left, signify as much and start the timer with a
|
||||
# very short interval so the appropriate signal can be fired. Note that
|
||||
@@ -54,21 +50,21 @@ func show_chooser():
|
||||
_no_more_options = true
|
||||
$Timer.start(0.05)
|
||||
return
|
||||
|
||||
if self.dialog.avatar != "-":
|
||||
$AvatarContainer.add_child(
|
||||
ResourceLoader.load(self.dialog.avatar).instance()
|
||||
)
|
||||
|
||||
$MarginContainer.show()
|
||||
|
||||
%MarginContainer.show()
|
||||
# Position in the middle of the screen.
|
||||
# Must be called after show
|
||||
%MarginContainer.position.x = get_viewport_rect().size.x / 2 - _vbox.size.x /2
|
||||
%MarginContainer.position.y = get_viewport_rect().size.y / 2 - _vbox.size.y /2
|
||||
|
||||
if self.dialog.timeout > 0:
|
||||
|
||||
$Timer.start(self.dialog.timeout)
|
||||
|
||||
|
||||
# Hide the chooser
|
||||
func hide_chooser():
|
||||
$MarginContainer.hide()
|
||||
%MarginContainer.hide()
|
||||
|
||||
|
||||
# An option was choosen, emit the option
|
||||
@@ -76,9 +72,8 @@ func hide_chooser():
|
||||
# #### Parameters
|
||||
# - option: Option that was chosen
|
||||
func _option_chosen(option: ESCDialogOption):
|
||||
_remove_avatar()
|
||||
$TimerProgress.value = 0
|
||||
emit_signal("option_chosen", option)
|
||||
option_chosen.emit(option)
|
||||
|
||||
|
||||
# An option was chosen directly from the list
|
||||
@@ -95,12 +90,6 @@ func _on_Timer_timeout() -> void:
|
||||
_no_more_options = false
|
||||
_option_chosen(option_chosen)
|
||||
|
||||
|
||||
# Remove the avatar
|
||||
func _remove_avatar():
|
||||
if $AvatarContainer.get_child_count() > 0:
|
||||
$AvatarContainer.remove_child($AvatarContainer.get_child(0))
|
||||
|
||||
# Handler managing pause notification from Escoria
|
||||
func _on_paused():
|
||||
hide_chooser()
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
uid://cvhue8e0ory00
|
||||
@@ -1,61 +1,62 @@
|
||||
[gd_scene load_steps=5 format=2]
|
||||
[gd_scene load_steps=5 format=3 uid="uid://nbnsf3pmh4jg"]
|
||||
|
||||
[ext_resource path="res://addons/escoria-ui-return-monkey-island-dialog-simple/chooser/simple.gd" type="Script" id=1]
|
||||
[ext_resource path="res://addons/escoria-ui-return-monkey-island-dialog-simple/theme.tres" type="Theme" id=2]
|
||||
[ext_resource type="Script" uid="uid://cvhue8e0ory00" path="res://addons/escoria-ui-return-monkey-island-dialog-simple/chooser/simple.gd" id="1"]
|
||||
[ext_resource type="Theme" uid="uid://dvwfrnya2nhxu" path="res://addons/escoria-ui-return-monkey-island-dialog-simple/theme/dialog.tres" id="2"]
|
||||
|
||||
[sub_resource type="Gradient" id=1]
|
||||
colors = PoolColorArray( 1, 0, 0, 1, 1, 0, 0, 1 )
|
||||
[sub_resource type="Gradient" id="1"]
|
||||
colors = PackedColorArray(1, 0, 0, 1, 1, 0, 0, 1)
|
||||
|
||||
[sub_resource type="GradientTexture" id=2]
|
||||
gradient = SubResource( 1 )
|
||||
[sub_resource type="GradientTexture2D" id="2"]
|
||||
gradient = SubResource("1")
|
||||
|
||||
[node name="text_dialog_choice" type="Control"]
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
margin_top = 560.0
|
||||
margin_right = 7.0
|
||||
theme = ExtResource( 2 )
|
||||
script = ExtResource( 1 )
|
||||
layout_mode = 3
|
||||
anchors_preset = 0
|
||||
size_flags_horizontal = 4
|
||||
size_flags_vertical = 4
|
||||
theme = ExtResource("2")
|
||||
script = ExtResource("1")
|
||||
color_hover = Color(0.0704665, 0.552225, 0, 1)
|
||||
|
||||
[node name="MarginContainer" type="MarginContainer" parent="."]
|
||||
margin_left = 20.0
|
||||
margin_top = 10.0
|
||||
margin_right = 1280.0
|
||||
margin_bottom = 185.0
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 1
|
||||
anchors_preset = 8
|
||||
anchor_left = 0.5
|
||||
anchor_top = 0.5
|
||||
anchor_right = 0.5
|
||||
anchor_bottom = 0.5
|
||||
offset_left = -20.0
|
||||
offset_top = -20.0
|
||||
offset_right = 20.0
|
||||
offset_bottom = 20.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
mouse_filter = 2
|
||||
custom_constants/margin_top = 20
|
||||
custom_constants/margin_left = 20
|
||||
theme_override_constants/margin_left = 20
|
||||
theme_override_constants/margin_top = 20
|
||||
theme_override_constants/margin_right = 20
|
||||
theme_override_constants/margin_bottom = 20
|
||||
|
||||
[node name="ScrollContainer" type="ScrollContainer" parent="MarginContainer"]
|
||||
margin_left = 20.0
|
||||
margin_top = 20.0
|
||||
margin_right = 1260.0
|
||||
margin_bottom = 175.0
|
||||
scroll_horizontal_enabled = false
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
clip_contents = false
|
||||
layout_mode = 2
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer/ScrollContainer"]
|
||||
margin_right = 1240.0
|
||||
margin_bottom = 155.0
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
custom_constants/separation = 10
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
theme_override_constants/separation = 10
|
||||
|
||||
[node name="Timer" type="Timer" parent="."]
|
||||
one_shot = true
|
||||
|
||||
[node name="TimerProgress" type="TextureProgress" parent="."]
|
||||
[node name="TimerProgress" type="TextureProgressBar" parent="."]
|
||||
custom_minimum_size = Vector2(0, 20)
|
||||
layout_mode = 0
|
||||
anchor_right = 1.0
|
||||
rect_min_size = Vector2( 0, 20 )
|
||||
texture_progress = SubResource( 2 )
|
||||
nine_patch_stretch = true
|
||||
|
||||
[node name="AvatarContainer" type="Node2D" parent="."]
|
||||
position = Vector2( 94, 68 )
|
||||
texture_progress = SubResource("2")
|
||||
|
||||
[connection signal="timeout" from="Timer" to="." method="_on_Timer_timeout"]
|
||||
|
||||
@@ -9,7 +9,7 @@ class_name SayLastDialogOptionCommand
|
||||
|
||||
# Return the descriptor of the arguments of this command
|
||||
func configure() -> ESCCommandArgumentDescriptor:
|
||||
return ESCCommandArgumentDescriptor.new()
|
||||
return ESCCommandArgumentDescriptor.new()
|
||||
|
||||
# Run the command
|
||||
func run(_command_params: Array) -> int:
|
||||
@@ -34,17 +34,15 @@ func run(_command_params: Array) -> int:
|
||||
return ESCExecution.RC_CANCEL
|
||||
|
||||
var last_chosen_option = escoria.globals_manager.get_global("ESC_DIALOG_CHOSEN_OPTION")
|
||||
# Surround text with quotes. Required by escoria.dialog_player.say()
|
||||
var text = "\"%s\"" % last_chosen_option
|
||||
|
||||
var speaking_character_global_id = escoria.main.current_scene.player.global_id
|
||||
|
||||
escoria.dialog_player.say(
|
||||
speaking_character_global_id,
|
||||
"",
|
||||
text
|
||||
last_chosen_option.get_translated_option(),
|
||||
last_chosen_option.get_translation_id()
|
||||
)
|
||||
yield(escoria.dialog_player, "say_finished")
|
||||
await escoria.dialog_player.say_finished
|
||||
escoria.current_state = escoria.GAME_STATE.DEFAULT
|
||||
|
||||
return ESCExecution.RC_OK
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
uid://dlsaxwtoarkon
|
||||
@@ -54,7 +54,7 @@ func configure() -> ESCCommandArgumentDescriptor:
|
||||
|
||||
# Validate whether the given arguments match the command descriptor
|
||||
func validate(arguments: Array):
|
||||
if not .validate(arguments):
|
||||
if not super.validate(arguments):
|
||||
return false
|
||||
|
||||
if arguments[0].to_upper() != CURRENT_PLAYER_KEYWORD \
|
||||
@@ -74,7 +74,7 @@ func run(command_params: Array) -> int:
|
||||
escoria.current_state = escoria.GAME_STATE.DIALOG
|
||||
var param_global_id = command_params[0]
|
||||
var param_list_id = command_params[1]
|
||||
var param_lenght = command_params[2]
|
||||
var param_length = command_params[2]
|
||||
|
||||
if !escoria.dialog_player:
|
||||
escoria.logger.error(
|
||||
@@ -94,7 +94,7 @@ func run(command_params: Array) -> int:
|
||||
escoria.current_state = escoria.GAME_STATE.DEFAULT
|
||||
return ESCExecution.RC_CANCEL
|
||||
|
||||
var text = param_list_id + "_" + String(rng.randi_range(0,param_lenght -1)) + ':" "'
|
||||
var key = param_list_id + "_" + String.num_int64(rng.randi_range(0,param_length -1))
|
||||
|
||||
var speaking_character_global_id = escoria.main.current_scene.player.global_id \
|
||||
if param_global_id.to_upper() == CURRENT_PLAYER_KEYWORD \
|
||||
@@ -102,10 +102,11 @@ func run(command_params: Array) -> int:
|
||||
|
||||
escoria.dialog_player.say(
|
||||
speaking_character_global_id,
|
||||
"",
|
||||
text
|
||||
"", # default type
|
||||
key,
|
||||
key
|
||||
)
|
||||
yield(escoria.dialog_player, "say_finished")
|
||||
await escoria.dialog_player.say_finished
|
||||
escoria.current_state = escoria.GAME_STATE.DEFAULT
|
||||
|
||||
var current_count_global_key = "%s_count" % [param_list_id]
|
||||
@@ -123,4 +124,4 @@ func interrupt():
|
||||
escoria.logger.debug(
|
||||
self,
|
||||
"[%s] interrupt() function not implemented." % get_command_name()
|
||||
)
|
||||
)
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
uid://duufh3f25hav8
|
||||
@@ -52,7 +52,7 @@ func configure() -> ESCCommandArgumentDescriptor:
|
||||
|
||||
# Validate whether the given arguments match the command descriptor
|
||||
func validate(arguments: Array):
|
||||
if not .validate(arguments):
|
||||
if not super.validate(arguments):
|
||||
return false
|
||||
|
||||
if arguments[0].to_upper() != CURRENT_PLAYER_KEYWORD \
|
||||
@@ -95,9 +95,10 @@ func run(command_params: Array) -> int:
|
||||
|
||||
var current_index_global_key = "%s_current_iteration" % [param_list_id]
|
||||
var current_index = escoria.globals_manager.get_global(current_index_global_key)
|
||||
|
||||
if(current_index == null):
|
||||
current_index = 0
|
||||
var text = '%s_%s:" "' % [param_list_id,current_index]
|
||||
var key = "%s_%s" % [param_list_id,current_index]
|
||||
|
||||
|
||||
var speaking_character_global_id = escoria.main.current_scene.player.global_id \
|
||||
@@ -107,9 +108,10 @@ func run(command_params: Array) -> int:
|
||||
escoria.dialog_player.say(
|
||||
speaking_character_global_id,
|
||||
"",
|
||||
text
|
||||
key,
|
||||
key,
|
||||
)
|
||||
yield(escoria.dialog_player, "say_finished")
|
||||
await escoria.dialog_player.say_finished
|
||||
escoria.current_state = escoria.GAME_STATE.DEFAULT
|
||||
|
||||
current_index += 1
|
||||
@@ -137,4 +139,4 @@ func interrupt():
|
||||
escoria.logger.debug(
|
||||
self,
|
||||
"[%s] interrupt() function not implemented." % get_command_name()
|
||||
)
|
||||
)
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
uid://tvxyry5g7kou
|
||||
@@ -0,0 +1,139 @@
|
||||
# `say_to_camera player text [type]`
|
||||
#
|
||||
# Displays the specified string as dialog spoken by the player. This command
|
||||
# blocks further event execution until the dialog has finished being 'said'
|
||||
# (either as displayed text or as audible speech from a file).
|
||||
#
|
||||
# Global variables can be substituted into the text by wrapping the global
|
||||
# name in braces.
|
||||
# e.g. say player "I have {coin_count} coins remaining".
|
||||
#
|
||||
# **Parameters**
|
||||
#
|
||||
# - *player*: Global ID of the `ESCPlayer` or `ESCItem` object that is active.
|
||||
# You can specify `current_player` in order to refer to the currently active
|
||||
# player, e.g. in cases where multiple players are playable such as in games
|
||||
# like Maniac Mansion or Day of the Tentacle.
|
||||
# - *text*: Text to display.
|
||||
# - *key*: Translation key (default: nil)
|
||||
# - *type*: Dialog type to use. One of `floating` or `avatar`.
|
||||
# (default: the value set in the setting "Escoria/UI/Default Dialog Type")
|
||||
#
|
||||
# The text supports translation keys by prepending the key followed by
|
||||
# a colon (`:`) to the text.
|
||||
# For more details see: https://docs.escoria-framework.org/en/devel/getting_started/dialogs.html#translations
|
||||
#
|
||||
# Playing an audio file while the text is being
|
||||
# displayed is also supported by this mechanism.
|
||||
# For more details see: https://docs.escoria-framework.org/en/devel/getting_started/dialogs.html#recorded_speech
|
||||
#
|
||||
# Example: `say(player, "Picture's looking good.", "ROOM1_PICTURE")`
|
||||
#
|
||||
# @ESC
|
||||
extends ESCBaseCommand
|
||||
class_name SayToCameraCommand
|
||||
|
||||
|
||||
const CURRENT_PLAYER_KEYWORD = "CURRENT_PLAYER"
|
||||
|
||||
const DEFAULT_CAMERA_DIRECTION = 4
|
||||
|
||||
var globals_regex : RegEx # Regex to match global variables in strings
|
||||
|
||||
|
||||
|
||||
# Constructor
|
||||
func _init() -> void:
|
||||
globals_regex = RegEx.new()
|
||||
# Use look-ahead/behind to capture the term (i.e. global) in braces
|
||||
globals_regex.compile("(?<=\\{)(.*)(?=\\})")
|
||||
|
||||
|
||||
# Return the descriptor of the arguments of this command
|
||||
func configure() -> ESCCommandArgumentDescriptor:
|
||||
return ESCCommandArgumentDescriptor.new(
|
||||
2,
|
||||
[TYPE_STRING, TYPE_STRING, TYPE_STRING, TYPE_STRING],
|
||||
[
|
||||
null,
|
||||
null,
|
||||
"",
|
||||
""
|
||||
],
|
||||
[
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
true
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
# Validate whether the given arguments match the command descriptor
|
||||
func validate(arguments: Array):
|
||||
if not super.validate(arguments):
|
||||
return false
|
||||
|
||||
if arguments[0].to_upper() != CURRENT_PLAYER_KEYWORD \
|
||||
and not escoria.object_manager.has(arguments[0]):
|
||||
raise_invalid_object_error(self, arguments[0])
|
||||
return false
|
||||
|
||||
return true
|
||||
|
||||
|
||||
# Run the command
|
||||
func run(command_params: Array) -> int:
|
||||
var dict: Dictionary
|
||||
|
||||
escoria.current_state = escoria.GAME_STATE.DIALOG
|
||||
|
||||
if !escoria.dialog_player:
|
||||
raise_error(
|
||||
self,
|
||||
"No dialog player was registered and the 'say' command was encountered."
|
||||
)
|
||||
escoria.current_state = escoria.GAME_STATE.DEFAULT
|
||||
return ESCExecution.RC_ERROR
|
||||
|
||||
if not escoria.main.current_scene.player:
|
||||
escoria.logger.warn(
|
||||
self,
|
||||
"[%s]: No player item in the current scene was registered and the say command was encountered."
|
||||
% get_command_name()
|
||||
)
|
||||
escoria.current_state = escoria.GAME_STATE.DEFAULT
|
||||
return ESCExecution.RC_CANCEL
|
||||
|
||||
# Replace the names of any globals in "{ }" with their value
|
||||
command_params[1] = escoria.globals_manager.replace_globals(command_params[1])
|
||||
|
||||
|
||||
|
||||
var speaking_character_global_id = escoria.main.current_scene.player.global_id \
|
||||
if command_params[0].to_upper() == CURRENT_PLAYER_KEYWORD \
|
||||
else command_params[0]
|
||||
var node = escoria.object_manager.get_object(command_params[0]).node
|
||||
|
||||
|
||||
escoria.object_manager.get_object(command_params[0]).node\
|
||||
.set_direction(DEFAULT_CAMERA_DIRECTION)
|
||||
|
||||
escoria.dialog_player.say(
|
||||
speaking_character_global_id,
|
||||
command_params[3],
|
||||
command_params[1],
|
||||
command_params[2]
|
||||
)
|
||||
await escoria.dialog_player.say_finished
|
||||
escoria.current_state = escoria.GAME_STATE.DEFAULT
|
||||
|
||||
return ESCExecution.RC_OK
|
||||
|
||||
|
||||
# Function called when the command is interrupted.
|
||||
func interrupt():
|
||||
escoria.logger.debug(
|
||||
self,
|
||||
"[%s] interrupt() function not implemented." % get_command_name()
|
||||
)
|
||||
@@ -0,0 +1 @@
|
||||
uid://d0sdlkjqr8f67
|
||||
@@ -1,4 +0,0 @@
|
||||
extends Label
|
||||
|
||||
func _process(_delta):
|
||||
self.visible = escoria.inputs_manager.input_mode != escoria.inputs_manager.INPUT_NONE
|
||||
@@ -1,13 +1,13 @@
|
||||
[gd_scene load_steps=3 format=2]
|
||||
[gd_scene load_steps=3 format=3 uid="uid://dyi4lxm20wgne"]
|
||||
|
||||
[ext_resource path="res://addons/escoria-ui-return-monkey-island/fonts/dialog_tip.tres" type="DynamicFont" id=1]
|
||||
[ext_resource path="res://addons/escoria-ui-return-monkey-island-dialog-simple/dialog_tip.gd" type="Script" id=2]
|
||||
[ext_resource type="Theme" uid="uid://dvpaon5mw2w8l" path="res://addons/escoria-ui-return-monkey-island/theme.tres" id="1_3renm"]
|
||||
|
||||
[node name="Label" type="Label"]
|
||||
margin_left = 1057.0
|
||||
margin_top = 533.0
|
||||
margin_right = 1259.0
|
||||
margin_bottom = 551.0
|
||||
custom_fonts/font = ExtResource( 1 )
|
||||
text = "Haz click para acelerar el texto"
|
||||
script = ExtResource( 2 )
|
||||
offset_left = 1073.0
|
||||
offset_top = 508.0
|
||||
offset_right = 1248.0
|
||||
offset_bottom = 531.0
|
||||
grow_horizontal = 0
|
||||
mouse_filter = 1
|
||||
theme = ExtResource("1_3renm")
|
||||
text = "click_to_skip_dialog"
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
"""
|
||||
Base interface for all states: it doesn't do anything in itself
|
||||
but forces us to pass the right arguments to the methods below
|
||||
and makes sure every State object had all of these methods.
|
||||
"""
|
||||
extends Node
|
||||
|
||||
|
||||
signal finished(next_state_name)
|
||||
|
||||
|
||||
# Initialize the state. E.g. change the animation
|
||||
func enter():
|
||||
return
|
||||
|
||||
|
||||
# Clean up the state. Reinitialize values like a timer
|
||||
func exit():
|
||||
return
|
||||
|
||||
|
||||
func handle_input(_event):
|
||||
return
|
||||
|
||||
|
||||
func update(_delta):
|
||||
return
|
||||
|
||||
|
||||
func _on_animation_finished(_anim_name):
|
||||
return
|
||||
@@ -1,92 +0,0 @@
|
||||
"""
|
||||
Base interface for a generic state machine
|
||||
It handles initializing, setting the machine active or not
|
||||
delegating _physics_process, _input calls to the State nodes,
|
||||
and changing the current/active state.
|
||||
"""
|
||||
extends Node
|
||||
|
||||
|
||||
signal state_changed(current_state)
|
||||
|
||||
|
||||
"""
|
||||
You must set a starting node from the inspector or on
|
||||
the node that inherits from this state machine interface
|
||||
If you don't the game will crash (on purpose, so you won't
|
||||
forget to initialize the state machine)
|
||||
"""
|
||||
export(NodePath) var START_STATE
|
||||
var states_map = {}
|
||||
|
||||
var states_stack = [] # can also be used as a pushdown automaton
|
||||
var current_state = null
|
||||
var current_state_name = ""
|
||||
var _active = false setget set_active
|
||||
|
||||
|
||||
func initialize(start_state):
|
||||
for child in get_children():
|
||||
child.connect("finished", self, "_change_state")
|
||||
|
||||
set_active(true)
|
||||
states_stack.push_front(start_state)
|
||||
current_state = states_stack[0]
|
||||
current_state.enter()
|
||||
|
||||
|
||||
func set_active(value):
|
||||
_active = value
|
||||
set_physics_process(value)
|
||||
set_process_input(value)
|
||||
if not _active:
|
||||
states_stack = []
|
||||
current_state = null
|
||||
|
||||
|
||||
func _input(event):
|
||||
current_state.handle_input(event)
|
||||
|
||||
|
||||
func _physics_process(delta):
|
||||
current_state.update(delta)
|
||||
|
||||
|
||||
func _on_animation_finished(anim_name):
|
||||
if not _active:
|
||||
return
|
||||
current_state._on_animation_finished(anim_name)
|
||||
|
||||
|
||||
func _change_state(state_name):
|
||||
if not _active:
|
||||
return
|
||||
|
||||
escoria.logger.trace(
|
||||
self,
|
||||
"Dialog State Machine: Changing state from '%s' to '%s'." % [current_state_name, state_name]
|
||||
)
|
||||
|
||||
current_state.exit()
|
||||
|
||||
if state_name == "previous":
|
||||
states_stack.pop_front()
|
||||
else:
|
||||
states_stack[0] = states_map[state_name]
|
||||
|
||||
current_state = states_stack[0]
|
||||
|
||||
emit_signal("state_changed", current_state)
|
||||
|
||||
#if state_name != "previous":
|
||||
current_state.enter()
|
||||
|
||||
current_state_name = state_name
|
||||
|
||||
|
||||
func get_current_state_name():
|
||||
for key in states_map.keys():
|
||||
if states_map[key] == current_state:
|
||||
return key
|
||||
|
||||
return null
|
||||
@@ -1,5 +1,5 @@
|
||||
@tool
|
||||
# A simple dialog manager for Escoria
|
||||
tool
|
||||
extends EditorPlugin
|
||||
|
||||
|
||||
@@ -10,23 +10,23 @@ const READING_SPEED_IN_WPM_DEFAULT_VALUE = 200
|
||||
const TEXT_TIME_PER_LETTER_MS_DEFAULT_VALUE = 100
|
||||
const TEXT_TIME_PER_LETTER_MS_FAST_DEFAULT_VALUE = 25
|
||||
|
||||
var left_click_actions: PoolStringArray = [
|
||||
var left_click_actions: PackedStringArray = [
|
||||
RTMISimpleDialogSettings.LEFT_CLICK_ACTION_SPEED_UP,
|
||||
RTMISimpleDialogSettings.LEFT_CLICK_ACTION_INSTANT_FINISH,
|
||||
RTMISimpleDialogSettings.LEFT_CLICK_ACTION_NOTHING
|
||||
]
|
||||
|
||||
var stop_talking_animation_on_options: PoolStringArray = [
|
||||
var stop_talking_animation_on_options: PackedStringArray = [
|
||||
RTMISimpleDialogSettings.STOP_TALKING_ANIMATION_ON_END_OF_TEXT,
|
||||
RTMISimpleDialogSettings.STOP_TALKING_ANIMATION_ON_END_OF_AUDIO
|
||||
]
|
||||
|
||||
# Override function to return the plugin name.
|
||||
func get_plugin_name():
|
||||
func _get_plugin_name():
|
||||
return "escoria-rtmi-dialog-simple"
|
||||
|
||||
# Unregister ourselves
|
||||
func disable_plugin():
|
||||
func _disable_plugin():
|
||||
print("Disabling plugin Escoria Dialog Simple")
|
||||
ESCProjectSettingsManager.remove_setting(
|
||||
ESCProjectSettingsManager.DEFAULT_DIALOG_TYPE
|
||||
@@ -44,6 +44,11 @@ func disable_plugin():
|
||||
RTMISimpleDialogSettings.TEXT_TIME_PER_LETTER_MS_FAST
|
||||
)
|
||||
|
||||
ESCProjectSettingsManager.remove_setting(
|
||||
RTMISimpleDialogSettings.SLOW_TEXT_MODE
|
||||
)
|
||||
|
||||
|
||||
ESCProjectSettingsManager.remove_setting(
|
||||
RTMISimpleDialogSettings.CLEAR_TEXT_BY_CLICK_ONLY
|
||||
)
|
||||
@@ -64,8 +69,8 @@ func disable_plugin():
|
||||
|
||||
|
||||
# Add ourselves to the list of dialog managers
|
||||
func enable_plugin():
|
||||
print("Enabling plugin Escoria Dialog Simple")
|
||||
func _enable_plugin():
|
||||
print("Enabling plugin RTMI Dialog Simple")
|
||||
|
||||
if EscoriaPlugin.register_dialog_manager(self, MANAGER_CLASS):
|
||||
ESCProjectSettingsManager.register_setting(
|
||||
@@ -87,23 +92,23 @@ func enable_plugin():
|
||||
|
||||
ESCProjectSettingsManager.register_setting(
|
||||
RTMISimpleDialogSettings.TEXT_TIME_PER_LETTER_MS,
|
||||
TEXT_TIME_PER_LETTER_MS_DEFAULT_VALUE,
|
||||
RTMISimpleDialogSettings.TEXT_TIME_PER_LETTER_MS_DEFAULT_VALUE,
|
||||
{
|
||||
"type": TYPE_REAL
|
||||
"type": TYPE_FLOAT
|
||||
}
|
||||
)
|
||||
|
||||
ESCProjectSettingsManager.register_setting(
|
||||
RTMISimpleDialogSettings.TEXT_TIME_PER_LETTER_MS_FAST,
|
||||
TEXT_TIME_PER_LETTER_MS_FAST_DEFAULT_VALUE,
|
||||
RTMISimpleDialogSettings.TEXT_TIME_PER_LETTER_MS_FAST_DEFAULT_VALUE,
|
||||
{
|
||||
"type": TYPE_REAL
|
||||
"type": TYPE_FLOAT
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
ESCProjectSettingsManager.register_setting(
|
||||
RTMISimpleDialogSettings.CLEAR_TEXT_BY_CLICK_ONLY,
|
||||
false,
|
||||
RTMISimpleDialogSettings.SLOW_TEXT_MODE,
|
||||
RTMISimpleDialogSettings.SLOW_TEXT_MODE_DEFAULT_VALUE,
|
||||
{
|
||||
"type": TYPE_BOOL
|
||||
}
|
||||
@@ -111,13 +116,21 @@ func enable_plugin():
|
||||
|
||||
ESCProjectSettingsManager.register_setting(
|
||||
RTMISimpleDialogSettings.READING_SPEED_IN_WPM,
|
||||
READING_SPEED_IN_WPM_DEFAULT_VALUE,
|
||||
RTMISimpleDialogSettings.READING_SPEED_IN_WPM_DEFAULT_VALUE,
|
||||
{
|
||||
"type": TYPE_INT
|
||||
}
|
||||
)
|
||||
|
||||
var left_click_actions_string: String = left_click_actions.join(",")
|
||||
ESCProjectSettingsManager.register_setting(
|
||||
RTMISimpleDialogSettings.CLEAR_TEXT_BY_CLICK_ONLY,
|
||||
RTMISimpleDialogSettings.CLEAR_TEXT_BY_CLICK_ONLY_DEFAULT_VALUE,
|
||||
{
|
||||
"type": TYPE_INT
|
||||
}
|
||||
)
|
||||
|
||||
var left_click_actions_string: String = ",".join(left_click_actions)
|
||||
|
||||
ESCProjectSettingsManager.register_setting(
|
||||
RTMISimpleDialogSettings.LEFT_CLICK_ACTION,
|
||||
@@ -129,7 +142,7 @@ func enable_plugin():
|
||||
}
|
||||
)
|
||||
|
||||
var stop_talking_animation_on_options_string: String = stop_talking_animation_on_options.join(",")
|
||||
var stop_talking_animation_on_options_string: String = ",".join(stop_talking_animation_on_options)
|
||||
|
||||
ESCProjectSettingsManager.register_setting(
|
||||
RTMISimpleDialogSettings.STOP_TALKING_ANIMATION_ON,
|
||||
@@ -143,6 +156,6 @@ func enable_plugin():
|
||||
|
||||
else:
|
||||
get_editor_interface().set_plugin_enabled(
|
||||
get_plugin_name(),
|
||||
_get_plugin_name(),
|
||||
false
|
||||
)
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
uid://bw7paepd6ster
|
||||
@@ -2,9 +2,13 @@
|
||||
extends ESCDialogManager
|
||||
class_name ESCReturnToMonekyIslandDialogs
|
||||
|
||||
|
||||
# State machine that governs how the dialog manager behaves
|
||||
var state_machine = preload("res://addons/escoria-ui-return-monkey-island-dialog-simple/rtmi_dialog_simple_state_machine.gd").new()
|
||||
var state_machine = (
|
||||
preload(
|
||||
"res://addons/escoria-ui-return-monkey-island-dialog-simple/rtmi_dialog_simple_state_machine.gd"
|
||||
)
|
||||
. new()
|
||||
)
|
||||
|
||||
# The currently running player
|
||||
var _type_player: Node = null
|
||||
@@ -16,6 +20,9 @@ var _dialog_player: Node = null
|
||||
# Reference to the dialog hint ("click to speed up")
|
||||
var _dialog_tip: Node = null
|
||||
|
||||
# Config holder for click to continue feature.
|
||||
var _click_to_continue: bool
|
||||
|
||||
# Basic state tracking
|
||||
var _is_saying: bool = false
|
||||
|
||||
@@ -24,10 +31,15 @@ var _is_saying: bool = false
|
||||
var _should_preserve_dialog_box: bool = false
|
||||
|
||||
|
||||
func _init() -> void:
|
||||
_click_to_continue = escoria.settings_manager.get_custom_setting(
|
||||
RTMISimpleDialogSettings.CLEAR_TEXT_BY_CLICK_ONLY_KEY, false
|
||||
)
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
add_child(state_machine)
|
||||
escoria.connect("paused", self, "_on_paused")
|
||||
|
||||
escoria.connect("paused", Callable(self, "_on_paused"))
|
||||
|
||||
|
||||
# Check whether a specific type is supported by the
|
||||
@@ -37,7 +49,7 @@ func _ready() -> void:
|
||||
# - type: required type
|
||||
# *Returns* Whether the type is supported or not
|
||||
func has_type(type: String) -> bool:
|
||||
return true if type in ["floating"] else false
|
||||
return true if type == "floating" else false
|
||||
|
||||
|
||||
# Check whether a specific chooser type is supported by the
|
||||
@@ -49,6 +61,7 @@ func has_type(type: String) -> bool:
|
||||
func has_chooser_type(type: String) -> bool:
|
||||
return true if type == "simple" else false
|
||||
|
||||
|
||||
# Instructs the dialog manager to preserve the next dialog box used by a `say`
|
||||
# command until a call to `disable_preserve_dialog_box` is made.
|
||||
#
|
||||
@@ -72,7 +85,7 @@ func disable_preserve_dialog_box() -> void:
|
||||
if is_instance_valid(_dialog_player) and _dialog_player.get_children().has(_type_player):
|
||||
_dialog_player.remove_child(_type_player)
|
||||
_preserved_type_player_type = ""
|
||||
_dialog_player.remove_child(_dialog_tip)
|
||||
|
||||
|
||||
# Output a text said by the item specified by the global id. Emit
|
||||
# `say_finished` after finishing displaying the text.
|
||||
@@ -83,17 +96,18 @@ func disable_preserve_dialog_box() -> void:
|
||||
# - text: Text to say, optional prefixed by a translation key separated
|
||||
# by a ":"
|
||||
# - type: Type of dialog box to use
|
||||
func say(dialog_player: Node, global_id: String, text: String, type: String):
|
||||
# - *key*: Translation key
|
||||
func say(dialog_player: Node, global_id: String, text: String, type: String, key: String):
|
||||
_dialog_player = dialog_player
|
||||
|
||||
_initialize_say_states(global_id, text, type)
|
||||
_initialize_say_states(global_id, text, type, key)
|
||||
|
||||
if _should_preserve_dialog_box:
|
||||
# If the dialog box type doesn't match what's currently being reused (if anything),
|
||||
# we want to remove the old one (if it exists) and then initialize and add the new dialog
|
||||
# box type to the dialog player
|
||||
if type != _preserved_type_player_type:
|
||||
if _dialog_player.get_children().has(_type_player):
|
||||
if is_instance_valid(_type_player) and _dialog_player.get_children().has(_type_player):
|
||||
_dialog_player.remove_child(_type_player)
|
||||
|
||||
_init_type_player(type)
|
||||
@@ -105,37 +119,39 @@ func say(dialog_player: Node, global_id: String, text: String, type: String):
|
||||
state_machine._change_state("say")
|
||||
|
||||
|
||||
func do_say(global_id: String, text: String) -> void:
|
||||
func do_say(global_id: String, text: String, has_audio: bool = false) -> void:
|
||||
# Only add_child here in order to prevent _type_player from running its _process method
|
||||
# before we're ready, and only if it's necessary
|
||||
if not _dialog_player.get_children().has(_type_player):
|
||||
_dialog_player.add_child(_type_player)
|
||||
add_dialog_tip()
|
||||
|
||||
|
||||
_type_player.say(global_id, text)
|
||||
|
||||
if not _click_to_continue:
|
||||
add_dialog_tip()
|
||||
|
||||
_type_player.say(global_id, text, has_audio)
|
||||
escoria.game_scene.clear_highlights()
|
||||
gymkhana.cursor_manager.clear_cursor()
|
||||
|
||||
|
||||
func _init_type_player(type: String) -> void:
|
||||
if type == "floating":
|
||||
_type_player = preload(\
|
||||
"res://addons/escoria-ui-return-monkey-island-dialog-simple/types/floating.tscn"\
|
||||
).instance()
|
||||
else:
|
||||
_type_player = preload(\
|
||||
"res://addons/escoria-ui-return-monkey-island-dialog-simple/types/avatar.tscn"\
|
||||
).instance()
|
||||
_dialog_tip = preload(\
|
||||
"res://addons/escoria-ui-return-monkey-island-dialog-simple/dialog_tip.tscn"\
|
||||
).instance()
|
||||
_type_player = (
|
||||
preload(
|
||||
"res://addons/escoria-ui-return-monkey-island-dialog-simple/types/floating.tscn"
|
||||
)
|
||||
. instantiate()
|
||||
)
|
||||
_dialog_tip = (
|
||||
preload("res://addons/escoria-ui-return-monkey-island-dialog-simple/dialog_tip.tscn")
|
||||
. instantiate()
|
||||
)
|
||||
|
||||
_type_player.connect("say_finished", self, "_on_say_finished")
|
||||
_type_player.connect("say_visible", self, "_on_say_visible")
|
||||
_type_player.say_finished.connect(_on_say_finished)
|
||||
_type_player.say_visible.connect(_on_say_visible)
|
||||
|
||||
func _initialize_say_states(global_id: String, text: String, type: String) -> void:
|
||||
state_machine.states_map["say"].initialize(self, global_id, text, type)
|
||||
|
||||
func _initialize_say_states(global_id: String, text: String, type: String, key: String) -> void:
|
||||
state_machine.states_map["say"].initialize(self, global_id, text, type, key)
|
||||
state_machine.states_map["finish"].initialize(_dialog_player)
|
||||
state_machine.states_map["say_fast"].initialize(self)
|
||||
state_machine.states_map["say_finish"].initialize(self)
|
||||
@@ -146,15 +162,17 @@ func _initialize_say_states(global_id: String, text: String, type: String) -> vo
|
||||
func _on_say_finished():
|
||||
if not _should_preserve_dialog_box and _dialog_player.get_children().has(_type_player):
|
||||
_dialog_player.remove_child(_type_player)
|
||||
remove_dialop_tip()
|
||||
|
||||
hide_dialop_tip()
|
||||
_is_saying = false
|
||||
|
||||
emit_signal("say_finished")
|
||||
say_finished.emit()
|
||||
|
||||
|
||||
func _on_say_visible():
|
||||
emit_signal("say_visible")
|
||||
|
||||
escoria.game_scene.hide_tooltips()
|
||||
say_visible.emit()
|
||||
|
||||
|
||||
# Present an option chooser to the player and sends the signal
|
||||
# `option_chosen` with the chosen dialog option
|
||||
@@ -166,39 +184,51 @@ func _on_say_visible():
|
||||
func choose(dialog_player: Node, dialog: ESCDialog, type: String):
|
||||
_dialog_player = dialog_player
|
||||
|
||||
escoria.game_scene.close_inventory()
|
||||
state_machine.states_map["choices"].initialize(dialog_player, self, dialog, type)
|
||||
state_machine._change_state("choices")
|
||||
escoria.game_scene.clear_highlights()
|
||||
|
||||
|
||||
func do_choose(dialog_player: Node, dialog: ESCDialog, type: String = "simple"):
|
||||
escoria.game_scene.hide_tooltips()
|
||||
|
||||
var chooser
|
||||
|
||||
if type == "simple" or type == "":
|
||||
chooser = preload(\
|
||||
"res://addons/escoria-ui-return-monkey-island-dialog-simple/chooser/simple.tscn"\
|
||||
).instance()
|
||||
|
||||
chooser = (
|
||||
preload(
|
||||
"res://addons/escoria-ui-return-monkey-island-dialog-simple/chooser/simple.tscn"
|
||||
)
|
||||
. instantiate()
|
||||
)
|
||||
|
||||
dialog_player.add_child(chooser)
|
||||
chooser.set_dialog(dialog)
|
||||
chooser.show_chooser()
|
||||
var option = yield(chooser, "option_chosen")
|
||||
|
||||
var option = await chooser.option_chosen
|
||||
dialog_player.remove_child(chooser)
|
||||
|
||||
# MODIFIED FOR RETURN TO MONKEY UI
|
||||
if option is ESCDialogOption:
|
||||
escoria.globals_manager.set_global("ESC_DIALOG_CHOSEN_OPTION", option.option)
|
||||
escoria.globals_manager.set_global("ESC_DIALOG_CHOSEN_OPTION", option)
|
||||
# END MODIFIED FOR RETURN TO MONKEY UI
|
||||
emit_signal("option_chosen", option)
|
||||
option_chosen.emit(option)
|
||||
escoria.game_scene.hide_tooltips()
|
||||
escoria.game_scene.update_highlights()
|
||||
|
||||
|
||||
|
||||
# Trigger running the dialogue faster
|
||||
func speedup():
|
||||
(escoria.object_manager.get_object(escoria.object_manager.SPEECH).node as ESCSpeechPlayer).set_state("off")
|
||||
if is_instance_valid(_type_player):
|
||||
_type_player.speedup()
|
||||
|
||||
|
||||
# Trigger an instant finish of the current dialog
|
||||
func finish():
|
||||
(escoria.object_manager.get_object(escoria.object_manager.SPEECH).node as ESCSpeechPlayer).set_state("off")
|
||||
if is_instance_valid(_type_player):
|
||||
_type_player.finish()
|
||||
|
||||
@@ -207,29 +237,35 @@ func finish():
|
||||
func interrupt():
|
||||
if _dialog_player.get_children().has(_type_player):
|
||||
(
|
||||
escoria.object_manager.get_object(escoria.object_manager.SPEECH).node\
|
||||
as ESCSpeechPlayer
|
||||
).set_state("off")
|
||||
(
|
||||
escoria.object_manager.get_object(escoria.object_manager.SPEECH).node
|
||||
as ESCSpeechPlayer
|
||||
)
|
||||
. set_state("off")
|
||||
)
|
||||
|
||||
if not _should_preserve_dialog_box and _dialog_player.get_children().has(_type_player):
|
||||
_dialog_player.remove_child(_type_player)
|
||||
remove_dialop_tip()
|
||||
hide_dialop_tip()
|
||||
|
||||
emit_signal("say_finished")
|
||||
|
||||
|
||||
# To be called if voice audio has finished.
|
||||
func voice_audio_finished():
|
||||
if is_instance_valid(_type_player):
|
||||
_type_player.voice_audio_finished()
|
||||
say_finished.emit()
|
||||
|
||||
|
||||
func add_dialog_tip():
|
||||
if not _dialog_player.get_children().has(_dialog_tip):
|
||||
_dialog_player.add_child(_dialog_tip)
|
||||
_dialog_tip.visible = true
|
||||
|
||||
|
||||
func hide_dialop_tip():
|
||||
if _dialog_player.get_children().has(_dialog_tip):
|
||||
_dialog_tip.visible = false
|
||||
|
||||
func remove_dialop_tip():
|
||||
_dialog_player.remove_child(_dialog_tip)
|
||||
|
||||
func _on_paused():
|
||||
remove_dialop_tip()
|
||||
hide_dialop_tip()
|
||||
|
||||
## To be called if voice audio has finished.
|
||||
func voice_audio_finished():
|
||||
if is_instance_valid(_type_player) and _type_player.has_method("voice_audio_finished"):
|
||||
_type_player.voice_audio_finished()
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
uid://cn37lmbastinu
|
||||
@@ -5,9 +5,17 @@ const SETTINGS_ROOT = "escoria/rtmi_dialog_simple"
|
||||
|
||||
const AVATARS_PATH = "%s/avatars_path" % SETTINGS_ROOT
|
||||
const TEXT_TIME_PER_LETTER_MS = "%s/text_time_per_letter_ms" % SETTINGS_ROOT
|
||||
const TEXT_TIME_PER_LETTER_MS_DEFAULT_VALUE = 100
|
||||
const TEXT_TIME_PER_LETTER_MS_FAST = "%s/text_time_per_fast_letter_ms" % SETTINGS_ROOT
|
||||
const TEXT_TIME_PER_LETTER_MS_FAST_DEFAULT_VALUE = 25
|
||||
const SLOW_TEXT_MODE_KEY = "slow_text_mode"
|
||||
const SLOW_TEXT_MODE = "%s/slow_text_mode" % SETTINGS_ROOT
|
||||
const SLOW_TEXT_MODE_DEFAULT_VALUE = false
|
||||
const READING_SPEED_IN_WPM = "%s/reading_speed_in_wpm" % SETTINGS_ROOT
|
||||
const READING_SPEED_IN_WPM_DEFAULT_VALUE = 200
|
||||
const CLEAR_TEXT_BY_CLICK_ONLY_KEY = "clear_text_by_click_only"
|
||||
const CLEAR_TEXT_BY_CLICK_ONLY = "%s/clear_text_by_click_only" % SETTINGS_ROOT
|
||||
const CLEAR_TEXT_BY_CLICK_ONLY_DEFAULT_VALUE = false
|
||||
const LEFT_CLICK_ACTION = "%s/left_click_action" % SETTINGS_ROOT
|
||||
|
||||
const STOP_TALKING_ANIMATION_ON = "%s/stop_talking_animation_on" % SETTINGS_ROOT
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
uid://b6s8umo4wf644
|
||||
@@ -1,4 +1,4 @@
|
||||
extends "res://addons/escoria-ui-return-monkey-island-dialog-simple/patterns/state_machine/state_machine.gd"
|
||||
extends StateMachine
|
||||
|
||||
func _init():
|
||||
_create_states()
|
||||
@@ -6,8 +6,7 @@ func _init():
|
||||
|
||||
current_state_name = "idle"
|
||||
START_STATE = states_map[current_state_name]
|
||||
|
||||
initialize(START_STATE)
|
||||
initialize(states_map[current_state_name])
|
||||
|
||||
|
||||
# Creates the states for this state machine.
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
uid://iivljvomkr7q
|
||||
@@ -1,4 +1,4 @@
|
||||
extends "res://addons/escoria-ui-return-monkey-island-dialog-simple/patterns/state_machine/state.gd"
|
||||
extends State
|
||||
|
||||
|
||||
# The owning dialog player.
|
||||
@@ -23,7 +23,7 @@ func initialize(dialog_player, dialog_chooser_ui: ESCDialogManager, dialog: ESCD
|
||||
func enter():
|
||||
escoria.logger.trace(self, "Dialog State Machine: Entered 'choices'.")
|
||||
|
||||
if _dialog.options.empty():
|
||||
if _dialog.options.is_empty():
|
||||
escoria.logger.error(
|
||||
self,
|
||||
"Received dialog options array was empty."
|
||||
@@ -36,9 +36,9 @@ func update(_delta):
|
||||
if _ready_to_choose:
|
||||
_ready_to_choose = false
|
||||
_dialog_chooser_ui.do_choose(_dialog_player, _dialog, _type)
|
||||
var option = yield(_dialog_chooser_ui, "option_chosen")
|
||||
var option = await _dialog_chooser_ui.option_chosen
|
||||
|
||||
escoria.logger.trace(self, "Dialog State Machine: 'choices' -> 'idle'")
|
||||
|
||||
emit_signal("finished", "idle")
|
||||
_dialog_player.emit_signal("option_chosen", option)
|
||||
finished.emit("idle")
|
||||
_dialog_player.option_chosen.emit(option)
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
uid://dkymk83pahngj
|
||||
@@ -1,4 +1,4 @@
|
||||
extends "res://addons/escoria-ui-return-monkey-island-dialog-simple/patterns/state_machine/state.gd"
|
||||
extends State
|
||||
|
||||
|
||||
# Owning dialog player
|
||||
@@ -17,5 +17,5 @@ func enter():
|
||||
|
||||
func update(_delta):
|
||||
escoria.logger.trace(self, "Dialog State Machine: 'finish' -> 'idle'")
|
||||
emit_signal("finished", "idle")
|
||||
_dialog_player.emit_signal("say_finished")
|
||||
finished.emit("idle")
|
||||
_dialog_player.say_finished.emit()
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
uid://cy6bt6secukba
|
||||
@@ -1,4 +1,4 @@
|
||||
extends "res://addons/escoria-ui-return-monkey-island-dialog-simple/patterns/state_machine/state.gd"
|
||||
extends State
|
||||
|
||||
func enter():
|
||||
escoria.logger.trace(self, "Dialog State Machine: Entered 'idle'.")
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
uid://ci0cqim2bs0qk
|
||||
@@ -1,4 +1,4 @@
|
||||
extends "res://addons/escoria-ui-return-monkey-island-dialog-simple/patterns/state_machine/state.gd"
|
||||
extends State
|
||||
|
||||
|
||||
# Reference to the currently playing dialog manager
|
||||
@@ -13,13 +13,12 @@ func enter():
|
||||
escoria.logger.trace(self, "Dialog State Machine: Entered 'interrupt'.")
|
||||
|
||||
if _dialog_manager != null:
|
||||
if not _dialog_manager.is_connected("say_finished", self, "_on_say_finished"):
|
||||
_dialog_manager.connect("say_finished", self, "_on_say_finished")
|
||||
if not _dialog_manager.say_finished.is_connected(_on_say_finished):
|
||||
_dialog_manager.say_finished.connect(_on_say_finished)
|
||||
|
||||
_dialog_manager.interrupt()
|
||||
|
||||
|
||||
func _on_say_finished() -> void:
|
||||
escoria.logger.trace(self, "Dialog State Machine: 'interrupt' -> 'finish'")
|
||||
emit_signal("finished", "finish")
|
||||
|
||||
finished.emit("finish")
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
uid://8r0bhwdf6yvh
|
||||
@@ -1,11 +1,7 @@
|
||||
extends "res://addons/escoria-ui-return-monkey-island-dialog-simple/patterns/state_machine/state.gd"
|
||||
extends State
|
||||
|
||||
|
||||
# A regular expression that separates the translation key from the text
|
||||
const KEYTEXT_REGEX = "^((?<key>[^:]+):)?\"(?<text>.+)\""
|
||||
|
||||
|
||||
# Reference to the currently playing dialog manager
|
||||
# Reference to the currently playing dialog manager
|
||||
var _dialog_manager: ESCDialogManager = null
|
||||
|
||||
# Character that is talking
|
||||
@@ -14,27 +10,30 @@ var _character: String
|
||||
# UI to use for the dialog
|
||||
var _type: String
|
||||
|
||||
# Translation key
|
||||
var _key: String = ""
|
||||
|
||||
# Text to say
|
||||
var _text: String
|
||||
|
||||
# Regular expression object for the separation of key and text
|
||||
var _keytext_regex: RegEx = RegEx.new()
|
||||
|
||||
var _ready_to_say: bool
|
||||
|
||||
# flag for whether the dialog manager has started to "say" to ensure that it has
|
||||
# prior to exiting this state as other states need this to happen to continue
|
||||
# (other states rely on the setup that the dialog manager does)
|
||||
var _say_started: bool
|
||||
|
||||
var _has_audio: bool = false
|
||||
|
||||
var _stop_talking_animation_on_option: String
|
||||
|
||||
|
||||
# Constructor
|
||||
func _init() -> void:
|
||||
_keytext_regex.compile(KEYTEXT_REGEX)
|
||||
|
||||
|
||||
func initialize(dialog_manager: ESCDialogManager, character: String, text: String, type: String) -> void:
|
||||
func initialize(dialog_manager: ESCDialogManager, character: String, text: String, type: String, key: String) -> void:
|
||||
_dialog_manager = dialog_manager
|
||||
_character = character
|
||||
_text = text
|
||||
_type = type
|
||||
_key = key
|
||||
_stop_talking_animation_on_option = \
|
||||
ESCProjectSettingsManager.get_setting(RTMISimpleDialogSettings.STOP_TALKING_ANIMATION_ON)
|
||||
|
||||
@@ -53,85 +52,81 @@ func handle_input(_event):
|
||||
func _handle_left_click_action(left_click_action: String) -> void:
|
||||
match left_click_action:
|
||||
RTMISimpleDialogSettings.LEFT_CLICK_ACTION_SPEED_UP:
|
||||
if _dialog_manager.is_connected("say_visible", self, "_on_say_visible"):
|
||||
_dialog_manager.disconnect("say_visible", self, "_on_say_visible")
|
||||
if _dialog_manager.say_visible.is_connected(_on_say_visible):
|
||||
_dialog_manager.say_visible.disconnect(_on_say_visible)
|
||||
|
||||
escoria.logger.trace(self, "Dialog State Machine: 'say' -> 'say_fast'")
|
||||
emit_signal("finished", "say_fast")
|
||||
finished.emit("say_fast")
|
||||
RTMISimpleDialogSettings.LEFT_CLICK_ACTION_INSTANT_FINISH:
|
||||
if _dialog_manager.is_connected("say_visible", self, "_on_say_visible"):
|
||||
_dialog_manager.disconnect("say_visible", self, "_on_say_visible")
|
||||
if _dialog_manager.say_visible.is_connected(_on_say_visible):
|
||||
_dialog_manager.say_visible.disconnect(_on_say_visible)
|
||||
|
||||
escoria.logger.trace(self, "Dialog State Machine: 'say' -> 'say_finish'")
|
||||
emit_signal("finished", "say_finish")
|
||||
finished.emit("say_finish")
|
||||
|
||||
get_tree().set_input_as_handled()
|
||||
get_viewport().set_input_as_handled()
|
||||
|
||||
|
||||
func enter():
|
||||
escoria.logger.trace(self, "Dialog State Machine: Entered 'say'.")
|
||||
|
||||
if not _dialog_manager.is_connected("say_visible", self, "_on_say_visible"):
|
||||
_dialog_manager.connect("say_visible", self, "_on_say_visible")
|
||||
_say_started = false
|
||||
_has_audio = false
|
||||
|
||||
if not _dialog_manager.say_visible.is_connected(_on_say_visible):
|
||||
_dialog_manager.say_visible.connect(_on_say_visible)
|
||||
|
||||
var matches = _keytext_regex.search(_text)
|
||||
|
||||
if not matches:
|
||||
escoria.logger.error(
|
||||
self,
|
||||
"Unexpected text encountered: %s." % _text
|
||||
)
|
||||
|
||||
var key = matches.get_string("key")
|
||||
|
||||
if matches.get_string("key") != "":
|
||||
var _speech_resource = _get_voice_file(
|
||||
matches.get_string("key")
|
||||
)
|
||||
if _key and not _key.is_empty():
|
||||
var _speech_resource = _get_voice_file(_key)
|
||||
|
||||
if _speech_resource == "":
|
||||
escoria.logger.warn(
|
||||
self,
|
||||
"Unable to find voice file with key '%s'." % matches.get_string("key")
|
||||
"Unable to find voice file with key '%s'." % _key
|
||||
)
|
||||
else:
|
||||
(
|
||||
escoria.object_manager.get_object(escoria.object_manager.SPEECH).node\
|
||||
as ESCSpeechPlayer
|
||||
).set_state(_speech_resource)
|
||||
_has_audio = true
|
||||
|
||||
if _stop_talking_animation_on_option == RTMISimpleDialogSettings.STOP_TALKING_ANIMATION_ON_END_OF_AUDIO:
|
||||
if not (
|
||||
escoria.object_manager.get_object(escoria.object_manager.SPEECH).node\
|
||||
as ESCSpeechPlayer
|
||||
).stream.is_connected("finished", self, "_on_audio_finished"):
|
||||
).stream.finished.is_connected(_on_audio_finished):
|
||||
|
||||
(
|
||||
escoria.object_manager.get_object(escoria.object_manager.SPEECH).node\
|
||||
as ESCSpeechPlayer
|
||||
).stream.connect("finished", self, "_on_audio_finished")
|
||||
).stream.finished.connect(_on_audio_finished)
|
||||
|
||||
var translated_text: String = tr(matches.get_string("key"))
|
||||
var translated_text: String = escoria.globals_manager.replace_globals(tr(_key))
|
||||
|
||||
# Only update the text if the translated text was found; otherwise, raise
|
||||
# a warning and use the original, untranslated text.
|
||||
if translated_text == matches.get_string("key"):
|
||||
if translated_text == _key:
|
||||
escoria.logger.warn(
|
||||
self,
|
||||
"Unable to find translation key '%s'. Using untranslated text." % matches.get_string("key")
|
||||
"Unable to find translation key '%s'. Using untranslated text." % _key
|
||||
)
|
||||
_text = matches.get_string("text")
|
||||
else:
|
||||
_text = translated_text
|
||||
else:
|
||||
_text = matches.get_string("text")
|
||||
|
||||
_ready_to_say = true
|
||||
|
||||
|
||||
func exit() -> void:
|
||||
if not _say_started:
|
||||
_dialog_manager.do_say(_character, _text, _has_audio)
|
||||
_say_started = true
|
||||
|
||||
|
||||
func update(_delta):
|
||||
if _ready_to_say:
|
||||
_dialog_manager.do_say(_character, _text)
|
||||
_dialog_manager.do_say(_character, _text, _has_audio)
|
||||
_say_started = true
|
||||
_ready_to_say = false
|
||||
|
||||
|
||||
@@ -148,15 +143,15 @@ func _get_voice_file(key: String, start: String = "") -> String:
|
||||
start = ESCProjectSettingsManager.get_setting(
|
||||
ESCProjectSettingsManager.SPEECH_FOLDER
|
||||
)
|
||||
var _dir = Directory.new()
|
||||
if _dir.open(start) == OK:
|
||||
_dir.list_dir_begin(true, true)
|
||||
var _dir = DirAccess.open(start)
|
||||
if _dir != null:
|
||||
_dir.list_dir_begin() # TODOConverter3To4 fill missing arguments https://github.com/godotengine/godot/pull/40547
|
||||
var file_name = _dir.get_next()
|
||||
while file_name != "":
|
||||
if _dir.current_is_dir():
|
||||
var _voice_file = _get_voice_file(
|
||||
key,
|
||||
start.plus_file(file_name)
|
||||
start.path_join(file_name)
|
||||
)
|
||||
if _voice_file != "":
|
||||
return _voice_file
|
||||
@@ -167,14 +162,14 @@ func _get_voice_file(key: String, start: String = "") -> String:
|
||||
ESCProjectSettingsManager.SPEECH_EXTENSION
|
||||
)
|
||||
]:
|
||||
return start.plus_file(file_name.trim_suffix(".import"))
|
||||
return start.path_join(file_name.trim_suffix(".import"))
|
||||
file_name = _dir.get_next()
|
||||
return ""
|
||||
|
||||
|
||||
func _on_say_visible() -> void:
|
||||
escoria.logger.trace(self, "Dialog State Machine: 'say' -> 'visible'")
|
||||
emit_signal("finished", "visible")
|
||||
finished.emit("visible")
|
||||
|
||||
|
||||
func _on_audio_finished() -> void:
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
uid://bh8a06uoe432e
|
||||
@@ -1,4 +1,4 @@
|
||||
extends "res://addons/escoria-ui-return-monkey-island-dialog-simple/patterns/state_machine/state.gd"
|
||||
extends State
|
||||
|
||||
|
||||
# Reference to the currently playing dialog manager
|
||||
@@ -16,8 +16,8 @@ func enter():
|
||||
escoria.inputs_manager.INPUT_NONE and \
|
||||
_dialog_manager != null:
|
||||
|
||||
if not _dialog_manager.is_connected("say_visible", self, "_on_say_visible"):
|
||||
_dialog_manager.connect("say_visible", self, "_on_say_visible")
|
||||
if not _dialog_manager.say_visible.is_connected(_on_say_visible):
|
||||
_dialog_manager.say_visible.connect(_on_say_visible)
|
||||
|
||||
_dialog_manager.speedup()
|
||||
else:
|
||||
@@ -26,4 +26,4 @@ func enter():
|
||||
|
||||
func _on_say_visible() -> void:
|
||||
escoria.logger.trace(self, "Dialog State Machine: 'say_fast' -> 'visible'")
|
||||
emit_signal("finished", "visible")
|
||||
finished.emit("visible")
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
uid://b4dm1jk8q55fc
|
||||
@@ -1,4 +1,4 @@
|
||||
extends "res://addons/escoria-ui-return-monkey-island-dialog-simple/patterns/state_machine/state.gd"
|
||||
extends State
|
||||
|
||||
|
||||
# Reference to the currently playing dialog manager
|
||||
@@ -16,8 +16,8 @@ func enter():
|
||||
escoria.inputs_manager.INPUT_NONE and \
|
||||
_dialog_manager != null:
|
||||
|
||||
if not _dialog_manager.is_connected("say_visible", self, "_on_say_visible"):
|
||||
_dialog_manager.connect("say_visible", self, "_on_say_visible")
|
||||
if not _dialog_manager.say_visible.is_connected(_on_say_visible):
|
||||
_dialog_manager.say_visible.connect(_on_say_visible)
|
||||
|
||||
_dialog_manager.finish()
|
||||
else:
|
||||
@@ -26,4 +26,4 @@ func enter():
|
||||
|
||||
func _on_say_visible() -> void:
|
||||
escoria.logger.trace(self, "Dialog State Machine: 'say_finish' -> 'visible'")
|
||||
emit_signal("finished", "visible")
|
||||
finished.emit("visible")
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
uid://bh1rpfjjpxgmp
|
||||
@@ -1,4 +1,4 @@
|
||||
extends "res://addons/escoria-ui-return-monkey-island-dialog-simple/patterns/state_machine/state.gd"
|
||||
extends State
|
||||
|
||||
|
||||
# Reference to the currently playing dialog manager
|
||||
@@ -12,23 +12,29 @@ func initialize(dialog_manager: ESCDialogManager) -> void:
|
||||
func enter():
|
||||
escoria.logger.trace(self, "Dialog State Machine: Entered 'visible'.")
|
||||
|
||||
if not _dialog_manager.is_connected("say_finished", self, "_on_say_finished"):
|
||||
_dialog_manager.connect("say_finished", self, "_on_say_finished")
|
||||
if not _dialog_manager.say_finished.is_connected(_on_say_finished):
|
||||
_dialog_manager.say_finished.connect(_on_say_finished)
|
||||
|
||||
|
||||
func handle_input(_event):
|
||||
if _event is InputEventMouseButton and _event.pressed:
|
||||
if escoria.inputs_manager.input_mode != \
|
||||
escoria.inputs_manager.INPUT_NONE:
|
||||
if _event is not InputEventMouseButton:
|
||||
return
|
||||
|
||||
if _dialog_manager.is_connected("say_finished", self, "_on_say_finished"):
|
||||
_dialog_manager.disconnect("say_finished", self, "_on_say_finished")
|
||||
if !_event.pressed:
|
||||
return
|
||||
|
||||
emit_signal("finished", "interrupt")
|
||||
get_tree().set_input_as_handled()
|
||||
if escoria.inputs_manager.input_mode == \
|
||||
escoria.inputs_manager.INPUT_NONE:
|
||||
return
|
||||
|
||||
if _dialog_manager.say_finished.is_connected(_on_say_finished):
|
||||
_dialog_manager.say_finished.disconnect(_on_say_finished)
|
||||
|
||||
finished.emit("interrupt")
|
||||
#get_viewport().set_input_as_handled()
|
||||
|
||||
|
||||
# Handles the end of a say function after it has emitted say_finished.
|
||||
func _on_say_finished():
|
||||
escoria.logger.trace(self, "Dialog State Machine: 'visible' -> 'finish'")
|
||||
emit_signal("finished", "finish")
|
||||
finished.emit("finish")
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
uid://dbawq8ee81noc
|
||||
@@ -1,19 +1,42 @@
|
||||
[gd_resource type="Theme" load_steps=3 format=2]
|
||||
[gd_resource type="Theme" load_steps=4 format=3 uid="uid://dlo07cyfhpilq"]
|
||||
|
||||
[ext_resource path="res://addons/escoria-ui-return-monkey-island/fonts/caslonantique.tres" type="DynamicFont" id=1]
|
||||
[sub_resource type="StyleBoxFlat" id="1"]
|
||||
content_margin_left = 4.0
|
||||
content_margin_top = 4.0
|
||||
content_margin_right = 4.0
|
||||
content_margin_bottom = 4.0
|
||||
bg_color = Color(0, 0, 0, 0.462745)
|
||||
corner_radius_top_right = 5
|
||||
corner_radius_bottom_right = 5
|
||||
expand_margin_left = 19.0
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id=1]
|
||||
content_margin_left = 5.0
|
||||
content_margin_right = 5.0
|
||||
content_margin_top = 5.0
|
||||
content_margin_bottom = 5.0
|
||||
bg_color = Color( 0, 0, 0, 0.815686 )
|
||||
corner_radius_top_left = 8
|
||||
corner_radius_top_right = 8
|
||||
corner_radius_bottom_right = 8
|
||||
corner_radius_bottom_left = 8
|
||||
[sub_resource type="StyleBoxFlat" id="2"]
|
||||
bg_color = Color(0, 0, 0, 0.509804)
|
||||
corner_radius_top_left = 5
|
||||
corner_radius_top_right = 5
|
||||
corner_radius_bottom_right = 5
|
||||
corner_radius_bottom_left = 5
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id="3"]
|
||||
bg_color = Color(0, 0, 0, 0.388235)
|
||||
draw_center = false
|
||||
corner_radius_top_left = 5
|
||||
corner_radius_top_right = 5
|
||||
corner_radius_bottom_right = 5
|
||||
corner_radius_bottom_left = 5
|
||||
expand_margin_left = 5.0
|
||||
expand_margin_top = 5.0
|
||||
expand_margin_right = 5.0
|
||||
expand_margin_bottom = 5.0
|
||||
|
||||
[resource]
|
||||
default_font = ExtResource( 1 )
|
||||
RichTextLabel/styles/normal = SubResource( 1 )
|
||||
VBoxContainer/constants/separation = 1
|
||||
Label/colors/font_color = Color(1, 1, 1, 1)
|
||||
Label/colors/font_color_shadow = Color(0, 0, 0, 0)
|
||||
Label/colors/font_outline_modulate = Color(1, 0, 0, 1)
|
||||
Label/colors/label_box_bg = Color(0, 0, 0, 0.745098)
|
||||
Label/fonts/font = null
|
||||
Label/styles/normal = SubResource("1")
|
||||
RichTextLabel/font_sizes/font_size = 20
|
||||
RichTextLabel/fonts/normal_font = null
|
||||
RichTextLabel/styles/focus = SubResource("2")
|
||||
RichTextLabel/styles/normal = SubResource("3")
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
[gd_resource type="Theme" load_steps=4 format=3 uid="uid://dvwfrnya2nhxu"]
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id="1"]
|
||||
content_margin_left = 4.0
|
||||
content_margin_top = 4.0
|
||||
content_margin_right = 4.0
|
||||
content_margin_bottom = 4.0
|
||||
bg_color = Color(0, 0, 0, 0.462745)
|
||||
corner_radius_top_right = 5
|
||||
corner_radius_bottom_right = 5
|
||||
expand_margin_left = 19.0
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_yu8vd"]
|
||||
bg_color = Color(0, 0, 0, 0.607843)
|
||||
corner_radius_top_left = 5
|
||||
corner_radius_top_right = 5
|
||||
corner_radius_bottom_right = 5
|
||||
corner_radius_bottom_left = 5
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_hq7vb"]
|
||||
bg_color = Color(0, 0, 0, 0.65882355)
|
||||
corner_radius_top_left = 10
|
||||
corner_radius_top_right = 10
|
||||
corner_radius_bottom_right = 5
|
||||
corner_radius_bottom_left = 5
|
||||
|
||||
[resource]
|
||||
Label/colors/font_color = Color(1, 1, 1, 1)
|
||||
Label/colors/font_color_shadow = Color(0, 0, 0, 0)
|
||||
Label/colors/font_outline_modulate = Color(1, 0, 0, 1)
|
||||
Label/colors/label_box_bg = Color(0, 0, 0, 0.745098)
|
||||
Label/styles/normal = SubResource("1")
|
||||
Panel/styles/panel = SubResource("StyleBoxFlat_yu8vd")
|
||||
PanelContainer/styles/panel = SubResource("StyleBoxFlat_hq7vb")
|
||||
@@ -1,227 +0,0 @@
|
||||
# A dialog GUI showing a dialog box and character portraits
|
||||
extends Popup
|
||||
|
||||
|
||||
# Signal emitted when text has been said
|
||||
signal say_finished
|
||||
|
||||
# Signal emitted when text has just become fully visible
|
||||
signal say_visible
|
||||
|
||||
|
||||
# The text speed per character for normal display
|
||||
var _text_time_per_character: float
|
||||
|
||||
# The text speed per character if the dialog line is skipped
|
||||
var _fast_text_time_per_character: float
|
||||
|
||||
# The reading speed to be used in determining the length of time text remains
|
||||
# on the screen.
|
||||
var _reading_speed_in_wpm: int
|
||||
|
||||
# Used to extract words from lines of text.
|
||||
var _word_regex: RegEx = RegEx.new()
|
||||
|
||||
# Whether the current dialog is speeding up
|
||||
var _is_speeding_up: bool = false
|
||||
|
||||
# The current line of text being displayed.
|
||||
var _current_line: String
|
||||
|
||||
|
||||
# The node holding the avatar
|
||||
onready var avatar_node = $Panel/MarginContainer/HSplitContainer/VBoxContainer\
|
||||
/avatar
|
||||
|
||||
# The node showing the text
|
||||
onready var text_node = $Panel/MarginContainer/HSplitContainer/text
|
||||
|
||||
# The tween node for text animations
|
||||
onready var tween = $Panel/MarginContainer/HSplitContainer/text/Tween
|
||||
|
||||
# Whether the dialog manager is paused
|
||||
onready var is_paused: bool = true
|
||||
|
||||
|
||||
|
||||
# Build up the UI
|
||||
func _ready():
|
||||
_text_time_per_character = ProjectSettings.get_setting(
|
||||
RTMISimpleDialogSettings.TEXT_TIME_PER_LETTER_MS
|
||||
)
|
||||
|
||||
if _text_time_per_character < 0:
|
||||
escoria.logger.warn(
|
||||
self,
|
||||
"%s setting must be a non-negative number. Will use default value of %s." %
|
||||
[
|
||||
RTMISimpleDialogSettings.TEXT_TIME_PER_LETTER_MS,
|
||||
RTMISimpleDialogSettings.TEXT_TIME_PER_LETTER_MS_DEFAULT_VALUE
|
||||
]
|
||||
)
|
||||
|
||||
_text_time_per_character = RTMISimpleDialogSettings.TEXT_TIME_PER_LETTER_MS_DEFAULT_VALUE
|
||||
|
||||
_fast_text_time_per_character = ProjectSettings.get_setting(
|
||||
RTMISimpleDialogSettings.TEXT_TIME_PER_LETTER_MS_FAST
|
||||
)
|
||||
|
||||
if _fast_text_time_per_character < 0:
|
||||
escoria.logger.warn(
|
||||
self,
|
||||
"%s setting must be a non-negative number. Will use default value of %s." %
|
||||
[
|
||||
RTMISimpleDialogSettings.TEXT_TIME_PER_LETTER_MS_FAST,
|
||||
RTMISimpleDialogSettings.TEXT_TIME_PER_LETTER_MS_FAST_DEFAULT_VALUE
|
||||
]
|
||||
)
|
||||
|
||||
_fast_text_time_per_character = RTMISimpleDialogSettings.TEXT_TIME_PER_LETTER_MS_FAST_DEFAULT_VALUE
|
||||
|
||||
_reading_speed_in_wpm = ProjectSettings.get_setting(
|
||||
RTMISimpleDialogSettings.READING_SPEED_IN_WPM
|
||||
)
|
||||
|
||||
if _reading_speed_in_wpm <= 0:
|
||||
escoria.logger.warn(
|
||||
self,
|
||||
"%s setting must be a positive number. Will use default value of %s." %
|
||||
[
|
||||
RTMISimpleDialogSettings.READING_SPEED_IN_WPM,
|
||||
RTMISimpleDialogSettings.READING_SPEED_IN_WPM_DEFAULT_VALUE
|
||||
]
|
||||
)
|
||||
|
||||
_reading_speed_in_wpm = RTMISimpleDialogSettings.READING_SPEED_IN_WPM_DEFAULT_VALUE
|
||||
|
||||
_word_regex.compile("\\S+")
|
||||
|
||||
text_node.bbcode_enabled = true
|
||||
tween.connect(
|
||||
"tween_completed",
|
||||
self,
|
||||
"_on_dialog_line_typed"
|
||||
)
|
||||
|
||||
escoria.connect("paused", self, "_on_paused")
|
||||
escoria.connect("resumed", self, "_on_resumed")
|
||||
|
||||
|
||||
# Switch the current character
|
||||
#
|
||||
# #### Parameters
|
||||
# - name: The name of the current character
|
||||
func set_current_character(name: String):
|
||||
if ProjectSettings.get_setting("escoria/dialog_simple/avatars_path").empty():
|
||||
escoria.logger.warn(self, "Unable to load avatar '%s': Avatar path not specified" % name)
|
||||
return
|
||||
|
||||
var avatar = "%s/%s.tres" % [
|
||||
ProjectSettings.get_setting("escoria/dialog_simple/avatars_path"),
|
||||
name
|
||||
]
|
||||
if ResourceLoader.exists(avatar):
|
||||
avatar_node.texture = ResourceLoader.load(avatar)
|
||||
|
||||
if avatar_node.texture is AnimatedTexture:
|
||||
avatar_node.texture.current_frame = 0
|
||||
avatar_node.texture.pause = false
|
||||
else:
|
||||
escoria.logger.warn(self, "Unable to load avatar '%s': Resource not found in path '%s'" %
|
||||
[name, ProjectSettings.get_setting("escoria/dialog_simple/avatars_path")])
|
||||
|
||||
|
||||
# Make a character say something
|
||||
#
|
||||
# #### Parameters
|
||||
# - character: The global id of the character speaking
|
||||
# - line: Line to say
|
||||
func say(character: String, line: String):
|
||||
_current_line = line
|
||||
|
||||
_is_speeding_up = false
|
||||
popup_centered()
|
||||
set_current_character(character)
|
||||
|
||||
text_node.bbcode_text = tr(line)
|
||||
|
||||
text_node.percent_visible = 0.0
|
||||
var time_show_full_text = _text_time_per_character / 1000 * len(line)
|
||||
|
||||
tween.interpolate_property(text_node, "percent_visible",
|
||||
0.0, 1.0, time_show_full_text,
|
||||
Tween.TRANS_LINEAR, Tween.EASE_IN_OUT)
|
||||
tween.start()
|
||||
|
||||
|
||||
# Called by the dialog player when the
|
||||
func speedup():
|
||||
if not _is_speeding_up:
|
||||
_is_speeding_up = true
|
||||
var time_show_full_text = _fast_text_time_per_character / 1000 * len(_current_line)
|
||||
tween.remove_all()
|
||||
tween.interpolate_property(text_node, "percent_visible",
|
||||
text_node.percent_visible, 1.0, time_show_full_text,
|
||||
Tween.TRANS_LINEAR, Tween.EASE_IN_OUT)
|
||||
tween.start()
|
||||
|
||||
|
||||
# Called by the dialog player when user wants to finish dialogue immediately.
|
||||
func finish():
|
||||
tween.remove_all()
|
||||
tween.interpolate_property(text_node, "percent_visible",
|
||||
text_node.percent_visible, 1.0, 0.0)
|
||||
tween.start()
|
||||
|
||||
|
||||
# To be called if voice audio has finished.
|
||||
func voice_audio_finished():
|
||||
if avatar_node and avatar_node.texture:
|
||||
avatar_node.texture.current_frame = 0
|
||||
avatar_node.texture.pause = true
|
||||
|
||||
|
||||
# The dialog line was printed, start the waiting time and then finish
|
||||
# the dialog
|
||||
func _on_dialog_line_typed(object, key):
|
||||
if avatar_node.texture is AnimatedTexture:
|
||||
avatar_node.texture.current_frame = 0
|
||||
avatar_node.texture.pause = true
|
||||
|
||||
text_node.visible_characters = -1
|
||||
|
||||
var time_to_disappear: float = _calculate_time_to_disappear()
|
||||
$Timer.start(time_to_disappear)
|
||||
$Timer.connect("timeout", self, "_on_dialog_finished")
|
||||
|
||||
emit_signal("say_visible")
|
||||
|
||||
|
||||
func _calculate_time_to_disappear() -> float:
|
||||
return (_get_number_of_words() / _reading_speed_in_wpm as float) * 60
|
||||
|
||||
|
||||
func _get_number_of_words() -> int:
|
||||
return _word_regex.search_all(text_node.get_text()).size()
|
||||
|
||||
|
||||
# Ending the dialog
|
||||
func _on_dialog_finished():
|
||||
# Only trigger to clear the text if we aren't limiting the clearing trigger to a click.
|
||||
if not ESCProjectSettingsManager.get_setting(RTMISimpleDialogSettings.CLEAR_TEXT_BY_CLICK_ONLY):
|
||||
emit_signal("say_finished")
|
||||
queue_free()
|
||||
|
||||
|
||||
# Handler managing pause notification from Escoria
|
||||
func _on_paused():
|
||||
if tween.is_active():
|
||||
is_paused = true
|
||||
tween.stop_all()
|
||||
|
||||
|
||||
# Handler managing resume notification from Escoria
|
||||
func _on_resumed():
|
||||
if not tween.is_active():
|
||||
is_paused = false
|
||||
tween.resume_all()
|
||||
@@ -0,0 +1 @@
|
||||
uid://cfkvypxfuu2mt
|
||||
@@ -1,68 +0,0 @@
|
||||
[gd_scene load_steps=2 format=2]
|
||||
|
||||
[ext_resource path="res://addons/escoria-ui-return-monkey-island-dialog-simple/types/avatar.gd" type="Script" id=1]
|
||||
|
||||
[node name="dialog_box" type="Popup"]
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
margin_right = -782.0
|
||||
margin_bottom = -734.0
|
||||
script = ExtResource( 1 )
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="Timer" type="Timer" parent="."]
|
||||
|
||||
[node name="Panel" type="Panel" parent="."]
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="MarginContainer" type="MarginContainer" parent="Panel"]
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
custom_constants/margin_right = 20
|
||||
custom_constants/margin_top = 20
|
||||
custom_constants/margin_left = 20
|
||||
custom_constants/margin_bottom = 20
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="HSplitContainer" type="HSplitContainer" parent="Panel/MarginContainer"]
|
||||
margin_left = 20.0
|
||||
margin_top = 20.0
|
||||
margin_right = 478.0
|
||||
margin_bottom = 146.0
|
||||
custom_constants/separation = 35
|
||||
dragger_visibility = 1
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="Panel/MarginContainer/HSplitContainer"]
|
||||
margin_right = 88.0
|
||||
margin_bottom = 126.0
|
||||
size_flags_horizontal = 3
|
||||
size_flags_stretch_ratio = 0.3
|
||||
|
||||
[node name="avatar" type="TextureRect" parent="Panel/MarginContainer/HSplitContainer/VBoxContainer"]
|
||||
margin_right = 88.0
|
||||
margin_bottom = 108.0
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
expand = true
|
||||
|
||||
[node name="text" type="RichTextLabel" parent="Panel/MarginContainer/HSplitContainer"]
|
||||
margin_left = 123.0
|
||||
margin_right = 458.0
|
||||
margin_bottom = 126.0
|
||||
size_flags_horizontal = 3
|
||||
bbcode_enabled = true
|
||||
bbcode_text = "Here be some text"
|
||||
text = "Here be some text"
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="Tween" type="Tween" parent="Panel/MarginContainer/HSplitContainer/text"]
|
||||
@@ -1,6 +1,5 @@
|
||||
# A dialog UI using a label above the head of the character
|
||||
extends RichTextLabel
|
||||
|
||||
# A dialog GUI showing a dialog box and character portraits
|
||||
extends Window
|
||||
|
||||
# Signal emitted when text has been said
|
||||
signal say_finished
|
||||
@@ -8,6 +7,15 @@ signal say_finished
|
||||
# Signal emitted when text has just become fully visible
|
||||
signal say_visible
|
||||
|
||||
const SLOW_TEXT_MODE_MULTIPLIER: float = 2
|
||||
|
||||
# Progress bar feature flag
|
||||
const PROGRESS_BAR_ENABLED: bool = false
|
||||
|
||||
const MINIMUM_TALKING_TIME: float = 2.0
|
||||
const DEFAULT_SPEECH_SPEED_MULTIPLIER: float = 1.0
|
||||
|
||||
@export var centered_text: bool
|
||||
|
||||
# The text speed per character for normal display
|
||||
var _text_time_per_character: float
|
||||
@@ -22,7 +30,6 @@ var _reading_speed_in_wpm: int
|
||||
# Used to extract words from lines of text.
|
||||
var _word_regex: RegEx = RegEx.new()
|
||||
|
||||
|
||||
# Current character speaking, to keep track of reference for animation purposes
|
||||
var _current_character
|
||||
|
||||
@@ -32,19 +39,44 @@ var _is_speeding_up: bool = false
|
||||
# The current line of text being displayed.
|
||||
var _current_line: String
|
||||
|
||||
# If the current line has audio or not.
|
||||
var _has_audio: bool
|
||||
|
||||
# Tween node for text animation
|
||||
onready var tween: Tween = $Tween
|
||||
# Timer for character talking
|
||||
var _talking_timer
|
||||
|
||||
# The node showing the text
|
||||
onready var text_node: RichTextLabel = self
|
||||
# Timer for clearing the dialog
|
||||
var _clearing_timer
|
||||
|
||||
var _x_position_offset: int = -10
|
||||
var _y_position_offset: int = -20
|
||||
|
||||
var _dialog_location_node = null
|
||||
|
||||
# Click to continue flag from settings.
|
||||
var _click_to_continue: bool = false
|
||||
|
||||
# Slow text flag from settings.
|
||||
var _slow_text_mode: bool = false
|
||||
|
||||
# Progress var Tween reference
|
||||
var _progress_tween: Tween
|
||||
|
||||
# Whether the dialog manager is paused
|
||||
onready var is_paused: bool = true
|
||||
@onready var is_paused: bool = true
|
||||
|
||||
|
||||
# Enable bbcode and catch the signal when a tween completed
|
||||
# Build up the UI
|
||||
func _ready():
|
||||
_click_to_continue = escoria.settings_manager.get_custom_setting(
|
||||
RTMISimpleDialogSettings.CLEAR_TEXT_BY_CLICK_ONLY_KEY,
|
||||
RTMISimpleDialogSettings.CLEAR_TEXT_BY_CLICK_ONLY_DEFAULT_VALUE
|
||||
)
|
||||
_slow_text_mode = escoria.settings_manager.get_custom_setting(
|
||||
RTMISimpleDialogSettings.SLOW_TEXT_MODE_KEY,
|
||||
RTMISimpleDialogSettings.SLOW_TEXT_MODE_DEFAULT_VALUE
|
||||
)
|
||||
|
||||
_text_time_per_character = ProjectSettings.get_setting(
|
||||
RTMISimpleDialogSettings.TEXT_TIME_PER_LETTER_MS
|
||||
)
|
||||
@@ -52,14 +84,16 @@ func _ready():
|
||||
if _text_time_per_character < 0:
|
||||
escoria.logger.warn(
|
||||
self,
|
||||
"%s setting must be a non-negative number. Will use default value of %s." %
|
||||
[
|
||||
(
|
||||
"%s setting must be a non-negative number. Will use default value of %s."
|
||||
% [
|
||||
RTMISimpleDialogSettings.TEXT_TIME_PER_LETTER_MS,
|
||||
RTMISimpleDialogSettings.TEXT_TIME_PER_LETTER_MS_DEFAULT_VALUE
|
||||
escoria.TEXT_TIME_PER_LETTER_MS_DEFAULT_VALUE
|
||||
]
|
||||
)
|
||||
)
|
||||
|
||||
_text_time_per_character = RTMISimpleDialogSettings.TEXT_TIME_PER_LETTER_MS_DEFAULT_VALUE
|
||||
_text_time_per_character = escoria.TEXT_TIME_PER_LETTER_MS_DEFAULT_VALUE
|
||||
|
||||
_fast_text_time_per_character = ProjectSettings.get_setting(
|
||||
RTMISimpleDialogSettings.TEXT_TIME_PER_LETTER_MS_FAST
|
||||
@@ -68,14 +102,16 @@ func _ready():
|
||||
if _fast_text_time_per_character < 0:
|
||||
escoria.logger.warn(
|
||||
self,
|
||||
"%s setting must be a non-negative number. Will use default value of %s." %
|
||||
[
|
||||
(
|
||||
"%s setting must be a non-negative number. Will use default value of %s."
|
||||
% [
|
||||
RTMISimpleDialogSettings.TEXT_TIME_PER_LETTER_MS_FAST,
|
||||
RTMISimpleDialogSettings.TEXT_TIME_PER_LETTER_MS_FAST_DEFAULT_VALUE
|
||||
escoria.TEXT_TIME_PER_LETTER_MS_FAST_DEFAULT_VALUE
|
||||
]
|
||||
)
|
||||
)
|
||||
|
||||
_fast_text_time_per_character = RTMISimpleDialogSettings.TEXT_TIME_PER_LETTER_MS_FAST_DEFAULT_VALUE
|
||||
_fast_text_time_per_character = escoria.TEXT_TIME_PER_LETTER_MS_FAST_DEFAULT_VALUE
|
||||
|
||||
_reading_speed_in_wpm = ProjectSettings.get_setting(
|
||||
RTMISimpleDialogSettings.READING_SPEED_IN_WPM
|
||||
@@ -84,44 +120,37 @@ func _ready():
|
||||
if _reading_speed_in_wpm <= 0:
|
||||
escoria.logger.warn(
|
||||
self,
|
||||
"%s setting must be a positive number. Will use default value of %s." %
|
||||
[
|
||||
(
|
||||
"%s setting must be a positive number. Will use default value of %s."
|
||||
% [
|
||||
RTMISimpleDialogSettings.READING_SPEED_IN_WPM,
|
||||
RTMISimpleDialogSettings.READING_SPEED_IN_WPM_DEFAULT_VALUE
|
||||
escoria.READING_SPEED_IN_WPM_DEFAULT_VALUE
|
||||
]
|
||||
)
|
||||
)
|
||||
|
||||
_reading_speed_in_wpm = RTMISimpleDialogSettings.READING_SPEED_IN_WPM_DEFAULT_VALUE
|
||||
_reading_speed_in_wpm = escoria.READING_SPEED_IN_WPM_DEFAULT_VALUE
|
||||
|
||||
_word_regex.compile("\\S+")
|
||||
|
||||
bbcode_enabled = true
|
||||
$Tween.connect("tween_completed", self, "_on_dialog_line_typed")
|
||||
%text_node.bbcode_enabled = true
|
||||
|
||||
connect("tree_exiting", self, "_on_tree_exiting")
|
||||
_talking_timer = Timer.new()
|
||||
_talking_timer.one_shot = true
|
||||
_talking_timer.timeout.connect(_on_dialog_line_typed)
|
||||
add_child(_talking_timer)
|
||||
|
||||
escoria.connect("paused", self, "_on_paused")
|
||||
escoria.connect("resumed", self, "_on_resumed")
|
||||
_clearing_timer = Timer.new()
|
||||
_clearing_timer.one_shot = true
|
||||
_clearing_timer.timeout.connect(_on_dialog_finished)
|
||||
add_child(_clearing_timer)
|
||||
|
||||
tree_exiting.connect(_on_tree_exiting)
|
||||
|
||||
_current_line = ""
|
||||
|
||||
|
||||
func _process(delta):
|
||||
if _current_character.is_inside_tree() and \
|
||||
_current_character.has_node("dialog_position"):
|
||||
# Position the RichTextLabel on the character's dialog position, if any.
|
||||
rect_position = _current_character.get_node("dialog_position") \
|
||||
.get_global_transform_with_canvas().origin
|
||||
rect_position.x -= rect_size.x / 2
|
||||
|
||||
if rect_position.x < 0:
|
||||
rect_position.x = 0
|
||||
|
||||
var screen_margin = rect_position.x + rect_size.x - \
|
||||
ProjectSettings.get("display/window/size/width")
|
||||
|
||||
if screen_margin > 0:
|
||||
rect_position.x -= screen_margin
|
||||
if PROGRESS_BAR_ENABLED:
|
||||
_progress_tween = create_tween()
|
||||
|
||||
|
||||
# Make a character say something
|
||||
@@ -129,130 +158,188 @@ func _process(delta):
|
||||
# #### Parameters
|
||||
# - character: The global id of the character speaking
|
||||
# - line: Line to say
|
||||
func say(character: String, line: String) :
|
||||
func say(character: String, line: String, has_audio: bool = false):
|
||||
_current_line = line
|
||||
_has_audio = has_audio
|
||||
|
||||
show()
|
||||
# Hide in case the same box is used
|
||||
%ClickToContinueTip.visible = true if _click_to_continue else false
|
||||
|
||||
_is_speeding_up = false
|
||||
|
||||
# Position the RichTextLabel on the character's dialog position, if any.
|
||||
_current_character = escoria.object_manager.get_object(character).node
|
||||
|
||||
var dialog_location_count: int = 0
|
||||
|
||||
for c in escoria.object_manager.get_object(character).node.get_children():
|
||||
if c is Marker2D:
|
||||
# Identify any Postion2D nodes
|
||||
if c is ESCDialogLocation:
|
||||
dialog_location_count += 1
|
||||
_dialog_location_node = c
|
||||
|
||||
if dialog_location_count > 1:
|
||||
escoria.logger.warn(
|
||||
self,
|
||||
(
|
||||
"Multiple ESCDialogLocation nodes found "
|
||||
+ "object %s. Last one will be used." % _current_character
|
||||
)
|
||||
)
|
||||
|
||||
# Set text color to color set in the actor
|
||||
var text_color = _current_character.dialog_color
|
||||
var text_color_html = text_color.to_html(false)
|
||||
|
||||
text_node.bbcode_text = "[center][color=#" + text_color_html + "]" \
|
||||
.format([text_color_html]) + tr(line) + "[/color][center]"
|
||||
%text_node.text = (
|
||||
"[color=#" + text_color_html + "]".format([text_color_html]) + tr(line) + "[/color]"
|
||||
)
|
||||
if centered_text:
|
||||
%text_node.text = "[center]" + %text_node.text + "[/center]"
|
||||
if _current_character.is_inside_tree() and is_instance_valid(_dialog_location_node):
|
||||
position = _dialog_location_node.get_global_transform_with_canvas().origin
|
||||
|
||||
if _current_character.is_inside_tree() and \
|
||||
_current_character.has_node("dialog_position"):
|
||||
rect_position = _current_character.get_node(
|
||||
"dialog_position"
|
||||
).get_global_transform_with_canvas().origin
|
||||
rect_position.x -= rect_size.x / 2
|
||||
position.x -= size.x / 2
|
||||
else:
|
||||
rect_position.x = 0
|
||||
rect_size.x = ProjectSettings.get_setting("display/window/size/width")
|
||||
position.x = 0
|
||||
size.x = ProjectSettings.get_setting("display/window/size/viewport_width")
|
||||
|
||||
if rect_position.x < 0:
|
||||
rect_position.x = 0
|
||||
_account_for_margin_x()
|
||||
|
||||
var screen_margin = rect_position.x + rect_size.x - \
|
||||
ProjectSettings.get("display/window/size/width")
|
||||
|
||||
if screen_margin > 0:
|
||||
rect_position.x -= screen_margin
|
||||
_account_for_margin_y()
|
||||
|
||||
_current_character.start_talking()
|
||||
|
||||
text_node.percent_visible = 0.0
|
||||
var time_show_full_text = _text_time_per_character / 1000 * len(_current_line)
|
||||
var slow_text_mode = ProjectSettings.get_setting(RTMISimpleDialogSettings.SLOW_TEXT_MODE)
|
||||
|
||||
var time_show_full_text = _calculate_talking_time()
|
||||
|
||||
# We keep the timer as a way to simulate reading time.
|
||||
_talking_timer.start(time_show_full_text)
|
||||
|
||||
if PROGRESS_BAR_ENABLED:
|
||||
var total_time: float = _calculate_total_time()
|
||||
%ProgressBar.visible = true
|
||||
%ProgressBar.value = 0
|
||||
_progress_tween.tween_property(%ProgressBar, "value", 100, total_time)
|
||||
|
||||
tween.interpolate_property(text_node, "percent_visible",
|
||||
0.0, 1.0, time_show_full_text,
|
||||
Tween.TRANS_LINEAR, Tween.EASE_IN_OUT)
|
||||
tween.start()
|
||||
set_process(true)
|
||||
|
||||
|
||||
# Called by the dialog player when user wants to finish dialogue fast.
|
||||
# Called by the dialog player when the
|
||||
func speedup():
|
||||
if not _is_speeding_up:
|
||||
_is_speeding_up = true
|
||||
var time_show_full_text = _fast_text_time_per_character / 1000 * len(_current_line)
|
||||
|
||||
tween.remove_all()
|
||||
tween.interpolate_property(text_node, "percent_visible",
|
||||
text_node.percent_visible, 1.0, time_show_full_text,
|
||||
Tween.TRANS_LINEAR, Tween.EASE_IN_OUT)
|
||||
tween.start()
|
||||
say_visible.emit()
|
||||
say_finished.emit()
|
||||
|
||||
|
||||
# Called by the dialog player when user wants to finish dialogue immediately.
|
||||
func finish():
|
||||
tween.remove_all()
|
||||
tween.interpolate_property(text_node, "percent_visible",
|
||||
text_node.percent_visible, 1.0, 0.0)
|
||||
tween.start()
|
||||
say_visible.emit()
|
||||
say_finished.emit()
|
||||
|
||||
|
||||
# To be called if voice audio has finished.
|
||||
func voice_audio_finished():
|
||||
if not _click_to_continue:
|
||||
_stop_character_talking()
|
||||
finish();
|
||||
|
||||
|
||||
# Handler to deal with this node being removed
|
||||
func _on_tree_exiting() -> void:
|
||||
_stop_character_talking()
|
||||
|
||||
|
||||
# The dialog line was printed, start the waiting time and then finish
|
||||
# the dialog
|
||||
func _on_dialog_line_typed(object, key):
|
||||
func _on_dialog_line_typed():
|
||||
_stop_character_talking()
|
||||
text_node.visible_characters = -1
|
||||
|
||||
var time_to_disappear: float = _calculate_time_to_disappear()
|
||||
$Timer.start(time_to_disappear)
|
||||
$Timer.connect("timeout", self, "_on_dialog_finished")
|
||||
# This signal is for the core.
|
||||
say_visible.emit()
|
||||
|
||||
emit_signal("say_visible")
|
||||
# Start time to pass line, except click is required or line has audio.
|
||||
if not _click_to_continue and not _has_audio:
|
||||
var time_to_disappear: float = _calculate_time_to_disappear()
|
||||
_clearing_timer.start(time_to_disappear)
|
||||
|
||||
|
||||
func _calculate_talking_time() -> float:
|
||||
if _slow_text_mode:
|
||||
escoria.logger.info(self, "Text in Slow mode")
|
||||
_text_time_per_character = _text_time_per_character * SLOW_TEXT_MODE_MULTIPLIER
|
||||
|
||||
var time = _text_time_per_character / 1000 * len(_current_line)
|
||||
|
||||
var minimum_time = MINIMUM_TALKING_TIME
|
||||
if _slow_text_mode:
|
||||
minimum_time = MINIMUM_TALKING_TIME * SLOW_TEXT_MODE_MULTIPLIER
|
||||
if time < minimum_time:
|
||||
return minimum_time
|
||||
|
||||
return time
|
||||
|
||||
|
||||
func _calculate_time_to_disappear() -> float:
|
||||
return (_get_number_of_words() / _reading_speed_in_wpm as float) * 60
|
||||
return _get_number_of_words() as float / _reading_speed_in_wpm as float
|
||||
|
||||
|
||||
func _calculate_total_time() -> float:
|
||||
return _calculate_talking_time() + _calculate_time_to_disappear()
|
||||
|
||||
|
||||
func _get_number_of_words() -> int:
|
||||
return _word_regex.search_all(text_node.get_text()).size()
|
||||
var a = _word_regex.search_all(%text_node.get_text())
|
||||
var b = _word_regex.search_all(%text_node.get_text()).size()
|
||||
return _word_regex.search_all(%text_node.get_text()).size()
|
||||
|
||||
|
||||
# Ending the dialog
|
||||
func _on_dialog_finished():
|
||||
# Only trigger to clear the text if we aren't limiting the clearing trigger to a click.
|
||||
if not ESCProjectSettingsManager.get_setting(RTMISimpleDialogSettings.CLEAR_TEXT_BY_CLICK_ONLY):
|
||||
emit_signal("say_finished")
|
||||
say_finished.emit()
|
||||
|
||||
|
||||
# Handler managing pause notification from Escoria
|
||||
func _on_paused():
|
||||
if tween.is_active():
|
||||
is_paused = true
|
||||
visible = false
|
||||
tween.stop_all()
|
||||
_talking_timer.set_paused(true)
|
||||
|
||||
|
||||
# Handler managing resume notification from Escoria
|
||||
func _on_resumed():
|
||||
if not tween.is_active():
|
||||
is_paused = false
|
||||
visible = true
|
||||
tween.resume_all()
|
||||
|
||||
|
||||
# Handler to deal with this node being removed
|
||||
func _on_tree_exiting() -> void:
|
||||
_stop_character_talking()
|
||||
_talking_timer.set_paused(false)
|
||||
|
||||
|
||||
func _stop_character_talking():
|
||||
# Make the speaking item animation stop talking, if it is still alive
|
||||
if is_instance_valid(_current_character) and _current_character != null:
|
||||
_current_character.stop_talking()
|
||||
|
||||
|
||||
func _on_tree_exited():
|
||||
_stop_character_talking()
|
||||
|
||||
|
||||
func _account_for_margin_x() -> void:
|
||||
if position.x < 0:
|
||||
position.x = 0
|
||||
|
||||
var screen_margin_x = (
|
||||
position.x + size.x - ProjectSettings.get("display/window/size/viewport_width")
|
||||
)
|
||||
|
||||
if screen_margin_x > 0:
|
||||
position.x -= screen_margin_x + _x_position_offset
|
||||
|
||||
|
||||
func _account_for_margin_y() -> void:
|
||||
if position.y < 0:
|
||||
position.y = 0
|
||||
|
||||
var screen_margin_y = (
|
||||
position.y + size.y - ProjectSettings.get("display/window/size/viewport_height")
|
||||
)
|
||||
|
||||
if screen_margin_y > 0:
|
||||
position.y -= screen_margin_y + _y_position_offset
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
uid://d12nyx86nlc6h
|
||||
@@ -1,18 +1,81 @@
|
||||
[gd_scene load_steps=3 format=2]
|
||||
[gd_scene load_steps=7 format=3 uid="uid://cp75ofyuetxux"]
|
||||
|
||||
[ext_resource path="res://addons/escoria-ui-return-monkey-island-dialog-simple/types/floating.gd" type="Script" id=1]
|
||||
[ext_resource path="res://addons/escoria-ui-return-monkey-island-dialog-simple/theme.tres" type="Theme" id=2]
|
||||
[ext_resource type="Script" uid="uid://d12nyx86nlc6h" path="res://addons/escoria-ui-return-monkey-island-dialog-simple/types/floating.gd" id="1"]
|
||||
[ext_resource type="Texture2D" uid="uid://cn1fjp4q7b5e0" path="res://addons/escoria-ui-return-monkey-island/cursors/rounded_mouse_left.png" id="2_4itiw"]
|
||||
[ext_resource type="Theme" uid="uid://dvwfrnya2nhxu" path="res://addons/escoria-ui-return-monkey-island-dialog-simple/theme/dialog.tres" id="2_7uovn"]
|
||||
[ext_resource type="Theme" uid="uid://dlo07cyfhpilq" path="res://addons/escoria-ui-return-monkey-island-dialog-simple/theme.tres" id="2_f1tsx"]
|
||||
[ext_resource type="Theme" uid="uid://bf2eet52fueam" path="res://addons/escoria-ui-return-monkey-island/theme/ui.tres" id="3_xhqtt"]
|
||||
|
||||
[node name="dialog_label" type="RichTextLabel"]
|
||||
margin_right = 672.0
|
||||
margin_bottom = 97.0
|
||||
theme = ExtResource( 2 )
|
||||
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_4itiw"]
|
||||
|
||||
[node name="dialog_box" type="Window"]
|
||||
transparent_bg = true
|
||||
oversampling_override = 1.0
|
||||
size = Vector2i(600, 167)
|
||||
unresizable = true
|
||||
borderless = true
|
||||
transparent = true
|
||||
popup_window = true
|
||||
script = ExtResource("1")
|
||||
centered_text = true
|
||||
|
||||
[node name="PanelContainer" type="PanelContainer" parent="."]
|
||||
custom_minimum_size = Vector2(600, 60)
|
||||
offset_right = 600.0
|
||||
offset_bottom = 60.0
|
||||
scale = Vector2(0.9775281, 1)
|
||||
theme = ExtResource("2_7uovn")
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="PanelContainer"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="MarginContainer" type="MarginContainer" parent="PanelContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
theme_override_constants/margin_left = 15
|
||||
theme_override_constants/margin_top = 15
|
||||
theme_override_constants/margin_right = 15
|
||||
theme_override_constants/margin_bottom = 15
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="PanelContainer/VBoxContainer/MarginContainer"]
|
||||
layout_mode = 2
|
||||
theme_override_constants/separation = 20
|
||||
|
||||
[node name="text_node" type="RichTextLabel" parent="PanelContainer/VBoxContainer/MarginContainer/VBoxContainer"]
|
||||
unique_name_in_owner = true
|
||||
clip_contents = false
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
theme = ExtResource("2_f1tsx")
|
||||
bbcode_enabled = true
|
||||
bbcode_text = "[center]Here be some text.[/center]"
|
||||
text = "Here be some text."
|
||||
fit_content_height = true
|
||||
script = ExtResource( 1 )
|
||||
text = "Here be some text.Here be some text.Here be some text.[i]Here be some text.[/i]Here be some text.Here be some text.Here[b] be some[/b] text.Here be some text.Here be some text.Here be some text.Here be some text.Here be some text."
|
||||
fit_content = true
|
||||
scroll_active = false
|
||||
autowrap_mode = 2
|
||||
justification_flags = 171
|
||||
|
||||
[node name="Tween" type="Tween" parent="."]
|
||||
[node name="ClickToContinueTip" type="HBoxContainer" parent="PanelContainer/VBoxContainer/MarginContainer/VBoxContainer"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 8
|
||||
size_flags_vertical = 4
|
||||
|
||||
[node name="Timer" type="Timer" parent="."]
|
||||
[node name="icon" type="Sprite2D" parent="PanelContainer/VBoxContainer/MarginContainer/VBoxContainer/ClickToContinueTip"]
|
||||
position = Vector2(1, 8)
|
||||
scale = Vector2(0.583333, 0.583333)
|
||||
texture = ExtResource("2_4itiw")
|
||||
offset = Vector2(-28, 1)
|
||||
|
||||
[node name="label" type="Label" parent="PanelContainer/VBoxContainer/MarginContainer/VBoxContainer/ClickToContinueTip"]
|
||||
layout_mode = 2
|
||||
theme = ExtResource("3_xhqtt")
|
||||
theme_override_font_sizes/font_size = 12
|
||||
theme_override_styles/normal = SubResource("StyleBoxEmpty_4itiw")
|
||||
text = "CLICK_TO_CONTINUE_TIP"
|
||||
|
||||
[node name="ProgressBar" type="ProgressBar" parent="PanelContainer/VBoxContainer"]
|
||||
unique_name_in_owner = true
|
||||
visible = false
|
||||
layout_mode = 2
|
||||
value = 50.0
|
||||
rounded = true
|
||||
show_percentage = false
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
extends Node
|
||||
|
||||
var item_count_manager: ESCItemCountManager
|
||||
|
||||
var tooltip_manager: ESCTootltipManager
|
||||
|
||||
func get_item(global_id: String) -> ESCItem:
|
||||
var object = escoria.object_manager.get_object(global_id)
|
||||
if !object:
|
||||
return null
|
||||
|
||||
var node = object.node
|
||||
if not node is ESCItem:
|
||||
escoria.logger.error(
|
||||
"set_tootltip: invalid object",
|
||||
["Object is not an ESCItem"]
|
||||
)
|
||||
return null
|
||||
|
||||
return node
|
||||
@@ -1,20 +0,0 @@
|
||||
extends TextureButton
|
||||
|
||||
export(Texture) var musicEnabledTexture: Texture
|
||||
export(Texture) var musicEnabledHoverTexture: Texture
|
||||
|
||||
export(Texture) var musicDisabledTexture: Texture
|
||||
export(Texture) var musicDisabledHoverTexture: Texture
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
pass # Replace with function body.
|
||||
|
||||
func _process(delta: float):
|
||||
if escoria.game_scene.musicEnabled == true:
|
||||
texture_normal = musicEnabledTexture
|
||||
texture_hover = musicEnabledHoverTexture
|
||||
else:
|
||||
texture_normal = musicDisabledTexture
|
||||
texture_hover = musicDisabledHoverTexture
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
class_name RTMIAchievementManager
|
||||
|
||||
signal unlocked(achievement_id)
|
||||
|
||||
## Called each second
|
||||
signal time_updated(current_time)
|
||||
|
||||
var time_tracker: RTMIAchievementTimeTracker
|
||||
var played_time: int:
|
||||
get:
|
||||
return time_tracker.time if time_tracker != null else 0
|
||||
|
||||
var _game_achievements: Array = ProjectSettings.get(RTMIUiSettings.ACHIEVEMENT_LIST)
|
||||
|
||||
## Track unlocked achievements
|
||||
var _achievement_tracker: Dictionary = {}
|
||||
|
||||
|
||||
func _init() -> void:
|
||||
_load_achievements()
|
||||
escoria.new_game_started.connect(_on_new_game_started)
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
escoria.get_escoria().add_child(time_tracker)
|
||||
|
||||
|
||||
func _on_new_game_started() -> void:
|
||||
if time_tracker == null:
|
||||
time_tracker = RTMIAchievementTimeTracker.new()
|
||||
escoria.main.add_child(time_tracker)
|
||||
|
||||
|
||||
func get_achievements() -> Dictionary:
|
||||
return _achievement_tracker.duplicate()
|
||||
|
||||
|
||||
func get_achievements_total() -> int:
|
||||
return _game_achievements.size()
|
||||
|
||||
|
||||
func get_unlocked_achievements_total() -> int:
|
||||
var unlocked_achievements_total = 0
|
||||
for key in _achievement_tracker:
|
||||
if _achievement_tracker.get(key):
|
||||
unlocked_achievements_total += 1
|
||||
return unlocked_achievements_total
|
||||
|
||||
|
||||
func reset_achievements() -> void:
|
||||
_achievement_tracker.clear()
|
||||
_load_achievements()
|
||||
|
||||
time_tracker.restart()
|
||||
|
||||
|
||||
func _load_achievements() -> void:
|
||||
for achievement_id in _game_achievements:
|
||||
_achievement_tracker.set(achievement_id, false)
|
||||
|
||||
|
||||
func unlock_achievement(achievement_id) -> void:
|
||||
if not is_unlocked(achievement_id):
|
||||
escoria.logger.info(self, "Achievent '%s' unlocked." % achievement_id)
|
||||
_achievement_tracker.set(achievement_id, true)
|
||||
unlocked.emit(achievement_id)
|
||||
|
||||
|
||||
func is_unlocked(achievement_id: String) -> bool:
|
||||
if not has(achievement_id):
|
||||
escoria.logger.error(self, "Achievement '%s' not found.")
|
||||
return false
|
||||
return _achievement_tracker.get(achievement_id)
|
||||
|
||||
|
||||
func has(achievement_id: String) -> bool:
|
||||
return _achievement_tracker.has(achievement_id)
|
||||
|
||||
|
||||
func generate_achievement_literal(achievement_id: String, variant: String = "_title") -> String:
|
||||
var literal = "achievement_%s" % achievement_id
|
||||
if variant != "":
|
||||
literal += "_%s" % variant
|
||||
return literal
|
||||
|
||||
|
||||
func start_tracking_time() -> void:
|
||||
if not time_tracker == null:
|
||||
time_tracker.restart()
|
||||
|
||||
|
||||
func pause_tracking_time() -> void:
|
||||
if not time_tracker == null:
|
||||
time_tracker.pause()
|
||||
|
||||
|
||||
func resume_tracking_time() -> void:
|
||||
if not time_tracker == null:
|
||||
time_tracker.resume()
|
||||
|
||||
|
||||
func stop_tracking_time() -> void:
|
||||
if not time_tracker == null:
|
||||
time_tracker.stop()
|
||||
@@ -0,0 +1 @@
|
||||
uid://dsyi6bph3dfai
|
||||
@@ -0,0 +1,50 @@
|
||||
class_name RTMIAchievementNotification
|
||||
extends Control
|
||||
|
||||
const _FADE_IN_TIME: float = 0.5
|
||||
const _CLEAR_DELAY: float = 4
|
||||
const _FADE_OUT_TIME: float = 0.5
|
||||
|
||||
var achievement_id: String:
|
||||
get:
|
||||
return achievement_id
|
||||
set(p_achievement_id):
|
||||
achievement_id = p_achievement_id
|
||||
%AchievementTitle.text = tr(gymkhana.achievement_manager.generate_achievement_literal(
|
||||
achievement_id, "title"
|
||||
))
|
||||
%AchievementCounter.text = "(%s/%s)" % [gymkhana.achievement_manager.get_unlocked_achievements_total(), gymkhana.achievement_manager.get_achievements_total()]
|
||||
|
||||
var _timer: Timer = Timer.new()
|
||||
|
||||
var _first_time = true
|
||||
|
||||
|
||||
func _enter_tree() -> void:
|
||||
if _first_time:
|
||||
var tween: Tween = create_tween()
|
||||
tween.tween_property(self, "modulate:a", 1.0, _FADE_IN_TIME).from(0.0)
|
||||
|
||||
_timer.one_shot = true
|
||||
_timer.timeout.connect(_clear_timer_timeout)
|
||||
add_child(_timer)
|
||||
|
||||
_timer.start(_CLEAR_DELAY)
|
||||
_first_time = false
|
||||
|
||||
|
||||
func _clear_timer_timeout() -> void:
|
||||
var tween: Tween = create_tween()
|
||||
tween.tween_property(self, "modulate:a", 0.0, _FADE_OUT_TIME).from(1.0)
|
||||
tween.finished.connect(_fade_out_finished)
|
||||
|
||||
|
||||
func _fade_out_finished() -> void:
|
||||
queue_free()
|
||||
|
||||
|
||||
func _on_clear_button_button_up() -> void:
|
||||
_timer.stop()
|
||||
var tween: Tween = create_tween()
|
||||
tween.tween_property(self, "modulate:a", 0.0, _FADE_OUT_TIME).from(1.0)
|
||||
tween.finished.connect(_fade_out_finished)
|
||||
@@ -0,0 +1 @@
|
||||
uid://cbc01kasyr4uf
|
||||
@@ -0,0 +1,63 @@
|
||||
[gd_scene load_steps=3 format=3 uid="uid://dip0jl80tklyg"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://cbc01kasyr4uf" path="res://addons/escoria-ui-return-monkey-island/achievements/rtmi_achievement_notification.gd" id="1_fsunq"]
|
||||
|
||||
[sub_resource type="LabelSettings" id="LabelSettings_fw80s"]
|
||||
font_color = Color(1, 0.6166667, 0, 1)
|
||||
|
||||
[node name="AchievementNotification" type="Control"]
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("1_fsunq")
|
||||
|
||||
[node name="PanelContainer" type="PanelContainer" parent="."]
|
||||
layout_mode = 0
|
||||
offset_right = 40.0
|
||||
offset_bottom = 40.0
|
||||
|
||||
[node name="MarginContainer" type="MarginContainer" parent="PanelContainer"]
|
||||
layout_mode = 2
|
||||
theme_override_constants/margin_left = 10
|
||||
theme_override_constants/margin_top = 10
|
||||
theme_override_constants/margin_right = 15
|
||||
theme_override_constants/margin_bottom = 10
|
||||
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="PanelContainer/MarginContainer"]
|
||||
layout_mode = 2
|
||||
theme_override_constants/separation = 8
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="PanelContainer/MarginContainer/HBoxContainer"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="PanelContainer/MarginContainer/HBoxContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Label" type="Label" parent="PanelContainer/MarginContainer/HBoxContainer/VBoxContainer/HBoxContainer"]
|
||||
layout_mode = 2
|
||||
text = "ACHIEVEMENT_UNLOCKED_NOTIFICATION_LABEL"
|
||||
|
||||
[node name="AchievementCounter" type="Label" parent="PanelContainer/MarginContainer/HBoxContainer/VBoxContainer/HBoxContainer"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
text = "(1/2)"
|
||||
horizontal_alignment = 2
|
||||
|
||||
[node name="AchievementTitle" type="Label" parent="PanelContainer/MarginContainer/HBoxContainer/VBoxContainer"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
text = "ACHIEVEMENT_ACHIVEMENT_ID_TITLE"
|
||||
label_settings = SubResource("LabelSettings_fw80s")
|
||||
|
||||
[node name="ClearButton" type="Button" parent="PanelContainer/MarginContainer/HBoxContainer"]
|
||||
visible = false
|
||||
custom_minimum_size = Vector2(30, 30)
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
size_flags_vertical = 0
|
||||
text = "X"
|
||||
|
||||
[connection signal="button_up" from="PanelContainer/MarginContainer/HBoxContainer/ClearButton" to="." method="_on_clear_button_button_up"]
|
||||
@@ -0,0 +1,13 @@
|
||||
class_name RTMIAchievementNotificationContainer
|
||||
extends PanelContainer
|
||||
|
||||
|
||||
var _achievement_notification_scene = preload("res://addons/escoria-ui-return-monkey-island/achievements/rtmi_achievement_notification.tscn")
|
||||
|
||||
func _ready() -> void:
|
||||
gymkhana.achievement_manager.unlocked.connect(_achievement_unlocked)
|
||||
|
||||
func _achievement_unlocked(achievement_id) -> void:
|
||||
var achivement_notification = _achievement_notification_scene.instantiate() as RTMIAchievementNotification
|
||||
achivement_notification.achievement_id = achievement_id
|
||||
%Container.add_child(achivement_notification)
|
||||
@@ -0,0 +1 @@
|
||||
uid://bsfo4u74sp5qn
|
||||
@@ -0,0 +1,18 @@
|
||||
[gd_scene load_steps=3 format=3 uid="uid://d3kgkl2r5xe4d"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://bsfo4u74sp5qn" path="res://addons/escoria-ui-return-monkey-island/achievements/rtmi_achievement_notification_container.gd" id="1_omhs5"]
|
||||
|
||||
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_117yv"]
|
||||
|
||||
[node name="AchievementContainer" type="PanelContainer"]
|
||||
offset_right = 40.0
|
||||
offset_bottom = 40.0
|
||||
theme_override_styles/panel = SubResource("StyleBoxEmpty_117yv")
|
||||
script = ExtResource("1_omhs5")
|
||||
|
||||
[node name="MarginContainer" type="MarginContainer" parent="."]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Container" type="VBoxContainer" parent="MarginContainer"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
@@ -0,0 +1,54 @@
|
||||
class_name RTMIAchievementTimeTracker
|
||||
extends Node
|
||||
|
||||
const TIMEOUT_TIME: float = 1.0
|
||||
|
||||
## Timer node
|
||||
var _timer: Timer
|
||||
|
||||
## Elapsed time tracker, in seconds.
|
||||
var _elapsed_seconds: int
|
||||
|
||||
var time: int:
|
||||
get:
|
||||
return _elapsed_seconds
|
||||
|
||||
|
||||
func _ready():
|
||||
process_mode = Node.PROCESS_MODE_ALWAYS
|
||||
|
||||
func _enter_tree() -> void:
|
||||
_timer = Timer.new()
|
||||
_timer.timeout.connect(_timer_timeout)
|
||||
add_child(_timer)
|
||||
start()
|
||||
|
||||
func _timer_timeout() -> void:
|
||||
_elapsed_seconds += 1
|
||||
gymkhana.achievement_manager.time_updated.emit(_elapsed_seconds)
|
||||
|
||||
func elapsed_seconds() -> int:
|
||||
return _elapsed_seconds
|
||||
|
||||
func start() -> void:
|
||||
_timer.start(TIMEOUT_TIME)
|
||||
|
||||
func reset() -> void:
|
||||
_elapsed_seconds = 0
|
||||
|
||||
func stop() -> void:
|
||||
_timer.stop()
|
||||
_timer.timeout.disconnect(_timer_timeout)
|
||||
|
||||
func pause() -> void:
|
||||
_timer.paused = true
|
||||
|
||||
func resume() -> void:
|
||||
_timer.paused = false
|
||||
|
||||
func restart() -> void:
|
||||
reset()
|
||||
start()
|
||||
|
||||
func get_time() -> int:
|
||||
return _elapsed_seconds
|
||||
@@ -0,0 +1 @@
|
||||
uid://bpbe3rklkaddi
|
||||
@@ -0,0 +1,34 @@
|
||||
@tool
|
||||
extends Control
|
||||
|
||||
|
||||
func get_registry_id():
|
||||
return "achievement_inspector"
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
gymkhana.achievement_manager.unlocked.connect(_on_achievement_unlocked)
|
||||
gymkhana.achievement_manager.time_updated.connect(_on_time_updated)
|
||||
update()
|
||||
|
||||
|
||||
func _on_achievement_unlocked(_achievement_id: String) -> void:
|
||||
update()
|
||||
|
||||
|
||||
func update() -> void:
|
||||
clear()
|
||||
var achievements = gymkhana.achievement_manager.get_achievements()
|
||||
achievements.sort()
|
||||
for key in achievements:
|
||||
%Container.add_child(UiEscoriaVariableBuilder.create(key, achievements[key]))
|
||||
|
||||
|
||||
func clear() -> void:
|
||||
for child in %Container.get_children():
|
||||
%Container.remove_child(child)
|
||||
child.queue_free()
|
||||
|
||||
|
||||
func _on_time_updated(elapsed_time_in_seconds: int) -> void:
|
||||
%TimeTrackerLabel.text = str(elapsed_time_in_seconds)
|
||||
@@ -0,0 +1 @@
|
||||
uid://vqxa0p3tqchn
|
||||
@@ -0,0 +1,36 @@
|
||||
[gd_scene load_steps=2 format=3 uid="uid://diaqb8q4cula7"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://vqxa0p3tqchn" path="res://addons/escoria-ui-return-monkey-island/achievements/rtmi_achievements_dev_tool.gd" id="1_1st1v"]
|
||||
|
||||
[node name="AchievementInspector" type="Control"]
|
||||
layout_mode = 3
|
||||
anchors_preset = 0
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
script = ExtResource("1_1st1v")
|
||||
|
||||
[node name="PanelContainer" type="PanelContainer" parent="."]
|
||||
layout_mode = 0
|
||||
offset_right = 4.0
|
||||
offset_bottom = 404.0
|
||||
|
||||
[node name="MarginContainer" type="MarginContainer" parent="PanelContainer"]
|
||||
layout_mode = 2
|
||||
theme_override_constants/margin_left = 2
|
||||
theme_override_constants/margin_top = 2
|
||||
theme_override_constants/margin_right = 2
|
||||
theme_override_constants/margin_bottom = 2
|
||||
|
||||
[node name="ScrollContainer" type="ScrollContainer" parent="PanelContainer/MarginContainer"]
|
||||
custom_minimum_size = Vector2(0, 400)
|
||||
layout_mode = 2
|
||||
horizontal_scroll_mode = 0
|
||||
|
||||
[node name="Container" type="VBoxContainer" parent="PanelContainer/MarginContainer/ScrollContainer"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
|
||||
[node name="TimeTrackerLabel" type="Label" parent="PanelContainer/MarginContainer"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
text = "00:00:00"
|
||||
@@ -0,0 +1,13 @@
|
||||
class_name RTMIScoreRow
|
||||
|
||||
var name: String
|
||||
|
||||
var time: int
|
||||
|
||||
var date: String
|
||||
|
||||
|
||||
func _init(document: Dictionary) -> void:
|
||||
name = document.get("name")
|
||||
time = document.get("time")
|
||||
date = document.get("$createdAt")
|
||||
@@ -0,0 +1 @@
|
||||
uid://8c4xr4s71geu
|
||||
@@ -0,0 +1,145 @@
|
||||
class_name RTMIScoreManager
|
||||
extends Node
|
||||
## Score manager to get and submit scores from and to Scoreboard web service.
|
||||
|
||||
const PERFECT = "perfect"
|
||||
const FASTEST = "fastest"
|
||||
const SUBMIT = "submit"
|
||||
|
||||
const API_CONFIG_PATH = "res://secret/api.cfg"
|
||||
const API_CONFIG_DB_SECTION = "score_db"
|
||||
const API_CONFIG_SUBMIT_SECTION = "score_submit"
|
||||
|
||||
# Variables loaded from api.cfg
|
||||
var api_url: String
|
||||
var project_id: String
|
||||
var database_id: String
|
||||
var score_submit_url: String
|
||||
var score_submit_key: String
|
||||
|
||||
# Session cookie used for authentication. Needed for score submitting. Stored encrypted in session_cookie.cfg
|
||||
# using session_cookie_encrypted_pass as key.
|
||||
var session_cookie: String = ""
|
||||
# Session cookie expiry date in seconds from Unix epoch.
|
||||
var session_cookie_expiry_date: int = -1
|
||||
|
||||
var http_requests: Dictionary = {
|
||||
PERFECT: HTTPRequest.new(),
|
||||
FASTEST: HTTPRequest.new(),
|
||||
SUBMIT: HTTPRequest.new(),
|
||||
}
|
||||
|
||||
|
||||
func _init(scene) -> void:
|
||||
_load_api_config()
|
||||
|
||||
# TODO: remove when https://functions.app.fosil.eu has a valid certificate
|
||||
http_requests[SUBMIT].set_tls_options(TLSOptions.client_unsafe())
|
||||
|
||||
scene.add_child(http_requests[PERFECT])
|
||||
scene.add_child(http_requests[FASTEST])
|
||||
scene.add_child(http_requests[SUBMIT])
|
||||
|
||||
|
||||
func _load_api_config() -> void:
|
||||
var config = ConfigFile.new()
|
||||
var error = config.load(API_CONFIG_PATH)
|
||||
if error != OK:
|
||||
push_error("An error occurred loading api config: error=%s" % error)
|
||||
return
|
||||
|
||||
api_url = config.get_value(API_CONFIG_DB_SECTION, "url", "")
|
||||
project_id = config.get_value(API_CONFIG_DB_SECTION, "project_id", "")
|
||||
database_id = config.get_value(API_CONFIG_DB_SECTION, "database_id", "")
|
||||
score_submit_url = config.get_value(API_CONFIG_SUBMIT_SECTION, "url", "")
|
||||
score_submit_key = config.get_value(API_CONFIG_SUBMIT_SECTION, "key", "")
|
||||
|
||||
|
||||
func get_scores(collection: String) -> Array[RTMIScoreRow]:
|
||||
var http_request = http_requests[collection]
|
||||
var response_data = await _score_http_request(http_request, "%s/databases/%s/collections/%s/documents" % [api_url, database_id, collection])
|
||||
|
||||
if not response_data:
|
||||
return []
|
||||
|
||||
# Map DB rows to RTMIScoreRow
|
||||
var scores_untyped = response_data.get("documents").map(func(document): return RTMIScoreRow.new(document))
|
||||
scores_untyped.sort_custom(func(first, last): return first.time < last.time)
|
||||
# Array.map() does not support typing, we need to use Array.assign to set the type.
|
||||
var scores: Array[RTMIScoreRow]
|
||||
scores.assign(scores_untyped)
|
||||
return scores
|
||||
|
||||
|
||||
func submit_score(collection: String, name: String, time: int) -> bool:
|
||||
var hash = ("%s_%s_%s_%s" % [collection, name, time, score_submit_key]).sha256_text()
|
||||
var request_data: String = (
|
||||
JSON
|
||||
. new()
|
||||
. stringify(
|
||||
{
|
||||
"collectionId": collection,
|
||||
"score":
|
||||
{
|
||||
"name": name,
|
||||
"time": time,
|
||||
},
|
||||
"hash": hash
|
||||
}
|
||||
)
|
||||
)
|
||||
var response_data = await _score_http_request(http_requests[SUBMIT], score_submit_url, HTTPClient.METHOD_POST, request_data)
|
||||
|
||||
if not response_data.success:
|
||||
push_error("Error submitting score: error=%s" % response_data.errorMsg)
|
||||
|
||||
return response_data.success
|
||||
|
||||
|
||||
## Calculates a certain time which position would have in scoreboard. First position is 0.
|
||||
func calculate_score_position(collection: String, time: int) -> int:
|
||||
var scores: Array[RTMIScoreRow] = await get_scores(collection)
|
||||
var pos = scores.find_custom(func(score): return time < score.time)
|
||||
if pos < 0:
|
||||
return scores.size()
|
||||
|
||||
return pos
|
||||
|
||||
|
||||
func _score_http_request(
|
||||
http_request: HTTPRequest, url: String, method: int = HTTPClient.METHOD_GET, request_data: String = "", additional_headers: Array = []
|
||||
) -> Variant:
|
||||
var headers = ["X-Appwrite-Project: %s" % project_id, "Content-Type: application/json"]
|
||||
headers.append_array(additional_headers)
|
||||
|
||||
var error = http_request.request(url, headers, method, request_data)
|
||||
if error:
|
||||
push_error("An error occurred creating the HTTP request: error=%s" % error)
|
||||
return null
|
||||
|
||||
var response: Array = await http_request.request_completed
|
||||
var result: int = response[0]
|
||||
var http_status: int = response[1]
|
||||
var response_body: PackedByteArray = response[3]
|
||||
|
||||
if result != HTTPRequest.RESULT_SUCCESS or http_status < 200 or http_status >= 300:
|
||||
push_error("HTTP request returned an error: result=%s http_status=%s body=%s" % [result, http_status, response_body.get_string_from_utf8()])
|
||||
return null
|
||||
|
||||
var response_data = JSON.parse_string(response_body.get_string_from_utf8())
|
||||
if not response_data:
|
||||
push_error("Error parsing HTTP response body.")
|
||||
return null
|
||||
|
||||
return response_data
|
||||
|
||||
|
||||
func format_time(time: int) -> String:
|
||||
var hours = time / 3600
|
||||
var minutes = (time % 3600) / 60
|
||||
var seconds = time % 60
|
||||
|
||||
if hours:
|
||||
return "%dh %02dm %02ds" % [hours, minutes, seconds]
|
||||
|
||||
return "%dm %02ds" % [minutes, seconds]
|
||||
@@ -0,0 +1 @@
|
||||
uid://br2xa7lcrals3
|
||||
@@ -0,0 +1,16 @@
|
||||
extends Control
|
||||
|
||||
func _ready() -> void:
|
||||
refresh()
|
||||
|
||||
func refresh():
|
||||
%FastestScores.refresh()
|
||||
%PerfectScores.refresh()
|
||||
|
||||
|
||||
func _on_back_pressed() -> void:
|
||||
hide()
|
||||
|
||||
|
||||
func _on_refresh_pressed() -> void:
|
||||
refresh()
|
||||
@@ -0,0 +1 @@
|
||||
uid://bhi02d1pasur4
|
||||
@@ -0,0 +1,59 @@
|
||||
[gd_scene load_steps=5 format=3 uid="uid://cqgluci3f3v3n"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://bhi02d1pasur4" path="res://addons/escoria-ui-return-monkey-island/achievements/scoreboard/rtmi_scoreboard.gd" id="1_efvuy"]
|
||||
[ext_resource type="Theme" uid="uid://djtwqnfbbt5t8" path="res://addons/escoria-ui-return-monkey-island/theme/menu.tres" id="1_ip2kf"]
|
||||
[ext_resource type="PackedScene" uid="uid://ooknv238745j" path="res://addons/escoria-ui-return-monkey-island/achievements/scoreboard/rtmi_scoreboard_panel.tscn" id="1_o5uv4"]
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_efvuy"]
|
||||
bg_color = Color(0.22, 0.22, 0.22, 1)
|
||||
|
||||
[node name="RtmiScoreboard" type="PanelContainer"]
|
||||
process_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
theme = ExtResource("1_ip2kf")
|
||||
theme_override_styles/panel = SubResource("StyleBoxFlat_efvuy")
|
||||
script = ExtResource("1_efvuy")
|
||||
|
||||
[node name="CenterContainer" type="CenterContainer" parent="."]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="CenterContainer"]
|
||||
layout_mode = 2
|
||||
theme_override_constants/separation = 20
|
||||
alignment = 1
|
||||
|
||||
[node name="HBoxContainer2" type="HBoxContainer" parent="CenterContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="FastestScores" parent="CenterContainer/VBoxContainer/HBoxContainer2" instance=ExtResource("1_o5uv4")]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
collection = "fastest"
|
||||
|
||||
[node name="PerfectScores" parent="CenterContainer/VBoxContainer/HBoxContainer2" instance=ExtResource("1_o5uv4")]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
collection = "perfect"
|
||||
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="CenterContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
alignment = 1
|
||||
|
||||
[node name="Back" type="Button" parent="CenterContainer/VBoxContainer/HBoxContainer"]
|
||||
custom_minimum_size = Vector2(300, 50)
|
||||
layout_mode = 2
|
||||
text = "SCOREBOARD_BACK"
|
||||
|
||||
[node name="Refresh" type="Button" parent="CenterContainer/VBoxContainer/HBoxContainer"]
|
||||
custom_minimum_size = Vector2(300, 50)
|
||||
layout_mode = 2
|
||||
text = "SCOREBOARD_REFRESH"
|
||||
|
||||
[connection signal="pressed" from="CenterContainer/VBoxContainer/HBoxContainer/Back" to="." method="_on_back_pressed"]
|
||||
[connection signal="pressed" from="CenterContainer/VBoxContainer/HBoxContainer/Refresh" to="." method="_on_refresh_pressed"]
|
||||
@@ -0,0 +1,115 @@
|
||||
@tool
|
||||
class_name RTMISocoreboardPanel
|
||||
extends PanelContainer
|
||||
|
||||
const RECORDS_PER_PAGE: int = 10
|
||||
|
||||
@export var collection: String
|
||||
|
||||
var scores: Array[RTMIScoreRow]
|
||||
var total_records: int = 0
|
||||
var current_page: int = 0
|
||||
var total_pages: int = 0
|
||||
|
||||
@onready var prev_button: RTMIMenuButton = %PrevButton
|
||||
@onready var next_button: RTMIMenuButton = %NextButton
|
||||
@onready var spinner: Spinner = %Spinner
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
%Title.text = str("SCOREBOARD_%s_TITLE" % collection).to_upper()
|
||||
spinner.hide()
|
||||
prev_button.pressed.connect(_prev_page)
|
||||
next_button.pressed.connect(_next_page)
|
||||
|
||||
|
||||
func refresh() -> void:
|
||||
current_page = 0
|
||||
total_records = 0
|
||||
spinner.show()
|
||||
await _get_scores()
|
||||
spinner.hide()
|
||||
_fill_scores()
|
||||
|
||||
|
||||
func _fill_scores():
|
||||
_clear_scores()
|
||||
|
||||
total_records = scores.size()
|
||||
total_pages = total_records / RECORDS_PER_PAGE
|
||||
if total_records % RECORDS_PER_PAGE > 0:
|
||||
total_pages += 1
|
||||
_update_pager()
|
||||
|
||||
if scores.is_empty():
|
||||
return
|
||||
|
||||
var start_score = current_page * RECORDS_PER_PAGE
|
||||
var end_score = (current_page + 1) * RECORDS_PER_PAGE
|
||||
if end_score >= total_records:
|
||||
end_score = total_records + 1
|
||||
var scores_slice = scores.slice(start_score, end_score)
|
||||
|
||||
var pos: int = RECORDS_PER_PAGE * current_page + 1
|
||||
for score in scores_slice:
|
||||
# ToDo create and add rich label
|
||||
var label = Label.new()
|
||||
label.add_theme_font_override("font", load("res://addons/escoria-ui-return-monkey-island/fonts/SpaceMono-Regular.ttf"))
|
||||
label.text = (" %2s. %-24s %10s %19s" % [pos, score.name.to_upper(), _format_time(score.time), _format_date(score.date)])
|
||||
%Scores.add_child(label)
|
||||
pos += 1
|
||||
|
||||
|
||||
func _clear_scores() -> void:
|
||||
for child in %Scores.get_children():
|
||||
%Scores.remove_child(child)
|
||||
child.queue_free()
|
||||
|
||||
|
||||
func _get_scores() -> void:
|
||||
if gymkhana.score_manager == null:
|
||||
return
|
||||
|
||||
scores = await gymkhana.score_manager.get_scores(collection)
|
||||
|
||||
|
||||
func _prev_page() -> void:
|
||||
if current_page > 0:
|
||||
current_page -= 1
|
||||
_fill_scores()
|
||||
|
||||
|
||||
func _next_page() -> void:
|
||||
if current_page < total_pages - 1:
|
||||
current_page += 1
|
||||
_fill_scores()
|
||||
|
||||
|
||||
func _update_pager() -> void:
|
||||
prev_button.disabled = true
|
||||
prev_button.focus_mode = FOCUS_NONE
|
||||
|
||||
next_button.disabled = true
|
||||
next_button.focus_mode = FOCUS_NONE
|
||||
|
||||
if current_page > 0:
|
||||
prev_button.disabled = false
|
||||
|
||||
if current_page < total_pages - 1:
|
||||
next_button.disabled = false
|
||||
|
||||
|
||||
func _format_date(iso_date: String) -> String:
|
||||
var date = Time.get_datetime_dict_from_datetime_string(iso_date, false)
|
||||
return "%s/%02d/%02d %02d:%02d" % [date["year"], date["month"], date["day"], date["hour"], date["minute"]]
|
||||
|
||||
|
||||
func _format_time(time: int) -> String:
|
||||
var hours = time / 3600
|
||||
var minutes = (time % 3600) / 60
|
||||
var seconds = time % 60
|
||||
|
||||
if hours:
|
||||
return "%dh %02dm %02ds" % [hours, minutes, seconds]
|
||||
|
||||
return "%dm %02ds" % [minutes, seconds]
|
||||
@@ -0,0 +1 @@
|
||||
uid://cxvhsdqap7w1b
|
||||
@@ -0,0 +1,194 @@
|
||||
[gd_scene load_steps=8 format=3 uid="uid://ooknv238745j"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://cxvhsdqap7w1b" path="res://addons/escoria-ui-return-monkey-island/achievements/scoreboard/rtmi_scoreboard_panel.gd" id="1_35c2h"]
|
||||
[ext_resource type="Theme" uid="uid://djtwqnfbbt5t8" path="res://addons/escoria-ui-return-monkey-island/theme/menu.tres" id="1_ine7w"]
|
||||
[ext_resource type="FontFile" uid="uid://bq0vin2knt0or" path="res://addons/escoria-ui-return-monkey-island/fonts/SpaceMono-Regular.ttf" id="2_bn406"]
|
||||
[ext_resource type="Script" uid="uid://elqkwjm0r5c7" path="res://addons/escoria-ui-return-monkey-island/menus/rtmi_menu_button.gd" id="2_hgepf"]
|
||||
[ext_resource type="Script" uid="uid://doqt8bqgwakt" path="res://addons/tattomoosa.spinner/spinner.gd" id="4_bn406"]
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_ine7w"]
|
||||
bg_color = Color(0.2520276, 0.25202766, 0.25202754, 1)
|
||||
|
||||
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_hgepf"]
|
||||
|
||||
[node name="ScoreBoardPanel" type="PanelContainer"]
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
theme = ExtResource("1_ine7w")
|
||||
theme_override_styles/panel = SubResource("StyleBoxFlat_ine7w")
|
||||
script = ExtResource("1_35c2h")
|
||||
|
||||
[node name="MarginContainer" type="MarginContainer" parent="."]
|
||||
layout_mode = 2
|
||||
theme_override_constants/margin_left = 10
|
||||
theme_override_constants/margin_top = 10
|
||||
theme_override_constants/margin_right = 10
|
||||
theme_override_constants/margin_bottom = 10
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Title" type="Label" parent="MarginContainer/VBoxContainer"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
theme_override_fonts/font = ExtResource("2_bn406")
|
||||
theme_override_font_sizes/font_size = 23
|
||||
text = "SCOREBOARD__TITLE"
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="Scores" type="VBoxContainer" parent="MarginContainer/VBoxContainer"]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(600, 280)
|
||||
layout_mode = 2
|
||||
|
||||
[node name="RichTextLabel" type="RichTextLabel" parent="MarginContainer/VBoxContainer/Scores"]
|
||||
layout_mode = 2
|
||||
text = "PLAYER_NAME - TIME - DATE"
|
||||
fit_content = true
|
||||
scroll_active = false
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="RichTextLabel2" type="RichTextLabel" parent="MarginContainer/VBoxContainer/Scores"]
|
||||
layout_mode = 2
|
||||
text = "PLAYER_NAME - TIME - DATE"
|
||||
fit_content = true
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="RichTextLabel3" type="RichTextLabel" parent="MarginContainer/VBoxContainer/Scores"]
|
||||
layout_mode = 2
|
||||
text = "PLAYER_NAME - TIME - DATE"
|
||||
fit_content = true
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="RichTextLabel4" type="RichTextLabel" parent="MarginContainer/VBoxContainer/Scores"]
|
||||
layout_mode = 2
|
||||
text = "PLAYER_NAME - TIME - DATE"
|
||||
fit_content = true
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="RichTextLabel5" type="RichTextLabel" parent="MarginContainer/VBoxContainer/Scores"]
|
||||
layout_mode = 2
|
||||
text = "PLAYER_NAME - TIME - DATE"
|
||||
fit_content = true
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="RichTextLabel6" type="RichTextLabel" parent="MarginContainer/VBoxContainer/Scores"]
|
||||
layout_mode = 2
|
||||
text = "PLAYER_NAME - TIME - DATE"
|
||||
fit_content = true
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="RichTextLabel7" type="RichTextLabel" parent="MarginContainer/VBoxContainer/Scores"]
|
||||
layout_mode = 2
|
||||
text = "PLAYER_NAME - TIME - DATE"
|
||||
fit_content = true
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="RichTextLabel8" type="RichTextLabel" parent="MarginContainer/VBoxContainer/Scores"]
|
||||
layout_mode = 2
|
||||
text = "PLAYER_NAME - TIME - DATE"
|
||||
fit_content = true
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="RichTextLabel9" type="RichTextLabel" parent="MarginContainer/VBoxContainer/Scores"]
|
||||
layout_mode = 2
|
||||
text = "PLAYER_NAME - TIME - DATE"
|
||||
fit_content = true
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="RichTextLabel10" type="RichTextLabel" parent="MarginContainer/VBoxContainer/Scores"]
|
||||
layout_mode = 2
|
||||
text = "PLAYER_NAME - TIME - DATE"
|
||||
fit_content = true
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
alignment = 1
|
||||
|
||||
[node name="PrevButton" type="Button" parent="MarginContainer/VBoxContainer/HBoxContainer"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
theme_override_styles/focus = SubResource("StyleBoxEmpty_hgepf")
|
||||
text = "< "
|
||||
script = ExtResource("2_hgepf")
|
||||
metadata/_custom_type_script = "uid://elqkwjm0r5c7"
|
||||
|
||||
[node name="NextButton" type="Button" parent="MarginContainer/VBoxContainer/HBoxContainer"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
text = ">"
|
||||
script = ExtResource("2_hgepf")
|
||||
metadata/_custom_type_script = "uid://elqkwjm0r5c7"
|
||||
|
||||
[node name="Spinner" type="Range" parent="."]
|
||||
_import_path = NodePath("")
|
||||
unique_name_in_owner = true
|
||||
process_mode = 0
|
||||
process_priority = 0
|
||||
process_physics_priority = 0
|
||||
process_thread_group = 0
|
||||
physics_interpolation_mode = 2
|
||||
auto_translate_mode = 0
|
||||
editor_description = ""
|
||||
visible = false
|
||||
modulate = Color(1, 1, 1, 1)
|
||||
self_modulate = Color(1, 1, 1, 1)
|
||||
show_behind_parent = false
|
||||
top_level = false
|
||||
clip_children = 0
|
||||
light_mask = 1
|
||||
visibility_layer = 1
|
||||
z_index = 0
|
||||
z_as_relative = true
|
||||
y_sort_enabled = false
|
||||
texture_filter = 0
|
||||
texture_repeat = 0
|
||||
material = null
|
||||
use_parent_material = false
|
||||
clip_contents = true
|
||||
custom_minimum_size = Vector2(100, 100)
|
||||
layout_direction = 0
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
size_flags_vertical = 4
|
||||
size_flags_stretch_ratio = 1.0
|
||||
localize_numeral_system = true
|
||||
tooltip_text = ""
|
||||
tooltip_auto_translate_mode = 0
|
||||
focus_neighbor_left = NodePath("")
|
||||
focus_neighbor_top = NodePath("")
|
||||
focus_neighbor_right = NodePath("")
|
||||
focus_neighbor_bottom = NodePath("")
|
||||
focus_next = NodePath("")
|
||||
focus_previous = NodePath("")
|
||||
focus_mode = 0
|
||||
focus_behavior_recursive = 0
|
||||
mouse_filter = 0
|
||||
mouse_behavior_recursive = 0
|
||||
mouse_force_pass_scroll_events = true
|
||||
mouse_default_cursor_shape = 0
|
||||
accessibility_name = ""
|
||||
accessibility_description = ""
|
||||
accessibility_live = 0
|
||||
accessibility_controls_nodes = Array[NodePath]([])
|
||||
accessibility_described_by_nodes = Array[NodePath]([])
|
||||
accessibility_labeled_by_nodes = Array[NodePath]([])
|
||||
accessibility_flow_to_nodes = Array[NodePath]([])
|
||||
theme = null
|
||||
theme_type_variation = &""
|
||||
min_value = 0.0
|
||||
max_value = 100.0
|
||||
step = 1.0
|
||||
value = 0.0
|
||||
exp_edit = false
|
||||
rounded = false
|
||||
allow_greater = false
|
||||
allow_lesser = false
|
||||
script = ExtResource("4_bn406")
|
||||
spin_fill_percent = 0.091
|
||||
color_progress = Color(1, 1, 1, 1)
|
||||
color_background = Color(0, 0, 0, 0)
|
||||
@@ -0,0 +1,147 @@
|
||||
class_name RTMIAchievementSummaryContainer
|
||||
extends PanelContainer
|
||||
|
||||
signal score_submitted()
|
||||
|
||||
const CHARACTER_LIMIT: int = 32
|
||||
const ALLOWED_CHARACTERS = "[à-ÿÀ-ŸA-Za-z0-9 _-]"
|
||||
|
||||
var perfect = false
|
||||
var collection: String
|
||||
|
||||
@onready var input_name: LineEdit = %InputName
|
||||
@onready var total_time: Label = %TotalTime
|
||||
@onready var pos: Label = %Position
|
||||
@onready var achievement_count: Label = %AchievementCount
|
||||
@onready var unlocked_achievements_container: VBoxContainer = %UnlockedAchievementsContainer
|
||||
@onready var submit_button: RTMIMenuButton = %SubmitButton
|
||||
@onready var spinner: Spinner = %Spinner
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
_fill()
|
||||
input_name.text_changed.connect(_on_input_name_changed)
|
||||
input_name.grab_focus()
|
||||
|
||||
|
||||
func show():
|
||||
super.show()
|
||||
|
||||
|
||||
func _input(event: InputEvent) -> void:
|
||||
if event.is_action_pressed("ui_enter"):
|
||||
_on_submit_button_up()
|
||||
|
||||
|
||||
func _fill():
|
||||
_clear()
|
||||
total_time.text = gymkhana.score_manager.format_time(gymkhana.achievement_manager.played_time)
|
||||
var achievements = gymkhana.achievement_manager.get_achievements()
|
||||
var unlocked = 0
|
||||
for achievement_key in achievements:
|
||||
var label = Label.new()
|
||||
label.text = tr(gymkhana.achievement_manager.generate_achievement_literal(
|
||||
achievement_key, "title"
|
||||
))
|
||||
label.add_theme_color_override("font_color", Color.DIM_GRAY)
|
||||
if achievements.get(achievement_key):
|
||||
label.add_theme_color_override("font_color", Color.GREEN)
|
||||
unlocked += 1
|
||||
unlocked_achievements_container.add_child(label)
|
||||
|
||||
achievement_count.text = "%s / %s" % [unlocked, achievements.size()]
|
||||
|
||||
if unlocked == achievements.size():
|
||||
submit_button.text = tr("SUBMIT_PERFECT_SCORE")
|
||||
perfect = true
|
||||
|
||||
collection = gymkhana.score_manager.PERFECT if perfect else gymkhana.score_manager.FASTEST
|
||||
check_score()
|
||||
|
||||
|
||||
func check_score():
|
||||
if perfect:
|
||||
escoria.game_scene.launch_confetti()
|
||||
|
||||
var played_time = floor(randf() * 1000)
|
||||
var pos_int = await gymkhana.score_manager.calculate_score_position(collection, gymkhana.achievement_manager.played_time)
|
||||
pos.text = "#" + str(pos_int + 1)
|
||||
|
||||
|
||||
func _clear() -> void:
|
||||
for child in unlocked_achievements_container.get_children():
|
||||
unlocked_achievements_container.remove_child(child)
|
||||
child.queue_free()
|
||||
|
||||
|
||||
func _get_all_achievements() -> Array:
|
||||
var unlocked_achievements: Array = []
|
||||
var all_achievements = gymkhana.achievement_manager.get_achievements()
|
||||
for achievement in all_achievements:
|
||||
if all_achievements.get(achievement) == true:
|
||||
unlocked_achievements.append(achievement)
|
||||
return unlocked_achievements
|
||||
|
||||
|
||||
func _on_input_name_changed(_new_text: String):
|
||||
var valid = _validate_name()
|
||||
|
||||
if not valid:
|
||||
_set_label_error()
|
||||
return
|
||||
_set_label_no_error()
|
||||
|
||||
|
||||
func _on_submit_button_up() -> void:
|
||||
var valid = _validate_name()
|
||||
if not valid:
|
||||
_set_label_error()
|
||||
return
|
||||
|
||||
spinner.show()
|
||||
var success: bool = await gymkhana.score_manager.submit_score(collection, input_name.text, gymkhana.achievement_manager.played_time)
|
||||
if success:
|
||||
_set_submit_ok()
|
||||
input_name.editable = false
|
||||
input_name.selecting_enabled = false
|
||||
input_name.focus_mode = FOCUS_NONE
|
||||
submit_button.disabled = true
|
||||
submit_button.focus_mode = FOCUS_NONE
|
||||
score_submitted.emit()
|
||||
else:
|
||||
_set_submit_error()
|
||||
spinner.hide()
|
||||
|
||||
|
||||
func _validate_name() -> bool:
|
||||
if input_name.text == "":
|
||||
return false
|
||||
|
||||
var regex = RegEx.new()
|
||||
regex.compile(ALLOWED_CHARACTERS)
|
||||
var result = regex.sub(input_name.text, "", true)
|
||||
|
||||
var valid_name = ""
|
||||
for char in regex.search_all(input_name.text):
|
||||
valid_name += char.get_string()
|
||||
|
||||
input_name.text = valid_name
|
||||
input_name.caret_column = valid_name.length()
|
||||
|
||||
return true
|
||||
|
||||
|
||||
func _set_label_error() -> void:
|
||||
input_name.modulate = Color.RED
|
||||
|
||||
|
||||
func _set_label_no_error() -> void:
|
||||
input_name.modulate = Color.WHITE
|
||||
|
||||
|
||||
func _set_submit_ok() -> void:
|
||||
submit_button.modulate = Color.GREEN
|
||||
|
||||
|
||||
func _set_submit_error() -> void:
|
||||
submit_button.modulate = Color.RED
|
||||
@@ -0,0 +1 @@
|
||||
uid://wor3bvk7tdh0
|
||||
@@ -0,0 +1,228 @@
|
||||
[gd_scene load_steps=5 format=3 uid="uid://ch5d4emoxq6t4"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://wor3bvk7tdh0" path="res://addons/escoria-ui-return-monkey-island/achievements/summary/rtmi_achievement_summary.gd" id="1_vcqj7"]
|
||||
[ext_resource type="Script" uid="uid://elqkwjm0r5c7" path="res://addons/escoria-ui-return-monkey-island/menus/rtmi_menu_button.gd" id="2_3d1qx"]
|
||||
[ext_resource type="Script" uid="uid://doqt8bqgwakt" path="res://addons/tattomoosa.spinner/spinner.gd" id="3_co5jd"]
|
||||
|
||||
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_co5jd"]
|
||||
|
||||
[node name="AchievementSummary" type="PanelContainer"]
|
||||
custom_minimum_size = Vector2(300, 0)
|
||||
offset_right = 40.0
|
||||
offset_bottom = 40.0
|
||||
script = ExtResource("1_vcqj7")
|
||||
|
||||
[node name="MarginContainer" type="MarginContainer" parent="."]
|
||||
layout_mode = 2
|
||||
theme_override_constants/margin_left = 10
|
||||
theme_override_constants/margin_top = 10
|
||||
theme_override_constants/margin_right = 10
|
||||
theme_override_constants/margin_bottom = 10
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer/VBoxContainer/HBoxContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="TotalTimeLabel" type="Label" parent="MarginContainer/VBoxContainer/HBoxContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 20
|
||||
text = "TOTAL_TIME"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="TotalTime" type="Label" parent="MarginContainer/VBoxContainer/HBoxContainer/VBoxContainer"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 24
|
||||
text = "0h 00m 00s"
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 2
|
||||
|
||||
[node name="VBoxContainer2" type="VBoxContainer" parent="MarginContainer/VBoxContainer/HBoxContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="PositionLabel" type="Label" parent="MarginContainer/VBoxContainer/HBoxContainer/VBoxContainer2"]
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 20
|
||||
text = "POSITION"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="Position" type="Label" parent="MarginContainer/VBoxContainer/HBoxContainer/VBoxContainer2"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 24
|
||||
text = "-"
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 2
|
||||
|
||||
[node name="HSeparator" type="HSeparator" parent="MarginContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
theme_override_styles/separator = SubResource("StyleBoxEmpty_co5jd")
|
||||
|
||||
[node name="MarginContainer2" type="MarginContainer" parent="MarginContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="HBoxContainer2" type="HBoxContainer" parent="MarginContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="AchievementTitle" type="Label" parent="MarginContainer/VBoxContainer/HBoxContainer2"]
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 12
|
||||
text = "ACHIEVEMENT_SUMMARY"
|
||||
|
||||
[node name="AchievementCount" type="Label" parent="MarginContainer/VBoxContainer/HBoxContainer2"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
theme_override_font_sizes/font_size = 12
|
||||
text = "1 / 7"
|
||||
horizontal_alignment = 2
|
||||
|
||||
[node name="MarginContainer" type="MarginContainer" parent="MarginContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
theme_override_constants/margin_top = 10
|
||||
theme_override_constants/margin_bottom = 10
|
||||
|
||||
[node name="UnlockedAchievementsContainer" type="VBoxContainer" parent="MarginContainer/VBoxContainer/MarginContainer"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
theme_override_constants/separation = 4
|
||||
|
||||
[node name="Label" type="Label" parent="MarginContainer/VBoxContainer/MarginContainer/UnlockedAchievementsContainer"]
|
||||
layout_mode = 2
|
||||
text = "ACHIEVEMENT TEXT PLACEHOLDER"
|
||||
|
||||
[node name="Label2" type="Label" parent="MarginContainer/VBoxContainer/MarginContainer/UnlockedAchievementsContainer"]
|
||||
layout_mode = 2
|
||||
text = "ACHIEVEMENT TEXT PLACEHOLDER"
|
||||
|
||||
[node name="Label3" type="Label" parent="MarginContainer/VBoxContainer/MarginContainer/UnlockedAchievementsContainer"]
|
||||
layout_mode = 2
|
||||
text = "ACHIEVEMENT TEXT PLACEHOLDER"
|
||||
|
||||
[node name="Label4" type="Label" parent="MarginContainer/VBoxContainer/MarginContainer/UnlockedAchievementsContainer"]
|
||||
layout_mode = 2
|
||||
text = "ACHIEVEMENT TEXT PLACEHOLDER"
|
||||
|
||||
[node name="Label5" type="Label" parent="MarginContainer/VBoxContainer/MarginContainer/UnlockedAchievementsContainer"]
|
||||
layout_mode = 2
|
||||
text = "ACHIEVEMENT TEXT PLACEHOLDER"
|
||||
|
||||
[node name="Label6" type="Label" parent="MarginContainer/VBoxContainer/MarginContainer/UnlockedAchievementsContainer"]
|
||||
layout_mode = 2
|
||||
text = "ACHIEVEMENT TEXT PLACEHOLDER"
|
||||
|
||||
[node name="HSeparator3" type="HSeparator" parent="MarginContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
theme_override_styles/separator = SubResource("StyleBoxEmpty_co5jd")
|
||||
|
||||
[node name="InputName" type="LineEdit" parent="MarginContainer/VBoxContainer"]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(0, 60)
|
||||
layout_mode = 2
|
||||
placeholder_text = "NAME_PLACEHOLDER"
|
||||
clear_button_enabled = true
|
||||
caret_blink = true
|
||||
|
||||
[node name="HSeparator2" type="HSeparator" parent="MarginContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
theme_override_styles/separator = SubResource("StyleBoxEmpty_co5jd")
|
||||
|
||||
[node name="SubmitButton" type="Button" parent="MarginContainer/VBoxContainer"]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(0, 60)
|
||||
layout_mode = 2
|
||||
text = "SUBMIT_SCORE"
|
||||
script = ExtResource("2_3d1qx")
|
||||
metadata/_custom_type_script = "uid://elqkwjm0r5c7"
|
||||
|
||||
[node name="Spinner" type="Range" parent="MarginContainer/VBoxContainer/SubmitButton"]
|
||||
_import_path = NodePath("")
|
||||
unique_name_in_owner = true
|
||||
process_mode = 0
|
||||
process_priority = 0
|
||||
process_physics_priority = 0
|
||||
process_thread_group = 0
|
||||
physics_interpolation_mode = 2
|
||||
auto_translate_mode = 0
|
||||
editor_description = ""
|
||||
visible = false
|
||||
modulate = Color(1, 1, 1, 1)
|
||||
self_modulate = Color(1, 1, 1, 1)
|
||||
show_behind_parent = false
|
||||
top_level = false
|
||||
clip_children = 0
|
||||
light_mask = 1
|
||||
visibility_layer = 1
|
||||
z_index = 0
|
||||
z_as_relative = true
|
||||
y_sort_enabled = false
|
||||
texture_filter = 0
|
||||
texture_repeat = 0
|
||||
material = null
|
||||
use_parent_material = false
|
||||
clip_contents = true
|
||||
custom_minimum_size = Vector2(16, 16)
|
||||
layout_direction = 0
|
||||
layout_mode = 1
|
||||
anchors_preset = 4
|
||||
anchor_left = 0.0
|
||||
anchor_top = 0.5
|
||||
anchor_right = 0.0
|
||||
anchor_bottom = 0.5
|
||||
offset_left = 20.0
|
||||
offset_top = -20.0
|
||||
offset_right = 60.0
|
||||
offset_bottom = 20.0
|
||||
grow_horizontal = 1
|
||||
grow_vertical = 2
|
||||
rotation = 0.0
|
||||
scale = Vector2(1, 1)
|
||||
pivot_offset = Vector2(0, 0)
|
||||
size_flags_horizontal = 1
|
||||
size_flags_vertical = 1
|
||||
size_flags_stretch_ratio = 1.0
|
||||
localize_numeral_system = true
|
||||
tooltip_text = ""
|
||||
tooltip_auto_translate_mode = 0
|
||||
focus_neighbor_left = NodePath("")
|
||||
focus_neighbor_top = NodePath("")
|
||||
focus_neighbor_right = NodePath("")
|
||||
focus_neighbor_bottom = NodePath("")
|
||||
focus_next = NodePath("")
|
||||
focus_previous = NodePath("")
|
||||
focus_mode = 0
|
||||
focus_behavior_recursive = 0
|
||||
mouse_filter = 0
|
||||
mouse_behavior_recursive = 0
|
||||
mouse_force_pass_scroll_events = true
|
||||
mouse_default_cursor_shape = 0
|
||||
accessibility_name = ""
|
||||
accessibility_description = ""
|
||||
accessibility_live = 0
|
||||
accessibility_controls_nodes = Array[NodePath]([])
|
||||
accessibility_described_by_nodes = Array[NodePath]([])
|
||||
accessibility_labeled_by_nodes = Array[NodePath]([])
|
||||
accessibility_flow_to_nodes = Array[NodePath]([])
|
||||
theme = null
|
||||
theme_type_variation = &""
|
||||
min_value = 0.0
|
||||
max_value = 100.0
|
||||
step = 1.0
|
||||
value = 0.0
|
||||
exp_edit = false
|
||||
rounded = false
|
||||
allow_greater = false
|
||||
allow_lesser = false
|
||||
script = ExtResource("3_co5jd")
|
||||
color_progress = Color(0.98, 0.98, 0.98, 1)
|
||||
color_background = Color(0, 0, 0, 0)
|
||||
metadata/_custom_type_script = "uid://doqt8bqgwakt"
|
||||
|
||||
[connection signal="button_up" from="MarginContainer/VBoxContainer/SubmitButton" to="." method="_on_submit_button_up"]
|
||||
@@ -1,10 +0,0 @@
|
||||
extends Button
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
pass # Replace with function body.
|
||||
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
#func _process(delta):
|
||||
# pass
|
||||
@@ -0,0 +1,22 @@
|
||||
extends TextureButton
|
||||
|
||||
@export var music_enabled_texture: Texture2D
|
||||
@export var music_enabled_hover_texture: Texture2D
|
||||
|
||||
@export var music_disabled_texture: Texture2D
|
||||
@export var music_disabled_hover_texture: Texture2D
|
||||
|
||||
func _ready():
|
||||
gymkhana.music_manager.toggled.connect(_music_toggled)
|
||||
set_texture(gymkhana.music_manager.music_enabled)
|
||||
|
||||
func _music_toggled(current_value: bool) -> void:
|
||||
set_texture(current_value)
|
||||
|
||||
func set_texture(current_value: bool) -> void:
|
||||
if current_value:
|
||||
texture_normal = music_enabled_texture
|
||||
texture_hover = music_enabled_hover_texture
|
||||
else:
|
||||
texture_normal = music_disabled_texture
|
||||
texture_hover = music_disabled_hover_texture
|
||||
@@ -0,0 +1 @@
|
||||
uid://chas0xyx88njl
|
||||
100
addons/escoria-ui-return-monkey-island/cursors/arrow.svg
Normal file
@@ -0,0 +1,100 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
width="128"
|
||||
height="128"
|
||||
viewBox="0 0 128 128"
|
||||
fill="none"
|
||||
version="1.1"
|
||||
id="svg5"
|
||||
sodipodi:docname="arrow.svg"
|
||||
inkscape:version="1.3.2 (1:1.3.2+202311252150+091e20ef0f)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview5"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:zoom="11.294988"
|
||||
inkscape:cx="17.397098"
|
||||
inkscape:cy="20.053143"
|
||||
inkscape:window-width="1680"
|
||||
inkscape:window-height="941"
|
||||
inkscape:window-x="1920"
|
||||
inkscape:window-y="15"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="g5" />
|
||||
<g
|
||||
id="g5"
|
||||
transform="matrix(0.28239848,0,0,0.28239848,1.1963533e-7,0.36640485)">
|
||||
<g
|
||||
filter="url(#filter0_d_18_113)"
|
||||
id="g2"
|
||||
transform="matrix(0.41664582,0,0,0.41664582,-24.496608,-11.993109)">
|
||||
<path
|
||||
d="M 74.3177,39.3652 74.1548,178.66 c -0.0025,2.106 1.6813,3.832 3.7847,3.941 8.8629,0.457 31.2815,2.402 45.6585,10.577 10.789,6.135 11.755,13.002 23.111,7.993 11.356,-5.009 6.351,-10.094 9.095,-22.199 3.651,-16.107 16.936,-33.789 22.433,-40.594 1.316,-1.629 1.168,-4.019 -0.38,-5.428 L 74.8532,39.129 c -0.2054,-0.1871 -0.5352,-0.0416 -0.5355,0.2362 z"
|
||||
fill="#0000ff"
|
||||
id="path1" />
|
||||
<path
|
||||
d="m 69.1977,39.3592 v 0 L 69.0348,178.654 c -0.0058,4.913 3.8938,8.815 8.6409,9.06 4.3013,0.222 11.8834,0.806 20.099,2.317 8.2933,1.525 16.8373,3.927 23.2923,7.598 2.359,1.341 4.203,2.732 5.898,4.089 0.286,0.228 0.582,0.469 0.887,0.716 1.359,1.103 2.885,2.342 4.4,3.277 2.065,1.274 4.475,2.249 7.475,2.306 2.874,0.054 5.834,-0.744 9.048,-2.162 3.204,-1.413 5.788,-3.056 7.653,-5.238 1.961,-2.296 2.767,-4.765 3.121,-7.126 0.239,-1.591 0.294,-3.427 0.342,-5.048 0.014,-0.486 0.028,-0.952 0.047,-1.387 0.087,-2.097 0.268,-4.345 0.859,-6.952 1.645,-7.256 5.548,-15.147 9.896,-22.242 4.31,-7.032 8.861,-12.966 11.527,-16.267 l -3.499,-2.826 3.499,2.826 c 2.966,-3.672 2.697,-9.141 -0.915,-12.43 L 78.3009,35.3438 v 0 c -3.491,-3.1798 -9.0976,-0.7068 -9.1032,4.0154 z"
|
||||
stroke="#0000ff"
|
||||
stroke-width="10.24"
|
||||
id="path2"
|
||||
style="fill:#f2f2f2;stroke:#ffffff;stroke-opacity:1" />
|
||||
</g>
|
||||
<path
|
||||
d="m 6.4680104,4.1068365 -0.06883,58.8658875 c -7.09e-4,0.584971 0.46281,1.064114 1.047281,1.089112 3.2398786,0.13791 13.2513366,0.848291 19.5535216,4.431862 4.495191,2.556122 4.897671,5.417231 9.629101,3.330251 4.731426,-2.087396 2.646118,-4.20604 3.789394,-9.249121 1.601172,-7.063397 7.648372,-14.853007 9.679512,-17.322051 0.36957,-0.448727 0.32582,-1.108694 -0.10416,-1.500341 z"
|
||||
fill="#00ff00"
|
||||
id="path3"
|
||||
style="stroke-width:0.416646;fill:#666666" />
|
||||
</g>
|
||||
<defs
|
||||
id="defs5">
|
||||
<filter
|
||||
id="filter0_d_18_113"
|
||||
x="58.7948"
|
||||
y="28.784901"
|
||||
width="135.694"
|
||||
height="197.15401"
|
||||
filterUnits="userSpaceOnUse"
|
||||
color-interpolation-filters="sRGB">
|
||||
<feFlood
|
||||
flood-opacity="0"
|
||||
result="BackgroundImageFix"
|
||||
id="feFlood3" />
|
||||
<feColorMatrix
|
||||
in="SourceAlpha"
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
|
||||
result="hardAlpha"
|
||||
id="feColorMatrix3" />
|
||||
<feOffset
|
||||
dy="7.68"
|
||||
id="feOffset3" />
|
||||
<feGaussianBlur
|
||||
stdDeviation="2.56"
|
||||
id="feGaussianBlur3" />
|
||||
<feColorMatrix
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"
|
||||
id="feColorMatrix4" />
|
||||
<feBlend
|
||||
mode="normal"
|
||||
in2="BackgroundImageFix"
|
||||
result="effect1_dropShadow_18_113"
|
||||
id="feBlend4" />
|
||||
<feBlend
|
||||
mode="normal"
|
||||
in="SourceGraphic"
|
||||
in2="effect1_dropShadow_18_113"
|
||||
result="shape"
|
||||
id="feBlend5" />
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.1 KiB |
79
addons/escoria-ui-return-monkey-island/cursors/blank.svg
Normal file
@@ -0,0 +1,79 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
width="128"
|
||||
height="128"
|
||||
viewBox="0 0 128 128"
|
||||
fill="none"
|
||||
version="1.1"
|
||||
id="svg5"
|
||||
sodipodi:docname="blank.svg"
|
||||
inkscape:version="1.3.2 (1:1.3.2+202311252150+091e20ef0f)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview5"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:zoom="11.294988"
|
||||
inkscape:cx="17.485632"
|
||||
inkscape:cy="20.141677"
|
||||
inkscape:window-width="1680"
|
||||
inkscape:window-height="941"
|
||||
inkscape:window-x="1920"
|
||||
inkscape:window-y="15"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="g5" />
|
||||
<g
|
||||
id="g5"
|
||||
transform="matrix(0.28239848,0,0,0.28239848,1.1963533e-7,0.36640485)" />
|
||||
<defs
|
||||
id="defs5">
|
||||
<filter
|
||||
id="filter0_d_18_113"
|
||||
x="58.7948"
|
||||
y="28.784901"
|
||||
width="135.694"
|
||||
height="197.15401"
|
||||
filterUnits="userSpaceOnUse"
|
||||
color-interpolation-filters="sRGB">
|
||||
<feFlood
|
||||
flood-opacity="0"
|
||||
result="BackgroundImageFix"
|
||||
id="feFlood3" />
|
||||
<feColorMatrix
|
||||
in="SourceAlpha"
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
|
||||
result="hardAlpha"
|
||||
id="feColorMatrix3" />
|
||||
<feOffset
|
||||
dy="7.68"
|
||||
id="feOffset3" />
|
||||
<feGaussianBlur
|
||||
stdDeviation="2.56"
|
||||
id="feGaussianBlur3" />
|
||||
<feColorMatrix
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"
|
||||
id="feColorMatrix4" />
|
||||
<feBlend
|
||||
mode="normal"
|
||||
in2="BackgroundImageFix"
|
||||
result="effect1_dropShadow_18_113"
|
||||
id="feBlend4" />
|
||||
<feBlend
|
||||
mode="normal"
|
||||
in="SourceGraphic"
|
||||
in2="effect1_dropShadow_18_113"
|
||||
result="shape"
|
||||
id="feBlend5" />
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.2 KiB |
81
addons/escoria-ui-return-monkey-island/cursors/east.svg
Normal file
@@ -0,0 +1,81 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
width="128"
|
||||
height="128"
|
||||
viewBox="0 0 128 128"
|
||||
fill="none"
|
||||
version="1.1"
|
||||
id="svg5"
|
||||
sodipodi:docname="east.svg"
|
||||
inkscape:version="1.3.2 (1:1.3.2+202311252150+091e20ef0f)"
|
||||
xml:space="preserve"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
|
||||
id="namedview5"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:zoom="3.9933811"
|
||||
inkscape:cx="57.219683"
|
||||
inkscape:cy="60.224655"
|
||||
inkscape:window-width="1680"
|
||||
inkscape:window-height="941"
|
||||
inkscape:window-x="1920"
|
||||
inkscape:window-y="15"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="g5" /><g
|
||||
id="g5"
|
||||
transform="matrix(0.28239848,0,0,0.28239848,1.1963533e-7,0.36640485)"><g
|
||||
style="fill:none"
|
||||
id="g1"
|
||||
transform="matrix(-0.82301095,0,0,-0.82301095,182.41215,136.85333)"><path
|
||||
d="m 42.8435,124.893 c -1.433,0.787 -2.3236,2.292 -2.3236,3.927 0,1.635 0.8906,3.14 2.3236,3.927 l 54.7779,30.08 c 0.627191,0.34422 1.302043,0.52288 1.973343,0.54975 1.581207,0.0633 3.142697,-0.71559 4.015257,-2.15675 l -3.8322,-2.32 c 3.8322,2.32 3.8332,2.319 3.8332,2.319 l 10e-4,-0.002 0.002,-0.003 0.006,-0.01 0.018,-0.03 0.063,-0.106 c 0.054,-0.091 0.131,-0.221 0.228,-0.387 0.194,-0.333 0.469,-0.812 0.807,-1.418 0.675,-1.21 1.601,-2.93 2.619,-4.992 1.631,-3.303 3.548,-7.578 5.037,-12.096 0.307,-0.002 0.635,-0.003 0.982,-0.004 2.728,-0.008 6.629,-0.009 11.318,-0.006 9.291,0.006 21.656,0.029 34.074,0.052 l 0.342,10e-4 c 12.53,0.023 25.088,0.047 34.56,0.052 4.735,0.003 8.704,0.002 11.516,-0.007 1.404,-0.004 2.528,-0.009 3.317,-0.017 0.392,-0.004 0.717,-0.009 0.958,-0.014 0.117,-0.003 0.238,-0.006 0.347,-0.011 0.051,-0.002 0.131,-0.006 0.22,-0.013 0.028,-0.003 0.07,-0.006 0.12,-0.011 0.021,-0.002 0.041,-0.004 0.062,-0.006 0.185,-0.019 0.387,-0.051 0.605,-0.099 0.437,-0.097 0.923,-0.262 1.427,-0.523 1.038,-0.539 1.973,-1.395 2.726,-2.567 1.424,-2.219 2.194,-5.552 2.194,-10.51 0,-4.959 -0.77,-8.292 -2.194,-10.511 -0.753,-1.172 -1.688,-2.028 -2.726,-2.566 -0.504,-0.262 -0.99,-0.427 -1.427,-0.524 -0.218,-0.048 -0.42,-0.08 -0.605,-0.099 -0.015,-0.001 -0.031,-0.003 -0.046,-0.004 -0.047,-0.005 -0.087,-0.009 -0.115,-0.011 -0.092,-0.008 -0.175,-0.012 -0.229,-0.015 -0.114,-0.006 -0.239,-0.009 -0.359,-0.012 -0.247,-0.007 -0.577,-0.012 -0.973,-0.016 -0.797,-0.009 -1.929,-0.015 -3.339,-0.02 -2.825,-0.009 -6.806,-0.01 -11.552,-0.007 -9.476,0.007 -22.022,0.033 -34.545,0.06 h -0.071 c -12.549,0.027 -25.067,0.053 -34.452,0.059 -4.694,0.004 -8.597,0.002 -11.327,-0.007 -0.364,-0.002 -0.706,-0.003 -1.025,-0.004 -1.494,-4.388 -3.363,-8.515 -4.946,-11.701 -0.989,-1.991 -1.884,-3.6474 -2.534,-4.8119 -0.326,-0.5829 -0.591,-1.044 -0.778,-1.3639 -0.093,-0.16 -0.167,-0.2848 -0.219,-0.372 l -0.061,-0.1022 -0.018,-0.0294 -0.005,-0.0092 -0.002,-0.0032 -10e-4,-0.0013 c 0,-5e-4 -0.001,-0.001 -3.8332,2.3188 l 3.8322,-2.3198 c -1.243,-2.0539 -3.8841,-2.7627 -5.9886,-1.607 z"
|
||||
stroke="#0000ff"
|
||||
stroke-width="8.96"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
id="path1-3"
|
||||
sodipodi:nodetypes="csccscccccccccccccsccccsccccccccscccccccccccccccccccsccccccccc"
|
||||
style="stroke:#f2f2f2;stroke-opacity:1" /><path
|
||||
d="M 44.9999,128.82 99.7778,98.7397 c 0,0 6.1412,10.1473 9.0922,20.5063 0.06,0.213 99.974,-0.211 100.842,0 0,0 2.968,0 2.968,9.246 0,9.245 -2.968,9.245 -2.968,9.245 -0.76,0.188 -100.609,-0.186 -100.66,0 -2.87,10.583 -9.2742,21.163 -9.2742,21.163 z"
|
||||
fill="#00ff00"
|
||||
id="path2-6"
|
||||
style="fill:#666666;fill-opacity:1" /></g></g><defs
|
||||
id="defs5"><filter
|
||||
id="filter0_d_18_113"
|
||||
x="58.7948"
|
||||
y="28.784901"
|
||||
width="135.694"
|
||||
height="197.15401"
|
||||
filterUnits="userSpaceOnUse"
|
||||
color-interpolation-filters="sRGB"><feFlood
|
||||
flood-opacity="0"
|
||||
result="BackgroundImageFix"
|
||||
id="feFlood3" /><feColorMatrix
|
||||
in="SourceAlpha"
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
|
||||
result="hardAlpha"
|
||||
id="feColorMatrix3" /><feOffset
|
||||
dy="7.68"
|
||||
id="feOffset3" /><feGaussianBlur
|
||||
stdDeviation="2.56"
|
||||
id="feGaussianBlur3" /><feColorMatrix
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"
|
||||
id="feColorMatrix4" /><feBlend
|
||||
mode="normal"
|
||||
in2="BackgroundImageFix"
|
||||
result="effect1_dropShadow_18_113"
|
||||
id="feBlend4" /><feBlend
|
||||
mode="normal"
|
||||
in="SourceGraphic"
|
||||
in2="effect1_dropShadow_18_113"
|
||||
result="shape"
|
||||
id="feBlend5" /></filter></defs></svg>
|
||||
|
After Width: | Height: | Size: 4.9 KiB |
110
addons/escoria-ui-return-monkey-island/cursors/hand.svg
Normal file
@@ -0,0 +1,110 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
width="128"
|
||||
height="128"
|
||||
viewBox="0 0 128 128"
|
||||
fill="none"
|
||||
version="1.1"
|
||||
id="svg5"
|
||||
sodipodi:docname="hand.svg"
|
||||
inkscape:version="1.3.2 (1:1.3.2+202311252150+091e20ef0f)"
|
||||
xml:space="preserve"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
|
||||
id="namedview5"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:zoom="11.294988"
|
||||
inkscape:cx="17.397098"
|
||||
inkscape:cy="20.053143"
|
||||
inkscape:window-width="1680"
|
||||
inkscape:window-height="941"
|
||||
inkscape:window-x="1920"
|
||||
inkscape:window-y="15"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="g5" /><g
|
||||
id="g5"
|
||||
transform="matrix(0.28239848,0,0,0.28239848,1.1963533e-7,0.36640485)"><g
|
||||
style="fill:none"
|
||||
id="g3"
|
||||
transform="matrix(0.38020692,0,0,0.38020692,-9.40517,-10.599142)"><g
|
||||
filter="url(#filter0_d_21_2)"
|
||||
id="g1"><path
|
||||
d="m 117.348,35.02 c -6.215,0 -12.306,3.0662 -16.178,8.2326 -3.8717,5.1664 -5.7582,12.2574 -5.7582,20.307 V 125.03 c -4.8514,-3.593 -10.5586,-9.073 -14.807,-10.977 -8.5854,-3.847 -16.4297,-4.602 -22.759,-2.744 -12.6585,3.715 -16.7264,15.916 -16.7264,15.916 l -1.9194,6.312 5.484,3.841 c 12.0713,8.157 24.3061,28.164 35.9208,46.652 5.8073,9.243 11.5325,17.911 18.0975,24.972 6.5647,7.06 14.6697,12.962 24.6787,12.898 l 77.325,-0.274 7.952,-0.274 0.822,-7.684 8.775,-87.814 c 1.302,-12.594 -6.33,-23.323 -16.178,-26.6188 -4.753,-1.5907 -10.207,-0.7745 -15.081,1.3718 -3.201,-4.9067 -7.388,-8.6174 -12.614,-9.8788 -4.451,-1.0743 -9.19,-0.1265 -13.436,1.6465 -3.049,-4.3574 -7.035,-7.5296 -11.791,-9.0558 -3.062,-0.9828 -6.554,-0.2214 -9.871,0.2739 V 63.5602 c 0,-8.0497 -1.886,-15.1407 -5.758,-20.3071 -3.872,-5.1663 -9.963,-8.2325 -16.178,-8.2325 z"
|
||||
fill="#0000ff"
|
||||
id="path1-3"
|
||||
style="fill:#ffffff;fill-opacity:1" /></g><path
|
||||
d="m 123.063,212.94 77.496,-0.503 8.772,-88.175 c 1.84,-17.873 -20.2,-25.3098 -26.318,-8.818 0.079,-19.819 -20.208,-22.2988 -26.318,-8.817 0.765,-16.375 -19.934,-22.7127 -26.318,-8.818 V 62.5394 c 0,-26.4526 -26.318,-26.4526 -26.318,0 V 141.897 C 60.195,97.8095 49.4399,129.489 49.4399,129.489 c 29.8072,20.228 48.039,83.617 73.6231,83.451 z"
|
||||
fill="#00ff00"
|
||||
id="path2-6"
|
||||
style="fill:#666666;fill-opacity:1" /></g></g><defs
|
||||
id="defs5"><filter
|
||||
id="filter0_d_18_113"
|
||||
x="58.7948"
|
||||
y="28.784901"
|
||||
width="135.694"
|
||||
height="197.15401"
|
||||
filterUnits="userSpaceOnUse"
|
||||
color-interpolation-filters="sRGB"><feFlood
|
||||
flood-opacity="0"
|
||||
result="BackgroundImageFix"
|
||||
id="feFlood3" /><feColorMatrix
|
||||
in="SourceAlpha"
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
|
||||
result="hardAlpha"
|
||||
id="feColorMatrix3" /><feOffset
|
||||
dy="7.68"
|
||||
id="feOffset3" /><feGaussianBlur
|
||||
stdDeviation="2.56"
|
||||
id="feGaussianBlur3" /><feColorMatrix
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"
|
||||
id="feColorMatrix4" /><feBlend
|
||||
mode="normal"
|
||||
in2="BackgroundImageFix"
|
||||
result="effect1_dropShadow_18_113"
|
||||
id="feBlend4" /><feBlend
|
||||
mode="normal"
|
||||
in="SourceGraphic"
|
||||
in2="effect1_dropShadow_18_113"
|
||||
result="shape"
|
||||
id="feBlend5" /></filter><filter
|
||||
id="filter0_d_21_2"
|
||||
x="34.08"
|
||||
y="35.02"
|
||||
width="189.44"
|
||||
height="199.68"
|
||||
filterUnits="userSpaceOnUse"
|
||||
color-interpolation-filters="sRGB"><feFlood
|
||||
flood-opacity="0"
|
||||
result="BackgroundImageFix"
|
||||
id="feFlood2" /><feColorMatrix
|
||||
in="SourceAlpha"
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
|
||||
result="hardAlpha"
|
||||
id="feColorMatrix2" /><feOffset
|
||||
dy="7.68"
|
||||
id="feOffset2" /><feGaussianBlur
|
||||
stdDeviation="2.56"
|
||||
id="feGaussianBlur2" /><feColorMatrix
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"
|
||||
id="feColorMatrix3-7" /><feBlend
|
||||
mode="normal"
|
||||
in2="BackgroundImageFix"
|
||||
result="effect1_dropShadow_21_2"
|
||||
id="feBlend3" /><feBlend
|
||||
mode="normal"
|
||||
in="SourceGraphic"
|
||||
in2="effect1_dropShadow_21_2"
|
||||
result="shape"
|
||||
id="feBlend4-5" /></filter></defs></svg>
|
||||
|
After Width: | Height: | Size: 4.7 KiB |
|
Before Width: | Height: | Size: 144 B |
|
Before Width: | Height: | Size: 145 B |
81
addons/escoria-ui-return-monkey-island/cursors/north.svg
Normal file
@@ -0,0 +1,81 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
width="128"
|
||||
height="128"
|
||||
viewBox="0 0 128 128"
|
||||
fill="none"
|
||||
version="1.1"
|
||||
id="svg5"
|
||||
sodipodi:docname="north.svg"
|
||||
inkscape:version="1.3.2 (1:1.3.2+202311252150+091e20ef0f)"
|
||||
xml:space="preserve"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
|
||||
id="namedview5"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:zoom="3.9933811"
|
||||
inkscape:cx="57.720512"
|
||||
inkscape:cy="68.989158"
|
||||
inkscape:window-width="1680"
|
||||
inkscape:window-height="941"
|
||||
inkscape:window-x="1920"
|
||||
inkscape:window-y="15"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="g5" /><g
|
||||
id="g5"
|
||||
transform="matrix(0.28239848,0,0,0.28239848,1.1963533e-7,0.36640485)"><g
|
||||
style="fill:none"
|
||||
id="g1"
|
||||
transform="matrix(0,0.82301095,-0.82301095,0,138.15081,-30.958707)"><path
|
||||
d="m 42.8435,124.893 c -1.433,0.787 -2.3236,2.292 -2.3236,3.927 0,1.635 0.8906,3.14 2.3236,3.927 l 54.7779,30.08 c 0.627191,0.34422 1.302043,0.52288 1.973343,0.54975 1.581207,0.0633 3.142697,-0.71559 4.015257,-2.15675 l -3.8322,-2.32 c 3.8322,2.32 3.8332,2.319 3.8332,2.319 l 10e-4,-0.002 0.002,-0.003 0.006,-0.01 0.018,-0.03 0.063,-0.106 c 0.054,-0.091 0.131,-0.221 0.228,-0.387 0.194,-0.333 0.469,-0.812 0.807,-1.418 0.675,-1.21 1.601,-2.93 2.619,-4.992 1.631,-3.303 3.548,-7.578 5.037,-12.096 0.307,-0.002 0.635,-0.003 0.982,-0.004 2.728,-0.008 6.629,-0.009 11.318,-0.006 9.291,0.006 21.656,0.029 34.074,0.052 l 0.342,10e-4 c 12.53,0.023 25.088,0.047 34.56,0.052 4.735,0.003 8.704,0.002 11.516,-0.007 1.404,-0.004 2.528,-0.009 3.317,-0.017 0.392,-0.004 0.717,-0.009 0.958,-0.014 0.117,-0.003 0.238,-0.006 0.347,-0.011 0.051,-0.002 0.131,-0.006 0.22,-0.013 0.028,-0.003 0.07,-0.006 0.12,-0.011 0.021,-0.002 0.041,-0.004 0.062,-0.006 0.185,-0.019 0.387,-0.051 0.605,-0.099 0.437,-0.097 0.923,-0.262 1.427,-0.523 1.038,-0.539 1.973,-1.395 2.726,-2.567 1.424,-2.219 2.194,-5.552 2.194,-10.51 0,-4.959 -0.77,-8.292 -2.194,-10.511 -0.753,-1.172 -1.688,-2.028 -2.726,-2.566 -0.504,-0.262 -0.99,-0.427 -1.427,-0.524 -0.218,-0.048 -0.42,-0.08 -0.605,-0.099 -0.015,-0.001 -0.031,-0.003 -0.046,-0.004 -0.047,-0.005 -0.087,-0.009 -0.115,-0.011 -0.092,-0.008 -0.175,-0.012 -0.229,-0.015 -0.114,-0.006 -0.239,-0.009 -0.359,-0.012 -0.247,-0.007 -0.577,-0.012 -0.973,-0.016 -0.797,-0.009 -1.929,-0.015 -3.339,-0.02 -2.825,-0.009 -6.806,-0.01 -11.552,-0.007 -9.476,0.007 -22.022,0.033 -34.545,0.06 h -0.071 c -12.549,0.027 -25.067,0.053 -34.452,0.059 -4.694,0.004 -8.597,0.002 -11.327,-0.007 -0.364,-0.002 -0.706,-0.003 -1.025,-0.004 -1.494,-4.388 -3.363,-8.515 -4.946,-11.701 -0.989,-1.991 -1.884,-3.6474 -2.534,-4.8119 -0.326,-0.5829 -0.591,-1.044 -0.778,-1.3639 -0.093,-0.16 -0.167,-0.2848 -0.219,-0.372 l -0.061,-0.1022 -0.018,-0.0294 -0.005,-0.0092 -0.002,-0.0032 -10e-4,-0.0013 c 0,-5e-4 -0.001,-0.001 -3.8332,2.3188 l 3.8322,-2.3198 c -1.243,-2.0539 -3.8841,-2.7627 -5.9886,-1.607 z"
|
||||
stroke="#0000ff"
|
||||
stroke-width="8.96"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
id="path1-3"
|
||||
sodipodi:nodetypes="csccscccccccccccccsccccsccccccccscccccccccccccccccccsccccccccc"
|
||||
style="stroke:#f2f2f2;stroke-opacity:1" /><path
|
||||
d="M 44.9999,128.82 99.7778,98.7397 c 0,0 6.1412,10.1473 9.0922,20.5063 0.06,0.213 99.974,-0.211 100.842,0 0,0 2.968,0 2.968,9.246 0,9.245 -2.968,9.245 -2.968,9.245 -0.76,0.188 -100.609,-0.186 -100.66,0 -2.87,10.583 -9.2742,21.163 -9.2742,21.163 z"
|
||||
fill="#00ff00"
|
||||
id="path2-6"
|
||||
style="fill:#666666;fill-opacity:1" /></g></g><defs
|
||||
id="defs5"><filter
|
||||
id="filter0_d_18_113"
|
||||
x="58.7948"
|
||||
y="28.784901"
|
||||
width="135.694"
|
||||
height="197.15401"
|
||||
filterUnits="userSpaceOnUse"
|
||||
color-interpolation-filters="sRGB"><feFlood
|
||||
flood-opacity="0"
|
||||
result="BackgroundImageFix"
|
||||
id="feFlood3" /><feColorMatrix
|
||||
in="SourceAlpha"
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
|
||||
result="hardAlpha"
|
||||
id="feColorMatrix3" /><feOffset
|
||||
dy="7.68"
|
||||
id="feOffset3" /><feGaussianBlur
|
||||
stdDeviation="2.56"
|
||||
id="feGaussianBlur3" /><feColorMatrix
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"
|
||||
id="feColorMatrix4" /><feBlend
|
||||
mode="normal"
|
||||
in2="BackgroundImageFix"
|
||||
result="effect1_dropShadow_18_113"
|
||||
id="feBlend4" /><feBlend
|
||||
mode="normal"
|
||||
in="SourceGraphic"
|
||||
in2="effect1_dropShadow_18_113"
|
||||
result="shape"
|
||||
id="feBlend5" /></filter></defs></svg>
|
||||
|
After Width: | Height: | Size: 4.9 KiB |
81
addons/escoria-ui-return-monkey-island/cursors/south.svg
Normal file
@@ -0,0 +1,81 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
width="128"
|
||||
height="128"
|
||||
viewBox="0 0 128 128"
|
||||
fill="none"
|
||||
version="1.1"
|
||||
id="svg5"
|
||||
sodipodi:docname="south.svg"
|
||||
inkscape:version="1.3.2 (1:1.3.2+202311252150+091e20ef0f)"
|
||||
xml:space="preserve"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
|
||||
id="namedview5"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:zoom="3.9933811"
|
||||
inkscape:cx="57.219683"
|
||||
inkscape:cy="60.224655"
|
||||
inkscape:window-width="1680"
|
||||
inkscape:window-height="941"
|
||||
inkscape:window-x="1920"
|
||||
inkscape:window-y="15"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="g5" /><g
|
||||
id="g5"
|
||||
transform="matrix(0.28239848,0,0,0.28239848,1.1963533e-7,0.36640485)"><g
|
||||
style="fill:none"
|
||||
id="g1"
|
||||
transform="matrix(0,-0.82301095,0.82301095,0,-73.90381,181.97657)"><path
|
||||
d="m 42.8435,124.893 c -1.433,0.787 -2.3236,2.292 -2.3236,3.927 0,1.635 0.8906,3.14 2.3236,3.927 l 54.7779,30.08 c 0.627191,0.34422 1.302043,0.52288 1.973343,0.54975 1.581207,0.0633 3.142697,-0.71559 4.015257,-2.15675 l -3.8322,-2.32 c 3.8322,2.32 3.8332,2.319 3.8332,2.319 l 10e-4,-0.002 0.002,-0.003 0.006,-0.01 0.018,-0.03 0.063,-0.106 c 0.054,-0.091 0.131,-0.221 0.228,-0.387 0.194,-0.333 0.469,-0.812 0.807,-1.418 0.675,-1.21 1.601,-2.93 2.619,-4.992 1.631,-3.303 3.548,-7.578 5.037,-12.096 0.307,-0.002 0.635,-0.003 0.982,-0.004 2.728,-0.008 6.629,-0.009 11.318,-0.006 9.291,0.006 21.656,0.029 34.074,0.052 l 0.342,10e-4 c 12.53,0.023 25.088,0.047 34.56,0.052 4.735,0.003 8.704,0.002 11.516,-0.007 1.404,-0.004 2.528,-0.009 3.317,-0.017 0.392,-0.004 0.717,-0.009 0.958,-0.014 0.117,-0.003 0.238,-0.006 0.347,-0.011 0.051,-0.002 0.131,-0.006 0.22,-0.013 0.028,-0.003 0.07,-0.006 0.12,-0.011 0.021,-0.002 0.041,-0.004 0.062,-0.006 0.185,-0.019 0.387,-0.051 0.605,-0.099 0.437,-0.097 0.923,-0.262 1.427,-0.523 1.038,-0.539 1.973,-1.395 2.726,-2.567 1.424,-2.219 2.194,-5.552 2.194,-10.51 0,-4.959 -0.77,-8.292 -2.194,-10.511 -0.753,-1.172 -1.688,-2.028 -2.726,-2.566 -0.504,-0.262 -0.99,-0.427 -1.427,-0.524 -0.218,-0.048 -0.42,-0.08 -0.605,-0.099 -0.015,-0.001 -0.031,-0.003 -0.046,-0.004 -0.047,-0.005 -0.087,-0.009 -0.115,-0.011 -0.092,-0.008 -0.175,-0.012 -0.229,-0.015 -0.114,-0.006 -0.239,-0.009 -0.359,-0.012 -0.247,-0.007 -0.577,-0.012 -0.973,-0.016 -0.797,-0.009 -1.929,-0.015 -3.339,-0.02 -2.825,-0.009 -6.806,-0.01 -11.552,-0.007 -9.476,0.007 -22.022,0.033 -34.545,0.06 h -0.071 c -12.549,0.027 -25.067,0.053 -34.452,0.059 -4.694,0.004 -8.597,0.002 -11.327,-0.007 -0.364,-0.002 -0.706,-0.003 -1.025,-0.004 -1.494,-4.388 -3.363,-8.515 -4.946,-11.701 -0.989,-1.991 -1.884,-3.6474 -2.534,-4.8119 -0.326,-0.5829 -0.591,-1.044 -0.778,-1.3639 -0.093,-0.16 -0.167,-0.2848 -0.219,-0.372 l -0.061,-0.1022 -0.018,-0.0294 -0.005,-0.0092 -0.002,-0.0032 -10e-4,-0.0013 c 0,-5e-4 -0.001,-0.001 -3.8332,2.3188 l 3.8322,-2.3198 c -1.243,-2.0539 -3.8841,-2.7627 -5.9886,-1.607 z"
|
||||
stroke="#0000ff"
|
||||
stroke-width="8.96"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
id="path1-3"
|
||||
sodipodi:nodetypes="csccscccccccccccccsccccsccccccccscccccccccccccccccccsccccccccc"
|
||||
style="stroke:#f2f2f2;stroke-opacity:1" /><path
|
||||
d="M 44.9999,128.82 99.7778,98.7397 c 0,0 6.1412,10.1473 9.0922,20.5063 0.06,0.213 99.974,-0.211 100.842,0 0,0 2.968,0 2.968,9.246 0,9.245 -2.968,9.245 -2.968,9.245 -0.76,0.188 -100.609,-0.186 -100.66,0 -2.87,10.583 -9.2742,21.163 -9.2742,21.163 z"
|
||||
fill="#00ff00"
|
||||
id="path2-6"
|
||||
style="fill:#666666;fill-opacity:1" /></g></g><defs
|
||||
id="defs5"><filter
|
||||
id="filter0_d_18_113"
|
||||
x="58.7948"
|
||||
y="28.784901"
|
||||
width="135.694"
|
||||
height="197.15401"
|
||||
filterUnits="userSpaceOnUse"
|
||||
color-interpolation-filters="sRGB"><feFlood
|
||||
flood-opacity="0"
|
||||
result="BackgroundImageFix"
|
||||
id="feFlood3" /><feColorMatrix
|
||||
in="SourceAlpha"
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
|
||||
result="hardAlpha"
|
||||
id="feColorMatrix3" /><feOffset
|
||||
dy="7.68"
|
||||
id="feOffset3" /><feGaussianBlur
|
||||
stdDeviation="2.56"
|
||||
id="feGaussianBlur3" /><feColorMatrix
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"
|
||||
id="feColorMatrix4" /><feBlend
|
||||
mode="normal"
|
||||
in2="BackgroundImageFix"
|
||||
result="effect1_dropShadow_18_113"
|
||||
id="feBlend4" /><feBlend
|
||||
mode="normal"
|
||||
in="SourceGraphic"
|
||||
in2="effect1_dropShadow_18_113"
|
||||
result="shape"
|
||||
id="feBlend5" /></filter></defs></svg>
|
||||
|
After Width: | Height: | Size: 4.9 KiB |
92
addons/escoria-ui-return-monkey-island/cursors/wait.svg
Normal file
@@ -0,0 +1,92 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
width="128"
|
||||
height="128"
|
||||
viewBox="0 0 128 128"
|
||||
fill="none"
|
||||
version="1.1"
|
||||
id="svg5"
|
||||
sodipodi:docname="wait.svg"
|
||||
inkscape:version="1.3.2 (1:1.3.2+202311252150+091e20ef0f)"
|
||||
xml:space="preserve"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
|
||||
id="namedview5"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:zoom="22.589975"
|
||||
inkscape:cx="8.9198859"
|
||||
inkscape:cy="13.435163"
|
||||
inkscape:window-width="1680"
|
||||
inkscape:window-height="941"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="g5" /><g
|
||||
id="g5"
|
||||
transform="matrix(0.28239848,0,0,0.28239848,1.1963533e-7,0.36640485)"><g
|
||||
id="g1"
|
||||
transform="matrix(0.59297639,0,0,0.60377959,-187.61608,-90.048853)"><path
|
||||
d="m 351.44777,217.73491 c 26.5867,0 30.72994,-21.55277 30.72994,-48.1394 h -59.67743 c 0,26.58663 2.36086,48.1394 28.94749,48.1394 z m 0,0 c 26.5867,0 32.15216,21.55269 32.15216,48.13939 h -60.49837 c 0,-26.5867 1.75958,-48.13939 28.34621,-48.13939 z"
|
||||
stroke="#000000"
|
||||
stroke-width="10.3156"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
id="path1"
|
||||
style="fill:#666666;fill-opacity:1;stroke:#f2f2f2;stroke-opacity:1"
|
||||
sodipodi:nodetypes="sccssccs" /><path
|
||||
d="m 324.48025,154.99424 28.56986,-0.59425 h 30.04925"
|
||||
stroke="#000000"
|
||||
stroke-width="10.3156"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
id="path2"
|
||||
style="stroke:#f2f2f2;stroke-opacity:1"
|
||||
sodipodi:nodetypes="ccc" /><path
|
||||
d="m 321.60178,280.75129 29.97802,0.69482 32.82485,0.16418"
|
||||
stroke="#000000"
|
||||
stroke-width="10.3156"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
id="path3"
|
||||
style="stroke:#f2f2f2;stroke-opacity:1"
|
||||
sodipodi:nodetypes="ccc" /></g></g><defs
|
||||
id="defs5"><filter
|
||||
id="filter0_d_18_113"
|
||||
x="58.7948"
|
||||
y="28.784901"
|
||||
width="135.694"
|
||||
height="197.15401"
|
||||
filterUnits="userSpaceOnUse"
|
||||
color-interpolation-filters="sRGB"><feFlood
|
||||
flood-opacity="0"
|
||||
result="BackgroundImageFix"
|
||||
id="feFlood3" /><feColorMatrix
|
||||
in="SourceAlpha"
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
|
||||
result="hardAlpha"
|
||||
id="feColorMatrix3" /><feOffset
|
||||
dy="7.68"
|
||||
id="feOffset3" /><feGaussianBlur
|
||||
stdDeviation="2.56"
|
||||
id="feGaussianBlur3" /><feColorMatrix
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"
|
||||
id="feColorMatrix4" /><feBlend
|
||||
mode="normal"
|
||||
in2="BackgroundImageFix"
|
||||
result="effect1_dropShadow_18_113"
|
||||
id="feBlend4" /><feBlend
|
||||
mode="normal"
|
||||
in="SourceGraphic"
|
||||
in2="effect1_dropShadow_18_113"
|
||||
result="shape"
|
||||
id="feBlend5" /></filter></defs></svg>
|
||||
|
After Width: | Height: | Size: 3.3 KiB |