Initial commit
This commit is contained in:
commit
235f84833f
|
@ -0,0 +1 @@
|
||||||
|
/target
|
|
@ -0,0 +1,45 @@
|
||||||
|
{
|
||||||
|
// Use IntelliSense to learn about possible attributes.
|
||||||
|
// Hover to view descriptions of existing attributes.
|
||||||
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"type": "lldb",
|
||||||
|
"request": "launch",
|
||||||
|
"name": "Debug executable 'metodol_projekt'",
|
||||||
|
"cargo": {
|
||||||
|
"args": [
|
||||||
|
"build",
|
||||||
|
"--bin=metodol_projekt",
|
||||||
|
"--package=metodol_projekt"
|
||||||
|
],
|
||||||
|
"filter": {
|
||||||
|
"name": "metodol_projekt",
|
||||||
|
"kind": "bin"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"args": [],
|
||||||
|
"cwd": "${workspaceFolder}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "lldb",
|
||||||
|
"request": "launch",
|
||||||
|
"name": "Debug unit tests in executable 'metodol_projekt'",
|
||||||
|
"cargo": {
|
||||||
|
"args": [
|
||||||
|
"test",
|
||||||
|
"--no-run",
|
||||||
|
"--bin=metodol_projekt",
|
||||||
|
"--package=metodol_projekt"
|
||||||
|
],
|
||||||
|
"filter": {
|
||||||
|
"name": "metodol_projekt",
|
||||||
|
"kind": "bin"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"args": [],
|
||||||
|
"cwd": "${workspaceFolder}"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,578 @@
|
||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 4
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "android-tzdata"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "android_system_properties"
|
||||||
|
version = "0.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "autocfg"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "2.9.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bumpalo"
|
||||||
|
version = "3.19.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cc"
|
||||||
|
version = "1.2.27"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d487aa071b5f64da6f19a3e848e3578944b726ee5a4854b82172f02aa876bfdc"
|
||||||
|
dependencies = [
|
||||||
|
"shlex",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg-if"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "chrono"
|
||||||
|
version = "0.4.41"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d"
|
||||||
|
dependencies = [
|
||||||
|
"android-tzdata",
|
||||||
|
"iana-time-zone",
|
||||||
|
"js-sys",
|
||||||
|
"num-traits",
|
||||||
|
"wasm-bindgen",
|
||||||
|
"windows-link",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "colored"
|
||||||
|
version = "3.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fde0e0ec90c9dfb3b4b1a0891a7dcd0e2bffde2f7efed5fe7c9bb00e5bfb915e"
|
||||||
|
dependencies = [
|
||||||
|
"windows-sys 0.59.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "core-foundation-sys"
|
||||||
|
version = "0.8.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "errno"
|
||||||
|
version = "0.3.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cea14ef9355e3beab063703aa9dab15afd25f0667c341310c1e5274bb1d0da18"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"windows-sys 0.59.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "iana-time-zone"
|
||||||
|
version = "0.1.63"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8"
|
||||||
|
dependencies = [
|
||||||
|
"android_system_properties",
|
||||||
|
"core-foundation-sys",
|
||||||
|
"iana-time-zone-haiku",
|
||||||
|
"js-sys",
|
||||||
|
"log",
|
||||||
|
"wasm-bindgen",
|
||||||
|
"windows-core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "iana-time-zone-haiku"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itoa"
|
||||||
|
version = "1.0.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "js-sys"
|
||||||
|
version = "0.3.77"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f"
|
||||||
|
dependencies = [
|
||||||
|
"once_cell",
|
||||||
|
"wasm-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lazy_static"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libc"
|
||||||
|
version = "0.2.174"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "linux-raw-sys"
|
||||||
|
version = "0.4.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "log"
|
||||||
|
version = "0.4.27"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memchr"
|
||||||
|
version = "2.7.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "metodol_projekt"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"chrono",
|
||||||
|
"colored",
|
||||||
|
"lazy_static",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"signal-hook",
|
||||||
|
"terminal_size",
|
||||||
|
"text_io",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-traits"
|
||||||
|
version = "0.2.19"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "once_cell"
|
||||||
|
version = "1.21.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.95"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "1.0.40"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustix"
|
||||||
|
version = "0.38.44"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"errno",
|
||||||
|
"libc",
|
||||||
|
"linux-raw-sys",
|
||||||
|
"windows-sys 0.59.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustversion"
|
||||||
|
version = "1.0.21"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ryu"
|
||||||
|
version = "1.0.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde"
|
||||||
|
version = "1.0.219"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
|
||||||
|
dependencies = [
|
||||||
|
"serde_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_derive"
|
||||||
|
version = "1.0.219"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_json"
|
||||||
|
version = "1.0.140"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373"
|
||||||
|
dependencies = [
|
||||||
|
"itoa",
|
||||||
|
"memchr",
|
||||||
|
"ryu",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "shlex"
|
||||||
|
version = "1.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "signal-hook"
|
||||||
|
version = "0.3.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d881a16cf4426aa584979d30bd82cb33429027e42122b169753d6ef1085ed6e2"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"signal-hook-registry",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "signal-hook-registry"
|
||||||
|
version = "1.4.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9203b8055f63a2a00e2f593bb0510367fe707d7ff1e5c872de2f537b339e5410"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "2.0.103"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e4307e30089d6fd6aff212f2da3a1f9e32f3223b1f010fb09b7c95f90f3ca1e8"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "terminal_size"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7"
|
||||||
|
dependencies = [
|
||||||
|
"rustix",
|
||||||
|
"windows-sys 0.48.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "text_io"
|
||||||
|
version = "0.1.13"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4d8d3ca3b06292094e03841d8995e910712d2a10b5869c8f9725385b29761115"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-ident"
|
||||||
|
version = "1.0.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen"
|
||||||
|
version = "0.2.100"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"once_cell",
|
||||||
|
"rustversion",
|
||||||
|
"wasm-bindgen-macro",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-backend"
|
||||||
|
version = "0.2.100"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6"
|
||||||
|
dependencies = [
|
||||||
|
"bumpalo",
|
||||||
|
"log",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
"wasm-bindgen-shared",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-macro"
|
||||||
|
version = "0.2.100"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407"
|
||||||
|
dependencies = [
|
||||||
|
"quote",
|
||||||
|
"wasm-bindgen-macro-support",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-macro-support"
|
||||||
|
version = "0.2.100"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
"wasm-bindgen-backend",
|
||||||
|
"wasm-bindgen-shared",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-shared"
|
||||||
|
version = "0.2.100"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-core"
|
||||||
|
version = "0.61.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3"
|
||||||
|
dependencies = [
|
||||||
|
"windows-implement",
|
||||||
|
"windows-interface",
|
||||||
|
"windows-link",
|
||||||
|
"windows-result",
|
||||||
|
"windows-strings",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-implement"
|
||||||
|
version = "0.60.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-interface"
|
||||||
|
version = "0.59.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-link"
|
||||||
|
version = "0.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-result"
|
||||||
|
version = "0.3.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6"
|
||||||
|
dependencies = [
|
||||||
|
"windows-link",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-strings"
|
||||||
|
version = "0.4.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57"
|
||||||
|
dependencies = [
|
||||||
|
"windows-link",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-sys"
|
||||||
|
version = "0.48.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
|
||||||
|
dependencies = [
|
||||||
|
"windows-targets 0.48.5",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-sys"
|
||||||
|
version = "0.59.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
|
||||||
|
dependencies = [
|
||||||
|
"windows-targets 0.52.6",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-targets"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
|
||||||
|
dependencies = [
|
||||||
|
"windows_aarch64_gnullvm 0.48.5",
|
||||||
|
"windows_aarch64_msvc 0.48.5",
|
||||||
|
"windows_i686_gnu 0.48.5",
|
||||||
|
"windows_i686_msvc 0.48.5",
|
||||||
|
"windows_x86_64_gnu 0.48.5",
|
||||||
|
"windows_x86_64_gnullvm 0.48.5",
|
||||||
|
"windows_x86_64_msvc 0.48.5",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-targets"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
|
||||||
|
dependencies = [
|
||||||
|
"windows_aarch64_gnullvm 0.52.6",
|
||||||
|
"windows_aarch64_msvc 0.52.6",
|
||||||
|
"windows_i686_gnu 0.52.6",
|
||||||
|
"windows_i686_gnullvm",
|
||||||
|
"windows_i686_msvc 0.52.6",
|
||||||
|
"windows_x86_64_gnu 0.52.6",
|
||||||
|
"windows_x86_64_gnullvm 0.52.6",
|
||||||
|
"windows_x86_64_msvc 0.52.6",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_aarch64_gnullvm"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_aarch64_gnullvm"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_aarch64_msvc"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_aarch64_msvc"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_gnu"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_gnu"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_gnullvm"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_msvc"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_msvc"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnu"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnu"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnullvm"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnullvm"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_msvc"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_msvc"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
|
@ -0,0 +1,16 @@
|
||||||
|
[package]
|
||||||
|
name = "metodol_projekt"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
serde = { version = "1.0.219", features = ["derive"] }
|
||||||
|
serde_json = "1.0.140"
|
||||||
|
terminal_size = "0.3.0"
|
||||||
|
signal-hook = "0.3"
|
||||||
|
text_io = "0.1.13"
|
||||||
|
lazy_static = "1.5.0"
|
||||||
|
colored = "3.0.0"
|
||||||
|
chrono = "0.4.41"
|
|
@ -0,0 +1,224 @@
|
||||||
|
{
|
||||||
|
"version": 1,
|
||||||
|
"maps": [
|
||||||
|
{
|
||||||
|
"default": true,
|
||||||
|
"map_required": true,
|
||||||
|
"starting_location": [3, 6],
|
||||||
|
"name": "Mystic Forest",
|
||||||
|
"description": "A mystical forest filled with ancient trees and hidden secrets.",
|
||||||
|
"id": "mystic_forest",
|
||||||
|
"width": 10,
|
||||||
|
"height": 10,
|
||||||
|
"events": [
|
||||||
|
{
|
||||||
|
"evt_type": "npc",
|
||||||
|
"command_id": "oak",
|
||||||
|
"name": "Elder Oak",
|
||||||
|
"location": [2, 3],
|
||||||
|
"dialogue": [
|
||||||
|
"You meet the Elder Oak, a towering tree with a face carved into its bark.",
|
||||||
|
"<i>Welcome to the Mystic Forest, young traveler.</i>",
|
||||||
|
"<i>Many secrets lie within these woods.</i>",
|
||||||
|
"<i>Seek the hidden glades and you may find treasures untold.</i>"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"evt_type": "item",
|
||||||
|
"command_id": "scroll",
|
||||||
|
"name": "Ancient Scroll",
|
||||||
|
"description": "A scroll containing secrets of the forest.",
|
||||||
|
"location": [7, 8]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"evt_type": "location",
|
||||||
|
"command_id": "mystic_cottage",
|
||||||
|
"name": "Mystic Cottage",
|
||||||
|
"description": "A small cottage made of enchanted wood, home to a wise hermit.",
|
||||||
|
"location": [2, 6]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"tilemap": [
|
||||||
|
["water_border", "water_border", "water_border", "water_border", "water_border", "water_border", "water_border", "water_border", "water_border", "water_border"],
|
||||||
|
["water_border", "grass", "grass", "grass", "grass", "grass", "grass", "grass", "grass", "water_border"],
|
||||||
|
["water_border", "grass", "grass", "grass", "grass", "grass", "grass", "grass", "grass", "water_border"],
|
||||||
|
["water_border", "grass", "grass", "grass", "grass", "grass", "grass", "grass", "grass", "water_border"],
|
||||||
|
["water_border", "grass", "grass", "grass", "grass", "grass", "grass", "grass", "grass", "water_border"],
|
||||||
|
["water_border", "grass", "grass", "grass", "grass", "grass", "grass", "grass", "grass", "water_border"],
|
||||||
|
["water_border", "water", "house", "grass", "grass", "grass", "grass", "grass", "grass", "water_border"],
|
||||||
|
["water_border", "grass", "grass", "grass", "grass", "grass", "grass", "grass", "grass", "water_border"],
|
||||||
|
["water_border", "grass", "grass", "grass", "grass", "grass", "grass", "grass", "grass", "water_border"],
|
||||||
|
["water_border", "water_border", "water_border", "water_border", "water_border", "water_border", "water_border", "water_border", "water_border", "water_border"]
|
||||||
|
],
|
||||||
|
"tiles": {
|
||||||
|
"house": {
|
||||||
|
"name": "Mystic Cottage",
|
||||||
|
"icon": {
|
||||||
|
"char": "H",
|
||||||
|
"color": [139, 69, 19]
|
||||||
|
},
|
||||||
|
"walkable": true,
|
||||||
|
"description": "A small cottage made of enchanted wood, home to a wise hermit.",
|
||||||
|
"bitmap": [
|
||||||
|
["H", "H", "H", "H", "H", "H", "H", "H", "H", "H", "H", "H", "H", "H", "H", "H"],
|
||||||
|
["H", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "H"],
|
||||||
|
["H", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "H"],
|
||||||
|
["H", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "H"],
|
||||||
|
["H", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "H"],
|
||||||
|
["H", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "H"],
|
||||||
|
["H", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "H"],
|
||||||
|
["H", "H", "H", "H", "H", "H", "H", "H", "H", "H", "H", "H", "H", "H", "H", "H"]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"water_border": {
|
||||||
|
"name": "Water Border",
|
||||||
|
"icon": {
|
||||||
|
"char": "~",
|
||||||
|
"color": [0, 0, 255]
|
||||||
|
},
|
||||||
|
"walkable": false,
|
||||||
|
"description": "A border of water surrounding the Mystic Forest.",
|
||||||
|
"bitmap": [
|
||||||
|
["~", "~", "~", "~", "~", "~", "~", "~", "~", "~"],
|
||||||
|
["~", " ", " ", " ", " ", " ", " ", " ", " ", "~"],
|
||||||
|
["~", " ", " ", " ", " ", " ", " ", " ", " ", "~"],
|
||||||
|
["~", " ", " ", " ", " ", " ", " ", " ", " ", "~"],
|
||||||
|
["~", " ", " ", " ", " ", " ", " ", " ", " ", "~"],
|
||||||
|
["~", " ", " ", " ", " ", " ", " ", " ", " ", "~"],
|
||||||
|
["~", " ", " ", " ", " ", " ", " ", " ", " ", "~"],
|
||||||
|
["~", "~", "~", "~", "~", "~", "~", "~", "~", "~"]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"water": {
|
||||||
|
"name": "Water",
|
||||||
|
"icon": {
|
||||||
|
"char": "~",
|
||||||
|
"color": [0, 128, 255]
|
||||||
|
},
|
||||||
|
"walkable": true,
|
||||||
|
"description": "A serene body of water, perfect for fishing or swimming.",
|
||||||
|
"bitmap": [
|
||||||
|
["~", " ", " ", "~", " ", " ", "~", " ", " ", "~", " ", " ", "~", " ", " ", "~"],
|
||||||
|
[" ", "~", " ", " ", "~", " ", " ", "~", " ", " ", "~", " ", " ", "~", " ", " "],
|
||||||
|
[" ", " ", "~", " ", " ", "~", " ", " ", "~", " ", " ", "~", " ", " ", "~", " "],
|
||||||
|
["~", " ", " ", "~", " ", " ", "~", " ", " ", "~", " ", " ", "~", " ", " ", "~"],
|
||||||
|
[" ", "~", " ", " ", "~", " ", " ", "~", " ", " ", "~", " ", " ", "~", " ", " "],
|
||||||
|
[" ", " ", "~", " ", " ", "~", " ", " ", "~", " ", " ", "~", " ", " ", "~", " "],
|
||||||
|
["~", " ", " ", "~", " ", " ", "~", " ", " ", "~", " ", " ", "~", " ", " ", "~"],
|
||||||
|
[" ", "~", " ", " ", "~", " ", " ", "~", " ", " ", "~", " ", " ", "~", " ", " "]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"grass": {
|
||||||
|
"name": "Grass",
|
||||||
|
"icon": {
|
||||||
|
"char": "#",
|
||||||
|
"color": [0, 255, 0]
|
||||||
|
},
|
||||||
|
"walkable": true,
|
||||||
|
"description": "Lush green grass, perfect for a picnic or a stroll.",
|
||||||
|
"bitmap": [
|
||||||
|
["#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " "],
|
||||||
|
[" ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#"],
|
||||||
|
["#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " "],
|
||||||
|
[" ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#"],
|
||||||
|
["#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " "],
|
||||||
|
[" ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#"],
|
||||||
|
["#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " "],
|
||||||
|
[" ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#"]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
"default": false,
|
||||||
|
"map_required": false,
|
||||||
|
"starting_location": [2, 4],
|
||||||
|
"name": "Mystic Cottage",
|
||||||
|
"description": "A small cottage made of enchanted wood, home to a wise hermit.",
|
||||||
|
"id": "mystic_cottage",
|
||||||
|
"width": 5,
|
||||||
|
"height": 5,
|
||||||
|
"events": [
|
||||||
|
{
|
||||||
|
"evt_type": "item",
|
||||||
|
"command_id": "map",
|
||||||
|
"name": "Mystic Forest Map",
|
||||||
|
"description": "A map of the Mystic Forest.",
|
||||||
|
"location": [7, 8]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"evt_type": "location",
|
||||||
|
"command_id": "mystic_forest",
|
||||||
|
"name": "Door",
|
||||||
|
"description": "A small wooden door leading to the outside.",
|
||||||
|
"location": [2, 4]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"tilemap": [
|
||||||
|
["wall", "wall", "wall", "wall", "wall"],
|
||||||
|
["wall", "floor", "floor", "floor", "wall"],
|
||||||
|
["wall", "floor", "floor", "floor", "wall"],
|
||||||
|
["wall", "floor", "floor", "floor", "wall"],
|
||||||
|
["wall", "wall", "door", "wall", "wall"]
|
||||||
|
],
|
||||||
|
"tiles": {
|
||||||
|
"wall": {
|
||||||
|
"name": "Wall",
|
||||||
|
"icon": {
|
||||||
|
"char": "#",
|
||||||
|
"color": [0, 0, 255]
|
||||||
|
},
|
||||||
|
"walkable": false,
|
||||||
|
"description": "A sturdy wall made of enchanted wood, protecting the cottage.",
|
||||||
|
"bitmap": [
|
||||||
|
["#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#"],
|
||||||
|
["#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#"],
|
||||||
|
["#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#"],
|
||||||
|
["#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#"],
|
||||||
|
["#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#"],
|
||||||
|
["#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#"],
|
||||||
|
["#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#"],
|
||||||
|
["#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#"]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"floor": {
|
||||||
|
"name": "Floor",
|
||||||
|
"icon": {
|
||||||
|
"char": "+",
|
||||||
|
"color": [237, 207, 147]
|
||||||
|
},
|
||||||
|
"walkable": true,
|
||||||
|
"description": "A cozy wooden floor, warm and inviting.",
|
||||||
|
"bitmap": [
|
||||||
|
["+", " ", "+", " ", "+", " ", "+", " ", "+", " ", "+", " ", "+", " ", "+", " "],
|
||||||
|
[" ", "+", " ", "+", " ", "+", " ", "+", " ", "+", " ", "+", " ", "+", " ", "+"],
|
||||||
|
["+", " ", "+", " ", "+", " ", "+", " ", "+", " ", "+", " ", "+", " ", "+", " "],
|
||||||
|
[" ", "+", " ", "+", " ", "+", " ", "+", " ", "+", " ", "+", " ", "+", " ", "+"],
|
||||||
|
["+", " ", "+", " ", "+", " ", "+", " ", "+", " ", "+", " ", "+", " ", "+", " "],
|
||||||
|
[" ", "+", " ", "+", " ", "+", " ", "+", " ", "+", " ", "+", " ", "+", " ", "+"],
|
||||||
|
["+", " ", "+", " ", "+", " ", "+", " ", "+", " ", "+", " ", "+", " ", "+", " "],
|
||||||
|
[" ", "+", " ", "+", " ", "+", " ", "+", " ", "+", " ", "+", " ", "+", " ", "+"]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"door": {
|
||||||
|
"name": "Door",
|
||||||
|
"icon": {
|
||||||
|
"char": "@",
|
||||||
|
"color": [128, 0, 0]
|
||||||
|
},
|
||||||
|
"walkable": true,
|
||||||
|
"description": "A small wooden door leading to the outside.",
|
||||||
|
"bitmap": [
|
||||||
|
["@", "@", "@", "@", "@", "@", "@", "@", "@", "@", "@", "@", "@", "@", "@", "@"],
|
||||||
|
["@", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "@"],
|
||||||
|
["@", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "@"],
|
||||||
|
["@", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "+", "-", "-", "@"],
|
||||||
|
["@", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "|", " ", " ", "@"],
|
||||||
|
["@", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "@"],
|
||||||
|
["@", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "@"],
|
||||||
|
["@", "@", "@", "@", "@", "@", "@", "@", "@", "@", "@", "@", "@", "@", "@", "@"]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,330 @@
|
||||||
|
{
|
||||||
|
"version": 1,
|
||||||
|
"maps": [
|
||||||
|
{
|
||||||
|
"default": true,
|
||||||
|
"map_required": true,
|
||||||
|
"starting_location": [1, 14],
|
||||||
|
"name": "test2",
|
||||||
|
"description": "testtttt2",
|
||||||
|
"id": "test2",
|
||||||
|
"width": 16,
|
||||||
|
"height": 16,
|
||||||
|
"events": [
|
||||||
|
{
|
||||||
|
"evt_type": "location",
|
||||||
|
"command_id": "mystic_cottage",
|
||||||
|
"name": "Mystic Cottage",
|
||||||
|
"description": "A small cottage made of enchanted wood, home to a wise hermit.",
|
||||||
|
"location": [8, 4]
|
||||||
|
}, {
|
||||||
|
"evt_type": "item",
|
||||||
|
"command_id": "gate_key",
|
||||||
|
"name": "Gate key",
|
||||||
|
"description": "A key that unlocks the gate.",
|
||||||
|
"location": [5, 15]
|
||||||
|
}, {
|
||||||
|
"evt_type": "lock",
|
||||||
|
"command_id": "gate_key",
|
||||||
|
"name": "Gate",
|
||||||
|
"description": "This gate is locked. You need a key to open it.",
|
||||||
|
"location": [7, 13]
|
||||||
|
}, {
|
||||||
|
"evt_type": "lock",
|
||||||
|
"command_id": "gate_key",
|
||||||
|
"name": "Gate",
|
||||||
|
"description": "This gate is locked. You need a key to open it.",
|
||||||
|
"location": [8, 13]
|
||||||
|
}, {
|
||||||
|
"evt_type": "item",
|
||||||
|
"command_id": "map",
|
||||||
|
"name": "Map",
|
||||||
|
"description": "A map of the Mystic Forest.",
|
||||||
|
"location": [8, 14]
|
||||||
|
}, {
|
||||||
|
"evt_type": "npc",
|
||||||
|
"command_id": "czesio",
|
||||||
|
"name": "Czesio",
|
||||||
|
"description": "A friendly NPC who can help you with your journey.",
|
||||||
|
"location": [0, 14]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"tilemap": [
|
||||||
|
["grass", "grass", "grass", "grass", "fence", "fence", "fence", "fence", "fence", "fence", "fence", "fence", "grass", "grass", "grass", "grass"],
|
||||||
|
["grass", "grass", "grass", "grass", "fence", "grass", "grass", "grass", "grass", "grass", "grass", "fence", "grass", "grass", "grass", "grass"],
|
||||||
|
["grass", "grass", "grass", "grass", "fence", "grass", "grass", "grass", "grass", "grass", "grass", "fence", "grass", "grass", "grass", "grass"],
|
||||||
|
["grass", "grass", "grass", "grass", "fence", "grass", "grass", "house", "house", "grass", "grass", "fence", "grass", "grass", "grass", "grass"],
|
||||||
|
["grass", "grass", "grass", "grass", "fence", "grass", "grass", "house", "house_entry", "grass", "grass", "fence", "grass", "grass", "grass", "grass"],
|
||||||
|
["grass", "grass", "grass", "grass", "fence", "grass", "grass", "grass", "grass", "grass", "grass", "fence", "grass", "grass", "grass", "grass"],
|
||||||
|
["grass", "grass", "grass", "grass", "fence", "grass", "grass", "grass", "grass", "grass", "grass", "fence", "grass", "grass", "grass", "grass"],
|
||||||
|
["grass", "grass", "grass", "grass", "fence", "grass", "grass", "grass", "grass", "wall", "wall", "fence", "grass", "grass", "grass", "grass"],
|
||||||
|
["grass", "grass", "grass", "grass", "fence", "grass", "grass", "grass", "grass", "wall", "wall", "fence", "grass", "grass", "grass", "grass"],
|
||||||
|
["grass", "grass", "grass", "grass", "fence", "fence", "fence", "gate", "fence", "gate", "gate", "fence", "grass", "grass", "grass", "grass"],
|
||||||
|
["grass", "grass", "grass", "grass", "fence", "wall", "wall", "grass", "grass", "concrete", "concrete", "fence", "grass", "grass", "grass", "grass"],
|
||||||
|
["grass", "grass", "grass", "grass", "fence", "wall", "wall", "grass", "grass", "concrete", "concrete", "fence", "grass", "grass", "grass", "grass"],
|
||||||
|
["grass", "grass", "grass", "grass", "fence", "wall", "wall", "grass", "grass", "concrete", "concrete", "fence", "grass", "grass", "grass", "grass"],
|
||||||
|
["fence", "fence", "fence", "fence", "fence", "wall", "wall", "gate", "gate", "wall", "wall", "fence", "fence", "fence", "fence", "fence"],
|
||||||
|
["road", "road", "road", "road", "road", "road", "road", "road", "road", "road", "road", "road", "road", "road", "road", "road"],
|
||||||
|
["road", "road", "road", "road", "road", "road", "road", "road", "road", "road", "road", "road", "road", "road", "road", "road"]
|
||||||
|
],
|
||||||
|
"tiles": {
|
||||||
|
"road": {
|
||||||
|
"name": "Road",
|
||||||
|
"icon": {
|
||||||
|
"char": "=",
|
||||||
|
"color": [64, 64, 64]
|
||||||
|
},
|
||||||
|
"walkable": true,
|
||||||
|
"description": "Part of road.",
|
||||||
|
"bitmap": [
|
||||||
|
["=", "=", "=", "=", "=", "=", "=", "=", "=", "=", "=", "=", "=", "=", "=", "="],
|
||||||
|
["=", "=", "=", "=", "=", "=", "=", "=", "=", "=", "=", "=", "=", "=", "=", "="],
|
||||||
|
["=", "=", "=", "=", "=", "=", "=", "=", "=", "=", "=", "=", "=", "=", "=", "="],
|
||||||
|
["=", "=", "=", "=", "=", "=", "=", "=", "=", "=", "=", "=", "=", "=", "=", "="],
|
||||||
|
["=", "=", "=", "=", "=", "=", "=", "=", "=", "=", "=", "=", "=", "=", "=", "="],
|
||||||
|
["=", "=", "=", "=", "=", "=", "=", "=", "=", "=", "=", "=", "=", "=", "=", "="],
|
||||||
|
["=", "=", "=", "=", "=", "=", "=", "=", "=", "=", "=", "=", "=", "=", "=", "="],
|
||||||
|
["=", "=", "=", "=", "=", "=", "=", "=", "=", "=", "=", "=", "=", "=", "=", "="]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"fence": {
|
||||||
|
"name": "Fence",
|
||||||
|
"icon": {
|
||||||
|
"char": "+",
|
||||||
|
"color": [75, 26, 16]
|
||||||
|
},
|
||||||
|
"walkable": false,
|
||||||
|
"description": "A wooden fence, keeping the area secure.",
|
||||||
|
"bitmap": [
|
||||||
|
["+", "+", "+", "+", "+", "+", "+", "+", "+", "+", "+", "+", "+", "+", "+", "+"],
|
||||||
|
["|", " ", " ", "|", " ", " ", "|", " ", " ", "|", " ", " ", "|", " ", " ", "|"],
|
||||||
|
["|", " ", " ", "|", " ", " ", "|", " ", " ", "|", " ", " ", "|", " ", " ", "|"],
|
||||||
|
["|", "+", "+", "+", "+", "+", "+", "+", "+", "+", "+", "+", "+", "+", "+", "+"],
|
||||||
|
["|", " ", " ", "|", " ", " ", "|", " ", " ", "|", " ", " ", "|", " ", " ", "|"],
|
||||||
|
["|", " ", " ", "|", " ", " ", "|", " ", " ", "|", " ", " ", "|", " ", " ", "|"],
|
||||||
|
["|", "+", "+", "+", "+", "+", "+", "+", "+", "+", "+", "+", "+", "+", "+", "+"],
|
||||||
|
["+", "+", "+", "+", "+", "+", "+", "+", "+", "+", "+", "+", "+", "+", "+", "+"]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"gate": {
|
||||||
|
"name": "Fence gate",
|
||||||
|
"icon": {
|
||||||
|
"char": "@",
|
||||||
|
"color": [75, 26, 16]
|
||||||
|
},
|
||||||
|
"walkable": true,
|
||||||
|
"description": "A wooden gate in the fence, allowing passage.",
|
||||||
|
"bitmap": [
|
||||||
|
["+", "+", "+", "+", "+", "+", "+", "+", "+", "+", "+", "+", "+", "+", "+", "+"],
|
||||||
|
["|", " ", " ", "|", " ", " ", "@", " ", " ", "@", " ", " ", "|", " ", " ", "|"],
|
||||||
|
["|", " ", " ", "|", " ", " ", "@", " ", " ", "@", " ", " ", "|", " ", " ", "|"],
|
||||||
|
["|", "+", "+", "+", "+", "+", "@", " ", " ", "@", "+", "+", "+", "+", "+", "+"],
|
||||||
|
["|", " ", " ", "|", " ", " ", "@", " ", " ", "@", " ", " ", "|", " ", " ", "|"],
|
||||||
|
["|", " ", " ", "|", " ", " ", "@", " ", " ", "@", " ", " ", "|", " ", " ", "|"],
|
||||||
|
["|", "+", "+", "+", "+", "+", "+", "+", "+", "+", "+", "+", "+", "+", "+", "+"],
|
||||||
|
["+", "+", "+", "+", "+", "+", "+", "+", "+", "+", "+", "+", "+", "+", "+", "+"]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"wall": {
|
||||||
|
"name": "Wall",
|
||||||
|
"icon": {
|
||||||
|
"char": "#",
|
||||||
|
"color": [204, 204, 204]
|
||||||
|
},
|
||||||
|
"walkable": false,
|
||||||
|
"description": "A sturdy wall made of stone, providing protection.",
|
||||||
|
"bitmap": [
|
||||||
|
["#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#"],
|
||||||
|
["#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#"],
|
||||||
|
["#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#"],
|
||||||
|
["#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#"],
|
||||||
|
["#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#"],
|
||||||
|
["#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#"],
|
||||||
|
["#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#"],
|
||||||
|
["#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#"]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"concrete": {
|
||||||
|
"name": "Concrete",
|
||||||
|
"icon": {
|
||||||
|
"char": ".",
|
||||||
|
"color": [224, 224, 224]
|
||||||
|
},
|
||||||
|
"walkable": true,
|
||||||
|
"description": "A smooth concrete surface, often used in urban areas.",
|
||||||
|
"bitmap": [
|
||||||
|
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", "."],
|
||||||
|
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", "."],
|
||||||
|
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", "."],
|
||||||
|
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", "."],
|
||||||
|
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", "."],
|
||||||
|
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", "."],
|
||||||
|
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", "."],
|
||||||
|
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", "."]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"grass": {
|
||||||
|
"name": "Grass",
|
||||||
|
"icon": {
|
||||||
|
"char": ",",
|
||||||
|
"color": [0, 255, 0]
|
||||||
|
},
|
||||||
|
"walkable": true,
|
||||||
|
"description": "Lush green grass, perfect for a picnic or a stroll.",
|
||||||
|
"bitmap": [
|
||||||
|
["#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " "],
|
||||||
|
[" ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#"],
|
||||||
|
["#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " "],
|
||||||
|
[" ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#"],
|
||||||
|
["#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " "],
|
||||||
|
[" ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#"],
|
||||||
|
["#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " "],
|
||||||
|
[" ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#"]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"house": {
|
||||||
|
"name": "House",
|
||||||
|
"icon": {
|
||||||
|
"char": "#",
|
||||||
|
"color": [153, 111, 41]
|
||||||
|
},
|
||||||
|
"walkable": false,
|
||||||
|
"description": "A cozy little house made of enchanted wood, home to a wise hermit.",
|
||||||
|
"bitmap": [
|
||||||
|
["#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " "],
|
||||||
|
[" ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#"],
|
||||||
|
["#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " "],
|
||||||
|
[" ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#"],
|
||||||
|
["#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " "],
|
||||||
|
[" ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#"],
|
||||||
|
["#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " "],
|
||||||
|
[" ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#"]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"house_entry": {
|
||||||
|
"name": "House door",
|
||||||
|
"icon": {
|
||||||
|
"char": "@",
|
||||||
|
"color": [189, 135, 48]
|
||||||
|
},
|
||||||
|
"walkable": true,
|
||||||
|
"description": "A small wooden door leading to the inside of the house.",
|
||||||
|
"bitmap": [
|
||||||
|
["#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " "],
|
||||||
|
[" ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#"],
|
||||||
|
["#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " "],
|
||||||
|
[" ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#"],
|
||||||
|
["#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " "],
|
||||||
|
[" ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#"],
|
||||||
|
["#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " "],
|
||||||
|
[" ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#"]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"npcs": {
|
||||||
|
"czesio": {
|
||||||
|
"name": "Czesio",
|
||||||
|
"description": "Dzieńdobry",
|
||||||
|
"dialogue": [
|
||||||
|
"Hello adventurer!",
|
||||||
|
"What do you need?",
|
||||||
|
"#(00FF00)1. Nothing",
|
||||||
|
"#(00FF00)2. Gate key"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
"default": false,
|
||||||
|
"map_required": false,
|
||||||
|
"starting_location": [2, 4],
|
||||||
|
"name": "Mystic Cottage",
|
||||||
|
"description": "A small cottage made of enchanted wood, home to a wise hermit.",
|
||||||
|
"id": "mystic_cottage",
|
||||||
|
"width": 5,
|
||||||
|
"height": 5,
|
||||||
|
"events": [
|
||||||
|
{
|
||||||
|
"evt_type": "item",
|
||||||
|
"command_id": "map",
|
||||||
|
"name": "Mystic Forest Map",
|
||||||
|
"description": "A map of the Mystic Forest.",
|
||||||
|
"location": [7, 8]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"evt_type": "location",
|
||||||
|
"command_id": "test2",
|
||||||
|
"name": "Door",
|
||||||
|
"description": "A small wooden door leading to the outside.",
|
||||||
|
"location": [2, 4]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"tilemap": [
|
||||||
|
["wall", "wall", "wall", "wall", "wall"],
|
||||||
|
["wall", "floor", "floor", "floor", "wall"],
|
||||||
|
["wall", "floor", "floor", "floor", "wall"],
|
||||||
|
["wall", "floor", "floor", "floor", "wall"],
|
||||||
|
["wall", "wall", "door", "wall", "wall"]
|
||||||
|
],
|
||||||
|
"tiles": {
|
||||||
|
"wall": {
|
||||||
|
"name": "Wall",
|
||||||
|
"icon": {
|
||||||
|
"char": "#",
|
||||||
|
"color": [0, 0, 255]
|
||||||
|
},
|
||||||
|
"walkable": false,
|
||||||
|
"description": "A sturdy wall made of enchanted wood, protecting the cottage.",
|
||||||
|
"bitmap": [
|
||||||
|
["#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#"],
|
||||||
|
["#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#"],
|
||||||
|
["#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#"],
|
||||||
|
["#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#"],
|
||||||
|
["#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#"],
|
||||||
|
["#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#"],
|
||||||
|
["#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#"],
|
||||||
|
["#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#"]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"floor": {
|
||||||
|
"name": "Floor",
|
||||||
|
"icon": {
|
||||||
|
"char": "+",
|
||||||
|
"color": [237, 207, 147]
|
||||||
|
},
|
||||||
|
"walkable": true,
|
||||||
|
"description": "A cozy wooden floor, warm and inviting.",
|
||||||
|
"bitmap": [
|
||||||
|
["+", " ", "+", " ", "+", " ", "+", " ", "+", " ", "+", " ", "+", " ", "+", " "],
|
||||||
|
[" ", "+", " ", "+", " ", "+", " ", "+", " ", "+", " ", "+", " ", "+", " ", "+"],
|
||||||
|
["+", " ", "+", " ", "+", " ", "+", " ", "+", " ", "+", " ", "+", " ", "+", " "],
|
||||||
|
[" ", "+", " ", "+", " ", "+", " ", "+", " ", "+", " ", "+", " ", "+", " ", "+"],
|
||||||
|
["+", " ", "+", " ", "+", " ", "+", " ", "+", " ", "+", " ", "+", " ", "+", " "],
|
||||||
|
[" ", "+", " ", "+", " ", "+", " ", "+", " ", "+", " ", "+", " ", "+", " ", "+"],
|
||||||
|
["+", " ", "+", " ", "+", " ", "+", " ", "+", " ", "+", " ", "+", " ", "+", " "],
|
||||||
|
[" ", "+", " ", "+", " ", "+", " ", "+", " ", "+", " ", "+", " ", "+", " ", "+"]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"door": {
|
||||||
|
"name": "Door",
|
||||||
|
"icon": {
|
||||||
|
"char": "@",
|
||||||
|
"color": [128, 0, 0]
|
||||||
|
},
|
||||||
|
"walkable": true,
|
||||||
|
"description": "A small wooden door leading to the outside.",
|
||||||
|
"bitmap": [
|
||||||
|
["@", "@", "@", "@", "@", "@", "@", "@", "@", "@", "@", "@", "@", "@", "@", "@"],
|
||||||
|
["@", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "@"],
|
||||||
|
["@", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "@"],
|
||||||
|
["@", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "+", "-", "-", "@"],
|
||||||
|
["@", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "|", " ", " ", "@"],
|
||||||
|
["@", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "@"],
|
||||||
|
["@", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "@"],
|
||||||
|
["@", "@", "@", "@", "@", "@", "@", "@", "@", "@", "@", "@", "@", "@", "@", "@"]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"npcs": {}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
{"coords":{"mystic_cottage":[2,4],"test2":[9,4]},"current_map_id":"test2","flags":{"gate_opened":true},"health":100,"inventory":["map","gate_key"],"last_save":"2025-07-11 14:11:52","lines_of_text":["> save progress","#(00FF00)Progress restored","> go d","You moved into grass tile","> go r","You moved into grass tile","> go r","You moved into grass tile","> go u","You moved into house_entry tile","> enter house","You entered a location.","> go u","You moved into floor tile","> go d","You moved into door tile","> exit house","You exited a location.","> go r","You moved into grass tile","> save progress"],"map_pack":"map","player_name":"Kapitan Bomba","stamina":50,"version":1}
|
|
@ -0,0 +1,24 @@
|
||||||
|
{
|
||||||
|
"version": 1,
|
||||||
|
"map_pack": "map",
|
||||||
|
"player_name": "Kapitan Bomba",
|
||||||
|
"last_save": "2025-06-18T12:00:00Z",
|
||||||
|
"current_map_id": "test2",
|
||||||
|
"health": 100,
|
||||||
|
"mana": 50,
|
||||||
|
"coords": {
|
||||||
|
"test2": [5, 1]
|
||||||
|
},
|
||||||
|
"inventory": [
|
||||||
|
"map",
|
||||||
|
"gate_key"
|
||||||
|
],
|
||||||
|
"flags": {
|
||||||
|
"gate_opened": true
|
||||||
|
},
|
||||||
|
"lines_of_text": [
|
||||||
|
"1",
|
||||||
|
"2",
|
||||||
|
"3"
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
pub mod player;
|
|
@ -0,0 +1,81 @@
|
||||||
|
use crate::{structs::json::Tile, tui::text::add_text, utils::maps::{get_current_map, get_map_events}};
|
||||||
|
|
||||||
|
pub fn move_player(x: i8, y: i8, dry_run: bool) -> bool {
|
||||||
|
let mut all_coords = crate::PLAYER_COORDS.lock().unwrap();
|
||||||
|
let player_coords = *all_coords.get(get_current_map().unwrap().id.as_str()).unwrap();
|
||||||
|
// let mut new_coords = (player_coords.0 + x, player_coords.1 + y);
|
||||||
|
let new_coords = (
|
||||||
|
player_coords.0.wrapping_add_signed(x as i8),
|
||||||
|
player_coords.1.wrapping_add_signed(y as i8),
|
||||||
|
);
|
||||||
|
|
||||||
|
let map = get_current_map().unwrap();
|
||||||
|
|
||||||
|
let width = map.width as u8;
|
||||||
|
let height = map.height as u8;
|
||||||
|
|
||||||
|
// check if new coordinates are within bounds
|
||||||
|
if new_coords.0 >= width || new_coords.1 >= height {
|
||||||
|
return false; // Out of bounds, do not move
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if new coordinates are onto walkable tile
|
||||||
|
let tile_name = map.tilemap.get(new_coords.1 as usize)
|
||||||
|
.and_then(|row| row.get(new_coords.0 as usize))
|
||||||
|
.and_then(|tile| Some(tile.as_str()))
|
||||||
|
.unwrap_or_default();
|
||||||
|
|
||||||
|
let walkable = map.tiles.get(tile_name)
|
||||||
|
.and_then(|tile| Some(tile.walkable))
|
||||||
|
.unwrap_or(false);
|
||||||
|
|
||||||
|
// check if player is allowed to enter onto this tile
|
||||||
|
let events = get_map_events(get_current_map().unwrap().id.as_str()).unwrap();
|
||||||
|
|
||||||
|
let evt = events.iter().find(|e| e.evt_type == "lock" && e.location[0] == new_coords.0 && e.location[1] == new_coords.1);
|
||||||
|
if evt.is_some() {
|
||||||
|
let evt = evt.unwrap();
|
||||||
|
|
||||||
|
let required_item = evt.command_id.clone();
|
||||||
|
let player_items = crate::PLAYER_INVENTORY.lock().unwrap().clone();
|
||||||
|
if !player_items.contains(&required_item) {
|
||||||
|
if !dry_run { add_text(evt.description.as_ref().unwrap()); }
|
||||||
|
return false; // Player does not have required item to enter this tile
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if dry_run { return walkable; }
|
||||||
|
|
||||||
|
if !walkable {
|
||||||
|
add_text(&format!("! Cannot move into {} tile", tile_name));
|
||||||
|
return false; // Not a walkable tile, do not move
|
||||||
|
}
|
||||||
|
|
||||||
|
all_coords.insert(map.id, new_coords);
|
||||||
|
*crate::PLAYER_STAMINA.lock().unwrap() -= 1;
|
||||||
|
|
||||||
|
// crate::PLAYER_COORDS.lock().unwrap().0 = new_coords.0;
|
||||||
|
// crate::PLAYER_COORDS.lock().unwrap().1 = new_coords.1;
|
||||||
|
|
||||||
|
add_text(&format!("You moved into {} tile", tile_name));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_current_tile() -> Option<Tile> {
|
||||||
|
let map = get_current_map().unwrap();
|
||||||
|
let player_coords = crate::PLAYER_COORDS.lock().unwrap().clone();
|
||||||
|
let map_coords = *player_coords.get(map.id.as_str()).unwrap();
|
||||||
|
|
||||||
|
let tile_id = map.tilemap
|
||||||
|
.get(map_coords.1 as usize)
|
||||||
|
.and_then(|row| row.get(map_coords.0 as usize))
|
||||||
|
.and_then(|tile| Some(tile.as_str()))
|
||||||
|
.unwrap_or_default();
|
||||||
|
|
||||||
|
let tile = map.tiles.get(tile_id)
|
||||||
|
.cloned()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
Some(tile)
|
||||||
|
}
|
|
@ -0,0 +1,232 @@
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::io::Write;
|
||||||
|
use std::sync::Mutex;
|
||||||
|
use std::{env, io};
|
||||||
|
use lazy_static::lazy_static;
|
||||||
|
use serde_json::{Map, Value};
|
||||||
|
use terminal_size::{Width, Height, terminal_size};
|
||||||
|
use signal_hook::consts::signal::SIGWINCH;
|
||||||
|
use signal_hook::iterator::Signals;
|
||||||
|
use text_io::read;
|
||||||
|
|
||||||
|
mod utils;
|
||||||
|
use utils::os::*;
|
||||||
|
|
||||||
|
mod tui;
|
||||||
|
use tui::interface::draw_interface;
|
||||||
|
use tui::interface::clear_input;
|
||||||
|
|
||||||
|
mod parser;
|
||||||
|
use parser::nlp::parse_command;
|
||||||
|
|
||||||
|
mod structs;
|
||||||
|
|
||||||
|
use crate::parser::nlp::get_available_commands;
|
||||||
|
use crate::structs::json::MapData;
|
||||||
|
use crate::structs::save::SaveData;
|
||||||
|
use crate::tui::interface::draw_player_data;
|
||||||
|
use crate::tui::map::{draw_map, draw_tile};
|
||||||
|
use crate::tui::menu::display_splash_screen;
|
||||||
|
|
||||||
|
mod game;
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
static ref MAP_PACK: Mutex<String> = Mutex::new("".to_string());
|
||||||
|
static ref PLAYER_NAME: Mutex<String> = Mutex::new("Player".to_string());
|
||||||
|
static ref PLAYER_HEALTH: Mutex<u32> = Mutex::new(100);
|
||||||
|
static ref PLAYER_STAMINA: Mutex<u32> = Mutex::new(50);
|
||||||
|
static ref PLAYER_COORDS: Mutex<HashMap<String, (u8, u8)>> = Mutex::new(HashMap::new());
|
||||||
|
static ref PLAYER_INVENTORY: Mutex<Vec<String>> = Mutex::new(Vec::new());
|
||||||
|
static ref FLAGS: Mutex<HashMap<String, bool>> = Mutex::new(HashMap::new());
|
||||||
|
static ref MAPS: Mutex<Vec<MapData>> = Mutex::new(Vec::new());
|
||||||
|
static ref CURRENT_MAP_ID: Mutex<String> = Mutex::new("default".to_string());
|
||||||
|
static ref LINES_OF_TEXT: Mutex<Vec<String>> = Mutex::new(Vec::new());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
set_terminal_title("Twoja Stara: The Game");
|
||||||
|
|
||||||
|
let args: Vec<String> = env::args().collect();
|
||||||
|
if args.len() > 1 && args[1] == "-d" {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut signals = Signals::new(&[SIGWINCH]).expect("Failed to set up signal handling");
|
||||||
|
|
||||||
|
let min_width = 100;
|
||||||
|
let min_height = 30;
|
||||||
|
// let width: u16;
|
||||||
|
let height: u16;
|
||||||
|
|
||||||
|
loop {
|
||||||
|
clear_console();
|
||||||
|
let size = terminal_size();
|
||||||
|
if let Some((Width(w), Height(h))) = size {
|
||||||
|
if w >= min_width && h >= min_height {
|
||||||
|
// width = w;
|
||||||
|
height = h;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("Terminal size is too small. Minimum size is {}x{}, but current size is {}x{}.", min_width, min_height, w, h);
|
||||||
|
|
||||||
|
signals.forever().find(|&signal| signal == SIGWINCH);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// display_splash_screen();
|
||||||
|
|
||||||
|
enum GameState {
|
||||||
|
New,
|
||||||
|
Loaded
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut error = "";
|
||||||
|
let game_state: GameState;
|
||||||
|
let map_name: String;
|
||||||
|
|
||||||
|
loop {
|
||||||
|
clear_console();
|
||||||
|
display_splash_screen();
|
||||||
|
// move_cursor(0, 0);
|
||||||
|
println!("1. Start new game\n2. Load from save.json{}", error);
|
||||||
|
let choice: String = read!("{}\n");
|
||||||
|
match choice.as_str() {
|
||||||
|
"1" => {
|
||||||
|
game_state = GameState::New;
|
||||||
|
|
||||||
|
map_name = "map".to_string();
|
||||||
|
|
||||||
|
*PLAYER_NAME.lock().unwrap() = "Player".to_string();
|
||||||
|
*PLAYER_HEALTH.lock().unwrap() = 100;
|
||||||
|
*PLAYER_STAMINA.lock().unwrap() = 50;
|
||||||
|
*PLAYER_COORDS.lock().unwrap() = HashMap::new();
|
||||||
|
*PLAYER_INVENTORY.lock().unwrap() = Vec::new();
|
||||||
|
*FLAGS.lock().unwrap() = HashMap::new();
|
||||||
|
*CURRENT_MAP_ID.lock().unwrap() = map_name.to_string();
|
||||||
|
|
||||||
|
let mut lines = Vec::new();
|
||||||
|
lines.push("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.");
|
||||||
|
*LINES_OF_TEXT.lock().unwrap() = Vec::new();
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
"2" => {
|
||||||
|
let save = utils::json::load_json("save.json");
|
||||||
|
match save {
|
||||||
|
Ok(data) => {
|
||||||
|
game_state = GameState::Loaded;
|
||||||
|
|
||||||
|
let save_data: SaveData = serde_json::from_value(data).unwrap();
|
||||||
|
let mut lines = save_data.lines_of_text;
|
||||||
|
lines.push("#(00FF00)Progress restored".to_string());
|
||||||
|
|
||||||
|
*PLAYER_NAME.lock().unwrap() = save_data.player_name;
|
||||||
|
*PLAYER_HEALTH.lock().unwrap() = save_data.health;
|
||||||
|
*PLAYER_STAMINA.lock().unwrap() = save_data.stamina;
|
||||||
|
*PLAYER_COORDS.lock().unwrap() = save_data.coords.iter().map(|(k, v)| (k.to_string(), (v[0], v[1]))).collect();
|
||||||
|
*PLAYER_INVENTORY.lock().unwrap() = save_data.inventory;
|
||||||
|
*FLAGS.lock().unwrap() = save_data.flags;
|
||||||
|
*CURRENT_MAP_ID.lock().unwrap() = save_data.current_map_id.clone();
|
||||||
|
*LINES_OF_TEXT.lock().unwrap() = lines;
|
||||||
|
|
||||||
|
map_name = save_data.map_pack;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
eprintln!("Error loading save file: {}", e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
error = "\nPlease select either 1 or 2";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("Loading map: {}.json", map_name);
|
||||||
|
let json_data = utils::json::load_json(format!("{}.json", map_name).as_str());
|
||||||
|
*MAP_PACK.lock().unwrap() = map_name;
|
||||||
|
|
||||||
|
match json_data {
|
||||||
|
Ok(data) => {
|
||||||
|
let maps: Vec<MapData> = data.get("maps")
|
||||||
|
.and_then(|v| v.as_array())
|
||||||
|
.unwrap_or(&Vec::new())
|
||||||
|
.iter()
|
||||||
|
.filter_map(|v| v.as_object().cloned())
|
||||||
|
.collect::<Vec<Map<String, Value>>>()
|
||||||
|
.iter()
|
||||||
|
.filter_map(|map| {
|
||||||
|
print!("{:?}, ", map.get("id"));
|
||||||
|
serde_json::from_value(Value::Object(map.clone())).ok()
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
*MAPS.lock().unwrap() = maps.clone();
|
||||||
|
println!("asdf{:?}", MAPS.lock().unwrap());
|
||||||
|
|
||||||
|
if matches!(game_state, GameState::New) {
|
||||||
|
let current_map_id = maps.iter()
|
||||||
|
.find(|map| map.default)
|
||||||
|
.and_then(|map| Some(map.id.clone()))
|
||||||
|
.unwrap()
|
||||||
|
.to_string();
|
||||||
|
|
||||||
|
*CURRENT_MAP_ID.lock().unwrap() = current_map_id.clone();
|
||||||
|
|
||||||
|
let mut coords = PLAYER_COORDS.lock().unwrap();
|
||||||
|
|
||||||
|
for(_, map) in maps.iter().enumerate() {
|
||||||
|
coords.insert(map.id.clone(), (
|
||||||
|
*map.starting_location.get(0).unwrap(),
|
||||||
|
*map.starting_location.get(1).unwrap()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// let starting_location = data.get("data")
|
||||||
|
// .and_then(|v| v.as_object())
|
||||||
|
// .and_then(|obj| obj.get("starting_location"))
|
||||||
|
// .and_then(|v| v.as_array())
|
||||||
|
// .unwrap();
|
||||||
|
|
||||||
|
// let mut a = PLAYER_COORDS.lock().unwrap();
|
||||||
|
// a.insert(current_map_id, (
|
||||||
|
// starting_location.get(0).and_then(|v| v.as_u64()).unwrap_or(0).try_into().unwrap_or(0),
|
||||||
|
// starting_location.get(1).and_then(|v| v.as_u64()).unwrap_or(0).try_into().unwrap_or(0)
|
||||||
|
// ));
|
||||||
|
|
||||||
|
// PLAYER_COORDS.lock().unwrap().0 = starting_location.get(0).and_then(|v| v.as_u64()).unwrap_or(0).try_into().unwrap_or(0);
|
||||||
|
// PLAYER_COORDS.lock().unwrap().1 = starting_location.get(1).and_then(|v| v.as_u64()).unwrap_or(0).try_into().unwrap_or(0);
|
||||||
|
// draw_map(map_data);
|
||||||
|
|
||||||
|
},
|
||||||
|
Err(e) => eprintln!("Error loading JSON data: {}", e),
|
||||||
|
}
|
||||||
|
|
||||||
|
draw_interface();
|
||||||
|
|
||||||
|
loop {
|
||||||
|
if PLAYER_INVENTORY.lock().unwrap().clone().iter().find(|x| x == &"map").is_some() { draw_map() }
|
||||||
|
move_cursor(2, height - 2);
|
||||||
|
set_cursor_visibility(true);
|
||||||
|
|
||||||
|
let line: String = read!("{}\n");
|
||||||
|
parse_command(&line);
|
||||||
|
draw_tile();
|
||||||
|
get_available_commands();
|
||||||
|
io::stdout().flush().expect("Failed to flush stdout");
|
||||||
|
// thread::sleep(std::time::Duration::from_millis(1000));
|
||||||
|
clear_input();
|
||||||
|
draw_player_data();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// move_cursor(width - 1, height - 1);
|
||||||
|
// loop {}
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
pub mod nlp;
|
|
@ -0,0 +1,300 @@
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use colored::Colorize;
|
||||||
|
use serde_json::to_value;
|
||||||
|
|
||||||
|
use crate::{game::player::move_player, structs::save::SaveData, tui::{text::add_text}, utils::{json::save_json, maps::{get_current_map, get_map_events, get_npc, load_new_map}, os::move_cursor}};
|
||||||
|
|
||||||
|
lazy_static::lazy_static! {
|
||||||
|
static ref COMMAND_SYNONYMS: HashMap<&'static str, &'static str> = {
|
||||||
|
let mut map = HashMap::new();
|
||||||
|
map.insert("go", "go");
|
||||||
|
map.insert("towards", "go");
|
||||||
|
map.insert("head", "go");
|
||||||
|
map.insert("walk", "go");
|
||||||
|
map.insert("move", "go");
|
||||||
|
map.insert("mv", "go");
|
||||||
|
map.insert("examine", "examine");
|
||||||
|
map.insert("inspect", "examine");
|
||||||
|
map.insert("look", "examine");
|
||||||
|
map.insert("take", "take");
|
||||||
|
map.insert("grab", "take");
|
||||||
|
map.insert("pick", "take");
|
||||||
|
map.insert("enter", "enter");
|
||||||
|
map.insert("exit", "exit");
|
||||||
|
map.insert("leave", "exit");
|
||||||
|
map.insert("talk", "talk");
|
||||||
|
map.insert("describe", "describe");
|
||||||
|
map.insert("desc", "describe");
|
||||||
|
map.insert("talk", "talk");
|
||||||
|
map.insert("say", "say");
|
||||||
|
map.insert("save", "save");
|
||||||
|
map
|
||||||
|
};
|
||||||
|
|
||||||
|
static ref DIRECTIONS: HashMap<&'static str, (i8, i8)> = {
|
||||||
|
let mut map = HashMap::new();
|
||||||
|
map.insert("north", (0, -1));
|
||||||
|
map.insert("n", (0, -1));
|
||||||
|
map.insert("up", (0, -1));
|
||||||
|
map.insert("u", (0, -1));
|
||||||
|
map.insert("south", (0, 1));
|
||||||
|
map.insert("s", (0, 1));
|
||||||
|
map.insert("down", (0, 1));
|
||||||
|
map.insert("d", (0, 1));
|
||||||
|
map.insert("east", (1, 0));
|
||||||
|
map.insert("e", (1, 0));
|
||||||
|
map.insert("right", (1, 0));
|
||||||
|
map.insert("r", (1, 0));
|
||||||
|
map.insert("west", (-1, 0));
|
||||||
|
map.insert("w", (-1, 0));
|
||||||
|
map.insert("left", (-1, 0));
|
||||||
|
map.insert("l", (-1, 0));
|
||||||
|
map
|
||||||
|
};
|
||||||
|
|
||||||
|
static ref LOCATIONS: HashMap<&'static str, &'static str> = {
|
||||||
|
let mut map = HashMap::new();
|
||||||
|
map.insert("home", "home");
|
||||||
|
map.insert("house", "home");
|
||||||
|
map.insert("cave", "cave");
|
||||||
|
map.insert("forest", "forest");
|
||||||
|
map.insert("village", "village");
|
||||||
|
map.insert("town", "town");
|
||||||
|
map.insert("city", "city");
|
||||||
|
map
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parse_command(input: &str) -> Option<(&str, String)> {
|
||||||
|
let parts: Vec<&str> = input.trim().split_whitespace().collect();
|
||||||
|
if parts.len() < 2 {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let command = parts[0];
|
||||||
|
let argument = parts[1..].join(" ");
|
||||||
|
let height = if let Some((_, terminal_size::Height(h))) = terminal_size::terminal_size() {
|
||||||
|
h
|
||||||
|
} else {
|
||||||
|
24 // Default height if terminal size cannot be determined
|
||||||
|
};
|
||||||
|
if let Some(synonym) = COMMAND_SYNONYMS.get(command) {
|
||||||
|
// print!("{}", input.green());
|
||||||
|
add_text(format!("> {} {}", synonym, argument).as_str());
|
||||||
|
move_cursor(2, height - 2);
|
||||||
|
match synonym {
|
||||||
|
&"go" => {
|
||||||
|
if let Some(direction) = DIRECTIONS.get(argument.as_str()) {
|
||||||
|
print!("{}", input.green());
|
||||||
|
move_player(direction.0, direction.1, false);
|
||||||
|
} else {
|
||||||
|
println!("{}", format!("{} | unknown direction: {}", input, argument).red());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&"enter" => {
|
||||||
|
let events = get_map_events(get_current_map().unwrap().id.as_str())?;
|
||||||
|
let all_coords = crate::PLAYER_COORDS.lock().unwrap().clone();
|
||||||
|
let player_coords = all_coords.get(get_current_map().unwrap().id.as_str())?;
|
||||||
|
|
||||||
|
let evt = events.iter().find(|e| e.evt_type == "location" && e.location[0] == player_coords.0 && e.location[1] == player_coords.1);
|
||||||
|
if evt.is_some() {
|
||||||
|
let evt = evt.unwrap();
|
||||||
|
add_text("You entered a location.");
|
||||||
|
|
||||||
|
load_new_map(evt.command_id.as_str());
|
||||||
|
|
||||||
|
move_cursor(1, 1);
|
||||||
|
print!("Player: {} | Map: {}", crate::PLAYER_NAME.lock().unwrap().bold().underline(), get_current_map().unwrap().name.bold().underline());
|
||||||
|
|
||||||
|
// *crate::CURRENT_MAP_ID.lock().unwrap() = evt.command_id.clone();
|
||||||
|
} else {
|
||||||
|
add_text("! You cannot enter this location.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&"exit" => {
|
||||||
|
let events = get_map_events(get_current_map().unwrap().id.as_str())?;
|
||||||
|
let all_coords = crate::PLAYER_COORDS.lock().unwrap().clone();
|
||||||
|
let player_coords = all_coords.get(get_current_map().unwrap().id.as_str())?;
|
||||||
|
|
||||||
|
// print!("{:?}, {:?}", events, player_coords);
|
||||||
|
|
||||||
|
let evt = events.iter().find(|e| e.evt_type == "location" && e.location[0] == player_coords.0 && e.location[1] == player_coords.1);
|
||||||
|
if evt.is_some() {
|
||||||
|
let evt = evt.unwrap();
|
||||||
|
add_text("You exited a location.");
|
||||||
|
|
||||||
|
load_new_map(evt.command_id.as_str());
|
||||||
|
move_cursor(1, 1);
|
||||||
|
print!("Player: {} | Map: {}", crate::PLAYER_NAME.lock().unwrap().bold().underline(), get_current_map().unwrap().name.bold().underline());
|
||||||
|
|
||||||
|
// *crate::CURRENT_MAP_ID.lock().unwrap() = evt.command_id.clone();
|
||||||
|
} else {
|
||||||
|
add_text("! You cannot exit from this location.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&"describe" => {
|
||||||
|
match argument.as_str() {
|
||||||
|
"item" => {
|
||||||
|
let events = get_map_events(get_current_map().unwrap().id.as_str())?;
|
||||||
|
let all_coords = crate::PLAYER_COORDS.lock().unwrap().clone();
|
||||||
|
let player_coords = all_coords.get(get_current_map().unwrap().id.as_str())?;
|
||||||
|
|
||||||
|
let evt = events.iter().find(|e| e.evt_type == "item" && e.location[0] == player_coords.0 && e.location[1] == player_coords.1);
|
||||||
|
if evt.is_some() {
|
||||||
|
let evt = evt.unwrap();
|
||||||
|
add_text(evt.description.as_ref().unwrap_or(&"No description available.".to_string()).as_str());
|
||||||
|
} else {
|
||||||
|
add_text("! No item to describe here.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"tile" => {
|
||||||
|
let current_tile = crate::game::player::get_current_tile().unwrap();
|
||||||
|
add_text(current_tile.description.as_deref().unwrap_or("No description available."));
|
||||||
|
}
|
||||||
|
"location" => {
|
||||||
|
let map = get_current_map().unwrap();
|
||||||
|
add_text(map.description.as_str());
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
print!("{}", format!("{} | unknown argument: {}", input, argument).red());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&"take" => {
|
||||||
|
let events = get_map_events(get_current_map().unwrap().id.as_str())?;
|
||||||
|
let all_coords = crate::PLAYER_COORDS.lock().unwrap().clone();
|
||||||
|
let player_coords = all_coords.get(get_current_map().unwrap().id.as_str())?;
|
||||||
|
let mut flags = crate::FLAGS.lock().unwrap();
|
||||||
|
let evt = events.iter().find(|e| e.evt_type == "item" && e.location[0] == player_coords.0 && e.location[1] == player_coords.1);
|
||||||
|
|
||||||
|
if !evt.is_some() {
|
||||||
|
add_text("! Nothing to pick up here.");
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let evt = evt.unwrap();
|
||||||
|
|
||||||
|
if !flags.contains_key(evt.command_id.as_str()) {
|
||||||
|
add_text(format!("You picked up {}.", evt.command_id).as_str());
|
||||||
|
|
||||||
|
crate::PLAYER_INVENTORY.lock().unwrap().push(evt.command_id.clone());
|
||||||
|
flags.insert(evt.command_id.clone(), true);
|
||||||
|
} else {
|
||||||
|
add_text("! Nothing to pick up here.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&"talk" => {
|
||||||
|
let events = get_map_events(get_current_map().unwrap().id.as_str())?;
|
||||||
|
let all_coords = crate::PLAYER_COORDS.lock().unwrap().clone();
|
||||||
|
let player_coords = all_coords.get(get_current_map().unwrap().id.as_str())?;
|
||||||
|
|
||||||
|
let evt = events.iter().find(|e| e.evt_type == "npc" && e.location[0] == player_coords.0 && e.location[1] == player_coords.1);
|
||||||
|
|
||||||
|
match evt {
|
||||||
|
Some(e) => {
|
||||||
|
let npc = get_npc(&e.command_id);
|
||||||
|
match npc {
|
||||||
|
Some(n) => {
|
||||||
|
add_text(format!("You talked to {}.", n.name).as_str());
|
||||||
|
for line in n.dialogue.iter() {
|
||||||
|
add_text(line);
|
||||||
|
}
|
||||||
|
add_text("#(FFFF00)Use `say <number>` to respond");
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
add_text("! Strange NPC here, no dialogue available.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
add_text("! No NPC to talk to here.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&"say" => {
|
||||||
|
match argument.as_str() {
|
||||||
|
"1" => {
|
||||||
|
add_text("You said: 'Nothing'");
|
||||||
|
}
|
||||||
|
"2" => {
|
||||||
|
add_text("You said: 'Gate key'");
|
||||||
|
add_text("You acquired a key");
|
||||||
|
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
add_text("#(FF0000)! Unknown argument for 'say' command.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&"save" => {
|
||||||
|
let save_data = SaveData {
|
||||||
|
version: 1,
|
||||||
|
map_pack: crate::MAP_PACK.lock().unwrap().clone(),
|
||||||
|
player_name: crate::PLAYER_NAME.lock().unwrap().clone(),
|
||||||
|
last_save: chrono::Local::now().format("%Y-%m-%d %H:%M:%S").to_string(),
|
||||||
|
current_map_id: crate::CURRENT_MAP_ID.lock().unwrap().clone(),
|
||||||
|
health: *crate::PLAYER_HEALTH.lock().unwrap(),
|
||||||
|
stamina: *crate::PLAYER_STAMINA.lock().unwrap(),
|
||||||
|
coords: crate::PLAYER_COORDS.lock().unwrap().iter().map(|(k, v)| (k.to_string(), vec![v.0, v.1])).collect(),
|
||||||
|
inventory: crate::PLAYER_INVENTORY.lock().unwrap().clone(),
|
||||||
|
flags: crate::FLAGS.lock().unwrap().clone(),
|
||||||
|
lines_of_text: crate::LINES_OF_TEXT.lock().unwrap().clone(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let result = save_json("save.json", to_value(save_data).unwrap());
|
||||||
|
match result {
|
||||||
|
Ok(_) => {
|
||||||
|
add_text("#(00FF00)Progress saved");
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
add_text(format!("#(FF0000)Failed to save: {:?}", e).as_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
print!("{}", input.red());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some((synonym, argument))
|
||||||
|
} else {
|
||||||
|
print!("{}", input.red());
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_available_commands() {
|
||||||
|
let width = if let Some((terminal_size::Width(w), _)) = terminal_size::terminal_size() {
|
||||||
|
w
|
||||||
|
} else {
|
||||||
|
80 // Default height if terminal size cannot be determined
|
||||||
|
};
|
||||||
|
|
||||||
|
let events = get_map_events(get_current_map().unwrap().id.as_str()).unwrap();
|
||||||
|
let all_coords = crate::PLAYER_COORDS.lock().unwrap().clone();
|
||||||
|
let player_coords = all_coords.get(get_current_map().unwrap().id.as_str()).unwrap();
|
||||||
|
let evt_item = events.iter().find(|e| e.evt_type == "item" && e.location[0] == player_coords.0 && e.location[1] == player_coords.1);
|
||||||
|
let evt_location = events.iter().find(|e| e.evt_type == "location" && e.location[0] == player_coords.0 && e.location[1] == player_coords.1);
|
||||||
|
let evt_npc = events.iter().find(|e| e.evt_type == "npc" && e.location[0] == player_coords.0 && e.location[1] == player_coords.1);
|
||||||
|
let flags = crate::FLAGS.lock().unwrap();
|
||||||
|
|
||||||
|
// GO
|
||||||
|
move_cursor(width - 24, 4);
|
||||||
|
print!("GO | {} {} {} {}",
|
||||||
|
if move_player(0, -1, true) { "▲".green() } else { "▲".red() },
|
||||||
|
if move_player(0, 1, true) { "▼".green() } else { "▼".red() },
|
||||||
|
if move_player(-1, 0, true) { "◀".green() } else { "◀".red() },
|
||||||
|
if move_player(1, 0, true) { "▶".green() } else { "▶".red() }
|
||||||
|
);
|
||||||
|
|
||||||
|
// TAKE
|
||||||
|
move_cursor(width - 24, 5);
|
||||||
|
print!("TAKE | {}", if evt_item.is_some() && !flags.contains_key(evt_item.unwrap().command_id.as_str()) { "✔".green() } else { "✘".red() });
|
||||||
|
|
||||||
|
// ENTER/EXIT
|
||||||
|
move_cursor(width - 24, 6);
|
||||||
|
print!("ENTER | {}", if evt_location.is_some() { "✔".green() } else { "✘".red() });
|
||||||
|
|
||||||
|
// TALK
|
||||||
|
move_cursor(width - 24, 7);
|
||||||
|
print!("TALK | {}", if evt_npc.is_some() { "✔".green() } else { "✘".red() });
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
|
pub struct MapData {
|
||||||
|
pub default: bool,
|
||||||
|
pub map_required: bool,
|
||||||
|
pub starting_location: Vec<u8>,
|
||||||
|
pub name: String,
|
||||||
|
pub description: String,
|
||||||
|
pub id: String,
|
||||||
|
pub width: u16,
|
||||||
|
pub height: u16,
|
||||||
|
pub events: Vec<Events>,
|
||||||
|
pub tilemap: Vec<Vec<String>>,
|
||||||
|
pub tiles: HashMap<String, Tile>,
|
||||||
|
pub npcs: HashMap<String, NPC>
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
|
pub struct Events {
|
||||||
|
pub evt_type: String,
|
||||||
|
pub command_id: String,
|
||||||
|
pub name: String,
|
||||||
|
pub description: Option<String>,
|
||||||
|
pub location: Vec<u8>,
|
||||||
|
pub dialogue: Option<Vec<String>>
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
|
pub struct Tile {
|
||||||
|
pub name: String,
|
||||||
|
pub icon: Option<TileIcon>,
|
||||||
|
pub walkable: bool,
|
||||||
|
pub description: Option<String>,
|
||||||
|
pub bitmap: Vec<Vec<String>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
|
pub struct TileIcon {
|
||||||
|
pub char: String,
|
||||||
|
pub color: Vec<u8>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
|
pub struct NPC {
|
||||||
|
pub name: String,
|
||||||
|
pub description: String,
|
||||||
|
pub dialogue: Vec<String>,
|
||||||
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
pub mod json;
|
||||||
|
pub mod save;
|
|
@ -0,0 +1,18 @@
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
|
pub struct SaveData {
|
||||||
|
pub version: u16,
|
||||||
|
pub map_pack: String,
|
||||||
|
pub player_name: String,
|
||||||
|
pub last_save: String,
|
||||||
|
pub current_map_id: String,
|
||||||
|
pub health: u32,
|
||||||
|
pub stamina: u32,
|
||||||
|
pub coords: HashMap<String, Vec<u8>>,
|
||||||
|
pub inventory: Vec<String>,
|
||||||
|
pub flags: HashMap<String, bool>,
|
||||||
|
pub lines_of_text: Vec<String>
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,113 @@
|
||||||
|
use colored::Colorize;
|
||||||
|
use terminal_size::{Width, Height, terminal_size};
|
||||||
|
|
||||||
|
use crate::{parser::nlp::get_available_commands, tui::{map::draw_tile, text::refresh_text}, utils::{maps::get_current_map, os::move_cursor}};
|
||||||
|
|
||||||
|
pub fn draw_interface() {
|
||||||
|
move_cursor(0, 0);
|
||||||
|
|
||||||
|
let Some((Width(w), Height(h))) = terminal_size()
|
||||||
|
else {
|
||||||
|
eprintln!("Could not determine terminal size.");
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
let horizontal_char = "─";
|
||||||
|
let vertical_char = "│";
|
||||||
|
// let corner_char = "+";
|
||||||
|
let perp_down_char = "┬";
|
||||||
|
let perp_up_char = "┴";
|
||||||
|
let perp_left_char = "├";
|
||||||
|
let perp_right_char = "┤";
|
||||||
|
let corner_down_left_char = "┌";
|
||||||
|
let corner_down_right_char = "┐";
|
||||||
|
let corner_up_left_char = "└";
|
||||||
|
let corner_up_right_char = "┘";
|
||||||
|
|
||||||
|
let horizontal_line = horizontal_char.repeat(usize::from(w - 2));
|
||||||
|
|
||||||
|
print!("{}", String::from(corner_down_left_char) + &horizontal_line + corner_down_right_char);
|
||||||
|
for i in 0..(h - 2) {
|
||||||
|
if i == 0 {
|
||||||
|
print!("{}", String::from(vertical_char) + &" ".repeat(usize::from(w - 2)) + vertical_char);
|
||||||
|
} else if i == 1 {
|
||||||
|
print!("{}", String::from(perp_left_char) + &horizontal_char.repeat(16) + perp_down_char + &horizontal_char.repeat(usize::from(w - 19 - 25)) + perp_down_char + &horizontal_char.repeat(24) + perp_right_char);
|
||||||
|
} else if i == h - 9 || i == 10 {
|
||||||
|
print!("{}", String::from(perp_left_char) + &horizontal_char.repeat(16) + perp_right_char + &" ".repeat(usize::from(w - 19 - 25)) + vertical_char + &" ".repeat(24) + vertical_char);
|
||||||
|
} else if i < h - 4 {
|
||||||
|
print!("{}", String::from(vertical_char) + &" ".repeat(16) + vertical_char + &" ".repeat(usize::from(w - 19 - 25)) + vertical_char + &" ".repeat(24) + vertical_char);
|
||||||
|
} else if i == h - 4 {
|
||||||
|
print!("{}", String::from(perp_left_char) + &horizontal_char.repeat(16) + perp_up_char + &horizontal_char.repeat(usize::from(w - 19 - 25)) + perp_up_char + &horizontal_char.repeat(24) + perp_right_char);
|
||||||
|
} else {
|
||||||
|
print!("{}", String::from(vertical_char) + &" ".repeat(usize::from(w - 2)) + vertical_char);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
print!("{}", String::from(corner_up_left_char) + &horizontal_line + corner_up_right_char);
|
||||||
|
|
||||||
|
draw_player_data();
|
||||||
|
|
||||||
|
move_cursor(w - 21, 3);
|
||||||
|
print!("{}", "POSSIBLE ACTIONS".bold().underline());
|
||||||
|
|
||||||
|
move_cursor(1, 1);
|
||||||
|
print!("Player: {} | Map: {}", crate::PLAYER_NAME.lock().unwrap().bold().underline(), get_current_map().unwrap().name.bold().underline());
|
||||||
|
|
||||||
|
draw_tile();
|
||||||
|
get_available_commands();
|
||||||
|
|
||||||
|
refresh_text();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn clear_input() {
|
||||||
|
let Some((Width(width), Height(height))) = terminal_size()
|
||||||
|
else {
|
||||||
|
eprintln!("Could not determine terminal size.");
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
move_cursor(2, height - 2);
|
||||||
|
|
||||||
|
print!("{:width$}", "", width = usize::from(width - 4));
|
||||||
|
move_cursor(2, height - 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn draw_player_data() {
|
||||||
|
let Some((Width(_), Height(height))) = terminal_size()
|
||||||
|
else {
|
||||||
|
eprintln!("Could not determine terminal size.");
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
let y = height - 7;
|
||||||
|
|
||||||
|
let hp = u16::try_from(*crate::PLAYER_HEALTH.lock().unwrap()).unwrap();
|
||||||
|
let sp = u16::try_from(*crate::PLAYER_STAMINA.lock().unwrap()).unwrap();
|
||||||
|
|
||||||
|
let max_hp = 100;
|
||||||
|
let max_sp = 50;
|
||||||
|
|
||||||
|
move_cursor(1, y);
|
||||||
|
print!("HP: {}/{}", hp, max_hp);
|
||||||
|
move_cursor(1, y + 1);
|
||||||
|
let hp_blocks_count = ((hp as f64) / 100.0 * 16.0).ceil() as u8;
|
||||||
|
let mut hp_blocks = String::from("");
|
||||||
|
for _ in 0..hp_blocks_count {
|
||||||
|
hp_blocks.push('█');
|
||||||
|
}
|
||||||
|
for _ in hp_blocks_count..16 {
|
||||||
|
hp_blocks.push('_');
|
||||||
|
}
|
||||||
|
print!("{}", hp_blocks.red());
|
||||||
|
|
||||||
|
move_cursor(1, y + 2);
|
||||||
|
print!("SP: {}/{}", sp, max_sp);
|
||||||
|
move_cursor(1, y + 3);
|
||||||
|
let mp_blocks_count = ((sp as f64) / 50.0 * 16.0).ceil() as u8;
|
||||||
|
let mut mp_blocks = String::from("");
|
||||||
|
for _ in 0..mp_blocks_count {
|
||||||
|
mp_blocks.push('█');
|
||||||
|
}
|
||||||
|
for _ in mp_blocks_count..16 {
|
||||||
|
mp_blocks.push('_');
|
||||||
|
}
|
||||||
|
print!("{}", mp_blocks.yellow());
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
use colored::Colorize;
|
||||||
|
|
||||||
|
use crate::{game::player::get_current_tile, utils::os::move_cursor};
|
||||||
|
|
||||||
|
pub fn draw_tile() {
|
||||||
|
let tile = get_current_tile();
|
||||||
|
|
||||||
|
let bitmap = tile.clone().unwrap().bitmap;
|
||||||
|
|
||||||
|
for (y, row) in bitmap.iter().enumerate() {
|
||||||
|
move_cursor(1, (y as u16) + 3);
|
||||||
|
for (_, pixel) in row.iter().enumerate() {
|
||||||
|
let colors = tile.clone().unwrap().icon.unwrap().color;
|
||||||
|
|
||||||
|
print!("{}", pixel.on_truecolor(colors[0], colors[1], colors[2]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn draw_map() {
|
||||||
|
clear_map();
|
||||||
|
let map = crate::utils::maps::get_current_map().unwrap().clone();
|
||||||
|
let player_coords = crate::PLAYER_COORDS.lock().unwrap().clone();
|
||||||
|
let map_coords = *player_coords.get(map.id.as_str()).unwrap();
|
||||||
|
|
||||||
|
let starting_index = (
|
||||||
|
if map.width > 16 {
|
||||||
|
if map_coords.0 > 8 {
|
||||||
|
map_coords.0 as u16 - 8
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
} else { 0 },
|
||||||
|
if map.height > 8 {
|
||||||
|
if map_coords.1 > 4 {
|
||||||
|
map_coords.1 as u16 - 4
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
} else { 0 }
|
||||||
|
);
|
||||||
|
|
||||||
|
for (y, row) in map.tilemap.iter().skip(starting_index.1 as usize).enumerate() {
|
||||||
|
if y >= 8 { break }
|
||||||
|
move_cursor(1, (y as u16) + 12);
|
||||||
|
for (x, tile_id) in row.iter().skip(starting_index.0 as usize).enumerate() {
|
||||||
|
if x + starting_index.0 as usize == map_coords.0 as usize && y + starting_index.1 as usize == map_coords.1 as usize {
|
||||||
|
print!("{}", "X".bold().red().on_truecolor(228, 209, 178));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let tile = map.tiles.get(tile_id.as_str()).unwrap();
|
||||||
|
let icon = tile.icon.clone().unwrap();
|
||||||
|
print!("{}", icon.char.truecolor(icon.color[0], icon.color[1], icon.color[2]).on_truecolor(228, 209, 178));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn clear_map() {
|
||||||
|
for y in 0..8 {
|
||||||
|
move_cursor(1, 12 + y);
|
||||||
|
print!("{}", " ".repeat(16));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
use std::io::{self, Write};
|
||||||
|
|
||||||
|
pub fn display_splash_screen() {
|
||||||
|
let splash = r#"
|
||||||
|
▄▄▄█████▓ ██░ ██ ▓█████ ▄████ ▄▄▄ ███▄ ▄███▓▓█████
|
||||||
|
▓ ██▒ ▓▒▓██░ ██▒▓█ ▀ ██▒ ▀█▒▒████▄ ▓██▒▀█▀ ██▒▓█ ▀
|
||||||
|
▒ ▓██░ ▒░▒██▀▀██░▒███ ▒██░▄▄▄░▒██ ▀█▄ ▓██ ▓██░▒███
|
||||||
|
░ ▓██▓ ░ ░▓█ ░██ ▒▓█ ▄ ░▓█ ██▓░██▄▄▄▄██ ▒██ ▒██ ▒▓█ ▄
|
||||||
|
▒██▒ ░ ░▓█▒░██▓░▒████▒ ░▒▓███▀▒ ▓█ ▓██▒▒██▒ ░██▒░▒████▒
|
||||||
|
▒ ░░ ▒ ░░▒░▒░░ ▒░ ░ ░▒ ▒ ▒▒ ▓▒█░░ ▒░ ░ ░░░ ▒░ ░
|
||||||
|
░ ▒ ░▒░ ░ ░ ░ ░ ░ ░ ▒ ▒▒ ░░ ░ ░ ░ ░ ░
|
||||||
|
░ ░ ░░ ░ ░ ░ ░ ░ ░ ▒ ░ ░ ░
|
||||||
|
░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░
|
||||||
|
|
||||||
|
"#;
|
||||||
|
|
||||||
|
let stdout = io::stdout();
|
||||||
|
let mut handle = stdout.lock();
|
||||||
|
write!(handle, "{}", splash).unwrap();
|
||||||
|
handle.flush().unwrap();
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
pub mod menu;
|
||||||
|
pub mod interface;
|
||||||
|
pub mod map;
|
||||||
|
pub mod text;
|
|
@ -0,0 +1,117 @@
|
||||||
|
use colored::{ColoredString, Colorize};
|
||||||
|
use terminal_size::{Width, Height, terminal_size};
|
||||||
|
|
||||||
|
use crate::utils::os::{move_cursor, set_cursor_visibility};
|
||||||
|
|
||||||
|
// pub fn clear_text() {
|
||||||
|
// set_cursor_visibility(false);
|
||||||
|
// // let Some((Width(width), Height(height))) = terminal_size()
|
||||||
|
// // else {
|
||||||
|
// // eprintln!("Could not determine terminal size.");
|
||||||
|
// // return;
|
||||||
|
// // };
|
||||||
|
|
||||||
|
// // let text_area_width: u16 = width - 4 - 16 - 24;
|
||||||
|
|
||||||
|
// move_cursor(18, 1);
|
||||||
|
// // print!("{}", "x".repeat(usize::from(text_area_width)));
|
||||||
|
// *crate::LINES_OF_TEXT.lock().unwrap() = [].to_vec();
|
||||||
|
// }
|
||||||
|
|
||||||
|
fn color_text(text: &str) -> ColoredString {
|
||||||
|
if text.starts_with("#") {
|
||||||
|
let color_code_raw = &text[2..8];
|
||||||
|
let color_code = (
|
||||||
|
u8::from_str_radix(&color_code_raw[0..2], 16).unwrap_or(255),
|
||||||
|
u8::from_str_radix(&color_code_raw[2..4], 16).unwrap_or(255),
|
||||||
|
u8::from_str_radix(&color_code_raw[4..6], 16).unwrap_or(255)
|
||||||
|
);
|
||||||
|
let text = &text[9..].truecolor(color_code.0, color_code.1, color_code.2);
|
||||||
|
|
||||||
|
text.clone()
|
||||||
|
} else {
|
||||||
|
text.normal()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_text(text: &str) {
|
||||||
|
set_cursor_visibility(false);
|
||||||
|
let Some((Width(width), Height(height))) = terminal_size()
|
||||||
|
else {
|
||||||
|
eprintln!("Could not determine terminal size.");
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
let text_area_width: u16 = width - 4 - 16 - 24;
|
||||||
|
|
||||||
|
let mut lines_of_text = crate::LINES_OF_TEXT.lock().unwrap();
|
||||||
|
|
||||||
|
// move_cursor(18, (*lines_of_text + 1).try_into().unwrap_or(1));
|
||||||
|
|
||||||
|
let wrapped_lines = wrap_text(text, text_area_width);
|
||||||
|
for line in wrapped_lines {
|
||||||
|
lines_of_text.push(line);
|
||||||
|
print_text(lines_of_text.clone(), text_area_width, height - 6);
|
||||||
|
// move_cursor(18, (*lines_of_text + 1).try_into().unwrap_or(1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn wrap_text(text: &str, width: u16) -> Vec<String> {
|
||||||
|
let mut wrapped_lines = Vec::new();
|
||||||
|
let mut current_line = String::new();
|
||||||
|
let words: Vec<&str> = text.split_whitespace().collect();
|
||||||
|
|
||||||
|
for word in words {
|
||||||
|
if current_line.len() + word.len() + 1 > usize::from(width) {
|
||||||
|
wrapped_lines.push(current_line.trim().to_string());
|
||||||
|
current_line.clear();
|
||||||
|
}
|
||||||
|
if !current_line.is_empty() {
|
||||||
|
current_line.push(' ');
|
||||||
|
}
|
||||||
|
current_line.push_str(word);
|
||||||
|
}
|
||||||
|
|
||||||
|
if !current_line.is_empty() {
|
||||||
|
wrapped_lines.push(current_line.trim().to_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
wrapped_lines
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print_text(lines: Vec<String>, width: u16, height: u16) {
|
||||||
|
set_cursor_visibility(false);
|
||||||
|
|
||||||
|
let mut line_number = 3;
|
||||||
|
|
||||||
|
if lines.len() > usize::from(height) {
|
||||||
|
let start_index = lines.len() - usize::from(height);
|
||||||
|
let end_index = lines.len();
|
||||||
|
let visible_lines = &lines[start_index..end_index];
|
||||||
|
for line in visible_lines.iter() {
|
||||||
|
let text = color_text(&line);
|
||||||
|
move_cursor(18, line_number);
|
||||||
|
print!("{}{}", text, " ".repeat(usize::from(width) - line.len()));
|
||||||
|
line_number += 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for line in lines.iter() {
|
||||||
|
let text = color_text(&line);
|
||||||
|
move_cursor(18, line_number);
|
||||||
|
print!("{}", text);
|
||||||
|
line_number += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn refresh_text() {
|
||||||
|
let Some((Width(width), Height(height))) = terminal_size()
|
||||||
|
else {
|
||||||
|
eprintln!("Could not determine terminal size.");
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
let text_area_width: u16 = width - 4 - 16 - 24;
|
||||||
|
|
||||||
|
let lines_of_text = crate::LINES_OF_TEXT.lock().unwrap();
|
||||||
|
|
||||||
|
print_text(lines_of_text.to_vec(), text_area_width, height);
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
pub fn load_json(file_path: &str) -> Result<serde_json::Value, Box<dyn std::error::Error>> {
|
||||||
|
let file = std::fs::File::open(file_path)?;
|
||||||
|
let reader = std::io::BufReader::new(file);
|
||||||
|
let json_data: serde_json::Value = serde_json::from_reader(reader)?;
|
||||||
|
Ok(json_data)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn save_json(file_path: &str, data: serde_json::Value) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
let file = std::fs::File::create(file_path)?;
|
||||||
|
let writer = std::io::BufWriter::new(file);
|
||||||
|
serde_json::to_writer(writer, &data)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
use crate::structs::json::{Events, MapData, NPC};
|
||||||
|
|
||||||
|
pub fn get_map_data_by_id(map_id: &str) -> Option<MapData> {
|
||||||
|
let maps = crate::MAPS.lock().unwrap();
|
||||||
|
maps.iter().find(|map| map.id == map_id).cloned()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_current_map() -> Option<MapData> {
|
||||||
|
let current_map_id = crate::CURRENT_MAP_ID.lock().unwrap().clone();
|
||||||
|
let maps = crate::MAPS.lock().unwrap();
|
||||||
|
|
||||||
|
maps.iter().find(|map| map.id == current_map_id).cloned()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_map_events(map_id: &str) -> Option<Vec<Events>> {
|
||||||
|
let map = get_map_data_by_id(map_id)?;
|
||||||
|
Some(map.events)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_npc(npc_id: &str) -> Option<NPC> {
|
||||||
|
let map = get_current_map()?;
|
||||||
|
map.npcs.get(npc_id).cloned()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn load_new_map(map_id: &str) {
|
||||||
|
let map = get_map_data_by_id(map_id).unwrap();
|
||||||
|
*crate::CURRENT_MAP_ID.lock().unwrap() = map.id.clone();
|
||||||
|
let coords = crate::PLAYER_COORDS.lock().unwrap().clone();
|
||||||
|
if coords.get(&map.id).is_none() {
|
||||||
|
// If the player has no coordinates for this map, set starting location
|
||||||
|
let starting_location = map.starting_location.clone();
|
||||||
|
crate::PLAYER_COORDS.lock().unwrap().insert(map.id.clone(), (starting_location[0] as u8, starting_location[1] as u8));
|
||||||
|
}
|
||||||
|
// let new_coords = map.starting_location.clone();
|
||||||
|
// *crate::PLAYER_COORDS.lock().unwrap() = (new_coords[0] as u8, new_coords[1] as u8);
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
pub mod json;
|
||||||
|
pub mod os;
|
||||||
|
pub mod maps;
|
|
@ -0,0 +1,41 @@
|
||||||
|
use std::io::{self, Write};
|
||||||
|
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
pub fn move_cursor(x: u16, y: u16) {
|
||||||
|
{
|
||||||
|
let stdout = io::stdout();
|
||||||
|
let mut handle = stdout.lock();
|
||||||
|
write!(handle, "\x1b[{};{}H", y + 1, x + 1).unwrap();
|
||||||
|
handle.flush().unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
pub fn clear_console() {
|
||||||
|
{
|
||||||
|
let stdout = io::stdout();
|
||||||
|
let mut handle = stdout.lock();
|
||||||
|
write!(handle, "\x1b[2J\x1b[H").unwrap();
|
||||||
|
handle.flush().unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
pub fn set_terminal_title(title: &str) {
|
||||||
|
let stdout = io::stdout();
|
||||||
|
let mut handle = stdout.lock();
|
||||||
|
write!(handle, "\x1b]0;{}\x07", title).unwrap();
|
||||||
|
handle.flush().unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
pub fn set_cursor_visibility(enable: bool) {
|
||||||
|
let stdout = io::stdout();
|
||||||
|
let mut handle = stdout.lock();
|
||||||
|
if enable {
|
||||||
|
write!(handle, "\x1b[?25h").unwrap(); // Show cursor
|
||||||
|
} else {
|
||||||
|
write!(handle, "\x1b[?25l").unwrap(); // Hide cursor
|
||||||
|
}
|
||||||
|
handle.flush().unwrap();
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
pub mod linux;
|
||||||
|
pub mod windows;
|
||||||
|
|
||||||
|
pub fn move_cursor(x: u16, y: u16) {
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
linux::move_cursor(x, y);
|
||||||
|
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
windows::move_cursor(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn clear_console() {
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
linux::clear_console();
|
||||||
|
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
windows::clear_console();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_terminal_title(title: &str) {
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
linux::set_terminal_title(title);
|
||||||
|
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
windows::set_terminal_title(title);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_cursor_visibility(enable: bool) {
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
linux::set_cursor_visibility(enable);
|
||||||
|
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
windows::set_cursor_visibility(enable);
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
pub fn move_cursor(x: u16, y: u16) {
|
||||||
|
{
|
||||||
|
use std::io::{self, Write};
|
||||||
|
use std::os::windows::io::AsRawHandle;
|
||||||
|
use winapi::um::wincon::{SetConsoleCursorPosition, COORD};
|
||||||
|
|
||||||
|
let stdout = io::stdout();
|
||||||
|
let handle = stdout.as_raw_handle();
|
||||||
|
let coord = COORD { X: x as i16, Y: y as i16 };
|
||||||
|
unsafe {
|
||||||
|
SetConsoleCursorPosition(handle, coord);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
pub fn clear_console() {
|
||||||
|
{
|
||||||
|
use std::io::{self, Write};
|
||||||
|
use winapi::um::wincon::{GetConsoleScreenBufferInfo, COORD, CONSOLE_SCREEN_BUFFER_INFO, FillConsoleOutputCharacterA, FillConsoleOutputAttribute};
|
||||||
|
use winapi::um::winbase::GetStdHandle;
|
||||||
|
use winapi::um::winnt::STD_OUTPUT_HANDLE;
|
||||||
|
|
||||||
|
let stdout = io::stdout();
|
||||||
|
let handle = unsafe { GetStdHandle(STD_OUTPUT_HANDLE) };
|
||||||
|
let mut csbi: CONSOLE_SCREEN_BUFFER_INFO = unsafe { std::mem::zeroed() };
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
GetConsoleScreenBufferInfo(handle, &mut csbi);
|
||||||
|
let size = csbi.dwSize;
|
||||||
|
let coord = COORD { X: 0, Y: 0 };
|
||||||
|
FillConsoleOutputCharacterA(handle, b' ' as u8, (size.X * size.Y) as u32, coord, std::ptr::null_mut());
|
||||||
|
FillConsoleOutputAttribute(handle, csbi.wAttributes, (size.X * size.Y) as u32, coord, std::ptr::null_mut());
|
||||||
|
SetConsoleCursorPosition(handle, coord);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
pub fn set_terminal_title(title: &str) {
|
||||||
|
use std::io::{self, Write};
|
||||||
|
use winapi::um::wincon::SetConsoleTitleA;
|
||||||
|
|
||||||
|
let title_bytes = title.as_bytes();
|
||||||
|
let c_title = std::ffi::CString::new(title_bytes).unwrap();
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
SetConsoleTitleA(c_title.as_ptr());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
pub fn set_cursor_visibility(enable: bool) {
|
||||||
|
use std::io::{self, Write};
|
||||||
|
use winapi::um::wincon::{SetConsoleCursorInfo, CONSOLE_CURSOR_INFO};
|
||||||
|
|
||||||
|
let stdout = io::stdout();
|
||||||
|
let handle = stdout.as_raw_handle();
|
||||||
|
let mut cursor_info: CONSOLE_CURSOR_INFO = unsafe { std::mem::zeroed() };
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
SetConsoleCursorInfo(handle, &mut cursor_info);
|
||||||
|
cursor_info.bVisible = if enable { 1 } else { 0 };
|
||||||
|
SetConsoleCursorInfo(handle, &cursor_info);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue