├── .clang-format ├── .clang-tidy ├── .github └── workflows │ ├── build.yml │ ├── docs.yml │ └── lint.yml ├── .gitignore ├── .gitmodules ├── CMakeLists.txt ├── assets ├── logo-square.png ├── logo-square.svg ├── logo.png └── logo.svg ├── changelog.md ├── contributing.md ├── docs ├── CNAME ├── SUMMARY.md ├── assets │ ├── icons │ │ ├── spacer-bool.png │ │ ├── spacer-class.png │ │ ├── spacer-color.png │ │ ├── spacer-enum.png │ │ ├── spacer-float.png │ │ ├── spacer-folder.png │ │ ├── spacer-int.png │ │ ├── spacer-misc.png │ │ ├── spacer-string.png │ │ └── spacer-vec.png │ ├── javascript │ │ ├── extra.js │ │ └── mathjax.js │ ├── logo-square.png │ ├── logo.png │ └── stylesheets │ │ └── extra.css ├── engine │ ├── datatypes.md │ ├── encodings │ │ ├── binary-chunked.md │ │ └── binary.md │ ├── formats │ │ ├── animation.md │ │ ├── archive.md │ │ ├── bytecode.md │ │ ├── font.md │ │ ├── savegame.md │ │ ├── script_binaries.md │ │ ├── texture.md │ │ └── vdf.md │ ├── objects │ │ ├── _generate.py │ │ ├── _template.mdt │ │ ├── oCCSTrigger.md │ │ ├── oCCSTrigger.yml │ │ ├── oCInfo.md │ │ ├── oCInfo.yml │ │ ├── oCInfoManager.md │ │ ├── oCInfoManager.yml │ │ ├── oCItem.md │ │ ├── oCItem.yml │ │ ├── oCLogManager.md │ │ ├── oCLogManager.yml │ │ ├── oCLogTopic.md │ │ ├── oCLogTopic.yml │ │ ├── oCMOB.md │ │ ├── oCMOB.yml │ │ ├── oCMission.md │ │ ├── oCMission.yml │ │ ├── oCMissionManager.md │ │ ├── oCMissionManager.yml │ │ ├── oCMobBed.md │ │ ├── oCMobBed.yml │ │ ├── oCMobContainer.md │ │ ├── oCMobContainer.yml │ │ ├── oCMobDoor.md │ │ ├── oCMobFire.md │ │ ├── oCMobInter.md │ │ ├── oCMobLadder.md │ │ ├── oCMobLockable.md │ │ ├── oCMobSwitch.md │ │ ├── oCMobWheel.md │ │ ├── oCSavegameInfo.md │ │ ├── oCTouchDamage.md │ │ ├── oCTriggerChangeLevel.md │ │ ├── oCTriggerScript.md │ │ ├── oCVob.md │ │ ├── oCZoneMusic.md │ │ ├── oCZoneMusicDefault.md │ │ ├── zCCSCamera.md │ │ ├── zCCamTrj_KeyFrame.md │ │ ├── zCCodeMaster.md │ │ ├── zCDecal.md │ │ ├── zCEarthquake.md │ │ ├── zCEffect.md │ │ ├── zCMessageFilter.md │ │ ├── zCMover.md │ │ ├── zCMoverController.md │ │ ├── zCPFXController.md │ │ ├── zCTouchDamage.md │ │ ├── zCTrigger.md │ │ ├── zCTriggerBase.md │ │ ├── zCTriggerList.md │ │ ├── zCTriggerUntouch.md │ │ ├── zCTriggerWorldStart.md │ │ ├── zCVisual.md │ │ ├── zCVob.md │ │ ├── zCVobAnimate.md │ │ ├── zCVobLensFlare.md │ │ ├── zCVobLevelCompo.md │ │ ├── zCVobLight.md │ │ ├── zCVobScreenFX.md │ │ ├── zCVobSound.md │ │ ├── zCVobSoundDaytime.md │ │ ├── zCVobSpot.md │ │ ├── zCVobStair.md │ │ ├── zCVobStartpoint.md │ │ ├── zCZone.md │ │ ├── zCZoneVobFarPlane.md │ │ ├── zCZoneVobFarPlaneDefault.md │ │ ├── zCZoneZFog.md │ │ └── zCZoneZFogDefault.md │ └── overview.md ├── index.md └── library │ ├── api │ ├── archive.md │ ├── cutscene-library.md │ ├── daedalus-script.md │ ├── daedalus-vm.md │ ├── font.md │ ├── mesh.md │ ├── model-animation.md │ ├── model-hierarchy.md │ ├── model-mesh.md │ ├── model-script.md │ ├── model.md │ ├── morph-mesh.md │ ├── multi-resolution-mesh.md │ ├── save-game.md │ ├── texture.md │ ├── virtual-file-system.md │ └── world.md │ ├── misc │ └── v1.2-to-v1.3.md │ ├── overview.md │ ├── quickstart.md │ └── reference.md ├── examples ├── CMakeLists.txt ├── load_vdf.cc ├── load_zen.cc ├── run_interpreter.cc └── zen2zen.cc ├── include └── zenkit │ ├── Archive.hh │ ├── Boxes.hh │ ├── CutsceneLibrary.hh │ ├── DaedalusScript.hh │ ├── DaedalusVm.hh │ ├── Date.hh │ ├── Error.hh │ ├── Font.hh │ ├── Library.hh │ ├── Logger.hh │ ├── Material.hh │ ├── Mesh.hh │ ├── Misc.hh │ ├── Mmap.hh │ ├── Model.hh │ ├── ModelAnimation.hh │ ├── ModelHierarchy.hh │ ├── ModelMesh.hh │ ├── ModelScript.hh │ ├── MorphMesh.hh │ ├── MultiResolutionMesh.hh │ ├── Object.hh │ ├── SaveGame.hh │ ├── SoftSkinMesh.hh │ ├── Stream.hh │ ├── Texture.hh │ ├── Vfs.hh │ ├── World.hh │ ├── addon │ ├── daedalus.hh │ └── texcvt.hh │ ├── vobs │ ├── Camera.hh │ ├── Light.hh │ ├── Misc.hh │ ├── MovableObject.hh │ ├── Sound.hh │ ├── Trigger.hh │ ├── VirtualObject.hh │ └── Zone.hh │ └── world │ ├── BspTree.hh │ ├── VobTree.hh │ └── WayNet.hh ├── license.md ├── mkdocs.yml ├── readme.md ├── src ├── Archive.cc ├── Boxes.cc ├── CutsceneLibrary.cc ├── DaedalusScript.cc ├── DaedalusVm.cc ├── Date.cc ├── Error.cc ├── Font.cc ├── Internal.hh ├── Logger.cc ├── Material.cc ├── Mesh.cc ├── Misc.cc ├── MmapPosix.cc ├── MmapWin32.cc ├── Model.cc ├── ModelAnimation.cc ├── ModelHierarchy.cc ├── ModelMesh.cc ├── ModelScript.cc ├── ModelScriptDsl.cc ├── ModelScriptDsl.hh ├── MorphMesh.cc ├── MultiResolutionMesh.cc ├── Object.cc ├── SaveGame.cc ├── SoftSkinMesh.cc ├── Stream.cc ├── Texture.cc ├── Vfs.cc ├── World.cc ├── addon │ ├── daedalus.cc │ └── texcvt.cc ├── archive │ ├── ArchiveAscii.cc │ ├── ArchiveAscii.hh │ ├── ArchiveBinary.cc │ ├── ArchiveBinary.hh │ ├── ArchiveBinsafe.cc │ └── ArchiveBinsafe.hh ├── vobs │ ├── Camera.cc │ ├── Light.cc │ ├── Misc.cc │ ├── MovableObject.cc │ ├── Sound.cc │ ├── Trigger.cc │ ├── VirtualObject.cc │ └── Zone.cc └── world │ ├── BspTree.cc │ ├── VobTree.cc │ └── WayNet.cc ├── support └── BuildSupport.cmake ├── tests ├── TestArchive.cc ├── TestCutsceneLibrary.cc ├── TestDaedalusScript.cc ├── TestFont.cc ├── TestMaterial.cc ├── TestModel.cc ├── TestModelAnimation.cc ├── TestModelHierarchy.cc ├── TestModelMesh.cc ├── TestModelScript.cc ├── TestMorphMesh.cc ├── TestMultiResolutionMesh.cc ├── TestSaveGame.cc ├── TestStream.cc ├── TestTexture.cc ├── TestVfs.cc ├── TestVobsG1.cc ├── TestVobsG2.cc ├── TestWorld.cc └── samples │ ├── G1 │ ├── DEMON_DIE_BODY.MAT │ ├── FONT_OLD_10_WHITE_HI.FNT │ ├── HUMANS-S_FISTRUN.MAN │ ├── Save │ │ ├── LOG.SAV │ │ ├── SAVEDAT.SAV │ │ ├── SAVEHDR.SAV │ │ ├── SAVEINFO.SAV │ │ ├── THUMB.SAV │ │ └── WORLD.SAV │ ├── SaveFast │ │ ├── LOG.SAV │ │ ├── SAVEDAT.SAV │ │ ├── SAVEHDR.SAV │ │ ├── SAVEINFO.SAV │ │ ├── THUMB.SAV │ │ └── WORLD.SAV │ └── VOb │ │ ├── oCCSTrigger.zen │ │ ├── oCItem.zen │ │ ├── oCMOB.zen │ │ ├── oCMobContainer.zen │ │ ├── oCMobDoor.zen │ │ ├── oCMobFire.zen │ │ ├── oCMobInter.zen │ │ ├── oCTriggerChangeLevel.zen │ │ ├── oCTriggerScript.zen │ │ ├── oCZoneMusic.zen │ │ ├── zCMover.zen │ │ ├── zCPFXControler.zen │ │ ├── zCTriggerList.zen │ │ ├── zCVob.zen │ │ ├── zCVobAnimate.zen │ │ ├── zCVobLensFlare.zen │ │ ├── zCVobLight.zen │ │ ├── zCVobSound.zen │ │ ├── zCVobSoundDaytime.zen │ │ ├── zCZoneVobFarPlane.zen │ │ └── zCZoneZFog.zen │ ├── G2 │ ├── DEMON_DIE_BODY.MAT │ ├── FONT_OLD_10_WHITE_HI.FNT │ ├── HUMANS-S_FISTRUN.MAN │ ├── Save │ │ ├── LOG.SAV │ │ ├── NEWWORLD.SAV │ │ ├── SAVEDAT.SAV │ │ ├── SAVEHDR.SAV │ │ ├── SAVEINFO.SAV │ │ └── THUMB.SAV │ ├── SaveFast │ │ ├── NEWWORLD.SAV │ │ ├── OLDWORLD.SAV │ │ ├── SAVEDAT.SAV │ │ ├── SAVEHDR.SAV │ │ ├── SAVEINFO.SAV │ │ └── THUMB.SAV │ └── VOb │ │ ├── oCItem.zen │ │ ├── oCMOB.zen │ │ ├── oCMobContainer.zen │ │ ├── oCMobDoor.zen │ │ ├── oCMobFire.zen │ │ ├── oCMobInter.zen │ │ ├── oCTouchDamage.zen │ │ ├── oCTriggerChangeLevel.zen │ │ ├── oCTriggerScript.zen │ │ ├── oCZoneMusic.zen │ │ ├── zCCSCamera.zen │ │ ├── zCCodeMaster.zen │ │ ├── zCEarthquake.zen │ │ ├── zCMessageFilter.zen │ │ ├── zCMover.zen │ │ ├── zCPFXControler.zen │ │ ├── zCTrigger.zen │ │ ├── zCTriggerList.zen │ │ ├── zCTriggerUntouch.zen │ │ ├── zCTriggerWorldStart.zen │ │ ├── zCVob.zen │ │ ├── zCVobAnimate.zen │ │ ├── zCVobLight.zen │ │ ├── zCVobSound.zen │ │ ├── zCVobSoundDaytime.zen │ │ ├── zCZoneVobFarPlane.zen │ │ └── zCZoneZFog.zen │ ├── ascii.zen │ ├── basic.bin │ ├── basic.vdf │ ├── basic.vdf.dir │ ├── README.md │ ├── config.yml │ └── licenses │ │ ├── MIT.md │ │ └── gpl │ │ ├── GPL-3.0.md │ │ └── LGPL-3.0.md │ ├── binary.zen │ ├── empty.txt │ ├── erz.expected.0.bin │ ├── erz.tex │ ├── hierarchy0.mdh │ ├── menu.dat.readme │ ├── mesh0.mrm │ ├── morph0.mmb │ ├── ou.bin.readme │ ├── secretdoor.mdm │ ├── smoke_waterpipe.mdm │ ├── waran.mds │ ├── waran.msb │ └── world.zen.readme └── vendor └── CMakeLists.txt /.clang-format: -------------------------------------------------------------------------------- 1 | AlignAfterOpenBracket: Align 2 | AlignConsecutiveMacros: None 3 | AlignConsecutiveAssignments: None 4 | AlignConsecutiveDeclarations: None 5 | AlignEscapedNewlines: Right 6 | AlignOperands: false 7 | AlignTrailingComments: true 8 | AllowAllArgumentsOnNextLine: false 9 | AllowAllConstructorInitializersOnNextLine: true 10 | AllowAllParametersOfDeclarationOnNextLine: false 11 | AllowShortBlocksOnASingleLine: Empty 12 | AllowShortCaseLabelsOnASingleLine: false 13 | AllowShortFunctionsOnASingleLine: Empty 14 | AllowShortIfStatementsOnASingleLine: WithoutElse 15 | AllowShortLambdasOnASingleLine: All 16 | AllowShortLoopsOnASingleLine: false 17 | AlwaysBreakAfterDefinitionReturnType: None 18 | AlwaysBreakAfterReturnType: None 19 | AlwaysBreakBeforeMultilineStrings: false 20 | AlwaysBreakTemplateDeclarations: Yes 21 | BinPackArguments: false 22 | BinPackParameters: false 23 | BreakBeforeBinaryOperators: None 24 | BreakBeforeBraces: Attach 25 | BreakBeforeTernaryOperators: true 26 | BreakConstructorInitializers: BeforeColon 27 | BreakInheritanceList: BeforeColon 28 | ColumnLimit: 120 29 | CompactNamespaces: false 30 | Cpp11BracedListStyle: true 31 | FixNamespaceComments: true 32 | IncludeBlocks: Preserve 33 | IndentCaseLabels: false 34 | IndentWidth: 4 35 | Language: Cpp 36 | NamespaceIndentation: All 37 | PointerAlignment: Left 38 | ReflowComments: true 39 | SortUsingDeclarations: true 40 | SpaceAfterCStyleCast: true 41 | SpaceAfterLogicalNot: false 42 | SpaceAfterTemplateKeyword: true 43 | SpaceBeforeAssignmentOperators: true 44 | SpaceBeforeCpp11BracedList: true 45 | SpaceBeforeCtorInitializerColon: true 46 | SpaceBeforeInheritanceColon: true 47 | SpaceBeforeParens: ControlStatements 48 | SpaceBeforeRangeBasedForLoopColon: true 49 | SpaceInEmptyParentheses: false 50 | SpacesInAngles: false 51 | SpacesBeforeTrailingComments: 1 52 | TabWidth: 4 53 | UseTab: ForIndentation 54 | AccessModifierOffset: -4 55 | IndentPPDirectives: BeforeHash 56 | QualifierAlignment: Right 57 | -------------------------------------------------------------------------------- /.clang-tidy: -------------------------------------------------------------------------------- 1 | Checks: '-*,bugprone-*,cppcoreguidelines-*,concurrency-*,clang-analyzer-*,hicpp-*,misc-*,modernize-*,performance-*,' 2 | 'portability-*,readability-*,-modernize-use-trailing-return-type,-cppcoreguidelines-pro-bounds-pointer-arithmetic,' 3 | '-cppcoreguidelines-prefer-member-initializer' 4 | WarningsAsErrors: '*' 5 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: 'Build' 2 | on: 3 | - 'push' 4 | - 'pull_request' 5 | jobs: 6 | linux: 7 | name: "Linux" 8 | strategy: 9 | fail-fast: false 10 | matrix: 11 | build_type: 12 | - 'Release' 13 | - 'Debug' 14 | image: 15 | - 'clang-11' 16 | - 'clang-14' 17 | - 'gcc-9' 18 | - 'gcc-12' 19 | runs-on: 'ubuntu-latest' 20 | container: 21 | image: 'ghcr.io/lmichaelis/images:${{matrix.image}}' 22 | steps: 23 | - uses: 'actions/checkout@v3' 24 | - name: 'Configure' 25 | run: 'cmake -B build -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DZK_BUILD_EXAMPLES=ON -DZK_BUILD_TESTS=ON' 26 | - name: 'Build' 27 | run: 'cmake --build build' 28 | - name: 'Test' 29 | working-directory: 'build/' 30 | run: 'ctest --output-on-failure' 31 | 32 | macos: 33 | name: "MacOS" 34 | strategy: 35 | fail-fast: false 36 | matrix: 37 | xcode: 38 | - '15' 39 | build_type: [ 'Debug', 'Release' ] 40 | env: 41 | ASAN_OPTIONS: 'detect_container_overflow=0' 42 | runs-on: 'macos-latest' 43 | steps: 44 | - uses: 'actions/checkout@v3' 45 | - uses: 'maxim-lobanov/setup-xcode@v1' 46 | with: 47 | xcode-version: '${{matrix.xcode}}' 48 | - name: 'Configure' 49 | run: 'cmake -B build -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DZK_BUILD_EXAMPLES=ON -DZK_BUILD_TESTS=ON -DBUILD_SQUISH_WITH_SSE2=OFF' 50 | - name: 'Build' 51 | run: 'cmake --build build' 52 | - name: 'Test' 53 | working-directory: 'build/' 54 | run: 'ctest --output-on-failure' 55 | 56 | windows: 57 | name: "Windows" 58 | runs-on: 'windows-2019' 59 | steps: 60 | - uses: 'actions/checkout@v3' 61 | with: 62 | submodules: 'recursive' 63 | - name: 'Configure' 64 | shell: 'bash' 65 | run: 'cmake -B build -G "Visual Studio 16 2019" -DCMAKE_BUILD_TYPE=Release -DZK_BUILD_EXAMPLES=ON -DZK_BUILD_TESTS=ON -DCMAKE_POLICY_VERSION_MINIMUM=3.5' 66 | - name: 'Build' 67 | run: 'cmake --build build --config Release -j 2' 68 | - name: 'Test' 69 | working-directory: 'build/' 70 | run: 'ctest -C Release --output-on-failure' 71 | -------------------------------------------------------------------------------- /.github/workflows/docs.yml: -------------------------------------------------------------------------------- 1 | name: 'Documentation' 2 | on: 3 | push: 4 | branches: 5 | - 'main' 6 | paths: 7 | - 'docs/**' 8 | - '.github/workflows/docs.yml' 9 | - 'mkdocs.yml' 10 | permissions: 11 | contents: 'write' 12 | jobs: 13 | deploy: 14 | name: 'Publish Documentation' 15 | runs-on: 'ubuntu-latest' 16 | steps: 17 | - uses: 'actions/checkout@v3' 18 | - uses: 'actions/setup-python@v4' 19 | with: 20 | python-version: '3.x' 21 | - run: 'pip install mkdocs-material==9.5.18 mkdocs-section-index mkdocs-literate-nav' 22 | - run: 'mkdocs gh-deploy -b "auto/pages" --force' 23 | -------------------------------------------------------------------------------- /.github/workflows/lint.yml: -------------------------------------------------------------------------------- 1 | name: 'Lint' 2 | on: 3 | - 'push' 4 | - 'pull_request' 5 | jobs: 6 | format: 7 | name: 'Formatting' 8 | runs-on: 'ubuntu-latest' 9 | container: 10 | image: 'docker.io/ubuntu:latest' 11 | steps: 12 | - name: "Dependencies" 13 | run: 'apt update && apt install -y git clang-format' 14 | - uses: 'actions/checkout@v3' 15 | with: 16 | submodules: 'recursive' 17 | - name: 'clang-format' 18 | shell: 'bash' 19 | run: 'find include src tests examples -iname "*.hh" -or -iname "*.cc" | xargs clang-format --dry-run --style=file --Werror' 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.build/ 2 | /.idea/ 3 | /.vscode/ 4 | /.cache/ 5 | 6 | /build/ 7 | /cmake-build-*/ 8 | /data/ 9 | /site/ 10 | 11 | *.proprietary.* 12 | *.env 13 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "vendor/doctest"] 2 | path = vendor/doctest 3 | url = https://github.com/doctest/doctest.git 4 | [submodule "vendor/mio"] 5 | path = vendor/mio 6 | url = https://github.com/mandreyel/mio.git 7 | [submodule "vendor/libsquish"] 8 | path = vendor/libsquish 9 | url = https://github.com/lmichaelis/phoenix-libsquish.git 10 | -------------------------------------------------------------------------------- /assets/logo-square.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/assets/logo-square.png -------------------------------------------------------------------------------- /assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/assets/logo.png -------------------------------------------------------------------------------- /contributing.md: -------------------------------------------------------------------------------- 1 | # How to contribute to _ZenKit_ 2 | 3 | If you'd like to add a feature or fix a bug, you're more than welcome to help! You can grab one of the open issues and 4 | start to work on it, too. 5 | 6 | There are some conventions I'd ask you to keep in mind while writing code for _ZenKit_. I've outlined them below. 7 | 8 | ## Conventions 9 | 10 | There are a few things that should be followed to keep the codebase consistent. 11 | 12 | ### Git 13 | 14 | Your commits should be small. Avoid bundling multiple changes relating to (for example) multiple different issues or bugs 15 | into one commit. Rather, create multiple smaller commits, each self-contained only changing one part of the logic[^1]. 16 | 17 | [^1]: For example, if there is an issue with the VM and you change something, then add a new API to the `DaedalusScript`, 18 | those should be two separate commits. 19 | 20 | ### C++ code 21 | 22 | * Class names are `PascalCase` 23 | * Function names are `snake_case` and private member functions are prefixed with an underscore 24 | * Member variables are `snake_case` and private member variables are prefixed with `_m_` 25 | 26 | Use `clang-format`. While the CI pipeline will complain about noncompliance, you can avoid unnecessary commits by 27 | checking your code before pushing. 28 | 29 | Some miscellaneous conventions apply as well: 30 | 31 | * **Never** write `using namespace` in any header file and avoid doing it library source code as well 32 | * There should be no mutable global state (all global variables should be `const` or `static constexpr`) 33 | * Constructors should only construct objects. If your constructor affects any other state not tied to the object it's 34 | constructing, it should probably be a function instead. 35 | -------------------------------------------------------------------------------- /docs/CNAME: -------------------------------------------------------------------------------- 1 | zk.gothickit.dev 2 | -------------------------------------------------------------------------------- /docs/assets/icons/spacer-bool.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/docs/assets/icons/spacer-bool.png -------------------------------------------------------------------------------- /docs/assets/icons/spacer-class.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/docs/assets/icons/spacer-class.png -------------------------------------------------------------------------------- /docs/assets/icons/spacer-color.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/docs/assets/icons/spacer-color.png -------------------------------------------------------------------------------- /docs/assets/icons/spacer-enum.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/docs/assets/icons/spacer-enum.png -------------------------------------------------------------------------------- /docs/assets/icons/spacer-float.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/docs/assets/icons/spacer-float.png -------------------------------------------------------------------------------- /docs/assets/icons/spacer-folder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/docs/assets/icons/spacer-folder.png -------------------------------------------------------------------------------- /docs/assets/icons/spacer-int.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/docs/assets/icons/spacer-int.png -------------------------------------------------------------------------------- /docs/assets/icons/spacer-misc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/docs/assets/icons/spacer-misc.png -------------------------------------------------------------------------------- /docs/assets/icons/spacer-string.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/docs/assets/icons/spacer-string.png -------------------------------------------------------------------------------- /docs/assets/icons/spacer-vec.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/docs/assets/icons/spacer-vec.png -------------------------------------------------------------------------------- /docs/assets/javascript/extra.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2024 GothicKit Contributors. 3 | * SPDX-License-Identifier: MIT 4 | */ 5 | 6 | const SPACER_TYPE_NAMES = new Map([ 7 | ["sp-folder", "Property Group"], 8 | ["sp-int", "Integer"], 9 | ["sp-float", "Float"], 10 | ["sp-string", "String"], 11 | ["sp-misc", "Raw"], 12 | ["sp-vec", "3D Vector"], 13 | ["sp-bool", "Boolean"], 14 | ["sp-enum", "Enum"], 15 | ["sp-class", "Class"], 16 | ["sp-color", "Color"], 17 | ["sp-none", ""], 18 | ]); 19 | 20 | document$.subscribe(() => { 21 | for (const [k, v] of SPACER_TYPE_NAMES) { 22 | const items = document.querySelectorAll(`.${k}`) 23 | items.forEach(e => { 24 | e.title = v; 25 | }) 26 | } 27 | }) 28 | -------------------------------------------------------------------------------- /docs/assets/javascript/mathjax.js: -------------------------------------------------------------------------------- 1 | window.MathJax = { 2 | tex: { 3 | inlineMath: [["\\(", "\\)"]], 4 | displayMath: [["\\[", "\\]"]], 5 | processEscapes: true, 6 | processEnvironments: true 7 | }, 8 | options: { 9 | ignoreHtmlClass: ".*|", 10 | processHtmlClass: "arithmatex" 11 | } 12 | }; 13 | 14 | document$.subscribe(() => { 15 | MathJax.typesetPromise() 16 | }) 17 | -------------------------------------------------------------------------------- /docs/assets/logo-square.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/docs/assets/logo-square.png -------------------------------------------------------------------------------- /docs/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/docs/assets/logo.png -------------------------------------------------------------------------------- /docs/assets/stylesheets/extra.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2022 Luis Michaelis 3 | * SPDX-License-Identifier: MIT 4 | */ 5 | 6 | :root > * { 7 | --md-default-bg-color: #222222; 8 | --md-code-bg-color: #282828; 9 | --md-footer-bg-color: #282828; 10 | --md-footer-bg-color--dark: #282828; 11 | } 12 | 13 | .md-typeset .md-annotation__index > ::before { 14 | content: attr(data-md-annotation-id); 15 | } 16 | 17 | .md-typeset :focus-within > .md-annotation__index > ::before { 18 | transform: none; 19 | } 20 | 21 | ul .sp-folder, 22 | ul .sp-class, 23 | ul .sp-int, 24 | ul .sp-string, 25 | ul .sp-misc, 26 | ul .sp-bool, 27 | ul .sp-enum, 28 | ul .sp-vec, 29 | ul .sp-float, 30 | ul .sp-color { 31 | margin: 0 0 0 0.5em !important; 32 | padding: 0 !important; 33 | list-style-type: none; 34 | font-family: monospace; 35 | } 36 | 37 | .sp-folder::before { 38 | content: url("/assets/icons/spacer-folder.png"); 39 | padding-right: 0.5em; 40 | } 41 | 42 | .sp-int::before { 43 | content: url("/assets/icons/spacer-int.png"); 44 | padding-right: 0.5em; 45 | } 46 | 47 | .sp-float::before { 48 | content: url("/assets/icons/spacer-float.png"); 49 | padding-right: 0.5em; 50 | } 51 | 52 | .sp-string::before { 53 | content: url("/assets/icons/spacer-string.png"); 54 | padding-right: 0.5em; 55 | } 56 | 57 | .sp-misc::before { 58 | content: url("/assets/icons/spacer-misc.png"); 59 | padding-right: 0.5em; 60 | } 61 | 62 | .sp-vec::before { 63 | content: url("/assets/icons/spacer-vec.png"); 64 | padding-right: 0.5em; 65 | } 66 | 67 | .sp-bool::before { 68 | content: url("/assets/icons/spacer-bool.png"); 69 | padding-right: 0.5em; 70 | } 71 | 72 | .sp-enum::before { 73 | content: url("/assets/icons/spacer-enum.png"); 74 | padding-right: 0.5em; 75 | } 76 | 77 | .sp-class::before { 78 | content: url("/assets/icons/spacer-class.png"); 79 | padding-right: 0.5em; 80 | } 81 | 82 | .sp-color::before { 83 | content: url("/assets/icons/spacer-color.png"); 84 | padding-right: 0.5em; 85 | } 86 | 87 | .sp-none { 88 | margin-top: 0 !important; 89 | margin-bottom: 0 !important; 90 | list-style: none; 91 | font-family: monospace; 92 | } 93 | -------------------------------------------------------------------------------- /docs/engine/encodings/binary-chunked.md: -------------------------------------------------------------------------------- 1 | # Chunked Binary Encoding 2 | 3 | !!! abstract inline end "Quick Infos" 4 | **Type:** Encoding
5 | **Class Name:** `zCFileBIN`
6 | **Used By:** [`zCModelAni`](../formats/animation.md) 7 | 8 | Many asset files are encoded in [binary](binary.md), splitting the data up into sections called chunks. Each chunk 9 | consists of a type identifier, its size and the actual data wrapped inside it. Files using the chunked binary encoding 10 | do not contain data outside of chunks. 11 | 12 | ```c title="File Structure" 13 | struct zCFileBIN { 14 | zCFileBIN_Chunk chunks[]; 15 | } 16 | 17 | struct zCFileBIN_Chunk { 18 | ushort type; 19 | uint size; 20 | byte data[/* size */]; 21 | }; 22 | ``` 23 | 24 | It should be noted that, apart from the data being grouped into chunks, files encoded in chunked binary behave the same 25 | as flat [binary](binary.md) files. 26 | 27 | ## Representation 28 | 29 | Wherever the chunked binary format is used in asset format references, the chunks are represented in a tabbed list. To 30 | keep it concise, the names of the tabs contain the chunk type and their content contains a C-style struct defining the 31 | data stored within. 32 | 33 | === "`0x1000`" 34 | 35 | ```c title="Section 0x1000" 36 | struct MyClass_Section1 { 37 | uint myValue1; 38 | 39 | // ... 40 | }; 41 | ``` 42 | 43 | This tab describes the section with type `0x1000`. As declared in the struct above, it only contains a 32-bit 44 | unsigned integer. The definition of all datatypes can be found in the [Datatype Reference](../datatypes.md). 45 | 46 | === "`0x1010`" 47 | 48 | ```c title="Section 0x1010" 49 | struct MyClass_Section2 { 50 | string myValue2; 51 | 52 | // ... 53 | }; 54 | ``` 55 | 56 | This tab describes the section with type `0x1010`. As you can see, it works the same as the first tab. 57 | 58 | You may have noticed, that the chunk's size is not mentioned anywhere in these tabs. While it should be taken as the 59 | actual size of the chunk, this reference aims to be as complete as possible, so the size of the struct provided for 60 | each section should be the same as the chunk size. If it is not, there is an error in this documentation. 61 | -------------------------------------------------------------------------------- /docs/engine/encodings/binary.md: -------------------------------------------------------------------------------- 1 | # Binary Encoding 2 | 3 | !!! abstract inline end "Quick Infos" 4 | **Type:** Encoding
5 | **Class Name:** `zFILE`
6 | **Used By:** [`zCFileBIN`](binary-chunked.md), [`zCFont`](../formats/font.md), [`zCTexture`](../formats/texture.md), [`zFILE_VDFS`](../formats/vdf.md) 7 | 8 | Most asset files and other encodings are based flat binary files. As their name indicates, files encoded using flat 9 | binary just contain raw bytes. Their structure is fully defined by the asset format using the encoding. 10 | 11 | Binary files and other encodings based on them are *little-endian*. 12 | 13 | ## Representation 14 | 15 | Wherever binary data needs to be represented in a structured form, C-style structs are used. In this documentation, 16 | they are intended to be read without any sort of padding (see below). All primitive datatypes and how they should be 17 | read are documented in the [Datatype Reference](../datatypes.md). 18 | 19 | ```c title="Example Binary Data" 20 | struct Example { 21 | ushort checksum; 22 | byte type; 23 | }; 24 | 25 | static_assert(sizeof(Example) == 3, "A ushort is 2 bytes plus a byte is 3 bytes"); 26 | ``` 27 | 28 | Often, binary structures contain arrays of dynamic size. In order to allow for more fluent definitions, the C-style 29 | array declaration syntax is used. The variable containing the dynamic size of the array is put in a comment within 30 | the brackets. 31 | 32 | ```c title="Example Binary Data Containing Arrays" 33 | struct Example { 34 | uint staticArray[10]; //< A set of 10 consecutive uints 35 | 36 | ushort dynamicLength; 37 | byte dynamicArray[/* dynamicLength */]; //< A set of `dynamicLength` consecutive bytes 38 | }; 39 | ``` 40 | -------------------------------------------------------------------------------- /docs/engine/formats/font.md: -------------------------------------------------------------------------------- 1 | # ZenGin Fonts 2 | 3 | !!! abstract inline end "Quick Infos" 4 | **Type:** Asset Format
5 | **Format Name:** Font
6 | **File Extension:** `.FNT`
7 | **Class Name:** `zCFont`
8 | **Encoding:** [Binary](../encodings/binary.md)
9 | 10 | *ZenGin* font files contain metadata for bitmap fonts used in the engine. In particular, they contain the position and 11 | size of font glyphs in a texture file. 12 | 13 | Fonts are found within the `Textures.vdf` file found in the `Data/` directory in the Gothic installation. 14 | 15 | ## Format Description 16 | 17 | Fonts are stored in a [binary](../encodings/binary.md) file which contains the following data. Also refer to the 18 | [Datatype Reference](../datatypes.md) for general information about often used datatypes. 19 | 20 | ```c title="Font Structure" 21 | struct zCFont { 22 | string version; // Always "1". 23 | string imageName; 24 | uint glyphHeight; 25 | uint glyphCount; 26 | 27 | byte glyphWidths[/* glyphCount */]; 28 | zVEC2 glyphTopLeftUVs[/* glyphCount */]; 29 | zVEC2 glyphBottomRightUVs[/* glyphCount */]; 30 | }; 31 | ``` 32 | 33 | Since *ZenGin* fonts are a kind of bitmap font, a font [texture](texture.md) is required in addition to this font 34 | metadata file. The name of that texture is found in `imageName`. 35 | 36 | To get the actual pixel coordinates for each glyph in the texture for any given UV-coordinate, multiply the `x` 37 | coordinate by the width of the texture and the `y` coordinate by the height of the texture. 38 | 39 | !!! warning 40 | Some coordinates are negative. These should be ignored since they don't have a glyph image associated with them. 41 | -------------------------------------------------------------------------------- /docs/engine/objects/_generate.py: -------------------------------------------------------------------------------- 1 | # Copyright © 2024 GothicKit Contributors. 2 | # SPDX-License-Identifier: MIT 3 | import os 4 | import re 5 | import sys 6 | import yaml 7 | from typing import Any 8 | 9 | from jinja2 import Template 10 | 11 | LINK_BASIC = re.compile(r"\[(\w+)\]") 12 | LINK_FIELD = re.compile(r"\[(\w+):(\w+)\]") 13 | 14 | 15 | def _resolve_links_str(str: str) -> str: 16 | text = re.sub(LINK_BASIC, r"[`\1`](\1.md)", str) 17 | text = re.sub(LINK_FIELD, lambda g: f"[`{g.group(1)}:{g.group(2)}`]({g.group(1)}.md#{g.group(2).lower()})", text) 18 | return text 19 | 20 | 21 | def _resolve_links(cfg: dict[str, Any]): 22 | if "class" in cfg: 23 | cfg["class"]["description"] = _resolve_links_str(cfg["class"]["description"]) 24 | 25 | if "properties" not in cfg: 26 | return 27 | 28 | for prop in cfg["properties"].values(): 29 | if prop["type"] == "group": 30 | _resolve_links(prop) 31 | elif "description" in prop: 32 | prop["description"] = _resolve_links_str(prop["description"]) 33 | 34 | 35 | def main(paths: list[str]) -> None: 36 | with open("_template.mdt", "r") as fp: 37 | env = Template(fp.read(), trim_blocks=True, lstrip_blocks=True) 38 | 39 | for path in paths: 40 | print(path) 41 | with open(path, "rb") as fp: 42 | cfg = yaml.safe_load(fp) 43 | 44 | _resolve_links(cfg) 45 | 46 | with open(cfg["class"]["name"] + ".md", "w") as fp: 47 | fp.write(re.sub(r"\n{2,}", "\n\n", env.render(cfg)).lstrip()) 48 | 49 | 50 | if __name__ == "__main__": 51 | if len(sys.argv) < 2: 52 | paths = [i for i in os.listdir(".") if i .endswith(".yml")] 53 | main(paths) 54 | else: 55 | main(sys.argv[1:]) 56 | -------------------------------------------------------------------------------- /docs/engine/objects/oCCSTrigger.md: -------------------------------------------------------------------------------- 1 | # `oCCSTrigger` 2 | 3 | !!! abstract inline end "Quick Infos" 4 | **Type:** Object
5 | **Format Name:** ZenGin Archive
6 | **File Extension:** `.ZEN`
7 | **Class Name:** `oCCSTrigger`
8 | **Version Identifiers:**
9 | — Gothic I: `24577`
10 | — Gothic II: `24577`
11 | **ZenKit Class:** `VCutsceneTrigger`
12 | **Sources:**
13 | — [spacerhilfedatei.sph](https://wiki.worldofgothic.de/doku.php?id=spacer:hilfedatei)
14 | — [gothic-library.ru](http://www.gothic-library.ru/publ/class_occstrigger/1-1-0-530) 15 | 16 | A special trigger VObject which can start a cutscene. The [`zCTriggerBase:triggerTarget`](zCTriggerBase.md#triggertarget) must be the name of the cutscene (without the extension) to be started. For this to work, the cutscene must already be loaded. `OnUntrigger` events are ignored by `oCCSTrigger`s. 17 | 18 | === "Gothic 1" 19 | - [zCVob](zCVob.md) 20 | {: .sp-class} 21 | - [zCTriggerBase](zCTriggerBase.md) 22 | {: .sp-class} 23 | - [zCTrigger](zCTrigger.md) 24 | {: .sp-class} 25 | - oCCSTrigger 26 | {: .sp-class} 27 | - <empty> 28 | {: .sp-none} 29 | 30 | === "Gothic 2" 31 | - [zCVob](zCVob.md) 32 | {: .sp-class} 33 | - [zCTriggerBase](zCTriggerBase.md) 34 | {: .sp-class} 35 | - [zCTrigger](zCTrigger.md) 36 | {: .sp-class} 37 | - oCCSTrigger 38 | {: .sp-class} 39 | - <empty> 40 | {: .sp-none} 41 | 42 | === "Gothic 1 (Save)" 43 | - [zCVob](zCVob.md) 44 | {: .sp-class} 45 | - [zCTriggerBase](zCTriggerBase.md) 46 | {: .sp-class} 47 | - [zCTrigger](zCTrigger.md) 48 | {: .sp-class} 49 | - oCCSTrigger 50 | {: .sp-class} 51 | - <empty> 52 | {: .sp-none} 53 | 54 | === "Gothic 2 (Save)" 55 | - [zCVob](zCVob.md) 56 | {: .sp-class} 57 | - [zCTriggerBase](zCTriggerBase.md) 58 | {: .sp-class} 59 | - [zCTrigger](zCTrigger.md) 60 | {: .sp-class} 61 | - oCCSTrigger 62 | {: .sp-class} 63 | - <empty> 64 | {: .sp-none} 65 | 66 | -------------------------------------------------------------------------------- /docs/engine/objects/oCCSTrigger.yml: -------------------------------------------------------------------------------- 1 | class: 2 | name: "oCCSTrigger" 3 | bases: [ 4 | "zCVob", 5 | "zCTriggerBase", 6 | "zCTrigger", 7 | ] 8 | description: | 9 | A special trigger VObject which can start a cutscene. The [zCTriggerBase:triggerTarget] must be the name 10 | of the cutscene (without the extension) to be started. For this to work, the cutscene must already be loaded. 11 | `OnUntrigger` events are ignored by `oCCSTrigger`s. 12 | zenkit: "VCutsceneTrigger" 13 | version: 14 | gothic1: 24577 15 | gothic2: 24577 16 | sources: 17 | spacerhilfedatei.sph: "https://wiki.worldofgothic.de/doku.php?id=spacer:hilfedatei" 18 | gothic-library.ru: "http://www.gothic-library.ru/publ/class_occstrigger/1-1-0-530" 19 | 20 | -------------------------------------------------------------------------------- /docs/engine/objects/oCInfo.md: -------------------------------------------------------------------------------- 1 | # `oCInfo` 2 | 3 | !!! abstract inline end "Quick Infos" 4 | **Type:** Object
5 | **Format Name:** ZenGin Archive
6 | **File Extension:** `.ZEN`
7 | **Class Name:** `oCInfo`
8 | **Version Identifiers:**
9 | — Gothic I: `0`
10 | — Gothic II: `0`
11 | **ZenKit Class:** `—` 12 | 13 | === "Gothic 1" 14 | - oCInfo 15 | {: .sp-class} 16 | - <empty> 17 | {: .sp-none} 18 | 19 | === "Gothic 2" 20 | - oCInfo 21 | {: .sp-class} 22 | - <empty> 23 | {: .sp-none} 24 | 25 | === "Gothic 1 (Save)" 26 | - oCInfo 27 | {: .sp-class} 28 | - [Told](#told) = FALSE 29 | {: .sp-bool} 30 | - [InstName](#instname) = 31 | {: .sp-string} 32 | 33 | === "Gothic 2 (Save)" 34 | - oCInfo 35 | {: .sp-class} 36 | - [Told](#told) = FALSE 37 | {: .sp-bool} 38 | - [InstName](#instname) = 39 | {: .sp-string} 40 | 41 | ## Properties 42 | 43 | #### `Told` {: .sp-bool} 44 | 45 | : Whether the hero has already been told this info. 46 | 47 | * `False` — The info has not yet been told. 48 | * `True` — The info has already been told. 49 | !!! warning 50 | This property is only available in saved games. 51 | 52 | #### `InstName` {: .sp-string} 53 | 54 | : The name of the script instance representing this info. 55 | 56 | !!! warning 57 | This property is only available in saved games. 58 | 59 | -------------------------------------------------------------------------------- /docs/engine/objects/oCInfo.yml: -------------------------------------------------------------------------------- 1 | class: 2 | name: "oCInfo" 3 | bases: [] 4 | description: "" 5 | zenkit: "—" 6 | version: 7 | gothic1: 0 8 | gothic2: 0 9 | properties: 10 | Told: 11 | type: "bool" 12 | description: "Whether the hero has already been told this info." 13 | default: "FALSE" 14 | version: [1, 2] 15 | save: true 16 | options: 17 | FALSE: "The info has not yet been told." 18 | TRUE: "The info has already been told." 19 | InstName: 20 | type: "string" 21 | description: "The name of the script instance representing this info." 22 | default: "" 23 | version: [1, 2] 24 | save: true 25 | -------------------------------------------------------------------------------- /docs/engine/objects/oCInfoManager.md: -------------------------------------------------------------------------------- 1 | # `oCInfoManager` 2 | 3 | !!! abstract inline end "Quick Infos" 4 | **Type:** Object
5 | **Format Name:** ZenGin Archive
6 | **File Extension:** `.ZEN`
7 | **Class Name:** `oCInfoManager`
8 | **Version Identifiers:**
9 | — Gothic I: `0`
10 | — Gothic II: `0`
11 | **ZenKit Class:** `—` 12 | 13 | === "Gothic 1" 14 | - oCInfoManager 15 | {: .sp-class} 16 | - <empty> 17 | {: .sp-none} 18 | 19 | === "Gothic 2" 20 | - oCInfoManager 21 | {: .sp-class} 22 | - <empty> 23 | {: .sp-none} 24 | 25 | === "Gothic 1 (Save)" 26 | - oCInfoManager 27 | {: .sp-class} 28 | - [NumOfEntries](#numofentries) = 0 29 | {: .sp-int} 30 | - [oCInfo](oCInfo.md) ... = NULL 31 | {: .sp-class} 32 | 33 | === "Gothic 2 (Save)" 34 | - oCInfoManager 35 | {: .sp-class} 36 | - [NumOfEntries](#numofentries) = 0 37 | {: .sp-int} 38 | - [oCInfo](oCInfo.md) ... = NULL 39 | {: .sp-class} 40 | 41 | ## Properties 42 | 43 | #### `NumOfEntries` {: .sp-int} 44 | 45 | : The number of saved [`oCInfo`](oCInfo.md) objects. 46 | 47 | !!! warning 48 | This property is only available in saved games. 49 | 50 | -------------------------------------------------------------------------------- /docs/engine/objects/oCInfoManager.yml: -------------------------------------------------------------------------------- 1 | class: 2 | name: "oCInfoManager" 3 | bases: [] 4 | description: "" 5 | zenkit: "—" 6 | version: 7 | gothic1: 0 8 | gothic2: 0 9 | properties: 10 | NumOfEntries: 11 | type: "int" 12 | description: "The number of saved [oCInfo] objects." 13 | default: "0" 14 | version: [1, 2] 15 | save: true 16 | oCInfo: 17 | type: "class" 18 | default: "NULL" 19 | version: [1, 2] 20 | save: true 21 | multi: true 22 | -------------------------------------------------------------------------------- /docs/engine/objects/oCItem.md: -------------------------------------------------------------------------------- 1 | # `oCItem` 2 | 3 | !!! abstract inline end "Quick Infos" 4 | **Type:** Object
5 | **Format Name:** ZenGin Archive
6 | **File Extension:** `.ZEN`
7 | **Class Name:** `oCItem`
8 | **Version Identifiers:**
9 | — Gothic I: `0`
10 | — Gothic II: `0`
11 | **ZenKit Class:** `—`
12 | **Sources:**
13 | — [gothic-library.ru](http://www.gothic-library.ru/publ/class_occstrigger/1-1-0-530) 14 | 15 | Represents an item in the game world. Items are special VObjects which are tied to a script instance which defines their attributes. They have physics enabled and can be targeted and picked up by the player. 16 | 17 | === "Gothic 1" 18 | - [zCVob](zCVob.md) 19 | {: .sp-class} 20 | - [oCVob](oCVob.md) 21 | {: .sp-class} 22 | - oCItem 23 | {: .sp-class} 24 | - [itemInstance](#iteminstance) = 25 | {: .sp-string} 26 | 27 | === "Gothic 2" 28 | - [zCVob](zCVob.md) 29 | {: .sp-class} 30 | - [oCVob](oCVob.md) 31 | {: .sp-class} 32 | - oCItem 33 | {: .sp-class} 34 | - [itemInstance](#iteminstance) = 35 | {: .sp-string} 36 | 37 | === "Gothic 1 (Save)" 38 | - [zCVob](zCVob.md) 39 | {: .sp-class} 40 | - [oCVob](oCVob.md) 41 | {: .sp-class} 42 | - oCItem 43 | {: .sp-class} 44 | - [itemInstance](#iteminstance) = 45 | {: .sp-string} 46 | - [amount](#amount) = 47 | {: .sp-int} 48 | - [flags](#flags) = 49 | {: .sp-int} 50 | 51 | === "Gothic 2 (Save)" 52 | - [zCVob](zCVob.md) 53 | {: .sp-class} 54 | - [oCVob](oCVob.md) 55 | {: .sp-class} 56 | - oCItem 57 | {: .sp-class} 58 | - [itemInstance](#iteminstance) = 59 | {: .sp-string} 60 | - [amount](#amount) = 61 | {: .sp-int} 62 | - [flags](#flags) = 63 | {: .sp-int} 64 | 65 | ## Properties 66 | 67 | #### `itemInstance` {: .sp-string} 68 | 69 | : The name of the script instance representing the item. 70 | 71 | #### `amount` {: .sp-int} 72 | 73 | : Unknown. 74 | 75 | !!! warning 76 | This property is only available in saved games. 77 | 78 | #### `flags` {: .sp-int} 79 | 80 | : Unknown. 81 | 82 | !!! warning 83 | This property is only available in saved games. 84 | 85 | -------------------------------------------------------------------------------- /docs/engine/objects/oCItem.yml: -------------------------------------------------------------------------------- 1 | class: 2 | name: "oCItem" 3 | bases: 4 | - "zCVob" 5 | - "oCVob" 6 | description: | 7 | Represents an item in the game world. Items are special VObjects which are tied to a script instance which defines 8 | their attributes. They have physics enabled and can be targeted and picked up by the player. 9 | zenkit: "—" 10 | version: 11 | gothic1: 0 12 | gothic2: 0 13 | sources: 14 | gothic-library.ru: http://www.gothic-library.ru/publ/class_occstrigger/1-1-0-530 15 | properties: 16 | itemInstance: 17 | type: "string" 18 | description: "The name of the script instance representing the item." 19 | default: "" 20 | version: [1, 2] 21 | save: false 22 | amount: 23 | type: "int" 24 | description: "Unknown." 25 | default: "" 26 | version: [1, 2] 27 | save: true 28 | flags: 29 | type: "int" 30 | description: "Unknown." 31 | default: "" 32 | version: [1, 2] 33 | save: true 34 | -------------------------------------------------------------------------------- /docs/engine/objects/oCLogManager.md: -------------------------------------------------------------------------------- 1 | # `oCLogManager` 2 | 3 | !!! abstract inline end "Quick Infos" 4 | **Type:** Object
5 | **Format Name:** ZenGin Archive
6 | **File Extension:** `.ZEN`
7 | **Class Name:** `oCLogManager`
8 | **Version Identifiers:**
9 | — Gothic I: `0`
10 | — Gothic II: `0`
11 | **ZenKit Class:** `—` 12 | 13 | === "Gothic 1" 14 | - oCLogManager 15 | {: .sp-class} 16 | - [LOGMANAGERTOPICCOUNT](#logmanagertopiccount) = 0 17 | {: .sp-int} 18 | - [oCLogTopic](oCLogTopic.md) ... = NULL 19 | {: .sp-class} 20 | 21 | === "Gothic 2" 22 | - oCLogManager 23 | {: .sp-class} 24 | - [LOGMANAGERTOPICCOUNT](#logmanagertopiccount) = 0 25 | {: .sp-int} 26 | - [oCLogTopic](oCLogTopic.md) ... = NULL 27 | {: .sp-class} 28 | 29 | === "Gothic 1 (Save)" 30 | - oCLogManager 31 | {: .sp-class} 32 | - [LOGMANAGERTOPICCOUNT](#logmanagertopiccount) = 0 33 | {: .sp-int} 34 | - [oCLogTopic](oCLogTopic.md) ... = NULL 35 | {: .sp-class} 36 | 37 | === "Gothic 2 (Save)" 38 | - oCLogManager 39 | {: .sp-class} 40 | - [LOGMANAGERTOPICCOUNT](#logmanagertopiccount) = 0 41 | {: .sp-int} 42 | - [oCLogTopic](oCLogTopic.md) ... = NULL 43 | {: .sp-class} 44 | 45 | ## Properties 46 | 47 | #### `LOGMANAGERTOPICCOUNT` {: .sp-int} 48 | 49 | : The number of saved [`oCLogTopic`](oCLogTopic.md) objects. 50 | 51 | -------------------------------------------------------------------------------- /docs/engine/objects/oCLogManager.yml: -------------------------------------------------------------------------------- 1 | class: 2 | name: "oCLogManager" 3 | bases: [] 4 | description: "" 5 | zenkit: "—" 6 | version: 7 | gothic1: 0 8 | gothic2: 0 9 | properties: 10 | LOGMANAGERTOPICCOUNT: 11 | type: "int" 12 | description: "The number of saved [oCLogTopic] objects." 13 | default: "0" 14 | version: [1, 2] 15 | save: false 16 | oCLogTopic: 17 | type: "class" 18 | default: "NULL" 19 | version: [1, 2] 20 | save: false 21 | multi: true 22 | -------------------------------------------------------------------------------- /docs/engine/objects/oCLogTopic.yml: -------------------------------------------------------------------------------- 1 | class: 2 | name: "oCLogTopic" 3 | bases: [] 4 | description: "" 5 | zenkit: "—" 6 | version: 7 | gothic1: 0 8 | gothic2: 0 9 | properties: 10 | TOPICDESCRIPTION: 11 | type: "string" 12 | description: "The name of the quest log entry." 13 | default: "0" 14 | version: [1, 2] 15 | save: false 16 | TOPICSECTION: 17 | type: "enum" 18 | description: "The quest log section the entry is in." 19 | default: "zELogSection_Missions" 20 | version: [1, 2] 21 | save: false 22 | options: 23 | zELogSection_Missions: The entry is in one of the mission sections of the quest log. 24 | zELogSection_Notes: The entry is in the general notes section of the quest log. 25 | TOPICSTATUS: 26 | type: "enum" 27 | description: "The status the quest log entry." 28 | default: "zELogTopicStatus_Free" 29 | version: [1, 2] 30 | save: false 31 | options: 32 | zELogTopicStatus_Free: Unknown, makes the entry disappear from the quest log. 33 | zELogTopicStatus_Running: The entry is in the 'running quests' section of the quest log. 34 | zELogTopicStatus_Success: The entry is in the 'succeeded quests' section of the quest log. 35 | zELogTopicStatus_Failure: The entry is in the 'failed quests' section of the quest log. 36 | zELogTopicStatus_Obsolete: The entry is in the 'obsolete quests' section of the quest log. 37 | extra: 38 | type: "warning" 39 | text: "This field is ignored unless [`TOPICSECTION`](#topicsection) is set to `zELogSection_Missions`." 40 | LOGTOPICENTRYCOUNT: 41 | type: "int" 42 | description: "The number of entries of this log topic." 43 | default: "0" 44 | version: [1, 2] 45 | save: false 46 | LOGMANAGERENTRYCOUNT: 47 | type: "int" 48 | description: "The same as [`LOGTOPICENTRYCOUNT`](#logtopicentrycount)." 49 | default: "0" 50 | version: [ 1, 2 ] 51 | save: false 52 | ENTRYDESCRIPTION: 53 | type: "string" 54 | description: "A single entry in the log topic. Log entries are shown in chronological order on the detailed view of the log topic, separated by three dashes." 55 | default: "" 56 | version: [ 1, 2 ] 57 | save: false 58 | multi: true 59 | -------------------------------------------------------------------------------- /docs/engine/objects/oCMission.yml: -------------------------------------------------------------------------------- 1 | class: 2 | name: "oCMission" 3 | bases: [] 4 | description: "" 5 | zenkit: "—" 6 | version: 7 | gothic1: 0 8 | gothic2: 0 9 | properties: 10 | name: 11 | type: "string" 12 | description: "Unknown." 13 | default: "" 14 | version: [1, 2] 15 | save: true 16 | ID: 17 | type: "int" 18 | description: "Unknown." 19 | default: "0" 20 | version: [1, 2] 21 | save: true 22 | AV: 23 | type: "bool" 24 | description: "Unknown." 25 | default: "FALSE" 26 | version: [1, 2] 27 | save: true 28 | NumInList: 29 | type: "int" 30 | description: "The number of statuses stored for the mission." 31 | default: "0" 32 | version: [1, 2] 33 | save: true 34 | "Status ...": 35 | type: "group" 36 | version: [ 1, 2 ] 37 | save: true 38 | properties: 39 | VobIDL: 40 | type: "int" 41 | description: "Unknown." 42 | default: "0" 43 | version: [ 1, 2 ] 44 | save: true 45 | StatusL: 46 | type: "int" 47 | description: "Unknown." 48 | default: "0" 49 | version: [ 1, 2 ] 50 | save: true 51 | startTimeL: 52 | type: "float" 53 | description: "Unknown." 54 | default: "0.0" 55 | version: [ 1, 2 ] 56 | save: true 57 | StatusIndex: 58 | type: "int" 59 | description: "Unknown." 60 | default: "0" 61 | version: [1, 2] 62 | save: true -------------------------------------------------------------------------------- /docs/engine/objects/oCMissionManager.md: -------------------------------------------------------------------------------- 1 | # `oCMissionManager` 2 | 3 | !!! abstract inline end "Quick Infos" 4 | **Type:** Object
5 | **Format Name:** ZenGin Archive
6 | **File Extension:** `.ZEN`
7 | **Class Name:** `oCMissionManager`
8 | **Version Identifiers:**
9 | — Gothic I: `0`
10 | — Gothic II: `0`
11 | **ZenKit Class:** `—` 12 | 13 | === "Gothic 1" 14 | - oCMissionManager 15 | {: .sp-class} 16 | - [NumOfEntries](#numofentries) = 0 17 | {: .sp-int} 18 | - [oCMission](oCMission.md) ... = NULL 19 | {: .sp-class} 20 | 21 | === "Gothic 2" 22 | - oCMissionManager 23 | {: .sp-class} 24 | - [NumOfEntries](#numofentries) = 0 25 | {: .sp-int} 26 | - [oCMission](oCMission.md) ... = NULL 27 | {: .sp-class} 28 | 29 | === "Gothic 1 (Save)" 30 | - oCMissionManager 31 | {: .sp-class} 32 | - [NumOfEntries](#numofentries) = 0 33 | {: .sp-int} 34 | - [oCMission](oCMission.md) ... = NULL 35 | {: .sp-class} 36 | 37 | === "Gothic 2 (Save)" 38 | - oCMissionManager 39 | {: .sp-class} 40 | - [NumOfEntries](#numofentries) = 0 41 | {: .sp-int} 42 | - [oCMission](oCMission.md) ... = NULL 43 | {: .sp-class} 44 | 45 | ## Properties 46 | 47 | #### `NumOfEntries` {: .sp-int} 48 | 49 | : The number of saved [`oCMission`](oCMission.md) objects. 50 | 51 | -------------------------------------------------------------------------------- /docs/engine/objects/oCMissionManager.yml: -------------------------------------------------------------------------------- 1 | class: 2 | name: "oCMissionManager" 3 | bases: [] 4 | description: "" 5 | zenkit: "—" 6 | version: 7 | gothic1: 0 8 | gothic2: 0 9 | properties: 10 | NumOfEntries: 11 | type: "int" 12 | description: "The number of saved [oCMission] objects." 13 | default: "0" 14 | version: [1, 2] 15 | save: false 16 | oCMission: 17 | type: "class" 18 | default: "NULL" 19 | version: [1, 2] 20 | save: false 21 | multi: true 22 | -------------------------------------------------------------------------------- /docs/engine/objects/oCMobBed.md: -------------------------------------------------------------------------------- 1 | # `oCMobBed` 2 | 3 | !!! abstract inline end "Quick Infos" 4 | **Type:** Object
5 | **Format Name:** ZenGin Archive
6 | **File Extension:** `.ZEN`
7 | **Class Name:** `oCMobBed`
8 | **Version Identifiers:**
9 | — Gothic I: `35585`
10 | — Gothic II: `35585`
11 | **ZenKit Class:** `VBed`
12 | **Sources:**
13 | — [spacerhilfedatei.sph](https://wiki.worldofgothic.de/doku.php?id=spacer:hilfedatei) 14 | 15 | VObject marking beds for NPCs and the player to sleep on. In the original Gothic I, there is a bug which prevents `oCMobBed`s from working correctly, so it is recommended to instead use [`oCMobDoor`](oCMobDoor.md) and attach the visual of a bed when targeting that platform. 16 | 17 | === "Gothic 1" 18 | - [zCVob](zCVob.md) 19 | {: .sp-class} 20 | - [oCVob](oCVob.md) 21 | {: .sp-class} 22 | - [oCMob](oCMob.md) 23 | {: .sp-class} 24 | - [oCMobInter](oCMobInter.md) 25 | {: .sp-class} 26 | - oCMobBed 27 | {: .sp-class} 28 | - <empty> 29 | {: .sp-none} 30 | 31 | === "Gothic 2" 32 | - [zCVob](zCVob.md) 33 | {: .sp-class} 34 | - [oCVob](oCVob.md) 35 | {: .sp-class} 36 | - [oCMob](oCMob.md) 37 | {: .sp-class} 38 | - [oCMobInter](oCMobInter.md) 39 | {: .sp-class} 40 | - oCMobBed 41 | {: .sp-class} 42 | - <empty> 43 | {: .sp-none} 44 | 45 | === "Gothic 1 (Save)" 46 | - [zCVob](zCVob.md) 47 | {: .sp-class} 48 | - [oCVob](oCVob.md) 49 | {: .sp-class} 50 | - [oCMob](oCMob.md) 51 | {: .sp-class} 52 | - [oCMobInter](oCMobInter.md) 53 | {: .sp-class} 54 | - oCMobBed 55 | {: .sp-class} 56 | - <empty> 57 | {: .sp-none} 58 | 59 | === "Gothic 2 (Save)" 60 | - [zCVob](zCVob.md) 61 | {: .sp-class} 62 | - [oCVob](oCVob.md) 63 | {: .sp-class} 64 | - [oCMob](oCMob.md) 65 | {: .sp-class} 66 | - [oCMobInter](oCMobInter.md) 67 | {: .sp-class} 68 | - oCMobBed 69 | {: .sp-class} 70 | - <empty> 71 | {: .sp-none} 72 | 73 | -------------------------------------------------------------------------------- /docs/engine/objects/oCMobBed.yml: -------------------------------------------------------------------------------- 1 | class: 2 | name: "oCMobBed" 3 | bases: 4 | - "zCVob" 5 | - "oCVob" 6 | - "oCMob" 7 | - "oCMobInter" 8 | description: | 9 | VObject marking beds for NPCs and the player to sleep on. In the original Gothic I, there is a bug which prevents `oCMobBed`s from working correctly, so it is recommended to instead use [oCMobDoor] and attach the visual of a bed when targeting that platform. 10 | zenkit: "VBed" 11 | sources: 12 | spacerhilfedatei.sph: "https://wiki.worldofgothic.de/doku.php?id=spacer:hilfedatei" 13 | version: 14 | gothic1: 35585 15 | gothic2: 35585 16 | -------------------------------------------------------------------------------- /docs/engine/objects/oCMobContainer.yml: -------------------------------------------------------------------------------- 1 | class: 2 | name: "oCMobContainer" 3 | bases: 4 | - zCVob 5 | - oCVob 6 | - oCMOB 7 | - oCMOBInter 8 | - oCMOBLockable 9 | description: "An object which contains items." 10 | zenkit: "VContainer" 11 | version: 12 | gothic1: 64513 13 | gothic2: 64513 14 | sources: 15 | spacerhilfedatei.sph: https://wiki.worldofgothic.de/doku.php?id=spacer:hilfedatei 16 | gothic-library.ru: http://www.gothic-library.ru/publ/ocmobcontainer/1-1-0-509 17 | properties: 18 | Container: 19 | type: "group" 20 | version: [ 1, 2 ] 21 | save: false 22 | properties: 23 | contains: 24 | type: "string" 25 | description: | 26 | The items found inside the container as a comma-separated list. Each element of the list starts with the name of the 27 | item script instance and is optionally followed by a colon and a number, indicating the number of that item to be found 28 | inside. 29 | default: "" 30 | version: [ 1, 2 ] 31 | save: false 32 | example: "ItMi_Gold:75, ItFo_Fish:2, ItMi_Quartz" 33 | NumOfEntries: 34 | type: "int" 35 | description: "The number of items in the container." 36 | default: "0" 37 | version: [ 1, 2 ] 38 | save: true 39 | oCItem: 40 | type: "class" 41 | default: "NULL" 42 | version: [ 1, 2 ] 43 | save: true 44 | multi: true 45 | -------------------------------------------------------------------------------- /docs/engine/objects/oCMobDoor.md: -------------------------------------------------------------------------------- 1 | # oCMobDoor 2 | 3 | !!! abstract inline end "Quick Infos" 4 | **Type:** Virtual Object
5 | **Format Name:** ZenGin Archive
6 | **File Extension:** `.ZEN`
7 | **Class Name:** `oCMobDoor`
8 | **Version Identifiers:**
9 | — Gothic I: `64513`
10 | — Gothic II: `64513`
11 | **ZenKit Class:** `VDoor`
12 | **Sources:**
13 | — [gothic-library.ru](http://www.gothic-library.ru/publ/ocmobdoor/1-1-0-510) 14 | 15 | A VObject representing a door. This is also used for NPCs navigating the waynet. 16 | 17 | === "Gothic 1" 18 | 19 | - [zCVob](zCVob.md) 20 | {: .sp-class} 21 | - [oCVob](oCVob.md) 22 | {: .sp-class} 23 | - [oCMOB](oCMOB.md) 24 | {: .sp-class} 25 | - [oCMobInter](oCMobInter.md) 26 | {: .sp-class} 27 | - [*oCMobLockable*](oCMobLockable.md) 28 | {: .sp-class} 29 | - oCMobDoor 30 | {: .sp-class} 31 | - <empty> 32 | {: .sp-empty} 33 | 34 | === "Gothic 2" 35 | 36 | - [zCVob](zCVob.md) 37 | {: .sp-class} 38 | - [oCVob](oCVob.md) 39 | {: .sp-class} 40 | - [oCMOB](oCMOB.md) 41 | {: .sp-class} 42 | - [oCMobInter](oCMobInter.md) 43 | {: .sp-class} 44 | - [*oCMobLockable*](oCMobLockable.md) 45 | {: .sp-class} 46 | - oCMobDoor 47 | {: .sp-class} 48 | - <empty> 49 | {: .sp-empty} 50 | 51 | === "Gothic 1 (Save)" 52 | 53 | - [zCVob](zCVob.md) 54 | {: .sp-class} 55 | - [oCVob](oCVob.md) 56 | {: .sp-class} 57 | - [oCMOB](oCMOB.md) 58 | {: .sp-class} 59 | - [oCMobInter](oCMobInter.md) 60 | {: .sp-class} 61 | - [*oCMobLockable*](oCMobLockable.md) 62 | {: .sp-class} 63 | - oCMobDoor 64 | {: .sp-class} 65 | - <empty> 66 | {: .sp-empty} 67 | 68 | === "Gothic 2 (Save)" 69 | 70 | - [zCVob](zCVob.md) 71 | {: .sp-class} 72 | - [oCVob](oCVob.md) 73 | {: .sp-class} 74 | - [oCMOB](oCMOB.md) 75 | {: .sp-class} 76 | - [oCMobInter](oCMobInter.md) 77 | {: .sp-class} 78 | - [*oCMobLockable*](oCMobLockable.md) 79 | {: .sp-class} 80 | - oCMobDoor 81 | {: .sp-class} 82 | - <empty> 83 | {: .sp-empty} 84 | -------------------------------------------------------------------------------- /docs/engine/objects/oCMobFire.md: -------------------------------------------------------------------------------- 1 | # oCMobFire 2 | 3 | !!! abstract inline end "Quick Infos" 4 | **Type:** Virtual Object
5 | **Format Name:** ZenGin Archive
6 | **File Extension:** `.ZEN`
7 | **Class Name:** `oCMobFire`
8 | **Version Identifiers:**
9 | — Gothic I: `18433`
10 | — Gothic II: `18433`
11 | **ZenKit Class:** `VFire`
12 | **Sources:**
13 | — [gothic-library.ru](http://www.gothic-library.ru/publ/ocmobfire/1-1-0-506) 14 | 15 | An object with an integrated fire effect. Only supports rigged models as visuals. 16 | 17 | === "Gothic 1" 18 | 19 | - [zCVob](zCVob.md) 20 | {: .sp-class} 21 | - [oCVob](oCVob.md) 22 | {: .sp-class} 23 | - [oCMOB](oCMOB.md) 24 | {: .sp-class} 25 | - [oCMobInter](oCMobInter.md) 26 | {: .sp-class} 27 | - oCMobFire 28 | {: .sp-class} 29 | - [fireSlot](#fireslot) = "" 30 | {: .sp-string} 31 | - [fireVobtreeName](#firevobtreename) = "" 32 | {: .sp-string} 33 | 34 | === "Gothic 2" 35 | 36 | - [zCVob](zCVob.md) 37 | {: .sp-class} 38 | - [oCVob](oCVob.md) 39 | {: .sp-class} 40 | - [oCMOB](oCMOB.md) 41 | {: .sp-class} 42 | - [oCMobInter](oCMobInter.md) 43 | {: .sp-class} 44 | - oCMobFire 45 | {: .sp-class} 46 | - [fireSlot](#fireslot) = "" 47 | {: .sp-string} 48 | - [fireVobtreeName](#firevobtreename) = "" 49 | {: .sp-string} 50 | 51 | === "Gothic 1 (Save)" 52 | 53 | - [zCVob](zCVob.md) 54 | {: .sp-class} 55 | - [oCVob](oCVob.md) 56 | {: .sp-class} 57 | - [oCMOB](oCMOB.md) 58 | {: .sp-class} 59 | - [oCMobInter](oCMobInter.md) 60 | {: .sp-class} 61 | - oCMobFire 62 | {: .sp-class} 63 | - [fireSlot](#fireslot) = "" 64 | {: .sp-string} 65 | - [fireVobtreeName](#firevobtreename) = "" 66 | {: .sp-string} 67 | 68 | === "Gothic 2 (Save)" 69 | 70 | - [zCVob](zCVob.md) 71 | {: .sp-class} 72 | - [oCVob](oCVob.md) 73 | {: .sp-class} 74 | - [oCMOB](oCMOB.md) 75 | {: .sp-class} 76 | - [oCMobInter](oCMobInter.md) 77 | {: .sp-class} 78 | - oCMobFire 79 | {: .sp-class} 80 | - [fireSlot](#fireslot) = "" 81 | {: .sp-string} 82 | - [fireVobtreeName](#firevobtreename) = "" 83 | {: .sp-string} 84 | 85 | ## Properties 86 | 87 | #### `fireSlot` {: .sp-string} 88 | 89 | : The bone of the rigged model to place the fire effect at. 90 | 91 | #### `fireVobtreeName` {: .sp-string} 92 | 93 | : The name of the template file which contains the configuration of the fire effect. For example: `FIRETREE_MEDIUM.ZEN`. 94 | -------------------------------------------------------------------------------- /docs/engine/objects/oCMobLadder.md: -------------------------------------------------------------------------------- 1 | # oCMobLadder 2 | 3 | !!! abstract inline end "Quick Infos" 4 | **Type:** Virtual Object
5 | **Format Name:** ZenGin Archive
6 | **File Extension:** `.ZEN`
7 | **Class Name:** `oCMobLadder`
8 | **Version Identifiers:**
9 | — Gothic I: `35585`
10 | — Gothic II: `35585`
11 | **ZenKit Class:** `VLadder`
12 | **Sources:**
13 | — [spacerhilfedatei.sph](https://wiki.worldofgothic.de/doku.php?id=spacer:hilfedatei)
14 | — [gothic-library.ru](http://www.gothic-library.ru/publ/ocmobladder/1-1-0-508) 15 | 16 | A VObject representing a ladder. NPCs can interact with ladders by climbing. 17 | 18 | === "Gothic 1" 19 | 20 | - [zCVob](zCVob.md) 21 | {: .sp-class} 22 | - [oCVob](oCVob.md) 23 | {: .sp-class} 24 | - [oCMOB](oCMOB.md) 25 | {: .sp-class} 26 | - [oCMobInter](oCMobInter.md) 27 | {: .sp-class} 28 | - oCMobLadder 29 | {: .sp-class} 30 | - <empty> 31 | {: .sp-none} 32 | 33 | === "Gothic 2" 34 | 35 | - [zCVob](zCVob.md) 36 | {: .sp-class} 37 | - [oCVob](oCVob.md) 38 | {: .sp-class} 39 | - [oCMOB](oCMOB.md) 40 | {: .sp-class} 41 | - [oCMobInter](oCMobInter.md) 42 | {: .sp-class} 43 | - oCMobLadder 44 | {: .sp-class} 45 | - <empty> 46 | {: .sp-none} 47 | 48 | === "Gothic 1 (Save)" 49 | 50 | - [zCVob](zCVob.md) 51 | {: .sp-class} 52 | - [oCVob](oCVob.md) 53 | {: .sp-class} 54 | - [oCMOB](oCMOB.md) 55 | {: .sp-class} 56 | - [oCMobInter](oCMobInter.md) 57 | {: .sp-class} 58 | - oCMobLadder 59 | {: .sp-class} 60 | - <empty> 61 | {: .sp-none} 62 | 63 | === "Gothic 2 (Save)" 64 | 65 | - [zCVob](zCVob.md) 66 | {: .sp-class} 67 | - [oCVob](oCVob.md) 68 | {: .sp-class} 69 | - [oCMOB](oCMOB.md) 70 | {: .sp-class} 71 | - [oCMobInter](oCMobInter.md) 72 | {: .sp-class} 73 | - oCMobLadder 74 | {: .sp-class} 75 | - <empty> 76 | {: .sp-none} 77 | 78 | -------------------------------------------------------------------------------- /docs/engine/objects/oCMobSwitch.md: -------------------------------------------------------------------------------- 1 | # oCMobSwitch 2 | 3 | !!! abstract inline end "Quick Infos" 4 | **Type:** Virtual Object
5 | **Format Name:** ZenGin Archive
6 | **File Extension:** `.ZEN`
7 | **Class Name:** `oCMobSwitch`
8 | **Version Identifiers:**
9 | — Gothic I: `35585`
10 | — Gothic II: `35585`
11 | **ZenKit Class:** `VSwitch`
12 | **Sources:**
13 | — [spacerhilfedatei.sph](https://wiki.worldofgothic.de/doku.php?id=spacer:hilfedatei) 14 | 15 | A VObject representing a switch with two states. 16 | 17 | === "Gothic 1" 18 | 19 | - [zCVob](zCVob.md) 20 | {: .sp-class} 21 | - [oCVob](oCVob.md) 22 | {: .sp-class} 23 | - [oCMOB](oCMOB.md) 24 | {: .sp-class} 25 | - [oCMobInter](oCMobInter.md) 26 | {: .sp-class} 27 | - oCMobSwitch 28 | {: .sp-class} 29 | - <empty> 30 | {: .sp-none} 31 | 32 | === "Gothic 2" 33 | 34 | - [zCVob](zCVob.md) 35 | {: .sp-class} 36 | - [oCVob](oCVob.md) 37 | {: .sp-class} 38 | - [oCMOB](oCMOB.md) 39 | {: .sp-class} 40 | - [oCMobInter](oCMobInter.md) 41 | {: .sp-class} 42 | - oCMobSwitch 43 | {: .sp-class} 44 | - <empty> 45 | {: .sp-none} 46 | 47 | === "Gothic 1 (Save)" 48 | 49 | - [zCVob](zCVob.md) 50 | {: .sp-class} 51 | - [oCVob](oCVob.md) 52 | {: .sp-class} 53 | - [oCMOB](oCMOB.md) 54 | {: .sp-class} 55 | - [oCMobInter](oCMobInter.md) 56 | {: .sp-class} 57 | - oCMobSwitch 58 | {: .sp-class} 59 | - <empty> 60 | {: .sp-none} 61 | 62 | === "Gothic 2 (Save)" 63 | 64 | - [zCVob](zCVob.md) 65 | {: .sp-class} 66 | - [oCVob](oCVob.md) 67 | {: .sp-class} 68 | - [oCMOB](oCMOB.md) 69 | {: .sp-class} 70 | - [oCMobInter](oCMobInter.md) 71 | {: .sp-class} 72 | - oCMobSwitch 73 | {: .sp-class} 74 | - <empty> 75 | {: .sp-none} 76 | -------------------------------------------------------------------------------- /docs/engine/objects/oCMobWheel.md: -------------------------------------------------------------------------------- 1 | # oCMobWheel 2 | 3 | !!! abstract inline end "Quick Infos" 4 | **Type:** Virtual Object
5 | **Format Name:** ZenGin Archive
6 | **File Extension:** `.ZEN`
7 | **Class Name:** `oCMobWheel`
8 | **Version Identifiers:**
9 | — Gothic I: `35585`
10 | — Gothic II: `35585`
11 | **ZenKit Class:** `VWheel`
12 | **Sources:**
13 | — [spacerhilfedatei.sph](https://wiki.worldofgothic.de/doku.php?id=spacer:hilfedatei) 14 | 15 | A wheel with four different states. For example, this is used for the gates of the old camp in Gothic I. 16 | 17 | === "Gothic 1" 18 | 19 | - [zCVob](zCVob.md) 20 | {: .sp-class} 21 | - [oCVob](oCVob.md) 22 | {: .sp-class} 23 | - [oCMOB](oCMOB.md) 24 | {: .sp-class} 25 | - [oCMobInter](oCMobInter.md) 26 | {: .sp-class} 27 | - oCMobWheel 28 | {: .sp-class} 29 | - <empty> 30 | {: .sp-none} 31 | 32 | === "Gothic 2" 33 | 34 | - [zCVob](zCVob.md) 35 | {: .sp-class} 36 | - [oCVob](oCVob.md) 37 | {: .sp-class} 38 | - [oCMOB](oCMOB.md) 39 | {: .sp-class} 40 | - [oCMobInter](oCMobInter.md) 41 | {: .sp-class} 42 | - oCMobWheel 43 | {: .sp-class} 44 | - <empty> 45 | {: .sp-none} 46 | 47 | === "Gothic 1 (Save)" 48 | 49 | - [zCVob](zCVob.md) 50 | {: .sp-class} 51 | - [oCVob](oCVob.md) 52 | {: .sp-class} 53 | - [oCMOB](oCMOB.md) 54 | {: .sp-class} 55 | - [oCMobInter](oCMobInter.md) 56 | {: .sp-class} 57 | - oCMobWheel 58 | {: .sp-class} 59 | - <empty> 60 | {: .sp-none} 61 | 62 | === "Gothic 2 (Save)" 63 | 64 | - [zCVob](zCVob.md) 65 | {: .sp-class} 66 | - [oCVob](oCVob.md) 67 | {: .sp-class} 68 | - [oCMOB](oCMOB.md) 69 | {: .sp-class} 70 | - [oCMobInter](oCMobInter.md) 71 | {: .sp-class} 72 | - oCMobWheel 73 | {: .sp-class} 74 | - <empty> 75 | {: .sp-none} 76 | -------------------------------------------------------------------------------- /docs/engine/objects/oCTouchDamage.md: -------------------------------------------------------------------------------- 1 | # oCTouchDamage 2 | 3 | !!! abstract inline end "Quick Infos" 4 | **Type:** Virtual Object
5 | **Format Name:** ZenGin Archive
6 | **File Extension:** `.ZEN`
7 | **Class Name:** `oCTouchDamage`
8 | **Version Identifiers:**
9 | — Gothic I: `36865`
10 | — Gothic II: `36865`
11 | **ZenKit Class:** `VTouchDamage` 12 | 13 | === "Gothic 1" 14 | 15 | - [zCVob](zCVob.md) 16 | {: .sp-class} 17 | - [*zCEffect*](zCEffect.md) 18 | {: .sp-class} 19 | - [zCTouchDamage](zCTouchDamage.md) 20 | {: .sp-class} 21 | - oCTouchDamage 22 | {: .sp-class} 23 | - <empty> 24 | {: .sp-none} 25 | 26 | === "Gothic 2" 27 | 28 | - [zCVob](zCVob.md) 29 | {: .sp-class} 30 | - [*zCEffect*](zCEffect.md) 31 | {: .sp-class} 32 | - [zCTouchDamage](zCTouchDamage.md) 33 | {: .sp-class} 34 | - oCTouchDamage 35 | {: .sp-class} 36 | - <empty> 37 | {: .sp-none} 38 | 39 | === "Gothic 1 (Save)" 40 | 41 | - [zCVob](zCVob.md) 42 | {: .sp-class} 43 | - [*zCEffect*](zCEffect.md) 44 | {: .sp-class} 45 | - [zCTouchDamage](zCTouchDamage.md) 46 | {: .sp-class} 47 | - oCTouchDamage 48 | {: .sp-class} 49 | - <empty> 50 | {: .sp-none} 51 | 52 | === "Gothic 2 (Save)" 53 | 54 | - [zCVob](zCVob.md) 55 | {: .sp-class} 56 | - [*zCEffect*](zCEffect.md) 57 | {: .sp-class} 58 | - [zCTouchDamage](zCTouchDamage.md) 59 | {: .sp-class} 60 | - oCTouchDamage 61 | {: .sp-class} 62 | - <empty> 63 | {: .sp-none} 64 | -------------------------------------------------------------------------------- /docs/engine/objects/oCTriggerChangeLevel.md: -------------------------------------------------------------------------------- 1 | # oCTriggerChangeLevel 2 | 3 | !!! abstract inline end "Quick Infos" 4 | **Type:** Virtual Object
5 | **Format Name:** ZenGin Archive
6 | **File Extension:** `.ZEN`
7 | **Class Name:** `oCTriggerChangeLevel`
8 | **Version Identifiers:**
9 | — Gothic I: `24577`
10 | — Gothic II: `24577`
11 | **ZenKit Class:** `VTriggerChangeLevel`
12 | **Sources:**
13 | — [spacerhilfedatei.sph](https://wiki.worldofgothic.de/doku.php?id=spacer:hilfedatei) 14 | 15 | A special [`zCTrigger`](zCTrigger.md) which in addition to performing all other trigger actions also causes the engine 16 | to load another level when activated. 17 | 18 | === "Gothic 1" 19 | 20 | - [zCVob](zCVob.md) 21 | {: .sp-class} 22 | - [*zCTriggerBase*](zCTriggerBase.md) 23 | {: .sp-class} 24 | - [zCTrigger](zCTrigger.md) 25 | {: .sp-class} 26 | - oCTriggerChangeLevel 27 | {: .sp-class} 28 | - [levelName](#levelname) = "" 29 | {: .sp-string} 30 | - [startVobName](#startvobname) = "" 31 | {: .sp-string} 32 | 33 | === "Gothic 2" 34 | 35 | - [zCVob](zCVob.md) 36 | {: .sp-class} 37 | - [*zCTriggerBase*](zCTriggerBase.md) 38 | {: .sp-class} 39 | - [zCTrigger](zCTrigger.md) 40 | {: .sp-class} 41 | - oCTriggerChangeLevel 42 | {: .sp-class} 43 | - [levelName](#levelname) = "" 44 | {: .sp-string} 45 | - [startVobName](#startvobname) = "" 46 | {: .sp-string} 47 | 48 | === "Gothic 1 (Save)" 49 | 50 | - [zCVob](zCVob.md) 51 | {: .sp-class} 52 | - [*zCTriggerBase*](zCTriggerBase.md) 53 | {: .sp-class} 54 | - [zCTrigger](zCTrigger.md) 55 | {: .sp-class} 56 | - oCTriggerChangeLevel 57 | {: .sp-class} 58 | - [levelName](#levelname) = "" 59 | {: .sp-string} 60 | - [startVobName](#startvobname) = "" 61 | {: .sp-string} 62 | 63 | === "Gothic 2 (Save)" 64 | 65 | - [zCVob](zCVob.md) 66 | {: .sp-class} 67 | - [*zCTriggerBase*](zCTriggerBase.md) 68 | {: .sp-class} 69 | - [zCTrigger](zCTrigger.md) 70 | {: .sp-class} 71 | - oCTriggerChangeLevel 72 | {: .sp-class} 73 | - [levelName](#levelname) = "" 74 | {: .sp-string} 75 | - [startVobName](#startvobname) = "" 76 | {: .sp-string} 77 | 78 | ## Properties 79 | 80 | #### `levelName` {: .sp-string} 81 | 82 | : The name of the level to load including the file extension. 83 | 84 | #### `startVobName` {: .sp-string} 85 | 86 | : The name of the VObject in the new level to place the player at. 87 | -------------------------------------------------------------------------------- /docs/engine/objects/oCTriggerScript.md: -------------------------------------------------------------------------------- 1 | # oCTriggerScript 2 | 3 | !!! abstract inline end "Quick Infos" 4 | **Type:** Virtual Object
5 | **Format Name:** ZenGin Archive
6 | **File Extension:** `.ZEN`
7 | **Class Name:** `oCTriggerScript`
8 | **Version Identifiers:**
9 | — Gothic I: `24577`
10 | — Gothic II: `24577`
11 | **ZenKit Class:** `VTriggerScript`
12 | **Sources:**
13 | — [spacerhilfedatei.sph](https://wiki.worldofgothic.de/doku.php?id=spacer:hilfedatei) 14 | 15 | A special [`zCTrigger`](zCTrigger.md) which in addition to performing all other trigger actions also calls a script 16 | function when the trigger is activated. `OnUntrigger` events do not result in the script function being called. 17 | 18 | === "Gothic 1" 19 | 20 | - [zCVob](zCVob.md) 21 | {: .sp-class} 22 | - [*zCTriggerBase*](zCTriggerBase.md) 23 | {: .sp-class} 24 | - [zCTrigger](zCTrigger.md) 25 | {: .sp-class} 26 | - oCTriggerScript 27 | {: .sp-class} 28 | - [scriptFunc](#scriptfunc) = "" 29 | {: .sp-string} 30 | 31 | === "Gothic 2" 32 | 33 | - [zCVob](zCVob.md) 34 | {: .sp-class} 35 | - [*zCTriggerBase*](zCTriggerBase.md) 36 | {: .sp-class} 37 | - [zCTrigger](zCTrigger.md) 38 | {: .sp-class} 39 | - oCTriggerScript 40 | {: .sp-class} 41 | - [scriptFunc](#scriptfunc) = "" 42 | {: .sp-string} 43 | 44 | === "Gothic 1 (Save)" 45 | 46 | - [zCVob](zCVob.md) 47 | {: .sp-class} 48 | - [*zCTriggerBase*](zCTriggerBase.md) 49 | {: .sp-class} 50 | - [zCTrigger](zCTrigger.md) 51 | {: .sp-class} 52 | - oCTriggerScript 53 | {: .sp-class} 54 | - [scriptFunc](#scriptfunc) = "" 55 | {: .sp-string} 56 | 57 | === "Gothic 2 (Save)" 58 | 59 | - [zCVob](zCVob.md) 60 | {: .sp-class} 61 | - [*zCTriggerBase*](zCTriggerBase.md) 62 | {: .sp-class} 63 | - [zCTrigger](zCTrigger.md) 64 | {: .sp-class} 65 | - oCTriggerScript 66 | {: .sp-class} 67 | - [scriptFunc](#scriptfunc) = "" 68 | {: .sp-string} 69 | 70 | ## Properties 71 | 72 | #### `scriptFunc` {: .sp-string} 73 | 74 | : The name script function to call when the trigger successfully processes a message. 75 | -------------------------------------------------------------------------------- /docs/engine/objects/oCVob.md: -------------------------------------------------------------------------------- 1 | # oCVob 2 | 3 | !!! abstract inline end "Quick Infos" 4 | **Type:** Virtual Object
5 | **Format Name:** ZenGin Archive
6 | **File Extension:** `.ZEN`
7 | **Class Name:** `oCVob`
8 | **Version Identifiers:**
9 | — Gothic I: `12289`
10 | — Gothic II: *Unused*
11 | **ZenKit Class:** — 12 | 13 | 14 | === "Gothic 1" 15 | 16 | - [zCVob](zCVob.md) 17 | {: .sp-class} 18 | - oCVob 19 | {: .sp-class} 20 | - <empty> 21 | {: .sp-none} 22 | 23 | === "Gothic 2" 24 | 25 | - [zCVob](zCVob.md) 26 | {: .sp-class} 27 | - oCVob 28 | {: .sp-class} 29 | - <empty> 30 | {: .sp-none} 31 | 32 | === "Gothic 1 (Save)" 33 | 34 | - [zCVob](zCVob.md) 35 | {: .sp-class} 36 | - oCVob 37 | {: .sp-class} 38 | - <empty> 39 | {: .sp-none} 40 | 41 | === "Gothic 2 (Save)" 42 | 43 | - [zCVob](zCVob.md) 44 | {: .sp-class} 45 | - oCVob 46 | {: .sp-class} 47 | - <empty> 48 | {: .sp-none} 49 | -------------------------------------------------------------------------------- /docs/engine/objects/oCZoneMusicDefault.md: -------------------------------------------------------------------------------- 1 | # oCZoneMusicDefault 2 | 3 | !!! abstract inline end "Quick Infos" 4 | **Type:** Virtual Object
5 | **Format Name:** ZenGin Archive
6 | **File Extension:** `.ZEN`
7 | **Class Name:** `oCZoneMusicDefault`
8 | **Version Identifiers:**
9 | — Gothic I: `0`
10 | — Gothic II: `0`
11 | **ZenKit Class:** `VZoneMusicDefault`
12 | **Sources:**
13 | — [spacerhilfedatei.sph](https://wiki.worldofgothic.de/doku.php?id=spacer:hilfedatei) 14 | 15 | Determines the default music to be played when the camera is outside any [`oCZoneMusic`](oCZoneMusic.md) zones. The 16 | volume-related options of the zone are ignored. There may only be one `oCZoneMusicDefault` object in a world. 17 | 18 | === "Gothic 1" 19 | 20 | - [zCVob](zCVob.md) 21 | {: .sp-class} 22 | - [*zCZone*](zCZone.md) 23 | {: .sp-class} 24 | - [oCZoneMusic](oCZoneMusic.md) 25 | {: .sp-class} 26 | - oCZoneMusicDefault 27 | {: .sp-class} 28 | - <empty> 29 | {: .sp-none} 30 | 31 | === "Gothic 2" 32 | 33 | - [zCVob](zCVob.md) 34 | {: .sp-class} 35 | - [*zCZone*](zCZone.md) 36 | {: .sp-class} 37 | - [oCZoneMusic](oCZoneMusic.md) 38 | {: .sp-class} 39 | - oCZoneMusicDefault 40 | {: .sp-class} 41 | - <empty> 42 | {: .sp-none} 43 | 44 | === "Gothic 1 (Save)" 45 | 46 | - [zCVob](zCVob.md) 47 | {: .sp-class} 48 | - [*zCZone*](zCZone.md) 49 | {: .sp-class} 50 | - [oCZoneMusic](oCZoneMusic.md) 51 | {: .sp-class} 52 | - oCZoneMusicDefault 53 | {: .sp-class} 54 | - <empty> 55 | {: .sp-none} 56 | 57 | === "Gothic 2 (Save)" 58 | 59 | - [zCVob](zCVob.md) 60 | {: .sp-class} 61 | - [*zCZone*](zCZone.md) 62 | {: .sp-class} 63 | - [oCZoneMusic](oCZoneMusic.md) 64 | {: .sp-class} 65 | - oCZoneMusicDefault 66 | {: .sp-class} 67 | - <empty> 68 | {: .sp-none} 69 | -------------------------------------------------------------------------------- /docs/engine/objects/zCEarthquake.md: -------------------------------------------------------------------------------- 1 | # zCEarthquake 2 | 3 | !!! abstract inline end "Quick Infos" 4 | **Type:** Virtual Object
5 | **Format Name:** ZenGin Archive
6 | **File Extension:** `.ZEN`
7 | **Class Name:** `zCEarthquake`
8 | **Version Identifiers:**
9 | — Gothic I: *Unused*
10 | — Gothic II: `52224`
11 | **ZenKit Class:** `VEarthquake`
12 | **Sources:**
13 | — [spacerhilfedatei.sph](https://wiki.worldofgothic.de/doku.php?id=spacer:hilfedatei)
14 | — [gothic-library.ru](http://www.gothic-library.ru/publ/zcearthquake/1-1-0-516) 15 | 16 | 17 | A VObject used to create an earthquake effect when it receives an `OnTrigger` event. An earthquake is represented 18 | by a shaking camera. 19 | 20 | !!! warning 21 | This VObject is only available in Gothic II. 22 | 23 | === "Gothic 1" 24 | 25 | *Unavailable* 26 | 27 | === "Gothic 2" 28 | 29 | - [zCVob](zCVob.md) 30 | {: .sp-class} 31 | - [*zCEffect*](zCEffect.md) 32 | {: .sp-class} 33 | - zCEarthquake 34 | {: .sp-class} 35 | - Earthquake 36 | {: .sp-folder} 37 | - [radius](#radius) = 200 38 | {: .sp-float} 39 | - [timeSec](#timeSec) = 5 40 | {: .sp-float} 41 | - [amplitudeCM](#amplitudeCM) = 0 42 | {: .sp-vec} 43 | 44 | === "Gothic 1 (Save)" 45 | 46 | *Unavailable* 47 | 48 | === "Gothic 2 (Save)" 49 | 50 | - [zCVob](zCVob.md) 51 | {: .sp-class} 52 | - [*zCEffect*](zCEffect.md) 53 | {: .sp-class} 54 | - zCEarthquake 55 | {: .sp-class} 56 | - Earthquake 57 | {: .sp-folder} 58 | - [radius](#radius) = 200 59 | {: .sp-float} 60 | - [timeSec](#timeSec) = 5 61 | {: .sp-float} 62 | - [amplitudeCM](#amplitudeCM) = 0 63 | {: .sp-vec} 64 | 65 | ## Properties 66 | 67 | #### `radius` {: .sp-float} 68 | 69 | : The radius of the earthquake effect 70 | 71 | #### `timeSec` {: .sp-float} 72 | 73 | : The duration of the earthquake effect in seconds. 74 | 75 | #### `amplitudeCM` {: .sp-float} 76 | 77 | : The amplitude of the earthquake effect. 78 | -------------------------------------------------------------------------------- /docs/engine/objects/zCEffect.md: -------------------------------------------------------------------------------- 1 | # zCEffect 2 | 3 | !!! abstract inline end "Quick Infos" 4 | **Type:** Virtual Object
5 | **Format Name:** ZenGin Archive
6 | **File Extension:** `.ZEN`
7 | **Class Name:** `zCEffect`
8 | **Version Identifiers:**
9 | — Gothic I: `12289`
10 | — Gothic II: `52224`
11 | **ZenKit Class:** —
12 | 13 | The base class for many visual and sound effects. 14 | 15 | !!! warning 16 | This object is an abstract base class and cannot be instantiated by itself. 17 | 18 | === "Gothic 1" 19 | 20 | - [zCVob](zCVob.md) 21 | {: .sp-class} 22 | - zCEffect 23 | {: .sp-class} 24 | - <empty> 25 | {: .sp-empty} 26 | 27 | === "Gothic 2" 28 | 29 | - [zCVob](zCVob.md) 30 | {: .sp-class} 31 | - zCEffect 32 | {: .sp-class} 33 | - <empty> 34 | {: .sp-empty} 35 | 36 | === "Gothic 1 (Save)" 37 | 38 | - [zCVob](zCVob.md) 39 | {: .sp-class} 40 | - zCEffect 41 | {: .sp-class} 42 | - <empty> 43 | {: .sp-empty} 44 | 45 | === "Gothic 2 (Save)" 46 | 47 | - [zCVob](zCVob.md) 48 | {: .sp-class} 49 | - zCEffect 50 | {: .sp-class} 51 | - <empty> 52 | {: .sp-empty} 53 | -------------------------------------------------------------------------------- /docs/engine/objects/zCTriggerBase.md: -------------------------------------------------------------------------------- 1 | # zCTriggerBase 2 | 3 | !!! abstract inline end "Quick Infos" 4 | **Type:** Virtual Object
5 | **Format Name:** ZenGin Archive
6 | **File Extension:** `.ZEN`
7 | **Class Name:** `zCTriggerBase`
8 | **Version Identifiers:**
9 | — Gothic I: `12289`
10 | — Gothic II: `52224`
11 | **ZenKit Class:** —
12 | 13 | The base class for many triggers. 14 | 15 | !!! warning 16 | This object is an abstract base class and cannot be instantiated by itself. 17 | 18 | === "Gothic 1" 19 | 20 | - [zCVob](zCVob.md) 21 | {: .sp-class} 22 | - zCTriggerBase 23 | {: .sp-class} 24 | - [triggerTarget](#triggerTarget) = "" 25 | {: .sp-string} 26 | 27 | === "Gothic 2" 28 | 29 | - [zCVob](zCVob.md) 30 | {: .sp-class} 31 | - zCTriggerBase 32 | {: .sp-class} 33 | - [triggerTarget](#triggerTarget) = "" 34 | {: .sp-string} 35 | 36 | === "Gothic 1 (Save)" 37 | 38 | - [zCVob](zCVob.md) 39 | {: .sp-class} 40 | - zCTriggerBase 41 | {: .sp-class} 42 | - [triggerTarget](#triggerTarget) = "" 43 | {: .sp-string} 44 | 45 | === "Gothic 2 (Save)" 46 | 47 | - [zCVob](zCVob.md) 48 | {: .sp-class} 49 | - zCTriggerBase 50 | {: .sp-class} 51 | - [triggerTarget](#triggerTarget) = "" 52 | {: .sp-string} 53 | 54 | ## Properties 55 | 56 | #### `triggerTarget` {: .sp-string} 57 | 58 | : The name of VObject to send `OnTrigger` and `OnUntrigger` events to after processing. 59 | -------------------------------------------------------------------------------- /docs/engine/objects/zCTriggerUntouch.md: -------------------------------------------------------------------------------- 1 | # zCTriggerUntouch 2 | 3 | !!! abstract inline end "Quick Infos" 4 | **Type:** Virtual Object
5 | **Format Name:** ZenGin Archive
6 | **File Extension:** `.ZEN`
7 | **Class Name:** `zCTriggerUntouch`
8 | **Version Identifiers:**
9 | — Gothic I: `52224`
10 | — Gothic II: `52224`
11 | **ZenKit Class:** `VTriggerUntouch`
12 | **Sources:**
13 | — [spacerhilfedatei.sph](https://wiki.worldofgothic.de/doku.php?id=spacer:hilfedatei) 14 | 15 | A trigger which fires an `OnTrigger` event to its [`triggerTarget`](zCTriggerBase.md#triggertarget) if any `OnUntouch` 16 | event is emitted from an inanimate object within the object's bounding box. 17 | 18 | === "Gothic 1" 19 | 20 | - [zCVob](zCVob.md) 21 | {: .sp-class} 22 | - [*zCTriggerBase*](zCTriggerBase.md) 23 | {: .sp-class} 24 | - zCTriggerUntouch 25 | {: .sp-class} 26 | - <empty> 27 | {: .sp-none} 28 | 29 | === "Gothic 2" 30 | 31 | - [zCVob](zCVob.md) 32 | {: .sp-class} 33 | - [*zCTriggerBase*](zCTriggerBase.md) 34 | {: .sp-class} 35 | - zCTriggerUntouch 36 | {: .sp-class} 37 | - <empty> 38 | {: .sp-none} 39 | 40 | === "Gothic 1 (Save)" 41 | 42 | - [zCVob](zCVob.md) 43 | {: .sp-class} 44 | - [*zCTriggerBase*](zCTriggerBase.md) 45 | {: .sp-class} 46 | - zCTriggerUntouch 47 | {: .sp-class} 48 | - <empty> 49 | {: .sp-none} 50 | 51 | === "Gothic 2 (Save)" 52 | 53 | - [zCVob](zCVob.md) 54 | {: .sp-class} 55 | - [*zCTriggerBase*](zCTriggerBase.md) 56 | {: .sp-class} 57 | - zCTriggerUntouch 58 | {: .sp-class} 59 | - <empty> 60 | {: .sp-none} 61 | -------------------------------------------------------------------------------- /docs/engine/objects/zCTriggerWorldStart.md: -------------------------------------------------------------------------------- 1 | # zCTriggerWorldStart 2 | 3 | !!! abstract inline end "Quick Infos" 4 | **Type:** Virtual Object
5 | **Format Name:** ZenGin Archive
6 | **File Extension:** `.ZEN`
7 | **Class Name:** `zCTriggerWorldStart`
8 | **Version Identifiers:**
9 | — Gothic I: `52224`
10 | — Gothic II: `52224`
11 | **ZenKit Class:** `VTriggerWorldStart`
12 | **Sources:**
13 | — [spacerhilfedatei.sph](https://wiki.worldofgothic.de/doku.php?id=spacer:hilfedatei) 14 | 15 | A special trigger which fires an `OnTrigger` event to its [`triggerTarget`](zCTriggerBase.md#triggertarget) when the 16 | world is loaded and started. 17 | 18 | === "Gothic 1" 19 | 20 | - [zCVob](zCVob.md) 21 | {: .sp-class} 22 | - [*zCTriggerBase*](zCTriggerBase.md) 23 | {: .sp-class} 24 | - zCTriggerWorldStart 25 | {: .sp-class} 26 | - [fireOnlyFirstTime](#fireonlyfirsttime) = FALSE 27 | {: .sp-bool} 28 | 29 | === "Gothic 2" 30 | 31 | - [zCVob](zCVob.md) 32 | {: .sp-class} 33 | - [*zCTriggerBase*](zCTriggerBase.md) 34 | {: .sp-class} 35 | - zCTriggerWorldStart 36 | {: .sp-class} 37 | - [fireOnlyFirstTime](#fireonlyfirsttime) = FALSE 38 | {: .sp-bool} 39 | 40 | === "Gothic 1 (Save)" 41 | 42 | - [zCVob](zCVob.md) 43 | {: .sp-class} 44 | - [*zCTriggerBase*](zCTriggerBase.md) 45 | {: .sp-class} 46 | - zCTriggerWorldStart 47 | {: .sp-class} 48 | - [fireOnlyFirstTime](#fireonlyfirsttime) = FALSE 49 | {: .sp-bool} 50 | 51 | === "Gothic 2 (Save)" 52 | 53 | - [zCVob](zCVob.md) 54 | {: .sp-class} 55 | - [*zCTriggerBase*](zCTriggerBase.md) 56 | {: .sp-class} 57 | - zCTriggerWorldStart 58 | {: .sp-class} 59 | - [fireOnlyFirstTime](#fireonlyfirsttime) = FALSE 60 | {: .sp-bool} 61 | 62 | ## Properties 63 | 64 | #### `fireOnlyFirstTime` {: .sp-bool} 65 | 66 | : Determines whether to fire the `OnTrigger` event only the first time the world is loaded. 67 | 68 | * `TRUE` — Only fire the event if this is the first time the world is loaded. 69 | * `FALSE` — Fire the event every time the world is loaded. 70 | -------------------------------------------------------------------------------- /docs/engine/objects/zCVisual.md: -------------------------------------------------------------------------------- 1 | # zCVisual 2 | 3 | The base class for visual objects in the game world. It itself does not have any additional properties. The following 4 | visuals exist but also don't have any properties associated with them: 5 | 6 | - zCMesh 7 | {: .sp-class} 8 | - zCProgMeshProto 9 | {: .sp-class} 10 | - zCParticleFX 11 | {: .sp-class} 12 | - zCAICamera 13 | {: .sp-class} 14 | - zCModel 15 | {: .sp-class} 16 | - zCMorphMesh 17 | {: .sp-class} 18 | 19 | The only visual which has additional data associated with it is [zCDecal](zCDecal.md). 20 | -------------------------------------------------------------------------------- /docs/engine/objects/zCVobAnimate.md: -------------------------------------------------------------------------------- 1 | # zCVobAnimate 2 | 3 | !!! abstract inline end "Quick Infos" 4 | **Type:** Virtual Object
5 | **Format Name:** ZenGin Archive
6 | **File Extension:** `.ZEN`
7 | **Class Name:** `zCVobAnimate`
8 | **Version Identifiers:**
9 | — Gothic I: `12289`
10 | — Gothic II: `52224`
11 | **ZenKit Class:** `VAnimate`
12 | **Sources:**
13 | — [spacerhilfedatei.sph](https://wiki.worldofgothic.de/doku.php?id=spacer:hilfedatei)
14 | — [gothic-library.ru](http://www.gothic-library.ru/publ/zcvobanimate/1-1-0-523) 15 | 16 | A VObject used to create animated models. The visual of such objects can either be a 17 | [morph mesh](../../engine/formats/morph-mesh.md) or a model with a skeletal animation 18 | (i.e. a [model script](../../engine/formats/model-script.md)). The animation of these objects can be started 19 | and stopped using `OnTrigger` and `OnUntrigger` events. 20 | 21 | === "Gothic 1" 22 | 23 | - [zCVob](zCVob.md) 24 | {: .sp-class} 25 | - [*zCEffect*](zCEffect.md) 26 | {: .sp-class} 27 | - zCVobAnimate 28 | {: .sp-class} 29 | - [startOn](#starton) = "" 30 | {: .sp-bool} 31 | 32 | === "Gothic 2" 33 | 34 | - [zCVob](zCVob.md) 35 | {: .sp-class} 36 | - [*zCEffect*](zCEffect.md) 37 | {: .sp-class} 38 | - zCVobAnimate 39 | {: .sp-class} 40 | - [startOn](#starton) = "" 41 | {: .sp-bool} 42 | 43 | === "Gothic 1 (Save)" 44 | 45 | - [zCVob](zCVob.md) 46 | {: .sp-class} 47 | - [*zCEffect*](zCEffect.md) 48 | {: .sp-class} 49 | - zCVobAnimate 50 | {: .sp-class} 51 | - [startOn](#starton) = "" 52 | {: .sp-bool} 53 | - [isRunning](#isrunning) = FALSE 54 | {: .sp-bool} 55 | 56 | === "Gothic 2 (Save)" 57 | 58 | - [zCVob](zCVob.md) 59 | {: .sp-class} 60 | - [*zCEffect*](zCEffect.md) 61 | {: .sp-class} 62 | - zCVobAnimate 63 | {: .sp-class} 64 | - [startOn](#starton) = "" 65 | {: .sp-bool} 66 | - [isRunning](#isrunning) = FALSE 67 | {: .sp-bool} 68 | 69 | ## Properties 70 | 71 | #### `startOn` {: .sp-bool} 72 | 73 | : Whether to start this animation when loading the level. 74 | 75 | * `TRUE` — Immediately start the animation when the level is loaded. 76 | * `FALSE` — Don't automatically start the animation. 77 | 78 | #### `isRunning` {: .sp-bool} 79 | 80 | : Unknown. 81 | 82 | !!! warning 83 | This property is only available in saved games. 84 | -------------------------------------------------------------------------------- /docs/engine/objects/zCVobLensFlare.md: -------------------------------------------------------------------------------- 1 | # zCVobLensFlare 2 | 3 | !!! abstract inline end "Quick Infos" 4 | **Type:** Virtual Object
5 | **Format Name:** ZenGin Archive
6 | **File Extension:** `.ZEN`
7 | **Class Name:** `zCVobLensFlare`
8 | **Version Identifiers:**
9 | — Gothic I: `64704`
10 | — Gothic II: `193`
11 | **ZenKit Class:** `VLensFlare`
12 | **Sources:**
13 | — [spacerhilfedatei.sph](https://wiki.worldofgothic.de/doku.php?id=spacer:hilfedatei)
14 | — [gothic-library.ru](http://www.gothic-library.ru/publ/class_zcvoblensflare/1-1-0-524) 15 | 16 | Represents a lens flare effect. Behaves exactly like the base [`zCVob`](zCVob.md) but has a lens flare effect. 17 | 18 | === "Gothic 1" 19 | 20 | - [zCVob](zCVob.md) 21 | {: .sp-class} 22 | - [*zCEffect*](zCEffect.md) 23 | {: .sp-class} 24 | - zCVobLensFlare 25 | {: .sp-class} 26 | - [lensflareFX](#lensflarefx) = "" 27 | {: .sp-string} 28 | 29 | === "Gothic 2" 30 | 31 | - [zCVob](zCVob.md) 32 | {: .sp-class} 33 | - [*zCEffect*](zCEffect.md) 34 | {: .sp-class} 35 | - zCVobLensFlare 36 | {: .sp-class} 37 | - [lensflareFX](#lensflarefx) = "" 38 | {: .sp-string} 39 | 40 | === "Gothic 1 (Save)" 41 | 42 | - [zCVob](zCVob.md) 43 | {: .sp-class} 44 | - [*zCEffect*](zCEffect.md) 45 | {: .sp-class} 46 | - zCVobLensFlare 47 | {: .sp-class} 48 | - [lensflareFX](#lensflarefx) = "" 49 | {: .sp-string} 50 | 51 | === "Gothic 2 (Save)" 52 | 53 | - [zCVob](zCVob.md) 54 | {: .sp-class} 55 | - [*zCEffect*](zCEffect.md) 56 | {: .sp-class} 57 | - zCVobLensFlare 58 | {: .sp-class} 59 | - [lensflareFX](#lensflarefx) = "" 60 | {: .sp-string} 61 | 62 | ## Properties 63 | 64 | #### `lensflareFX` {: .sp-string} 65 | 66 | : The name of the lens flare effect. Must be one of the effects listed in `/_work/data/Presets/Lensflare.zen`. 67 | -------------------------------------------------------------------------------- /docs/engine/objects/zCVobLevelCompo.md: -------------------------------------------------------------------------------- 1 | # zCVobLevelCompo 2 | 3 | !!! abstract inline end "Quick Infos" 4 | **Type:** Virtual Object
5 | **Format Name:** ZenGin Archive
6 | **File Extension:** `.ZEN`
7 | **Class Name:** `zCVobLevelCompo`
8 | **Version Identifiers:**
9 | — Gothic I: `12289`
10 | — Gothic II: `52224`
11 | **ZenKit Class:** `VLevel`
12 | **Sources:**
13 | — [gothic-library.ru](http://www.gothic-library.ru/publ/class_zcvoblevelcompo/1-1-0-496) 14 | 15 | 16 | Used as root objects of game levels. Only used to group together other VObjects. Only one of the `zCVobLevelCompo` 17 | objects will have a visual which corresponds to the mesh of the world it exists in. Generally, it can be ignored and 18 | has no relevance to other VObjects in the hierarchy. 19 | 20 | === "Gothic 1" 21 | 22 | - [zCVob](zCVob.md) 23 | {: .sp-class} 24 | - zCVobLevelCompo 25 | {: .sp-class} 26 | - <empty> 27 | {: .sp-none} 28 | 29 | === "Gothic 2" 30 | 31 | - [zCVob](zCVob.md) 32 | {: .sp-class} 33 | - zCVobLevelCompo 34 | {: .sp-class} 35 | - <empty> 36 | {: .sp-none} 37 | 38 | === "Gothic 1 (Save)" 39 | 40 | - [zCVob](zCVob.md) 41 | {: .sp-class} 42 | - zCVobLevelCompo 43 | {: .sp-class} 44 | - <empty> 45 | {: .sp-none} 46 | 47 | === "Gothic 2 (Save)" 48 | 49 | - [zCVob](zCVob.md) 50 | {: .sp-class} 51 | - zCVobLevelCompo 52 | {: .sp-class} 53 | - <empty> 54 | {: .sp-none} 55 | -------------------------------------------------------------------------------- /docs/engine/objects/zCVobScreenFX.md: -------------------------------------------------------------------------------- 1 | # zCVobScreenFX 2 | 3 | !!! abstract inline end "Quick Infos" 4 | **Type:** Virtual Object
5 | **Format Name:** ZenGin Archive
6 | **File Extension:** `.ZEN`
7 | **Class Name:** `zCVobScreenFX`
8 | **Version Identifiers:**
9 | — Gothic I: `12289`
10 | — Gothic II: `52224`
11 | **ZenKit Class:** `VScreenEffect`
12 | **Sources:**
13 | — [spacerhilfedatei.sph](https://wiki.worldofgothic.de/doku.php?id=spacer:hilfedatei)
14 | — [gothic-library.ru](http://www.gothic-library.ru/publ/zcvobscreenfx/1-1-0-525) 15 | 16 | Screen effect VObjects are used to create special effects. They are used for field-of-view changes, adding black bars 17 | for a cinematic feel to the game and other post-processing effects. 18 | 19 | === "Gothic 1" 20 | 21 | - [zCVob](zCVob.md) 22 | {: .sp-class} 23 | - [*zCEffect*](zCEffect.md) 24 | {: .sp-class} 25 | - zCVobScreenFX 26 | {: .sp-class} 27 | - <empty> 28 | {: .sp-none} 29 | 30 | === "Gothic 2" 31 | 32 | - [zCVob](zCVob.md) 33 | {: .sp-class} 34 | - [*zCEffect*](zCEffect.md) 35 | {: .sp-class} 36 | - zCVobScreenFX 37 | {: .sp-class} 38 | - <empty> 39 | {: .sp-none} 40 | 41 | === "Gothic 1 (Save)" 42 | 43 | - [zCVob](zCVob.md) 44 | {: .sp-class} 45 | - [*zCEffect*](zCEffect.md) 46 | {: .sp-class} 47 | - zCVobScreenFX 48 | {: .sp-class} 49 | - <empty> 50 | {: .sp-none} 51 | 52 | === "Gothic 2 (Save)" 53 | 54 | - [zCVob](zCVob.md) 55 | {: .sp-class} 56 | - [*zCEffect*](zCEffect.md) 57 | {: .sp-class} 58 | - zCVobScreenFX 59 | {: .sp-class} 60 | - <empty> 61 | {: .sp-none} 62 | -------------------------------------------------------------------------------- /docs/engine/objects/zCVobSpot.md: -------------------------------------------------------------------------------- 1 | # zCVobSpot 2 | 3 | !!! abstract inline end "Quick Infos" 4 | **Type:** Virtual Object
5 | **Format Name:** ZenGin Archive
6 | **File Extension:** `.ZEN`
7 | **Class Name:** `zCVobSpot`
8 | **Version Identifiers:**
9 | — Gothic I: `12289`
10 | — Gothic II: `52224`
11 | **ZenKit Class:** `VSpot`
12 | **Sources:**
13 | — [spacerhilfedatei.sph](https://wiki.worldofgothic.de/doku.php?id=spacer:hilfedatei)
14 | — [gothic-library.ru](http://www.gothic-library.ru/publ/class_zcvobspot/1-1-0-498) 15 | 16 | Spot objects are used to mark a position and orientation in virtual space. They are equivalent in function to way net 17 | free points and can be used in scripts to spawn other objects at their location. 18 | 19 | === "Gothic 1" 20 | 21 | - [zCVob](zCVob.md) 22 | {: .sp-class} 23 | - zCVobSpot 24 | {: .sp-class} 25 | - <empty> 26 | {: .sp-none} 27 | 28 | === "Gothic 2" 29 | 30 | - [zCVob](zCVob.md) 31 | {: .sp-class} 32 | - zCVobSpot 33 | {: .sp-class} 34 | - <empty> 35 | {: .sp-none} 36 | 37 | === "Gothic 1 (Save)" 38 | 39 | - [zCVob](zCVob.md) 40 | {: .sp-class} 41 | - zCVobSpot 42 | {: .sp-class} 43 | - <empty> 44 | {: .sp-none} 45 | 46 | === "Gothic 2 (Save)" 47 | 48 | - [zCVob](zCVob.md) 49 | {: .sp-class} 50 | - zCVobSpot 51 | {: .sp-class} 52 | - <empty> 53 | {: .sp-none} 54 | -------------------------------------------------------------------------------- /docs/engine/objects/zCVobStair.md: -------------------------------------------------------------------------------- 1 | # zCVobStair 2 | 3 | !!! abstract inline end "Quick Infos" 4 | **Type:** Virtual Object
5 | **Format Name:** ZenGin Archive
6 | **File Extension:** `.ZEN`
7 | **Class Name:** `zCVobStair`
8 | **Version Identifiers:**
9 | — Gothic I: `12289`
10 | — Gothic II: *Unused*
11 | **Sources:**
12 | — [spacerhilfedatei.sph](https://wiki.worldofgothic.de/doku.php?id=spacer:hilfedatei)
13 | — [gothic-library.ru](http://www.gothic-library.ru/publ/class_zcvobstair/1-1-0-499) 14 | 15 | 16 | Used to mark staircase models in Gothic I only. This type of VObject was taken into account by the NPC pathfinding 17 | routines to properly ascend and descend staircases. 18 | 19 | !!! warning 20 | This VObject is only available in Gothic I. 21 | 22 | === "Gothic 1" 23 | 24 | - [zCVob](zCVob.md) 25 | {: .sp-class} 26 | - zCVobStair 27 | {: .sp-class} 28 | - <empty> 29 | {: .sp-none} 30 | 31 | === "Gothic 2" 32 | 33 | *Unavailable.* 34 | 35 | === "Gothic 1 (Save)" 36 | 37 | - [zCVob](zCVob.md) 38 | {: .sp-class} 39 | - zCVobStair 40 | {: .sp-class} 41 | - <empty> 42 | {: .sp-none} 43 | 44 | === "Gothic 2 (Save)" 45 | 46 | *Unavailable.* 47 | -------------------------------------------------------------------------------- /docs/engine/objects/zCVobStartpoint.md: -------------------------------------------------------------------------------- 1 | # zCVobStartpoint 2 | 3 | !!! abstract inline end "Quick Infos" 4 | **Type:** Virtual Object
5 | **Format Name:** ZenGin Archive
6 | **File Extension:** `.ZEN`
7 | **Class Name:** `zCVobStartpoint`
8 | **Version Identifiers:**
9 | — Gothic I: `12289`
10 | — Gothic II: `52224`
11 | **ZenKit Class:** `VStartPoint`
12 | **Sources:**
13 | — [spacerhilfedatei.sph](https://wiki.worldofgothic.de/doku.php?id=spacer:hilfedatei)
14 | — [gothic-library.ru](http://www.gothic-library.ru/publ/class_zcvobstartpoint/1-1-0-500) 15 | 16 | Marks the players initial position when loading in the game level. Behaves like [`zCVobSpot`](zCVobSpot.md) but causes 17 | the game to put the player at its location and in its orientation when the world is loaded. 18 | 19 | === "Gothic 1" 20 | 21 | - [zCVob](zCVob.md) 22 | {: .sp-class} 23 | - zCVobStartpoint 24 | {: .sp-class} 25 | - <empty> 26 | {: .sp-none} 27 | 28 | === "Gothic 2" 29 | 30 | - [zCVob](zCVob.md) 31 | {: .sp-class} 32 | - zCVobStartpoint 33 | {: .sp-class} 34 | - <empty> 35 | {: .sp-none} 36 | 37 | === "Gothic 1 (Save)" 38 | 39 | - [zCVob](zCVob.md) 40 | {: .sp-class} 41 | - zCVobStartpoint 42 | {: .sp-class} 43 | - <empty> 44 | {: .sp-none} 45 | 46 | === "Gothic 2 (Save)" 47 | 48 | - [zCVob](zCVob.md) 49 | {: .sp-class} 50 | - zCVobStartpoint 51 | {: .sp-class} 52 | - <empty> 53 | {: .sp-none} 54 | -------------------------------------------------------------------------------- /docs/engine/objects/zCZone.md: -------------------------------------------------------------------------------- 1 | # zCZone 2 | 3 | !!! abstract inline end "Quick Infos" 4 | **Type:** Virtual Object
5 | **Format Name:** ZenGin Archive
6 | **File Extension:** `.ZEN`
7 | **Class Name:** `zCZone`
8 | **Version Identifiers:**
9 | — Gothic I: `12289`
10 | — Gothic II: `52224`
11 | **ZenKit Class:** —
12 | 13 | The base class for effect zones. 14 | 15 | !!! warning 16 | This object is an abstract base class and cannot be instantiated by itself. 17 | 18 | === "Gothic 1" 19 | 20 | - [zCVob](zCVob.md) 21 | {: .sp-class} 22 | - zCZone 23 | {: .sp-class} 24 | - <empty> 25 | {: .sp-empty} 26 | 27 | === "Gothic 2" 28 | 29 | - [zCVob](zCVob.md) 30 | {: .sp-class} 31 | - zCZone 32 | {: .sp-class} 33 | - <empty> 34 | {: .sp-empty} 35 | 36 | === "Gothic 1 (Save)" 37 | 38 | - [zCVob](zCVob.md) 39 | {: .sp-class} 40 | - zCZone 41 | {: .sp-class} 42 | - <empty> 43 | {: .sp-empty} 44 | 45 | === "Gothic 2 (Save)" 46 | 47 | - [zCVob](zCVob.md) 48 | {: .sp-class} 49 | - zCZone 50 | {: .sp-class} 51 | - <empty> 52 | {: .sp-empty} 53 | -------------------------------------------------------------------------------- /docs/engine/objects/zCZoneVobFarPlane.md: -------------------------------------------------------------------------------- 1 | # zCZoneVobFarPlane 2 | 3 | !!! abstract inline end "Quick Infos" 4 | **Type:** Virtual Object
5 | **Format Name:** ZenGin Archive
6 | **File Extension:** `.ZEN`
7 | **Class Name:** `zCZoneVobFarPlane`
8 | **Version Identifiers:**
9 | — Gothic I: `12289`
10 | — Gothic II: `52224`
11 | **ZenKit Class:** `VZoneFarPlane`
12 | **Sources:**
13 | — [gothic-library.ru](http://www.gothic-library.ru/publ/class_zczonevobfarplane/1-1-0-706) 14 | 15 | 16 | A VObject which defines the loading range of VObjects within its bounding box. 17 | 18 | === "Gothic 1" 19 | 20 | - [zCVob](zCVob.md) 21 | {: .sp-class} 22 | - [*zCZone*](zCZone.md) 23 | {: .sp-class} 24 | - zCZoneVobFarPlane 25 | {: .sp-class} 26 | - [vobFarPlaneZ](#vobfarplanez) = 12000.0 27 | {: .sp-float} 28 | - [innerRangePerc](#innerrangeperc) = 0.0 29 | {: .sp-float} 30 | 31 | === "Gothic 2" 32 | 33 | - [zCVob](zCVob.md) 34 | {: .sp-class} 35 | - [*zCZone*](zCZone.md) 36 | {: .sp-class} 37 | - zCZoneVobFarPlane 38 | {: .sp-class} 39 | - [vobFarPlaneZ](#vobfarplanez) = 12000.0 40 | {: .sp-float} 41 | - [innerRangePerc](#innerrangeperc) = 0.0 42 | {: .sp-float} 43 | 44 | === "Gothic 1 (Save)" 45 | 46 | - [zCVob](zCVob.md) 47 | {: .sp-class} 48 | - [*zCZone*](zCZone.md) 49 | {: .sp-class} 50 | - zCZoneVobFarPlane 51 | {: .sp-class} 52 | - [vobFarPlaneZ](#vobfarplanez) = 12000.0 53 | {: .sp-float} 54 | - [innerRangePerc](#innerrangeperc) = 0.0 55 | {: .sp-float} 56 | 57 | === "Gothic 2 (Save)" 58 | 59 | - [zCVob](zCVob.md) 60 | {: .sp-class} 61 | - [*zCZone*](zCZone.md) 62 | {: .sp-class} 63 | - zCZoneVobFarPlane 64 | {: .sp-class} 65 | - [vobFarPlaneZ](#vobfarplanez) = 12000.0 66 | {: .sp-float} 67 | - [innerRangePerc](#innerrangeperc) = 0.0 68 | {: .sp-float} 69 | 70 | ## Properties 71 | 72 | #### `vobFarPlaneZ` {: .sp-float} 73 | 74 | : The loading range of VObject within. 75 | 76 | 77 | #### `innerRangePerc` {: .sp-float} 78 | 79 | : Unknown. 80 | -------------------------------------------------------------------------------- /docs/engine/objects/zCZoneVobFarPlaneDefault.md: -------------------------------------------------------------------------------- 1 | # zCZoneVobFarPlaneDefault 2 | 3 | !!! abstract inline end "Quick Infos" 4 | **Type:** Virtual Object
5 | **Format Name:** ZenGin Archive
6 | **File Extension:** `.ZEN`
7 | **Class Name:** `zCZoneVobFarPlaneDefault`
8 | **Version Identifiers:**
9 | — Gothic I: `12289`
10 | — Gothic II: `52224`
11 | **ZenKit Class:** `VZoneFarPlaneDefault`
12 | **Sources:**
13 | — [gothic-library.ru](http://www.gothic-library.ru/publ/class_zczonevobfarplanedefault/1-1-0-707) 14 | 15 | 16 | A VObject which defines the default loading range of VObjects in the entire world. There may only be one of these 17 | objects in each world. Its effect can be overridden using [zCZoneVobFarPlane](zCZoneVobFarPlane.md) objects. 18 | 19 | === "Gothic 1" 20 | 21 | - [zCVob](zCVob.md) 22 | {: .sp-class} 23 | - [*zCZone*](zCZone.md) 24 | {: .sp-class} 25 | - [zCZoneVobFarPlane](zCZoneVobFarPlane.md) 26 | {: .sp-class} 27 | - zCZoneVobFarPlane 28 | {: .sp-class} 29 | - <empty> 30 | {: .sp-none} 31 | 32 | === "Gothic 2" 33 | 34 | - [zCVob](zCVob.md) 35 | {: .sp-class} 36 | - [*zCZone*](zCZone.md) 37 | {: .sp-class} 38 | - [zCZoneVobFarPlane](zCZoneVobFarPlane.md) 39 | {: .sp-class} 40 | - zCZoneVobFarPlane 41 | {: .sp-class} 42 | - <empty> 43 | {: .sp-none} 44 | 45 | === "Gothic 1 (Save)" 46 | 47 | - [zCVob](zCVob.md) 48 | {: .sp-class} 49 | - [*zCZone*](zCZone.md) 50 | {: .sp-class} 51 | - [zCZoneVobFarPlane](zCZoneVobFarPlane.md) 52 | {: .sp-class} 53 | - zCZoneVobFarPlane 54 | {: .sp-class} 55 | - <empty> 56 | {: .sp-none} 57 | 58 | === "Gothic 2 (Save)" 59 | 60 | - [zCVob](zCVob.md) 61 | {: .sp-class} 62 | - [*zCZone*](zCZone.md) 63 | {: .sp-class} 64 | - [zCZoneVobFarPlane](zCZoneVobFarPlane.md) 65 | {: .sp-class} 66 | - zCZoneVobFarPlane 67 | {: .sp-class} 68 | - <empty> 69 | {: .sp-none} 70 | -------------------------------------------------------------------------------- /docs/engine/objects/zCZoneZFogDefault.md: -------------------------------------------------------------------------------- 1 | # zCZoneZFogDefault 2 | 3 | !!! abstract inline end "Quick Infos" 4 | **Type:** Virtual Object
5 | **Format Name:** ZenGin Archive
6 | **File Extension:** `.ZEN`
7 | **Class Name:** `zCZoneZFogDefault`
8 | **Version Identifiers:**
9 | — Gothic I: `12289`
10 | — Gothic II: `52224`
11 | **ZenKit Class:** `VZoneFogDefault`
12 | **Sources:**
13 | — [gothic-library.ru](http://www.gothic-library.ru/publ/class_zczonezfogdefault/1-1-0-10) 14 | 15 | 16 | A VObject which defines the default fog for the entire world. There may only be one of these objects in each world. 17 | Its effect can be overridden using [zCZoneZFog](zCZoneZFog.md) objects. 18 | 19 | === "Gothic 1" 20 | 21 | - [zCVob](zCVob.md) 22 | {: .sp-class} 23 | - [*zCZone*](zCZone.md) 24 | {: .sp-class} 25 | - [zCZoneZFog](zCZoneZFog.md) 26 | {: .sp-class} 27 | - zCZoneZFogDefault 28 | {: .sp-class} 29 | - <empty> 30 | {: .sp-none} 31 | 32 | === "Gothic 2" 33 | 34 | - [zCVob](zCVob.md) 35 | {: .sp-class} 36 | - [*zCZone*](zCZone.md) 37 | {: .sp-class} 38 | - [zCZoneZFog](zCZoneZFog.md) 39 | {: .sp-class} 40 | - zCZoneZFogDefault 41 | {: .sp-class} 42 | - <empty> 43 | {: .sp-none} 44 | 45 | === "Gothic 1 (Save)" 46 | 47 | - [zCVob](zCVob.md) 48 | {: .sp-class} 49 | - [*zCZone*](zCZone.md) 50 | {: .sp-class} 51 | - [zCZoneZFog](zCZoneZFog.md) 52 | {: .sp-class} 53 | - zCZoneZFogDefault 54 | {: .sp-class} 55 | - <empty> 56 | {: .sp-none} 57 | 58 | === "Gothic 2 (Save)" 59 | 60 | - [zCVob](zCVob.md) 61 | {: .sp-class} 62 | - [*zCZone*](zCZone.md) 63 | {: .sp-class} 64 | - [zCZoneZFog](zCZoneZFog.md) 65 | {: .sp-class} 66 | - zCZoneZFogDefault 67 | {: .sp-class} 68 | - <empty> 69 | {: .sp-none} 70 | -------------------------------------------------------------------------------- /docs/engine/overview.md: -------------------------------------------------------------------------------- 1 | --- 2 | hide: 3 | 4 | - footer 5 | 6 | --- 7 | 8 | # ZenGin Reference 9 | 10 | Welcome to the open *ZenGin* reference documentation. This page contains information about file formats used by the 11 | *ZenGin*, an early 2000's game engine developed by [Piranha Bytes](https://www.piranha-bytes.com/) for the games 12 | [Gothic](https://en.wikipedia.org/wiki/Gothic_(video_game)) 13 | and [Gothic II](https://en.wikipedia.org/wiki/Gothic_(video_game)). 14 | 15 | ## Prerequisites 16 | 17 | To properly understand this documentation, a good understanding of binary data and operations as well as the C 18 | programming language is highly useful. Experience with other data exchange formats such as 19 | [JSON](https://en.wikipedia.org/wiki/JSON) and [XML](https://en.wikipedia.org/wiki/XML) might also be helpful. 20 | -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | # *ZenKit* – Documentation 2 | 3 | ![](assets/logo.png) 4 | 5 | !!! quote 6 | The *ZenKit* project aims to re-implement file formats used by the ZenGin made by [Piranha Bytes](https://www.piranha-bytes.com/) 7 | for their early-2000s games [Gothic](https://en.wikipedia.org/wiki/Gothic_(video_game)) and [Gothic II](https://en.wikipedia.org/wiki/Gothic_II). 8 | It is heavily based on [ZenLib](https://github.com/Try/ZenLib) which is used as an initial reference implementation of the file formats. 9 | 10 | Welcome to the joint *ZenKit* and *ZenGin* reference documentation. Here you will find information about how to 11 | use the *ZenKit* library to parse *ZenGin* files as well as in-depth descriptions of the file formats being used. 12 | 13 | The [Library Reference](library/overview.md) contains information relevant for users of the *ZenKit* library while the 14 | [ZenGin Reference](engine/overview.md) contains detailed information about each file format and the *ZenGin* 15 | itself. 16 | -------------------------------------------------------------------------------- /docs/library/api/mesh.md: -------------------------------------------------------------------------------- 1 | # Meshes 2 | 3 | # Loading Meshes 4 | 5 | === "C" 6 | 7 | ```c title="Example" 8 | #include 9 | #include 10 | 11 | int main(int, const char** argv) { 12 | // Load from a file on disk: 13 | ZkMesh* mesh = ZkMesh_loadPath("MyMesh.MSH"); 14 | ZkMesh_del(mesh); 15 | 16 | // ... or from a VFS: 17 | ZkVfs* vfs = ZkVfs_new(); 18 | ZkVfs_mountDiskHost(vfs, "Meshes.vdf", ZkVfsOverwriteBehavior_OLDER); 19 | mesh = ZkMesh_loadVfs(vfs, "MyMesh.MSH"); 20 | ZkMesh_del(mesh); 21 | ZkVfs_del(vfs); 22 | 23 | return 0; 24 | } 25 | ``` 26 | 27 | === "C++" 28 | 29 | ```cpp title="Example" 30 | #include 31 | #include 32 | #include 33 | 34 | int main(int, char const** argv) { 35 | zenkit::Mesh mesh {}; 36 | 37 | // Load from a file on disk: 38 | auto r = zenkit::Read::from("MyMesh.MSH"); 39 | mesh.load(r.get()); 40 | 41 | // ... or from a VFS 42 | zenkit::Vfs vfs; 43 | vfs.mount_disk("Meshes.vdf", zenkit::VfsOverwriteBehavior::OLDER) 44 | 45 | r = vfs->find("MyMesh.MSH")->open_read(); 46 | mesh.load(r.get()); 47 | 48 | return 0; 49 | } 50 | ``` 51 | 52 | === "C#" 53 | 54 | ```c# title="Example" 55 | using ZenKit; 56 | 57 | // Load from a file on disk: 58 | var mesh = new Mesh("MyMesh.MSH"); 59 | 60 | // ... or from a VFS: 61 | var vfs = new Vfs(); 62 | vfs.MountDisk("Meshes.vdf", VfsOverwriteBehavior.Older); 63 | mesh = new Mesh(vfs, "MyMesh.MSH"); 64 | ``` 65 | 66 | === "Java" 67 | 68 | ```java title="Example" 69 | import dev.gothickit.zenkit.msh.Mesh; 70 | import dev.gothickit.zenkit.vfs.Vfs; 71 | import dev.gothickit.zenkit.vfs.VfsOverwriteBehavior; 72 | 73 | // Load from a file on disk: 74 | var mesh = Mesh.load("MyMesh.MSH"); 75 | 76 | // ... or from a VFS: 77 | var vfs = new Vfs(); 78 | vfs.mountDisk("Meshes.vdf", VfsOverwriteBehavior.OLDER) 79 | mesh = Mesh.load(vfs, "MyMesh.MSH"); 80 | ``` 81 | 82 | === "Python" 83 | 84 | ```python title="Example" 85 | from zenkit import Vfs, VfsOverwriteBehavior, Mesh 86 | 87 | # Load from a file on disk: 88 | mesh = Mesh.load("MyMesh.MSH") 89 | 90 | # ... or from a VFS: 91 | vfs = Vfs() 92 | vfs.mount_disk("Meshes.vdf", clobber=VfsOverwriteBehavior.OLDER) 93 | mesh = Mesh.load(vfs.find("MyMesh.MSH")) 94 | ``` 95 | -------------------------------------------------------------------------------- /docs/library/api/model-hierarchy.md: -------------------------------------------------------------------------------- 1 | # Model Hierarchies 2 | 3 | ### Loading Model Hierarchies 4 | 5 | === "C" 6 | 7 | ```c title="Example" 8 | #include 9 | #include 10 | 11 | int main(int, const char** argv) { 12 | // Load from a file on disk: 13 | ZkModelHierarchy* mdh = ZkModelHierarchy_loadPath("MySkeleton.MDH"); 14 | ZkModelHierarchy_del(mdh); 15 | 16 | // ... or from a VFS: 17 | ZkVfs* vfs = ZkVfs_new(); 18 | ZkVfs_mountDiskHost(vfs, "Anims.vdf", ZkVfsOverwriteBehavior_OLDER); 19 | mdh = ZkModelHierarchy_loadVfs(vfs, "MySkeleton.MDH"); 20 | ZkModelHierarchy_del(mdh); 21 | ZkVfs_del(vfs); 22 | 23 | return 0; 24 | } 25 | ``` 26 | 27 | === "C++" 28 | 29 | ```cpp title="Example" 30 | #include 31 | #include 32 | #include 33 | 34 | int main(int, char const** argv) { 35 | zenkit::ModelHierarchy mdh {}; 36 | 37 | // Load from a file on disk: 38 | auto r = zenkit::Read::from("MySkeleton.MDH"); 39 | mdh.load(r.get()); 40 | 41 | // ... or from a VFS 42 | zenkit::Vfs vfs; 43 | vfs.mount_disk("Anims.vdf", zenkit::VfsOverwriteBehavior::OLDER) 44 | 45 | r = vfs->find("MySkeleton.MDH")->open_read(); 46 | mdh.load(r.get()); 47 | 48 | return 0; 49 | } 50 | ``` 51 | 52 | === "C#" 53 | 54 | ```c# title="Example" 55 | using ZenKit; 56 | 57 | // Load from a file on disk: 58 | var mdh = new ModelHierarchy("MySkeleton.MDH"); 59 | 60 | // ... or from a VFS: 61 | var vfs = new Vfs(); 62 | vfs.MountDisk("Anims.vdf", VfsOverwriteBehavior.Older); 63 | mdh = new ModelHierarchy(vfs, "MySkeleton.MDH"); 64 | ``` 65 | 66 | === "Java" 67 | 68 | ```java title="Example" 69 | import dev.gothickit.zenkit.mdh.ModelHierarchy; 70 | import dev.gothickit.zenkit.vfs.Vfs; 71 | import dev.gothickit.zenkit.vfs.VfsOverwriteBehavior; 72 | 73 | // Load from a file on disk: 74 | var mdh = ModelHierarchy.load("MySkeleton.MDH"); 75 | 76 | // ... or from a VFS: 77 | var vfs = new Vfs(); 78 | vfs.mountDisk("Anims.vdf", VfsOverwriteBehavior.OLDER) 79 | mdh = ModelHierarchy.load(vfs, "MySkeleton.MDH"); 80 | ``` 81 | 82 | === "Python" 83 | 84 | ```python title="Example" 85 | from zenkit import Vfs, VfsOverwriteBehavior, ModelHierarchy 86 | 87 | # Load from a file on disk: 88 | mdh = ModelHierarchy.load("MySkeleton.MDH") 89 | 90 | # ... or from a VFS: 91 | vfs = Vfs() 92 | vfs.mount_disk("Anims.vdf", clobber=VfsOverwriteBehavior.OLDER) 93 | mdh = ModelHierarchy.load(vfs.find("MySkeleton.MDH")) 94 | ``` 95 | -------------------------------------------------------------------------------- /docs/library/api/model-mesh.md: -------------------------------------------------------------------------------- 1 | # Model Meshes 2 | 3 | ### Loading Model Meshes 4 | 5 | === "C" 6 | 7 | ```c title="Example" 8 | #include 9 | #include 10 | 11 | int main(int, const char** argv) { 12 | // Load from a file on disk: 13 | ZkModelMesh* mdm = ZkModelMesh_loadPath("MyMesh.MDM"); 14 | ZkModelMesh_del(mdm); 15 | 16 | // ... or from a VFS: 17 | ZkVfs* vfs = ZkVfs_new(); 18 | ZkVfs_mountDiskHost(vfs, "Anims.vdf", ZkVfsOverwriteBehavior_OLDER); 19 | mdm = ZkModelMesh_loadVfs(vfs, "MyMesh.MDM"); 20 | ZkModelMesh_del(mdm); 21 | ZkVfs_del(vfs); 22 | 23 | return 0; 24 | } 25 | ``` 26 | 27 | === "C++" 28 | 29 | ```cpp title="Example" 30 | #include 31 | #include 32 | #include 33 | 34 | int main(int, char const** argv) { 35 | zenkit::ModelMesh mesh {}; 36 | 37 | // Load from a file on disk: 38 | auto r = zenkit::Read::from("MyMesh.MDM"); 39 | mesh.load(r.get()); 40 | 41 | // ... or from a VFS 42 | zenkit::Vfs vfs; 43 | vfs.mount_disk("Anims.vdf", zenkit::VfsOverwriteBehavior::OLDER) 44 | 45 | r = vfs->find("MyMesh.MDM")->open_read(); 46 | mesh.load(r.get()); 47 | 48 | return 0; 49 | } 50 | ``` 51 | 52 | === "C#" 53 | 54 | ```c# title="Example" 55 | using ZenKit; 56 | 57 | // Load from a file on disk: 58 | var mesh = new ModelMesh("MyMesh.MDM"); 59 | 60 | // ... or from a VFS: 61 | var vfs = new Vfs(); 62 | vfs.MountDisk("Anims.vdf", VfsOverwriteBehavior.Older); 63 | mesh = new ModelMesh(vfs, "MyMesh.MDM"); 64 | ``` 65 | 66 | === "Java" 67 | 68 | ```java title="Example" 69 | import dev.gothickit.zenkit.mdm.ModelMesh; 70 | import dev.gothickit.zenkit.vfs.Vfs; 71 | import dev.gothickit.zenkit.vfs.VfsOverwriteBehavior; 72 | 73 | // Load from a file on disk: 74 | var mesh = ModelMesh.load("MyMesh.MDM"); 75 | 76 | // ... or from a VFS: 77 | var vfs = new Vfs(); 78 | vfs.mountDisk("Anims.vdf", VfsOverwriteBehavior.OLDER) 79 | mesh = ModelMesh.load(vfs, "MyMesh.MDM"); 80 | ``` 81 | 82 | === "Python" 83 | 84 | ```python title="Example" 85 | from zenkit import Vfs, VfsOverwriteBehavior, ModelMesh 86 | 87 | # Load from a file on disk: 88 | mesh = ModelMesh.load("MyMesh.MDM") 89 | 90 | # ... or from a VFS: 91 | vfs = Vfs() 92 | vfs.mount_disk("Anims.vdf", clobber=VfsOverwriteBehavior.OLDER) 93 | mesh = ModelMesh.load(vfs.find("MyMesh.MDM")) 94 | ``` 95 | -------------------------------------------------------------------------------- /docs/library/api/model-script.md: -------------------------------------------------------------------------------- 1 | # Model Scripts 2 | 3 | ### Loading Model Scripts 4 | 5 | === "C" 6 | 7 | ```c title="Example" 8 | #include 9 | #include 10 | 11 | int main(int, const char** argv) { 12 | // Load from a file on disk: 13 | ZkModelScript* mds = ZkModelScript_loadPath("MyScript.MDS"); 14 | ZkModelScript_del(mds); 15 | 16 | // ... or from a VFS: 17 | ZkVfs* vfs = ZkVfs_new(); 18 | ZkVfs_mountDiskHost(vfs, "Anims.vdf", ZkVfsOverwriteBehavior_OLDER); 19 | mds = ZkModelScript_loadVfs(vfs, "MyScript.MDS"); 20 | ZkModelScript_del(mds); 21 | ZkVfs_del(vfs); 22 | 23 | return 0; 24 | } 25 | ``` 26 | 27 | === "C++" 28 | 29 | ```cpp title="Example" 30 | #include 31 | #include 32 | #include 33 | 34 | int main(int, char const** argv) { 35 | zenkit::ModelScript mds {}; 36 | 37 | // Load from a file on disk: 38 | auto r = zenkit::Read::from("MyScript.MDS"); 39 | mds.load(r.get()); 40 | 41 | // ... or from a VFS 42 | zenkit::Vfs vfs; 43 | vfs.mount_disk("Anims.vdf", zenkit::VfsOverwriteBehavior::OLDER) 44 | 45 | r = vfs->find("MyScript.MDS")->open_read(); 46 | mds.load(r.get()); 47 | 48 | return 0; 49 | } 50 | ``` 51 | 52 | === "C#" 53 | 54 | ```c# title="Example" 55 | using ZenKit; 56 | 57 | // Load from a file on disk: 58 | var mds = new ModelScript("MyScript.MDS"); 59 | 60 | // ... or from a VFS: 61 | var vfs = new Vfs(); 62 | vfs.MountDisk("Anims.vdf", VfsOverwriteBehavior.Older); 63 | mds = new ModelScript(vfs, "MyScript.MDS"); 64 | ``` 65 | 66 | === "Java" 67 | 68 | ```java title="Example" 69 | import dev.gothickit.zenkit.mds.ModelScript; 70 | import dev.gothickit.zenkit.vfs.Vfs; 71 | import dev.gothickit.zenkit.vfs.VfsOverwriteBehavior; 72 | 73 | // Load from a file on disk: 74 | var mds = ModelScript.load("MyScript.MDS"); 75 | 76 | // ... or from a VFS: 77 | var vfs = new Vfs(); 78 | vfs.mountDisk("Anims.vdf", VfsOverwriteBehavior.OLDER) 79 | mds = ModelScript.load(vfs, "MyScript.MDS"); 80 | ``` 81 | 82 | === "Python" 83 | 84 | !!! warning 85 | Not yet available. 86 | -------------------------------------------------------------------------------- /docs/library/api/model.md: -------------------------------------------------------------------------------- 1 | # Models 2 | 3 | *Models* are basic containers for a [Model Hierarchy](model-hierarchy.md) and a [Model Mesh](model-mesh.md). 4 | 5 | # Loading Models 6 | 7 | === "C" 8 | 9 | ```c title="Example" 10 | #include 11 | #include 12 | 13 | int main(int, const char** argv) { 14 | // Load from a file on disk: 15 | ZkModel* mesh = ZkModel_loadPath("MyMesh.MDL"); 16 | ZkModel_del(mesh); 17 | 18 | // ... or from a VFS: 19 | ZkVfs* vfs = ZkVfs_new(); 20 | ZkVfs_mountDiskHost(vfs, "Anims.vdf", ZkVfsOverwriteBehavior_OLDER); 21 | mesh = ZkModel_loadVfs(vfs, "MyMesh.MDL"); 22 | ZkModel_del(mesh); 23 | ZkVfs_del(vfs); 24 | 25 | return 0; 26 | } 27 | ``` 28 | 29 | === "C++" 30 | 31 | ```cpp title="Example" 32 | #include 33 | #include 34 | #include 35 | 36 | int main(int, char const** argv) { 37 | zenkit::Model mesh {}; 38 | 39 | // Load from a file on disk: 40 | auto r = zenkit::Read::from("MyMesh.MDL"); 41 | mesh.load(r.get()); 42 | 43 | // ... or from a VFS 44 | zenkit::Vfs vfs; 45 | vfs.mount_disk("Anims.vdf", zenkit::VfsOverwriteBehavior::OLDER) 46 | 47 | r = vfs->find("MyMesh.MDL")->open_read(); 48 | mesh.load(r.get()); 49 | 50 | return 0; 51 | } 52 | ``` 53 | 54 | === "C#" 55 | 56 | ```c# title="Example" 57 | using ZenKit; 58 | 59 | // Load from a file on disk: 60 | var mesh = new Model("MyMesh.MDL"); 61 | 62 | // ... or from a VFS: 63 | var vfs = new Vfs(); 64 | vfs.MountDisk("Anims.vdf", VfsOverwriteBehavior.Older); 65 | mesh = new Model(vfs, "MyMesh.MDL"); 66 | ``` 67 | 68 | === "Java" 69 | 70 | ```java title="Example" 71 | import dev.gothickit.zenkit.mdl.Model; 72 | import dev.gothickit.zenkit.vfs.Vfs; 73 | import dev.gothickit.zenkit.vfs.VfsOverwriteBehavior; 74 | 75 | // Load from a file on disk: 76 | var mesh = Model.load("MyMesh.MDL"); 77 | 78 | // ... or from a VFS: 79 | var vfs = new Vfs(); 80 | vfs.mountDisk("Anims.vdf", VfsOverwriteBehavior.OLDER) 81 | mesh = Model.load(vfs, "MyMesh.MDL"); 82 | ``` 83 | 84 | === "Python" 85 | 86 | ```python title="Example" 87 | from zenkit import Vfs, VfsOverwriteBehavior, Model 88 | 89 | # Load from a file on disk: 90 | mesh = Model.load("MyMesh.MDL") 91 | 92 | # ... or from a VFS: 93 | vfs = Vfs() 94 | vfs.mount_disk("Anims.vdf", clobber=VfsOverwriteBehavior.OLDER) 95 | mesh = Model.load(vfs.find("MyMesh.MDL")) 96 | ``` 97 | -------------------------------------------------------------------------------- /docs/library/api/morph-mesh.md: -------------------------------------------------------------------------------- 1 | # Morph Meshes 2 | 3 | ### Loading Morph Meshes 4 | 5 | === "C" 6 | 7 | ```c title="Example" 8 | #include 9 | #include 10 | 11 | int main(int, const char** argv) { 12 | // Load from a file on disk: 13 | ZkMorphMesh* mmb = ZkMorphMesh_loadPath("MyMesh.MMB"); 14 | ZkMorphMesh_del(mmb); 15 | 16 | // ... or from a VFS: 17 | ZkVfs* vfs = ZkVfs_new(); 18 | ZkVfs_mountDiskHost(vfs, "Anims.vdf", ZkVfsOverwriteBehavior_OLDER); 19 | mmb = ZkMorphMesh_loadVfs(vfs, "MyMesh.MMB"); 20 | ZkMorphMesh_del(mmb); 21 | ZkVfs_del(vfs); 22 | 23 | return 0; 24 | } 25 | ``` 26 | 27 | === "C++" 28 | 29 | ```cpp title="Example" 30 | #include 31 | #include 32 | #include 33 | 34 | int main(int, char const** argv) { 35 | zenkit::MorphMesh mmb {}; 36 | 37 | // Load from a file on disk: 38 | auto r = zenkit::Read::from("MyMesh.MMB"); 39 | mmb.load(r.get()); 40 | 41 | // ... or from a VFS 42 | zenkit::Vfs vfs; 43 | vfs.mount_disk("Anims.vdf", zenkit::VfsOverwriteBehavior::OLDER) 44 | 45 | r = vfs->find("MyMesh.MMB")->open_read(); 46 | mmb.load(r.get()); 47 | 48 | return 0; 49 | } 50 | ``` 51 | 52 | === "C#" 53 | 54 | ```c# title="Example" 55 | using ZenKit; 56 | 57 | // Load from a file on disk: 58 | var mmb = new MorphMesh("MyMesh.MMB"); 59 | 60 | // ... or from a VFS: 61 | var vfs = new Vfs(); 62 | vfs.MountDisk("Anims.vdf", VfsOverwriteBehavior.Older); 63 | mmb = new MorphMesh(vfs, "MyMesh.MMB"); 64 | ``` 65 | 66 | === "Java" 67 | 68 | ```java title="Example" 69 | import dev.gothickit.zenkit.mmb.MorphMesh; 70 | import dev.gothickit.zenkit.vfs.Vfs; 71 | import dev.gothickit.zenkit.vfs.VfsOverwriteBehavior; 72 | 73 | // Load from a file on disk: 74 | var mmb = MorphMesh.load("MyMesh.MMB"); 75 | 76 | // ... or from a VFS: 77 | var vfs = new Vfs(); 78 | vfs.mountDisk("Anims.vdf", VfsOverwriteBehavior.OLDER) 79 | mmb = MorphMesh.load(vfs, "MyMesh.MMB"); 80 | ``` 81 | 82 | === "Python" 83 | 84 | ```python title="Example" 85 | from zenkit import Vfs, VfsOverwriteBehavior, MorphMesh 86 | 87 | # Load from a file on disk: 88 | mmb = MorphMesh.load("MyMesh.MMB") 89 | 90 | # ... or from a VFS: 91 | vfs = Vfs() 92 | vfs.mount_disk("Anims.vdf", clobber=VfsOverwriteBehavior.OLDER) 93 | mmb = MorphMesh.load(vfs.find("MyMesh.MMB")) 94 | ``` 95 | -------------------------------------------------------------------------------- /docs/library/api/multi-resolution-mesh.md: -------------------------------------------------------------------------------- 1 | # Multi Resolution Meshes 2 | 3 | ### Loading Multi Resolution Meshes 4 | 5 | === "C" 6 | 7 | ```c title="Example" 8 | #include 9 | #include 10 | 11 | int main(int, const char** argv) { 12 | // Load from a file on disk: 13 | ZkMultiResolutionMesh* mrm = ZkMultiResolutionMesh_loadPath("MyMesh.MRM"); 14 | ZkMultiResolutionMesh_del(mrm); 15 | 16 | // ... or from a VFS: 17 | ZkVfs* vfs = ZkVfs_new(); 18 | ZkVfs_mountDiskHost(vfs, "Meshes.vdf", ZkVfsOverwriteBehavior_OLDER); 19 | mrm = ZkMultiResolutionMesh_loadVfs(vfs, "MyMesh.MRM"); 20 | ZkMultiResolutionMesh_del(mrm); 21 | ZkVfs_del(vfs); 22 | 23 | return 0; 24 | } 25 | ``` 26 | 27 | === "C++" 28 | 29 | ```cpp title="Example" 30 | #include 31 | #include 32 | #include 33 | 34 | int main(int, char const** argv) { 35 | zenkit::MultiResolutionMesh mrm {}; 36 | 37 | // Load from a file on disk: 38 | auto r = zenkit::Read::from("MyMesh.MRM"); 39 | mrm.load(r.get()); 40 | 41 | // ... or from a VFS 42 | zenkit::Vfs vfs; 43 | vfs.mount_disk("Meshes.vdf", zenkit::VfsOverwriteBehavior::OLDER) 44 | 45 | r = vfs->find("MyMesh.MRM")->open_read(); 46 | mrm.load(r.get()); 47 | 48 | return 0; 49 | } 50 | ``` 51 | 52 | === "C#" 53 | 54 | ```c# title="Example" 55 | using ZenKit; 56 | 57 | // Load from a file on disk: 58 | var mrm = new MultiResolutionMesh("MyMesh.MRM"); 59 | 60 | // ... or from a VFS: 61 | var vfs = new Vfs(); 62 | vfs.MountDisk("Meshes.vdf", VfsOverwriteBehavior.Older); 63 | mrm = new MultiResolutionMesh(vfs, "MyMesh.MRM"); 64 | ``` 65 | 66 | === "Java" 67 | 68 | ```java title="Example" 69 | import dev.gothickit.zenkit.mrm.MultiResolutionMesh; 70 | import dev.gothickit.zenkit.vfs.Vfs; 71 | import dev.gothickit.zenkit.vfs.VfsOverwriteBehavior; 72 | 73 | // Load from a file on disk: 74 | var mrm = MultiResolutionMesh.load("MyMesh.MRM"); 75 | 76 | // ... or from a VFS: 77 | var vfs = new Vfs(); 78 | vfs.mountDisk("Meshes.vdf", VfsOverwriteBehavior.OLDER) 79 | mrm = MultiResolutionMesh.load(vfs, "MyMesh.MRM"); 80 | ``` 81 | 82 | === "Python" 83 | 84 | ```python title="Example" 85 | from zenkit import Vfs, VfsOverwriteBehavior, MultiResolutionMesh 86 | 87 | # Load from a file on disk: 88 | mrm = MultiResolutionMesh.load("MyMesh.MRM") 89 | 90 | # ... or from a VFS: 91 | vfs = Vfs() 92 | vfs.mount_disk("Meshes.vdf", clobber=VfsOverwriteBehavior.OLDER) 93 | mrm = MultiResolutionMesh.load(vfs.find("MyMesh.MRM")) 94 | ``` 95 | -------------------------------------------------------------------------------- /docs/library/api/texture.md: -------------------------------------------------------------------------------- 1 | # Textures 2 | 3 | ### Loading Textures 4 | 5 | === "C" 6 | 7 | ```c title="Example" 8 | #include 9 | #include 10 | 11 | int main(int, const char** argv) { 12 | // Load from a file on disk: 13 | ZkTexture* tex = ZkTexture_loadPath("MyTexture.TEX"); 14 | ZkTexture_del(tex); 15 | 16 | // ... or from a VFS: 17 | ZkVfs* vfs = ZkVfs_new(); 18 | ZkVfs_mountDiskHost(vfs, "Textures.vdf", ZkVfsOverwriteBehavior_OLDER); 19 | tex = ZkTexture_loadVfs(vfs, "MyTexture.TEX"); 20 | ZkTexture_del(tex); 21 | ZkVfs_del(vfs); 22 | 23 | return 0; 24 | } 25 | ``` 26 | 27 | === "C++" 28 | 29 | ```cpp title="Example" 30 | #include 31 | #include 32 | #include 33 | 34 | int main(int, char const** argv) { 35 | zenkit::Texture tex {}; 36 | 37 | // Load from a file on disk: 38 | auto r = zenkit::Read::from("MyTexture.TEX"); 39 | tex.load(r.get()); 40 | 41 | // ... or from a VFS 42 | zenkit::Vfs vfs; 43 | vfs.mount_disk("Textures.vdf", zenkit::VfsOverwriteBehavior::OLDER) 44 | 45 | r = vfs->find("MyTexture.TEX")->open_read(); 46 | tex.load(r.get()); 47 | 48 | return 0; 49 | } 50 | ``` 51 | 52 | === "C#" 53 | 54 | ```c# title="Example" 55 | using ZenKit; 56 | 57 | // Load from a file on disk: 58 | var tex = new Texture("MyTexture.TEX"); 59 | 60 | // ... or from a VFS: 61 | var vfs = new Vfs(); 62 | vfs.MountDisk("Textures.vdf", VfsOverwriteBehavior.Older); 63 | tex = new Texture(vfs, "MyTexture.TEX"); 64 | ``` 65 | 66 | === "Java" 67 | 68 | ```java title="Example" 69 | import dev.gothickit.zenkit.tex.Texture; 70 | import dev.gothickit.zenkit.vfs.Vfs; 71 | import dev.gothickit.zenkit.vfs.VfsOverwriteBehavior; 72 | 73 | // Load from a file on disk: 74 | var tex = Texture.load("MyTexture.TEX"); 75 | 76 | // ... or from a VFS: 77 | var vfs = new Vfs(); 78 | vfs.mountDisk("Textures.vdf", VfsOverwriteBehavior.OLDER) 79 | tex = Texture.load(vfs, "MyTexture.TEX"); 80 | ``` 81 | 82 | === "Python" 83 | 84 | ```python title="Example" 85 | from zenkit import Vfs, VfsOverwriteBehavior, Texture 86 | 87 | # Load from a file on disk: 88 | tex = Texture.load("MyTexture.TEX") 89 | 90 | # ... or from a VFS: 91 | vfs = Vfs() 92 | vfs.mount_disk("Textures.vdf", clobber=VfsOverwriteBehavior.OLDER) 93 | tex = Texture.load(vfs.find("MyTexture.TEX")) 94 | ``` 95 | -------------------------------------------------------------------------------- /docs/library/api/world.md: -------------------------------------------------------------------------------- 1 | # Worlds 2 | 3 | ### Loading Worlds 4 | 5 | === "C" 6 | 7 | ```c title="Example" 8 | #include 9 | #include 10 | 11 | int main(int, const char** argv) { 12 | // Load from a file on disk: 13 | ZkWorld* world = ZkWorld_loadPath("OLDWORLD.ZEN"); 14 | ZkWorld_del(world); 15 | 16 | // ... or from a VFS: 17 | ZkVfs* vfs = ZkVfs_new(); 18 | ZkVfs_mountDiskHost(vfs, "Worlds.vdf", ZkVfsOverwriteBehavior_OLDER); 19 | world = ZkWorld_loadVfs(vfs, "OLDWORLD.ZEN"); 20 | ZkWorld_del(world); 21 | ZkVfs_del(vfs); 22 | 23 | return 0; 24 | } 25 | ``` 26 | 27 | === "C++" 28 | 29 | ```cpp title="Example" 30 | #include 31 | #include 32 | #include 33 | 34 | int main(int, char const** argv) { 35 | zenkit::World world {}; 36 | 37 | // Load from a file on disk: 38 | auto r = zenkit::Read::from("OLDWORLD.ZEN"); 39 | world.load(r.get()); 40 | 41 | // ... or from a VFS 42 | zenkit::Vfs vfs; 43 | vfs.mount_disk("Worlds.vdf", zenkit::VfsOverwriteBehavior::OLDER) 44 | 45 | r = vfs->find("OLDWORLD.ZEN")->open_read(); 46 | world.load(r.get()); 47 | 48 | return 0; 49 | } 50 | ``` 51 | 52 | === "C#" 53 | 54 | ```c# title="Example" 55 | using ZenKit; 56 | 57 | // Load from a file on disk: 58 | var world = new World("OLDWORLD.ZEN"); 59 | 60 | // ... or from a VFS: 61 | var vfs = new Vfs(); 62 | vfs.MountDisk("Worlds.vdf", VfsOverwriteBehavior.Older); 63 | world = new World(vfs, "OLDWORLD.ZEN"); 64 | ``` 65 | 66 | === "Java" 67 | 68 | ```java title="Example" 69 | import dev.gothickit.zenkit.world.World; 70 | import dev.gothickit.zenkit.vfs.Vfs; 71 | import dev.gothickit.zenkit.vfs.VfsOverwriteBehavior; 72 | 73 | // Load from a file on disk: 74 | var world = World.load("OLDWORLD.ZEN"); 75 | 76 | // ... or from a VFS: 77 | var vfs = new Vfs(); 78 | vfs.mountDisk("Worlds.vdf", VfsOverwriteBehavior.OLDER) 79 | world = World.load(vfs, "OLDWORLD.ZEN"); 80 | ``` 81 | 82 | === "Python" 83 | 84 | ```python title="Example" 85 | from zenkit import Vfs, VfsOverwriteBehavior, World 86 | 87 | # Load from a file on disk: 88 | world = World.load("OLDWORLD.ZEN") 89 | 90 | # ... or from a VFS: 91 | vfs = Vfs() 92 | vfs.mount_disk("Worlds.vdf", clobber=VfsOverwriteBehavior.OLDER) 93 | world = World.load(vfs.find("OLDWORLD.ZEN")) 94 | ``` 95 | -------------------------------------------------------------------------------- /docs/library/overview.md: -------------------------------------------------------------------------------- 1 | --- 2 | hide: 3 | - footer 4 | --- 5 | 6 | # Library Reference 7 | 8 | ![](../assets/logo.png) 9 | 10 | Welcome to the *ZenKit* reference documentation. This page contains information about how to use *ZenKit*, a 11 | C++-library for parsing file formats used by the *ZenGin*, an early 2000's game engine developed by 12 | [Piranha Bytes][] for the games [Gothic][] and [Gothic II][]. 13 | 14 | If you are new to *ZenKit*, a good place to start is [the quickstart guide](quickstart.md). If you are looking 15 | for information about a specific file type, the [file type reference](reference.md) might be the place you're 16 | looking for. 17 | 18 | [Piranha Bytes]: https://www.piranha-bytes.com/ 19 | [Gothic]: https://en.wikipedia.org/wiki/Gothic_(video_game) 20 | [Gothic II]: https://en.wikipedia.org/wiki/Gothic_(video_game) 21 | -------------------------------------------------------------------------------- /examples/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(load_vdf load_vdf.cc) 2 | target_link_libraries(load_vdf PRIVATE zenkit) 3 | 4 | add_executable(load_zen load_zen.cc) 5 | target_link_libraries(load_zen PRIVATE zenkit) 6 | 7 | add_executable(run_interpreter run_interpreter.cc) 8 | target_link_libraries(run_interpreter PRIVATE zenkit) 9 | 10 | add_executable(zen2zen zen2zen.cc) 11 | target_link_libraries(zen2zen PRIVATE zenkit) 12 | 13 | set_target_properties(load_vdf load_zen run_interpreter zen2zen 14 | PROPERTIES 15 | RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/examples" 16 | ) 17 | -------------------------------------------------------------------------------- /examples/load_vdf.cc: -------------------------------------------------------------------------------- 1 | // Copyright © 2022-2023 GothicKit Contributors. 2 | // SPDX-License-Identifier: MIT 3 | #include 4 | 5 | #include 6 | 7 | void print_entries(std::set const& entries) { 8 | for (auto& e : entries) { 9 | if (e.type() == zenkit::VfsNodeType::DIRECTORY) { 10 | print_entries(e.children()); 11 | } else { 12 | std::cout << e.name() << "\n"; 13 | } 14 | } 15 | } 16 | 17 | int main(int argc, char** argv) { 18 | if (argc != 2) { 19 | std::cerr << "Please provide an input file."; 20 | return -1; 21 | } 22 | 23 | zenkit::Vfs vfs {}; 24 | vfs.mount_disk(argv[1]); 25 | print_entries(vfs.root().children()); 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /examples/load_zen.cc: -------------------------------------------------------------------------------- 1 | // Copyright © 2022-2023 GothicKit Contributors. 2 | // SPDX-License-Identifier: MIT 3 | #include "zenkit/Vfs.hh" 4 | #include "zenkit/World.hh" 5 | 6 | #include 7 | 8 | #include 9 | 10 | void print_entries(std::unique_ptr& reader) { 11 | int level = 0; 12 | zenkit::ArchiveObject obj {}; 13 | 14 | do { 15 | if (reader->read_object_begin(obj)) { 16 | level++; 17 | std::cout << " Object(class=" << obj.class_name << ", name=" << obj.object_name 18 | << ", index=" << obj.index << ", version=" << obj.version << ")\n"; 19 | } else { 20 | if (level == 0) break; 21 | // Reading the entries requires knowing their type. See `phoenix/source/world/vob_tree.cc for examples. 22 | reader->skip_object(true); 23 | level--; 24 | } 25 | } while (true); 26 | } 27 | 28 | int main(int argc, char** argv) { 29 | if (argc != 2) { 30 | std::cerr << "Please provide an input file."; 31 | return -1; 32 | } 33 | 34 | zenkit::Vfs vfs; 35 | vfs.mount_disk(argv[1]); 36 | 37 | zenkit::World wld; 38 | 39 | auto rd = vfs.find("NEWWORLD.ZEN")->open_read(); 40 | wld.load(rd.get()); 41 | return 0; 42 | } 43 | -------------------------------------------------------------------------------- /include/zenkit/Boxes.hh: -------------------------------------------------------------------------------- 1 | // Copyright © 2021-2024 GothicKit Contributors. 2 | // SPDX-License-Identifier: MIT 3 | #pragma once 4 | #include "zenkit/Library.hh" 5 | #include "zenkit/Misc.hh" 6 | 7 | #include 8 | 9 | namespace zenkit { 10 | class Read; 11 | class Write; 12 | 13 | /// \brief Represents a axis-aligned bounding box (AABB) 14 | struct AxisAlignedBoundingBox { 15 | static constexpr AxisAlignedBoundingBox zero() { 16 | return {Vec3 {0}, Vec3 {0}}; 17 | } 18 | 19 | /// \brief The coordinates of the minimum corner of the bounding box. 20 | Vec3 min; 21 | 22 | /// \brief The coordinates of the maximum corner of the bounding box. 23 | Vec3 max; 24 | 25 | ZKAPI void load(Read* r); 26 | ZKAPI void save(Write* w) const; 27 | }; 28 | 29 | /// \brief Represents an oriented bounding box. 30 | /// 31 | /// In contrast to regular bounding boxes, [oriented bounding 32 | /// boxes](https://en.wikipedia.org/wiki/Minimum_bounding_box#Arbitrarily_oriented_minimum_bounding_box) may be 33 | /// rotated in the coordinate system and don't have to align with its axes. 34 | struct OrientedBoundingBox { 35 | Vec3 center; 36 | Vec3 axes[3]; 37 | Vec3 half_width; 38 | 39 | std::vector children; 40 | 41 | ZKAPI void load(Read* r); 42 | ZKAPI void save(Write* w) const; 43 | 44 | /// \brief Calculates an axis-aligned bounding box from this oriented bounding box. 45 | /// \todo Write a test for this. 46 | /// \return An AABB which contains this OBB. 47 | [[nodiscard]] ZKAPI AxisAlignedBoundingBox as_bbox() const; 48 | }; 49 | } // namespace zenkit 50 | -------------------------------------------------------------------------------- /include/zenkit/Date.hh: -------------------------------------------------------------------------------- 1 | // Copyright © 2023-2024 GothicKit Contributors. 2 | // SPDX-License-Identifier: MIT 3 | #pragma once 4 | #include "zenkit/Library.hh" 5 | 6 | #include 7 | 8 | namespace zenkit { 9 | class Read; 10 | class Write; 11 | 12 | /// \brief A basic date and time structure used by the *ZenGin*. 13 | struct Date { 14 | ZKAPI void load(Read* r); 15 | ZKAPI void save(Write* w) const; 16 | 17 | std::uint32_t year; 18 | std::uint16_t month; 19 | std::uint16_t day; 20 | std::uint16_t hour; 21 | std::uint16_t minute; 22 | std::uint16_t second; 23 | }; 24 | } // namespace zenkit 25 | -------------------------------------------------------------------------------- /include/zenkit/Error.hh: -------------------------------------------------------------------------------- 1 | // Copyright © 2023 GothicKit Contributors. 2 | // SPDX-License-Identifier: MIT 3 | #pragma once 4 | #include "zenkit/Library.hh" 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | namespace zenkit { 11 | /// \brief Base class for all exceptions. 12 | class Error : public std::exception { 13 | public: 14 | ZKAPI explicit Error(std::string&& message); 15 | 16 | [[nodiscard]] ZKAPI char const* what() const noexcept override { 17 | return message.c_str(); 18 | } 19 | 20 | std::string const message; 21 | }; 22 | 23 | /// \brief An error representing a parsing failure of any kind. 24 | class ParserError : public Error { 25 | public: 26 | ZKINT explicit ParserError(std::string&& resource_type); 27 | ZKAPI explicit ParserError(std::string&& resource_type, std::string&& context); 28 | ZKINT explicit ParserError(std::string&& resource_type, std::exception const& cause); 29 | ZKINT explicit ParserError(std::string&& resource_type, std::exception const& cause, std::string&& context); 30 | 31 | std::string const resource_type; 32 | std::optional const context {std::nullopt}; 33 | std::optional const cause {std::nullopt}; 34 | }; 35 | } // namespace zenkit 36 | -------------------------------------------------------------------------------- /include/zenkit/Library.hh: -------------------------------------------------------------------------------- 1 | // Copyright © 2023 GothicKit Contributors. 2 | // SPDX-License-Identifier: MIT 3 | #pragma once 4 | 5 | #ifdef ZKDYN 6 | #if defined(_WIN32) || defined(__CYGWIN__) 7 | #ifdef _ZKEXPORT 8 | #ifdef __GNUC__ 9 | #define ZKAPI __attribute__((dllexport)) 10 | #else 11 | #define ZKAPI __declspec(dllexport) 12 | #endif 13 | #else 14 | #ifdef __GNUC__ 15 | #define ZKAPI __attribute__((dllimport)) 16 | #else 17 | #define ZKAPI __declspec(dllimport) 18 | #endif 19 | #endif 20 | #define ZKINT 21 | #else 22 | #define ZKAPI __attribute__((visibility("default"))) 23 | #define ZKINT __attribute__((visibility("hidden"))) 24 | #endif 25 | #else 26 | #define ZKAPI 27 | #define ZKINT 28 | #endif 29 | 30 | #ifndef ZKNO_REM 31 | #define ZKREM(reason) [[deprecated(reason)]] 32 | #else 33 | #define ZKREM(reason) 34 | #endif 35 | -------------------------------------------------------------------------------- /include/zenkit/Logger.hh: -------------------------------------------------------------------------------- 1 | // Copyright © 2023 GothicKit Contributors. 2 | // SPDX-License-Identifier: MIT 3 | #pragma once 4 | #include "zenkit/Library.hh" 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #if defined(__GNUC__) || defined(__clang__) 12 | #define ZK_PRINTF_LIKE(a, b) [[gnu::format(printf, a, b)]] 13 | #else 14 | #define ZK_PRINTF_LIKE(a, b) 15 | #endif 16 | 17 | namespace zenkit { 18 | enum class LogLevel : std::uint8_t { 19 | ERROR = 0, 20 | WARNING = 1, 21 | INFO = 2, 22 | DEBUG = 3, 23 | TRACE = 4, 24 | 25 | error ZKREM("renamed to LogLevel::ERROR") = ERROR, 26 | warn ZKREM("renamed to LogLevel::WARNING") = WARNING, 27 | info ZKREM("renamed to LogLevel::INFO") = INFO, 28 | debug ZKREM("renamed to LogLevel::DEBUG") = DEBUG 29 | }; 30 | 31 | class Logger { 32 | public: 33 | using level ZKREM("renamed to zenkit::LogLevel") = LogLevel; 34 | 35 | /// \brief Supply a custom logger callback to be used for log output from ZenKit. 36 | /// \param callback The callback to use. 37 | ZKREM("renamed to ::set") 38 | ZKAPI static void use_logger(std::function&& callback); 39 | 40 | /// \brief Use the default logger callback for ZenKit. 41 | ZKREM("renamed to ::set_default") ZKAPI static void use_default_logger(); 42 | 43 | ZK_PRINTF_LIKE(3, 4) ZKAPI static void log(LogLevel lvl, char const* name, char const* fmt, ...); 44 | ZKAPI static void logv(LogLevel lvl, char const* name, char const* fmt, va_list ap); 45 | ZKAPI static void set(LogLevel lvl, std::function const& cb); 46 | ZKAPI static void set_default(LogLevel lvl); 47 | 48 | private: 49 | static std::function _s_callback; 50 | static LogLevel _s_level; 51 | }; 52 | } // namespace zenkit 53 | -------------------------------------------------------------------------------- /include/zenkit/Mmap.hh: -------------------------------------------------------------------------------- 1 | // Copyright © 2023 GothicKit Contributors. 2 | // SPDX-License-Identifier: MIT 3 | #pragma once 4 | #include 5 | 6 | namespace zenkit { 7 | #ifdef _ZK_WITH_MMAP 8 | class Mmap { 9 | public: 10 | explicit Mmap(std::filesystem::path const& path); 11 | 12 | Mmap(Mmap const&) = delete; 13 | Mmap(Mmap&&) noexcept; 14 | 15 | ~Mmap() noexcept; 16 | 17 | [[nodiscard]] std::byte const* data() const noexcept { 18 | return _m_data; 19 | } 20 | 21 | [[nodiscard]] std::size_t size() const noexcept { 22 | return _m_size; 23 | } 24 | 25 | private: 26 | std::byte const* _m_data; 27 | std::size_t _m_size; 28 | 29 | void* _m_platform_handle {nullptr}; 30 | }; 31 | #endif 32 | } // namespace zenkit 33 | -------------------------------------------------------------------------------- /include/zenkit/Model.hh: -------------------------------------------------------------------------------- 1 | // Copyright © 2022-2024 GothicKit Contributors. 2 | // SPDX-License-Identifier: MIT 3 | #pragma once 4 | #include "zenkit/Library.hh" 5 | #include "zenkit/ModelHierarchy.hh" 6 | #include "zenkit/ModelMesh.hh" 7 | 8 | namespace zenkit { 9 | class Read; 10 | 11 | /// \brief Represents a *ZenGin* model. 12 | /// 13 | ///

*ZenGin* models contain a zenkit::ModelMesh and a zenkit::ModelHierarchy bundled into one file. Try are 14 | /// typically found in files with the `MDL` extension.

15 | class Model { 16 | public: 17 | ZKAPI void load(Read* r); 18 | ZKAPI void save(Write* w, GameVersion version) const; 19 | 20 | /// \brief The zenkit::ModelHierarchy associated with this model. 21 | ModelHierarchy hierarchy {}; 22 | 23 | /// \brief The zenkit::ModelMesh associated with this model. 24 | ModelMesh mesh {}; 25 | }; 26 | } // namespace zenkit 27 | -------------------------------------------------------------------------------- /include/zenkit/ModelHierarchy.hh: -------------------------------------------------------------------------------- 1 | // Copyright © 2021-2024 GothicKit Contributors. 2 | // SPDX-License-Identifier: MIT 3 | #pragma once 4 | #include "zenkit/Boxes.hh" 5 | #include "zenkit/Date.hh" 6 | #include "zenkit/Library.hh" 7 | 8 | #include 9 | #include 10 | 11 | namespace zenkit { 12 | class Read; 13 | 14 | /// \brief A node in the hierarchy tree. 15 | struct ModelHierarchyNode { 16 | /// \brief The index of this node's parent node. 17 | std::int16_t parent_index; 18 | 19 | /// \brief The name of this node. 20 | std::string name; 21 | 22 | /// \brief The position and rotation of this node in its base state. 23 | Mat4 transform; 24 | }; 25 | 26 | /// \brief Represents a *ZenGin* model hierarchy. 27 | /// 28 | ///

Model hierarchy files represent the skeletal structure of a mesh. These skeletons are used to animate mostly 29 | /// animals and humans in the game which is commonly referred to as rigging.

30 | class ModelHierarchy { 31 | public: 32 | ZKAPI void load(Read* r); 33 | ZKAPI void save(Write* w) const; 34 | 35 | /// \brief The list of nodes this hierarchy consists of. 36 | std::vector nodes {}; 37 | 38 | /// \brief The bounding box of this hierarchy. 39 | AxisAlignedBoundingBox bbox {}; 40 | 41 | /// \brief The collision bounding box of this hierarchy. 42 | AxisAlignedBoundingBox collision_bbox {}; 43 | 44 | /// \brief The translation of the root node of this hierarchy. 45 | Vec3 root_translation {}; 46 | 47 | /// \brief The checksum of this hierarchy. 48 | std::uint32_t checksum; 49 | 50 | Date source_date; 51 | std::string source_path; 52 | }; 53 | } // namespace zenkit 54 | -------------------------------------------------------------------------------- /include/zenkit/ModelMesh.hh: -------------------------------------------------------------------------------- 1 | // Copyright © 2021-2024 GothicKit Contributors. 2 | // SPDX-License-Identifier: MIT 3 | #pragma once 4 | #include "zenkit/Library.hh" 5 | #include "zenkit/MultiResolutionMesh.hh" 6 | #include "zenkit/SoftSkinMesh.hh" 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | namespace zenkit { 14 | class Read; 15 | 16 | /// \brief Represents a *ZenGin* model mesh. 17 | /// 18 | ///

Model meshes contain multiple phoenix::softskin_mesh instances as well as a set of phoenix::proto_mesh 19 | /// attachments. They can be found within `MDM` files and are embedded within phoenix::model objects.

20 | class ModelMesh { 21 | public: 22 | ZKAPI void load(Read* r); 23 | ZKAPI void save(Write* w, GameVersion version) const; 24 | 25 | /// \brief A list of soft-skin meshes associated with this model mesh. 26 | std::vector meshes {}; 27 | 28 | /// \brief A map of attachment names to attachment meshes of this model mesh. 29 | std::unordered_map attachments {}; 30 | 31 | /// \brief The checksum of the model hierarchy this model was made for. 32 | std::uint32_t checksum; 33 | }; 34 | } // namespace zenkit 35 | -------------------------------------------------------------------------------- /include/zenkit/MorphMesh.hh: -------------------------------------------------------------------------------- 1 | // Copyright © 2021-2024 GothicKit Contributors. 2 | // SPDX-License-Identifier: MIT 3 | #pragma once 4 | #include "zenkit/Date.hh" 5 | #include "zenkit/Library.hh" 6 | #include "zenkit/MultiResolutionMesh.hh" 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | namespace zenkit { 13 | class Read; 14 | 15 | /// \brief An animation used by morph meshes 16 | struct MorphAnimation { 17 | /// \brief The name of the animation. 18 | std::string name; 19 | 20 | /// \brief The animation layer the animation is played at. 21 | std::int32_t layer; 22 | float blend_in; 23 | float blend_out; 24 | 25 | /// \brief The duration of the animation in seconds. 26 | float duration; 27 | float speed; 28 | std::uint8_t flags; 29 | 30 | /// \brief The number of frames of the animation. 31 | std::uint32_t frame_count; 32 | 33 | /// \brief The set of vertices affected by the animation. 34 | std::vector vertices; 35 | 36 | /// \brief The set of samples of the animation. 37 | std::vector samples; 38 | }; 39 | 40 | /// \brief A reference to a morph mesh source file. 41 | struct MorphSource { 42 | /// \brief The date of file creation. 43 | Date file_date; 44 | 45 | /// \brief The name of the source file. 46 | std::string file_name; 47 | }; 48 | 49 | /// \brief Represents a *ZenGin* morph mesh. 50 | /// 51 | ///

Morph meshes represents meshes which can deform using a set of animations. With these meshes, the positions 52 | /// of the vertices of the underlying phoenix::proto_mesh are actually changed while an animation plays.

53 | class MorphMesh { 54 | public: 55 | ZKAPI void load(Read* r); 56 | 57 | /// \brief The name of the mesh. 58 | std::string name {}; 59 | 60 | /// \brief The underlying mesh. 61 | MultiResolutionMesh mesh {}; 62 | 63 | /// \brief All morph positions associated with the mesh. 64 | std::vector morph_positions {}; 65 | 66 | /// \brief All animations associated with the mesh. 67 | std::vector animations {}; 68 | 69 | /// \brief A list of source files this morph mesh was compiled from. 70 | std::vector sources {}; 71 | }; 72 | } // namespace zenkit 73 | -------------------------------------------------------------------------------- /include/zenkit/SoftSkinMesh.hh: -------------------------------------------------------------------------------- 1 | // Copyright © 2021-2024 GothicKit Contributors. 2 | // SPDX-License-Identifier: MIT 3 | #pragma once 4 | #include "zenkit/Boxes.hh" 5 | #include "zenkit/Library.hh" 6 | #include "zenkit/MultiResolutionMesh.hh" 7 | 8 | #include 9 | #include 10 | 11 | namespace zenkit { 12 | class Read; 13 | 14 | struct SoftSkinWedgeNormal { 15 | Vec3 normal; 16 | std::uint32_t index; 17 | }; 18 | 19 | struct SoftSkinWeightEntry { 20 | float weight; 21 | Vec3 position; 22 | std::uint8_t node_index; 23 | }; 24 | 25 | /// \brief Represents a soft-skin mesh. 26 | class SoftSkinMesh { 27 | public: 28 | ZKAPI void load(Read* r); 29 | ZKAPI void save(Write* w, GameVersion version) const; 30 | 31 | /// \brief The embedded proto-mesh. 32 | MultiResolutionMesh mesh; 33 | 34 | /// \brief The meshes bounding boxes (there is one for each node). 35 | std::vector bboxes; 36 | 37 | /// \brief A list of wedge normals. 38 | std::vector wedge_normals; 39 | 40 | /// \brief Node weights. 41 | std::vector> weights; 42 | 43 | /// \brief Nodes. 44 | std::vector nodes; 45 | }; 46 | } // namespace zenkit 47 | -------------------------------------------------------------------------------- /include/zenkit/addon/texcvt.hh: -------------------------------------------------------------------------------- 1 | // Copyright © 2022-2023 GothicKit Contributors. 2 | // SPDX-License-Identifier: MIT 3 | #pragma once 4 | #include "zenkit/Library.hh" 5 | #include "zenkit/Texture.hh" 6 | 7 | #include 8 | 9 | namespace zenkit { 10 | /// \brief Converts a texture to the DDS format. 11 | /// \param tex The texture to convert. 12 | /// \return A buffer containing the DDS file. 13 | [[nodiscard]] ZKAPI std::vector to_dds(Texture const& tex); 14 | } // namespace zenkit 15 | -------------------------------------------------------------------------------- /include/zenkit/world/BspTree.hh: -------------------------------------------------------------------------------- 1 | // Copyright © 2021-2024 GothicKit Contributors. 2 | // SPDX-License-Identifier: MIT 3 | #pragma once 4 | #include "zenkit/Boxes.hh" 5 | #include "zenkit/Library.hh" 6 | #include "zenkit/Misc.hh" 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | namespace zenkit { 13 | class Read; 14 | class Write; 15 | 16 | enum class BspTreeType : std::uint32_t { 17 | INDOOR = 0, 18 | OUTDOOR = 1, 19 | 20 | // Deprecated entries. 21 | indoor ZKREM("renamed to BspTreeType::INDOOR") = INDOOR, 22 | outdoor ZKREM("renamed to BspTreeType::OUTDOOR") = OUTDOOR, 23 | }; 24 | 25 | /// \brief Represents a BSP tree node. 26 | struct BspNode { 27 | Vec4 plane; 28 | AxisAlignedBoundingBox bbox; 29 | std::uint32_t polygon_index; 30 | std::uint32_t polygon_count; 31 | 32 | std::int32_t front_index {-1}; 33 | std::int32_t back_index {-1}; 34 | std::int32_t parent_index {-1}; 35 | 36 | [[nodiscard]] ZKAPI bool is_leaf() const noexcept { 37 | return front_index == -1 && back_index == -1; 38 | } 39 | }; 40 | 41 | /// \brief Represents a BSP sector. 42 | struct BspSector { 43 | std::string name; 44 | std::vector node_indices; 45 | std::vector portal_polygon_indices; 46 | }; 47 | 48 | /// \brief Represents a binary space partitioning tree as implemented in the ZenGin. 49 | /// 50 | /// [Binary space partitioning](https://en.wikipedia.org/wiki/Binary_space_partitioning) is used for rapidly 51 | /// drawing three-dimensional scenes and performing ray-casts. 52 | class BspTree { 53 | public: 54 | ZKINT void load(Read* r, std::uint32_t version); 55 | ZKINT void save(Write* w, GameVersion version) const; 56 | 57 | /// \brief The mode of the tree (either indoor or outdoor). 58 | BspTreeType mode; 59 | 60 | /// \brief A list of polygon indices. 61 | std::vector polygon_indices; 62 | 63 | /// \brief All BSP leaf polygon indices. 64 | std::vector leaf_polygons; 65 | 66 | /// \brief All BSP light points. 67 | std::vector light_points; 68 | 69 | /// \brief All BSP sectors. 70 | std::vector sectors; 71 | 72 | /// \brief Polygon indices of portals. 73 | std::vector portal_polygon_indices; 74 | 75 | /// \brief All BSP nodes associated with the tree. 76 | std::vector nodes; 77 | 78 | /// \brief All BSP leaf node indices. 79 | std::vector leaf_node_indices; 80 | }; 81 | } // namespace zenkit 82 | -------------------------------------------------------------------------------- /include/zenkit/world/VobTree.hh: -------------------------------------------------------------------------------- 1 | // Copyright © 2021-2023 GothicKit Contributors. 2 | // SPDX-License-Identifier: MIT 3 | #pragma once 4 | #include "zenkit/Archive.hh" 5 | #include "zenkit/Misc.hh" 6 | #include "zenkit/vobs/VirtualObject.hh" 7 | 8 | #include 9 | 10 | namespace zenkit { 11 | /// \brief Parses a VOB tree from the given reader. 12 | /// \param in The reader to read from. 13 | /// \param version The version of Gothic being used. 14 | /// \return The tree parsed. 15 | ZKAPI std::shared_ptr parse_vob_tree(ReadArchive& in, GameVersion version); 16 | ZKAPI void save_vob_tree(WriteArchive& w, GameVersion version, std::shared_ptr const& obj); 17 | } // namespace zenkit 18 | -------------------------------------------------------------------------------- /include/zenkit/world/WayNet.hh: -------------------------------------------------------------------------------- 1 | // Copyright © 2021-2024 GothicKit Contributors. 2 | // SPDX-License-Identifier: MIT 3 | #pragma once 4 | #include "zenkit/Library.hh" 5 | #include "zenkit/Object.hh" 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | namespace zenkit { 13 | class ReadArchive; 14 | 15 | #ifndef ZK_FUTURE 16 | /// \brief Represents a single waypoint. 17 | struct WayPoint { 18 | std::string name; 19 | std::int32_t water_depth; 20 | bool under_water; 21 | Vec3 position; 22 | Vec3 direction; 23 | bool free_point {false}; 24 | }; 25 | 26 | /// \brief Represents a connection between two waypoints. 27 | struct WayEdge { 28 | /// \brief The index of the first waypoint of the connection. 29 | std::uint32_t a; 30 | 31 | /// \brief The index of the second waypoint of the connection. 32 | std::uint32_t b; 33 | }; 34 | 35 | /// \brief Represents a way-net. 36 | /// 37 | /// Way-nets are used for NPC navigation and path finding. 38 | class WayNet { 39 | public: 40 | /// \brief PParses a way-net from the given reader. 41 | /// \param in The reader to read from. 42 | /// \return The way-net parsed. 43 | ZKINT void load(ReadArchive& in); 44 | 45 | public: 46 | /// \brief All waypoints of this way-net. 47 | std::vector waypoints; 48 | 49 | /// \brief All edges of this way-net. 50 | std::vector edges; 51 | }; 52 | #else 53 | /// \brief Represents a single waypoint. 54 | struct WayPoint : Object { 55 | ZK_OBJECT(ObjectType::zCWaypoint); 56 | 57 | std::string name; 58 | std::int32_t water_depth; 59 | bool under_water; 60 | Vec3 position; 61 | Vec3 direction; 62 | bool free_point {false}; 63 | 64 | ZKINT void load(ReadArchive& r, GameVersion version) override; 65 | ZKINT void save(WriteArchive& w, GameVersion version) const override; 66 | }; 67 | 68 | /// \brief Represents a way-net. 69 | /// 70 | /// Way-nets are used for NPC navigation and path finding. 71 | class WayNet : public Object { 72 | ZK_OBJECT(ObjectType::zCWayNet); 73 | 74 | ZKINT void load(ReadArchive& r, GameVersion version) override; 75 | ZKINT void save(WriteArchive& w, GameVersion version) const override; 76 | 77 | /// \brief All waypoints of this way-net. 78 | std::vector> points; 79 | 80 | /// \brief All edges of this way-net. 81 | std::vector, std::shared_ptr>> edges; 82 | }; 83 | #endif 84 | } // namespace zenkit 85 | -------------------------------------------------------------------------------- /license.md: -------------------------------------------------------------------------------- 1 | # The MIT license 2 | **Copyright © 2021-2024 GothicKit Contributors** 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of 5 | this software and associated documentation files (the “Software”), to deal in 6 | the Software without restriction, including without limitation the rights to use, 7 | copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the 8 | Software, and to permit persons to whom the Software is furnished to do so, subject 9 | to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | _THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 15 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 16 | PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 17 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT 18 | OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | DEALINGS IN THE SOFTWARE._ 20 | -------------------------------------------------------------------------------- /mkdocs.yml: -------------------------------------------------------------------------------- 1 | site_name: 'ZenKit' 2 | site_url: 'https://zk.gothickit.dev' 3 | copyright: 'Copyright © 2022-2023 GothicKit Contributors.' 4 | repo_url: 'https://github.com/GothicKit/ZenKit' 5 | edit_uri: 'edit/main/docs/' 6 | theme: 7 | name: 'material' 8 | language: 'en' 9 | logo: 'assets/logo-square.png' 10 | favicon: 'assets/logo-square.png' 11 | icon: 12 | repo: 'fontawesome/brands/github' 13 | palette: 14 | scheme: 'slate' 15 | primary: 'red' 16 | features: 17 | - 'navigation.instant' 18 | - 'navigation.tabs' 19 | - 'navigation.sections' 20 | - 'search.suggest' 21 | - 'search.highlight' 22 | - 'content.tabs.link' 23 | - 'content.code.copy' 24 | - 'content.code.annotate' 25 | extra_css: 26 | - 'assets/stylesheets/extra.css' 27 | extra_javascript: 28 | - 'assets/javascript/extra.js' 29 | - 'assets/javascript/mathjax.js' 30 | - 'https://polyfill.io/v3/polyfill.min.js?features=es6' 31 | - 'https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js' 32 | plugins: 33 | - 'search' 34 | - literate-nav: 35 | nav_file: 'SUMMARY.md' 36 | - 'section-index' 37 | markdown_extensions: 38 | - toc: 39 | permalink: true 40 | - pymdownx.highlight: 41 | anchor_linenums: true 42 | auto_title: true 43 | - pymdownx.emoji 44 | - pymdownx.tabbed: 45 | alternate_style: true 46 | slugify: !!python/object/apply:pymdownx.slugs.slugify 47 | kwds: 48 | case: lower 49 | - pymdownx.arithmatex: 50 | generic: true 51 | - 'abbr' 52 | - 'admonition' 53 | - 'footnotes' 54 | - 'tables' 55 | - 'pymdownx.superfences' 56 | - 'pymdownx.inlinehilite' 57 | - 'md_in_html' 58 | - 'pymdownx.details' 59 | - 'def_list' 60 | - 'attr_list' 61 | -------------------------------------------------------------------------------- /src/Boxes.cc: -------------------------------------------------------------------------------- 1 | // Copyright © 2022-2024 GothicKit Contributors. 2 | // SPDX-License-Identifier: MIT 3 | #include "zenkit/Boxes.hh" 4 | #include "zenkit/Stream.hh" 5 | 6 | #include 7 | 8 | namespace zenkit { 9 | void AxisAlignedBoundingBox::load(Read* r) { 10 | this->min = r->read_vec3(); 11 | this->max = r->read_vec3(); 12 | } 13 | 14 | void AxisAlignedBoundingBox::save(Write* w) const { 15 | w->write_vec3(this->min); 16 | w->write_vec3(this->max); 17 | } 18 | 19 | void OrientedBoundingBox::load(Read* r) { 20 | center = r->read_vec3(); 21 | axes[0] = r->read_vec3(); 22 | axes[1] = r->read_vec3(); 23 | axes[2] = r->read_vec3(); 24 | half_width = r->read_vec3(); 25 | 26 | children.resize(r->read_ushort()); 27 | for (auto& child : children) { 28 | child.load(r); 29 | } 30 | } 31 | 32 | void OrientedBoundingBox::save(Write* w) const { 33 | w->write_vec3(center); 34 | w->write_vec3(axes[0]); 35 | w->write_vec3(axes[1]); 36 | w->write_vec3(axes[2]); 37 | w->write_vec3(half_width); 38 | 39 | w->write_ushort(static_cast(this->children.size())); 40 | for (auto& child : children) { 41 | child.save(w); 42 | } 43 | } 44 | 45 | AxisAlignedBoundingBox OrientedBoundingBox::as_bbox() const { 46 | float const sign[8][3] = {{-1, -1, -1}, 47 | {-1, -1, +1}, 48 | {-1, +1, -1}, 49 | {-1, +1, +1}, 50 | {+1, -1, -1}, 51 | {+1, -1, +1}, 52 | {+1, +1, -1}, 53 | {+1, +1, +1}}; 54 | 55 | AxisAlignedBoundingBox box {}; 56 | box.min = {std::numeric_limits::max(), 57 | std::numeric_limits::max(), 58 | std::numeric_limits::max()}; 59 | 60 | box.max = {std::numeric_limits::min(), 61 | std::numeric_limits::min(), 62 | std::numeric_limits::min()}; 63 | 64 | for (auto i : sign) { 65 | auto point = center; 66 | auto axis0 = axes[0] * half_width.x * i[0]; 67 | auto axis1 = axes[1] * half_width.y * i[1]; 68 | auto axis2 = axes[2] * half_width.z * i[2]; 69 | 70 | point.x += axis0.x + axis1.x + axis2.x; 71 | point.y += axis0.y + axis1.y + axis2.y; 72 | point.z += axis0.z + axis1.z + axis2.z; 73 | 74 | box.min.x = std::min(box.min.x, point.x); 75 | box.min.y = std::min(box.min.y, point.y); 76 | box.min.z = std::min(box.min.z, point.z); 77 | 78 | box.max.x = std::max(box.max.x, point.x); 79 | box.max.y = std::max(box.max.y, point.y); 80 | box.max.z = std::max(box.max.z, point.z); 81 | } 82 | 83 | return box; 84 | } 85 | } // namespace zenkit 86 | -------------------------------------------------------------------------------- /src/Date.cc: -------------------------------------------------------------------------------- 1 | // Copyright © 2022-2024 GothicKit Contributors. 2 | // SPDX-License-Identifier: MIT 3 | #include "zenkit/Date.hh" 4 | #include "zenkit/Stream.hh" 5 | 6 | namespace zenkit { 7 | void Date::load(Read* r) { 8 | this->year = r->read_uint(); 9 | this->month = r->read_ushort(); 10 | this->day = r->read_ushort(); 11 | this->hour = r->read_ushort(); 12 | this->minute = r->read_ushort(); 13 | this->second = r->read_ushort(); 14 | (void) r->read_ushort(); // padding 15 | } 16 | 17 | void Date::save(Write* w) const { 18 | w->write_uint(this->year); 19 | w->write_ushort(this->month); 20 | w->write_ushort(this->day); 21 | w->write_ushort(this->hour); 22 | w->write_ushort(this->minute); 23 | w->write_ushort(this->second); 24 | w->write_ushort(0); // padding 25 | } 26 | } // namespace zenkit 27 | -------------------------------------------------------------------------------- /src/Error.cc: -------------------------------------------------------------------------------- 1 | // Copyright © 2023 GothicKit Contributors. 2 | // SPDX-License-Identifier: MIT 3 | #include "zenkit/Error.hh" 4 | 5 | namespace zenkit { 6 | Error::Error(std::string&& msg) : message(std::move(msg)) {} 7 | 8 | ParserError::ParserError(std::string&& type) 9 | : Error("failed parsing resource of type " + type), resource_type(type) {} 10 | 11 | ParserError::ParserError(std::string&& type, std::string&& ctx) 12 | : Error("failed parsing resource of type " + type + " [context: " + ctx + "]"), resource_type(std::move(type)), 13 | context(std::move(ctx)) {} 14 | 15 | ParserError::ParserError(std::string&& type, std::exception const& other_exc) 16 | : Error("failed parsing resource of type " + type + " due to [" + other_exc.what() + "]"), 17 | resource_type(std::move(type)), cause(other_exc) {} 18 | 19 | ParserError::ParserError(std::string&& type, std::exception const& other_exc, std::string&& ctx) 20 | : Error("failed parsing resource of type " + type + " due to [" + other_exc.what() + "] [context: " + ctx + 21 | "]"), 22 | resource_type(std::move(type)), context(std::move(ctx)), cause(other_exc) {} 23 | } // namespace zenkit 24 | -------------------------------------------------------------------------------- /src/Font.cc: -------------------------------------------------------------------------------- 1 | // Copyright © 2021-2024 GothicKit Contributors. 2 | // SPDX-License-Identifier: MIT 3 | #include "zenkit/Font.hh" 4 | #include "zenkit/Stream.hh" 5 | #include "zenkit/Error.hh" 6 | 7 | namespace zenkit { 8 | bool FontGlyph::operator==(FontGlyph const& g) const noexcept { 9 | return this->width == g.width && this->uv[0] == g.uv[0] && this->uv[1] == g.uv[1]; 10 | } 11 | 12 | Font::Font(std::string font_name, std::uint32_t font_height, std::vector font_glyphs) 13 | : name(std::move(font_name)), height(font_height), glyphs(std::move(font_glyphs)) {} 14 | 15 | void Font::load(Read* r) { 16 | if (auto version = r->read_line(true); version != "1") { 17 | throw ParserError {"Font", "version mismatch: expected version 1, got " + version}; 18 | } 19 | 20 | this->name = r->read_line(false); 21 | this->height = r->read_uint(); 22 | 23 | this->glyphs.resize(r->read_uint()); 24 | for (auto& glyph : glyphs) { 25 | glyph.width = r->read_ubyte(); 26 | } 27 | 28 | for (auto& glyph : glyphs) { 29 | glyph.uv[0] = r->read_vec2(); 30 | } 31 | 32 | for (auto& glyph : glyphs) { 33 | glyph.uv[1] = r->read_vec2(); 34 | } 35 | } 36 | 37 | void Font::save(Write* w) const { 38 | w->write_line("1"); 39 | w->write_line(this->name); 40 | w->write_uint(this->height); 41 | 42 | w->write_uint(static_cast(this->glyphs.size())); 43 | for (auto& glyph : glyphs) { 44 | w->write_ubyte(glyph.width); 45 | } 46 | 47 | for (auto& glyph : glyphs) { 48 | w->write_vec2(glyph.uv[0]); 49 | } 50 | 51 | for (auto& glyph : glyphs) { 52 | w->write_vec2(glyph.uv[1]); 53 | } 54 | } 55 | } // namespace zenkit 56 | -------------------------------------------------------------------------------- /src/Internal.hh: -------------------------------------------------------------------------------- 1 | // Copyright © 2023 GothicKit Contributors. 2 | // SPDX-License-Identifier: MIT 3 | #pragma once 4 | #include "zenkit/Logger.hh" 5 | #include 6 | 7 | #ifndef _MSC_VER 8 | #define ZKLOGT(...) zenkit::Logger::log(zenkit::LogLevel::TRACE, __VA_ARGS__) 9 | #define ZKLOGD(...) zenkit::Logger::log(zenkit::LogLevel::DEBUG, __VA_ARGS__) 10 | #define ZKLOGI(...) zenkit::Logger::log(zenkit::LogLevel::INFO, __VA_ARGS__) 11 | #define ZKLOGW(...) zenkit::Logger::log(zenkit::LogLevel::WARNING, __VA_ARGS__) 12 | #define ZKLOGE(...) zenkit::Logger::log(zenkit::LogLevel::ERROR, __VA_ARGS__) 13 | #else 14 | #define ZKLOGT(...) zenkit::Logger::log(zenkit::LogLevel::TRACE, ##__VA_ARGS__) 15 | #define ZKLOGD(...) zenkit::Logger::log(zenkit::LogLevel::DEBUG, ##__VA_ARGS__) 16 | #define ZKLOGI(...) zenkit::Logger::log(zenkit::LogLevel::INFO, ##__VA_ARGS__) 17 | #define ZKLOGW(...) zenkit::Logger::log(zenkit::LogLevel::WARNING, ##__VA_ARGS__) 18 | #define ZKLOGE(...) zenkit::Logger::log(zenkit::LogLevel::ERROR, ##__VA_ARGS__) 19 | #endif 20 | -------------------------------------------------------------------------------- /src/Misc.cc: -------------------------------------------------------------------------------- 1 | // Copyright © 2023 GothicKit Contributors. 2 | // SPDX-License-Identifier: MIT 3 | #include "zenkit/Misc.hh" 4 | 5 | #include "Internal.hh" 6 | 7 | #include 8 | #include 9 | 10 | namespace zenkit { 11 | bool iequals(std::string_view a, std::string_view b) { 12 | return std::equal(a.begin(), a.end(), b.begin(), b.end(), [](char c1, char c2) { 13 | return std::tolower(c1) == std::tolower(c2); 14 | }); 15 | } 16 | 17 | bool icompare(std::string_view a, std::string_view b) { 18 | return std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end(), [](char c1, char c2) { 19 | return std::tolower(c1) < std::tolower(c2); 20 | }); 21 | } 22 | } // namespace zenkit 23 | -------------------------------------------------------------------------------- /src/MmapPosix.cc: -------------------------------------------------------------------------------- 1 | // Copyright © 2023 GothicKit Contributors. 2 | // SPDX-License-Identifier: MIT 3 | #include "zenkit/Mmap.hh" 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | namespace zenkit { 11 | Mmap::Mmap(std::filesystem::path const& path) { 12 | auto handle = open(path.c_str(), O_RDONLY); 13 | 14 | if (handle == -1) { 15 | throw std::runtime_error {"Failed to open " + path.string()}; 16 | } 17 | 18 | struct stat st {}; 19 | if (fstat(handle, &st) != 0) { 20 | throw std::runtime_error {"Failed to stat " + path.string()}; 21 | } 22 | 23 | _m_data = 24 | static_cast(mmap(nullptr, static_cast(st.st_size), PROT_READ, MAP_SHARED, handle, 0)); 25 | if (_m_data == nullptr) { 26 | throw std::runtime_error {"Failed to mmap " + path.string()}; 27 | } 28 | 29 | _m_size = static_cast(st.st_size); 30 | _m_platform_handle = (void*) _m_data; 31 | 32 | close(handle); 33 | } 34 | 35 | Mmap::Mmap(Mmap&& other) noexcept { 36 | _m_data = other.data(); 37 | _m_size = other.size(); 38 | 39 | other._m_data = nullptr; 40 | other._m_size = 0; 41 | } 42 | 43 | Mmap::~Mmap() noexcept { 44 | if (_m_data != nullptr) { 45 | munmap((void*) _m_data, _m_size); 46 | _m_data = nullptr; 47 | _m_platform_handle = nullptr; 48 | } 49 | } 50 | } // namespace zenkit 51 | -------------------------------------------------------------------------------- /src/MmapWin32.cc: -------------------------------------------------------------------------------- 1 | // Copyright © 2023 GothicKit Contributors. 2 | // SPDX-License-Identifier: MIT 3 | #include "zenkit/Mmap.hh" 4 | 5 | #include 6 | 7 | namespace zenkit { 8 | struct Platform { 9 | HANDLE hFile; 10 | HANDLE hFileMapping; 11 | }; 12 | 13 | Mmap::Mmap(std::filesystem::path const& path) { 14 | HANDLE hFile; 15 | 16 | hFile = CreateFileW(path.c_str(), 17 | GENERIC_READ, 18 | FILE_SHARE_READ, 19 | nullptr, 20 | OPEN_EXISTING, 21 | FILE_ATTRIBUTE_NORMAL, 22 | nullptr); 23 | if (hFile == INVALID_HANDLE_VALUE) { 24 | throw std::runtime_error {"Failed to open " + path.string()}; 25 | } 26 | 27 | _m_size = GetFileSize(hFile, nullptr); 28 | 29 | HANDLE hFileMapping = CreateFileMappingA(hFile, nullptr, PAGE_READONLY, 0, _m_size, nullptr); 30 | if (hFileMapping == nullptr) { 31 | CloseHandle(hFile); 32 | throw std::runtime_error {"Failed to memory-map " + path.string()}; 33 | } 34 | 35 | _m_data = static_cast(MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0)); 36 | _m_platform_handle = new Platform {hFile, hFileMapping}; 37 | } 38 | 39 | Mmap::Mmap(Mmap&& other) noexcept { 40 | _m_data = other._m_data; 41 | _m_size = other._m_size; 42 | _m_platform_handle = other._m_platform_handle; 43 | 44 | other._m_data = nullptr; 45 | other._m_size = 0; 46 | other._m_platform_handle = nullptr; 47 | } 48 | 49 | Mmap::~Mmap() noexcept { 50 | if (_m_platform_handle != nullptr) { 51 | UnmapViewOfFile(_m_data); 52 | 53 | auto* platform = reinterpret_cast(_m_platform_handle); 54 | CloseHandle(platform->hFileMapping); 55 | CloseHandle(platform->hFile); 56 | delete platform; 57 | 58 | _m_data = nullptr; 59 | _m_size = 0; 60 | _m_platform_handle = nullptr; 61 | } 62 | } 63 | } // namespace zenkit 64 | -------------------------------------------------------------------------------- /src/Model.cc: -------------------------------------------------------------------------------- 1 | // Copyright © 2022-2024 GothicKit Contributors. 2 | // SPDX-License-Identifier: MIT 3 | #include "zenkit/Model.hh" 4 | #include "zenkit/Stream.hh" 5 | 6 | namespace zenkit { 7 | void Model::load(Read* r) { 8 | this->hierarchy.load(r); 9 | this->mesh.load(r); 10 | } 11 | 12 | void Model::save(Write* w, GameVersion version) const { 13 | this->hierarchy.save(w); 14 | this->mesh.save(w, version); 15 | } 16 | } // namespace zenkit 17 | -------------------------------------------------------------------------------- /src/ModelHierarchy.cc: -------------------------------------------------------------------------------- 1 | // Copyright © 2021-2024 GothicKit Contributors. 2 | // SPDX-License-Identifier: MIT 3 | #include "zenkit/ModelHierarchy.hh" 4 | #include "zenkit/Stream.hh" 5 | 6 | #include "Internal.hh" 7 | 8 | namespace zenkit { 9 | enum class ModelHierarchyChunkType : std::uint16_t { 10 | HIERARCHY = 0xD100, 11 | SOURCE = 0xD110, 12 | END = 0xD120, 13 | }; 14 | 15 | void ModelHierarchy::load(Read* r) { 16 | proto::read_chunked( // 17 | r, 18 | "ModelHierarchy", 19 | [this](Read* c, ModelHierarchyChunkType type) { 20 | switch (type) { 21 | case ModelHierarchyChunkType::HIERARCHY: { 22 | if (auto version = c->read_uint(); version != 0x03) { 23 | ZKLOGW("ModelHierarchy", "Trying to parse ModelHierarchy with unsupported version %d", version); 24 | } 25 | 26 | this->nodes.resize(c->read_ushort()); 27 | for (auto& node : this->nodes) { 28 | node.name = c->read_line(false); 29 | node.parent_index = c->read_short(); 30 | node.transform = c->read_mat4(); 31 | } 32 | 33 | this->bbox.load(c); 34 | this->collision_bbox.load(c); 35 | this->root_translation = c->read_vec3(); 36 | this->checksum = c->read_uint(); 37 | break; 38 | } 39 | case ModelHierarchyChunkType::SOURCE: 40 | this->source_date.load(c); 41 | this->source_path = c->read_line(false); 42 | break; 43 | case ModelHierarchyChunkType::END: 44 | return true; 45 | default: 46 | break; 47 | } 48 | 49 | return false; 50 | }); 51 | } 52 | 53 | void ModelHierarchy::save(Write* w) const { 54 | proto::write_chunk(w, ModelHierarchyChunkType::HIERARCHY, [this](Write* c) { 55 | c->write_uint(0x03); 56 | c->write_ushort(static_cast(this->nodes.size())); 57 | 58 | for (auto& node : this->nodes) { 59 | c->write_line(node.name); 60 | c->write_short(node.parent_index); 61 | c->write_mat4(node.transform); 62 | } 63 | 64 | this->bbox.save(c); 65 | this->collision_bbox.save(c); 66 | c->write_vec3(this->root_translation); 67 | c->write_uint(this->checksum); 68 | }); 69 | 70 | proto::write_chunk(w, ModelHierarchyChunkType::SOURCE, [this](Write* c) { 71 | this->source_date.save(c); 72 | c->write_line(this->source_path); 73 | }); 74 | 75 | proto::write_chunk(w, ModelHierarchyChunkType::END, [](Write*) {}); 76 | } 77 | } // namespace zenkit 78 | -------------------------------------------------------------------------------- /src/MorphMesh.cc: -------------------------------------------------------------------------------- 1 | // Copyright © 2021-2024 GothicKit Contributors. 2 | // SPDX-License-Identifier: MIT 3 | #include "zenkit/MorphMesh.hh" 4 | #include "zenkit/Stream.hh" 5 | 6 | namespace zenkit { 7 | enum class MorphMeshChunkType : std::uint16_t { 8 | SOURCES = 0xE010, 9 | HEADER = 0xE020, 10 | ANIMATIONS = 0xE030, 11 | PROTO = 0xB100, 12 | MORPH = 0xB1FF 13 | }; 14 | 15 | void MorphMesh::load(Read* r) { 16 | proto::read_chunked(r, "MorphMesh", [this](Read* c, MorphMeshChunkType type) { 17 | switch (type) { 18 | case MorphMeshChunkType::SOURCES: { 19 | auto count = c->read_ushort(); 20 | this->sources.resize(count); 21 | 22 | for (auto i = 0u; i < count; ++i) { 23 | this->sources[i].file_date.load(c); 24 | this->sources[i].file_name = c->read_line(true); 25 | } 26 | 27 | break; 28 | } 29 | case MorphMeshChunkType::HEADER: 30 | /* version = */ (void) c->read_uint(); 31 | this->name = c->read_line(true); 32 | break; 33 | case MorphMeshChunkType::PROTO: { 34 | this->mesh.load_from_section(c); 35 | this->morph_positions.resize(this->mesh.positions.size()); 36 | break; 37 | } 38 | case MorphMeshChunkType::MORPH: 39 | for (auto& morph_position : this->morph_positions) { 40 | morph_position = c->read_vec3(); 41 | } 42 | break; 43 | case MorphMeshChunkType::ANIMATIONS: { 44 | auto animation_count = c->read_ushort(); 45 | this->animations.reserve(animation_count); 46 | 47 | for (int32_t i = 0; i < animation_count; ++i) { 48 | auto& anim = this->animations.emplace_back(); 49 | anim.name = c->read_line(false); 50 | anim.blend_in = c->read_float(); 51 | anim.blend_out = c->read_float(); 52 | anim.duration = c->read_float(); 53 | anim.layer = c->read_int(); 54 | anim.speed = c->read_float(); 55 | anim.flags = c->read_ubyte(); 56 | 57 | auto vertex_count = c->read_uint(); 58 | anim.frame_count = c->read_uint(); 59 | 60 | anim.vertices.resize(vertex_count); 61 | anim.samples.resize(anim.frame_count * vertex_count); 62 | 63 | for (std::uint32_t j = 0; j < vertex_count; ++j) { 64 | anim.vertices[j] = c->read_uint(); 65 | } 66 | 67 | for (std::uint32_t j = 0; j < vertex_count * anim.frame_count; ++j) { 68 | anim.samples[j] = c->read_vec3(); 69 | } 70 | } 71 | break; 72 | } 73 | default: 74 | break; 75 | } 76 | 77 | return false; 78 | }); 79 | } 80 | } // namespace zenkit 81 | -------------------------------------------------------------------------------- /src/Object.cc: -------------------------------------------------------------------------------- 1 | #include "zenkit/Object.hh" 2 | 3 | namespace zenkit { 4 | ObjectType Object::get_object_type() const { 5 | return ObjectType::unknown; 6 | } 7 | 8 | uint16_t Object::get_version_identifier(GameVersion) const { 9 | return 0; 10 | } 11 | 12 | void Object::load(ReadArchive&, GameVersion) {} 13 | 14 | void Object::save(WriteArchive&, GameVersion) const {} 15 | } // namespace zenkit -------------------------------------------------------------------------------- /src/world/VobTree.cc: -------------------------------------------------------------------------------- 1 | // Copyright © 2021-2023 GothicKit Contributors. 2 | // SPDX-License-Identifier: MIT 3 | #include "zenkit/world/VobTree.hh" 4 | #include "zenkit/Archive.hh" 5 | #include "zenkit/vobs/VirtualObject.hh" 6 | 7 | namespace zenkit { 8 | std::shared_ptr parse_vob_tree(ReadArchive& in, GameVersion version) { 9 | auto obj = in.read_object(version); 10 | if (obj != nullptr && !is_vobject(obj->get_object_type())) { 11 | obj = nullptr; 12 | } 13 | 14 | // NOTE(lmichaelis): The NDK does not seem to support `reinterpret_pointer_cast`. 15 | std::shared_ptr object {obj, reinterpret_cast(obj.get())}; 16 | 17 | auto child_count = static_cast(in.read_int()); 18 | if (object == nullptr) { 19 | std::function skip; 20 | skip = [&skip, &in](size_t count) { 21 | for (auto i = 0u; i < count; ++i) { 22 | in.skip_object(false); 23 | 24 | auto num_children = static_cast(in.read_int()); 25 | skip(num_children); 26 | } 27 | }; 28 | 29 | skip(child_count); 30 | return nullptr; 31 | } 32 | 33 | object->children.reserve(child_count); 34 | 35 | for (auto i = 0u; i < child_count; ++i) { 36 | auto child = parse_vob_tree(in, version); 37 | if (child == nullptr) continue; 38 | 39 | object->children.push_back(std::move(child)); 40 | } 41 | 42 | return object; 43 | } 44 | 45 | void save_vob_tree(WriteArchive& w, GameVersion version, std::shared_ptr const& obj) { 46 | w.write_object(obj, version); 47 | 48 | // TODO(lmichaelis): replace `0` below with the n of the nth child we're writing 49 | w.write_int("childs0", obj->children.size()); 50 | 51 | for (auto& child : obj->children) { 52 | save_vob_tree(w, version, child); 53 | } 54 | } 55 | } // namespace zenkit 56 | -------------------------------------------------------------------------------- /tests/TestCutsceneLibrary.cc: -------------------------------------------------------------------------------- 1 | // Copyright © 2021-2023 GothicKit Contributors. 2 | // SPDX-License-Identifier: MIT 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | static void verify_g1(zenkit::CutsceneLibrary const& msgs) { 10 | CHECK_EQ(msgs.blocks.size(), 7360); 11 | 12 | auto msg20 = msgs.block_by_name("DIA_ARTO_PERM_15_00"); 13 | auto msg100 = msgs.block_by_name("DIA_BaalKagan_WasDrin_13_01"); 14 | auto msg200 = msgs.blocks[200]; 15 | auto msg_none = msgs.block_by_name("nonexistent"); 16 | 17 | CHECK_NE(msg20, nullptr); 18 | CHECK_NE(msg100, nullptr); 19 | CHECK_NE(msg200, nullptr); 20 | CHECK_EQ(msg_none, nullptr); 21 | 22 | auto message = msg20->get_message(); 23 | CHECK_EQ(message->type, 0); 24 | CHECK_EQ(message->text, "Du redest nicht viel, was?"); 25 | CHECK_EQ(message->name, "DIA_ARTO_PERM_15_00.WAV"); 26 | 27 | message = msg100->get_message(); 28 | CHECK_EQ(message->type, 0); 29 | CHECK_EQ(message->text, "Ich kann dich auf viele Arten entlohnen."); 30 | CHECK_EQ(message->name, "DIA_BAALKAGAN_WASDRIN_13_01.WAV"); 31 | 32 | message = msg200->get_message(); 33 | CHECK_EQ(message->type, 0); 34 | CHECK_EQ(message->text, "Stimmt genau."); 35 | CHECK_EQ(message->name, "DIA_BAALTARAN_INTOCASTLE_EXACTLY_15_00.WAV"); 36 | } 37 | 38 | TEST_SUITE("CutsceneLibrary") { 39 | TEST_CASE("CutsceneLibrary.load(GOTHIC1)") { 40 | auto r = zenkit::Read::from("./samples/ou.proprietary.bin"); 41 | auto ar = zenkit::ReadArchive::from(r.get()); 42 | auto msgs = ar->read_object(zenkit::GameVersion::GOTHIC_1); 43 | verify_g1(*msgs); 44 | } 45 | 46 | TEST_CASE("CutsceneLibrary.dump(GOTHIC1)") { 47 | auto r = zenkit::Read::from("./samples/ou.proprietary.bin"); 48 | auto ar = zenkit::ReadArchive::from(r.get()); 49 | auto msgs_tmp = ar->read_object(zenkit::GameVersion::GOTHIC_1); 50 | 51 | std::vector data; 52 | auto w = zenkit::Write::to(&data); 53 | auto aw = zenkit::WriteArchive::to(w.get(), zenkit::ArchiveFormat::BINARY); 54 | aw->write_object(msgs_tmp, zenkit::GameVersion::GOTHIC_1); 55 | 56 | r = zenkit::Read::from(&data); 57 | ar = zenkit::ReadArchive::from(r.get()); 58 | auto msgs = ar->read_object(zenkit::GameVersion::GOTHIC_1); 59 | 60 | verify_g1(*msgs); 61 | } 62 | 63 | TEST_CASE("CutsceneLibrary.load(GOTHIC2)" * doctest::skip()) { 64 | // TODO: Stub 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /tests/TestModel.cc: -------------------------------------------------------------------------------- 1 | // Copyright © 2022-2024 GothicKit Contributors. 2 | // SPDX-License-Identifier: MIT 3 | #include 4 | 5 | // TODO: Stub 6 | -------------------------------------------------------------------------------- /tests/TestModelHierarchy.cc: -------------------------------------------------------------------------------- 1 | // Copyright © 2021-2024 GothicKit Contributors. 2 | // SPDX-License-Identifier: MIT 3 | #include 4 | #include 5 | #include 6 | 7 | TEST_SUITE("ModelHierarchy") { 8 | TEST_CASE("ModelHierarchy.load(GOTHIC?)") { 9 | auto in = zenkit::Read::from("./samples/hierarchy0.mdh"); 10 | 11 | zenkit::ModelHierarchy mesh {}; 12 | mesh.load(in.get()); 13 | 14 | CHECK_EQ(mesh.nodes.size(), 7); 15 | CHECK_EQ(mesh.nodes[0].name, "BIP01 MUEHLE"); 16 | CHECK_EQ(mesh.nodes[0].parent_index, -1); 17 | CHECK_EQ(mesh.nodes[0].transform, zenkit::Mat4 {-1, 0, 0, 0, 0, 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1}); 18 | 19 | CHECK_EQ(mesh.nodes[1].name, "BIP01 NABE"); 20 | CHECK_EQ(mesh.nodes[1].parent_index, 0); 21 | CHECK_EQ(mesh.nodes[1].transform, zenkit::Mat4 {1, 0, 0, 0, 0, 1, -0, 0, 0, 0, 1, 0, 0, 0, -394.040466, 1}); 22 | 23 | auto box0 = mesh.bbox; 24 | CHECK_EQ(box0.min, zenkit::Vec3 {-497.17572, -0.575592041, -105.896698}); 25 | CHECK_EQ(box0.max, zenkit::Vec3 {515.717346, 364.943878, 893.536743}); 26 | 27 | auto box1 = mesh.collision_bbox; 28 | CHECK_EQ(box1.min, zenkit::Vec3 {-248.58786f, -0.402914435f, -52.948349f}); 29 | CHECK_EQ(box1.max, zenkit::Vec3 {257.858673f, 291.955109f, 446.768372f}); 30 | 31 | CHECK_EQ(mesh.root_translation, zenkit::Vec3 {0, 0, -394.040466}); 32 | } 33 | 34 | TEST_CASE("ModelHierarchy.load(GOTHIC1)" * doctest::skip()) { 35 | // TODO: Stub 36 | } 37 | 38 | TEST_CASE("ModelHierarchy.load(GOTHIC2)" * doctest::skip()) { 39 | // TODO: Stub 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /tests/TestModelMesh.cc: -------------------------------------------------------------------------------- 1 | // Copyright © 2021-2024 GothicKit Contributors. 2 | // SPDX-License-Identifier: MIT 3 | #include 4 | #include 5 | #include 6 | 7 | TEST_SUITE("ModelMesh") { 8 | // TODO: find a mesh with multiple attachments 9 | TEST_CASE("ModelMesh.load(GOTHIC?)") { 10 | auto in = zenkit::Read::from("./samples/secretdoor.mdm"); 11 | zenkit::ModelMesh mesh {}; 12 | mesh.load(in.get()); 13 | 14 | CHECK_EQ(mesh.attachments.size(), 1); 15 | CHECK_NE(mesh.attachments.find("BIP01 DOOR"), mesh.attachments.end()); 16 | CHECK_EQ(mesh.attachments.at("BIP01 DOOR").positions.size(), 8); 17 | } 18 | 19 | // TODO: find a mesh which has actual vertex weights 20 | TEST_CASE("ModelMesh.load(GOTHIC?)") { 21 | auto in = zenkit::Read::from("./samples/smoke_waterpipe.mdm"); 22 | zenkit::ModelMesh mesh {}; 23 | mesh.load(in.get()); 24 | 25 | auto& meshes = mesh.meshes; 26 | CHECK_EQ(meshes.size(), 1); 27 | 28 | auto& sk = meshes[0]; 29 | CHECK_EQ(sk.mesh.positions.size(), 115); 30 | CHECK_EQ(sk.mesh.normals.size(), 115); 31 | CHECK_EQ(sk.mesh.materials.size(), 1); 32 | CHECK_EQ(sk.mesh.sub_meshes.size(), 1); 33 | 34 | CHECK_EQ(sk.weights.size(), 115); 35 | CHECK_EQ(sk.weights[0].size(), 1); 36 | CHECK_EQ(sk.weights[0][0].weight, 1.0f); 37 | CHECK_EQ(sk.weights[0][0].position, zenkit::Vec3 {-5.49776077f, 35.086731f, -2.64756012f}); 38 | CHECK_EQ(sk.weights[0][0].node_index, 0); 39 | CHECK_EQ(sk.weights[62].size(), 1); 40 | CHECK_EQ(sk.weights[62][0].weight, 1.0f); 41 | CHECK_EQ(sk.weights[62][0].position, zenkit::Vec3 {0.260997772f, 18.0412712f, -23.9048882f}); 42 | CHECK_EQ(sk.weights[62][0].node_index, 4); 43 | CHECK_EQ(sk.weights[114].size(), 1); 44 | CHECK_EQ(sk.weights[114][0].weight, 1.0f); 45 | CHECK_EQ(sk.weights[114][0].position, zenkit::Vec3 {1.05304337f, 71.0284958f, 1.32049942f}); 46 | CHECK_EQ(sk.weights[114][0].node_index, 0); 47 | 48 | CHECK_EQ(sk.wedge_normals.size(), 0); 49 | CHECK_EQ(sk.nodes.size(), 6); 50 | CHECK_EQ(sk.nodes[0], 0); 51 | CHECK_EQ(sk.nodes[1], 5); 52 | CHECK_EQ(sk.nodes[2], 3); 53 | 54 | CHECK_EQ(sk.bboxes.size(), 6); 55 | CHECK_EQ(sk.bboxes[0].center, zenkit::Vec3 {0.612892151, 41.7827187, 0.705307007}); 56 | CHECK_EQ(sk.bboxes[0].half_width, zenkit::Vec3 {15.2073612, 33.4261742, 14.8513918}); 57 | CHECK_EQ(sk.bboxes[0].axes[0], zenkit::Vec3 {0.777145922, 0, -0.629320442}); 58 | CHECK_EQ(sk.bboxes[0].axes[1], zenkit::Vec3 {0, 1, 0}); 59 | CHECK_EQ(sk.bboxes[0].axes[2], zenkit::Vec3 {0.629320442, 0, 0.777145922}); 60 | 61 | CHECK_EQ(sk.bboxes[0].children.size(), 0); 62 | } 63 | 64 | TEST_CASE("ModelMesh.load(GOTHIC1)" * doctest::skip()) { 65 | // TODO: Stub 66 | } 67 | 68 | TEST_CASE("ModelMesh.load(GOTHIC2)" * doctest::skip()) { 69 | // TODO: Stub 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /tests/TestMorphMesh.cc: -------------------------------------------------------------------------------- 1 | // Copyright © 2021-2024 GothicKit Contributors. 2 | // SPDX-License-Identifier: MIT 3 | #include 4 | #include 5 | #include 6 | 7 | TEST_SUITE("MorphMesh") { 8 | TEST_CASE("MorphMesh.load(GOTHIC?)") { 9 | auto in = zenkit::Read::from("./samples/morph0.mmb"); 10 | zenkit::MorphMesh mesh {}; 11 | mesh.load(in.get()); 12 | 13 | CHECK_EQ(mesh.name, "ITRWSMALLBOW"); 14 | CHECK_EQ(mesh.morph_positions.size(), 28); 15 | CHECK_EQ(mesh.morph_positions[0], zenkit::Vec3 {-40.9461403, -1.73638999, -26.7512894}); 16 | CHECK_EQ(mesh.morph_positions[1], zenkit::Vec3 {-29.6147194, -1.97599006, -9.19756984}); 17 | 18 | auto& anims = mesh.animations; 19 | CHECK_EQ(anims.size(), 4); 20 | 21 | auto& anim = anims[1]; 22 | CHECK_EQ(anim.name, "S_SHOOT"); 23 | CHECK_EQ(anim.layer, 1); 24 | CHECK_EQ(anim.blend_in, 0.0100000007f); 25 | CHECK_EQ(anim.blend_out, -0.0100000007f); 26 | CHECK_EQ(anim.duration, 400.0f); 27 | CHECK_EQ(anim.speed, 0.0250000004f); 28 | CHECK_EQ(anim.flags, 0); 29 | 30 | CHECK_EQ(anim.vertices.size(), 3); 31 | CHECK_EQ(anim.vertices[0], 25); 32 | CHECK_EQ(anim.vertices[1], 26); 33 | CHECK_EQ(anim.vertices[2], 27); 34 | 35 | CHECK_EQ(anim.frame_count, 10); 36 | CHECK_EQ(anim.samples.size(), 30); 37 | 38 | CHECK_EQ(anim.samples[0], zenkit::Vec3 {0.519770026f, 0, 1.27206039f}); 39 | CHECK_EQ(anim.samples[9], zenkit::Vec3 {0, 0, 0}); 40 | CHECK_EQ(anim.samples[19], zenkit::Vec3 {-8.51126003f, 0, -20.8299408f}); 41 | 42 | CHECK_EQ(mesh.sources.size(), 4); 43 | CHECK_EQ(mesh.sources[1].file_date.year, 2000); 44 | CHECK_EQ(mesh.sources[1].file_date.month, 5); 45 | CHECK_EQ(mesh.sources[1].file_date.day, 8); 46 | CHECK_EQ(mesh.sources[1].file_date.hour, 9); 47 | CHECK_EQ(mesh.sources[1].file_date.minute, 13); 48 | CHECK_EQ(mesh.sources[1].file_date.second, 58); 49 | CHECK_EQ(mesh.sources[1].file_name, "ITRWSMALLBOWSHOOT.ASC"); 50 | } 51 | 52 | TEST_CASE("MorphMesh.load(GOTHIC1)" * doctest::skip()) { 53 | // TODO: Stub 54 | } 55 | 56 | TEST_CASE("MorphMesh.load(GOTHIC2)" * doctest::skip()) { 57 | // TODO: Stub 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /tests/TestTexture.cc: -------------------------------------------------------------------------------- 1 | // Copyright © 2021-2023 GothicKit Contributors. 2 | // SPDX-License-Identifier: MIT 3 | #include 4 | #include 5 | #include 6 | 7 | TEST_SUITE("Texture") { 8 | TEST_CASE("Texture.load(GOTHIC?)") { 9 | auto in = zenkit::Read::from("./samples/erz.tex"); 10 | zenkit::Texture texture {}; 11 | texture.load(in.get()); 12 | 13 | CHECK_EQ(texture.height(), 128); 14 | CHECK_EQ(texture.width(), 128); 15 | 16 | CHECK_EQ(texture.mipmap_width(0), 128); 17 | CHECK_EQ(texture.mipmap_height(0), 128); 18 | CHECK_EQ(texture.mipmap_width(1), 64); 19 | CHECK_EQ(texture.mipmap_height(1), 64); 20 | CHECK_EQ(texture.mipmap_width(2), 32); 21 | CHECK_EQ(texture.mipmap_height(2), 32); 22 | CHECK_EQ(texture.average_color(), 0xff443a3c); 23 | 24 | CHECK_EQ(texture.ref_height(), 128); 25 | CHECK_EQ(texture.ref_width(), 128); 26 | 27 | CHECK_EQ(texture.mipmaps(), 5); 28 | CHECK_EQ(texture.format(), zenkit::TextureFormat::DXT1); 29 | } 30 | 31 | TEST_CASE("Texture.load(GOTHIC1)" * doctest::skip()) { 32 | // TODO: Stub 33 | } 34 | 35 | TEST_CASE("Texture.load(GOTHIC2)" * doctest::skip()) { 36 | // TODO: Stub 37 | } 38 | } 39 | 40 | // TODO: Check other formats as well (DXT3, DXT5, ...) 41 | -------------------------------------------------------------------------------- /tests/TestVfs.cc: -------------------------------------------------------------------------------- 1 | // Copyright © 2023 GothicKit Contributors. 2 | // SPDX-License-Identifier: MIT 3 | #include 4 | 5 | #include 6 | 7 | void check_vfs(zenkit::Vfs const& vdf) { 8 | // Checks if all entries are here 9 | 10 | auto const& roots = vdf.root().children(); 11 | CHECK_EQ(roots.size(), 3); 12 | 13 | auto const* config_yml = vdf.find("config.yml"); 14 | CHECK_NE(config_yml, nullptr); 15 | CHECK(config_yml->type() == zenkit::VfsNodeType::FILE); 16 | 17 | auto const* readme_md = vdf.find("readme.md"); 18 | CHECK_NE(readme_md, nullptr); 19 | CHECK(readme_md->type() == zenkit::VfsNodeType::FILE); 20 | 21 | auto const* licenses_dir = vdf.find("licenses"); 22 | CHECK_NE(licenses_dir, nullptr); 23 | CHECK(licenses_dir->type() == zenkit::VfsNodeType::DIRECTORY); 24 | CHECK_EQ(licenses_dir->children().size(), 2); 25 | 26 | auto const* mit_md = vdf.find("MIT.MD"); 27 | CHECK_NE(mit_md, nullptr); 28 | CHECK(mit_md->type() == zenkit::VfsNodeType::FILE); 29 | 30 | auto const* gpl_dir = licenses_dir->child("gpl"); 31 | CHECK_NE(gpl_dir, nullptr); 32 | CHECK(gpl_dir->type() == zenkit::VfsNodeType::DIRECTORY); 33 | CHECK_EQ(gpl_dir->children().size(), 2); 34 | 35 | auto const* lgpl_md = gpl_dir->child("lgpl-3.0.md"); 36 | CHECK_EQ(gpl_dir->child("lgpl"), nullptr); 37 | CHECK_NE(lgpl_md, nullptr); 38 | CHECK(lgpl_md->type() == zenkit::VfsNodeType::FILE); 39 | 40 | auto const* gpl_md = vdf.find("gpl-3.0.MD"); 41 | CHECK_NE(gpl_md, nullptr); 42 | CHECK(gpl_md->type() == zenkit::VfsNodeType::FILE); 43 | 44 | CHECK_NE(vdf.find("lGpL-3.0.Md"), nullptr); 45 | CHECK_EQ(vdf.find("nonexistent"), nullptr); 46 | CHECK_NE(vdf.find("liceNSES"), nullptr); 47 | CHECK_EQ(vdf.find(""), nullptr); 48 | 49 | CHECK_NE(vdf.resolve("licEnSES/GPL/gpl-3.0.md"), nullptr); 50 | CHECK_EQ(vdf.resolve("licEnSES/GPL/nonexistent"), nullptr); 51 | CHECK_NE(vdf.resolve("/LICENSES"), nullptr); 52 | CHECK_NE(vdf.resolve(""), nullptr); 53 | CHECK_NE(vdf.resolve("/"), nullptr); 54 | 55 | // Ignores trailing whitespace (see #75) 56 | CHECK_NE(vdf.find("config.yml "), nullptr); 57 | CHECK_NE(vdf.resolve("licEnSES /GPL/gpl-3.0.md "), nullptr); 58 | } 59 | 60 | TEST_SUITE("Vfs") { 61 | TEST_CASE("Vfs.mount_disk(GOTHIC?)") { 62 | auto vdf = zenkit::Vfs {}; 63 | vdf.mount_disk("./samples/basic.vdf"); 64 | check_vfs(vdf); 65 | } 66 | 67 | TEST_CASE("Vfs.mount_host(GOTHIC?)") { 68 | auto vdf = zenkit::Vfs {}; 69 | vdf.mount_host("./samples/basic.vdf.dir", "/"); 70 | check_vfs(vdf); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /tests/samples/G1/DEMON_DIE_BODY.MAT: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G1/DEMON_DIE_BODY.MAT -------------------------------------------------------------------------------- /tests/samples/G1/FONT_OLD_10_WHITE_HI.FNT: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G1/FONT_OLD_10_WHITE_HI.FNT -------------------------------------------------------------------------------- /tests/samples/G1/HUMANS-S_FISTRUN.MAN: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G1/HUMANS-S_FISTRUN.MAN -------------------------------------------------------------------------------- /tests/samples/G1/Save/LOG.SAV: -------------------------------------------------------------------------------- 1 | minutes day hour minute level experience learnpoints guild strength dexterity max.hitpoints max.mana 1handed 2handed bow crossbow circle picklock pickpocket sneak acrobatic 2 | 0 0 8 0 0 0 0 (none) 10 10 40 5 0 0 0 0 0 0 0 0 0 3 | -------------------------------------------------------------------------------- /tests/samples/G1/Save/SAVEDAT.SAV: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G1/Save/SAVEDAT.SAV -------------------------------------------------------------------------------- /tests/samples/G1/Save/SAVEHDR.SAV: -------------------------------------------------------------------------------- 1 | WORLD.ZEN 2 | -------------------------------------------------------------------------------- /tests/samples/G1/Save/SAVEINFO.SAV: -------------------------------------------------------------------------------- 1 | ZenGin Archive 2 | ver 1 3 | zCArchiverGeneric 4 | ASCII 5 | saveGame 0 6 | date 24.12.2022 21:36:0 7 | user steamuser 8 | END 9 | objects 1 10 | END 11 | 12 | [% oCSavegameInfo 0 0] 13 | Title=string:sds 14 | WorldName=string:WORLD 15 | TimeDay=int:0 16 | TimeHour=int:8 17 | TimeMin=int:6 18 | SaveDate=string:24.12.2022 - 21:36 19 | VersionMajor=int:1 20 | VersionMinor=int:87 21 | PlayTimeSeconds=int:49 22 | [] 23 | -------------------------------------------------------------------------------- /tests/samples/G1/Save/THUMB.SAV: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G1/Save/THUMB.SAV -------------------------------------------------------------------------------- /tests/samples/G1/Save/WORLD.SAV: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G1/Save/WORLD.SAV -------------------------------------------------------------------------------- /tests/samples/G1/SaveFast/LOG.SAV: -------------------------------------------------------------------------------- 1 | minutes day hour minute level experience learnpoints guild strength dexterity max.hitpoints max.mana 1handed 2handed bow crossbow circle picklock pickpocket sneak acrobatic 2 | 0 0 8 0 0 0 0 (none) 10 10 40 5 0 0 0 0 0 0 0 0 0 3 | 5 0 8 5 0 0 0 (none) 10 10 40 5 0 0 0 0 0 0 0 0 0 4 | -------------------------------------------------------------------------------- /tests/samples/G1/SaveFast/SAVEDAT.SAV: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G1/SaveFast/SAVEDAT.SAV -------------------------------------------------------------------------------- /tests/samples/G1/SaveFast/SAVEHDR.SAV: -------------------------------------------------------------------------------- 1 | WORLD.ZEN 2 | -------------------------------------------------------------------------------- /tests/samples/G1/SaveFast/SAVEINFO.SAV: -------------------------------------------------------------------------------- 1 | ZenGin Archive 2 | ver 1 3 | zCArchiverGeneric 4 | ASCII 5 | saveGame 0 6 | date 28.12.2022 19:32:50 7 | user steamuser 8 | END 9 | objects 1 10 | END 11 | 12 | [% oCSavegameInfo 0 0] 13 | Title=string:sds_fast 14 | WorldName=string:WORLD 15 | TimeDay=int:0 16 | TimeHour=int:8 17 | TimeMin=int:6 18 | SaveDate=string:28.12.2022 - 19:32 19 | VersionMajor=int:1 20 | VersionMinor=int:87 21 | PlayTimeSeconds=int:60 22 | [] 23 | -------------------------------------------------------------------------------- /tests/samples/G1/SaveFast/THUMB.SAV: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G1/SaveFast/THUMB.SAV -------------------------------------------------------------------------------- /tests/samples/G1/SaveFast/WORLD.SAV: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G1/SaveFast/WORLD.SAV -------------------------------------------------------------------------------- /tests/samples/G1/VOb/oCCSTrigger.zen: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G1/VOb/oCCSTrigger.zen -------------------------------------------------------------------------------- /tests/samples/G1/VOb/oCItem.zen: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G1/VOb/oCItem.zen -------------------------------------------------------------------------------- /tests/samples/G1/VOb/oCMOB.zen: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G1/VOb/oCMOB.zen -------------------------------------------------------------------------------- /tests/samples/G1/VOb/oCMobContainer.zen: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G1/VOb/oCMobContainer.zen -------------------------------------------------------------------------------- /tests/samples/G1/VOb/oCMobDoor.zen: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G1/VOb/oCMobDoor.zen -------------------------------------------------------------------------------- /tests/samples/G1/VOb/oCMobFire.zen: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G1/VOb/oCMobFire.zen -------------------------------------------------------------------------------- /tests/samples/G1/VOb/oCMobInter.zen: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G1/VOb/oCMobInter.zen -------------------------------------------------------------------------------- /tests/samples/G1/VOb/oCTriggerChangeLevel.zen: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G1/VOb/oCTriggerChangeLevel.zen -------------------------------------------------------------------------------- /tests/samples/G1/VOb/oCTriggerScript.zen: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G1/VOb/oCTriggerScript.zen -------------------------------------------------------------------------------- /tests/samples/G1/VOb/oCZoneMusic.zen: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G1/VOb/oCZoneMusic.zen -------------------------------------------------------------------------------- /tests/samples/G1/VOb/zCMover.zen: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G1/VOb/zCMover.zen -------------------------------------------------------------------------------- /tests/samples/G1/VOb/zCPFXControler.zen: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G1/VOb/zCPFXControler.zen -------------------------------------------------------------------------------- /tests/samples/G1/VOb/zCTriggerList.zen: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G1/VOb/zCTriggerList.zen -------------------------------------------------------------------------------- /tests/samples/G1/VOb/zCVob.zen: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G1/VOb/zCVob.zen -------------------------------------------------------------------------------- /tests/samples/G1/VOb/zCVobAnimate.zen: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G1/VOb/zCVobAnimate.zen -------------------------------------------------------------------------------- /tests/samples/G1/VOb/zCVobLensFlare.zen: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G1/VOb/zCVobLensFlare.zen -------------------------------------------------------------------------------- /tests/samples/G1/VOb/zCVobLight.zen: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G1/VOb/zCVobLight.zen -------------------------------------------------------------------------------- /tests/samples/G1/VOb/zCVobSound.zen: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G1/VOb/zCVobSound.zen -------------------------------------------------------------------------------- /tests/samples/G1/VOb/zCVobSoundDaytime.zen: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G1/VOb/zCVobSoundDaytime.zen -------------------------------------------------------------------------------- /tests/samples/G1/VOb/zCZoneVobFarPlane.zen: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G1/VOb/zCZoneVobFarPlane.zen -------------------------------------------------------------------------------- /tests/samples/G1/VOb/zCZoneZFog.zen: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G1/VOb/zCZoneZFog.zen -------------------------------------------------------------------------------- /tests/samples/G2/DEMON_DIE_BODY.MAT: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G2/DEMON_DIE_BODY.MAT -------------------------------------------------------------------------------- /tests/samples/G2/FONT_OLD_10_WHITE_HI.FNT: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G2/FONT_OLD_10_WHITE_HI.FNT -------------------------------------------------------------------------------- /tests/samples/G2/HUMANS-S_FISTRUN.MAN: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G2/HUMANS-S_FISTRUN.MAN -------------------------------------------------------------------------------- /tests/samples/G2/Save/LOG.SAV: -------------------------------------------------------------------------------- 1 | minutes day hour minute level experience learnpoints guild strength dexterity max.hitpoints max.mana 1handed 2handed bow crossbow circle picklock pickpocket sneak acrobatic 2 | 0 0 8 0 0 0 0 Gildenlos 10 10 40 10 0 0 0 0 0 0 0 0 0 3 | 6 0 8 6 0 0 0 Gildenlos 10 10 40 10 0 0 0 0 0 0 0 0 0 4 | 60 0 9 0 0 200 0 Gildenlos 10 10 40 10 0 0 0 0 0 0 0 0 0 5 | 114 0 9 54 0 270 0 Gildenlos 10 10 40 10 0 0 0 0 0 0 0 0 0 6 | 120 0 10 0 0 300 0 Gildenlos 10 10 40 10 0 0 0 0 0 0 0 0 0 7 | 180 0 11 0 0 490 0 Gildenlos 10 10 40 10 0 0 0 0 0 0 0 0 0 8 | 240 0 12 0 0 490 0 Gildenlos 10 10 40 10 0 0 0 0 0 0 0 0 0 9 | 261 0 12 21 0 490 0 Gildenlos 10 10 40 10 0 0 0 0 0 0 0 0 0 10 | 265 0 12 25 0 490 0 Gildenlos 10 10 40 10 0 0 0 0 0 0 0 0 0 11 | 267 0 12 27 0 490 0 Gildenlos 10 10 40 10 0 0 0 0 0 0 0 0 0 12 | -------------------------------------------------------------------------------- /tests/samples/G2/Save/NEWWORLD.SAV: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G2/Save/NEWWORLD.SAV -------------------------------------------------------------------------------- /tests/samples/G2/Save/SAVEDAT.SAV: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G2/Save/SAVEDAT.SAV -------------------------------------------------------------------------------- /tests/samples/G2/Save/SAVEHDR.SAV: -------------------------------------------------------------------------------- 1 | NEWWORLD\NEWWORLD.ZEN 2 | -------------------------------------------------------------------------------- /tests/samples/G2/Save/SAVEINFO.SAV: -------------------------------------------------------------------------------- 1 | ZenGin Archive 2 | ver 1 3 | zCArchiverGeneric 4 | ASCII 5 | saveGame 0 6 | date 28.12.2022 18:26:10 7 | user steamuser 8 | END 9 | objects 1 10 | END 11 | 12 | [% oCSavegameInfo 0 0] 13 | Title=string:uwuowo 14 | WorldName=string:NEWWORLD 15 | TimeDay=int:0 16 | TimeHour=int:12 17 | TimeMin=int:28 18 | SaveDate=string:28.12.2022 - 18:26 19 | VersionMajor=int:2 20 | VersionMinor=int:6 21 | PlayTimeSeconds=int:1277 22 | VersionPoint=int:0 23 | VersionInt=int:0 24 | VersionAppName=string:Gothic II - 2.6 (fix) 25 | [] 26 | -------------------------------------------------------------------------------- /tests/samples/G2/Save/THUMB.SAV: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G2/Save/THUMB.SAV -------------------------------------------------------------------------------- /tests/samples/G2/SaveFast/NEWWORLD.SAV: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G2/SaveFast/NEWWORLD.SAV -------------------------------------------------------------------------------- /tests/samples/G2/SaveFast/OLDWORLD.SAV: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G2/SaveFast/OLDWORLD.SAV -------------------------------------------------------------------------------- /tests/samples/G2/SaveFast/SAVEDAT.SAV: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G2/SaveFast/SAVEDAT.SAV -------------------------------------------------------------------------------- /tests/samples/G2/SaveFast/SAVEHDR.SAV: -------------------------------------------------------------------------------- 1 | OLDWORLD\OLDWORLD.ZEN 2 | -------------------------------------------------------------------------------- /tests/samples/G2/SaveFast/SAVEINFO.SAV: -------------------------------------------------------------------------------- 1 | ZenGin Archive 2 | ver 1 3 | zCArchiverGeneric 4 | ASCII 5 | saveGame 0 6 | date 3.10.2022 11:15:55 7 | user steamuser 8 | END 9 | objects 1 10 | END 11 | 12 | [% oCSavegameInfo 0 0] 13 | Title=string:inminevalley 14 | WorldName=string:OLDWORLD 15 | TimeDay=int:0 16 | TimeHour=int:0 17 | TimeMin=int:0 18 | SaveDate=string:3.10.2022 - 11:15 19 | VersionMajor=int:2 20 | VersionMinor=int:6 21 | PlayTimeSeconds=int:433 22 | VersionPoint=int:0 23 | VersionInt=int:0 24 | VersionAppName=string:Gothic II - 2.6 (fix) 25 | [] 26 | -------------------------------------------------------------------------------- /tests/samples/G2/SaveFast/THUMB.SAV: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G2/SaveFast/THUMB.SAV -------------------------------------------------------------------------------- /tests/samples/G2/VOb/oCItem.zen: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G2/VOb/oCItem.zen -------------------------------------------------------------------------------- /tests/samples/G2/VOb/oCMOB.zen: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G2/VOb/oCMOB.zen -------------------------------------------------------------------------------- /tests/samples/G2/VOb/oCMobContainer.zen: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G2/VOb/oCMobContainer.zen -------------------------------------------------------------------------------- /tests/samples/G2/VOb/oCMobDoor.zen: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G2/VOb/oCMobDoor.zen -------------------------------------------------------------------------------- /tests/samples/G2/VOb/oCMobFire.zen: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G2/VOb/oCMobFire.zen -------------------------------------------------------------------------------- /tests/samples/G2/VOb/oCMobInter.zen: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G2/VOb/oCMobInter.zen -------------------------------------------------------------------------------- /tests/samples/G2/VOb/oCTouchDamage.zen: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G2/VOb/oCTouchDamage.zen -------------------------------------------------------------------------------- /tests/samples/G2/VOb/oCTriggerChangeLevel.zen: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G2/VOb/oCTriggerChangeLevel.zen -------------------------------------------------------------------------------- /tests/samples/G2/VOb/oCTriggerScript.zen: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G2/VOb/oCTriggerScript.zen -------------------------------------------------------------------------------- /tests/samples/G2/VOb/oCZoneMusic.zen: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G2/VOb/oCZoneMusic.zen -------------------------------------------------------------------------------- /tests/samples/G2/VOb/zCCSCamera.zen: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G2/VOb/zCCSCamera.zen -------------------------------------------------------------------------------- /tests/samples/G2/VOb/zCCodeMaster.zen: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G2/VOb/zCCodeMaster.zen -------------------------------------------------------------------------------- /tests/samples/G2/VOb/zCEarthquake.zen: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G2/VOb/zCEarthquake.zen -------------------------------------------------------------------------------- /tests/samples/G2/VOb/zCMessageFilter.zen: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G2/VOb/zCMessageFilter.zen -------------------------------------------------------------------------------- /tests/samples/G2/VOb/zCMover.zen: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G2/VOb/zCMover.zen -------------------------------------------------------------------------------- /tests/samples/G2/VOb/zCPFXControler.zen: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G2/VOb/zCPFXControler.zen -------------------------------------------------------------------------------- /tests/samples/G2/VOb/zCTrigger.zen: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G2/VOb/zCTrigger.zen -------------------------------------------------------------------------------- /tests/samples/G2/VOb/zCTriggerList.zen: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G2/VOb/zCTriggerList.zen -------------------------------------------------------------------------------- /tests/samples/G2/VOb/zCTriggerUntouch.zen: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G2/VOb/zCTriggerUntouch.zen -------------------------------------------------------------------------------- /tests/samples/G2/VOb/zCTriggerWorldStart.zen: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G2/VOb/zCTriggerWorldStart.zen -------------------------------------------------------------------------------- /tests/samples/G2/VOb/zCVob.zen: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G2/VOb/zCVob.zen -------------------------------------------------------------------------------- /tests/samples/G2/VOb/zCVobAnimate.zen: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G2/VOb/zCVobAnimate.zen -------------------------------------------------------------------------------- /tests/samples/G2/VOb/zCVobLight.zen: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G2/VOb/zCVobLight.zen -------------------------------------------------------------------------------- /tests/samples/G2/VOb/zCVobSound.zen: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G2/VOb/zCVobSound.zen -------------------------------------------------------------------------------- /tests/samples/G2/VOb/zCVobSoundDaytime.zen: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G2/VOb/zCVobSoundDaytime.zen -------------------------------------------------------------------------------- /tests/samples/G2/VOb/zCZoneVobFarPlane.zen: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G2/VOb/zCZoneVobFarPlane.zen -------------------------------------------------------------------------------- /tests/samples/G2/VOb/zCZoneZFog.zen: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/G2/VOb/zCZoneZFog.zen -------------------------------------------------------------------------------- /tests/samples/ascii.zen: -------------------------------------------------------------------------------- 1 | ZenGin Archive 2 | ver 1 3 | zCArchiverGeneric 4 | ASCII 5 | saveGame 0 6 | date 01.01.2001 00:00:00 7 | user luis 8 | END 9 | objects 23 10 | END 11 | 12 | [root_obj % 21237 1] 13 | someField0=string:a basic string 14 | someField00=bool:1 15 | 16 | [skipped % 0 3] 17 | skippedField=string:skipped 18 | [] 19 | 20 | someField1=int:672 21 | someField2=float:12.12421 22 | someField3=int:255 23 | someField4=int:32621 24 | someField5=enum:6 25 | someField6=bool:1 26 | someField7=color:1 2 3 255 27 | someField8=vec3:50 100.123 -150 28 | someField9=rawFloat:111.11 -12.99 29 | someField10=rawFloat:12 34 56 78 89 0 30 | someField11=raw:d8a47e3f00000000e584d23d000000000000803f00000000e584d2bd00000000d8a47e3f 31 | someField12=raw:f242a710 32 | 33 | [child_obj test:class:name 7323 2] 34 | [] 35 | [] 36 | -------------------------------------------------------------------------------- /tests/samples/basic.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/basic.bin -------------------------------------------------------------------------------- /tests/samples/basic.vdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/basic.vdf -------------------------------------------------------------------------------- /tests/samples/basic.vdf.dir/README.md: -------------------------------------------------------------------------------- 1 | This is just some sample data which is merged into `test/samples/basic.vdf`. -------------------------------------------------------------------------------- /tests/samples/basic.vdf.dir/config.yml: -------------------------------------------------------------------------------- 1 | # Some random file I guess :D 2 | name: John Smith 3 | age: 33 -------------------------------------------------------------------------------- /tests/samples/basic.vdf.dir/licenses/MIT.md: -------------------------------------------------------------------------------- 1 | # The MIT license 2 | 3 | **Copyright ** 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 6 | documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 7 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit 8 | persons to whom the Software is furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the 11 | Software. 12 | 13 | *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 14 | WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 15 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 16 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.* -------------------------------------------------------------------------------- /tests/samples/binary.zen: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/binary.zen -------------------------------------------------------------------------------- /tests/samples/empty.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/empty.txt -------------------------------------------------------------------------------- /tests/samples/erz.expected.0.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/erz.expected.0.bin -------------------------------------------------------------------------------- /tests/samples/erz.tex: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/erz.tex -------------------------------------------------------------------------------- /tests/samples/hierarchy0.mdh: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/hierarchy0.mdh -------------------------------------------------------------------------------- /tests/samples/menu.dat.readme: -------------------------------------------------------------------------------- 1 | To run the script tests you need to own a copy of Gothic 1. Copy or link MENU.DAT from 2 | $GOTHIC_INSTALL_DIR/_work/DATA/scripts/_compiled here with the name 'menu.proprietary.dat' 3 | (this is automatically excluded from version control). 4 | -------------------------------------------------------------------------------- /tests/samples/mesh0.mrm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/mesh0.mrm -------------------------------------------------------------------------------- /tests/samples/morph0.mmb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/morph0.mmb -------------------------------------------------------------------------------- /tests/samples/ou.bin.readme: -------------------------------------------------------------------------------- 1 | To run the message database tests you need to own a German copy of Gothic 1. Copy or link OU.BIN from 2 | $GOTHIC_INSTALL_DIR/_work/DATA/scripts/content/CUTSCENE here with the name 'ou.proprietary.bin' 3 | (this is automatically excluded from version control). 4 | -------------------------------------------------------------------------------- /tests/samples/secretdoor.mdm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/secretdoor.mdm -------------------------------------------------------------------------------- /tests/samples/smoke_waterpipe.mdm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/smoke_waterpipe.mdm -------------------------------------------------------------------------------- /tests/samples/waran.mds: -------------------------------------------------------------------------------- 1 | Model("TestModel") { 2 | meshAndTree("TestModelMesh.asc" DONT_USE_MESH) 3 | registerMesh("AnotherTestModelMesh1.asc") 4 | registerMesh("AnotherTestModelMesh2.asc") 5 | 6 | // A comment. 7 | 8 | aniEnum { 9 | ani("aniName1" 111 "aniNext1" 4.2 0.5 MI "aniModel1" F 221 -331 FPS:25 CVS:0.2 10 | 11 | ani("aniName2" 112 "aniNext2" 9.0 0 M. "aniModel2" R 222 332) { 12 | *eventTag(0 "DEF_DROP_TORCH" ATTACH) 13 | *eventTag(1 "DEF_WINDOW" "1 2 3 4 5") 14 | *eventTag("DEF_CREATE_ITEM" "eventSlot" "eventItem") 15 | 16 | *eventSFX(3 "sfxName1" EMPTY_SLOT) 17 | *eventSFX(4 "sfxName2" R:67.4) 18 | *eventSFX(4 "sfxName3" R:98.1 EMTPY_SLOT) 19 | *eventSFXGrnd(5 "sfxGrndName") 20 | 21 | *eventPFX(6 "pfxName1" "pfxPosition1" ATTACH) 22 | *eventPFX(7 991 "pfxName2" "pfxPosition2") 23 | *eventPFX(9 991 "pfxName3" "pfxPosition3" "ATTACH") 24 | *eventPFXStop(8 992) 25 | 26 | *eventMMStartAni(9 "mmAni1") 27 | *eventMMStartAni(10 "mmAni2" "mmNode") 28 | 29 | *eventCamTremor(11 881 882 883 884) 30 | } 31 | 32 | // Another comment. 33 | / Maybe even more :> 34 | 35 | aniBlend( ("blendName1" "blendNext1") 36 | aniBlend("blendName2" 113 "blendNext2") 37 | 38 | aniBlend("blendName3" "blendNext3" 223.1 333.1) { 39 | *eventSFX(4 "sfxName2" R:67.4) 40 | } 41 | 42 | aniAlias("aliasName1" 114 "aliasNext1" 100.1 200.2 RE "aliasAlias1") 43 | aniAlias("aliasName2" 115 "aliasNext2" 101.1 201.2 .F "aliasAlias2" R) 44 | 45 | aniComb("combName1" 116 "combNext1" 102.1 202.2 M "combModel1" 226) { 46 | *eventTag(0 "DEF_DROP_TORCH" ATTACH) 47 | } 48 | 49 | aniComb("combName2" 117 "combNext2" 103.1 203.2 I. "combModel2" 227) 50 | 51 | AniDisable("disable1") 52 | aniDisable("disable2") 53 | 54 | modelTag("DEF_HIT_LIMB" "tag1") 55 | modelTag("DEF_HIT_LIMB" "tag2") 56 | } 57 | -------------------------------------------------------------------------------- /tests/samples/waran.msb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GothicKit/ZenKit/7a323c32a6def07b20d1847e4f97c191595c6f2f/tests/samples/waran.msb -------------------------------------------------------------------------------- /tests/samples/world.zen.readme: -------------------------------------------------------------------------------- 1 | To run the world tests you need to own a copy of Gothic 1. Extract WORLD.ZEN from $GOTHIC_INSTALL_DIR/Data/worlds.VDF 2 | and link or copy it here with the name 'world.proprietary.zen' (this is automatically excluded from version control). 3 | -------------------------------------------------------------------------------- /vendor/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include(FetchContent) 2 | 3 | # This warning only occurs in CMake 3.24 or greater. 4 | # https://cmake.org/cmake/help/latest/policy/CMP0135.html#cmp0135 5 | if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.24") 6 | cmake_policy(SET CMP0135 NEW) 7 | endif () 8 | 9 | set(BUILD_STATIC_LIBS ON) 10 | set(BUILD_SHARED_LIBS OFF) 11 | set(BUILD_SQUISH_WITH_OPENMP OFF CACHE BOOL "" FORCE) 12 | 13 | function(px_add_dependency NAME URL URL_HASH) 14 | if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${NAME}/CMakeLists.txt) 15 | add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/${NAME} EXCLUDE_FROM_ALL) 16 | set(${NAME}_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/${NAME} CACHE PATH "Path to the sources for the ${NAME} library." FORCE) 17 | else () 18 | FetchContent_Declare( 19 | ${NAME} 20 | URL ${URL} 21 | URL_HASH SHA1=${URL_HASH} 22 | ) 23 | 24 | if (NOT ${NAME}_POPULATED) 25 | message(STATUS "Downloading ${NAME}") 26 | FetchContent_Populate(${NAME}) 27 | add_subdirectory(${${NAME}_SOURCE_DIR} ${${NAME}_BINARY_DIR} EXCLUDE_FROM_ALL) 28 | endif () 29 | 30 | set(${NAME}_SOURCE_DIR ${${NAME}_SOURCE_DIR} CACHE PATH "Path to the sources for the ${NAME} library." FORCE) 31 | endif () 32 | endfunction() 33 | 34 | px_add_dependency(doctest https://github.com/doctest/doctest/archive/refs/tags/v2.4.9.zip d1563419fa370c34c90e028c2e903a70c8dc07b2) 35 | px_add_dependency(libsquish https://github.com/lmichaelis/phoenix-libsquish/archive/cc82beff55210816e1bd531fc6057203dc309807.zip 953f5cd072cd6674d1aeaff5ff91225f2197283c) 36 | 37 | # msvc: disable -wno-* flags 38 | if (NOT MSVC) 39 | target_compile_options(squish PRIVATE -Wno-unused-but-set-variable) 40 | endif () 41 | 42 | target_include_directories(squish PUBLIC ${libsquish_SOURCE_DIR}) 43 | --------------------------------------------------------------------------------