diff --git a/404.html b/404.html index 921dda76c7..da0780d37e 100644 --- a/404.html +++ b/404.html @@ -1,4 +1,4 @@ - Gothic Modding Community

404 - Not found

\ No newline at end of file +

404 - Not found

\ No newline at end of file diff --git a/assets/icons/spacer-bool.png b/assets/icons/spacer-bool.png new file mode 100644 index 0000000000..693a514bfc Binary files /dev/null and b/assets/icons/spacer-bool.png differ diff --git a/assets/icons/spacer-class.png b/assets/icons/spacer-class.png new file mode 100644 index 0000000000..71a64637b5 Binary files /dev/null and b/assets/icons/spacer-class.png differ diff --git a/assets/icons/spacer-color.png b/assets/icons/spacer-color.png new file mode 100644 index 0000000000..efd9bf2514 Binary files /dev/null and b/assets/icons/spacer-color.png differ diff --git a/assets/icons/spacer-enum.png b/assets/icons/spacer-enum.png new file mode 100644 index 0000000000..86871d444a Binary files /dev/null and b/assets/icons/spacer-enum.png differ diff --git a/assets/icons/spacer-float.png b/assets/icons/spacer-float.png new file mode 100644 index 0000000000..18278ed923 Binary files /dev/null and b/assets/icons/spacer-float.png differ diff --git a/assets/icons/spacer-folder.png b/assets/icons/spacer-folder.png new file mode 100644 index 0000000000..6a1236d820 Binary files /dev/null and b/assets/icons/spacer-folder.png differ diff --git a/assets/icons/spacer-int.png b/assets/icons/spacer-int.png new file mode 100644 index 0000000000..beb3f0bea8 Binary files /dev/null and b/assets/icons/spacer-int.png differ diff --git a/assets/icons/spacer-misc.png b/assets/icons/spacer-misc.png new file mode 100644 index 0000000000..f03426fcce Binary files /dev/null and b/assets/icons/spacer-misc.png differ diff --git a/assets/icons/spacer-string.png b/assets/icons/spacer-string.png new file mode 100644 index 0000000000..7c6f70fbb3 Binary files /dev/null and b/assets/icons/spacer-string.png differ diff --git a/assets/icons/spacer-vec.png b/assets/icons/spacer-vec.png new file mode 100644 index 0000000000..0f88b1d306 Binary files /dev/null and b/assets/icons/spacer-vec.png differ diff --git a/assets/images/c_menu_item_farmesize.png b/assets/images/c_menu_item_farmesize.png new file mode 100644 index 0000000000..b2769a5c28 Binary files /dev/null and b/assets/images/c_menu_item_farmesize.png differ diff --git a/assets/images/decdat_loaded.png b/assets/images/decdat_loaded.png new file mode 100644 index 0000000000..4e6d49c39a Binary files /dev/null and b/assets/images/decdat_loaded.png differ diff --git a/assets/images/decdat_window.png b/assets/images/decdat_window.png new file mode 100644 index 0000000000..5adac49cf5 Binary files /dev/null and b/assets/images/decdat_window.png differ diff --git a/assets/images/social/zengin/union/plugins/zgamepad/keys_engine_logical.cs.png b/assets/images/social/blog/category/community-news.cs.png similarity index 54% rename from assets/images/social/zengin/union/plugins/zgamepad/keys_engine_logical.cs.png rename to assets/images/social/blog/category/community-news.cs.png index b30f818d30..469b5c0837 100644 Binary files a/assets/images/social/zengin/union/plugins/zgamepad/keys_engine_logical.cs.png and b/assets/images/social/blog/category/community-news.cs.png differ diff --git a/assets/images/social/zengin/union/plugins/zgamepad/keys_engine_logical.pl.png b/assets/images/social/blog/category/community-news.pl.png similarity index 56% rename from assets/images/social/zengin/union/plugins/zgamepad/keys_engine_logical.pl.png rename to assets/images/social/blog/category/community-news.pl.png index 5e58cf1202..0e19dd2e1e 100644 Binary files a/assets/images/social/zengin/union/plugins/zgamepad/keys_engine_logical.pl.png and b/assets/images/social/blog/category/community-news.pl.png differ diff --git a/assets/images/social/zengin/union/plugins/zgamepad/keys_engine_logical.png b/assets/images/social/blog/category/community-news.png similarity index 56% rename from assets/images/social/zengin/union/plugins/zgamepad/keys_engine_logical.png rename to assets/images/social/blog/category/community-news.png index e0f27cfe11..2b10384c94 100644 Binary files a/assets/images/social/zengin/union/plugins/zgamepad/keys_engine_logical.png and b/assets/images/social/blog/category/community-news.png differ diff --git a/assets/images/social/blog/category/tutorials.cs.png b/assets/images/social/blog/category/tutorials.cs.png new file mode 100644 index 0000000000..5515fcb13b Binary files /dev/null and b/assets/images/social/blog/category/tutorials.cs.png differ diff --git a/assets/images/social/blog/category/tutorials.pl.png b/assets/images/social/blog/category/tutorials.pl.png new file mode 100644 index 0000000000..d0efa8cea5 Binary files /dev/null and b/assets/images/social/blog/category/tutorials.pl.png differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/tools/random.png b/assets/images/social/blog/category/tutorials.png similarity index 56% rename from assets/images/social/zengin/scripts/extenders/lego/tools/random.png rename to assets/images/social/blog/category/tutorials.png index 6610ca638e..727f220b1e 100644 Binary files a/assets/images/social/zengin/scripts/extenders/lego/tools/random.png and b/assets/images/social/blog/category/tutorials.png differ diff --git a/assets/images/social/blog/index.cs.png b/assets/images/social/blog/index.cs.png new file mode 100644 index 0000000000..f1df9feb01 Binary files /dev/null and b/assets/images/social/blog/index.cs.png differ diff --git a/assets/images/social/blog/index.pl.png b/assets/images/social/blog/index.pl.png new file mode 100644 index 0000000000..0addd8c8c3 Binary files /dev/null and b/assets/images/social/blog/index.pl.png differ diff --git a/assets/images/social/blog/index.png b/assets/images/social/blog/index.png new file mode 100644 index 0000000000..2149067a4e Binary files /dev/null and b/assets/images/social/blog/index.png differ diff --git a/assets/images/social/blog/posts/community_news/welcome.cs.png b/assets/images/social/blog/posts/community_news/welcome.cs.png new file mode 100644 index 0000000000..9dd45b898f Binary files /dev/null and b/assets/images/social/blog/posts/community_news/welcome.cs.png differ diff --git a/assets/images/social/blog/posts/community_news/welcome.pl.png b/assets/images/social/blog/posts/community_news/welcome.pl.png new file mode 100644 index 0000000000..a68bdfd0c4 Binary files /dev/null and b/assets/images/social/blog/posts/community_news/welcome.pl.png differ diff --git a/assets/images/social/blog/posts/community_news/welcome.png b/assets/images/social/blog/posts/community_news/welcome.png new file mode 100644 index 0000000000..8b71bb288b Binary files /dev/null and b/assets/images/social/blog/posts/community_news/welcome.png differ diff --git a/assets/images/social/blog/posts/tutorials/how_to_write_blog_posts.cs.png b/assets/images/social/blog/posts/tutorials/how_to_write_blog_posts.cs.png new file mode 100644 index 0000000000..5944b79e9f Binary files /dev/null and b/assets/images/social/blog/posts/tutorials/how_to_write_blog_posts.cs.png differ diff --git a/assets/images/social/blog/posts/tutorials/how_to_write_blog_posts.pl.png b/assets/images/social/blog/posts/tutorials/how_to_write_blog_posts.pl.png new file mode 100644 index 0000000000..03fa685ecb Binary files /dev/null and b/assets/images/social/blog/posts/tutorials/how_to_write_blog_posts.pl.png differ diff --git a/assets/images/social/blog/posts/tutorials/how_to_write_blog_posts.png b/assets/images/social/blog/posts/tutorials/how_to_write_blog_posts.png new file mode 100644 index 0000000000..647ac08081 Binary files /dev/null and b/assets/images/social/blog/posts/tutorials/how_to_write_blog_posts.png differ diff --git a/assets/images/social/blog/tags.cs.png b/assets/images/social/blog/tags.cs.png new file mode 100644 index 0000000000..34c4f80a30 Binary files /dev/null and b/assets/images/social/blog/tags.cs.png differ diff --git a/assets/images/social/blog/tags.pl.png b/assets/images/social/blog/tags.pl.png new file mode 100644 index 0000000000..aa2cce0ad6 Binary files /dev/null and b/assets/images/social/blog/tags.pl.png differ diff --git a/assets/images/social/blog/tags.png b/assets/images/social/blog/tags.png new file mode 100644 index 0000000000..576b1b213b Binary files /dev/null and b/assets/images/social/blog/tags.png differ diff --git a/assets/images/social/zengin/anims/events.cs.png b/assets/images/social/zengin/anims/events.cs.png deleted file mode 100644 index c7247b1062..0000000000 Binary files a/assets/images/social/zengin/anims/events.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/anims/events.pl.png b/assets/images/social/zengin/anims/events.pl.png deleted file mode 100644 index d8defe353d..0000000000 Binary files a/assets/images/social/zengin/anims/events.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/anims/events.png b/assets/images/social/zengin/anims/events.png deleted file mode 100644 index 471dffef9d..0000000000 Binary files a/assets/images/social/zengin/anims/events.png and /dev/null differ diff --git a/assets/images/social/zengin/anims/index.cs.png b/assets/images/social/zengin/anims/index.cs.png deleted file mode 100644 index 651410a9ee..0000000000 Binary files a/assets/images/social/zengin/anims/index.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/anims/index.pl.png b/assets/images/social/zengin/anims/index.pl.png deleted file mode 100644 index e8e679a07c..0000000000 Binary files a/assets/images/social/zengin/anims/index.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/anims/index.png b/assets/images/social/zengin/anims/index.png deleted file mode 100644 index 0dbf9dbf59..0000000000 Binary files a/assets/images/social/zengin/anims/index.png and /dev/null differ diff --git a/assets/images/social/zengin/anims/mds.cs.png b/assets/images/social/zengin/anims/mds.cs.png deleted file mode 100644 index a264fdc739..0000000000 Binary files a/assets/images/social/zengin/anims/mds.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/anims/mds.pl.png b/assets/images/social/zengin/anims/mds.pl.png deleted file mode 100644 index 083c84fa62..0000000000 Binary files a/assets/images/social/zengin/anims/mds.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/anims/mds.png b/assets/images/social/zengin/anims/mds.png deleted file mode 100644 index 2e648c25be..0000000000 Binary files a/assets/images/social/zengin/anims/mds.png and /dev/null differ diff --git a/assets/images/social/zengin/anims/tutorials/standalone_animation.cs.png b/assets/images/social/zengin/anims/tutorials/standalone_animation.cs.png deleted file mode 100644 index 9e6e1d5392..0000000000 Binary files a/assets/images/social/zengin/anims/tutorials/standalone_animation.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/anims/tutorials/standalone_animation.pl.png b/assets/images/social/zengin/anims/tutorials/standalone_animation.pl.png deleted file mode 100644 index ccb9704d7a..0000000000 Binary files a/assets/images/social/zengin/anims/tutorials/standalone_animation.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/anims/tutorials/standalone_animation.png b/assets/images/social/zengin/anims/tutorials/standalone_animation.png deleted file mode 100644 index 36551063bd..0000000000 Binary files a/assets/images/social/zengin/anims/tutorials/standalone_animation.png and /dev/null differ diff --git a/assets/images/social/zengin/general_info/directory_structure.cs.png b/assets/images/social/zengin/general_info/directory_structure.cs.png deleted file mode 100644 index c6222ca5ff..0000000000 Binary files a/assets/images/social/zengin/general_info/directory_structure.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/general_info/directory_structure.pl.png b/assets/images/social/zengin/general_info/directory_structure.pl.png deleted file mode 100644 index a92dc56f41..0000000000 Binary files a/assets/images/social/zengin/general_info/directory_structure.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/general_info/directory_structure.png b/assets/images/social/zengin/general_info/directory_structure.png deleted file mode 100644 index 6b7f7b1294..0000000000 Binary files a/assets/images/social/zengin/general_info/directory_structure.png and /dev/null differ diff --git a/assets/images/social/zengin/general_info/object_persistence.cs.png b/assets/images/social/zengin/general_info/object_persistence.cs.png deleted file mode 100644 index 8b244bff9f..0000000000 Binary files a/assets/images/social/zengin/general_info/object_persistence.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/general_info/object_persistence.pl.png b/assets/images/social/zengin/general_info/object_persistence.pl.png deleted file mode 100644 index 7aa1d2c49e..0000000000 Binary files a/assets/images/social/zengin/general_info/object_persistence.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/general_info/object_persistence.png b/assets/images/social/zengin/general_info/object_persistence.png deleted file mode 100644 index cd874b42e1..0000000000 Binary files a/assets/images/social/zengin/general_info/object_persistence.png and /dev/null differ diff --git a/assets/images/social/zengin/general_info/vdfs.cs.png b/assets/images/social/zengin/general_info/vdfs.cs.png deleted file mode 100644 index 6c6cfa97ea..0000000000 Binary files a/assets/images/social/zengin/general_info/vdfs.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/general_info/vdfs.pl.png b/assets/images/social/zengin/general_info/vdfs.pl.png deleted file mode 100644 index 6aee5847a1..0000000000 Binary files a/assets/images/social/zengin/general_info/vdfs.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/general_info/vdfs.png b/assets/images/social/zengin/general_info/vdfs.png deleted file mode 100644 index c1c7f5f236..0000000000 Binary files a/assets/images/social/zengin/general_info/vdfs.png and /dev/null differ diff --git a/assets/images/social/zengin/index.cs.png b/assets/images/social/zengin/index.cs.png deleted file mode 100644 index 3bf1a6c0b6..0000000000 Binary files a/assets/images/social/zengin/index.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/index.pl.png b/assets/images/social/zengin/index.pl.png deleted file mode 100644 index 02918d5470..0000000000 Binary files a/assets/images/social/zengin/index.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/index.png b/assets/images/social/zengin/index.png deleted file mode 100644 index c854d05773..0000000000 Binary files a/assets/images/social/zengin/index.png and /dev/null differ diff --git a/assets/images/social/zengin/meshes.cs.png b/assets/images/social/zengin/meshes.cs.png deleted file mode 100644 index f9d4d2cb37..0000000000 Binary files a/assets/images/social/zengin/meshes.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/meshes.pl.png b/assets/images/social/zengin/meshes.pl.png deleted file mode 100644 index 5f26b6976b..0000000000 Binary files a/assets/images/social/zengin/meshes.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/meshes.png b/assets/images/social/zengin/meshes.png deleted file mode 100644 index 82f9fd6c74..0000000000 Binary files a/assets/images/social/zengin/meshes.png and /dev/null differ diff --git a/assets/images/social/zengin/music.cs.png b/assets/images/social/zengin/music.cs.png deleted file mode 100644 index 31ec3beaf0..0000000000 Binary files a/assets/images/social/zengin/music.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/music.pl.png b/assets/images/social/zengin/music.pl.png deleted file mode 100644 index c786b68a82..0000000000 Binary files a/assets/images/social/zengin/music.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/music.png b/assets/images/social/zengin/music.png deleted file mode 100644 index 77db69a79e..0000000000 Binary files a/assets/images/social/zengin/music.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/classes/c_info.cs.png b/assets/images/social/zengin/scripts/classes/c_info.cs.png deleted file mode 100644 index eacf83a011..0000000000 Binary files a/assets/images/social/zengin/scripts/classes/c_info.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/classes/c_info.pl.png b/assets/images/social/zengin/scripts/classes/c_info.pl.png deleted file mode 100644 index d716e5076f..0000000000 Binary files a/assets/images/social/zengin/scripts/classes/c_info.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/classes/c_info.png b/assets/images/social/zengin/scripts/classes/c_info.png deleted file mode 100644 index c872947cf5..0000000000 Binary files a/assets/images/social/zengin/scripts/classes/c_info.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/classes/c_item.cs.png b/assets/images/social/zengin/scripts/classes/c_item.cs.png deleted file mode 100644 index 0090963e6a..0000000000 Binary files a/assets/images/social/zengin/scripts/classes/c_item.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/classes/c_item.pl.png b/assets/images/social/zengin/scripts/classes/c_item.pl.png deleted file mode 100644 index 0fbbf2d817..0000000000 Binary files a/assets/images/social/zengin/scripts/classes/c_item.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/classes/c_item.png b/assets/images/social/zengin/scripts/classes/c_item.png deleted file mode 100644 index ea14d3a3c4..0000000000 Binary files a/assets/images/social/zengin/scripts/classes/c_item.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/classes/c_menu.cs.png b/assets/images/social/zengin/scripts/classes/c_menu.cs.png deleted file mode 100644 index d694a87ebb..0000000000 Binary files a/assets/images/social/zengin/scripts/classes/c_menu.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/classes/c_menu.pl.png b/assets/images/social/zengin/scripts/classes/c_menu.pl.png deleted file mode 100644 index 9861d13253..0000000000 Binary files a/assets/images/social/zengin/scripts/classes/c_menu.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/classes/c_menu.png b/assets/images/social/zengin/scripts/classes/c_menu.png deleted file mode 100644 index 83ba1ef656..0000000000 Binary files a/assets/images/social/zengin/scripts/classes/c_menu.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/classes/c_musicsys_cfg.cs.png b/assets/images/social/zengin/scripts/classes/c_musicsys_cfg.cs.png deleted file mode 100644 index 5b2b30e93a..0000000000 Binary files a/assets/images/social/zengin/scripts/classes/c_musicsys_cfg.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/classes/c_musicsys_cfg.pl.png b/assets/images/social/zengin/scripts/classes/c_musicsys_cfg.pl.png deleted file mode 100644 index 2f3c6c32cf..0000000000 Binary files a/assets/images/social/zengin/scripts/classes/c_musicsys_cfg.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/classes/c_musicsys_cfg.png b/assets/images/social/zengin/scripts/classes/c_musicsys_cfg.png deleted file mode 100644 index c23e576aea..0000000000 Binary files a/assets/images/social/zengin/scripts/classes/c_musicsys_cfg.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/classes/c_musictheme.cs.png b/assets/images/social/zengin/scripts/classes/c_musictheme.cs.png deleted file mode 100644 index 98acd8d987..0000000000 Binary files a/assets/images/social/zengin/scripts/classes/c_musictheme.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/classes/c_musictheme.pl.png b/assets/images/social/zengin/scripts/classes/c_musictheme.pl.png deleted file mode 100644 index 28339db8c6..0000000000 Binary files a/assets/images/social/zengin/scripts/classes/c_musictheme.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/classes/c_musictheme.png b/assets/images/social/zengin/scripts/classes/c_musictheme.png deleted file mode 100644 index ed99385ac5..0000000000 Binary files a/assets/images/social/zengin/scripts/classes/c_musictheme.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/classes/c_svm.cs.png b/assets/images/social/zengin/scripts/classes/c_svm.cs.png deleted file mode 100644 index a85ece0c20..0000000000 Binary files a/assets/images/social/zengin/scripts/classes/c_svm.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/classes/c_svm.pl.png b/assets/images/social/zengin/scripts/classes/c_svm.pl.png deleted file mode 100644 index e3972cd8e8..0000000000 Binary files a/assets/images/social/zengin/scripts/classes/c_svm.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/classes/c_svm.png b/assets/images/social/zengin/scripts/classes/c_svm.png deleted file mode 100644 index 3dcd49f2ac..0000000000 Binary files a/assets/images/social/zengin/scripts/classes/c_svm.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/afsp/afsp_eim.cs.png b/assets/images/social/zengin/scripts/extenders/afsp/afsp_eim.cs.png deleted file mode 100644 index a7adb43e95..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/afsp/afsp_eim.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/afsp/afsp_eim.pl.png b/assets/images/social/zengin/scripts/extenders/afsp/afsp_eim.pl.png deleted file mode 100644 index 0ad5a394b9..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/afsp/afsp_eim.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/afsp/afsp_eim.png b/assets/images/social/zengin/scripts/extenders/afsp/afsp_eim.png deleted file mode 100644 index 98f50d0526..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/afsp/afsp_eim.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/afsp/index.cs.png b/assets/images/social/zengin/scripts/extenders/afsp/index.cs.png deleted file mode 100644 index 50b6e4186a..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/afsp/index.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/afsp/index.pl.png b/assets/images/social/zengin/scripts/extenders/afsp/index.pl.png deleted file mode 100644 index 5df72511f7..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/afsp/index.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/afsp/index.png b/assets/images/social/zengin/scripts/extenders/afsp/index.png deleted file mode 100644 index 0f2eafbacd..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/afsp/index.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/ikarus/constants.cs.png b/assets/images/social/zengin/scripts/extenders/ikarus/constants.cs.png deleted file mode 100644 index a060ca0d8d..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/ikarus/constants.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/ikarus/constants.pl.png b/assets/images/social/zengin/scripts/extenders/ikarus/constants.pl.png deleted file mode 100644 index cf1ed52618..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/ikarus/constants.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/ikarus/constants.png b/assets/images/social/zengin/scripts/extenders/ikarus/constants.png deleted file mode 100644 index f135ded7b8..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/ikarus/constants.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/ikarus/examples.cs.png b/assets/images/social/zengin/scripts/extenders/ikarus/examples.cs.png deleted file mode 100644 index 25d71352f8..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/ikarus/examples.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/ikarus/examples.pl.png b/assets/images/social/zengin/scripts/extenders/ikarus/examples.pl.png deleted file mode 100644 index d2610e9b2c..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/ikarus/examples.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/ikarus/examples.png b/assets/images/social/zengin/scripts/extenders/ikarus/examples.png deleted file mode 100644 index 3fae4aaca6..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/ikarus/examples.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/ikarus/floats.cs.png b/assets/images/social/zengin/scripts/extenders/ikarus/floats.cs.png deleted file mode 100644 index 8323787ab1..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/ikarus/floats.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/ikarus/floats.pl.png b/assets/images/social/zengin/scripts/extenders/ikarus/floats.pl.png deleted file mode 100644 index 97f20cd6f5..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/ikarus/floats.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/ikarus/floats.png b/assets/images/social/zengin/scripts/extenders/ikarus/floats.png deleted file mode 100644 index 556bb9670b..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/ikarus/floats.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/ikarus/functions/arrays.cs.png b/assets/images/social/zengin/scripts/extenders/ikarus/functions/arrays.cs.png deleted file mode 100644 index 49ab10ce03..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/ikarus/functions/arrays.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/ikarus/functions/arrays.pl.png b/assets/images/social/zengin/scripts/extenders/ikarus/functions/arrays.pl.png deleted file mode 100644 index 111ffc5dee..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/ikarus/functions/arrays.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/ikarus/functions/arrays.png b/assets/images/social/zengin/scripts/extenders/ikarus/functions/arrays.png deleted file mode 100644 index e0ceb954c8..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/ikarus/functions/arrays.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/ikarus/functions/asm.cs.png b/assets/images/social/zengin/scripts/extenders/ikarus/functions/asm.cs.png deleted file mode 100644 index 416080dc11..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/ikarus/functions/asm.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/ikarus/functions/asm.pl.png b/assets/images/social/zengin/scripts/extenders/ikarus/functions/asm.pl.png deleted file mode 100644 index 06acf8c5a7..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/ikarus/functions/asm.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/ikarus/functions/asm.png b/assets/images/social/zengin/scripts/extenders/ikarus/functions/asm.png deleted file mode 100644 index 3f9f36f1de..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/ikarus/functions/asm.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/ikarus/functions/call.cs.png b/assets/images/social/zengin/scripts/extenders/ikarus/functions/call.cs.png deleted file mode 100644 index a6da85245e..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/ikarus/functions/call.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/ikarus/functions/call.pl.png b/assets/images/social/zengin/scripts/extenders/ikarus/functions/call.pl.png deleted file mode 100644 index 927f057740..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/ikarus/functions/call.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/ikarus/functions/call.png b/assets/images/social/zengin/scripts/extenders/ikarus/functions/call.png deleted file mode 100644 index 293fe124cb..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/ikarus/functions/call.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/ikarus/functions/debug.cs.png b/assets/images/social/zengin/scripts/extenders/ikarus/functions/debug.cs.png deleted file mode 100644 index 60478bd0e2..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/ikarus/functions/debug.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/ikarus/functions/debug.pl.png b/assets/images/social/zengin/scripts/extenders/ikarus/functions/debug.pl.png deleted file mode 100644 index 924da2ce26..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/ikarus/functions/debug.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/ikarus/functions/debug.png b/assets/images/social/zengin/scripts/extenders/ikarus/functions/debug.png deleted file mode 100644 index f687898589..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/ikarus/functions/debug.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/ikarus/functions/ini_access.cs.png b/assets/images/social/zengin/scripts/extenders/ikarus/functions/ini_access.cs.png deleted file mode 100644 index 99f8b0a06c..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/ikarus/functions/ini_access.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/ikarus/functions/ini_access.pl.png b/assets/images/social/zengin/scripts/extenders/ikarus/functions/ini_access.pl.png deleted file mode 100644 index 9f4c014a91..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/ikarus/functions/ini_access.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/ikarus/functions/ini_access.png b/assets/images/social/zengin/scripts/extenders/ikarus/functions/ini_access.png deleted file mode 100644 index a502ecdcb5..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/ikarus/functions/ini_access.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/ikarus/functions/jumps_loops.cs.png b/assets/images/social/zengin/scripts/extenders/ikarus/functions/jumps_loops.cs.png deleted file mode 100644 index ab5c40f16d..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/ikarus/functions/jumps_loops.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/ikarus/functions/jumps_loops.pl.png b/assets/images/social/zengin/scripts/extenders/ikarus/functions/jumps_loops.pl.png deleted file mode 100644 index 3e640b4054..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/ikarus/functions/jumps_loops.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/ikarus/functions/jumps_loops.png b/assets/images/social/zengin/scripts/extenders/ikarus/functions/jumps_loops.png deleted file mode 100644 index fd96308b32..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/ikarus/functions/jumps_loops.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/ikarus/functions/keyboard.cs.png b/assets/images/social/zengin/scripts/extenders/ikarus/functions/keyboard.cs.png deleted file mode 100644 index 016924a8bd..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/ikarus/functions/keyboard.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/ikarus/functions/keyboard.pl.png b/assets/images/social/zengin/scripts/extenders/ikarus/functions/keyboard.pl.png deleted file mode 100644 index 7fd8f78ccc..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/ikarus/functions/keyboard.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/ikarus/functions/keyboard.png b/assets/images/social/zengin/scripts/extenders/ikarus/functions/keyboard.png deleted file mode 100644 index ec85d18c2a..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/ikarus/functions/keyboard.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/ikarus/functions/mem_access.cs.png b/assets/images/social/zengin/scripts/extenders/ikarus/functions/mem_access.cs.png deleted file mode 100644 index ab73fe882c..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/ikarus/functions/mem_access.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/ikarus/functions/mem_access.pl.png b/assets/images/social/zengin/scripts/extenders/ikarus/functions/mem_access.pl.png deleted file mode 100644 index 680d691e16..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/ikarus/functions/mem_access.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/ikarus/functions/mem_access.png b/assets/images/social/zengin/scripts/extenders/ikarus/functions/mem_access.png deleted file mode 100644 index a77d3efc7d..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/ikarus/functions/mem_access.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/ikarus/functions/mem_utility.cs.png b/assets/images/social/zengin/scripts/extenders/ikarus/functions/mem_utility.cs.png deleted file mode 100644 index c6b7462e5e..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/ikarus/functions/mem_utility.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/ikarus/functions/mem_utility.pl.png b/assets/images/social/zengin/scripts/extenders/ikarus/functions/mem_utility.pl.png deleted file mode 100644 index f9debd3420..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/ikarus/functions/mem_utility.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/ikarus/functions/mem_utility.png b/assets/images/social/zengin/scripts/extenders/ikarus/functions/mem_utility.png deleted file mode 100644 index e77b41ef37..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/ikarus/functions/mem_utility.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/ikarus/functions/menu_access.cs.png b/assets/images/social/zengin/scripts/extenders/ikarus/functions/menu_access.cs.png deleted file mode 100644 index 855b32f1c1..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/ikarus/functions/menu_access.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/ikarus/functions/menu_access.pl.png b/assets/images/social/zengin/scripts/extenders/ikarus/functions/menu_access.pl.png deleted file mode 100644 index 7652cae0c5..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/ikarus/functions/menu_access.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/ikarus/functions/menu_access.png b/assets/images/social/zengin/scripts/extenders/ikarus/functions/menu_access.png deleted file mode 100644 index 771562618a..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/ikarus/functions/menu_access.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/ikarus/functions/objects.cs.png b/assets/images/social/zengin/scripts/extenders/ikarus/functions/objects.cs.png deleted file mode 100644 index c219990a73..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/ikarus/functions/objects.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/ikarus/functions/objects.pl.png b/assets/images/social/zengin/scripts/extenders/ikarus/functions/objects.pl.png deleted file mode 100644 index 92a8332f5a..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/ikarus/functions/objects.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/ikarus/functions/objects.png b/assets/images/social/zengin/scripts/extenders/ikarus/functions/objects.png deleted file mode 100644 index e2a6750956..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/ikarus/functions/objects.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/ikarus/functions/parser.cs.png b/assets/images/social/zengin/scripts/extenders/ikarus/functions/parser.cs.png deleted file mode 100644 index 40913b37b8..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/ikarus/functions/parser.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/ikarus/functions/parser.pl.png b/assets/images/social/zengin/scripts/extenders/ikarus/functions/parser.pl.png deleted file mode 100644 index d7477b6cb0..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/ikarus/functions/parser.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/ikarus/functions/parser.png b/assets/images/social/zengin/scripts/extenders/ikarus/functions/parser.png deleted file mode 100644 index afe013936b..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/ikarus/functions/parser.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/ikarus/functions/string.cs.png b/assets/images/social/zengin/scripts/extenders/ikarus/functions/string.cs.png deleted file mode 100644 index 137e0b0eb2..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/ikarus/functions/string.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/ikarus/functions/string.pl.png b/assets/images/social/zengin/scripts/extenders/ikarus/functions/string.pl.png deleted file mode 100644 index 5514c88ba6..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/ikarus/functions/string.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/ikarus/functions/string.png b/assets/images/social/zengin/scripts/extenders/ikarus/functions/string.png deleted file mode 100644 index 2f5431bf84..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/ikarus/functions/string.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/ikarus/functions/time_benchmark.cs.png b/assets/images/social/zengin/scripts/extenders/ikarus/functions/time_benchmark.cs.png deleted file mode 100644 index 69ae5a09a1..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/ikarus/functions/time_benchmark.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/ikarus/functions/time_benchmark.pl.png b/assets/images/social/zengin/scripts/extenders/ikarus/functions/time_benchmark.pl.png deleted file mode 100644 index e6c2b506fd..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/ikarus/functions/time_benchmark.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/ikarus/functions/time_benchmark.png b/assets/images/social/zengin/scripts/extenders/ikarus/functions/time_benchmark.png deleted file mode 100644 index c3b2b06744..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/ikarus/functions/time_benchmark.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/ikarus/functions/win_utilities.cs.png b/assets/images/social/zengin/scripts/extenders/ikarus/functions/win_utilities.cs.png deleted file mode 100644 index b5a5ab7370..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/ikarus/functions/win_utilities.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/ikarus/functions/win_utilities.pl.png b/assets/images/social/zengin/scripts/extenders/ikarus/functions/win_utilities.pl.png deleted file mode 100644 index d008bae860..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/ikarus/functions/win_utilities.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/ikarus/functions/win_utilities.png b/assets/images/social/zengin/scripts/extenders/ikarus/functions/win_utilities.png deleted file mode 100644 index 45aad45013..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/ikarus/functions/win_utilities.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/ikarus/index.cs.png b/assets/images/social/zengin/scripts/extenders/ikarus/index.cs.png deleted file mode 100644 index 4748dae8ed..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/ikarus/index.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/ikarus/index.pl.png b/assets/images/social/zengin/scripts/extenders/ikarus/index.pl.png deleted file mode 100644 index cc333140db..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/ikarus/index.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/ikarus/index.png b/assets/images/social/zengin/scripts/extenders/ikarus/index.png deleted file mode 100644 index 0e3469fc9d..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/ikarus/index.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/ikarus/setup.cs.png b/assets/images/social/zengin/scripts/extenders/ikarus/setup.cs.png deleted file mode 100644 index 7ccda6d5e0..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/ikarus/setup.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/ikarus/setup.pl.png b/assets/images/social/zengin/scripts/extenders/ikarus/setup.pl.png deleted file mode 100644 index 520c2af16e..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/ikarus/setup.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/ikarus/setup.png b/assets/images/social/zengin/scripts/extenders/ikarus/setup.png deleted file mode 100644 index 863f24e8f7..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/ikarus/setup.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/index.cs.png b/assets/images/social/zengin/scripts/extenders/index.cs.png deleted file mode 100644 index 93f8736b67..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/index.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/index.pl.png b/assets/images/social/zengin/scripts/extenders/index.pl.png deleted file mode 100644 index f2fc9407f2..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/index.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/index.png b/assets/images/social/zengin/scripts/extenders/index.png deleted file mode 100644 index 3e59ac1b10..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/index.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/applications/anim8.cs.png b/assets/images/social/zengin/scripts/extenders/lego/applications/anim8.cs.png deleted file mode 100644 index 34a37c5efb..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/applications/anim8.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/applications/anim8.pl.png b/assets/images/social/zengin/scripts/extenders/lego/applications/anim8.pl.png deleted file mode 100644 index 34a37c5efb..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/applications/anim8.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/applications/anim8.png b/assets/images/social/zengin/scripts/extenders/lego/applications/anim8.png deleted file mode 100644 index 34a37c5efb..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/applications/anim8.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/applications/bars.cs.png b/assets/images/social/zengin/scripts/extenders/lego/applications/bars.cs.png deleted file mode 100644 index 71c1062870..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/applications/bars.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/applications/bars.pl.png b/assets/images/social/zengin/scripts/extenders/lego/applications/bars.pl.png deleted file mode 100644 index 5e472262b1..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/applications/bars.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/applications/bars.png b/assets/images/social/zengin/scripts/extenders/lego/applications/bars.png deleted file mode 100644 index 0b2ceace76..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/applications/bars.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/applications/bloodsplats.cs.png b/assets/images/social/zengin/scripts/extenders/lego/applications/bloodsplats.cs.png deleted file mode 100644 index c994811514..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/applications/bloodsplats.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/applications/bloodsplats.pl.png b/assets/images/social/zengin/scripts/extenders/lego/applications/bloodsplats.pl.png deleted file mode 100644 index c994811514..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/applications/bloodsplats.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/applications/bloodsplats.png b/assets/images/social/zengin/scripts/extenders/lego/applications/bloodsplats.png deleted file mode 100644 index c994811514..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/applications/bloodsplats.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/applications/buffs.cs.png b/assets/images/social/zengin/scripts/extenders/lego/applications/buffs.cs.png deleted file mode 100644 index b09ede29e2..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/applications/buffs.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/applications/buffs.pl.png b/assets/images/social/zengin/scripts/extenders/lego/applications/buffs.pl.png deleted file mode 100644 index ec307b0b97..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/applications/buffs.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/applications/buffs.png b/assets/images/social/zengin/scripts/extenders/lego/applications/buffs.png deleted file mode 100644 index b8dc1d18cd..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/applications/buffs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/applications/buttons.cs.png b/assets/images/social/zengin/scripts/extenders/lego/applications/buttons.cs.png deleted file mode 100644 index 5d2e99dcd8..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/applications/buttons.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/applications/buttons.pl.png b/assets/images/social/zengin/scripts/extenders/lego/applications/buttons.pl.png deleted file mode 100644 index dc3fceb225..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/applications/buttons.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/applications/buttons.png b/assets/images/social/zengin/scripts/extenders/lego/applications/buttons.png deleted file mode 100644 index 139e2d9a60..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/applications/buttons.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/applications/console_commands.cs.png b/assets/images/social/zengin/scripts/extenders/lego/applications/console_commands.cs.png deleted file mode 100644 index 6bde47107a..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/applications/console_commands.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/applications/console_commands.pl.png b/assets/images/social/zengin/scripts/extenders/lego/applications/console_commands.pl.png deleted file mode 100644 index 4cc8db014c..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/applications/console_commands.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/applications/console_commands.png b/assets/images/social/zengin/scripts/extenders/lego/applications/console_commands.png deleted file mode 100644 index a7234ebf88..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/applications/console_commands.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/applications/cursor.cs.png b/assets/images/social/zengin/scripts/extenders/lego/applications/cursor.cs.png deleted file mode 100644 index 4b2fdeaae8..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/applications/cursor.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/applications/cursor.pl.png b/assets/images/social/zengin/scripts/extenders/lego/applications/cursor.pl.png deleted file mode 100644 index b6960b0ccf..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/applications/cursor.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/applications/cursor.png b/assets/images/social/zengin/scripts/extenders/lego/applications/cursor.png deleted file mode 100644 index 5e711242d4..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/applications/cursor.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/applications/dialoggestures.cs.png b/assets/images/social/zengin/scripts/extenders/lego/applications/dialoggestures.cs.png deleted file mode 100644 index 0207199e9d..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/applications/dialoggestures.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/applications/dialoggestures.pl.png b/assets/images/social/zengin/scripts/extenders/lego/applications/dialoggestures.pl.png deleted file mode 100644 index 0207199e9d..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/applications/dialoggestures.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/applications/dialoggestures.png b/assets/images/social/zengin/scripts/extenders/lego/applications/dialoggestures.png deleted file mode 100644 index 0207199e9d..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/applications/dialoggestures.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/applications/focusnames.cs.png b/assets/images/social/zengin/scripts/extenders/lego/applications/focusnames.cs.png deleted file mode 100644 index 4a1d21f612..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/applications/focusnames.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/applications/focusnames.pl.png b/assets/images/social/zengin/scripts/extenders/lego/applications/focusnames.pl.png deleted file mode 100644 index b06b5d2000..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/applications/focusnames.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/applications/focusnames.png b/assets/images/social/zengin/scripts/extenders/lego/applications/focusnames.png deleted file mode 100644 index 91ce217719..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/applications/focusnames.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/applications/gamestate.cs.png b/assets/images/social/zengin/scripts/extenders/lego/applications/gamestate.cs.png deleted file mode 100644 index 60c54ad5b3..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/applications/gamestate.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/applications/gamestate.pl.png b/assets/images/social/zengin/scripts/extenders/lego/applications/gamestate.pl.png deleted file mode 100644 index d431ee0b68..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/applications/gamestate.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/applications/gamestate.png b/assets/images/social/zengin/scripts/extenders/lego/applications/gamestate.png deleted file mode 100644 index 60c54ad5b3..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/applications/gamestate.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/applications/names.cs.png b/assets/images/social/zengin/scripts/extenders/lego/applications/names.cs.png deleted file mode 100644 index c52c2b38b9..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/applications/names.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/applications/names.pl.png b/assets/images/social/zengin/scripts/extenders/lego/applications/names.pl.png deleted file mode 100644 index 385daa7f99..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/applications/names.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/applications/names.png b/assets/images/social/zengin/scripts/extenders/lego/applications/names.png deleted file mode 100644 index 850b304527..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/applications/names.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/applications/render.cs.png b/assets/images/social/zengin/scripts/extenders/lego/applications/render.cs.png deleted file mode 100644 index 6a4a370785..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/applications/render.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/applications/render.pl.png b/assets/images/social/zengin/scripts/extenders/lego/applications/render.pl.png deleted file mode 100644 index 03155530ba..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/applications/render.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/applications/render.png b/assets/images/social/zengin/scripts/extenders/lego/applications/render.png deleted file mode 100644 index cf2444b022..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/applications/render.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/applications/saves.cs.png b/assets/images/social/zengin/scripts/extenders/lego/applications/saves.cs.png deleted file mode 100644 index fc73fb713e..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/applications/saves.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/applications/saves.pl.png b/assets/images/social/zengin/scripts/extenders/lego/applications/saves.pl.png deleted file mode 100644 index bd2eea6260..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/applications/saves.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/applications/saves.png b/assets/images/social/zengin/scripts/extenders/lego/applications/saves.png deleted file mode 100644 index 7056353222..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/applications/saves.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/applications/trialoge.cs.png b/assets/images/social/zengin/scripts/extenders/lego/applications/trialoge.cs.png deleted file mode 100644 index baea229414..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/applications/trialoge.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/applications/trialoge.pl.png b/assets/images/social/zengin/scripts/extenders/lego/applications/trialoge.pl.png deleted file mode 100644 index 22429d4f95..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/applications/trialoge.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/applications/trialoge.png b/assets/images/social/zengin/scripts/extenders/lego/applications/trialoge.png deleted file mode 100644 index baea229414..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/applications/trialoge.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/index.cs.png b/assets/images/social/zengin/scripts/extenders/lego/index.cs.png deleted file mode 100644 index 8825f29073..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/index.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/index.pl.png b/assets/images/social/zengin/scripts/extenders/lego/index.pl.png deleted file mode 100644 index 5bc1ae25be..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/index.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/index.png b/assets/images/social/zengin/scripts/extenders/lego/index.png deleted file mode 100644 index f3e814ca20..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/index.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/tools/ai_function.cs.png b/assets/images/social/zengin/scripts/extenders/lego/tools/ai_function.cs.png deleted file mode 100644 index c0d17cadbc..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/tools/ai_function.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/tools/ai_function.pl.png b/assets/images/social/zengin/scripts/extenders/lego/tools/ai_function.pl.png deleted file mode 100644 index 779e44ff07..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/tools/ai_function.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/tools/ai_function.png b/assets/images/social/zengin/scripts/extenders/lego/tools/ai_function.png deleted file mode 100644 index c0d17cadbc..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/tools/ai_function.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/tools/binary_machines.cs.png b/assets/images/social/zengin/scripts/extenders/lego/tools/binary_machines.cs.png deleted file mode 100644 index 669929db77..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/tools/binary_machines.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/tools/binary_machines.pl.png b/assets/images/social/zengin/scripts/extenders/lego/tools/binary_machines.pl.png deleted file mode 100644 index 675c960a84..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/tools/binary_machines.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/tools/binary_machines.png b/assets/images/social/zengin/scripts/extenders/lego/tools/binary_machines.png deleted file mode 100644 index 669929db77..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/tools/binary_machines.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/tools/event_handler.cs.png b/assets/images/social/zengin/scripts/extenders/lego/tools/event_handler.cs.png deleted file mode 100644 index 6fa90e0341..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/tools/event_handler.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/tools/event_handler.pl.png b/assets/images/social/zengin/scripts/extenders/lego/tools/event_handler.pl.png deleted file mode 100644 index 6fa90e0341..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/tools/event_handler.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/tools/event_handler.png b/assets/images/social/zengin/scripts/extenders/lego/tools/event_handler.png deleted file mode 100644 index 6fa90e0341..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/tools/event_handler.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/tools/frame_functions.cs.png b/assets/images/social/zengin/scripts/extenders/lego/tools/frame_functions.cs.png deleted file mode 100644 index bc769d75b5..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/tools/frame_functions.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/tools/frame_functions.pl.png b/assets/images/social/zengin/scripts/extenders/lego/tools/frame_functions.pl.png deleted file mode 100644 index bc769d75b5..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/tools/frame_functions.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/tools/frame_functions.png b/assets/images/social/zengin/scripts/extenders/lego/tools/frame_functions.png deleted file mode 100644 index bc769d75b5..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/tools/frame_functions.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/tools/hashtables.cs.png b/assets/images/social/zengin/scripts/extenders/lego/tools/hashtables.cs.png deleted file mode 100644 index c34ddf2b31..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/tools/hashtables.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/tools/hashtables.pl.png b/assets/images/social/zengin/scripts/extenders/lego/tools/hashtables.pl.png deleted file mode 100644 index c34ddf2b31..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/tools/hashtables.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/tools/hashtables.png b/assets/images/social/zengin/scripts/extenders/lego/tools/hashtables.png deleted file mode 100644 index c34ddf2b31..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/tools/hashtables.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/tools/hook_dae.cs.png b/assets/images/social/zengin/scripts/extenders/lego/tools/hook_dae.cs.png deleted file mode 100644 index dacdab34b3..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/tools/hook_dae.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/tools/hook_dae.pl.png b/assets/images/social/zengin/scripts/extenders/lego/tools/hook_dae.pl.png deleted file mode 100644 index dacdab34b3..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/tools/hook_dae.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/tools/hook_dae.png b/assets/images/social/zengin/scripts/extenders/lego/tools/hook_dae.png deleted file mode 100644 index dacdab34b3..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/tools/hook_dae.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/tools/hook_engine.cs.png b/assets/images/social/zengin/scripts/extenders/lego/tools/hook_engine.cs.png deleted file mode 100644 index d30e7a58a5..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/tools/hook_engine.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/tools/hook_engine.pl.png b/assets/images/social/zengin/scripts/extenders/lego/tools/hook_engine.pl.png deleted file mode 100644 index ac62de2c91..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/tools/hook_engine.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/tools/hook_engine.png b/assets/images/social/zengin/scripts/extenders/lego/tools/hook_engine.png deleted file mode 100644 index 785e7271bb..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/tools/hook_engine.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/tools/int64.cs.png b/assets/images/social/zengin/scripts/extenders/lego/tools/int64.cs.png deleted file mode 100644 index 467c2d5eff..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/tools/int64.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/tools/int64.pl.png b/assets/images/social/zengin/scripts/extenders/lego/tools/int64.pl.png deleted file mode 100644 index aad17b893b..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/tools/int64.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/tools/int64.png b/assets/images/social/zengin/scripts/extenders/lego/tools/int64.png deleted file mode 100644 index ec8062f603..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/tools/int64.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/tools/interface.cs.png b/assets/images/social/zengin/scripts/extenders/lego/tools/interface.cs.png deleted file mode 100644 index c52ef3aa53..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/tools/interface.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/tools/interface.pl.png b/assets/images/social/zengin/scripts/extenders/lego/tools/interface.pl.png deleted file mode 100644 index c52ef3aa53..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/tools/interface.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/tools/interface.png b/assets/images/social/zengin/scripts/extenders/lego/tools/interface.png deleted file mode 100644 index c52ef3aa53..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/tools/interface.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/tools/item_helper.cs.png b/assets/images/social/zengin/scripts/extenders/lego/tools/item_helper.cs.png deleted file mode 100644 index c1a2b3c1f7..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/tools/item_helper.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/tools/item_helper.pl.png b/assets/images/social/zengin/scripts/extenders/lego/tools/item_helper.pl.png deleted file mode 100644 index 4672798f3b..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/tools/item_helper.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/tools/item_helper.png b/assets/images/social/zengin/scripts/extenders/lego/tools/item_helper.png deleted file mode 100644 index ee1f4ec2f2..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/tools/item_helper.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/tools/list.cs.png b/assets/images/social/zengin/scripts/extenders/lego/tools/list.cs.png deleted file mode 100644 index d7ed3541e3..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/tools/list.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/tools/list.pl.png b/assets/images/social/zengin/scripts/extenders/lego/tools/list.pl.png deleted file mode 100644 index 7aa2ea27ba..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/tools/list.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/tools/list.png b/assets/images/social/zengin/scripts/extenders/lego/tools/list.png deleted file mode 100644 index bb9d4e19b6..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/tools/list.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/tools/locals.cs.png b/assets/images/social/zengin/scripts/extenders/lego/tools/locals.cs.png deleted file mode 100644 index e1431373d6..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/tools/locals.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/tools/locals.pl.png b/assets/images/social/zengin/scripts/extenders/lego/tools/locals.pl.png deleted file mode 100644 index 533bbab23b..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/tools/locals.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/tools/locals.png b/assets/images/social/zengin/scripts/extenders/lego/tools/locals.png deleted file mode 100644 index 823a45df1d..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/tools/locals.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/tools/misc.cs.png b/assets/images/social/zengin/scripts/extenders/lego/tools/misc.cs.png deleted file mode 100644 index 866a915d70..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/tools/misc.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/tools/misc.pl.png b/assets/images/social/zengin/scripts/extenders/lego/tools/misc.pl.png deleted file mode 100644 index fd984c344b..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/tools/misc.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/tools/misc.png b/assets/images/social/zengin/scripts/extenders/lego/tools/misc.png deleted file mode 100644 index 866a915d70..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/tools/misc.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/tools/permmem.cs.png b/assets/images/social/zengin/scripts/extenders/lego/tools/permmem.cs.png deleted file mode 100644 index 94a56cc236..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/tools/permmem.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/tools/permmem.pl.png b/assets/images/social/zengin/scripts/extenders/lego/tools/permmem.pl.png deleted file mode 100644 index cf8e6c526c..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/tools/permmem.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/tools/permmem.png b/assets/images/social/zengin/scripts/extenders/lego/tools/permmem.png deleted file mode 100644 index e81b8a6b30..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/tools/permmem.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/tools/queue.cs.png b/assets/images/social/zengin/scripts/extenders/lego/tools/queue.cs.png deleted file mode 100644 index e0693ea226..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/tools/queue.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/tools/queue.pl.png b/assets/images/social/zengin/scripts/extenders/lego/tools/queue.pl.png deleted file mode 100644 index b8dd0968c4..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/tools/queue.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/tools/queue.png b/assets/images/social/zengin/scripts/extenders/lego/tools/queue.png deleted file mode 100644 index e592345c5b..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/tools/queue.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/tools/random.cs.png b/assets/images/social/zengin/scripts/extenders/lego/tools/random.cs.png deleted file mode 100644 index 6ca4a5e494..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/tools/random.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/tools/random.pl.png b/assets/images/social/zengin/scripts/extenders/lego/tools/random.pl.png deleted file mode 100644 index 5e11c04712..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/tools/random.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/tools/string_builder.cs.png b/assets/images/social/zengin/scripts/extenders/lego/tools/string_builder.cs.png deleted file mode 100644 index dbd8104629..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/tools/string_builder.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/tools/string_builder.pl.png b/assets/images/social/zengin/scripts/extenders/lego/tools/string_builder.pl.png deleted file mode 100644 index dbd8104629..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/tools/string_builder.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/tools/string_builder.png b/assets/images/social/zengin/scripts/extenders/lego/tools/string_builder.png deleted file mode 100644 index dbd8104629..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/tools/string_builder.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/tools/talents.cs.png b/assets/images/social/zengin/scripts/extenders/lego/tools/talents.cs.png deleted file mode 100644 index 2c7837bc72..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/tools/talents.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/tools/talents.pl.png b/assets/images/social/zengin/scripts/extenders/lego/tools/talents.pl.png deleted file mode 100644 index 7eddf400b9..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/tools/talents.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/tools/talents.png b/assets/images/social/zengin/scripts/extenders/lego/tools/talents.png deleted file mode 100644 index f62cc66707..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/tools/talents.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/tools/timer.cs.png b/assets/images/social/zengin/scripts/extenders/lego/tools/timer.cs.png deleted file mode 100644 index 3f792b0d9b..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/tools/timer.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/tools/timer.pl.png b/assets/images/social/zengin/scripts/extenders/lego/tools/timer.pl.png deleted file mode 100644 index c2542da014..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/tools/timer.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/tools/timer.png b/assets/images/social/zengin/scripts/extenders/lego/tools/timer.png deleted file mode 100644 index a35709149f..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/tools/timer.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/tools/view.cs.png b/assets/images/social/zengin/scripts/extenders/lego/tools/view.cs.png deleted file mode 100644 index 67d561816c..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/tools/view.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/tools/view.pl.png b/assets/images/social/zengin/scripts/extenders/lego/tools/view.pl.png deleted file mode 100644 index 144bf11b0c..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/tools/view.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/tools/view.png b/assets/images/social/zengin/scripts/extenders/lego/tools/view.png deleted file mode 100644 index f00fe9354e..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/tools/view.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/various/userconstants.cs.png b/assets/images/social/zengin/scripts/extenders/lego/various/userconstants.cs.png deleted file mode 100644 index a7d6fdf521..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/various/userconstants.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/various/userconstants.pl.png b/assets/images/social/zengin/scripts/extenders/lego/various/userconstants.pl.png deleted file mode 100644 index 1b8686cdfd..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/various/userconstants.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/lego/various/userconstants.png b/assets/images/social/zengin/scripts/extenders/lego/various/userconstants.png deleted file mode 100644 index f85bbe74be..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/lego/various/userconstants.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/standalone/gameKeyEvents.cs.png b/assets/images/social/zengin/scripts/extenders/standalone/gameKeyEvents.cs.png deleted file mode 100644 index dfc43e49f3..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/standalone/gameKeyEvents.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/standalone/gameKeyEvents.pl.png b/assets/images/social/zengin/scripts/extenders/standalone/gameKeyEvents.pl.png deleted file mode 100644 index f332085575..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/standalone/gameKeyEvents.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/standalone/gameKeyEvents.png b/assets/images/social/zengin/scripts/extenders/standalone/gameKeyEvents.png deleted file mode 100644 index ce2a811eeb..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/standalone/gameKeyEvents.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/standalone/index.cs.png b/assets/images/social/zengin/scripts/extenders/standalone/index.cs.png deleted file mode 100644 index c4d7922818..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/standalone/index.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/standalone/index.pl.png b/assets/images/social/zengin/scripts/extenders/standalone/index.pl.png deleted file mode 100644 index 1ad4904de0..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/standalone/index.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/standalone/index.png b/assets/images/social/zengin/scripts/extenders/standalone/index.png deleted file mode 100644 index 96551221f5..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/standalone/index.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/standalone/setBarPositions.cs.png b/assets/images/social/zengin/scripts/extenders/standalone/setBarPositions.cs.png deleted file mode 100644 index 25da56a2b2..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/standalone/setBarPositions.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/standalone/setBarPositions.pl.png b/assets/images/social/zengin/scripts/extenders/standalone/setBarPositions.pl.png deleted file mode 100644 index 0a825cff85..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/standalone/setBarPositions.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/standalone/setBarPositions.png b/assets/images/social/zengin/scripts/extenders/standalone/setBarPositions.png deleted file mode 100644 index 4652a9f1d4..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/standalone/setBarPositions.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/classes/c_trigger.cs.png b/assets/images/social/zengin/scripts/extenders/zparserextender/classes/c_trigger.cs.png deleted file mode 100644 index e790f3765f..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/classes/c_trigger.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/classes/c_trigger.pl.png b/assets/images/social/zengin/scripts/extenders/zparserextender/classes/c_trigger.pl.png deleted file mode 100644 index f119e608e3..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/classes/c_trigger.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/classes/c_trigger.png b/assets/images/social/zengin/scripts/extenders/zparserextender/classes/c_trigger.png deleted file mode 100644 index c6d1dabe81..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/classes/c_trigger.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/classes/helperclasses.cs.png b/assets/images/social/zengin/scripts/extenders/zparserextender/classes/helperclasses.cs.png deleted file mode 100644 index 1c1bc2e2d2..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/classes/helperclasses.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/classes/helperclasses.pl.png b/assets/images/social/zengin/scripts/extenders/zparserextender/classes/helperclasses.pl.png deleted file mode 100644 index 65f21a3887..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/classes/helperclasses.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/classes/helperclasses.png b/assets/images/social/zengin/scripts/extenders/zparserextender/classes/helperclasses.png deleted file mode 100644 index 83575bd0bc..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/classes/helperclasses.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/daedalus_injection/hooks.cs.png b/assets/images/social/zengin/scripts/extenders/zparserextender/daedalus_injection/hooks.cs.png deleted file mode 100644 index e6b6427555..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/daedalus_injection/hooks.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/daedalus_injection/hooks.pl.png b/assets/images/social/zengin/scripts/extenders/zparserextender/daedalus_injection/hooks.pl.png deleted file mode 100644 index 4898b62716..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/daedalus_injection/hooks.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/daedalus_injection/hooks.png b/assets/images/social/zengin/scripts/extenders/zparserextender/daedalus_injection/hooks.png deleted file mode 100644 index b2f0ceddd4..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/daedalus_injection/hooks.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/daedalus_injection/index.cs.png b/assets/images/social/zengin/scripts/extenders/zparserextender/daedalus_injection/index.cs.png deleted file mode 100644 index 46413bb400..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/daedalus_injection/index.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/daedalus_injection/index.pl.png b/assets/images/social/zengin/scripts/extenders/zparserextender/daedalus_injection/index.pl.png deleted file mode 100644 index 13c5a01894..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/daedalus_injection/index.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/daedalus_injection/index.png b/assets/images/social/zengin/scripts/extenders/zparserextender/daedalus_injection/index.png deleted file mode 100644 index a216da3d7b..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/daedalus_injection/index.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/daedalus_injection/meta.cs.png b/assets/images/social/zengin/scripts/extenders/zparserextender/daedalus_injection/meta.cs.png deleted file mode 100644 index 8a00b7a57c..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/daedalus_injection/meta.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/daedalus_injection/meta.pl.png b/assets/images/social/zengin/scripts/extenders/zparserextender/daedalus_injection/meta.pl.png deleted file mode 100644 index a09e7245d0..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/daedalus_injection/meta.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/daedalus_injection/meta.png b/assets/images/social/zengin/scripts/extenders/zparserextender/daedalus_injection/meta.png deleted file mode 100644 index 4a3c390247..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/daedalus_injection/meta.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/daedalus_injection/other.cs.png b/assets/images/social/zengin/scripts/extenders/zparserextender/daedalus_injection/other.cs.png deleted file mode 100644 index 41838e663d..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/daedalus_injection/other.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/daedalus_injection/other.pl.png b/assets/images/social/zengin/scripts/extenders/zparserextender/daedalus_injection/other.pl.png deleted file mode 100644 index 8ecfa826e9..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/daedalus_injection/other.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/daedalus_injection/other.png b/assets/images/social/zengin/scripts/extenders/zparserextender/daedalus_injection/other.png deleted file mode 100644 index 0e6650d53b..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/daedalus_injection/other.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/examples/signposts.cs.png b/assets/images/social/zengin/scripts/extenders/zparserextender/examples/signposts.cs.png deleted file mode 100644 index d504be22fa..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/examples/signposts.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/examples/signposts.pl.png b/assets/images/social/zengin/scripts/extenders/zparserextender/examples/signposts.pl.png deleted file mode 100644 index 9af1d30036..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/examples/signposts.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/examples/signposts.png b/assets/images/social/zengin/scripts/extenders/zparserextender/examples/signposts.png deleted file mode 100644 index 49db02b63c..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/examples/signposts.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/ai.cs.png b/assets/images/social/zengin/scripts/extenders/zparserextender/externals/ai.cs.png deleted file mode 100644 index 2d137b4c84..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/ai.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/ai.pl.png b/assets/images/social/zengin/scripts/extenders/zparserextender/externals/ai.pl.png deleted file mode 100644 index 3da2d09578..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/ai.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/ai.png b/assets/images/social/zengin/scripts/extenders/zparserextender/externals/ai.png deleted file mode 100644 index cb99035d15..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/ai.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/cast.cs.png b/assets/images/social/zengin/scripts/extenders/zparserextender/externals/cast.cs.png deleted file mode 100644 index 8611c53214..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/cast.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/cast.pl.png b/assets/images/social/zengin/scripts/extenders/zparserextender/externals/cast.pl.png deleted file mode 100644 index 2dcbee8793..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/cast.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/cast.png b/assets/images/social/zengin/scripts/extenders/zparserextender/externals/cast.png deleted file mode 100644 index 679cce7745..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/cast.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/events_vars.cs.png b/assets/images/social/zengin/scripts/extenders/zparserextender/externals/events_vars.cs.png deleted file mode 100644 index 0ec31085d0..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/events_vars.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/events_vars.pl.png b/assets/images/social/zengin/scripts/extenders/zparserextender/externals/events_vars.pl.png deleted file mode 100644 index 3706cc276b..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/events_vars.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/events_vars.png b/assets/images/social/zengin/scripts/extenders/zparserextender/externals/events_vars.png deleted file mode 100644 index f29bfeae21..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/events_vars.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/hlp.cs.png b/assets/images/social/zengin/scripts/extenders/zparserextender/externals/hlp.cs.png deleted file mode 100644 index 1e37ae3242..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/hlp.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/hlp.pl.png b/assets/images/social/zengin/scripts/extenders/zparserextender/externals/hlp.pl.png deleted file mode 100644 index 3a93603ad0..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/hlp.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/hlp.png b/assets/images/social/zengin/scripts/extenders/zparserextender/externals/hlp.png deleted file mode 100644 index b38abc6e52..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/hlp.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/log.cs.png b/assets/images/social/zengin/scripts/extenders/zparserextender/externals/log.cs.png deleted file mode 100644 index 2764ca66f7..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/log.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/log.pl.png b/assets/images/social/zengin/scripts/extenders/zparserextender/externals/log.pl.png deleted file mode 100644 index 702414bd52..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/log.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/log.png b/assets/images/social/zengin/scripts/extenders/zparserextender/externals/log.png deleted file mode 100644 index 115c8041c2..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/log.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/mdl.cs.png b/assets/images/social/zengin/scripts/extenders/zparserextender/externals/mdl.cs.png deleted file mode 100644 index 15d7bf4d43..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/mdl.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/mdl.pl.png b/assets/images/social/zengin/scripts/extenders/zparserextender/externals/mdl.pl.png deleted file mode 100644 index 06da915dd1..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/mdl.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/mdl.png b/assets/images/social/zengin/scripts/extenders/zparserextender/externals/mdl.png deleted file mode 100644 index 5122e62409..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/mdl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/menu.cs.png b/assets/images/social/zengin/scripts/extenders/zparserextender/externals/menu.cs.png deleted file mode 100644 index e899f14ab8..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/menu.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/menu.pl.png b/assets/images/social/zengin/scripts/extenders/zparserextender/externals/menu.pl.png deleted file mode 100644 index 3164cba906..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/menu.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/menu.png b/assets/images/social/zengin/scripts/extenders/zparserextender/externals/menu.png deleted file mode 100644 index 74b43d7c32..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/menu.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/mob.cs.png b/assets/images/social/zengin/scripts/extenders/zparserextender/externals/mob.cs.png deleted file mode 100644 index 7dfd57d082..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/mob.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/mob.pl.png b/assets/images/social/zengin/scripts/extenders/zparserextender/externals/mob.pl.png deleted file mode 100644 index dc216873cf..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/mob.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/mob.png b/assets/images/social/zengin/scripts/extenders/zparserextender/externals/mob.png deleted file mode 100644 index 8a435ffaa8..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/mob.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/npc.cs.png b/assets/images/social/zengin/scripts/extenders/zparserextender/externals/npc.cs.png deleted file mode 100644 index 70702fa9f3..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/npc.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/npc.pl.png b/assets/images/social/zengin/scripts/extenders/zparserextender/externals/npc.pl.png deleted file mode 100644 index 0f1987bb56..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/npc.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/npc.png b/assets/images/social/zengin/scripts/extenders/zparserextender/externals/npc.png deleted file mode 100644 index 121fbde4b7..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/npc.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/par.cs.png b/assets/images/social/zengin/scripts/extenders/zparserextender/externals/par.cs.png deleted file mode 100644 index ba40f656c8..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/par.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/par.pl.png b/assets/images/social/zengin/scripts/extenders/zparserextender/externals/par.pl.png deleted file mode 100644 index 2f8f0f002a..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/par.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/par.png b/assets/images/social/zengin/scripts/extenders/zparserextender/externals/par.png deleted file mode 100644 index 1afa14864e..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/par.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/string.cs.png b/assets/images/social/zengin/scripts/extenders/zparserextender/externals/string.cs.png deleted file mode 100644 index eb1cfd5d2a..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/string.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/string.pl.png b/assets/images/social/zengin/scripts/extenders/zparserextender/externals/string.pl.png deleted file mode 100644 index 4e5ed43a00..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/string.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/string.png b/assets/images/social/zengin/scripts/extenders/zparserextender/externals/string.png deleted file mode 100644 index 79c6aa3d5e..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/string.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/vob.cs.png b/assets/images/social/zengin/scripts/extenders/zparserextender/externals/vob.cs.png deleted file mode 100644 index d22d93df29..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/vob.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/vob.pl.png b/assets/images/social/zengin/scripts/extenders/zparserextender/externals/vob.pl.png deleted file mode 100644 index cdd79a44c0..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/vob.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/vob.png b/assets/images/social/zengin/scripts/extenders/zparserextender/externals/vob.png deleted file mode 100644 index 3c71838e33..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/vob.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/wld.cs.png b/assets/images/social/zengin/scripts/extenders/zparserextender/externals/wld.cs.png deleted file mode 100644 index 07c3365537..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/wld.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/wld.pl.png b/assets/images/social/zengin/scripts/extenders/zparserextender/externals/wld.pl.png deleted file mode 100644 index bb9d433436..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/wld.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/wld.png b/assets/images/social/zengin/scripts/extenders/zparserextender/externals/wld.png deleted file mode 100644 index 3c52876a39..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/externals/wld.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/index.cs.png b/assets/images/social/zengin/scripts/extenders/zparserextender/index.cs.png deleted file mode 100644 index d70b38b0f9..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/index.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/index.pl.png b/assets/images/social/zengin/scripts/extenders/zparserextender/index.pl.png deleted file mode 100644 index b520cb90da..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/index.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/index.png b/assets/images/social/zengin/scripts/extenders/zparserextender/index.png deleted file mode 100644 index 03741d8132..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/index.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/syntax_extensions/dialogues.cs.png b/assets/images/social/zengin/scripts/extenders/zparserextender/syntax_extensions/dialogues.cs.png deleted file mode 100644 index eb985e8ead..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/syntax_extensions/dialogues.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/syntax_extensions/dialogues.pl.png b/assets/images/social/zengin/scripts/extenders/zparserextender/syntax_extensions/dialogues.pl.png deleted file mode 100644 index 41d0059d2b..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/syntax_extensions/dialogues.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/syntax_extensions/dialogues.png b/assets/images/social/zengin/scripts/extenders/zparserextender/syntax_extensions/dialogues.png deleted file mode 100644 index d5d179f118..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/syntax_extensions/dialogues.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/syntax_extensions/events.cs.png b/assets/images/social/zengin/scripts/extenders/zparserextender/syntax_extensions/events.cs.png deleted file mode 100644 index 0ec31085d0..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/syntax_extensions/events.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/syntax_extensions/events.pl.png b/assets/images/social/zengin/scripts/extenders/zparserextender/syntax_extensions/events.pl.png deleted file mode 100644 index 3706cc276b..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/syntax_extensions/events.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/syntax_extensions/events.png b/assets/images/social/zengin/scripts/extenders/zparserextender/syntax_extensions/events.png deleted file mode 100644 index f29bfeae21..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/syntax_extensions/events.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/syntax_extensions/extern.cs.png b/assets/images/social/zengin/scripts/extenders/zparserextender/syntax_extensions/extern.cs.png deleted file mode 100644 index ee1184b6b6..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/syntax_extensions/extern.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/syntax_extensions/extern.pl.png b/assets/images/social/zengin/scripts/extenders/zparserextender/syntax_extensions/extern.pl.png deleted file mode 100644 index 0199af3070..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/syntax_extensions/extern.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/syntax_extensions/extern.png b/assets/images/social/zengin/scripts/extenders/zparserextender/syntax_extensions/extern.png deleted file mode 100644 index 27aaf9273c..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/syntax_extensions/extern.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/syntax_extensions/namespaces.cs.png b/assets/images/social/zengin/scripts/extenders/zparserextender/syntax_extensions/namespaces.cs.png deleted file mode 100644 index f7adcd1f22..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/syntax_extensions/namespaces.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/syntax_extensions/namespaces.pl.png b/assets/images/social/zengin/scripts/extenders/zparserextender/syntax_extensions/namespaces.pl.png deleted file mode 100644 index 39ae937132..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/syntax_extensions/namespaces.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/syntax_extensions/namespaces.png b/assets/images/social/zengin/scripts/extenders/zparserextender/syntax_extensions/namespaces.png deleted file mode 100644 index 8a0aa81cd7..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/syntax_extensions/namespaces.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/syntax_extensions/testelse.cs.png b/assets/images/social/zengin/scripts/extenders/zparserextender/syntax_extensions/testelse.cs.png deleted file mode 100644 index cc298852fe..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/syntax_extensions/testelse.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/syntax_extensions/testelse.pl.png b/assets/images/social/zengin/scripts/extenders/zparserextender/syntax_extensions/testelse.pl.png deleted file mode 100644 index cb55ef70c6..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/syntax_extensions/testelse.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/syntax_extensions/testelse.png b/assets/images/social/zengin/scripts/extenders/zparserextender/syntax_extensions/testelse.png deleted file mode 100644 index 33c0e764f9..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/syntax_extensions/testelse.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/syntax_extensions/while.cs.png b/assets/images/social/zengin/scripts/extenders/zparserextender/syntax_extensions/while.cs.png deleted file mode 100644 index da26f1de7b..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/syntax_extensions/while.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/syntax_extensions/while.pl.png b/assets/images/social/zengin/scripts/extenders/zparserextender/syntax_extensions/while.pl.png deleted file mode 100644 index 05753b83a9..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/syntax_extensions/while.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/extenders/zparserextender/syntax_extensions/while.png b/assets/images/social/zengin/scripts/extenders/zparserextender/syntax_extensions/while.png deleted file mode 100644 index bc0f0f94b1..0000000000 Binary files a/assets/images/social/zengin/scripts/extenders/zparserextender/syntax_extensions/while.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/externals/doc.cs.png b/assets/images/social/zengin/scripts/externals/doc.cs.png deleted file mode 100644 index ae7d266fc4..0000000000 Binary files a/assets/images/social/zengin/scripts/externals/doc.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/externals/doc.pl.png b/assets/images/social/zengin/scripts/externals/doc.pl.png deleted file mode 100644 index 9fbf87b50e..0000000000 Binary files a/assets/images/social/zengin/scripts/externals/doc.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/externals/doc.png b/assets/images/social/zengin/scripts/externals/doc.png deleted file mode 100644 index 2b1172692f..0000000000 Binary files a/assets/images/social/zengin/scripts/externals/doc.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/externals/index.cs.png b/assets/images/social/zengin/scripts/externals/index.cs.png deleted file mode 100644 index 21417b7980..0000000000 Binary files a/assets/images/social/zengin/scripts/externals/index.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/externals/index.pl.png b/assets/images/social/zengin/scripts/externals/index.pl.png deleted file mode 100644 index c09dc8acb7..0000000000 Binary files a/assets/images/social/zengin/scripts/externals/index.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/externals/index.png b/assets/images/social/zengin/scripts/externals/index.png deleted file mode 100644 index 3afbe3c5c7..0000000000 Binary files a/assets/images/social/zengin/scripts/externals/index.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/externals/log.cs.png b/assets/images/social/zengin/scripts/externals/log.cs.png deleted file mode 100644 index 2764ca66f7..0000000000 Binary files a/assets/images/social/zengin/scripts/externals/log.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/externals/log.pl.png b/assets/images/social/zengin/scripts/externals/log.pl.png deleted file mode 100644 index 702414bd52..0000000000 Binary files a/assets/images/social/zengin/scripts/externals/log.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/externals/log.png b/assets/images/social/zengin/scripts/externals/log.png deleted file mode 100644 index 115c8041c2..0000000000 Binary files a/assets/images/social/zengin/scripts/externals/log.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/externals/mdl.cs.png b/assets/images/social/zengin/scripts/externals/mdl.cs.png deleted file mode 100644 index 15d7bf4d43..0000000000 Binary files a/assets/images/social/zengin/scripts/externals/mdl.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/externals/mdl.pl.png b/assets/images/social/zengin/scripts/externals/mdl.pl.png deleted file mode 100644 index 06da915dd1..0000000000 Binary files a/assets/images/social/zengin/scripts/externals/mdl.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/externals/mdl.png b/assets/images/social/zengin/scripts/externals/mdl.png deleted file mode 100644 index 5122e62409..0000000000 Binary files a/assets/images/social/zengin/scripts/externals/mdl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/index.cs.png b/assets/images/social/zengin/scripts/index.cs.png deleted file mode 100644 index 476412732c..0000000000 Binary files a/assets/images/social/zengin/scripts/index.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/index.pl.png b/assets/images/social/zengin/scripts/index.pl.png deleted file mode 100644 index 89a4587904..0000000000 Binary files a/assets/images/social/zengin/scripts/index.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/scripts/index.png b/assets/images/social/zengin/scripts/index.png deleted file mode 100644 index 01a23659ed..0000000000 Binary files a/assets/images/social/zengin/scripts/index.png and /dev/null differ diff --git a/assets/images/social/zengin/sound/index.cs.png b/assets/images/social/zengin/sound/index.cs.png deleted file mode 100644 index b30a755d57..0000000000 Binary files a/assets/images/social/zengin/sound/index.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/sound/index.pl.png b/assets/images/social/zengin/sound/index.pl.png deleted file mode 100644 index e395ae748d..0000000000 Binary files a/assets/images/social/zengin/sound/index.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/sound/index.png b/assets/images/social/zengin/sound/index.png deleted file mode 100644 index 2f8ff7f64c..0000000000 Binary files a/assets/images/social/zengin/sound/index.png and /dev/null differ diff --git a/assets/images/social/zengin/sound/tutorials/change_sfx.cs.png b/assets/images/social/zengin/sound/tutorials/change_sfx.cs.png deleted file mode 100644 index bed8cb93eb..0000000000 Binary files a/assets/images/social/zengin/sound/tutorials/change_sfx.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/sound/tutorials/change_sfx.pl.png b/assets/images/social/zengin/sound/tutorials/change_sfx.pl.png deleted file mode 100644 index b348721e01..0000000000 Binary files a/assets/images/social/zengin/sound/tutorials/change_sfx.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/sound/tutorials/change_sfx.png b/assets/images/social/zengin/sound/tutorials/change_sfx.png deleted file mode 100644 index 797b9a3a42..0000000000 Binary files a/assets/images/social/zengin/sound/tutorials/change_sfx.png and /dev/null differ diff --git a/assets/images/social/zengin/textures.cs.png b/assets/images/social/zengin/textures.cs.png deleted file mode 100644 index 4c08b40a40..0000000000 Binary files a/assets/images/social/zengin/textures.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/textures.pl.png b/assets/images/social/zengin/textures.pl.png deleted file mode 100644 index 3544123b29..0000000000 Binary files a/assets/images/social/zengin/textures.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/textures.png b/assets/images/social/zengin/textures.png deleted file mode 100644 index 8920b47db3..0000000000 Binary files a/assets/images/social/zengin/textures.png and /dev/null differ diff --git a/assets/images/social/zengin/tools/daedalus_tools/daedalus_language_server.cs.png b/assets/images/social/zengin/tools/daedalus_tools/daedalus_language_server.cs.png deleted file mode 100644 index 31de2f3484..0000000000 Binary files a/assets/images/social/zengin/tools/daedalus_tools/daedalus_language_server.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/tools/daedalus_tools/daedalus_language_server.pl.png b/assets/images/social/zengin/tools/daedalus_tools/daedalus_language_server.pl.png deleted file mode 100644 index eaff1137d2..0000000000 Binary files a/assets/images/social/zengin/tools/daedalus_tools/daedalus_language_server.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/tools/daedalus_tools/daedalus_language_server.png b/assets/images/social/zengin/tools/daedalus_tools/daedalus_language_server.png deleted file mode 100644 index be50f86ca5..0000000000 Binary files a/assets/images/social/zengin/tools/daedalus_tools/daedalus_language_server.png and /dev/null differ diff --git a/assets/images/social/zengin/tools/gothic_sourcer.cs.png b/assets/images/social/zengin/tools/gothic_sourcer.cs.png deleted file mode 100644 index ee825957e5..0000000000 Binary files a/assets/images/social/zengin/tools/gothic_sourcer.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/tools/gothic_sourcer.pl.png b/assets/images/social/zengin/tools/gothic_sourcer.pl.png deleted file mode 100644 index 3b63710f1b..0000000000 Binary files a/assets/images/social/zengin/tools/gothic_sourcer.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/tools/gothic_sourcer.png b/assets/images/social/zengin/tools/gothic_sourcer.png deleted file mode 100644 index 808f0c43d9..0000000000 Binary files a/assets/images/social/zengin/tools/gothic_sourcer.png and /dev/null differ diff --git a/assets/images/social/zengin/tools/index.cs.png b/assets/images/social/zengin/tools/index.cs.png deleted file mode 100644 index ddb4b55938..0000000000 Binary files a/assets/images/social/zengin/tools/index.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/tools/index.pl.png b/assets/images/social/zengin/tools/index.pl.png deleted file mode 100644 index 3cd5337ff6..0000000000 Binary files a/assets/images/social/zengin/tools/index.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/tools/index.png b/assets/images/social/zengin/tools/index.png deleted file mode 100644 index 2d39310ba5..0000000000 Binary files a/assets/images/social/zengin/tools/index.png and /dev/null differ diff --git a/assets/images/social/zengin/tools/vdfs_tools/gothic_vdfs.cs.png b/assets/images/social/zengin/tools/vdfs_tools/gothic_vdfs.cs.png deleted file mode 100644 index 7c67c358a6..0000000000 Binary files a/assets/images/social/zengin/tools/vdfs_tools/gothic_vdfs.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/tools/vdfs_tools/gothic_vdfs.pl.png b/assets/images/social/zengin/tools/vdfs_tools/gothic_vdfs.pl.png deleted file mode 100644 index 59f17c065a..0000000000 Binary files a/assets/images/social/zengin/tools/vdfs_tools/gothic_vdfs.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/tools/vdfs_tools/gothic_vdfs.png b/assets/images/social/zengin/tools/vdfs_tools/gothic_vdfs.png deleted file mode 100644 index 810cfc1c5b..0000000000 Binary files a/assets/images/social/zengin/tools/vdfs_tools/gothic_vdfs.png and /dev/null differ diff --git a/assets/images/social/zengin/tools/vdfs_tools/vdfs_tool.cs.png b/assets/images/social/zengin/tools/vdfs_tools/vdfs_tool.cs.png deleted file mode 100644 index a60763e6d3..0000000000 Binary files a/assets/images/social/zengin/tools/vdfs_tools/vdfs_tool.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/tools/vdfs_tools/vdfs_tool.pl.png b/assets/images/social/zengin/tools/vdfs_tools/vdfs_tool.pl.png deleted file mode 100644 index b05dd8aaf5..0000000000 Binary files a/assets/images/social/zengin/tools/vdfs_tools/vdfs_tool.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/tools/vdfs_tools/vdfs_tool.png b/assets/images/social/zengin/tools/vdfs_tools/vdfs_tool.png deleted file mode 100644 index 4d271c9b48..0000000000 Binary files a/assets/images/social/zengin/tools/vdfs_tools/vdfs_tool.png and /dev/null differ diff --git a/assets/images/social/zengin/tools/zSpy.cs.png b/assets/images/social/zengin/tools/zSpy.cs.png deleted file mode 100644 index 40c6b9097e..0000000000 Binary files a/assets/images/social/zengin/tools/zSpy.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/tools/zSpy.pl.png b/assets/images/social/zengin/tools/zSpy.pl.png deleted file mode 100644 index 9ee40528c4..0000000000 Binary files a/assets/images/social/zengin/tools/zSpy.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/tools/zSpy.png b/assets/images/social/zengin/tools/zSpy.png deleted file mode 100644 index 6bdba531c8..0000000000 Binary files a/assets/images/social/zengin/tools/zSpy.png and /dev/null differ diff --git a/assets/images/social/zengin/union/index.cs.png b/assets/images/social/zengin/union/index.cs.png deleted file mode 100644 index f9b7747a9b..0000000000 Binary files a/assets/images/social/zengin/union/index.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/union/index.pl.png b/assets/images/social/zengin/union/index.pl.png deleted file mode 100644 index 1a5969bae8..0000000000 Binary files a/assets/images/social/zengin/union/index.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/union/index.png b/assets/images/social/zengin/union/index.png deleted file mode 100644 index c772fbca20..0000000000 Binary files a/assets/images/social/zengin/union/index.png and /dev/null differ diff --git a/assets/images/social/zengin/union/plugins/zbassmusic.cs.png b/assets/images/social/zengin/union/plugins/zbassmusic.cs.png deleted file mode 100644 index 4e16b36a8c..0000000000 Binary files a/assets/images/social/zengin/union/plugins/zbassmusic.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/union/plugins/zbassmusic.pl.png b/assets/images/social/zengin/union/plugins/zbassmusic.pl.png deleted file mode 100644 index 0c572bdfc5..0000000000 Binary files a/assets/images/social/zengin/union/plugins/zbassmusic.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/union/plugins/zbassmusic.png b/assets/images/social/zengin/union/plugins/zbassmusic.png deleted file mode 100644 index 91f3bd2492..0000000000 Binary files a/assets/images/social/zengin/union/plugins/zbassmusic.png and /dev/null differ diff --git a/assets/images/social/zengin/union/plugins/zgamepad/controls.cs.png b/assets/images/social/zengin/union/plugins/zgamepad/controls.cs.png deleted file mode 100644 index c59f06d2af..0000000000 Binary files a/assets/images/social/zengin/union/plugins/zgamepad/controls.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/union/plugins/zgamepad/controls.pl.png b/assets/images/social/zengin/union/plugins/zgamepad/controls.pl.png deleted file mode 100644 index 3f28216edb..0000000000 Binary files a/assets/images/social/zengin/union/plugins/zgamepad/controls.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/union/plugins/zgamepad/controls.png b/assets/images/social/zengin/union/plugins/zgamepad/controls.png deleted file mode 100644 index 7ccb7144cb..0000000000 Binary files a/assets/images/social/zengin/union/plugins/zgamepad/controls.png and /dev/null differ diff --git a/assets/images/social/zengin/union/plugins/zgamepad/index.cs.png b/assets/images/social/zengin/union/plugins/zgamepad/index.cs.png deleted file mode 100644 index de754fdddb..0000000000 Binary files a/assets/images/social/zengin/union/plugins/zgamepad/index.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/union/plugins/zgamepad/index.pl.png b/assets/images/social/zengin/union/plugins/zgamepad/index.pl.png deleted file mode 100644 index e4549e3476..0000000000 Binary files a/assets/images/social/zengin/union/plugins/zgamepad/index.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/union/plugins/zgamepad/index.png b/assets/images/social/zengin/union/plugins/zgamepad/index.png deleted file mode 100644 index f3ebc3e309..0000000000 Binary files a/assets/images/social/zengin/union/plugins/zgamepad/index.png and /dev/null differ diff --git a/assets/images/social/zengin/union/plugins/zgamepad/keys_engine_absolute.cs.png b/assets/images/social/zengin/union/plugins/zgamepad/keys_engine_absolute.cs.png deleted file mode 100644 index 9bdbf846cf..0000000000 Binary files a/assets/images/social/zengin/union/plugins/zgamepad/keys_engine_absolute.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/union/plugins/zgamepad/keys_engine_absolute.pl.png b/assets/images/social/zengin/union/plugins/zgamepad/keys_engine_absolute.pl.png deleted file mode 100644 index f238c7d340..0000000000 Binary files a/assets/images/social/zengin/union/plugins/zgamepad/keys_engine_absolute.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/union/plugins/zgamepad/keys_engine_absolute.png b/assets/images/social/zengin/union/plugins/zgamepad/keys_engine_absolute.png deleted file mode 100644 index 74ffebe6e2..0000000000 Binary files a/assets/images/social/zengin/union/plugins/zgamepad/keys_engine_absolute.png and /dev/null differ diff --git a/assets/images/social/zengin/union/plugins/zgamepad/keys_gamepad.cs.png b/assets/images/social/zengin/union/plugins/zgamepad/keys_gamepad.cs.png deleted file mode 100644 index 485b2c8ad1..0000000000 Binary files a/assets/images/social/zengin/union/plugins/zgamepad/keys_gamepad.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/union/plugins/zgamepad/keys_gamepad.pl.png b/assets/images/social/zengin/union/plugins/zgamepad/keys_gamepad.pl.png deleted file mode 100644 index 21944b01bd..0000000000 Binary files a/assets/images/social/zengin/union/plugins/zgamepad/keys_gamepad.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/union/plugins/zgamepad/keys_gamepad.png b/assets/images/social/zengin/union/plugins/zgamepad/keys_gamepad.png deleted file mode 100644 index 6ca3e02723..0000000000 Binary files a/assets/images/social/zengin/union/plugins/zgamepad/keys_gamepad.png and /dev/null differ diff --git a/assets/images/social/zengin/union/plugins/zgamepad/logical_functions.cs.png b/assets/images/social/zengin/union/plugins/zgamepad/logical_functions.cs.png deleted file mode 100644 index 2170207add..0000000000 Binary files a/assets/images/social/zengin/union/plugins/zgamepad/logical_functions.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/union/plugins/zgamepad/logical_functions.pl.png b/assets/images/social/zengin/union/plugins/zgamepad/logical_functions.pl.png deleted file mode 100644 index 530fd3cd4e..0000000000 Binary files a/assets/images/social/zengin/union/plugins/zgamepad/logical_functions.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/union/plugins/zgamepad/logical_functions.png b/assets/images/social/zengin/union/plugins/zgamepad/logical_functions.png deleted file mode 100644 index c505941bfd..0000000000 Binary files a/assets/images/social/zengin/union/plugins/zgamepad/logical_functions.png and /dev/null differ diff --git a/assets/images/social/zengin/union/sdk/events.cs.png b/assets/images/social/zengin/union/sdk/events.cs.png deleted file mode 100644 index d29b261e39..0000000000 Binary files a/assets/images/social/zengin/union/sdk/events.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/union/sdk/events.pl.png b/assets/images/social/zengin/union/sdk/events.pl.png deleted file mode 100644 index e58afed5ec..0000000000 Binary files a/assets/images/social/zengin/union/sdk/events.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/union/sdk/events.png b/assets/images/social/zengin/union/sdk/events.png deleted file mode 100644 index 42c1ae2852..0000000000 Binary files a/assets/images/social/zengin/union/sdk/events.png and /dev/null differ diff --git a/assets/images/social/zengin/union/sdk/externals.cs.png b/assets/images/social/zengin/union/sdk/externals.cs.png deleted file mode 100644 index 21417b7980..0000000000 Binary files a/assets/images/social/zengin/union/sdk/externals.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/union/sdk/externals.pl.png b/assets/images/social/zengin/union/sdk/externals.pl.png deleted file mode 100644 index c09dc8acb7..0000000000 Binary files a/assets/images/social/zengin/union/sdk/externals.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/union/sdk/externals.png b/assets/images/social/zengin/union/sdk/externals.png deleted file mode 100644 index 3afbe3c5c7..0000000000 Binary files a/assets/images/social/zengin/union/sdk/externals.png and /dev/null differ diff --git a/assets/images/social/zengin/union/sdk/getting_started.cs.png b/assets/images/social/zengin/union/sdk/getting_started.cs.png deleted file mode 100644 index e056899377..0000000000 Binary files a/assets/images/social/zengin/union/sdk/getting_started.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/union/sdk/getting_started.pl.png b/assets/images/social/zengin/union/sdk/getting_started.pl.png deleted file mode 100644 index e1b821647f..0000000000 Binary files a/assets/images/social/zengin/union/sdk/getting_started.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/union/sdk/getting_started.png b/assets/images/social/zengin/union/sdk/getting_started.png deleted file mode 100644 index 2fc83e4174..0000000000 Binary files a/assets/images/social/zengin/union/sdk/getting_started.png and /dev/null differ diff --git a/assets/images/social/zengin/union/sdk/hooks.cs.png b/assets/images/social/zengin/union/sdk/hooks.cs.png deleted file mode 100644 index a5609e889f..0000000000 Binary files a/assets/images/social/zengin/union/sdk/hooks.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/union/sdk/hooks.pl.png b/assets/images/social/zengin/union/sdk/hooks.pl.png deleted file mode 100644 index 6c43558d39..0000000000 Binary files a/assets/images/social/zengin/union/sdk/hooks.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/union/sdk/hooks.png b/assets/images/social/zengin/union/sdk/hooks.png deleted file mode 100644 index 101510ac3f..0000000000 Binary files a/assets/images/social/zengin/union/sdk/hooks.png and /dev/null differ diff --git a/assets/images/social/zengin/union/sdk/index.cs.png b/assets/images/social/zengin/union/sdk/index.cs.png deleted file mode 100644 index 967b9f1ff1..0000000000 Binary files a/assets/images/social/zengin/union/sdk/index.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/union/sdk/index.pl.png b/assets/images/social/zengin/union/sdk/index.pl.png deleted file mode 100644 index ae11bb4b7b..0000000000 Binary files a/assets/images/social/zengin/union/sdk/index.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/union/sdk/index.png b/assets/images/social/zengin/union/sdk/index.png deleted file mode 100644 index 27359648a8..0000000000 Binary files a/assets/images/social/zengin/union/sdk/index.png and /dev/null differ diff --git a/assets/images/social/zengin/video.cs.png b/assets/images/social/zengin/video.cs.png deleted file mode 100644 index dd24496428..0000000000 Binary files a/assets/images/social/zengin/video.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/video.pl.png b/assets/images/social/zengin/video.pl.png deleted file mode 100644 index 054b8ccd93..0000000000 Binary files a/assets/images/social/zengin/video.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/video.png b/assets/images/social/zengin/video.png deleted file mode 100644 index f1e4ae32e8..0000000000 Binary files a/assets/images/social/zengin/video.png and /dev/null differ diff --git a/assets/images/social/zengin/worlds/Classes/zCVob.cs.png b/assets/images/social/zengin/worlds/Classes/zCVob.cs.png deleted file mode 100644 index a2fa7690e7..0000000000 Binary files a/assets/images/social/zengin/worlds/Classes/zCVob.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/worlds/Classes/zCVob.pl.png b/assets/images/social/zengin/worlds/Classes/zCVob.pl.png deleted file mode 100644 index 54961382e2..0000000000 Binary files a/assets/images/social/zengin/worlds/Classes/zCVob.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/worlds/Classes/zCVob.png b/assets/images/social/zengin/worlds/Classes/zCVob.png deleted file mode 100644 index a2c322fb60..0000000000 Binary files a/assets/images/social/zengin/worlds/Classes/zCVob.png and /dev/null differ diff --git a/assets/images/social/zengin/worlds/index.cs.png b/assets/images/social/zengin/worlds/index.cs.png deleted file mode 100644 index a8c48b4981..0000000000 Binary files a/assets/images/social/zengin/worlds/index.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/worlds/index.pl.png b/assets/images/social/zengin/worlds/index.pl.png deleted file mode 100644 index 3669c594e4..0000000000 Binary files a/assets/images/social/zengin/worlds/index.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/worlds/index.png b/assets/images/social/zengin/worlds/index.png deleted file mode 100644 index 045b6f9252..0000000000 Binary files a/assets/images/social/zengin/worlds/index.png and /dev/null differ diff --git a/assets/images/social/zengin/worlds/spacer.cs.png b/assets/images/social/zengin/worlds/spacer.cs.png deleted file mode 100644 index 5f97abee54..0000000000 Binary files a/assets/images/social/zengin/worlds/spacer.cs.png and /dev/null differ diff --git a/assets/images/social/zengin/worlds/spacer.pl.png b/assets/images/social/zengin/worlds/spacer.pl.png deleted file mode 100644 index e3fde8e9c5..0000000000 Binary files a/assets/images/social/zengin/worlds/spacer.pl.png and /dev/null differ diff --git a/assets/images/social/zengin/worlds/spacer.png b/assets/images/social/zengin/worlds/spacer.png deleted file mode 100644 index 01b2aca65a..0000000000 Binary files a/assets/images/social/zengin/worlds/spacer.png and /dev/null differ diff --git a/assets/images/zCVob_G1.png b/assets/images/zCVob_G1.png deleted file mode 100644 index 5485e78615..0000000000 Binary files a/assets/images/zCVob_G1.png and /dev/null differ diff --git a/assets/images/zCVob_G2A.png b/assets/images/zCVob_G2A.png deleted file mode 100644 index b7a7c805a4..0000000000 Binary files a/assets/images/zCVob_G2A.png and /dev/null differ diff --git a/assets/images/zsplitdialogs.png b/assets/images/zsplitdialogs.png new file mode 100644 index 0000000000..78b11109e3 Binary files /dev/null and b/assets/images/zsplitdialogs.png differ diff --git a/assets/javascripts/bundle.081f42fc.min.js b/assets/javascripts/bundle.081f42fc.min.js new file mode 100644 index 0000000000..32734cd370 --- /dev/null +++ b/assets/javascripts/bundle.081f42fc.min.js @@ -0,0 +1,29 @@ +"use strict";(()=>{var Fi=Object.create;var gr=Object.defineProperty;var ji=Object.getOwnPropertyDescriptor;var Wi=Object.getOwnPropertyNames,Dt=Object.getOwnPropertySymbols,Ui=Object.getPrototypeOf,xr=Object.prototype.hasOwnProperty,no=Object.prototype.propertyIsEnumerable;var oo=(e,t,r)=>t in e?gr(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,R=(e,t)=>{for(var r in t||(t={}))xr.call(t,r)&&oo(e,r,t[r]);if(Dt)for(var r of Dt(t))no.call(t,r)&&oo(e,r,t[r]);return e};var io=(e,t)=>{var r={};for(var o in e)xr.call(e,o)&&t.indexOf(o)<0&&(r[o]=e[o]);if(e!=null&&Dt)for(var o of Dt(e))t.indexOf(o)<0&&no.call(e,o)&&(r[o]=e[o]);return r};var yr=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var Di=(e,t,r,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of Wi(t))!xr.call(e,n)&&n!==r&&gr(e,n,{get:()=>t[n],enumerable:!(o=ji(t,n))||o.enumerable});return e};var Vt=(e,t,r)=>(r=e!=null?Fi(Ui(e)):{},Di(t||!e||!e.__esModule?gr(r,"default",{value:e,enumerable:!0}):r,e));var ao=(e,t,r)=>new Promise((o,n)=>{var i=p=>{try{s(r.next(p))}catch(c){n(c)}},a=p=>{try{s(r.throw(p))}catch(c){n(c)}},s=p=>p.done?o(p.value):Promise.resolve(p.value).then(i,a);s((r=r.apply(e,t)).next())});var co=yr((Er,so)=>{(function(e,t){typeof Er=="object"&&typeof so!="undefined"?t():typeof define=="function"&&define.amd?define(t):t()})(Er,function(){"use strict";function e(r){var o=!0,n=!1,i=null,a={text:!0,search:!0,url:!0,tel:!0,email:!0,password:!0,number:!0,date:!0,month:!0,week:!0,time:!0,datetime:!0,"datetime-local":!0};function s(H){return!!(H&&H!==document&&H.nodeName!=="HTML"&&H.nodeName!=="BODY"&&"classList"in H&&"contains"in H.classList)}function p(H){var mt=H.type,ze=H.tagName;return!!(ze==="INPUT"&&a[mt]&&!H.readOnly||ze==="TEXTAREA"&&!H.readOnly||H.isContentEditable)}function c(H){H.classList.contains("focus-visible")||(H.classList.add("focus-visible"),H.setAttribute("data-focus-visible-added",""))}function l(H){H.hasAttribute("data-focus-visible-added")&&(H.classList.remove("focus-visible"),H.removeAttribute("data-focus-visible-added"))}function f(H){H.metaKey||H.altKey||H.ctrlKey||(s(r.activeElement)&&c(r.activeElement),o=!0)}function u(H){o=!1}function h(H){s(H.target)&&(o||p(H.target))&&c(H.target)}function w(H){s(H.target)&&(H.target.classList.contains("focus-visible")||H.target.hasAttribute("data-focus-visible-added"))&&(n=!0,window.clearTimeout(i),i=window.setTimeout(function(){n=!1},100),l(H.target))}function A(H){document.visibilityState==="hidden"&&(n&&(o=!0),te())}function te(){document.addEventListener("mousemove",J),document.addEventListener("mousedown",J),document.addEventListener("mouseup",J),document.addEventListener("pointermove",J),document.addEventListener("pointerdown",J),document.addEventListener("pointerup",J),document.addEventListener("touchmove",J),document.addEventListener("touchstart",J),document.addEventListener("touchend",J)}function ie(){document.removeEventListener("mousemove",J),document.removeEventListener("mousedown",J),document.removeEventListener("mouseup",J),document.removeEventListener("pointermove",J),document.removeEventListener("pointerdown",J),document.removeEventListener("pointerup",J),document.removeEventListener("touchmove",J),document.removeEventListener("touchstart",J),document.removeEventListener("touchend",J)}function J(H){H.target.nodeName&&H.target.nodeName.toLowerCase()==="html"||(o=!1,ie())}document.addEventListener("keydown",f,!0),document.addEventListener("mousedown",u,!0),document.addEventListener("pointerdown",u,!0),document.addEventListener("touchstart",u,!0),document.addEventListener("visibilitychange",A,!0),te(),r.addEventListener("focus",h,!0),r.addEventListener("blur",w,!0),r.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&r.host?r.host.setAttribute("data-js-focus-visible",""):r.nodeType===Node.DOCUMENT_NODE&&(document.documentElement.classList.add("js-focus-visible"),document.documentElement.setAttribute("data-js-focus-visible",""))}if(typeof window!="undefined"&&typeof document!="undefined"){window.applyFocusVisiblePolyfill=e;var t;try{t=new CustomEvent("focus-visible-polyfill-ready")}catch(r){t=document.createEvent("CustomEvent"),t.initCustomEvent("focus-visible-polyfill-ready",!1,!1,{})}window.dispatchEvent(t)}typeof document!="undefined"&&e(document)})});var Yr=yr((Rt,Kr)=>{/*! + * clipboard.js v2.0.11 + * https://clipboardjs.com/ + * + * Licensed MIT © Zeno Rocha + */(function(t,r){typeof Rt=="object"&&typeof Kr=="object"?Kr.exports=r():typeof define=="function"&&define.amd?define([],r):typeof Rt=="object"?Rt.ClipboardJS=r():t.ClipboardJS=r()})(Rt,function(){return function(){var e={686:function(o,n,i){"use strict";i.d(n,{default:function(){return Ii}});var a=i(279),s=i.n(a),p=i(370),c=i.n(p),l=i(817),f=i.n(l);function u(V){try{return document.execCommand(V)}catch(_){return!1}}var h=function(_){var O=f()(_);return u("cut"),O},w=h;function A(V){var _=document.documentElement.getAttribute("dir")==="rtl",O=document.createElement("textarea");O.style.fontSize="12pt",O.style.border="0",O.style.padding="0",O.style.margin="0",O.style.position="absolute",O.style[_?"right":"left"]="-9999px";var j=window.pageYOffset||document.documentElement.scrollTop;return O.style.top="".concat(j,"px"),O.setAttribute("readonly",""),O.value=V,O}var te=function(_,O){var j=A(_);O.container.appendChild(j);var D=f()(j);return u("copy"),j.remove(),D},ie=function(_){var O=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body},j="";return typeof _=="string"?j=te(_,O):_ instanceof HTMLInputElement&&!["text","search","url","tel","password"].includes(_==null?void 0:_.type)?j=te(_.value,O):(j=f()(_),u("copy")),j},J=ie;function H(V){"@babel/helpers - typeof";return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?H=function(O){return typeof O}:H=function(O){return O&&typeof Symbol=="function"&&O.constructor===Symbol&&O!==Symbol.prototype?"symbol":typeof O},H(V)}var mt=function(){var _=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},O=_.action,j=O===void 0?"copy":O,D=_.container,Y=_.target,ke=_.text;if(j!=="copy"&&j!=="cut")throw new Error('Invalid "action" value, use either "copy" or "cut"');if(Y!==void 0)if(Y&&H(Y)==="object"&&Y.nodeType===1){if(j==="copy"&&Y.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if(j==="cut"&&(Y.hasAttribute("readonly")||Y.hasAttribute("disabled")))throw new Error(`Invalid "target" attribute. You can't cut text from elements with "readonly" or "disabled" attributes`)}else throw new Error('Invalid "target" value, use a valid Element');if(ke)return J(ke,{container:D});if(Y)return j==="cut"?w(Y):J(Y,{container:D})},ze=mt;function Ie(V){"@babel/helpers - typeof";return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?Ie=function(O){return typeof O}:Ie=function(O){return O&&typeof Symbol=="function"&&O.constructor===Symbol&&O!==Symbol.prototype?"symbol":typeof O},Ie(V)}function _i(V,_){if(!(V instanceof _))throw new TypeError("Cannot call a class as a function")}function ro(V,_){for(var O=0;O<_.length;O++){var j=_[O];j.enumerable=j.enumerable||!1,j.configurable=!0,"value"in j&&(j.writable=!0),Object.defineProperty(V,j.key,j)}}function Ai(V,_,O){return _&&ro(V.prototype,_),O&&ro(V,O),V}function Ci(V,_){if(typeof _!="function"&&_!==null)throw new TypeError("Super expression must either be null or a function");V.prototype=Object.create(_&&_.prototype,{constructor:{value:V,writable:!0,configurable:!0}}),_&&br(V,_)}function br(V,_){return br=Object.setPrototypeOf||function(j,D){return j.__proto__=D,j},br(V,_)}function Hi(V){var _=Pi();return function(){var j=Wt(V),D;if(_){var Y=Wt(this).constructor;D=Reflect.construct(j,arguments,Y)}else D=j.apply(this,arguments);return ki(this,D)}}function ki(V,_){return _&&(Ie(_)==="object"||typeof _=="function")?_:$i(V)}function $i(V){if(V===void 0)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return V}function Pi(){if(typeof Reflect=="undefined"||!Reflect.construct||Reflect.construct.sham)return!1;if(typeof Proxy=="function")return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],function(){})),!0}catch(V){return!1}}function Wt(V){return Wt=Object.setPrototypeOf?Object.getPrototypeOf:function(O){return O.__proto__||Object.getPrototypeOf(O)},Wt(V)}function vr(V,_){var O="data-clipboard-".concat(V);if(_.hasAttribute(O))return _.getAttribute(O)}var Ri=function(V){Ci(O,V);var _=Hi(O);function O(j,D){var Y;return _i(this,O),Y=_.call(this),Y.resolveOptions(D),Y.listenClick(j),Y}return Ai(O,[{key:"resolveOptions",value:function(){var D=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{};this.action=typeof D.action=="function"?D.action:this.defaultAction,this.target=typeof D.target=="function"?D.target:this.defaultTarget,this.text=typeof D.text=="function"?D.text:this.defaultText,this.container=Ie(D.container)==="object"?D.container:document.body}},{key:"listenClick",value:function(D){var Y=this;this.listener=c()(D,"click",function(ke){return Y.onClick(ke)})}},{key:"onClick",value:function(D){var Y=D.delegateTarget||D.currentTarget,ke=this.action(Y)||"copy",Ut=ze({action:ke,container:this.container,target:this.target(Y),text:this.text(Y)});this.emit(Ut?"success":"error",{action:ke,text:Ut,trigger:Y,clearSelection:function(){Y&&Y.focus(),window.getSelection().removeAllRanges()}})}},{key:"defaultAction",value:function(D){return vr("action",D)}},{key:"defaultTarget",value:function(D){var Y=vr("target",D);if(Y)return document.querySelector(Y)}},{key:"defaultText",value:function(D){return vr("text",D)}},{key:"destroy",value:function(){this.listener.destroy()}}],[{key:"copy",value:function(D){var Y=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body};return J(D,Y)}},{key:"cut",value:function(D){return w(D)}},{key:"isSupported",value:function(){var D=arguments.length>0&&arguments[0]!==void 0?arguments[0]:["copy","cut"],Y=typeof D=="string"?[D]:D,ke=!!document.queryCommandSupported;return Y.forEach(function(Ut){ke=ke&&!!document.queryCommandSupported(Ut)}),ke}}]),O}(s()),Ii=Ri},828:function(o){var n=9;if(typeof Element!="undefined"&&!Element.prototype.matches){var i=Element.prototype;i.matches=i.matchesSelector||i.mozMatchesSelector||i.msMatchesSelector||i.oMatchesSelector||i.webkitMatchesSelector}function a(s,p){for(;s&&s.nodeType!==n;){if(typeof s.matches=="function"&&s.matches(p))return s;s=s.parentNode}}o.exports=a},438:function(o,n,i){var a=i(828);function s(l,f,u,h,w){var A=c.apply(this,arguments);return l.addEventListener(u,A,w),{destroy:function(){l.removeEventListener(u,A,w)}}}function p(l,f,u,h,w){return typeof l.addEventListener=="function"?s.apply(null,arguments):typeof u=="function"?s.bind(null,document).apply(null,arguments):(typeof l=="string"&&(l=document.querySelectorAll(l)),Array.prototype.map.call(l,function(A){return s(A,f,u,h,w)}))}function c(l,f,u,h){return function(w){w.delegateTarget=a(w.target,f),w.delegateTarget&&h.call(l,w)}}o.exports=p},879:function(o,n){n.node=function(i){return i!==void 0&&i instanceof HTMLElement&&i.nodeType===1},n.nodeList=function(i){var a=Object.prototype.toString.call(i);return i!==void 0&&(a==="[object NodeList]"||a==="[object HTMLCollection]")&&"length"in i&&(i.length===0||n.node(i[0]))},n.string=function(i){return typeof i=="string"||i instanceof String},n.fn=function(i){var a=Object.prototype.toString.call(i);return a==="[object Function]"}},370:function(o,n,i){var a=i(879),s=i(438);function p(u,h,w){if(!u&&!h&&!w)throw new Error("Missing required arguments");if(!a.string(h))throw new TypeError("Second argument must be a String");if(!a.fn(w))throw new TypeError("Third argument must be a Function");if(a.node(u))return c(u,h,w);if(a.nodeList(u))return l(u,h,w);if(a.string(u))return f(u,h,w);throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList")}function c(u,h,w){return u.addEventListener(h,w),{destroy:function(){u.removeEventListener(h,w)}}}function l(u,h,w){return Array.prototype.forEach.call(u,function(A){A.addEventListener(h,w)}),{destroy:function(){Array.prototype.forEach.call(u,function(A){A.removeEventListener(h,w)})}}}function f(u,h,w){return s(document.body,u,h,w)}o.exports=p},817:function(o){function n(i){var a;if(i.nodeName==="SELECT")i.focus(),a=i.value;else if(i.nodeName==="INPUT"||i.nodeName==="TEXTAREA"){var s=i.hasAttribute("readonly");s||i.setAttribute("readonly",""),i.select(),i.setSelectionRange(0,i.value.length),s||i.removeAttribute("readonly"),a=i.value}else{i.hasAttribute("contenteditable")&&i.focus();var p=window.getSelection(),c=document.createRange();c.selectNodeContents(i),p.removeAllRanges(),p.addRange(c),a=p.toString()}return a}o.exports=n},279:function(o){function n(){}n.prototype={on:function(i,a,s){var p=this.e||(this.e={});return(p[i]||(p[i]=[])).push({fn:a,ctx:s}),this},once:function(i,a,s){var p=this;function c(){p.off(i,c),a.apply(s,arguments)}return c._=a,this.on(i,c,s)},emit:function(i){var a=[].slice.call(arguments,1),s=((this.e||(this.e={}))[i]||[]).slice(),p=0,c=s.length;for(p;p{"use strict";/*! + * escape-html + * Copyright(c) 2012-2013 TJ Holowaychuk + * Copyright(c) 2015 Andreas Lubbe + * Copyright(c) 2015 Tiancheng "Timothy" Gu + * MIT Licensed + */var ts=/["'&<>]/;ei.exports=rs;function rs(e){var t=""+e,r=ts.exec(t);if(!r)return t;var o,n="",i=0,a=0;for(i=r.index;i0&&i[i.length-1])&&(c[0]===6||c[0]===2)){r=0;continue}if(c[0]===3&&(!i||c[1]>i[0]&&c[1]=e.length&&(e=void 0),{value:e&&e[o++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")}function N(e,t){var r=typeof Symbol=="function"&&e[Symbol.iterator];if(!r)return e;var o=r.call(e),n,i=[],a;try{for(;(t===void 0||t-- >0)&&!(n=o.next()).done;)i.push(n.value)}catch(s){a={error:s}}finally{try{n&&!n.done&&(r=o.return)&&r.call(o)}finally{if(a)throw a.error}}return i}function q(e,t,r){if(r||arguments.length===2)for(var o=0,n=t.length,i;o1||s(u,h)})})}function s(u,h){try{p(o[u](h))}catch(w){f(i[0][3],w)}}function p(u){u.value instanceof nt?Promise.resolve(u.value.v).then(c,l):f(i[0][2],u)}function c(u){s("next",u)}function l(u){s("throw",u)}function f(u,h){u(h),i.shift(),i.length&&s(i[0][0],i[0][1])}}function mo(e){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var t=e[Symbol.asyncIterator],r;return t?t.call(e):(e=typeof de=="function"?de(e):e[Symbol.iterator](),r={},o("next"),o("throw"),o("return"),r[Symbol.asyncIterator]=function(){return this},r);function o(i){r[i]=e[i]&&function(a){return new Promise(function(s,p){a=e[i](a),n(s,p,a.done,a.value)})}}function n(i,a,s,p){Promise.resolve(p).then(function(c){i({value:c,done:s})},a)}}function k(e){return typeof e=="function"}function ft(e){var t=function(o){Error.call(o),o.stack=new Error().stack},r=e(t);return r.prototype=Object.create(Error.prototype),r.prototype.constructor=r,r}var zt=ft(function(e){return function(r){e(this),this.message=r?r.length+` errors occurred during unsubscription: +`+r.map(function(o,n){return n+1+") "+o.toString()}).join(` + `):"",this.name="UnsubscriptionError",this.errors=r}});function qe(e,t){if(e){var r=e.indexOf(t);0<=r&&e.splice(r,1)}}var Fe=function(){function e(t){this.initialTeardown=t,this.closed=!1,this._parentage=null,this._finalizers=null}return e.prototype.unsubscribe=function(){var t,r,o,n,i;if(!this.closed){this.closed=!0;var a=this._parentage;if(a)if(this._parentage=null,Array.isArray(a))try{for(var s=de(a),p=s.next();!p.done;p=s.next()){var c=p.value;c.remove(this)}}catch(A){t={error:A}}finally{try{p&&!p.done&&(r=s.return)&&r.call(s)}finally{if(t)throw t.error}}else a.remove(this);var l=this.initialTeardown;if(k(l))try{l()}catch(A){i=A instanceof zt?A.errors:[A]}var f=this._finalizers;if(f){this._finalizers=null;try{for(var u=de(f),h=u.next();!h.done;h=u.next()){var w=h.value;try{fo(w)}catch(A){i=i!=null?i:[],A instanceof zt?i=q(q([],N(i)),N(A.errors)):i.push(A)}}}catch(A){o={error:A}}finally{try{h&&!h.done&&(n=u.return)&&n.call(u)}finally{if(o)throw o.error}}}if(i)throw new zt(i)}},e.prototype.add=function(t){var r;if(t&&t!==this)if(this.closed)fo(t);else{if(t instanceof e){if(t.closed||t._hasParent(this))return;t._addParent(this)}(this._finalizers=(r=this._finalizers)!==null&&r!==void 0?r:[]).push(t)}},e.prototype._hasParent=function(t){var r=this._parentage;return r===t||Array.isArray(r)&&r.includes(t)},e.prototype._addParent=function(t){var r=this._parentage;this._parentage=Array.isArray(r)?(r.push(t),r):r?[r,t]:t},e.prototype._removeParent=function(t){var r=this._parentage;r===t?this._parentage=null:Array.isArray(r)&&qe(r,t)},e.prototype.remove=function(t){var r=this._finalizers;r&&qe(r,t),t instanceof e&&t._removeParent(this)},e.EMPTY=function(){var t=new e;return t.closed=!0,t}(),e}();var Tr=Fe.EMPTY;function qt(e){return e instanceof Fe||e&&"closed"in e&&k(e.remove)&&k(e.add)&&k(e.unsubscribe)}function fo(e){k(e)?e():e.unsubscribe()}var $e={onUnhandledError:null,onStoppedNotification:null,Promise:void 0,useDeprecatedSynchronousErrorHandling:!1,useDeprecatedNextContext:!1};var ut={setTimeout:function(e,t){for(var r=[],o=2;o0},enumerable:!1,configurable:!0}),t.prototype._trySubscribe=function(r){return this._throwIfClosed(),e.prototype._trySubscribe.call(this,r)},t.prototype._subscribe=function(r){return this._throwIfClosed(),this._checkFinalizedStatuses(r),this._innerSubscribe(r)},t.prototype._innerSubscribe=function(r){var o=this,n=this,i=n.hasError,a=n.isStopped,s=n.observers;return i||a?Tr:(this.currentObservers=null,s.push(r),new Fe(function(){o.currentObservers=null,qe(s,r)}))},t.prototype._checkFinalizedStatuses=function(r){var o=this,n=o.hasError,i=o.thrownError,a=o.isStopped;n?r.error(i):a&&r.complete()},t.prototype.asObservable=function(){var r=new F;return r.source=this,r},t.create=function(r,o){return new Eo(r,o)},t}(F);var Eo=function(e){re(t,e);function t(r,o){var n=e.call(this)||this;return n.destination=r,n.source=o,n}return t.prototype.next=function(r){var o,n;(n=(o=this.destination)===null||o===void 0?void 0:o.next)===null||n===void 0||n.call(o,r)},t.prototype.error=function(r){var o,n;(n=(o=this.destination)===null||o===void 0?void 0:o.error)===null||n===void 0||n.call(o,r)},t.prototype.complete=function(){var r,o;(o=(r=this.destination)===null||r===void 0?void 0:r.complete)===null||o===void 0||o.call(r)},t.prototype._subscribe=function(r){var o,n;return(n=(o=this.source)===null||o===void 0?void 0:o.subscribe(r))!==null&&n!==void 0?n:Tr},t}(g);var _r=function(e){re(t,e);function t(r){var o=e.call(this)||this;return o._value=r,o}return Object.defineProperty(t.prototype,"value",{get:function(){return this.getValue()},enumerable:!1,configurable:!0}),t.prototype._subscribe=function(r){var o=e.prototype._subscribe.call(this,r);return!o.closed&&r.next(this._value),o},t.prototype.getValue=function(){var r=this,o=r.hasError,n=r.thrownError,i=r._value;if(o)throw n;return this._throwIfClosed(),i},t.prototype.next=function(r){e.prototype.next.call(this,this._value=r)},t}(g);var Lt={now:function(){return(Lt.delegate||Date).now()},delegate:void 0};var _t=function(e){re(t,e);function t(r,o,n){r===void 0&&(r=1/0),o===void 0&&(o=1/0),n===void 0&&(n=Lt);var i=e.call(this)||this;return i._bufferSize=r,i._windowTime=o,i._timestampProvider=n,i._buffer=[],i._infiniteTimeWindow=!0,i._infiniteTimeWindow=o===1/0,i._bufferSize=Math.max(1,r),i._windowTime=Math.max(1,o),i}return t.prototype.next=function(r){var o=this,n=o.isStopped,i=o._buffer,a=o._infiniteTimeWindow,s=o._timestampProvider,p=o._windowTime;n||(i.push(r),!a&&i.push(s.now()+p)),this._trimBuffer(),e.prototype.next.call(this,r)},t.prototype._subscribe=function(r){this._throwIfClosed(),this._trimBuffer();for(var o=this._innerSubscribe(r),n=this,i=n._infiniteTimeWindow,a=n._buffer,s=a.slice(),p=0;p0?e.prototype.schedule.call(this,r,o):(this.delay=o,this.state=r,this.scheduler.flush(this),this)},t.prototype.execute=function(r,o){return o>0||this.closed?e.prototype.execute.call(this,r,o):this._execute(r,o)},t.prototype.requestAsyncId=function(r,o,n){return n===void 0&&(n=0),n!=null&&n>0||n==null&&this.delay>0?e.prototype.requestAsyncId.call(this,r,o,n):(r.flush(this),0)},t}(vt);var So=function(e){re(t,e);function t(){return e!==null&&e.apply(this,arguments)||this}return t}(gt);var Hr=new So(To);var Oo=function(e){re(t,e);function t(r,o){var n=e.call(this,r,o)||this;return n.scheduler=r,n.work=o,n}return t.prototype.requestAsyncId=function(r,o,n){return n===void 0&&(n=0),n!==null&&n>0?e.prototype.requestAsyncId.call(this,r,o,n):(r.actions.push(this),r._scheduled||(r._scheduled=bt.requestAnimationFrame(function(){return r.flush(void 0)})))},t.prototype.recycleAsyncId=function(r,o,n){var i;if(n===void 0&&(n=0),n!=null?n>0:this.delay>0)return e.prototype.recycleAsyncId.call(this,r,o,n);var a=r.actions;o!=null&&((i=a[a.length-1])===null||i===void 0?void 0:i.id)!==o&&(bt.cancelAnimationFrame(o),r._scheduled=void 0)},t}(vt);var Mo=function(e){re(t,e);function t(){return e!==null&&e.apply(this,arguments)||this}return t.prototype.flush=function(r){this._active=!0;var o=this._scheduled;this._scheduled=void 0;var n=this.actions,i;r=r||n.shift();do if(i=r.execute(r.state,r.delay))break;while((r=n[0])&&r.id===o&&n.shift());if(this._active=!1,i){for(;(r=n[0])&&r.id===o&&n.shift();)r.unsubscribe();throw i}},t}(gt);var me=new Mo(Oo);var M=new F(function(e){return e.complete()});function Yt(e){return e&&k(e.schedule)}function kr(e){return e[e.length-1]}function Xe(e){return k(kr(e))?e.pop():void 0}function He(e){return Yt(kr(e))?e.pop():void 0}function Bt(e,t){return typeof kr(e)=="number"?e.pop():t}var xt=function(e){return e&&typeof e.length=="number"&&typeof e!="function"};function Gt(e){return k(e==null?void 0:e.then)}function Jt(e){return k(e[ht])}function Xt(e){return Symbol.asyncIterator&&k(e==null?void 0:e[Symbol.asyncIterator])}function Zt(e){return new TypeError("You provided "+(e!==null&&typeof e=="object"?"an invalid object":"'"+e+"'")+" where a stream was expected. You can provide an Observable, Promise, ReadableStream, Array, AsyncIterable, or Iterable.")}function Gi(){return typeof Symbol!="function"||!Symbol.iterator?"@@iterator":Symbol.iterator}var er=Gi();function tr(e){return k(e==null?void 0:e[er])}function rr(e){return lo(this,arguments,function(){var r,o,n,i;return Nt(this,function(a){switch(a.label){case 0:r=e.getReader(),a.label=1;case 1:a.trys.push([1,,9,10]),a.label=2;case 2:return[4,nt(r.read())];case 3:return o=a.sent(),n=o.value,i=o.done,i?[4,nt(void 0)]:[3,5];case 4:return[2,a.sent()];case 5:return[4,nt(n)];case 6:return[4,a.sent()];case 7:return a.sent(),[3,2];case 8:return[3,10];case 9:return r.releaseLock(),[7];case 10:return[2]}})})}function or(e){return k(e==null?void 0:e.getReader)}function W(e){if(e instanceof F)return e;if(e!=null){if(Jt(e))return Ji(e);if(xt(e))return Xi(e);if(Gt(e))return Zi(e);if(Xt(e))return Lo(e);if(tr(e))return ea(e);if(or(e))return ta(e)}throw Zt(e)}function Ji(e){return new F(function(t){var r=e[ht]();if(k(r.subscribe))return r.subscribe(t);throw new TypeError("Provided object does not correctly implement Symbol.observable")})}function Xi(e){return new F(function(t){for(var r=0;r=2;return function(o){return o.pipe(e?v(function(n,i){return e(n,i,o)}):le,Te(1),r?Be(t):zo(function(){return new ir}))}}function Fr(e){return e<=0?function(){return M}:y(function(t,r){var o=[];t.subscribe(T(r,function(n){o.push(n),e=2,!0))}function pe(e){e===void 0&&(e={});var t=e.connector,r=t===void 0?function(){return new g}:t,o=e.resetOnError,n=o===void 0?!0:o,i=e.resetOnComplete,a=i===void 0?!0:i,s=e.resetOnRefCountZero,p=s===void 0?!0:s;return function(c){var l,f,u,h=0,w=!1,A=!1,te=function(){f==null||f.unsubscribe(),f=void 0},ie=function(){te(),l=u=void 0,w=A=!1},J=function(){var H=l;ie(),H==null||H.unsubscribe()};return y(function(H,mt){h++,!A&&!w&&te();var ze=u=u!=null?u:r();mt.add(function(){h--,h===0&&!A&&!w&&(f=Wr(J,p))}),ze.subscribe(mt),!l&&h>0&&(l=new at({next:function(Ie){return ze.next(Ie)},error:function(Ie){A=!0,te(),f=Wr(ie,n,Ie),ze.error(Ie)},complete:function(){w=!0,te(),f=Wr(ie,a),ze.complete()}}),W(H).subscribe(l))})(c)}}function Wr(e,t){for(var r=[],o=2;oe.next(document)),e}function $(e,t=document){return Array.from(t.querySelectorAll(e))}function P(e,t=document){let r=fe(e,t);if(typeof r=="undefined")throw new ReferenceError(`Missing element: expected "${e}" to be present`);return r}function fe(e,t=document){return t.querySelector(e)||void 0}function Re(){var e,t,r,o;return(o=(r=(t=(e=document.activeElement)==null?void 0:e.shadowRoot)==null?void 0:t.activeElement)!=null?r:document.activeElement)!=null?o:void 0}var xa=S(d(document.body,"focusin"),d(document.body,"focusout")).pipe(_e(1),Q(void 0),m(()=>Re()||document.body),B(1));function et(e){return xa.pipe(m(t=>e.contains(t)),K())}function kt(e,t){return C(()=>S(d(e,"mouseenter").pipe(m(()=>!0)),d(e,"mouseleave").pipe(m(()=>!1))).pipe(t?Ht(r=>Me(+!r*t)):le,Q(e.matches(":hover"))))}function Bo(e,t){if(typeof t=="string"||typeof t=="number")e.innerHTML+=t.toString();else if(t instanceof Node)e.appendChild(t);else if(Array.isArray(t))for(let r of t)Bo(e,r)}function x(e,t,...r){let o=document.createElement(e);if(t)for(let n of Object.keys(t))typeof t[n]!="undefined"&&(typeof t[n]!="boolean"?o.setAttribute(n,t[n]):o.setAttribute(n,""));for(let n of r)Bo(o,n);return o}function sr(e){if(e>999){let t=+((e-950)%1e3>99);return`${((e+1e-6)/1e3).toFixed(t)}k`}else return e.toString()}function wt(e){let t=x("script",{src:e});return C(()=>(document.head.appendChild(t),S(d(t,"load"),d(t,"error").pipe(b(()=>$r(()=>new ReferenceError(`Invalid script: ${e}`))))).pipe(m(()=>{}),L(()=>document.head.removeChild(t)),Te(1))))}var Go=new g,ya=C(()=>typeof ResizeObserver=="undefined"?wt("https://unpkg.com/resize-observer-polyfill"):I(void 0)).pipe(m(()=>new ResizeObserver(e=>e.forEach(t=>Go.next(t)))),b(e=>S(Ke,I(e)).pipe(L(()=>e.disconnect()))),B(1));function ce(e){return{width:e.offsetWidth,height:e.offsetHeight}}function ge(e){let t=e;for(;t.clientWidth===0&&t.parentElement;)t=t.parentElement;return ya.pipe(E(r=>r.observe(t)),b(r=>Go.pipe(v(o=>o.target===t),L(()=>r.unobserve(t)))),m(()=>ce(e)),Q(ce(e)))}function Tt(e){return{width:e.scrollWidth,height:e.scrollHeight}}function cr(e){let t=e.parentElement;for(;t&&(e.scrollWidth<=t.scrollWidth&&e.scrollHeight<=t.scrollHeight);)t=(e=t).parentElement;return t?e:void 0}function Jo(e){let t=[],r=e.parentElement;for(;r;)(e.clientWidth>r.clientWidth||e.clientHeight>r.clientHeight)&&t.push(r),r=(e=r).parentElement;return t.length===0&&t.push(document.documentElement),t}function Ue(e){return{x:e.offsetLeft,y:e.offsetTop}}function Xo(e){let t=e.getBoundingClientRect();return{x:t.x+window.scrollX,y:t.y+window.scrollY}}function Zo(e){return S(d(window,"load"),d(window,"resize")).pipe(Le(0,me),m(()=>Ue(e)),Q(Ue(e)))}function pr(e){return{x:e.scrollLeft,y:e.scrollTop}}function De(e){return S(d(e,"scroll"),d(window,"scroll"),d(window,"resize")).pipe(Le(0,me),m(()=>pr(e)),Q(pr(e)))}var en=new g,Ea=C(()=>I(new IntersectionObserver(e=>{for(let t of e)en.next(t)},{threshold:0}))).pipe(b(e=>S(Ke,I(e)).pipe(L(()=>e.disconnect()))),B(1));function tt(e){return Ea.pipe(E(t=>t.observe(e)),b(t=>en.pipe(v(({target:r})=>r===e),L(()=>t.unobserve(e)),m(({isIntersecting:r})=>r))))}function tn(e,t=16){return De(e).pipe(m(({y:r})=>{let o=ce(e),n=Tt(e);return r>=n.height-o.height-t}),K())}var lr={drawer:P("[data-md-toggle=drawer]"),search:P("[data-md-toggle=search]")};function rn(e){return lr[e].checked}function Je(e,t){lr[e].checked!==t&&lr[e].click()}function Ve(e){let t=lr[e];return d(t,"change").pipe(m(()=>t.checked),Q(t.checked))}function wa(e,t){switch(e.constructor){case HTMLInputElement:return e.type==="radio"?/^Arrow/.test(t):!0;case HTMLSelectElement:case HTMLTextAreaElement:return!0;default:return e.isContentEditable}}function Ta(){return S(d(window,"compositionstart").pipe(m(()=>!0)),d(window,"compositionend").pipe(m(()=>!1))).pipe(Q(!1))}function on(){let e=d(window,"keydown").pipe(v(t=>!(t.metaKey||t.ctrlKey)),m(t=>({mode:rn("search")?"search":"global",type:t.key,claim(){t.preventDefault(),t.stopPropagation()}})),v(({mode:t,type:r})=>{if(t==="global"){let o=Re();if(typeof o!="undefined")return!wa(o,r)}return!0}),pe());return Ta().pipe(b(t=>t?M:e))}function xe(){return new URL(location.href)}function pt(e,t=!1){if(G("navigation.instant")&&!t){let r=x("a",{href:e.href});document.body.appendChild(r),r.click(),r.remove()}else location.href=e.href}function nn(){return new g}function an(){return location.hash.slice(1)}function sn(e){let t=x("a",{href:e});t.addEventListener("click",r=>r.stopPropagation()),t.click()}function Sa(e){return S(d(window,"hashchange"),e).pipe(m(an),Q(an()),v(t=>t.length>0),B(1))}function cn(e){return Sa(e).pipe(m(t=>fe(`[id="${t}"]`)),v(t=>typeof t!="undefined"))}function $t(e){let t=matchMedia(e);return ar(r=>t.addListener(()=>r(t.matches))).pipe(Q(t.matches))}function pn(){let e=matchMedia("print");return S(d(window,"beforeprint").pipe(m(()=>!0)),d(window,"afterprint").pipe(m(()=>!1))).pipe(Q(e.matches))}function Nr(e,t){return e.pipe(b(r=>r?t():M))}function zr(e,t){return new F(r=>{let o=new XMLHttpRequest;return o.open("GET",`${e}`),o.responseType="blob",o.addEventListener("load",()=>{o.status>=200&&o.status<300?(r.next(o.response),r.complete()):r.error(new Error(o.statusText))}),o.addEventListener("error",()=>{r.error(new Error("Network error"))}),o.addEventListener("abort",()=>{r.complete()}),typeof(t==null?void 0:t.progress$)!="undefined"&&(o.addEventListener("progress",n=>{var i;if(n.lengthComputable)t.progress$.next(n.loaded/n.total*100);else{let a=(i=o.getResponseHeader("Content-Length"))!=null?i:0;t.progress$.next(n.loaded/+a*100)}}),t.progress$.next(5)),o.send(),()=>o.abort()})}function Ne(e,t){return zr(e,t).pipe(b(r=>r.text()),m(r=>JSON.parse(r)),B(1))}function ln(e,t){let r=new DOMParser;return zr(e,t).pipe(b(o=>o.text()),m(o=>r.parseFromString(o,"text/html")),B(1))}function mn(e,t){let r=new DOMParser;return zr(e,t).pipe(b(o=>o.text()),m(o=>r.parseFromString(o,"text/xml")),B(1))}function fn(){return{x:Math.max(0,scrollX),y:Math.max(0,scrollY)}}function un(){return S(d(window,"scroll",{passive:!0}),d(window,"resize",{passive:!0})).pipe(m(fn),Q(fn()))}function dn(){return{width:innerWidth,height:innerHeight}}function hn(){return d(window,"resize",{passive:!0}).pipe(m(dn),Q(dn()))}function bn(){return z([un(),hn()]).pipe(m(([e,t])=>({offset:e,size:t})),B(1))}function mr(e,{viewport$:t,header$:r}){let o=t.pipe(Z("size")),n=z([o,r]).pipe(m(()=>Ue(e)));return z([r,t,n]).pipe(m(([{height:i},{offset:a,size:s},{x:p,y:c}])=>({offset:{x:a.x-p,y:a.y-c+i},size:s})))}function Oa(e){return d(e,"message",t=>t.data)}function Ma(e){let t=new g;return t.subscribe(r=>e.postMessage(r)),t}function vn(e,t=new Worker(e)){let r=Oa(t),o=Ma(t),n=new g;n.subscribe(o);let i=o.pipe(X(),ne(!0));return n.pipe(X(),Pe(r.pipe(U(i))),pe())}var La=P("#__config"),St=JSON.parse(La.textContent);St.base=`${new URL(St.base,xe())}`;function ye(){return St}function G(e){return St.features.includes(e)}function Ee(e,t){return typeof t!="undefined"?St.translations[e].replace("#",t.toString()):St.translations[e]}function Se(e,t=document){return P(`[data-md-component=${e}]`,t)}function ae(e,t=document){return $(`[data-md-component=${e}]`,t)}function _a(e){let t=P(".md-typeset > :first-child",e);return d(t,"click",{once:!0}).pipe(m(()=>P(".md-typeset",e)),m(r=>({hash:__md_hash(r.innerHTML)})))}function gn(e){if(!G("announce.dismiss")||!e.childElementCount)return M;if(!e.hidden){let t=P(".md-typeset",e);__md_hash(t.innerHTML)===__md_get("__announce")&&(e.hidden=!0)}return C(()=>{let t=new g;return t.subscribe(({hash:r})=>{e.hidden=!0,__md_set("__announce",r)}),_a(e).pipe(E(r=>t.next(r)),L(()=>t.complete()),m(r=>R({ref:e},r)))})}function Aa(e,{target$:t}){return t.pipe(m(r=>({hidden:r!==e})))}function xn(e,t){let r=new g;return r.subscribe(({hidden:o})=>{e.hidden=o}),Aa(e,t).pipe(E(o=>r.next(o)),L(()=>r.complete()),m(o=>R({ref:e},o)))}function Pt(e,t){return t==="inline"?x("div",{class:"md-tooltip md-tooltip--inline",id:e,role:"tooltip"},x("div",{class:"md-tooltip__inner md-typeset"})):x("div",{class:"md-tooltip",id:e,role:"tooltip"},x("div",{class:"md-tooltip__inner md-typeset"}))}function yn(...e){return x("div",{class:"md-tooltip2",role:"tooltip"},x("div",{class:"md-tooltip2__inner md-typeset"},e))}function En(e,t){if(t=t?`${t}_annotation_${e}`:void 0,t){let r=t?`#${t}`:void 0;return x("aside",{class:"md-annotation",tabIndex:0},Pt(t),x("a",{href:r,class:"md-annotation__index",tabIndex:-1},x("span",{"data-md-annotation-id":e})))}else return x("aside",{class:"md-annotation",tabIndex:0},Pt(t),x("span",{class:"md-annotation__index",tabIndex:-1},x("span",{"data-md-annotation-id":e})))}function wn(e){return x("button",{class:"md-clipboard md-icon",title:Ee("clipboard.copy"),"data-clipboard-target":`#${e} > code`})}function qr(e,t){let r=t&2,o=t&1,n=Object.keys(e.terms).filter(p=>!e.terms[p]).reduce((p,c)=>[...p,x("del",null,c)," "],[]).slice(0,-1),i=ye(),a=new URL(e.location,i.base);G("search.highlight")&&a.searchParams.set("h",Object.entries(e.terms).filter(([,p])=>p).reduce((p,[c])=>`${p} ${c}`.trim(),""));let{tags:s}=ye();return x("a",{href:`${a}`,class:"md-search-result__link",tabIndex:-1},x("article",{class:"md-search-result__article md-typeset","data-md-score":e.score.toFixed(2)},r>0&&x("div",{class:"md-search-result__icon md-icon"}),r>0&&x("h1",null,e.title),r<=0&&x("h2",null,e.title),o>0&&e.text.length>0&&e.text,e.tags&&e.tags.map(p=>{let c=s?p in s?`md-tag-icon md-tag--${s[p]}`:"md-tag-icon":"";return x("span",{class:`md-tag ${c}`},p)}),o>0&&n.length>0&&x("p",{class:"md-search-result__terms"},Ee("search.result.term.missing"),": ",...n)))}function Tn(e){let t=e[0].score,r=[...e],o=ye(),n=r.findIndex(l=>!`${new URL(l.location,o.base)}`.includes("#")),[i]=r.splice(n,1),a=r.findIndex(l=>l.scoreqr(l,1)),...p.length?[x("details",{class:"md-search-result__more"},x("summary",{tabIndex:-1},x("div",null,p.length>0&&p.length===1?Ee("search.result.more.one"):Ee("search.result.more.other",p.length))),...p.map(l=>qr(l,1)))]:[]];return x("li",{class:"md-search-result__item"},c)}function Sn(e){return x("ul",{class:"md-source__facts"},Object.entries(e).map(([t,r])=>x("li",{class:`md-source__fact md-source__fact--${t}`},typeof r=="number"?sr(r):r)))}function Qr(e){let t=`tabbed-control tabbed-control--${e}`;return x("div",{class:t,hidden:!0},x("button",{class:"tabbed-button",tabIndex:-1,"aria-hidden":"true"}))}function On(e){return x("div",{class:"md-typeset__scrollwrap"},x("div",{class:"md-typeset__table"},e))}function Ca(e){var o;let t=ye(),r=new URL(`../${e.version}/`,t.base);return x("li",{class:"md-version__item"},x("a",{href:`${r}`,class:"md-version__link"},e.title,((o=t.version)==null?void 0:o.alias)&&e.aliases.length>0&&x("span",{class:"md-version__alias"},e.aliases[0])))}function Mn(e,t){var o;let r=ye();return e=e.filter(n=>{var i;return!((i=n.properties)!=null&&i.hidden)}),x("div",{class:"md-version"},x("button",{class:"md-version__current","aria-label":Ee("select.version")},t.title,((o=r.version)==null?void 0:o.alias)&&t.aliases.length>0&&x("span",{class:"md-version__alias"},t.aliases[0])),x("ul",{class:"md-version__list"},e.map(Ca)))}var Ha=0;function ka(e){let t=z([et(e),kt(e)]).pipe(m(([o,n])=>o||n),K()),r=C(()=>Jo(e)).pipe(oe(De),ct(1),m(()=>Xo(e)));return t.pipe(Ae(o=>o),b(()=>z([t,r])),m(([o,n])=>({active:o,offset:n})),pe())}function $a(e,t){let{content$:r,viewport$:o}=t,n=`__tooltip2_${Ha++}`;return C(()=>{let i=new g,a=new _r(!1);i.pipe(X(),ne(!1)).subscribe(a);let s=a.pipe(Ht(c=>Me(+!c*250,Hr)),K(),b(c=>c?r:M),E(c=>c.id=n),pe());z([i.pipe(m(({active:c})=>c)),s.pipe(b(c=>kt(c,250)),Q(!1))]).pipe(m(c=>c.some(l=>l))).subscribe(a);let p=a.pipe(v(c=>c),ee(s,o),m(([c,l,{size:f}])=>{let u=e.getBoundingClientRect(),h=u.width/2;if(l.role==="tooltip")return{x:h,y:8+u.height};if(u.y>=f.height/2){let{height:w}=ce(l);return{x:h,y:-16-w}}else return{x:h,y:16+u.height}}));return z([s,i,p]).subscribe(([c,{offset:l},f])=>{c.style.setProperty("--md-tooltip-host-x",`${l.x}px`),c.style.setProperty("--md-tooltip-host-y",`${l.y}px`),c.style.setProperty("--md-tooltip-x",`${f.x}px`),c.style.setProperty("--md-tooltip-y",`${f.y}px`),c.classList.toggle("md-tooltip2--top",f.y<0),c.classList.toggle("md-tooltip2--bottom",f.y>=0)}),a.pipe(v(c=>c),ee(s,(c,l)=>l),v(c=>c.role==="tooltip")).subscribe(c=>{let l=ce(P(":scope > *",c));c.style.setProperty("--md-tooltip-width",`${l.width}px`),c.style.setProperty("--md-tooltip-tail","0px")}),a.pipe(K(),be(me),ee(s)).subscribe(([c,l])=>{l.classList.toggle("md-tooltip2--active",c)}),z([a.pipe(v(c=>c)),s]).subscribe(([c,l])=>{l.role==="dialog"?(e.setAttribute("aria-controls",n),e.setAttribute("aria-haspopup","dialog")):e.setAttribute("aria-describedby",n)}),a.pipe(v(c=>!c)).subscribe(()=>{e.removeAttribute("aria-controls"),e.removeAttribute("aria-describedby"),e.removeAttribute("aria-haspopup")}),ka(e).pipe(E(c=>i.next(c)),L(()=>i.complete()),m(c=>R({ref:e},c)))})}function lt(e,{viewport$:t},r=document.body){return $a(e,{content$:new F(o=>{let n=e.title,i=yn(n);return o.next(i),e.removeAttribute("title"),r.append(i),()=>{i.remove(),e.setAttribute("title",n)}}),viewport$:t})}function Pa(e,t){let r=C(()=>z([Zo(e),De(t)])).pipe(m(([{x:o,y:n},i])=>{let{width:a,height:s}=ce(e);return{x:o-i.x+a/2,y:n-i.y+s/2}}));return et(e).pipe(b(o=>r.pipe(m(n=>({active:o,offset:n})),Te(+!o||1/0))))}function Ln(e,t,{target$:r}){let[o,n]=Array.from(e.children);return C(()=>{let i=new g,a=i.pipe(X(),ne(!0));return i.subscribe({next({offset:s}){e.style.setProperty("--md-tooltip-x",`${s.x}px`),e.style.setProperty("--md-tooltip-y",`${s.y}px`)},complete(){e.style.removeProperty("--md-tooltip-x"),e.style.removeProperty("--md-tooltip-y")}}),tt(e).pipe(U(a)).subscribe(s=>{e.toggleAttribute("data-md-visible",s)}),S(i.pipe(v(({active:s})=>s)),i.pipe(_e(250),v(({active:s})=>!s))).subscribe({next({active:s}){s?e.prepend(o):o.remove()},complete(){e.prepend(o)}}),i.pipe(Le(16,me)).subscribe(({active:s})=>{o.classList.toggle("md-tooltip--active",s)}),i.pipe(ct(125,me),v(()=>!!e.offsetParent),m(()=>e.offsetParent.getBoundingClientRect()),m(({x:s})=>s)).subscribe({next(s){s?e.style.setProperty("--md-tooltip-0",`${-s}px`):e.style.removeProperty("--md-tooltip-0")},complete(){e.style.removeProperty("--md-tooltip-0")}}),d(n,"click").pipe(U(a),v(s=>!(s.metaKey||s.ctrlKey))).subscribe(s=>{s.stopPropagation(),s.preventDefault()}),d(n,"mousedown").pipe(U(a),ee(i)).subscribe(([s,{active:p}])=>{var c;if(s.button!==0||s.metaKey||s.ctrlKey)s.preventDefault();else if(p){s.preventDefault();let l=e.parentElement.closest(".md-annotation");l instanceof HTMLElement?l.focus():(c=Re())==null||c.blur()}}),r.pipe(U(a),v(s=>s===o),Ge(125)).subscribe(()=>e.focus()),Pa(e,t).pipe(E(s=>i.next(s)),L(()=>i.complete()),m(s=>R({ref:e},s)))})}function Ra(e){return e.tagName==="CODE"?$(".c, .c1, .cm",e):[e]}function Ia(e){let t=[];for(let r of Ra(e)){let o=[],n=document.createNodeIterator(r,NodeFilter.SHOW_TEXT);for(let i=n.nextNode();i;i=n.nextNode())o.push(i);for(let i of o){let a;for(;a=/(\(\d+\))(!)?/.exec(i.textContent);){let[,s,p]=a;if(typeof p=="undefined"){let c=i.splitText(a.index);i=c.splitText(s.length),t.push(c)}else{i.textContent=s,t.push(i);break}}}}return t}function _n(e,t){t.append(...Array.from(e.childNodes))}function fr(e,t,{target$:r,print$:o}){let n=t.closest("[id]"),i=n==null?void 0:n.id,a=new Map;for(let s of Ia(t)){let[,p]=s.textContent.match(/\((\d+)\)/);fe(`:scope > li:nth-child(${p})`,e)&&(a.set(p,En(p,i)),s.replaceWith(a.get(p)))}return a.size===0?M:C(()=>{let s=new g,p=s.pipe(X(),ne(!0)),c=[];for(let[l,f]of a)c.push([P(".md-typeset",f),P(`:scope > li:nth-child(${l})`,e)]);return o.pipe(U(p)).subscribe(l=>{e.hidden=!l,e.classList.toggle("md-annotation-list",l);for(let[f,u]of c)l?_n(f,u):_n(u,f)}),S(...[...a].map(([,l])=>Ln(l,t,{target$:r}))).pipe(L(()=>s.complete()),pe())})}function An(e){if(e.nextElementSibling){let t=e.nextElementSibling;if(t.tagName==="OL")return t;if(t.tagName==="P"&&!t.children.length)return An(t)}}function Cn(e,t){return C(()=>{let r=An(e);return typeof r!="undefined"?fr(r,e,t):M})}var Hn=Vt(Yr());var Fa=0;function kn(e){if(e.nextElementSibling){let t=e.nextElementSibling;if(t.tagName==="OL")return t;if(t.tagName==="P"&&!t.children.length)return kn(t)}}function ja(e){return ge(e).pipe(m(({width:t})=>({scrollable:Tt(e).width>t})),Z("scrollable"))}function $n(e,t){let{matches:r}=matchMedia("(hover)"),o=C(()=>{let n=new g,i=n.pipe(Fr(1));n.subscribe(({scrollable:c})=>{c&&r?e.setAttribute("tabindex","0"):e.removeAttribute("tabindex")});let a=[];if(Hn.default.isSupported()&&(e.closest(".copy")||G("content.code.copy")&&!e.closest(".no-copy"))){let c=e.closest("pre");c.id=`__code_${Fa++}`;let l=wn(c.id);c.insertBefore(l,e),G("content.tooltips")&&a.push(lt(l,{viewport$}))}let s=e.closest(".highlight");if(s instanceof HTMLElement){let c=kn(s);if(typeof c!="undefined"&&(s.classList.contains("annotate")||G("content.code.annotate"))){let l=fr(c,e,t);a.push(ge(s).pipe(U(i),m(({width:f,height:u})=>f&&u),K(),b(f=>f?l:M)))}}return $(":scope > span[id]",e).length&&e.classList.add("md-code__content"),ja(e).pipe(E(c=>n.next(c)),L(()=>n.complete()),m(c=>R({ref:e},c)),Pe(...a))});return G("content.lazy")?tt(e).pipe(v(n=>n),Te(1),b(()=>o)):o}function Wa(e,{target$:t,print$:r}){let o=!0;return S(t.pipe(m(n=>n.closest("details:not([open])")),v(n=>e===n),m(()=>({action:"open",reveal:!0}))),r.pipe(v(n=>n||!o),E(()=>o=e.open),m(n=>({action:n?"open":"close"}))))}function Pn(e,t){return C(()=>{let r=new g;return r.subscribe(({action:o,reveal:n})=>{e.toggleAttribute("open",o==="open"),n&&e.scrollIntoView()}),Wa(e,t).pipe(E(o=>r.next(o)),L(()=>r.complete()),m(o=>R({ref:e},o)))})}var Rn=".node circle,.node ellipse,.node path,.node polygon,.node rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}marker{fill:var(--md-mermaid-edge-color)!important}.edgeLabel .label rect{fill:#0000}.label{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.label foreignObject{line-height:normal;overflow:visible}.label div .edgeLabel{color:var(--md-mermaid-label-fg-color)}.edgeLabel,.edgeLabel rect,.label div .edgeLabel{background-color:var(--md-mermaid-label-bg-color)}.edgeLabel,.edgeLabel rect{fill:var(--md-mermaid-label-bg-color);color:var(--md-mermaid-edge-color)}.edgePath .path,.flowchart-link{stroke:var(--md-mermaid-edge-color);stroke-width:.05rem}.edgePath .arrowheadPath{fill:var(--md-mermaid-edge-color);stroke:none}.cluster rect{fill:var(--md-default-fg-color--lightest);stroke:var(--md-default-fg-color--lighter)}.cluster span{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}g #flowchart-circleEnd,g #flowchart-circleStart,g #flowchart-crossEnd,g #flowchart-crossStart,g #flowchart-pointEnd,g #flowchart-pointStart{stroke:none}g.classGroup line,g.classGroup rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}g.classGroup text{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.classLabel .box{fill:var(--md-mermaid-label-bg-color);background-color:var(--md-mermaid-label-bg-color);opacity:1}.classLabel .label{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.node .divider{stroke:var(--md-mermaid-node-fg-color)}.relation{stroke:var(--md-mermaid-edge-color)}.cardinality{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.cardinality text{fill:inherit!important}defs #classDiagram-compositionEnd,defs #classDiagram-compositionStart,defs #classDiagram-dependencyEnd,defs #classDiagram-dependencyStart,defs #classDiagram-extensionEnd,defs #classDiagram-extensionStart{fill:var(--md-mermaid-edge-color)!important;stroke:var(--md-mermaid-edge-color)!important}defs #classDiagram-aggregationEnd,defs #classDiagram-aggregationStart{fill:var(--md-mermaid-label-bg-color)!important;stroke:var(--md-mermaid-edge-color)!important}g.stateGroup rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}g.stateGroup .state-title{fill:var(--md-mermaid-label-fg-color)!important;font-family:var(--md-mermaid-font-family)}g.stateGroup .composit{fill:var(--md-mermaid-label-bg-color)}.nodeLabel,.nodeLabel p{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}a .nodeLabel{text-decoration:underline}.node circle.state-end,.node circle.state-start,.start-state{fill:var(--md-mermaid-edge-color);stroke:none}.end-state-inner,.end-state-outer{fill:var(--md-mermaid-edge-color)}.end-state-inner,.node circle.state-end{stroke:var(--md-mermaid-label-bg-color)}.transition{stroke:var(--md-mermaid-edge-color)}[id^=state-fork] rect,[id^=state-join] rect{fill:var(--md-mermaid-edge-color)!important;stroke:none!important}.statediagram-cluster.statediagram-cluster .inner{fill:var(--md-default-bg-color)}.statediagram-cluster rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}.statediagram-state rect.divider{fill:var(--md-default-fg-color--lightest);stroke:var(--md-default-fg-color--lighter)}defs #statediagram-barbEnd{stroke:var(--md-mermaid-edge-color)}.attributeBoxEven,.attributeBoxOdd{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}.entityBox{fill:var(--md-mermaid-label-bg-color);stroke:var(--md-mermaid-node-fg-color)}.entityLabel{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.relationshipLabelBox{fill:var(--md-mermaid-label-bg-color);fill-opacity:1;background-color:var(--md-mermaid-label-bg-color);opacity:1}.relationshipLabel{fill:var(--md-mermaid-label-fg-color)}.relationshipLine{stroke:var(--md-mermaid-edge-color)}defs #ONE_OR_MORE_END *,defs #ONE_OR_MORE_START *,defs #ONLY_ONE_END *,defs #ONLY_ONE_START *,defs #ZERO_OR_MORE_END *,defs #ZERO_OR_MORE_START *,defs #ZERO_OR_ONE_END *,defs #ZERO_OR_ONE_START *{stroke:var(--md-mermaid-edge-color)!important}defs #ZERO_OR_MORE_END circle,defs #ZERO_OR_MORE_START circle{fill:var(--md-mermaid-label-bg-color)}.actor{fill:var(--md-mermaid-sequence-actor-bg-color);stroke:var(--md-mermaid-sequence-actor-border-color)}text.actor>tspan{fill:var(--md-mermaid-sequence-actor-fg-color);font-family:var(--md-mermaid-font-family)}line{stroke:var(--md-mermaid-sequence-actor-line-color)}.actor-man circle,.actor-man line{fill:var(--md-mermaid-sequence-actorman-bg-color);stroke:var(--md-mermaid-sequence-actorman-line-color)}.messageLine0,.messageLine1{stroke:var(--md-mermaid-sequence-message-line-color)}.note{fill:var(--md-mermaid-sequence-note-bg-color);stroke:var(--md-mermaid-sequence-note-border-color)}.loopText,.loopText>tspan,.messageText,.noteText>tspan{stroke:none;font-family:var(--md-mermaid-font-family)!important}.messageText{fill:var(--md-mermaid-sequence-message-fg-color)}.loopText,.loopText>tspan{fill:var(--md-mermaid-sequence-loop-fg-color)}.noteText>tspan{fill:var(--md-mermaid-sequence-note-fg-color)}#arrowhead path{fill:var(--md-mermaid-sequence-message-line-color);stroke:none}.loopLine{fill:var(--md-mermaid-sequence-loop-bg-color);stroke:var(--md-mermaid-sequence-loop-border-color)}.labelBox{fill:var(--md-mermaid-sequence-label-bg-color);stroke:none}.labelText,.labelText>span{fill:var(--md-mermaid-sequence-label-fg-color);font-family:var(--md-mermaid-font-family)}.sequenceNumber{fill:var(--md-mermaid-sequence-number-fg-color)}rect.rect{fill:var(--md-mermaid-sequence-box-bg-color);stroke:none}rect.rect+text.text{fill:var(--md-mermaid-sequence-box-fg-color)}defs #sequencenumber{fill:var(--md-mermaid-sequence-number-bg-color)!important}";var Br,Da=0;function Va(){return typeof mermaid=="undefined"||mermaid instanceof Element?wt("https://unpkg.com/mermaid@10/dist/mermaid.min.js"):I(void 0)}function In(e){return e.classList.remove("mermaid"),Br||(Br=Va().pipe(E(()=>mermaid.initialize({startOnLoad:!1,themeCSS:Rn,sequence:{actorFontSize:"16px",messageFontSize:"16px",noteFontSize:"16px"}})),m(()=>{}),B(1))),Br.subscribe(()=>ao(this,null,function*(){e.classList.add("mermaid");let t=`__mermaid_${Da++}`,r=x("div",{class:"mermaid"}),o=e.textContent,{svg:n,fn:i}=yield mermaid.render(t,o),a=r.attachShadow({mode:"closed"});a.innerHTML=n,e.replaceWith(r),i==null||i(a)})),Br.pipe(m(()=>({ref:e})))}var Fn=x("table");function jn(e){return e.replaceWith(Fn),Fn.replaceWith(On(e)),I({ref:e})}function Na(e){let t=e.find(r=>r.checked)||e[0];return S(...e.map(r=>d(r,"change").pipe(m(()=>P(`label[for="${r.id}"]`))))).pipe(Q(P(`label[for="${t.id}"]`)),m(r=>({active:r})))}function Wn(e,{viewport$:t,target$:r}){let o=P(".tabbed-labels",e),n=$(":scope > input",e),i=Qr("prev");e.append(i);let a=Qr("next");return e.append(a),C(()=>{let s=new g,p=s.pipe(X(),ne(!0));z([s,ge(e)]).pipe(U(p),Le(1,me)).subscribe({next([{active:c},l]){let f=Ue(c),{width:u}=ce(c);e.style.setProperty("--md-indicator-x",`${f.x}px`),e.style.setProperty("--md-indicator-width",`${u}px`);let h=pr(o);(f.xh.x+l.width)&&o.scrollTo({left:Math.max(0,f.x-16),behavior:"smooth"})},complete(){e.style.removeProperty("--md-indicator-x"),e.style.removeProperty("--md-indicator-width")}}),z([De(o),ge(o)]).pipe(U(p)).subscribe(([c,l])=>{let f=Tt(o);i.hidden=c.x<16,a.hidden=c.x>f.width-l.width-16}),S(d(i,"click").pipe(m(()=>-1)),d(a,"click").pipe(m(()=>1))).pipe(U(p)).subscribe(c=>{let{width:l}=ce(o);o.scrollBy({left:l*c,behavior:"smooth"})}),r.pipe(U(p),v(c=>n.includes(c))).subscribe(c=>c.click()),o.classList.add("tabbed-labels--linked");for(let c of n){let l=P(`label[for="${c.id}"]`);l.replaceChildren(x("a",{href:`#${l.htmlFor}`,tabIndex:-1},...Array.from(l.childNodes))),d(l.firstElementChild,"click").pipe(U(p),v(f=>!(f.metaKey||f.ctrlKey)),E(f=>{f.preventDefault(),f.stopPropagation()})).subscribe(()=>{history.replaceState({},"",`#${l.htmlFor}`),l.click()})}return G("content.tabs.link")&&s.pipe(Ce(1),ee(t)).subscribe(([{active:c},{offset:l}])=>{let f=c.innerText.trim();if(c.hasAttribute("data-md-switching"))c.removeAttribute("data-md-switching");else{let u=e.offsetTop-l.y;for(let w of $("[data-tabs]"))for(let A of $(":scope > input",w)){let te=P(`label[for="${A.id}"]`);if(te!==c&&te.innerText.trim()===f){te.setAttribute("data-md-switching",""),A.click();break}}window.scrollTo({top:e.offsetTop-u});let h=__md_get("__tabs")||[];__md_set("__tabs",[...new Set([f,...h])])}}),s.pipe(U(p)).subscribe(()=>{for(let c of $("audio, video",e))c.pause()}),tt(e).pipe(b(()=>Na(n)),E(c=>s.next(c)),L(()=>s.complete()),m(c=>R({ref:e},c)))}).pipe(Qe(se))}function Un(e,{viewport$:t,target$:r,print$:o}){return S(...$(".annotate:not(.highlight)",e).map(n=>Cn(n,{target$:r,print$:o})),...$("pre:not(.mermaid) > code",e).map(n=>$n(n,{target$:r,print$:o})),...$("pre.mermaid",e).map(n=>In(n)),...$("table:not([class])",e).map(n=>jn(n)),...$("details",e).map(n=>Pn(n,{target$:r,print$:o})),...$("[data-tabs]",e).map(n=>Wn(n,{viewport$:t,target$:r})),...$("[title]",e).filter(()=>G("content.tooltips")).map(n=>lt(n,{viewport$:t})))}function za(e,{alert$:t}){return t.pipe(b(r=>S(I(!0),I(!1).pipe(Ge(2e3))).pipe(m(o=>({message:r,active:o})))))}function Dn(e,t){let r=P(".md-typeset",e);return C(()=>{let o=new g;return o.subscribe(({message:n,active:i})=>{e.classList.toggle("md-dialog--active",i),r.textContent=n}),za(e,t).pipe(E(n=>o.next(n)),L(()=>o.complete()),m(n=>R({ref:e},n)))})}var qa=0;function Qa(e,t){document.body.append(e);let{width:r}=ce(e);e.style.setProperty("--md-tooltip-width",`${r}px`),e.remove();let o=cr(t),n=typeof o!="undefined"?De(o):I({x:0,y:0}),i=S(et(t),kt(t)).pipe(K());return z([i,n]).pipe(m(([a,s])=>{let{x:p,y:c}=Ue(t),l=ce(t),f=t.closest("table");return f&&t.parentElement&&(p+=f.offsetLeft+t.parentElement.offsetLeft,c+=f.offsetTop+t.parentElement.offsetTop),{active:a,offset:{x:p-s.x+l.width/2-r/2,y:c-s.y+l.height+8}}}))}function Vn(e){let t=e.title;if(!t.length)return M;let r=`__tooltip_${qa++}`,o=Pt(r,"inline"),n=P(".md-typeset",o);return n.innerHTML=t,C(()=>{let i=new g;return i.subscribe({next({offset:a}){o.style.setProperty("--md-tooltip-x",`${a.x}px`),o.style.setProperty("--md-tooltip-y",`${a.y}px`)},complete(){o.style.removeProperty("--md-tooltip-x"),o.style.removeProperty("--md-tooltip-y")}}),S(i.pipe(v(({active:a})=>a)),i.pipe(_e(250),v(({active:a})=>!a))).subscribe({next({active:a}){a?(e.insertAdjacentElement("afterend",o),e.setAttribute("aria-describedby",r),e.removeAttribute("title")):(o.remove(),e.removeAttribute("aria-describedby"),e.setAttribute("title",t))},complete(){o.remove(),e.removeAttribute("aria-describedby"),e.setAttribute("title",t)}}),i.pipe(Le(16,me)).subscribe(({active:a})=>{o.classList.toggle("md-tooltip--active",a)}),i.pipe(ct(125,me),v(()=>!!e.offsetParent),m(()=>e.offsetParent.getBoundingClientRect()),m(({x:a})=>a)).subscribe({next(a){a?o.style.setProperty("--md-tooltip-0",`${-a}px`):o.style.removeProperty("--md-tooltip-0")},complete(){o.style.removeProperty("--md-tooltip-0")}}),Qa(o,e).pipe(E(a=>i.next(a)),L(()=>i.complete()),m(a=>R({ref:e},a)))}).pipe(Qe(se))}function Ka({viewport$:e}){if(!G("header.autohide"))return I(!1);let t=e.pipe(m(({offset:{y:n}})=>n),Ye(2,1),m(([n,i])=>[nMath.abs(i-n.y)>100),m(([,[n]])=>n),K()),o=Ve("search");return z([e,o]).pipe(m(([{offset:n},i])=>n.y>400&&!i),K(),b(n=>n?r:I(!1)),Q(!1))}function Nn(e,t){return C(()=>z([ge(e),Ka(t)])).pipe(m(([{height:r},o])=>({height:r,hidden:o})),K((r,o)=>r.height===o.height&&r.hidden===o.hidden),B(1))}function zn(e,{header$:t,main$:r}){return C(()=>{let o=new g,n=o.pipe(X(),ne(!0));o.pipe(Z("active"),We(t)).subscribe(([{active:a},{hidden:s}])=>{e.classList.toggle("md-header--shadow",a&&!s),e.hidden=s});let i=ue($("[title]",e)).pipe(v(()=>G("content.tooltips")),oe(a=>Vn(a)));return r.subscribe(o),t.pipe(U(n),m(a=>R({ref:e},a)),Pe(i.pipe(U(n))))})}function Ya(e,{viewport$:t,header$:r}){return mr(e,{viewport$:t,header$:r}).pipe(m(({offset:{y:o}})=>{let{height:n}=ce(e);return{active:o>=n}}),Z("active"))}function qn(e,t){return C(()=>{let r=new g;r.subscribe({next({active:n}){e.classList.toggle("md-header__title--active",n)},complete(){e.classList.remove("md-header__title--active")}});let o=fe(".md-content h1");return typeof o=="undefined"?M:Ya(o,t).pipe(E(n=>r.next(n)),L(()=>r.complete()),m(n=>R({ref:e},n)))})}function Qn(e,{viewport$:t,header$:r}){let o=r.pipe(m(({height:i})=>i),K()),n=o.pipe(b(()=>ge(e).pipe(m(({height:i})=>({top:e.offsetTop,bottom:e.offsetTop+i})),Z("bottom"))));return z([o,n,t]).pipe(m(([i,{top:a,bottom:s},{offset:{y:p},size:{height:c}}])=>(c=Math.max(0,c-Math.max(0,a-p,i)-Math.max(0,c+p-s)),{offset:a-i,height:c,active:a-i<=p})),K((i,a)=>i.offset===a.offset&&i.height===a.height&&i.active===a.active))}function Ba(e){let t=__md_get("__palette")||{index:e.findIndex(o=>matchMedia(o.getAttribute("data-md-color-media")).matches)},r=Math.max(0,Math.min(t.index,e.length-1));return I(...e).pipe(oe(o=>d(o,"change").pipe(m(()=>o))),Q(e[r]),m(o=>({index:e.indexOf(o),color:{media:o.getAttribute("data-md-color-media"),scheme:o.getAttribute("data-md-color-scheme"),primary:o.getAttribute("data-md-color-primary"),accent:o.getAttribute("data-md-color-accent")}})),B(1))}function Kn(e){let t=$("input",e),r=x("meta",{name:"theme-color"});document.head.appendChild(r);let o=x("meta",{name:"color-scheme"});document.head.appendChild(o);let n=$t("(prefers-color-scheme: light)");return C(()=>{let i=new g;return i.subscribe(a=>{if(document.body.setAttribute("data-md-color-switching",""),a.color.media==="(prefers-color-scheme)"){let s=matchMedia("(prefers-color-scheme: light)"),p=document.querySelector(s.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");a.color.scheme=p.getAttribute("data-md-color-scheme"),a.color.primary=p.getAttribute("data-md-color-primary"),a.color.accent=p.getAttribute("data-md-color-accent")}for(let[s,p]of Object.entries(a.color))document.body.setAttribute(`data-md-color-${s}`,p);for(let s=0;sa.key==="Enter"),ee(i,(a,s)=>s)).subscribe(({index:a})=>{a=(a+1)%t.length,t[a].click(),t[a].focus()}),i.pipe(m(()=>{let a=Se("header"),s=window.getComputedStyle(a);return o.content=s.colorScheme,s.backgroundColor.match(/\d+/g).map(p=>(+p).toString(16).padStart(2,"0")).join("")})).subscribe(a=>r.content=`#${a}`),i.pipe(be(se)).subscribe(()=>{document.body.removeAttribute("data-md-color-switching")}),Ba(t).pipe(U(n.pipe(Ce(1))),st(),E(a=>i.next(a)),L(()=>i.complete()),m(a=>R({ref:e},a)))})}function Yn(e,{progress$:t}){return C(()=>{let r=new g;return r.subscribe(({value:o})=>{e.style.setProperty("--md-progress-value",`${o}`)}),t.pipe(E(o=>r.next({value:o})),L(()=>r.complete()),m(o=>({ref:e,value:o})))})}var Gr=Vt(Yr());function Ga(e){e.setAttribute("data-md-copying","");let t=e.closest("[data-copy]"),r=t?t.getAttribute("data-copy"):e.innerText;return e.removeAttribute("data-md-copying"),r.trimEnd()}function Bn({alert$:e}){Gr.default.isSupported()&&new F(t=>{new Gr.default("[data-clipboard-target], [data-clipboard-text]",{text:r=>r.getAttribute("data-clipboard-text")||Ga(P(r.getAttribute("data-clipboard-target")))}).on("success",r=>t.next(r))}).pipe(E(t=>{t.trigger.focus()}),m(()=>Ee("clipboard.copied"))).subscribe(e)}function Gn(e,t){return e.protocol=t.protocol,e.hostname=t.hostname,e}function Ja(e,t){let r=new Map;for(let o of $("url",e)){let n=P("loc",o),i=[Gn(new URL(n.textContent),t)];r.set(`${i[0]}`,i);for(let a of $("[rel=alternate]",o)){let s=a.getAttribute("href");s!=null&&i.push(Gn(new URL(s),t))}}return r}function ur(e){return mn(new URL("sitemap.xml",e)).pipe(m(t=>Ja(t,new URL(e))),ve(()=>I(new Map)))}function Xa(e,t){if(!(e.target instanceof Element))return M;let r=e.target.closest("a");if(r===null)return M;if(r.target||e.metaKey||e.ctrlKey)return M;let o=new URL(r.href);return o.search=o.hash="",t.has(`${o}`)?(e.preventDefault(),I(new URL(r.href))):M}function Jn(e){let t=new Map;for(let r of $(":scope > *",e.head))t.set(r.outerHTML,r);return t}function Xn(e){for(let t of $("[href], [src]",e))for(let r of["href","src"]){let o=t.getAttribute(r);if(o&&!/^(?:[a-z]+:)?\/\//i.test(o)){t[r]=t[r];break}}return I(e)}function Za(e){for(let o of["[data-md-component=announce]","[data-md-component=container]","[data-md-component=header-topic]","[data-md-component=outdated]","[data-md-component=logo]","[data-md-component=skip]",...G("navigation.tabs.sticky")?["[data-md-component=tabs]"]:[]]){let n=fe(o),i=fe(o,e);typeof n!="undefined"&&typeof i!="undefined"&&n.replaceWith(i)}let t=Jn(document);for(let[o,n]of Jn(e))t.has(o)?t.delete(o):document.head.appendChild(n);for(let o of t.values()){let n=o.getAttribute("name");n!=="theme-color"&&n!=="color-scheme"&&o.remove()}let r=Se("container");return je($("script",r)).pipe(b(o=>{let n=e.createElement("script");if(o.src){for(let i of o.getAttributeNames())n.setAttribute(i,o.getAttribute(i));return o.replaceWith(n),new F(i=>{n.onload=()=>i.complete()})}else return n.textContent=o.textContent,o.replaceWith(n),M}),X(),ne(document))}function Zn({location$:e,viewport$:t,progress$:r}){let o=ye();if(location.protocol==="file:")return M;let n=ur(o.base);I(document).subscribe(Xn);let i=d(document.body,"click").pipe(We(n),b(([p,c])=>Xa(p,c)),pe()),a=d(window,"popstate").pipe(m(xe),pe());i.pipe(ee(t)).subscribe(([p,{offset:c}])=>{history.replaceState(c,""),history.pushState(null,"",p)}),S(i,a).subscribe(e);let s=e.pipe(Z("pathname"),b(p=>ln(p,{progress$:r}).pipe(ve(()=>(pt(p,!0),M)))),b(Xn),b(Za),pe());return S(s.pipe(ee(e,(p,c)=>c)),s.pipe(b(()=>e),Z("pathname"),b(()=>e),Z("hash")),e.pipe(K((p,c)=>p.pathname===c.pathname&&p.hash===c.hash),b(()=>i),E(()=>history.back()))).subscribe(p=>{var c,l;history.state!==null||!p.hash?window.scrollTo(0,(l=(c=history.state)==null?void 0:c.y)!=null?l:0):(history.scrollRestoration="auto",sn(p.hash),history.scrollRestoration="manual")}),e.subscribe(()=>{history.scrollRestoration="manual"}),d(window,"beforeunload").subscribe(()=>{history.scrollRestoration="auto"}),t.pipe(Z("offset"),_e(100)).subscribe(({offset:p})=>{history.replaceState(p,"")}),s}var ri=Vt(ti());function oi(e){let t=e.separator.split("|").map(n=>n.replace(/(\(\?[!=<][^)]+\))/g,"").length===0?"\uFFFD":n).join("|"),r=new RegExp(t,"img"),o=(n,i,a)=>`${i}${a}`;return n=>{n=n.replace(/[\s*+\-:~^]+/g," ").trim();let i=new RegExp(`(^|${e.separator}|)(${n.replace(/[|\\{}()[\]^$+*?.-]/g,"\\$&").replace(r,"|")})`,"img");return a=>(0,ri.default)(a).replace(i,o).replace(/<\/mark>(\s+)]*>/img,"$1")}}function It(e){return e.type===1}function dr(e){return e.type===3}function ni(e,t){let r=vn(e);return S(I(location.protocol!=="file:"),Ve("search")).pipe(Ae(o=>o),b(()=>t)).subscribe(({config:o,docs:n})=>r.next({type:0,data:{config:o,docs:n,options:{suggest:G("search.suggest")}}})),r}function ii({document$:e}){let t=ye(),r=Ne(new URL("../versions.json",t.base)).pipe(ve(()=>M)),o=r.pipe(m(n=>{let[,i]=t.base.match(/([^/]+)\/?$/);return n.find(({version:a,aliases:s})=>a===i||s.includes(i))||n[0]}));r.pipe(m(n=>new Map(n.map(i=>[`${new URL(`../${i.version}/`,t.base)}`,i]))),b(n=>d(document.body,"click").pipe(v(i=>!i.metaKey&&!i.ctrlKey),ee(o),b(([i,a])=>{if(i.target instanceof Element){let s=i.target.closest("a");if(s&&!s.target&&n.has(s.href)){let p=s.href;return!i.target.closest(".md-version")&&n.get(p)===a?M:(i.preventDefault(),I(p))}}return M}),b(i=>ur(new URL(i)).pipe(m(a=>{let p=xe().href.replace(t.base,i);return a.has(p.split("#")[0])?new URL(p):new URL(i)})))))).subscribe(n=>pt(n,!0)),z([r,o]).subscribe(([n,i])=>{P(".md-header__topic").appendChild(Mn(n,i))}),e.pipe(b(()=>o)).subscribe(n=>{var a;let i=__md_get("__outdated",sessionStorage);if(i===null){i=!0;let s=((a=t.version)==null?void 0:a.default)||"latest";Array.isArray(s)||(s=[s]);e:for(let p of s)for(let c of n.aliases.concat(n.version))if(new RegExp(p,"i").test(c)){i=!1;break e}__md_set("__outdated",i,sessionStorage)}if(i)for(let s of ae("outdated"))s.hidden=!1})}function ns(e,{worker$:t}){let{searchParams:r}=xe();r.has("q")&&(Je("search",!0),e.value=r.get("q"),e.focus(),Ve("search").pipe(Ae(i=>!i)).subscribe(()=>{let i=xe();i.searchParams.delete("q"),history.replaceState({},"",`${i}`)}));let o=et(e),n=S(t.pipe(Ae(It)),d(e,"keyup"),o).pipe(m(()=>e.value),K());return z([n,o]).pipe(m(([i,a])=>({value:i,focus:a})),B(1))}function ai(e,{worker$:t}){let r=new g,o=r.pipe(X(),ne(!0));z([t.pipe(Ae(It)),r],(i,a)=>a).pipe(Z("value")).subscribe(({value:i})=>t.next({type:2,data:i})),r.pipe(Z("focus")).subscribe(({focus:i})=>{i&&Je("search",i)}),d(e.form,"reset").pipe(U(o)).subscribe(()=>e.focus());let n=P("header [for=__search]");return d(n,"click").subscribe(()=>e.focus()),ns(e,{worker$:t}).pipe(E(i=>r.next(i)),L(()=>r.complete()),m(i=>R({ref:e},i)),B(1))}function si(e,{worker$:t,query$:r}){let o=new g,n=tn(e.parentElement).pipe(v(Boolean)),i=e.parentElement,a=P(":scope > :first-child",e),s=P(":scope > :last-child",e);Ve("search").subscribe(l=>s.setAttribute("role",l?"list":"presentation")),o.pipe(ee(r),Ur(t.pipe(Ae(It)))).subscribe(([{items:l},{value:f}])=>{switch(l.length){case 0:a.textContent=f.length?Ee("search.result.none"):Ee("search.result.placeholder");break;case 1:a.textContent=Ee("search.result.one");break;default:let u=sr(l.length);a.textContent=Ee("search.result.other",u)}});let p=o.pipe(E(()=>s.innerHTML=""),b(({items:l})=>S(I(...l.slice(0,10)),I(...l.slice(10)).pipe(Ye(4),Vr(n),b(([f])=>f)))),m(Tn),pe());return p.subscribe(l=>s.appendChild(l)),p.pipe(oe(l=>{let f=fe("details",l);return typeof f=="undefined"?M:d(f,"toggle").pipe(U(o),m(()=>f))})).subscribe(l=>{l.open===!1&&l.offsetTop<=i.scrollTop&&i.scrollTo({top:l.offsetTop})}),t.pipe(v(dr),m(({data:l})=>l)).pipe(E(l=>o.next(l)),L(()=>o.complete()),m(l=>R({ref:e},l)))}function is(e,{query$:t}){return t.pipe(m(({value:r})=>{let o=xe();return o.hash="",r=r.replace(/\s+/g,"+").replace(/&/g,"%26").replace(/=/g,"%3D"),o.search=`q=${r}`,{url:o}}))}function ci(e,t){let r=new g,o=r.pipe(X(),ne(!0));return r.subscribe(({url:n})=>{e.setAttribute("data-clipboard-text",e.href),e.href=`${n}`}),d(e,"click").pipe(U(o)).subscribe(n=>n.preventDefault()),is(e,t).pipe(E(n=>r.next(n)),L(()=>r.complete()),m(n=>R({ref:e},n)))}function pi(e,{worker$:t,keyboard$:r}){let o=new g,n=Se("search-query"),i=S(d(n,"keydown"),d(n,"focus")).pipe(be(se),m(()=>n.value),K());return o.pipe(We(i),m(([{suggest:s},p])=>{let c=p.split(/([\s-]+)/);if(s!=null&&s.length&&c[c.length-1]){let l=s[s.length-1];l.startsWith(c[c.length-1])&&(c[c.length-1]=l)}else c.length=0;return c})).subscribe(s=>e.innerHTML=s.join("").replace(/\s/g," ")),r.pipe(v(({mode:s})=>s==="search")).subscribe(s=>{switch(s.type){case"ArrowRight":e.innerText.length&&n.selectionStart===n.value.length&&(n.value=e.innerText);break}}),t.pipe(v(dr),m(({data:s})=>s)).pipe(E(s=>o.next(s)),L(()=>o.complete()),m(()=>({ref:e})))}function li(e,{index$:t,keyboard$:r}){let o=ye();try{let n=ni(o.search,t),i=Se("search-query",e),a=Se("search-result",e);d(e,"click").pipe(v(({target:p})=>p instanceof Element&&!!p.closest("a"))).subscribe(()=>Je("search",!1)),r.pipe(v(({mode:p})=>p==="search")).subscribe(p=>{let c=Re();switch(p.type){case"Enter":if(c===i){let l=new Map;for(let f of $(":first-child [href]",a)){let u=f.firstElementChild;l.set(f,parseFloat(u.getAttribute("data-md-score")))}if(l.size){let[[f]]=[...l].sort(([,u],[,h])=>h-u);f.click()}p.claim()}break;case"Escape":case"Tab":Je("search",!1),i.blur();break;case"ArrowUp":case"ArrowDown":if(typeof c=="undefined")i.focus();else{let l=[i,...$(":not(details) > [href], summary, details[open] [href]",a)],f=Math.max(0,(Math.max(0,l.indexOf(c))+l.length+(p.type==="ArrowUp"?-1:1))%l.length);l[f].focus()}p.claim();break;default:i!==Re()&&i.focus()}}),r.pipe(v(({mode:p})=>p==="global")).subscribe(p=>{switch(p.type){case"f":case"s":case"/":i.focus(),i.select(),p.claim();break}});let s=ai(i,{worker$:n});return S(s,si(a,{worker$:n,query$:s})).pipe(Pe(...ae("search-share",e).map(p=>ci(p,{query$:s})),...ae("search-suggest",e).map(p=>pi(p,{worker$:n,keyboard$:r}))))}catch(n){return e.hidden=!0,Ke}}function mi(e,{index$:t,location$:r}){return z([t,r.pipe(Q(xe()),v(o=>!!o.searchParams.get("h")))]).pipe(m(([o,n])=>oi(o.config)(n.searchParams.get("h"))),m(o=>{var a;let n=new Map,i=document.createNodeIterator(e,NodeFilter.SHOW_TEXT);for(let s=i.nextNode();s;s=i.nextNode())if((a=s.parentElement)!=null&&a.offsetHeight){let p=s.textContent,c=o(p);c.length>p.length&&n.set(s,c)}for(let[s,p]of n){let{childNodes:c}=x("span",null,p);s.replaceWith(...Array.from(c))}return{ref:e,nodes:n}}))}function as(e,{viewport$:t,main$:r}){let o=e.closest(".md-grid"),n=o.offsetTop-o.parentElement.offsetTop;return z([r,t]).pipe(m(([{offset:i,height:a},{offset:{y:s}}])=>(a=a+Math.min(n,Math.max(0,s-i))-n,{height:a,locked:s>=i+n})),K((i,a)=>i.height===a.height&&i.locked===a.locked))}function Jr(e,o){var n=o,{header$:t}=n,r=io(n,["header$"]);let i=P(".md-sidebar__scrollwrap",e),{y:a}=Ue(i);return C(()=>{let s=new g,p=s.pipe(X(),ne(!0)),c=s.pipe(Le(0,me));return c.pipe(ee(t)).subscribe({next([{height:l},{height:f}]){i.style.height=`${l-2*a}px`,e.style.top=`${f}px`},complete(){i.style.height="",e.style.top=""}}),c.pipe(Ae()).subscribe(()=>{for(let l of $(".md-nav__link--active[href]",e)){if(!l.clientHeight)continue;let f=l.closest(".md-sidebar__scrollwrap");if(typeof f!="undefined"){let u=l.offsetTop-f.offsetTop,{height:h}=ce(f);f.scrollTo({top:u-h/2})}}}),ue($("label[tabindex]",e)).pipe(oe(l=>d(l,"click").pipe(be(se),m(()=>l),U(p)))).subscribe(l=>{let f=P(`[id="${l.htmlFor}"]`);P(`[aria-labelledby="${l.id}"]`).setAttribute("aria-expanded",`${f.checked}`)}),as(e,r).pipe(E(l=>s.next(l)),L(()=>s.complete()),m(l=>R({ref:e},l)))})}function fi(e,t){if(typeof t!="undefined"){let r=`https://api.github.com/repos/${e}/${t}`;return Ct(Ne(`${r}/releases/latest`).pipe(ve(()=>M),m(o=>({version:o.tag_name})),Be({})),Ne(r).pipe(ve(()=>M),m(o=>({stars:o.stargazers_count,forks:o.forks_count})),Be({}))).pipe(m(([o,n])=>R(R({},o),n)))}else{let r=`https://api.github.com/users/${e}`;return Ne(r).pipe(m(o=>({repositories:o.public_repos})),Be({}))}}function ui(e,t){let r=`https://${e}/api/v4/projects/${encodeURIComponent(t)}`;return Ne(r).pipe(ve(()=>M),m(({star_count:o,forks_count:n})=>({stars:o,forks:n})),Be({}))}function di(e){let t=e.match(/^.+github\.com\/([^/]+)\/?([^/]+)?/i);if(t){let[,r,o]=t;return fi(r,o)}if(t=e.match(/^.+?([^/]*gitlab[^/]+)\/(.+?)\/?$/i),t){let[,r,o]=t;return ui(r,o)}return M}var ss;function cs(e){return ss||(ss=C(()=>{let t=__md_get("__source",sessionStorage);if(t)return I(t);if(ae("consent").length){let o=__md_get("__consent");if(!(o&&o.github))return M}return di(e.href).pipe(E(o=>__md_set("__source",o,sessionStorage)))}).pipe(ve(()=>M),v(t=>Object.keys(t).length>0),m(t=>({facts:t})),B(1)))}function hi(e){let t=P(":scope > :last-child",e);return C(()=>{let r=new g;return r.subscribe(({facts:o})=>{t.appendChild(Sn(o)),t.classList.add("md-source__repository--active")}),cs(e).pipe(E(o=>r.next(o)),L(()=>r.complete()),m(o=>R({ref:e},o)))})}function ps(e,{viewport$:t,header$:r}){return ge(document.body).pipe(b(()=>mr(e,{header$:r,viewport$:t})),m(({offset:{y:o}})=>({hidden:o>=10})),Z("hidden"))}function bi(e,t){return C(()=>{let r=new g;return r.subscribe({next({hidden:o}){e.hidden=o},complete(){e.hidden=!1}}),(G("navigation.tabs.sticky")?I({hidden:!1}):ps(e,t)).pipe(E(o=>r.next(o)),L(()=>r.complete()),m(o=>R({ref:e},o)))})}function ls(e,{viewport$:t,header$:r}){let o=new Map,n=$(".md-nav__link",e);for(let s of n){let p=decodeURIComponent(s.hash.substring(1)),c=fe(`[id="${p}"]`);typeof c!="undefined"&&o.set(s,c)}let i=r.pipe(Z("height"),m(({height:s})=>{let p=Se("main"),c=P(":scope > :first-child",p);return s+.8*(c.offsetTop-p.offsetTop)}),pe());return ge(document.body).pipe(Z("height"),b(s=>C(()=>{let p=[];return I([...o].reduce((c,[l,f])=>{for(;p.length&&o.get(p[p.length-1]).tagName>=f.tagName;)p.pop();let u=f.offsetTop;for(;!u&&f.parentElement;)f=f.parentElement,u=f.offsetTop;let h=f.offsetParent;for(;h;h=h.offsetParent)u+=h.offsetTop;return c.set([...p=[...p,l]].reverse(),u)},new Map))}).pipe(m(p=>new Map([...p].sort(([,c],[,l])=>c-l))),We(i),b(([p,c])=>t.pipe(jr(([l,f],{offset:{y:u},size:h})=>{let w=u+h.height>=Math.floor(s.height);for(;f.length;){let[,A]=f[0];if(A-c=u&&!w)f=[l.pop(),...f];else break}return[l,f]},[[],[...p]]),K((l,f)=>l[0]===f[0]&&l[1]===f[1])))))).pipe(m(([s,p])=>({prev:s.map(([c])=>c),next:p.map(([c])=>c)})),Q({prev:[],next:[]}),Ye(2,1),m(([s,p])=>s.prev.length{let i=new g,a=i.pipe(X(),ne(!0));if(i.subscribe(({prev:s,next:p})=>{for(let[c]of p)c.classList.remove("md-nav__link--passed"),c.classList.remove("md-nav__link--active");for(let[c,[l]]of s.entries())l.classList.add("md-nav__link--passed"),l.classList.toggle("md-nav__link--active",c===s.length-1)}),G("toc.follow")){let s=S(t.pipe(_e(1),m(()=>{})),t.pipe(_e(250),m(()=>"smooth")));i.pipe(v(({prev:p})=>p.length>0),We(o.pipe(be(se))),ee(s)).subscribe(([[{prev:p}],c])=>{let[l]=p[p.length-1];if(l.offsetHeight){let f=cr(l);if(typeof f!="undefined"){let u=l.offsetTop-f.offsetTop,{height:h}=ce(f);f.scrollTo({top:u-h/2,behavior:c})}}})}return G("navigation.tracking")&&t.pipe(U(a),Z("offset"),_e(250),Ce(1),U(n.pipe(Ce(1))),st({delay:250}),ee(i)).subscribe(([,{prev:s}])=>{let p=xe(),c=s[s.length-1];if(c&&c.length){let[l]=c,{hash:f}=new URL(l.href);p.hash!==f&&(p.hash=f,history.replaceState({},"",`${p}`))}else p.hash="",history.replaceState({},"",`${p}`)}),ls(e,{viewport$:t,header$:r}).pipe(E(s=>i.next(s)),L(()=>i.complete()),m(s=>R({ref:e},s)))})}function ms(e,{viewport$:t,main$:r,target$:o}){let n=t.pipe(m(({offset:{y:a}})=>a),Ye(2,1),m(([a,s])=>a>s&&s>0),K()),i=r.pipe(m(({active:a})=>a));return z([i,n]).pipe(m(([a,s])=>!(a&&s)),K(),U(o.pipe(Ce(1))),ne(!0),st({delay:250}),m(a=>({hidden:a})))}function gi(e,{viewport$:t,header$:r,main$:o,target$:n}){let i=new g,a=i.pipe(X(),ne(!0));return i.subscribe({next({hidden:s}){e.hidden=s,s?(e.setAttribute("tabindex","-1"),e.blur()):e.removeAttribute("tabindex")},complete(){e.style.top="",e.hidden=!0,e.removeAttribute("tabindex")}}),r.pipe(U(a),Z("height")).subscribe(({height:s})=>{e.style.top=`${s+16}px`}),d(e,"click").subscribe(s=>{s.preventDefault(),window.scrollTo({top:0})}),ms(e,{viewport$:t,main$:o,target$:n}).pipe(E(s=>i.next(s)),L(()=>i.complete()),m(s=>R({ref:e},s)))}function xi({document$:e,viewport$:t}){e.pipe(b(()=>$(".md-ellipsis")),oe(r=>tt(r).pipe(U(e.pipe(Ce(1))),v(o=>o),m(()=>r),Te(1))),v(r=>r.offsetWidth{let o=r.innerText,n=r.closest("a")||r;return n.title=o,lt(n,{viewport$:t}).pipe(U(e.pipe(Ce(1))),L(()=>n.removeAttribute("title")))})).subscribe(),e.pipe(b(()=>$(".md-status")),oe(r=>lt(r,{viewport$:t}))).subscribe()}function yi({document$:e,tablet$:t}){e.pipe(b(()=>$(".md-toggle--indeterminate")),E(r=>{r.indeterminate=!0,r.checked=!1}),oe(r=>d(r,"change").pipe(Dr(()=>r.classList.contains("md-toggle--indeterminate")),m(()=>r))),ee(t)).subscribe(([r,o])=>{r.classList.remove("md-toggle--indeterminate"),o&&(r.checked=!1)})}function fs(){return/(iPad|iPhone|iPod)/.test(navigator.userAgent)}function Ei({document$:e}){e.pipe(b(()=>$("[data-md-scrollfix]")),E(t=>t.removeAttribute("data-md-scrollfix")),v(fs),oe(t=>d(t,"touchstart").pipe(m(()=>t)))).subscribe(t=>{let r=t.scrollTop;r===0?t.scrollTop=1:r+t.offsetHeight===t.scrollHeight&&(t.scrollTop=r-1)})}function wi({viewport$:e,tablet$:t}){z([Ve("search"),t]).pipe(m(([r,o])=>r&&!o),b(r=>I(r).pipe(Ge(r?400:100))),ee(e)).subscribe(([r,{offset:{y:o}}])=>{if(r)document.body.setAttribute("data-md-scrolllock",""),document.body.style.top=`-${o}px`;else{let n=-1*parseInt(document.body.style.top,10);document.body.removeAttribute("data-md-scrolllock"),document.body.style.top="",n&&window.scrollTo(0,n)}})}Object.entries||(Object.entries=function(e){let t=[];for(let r of Object.keys(e))t.push([r,e[r]]);return t});Object.values||(Object.values=function(e){let t=[];for(let r of Object.keys(e))t.push(e[r]);return t});typeof Element!="undefined"&&(Element.prototype.scrollTo||(Element.prototype.scrollTo=function(e,t){typeof e=="object"?(this.scrollLeft=e.left,this.scrollTop=e.top):(this.scrollLeft=e,this.scrollTop=t)}),Element.prototype.replaceWith||(Element.prototype.replaceWith=function(...e){let t=this.parentNode;if(t){e.length===0&&t.removeChild(this);for(let r=e.length-1;r>=0;r--){let o=e[r];typeof o=="string"?o=document.createTextNode(o):o.parentNode&&o.parentNode.removeChild(o),r?t.insertBefore(this.previousSibling,o):t.replaceChild(o,this)}}}));function us(){return location.protocol==="file:"?wt(`${new URL("search/search_index.js",Xr.base)}`).pipe(m(()=>__index),B(1)):Ne(new URL("search/search_index.json",Xr.base))}document.documentElement.classList.remove("no-js");document.documentElement.classList.add("js");var ot=Yo(),jt=nn(),Ot=cn(jt),Zr=on(),Oe=bn(),hr=$t("(min-width: 960px)"),Si=$t("(min-width: 1220px)"),Oi=pn(),Xr=ye(),Mi=document.forms.namedItem("search")?us():Ke,eo=new g;Bn({alert$:eo});var to=new g;G("navigation.instant")&&Zn({location$:jt,viewport$:Oe,progress$:to}).subscribe(ot);var Ti;((Ti=Xr.version)==null?void 0:Ti.provider)==="mike"&&ii({document$:ot});S(jt,Ot).pipe(Ge(125)).subscribe(()=>{Je("drawer",!1),Je("search",!1)});Zr.pipe(v(({mode:e})=>e==="global")).subscribe(e=>{switch(e.type){case"p":case",":let t=fe("link[rel=prev]");typeof t!="undefined"&&pt(t);break;case"n":case".":let r=fe("link[rel=next]");typeof r!="undefined"&&pt(r);break;case"Enter":let o=Re();o instanceof HTMLLabelElement&&o.click()}});xi({viewport$:Oe,document$:ot});yi({document$:ot,tablet$:hr});Ei({document$:ot});wi({viewport$:Oe,tablet$:hr});var rt=Nn(Se("header"),{viewport$:Oe}),Ft=ot.pipe(m(()=>Se("main")),b(e=>Qn(e,{viewport$:Oe,header$:rt})),B(1)),ds=S(...ae("consent").map(e=>xn(e,{target$:Ot})),...ae("dialog").map(e=>Dn(e,{alert$:eo})),...ae("header").map(e=>zn(e,{viewport$:Oe,header$:rt,main$:Ft})),...ae("palette").map(e=>Kn(e)),...ae("progress").map(e=>Yn(e,{progress$:to})),...ae("search").map(e=>li(e,{index$:Mi,keyboard$:Zr})),...ae("source").map(e=>hi(e))),hs=C(()=>S(...ae("announce").map(e=>gn(e)),...ae("content").map(e=>Un(e,{viewport$:Oe,target$:Ot,print$:Oi})),...ae("content").map(e=>G("search.highlight")?mi(e,{index$:Mi,location$:jt}):M),...ae("header-title").map(e=>qn(e,{viewport$:Oe,header$:rt})),...ae("sidebar").map(e=>e.getAttribute("data-md-type")==="navigation"?Nr(Si,()=>Jr(e,{viewport$:Oe,header$:rt,main$:Ft})):Nr(hr,()=>Jr(e,{viewport$:Oe,header$:rt,main$:Ft}))),...ae("tabs").map(e=>bi(e,{viewport$:Oe,header$:rt})),...ae("toc").map(e=>vi(e,{viewport$:Oe,header$:rt,main$:Ft,target$:Ot})),...ae("top").map(e=>gi(e,{viewport$:Oe,header$:rt,main$:Ft,target$:Ot})))),Li=ot.pipe(b(()=>hs),Pe(ds),B(1));Li.subscribe();window.document$=ot;window.location$=jt;window.target$=Ot;window.keyboard$=Zr;window.viewport$=Oe;window.tablet$=hr;window.screen$=Si;window.print$=Oi;window.alert$=eo;window.progress$=to;window.component$=Li;})(); +//# sourceMappingURL=bundle.081f42fc.min.js.map + diff --git a/assets/javascripts/bundle.081f42fc.min.js.map b/assets/javascripts/bundle.081f42fc.min.js.map new file mode 100644 index 0000000000..e055db5acc --- /dev/null +++ b/assets/javascripts/bundle.081f42fc.min.js.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": ["node_modules/focus-visible/dist/focus-visible.js", "node_modules/clipboard/dist/clipboard.js", "node_modules/escape-html/index.js", "src/templates/assets/javascripts/bundle.ts", "node_modules/rxjs/node_modules/tslib/tslib.es6.js", "node_modules/rxjs/src/internal/util/isFunction.ts", "node_modules/rxjs/src/internal/util/createErrorClass.ts", "node_modules/rxjs/src/internal/util/UnsubscriptionError.ts", "node_modules/rxjs/src/internal/util/arrRemove.ts", "node_modules/rxjs/src/internal/Subscription.ts", "node_modules/rxjs/src/internal/config.ts", "node_modules/rxjs/src/internal/scheduler/timeoutProvider.ts", "node_modules/rxjs/src/internal/util/reportUnhandledError.ts", "node_modules/rxjs/src/internal/util/noop.ts", "node_modules/rxjs/src/internal/NotificationFactories.ts", "node_modules/rxjs/src/internal/util/errorContext.ts", "node_modules/rxjs/src/internal/Subscriber.ts", "node_modules/rxjs/src/internal/symbol/observable.ts", "node_modules/rxjs/src/internal/util/identity.ts", "node_modules/rxjs/src/internal/util/pipe.ts", "node_modules/rxjs/src/internal/Observable.ts", "node_modules/rxjs/src/internal/util/lift.ts", "node_modules/rxjs/src/internal/operators/OperatorSubscriber.ts", "node_modules/rxjs/src/internal/scheduler/animationFrameProvider.ts", "node_modules/rxjs/src/internal/util/ObjectUnsubscribedError.ts", "node_modules/rxjs/src/internal/Subject.ts", "node_modules/rxjs/src/internal/BehaviorSubject.ts", "node_modules/rxjs/src/internal/scheduler/dateTimestampProvider.ts", "node_modules/rxjs/src/internal/ReplaySubject.ts", "node_modules/rxjs/src/internal/scheduler/Action.ts", "node_modules/rxjs/src/internal/scheduler/intervalProvider.ts", "node_modules/rxjs/src/internal/scheduler/AsyncAction.ts", "node_modules/rxjs/src/internal/Scheduler.ts", "node_modules/rxjs/src/internal/scheduler/AsyncScheduler.ts", "node_modules/rxjs/src/internal/scheduler/async.ts", "node_modules/rxjs/src/internal/scheduler/QueueAction.ts", "node_modules/rxjs/src/internal/scheduler/QueueScheduler.ts", "node_modules/rxjs/src/internal/scheduler/queue.ts", "node_modules/rxjs/src/internal/scheduler/AnimationFrameAction.ts", "node_modules/rxjs/src/internal/scheduler/AnimationFrameScheduler.ts", "node_modules/rxjs/src/internal/scheduler/animationFrame.ts", "node_modules/rxjs/src/internal/observable/empty.ts", "node_modules/rxjs/src/internal/util/isScheduler.ts", "node_modules/rxjs/src/internal/util/args.ts", "node_modules/rxjs/src/internal/util/isArrayLike.ts", "node_modules/rxjs/src/internal/util/isPromise.ts", "node_modules/rxjs/src/internal/util/isInteropObservable.ts", "node_modules/rxjs/src/internal/util/isAsyncIterable.ts", "node_modules/rxjs/src/internal/util/throwUnobservableError.ts", "node_modules/rxjs/src/internal/symbol/iterator.ts", "node_modules/rxjs/src/internal/util/isIterable.ts", "node_modules/rxjs/src/internal/util/isReadableStreamLike.ts", "node_modules/rxjs/src/internal/observable/innerFrom.ts", "node_modules/rxjs/src/internal/util/executeSchedule.ts", "node_modules/rxjs/src/internal/operators/observeOn.ts", "node_modules/rxjs/src/internal/operators/subscribeOn.ts", "node_modules/rxjs/src/internal/scheduled/scheduleObservable.ts", "node_modules/rxjs/src/internal/scheduled/schedulePromise.ts", "node_modules/rxjs/src/internal/scheduled/scheduleArray.ts", "node_modules/rxjs/src/internal/scheduled/scheduleIterable.ts", "node_modules/rxjs/src/internal/scheduled/scheduleAsyncIterable.ts", "node_modules/rxjs/src/internal/scheduled/scheduleReadableStreamLike.ts", "node_modules/rxjs/src/internal/scheduled/scheduled.ts", "node_modules/rxjs/src/internal/observable/from.ts", "node_modules/rxjs/src/internal/observable/of.ts", "node_modules/rxjs/src/internal/observable/throwError.ts", "node_modules/rxjs/src/internal/util/EmptyError.ts", "node_modules/rxjs/src/internal/util/isDate.ts", "node_modules/rxjs/src/internal/operators/map.ts", "node_modules/rxjs/src/internal/util/mapOneOrManyArgs.ts", "node_modules/rxjs/src/internal/util/argsArgArrayOrObject.ts", "node_modules/rxjs/src/internal/util/createObject.ts", "node_modules/rxjs/src/internal/observable/combineLatest.ts", "node_modules/rxjs/src/internal/operators/mergeInternals.ts", "node_modules/rxjs/src/internal/operators/mergeMap.ts", "node_modules/rxjs/src/internal/operators/mergeAll.ts", "node_modules/rxjs/src/internal/operators/concatAll.ts", "node_modules/rxjs/src/internal/observable/concat.ts", "node_modules/rxjs/src/internal/observable/defer.ts", "node_modules/rxjs/src/internal/observable/fromEvent.ts", "node_modules/rxjs/src/internal/observable/fromEventPattern.ts", "node_modules/rxjs/src/internal/observable/timer.ts", "node_modules/rxjs/src/internal/observable/merge.ts", "node_modules/rxjs/src/internal/observable/never.ts", "node_modules/rxjs/src/internal/util/argsOrArgArray.ts", "node_modules/rxjs/src/internal/operators/filter.ts", "node_modules/rxjs/src/internal/observable/zip.ts", "node_modules/rxjs/src/internal/operators/audit.ts", "node_modules/rxjs/src/internal/operators/auditTime.ts", "node_modules/rxjs/src/internal/operators/bufferCount.ts", "node_modules/rxjs/src/internal/operators/catchError.ts", "node_modules/rxjs/src/internal/operators/scanInternals.ts", "node_modules/rxjs/src/internal/operators/combineLatest.ts", "node_modules/rxjs/src/internal/operators/combineLatestWith.ts", "node_modules/rxjs/src/internal/operators/debounce.ts", "node_modules/rxjs/src/internal/operators/debounceTime.ts", "node_modules/rxjs/src/internal/operators/defaultIfEmpty.ts", "node_modules/rxjs/src/internal/operators/take.ts", "node_modules/rxjs/src/internal/operators/ignoreElements.ts", "node_modules/rxjs/src/internal/operators/mapTo.ts", "node_modules/rxjs/src/internal/operators/delayWhen.ts", "node_modules/rxjs/src/internal/operators/delay.ts", "node_modules/rxjs/src/internal/operators/distinctUntilChanged.ts", "node_modules/rxjs/src/internal/operators/distinctUntilKeyChanged.ts", "node_modules/rxjs/src/internal/operators/throwIfEmpty.ts", "node_modules/rxjs/src/internal/operators/endWith.ts", "node_modules/rxjs/src/internal/operators/finalize.ts", "node_modules/rxjs/src/internal/operators/first.ts", "node_modules/rxjs/src/internal/operators/takeLast.ts", "node_modules/rxjs/src/internal/operators/merge.ts", "node_modules/rxjs/src/internal/operators/mergeWith.ts", "node_modules/rxjs/src/internal/operators/repeat.ts", "node_modules/rxjs/src/internal/operators/scan.ts", "node_modules/rxjs/src/internal/operators/share.ts", "node_modules/rxjs/src/internal/operators/shareReplay.ts", "node_modules/rxjs/src/internal/operators/skip.ts", "node_modules/rxjs/src/internal/operators/skipUntil.ts", "node_modules/rxjs/src/internal/operators/startWith.ts", "node_modules/rxjs/src/internal/operators/switchMap.ts", "node_modules/rxjs/src/internal/operators/takeUntil.ts", "node_modules/rxjs/src/internal/operators/takeWhile.ts", "node_modules/rxjs/src/internal/operators/tap.ts", "node_modules/rxjs/src/internal/operators/throttle.ts", "node_modules/rxjs/src/internal/operators/throttleTime.ts", "node_modules/rxjs/src/internal/operators/withLatestFrom.ts", "node_modules/rxjs/src/internal/operators/zip.ts", "node_modules/rxjs/src/internal/operators/zipWith.ts", "src/templates/assets/javascripts/browser/document/index.ts", "src/templates/assets/javascripts/browser/element/_/index.ts", "src/templates/assets/javascripts/browser/element/focus/index.ts", "src/templates/assets/javascripts/browser/element/hover/index.ts", "src/templates/assets/javascripts/utilities/h/index.ts", "src/templates/assets/javascripts/utilities/round/index.ts", "src/templates/assets/javascripts/browser/script/index.ts", "src/templates/assets/javascripts/browser/element/size/_/index.ts", "src/templates/assets/javascripts/browser/element/size/content/index.ts", "src/templates/assets/javascripts/browser/element/offset/_/index.ts", "src/templates/assets/javascripts/browser/element/offset/content/index.ts", "src/templates/assets/javascripts/browser/element/visibility/index.ts", "src/templates/assets/javascripts/browser/toggle/index.ts", "src/templates/assets/javascripts/browser/keyboard/index.ts", "src/templates/assets/javascripts/browser/location/_/index.ts", "src/templates/assets/javascripts/browser/location/hash/index.ts", "src/templates/assets/javascripts/browser/media/index.ts", "src/templates/assets/javascripts/browser/request/index.ts", "src/templates/assets/javascripts/browser/viewport/offset/index.ts", "src/templates/assets/javascripts/browser/viewport/size/index.ts", "src/templates/assets/javascripts/browser/viewport/_/index.ts", "src/templates/assets/javascripts/browser/viewport/at/index.ts", "src/templates/assets/javascripts/browser/worker/index.ts", "src/templates/assets/javascripts/_/index.ts", "src/templates/assets/javascripts/components/_/index.ts", "src/templates/assets/javascripts/components/announce/index.ts", "src/templates/assets/javascripts/components/consent/index.ts", "src/templates/assets/javascripts/templates/tooltip/index.tsx", "src/templates/assets/javascripts/templates/annotation/index.tsx", "src/templates/assets/javascripts/templates/clipboard/index.tsx", "src/templates/assets/javascripts/templates/search/index.tsx", "src/templates/assets/javascripts/templates/source/index.tsx", "src/templates/assets/javascripts/templates/tabbed/index.tsx", "src/templates/assets/javascripts/templates/table/index.tsx", "src/templates/assets/javascripts/templates/version/index.tsx", "src/templates/assets/javascripts/components/tooltip2/index.ts", "src/templates/assets/javascripts/components/content/annotation/_/index.ts", "src/templates/assets/javascripts/components/content/annotation/list/index.ts", "src/templates/assets/javascripts/components/content/annotation/block/index.ts", "src/templates/assets/javascripts/components/content/code/_/index.ts", "src/templates/assets/javascripts/components/content/details/index.ts", "src/templates/assets/javascripts/components/content/mermaid/index.css", "src/templates/assets/javascripts/components/content/mermaid/index.ts", "src/templates/assets/javascripts/components/content/table/index.ts", "src/templates/assets/javascripts/components/content/tabs/index.ts", "src/templates/assets/javascripts/components/content/_/index.ts", "src/templates/assets/javascripts/components/dialog/index.ts", "src/templates/assets/javascripts/components/tooltip/index.ts", "src/templates/assets/javascripts/components/header/_/index.ts", "src/templates/assets/javascripts/components/header/title/index.ts", "src/templates/assets/javascripts/components/main/index.ts", "src/templates/assets/javascripts/components/palette/index.ts", "src/templates/assets/javascripts/components/progress/index.ts", "src/templates/assets/javascripts/integrations/clipboard/index.ts", "src/templates/assets/javascripts/integrations/sitemap/index.ts", "src/templates/assets/javascripts/integrations/instant/index.ts", "src/templates/assets/javascripts/integrations/search/highlighter/index.ts", "src/templates/assets/javascripts/integrations/search/worker/message/index.ts", "src/templates/assets/javascripts/integrations/search/worker/_/index.ts", "src/templates/assets/javascripts/integrations/version/index.ts", "src/templates/assets/javascripts/components/search/query/index.ts", "src/templates/assets/javascripts/components/search/result/index.ts", "src/templates/assets/javascripts/components/search/share/index.ts", "src/templates/assets/javascripts/components/search/suggest/index.ts", "src/templates/assets/javascripts/components/search/_/index.ts", "src/templates/assets/javascripts/components/search/highlight/index.ts", "src/templates/assets/javascripts/components/sidebar/index.ts", "src/templates/assets/javascripts/components/source/facts/github/index.ts", "src/templates/assets/javascripts/components/source/facts/gitlab/index.ts", "src/templates/assets/javascripts/components/source/facts/_/index.ts", "src/templates/assets/javascripts/components/source/_/index.ts", "src/templates/assets/javascripts/components/tabs/index.ts", "src/templates/assets/javascripts/components/toc/index.ts", "src/templates/assets/javascripts/components/top/index.ts", "src/templates/assets/javascripts/patches/ellipsis/index.ts", "src/templates/assets/javascripts/patches/indeterminate/index.ts", "src/templates/assets/javascripts/patches/scrollfix/index.ts", "src/templates/assets/javascripts/patches/scrolllock/index.ts", "src/templates/assets/javascripts/polyfills/index.ts"], + "sourcesContent": ["(function (global, factory) {\n typeof exports === 'object' && typeof module !== 'undefined' ? factory() :\n typeof define === 'function' && define.amd ? define(factory) :\n (factory());\n}(this, (function () { 'use strict';\n\n /**\n * Applies the :focus-visible polyfill at the given scope.\n * A scope in this case is either the top-level Document or a Shadow Root.\n *\n * @param {(Document|ShadowRoot)} scope\n * @see https://github.com/WICG/focus-visible\n */\n function applyFocusVisiblePolyfill(scope) {\n var hadKeyboardEvent = true;\n var hadFocusVisibleRecently = false;\n var hadFocusVisibleRecentlyTimeout = null;\n\n var inputTypesAllowlist = {\n text: true,\n search: true,\n url: true,\n tel: true,\n email: true,\n password: true,\n number: true,\n date: true,\n month: true,\n week: true,\n time: true,\n datetime: true,\n 'datetime-local': true\n };\n\n /**\n * Helper function for legacy browsers and iframes which sometimes focus\n * elements like document, body, and non-interactive SVG.\n * @param {Element} el\n */\n function isValidFocusTarget(el) {\n if (\n el &&\n el !== document &&\n el.nodeName !== 'HTML' &&\n el.nodeName !== 'BODY' &&\n 'classList' in el &&\n 'contains' in el.classList\n ) {\n return true;\n }\n return false;\n }\n\n /**\n * Computes whether the given element should automatically trigger the\n * `focus-visible` class being added, i.e. whether it should always match\n * `:focus-visible` when focused.\n * @param {Element} el\n * @return {boolean}\n */\n function focusTriggersKeyboardModality(el) {\n var type = el.type;\n var tagName = el.tagName;\n\n if (tagName === 'INPUT' && inputTypesAllowlist[type] && !el.readOnly) {\n return true;\n }\n\n if (tagName === 'TEXTAREA' && !el.readOnly) {\n return true;\n }\n\n if (el.isContentEditable) {\n return true;\n }\n\n return false;\n }\n\n /**\n * Add the `focus-visible` class to the given element if it was not added by\n * the author.\n * @param {Element} el\n */\n function addFocusVisibleClass(el) {\n if (el.classList.contains('focus-visible')) {\n return;\n }\n el.classList.add('focus-visible');\n el.setAttribute('data-focus-visible-added', '');\n }\n\n /**\n * Remove the `focus-visible` class from the given element if it was not\n * originally added by the author.\n * @param {Element} el\n */\n function removeFocusVisibleClass(el) {\n if (!el.hasAttribute('data-focus-visible-added')) {\n return;\n }\n el.classList.remove('focus-visible');\n el.removeAttribute('data-focus-visible-added');\n }\n\n /**\n * If the most recent user interaction was via the keyboard;\n * and the key press did not include a meta, alt/option, or control key;\n * then the modality is keyboard. Otherwise, the modality is not keyboard.\n * Apply `focus-visible` to any current active element and keep track\n * of our keyboard modality state with `hadKeyboardEvent`.\n * @param {KeyboardEvent} e\n */\n function onKeyDown(e) {\n if (e.metaKey || e.altKey || e.ctrlKey) {\n return;\n }\n\n if (isValidFocusTarget(scope.activeElement)) {\n addFocusVisibleClass(scope.activeElement);\n }\n\n hadKeyboardEvent = true;\n }\n\n /**\n * If at any point a user clicks with a pointing device, ensure that we change\n * the modality away from keyboard.\n * This avoids the situation where a user presses a key on an already focused\n * element, and then clicks on a different element, focusing it with a\n * pointing device, while we still think we're in keyboard modality.\n * @param {Event} e\n */\n function onPointerDown(e) {\n hadKeyboardEvent = false;\n }\n\n /**\n * On `focus`, add the `focus-visible` class to the target if:\n * - the target received focus as a result of keyboard navigation, or\n * - the event target is an element that will likely require interaction\n * via the keyboard (e.g. a text box)\n * @param {Event} e\n */\n function onFocus(e) {\n // Prevent IE from focusing the document or HTML element.\n if (!isValidFocusTarget(e.target)) {\n return;\n }\n\n if (hadKeyboardEvent || focusTriggersKeyboardModality(e.target)) {\n addFocusVisibleClass(e.target);\n }\n }\n\n /**\n * On `blur`, remove the `focus-visible` class from the target.\n * @param {Event} e\n */\n function onBlur(e) {\n if (!isValidFocusTarget(e.target)) {\n return;\n }\n\n if (\n e.target.classList.contains('focus-visible') ||\n e.target.hasAttribute('data-focus-visible-added')\n ) {\n // To detect a tab/window switch, we look for a blur event followed\n // rapidly by a visibility change.\n // If we don't see a visibility change within 100ms, it's probably a\n // regular focus change.\n hadFocusVisibleRecently = true;\n window.clearTimeout(hadFocusVisibleRecentlyTimeout);\n hadFocusVisibleRecentlyTimeout = window.setTimeout(function() {\n hadFocusVisibleRecently = false;\n }, 100);\n removeFocusVisibleClass(e.target);\n }\n }\n\n /**\n * If the user changes tabs, keep track of whether or not the previously\n * focused element had .focus-visible.\n * @param {Event} e\n */\n function onVisibilityChange(e) {\n if (document.visibilityState === 'hidden') {\n // If the tab becomes active again, the browser will handle calling focus\n // on the element (Safari actually calls it twice).\n // If this tab change caused a blur on an element with focus-visible,\n // re-apply the class when the user switches back to the tab.\n if (hadFocusVisibleRecently) {\n hadKeyboardEvent = true;\n }\n addInitialPointerMoveListeners();\n }\n }\n\n /**\n * Add a group of listeners to detect usage of any pointing devices.\n * These listeners will be added when the polyfill first loads, and anytime\n * the window is blurred, so that they are active when the window regains\n * focus.\n */\n function addInitialPointerMoveListeners() {\n document.addEventListener('mousemove', onInitialPointerMove);\n document.addEventListener('mousedown', onInitialPointerMove);\n document.addEventListener('mouseup', onInitialPointerMove);\n document.addEventListener('pointermove', onInitialPointerMove);\n document.addEventListener('pointerdown', onInitialPointerMove);\n document.addEventListener('pointerup', onInitialPointerMove);\n document.addEventListener('touchmove', onInitialPointerMove);\n document.addEventListener('touchstart', onInitialPointerMove);\n document.addEventListener('touchend', onInitialPointerMove);\n }\n\n function removeInitialPointerMoveListeners() {\n document.removeEventListener('mousemove', onInitialPointerMove);\n document.removeEventListener('mousedown', onInitialPointerMove);\n document.removeEventListener('mouseup', onInitialPointerMove);\n document.removeEventListener('pointermove', onInitialPointerMove);\n document.removeEventListener('pointerdown', onInitialPointerMove);\n document.removeEventListener('pointerup', onInitialPointerMove);\n document.removeEventListener('touchmove', onInitialPointerMove);\n document.removeEventListener('touchstart', onInitialPointerMove);\n document.removeEventListener('touchend', onInitialPointerMove);\n }\n\n /**\n * When the polfyill first loads, assume the user is in keyboard modality.\n * If any event is received from a pointing device (e.g. mouse, pointer,\n * touch), turn off keyboard modality.\n * This accounts for situations where focus enters the page from the URL bar.\n * @param {Event} e\n */\n function onInitialPointerMove(e) {\n // Work around a Safari quirk that fires a mousemove on whenever the\n // window blurs, even if you're tabbing out of the page. \u00AF\\_(\u30C4)_/\u00AF\n if (e.target.nodeName && e.target.nodeName.toLowerCase() === 'html') {\n return;\n }\n\n hadKeyboardEvent = false;\n removeInitialPointerMoveListeners();\n }\n\n // For some kinds of state, we are interested in changes at the global scope\n // only. For example, global pointer input, global key presses and global\n // visibility change should affect the state at every scope:\n document.addEventListener('keydown', onKeyDown, true);\n document.addEventListener('mousedown', onPointerDown, true);\n document.addEventListener('pointerdown', onPointerDown, true);\n document.addEventListener('touchstart', onPointerDown, true);\n document.addEventListener('visibilitychange', onVisibilityChange, true);\n\n addInitialPointerMoveListeners();\n\n // For focus and blur, we specifically care about state changes in the local\n // scope. This is because focus / blur events that originate from within a\n // shadow root are not re-dispatched from the host element if it was already\n // the active element in its own scope:\n scope.addEventListener('focus', onFocus, true);\n scope.addEventListener('blur', onBlur, true);\n\n // We detect that a node is a ShadowRoot by ensuring that it is a\n // DocumentFragment and also has a host property. This check covers native\n // implementation and polyfill implementation transparently. If we only cared\n // about the native implementation, we could just check if the scope was\n // an instance of a ShadowRoot.\n if (scope.nodeType === Node.DOCUMENT_FRAGMENT_NODE && scope.host) {\n // Since a ShadowRoot is a special kind of DocumentFragment, it does not\n // have a root element to add a class to. So, we add this attribute to the\n // host element instead:\n scope.host.setAttribute('data-js-focus-visible', '');\n } else if (scope.nodeType === Node.DOCUMENT_NODE) {\n document.documentElement.classList.add('js-focus-visible');\n document.documentElement.setAttribute('data-js-focus-visible', '');\n }\n }\n\n // It is important to wrap all references to global window and document in\n // these checks to support server-side rendering use cases\n // @see https://github.com/WICG/focus-visible/issues/199\n if (typeof window !== 'undefined' && typeof document !== 'undefined') {\n // Make the polyfill helper globally available. This can be used as a signal\n // to interested libraries that wish to coordinate with the polyfill for e.g.,\n // applying the polyfill to a shadow root:\n window.applyFocusVisiblePolyfill = applyFocusVisiblePolyfill;\n\n // Notify interested libraries of the polyfill's presence, in case the\n // polyfill was loaded lazily:\n var event;\n\n try {\n event = new CustomEvent('focus-visible-polyfill-ready');\n } catch (error) {\n // IE11 does not support using CustomEvent as a constructor directly:\n event = document.createEvent('CustomEvent');\n event.initCustomEvent('focus-visible-polyfill-ready', false, false, {});\n }\n\n window.dispatchEvent(event);\n }\n\n if (typeof document !== 'undefined') {\n // Apply the polyfill to the global document, so that no JavaScript\n // coordination is required to use the polyfill in the top-level document:\n applyFocusVisiblePolyfill(document);\n }\n\n})));\n", "/*!\n * clipboard.js v2.0.11\n * https://clipboardjs.com/\n *\n * Licensed MIT \u00A9 Zeno Rocha\n */\n(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"ClipboardJS\"] = factory();\n\telse\n\t\troot[\"ClipboardJS\"] = factory();\n})(this, function() {\nreturn /******/ (function() { // webpackBootstrap\n/******/ \tvar __webpack_modules__ = ({\n\n/***/ 686:\n/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n\n// EXPORTS\n__webpack_require__.d(__webpack_exports__, {\n \"default\": function() { return /* binding */ clipboard; }\n});\n\n// EXTERNAL MODULE: ./node_modules/tiny-emitter/index.js\nvar tiny_emitter = __webpack_require__(279);\nvar tiny_emitter_default = /*#__PURE__*/__webpack_require__.n(tiny_emitter);\n// EXTERNAL MODULE: ./node_modules/good-listener/src/listen.js\nvar listen = __webpack_require__(370);\nvar listen_default = /*#__PURE__*/__webpack_require__.n(listen);\n// EXTERNAL MODULE: ./node_modules/select/src/select.js\nvar src_select = __webpack_require__(817);\nvar select_default = /*#__PURE__*/__webpack_require__.n(src_select);\n;// CONCATENATED MODULE: ./src/common/command.js\n/**\n * Executes a given operation type.\n * @param {String} type\n * @return {Boolean}\n */\nfunction command(type) {\n try {\n return document.execCommand(type);\n } catch (err) {\n return false;\n }\n}\n;// CONCATENATED MODULE: ./src/actions/cut.js\n\n\n/**\n * Cut action wrapper.\n * @param {String|HTMLElement} target\n * @return {String}\n */\n\nvar ClipboardActionCut = function ClipboardActionCut(target) {\n var selectedText = select_default()(target);\n command('cut');\n return selectedText;\n};\n\n/* harmony default export */ var actions_cut = (ClipboardActionCut);\n;// CONCATENATED MODULE: ./src/common/create-fake-element.js\n/**\n * Creates a fake textarea element with a value.\n * @param {String} value\n * @return {HTMLElement}\n */\nfunction createFakeElement(value) {\n var isRTL = document.documentElement.getAttribute('dir') === 'rtl';\n var fakeElement = document.createElement('textarea'); // Prevent zooming on iOS\n\n fakeElement.style.fontSize = '12pt'; // Reset box model\n\n fakeElement.style.border = '0';\n fakeElement.style.padding = '0';\n fakeElement.style.margin = '0'; // Move element out of screen horizontally\n\n fakeElement.style.position = 'absolute';\n fakeElement.style[isRTL ? 'right' : 'left'] = '-9999px'; // Move element to the same position vertically\n\n var yPosition = window.pageYOffset || document.documentElement.scrollTop;\n fakeElement.style.top = \"\".concat(yPosition, \"px\");\n fakeElement.setAttribute('readonly', '');\n fakeElement.value = value;\n return fakeElement;\n}\n;// CONCATENATED MODULE: ./src/actions/copy.js\n\n\n\n/**\n * Create fake copy action wrapper using a fake element.\n * @param {String} target\n * @param {Object} options\n * @return {String}\n */\n\nvar fakeCopyAction = function fakeCopyAction(value, options) {\n var fakeElement = createFakeElement(value);\n options.container.appendChild(fakeElement);\n var selectedText = select_default()(fakeElement);\n command('copy');\n fakeElement.remove();\n return selectedText;\n};\n/**\n * Copy action wrapper.\n * @param {String|HTMLElement} target\n * @param {Object} options\n * @return {String}\n */\n\n\nvar ClipboardActionCopy = function ClipboardActionCopy(target) {\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {\n container: document.body\n };\n var selectedText = '';\n\n if (typeof target === 'string') {\n selectedText = fakeCopyAction(target, options);\n } else if (target instanceof HTMLInputElement && !['text', 'search', 'url', 'tel', 'password'].includes(target === null || target === void 0 ? void 0 : target.type)) {\n // If input type doesn't support `setSelectionRange`. Simulate it. https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/setSelectionRange\n selectedText = fakeCopyAction(target.value, options);\n } else {\n selectedText = select_default()(target);\n command('copy');\n }\n\n return selectedText;\n};\n\n/* harmony default export */ var actions_copy = (ClipboardActionCopy);\n;// CONCATENATED MODULE: ./src/actions/default.js\nfunction _typeof(obj) { \"@babel/helpers - typeof\"; if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\n\n\n/**\n * Inner function which performs selection from either `text` or `target`\n * properties and then executes copy or cut operations.\n * @param {Object} options\n */\n\nvar ClipboardActionDefault = function ClipboardActionDefault() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n // Defines base properties passed from constructor.\n var _options$action = options.action,\n action = _options$action === void 0 ? 'copy' : _options$action,\n container = options.container,\n target = options.target,\n text = options.text; // Sets the `action` to be performed which can be either 'copy' or 'cut'.\n\n if (action !== 'copy' && action !== 'cut') {\n throw new Error('Invalid \"action\" value, use either \"copy\" or \"cut\"');\n } // Sets the `target` property using an element that will be have its content copied.\n\n\n if (target !== undefined) {\n if (target && _typeof(target) === 'object' && target.nodeType === 1) {\n if (action === 'copy' && target.hasAttribute('disabled')) {\n throw new Error('Invalid \"target\" attribute. Please use \"readonly\" instead of \"disabled\" attribute');\n }\n\n if (action === 'cut' && (target.hasAttribute('readonly') || target.hasAttribute('disabled'))) {\n throw new Error('Invalid \"target\" attribute. You can\\'t cut text from elements with \"readonly\" or \"disabled\" attributes');\n }\n } else {\n throw new Error('Invalid \"target\" value, use a valid Element');\n }\n } // Define selection strategy based on `text` property.\n\n\n if (text) {\n return actions_copy(text, {\n container: container\n });\n } // Defines which selection strategy based on `target` property.\n\n\n if (target) {\n return action === 'cut' ? actions_cut(target) : actions_copy(target, {\n container: container\n });\n }\n};\n\n/* harmony default export */ var actions_default = (ClipboardActionDefault);\n;// CONCATENATED MODULE: ./src/clipboard.js\nfunction clipboard_typeof(obj) { \"@babel/helpers - typeof\"; if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { clipboard_typeof = function _typeof(obj) { return typeof obj; }; } else { clipboard_typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return clipboard_typeof(obj); }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\nfunction _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (clipboard_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _isNativeReflectConstruct() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\n\n\n\n\n\n/**\n * Helper function to retrieve attribute value.\n * @param {String} suffix\n * @param {Element} element\n */\n\nfunction getAttributeValue(suffix, element) {\n var attribute = \"data-clipboard-\".concat(suffix);\n\n if (!element.hasAttribute(attribute)) {\n return;\n }\n\n return element.getAttribute(attribute);\n}\n/**\n * Base class which takes one or more elements, adds event listeners to them,\n * and instantiates a new `ClipboardAction` on each click.\n */\n\n\nvar Clipboard = /*#__PURE__*/function (_Emitter) {\n _inherits(Clipboard, _Emitter);\n\n var _super = _createSuper(Clipboard);\n\n /**\n * @param {String|HTMLElement|HTMLCollection|NodeList} trigger\n * @param {Object} options\n */\n function Clipboard(trigger, options) {\n var _this;\n\n _classCallCheck(this, Clipboard);\n\n _this = _super.call(this);\n\n _this.resolveOptions(options);\n\n _this.listenClick(trigger);\n\n return _this;\n }\n /**\n * Defines if attributes would be resolved using internal setter functions\n * or custom functions that were passed in the constructor.\n * @param {Object} options\n */\n\n\n _createClass(Clipboard, [{\n key: \"resolveOptions\",\n value: function resolveOptions() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n this.action = typeof options.action === 'function' ? options.action : this.defaultAction;\n this.target = typeof options.target === 'function' ? options.target : this.defaultTarget;\n this.text = typeof options.text === 'function' ? options.text : this.defaultText;\n this.container = clipboard_typeof(options.container) === 'object' ? options.container : document.body;\n }\n /**\n * Adds a click event listener to the passed trigger.\n * @param {String|HTMLElement|HTMLCollection|NodeList} trigger\n */\n\n }, {\n key: \"listenClick\",\n value: function listenClick(trigger) {\n var _this2 = this;\n\n this.listener = listen_default()(trigger, 'click', function (e) {\n return _this2.onClick(e);\n });\n }\n /**\n * Defines a new `ClipboardAction` on each click event.\n * @param {Event} e\n */\n\n }, {\n key: \"onClick\",\n value: function onClick(e) {\n var trigger = e.delegateTarget || e.currentTarget;\n var action = this.action(trigger) || 'copy';\n var text = actions_default({\n action: action,\n container: this.container,\n target: this.target(trigger),\n text: this.text(trigger)\n }); // Fires an event based on the copy operation result.\n\n this.emit(text ? 'success' : 'error', {\n action: action,\n text: text,\n trigger: trigger,\n clearSelection: function clearSelection() {\n if (trigger) {\n trigger.focus();\n }\n\n window.getSelection().removeAllRanges();\n }\n });\n }\n /**\n * Default `action` lookup function.\n * @param {Element} trigger\n */\n\n }, {\n key: \"defaultAction\",\n value: function defaultAction(trigger) {\n return getAttributeValue('action', trigger);\n }\n /**\n * Default `target` lookup function.\n * @param {Element} trigger\n */\n\n }, {\n key: \"defaultTarget\",\n value: function defaultTarget(trigger) {\n var selector = getAttributeValue('target', trigger);\n\n if (selector) {\n return document.querySelector(selector);\n }\n }\n /**\n * Allow fire programmatically a copy action\n * @param {String|HTMLElement} target\n * @param {Object} options\n * @returns Text copied.\n */\n\n }, {\n key: \"defaultText\",\n\n /**\n * Default `text` lookup function.\n * @param {Element} trigger\n */\n value: function defaultText(trigger) {\n return getAttributeValue('text', trigger);\n }\n /**\n * Destroy lifecycle.\n */\n\n }, {\n key: \"destroy\",\n value: function destroy() {\n this.listener.destroy();\n }\n }], [{\n key: \"copy\",\n value: function copy(target) {\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {\n container: document.body\n };\n return actions_copy(target, options);\n }\n /**\n * Allow fire programmatically a cut action\n * @param {String|HTMLElement} target\n * @returns Text cutted.\n */\n\n }, {\n key: \"cut\",\n value: function cut(target) {\n return actions_cut(target);\n }\n /**\n * Returns the support of the given action, or all actions if no action is\n * given.\n * @param {String} [action]\n */\n\n }, {\n key: \"isSupported\",\n value: function isSupported() {\n var action = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ['copy', 'cut'];\n var actions = typeof action === 'string' ? [action] : action;\n var support = !!document.queryCommandSupported;\n actions.forEach(function (action) {\n support = support && !!document.queryCommandSupported(action);\n });\n return support;\n }\n }]);\n\n return Clipboard;\n}((tiny_emitter_default()));\n\n/* harmony default export */ var clipboard = (Clipboard);\n\n/***/ }),\n\n/***/ 828:\n/***/ (function(module) {\n\nvar DOCUMENT_NODE_TYPE = 9;\n\n/**\n * A polyfill for Element.matches()\n */\nif (typeof Element !== 'undefined' && !Element.prototype.matches) {\n var proto = Element.prototype;\n\n proto.matches = proto.matchesSelector ||\n proto.mozMatchesSelector ||\n proto.msMatchesSelector ||\n proto.oMatchesSelector ||\n proto.webkitMatchesSelector;\n}\n\n/**\n * Finds the closest parent that matches a selector.\n *\n * @param {Element} element\n * @param {String} selector\n * @return {Function}\n */\nfunction closest (element, selector) {\n while (element && element.nodeType !== DOCUMENT_NODE_TYPE) {\n if (typeof element.matches === 'function' &&\n element.matches(selector)) {\n return element;\n }\n element = element.parentNode;\n }\n}\n\nmodule.exports = closest;\n\n\n/***/ }),\n\n/***/ 438:\n/***/ (function(module, __unused_webpack_exports, __webpack_require__) {\n\nvar closest = __webpack_require__(828);\n\n/**\n * Delegates event to a selector.\n *\n * @param {Element} element\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @param {Boolean} useCapture\n * @return {Object}\n */\nfunction _delegate(element, selector, type, callback, useCapture) {\n var listenerFn = listener.apply(this, arguments);\n\n element.addEventListener(type, listenerFn, useCapture);\n\n return {\n destroy: function() {\n element.removeEventListener(type, listenerFn, useCapture);\n }\n }\n}\n\n/**\n * Delegates event to a selector.\n *\n * @param {Element|String|Array} [elements]\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @param {Boolean} useCapture\n * @return {Object}\n */\nfunction delegate(elements, selector, type, callback, useCapture) {\n // Handle the regular Element usage\n if (typeof elements.addEventListener === 'function') {\n return _delegate.apply(null, arguments);\n }\n\n // Handle Element-less usage, it defaults to global delegation\n if (typeof type === 'function') {\n // Use `document` as the first parameter, then apply arguments\n // This is a short way to .unshift `arguments` without running into deoptimizations\n return _delegate.bind(null, document).apply(null, arguments);\n }\n\n // Handle Selector-based usage\n if (typeof elements === 'string') {\n elements = document.querySelectorAll(elements);\n }\n\n // Handle Array-like based usage\n return Array.prototype.map.call(elements, function (element) {\n return _delegate(element, selector, type, callback, useCapture);\n });\n}\n\n/**\n * Finds closest match and invokes callback.\n *\n * @param {Element} element\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @return {Function}\n */\nfunction listener(element, selector, type, callback) {\n return function(e) {\n e.delegateTarget = closest(e.target, selector);\n\n if (e.delegateTarget) {\n callback.call(element, e);\n }\n }\n}\n\nmodule.exports = delegate;\n\n\n/***/ }),\n\n/***/ 879:\n/***/ (function(__unused_webpack_module, exports) {\n\n/**\n * Check if argument is a HTML element.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.node = function(value) {\n return value !== undefined\n && value instanceof HTMLElement\n && value.nodeType === 1;\n};\n\n/**\n * Check if argument is a list of HTML elements.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.nodeList = function(value) {\n var type = Object.prototype.toString.call(value);\n\n return value !== undefined\n && (type === '[object NodeList]' || type === '[object HTMLCollection]')\n && ('length' in value)\n && (value.length === 0 || exports.node(value[0]));\n};\n\n/**\n * Check if argument is a string.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.string = function(value) {\n return typeof value === 'string'\n || value instanceof String;\n};\n\n/**\n * Check if argument is a function.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.fn = function(value) {\n var type = Object.prototype.toString.call(value);\n\n return type === '[object Function]';\n};\n\n\n/***/ }),\n\n/***/ 370:\n/***/ (function(module, __unused_webpack_exports, __webpack_require__) {\n\nvar is = __webpack_require__(879);\nvar delegate = __webpack_require__(438);\n\n/**\n * Validates all params and calls the right\n * listener function based on its target type.\n *\n * @param {String|HTMLElement|HTMLCollection|NodeList} target\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listen(target, type, callback) {\n if (!target && !type && !callback) {\n throw new Error('Missing required arguments');\n }\n\n if (!is.string(type)) {\n throw new TypeError('Second argument must be a String');\n }\n\n if (!is.fn(callback)) {\n throw new TypeError('Third argument must be a Function');\n }\n\n if (is.node(target)) {\n return listenNode(target, type, callback);\n }\n else if (is.nodeList(target)) {\n return listenNodeList(target, type, callback);\n }\n else if (is.string(target)) {\n return listenSelector(target, type, callback);\n }\n else {\n throw new TypeError('First argument must be a String, HTMLElement, HTMLCollection, or NodeList');\n }\n}\n\n/**\n * Adds an event listener to a HTML element\n * and returns a remove listener function.\n *\n * @param {HTMLElement} node\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listenNode(node, type, callback) {\n node.addEventListener(type, callback);\n\n return {\n destroy: function() {\n node.removeEventListener(type, callback);\n }\n }\n}\n\n/**\n * Add an event listener to a list of HTML elements\n * and returns a remove listener function.\n *\n * @param {NodeList|HTMLCollection} nodeList\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listenNodeList(nodeList, type, callback) {\n Array.prototype.forEach.call(nodeList, function(node) {\n node.addEventListener(type, callback);\n });\n\n return {\n destroy: function() {\n Array.prototype.forEach.call(nodeList, function(node) {\n node.removeEventListener(type, callback);\n });\n }\n }\n}\n\n/**\n * Add an event listener to a selector\n * and returns a remove listener function.\n *\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listenSelector(selector, type, callback) {\n return delegate(document.body, selector, type, callback);\n}\n\nmodule.exports = listen;\n\n\n/***/ }),\n\n/***/ 817:\n/***/ (function(module) {\n\nfunction select(element) {\n var selectedText;\n\n if (element.nodeName === 'SELECT') {\n element.focus();\n\n selectedText = element.value;\n }\n else if (element.nodeName === 'INPUT' || element.nodeName === 'TEXTAREA') {\n var isReadOnly = element.hasAttribute('readonly');\n\n if (!isReadOnly) {\n element.setAttribute('readonly', '');\n }\n\n element.select();\n element.setSelectionRange(0, element.value.length);\n\n if (!isReadOnly) {\n element.removeAttribute('readonly');\n }\n\n selectedText = element.value;\n }\n else {\n if (element.hasAttribute('contenteditable')) {\n element.focus();\n }\n\n var selection = window.getSelection();\n var range = document.createRange();\n\n range.selectNodeContents(element);\n selection.removeAllRanges();\n selection.addRange(range);\n\n selectedText = selection.toString();\n }\n\n return selectedText;\n}\n\nmodule.exports = select;\n\n\n/***/ }),\n\n/***/ 279:\n/***/ (function(module) {\n\nfunction E () {\n // Keep this empty so it's easier to inherit from\n // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3)\n}\n\nE.prototype = {\n on: function (name, callback, ctx) {\n var e = this.e || (this.e = {});\n\n (e[name] || (e[name] = [])).push({\n fn: callback,\n ctx: ctx\n });\n\n return this;\n },\n\n once: function (name, callback, ctx) {\n var self = this;\n function listener () {\n self.off(name, listener);\n callback.apply(ctx, arguments);\n };\n\n listener._ = callback\n return this.on(name, listener, ctx);\n },\n\n emit: function (name) {\n var data = [].slice.call(arguments, 1);\n var evtArr = ((this.e || (this.e = {}))[name] || []).slice();\n var i = 0;\n var len = evtArr.length;\n\n for (i; i < len; i++) {\n evtArr[i].fn.apply(evtArr[i].ctx, data);\n }\n\n return this;\n },\n\n off: function (name, callback) {\n var e = this.e || (this.e = {});\n var evts = e[name];\n var liveEvents = [];\n\n if (evts && callback) {\n for (var i = 0, len = evts.length; i < len; i++) {\n if (evts[i].fn !== callback && evts[i].fn._ !== callback)\n liveEvents.push(evts[i]);\n }\n }\n\n // Remove event from queue to prevent memory leak\n // Suggested by https://github.com/lazd\n // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910\n\n (liveEvents.length)\n ? e[name] = liveEvents\n : delete e[name];\n\n return this;\n }\n};\n\nmodule.exports = E;\nmodule.exports.TinyEmitter = E;\n\n\n/***/ })\n\n/******/ \t});\n/************************************************************************/\n/******/ \t// The module cache\n/******/ \tvar __webpack_module_cache__ = {};\n/******/ \t\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(__webpack_module_cache__[moduleId]) {\n/******/ \t\t\treturn __webpack_module_cache__[moduleId].exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = __webpack_module_cache__[moduleId] = {\n/******/ \t\t\t// no module.id needed\n/******/ \t\t\t// no module.loaded needed\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/ \t\n/******/ \t\t// Execute the module function\n/******/ \t\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n/******/ \t\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/ \t\n/************************************************************************/\n/******/ \t/* webpack/runtime/compat get default export */\n/******/ \t!function() {\n/******/ \t\t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t\t__webpack_require__.n = function(module) {\n/******/ \t\t\tvar getter = module && module.__esModule ?\n/******/ \t\t\t\tfunction() { return module['default']; } :\n/******/ \t\t\t\tfunction() { return module; };\n/******/ \t\t\t__webpack_require__.d(getter, { a: getter });\n/******/ \t\t\treturn getter;\n/******/ \t\t};\n/******/ \t}();\n/******/ \t\n/******/ \t/* webpack/runtime/define property getters */\n/******/ \t!function() {\n/******/ \t\t// define getter functions for harmony exports\n/******/ \t\t__webpack_require__.d = function(exports, definition) {\n/******/ \t\t\tfor(var key in definition) {\n/******/ \t\t\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n/******/ \t\t\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n/******/ \t\t\t\t}\n/******/ \t\t\t}\n/******/ \t\t};\n/******/ \t}();\n/******/ \t\n/******/ \t/* webpack/runtime/hasOwnProperty shorthand */\n/******/ \t!function() {\n/******/ \t\t__webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }\n/******/ \t}();\n/******/ \t\n/************************************************************************/\n/******/ \t// module exports must be returned from runtime so entry inlining is disabled\n/******/ \t// startup\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(686);\n/******/ })()\n.default;\n});", "/*!\n * escape-html\n * Copyright(c) 2012-2013 TJ Holowaychuk\n * Copyright(c) 2015 Andreas Lubbe\n * Copyright(c) 2015 Tiancheng \"Timothy\" Gu\n * MIT Licensed\n */\n\n'use strict';\n\n/**\n * Module variables.\n * @private\n */\n\nvar matchHtmlRegExp = /[\"'&<>]/;\n\n/**\n * Module exports.\n * @public\n */\n\nmodule.exports = escapeHtml;\n\n/**\n * Escape special characters in the given string of html.\n *\n * @param {string} string The string to escape for inserting into HTML\n * @return {string}\n * @public\n */\n\nfunction escapeHtml(string) {\n var str = '' + string;\n var match = matchHtmlRegExp.exec(str);\n\n if (!match) {\n return str;\n }\n\n var escape;\n var html = '';\n var index = 0;\n var lastIndex = 0;\n\n for (index = match.index; index < str.length; index++) {\n switch (str.charCodeAt(index)) {\n case 34: // \"\n escape = '"';\n break;\n case 38: // &\n escape = '&';\n break;\n case 39: // '\n escape = ''';\n break;\n case 60: // <\n escape = '<';\n break;\n case 62: // >\n escape = '>';\n break;\n default:\n continue;\n }\n\n if (lastIndex !== index) {\n html += str.substring(lastIndex, index);\n }\n\n lastIndex = index + 1;\n html += escape;\n }\n\n return lastIndex !== index\n ? html + str.substring(lastIndex, index)\n : html;\n}\n", "/*\n * Copyright (c) 2016-2024 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport \"focus-visible\"\n\nimport {\n EMPTY,\n NEVER,\n Observable,\n Subject,\n defer,\n delay,\n filter,\n map,\n merge,\n mergeWith,\n shareReplay,\n switchMap\n} from \"rxjs\"\n\nimport { configuration, feature } from \"./_\"\nimport {\n at,\n getActiveElement,\n getOptionalElement,\n requestJSON,\n setLocation,\n setToggle,\n watchDocument,\n watchKeyboard,\n watchLocation,\n watchLocationTarget,\n watchMedia,\n watchPrint,\n watchScript,\n watchViewport\n} from \"./browser\"\nimport {\n getComponentElement,\n getComponentElements,\n mountAnnounce,\n mountBackToTop,\n mountConsent,\n mountContent,\n mountDialog,\n mountHeader,\n mountHeaderTitle,\n mountPalette,\n mountProgress,\n mountSearch,\n mountSearchHiglight,\n mountSidebar,\n mountSource,\n mountTableOfContents,\n mountTabs,\n watchHeader,\n watchMain\n} from \"./components\"\nimport {\n SearchIndex,\n setupClipboardJS,\n setupInstantNavigation,\n setupVersionSelector\n} from \"./integrations\"\nimport {\n patchEllipsis,\n patchIndeterminate,\n patchScrollfix,\n patchScrolllock\n} from \"./patches\"\nimport \"./polyfills\"\n\n/* ----------------------------------------------------------------------------\n * Functions - @todo refactor\n * ------------------------------------------------------------------------- */\n\n/**\n * Fetch search index\n *\n * @returns Search index observable\n */\nfunction fetchSearchIndex(): Observable {\n if (location.protocol === \"file:\") {\n return watchScript(\n `${new URL(\"search/search_index.js\", config.base)}`\n )\n .pipe(\n // @ts-ignore - @todo fix typings\n map(() => __index),\n shareReplay(1)\n )\n } else {\n return requestJSON(\n new URL(\"search/search_index.json\", config.base)\n )\n }\n}\n\n/* ----------------------------------------------------------------------------\n * Application\n * ------------------------------------------------------------------------- */\n\n/* Yay, JavaScript is available */\ndocument.documentElement.classList.remove(\"no-js\")\ndocument.documentElement.classList.add(\"js\")\n\n/* Set up navigation observables and subjects */\nconst document$ = watchDocument()\nconst location$ = watchLocation()\nconst target$ = watchLocationTarget(location$)\nconst keyboard$ = watchKeyboard()\n\n/* Set up media observables */\nconst viewport$ = watchViewport()\nconst tablet$ = watchMedia(\"(min-width: 960px)\")\nconst screen$ = watchMedia(\"(min-width: 1220px)\")\nconst print$ = watchPrint()\n\n/* Retrieve search index, if search is enabled */\nconst config = configuration()\nconst index$ = document.forms.namedItem(\"search\")\n ? fetchSearchIndex()\n : NEVER\n\n/* Set up Clipboard.js integration */\nconst alert$ = new Subject()\nsetupClipboardJS({ alert$ })\n\n/* Set up progress indicator */\nconst progress$ = new Subject()\n\n/* Set up instant navigation, if enabled */\nif (feature(\"navigation.instant\"))\n setupInstantNavigation({ location$, viewport$, progress$ })\n .subscribe(document$)\n\n/* Set up version selector */\nif (config.version?.provider === \"mike\")\n setupVersionSelector({ document$ })\n\n/* Always close drawer and search on navigation */\nmerge(location$, target$)\n .pipe(\n delay(125)\n )\n .subscribe(() => {\n setToggle(\"drawer\", false)\n setToggle(\"search\", false)\n })\n\n/* Set up global keyboard handlers */\nkeyboard$\n .pipe(\n filter(({ mode }) => mode === \"global\")\n )\n .subscribe(key => {\n switch (key.type) {\n\n /* Go to previous page */\n case \"p\":\n case \",\":\n const prev = getOptionalElement(\"link[rel=prev]\")\n if (typeof prev !== \"undefined\")\n setLocation(prev)\n break\n\n /* Go to next page */\n case \"n\":\n case \".\":\n const next = getOptionalElement(\"link[rel=next]\")\n if (typeof next !== \"undefined\")\n setLocation(next)\n break\n\n /* Expand navigation, see https://bit.ly/3ZjG5io */\n case \"Enter\":\n const active = getActiveElement()\n if (active instanceof HTMLLabelElement)\n active.click()\n }\n })\n\n/* Set up patches */\npatchEllipsis({ viewport$, document$ })\npatchIndeterminate({ document$, tablet$ })\npatchScrollfix({ document$ })\npatchScrolllock({ viewport$, tablet$ })\n\n/* Set up header and main area observable */\nconst header$ = watchHeader(getComponentElement(\"header\"), { viewport$ })\nconst main$ = document$\n .pipe(\n map(() => getComponentElement(\"main\")),\n switchMap(el => watchMain(el, { viewport$, header$ })),\n shareReplay(1)\n )\n\n/* Set up control component observables */\nconst control$ = merge(\n\n /* Consent */\n ...getComponentElements(\"consent\")\n .map(el => mountConsent(el, { target$ })),\n\n /* Dialog */\n ...getComponentElements(\"dialog\")\n .map(el => mountDialog(el, { alert$ })),\n\n /* Header */\n ...getComponentElements(\"header\")\n .map(el => mountHeader(el, { viewport$, header$, main$ })),\n\n /* Color palette */\n ...getComponentElements(\"palette\")\n .map(el => mountPalette(el)),\n\n /* Progress bar */\n ...getComponentElements(\"progress\")\n .map(el => mountProgress(el, { progress$ })),\n\n /* Search */\n ...getComponentElements(\"search\")\n .map(el => mountSearch(el, { index$, keyboard$ })),\n\n /* Repository information */\n ...getComponentElements(\"source\")\n .map(el => mountSource(el))\n)\n\n/* Set up content component observables */\nconst content$ = defer(() => merge(\n\n /* Announcement bar */\n ...getComponentElements(\"announce\")\n .map(el => mountAnnounce(el)),\n\n /* Content */\n ...getComponentElements(\"content\")\n .map(el => mountContent(el, { viewport$, target$, print$ })),\n\n /* Search highlighting */\n ...getComponentElements(\"content\")\n .map(el => feature(\"search.highlight\")\n ? mountSearchHiglight(el, { index$, location$ })\n : EMPTY\n ),\n\n /* Header title */\n ...getComponentElements(\"header-title\")\n .map(el => mountHeaderTitle(el, { viewport$, header$ })),\n\n /* Sidebar */\n ...getComponentElements(\"sidebar\")\n .map(el => el.getAttribute(\"data-md-type\") === \"navigation\"\n ? at(screen$, () => mountSidebar(el, { viewport$, header$, main$ }))\n : at(tablet$, () => mountSidebar(el, { viewport$, header$, main$ }))\n ),\n\n /* Navigation tabs */\n ...getComponentElements(\"tabs\")\n .map(el => mountTabs(el, { viewport$, header$ })),\n\n /* Table of contents */\n ...getComponentElements(\"toc\")\n .map(el => mountTableOfContents(el, {\n viewport$, header$, main$, target$\n })),\n\n /* Back-to-top button */\n ...getComponentElements(\"top\")\n .map(el => mountBackToTop(el, { viewport$, header$, main$, target$ }))\n))\n\n/* Set up component observables */\nconst component$ = document$\n .pipe(\n switchMap(() => content$),\n mergeWith(control$),\n shareReplay(1)\n )\n\n/* Subscribe to all components */\ncomponent$.subscribe()\n\n/* ----------------------------------------------------------------------------\n * Exports\n * ------------------------------------------------------------------------- */\n\nwindow.document$ = document$ /* Document observable */\nwindow.location$ = location$ /* Location subject */\nwindow.target$ = target$ /* Location target observable */\nwindow.keyboard$ = keyboard$ /* Keyboard observable */\nwindow.viewport$ = viewport$ /* Viewport observable */\nwindow.tablet$ = tablet$ /* Media tablet observable */\nwindow.screen$ = screen$ /* Media screen observable */\nwindow.print$ = print$ /* Media print observable */\nwindow.alert$ = alert$ /* Alert subject */\nwindow.progress$ = progress$ /* Progress indicator subject */\nwindow.component$ = component$ /* Component observable */\n", "/*! *****************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise */\r\n\r\nvar extendStatics = function(d, b) {\r\n extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\r\n return extendStatics(d, b);\r\n};\r\n\r\nexport function __extends(d, b) {\r\n if (typeof b !== \"function\" && b !== null)\r\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nexport var __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n }\r\n return __assign.apply(this, arguments);\r\n}\r\n\r\nexport function __rest(s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n t[p[i]] = s[p[i]];\r\n }\r\n return t;\r\n}\r\n\r\nexport function __decorate(decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __metadata(metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nexport function __awaiter(thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\nexport function __generator(thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (_) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n}\r\n\r\nexport var __createBinding = Object.create ? (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\r\n}) : (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n o[k2] = m[k];\r\n});\r\n\r\nexport function __exportStar(m, o) {\r\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\r\n}\r\n\r\nexport function __values(o) {\r\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\r\n if (m) return m.call(o);\r\n if (o && typeof o.length === \"number\") return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\r\n}\r\n\r\nexport function __read(o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spread() {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spreadArrays() {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n}\r\n\r\nexport function __spreadArray(to, from, pack) {\r\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\r\n if (ar || !(i in from)) {\r\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\r\n ar[i] = from[i];\r\n }\r\n }\r\n return to.concat(ar || Array.prototype.slice.call(from));\r\n}\r\n\r\nexport function __await(v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nexport function __asyncGenerator(thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nexport function __asyncDelegator(o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === \"return\" } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nexport function __asyncValues(o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nexport function __makeTemplateObject(cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n};\r\n\r\nvar __setModuleDefault = Object.create ? (function(o, v) {\r\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\r\n}) : function(o, v) {\r\n o[\"default\"] = v;\r\n};\r\n\r\nexport function __importStar(mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\r\n __setModuleDefault(result, mod);\r\n return result;\r\n}\r\n\r\nexport function __importDefault(mod) {\r\n return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n\r\nexport function __classPrivateFieldGet(receiver, state, kind, f) {\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\r\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\r\n}\r\n\r\nexport function __classPrivateFieldSet(receiver, state, value, kind, f) {\r\n if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\r\n return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\r\n}\r\n", "/**\n * Returns true if the object is a function.\n * @param value The value to check\n */\nexport function isFunction(value: any): value is (...args: any[]) => any {\n return typeof value === 'function';\n}\n", "/**\n * Used to create Error subclasses until the community moves away from ES5.\n *\n * This is because compiling from TypeScript down to ES5 has issues with subclassing Errors\n * as well as other built-in types: https://github.com/Microsoft/TypeScript/issues/12123\n *\n * @param createImpl A factory function to create the actual constructor implementation. The returned\n * function should be a named function that calls `_super` internally.\n */\nexport function createErrorClass(createImpl: (_super: any) => any): T {\n const _super = (instance: any) => {\n Error.call(instance);\n instance.stack = new Error().stack;\n };\n\n const ctorFunc = createImpl(_super);\n ctorFunc.prototype = Object.create(Error.prototype);\n ctorFunc.prototype.constructor = ctorFunc;\n return ctorFunc;\n}\n", "import { createErrorClass } from './createErrorClass';\n\nexport interface UnsubscriptionError extends Error {\n readonly errors: any[];\n}\n\nexport interface UnsubscriptionErrorCtor {\n /**\n * @deprecated Internal implementation detail. Do not construct error instances.\n * Cannot be tagged as internal: https://github.com/ReactiveX/rxjs/issues/6269\n */\n new (errors: any[]): UnsubscriptionError;\n}\n\n/**\n * An error thrown when one or more errors have occurred during the\n * `unsubscribe` of a {@link Subscription}.\n */\nexport const UnsubscriptionError: UnsubscriptionErrorCtor = createErrorClass(\n (_super) =>\n function UnsubscriptionErrorImpl(this: any, errors: (Error | string)[]) {\n _super(this);\n this.message = errors\n ? `${errors.length} errors occurred during unsubscription:\n${errors.map((err, i) => `${i + 1}) ${err.toString()}`).join('\\n ')}`\n : '';\n this.name = 'UnsubscriptionError';\n this.errors = errors;\n }\n);\n", "/**\n * Removes an item from an array, mutating it.\n * @param arr The array to remove the item from\n * @param item The item to remove\n */\nexport function arrRemove(arr: T[] | undefined | null, item: T) {\n if (arr) {\n const index = arr.indexOf(item);\n 0 <= index && arr.splice(index, 1);\n }\n}\n", "import { isFunction } from './util/isFunction';\nimport { UnsubscriptionError } from './util/UnsubscriptionError';\nimport { SubscriptionLike, TeardownLogic, Unsubscribable } from './types';\nimport { arrRemove } from './util/arrRemove';\n\n/**\n * Represents a disposable resource, such as the execution of an Observable. A\n * Subscription has one important method, `unsubscribe`, that takes no argument\n * and just disposes the resource held by the subscription.\n *\n * Additionally, subscriptions may be grouped together through the `add()`\n * method, which will attach a child Subscription to the current Subscription.\n * When a Subscription is unsubscribed, all its children (and its grandchildren)\n * will be unsubscribed as well.\n *\n * @class Subscription\n */\nexport class Subscription implements SubscriptionLike {\n /** @nocollapse */\n public static EMPTY = (() => {\n const empty = new Subscription();\n empty.closed = true;\n return empty;\n })();\n\n /**\n * A flag to indicate whether this Subscription has already been unsubscribed.\n */\n public closed = false;\n\n private _parentage: Subscription[] | Subscription | null = null;\n\n /**\n * The list of registered finalizers to execute upon unsubscription. Adding and removing from this\n * list occurs in the {@link #add} and {@link #remove} methods.\n */\n private _finalizers: Exclude[] | null = null;\n\n /**\n * @param initialTeardown A function executed first as part of the finalization\n * process that is kicked off when {@link #unsubscribe} is called.\n */\n constructor(private initialTeardown?: () => void) {}\n\n /**\n * Disposes the resources held by the subscription. May, for instance, cancel\n * an ongoing Observable execution or cancel any other type of work that\n * started when the Subscription was created.\n * @return {void}\n */\n unsubscribe(): void {\n let errors: any[] | undefined;\n\n if (!this.closed) {\n this.closed = true;\n\n // Remove this from it's parents.\n const { _parentage } = this;\n if (_parentage) {\n this._parentage = null;\n if (Array.isArray(_parentage)) {\n for (const parent of _parentage) {\n parent.remove(this);\n }\n } else {\n _parentage.remove(this);\n }\n }\n\n const { initialTeardown: initialFinalizer } = this;\n if (isFunction(initialFinalizer)) {\n try {\n initialFinalizer();\n } catch (e) {\n errors = e instanceof UnsubscriptionError ? e.errors : [e];\n }\n }\n\n const { _finalizers } = this;\n if (_finalizers) {\n this._finalizers = null;\n for (const finalizer of _finalizers) {\n try {\n execFinalizer(finalizer);\n } catch (err) {\n errors = errors ?? [];\n if (err instanceof UnsubscriptionError) {\n errors = [...errors, ...err.errors];\n } else {\n errors.push(err);\n }\n }\n }\n }\n\n if (errors) {\n throw new UnsubscriptionError(errors);\n }\n }\n }\n\n /**\n * Adds a finalizer to this subscription, so that finalization will be unsubscribed/called\n * when this subscription is unsubscribed. If this subscription is already {@link #closed},\n * because it has already been unsubscribed, then whatever finalizer is passed to it\n * will automatically be executed (unless the finalizer itself is also a closed subscription).\n *\n * Closed Subscriptions cannot be added as finalizers to any subscription. Adding a closed\n * subscription to a any subscription will result in no operation. (A noop).\n *\n * Adding a subscription to itself, or adding `null` or `undefined` will not perform any\n * operation at all. (A noop).\n *\n * `Subscription` instances that are added to this instance will automatically remove themselves\n * if they are unsubscribed. Functions and {@link Unsubscribable} objects that you wish to remove\n * will need to be removed manually with {@link #remove}\n *\n * @param teardown The finalization logic to add to this subscription.\n */\n add(teardown: TeardownLogic): void {\n // Only add the finalizer if it's not undefined\n // and don't add a subscription to itself.\n if (teardown && teardown !== this) {\n if (this.closed) {\n // If this subscription is already closed,\n // execute whatever finalizer is handed to it automatically.\n execFinalizer(teardown);\n } else {\n if (teardown instanceof Subscription) {\n // We don't add closed subscriptions, and we don't add the same subscription\n // twice. Subscription unsubscribe is idempotent.\n if (teardown.closed || teardown._hasParent(this)) {\n return;\n }\n teardown._addParent(this);\n }\n (this._finalizers = this._finalizers ?? []).push(teardown);\n }\n }\n }\n\n /**\n * Checks to see if a this subscription already has a particular parent.\n * This will signal that this subscription has already been added to the parent in question.\n * @param parent the parent to check for\n */\n private _hasParent(parent: Subscription) {\n const { _parentage } = this;\n return _parentage === parent || (Array.isArray(_parentage) && _parentage.includes(parent));\n }\n\n /**\n * Adds a parent to this subscription so it can be removed from the parent if it\n * unsubscribes on it's own.\n *\n * NOTE: THIS ASSUMES THAT {@link _hasParent} HAS ALREADY BEEN CHECKED.\n * @param parent The parent subscription to add\n */\n private _addParent(parent: Subscription) {\n const { _parentage } = this;\n this._parentage = Array.isArray(_parentage) ? (_parentage.push(parent), _parentage) : _parentage ? [_parentage, parent] : parent;\n }\n\n /**\n * Called on a child when it is removed via {@link #remove}.\n * @param parent The parent to remove\n */\n private _removeParent(parent: Subscription) {\n const { _parentage } = this;\n if (_parentage === parent) {\n this._parentage = null;\n } else if (Array.isArray(_parentage)) {\n arrRemove(_parentage, parent);\n }\n }\n\n /**\n * Removes a finalizer from this subscription that was previously added with the {@link #add} method.\n *\n * Note that `Subscription` instances, when unsubscribed, will automatically remove themselves\n * from every other `Subscription` they have been added to. This means that using the `remove` method\n * is not a common thing and should be used thoughtfully.\n *\n * If you add the same finalizer instance of a function or an unsubscribable object to a `Subscription` instance\n * more than once, you will need to call `remove` the same number of times to remove all instances.\n *\n * All finalizer instances are removed to free up memory upon unsubscription.\n *\n * @param teardown The finalizer to remove from this subscription\n */\n remove(teardown: Exclude): void {\n const { _finalizers } = this;\n _finalizers && arrRemove(_finalizers, teardown);\n\n if (teardown instanceof Subscription) {\n teardown._removeParent(this);\n }\n }\n}\n\nexport const EMPTY_SUBSCRIPTION = Subscription.EMPTY;\n\nexport function isSubscription(value: any): value is Subscription {\n return (\n value instanceof Subscription ||\n (value && 'closed' in value && isFunction(value.remove) && isFunction(value.add) && isFunction(value.unsubscribe))\n );\n}\n\nfunction execFinalizer(finalizer: Unsubscribable | (() => void)) {\n if (isFunction(finalizer)) {\n finalizer();\n } else {\n finalizer.unsubscribe();\n }\n}\n", "import { Subscriber } from './Subscriber';\nimport { ObservableNotification } from './types';\n\n/**\n * The {@link GlobalConfig} object for RxJS. It is used to configure things\n * like how to react on unhandled errors.\n */\nexport const config: GlobalConfig = {\n onUnhandledError: null,\n onStoppedNotification: null,\n Promise: undefined,\n useDeprecatedSynchronousErrorHandling: false,\n useDeprecatedNextContext: false,\n};\n\n/**\n * The global configuration object for RxJS, used to configure things\n * like how to react on unhandled errors. Accessible via {@link config}\n * object.\n */\nexport interface GlobalConfig {\n /**\n * A registration point for unhandled errors from RxJS. These are errors that\n * cannot were not handled by consuming code in the usual subscription path. For\n * example, if you have this configured, and you subscribe to an observable without\n * providing an error handler, errors from that subscription will end up here. This\n * will _always_ be called asynchronously on another job in the runtime. This is because\n * we do not want errors thrown in this user-configured handler to interfere with the\n * behavior of the library.\n */\n onUnhandledError: ((err: any) => void) | null;\n\n /**\n * A registration point for notifications that cannot be sent to subscribers because they\n * have completed, errored or have been explicitly unsubscribed. By default, next, complete\n * and error notifications sent to stopped subscribers are noops. However, sometimes callers\n * might want a different behavior. For example, with sources that attempt to report errors\n * to stopped subscribers, a caller can configure RxJS to throw an unhandled error instead.\n * This will _always_ be called asynchronously on another job in the runtime. This is because\n * we do not want errors thrown in this user-configured handler to interfere with the\n * behavior of the library.\n */\n onStoppedNotification: ((notification: ObservableNotification, subscriber: Subscriber) => void) | null;\n\n /**\n * The promise constructor used by default for {@link Observable#toPromise toPromise} and {@link Observable#forEach forEach}\n * methods.\n *\n * @deprecated As of version 8, RxJS will no longer support this sort of injection of a\n * Promise constructor. If you need a Promise implementation other than native promises,\n * please polyfill/patch Promise as you see appropriate. Will be removed in v8.\n */\n Promise?: PromiseConstructorLike;\n\n /**\n * If true, turns on synchronous error rethrowing, which is a deprecated behavior\n * in v6 and higher. This behavior enables bad patterns like wrapping a subscribe\n * call in a try/catch block. It also enables producer interference, a nasty bug\n * where a multicast can be broken for all observers by a downstream consumer with\n * an unhandled error. DO NOT USE THIS FLAG UNLESS IT'S NEEDED TO BUY TIME\n * FOR MIGRATION REASONS.\n *\n * @deprecated As of version 8, RxJS will no longer support synchronous throwing\n * of unhandled errors. All errors will be thrown on a separate call stack to prevent bad\n * behaviors described above. Will be removed in v8.\n */\n useDeprecatedSynchronousErrorHandling: boolean;\n\n /**\n * If true, enables an as-of-yet undocumented feature from v5: The ability to access\n * `unsubscribe()` via `this` context in `next` functions created in observers passed\n * to `subscribe`.\n *\n * This is being removed because the performance was severely problematic, and it could also cause\n * issues when types other than POJOs are passed to subscribe as subscribers, as they will likely have\n * their `this` context overwritten.\n *\n * @deprecated As of version 8, RxJS will no longer support altering the\n * context of next functions provided as part of an observer to Subscribe. Instead,\n * you will have access to a subscription or a signal or token that will allow you to do things like\n * unsubscribe and test closed status. Will be removed in v8.\n */\n useDeprecatedNextContext: boolean;\n}\n", "import type { TimerHandle } from './timerHandle';\ntype SetTimeoutFunction = (handler: () => void, timeout?: number, ...args: any[]) => TimerHandle;\ntype ClearTimeoutFunction = (handle: TimerHandle) => void;\n\ninterface TimeoutProvider {\n setTimeout: SetTimeoutFunction;\n clearTimeout: ClearTimeoutFunction;\n delegate:\n | {\n setTimeout: SetTimeoutFunction;\n clearTimeout: ClearTimeoutFunction;\n }\n | undefined;\n}\n\nexport const timeoutProvider: TimeoutProvider = {\n // When accessing the delegate, use the variable rather than `this` so that\n // the functions can be called without being bound to the provider.\n setTimeout(handler: () => void, timeout?: number, ...args) {\n const { delegate } = timeoutProvider;\n if (delegate?.setTimeout) {\n return delegate.setTimeout(handler, timeout, ...args);\n }\n return setTimeout(handler, timeout, ...args);\n },\n clearTimeout(handle) {\n const { delegate } = timeoutProvider;\n return (delegate?.clearTimeout || clearTimeout)(handle as any);\n },\n delegate: undefined,\n};\n", "import { config } from '../config';\nimport { timeoutProvider } from '../scheduler/timeoutProvider';\n\n/**\n * Handles an error on another job either with the user-configured {@link onUnhandledError},\n * or by throwing it on that new job so it can be picked up by `window.onerror`, `process.on('error')`, etc.\n *\n * This should be called whenever there is an error that is out-of-band with the subscription\n * or when an error hits a terminal boundary of the subscription and no error handler was provided.\n *\n * @param err the error to report\n */\nexport function reportUnhandledError(err: any) {\n timeoutProvider.setTimeout(() => {\n const { onUnhandledError } = config;\n if (onUnhandledError) {\n // Execute the user-configured error handler.\n onUnhandledError(err);\n } else {\n // Throw so it is picked up by the runtime's uncaught error mechanism.\n throw err;\n }\n });\n}\n", "/* tslint:disable:no-empty */\nexport function noop() { }\n", "import { CompleteNotification, NextNotification, ErrorNotification } from './types';\n\n/**\n * A completion object optimized for memory use and created to be the\n * same \"shape\" as other notifications in v8.\n * @internal\n */\nexport const COMPLETE_NOTIFICATION = (() => createNotification('C', undefined, undefined) as CompleteNotification)();\n\n/**\n * Internal use only. Creates an optimized error notification that is the same \"shape\"\n * as other notifications.\n * @internal\n */\nexport function errorNotification(error: any): ErrorNotification {\n return createNotification('E', undefined, error) as any;\n}\n\n/**\n * Internal use only. Creates an optimized next notification that is the same \"shape\"\n * as other notifications.\n * @internal\n */\nexport function nextNotification(value: T) {\n return createNotification('N', value, undefined) as NextNotification;\n}\n\n/**\n * Ensures that all notifications created internally have the same \"shape\" in v8.\n *\n * TODO: This is only exported to support a crazy legacy test in `groupBy`.\n * @internal\n */\nexport function createNotification(kind: 'N' | 'E' | 'C', value: any, error: any) {\n return {\n kind,\n value,\n error,\n };\n}\n", "import { config } from '../config';\n\nlet context: { errorThrown: boolean; error: any } | null = null;\n\n/**\n * Handles dealing with errors for super-gross mode. Creates a context, in which\n * any synchronously thrown errors will be passed to {@link captureError}. Which\n * will record the error such that it will be rethrown after the call back is complete.\n * TODO: Remove in v8\n * @param cb An immediately executed function.\n */\nexport function errorContext(cb: () => void) {\n if (config.useDeprecatedSynchronousErrorHandling) {\n const isRoot = !context;\n if (isRoot) {\n context = { errorThrown: false, error: null };\n }\n cb();\n if (isRoot) {\n const { errorThrown, error } = context!;\n context = null;\n if (errorThrown) {\n throw error;\n }\n }\n } else {\n // This is the general non-deprecated path for everyone that\n // isn't crazy enough to use super-gross mode (useDeprecatedSynchronousErrorHandling)\n cb();\n }\n}\n\n/**\n * Captures errors only in super-gross mode.\n * @param err the error to capture\n */\nexport function captureError(err: any) {\n if (config.useDeprecatedSynchronousErrorHandling && context) {\n context.errorThrown = true;\n context.error = err;\n }\n}\n", "import { isFunction } from './util/isFunction';\nimport { Observer, ObservableNotification } from './types';\nimport { isSubscription, Subscription } from './Subscription';\nimport { config } from './config';\nimport { reportUnhandledError } from './util/reportUnhandledError';\nimport { noop } from './util/noop';\nimport { nextNotification, errorNotification, COMPLETE_NOTIFICATION } from './NotificationFactories';\nimport { timeoutProvider } from './scheduler/timeoutProvider';\nimport { captureError } from './util/errorContext';\n\n/**\n * Implements the {@link Observer} interface and extends the\n * {@link Subscription} class. While the {@link Observer} is the public API for\n * consuming the values of an {@link Observable}, all Observers get converted to\n * a Subscriber, in order to provide Subscription-like capabilities such as\n * `unsubscribe`. Subscriber is a common type in RxJS, and crucial for\n * implementing operators, but it is rarely used as a public API.\n *\n * @class Subscriber\n */\nexport class Subscriber extends Subscription implements Observer {\n /**\n * A static factory for a Subscriber, given a (potentially partial) definition\n * of an Observer.\n * @param next The `next` callback of an Observer.\n * @param error The `error` callback of an\n * Observer.\n * @param complete The `complete` callback of an\n * Observer.\n * @return A Subscriber wrapping the (partially defined)\n * Observer represented by the given arguments.\n * @nocollapse\n * @deprecated Do not use. Will be removed in v8. There is no replacement for this\n * method, and there is no reason to be creating instances of `Subscriber` directly.\n * If you have a specific use case, please file an issue.\n */\n static create(next?: (x?: T) => void, error?: (e?: any) => void, complete?: () => void): Subscriber {\n return new SafeSubscriber(next, error, complete);\n }\n\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n protected isStopped: boolean = false;\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n protected destination: Subscriber | Observer; // this `any` is the escape hatch to erase extra type param (e.g. R)\n\n /**\n * @deprecated Internal implementation detail, do not use directly. Will be made internal in v8.\n * There is no reason to directly create an instance of Subscriber. This type is exported for typings reasons.\n */\n constructor(destination?: Subscriber | Observer) {\n super();\n if (destination) {\n this.destination = destination;\n // Automatically chain subscriptions together here.\n // if destination is a Subscription, then it is a Subscriber.\n if (isSubscription(destination)) {\n destination.add(this);\n }\n } else {\n this.destination = EMPTY_OBSERVER;\n }\n }\n\n /**\n * The {@link Observer} callback to receive notifications of type `next` from\n * the Observable, with a value. The Observable may call this method 0 or more\n * times.\n * @param {T} [value] The `next` value.\n * @return {void}\n */\n next(value?: T): void {\n if (this.isStopped) {\n handleStoppedNotification(nextNotification(value), this);\n } else {\n this._next(value!);\n }\n }\n\n /**\n * The {@link Observer} callback to receive notifications of type `error` from\n * the Observable, with an attached `Error`. Notifies the Observer that\n * the Observable has experienced an error condition.\n * @param {any} [err] The `error` exception.\n * @return {void}\n */\n error(err?: any): void {\n if (this.isStopped) {\n handleStoppedNotification(errorNotification(err), this);\n } else {\n this.isStopped = true;\n this._error(err);\n }\n }\n\n /**\n * The {@link Observer} callback to receive a valueless notification of type\n * `complete` from the Observable. Notifies the Observer that the Observable\n * has finished sending push-based notifications.\n * @return {void}\n */\n complete(): void {\n if (this.isStopped) {\n handleStoppedNotification(COMPLETE_NOTIFICATION, this);\n } else {\n this.isStopped = true;\n this._complete();\n }\n }\n\n unsubscribe(): void {\n if (!this.closed) {\n this.isStopped = true;\n super.unsubscribe();\n this.destination = null!;\n }\n }\n\n protected _next(value: T): void {\n this.destination.next(value);\n }\n\n protected _error(err: any): void {\n try {\n this.destination.error(err);\n } finally {\n this.unsubscribe();\n }\n }\n\n protected _complete(): void {\n try {\n this.destination.complete();\n } finally {\n this.unsubscribe();\n }\n }\n}\n\n/**\n * This bind is captured here because we want to be able to have\n * compatibility with monoid libraries that tend to use a method named\n * `bind`. In particular, a library called Monio requires this.\n */\nconst _bind = Function.prototype.bind;\n\nfunction bind any>(fn: Fn, thisArg: any): Fn {\n return _bind.call(fn, thisArg);\n}\n\n/**\n * Internal optimization only, DO NOT EXPOSE.\n * @internal\n */\nclass ConsumerObserver implements Observer {\n constructor(private partialObserver: Partial>) {}\n\n next(value: T): void {\n const { partialObserver } = this;\n if (partialObserver.next) {\n try {\n partialObserver.next(value);\n } catch (error) {\n handleUnhandledError(error);\n }\n }\n }\n\n error(err: any): void {\n const { partialObserver } = this;\n if (partialObserver.error) {\n try {\n partialObserver.error(err);\n } catch (error) {\n handleUnhandledError(error);\n }\n } else {\n handleUnhandledError(err);\n }\n }\n\n complete(): void {\n const { partialObserver } = this;\n if (partialObserver.complete) {\n try {\n partialObserver.complete();\n } catch (error) {\n handleUnhandledError(error);\n }\n }\n }\n}\n\nexport class SafeSubscriber extends Subscriber {\n constructor(\n observerOrNext?: Partial> | ((value: T) => void) | null,\n error?: ((e?: any) => void) | null,\n complete?: (() => void) | null\n ) {\n super();\n\n let partialObserver: Partial>;\n if (isFunction(observerOrNext) || !observerOrNext) {\n // The first argument is a function, not an observer. The next\n // two arguments *could* be observers, or they could be empty.\n partialObserver = {\n next: (observerOrNext ?? undefined) as (((value: T) => void) | undefined),\n error: error ?? undefined,\n complete: complete ?? undefined,\n };\n } else {\n // The first argument is a partial observer.\n let context: any;\n if (this && config.useDeprecatedNextContext) {\n // This is a deprecated path that made `this.unsubscribe()` available in\n // next handler functions passed to subscribe. This only exists behind a flag\n // now, as it is *very* slow.\n context = Object.create(observerOrNext);\n context.unsubscribe = () => this.unsubscribe();\n partialObserver = {\n next: observerOrNext.next && bind(observerOrNext.next, context),\n error: observerOrNext.error && bind(observerOrNext.error, context),\n complete: observerOrNext.complete && bind(observerOrNext.complete, context),\n };\n } else {\n // The \"normal\" path. Just use the partial observer directly.\n partialObserver = observerOrNext;\n }\n }\n\n // Wrap the partial observer to ensure it's a full observer, and\n // make sure proper error handling is accounted for.\n this.destination = new ConsumerObserver(partialObserver);\n }\n}\n\nfunction handleUnhandledError(error: any) {\n if (config.useDeprecatedSynchronousErrorHandling) {\n captureError(error);\n } else {\n // Ideal path, we report this as an unhandled error,\n // which is thrown on a new call stack.\n reportUnhandledError(error);\n }\n}\n\n/**\n * An error handler used when no error handler was supplied\n * to the SafeSubscriber -- meaning no error handler was supplied\n * do the `subscribe` call on our observable.\n * @param err The error to handle\n */\nfunction defaultErrorHandler(err: any) {\n throw err;\n}\n\n/**\n * A handler for notifications that cannot be sent to a stopped subscriber.\n * @param notification The notification being sent\n * @param subscriber The stopped subscriber\n */\nfunction handleStoppedNotification(notification: ObservableNotification, subscriber: Subscriber) {\n const { onStoppedNotification } = config;\n onStoppedNotification && timeoutProvider.setTimeout(() => onStoppedNotification(notification, subscriber));\n}\n\n/**\n * The observer used as a stub for subscriptions where the user did not\n * pass any arguments to `subscribe`. Comes with the default error handling\n * behavior.\n */\nexport const EMPTY_OBSERVER: Readonly> & { closed: true } = {\n closed: true,\n next: noop,\n error: defaultErrorHandler,\n complete: noop,\n};\n", "/**\n * Symbol.observable or a string \"@@observable\". Used for interop\n *\n * @deprecated We will no longer be exporting this symbol in upcoming versions of RxJS.\n * Instead polyfill and use Symbol.observable directly *or* use https://www.npmjs.com/package/symbol-observable\n */\nexport const observable: string | symbol = (() => (typeof Symbol === 'function' && Symbol.observable) || '@@observable')();\n", "/**\n * This function takes one parameter and just returns it. Simply put,\n * this is like `(x: T): T => x`.\n *\n * ## Examples\n *\n * This is useful in some cases when using things like `mergeMap`\n *\n * ```ts\n * import { interval, take, map, range, mergeMap, identity } from 'rxjs';\n *\n * const source$ = interval(1000).pipe(take(5));\n *\n * const result$ = source$.pipe(\n * map(i => range(i)),\n * mergeMap(identity) // same as mergeMap(x => x)\n * );\n *\n * result$.subscribe({\n * next: console.log\n * });\n * ```\n *\n * Or when you want to selectively apply an operator\n *\n * ```ts\n * import { interval, take, identity } from 'rxjs';\n *\n * const shouldLimit = () => Math.random() < 0.5;\n *\n * const source$ = interval(1000);\n *\n * const result$ = source$.pipe(shouldLimit() ? take(5) : identity);\n *\n * result$.subscribe({\n * next: console.log\n * });\n * ```\n *\n * @param x Any value that is returned by this function\n * @returns The value passed as the first parameter to this function\n */\nexport function identity(x: T): T {\n return x;\n}\n", "import { identity } from './identity';\nimport { UnaryFunction } from '../types';\n\nexport function pipe(): typeof identity;\nexport function pipe(fn1: UnaryFunction): UnaryFunction;\nexport function pipe(fn1: UnaryFunction, fn2: UnaryFunction): UnaryFunction;\nexport function pipe(fn1: UnaryFunction, fn2: UnaryFunction, fn3: UnaryFunction): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction,\n fn6: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction,\n fn6: UnaryFunction,\n fn7: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction,\n fn6: UnaryFunction,\n fn7: UnaryFunction,\n fn8: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction,\n fn6: UnaryFunction,\n fn7: UnaryFunction,\n fn8: UnaryFunction,\n fn9: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction,\n fn6: UnaryFunction,\n fn7: UnaryFunction,\n fn8: UnaryFunction,\n fn9: UnaryFunction,\n ...fns: UnaryFunction[]\n): UnaryFunction;\n\n/**\n * pipe() can be called on one or more functions, each of which can take one argument (\"UnaryFunction\")\n * and uses it to return a value.\n * It returns a function that takes one argument, passes it to the first UnaryFunction, and then\n * passes the result to the next one, passes that result to the next one, and so on. \n */\nexport function pipe(...fns: Array>): UnaryFunction {\n return pipeFromArray(fns);\n}\n\n/** @internal */\nexport function pipeFromArray(fns: Array>): UnaryFunction {\n if (fns.length === 0) {\n return identity as UnaryFunction;\n }\n\n if (fns.length === 1) {\n return fns[0];\n }\n\n return function piped(input: T): R {\n return fns.reduce((prev: any, fn: UnaryFunction) => fn(prev), input as any);\n };\n}\n", "import { Operator } from './Operator';\nimport { SafeSubscriber, Subscriber } from './Subscriber';\nimport { isSubscription, Subscription } from './Subscription';\nimport { TeardownLogic, OperatorFunction, Subscribable, Observer } from './types';\nimport { observable as Symbol_observable } from './symbol/observable';\nimport { pipeFromArray } from './util/pipe';\nimport { config } from './config';\nimport { isFunction } from './util/isFunction';\nimport { errorContext } from './util/errorContext';\n\n/**\n * A representation of any set of values over any amount of time. This is the most basic building block\n * of RxJS.\n *\n * @class Observable\n */\nexport class Observable implements Subscribable {\n /**\n * @deprecated Internal implementation detail, do not use directly. Will be made internal in v8.\n */\n source: Observable | undefined;\n\n /**\n * @deprecated Internal implementation detail, do not use directly. Will be made internal in v8.\n */\n operator: Operator | undefined;\n\n /**\n * @constructor\n * @param {Function} subscribe the function that is called when the Observable is\n * initially subscribed to. This function is given a Subscriber, to which new values\n * can be `next`ed, or an `error` method can be called to raise an error, or\n * `complete` can be called to notify of a successful completion.\n */\n constructor(subscribe?: (this: Observable, subscriber: Subscriber) => TeardownLogic) {\n if (subscribe) {\n this._subscribe = subscribe;\n }\n }\n\n // HACK: Since TypeScript inherits static properties too, we have to\n // fight against TypeScript here so Subject can have a different static create signature\n /**\n * Creates a new Observable by calling the Observable constructor\n * @owner Observable\n * @method create\n * @param {Function} subscribe? the subscriber function to be passed to the Observable constructor\n * @return {Observable} a new observable\n * @nocollapse\n * @deprecated Use `new Observable()` instead. Will be removed in v8.\n */\n static create: (...args: any[]) => any = (subscribe?: (subscriber: Subscriber) => TeardownLogic) => {\n return new Observable(subscribe);\n };\n\n /**\n * Creates a new Observable, with this Observable instance as the source, and the passed\n * operator defined as the new observable's operator.\n * @method lift\n * @param operator the operator defining the operation to take on the observable\n * @return a new observable with the Operator applied\n * @deprecated Internal implementation detail, do not use directly. Will be made internal in v8.\n * If you have implemented an operator using `lift`, it is recommended that you create an\n * operator by simply returning `new Observable()` directly. See \"Creating new operators from\n * scratch\" section here: https://rxjs.dev/guide/operators\n */\n lift(operator?: Operator): Observable {\n const observable = new Observable();\n observable.source = this;\n observable.operator = operator;\n return observable;\n }\n\n subscribe(observerOrNext?: Partial> | ((value: T) => void)): Subscription;\n /** @deprecated Instead of passing separate callback arguments, use an observer argument. Signatures taking separate callback arguments will be removed in v8. Details: https://rxjs.dev/deprecations/subscribe-arguments */\n subscribe(next?: ((value: T) => void) | null, error?: ((error: any) => void) | null, complete?: (() => void) | null): Subscription;\n /**\n * Invokes an execution of an Observable and registers Observer handlers for notifications it will emit.\n *\n * Use it when you have all these Observables, but still nothing is happening.\n *\n * `subscribe` is not a regular operator, but a method that calls Observable's internal `subscribe` function. It\n * might be for example a function that you passed to Observable's constructor, but most of the time it is\n * a library implementation, which defines what will be emitted by an Observable, and when it be will emitted. This means\n * that calling `subscribe` is actually the moment when Observable starts its work, not when it is created, as it is often\n * the thought.\n *\n * Apart from starting the execution of an Observable, this method allows you to listen for values\n * that an Observable emits, as well as for when it completes or errors. You can achieve this in two\n * of the following ways.\n *\n * The first way is creating an object that implements {@link Observer} interface. It should have methods\n * defined by that interface, but note that it should be just a regular JavaScript object, which you can create\n * yourself in any way you want (ES6 class, classic function constructor, object literal etc.). In particular, do\n * not attempt to use any RxJS implementation details to create Observers - you don't need them. Remember also\n * that your object does not have to implement all methods. If you find yourself creating a method that doesn't\n * do anything, you can simply omit it. Note however, if the `error` method is not provided and an error happens,\n * it will be thrown asynchronously. Errors thrown asynchronously cannot be caught using `try`/`catch`. Instead,\n * use the {@link onUnhandledError} configuration option or use a runtime handler (like `window.onerror` or\n * `process.on('error)`) to be notified of unhandled errors. Because of this, it's recommended that you provide\n * an `error` method to avoid missing thrown errors.\n *\n * The second way is to give up on Observer object altogether and simply provide callback functions in place of its methods.\n * This means you can provide three functions as arguments to `subscribe`, where the first function is equivalent\n * of a `next` method, the second of an `error` method and the third of a `complete` method. Just as in case of an Observer,\n * if you do not need to listen for something, you can omit a function by passing `undefined` or `null`,\n * since `subscribe` recognizes these functions by where they were placed in function call. When it comes\n * to the `error` function, as with an Observer, if not provided, errors emitted by an Observable will be thrown asynchronously.\n *\n * You can, however, subscribe with no parameters at all. This may be the case where you're not interested in terminal events\n * and you also handled emissions internally by using operators (e.g. using `tap`).\n *\n * Whichever style of calling `subscribe` you use, in both cases it returns a Subscription object.\n * This object allows you to call `unsubscribe` on it, which in turn will stop the work that an Observable does and will clean\n * up all resources that an Observable used. Note that cancelling a subscription will not call `complete` callback\n * provided to `subscribe` function, which is reserved for a regular completion signal that comes from an Observable.\n *\n * Remember that callbacks provided to `subscribe` are not guaranteed to be called asynchronously.\n * It is an Observable itself that decides when these functions will be called. For example {@link of}\n * by default emits all its values synchronously. Always check documentation for how given Observable\n * will behave when subscribed and if its default behavior can be modified with a `scheduler`.\n *\n * #### Examples\n *\n * Subscribe with an {@link guide/observer Observer}\n *\n * ```ts\n * import { of } from 'rxjs';\n *\n * const sumObserver = {\n * sum: 0,\n * next(value) {\n * console.log('Adding: ' + value);\n * this.sum = this.sum + value;\n * },\n * error() {\n * // We actually could just remove this method,\n * // since we do not really care about errors right now.\n * },\n * complete() {\n * console.log('Sum equals: ' + this.sum);\n * }\n * };\n *\n * of(1, 2, 3) // Synchronously emits 1, 2, 3 and then completes.\n * .subscribe(sumObserver);\n *\n * // Logs:\n * // 'Adding: 1'\n * // 'Adding: 2'\n * // 'Adding: 3'\n * // 'Sum equals: 6'\n * ```\n *\n * Subscribe with functions ({@link deprecations/subscribe-arguments deprecated})\n *\n * ```ts\n * import { of } from 'rxjs'\n *\n * let sum = 0;\n *\n * of(1, 2, 3).subscribe(\n * value => {\n * console.log('Adding: ' + value);\n * sum = sum + value;\n * },\n * undefined,\n * () => console.log('Sum equals: ' + sum)\n * );\n *\n * // Logs:\n * // 'Adding: 1'\n * // 'Adding: 2'\n * // 'Adding: 3'\n * // 'Sum equals: 6'\n * ```\n *\n * Cancel a subscription\n *\n * ```ts\n * import { interval } from 'rxjs';\n *\n * const subscription = interval(1000).subscribe({\n * next(num) {\n * console.log(num)\n * },\n * complete() {\n * // Will not be called, even when cancelling subscription.\n * console.log('completed!');\n * }\n * });\n *\n * setTimeout(() => {\n * subscription.unsubscribe();\n * console.log('unsubscribed!');\n * }, 2500);\n *\n * // Logs:\n * // 0 after 1s\n * // 1 after 2s\n * // 'unsubscribed!' after 2.5s\n * ```\n *\n * @param {Observer|Function} observerOrNext (optional) Either an observer with methods to be called,\n * or the first of three possible handlers, which is the handler for each value emitted from the subscribed\n * Observable.\n * @param {Function} error (optional) A handler for a terminal event resulting from an error. If no error handler is provided,\n * the error will be thrown asynchronously as unhandled.\n * @param {Function} complete (optional) A handler for a terminal event resulting from successful completion.\n * @return {Subscription} a subscription reference to the registered handlers\n * @method subscribe\n */\n subscribe(\n observerOrNext?: Partial> | ((value: T) => void) | null,\n error?: ((error: any) => void) | null,\n complete?: (() => void) | null\n ): Subscription {\n const subscriber = isSubscriber(observerOrNext) ? observerOrNext : new SafeSubscriber(observerOrNext, error, complete);\n\n errorContext(() => {\n const { operator, source } = this;\n subscriber.add(\n operator\n ? // We're dealing with a subscription in the\n // operator chain to one of our lifted operators.\n operator.call(subscriber, source)\n : source\n ? // If `source` has a value, but `operator` does not, something that\n // had intimate knowledge of our API, like our `Subject`, must have\n // set it. We're going to just call `_subscribe` directly.\n this._subscribe(subscriber)\n : // In all other cases, we're likely wrapping a user-provided initializer\n // function, so we need to catch errors and handle them appropriately.\n this._trySubscribe(subscriber)\n );\n });\n\n return subscriber;\n }\n\n /** @internal */\n protected _trySubscribe(sink: Subscriber): TeardownLogic {\n try {\n return this._subscribe(sink);\n } catch (err) {\n // We don't need to return anything in this case,\n // because it's just going to try to `add()` to a subscription\n // above.\n sink.error(err);\n }\n }\n\n /**\n * Used as a NON-CANCELLABLE means of subscribing to an observable, for use with\n * APIs that expect promises, like `async/await`. You cannot unsubscribe from this.\n *\n * **WARNING**: Only use this with observables you *know* will complete. If the source\n * observable does not complete, you will end up with a promise that is hung up, and\n * potentially all of the state of an async function hanging out in memory. To avoid\n * this situation, look into adding something like {@link timeout}, {@link take},\n * {@link takeWhile}, or {@link takeUntil} amongst others.\n *\n * #### Example\n *\n * ```ts\n * import { interval, take } from 'rxjs';\n *\n * const source$ = interval(1000).pipe(take(4));\n *\n * async function getTotal() {\n * let total = 0;\n *\n * await source$.forEach(value => {\n * total += value;\n * console.log('observable -> ' + value);\n * });\n *\n * return total;\n * }\n *\n * getTotal().then(\n * total => console.log('Total: ' + total)\n * );\n *\n * // Expected:\n * // 'observable -> 0'\n * // 'observable -> 1'\n * // 'observable -> 2'\n * // 'observable -> 3'\n * // 'Total: 6'\n * ```\n *\n * @param next a handler for each value emitted by the observable\n * @return a promise that either resolves on observable completion or\n * rejects with the handled error\n */\n forEach(next: (value: T) => void): Promise;\n\n /**\n * @param next a handler for each value emitted by the observable\n * @param promiseCtor a constructor function used to instantiate the Promise\n * @return a promise that either resolves on observable completion or\n * rejects with the handled error\n * @deprecated Passing a Promise constructor will no longer be available\n * in upcoming versions of RxJS. This is because it adds weight to the library, for very\n * little benefit. If you need this functionality, it is recommended that you either\n * polyfill Promise, or you create an adapter to convert the returned native promise\n * to whatever promise implementation you wanted. Will be removed in v8.\n */\n forEach(next: (value: T) => void, promiseCtor: PromiseConstructorLike): Promise;\n\n forEach(next: (value: T) => void, promiseCtor?: PromiseConstructorLike): Promise {\n promiseCtor = getPromiseCtor(promiseCtor);\n\n return new promiseCtor((resolve, reject) => {\n const subscriber = new SafeSubscriber({\n next: (value) => {\n try {\n next(value);\n } catch (err) {\n reject(err);\n subscriber.unsubscribe();\n }\n },\n error: reject,\n complete: resolve,\n });\n this.subscribe(subscriber);\n }) as Promise;\n }\n\n /** @internal */\n protected _subscribe(subscriber: Subscriber): TeardownLogic {\n return this.source?.subscribe(subscriber);\n }\n\n /**\n * An interop point defined by the es7-observable spec https://github.com/zenparsing/es-observable\n * @method Symbol.observable\n * @return {Observable} this instance of the observable\n */\n [Symbol_observable]() {\n return this;\n }\n\n /* tslint:disable:max-line-length */\n pipe(): Observable;\n pipe(op1: OperatorFunction): Observable;\n pipe(op1: OperatorFunction, op2: OperatorFunction): Observable;\n pipe(op1: OperatorFunction, op2: OperatorFunction, op3: OperatorFunction): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction,\n op6: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction,\n op6: OperatorFunction,\n op7: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction,\n op6: OperatorFunction,\n op7: OperatorFunction,\n op8: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction,\n op6: OperatorFunction,\n op7: OperatorFunction,\n op8: OperatorFunction,\n op9: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction,\n op6: OperatorFunction,\n op7: OperatorFunction,\n op8: OperatorFunction,\n op9: OperatorFunction,\n ...operations: OperatorFunction[]\n ): Observable;\n /* tslint:enable:max-line-length */\n\n /**\n * Used to stitch together functional operators into a chain.\n * @method pipe\n * @return {Observable} the Observable result of all of the operators having\n * been called in the order they were passed in.\n *\n * ## Example\n *\n * ```ts\n * import { interval, filter, map, scan } from 'rxjs';\n *\n * interval(1000)\n * .pipe(\n * filter(x => x % 2 === 0),\n * map(x => x + x),\n * scan((acc, x) => acc + x)\n * )\n * .subscribe(x => console.log(x));\n * ```\n */\n pipe(...operations: OperatorFunction[]): Observable {\n return pipeFromArray(operations)(this);\n }\n\n /* tslint:disable:max-line-length */\n /** @deprecated Replaced with {@link firstValueFrom} and {@link lastValueFrom}. Will be removed in v8. Details: https://rxjs.dev/deprecations/to-promise */\n toPromise(): Promise;\n /** @deprecated Replaced with {@link firstValueFrom} and {@link lastValueFrom}. Will be removed in v8. Details: https://rxjs.dev/deprecations/to-promise */\n toPromise(PromiseCtor: typeof Promise): Promise;\n /** @deprecated Replaced with {@link firstValueFrom} and {@link lastValueFrom}. Will be removed in v8. Details: https://rxjs.dev/deprecations/to-promise */\n toPromise(PromiseCtor: PromiseConstructorLike): Promise;\n /* tslint:enable:max-line-length */\n\n /**\n * Subscribe to this Observable and get a Promise resolving on\n * `complete` with the last emission (if any).\n *\n * **WARNING**: Only use this with observables you *know* will complete. If the source\n * observable does not complete, you will end up with a promise that is hung up, and\n * potentially all of the state of an async function hanging out in memory. To avoid\n * this situation, look into adding something like {@link timeout}, {@link take},\n * {@link takeWhile}, or {@link takeUntil} amongst others.\n *\n * @method toPromise\n * @param [promiseCtor] a constructor function used to instantiate\n * the Promise\n * @return A Promise that resolves with the last value emit, or\n * rejects on an error. If there were no emissions, Promise\n * resolves with undefined.\n * @deprecated Replaced with {@link firstValueFrom} and {@link lastValueFrom}. Will be removed in v8. Details: https://rxjs.dev/deprecations/to-promise\n */\n toPromise(promiseCtor?: PromiseConstructorLike): Promise {\n promiseCtor = getPromiseCtor(promiseCtor);\n\n return new promiseCtor((resolve, reject) => {\n let value: T | undefined;\n this.subscribe(\n (x: T) => (value = x),\n (err: any) => reject(err),\n () => resolve(value)\n );\n }) as Promise;\n }\n}\n\n/**\n * Decides between a passed promise constructor from consuming code,\n * A default configured promise constructor, and the native promise\n * constructor and returns it. If nothing can be found, it will throw\n * an error.\n * @param promiseCtor The optional promise constructor to passed by consuming code\n */\nfunction getPromiseCtor(promiseCtor: PromiseConstructorLike | undefined) {\n return promiseCtor ?? config.Promise ?? Promise;\n}\n\nfunction isObserver(value: any): value is Observer {\n return value && isFunction(value.next) && isFunction(value.error) && isFunction(value.complete);\n}\n\nfunction isSubscriber(value: any): value is Subscriber {\n return (value && value instanceof Subscriber) || (isObserver(value) && isSubscription(value));\n}\n", "import { Observable } from '../Observable';\nimport { Subscriber } from '../Subscriber';\nimport { OperatorFunction } from '../types';\nimport { isFunction } from './isFunction';\n\n/**\n * Used to determine if an object is an Observable with a lift function.\n */\nexport function hasLift(source: any): source is { lift: InstanceType['lift'] } {\n return isFunction(source?.lift);\n}\n\n/**\n * Creates an `OperatorFunction`. Used to define operators throughout the library in a concise way.\n * @param init The logic to connect the liftedSource to the subscriber at the moment of subscription.\n */\nexport function operate(\n init: (liftedSource: Observable, subscriber: Subscriber) => (() => void) | void\n): OperatorFunction {\n return (source: Observable) => {\n if (hasLift(source)) {\n return source.lift(function (this: Subscriber, liftedSource: Observable) {\n try {\n return init(liftedSource, this);\n } catch (err) {\n this.error(err);\n }\n });\n }\n throw new TypeError('Unable to lift unknown Observable type');\n };\n}\n", "import { Subscriber } from '../Subscriber';\n\n/**\n * Creates an instance of an `OperatorSubscriber`.\n * @param destination The downstream subscriber.\n * @param onNext Handles next values, only called if this subscriber is not stopped or closed. Any\n * error that occurs in this function is caught and sent to the `error` method of this subscriber.\n * @param onError Handles errors from the subscription, any errors that occur in this handler are caught\n * and send to the `destination` error handler.\n * @param onComplete Handles completion notification from the subscription. Any errors that occur in\n * this handler are sent to the `destination` error handler.\n * @param onFinalize Additional teardown logic here. This will only be called on teardown if the\n * subscriber itself is not already closed. This is called after all other teardown logic is executed.\n */\nexport function createOperatorSubscriber(\n destination: Subscriber,\n onNext?: (value: T) => void,\n onComplete?: () => void,\n onError?: (err: any) => void,\n onFinalize?: () => void\n): Subscriber {\n return new OperatorSubscriber(destination, onNext, onComplete, onError, onFinalize);\n}\n\n/**\n * A generic helper for allowing operators to be created with a Subscriber and\n * use closures to capture necessary state from the operator function itself.\n */\nexport class OperatorSubscriber extends Subscriber {\n /**\n * Creates an instance of an `OperatorSubscriber`.\n * @param destination The downstream subscriber.\n * @param onNext Handles next values, only called if this subscriber is not stopped or closed. Any\n * error that occurs in this function is caught and sent to the `error` method of this subscriber.\n * @param onError Handles errors from the subscription, any errors that occur in this handler are caught\n * and send to the `destination` error handler.\n * @param onComplete Handles completion notification from the subscription. Any errors that occur in\n * this handler are sent to the `destination` error handler.\n * @param onFinalize Additional finalization logic here. This will only be called on finalization if the\n * subscriber itself is not already closed. This is called after all other finalization logic is executed.\n * @param shouldUnsubscribe An optional check to see if an unsubscribe call should truly unsubscribe.\n * NOTE: This currently **ONLY** exists to support the strange behavior of {@link groupBy}, where unsubscription\n * to the resulting observable does not actually disconnect from the source if there are active subscriptions\n * to any grouped observable. (DO NOT EXPOSE OR USE EXTERNALLY!!!)\n */\n constructor(\n destination: Subscriber,\n onNext?: (value: T) => void,\n onComplete?: () => void,\n onError?: (err: any) => void,\n private onFinalize?: () => void,\n private shouldUnsubscribe?: () => boolean\n ) {\n // It's important - for performance reasons - that all of this class's\n // members are initialized and that they are always initialized in the same\n // order. This will ensure that all OperatorSubscriber instances have the\n // same hidden class in V8. This, in turn, will help keep the number of\n // hidden classes involved in property accesses within the base class as\n // low as possible. If the number of hidden classes involved exceeds four,\n // the property accesses will become megamorphic and performance penalties\n // will be incurred - i.e. inline caches won't be used.\n //\n // The reasons for ensuring all instances have the same hidden class are\n // further discussed in this blog post from Benedikt Meurer:\n // https://benediktmeurer.de/2018/03/23/impact-of-polymorphism-on-component-based-frameworks-like-react/\n super(destination);\n this._next = onNext\n ? function (this: OperatorSubscriber, value: T) {\n try {\n onNext(value);\n } catch (err) {\n destination.error(err);\n }\n }\n : super._next;\n this._error = onError\n ? function (this: OperatorSubscriber, err: any) {\n try {\n onError(err);\n } catch (err) {\n // Send any errors that occur down stream.\n destination.error(err);\n } finally {\n // Ensure finalization.\n this.unsubscribe();\n }\n }\n : super._error;\n this._complete = onComplete\n ? function (this: OperatorSubscriber) {\n try {\n onComplete();\n } catch (err) {\n // Send any errors that occur down stream.\n destination.error(err);\n } finally {\n // Ensure finalization.\n this.unsubscribe();\n }\n }\n : super._complete;\n }\n\n unsubscribe() {\n if (!this.shouldUnsubscribe || this.shouldUnsubscribe()) {\n const { closed } = this;\n super.unsubscribe();\n // Execute additional teardown if we have any and we didn't already do so.\n !closed && this.onFinalize?.();\n }\n }\n}\n", "import { Subscription } from '../Subscription';\n\ninterface AnimationFrameProvider {\n schedule(callback: FrameRequestCallback): Subscription;\n requestAnimationFrame: typeof requestAnimationFrame;\n cancelAnimationFrame: typeof cancelAnimationFrame;\n delegate:\n | {\n requestAnimationFrame: typeof requestAnimationFrame;\n cancelAnimationFrame: typeof cancelAnimationFrame;\n }\n | undefined;\n}\n\nexport const animationFrameProvider: AnimationFrameProvider = {\n // When accessing the delegate, use the variable rather than `this` so that\n // the functions can be called without being bound to the provider.\n schedule(callback) {\n let request = requestAnimationFrame;\n let cancel: typeof cancelAnimationFrame | undefined = cancelAnimationFrame;\n const { delegate } = animationFrameProvider;\n if (delegate) {\n request = delegate.requestAnimationFrame;\n cancel = delegate.cancelAnimationFrame;\n }\n const handle = request((timestamp) => {\n // Clear the cancel function. The request has been fulfilled, so\n // attempting to cancel the request upon unsubscription would be\n // pointless.\n cancel = undefined;\n callback(timestamp);\n });\n return new Subscription(() => cancel?.(handle));\n },\n requestAnimationFrame(...args) {\n const { delegate } = animationFrameProvider;\n return (delegate?.requestAnimationFrame || requestAnimationFrame)(...args);\n },\n cancelAnimationFrame(...args) {\n const { delegate } = animationFrameProvider;\n return (delegate?.cancelAnimationFrame || cancelAnimationFrame)(...args);\n },\n delegate: undefined,\n};\n", "import { createErrorClass } from './createErrorClass';\n\nexport interface ObjectUnsubscribedError extends Error {}\n\nexport interface ObjectUnsubscribedErrorCtor {\n /**\n * @deprecated Internal implementation detail. Do not construct error instances.\n * Cannot be tagged as internal: https://github.com/ReactiveX/rxjs/issues/6269\n */\n new (): ObjectUnsubscribedError;\n}\n\n/**\n * An error thrown when an action is invalid because the object has been\n * unsubscribed.\n *\n * @see {@link Subject}\n * @see {@link BehaviorSubject}\n *\n * @class ObjectUnsubscribedError\n */\nexport const ObjectUnsubscribedError: ObjectUnsubscribedErrorCtor = createErrorClass(\n (_super) =>\n function ObjectUnsubscribedErrorImpl(this: any) {\n _super(this);\n this.name = 'ObjectUnsubscribedError';\n this.message = 'object unsubscribed';\n }\n);\n", "import { Operator } from './Operator';\nimport { Observable } from './Observable';\nimport { Subscriber } from './Subscriber';\nimport { Subscription, EMPTY_SUBSCRIPTION } from './Subscription';\nimport { Observer, SubscriptionLike, TeardownLogic } from './types';\nimport { ObjectUnsubscribedError } from './util/ObjectUnsubscribedError';\nimport { arrRemove } from './util/arrRemove';\nimport { errorContext } from './util/errorContext';\n\n/**\n * A Subject is a special type of Observable that allows values to be\n * multicasted to many Observers. Subjects are like EventEmitters.\n *\n * Every Subject is an Observable and an Observer. You can subscribe to a\n * Subject, and you can call next to feed values as well as error and complete.\n */\nexport class Subject extends Observable implements SubscriptionLike {\n closed = false;\n\n private currentObservers: Observer[] | null = null;\n\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n observers: Observer[] = [];\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n isStopped = false;\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n hasError = false;\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n thrownError: any = null;\n\n /**\n * Creates a \"subject\" by basically gluing an observer to an observable.\n *\n * @nocollapse\n * @deprecated Recommended you do not use. Will be removed at some point in the future. Plans for replacement still under discussion.\n */\n static create: (...args: any[]) => any = (destination: Observer, source: Observable): AnonymousSubject => {\n return new AnonymousSubject(destination, source);\n };\n\n constructor() {\n // NOTE: This must be here to obscure Observable's constructor.\n super();\n }\n\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n lift(operator: Operator): Observable {\n const subject = new AnonymousSubject(this, this);\n subject.operator = operator as any;\n return subject as any;\n }\n\n /** @internal */\n protected _throwIfClosed() {\n if (this.closed) {\n throw new ObjectUnsubscribedError();\n }\n }\n\n next(value: T) {\n errorContext(() => {\n this._throwIfClosed();\n if (!this.isStopped) {\n if (!this.currentObservers) {\n this.currentObservers = Array.from(this.observers);\n }\n for (const observer of this.currentObservers) {\n observer.next(value);\n }\n }\n });\n }\n\n error(err: any) {\n errorContext(() => {\n this._throwIfClosed();\n if (!this.isStopped) {\n this.hasError = this.isStopped = true;\n this.thrownError = err;\n const { observers } = this;\n while (observers.length) {\n observers.shift()!.error(err);\n }\n }\n });\n }\n\n complete() {\n errorContext(() => {\n this._throwIfClosed();\n if (!this.isStopped) {\n this.isStopped = true;\n const { observers } = this;\n while (observers.length) {\n observers.shift()!.complete();\n }\n }\n });\n }\n\n unsubscribe() {\n this.isStopped = this.closed = true;\n this.observers = this.currentObservers = null!;\n }\n\n get observed() {\n return this.observers?.length > 0;\n }\n\n /** @internal */\n protected _trySubscribe(subscriber: Subscriber): TeardownLogic {\n this._throwIfClosed();\n return super._trySubscribe(subscriber);\n }\n\n /** @internal */\n protected _subscribe(subscriber: Subscriber): Subscription {\n this._throwIfClosed();\n this._checkFinalizedStatuses(subscriber);\n return this._innerSubscribe(subscriber);\n }\n\n /** @internal */\n protected _innerSubscribe(subscriber: Subscriber) {\n const { hasError, isStopped, observers } = this;\n if (hasError || isStopped) {\n return EMPTY_SUBSCRIPTION;\n }\n this.currentObservers = null;\n observers.push(subscriber);\n return new Subscription(() => {\n this.currentObservers = null;\n arrRemove(observers, subscriber);\n });\n }\n\n /** @internal */\n protected _checkFinalizedStatuses(subscriber: Subscriber) {\n const { hasError, thrownError, isStopped } = this;\n if (hasError) {\n subscriber.error(thrownError);\n } else if (isStopped) {\n subscriber.complete();\n }\n }\n\n /**\n * Creates a new Observable with this Subject as the source. You can do this\n * to create custom Observer-side logic of the Subject and conceal it from\n * code that uses the Observable.\n * @return {Observable} Observable that the Subject casts to\n */\n asObservable(): Observable {\n const observable: any = new Observable();\n observable.source = this;\n return observable;\n }\n}\n\n/**\n * @class AnonymousSubject\n */\nexport class AnonymousSubject extends Subject {\n constructor(\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n public destination?: Observer,\n source?: Observable\n ) {\n super();\n this.source = source;\n }\n\n next(value: T) {\n this.destination?.next?.(value);\n }\n\n error(err: any) {\n this.destination?.error?.(err);\n }\n\n complete() {\n this.destination?.complete?.();\n }\n\n /** @internal */\n protected _subscribe(subscriber: Subscriber): Subscription {\n return this.source?.subscribe(subscriber) ?? EMPTY_SUBSCRIPTION;\n }\n}\n", "import { Subject } from './Subject';\nimport { Subscriber } from './Subscriber';\nimport { Subscription } from './Subscription';\n\n/**\n * A variant of Subject that requires an initial value and emits its current\n * value whenever it is subscribed to.\n *\n * @class BehaviorSubject\n */\nexport class BehaviorSubject extends Subject {\n constructor(private _value: T) {\n super();\n }\n\n get value(): T {\n return this.getValue();\n }\n\n /** @internal */\n protected _subscribe(subscriber: Subscriber): Subscription {\n const subscription = super._subscribe(subscriber);\n !subscription.closed && subscriber.next(this._value);\n return subscription;\n }\n\n getValue(): T {\n const { hasError, thrownError, _value } = this;\n if (hasError) {\n throw thrownError;\n }\n this._throwIfClosed();\n return _value;\n }\n\n next(value: T): void {\n super.next((this._value = value));\n }\n}\n", "import { TimestampProvider } from '../types';\n\ninterface DateTimestampProvider extends TimestampProvider {\n delegate: TimestampProvider | undefined;\n}\n\nexport const dateTimestampProvider: DateTimestampProvider = {\n now() {\n // Use the variable rather than `this` so that the function can be called\n // without being bound to the provider.\n return (dateTimestampProvider.delegate || Date).now();\n },\n delegate: undefined,\n};\n", "import { Subject } from './Subject';\nimport { TimestampProvider } from './types';\nimport { Subscriber } from './Subscriber';\nimport { Subscription } from './Subscription';\nimport { dateTimestampProvider } from './scheduler/dateTimestampProvider';\n\n/**\n * A variant of {@link Subject} that \"replays\" old values to new subscribers by emitting them when they first subscribe.\n *\n * `ReplaySubject` has an internal buffer that will store a specified number of values that it has observed. Like `Subject`,\n * `ReplaySubject` \"observes\" values by having them passed to its `next` method. When it observes a value, it will store that\n * value for a time determined by the configuration of the `ReplaySubject`, as passed to its constructor.\n *\n * When a new subscriber subscribes to the `ReplaySubject` instance, it will synchronously emit all values in its buffer in\n * a First-In-First-Out (FIFO) manner. The `ReplaySubject` will also complete, if it has observed completion; and it will\n * error if it has observed an error.\n *\n * There are two main configuration items to be concerned with:\n *\n * 1. `bufferSize` - This will determine how many items are stored in the buffer, defaults to infinite.\n * 2. `windowTime` - The amount of time to hold a value in the buffer before removing it from the buffer.\n *\n * Both configurations may exist simultaneously. So if you would like to buffer a maximum of 3 values, as long as the values\n * are less than 2 seconds old, you could do so with a `new ReplaySubject(3, 2000)`.\n *\n * ### Differences with BehaviorSubject\n *\n * `BehaviorSubject` is similar to `new ReplaySubject(1)`, with a couple of exceptions:\n *\n * 1. `BehaviorSubject` comes \"primed\" with a single value upon construction.\n * 2. `ReplaySubject` will replay values, even after observing an error, where `BehaviorSubject` will not.\n *\n * @see {@link Subject}\n * @see {@link BehaviorSubject}\n * @see {@link shareReplay}\n */\nexport class ReplaySubject extends Subject {\n private _buffer: (T | number)[] = [];\n private _infiniteTimeWindow = true;\n\n /**\n * @param bufferSize The size of the buffer to replay on subscription\n * @param windowTime The amount of time the buffered items will stay buffered\n * @param timestampProvider An object with a `now()` method that provides the current timestamp. This is used to\n * calculate the amount of time something has been buffered.\n */\n constructor(\n private _bufferSize = Infinity,\n private _windowTime = Infinity,\n private _timestampProvider: TimestampProvider = dateTimestampProvider\n ) {\n super();\n this._infiniteTimeWindow = _windowTime === Infinity;\n this._bufferSize = Math.max(1, _bufferSize);\n this._windowTime = Math.max(1, _windowTime);\n }\n\n next(value: T): void {\n const { isStopped, _buffer, _infiniteTimeWindow, _timestampProvider, _windowTime } = this;\n if (!isStopped) {\n _buffer.push(value);\n !_infiniteTimeWindow && _buffer.push(_timestampProvider.now() + _windowTime);\n }\n this._trimBuffer();\n super.next(value);\n }\n\n /** @internal */\n protected _subscribe(subscriber: Subscriber): Subscription {\n this._throwIfClosed();\n this._trimBuffer();\n\n const subscription = this._innerSubscribe(subscriber);\n\n const { _infiniteTimeWindow, _buffer } = this;\n // We use a copy here, so reentrant code does not mutate our array while we're\n // emitting it to a new subscriber.\n const copy = _buffer.slice();\n for (let i = 0; i < copy.length && !subscriber.closed; i += _infiniteTimeWindow ? 1 : 2) {\n subscriber.next(copy[i] as T);\n }\n\n this._checkFinalizedStatuses(subscriber);\n\n return subscription;\n }\n\n private _trimBuffer() {\n const { _bufferSize, _timestampProvider, _buffer, _infiniteTimeWindow } = this;\n // If we don't have an infinite buffer size, and we're over the length,\n // use splice to truncate the old buffer values off. Note that we have to\n // double the size for instances where we're not using an infinite time window\n // because we're storing the values and the timestamps in the same array.\n const adjustedBufferSize = (_infiniteTimeWindow ? 1 : 2) * _bufferSize;\n _bufferSize < Infinity && adjustedBufferSize < _buffer.length && _buffer.splice(0, _buffer.length - adjustedBufferSize);\n\n // Now, if we're not in an infinite time window, remove all values where the time is\n // older than what is allowed.\n if (!_infiniteTimeWindow) {\n const now = _timestampProvider.now();\n let last = 0;\n // Search the array for the first timestamp that isn't expired and\n // truncate the buffer up to that point.\n for (let i = 1; i < _buffer.length && (_buffer[i] as number) <= now; i += 2) {\n last = i;\n }\n last && _buffer.splice(0, last + 1);\n }\n }\n}\n", "import { Scheduler } from '../Scheduler';\nimport { Subscription } from '../Subscription';\nimport { SchedulerAction } from '../types';\n\n/**\n * A unit of work to be executed in a `scheduler`. An action is typically\n * created from within a {@link SchedulerLike} and an RxJS user does not need to concern\n * themselves about creating and manipulating an Action.\n *\n * ```ts\n * class Action extends Subscription {\n * new (scheduler: Scheduler, work: (state?: T) => void);\n * schedule(state?: T, delay: number = 0): Subscription;\n * }\n * ```\n *\n * @class Action\n */\nexport class Action extends Subscription {\n constructor(scheduler: Scheduler, work: (this: SchedulerAction, state?: T) => void) {\n super();\n }\n /**\n * Schedules this action on its parent {@link SchedulerLike} for execution. May be passed\n * some context object, `state`. May happen at some point in the future,\n * according to the `delay` parameter, if specified.\n * @param {T} [state] Some contextual data that the `work` function uses when\n * called by the Scheduler.\n * @param {number} [delay] Time to wait before executing the work, where the\n * time unit is implicit and defined by the Scheduler.\n * @return {void}\n */\n public schedule(state?: T, delay: number = 0): Subscription {\n return this;\n }\n}\n", "import type { TimerHandle } from './timerHandle';\ntype SetIntervalFunction = (handler: () => void, timeout?: number, ...args: any[]) => TimerHandle;\ntype ClearIntervalFunction = (handle: TimerHandle) => void;\n\ninterface IntervalProvider {\n setInterval: SetIntervalFunction;\n clearInterval: ClearIntervalFunction;\n delegate:\n | {\n setInterval: SetIntervalFunction;\n clearInterval: ClearIntervalFunction;\n }\n | undefined;\n}\n\nexport const intervalProvider: IntervalProvider = {\n // When accessing the delegate, use the variable rather than `this` so that\n // the functions can be called without being bound to the provider.\n setInterval(handler: () => void, timeout?: number, ...args) {\n const { delegate } = intervalProvider;\n if (delegate?.setInterval) {\n return delegate.setInterval(handler, timeout, ...args);\n }\n return setInterval(handler, timeout, ...args);\n },\n clearInterval(handle) {\n const { delegate } = intervalProvider;\n return (delegate?.clearInterval || clearInterval)(handle as any);\n },\n delegate: undefined,\n};\n", "import { Action } from './Action';\nimport { SchedulerAction } from '../types';\nimport { Subscription } from '../Subscription';\nimport { AsyncScheduler } from './AsyncScheduler';\nimport { intervalProvider } from './intervalProvider';\nimport { arrRemove } from '../util/arrRemove';\nimport { TimerHandle } from './timerHandle';\n\nexport class AsyncAction extends Action {\n public id: TimerHandle | undefined;\n public state?: T;\n // @ts-ignore: Property has no initializer and is not definitely assigned\n public delay: number;\n protected pending: boolean = false;\n\n constructor(protected scheduler: AsyncScheduler, protected work: (this: SchedulerAction, state?: T) => void) {\n super(scheduler, work);\n }\n\n public schedule(state?: T, delay: number = 0): Subscription {\n if (this.closed) {\n return this;\n }\n\n // Always replace the current state with the new state.\n this.state = state;\n\n const id = this.id;\n const scheduler = this.scheduler;\n\n //\n // Important implementation note:\n //\n // Actions only execute once by default, unless rescheduled from within the\n // scheduled callback. This allows us to implement single and repeat\n // actions via the same code path, without adding API surface area, as well\n // as mimic traditional recursion but across asynchronous boundaries.\n //\n // However, JS runtimes and timers distinguish between intervals achieved by\n // serial `setTimeout` calls vs. a single `setInterval` call. An interval of\n // serial `setTimeout` calls can be individually delayed, which delays\n // scheduling the next `setTimeout`, and so on. `setInterval` attempts to\n // guarantee the interval callback will be invoked more precisely to the\n // interval period, regardless of load.\n //\n // Therefore, we use `setInterval` to schedule single and repeat actions.\n // If the action reschedules itself with the same delay, the interval is not\n // canceled. If the action doesn't reschedule, or reschedules with a\n // different delay, the interval will be canceled after scheduled callback\n // execution.\n //\n if (id != null) {\n this.id = this.recycleAsyncId(scheduler, id, delay);\n }\n\n // Set the pending flag indicating that this action has been scheduled, or\n // has recursively rescheduled itself.\n this.pending = true;\n\n this.delay = delay;\n // If this action has already an async Id, don't request a new one.\n this.id = this.id ?? this.requestAsyncId(scheduler, this.id, delay);\n\n return this;\n }\n\n protected requestAsyncId(scheduler: AsyncScheduler, _id?: TimerHandle, delay: number = 0): TimerHandle {\n return intervalProvider.setInterval(scheduler.flush.bind(scheduler, this), delay);\n }\n\n protected recycleAsyncId(_scheduler: AsyncScheduler, id?: TimerHandle, delay: number | null = 0): TimerHandle | undefined {\n // If this action is rescheduled with the same delay time, don't clear the interval id.\n if (delay != null && this.delay === delay && this.pending === false) {\n return id;\n }\n // Otherwise, if the action's delay time is different from the current delay,\n // or the action has been rescheduled before it's executed, clear the interval id\n if (id != null) {\n intervalProvider.clearInterval(id);\n }\n\n return undefined;\n }\n\n /**\n * Immediately executes this action and the `work` it contains.\n * @return {any}\n */\n public execute(state: T, delay: number): any {\n if (this.closed) {\n return new Error('executing a cancelled action');\n }\n\n this.pending = false;\n const error = this._execute(state, delay);\n if (error) {\n return error;\n } else if (this.pending === false && this.id != null) {\n // Dequeue if the action didn't reschedule itself. Don't call\n // unsubscribe(), because the action could reschedule later.\n // For example:\n // ```\n // scheduler.schedule(function doWork(counter) {\n // /* ... I'm a busy worker bee ... */\n // var originalAction = this;\n // /* wait 100ms before rescheduling the action */\n // setTimeout(function () {\n // originalAction.schedule(counter + 1);\n // }, 100);\n // }, 1000);\n // ```\n this.id = this.recycleAsyncId(this.scheduler, this.id, null);\n }\n }\n\n protected _execute(state: T, _delay: number): any {\n let errored: boolean = false;\n let errorValue: any;\n try {\n this.work(state);\n } catch (e) {\n errored = true;\n // HACK: Since code elsewhere is relying on the \"truthiness\" of the\n // return here, we can't have it return \"\" or 0 or false.\n // TODO: Clean this up when we refactor schedulers mid-version-8 or so.\n errorValue = e ? e : new Error('Scheduled action threw falsy error');\n }\n if (errored) {\n this.unsubscribe();\n return errorValue;\n }\n }\n\n unsubscribe() {\n if (!this.closed) {\n const { id, scheduler } = this;\n const { actions } = scheduler;\n\n this.work = this.state = this.scheduler = null!;\n this.pending = false;\n\n arrRemove(actions, this);\n if (id != null) {\n this.id = this.recycleAsyncId(scheduler, id, null);\n }\n\n this.delay = null!;\n super.unsubscribe();\n }\n }\n}\n", "import { Action } from './scheduler/Action';\nimport { Subscription } from './Subscription';\nimport { SchedulerLike, SchedulerAction } from './types';\nimport { dateTimestampProvider } from './scheduler/dateTimestampProvider';\n\n/**\n * An execution context and a data structure to order tasks and schedule their\n * execution. Provides a notion of (potentially virtual) time, through the\n * `now()` getter method.\n *\n * Each unit of work in a Scheduler is called an `Action`.\n *\n * ```ts\n * class Scheduler {\n * now(): number;\n * schedule(work, delay?, state?): Subscription;\n * }\n * ```\n *\n * @class Scheduler\n * @deprecated Scheduler is an internal implementation detail of RxJS, and\n * should not be used directly. Rather, create your own class and implement\n * {@link SchedulerLike}. Will be made internal in v8.\n */\nexport class Scheduler implements SchedulerLike {\n public static now: () => number = dateTimestampProvider.now;\n\n constructor(private schedulerActionCtor: typeof Action, now: () => number = Scheduler.now) {\n this.now = now;\n }\n\n /**\n * A getter method that returns a number representing the current time\n * (at the time this function was called) according to the scheduler's own\n * internal clock.\n * @return {number} A number that represents the current time. May or may not\n * have a relation to wall-clock time. May or may not refer to a time unit\n * (e.g. milliseconds).\n */\n public now: () => number;\n\n /**\n * Schedules a function, `work`, for execution. May happen at some point in\n * the future, according to the `delay` parameter, if specified. May be passed\n * some context object, `state`, which will be passed to the `work` function.\n *\n * The given arguments will be processed an stored as an Action object in a\n * queue of actions.\n *\n * @param {function(state: ?T): ?Subscription} work A function representing a\n * task, or some unit of work to be executed by the Scheduler.\n * @param {number} [delay] Time to wait before executing the work, where the\n * time unit is implicit and defined by the Scheduler itself.\n * @param {T} [state] Some contextual data that the `work` function uses when\n * called by the Scheduler.\n * @return {Subscription} A subscription in order to be able to unsubscribe\n * the scheduled work.\n */\n public schedule(work: (this: SchedulerAction, state?: T) => void, delay: number = 0, state?: T): Subscription {\n return new this.schedulerActionCtor(this, work).schedule(state, delay);\n }\n}\n", "import { Scheduler } from '../Scheduler';\nimport { Action } from './Action';\nimport { AsyncAction } from './AsyncAction';\nimport { TimerHandle } from './timerHandle';\n\nexport class AsyncScheduler extends Scheduler {\n public actions: Array> = [];\n /**\n * A flag to indicate whether the Scheduler is currently executing a batch of\n * queued actions.\n * @type {boolean}\n * @internal\n */\n public _active: boolean = false;\n /**\n * An internal ID used to track the latest asynchronous task such as those\n * coming from `setTimeout`, `setInterval`, `requestAnimationFrame`, and\n * others.\n * @type {any}\n * @internal\n */\n public _scheduled: TimerHandle | undefined;\n\n constructor(SchedulerAction: typeof Action, now: () => number = Scheduler.now) {\n super(SchedulerAction, now);\n }\n\n public flush(action: AsyncAction): void {\n const { actions } = this;\n\n if (this._active) {\n actions.push(action);\n return;\n }\n\n let error: any;\n this._active = true;\n\n do {\n if ((error = action.execute(action.state, action.delay))) {\n break;\n }\n } while ((action = actions.shift()!)); // exhaust the scheduler queue\n\n this._active = false;\n\n if (error) {\n while ((action = actions.shift()!)) {\n action.unsubscribe();\n }\n throw error;\n }\n }\n}\n", "import { AsyncAction } from './AsyncAction';\nimport { AsyncScheduler } from './AsyncScheduler';\n\n/**\n *\n * Async Scheduler\n *\n * Schedule task as if you used setTimeout(task, duration)\n *\n * `async` scheduler schedules tasks asynchronously, by putting them on the JavaScript\n * event loop queue. It is best used to delay tasks in time or to schedule tasks repeating\n * in intervals.\n *\n * If you just want to \"defer\" task, that is to perform it right after currently\n * executing synchronous code ends (commonly achieved by `setTimeout(deferredTask, 0)`),\n * better choice will be the {@link asapScheduler} scheduler.\n *\n * ## Examples\n * Use async scheduler to delay task\n * ```ts\n * import { asyncScheduler } from 'rxjs';\n *\n * const task = () => console.log('it works!');\n *\n * asyncScheduler.schedule(task, 2000);\n *\n * // After 2 seconds logs:\n * // \"it works!\"\n * ```\n *\n * Use async scheduler to repeat task in intervals\n * ```ts\n * import { asyncScheduler } from 'rxjs';\n *\n * function task(state) {\n * console.log(state);\n * this.schedule(state + 1, 1000); // `this` references currently executing Action,\n * // which we reschedule with new state and delay\n * }\n *\n * asyncScheduler.schedule(task, 3000, 0);\n *\n * // Logs:\n * // 0 after 3s\n * // 1 after 4s\n * // 2 after 5s\n * // 3 after 6s\n * ```\n */\n\nexport const asyncScheduler = new AsyncScheduler(AsyncAction);\n\n/**\n * @deprecated Renamed to {@link asyncScheduler}. Will be removed in v8.\n */\nexport const async = asyncScheduler;\n", "import { AsyncAction } from './AsyncAction';\nimport { Subscription } from '../Subscription';\nimport { QueueScheduler } from './QueueScheduler';\nimport { SchedulerAction } from '../types';\nimport { TimerHandle } from './timerHandle';\n\nexport class QueueAction extends AsyncAction {\n constructor(protected scheduler: QueueScheduler, protected work: (this: SchedulerAction, state?: T) => void) {\n super(scheduler, work);\n }\n\n public schedule(state?: T, delay: number = 0): Subscription {\n if (delay > 0) {\n return super.schedule(state, delay);\n }\n this.delay = delay;\n this.state = state;\n this.scheduler.flush(this);\n return this;\n }\n\n public execute(state: T, delay: number): any {\n return delay > 0 || this.closed ? super.execute(state, delay) : this._execute(state, delay);\n }\n\n protected requestAsyncId(scheduler: QueueScheduler, id?: TimerHandle, delay: number = 0): TimerHandle {\n // If delay exists and is greater than 0, or if the delay is null (the\n // action wasn't rescheduled) but was originally scheduled as an async\n // action, then recycle as an async action.\n\n if ((delay != null && delay > 0) || (delay == null && this.delay > 0)) {\n return super.requestAsyncId(scheduler, id, delay);\n }\n\n // Otherwise flush the scheduler starting with this action.\n scheduler.flush(this);\n\n // HACK: In the past, this was returning `void`. However, `void` isn't a valid\n // `TimerHandle`, and generally the return value here isn't really used. So the\n // compromise is to return `0` which is both \"falsy\" and a valid `TimerHandle`,\n // as opposed to refactoring every other instanceo of `requestAsyncId`.\n return 0;\n }\n}\n", "import { AsyncScheduler } from './AsyncScheduler';\n\nexport class QueueScheduler extends AsyncScheduler {\n}\n", "import { QueueAction } from './QueueAction';\nimport { QueueScheduler } from './QueueScheduler';\n\n/**\n *\n * Queue Scheduler\n *\n * Put every next task on a queue, instead of executing it immediately\n *\n * `queue` scheduler, when used with delay, behaves the same as {@link asyncScheduler} scheduler.\n *\n * When used without delay, it schedules given task synchronously - executes it right when\n * it is scheduled. However when called recursively, that is when inside the scheduled task,\n * another task is scheduled with queue scheduler, instead of executing immediately as well,\n * that task will be put on a queue and wait for current one to finish.\n *\n * This means that when you execute task with `queue` scheduler, you are sure it will end\n * before any other task scheduled with that scheduler will start.\n *\n * ## Examples\n * Schedule recursively first, then do something\n * ```ts\n * import { queueScheduler } from 'rxjs';\n *\n * queueScheduler.schedule(() => {\n * queueScheduler.schedule(() => console.log('second')); // will not happen now, but will be put on a queue\n *\n * console.log('first');\n * });\n *\n * // Logs:\n * // \"first\"\n * // \"second\"\n * ```\n *\n * Reschedule itself recursively\n * ```ts\n * import { queueScheduler } from 'rxjs';\n *\n * queueScheduler.schedule(function(state) {\n * if (state !== 0) {\n * console.log('before', state);\n * this.schedule(state - 1); // `this` references currently executing Action,\n * // which we reschedule with new state\n * console.log('after', state);\n * }\n * }, 0, 3);\n *\n * // In scheduler that runs recursively, you would expect:\n * // \"before\", 3\n * // \"before\", 2\n * // \"before\", 1\n * // \"after\", 1\n * // \"after\", 2\n * // \"after\", 3\n *\n * // But with queue it logs:\n * // \"before\", 3\n * // \"after\", 3\n * // \"before\", 2\n * // \"after\", 2\n * // \"before\", 1\n * // \"after\", 1\n * ```\n */\n\nexport const queueScheduler = new QueueScheduler(QueueAction);\n\n/**\n * @deprecated Renamed to {@link queueScheduler}. Will be removed in v8.\n */\nexport const queue = queueScheduler;\n", "import { AsyncAction } from './AsyncAction';\nimport { AnimationFrameScheduler } from './AnimationFrameScheduler';\nimport { SchedulerAction } from '../types';\nimport { animationFrameProvider } from './animationFrameProvider';\nimport { TimerHandle } from './timerHandle';\n\nexport class AnimationFrameAction extends AsyncAction {\n constructor(protected scheduler: AnimationFrameScheduler, protected work: (this: SchedulerAction, state?: T) => void) {\n super(scheduler, work);\n }\n\n protected requestAsyncId(scheduler: AnimationFrameScheduler, id?: TimerHandle, delay: number = 0): TimerHandle {\n // If delay is greater than 0, request as an async action.\n if (delay !== null && delay > 0) {\n return super.requestAsyncId(scheduler, id, delay);\n }\n // Push the action to the end of the scheduler queue.\n scheduler.actions.push(this);\n // If an animation frame has already been requested, don't request another\n // one. If an animation frame hasn't been requested yet, request one. Return\n // the current animation frame request id.\n return scheduler._scheduled || (scheduler._scheduled = animationFrameProvider.requestAnimationFrame(() => scheduler.flush(undefined)));\n }\n\n protected recycleAsyncId(scheduler: AnimationFrameScheduler, id?: TimerHandle, delay: number = 0): TimerHandle | undefined {\n // If delay exists and is greater than 0, or if the delay is null (the\n // action wasn't rescheduled) but was originally scheduled as an async\n // action, then recycle as an async action.\n if (delay != null ? delay > 0 : this.delay > 0) {\n return super.recycleAsyncId(scheduler, id, delay);\n }\n // If the scheduler queue has no remaining actions with the same async id,\n // cancel the requested animation frame and set the scheduled flag to\n // undefined so the next AnimationFrameAction will request its own.\n const { actions } = scheduler;\n if (id != null && actions[actions.length - 1]?.id !== id) {\n animationFrameProvider.cancelAnimationFrame(id as number);\n scheduler._scheduled = undefined;\n }\n // Return undefined so the action knows to request a new async id if it's rescheduled.\n return undefined;\n }\n}\n", "import { AsyncAction } from './AsyncAction';\nimport { AsyncScheduler } from './AsyncScheduler';\n\nexport class AnimationFrameScheduler extends AsyncScheduler {\n public flush(action?: AsyncAction): void {\n this._active = true;\n // The async id that effects a call to flush is stored in _scheduled.\n // Before executing an action, it's necessary to check the action's async\n // id to determine whether it's supposed to be executed in the current\n // flush.\n // Previous implementations of this method used a count to determine this,\n // but that was unsound, as actions that are unsubscribed - i.e. cancelled -\n // are removed from the actions array and that can shift actions that are\n // scheduled to be executed in a subsequent flush into positions at which\n // they are executed within the current flush.\n const flushId = this._scheduled;\n this._scheduled = undefined;\n\n const { actions } = this;\n let error: any;\n action = action || actions.shift()!;\n\n do {\n if ((error = action.execute(action.state, action.delay))) {\n break;\n }\n } while ((action = actions[0]) && action.id === flushId && actions.shift());\n\n this._active = false;\n\n if (error) {\n while ((action = actions[0]) && action.id === flushId && actions.shift()) {\n action.unsubscribe();\n }\n throw error;\n }\n }\n}\n", "import { AnimationFrameAction } from './AnimationFrameAction';\nimport { AnimationFrameScheduler } from './AnimationFrameScheduler';\n\n/**\n *\n * Animation Frame Scheduler\n *\n * Perform task when `window.requestAnimationFrame` would fire\n *\n * When `animationFrame` scheduler is used with delay, it will fall back to {@link asyncScheduler} scheduler\n * behaviour.\n *\n * Without delay, `animationFrame` scheduler can be used to create smooth browser animations.\n * It makes sure scheduled task will happen just before next browser content repaint,\n * thus performing animations as efficiently as possible.\n *\n * ## Example\n * Schedule div height animation\n * ```ts\n * // html:
\n * import { animationFrameScheduler } from 'rxjs';\n *\n * const div = document.querySelector('div');\n *\n * animationFrameScheduler.schedule(function(height) {\n * div.style.height = height + \"px\";\n *\n * this.schedule(height + 1); // `this` references currently executing Action,\n * // which we reschedule with new state\n * }, 0, 0);\n *\n * // You will see a div element growing in height\n * ```\n */\n\nexport const animationFrameScheduler = new AnimationFrameScheduler(AnimationFrameAction);\n\n/**\n * @deprecated Renamed to {@link animationFrameScheduler}. Will be removed in v8.\n */\nexport const animationFrame = animationFrameScheduler;\n", "import { Observable } from '../Observable';\nimport { SchedulerLike } from '../types';\n\n/**\n * A simple Observable that emits no items to the Observer and immediately\n * emits a complete notification.\n *\n * Just emits 'complete', and nothing else.\n *\n * ![](empty.png)\n *\n * A simple Observable that only emits the complete notification. It can be used\n * for composing with other Observables, such as in a {@link mergeMap}.\n *\n * ## Examples\n *\n * Log complete notification\n *\n * ```ts\n * import { EMPTY } from 'rxjs';\n *\n * EMPTY.subscribe({\n * next: () => console.log('Next'),\n * complete: () => console.log('Complete!')\n * });\n *\n * // Outputs\n * // Complete!\n * ```\n *\n * Emit the number 7, then complete\n *\n * ```ts\n * import { EMPTY, startWith } from 'rxjs';\n *\n * const result = EMPTY.pipe(startWith(7));\n * result.subscribe(x => console.log(x));\n *\n * // Outputs\n * // 7\n * ```\n *\n * Map and flatten only odd numbers to the sequence `'a'`, `'b'`, `'c'`\n *\n * ```ts\n * import { interval, mergeMap, of, EMPTY } from 'rxjs';\n *\n * const interval$ = interval(1000);\n * const result = interval$.pipe(\n * mergeMap(x => x % 2 === 1 ? of('a', 'b', 'c') : EMPTY),\n * );\n * result.subscribe(x => console.log(x));\n *\n * // Results in the following to the console:\n * // x is equal to the count on the interval, e.g. (0, 1, 2, 3, ...)\n * // x will occur every 1000ms\n * // if x % 2 is equal to 1, print a, b, c (each on its own)\n * // if x % 2 is not equal to 1, nothing will be output\n * ```\n *\n * @see {@link Observable}\n * @see {@link NEVER}\n * @see {@link of}\n * @see {@link throwError}\n */\nexport const EMPTY = new Observable((subscriber) => subscriber.complete());\n\n/**\n * @param scheduler A {@link SchedulerLike} to use for scheduling\n * the emission of the complete notification.\n * @deprecated Replaced with the {@link EMPTY} constant or {@link scheduled} (e.g. `scheduled([], scheduler)`). Will be removed in v8.\n */\nexport function empty(scheduler?: SchedulerLike) {\n return scheduler ? emptyScheduled(scheduler) : EMPTY;\n}\n\nfunction emptyScheduled(scheduler: SchedulerLike) {\n return new Observable((subscriber) => scheduler.schedule(() => subscriber.complete()));\n}\n", "import { SchedulerLike } from '../types';\nimport { isFunction } from './isFunction';\n\nexport function isScheduler(value: any): value is SchedulerLike {\n return value && isFunction(value.schedule);\n}\n", "import { SchedulerLike } from '../types';\nimport { isFunction } from './isFunction';\nimport { isScheduler } from './isScheduler';\n\nfunction last(arr: T[]): T | undefined {\n return arr[arr.length - 1];\n}\n\nexport function popResultSelector(args: any[]): ((...args: unknown[]) => unknown) | undefined {\n return isFunction(last(args)) ? args.pop() : undefined;\n}\n\nexport function popScheduler(args: any[]): SchedulerLike | undefined {\n return isScheduler(last(args)) ? args.pop() : undefined;\n}\n\nexport function popNumber(args: any[], defaultValue: number): number {\n return typeof last(args) === 'number' ? args.pop()! : defaultValue;\n}\n", "export const isArrayLike = ((x: any): x is ArrayLike => x && typeof x.length === 'number' && typeof x !== 'function');", "import { isFunction } from \"./isFunction\";\n\n/**\n * Tests to see if the object is \"thennable\".\n * @param value the object to test\n */\nexport function isPromise(value: any): value is PromiseLike {\n return isFunction(value?.then);\n}\n", "import { InteropObservable } from '../types';\nimport { observable as Symbol_observable } from '../symbol/observable';\nimport { isFunction } from './isFunction';\n\n/** Identifies an input as being Observable (but not necessary an Rx Observable) */\nexport function isInteropObservable(input: any): input is InteropObservable {\n return isFunction(input[Symbol_observable]);\n}\n", "import { isFunction } from './isFunction';\n\nexport function isAsyncIterable(obj: any): obj is AsyncIterable {\n return Symbol.asyncIterator && isFunction(obj?.[Symbol.asyncIterator]);\n}\n", "/**\n * Creates the TypeError to throw if an invalid object is passed to `from` or `scheduled`.\n * @param input The object that was passed.\n */\nexport function createInvalidObservableTypeError(input: any) {\n // TODO: We should create error codes that can be looked up, so this can be less verbose.\n return new TypeError(\n `You provided ${\n input !== null && typeof input === 'object' ? 'an invalid object' : `'${input}'`\n } where a stream was expected. You can provide an Observable, Promise, ReadableStream, Array, AsyncIterable, or Iterable.`\n );\n}\n", "export function getSymbolIterator(): symbol {\n if (typeof Symbol !== 'function' || !Symbol.iterator) {\n return '@@iterator' as any;\n }\n\n return Symbol.iterator;\n}\n\nexport const iterator = getSymbolIterator();\n", "import { iterator as Symbol_iterator } from '../symbol/iterator';\nimport { isFunction } from './isFunction';\n\n/** Identifies an input as being an Iterable */\nexport function isIterable(input: any): input is Iterable {\n return isFunction(input?.[Symbol_iterator]);\n}\n", "import { ReadableStreamLike } from '../types';\nimport { isFunction } from './isFunction';\n\nexport async function* readableStreamLikeToAsyncGenerator(readableStream: ReadableStreamLike): AsyncGenerator {\n const reader = readableStream.getReader();\n try {\n while (true) {\n const { value, done } = await reader.read();\n if (done) {\n return;\n }\n yield value!;\n }\n } finally {\n reader.releaseLock();\n }\n}\n\nexport function isReadableStreamLike(obj: any): obj is ReadableStreamLike {\n // We don't want to use instanceof checks because they would return\n // false for instances from another Realm, like an

Let us get a quick look at the naming convention to get a basic idea what is going on before we start.

The first letter indicates a type of animation (transition - t_ - or state - s_). Then depending on the animation type we have:

Transition animation

t_Run_2_Sneak
-
Transition animation from the run animation to the sneak animation.
t_BSANVIL_Stand_2_S0
-
Transition animation for the blacksmith's anvil from standing to state 0.

State animation

s_Run
-
State animation for the looping animation.
s_BSANVIL_S0
-
State animation for the blacksmith's anvil and its first state.

ani

This is the main command you will be using while defining new animations.

Example:

ani    ("t_Yes" 2 "" 0.1 0.1 M. "Hum_Yes_M01.asc" F 1 44)
-
Syntax:
ani (ANI_NAME LAYER NEXT_ANI BLEND_IN BLEND_OUT FLAGS ASC_NAME ANI_DIR START_FRAME END_FRAME)
-
ani - is a keyword, we are defining new animation

Let's describe all the parameters

ANI_NAME - animation name, we use it in Daedalus as animation identifier

There is a naming convention, that is recommended and sometimes required to be used.

  • prefix t_ - transition animations
  • prefix s_ - state animations - they usually run in a loop
  • prefix c_ - animations used for animation combining/interpolation

LAYER - layer number for multi-layer animations

NEXT_ANI - name of the next animations

BLEND_IN - time in seconds describing animation blending at the start

If we set it to 0.5, it takes 0.5 seconds for this animation to take full effect. At 0.0 s the previous animation has full effect on the bones of the skeleton, at 0.1 s it is influenced by 20% by this animation and at 0.5s it is completely influenced by this animation and the previous one has no effect.

BLEND_OUT - time in seconds describing animation blending at the end

FLAGS - flags, that describe animation behavior

  • M - specifies a movement animation, the animation of the model translates into a changed position in the game world
  • R - the same as M but for rotation
  • E - this flag makes this animation run only, if the animation in the same layer are finished, this is used in the movement animations. The animation s_walk (walking loop animation) runs, when the player is walking,when he stops the transition animation to standing state is played t_walk_2_stand. This animation uses the E flag to wait for the walk cycle animation to finish, to smoothly transition into the standing state.
  • F - the engine ignores height coordinate - doesn't keep the model "glued" to the ground (falling/flying animation)
  • I - specifies idle animation - breathing, standing with a drawn weapon and moving the weapon

ASC_NAME - name of the source file exported from Blender

ANI_DIR - direction of the animation

  • F - forward
  • R - reverse

START_FRAME - on what frame from the source file the animation starts

END_FRAME - on what frame from the source file the animation ends

aniAlias

Generally considered as one of the most useful commands, aniAlias is used to create an alias (hard link for UNIX users) for an already defined animation.

Example:

aniAlias ("t_Sneak_2_Run" 1 "s_Run" 0.0    0.1    M. "t_Run_2_Sneak" R)
-
Syntax:
aniAlias (ANI_NAME LAYER NEXT_ANI BLEND_IN BLEND_OUT FLAGS ALIAS_NAME ANI_DIR)
-

ANI_NAME - name of the new animation

LAYER - layer the animation is on

NEXT_ANI - name of the next animations

BLEND_IN - time in seconds describing animation blending at the start

BLEND_OUT - time in seconds describing animation blending at the end

FLAGS - flags, that describe animation behavior

ALIAS_NAME - name of the animation we want to use as a source for the alias

ANI_DIR - direction of the animation

If we look for the animation in the example we can see that there is a related one just one line above

1
-2
ani            ("t_Run_2_Sneak" 1 "s_Sneak" 0.1 0.0 M. "Hum_Sneak_M01.asc"     F 0 10)
-aniAlias    ("t_Sneak_2_Run" 1 "s_Run"      0.0 0.1 M. "t_Run_2_Sneak"      R)
-
In this example we are defining t_Sneak_2_Run animation and we are specifying that the animation after this one is finished will be s_Run and that it is being made by reversing animation t_Run_2_Sneak by specifying the R flag.

aniBlend

AniBlend is used to define animations that are a result of blending of two animations. This animation is not animated by hand, but it is dynamically generated by the engine during run-time.

Example

aniBlend ("t_RunR_2_Run" "s_Run" 0.2 0.2)
-
Syntax:
aniBlend (ANI_NAME NEXT_ANI BLEND_IN BLEND_OUT)
-

ANI_NAME - name of the new animation

NEXT_ANI - name of the next animations

BLEND_IN - time in seconds describing animation blending at the start

BLEND_OUT - time in seconds describing animation blending at the end

aniSync

Not used in the game.

aniBatch

Not used in the game.

Animation state machine

More complex animations such as MOBSI animations form a state machine - an animation set.

MDS script for the big chest
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
Model ("CHESTBIG_OCCRATELARGE")
-{
-    meshAndTree ("CHESTBIG_OCCRATELARGE.asc")
-
-    aniEnum
-    {
-// Closed chest
-        ani         ("s_S0"                 1   "s_S0"  0.0 0.0 M.  "CHESTBIG_USE.asc"  F   20  20)
-// Opening the chest 
-        ani         ("t_S0_2_S1"            1   "s_S1"  0.0 0.0 M.  "CHESTBIG_USE.ASC"  F   50  79)
-        {
-            *eventSFX   (50 "chest_try")
-            *eventSFX   (55 "chest_open")
-        }
-// Opened chest
-        ani         ("s_S1"                 1   "s_S1"  0.0 0.0 M.  "CHESTBIG_USE.asc"  F   80  80)
-// Closing the chest
-        ani         ("t_S1_2_S0"            1   "s_S0"  0.0 0.0 M.  "CHESTBIG_USE.asc"  R   50  79)
-        {
-            *eventSFX   (78 "chest_close")
-        }
-// Pick lock broken
-        ani         ("t_S0_Try"             1   "s_S0"  0.0 0.0 M.  "CHESTBIG_USE.asc"          F   96  124)
-        {
-            *eventSFX   (100    "chest_try")
-            *eventSFX   (115    "Hammer")
-        }
-    }
-}
-
stateDiagram-v2
-    s_S0      : Closed chest
-    t_S0_2_S1 : Opening the chest
-    s_S1      : Opened chest
-    t_S1_2_S0 : Closing the chest
-    t_S0_Try  : Pick lock broken
-    [*] --> s_S0
-    s_S0 --> s_S0
-
-    s_S0 --> t_S0_2_S1
-    t_S0_2_S1 --> s_S1
-    s_S1 --> s_S1
-
-    s_S1 --> t_S1_2_S0
-    t_S1_2_S0 --> s_S0
-
-    s_S0 --> t_S0_Try
-    t_S0_Try --> s_S0
\ No newline at end of file diff --git a/cs/zengin/anims/standalone_ani/index.html b/cs/zengin/anims/standalone_ani/index.html deleted file mode 100644 index 40570b3c17..0000000000 --- a/cs/zengin/anims/standalone_ani/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/cs/zengin/anims/tutorials/standalone_animation/index.html b/cs/zengin/anims/tutorials/standalone_animation/index.html deleted file mode 100644 index 4f8b29cd32..0000000000 --- a/cs/zengin/anims/tutorials/standalone_animation/index.html +++ /dev/null @@ -1,88 +0,0 @@ - Standalone animation - Gothic Modding Community

Standalone animation

Acknowledgment

This tutorial would not be possible without the ZenGin documentation available in the mod-kit. Further credits also go to Mark56 who helped me understand animations in the first place, Fawkes and his request for me to do some animations for his excellent mod - Replay Mod, and last but not least Flosha from the Phoenix team who was the one for whom I offered to write this tutorial to help with the development of the Phoenix project.

Let us start with the easiest animation - a very simple gesturing animation.

Info

You can find some of the videos that are mentioned in the text below in this play-list.

Firstly we have to have the animation source files ready. Best way to decompile them is using Gothic Sourcer. In GothicSourcer you choose Tools > Decompiler models > Dynamic (MDS or MSB) and choose an MDS file of your choice - Humans.mds in our case and then click the decompile button.

Animating

Open Blender, File > Import > Kerrax ASCII model (.asc), navigate to the folder with your decompiled animation files and select HUM_BODY_NAKED0.ASC. This file contains the skeleton and skin model for human NPCs.

What bone hierarchy is this model using?

If you open the .mds file, you can see a command meshAndTree that specifies what model contains the skeleton. And there lies our answer:

1
-2
-3
Model ("HuS")
-{
-    meshAndTree ("Hum_Body_Naked0.ASC" DONT_USE_MESH)
-

A windows pops up and you can read some interesting information about the model you are about to import. We are interested in the fact that Completely replace current scene is ticked, we want to use Armature modifier, and we also want to Try to connect bones and Use sample meshes from folder. You should provide a path to a directory with the sample meshes - these are meshes for items, that usually go into slot bones. Lastly, the space transformation scale should be set to 0.01. This is because ZenGin works with centimeter units and one unit in Blender is a meter.

Click import and wait for the magic to happen.

This video shows a freshly imported model with all default meshes.

Note

If we now want to play (or edit) existing animation, we can now load it on top of this. Just as before File > Import > Kerrax ASCII model (.asc) and select different animation file (or armor file), for example Hum_SmokeHerb_Layer_M01.asc for an animation file.

Gothic characters are modular and you can change their heads on the fly, even during gameplay as seen in this amazing video from my dear friend and colleague Fawkes - Head changing. Let's add a head so that we can see how the whole body will behave while we are animating. File > Import > Kerrax ASCII model (.asc), navigate to your head model. You will have to decompile it like we did with the body itself. We will import HUM_HEAD_PONY.ASC. Please make sure to select the target bone for importing Bip01 Head, this will attach the head to the proper bone, just like the engine does it.

Now we have everything ready to start animating. The video shows the DopeSheet a nice way to edit keyframes.

DopeSheet

Blender's dope sheet can be used to copy entire sets of keyframes. It is useful if we want to create a looping animation.

We can import an animation into Blender as a base.

Tip

If you don't know the name of the animation, just go into the game and make your character perform the animation you want. While in MARVIN mode, you can press G and the animation information together with other info will be displayed right on the screen

In this video we can see that the idle standing animation is s_run. We want to make an animation that is going to start from this idle animation, so we will import it into blender. We find it by looking into the .mds file, look for s_run name and get the name of the file.

ani    ("s_Run" 1 "s_Run" 0.1 0.1 MI "Hum_RunAmbient_M01.asc" F 1 50)  
-
As we can see, we have to import the Hum_RunAmbient_M01.asc file.

Next goes the first trick. Since we want our animation to end exactly, as it started - ether because we want the hero to continue his standing animation, or we want to make a looping animation, we somehow have to copy the pose. We use the DopeSheet screen, to delete all keyframes and then copy the keyframe set from keyframe number 0 and drag it somewhere to the end of the timeline.

Once the animation is done, we have to export it into an asc format again, File > Export > Kerrax ASCII model (.asc) and then save it to _work\data\Anims\asc\ so the engine can see it and convert it.
There are many options here that we will explore later, but we have tick Export animation and pick bones that we want to export - this is useful for animations that are played on different layers (dialogue gestures, scratching head, scratching a shoulder,...).

Animation script

Now that we have exported the animation, we now have to define it in Humans.mds.

Open the file, scroll to the end and define a new animation.

Attention

All ani code has to be between the curly brackets, this means you have to insert it before the last two closing curly brackets } }.

Example:

ani ("t_backpain" 1 "" 0.0 0.0 M. "Hum_back.ASC" F 0 121)  
-

Save the Humans.mds file and try it in game. Nothing happens! The reason is that the mds has been already compiled, and we have to recompile it. The easiest is to go to Anims\_compiled and delete HUMANS.MSB.
Run the game and try to play the animation again (play ani t_backpain in MARVIN console) and now everything should work.

Amazing, now you have your first animation in the game. And you can use it to do some fun stuff, like in dialogues using the AI_PlayAni function.

Example dialogue

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
instance DIA_Xardas_Back (C_INFO)
-{
-    npc         = NONE_100_Xardas;
-    nr          = 11;
-    condition   = DIA_Xardas_Back_Condition;
-    information = DIA_Xardas_Back_Info;
-    permanent   = TRUE;
-    description = "What's wrong?";
-};
-
-func int DIA_Xardas_Back_Condition () {
-    return TRUE;
-};
-
-func void DIA_Xardas_Back_Info () {
-    AI_Output (self, hero, "DIA_Xardas_MOB_14_00"); // My back hurts so much.
-
-    // This is our animation!!!!!
-    AI_PlayAni(self, "T_BACKPAIN"); 
-    AI_Output (self, hero, "DIA_Xardas_MOB_14_01"); // How do YOU feel?
-
-    AI_Output (hero, self, "DIA_Xardas_MOB_14_02"); // My back is fine.
-    AI_StopProcessInfos(self);
-};
-

\ No newline at end of file diff --git a/cs/zengin/general_info/directory_structure/index.html b/cs/zengin/general_info/directory_structure/index.html deleted file mode 100644 index 73cb1467a6..0000000000 --- a/cs/zengin/general_info/directory_structure/index.html +++ /dev/null @@ -1,81 +0,0 @@ - Directory structure - Gothic Modding Community

ZenGin directory structure

Modding is all about changing the game files. To achieve that, we have to know the directory (folder) structure of a Gothic game.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
├── Data
-│   ├── $Templates$
-│   ├── modvdf
-│   └── Plugins
-├── Miles
-├── Saves
-├── System
-│   └── Autorun
-└── _work
-    └── DATA
-        ├── Anims
-        │   └── _Compiled
-        ├── Meshes
-        │   └── _Compiled
-        ├── Music
-        ├── Presets
-        ├── Scripts
-        │   ├── _compiled
-        │   └── content
-        │       └── CUTSCENE
-        ├── Sound
-        ├── Textures
-        ├── Video
-        └── Worlds
-

Data

Data directory contains .vdf volumes of the game. These contain anims.vdf - animations, speech.vdf - dubbing, worlds.vdf - world ZEN files.

Saves

Contains saved games.

System

The system directory contains the game executable, GothicStarter.exe, GothicStarter_mod.exe, configuration .ini files, mod .ini files and mod icons and description .rtf files.

system/Autorun is a Union specific directory, it serves as a default search directory for Daedalus injection scripts with zParserExtender and Union plugins.

_work/DATA

This is where the magic happens:

  • Anims - contains animations and animated models.
    • _compiled - contains compiled animations.
  • Meshes - contains meshes source and compiled files.
    • _compiled - contains compiled meshes.
  • Music - contains music files.
  • Presets - contains basic presets.
  • Scripts
    • _compiled - contains compiled scripts - .dat files.
    • Content - contains scripts that make up the content of the game.
    • System - contains scripts that make up the menu.
  • Sound - contains sound effects .wav or .ogg format (Union only).
  • Video - contains videos in .bik format.
\ No newline at end of file diff --git a/cs/zengin/general_info/object_persistence/index.html b/cs/zengin/general_info/object_persistence/index.html deleted file mode 100644 index c7c5ed4991..0000000000 --- a/cs/zengin/general_info/object_persistence/index.html +++ /dev/null @@ -1,376 +0,0 @@ - Object persistence - Gothic Modding Community

Object persistence

In order to simplify the process of loading and saving data of various types to and from the user's hard-drive, ZenGin implements a simple object persistence system using the zCArchiver class and its derivatives that allow the individual engine classes to implement a routine specifying which data should be saved or loaded from disk and in which manner.

An object that is derived from the zCObject class may overload the Archive and Unarchive virtual methods. The class may then call on an interface provided by the zCArchiver class within these methods which allows it to directly read from or write to a stream using several modes. Those are ASCII and BinSafe by default. There are, however, more options, as is explained below.

Archive format

In order to better understand how this process works, it would be best to look at an example of a .ZEN file containing an instance of an oCWorld object.

When you open up a ZenGin archive, you will see the following at the start of the file:

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
ZenGin Archive
-ver 1
-zCArchiverGeneric
-ASCII
-saveGame 0
-date 7.1.2001 23:9:19
-user roeske
-END
-objects 2594     
-END
-

Let's look at each of these properties and what they mean:

ZenGin Archive

This simply specifies that the following data is an zCArchiver archive.

ver 1

Version specification. Can be either 0 or 1. Both Gothic 1 and 2 are already on version 1, although version 0 archives can also be occasionally found.

zCArchiverGeneric

Specifies which derived zCArchiver class should be used to read this archive. Accepted values are zCArchiverGeneric for ASCII and Binary archives, and zCArchiverBinSafe for BinSafe archives. More info below.
This property might not be present in older archives.

ASCII

This is the most important part of the header as it specifies in which format should the data be stored. There are 4 different modes:

  • ASCII - The simplest one. It stores data in human-readable ASCII notation (not unlike JSON for example). This is usually used when saving data during development and/or testing, while the final version of said data will most likely be stored as BIN_SAFE.
  • ASCII_PROPS - Same as ASCII except with more additional data that the developer can specify for visual clarity. In practice, it is not used anywhere and mostly serves only to prettify debug info (try typing ZWORLD VOBPROPS in the console and look in zSpy ;) ).
  • BINARY - Binary representation of the class instance, which mostly copies the data 1:1 into/from the stream. In practice, this format is only used to store savefiles (.SAV).
  • BIN_SAFE - BinSafe, short for Binary Safe, is an extended version of Binary which stores type information along with the data itself. This is meant to make error checking for invalid data easier. There are other changes which are explained below. Most, if not all world files (.ZEN), are stored in this format.

saveGame 0

Specifies if this archive is a savefile. This property might not be present in older archives.

date 7.1.2001 23:9:19

The date at which this archive was created.

user roeske

The user which created the archive. This property might not be present in older archives.

END

Tells the parses that this is the end of the header.

We may additionally find a property called csum in version 0 archives which stores the checksum of the whole archive. This property is, however, unused and equals 00000000 by default.

In order to correctly read the archive's header across varying engine versions, one should not count on the properties always being in the same order or even being there at all.

If the archive utilizes zCArchiverGeneric then this header will also be followed by a short section specifying the number of object instances in this archive. This value will be used to initialize the objectList, which is an array of pointers where the addresses of loaded objects will be stored for later referencing. This property would be directly part of the main header in older versions.

objects 2594 END  
-

If the archive is created using zCArchiverBinSafe, this data will be stored in the following binary structure:

1
-2
-3
-4
struct BinSafeArchiveHeader  
-{  
-    uint32_t version;     // Always equals 2 uint32_t objectCount;  // Serves the same function as "objects n" uint32_t chunkPos;    // Offset to chunk hash table};
-};  
-

Contents

Looking further into the archive, we see what appears to be a nested structure.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
[% oCWorld:zCWorld 64513 0]
-    [VobTree % 0 0]
-        childs0=int:1
-        [% zCVobLevelCompo:zCVob 12289 1]
-            pack=int:0
-            presetName=string:
-            bbox3DWS=rawFloat:-71919.9609 -13091.8232 -59900 108999.992 20014.0352 67399.9922 
-            trafoOSToWSRot=raw:0000803f0000000000000000000000000000803f0000000000000000000000000000803f
-            trafoOSToWSPos=vec3:0 0 0
-            vobName=string:LEVEL-VOB
-            visual=string:SURFACE.3DS
-            showVisual=bool:0
-            visualCamAlign=enum:0
-            cdStatic=bool:1
-            cdDyn=bool:0
-            staticVob=bool:0
-            dynShadow=enum:0
-            [visual zCMesh 0 2]
-            []
-            [ai % 0 0]
-            []
-        []
-        ...
-

We primarily differentiate between chunks and properties within ZenGin archives:

Chunks

A chunk is a structure that groups properties together. For most of the time, a chunk represents a class instance. This is, however, not always true as classes may arbitrarily create chunks as is needed. For example, the sample above contains a chunk called VobTree, which does not represent a class instance, but only serves to make the reading of the archive easier.

While in ASCII mode, the start of a chunk is represented using square brackets.

[% oCWorld:zCWorld 64513 0]

There are 4 pieces of data separated by spaces inside the start of each chunk, which are:

  • Object name - The name of the chunk to use while reading. If the chunk has no name, then it will be simply equal to %.
  • Class name - The name of the class which this chunk represents. Class names are stored with their full inheritance hierarchy (e.g. oCMobLadder:oCMobInter:oCMOB:zCVob). In case the chunk is not an object, but an arbitrary chunk, then this field will be equal to % (% can also mean that this chunk is a nullptr). In some cases you may encounter the symbol § instead. This means that the object already exists and that the parser should look for it in the objectList using the object index. Using this mechanism, a single instance can be referenced multiple times without worrying about duplicity.
  • Class version - Used to ensure that the data being read is compatible with the current game/engine version, so that there are no mismatches in the data pattern. This value is different for every class and varies between game versions.
  • Object index - An index into the objectList under which this object will be stored. If the class name is equal to §, then this value will be used to retrieve an existing instance from the objectList.

If this is a Binary archive, the same data will be stored in the following binary structure:

1
-2
-3
-4
-5
-6
-7
-8
struct BinaryObjectHeader
-{
-    uint32_t    objectSize;        // Size of the whole object in bytes
-    uint16_t    classVersion;
-    uint32_t    objectIndex;
-    char        objectName[];    // Null-terminated string
-    char        className[];    // Null-terminated string
-};
-

Oddly enough, if the archive is BinSafe, then the data will be encoded the same way as in ASCII mode, except that it will be stored as a type-checked property.

1
-2
-3
-4
-5
-6
struct BinSafeObjectHeader
-{
-    uint32_t    type;    // 0x1 = TYPE_STRING
-    uint16_t    length;    // Length of the text
-    char        text[];    // [% oCWorld:zCWorld 64513 0]
-};
-

In ASCII mode [] represents the end of the current chunk.

Properties

We find properties inside the chunks which are key-value pairs that classes use to store the actual data. Each property stores its name, type and value. In ASCII mode the format for this isname=type:value.

For example:

visual=string:SURFACE.3DS

By default, zCArchiver allows to store properties of the following types:

  • Int - A regular 32-bit integer. In ASCII mode, int gets stored as name=int:1, while in Binary mode, it's just the raw value stored as 4 bytes.

  • Byte - A 8-bit integer. ASCII mode doesn't differentiate between Int and Byte, so this will be stored as name=int:1 regardless. Binary mode stores only the single byte.

  • Word - A 16-bit integer. ASCII mode doesn't differentiate between Int and Word, so this will be stored as name=int:1 regardless. Binary mode stores only the 2 bytes.

  • Float - A standard IEEE 754 32-bit floating point number. In ASCII mode the format is name=float:1.0, while in Binary mode the float gets stored raw as 4 bytes.

  • Bool - Stores a single-byte boolean value. In ASCII mode its name=bool:1 and in Binary mode it's a single byte.

  • String - An ASCII encoded string. While in ASCII mode, strings are stored as name=string:value. In Binary mode, strings are NULL terminated.

  • Vec3 - A three component vector, mainly used to store positional data. The ASCII mode format is name=vec3:1.0 1.0 1.0. In Binary mode the three components of the vector are stored in series, which equals to a total size of 12 bytes.

  • Color - A 32-bit color value stored as BGRA. In ASCII mode the color is stored as name=color:255 255 255 255 while in Binary mode it's just 4 raw bytes.

  • Raw - Raw binary data. In order to maintain readability, in ASCII mode this gets stored as a hex encoded string such as name=raw:63D15B07. In Binary mode, only the data itself is stored, without any other info. Be aware that due to this you must know the size of the data beforehand.

  • RawFloat - An array of floats, mainly used to store bounding boxes. In ASCII mode, the floats are stored as name=rawFloat:1.0 1.0 1.0 1.0 1.0 1.0. In Binary mode the floats are stored in series as raw bytes. Same as with Raw, you must know the size of the array beforehand.

  • Enum - An enum value. In ASCII mode, it gets stored as name=enum:1. In Binary mode, it behaves the same as Int.

As you might have noticed, binary mode doesn't perform any kind of checks on if it's reading the right property or even data of the correct type. This is why BinSafe mode exists, as it stores the property type in along with the data itself.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
-37
-38
-39
-40
-41
-42
-43
enum TYPE
-{
-    TYPE_STRING        = 0x1,
-    TYPE_INTEGER    = 0x2,
-    TYPE_FLOAT        = 0x3,
-    TYPE_BYTE        = 0x4,
-    TYPE_WORD        = 0x5,
-    TYPE_BOOL        = 0x6,
-    TYPE_VEC3        = 0x7,
-    TYPE_COLOR        = 0x8,
-    TYPE_RAW        = 0x9,
-    TYPE_RAWFLOAT    = 0x10,
-    TYPE_ENUM        = 0x11
-    TYPE_HASH        = 0x12,
-};
-
-struct BinSafeProperty
-{
-    TYPE type;
-    union
-    {
-        struct
-        {
-            uint16_t    stringLength;
-            char        stringValue[];
-        }
-        uint32_t    integerOrHashOrEnumValue;
-        float        floatValue;
-        uint8_t        byteOrBoolValue;
-        zVEC3        vec3Value;
-        zCOLOR        colorValue;
-        struct
-        {
-            uint16_t    rawLength;
-            char        rawValue[];
-        }
-        struct
-        {
-            uint16_t    rawFloatLength;
-            float        rawFloatValue[];
-        }        
-    };
-};
-

Looking at the enumeration of types, you might notice that BinSafe mode has an additional property type called Hash. BinSafe archives include a hash table which is stored in the following manner:

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
struct BinSafeHashTable
-{
-    uint32_t chunkCount;
-    for (chunkCount)
-    {
-        uint16_t    stringLength;
-        uint16_t    linearValue;
-        uint32_t    hashValue;
-        char        text[stringLength];
-    }
-};
-

Instead of storing the raw value, properties may save a hash instead, which is then used to look up the corresponding value from the hash table.

Implementation

As mentioned in the opening paragraph, classes may use the described functionality by overloading the Archive and Unarchive virtual methods, which pass an instance of zCArchiver by reference. When the class instance is then serialized and/or parsed, these methods are called and perform the desired serialization/parsing work.

The class uses methods provided by the zCArchiver instance within these routines. These methods return/accept a value of a specific type (e.g. ReadInt/WriteInt), while they do the actual reading/writing work behind the scenes based on the current mode (ASCII/Binary/BinSafe). The programmer writing the class then does not care whether the final archive will be saved as ASCII, Binary or BinSafe, as they only use the zCArchiver Read* and Write* methods.

A practical example

Let's propose that we have a class which is declared like so:

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
class zCMyClass : public zCObject
-{
-public:
-
-    zCMyClass()                {}
-    virtual ~zCMyClass()    {}
-
-    virtual void Archive(zCArchiver&);
-    virtual void Unarchive(zCArchiver&);
-
-    int myInt;
-    zCMyClass* myObject;
-    zCMyClass* secondPointerToMyObject;
-
-};
-

The hypothetical class then implements these virtual functions:

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
void zCMyClass::Archive(zCArchiver& archiver)
-{
-    archiver.WriteInt("myInt", myInt);
-
-    archiver.WriteObject("myObject", myObject);
-
-    archiver.WriteChunkStart("myChunk", 0);
-    archiver.WriteObject("secondPointerToMyObject", secondPointerToMyObject);
-    archiver.WriteChunkEnd();
-}
-
-void zCMyClass::Unarchive(zCArchiver& archiver)
-{
-    archiver.ReadInt("myInt", myInt);
-
-    myObject = dynamic_cast<zCMyClass*>(archiver.ReadObject("myObject"));
-
-    archiver.ReadChunkStart("myChunk");
-    secondPointerToMyObject = dynamic_cast<zCMyClass*>(archiver.ReadObject("secondPointerToMyObject"));
-    archiver.ReadChunkEnd();
-}
-

We then initialize the class in the following way:

1
-2
-3
-4
-5
-6
-7
-8
zCMyClass object;
-
-object.myInt = 12121212;
-
-object.myObject = new zCMyClass();
-object.myObject->myInt = 34343434;
-
-object.secondPointerToMyObject = object.myObject;
-

If we now serialized, or to use the engine's term "archived", this instance into an ASCII archive, the result would look like this:

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
ZenGin Archive
-ver 1
-zCArchiverGeneric
-ASCII
-saveGame 0
-date 3.7.2022 0:0:0
-user GMC
-END
-objects 2     
-END
-
-[% zCMyClass 0 0]
-    myInt=int:12121212
-    [myObject zCMyClass 0 1]
-        myInt=int:34343434
-        [myObject % 0 0]
-        []
-        [myChunk % 0 0]
-            [secondPointerToMyObject % 0 0]
-            []
-        []
-    []
-    [myChunk % 0 0]
-        [secondPointerToMyObject § 0 1]
-        []
-    []
-[]
-

Notice how secondPointerToMyObject doesn't have any contents. The character § tells the parser that this object already exists in the objectList, and that instead of creating a new instance, it should return an existing instance which is stored under index 1 in the objectList.
This allows an instance to be referenced from multiple places, without the need to worry about duplicity.

If we used Binary or BinSafe mode, we would see a big blob of binary data instead. This would, of course, store the exact same data, although in a slightly less human-readable format.

Final thoughts

We hope this helps you better understand the inner workings of ZenGin. If you want to see how Piranha Bytes went about implementing a much more advanced version of this system for their next engine, check out Genome's object persistence system.

\ No newline at end of file diff --git a/cs/zengin/general_info/vdfs/index.html b/cs/zengin/general_info/vdfs/index.html deleted file mode 100644 index 1cecc593cd..0000000000 --- a/cs/zengin/general_info/vdfs/index.html +++ /dev/null @@ -1,34 +0,0 @@ - VDFS virtual file system - Gothic Modding Community

VDFS

VDFS is the virtual file system used by ZenGin to distribute and store many, but not all, game assets.

Tools

The community created variety of different modding tools for work with VDFS volumes over the times, such as:

GothicVDFS

  • Viewing
  • Extracting
  • Building .mod and .vdf archives

VDFS Tool

  • Viewing
  • Extracting
  • Building
  • Optimizing
  • Compressing .mod and .vdf archives
\ No newline at end of file diff --git a/cs/zengin/index.html b/cs/zengin/index.html deleted file mode 100644 index 2ed1d58463..0000000000 --- a/cs/zengin/index.html +++ /dev/null @@ -1,34 +0,0 @@ - ZenGin - Gothic Modding Community

ZenGin

The game engine ZenGin is used by Gothic 1 and 2. This section contains the documentation of the various aspects of ZenGin modding.

\ No newline at end of file diff --git a/cs/zengin/meshes/index.html b/cs/zengin/meshes/index.html deleted file mode 100644 index 3aa6514a05..0000000000 --- a/cs/zengin/meshes/index.html +++ /dev/null @@ -1,34 +0,0 @@ - Meshes - Gothic Modding Community

Meshes

Everything about 3D models in ZenGin.

\ No newline at end of file diff --git a/cs/zengin/music/index.html b/cs/zengin/music/index.html deleted file mode 100644 index 8736860d34..0000000000 --- a/cs/zengin/music/index.html +++ /dev/null @@ -1,34 +0,0 @@ - Music - Gothic Modding Community

Music

Zengin uses DirectMusic for playing in-game soundtrack. To edit Gothic music files you need the Direct Music Producer, a program released by Microsoft and provided with older DirectX SDK.

Warning

Music files can't be packed in the .vdf or .mod archives, all music files must be located in /_work/Data/Music directory.

File formats

The music directory contains these file types:

  • .dls - Downloadable Sound format file. This is the base for all other files. Contains:

    • Collections of virtual musical instruments.
    • Wave files instruments use.
  • .sty - Style file. Contains:

    • Bands - settings for virtual instruments from .dls.
    • Patterns - fragments of tracks, that can be later merged, looped and superimposed on each other
  • .sgt - File with properly connected patterns - the final track

Alternative Music System

The zBassMusic plugin replaces Zengin's default music library with the much newer BASS library. This allows, among other things, to play music in such formats as .mp3 or .ogg, and to pack songs into .vdf and .mod archives.

\ No newline at end of file diff --git a/cs/zengin/scripts/classes/c_info/index.html b/cs/zengin/scripts/classes/c_info/index.html deleted file mode 100644 index 3f72aaee60..0000000000 --- a/cs/zengin/scripts/classes/c_info/index.html +++ /dev/null @@ -1,228 +0,0 @@ - C_INFO - Gothic Modding Community

C_INFO Daedalus class

Acknowledgment

Heavily inspired by the amazing documentation site Gothic library.

The C_INFO class is used to define dialogues in the game.

Class definition

Class definition as it is defined in Scripts/Content/_intern/Classes.d script file.

C_Info Daedalus class
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
class C_Info
-{
-    var int    npc;         // npc instance has the dialogue
-    var int    nr;          // number of the dialogue (for sorting)
-    var int    important;   // should the npc start the dialogue automatically
-    var func   condition;   // condition function
-    var func   information; // function called on selecting the dialogue
-    var string description; // text in the dialogue box
-    var int    trade;       // should the dialogue show the trade window
-    var int    permanent;   // should the dialogue be permanent or only one time deal
-};
-

Class members

Variable Type Description
npc int npc instance to have the dialogue
nr int dialogue order number
important int npc addresses player automatically
condition func condition function whether the dialogue is shown or not
information func function called on dialogue selection - contains the dialogue lines and other logic
description string text shown in the dialogue box
trade int is it a trade dialogue
permanent int does the dialogue stay after being played once

Class member overview

Description of the class member variables.

npc

Sets what NPC will have this dialogue instance. Set an NPC instance.

1
-2
-3
-4
-5
instance Info_Diego_Gamestart (C_INFO)
-{
-    npc    = PC_Thief; // NPC instance for Diego
-    // ...
-};
-

nr

The nr member variables determines the order of shown dialogues. Dialogues are ordered in the ascending order - instances with higher nr are below instances with lower nr.

1
-2
-3
-4
-5
-6
instance Info_Diego_Gamestart (C_INFO)
-{
-    // ...
-    nr = 1;
-    // ...
-};
-

Note

This is why the end dialogues usually have nr = 999; this is the highest number out of any dialogues therefore will always show up at the bottom. (999 is not the highest number the nr can store, it is just considered the highest number, as there will hardly be 998 dialogue instances for a single character)

important

The important member variable determines whether the NPC will automatically address the player or not.

  • important = TRUE - the NPC will address the player
  • important = FALSE - the player has to talk to the NPC

When important is set to TRUE, the description is not needed since the dialogue is never shown in the dialogue box.

Info

If there are multiple important dialogues that satisfy their condition function, they will be played in the order specified by nr.

Tip

important variable is of the type integer, and it is initialized by the engine to the value of 0. If you do not want your dialogue to be important, you can omit the important member variable since it will be initialized to 0 by the engine.

condition

Condition function with signature func int f(). If the function returns TRUE the dialogue is displayed, if it returns FALSE it is not displayed. The function name does not have to follow a particular naming convention, but a naming convention is used throughout all the Gothic scripts: {DialogueName}_Condition.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
instance Info_Diego_Gamestart (C_INFO)
-{
-    // ...
-    condition = Info_Diego_Gamestart_Condition;
-    // ...
-};
-
-func int Info_Diego_Gamestart_Condition()
-{
-    if (Kapitel < 2) // Show only when chapter is less than 2
-    {
-        return TRUE;
-    };
-    return FALSE; // Not needed, but added for readability
-};
-
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
instance Info_Diego_EXIT_Gamestart(C_INFO)
-{
-    // ...
-    condition = Info_Diego_EXIT_Gamestart_Condition;
-    // ...
-};
-
-func int Info_Diego_EXIT_Gamestart_Condition()
-{
-    return TRUE; // or return 1;
-};
-

Tip

It is unnecessary to return FALSE from dialogue conditions, but in other cases it can very rarely cause subtle bugs. It is thus good practice to always return some value, even if that is FALSE.

information

The information function contains the function name (without double quotes "" as func is a type in Daedalus) that is called when the dialogue option is selected. It contains the lines NPCs will say, items that will be transferred, quests related logic and much more. The function name does not have to follow a particular naming convention, but a naming convention is used throughout all the Gothic scripts: {DialogueName}_Info.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
instance Info_Diego_Gamestart (C_INFO)
-{
-    npc         = PC_Thief;
-    nr          = 1;
-    condition   = Info_Diego_Gamestart_Condition;
-    information = Info_Diego_Gamestart_Info;
-    permanent   = FALSE;
-    important   = TRUE;
-};
-
-func int Info_Diego_Gamestart_Condition()
-{
-    if (Kapitel < 2)
-    {
-        return TRUE;
-    };
-    return FALSE;
-};
-
-func void Info_Diego_Gamestart_Info()
-{
-    AI_Output(self,hero,"Info_Diego_Gamestart_11_00"); //I'm Diego.
-    AI_Output(hero,self,"Info_Diego_Gamestart_15_01"); //I'm...
-    AI_Output(self,hero,"Info_Diego_Gamestart_11_02"); //I'm not interested in who you are. You've just arrived. I look after the new arrivals. That's all for now.
-    AI_Output(self,hero,"Info_Diego_Gamestart_11_03"); //If you plan to stay alive for a while, you should talk to me. But of course I won't keep you from choosing your own destruction. Well, what do you think?
-
-    B_Kapitelwechsel(1); // Show the chapter 1 screen
-};
-

description

Specify a string that will be shown in the dialogue window.

1
-2
-3
-4
-5
instance DIA_XARDAS_GMC(C_INFO)
-{
-    // ...
-    description = "Hello, is this the GMC site?";
-};
-

Description

trade

If trade is set to TRUE the trading interface will be launched after the content information function is finished.

Fisk's trade dialogue
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
instance  Stt_311_Fisk_Trade (C_INFO)
-{
-    npc         = Stt_311_Fisk;
-    nr          = 800;
-    condition   = Stt_311_Fisk_Trade_Condition;
-    information = Stt_311_Fisk_Trade_Info;
-    permanent   = TRUE;
-    description = "Show me your goods.";
-    trade       = TRUE;
-};
-
-func int  Stt_311_Fisk_Trade_Condition()
-{
-    return TRUE;
-};
-
-func void  Stt_311_Fisk_Trade_Info()
-{
-    AI_Output (other, self, "Stt_311_Fisk_Trade_15_00"); //Show me your goods.
-};
-

Trivia

Trade manager has been added to ZenGin not that long before the release of Gothic 1 (as discussed and discovered on Phoenix the Game Discord server with the acquisition of Gothic version 0.94k). In version 0.94 the trade manager worked quite differently and used a special (nowadays unused) Daedalus class C_ItemReact.

permanent

Dialogues with permanent = TRUE do not disappear after the dialogue is played. This is used for dialogues where you ask for directions or flavor dialogues for unnamed NPCs.

Bug

Frequently used external function Npc_KnowsInfo which returns true if the dialogue instance has been played has had a bug in the implementation for a long time. This bug made it impossible to use this function with dialogue instances with permanent = TRUE as it would always return FALSE. This has been fixed in Union 1.0m.

LeGo

LeGo implements a lot of useful functions for dialogues. It makes it possible to create Trialogues and change NPCs behaviour by Dialoggestures. Moreover, any Daedalus function can be added to NPCs AI queue via the AI_Function package.

zParserExtender

zParserExtender implements some Quality of Life features for dialogues. More information can be found in Dialogue constants article.

AF Script Packet

Enhanced Info Manager (implemented using Ikarus and LeGo) adds tons of customizations and additional features to dialogues. More information can be found in the AFSP Enhanced Information Manager article.

\ No newline at end of file diff --git a/cs/zengin/scripts/classes/c_item/index.html b/cs/zengin/scripts/classes/c_item/index.html deleted file mode 100644 index 9960a8120e..0000000000 --- a/cs/zengin/scripts/classes/c_item/index.html +++ /dev/null @@ -1,369 +0,0 @@ - C_ITEM - Gothic Modding Community

C_ITEM Daedalus class

Acknowledgment

Heavily inspired by the amazing documentation site Gothic library

The C_ITEM class is used to define new items in the game.

Class definition

Class definition as it is defined in Scripts/Content/_intern/Classes.d script file.

C_Item Daedalus class
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
-37
-38
-39
-40
-41
-42
-43
-44
-45
-46
-47
-48
-49
-50
-51
-52
-53
-54
-55
-56
-57
-58
-59
-60
-61
-62
-63
-64
-65
-66
-67
-68
-69
-70
-71
-72
-73
-74
class C_Item
-{
-    // For all Items
-    var int    id;                         // ID of the item
-    var string name;                       // Name of the item
-    var string nameID;                     // Name ID
-    var int    hp;                         // Current health of the item
-    var int    hp_max;                     // Maximum health of the item
-
-    var int    mainflag;                   // Item category flag
-    var int    flags;                      // Item type flag
-    var int    weight;                     // Weight of the item
-    var int    value;                      // Value of the item
-
-    // For weapons
-    var int    damageType;                 // Damage type
-    var int    damageTotal;                // Total amount of damage
-    var int    damage[DAM_INDEX_MAX];      // Array of damage types
-
-    // For armours
-    var int    wear;                       // Flag to specify where to wear an item
-    var int    protection[PROT_INDEX_MAX]; // Protection array of different damage types
-
-    // For food
-    var int    nutrition;                  // The amount of HP healed
-
-    // Benötigte Attribute zum Benutzen des Items
-    var int    cond_atr[3];                // Array of NPC attributes needed to equip the item
-    var int    cond_value[3];              // Array of values corresponding to the cond_atr array
-
-    // Attributes to be changed on equip
-    var int    change_atr[3];              // Array of attributes that will be changed on equip
-    var int    change_value[3];            // Array of values of the attributes defined in change_atr
-
-    // Parser functions
-    var func   magic;
-    var func   on_equip;                   // Called on equpping an item
-    var func   on_unequip;                 // Called on unequipping an item
-    var func   on_state[4];
-
-    var func   owner;                      // Owner of the item: instance name
-    var int    ownerGuild;                 // Owner of the item: guild
-    var int    disguiseGuild;              // NPC guild set when equipping an item
-
-    // 3DS model file
-    var string visual;                     // Item model file
-
-    // NPC mesh change, when equipping an item
-    var string visual_change;              // .asc file
-    var string effect;                     // Effect instance
-
-    var int    visual_skin;                // Texture variation
-
-    var string scemeName;                  // Animation sceme name
-    var int    material;                   // Material of the object
-
-    var int    munition;                   // Ammo instance
-
-    var int    spell;                      // ID if the spell that this item does
-    var int    range;                      // Range of the weapon
-
-    var int    mag_circle;                 // Circle of magic needed to use this item
-
-    var string description;                // The name of the item shown in the preview box
-    var string text[ITM_TEXT_MAX];         // Array of string describing the item (left side)
-    var int    count[ITM_TEXT_MAX];        // Array of integers (the right side)
-
-    // Parameters for displaying items in the inventory
-    var int    inv_zbias                   // How far away is the item from the screen
-    var int    inv_rotx                    // X-axis rotation
-    var int    inv_roty                    // Y-axis rotation
-    var int    inv_rotz                    // Z-axis rotation
-    var int    inv_animate                 // Should the item rotate in the inventory
-};
-

It has many member variables but not all of them are used for every item. It is not necessary to define every one of these variables for every item as it was discussed on InsideGothic.

Class members

A selection of the most important class members.

change_atr & change_value

change_atr stores the attributes that will be changed by the amount specified in change_value.

NPCs have these attributes:

1
-2
-3
-4
-5
-6
-7
-8
-9
const int ATR_HITPOINTS      =  0;  // Hit points
-const int ATR_HITPOINTS_MAX  =  1;  // Max hitpoints
-const int ATR_MANA           =  2;  // Mana
-const int ATR_MANA_MAX       =  3;  // Max mana
-
-const int ATR_STRENGTH       =  4;  // Strength
-const int ATR_DEXTERITY      =  5;  // Dexterity
-const int ATR_REGENERATEHP   =  6;  // HP regeneration per second
-const int ATR_REGENERATEMANA =  7;  // Mana regeneration per second
-

This can be used on all equipable items to change the attributes. As an example we can create a sword that has a 10 point dexterity bonus.

1
-2
-3
-4
-5
-6
-7
instance ItMw_testSword (C_Item)
-{
-    // some code
-    change_atr[0]   = ATR_DEXTERITY;
-    change_value[0] = 10;
-    // some code
-};
-

Warning

Do not change ATR_HITPOINTS, ATR_MANA, ATR_HITPOINTS_MAX or ATR_MANA_MAX as it will result in unwanted behaviour with max health or max mana.

You can change ATR_HITPOINTS_MAX and ATR_MANA_MAX attributes in on_equip and on_unequip

cond_atr & cond_value

cond_atr stores the attributes that will be checked as a requirement to equip an item, the amount specified in cond_value.

The next example sword is equipable only if the NPC has at least 5 strength. If the requirements are not met G_CanNotUse() is called.

1
-2
-3
-4
-5
-6
-7
instance ItMw_testSword (C_Item)
-{
-    // some code
-    cond_atr[2]     = ATR_STRENGTH;
-    cond_value[2]   = 5;
-    // some code
-};
-

Try injecting the code below zParserExtender to test it in game right away. It is compatible with G2NotR.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
instance ItMw_testSword (C_Item)
-{
-    name            = TXT_Spells[10]; // demonstrates the usage of direct constr array access
-
-    mainflag        = ITEM_KAT_NF;
-    flags           = ITEM_SWD;
-    material        = MAT_METAL;
-
-    value           = 10;
-
-    damageTotal     = 10;
-    damagetype      = DAM_EDGE;
-    range           = 100;
-
-    cond_atr[2]     = ATR_STRENGTH;
-    cond_value[2]   = 5;
-
-    change_atr[0]   = ATR_DEXTERITY;
-    change_value[0] = 10;
-
-    visual          = "ItMw_010_1h_Sword_short_01.3DS";
-
-    description     = name;
-
-    TEXT[2]         = NAME_Damage;      COUNT[2] = damageTotal;
-    TEXT[3]         = NAME_Str_needed;  COUNT[3] = cond_value[2];
-    TEXT[4]         = NAME_OneHanded;
-    TEXT[5]         = NAME_Value;       COUNT[5] = value;
-};
-
To insert it into the game use insert ItMw_testSword in console.

text & count arrays

These two arrays are used to put information into the item information box. Text and Count The maximum number of lines is 6. This is defined in the engine, but for script side class definition is declared in the scripts too.

const int ITM_TEXT_MAX = 6;
-
This example shows an item with all elements of TEXT and COUNT array filled.

Note

Please notice the last COUNT element. It did not take the value we entered, but shows 10 which is the value of the item. This behaviour can be changed with Ikarus or Union.

Item example

You can find the code below

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
instance ItMw_testSword (C_Item)
-{
-    name          = TXT_Spells[10];
-
-    mainflag      = ITEM_KAT_NF;
-    flags         = ITEM_SWD;
-    material      = MAT_METAL;
-
-    value         = 10;
-
-    damageTotal   = 10;
-    damagetype    = DAM_EDGE;
-    range         = 100;
-
-    cond_atr[2]   = ATR_STRENGTH;
-    cond_value[2] = 5;
-
-    change_atr[0] = ATR_DEXTERITY;
-    change_value[0] = 10;
-
-    visual        = "ItMw_010_1h_Sword_short_01.3DS";
-
-    description   = name;
-
-    TEXT[0]       = "Line 0";     COUNT[0]      = 0; 
-    TEXT[1]       = "Line 1";     COUNT[1]      = 1; 
-    TEXT[2]       = "Line 2";     COUNT[2]      = 2; 
-    TEXT[3]       = "Line 3";     COUNT[3]      = 3; 
-    TEXT[4]       = "Line 4";     COUNT[4]      = 34;
-    TEXT[5]       = "Line 5";     COUNT[5]      = 35;
-};
-

description & name

description - determines the name of the item in the inventory

name - determines the focus name of the item in the world

In the scripts you often find that the description is assigned the value of name.

1
-2
-3
-4
-5
-6
-7
instance ItMw_testSword (C_Item)
-{
-    name = "New amazing sword";
-    // ...
-    description   = name; // description now has the same value as '    // ...name'
-    // ...
-};
-
This is used in the case where you want to show the name of the item on focus too.

There is a second way used in the scripts though with, for example,magic scrolls - the focus name in the world is "Scroll" and in inventory the scroll carries the name of the spell. This is how it is done:

1
-2
-3
-4
-5
-6
-7
instance ItSc_InstantFireball (C_Item)
-{
-    name                 =    NAME_Spruchrolle; // const string = "Scroll"
-    // ...
-    description            =     NAME_SPL_InstantFireball; // const string = "Fireball"
-    // ...
-};
-

hp & hp_max

Both of these parameters are unused.

Trivia

In alpha ZenGin versions the player was able to destroy objects. This feature was abandoned during the course of the development.
This video shows the reconstruction of this feature.

\ No newline at end of file diff --git a/cs/zengin/scripts/classes/c_menu/index.html b/cs/zengin/scripts/classes/c_menu/index.html deleted file mode 100644 index 479b4f2533..0000000000 --- a/cs/zengin/scripts/classes/c_menu/index.html +++ /dev/null @@ -1,157 +0,0 @@ - C_MENU - Gothic Modding Community

C_MENU Daedalus class

Acknowledgment

Heavily inspired by the amazing documentation site Gothic library

Class C_Menu is responsible for the behavior and properties of the game menus (options, save etc.).

Class definition

Class definition as it is defined in Scripts/System/_intern/Menu.d script file.

C_Menu Daedalus class
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
class C_Menu 
-{
-    var     string  backPic;            // Menu background image
-    var     string  backWorld;          // Background ZEN-world of the game menu (Not used)
-    var     int     posx;               // The top left point of the menu on the screen horizontally (X-axis)
-    var     int     posy;               // The top left point of the menu on the screen vertically (Y-axis)
-    var     int     dimx;               // Menu width in virtual coordinates
-    var     int     dimy;               // Menu height in virtual coordinates
-    var     int     alpha;              // Menu transparency
-    var     string  musicTheme;         // Music track of the menu
-    var     int     eventTimerMSec;     // trigger time for the event EVENT_TIMER
-    var     string  items[150];         // Menu items
-    var     int     flags;              // Menu flags
-    var     int     defaultOutGame;     // Menu item highlighted by default when the game is not running
-    var     int     defaultInGame;      // Menu item highlighted by default when the game is running
-};
-

Class members

Variable Type Description
backPic string Menu background image
backWorld string Background ZEN-world of the game menu (Not used)
posx int The top left point of the menu on the screen horizontally (X-axis)
posy int The top left point of the menu on the screen vertically (Y-axis)
dimx int Menu width in virtual coordinates
dimy int Menu height in virtual coordinates
alpha int Menu transparency
musicTheme string Music track of the menu
eventTimerMSec int The timer that triggered the event in seconds
items string Menu items
flags int Menu flags
defaultOutGame int Menu item highlighted by default when the game is not running
defaultInGame int Menu item highlighted by default when the game is running

Class member overview

Description of the class member variables.

backPic

backPic is just a name of background image of the menu in .tga format.

backWorld

Deprecated setting

The background world of the game menu in .ZEN format.

posx

The horizontal position of the top left point of the menu on the screen, in virtual coordinates.

posy

The vertical position of the top left point of the menu on the screen, in virtual coordinates.

dimx

Menu width in virtual coordinates.

dimy

Menu height in virtual coordinates.

alpha

Menu transparency. Accepts values ​​from 0 to 255. Without the backPic property specified, the value of this parameter is ignored.

Note

Texture transparency can only be adjusted if the texture has an alpha channel.

musicTheme

Music theme of the menu.

1
-2
-3
-4
-5
-6
instance MENU_MAIN(C_MENU_DEF)
-{
-    ...
-    musictheme = "SYS_Menu";
-    ...
-};
-
All instances of musical themes are stored in a file Scripts/System/Music/MusicInst.d

eventTimerMSec

Defines the trigger time for the event EVENT_TIMER in seconds.

The list of constants for all menu events is described in the file Scripts/System/_intern/Menu.d

1
-2
-3
-4
-5
-6
-7
-8
-9
const int EVENT_UNDEF       = 0;    // Undefined
-const int EVENT_EXECUTE     = 1;    // Process start event
-const int EVENT_CHANGED     = 2;    // Menu parameter change event
-const int EVENT_LEAVE       = 3;    // Menu item focus loss event
-const int EVENT_TIMER       = 4;    // Timer fire event
-const int EVENT_CLOSE       = 5;    // Menu close event
-const int EVENT_INIT        = 6;    // Initialization event
-const int EVENT_SEL_PREV    = 7;    // Select event of the previous menu item
-const int EVENT_SEL_NEXT    = 8;    // Select event of the next menu item
-

items

An array of items belonging to this menu. It is possible to use up to 150 items in one menu. The same elements can be used for different menus. The element instance is specified as the value.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
// Menu
-instance MENU_MAIN(C_MENU_DEF)
-{
-    ...
-    items[0]        = "MENUITEM_MAIN_HEADLINE";         
-    items[1]        = "MENUITEM_MAIN_HEADLINE2";
-    items[2]        = "MENUITEM_MAIN_NEWGAME";
-    ...
-};
-
-// Menu elements: labels, checkboxes, sliders, etc.
-
-instance MENUITEM_MAIN_HEADLINE(C_MENU_ITEM_DEF)
-{
-    ...
-};
-
-instance MENUITEM_MAIN_HEADLINE2(C_MENU_ITEM_DEF)
-{
-    ...
-};
-
-instance MENUITEM_MAIN_NEWGAME(C_MENU_ITEM_DEF)
-{
-    ...
-};
-

flags

Menu flags.

The list of flag constants can be found in the file Scripts/System/_intern/Menu.d

1
-2
-3
-4
-5
-6
-7
const int MENU_OVERTOP          = 1;    // Show menu over previous menu or in game
-const int MENU_EXCLUSIVE        = 2;    // Close all previous menus. Only the active menu is displayed
-const int MENU_NOANI            = 4;    // No animation
-const int MENU_DONTSCALE_DIM    = 8;    // Don't Scale Menu Sizes
-const int MENU_DONTSCALE_POS    = 16;   // Empty flag
-const int MENU_ALIGN_CENTER     = 32;   // Center Align Menu
-const int MENU_SHOW_INFO        = 64;   // Display information at the bottom of the description menu from menu items text[1]
-
  • MENU_OVERTOP - Flag to display the menu over the previous menu. It is not advisable to use with a transparent menu.
  • MENU_EXCLUSIVE - Hide all menus except the active one. When closed, the previous menu is restored.
  • MENU_NOANI - Animation of minimizing and maximizing windows. The game is mainly used for dialogue windows. You can't enable or disable the animation of dialog windows through scripts. This is done using the animatedWindows setting in the Gothic.ini file.
  • MENU_DONTSCALE_DIM - Scale the menu to fit 640x480 resolution.
  • MENU_DONTSCALE_POS - Empty flag. Not used.
  • MENU_ALIGN_CENTER - Align the menu to the center of the screen.
  • MENU_SHOW_INFO - Display information at the bottom of menu description from menu item text[1].

defaultOutGame

The menu item that is highlighted by default when the game is not running.

A value of -1 enables automatic selection of the first selectable element.

Items with the ~IT_SELECTABLE flag are not selected.

defaultInGame

Menu item highlighted by default when the game is running.

A value of -1 enables automatic selection of the first selectable element.

Items with the ~IT_SELECTABLE flag are not selected.

\ No newline at end of file diff --git a/cs/zengin/scripts/classes/c_musicsys_cfg/index.html b/cs/zengin/scripts/classes/c_musicsys_cfg/index.html deleted file mode 100644 index 218ee53b6f..0000000000 --- a/cs/zengin/scripts/classes/c_musicsys_cfg/index.html +++ /dev/null @@ -1,51 +0,0 @@ - C_MUSICSYS_CFG - Gothic Modding Community

C_MUSICSYS_CFG Daedalus class

Acknowledgment

Heavily inspired by the amazing documentation site Gothic library

Class C_MusicSys_CFG defines the global settings for the game's music.

An instance of this class is declared only once.

Class definition

Class definition as it is defined in Scripts/System/_intern/Music.d script file.

C_MusicSys_CFG Daedalus class
1
-2
-3
-4
-5
-6
-7
-8
-9
class C_MusicSys_CFG
-{
-    var float volume;               // Music volume
-    var int   bitResolution;        // Sound quality
-    var int   globalReverbEnabled;  // Enable global reverb
-    var int   sampleRate;           // Frequency
-    var int   numChannels;          // Sound channels
-    var int   reverbBufferSize;     // Reverb buffer size
-};
-

Class members

Variable Type Description
volume float Overall game music volume
bitResolution int Sound quality
globalReverbEnabled int Enable global reverb
sampleRate int Frequency
numChannels int Number of sound chanells
reverbBufferSize int The size of reverb buffer

Class member overview

Description of the class member variables.

volume

The overall volume of the background music (soundtrack). From 0.0 to 1.0.

bitResolution

Sound quality. 8 or 16 bit.

globalReverbEnabled

Enable global reverb.

sampleRate

Frequency. From 11050 to 44100.

numChannels

Number of sound channels. From 16 to 32.

reverbBufferSize

The size of the reverb buffer.

\ No newline at end of file diff --git a/cs/zengin/scripts/classes/c_musictheme/index.html b/cs/zengin/scripts/classes/c_musictheme/index.html deleted file mode 100644 index 154054885f..0000000000 --- a/cs/zengin/scripts/classes/c_musictheme/index.html +++ /dev/null @@ -1,115 +0,0 @@ - C_MUSICTHEME - Gothic Modding Community

C_MUSICTHEME Daedalus class

Acknowledgment

Heavily inspired by the amazing documentation site Gothic library

Class C_MusicTheme describes musical themes.

Class definition

Class definition as it is defined in Scripts/System/_intern/Music.d script file.

C_MusicTheme Daedalus class
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
class C_MusicTheme
-{
-    var string      file;           // Sound file in DirectMusic `.sgt` format
-    var float       vol;            // Sound volume
-    var int         loop;           // Enable cycle
-    var float       reverbMix;      // Reverb mixing
-    var float       reverbTime;     // Reverb time
-    var int         transType;      // Type of transition to the next theme
-    var int         transSubType;   // Subtype of transition to the next theme song
-};
-

Class members

Variable Type Description
file string Sound file in DirectMusic .sgt format
vol float Sound volume
loop int Enable/disable cycle
reverbMix float Reverb mixing
reverbTime float Reverb time
transType int The type of transition to the next theme song
transSubType int The subtype of transition to the next theme song

Class member overview

Description of the class member variables.

file

DirectMusic sound in *.sgt format or MIDI file.

vol

The volume of the theme song. From 0.0 to 1.0.

loop

Enable/disable theme music looping. Disabled = 0. Enabled = 1.

reverbMix

Reverb mixing. Measured in decibels.

reverbTime

Reverberation time in milliseconds.

transType

The type of transition to the next theme song.

The list of constants for all transitions types is described in the file Scripts/System/_intern/Music.d

1
-2
-3
-4
-5
-6
-7
const int TRANSITION_TYPE_NONE          = 1;    // No transition
-const int TRANSITION_TYPE_GROOVE        = 2;    // Ripple
-const int TRANSITION_TYPE_FILL          = 3;    // Padding
-const int TRANSITION_TYPE_BREAK         = 4;    // Break
-const int TRANSITION_TYPE_INTRO         = 5;    // Introductory
-const int TRANSITION_TYPE_END           = 6;    // End topic
-const int TRANSITION_TYPE_ENDANDINTRO   = 7;    // End and start new
-

transSubType

The subtype of transition to the next theme song.

The list of constants for all transitions subtypes is described in the file Scripts/System/_intern/Music.d

1
-2
-3
const INT TRANSITION_SUB_TYPE_IMMEDIATE = 1;    // Instant transition
-const INT TRANSITION_SUB_TYPE_BEAT      = 2;    // Rhythmic transition
-const INT TRANSITION_SUB_TYPE_MEASURE   = 3;    // Gradual transition
-

Name features

The musical themes of the game are played depending on the game situation. By default, the theme with the _STD (standard) suffix is played. In case of a threat, the _THR (threat) theme will be played. During the combat the _FGT (fight) theme plays.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
instance WOO_DAY_STD(C_MUSICTHEME_STANDARD)
-{
-    file = "woo_daystd.sgt";
-};
-
-instance WOO_DAY_THR(C_MUSICTHEME_THREAT)
-{
-    file = "woo_daythr.sgt";
-};
-
-instance WOO_DAY_FGT(C_MUSICTHEME_FIGHT)
-{
-    file = "woo_dayfgt.sgt";
-};
-
In addition, the suffix _DAY_ and _NGT_ determines whether the theme should be played on day or night.
1
-2
-3
-4
-5
-6
-7
-8
-9
instance OWD_DAY_FGT(C_MUSICTHEME_FIGHT)
-{
-    file = "owp_dayfgt.sgt";
-};
-
-instance OWD_NGT_STD(C_MUSICTHEME_STANDARD)
-{
-    file = "owd_daystd.sgt";
-};
-

Tip

In G2 the C_MUSICTHEME_STANDARD, C_MUSICTHEME_THREAT and C_MUSICTHEME_FIGHT prototypes are used by default.

\ No newline at end of file diff --git a/cs/zengin/scripts/classes/c_svm/index.html b/cs/zengin/scripts/classes/c_svm/index.html deleted file mode 100644 index 53c39e6b54..0000000000 --- a/cs/zengin/scripts/classes/c_svm/index.html +++ /dev/null @@ -1,77 +0,0 @@ - C_SVM - Gothic Modding Community

C_SVM Daedalus class

Acknowledgment

Heavily inspired by the amazing documentation site Gothic library

The C_SVM class is used to define sound dialogues (smalltalk, reactions) that are defined for every C_NPC.voice.

Class definition

C_SVM class is the only class with variable number of members. The C_SVM definition in the scripts dictates the content of the class. Every Gothic game has a different number of SVM entries. As an interesting information (more than anything else) we include a table with the numbers of voice lines and voices below.

Game voice lines voices
Gothic 1 136 17
Gothic Sequel 110 17 (30 planned)
Gothic 2 202 19
Gothic 2 Addon 235 19
Chronicles of Myrtana 1346 73
Returning New Balance 495 19

Rules

The number of instances is defined by a constant integer with a specified name read by the engine.

const int SVM_MODULES = 18;
-

Info

The value SVM_MODULES = 18 means 18 SVMs will be parsed by the engine and because the first one, SVM_0, is empty, the final number of voices is 18 - 1 = 17.

Instances of the C_SVM class must have the name SVM_XXX.

1
-2
-3
-4
instance svm_1(c_svm)
-{
-    // ...
-};
-
The first instance svm_0 is always empty, it is used internally by the engine.
instance svm_0(c_svm) {};
-

Usage in the scripts

While some defined SVMs are used automatically by the engine - the 20 smalltalk lines for example, others are used in the scripts.
To instruct the engine to run a specific SVM, external function AI_OutputSVM is used. In the original scripts it is wrapped in a script function B_Say.
To reference the SVM, you use the $ symbol followed by the name of the member variable in the C_SVM class definition.

1
-2
-3
-4
-5
-6
// some code
-    {
-        PrintScreen    ("Not enough skill points!", -1,-1,"FONT_OLD_20_WHITE.TGA",1);
-        B_Say (self, other, "$NOLEARNNOPOINTS");
-    };
-// some code
-
Here the $NOLEARNNOPOINTS references the var string NoLearnNoPoints in SVM.D. The voice is then chosen automatically by the engine.
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
class C_SVM
-{
-    //...
-
-    // Teacher comments
-    var string NoLearnNoPoints;       // NPC teacher doesn't teach - not enough learning points!
-    var string NoLearnOverMax;        // NPC teacher doesn't teach - cannot teach above 100 points!
-    var string NoLearnYouAlreadyKnow; // You have to know something to become a master!
-    var string NoLearnYoureBetter;    // You are better than the teacher!
-
-    //...
-};
-
\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/afsp/afsp_eim/index.html b/cs/zengin/scripts/extenders/afsp/afsp_eim/index.html deleted file mode 100644 index 0cd7332828..0000000000 --- a/cs/zengin/scripts/extenders/afsp/afsp_eim/index.html +++ /dev/null @@ -1,469 +0,0 @@ - Enhanced Info Manager - Gothic Modding Community

Enhanced Information Manager

Warning

This is a quick paste-in of and old version of AFSP's documentation and the information should be taken with a grain of salt. It may not be up-to-date since AFSP is being developed all the time and this is only a demo page.

Enhanced Information Manager allows you to more precisely control the Information Manager (dialogue manager). Change color, font and much more! This package "scans" the dialogue string for modifiers and alters the string based on the modifiers you specify.

Initialization

To use this feature you have to:

  1. Add _headers_G[1/2]_EnhancedInfoManager.src or _headers_G[1/2]_All.src to your Gothic.src after Ikarus and LeGo initialization.
  2. Call G12_EnhancedInfoManager_Init(); from your INIT_GLOBAL() function in Startup.d

Change colour

Set font color for a dialogue choice.

h@[hex color value]
-
Set font color for highlighted dialogue choice.
hs@[hex color value]
-
Example
description = "h@2a85a3 hs@2ea9d1 This dialogue is blue.";
-

Change font

Set font itself for a dialogue choice.

f@[font name]
-
Set font itself for highlighted dialogue choice.
fs@[font name]
-
Example
description = "f@font_old_20_white.tga fs@font_old_10_white.tga This dialogue has a different font, when selected.";
-

Change text alignment

Align text left.

al@
-
Align text center.
ac@
-
Align text right.
ar@
-
Example
1
-2
-3
description = "al@ This dialogue has LEFT alignment.";
-description = "ac@ This dialogue has CENTER alignment.";
-description = "ar@ This dialogue has RIGHT alignment.";
-

Disable dialogue

Player cannot highlight (and select) this dialogue.

d@
-

Text input field

Input field allows you to turn a dialogue choice into an input text field.

a@
-
Example
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
INSTANCE DIA_Xardas_Password (C_Info)
-{
-    npc         = NONE_100_Xardas;
-    nr          = 1;
-    condition   = DIA_Xardas_Password_Condition;
-    information = DIA_Xardas_Password_Info;
-    permanent   = FALSE;
-    description = "a@ What is the password to get to the Mages of Water?";
-};
-
-FUNC INT DIA_Xardas_Password_Condition () {
-    return TRUE;
-};
-
-FUNC VOID DIA_Xardas_Password_Info () {
-    if (Hlp_StrCmp (InfoManagerAnswer, "TETRIANDOCH"))
-    {
-        PrintScreen ("Yes that is correct!", -1, -1, "font_old_10_white.tga", 3);
-    }
-    else
-    {
-        PrintScreen ("No that is wrong!", -1, -1, "font_old_10_white.tga", 3);
-    };
-};
-

Dialogue numbers

This feature shows a dialogue number next to the dialogue line (visual for Dialogue keyboard controls). To turn this on you just set InfoManagerNumKeysNumbers variable to true. (in your INIT_GLOBAL() function).

InfoManagerNumKeysNumbers = TRUE;
-

Dialogue keyboard controls

Note

This has also been fixed in Union and we noticed a strange behavior with different keyboard layouts.

This feature changes the way number keys affect dialogue selection. The first dialogue is no longer 0 and you highlight the dialogue option by pressing appropriate number.

InfoManagerNumKeysControls = TRUE;
-

Spinners

This is by far the most flashy feature of EIM as it allows you to use left/right arrow keys on a dialogue option to increase/decease numerical value. This can be used in many ways.

This feature is a bit more complex:

  1. Set up a standard dialogue

    Notice

    Notice we are using "dummy" as a description, since it is going to get updated. If something goes wrong the "dummy" string shows up and you can clearly tell something went wrong.

    1
    -2
    -3
    -4
    -5
    -6
    -7
    -8
    INSTANCE PC_Pan_Cook_Meat (C_Info)
    -{
    -    nr           = 1;
    -    condition    = PC_Pan_Cook_Meat_Condition;
    -    information  = PC_Pan_Cook_Meat_Info;
    -    permanent    = TRUE;
    -    description  = "dummy"; //Description is updated in PC_Pan_Cook_Meat_Condition
    -};
    -
  2. Most of the magic takes place in the condition function (apart from the code behind the scenes, of course).

     1
    - 2
    - 3
    - 4
    - 5
    - 6
    - 7
    - 8
    - 9
    -10
    -11
    -12
    -13
    -14
    -15
    -16
    -17
    -18
    -19
    -20
    -21
    -22
    -23
    -24
    -25
    -26
    -27
    -28
    -29
    -30
    -31
    -32
    -33
    -34
    -35
    -36
    -37
    -38
    -39
    -40
    -41
    -42
    -43
    -44
    -45
    -46
    -47
    -48
    -49
    -50
    -51
    -52
    var int selectedMeat; // global variable for this spinner value
    -
    -FUNC INT PC_Pan_Cook_Meat_Condition ()
    -{
    -    if (PLAYER_MOBSI_PRODUCTION == MOBSI_DIALOG_PAN)
    -    {
    -        var string lastSpinnerID;
    -
    -        var int total; total = NPC_HasItems (self, ItFoMuttonRaw);
    -
    -        if (selectedMeat == 0) { selectedMeat = 1; }; //Default initial value
    -
    -        //Check currently selected spinned ID --> is it this one?
    -        if (Hlp_StrCmp (InfoManagerSpinnerID, "CookMeat"))
    -        {
    -            //Setup spinner if spinner ID has changed
    -            if (!Hlp_StrCmp (InfoManagerSpinnerID, lastSpinnerID))
    -            {
    -                //Restore previous value
    -                InfoManagerSpinnerValue = selectedMeat;
    -            };
    -
    -            //Page Up/Down quantity
    -            InfoManagerSpinnerPageSize = 5;
    -
    -            //Min/Max value (Home/End keys)
    -            InfoManagerSpinnerValueMin = 1;
    -            InfoManagerSpinnerValueMax = total;
    -
    -            //Update number which is shown in description (in case it was changed by _HOOK_VIEWDIALOGCHOICE_HANDLEEVENT
    -            selectedMeat = InfoManagerSpinnerValue;
    -
    -        };
    -
    -        lastSpinnerID = InfoManagerSpinnerID; //Remember last active spinner ID
    -
    -        var string newDescription;
    -
    -        //Spinner ID 'CookMeat'
    -        newDescription = "s@CookMeat Cook some meat: ";
    -
    -        newDescription = ConcatStrings (newDescription, IntToString (selectedMeat));
    -        newDescription = ConcatStrings (newDescription, " / ");
    -        newDescription = ConcatStrings (newDescription, IntToString (total));
    -
    -        //Update description
    -        PC_Pan_Cook_Meat.description = newDescription;
    -        return TRUE;
    -    };
    -
    -    return FALSE;
    -};
    -
  3. We can use the spinner value stored in selectedMeat variable here in the info function to create the meat (or do other stuff with it).

     1
    - 2
    - 3
    - 4
    - 5
    - 6
    - 7
    - 8
    - 9
    -10
    -11
    -12
    -13
    -14
    -15
    -16
    -17
    -18
    FUNC VOID PC_Pan_Cook_Meat_Info () {
    -    //If we don't have any meat ... don't cook any :)
    -    if (!NPC_HasItems (self, ItFoMuttonRaw)) { return; };
    -
    -    //This should not happen - but you never know!
    -    if (selectedMeat < 1) { return; };
    -
    -    //This should not happen either! but just in case
    -    if (selectedMeat > (NPC_HasItems (self, ItFoMuttonRaw))) {
    -        selectedMeat = NPC_HasItems (self, ItFoMuttonRaw);
    -    };
    -
    -    NPC_RemoveInvItems (self, ItFoMuttonRaw, selectedMeat);
    -    CreateInvItems (self, ItFoMutton, selectedMeat);
    -
    -    //Reset value for next time
    -    selectedMeat = 1;
    -};
    -

Spinners: Full code example

Spinner example
  1
-  2
-  3
-  4
-  5
-  6
-  7
-  8
-  9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
-100
-101
-102
-103
-104
-105
-106
-107
-108
-109
INSTANCE PC_Pan_Cook_Meat (C_Info)
-{
-    nr           = 1;
-    condition    = PC_Pan_Cook_Meat_Condition;
-    information  = PC_Pan_Cook_Meat_Info;
-    permanent    = TRUE;
-    description  = "dummy"; //Description is updated in PC_Pan_Cook_Meat_Condition
-};
-
-var int selectedMeat;
-
-FUNC INT PC_Pan_Cook_Meat_Condition ()
-{
-    if (PLAYER_MOBSI_PRODUCTION == MOBSI_DIALOG_PAN)
-    {
-        var string lastSpinnerID;
-
-        var int total; total = NPC_HasItems (self, ItFoMuttonRaw);
-
-        if (selectedMeat == 0) { selectedMeat = 1; }; //Default initial value
-
-        //Check currently selected spinned ID --> is it this one?
-        if (Hlp_StrCmp (InfoManagerSpinnerID, "CookMeat"))
-        {
-            //Setup spinner if spinner ID has changed
-            if (!Hlp_StrCmp (InfoManagerSpinnerID, lastSpinnerID))
-            {
-                //Restore previous value
-                InfoManagerSpinnerValue = selectedMeat;
-            };
-
-            //Page Up/Down quantity
-            InfoManagerSpinnerPageSize = 5;
-
-            //Min/Max value (Home/End keys)
-            InfoManagerSpinnerValueMin = 1;
-            InfoManagerSpinnerValueMax = total;
-
-            //Update number which is shown in description (in case it was changed by _HOOK_VIEWDIALOGCHOICE_HANDLEEVENT
-            selectedMeat = InfoManagerSpinnerValue;
-        };
-
-        lastSpinnerID = InfoManagerSpinnerID; //Remember last active spinner ID
-
-        var string newDescription;
-
-        //Spinner ID 'CookMeat'
-        newDescription = "s@CookMeat Cook some meat: ";
-
-        newDescription = ConcatStrings (newDescription, IntToString (selectedMeat));
-        newDescription = ConcatStrings (newDescription, " / ");
-        newDescription = ConcatStrings (newDescription, IntToString (total));
-
-        //Update description
-        PC_Pan_Cook_Meat.description = newDescription;
-        return TRUE;
-    };
-
-    return FALSE;
-};
-
-FUNC VOID PC_Pan_Cook_Meat_Info ()
-{
-    //If we don't have any meat ... don't cook any :)
-    if (!NPC_HasItems (self, ItFoMuttonRaw)) { return; };
-
-    //This should not happen - but you never know!
-    if (selectedMeat < 1) { return; };
-
-    //This should not happen either! but just in case
-    if (selectedMeat > (NPC_HasItems (self, ItFoMuttonRaw)))
-    {
-        selectedMeat = NPC_HasItems (self, ItFoMuttonRaw);
-    };
-
-    NPC_RemoveInvItems (self, ItFoMuttonRaw, selectedMeat);
-    CreateInvItems (self, ItFoMutton, selectedMeat);
-
-    //Reset value for next time
-    InfoManagerSpinnerValue = 1;
-};
-
-INSTANCE PC_Pan_Cook_Meat_Exit (C_Info)
-{
-    nr          = 999;
-    condition   = PC_Pan_Cook_Meat_Exit_Condition;
-    information = PC_Pan_Cook_Meat_Exit_Info;
-    permanent   = TRUE;
-    description = "End";
-};
-
-FUNC INT PC_Pan_Cook_Meat_Exit_Condition ()
-{
-    if (PLAYER_MOBSI_PRODUCTION == MOBSI_DIALOG_PAN)
-    {
-        return TRUE;
-    };
-    return FALSE;
-};
-
-FUNC VOID PC_Pan_Cook_Meat_Exit_Info ()
-{
-    if (PLAYER_MOBSI_PRODUCTION != MOBSI_DIALOG_NONE)
-    {
-        PLAYER_MOBSI_PRODUCTION = MOBSI_DIALOG_NONE;
-        hero.aivar[AIV_INVINCIBLE] = FALSE;
-        AI_StopProcessInfos (hero);
-    };
-};
-
\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/afsp/index.html b/cs/zengin/scripts/extenders/afsp/index.html deleted file mode 100644 index f18de97daf..0000000000 --- a/cs/zengin/scripts/extenders/afsp/index.html +++ /dev/null @@ -1,34 +0,0 @@ - AF Script Packet - Gothic Modding Community

AF Script Packet

Auronen & Fawkes' Script Packet is a script package built on top of Ikarus and LeGo. It implements many features and there is also a Union version which is in its infancy stage.

Note

AFSP's documentation is lacking (@Auronen: "My fault"). The authors will host the documentation on GMC.

Contacts
Authors Fawkes & Auronen
GitHub AFSP
Forum AFSP
\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/ikarus/constants/index.html b/cs/zengin/scripts/extenders/ikarus/constants/index.html deleted file mode 100644 index c27b1b852c..0000000000 --- a/cs/zengin/scripts/extenders/ikarus/constants/index.html +++ /dev/null @@ -1,43 +0,0 @@ - Constants - Gothic Modding Community

Ikarus User Constants

In the Constants file, you'll find user variables that control various aspects, including the debug output of Ikarus. You can customize these variables to suit your needs.

MEM-Helper

  • const string MEM_FARFARAWAY
    Waypoint where the Mem-Helper is spawned (default: "TOT")
  • const string MEM_HELPER_NAME
    Name of the Mem-Helper (default: "MEMHLP")

Debug

  • const int zERR_ErrorBoxOnlyForFirst
    Controls whether only the first error should trigger an error box (default: 1).
  • const int zERR_StackTraceOnlyForFirst
    Determines if stack traces should be displayed only for the first error (default: 0).

MEM_Debug

The MEM_Debug function allows you to set up a custom message channel for debugging purposes. You can adjust the following variables to configure this channel:

  • const string zERR_DEBUG_PREFIX
    Specifies a prefix to be added to each debug message (default: "Debug: ").
  • const int zERR_DEBUG_TOSPY
    Controls whether MEM_Debug messages should be sent to zSpy (default: 1).
  • const int zERR_DEBUG_TYPE
    Specifies the message type for MEM_Debug messages when sent to zSpy (default: zERR_TYPE_INFO).
  • const int zERR_DEBUG_TOSCREEN
    Determines whether MEM_Debug messages should be printed to the screen (default: 0).
  • const int zERR_DEBUG_ERRORBOX
    Allows you to display an error box for MEM_Debug messages (default: 0).

Error message types

1
-2
-3
-4
-5
const int zERR_TYPE_OK    = 0; /* [ungenutzt]        */
-const int zERR_TYPE_INFO  = 1; /* MEM_Info           */
-const int zERR_TYPE_WARN  = 2; /* MEM_Warn           */
-const int zERR_TYPE_FAULT = 3; /* MEM_Error          */
-const int zERR_TYPE_FATAL = 4; /* [ungenutzt]        */
-
\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/ikarus/examples/index.html b/cs/zengin/scripts/extenders/ikarus/examples/index.html deleted file mode 100644 index 3547274f31..0000000000 --- a/cs/zengin/scripts/extenders/ikarus/examples/index.html +++ /dev/null @@ -1,371 +0,0 @@ - Examples - Gothic Modding Community

Ikarus examples

A collection of examples ported from the original Ikarus documentation.

Note

The original Ikarus documentation is a part of the code. You can find it in the GitHub repository.

Open focused chest or door

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
func void OpenFocussedChestOrDoor() 
-{
-    var oCNpc her; her = Hlp_GetNpc(hero);
-
-    // No focus vob at all?
-    if (!her.focus_vob) 
-    {
-        Print ("No focus!");
-        return;
-    };
-
-    // Focus vob not a lockable vob?
-    if (!Hlp_Is_oCMobLockable(her.focus_vob))
-    {
-        Print ("No chest or door in focus!");
-        return;
-    };
-
-    var oCMobLockable Lockable;
-    Lockable = MEM_PtrToInst (her.focus_vob);
-
-    if (Lockable.bitfield & oCMobLockable_bitfield_locked) 
-    {
-        Lockable.bitfield = Lockable.bitfield & ~ oCMobLockable_bitfield_locked;
-        Print (ConcatStrings ("Opened the following vob: ", Lockable._zCObject_objectName));
-    } 
-    else
-    {
-        Print (ConcatStrings ( Lockable._zCObject_objectName, "wasn't even complete!"));
-    };
-};
-
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
func void PrintCameraPos()
-{
-    // Initialize global instances (which only exist once):
-    // Initializes MEM_World, MEM_Game, etc. including MEM_Camera
-    MEM_InitGlobalInst();
-
-    /* The camera object is not a vob (but something abstract), 
-    do not know where and how there are position data.
-    I prefer to work on the camera vob : */
-    var zCVob camVob;
-    camVob = MEM_PtrToInst (MEM_Camera.connectedVob);
-
-    /* Here you have to know how the transformation matrix is structured:
-
-    It consists of three vectors, the x, y and z directions of the local coordinate system of the camera vob
-    in world coordinates (where z specifies the
-    line of sight). These vectors are
-    denoted by v1, v2, v3.
-    In addition, in the 4th column there is the translation,
-    that is, the position of the camera.
-
-    v1_x v2_x v3_x x
-    v1_y v2_y v3_y y
-    v1_z v3_z v3_z z
-    0 0 0 0
-
-    The matrix is stored row by row in memory.
-    Since we are interested in the last column are the indices
-    in the trafoWorld Array 3, 7 and 11 that we need. */
-
-    Print (ConcatStrings ("x: ",IntToString(roundf(camVob.trafoObjToWorld[3]))));
-    Print (ConcatStrings ("y: ",IntToString(roundf(camVob.trafoObjToWorld[7]))));
-    Print (ConcatStrings ("z: ",IntToString(roundf(camVob.trafoObjToWorld[11]))));
-};
-

Start rain

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
func void StartRain()
-{
-    // Initialize global instances
-    // This also includes Skycontroller
-    MEM_InitGlobalInst(); 
-
-    // start at the beginning of the day (12:00 noon)
-    MEM_SkyController.rainFX_timeStartRain = 0; // FLOATNULL constant
-    // end at the end of the day (12:00 noon of the next day)
-    MEM_SkyController.rainFX_timeStopRain = 1065353216; // FLOATONE constant
-
-    /* Note: The start and end times are floating point numbers.
-    * 0 stands for the beginning of the day 1 for the end of the day.
-    * a day in the game begins at 12:00 p.m.
-    * For the structure of the floating point format, google for IEEE-745.*/
-
-    /* Result: rain all day! (unless you are in a zone
-    * in which it snows, then snow all day) */
-};
-

Nested loop

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
-37
-38
-39
-40
-41
-42
-43
-44
-45
-46
-47
-48
// Should enumerate all pairs (x,y) with 0 <= x < max_x, 0 <= j < max_y
-
-func void printpairs(var int max_x, var int max_y)
-{
-    // Initialize labels
-    MEM_InitLabels();
-    // PrintDebug should be used, i.e. activate debug output
-    MEM_SetShowDebug (1);
-
-    var int x; var int y; x = 0;
-
-    // while (x < max_x)
-    var int x_loop; x_loop = MEM_StackPos.position;
-    if (x < max_x)
-    { 
-        y = 0;
-        // while (y < max_y) 
-        var int y_loop; y_loop = MEM_StackPos.position;
-        if (y < max_y)
-        { 
-            var string out; out = "(";
-            out = ConcatStrings (out, IntToString (x));
-            out = ConcatStrings (out, ", ");
-            out = ConcatStrings (out, IntToString (y));
-            out = ConcatStrings (out, ")");
-            PrintDebug (out);
-            y += 1;
-
-            // continue y_loop 
-            MEM_StackPos.position = y_loop;
-        };
-        x += 1;
-        // continue x_loop
-        MEM_StackPos.position = x_loop;
-    };
-};
-
-/*
-    Output of a call printpairs(4,2) would then be: 
-    00:36 Info: 5 U: Skript: (0, 0) .... 
-    00:36 Info: 5 U: Skript: (0, 1) .... 
-    00:36 Info: 5 U: Skript: (1, 0) .... 
-    00:36 Info: 5 U: Skript: (1, 1) .... 
-    00:36 Info: 5 U: Skript: (2, 0) .... 
-    00:36 Info: 5 U: Skript: (2, 1) .... 
-    00:36 Info: 5 U: Skript: (3, 0) .... 
-    00:36 Info: 5 U: Skript: (3, 1) .... 
-*/
-

Calling a function by their name

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
-37
-38
-39
// This example doesn't show why MEM_CallByString * is useful, but how to use the function.
-
-var zCVob someObject;
-func int MyFunction(var int param1, var string str1, var int param2, var string str2)
-{
-    Print (ConcatStrings (str1, str2)); //(*)
-    return 100 * param1 + param2;
-};
-
-func void foo()
-{ 
-    var int result;
-
-    // The following code is in this case equivalent to:
-    // result = MyFunction(42, "Hello", 23, "World!");
-
-    // Lay the call arguments on the call stack
-    MEM_PushIntParam (42);
-    MEM_PushStringParam ("Hello ");
-    MEM_PushIntParam (23);
-    MEM_PushStringParam ("World!");
-
-    MEM_CallByString ("MYFUNCTION");
-
-    // the function puts the result (of type int in this case) on the stack
-    // we pop the int result and save it to a variable
-    result = MEM_PopIntResult();
-
-    // print the result
-    Print (IntToString (result));
-};
-
-/*
-    Note: Since symbol indices are continuous and someObject's symbol index 
-    is simply given by someObject itself, could
-    MEM_CallByString("MYFUNCTION"); 
-    also be replaced here by 
-    MEM_CallByID(someObject + 1);
-*/
-
\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/ikarus/floats/index.html b/cs/zengin/scripts/extenders/ikarus/floats/index.html deleted file mode 100644 index 5399459284..0000000000 --- a/cs/zengin/scripts/extenders/ikarus/floats/index.html +++ /dev/null @@ -1,80 +0,0 @@ - Floats - Gothic Modding Community

Floats

This part of ikarus implements support for 32 bit IEEE 754 floats in Daedalus. The script was originally created to edit zFLOAT and zREAL variables, but can also be used to arithmetic operations on real float values (not to be confused with Daedalus floats).

Initialization

The best way to initialize all Ikarus functions is to call MEM_InitAll() in the Init_Global() initialization function.

Warning

If you want to use Ikarus in Gothic 1, it is best to define your own Init_Global() function and call it from every world initialization function.

MEM_InitAll();
-

Implementation

float.d on GitHub

Functions

Danger

Ikarus floats are saved as int but it doesn't mean that you can use arithmetic operators on them. All operations on floats must be done with functions listed below.

mkf

(make float) Converts the input integer x to a float value.

func int mkf(var int x)
-
Parameters
  • var int x
    The input integer

Return value

The function returns the float representation of the input integer x.

truncf

(truncate float) Truncates the decimal part of the input float x.

func int truncf(var int x)
-
Parameters
  • var int x
    The input float

Return value

The function returns the integer part of the input float x by discarding the decimal part.

roundf

(round float) Rounds the input float x to the nearest integer value.

func int roundf(var int x)
-
Parameters
  • var int x
    The input float

Return value

The function returns the nearest integer value to the input float x. If the decimal part is exactly halfway between two integers, the function rounds to the nearest even integer.

addf

(add floats) Adds two ikarus floats together.

func int addf(var int x, var int y)
-
Parameters
  • var int x
    The first float
  • var int y
    The second float

Return value

The function returns the sum of the input floats x and y. (x + y)

subf

(subtract floats) Subtracts the second float from the first float.

func int subf(var int x, var int y)
-
Parameters
  • var int x
    The first float
  • var int y
    The second float

Return value

The function returns the difference between the first float x and the second float y. (x - y)

negf

(negate float) Negates the input float.

func int negf(var int x)
-
Parameters
  • var int x
    The input float

Return value

The function returns the negation of the input float x.

mulf

(multiply floats) Multiplies two ikarus floats.

func int mulf(var int x, var int y)
-
Parameters
  • var int x
    The first float
  • var int y
    The second float

Return value

The function returns the product of multiplying the input floats x and y. (x * y)

divf

(divide floats) Divides two ikarus floats.

func int divf(var int x, var int y)
-
Parameters
  • var int x
    The dividend float
  • var int y
    The divisor float

Return value

The function returns the quotient of dividing the input float x by y. (x / y)

invf

(inverse float) Computes the inverse of the input float.

func int invf(var int x)
-
Parameters
  • var int x
    The input float

Return value

The function returns the inverse of the x, calculated as 1/x.

gf

(greater) Checks if the first float is greater than the second float.

func int gf(var int x, var int y)
-
Parameters
  • var int x
    The first float
  • var int y
    The second float

Return value

The function returns TRUE if x is greater than y, FALSE is returned otherwise.

gef

(greater or equal) Checks if the first float is greater than or equal to the second float.

func int gef(var int x, var int y)
-
Parameters
  • var int x
    The first float
  • var int y
    The second float

Return value

The function returns TRUE if x is greater than or equal to y, FALSE is returned otherwise.

lf

(lower) Checks if the first float is less than the second float.

func int lf(var int x, var int y)
-
Parameters
  • var int x
    The first float
  • var int y
    The second float

Return value

The function returns TRUE if x is less than y, FALSE is returned otherwise.

lef

(lower or equal) Checks if the first float is less than or equal to the second float.

func int lef(var int x, var int y)
-
Parameters
  • var int x
    The first float
  • var int y
    The second float

Return value

The function returns TRUE if x is less than or equal to y, FALSE is returned otherwise.

sqrf

(square float) Calculates the square of the float.

func int sqrf(var int x)
-
Parameters
  • var int x
    The input float

Return value

The function returns the square of the input float x, computed as x * x.

sqrtf

(square root float) Calculates the square root of the float.

func int sqrtf(var int x)
-
Parameters
  • var int x
    The input float

Return value

The function returns the square root of the input float x.

sqrtf_approx

Calculates the approximate square root of a float.

func int sqrtf_approx(var int f)
-
Parameters
  • var int f
    The input float

Return value

The function returns the approximate square root of the input float as an ikarus float.

absf

(absolute value) Computes the absolute value of a float.

func int absf(var int x)
-
Parameters
  • var int x
    The input float

Return value

The function returns the absolute value of the input float x, which is the value without the negative sign (if present).

fracf

(fraction) Computes the fraction of two integers p and q.

func int fracf(var int p, var int q)
-
Parameters
  • var int p
    Numerator
  • var int q
    Denominator

Return value

The function returns the fraction of p divided by q as an ikarus float.

castFromIntf

Converts an ikarus float to a Daedalus float.

func float castFromIntf(var int f)
-
Parameters
  • var int f
    Ikarus float

Return Value

The function returns the value f as a Daedalus float.

castToIntf

Converts a Daedalus float to an ikarus float.

func int castToIntf(var float f)
-
Parameters
  • var float f
    Daedalus float

Return Value

The function returns the value f as an ikarus float.

toStringf

Converts a float value to its string representation.

func string toStringf(var int x)
-
Parameters
  • var int x
    Input float value

Return value

The function returns a string representation of the input float value.

printf

(print float) Prints the float on screen using Print().

func void printf(var int x)
-
Parameters
  • var int x
    The printed float

Examples

Simple operations

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
var int float1; float1 = mkf(5);        // Create an Ikarus float with value 5
-var int float2; float2 = mkf(2);        // Create an Ikarus float with value 2
-
-var int addResult; addResluts  = addf(float1, float2);     // Add float1 and float2
-var int subResult; subResults  = subf(float1, float2);     // Subtract float2 from float1
-var int mulResult; mulRelsults = mulf(float1, float2);     // Multiply float1 by float2
-var int divResult; divResults  = divf(float1, float2);     // Divide float1 by float2
-
-printf(addResult);   // Output: 7
-printf(subResult);   // Output: 3
-printf(mulResult);   // Output: 10
-printf(divResult);   // Output: 2.5
-
\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/ikarus/functions/arrays/index.html b/cs/zengin/scripts/extenders/ikarus/functions/arrays/index.html deleted file mode 100644 index dbef4d6518..0000000000 --- a/cs/zengin/scripts/extenders/ikarus/functions/arrays/index.html +++ /dev/null @@ -1,52 +0,0 @@ - Arrays (zCArray) - Gothic Modding Community

Arrays (zCArray)

Set of function for working with ZenGin's zCArray data structure.

Initialization

The best way to initialize all Ikarus functions is to call MEM_InitAll() in the Init_Global() initialization function.

Warning

If you want to use Ikarus in Gothic 1, it is best to define your own Init_Global() function and call it from every world initialization function.

MEM_InitAll();
-

Implementation

Ikarus.d on GitHub

Functions

MEM_ArrayCreate

Creates an empty zCArray (allocates memory) and returns a pointer to it.

func int MEM_ArrayCreate()
-
Return value

The function returns a pointer to the created zCArray.

MEM_ArrayFree

Frees the memory allocated for a zCArray and its data.

func void MEM_ArrayFree(var int zCArray_ptr)
-
Parameters
  • var int zCArray_ptr
    Pointer to the zCArray to be freed

MEM_ArrayClear

Clears the data of a zCArray, freeing the memory used by its elements. The array becomes empty.

func void MEM_ArrayClear (var int zCArray_ptr)
-
Parameters
  • var int zCArray_ptr
    Pointer to the zCArray to be cleared

MEM_ArraySize

Returns the size (number of elements) of an array.

func int MEM_ArraySize(var int zCArray_ptr)
-
Parameters
  • var int zCArray_ptr
    Pointer to the zCArray

Return value

The function returns a number of a zCArray elements.

MEM_ArrayWrite

Writes a value at a specific position in the zCArray.

func void MEM_ArrayWrite(var int zCArray_ptr, var int pos, var int value)
-
Parameters
  • var int zCArray_ptr
    Pointer to the zCArray
  • var int pos
    Position in the array where the value will be written
  • var int value
    Value to be written

MEM_ArrayRead

Reads the value at a specific position in the zCArray.

func int MEM_ArrayRead(var int zCArray_ptr, var int pos)
-
Parameters
  • var int zCArray_ptr
    Pointer to the zCArray
  • var int pos
    Position in the array from which the value will be read

Return value

The function returns the value at a specific position in the zCArray.

MEM_ArrayInsert

Appends a value to the end of the zCArray. The array is automatically resized if it is too small.

func void MEM_ArrayInsert (var int zCArray_ptr, var int value)
-
Parameters
  • var int zCArray_ptr
    Pointer to the zCArray
  • var int value
    Value to be inserted

MEM_ArrayPush

Alias for MEM_ArrayInsert, inserts a value at the end of the zCArray.

func void MEM_ArrayPush (var int zCArray_ptr, var int value)
-
Parameters
  • var int zCArray_ptr
    Pointer to the zCArray
  • var int value
    Value to be inserted

MEM_ArrayPop

Removes and returns the last element from the zCArray.

func int MEM_ArrayPop(var int zCArray_ptr)
-
Parameters
  • var int zCArray_ptr
    Pointer to the zCArray

Return value

The function returns the element removed from the end of an array.

MEM_ArrayTop

Returns the last element of the zCArray without removing it.

func int MEM_ArrayTop(var int zCArray_ptr)
-
Parameters
  • var int zCArray_ptr
    Pointer to the zCArray

Return value

The function returns the last element of an array.

MEM_ArrayIndexOf

Searches the zCArray for the first occurrence of a value and returns its index.

func int MEM_ArrayIndexOf(var int zCArray_ptr, var int value)
-
Parameters
  • var int zCArray_ptr
    Pointer to the zCArray
  • var int value
    Value to search for

Return value

The function returns the index of a first occurrence of a value. If not found -1 is returned.

MEM_ArrayRemoveIndex

Removes the element at a specific index from the zCArray.

func void MEM_ArrayRemoveIndex (var int zCArray_ptr, var int index)
-
Parameters
  • var int zCArray_ptr
    Pointer to the zCArray
  • var int index
    Index of the element to be removed

MEM_ArrayRemoveValue

Removes all occurrences of a value from the zCArray.

func void MEM_ArrayRemoveValue (var int zCArray_ptr, var int value)
-
Parameters
  • var int zCArray_ptr
    Pointer to the zCArray
  • var int value
    Value to be removed

MEM_ArrayRemoveValueOnce

Removes the first occurrence of a value from the zCArray. If value is not found, a warning is issued.

func void MEM_ArrayRemoveValueOnce (var int zCArray_ptr, var int value)
-
Parameters
  • var int zCArray_ptr
    Pointer to the zCArray
  • var int value
    Value to be removed

MEM_ArraySort

Sorts the elements of the zCArray in ascending order.

func void MEM_ArraySort(var int zCArray_ptr)
-
Parameters
  • var int zCArray_ptr
    Pointer to the zCArray

MEM_ArrayUnique

Removes duplicate elements from the zCArray.

func void MEM_ArrayUnique(var int zCArray_ptr)
-
Parameters
  • var int zCArray_ptr
    Pointer to the zCArray

MEM_ArrayToString

Converts the zCArray to a string representation.

func string MEM_ArrayToString (var int zCArray_ptr)
-
Parameters
  • var int zCArray_ptr
    Pointer to the zCArray

Return value

The function returns a string representation of a given array.

\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/ikarus/functions/asm/index.html b/cs/zengin/scripts/extenders/ikarus/functions/asm/index.html deleted file mode 100644 index b88e1db293..0000000000 --- a/cs/zengin/scripts/extenders/ikarus/functions/asm/index.html +++ /dev/null @@ -1,87 +0,0 @@ - ASM - Gothic Modding Community

Ikarus Machine Code Implementation (ASM)

Machine code refers to a program or program segment written in machine language, which can be directly executed by a processor without further translation steps. The relevant machine language for us is that belonging to the x86 processor architecture. All machine instructions, what they do, and how they are encoded in machine language can be found in the Intel Manuals.

In practice, dealing with (abstract) machine instructions and manually translating them into (concrete) machine code is rarely necessary due to its complexity.

However, machine code can be useful for performing technical tasks that cannot be expressed in Daedalus directly. For example, the CALL package use the ASM function set as a basis.

Note

The functions in this chapter have the ASM_ prefix for Assembly (language). Assembly language is a human-readable language with one-to-one correspondences to machine language. Strictly speaking, the ASM_ prefix is misleading here, as it pertains to machine code rather than assembly language. However, conceptually, the two are closely related.

Initialization

The best way to initialize all Ikarus functions is to call MEM_InitAll() in the Init_Global() initialization function.

Warning

If you want to use Ikarus in Gothic 1, it is best to define your own Init_Global() function and call it from every world initialization function.

MEM_InitAll();
-

Implementation

Ikarus.d on GitHub

Opcodes

The code defines several constants that represent different machine code instructions. Each constant is assigned a hexadecimal value and corresponds to a specific machine code instruction. Here is a link to all instructions.

Internal Stack

The code includes an internal stack implementation, allowing the storage of data. The stack is already used at two points:

  • When calling an engine function, the address of the current run is stored in the internal stack.
  • When nesting the use of the CALL package, a push and pop operation is performed to manage the context.

The internal stack is implemented using an array, and the following functions are provided:

ASMINT_Push

Pushes the specified data onto the internal stack.

func void ASMINT_Push(var int data)
-
Parameters
  • var int data
    Data pushed onto internal stack

ASMINT_Pop

Pops and returns the topmost data from the internal stack.

func int ASMINT_Pop()
-
Return value

The function returns a data popped form the internal stack.

Functions (Core)

The ASM core functionality provides a framework for assembling machine code instructions and executing them. The following functions are included:

ASMINT_Init

Initializes the ASM system by creating an internal stack and finding function addresses.

func void ASMINT_Init()
-

Tip

It's worth noting that ASMINT_Ini is also invoked by the MEM_InitAll function.

ASM_Open

Changes the size of the memory allocated at the start o the dictation

The memory in which the machine code is stored is allocated at the beginning of the dictation. If this function isn't called a default size (see Constant below) is allocated by ASM or ASM_Here function. The 256 bytes is often sufficient for simple applications, but if more memory is required, this function must be called at the beginning of the dictation.

func void ASM_Open(var int space)
-
Parameters
  • var int space
    Space allocated for machine code (in bytes)

Constant

ASM_StandardStreamLength constant defines the default space available for an Assembler sequence (in bytes).

const int ASM_StandardStreamLength = 256;
-

ASM

Writes machine code instructions to the stream.

Using this function it is possible to dictate machine code little by little. The data bytes of the length (maximum 4!) are appended to the previously dictated part. This creates a program piece by piece that can be executed by the processor.

func void ASM(var int data, var int length)
-
Parameters
  • var int data
    The machine code instruction or its part
  • var int length
    Length of the data (max 4 bytes)

ASM_1

ASM with length parameter hardcoded to 1. Writes one byte machine code instructions to the stream.

func void ASM_1(var int data) 
-
Parameters
  • var int data
    One byte machine code instruction or its part

ASM_2

ASM with length parameter hardcoded to 2. Writes two bytes machine code instructions to the stream.

func void ASM_1(var int data) 
-
Parameters
  • var int data
    Two bytes machine code instruction or its part

ASM_3

ASM with length parameter hardcoded to 3. Writes three bytes machine code instructions to the stream.

func void ASM_1(var int data) 
-
Parameters
  • var int data
    Three bytes machine code instruction or its part

ASM_4

ASM with length parameter hardcoded to 4. Writes four bytes machine code instructions to the stream.

func void ASM_1(var int data) 
-
Parameters
  • var int data
    Four bytes machine code instruction or its part

ASM_Here

Provides, the address of the cursor, i.e., the address of the location that will be described next by a call to ASM. It is guaranteed that the location where the code is written is also the location where it will be executed.

func int ASM_Here()
-

Return value

The function returns an address that is the current position in the machine code stream.

ASM_Close

Finalizes the stream by adding a return instruction and returns the starting address of the stream. This pointer can now be passed to at any time and any number of times to execute the machine code.

Warning

The memory area obtained by ASM_Close must be released manually using MEM_Free to avoid memory leaks. It is probably sufficient for almost all practical purposes.

func int ASM_Close()
-
Return value

The function returns a starting address of the stream (pointer to the stream).

ASM_Run

Executes a machine code (stream) from a pointer.

Note

ASM_Run can also be used to call engine functions with no parameters and no relevant return value. In this case ptr would simply have to point to the function to be executed in the code segment.

func void ASM_Run(var int ptr)
-
Parameters
  • var int ptr
    Pointer to the executed code (returned form ASM_Close)

ASM_RunOnce

Executes the code dictated up to that point, similar to how an external function is executed. After that the code is released, and new code can be dictated.

func void ASM_RunOnce()
-

Example

The following function sets the NPC passed as slf as the player, as if you had pressed O in Marvin mode with this NPC in focus. This is so short because there is already a function for this exact purpose, it's just not normally accessible from the scripts. It is therefore sufficient to write assembly code that pushes the parameter of the function (the this pointer) into the appropriate register and then calls the function.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
func void SetAsPlayer(var C_NPC slf) { /* Address of the function */
-    const int oCNpc__SetAsPlayer = 7612064; //0x7426A0 (Gothic2.exe)
-
-    var int slfPtr;
-    slfPtr = MEM_InstToPtr (slf);
-
-    //mov ecx slfPtr
-    ASM_1(ASMINT_OP_movImToECX); /* move a value to ecx */
-    ASM_4(slfPtr); /* a value */
-
-    //call oCNpc__SetAsPlayer
-    ASM_1(ASMINT_OP_call);
-    ASM_4(oCNpc__SetAsPlayer - ASM_Here() - 4);
-
-    ASM_RunOnce(); /* return will be added automatically */
-};
-

Note

Call targets are specified relative to the instruction that would have been executed after the actual call instruction. Therefore, both ASM_Here() and the subtraction of 4 in the call parameter are necessary.

The above example describes, among other things, CALL__thiscall function form the CALL Package that can be also used to implement SetAsPlayer.

1
-2
-3
-4
func void SetAsPlayer(var C_NPC slf) { 
-    const int oCNpc__SetAsPlayer = 7612064;
-    CALL__thiscall(MEM_InstToPtr(slf), oCNpc__SetAsPlayer);
-};
-
\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/ikarus/functions/call/index.html b/cs/zengin/scripts/extenders/ikarus/functions/call/index.html deleted file mode 100644 index 6bebb4eb70..0000000000 --- a/cs/zengin/scripts/extenders/ikarus/functions/call/index.html +++ /dev/null @@ -1,181 +0,0 @@ - CALL Package - Gothic Modding Community

CALL Package

This part of Ikarus makes possible to call engine functions directly from scripts.

In order to be able to invoke an engine function, you must know some of its properties. This includes the number and types of parameters, the type of return value, address of function and calling convention.

Knowledge about engine functions can be obtained using tools like IDA, which can analyze and convert GothicMod.exe / Gothic2.exe into a more human-readable format.

Info

In fact, machine code execution (ASM) is part of the CALL package, but due to its complexity, this functionality is discussed in a separate article.

Initialization

The best way to initialize all Ikarus functions is to call MEM_InitAll() in the Init_Global() initialization function.

Warning

If you want to use Ikarus in Gothic 1, it is best to define your own Init_Global() function and call it from every world initialization function.

MEM_InitAll();
-

Implementation

Ikarus.d on GitHub

Call modes

There are two modes:

Disposable

The simple mode that produces a disposable call that is used only once. All parameters are hardcoded.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
func int hero_GetAssessEnemy() {
-    const int oCNpc__GetPerceptionFunc = 7726080; //0x75E400
-
-    CALL_IntParam(_@(PERC_ASSESSENEMY));
-    CALL_PutRetValTo(_@(funcID));
-    CALL__thiscall(_@(hero), oCNpc__GetPerceptionFunc);
-
-    var int funcID;
-    return +funcID;
-};
-

Recyclable

The second version produces code that can be used more than once. Instead of the parameters the user specifies the address where the parameters are to be taken from. In addition to executing the code, the user will receive an address that he can use to repeat the call. This is much faster than rebuilding the call from scratch.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
func int Npc_GetPercFunc(var C_Npc npc, var int type) {
-    const int oCNpc__GetPerceptionFunc = 7726080; //0x75E400
-
-    var int npcPtr; npcPtr = _@(npc);
-
-    const int call = 0;
-    if (CALL_Begin(call)) {
-        CALL_IntParam(_@(type));
-        CALL_PutRetValTo(_@(funcID));
-        CALL__thiscall(_@(npcPtr), oCNpc__GetPerceptionFunc);
-        call = CALL_End();
-    };
-
-    var int funcID;
-    return +funcID;
-};
-

Receives a pointer. In case the pointer is non-zero, the code at this position is executed and 0 is returned. In case pointer is zero, the current mode is changed into recyclable mode, this means that the call functions expect instructions to build a recyclable call. This mode will continue until CALL_End(). This allows code like this:

Start and End

CALL_Open

Initializes a Recyclable call mode.

func void CALL_Open()
-

CALL_Begin

A practical wrapper for CALL_Open. Makes a call if it had been already created, initializes it otherwise.

func int CALL_Begin(var int ptr)
-
Parameters
  • var int ptr
    Zero if you need to create a new recyclable function to be called (usually, before first use). In this case CALL_Open is called and CALL_Begin returns 1.

Return Value

The function returns 1 if the new call has been created, 0 is returned otherwise.

CALL_Close

Finalizes a function call in recyclable mode, restoring the previous execution context.

func int CALL_Close()
-

CALL_End

Finalizes a function call, pushes the pointer onto the stack, and runs the associated assembly code (makes an actual call).

func int CALL_End()
-

Return Value

The function returns a pointer that could be used to repeat the call.

Tip

CALL_Close only finalizes the function call, returning the pointer, while CALL_End additionally handles pushing the pointer onto the stack and running associated assembly code.

Passing parameters

Parameters must be arranged on the machine stack from right to left i.e. from the parameter on the far right to the parameter on the far left. These functions generate machine code that will place parameters on the machine stack when executed.

Note

These functions do not impose any parameters on the Machine stack. Exactly it should say: You create the machine code that will put parameters on the machine stack when it is executed. And it is only carried out in the second step with the announcement of the calling convention.

CALL_IntParam

Passes an integer (int32) as a parameter to the called function.

func void CALL_IntParam(var int param)
-
Parameters
  • var int param
    Address of an integer to be passed

CALL_FloatParam

Passes an IEEE 7554 floating-point number (single / zREAL) as a parameter to the called function.

func void CALL_FloatParam(var int param)
-
Parameters
  • var int param
    Address of a float to be passed

CALL_PtrParam

Passes a pointer (void*) as a parameter to the called function.

func void CALL_PtrParam(var int param)
-
Parameters
  • var int param
    Pointer to be passed

CALL_zStringPtrParam

Passes a string (zString*) as a parameter to the called function.

func void CALL_zStringPtrParam(var string param)
-
Parameters
  • var string param
    String to be passed

Warning

This function only works when writing a disposable call!

CALL_cStringPtrParam

Passes a char array (char **) as a parameter to the called function.

func void CALL_cStringPtrParam(var string param)
-
Parameters
  • var string param
    String to be passed as character array`

Warning

This function only works when writing a disposable call!

CALL_StructParam

Passes a structure (struct) as a parameter to the called function.

func void CALL_StructParam(var int ptr, var int words)
-
Parameters
  • var int param
    Pointer to the object
  • var int words
    Size of a structure (1 word = 32 bits)

Note

CALL_IntParam, CALL_FloatParam, and CALL_PtrParam are functionally identical and are differentiated for code readability.

The call

The calling convention determines how the function's parameters are passed. IDA or another disassembler can be used to identify the convention used by a specific engine function.

The announcement of the calling convention, i.e. the call of one of the four functions below is also the time of calling the function. In particular, all parameters must already be specified at this point.

CALL__stdcall

Calls a function with __stdcall (Standard Call) calling convention.

func void CALL__stdcall(var int adr)
-
Parameters
  • var int adr
    Address of a function

CALL__thiscall

Calls a function with __thiscall calling convention. Used with a member functions.

func void CALL__thiscall(var int this, var int adr)
-
Parameters
  • var int this
    Pointer to the owner class object passed as a this parameter
  • var int adr
    Address of a function

CALL__cdecl

Calls a function with __cdecl calling convention. Used with non-Windows API and non-class functions.

func void CALL__cdecl (var int adr)
-
Parameters
  • var int adr
    Address of a function

CALL__fastcall

Calls a function with __fastcall calling convention.

func void CALL__fastcall(var int ecx, var int edx, var int adr)
-
Parameters
  • var int ecx
    First parameter of a function
  • var int edx
    Second parameter of a function
  • var int adr
    Address of a function

Return Value

As soon as the function call has taken place, i.e. after step 2, the return value can be queried. The following functions interpret the return value (usually this is the content of EAX immediately after the call) in the manner suggested in the function name. The result is then returned in a manner usable in Daedalus.

Note

Some return values are not stored in the EAX. In that case the call of the special function RetValIs is required to get the return value.

Following functions are provided: CALL_RetValIsFloat, CALL_RetValIszString, CALL_RetValIsStruct.

CALL_PutRetValTo

Simply places the return value to the given address (mostly the address of a daedalus integer). Must be called before The Call function.

func void CALL_PutRetValTo(var int adr)
-
Parameters
  • var int adr
    Destination address of the return value

CALL_RetValAsInt

Retrieves an integer returned by the called function.

func int CALL_RetValAsInt()
-
Return value

The function returns an integer returned by the previously called engine function.

CALL_RetValIsFloat

Specifies that the return value is a float. Must be called before The Call function to allow getting the return value with CALL_RetValAsFloat.

func void CALL_RetValIsFloat()
-

CALL_RetValAsFloat

Retrieves a float returned by the called function.

func int CALL_RetValAsFloat()
-
Return value

The function returns a float returned by the previously called engine function.

CALL_RetValAsPtr

Retrieves a pointer (void*) returned by the called function.

func int CALL_RetValAsPtr()
-
Return value

The function returns a pointer returned by the previously called engine function.

CALL_RetValIsStruct

Specifies that the return value is a Structure. Must be called before The Call function to allow getting the return value with CALL_RetValAsStructPtr.

func void CALL_RetValIsStruct(var int size)
-
Parameters
  • var int size
    Size of the returned structure in bytes

Danger

If the return value is a structure with a size larger than 32 bit, the space for the return value has to be allocated by the caller (this is us).The address to the allocated memory is expected on the stack as an additional parameter (pushed last).

Warning

It is in your responsibility to free the structure memory, when the return value is not needed any more.

CALL_RetValAsStructPtr

Retrieves a pointer to the structure returned by the called function and converts it to the instance. Can be used to make an assignment to an instance, for example an assignment to a var zCVob if the return value is a pointer to a zCVob.

func MEMINT_HelperClass CALL_RetValAsStructPtr()
-
Return value

The function returns an instance returned by the previously called engine function.

CALL_RetValIszString

Specifies that the return value is a zString (20 bytes structure). Must be called before The Call function to allow getting the return value with CALL_RetValAszStringPtr and CALL_RetValAszString.

func string CALL_RetValAszString()
-

Note

CALL_RetValAszStringPtr and CALL_RetValAszString are quite different and should not be confused. Using CALL_RetValAszString frees up memory that may still be needed. In a reverse with CALL_RetValAszStringPtr memory that is no longer needed is not freed and can cause memory leak.

CALL_RetValAszStringPtr

Retrieves a zString pointer and converts it to the daedalus string. (don't frees the memory)

func string CALL_RetValAszStringPtr()
-
Return value

The function returns a daedalus string form a zString returned by the previously called engine function.

CALL_RetValAszString

Retrieves a zString pointer and converts it to the daedalus string. (frees the memory)

func string CALL_RetValAszString()
-
Return value

The function returns a daedalus string form a zString returned by the previously called engine function.

Function author note

A zString is merely a special case of a structure, with the difference, that it is used as a primitive datatype. Nobody will be willing to use it as a pointer to some memory or an instance in Daedalus. This function copies the contents of the zString into a daedalus string and frees the zString afterwards.

Examples

Apply overlay (Disposable)

1
-2
-3
-4
-5
-6
-7
-8
// .text:0072D2C0:int __thiscall oCNpc::ApplyOverlay(class zSTRING const &)
-
-func void example1(){
-    const int oCNpc__ApplyOverlay = 7525056; //0x72D2C0 (G2A)
-    CALL_zStringPtrParam ("HUMANS_MILITIA.MDS");
-    CALL__thiscall (MEM_InstToPtr (hero), oCNpc__ApplyOverlay);
-    //We are not interested in the return value here.
-};
-

Get time as string (Disposable)

e.g. "7:30" for half past seven in the morning

1
-2
-3
-4
-5
-6
-7
-8
// .text:00780EC0:class zSTRING __thiscall oCWorldTimer::GetTimeString(void)
-
-func void example2(){
-    const int oCWorldTimer__GetTimeString = 7868096; //780EC0 (G2A)
-    CALL_RetValIszString();
-    CALL__thiscall (MEM_InstToPtr (MEM_WorldTimer), oCWorldTimer__GetTimeString );
-    PrintDebug (CALL_RetValAszString());
-};
-

Get the "sky time" (Disposable)

Sky time is a floating point value between 0 and 1 that jumps back from 1 to 0 at noon.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
// .text:00781240:float __thiscall oCWorldTimer::GetSkyTime(void)
-
-func int GetSkyTime() {
-    const int oCWorldTimer__GetSkyTime = 7868992; //0x781240
-    CALL_RetValIsFloat();
-    CALL__thiscall (MEM_InstToPtr (MEM_WorldTimer),
-    oCWorldTimer__GetSkyTime);
-
-    return CALL_RetValAsFloat();
-};
-

Delete Vob (Recyclable)

Call of the oCWorld.RemoveVob. MEM_DeleteVob is an ikarus built-in function.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
func void MEM_DeleteVob(var int vobPtr) {
-    var int world; world = MEM_Game._zCSession_world;
-
-    const int call = 0;
-    if (CALL_Begin(call)) {
-        /* oCWorld.RemoveVob */
-        CALL_IntParam(_@(vobPtr));
-        CALL__thiscall(_@(world), MEMINT_SwitchG1G2(7171824, 7864512));
-
-        call = CALL_End();
-    };
-};
-
\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/ikarus/functions/debug/index.html b/cs/zengin/scripts/extenders/ikarus/functions/debug/index.html deleted file mode 100644 index c44e7617b6..0000000000 --- a/cs/zengin/scripts/extenders/ikarus/functions/debug/index.html +++ /dev/null @@ -1,46 +0,0 @@ - Debug - Gothic Modding Community

Debug

A set of debugging and error-handling functions for mod development with Ikarus.

Initialization

The best way to initialize all Ikarus functions is to call MEM_InitAll() in the Init_Global() initialization function.

Warning

If you want to use Ikarus in Gothic 1, it is best to define your own Init_Global() function and call it from every world initialization function.

MEM_InitAll();
-

Implementation

Ikarus.d on GitHub

Functions

MEM_CheckVersion

Checks if the version of Ikarus is the specified version or newer.

func int MEM_CheckVersion(var int base, var int major, var int minor)
-
Parameters
  • var int base
    Base version number
  • var int major
    Major revision number
  • var int minor
    Minor revision number

Return value

The function returns TRUE if the version of Ikarus is the specified version or newer, FALSE is returned otherwise.

MEM_SetShowDebug

Sets the variable that is also toggled by the toggle debug command. As a result, messages outputted by PrintDebug are directed to the zSpy

func void MEM_SetShowDebug(var int on)
-
Parameters
  • var int on
    Specifies whether to turn on (TRUE) or off (FALSE) debug information.

MEM_SendToSpy

Sends a message to the debugging console.

func void MEM_SendToSpy(var int errorType, var string text)
-
Parameters
  • var int errorType
    Type of error (e.g., zERR_TYPE_FAULT, zERR_TYPE_WARN, zERR_TYPE_INFO)
  • var string text
    The message to be sent.

MEM_ErrorBox

Displays an error message in a message box.

func void MEM_ErrorBox(var string text)
-
Parameters
  • var string text
    The error message to be displayed.

MEM_PrintStackTrace

Prints the stack trace.

func void MEM_PrintStackTrace()
-

MEM_Error

Handles a fatal error, displaying the error message and printing the stack trace.

func void MEM_Error(var string error)
-
Parameters
  • var string error
    The error message.

MEM_Warn

Handles a warning, displaying the warning message and printing the stack trace.

func void MEM_Warn(var string warn)
-
Parameters
  • var string warn
    The warning message.

MEM_Info

Handles an information message, printing it if enabled in the settings.

func void MEM_Info(var string info)
-
Parameters
  • var string info
    The information message.

MEM_AssertFail

Handles an assertion failure, reporting the error message as a fatal error.

func void MEM_AssertFail(var string assertFailText)
-
Parameters
  • var string assertFailText
    The assertion failure message.

MEM_Debug

Freely configurable debug channel. See how to setup it in the Constants article.

func void MEM_Debug(var string message)
-
Parameters
  • var string message
    The debug message.

MEMINT_SwitchG1G2

Switches between values based on the game version. Used mainly to change addresses in multi-platform hooks or function calls.

func int MEMINT_SwitchG1G2(var int g1Val, var int g2Val)
-
Parameters
  • var int g1Val The value to return if the game version is Gothic 1.
  • var int g2Val
    The value to return if the game version is Gothic 2.

Return value

The function returns an appropriate value based on the game version.

\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/ikarus/functions/ini_access/index.html b/cs/zengin/scripts/extenders/ikarus/functions/ini_access/index.html deleted file mode 100644 index 24f4c3b7ee..0000000000 --- a/cs/zengin/scripts/extenders/ikarus/functions/ini_access/index.html +++ /dev/null @@ -1,49 +0,0 @@ - Ini File Access - Gothic Modding Community

Configuration file access

This part of Ikarus gives you access to Gothic.ini and loaded mod configuration files.

Initialization

The best way to initialize all Ikarus functions is to call MEM_InitAll() in the Init_Global() initialization function.

Warning

If you want to use Ikarus in Gothic 1, it is best to define your own Init_Global() function and call it from every world initialization function.

MEM_InitAll();
-

Implementation

Ikarus.d on GitHub

Read functions

MEM_GetCommandLine

Returns the contents of the command line passed to Gothic.

func string MEM_GetCommandLine()
-
Return value

The function returns contents of the command line passed to Gothic. This could, for example, look like this:

"-TIME:7:35 -GAME:TEST_IKARUS.INI -ZREPARSE -ZWINDOW -ZLOG:5,S -DEVMODE -ZMAXFRAMERATE:30"

MEM_GetGothOpt

Searches the Gothic.ini for an option.

func string MEM_GetGothOpt(var string sectionname, var string optionname)
-
Parameters
  • var string sectionname
    Settings section like [GAME]
  • var string optionname
    One setting entry like playLogoVideos

Return value

The function returns an option value as a string or empty string if option was not found.

MEM_GetModOpt

Searches the loaded mod ini file for option.

func void MEM_GetModOpt(var string sectionname, var string optionname)
-
Parameters
  • var string sectionname
    Settings section like [INFO]
  • var string optionname
    One setting entry like Title

Return value

The function returns an option value as a string or empty string if option was not found.

MEM_GothOptSectionExists

Checks whether a section exists in Gothic.ini

func int MEM_GothOptSectionExists(var string sectionname)
-
Parameters
  • var string sectionname
    Settings section like [GAME]

Return value

The function returns TRUE if section exists FALSE is returned otherwise.

MEM_ModOptSectionExists

Checks whether a section exists in loaded mod ini file

func int MEM_ModOptSectionExists(var string sectionname)
-
Parameters
  • var string sectionname
    Settings section like [INFO]

Return value

The function returns TRUE if section exists FALSE is returned otherwise.

MEM_GothOptExists

Checks whether an option exists in Gothic.ini

func int MEM_GothOptExists(var string sectionname, var string optionname)
-
Parameters
  • var string sectionname
    Settings section like [GAME]
  • var string optionname
    One setting entry like playLogoVideos

Return value

The function returns TRUE if option in a section exist FALSE is returned otherwise.

MEM_ModOptExists

Checks whether an option exists in loaded mod ini file

func int MEM_ModOptExists(var string sectionname, var string optionname)
-
Parameters
  • var string sectionname
    Settings section like [INFO]
  • var string optionname
    One setting entry like Title

Return value

The function returns TRUE if option in a section exist FALSE is returned otherwise.

Write functions

Warning

Mod configuration is never saved to disk, therefore no separate functions exist for writing to it.

MEM_SetGothOpt

The option option in the section section is set to the value. If the section and/or option does not exist, it will be created.

func void MEM_SetGothOpt(var string section, var string option, var string value)
-
Parameters
  • var string section
    The section where the option should be located
  • var string option
    Option to write/overwrite
  • var string value
    Value to set the option to

MEM_ApplyGothOpt

Applies the changes and saves the ini to disk

func void MEM_ApplyGothOpt()
-

Tip

If you introduce new options, it is best to follow certain practices. It is a good practice to name your options in a clear manner and place them in a section named the same as your mod. Do not place your mod options into the [GAME] or [PERFORMANCE] sections.

Key functions

The Gothic.ini contains the assignment of physical keys (e.g. "W") to logical keys (e.g. "keyUp").

MEM_GetKey

Returns the primary key assigned to logical key.

func int MEM_GetKey(var string name)
-
Parameters
  • var string name
    Name of the logical key

Return value

The function returns key assigned to logical key

MEM_GetSecondaryKey

Returns a secondary key assigned to logical key.

func int MEM_GetSecondaryKey(var string name)
-
Parameters
  • var string name
    Name of the logical key

Return value

The function returns key assigned to logical key

MEM_SetKeys

Sets keyboard keys of the logical key.

func void MEM_SetKeys(var string name, var int primary, var int secondary)
-
Parameters

MEM_SetKey

Sets the primary keyboard key of the logical key.

func void MEM_SetKey(var string name, var int key)
-
Parameters

MEM_SetSecondaryKey

Sets the secondary keyboard key of the logical key.

func void MEM_SetSecondaryKey(var string name, var int key)
-
Parameters
\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/ikarus/functions/jumps_loops/index.html b/cs/zengin/scripts/extenders/ikarus/functions/jumps_loops/index.html deleted file mode 100644 index 5300fb9694..0000000000 --- a/cs/zengin/scripts/extenders/ikarus/functions/jumps_loops/index.html +++ /dev/null @@ -1,560 +0,0 @@ - Jumps and Loops - Gothic Modding Community

Jumps and Loops

Jumps

Jumps in Ikarus are implemented by direct manipulation of the stack pointer, achieved with two lines of code. These lines enable the change of the current position within the parser stack, representing machine-level code generated during script compilation. By querying and setting this position, the execution flow can be redirected to a new location in the code.

Initialization

To ensure the correct functioning of this jump mechanism, it is crucial to execute the MEM_InitLabels() function once after loading a saved game. The recommended practice is to integrate this initialization function within INIT_GLOBAL. It's only after MEM_InitLabels() has been called that accessing MEM_StackPos.position becomes valid.

func void MEM_InitLabels()
-

Tip

It's worth noting that MEM_InitLabels is also invoked by the MEM_InitAll function.

Usage

  • Label Initialization
    Before attempting a jump, it's important to initialize the label to which the jump is intended. Forward jumps, where the jump point is encountered before the jump target, can be challenging. Label initialization looks like that:
    1
    -2
    -3
    -4
    // [...]
    -var int label;
    -label = MEM_StackPos.position;
    -// [...]
    -
  • Actual jump
    After initializing the label you could simply jump to it by setting MEM_StackPos.position to the label.
    1
    -2
    -3
    // [...]
    -MEM_StackPos.position = label;
    -// [...]
    -

Jump flowchart

flowchart TD
-A(Start) --> B["var int label; \n label = MEM_StackPos.position;"];
-B --> C{Your code}
-C -->D["MEM_StackPos.position = label;"];
-C --> E(End)
-D --> |Jump| B;

Notes and warnings

  • Validity of Labels
    Labels become invalid after saving and loading. Consequently, labels should be used immediately, and there is generally no reason to persist them for an extended period.

  • Caution with Jumping
    Jumping between different functions without a clear understanding of the code structure can lead to unexpected issues. Similarly, using labels without a thorough comprehension of their purpose may result in undesired consequences. It's crucial to exercise caution, especially when making assignments involving labels.

Examples

The following code outputs the numbers from 0 to 42:

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
func void foo() {
-    /* Initialization */
-    MEM_InitLabels();
-    var int count; count = 0;
-
-    /* Record the execution position in label. */
-    var int label;
-    label = MEM_StackPos.position;
-    /* <---- label now points here,
-    * i.e. to the position AFTER the assignment of label. */
-
-    Print (ConcatStrings ("COUNT: ", IntToString (count)));
-    count += 1;
-
-    if (count <= 42) {
-        /* Replace the execution position,
-        * with the "<-----" the system then continues */
-        MEM_StackPos.position = label;
-    };
-
-    /* Once 43 is reached, the “loop” is exited. */
-};
-

The following code should enumerate all pairs (x,y) with 0 <= x < max_x, 0 <= y < max_y

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
-37
-38
-39
-40
-41
-42
-43
-44
-45
-46
func void printpairs(var int max_x, var int max_y)
-{
-    // Initialize labels
-    MEM_InitLabels();
-    // PrintDebug should be used, i.e. activate debug output
-    MEM_SetShowDebug (1);
-
-    var int x; var int y; x = 0;
-
-    // while (x < max_x)
-    var int x_loop; x_loop = MEM_StackPos.position;
-    if (x < max_x)
-    { 
-        y = 0;
-        // while (y < max_y) 
-        var int y_loop; y_loop = MEM_StackPos.position;
-        if (y < max_y)
-        { 
-            var string out; out = "(";
-            out = ConcatStrings (out, IntToString (x));
-            out = ConcatStrings (out, ", ");
-            out = ConcatStrings (out, IntToString (y));
-            out = ConcatStrings (out, ")");
-            PrintDebug (out);
-            y += 1;
-
-            // continue y_loop 
-            MEM_StackPos.position = y_loop;
-        };
-        x += 1;
-        // continue x_loop
-        MEM_StackPos.position = x_loop;
-    };
-};
-
-/*
-    Output of a call printpairs(4,2) would then be: 
-    00:36 Info: 5 U: Skript: (0, 0) .... 
-    00:36 Info: 5 U: Skript: (0, 1) .... 
-    00:36 Info: 5 U: Skript: (1, 0) .... 
-    00:36 Info: 5 U: Skript: (1, 1) .... 
-    00:36 Info: 5 U: Skript: (2, 0) .... 
-    00:36 Info: 5 U: Skript: (2, 1) .... 
-    00:36 Info: 5 U: Skript: (3, 0) .... 
-    00:36 Info: 5 U: Skript: (3, 1) .... 
-*/
-

Label and Goto

Besides the normal jumps Ikarus implements MEM_Label and MEM_Goto functions. They work similar to the stack manipulation with var int label but the interface is much more user-friendly and defining new variables is not needed.

MEM_Label

Function that works like a label = MEM_StackPos.position;. You could jump to it with MEM_Goto.

func void MEM_Label(var int lbl)
-
Parameters
  • var int lbl
    Number of the label, used for nested loop or multiple loops within one function

MEM_Goto

Function that works like a MEM_StackPos.position = label;. Executes a jump to a MEM_Label with specified number.

func void MEM_Goto(var int lbl)
-
Parameters
  • var int lbl
    Number of the label, the function will jump to

Usage

Usage of Label and Goto is probably self-explanatory, since it is same as in the regular Ikarus Jump. But before using it reading the Notes and warnings of the Jumps is recommended.

Label-Goto loop flowchart

flowchart TD
-A(Start) --> B["MEM_Label(0);"];
-B --> C{Your code}
-C -->D["MEM_Goto(0);"];
-C --> E(End)
-D --> |Jump| B;
Label-Goto loop
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
func void LabelGoto_test() {
-    var int i; 
-    MEM_Label(0);
-        MEM_Debug(IntToString(i));
-        i = i + 1;
-        if(i >= 4)
-        {
-            return;
-        };
-        MEM_Goto(0);
-};
-
-//  Results:
-//  Info:  0 Q:     Debug: 0
-//  Info:  0 Q:     Debug: 1
-//  Info:  0 Q:     Debug: 2
-//  Info:  0 Q:     Debug: 3
-

Examples

The following code outputs the numbers from 0 to 42:

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
func void foo() {
-    var int count; count = 0;
-
-    MEM_Label(0);
-    /* <---- label now points here,
-    * i.e. to the position AFTER the assignment of label. */
-
-    Print (ConcatStrings ("COUNT: ", IntToString (count)));
-    count += 1;
-
-    if (count <= 42) {
-        // Jump to the MEM_Label
-        MEM_Goto(0);
-    };
-
-    /* Once 43 is reached, the “loop” is exited. */
-};
-

The following code should enumerate all pairs (x,y) with 0 <= x < max_x, 0 <= y < max_y

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
-37
-38
-39
-40
-41
-42
func void printpairs(var int max_x, var int max_y)
-{
-    // PrintDebug should be used, i.e. activate debug output
-    MEM_SetShowDebug (1);
-
-    var int x; var int y; x = 0;
-
-    // while (x < max_x)
-    MEM_Label(0);
-    if (x < max_x)
-    { 
-        y = 0;
-        // while (y < max_y) 
-        MEM_Label(1);
-        if (y < max_y)
-        { 
-            var string out; out = "(";
-            out = ConcatStrings (out, IntToString (x));
-            out = ConcatStrings (out, ", ");
-            out = ConcatStrings (out, IntToString (y));
-            out = ConcatStrings (out, ")");
-            PrintDebug (out);
-            y += 1;
-
-            MEM_Goto(1);
-        };
-        x += 1;
-       MEM_Goto(0);
-    };
-};
-
-/*
-    Output of a call printpairs(4,2) would then be: 
-    00:36 Info: 5 U: Skript: (0, 0) .... 
-    00:36 Info: 5 U: Skript: (0, 1) .... 
-    00:36 Info: 5 U: Skript: (1, 0) .... 
-    00:36 Info: 5 U: Skript: (1, 1) .... 
-    00:36 Info: 5 U: Skript: (2, 0) .... 
-    00:36 Info: 5 U: Skript: (2, 1) .... 
-    00:36 Info: 5 U: Skript: (3, 0) .... 
-    00:36 Info: 5 U: Skript: (3, 1) .... 
-*/
-

While loop

Ikarus also implements a while loop. Its syntax isn't as good as the loop from zParserExtender, due to the daedalus limitations, but it works as a normal while loop that can be found in many programming languages.

Syntax

The Ikarus while loop consist of three things:

  • while function
    That works like a while statement and start of the brace while(var int b){.

    func void while(var int b)
    -
  • end constant
    That works like an ending brace }.

    const int end = -72;
    -
  • break and continue constant
    These two constants works like a regular break and continue statements in C.

    1
    -2
    const int break = -42;
    -const int continue = -23;
    -
while loop
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
func void while_test() {
-    var int value; value = 10;
-    while(value > 0); //{
-
-        if (value == 8)
-        {
-            continue;
-        };
-
-        if (value == 2)
-        {
-            break;
-        };
-    end; //}
-};
-

Examples

The following code outputs the numbers from 0 to 42:

1
-2
-3
-4
-5
-6
-7
-8
-9
func void foo() {
-    var int count; count = 0;
-    while(count <= 42); //{
-        Print (ConcatStrings ("COUNT: ", IntToString (count)));
-        count += 1;
-    end; //}
-
-    /* Once 43 is reached, the loop is exited. */
-}; 
-

The following code should enumerate all pairs (x,y) with 0 <= x < max_x, 0 <= y < max_y

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
func void printpairs(var int max_x, var int max_y)
-{
-    // PrintDebug should be used, i.e. activate debug output
-    MEM_SetShowDebug (1);
-
-    var int x; var int y; x = 0;
-
-    while(x < max_x); //{
-        y = 0;
-        while(y < max_y); //{  
-            var string out; out = "(";
-            out = ConcatStrings (out, IntToString (x));
-            out = ConcatStrings (out, ", ");
-            out = ConcatStrings (out, IntToString (y));
-            out = ConcatStrings (out, ")");
-            PrintDebug (out);
-            y += 1;
-        end; //}
-        x += 1;
-    end; //}
-};
-
-/*
-    Output of a call printpairs(4,2) would then be: 
-    00:36 Info: 5 U: Skript: (0, 0) .... 
-    00:36 Info: 5 U: Skript: (0, 1) .... 
-    00:36 Info: 5 U: Skript: (1, 0) .... 
-    00:36 Info: 5 U: Skript: (1, 1) .... 
-    00:36 Info: 5 U: Skript: (2, 0) .... 
-    00:36 Info: 5 U: Skript: (2, 1) .... 
-    00:36 Info: 5 U: Skript: (3, 0) .... 
-    00:36 Info: 5 U: Skript: (3, 1) .... 
-*/
-

Repeat loop

In addition Ikarus implements something called Repeat loop.

Initialization

To use Repeat loop you must first call MEM_InitRepeat() function once after loading a saved game. The recommended practice is to integrate this initialization function within INIT_GLOBAL.

func void MEM_InitRepeat()
-

Tip

It's worth noting that MEM_InitRepeat is also invoked by the MEM_InitAll function.

Syntax

Repeat loop has a syntax very similar to the while loop. It also uses end constant as an ending brace. break and continue statements can be used within it as well. The main difference is the main loop function Repeat that has following properties:

func void Repeat(var int variable, var int limit)
-
  • var int variable
    A variable that increase with every loop iteration.
  • var int limit
    A variable that defines the number of loop iterations. If variable >= limit the loop is exited.

Repeat loop flowchart

flowchart TD
-    A(Start) --> B["Repeat(i, limit)"] 
-    B --> C{i < limit}
-    C -->|true| D[Command]
-    D --> |i = i + 1| B
-    C --> |false| E(End)
Repeat loop
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
func void Repeat_test() {
-    Repeat(i, 4); var int i; //{
-        MEM_Debug(IntToString(i));
-    end; //}
-};
-
-//  Results:
-//  Info:  0 Q:     Debug: 0
-//  Info:  0 Q:     Debug: 1
-//  Info:  0 Q:     Debug: 2
-//  Info:  0 Q:     Debug: 3
-

Examples

The following code outputs the numbers from 0 to 42:

1
-2
-3
-4
-5
-6
-7
func void foo() {
-    Repeat(count, 43); var int count; //{
-        Print (ConcatStrings ("COUNT: ", IntToString (count)));
-    end; //}
-
-    /* Once 43 is reached, the loop is exited. */
-}; 
-

The following code should enumerate all pairs (x,y) with 0 <= x < max_x, 0 <= y < max_y

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
func void printpairs(var int max_x, var int max_y)
-{
-    // PrintDebug should be used, i.e. activate debug output
-    MEM_SetShowDebug (1);
-
-    var int x; var int y; x = 0;
-
-    Repeat(x, max_x); //{
-        y = 0;
-        Repeat(y, max_y); //{  
-            var string out; out = "(";
-            out = ConcatStrings (out, IntToString (x));
-            out = ConcatStrings (out, ", ");
-            out = ConcatStrings (out, IntToString (y));
-            out = ConcatStrings (out, ")");
-            PrintDebug (out);
-        end; //}
-    end; //}
-};
-
-/*
-    Output of a call printpairs(4,2) would then be: 
-    00:36 Info: 5 U: Skript: (0, 0) .... 
-    00:36 Info: 5 U: Skript: (0, 1) .... 
-    00:36 Info: 5 U: Skript: (1, 0) .... 
-    00:36 Info: 5 U: Skript: (1, 1) .... 
-    00:36 Info: 5 U: Skript: (2, 0) .... 
-    00:36 Info: 5 U: Skript: (2, 1) .... 
-    00:36 Info: 5 U: Skript: (3, 0) .... 
-    00:36 Info: 5 U: Skript: (3, 1) .... 
-*/
-
\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/ikarus/functions/keyboard/index.html b/cs/zengin/scripts/extenders/ikarus/functions/keyboard/index.html deleted file mode 100644 index 6d84307611..0000000000 --- a/cs/zengin/scripts/extenders/ikarus/functions/keyboard/index.html +++ /dev/null @@ -1,38 +0,0 @@ - Keyboard - Gothic Modding Community

Keyboard interaction

This part of Ikarus implements function that make interaction with keyboard possible.

Info

Keyboard interaction is also implemented with gameKeyEvents.d

Initialization

The best way to initialize all Ikarus functions is to call MEM_InitAll() in the Init_Global() initialization function.

Warning

If you want to use Ikarus in Gothic 1, it is best to define your own Init_Global() function and call it from every world initialization function.

MEM_InitAll();
-

Implementation

Ikarus.d on GitHub

Functions

Tip

Different players use different keys for specific actions! However, it is possible to get key assigned to the action from Gothic.ini. See Ini access.

MEM_KeyPressed

Checks if the key is hold right at the moment of function call.

func int MEM_KeyPressed(var int key)
-
Parameters
  • var int key
    Checked key

Return value

The function returns TRUE if the key is hold, FALSE is returned otherwise.

MEM_KeyState

Returns the state of the key.

func int MEM_KeyState(var int key)
-
Parameters
  • var int key
    Checked key

Return value

The function returns actual key state.

Key states

  • KEY_UP - The key is not pressed and was not pressed before. ("not pressed")
  • KEY_PRESSED - The key is pressed and was not previously pressed. ("new pressed")
  • KEY_HOLD - The key is pressed and was also pressed before. ("still pressed")
  • KEY_RELEASED - The key is not pressed and was previously pressed. ("let go")

KEY_PRESSED or KEY_RELEASED will be returned if the state of the key has changed since the last query.

KEY_UP or KEY_HOLD are returned if the state has not changed.

MEM_InsertKeyEvent

Makes the game think that the key was pressed.

func void MEM_InsertKeyEvent(var int key)
-
Parameters
  • var int key
    Key to be "pressed"
\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/ikarus/functions/mem_access/index.html b/cs/zengin/scripts/extenders/ikarus/functions/mem_access/index.html deleted file mode 100644 index 32b8ca40b1..0000000000 --- a/cs/zengin/scripts/extenders/ikarus/functions/mem_access/index.html +++ /dev/null @@ -1,53 +0,0 @@ - Memory Access - Gothic Modding Community

Elementary memory access

This part of Ikarus makes it possible to read and write memory as different data types - integers, strings, arrays of integers or strings and bytes.

If address <= 0, an error is thrown. Otherwise, an attempt is made to read or write at this address. If the address falls into invalid range, for example in a code segment, access violation will occur (Gothic crashes). In the case of string operations, it is also necessary that at the specified position a valid zString already exists.

Initialization

The best way to initialize all Ikarus functions is to call MEM_InitAll() in the Init_Global() initialization function.

Warning

If you want to use Ikarus in Gothic 1, it is best to define your own Init_Global() function and call it from every world initialization function.

MEM_InitAll();
-

Implementation

Ikarus.d on GitHub

Read functions

MEM_ReadInt

Reads int from the address.

func int MEM_ReadInt(var int address)
-
Parameters
  • var int address
    Memory address to read from

Return value

The function returns an integer value if the address is correct.

MEM_ReadString

Reads string from the address.

func string MEM_ReadString(var int address)
-
Parameters
  • var int address
    Memory address to read from

Return value

The function returns string if the address is correct.

MEM_ReadByte

Reads byte from the address.

func int MEM_ReadByte(var int address)
-
Parameters
  • var int address
    Memory address to read from

Return value

The function returns byte value if the address is correct.

MEM_ReadIntArray

Reads int from the array at the arrayAddress.

func int MEM_ReadIntArray(var int arrayAddress, var int offset)
-
Parameters
  • var int arrayAddress
    Memory address of array
  • var int offset
    Array offset (array index)

Return value

The function returns integer value from the array if the address is correct.

MEM_ReadStringArray

Info

MEM_ReadStringArray has been already moved to the LeGo PermMem package.

MEM_ReadByteArray

Reads byte from the array at the arrayAddress.

func int MEM_ReadByteArray(var int arrayAddress, var int offset)
-
Parameters
  • var int arrayAddress
    Memory address of array
  • var int offset
    Array offset (array index)

Return value

The function returns byte from the array if the address is correct.

Write functions

MEM_WriteInt

Writes int value in the address.

func void MEM_WriteInt(var int address, var int value)
-
Parameters
  • var int address
    Memory address to write into
  • var int value
    Integer value to write
Example

An example of using this function is the following Ikarus function, which turns debugging messages on and off:

1
-2
-3
-4
func void MEM_SetShowDebug(var int on)
-{
-    MEM_WriteInt(showDebugAddress, on);
-};
-

MEM_WriteString

Writes string in the address.

func void MEM_WriteString(var int address, var string value)
-
Parameters
  • var int address
    Memory address to write into
  • var int value
    String to write

MEM_WriteByte

Only the byte at address address is changed here, not a whole four-byte word. That is, the three subsequent bytes remain untouched. If 0 <= val < 256 does not apply in MEM_WriteByte, a warning is issued and val is trimmed accordingly. In particular, shouldn't be negative numbers are passed.

func void MEM_WriteByte(var int address, var int value)
-
Parameters
  • var int address
    Memory address to write into
  • var int value
    Byte to write

MEM_WriteIntArray

Writes int value in the array at arrayAddress.

func void MEM_WriteIntArray(var int arrayAddress, var int offset, var int value)
-
Parameters
  • var int arrayAddress
    Memory address of array
  • var int offset
    Array offset (array index)
  • var int value
    Integer value to write

MEM_WriteStringArray

Writes string value in the array at arrayAddress.

func void MEM_WriteStringArray(var int arrayAddress, var int offset, var string value)
-
Parameters
  • var int arrayAddress
    Memory address of array
  • var int offset
    Array offset (array index)
  • var string value
    String to write

MEM_WriteByteArray

Writes byte value in the array at arrayAddress.

func void MEM_WriteByteArray(var int arrayAddress, var int offset, var int value)
-
Parameters
  • var int arrayAddress
    Memory address of array
  • var int offset
    Array offset (array index)
  • var int value
    Byte to write
\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/ikarus/functions/mem_utility/index.html b/cs/zengin/scripts/extenders/ikarus/functions/mem_utility/index.html deleted file mode 100644 index 97ef114132..0000000000 --- a/cs/zengin/scripts/extenders/ikarus/functions/mem_utility/index.html +++ /dev/null @@ -1,48 +0,0 @@ - Memory utility - Gothic Modding Community

Memory utility

Ikarus utility functions, for memory management and manipulation.

Initialization

The best way to initialize all Ikarus functions is to call MEM_InitAll() in the Init_Global() initialization function.

Warning

If you want to use Ikarus in Gothic 1, it is best to define your own Init_Global() function and call it from every world initialization function.

MEM_InitAll();
-

Implementation

Ikarus.d on GitHub

Functions

MEM_Alloc

Allocates a specified amount of memory and returns a pointer to the allocated memory area.

Danger

Gothic does not and cannot retain a reference to this memory area or release it, even when destroying the session. Therefore, memory should only be reserved under certain conditions:

  • It is guaranteed to exist and can be released again with MEM_Free after loading a save game.
  • Gothic is aware of this memory area and independently releases it.

It might be possible to create new objects with this function and permanently integrate them into the object structure of Gothic. However, extreme caution is advised, as object structures cannot be used, and manual handling is required.

This function is well-suited for building small elements like list items and integrating them into existing lists. The memory allocated by this function is always initialized to zero.

func int MEM_Alloc(var int amount)
-
Parameters
  • var int amount
    The amount of bytes to allocate

Return value

The function returns a pointer to the allocated memory area.

MEM_Realloc

Allocates a memory area of ​​size newsize and returns a pointer to this memory area. The memory area from location ptr is released.

If newsize >= oldsize, the first oldsize bytes from the old memory area are transferred to the new one. The additional memory is initialized with zero.

If newsize <= oldsize, all bytes of the new memory area are initialized with the corresponding values ​​of the old memory area.

This function is intended to create an allocated memory area enlarge or reduce. Existing data remains naturally way received.

func int MEM_Realloc(var int ptr, var int oldsize, var int newsize)
-
Parameters
  • var int ptr
    The original pointer to the memory block
  • var int oldsize
    The size of the original memory block
  • var int newsize
    The size of the new memory block

Return value

The function returns a pointer to the modified memory area.

MEM_Free

Releases an allocated memory area.

Danger

Great caution is advised, especially when attempting to destroy engine objects, as no destructors are called!

Releasing small things such as list elements can be done easily.

func void MEM_Free(var int ptr)
-
Parameters
  • var int ptr
    Pointer to the released memory block

MEM_Copy

Copies a specified number of words from the source address to the destination address.

func void MEM_Copy(var int src, var int dst, var int wordcount)
-
Parameters
  • var int src
    The source address to copy from
  • var int dst
    The destination address to copy to
  • var int wordCount
    The number of words to copy

MEM_CopyWords

Alias to MEM_Copy. Copies a specified number of words from the source address to the destination address.

func void MEM_CopyWords(var int src, var int dst, var int wordcount) 
-
Parameters
  • var int src
    The source address to copy from
  • var int dst
    The destination address to copy to
  • var int wordCount
    The number of words to copy

MEM_CopyBytes

Copies a specified number of bytes from the source address to the destination address

func void MEM_CopyBytes(var int src, var int dst, var int byteCount)
-
Parameters
  • var int src
    The source address to copy from
  • var int dst
    The destination address to copy to
  • var int byteCount
    The number of bytes to copy

MEM_Swap

Swaps a specified number of words between the source address and the destination address.

func void MEM_Swap(var int src, var int dst, var int wordCount)
-
Parameters
  • var int src
    The source address to swap from
  • var int dst
    The destination address to swap to
  • var int wordCount
    The number of words to swap

MEM_SwapWords

Alias to MEM_Swap. Swaps a specified number of words between the source address and the destination address.

func void MEM_SwapWords(var int src, var int dst, var int wordCount)
-
Parameters
  • var int src
    The source address to swap from
  • var int dst
    The destination address to swap to
  • var int wordCount
    The number of words to swap

MEM_SwapBytes

Swaps a specified number of bytes between the source address and the destination address.

func void MEM_SwapBytes(var int src, var int dst, var int byteCount)
-
Parameters
  • var int src
    The source address to swap from
  • var int dst
    The destination address to swap to
  • var int byteCount
    The number of bytes to swap

MEM_Clear

Sets a specified number of bytes in memory to zero.

func void MEM_Clear(var int ptr, var int size)
-
Parameters
  • var int ptr
    The memory address to start clearing from
  • var int size
    The number of bytes to clear

MEM_Compare

Compares a specified number of words between two memory blocks.

func int MEM_Compare(var int ptr0, var int ptr1, var int wordCount)
-
Parameters
  • var int ptr0
    The first memory block to compare
  • var int ptr1
    The second memory block to compare
  • var int wordCount
    The number of words to compare

Return value

The function returns TRUE if the memory blocks are equal, FALSE is returned otherwise.

MEM_CompareWords

Alias to MEM_Compare. Compares a specified number of words between two memory blocks.

func int MEM_CompareWords(var int ptr0, var int ptr1, var int wordCount)
-
Parameters
  • var int ptr0
    The first memory block to compare
  • var int ptr1
    The second memory block to compare
  • var int wordCount
    The number of words to compare

Return value

The function returns TRUE if the memory blocks are equal, FALSE is returned otherwise.

MEM_CompareBytes

Compares a specified number of bytes between two memory blocks.

func int MEM_CompareBytes(var int ptr1, var int ptr2, var int byteCount)
-
Parameters
  • var int ptr0
    The first memory block to compare
  • var int ptr1
    The second memory block to compare
  • var int wordCount
    The number of bytes to compare

Return value

The function returns TRUE if the memory blocks are equal, FALSE is returned otherwise.

\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/ikarus/functions/menu_access/index.html b/cs/zengin/scripts/extenders/ikarus/functions/menu_access/index.html deleted file mode 100644 index 985d0ba111..0000000000 --- a/cs/zengin/scripts/extenders/ikarus/functions/menu_access/index.html +++ /dev/null @@ -1,37 +0,0 @@ - Access Menu Objects - Gothic Modding Community

Access Menu Objects

These Ikarus functions are intended to provide and simplify access to menu items (e.g. in the character menu).

Tip

Some menus are generated every time they are used, while others are generated once and then kept. For example, a character menu is only available after it was opened for the first time, after that it is kept in memory. Depending on what you actually want to do, it can make sense to introduce changes in the menu scripts.

Initialization

The best way to initialize all Ikarus functions is to call MEM_InitAll() in the Init_Global() initialization function.

Warning

If you want to use Ikarus in Gothic 1, it is best to define your own Init_Global() function and call it from every world initialization function.

MEM_InitAll();
-

Implementation

Ikarus.d on GitHub

Functions

MEM_GetMenuByString

func int MEM_GetMenuByString(var string menuName)
-

Parameters

  • var string menuName
    Name of the Gothic menu e.g. MENU_STATUS

Return value

The function returns the address of the menu if a menu with this name exists, null otherwise.

MEM_GetMenuItemByString

func int MEM_GetMenuItemByString(var string menuItemName)
-

Parameters

  • var string menuItemName
    Name of the Gothic menu item e.g. MENU_ITEM_PLAYERGUILD_TITLE

Return value

The function returns the address of the menu item if a menu item with this name exists, null otherwise.

\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/ikarus/functions/objects/index.html b/cs/zengin/scripts/extenders/ikarus/functions/objects/index.html deleted file mode 100644 index 45f2979727..0000000000 --- a/cs/zengin/scripts/extenders/ikarus/functions/objects/index.html +++ /dev/null @@ -1,155 +0,0 @@ - zCObjects - Gothic Modding Community

zCObjects

Set of functions for working with zCObject and its subclasses instances.

Initialization

The best way to initialize all Ikarus functions is to call MEM_InitAll() in the Init_Global() initialization function.

Warning

If you want to use Ikarus in Gothic 1, it is best to define your own Init_Global() function and call it from every world initialization function.

MEM_InitAll();
-

Implementation

Ikarus.d on GitHub

Global instances

Ikarus package introduces the following instances:

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
instance MEM_Game (oCGame);
-instance MEM_World(oWorld);
-instance MEM_Timer(zCTimer);
-instance MEM_WorldTimer(oCWorldTimer);
-instance MEM_Vobtree(zCTree);
-instance MEM_InfoMan(oCInfoManager);
-instance MEM_InformationMan (oCInformationManager);
-instance MEM_Waynet(zCWaynet);
-instance MEM_Camera(zCCamera);
-instance MEM_SkyController(zCSkyController_Outdoor);
-instance MEM_SpawnManager (oCSpawnManager);
-instance MEM_GameMananger (CGameManager);
-instance MEM_GameManager (CGameManager);
-instance MEM_Parser(zCParser);
-

The classes used here all have one thing in common: there is a maximum of one object of them at the same time (e.g. there is not two worlds or two sky at the same time).

MEM_InitGlobalInst function sets the offsets of these instances to the corresponding unique object. While it has been called, all of the above instances can be used.

MEM_InitGlobalInst

Initializes global instances of commonly used objects in the game (is called by the MEM_InitAll function).

func void MEM_InitGlobalInst()
-

Warning

MEM_InitGlobalInst must be executed once after loading a savegame. The easiest way is do it is to call this function from INIT_GLOBAL.

Functions

About zCClassDef

For every class (derived from zCObject) there is an "administrative object" of type zCClassDef. This encapsulates some useful information about all objects in this class.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
class zCClassDef {
-    var string className;            //zSTRING
-    var string baseClassName;        //zSTRING
-    var string scriptClassName;      //zSTRING
-    var int baseClassDef;            //zCClassDef*
-    var int createNewInstance;       //zCObject* ( *) (void) 
-    var int createNewInstanceBackup; //zCObject* ( *) (void)
-    var int classFlags;              //zDWORD
-    var int classSize;               //zDWORD
-    var int numLivingObjects;
-    var int numCtorCalled;
-    var int hashTable;               //zCObject**
-    var int objectList_array;        //zCObject**
-    var int objectList_numAlloc;     //int
-    var int objectList_numInArray;   //int
-    var int bitfield;
-};
-

Full Ikarus definition of this class, with members description can be found in Misc.d file. The class is same for G1 and G2A engines.

MEM_GetClassDef

Returns a pointer to the zCClassDef of the object. For more info see the About zCClassDef section above.

Passing these functions a pointer that does not point to a zCObject will most likely result in a crash lead.

func int MEM_GetClassDef(var int objPtr)
-
Parameters
  • var int objPtr
    A pointer to the object whose class definition is to be retrieved

Return value

The function returns a pointer to the zCClassDef of the object.

Example

This would return a pointer to the zCClassDef object that belongs to the oCNpc class.

1
-2
-3
-4
-5
func int example1
-{
-    var int her; her = MEM_InstToPtr(hero);
-    return MEM_GetClassDef(her);
-};
-

MEM_GetClassName

This function returns the name of the class to which an object belongs.

func string MEM_GetClassName(var int objPtr)
-
Parameters
  • var int objPtr
    A pointer to the object whose class name is to be retrieved

Return value

The function returns the objects class name as a string, if the object is invalid an empty string is returned.

Example

This would return a name of the oCNpc class as a string.

1
-2
-3
-4
-5
-6
func string example2
-{
-    var int her; her = MEM_InstToPtr(hero);
-    return MEM_GetClassName(her);
-};
-// return: "oCNpc"
-

MEM_CheckInheritance

Checks if an object is derived from a specific class definition.

func int MEM_CheckInheritance(var int objPtr, var int classDef)
-
Parameters
  • var int objPtr
    A pointer to the object to be checked
  • var int classDef
    A pointer to the class definition to check against

Return value

The function returns TRUE if the object is derived from the specified class definition, FALSE is returned otherwise.

Hlp_Is_*

In addition MEM_CheckInheritance function has some overloads with hardcoded classDef parameter.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
func int Hlp_Is_oCMobFire(var int ptr){};
-func int Hlp_Is_zCMover(var int ptr){};
-func int Hlp_Is_oCMob(var int ptr){};
-func int Hlp_Is_oCMobInter(var int ptr){};
-func int Hlp_Is_oCMobLockable(var int ptr){};
-func int Hlp_Is_oCMobContainer(var int ptr){};
-func int Hlp_Is_oCMobDoor(var int ptr){};
-func int Hlp_Is_oCMobBed(var int ptr){};
-func int Hlp_Is_oCMobSwitch(var int ptr){};
-func int Hlp_Is_oCMobWheel(var int ptr){};
-func int Hlp_Is_oCMobLadder(var int ptr){};
-func int Hlp_Is_oCNpc(var int ptr){};
-func int Hlp_Is_oCItem(var int ptr){};
-func int Hlp_Is_zCVobLight(var int ptr){};
-

The usage of these functions is probably obvious, they checks if the given object belongs to class given in the function name.

MEM_InsertVob

Inserts a Vob with the visual vis at the waypoint wp. If the visual or waypoint does not exist, this is the behaviour this function undefined.

Note

The inserted Vob is even an oCMob, so it can be given a focus name, for example. But you can treat it like a zCVob), if you don't need the additional properties.

func int MEM_InsertVob(var string vis, var string wp)
-
Parameters
  • var string vis
    Name of the inserted Vob visual ("FAKESCROLL.3DS", "FIRE.PFX", "SNA_BODY.ASC", "CHESTSMALL_NW_POOR_LOCKED.MDS", "ADD_PIRATEFLAG.MMS" etc.)
  • var string wp
    Name of the waypoint to insert Vob on

Return value

The function returns a pointer to the created object.

MEM_DeleteVob

Deletes a specific Vob form world.

func void MEM_DeleteVob(var int vobPtr)
-
Parameters
  • var int vobPtr
    Pointer to a zCVob object to be deleted

MEM_RenameVob

Renames the passed Vob to the newName that is also passed.

The object becomes this first removed from the Vob-hashtable, then unnamed and then again inserted into the Vob-hashtable under a new name.

func void MEM_RenameVob(var int vobPtr, var string newName)
-
Parameters
  • var int vobPtr
    Pointer to a zCVob object to be renamed
  • var string newName
    The new Name of the Vob

MEM_TriggerVob

Sends a trigger message to the Vob.

func void MEM_TriggerVob(var int vobPtr)
-
Parameters
  • var int vobPtr
    Pointer to a triggered zCVob

Danger

If triggering the Vob has immediate effects (even before MEM_TriggerVob is exited), the name of the Vob is corrupted during this time. It is not advisable to rename, trigger again or destroy the object at this moment, the behavior in such cases is untested.

MEM_UntriggerVob

Sends an untrigger message to the Vob.

func void MEM_TriggerVob(var int vobPtr)
-
Parameters
  • var int vobPtr
    Pointer to an untriggered zCVob

Danger

If untriggering the Vob has immediate effects (even before MEM_TriggerVob is exited), the name of the Vob is corrupted during this time. It is not advisable to rename, trigger again or destroy the object at this moment, the behavior in such cases is untested.

MEM_SearchVobByName

Returns the address of a zCVob named str if such a Vob exists.

func int MEM_SearchVobByName(var string str)
-
Parameters
  • var string str
    Name of searched zCVob

Return value

The function returns a pointer to the zCVob if the object with the given name exist. 0 is returned otherwise.

MEM_SearchAllVobsByName

Variation of MEM_SearchVobByName. Creates a zCArray in which all pointers are to Vobs with the name str. If no Vob with the name exists, an empty zCArray is created. A pointer to the created zCArray is then returned. This can be evaluated, but should be released again with MEM_ArrayFree before the end of the frame (before the player can load) to avoid memory leaks.

func int MEM_SearchAllVobsByName(var string str)
-
Parameters
  • var string str
    Name of searched zCVob

Return value

The function returns a pointer to the created zCArray, that contains pointers to the all Vobs with the specified name.

MEM_GetBufferCRC32

Calculates the CRC32 hash value from a byte array starting at the address specified by buf and having a length of buflen.

func int MEM_GetBufferCRC32(var int buf, var int buflen)
-
Parameters
  • var int buf
    Address of a byte array, the hash calculation will begin from

  • var int buflen
    The length of the byte array starting from the address specified by buf

Return value

The function returns the calculated CRC32 hash value.

MEM_GetStringHash

Calculates the CRC32 hash value for a string.

func int MEM_GetStringHash(var string str)
-
Parameters
  • var string str
    A string for which the hash value is to be calculated

Return value

The function returns an integer representing the calculated hash value for the input string.

\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/ikarus/functions/parser/index.html b/cs/zengin/scripts/extenders/ikarus/functions/parser/index.html deleted file mode 100644 index 5f4e4a9545..0000000000 --- a/cs/zengin/scripts/extenders/ikarus/functions/parser/index.html +++ /dev/null @@ -1,110 +0,0 @@ - Parser stuff - Gothic Modding Community

zCParser related functions

This Ikarus part provides some useful functions to work with parser, its instances, symbols and stack.

Danger

Remember to always assign an instance to a correct class. If you assign an oCNpc pointer to oCItem class you won't be able to read any data from it.

Implementation

Ikarus.d on GitHub

Initialization

The best way to initialize all Ikarus functions is to call MEM_InitAll() in the Init_Global() initialization function.

Warning

If you want to use Ikarus in Gothic 1, it is best to define your own Init_Global() function and call it from every world initialization function.

MEM_InitAll();
-

MEM_ReinitParser

Parser operations are initialized with this function.

func void MEM_ReinitParser()
-

Tip

It's worth noting that MEM_ReinitParser is also invoked by the MEM_InitAll function.

Pointers and instances

MEM_PtrToInst

Returns an instance pointed to by the pointer. If the pointer is null an error is thrown.

func MEMINT_HelperClass MEM_PtrToInst(var int ptr)
-
Parameters
  • var int ptr
    Pointer to return an instance from

Shortcut

In addition there is a function _^ with the same signature and functionality as MEM_PtrToInst. It is used as a shortcut, since the converting pointer to instance is commonly used while working with Ikarus.

func MEMINT_HelperClass _^ (var int ptr)
-
Example

Following code

var oCNpc her; her = MEM_PtrToInst(heroPtr);
-
is equivalent to
var oCNpc her; her = _^(heroPtr);
-

MEM_NullToInst

Returns an instance from a null pointer.

func MEMINT_HelperClass MEM_NullToInst()
-

MEM_AssignInst

Takes an instance from a pointer and assigns it to a given instance. If the pointer is null an error is thrown.

func void MEM_AssignInst(var int inst, var int ptr)
-
Parameters
  • var int ptr
    Pointer to assign an instance from
  • var int inst
    Instance to which the pointer will be assigned
Example

Following code

1
-2
var oCNpc inst;
-MEM_AssignInst (inst, ptr); 
-
is equivalent to
1
-2
var oCNpc inst;
-inst = MEM_PtrToInst(ptr);
-

MEM_AssignInstNull

Assigns null pointer to a given instance.

func void MEM_AssignInstNull(var int inst)
-
Parameters
  • var int inst
    Instance to which the null pointer will be assigned

MEM_InstToPtr

Returns a pointer to given instance.

func int MEM_InstToPtr(var int inst)
-
Parameters
  • var int inst
    The instance to which the pointer is returned

MEM_InstGetOffset

Alias to MEM_InstToPtr. Returns a pointer to given instance.

func int MEM_InstGetOffset(var int inst)
-
Parameters
  • var int inst
    The instance to which the pointer is returned

MEM_CpyInst

Returns a copy of a given instance

func MEMINT_HelperClass MEM_CpyInst(var int inst)
-
Parameters
  • var int inst
    Instance to copy
example

Following code

selfCopy = MEM_CpyInst (self);
-
is equivalent to
selfCopy = MEM_PtrToInst (MEM_InstToPtr (self));
-

Call function

You don't always know at compile time when you want to call which function. For example, if you want to call the condition function of a mob that the player has in focus, you are at a loss at compile time because you have no idea which mob the player will choose. Ikarus provides a way to call functions based on their name or symbol index. In the example of the mob, the name of the condition function can simply be looked up in the mob.

Note

The functions below also work for externals without any restrictions.

Passing Parameters

If the function to be called has parameters, these must first be placed on the data stack. The parameters must be pushed in the correct order, from left to right.

MEM_PushIntParam

Passes an integer as a parameter to the called function.

func void MEM_PushIntParam (var int param)
-
Parameters
  • var int param
    Integer to pass as a function parameter

MEM_PushInstParam

Passes an instance as a parameter to the called function.

func void MEM_PushInstParam (var int inst)
-
Parameters
  • var int inst
    Instance to pass as a function parameter

MEM_PushStringParam

Passes a string as a parameter to the called function.

func void MEM_PushStringParam (var string str)
-
Parameters
  • var string str
    String to pass as a function parameter

The call

MEM_Call

Calls a function.

func void MEM_Call(var func fnc)
-
Parameters
  • var func fnc
    Function to be called

MEM_CallByID

Calls a function by its ID.

func void MEM_CallByID (var int symbID)
-
Parameters
  • var int symbID
    The ID of the function to be called

MEM_CallByPtr

Calls a function by its pointer.

func void MEM_CallByPtr(var int ptr)
-
Parameters
  • var int ptr
    The pointer of the function to be called

MEM_CallByOffset

Calls a function by its offset.

func void MEM_CallByOffset(var int offset)
-
Parameters
  • var int offset
    The offset of the function to be called

MEM_CallByString

Calls a function by its name.

func void MEM_CallByString (var string fnc)
-
Parameters
  • var string fnc
    The name of the function IN CAPITAL LETTERS.

Return value

If a function has a return value, it should be fetched from the data stack after it is called, otherwise stack overflows can occur under unfavorable circumstances (aside from that, you may simply want the return value because it contains important information).

MEM_PopIntResult

Retrieves an integer returned by the called function.

func int MEM_PopIntResult()
-
Return value

The function returns an integer returned by the previously called script function.

MEM_PopStringResult

Retrieves a daedalus string returned by the called function.

func string MEM_PopStringResult()
-
Return value

The function returns a string returned by the previously called script function.

MEM_PopInstResult

Retrieves an instance returned by the called function.

func MEMINT_HelperClass MEM_PopInstResult()
-
Return value

The function returns an instance returned by the previously called script function.

Function stuff

MEM_GetFuncID

Returns the ID of the given function.

func int MEM_GetFuncID(var func fnc)
-
Parameters
  • var func fnc
    The function whose ID is returned

MEM_GetFuncPtr

Returns the pointer of the given function.

func int MEM_GetFuncPtr(var func fnc)
-
Parameters
  • var func fnc
    The function whose pointer is returned

MEM_GetFuncOffset

Returns the offset of the given function.

func int MEM_GetFuncOffset(var func fnc)
-
Parameters
  • var func fnc
    The function whose offset is returned

MEM_GetFuncIDByOffset

MEM_GetFuncID, but with an offset as a parameter.

func int MEM_GetFuncIDByOffset(var int offset)
-
Parameters
  • var int offset
    Offset of a function whose ID is returned

Return value

The function returns an ID of a function with a given offset.

MEM_ReplaceFunc

Replaces the f1 function with f2 function so if you call the first function, the second function is called.

func void MEM_ReplaceFunc(var func f1, var func f2)
-
Parameters
  • var func f1
    Function to replace
  • var func f2
    Function called instead of f1

Parser stack

MEM_GetFrameBoundary

Returns the address/pointer to the boundary of a stack frame (ESP).

func int MEM_GetFrameBoundary()
-

MEM_GetCallerStackPos

Retrieves the stack position (pop position) of the caller's caller (look at the example for better understanding).

func int MEM_GetCallerStackPos()
-
Return value

The function returns an integer representing the stack position of the caller's caller.

Example

After calling B() from within A(), when MEM_GetCallerStackPos() is invoked in function B(), it retrieves the stack position of the caller's caller, which is function A() in this case. Therefore, the variable adr will contain the stack position of function A().

1
-2
-3
-4
-5
-6
-7
-8
func void A(){
-    B();
-};
-
-func void B(){
-    int adr; adr = MEM_GetCallerStackPos();
-    // Now, 'adr' will contain the stack position of A.
-};
-

MEM_SetCallerStackPos

Sets the stack position (pop position) of the caller's caller.

func void MEM_SetCallerStackPos(var int popPos)
-
Parameters
  • var int popPos
    An integer parameter representing the new stack position of the caller's caller

Get address

MEM_GetAddress_Init

Initializes the MEM_GetIntAddress, MEM_GetFloatAddress and MEM_GetStringAddress functions.

func void MEM_GetAddress_Init()
-

Tip

It's worth noting that MEM_GetAddress_Init is also invoked by the MEM_InitAll function.

MEM_GetIntAddress

Returns an address of a given integer.

func int MEM_GetIntAddress(var int i)
-
Parameters
  • var int i
    Integer whose address is returned

Shortcut

In addition there is a function _@ with the same signature and functionality as MEM_GetIntAddress.

func int _@(var int i)
-

MEM_GetFloatAddress

Returns an address of a given daedalus float.

func int MEM_GetFloatAddress(var float f)
-
Parameters
  • var float f
    Float whose address is returned

Shortcut

In addition there is a function _@f with the same signature and functionality as MEM_GetFloatAddress.

func int _@s(var string s)
-

MEM_GetStringAddress

Returns an address of a given string.

func int MEM_GetStringAddress(var string s)
-
Parameters
  • var string s
    String whose address is returned

Shortcut

In addition there is a function _@s with the same signature and functionality as MEM_GetStringAddress.

func int _@s(var string s)
-

STR_GetAddressInit

Alias to MEM_GetAddress_Init, kept for downward compatibility.

func void STR_GetAddressInit()
-

STR_GetAddress

Function similar to MEM_GetStringAddress. There is a guarantee, that this function works initialized i.e. invokes MEM_GetAddress_Init, but the first time may only return an address of a copy of the string.

func int STR_GetAddress(var string str)
-

Static arrays

Accessing static arrays like this below is very tedious in Daedalus.

var int myStaticArray[42];
-
It is not possible to access myStaticArray[i] with a variable index i, but only with a constant. This changes with the following functions.

Danger

Neither function performs any kind of validity check. If the value passed is not an array or offsets are beyond the boundaries of the array passed, the behavior is undefined.

MEM_InitStatArrs

Initializes static arrays read and write functions.

func void MEM_InitStatArrs()
-

MEM_WriteStatArr

Changes the value at the offset of a static integer-array.

func void MEM_WriteStatArr (var int array, var int offset, var int value)
-
Parameters
  • var int array
    Array which will be edited
  • var int offset
    Array index at which value will be edited
  • var int value
    The new value

MEM_ReadStatArr

Reads the value at the specific offset of a static integer-array.

func int MEM_ReadStatArr (var int array, var int offset)
-
Parameters
  • var int array
    Array to get a value from
  • var int offset
    Array index of the value to return

Return value

The function returns an integer value from the offset of a given static array.

MEM_WriteStatStringArr

Changes the value at the offset of a static string-array.

func void MEM_WriteStatStringArr(var string array, var int offset, var string value)
-
Parameters
  • var string array
    Array which will be edited
  • var int offset
    Array index at which value will be edited
  • var string value
    The new value

MEM_ReadStatStringArr

Reads the value at the specific offset of a static string-array.

func string MEM_ReadStatStringArr(var string array, var int offset)
-
Parameters
  • var string array
    Array to get a value from
  • var int offset
    Array index of the value to return

Return value

The function returns a string form the offset of a given static array.

Parser symbol

MEM_SetCurrParserSymb

Makes currParserSymb point to the symbol of the specified instance.

func void MEM_SetCurrParserSymb (var int inst)
-
Parameters
  • var int inst
    Instance to whose symbol currParserSymb will be set

currParserSymb

An instance representing current parser symbol.

INSTANCE currParserSymb (zCPar_Symbol);
-

MEM_FindParserSymbol

Returns the index of the parser symbol with name inst if such a symbol exists.

func int MEM_FindParserSymbol(var string inst)
-
Parameters
  • var string inst
    Name of the symbol to be found

Return value

The function returns the index of the parser symbol with name inst if such a symbol exists. If non exists, a warning is issued and -1 is returned.

MEM_GetSymbolIndex

Alias to MEM_FindParserSymbol. Returns the index of the parser symbol with name inst if such a symbol exists.

func int MEM_GetSymbolIndex(var string inst)
-
Parameters
  • var string inst
    Name of the symbol to be found

Return value

The function returns the index of the parser symbol with name inst if such a symbol exists. If non exists, a warning is issued and -1 is returned.

MEM_GetParserSymbol

Looks for the parser symbol with the name inst and returns a pointer to the appropriate zCPar_Symbol structure.

func int MEM_GetParserSymbol (var string inst)
-
Parameters
  • var string inst
    Name of the symbol to be found

Return value

The function returns the appropriate zCPar_Symbol structure of the parser symbol with name inst if such a symbol exists. If non exists, a warning is issued and 0 is returned.

MEM_GetSymbol

Alias to MEM_GetParserSymbol. Looks for the parser symbol with the name inst and returns a pointer to the appropriate zCPar_Symbol structure.

func int MEM_GetSymbol(var string inst)
-
Parameters
  • var string inst
    Name of the symbol to be found

Return value

The function returns the appropriate zCPar_Symbol structure of the parser symbol with name inst if such a symbol exists. If non exists, a warning is issued and 0 is returned.

MEM_GetSymbolByIndex

MEM_GetParserSymbol, but with ID (index) as a parameter.

func int MEM_GetSymbolByIndex(var int id)
-
Parameters
  • var string inst
    ID (index) of the symbol to be found

Return value

The function returns the appropriate zCPar_Symbol structure of the parser symbol with name inst if such a symbol exists. If non exists, a warning is issued and 0 is returned.

\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/ikarus/functions/preamble/index.html b/cs/zengin/scripts/extenders/ikarus/functions/preamble/index.html deleted file mode 100644 index 618f78c987..0000000000 --- a/cs/zengin/scripts/extenders/ikarus/functions/preamble/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/cs/zengin/scripts/extenders/ikarus/functions/string/index.html b/cs/zengin/scripts/extenders/ikarus/functions/string/index.html deleted file mode 100644 index 5067991546..0000000000 --- a/cs/zengin/scripts/extenders/ikarus/functions/string/index.html +++ /dev/null @@ -1,138 +0,0 @@ - String operations - Gothic Modding Community

String operations

Collection of Ikarus functions to manipulate and format strings.

Initialization

The best way to initialize all Ikarus functions is to call MEM_InitAll() in the Init_Global() initialization function.

Warning

If you want to use Ikarus in Gothic 1, it is best to define your own Init_Global() function and call it from every world initialization function.

MEM_InitAll();
-

Implementation

Ikarus.d on GitHub

Functions

STR_GetCharAt

Returns the ASCII value of a character at a specific position in a string.

func int STR_GetCharAt (var string str, var int pos)
-
Parameters
  • var string str
    The input string
  • var int pos
    The position of the character

Return value

The function returns the ASCII value of the character at the specified position.

STR_Len

Returns the length of a string.

func int STR_Len (var string str)
-
Parameters
  • var string str
    The input string

Return value

The function returns the length of the string in characters.

STR_toChar

Converts a string to a pointer to its character array.

func int STR_toChar (var string str)
-
Parameters
  • var string str
    The input string

Return value

The function returns a pointer to the character array representing the input string str

STR_FromChar

Converts a character array to a string.

func string STR_FromChar(var int char)
-
Parameters
  • var int char
    Pointer to the character array

Return value

The function returns a string representation of the character array.

STR_SubStr

Extracts a substring from a given string.

func string STR_SubStr (var string str, var int start, var int count)
-
Parameters
  • var string str
    The input string
  • var int start
    The starting position of the substring
  • var int count
    The length of the substring

Return value

The function returns a substring, if the starting position is invalid an empty string is returned.

STR_Prefix

Extracts a prefix of a given string, similar to STR_SubStr, but with the starting position set to the first character of the string.

func string STR_Prefix (var string str, var int len)
-
Parameters
  • var string str
    The input string
  • var int count
    The length of the prefix

Return value

The function returns a prefix of the input string with the specified length.

STR_Compare

Compares two strings lexicographically and returns a result indicating their relative order.

func int STR_Compare(var string str1, var string str2)
-
Parameters
  • var string str1 The first string to compare
  • var string str2 The second string to compare

Return Value

The function returns an integer value representing the result of the comparison:

  • STR_GREATER (1): If str1 comes lexicographically after str2.
  • STR_EQUAL (0): If str1 is lexicographically equal to str2.
  • STR_SMALLER (-1): If str1 comes lexicographically before str2.
Examples

The comparison is based on lexicographic order, which is the order of characters as they appear in the ASCII table. Uppercase letters come before lowercase letters.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
int result1 = STR_Compare("A", "B");
-// The 'result1' variable now contains STR_SMALLER
-
-int result2 = STR_Compare("ABC", "ABC");
-// The 'result2' variable now contains STR_EQUAL
-
-int result3 = STR_Compare("AA", "A");
-// The 'result3' variable now contains STR_GREATER
-
-int result4 = STR_Compare("BA", "BB");
-// The 'result4' variable now contains STR_SMALLER
-
-int result5 = STR_Compare("B", "a");
-// The 'result5' variable now contains STR_SMALLER
-
-int result6 = STR_Compare("A", "");
-// The 'result6' variable now contains STR_GREATER
-

STR_ToInt

Converts a string to an integer.

func int STR_ToInt (var string str)
-
Parameters
  • var string str
    The input string

Return Value

The function returns an integer value of the string, if a string is invalid (doesn't contain an integer) zero is returned.

STR_IndexOf

Searches for a substring tok within a given string and returns the index of the first occurrence of tok, taking into account upper and lower case letters.

func int STR_IndexOf(var string str, var string tok)
-
Parameters
  • var string str
    The string in which to search for tok.
  • var string tok
    The substring to search for within str.

Return Value

The function returns the index at which the first occurrence of tok begins within str. If tok is not found in str, the function returns -1.

Examples
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
int index1 = STR_IndexOf("Hello World!", "Hell");
-// The 'index1' variable now contains 0
-
-int index2 = STR_IndexOf("Hello World!", "World");
-// The 'index2' variable now contains 6
-
-int index3 = STR_IndexOf("Hello World!", "Cake");
-// The 'index3' variable now contains -1
-
-int index4 = STR_IndexOf("Hello World!", "");
-// The 'index4' variable now contains 0
-
-int index5 = STR_IndexOf("Hello", "Hello World!");
-// The 'index5' variable now contains -1
-
-int index6 = STR_IndexOf("hello Hell!", "Hell");
-// The 'index6' variable now contains 6
-
-int index7 = STR_IndexOf("", "");
-// The 'index7' variable now contains 0
-

STR_SplitCount

Counts the number of parts a string splits into when using a specified separator.

func int STR_SplitCount(var string str, var string separator)
-
Parameters
  • var string str
    The input string to be split.
  • var string separator
    The separator character or string used to split the input string.

Return Value

The function returns a number of parts the input string splits into when using the specified separator.

Example
1
-2
-3
string inputStr = "This is a sentence.";
-int count = STR_SplitCount(inputStr, " ");
-// The 'count' variable now contains 4
-

STR_Split

Splits a string into multiple substrings based on a specified separator and returns the substring at a specified offset.

func string STR_Split(var string str, var string separator, var int offset)
-

Parameters

  • var string str
    The input string to be split.
  • var string separator
    The separator character or string used to split the input string.
  • var int offset
    The index of the substring to be returned after splitting. The index is zero-based.

Return Value

The function returns a substring at the specified offset after splitting the input string. If the offset is greater than or equal to the number of parts generated by splitting, an empty string is returned.

Example

1
-2
-3
-4
-5
-6
-7
func void foo() {
-    string inputStr = "This is a sentence.";
-    string tok1 = STR_Split(inputStr, " ", 0); // This
-    string tok2 = STR_Split(inputStr, " ", 1); // is
-    string tok3 = STR_Split(inputStr, " ", 2); // a
-    string tok4 = STR_Split(inputStr, " ", 3); // sentence
-};
-
At the end of the function, tok1 contains "This", tok2 contains "is", tok3 contains "a", and tok4 contains "sentence.".

STR_Upper

Converts a string to uppercase.

func string STR_Upper(var string str)
-
Parameters
  • var string str
    The input string

Return Value

The function returns a copy of str with all uppercase letters converted to their corresponding uppercase letters.

STR_Lower

Converts a string to lowercase.

func string STR_Lower(var string str)
-
Parameters
  • var string str
    The input string

Return Value

The function returns a copy of str with all lowercase letters converted to their corresponding uppercase letters.

\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/ikarus/functions/time_benchmark/index.html b/cs/zengin/scripts/extenders/ikarus/functions/time_benchmark/index.html deleted file mode 100644 index 1d66272919..0000000000 --- a/cs/zengin/scripts/extenders/ikarus/functions/time_benchmark/index.html +++ /dev/null @@ -1,64 +0,0 @@ - Time and Benchmark - Gothic Modding Community

Time and Benchmark

Set of functions to time measurement and Benchmark.

Initialization

The best way to initialize all Ikarus functions is to call MEM_InitAll() in the Init_Global() initialization function.

Warning

If you want to use Ikarus in Gothic 1, it is best to define your own Init_Global() function and call it from every world initialization function.

MEM_InitAll();
-

Implementation

Ikarus.d on GitHub

Time functions

MEM_GetSystemTime

Returns the elapsed time since Gothic started.

func int MEM_GetSystemTime()
-
Return value

The function returns the elapsed time since the start of Gothic in milliseconds. This value is used for timing measurements, in the BenchmarkMS functions.

MEM_GetPerformanceCounter

Call to the WinAPI QueryPerformanceCounter function.

func int MEM_GetPerformanceCounter()
-
Return value

The function returns a value representing the number of elapsed ticks since the system was started. This value is used for timing measurements, in the BenchmarkPC functions.

Benchmark functions

Tip

For reliable results, avoid measuring a single run of a function; instead, measure the total duration of multiple runs (e.g., 1000). This is crucial, especially for very fast functions, as a single run can distort the measurement. Use _N benchmark functions to include a parameter specifying the number of runs for function f.

Choose the parameter n to ensure meaningful results. If n executions take less than a millisecond, obtaining a return value in milliseconds has no sense. For very fast functions, the time spent in the benchmark function, not in f, significantly affects the measurement, falsifying the result. Reliable measurements are achievable only for functions with sufficient slowness.

For reference, here is a timing for some operations (in nanoseconds, i.e., billionths of a second):

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
- Function call (jumping back and forth): 30ns
-- Elementary calculation (e.g., i = i + 1): 130ns
-- Wld_IsTime: 200ns
-- MEM_ReadInt, MEM_WriteInt: 350ns
-- Hlp_StrCmp("Hello", "Hello"): 500ns
-- MEM_InstToPtr: 1400ns
-- (small) Allocate and free memory: 9700ns
-- CALL__stdcall (in empty function): 29000ns
-- MEM_GetParserSymb: 280000ns
-
-- Iteration of the benchmark function: 300ns
-

MEM_BenchmarkMS

Benchmark of the execution time for a specified function. (Milliseconds)

func int MEM_BenchmarkMS(var func f)
-
Parameters
  • var func f
    Function to benchmark

Return value

The function returns the duration of a function execution in milliseconds.

MEM_BenchmarkMMS

Benchmark of the execution time for a specified function. (microseconds)

func int MEM_BenchmarkMMS(var func f)
-
Parameters
  • var func f
    Function to benchmark

Return value

The function returns the duration of a function execution in microseconds.

MEM_BenchmarkPC

Benchmark of the execution time for a specified function, using the Performancecounter.

func int MEM_BenchmarkMS(var func f)
-
Parameters
  • var func f
    Function to benchmark

Return value

The function returns the number of Performancecounter ticks the function needs.

MEM_BenchmarkMS_N

MEM_BenchmarkMS, but with the parameter to specify the number of function runs.

func int MEM_BenchmarkMS_N(var func f, var int n)
-
Parameters
  • var func f
    Function to benchmark
  • var int n
    Number of runs

Return value

The function returns a summed duration of multiple (n) runs of the function in milliseconds.

MEM_BenchmarkMMS_N

MEM_BenchmarkMMS, but with the parameter to specify the number of function runs.

func int MEM_BenchmarkMMS_N(var func f, var int n)
-
Parameters
  • var func f
    Function to benchmark
  • var int n
    Number of runs

Return value

The function returns a summed duration of multiple (n) runs of the function in microseconds.

MEM_BenchmarkPC_N

MEM_BenchmarkPC, but with the parameter to specify the number of function runs.

func int MEM_BenchmarkPC_N(var func f, var int n)
-
Parameters
  • var func f
    Function to benchmark
  • var int n
    Number of runs

Return value

The function returns a summed number of Performancecounter ticks needed to execute function multiple (n) times.

\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/ikarus/functions/win_utilities/index.html b/cs/zengin/scripts/extenders/ikarus/functions/win_utilities/index.html deleted file mode 100644 index f5a5ddabf1..0000000000 --- a/cs/zengin/scripts/extenders/ikarus/functions/win_utilities/index.html +++ /dev/null @@ -1,55 +0,0 @@ - Windows Utilities - Gothic Modding Community

Windows Utilities

This part of Ikarus implements some WinAPI functions that can be used directly from Gothic scripts.

Initialization

The best way to initialize all Ikarus functions is to call MEM_InitAll() in the Init_Global() initialization function.

Warning

If you want to use Ikarus in Gothic 1, it is best to define your own Init_Global() function and call it from every world initialization function.

MEM_InitAll();
-

Implementation

Ikarus.d on GitHub

Functions

LoadLibrary

Loads the specified module into the address space of the calling process. Full documentation here.

func int LoadLibrary(var string lpFileName)
-
Parameters
  • var string lpFileName
    Name of loaded module

Return value

The function returns a handle to the module.

GetProcAddress

Retrieves the address from the specified dynamic-link library. Full documentation here.

func int GetProcAddress(var int hModule, var string lpProcName)
-
Parameters
  • var int hModule
    A handle to the DLL module that contains the function or variable. Can be obtained using the LoadLibrary function.
  • var string lpProcName
    The function or variable name.

Return value The function returns address of the function or variable.

FindKernelDllFunction

Uses GetProcAddress to find function inside the KERNEL32.DLL file.

func int FindKernelDllFunction(var string name)
-
Parameters
  • var string name
    Name of the looked function.

Return value

The function returns address of the function.

VirtualProtect

Changes the protection on a region of committed pages in the virtual address space of the calling process. Full documentation here.

func int VirtualProtect(var int lpAddress, var int dwSize, var int flNewProtect)
-
Parameters
  • var int lpAddress
    The address of the starting page of the region of pages whose access protection attributes are to be changed.
  • var int dwSize
    The size of the region whose access protection attributes are to be changed, in bytes.
  • var int flNewProtect
    The memory protection option. All options can be found here.

Return value

The function returns lpflOldProtectPtr - a pointer to a variable that receives the previous access protection value.

Author's comment:

I made lpflOldProtectPtr the return value and ignored the return Value of VirtualProtect.

MemoryProtectionOverride

Alias to VirtualProtect but with predefined PAGE_EXECUTE_READWRITE protection option

func void MemoryProtectionOverride(var int address, var int size)
-
Parameters
  • var int address
    The address of the starting page of the region of pages whose access protection attributes are to be changed.
  • var int size
    The size of the region whose access protection attributes are to be changed, in bytes.

MEM_MessageBox

Calls the WinAPI MessageBox function.

func int MEM_MessageBox(var string txt, var string caption, var int type)
-
Parameters
  • var string txt
    Content of the MessageBox.
  • var string caption
    Header of MessageBox.
  • var int type
    Type of MessageBox. All types listed here.

MEM_InfoBox

Alias to MEM_MessageBox with "Information:" header and MB_OK | MB_ICONINFORMATION type.

func void MEM_InfoBox(var string txt)
-
Parameters
  • var string txt
    Content of the InfoBox.

Examples

Sleep

Following function calls the Sleep function from the KERNEL32.DLL. A documentation of this function can be found here.

1
-2
-3
-4
-5
-6
-7
func void Sleep(var int ms) {
-    var int adr;
-    adr = GetProcAddress(LoadLibrary("KERNEL32.DLL"), "Sleep");
-
-    CALL_IntParam(ms);
-    CALL__stdcall(adr); // 0x007B47E6
-};
-
\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/ikarus/index.html b/cs/zengin/scripts/extenders/ikarus/index.html deleted file mode 100644 index 1d84fe0d46..0000000000 --- a/cs/zengin/scripts/extenders/ikarus/index.html +++ /dev/null @@ -1,34 +0,0 @@ - Ikarus - Gothic Modding Community

Ikarus

Ikarus is a Daedalus library for Gothic. It exploits the interpreter to allow arbitrary memory access and defines tonne of useful functions for interfacing with the engine.

Contacts
Author Sektenspinner & contributors
GitHub Ikarus
Forum Ikarus

Author Note (by Sektenspinner)

This script package is not called Ikarus for nothing:

One can leave the boundaries of Daedalus behind, but may also crash and burn. For instance, reading from invalid addresses won't trigger a zSpy warning but will result in a desktop crash with an Access Violation. This is not a reason to panic but requires a tolerance for frustration (which can be useful for scripters in general).

Of course, such spectacular-looking errors can be fixed, and with focused and systematic work, something sensible can be achieved.

In short: Extra care is needed! A bug that leads to a crash is not something you want in the release version. But if you work cleanly and test extensively, it's not such a big deal.

A good friend in debugging crashes is undoubtedly PrintDebug. It allows sending messages to zSpy (for example, to narrow down where the crash is occurring). It's worth enabling debug messages by MEM_SetShowDebug and the text filter (Options -> Textfilter) in zSpy.

Note

Ikarus is hosted on GitHub and the documentation is built in. The translation is planned.

\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/ikarus/ini_access/index.html b/cs/zengin/scripts/extenders/ikarus/ini_access/index.html deleted file mode 100644 index 40bdff0db7..0000000000 --- a/cs/zengin/scripts/extenders/ikarus/ini_access/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/cs/zengin/scripts/extenders/ikarus/keyboard/index.html b/cs/zengin/scripts/extenders/ikarus/keyboard/index.html deleted file mode 100644 index 9d58a0c0c6..0000000000 --- a/cs/zengin/scripts/extenders/ikarus/keyboard/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/cs/zengin/scripts/extenders/ikarus/mem_access/index.html b/cs/zengin/scripts/extenders/ikarus/mem_access/index.html deleted file mode 100644 index f09e17255d..0000000000 --- a/cs/zengin/scripts/extenders/ikarus/mem_access/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/cs/zengin/scripts/extenders/ikarus/setup/index.html b/cs/zengin/scripts/extenders/ikarus/setup/index.html deleted file mode 100644 index ae80947f0a..0000000000 --- a/cs/zengin/scripts/extenders/ikarus/setup/index.html +++ /dev/null @@ -1,138 +0,0 @@ - Setup - Gothic Modding Community

Ikarus Setup

Download

First you need to download ikarus from the official github repository. We recommend using the master branch as it contains the latest and most up-to-date version of Ikarus. However, you can also download a specific release if needed.

File location

Before unpacking the downloaded archive it's needed to create a dedicated folder in <Gothic-dir>\_work\Data\Scripts\Content directory. You can name this folder as you wish; in this guide, we'll refer to it as the "MOD" folder. Unpack the downloaded files into this newly created folder. The archiver should create a folder named Ikarus-master or Ikarus-X.X.X. For better readability change its name to the much simpler Ikarus.

Tip

It's a good practice to delete any unused files, so delete files for other gothic version than this you are using.

Parsing

Ikarus consists of three main parts, constants, classes and the Ikarus core. It's essential to parse these in a specific order. Additionally, there is a floats package which isn't essential, but it is highly recommended to parse it, especially if you are working with LeGo that depends on it.

The Ikarus Core is identical for both Gothic 1 and 2 and is contained in a single file, Ikarus.d. However, there are separate files for the constants and classes for each engine, and they must be parsed correctly. Ikarus uses a C_NPC and therefore has to be parsed after the C_NPC class (after the classes.d file). There are no other dependencies.

Since Ikarus 1.2.1 there is additional .src file for each game engine, to simplify adding files to Gothic.src

Warning

Following example is for Gothic 2. If you are using Gothic 1 replace the G2 at the end of the file/directory name with G1.

1
-2
-3
-4
-5
-6
_INTERN\CONSTANTS.D
-_INTERN\CLASSES.D
-MOD\IKARUS\Ikarus_Const_G2.d
-MOD\IKARUS\EngineClasses_G2\*.d
-MOD\IKARUS\Ikarus.d
-MOD\IKARUS\float.d
-
1
-2
-3
_INTERN\CONSTANTS.D
-_INTERN\CLASSES.D
-MOD\IKARUS\IKARUS_G2.SRC
-

Initialization

Before you can use Ikarus in your scripts, it must be properly initialized. The initialization process differs between Gothic 1 and Gothic 2.

MEM_InitAll

This is main ikarus initialization function, however it consists of some smaller initialization functions.

func void MEM_InitAll()
-
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
func void MEM_InitAll() {
-    if (!MEMINT_ReportVersionCheck()) {
-        return;
-    };
-
-    MEM_ReinitParser(); /* depends on nothing */
-    MEM_InitLabels(); /* depends in MEM_ReinitParser */
-    MEM_InitGlobalInst(); /* depends on MEM_ReinitParser */
-
-    /* now I can use MEM_ReplaceFunc, MEM_GetFuncID */
-    MEM_GetAddress_Init(); /* depends on MEM_ReinitParser and MEM_InitLabels */
-    /* now the nicer operators are available */
-
-    MEM_InitStatArrs(); /* depends on MEM_ReinitParser and MEM_InitLabels */
-    ASMINT_Init();
-
-    MEMINT_ReplaceLoggingFunctions();
-    MEMINT_ReplaceSlowFunctions();
-    MEM_InitRepeat();
-
-    /* takes a wail the first time it is called.
-        call it to avoid delay later */
-    var int dump; dump = MEM_GetFuncIDByOffset(0);
-};
-

Gothic 1

To initialize Ikarus in Gothic 1 you must define your own INIT_GLOBAL function at the top of the Startup.d file. Then the INIT_GLOBAL should be called in every INIT_<location> function (e.g. INIT_SURFACE,INIT_OLDCAMP etc.). INIT_SUB_<location> functions can be skipped in that process.

Then in your INIT_GLOBAL function you call MEM_InitAll() initialization function.

Startup.d
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
FUNC VOID INIT_GLOBAL()
-{
-    // Init Ikarus
-    MEM_InitAll ();
-};
-
-// [...]
-
-func VOID INIT_SURFACE ()
-{
-    Init_Global();
-    INIT_SUB_SURFACE ();
-};
-// [...]
-

Gothic 2

Gothic 2 has its own INIT_GLOBAL function, so the initialization process is much simpler. All you have to do is to call MEM_InitAll() in INIT_GLOBAL function located in the Startup.d file.

Startup.d
1
-2
-3
-4
-5
-6
-7
FUNC VOID INIT_GLOBAL()
-{
-    // Init Ikarus
-    MEM_InitAll ();
-};
-
-// [...]
-
\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/index.html b/cs/zengin/scripts/extenders/index.html deleted file mode 100644 index 34f3a95b28..0000000000 --- a/cs/zengin/scripts/extenders/index.html +++ /dev/null @@ -1,34 +0,0 @@ - Daedalus extenders - Gothic Modding Community

Daedalus extenders

The default scripting language Daedalus can be quite limiting. Over the years the community created quite a few extenders to, well, extend the functionality. Before Union came along, the standard to interface with the engine was the script library Ikarus and a collection of packages LeGo built on top of that. Not so recently, an additional script packet was made (and is actively being worked on) AF Script Packet that offers even more functionality and is built on top of Ikarus & LeGo.
With the adoption of Union and plugins the Union system can use a new extender emerged called zParserExtender. Other Union plugins can, of course, implement their own external functions. A lot of scripts are also scattered on the Gothic forums, and documentation of some of them can be found in the Standalone section.

\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/lego/ai_function/index.html b/cs/zengin/scripts/extenders/lego/ai_function/index.html deleted file mode 100644 index 1963f1c536..0000000000 --- a/cs/zengin/scripts/extenders/lego/ai_function/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/cs/zengin/scripts/extenders/lego/anim8/index.html b/cs/zengin/scripts/extenders/lego/anim8/index.html deleted file mode 100644 index db533d2cdf..0000000000 --- a/cs/zengin/scripts/extenders/lego/anim8/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/cs/zengin/scripts/extenders/lego/applications/anim8/index.html b/cs/zengin/scripts/extenders/lego/applications/anim8/index.html deleted file mode 100644 index a8a1209b4b..0000000000 --- a/cs/zengin/scripts/extenders/lego/applications/anim8/index.html +++ /dev/null @@ -1,182 +0,0 @@ - Anim8 - Gothic Modding Community

Anim8

This package allows int or float values to be "animated" over a period of time. It is possible to string several commands together and to set the type of movement. The new version of PrintS from Interface uses Anim8.

Dependencies

Initialization

Initialize with LeGo_Anim8 flag.

LeGo_Init(LeGo_Anim8);
-

Implementation

Anim8.d on GitHub

Functions

Anim8_New

Creates a new Anim8 object that can be filled with commands.

func int Anim8_New(var int initialValue, var int IsFloat)
-
Parameters
  • var int initialValue
    The initial value to start animating from. Can be an integer, or an Ikarus float.
  • var int IsFloat
    If the initialValue is an Ikarus float, this parameter must be set to TRUE. If it is an integer, it must be set to FALSE.

Return value

The function returns handle of the Anim8 object.

Anim8_NewExt

Creates a new Anim8 object with advanced options. Extends the Anim8_New function.

func int Anim8_NewExt(var int value, var func handler, var int data, var int IsFloat)
-
Parameters
  • var int value
    The initial value to start animating from. Can be an integer, or an Ikarus float.
  • var func handler
    This function is called whenever the object is updated. The signature of the functions depends on the data value:
    data != 0: func void handler(var int data, var int value),
    data == 0: func void handler(var int value).
  • var int data
    Optional parameter to send an additional value to the handler function. If data == 0, it is ignored.
  • var int IsFloat
    If the initialValue is an Ikarus float, this parameter must be set to TRUE. If it is an integer, it must be set to FALSE.

Return value

The function returns handle of the Anim8 object.

Anim8_Delete

Deletes an Anim8 object created with Anim8_New.

func void Anim8_Delete(var int handle)
-
Parameters
  • var int handle
    Handle returned from Anim8_New

Anim8_Get

Get current value of the object.

func int Anim8_Get(var int handle)
-
Parameters
  • var int handle
    Handle returned from Anim8_New

Return value

The function returns value of the object.

Anim8_Set

Sets the value of the object.

func void Anim8_Set(var int handle, var int value)
-
Parameters
  • var int handle
    Handle returned from Anim8_New
  • var int value
    New value of the object

Anim8_Empty

Indicates whether the object is empty, i.e. has no more commands to process.

func int Anim8_Empty(var int handle)
-
Parameters
  • var int handle
    Handle returned from Anim8_New

Return value

The function returns TRUE if object is empty (has no more commands), FALSE is returned otherwise.

Anim8_RemoveIfEmpty

If desired, Anim8 can automatically delete an object after it is empty.

func void Anim8_RemoveIfEmpty(var int handle, var int on)
-
Parameters
  • var int handle
    Handle returned from Anim8_New
  • var int on
    TRUE: enable, FALSE: disable

Anim8_RemoveDataIfEmpty

With Anim8_NewExt handler and data can be set. If this function is called with TRUE, data is taken as a handle and delete(data) is called if the object is empty. Works only if Anim8_RemoveIfEmpty is also activated.

func void Anim8_RemoveDataIfEmpty(var int handle, var int on)
-
Parameters
  • var int handle
    Handle returned from Anim8_New
  • var int on
    TRUE: enable, FALSE: disable

Anim8

Packet core. Gives the object a new command to process.

func void Anim8(var int handle, var int target, var int span, var int interpol)
-
Parameters
  • var int handle
    Handle returned from Anim8_New
  • var int target
    Target value of this command. When the object's value has reached this value, the command is considered completed and deleted.
  • var int span
    Action duration in milliseconds
  • var int interpol
    What form of movement is used (See constants for this)

Anim8q

As already mentioned above, Anim8 can also process several commands one after the other. While Anim8 completely resets the object and deletes all commands, Anim8q just appends a new command to the list. This will be processed as soon as the previous one is completed.

func void Anim8q(var int handle, var int target, var int span, var int interpol)
-
Parameters
  • var int handle
    Handle returned from Anim8_New
  • var int target
    Target value of this command. When the object's value has reached this value, the command is considered completed and another one in the queue will start.
  • var int span
    Action duration in milliseconds
  • var int interpol
    What form of movement is used (See constants for this)

Anim8_CallOnRemove

Registers a function to be called when the object is deleted (e.g. by Anim8_RemoveIfEmpty)

func void Anim8_CallOnRemove(var int handle, var func dfnc)
-
Parameters
  • var int handle
    Handle returned from Anim8_New
  • var func dfnc
    This function is called when the object is deleted

Examples

Count up to a number

Count from 0 to 10 in 10 seconds. We use the Print_Ext function from Interface to display the text.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
func void Example1()
-{
-    // First we create a handle to a text:
-    var int MyText; MyText = Print_Ext(20, 20, "0", Font_Screen, COL_White, -1);
-
-    // After that we create a new, extended Anim8 object.
-    // It gets a handler and the handle to the text as data:
-    var int MyAnim8; MyAnim8 = Anim8_NewExt(0, MyLoop1, MyText, FALSE); 
-    // Start value 1, MyLoop1 as handler, MyText as data and no float
-
-    // Now the command to count to 10:
-    Anim8(MyAnim8, 10, 10000, A8_Constant); // With MyAnim8 to 10 within 10000ms with constant motion.
-
-    // So that the text and the Anim8 object are deleted after the process. 
-    // Now we have to do two more things:
-    Anim8_RemoveIfEmpty(MyAnim8, TRUE);
-    Anim8_RemoveDataIfEmpty(MyAnim8, TRUE);
-};
-
-func void MyLoop1(var int MyText, var int Number)
-{
-    var zCViewText t; t = _^(myText);
-
-    // Now the text is set to the value of the Anim8 object:
-    t.text = IntToString(Number);
-
-    // As I said, everything is deleted fully automatically
-};
-
A similar example can be found in the Interface examples.

Moving zCVob in loop

Now we make a vob constantly move back and forth, but without a mover. FrameFunctions are used for the loop:

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
-37
-38
-39
-40
-41
var zCVob MyVob;
-var int MyVobAni;
-
-func void Example2()
-{
-    // We use Ikarus to get a pointer to a known VOB:
-    MyVob = MEM_PtrToInst(MEM_SearchVobByName("MYVOB"));
-    // There must be a vob with the appropriate name in the world for this.
-
-    // Since the positions of a vob are floats, this time Anim8 must also use floats:
-    MyVobAni = Anim8_New(MyVob.trafoObjToWorld[3], TRUE);
-    // The X position of the vob serves as the starting value.
-    // We will also move it along this axis.
-
-    // Now start a loop that "nudges" the vob over and over again:
-    FF_Apply(MyVobLoop);
-};
-
-func void MyVobLoop()
-{
-    // We get the pointer to the VOB again
-    MyVob = MEM_PtrToInst(MEM_SearchVobByName("MYVOB"));
-
-    // Whenever there are no more commands, we add new ones:
-    if(Anim8_Empty(MyVobAni))
-    {
-        // First move by three meters:
-        Anim8(MyVobAni, addf(MyVob.trafoObjToWorld[3], mkf(300)), 1000, A8_SlowEnd);
-        // Then wait half a second:
-        Anim8q(MyVobAni, 0, 500, A8_Wait);
-        // And then back again:
-        Anim8q(MyVobAni, MyVob.trafoObjToWorld[3], 1000, A8_SlowEnd);
-        // And wait another half a second:
-        Anim8q(MyVobAni, 0, 500, A8_Wait);
-        // Note the 'q' in the follow-up commands.
-        // While Anim8 completely resets the command list, i.e. starts again, Anim8q appends the command to the queue.
-        // So you can tinker with a command sequence.
-    };
-    // Of course, we must set the "animated" value to the VOB itself
-    MyVob.trafoObjToWorld[3] = Anim8_Get(MyVobAni);
-};
-
\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/lego/applications/bars/index.html b/cs/zengin/scripts/extenders/lego/applications/bars/index.html deleted file mode 100644 index 8d182ff4a3..0000000000 --- a/cs/zengin/scripts/extenders/lego/applications/bars/index.html +++ /dev/null @@ -1,165 +0,0 @@ - Bars - Gothic Modding Community

Bars

This package makes it very easy to add new bars, for e.g. stamina.

Dependencies

Initialization

Initialize with LeGo_Bars flag.

LeGo_Init(LeGo_Bars);
-

Implementation

Bars.d on GitHub

Functions

Note

If the GothicBar prototype is selected as the initial type (GothicBar@ as the constructor), the user's own bars are visually indistinguishable from those used in Gothic.

Bar_Create

Creates a new bar from a constructor instance.

func int Bar_Create(var int inst)
-

Parameters

  • var int inst
    Constructor instance of Bar class

Return value

The function returns the address of the new bar, aka the handle.

Examples

var int bar; bar = Bar_Create(GothicBar@);

1
-2
var int bar; bar = Bar_Create(GothicBar@); // Create a new bar
-Bar_SetPercent(bar, 50);                   // And set the value to 50%
-
1
-2
-3
-4
-5
func void Example_1()
-{
-    var int bar; bar = Bar_Create(GothicBar@); // Create a new bar
-    Bar_SetPercent(bar, 50);                   // And set the value to 50%
-};
-

Bar_Delete

Deletes a bar from the screen and from memory.

func void Bar_Delete(var int bar)
-

Parameters

  • var int bar
    Handle returned from Bar_Create

Bar_SetMax

Changes a bar's maximum value but does not update its bar length (only Bar_SetPercent, Bar_SetPromille and Bar_SetValue)

func void Bar_SetMax(var int bar, var int max)
-
Parameters
  • var int bar
    Handle returned from Bar_Create

  • var int max
    New maximum value

Bar_SetValue

Sets the value of the bar.

func void Bar_SetValue(var int bar, var int val)
-
Parameters
  • var int bar
    Handle returned from Bar_Create
  • var int val
    New value of the bar

Bar_SetPercent

Sets the value of the bar but as a percentage (0..100).

func void Bar_SetPercent(var int bar, var int perc)
-
Parameters
  • var int bar
    Handle returned from Bar_Create
  • var int perc
    New value of the bar in percent

Bar_SetPromille

Sets the value of the bar but per mille (0..1000).

func void Bar_SetPromille(var int bar, var int pro)
-
Parameters
  • var int bar
    Handle returned from Bar_Create
  • var int pro
    New value of the bar in per mille

Bar_Hide

Hides a bar. It will not be deleted.

func void Bar_Hide(var int bar)
-
Parameters
  • var int bar
    Handle returned from Bar_Create

Bar_Show

Displays a bar again after using Bar_Hide.

func void Bar_Show(var int bar)
-
Parameters
  • var int bar
    Handle returned from Bar_Create

Bar_MoveTo

Move the bar to virtual position.

func void Bar_MoveTo(var int bar, var int x, var int y)
-
Parameters
  • var int bar
    Handle returned from Bar_Create
  • var int x
    New horizontal position in virtual coordinates
  • var int y
    New vertical position in virtual coordinates

Bar_MoveToPxl

Move the bar to pixel position.

func void Bar_MoveToPxl(var int bar, var int x, var int y)
-
Parameters
  • var int bar
    Handle returned from Bar_Create
  • var int x
    New horizontal position in pixels
  • var int y
    New vertical position in pixels

Bar_SetAlpha

Sets the transparency of the bar.

func void Bar_SetAlpha(var int bar, var int alpha)
-
Parameters
  • var int bar
    Handle returned from Bar_Create
  • var int alpha
    Transparency value (0..255)

Bar_SetBarTexture

Sets the foreground texture of the bar.

func void Bar_SetBarTexture(var int bar, var string barTex)
-
Parameters
  • var int bar
    Handle returned from Bar_Create
  • var string barTex
    The new foreground texture

Bar_SetBackTexture

Sets the background texture of the bar.

func void Bar_SetBackTexture(var int bar, var string backTex)
-
Parameters
  • var int bar
    Handle returned from Bar_Create
  • var string backTex
    The new background texture

Bar_Resize

Resize an existing bar.

func void Bar_Resize(var int bar, var int width, var int height)
-
Parameters
  • var int bar
    Handle returned from Bar_Create
  • var int width
    New width in virtual coordinates
  • var int height
    New height in virtual coordinates

Bar_ResizePxl

Resize existing bar (in pixels).

func void Bar_ResizePxl(var int bar, var int x, var int y)
-
Parameters
  • var int bar
    Handle returned from Bar_Create
  • var int x
    New width in pixels
  • var int y
    New height in pixels

Examples

Note

The bars assume a certain basic understanding of the PermMem module.

A dedicated experience bar

Bars implement the Bar class. It looks like this:

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
class Bar
-{
-    var int x;          // X position on the screen (middle of the bar)
-    var int y;          // Y position on the screen (middle of the bar)
-    var int barTop;     // Top/bottom margin
-    var int barLeft;    // Left/right margin
-    var int width;      // Bar width
-    var int height;     // Bar height
-    var string backTex; // Background texture
-    var string barTex;  // Actual bar texture
-    var int value;      // Current value
-    var int valueMax;   // Maximum value
-};
-
The GothicBar prototype is a bar, which mimics the standard Gothic status bar.
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
prototype GothicBar(Bar)
-{
-    x = Print_Screen[PS_X] / 2;
-    y = Print_Screen[PS_Y] - 20;
-    barTop = 3;
-    barLeft = 7;
-    width = 180;
-    height = 20;
-    backTex = "Bar_Back.tga";
-    barTex = "Bar_Misc.tga";
-    value = 100;
-    valueMax = 100;
-};
-

It is much easier to set up a new instance using this prototype. GothicBar without modifications can be found as the GothicBar@ instance, which we used to create the bar in the example above. GothicBar is located in the middle of the screen and looks exactly like the Gothic underwater bar.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
// Instance created from 
-instance Bar_1(GothicBar)
-{
-    x = 100;
-    y = 20;
-};
-
-func void Example_1()
-{
-    // Example_1 could e.g. be called in Init_Global
-    FF_ApplyOnce(Loop_1);
-};
-
-func void Loop_1()
-{
-    // Example_1 gets this loop running.
-    // Here the bar should be constructed once
-    // and then adapted to the EXP of the hero:
-    var int MyBar;
-    if(!Hlp_IsValidHandle(MyBar))
-    {
-        MyBar = Bar_Create(Bar_1); // Our Bar_1
-    };
-    // The rest is probably self-explanatory:
-    Bar_SetMax(MyBar, hero.exp_next);
-    Bar_SetValue(MyBar, hero.exp);
-};
-

Note

This is translation of article originally written by Gottfried and Lehona and hosted on LeGo's official documentation website.

\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/lego/applications/bloodsplats/index.html b/cs/zengin/scripts/extenders/lego/applications/bloodsplats/index.html deleted file mode 100644 index 2b6517e038..0000000000 --- a/cs/zengin/scripts/extenders/lego/applications/bloodsplats/index.html +++ /dev/null @@ -1,38 +0,0 @@ - Bloodsplats - Gothic Modding Community

Bloodsplats

If this package is activated, red blood splatters will appear on the screen when the hero takes damage. For this, the damage perception for the hero is redirected to _B_HeroDamage(). To use the Bloodsplats, the enclosed textures must be available. Also, the VFX "HERO_HURT" (also included) should be entered in the VfxInst.d to create an even better hit effect. All textures used here are from CGTextures.com. If you use Bloodsplats in your modification, this site must be noted in the credits.

Tip

See user constants to edit behavior of this packet.

Dependencies

Initialization

Initialize with LeGo_Bloodsplats flag.

LeGo_Init(LeGo_Bloodsplats);
-

Implementation

Bloodsplats.d on GitHub

Functions

Bloodsplat

Puts a blood splatter on the screen.

func void Bloodsplat(var int damage)
-
Parameters
  • var int damage
    The damage (affects the size of the splatter)

Bloodsplats_Rage

Pretty pointless feature that smears the entire screen.

func void Bloodsplats_Rage()
-

Npc_GetPercFunc

oCNpc::GetPerceptionFunc engine function wrapper

func int Npc_GetPercFunc(var C_Npc npc, var int type)
-
Parameters
  • var C_NPC npc
    NPC whose perception is checked
  • var int type
    Checked perception type (form Constant.d)

Return value

The function returns the state of NPCs selected perception.

\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/lego/applications/buffs/index.html b/cs/zengin/scripts/extenders/lego/applications/buffs/index.html deleted file mode 100644 index f9700da848..0000000000 --- a/cs/zengin/scripts/extenders/lego/applications/buffs/index.html +++ /dev/null @@ -1,138 +0,0 @@ - Buffs - Gothic Modding Community

Buffs

This package allows you to easily create status effects that can affect any NPC. Status effects on the hero are displayed graphically in a bar.

Dependencies

Initialization

Initialize with LeGo_Buffs flag.

LeGo_Init(LeGo_Buffs);
-

Warning

This package is still experimental and not included in the LeGo_All initialization flag.

Implementation

Buffs.d on GitHub

Functions

Buff_Apply

Applies a status effect to an NPC.

func int Buff_Apply(var C_NPC npc, var int buff)
-
Parameters
  • var C_NPC npc
    NPC to be affected by this effect

  • var int buff
    The instance of the effect to apply to the NPC

Return value

The function returns the handle of the buff, which was just generated.

Buff_ApplyUnique

Buff_Apply, but nothing happens if a status effect of that kind is already on the NPC.

func int Buff_ApplyUnique(var C_NPC npc, var int buff)
-
Parameters
  • var C_NPC npc
    NPC to be affected by this effect

  • var int buff
    The instance of the effect to apply to the NPC

Return value

The function returns the handle of the buff, which was just generated or 0 if the buff is already applied on the NPC.

Buff_ApplyOrRefresh

Buff_Apply, but if a status effect of this type is already affecting the NPC, the duration will be reset.

func int Buff_ApplyOrRefresh(var C_NPC n, var int buff)
-
Parameters
  • var C_NPC npc
    NPC to be affected by this effect

  • var int buff
    The instance of the effect to apply to the NPC

Return value

The function returns the handle of the buff, which was just generated or refreshed.

Buff_Refresh

Resets the duration of the buff.

func void Buff_Refresh(var int buffHandle)
-
Parameters
  • var int buffHandle
    Handle of the buff to refresh

Buff_Remove

Removes the buff from the all NPCs.

func void Buff_Remove(var int buffHandle)
-
Parameters
  • var int buffHandle
    Handle of the buff to remove

Buff_RemoveAll

Removes the buffs form the NPC.

func void Buff_RemoveAll(var C_NPC npc, var int buffInstance)
-
Parameters
  • var C_NPC npc
    NPC whose buff should be removed

Buff_GetNpc

Returns a pointer to the NPC, which is affected by the buff.

func int Buff_GetNpc(var int buffHandle)
-
Parameters
  • var int buffHandle
    Handle of the buff

Return value

The function returns a pointer to the NPC, which is affected by the buff.

Buff_Has

Checks if the NPC already has an effect applied.

func int Buff_Has(var C_NPC npc, var int buff)
-
Parameters
  • var C_NPC npc
    Checked NPC

  • var int buff
    The instance of the effect

Return value

The function returns TRUE if the NPC has an effect applied. FALSE is returned otherwise.

SAVE_GetFuncID

Same as MEM_GetFuncID but gets the current instance.

func int SAVE_GetFuncID(var func f)
-
Parameters

var func f
Function whose ID is got

Return value

The function returns the ID of given function.

lCBuff class

The buffs package implements an lCBuff class, which looks like this:

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
class lCBuff
-{
-    var string name;    // buff name 
-    var int buffType;   // GOOD / NEUTRAL / BAD | 1 / 0 / -1
-    var int targetID;   // NPC that is currently affected by this buff
-    var int durationMS; // buff duration in milliseconds
-    var int tickMS;     // tick duration in milliseconds, first tick occurs at tickMS milliseconds
-    var int nextTickNr; // e.g. before the first tick this will be 0; OBSOLETE, remove when possible
-
-    var int OnApply; 
-    var int OnTick;
-    var int OnRemoved;
-
-    var string buffTex;  // associated texture - currently only used for buffs applied on the hero
-    // var int originID; // Who casted/created this buff?
-
-    // Internal, no need to set during instance construction
-    var int _startedTime;
-    var int _endTime;    // Not redundant with durationMS because buffs can be refreshed
-};
-

Examples

Delayed poison

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
instance deadly_poison(lCBuff)
-{
-    name = "Deadly poison";
-    bufftype = BUFF_BAD;
-
-    durationMS = 10*1000; // 10 seconds long
-    tickMS = 1000;        // Every second
-
-    buffTex = "POISON.TGA";
-};
-

Damage should also be added:

1
-2
-3
-4
-5
-6
-7
-8
func void deadly_poison_damage(var int buffHandle)
-{
-    var int ptr; ptr = Buff_GetNpc(buffHandle);
-    if (!ptr) { return; }; // Can happen if e.g. the world was changed
-
-    var C_NPC npc; npc = _^(ptr);
-    Npc_ChangeAttribute(npc, ATR_HITPOINTS, -3); // 3 damage
-};
-
For complicated technical reasons we use the function SAVE_GetFuncID instead of MEM_GetFuncID.
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
instance deadly_poison(lCBuff)
-{
-    name = "Deadly poison";
-    bufftype = BUFF_BAD;
-
-    durationMS = 10 * 1000; //10 seconds long
-    tickMS = 1000; // Every second
-
-    onTick = SAVE_GetFuncID(deadly_poison_damage); // The damage should be applied every second
-    buffTex = "POISON.TGA";
-};
-

For example, if this buff is now applied to the hero, by calling Buff_Apply(hero, deadly_poison), he loses a total of 30 HP over 10 seconds.

\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/lego/applications/buttons/index.html b/cs/zengin/scripts/extenders/lego/applications/buttons/index.html deleted file mode 100644 index 2dc2bb1164..0000000000 --- a/cs/zengin/scripts/extenders/lego/applications/buttons/index.html +++ /dev/null @@ -1,57 +0,0 @@ - Buttons - Gothic Modding Community

Buttons

This package extends the handling of the mouse and allows creating rectangular buttons, which react to mouse (hover) entry and exit as well as a mouse click.

Dependencies

Initialization

Initialize with LeGo_Buttons flag.

LeGo_Init(LeGo_Buttons);
-

Implementation

Buffs.d on GitHub

Functions

Button_Create

Creates a button. It is initially hidden (not visible and does not react to the mouse). The three callback functions have the following signature void f(int handle).

func int Button_Create(var int posx, var int posy, var int width, var int height, var string tex, var func on_enter, var func on_leave, var func on_click)
-
Parameters
  • var int posx
    The horizontal position of the button in virtual coordinates
  • var int posy
    The vertical position of the button in virtual coordinates
  • var int width
    Width of the button in virtual coordinates
  • var int height
    Height of the button in virtual coordinates
  • var string tex
    Name of the button texture
  • var func on_enter
    This function is called when the mouse enters the button
  • var func on_leave
    This function is called when the mouse leaves the button
  • var func on_click
    This function is called when the user performs a mouse click on the button (left mouse button)

Return value

The function returns a handle to created button.

Button_CreatePxl

Button_Create with pixels instead of virtual coordinates.

func int Button_CreatePxl(var int posx, var int posy, var int width, var int height, var string tex, var func on_enter, var func on_leave, var func on_click)
-
Parameters
  • var int posx
    The horizontal position of the button in pixels
  • var int posy
    The vertical position of the button in pixels
  • var int width
    Width of the button in pixels
  • var int height
    Height of the button in pixels
  • var string tex
    Name of the button texture
  • var func on_enter
    This function is called when the mouse enters the button
  • var func on_leave
    This function is called when the mouse leaves the button
  • var func on_click
    This function is called when the user performs a mouse click on the button (left mouse button)

Return value

The function returns a handle to created button.

Button_Delete

Completely deletes a button.

func void Button_Delete(var int hndl)
-
Parameters
  • var int hndl
    Handle returned from Button_Create

Button_Show

Shows the button and makes it respond to the mouse.

func void Button_Show(var int hndl)
-
Parameters
  • var int hndl
    Handle returned from Button_Create

Button_Hide

Hides the button and disables it, so it is no longer responding to the mouse.

func void Button_Hide(var int hndl)
-
Parameters
  • var int hndl
    Handle returned from Button_Create

Button_SetTexture

Sets the texture of the button.

func void Button_SetTexture(var int hndl, var string tex)
-
Parameters
  • var int hndl
    Handle returned from Button_Create
  • var string tex
    Name of the new texture

Button_SetCaption

Displays a centered text on the button.

func void Button_SetCaption(var int hndl, var string caption, var string font)
-
Parameters
  • var int hndl
    Handle returned from Button_Create
  • var string caption
    The text to be displayed
  • var string font
    The font in which the text should be displayed

Button_CreateMouseover

Attaches a mouseover box to the cursor.

func void Button_CreateMouseover(var string text, var string font)
-
Parameters
  • var string text
    The text in the mouseover box
  • var string font
    The font of the text

Button_DeleteMouseover

Deletes the mouseover box.

func void Button_DeleteMouseover()
-

Button_Activate

Activates the button, so it reacts to the mouse. Does not change the visibility.

func void Button_Activate(var int hndl)
-
Parameters
  • var int hndl
    Handle returned from Button_Create

Button_Deactivate

Disables the button, so it no longer reacts to the mouse.

func void Button_Deactivate(var int hndl)
-
Parameters
  • var int hndl
    Handle returned from Button_Create

Button_SetUserData

Sets the user data of the button, an integer, to give the button individual information.

func void Button_SetUserData(var int hndl, var int data)
-
Parameters
  • var int hndl
    Handle returned from Button_Create
  • var int data
    Individual integer of the button (part of the internal _Button class)

Button_GetUserData

Gets the user data of the button.

func int Button_GetUserData(var int hndl)
-
Parameters
  • var int hndl
    Handle returned from Button_Create

Return value

The function returns the user data of the button.

Button_GetState

Gets the status of the button as a bit field. See User Constants.

func int Button_GetState(var int hndl)
-
Parameters
  • var int hndl
    Handle returned from Button_Create

Return value

The function returns the status of the button.

Button_Move

Moves the button by the given value in pixels. posx = posx + nposx

func void Button_Move(var int hndl, var int nposx, var int nposy)
-
Parameters
  • var int hndl
    Handle returned from Button_Create
  • var int nposx
    X-axis shift in pixels
  • var int nposy
    Y-axis shift in pixels

Button_MoveVrt

Moves the button by the given value in virtual coordinates. posx = posx + nposx

func void Button_Move(var int hndl, var int nposx, var int nposy)
-
Parameters
  • var int hndl
    Handle returned from Button_Create
  • var int nposx
    X-axis shift in virtual coordinates
  • var int nposy
    Y-axis shift in virtual coordinates

Button_MoveTo

Moves a button to the given position in pixels. posx = nposx

func void Button_MoveVrt(var int hndl, var int nposx, var int nposy)
-
Parameters
  • var int hndl
    Handle returned from Button_Create
  • var int nposx
    New horizontal position in pixels
  • var int nposy
    New vertical position in pixels

Button_MoveToVrt

Moves a button to the given position in virtual coordinates. posx = nvposx

func void Button_MoveVrt(var int hndl, var int nvposx, var int nvposy)
-
Parameters
  • var int hndl
    Handle returned from Button_Create
  • var int nvposx
    New horizontal position in virtual coordinates
  • var int nvposy
    New vertical position in virtual coordinates

Button_GetViewHandle

Returns the button's zCView as a handle.

func int Button_GetViewHandle(var int hndl)
-
Parameters
  • var int hndl
    Handle returned from Button_Create

Return value

The function returns the button's zCView as a handle.

Button_GetViewPtr

Returns the button's zCView as a pointer.

func int Button_GetViewPtr(var int hndl)
-
Parameters
  • var int hndl
    Handle returned from Button_Create

Return value

The function returns the button's zCView as a pointer.

Button_GetView

Returns the button's zCView as an object.

func zCView Button_GetView(var int hndl)
-
Parameters
  • var int hndl
    Handle returned from Button_Create

Return value

The function returns the button's zCView as an object.

Button_GetCaptionPtr

Returns the pointer to the text of the button.

func int Button_GetCaptionPtr(var int hndl)
-
Parameters
  • var int hndl
    Handle returned from Button_Create

Return value

The function returns the pointer to the text of the button.

\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/lego/applications/console_commands/index.html b/cs/zengin/scripts/extenders/lego/applications/console_commands/index.html deleted file mode 100644 index e4a4dbde84..0000000000 --- a/cs/zengin/scripts/extenders/lego/applications/console_commands/index.html +++ /dev/null @@ -1,86 +0,0 @@ - Console Commands - Gothic Modding Community

Console Commands

This package allows you to create new console commands.

Dependencies

Initialization

Initialize with LeGo_ConsoleCommands flag.

LeGo_Init(LeGo_ConsoleCommands);
-

Implementation

ConsoleCommands.d on GitHub

Functions

CC_Register

Registers a new console command.

func void CC_Register(var func f, var string cmdPrefix, var string description)
-
Parameters
  • var func f
    This function is executed when the cmdPrefix command is entered in the console. The function signature is func string f(var string p0). The string passed is everything that was specified in the console after the actual command. The return value is then displayed in the console.
  • var string cmdPrefix
    This is a command, which can be entered in the console.
  • var string description
    This text appears next to the command (in zSpy) when you use the help command in the console.

CC_Remove

Removes a function from the console commands.

func void CC_Remove(var func f)
-
Parameters
  • var func f
    This function will be removed, i.e. the associated command will no longer work.

CC_Active

Checks whether the function passed is already part of a console command.

func int CC_Active(var func f)
-
Parameters
  • var func f
    Function being checked

Return value

The function returns TRUE if there is a corresponding function, FALSE is returned otherwise.

Examples

Basic command example

As a basic example - let us create a version command, which prints a version of our modification.
Firstly, we declare a constant string variable to hold the version string to be shown.

const string Mod_Version = "My mod version 0.1alpha";
-
Next we create the command function.

Note

Notice the correct function signature. If you do not adhere to the correct function signature, the command will crash the game.

1
-2
-3
-4
-5
// This function is called by our console
-func string CC_ModVersion(var string param)
-{
-    return Mod_Version;
-};
-
We then have to register the functions. For convenience, I created a new RegisterConsoleFunctions function to initialize all console commands. The function is really simple.
1
-2
-3
-4
func void RegisterConsoleFunctions()
-{
-    CC_Register (CC_ModVersion, "version", "Version of my amazing mod.");
-};
-
Lastly, we have to call this function from INIT_GLOBAL function.
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
func void INIT_GLOBAL()
-{
-    // will be called for every world (from INIT_<LevelName>)
-    Game_InitGerman();
-
-    // Ikarus initialization
-    MEM_InitAll();
-
-    // LeGo initialization
-    LeGo_Init(LeGo_ConsoleCommands);
-
-    // Here we register all of our commands
-    RegisterConsoleFunctions();
-
-    // the rest of the code 
-};
-
\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/lego/applications/cursor/index.html b/cs/zengin/scripts/extenders/lego/applications/cursor/index.html deleted file mode 100644 index a1e3dc2409..0000000000 --- a/cs/zengin/scripts/extenders/lego/applications/cursor/index.html +++ /dev/null @@ -1,182 +0,0 @@ - Cursor - Gothic Modding Community

Cursor

This package implements Gothic in-game mouse cursor support. To visually display the cursor there is a Cursor.tga file in the resources, but the texture can be changed in user constants.

Warning

The cursor only works if the mouse is activated in the Gothic settings. It can be done directly from the scripts. See the Ini file access.

Dependencies

Initialization

Initialize with LeGo_Cursor flag.

LeGo_Init(LeGo_Cursor);
-

Implementation

Cursor.d on GitHub

Variables

  • var int Cursor_X
    Always contains the X coordinate of the mouse cursor.
  • var int Cursor_Y
    Always contains the Y coordinate of the mouse cursor.
  • var float Cursor_RelX
    Always contains the relative X coordinate of the mouse cursor as an Ikarus float.
  • var float Cursor_RelY
    Always contains the relative Y coordinate of the mouse cursor as an Ikarus float.
  • var int Cursor_Wheel
    Variable containing the value of the mouse wheel.
  • var int Cursor_Left
    Variable that always contains the KeyState of the left mouse button.
  • var int Cursor_Mid
    Variable that always contains the KeyState of the middle mouse button.
  • var int Cursor_Right
    Variable that always contains the KeyState of the right mouse button.
  • var int Cursor_Event
    An event handler that can send information about the mouse cursor. It can be used with all functions of the EventHandler package.
  • var int Cursor_NoEngine
    Variable that can prevent the engine from working. If is set to TRUE the engine no longer reacts to mouse movements.

Functions

Cursor_Hide

Hides the displayed mouse cursor.

func void Cursor_Hide()
-

Cursor_Show

Shows the mouse cursor.

func void Cursor_Show()
-

SetMouseEnabled

Can manually enable or disable the mouse.

func void SetMouseEnabled(var int enabled)
-
Parameters
  • var int enabled
    TRUE - Mouse activated

Examples

Click a button

We use a View to display a button to be clicked. The FrameFunctions take care of the loop to check whether a click was made.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
-37
-38
-39
-40
var int Button;
-func void Example1()
-{
-    // We show the cursor and at the same time a button to be clicked:
-    Cursor_Show();
-
-    // New View:
-    Button = View_CreatePxl(5, 5, 125, 50);
-    View_SetTexture(Button, "BUTTONTEX.TGA");
-    View_Open(Button);
-
-    // Optionally, mouse can be switched off for the engine:
-    Cursor_NoEngine = true; // -> The engine then no longer reacts to movements, so the camera does not move either
-
-    // Enable loop function:
-    FF_ApplyOnce(Button_Click);
-};
-
-func void Button_Click()
-{
-    if(Cursor_Left != KEY_PRESSED) { return; }; // Exit the function if the left mouse button was not pressed
-
-    if(Cursor_X >= 5 && Cursor_X <= 125
-    && Cursor_Y >= 5 && Cursor_Y <= 50) // Simply take over the coordinates of the view
-    { 
-        // Here the button was clicked.
-        // Remove button and end loop:
-        View_Close(Button);
-        View_Delete(Button);
-        Button = 0;
-
-        // Allow the engine to continue working:
-        Cursor_NoEngine = false;
-
-        FF_Remove(Button_Click);
-
-        // Hide the mouse:
-        Cursor_Hide();
-    };
-};
-

This also can be done by the Buttons package instead of View.

Event handler

Since LeGo 2.2 there is also an event handler (var int Cursor_Event) in the cursor package. This example briefly explains how it works:

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
func void Example2()
-{
-    // We register MyCursorListener as the handler/listener of the Cursor_Event:
-    Event_Add(Cursor_Event, MyCursorListener);
-
-    // From now on, MyCursorListener will be called whenever the cursor has something to report.
-};
-
-func void MyCursorListener(var int state)
-{
-    // The rest is self-explanatory:
-
-    if(state == CUR_WheelUp)
-    {
-        PrintS("Wheel up!");
-    };
-    if(state == CUR_WheelDown)
-    {
-        PrintS("Wheel down!");
-    };
-    if(state == CUR_LeftClick)
-    {
-        PrintS("Leftclick!");
-    };
-    if(state == CUR_RightClick)
-    {
-        PrintS("Rightclick!");
-    };
-    if(state == CUR_MidClick)
-    {
-        PrintS("Wheelclick!");
-    };
-};
-
Constants used in the example can be found in the user constants.
\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/lego/applications/dialoggestures/index.html b/cs/zengin/scripts/extenders/lego/applications/dialoggestures/index.html deleted file mode 100644 index 169c6e4277..0000000000 --- a/cs/zengin/scripts/extenders/lego/applications/dialoggestures/index.html +++ /dev/null @@ -1,39 +0,0 @@ - Dialoggestures - Gothic Modding Community

Dialoggestures

This package can modify the NPCs' gestures during dialogue to better bring out emotions.

Dependencies

Initialization

N/A

Implementation

Dialoggestures.d on GitHub

Functions

DIAG

With this function the dialog gestures for all NPCs can be overridden. To understand the principle, it is recommended to take a look at the examples.

The full name of the animation can be described as follows:

DIAG_Prefix + aniName + DIAG_Suffix + ((rand() % (max - (min - 1))) + min).ToString("00");
-
DIAG_Prefix and DIAG_Suffix are user constants.

func void DIAG(var string AniName, var int Min, var int Max)
-
Parameters
  • var string AniName
    The new dialogue gesture
  • var int Min
    Lowest animation number
  • var int Max
    Highest animation number

DIAG_Reset

Resets the dialog gestures to the default.

func void DIAG_Reset()
-

DIAG_SetAni

Sets animation directly.

func void DIAG_SetAni(var string AniName)
-
Parameters
  • var string AniName
    Animation name

DIAG_SetMinMax

Sets animation numbers directly.

func void DIAG_SetMinMax(var int min, var int max)
-
Parameters
  • var int min
    Lowest animation number
  • var int max
    Highest animation number

Examples

Note

See Examples in the Trialoge article.

\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/lego/applications/focusnames/index.html b/cs/zengin/scripts/extenders/lego/applications/focusnames/index.html deleted file mode 100644 index 0bccc16597..0000000000 --- a/cs/zengin/scripts/extenders/lego/applications/focusnames/index.html +++ /dev/null @@ -1,63 +0,0 @@ - Focusnames - Gothic Modding Community

Focusnames

This package colors the focus names of the NPCs in appropriate colors according to the behavior defined below (alpha values are taken into account). Also affects monsters. (Mobs/Items get Color_Neutral)

Dependencies

Initialization

Initialize with LeGo_Focusnames flag.

LeGo_Init(LeGo_Focusnames);
-

Implementation

Focusnames.d on GitHub

Usage

If you want to change colors for any behavior edit the following functions directly in Focusnames.d file.

Focusnames_Color_Friendly

1
-2
-3
-4
func int Focusnames_Color_Friendly()
-{
-    return RGBA(0, 255, 0, 255); // Green
-};
-

Focusnames_Color_Neutral

1
-2
-3
-4
func int Focusnames_Color_Neutral()
-{
-    return RGBA(255, 255, 255, 255); // White
-};
-

Focusnames_Color_Angry

1
-2
-3
-4
func int Focusnames_Color_Angry()
-{
-    return RGBA(255, 180, 0, 255); // Orange
-};
-

Focusnames_Color_Hostile

1
-2
-3
-4
func int Focusnames_Color_Hostile()
-{
-    return RGBA(255, 0, 0, 255); // Red
-};
-
\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/lego/applications/gamestate/index.html b/cs/zengin/scripts/extenders/lego/applications/gamestate/index.html deleted file mode 100644 index d36c3954eb..0000000000 --- a/cs/zengin/scripts/extenders/lego/applications/gamestate/index.html +++ /dev/null @@ -1,177 +0,0 @@ - Gamestate - Gothic Modding Community

Gamestate

Gamestate package allows to check for different game states (game start, game load or level change).

Dependencies

Initialization

Initialize with LeGo_Gamestate flag.

LeGo_Init(LeGo_Gamestate);
-

Implementation

Gamestate.d on GitHub

Functions

Gamestate_AddListener

Adds a listener/handler to the game-state event.

func void Gamestate_AddListener(var func listener)
-
Parameters
  • var func listener
    This function will be called on a game-state change. The current game-state is passed as a parameter.

Gamestate_RemoveListener

Removes game-state listener.

func void Gamestate_RemoveListener(var func listener)
-
Parameters
  • var func listener
    Listener function to be removed.

Examples

There are now two possibilities. Everything can be done directly into the Init_Global, or with EventHandler.

Init_Global

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
func void Init_Global()
-{
-    // [...]
-
-    LeGo_Init(LeGo_All);
-
-    if(Gamestate == Gamestate_NewGame) 
-    {
-        MEM_Info("New game started.");
-    }
-    else if(Gamestate == Gamestate_Loaded)
-    {
-        MEM_Info("Game loaded.");
-    }
-    else if(Gamestate == Gamestate_WorldChange)
-    {
-        MEM_Info("Worldshift.");
-    }
-    else
-    {
-        MEM_Info("I don't pass.");
-    };
-};
-

It can also be done like that:

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
func void Init_Global()
-{
-    // [...]
-
-    LeGo_Init(LeGo_All);
-
-    if(Gamestate == Gamestate_NewGame)
-    {
-        FF_Apply(MyLoop);
-        FF_Apply(My2ndLoop);
-    };
-};
-
This would have the same effect as:
1
-2
-3
-4
-5
-6
-7
-8
-9
func void Init_Global()
-{
-    // [...]
-
-    LeGo_Init(LeGo_All);
-
-    FF_ApplyOnce(MyLoop);
-    FF_ApplyOnce(My2ndLoop);
-};
-

EventHandler

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
func void Init_Global()
-{
-    // [...]
-
-    LeGo_Init(LeGo_All);
-
-    Gamestate_AddListener(MyGamestateListener);
-};
-
-func void MyGamestateListener(var int state)
-{
-    if(state == Gamestate_NewGame)
-    {
-        MEM_Info("New game started.");
-    }
-    else if(state == Gamestate_Loaded)
-    {
-        MEM_Info("Game loaded.");
-    }
-    else if(state == Gamestate_WorldChange)
-    {
-        MEM_Info("Worldshift.");
-    }
-    else
-    {
-        MEM_Info("I don't pass.");
-    };
-};
-
This is the same as the Init_Global example, but it may look more elegant to some.

Note

This is translation of article originally written by Gottfried and Lehona and hosted on LeGo's official documentation website.

\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/lego/applications/names/index.html b/cs/zengin/scripts/extenders/lego/applications/names/index.html deleted file mode 100644 index 06262c85fa..0000000000 --- a/cs/zengin/scripts/extenders/lego/applications/names/index.html +++ /dev/null @@ -1,57 +0,0 @@ - Names - Gothic Modding Community

Names

Allows the user to change NPC name e.g. after he shows up.

Dependencies

Initialization

N/A

Implementation

Names.d on GitHub

Functions

SetName

Should be set in InitGlobal().

func void SetName(var C_NPC npc, var string name)
-
Parameters
  • var C_NPC npc
    The NPC to be named
  • var string name
    The name of the NPC

ShowName

Permanently displays the name set by SetName function above the npc.

func void ShowName(var C_NPC npc)
-
Parameters
  • var C_NPC npc
    The NPC whose name should be shown

Examples

Show the name of an NPC later

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
instance PAL_100_Friend(C_NPC)
-{
-    name = "Paladin";
-
-    // [...]
-};
-
-func void Init_Global()
-{
-    SetName(PAL_100_Friend, "Arto");
-};
-
At the start of the game, the name "Paladin" is displayed above PAL_100_Friend.

If ShowName(PAL_100_Friend); is used during a dialogue, the name "Arto" is permanently visible above the npc.

\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/lego/applications/render/index.html b/cs/zengin/scripts/extenders/lego/applications/render/index.html deleted file mode 100644 index e27fe7437a..0000000000 --- a/cs/zengin/scripts/extenders/lego/applications/render/index.html +++ /dev/null @@ -1,42 +0,0 @@ - Render - Gothic Modding Community

Render

With this package items can be rendered on the screen. Since items are rendered independently of the normal views, textures that are 'below' the items must also be managed by this package, this behaviour is managed by the priority system. The view with the highest priority is always rendered first, so it is at the bottom. In theory, any .3DS model can be rendered if you just create a suitable item script.

Dependencies

Initialization

Initialize with LeGo_Render flag.

LeGo_Init(LeGo_Render);
-

Warning

This package is still experimental and not included in LeGo_All initialization flag.

Implementation

Render.d on GitHub

Functions

Render_AddItemPrio

Generates the render of an item, with a manually specified priority.

func int Render_AddItemPrio(var int itemInst, var int x1, var int y1, var int x2, var int y2, var int priority)
-
Parameters
  • var int itemInst
    The instance of the item to render
  • var int x1 var int y1
    The top left coordinate of the view
  • var int x2 var int y2
    The bottom right coordinate of the view
  • var int priority
    The priority of this render object

Return value

The function returns a handle of the render object.

Render_AddItem

Generates the render of an item, with priority set to 0.

func int Render_AddItem(var int itemInst, var int x1, var int y1, var int x2, var int y2)
-
Parameters
  • var int itemInst
    The instance of the item to render
  • var int x1 var int y1
    The top left coordinate of the view
  • var int x2 var int y2
    The bottom right coordinate of the view

Return value

The function returns a handle of the render object.

Render_AddViewPrio

Generates the render of a View, with a manually specified priority.

func int Render_AddViewPrio(var int view, var int priority)
-
Parameters
  • var int view
    A handle to a View
  • var int priority
    The priority of this render object

Return value

The function returns a handle of the render object.

Render_AddView

Generates the render of a View, with priority set to 0.

func int Render_AddView(var int view)
-
Parameters
  • var int view
    A handle to a View

Return value

The function returns a handle of the render object.

Render_OpenView

Opens a render object. Only open render objects are displayed.

func void Render_OpenView(var int handle)
-
Parameters
  • var int handle
    Handle of a render object

Render_CloseView

Closes a render object. Only open render objects are displayed.

func void Render_CloseView(var int handle)
-
Parameters
  • var int handle
    Handle of a render object

Render_Remove

Deletes a render object. The associated view is deleted automatically.

func void Render_Remove(var int handle)
-
Parameters
  • var int handle
    Handle of a render object
\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/lego/applications/saves/index.html b/cs/zengin/scripts/extenders/lego/applications/saves/index.html deleted file mode 100644 index 88d2773c9d..0000000000 --- a/cs/zengin/scripts/extenders/lego/applications/saves/index.html +++ /dev/null @@ -1,95 +0,0 @@ - Saves - Gothic Modding Community

Saves

Offers an open file stream that can read/write variables on save/load. It is used by PermMem, so you don't need to address it manually anymore.

Dependencies

Initialization

Initialize with LeGo_Saves flag.

LeGo_Init(LeGo_Saves);
-

Implementation

Saves.d on GitHub

Functions

BW_Savegame

Custom function. It creates a stream to its own memory file, this can be filled with the BW_* functions from the BinaryMachines.

func void BW_Savegame()
-

BR_Savegame

Custom function. It opens a stream to a previously saved memory file, which can be read from the BinaryMachines using the BR_* functions.

func void BR_Savegame()
-

Examples

Save a high score list

var string MyScoreList[10];
-

Since strings are not saved by the game by default, we use the functions from Saves.d to create an additional memory file that only belongs to us. At the top the Saves.d file has two functions: BW_Savegame and BR_Savegame. BinaryMachines functions are used to save or read the file, we don't need to do anything else than to use them here, the rest is done by Saves.d completely by itself. Therefore, we only modify these two functions.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
func void BW_Savegame() 
-{
-    // Save high score list
-    BW_String(MyScoreList[0]);
-    BW_String(MyScoreList[1]);
-    BW_String(MyScoreList[2]);
-    BW_String(MyScoreList[3]);
-    BW_String(MyScoreList[4]);
-    BW_String(MyScoreList[5]);
-    BW_String(MyScoreList[6]);
-    BW_String(MyScoreList[7]);
-    BW_String(MyScoreList[8]);
-    BW_String(MyScoreList[9]);
-};
-
-func void BR_Savegame() 
-{
-    // Load high score list
-    MyScoreList[0] = BR_String();
-    MyScoreList[1] = BR_String();
-    MyScoreList[2] = BR_String();
-    MyScoreList[3] = BR_String();
-    MyScoreList[4] = BR_String();
-    MyScoreList[5] = BR_String();
-    MyScoreList[6] = BR_String();
-    MyScoreList[7] = BR_String();
-    MyScoreList[8] = BR_String();
-    MyScoreList[9] = BR_String();
-};
-

Tip

Since LeGo 2.0, such things can be implemented much more elegantly with PermMem.

\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/lego/applications/trialoge/index.html b/cs/zengin/scripts/extenders/lego/applications/trialoge/index.html deleted file mode 100644 index 1c3db76119..0000000000 --- a/cs/zengin/scripts/extenders/lego/applications/trialoge/index.html +++ /dev/null @@ -1,225 +0,0 @@ - Trialoge - Gothic Modding Community

Trialoge

This package allows you to create conversations with any number of NPCs and control the camera during the dialog.

Dependencies

Initialization

Initialize with LeGo_Trialoge flag.

LeGo_Init(LeGo_Trialoge);
-

Implementation

Trialoge.d on GitHub

Functions

EquipWeapon

Sektenspinner's function. Makes NPC equip a weapon.

func void EquipWeapon(var C_NPC slf, var int ItemInstance)
-
Parameters
  • var C_NPC slf
    NPC to have a weapon equipped
  • var int ItemInstance
    Weapon instance ID to be equipped

Configuration

const int EquipWeapon_TogglesEquip = 1

Above constant configures the behaviour of the function when trying to equip an already equipped weapon:

  • 0 - EquipWeapon will do nothing
  • 1 - EquipWeapon will unequip this weapon

Npc_GetArmor

Returns NPC's equipped armor.

func int Npc_GetArmor(var C_NPC slf)
-
Parameters
  • var C_NPC slf
    NPC to get the armor from

Return value

The function returns instance of armor worn by the NPC.

Npc_GetMeleeWeapon

Returns NPC's equipped melee weapon.

func int Npc_GetMeleeWeapon(var C_NPC slf)
-
Parameters
  • var C_NPC slf
    NPC to get the weapon from

Return value

The function returns instance ID of melee weapon equipped by the NPC.

Npc_GetRangedWeapon

Returns NPC's equipped ranged weapon.

func int Npc_GetRangedWeapon(var c_npc slf)
-
Parameters
  • var C_NPC slf
    NPC to get the weapon from

Return value

The function returns instance ID of ranged weapon equipped by the NPC.

Npc_TradeItem

Swaps NPCs equipped weapon.

func void Npc_TradeItem(var c_npc slf, var int itm0, var int itm1) 
-
Parameters
  • var C_NPC slf
    NPC to perform operation on
  • var int itm0
    instance ID of item to remove
  • var int itm1
    instance ID of item to create and equip

DiaCAM_Update

Sektenspinner's function that updates the dialogue camera. (Used internally.)

func void DiaCAM_Update()
-

DiaCAM_Disable

Completely disable the dialogue cameras.

func void DiaCAM_Disable()
-

DiaCAM_Enable

Resets the dialogue cameras to the default settings.

func void DiaCAM_Enable()
-

TRIA_Wait

Makes self and other wait for each other, e.g. for AI_GotoWP actions for synchronization.

func void TRIA_Wait()
-

TRIA_Invite

Invites an NPC into a conversation. Must be called before TRIA_Start.

func void TRIA_Invite(var C_NPC slf)
-
Parameters
  • var C_NPC slf
    The invited NPC

TRIA_Start

Starts trialogues. Before that, all NPCs should be invited by TRIA_Invite.

func void TRIA_Start()
-

TRIA_Barrier

Similar to TRIA_Wait but applies to all participating NPCs.

func void TRIA_Barrier()
-

TRIA_Next

Sets the called npc to self.

func void TRIA_Next(var C_NPC n0)
-
Parameters
  • var C_NPC n0
    NPC to set to self

TRIA_Cam

Starts a tracking shot.

func void TRIA_Cam(var string evt)
-
Parameters
  • var string evt
    The name of the tracking shot in Spacer. If "" is passed, the running trace shot will be aborted.

TRIA_Finish

Ends an ongoing trialogue. Must always be called at the end, otherwise no further trialogues can be started.

func void TRIA_Finish()
-

Examples

A Simple Trialogue

The following conversation is resolved via the trialogues:

  1. Arto: I'm sorry Hero, but you can't pass here.
  2. Hero: Why not?
  3. Horka: The city has been closed.
  4. Hero: I have some gold with me, can we trade?
  5. Squelto: No. We are not open to bribery.
  6. Hero: Sure?
  7. Arto: I have to ask you to leave now.
  8. Hero: Well...
     1
    - 2
    - 3
    - 4
    - 5
    - 6
    - 7
    - 8
    - 9
    -10
    -11
    -12
    -13
    -14
    -15
    -16
    -17
    -18
    -19
    -20
    -21
    -22
    -23
    -24
    -25
    -26
    -27
    -28
    -29
    -30
    -31
    -32
    -33
    -34
    -35
    -36
    -37
    -38
    -39
    -40
    -41
    -42
    -43
    -44
    -45
    -46
    -47
    -48
    -49
    -50
    -51
    -52
    -53
    -54
    -55
    -56
    -57
    -58
    -59
    -60
    -61
    -62
    -63
    -64
    -65
    -66
    -67
    -68
    -69
    -70
    -71
    -72
    -73
    -74
    -75
    -76
    -77
    -78
    -79
    -80
    -81
    -82
    -83
    -84
    -85
    -86
    -87
    -88
    instance TRIA_Test (C_INFO)
    -{
    -    npc         = PAL_100_Friend;
    -    nr          = 10;
    -    condition   = TRIA_Test_condition;
    -    information = TRIA_Test_info;
    -    important   = FALSE;
    -    permanent   = 1;
    -    description = "TRIALOGTEST";
    -};
    -
    -func int TRIA_Test_condition()
    -{
    -    return TRUE;
    -};
    -
    -func void TRIA_Test_info()
    -{
    -    var C_NPC Arto; Arto       = Hlp_GetNpc(PAL_100_Friend); // He is the owner of dialogue
    -    var C_NPC Horka; Horka     = Hlp_GetNpc(PAL_101_Horka);
    -    var C_NPC Squelto; Squelto = Hlp_GetNpc(PAL_102_Squelto);
    -
    -    TRIA_Invite(Horka);   // Invite Horka into this dialogue
    -    TRIA_Invite(Squelto); // Invite Squelto into this dialog
    -    TRIA_Start();         // Start the conversation
    -    // The hero and Arto do not have to/may not be invited. They are in dialogue anyway.
    -
    -    // Hero now talks to Arto (self = Arto, other = Hero)
    -    TRIA_Next(Arto);
    -
    -    DIAG_Reset();
    -
    -    AI_Output (self, other, "TRIA_TEST_00"); //Sorry hero, but you can't pass here.
    -
    -    // Hero now talks to Horka (self = Horka, other = Hero)
    -    TRIA_Next(Horka);
    -
    -    AI_Output (other, self, "TRIA_TEST_01"); //Why not?
    -
    -    AI_GotoNpc(self, other);
    -    AI_TurnToNpc(other, self);
    -
    -    AI_Output (self, other, "TRIA_TEST_02"); //The city has been closed.
    -
    -    // Hero looks around conspiratorially during the next sentence
    -    DIAG("Nervous", 1, 2);
    -
    -    AI_Output (other, self, "TRIA_TEST_03"); //I have some gold with me, can we trade?
    -
    -    // Hero should now move normally again
    -    DIAG_Reset();
    -
    -    // Start tracking shot
    -    TRIA_Cam("CAMERASTART");
    -
    -    // Hero now talks to Squelto (self = Squelto, other = Hero)
    -    TRIA_Next(Squelto);
    -
    -    AI_TurnToNpc(other, self);
    -
    -    DIAG("No", 0, 1);
    -    AI_Output (self, other, "TRIA_TEST_04"); //No. We are not open to bribery.
    -
    -    // Hero talks to Arto again (self = Arto, other = Hero)
    -    TRIA_Next(Arto);
    -
    -    // Hero should now articulate questioningly
    -    DIAG("NotSure", 0, 1);
    -
    -    AI_Output (other, self, "TRIA_TEST_05"); //Sure?
    -
    -    AI_TurnToNpc(other, self);
    -
    -    // tracking shot end
    -    TRIA_Cam("");
    -
    -    // Arto should react angrily
    -    DIAG("Angry", 0, 4);
    -
    -    AI_Output (self, other, "TRIA_TEST_06"); //I have to ask you to leave now
    -
    -    // Hero should now move normally again
    -    DIAG_Reset();
    -
    -    AI_Output (other, self, "TRIA_TEST_07"); //Well...
    -
    -    TRIA_Finish(); // End
    -};
    -

Note

In addition, here are still Dialoggestures used.

\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/lego/bars/index.html b/cs/zengin/scripts/extenders/lego/bars/index.html deleted file mode 100644 index d9593db1bf..0000000000 --- a/cs/zengin/scripts/extenders/lego/bars/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/cs/zengin/scripts/extenders/lego/bloodsplats/index.html b/cs/zengin/scripts/extenders/lego/bloodsplats/index.html deleted file mode 100644 index 07805ad05a..0000000000 --- a/cs/zengin/scripts/extenders/lego/bloodsplats/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/cs/zengin/scripts/extenders/lego/console_commands/index.html b/cs/zengin/scripts/extenders/lego/console_commands/index.html deleted file mode 100644 index 1dec884d9e..0000000000 --- a/cs/zengin/scripts/extenders/lego/console_commands/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/cs/zengin/scripts/extenders/lego/dialoggestures/index.html b/cs/zengin/scripts/extenders/lego/dialoggestures/index.html deleted file mode 100644 index f446c3350b..0000000000 --- a/cs/zengin/scripts/extenders/lego/dialoggestures/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/cs/zengin/scripts/extenders/lego/focusnames/index.html b/cs/zengin/scripts/extenders/lego/focusnames/index.html deleted file mode 100644 index 565bdc88c9..0000000000 --- a/cs/zengin/scripts/extenders/lego/focusnames/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/cs/zengin/scripts/extenders/lego/frame_functions/index.html b/cs/zengin/scripts/extenders/lego/frame_functions/index.html deleted file mode 100644 index 79d8a8e592..0000000000 --- a/cs/zengin/scripts/extenders/lego/frame_functions/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/cs/zengin/scripts/extenders/lego/gamestate/index.html b/cs/zengin/scripts/extenders/lego/gamestate/index.html deleted file mode 100644 index 66a81fdd74..0000000000 --- a/cs/zengin/scripts/extenders/lego/gamestate/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/cs/zengin/scripts/extenders/lego/index.html b/cs/zengin/scripts/extenders/lego/index.html deleted file mode 100644 index fd4d9bd52d..0000000000 --- a/cs/zengin/scripts/extenders/lego/index.html +++ /dev/null @@ -1,34 +0,0 @@ - LeGo - Gothic Modding Community
\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/lego/int64/index.html b/cs/zengin/scripts/extenders/lego/int64/index.html deleted file mode 100644 index c45777f16c..0000000000 --- a/cs/zengin/scripts/extenders/lego/int64/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/cs/zengin/scripts/extenders/lego/item_helper/index.html b/cs/zengin/scripts/extenders/lego/item_helper/index.html deleted file mode 100644 index 157ce75b3a..0000000000 --- a/cs/zengin/scripts/extenders/lego/item_helper/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/cs/zengin/scripts/extenders/lego/locals/index.html b/cs/zengin/scripts/extenders/lego/locals/index.html deleted file mode 100644 index d871a56318..0000000000 --- a/cs/zengin/scripts/extenders/lego/locals/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/cs/zengin/scripts/extenders/lego/misc/index.html b/cs/zengin/scripts/extenders/lego/misc/index.html deleted file mode 100644 index 38bec415d2..0000000000 --- a/cs/zengin/scripts/extenders/lego/misc/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/cs/zengin/scripts/extenders/lego/names/index.html b/cs/zengin/scripts/extenders/lego/names/index.html deleted file mode 100644 index b6e6f05ae7..0000000000 --- a/cs/zengin/scripts/extenders/lego/names/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/cs/zengin/scripts/extenders/lego/random/index.html b/cs/zengin/scripts/extenders/lego/random/index.html deleted file mode 100644 index 80cf3eadb4..0000000000 --- a/cs/zengin/scripts/extenders/lego/random/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/cs/zengin/scripts/extenders/lego/talents/index.html b/cs/zengin/scripts/extenders/lego/talents/index.html deleted file mode 100644 index e1fa771490..0000000000 --- a/cs/zengin/scripts/extenders/lego/talents/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/cs/zengin/scripts/extenders/lego/timer/index.html b/cs/zengin/scripts/extenders/lego/timer/index.html deleted file mode 100644 index 79f96d8e26..0000000000 --- a/cs/zengin/scripts/extenders/lego/timer/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/cs/zengin/scripts/extenders/lego/tools/ai_function/index.html b/cs/zengin/scripts/extenders/lego/tools/ai_function/index.html deleted file mode 100644 index ac8844ac2e..0000000000 --- a/cs/zengin/scripts/extenders/lego/tools/ai_function/index.html +++ /dev/null @@ -1,71 +0,0 @@ - AI_Function - Gothic Modding Community

AI_Function

This package allows time-delayed functions to be called by enqueuing the functions in the AI queue of the NPC in question. This can be very useful in writing cutscenes on engine or implementing new routines.

Dependencies

Initialization

Initialize with LeGo_AI_Function flag.

LeGo_Init(LeGo_AI_Function);
-

Implementation

AI_Function.d on GitHub

Functions

The script function function is called with a delay: it joins the AI queue of slf.

func void AI_Function(var C_NPC slf, var func function)
-
Parameters
  • var C_NPC slf
    NPC in whose AI queue the function is queued
  • var func function
    Name of function to be queued

Additionally, there are some overloads of AI_Function, which allow to call functions with parameters.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
func void AI_Function_I  (var C_NPC slf, var func function, var int    param) {}; // Int
-func void AI_Function_N  (var C_NPC slf, var func function, var int    param) {}; // Instance (e.g. NPC)
-func void AI_Function_S  (var C_NPC slf, var func function, var string param) {}; // String
-func void AI_Function_II (var C_NPC slf, var func function, var int    param1, var int    param2) {}; // Int, Int
-func void AI_Function_NN (var C_NPC slf, var func function, var int    param1, var int    param2) {}; // Instance, Instance
-func void AI_Function_SS (var C_NPC slf, var func function, var string param1, var string param2) {}; // String, String
-func void AI_Function_IS (var C_NPC slf, var func function, var int    param1, var string param2) {}; // Int, String
-func void AI_Function_SI (var C_NPC slf, var func function, var string param1, var int    param2) {}; // String, Int
-func void AI_Function_NS (var C_NPC slf, var func function, var int    param1, var string param2) {}; // Instance, String
-func void AI_Function_SN (var C_NPC slf, var func function, var string param1, var int    param2) {}; // String, Instance
-func void AI_Function_IN (var C_NPC slf, var func function, var int    param1, var int    param2) {}; // Int, Instance
-func void AI_Function_NI (var C_NPC slf, var func function, var int    param1, var int    param2) {}; // Instance, Int
-
Functions with more than two parameters cannot be called, but parameters can be passed indirectly via global variables.

In the called function, self can be accessed as follows:

var oCNpc slf; slf = _^(ECX);
-

Info

From LeGo 2.7.2 the global instance self is provided correctly and can be used directly.

Examples

Enqueueing a simple function

Before a function is called, any Npc should first complete its AI queue.

Here the hero is supposed to run to a waypoint, and only when he has arrived is to start a tracking shot.

1
-2
-3
-4
-5
-6
func void Example1() {
-    Npc_ClearAIQueue(hero);
-    AI_GotoWP(hero, "MYWAYPOINT");
-
-    AI_Function_S(hero, Wld_SendTrigger, "CAMERASTART");
-};
-
As soon as the hero has reached the waypoint, Wld_SendTrigger("CAMERASTART"); is called.
\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/lego/tools/binary_machines/index.html b/cs/zengin/scripts/extenders/lego/tools/binary_machines/index.html deleted file mode 100644 index 0a9e0d54b4..0000000000 --- a/cs/zengin/scripts/extenders/lego/tools/binary_machines/index.html +++ /dev/null @@ -1,233 +0,0 @@ - BinaryMachines - Gothic Modding Community

BinaryMachines

This package allows you to create and write your own files anywhere in the file system.

Dependencies

N/A

Initialization

N/A

Implementation

BinaryMachines.d on GitHub

BinaryWriter

BW_NewFile

Creates the file with the file name and opens a stream. Doesn't work if a stream is already open.

func int BW_NewFile(var string file)
-
Parameters
  • var string file
    Name of created file

Return value

The function returns TRUE if the file is successfully created and initialized, FALSE is returned otherwise.

BW_Close

Closes the current write stream.

func void BW_Close()
-

BW

Writes length bytes from the data to the stream, maximum 4 bytes.

func void BW(var int data, var int length)
-
Parameters
  • var int data
    Value of bytes
  • var int length
    Number of bytes

BW_Int

Writes 4 bytes from the data to the stream. Same as BW(data, 4).

func void BW_Int(var int data)
-
Parameters
  • var int data
    Integer value to write

BW_Char

Writes the first character from the data to the stream. Same as BW(Str_GetCharAt(data, 0), 1).

func void BW_Char(var string data)
-
Parameters
  • var string data
    Char to write

BW_String

Writes the data terminated with \0 to the stream.

func void BW_String(var string data)
-
Parameters
  • var string data
    String to write

BW_Byte

Writes a byte from the data to the stream. Same as BW(data, 1).

func void BW_Byte(var int data)
-
Parameters
  • var int data
    Byte value to write

BW_Bytes

Writes length of bytes from the pointer dataPtr to the stream.

func void BW_Bytes(var int dataPtr, var int length)
-
Parameters
  • var int dataPtr
    Pointer of data to write
  • var int length
    Number of bytes

BW_Text

Writes the string to the stream without terminating it. So it can no longer be read.

func void BW_Text(var string data)
-
Parameters
  • var string data
    Text to write

BW_NextLine

Writes a paragraph to the stream.

func void BW_NextLine()
-

BinaryReader

BR_OpenFile

Opens the file with the file name and opens a stream. Doesn't work if a stream is already open.

func int BR_OpenFile(var string file)
-
Parameters
  • var string file
    File to be opened

Return value

The function returns TRUE if the file is successfully opened and initialized, FALSEis returned otherwise.

BR_Close

Closes the current read stream.

func void BR_Close()
-

BR

Reads bytes from the stream.

func int BR(var int length)
-
Parameters
  • var int length
    Number of bytes to read (maximum 4)

Return value

The function returns the value of read bytes.

BR_Int

Reads 4 bytes from the stream. Same as BR(4).

func int BR_Int()
-
Return value

The function returns the read integer.

BR_Char

Reads a character from the stream. Same as BR(1).

func string BR_Char()
-
Return value

The function returns the read character as a string.

BR_String

Reads a string terminated by \0 from the stream.

func string BR_String()
-
Return value

The function returns the read string.

BR_Byte

Reads a byte from the stream.

func int BR_Byte()
-
Return value

The function returns the read byte.

BR_Bytes

Reads bytes from the stream.

func int BR_Bytes(var int length)
-
Parameters
  • var int length
    Number of bytes to read

Return value

The function returns a pointer to the read bytes.

BR_TextLine

Reads a line from the stream.

func string BR_TextLine()
-
Return value

The function returns the read line.

BR_Text

Reads a string of the given length from a stream.

func string BR_Text(var int length)
-
Parameters
  • var int length
    Number of characters to read

Return value

The function returns the read string.

BR_NextLine

Changes the read position to the next paragraph, created with BW_NextLine

func void BR_NextLine()
-

Enginecalls

WIN_GetLastError

Call of a Win32 API GetLastError function

func int WIN_GetLastError()
-
Return value

The function returns calling thread's last-error code.

WIN_CreateFile

Call of a Win32 API CreateFileA function

func int WIN_CreateFile(var string lpFileName,var int dwDesiredAccess,var int dwShareMode,var int lpSecurityAttributes,var int dwCreationDisposition,var int dwFlagsAndAttributes,var int hTemplateFile)
-
Parameters

Full description of parameters can be found here

Return value

Information about return value can be found here

WIN_WriteFile

Call of a Win32 API WriteFile function

func void WIN_WriteFile(var int hFile,var int lpBuffer,var int nNumberOfBytesToWrite,var int lpNumberOfBytesWritten,var int lpOverlapped)
-
Parameters

Full description of parameters can be found here

WIN_ReadFile

Call of a Win32 API ReadFile function

func void WIN_ReadFile(var int hFile,var int lpBuffer,var int nNumberOfBytesToRead,var int lpNumberOfBytesRead,var int lpOverlapped)
-
Parameters

Full description of parameters can be found here

WIN_CloseHandle

Call of a Win32 API CloseHandle function

func void WIN_CloseHandle(var int hObject)
-
Parameters

Full description of parameters can be found here

WIN_GetFileSize

Call of a Win32 API GetFileSize function

func int WIN_GetFileSize(var int hFile,var int lpFileSizeHigh)
-
Parameters

Full description of parameters can be found here

Return value

Information about return value can be found here

Constants

In addition there are some constants defined for use with the specific engine calls.

1
-2
-3
-4
-5
-6
-7
-8
const int CREATE_ALWAYS = 2;
-const int OPEN_EXISTING = 3;
-const int GENERIC_ALL = 1073741824;
-const int GENERIC_READ = -2147483648;
-const int FILE_SHARE_READ = 1;
-const int FILE_SHARE_WRITE = 2;
-const int FILE_SHARE_DELETE = 4;
-const int FILE_ATTRIBUTE_NORMAL = 128;
-

Examples

Save and load variables

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
const string filename = "System\MySave.sav";
-
-var string s0; // string
-var int    i1; // int
-var int    b2; // byte
-var string c3; // char
-
-func void SaveMyData() 
-{
-    if(BW_NewFile(filename))  // Create a new file:
-    { 
-        BW_String(s0);
-        BW_Int(i1);
-        BW_Byte(b2);
-        BW_Char(c3);          // Save stuff..
-        BW_Close();           // ..and close.
-    };
-};
-
-func void LoadMyData() {
-    if(BR_OpenFile(filename)) // Try to open file:
-    { 
-        s0 = BR_String();
-        i1 = BR_Int();
-        b2 = BR_Byte();
-        c3 = BR_Char();       // Read in values..
-        BR_Close();           // ..and close.
-    }
-    else 
-    {
-        SaveMyData();         // Otherwise create a save file.
-    };
-};
-

Congratulate the player

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
func void Certificate(var string Username, var int Score) 
-{
-    var string filename; filename = ConcatStrings(Username, "'s Certificate.txt");
-    BW_NewFile(filename); // Username + "s Certificate.txt". The file is then in the Gothic directory.
-    BW_Text("Congratulations "); BW_Text(Username);
-    BW_TextLine("!");
-
-    BW_Text("You have reached ");
-    BW_Text(IntToString(Score)); // Not BW_Int!
-    BW_TextLine(" Points in this fun game.");
-
-    BW_NextLine();
-
-    BW_Text("Best regards, Author");
-    BW_Close();
-
-    /*
-       When calling:  Certificate("Player", 1000);
-       a file with the name 'Player's Certificate.txt' would come out which would contain the following:
-
-        Congratulations Player
-        You have reached 1000 Points in this fun game.
-
-        Best regards, Author
-    */
-};
-

The location of an NPCs

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
func void BW_NpcPosition(var C_NPC slf) 
-{
-    var int ptr; ptr = MEM_Alloc(60);                // 16 * 4
-    MEM_CopyBytes(MEM_InstToPtr(slf) + 60, ptr, 60); // Copy slf.trafoObjToWorld
-    BW_Bytes(ptr, 60);                               // Writes the 60 copied bytes
-    MEM_Free(ptr);                                   // And clean up..
-};
-
-func void BR_NpcPosition(var C_NPC slf) 
-{
-    var int ptr; ptr = BR_Bytes(60);                 // Read 60 bytes
-    MEM_CopyBytes(ptr, MEM_InstToPtr(slf) + 60, 60); // Paste back into slf
-    MEM_Free(ptr);                                   // And clean up again..
-};
-
-/*
-   Normal use:
-     BW_NewFile(file);
-     BW_NpcPosition(hero);
-     BW_Close();
-*/
-

Note

Examples originally written by Gottfried and posted on World of Gothic forum.

\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/lego/tools/event_handler/index.html b/cs/zengin/scripts/extenders/lego/tools/event_handler/index.html deleted file mode 100644 index 9525d0a923..0000000000 --- a/cs/zengin/scripts/extenders/lego/tools/event_handler/index.html +++ /dev/null @@ -1,55 +0,0 @@ - EventHandler - Gothic Modding Community

EventHandler

This package allows to create new events and trigger them at desired times. The Gamestate package already uses it.

Warning

The EventHandler requires some basic understanding of the PermMem. The documentation can be found here.

Dependencies

Initialization

Initialize with LeGo_EventHandler flag.

LeGo_Init(LeGo_EventHandler);
-

Implementation

EventHandler.d on GitHub

Functions

Event_Create

Creates a new event and returns a handle to it.

func int Event_Create()
-
Return value

The function returns a new PermMem handle to an event.

Event_Delete

Alias to PermMem delete. Cleans up the handle.

func void Event_Delete(var int event)
-
Parameters
  • var int event
    Handle returned from Event_Create

Event_Empty

Checks whether the event is "empty", i.e. nothing will happen after its execution.

func int Event_Empty(var int event)
-
Parameters
  • var int event
    Handle returned from Event_Create

Return value

The function returns TRUE if event is empty, FALSE is returned otherwise.

Event_Has

Checks if function is added to the event.

func int Event_Has(var int event, var func function)
-
Parameters
  • var int event
    Handle returned from Event_Create
  • var func function
    Checked function

Return value

The function returns TRUE if function is added, FALSE is returned otherwise.

Event_Add

Adds an event handler function. The handler is called after running Event_Execute.

func void Event_Add(var int event, var func function)
-
Parameters
  • var int event
    Handle returned from Event_Create
  • var func function
    Function to be added

Event_AddOnce

Event_Add but checks if the handler function is already added, to prevent duplicates.

func void Event_AddOnce(var int event, var func function)
-
Parameters
  • var int event
    Handle returned from Event_Create
  • var func function
    Function to be added

Event_Remove

Removes the event handler function from the event.

func void Event_Remove(var int event, var func function)
-
Parameters
  • var int event
    Handle returned from Event_Create
  • var func function
    Function to be removed

Event_Execute

Core of the package. Calls all functions registered via Event_Add and Event_AddOnce.

func void Event_Execute(var int event, var int data)
-
Parameters
  • var int event
    Handle returned from Event_Create
  • var int data
    Int parameter passed to all executed functions

Ptr functions

Tip

The pointer functions are used internally by the previous functions. If you created an event with Event_Create use functions without Ptr in the name, but if you created event with EventPtr_Create use only Ptr functions. The normal user will probably never need the pointer versions, however the choice, which one to use is yours.

EventPtr_Create

Creates a new event and returns a pointer to it.

func int EventPtr_Create()
-
Return value

The function returns a new PermMem pointer to an event.

EventPtr_Delete

Alias to PermMem free. Cleans up the pointer.

func void EventPtr_Delete(var int eventPtr)
-
Parameters
  • var int eventPtr
    Pointer returned from EventPtr_Create

EventPtr_Empty

Checks whether the event is "empty", i.e. nothing will happen after its execution.

func int EventPtr_Empty(var int eventPtr)
-
Parameters
  • var int eventPtr
    Pointer returned from EventPtr_Create

Return value

The function returns TRUE if empty, FALSE is returned otherwise.

EventPtr_Has

Checks if function is added to an event.

func int EventPtr_Has(var int eventPtr, var func function)
-
Parameters
  • var int eventPtr
    Pointer returned from EventPtr_Create
  • var func function
    Checked function

Return value

The function returns TRUE if function is added, FALSE is returned otherwise.

EventPtr_HasI

EventPtr_Has but with function ID instead of pointer. Used mainly internally.

func int EventPtr_HasI(var int eventPtr, var int id)
-
Parameters
  • var int eventPtr
    Pointer returned from EventPtr_Create
  • var int id
    ID of checked function

Return value

The function returns TRUE if function is added, FALSE is returned otherwise.

EventPtr_Add

Adds an event handler function. The handler is called after running EventPtr_Execute.

func void EventPtr_Add(var int eventPtr, var func function)
-
Parameters
  • var int eventPtr
    Pointer returned from EventPtr_Create
  • var func function
    Function to be added

EventPtr_AddI

EventPtr_Add but with function ID instead of pointer. Used mainly internally.

func void EventPtr_AddI(var int eventPtr, var int id)
-
Parameters
  • var int eventPtr
    Pointer returned from EventPtr_Create
  • var int id
    ID of function to be added

EventPtr_AddOnce

Event_Add but checks if function is already added, to prevent duplicates.

func void EventPtr_AddOnce(var int eventPtr, var func function)
-
Parameters
  • var int eventPtr
    Pointer returned from EventPtr_Create
  • var func function
    Function to be added

EventPtr_AddOnceI

EventPtr_AddI but checks if function is already added, to prevent duplicates.

func void EventPtr_AddOnceI(var int eventPtr, var int id)
-
Parameters
  • var int eventPtr
    Pointer returned from EventPtr_Create
  • var int id
    ID of function to be added

EventPtr_Remove

Removes a function from the event's call list.

func void EventPtr_Remove(var int eventPtr, var func function)
-
Parameters
  • var int eventPtr
    Pointer returned from EventPtr_Create
  • var func function
    Function to be removed

EventPtr_RemoveI

EventPtr_Remove but with function ID instead of pointer. Used mainly internally.

func void EventPtr_RemoveI(var int eventPtr, var int id)
-
Parameters
  • var int eventPtr
    Pointer returned from EventPtr_Create
  • var int id
    ID of function to be removed

EventPtr_Execute

Core of the package. Calls all functions registered via EventPtr_Add and EventPtr_AddOnce.

func void EventPtr_Execute(var int eventPtr, var int data)
-
  • var int eventPtr
    Pointer returned from EventPtr_Create
  • var int data
    Int parameter passed to all executed functions

Examples

Note

This article has no built-in examples, but the best way to understand how EventHandler works is reading source code of the Gamestate package.

\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/lego/tools/frame_functions/index.html b/cs/zengin/scripts/extenders/lego/tools/frame_functions/index.html deleted file mode 100644 index b368929483..0000000000 --- a/cs/zengin/scripts/extenders/lego/tools/frame_functions/index.html +++ /dev/null @@ -1,119 +0,0 @@ - FrameFunctions - Gothic Modding Community

FrameFunctions

The FrameFunctions package allows to call any number of functions called on every frame, or every specified time delay.

Dependencies

Initialization

Initialize with LeGo_FrameFunctions flag.

LeGo_Init(LeGo_FrameFunctions);
-

Implementation

FrameFunctions.d on GitHub

Functions

FF_Apply

Adds the Daedalus function function to the running FrameFunctions list. function is called each frame.

func void FF_Apply(var func function)
-
Parameters
  • var func function
    Name of the function

FF_ApplyGT

Adds the Daedalus function function to the running FrameFunctions list. function is called every frame except when the game is paused.

func void FF_ApplyGT(var func function)
-
Parameters
  • var func function
    Name of the function

FF_ApplyData

Adds the Daedalus function function to the running FrameFunctions list. The integer parameter data is passed to the function function.

func void FF_ApplyData(var func function, var int data)
-
Parameters
  • var func function
    Name of the function.
  • var int data
    Value passed to the function as a parameter

FF_ApplyExt

Adds the Daedalus function function to the running FrameFunctions list. The function function is called every delay milliseconds, and it runs only cycles number of times.

func void FF_ApplyExt(var func function, var int delay, var int cycles)
-
Parameters
  • var func function
    Name of the function
  • var int delay
    Delay between calls in milliseconds (0 = every frame)
  • var int cycles
    How many times should the function be called (-1 = endless)

FF_ApplyExtGT

Adds the Daedalus function function to the running FrameFunctions list. The function function is called every delay milliseconds, and it runs only cycles number of times. Gets called only when the game is not paused.

func void FF_ApplyExtGT(var func function, var int delay, var int cycles)
-
Parameters
  • var func function
    Name of the function
  • var int delay
    Delay between calls in milliseconds (0 = every frame)
  • var int cycles
    How many times should the function be called (-1 = endless)

FF_ApplyExtData

Adds the Daedalus function function to the running FrameFunctions list. The function function is called every delay milliseconds, and it runs only cycles number of times. The integer parameter data is passed to the function function.

func void FF_ApplyExtData(var func function, var int delay, var int cycles, var int data)
-
Parameters
  • var func function
    Name of the function.
  • var int delay
    Delay between calls in milliseconds (0 = every frame)
  • var int cycles
    How many times should the function be called (-1 = endless)
  • var int data
    Value passed to the function as a parameter

FF_ApplyExtDataGT

Adds the Daedalus function function to the running FrameFunctions list. The function function is called every delay milliseconds, and it runs only cycles number of times. The integer parameter data is passed to the function function. Gets called only when the game is not paused.

func void FF_ApplyExtData(var func function, var int delay, var int cycles, var int data)
-
Parameters
  • var func function
    Name of the function.
  • var int delay
    Delay between calls in milliseconds (0 = every frame)
  • var int cycles
    How many times should the function be called (-1 = endless)
  • var int data
    Value passed to the function as a parameter

FF_ApplyOnce

Alias to FF_Apply, which only adds the function once, even after multiple calls.

func void FF_ApplyOnce(var func function)
-
Parameters
  • var func function
    Name of the function

FF_ApplyOnceGT

Alias to FF_ApplyGT, which only adds the function once, even after multiple calls. Loop doesn't run if the game is paused.

func voidoften FF_ApplyOnceGT(var func function)
-
Parameters
  • var func function
    Name of the function.

FF_ApplyOnceData

Alias to FF_ApplyData, which only adds the function with the specified parameter once, even after multiple calls.

func void FF_ApplyOnceData(var func function, var int data)
-
Parameters
  • var func function
    Name of the function.
  • var int data
    Value passed to the function as a parameter

FF_ApplyOnceExt

Alias to FF_ApplyExt, which adds the function only once, after repeated calls.

func void FF_ApplyOnceExt(var func function, var int delay, var int cycles)
-
Parameters
  • var func function
    Name of the function
  • var int delay
    Delay between calls in milliseconds (0 = every frame)
  • var int cycles
    How many times should the function be called (-1 = endless)

FF_ApplyOnceExtGT

Alias to FF_ApplyExtGT, which adds the function only once after repeated calls. Loop doesn't run if the game is paused.

func void FF_ApplyOnceExtGT(var func function, var int delay, var int cycles)
-
Parameters
  • var func function
    Name of the function
  • var int delay
    Delay between calls in milliseconds (0 = every frame)
  • var int cycles
    How many times should the function be called (-1 = endless)

FF_ApplyOnceExtData

Alias to FF_ApplyExtData, which adds the function with the specified parameter only once, after repeated calls.

func void FF_ApplyOnceExtData(var func function, var int delay, var int cycles, var int data)
-
Parameters
  • var func function
    Name of the function
  • var int delay
    Delay between calls in milliseconds (0 = every frame)
  • var int cycles
    How many times should the function be called (-1 = endless)
  • var int data
    Value passed to the function as a parameter

FF_Active

Checks whether the function is active.

func int FF_Active(var func function)
-
Parameters
  • var func function
    Name of the function

Return value The function returns TRUE if the function is active, FALSE if it is not.

FF_ActiveData

Checks whether the function with the specified data is active.

func int FF_ActiveData(var func function, var int data)
-
Parameters
  • var func function
    Name of the function
  • var int data
    Value previously passed to the function

Return value The function returns TRUE if the function is active, FALSE if it is not.

FF_Remove

Stops a specific FrameFunction.

func void FF_Remove(var func function)
-
Parameters
  • var func function
    Name of the stopped function

FF_RemoveAll

Stops all intsnces of a specific FrameFunction.

func void FF_RemoveAll(var func function)
-
Parameters
  • var func function
    Name of the stopped function

FF_RemoveData

Stops a specific FrameFunction, with the specified value (see FF_ApplyExtData ).

func void FF_RemoveData(var func function, var int data)
-
Parameters
  • var func function
    Name of the stopped function
  • var int data
    Value previously passed to the function as a parameter

Examples

A function called every frame

In this example function MyFunc will be executed on every frame.

1
-2
-3
-4
-5
-6
func void Example1()
-{
-    FF_Apply(MyFunc);
-};
-
-func void MyFunc() {};
-
After the Example1 function is executed the function MyFunc is called on every frame.

The easiest and best way to run a function from the beginning is to call FF-Apply directly in the Init_Global (under LeGo_Init), there is a small problem: If the game is loaded, Init_Global is called a second time, the function is added to the list again and is therefore always called twice.

To avoid this effect, you should check whether the function is already active:

1
-2
-3
-4
-5
-6
-7
func void Example1()
-{
-    if(!FF_Active(MyFunc))
-    {
-        FF_Apply(MyFunc);
-    };
-};
-

However, since LeGo version 2.2 there is an even more pleasant method to do this:

1
-2
-3
-4
func void Example1()
-{
-    FF_ApplyOnce(MyFunc);
-};
-
FF_ApplyOnce function already implements the check for function activity.

Calling delayed function

Create a function, that is called once after 3 seconds.

1
-2
-3
-4
-5
-6
func void Example2()
-{
-    FF_ApplyExt(MyFunc2, 3000, 1); // 3000 ms = 3 s, this function is called only once
-};
-
-func void MyFunc2() {};
-

There is also a Once variant of this function, that prevents adding it twice into the frame function list.

1
-2
-3
-4
func void Example2()
-{
-    FF_ApplyOnceExt(MyFunc2, 3000, 1);
-};
-

Note

FF_ApplyExt(MyFunc, 0, -1) is the same as FF_Apply(MyFunc).

FrameFunction with Timer

Since LeGo 2.2, FrameFunctions package uses the Timer package, so it is possible to pause FrameFunctions at will:

1
-2
-3
-4
-5
-6
-7
-8
-9
func void Example3()
-{
-    FF_ApplyOnceExt(MyFunc3, 4000, 2);
-};
-
-func void MyFunc3()
-{
-    Timer_SetPaused(!Timer_GetPaused());
-};
-
This would pause the timer after 4 seconds and let it continue after 8 seconds.

Warning

Because the timer doesn't run, the frame function execution is stopped as well. This script won't work. If the timer is to be paused, it must be paused outside FrameFunctions.

Note

This is translation of article originally written by Gottfried and Lehona and hosted on LeGo's official documentation website.

\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/lego/tools/hashtables/index.html b/cs/zengin/scripts/extenders/lego/tools/hashtables/index.html deleted file mode 100644 index 05b9ca56c9..0000000000 --- a/cs/zengin/scripts/extenders/lego/tools/hashtables/index.html +++ /dev/null @@ -1,146 +0,0 @@ - Hashtables - Gothic Modding Community

Hashtables

Hashtables package is an implementation of hashtables in Gothic. Currently (version 2.8.0) only integers are supported as keys. The Hashtables grow automatically.

Dependencies

Initialization

Initialize with LeGo_PermMem flag.

LeGo_Init(LeGo_PermMem);
-

Implementation

Hashtable.d on GitHub

Functions

HT_CreateSized

Generates a hashtable of the specified size.

func int HT_CreateSized(var int size)
-
Parameters
  • var int size
    Size of the hashtable to be created

Return value

The function returns a handle to the created hashtable.

HT_Create

Generates a standard size hashtable.

func int HT_Create()
-
Return value

The function returns a handle to the created hashtable.

HT_Insert

Inserts a value into the Hashtable.

func void HT_Insert(var int handle, var int val, var int key)
-
Parameters
  • var int handle
    Handle of a hashtable
  • var int val
    The value to be inserted
  • var int key
    The key associated with the value

HT_Resize

Changes the size of the hashtable (usually not necessary as it happens automatically).

func void HT_Resize(var int handle, var int size)
-
Parameters
  • var int handle
    Handle of a hashtable
  • var int size
    The new size of the hashtable

HT_Get

Reads a value from the hashtable.

func int HT_Get(var int handle, var int key)
-
Parameters
  • var int handle
    Handle of a hashtable
  • var int key
    The key whose value is to be read

Return value

The function returns the value associated with the key.

HT_Has

Checks if the key already exist in hashtable.

func int HT_Has(var int handle, var int key)
-
Parameters
  • var int handle
    Handle of a hashtable
  • var int key
    The key to be checked Return value

The function returns TRUE if the key exist, FALSE is returned otherwise.

HT_Remove

Removes a key from the hashtable.

func void HT_Remove(var int handle, var int key)
-
Parameters
  • var int handle
    Handle of a hashtable
  • var int key
    The key to be removed

HT_Change

Changes the value of a key already existing in the hashtable.

func void HT_Change(var int handle, var int val, var int key)
-
Parameters
  • var int handle
    Handle of a hashtable
  • var int val
    The new value
  • var int key
    The key whose value is to be changed

HT_InsertOrChange

Inserts a value into the Hashtable, or changes the value if the key already exist into hashtable.

func void HT_InsertOrChange(var int handle, var int val, var int key)
-
Parameters
  • var int handle
    Handle of a hashtable
  • var int val
    The new value
  • var int key
    The key whose value is to be changed or associated with the value.

HT_GetNumber

Returns the number of entries in a hashtable.

func int HT_GetNumber(var int handle)
-
Parameters
  • var int handle
    Handle of a hashtable

Return value

The function returns the number of entries in the hashtable.

HT_ForEach

Performs a function for each value pair in the hashtable.

func void HT_ForEach(var int handle, var func fnc)
-
Parameters
  • var int handle
    Handle of a hashtable
  • var func fnc
    A function with signature void (int key, int val)

HT_Destroy

Deletes the hashtable.

func void HT_Destroy(var int handle)
-
Parameters
  • var int handle
    The handle of the hashtable to be deleted

Examples

Simple operations

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
-37
-38
-39
-40
-41
-42
-43
-44
-45
-46
-47
-48
-49
-50
func void PrintKeyValuePair(var int key, var int val)
-{
-    Print(ConcatStrings(ConcatStrings("Key: ", IntToString(key)), ConcatStrings(", Value: ", IntToString(val))));
-};
-
-func void example()
-{
-    // Create a new hashtable
-    var int hashtableHandle; hashtableHandle = HT_Create();
-
-    // Insert values into the hashtable
-    HT_Insert(hashtableHandle, 42, 1);
-    HT_Insert(hashtableHandle, 23, 2);
-    HT_Insert(hashtableHandle, 56, 3);
-
-    // Get a value from the hashtable
-    var int value; value = HT_Get(hashtableHandle, 2);
-    Print(ConcatStrings("Value associated with key 2: ", IntToString(value)));
-
-    // Check if a key exists in the hashtable
-    if (HT_Has(hashtableHandle, 3))
-    {
-        Print("Key 3 exists in the hashtable.");
-    }
-    else
-    {
-        Print("Key 3 does not exist in the hashtable.");
-    };
-
-    // Remove a key from the hashtable
-    HT_Remove(hashtableHandle, 1);
-
-    // Change the value associated with a key
-    HT_Change(hashtableHandle, 99, 3);
-
-    // Insert a value or change it if the key exists
-    HT_InsertOrChange(hashtableHandle, 123, 4);
-
-    // Get the number of entries in the hashtable
-    var int numEntries; numEntries = HT_GetNumber(hashtableHandle);
-    Print(ConcatStrings("Number of entries in the hashtable: ", IntToString(numEntries)));
-
-
-    // Iterate through the hashtable and print key-value pairs
-    // Function from top of the example is used here
-    HT_ForEach(hashtableHandle, PrintKeyValuePair);
-
-    // Destroy the hashtable
-    HT_Destroy(hashtableHandle);
-};
-
\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/lego/tools/hook_dae/index.html b/cs/zengin/scripts/extenders/lego/tools/hook_dae/index.html deleted file mode 100644 index 7f618a82ae..0000000000 --- a/cs/zengin/scripts/extenders/lego/tools/hook_dae/index.html +++ /dev/null @@ -1,244 +0,0 @@ - HookDaedalus - Gothic Modding Community

HookDaedalus

This package allows hooking daedalus functions. The principle is similar HookEngine. We have a function (hooked function) into which we would like to hook another function (hook function).

Tip

Having to hook a Daedalus function should be pretty rare, because you can simply adjust the corresponding function. However, it may become necessary in some contexts.

Dependencies

N/A

Initialization

N/A

Implementation

HookDaedalus.d on GitHub

Functions

HookDaedalusFunc

Hooks the function.

func void HookDaedalusFunc(var func hooked, var func hook)
-
Parameters
  • var func hooked
    Hooked function
  • var func hook
    Hook function

HookDaedalusFuncF

Alias to the HookDaedalusFunc function.

func void HookDaedalusFuncF(var func hooked, var func hook)
-
Parameters
  • var func hooked
    Hooked function
  • var func hook
    Hook function

HookDaedalusFuncI

HookDaedalusFunc but with function ID.

func void HookDaedalusFuncI(var int hookedID, var int hookID)
-
Parameters
  • var int hookedID
    ID of hooked function
  • var int hookID
    ID of hook function

HookDaedalusFuncS

HookDaedalusFunc but with function name.

func void HookDaedalusFuncS(var string hookedName, var string hookName)
-
Parameters
  • var string hookedName
    Name of hooked function
  • var string hookName
    Name of hook function

IsHookD

Checks whether a function is already hooking another. Each function can be hooked any number of times, but each function can only hook one other.

func int IsHookD(var int funcID)
-
Parameters
  • var int funcID Symbol index of a hook function

Return value

The function returns TRUE if the function is already hooking another, FALSE is returned otherwise.

ContinueCall

Continues the program run with the original function.

func void ContinueCall()
-

PassArgumentI

Passes an integer as an argument to the original function. Must be called before ContinueCall.

func void PassArgumentI(var int i)
-
Parameters
  • var int i
    Integer argument to forward

PassArgumentS

Passes a string as an argument to the original function. Must be called before ContinueCall.

func void PassArgumentS(var string s)
-
Parameters
  • var string s
    String argument to forward

PassArgumentN

Passes an instance as an argument to the original function. Must be called before ContinueCall.

func void PassArgumentN(var instance n)
-
Parameters
  • var instance n
    Instance argument to forward

Examples

Hook before function

We have a hook:

HookDaedalusFunc(hooked, hook);
-
The functions can look like that:
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
func void hooked() 
-{
-    Print("Original function");
-};
-
-func void hook() 
-{
-    Print("Our hook");
-    ContinueCall();
-};
-
The results should look like that
1
-2
Our hook
-Original function
-

Hook after function

We have the same hook:

HookDaedalusFunc(hooked, hook);
-
The functions are also similar, but the ContinueCall(); is called first:
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
func void hooked() 
-{
-    Print("Original function");
-};
-
-func void hook() 
-{
-    ContinueCall();
-    Print("Our hook");
-};
-
The results should look like that:
1
-2
Original function
-Our hook
-

Arguments and return values

If a function to be hooked expects parameters or returns a value, our hooking function should conform to that.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
func int hooked(var int i) 
-{
-     Print("Original function");
-     return i+1;
-};
-
-func int hook(var int i) 
-{
-     Print("Our hook");
-     PassArgumentI(i);
-     ContinueCall();
-};
-
In this case, we may not return the value at the end of the hook because the returned value will just stay on the stack. However, we shouldn't give up on calling PassArgumentI(i) to ensure that it is still on top of the stack when the program continues with hooked.

Manipulation of arguments and return values

We can also manipulate arguments and return values with our hook.

1
-2
-3
-4
-5
-6
-7
-8
-9
func int hook(var int i) 
-{
-    Print("Our hook");
-    PassArgumentI(i+1);     // add 1
-    ContinueCall();
-    i = MEM_PopIntResult();
-    i *= 2;                 // Multiply by 2
-    return i;
-};
-

Multiple hooks

A function can be hooked any number of times, but each function can only hook one. New hooks are always inserted after the previous one. The following example illustrates this quite well.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
-37
-38
-39
-40
-41
-42
-43
-44
-45
-46
-47
-48
-49
-50
-51
-52
-53
-54
-55
-56
-57
-58
HookDaedalusFunc(a, b); // B hooks A
-HookDaedalusFunc(a, c); // C hooks A to B
-HookDaedalusFunc(a, d); // D hooks A to C
-
-HookDaedalusFunc(c, b); // Ignored because B is already hooking a function
-
-var int i; i = a(1);
-
-
-// Hooked function
-func int a(var int i) 
-{
-    MEM_Info(ConcatStrings("---  A: ", IntToString(i)));
-    return i+1;
-};
-
-// First hook function:
-// Replaces `a` because the program run is not continued with ContinueCall
-func int b(var int i) 
-{
-    MEM_Info(ConcatStrings("  -- B: ", IntToString(i)));
-    return i;
-};
-
-// Second hook function:
-// Increments the argument before ContinueCall and then decrements the return value
-func int c(var int i) 
-{
-    MEM_Info(ConcatStrings(" -> C: ", IntToString(i)));
-    passArgumentI(i+1);
-    ContinueCall();
-
-    i = MEM_PopIntResult();
-    i -= 1;
-    MEM_Info(ConcatStrings(" <- C: ", IntToString(i)));
-    return i;
-};
-
-// Third hook function:
-// Increments the argument before ContinueCall and then decrements the return value
-func int d(var int i) 
-{
-    MEM_Info(ConcatStrings("-> D: ", IntToString(i)));
-    passArgumentI(i+1);
-    ContinueCall();
-
-    i = MEM_PopIntResult();
-    i -= 1;
-    MEM_Info(ConcatStrings("<- D: ", IntToString(i)));
-    return i;
-};
-
-// Output:
-// -> D: 1
-//  -> C: 2
-//   -- B: 3
-//  <- C: 2
-// <- D: 1
-
\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/lego/tools/hook_engine/index.html b/cs/zengin/scripts/extenders/lego/tools/hook_engine/index.html deleted file mode 100644 index 480aa365b0..0000000000 --- a/cs/zengin/scripts/extenders/lego/tools/hook_engine/index.html +++ /dev/null @@ -1,66 +0,0 @@ - HookEngine - Gothic Modding Community

HookEngine

This package allows you to hook anywhere in an engine function to run your own Daedalus code.

Tip

Zerxes has provided a list of all engine functions for G2, including the number of bytes to fill in for oldInstr. This list can be found here. This should make it possible for everyone to use the HookEngine effectively without IDA.

Dependencies

N/A

Initialization

N/A

Implementation

HookEngine.d on GitHub

Functions

HookEngine

Attaches a function to an engine function address.

func void HookEngine(var int address, var int oldInstr, var string function)
-
Parameters
  • var int address
    Address of an engine function to which the function should be attached.
  • var int oldInstr
    The length in bytes of the instruction to be found at address, at least 5 bytes. Can be seen in IDA.
  • var string function
    Name of Daedalus function to be called.

HookEngineS

Alias to the HookEngine function.

func void HookEngineS(var int address, var int oldInstr, var string function)
-
Parameters
  • var int address
    Address of an engine function to which the function should be attached.
  • var int oldInstr
    The length in bytes of the instruction to be found at address, at least 5 bytes. Can be seen in IDA.
  • var string function
    Name of Daedalus function to be called.

HookEngineI

Alias to HookEngine with funcID.

func void HookEngineI(var int address, var int oldInstr, var int funcID)
-
Parameters
  • var int address
    Address of an engine function to which the function should be attached.
  • var int oldInstr
    The length in bytes of the instruction to be found at address, at least 5 bytes. Can be seen in IDA.
  • var int funcID
    ID of Daedalus function to be called.

HookEngineF

Alias to HookEngine with func parameter.

func void HookEngineF(var int address, var int oldInstr, var func function)
-
Parameters
  • var int address
    Address of an engine function to which the function should be attached.
  • var int oldInstr
    The length in bytes of the instruction to be found at address, at least 5 bytes. Can be seen in IDA.
  • var func function
    Daedalus function to be called.

IsHooked

Checks if a hook is already present at a given address.

func var int IsHooked(var int address)
-
Parameters
  • var int address
    Address of an engine function.

Return value

The function returns TRUE if the hook already exists at the address, FALSE is returned otherwise.

IsHook

Checks if a hook with a certain function is already present at an address.

func var int IsHook(var int address, var string function)
-
Parameters
  • var int address
    Address of an engine function.
  • var string function
    Name of a function.

Return value

The function returns TRUE if the hook already exists at the address, FALSE is returned otherwise.

IsHookI

Alias to IsHook with a funcID as parameter.

func var int IsHookI(var int address, var int funcID)
-
Parameters
  • var int address
    Address of an engine function.
  • var int funcID
    ID of a function.

Return value

The function returns TRUE if the hook already exists at the address, FALSE is returned otherwise.

IsHookF

Alias to IsHook with a function as parameter.

func var int IsHookF(var int address, var func function)
-
Parameters
  • var int address
    Address of an engine function.
  • var func function
    Daedalus function.

Return value func parameter The function returns TRUE if the hook already exists at the address, FALSE is returned otherwise.

RemoveHook

Removes a function from a hook so that it is no longer called.

func void RemoveHook(var int address, var int oldInstr, var string function)
-
Parameters
  • var int address
    Address of an engine function to which the function should be attached.
  • var int oldInstr
    The length in bytes of the instruction to be found at address, at least 5 bytes. Can be seen in IDA.
  • var string function
    Name of Daedalus function that should no longer be called.

RemoveHookI

Alias to RemoveHook with funcID.

func void RemoveHook(var int address, var int oldInstr, var int funcID)
-
Parameters
  • var int address
    Address of an engine function to which the function should be attached.
  • var int oldInstr
    The length in bytes of the instruction to be found at address, at least 5 bytes. Can be seen in IDA.
  • var int funcID
    ID of Daedalus function that should no longer be called.

RemoveHookF

Alias for RemoveHook with func parameter.

func void RemoveHook(var int address, var int oldInstr, var func function)
-
Parameters
  • var int address
    Address of an engine function to which the function should be attached.
  • var int oldInstr
    The length in bytes of the instruction to be found at address, at least 5 bytes. Can be seen in IDA.
  • var func function
    Daedalus function that should no longer be called.

ReplaceEngineFunc

Replaces an engine function with a Daedalus function.

func void ReplaceEngineFunc(var int address, var int thiscall_numparams, var string replaceFunc)
-
Parameters
  • var int address
    Address of the engine function to be replaced.
  • var int thiscall_numparams
    Number of parameters passed to the engine function, if it is a stdcall or thiscall (otherwise 0).
  • var string replaceFunc
    Name of a Daedalus function to be called instead.

ReplaceEngineFuncI

Alias to ReplaceEngineFunc with funcID.

func void ReplaceEngineFunc(var int address, var int thiscall_numparams, var int funcID)
-
Parameters
  • var int address
    Address of the engine function to be replaced.
  • var int thiscall_numparams
    Number of parameters passed to the engine function, if it is a stdcall or thiscall (otherwise 0).
  • var int funcID
    ID of a Daedalus function to be called instead.

ReplaceEngineFuncF

Alias to ReplaceEngineFunc with func parameter.

func void ReplaceEngineFunc(var int address, var int thiscall_numparams, var func function)
-
Parameters
  • var int address
    Address of the engine function to be replaced.
  • var int thiscall_numparams
    Number of parameters passed to the engine function, if it is a stdcall or thiscall (otherwise 0).
  • var func function
    Daedalus function to be called instead.

DisableEngineFunc

Makes sure that an engine function is simply skipped. This is very delicate and will not always work so easily.

func void DisableEngineFunc(var int address, var int thiscall_numparams)
-
Parameters
  • var int address
    Address of the engine function to be skipped.
  • var int thiscall_numparams
    Number of parameters passed to the engine function, if it is a stdcall or thiscall (otherwise 0).

Hook_ReturnFalse

Simple function to replace return FALSE in hook.

func void Hook_ReturnFalse()
-

Hook_ReturnTrue

Simple function to replace return TRUE in hook.

func void Hook_ReturnTrue()
-

Registers

In addition the HookEngine package implement x86 32-bit registers that can be used to access hooked function parameters.

1
-2
-3
-4
-5
-6
-7
-8
var int EAX;
-var int ECX;
-var int EDX;
-var int EBX;
-var int ESP;
-var int EBP;
-var int ESI;
-var int EDI;    
-
\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/lego/tools/int64/index.html b/cs/zengin/scripts/extenders/lego/tools/int64/index.html deleted file mode 100644 index 28e8309c6f..0000000000 --- a/cs/zengin/scripts/extenders/lego/tools/int64/index.html +++ /dev/null @@ -1,58 +0,0 @@ - Int64 - Gothic Modding Community

Int64

Int64 implements basic arithmetic for 64-bit integers based on machine code (hence the function signatures are also in machine code style). Furthermore, Int64 offers the constructor int64@ for Int64 objects, but mk64 expects a pointer, not a handle.

Dependencies

N/A

Initialization

N/A

Implementation

Int64.d on GitHub

Functions

mk64

Writes lo and hi in one place (dest). Makes Int64, hi has to be -1 for negative 32bit lo.

func void mk64(var int dest, var int hi, var int lo)
-
Parameters
  • var int dest
    A pointer to an Int64 object or just 8 bytes of free memory.
  • var int hi
    High part of integer.
  • var int lo
    Low part of integer.
Examples

Function looks like that:

1
-2
-3
-4
    func void mk64(var int dest, var int lo, var int hi) {
-    MEM_WriteInt(dest, lo);
-    MEM_WriteInt(dest+4, hi);
-    };
-
So if you want to get 9876543210 low part should be set to 1286608618 and the high part to 2
1
-2
-3
-4
-5
-6
var int ptr; ptr = MEM_Alloc(8);
-var int low; low = 1286608618;
-var int high; high = 2;
-mk64(ptr, low, high);
-// ...
-MEM_Free(ptr);
-

neg64

Negates the integer: *dest <- -(*dest)

func void neg64(var int dest)
-
Parameters
  • var int dest
    A pointer to an Int64 object or just 8 bytes of free memory.

add64

Adds src to dest: *dest <- *dest + *src

func void add64(var int dest, var int src)
-
Parameters
  • var int dest
    A pointer to an Int64 object or just 8 bytes of free memory. Will be changed.
  • var int src
    A pointer to an Int64 object. Will not change.

sub64

Subtracts src from dest: *dest <- *dest - *src

func void sub64(var int dest, var int src)
-
Parameters
  • var int dest
    A pointer to an Int64 object or just 8 bytes of free memory. Will be changed.
  • var int src
    A pointer to an Int64 object. Will not change.

mul64

Multiplies dest by src: *dest <- (*dest) * (*src)

func void mul64(var int dest, var int src)
-
Parameters
  • var int dest
    A pointer to an Int64 object or just 8 bytes of free memory. Will be changed.
  • var int src
    A pointer to an Int64 object. Will not change.

div64

Divides dest by src: *dest <- *dest / *src

func void mul64(var int dest, var int src)
-
Parameters
  • var int dest
    A pointer to an Int64 object or just 8 bytes of free memory. Will be changed.
  • var int src
    A pointer to an Int64 object. Will not change.
\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/lego/tools/interface/index.html b/cs/zengin/scripts/extenders/lego/tools/interface/index.html deleted file mode 100644 index 40a23ac5cc..0000000000 --- a/cs/zengin/scripts/extenders/lego/tools/interface/index.html +++ /dev/null @@ -1,249 +0,0 @@ - Interface - Gothic Modding Community

Interface

This package offers a lot of useful functions to work with the 2D interface.

Dependencies

Initialization

Initialize with LeGo_Interface and LeGo_PrintS flag.

LeGo_Init(LeGo_Interface | LeGo_PrintS);
-

Implementation

Interface.d on GitHub

Functions

sysGetTime

Better alternative for MEM_GetSysTime() from Ikarus.

func int sysGetTime()
-
Return value

The function returns elapsed time since game (system) startup.

RGBA

Generates a full zColor.

func int RGBA(var int r, var int g, var int b, var int a)
-
Parameters
  • var int r
    Red channel value (0..255)
  • var int g
    Green channel value (0..255)
  • var int b
    Blue channel value (0..255)
  • var int a
    Alpha (0..255, 0 = invisible)

Return value

The function returns a zColor object.

ChangeAlpha

Overrides the alpha value of a given zColor.

func int ChangeAlpha(var int zCol, var int a)
-
Parameters
  • var int zCol
    zColor to modify
  • var int a
    New alpha value

Return value

The function returns a modified zColor object.

GetAlpha

Returns the alpha value of a given zColor.

func int GetAlpha(var int zCol)
-
Parameters
  • var int zCol
    zColor to get alpha from

Creates a new zCViewText on the screen with PermMem that can be freely edited.

func int Print_CreateText(var string text, var string font)
-
Parameters
  • var string text
    The text of the zCViewText
  • var string font
    Font of text

Return value

The function returns a handle to zCViewText.

Print_CreateText but returns pointer to zCViewText instead of handle.

func int Print_CreateTextPtr(var string text, var string font)
-
Parameters
  • var string text
    The text of the zCViewText
  • var string font
    Font of text

Return value

The function returns a pointer to zCViewText.

Print_CreateTextPtr but with additional parameter to chose color of text.

func int Print_CreateTextPtrColored(var string text, var string font, var int color)
-
Parameters
  • var string text
    The text of the zCViewText
  • var string font
    Font of text
  • var int color
    zColor e.g. generated with RGBA function

Return value

The function returns a pointer to zCViewText.

Returns zCViewText instance from handle.

func zCViewText Print_GetText(var int hndl)
-
Parameters
  • var int hndl
    Handle to zCViewText

Returns zCViewText pointer from handle.

func int Print_GetTextPtr(var int hndl)
-
Parameters
  • var int hndl
    Handle to zCViewText

Removes a zCViewText from the screen.

func void Print_DeleteText(var int hndl)
-
Parameters

Changes the alpha value of a given zCViewText.

func void Print_SetAlpha(var int hndl, var int a)
-
Parameters
  • var int hndl
    Handle to zCViewText
  • var int a
    New alpha value

PrintPtr_SetAlpha

Print_SetAlpha but with pointer to zCViewText instead of handle.

func void PrintPtr_SetAlpha(var int ptr, var int a)
-
Parameters
  • var int ptr
    Pointer to zCViewText
  • var int a
    New alpha value

Writes the current resolution to the Print_Screen array and the current aspect ratio to Print_Ratio variable.

func void Print_GetScreenSize()
-

An int array holding the current resolution. (Filled by Print_GetScreenSize)

int Print_Screen[2];
-
  • Print_Screen[PS_X] is the horizontal resolution

  • Print_Screen[PS_Y] is the vertical resolution

A float variable that holds the current aspect ratio. (Filled by Print_GetScreenSize)

int Print_Ratio;
-

PS_VMax

An int constant that holds the highest possible value of a virtual coordinate.

const int PS_VMax = 8192;
-

Convents pixel position to a virtual position.

func int Print_ToVirtual(var int pxl, var int dim)
-
Parameters
  • var int pxl
    Pixel position to convert
  • var int dim
    PS_X or PS_Y (see Print_Screen)

Return value

The function returns a virtual position of a given pixel position.

Print_ToVirtual but returns Ikarus float value instead of integer.

func int Print_ToVirtualF(var int pxl, var int dim)
-
Parameters
  • var int pxl
    Pixel position to convert
  • var int dim
    PS_X or PS_Y (see Print_Screen)

Return value

The function returns a virtual position of a given pixel position as Ikarus float.

Convents virtual position to a pixel position.

func int Print_ToPixel(var int vrt, var int dim)
-
Parameters
  • var int vrt
    Virtual position to convert
  • var int dim
    PS_X or PS_Y (see Print_Screen)

Return value

The function returns a pixel position of a given virtual position.

Print_ToPixel but returns Ikarus float value instead of integer.

func int Print_ToPixelF(var int vrt, var int dim)
-
Parameters
  • var int vrt
    Virtual position to convert
  • var int dim
    PS_X or PS_Y (see Print_Screen)

Return value

The function returns a pixel position of a given virtual position as Ikarus float.

Gets the size in the specified dimension in ratioed by the screen.

func int Print_ToRatio(var int size, var int dim)
-
Parameters
  • var int size
    Size to convert
  • var int dim
    PS_X or PS_Y (see Print_Screen)

Return value

The function returns size correctly calculated to the ratio.

Example

If you have a view and the view you need to be a square of 400 units, you would do:

1
-2
height = Print_ToRatio(400, PS_Y);
-width = 400;
-
This is because width is always the max in virtual coordinates - 8192 virtual points and the height has a different height based on the ratio, this function calculates it for you.

PS_X can be used in function, if you already have the height but need the width in the correct ratio.

Converts angle in degrees to radians.

func int Print_ToRadian(var int angle)
-
Parameters
  • var int angle
    Angle in degrees

Return value

The function returns calculated angle in radians.

Converts angle in radians to degrees.

func int Print_ToDegree(var int angle)
-
Parameters
  • var int angle
    Angle in radians

Return value

The function returns calculated angle in degrees.

Returns a pointer to a zCFont by its name.

func int Print_GetFontPtr(var string font)
-
Parameters
  • var string font
    Name of font

Returns a name of a zCFont from its pointer.

func string Print_GetFontName(var int fontPtr)
-
Parameters
  • var int fontPtr
    Pointer to font

Returns the width of a string in pixels.

func int Print_GetStringWidth(var string s, var string font)
-
Parameters
  • var string s
    Measured string
  • var string font
    Name of font

Print_GetStringWidth but with zCFont pointer instead of name.

func int Print_GetStringWidthPtr(var string s, var int font)
-
Parameters
  • var string s
    Measured string
  • var int font
    zCFont pointer

Returns the height of a string in pixels.

func int Print_GetFontHeight(var string font)
-
Parameters
  • var string font
    Name of font

Like the external PrintScreen, writes a text on the screen, but with more options.

func int Print_Ext(var int x, var int y, var string text, var string font, var int color, var int time)
-
Parameters
  • var int x
    X coordinate on the screen (virtual)
  • var int y
    Y coordinate on the screen (virtual)
  • var string text
    Displayed text
  • var string font
    Name of font
  • var int color
    zColor e.g. generated with RGBA function
  • var int time
    display time in milliseconds (-1 = permanent)

Return value

If time == -1, a valid handle is returned. If time != -1, the print is only volatile and no handle is returned.

Example
1
-2
-3
-4
-5
func void Example1()
-{
-    //           x, y, text,   font,        color,                time
-    Print_ExtPxl(2, 2, "Text", FONT_Screen, RGBA(255, 0, 0, 128), 500);
-};
-

Print_Ext but with pixel coordinates instead of virtual.

func int Print_ExtPxl(var int x, var int y, var string text, var string font, var int color, var int time)
-
Parameters
  • var int x
    X coordinate on the screen (pixel)
  • var int y
    Y coordinate on the screen (pixel)
  • var string text
    Displayed text
  • var string font
    Name of font
  • var int color
    zColor e.g. generated with RGBA function
  • var int time
    display time in milliseconds (-1 = permanent)

Return value

If time == -1, a valid handle is returned. If time != -1, the print is only volatile and no handle is returned.

Returns the longest line from text as a string, using default line separator tilde ~.

func string Print_LongestLine(var string text, var string font)
-
Parameters
  • var string text
    Measured text
  • var string font
    Name of font

Returns the longest line from text as a string, but you specify new line separator.

func string Print_LongestLineExt(var string text, var string font, var string separator)
-
Parameters
  • var string text
    Measured text
  • var string font
    Name of font
  • var string separator
    New line separator

Returns the longest line width in pixels, using default line separator tilde ~.

func int Print_LongestLineLength(var string text, var string font)
-
Parameters
  • var string text
    Measured text
  • var string font
    Name of font

Returns the longest line width in pixels, but allows you to specify new line separator.

func int Print_LongestLineLengthExt(var string text, var string font, var string separator)
-
Parameters
  • var string text
    Measured text
  • var string font
    Name of font
  • var string separator
    New line separator

Creates a text field (view with text) using virtual coordinates.

func int Print_TextField(var int x, var int y, var string text, var string font, var int height)
-
Parameters
  • var int x
    X coordinate (virtual)
  • var int y
    Y coordinate (virtual)
  • var string text
    Text to be printed
  • var string font
    Name of font
  • var int height
    A specific line height

Return value

The function returns a text field pointer. Here is how it is used:

1
-2
var zCView view; view = get(viewHndl);
-view.textLines_next = Print_TextField(x, y, text, FONT, fontHeight);
-

Print_TextField but with pixel coordinates.

func int Print_TextFieldPxl(var int x, var int y, var string text, var string font)
-
Parameters
  • var int x
    X coordinate (pixel)
  • var int y
    Y coordinate (pixel)
  • var string text
    Text to be printed
  • var string font
    Name of font

Return value

The function returns a text field pointer. Look at the Print_TextField return value to see an example.

Print_TextField but you specify the color of text.

func int Print_TextFieldColored(var int x, var int y, var string text, var string font, var int height, var int color)
-
Parameters
  • var int x
    X coordinate (virtual)
  • var int y
    Y coordinate (virtual)
  • var string text
    Text to be printed
  • var string font
    Name of font
  • var int height
    A specific line height
  • var int color
    zColor e.g. generated with RGBA function

Return value

The function returns a text field pointer. Look at the Print_TextField return value to see an example.

PrintS

Same function as the external Print, but with smooth animations. The effect can be changed as desired with the user constants.

func void PrintS(var string txt)
-
Parameters
  • var string txt
    Printed text

PrintS_Ext

PrintS but with an additional parameter to choose the color of the text.

func void PrintS_Ext(var string txt, var int color)
-
Parameters
  • var string txt
    Printed text
  • var int color
    zColor e.g. generated with RGBA function

AI_PrintS

Version of PrintS that enqueue in given NPCs AI queue.

func void AI_PrintS(var c_npc slf, var string txt)
-
Parameters
  • var c_npc slf
    NPC to whose AI queue the function is enqueued
  • var string txt
    Printed text

AI_PrintS_Ext

Version of PrintS_Ext that enqueue in given NPCs AI queue.

func void AI_PrintS_Ext(var c_npc slf, var string txt, var int color)
-
Parameters
  • var c_npc slf
    NPC to whose AI queue the function is enqueued
  • var string txt
    Printed text
  • var int color
    zColor e.g. generated with RGBA function

Examples

Manage a print via zCViewText

It is also possible to create the text only via Print_CreateText and set it yourself. In this example, a text should fly over the image from left to right and be deleted again. The movement is handled by Anim8:

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
var int MyText;
-var int MyAnim8;
-func void PrintMyScrollingText(var string text) {
-    MyText = Print_CreateText(text, FONT_Screen); // We create an empty text item with the font FONT_Screen
-
-    var zCViewText MyTextObject; MyTextObject = Print_GetText(MyText); // Now we get the empty text item in a zCViewText
-
-    MyTextObject.posx = 1;      // adjust position
-    MyTextObject.posy = 1;      // ATTENTION: These values are virtual, i.e.: 0 = far left, 8192 = far right (i.e. no pixel specification)
-                                // (But if I prefer to have pixel coordinates I could use e.g. Print_ToVirtual)
-    MyTextObject.timed = false; // The text should not be timed (not disappear)
-
-    // Anim8 will animate a text
-    // First we need a new Anim8 object:
-    MyAnim8 = Anim8_New(1, false); // Start position is 1 and this value is not a float
-
-    Anim8(MyAnim8, 8192, 2000, A8_Constant); // Target Position is 8192, Duration is 2000 milliseconds, and Movement Form is Constant
-
-    // Now all we need is a loop that matches the x value of the text to the value of Anim8:
-    FF_Apply(ScrollMyText);
-};
-
-func void ScrollMyText() {
-    var zCViewText MyTextObject; MyTextObject = Print_GetText(MyText); // Get the text as an object again
-
-    // And now compare the values:
-    MyTextObject.posx = Anim8_Get(MyAnim8);
-
-    // When Anim8 is done with that, we end the loop and delete the text:
-    if(Anim8_Empty(MyAnim8)) {
-        Print_DeleteText(MyText);
-        FF_Remove(ScrollMyText);
-        // The Anim8 object must of course also be deleted. We don't need it anymore.
-        Anim8_Delete(MyAnim8);
-    };
-};
-

Manage a print via zCViewText with LeGo 2.2+

In those days it was perhaps pleasant, but today it is no longer. Anim8 has seen a few improvements with LeGo 2.2 that make it much easier to create the same effect:

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
-37
-38
-39
-40
-41
-42
-43
-44
var int MyText;
-var int MyAnim8;
-func void PrintMyScrollingText(var string text) {
-    // Create and set text:
-    MyText = Print_CreateText(text, FONT_Screen);
-
-    var zCViewText MyTextObject; MyTextObject = Print_GetText(MyText);
-
-    MyTextObject.posx = 1;
-    MyTextObject.posy = 1;
-
-    MyTextObject.timed = false;
-
-    // But now comes the trick: We use Anim8_NewExt, this allows us to set a "Handler" and "Data".
-    MyAnim8 = Anim8_NewExt(1, ScrollMyText, MyText, false);
-
-    // ScrollMyText is passed as the handler and MyText as the data.
-    // In concrete terms, this means: ScrollMyText is always called
-    // when Anim8 has recalculated the position.
-    // Pass data and the new position as parameters. Let's see how it goes.
-
-    // Set the animation again as usual:
-    Anim8(MyAnim8, 8192, 2000, A8_Constant);
-
-    // And this time no FrameFunction.
-    // Instead, we tell Anim8 to clean up by itself when it's done:
-    Anim8_RemoveIfEmpty(MyAnim8, true);
-
-    // The text should also disappear by itself:
-    Anim8_RemoveDataIfEmpty(MyAnim8, true);
-
-    // Since MyText is a handle, this will work.
-    // If MyText were a pointer, RemoveDataIfEmpty should not be activated, it would lead to an error message.
-};
-
-func void ScrollMyText(var int MyText, var int Position) {
-     // Get the text as an object again
-    var zCViewText MyTextObject; MyTextObject = Print_GetText(MyText);
-
-    // And now compare the values:
-    MyTextObject.posx = Position;
-
-    // Since Anim8 does the deleting itself, we don't have to worry about that.
-};
-
\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/lego/tools/item_helper/index.html b/cs/zengin/scripts/extenders/lego/tools/item_helper/index.html deleted file mode 100644 index de6c185fb7..0000000000 --- a/cs/zengin/scripts/extenders/lego/tools/item_helper/index.html +++ /dev/null @@ -1,35 +0,0 @@ - ItemHelper - Gothic Modding Community

ItemHelper

This package is very simple - it retrieves a oCItem pointer from an C_ITEM instance valid for the current world and session.

Warning

Make sure every world has waypoint with name TOT ("dead" in German). Ikarus & LeGo need this waypoint to spawn helper NPCs.
This is especially important in Gothic 1 since G1 vanilla worlds do not have the TOT waypoint.

Dependencies

N/A

Initialization

N/A

Implementation

ItemHelper.d on GitHub

Functions

Itm_GetPtr

func int Itm_GetPtr(var int instance)
-
Parameters
  • var int instance
    C_ITEM instance to get the pointer of

Return value The function returns oCItem pointer of the C_ITEM instance.

\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/lego/tools/list/index.html b/cs/zengin/scripts/extenders/lego/tools/list/index.html deleted file mode 100644 index fbc00dd73b..0000000000 --- a/cs/zengin/scripts/extenders/lego/tools/list/index.html +++ /dev/null @@ -1,60 +0,0 @@ - List - Gothic Modding Community

List

The List package is a collection of functions designed to simplify the handling of zCList and zCListSort lists in daedalus. It offers a range of functions for creating, manipulating, and querying lists.

Dependencies

N/A

Initialization

N/A

Implementation

List.d on GitHub

Functions

Note

All functions, expect List_Compare come with an additional "S" at the end for objects of type zCListSort. (Example: List_NodeS .) Unlike most LeGo packages, pointers are used here, not handles!

List_Create

Creates a list with an initial value.

func int List_Create(var int data)
-
Parameters
  • var int data
    The value of the first list element.

Return value

The function returns a pointer to the created list.

List_Add

Appends a value to the end of the list.

func void List_Add(var int list, var int data)
-
Parameters
  • var int list
    The list to be used.
  • var int data
    The value to be appended.

List_AddFront

Adds a value before the first element of the list.

func void List_AddFront(var int list, var int data)
-
Parameters
  • var int list
    The list to be used.
  • var int data
    The value to be appended.

List_AddOffset

Inserts a value between two list elements.

func void List_AddOffset(var int list, var int offset, var int data)
-
Parameters
  • var int list
    The list to be used.
  • var int offset
    The number of the list element after which the value is inserted.
  • var int data
    The value to be appended.

List_Set

Sets a list element to a specific value.

func void List_Set(var int node, var int data)
-
Parameters
  • var int node
    Pointer to a list element.
  • var int data
    The value to be written into the list element.

List_Get

Retrieves the value of a list element.

func int List_Get(var int list, var int nr)
-
Parameters
  • var int list
    The list to be used.
  • var int nr
    The number of the list element.

Return value

The function returns the value of the specified list element.

List_Node

Returns a pointer to a list element.

func int List_Node(var int list, var int nr)
-
Parameters
  • var int list
    The list to be used.
  • var int nr
    The number of a list element.

Return value

The function returns a pointer to the specified list element.

List_Length

Returns the length of the list (number of all elements).

func int List_Length(var int list)
-
Parameters
  • var int list
    The list to be used.

Return value

The function returns the number of elements in the list.

List_HasLength

Checks if the list has the specified length.

func int List_HasLength(var int list, var int length)
-
Parameters
  • var int list
    The list to be used.
  • var int length
    The desired length.

Return value

The function returns a boolean value indicating whether the list has the specified length or not.

List_End

Returns the last list element of the list.

func int List_End(var int list)
-
Parameters
  • var int list
    The list to be used.

Return value

The function returns a pointer to the last list element.

List_Concat

Concatenates two lists.

func void List_Concat(var int list, var int list2)
-
Parameters
  • var int list
    The first list.
  • var int list2
    The second list. Its beginning is appended to the end of the first list.

List_Contains

Returns the last list element with a specific value.

func int List_Contains(var int list, var int data)
-
Parameters
  • var int list
    The list to be used.
  • var int data
    The value to search for.

Return value

The function returns the number of the last list element with the value data.

List_For

Calls a function for each list element, passing a pointer to the list element as a parameter.

func void List_For(var int list, var string function)
-
Parameters
  • var int list
    The list to be used.
  • var string function
    Name of a function to be called for each list element (void handler(var int node)).

List_ForF

Similar to List_For, but with a function parameter instead of a string.

func void ListForF(var int list, var func function)
-
Parameters
  • var int list
    The list to be used.
  • var func function
    The function to be called for each list element (void handler(var int node)).

List_ForI

Similar to List_For, but with a function parameter instead of a string.

func void List_ForI(var int list, var int funcID)
-
Parameters
  • var int list
    The list to be used.
  • var int funcID
    ID of a function to be called for each list element (void handler(var int node)).

List_Delete

Deletes a list element. All subsequent elements shift position.

func void List_Delete(var int list, var int nr)
-
Parameters
  • var int list
    The list to be used.
  • var int nr
    The number of the list element to be deleted.

List_Destroy

Destroys the entire list.

func void List_Destroy(var int list)
-
Parameters
  • var int list
    The list to be destroyed.

List_ToArray

Returns a pointer to a memory area containing all values of the list.

func int List_ToArray(var int list)
-
Parameters
  • var int list
    The list to be used.

Return value

The function returns a memory area containing all the values of the list.

List_MoveDown

Moves the specified list node down by one position in the list.

func void List_MoveDown(var int list, var int node)
-
Parameters
  • var int list
    The list in which the node is located.
  • var int node
    The node to be moved down.

List_MoveUp

Moves the specified list node up by one position in the list.

func void List_MoveUp(var int list, var int node)
-
Parameters
  • var int list
    The list in which the node is located.
  • var int node
    The node to be moved up.

List_InsertSorted

Inserts a value into a sorted list while preserving the sort order.

func void List_InsertSorted(var int list, var int data, var func compare)
-
Parameters:
  • var int list
    The list to insert the value into.
  • var int data
    The value to be inserted.
  • var func compare
    A comparison function used to determine the sort order.

List_Compare

func int List_Compare(var int data1, var int data2, var func compare)
-
Parameters:
  • var int data1
    The first integer value.
  • var int data2
    The second integer value.
  • var func compare
    One of comparison functions. Return value

The function returns the return value of specified comparison function.

Comparison Functions

The following comparison functions can be used as the compare parameter in the List_InsertSorted and List_Compare function:

List_CmpAscending

Compares two integer values in ascending order.

func int List_CmpAscending(var int data1, var int data2)
-
Parameters:
  • var int data1
    The first integer value.
  • var int data2
    The second integer value.

Return Value:

The function returns TRUE if data1 is greater than data2, FALSE is returned otherwise.

List_CmpDescending

Compares two integer values in descending order.

func int List_CmpDescending(var int data1, var int data2)
-
Parameters:
  • var int data1
    The first integer value.
  • var int data2
    The second integer value.

Return Value:

The function returns TRUE if data1 is less than data2, FALSE is returned otherwise.

List_CmpAscendingUnsigned

Compares two unsigned integer values in ascending order.

func int List_CmpAscendingUnsigned(var int data1, var int data2)
-
Parameters:
  • var int data1
    The first unsigned integer value.
  • var int data2
    The second unsigned integer value.

Return Value:

The function returns TRUE if data1 is greater than data2, FALSE is returned otherwise.

List_CmpDescendingUnsigned

Compares two unsigned integer values in descending order.

func int List_CmpDescendingUnsigned(var int data1, var int data2)
-
Parameters:
  • var int data1
    The first unsigned integer value.
  • var int data2
    The second unsigned integer value.

Return Value:

The function returns TRUE if data1 is less than data2, FALSE is returned otherwise.

\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/lego/tools/locals/index.html b/cs/zengin/scripts/extenders/lego/tools/locals/index.html deleted file mode 100644 index 09e6b1df05..0000000000 --- a/cs/zengin/scripts/extenders/lego/tools/locals/index.html +++ /dev/null @@ -1,51 +0,0 @@ - Locals - Gothic Modding Community

Locals

Daedalus doesn't offer any local variables, which can quickly lead to problems with recursive functions. The Locals package allows variables to be saved temporarily on a pseudo-stack. Locals is a very specific package. People who work normally with Daedalus will probably never need it. There is also the final function, which can be used to emulate something similar to the final clause in Java.

Dependencies

Initialization

N/A

Implementation

Locals.d on GitHub

Functions

Locals

All that has to be done to enable the Locals is to write this function at the beginning of the function that should receive "real" local variables.

func void locals()
-

Final

It is hard to explain how to use it, but very easy to understand once you've seen an example.

func int Final()
-
Example

With final() it is very easy to emulate Java's final clause, i.e. a block of code can be specified, which is executed after this function is exited, regardless of when or where the function is exited.

1
-2
-3
-4
-5
-6
-7
-8
func void testFinal()
-{
-    if (final())
-    {
-        MEM_InfoBox("Final was called.");
-    };
-    MEM_InfoBox("This will appear before Final");
-};
-
Few lines of code say more than a thousand words.
\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/lego/tools/misc/index.html b/cs/zengin/scripts/extenders/lego/tools/misc/index.html deleted file mode 100644 index 2f6a8c26cb..0000000000 --- a/cs/zengin/scripts/extenders/lego/tools/misc/index.html +++ /dev/null @@ -1,43 +0,0 @@ - Misc - Gothic Modding Community

Misc

The Misc package introduces various helper functions that did not fit into any other package.

Dependencies

Initialization

N/A

Implementation

Misc.d on GitHub

Constants

Misc package implements the phi constant

const int phi = 1070141312; // PI/2
-
which is actually pi divided by 2 saved as an ikarus float.

Decimal: 1.5707...

Functions

atan2f

Calculates the arcus tangent of an angle between the origin and (x, y) point.

func int atan2f(var int x, var int y)
-
Parameters
  • var int x
    X-coordinate
  • var int y
    Y-coordinate

Return value

The function returns arcus tangent in radians as Ikarus float.

sin

Calculates the sine of an angle given in radians.

func int sin(var int angle)
-
Parameters
  • var int angle
    The angle in radians as a Ikarus float

Return value

The function returns sine of the angle as Ikarus float.

cos

Calculates the cosine of an angle given in radians.

func int cos(var int angle)
-
Parameters
  • var int angle
    The angle in radians as a Ikarus float

Return value

The function returns cosine of the angle as Ikarus float.

tan

Calculates the tangent of an angle given in radians.

func int tan(var int angle)
-
Parameters
  • var int angle
    The angle in radians as a Ikarus float

Return value

The function returns tangent of the angle as Ikarus float.

asin

Calculates the arcus sine.

func int asin(var int sine)
-
Parameters
  • var int sine
    The sine of an angle as a Ikarus float

Return value

The function returns arcus sine of the angle as Ikarus float.

acos

Calculates the arcus cosine

func int acos(var int cosine)
-
Parameters
  • var int cosine
    The cosine of an angle as a Ikarus float

Return value

The function returns arcus cosine of the angle as Ikarus float.

distance2D

Calculates the distance between two points on a two-dimensional plane.

func int distance2D(var int x1, var int x2, var int y1, var int y2)
-
Parameters
  • var int x1
    X-coordinate of the first point
  • var int x2
    X-coordinate of the second point
  • var int y1
    Y-coordinate of the first point
  • var int y2
    Y-coordinate of the second point

Return value

The function returns the distance between the two points.

distance2Df

Calculates the distance between two points on a two-dimensional plane but parameters and return values are Ikarus floats.

func int distance2Df(var int x1, var int x2, var int y1, var int y2)
-
Parameters
  • var int x1
    X-coordinate of the first point
  • var int x2
    X-coordinate of the second point
  • var int y1
    Y-coordinate of the first point
  • var int y2
    Y-coordinate of the second point

Return value

The function returns the distance between the two points as Ikarus float.

\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/lego/tools/permmem/index.html b/cs/zengin/scripts/extenders/lego/tools/permmem/index.html deleted file mode 100644 index f56e8d52e3..0000000000 --- a/cs/zengin/scripts/extenders/lego/tools/permmem/index.html +++ /dev/null @@ -1,86 +0,0 @@ - PermMem - Gothic Modding Community

PermMem

PermMem is a powerful package that allows classes (or instances) to be used permanently even after loading or restarting by saving them to the ASCII .ZEN archive in the savegame directory. PermMem manages handles that are used to access instances, and provides various functions to manipulate these handles and instances.

Dependencies

Initialization

Initialize with LeGo_PermMem flag.

LeGo_Init(LeGo_PermMem);
-

Implementation

PermMem.d on GitHub

Functions

new

Creates a handle to a new instance of inst.

func int new(var int inst)
-
Parameters
  • var int inst
    A valid instance. Used as "constructor"

Return value

The function returns a new, valid PermMem handle.

create

Similar to new, but here a pointer is returned directly and not a handle. Caution! Not managed by PermMem!

func int create(var int inst)
-
Parameters
  • var int inst
    A valid instance. Used as "constructor"

Return value

The function returns a pointer to the new instance.

wrap

"Wraps" a handle "around" a pointer so that the pointer can be used with any function that expects handles. Only conditionally managed by PermMem.

func int wrap(var int inst, var int ptr)
-
Parameters
  • var int inst
    A valid instance. Determines the type of the handle
  • var int ptr
    Pointer to wrap

Return value

The function returns a handle with ptr as content.

clear

Cleans the handle. After that it is invalid.

func void clear(var int hndl)
-
Parameters
  • var int hndl
    Valid PermMem handle

release

Frees the handle. The reserved memory is not deleted, the handle becomes invalid.

func void release(var int hndl)
-
Parameters
  • var int hndl
    Valid PermMem handle

delete

Cleans the handle just like clear, only the destructor is also called.

func void delete(var int hndl)
-
Parameters
  • var int hndl
    Valid PermMem handle

free

Similar to delete, only here a pointer is destroyed and not a handle. Caution! Not managed by PermMem!

func void free(var int ptr, var int inst)
-
Parameters
  • var int ptr
    The pointer to be cleaned
  • var int inst
    Instance used in create function.

get

Returns the instance of the handle.

func instance get(var int hndl)
-
Parameters
  • var int hndl
    Valid PermMem handle

getPtr

Returns a pointer to instance of handle.

func int getPtr(var int hndl)
-
Parameters
  • var int hndl
    Valid PermMem handle

setPtr

Sets the pointer of a handle.

func void setPtr(var int hndl, var int ptr)
-
Parameters
  • var int hndl
    Valid PermMem handle
  • var int ptr
    New pointer for handle

getInst

Returns the instance used to create the given handle in new function.

func int getInst(var int hndl)
-
Parameters
  • var int hndl
    Valid PermMem handle

numHandles

Returns the number of handles managed by PermMem.

func int numHandles()
-

sizeof

Gets the size of the given instance's class.

func int sizeof(var int inst)
-
Parameters
  • var int inst
    Any instance

Return value

The function returns the size of a given instance's class in bytes.

Hlp_IsValidHandle

Indicates whether the handle exists and is managed by PermMem.

func int Hlp_IsValidHandle(var int hndl)
-
Parameters
  • var int hndl
    PermMem's handle

Return value

The function returns TRUE if the handle is valid (managed by PermMem), FALSE is returned otherwise.

Example

The example function that use Hlp_IsValidHandle is Bar_SetMax form LeGo Bars package. The function first checks if the handle is valid, then gets the instance and changes its parameters.

1
-2
-3
-4
-5
-6
func void Bar_SetMax(var int bar, var int max) 
-{
-    if(!Hlp_IsValidHandle(bar)) { return; };
-    var _bar b; b = get(bar);
-    b.valMax = max;
-};
-

foreachHndl

Executes a function for each handle of an instance.

func void foreachHndl(var int inst, var func fnc)
-
Parameters
  • var int inst
    The function is called for this instance
  • var int inst
    This function is called. The signature is function(int handle)

hasHndl

Checks if PermMem has a handle of this instance.

func int hasHndl(var int inst)
-
Parameters
  • var int inst
    Instance to be checked

Return value

The function returns TRUE if the PermMem has a handle of this instance, FALSE is returned otherwise.

MEM_ReadStringArray

Function moved to PermMem form Ikarus. Reads string from the array at the arrayAddress.

func string MEM_ReadStringArray(var int arrayAddress, var int index)
-
Parameters
  • var int arrayAddress
    Memory address of array
  • var int offset
    Array offset (array index)

Return value

The function returns string from the array if the address is correct.

PM_Exists

Checks if the specified field already exists in the archive. (used with archiver/unarchiver)

func int PM_Exists(var string name)
-
Parameters
  • var string name
    Name of the field

Return value

The function returns TRUE if the field exists in the archive, FALSE is returned otherwise.

Archiver

PM_SaveInt

Saves an integer to the archive.

func void PM_SaveInt (var string name, var int val)
-
Parameters
  • var string name
    Name of the field in saved archive
  • var int val
    Value of the saved integer

PM_SaveFloat

Saves a daedalus float to the archive.

func void PM_SaveFloat (var string name, var int flt)
-
Parameters
  • var string name
    Name of the field in saved archive
  • var int flt
    Value of the saved float

PM_SaveString

Saves a string to the archive.

func void PM_SaveString (var string name, var string val)
-
Parameters
  • var string name
    Name of the field in saved archive
  • var string val
    Saved string

PM_SaveFuncID

Saves a function ID to the archive.

func void PM_SaveFuncID(var string name, var int fnc)
-
Parameters
  • var string name
    Name of the field in saved archive
  • var int fnc
    Saved function ID

PM_SaveFuncOffset

Saves a function offset to the archive.

func void PM_SaveFuncOffset(var string name, var int fnc)
-
Parameters
  • var string name
    Name of the field in saved archive
  • var int fnc
    Saved function offset

PM_SaveFuncPtr

Saves a function pointer to the archive.

func void PM_SaveFuncPtr(var string name, var int fnc)
-
Parameters
  • var string name
    Name of the field in saved archive
  • var int fnc
    Saved function pointer

PM_SaveClassPtr

Saves a pointer of a class to the archive.

func void PM_SaveClassPtr(var string name, var int ptr, var string className)
-
Parameters
  • var string name
    Name of the field in saved archive
  • var int ptr
    Saved pointer
  • var string className
    Name of the class of stored pointer

PM_SaveClass

Saves a class like PM_SaveClassPtr.

func void PM_SaveClass(var string name, var int ptr, var string className)
-
Parameters
  • var string name
    Name of the field in saved archive
  • var int ptr
    Saved class pointer
  • var string className
    Name of the class of stored pointer

PM_SaveIntArray

Saves an array of integers.

func void PM_SaveIntArray(var string name, var int ptr, var int elements)
-
Parameters
  • var string name
    Name of the field in saved archive
  • var int ptr
    Pointer to the array
  • var int elements
    Number of elements in array

PM_SaveStringArray

Saves an array of integers.

func void PM_SaveStringArray(var string name, var int ptr, var int elements)
-
Parameters
  • var string name
    Name of the field in saved archive
  • var int ptr
    Pointer to the array
  • var int elements
    Number of elements in array

Unarchiver

PM_Load

Universal function to load integers, floats, class pointers and int arrays.

func int PM_Load(var string name)
-
Parameters
  • var string name
    Name of the loaded field

Return value The function returns the data existing in the archive at the given field.

PM_LoadInt

Returns an integer stored in the archive.

func int PM_LoadInt(var string name)
-
Parameters
  • var string name
    Name of the loaded field

PM_LoadFloat

Returns a daedalus float stored in the archive.

func int PM_LoadFloat(var string name)
-
Parameters
  • var string name
    Name of the loaded field

PM_LoadString

Returns a string stored in the archive.

func string PM_LoadString(var string name)
-
Parameters
  • var string name
    Name of the loaded field

PM_LoadFuncID

Returns a function ID stored in the archive.

func int PM_LoadFuncID(var string name)
-
Parameters
  • var string name
    Name of the loaded field

PM_LoadFuncOffset

Returns a function offset stored in the archive.

func int PM_LoadFuncOffset(var string name)
-
Parameters
  • var string name
    Name of the loaded field

PM_LoadFuncPtr

Returns a function pointer stored in the archive.

func int PM_LoadFuncPtr(var string name)
-
Parameters
  • var string name
    Name of the loaded field

PM_LoadClassPtr

Returns a class pointer stored in the archive.

func int PM_LoadClassPtr(var string name)
-
Parameters
  • var string name
    Name of the loaded field

PM_LoadClass

Loads a pointer to the class from the archive to destPtr.

func void PM_LoadClass(var string name, var int destPtr)
-
Parameters
  • var string name
    Name of the loaded field
  • var int destPtr
    Destination pointer, the address to where it will deserialize the saved data

PM_LoadArray

Returns a pointer to array stored in the archive.

func int PM_LoadArray(var string name)
-
Parameters
  • var string name
    Name of the loaded field

PM_LoadArrayToPtr

Loads a pointer to array from the archive to destPtr.

func void PM_LoadArrayToPtr(var string name, var int destPtr)
-
Parameters
  • var string name
    Name of the loaded field
  • var int destPtr
    Destination pointer, the address to where it will deserialize the saved data

PM_LoadToPtr

Universal function to load array or class pointer from the archive to destPtr.

func void PM_LoadToPtr(var string name, var int destPtr)
-
Parameters
  • var string name
    Name of the loaded field
  • var int destPtr
    Destination pointer, the address to where it will deserialize the saved data
\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/lego/tools/queue/index.html b/cs/zengin/scripts/extenders/lego/tools/queue/index.html deleted file mode 100644 index 3fcb03b534..0000000000 --- a/cs/zengin/scripts/extenders/lego/tools/queue/index.html +++ /dev/null @@ -1,48 +0,0 @@ - Queue - Gothic Modding Community

Queue

This package is an implementation of the Queue data structure and a queue for function calls.

Dependencies

Initialization

N/A

Implementation

Queue.d on GitHub

Queue

Q_Create

Creates a new queue and returns a handle to it.

func int Q_Create()
-
Return value

The function returns a handle to a queue.

Q_Enqueue

Appends an integer to the back of the queue

func void Q_Enqueue(var int queue, var int value)
-
Parameters
  • var int queue
    Handle of a queue
  • var int value
    The value to be appended to the queue

Q_IsEmpty

Checks if the queue is empty.

func int Q_IsEmpty(var int queue)
-
Parameters
  • var int queue
    Handle of a queue

Return value

The function returns TRUE if the queue is empty, FALSE is returned otherwise.

Q_Advance

Removes the oldest value from the queue and returns it.

func int Q_Advance(var int queue)
-
Parameters
  • var int queue
    Handle of a queue

Return value

The function returns the oldest value in the queue.

Q_Peek

Returns the oldest value in the queue without removing it.

func int Q_Peek(var int queue)
-
Parameters
  • var int queue
    Handle of a queue

Return value

The function returns the oldest value in the queue.

Q_For

Function with the funcID is called with every element of the list as parameter.
The list element is passed to the function as a zCList pointer.

func void Q_For(var int queue, var int funcID)
-
Parameters
  • var int queue
    Handle of a queue
  • var int funcID
    ID of function that is executed for all values in the queue (signature: void (zCList*))

Q_ForF

Like Q_For, but with function as a parameter instead of a function ID.

func void Q_ForF(var int queue, var func f)
-
Parameters
  • var int queue
    Handle of a queue
  • var func f
    This function is executed for all values in the queue (signature: void (zCList*))

CallbackQueue

CQ_Create

Creates a new callback queue and returns a handle to it.

func int CQ_Create()
-
Return value

The function returns a handle to a callback queue.

CQ_EnqueueNoData

Appends a function to the callback queue.

func void CQ_EnqueueNoData(var int queue, var func function)
-
Parameters
  • var int queue
    Handle of a callback queue
  • var func function
    A function with no return value, expecting no parameter

CQ_EnqueueData

Appends a function together with a value to the callback queue.

func void CQ_EnqueueData(var int queue, var func function, var int data)
-
Parameters
  • var int queue
    Handle of a callback queue
  • var func function
    A function with no return value, expecting an integer as a parameter.
  • var int data
    When calling function, this value is passed as a parameter

CQ_Enqueue

Appends a function together with an optional value to the callback queue. This function should not usually be used. Use CQ_EnqueueData and CQ_EnqueueNoData instead.

func void CQ_Enqueue(var int queue, var int funcID, var int data, var int hasData)
-
Parameters
  • var int queue
    Handle of a callback queue
  • var int funcID
    The function ID of a function to be appended to the callback queue.
  • var int data
    If hasData is not 0, this value is passed to the associated function.
  • var int hasData
    Must be 0 if the function does not expect an integer as a parameter, otherwise not 0.

CQ_IsEmpty

Checks if no function is in the callback queue.

func int CQ_IsEmpty(var int queue)
-
Parameters
  • var int queue
    Handle of a callback queue

Return value

The function returns TRUE if the callback queue is empty, FALSE is returned otherwise.

CQ_Advance

Executes the foremost function of the callback queue and removes it from the callback queue.

func void CQ_Advance(var int queue)
-
Parameters
  • var int queue
    Handle of a callback queue

CQ_Exhaust

Executes all functions contained in the callback queue.

func void CQ_Exhaust(var int queue)
-
Parameters
  • var int queue
    Handle of a callback queue
\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/lego/tools/random/index.html b/cs/zengin/scripts/extenders/lego/tools/random/index.html deleted file mode 100644 index 79c6d84e93..0000000000 --- a/cs/zengin/scripts/extenders/lego/tools/random/index.html +++ /dev/null @@ -1,40 +0,0 @@ - Random - Gothic Modding Community

Random

Provides more random randomization than Hlp_Random() function.

Dependencies

N/A

Initialization

Initialize with LeGo_Random flag.

LeGo_Init(LeGo_Random);
-

Implementation

Random.d on GitHub

Functions

r_Next

Returns a random number.

func int r_Next()
-
Return value

The function returns a random number.

r_Max

Returns a random number from 0 to max.

func int r_Max(var int max)
-
Parameters
  • var int max
    Maximum value of number

Return value

The function returns a random number from 0 to 'max'.

r_MinMax

Returns a random number from 'min' to 'max'.

func int r_MinMax(var int min, var int max)
-
Parameters
  • var int max
    Maximum value of number
  • var int min
    Minimum value of number

Return value

The function returns a random number from min to max.

r_Init

Initializes the random number generator. Happens optionally in LeGo_Init.

func void r_Init(var int seed)
-
Parameters
  • var int seed
    The initializing value

r_DefaultInit

Initializes the random number generator based on the current time.

func void r_DefaultInit()
-
\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/lego/tools/string_builder/index.html b/cs/zengin/scripts/extenders/lego/tools/string_builder/index.html deleted file mode 100644 index b9cd64743c..0000000000 --- a/cs/zengin/scripts/extenders/lego/tools/string_builder/index.html +++ /dev/null @@ -1,155 +0,0 @@ - StringBuilder - Gothic Modding Community

StringBuilder

The StringBuilder is a package, designed to easily concatenate multiple elements into a string (without ConcatStrings and IntToString).

All created StringBuilders are transient. All functions starting from SB_InitBuffer, including it, use the active StringBuilder set with SB_New or SB_Use, so there is no var int stringBuilder parameter in functions. A look at the example explains what I mean.

Warning

The StringBuilder works with pointers, not handles like many other LeGo packages.

Dependencies

N/A

Initialization

N/A

Implementation

StringBuilder.d on GitHub

Functions

SB_New

Creates and returns a new StringBuilder. At the same time, this new StringBuilder is set as active. (See SB_Use.)

func int SB_New()
-
Return value

The function returns a pointer to a new StringBuilder.

SB_Use

Marks this StringBuilder as active. It can now be used with the functions.

func void SB_Use(var int sb)
-
Parameters
  • var int sb
    Pointer to a StringBuilder, returned from SB_New

SB_Get

Returns the active StringBuilder.

func int SB_Get()
-
Return value

The function returns the active StringBuilder object - last set with SB_Use or just created with SB_New.

SB_InitBuffer

If the size of the resulting string is already known, the buffer can be set manually. This is usually not necessary.

func void SB_InitBuffer(var int size)
-
Parameters
  • var int size
    Size in bytes. Warning! Only works if the StringBuilder has been newly created!

SB_Clear

Empties the current StringBuilder. It is not destroyed in the process, so it can be used again. If the object has a buffer allocated, the buffer is freed.

func void SB_Clear()
-

SB_Release

Releases the current stream of the StringBuilder. The StringBuilder is destroyed, and the stream can be obtained via SB_GetStream.

func void SB_Release()
-

SB_Destroy

Completely destroys the StringBuilder.

func void SB_Destroy()
-

SB_ToString

Returns a copy of the stream as a string.

func string SB_ToString()
-
Return value

The function returns the copy of the active StringBuilder as a string. If the StringBuilder object doesn't have a buffer allocated, an empty string is returned.

SB_ToStream

Returns a copy of the stream in raw format.

func int SB_ToStream()
-
Return value

The function returns a copy of the stream in raw format (char[])

SB_GetStream

Doesn't copy the stream, but returns it as it is.

func int SB_GetStream()
-
Return value

The function returns the stream as it is. SB_Destroy or SB_Clear destroy the returned pointer.

SB_Length

Returns the current length of the stream. Similar to STR_Len from Ikarus .

func int SB_Length()
-
Return value

The function returns the current length of the active StringBuilder.

SB_SetLength

Sets the length of the stream. When increasing, zero bytes are appended.

func void SB_SetLength(var int length)
-

Stream operations

SB

Appends a string, to the active StringBuilder.

func void SB(var string s)
-
Parameters
  • var string s
    The appended string

SBi

Appends an integer in text form, to the active StringBuilder.

func void SBi(var int i)
-
Parameters
  • var int i
    The appended integer

SBc

Appends a byte, to the active StringBuilder. (e.g. 82 for 'R' - An ASCII table can be quickly found)

func void SBc(var int c)
-
Parameters
  • var int c
    The appended byte (ASCII table character)

SBraw

Appends a raw bytes array, to the active StringBuilder.

func void SBraw(var int ptr, var int len)
-
Parameters
  • var int ptr
    Pointer to the appended array
  • var int len
    Length of an array

SBflt

Appends a Daedalus float in text form, to the active StringBuilder.

func void SBflt(var float x)
-
Parameters
  • var float x
    The appended Daedalus float value

SBf

Appends an Ikarus float in text form, to the active StringBuilder.

func void SBf(var int x)
-
Parameters
  • var float x
    The appended Ikarus float value

SBw

Appends a 4-byte raw data (interpreted as an integer x), to the active StringBuilder.

func void SBw(var int x)
-
Parameters
  • var int i
    The appended value

Independent Functions

STR_Escape

Makes escape sequences out of non-writable characters. For example, newline character \n becomes \\n, tab character \t becomes \\t, etc.

func string STR_Escape(var string s0)
-
Parameters
  • var string s0
    The string to be added escape sequences

Return value

The function returns a new string with escape sequences added for special characters.

STR_Unescape

Counterpart to STR_Escape. Escape sequences like \n, \r or \t are converted back.

func string STR_Unescape(var string s0)
-
Parameters
  • var string s0
    The string to be removed escape sequences

Return value

The function returns a new string with escape sequences replaced by their corresponding characters.

STR_StartsWith

Checks if the input string s starts with the specified prefix string.

func int STR_StartsWith(var string str, var string start) 
-
Parameters
  • var string str
    The string to be checked
  • var string start
    The searched prefix

Return value

The function returns TRUE if the string starts with the prefix, FALSE is returned otherwise.

Additional Functions

BuildStringSymbolsArray

Creates an array of all string symbols found in the parser's string table.

func int BuildStringSymbolsArray()
-
Return value

The function returns created array.

GetStringSymbolByAddr

Retrieves the symbol at the specified address from the string table.

func int BuildStringSymbolsArray()
-
Return value

The function returns a parser symbol at the given address.

Examples

Basic functionality

This is how function that builds a string looks without StringBuilder:

1
-2
-3
-4
-5
-6
-7
-8
func void PrintMyNumbers(var int x0, var int x1, var int x2) {
-    var string res;
-    res = ConcatStrings(IntToString(x0), ", ");
-    res = ConcatStrings(res, IntToString(x1));
-    res = ConcatStrings(res, ", ");
-    res = ConcatStrings(res, IntToString(x2));
-    PrintS(res);
-};
-
And now the function that uses StringBulider:
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
func void PrintMyNumbers(var int x0, var int x1, var int x2) {
-    var int s; s = SB_New();  // Create StringBuilder
-    SBi(x0);                  // Append Int
-    SB (", ");                // Append string
-    SBi(x1);                  // Append Int
-    SB (", ");                // Append string
-    SBi(x2);                  // Append Int
-    PrintS(SB_ToString());    // Get output as a string
-    SB_Destroy();             // Destroy StringBuilder
-};
-
Looks much more pleasant, right? But why do we create a StringBuilder and then not use it? The idea is the following: A StringBuilder is created with SB_New() and set as the active StringBuilder in the background. The package only supports one StringBuilder at a time, which will keep the pointer in case we want to use another StringBuilder in between.

Multiple StringBuilders

Simple example. We want to fill two StringBuilders at the same time and then return them combined:

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
func string Example2() {
-    // Create two StringBuilders:
-    var int s0; s0 = SB_New();
-    var int s1; s1 = SB_New();
-
-    // Set the first StringBuilder as active and fill it.
-    SB_Use(s0);
-    SB("Hello ");
-    SB("World!");
-
-    // Set the second StringBuilder as active and fill it.
-    SB_Use(s1);
-    SB("This is ");
-    SB("the hero speaking!");
-
-    // Now we want to combine the two StringBuilders.
-    // The system doesn't actually provide for such an operation, but it can still be done using a helper string
-    var string str; str = SB_ToString(); // This string now says “This is the hero speaking!”
-
-    SB_Use(s0);
-    SB(" ");
-    SB(str);
-
-    str = SB_ToString(); // Now "Hello world! This is the hero speaking!" are in the string.
-
-    // The rest is already known, we destroy StringBuilders
-    SB_Destroy();
-    SB_Use(s1);
-    SB_Destroy();
-
-    return str;
-};
-
\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/lego/tools/talents/index.html b/cs/zengin/scripts/extenders/lego/tools/talents/index.html deleted file mode 100644 index 83d13957b8..0000000000 --- a/cs/zengin/scripts/extenders/lego/tools/talents/index.html +++ /dev/null @@ -1,40 +0,0 @@ - Talents - Gothic Modding Community

Talents

The Talents package does two things:

  1. save any number of values for a specific NPC (effectively AIVar array extension).
  2. identify NPC by unique ID.

Talents package uses one free AIVar variables, the default is AIVar with the index 89 that can be customized in Userconst.d the AIV_TALENT constant.

Dependencies

Initialization

Initialize with LeGo_PermMem flag.

LeGo_Init(LeGo_PermMem);
-

Implementation

Talents.d on GitHub

Functions

Npc_GetID

Returns unique ID specific for provided NPC.

func int Npc_GetID(var C_NPC slf)
-
Parameters
  • var C_NPC slf
    NPC to get ID

Return value

The function returns NPCs unique ID.

Npc_FindByID

Finds the NPC pointer of an NPC with the given ID.

func int Npc_FindByID(var int ID)
-
Parameters
  • var int ID
    NPC ID

Return value

The function returns NPC pointer.

TAL_CreateTalent

Creates a talent into which you can later save a value for every NPC (just like AI_Var).

func int TAL_CreateTalent()
-
Return value

The function returns value that can be later used as a talent ID.

TAL_SetValue

Sets a new value to the specified talent.

func void TAL_SetValue(var C_NPC npc, var int talent, var int value)
-
Parameters
  • var C_NPC npc
    Set the talent value for this NPC
  • var int talent
    Talent ID
  • var int value
    Value to be set

TAL_GetValue

Returns the value of a saved talent for specified NPC.

func int TAL_GetValue(var C_NPC npc, var int talent)
-
Parameters
  • var C_NPC npc
    Get the talent value from this NPC
  • var int talent
    Talent ID
\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/lego/tools/timer/index.html b/cs/zengin/scripts/extenders/lego/tools/timer/index.html deleted file mode 100644 index 0592b4c86e..0000000000 --- a/cs/zengin/scripts/extenders/lego/tools/timer/index.html +++ /dev/null @@ -1,41 +0,0 @@ - Timer - Gothic Modding Community

Timer

Timer is a better alternative to the timers that Gothic offers. The FrameFunctions and Anim8 packages are already based on it. It isn't possible to modify the current time, as this would only cause difficulties.

Dependencies

N/A

Initialization

Initialize with LeGo_Timer flag.

LeGo_Init(LeGo_Timer);
-

Implementation

Timer.d on GitHub

Functions

Timer

Returns the current playing time. If a new game is started, the time is 0. It is measured in milliseconds.

func int Timer()
-
Return value

The function returns current playing time in milliseconds.

TimerGT

Returns the current game time, but the timer is paused when the game is paused (in the menu or status screen).

func int TimerGT()
-
Return value

The function returns current playing time in milliseconds, but without measuring time when game is paused.

TimerF

Alias to Timer function that returns the time as an Ikarus float value.

func int TimerF()
-
Return value

The function returns current playing time as an Ikarus float value.

Timer_SetPause

Pauses the timer (and thus all FrameFunctions and running animations).

func void Timer_SetPause(var int on)
-
Parameters
  • var int on
    Pause on/off

Timer_SetPauseInMenu

The timer can automatically pause when the game is paused. (status screen, main menu...)

func void Timer_SetPauseInMenu(var int on)
-
Parameters
  • var int on
    Automatic pause on/off

Timer_IsPaused

This can be used to query whether the timer is paused.

func int Timer_IsPaused()
-
Return value

The function returns TRUE if the timer is paused, FALSE is returned otherwise.

\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/lego/tools/view/index.html b/cs/zengin/scripts/extenders/lego/tools/view/index.html deleted file mode 100644 index 75d8b6b66f..0000000000 --- a/cs/zengin/scripts/extenders/lego/tools/view/index.html +++ /dev/null @@ -1,84 +0,0 @@ - View - Gothic Modding Community

View

This package can create textures on the screen and work with them in an extended manner.

Dependencies

Initialization

Initialize with LeGo_View flag.

LeGo_Init(LeGo_View);
-

Implementation

View.d on GitHub

Functions

View_Create

Creates a zCView with virtual coordinates.

func int View_Create(var int x1, var int y1, var int x2, var int y2) 
-
Parameters
  • var int x1/var int y1
    Top-left corner coordinates (virtual)
  • var int x2/var int y2
    Bottom-right corner coordinates (virtual)

Return value

The function returns a PermMem handle to a zCView.

View_CreatePxl

Alias for View_Create using pixel coordinates.

func int View_CreatePxl(var int x1, var int y1, var int x2, var int y2) 
-
Parameters
  • var int x1/var int y1
    Top-left corner coordinates (pixel)
  • var int x2/var int y2
    Bottom-right corner coordinates (pixel)

Return value

The function returns a PermMem handle to a zCView.

View_CreateCenter

Creates a zCView with virtual coordinates centered.

func int View_CreateCenter(var int x, var int y, var int width, var int height)
-
Parameters
  • var int x
    Horizontal position
  • var int y
    Vertical position
  • var int width
    Width of the view
  • var int height
    Height of the view

Return value

The function returns a PermMem handle to a zCView.

View_CreateCenterPxl

Alias for View_CreateCenter using pixel coordinates.

func int View_CreateCenterPxl(var int x, var int y, var int width, var int height)
-
Parameters
  • var int x
    Horizontal position
  • var int y
    Vertical position
  • var int width
    Width of the view
  • var int height
    Height of the view

Return value

The function returns a PermMem handle to a zCView.

View_Get

Alias for get form PermMem.

zCView View_Get(var int hndl)
-
Parameters

View_GetPtr

Alias for getPtr form PermMem.

func int View_GetPtr(var int hndl)
-
Parameters

View_Render

Renders a zCView. Should be used sparingly, as it works only in specific cases.

func void View_Render(var int hndl)
-
Parameters

View_SetTexture

Assigns a texture to a view. The key function of this package.

func void View_SetTexture(var int hndl, var string texture)
-
Parameters
  • var int hndl
    Handle created with View_Create
  • var string texture
    Filename of a texture

View_GetTexture

Gets the name of a previously assigned texture.

func string View_GetTexture(var int hndl)
-
Parameters

Return value

The function returns the previously assigned texture.

View_SetColor

Sets the color of a view.

func void View_SetColor(var int hndl, var int color)
-
Parameters
  • var int hndl
    Handle created with View_Create
  • var int color
    zColor, can be created with RGBA

View_GetColor

Gets the color of a view.

func int View_GetColor(var int hndl)
-
Parameters

Return value

The function returns the full zColor.

View_Open

Opens a view. It will be displayed on the screen.

func void View_Open(var int hndl)
-
Parameters

View_Close

Closes a view. It disappears from the screen but can still be used.

func void View_Close(var int hndl)
-
Parameters

View_Delete

Alias for delete.

`zCView` View_Delete(var int hndl)
-
Parameters

View_Resize

Scales a view to a virtual size. The top-left position of the view remains fixed.

func void View_Resize(var int hndl, var int width, var int height)
-
Parameters
  • var int hndl
    Handle created with View_Create
  • var int width
    New width of the view
  • var int height
    New height of the view

View_ResizePxl

Alias for View_Resize using pixel coordinates.

func void View_ResizePxl(var int hndl, var int width, var int height)
-
Parameters
  • var int hndl
    Handle created with View_Create
  • var int width
    New width of the view
  • var int height
    New height of the view

View_Move

Moves the view by virtual units.

func void View_Move(var int hndl, var int x, var int y)
-
Parameters
  • var int hndl
    Handle created with View_Create
  • var int x
    Shift left/right
  • var int y
    Shift up/down

View_MovePxl

Alias for View_Move using pixel coordinates.

func void View_MovePxl(var int hndl, var int x, var int y)
-
Parameters
  • var int hndl
    Handle created with View_Create
  • var int x
    Shift left/right
  • var int y
    Shift up/down

View_MoveTo

Moves the top-left corner of the view to a virtual position.

func void View_MoveTo(var int hndl, var int x, var int y)
-
Parameters
  • var int hndl
    Handle created with View_Create
  • var int x
    New horizontal position (-1 for no change)
  • var int y
    New vertical position (-1 for no change)

View_MoveToPxl

Alias for View_MoveTo using pixel coordinates.

func void View_MoveToPxl(var int hndl, var int x, var int y)
-
Parameters
  • var int hndl
    Handle created with View_Create
  • var int x
    New horizontal position (-1 for no change)
  • var int y
    New vertical position (-1 for no change)

View_AddText

Adds a text line to the view. The position is virtual and relative to the view's position. If the view is moved, the text moves as well.

func void View_AddText(var int hndl, var int x, var int y, var string text, var string font)
-
Parameters
  • var int hndl
    Handle created with View_Create
  • var int x
    Horizontal position
  • var int y
    Vertical position
  • var string text
    Added text
  • var string font
    Used Font

View_DeleteText

Removes all text added with View_AddText.

func void View_DeleteText(var int hndl)
-
Parameters

View_Top

Places the view above all others.

func void View_Top(var int hndl)
-
Parameters

Examples

Display a texture on the screen

Here a texture should be displayed over the entire screen:

1
-2
-3
-4
-5
-6
-7
func void Example1() {
-    var int View; 
-    View = View_Create(0, 0, PS_VMax, PS_VMax); // Virtual coordinates
-    View_SetTexture(View, "MyTexture.tga"); // Assign a texture to the view
-    // display the view on the screen:
-    View_Open(View);
-};
-

This would mean that the texture would be permanently visible on the screen (even after loading/saving/restarting). If we want it to disappear we have to use either View_Delete or View_Close.

Display a texture with pixel coordinates

Now a texture should be displayed at the top right and be 256 x 256 pixels in size:

1
-2
-3
-4
-5
-6
-7
func void Example2() {
-    Print_GetScreenSize();
-    var int View;
-    View = View_CreatePxl(Print_Screen[PS_X] - 256, 0, Print_Screen[PS_X], 256); // Pixel coordinates
-    View_SetTexture(View, "MYTEXTURE.TGA");
-    View_Open(View);
-};
-

To get the size of the screen we use the interface package.

\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/lego/trialoge/index.html b/cs/zengin/scripts/extenders/lego/trialoge/index.html deleted file mode 100644 index 91ea7a0823..0000000000 --- a/cs/zengin/scripts/extenders/lego/trialoge/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/cs/zengin/scripts/extenders/lego/various/userconstants/index.html b/cs/zengin/scripts/extenders/lego/various/userconstants/index.html deleted file mode 100644 index 149e6ba450..0000000000 --- a/cs/zengin/scripts/extenders/lego/various/userconstants/index.html +++ /dev/null @@ -1,34 +0,0 @@ - User constants - Gothic Modding Community

User constants

All constants that the user can either use or even change freely are defined in Userconst.d file.

Read only

These constants may only be used, not changed.

Anim8

These constants are used by Anim8 and Anim8q.

  • const int A8_Constant
    Constant movement speed
  • const int A8_SlowEnd
    Evenly decelerated movement
  • const int A8_SlowStart
    Evenly accelerated movement
  • const int A8_Wait
    Do nothing. The target value is ignored here

Buttons

The following bit masks can be applied to the status of a button:

  • const int BUTTON_ACTIVE
    The button is active, it reacts to the mouse
  • const int BUTTON_ENTERED
    The mouse is "within" the button

Interface

Dimensions

  • const int PS_X and const int PS_Y
    Use with Print_Screen or Print_ToVirtual functions
  • const int PS_VMax
    Highest possible value of a virtual coordinate

Colors

16 basic colors that can be used as zColor parameters

  • const int COL_Aqua
  • const int COL_Black
  • const int COL_Blue
  • const int COL_Fuchsia
  • const int COL_Gray
  • const int COL_Green
  • const int COL_Lime
  • const int COL_Maroon
  • const int COL_Navy
  • const int COL_Olive
  • const int COL_Purple
  • const int COL_Red
  • const int COL_Silver
  • const int COL_Teal
  • const int COL_White
  • const int COL_Yellow

Gamestate

Gamestate can assume these values:

  • const int Gamestate_NewGame
    New game started
  • const int Gamestate_Loaded
    A game has been loaded
  • const int Gamestate_WorldChange
    The world has changed
  • const int Gamestate_Saving
    The game is saved

Cursor

These constants are sent with Cursor_Event:

  • const int CUR_LeftClick
    The left mouse button was pressed
  • const int CUR_RightClick
    The right mouse button was pressed
  • const int CUR_MidClick
    The middle mouse button was pressed
  • const int CUR_WheelUp
    Mouse wheel up
  • const int CUR_WheelDown
    Mouse wheel down

Modifiable

These constants are often used by packages and may be changed freely.

Bloodsplats

  • const int BLOODSPLAT_NUM
    Maximum number on screen
  • const int BLOODSPLAT_TEX
    Highest Texture ID ("BLOODSPLAT" + texID + ".TGA")
  • const int BLOODSPLAT_DAM
    Texture size damage multiplier (damage * 2Bloodsplat_Dam)

Cursor

  • const string Cursor_Texture
    This texture is used to display the cursor (default: "CURSOR.TGA")

Interface

  • const string Print_LineSeperator
    Text boxes can be printed in multiple lines. This character separates the lines from each other.

PrintS

All position and size information is completely virtual:

  • const int PF_PrintX
    Start position on the X axis
  • const int PF_PrintY
    Start position on the Y axis
  • const int PF_TextHeight
    Space between individual lines

The times are given in ms:

  • const int PF_FadeInTime
    Time to fade in the text
  • const int PF_FadeOutTime
    Time to fade out the text
  • const int PF_MoveYTime
    Time needed to "slip down"
  • const int PF_WaitTime
    Time during which the print is fully visible

The font can be modified:

  • const string PF_Font
    Default: FONT_OLD_10_WHITE.TGA

Talents

  • const int AIV_TALENT
    Used AIVar

Dialoggestures

  • const string DIAG_Prefix
    Animation prefix ("DG_")
  • const string DIAG_Suffix
    Animation suffix ("_")
\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/standalone/gameKeyEvents/index.html b/cs/zengin/scripts/extenders/standalone/gameKeyEvents/index.html deleted file mode 100644 index 8d513ce14e..0000000000 --- a/cs/zengin/scripts/extenders/standalone/gameKeyEvents/index.html +++ /dev/null @@ -1,48 +0,0 @@ - gameKeyEvents - Gothic Modding Community

gameKeyEvents

Quick overview

Author: mud-freak
Platform: G1, G2NotR
Category: Engine, Keys

gameKeyEvents.d is a script, which handles key events with the oCGame::HandleEvent hook. Better alternative for FrameFunction with MEM_KeyState with which you don't have to check whether any menu is opened or player is in dialogue or can move etc.

Author's description

I looked up the address within oCGame::HandleEvent. I made it into a universally usable script for Gothic 1 and Gothic 2.

One could argue now that this is not much different from a FrameFunction with MEM_KeyState. The difference is that this approach saves the extra work of checking if any menu is open, whether the player is in a dialog, whether the player may move, etc. Also this function is "event driven", meaning it is really only called when a key is pressed/held instead of every frame in vain. So it's arguably more performant.

Dependencies

Initialization

Call Game_KeyEventInit() in the Init_Global() or other initialization function.

Game_KeyEventInit();
-

Implementation

gameKeyEvents.d on WoG forum

Usage

To add a key pressing detection edit the main function Game_KeyEvent.

1
-2
-3
-4
-5
-6
-7
func int Game_KeyEvent(var int key, var int pressed) {
-    if (key == KEY_LBRACKET) && (pressed) {
-        // Here enter your code.
-        return TRUE;
-    };
-    return FALSE;
-};
-
  • To change detected key rename KEY_LBRACKET to your own key e.g. taken from Ikarus constants.
  • To detect pressing a key leave (pressed) unchanged but if you want to detect holding change it to (!pressed). That's because

    pressed is FALSE: key is held, pressed is TRUE: key press onset

  • To run code when a key is pressed, paste it or call a function where the comment is.
  • To detect more than one key add else if.
\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/standalone/index.html b/cs/zengin/scripts/extenders/standalone/index.html deleted file mode 100644 index 62fac430fa..0000000000 --- a/cs/zengin/scripts/extenders/standalone/index.html +++ /dev/null @@ -1,34 +0,0 @@ - Standalone Scripts - Gothic Modding Community

Standalone Scripts

Over the years Gothic modders have created many useful features to use with Zengin scripts. This section contains documentation for some scripts that are "standalone", meaning they are not part of larger packages, but are often small features to make modders lives easier.

Script Bins

A few people came up with the idea of collecting scripts scattered on the forums, which resulted in the so-called Script Bins.

Warning

Script bins aren't updated frequently, so for the latest updates and new scripts also check the ScriptBin WoG thread.

WoG Script Bin

Script bin made by Kirides containing scripts from German WoG forum.

https://apps.kirides.de/wog-script-bin/

ScriptBin GitHub repository

Lehona has created a GitHub repository that contains scripts from some of the modders.

https://github.com/Lehona/ScriptBin

\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/standalone/setBarPositions/index.html b/cs/zengin/scripts/extenders/standalone/setBarPositions/index.html deleted file mode 100644 index 7db687c147..0000000000 --- a/cs/zengin/scripts/extenders/standalone/setBarPositions/index.html +++ /dev/null @@ -1,141 +0,0 @@ - setBarPositions - Gothic Modding Community

setBarPositions

Quick overview

Author: mud-freak
Platform: G1, G2NotR
Category: Engine, Interface

setBarPositions.d is a script that allows changing position of original gothic bars (HP, Mana, Swim, focus). Changes are directly in the engine, so bars are normally scaled.

Dependencies

Initialization

Call it in the Init_Global() or other initialization function. Set the manaAlwaysOn and swimAlwaysOn to TRUE/FALSE.

SetBarPositions_Init(manaAlwaysOn, swimAlwaysOn);
-

Implementation

setBarPositions.d on WoG forum

Usage

To change positions of bars edit the main function SetBarPosition. Look at the examples to see how you can adjust it to your preferences.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
func int SetBarPosition(var int barPtr) {
-    var oCViewStatusBar bar; bar = _^(barPtr);
-    var int x; var int y;
-
-    if (barPtr == MEM_Game.hpBar) {
-        // Original
-        x = Print_ToVirtual(10, PS_X);                                // 10 px from the left
-        y = PS_VMax - Print_ToVirtual(10 + bar.zCView_psizey, PS_Y);  // 10 px from the bottom
-
-    } else if (barPtr == MEM_Game.manaBar) {
-        // Original
-        x = PS_VMax - Print_ToVirtual(10 + bar.zCView_psizex, PS_X);  // 10 px from the right
-        y = PS_VMax - Print_ToVirtual(10 + bar.zCView_psizey, PS_Y);  // 10 px from the bottom
-
-    } else if (barPtr == MEM_Game.swimBar) {
-        // Original
-        x = (PS_VMax - bar.zCView_vsizex) / 2;                        // Centered
-        y = PS_VMax - Print_ToVirtual(10 + bar.zCView_psizey, PS_Y);  // 10 px from the bottom
-
-    } else if (barPtr == MEM_Game.focusBar) {
-        // Original
-        x = (PS_VMax - bar.zCView_vsizex) / 2;                        // Centered
-        y = Print_ToVirtual(10, PS_Y);                                // 10 px from the top
-    };
-
-    return x | (y << 14);
-};
-

Examples

All bars on the left side

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
/*
- * EXAMPLE: Stacked on the left
- */
-func int SetBarPosition(var int barPtr) {
-    var oCViewStatusBar bar; bar = _^(barPtr);
-    var int x; var int y;
-
-    if (barPtr == MEM_Game.hpBar) {
-        x = Print_ToVirtual(10, PS_X);
-        y = PS_VMax - Print_ToVirtual(6 + 3 * (4 + bar.zCView_psizey), PS_Y);
-
-    } else if (barPtr == MEM_Game.manaBar) {
-        x = Print_ToVirtual(10, PS_X);
-        y = PS_VMax - Print_ToVirtual(6 + 2 * (4 + bar.zCView_psizey), PS_Y);
-
-    } else if (barPtr == MEM_Game.swimBar) {
-        x = Print_ToVirtual(10, PS_X);
-        y = PS_VMax - Print_ToVirtual(6 + 1 * (4 + bar.zCView_psizey), PS_Y);
-
-    } else if (barPtr == MEM_Game.focusBar) {
-        // Original
-        x = (PS_VMax - bar.zCView_vsizex) / 2;                        // Centered
-        y = Print_ToVirtual(10, PS_Y);                                // 10 px from the top
-    };
-
-    return x | (y << 14);
-};
-
\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/zparserextender/c_trigger/index.html b/cs/zengin/scripts/extenders/zparserextender/c_trigger/index.html deleted file mode 100644 index 6db5ec0bd5..0000000000 --- a/cs/zengin/scripts/extenders/zparserextender/c_trigger/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/cs/zengin/scripts/extenders/zparserextender/classes/c_trigger/index.html b/cs/zengin/scripts/extenders/zparserextender/classes/c_trigger/index.html deleted file mode 100644 index a0ac52dcb1..0000000000 --- a/cs/zengin/scripts/extenders/zparserextender/classes/c_trigger/index.html +++ /dev/null @@ -1,145 +0,0 @@ - C_Trigger class - Gothic Modding Community

Trigger functions and the C_Trigger class

zParserExtender also implements cyclical functions called triggers - not to be confused with triggers in ZEN files, similar to a part of the functionality implemented in LeGo AI_Functions. These functions are called independently after a specified period of time. These triggers can also store user information. Up to 16 int variables can be stored in each trigger as well as self, other and victim instances.

Class definition

To define a trigger, the C_Trigger class is used:

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
/// Union zParserExtender Trigger class
-class C_Trigger
-{
-    var int Delay; // defines the frequency (in milliseconds) at which the function will be called.
-    var int Enabled; // determines if the trigger is active. If the value is equal to zero, the trigger is destroyed.
-    var int AIVariables[16]; // user data, which can be set independently when creating trigger (yes, you can write there absolutely everything you want).
-
-    // Hidden variable members
-    /*
-        - Func   - The function that the trigger will call.
-        - Self   - The NPC that will be placed in `self` when the function is called.
-        - Other  - An NPC that will be placed in `other` when the function is called.
-        - Victim - The NPC that will be placed in `victim` when the function is called.
-    */
-};
-

Creating instances

There are two external functions that are used to create C_Trigger instance.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
// function returns a trigger with no NPC (self, other or victim) bound to it
-func C_Trigger AI_StartTriggerScript(   var string funcName,
-                                        var int delay) {};
-
-// function is extended, if certain participants need to be assigned to it
-func C_Trigger AI_StartTriggerScriptEx( var string funcName,
-                                        var int delay,
-                                        var C_Npc slf,
-                                        var C_Npc oth,
-                                        var C_Npc vct) {};
-

Both of these functions return an instance of C_Trigger instance. You can of course configure the instance after its creation. You can, for example, fill in the AIVariables with relevant data. The trigger function has the required signature if 'func int f()'. It must return a value indicating the state of the loop. If the function returns LOOP_END the trigger will be stopped and the instance deleted. If LOOP_CONTINUE is returned, the function will be called again after Delay ms have passed.

Poison example

1
-2
-3
-4
-5
-6
-7
-8
-9
// Implement a trigger to simulate the effect of poison debuff:
-// Let's create a trigger on function `c_loop` with a call interval of 1 second.
-// When the function is called, the instance hero will be placed in self (although it can be any other NPC if desired).
-// The rest of the instances are left null (not used).
-
-var C_Trigger trigger;
-trigger = AI_StartTriggerScriptEx("c_loop", 1000, hero, null, null);
-trigger.AIVariables[0] = 15; // how many times the function should be called
-trigger.AIVariables[1] = 5;  // how much damage to deal each iteration
-

The trigger function

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
func int c_loop()
-{
-    // Create a loop end check, if the number of
-    // available iterations has reached 0. If it did
-    // we stop the trigger by returning the LOOP_END value.
-    if (SelfTrigger.AIVariables[0] <= 0)
-    {
-        return Loop_end;
-    };
-
-    SelfTrigger.Delay -= 20;         // Accelerate loop each call by 20 ms
-    SelfTrigger.AIVariables[0] -= 1; // Reduce number of remaining repeats
-    self.Attribute[ATR_HITPOINTS] -= SelfTrigger.AIVariables[1]; // Take health from self
-    return LOOP_CONTINUE;
-};
-

Trigger scope

Triggers can be divided into two types:

  • Global trigger ( AI_StartTriggerScript ) trigger created using this function works in all worlds. A trigger is considered global by default if neither self nor other nor victim has been provided for it.
  • Local trigger ( AI_StartTriggerScriptEx) trigger created with this function only works in the world in which it was created. A trigger is considered local if it has been presented with at least one NPC in self, other or victim (not null). If you want to create a trigger without linking it to any NPC, it is recommended to simply pass hero as self to the trigger.

Saving

The plugin creates a new save archive to save the information of the triggers that does not conflict with any of the built-in save files.

Searching

To search for a specific trigger, for example by NPC, the trigger external functions can be used.

1
-2
-3
-4
-5
-6
-7
-8
-9
// This way you can disable all triggers running on the `hero` instance
-var C_Trigger trigger = FirstTrigger;
-var C_Trigger trigger_saved;
-while (!Hlp_IsNULL(trigger))
-{
-    trigger_saved = trigger;
-    trigger = AI_GetNextTriggerBySelf(hero);
-    trigger_saved.Enabled = false;
-};
-
\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/zparserextender/classes/helperclasses/index.html b/cs/zengin/scripts/extenders/zparserextender/classes/helperclasses/index.html deleted file mode 100644 index ab06bd445f..0000000000 --- a/cs/zengin/scripts/extenders/zparserextender/classes/helperclasses/index.html +++ /dev/null @@ -1,390 +0,0 @@ - Engine classes - Gothic Modding Community

Engine classes

zParserExtender implements various proxy classes that can be used to access game world objects.

Warning

It is not recommended to implement complex mechanics using these classes and functions. They are present as a simple backup option for accessing game world objects and for quick fixes.

C_VOB

This class represents basic pointer to a game world object.

C_Color

Represents color in the RGBA format

1
-2
-3
-4
-5
-6
-7
class C_Color
-{
-    var int R; // red channel value
-    var int G; // green channel value
-    var int B; // blue channel value
-    var int A; // alpha channel value
-};
-

zVEC3

Represents 3D position in the world (float version for internal functions)

1
-2
-3
-4
-5
-6
class zVEC3
-{
-    var float X; // X coordinate
-    var float Y; // Y coordinate
-    var float Z; // Z coordinate
-};
-

C_Position

Represents 3D position in the world

1
-2
-3
-4
-5
-6
class C_Position
-{
-    var int X; // X coordinate
-    var int Y; // Y coordinate
-    var int Z; // Z coordinate
-};
-
Externals:
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
/// Returns the current position of the object in the world
-/// 
-/// @param vob vob to ge the position of
-/// @return C_Position instance - position of the VOB
-func C_Position Vob_GetVobPosition( var C_Vob vob ) {};
-
-/// Sets the current position of the object in the world
-/// 
-/// @param vob vob to get the position of
-/// @param pos new position of the vob
-func void Vob_SetVobPosition( var C_Vob vob, var C_Position pos ) {};
-

Note

The following classes define properties of C_VOB objects or classes derived from it.

C_VOB_DATA

Represents universal zCVob class

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
class C_VOB_DATA
-{
-    var string Name;              // object name
-    var float VisualAlpha;        // object's transparency 0.0 - 1.0
-    var int ShowVisual;           // display the mode
-    var int DrawBBox3D;           // show objects bounding box
-    var int VisualAlphaEnabled;   // enables objects transparency
-    var int PhysicsEnabled;       // enables object's physics
-    var int IgnoredByTraceRay;    // allow any object collisions
-    var int CollDetectionStatic;  // allow collision with static world polygons
-    var int CollDetectionDynamic; // allow collision with dynamic world objects
-    var int CastDynShadow;        // display shadow of the object
-    var int LightColorStatDirty;  // allow static lighting of the object
-    var int LightColorDynDirty;   // allow dynamic lighting of the object
-    var int SleepingMode;         // sets object's activity mode (0 - inactive, 1 - active, 2 - AI only)
-    var int DontWriteIntoArchive; // turns of the serialization of this object to the save file 
-};
-
Externals:
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
/// Returns the universal data of the zCVob object
-///
-/// @param vob VOB to get the position of
-/// @return general vob data C_Vob_Data
-func C_Vob_Data Vob_GetVobData( var C_Vob vob ) {};
-
-/// Sets the universal data to a zCVob object
-///
-/// @param vob VOB to get the position of
-/// @param data general vob data C_Vob_Data
-func void Vob_SetVobData( var C_Vob vob, var C_Vob_Data data ) {};
-

C_LIGHT_DATA

Represents zCVobLight objects

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
class C_LIGHT_DATA
-{
-    var int R;                // red light intensity
-    var int G;                // green light intensity
-    var int B;                // blue light intensity
-    var int Range;            // radius
-    var int RangeInv;         // 
-    var int RangeBackup;      // 
-    var int RangeAniActFrame; // current light animation frame for the radius
-    var int RangeAniFPS;      // speed of light animation for the radius
-    var int ColorAniActFrame; // current light animation frame for colour
-    var int ColorAniFPS;      // speed of light animation for colour
-    var int SpotConeAngleDeg; // angle of cone light source
-    var int IsStatic;         // whether the source is static
-    var int RangeAniSmooth;   // [UNUSED]
-    var int RangeAniLoop;     // [UNUSED]
-    var int ColorAniSmooth;   // allows soft transitions between colours
-    var int ColorAniLoop;     // [UNUSED]
-    var int IsTurnedOn;       // whether the light source is on
-    var int LightQuality;     // source quality (when statically compiling light) (0 - high, 1 - medium, 2 - low)
-    var int LightType;        // type of source (at static light compilation) (0 - point, 1 - cone)
-};
-
Externals:
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
/// Returns zCVobLight object data
-///
-/// @param vobLight vobLight object
-/// @return C_Light_Data of the light
-func C_Light_Data Vob_GetLightData( var C_Vob vobLight ) {};
-
-/// Sets the data of a zCVobLight object
-///
-/// @param vobLight object to apply the light data to
-/// @param data C_Light_Data light data to be set
-func void Vob_SetLightData( var C_Vob vobLight, var C_Light_Data data ) {};
-
-/// Clears the list of animation colours for the light source
-///
-/// @param vobLight light vob
-func void Vob_ClearLightAniList( var C_Vob vobLight ) {};
-
-/// Adds a color to the colour list
-///
-/// @param vobLight object to apply the colour to
-/// @param col colour to be applied
-func void Vob_AddLightAniColor( var C_Vob vobLight, var C_Color col ) {};
-
-/// Adds a color to the colour list
-///
-/// @param vobLight object to apply the colour to
-/// @param r red colour channel
-/// @param g green colour channel 
-/// @param b blue colour channel
-func void Vob_AddLightAniColorRGB(  var C_Vob vobLight,
-                                    var int r,
-                                    var int g,
-                                    var int b ) {};
-

C_MOB_DATA

Represents data for the used oCMOB object

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
class C_MOB_DATA
-{
-    var string VisibleName;     // name shown above the object
-    var int Hitpoints;          // number of hitpoints
-    var int Damage;             // damage the object can cause
-    var int IsDestroyed;        // if the object is destroyed
-    var int Moveable;           // whether the object can be moved
-    var int Takeable;           // whether the object can be taken
-    var int FocusOverride;      // if the object will redefine focus in combat mode
-    var int SndMat;             // object's material (0 - wood, 1 - stone, 2 - metal, 3 - skin, 4 - clay, 5 - glass)
-    var string VisualDestroyed; // model when the object is destroyed
-    var string OwnerStr;        // name of the instance of the owner of the object
-    var string OwnerGuildStr;   // name of the guild of the object
-    var int Owner;              // instance of the owner
-    var int OwnerGuild;         // guild instance
-    var int FocusNameIndex;     // the script string of the displayed name
-};
-
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
/// Returns the data of the oCMOB object
-///
-/// @param mob oCMOB object
-/// @return mob data
-func C_Mob_Data Vob_GetMobData( var C_Vob mob ) {};
-
-/// Sets the data of the oCMOB object
-///
-/// @param mob oCMOB object
-/// @param data C_Mob_Data to be set 
-func void Vob_SetMobData( var C_Vob mob, var C_Mob_Data data ) {};
-

C_MOBINTER_DATA

Represents data for the interactive object oCMobInter

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
class C_MOBINTER_DATA
-{
-    var string TriggerTarget;   // object name which will be triggered by OnTrigger
-    var string UseWithItem;     // name of the object instance that is needed for interaction
-    var string Sceme;           // name of the scene that corresponds to the object and character animations
-    var string ConditionFunc;   // scripting condition under which the interaction can be performed
-    var string OnStateFuncName; // the name pattern of the functions that will be called when the object changes the state
-    var int State;              // the current state of the object
-    var int State_num;          // number of object's states
-    var int State_target        // current state of the object
-    var int Rewind;             // prohibits object updating
-    var int MobStateAni;        // current animation of the object
-    var int NpcStateAni;        // current character animation
-};
-
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
/// Returns the data of the oCMobInter object
-///
-/// @param mobInter oCMobInter object
-/// @return MobInter_Data of the object
-func MobInter_Data Vob_GetMobInterData( var C_Vob mobInter ) {};
-
-/// Sets the data of the oCMobInter object
-///
-/// @param mobInter oCMobInter object
-/// @param data MobInter_Data of the object
-func void Vob_SetMobInterData( var C_Vob mobInter, var C_MobInter_Data data ) {};
-

C_MOBLOCKABLE_DATA

Represents data for the locked interactive object oCMobLockable

1
-2
-3
-4
-5
-6
-7
-8
class C_MOBLOCKABLE_DATA
-{
-    var int Locked;         // whether the object is locked
-    var int AutoOpen;       // [UNUSED]
-    var int PickLockNr;     // current rotation number 
-    var string KeyInstance; // key instance name for the object
-    var string PickLockStr; // combination to open the object ("LRRLR")
-};
-
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
/// Returns the data of the oCMobLockable object
-///
-/// @param mobLock oCMobLockable object
-/// @param data MobInter_Data of the object
-func C_MobLockable_Data Vob_GetMobInterData( var C_Vob mobLock ) {};
-
-/// Sets the data of the oCMobLockable object
-///
-/// @param mobLock oCMobLockable object
-/// @param data C_MobLockable_Data of the object
-func void Vob_SetMobInterData( var C_Vob mobLock, var C_MobLockable_Data data ) {};
-
\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/zparserextender/daedalus_injection/hooks/index.html b/cs/zengin/scripts/extenders/zparserextender/daedalus_injection/hooks/index.html deleted file mode 100644 index 0c517d6ab8..0000000000 --- a/cs/zengin/scripts/extenders/zparserextender/daedalus_injection/hooks/index.html +++ /dev/null @@ -1,84 +0,0 @@ - Hooking - Gothic Modding Community

Hooking Daedalus

Daedalus hooking is one of the most powerful features of this plugin. Hooking is a mechanism that allows you to replace any scripted object with a new one. To do this, you must define a new object with the same type, name and in the same namespace.

Hook/replacement will be performed only if the MergeMode setting is set to true for the current script in the META block or in the parameter of the same name in the .ini file of the mod.

Warning

If you forget to turn on the MergeMode, the compilation will fail with the redefinition error.

When an object (instance, function or variable) is hooked/replaced, the original one is available under the same name with the _old suffix (PC_Hero -> PC_Hero_old). This allows you to refer to the old object.

Function hook example

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
func void ZS_Attack_Loop()
-{
-    // if the enemy is a player and has no weapon, then
-    // also sheath the weapon.
-    if (Npc_IsPlayer(other) && !Npc_HasReadiedWeapon(other))
-    {
-        return LOOP_END;
-    };
-
-    // otherwise call the original function
-    return ZS_Attack_Loop_Old();
-};
-

This kind of substitution works for instances and variables too.

Warning

While hooking an instances, you have to take care not to call the prototype. Prototype should be always changed back to the original class.

This is wrong
1
-2
-3
-4
-5
instance pc_hero(Npc_Default)
-{
-    pc_hero_old();
-    name = "Pepe";
-};
-
This leads to a double call of prototype Npc_Default which is considered an unsafe practice with undefined behaviour.

The correct way is to call it like this:

1
-2
-3
-4
-5
instance pc_hero(C_NPC) // no prototype Npc_Default
-{
-    pc_hero_old();
-    name = "Pepe";
-};  
-
This way the prototype is called in the original function pc_hero_old() and not for the second time when creating the new hooked instance.

Dialogue hook example

The hooking mechanism is designed to introduce new dialogues into the game as well as replacing old ones with hooks. The scripter can create new merchants, quests, dialogues, as well as attach svm phrases to them.

All new or replaced dialogues will immediately become available, including from saves. In the event that new dialogs are disabled (plugin or script removed), the engine will continue to keep them in the save file, which will allow the dialogs to return at any time with the same state they were in the last time.

Warning

Currently not working as intended (I think). The old dialogue is still used and as a result you will end up with both the old and the new dialogue (unless you edit the old condition function).

1
-2
-3
-4
-5
instance DIA_XARDAS_HELLO(C_INFO)
-{
-    DIA_XARDAS_HELLO_old();
-    important = FALSE;
-};
-
\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/zparserextender/daedalus_injection/index.html b/cs/zengin/scripts/extenders/zparserextender/daedalus_injection/index.html deleted file mode 100644 index 813c275226..0000000000 --- a/cs/zengin/scripts/extenders/zparserextender/daedalus_injection/index.html +++ /dev/null @@ -1,34 +0,0 @@ - Daedalus Injection - Gothic Modding Community

Daedalus Injection

Script injection is a process of injecting Daedalus scripts on runtime without the need to recompile the scripts. This is essential for Union plugins that need to alter the scripts in a certain way, either for hotfixes or just for testing scripts without the need to recompile the whole .dat file.

To inject a script, simply put a .d or .src file in Gothic/System/Autorun directory and run the game.

Tip

Automatic injection does not extend to nested directories in the Autorun directory directly, but you can put a .src file into Autorun directory and the rest into a subdirectory to keep a cleaner structure.

Scripts in subdirectories can be accessed in two ways

  1. They are specified in a .src file
  2. The script file is an API script

API script

API scripts are .d files placed in Autorun subdirectories and are used as a dependency. It is assumed that the API script is not called on its own (or from a .src) file, but is called using the dependency keyword After in one of the injected script files' META block.

These scripts are meant to contain ready-made solution that need to be used by many other scripts as a dependency.

Warning

If the file specified in the After tag in the META block does not exist, the current file will not be parsed and injected since the dependency is missing, and it would fail. Due to this it is best to ship the dependency in the Autorun directory even if it comes from a different plugin.

\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/zparserextender/daedalus_injection/meta/index.html b/cs/zengin/scripts/extenders/zparserextender/daedalus_injection/meta/index.html deleted file mode 100644 index 1ca6ea5c4b..0000000000 --- a/cs/zengin/scripts/extenders/zparserextender/daedalus_injection/meta/index.html +++ /dev/null @@ -1,95 +0,0 @@ - META block - Gothic Modding Community

META block

The META block is optional. If it is specified, it has to be the very first thing in the file without any indent or a comment above it.

Syntax:

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
META
-{
-    Parser // specifies into which compiled file the scripts are going to be injected
-    /*
-        Code    Name              DAT file
-        ---     ------            -------
-        Game    parser            Gothic.dat
-        SFX     parserSoundFX     SFX.dat
-        PFX     parserParticleFX  ParticleFX.dat
-        VFX     parserVisualFX    VisualFX.dat
-        Camera  parserCamera      Camera.dat
-        Menu    parserMenu        Menu.dat
-        Music   parserMusic       Music.dat
-    */
-    MergeMode   // 0 - if conflict occurs = compilation error, 1 - if conflict occurs = hook
-    Engine      // comma separated list of engines for which the scripts will be injected 
-    /*
-        Code  Engine          Human readable name
-        ---   -----           -----------------------
-        G1    Gothic I        Gothic I Classic
-        G1A   Gothic Sequel   Gothic I Addon <3
-        G2    Gothic II       Gothic II Classic
-        G2A   Gothic II NoTR  Gothic II Addon
-    */
-
-    NativeWhile // use native while
-    Namespace   // namespace of this script file
-    Using       // comma separated list of namespaces, that are considered local for this script file
-    Mod         // specify for which mod should this code be injected
-    After       // comma separated list of scripts, after which this script should be parsed
-};
-
\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/zparserextender/daedalus_injection/other/index.html b/cs/zengin/scripts/extenders/zparserextender/daedalus_injection/other/index.html deleted file mode 100644 index 9f3a55d66a..0000000000 --- a/cs/zengin/scripts/extenders/zparserextender/daedalus_injection/other/index.html +++ /dev/null @@ -1,122 +0,0 @@ - Other features - Gothic Modding Community

Other functions of the extender

ini parameters

The choice of ini file depends on how the game was launched. If it was launched from Gothic.exe, then the parameters will be read from SystemPack.ini. If it was launched through GothicStarter.exe, then they will be read from the ini of the mod.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
[zParserExtender]
-LoadScript(obsolete) =
-;specifies a parser-script format script to run the scripts. The parameter is currently invalid.
-
-MergeMode = True
-;specifies whether injections will produce hooks.
-
-CompileDat = False
-;Determines if a copy of DAT file which has been modified by injection will be created.
-
-CompileOU = False
-;determines if a copy of an injection-modified OU file will be created.
-
-NativeWhile = False
-;Determines if a WHILE loop will be compiled. Defaults to False (for Ninja compatibility).
-
-MessagesLevel = 1
-;sets the output level. The higher the level, the more information will be printed to the debug console.
-
-StringIndexingMode = -1
-;defines string indexing mode (see string indexing). Default value is -1.
-;Default   = -1 - The default mode for the moment is Repair mode.
-;Disabled  =  0 - Do nothing with the indices.
-;TopSymbol =  1 - The plugin finds the uppermost unnamed string and sets a counter for it.
-;Repair    =  2 - The plugin goes through the whole string table and, if the indexing order is broken, puts the correct names. The counter is set on the basis of the search.
-

MARVIN console commands

zParserExtender adds console commands that save copies of the .dat files with the injected code.

Warning

If the mod uses Ikarus, the CompileDat option (in the .ini file) should be used since a fatal error may occur when using the command.

1
-2
-3
-4
-5
-6
-7
-8
-9
Parser SaveDat OU        - exports OU.Edited.bin
-Parser SaveDat Game      - exports Gothic.Edited.dat
-Parser SaveDat SFX       - exports SFX.Edited.dat
-Parser SaveDat PFX       - exports ParticleFX.Edited.dat
-Parser SaveDat VFX       - exports VisualFX.Edited.dat
-Parser SaveDat Camera    - exports Camera.Edited.dat
-Parser SaveDat Menu      - exports Menu.Edited.dat
-Parser SaveDat Music     - exports Music.Edited.dat
-Parser Export Stringlist - exports the full string table to Scripts\Exports\StringList.d
-

Launch options

Command line parameters can be passed to the game's exe via the command line or using GothicStarter_Mod.

1
-2
-3
-4
-5
-6
-7
-8
zReparse_OU     - parses and creates OU.bin
-zReparse_Game   - parses and creates Gothic.dat
-zReparse_SFX    - parses and creates SFX.dat
-zReparse_PFX    - parses and creates ParticleFX.dat
-zReparse_VFX    - parses and creates VisualFX.dat
-zReparse_Camera - parses and creates Camera.dat
-zReparse_Menu   - parses and creates Menu.dat
-zReparse_Music  - parses and creates Music.dat
-

Note

If you want to compile OU, you also have to include the Game parameter

-zReparse_Game -zReparse_OU

Const array access

The original zParser doesn't allow direct access to const string arrays. zParserExtender allows you to do so.

Example:

1
-2
-3
-4
func event GameInit()
-{
-    Hlp_MessageBox(TXT_INV_CAT[4]); // Prints "Artifacts"
-};
-

Other engine fixes

  1. When creating an item instance, the instance is placed into the global item instance
  2. On DAT file load, the engine restores the original symbol hierarchy
  3. When loading a save, the engine now skips unknown symbols, instead of crashing
\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/zparserextender/dialogues/index.html b/cs/zengin/scripts/extenders/zparserextender/dialogues/index.html deleted file mode 100644 index 096f1e4775..0000000000 --- a/cs/zengin/scripts/extenders/zparserextender/dialogues/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/cs/zengin/scripts/extenders/zparserextender/events/index.html b/cs/zengin/scripts/extenders/zparserextender/events/index.html deleted file mode 100644 index dc34083f74..0000000000 --- a/cs/zengin/scripts/extenders/zparserextender/events/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/cs/zengin/scripts/extenders/zparserextender/examples/signposts/index.html b/cs/zengin/scripts/extenders/zparserextender/examples/signposts/index.html deleted file mode 100644 index a9d1caa343..0000000000 --- a/cs/zengin/scripts/extenders/zparserextender/examples/signposts/index.html +++ /dev/null @@ -1,367 +0,0 @@ - Sign post example - Gothic Modding Community

Sign post teleportation

This is a short "problem-solving" example, where we try to demonstrate the power of Daedalus injection using zParserExtender. GaroK asked me if there is a way to teleport to all the sign posts in Khorinis to gather information for a Gothic wiki article.
The goal is to introduce a function that will teleport you to every signpost in Khorinis with the press of a button.

The problem

In ZenGin you can teleport to named game objects with the goto vob {vobname} command. But since the signposts do not have a vobname defined, I had to figure out a different approach.

ASCII ZEN

We want to get all the signposts position from Khorinis. The game world was loaded into one of the available world editor, I found one of the signposts and noted the visual which dictates the model of the in-game object nw_misc_sign_01.3DS. Alternatively, you can find the standard vanilla objects from both games on this website.
Next, the world was saved as a ASCII ZEN format. This allows us to write a macro to search for all instances of objects with a specific visual and extract the position vector.

One signpost object
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
[% oCMOB:zCVob 47105 317]
-    pack=int:0
-    presetName=string:
-    bbox3DWS=rawFloat:7564.8291 127.361191 -80.5309067 7611.52441 377.422913 1.67681122 
-    trafoOSToWSRot=raw:73e1673f9c4ec33b15efd8be4465d7bba0fe7f3f30ea7137e5edd83eecaa353bb7e2673f
-    trafoOSToWSPos=vec3:7588.17627 252.391052 -39.4283791
-    vobName=string:
-    visual=string:NW_MISC_SIGN_01.3DS
-    showVisual=bool:1
-    visualCamAlign=enum:0
-    visualAniMode=enum:0
-    visualAniModeStrength=float:0
-    vobFarClipZScale=float:1
-    cdStatic=bool:1
-    cdDyn=bool:1
-    staticVob=bool:1
-    dynShadow=enum:0
-    zbias=int:0
-    isAmbient=bool:0
-    [visual zCProgMeshProto 53505 318]
-    []
-    [ai % 0 0]
-    []
-    focusName=string:MOBNAME_INCITY02
-    hitpoints=int:10
-    damage=int:0
-    moveable=bool:0
-    takeable=bool:0
-    focusOverride=bool:0
-    soundMaterial=enum:0
-    visualDestroyed=string:
-    owner=string:
-    ownerGuild=string:
-    isDestroyed=bool:0
-[]
-

Tip

You can also see that the focusName has a MOBNAME_INCITY02 string constant.
This constant is defined in the scripts and its content is used as the focus name.

const string MOBNAME_INCITY02 = "To Marketplace";
-

The injectable script

As it is an injectable script, we have to specify the META tag.
Lets tell zParserExtender to insert this code into the game parser.

1
-2
-3
-4
META
-{
-    Parser = Game
-};
-
We want to teleport the player and for this we will need the C_Position and C_Vob_Data classes.
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
class C_Position
-{
-    var int X; // X coordinate
-    var int Y; // Y coordinate
-    var int Z; // Z coordinate
-};
-
-class C_VOB_DATA
-{
-    var string Name;              // object name
-    var float VisualAlpha;        // object's transparency 0.0 - 1.0
-    var int ShowVisual;           // display the mode
-    var int DrawBBox3D;           // show objects bounding box
-    var int VisualAlphaEnabled;   // enables objects transparency
-    var int PhysicsEnabled;       // enables object's physics
-    var int IgnoredByTraceRay;    // allow any object collisions
-    var int CollDetectionStatic;  // allow collision with static world polygons
-    var int CollDetectionDynamic; // allow collision with dynamic world objects
-    var int CastDynShadow;        // display shadow of the object
-    var int LightColorStatDirty;  // allow static lighting of the object
-    var int LightColorDynDirty;   // allow dynamic lighting of the object
-    var int SleepingMode;         // sets object's activity mode (0 - inactive, 1 - active, 2 - AI only)
-    var int DontWriteIntoArchive; // turns of the serialization of this object to the save file 
-};
-
It turns out there is 54 instances of objects with the desired visual. Let us define const int NUM_OF_SIGNS = 54 and a const int MAX_COORDS = 3 * NUM_OF_SIGNS - we will store 3 times 54 integers - for every signpost a x, y and z coordinate. And lastly a const int array containing all the positions.
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
-37
-38
-39
-40
-41
-42
-43
-44
-45
-46
-47
-48
-49
-50
-51
-52
-53
-54
-55
-56
-57
-58
-59
-60
// Number of signs we want to jump to
-const int NUM_OF_SIGNS = 54;
-const int MAX_COORDS = 3 * NUM_OF_SIGNS;
-
-const int sign_coordinates[MAX_COORDS] = {
-    11974,  309,   6815,
-    12024,  310,   6778,
-    12411,  1668,  -22495,
-    19491,  1281,  1669,
-    19563,  1281,  1687,
-    20294,  2058,  12487,
-    20324,  2058,  12419,
-    21917,  2900,  -22751,
-    2600,   -57,   -4351,
-    26695,  2419,  4308,
-    26770,  2418,  4319,
-    26978,  2937,  6130,
-    27015,  2936,  6104,
-    27049,  2937,  6159,
-    2964,   2142,  14424,
-    31383,  3896,  4699,
-    31427,  3896,  4640,
-    35368,  3870,  -4374,
-    35435,  3870,  -4355,
-    35437,  3871,  -4399,
-    36205,  3333,  -27186,
-    37774,  3875,  -501,
-    37812,  3874,  -469,
-    37849,  3874,  -512,
-    38291,  3732,  -6699,
-    39276,  3926,  -3357,
-    39307,  3924,  -3313,
-    39351,  3924,  -3359,
-    39435,  4350,  10902,
-    39458,  4350,  10827,
-    40932,  3861,  -3054,
-    42454,  2838,  -19437,
-    5297,   387,   -2145,
-    5358,   387,   -2184,
-    5362,   387,   -2128,
-    54006,  1723,  -10316,
-    54035,  1723,  -10387,
-    551,    -62,   -1820,
-    61080,  2132,  -11622,
-    61155,  2132,  -11625,
-    6408,   392,   3598,
-    6432,   393,   3652,
-    7000,   387,   -1482,
-    73439,  3341,  -11307,
-    7588,   252,   -39,
-    7590,   252,   -109,
-    7642,   253,   -83,
-    7713,   387,   -4782,
-    7758,   386,   -4775,
-    7776,   388,   -4811,
-    8154,   1206,  -17022,
-    8855,   395,   -2402,
-    9704,   393,   5129,
-    9738,   392,   5108
-};
-
Next define a built in event GameLoop function, to check for a pressed key. If the key U is pressed, the jump_to_sign function is called.
1
-2
-3
-4
-5
-6
-7
-8
-9
// check for pressed U button every frame
-func event GameLoop()
-{
-    // if U is toggled, run the function
-    if (Hlp_KeyToggled(KEY_U))
-    {
-        jump_to_sign();
-    };
-};
-

Let's look at the jump_to_sign function now.
This function is called on every U key press and goes through all the signposts and teleports the player to them.
At the start of the function we check if the index is not out of bounds and if it is, sets it back to 0 and starts over.

1
-2
-3
-4
-5
    // if we reached the end, start over
-    if (tp_index >= NUM_OF_SIGNS)
-    {
-        tp_index = 0;
-    };
-
Notice the use of Str_Format function for the formatted output.
1
-2
-3
-4
-5
// give information to the player
-Print(Str_Format("Sign %i/%i", tp_index+1, NUM_OF_SIGNS));
-
-var C_Position pos;  pos  = Vob_GetVobPosition(hero);
-var C_Vob_Data data; data = Vob_GetVobData(hero);
-
Daedalus does not allow array access with variables (only constants and literals). To access the coordinate array we use a selection of parser functions.
Firstly we get the game parser ID. Then we can use the Par_GetSymbolValueIntArray to access the sign_coordinates array and assign the coordinates to the pos variable.
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
// get parser ID for the GAME parser
-var int game_par_id; game_par_id = Par_GetParserID("game");
-
-// get parser ID of the array
-var int arr_id; arr_id = Par_GetSymbolID(game_par_id ,"sign_coordinates");
-
-// access the coordinates from above array
-pos.x = Par_GetSymbolValueIntArray(game_par_id ,arr_id ,tp_index * 3    ); 
-pos.y = Par_GetSymbolValueIntArray(game_par_id ,arr_id ,tp_index * 3 + 1);
-pos.z = Par_GetSymbolValueIntArray(game_par_id ,arr_id ,tp_index * 3 + 2);
-
And now comes the big trick. If you try to just change the position the dynamic and static collision is going to stop you at the first wall, tree or a mountain. To disable it, we can use the C_Vob_Data helper class, get players data, and disable both the static a dynamic collision. First we create a backup of the values just so we can restore them back after the teleport.
1
-2
-3
-4
-5
-6
-7
// backup original collision detection
-var int dyn;   dyn = data.CollDetectionDynamic;
-var int stat; stat = data.CollDetectionStatic;
-
-// turn off collision detection 
-data.CollDetectionDynamic = 0;
-data.CollDetectionStatic  = 0;
-
Let us apply the changed data to the player and edit the position.
1
-2
-3
-4
-5
// apply the edited data to player
-Vob_SetVobData(hero, data);
-
-// move the player 
-Vob_SetVobPosition(hero, pos);
-
Restore the collision detection data from the backup we made and set it.
1
-2
-3
-4
-5
-6
// restore collision detection
-data.CollDetectionDynamic = dyn;
-data.CollDetectionStatic  = stat;
-
-// apply the edited data to player
-Vob_SetVobData(hero, data);
-
Finally, we advance the index to jump to another signpost.
1
-2
// advance the index
-tp_index += 1;
-
\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/zparserextender/extern/index.html b/cs/zengin/scripts/extenders/zparserextender/extern/index.html deleted file mode 100644 index cfee35ac90..0000000000 --- a/cs/zengin/scripts/extenders/zparserextender/extern/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/cs/zengin/scripts/extenders/zparserextender/externals/ai/index.html b/cs/zengin/scripts/extenders/zparserextender/externals/ai/index.html deleted file mode 100644 index e7bb765ba8..0000000000 --- a/cs/zengin/scripts/extenders/zparserextender/externals/ai/index.html +++ /dev/null @@ -1,66 +0,0 @@ - AI functions - Gothic Modding Community

AI - functions for working with AI

Functions to work with the new C_Trigger class and NPC's AI queue.

AI_CallScript

Adds a funcName function call to the AI queue

1
-2
-3
func void AI_CallScript(var string funcName,
-                        var C_NPC slf,
-                        var C_NPC oth) {};
-
  • funcName - name of the function to be called
  • slf - will be inserted into global self instance
  • oth - will be inserted into global other instance

AI_startTriggerScript

Creates a trigger script that calls function funcName once every interval in milliseconds

func C_Trigger AI_startTriggerScript(var string funcName, var int interval) {};
-
  • funcName - name of the function to be called
  • interval - call period in milliseconds
  • return - created C_Trigger instance

AI_startTriggerScriptEx

Extended version call - Creates a trigger script, that calls function funcName once every interval in milliseconds also updates the self, other and victim global instances based on slf, oth and vct parameters respectively

1
-2
-3
-4
-5
func C_Trigger AI_startTriggerScriptEx( var string funcName,
-                                        var int interval,
-                                        var C_NPC slf,
-                                        var C_NPC oth,
-                                        var C_NPC vct) {};
-
  • funcName - name of the function to be called
  • interval - call period in milliseconds
  • slf - will be inserted into global self instance
  • oth - will be inserted into global other instance
  • vct - will be inserted into global victim instance
  • return - created C_Trigger instance

AI_GetTriggerByID

Returns a C_Trigger instance from the array of active triggers by the array index ID

func C_Trigger AI_GetTriggerByID(var int ID) {};
-
  • ID - array id
  • return - active C_Trigger instance

AI_GetTriggersNum

Returns the number of active C_Trigger scripts

func int AI_GetTriggersNum() {};
-
  • return - number of active C_Trigger scripts

AI_GetTriggerNPC

Returns the npc associated with the C_Trigger script based on the ID selfID = 0; otherID = 1; victimID = 2;

func C_NPC AI_GetTriggerNPC(var C_Trigger trigger, var int npcID) {};
-
  • trigger - C_Trigger script
  • npcID - NPC id
  • return - active C_Trigger instance

AI_GetTriggerFunc

Returns the function associated with the specified C_Trigger

func func AI_GetTriggerFunc(var C_Trigger trigger) {};
-
  • trigger - C_Trigger script
  • return - trigger function

AI_GetTriggerFuncName

Returns the function name of a function associated with the specified C_Trigger

func string AI_GetTriggerFuncName(var C_Trigger trigger) {};
-
  • trigger - C_Trigger script
  • return - active C_Trigger instance

Ai_GetNextTriggerByFunc

Returns the next trigger in the active trigger array based on the trigger function, starting on the startTrigger trigger

func C_Trigger Ai_GetNextTriggerByFunc(var C_Trigger startTrigger, var func function) {};
-
  • startTrigger - C_Trigger script to start the search from
  • function - function to be matched
  • return - C_Trigger instance

Ai_GetNextTriggerByFuncName

Returns the next trigger in the active trigger array based on the trigger function name, starting on the startTrigger trigger

func C_Trigger Ai_GetNextTriggerByFuncName(var C_Trigger startTrigger, var string functionName) {};
-
  • startTrigger - C_Trigger script to start the search from
  • functionName - name of a function to be matched
  • return - C_Trigger instance

Ai_GetNextTriggerBySelf

Returns the next trigger in the active trigger array based on the self trigger parameter, starting on the startTrigger instance set in the trigger

func C_Trigger Ai_GetNextTriggerBySelf(var C_Trigger startTrigger, var C_NPC self) {};
-
  • startTrigger - C_Trigger script to start the search from
  • self - C_NPC instance
  • return - C_Trigger instance

Ai_GetNextTriggerByOther

Returns the next trigger in the active trigger array based on the other trigger parameter, starting on the startTrigger instance set in the trigger

func C_Trigger Ai_GetNextTriggerByOther(var C_Trigger startTrigger, var C_NPC other) {};
-
  • startTrigger - C_Trigger script to start the search from
  • other - C_NPC instance
  • return - C_Trigger instance

Ai_GetNextTriggerByVictim

Returns the next trigger in the active trigger array based on the victim trigger parameter, starting on the startTrigger instance set in the trigger

func C_Trigger Ai_GetNextTriggerByVictim( var C_Trigger startTrigger, var C_NPC victim ) {};
-
  • startTrigger - C_Trigger script to start the search from
  • victim - C_NPC instance
  • return - C_Trigger instance

Ai_GetNextTriggerByNPCs

Returns the next trigger in the active trigger array based on all the NPCs set in the trigger script self, other and victim, starting on the startTrigger instance set in the trigger

1
-2
-3
-4
func c_trigger Ai_GetNextTriggerByNPCs( var C_Trigger startTrigger,
-                                        var C_NPC self,
-                                        var C_NPC other,
-                                        var C_NPC victim) {};
-
  • startTrigger - C_Trigger script to start the search from
  • self - self C_NPC instance
  • other - other C_NPC instance
  • victim - victim C_NPC instance
  • return - C_Trigger instance
\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/zparserextender/externals/cast/index.html b/cs/zengin/scripts/extenders/zparserextender/externals/cast/index.html deleted file mode 100644 index 626d039c3e..0000000000 --- a/cs/zengin/scripts/extenders/zparserextender/externals/cast/index.html +++ /dev/null @@ -1,45 +0,0 @@ - CAST functions - Gothic Modding Community

CAST - data type conversion functions

External functions for data type conversion and pointer casting.

Cast_PointerToInstance

Converts memory address (pointer) to an instance

func instance Cast_PointerToInstance(var int address) {};
-
  • address - object pointer
  • return - instance of the object

Cast_InstanceToPointer

Converts instance to a memory address (pointer)

func int Cast_InstanceToPointer( var instance object) {};
-
  • object - object instance
  • return - memory address (pointer) of the object

Cast_PointerToNpc

Casts memory address (pointer) to an NPC

func C_NPC Cast_PointerToNpc( var int address) {};
-
  • address - npc pointer
  • return - NPC instance

Cast_PointerToItem

Casts memory address (pointer) to an Item

func C_ITEM Cast_PointerToItem( var int address) {};
-
  • address - item pointer
  • return - Item instance

Cast_InstanceIsNpc

Checks whether object is an NPC

func int Cast_InstanceIsNpc( var instance object) {};
-
  • object - object to check
  • return - TRUE or FALSE

Cast_InstanceIsItem

Checks whether object is an Item

func int Cast_InstanceIsItem( var instance object) {};
-
  • object - object to check
  • return - TRUE or FALSE

Cast_InstanceIsMob

Checks whether object is an MOB

func int Cast_InstanceIsMob( var instance object) {};
-
  • object - object to check
  • return - TRUE or FALSE

Cast_GetInstanceIndex

Returns symbolID of the object, returns -1 when not found

func int Cast_GetInstanceIndex( var instance object) {};
-
  • object - instance of an object
  • return - symbol table index, -1 when not found

Cast_GetClassID

Returns the class identifier of a class by its name

func int Cast_GetClassID( var string className ) {};
-
  • className - name of the class
  • return - class identifier

Cast_GetVobClassID

Returns class identifier of the zCObject vob class

func int Cast_GetVobClassID( var instance object ) {};
-
  • object - object instance
  • return - class zCObject identifier

Cast_CheckVobClassID

Checks if the classId class is the parent class of the object

func int Cast_CheckVobClassID( var int classId, var instance object ) {};
-
  • classId - class identifier, from Cast_GetClassID function
  • object - object instance
  • return - class zCObject identifier
\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/zparserextender/externals/events_vars/index.html b/cs/zengin/scripts/extenders/zparserextender/externals/events_vars/index.html deleted file mode 100644 index 5d9a41564c..0000000000 --- a/cs/zengin/scripts/extenders/zparserextender/externals/events_vars/index.html +++ /dev/null @@ -1,55 +0,0 @@ - Event functions - Gothic Modding Community

Event functions and variables

On top of external functions, zParserExtender also adds these event functions and constants.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
/// Every event function with this name is executed once every frame
-func event GameLoop() {};
-
-/// Every event function with this name is executed once on game init
-func event GameInit() {};
-
-/// empty instance
-const instance null;
-
-/// not a number floating point constant
-const float NaN;
-
\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/zparserextender/externals/hlp/index.html b/cs/zengin/scripts/extenders/zparserextender/externals/hlp/index.html deleted file mode 100644 index a844cad850..0000000000 --- a/cs/zengin/scripts/extenders/zparserextender/externals/hlp/index.html +++ /dev/null @@ -1,54 +0,0 @@ - HLP functions - Gothic Modding Community

HLP - help functions

Helper functions generally used for safety checks, to get specific information from the engine or to interface with the configuration .ini files.

Hlp_HasFocusVob

Returns TRUE, if a specified NPC has a Vob in focus

func int Hlp_HasFocusVob( var C_NPC npc ) {};
-
  • npc - NPC
  • return - TRUE if npc has a focus Vob, FALSE if it does not

Hlp_GetFocusVob

Returns NPC's focus Vob

func instance Hlp_GetFocusVob( var C_NPC npc ) {};
-
  • npc - NPC
  • return - focus vob

Hlp_GetFocusVobName

Returns the name of NPC's focus vob

func string Hlp_GetFocusVobName( var C_NPC npc ) {};
-
  • npc - NPC
  • return - focus vob name

Hlp_GetStringLength

Returns the length of a specified string

func int Hlp_GetStringLength( var string str ) {};
-
  • return - length of str

IsNAN

Checks whether floating point number is valid

func int IsNAN( var float value ) {};
-
  • return - TRUE if value is NaN, FALSE if value is a valid floating point number

Hlp_KeyToggled

Checks whether key is toggled

func int Hlp_KeyToggled( var int key ) {};
-
  • key - key code
  • return - TRUE if key is toggled, FALSE if key is not toggled

Hlp_KeyPressed

Checks whether key is pressed

func int Hlp_KeyPressed( var int key ) {};
-
  • key - key code
  • return - TRUE if key is pressed, FALSE if key is not pressed

Hlp_LogicalKeyToggled

Checks whether logical key is toggled

func int Hlp_LogicalKeyToggled( var int key ) {};
-
  • key - key code
  • return - TRUE if key is toggled, FALSE if key is not toggled

Hlp_GameOnPause

Checks whether the game is paused

func int Hlp_GameOnPause() {};
-
  • return - TRUE if the game is paused, FALSE if the game is not paused

Hlp_MessageBox

Opens a message box with a specified message

func void Hlp_MessageBox( var string message ) {};
-
  • message - message to be printed

Hlp_PrintConsole

Prints a message to the Union debug console

func void Hlp_PrintConsole(var string message) {};
-
  • message - message to be printed

Hlp_OptionIsExists

Checks whether the entry in section in .ini file optName exists

optName values

  • "Gothic"
  • "Mod"
  • "SystemPack"
func int Hlp_OptionIsExists(var string optName, var string section, var string entry) {};
-
  • optName - the .ini file
  • section - settings section like [GAME]
  • entry - one setting entry like playLogoVideos
  • return - TRUE if the option exists, FALSE if the option does not exist

Hlp_ReadOptionInt

Read an integer value from specified .ini file, section and entry.

optName values

  • "Gothic"
  • "Mod"
  • "SystemPack"
func int Hlp_ReadOptionInt(var string optName, var string section, var string entry, var int default) {};
-
  • optName - the .ini file
  • section - settings section like [GAME]
  • entry - one setting entry like playLogoVideos
  • default - default value - if the value is empty
  • return - the option value

Hlp_ReadOptionFloat

Read a floating point value from specified .ini file, section and entry.

optName values

  • "Gothic"
  • "Mod"
  • "SystemPack"
func float Hlp_ReadOptionFloat(var string optName, var string section, var string entry, var float default) {};
-
  • optName - the .ini file
  • section - settings section like [INTERFACE]
  • entry - one setting entry like scale
  • default - default value - if the value is empty
  • return - the option value

Hlp_ReadOptionString

Read a string value from specified .ini file, section and entry.

optName values

  • "Gothic"
  • "Mod"
  • "SystemPack"
func string Hlp_ReadOptionString(var string optName, var string section, var string entry, var string default) {};
-
  • optName - the .ini file
  • section - settings section like [INTERFACE]
  • entry - one setting entry like scale
  • default - default value - if the value is empty
  • return - the option value

Hlp_WriteOptionInt

Writes an integer value to specified .ini file, section and entry.

optName values

  • "Gothic"
  • "Mod"
  • "SystemPack"
func void Hlp_WriteOptionInt(var string optName, var string section, var string entry, var int value) {};
-
  • optName - the .ini file
  • section - settings section like [INTERFACE]
  • entry - one setting entry like scale
  • value - value to be written

Hlp_WriteOptionFloat

Writes a floating point value to specified .ini file, section and entry.

optName values

  • "Gothic"
  • "Mod"
  • "SystemPack"
func void Hlp_WriteOptionFloat(var string optName, var string section, var string entry, var float value) {};
-
  • optName - the .ini file
  • section - settings section like [INTERFACE]
  • entry - one setting entry like scale
  • value - value to be written

Hlp_WriteOptionString

Writes a string value to specified .ini file, section and entry.

optName values

  • "Gothic"
  • "Mod"
  • "SystemPack"
func void Hlp_WriteOptionString(var string optName, var string section, var string entry, var string value) {};
-
  • optName - the .ini file
  • section - settings section like [INTERFACE]
  • entry - one setting entry like scale
  • value - value to be written

Hlp_GetSteamPersonalName

Returns the name of the current Steam user Returns empty string when not run with Steam

func string Hlp_GetSteamPersonalName() {};
-
  • return - string containing the Steam username, or an empty string

Hlp_DoEvent

Calls every event function with the name funcName.

func void Hlp_DoEvent(var string funcName) {};
-
  • funcName - name of the event function to be called (all of them).
\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/zparserextender/externals/log/index.html b/cs/zengin/scripts/extenders/zparserextender/externals/log/index.html deleted file mode 100644 index 75d03723fa..0000000000 --- a/cs/zengin/scripts/extenders/zparserextender/externals/log/index.html +++ /dev/null @@ -1,36 +0,0 @@ - Log functions - Gothic Modding Community

Log functions

As discussed on Inside Gothic, vanilla Gothic has no way of getting the status of a quest. These functions implement that functionality.

Log_GetTopicStatus

Returns the status of diary topic

  • -1 - Not found
  • 0 - Free
  • 1 - Running
  • 2 - Success
  • 3 - Failure
  • 4 - Obsolete
func int Log_GetTopicStatus(var string topic) {};
-
  • topic - name of the topic
  • return - topic status

Log_GetTopicSection

Returns the topic the diary topic is in

  • -1 - Not found
  • 0 - Missions
  • 1 - Notes
  • 2 - All
func int Log_GetTopicSection(var string topic) {};
-
  • topic - name of the topic
  • return - topic section
\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/zparserextender/externals/mdl/index.html b/cs/zengin/scripts/extenders/zparserextender/externals/mdl/index.html deleted file mode 100644 index baf03744c8..0000000000 --- a/cs/zengin/scripts/extenders/zparserextender/externals/mdl/index.html +++ /dev/null @@ -1,46 +0,0 @@ - MDL functions - Gothic Modding Community

MDL - model functions

Functions to tweak animation and other model related settings.

Mdl_GetAnimationIndex

Returns animation's index for specified NPC based on animation's name

func int Mdl_GetAnimationIndex( var C_NPC npc, var string ani_name ) {};
-
  • npc - NPC with the animation
  • ani_name - name of the animation in uppercase
  • return - animation index

Mdl_GetAnimationName

Returns animation's name for specified NPC based on animation's index

func string Mdl_GetAnimationName( var C_NPC npc, var int ani_index ) {};
-
  • npc - NPC with the animation
  • ani_index - animation index
  • return - animation name

Mdl_AnimationIsExists

Checks whether animation exists

func int Mdl_AnimationIsExists( var C_NPC npc, var int ani_index ) {};
-
  • npc - NPC with the animation
  • ani_index - animation index
  • return - animation name

Mdl_AnimationIsActive

Checks whether animation is active (whether it is currently played)

func int Mdl_AnimationIsActive( var C_NPC npc, var int ani_index ) {};
-
  • npc - NPC with the animation
  • ani_index - animation index
  • return - TRUE if the animation is playing, FALSE if it is not playing

Mdl_SetAllAnimationsFPS

Set framerate for all animations

func void Mdl_SetAllAnimationsFPS( var C_NPC npc, var float fps ) {};
-
  • npc - NPC with the animation
  • fps - framerate

Mdl_ResetAllAnimationsFPS

Reset framerate for all animations to default value

func void Mdl_ResetAllAnimationsFPS( var C_NPC npc ) {};
-
  • npc - NPC with the animation

Mdl_SetAnimationFPS

Set framerate for animation specified by animation index

func void Mdl_SetAnimationFPS( var C_NPC npc, var int ani_index, var float fps ) {};
-
  • npc - NPC with the animation
  • ani_index - animation index
  • fps - framerate

Mdl_ResetAnimationFPS

Reset framerate to default for animation specified by animation index

func void Mdl_ResetAnimationFPS( var C_NPC npc, var int ani_index ) {};
-
  • npc - NPC with the animation
  • ani_index - animation index

Mdl_SetVisible

Set NPCs visibility

func void Mdl_SetVisible( var C_NPC npc, var int isVisible ) {};
-
  • npc - specified NPC
  • isVisible - TRUE - visible, FALSE - invisible

Mdl_ApplyOverlayMds_AtFirst

Applies or moves existing overlay to the top of the list

func void Mdl_ApplyOverlayMds_AtFirst( var string mdsName ) {};
-
  • mdsName - name of the overlay

Mdl_SetNpcSpeedMultiplier

Sets a multiplier for animation speed 1.0 = 100% speed (normal speed)

func void Mdl_SetNpcSpeedMultiplier( var C_Npc npc, var float multiplier ) {};
-
  • npc - npc to be affected
  • multiplier - speed of the animation

Mdl_ResetNpcSpeedMultiplier

Resets the animation speed of an NPC

func void Mdl_ResetNpcSpeedMultiplier( var C_Npc npc ) {};
-
  • npc - npc to be affected
\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/zparserextender/externals/menu/index.html b/cs/zengin/scripts/extenders/zparserextender/externals/menu/index.html deleted file mode 100644 index f505903248..0000000000 --- a/cs/zengin/scripts/extenders/zparserextender/externals/menu/index.html +++ /dev/null @@ -1,56 +0,0 @@ - Menu function - Gothic Modding Community

Menu function

Find all C_MenuItem object instances by the mask and automatically places them in the current menu instance

func void Menu_SearchItems( var string mask ) {};
-
  • mask - regex like mask for searching

Example

This function is used in the Union Menu API script.
In this script the Menu_SearchItems external is used to collect all Union menu scripts that are placed into the Union & Plugins menu that will appear in the game if you use any of the plugins that use this feature.

Usage of Menu_SearchItems external function
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
instance MENU_OPT_UNION(C_MENU_DEF)
-{
-    Menu_SearchItems("MENUITEM_UNION_AUTO_*");
-    MENU_OPT_UNION_PY = 1200;
-    backpic           = MENU_BACK_PIC;
-    items[0]          = "UNION_MENUITEM_TITLE";
-    items[100]        = "UNION_MENUITEM_BACK";
-    defaultoutgame    = 0;
-    defaultingame     = 0;
-    Flags             = Flags | MENU_SHOW_INFO;
-};
-

In this case all instances are of the name MENUITEM_UNION_AUTO_* where * is a wildcard that can be substituted with anything. The plugin will search the scripts and find all instances (in the case of zGamePad it is MenuItem_Union_Auto_zGamePad)

This example comes from the zUnionMenu.d injectable API script that is part of the zGamePad plugin, GitHub link.

\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/zparserextender/externals/mob/index.html b/cs/zengin/scripts/extenders/zparserextender/externals/mob/index.html deleted file mode 100644 index c7ea6377ce..0000000000 --- a/cs/zengin/scripts/extenders/zparserextender/externals/mob/index.html +++ /dev/null @@ -1,45 +0,0 @@ - MOB functions - Gothic Modding Community

MOB - interactive object functions

Functions to manipulate interactive objects like destroying MOBs, setting lockpick combination and such.

Mob_Destroy

Marks oCMOB as destroyed, changes the visual to visualDestroyed (if present).

func void Mob_Destroy( var instance object ) {};
-
  • object - oCMOB to be destroyed

Mob_RemoveItem

Removes an item from a oCMobContainer

func void Mob_RemoveItem( var instance object, var int item ) {};
-
  • object - oCMobContainer object
  • item - item to be removed

Mob_RemoveItems

Removes specified number of items from a oCMobContainer

func void Mob_RemoveItems( var instance object, var int item, var int cnt ) {};
-
  • object - oCMobContainer object
  • item - item to be removed
  • cnt - number of items to be removed

Mob_InsertItem

Inserts an item into a oCMobContainer

func void Mob_InsertItem( var instance object, var int item ) {};
-
  • object - oCMobContainer object
  • item - item to be inserted

Mob_InsertItems

Inserts specified number of items into a oCMobContainer

func void Mob_InsertItems( var instance object, var int item, var int cnt ) {};
-
  • object - oCMobContainer object
  • item - item to be inserted
  • cnt - number of items to be inserted

Mob_GetLockCombination

Returns a lock combination of a oCMobContainer

func string Mob_GetLockCombination( var instance object ) {};
-
  • object - oCMobContainer object
  • return - lock combination

Mob_SetLockCombination

Sets a lock combination to a oCMobContainer

func void Mob_SetLockCombination( var instance object, var string comb ) {};
-
  • object - oCMobContainer object
  • comb - lock combination

Mob_IsLocked

Returns TRUE if the object is locked

func int Mob_IsLocked( var instance object ) {};
-
  • object - oCMobLockable object
  • return - TRUE if locked, FALSE if unlocked

Mob_SetLocked

Set the lock status of the object

func void Mob_SetLocked( var instance object, var int locked ) {};
-
  • object - oCMobLockable object
  • locked - lock or unlock the object

Mob_GetKeyInstance

Returns the key instance, that unlocks the object

func instance Mob_GetKeyInstance( var instance object ) {};
-
  • object - oCMobLockable object
  • return - the key C_ITEM instance

Mob_SetKeyInstance

Stets the key instance, that unlocks the object

func void Mob_SetKeyInstance( var instance object, var int key ) {};
-
  • object - oCMobLockable object
  • key - the key C_ITEM instance
\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/zparserextender/externals/npc/index.html b/cs/zengin/scripts/extenders/zparserextender/externals/npc/index.html deleted file mode 100644 index 506a87a8ef..0000000000 --- a/cs/zengin/scripts/extenders/zparserextender/externals/npc/index.html +++ /dev/null @@ -1,43 +0,0 @@ - NPC functions - Gothic Modding Community

NPC - character functions

NPC related functions.

Npc_SetAsHero

Changes players character to specified npc

func void Npc_SetAsHero( var C_NPC npc ) {};
-
  • npc - NPC to be set as players character

Npc_OpenInventory

Opens NPCs main inventory

func void Npc_OpenInventory( var C_NPC npc ) {};
-
  • npc - NPC

Npc_OpenInventorySteal

Opens the steal inventory of npc's focus NPC

func void Npc_OpenInventorySteal( var C_NPC npc ) {};
-
  • npc - NPC

Npc_OpenInventoryTrade

Start the trading dialogue with specified NPC

func void Npc_OpenInventoryTrade( var C_NPC npc ) {};
-
  • npc - NPC

Npc_GetLeftHandItem

Returns an item in NPC's left hand slot

func C_Item Npc_GetLeftHandItem( var C_Npc npc ) {};
-
  • npc - npc to be affected
  • return - found C_ITEM instance

Npc_GetRightHandItem

Returns an item in NPC's right hand slot

func C_Item Npc_GetRightHandItem( var C_Npc npc ) {};
-
  • npc - npc to be affected
  • return - found C_ITEM instance

Npc_GetSlotItem

Returns an item from a slot with the slotName

func C_Item Npc_GetSlotItem( var C_Npc npc, var string slotName ) {};
-
  • npc - npc to be affected
  • slotName - name of the slot
  • return - found C_ITEM instance

Npc_PutInSlot

Places an instance of the oCVom class (including items and NPCs) object into the slotName of the NPC The copyInInv parameter determines whether a copy of the object should remain in the character's inventory

func void Npc_PutInSlot(var C_Npc npc, var string slotName, var instance object, var int copyInInv) {};
-
  • npc - npc to remove the item from
  • slotName - name of the slot from which to remove the item
  • object - object to be inserted into the slot
  • copyInInv - should a copy of the object stay in character inventory

Npc_RemoveFromSlot

Removes an object from the slotName of the NPC. The dropIt parameter in Gothic 2 defines, whether object should drop out of the slot. In Gothic 1, this parameter is reserved and must be 0.

func void Npc_RemoveFromSlot(var C_Npc npc, var string slotName, var int dropIt) {};
-
  • npc - npc to remove the item from
  • slotName - name of the slot from which to remove the item
  • dropIt - should the object be dropped
\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/zparserextender/externals/par/index.html b/cs/zengin/scripts/extenders/zparserextender/externals/par/index.html deleted file mode 100644 index 227b2d34f1..0000000000 --- a/cs/zengin/scripts/extenders/zparserextender/externals/par/index.html +++ /dev/null @@ -1,51 +0,0 @@ - PAR functions - Gothic Modding Community

PAR - functions for parser manipulation

Parser functions are used to manipulate the parsers. Retrieve SymbolID, access arrays and such.

Par_GetParserID

Returns a parser ID of the parser with a parName name

Parser names:

  • "Game"
  • "SFX"
  • "PFX"
  • "VFX"
  • "Camera"
  • "Menu"
  • "Music"
func int Par_GetParserID(var string parName) {};
-
  • parName - parser name
  • return - parser ID

Par_GetSymbolID

Returns symbol ID for the symbol specified by its name

func int Par_GetSymbolID(var int parId, var string symName) {};
-
  • parID - parser ID
  • symName - symbol name
  • return - symbol ID

Par_GetSymbolLength

Returns symbol length (number of elements)

func int Par_GetSymbolLength(var int parId, var int symId) {};
-
  • parID - parser ID
  • symName - symbol name
  • return - symbol length

Par_GetSymbolValueInt

Returns the integer value of specified symbol

func int Par_GetSymbolValueInt(var int parId, var int symId) {};
-
  • parID - parser ID
  • symName - symbol name
  • return - symbol value

Par_GetSymbolValueFloat

Returns the float value of specified symbol

func float Par_GetSymbolValueFloat(var int parId, var int symId) {};
-
  • parID - parser ID
  • symName - symbol name
  • return - symbol value

Par_GetSymbolValueString

Returns the string value of specified symbol

func string Par_GetSymbolValueString(var int parId, var int symId) {};
-
  • parID - parser ID
  • symName - symbol name
  • return - symbol value

Par_GetSymbolValueInstance

Returns the instance value of specified symbol

func instance Par_GetSymbolValueInstance(var int parId, var int symId) {};
-
  • parID - parser ID
  • symName - symbol name
  • return - symbol value

Par_GetSymbolValueIntArray

Returns the value of specified integer array at the arrayID index

func int Par_GetSymbolValueIntArray(var int parId, var int symId, var int arrayId) {};
-
  • parID - parser ID
  • symName - symbol name
  • arrayID - array index
  • return - value

Par_GetSymbolValueFloatArray

Returns the value of specified float array at the arrayID index

func float Par_GetSymbolValueFloatArray(var int parId, var int symId, var int arrayId) {};
-
  • parID - parser ID
  • symName - symbol name
  • arrayID - array index
  • return - value

Par_GetSymbolValueStringArray

Returns the value of specified string array at the arrayID index

func string Par_GetSymbolValueStringArray(var int parId, var int symId, var int arrayId) {};
-
  • parID - parser ID
  • symName - symbol name
  • arrayID - array index
  • return - value

Par_SetSymbolValueInt

Sets a new integer value to specified symbol

func void Par_SetSymbolValueInt(var int value, var int parId, var int symId) {};
-
  • value - value to be set
  • parID - parser ID
  • symId - symbol ID

Par_SetSymbolValueFloat

Sets a new float value to specified symbol

func void Par_SetSymbolValueFloat(var float value, var int parId, var int symId) {};
-
  • value - value to be set
  • parID - parser ID
  • symId - symbol ID

Par_SetSymbolValueString

Sets a new string value to specified symbol

func void Par_SetSymbolValueString(var string value, var int parId, var int symId) {};
-
  • value - value to be set
  • parID - parser ID
  • symId - symbol ID

Par_SetSymbolValueInstance

Sets a new instance value to specified symbol

func void Par_SetSymbolValueInstance(var instance value, var int parId, var int symId, var int arrayId) {};
-
  • value - value to be set
  • parID - parser ID
  • symId - symbol ID

Par_SetSymbolValueIntArray

Sets a new integer value to specified integer array symbol

func void Par_SetSymbolValueIntArray(var int value, var int parId, var int symId, var int arrayId) {};
-
  • value - value to be set
  • parID - parser ID
  • symId - symbol ID
  • arrayId - array index

Par_SetSymbolValueFloatArray

Sets a new float value to specified float array symbol

func void Par_SetSymbolValueFloatArray(var float value, var int parId, var int symId, var int arrayId) {};
-
  • value - value to be set
  • parID - parser ID
  • symId - symbol ID
  • arrayId - array index

Par_SetSymbolValueStringArray

Sets a new string value to specified string array symbol

func void Par_SetSymbolValueStringArray(var string value, var int parId, var int symId, var int arrayId) {};
-
  • value - value to be set
  • parID - parser ID
  • symId - symbol ID
  • arrayId - array index
\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/zparserextender/externals/string/index.html b/cs/zengin/scripts/extenders/zparserextender/externals/string/index.html deleted file mode 100644 index 08f9fda9c2..0000000000 --- a/cs/zengin/scripts/extenders/zparserextender/externals/string/index.html +++ /dev/null @@ -1,77 +0,0 @@ - String functions - Gothic Modding Community

String functions

Functions to manipulate and format strings.

Str_Format

Returns formatted string using format specifiers

Format specifiers:

  • %s - inserts a string
  • %i - inserts an integer number
  • %x - inserts an integer in hexadecimal
  • %f - inserts a floating point number
  • %b - inserts a logical expression
  • %p - inserts a pointer
func string Str_Format( var string format, ... ) {};
-
  • return - formatted string

Examples

Very powerful function, can be used to streamline strings used in the scripts as well as optimize them for translations.

Define constants containing the string with format specifiers.

1
-2
const string MENU_SAVE = "Slot %i - press ENTER to save in this slot.";
-const string MENU_LOAD = "Slot %i - press ENTER to load saved game.";
-
Then define two format functions as such:
1
-2
-3
-4
func string GetSaveSlotString (var int number)
-{
-    return Str_format(MENU_SAVE, number);
-};
-
1
-2
-3
-4
func string GetLoadSlotString (var int number)
-{
-    return Str_format(MENU_LOAD, number);
-};
-

Tip

Since the whole translatable string is saved in one constant, it is very easy for translators to change the word order. This was not possible to do without code change to the ConcatStrings function calls within the scripts.
With this simple change, translators have to translate only 2 strings instead of 30 (15 + 15 slots) and only 2 strings are compiled into the compiled Menu.dat file.

Str_GetLocalizedString

Returns a string in the current language, otherwise in English. Arguments MUST be encoded in UTF-8! The result string will be converted to appropriate ANSI string.

1
-2
-3
-4
func string Str_GetLocalizedString( var string russian,
-                                    var string english,
-                                    var string german,
-                                    var string polish ) {};
-
  • russian - Russian string
  • english - English string
  • german - German string
  • polish - Polish string
  • return - string in the current language

Str_GetLocalizedStringEx

Returns a string in the current language, otherwise in English. Offers additional languages

1
-2
-3
-4
-5
-6
-7
-8
func string Str_GetLocalizedStringEx(   var string russian,
-                                        var string english,
-                                        var string german,
-                                        var string polish,
-                                        var string romanian,
-                                        var string italian,
-                                        var string czech,
-                                        var string spanish ) {};
-
  • russian - Russian string
  • english - English string
  • german - German string
  • polish - Polish string
  • romanian - Romanian string
  • italian - Italian string
  • czech - Czech string
  • spanish - Spanish string
  • return - string in the current language

Str_UTF8_to_ANSI

Converts UTF-8 string into an ANSI string with codePage

func string Str_UTF8_to_ANSI( var string utf8, var int codePage ) {};
-
  • utf8 - string encoded in UTF8
  • codePage - codePage id, can be obtained from Str_GetCurrentCP
  • return -

Str_GetCurrentCP

Return the code page corresponding to the current language set in the Union System

func int Str_GetCurrentCP() {};
-
  • return - code page corresponding to the current language

Str_GetLength

Returns the length of a string

func int Str_GetLength( var int str ) {};
-
  • str - string to be measured
  • return - length of the string
\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/zparserextender/externals/vob/index.html b/cs/zengin/scripts/extenders/zparserextender/externals/vob/index.html deleted file mode 100644 index d289bfc0e4..0000000000 --- a/cs/zengin/scripts/extenders/zparserextender/externals/vob/index.html +++ /dev/null @@ -1,55 +0,0 @@ - VOB functions - Gothic Modding Community

VOB - functions for object manipulation

VOB functions allow you to manipulate game world objects.

Vob_GetVobPosition

Returns the current position of the object in the world

func C_Position Vob_GetVobPosition( var C_Vob vob ) {};
-
  • vob - vob to ge the position of
  • return - C_Position instance - position of the VOB

Vob_SetVobPosition

Sets the current position of the object in the world

func void Vob_SetVobPosition( var C_Vob vob, var C_Position pos ) {};
-
  • vob - vob to get the position of
  • pos - new position of the vob

Vob_GetVobData

Returns the universal data of the zCVob object

func C_Vob_Data Vob_GetVobData( var C_Vob vob ) {};
-
  • vob - VOB to get the position of
  • return - general vob data C_Vob_Data

Vob_SetVobData

Sets the universal data to a zCVob object

func void Vob_SetVobData( var C_Vob vob, var C_Vob_Data data ) {};
-
  • vob - VOB to get the position of
  • data - general vob data C_Vob_Data

Vob_GetLightData

Returns zCVobLight object data

func C_Light_Data Vob_GetLightData( var C_Vob vobLight ) {};
-
  • vobLight - vobLight object
  • return - C_Light_Data of the light

Vob_SetLightData

Sets the data of a zCVobLight object

func void Vob_SetLightData( var C_Vob vobLight, var C_Light_Data data ) {};
-
  • vobLight - object to apply the light data to
  • data - C_Light_Data light data to be set

Vob_ClearLightAniList

Clears the list of animation colours for the light source

func void Vob_ClearLightAniList( var C_Vob vobLight ) {};
-
  • vobLight - light vob

Vob_AddLightAniColor

Adds a color to the colour list

func void Vob_AddLightAniColor( var C_Vob vobLight, var C_Color col ) {};
-
  • vobLight - object to apply the colour to
  • col - colour to be applied

Vob_AddLightAniColorRGB

Adds a color to the colour list

1
-2
-3
-4
func void Vob_AddLightAniColorRGB(  var C_Vob vobLight,
-                                    var int r,
-                                    var int g,
-                                    var int b ) {};
-
  • vobLight - object to apply the colour to
  • r - red colour channel
  • g - green colour channel
  • b - blue colour channel

Vob_GetMobData

Returns the data of the oCMOB object

func C_Mob_Data Vob_GetMobData( var C_Vob mob ) {};
-
  • mob - oCMOB object
  • return - mob data

Vob_SetMobData

Sets the data of the oCMOB object

func void Vob_SetMobData( var C_Vob mob, var C_Mob_Data data ) {};
-
  • mob - oCMOB object
  • data - C_Mob_Data to be set

Vob_GetMobInterData

Returns the data of the oCMobInter object

func MobInter_Data Vob_GetMobInterData( var C_Vob mobInter ) {};
-
  • mobInter - oCMobInter object
  • return - MobInter_Data of the object

Vob_SetMobInterData

Sets the data of the oCMobInter object

func void Vob_SetMobInterData( var C_Vob mobInter, var C_MobInter_Data data ) {};
-
  • mobInter - oCMobInter object
  • data - MobInter_Data of the object

Vob_GetMobInterData

Returns the data of the oCMobLockable object

func C_MobLockable_Data Vob_GetMobInterData( var C_Vob mobLock ) {};
-
  • mobLock - oCMobLockable object
  • data - MobInter_Data of the object
  • return - C_MobLockable_Data of the object

Vob_SetMobInterData

Sets the data of the oCMobLockable object

func void Vob_SetMobInterData( var C_Vob mobLock, var C_MobLockable_Data data ) {};
-
  • mobLock - oCMobLockable object
  • data - C_MobLockable_Data of the object
\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/zparserextender/externals/wld/index.html b/cs/zengin/scripts/extenders/zparserextender/externals/wld/index.html deleted file mode 100644 index fad5be48c7..0000000000 --- a/cs/zengin/scripts/extenders/zparserextender/externals/wld/index.html +++ /dev/null @@ -1,61 +0,0 @@ - WLD functions - Gothic Modding Community

WLD - world manipulation functions

Functions related to the world.

Wld_ChangeLevel

Trigger level change.

func void Wld_ChangeLevel( var string world, var string waypoint ) {};
-
  • world - name of the world
  • waypoint - target waypoint

Wld_FindVob

Return the VOB instance based on its name.

func instance Wld_FindVob( var string vobname ) {};
-
  • vobname - name of the vob
  • return - zCVob pointer

Wld_PlayEffectVob

Play a visual effect at specified vob

1
-2
-3
-4
-5
-6
func void Wld_PlayEffectVob(    var string effect,
-                                var instance pvob,
-                                var int level,
-                                var int damage,
-                                var int damage_type,
-                                var int damage_speed ) {};
-
  • effect - effect name
  • pvob - zCVob to play the effect at
  • level - effect level
  • damage - damage amount
  • damage_type - damage type
  • damage_speed - damage interval

Wld_PlayEffectAt

Play a visual effect at specified world coordinates

1
-2
-3
-4
-5
-6
func void Wld_PlayEffectAt( var string effect,
-                            var instance coord,
-                            var int level,
-                            var int damage,
-                            var int damage_type,
-                            var int damage_speed ) {};
-
  • effect - effect name
  • coord - world coordinates (zVEC3) to play the effect at
  • level - effect level
  • damage - damage amount
  • damage_type - damage type
  • damage_speed - damage interval

Wld_ToggleRain

Turns on the rain

func void Wld_ToggleRain( var float weight, var float time ) {};
-
  • weight - the strength of the rain
  • time - rain duration

Wld_SetWeatherType

Sets the weather type. Types:

0 - snow 1 - rain

func void Wld_SetWeatherType( var int type ) {};
-
  • type - weather type

Wld_GetWeatherType

Returns the weather type. Types:

0 - snow 1 - rain

func int Wld_GetWeatherType() {};
-
  • return - weather type
\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/zparserextender/helperclasses/index.html b/cs/zengin/scripts/extenders/zparserextender/helperclasses/index.html deleted file mode 100644 index cd2de661e8..0000000000 --- a/cs/zengin/scripts/extenders/zparserextender/helperclasses/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/cs/zengin/scripts/extenders/zparserextender/hooks/index.html b/cs/zengin/scripts/extenders/zparserextender/hooks/index.html deleted file mode 100644 index f421172fef..0000000000 --- a/cs/zengin/scripts/extenders/zparserextender/hooks/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/cs/zengin/scripts/extenders/zparserextender/index.html b/cs/zengin/scripts/extenders/zparserextender/index.html deleted file mode 100644 index 69807af170..0000000000 --- a/cs/zengin/scripts/extenders/zparserextender/index.html +++ /dev/null @@ -1,34 +0,0 @@ - zParserExtender - Gothic Modding Community

zParserExtender

zParserExtender extends ZenGin's parser and adds many useful features. It significantly extends the functionality of scripts with added functionality and new external functions. It also enhances script compilation, allowing to compile OU files directly with the game and allowing for runtime script injection. Since the Union version 1.0m zParserExtender is fully integrated in Union itself.

Note

This is mostly a translation of the original release post

Contacts
Author Gratt
GitHub zParserExtender
Forum zParserExtender
\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/zparserextender/injection/hooks/index.html b/cs/zengin/scripts/extenders/zparserextender/injection/hooks/index.html deleted file mode 100644 index c25e6ad4e8..0000000000 --- a/cs/zengin/scripts/extenders/zparserextender/injection/hooks/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/cs/zengin/scripts/extenders/zparserextender/injection/index.html b/cs/zengin/scripts/extenders/zparserextender/injection/index.html deleted file mode 100644 index 25bb9292b1..0000000000 --- a/cs/zengin/scripts/extenders/zparserextender/injection/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/cs/zengin/scripts/extenders/zparserextender/injection/meta/index.html b/cs/zengin/scripts/extenders/zparserextender/injection/meta/index.html deleted file mode 100644 index 9d44507911..0000000000 --- a/cs/zengin/scripts/extenders/zparserextender/injection/meta/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/cs/zengin/scripts/extenders/zparserextender/injection/other/index.html b/cs/zengin/scripts/extenders/zparserextender/injection/other/index.html deleted file mode 100644 index 13ad843a76..0000000000 --- a/cs/zengin/scripts/extenders/zparserextender/injection/other/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/cs/zengin/scripts/extenders/zparserextender/meta/index.html b/cs/zengin/scripts/extenders/zparserextender/meta/index.html deleted file mode 100644 index ae843c19be..0000000000 --- a/cs/zengin/scripts/extenders/zparserextender/meta/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/cs/zengin/scripts/extenders/zparserextender/namespaces/index.html b/cs/zengin/scripts/extenders/zparserextender/namespaces/index.html deleted file mode 100644 index 7ff03419e2..0000000000 --- a/cs/zengin/scripts/extenders/zparserextender/namespaces/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/cs/zengin/scripts/extenders/zparserextender/other/index.html b/cs/zengin/scripts/extenders/zparserextender/other/index.html deleted file mode 100644 index 3bb6b4a53a..0000000000 --- a/cs/zengin/scripts/extenders/zparserextender/other/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/cs/zengin/scripts/extenders/zparserextender/syntax_extensions/dialogues/index.html b/cs/zengin/scripts/extenders/zparserextender/syntax_extensions/dialogues/index.html deleted file mode 100644 index 52437af7c8..0000000000 --- a/cs/zengin/scripts/extenders/zparserextender/syntax_extensions/dialogues/index.html +++ /dev/null @@ -1,53 +0,0 @@ - Dialogue constants - Gothic Modding Community

Dialogue constants

To simplify dialogues, you can define up to 2 auxiliary variables or constants. Values corresponding to the current C_Info instance will be dynamically written there.

DIA_CurrentInstance

var int DIA_CurrentInstance
-
Contains the ID of the current C_Info instance. Can greatly simplify code or make it more reusable. Should be defined in scripts.
Example usage
1
-2
-3
Info_ClearChoices(DIA_CurrentInstance);
-Info_AddChoice(DIA_CurrentInstance, /*text*/, /*func*/);
-Npc_KnowsInfo(hero, DIA_CurrentInstance); // In this case DIA_CurrentInstance contains the last C_Info instance??
-
Create a wrapper function based on this variable
1
-2
-3
-4
func int C_HeroKnowsCurrentInfo()
-{
-    return Npc_KnowsInfo(hero, DIA_CurrentInstance);
-};
-

DIA_CurrentName

var string DIA_CurrentName;
-
Contains the name of the current instance of C_Info. Can be useful for debugging purposes. Should be defined in scripts. Usage scenarios:
1
-2
-3
Hlp_PrintConsole(DIA_CurrentName);
-Hlp_PrintConsole(Str_Format("%s[%s]", DIA_CurrentName, self.name);
-Hlp_StrCmp(DIA_CurrentName, "DIA_DiegoOw_Teach");
-
\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/zparserextender/syntax_extensions/events/index.html b/cs/zengin/scripts/extenders/zparserextender/syntax_extensions/events/index.html deleted file mode 100644 index fe292a4bcb..0000000000 --- a/cs/zengin/scripts/extenders/zparserextender/syntax_extensions/events/index.html +++ /dev/null @@ -1,57 +0,0 @@ - Event functions - Gothic Modding Community

Event functions

Event functions are functions sharing the same name. It can be defined multiple times but only once per file. Such functions are useful for implementing callback type functions. Every time an event is called, all instances of the same name will be called. The event is func with a return type event. Events are defined globally, meaning they ignore namespace they are in. To call an event from a script, use the external function Hlp_DoEvent(var string funcName).

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
func void GiveXP()
-{
-    Hlp_DoEvent("OnGiveXP");
-};
-
-func event OnGiveXP()
-{
-    // TODO
-    // This function can be defined in many files to do different things
-    // more appropriate for that file's context and all of them will be
-    // called, when function GiveXP (above) is called.
-};
-

Plugin implements two of these event functions

  • func event GameInit() - called when entering the main menu on game start
  • func event GameLoop() - called every frame when a world is loaded

Define these in any file in your scripts, they will be automatically called

\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/zparserextender/syntax_extensions/extern/index.html b/cs/zengin/scripts/extenders/zparserextender/syntax_extensions/extern/index.html deleted file mode 100644 index f511469a1f..0000000000 --- a/cs/zengin/scripts/extenders/zparserextender/syntax_extensions/extern/index.html +++ /dev/null @@ -1,41 +0,0 @@ - Extern binding - Gothic Modding Community

Extern binding

The extern binding allows you to secure your code against overriding or undefined symbol. Keyword extern before declaration means that if object of the same name exists, source object should be used. If not, a new one will be created.

1
-2
-3
-4
extern instance PC_Hero(C_Npc) 
-{
-    // TODO
-};
-
\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/zparserextender/syntax_extensions/namespaces/index.html b/cs/zengin/scripts/extenders/zparserextender/syntax_extensions/namespaces/index.html deleted file mode 100644 index 3a18cd94a2..0000000000 --- a/cs/zengin/scripts/extenders/zparserextender/syntax_extensions/namespaces/index.html +++ /dev/null @@ -1,298 +0,0 @@ - Namespaces - Gothic Modding Community

Namespaces

zParserExtender also implements namespaces. Namespaces ensure that all symbols inside the namespace are unique.

Defining a namespace

To define a namespace the new keyword namespace is used.

1
-2
-3
-4
-5
namespace zTestNamespace
-{
-    var int var01;
-    func void func01() { };
-};
-
1
-2
-3
-4
-5
-6
-7
META
-{
-    Namespace = zTestNamespace;
-};
-
-var int var01;
-func void func01() { };
-

Namespace nesting

Namespaces can be nested for finer control. In case of injection, the namespace defined in META is applied to all code inside the script.

To go deeper into the namespaces you use the namespace operator :. This code shows function with the same name within three different namespaces. The call in GameInit is made from the global namespace.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
namespace zTestNamespace01
-{
-    func void func01() { };
-};
-
-namespace zTestNamespace02
-{
-    func void func01() { };
-};
-
-namespace zTestNamespace03
-{
-    namespace zTestNamespace04
-    {
-        func void func01() { };
-    };
-};
-
-func event GameInit()
-{
-    // In this case, the reference is from global namespace to zTestNamespace
-    zTestNamespace01:func01();
-    zTestNamespace02:func01();
-    zTestNamespace03:zTestNamespace04:func01();
-};
-

Namespace traversal

To go up a namespace tree you use the namespace operator : without specifying a namespace. Number of operators determines how many levels you go up.

Exiting nested namespaces
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
func void func01()
-{
-    Hlp_MessageBox("#1");
-};
-
-namespace zTestNamespace01
-{
-    func void func01()
-    {
-        Hlp_MessageBox("#2");
-    };
-
-    namespace zTestNamespace02
-    {
-        func void func01()
-        {
-            Hlp_MessageBox("#3");
-        };
-
-        namespace zTestNamespace03
-        {
-            func void func01()
-            {
-                Hlp_MessageBox("#4");
-            };
-
-            func event GameInit()
-            {
-                :::func01(); // Calls the function 3 levels up
-                ::func01();  // Calls the function 2 levels up
-                :func01();   // Calls the function 1 level up
-                func01();    // Calls the function from the current namespace
-            };
-        };
-    };
-};
-

Optional namespace specification

There are three cases where the namespace prefix is optional

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
namespace zTestNamespace01
-{
-    func void func01()
-    {
-        Hlp_MessageBox("#1");
-    };
-
-    func event GameInit()
-    {
-        // Function call from the current namespace
-        func01();
-    };
-};
-
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
func void func01()
-{
-    Hlp_MessageBox("#1");
-};
-
-namespace zTestNamespace01
-{
-    func void func01()
-    {
-        Hlp_MessageBox("#2");
-    };
-
-    namespace zTestNamespace02
-    {
-        func event GameInit()
-        {
-            // Function call from the global namespace
-            func01();
-        };
-    };
-};
-
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
META
-{
-    using = zTestNamespace01;
-};
-
-namespace zTestNamespace01
-{
-    func void func01()
-    {
-        Hlp_MessageBox("#1");
-    };
-};
-
-func event GameInit()
-{
-    // Calls the function with the namespace specified in the META block
-    func01();
-};
-

Global namespace and Daedalus hooking

Namespace can not only be defined to an existing symbol but also to define new ones. Next code example shows how to implement a hook to a global instance.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
namespace zTestNamespace01
-{
-    const string Var01 = "New instance name";
-
-    // Hooking the global instance
-    instance :ItAr_Pir_L_Addon(C_Item)
-    {
-        ItAr_Pir_L_Addon_Old();
-        name = Var01;
-    };
-};
-
To hook an object, both signature and namespace has to match. It is syntactically allowed to hook an instance from a different space. Specify explicitly to which namespace the object will belong. This means that to hook instance ItAr_Pir_L_Addon from the namespace zTestNamespace01 to a global namespace, you have to refer to the global namespace using the namespace operator :. Since the function will be defined globally (as every symbol in ZenGin), it will be a part of the zTestNamespace01 which means that all functions will be local to this namespace.
\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/zparserextender/syntax_extensions/testelse/index.html b/cs/zengin/scripts/extenders/zparserextender/syntax_extensions/testelse/index.html deleted file mode 100644 index 8a9f25d6fa..0000000000 --- a/cs/zengin/scripts/extenders/zparserextender/syntax_extensions/testelse/index.html +++ /dev/null @@ -1,50 +0,0 @@ - Test-else binding - Gothic Modding Community

Test-else statements

The test-else bind statement can be used to define sections of code to be compiled. If the code is within the boundaries of the inactive test-else branch, it will not be compiled. This operator can take values as input that are converted to logical values. For example, if an object is passed as an argument, the parser will check for its existence. If it is an engine tag, it will return the result of matching the current engine with the tag:

Valid values:

  • instance name - PC_HERO, ItMi_Gold, ...
  • engine tag - G1, G1A, G2, G2A
  • Steam Overlay activity - Steam

The result can be combined from several arguments. Round brackets () can be used to specify priority and expressions support the logical negation operator !, logical AND && and OR ||.

The operator can be used anywhere in the script file. It is syntactically similar to if else statement, but curly braces {} can be omitted for single-line operations. For example:

SteamActivated constant is set only when Steam is active
test Steam var const SteamActivated = 1;
-
Example of a logical expression with an else branch
1
-2
-3
-4
-5
-6
-7
-8
test SteamActivated && G2A 
-{
-    // TODO
-}
-else 
-{
-    // TODO
-}
-
\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/zparserextender/syntax_extensions/while/index.html b/cs/zengin/scripts/extenders/zparserextender/syntax_extensions/while/index.html deleted file mode 100644 index 63a78b40a6..0000000000 --- a/cs/zengin/scripts/extenders/zparserextender/syntax_extensions/while/index.html +++ /dev/null @@ -1,62 +0,0 @@ - While loop - Gothic Modding Community

Native WHILE loop

Just like Ikarus zParserExtender implements a while loop.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
var int value; value = 10;
-while(value > 0)
-{
-    if (value == 8)
-    {
-        continue;
-    };
-
-    if (value == 2)
-    {
-        break;
-    };
-};
-

Note

To activate while it is necessary to set NativeWhile setting in SystemPack.ini

1
-2
[ZPARSE_EXTENDER]
-NativeWhile = true
-

Compiled while loop works in vanilla engine without the plugin.

\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/zparserextender/testelse/index.html b/cs/zengin/scripts/extenders/zparserextender/testelse/index.html deleted file mode 100644 index 54c26cdb73..0000000000 --- a/cs/zengin/scripts/extenders/zparserextender/testelse/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/cs/zengin/scripts/extenders/zparserextender/while/index.html b/cs/zengin/scripts/extenders/zparserextender/while/index.html deleted file mode 100644 index 84cdf313b4..0000000000 --- a/cs/zengin/scripts/extenders/zparserextender/while/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/cs/zengin/scripts/externals/doc/index.html b/cs/zengin/scripts/externals/doc/index.html deleted file mode 100644 index 49947d73fc..0000000000 --- a/cs/zengin/scripts/externals/doc/index.html +++ /dev/null @@ -1,299 +0,0 @@ - Doc functions - Gothic Modding Community

Doc external functions

Doc functions are used to control the document manager. They allow you to fine tune the display of maps, letters and books.

Doc_Create

Creates a new instance of the document manager and returns its ID.

func int Doc_Create() {};
-

Return value
Returns the ID of the document manager instance.

Example

1
-2
var int nDocID; // Variable to store the id in
-nDocID = Doc_Create();
-

Doc_CreateMap

Creates a new instance of the document manager with the arrow showing players position on the map and returns its ID.

func int Doc_CreateMap() {};
-

Return value
Returns the ID of the document manager instance.

Example

1
-2
var int nDocID; // Variable to store the id in
-nDocID = Doc_CreateMap();
-

Doc_SetLevel

Set a world level to a map. This maps the texture of the document to the bounding box of the provided level.

func void Doc_SetLevel(var int docID, var string level) {};
-

Parameters

  • var int docID - document manager ID
  • var string level - name of the ZEN file

Example

1
-2
nDocID = Doc_CreateMap();
-Doc_SetLevel(nDocID, "WORLD.ZEN");
-

Doc_SetLevelCoords

Warning

This function is only available in Gothic 2

Sets the map coordinates. This is used to map smaller portions of the world map to the document map to correctly show players position on the map.

func void Doc_SetLevelCoords(var int docID, var int left, var int top, var int right, var int bottom) {};
-

Parameters

  • var int docID - document manager ID
  • var int left - left coordinate
  • var int top - top coordinate
  • var int right - right coordinate
  • var int bottom - bottom coordinate

Example

Doc_SetLevelCoords(nDocID, -28000, 50500, 95500, -42500);
-

Doc_SetFont

Sets a font to be used on a page in a document with docID. Can be called multiple times to display different lines with different fonts.

func void Doc_SetFont(var int docID, var int page, var string font) {};
-

Parameters

  • var int docID - document manager ID
  • var int page - page index, if set to -1, fonts will be applied to all pages
  • var string font - font to be used

Example

Doc_SetFont(nDocID, -1, "FONT_10_BOOK.TGA");
-

Doc_SetPages

Sets the number of pages numOfPages of the document.

func void Doc_SetPages(var int docID, var int numOfPages) {};
-

Parameters

  • var int docID - document manager ID
  • var int numOfPages - number of pages

Example

1
-2
nDocID = Doc_Create();
-Doc_SetPages(nDocID, 2);
-

Doc_SetPage

Set page to have texture as a background with scale.

func void Doc_SetPage(var int docID, var int page, var string texture, var int scale) {};
-

Parameters

  • var int docID - document manager ID
  • var int page - page index, if set to -1, settings are applied to all pages
  • var string texture - texture of the background
  • var int scale - scale of the texture, TRUE to scale the page, FALSE to not scale

Example

1
-2
Doc_SetPage(nDocID, 0, "Book_Mage_L.tga", FALSE);
-Doc_SetPage(nDocID, 1, "Book_Mage_R.tga", FALSE);
-

Doc_SetMargins

Sets text margins of the page

1
-2
-3
-4
-5
-6
-7
func void Doc_SetMargins(var int docID,
-                         var int page,
-                         var int left,
-                         var int top,
-                         var int right,
-                         var int bottom,
-                         var int pixels) {};
-

Parameters

  • var int docID - document manager ID
  • var int page - page index, if set to -1, settings are applied to all pages
  • var int left - left margin
  • var int top - top margin
  • var int right - right margin
  • var int bottom - bottom margin
  • var int pixels - TRUE to use pixels, FALSE to use virtual coordinates

Warning

After a thorough examination of this external function in the decompiler, it looks like the function works in pixels only regardless of this parameter.

Example

Doc_SetMargins(nDocID, 0, 275, 20, 30, 20, TRUE);
-

Doc_PrintLine

Prints a line of text (font is set using Doc_SetFont) onto the document with docID, onto the page. Does not split the text into multiple lines if they do not fit onto the page.

func void Doc_PrintLine(var int docID, var int page, var string text) {};
-

Parameters

  • var int docID - document manager ID
  • var int page - page index
  • var string text - text to be printed

Example

1
-2
Doc_PrintLine(nDocID, 0, ""); // insert empty line
-Doc_PrintLine(nDocID, 0, "The Book");
-

Doc_PrintLines

Prints a line of text (font is set using Doc_SetFont) onto the document with docID, onto the page. Splits the text into multiple lines if they do not fit onto the page.

func void Doc_PrintLines(var int docID, var int page, var string text) {};
-

Parameters

  • var int docID - document manager ID
  • var int page - page index
  • var string text - text to be printed

Example

1
-2
Doc_PrintLines(nDocID, 0, "The war had been decided. Varant had lost its seaports, vital to army supplies. King Rhobar had not lingered on the battle fields for a long time, but left his generals to deal with the few remaining enemy troops. Varant had only one large force left, commanded by Lukkor, the most capable warlord of the Varant army, who had more than once turned defeat into victory.");
-Doc_PrintLines(nDocID, 0, "But now his army was trapped. The situation was hopeless, even though his army greatly outnumbered the enemy. Lee, a war hero from Myrtana, had lured him into this trap. The heavy cavalry had been unable to fight on the thick, swamped ground of the narrow valley. Lee's soldiers had occupied the range of hills surrounding the swamp, and they had struck repeatedly, decimating the army. The desperate sallies his troops had launched had been cut short in pools of blood. He was beaten.");
-

Doc_Show

Display the document using the document manager ID

func void Doc_Show(var int docID) {};
-

Parameters

  • var int docID - document manager ID

Example

1
-2
-3
-4
-5
-6
var int nDocID; // Variable to store the id in
-nDocID = Doc_Create();
-
-// ... document configuration
-
-Doc_Show(nDocID);
-

Externals with docu comments

  1
-  2
-  3
-  4
-  5
-  6
-  7
-  8
-  9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
-100
-101
-102
-103
-104
/// Creates a new instance of the document manager and returns its ID.
-///
-/// @return Returns the ID of the document manager instance.
-func int Doc_Create() {};
-
-/// Create a new instance of the document manager with the arrow showing players position on the map and returns its ID.
-///
-/// @return Returns the ID of the document manager instance.
-func int Doc_CreateMap() {};
-
-/// Prints a line of `text` onto the document with `docID`, onto the `page`.
-/// Does not line break
-/// 
-/// @param docID document manager ID
-/// @param page page index
-/// @param text text to be printed
-func void Doc_PrintLine(var int docID, var int page, var string text) {};
-
-/// Prints a line of `text` onto the document with `docID`, onto the `page`. The `text` is automatically split into multiple lines
-/// 
-/// @param docID document manager ID
-/// @param page page index
-/// @param text text to be printed
-func void Doc_PrintLines(var int docID, var int page, var string text) {};
-
-/// Sets a `font` to be used on a `page` in a document with `docID`. Can be called multiple times to display different lines with different fonts.
-///
-/// @param docID document manager ID
-/// @param page page index
-/// @param font font to be used
-func void Doc_SetFont(var int docID, var int page, var string font) {};
-
-/// Sets the number of pages `numOfPages` of the document.
-///
-/// @param docID document manager ID
-/// @param numOfPages number of pages
-func void Doc_SetPages(var int docID, var int numOfPages) {};
-
-/// Set `page` to have `texture` as a background with `scale`. 
-///
-/// @param docID document manager ID
-/// @param page page index, if set to `-1`, settings are applied to all pages
-/// @param texture texture of the background
-/// @param scale scale of the texture, if set to 1, there will be no resizing
-func void Doc_SetPage(var int docID, var int page, var string texture, var int scale) {};
-
-/// Set a world level to a map.
-///
-/// @param docID document manager ID
-/// @param level name of the ZEN file
-func void Doc_SetLevel(var int docID, var string level) {};
-
-/// Sets the map coordinates. 
-/// 
-/// @param docID document manager ID
-/// @param left left
-/// @param top top
-/// @param right top
-/// @param bottom bottom
-func void Doc_SetLevelCoords(var int docID, var int left, var int top, var int right, var int bottom) {};
-
-/// Sets text margins of the page
-///
-/// @param docID document manager ID
-/// @param page page index, if set to `-1`, settings are applied to all pages
-/// @param left left margin
-/// @param top top margin
-/// @param right right margin
-/// @param bottom bottom margin
-/// @param pixels `TRUE` to use pixels, `FALSE` to use virtual coordinates
-func void Doc_SetMargins(var int docID,
-                         var int page,
-                         var int left,
-                         var int top,
-                         var int right,
-                         var int bottom,
-                         var int pixels) {};
-
-/// Display the document using the document manager ID
-///
-/// @param docID document manager ID
-func void Doc_Show(var int docID) {};
-
-
-
-/// deprecated
-func void Doc_Open (var string Texture) {};
-
-/// deprecated
-func void Doc_Font(var string Font) {};
-
-/// deprecated
-func void Doc_Print (var string Text) {};
-
-/// deprecated
-func void Doc_MapCoordinates(var string s0,
-                             var float r1,
-                             var float r2,
-                             var float r3,
-                             var float r4,
-                             var float r5,
-                             var float r6,
-                             var float r7,
-                             var float r8) {};
-
\ No newline at end of file diff --git a/cs/zengin/scripts/externals/index.html b/cs/zengin/scripts/externals/index.html deleted file mode 100644 index fa10c5b568..0000000000 --- a/cs/zengin/scripts/externals/index.html +++ /dev/null @@ -1,34 +0,0 @@ - Externals - Gothic Modding Community

Externals

External functions are Daedalus functions (defined in the engine itself), that are used to interface with the engine. Gothic 1 and Gothic 2 implements slightly different set of external functions.
There are some external functions, that were used in the course of Gothic's development, but are now obsolete/deprecated because the underlying systems implemented in the engine were either turned off, or broken all together.

\ No newline at end of file diff --git a/cs/zengin/scripts/externals/log/index.html b/cs/zengin/scripts/externals/log/index.html deleted file mode 100644 index 316dff7f2f..0000000000 --- a/cs/zengin/scripts/externals/log/index.html +++ /dev/null @@ -1,87 +0,0 @@ - Log functions - Gothic Modding Community

Log external functions

Log externals are used to manipulate players log and to track quest progress.

Log_CreateTopic

Creates a new log topic with the name topicName under the section logSection

func void Log_CreateTopic(var string topicName, var int logSection) {};
-
Parameters
  • var string topicName
    Unique string used to identify and name the topic
  • var int logSection
    Indicates in which section to create the topic in.
    Takes constants LOG_MISSION, LOG_NOTE as values

Log_AddEntry

Adds an entry to a log topic with the name topicName under the section logSection

func void Log_AddEntry(var string topicName, var string entry) {};
-
Parameters
  • var string topicName
    Unique string used to identify and name the topic
  • var string entry
    Content of the new entry

Info

In the engine the Log_AddEntry() is wrapped in a B_LogEntry() function. This function also handles printing the "New Journal Entry" message to the screen and playing the sound effect.

1
-2
-3
-4
-5
-6
-7
-8
-9
func void B_LogEntry(var string topic, var string entry)
-{
-    PrintDebugNpc(PD_ZS_DETAIL, "B_LogEntry"); // Logging
-
-    Log_AddEntry(topic, entry);
-
-    PrintScreen(NAME_NewLogEntry, -1, _YPOS_MESSAGE_LOGENTRY, "font_old_10_white.tga", _TIME_MESSAGE_LOGENTRY);
-    Snd_Play("LogEntry");
-};
-

Log_SetTopicStatus

Changes the status of the topic with the name topicName

func void Log_SetTopicStatus(var string topicName, var int status) {};
-
Parameters
  • var string topicName
    Unique string used to identify and name the topic
  • var int status
    The status to be set.
    Takes constants LOG_RUNNING, LOG_SUCCESS, LOG_FAILED, LOG_OBSOLETE as values

zParserExtender

The log external function selection is missing functions to retrieve the status of a log entry. There are only functions to read the log status (as discussed on Inside Gothic). As a result of this the original scriptwriters had to define additional variable to track the log status in the scripts, even though the value is being already tracked by the engine. zParserExtender fixes this by introducing new log external functions.

Externals with docu comments

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
/// Creates a new log topic with the name `topicName` under the section `logSection`
-/// 
-/// @param topicName unique string used to identify and name the topic
-/// @param logSection [LOG_MISSION, LOG_NOTE] indicates in which section to create the topic in
-func void Log_CreateTopic(var string topicName, var int logSection) {};
-
-/// Creates a new log topic with the name `topicName` under the section `logSection`
-/// 
-/// @param topicName unique string used to identify and name the topic
-/// @param logSection [LOG_MISSION, LOG_NOTE] indicates in which section to create the topic in
-func void Log_AddEntry(var string topicName, var string entry) {};
-
-/// Changes the status of the topic with the name `topicName`
-///
-/// @param topicName unique string used to identify and name the topic
-/// @param status [LOG_RUNNING, LOG_SUCCESS, LOG_FAILED, LOG_OBSOLETE] the status to be set
-func void Log_SetTopicStatus(var string topicName, var int status) {};
-
\ No newline at end of file diff --git a/cs/zengin/scripts/externals/mdl/index.html b/cs/zengin/scripts/externals/mdl/index.html deleted file mode 100644 index 480d993117..0000000000 --- a/cs/zengin/scripts/externals/mdl/index.html +++ /dev/null @@ -1,281 +0,0 @@ - MDL functions - Gothic Modding Community

MDL functions

Functions to tweak animation and other model related settings.

Mdl_ApplyOverlayMDS

Apply an animation overlay with overlay_name for the specified npc

func void Mdl_ApplyOverlayMDS(var c_npc npc, var string overlay_name) {};
-

Parameters

  • var c_npc npc
    NPC to apply the overlay to
  • var string overlay_name
    Name of the animation overlay

Mdl_ApplyOverlayMDSTimed

Apply an animation overlay with overlay_name for the specified npc for duration milliseconds

func void Mdl_ApplyOverlayMDSTimed(var c_npc npc, var string overlay_name, var float duration) {};
-

Parameters

  • var c_npc npc
    NPC to apply the overlay to
  • var string overlay_name
    Name of the animation overlay
  • var float duration
    Overlay duration in milliseconds

Mdl_RemoveOverlayMDS

Remove the animation overlay overlay_name from specified npc

func void Mdl_RemoveOverlayMDS(var c_npc npc, var string overlay_name) {};
-

Parameters

  • var c_npc npc
    NPC to remove the overlay from
  • var string overlay_name
    Name of the animation overlay

Mdl_ApplyRandomAni

Assign a random animation ani2 to random animation list of animation ani1

func void Mdl_ApplyRandomAni(var c_npc npc, var string ani1, var string ani2) {};
-

Parameters

  • var c_npc npc
    NPC owning the animation
  • var string ani1
    The animation to assign random animation to
  • var string ani2
    Animation to be assigned

Mdl_ApplyRandomAniFreq

Sets the random animation frequency for animation ani1

func void Mdl_ApplyRandomAniFreq(var c_npc npc, var string ani1, var float frequency) {};
-

Parameters

  • var c_npc npc
    NPC owning the animation
  • var string ani1
    The animation to set the random frequency
  • var float frequency
    Number of seconds between random animations
Example
1
-2
-3
-4
// Attach T_WOUNDED_TRY animation to the S_WOUNDED animation
-Mdl_ApplyRandomAni(self, "S_WOUNDED", "T_WOUNDED_TRY");
-// Make the random animation attached play every 8 seconds
-Mdl_ApplyRandomAniFreq(self, "S_WOUNDED", 8);
-

Mdl_SetModelFatness

Set the procedural model fatness

func void Mdl_SetModelFatness(var c_npc npc, var float fatness) {};
-

Parameters

  • var c_npc npc
    NPC to apply the fatness to
  • var float fatness
    Fatness value

Mdl_SetModelScale

Set model scale per axis

func void Mdl_SetModelScale(var c_npc npc, var float x, var float y, var float z) {};
-

Parameters

  • var c_npc npc
    NPC to apply the scale to
  • var float x
    Scale along the x-axis, 1.0 = 100%, 1.5 = 150%, 0.9 = 90%
  • var float y
    Scale along the y-axis, 1.0 = 100%, 1.5 = 150%, 0.9 = 90%
  • var float z
    Scale along the z-axis, 1.0 = 100%, 1.5 = 150%, 0.9 = 90%

Mdl_SetVisualBody

Sets up the visual of an NPC

1
-2
-3
-4
-5
-6
-7
-8
func void Mdl_SetVisualBody(var instance npc,
-                            var string body_mesh,
-                            var int body_tex,
-                            var int skin,
-                            var string head_mesh,
-                            var int head_tex,
-                            var int teeth_tex,
-                            var int armor_inst       ) {};
-

Parameters

  • var instance npc
    NPC to be affected
  • var string body_mesh
    Mesh to be used as the body e.g. HUN_BODY_NAKED0
  • var int body_tex
    Body texture assigned to this body mesh
  • var int skin
    Body texture variant
  • var string head_mesh
    Head mesh
  • var int head_tex
    Head texture
  • var int teeth_tex
    Teeth texture
  • var int armor_inst
    Armor (C_ITEM instance) to be equipped or -1 for no armor

Mdl_SetVisual

Set the animation set (also dictates models you can set using the Mdl_SetVisualBody)

func void Mdl_SetVisual(var instance npc, var string animation_set) {};
-

Parameters

  • var instance npc
    NPC to apply the animation set to
  • var string animation_set
    Name of the MDS file that contains the animation set

Mdl_StartFaceAni

Start a face animation

1
-2
-3
-4
func void Mdl_StartFaceAni(var c_npc npc,
-                           var string name,
-                           var float intensity,
-                           var float holdtime) {};
-

Parameters

  • var c_npc npc
    NPC to apply the animation to
  • var string name
    Animation name
  • var float intensity
    Intensity of the animation 0.0 to 1.0
  • var float holdtime
    How long should the animation be held for -2 will use the MMS defined value, '-1' will make the hold time infinite

Mdl_ApplyRandomFaceAni

Start a random face animation

1
-2
-3
-4
-5
-6
-7
func void Mdl_ApplyRandomFaceAni(var c_npc npc,
-                                 var string name,
-                                 var float timemin,
-                                 var float timeminvar,
-                                 var float timemax,
-                                 var float timemaxvar,
-                                 var float probmin) {};
-

Parameters

  • var c_npc npc
    NPC to apply the animation to
  • var string name
    Animation name
  • var float timemin
    Minimum time after which the ani should be started (in seconds)
  • var float timeminvar
    Minimum boundary variation (in seconds)
  • var float timemax
    Maximum time after which the ani should be started (in seconds)
  • var float timemaxvar
    Maximum boundary variation (in seconds)
  • var float probmin
    Probability (0.0 to 1.0) to choose the lower boundary time

Externals with docu comments

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
-37
-38
-39
-40
-41
-42
-43
-44
-45
-46
-47
-48
-49
-50
-51
-52
-53
-54
-55
-56
-57
-58
-59
-60
-61
-62
-63
-64
-65
-66
-67
-68
-69
-70
-71
-72
-73
-74
-75
-76
-77
-78
-79
-80
-81
-82
-83
-84
-85
-86
-87
-88
-89
-90
-91
-92
-93
-94
-95
-96
-97
-98
-99
/// Apply an animation overlay with `overlay_name` for the specified `npc`
-/// 
-/// @param npc NPC to apply the overlay to
-/// @param overlay_name name of the animation overlay
-func void Mdl_ApplyOverlayMDS(var c_npc npc, var string overlay_name) {};
-
-/// Apply an animation overlay with `overlay_name` for the specified `npc` for `duration` milliseconds
-///
-/// @param npc NPC to apply the overlay to
-/// @param overlay_name name of the animation overlay
-/// @param duration overlay duration in milliseconds
-func void Mdl_ApplyOverlayMDSTimed(var c_npc npc, var string overlay_name, var float duration) {};
-
-/// Remove the animation overlay `overlay_name` from specified `npc` 
-/// 
-/// @param npc NPC to remove the overlay from
-/// @param overlay_name name of the animation overlay
-func void Mdl_RemoveOverlayMDS(var c_npc npc, var string overlay_name) {};
-
-/// Assign a random animation `ani2` to random animation list of animation `ani1`
-///
-/// @param npc NPC owning the animation
-/// @param ani1 the animation to assign random animation to
-/// @param ani2 animation to be assigned
-func void Mdl_ApplyRandomAni(var c_npc npc, var string ani1, var string ani2) {};
-
-/// Sets the random animation frequency for animation `ani1`
-///
-/// @param npc NPC owning the animation
-/// @param ani1 the animation to set the random frequency
-/// @param frequency number of seconds between random animations
-func void Mdl_ApplyRandomAniFreq(var c_npc npc, var string ani1, var float frequency) {};
-
-/// Set the procedural model fatness
-///
-/// @param npc NPC to apply the fatness to 
-/// @param fatness fatness value
-func void Mdl_SetModelFatness(var c_npc npc, var float fatness) {};
-
-/// Set model scale per axis
-///
-/// @param npc NPC to apply the scale to 
-/// @param x scale along the x axis, 1.0 = 100%, 1.5 = 150%, 0.9 = 90% 
-/// @param y scale along the y axis, 1.0 = 100%, 1.5 = 150%, 0.9 = 90% 
-/// @param z scale along the z axis, 1.0 = 100%, 1.5 = 150%, 0.9 = 90% 
-func void Mdl_SetModelScale(var c_npc npc, var float x, var float y, var float z) {};
-
-/// Sets up the visual of an NPC
-///
-/// @param npc NPC to be affected
-/// @param body_mesh mesh to be used as the body e.g. `HUN_BODY_NAKED0`
-/// @param body_tex body texture assigned to this body mesh
-/// @param skin body texture variant
-/// @param head_mesh head mesh
-/// @param head_tex head texture
-/// @param teeth_tex teeth texture
-/// @param armor_inst armor (C_ITEM instance) to be equipped or `-1` for no armor 
-func void Mdl_SetVisualBody(var instance npc,
-                            var string body_mesh,
-                            var int body_tex,
-                            var int skin,
-                            var string head_mesh,
-                            var int head_tex,
-                            var int teeth_tex,
-                            var int armor_inst       ) {};
-
-/// Set the animation set (also dictates models you can set using the `Mdl_SetVisualBody`)
-///
-/// @param npc NPC to apply the animation set to 
-/// @param animation_set name of the MDS file that contains the animation set
-func void Mdl_SetVisual(var instance npc, var string animation_set) {};
-
-/// Start a face animation
-///
-/// @param npc NPC to apply the animation to 
-/// @param name animation name
-/// @param intensity intensity of the animation 0.0 to 1.0
-/// @param holdtime how long should the animation be held for `-2` will use the MMS defined value, '-1' will make the hold time infinite
-func void Mdl_StartFaceAni(var c_npc npc,
-                           var string name,
-                           var float intensity,
-                           var float holdtime) {};
-
-/// Start a random face animation
-///
-/// @param npc NPC to apply the animation to 
-/// @param name animation name
-/// @param timemin minimum time after which the ani should be started (in seconds)
-/// @param timeminvar minimum boundary variation (in seconds)
-/// @param timemax maximum time after which the ani should be started (in seconds)
-/// @param timemaxvar maximum boundary variation (in seconds)
-/// @param probmin probability (0.0 to 1.0) to choose the lower boundary time
-func void Mdl_ApplyRandomFaceAni(var c_npc npc,
-                                 var string name,
-                                 var float timemin,
-                                 var float timeminvar,
-                                 var float timemax,
-                                 var float timemaxvar,
-                                 var float probmin) {};
-
\ No newline at end of file diff --git a/cs/zengin/scripts/index.html b/cs/zengin/scripts/index.html deleted file mode 100644 index 9c134b98b8..0000000000 --- a/cs/zengin/scripts/index.html +++ /dev/null @@ -1,34 +0,0 @@ - Scripts - Gothic Modding Community

Scripts

ZenGin uses its own scripting language called Daedalus. It is similar to C programming language, so if you know some C programming, it will be quite easy to get started.

The Scripts directory is where the scripts live. You will be able to find Daedalus script files - .d extension and .src files, that list all files to be compiled.

Daedalus scripts can be edited in any text editor. To get useful features like syntax highlighting you can use community developed tools like

\ No newline at end of file diff --git a/cs/zengin/sound/index.html b/cs/zengin/sound/index.html deleted file mode 100644 index 4bf6ec4bc3..0000000000 --- a/cs/zengin/sound/index.html +++ /dev/null @@ -1,35 +0,0 @@ - Sound - Gothic Modding Community

Sound

ZenGin uses .wav files for playing Sound Effects and Dubbing.

Info

In-game soundtrack isn't saved in .wav sound files. See Music.

Properties

Original gothic sound files has following properties:

SFX

Sound effects (SFX) are sounds made by monsters, spells, weapons etc. Sound effects are defined in multiple places, in .mds files as part of the animation EventBlocks, or in the SFX Daedalus scripts. Sounds are located in the _work/Data/Sound/SFX directory.

Speech

Dubbing for dialogues is located into _work/Data/Sound/Speech folder. Every single AI_Output has its own sound file with name defined in the function itself.

For this dialogue line

AI_Output(self,hero,"Info_Diego_Gamestart_11_00"); //I'm Diego.
-
the engine will play Info_Diego_Gamestart_11_00.wav sound file (if it exists).
\ No newline at end of file diff --git a/cs/zengin/sound/tutorials/change_sfx/index.html b/cs/zengin/sound/tutorials/change_sfx/index.html deleted file mode 100644 index 08da1a93bc..0000000000 --- a/cs/zengin/sound/tutorials/change_sfx/index.html +++ /dev/null @@ -1,34 +0,0 @@ - Changing Sound Effect - Gothic Modding Community

Changing Sound Effect

This is Gothic VDFS. It is a tool that allows you to pack and unpack files in .VDF and .MOD format.

Screenshot_1

Let us start with unpacking "Sound" file:

  1. In the "(Viewer)" tab, in the "Filename", go to your Gothic or Gothic II/Data folder and choose "Sound.VDF".
  2. Create a folder on your desktop or any other easily accessible place on your computer. Name it however you want.
  3. Go to "Root path" and choose the folder you just created.
  4. Press "Extract volume" if you want to unpack all sound files.

The chosen file should be unpacking right now.
image

Here are the files we just extracted:
image

It can oftentimes be tricky to find the sound you are looking for, but we will leave that for later. Let's just see how can we change a sound file in the game now.

  1. Get yourself any short sound file.
  2. In order for the sound to work in the game, it needs to be in mono .wav format. A lot of programs let you convert a file such as Audacity, so do just that;
  3. Rename your converted file into "INV_CHANGE.WAV" and replace it in SFX folder you just extracted;
  4. Go back to Gothic VDFS, go to (Builder) tab;
  5. In "Filename" you choose how do you want your file to be called and its location. I recommend creating separate folder and putting it there. You can also name the file however you want, as long as it has higher time stamp (more on that later) than original Sounds file. To create it as .VDF file, choose "All file" in the "Save file as" and call it "Sounds.VDF";
  6. In "Root path" go to and choose "_WORK" folder;
  7. In the field just below "Comment", add a * character and then click on the + next to it;
  8. Press "Build", and if you did everything right, the folder is being packed back into .VDF file;

That's how a successful process looks like:
image

Now get the file you just created, and put it in your Gothic/Data folder replacing the old one. The file we just replaced changes the sound in main menu and the inventory. If you can hear it, congratulations, you did it!

\ No newline at end of file diff --git a/cs/zengin/textures/index.html b/cs/zengin/textures/index.html deleted file mode 100644 index ba9246f794..0000000000 --- a/cs/zengin/textures/index.html +++ /dev/null @@ -1,34 +0,0 @@ - Textures - Gothic Modding Community

Textures

Textures are pictures that get projected onto a 3D models and on a 2D user interface in the game. We will discuss how to work with textures in this section.

\ No newline at end of file diff --git a/cs/zengin/tools/daedalus_tools/daedalus_language_server/index.html b/cs/zengin/tools/daedalus_tools/daedalus_language_server/index.html deleted file mode 100644 index 1117f11748..0000000000 --- a/cs/zengin/tools/daedalus_tools/daedalus_language_server/index.html +++ /dev/null @@ -1,34 +0,0 @@ - Daedalus Language Server - Gothic Modding Community
\ No newline at end of file diff --git a/cs/zengin/tools/dls/index.html b/cs/zengin/tools/dls/index.html deleted file mode 100644 index f1ea3a7574..0000000000 --- a/cs/zengin/tools/dls/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/cs/zengin/tools/gothic_sourcer/index.html b/cs/zengin/tools/gothic_sourcer/index.html deleted file mode 100644 index ec81cc72e3..0000000000 --- a/cs/zengin/tools/gothic_sourcer/index.html +++ /dev/null @@ -1,34 +0,0 @@ - Gothic Sourcer - Gothic Modding Community

Gothic Sourcer

Gothic Sourcer can be used to do a lot of things.

Todo

TODO

\ No newline at end of file diff --git a/cs/zengin/tools/gothic_vdfs/index.html b/cs/zengin/tools/gothic_vdfs/index.html deleted file mode 100644 index 9bbd7ec638..0000000000 --- a/cs/zengin/tools/gothic_vdfs/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/cs/zengin/tools/index.html b/cs/zengin/tools/index.html deleted file mode 100644 index 907e2f2557..0000000000 --- a/cs/zengin/tools/index.html +++ /dev/null @@ -1,34 +0,0 @@ - Tools - Gothic Modding Community

Tools

The community has developed many tools to help with the creation of Gothic mods.

Note

This list is a work in progress.

Daedalus

  • Daedalus Language Server - a VS Code/VS Codium extension that adds IDE like functionality for Daedalus scripting language
  • Ikarus - A daedalus library for the game Gothic. Exploits the interpreter to allow arbitrary memory access and defines a lot of useful functions for interfacing with the engine.
  • LeGo - A daedalus library for the game Gothic. It contains various packages to support modders.
  • AFSP - Fawkes' & Auronen's script package for Gothic 1 and Gothic 2: Night of the Raven.
  • Ninja - Ninja introduces the possibility of true modular modifications for the video games Gothic and Gothic 2 Night of the Raven.

VDFS tools

  • GothicVDFS - NicoDE's viewer, extractor and builder for .vdf and .mod volumes
  • VDFS Tool - Gratt's Union VDFS viewer, extractor, builder, optimizer and ZIP compressor for .vdf and .mod volumes

World Editors

  • Spacer - the original world editor for ZenGin, ships with the MDK
  • Union Gothic World Editor - Saturas' world editor, supports new object classes created with Union
  • Gothic World Editor - World editor for vanilla worlds, works with G1, G2 and G2 NotR worlds
  • Spacer.NET - A modernised version of Spacer available as a Gothic Mod.
\ No newline at end of file diff --git a/cs/zengin/tools/vdfs_tool/index.html b/cs/zengin/tools/vdfs_tool/index.html deleted file mode 100644 index ff3e73cc59..0000000000 --- a/cs/zengin/tools/vdfs_tool/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/cs/zengin/tools/vdfs_tools/gothic_vdfs/index.html b/cs/zengin/tools/vdfs_tools/gothic_vdfs/index.html deleted file mode 100644 index 55d40664a6..0000000000 --- a/cs/zengin/tools/vdfs_tools/gothic_vdfs/index.html +++ /dev/null @@ -1,34 +0,0 @@ - GothicVDFS - Gothic Modding Community

GothicVDFS

Gothic VDFS is still the most popular VDFS tool. It was created by NicoDE.

Download

You can download the tool from NicoDE's website - direct link.

Quick overview

\ No newline at end of file diff --git a/cs/zengin/tools/vdfs_tools/vdfs_tool/index.html b/cs/zengin/tools/vdfs_tools/vdfs_tool/index.html deleted file mode 100644 index eb1e18c78a..0000000000 --- a/cs/zengin/tools/vdfs_tools/vdfs_tool/index.html +++ /dev/null @@ -1,34 +0,0 @@ - VDFS Tool - Gothic Modding Community

VDFS Tool

VDFS Tool is a new program that supports new features introduced to VDFS by the Union team. Like ZIP compression or drag and drop support.

Download

You can download the tool from the post on WoP.ru - VDFS Tool or using the Resource Manager

Quick overview

\ No newline at end of file diff --git a/cs/zengin/tools/zSpy/index.html b/cs/zengin/tools/zSpy/index.html deleted file mode 100644 index eb5c59d73c..0000000000 --- a/cs/zengin/tools/zSpy/index.html +++ /dev/null @@ -1,49 +0,0 @@ - zSpy - Gothic Modding Community

zSpy

zSpy is a debugging tool that displays most of the operations performed by the engine during the Gothic or Spacer running.

Example image of running zSpy

zSpy

Warning

zSpy must be started before Gothic or the Spacer is started so that the program can find it. Sometimes in Gothic I this has to be done manually, in Gothic II This is done by the GothicStarter_mod.

In order to be able to follow the messages in zSpy, Gothic should be started in the window. The corresponding startup option can be found in GothicStarter (mod). Within Gothic, when Marvin mode is activated, you can switch between window and full-screen mode at any time with the F3 key.

Log Level

With the -zlog# command in GothicStarter, you can specify how many messages zSpy will output. # can be a number between -1 and 9. Used for:

  • -1 - Disable every message (expect fatal errors)

  • 0 - Shows only warnings, faults and fatal errors

  • 1 - 9 - Display more information. Every Information has their priority. If you select 1, the program displays only messages with priority =< 1, with 5 only priority =< 5, and with 9, almost everything that Gothic can produce.

For general debugging, recommended value is 5.

Output

The zSpy issues its reports in the following form:

1
-2
Time  Type  Priority  User   Message              ...      <filename,       #line>
-00:21 Info:  3        B:     GOTHIC: Exiting game ... .... <oGameManager.cpp,#617>
-

Time

Time elapsed since the start of Gothic.exe

Type

Type of message. The following message types are distinguished:

  • Fatal: - Critical error causing application to close.

  • Fault: - A simple bug that will not cause the application to stop, but display or performance issues may occur.

  • Warn: - A warning of possible consequences. An error that follows soon afterwards could have something to do with it.

  • Info: - General information about the progress of the program.

Priority

Priority level of the message. Messages with lower priority (higher number) can be disabled. See log level.

User

User ID - a letter defined by every engine developer to highlight its logs

  • D - Dieter
  • U - Ulf
  • B - Bert
  • C - Carsten
  • A - Andre
  • X - Kurt

Message

The most important part. A message that contains:

  • Symbol representing a program module. The names are mostly self-explanatory, so there is no need to type them all (MDL = 3D models, PAR = Parser etc.).

  • The message for the user.

Configuration

In zSpy, you can customize the font and its color depending on the type of message.

In addition, you can configure the logging options:

  • Filtering various messages (Info, Warn, Fault, Fatal).
  • Auto show/hide zSpy when starting/stopping Gothic.
  • Saving the log file to a separate file.

Console commands

List of console commands related with zSpy.

Note

The list is work in progress. Console commands needs a separate article or section.

zerr level

Sets a level of logging.

zerr level <#>
-

zerr searchspy

Links zSpy with Gothic. Useful when you run zSpy when the game is already running.

zerr searchspy
-

zerr authors

Sets a filter to display only messages of one author.

zerr authors <letter>
-
  • <letter> - One of the letters listed here.

zerr rem

Includes a remark into the log.

zerr rem
-
Looks like that:
1
-2
-3
-4
00:46 Info:  3 B:       OPT: Blood-Details: Value=2 .... <oGameManager.cpp,#1302>
-00:57 ---------------
-00:57 ---------------
-01:01 Info:  3 B:     GMAN: Leaving Menu-Section .... <oGameManager.cpp,#1537>
-

zerr status

Displays a current status of zSpy in the console.

zerr status
-
\ No newline at end of file diff --git a/cs/zengin/union/index.html b/cs/zengin/union/index.html deleted file mode 100644 index 5ade617190..0000000000 --- a/cs/zengin/union/index.html +++ /dev/null @@ -1,34 +0,0 @@ - Union - Gothic Modding Community

Union

Union is a system to patch and extend Gothic's engine the ZenGin. It allows you to load .dll files - ZenGin extensions created using the Gothic/Union SDK and .patch files - files designed to patch the game's executable. The Union installer also contains the SystemPack a collection of bug fixes and engine edits that improve performance.

Plug-ins

Union plugins are shipped in the form of a .dll library. This library contains the compiled C++ code with the Union SDK and an embedded .patch file.

Union SDK & Gothic API

Union software development kit is a collection of tools and the Gothic API that allow you to create Union plugins and alter the engine's behavior.
Gothic API is a set of 4 interfaces (each for one different ZenGin version) that allow you to interface with the engine, access the engine objects, change their behavior and introduce new classes and functionality.

PATCH file format

The .patch file contains one or more small programs that are designed to change the engine code (game executable). This is usually done to fix bugs. Union plug-ins contain an embedded .patch file and this file usually contains changes to the binary necessary for the proper function of the plug-in.

\ No newline at end of file diff --git a/cs/zengin/union/plugins/zbassmusic/index.html b/cs/zengin/union/plugins/zbassmusic/index.html deleted file mode 100644 index ae26430779..0000000000 --- a/cs/zengin/union/plugins/zbassmusic/index.html +++ /dev/null @@ -1,34 +0,0 @@ - zBassMusic - Gothic Modding Community

zBassMusic

zBassMusic is a modern music system for Gothic I and Gothic II NotR based on BASS Audio Library made by Silver Ore Team. It replaces the old DirectMusic system to let the modders create music for Gothic as regular audio files instead of DirectMusic format.

Info

For the plugin documentation, visit the github site of a project. The documentation is build into the code.

Contacts
Authors Silver Ore Team - tehe
GitHub zBassMusic
Discord Gothic Modding Community server

Features

  • Music playback with modern audio formats like WAV, MP3, OGG
  • Out-of-the-box support for existing C_MUSICTHEME instances
  • Scriptable interface to take full control of music scheduling
  • Loading music files from VDFS volumes (excluding .sgt)
  • Backwards compatibility with DirectMusic .sgt files
\ No newline at end of file diff --git a/cs/zengin/union/plugins/zgamepad/controls/index.html b/cs/zengin/union/plugins/zgamepad/controls/index.html deleted file mode 100644 index a884fe6fa2..0000000000 --- a/cs/zengin/union/plugins/zgamepad/controls/index.html +++ /dev/null @@ -1,140 +0,0 @@ - Controls customization - Gothic Modding Community

Gamepad controls

The zGamePad plugin comes with a default control scheme, but it is possible to create your own. The plugin will search for any file with the .gamepad.overlay extension placed in Gothic/System directory or in any of the loaded .mod and .vdf archives.

Control file syntax

Gamepad controls are set using the .gamepad configuration file. This file encodes the controls for different actions in the game and the hint string in multiple languages.

Warning

The .gamepad file must be encoded in Unicode or UTF-8 to accommodate the multilingual hint strings.

Regions

The format supports code blocks specified by the #region and #endregion keywords. These regions do not have any syntactical meaning, they only offer a convenient way to collapse sections of the code in editors with the syntax highlighting capabilities such as Notepad++

Regions
1
-2
-3
-4
-5
-6
-7
#region strings
-    // TODO
-#endregion
-
-#region fight scheme
-    // TODO
-#endregion
-

Comments

Comments are useful for quick information or just to disable some old code that might come in handy later. The .gamepad file syntax supports C++ line comments using two forward slashes //.

Warning

Comments can only be used at the start of any given line!

Comments
1
-2
// this is a comment
-KeyRecord // this is NOT a comment
-

Strings

Strings are used for interactive hints. They should be defined at the top of the file. To define a string, use the keyword String. Strings have the following format:

Multilang string syntax
1
-2
-3
-4
String [id]
-    [langTag] [text]
-    [langTag] [text]
-    [langTag] [text]
-

Example

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
String interact
-    Rus "Взаимодействовать"
-    Eng "Interact"
-    Pol "Interakcja"
-    Deu "Interagieren"
-
-String remove_weapon
-    Rus "Убрать оружие"
-    Eng "Remove weapon"
-    Pol "Chowanie broni"
-    Deu "Waffe entfernen"
-
The string name must be unique and is used to reference the string while defining hints. The language tag matches the language in SystemPack.ini. If the file does not contain the user's language, English will be taken by default. If there is no English, then the first one.

Control bindings

A binding is a description of an event that includes emulation object and conditions. Hints are part of the binding.
The general structure of the bind starts with the keyword KeyRecord and has the following format:

Control binding
1
-2
-3
-4
-5
-6
KeyRecord [modifier]
-    Id          [key name]
-    Combination [gamepad keys]
-    Emulation   [engine logical and absolute keys]
-    Condition   [engine logical, absolute keys or logical functions]
-    Help        [name of the hint string]
-
  • Id - unique identifier used by other users to override this control binding
  • [modifier] - can be empty or take the value of Toggled If the value is empty, the control binding will work as long as the player holds down the specified button or button combination.
    If the value is Toggled, the control binding will work only when the player toggles the button or button combination. (One press to start sneaking, another press to stop sneaking)
  • Combination - these are the gamepad buttons that the player must press or hold to activate the control binding.
  • Emulation - specify which buttons will be emulated. You can specify absolute buttons, or that are defined in the game settings (logical).
  • Condition - specify the condition under which the control binding can be activated. To invert condition, use the operator ! before the operand (!Cond_IsOverlayTop, !JOY_B)
  • Help - name of the text string with a hint which will be displayed when the Conditions are met.

  • [gamepad keys] - Gamepad key list

  • [engine logical keys] - Engine logical key list
  • [engine absolute keys] - Engine absolute key list
  • [logical functions] - Logical function list

Tip

All operators are optional! This means that if a binding should only show a hint, it doesn't have to contain Combination.

Example

Control binding examples
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
KeyRecord
-    Id          StopUsingPicklock
-    Combination JOY_B
-    Emulation   KEY_DOWN
-    Condition   Cond_InterfaceIsOpen, Cond_UsesPicklock, !JOY_B
-
-KeyRecord Toggled
-    Id          ReturnToHumanForm
-    Combination JOY_A
-    Emulation   KEY_RETURN
-    Condition   Cond_InTransformation
-    Help        end_transform
-
-KeyRecord
-    Id          QuickRingSelectSlot
-    Combination JOY_RSTICK_FULL
-    Condition   !Cond_InventoryIsOpen, Cond_IsOverlayTop
-    Help        focus_item
-

Controls override

If you want to change or remove bindings from another controls file, use the KeyDisable keyword.
Default controls file

Controls override syntax
KeyDisable [fileName].[Id]
-
Where fileName is the name of the controls file without extension and id is a key of the binding.

Example

Controls override example
1
-2
-3
-4
-5
-6
-7
-8
// remove key from the main controls file
-KeyDisable Controls.ArrowDown
-
-// create new key based on the same buttons
-KeyRecord Toggled
-    Id          ArrowDownNew
-    Combination JOY_DOWN
-    Emulation   GAME_DOWN
-
\ No newline at end of file diff --git a/cs/zengin/union/plugins/zgamepad/index.html b/cs/zengin/union/plugins/zgamepad/index.html deleted file mode 100644 index 2565b1bd86..0000000000 --- a/cs/zengin/union/plugins/zgamepad/index.html +++ /dev/null @@ -1,34 +0,0 @@ - zGamePad - Gothic Modding Community

zGamePad

zGamePad plugin adds gamepad support for ZenGin games.

Important

Visit the excellent original GitHub wiki page.

Contacts
Author Gratt
GitHub zGamePad
Forum zGamePad

Gamepad support

  • All xinput compatible (including emulators)
  • Xbox controller family
  • Dualshock 4
  • Dualsense
  • Nintendo Switch Joy-Cons
  • Nintendo Switch Pro Controller

Features

  • Natural Movements
    Intuitiveness and smoothness of movement controls is the main goal of this plugin. Touch the world of Gothic with your hands.
  • Interactive hints
    Interactive hints will help you in mastering the controls. You can always customize their appearance or disable them.
  • Quick access
    The plugin has two quick access rings - **weapons and items. Use them to always have access to your items.
  • Automatic save naming
    Sit comfortably. You do not have to reach for your keyboard, because the plugin itself will give a name to your saves.
  • Saves rotation
    The best alternative to quicksaves for gamepad controls.
  • Vibration response
    Immerse yourself in the game even more. Vibration will allow you to feel your character and everything that happens in the world.
  • Target locking
    The plugin will always help you win. Keeping the enemy in focus will allow you to fight much more effectively.
  • Stuck protection
    Oops! If you get stuck, hold both analogue sticks for a few seconds and the character will reset.
\ No newline at end of file diff --git a/cs/zengin/union/plugins/zgamepad/keys_engine_absolute/index.html b/cs/zengin/union/plugins/zgamepad/keys_engine_absolute/index.html deleted file mode 100644 index 09962e27d9..0000000000 --- a/cs/zengin/union/plugins/zgamepad/keys_engine_absolute/index.html +++ /dev/null @@ -1,383 +0,0 @@ - Engine absolute keys - Gothic Modding Community

Engine absolute keys

Absolute keys are the physical keys on your keyboard.

  1
-  2
-  3
-  4
-  5
-  6
-  7
-  8
-  9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
-100
-101
-102
-103
-104
-105
-106
-107
-108
-109
-110
-111
-112
-113
-114
-115
-116
-117
-118
-119
-120
-121
-122
-123
-124
-125
-126
-127
-128
-129
-130
-131
-132
-133
-134
-135
-136
-137
-138
-139
-140
-141
-142
-143
-144
-145
-146
-147
-148
-149
-150
-151
-152
-153
-154
-155
-156
-157
-158
-159
-160
-161
-162
-163
-164
-165
-166
-167
-168
-169
-170
-171
-172
-173
-174
-175
MOUSE_DX
-MOUSE_DY
-MOUSE_UP
-MOUSE_DOWN
-MOUSE_LEFT
-MOUSE_RIGHT
-MOUSE_WHEELUP
-MOUSE_WHEELDOWN
-MOUSE_BUTTONLEFT
-MOUSE_BUTTONRIGHT
-MOUSE_BUTTONMID
-MOUSE_XBUTTON1
-MOUSE_XBUTTON2
-MOUSE_XBUTTON3
-MOUSE_XBUTTON4
-MOUSE_XBUTTON5
-KEY_ESCAPE
-KEY_1
-KEY_2
-KEY_3
-KEY_4
-KEY_5
-KEY_6
-KEY_7
-KEY_8
-KEY_9
-KEY_0
-KEY_MINUS
-KEY_EQUALS
-KEY_BACK
-KEY_TAB
-KEY_Q
-KEY_W
-KEY_E
-KEY_R
-KEY_T
-KEY_Y
-KEY_U
-KEY_I
-KEY_O
-KEY_P
-KEY_LBRACKET
-KEY_RBRACKET
-KEY_RETURN
-KEY_LCONTROL
-KEY_A
-KEY_S
-KEY_D
-KEY_F
-KEY_G
-KEY_H
-KEY_J
-KEY_K
-KEY_L
-KEY_SEMICOLON
-KEY_APOSTROPHE
-KEY_GRAVE
-KEY_LSHIFT
-KEY_BACKSLASH
-KEY_Z
-KEY_X
-KEY_C
-KEY_V
-KEY_B
-KEY_N
-KEY_M
-KEY_COMMA
-KEY_PERIOD
-KEY_SLASH
-KEY_RSHIFT
-KEY_MULTIPLY
-KEY_LMENU
-KEY_SPACE
-KEY_CAPITAL
-KEY_F1
-KEY_F2
-KEY_F3
-KEY_F4
-KEY_F5
-KEY_F6
-KEY_F7
-KEY_F8
-KEY_F9
-KEY_F10
-KEY_NUMLOCK
-KEY_SCROLL
-KEY_NUMPAD7
-KEY_NUMPAD8
-KEY_NUMPAD9
-KEY_SUBTRACT
-KEY_NUMPAD4
-KEY_NUMPAD5
-KEY_NUMPAD6
-KEY_ADD
-KEY_NUMPAD1
-KEY_NUMPAD2
-KEY_NUMPAD3
-KEY_NUMPAD0
-KEY_DECIMAL
-KEY_OEM_102
-KEY_F11
-KEY_F12
-KEY_F13
-KEY_F14
-KEY_F15
-KEY_KANA
-KEY_ABNT_C1
-KEY_CONVERT
-KEY_NOCONVERT
-KEY_YEN
-KEY_ABNT_C2
-KEY_NUMPADEQUALS
-KEY_PREVTRACK
-KEY_AT
-KEY_COLON
-KEY_UNDERLINE
-KEY_KANJI
-KEY_STOP
-KEY_AX
-KEY_UNLABELED
-KEY_NEXTTRACK
-KEY_NUMPADENTER
-KEY_RCONTROL
-KEY_MUTE
-KEY_CALCULATOR
-KEY_PLAYPAUSE
-KEY_MEDIASTOP
-KEY_VOLUMEDOWN
-KEY_VOLUMEUP
-KEY_WEBHOME
-KEY_NUMPADCOMMA
-KEY_DIVIDE
-KEY_SYSRQ
-KEY_RMENU
-KEY_PAUSE
-KEY_HOME
-KEY_UP
-KEY_PRIOR
-KEY_LEFT
-KEY_RIGHT
-KEY_END
-KEY_DOWN
-KEY_NEXT
-KEY_INSERT
-KEY_DELETE
-KEY_LWIN
-KEY_RWIN
-KEY_APPS
-KEY_POWER
-KEY_SLEEP
-KEY_WAKE
-KEY_WEBSEARCH
-KEY_WEBFAVORITES
-KEY_WEBREFRESH
-KEY_WEBSTOP
-KEY_WEBFORWARD
-KEY_WEBBACK
-KEY_MYCOMPUTER
-KEY_MAIL
-KEY_MEDIASELECT
-KEY_BACKSPACE
-KEY_NUMPADSTAR
-KEY_LALT
-KEY_CAPSLOCK
-KEY_NUMPADMINUS
-KEY_NUMPADPLUS
-KEY_NUMPADPERIOD
-KEY_NUMPADSLASH
-KEY_RALT
-KEY_UPARROW
-KEY_PGUP
-KEY_LEFTARROW
-KEY_RIGHTARROW
-KEY_DOWNARROW
-KEY_PGDN
-
\ No newline at end of file diff --git a/cs/zengin/union/plugins/zgamepad/keys_engine_logical/index.html b/cs/zengin/union/plugins/zgamepad/keys_engine_logical/index.html deleted file mode 100644 index a112c96ddf..0000000000 --- a/cs/zengin/union/plugins/zgamepad/keys_engine_logical/index.html +++ /dev/null @@ -1,87 +0,0 @@ - Engine logical keys - Gothic Modding Community

Engine logical keys

Logical keys are the keys you set in keyboard settings in the game menu. These can fill multiple roles in different situations and the gamepad controls can be set to emulate these logical keys.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
GAME_LEFT
-GAME_RIGHT
-GAME_UP
-GAME_DOWN
-GAME_ACTION
-GAME_SLOW
-GAME_ACTION2
-GAME_WEAPON
-GAME_SMOVE
-GAME_SMOVE2
-GAME_SHIFT
-GAME_END
-GAME_INVENTORY
-GAME_LOOK
-GAME_SNEAK
-GAME_STRAFELEFT
-GAME_STRAFERIGHT
-GAME_SCREEN_STATUS
-GAME_SCREEN_LOG
-GAME_SCREEN_MAP
-GAME_LOOK_FP
-GAME_LOCK_TARGET
-GAME_PARADE
-GAME_ACTIONLEFT
-GAME_ACTIONRIGHT
-GAME_LAME_POTION
-GAME_LAME_HEAL
-
\ No newline at end of file diff --git a/cs/zengin/union/plugins/zgamepad/keys_gamepad/index.html b/cs/zengin/union/plugins/zgamepad/keys_gamepad/index.html deleted file mode 100644 index f02c0e9dea..0000000000 --- a/cs/zengin/union/plugins/zgamepad/keys_gamepad/index.html +++ /dev/null @@ -1,85 +0,0 @@ - Gamepad keys - Gothic Modding Community

Gamepad keys

In order to set gamepad keys, you have to know the key codes as they are listed below.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
JOY_UP
-JOY_DOWN
-JOY_LEFT
-JOY_RIGHT
-JOY_MENU
-JOY_VIEW
-JOY_LSTICK
-JOY_RSTICK
-JOY_LB
-JOY_RB
-JOY_A
-JOY_B
-JOY_X
-JOY_Y
-JOY_LSTICK_LOWUP
-JOY_LSTICK_UP
-JOY_LSTICK_DOWN
-JOY_LSTICK_LEFT
-JOY_LSTICK_RIGHT
-JOY_RT
-JOY_LT
-JOY_DPAD
-JOY_UPDOWN
-JOY_LEFTRIGHT
-JOY_LSTICK_FULL
-JOY_RSTICK_FULL
-
\ No newline at end of file diff --git a/cs/zengin/union/plugins/zgamepad/logical_functions/index.html b/cs/zengin/union/plugins/zgamepad/logical_functions/index.html deleted file mode 100644 index e462cdd1cd..0000000000 --- a/cs/zengin/union/plugins/zgamepad/logical_functions/index.html +++ /dev/null @@ -1,89 +0,0 @@ - Logical functions - Gothic Modding Community

Logical function names

Conditions for when to show or allow the control binding to work are specified using these logic functions. They describe different useful states of the game or user interface, allowing the user to set when will a certain control work.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
Cond_FightMode        - player is in the fight mode
-Cond_FightModeMelee   - player is in the melee fight mode
-Cond_FightModeRange   - player is in the ranged fight mode
-Cond_FightModeMagic   - player is in the magical fight mode
-Cond_CanShoot         - player is in the aim mode and can shoot now
-Cond_CanSneaking      - player is sneaking now
-Cond_Diving           - player is diving now
-Cond_HasFocusVob      - player has a focus vob
-Cond_HasFocusNpc      - player has a focus npc
-Cond_OnChooseWeapon   - weapon selection is active
-Cond_InventoryIsOpen  - inventory is open
-Cond_InTransformation - player is transformed
-Cond_VideoIsOpen      - video is playing
-Cond_CanLockTarget    - player in the fight mode now and can lock the focus vob
-Cond_G1               - this engine is a Gothic 1 (or sequel)
-Cond_G2               - this engine is a Gothic 2 NoTR (or classic)
-Cond_IsDialogTop      - dialog window is open on the top
-Cond_IsDocumentTop    - document object is open on the top
-Cond_IsOverlayTop     - gamepad overlay object is open on the top
-Cond_IsMenuTop        - game menu is open on the top
-Cond_OnSpellBook      - magic selection ring is active
-Cond_IsPlayerTalking  - player is talking to someone
-Cond_InterfaceIsOpen  - open any interface element
-Cond_HasLeftContainer - the left container is open (chest, plunder, trader)
-Cond_UsesPicklock     - player is picking a lock now
-Cond_IsOnTrade        - player is trading
-Cond_IsOverlayTop     - gamepad overlay object is open on the top
-Cond_IsMenuTop        - game menu is open on the top
-
\ No newline at end of file diff --git a/cs/zengin/union/sdk/events/index.html b/cs/zengin/union/sdk/events/index.html deleted file mode 100644 index 8b9a9d463b..0000000000 --- a/cs/zengin/union/sdk/events/index.html +++ /dev/null @@ -1,179 +0,0 @@ - Game Events - Gothic Modding Community

Game Events

Union defines several Game Events that are dispatched when a specific event occurs in-game. Handlers are defined in Plugin.cpp and we can use them to execute our code during specific moments of the application lifetime.

Events

Initialization

Game_Entry

Executes at the entry point of the Gothic executable. During this time the engine classes are not yet initialized, so using them may cause an access violation. The entry point be used to execute some logic before Gothic loads itself.

1
-2
-3
void Game_Entry() {
-
-}
-

Game_DefineExternals

Executes before the Daedalus parser starts loading scripts. It's meant to define custom external functions.

1
-2
-3
void Game_DefineExternals() {
-
-}
-

Game_Init

Executes right after DAT files are loaded and just before the main menu shows up.

1
-2
-3
void Game_Init() {
-
-}
-

Level Change

Game_LoadBegin

Executes when we initiate a level change by one of the possible actions. The default plugin template uses a common LoadBegin() function to handle all events but we also can write different logic for different cases.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
void LoadBegin() {
-
-}
-
-// When player clicks "New Game"
-void Game_LoadBegin_NewGame() {
-    LoadBegin();
-}
-
-// When player loads a saved game
-void Game_LoadBegin_SaveGame() {
-    LoadBegin();
-}
-
-// When player changes ZEN by a trigger
-void Game_LoadBegin_ChangeLevel() {
-    LoadBegin();
-}
-

Game_LoadEnd

Executes when the level loading finishes. The default plugin template uses a common LoadEnd() function to handle all events but we also can write different logic for different cases.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
void LoadEnd() {
-
-}
-
-// When player clicks "New Game"
-void Game_LoadEnd_NewGame() {
-    LoadEnd();
-}
-
-// When player loads a saved game
-void Game_LoadEnd_SaveGame() {
-    LoadEnd();
-}
-
-// When player changes ZEN by a trigger
-void Game_LoadEnd_ChangeLevel() {
-    LoadEnd();
-}
-

Game_LoadBegin_Trigger

Executes when the player enters a trigger that initiates ZEN change.

1
-2
-3
void Game_LoadBegin_Trigger() {
-
-}
-

Game_LoadEnd_Trigger

Executes after the player has entered a trigger that initiates ZEN change.

1
-2
-3
void Game_LoadEnd_Trigger() {
-
-}
-

Game_ApplyOptions

Executes after Game_LoadEnd, when we save the game, and also when we exit the game. It's meant to be used to apply options from INI files.

1
-2
-3
void Game_ApplyOptions() {
-
-}
-

Game Loop

Game_PreLoop

Executes at the start of every frame.

1
-2
-3
void Game_PreLoop() {
-
-}
-

Game_Loop

Executes at every frame.

1
-2
-3
void Game_Loop() {
-
-}
-

Game_PostLoop

Executes at the end of every frame.

1
-2
-3
void Game_PostLoop() {
-
-}
-

Game_MenuLoop

Executes at every frame when the game menu is active.

1
-2
-3
void Game_MenuLoop() {
-
-}
-

Game_SaveBegin

Executes when the player started saving a game.

1
-2
-3
void Game_SaveBegin() {
-
-}
-

Game_SaveEnd

Executes when the game save finishes.

1
-2
-3
void Game_SaveEnd() {
-
-}
-

Game_Pause

Executes when the player opens the in-game menu.

1
-2
-3
void Game_Pause() {
-
-}
-

Game_Unpause

Executes when the player leaves the in-game menu and also when the player loads a saved game.

1
-2
-3
void Game_Unpause() {
-
-}
-

Shutdown

Game_Exit

Executes when the player exits the game.

1
-2
-3
void Game_Exit() {
-
-}
-
\ No newline at end of file diff --git a/cs/zengin/union/sdk/externals/index.html b/cs/zengin/union/sdk/externals/index.html deleted file mode 100644 index f7d2994c34..0000000000 --- a/cs/zengin/union/sdk/externals/index.html +++ /dev/null @@ -1,117 +0,0 @@ - Externals - Gothic Modding Community

Externals

Externals are functions defined by the Gothic engine that can be called from scripts. Union SDK provides symbols for pointers to global zCParser instances that we can use to interact with the parser and to define a custom external function.

1
-2
-3
-4
-5
-6
-7
extern zCParser*    parser;
-extern zCParser*&   parserSoundFX;
-extern zCParser*&   parserParticleFX;
-extern zCParser*&   parserVisualFX;
-extern zCParser*&   parserCamera;
-extern zCParser*&   parserMenu;
-extern zCParser*&   parserMusic;
-

Creating custom external

To create an external we need to define a function handler and register it in the parser. Before we start, it's good to write down a Daedalus function signature so we can see the return and argument types that will be important later.

func string AddNumbers(var int FirstArgument, var int SecondArgument, var string ThirdArgument)  {}
-

Function handler

External function handler signature must:

  • return int or bool
  • use __cdecl calling convention (default in C++)
  • take no arguments

Inside the handler, we can use the global parser to pop function arguments and push the return value from/to the stack. It's important to pop the arguments in reverse order and to pop all of them even if we are not going to use them. Similarly, the return value must always be set if any and must never be set if the function returns void. If we don't follow the rules, the stack may get corrupted and lead to the Gothic crash.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
// __cdecl is optional because it's the default calling convention
-int __cdecl AddNumbers_External()
-{
-    // Declare arguments
-    int FirstArgument;
-    int SecondArgument;
-    zSTRING ThirdArgument;
-
-    // Pop arguments from the stack **IN REVERSE ORDER**
-    parser->GetParameter(ThirdArgument);
-    parser->GetParameter(SecondArgument);
-    parser->GetParameter(FirstArgument);
-
-    // Execute function logic
-    int result = FirstArgument + SecondArgument;
-    zSTRING output = ThirdArgument + zSTRING(result);
-
-    // Push return value
-    parser->SetReturn(output);
-
-    // Return value is ignored, so 0 or 1 is fine.
-    return 0;
-}
-

Register external

Externals should be registered in the parser during the Game_DefineExternals game event. We need to call parser->DefineExternal with variadic arguments:

  • external function name in Daedalus
  • reference to function handler
  • return type
  • ...argument types
  • zPAR_TYPE_VOID indicates the end of the argument types list
1
-2
-3
void Game_DefineExternals() {
-    parser->DefineExternal("AddNumbers", AddNumbers_External, zPAR_TYPE_STRING, zPAR_TYPE_INT, zPAR_TYPE_INT, zPAR_TYPE_STRING, zPAR_TYPE_VOID);
-}
-

Available types are defined by an enum:

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
enum {
-    zPAR_TYPE_VOID,
-    zPAR_TYPE_FLOAT,
-    zPAR_TYPE_INT,
-    zPAR_TYPE_STRING,
-    zPAR_TYPE_CLASS,
-    zPAR_TYPE_FUNC,
-    zPAR_TYPE_PROTOTYPE,
-    zPAR_TYPE_INSTANCE
-};
-
\ No newline at end of file diff --git a/cs/zengin/union/sdk/getting_started/index.html b/cs/zengin/union/sdk/getting_started/index.html deleted file mode 100644 index e5cc04ddef..0000000000 --- a/cs/zengin/union/sdk/getting_started/index.html +++ /dev/null @@ -1,78 +0,0 @@ - Getting Started - Gothic Modding Community

Getting Started

This article provides a beginner-friendly tutorial for setting up and compiling a Union project. Instructions for installing Union SDK are located at Union SDK.

Creating Union plugin

Create a Visual Studio project

To create a Union plugin project inside Visual Studio we need to use File -> New -> Project. On the next screen, we select "Union Plugin 1.0m", and click Next. For the project configuration, we should choose:

Key Value
Project name eg. MyPlugin
Location Directory where to store the source code
Solution Create new solution
Solution name eg. MyPlugin

We will also check "Place solution and project in the same directory" because our plugin consists of only one project, so there is no need to complicate the file structure.

File Structure

Folder / File Description
Engine SDK/ In this folder, we have the Gothic Engine API in the form of header files. Most of the files between engines are very similar to each other but they can't be used interchangeably because each engine has slightly different API and addresses of functions.
Engine SDK/User API/ These are empty files that are included in the corresponding engine headers. There are meant for placing additional methods extending classes that can be used for example in Hooks.
Plugin/System/ DLL entry point generated by Union. We shouldn't modify anything here.
Plugin/Workspace/Interface/ These are header files containing headers and source files important in correct order and an Interface.cpp file that merges all the code into one file.
Plugin/Workspace/Plugin/ Finally, this is the source code of the plugin and especially Plugin.cpp where we can create code executed on Game Events.

Build Configuration

Each Union plugin may target one or many versions of the Gothic engine and to select the proper API, Union SDK defines several build configurations for every engine, configuration, and also multiplatform build options. Each Target/Configuration combination is named [ENGINE] [CONFIGURATION].

Configurations:

  • Debug: Unoptimized build with debug symbols for development.
  • MD Release: Optimized build for release versions. Runtime Library: Multi-threaded DLL (/MD)
  • MT Release: Optimized build for release versions. Runtime Library: Multi-threaded (/MT)

Engines:

  • G1: Gothic I
  • G1A: Gothic Sequel
  • G2: Gothic II
  • G2A: Gothic II NotR
  • MP x2: Multiplatform target for both Gothic I (G1) and Gothic II NotR (G2A)
  • MP x4: Multiplatform target for all engine versions (Gothic I, Gothic Sequel, Gothic II, Gothic II NotR)

For learning Union, it's suggested to select G2A Debug for Gothic II NotR or G1 Debug for Gothic I.

Project Configuration

The Union plugin is a regular C++ Visual Studio project so it's possible to configure the project, compiler, linker, and debugger as we wish by going into Project -> Properties. For a starter, we should go to the General tab and check if Platform Toolset is installed and selected. If not, we should select one that's available on our system. Union was created with v100 but it also supports the newest toolkits, so it's best to select a modern one.

In the General tab, we can also specify the Output Directory where the plugin DLL will be placed after the build. During development, we can set it to <GOTHIC_DIR>/System/Autorun where <GOTHIC_DIR> is the root folder of the Gothic installation with Union that we will use for testing. Each DLL file placed in System/Autorun is automatically loaded by Union runtime.

Another method is to put the DLL in the System directory and modify Gothic.ini to include

1
-2
-3
[PLUGIN]
-# Plugin file names without .dll 
-PluginList = MyPlugin 
-

Build the plugin

After the initial configuration, we are ready to code something and see if our configuration is working. Let's collect some information about Union and display it with a MessageBox when the game starts. To do so, we locate the Plugin.cpp file and put our logic in one of the Game Events handlers. The best for that is Game_Init() because it's executed right after the engine loads every DAT file but before anything else:

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
void Game_Init() {
-    const CPlugin* myPlugin = CPlugin::GetCurrentPlugin();
-
-    CStringA gothicVersion;
-    switch (Union.GetEngineVersion()) {
-        case Engine_G1:  gothicVersion = "Gothic I";
-        case Engine_G1A:  gothicVersion = "Gothic Sequel";
-        case Engine_G2:  gothicVersion = "Gothic II";
-        case Engine_G2A:  gothicVersion = "Gothic II NoTR";
-    }
-
-    CStringA message = "Plugin: " + myPlugin->GetName() + "\n";
-    message = message + "Union Version: " + Union.GetUnionVersion().ToString() + "\n";
-    message = message + "Gothic Version: " + gothicVersion;
-
-    Message::Info(message, "Hello World");
-}
-

Now we can Build (F7) the project to create the DLL. If we have set up Output Directory before, the plugin will deploy directly to the game. Otherwise, we can copy it manually from Bin to <GOTHIC_DIR>/System/Autorun/MyPlugin.dll. When we launch the game, a MessageBox should appear right before the main menu: Union SDK MessageBox

Couldn't build the plugin?

If you could not build the plugin or it crashed the game, you have to do some debugging and find the root cause of that. For compilation errors look at the Visual Studio Output tab and read the errors.

If they say something about missing toolset, make sure that you selected a Platform Toolset that's installed.

If the proper toolset is selected but doesn't work, make sure that you are configuring the same Configuration that is used for building.

If the plugin was built but the game crashed, you probably selected Configuration for the wrong platform. Gothic 2 Night of the Raven is G2A and doesn't work with G2 or G1A. If you are playing Gothic II Classic from Steam, please be advised that it still uses the Night of The Raven engine so the plugin must target G2A.

Debugging

Union plugins are regular DLLs with executable code hooked to Gothic.exe and running on it, so they can be debugged using the same techniques as any other software.

Visual Studio Debugger

Visual Studio Debugger lets us set breakpoints on any line of code to stop the execution when we reach it. It also gives us a lot of information about the program state at this point. To use the debugger we only need to attach it to the Gothic.exe progress and compile the plugin with Debug configuration.

Option #1: Open Project -> Properties and in the Debugging tab, set Command to the path of our Gothic.exe. Then we can run "Local Windows Debugger" in Visual Studio and it starts Gothic with a debugger attached automatically.

Option #2: Open Debug -> Attach to process... and filter process list by "Gothic". Run the game separately and when the process appears in Visual Studio, select it and attach to it.

Caveats:

  • If we attach to the process early, we may get an "Exception thrown at 0x7B11DB86 (Shw32.dll) in Gothic2.exe: 0xC0000005: Access violation writing location 0x00ABD000." right at the beginning. It's fine, just click Continue and Gothic will start properly.
  • If a breakpoint hits when our cursor is locked by Gothic, we may not be able to get the cursor back until execution continues. In this case, we can still use Alt+Tab to switch to Visual Studio and use F5 to continue or F10 to step over. Disabling mouse support in the config may also fix this problem.

Printing to some output is probably the simplest form of debugging and Union provides us with several choices.

Logging to zSPY

zSPY can be accessed using a global zerr object. zSPY uses a message filtering system based on the first letter of the message, so our logs should follow the standard format used by other parts of ZenGine. Otherwise, the message may not be visible.

zerr->Message("X:   MyPlugin: message to zSPY");
-

Logging to Union console

Union console needs to be enabled inside SystemPack.ini first:

1
-2
[CORE]
-ShowDebugWindow = true
-
Then we can use a global cmd object behaving like C++ std::cout to log into the Union console:
cmd << "message to Union console";
-

Logging to Visual Studio

Visual Studio can also receive logs from our plugin using:

OutputDebugString("message to Visual Studio");
-
This method works only when we have a debugger attached, so it's not recommended for general logging.
\ No newline at end of file diff --git a/cs/zengin/union/sdk/hooks/index.html b/cs/zengin/union/sdk/hooks/index.html deleted file mode 100644 index 515ba4733f..0000000000 --- a/cs/zengin/union/sdk/hooks/index.html +++ /dev/null @@ -1,202 +0,0 @@ - Hooks - Gothic Modding Community

Hooks

Union provides a hooks system that lets us intercept calls to the engine functions and methods with our custom interceptor. To hook a function or method we need to know its address which can be acquired either from Engine SDK/[Engine]/Names_[Engine].hpp or from the engine classes headers Engine SDK/[Engine]/Headers.

Intercepting functions

To declare a hook we can use CInvoke class or HOOK AS macros.

1
-2
-3
CInvoke<function_type> Ivk_HookName(orignal_function_address, our_interceptor_function, hook_flags);
-
-HOOK Ivk_HookName AS(orignal_function_address, our_interceptor_function, hook_flags);
-

Regular functions

Regular functions are the functions declared outside of classes.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
// 0x0042C450 int __cdecl Apply_Options_Video(void)
-
-// Forward declaration
-int Apply_Options_Video(); 
-
-// Hook declaration
-CInvoke<int(*)()> Ivk_Apply_Options_Video(0x0042C450, &Apply_Options_Video);
-// Equivalent:
-// HOOK Ivk_Apply_Options_Video AS(0x0042C450, &Apply_Options_Video);
-
-// Implementation of interceptor
-int Apply_Options_Video() {
-    Message::Info("Before original Apply_Options_Video()");
-
-    // Original function can be called using CInvoke pointer.
-    int result = Ivk_Apply_Options_Video();
-
-    Message::Info("After original Apply_Options_Video()");
-
-    return result;
-}
-

Member function

Member functions are the functions declared as non-static class members and they take a class instance pointer as an implicit first argument (__thiscall calling convention). We can hook them in two ways using either a regular function or declaring a new method in User API.

Option #1 - Regular function

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
// 0x006015D0 public: virtual int __fastcall zCVob::Render(struct zTRenderContext &)
-
-// Forward declaration
-int __fastcall zCVob_Render(zCVob* _this, zTRenderContext& context);
-
-// Hook declaration
-CInvoke<int(__fastcall *)(zCVob* _this, zTRenderContext& context)> Ivk_zCVob_Render(0x006015D0, &zCVob_Render);
-// Equivalent:
-// HOOK Ivk_zCVob_Render AS(0x006015D0, &zCVob_Render);
-
-// Implementation of interceptor as regular function
-// Notice the first argument that's a pointer to class instance (this)
-int __fastcall zCVob_Render(zCVob* _this, zTRenderContext& context) {
-    if(_this == player) {
-        screen->PrintCX(1000, "Rendering a player zCVob");
-    }
-
-    // Call original method
-    return Ivk_zCVob_Render(_this, context);
-}
-

Option #2 - User API

In Engine SDK/User API we can find a .inc file for the class we are hooking and define a new member method there. In this case, we are looking for zCVob.inc:

1
-2
-3
-4
-5
-6
// Supported with union (c) 2020 Union team
-
-// User API for zCVob
-// Add your methods here
-
-int RenderUnion(zTRenderContext& context);
-

Then we can declare the hook pointing to our member method:

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
// 0x006015D0 public: virtual int __fastcall zCVob::Render(struct zTRenderContext &)
-
-// Hook declaration
-CInvoke<int(__fastcall zCVob::*)(zTRenderContext& context)> Ivk_zCVob_Render(0x006015D0, &zCVob::RenderUnion);
-// Equivalent:
-// HOOK Ivk_zCVob_Render AS(0x006015D0, &zCVob::RenderUnion);
-
-// Implementation of interceptor  method
-int zCVob::RenderUnion(zTRenderContext& context) {
-    if(this == player) {
-        screen->PrintCX(1000, "Rendering a player zCVob");
-    }
-
-    // Call original method
-    return Ivk_zCVob_Render(this, context);
-}
-

Hook flags

In the third argument of CInvoke we can provide hook flags. The default value is IVK_AUTO.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
enum EInterMode
-{
-    // Hook will not intercept the function.
-    IVK_DISABLED  = 1 << 1,
-
-    // Normal hook. If other hook is already defined for the same address, an error pops up.
-    IVK_NORMAL    = 1 << 2,
-
-    // Hook will automatically create an interception tree to allow multiple hooks for the same address.
-    IVK_AUTO      = 1 << 3,
-
-    // Overrides any hook defined for the same address before.
-    IVK_REDEFINE  = 1 << 4,
-
-    // Makes it impossible to override or disable the hook.
-    // It should be used only in very specific cases.
-    IVK_PROTECTED = 1 << 5,
-
-    // Same as IVK_DISABLED
-    IVK_READONLY  = IVK_DISABLED
-};
-

Credits

Examples are taken from the Union lessons in Russian created by Gratt on worldofplayers.ru/threads/41490/

\ No newline at end of file diff --git a/cs/zengin/union/sdk/index.html b/cs/zengin/union/sdk/index.html deleted file mode 100644 index 3e2cdc8cbb..0000000000 --- a/cs/zengin/union/sdk/index.html +++ /dev/null @@ -1,34 +0,0 @@ - Union SDK - Gothic Modding Community

Union SDK

Union SDK is a software development kit for making Union plugins that directly interact with Gothic engines. It contains a project template for Visual Studio IDE, a C++ library for hooking into a Gothic executable, and Gothic API with methods' addresses for the engines of Gothic I, Gothic II, Gothic II NotR, and also for the not released Gothic Sequel.

Working with Union SDK requires at least basic knowledge of C++ programming. Knowledge of the x86 (32-bit) architecture, dynamically linked libraries, and reverse engineering is also welcomed as we need to understand what the Gothic engine does under the hood to use it effectively.

Requirements

Union SDK requires Visual Studio IDE, NET Framework 4.7.2, and Visual C++ 2010 libraries. They are available on Microsoft websites:

Resource Manager

The official installation of Union SDK is provided through Resource Manager. After the installation, Visual Studio will have a new project template "Union Plugin 1.0" that creates a basic Union plugin project.

\ No newline at end of file diff --git a/cs/zengin/union/zgamepad/controls/index.html b/cs/zengin/union/zgamepad/controls/index.html deleted file mode 100644 index 670983c4e4..0000000000 --- a/cs/zengin/union/zgamepad/controls/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/cs/zengin/union/zgamepad/index.html b/cs/zengin/union/zgamepad/index.html deleted file mode 100644 index 54b84281d0..0000000000 --- a/cs/zengin/union/zgamepad/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/cs/zengin/union/zgamepad/keys_engine_absolute/index.html b/cs/zengin/union/zgamepad/keys_engine_absolute/index.html deleted file mode 100644 index 5c4ab76f03..0000000000 --- a/cs/zengin/union/zgamepad/keys_engine_absolute/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/cs/zengin/union/zgamepad/keys_engine_logical/index.html b/cs/zengin/union/zgamepad/keys_engine_logical/index.html deleted file mode 100644 index b45c94bcb0..0000000000 --- a/cs/zengin/union/zgamepad/keys_engine_logical/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/cs/zengin/union/zgamepad/keys_gamepad/index.html b/cs/zengin/union/zgamepad/keys_gamepad/index.html deleted file mode 100644 index 0fefcd91d8..0000000000 --- a/cs/zengin/union/zgamepad/keys_gamepad/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/cs/zengin/union/zgamepad/logical_functions/index.html b/cs/zengin/union/zgamepad/logical_functions/index.html deleted file mode 100644 index 613f2db2a3..0000000000 --- a/cs/zengin/union/zgamepad/logical_functions/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/cs/zengin/video/index.html b/cs/zengin/video/index.html deleted file mode 100644 index 6112764399..0000000000 --- a/cs/zengin/video/index.html +++ /dev/null @@ -1,34 +0,0 @@ - Video - Gothic Modding Community

Video

To get a video cutscene, intro or outro into the game, the video needs to be in a proper format - BINK video format .bik.

Editing the video

The video you recorded and want to use has to be edited. My go-to editor for this is kdenlive. It works very well, it is free and open source, and it supports BINK video as an input, which is great if you want to include subtitles in the video.

My version of kdenlive does not know how to export video straight to .bik so I just export my video to .mp4 and then convert it with RAD Video Tools.

RAD Video Tools

RAD Video Tools is a tool for converting other video formats to BINK .bik that Gothic can use.

Warning

Gothic 1 bink implementation has some problems as you have to set the audio compression to 104 and above in RAD tools to get video to work in Gothic 1.

NicoDE's comment:

Add 100 to the audio compression level when encoding videos, e.g. 104 for level 4 with old sound format (should be mentioned in the RAD Video Tools documentation) for G1 without updated Miles libraries.

Note

Newest Union (1.0m at the time of writing) has a new patch for BINK video playback. The issue with sound should be fixed.

\ No newline at end of file diff --git a/cs/zengin/worlds/Classes/zCVob/index.html b/cs/zengin/worlds/Classes/zCVob/index.html deleted file mode 100644 index d34e66f93d..0000000000 --- a/cs/zengin/worlds/Classes/zCVob/index.html +++ /dev/null @@ -1,34 +0,0 @@ - zCVob - Gothic Modding Community

zCVob

zCVob is a base class for all objects placed in a world.

Acknowledgment

Heavily inspired by the amazing documentation site Gothic library

Class members

zCVob properties in spacer

Properties of a zCVob class are split into two parts. The Internals are hardly ever needed to be edited manually, they are changeed by e.g. moving an object in Spacer. On the other hand the Vob properties can only be changed by the Objects context menu in Spacer.

Internals

Vob

zCVob properties in spacer2

Properties of a zCVob class are split into two parts. The Internals are hardly ever needed to be edited manually, they are changeed by e.g. moving an object in Spacer. On the other hand the Vob properties can only be changed by the Objects context menu in Spacer.

Internals

Vob

Class member overview

pack

No Information provided.

presetName

The name of the template that was used to create the item.

bbox3DWS

Volume of virtual object. Defined by two opposite diagonal points of the BoundingBox (1x, 1y, 1z, 2x, 2y, 2z). The volume is needed to calculate collisions and interactions with other game objects. For example, with dynamic objects, which include characters (class C_NPC), items (class C_ITEM ), etc.

Interaction processing begins when object volumes intersect. For example, when the player enters the world change trigger area, the engine loads another game level based on the parameters this trigger. All this happens when the main character's BoundingBox intersects with the trigger's BoundingBox.

The BoundingBox can only be changed using the Edit the Bbox button in Spcaer.

trafoOSToWSRot

Orientation relative to the coordinate center.

Note

This refers to the center of coordinates of the .3DS file of the game world on which the ZEN file is built.

trafoOSToWSPos

Coordinates of the position in space relative to the center of coordinates.

The coordinates are set automatically the first time an instance of the class is inserted into the game world. You can change them either directly by entering numerical values ​​in the corresponding fields of the parameter, by moving the vob in spacer.

vobName

An identifier of a zCVob shown in the editor and sometimes used in scripts. The name can be left blank.

For some object classes, entering a name is required: zCVobSpot , zCVobWaypoint , zCTrigger , etc.

Danger

Setting a name for every static and insignificant object can lead to an error when parsing the game world.

visual

The name of the file that will be responsible for the visual display of the object.

Different file formats are used for different object classes:

  • *.3DS - Static objects
  • *.PFX - Particle effects
  • *.TGA - Textures
  • *.MDS, *.ASC - Interactive objects
  • *.MMS - Animated objects

showVisual

This option is responsible for displaying the object.

Accepted values:

  • TRUE - Display.
  • FALSE - Do not display.

visualCamAlign

Option to align objects relative to the camera.

Accepted values:

  • NONE - Not used.
  • YAW - The object always faces the player.
  • FULL - The object is aligned relative to the world axes.

Note

For example, in order for the grass model to always face the character, you need to set this parameter to YAW.

visualAniMode

Wind simulation option. Used in conjunction with the visualAniModeStrength parameter.

Accepted values:

  • NONE - Not used.
  • WIND - Strong wind effect. Acceptable for herbs.
  • WIND2 - Light wind effect. Acceptable for trees.

Warning

This option is only available in Gothic 2 (Spacer2).

visualAniModeStrength

Wind power animation multiplier. Small values such as 0.001 are typically used. Used in conjunction with the visualAniMode parameter.

Warning

This option is only available in Gothic 2 (Spacer2).

vobFarClipZScale

Sets the loading range of the VOB object. Depends on the VOB drawing distance specified using the zCZoneVobFarPlane object.

The range of values is from 0.0 to 2.0.

With a value of 0.0, the object is not visible, but collisions are calculated. With a value of 2.0, the VOB drawing range is identical to the VOB drawing range of objects specified by the zCZoneVobFarPlane object.

Warning

This option is only available in Gothic 2 (Spacer2).

CdStatic

Determines if the VOB will collide with the static objects (world mesh and other VOBs with cdStatic on).

Accepted values:

  • TRUE - Collision handling for static objects is enabled.
  • FALSE - Collision handling for static objects is disabled.

Tip

A situation often arises when objects “refuse” to move beyond a certain point on the surface. This happens when cdStatic is set to TRUE, i.e. the object cannot cross the surface another static object. In this case, it is enough to disable the cdStatic parameter for the duration of the move, and turn it on again after the move.

CdDyn

Determines if the VOB will collide with dynamic objects (NPCs, items, etc.). This basically determines if the object has collision during gameplay.

Accepted values:

  • TRUE - Collision handling for dynamic objects is enabled.
  • FALSE - Collision handling for dynamic objects is disabled.

staticVob

Determines if the VOB is taken into consideration in static lighting calculations in Indoor spaces. Usually enabled in decorative Vobs, but some of the interactive ones have it disabled.

Accepted values:

  • TRUE - Calculate the shadow of the object.
  • FALSE - Do not calculate the shadow of the object.

Note

The shadow is calculated when compiling light in Low, Middle or High mode.

dynShadow

Determine if the object will cast a shadow when affected by dynamic light (e.g. torches).

Accepted values:

  • DS_NONE - No shadow.
  • DS_BLOB - Casts a circular shadow.

zbias

Option to remove texture flickering if a .TGA file is used as rendering.

Warning

This option is only available in Gothic 2 (Spacer2).

isAmbient

Sets the calculation of refracted lighting of objects.

Accepted values:

  • TRUE - Calculate the refraction of light.
  • FALSE - Do not calculate light refraction.

Warning

This option is only available in Gothic 2 (Spacer2).

\ No newline at end of file diff --git a/cs/zengin/worlds/index.html b/cs/zengin/worlds/index.html deleted file mode 100644 index 3ad54ea9c2..0000000000 --- a/cs/zengin/worlds/index.html +++ /dev/null @@ -1,34 +0,0 @@ - Worlds - Gothic Modding Community

Worlds

Acknowledgment

This article is heavily inspired by various tutorials from the polish TheModders forums.

Worlds, saved as .ZEN files in ZenGin, are archives that contain the world mesh (model), BSP tree and the information of all objects in the world. These objects are called VOBs ("virtual objects"). ZEN files can be saved in two ways; compiled and uncompiled. The compiled version is a full-fledged level with a terrain model. Uncompiled ZENs only save the VOB tree and are meant for specific use-cases.

Spacer is used to create these .ZEN files. There are also other world editors. The way of doing things can vary between these editors, so the specifics will be discussed in separate articles for those tools; at the same time, a lot of knowledge carries over between them. Also have in mind that Spacer is the least comfortable of the editors.

World contents

The content of worlds in Gothic can be roughly separated in the following way:

  • Base level mesh: terrain and buildings, sometimes also trees
  • VOBs: all interactive objects, items, foliage, small rocks, huts, furniture, ramps etc.

Asides from those elements, there are also many invisible VOBs, such as:

  • Waypoints - used for NPC navigation
  • Freepoints (zCVobSpot) - used mainly for NPC routines and roaming behavior for monsters
  • Startpoints - used only to spawn the player when starting a new game. Teleporting between levels is handled with scripts and uses freepoints to determine where the player will appear.
  • Sound emitters
  • Music zones
  • oCZoneMusic - music which plays inside the bounding box of this zone
  • oCZoneMusicDefault - default music which plays whenever the player is not inside some oCZoneMusic
  • Fog zones (zCZoneZFog) - areas which add fog, e.g. like in swamp areas where the sky is not visible. The setting to fade out the sky is optional though.
  • PFX - particle effects (fire, smoke, fireflies, falling leaves etc.)

Note

This list isn't exhaustive.

Creating a ZEN file

Before VOBs can be added to a world model, the world needs to be compiled. After importing a 3ds model, the world can be compiled as an outdoor or indoor world and saved as a ZEN.

The submeshes used in ZEN files have triangle count limits (it is also advisable to keep triangle count for each submesh under 50k for performance reasons). To get around this limitation and to parallelize work on various areas, it is possible to join multiple ZEN files together, which is done with special macros.

If you take a look at the original maps for Gothic 2, you can notice that they are in folders, where there's e.g. a file called NEWWORLD.ZEN and multiple .ZEN files with "part" in their name. The latter are the sub-zens used to create the full level.

However, a possibly more comfortable workflow is to have a single world mesh which is internally separated into multiple submeshes. This way triangle count limits won't be exceeded and the world won't need compiling from parts. As a trade-off, it is likely that it won't be possible for multiple people to work on the ZEN world at the same time.

Lighting

There are two light types in the game:

  • Static lights, which are baked onto the level. They can cast shadows (these only take static VOBs into consideration) and don't leak through walls. These have to be recompiled after making changes, but this process should only take moments. Static lights have the downside of only working in indoor worlds and in rooms which are closed with portals.
  • Dynamic lights are calculated during runtime, which allows them to move and change properties (their color, for example), but has a performance cost. Additionally, they don't look the best and will often leak through walls.

It is generally advised to use static lights whenever possible.

Portals

Portals are special parts of outdoor world meshes which separate interiors from exteriors. This allows the level to have dark areas: otherwise interiors are lit the same way as any outside area. Additionally, portals help with performance (interiors aren't rendered unless the player is nearby). Creation of portals has many caveats and will be discussed in a separate article. Portals are also related to NPC behavior (e.g. setting ownership of a room).

Optimisation

The game uses occlusion culling, which means that if an object is covered by another object, it is not rendered and saves performance. This means that the performance in a level can be boosted by a lot by creating city walls and mountains and valleys which separate areas.

Occlusion culling isn't a perfect process, so there's also the option of adding GHOSTOCCLUDERs, which are invisible walls which stop areas behind them from rendering. They are a part of the world mesh and are created by assigning a material called GHOSTOCCLUDER to chosen faces. The color of the material is traditionally purplish-blue or pink, but the material itself is not rendered in-game, so this is only to make them stand apart from the rest of the level during modelling. To get more technical, these occluder walls are used to help the BSP algorithm which runs during world compilation.

As mentioned before, another ways of optimisation are portals and limiting the number of dynamic lights. It is also not advisable to make many VOBs be affected by wind.

\ No newline at end of file diff --git a/cs/zengin/worlds/spacer/index.html b/cs/zengin/worlds/spacer/index.html deleted file mode 100644 index 554433552a..0000000000 --- a/cs/zengin/worlds/spacer/index.html +++ /dev/null @@ -1,45 +0,0 @@ - Spacer - Gothic Modding Community

Spacer

Spacer is the original world editor used to create maps in Gothic and it's installed by the MDK installer.

A good .ZEN file to start experimenting with Spacer is Toten Insel. It's a simple level which should load without issues for everyone. The map contains a custom texture, but it can be safely ignored.

Introduction

Upon launching Spacer, multiple windows will appear. They are:

  • The main viewport (black with text on launch)
  • The vobtree - allows to browse and select the objects already placed in a level
  • The object window - it has 3 tabs: Create, Modify and "...".
  • Toolbars - there's two of them and each button has a hover hint.
  • The help window - sometimes when clicking on something, this window will show a description. It's usually empty though.
  • The objectpages window - allows access to specific VOB settings. The contents of this window be changed with buttons on the horizontal toolbar.

Other windows dedicated to specific functionalities can also be opened or toggled (Window tab in the viewport or the horizontal toolbar).

When importing a mesh instead of a .ZEN file, some things will change. In this mode, objectpages has material data, one of the toolbars changes completely and the vobtree window changes into a texture browser.

Configuration

Before doing anything else, you will probably want to change a few settings first. Select Settings: View in the Settings tab in the main viewport to increase the viewport resolution. After doing that, press Align Toolwindows at Screen or Align Toolwindows at Spacer in the Window tab to clean up the window placement. You might still need to move some of the tool windows around after this, as they can overlap.

The most comfortable option we found was to set the resolution to something slightly smaller than the screen resolution (e.g. 1600:900 on a 1920:1080 screen) and then aligning the tool windows to screen.

To help with the control sensitivity issues, change the camera movement speed in the Settings: General.

Viewport controls

The camera has multiple modes of operation. Some of the controls may sound confusing, but will make sense once you try them.

Default selection mode

Arrows move the camera back and forward and rotate it sideways. A moves the camera up and Y lowers it.

PageUp and PageDown rotate the camera up and down. End resets this rotation.

Selecting VOBs is done by simply pointing at them with the mouse and clicking.

First-person selection mode

Toggled by the F3 button.

In this mode, you can point the camera with your mouse, and selection is done by pointing the green reticle at a VOB and clicking LMB. Arrows now move the camera parallel to itself (including sideways).

PageUp and PageDown still rotate the camera up and down, but it's better not to use them because it affects how the arrow movement behaves. End resets this rotation.

Default VOB movement mode

When a VOB is selected, press M to enter and exit this mode.

The arrows now move the VOB horizontally. Moving it up and down is done with A and Y.

The keys above the arrows now rotate the VOB:

  • Axis 1: Delete and PageDown
  • Axis 2: Insert and PageUp
  • Axis 3: Home and End

First-person VOB movement mode

When a VOB is selected, press T to enter and exit this mode.

The controls are the same as the default selection mode, but the camera is now placed at the selected VOB and it moves with the camera.

One caveat is that the controls are in the local space of the object. What this basically means is that if you rotated the object in any other way than horizontally, the movement and rotation will now be skewed.

Mixed VOB movement mode

When a VOB is selected, press C to enter and exit this mode. The VOB is now controlled like in the first-person movement mode, but the camera is not placed at the VOB: in other words, the camera remains in the same place.

General

Holding down Shift speeds up the camera in all of the modes. The numpad can be used for rotating instead of the buttons above the arrows. Both movement modes can be used from either of the selection modes. Movement modes can be selected from the vertical toolbar. This toolbar also has a "toggle camera position" button; this switches between two camera placements, which can be controlled independently.

The objects location can also be entered manually through the object window: open the Internals folder and select trafoOSToWSPos to input them at the bottom of the window. Don't forget to press "Apply". Unfortunately the rotation setting uses an odd format and can't be set manually.

Basic usage

This section covers some of the basic things done in the editor.

Inserting a VOB

  • In the Create tab in the Objects window, select the VOB type. Choose zcVob to add a simple decorative model.
  • Right click anywhere on the viewport
  • Select the insert option (Insert [zcVob] in this case)
  • A VOB without a mesh will be created in the middle of the screen. Try to not deselect it, but if you do, it can be found in the vobtree under the appropriate folder (zcVob in this case); it can be identified by a green dot.
  • In the Modify tab in the Object window, select "visual". Insert the model name in the text form at the bottom of the window. You can use pc_lob_sleeper3.3ds for now; this mesh should be present in both Gothic 1 and 2.
  • If you unpacked the meshes while installing the MDK or with GothicVDFS, you can also browse to the file using the file button next to the text form.
  • Make sure to click the Apply button. Do this after making any changes in the Object window or they will be lost.

Tip

You can use the VOB Bilder tool to comfortably browse model images and names. An online version is currently available here. The UI on the website is in Polish but it's simple enough to not matter.

  • To make the VOB have collision in-game, double click on cdDyn ("collision detection dynamic") to set it to true. Sometimes this is unadvised, e.g. with bushes or grass.

Tip

When placing pickable items, you can press the "apply physics on selected VOB" button in the vertical toolbar to make the item drop on the ground. It can save you a lot of work with placing those items. This won't work with a plain cVob though.

Common VOB settings

VOB settings vary depending on what the VOB type is. They all have common parameters of the base VOB class though. The full description of a zCVob class can be found here.

Issues

Spacer 2 received the last update in 2003 and is a very buggy tool. Here are some known issues.

Framerate dependence

The speed of camera in Spacer depends on the framerate. Depending on the angle of the camera and the level, Spacer can have huge framerate, which will make the camera move too quick.

You can try to limit the framerate of Spacer with external tools, but your mileage may vary. Such tools often only limit rendering using fake Vsync, but the underlying logic of the program can still run too fast.

Using the grid snap function can help when the framerate is high, but again: your mileage may vary.

Random freezes and crashes

Spacer will freeze or crash quite often at seemingly random moments. It is extremely important to save often and back up your work.

One of the common ways the editor can freeze is when rotating the camera vertically when the framerate is very high. In that case, changing the camera mode to F3 and back can sometimes help.

Copying VOBs

When copy-pasting a VOB in Spacer (right click menu), the new VOB might be created as a child of the original one and moving one of them will move both. This doesn't seem to be consistent, but it's worth checking before you accidentally ruin the careful placement of the original VOB.

Troubleshooting

You can have issues with loading a ZEN or a world model for a multitude of reasons. Here is some of the known ones.

  • Some terrain models aren't set up or exported properly.
  • Maps which use custom assets will cause issues or won't even load unless these assets are included in appropriate directories. The severity of this is different depending on the asset type. For example, textures will be replaced with a placeholder, but animations will cause crashes.

Note

This section is not exhaustive.

Creating ZENs

Presented here are the ways of working with new terrain models.

Compiling a world mesh

To create a completely new ZEN, you will first need a level mesh. These can be made from scratch or downloaded, but be aware that meshes, which aren't properly prepared won't compile correctly (you won't be able to move in the viewport). As with any other mesh in Gothic, it has to be in the 3ds format. It is recommended to place the mesh file somewhere in the _work/Data/Meshes (can be your own subfolder).

You can find free terrain models here if you want to practice this. Note that not all of them might compile properly; this one should be fine though.

First, load the mesh from the File tab of the viewport. To compile the mesh, press Compile World in the World tab. From here, multiple options are available:

  • Indoor/Outdoor: determines if the world will have a sky and the way that lighting behaves.
  • Detect leaks: might be related to checking if indoor ("underground") worlds have holes in them. In some games such holes can cause performance issues, perhaps it's the same here. Doesn't hurt to enable it.
  • Quick compile: self-explanatory, but the exact effects of this are unknown.
  • Polycheck: presumably checks if the model doesn't exceed triangle limits.
  • Editormode:

    • On: Spacer will load the mesh in editor mode, which allows you to change materials assigned to triangles and other mesh operations. It is more comfortable to do these things in an external 3D editor, but sometimes using this is recommended, e.g. for setting up portals. You can save the model as a .3ds in this mode.

    • Off: Spacer will create a ZEN where you can normally place VOBs. You can now save the world as a compiled ZEN and add VOBs to it.

Compiling a world from multiple meshes

First and foremost, the models used for this must be properly positioned and separated in your 3D editor of choice. Then each section must be exported as separate .3ds files. After that, compile each model and save it as a compiled ZEN. Place them in their own folder. You can place VOBs in those ZEN files, the VOB trees will be merged too.

Now, to join these zens together, you will need to define a macro in Tools>Macros. These are pretty much identical except for the ZEN list; for example, the Mining Colony ZEN in Gothic 2 (OLDWORLD.ZEN) is comprised of two models, and the macro looks like this:

1
-2
-3
-4
-5
-6
reset
-set error 3
-Load world oldworld\SURFACE.ZEN
-Load world oldworld\OLDCAMP.ZEN
-compile world outdoor
-compile light high
-

Then you double-click the macro name to run it and wait. The macro contains the reset directive, but it's worth doing it on a freshly opened Spacer instance just to be safe.

Keep in mind that compiling a world from multiple ZENs is meant as a final step in level production. This is because doing it will cause issues with culling and stop interiors from rendering (and thus stop you from editing it). Instead, the part ZENs are filled with VOBs separately and the world is compiled as a final step before testing the map.

Updating world meshes in a compiled ZEN

Ideally, updating the world mesh would be avoided, but it's an inevitable need when iterating a map design. Doing this in the original Spacer might not be impossible, but it is generally avoided and Spacer.NET or other editors are used for this instead.

\ No newline at end of file diff --git a/feed_rss_created.xml b/feed_rss_created.xml new file mode 100644 index 0000000000..5ac1f5fbf9 --- /dev/null +++ b/feed_rss_created.xml @@ -0,0 +1 @@ + Gothic Modding CommunityGothic Modding Community to zbiór pomocnych materiałów do modowania gier Gothic i Risen.https://auronen.cokoliv.eu/gmc/https://github.com/Gothic-Modding-Community/gmc/pl Sun, 30 Jun 2024 18:12:28 -0000 Sun, 30 Jun 2024 18:12:28 -0000 1440 MkDocs RSS plugin - v1.14.0 Introducing Community Posts kamilkrzyskow Community News Documentation MkDocs i18n <h1>Introducing Community Posts</h1><blockquote><p>Enabled by the built-in Blog plugin of Material for MkDocs.<br>[![Material for MkDocs][badge]{: .gmc-default-img}][mkdocs-material]</p></blockquote><p>Welcome to the new blog section of the GMC, where users can share tutorials, guides, analytical articles, useful snippets, promote their modding tools, and more.</p><p>This addition brings greater flexibility to content creation on our website.</p>https://auronen.cokoliv.eu/gmc/blog/community-news/introducing-community-posts/ Sun, 30 Jun 2024 18:10:38 +0000Gothic Modding Communityhttps://auronen.cokoliv.eu/gmc/blog/community-news/introducing-community-posts/#commentshttps://auronen.cokoliv.eu/gmc/blog/community-news/introducing-community-posts/ Introducing Community Posts kamilkrzyskow Community News Documentation MkDocs i18n <h1>Introducing Community Posts</h1><blockquote><p>Enabled by the built-in Blog plugin of Material for MkDocs.<br>[![Material for MkDocs][badge]{: .gmc-default-img}][mkdocs-material]</p></blockquote><p>Welcome to the new blog section of the GMC, where users can share tutorials, guides, analytical articles, useful snippets, promote their modding tools, and more.</p><p>This addition brings greater flexibility to content creation on our website.</p>https://auronen.cokoliv.eu/gmc/pl/blog/community-news/introducing-community-posts/ Sun, 30 Jun 2024 18:10:38 +0000Gothic Modding Communityhttps://auronen.cokoliv.eu/gmc/pl/blog/community-news/introducing-community-posts/#commentshttps://auronen.cokoliv.eu/gmc/pl/blog/community-news/introducing-community-posts/ Introducing Community Posts kamilkrzyskow Community News Documentation MkDocs i18n <h1>Introducing Community Posts</h1><blockquote><p>Enabled by the built-in Blog plugin of Material for MkDocs.<br>[![Material for MkDocs][badge]{: .gmc-default-img}][mkdocs-material]</p></blockquote><p>Welcome to the new blog section of the GMC, where users can share tutorials, guides, analytical articles, useful snippets, promote their modding tools, and more.</p><p>This addition brings greater flexibility to content creation on our website.</p>https://auronen.cokoliv.eu/gmc/cs/blog/community-news/introducing-community-posts/ Sun, 30 Jun 2024 18:10:38 +0000Gothic Modding Communityhttps://auronen.cokoliv.eu/gmc/cs/blog/community-news/introducing-community-posts/#commentshttps://auronen.cokoliv.eu/gmc/cs/blog/community-news/introducing-community-posts/ Guidelines For Community Posts kamilkrzyskow Best Practices Documentation How-To MkDocs Tutorials <h1>Guidelines For Community Posts</h1><p><strong>Question:</strong> What are the requirements for my blog post to be added here?<br><strong>Answer:</strong> There are almost no requirements, other than managing files properly.</p><p>Also read the general <a href="../../../contribute/index.md">contribution guide</a> for setup instructions. </p>https://auronen.cokoliv.eu/gmc/blog/tutorials/guidelines-for-community-posts/ Sun, 30 Jun 2024 14:59:47 +0000Gothic Modding Communityhttps://auronen.cokoliv.eu/gmc/blog/tutorials/guidelines-for-community-posts/#commentshttps://auronen.cokoliv.eu/gmc/blog/tutorials/guidelines-for-community-posts/ Guidelines For Community Posts kamilkrzyskow Best Practices Documentation How-To MkDocs Tutorials <h1>Guidelines For Community Posts</h1><p><strong>Question:</strong> What are the requirements for my blog post to be added here?<br><strong>Answer:</strong> There are almost no requirements, other than managing files properly.</p><p>Also read the general <a href="../../../contribute/index.md">contribution guide</a> for setup instructions. </p>https://auronen.cokoliv.eu/gmc/pl/blog/tutorials/guidelines-for-community-posts/ Sun, 30 Jun 2024 14:59:47 +0000Gothic Modding Communityhttps://auronen.cokoliv.eu/gmc/pl/blog/tutorials/guidelines-for-community-posts/#commentshttps://auronen.cokoliv.eu/gmc/pl/blog/tutorials/guidelines-for-community-posts/ Guidelines For Community Posts kamilkrzyskow Best Practices Documentation How-To MkDocs Tutorials <h1>Guidelines For Community Posts</h1><p><strong>Question:</strong> What are the requirements for my blog post to be added here?<br><strong>Answer:</strong> There are almost no requirements, other than managing files properly.</p><p>Also read the general <a href="../../../contribute/index.md">contribution guide</a> for setup instructions. </p>https://auronen.cokoliv.eu/gmc/cs/blog/tutorials/guidelines-for-community-posts/ Sun, 30 Jun 2024 14:59:47 +0000Gothic Modding Communityhttps://auronen.cokoliv.eu/gmc/cs/blog/tutorials/guidelines-for-community-posts/#commentshttps://auronen.cokoliv.eu/gmc/cs/blog/tutorials/guidelines-for-community-posts/ \ No newline at end of file diff --git a/feed_rss_updated.xml b/feed_rss_updated.xml new file mode 100644 index 0000000000..89207f2e54 --- /dev/null +++ b/feed_rss_updated.xml @@ -0,0 +1 @@ + Gothic Modding CommunityGothic Modding Community to zbiór pomocnych materiałów do modowania gier Gothic i Risen.https://auronen.cokoliv.eu/gmc/https://github.com/Gothic-Modding-Community/gmc/pl Sun, 30 Jun 2024 18:12:28 -0000 Sun, 30 Jun 2024 18:12:28 -0000 1440 MkDocs RSS plugin - v1.14.0 Introducing Community Posts kamilkrzyskow Community News Documentation MkDocs i18n <h1>Introducing Community Posts</h1><blockquote><p>Enabled by the built-in Blog plugin of Material for MkDocs.<br>[![Material for MkDocs][badge]{: .gmc-default-img}][mkdocs-material]</p></blockquote><p>Welcome to the new blog section of the GMC, where users can share tutorials, guides, analytical articles, useful snippets, promote their modding tools, and more.</p><p>This addition brings greater flexibility to content creation on our website.</p>https://auronen.cokoliv.eu/gmc/blog/community-news/introducing-community-posts/ Sun, 30 Jun 2024 18:10:38 +0000Gothic Modding Communityhttps://auronen.cokoliv.eu/gmc/blog/community-news/introducing-community-posts/#commentshttps://auronen.cokoliv.eu/gmc/blog/community-news/introducing-community-posts/ Guidelines For Community Posts kamilkrzyskow Best Practices Documentation How-To MkDocs Tutorials <h1>Guidelines For Community Posts</h1><p><strong>Question:</strong> What are the requirements for my blog post to be added here?<br><strong>Answer:</strong> There are almost no requirements, other than managing files properly.</p><p>Also read the general <a href="../../../contribute/index.md">contribution guide</a> for setup instructions. </p>https://auronen.cokoliv.eu/gmc/blog/tutorials/guidelines-for-community-posts/ Sun, 30 Jun 2024 18:10:38 +0000Gothic Modding Communityhttps://auronen.cokoliv.eu/gmc/blog/tutorials/guidelines-for-community-posts/#commentshttps://auronen.cokoliv.eu/gmc/blog/tutorials/guidelines-for-community-posts/ Introducing Community Posts kamilkrzyskow Community News Documentation MkDocs i18n <h1>Introducing Community Posts</h1><blockquote><p>Enabled by the built-in Blog plugin of Material for MkDocs.<br>[![Material for MkDocs][badge]{: .gmc-default-img}][mkdocs-material]</p></blockquote><p>Welcome to the new blog section of the GMC, where users can share tutorials, guides, analytical articles, useful snippets, promote their modding tools, and more.</p><p>This addition brings greater flexibility to content creation on our website.</p>https://auronen.cokoliv.eu/gmc/pl/blog/community-news/introducing-community-posts/ Sun, 30 Jun 2024 18:10:38 +0000Gothic Modding Communityhttps://auronen.cokoliv.eu/gmc/pl/blog/community-news/introducing-community-posts/#commentshttps://auronen.cokoliv.eu/gmc/pl/blog/community-news/introducing-community-posts/ Guidelines For Community Posts kamilkrzyskow Best Practices Documentation How-To MkDocs Tutorials <h1>Guidelines For Community Posts</h1><p><strong>Question:</strong> What are the requirements for my blog post to be added here?<br><strong>Answer:</strong> There are almost no requirements, other than managing files properly.</p><p>Also read the general <a href="../../../contribute/index.md">contribution guide</a> for setup instructions. </p>https://auronen.cokoliv.eu/gmc/pl/blog/tutorials/guidelines-for-community-posts/ Sun, 30 Jun 2024 18:10:38 +0000Gothic Modding Communityhttps://auronen.cokoliv.eu/gmc/pl/blog/tutorials/guidelines-for-community-posts/#commentshttps://auronen.cokoliv.eu/gmc/pl/blog/tutorials/guidelines-for-community-posts/ Introducing Community Posts kamilkrzyskow Community News Documentation MkDocs i18n <h1>Introducing Community Posts</h1><blockquote><p>Enabled by the built-in Blog plugin of Material for MkDocs.<br>[![Material for MkDocs][badge]{: .gmc-default-img}][mkdocs-material]</p></blockquote><p>Welcome to the new blog section of the GMC, where users can share tutorials, guides, analytical articles, useful snippets, promote their modding tools, and more.</p><p>This addition brings greater flexibility to content creation on our website.</p>https://auronen.cokoliv.eu/gmc/cs/blog/community-news/introducing-community-posts/ Sun, 30 Jun 2024 18:10:38 +0000Gothic Modding Communityhttps://auronen.cokoliv.eu/gmc/cs/blog/community-news/introducing-community-posts/#commentshttps://auronen.cokoliv.eu/gmc/cs/blog/community-news/introducing-community-posts/ Guidelines For Community Posts kamilkrzyskow Best Practices Documentation How-To MkDocs Tutorials <h1>Guidelines For Community Posts</h1><p><strong>Question:</strong> What are the requirements for my blog post to be added here?<br><strong>Answer:</strong> There are almost no requirements, other than managing files properly.</p><p>Also read the general <a href="../../../contribute/index.md">contribution guide</a> for setup instructions. </p>https://auronen.cokoliv.eu/gmc/cs/blog/tutorials/guidelines-for-community-posts/ Sun, 30 Jun 2024 18:10:38 +0000Gothic Modding Communityhttps://auronen.cokoliv.eu/gmc/cs/blog/tutorials/guidelines-for-community-posts/#commentshttps://auronen.cokoliv.eu/gmc/cs/blog/tutorials/guidelines-for-community-posts/ \ No newline at end of file diff --git a/genome/general_info/object_persistence/index.html b/genome/general_info/object_persistence/index.html index 80aebc56ec..91f8e9ba65 100644 --- a/genome/general_info/object_persistence/index.html +++ b/genome/general_info/object_persistence/index.html @@ -1,4 +1,4 @@ - Object persistence - Gothic Modding Community

Object persistence

Please note the following warning about Risen 2, 3 and ELEX 1 and 2

The following information only applies to Gothic 3 (2006) and Risen (2009). While newer Genome engine games share the same overall concepts, they have significant implementation differences that warrant their own section.

The engine is, due to the nature of the games themselves, required to store and load a vast amount of different types of data from the user's hard-drive. In order to streamline this parsing and/or serialization process, Genome implements an object persistence system using its own built-in runtime type information (RTTI) system.

Any class derived from bCObjectBase may declare its own member properties in such a way that when the object is then written into a file using the bCAccessorPropertyObject class, its associated properties will be automatically serialized into the stream by using special preprocessor macros. When the object is read back from the file, the class will be automatically initialized using the stored members.

Additionally, classes may overload the Read and Write (OnRead and OnWrite in Risen 1) virtual methods that allow the class to save additional data required during parsing such as paths to other necessary files.

As this system is quite flexible, it is used to store most of the game's data, from meshes, animations and textures to level and quest data. This is quite different from ZenGin, as its object persistence system is only used for worlds, saves, output units and parts of compiled meshes.

File format

Files

1
+     

Object persistence

Please note the following warning about Risen 2, 3 and ELEX 1 and 2

The following information only applies to Gothic 3 (2006) and Risen (2009). While newer Genome engine games share the same overall concepts, they have significant implementation differences that warrant their own section.

The engine is, due to the nature of the games themselves, required to store and load a vast amount of different types of data from the user's hard-drive. In order to streamline this parsing and/or serialization process, Genome implements an object persistence system using its own built-in runtime type information (RTTI) system.

Any class derived from bCObjectBase may declare its own member properties in such a way that when the object is then written into a file using the bCAccessorPropertyObject class, its associated properties will be automatically serialized into the stream by using special preprocessor macros. When the object is read back from the file, the class will be automatically initialized using the stored members.

Additionally, classes may overload the Read and Write (OnRead and OnWrite in Risen 1) virtual methods that allow the class to save additional data required during parsing such as paths to other necessary files.

As this system is quite flexible, it is used to store most of the game's data, from meshes, animations and textures to level and quest data. This is quite different from ZenGin, as its object persistence system is only used for worlds, saves, output units and parts of compiled meshes.

File format

Files

1
 2
 3
 4
struct bCIOStream
@@ -256,4 +256,4 @@
 object.myInt = 1;
 object.someData = 1;
 

If we now serialized, or to use the engine's term "archived", this instance into an ASCII stream, the result would look like this:


-
\ No newline at end of file +
\ No newline at end of file diff --git a/genome/index.html b/genome/index.html index 4231ad075b..4a51c1c1b7 100644 --- a/genome/index.html +++ b/genome/index.html @@ -1,4 +1,4 @@ - Genome engine - Gothic Modding Community

Genome engine

Genome engine is new engine by Piranha Bytes created for the game Gothic 3 and later used for the Risen and ELEX series of games.

\ No newline at end of file +

Genome engine

Genome engine is new engine by Piranha Bytes created for the game Gothic 3 and later used for the Risen and ELEX series of games.

\ No newline at end of file diff --git a/genome/tools/index.html b/genome/tools/index.html index a2d62fce48..b6e3d613d4 100644 --- a/genome/tools/index.html +++ b/genome/tools/index.html @@ -1,4 +1,4 @@ - Tools - Gothic Modding Community

Tools

Piranha Bytes did not release a modkit for their Genome engine, but the modding community has released a wide range of tools to work with the game's files and the engine itself.

Info

This page is under construction, for now, only handful of links are present.

Gothic 3 SDK

Georgeto, inspired by NicoDE's Risen SDK, has created an SDK for Gothic 3. It can be used to manipulate the engine in the similar way Union is able to manipulate ZenGin.
GitHub repository

\ No newline at end of file +

Tools

Piranha Bytes did not release a modkit for their Genome engine, but the modding community has released a wide range of tools to work with the game's files and the engine itself.

Info

This page is under construction, for now, only handful of links are present.

Gothic 3 SDK

Georgeto, inspired by NicoDE's Risen SDK, has created an SDK for Gothic 3. It can be used to manipulate the engine in the similar way Union is able to manipulate ZenGin.
GitHub repository

\ No newline at end of file diff --git a/index.html b/index.html index e4b4aa44ed..55de37ec66 100644 --- a/index.html +++ b/index.html @@ -1,4 +1,4 @@ - Welcome to Gothic Modding Community page - Gothic Modding Community

Welcome to Gothic Modding Community page

This GitHub page is designed to contain community maintained set of articles, tutorials and documentation for everything Gothic.

First two Gothic games use engine called ZenGin, developed by Piranha Bytes and Mad Scientists. If you want to know more about the history of the development, there is a heap of information on the Gothic Archive.

The content here is not meant to be taken as the holy word of modding. We are just modders sharing our experiences, knowledge and our favorite work flows.

Feel free to open a pull request with your article or propose changes.

You can open a pull request in this repository

\ No newline at end of file +

Welcome to Gothic Modding Community page

This GitHub page is designed to contain community maintained set of articles, tutorials and documentation for everything Gothic.

Info

The content here is not meant to be taken as the holy word of modding. We are just modders sharing our experiences, knowledge and our favorite work flows.

  • Discord Server


    If you have any modding related questions, or just want to talk join our discord server.

    Discord

  • Contribution


    Feel free to open a pull request with your article or propose changes. Here is detailed contribution guide.

    How to Contibute

  • Gothic Archive


    First two Gothic games use engine called ZenGin, developed by Piranha Bytes and Mad Scientists. If you want to know more about the history of the development, there is a heap of information on the Gothic Archive.

    Gothic Archive

  • Repository


    Check out our GitHub repository for the site's source code and updates.

    GitHub

\ No newline at end of file diff --git a/notready/index.html b/notready/index.html index ecf60d9266..0a0d57a51c 100644 --- a/notready/index.html +++ b/notready/index.html @@ -1,4 +1,4 @@ - Notready - Gothic Modding Community

Notready

Warning

Sorry, this page is not ready yet! 😢

\ No newline at end of file +

Notready

Warning

Sorry, this page is not ready yet! 😢

\ No newline at end of file diff --git a/pl/blog/category/community-news/index.html b/pl/blog/category/community-news/index.html new file mode 100644 index 0000000000..5616cd5f56 --- /dev/null +++ b/pl/blog/category/community-news/index.html @@ -0,0 +1,34 @@ + Community News - Gothic Modding Community

Community News

Introducing Community Posts

Enabled by the built-in Blog plugin of Material for MkDocs.
Material for MkDocs

Welcome to the new blog section of the GMC, where users can share tutorials, guides, analytical articles, useful snippets, promote their modding tools, and more.

This addition brings greater flexibility to content creation on our website.

\ No newline at end of file diff --git a/pl/blog/category/tutorials/index.html b/pl/blog/category/tutorials/index.html new file mode 100644 index 0000000000..3562e1a47c --- /dev/null +++ b/pl/blog/category/tutorials/index.html @@ -0,0 +1,34 @@ + Tutorials - Gothic Modding Community

Tutorials

\ No newline at end of file diff --git a/pl/blog/community-news/introducing-community-posts/index.html b/pl/blog/community-news/introducing-community-posts/index.html new file mode 100644 index 0000000000..dd0f1e731b --- /dev/null +++ b/pl/blog/community-news/introducing-community-posts/index.html @@ -0,0 +1,68 @@ + Introducing Community Posts - Gothic Modding Community

Introducing Community Posts

Enabled by the built-in Blog plugin of Material for MkDocs.
Material for MkDocs

Welcome to the new blog section of the GMC, where users can share tutorials, guides, analytical articles, useful snippets, promote their modding tools, and more.

This addition brings greater flexibility to content creation on our website.

Why a blog?

Throughout the history of the Gothic Modding Community, we've encountered a recurring issue: some content doesn't fit neatly into the "docs" format. To address this, we needed a new section. Initially, we considered a simple new area, but then the Blog plugin was announced for the Community version of the Material theme. We decided to wait for its release.

While waiting, we added support for i18n localization to attract new users for translation and content creation. However, despite our efforts, we didn't gain many regular contributors. Additionally, delays caused by the GitHub/PayPal issues further postponed the Blog plugin's release.

The Blog plugin eventually arrived in the Community version. Unfortunately, we discovered that the mkdocs-static-i18n plugin couldn't handle the internally generated blog pages. We hoped for a fix upstream, but the issue persisted.

i18n support

Not supported

As of July 02, 2024, the i18n plugin doesn't support blog pages.

Given the complexity of this issue, it likely requires overriding the Blog plugin's internal code. This could prevent users with localization from updating, creating a problematic situation for @ultrabug, who would need to constantly make fixes. The issue is further complicated by different versions of the Blog plugin for the Community and Insiders editions.

This applies to us as well. Despite many fixes and patches added to our docs on top of other plugins, we don't plan to add i18n support for the blog ourselves to maintain general flexibility. Especially since our community is still primarily composed of English speakers.

Who can add posts, what topics are allowed?

We don't plan to restrict posts too much. As long as they are not meme content, they will likely be accepted. For up-to-date guidelines, you can read the [how-to guide].

Comments

Let us know what do you think about the new feature!

\ No newline at end of file diff --git a/pl/blog/index.html b/pl/blog/index.html new file mode 100644 index 0000000000..22945c6878 --- /dev/null +++ b/pl/blog/index.html @@ -0,0 +1,34 @@ + Community Posts - Gothic Modding Community

Introducing Community Posts

Enabled by the built-in Blog plugin of Material for MkDocs.
Material for MkDocs

Welcome to the new blog section of the GMC, where users can share tutorials, guides, analytical articles, useful snippets, promote their modding tools, and more.

This addition brings greater flexibility to content creation on our website.

\ No newline at end of file diff --git a/pl/blog/posts/community-news/welcome/index.html b/pl/blog/posts/community-news/welcome/index.html new file mode 100644 index 0000000000..98c5eb53cf --- /dev/null +++ b/pl/blog/posts/community-news/welcome/index.html @@ -0,0 +1,15 @@ + + + + + + Redirecting... + + + + + + +Redirecting... + + diff --git a/pl/blog/posts/welcome/index.html b/pl/blog/posts/welcome/index.html new file mode 100644 index 0000000000..b70b40fe9e --- /dev/null +++ b/pl/blog/posts/welcome/index.html @@ -0,0 +1,15 @@ + + + + + + Redirecting... + + + + + + +Redirecting... + + diff --git a/pl/blog/tags/index.html b/pl/blog/tags/index.html new file mode 100644 index 0000000000..0b585f9a28 --- /dev/null +++ b/pl/blog/tags/index.html @@ -0,0 +1,34 @@ + Tags - Gothic Modding Community
\ No newline at end of file diff --git a/pl/blog/tutorials/guidelines-for-community-posts/index.html b/pl/blog/tutorials/guidelines-for-community-posts/index.html new file mode 100644 index 0000000000..e7b26e0039 --- /dev/null +++ b/pl/blog/tutorials/guidelines-for-community-posts/index.html @@ -0,0 +1,78 @@ + Guidelines For Community Posts - Gothic Modding Community

Guidelines For Community Posts

Question: What are the requirements for my blog post to be added here?
Answer: There are almost no requirements, other than managing files properly.

Also read the general contribution guide for setup instructions.

Technical Requirements

Creation Date

Each post must have a creation date used for sorting and ordering. The date key can be a simple string with the creation date or, an object structure with sub-keys created and updated.

date: 2024-07-01
+

Reference

At Least One Category

This blog uses category-based URLs instead of default time-based post URLs. The categories key is a list of strings.

1
+2
categories:
+  - Tutorials
+

Reference

Mandatory Opinionated Requirements

Use Categories Defined in the mkdocs.yml Config

Some categories can be used for slugs, while others cannot. If you want to add a new one, please ask first. To see an up-to-date list, check the categories_allowed option in the mkdocs.yml file. For more granularity, use tags, which offer more flexibility. You can see the index of used tags here.

Keep the Files Organized

Place posts in the blog/posts directory under a subdirectory matching the category slug (lowercase with _ in place of spaces):

Filenames should use _ for spaces and should be lowercase.

1
+2
blog/posts/community_news/welcome.md
+blog/posts/tutorials/how_to_write_blog_posts.md
+

For assets specific to the blog section:

Note the lack of posts.

assets/blog/images/tutorials/image.png
+

Assets Like Images Need to Be Placed Under the overrides Path

Due to the rest of the site using multiple languages (i18n), assets are kept in the overrides directory to reduce duplication of files after the build. The overrides directory is placed on top of the built directory so all relative paths are the same as if the files were in the docs directory. Use a couple of ../ to get to the root of the built site and access the asset:

../../../assets/images/gmc_logo.png
+

So in the example before:

../../../assets/blog/images/tutorials/image.png
+

Optional Opinionated Recommendations

Keep Keys and Values in the Front-Matter in Alphabetical Order

This will make it easier to spot mistakes.

Maintain a Strict Line Width Limit

It will make it easier to read and spot mistakes in Markdown. mkdocs-material uses an 80-character limit, which is a bit narrow. Currently, the CSS settings for the width of the content are roughly ~140 characters, which is a bit wide. This Markdown file uses a 100-character limit. Keep things reasonable and use the same width throughout the file, and do not break lines prematurely.

To avoid issues with long lines, define links before the next heading using this syntax: [text]: url. Then you can organically use the [text] in your paragraph, and it will be converted to a URL, or use [text][defined url] to wrap the text using a defined URL.

Avoid Name Conflicts

If a name conflict occurs, don't resort to adding a lazy -2 at the end. Instead, ensure your name is distinct for better searchability. For example, instead of result.png, use a more specific name like blender_modifier_result.png or the slug of the blog post you're writing.

Add a H2 Comments Heading at the Bottom

This will add a TOC element for users to easily skip the post and read the comments. The RSS plugin also expects this heading to exist.

Comments

Let us know what you think about these guidelines!

\ No newline at end of file diff --git a/pl/contribute/index.html b/pl/contribute/index.html index 9e84420d71..aba888829b 100644 --- a/pl/contribute/index.html +++ b/pl/contribute/index.html @@ -1,4 +1,4 @@ - Jak się udzielić - Gothic Modding Community

Jak się udzielić

Gothic Modding Community jest projektem napędzanym przed społeczność. Zachęcamy osoby do wnoszenia swojego wkładu.

Ta strona jest budowana przy pomocy statycznego generatora stron MkDocs oraz skórki Material for MkDocs, wraz z wieloma innymi wtyczkami do MkDocs.

Zależnie od skali i typu kontrybucji, trzeba spełnić inne wymagania wstępne.

Zgłoszenia

Po angielsku można zgłosić problem lub inny komentarz o funkcjonowaniu strony poprzez otworzenie problemu (ang. issue) na serwisie GitHub albo dołącz do nas na platformie Discord.

Wkład bezpośredni

Wkład bezpośredni wykonuje się poprzez stworzenie kopii tego repozytorium (ang. fork) oraz stworzenie prośby o połączenie (ang. pull request PR) na serwisie GitHub wraz ze zmianami do zatwierdzenia.

Nie zmarnuj czasu

Proszę się upewnić, że treść, jaka zostanie dodana, nie występuje już na wersji dev strony. Można skorzystać z funkcjonalności wyszukiwania, żeby przefiltrować GMC różnymi słowami kluczowymi i treściami.

Jak edytować pliki źródłowe?

Pliki źródłowe artykułów są pisane wykorzystując format plików Markdown .md (Markdown cheatsheet). Poza tym ta strona wykorzystuje wtyczkę Python Markdown Extensions, która rozszerza składnię o dodatkowe zasady pozwalające na wstawienie wzmianek jak ta, którą właśnie czytasz.

Mniejsze zmiany

Mniejsze zmiany, jak poprawianie błędów ortograficzny, gramatycznych, czy usuwanie/dodawanie słów do akapitów w jednym pliku, mogą być zrobione szybko poprzez kliknięcie przycisku w prawym górnym rogu artykułu. Otworzy to interfejs edytowania pliku w serwisie GitHub, które po zapisaniu zmian, automatycznie utworzy kopię (ang. fork) oraz gałąź (ang. brach) z łatką, a następnie otworzy prośbę o połączenie (ang. pull request) względem gałęzi dev.

Poprawna gałąź dla prośby o połączenie

Upewnij się, że prośba o połączenie (ang. pull request) jest skierowana do gałęzi dev albo specjalnej gałęzi pre-merge, a nie do gałęzi main.

Większe zmiany

Bardziej złożone zmiany takie jak, edycja wielu plików naraz, dodawanie nowych artykułów, obrazków, czy innych plików, albo zmiana konfiguracji strony jest łatwiej zrobić poprzez użycie zewnętrznych narzędzi na lokalnym PC. Większość z tych operacji można zrobić poprzez interfejs serwisu GitHub, ale jest to raczej uciążliwe oraz trudniej zauważyć problemy wynikające z procesu zmian, ponieważ nie są one widoczne w przeglądarce w ich ostatecznej formie.

Trochę przygotowań jest potrzebnych przed rozpoczęciem prac nad plikami, ponieważ do działania MkDocs wymaga zainstalowanego w systemie Pythona. GitHub działa nad systemem kontroli wersji git, więc jego instalacja jest też wymagana. Podstawowa znajomość obsługi Terminala/Konsoli poleceń/Powershell jest pomocna.

Przygotowanie Systemu (wideo)

Po pierwsze, trzeba zainstalować Python. Można podążać według tego poradnika krok po kroku dla Windowsa albo macOS jak zainstalować Python.

Wideo jest z 2017?!

Proces instalacji Pythona nie zmienił się od tamtego czasu. Jednakże proszę instalować najnowszą wersję Python 3.

Aby móc pracować zdalnie z GitHub, można zainstalować najnowszą wersję git, podążając według tego poradnika.

Jeżeli planujesz tylko edytować zawartość artykułów Markdown, możesz po prostu zainstalować najnowszą wersję Visual Studio Code, żeby mieć interfejs graficzny do zarządzania git oraz podgląd Markdown, albo pracuj z dowolnym znanym edytorem tekstu i omiń konfigurację środowiska.

Jeżeli planujesz bardziej złożone programowanie w Python, możesz podążyć według tego poradnika krok po kroku dla Windowsa lub macOS jak skonfigurować środowisko developerskie z Visual Studio Code (VS Code).

Przygotowanie Systemu (tekst)

Żeby przygotować system do uruchomienia projektu lokalnie, podążaj według tych instrukcji.

  1. Zainstaluj najnowszą wersję Pythona.
    Upewnij się, żeby zaznaczyć opcję "Add Python to PATH" podczas instalacji.

  2. Otwórz okno Terminala/Konsoli poleceń/PowerShell.

  3. Sprawdź, że instalacja Pythona była pomyślna, korzystając z tego polecenia (możliwa jest potrzeba restartu okna konsoli):

    python --version
    +     

    Jak się udzielić

    Gothic Modding Community jest projektem napędzanym przed społeczność. Zachęcamy osoby do wnoszenia swojego wkładu.

    Ta strona jest budowana przy pomocy statycznego generatora stron MkDocs oraz skórki Material for MkDocs, wraz z wieloma innymi wtyczkami do MkDocs.

    Zależnie od skali i typu kontrybucji, trzeba spełnić inne wymagania wstępne.

    Zgłoszenia

    Po angielsku można zgłosić problem lub inny komentarz o funkcjonowaniu strony poprzez otworzenie problemu (ang. issue) na serwisie GitHub albo dołącz do nas na platformie Discord.

    Wkład bezpośredni

    Wkład bezpośredni wykonuje się poprzez stworzenie kopii tego repozytorium (ang. fork) oraz stworzenie prośby o połączenie (ang. pull request PR) na serwisie GitHub wraz ze zmianami do zatwierdzenia.

    Nie zmarnuj czasu

    Proszę się upewnić, że treść, jaka zostanie dodana, nie występuje już na wersji dev strony. Można skorzystać z funkcjonalności wyszukiwania, żeby przefiltrować GMC różnymi słowami kluczowymi i treściami.

    Jak edytować pliki źródłowe?

    Pliki źródłowe artykułów są pisane wykorzystując format plików Markdown .md (Markdown cheatsheet). Poza tym ta strona wykorzystuje wtyczkę Python Markdown Extensions, która rozszerza składnię o dodatkowe zasady pozwalające na wstawienie wzmianek jak ta, którą właśnie czytasz.

    Mniejsze zmiany

    Mniejsze zmiany, jak poprawianie błędów ortograficzny, gramatycznych, czy usuwanie/dodawanie słów do akapitów w jednym pliku, mogą być zrobione szybko poprzez kliknięcie przycisku w prawym górnym rogu artykułu. Otworzy to interfejs edytowania pliku w serwisie GitHub, które po zapisaniu zmian, automatycznie utworzy kopię (ang. fork) oraz gałąź (ang. brach) z łatką, a następnie otworzy prośbę o połączenie (ang. pull request) względem gałęzi dev.

    Poprawna gałąź dla prośby o połączenie

    Upewnij się, że prośba o połączenie (ang. pull request) jest skierowana do gałęzi dev albo specjalnej gałęzi pre-merge, a nie do gałęzi main.

    Większe zmiany

    Bardziej złożone zmiany takie jak, edycja wielu plików naraz, dodawanie nowych artykułów, obrazków, czy innych plików, albo zmiana konfiguracji strony jest łatwiej zrobić poprzez użycie zewnętrznych narzędzi na lokalnym PC. Większość z tych operacji można zrobić poprzez interfejs serwisu GitHub, ale jest to raczej uciążliwe oraz trudniej zauważyć problemy wynikające z procesu zmian, ponieważ nie są one widoczne w przeglądarce w ich ostatecznej formie.

    Trochę przygotowań jest potrzebnych przed rozpoczęciem prac nad plikami, ponieważ do działania MkDocs wymaga zainstalowanego w systemie Pythona. GitHub działa nad systemem kontroli wersji git, więc jego instalacja jest też wymagana. Podstawowa znajomość obsługi Terminala/Konsoli poleceń/Powershell jest pomocna.

    Przygotowanie Systemu (wideo)

    Po pierwsze, trzeba zainstalować Python. Można podążać według tego poradnika krok po kroku dla Windowsa albo macOS jak zainstalować Python.

    Wideo jest z 2017?!

    Proces instalacji Pythona nie zmienił się od tamtego czasu. Jednakże proszę instalować najnowszą wersję Python 3.

    Aby móc pracować zdalnie z GitHub, można zainstalować najnowszą wersję git, podążając według tego poradnika.

    Jeżeli planujesz tylko edytować zawartość artykułów Markdown, możesz po prostu zainstalować najnowszą wersję Visual Studio Code, żeby mieć interfejs graficzny do zarządzania git oraz podgląd Markdown, albo pracuj z dowolnym znanym edytorem tekstu i omiń konfigurację środowiska.

    Jeżeli planujesz bardziej złożone programowanie w Python, możesz podążyć według tego poradnika krok po kroku dla Windowsa lub macOS jak skonfigurować środowisko developerskie z Visual Studio Code (VS Code).

    Przygotowanie Systemu (tekst)

    Żeby przygotować system do uruchomienia projektu lokalnie, podążaj według tych instrukcji.

    1. Zainstaluj najnowszą wersję Pythona.
      Upewnij się, żeby zaznaczyć opcję "Add Python to PATH" podczas instalacji.

    2. Otwórz okno Terminala/Konsoli poleceń/PowerShell.

    3. Sprawdź, że instalacja Pythona była pomyślna, korzystając z tego polecenia (możliwa jest potrzeba restartu okna konsoli):

      python --version
       
    4. Zainstaluj najnowszą wersję git, podążając według tego poradnika.

    5. Sprawdź, że instalacja git była pomyślna, korzystając z tego polecenia (możliwa jest potrzeba restartu okna konsoli):

      git --version
       
    6. (opcjonalne) Zainstaluj najnowszą wersję Visual Studio Code dla interfejsu graficznego do zarządzania git i podglądem Markdown.

    Praca lokalna

    Aby móc pracować lokalnie:

    1. Stwórz kopię (ang. fork) na serwisie GitHub.
    2. Na lokalnym PC nawiguj do folderu, w którym chcesz sklonować kopię repozytorium, oraz otwórz okno konsoli wewnątrz niego.
    3. Sklonuj kopię repozytorium, korzystając z tego polecenia:

      git clone https://github.com/user-name/forked-repository-name.git <DIR-PATH>
       

      Zamiast https://github.com/user-name/forked-repository-name.git skorzystaj z własnego linku, który jest widoczny po kliknięciu zielonego przycisku <> Code i wybraniu zakładki HTTPS.

      Zamień <DIR-PATH> ze ścieżką do folderu, do którego ma być sklonowane repozytorium albo . jeżeli już jesteś wewnątrz folderu gdzie pliki projektu mają się znajdować.

      To automatycznie utworzy zdalne repozytorium origin skierowane względem twojej kopii.

    4. Dodaj zdalne repozytorium upstream korzystając z tego polecenia:

      git remote add upstream https://github.com/Gothic-Modding-Community/gmc.git
      @@ -103,4 +103,4 @@
               "xx": "yyy",
           }
       %}
      -
    5. Odwiedź oficjalną stronę skórki. Upewnij się, że tłumaczenie skórki jest tam kompletne. Jeżeli nie jest, podążaj według poradnika kontrybucji skórki i wróć tutaj, nie trzeba czekać na zmiany w skórce.

    Dodaj przetłumaczone strony

    Każdy plik .md w folderze docs może mieć przetłumaczoną wersję.
    Żeby dodać tłumaczenie strony dla danego języka, stwórz kopię strony z dodaną końcówką tego języka. Na przykład index.md będzie index.xx.md dla języka xx bazując na ustawieniach z pliku mkdocs.yml.

    Każdy nieprzetłumaczony artykuł posiada przycisk w górnym prawym rogu obok tytułu. Pozwala na szybkie dodanie tłumaczenia poprzez interfejs serwisu GitHub bez potrzeby konfiguracji plików lokalnie.

    \ No newline at end of file +
  4. Odwiedź oficjalną stronę skórki. Upewnij się, że tłumaczenie skórki jest tam kompletne. Jeżeli nie jest, podążaj według poradnika kontrybucji skórki i wróć tutaj, nie trzeba czekać na zmiany w skórce.

Dodaj przetłumaczone strony

Każdy plik .md w folderze docs może mieć przetłumaczoną wersję.
Żeby dodać tłumaczenie strony dla danego języka, stwórz kopię strony z dodaną końcówką tego języka. Na przykład index.md będzie index.xx.md dla języka xx bazując na ustawieniach z pliku mkdocs.yml.

Każdy nieprzetłumaczony artykuł posiada przycisk w górnym prawym rogu obok tytułu. Pozwala na szybkie dodanie tłumaczenia poprzez interfejs serwisu GitHub bez potrzeby konfiguracji plików lokalnie.

\ No newline at end of file diff --git a/pl/genome/general_info/object_persistence/index.html b/pl/genome/general_info/object_persistence/index.html index 38680cda6e..a5ac9680e4 100644 --- a/pl/genome/general_info/object_persistence/index.html +++ b/pl/genome/general_info/object_persistence/index.html @@ -1,4 +1,4 @@ - Object persistence - Gothic Modding Community

Object persistence

Please note the following warning about Risen 2, 3 and ELEX 1 and 2

The following information only applies to Gothic 3 (2006) and Risen (2009). While newer Genome engine games share the same overall concepts, they have significant implementation differences that warrant their own section.

The engine is, due to the nature of the games themselves, required to store and load a vast amount of different types of data from the user's hard-drive. In order to streamline this parsing and/or serialization process, Genome implements an object persistence system using its own built-in runtime type information (RTTI) system.

Any class derived from bCObjectBase may declare its own member properties in such a way that when the object is then written into a file using the bCAccessorPropertyObject class, its associated properties will be automatically serialized into the stream by using special preprocessor macros. When the object is read back from the file, the class will be automatically initialized using the stored members.

Additionally, classes may overload the Read and Write (OnRead and OnWrite in Risen 1) virtual methods that allow the class to save additional data required during parsing such as paths to other necessary files.

As this system is quite flexible, it is used to store most of the game's data, from meshes, animations and textures to level and quest data. This is quite different from ZenGin, as its object persistence system is only used for worlds, saves, output units and parts of compiled meshes.

File format

Files

1
+     

Object persistence

Please note the following warning about Risen 2, 3 and ELEX 1 and 2

The following information only applies to Gothic 3 (2006) and Risen (2009). While newer Genome engine games share the same overall concepts, they have significant implementation differences that warrant their own section.

The engine is, due to the nature of the games themselves, required to store and load a vast amount of different types of data from the user's hard-drive. In order to streamline this parsing and/or serialization process, Genome implements an object persistence system using its own built-in runtime type information (RTTI) system.

Any class derived from bCObjectBase may declare its own member properties in such a way that when the object is then written into a file using the bCAccessorPropertyObject class, its associated properties will be automatically serialized into the stream by using special preprocessor macros. When the object is read back from the file, the class will be automatically initialized using the stored members.

Additionally, classes may overload the Read and Write (OnRead and OnWrite in Risen 1) virtual methods that allow the class to save additional data required during parsing such as paths to other necessary files.

As this system is quite flexible, it is used to store most of the game's data, from meshes, animations and textures to level and quest data. This is quite different from ZenGin, as its object persistence system is only used for worlds, saves, output units and parts of compiled meshes.

File format

Files

1
 2
 3
 4
struct bCIOStream
@@ -256,4 +256,4 @@
 object.myInt = 1;
 object.someData = 1;
 

If we now serialized, or to use the engine's term "archived", this instance into an ASCII stream, the result would look like this:


-
\ No newline at end of file +
\ No newline at end of file diff --git a/pl/genome/index.html b/pl/genome/index.html index fabf9b5aa2..da17aaf6b0 100644 --- a/pl/genome/index.html +++ b/pl/genome/index.html @@ -1,4 +1,4 @@ - Genome Engine - Gothic Modding Community

Genome Engine

Genome Engine to nowy silnik autorstwa Piranha Bytes stworzony na potrzeby gry Gothic 3, a następnie wykorzystany w serii gier Risen i ELEX.

\ No newline at end of file +

Genome Engine

Genome Engine to nowy silnik autorstwa Piranha Bytes stworzony na potrzeby gry Gothic 3, a następnie wykorzystany w serii gier Risen i ELEX.

\ No newline at end of file diff --git a/pl/genome/tools/index.html b/pl/genome/tools/index.html index a099ae7798..5db83eaaeb 100644 --- a/pl/genome/tools/index.html +++ b/pl/genome/tools/index.html @@ -1,4 +1,4 @@ - Tools - Gothic Modding Community

Tools

Piranha Bytes did not release a modkit for their Genome engine, but the modding community has released a wide range of tools to work with the game's files and the engine itself.

Info

This page is under construction, for now, only handful of links are present.

Gothic 3 SDK

Georgeto, inspired by NicoDE's Risen SDK, has created an SDK for Gothic 3. It can be used to manipulate the engine in the similar way Union is able to manipulate ZenGin.
GitHub repository

\ No newline at end of file +

Tools

Piranha Bytes did not release a modkit for their Genome engine, but the modding community has released a wide range of tools to work with the game's files and the engine itself.

Info

This page is under construction, for now, only handful of links are present.

Gothic 3 SDK

Georgeto, inspired by NicoDE's Risen SDK, has created an SDK for Gothic 3. It can be used to manipulate the engine in the similar way Union is able to manipulate ZenGin.
GitHub repository

\ No newline at end of file diff --git a/pl/index.html b/pl/index.html index 86da07bc4e..2c20884214 100644 --- a/pl/index.html +++ b/pl/index.html @@ -1,4 +1,4 @@ - Witamy na stronie Gothic Modding Community - Gothic Modding Community

Witamy na stronie Gothic Modding Community

Ta strona GitHub jest zaprojektowana w celu zawarcia zbioru artykułów, poradników oraz innej dokumentacji o Gothicu utrzymywanych przez społeczność.

Dwie pierwsze części gier Gothic korzystają z silnika o nazwie ZenGin, stworzonego przez Piranha Bytes oraz grupę programistów o nazwie Mad Scientists. Jeżeli chcesz wiedzieć więcej o historii tworzenia, to jest masa informacji na Gothic Archive.

Zawartość strony nie jest przeznaczona, aby być uznaną za święte słowa moddingu. Jesteśmy tylko modderami dzielącymi się doświadczeniami, wiedzą oraz naszym ulubionym tokiem pracy.

Nie krępuj się, aby otworzyć prośbę o połączenie (ang. pull request) z twoim artykułem, lub z propozycją zmian. Po więcej informacji jak to zrobić zobacz, Jak Się Udzielić.

Możesz otworzyć prośbę o połączenie względem tego repozytorium.

\ No newline at end of file +

Witamy na stronie Gothic Modding Community

Ta strona GitHub jest zaprojektowana w celu zawarcia zbioru artykułów, poradników oraz innej dokumentacji o Gothicu utrzymywanych przez społeczność.

Informacja

Zawartość strony nie jest przeznaczona, aby być uznaną za święte słowa moddingu. Jesteśmy tylko modderami dzielącymi się doświadczeniami, wiedzą oraz naszym ulubionym tokiem pracy.

  • Serwer Discord


    Jeśli masz jakieś pytania związane z modowaniem lub po prostu chcesz porozmawiać, dołącz do naszego serwera Discord.

    Discord

  • Udzielanie się


    Nie krępuj się, aby otworzyć prośbę o połączenie (ang. pull request) z twoim artykułem, lub z propozycją zmian. Tutaj znajdziesz pełną instrukcje jak to zrobić.

    Jak Się Udzielić

  • Gothic Archive


    Dwie pierwsze części gier Gothic korzystają z silnika o nazwie ZenGin, stworzonego przez Piranha Bytes oraz grupę programistów o nazwie Mad Scientists. Jeżeli chcesz wiedzieć więcej o historii tworzenia, to jest masa informacji na Gothic Archive.

    Gothic Archive

  • Repozytorium


    Sprawdź nasze repozytorium GitHub, aby uzyskać kod źródłowy strony i informacje o aktualizacjach.

    GitHub

\ No newline at end of file diff --git a/pl/notready/index.html b/pl/notready/index.html index 831b4a3064..37c53bee41 100644 --- a/pl/notready/index.html +++ b/pl/notready/index.html @@ -1,4 +1,4 @@ - Notready - Gothic Modding Community

Notready

Warning

Sorry, this page is not ready yet! 😢

\ No newline at end of file +

Notready

Warning

Sorry, this page is not ready yet! 😢

\ No newline at end of file diff --git a/pl/preferences/index.html b/pl/preferences/index.html index 53b510fe1f..3697546ba5 100644 --- a/pl/preferences/index.html +++ b/pl/preferences/index.html @@ -1,4 +1,4 @@ - Preferencje - Gothic Modding Community

Preferencje

Ta strona pozwala ustawić różne preferencje do czytania dokumentacji:

Kolor

Możesz zmienić nastrój strony poprzez zmianę koloru.

Zresetuj kolory

Czcionka

Możesz zmienić czcionkę na predefiniowany.

Własny CSS

Możesz dodać niestandardowe arkusze stylów.

\ No newline at end of file +

Preferencje

Ta strona pozwala ustawić różne preferencje do czytania dokumentacji:

Kolor

Możesz zmienić nastrój strony poprzez zmianę koloru.

Zresetuj kolory

Czcionka

Możesz zmienić czcionkę na predefiniowany.

Własny CSS

Możesz dodać niestandardowe arkusze stylów.

\ No newline at end of file diff --git a/pl/zengin/anims/events/index.html b/pl/zengin/anims/events/index.html deleted file mode 100644 index 95f010ae9c..0000000000 --- a/pl/zengin/anims/events/index.html +++ /dev/null @@ -1,265 +0,0 @@ - Events - Gothic Modding Community

Events

Acknowledgment

This tutorial was possible thanks to Kerrax, VAM and their excelent articles (MDS, EventTags) and Avallach from theModders who provided valuable insight.

Animation event block overview

We often need to perform some other actions together with our animation, such as playing a sound effect, inserting item into NPC's hand or changing an item instance into a different one, like turning a raw steel into hot raw steel. These actions often need to be done at very specific moment during the animation playback, therefore they are defined using events(#aniamtion-events) in the event block which follows right after the animation definition. The event block is started and closed by curly brackets.

Example:

1
-2
-3
-4
-5
-6
-7
-8
ani ("s_RunL" 1 "s_RunL" 0.0 0.1 M. "Hum_RunLoop_M01.asc" F 12 31) // animation
-{ // event block start
-
-    *eventSFXGrnd    (12    "Run") // animation event
-    *eventSFXGrnd    (24    "Run") // animation event
-    ...
-    *eventSFXGrnd    (30    "Run") // animation event
-} // event block end
-

Warning

Each animation can define a maximum of 16 events. Should you need more, split the animation into parts and use next_ani to chain them together.

Animation events

Animation events are commands telling engine to do something. Event *eventSFXGrnd(12 "Run") will command the engine to play sound Run at the very moment (12th frame) the character lands food on the ground. So with that in mind here is the general syntax as well as each animation event in the game.

General Syntax:

    *EVENTNAME (FRAME KEYWORD "INSTANCE" [OPTIONAL] [A:VALUE] [B:VALUE])
-

FRAME - all events specify on what frame int the animation source file .ASC should this event happen

KEYWORD - some events expect very specific keywords.

"INSTANCE" - this indicates parameter is expected to be inside quotes, usually it;s slot/bone or item/sound instance name from the scrips

[OPTIONAL] - this is an example of the optional parameter. Optional parameters will be indicated by brackets [], if you don't specify them, the event will use the default value defined by the engine.

A:VALUE - some events that have more than one optional parameter use a prefix to know which was specified

NODE_NAME - will indicate any NODE should work, be it bones (BIP01...) or ZS_ slots (ZS_RIGHTHAND)

SLOT - this will indicate most likely only ZS_ slots will work.

Warning

Events should follow in ascending order by the frame they appear on. i. e. *eventTag(1 ...) must come before *eventTag(2 ...)

Event Description
eventCamTremor camera shake
eventMMStartAni start morph-mesh
eventPFX create particle effect
eventPFXStop destroy particle effect
eventSwapMesh exchange item meshes between two slots
eventSFX create sound effect
eventSFXGRND create sound effect on the ground
eventTag generic event, does action specified in parameters
Defined in engine but never used ?
eventPFXGRND create particle effect on the ground
eventSetMesh ?
modelTag same as eventTag, but applies to morphmesh?

eventCamTremor

Earthquake effect (camera shake)

Example:

*eventCamTremor (12 1000    500   2  8 )
-

Syntax:

*eventCamTremor (FRAME RANGE DURATION MIN_AMPLIFIER MAX_AMPLIFIER)
-

eventCamTremor - is a keyword, for camera shake event

Let's describe all the parameters

FRAME - animation frame at which this event starts

RANGE - range from which the effect will be 'felt' defined in in-game centimeters (1000 is 10 meters in-game)

DURATION - duration of the effect in milliseconds

MIN_AMPLIFIER - minimum amount of shaking in in-game centimeters

MAX_AMPLIFIER - the maximum amount of shaking.

eventMMStartAni

Start the animation of the morph-mesh that is attached to the specified node. Mostly used to start NPC facial animations or to animate bows/crossbows shooting.

Example:

1
-2
-3
*eventMMStartAni    (14 "T_HURT")
-*eventMMStartAni    (6  "S_SHOOT"   "ZS_RIGHTHAND")
-*eventMMStartAni    (6  "S_BOOK_NEXT_PAGE"  "ZS_RIGHTHAND" I:0.5 H:5)
-

Syntax:

*eventMMStartAni (FRAME "ANI_NAME" ["NODE_NAME"] [I:INTENSITY] [H:HOLD_TIME])
-

FRAME - animation frame at which animation should start

ANI_NAME - name of the morph-mesh animation (specified in .MMS) file

NODE_NAME - node in the hierarchy, to which morph mesh is attached. If not specified, a default value of BIP01 HEAD will be used.

I:INTENSITY - float value to specify blending of morph animation with the current one ?

H:HOLD_TIME - time in seconds, how long will the animation "stay"

Both INTENSITY and HOLD_TIME can be specified in the MMS script. All gothic morph meshes specify those values in .MMS, therefore behavior when both specified in eventMMStartAni and .MMS file is unknown/untested

eventPfx

Start particle effect at the specified bone.

Example:

1
-2
*eventPFX   (12     "ZMODELLANDDUST"    "Bip01" )
-*eventPFX   (2  1   "DEMON_ATTACK"      "BIP01 R HAND"  ATTACH)
-

Syntax:

*eventPFX (FRAME [PFX_HANDLE] "PFX_NAME" "NODE_NAME" [ATTACH])
-

FRAME - animation frame at which particle effect starts

PFX_NAME - name of the PFX instance

PFX_HANDLE - an optional integer value. Specifying this creates a 'handle' and allows stop the PFX later using eventPFXStop

NODE_NAME - node in the hierarchy. particle effect will be spawned at the node's position. If not specified, a default value of BIP01 will be used.

ATTACH - keyword, including this keyword, will make particle effect follow the node specified, otherwise, it will stay where it spawned.

Tip

ATTACH is used to create demons burning hand during the attack, while without this keyword dust particles are made to stay at the position where NPC landed after falling.

eventPFXStop

Stops particle effect previously started by eventPfx

Example:

1
-2
-3
*eventPFX       (2  1   "DEMON_ATTACK"      "BIP01 R HAND"  ATTACH) // starts pfx with handle 1
-...
-*eventPFXStop   (70 1) // stops pfx started above
-

Syntax:

*eventPFXStop (FRAME PFX_HANDLE)
-

FRAME - animation frame at which particle effect should disappear

PFX_HANDLE - an integer value. Handle of the particle effect, that should be destroyed. Particle effect must be spawned using the same handle by eventPfx first

eventSwapMesh

Move mesh from source NODE to target node. Item should be present in the node already. Only mesh of the Items is moved, engine internally still keeps a reference to items in the original slot? Never used in game?

Example:

*eventSwapMesh (5 "ZS_CROSSBOW" "ZS_LEFTARM")
-

Syntax:

*eventSWAPMESH      (FRAME "SOURCE_NODE_NAME" "TARGET_NODE_NAME")
-

FRAME - animation frame at which transport of the mesh should happen

SOURCE_NODE_NAME - source node containing the item.

TARGET_NODE_NAME - target node that the item should be moved to.

Note

In some rare occasions duplicates item

eventSfx

Play sound effect. It can be either SFX instance from scripts, or .WAV file.

Example:

1
-2
-3
*eventSFX   (0  "Drown")
-*eventSFX   (8  "WHOOSH"    EMPTY_SLOT)
-*eventSFX   (8  "BAB_SIGH" R:5000   EMPTY_SLOT)   
-

Syntax:

*eventPFX (FRAME "SFX_NAME" [R:RANGE] [EMPTY_SLOT])
-

FRAME - animation frame at which particle effect starts

SFX_NAME - name of the SFX instance or .WAV file

R:RANGE - an optional integer value. The range from which the effect will be 'heard' defined in in-game centimeters (1000 is 10 meters in-game)

[EMPTY_SLOT] - optional keyword. By default audio effects use a single audio channel (slot) per Model. That means every eventSFX request will cancel any currently playing effect. If EMPTY_SLOT is specified, audio will be played on the next available (empty) audio slot and other sounds will not be interrupted.

Note

A lot of original game animations contain EMTPY_SLOT instead of EMPTY_SLOT which was probably unintended. Gothic therefore acts as no keyword was provided, which causes a lot of sound interruptions. Therefore be mindful of spelling when copying original MDS scripts

eventSfxGrnd

the same as eventSfx with only one difference, the sound effect name is appended with the current material name.

Example:

*eventSFXGrnd (12 "Run")
-

Syntax:

*eventSFXGrnd (FRAME "SFX_NAME" [R:RANGE] [EMPTY_SLOT])
-

Depending on the material of the texture, the character is standing on, the game will add one of the following suffixes:

Spacer Material Suffix Gothic 1 Gothic 2a
UNDEF _Undef ✔️ ✔️
EARTH _Earth ✔️ ✔️
SAND _Sand ✔️ ✔️
METAL _Metal ✔️ ✔️
WATER _Water ✔️ ✔️
WOOD _Wood ✔️ ✔️
SNOW _Snow ✔️
STONE _Stone ✔️ ✔️
default _Stone ✔️ ✔️

NPC running on grass texture, with material set to EARTH in world editor, will play sound Run_Earth by using *eventSFXGrnd (12 "Run") in run animation. _Earth suffix is determined and added by the engine.

eventTag

This is a generic type of event that does different actions based on the first parameter after the frame parameter. It was probably later in development to extend MDS functionality without the need to expand parser itself. All parameters except FRAME are passed inside quotes Further parameters are specific for every EVENT_TAG_TYPE.

Waning

eventTag contrary to other events is validated only at runtime. If parameters are wrong, it won't work or might crash the game

Syntax:

*eventTag (FRAME "EVENT_TAG_TYPE" "PARAMETER_1"  "PARAMETER_2" ... "PARAMETER_N")
-

FRAME - Frame at which the event will execute. This parameter is always first and the same for all eventTags

EVENT_TAG_TYPE - a type of event = action that should happen.

Here is a list of event tag types:

EVENT TAG TYPE Description
DEF_CREATE_ITEM Creates item into slot
DEF_INSERT_ITEM Inserts item to slot from inventory
DEF_REMOVE_ITEM Removes item from slot to inventory
DEF_DESTROY_ITEM Destroys item in slot
DEF_PLACE_ITEM ~~Places item from slot into mob slot~~ Destroys item in slot
DEF_EXCHANGE_ITEM Removes item in slot and replaces with new item
DEF_FIGHTMODE Sets npc into weapon stance
DEF_PLACE_MUNITION Inserts munition into slot
DEF_REMOVE_MUNITION Remove munition back to inventory
DEF_DRAWSOUND Plays weapon drawing sound based on weapon material
DEF_UNDRAWSOUND Plays weapon sheating sound based on weapon material
DEF_SWAPMESH Moves items visual to different slot visually
DEF_DRAWTORCH Inserts torch
DEF_INV_TORCH Moves torch to different slot temporarily
DEF_DROP_TORCH Drops torch from slot to world
DEF_HIT_LIMB Defines node which deals damage
DEF_DIR Defines attack direction
DEF_DAM_MULTIPLIER Defines damage mutliplier
DEF_PAR_FRAME Defines frame range for blocking
DEF_OPT_FRAME Defines damage frames
DEF_HIT_END Defines last frame to continue combo
DEF_WINDOW Defines frame for combo continuation

DEF_CREATE_ITEM

Creates a new item instance and inserts it into the specified slot. Item is not inserted permanently but only for the duration of interaction.

Example:

*eventTag    (4    "DEF_CREATE_ITEM"    "ZS_RIGHTHAND"    "ItMw_1H_Mace_L_04")
-

Syntax:

*eventTag (FRAME "DEF_CREATE_ITEM" "SLOT" "ITEM_INSTANCE")
-

SLOT - a name of the ZS_ slot, write in UPPERCASE

ITEM_INSTANCE - item instance from the scripts

Warning

This event tag most likely works only during Mob/Item interaction

DEF_INSERT_ITEM

Insert the interaction item into the specified slot.

  • during mob interaction, inserted item instance is of instance taken from UseWithItem mob property.
  • during item interaction (i.e. drink potion) item that started the SceneName will be inserted.

In the example below: (1) inserts ItMiSwordrawhot that is defined in spacer into ZS_LEFTHAND, then (2) spawns ItMw_1H_Mace_L_04 (hammer) into ZS_RIGHTHAND for anvil interaction.

Example:

1
-2
-3
-4
-5
ani    ("t_BSANVIL_S0_2_S1"    1    "s_BSANVIL_S1"    0.0    0.0    M.    "Hum_BSAnvil_Jue00.asc"    F    4    9)
-{
-    *eventTag    (4    "DEF_INSERT_ITEM"    "ZS_LEFTHAND")    // (1)
-    *eventTag    (4    "DEF_CREATE_ITEM"    "ZS_RIGHTHAND"    "ItMw_1H_Mace_L_04")    // (2)
-}
-

Syntax:

*eventTag (FRAME "DEF_INSERT_ITEM" "SLOT")
-

SLOT - a name of the ZS_ slot, use UPPERCASE

ITEM_INSTANCE - item instance from the scripts

Warning

This event tag most likely works only during Mob/Item interaction

The well-known Gothic bug:

If player gets hit while drinking a potion, the effect of the potion is applied, but the potion remains in the inventory - the reason for the bug is that the potion item is inserted into hand using DEF_INSERT_ITEM and would be removed from the world at the end of the drinking animation, while the potion's effect (a script function that increases stats) is applied at the very beginning of the animation. When the player is hit, the drinking animation is interrupted, and the engine does not remove the item from the world.

DEF_REMOVE_ITEM

Remove an item inserted into a slot via DEF_INSERT_ITEM from the slot back into the inventory.

Example:

*eventTag (0 "DEF_REMOVE_ITEM")
-

Syntax:

*eventTag (FRAME "DEF_REMOVE_ITEM")
-

Warning

This event tag most likely works only during Mob/Item interaction

DEF_DESTROY_ITEM

Destroys an item inserted into a slot via DEF_INSERT_ITEM. The item is removed from the world.

Example:

*eventTag (0 "DEF_DESTROY_ITEM")
-

Syntax:

*eventTag (FRAME "DEF_DESTROY_ITEM")
-

Warning

This event tag most likely works only during Mob/Item interaction

DEF_PLACE_ITEM

Remove the item inserted via eventTag DEF_INSERT_ITEM from the slot and the world. In terms of its action, eventTag DEF_PLACE_ITEM is a synonym for DEF_DESTROY_ITEM. Possibly fixed by SystemPack. See intended use.

Example:

*eventTag (0 "DEF_PLACE_ITEM")
-

Syntax:

*eventTag (FRAME "DEF_PLACE_ITEM")
-

Warning

This event tag most likely works only during Mob/Item interaction

Intended use

Presumably, the eventTag DEF_PLACE_ITEM was intended to have different behavior: If an NPC interacts with a MOB that has a ZS_SLOT node, then move the item inserted via DEF_INSERT_ITEM from the NPC node into the ZS_SLOT node on the MOB. An example would be orc priest hearts in the Temple of the Sleeper, Gothic 1.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
// Sleeper Portal
-ani ("t_SPORTAL_Stand_2_S0"     1    "s_SPORTAL_S0"     0.0    0.0    M.    "Hum_SleeperPortal_M01.asc"    F    0    19)
-ani ("s_SPORTAL_S0"             1    "s_SPORTAL_S0"     0.0    0.0    M.    "Hum_SleeperPortal_M01.asc"    F    20    20)
-ani ("t_SPORTAL_S0_2_Stand"     1    ""                 0.0    0.2    M.    "Hum_SleeperPortal_M01.asc"    R    0    19)
-ani ("t_SPORTAL_S0_2_S1"        1    "s_SPORTAL_S1"     0.0    0.0    M.    "Hum_SleeperPortal_M01.asc"    F    21    90    FPS:10)
-{
-    *eventTag    (60    "DEF_INSERT_ITEM"    "ZS_RIGHTHAND")    // (1)
-    *eventTag    (90    "DEF_PLACE_ITEM")    // (2)
-}
-ani ("s_SPORTAL_S1"             1    "s_SPORTAL_S1"     0.0    0.0    M.    "Hum_SleeperPortal_M01.asc"    F    91    91)
-ani ("t_SPORTAL_S1_2_Stand"     1    ""                 0.0    0.2    M.    "Hum_SleeperPortal_M01.asc"    F    90    100)
-

During animation on 60th frame,(1) inserts orc priest sword from the inventory, and (2) on 90th frame, presumably, should have left the sword inserted into the heart sticking out. There is ZS_SLOT present to indicate the location of the sword after insertion into the heart.

In reality, (2) simply removes the sword from the world like DEF_DESTROY_ITEM. This was most likely an unrealized idea. In G2, eventTag DEF_PLACE_ITEM is not used.

DEF_EXCHANGE_ITEM

Replace an item in a slot with another item. Item present in the slot is removed from the slot and the world, new item specified in parameters is created and inserted in the same slot.

Example:

*eventTag (37 "DEF_EXCHANGE_ITEM" "ZS_LEFTHAND" "ItMiSwordrawhot")
-

Syntax:

*eventTag (FRAME "DEF_EXCHANGE_ITEM" "SLOT" "ITEM_INSTANCE")
-

SLOT - a name of the ZS_ slot, use UPPERCASE

ITEM_INSTANCE - item instance from the scripts

Warning

This event tag most likely works only during Mob/Item interaction

DEF_FIGHTMODE

Set fight mode for the model. Used in transition animations to weapon stances like t_1h_2_1hRun.

Example:

*eventTag (5 "DEF_FIGHTMODE" "FIST")
-

Syntax:

*eventTag (FRAME "DEF_FIGHTMODE" "FIGHT_MODE")
-

FIGHT_MODE - fight modes are defined in the engine and can be one of the following:

  • "" - remove weapon
  • "FIST" - fists
  • "1H" or "1HS" - one-handed weapon
  • "2H" or "2HS" - two-handed weapon
  • "BOW" - bow
  • "CBOW" - crossbow
  • "MAG" - magic

Example: Parameter 1H sets fight mode for the actor (in the engine), but also exchanges sword from ZS_SWORD slot to the ZS_RIGHTHAND

DEF_PLACE_MUNITION

Place ammunition, from inventory such as an arrow into the specified slot. Used in reloading animations after a bow/crossbow shot.

Example:

*eventTag (9 "DEF_PLACE_MUNITION" "ZS_RIGHTHAND")
-

Syntax:

*eventTag (FRAME "DEF_PLACE_MUNITION" "SLOT")
-

SLOT - slot where the ammunition is created. There are only two valid slot names: "ZS_LEFTHAND" and "ZS_RIGHTHAND".

Ammunition always corresponds to the equipped ranged weapon instance and its munition field in the C_ITEM instance

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
instance ItRw_Sld_Bow(C_Item)
-{
-    name = "Лук";
-    mainflag = ITEM_KAT_FF;
-    flags = ITEM_BOW;
-    material = MAT_WOOD;
-    value = Value_SldBogen;
-    damageTotal = Damage_SldBogen;
-    damagetype = DAM_POINT;
-    munition = ItRw_Arrow;
-    cond_atr[2] = ATR_DEXTERITY;
-    cond_value[2] = Condition_SldBogen;
-    visual = "ItRw_Sld_Bow.mms";
-    description = name;
-    text[2] = NAME_Damage;
-    count[2] = damageTotal;
-    text[3] = NAME_Dex_needed;
-    count[3] = cond_value[2];
-    text[5] = NAME_Value;
-    count[5] = value;
-};
-

DEF_REMOVE_MUNITION

Remove ammunition previously placed by DEF_PLACE_MUNITION event

Example:

*eventTag (19 "DEF_REMOVE_MUNITION")
-

Syntax:

*eventTag (FRAME "DEF_REMOVE_MUNITION")
-

DEF_DRAWSOUND

Play weapon drawing sound. Determined by drawn weapon material field in the C_ITEM instance

  • “DrawSound_WO.wav” - for MAT_WOOD;
  • "DrawSound_ME.wav" - for MAT_METAL.

Example:

*eventTag (19 "DEF_DRAWSOUND")
-

Syntax:

*eventTag (FRAME "DEF_DRAWSOUND")
-

DEF_UNDRAWSOUND

Play weapon sheathing sound. Determined by drawn weapon material field in the C_ITEM instance

  • "UndrawSound_WO.wav” - for MAT_WOOD;
  • "UndrawSound_ME.wav" - for MAT_METAL.

Example:

*eventTag (19 "DEF_UNDRAWSOUND")
-

Syntax:

*eventTag (FRAME "DEF_UNDRAWSOUND")
-

DEF_SWAPMESH

Swap items in the specified slots.

Example:

*eventTag (5 "DEF_SWAPMESH" "ZS_CROSSBOW" "ZS_LEFTHAND")
-

Syntax:

*eventTag (FRAME "DEF_SWAPMESH" "SLOT1" "SLOT2")
-

SLOT1 - name of the slot with item to be exchanged.

SLOT2 - name of the slot with item to be exchanged.

Warning

In case SLOT1 or SLOT2 is equal to "ZS_LEFTHAND" or "ZS_RIGHTHAND", the engine will attempt to put the model into fight mode similar to DEF_FIGHTMODE event. This can lead to game freezing.

Tip

This event is similar to the *eventSwapMesh. The main difference is *eventSwapMesh will swap only visuals (meshes) of the items, while eventTag DEF_SWAPMESH will swap items and their slot references. After a game reload, meshes would reset their positions if swapped using *eventSwapMesh. Additionally *eventSwapMesh does not try to set the model into fight mode.

DEF_DRAWTORCH

Does nothing? never used.

Example:

*eventTag (5 "DEF_DRAWTORCH")
-

Syntax:

*eventTag (FRAME "DEF_DRAWTORCH")
-

DEF_INV_TORCH

Temporarily return torch into inventory, for the duration of mob/item interaction. Does nothing if a torch is not present in ZS_LEFTHAND. Used before interacting with mobs like bed, or before performing eating animations that require a left hand.

Example:

*eventTag (5 "DEF_INV_TORCH")
-

Syntax:

*eventTag (FRAME "DEF_INV_TORCH")
-

DEF_DROP_TORCH

Drop the torch onto the ground if present in ZS_LEFTHAND.

Example:

*eventTag (5 "DEF_DROP_TORCH")
-

Syntax:

*eventTag (FRAME "DEF_DROP_TORCH")
-

DEF_HIT_LIMB

Set which node is dealing damage to others. This node is then used in calculations for collisions. Up to four slots can be specified.

Example:

1
-2
-3
-4
-5
-6
// humans - fist attacks
-*eventTag (0     "DEF_HIT_LIMB"     "BIP01 R HAND")
-// humans - sword attacks
-*eventTag (0 "DEF_HIT_LIMB" "ZS_RIGHTHAND")
-// animals 
-eventTag (0 "DEF_HIT_LIMB"    "BIP01 HEAD")
-

Syntax:

*eventTag (FRAME "DEF_HIT_LIMB" "SLOT1" "SLOT2" "SLOT3" "SLOT4")
-

DEF_DIR

Set the direction of the attack. Enemy block animation is determined by this information. Not used.

Example:

1
-2
-3
*eventTag (0 "DEF_DIR"  "O")
-*eventTag (0 "DEF_DIR"  "L")
-*eventTag (0 "DEF_DIR"  "OUOL") // combo attack - top, under, 
-

Syntax:

*eventTag (FRAME "DEF_DIR" "DIRECTIONS")
-

DIRECTIONS - can be up to 10 characters, each character defines one attack direction during combo attack, default is O - capital letter O, not zero 0. Possible values are

  • O - (oben) from top/ over

  • U - (unter) from under

  • R - from right

  • L - from left

If the enemy is trying to block an attack with a defined direction it will choose a matching animation adding a direction suffix like t_1hParade_U for opponent's attack direction U

Note

Sadly this feature was unused in Gothic 1. All attacks use O direction and only defined animations for blocking are for said t_1hParade_O But can be easily restored with a few new animations and MDS file edits. In Gothic 2, blocking animation uses zero 0 instead of O which might indicate the feature no longer works.

DEF_DAM_MULTIPLIER

Set damage multiplier. For the attack animation. The damage will be multiplied by a provided number regardless of whether the attack is a critical attack or not.

Example:

1
-2
*eventTag (0 "DEF_DAM_MULTIPLIER"    "0.2")
-*eventTag (0 "DEF_DAM_MULTIPLIER"    "2.0")
-

Syntax:

*eventTag (FRAME "DEF_DAM_MULTIPLIER" "MULTIPLIER")
-

MULTIPLIER - float value inside quotes

DEF_PAR_FRAME

Set frame range during which damage is blocked. If not provided whole animation is blocking damage.

Example:

*eventTag (0 "DEF_PAR_FRAME"    "1 8")
-

Syntax:

*eventTag (FRAME "DEF_PAR_FRAME" "START_FRAME_END_FRAME")
-

START_FRAME_END_FRAME - Two integer numbers inside quotes. if "0 0" is provided, the animation will be blocking it's whole duration

DEF_OPT_FRAME

Set frames during which damage collisions should be evaluated. Damage is checked for collision with "hit limb". This event usually comes in pair with eventTags DEF_WINDOW and DEF_HIT_END

Example:

1
-2
*eventTag (0 "DEF_OPT_FRAME" "6") // on hit attack, hit on 6th frame
-*eventTag (0 "DEF_OPT_FRAME"  "6 30") // 2 attack combo, hit at 6th and 30th frame
-

Syntax:

*eventTag (FRAME "DEF_OPT_FRAME" "HIT_FRAME1 HIT_FRAME2 ... HIT_FRAME10")
-

HIT_FRAME1 HIT_FRAME2 ... HIT_FRAME10 - specify 1 and up to 10 integers separated by space inside quotes. Each number represents frame at which damage should be done. Number of provided hit frames determines number of combos (max 10 possible).

DEF_HIT_END

Set frames at which the combo is “cut off” if you do not press the “up” key (G1) or the left mouse button (G2) during the attack. Gothic has bug that in this case we will hear all the sound effects following this frame, and the animation ends with the character’s characteristic twitching. The number of frames specified in this entry must match the number of frames of the eventTag DEF_OPT_FRAME.

Example:

1
-2
*eventTag (0  "DEF_HIT_END"   "32") 
-*eventTag (0  "DEF_HIT_END"   "27 48 75")      
-

Syntax:

*eventTag (FRAME "DEF_HIT_END" "HIT_END1 HIT_END2 ... HIT_END10")
-

HIT_END1 HIT_END2 ... HIT_END10 - specify 1 and up to 10 integers separated by space inside quotes. After this frame combo cannot be continued and model will continue animation until the current DEF_WINDOW - 1`. Which is usually animation returning to idle stance

DEF_WINDOW

Set a “window” in the animation - an interval of frames during which you need to press the “up” (G1) or the left mouse button (G2) to continue the combo strike.

Example:

1
-2
*eventTag (0 "DEF_WINDOW"    "9 19") // one combo with window from 9-19 (can be chained)
-*eventTag (0  "DEF_WINDOW"    "10 23 32 41 58 70") // 3 combos with windows 10-23 then 32-41, 58-70
-

Syntax:

*eventTag (FRAME "DEF_WINDOW" "HIT_1_WINDOW_START HIT_1_WINDOW_END HIT_2_WINDOW_START HIT_2_WINDOW_END  ...")
-

HIT_1_WINDOW_START HIT_1_WINDOW_END HIT_2_WINDOW_START HIT_2_WINDOW_END - specify 1 and up to 20? integers separated by space inside quotes. A window consists of a start and end frame, therefore for each DEF_OPT_FRAME, you must provide 2 numbers.

  • HIT_WINDOW_START - First value of the pair defines frame from which attack can continue.
  • HIT_WINDOW_END - Second value is a little confusing. It defines START of the next attack animation. Ability to continue combo stops at DEF_HIT_END frames. Usually there are few frames of animation, where characters returns to idle position. HIT_WINDOW_END should be one frame after characters return to idle stance, which should also be first frame of the next attack

Attack eventTags explained

This is original attack combo from Gothic 1

1
-2
-3
-4
-5
-6
-7
-8
-9
ani ("s_1hAttack"   1   "s_1hAttack"    0.0 0.1 M.  "Hum_1hAttackComboT3_M05.asc"   F   1   114)
-{
-    *eventTag       (0 "DEF_HIT_LIMB"   "ZS_RIGHTHAND")
-    *eventTag       (0 "DEF_OPT_FRAME"  "4 36 73 107") 
-    *eventTag       (0 "DEF_HIT_END"    "31 63 95 113")
-    *eventTag       (0 "DEF_WINDOW"     "10 33 42 65 78 97 110 113")
-    *eventSFX       (4  "Whoosh"    EMPTY_SLOT  )
-    *eventSFX       (72 "BACK"  EMPTY_SLOT  )
-}
-

I will edit it slightly to make it more readable. Let's focus on the DEF_OPT_FRAME, DEF_HIT_END,

1
-2
-3
-4
-5
-6
-7
-8
ani ("s_1hAttack"   1   "s_1hAttack"    0.0 0.1 M.  "Hum_1hAttackComboT3_M05.asc"   F   1   114)
-{
-    ...
-    *eventTag       (0 "DEF_OPT_FRAME"  "4         36         73         107         ") 
-    *eventTag       (0 "DEF_HIT_END"    "      31         63       95             113")
-    *eventTag       (0 "DEF_WINDOW"     "   10   33     42  65   78  97     110   113")
-    ...
-}
-

Let's focus only on the first combo.

1
-2
-3
-4
-5
-6
-7
-8
ani ("s_1hAttack"   1   "s_1hAttack"    0.0 0.1 M.  "Hum_1hAttackComboT3_M05.asc"   F   1   114)
-{
-    ...
-    *eventTag       (0 "DEF_OPT_FRAME"  "4          ...") 
-    *eventTag       (0 "DEF_HIT_END"    "      31   ...")
-    *eventTag       (0 "DEF_WINDOW"     "   10   33 ...")
-    ...
-}
-
Frames Animation Description
1 animation start
1..4 swing of the sword
4 sword is in the front of the model DEF_OPT_FRAME - test damage collisions at this frame
4..10 end of the sword swing
10 model stands ready to start next swing DEF_WINDOW - user can press key to advance combo from this frame.
10..31 slight idle 'shake' if player continues combo, animation playback will jump to the frame 33 (DEF_WINDOW second pair), from the animation perspective, next attack starts from pose similar to frame 10. If perfect inputs would be provided, animation would continue perfectly.
31 DEF_HIT_END - ends user input.
31..32 model returns to the idle position
32 idle position, standing with sword in hand animation will end here, if combo not continued (DEF_WINDOW second pair - 1)
33 first frame of the next attack (similar to frame 10) DEF_WINDOW second pair, start of next attack

eventPfxGrnd

Not used anywhere in the original game. Could possibly spawn particle effect like eventPfx but with an added suffix similar to how eventSfxGrnd works. Needs to be investigated.

Syntax:

*eventPFXGRND (FRAME)
-

eventSetMesh

Unknown

Syntax:

*eventSETMESH (FRAME "NODE_NAME")
-

modelTag

Should work similarly to eventTag, but can be defined inside aniEnum block and applies to all animations of the Model.

Syntax:

*modelTag (FRAME "EVENT_TAG_TYPE" "PARAMETER1" "PARAMETER2" "PARAMETER3" "PARAMETER4" ... )
-
\ No newline at end of file diff --git a/pl/zengin/anims/index.html b/pl/zengin/anims/index.html deleted file mode 100644 index 0f60b6aa52..0000000000 --- a/pl/zengin/anims/index.html +++ /dev/null @@ -1,34 +0,0 @@ - Animation - Gothic Modding Community

Animation

Animations in ZenGin

Animations are (apart from maybe advanced programming work using Ikarus or Union) one of the most advanced modding techniques, since you not only must understand the way they work, but also know how to write the animation script and understand the whole scheme selection system, naming convention and of course know how to animate (that is my biggest problem :D). To get a new animation into ZenGin (the Gothic engine) is not difficult per se, I would describe it as tedious.

Luckily, there are tools to help us to achieve our goal - get a new animation to be used by the engine, and in effect, to be used and seen in the game.

To describe the whole process, I constructed this small tutorial, to help other people to get animations working and to spare them many hours of searching the excellent forum posts, that describe parts of the process.
__

Excluding advanced programming work with Ikarus or Union, animations are arguably the most advanced modding discipline of ZenGin engine. Its difficulty stems for the fact that you not only have to understand the general concept, but also learn how to write the animation scripts and understand the whole scheme selection system, including naming conventions and, most important for last - actually know how to animate. Adding new animations into ZenGin is more tedious than actually difficult.

There are tool to help with this endeavor - to get a new animation implemented in the engine, and seeing its effects in game. Following tutorial has been constructed to help others to get their animations working without having to scour old forum posts for hours.

Prerequisites - Tools & Materials

  1. Gothic Mod Development Kit (MDK)
    • Gothic 1 MDK - link
    • Gothic 2 MDK - link
  2. Blender
  3. Kerrax's Import Export plugin - follow the installation instructions to install the plugin, make sure to set up the texture paths too
  4. Tool for decompiling animations GothicSourcer, or use phoenix or write your own using ZenLib

The workflow

This is the basic step-by-step workflow on how to get the animation into the game.

  1. Load the actor (character or object) into your 3D software
  2. Create your animation
  3. Export the animation as an .asc file
  4. Write the MDS file
  5. Run the game to compile your animations
  6. Test your animations in-game using a Daedalus script or a console command

Sounds simple enough, except there is a lot missing. Even though the steps start with loading the actor into blender, understanding the system of animations to get high quality assets into your mod is more important.

Animation "types"

There are two main types of animations - skeletal and morphmesh animations. Character body animations are skeletal, and we animate the skeleton and the entire model (skin) moves around it. Morph mesh animation is, on the other hand, used for facial animations such as eating, blinking or talking and for animated meshes like wave water ferns or fish in Khorinis' harbor.

This guide focuses on skeletal animations. There are few different ones, all of which will have their own demonstration in the future. Categories are:

  1. Standalone animation - waving, bowing, eating
  2. MOBSI animations - bed, alchemy table, anvil
  3. Item animations - sweeping the floor with a broomstick, using the horn, playing the lute
  4. Mandatory animations - running, walking, sneaking
  5. Combined/interpolated animations - picking stuff up, aiming with a bow/crossbow

All of these animations are defined in an MDS file which will be talked about in the next sections.

\ No newline at end of file diff --git a/pl/zengin/anims/mds/index.html b/pl/zengin/anims/mds/index.html deleted file mode 100644 index 19bc6f0cbb..0000000000 --- a/pl/zengin/anims/mds/index.html +++ /dev/null @@ -1,121 +0,0 @@ - MDS ModelScript - Gothic Modding Community

MDS - model animation script

Tip

The MDS syntax is very simple and scripts can be edited in any text editor. It is, however, easier to work in an editor with a proper syntax highlighting. Daedalus Language Server's dev branch already merged the MDS grammar for syntax highlighting, we can expect it in the next release.

Model animation script is a file describing what skeleton should be used, what body meshes work with this set of animations and how should the animations be named, how fast they run, what animation is supposed to start after the current one is finished and much more. These files are located in Gothic\_work\DATA\Anims\ directory.

Whilst the code seems long and terrifying, it is in fact rather simple, and this guide will try to explain it whole.

Don't forget to use the search

If you search this file for t_Yes, you will get an example of the first type of animation - "standalone"

To play the animation in game you use this console command play ani t_yes.

Syntax and keywords

Let us get a quick look at the naming convention to get a basic idea what is going on before we start.

The first letter indicates a type of animation (transition - t_ - or state - s_). Then depending on the animation type we have:

Transition animation

t_Run_2_Sneak
-
Transition animation from the run animation to the sneak animation.
t_BSANVIL_Stand_2_S0
-
Transition animation for the blacksmith's anvil from standing to state 0.

State animation

s_Run
-
State animation for the looping animation.
s_BSANVIL_S0
-
State animation for the blacksmith's anvil and its first state.

ani

This is the main command you will be using while defining new animations.

Example:

ani    ("t_Yes" 2 "" 0.1 0.1 M. "Hum_Yes_M01.asc" F 1 44)
-
Syntax:
ani (ANI_NAME LAYER NEXT_ANI BLEND_IN BLEND_OUT FLAGS ASC_NAME ANI_DIR START_FRAME END_FRAME)
-
ani - is a keyword, we are defining new animation

Let's describe all the parameters

ANI_NAME - animation name, we use it in Daedalus as animation identifier

There is a naming convention, that is recommended and sometimes required to be used.

  • prefix t_ - transition animations
  • prefix s_ - state animations - they usually run in a loop
  • prefix c_ - animations used for animation combining/interpolation

LAYER - layer number for multi-layer animations

NEXT_ANI - name of the next animations

BLEND_IN - time in seconds describing animation blending at the start

If we set it to 0.5, it takes 0.5 seconds for this animation to take full effect. At 0.0 s the previous animation has full effect on the bones of the skeleton, at 0.1 s it is influenced by 20% by this animation and at 0.5s it is completely influenced by this animation and the previous one has no effect.

BLEND_OUT - time in seconds describing animation blending at the end

FLAGS - flags, that describe animation behavior

  • M - specifies a movement animation, the animation of the model translates into a changed position in the game world
  • R - the same as M but for rotation
  • E - this flag makes this animation run only, if the animation in the same layer are finished, this is used in the movement animations. The animation s_walk (walking loop animation) runs, when the player is walking,when he stops the transition animation to standing state is played t_walk_2_stand. This animation uses the E flag to wait for the walk cycle animation to finish, to smoothly transition into the standing state.
  • F - the engine ignores height coordinate - doesn't keep the model "glued" to the ground (falling/flying animation)
  • I - specifies idle animation - breathing, standing with a drawn weapon and moving the weapon

ASC_NAME - name of the source file exported from Blender

ANI_DIR - direction of the animation

  • F - forward
  • R - reverse

START_FRAME - on what frame from the source file the animation starts

END_FRAME - on what frame from the source file the animation ends

aniAlias

Generally considered as one of the most useful commands, aniAlias is used to create an alias (hard link for UNIX users) for an already defined animation.

Example:

aniAlias ("t_Sneak_2_Run" 1 "s_Run" 0.0    0.1    M. "t_Run_2_Sneak" R)
-
Syntax:
aniAlias (ANI_NAME LAYER NEXT_ANI BLEND_IN BLEND_OUT FLAGS ALIAS_NAME ANI_DIR)
-

ANI_NAME - name of the new animation

LAYER - layer the animation is on

NEXT_ANI - name of the next animations

BLEND_IN - time in seconds describing animation blending at the start

BLEND_OUT - time in seconds describing animation blending at the end

FLAGS - flags, that describe animation behavior

ALIAS_NAME - name of the animation we want to use as a source for the alias

ANI_DIR - direction of the animation

If we look for the animation in the example we can see that there is a related one just one line above

1
-2
ani            ("t_Run_2_Sneak" 1 "s_Sneak" 0.1 0.0 M. "Hum_Sneak_M01.asc"     F 0 10)
-aniAlias    ("t_Sneak_2_Run" 1 "s_Run"      0.0 0.1 M. "t_Run_2_Sneak"      R)
-
In this example we are defining t_Sneak_2_Run animation and we are specifying that the animation after this one is finished will be s_Run and that it is being made by reversing animation t_Run_2_Sneak by specifying the R flag.

aniBlend

AniBlend is used to define animations that are a result of blending of two animations. This animation is not animated by hand, but it is dynamically generated by the engine during run-time.

Example

aniBlend ("t_RunR_2_Run" "s_Run" 0.2 0.2)
-
Syntax:
aniBlend (ANI_NAME NEXT_ANI BLEND_IN BLEND_OUT)
-

ANI_NAME - name of the new animation

NEXT_ANI - name of the next animations

BLEND_IN - time in seconds describing animation blending at the start

BLEND_OUT - time in seconds describing animation blending at the end

aniSync

Not used in the game.

aniBatch

Not used in the game.

Animation state machine

More complex animations such as MOBSI animations form a state machine - an animation set.

MDS script for the big chest
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
Model ("CHESTBIG_OCCRATELARGE")
-{
-    meshAndTree ("CHESTBIG_OCCRATELARGE.asc")
-
-    aniEnum
-    {
-// Closed chest
-        ani         ("s_S0"                 1   "s_S0"  0.0 0.0 M.  "CHESTBIG_USE.asc"  F   20  20)
-// Opening the chest 
-        ani         ("t_S0_2_S1"            1   "s_S1"  0.0 0.0 M.  "CHESTBIG_USE.ASC"  F   50  79)
-        {
-            *eventSFX   (50 "chest_try")
-            *eventSFX   (55 "chest_open")
-        }
-// Opened chest
-        ani         ("s_S1"                 1   "s_S1"  0.0 0.0 M.  "CHESTBIG_USE.asc"  F   80  80)
-// Closing the chest
-        ani         ("t_S1_2_S0"            1   "s_S0"  0.0 0.0 M.  "CHESTBIG_USE.asc"  R   50  79)
-        {
-            *eventSFX   (78 "chest_close")
-        }
-// Pick lock broken
-        ani         ("t_S0_Try"             1   "s_S0"  0.0 0.0 M.  "CHESTBIG_USE.asc"          F   96  124)
-        {
-            *eventSFX   (100    "chest_try")
-            *eventSFX   (115    "Hammer")
-        }
-    }
-}
-
stateDiagram-v2
-    s_S0      : Closed chest
-    t_S0_2_S1 : Opening the chest
-    s_S1      : Opened chest
-    t_S1_2_S0 : Closing the chest
-    t_S0_Try  : Pick lock broken
-    [*] --> s_S0
-    s_S0 --> s_S0
-
-    s_S0 --> t_S0_2_S1
-    t_S0_2_S1 --> s_S1
-    s_S1 --> s_S1
-
-    s_S1 --> t_S1_2_S0
-    t_S1_2_S0 --> s_S0
-
-    s_S0 --> t_S0_Try
-    t_S0_Try --> s_S0
\ No newline at end of file diff --git a/pl/zengin/anims/standalone_ani/index.html b/pl/zengin/anims/standalone_ani/index.html deleted file mode 100644 index 40570b3c17..0000000000 --- a/pl/zengin/anims/standalone_ani/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/pl/zengin/anims/tutorials/standalone_animation/index.html b/pl/zengin/anims/tutorials/standalone_animation/index.html deleted file mode 100644 index 83ef2e70ea..0000000000 --- a/pl/zengin/anims/tutorials/standalone_animation/index.html +++ /dev/null @@ -1,88 +0,0 @@ - Standalone animation - Gothic Modding Community

Standalone animation

Acknowledgment

This tutorial would not be possible without the ZenGin documentation available in the mod-kit. Further credits also go to Mark56 who helped me understand animations in the first place, Fawkes and his request for me to do some animations for his excellent mod - Replay Mod, and last but not least Flosha from the Phoenix team who was the one for whom I offered to write this tutorial to help with the development of the Phoenix project.

Let us start with the easiest animation - a very simple gesturing animation.

Info

You can find some of the videos that are mentioned in the text below in this play-list.

Firstly we have to have the animation source files ready. Best way to decompile them is using Gothic Sourcer. In GothicSourcer you choose Tools > Decompiler models > Dynamic (MDS or MSB) and choose an MDS file of your choice - Humans.mds in our case and then click the decompile button.

Animating

Open Blender, File > Import > Kerrax ASCII model (.asc), navigate to the folder with your decompiled animation files and select HUM_BODY_NAKED0.ASC. This file contains the skeleton and skin model for human NPCs.

What bone hierarchy is this model using?

If you open the .mds file, you can see a command meshAndTree that specifies what model contains the skeleton. And there lies our answer:

1
-2
-3
Model ("HuS")
-{
-    meshAndTree ("Hum_Body_Naked0.ASC" DONT_USE_MESH)
-

A windows pops up and you can read some interesting information about the model you are about to import. We are interested in the fact that Completely replace current scene is ticked, we want to use Armature modifier, and we also want to Try to connect bones and Use sample meshes from folder. You should provide a path to a directory with the sample meshes - these are meshes for items, that usually go into slot bones. Lastly, the space transformation scale should be set to 0.01. This is because ZenGin works with centimeter units and one unit in Blender is a meter.

Click import and wait for the magic to happen.

This video shows a freshly imported model with all default meshes.

Note

If we now want to play (or edit) existing animation, we can now load it on top of this. Just as before File > Import > Kerrax ASCII model (.asc) and select different animation file (or armor file), for example Hum_SmokeHerb_Layer_M01.asc for an animation file.

Gothic characters are modular and you can change their heads on the fly, even during gameplay as seen in this amazing video from my dear friend and colleague Fawkes - Head changing. Let's add a head so that we can see how the whole body will behave while we are animating. File > Import > Kerrax ASCII model (.asc), navigate to your head model. You will have to decompile it like we did with the body itself. We will import HUM_HEAD_PONY.ASC. Please make sure to select the target bone for importing Bip01 Head, this will attach the head to the proper bone, just like the engine does it.

Now we have everything ready to start animating. The video shows the DopeSheet a nice way to edit keyframes.

DopeSheet

Blender's dope sheet can be used to copy entire sets of keyframes. It is useful if we want to create a looping animation.

We can import an animation into Blender as a base.

Tip

If you don't know the name of the animation, just go into the game and make your character perform the animation you want. While in MARVIN mode, you can press G and the animation information together with other info will be displayed right on the screen

In this video we can see that the idle standing animation is s_run. We want to make an animation that is going to start from this idle animation, so we will import it into blender. We find it by looking into the .mds file, look for s_run name and get the name of the file.

ani    ("s_Run" 1 "s_Run" 0.1 0.1 MI "Hum_RunAmbient_M01.asc" F 1 50)  
-
As we can see, we have to import the Hum_RunAmbient_M01.asc file.

Next goes the first trick. Since we want our animation to end exactly, as it started - ether because we want the hero to continue his standing animation, or we want to make a looping animation, we somehow have to copy the pose. We use the DopeSheet screen, to delete all keyframes and then copy the keyframe set from keyframe number 0 and drag it somewhere to the end of the timeline.

Once the animation is done, we have to export it into an asc format again, File > Export > Kerrax ASCII model (.asc) and then save it to _work\data\Anims\asc\ so the engine can see it and convert it.
There are many options here that we will explore later, but we have tick Export animation and pick bones that we want to export - this is useful for animations that are played on different layers (dialogue gestures, scratching head, scratching a shoulder,...).

Animation script

Now that we have exported the animation, we now have to define it in Humans.mds.

Open the file, scroll to the end and define a new animation.

Attention

All ani code has to be between the curly brackets, this means you have to insert it before the last two closing curly brackets } }.

Example:

ani ("t_backpain" 1 "" 0.0 0.0 M. "Hum_back.ASC" F 0 121)  
-

Save the Humans.mds file and try it in game. Nothing happens! The reason is that the mds has been already compiled, and we have to recompile it. The easiest is to go to Anims\_compiled and delete HUMANS.MSB.
Run the game and try to play the animation again (play ani t_backpain in MARVIN console) and now everything should work.

Amazing, now you have your first animation in the game. And you can use it to do some fun stuff, like in dialogues using the AI_PlayAni function.

Example dialogue

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
instance DIA_Xardas_Back (C_INFO)
-{
-    npc         = NONE_100_Xardas;
-    nr          = 11;
-    condition   = DIA_Xardas_Back_Condition;
-    information = DIA_Xardas_Back_Info;
-    permanent   = TRUE;
-    description = "What's wrong?";
-};
-
-func int DIA_Xardas_Back_Condition () {
-    return TRUE;
-};
-
-func void DIA_Xardas_Back_Info () {
-    AI_Output (self, hero, "DIA_Xardas_MOB_14_00"); // My back hurts so much.
-
-    // This is our animation!!!!!
-    AI_PlayAni(self, "T_BACKPAIN"); 
-    AI_Output (self, hero, "DIA_Xardas_MOB_14_01"); // How do YOU feel?
-
-    AI_Output (hero, self, "DIA_Xardas_MOB_14_02"); // My back is fine.
-    AI_StopProcessInfos(self);
-};
-

\ No newline at end of file diff --git a/pl/zengin/general_info/directory_structure/index.html b/pl/zengin/general_info/directory_structure/index.html deleted file mode 100644 index e42969e833..0000000000 --- a/pl/zengin/general_info/directory_structure/index.html +++ /dev/null @@ -1,81 +0,0 @@ - Directory structure - Gothic Modding Community

ZenGin directory structure

Modding is all about changing the game files. To achieve that, we have to know the directory (folder) structure of a Gothic game.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
├── Data
-│   ├── $Templates$
-│   ├── modvdf
-│   └── Plugins
-├── Miles
-├── Saves
-├── System
-│   └── Autorun
-└── _work
-    └── DATA
-        ├── Anims
-        │   └── _Compiled
-        ├── Meshes
-        │   └── _Compiled
-        ├── Music
-        ├── Presets
-        ├── Scripts
-        │   ├── _compiled
-        │   └── content
-        │       └── CUTSCENE
-        ├── Sound
-        ├── Textures
-        ├── Video
-        └── Worlds
-

Data

Data directory contains .vdf volumes of the game. These contain anims.vdf - animations, speech.vdf - dubbing, worlds.vdf - world ZEN files.

Saves

Contains saved games.

System

The system directory contains the game executable, GothicStarter.exe, GothicStarter_mod.exe, configuration .ini files, mod .ini files and mod icons and description .rtf files.

system/Autorun is a Union specific directory, it serves as a default search directory for Daedalus injection scripts with zParserExtender and Union plugins.

_work/DATA

This is where the magic happens:

  • Anims - contains animations and animated models.
    • _compiled - contains compiled animations.
  • Meshes - contains meshes source and compiled files.
    • _compiled - contains compiled meshes.
  • Music - contains music files.
  • Presets - contains basic presets.
  • Scripts
    • _compiled - contains compiled scripts - .dat files.
    • Content - contains scripts that make up the content of the game.
    • System - contains scripts that make up the menu.
  • Sound - contains sound effects .wav or .ogg format (Union only).
  • Video - contains videos in .bik format.
\ No newline at end of file diff --git a/pl/zengin/general_info/object_persistence/index.html b/pl/zengin/general_info/object_persistence/index.html deleted file mode 100644 index 0b53f52f87..0000000000 --- a/pl/zengin/general_info/object_persistence/index.html +++ /dev/null @@ -1,376 +0,0 @@ - Object persistence - Gothic Modding Community

Object persistence

In order to simplify the process of loading and saving data of various types to and from the user's hard-drive, ZenGin implements a simple object persistence system using the zCArchiver class and its derivatives that allow the individual engine classes to implement a routine specifying which data should be saved or loaded from disk and in which manner.

An object that is derived from the zCObject class may overload the Archive and Unarchive virtual methods. The class may then call on an interface provided by the zCArchiver class within these methods which allows it to directly read from or write to a stream using several modes. Those are ASCII and BinSafe by default. There are, however, more options, as is explained below.

Archive format

In order to better understand how this process works, it would be best to look at an example of a .ZEN file containing an instance of an oCWorld object.

When you open up a ZenGin archive, you will see the following at the start of the file:

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
ZenGin Archive
-ver 1
-zCArchiverGeneric
-ASCII
-saveGame 0
-date 7.1.2001 23:9:19
-user roeske
-END
-objects 2594     
-END
-

Let's look at each of these properties and what they mean:

ZenGin Archive

This simply specifies that the following data is an zCArchiver archive.

ver 1

Version specification. Can be either 0 or 1. Both Gothic 1 and 2 are already on version 1, although version 0 archives can also be occasionally found.

zCArchiverGeneric

Specifies which derived zCArchiver class should be used to read this archive. Accepted values are zCArchiverGeneric for ASCII and Binary archives, and zCArchiverBinSafe for BinSafe archives. More info below.
This property might not be present in older archives.

ASCII

This is the most important part of the header as it specifies in which format should the data be stored. There are 4 different modes:

  • ASCII - The simplest one. It stores data in human-readable ASCII notation (not unlike JSON for example). This is usually used when saving data during development and/or testing, while the final version of said data will most likely be stored as BIN_SAFE.
  • ASCII_PROPS - Same as ASCII except with more additional data that the developer can specify for visual clarity. In practice, it is not used anywhere and mostly serves only to prettify debug info (try typing ZWORLD VOBPROPS in the console and look in zSpy ;) ).
  • BINARY - Binary representation of the class instance, which mostly copies the data 1:1 into/from the stream. In practice, this format is only used to store savefiles (.SAV).
  • BIN_SAFE - BinSafe, short for Binary Safe, is an extended version of Binary which stores type information along with the data itself. This is meant to make error checking for invalid data easier. There are other changes which are explained below. Most, if not all world files (.ZEN), are stored in this format.

saveGame 0

Specifies if this archive is a savefile. This property might not be present in older archives.

date 7.1.2001 23:9:19

The date at which this archive was created.

user roeske

The user which created the archive. This property might not be present in older archives.

END

Tells the parses that this is the end of the header.

We may additionally find a property called csum in version 0 archives which stores the checksum of the whole archive. This property is, however, unused and equals 00000000 by default.

In order to correctly read the archive's header across varying engine versions, one should not count on the properties always being in the same order or even being there at all.

If the archive utilizes zCArchiverGeneric then this header will also be followed by a short section specifying the number of object instances in this archive. This value will be used to initialize the objectList, which is an array of pointers where the addresses of loaded objects will be stored for later referencing. This property would be directly part of the main header in older versions.

objects 2594 END  
-

If the archive is created using zCArchiverBinSafe, this data will be stored in the following binary structure:

1
-2
-3
-4
struct BinSafeArchiveHeader  
-{  
-    uint32_t version;     // Always equals 2 uint32_t objectCount;  // Serves the same function as "objects n" uint32_t chunkPos;    // Offset to chunk hash table};
-};  
-

Contents

Looking further into the archive, we see what appears to be a nested structure.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
[% oCWorld:zCWorld 64513 0]
-    [VobTree % 0 0]
-        childs0=int:1
-        [% zCVobLevelCompo:zCVob 12289 1]
-            pack=int:0
-            presetName=string:
-            bbox3DWS=rawFloat:-71919.9609 -13091.8232 -59900 108999.992 20014.0352 67399.9922 
-            trafoOSToWSRot=raw:0000803f0000000000000000000000000000803f0000000000000000000000000000803f
-            trafoOSToWSPos=vec3:0 0 0
-            vobName=string:LEVEL-VOB
-            visual=string:SURFACE.3DS
-            showVisual=bool:0
-            visualCamAlign=enum:0
-            cdStatic=bool:1
-            cdDyn=bool:0
-            staticVob=bool:0
-            dynShadow=enum:0
-            [visual zCMesh 0 2]
-            []
-            [ai % 0 0]
-            []
-        []
-        ...
-

We primarily differentiate between chunks and properties within ZenGin archives:

Chunks

A chunk is a structure that groups properties together. For most of the time, a chunk represents a class instance. This is, however, not always true as classes may arbitrarily create chunks as is needed. For example, the sample above contains a chunk called VobTree, which does not represent a class instance, but only serves to make the reading of the archive easier.

While in ASCII mode, the start of a chunk is represented using square brackets.

[% oCWorld:zCWorld 64513 0]

There are 4 pieces of data separated by spaces inside the start of each chunk, which are:

  • Object name - The name of the chunk to use while reading. If the chunk has no name, then it will be simply equal to %.
  • Class name - The name of the class which this chunk represents. Class names are stored with their full inheritance hierarchy (e.g. oCMobLadder:oCMobInter:oCMOB:zCVob). In case the chunk is not an object, but an arbitrary chunk, then this field will be equal to % (% can also mean that this chunk is a nullptr). In some cases you may encounter the symbol § instead. This means that the object already exists and that the parser should look for it in the objectList using the object index. Using this mechanism, a single instance can be referenced multiple times without worrying about duplicity.
  • Class version - Used to ensure that the data being read is compatible with the current game/engine version, so that there are no mismatches in the data pattern. This value is different for every class and varies between game versions.
  • Object index - An index into the objectList under which this object will be stored. If the class name is equal to §, then this value will be used to retrieve an existing instance from the objectList.

If this is a Binary archive, the same data will be stored in the following binary structure:

1
-2
-3
-4
-5
-6
-7
-8
struct BinaryObjectHeader
-{
-    uint32_t    objectSize;        // Size of the whole object in bytes
-    uint16_t    classVersion;
-    uint32_t    objectIndex;
-    char        objectName[];    // Null-terminated string
-    char        className[];    // Null-terminated string
-};
-

Oddly enough, if the archive is BinSafe, then the data will be encoded the same way as in ASCII mode, except that it will be stored as a type-checked property.

1
-2
-3
-4
-5
-6
struct BinSafeObjectHeader
-{
-    uint32_t    type;    // 0x1 = TYPE_STRING
-    uint16_t    length;    // Length of the text
-    char        text[];    // [% oCWorld:zCWorld 64513 0]
-};
-

In ASCII mode [] represents the end of the current chunk.

Properties

We find properties inside the chunks which are key-value pairs that classes use to store the actual data. Each property stores its name, type and value. In ASCII mode the format for this isname=type:value.

For example:

visual=string:SURFACE.3DS

By default, zCArchiver allows to store properties of the following types:

  • Int - A regular 32-bit integer. In ASCII mode, int gets stored as name=int:1, while in Binary mode, it's just the raw value stored as 4 bytes.

  • Byte - A 8-bit integer. ASCII mode doesn't differentiate between Int and Byte, so this will be stored as name=int:1 regardless. Binary mode stores only the single byte.

  • Word - A 16-bit integer. ASCII mode doesn't differentiate between Int and Word, so this will be stored as name=int:1 regardless. Binary mode stores only the 2 bytes.

  • Float - A standard IEEE 754 32-bit floating point number. In ASCII mode the format is name=float:1.0, while in Binary mode the float gets stored raw as 4 bytes.

  • Bool - Stores a single-byte boolean value. In ASCII mode its name=bool:1 and in Binary mode it's a single byte.

  • String - An ASCII encoded string. While in ASCII mode, strings are stored as name=string:value. In Binary mode, strings are NULL terminated.

  • Vec3 - A three component vector, mainly used to store positional data. The ASCII mode format is name=vec3:1.0 1.0 1.0. In Binary mode the three components of the vector are stored in series, which equals to a total size of 12 bytes.

  • Color - A 32-bit color value stored as BGRA. In ASCII mode the color is stored as name=color:255 255 255 255 while in Binary mode it's just 4 raw bytes.

  • Raw - Raw binary data. In order to maintain readability, in ASCII mode this gets stored as a hex encoded string such as name=raw:63D15B07. In Binary mode, only the data itself is stored, without any other info. Be aware that due to this you must know the size of the data beforehand.

  • RawFloat - An array of floats, mainly used to store bounding boxes. In ASCII mode, the floats are stored as name=rawFloat:1.0 1.0 1.0 1.0 1.0 1.0. In Binary mode the floats are stored in series as raw bytes. Same as with Raw, you must know the size of the array beforehand.

  • Enum - An enum value. In ASCII mode, it gets stored as name=enum:1. In Binary mode, it behaves the same as Int.

As you might have noticed, binary mode doesn't perform any kind of checks on if it's reading the right property or even data of the correct type. This is why BinSafe mode exists, as it stores the property type in along with the data itself.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
-37
-38
-39
-40
-41
-42
-43
enum TYPE
-{
-    TYPE_STRING        = 0x1,
-    TYPE_INTEGER    = 0x2,
-    TYPE_FLOAT        = 0x3,
-    TYPE_BYTE        = 0x4,
-    TYPE_WORD        = 0x5,
-    TYPE_BOOL        = 0x6,
-    TYPE_VEC3        = 0x7,
-    TYPE_COLOR        = 0x8,
-    TYPE_RAW        = 0x9,
-    TYPE_RAWFLOAT    = 0x10,
-    TYPE_ENUM        = 0x11
-    TYPE_HASH        = 0x12,
-};
-
-struct BinSafeProperty
-{
-    TYPE type;
-    union
-    {
-        struct
-        {
-            uint16_t    stringLength;
-            char        stringValue[];
-        }
-        uint32_t    integerOrHashOrEnumValue;
-        float        floatValue;
-        uint8_t        byteOrBoolValue;
-        zVEC3        vec3Value;
-        zCOLOR        colorValue;
-        struct
-        {
-            uint16_t    rawLength;
-            char        rawValue[];
-        }
-        struct
-        {
-            uint16_t    rawFloatLength;
-            float        rawFloatValue[];
-        }        
-    };
-};
-

Looking at the enumeration of types, you might notice that BinSafe mode has an additional property type called Hash. BinSafe archives include a hash table which is stored in the following manner:

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
struct BinSafeHashTable
-{
-    uint32_t chunkCount;
-    for (chunkCount)
-    {
-        uint16_t    stringLength;
-        uint16_t    linearValue;
-        uint32_t    hashValue;
-        char        text[stringLength];
-    }
-};
-

Instead of storing the raw value, properties may save a hash instead, which is then used to look up the corresponding value from the hash table.

Implementation

As mentioned in the opening paragraph, classes may use the described functionality by overloading the Archive and Unarchive virtual methods, which pass an instance of zCArchiver by reference. When the class instance is then serialized and/or parsed, these methods are called and perform the desired serialization/parsing work.

The class uses methods provided by the zCArchiver instance within these routines. These methods return/accept a value of a specific type (e.g. ReadInt/WriteInt), while they do the actual reading/writing work behind the scenes based on the current mode (ASCII/Binary/BinSafe). The programmer writing the class then does not care whether the final archive will be saved as ASCII, Binary or BinSafe, as they only use the zCArchiver Read* and Write* methods.

A practical example

Let's propose that we have a class which is declared like so:

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
class zCMyClass : public zCObject
-{
-public:
-
-    zCMyClass()                {}
-    virtual ~zCMyClass()    {}
-
-    virtual void Archive(zCArchiver&);
-    virtual void Unarchive(zCArchiver&);
-
-    int myInt;
-    zCMyClass* myObject;
-    zCMyClass* secondPointerToMyObject;
-
-};
-

The hypothetical class then implements these virtual functions:

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
void zCMyClass::Archive(zCArchiver& archiver)
-{
-    archiver.WriteInt("myInt", myInt);
-
-    archiver.WriteObject("myObject", myObject);
-
-    archiver.WriteChunkStart("myChunk", 0);
-    archiver.WriteObject("secondPointerToMyObject", secondPointerToMyObject);
-    archiver.WriteChunkEnd();
-}
-
-void zCMyClass::Unarchive(zCArchiver& archiver)
-{
-    archiver.ReadInt("myInt", myInt);
-
-    myObject = dynamic_cast<zCMyClass*>(archiver.ReadObject("myObject"));
-
-    archiver.ReadChunkStart("myChunk");
-    secondPointerToMyObject = dynamic_cast<zCMyClass*>(archiver.ReadObject("secondPointerToMyObject"));
-    archiver.ReadChunkEnd();
-}
-

We then initialize the class in the following way:

1
-2
-3
-4
-5
-6
-7
-8
zCMyClass object;
-
-object.myInt = 12121212;
-
-object.myObject = new zCMyClass();
-object.myObject->myInt = 34343434;
-
-object.secondPointerToMyObject = object.myObject;
-

If we now serialized, or to use the engine's term "archived", this instance into an ASCII archive, the result would look like this:

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
ZenGin Archive
-ver 1
-zCArchiverGeneric
-ASCII
-saveGame 0
-date 3.7.2022 0:0:0
-user GMC
-END
-objects 2     
-END
-
-[% zCMyClass 0 0]
-    myInt=int:12121212
-    [myObject zCMyClass 0 1]
-        myInt=int:34343434
-        [myObject % 0 0]
-        []
-        [myChunk % 0 0]
-            [secondPointerToMyObject % 0 0]
-            []
-        []
-    []
-    [myChunk % 0 0]
-        [secondPointerToMyObject § 0 1]
-        []
-    []
-[]
-

Notice how secondPointerToMyObject doesn't have any contents. The character § tells the parser that this object already exists in the objectList, and that instead of creating a new instance, it should return an existing instance which is stored under index 1 in the objectList.
This allows an instance to be referenced from multiple places, without the need to worry about duplicity.

If we used Binary or BinSafe mode, we would see a big blob of binary data instead. This would, of course, store the exact same data, although in a slightly less human-readable format.

Final thoughts

We hope this helps you better understand the inner workings of ZenGin. If you want to see how Piranha Bytes went about implementing a much more advanced version of this system for their next engine, check out Genome's object persistence system.

\ No newline at end of file diff --git a/pl/zengin/general_info/vdfs/index.html b/pl/zengin/general_info/vdfs/index.html deleted file mode 100644 index b032360d6f..0000000000 --- a/pl/zengin/general_info/vdfs/index.html +++ /dev/null @@ -1,34 +0,0 @@ - VDFS virtual file system - Gothic Modding Community

VDFS

VDFS is the virtual file system used by ZenGin to distribute and store many, but not all, game assets.

Tools

The community created variety of different modding tools for work with VDFS volumes over the times, such as:

GothicVDFS

  • Viewing
  • Extracting
  • Building .mod and .vdf archives

VDFS Tool

  • Viewing
  • Extracting
  • Building
  • Optimizing
  • Compressing .mod and .vdf archives
\ No newline at end of file diff --git a/pl/zengin/index.html b/pl/zengin/index.html deleted file mode 100644 index 1ceef6061d..0000000000 --- a/pl/zengin/index.html +++ /dev/null @@ -1,34 +0,0 @@ - ZenGin - Gothic Modding Community

ZenGin

Silnik gry ZenGin jest używany w grach Gothic 1 i 2. Ta sekcja zawiera dokumentację różnych aspektów modowania ZenGin.

\ No newline at end of file diff --git a/pl/zengin/meshes/index.html b/pl/zengin/meshes/index.html deleted file mode 100644 index 1bf1426491..0000000000 --- a/pl/zengin/meshes/index.html +++ /dev/null @@ -1,34 +0,0 @@ - Meshes - Gothic Modding Community

Meshes

Everything about 3D models in ZenGin.

\ No newline at end of file diff --git a/pl/zengin/music/index.html b/pl/zengin/music/index.html deleted file mode 100644 index 21a963978f..0000000000 --- a/pl/zengin/music/index.html +++ /dev/null @@ -1,34 +0,0 @@ - Muzyka - Gothic Modding Community

Muzyka

Zengin używa DirectMusic do odtwarzania ścieżki dźwiękowej w grze. Aby edytować pliki muzyczne Gothica, potrzebujesz programu Direct Music Producer, który został wydany przez Microsoft i był dostarczany do starszych zestawów SDK DirectX.

Ostrzeżenie

Pliki muzyczne nie mogą być spakowane do archiwów .vdf lub .mod, wszystkie takie pliki muszą znajdować się w katalogu /_work/Data/Music.

Formaty plików

Katalog Music zawiera następujące typy plików:

  • .dls - Plik formatu Downloadable Sound. Jest bazą dla wszystkich innych plików. Zawiera:

    • Kolekcje wirtualnych instrumentów muzycznych.
    • Pliki .wav używane przez instrumenty.
  • .sty - Plik stylu. Zawiera:

    • Zespoły (Bands) - ustawienia instrumentów wirtualnych z .dls.
    • Wzory (Patterns) - fragmenty utworów, które można później łączyć, zapętlać i nakładać na siebie.
  • .sgt - Plik z odpowiednio połączonymi wzorami (patternami) - końcowy utwór

Alternatywny System Muzyczny

Plugin zBassMusic zastępuje domyślną bibliotekę muzyczną Zengina, dużo nowszą biblioteką BASS. Umożliwia to między innymi odtwarzanie muzyki w takich formatach jak .mp3 lub .ogg, oraz pakownie utworów do archiwów .vdf i .mod.

\ No newline at end of file diff --git a/pl/zengin/scripts/classes/c_info/index.html b/pl/zengin/scripts/classes/c_info/index.html deleted file mode 100644 index a81cbea26b..0000000000 --- a/pl/zengin/scripts/classes/c_info/index.html +++ /dev/null @@ -1,228 +0,0 @@ - C_INFO - Gothic Modding Community

C_INFO Daedalus class

Acknowledgment

Heavily inspired by the amazing documentation site Gothic library.

The C_INFO class is used to define dialogues in the game.

Class definition

Class definition as it is defined in Scripts/Content/_intern/Classes.d script file.

C_Info Daedalus class
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
class C_Info
-{
-    var int    npc;         // npc instance has the dialogue
-    var int    nr;          // number of the dialogue (for sorting)
-    var int    important;   // should the npc start the dialogue automatically
-    var func   condition;   // condition function
-    var func   information; // function called on selecting the dialogue
-    var string description; // text in the dialogue box
-    var int    trade;       // should the dialogue show the trade window
-    var int    permanent;   // should the dialogue be permanent or only one time deal
-};
-

Class members

Variable Type Description
npc int npc instance to have the dialogue
nr int dialogue order number
important int npc addresses player automatically
condition func condition function whether the dialogue is shown or not
information func function called on dialogue selection - contains the dialogue lines and other logic
description string text shown in the dialogue box
trade int is it a trade dialogue
permanent int does the dialogue stay after being played once

Class member overview

Description of the class member variables.

npc

Sets what NPC will have this dialogue instance. Set an NPC instance.

1
-2
-3
-4
-5
instance Info_Diego_Gamestart (C_INFO)
-{
-    npc    = PC_Thief; // NPC instance for Diego
-    // ...
-};
-

nr

The nr member variables determines the order of shown dialogues. Dialogues are ordered in the ascending order - instances with higher nr are below instances with lower nr.

1
-2
-3
-4
-5
-6
instance Info_Diego_Gamestart (C_INFO)
-{
-    // ...
-    nr = 1;
-    // ...
-};
-

Note

This is why the end dialogues usually have nr = 999; this is the highest number out of any dialogues therefore will always show up at the bottom. (999 is not the highest number the nr can store, it is just considered the highest number, as there will hardly be 998 dialogue instances for a single character)

important

The important member variable determines whether the NPC will automatically address the player or not.

  • important = TRUE - the NPC will address the player
  • important = FALSE - the player has to talk to the NPC

When important is set to TRUE, the description is not needed since the dialogue is never shown in the dialogue box.

Info

If there are multiple important dialogues that satisfy their condition function, they will be played in the order specified by nr.

Tip

important variable is of the type integer, and it is initialized by the engine to the value of 0. If you do not want your dialogue to be important, you can omit the important member variable since it will be initialized to 0 by the engine.

condition

Condition function with signature func int f(). If the function returns TRUE the dialogue is displayed, if it returns FALSE it is not displayed. The function name does not have to follow a particular naming convention, but a naming convention is used throughout all the Gothic scripts: {DialogueName}_Condition.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
instance Info_Diego_Gamestart (C_INFO)
-{
-    // ...
-    condition = Info_Diego_Gamestart_Condition;
-    // ...
-};
-
-func int Info_Diego_Gamestart_Condition()
-{
-    if (Kapitel < 2) // Show only when chapter is less than 2
-    {
-        return TRUE;
-    };
-    return FALSE; // Not needed, but added for readability
-};
-
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
instance Info_Diego_EXIT_Gamestart(C_INFO)
-{
-    // ...
-    condition = Info_Diego_EXIT_Gamestart_Condition;
-    // ...
-};
-
-func int Info_Diego_EXIT_Gamestart_Condition()
-{
-    return TRUE; // or return 1;
-};
-

Tip

It is unnecessary to return FALSE from dialogue conditions, but in other cases it can very rarely cause subtle bugs. It is thus good practice to always return some value, even if that is FALSE.

information

The information function contains the function name (without double quotes "" as func is a type in Daedalus) that is called when the dialogue option is selected. It contains the lines NPCs will say, items that will be transferred, quests related logic and much more. The function name does not have to follow a particular naming convention, but a naming convention is used throughout all the Gothic scripts: {DialogueName}_Info.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
instance Info_Diego_Gamestart (C_INFO)
-{
-    npc         = PC_Thief;
-    nr          = 1;
-    condition   = Info_Diego_Gamestart_Condition;
-    information = Info_Diego_Gamestart_Info;
-    permanent   = FALSE;
-    important   = TRUE;
-};
-
-func int Info_Diego_Gamestart_Condition()
-{
-    if (Kapitel < 2)
-    {
-        return TRUE;
-    };
-    return FALSE;
-};
-
-func void Info_Diego_Gamestart_Info()
-{
-    AI_Output(self,hero,"Info_Diego_Gamestart_11_00"); //I'm Diego.
-    AI_Output(hero,self,"Info_Diego_Gamestart_15_01"); //I'm...
-    AI_Output(self,hero,"Info_Diego_Gamestart_11_02"); //I'm not interested in who you are. You've just arrived. I look after the new arrivals. That's all for now.
-    AI_Output(self,hero,"Info_Diego_Gamestart_11_03"); //If you plan to stay alive for a while, you should talk to me. But of course I won't keep you from choosing your own destruction. Well, what do you think?
-
-    B_Kapitelwechsel(1); // Show the chapter 1 screen
-};
-

description

Specify a string that will be shown in the dialogue window.

1
-2
-3
-4
-5
instance DIA_XARDAS_GMC(C_INFO)
-{
-    // ...
-    description = "Hello, is this the GMC site?";
-};
-

Description

trade

If trade is set to TRUE the trading interface will be launched after the content information function is finished.

Fisk's trade dialogue
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
instance  Stt_311_Fisk_Trade (C_INFO)
-{
-    npc         = Stt_311_Fisk;
-    nr          = 800;
-    condition   = Stt_311_Fisk_Trade_Condition;
-    information = Stt_311_Fisk_Trade_Info;
-    permanent   = TRUE;
-    description = "Show me your goods.";
-    trade       = TRUE;
-};
-
-func int  Stt_311_Fisk_Trade_Condition()
-{
-    return TRUE;
-};
-
-func void  Stt_311_Fisk_Trade_Info()
-{
-    AI_Output (other, self, "Stt_311_Fisk_Trade_15_00"); //Show me your goods.
-};
-

Trivia

Trade manager has been added to ZenGin not that long before the release of Gothic 1 (as discussed and discovered on Phoenix the Game Discord server with the acquisition of Gothic version 0.94k). In version 0.94 the trade manager worked quite differently and used a special (nowadays unused) Daedalus class C_ItemReact.

permanent

Dialogues with permanent = TRUE do not disappear after the dialogue is played. This is used for dialogues where you ask for directions or flavor dialogues for unnamed NPCs.

Bug

Frequently used external function Npc_KnowsInfo which returns true if the dialogue instance has been played has had a bug in the implementation for a long time. This bug made it impossible to use this function with dialogue instances with permanent = TRUE as it would always return FALSE. This has been fixed in Union 1.0m.

LeGo

LeGo implements a lot of useful functions for dialogues. It makes it possible to create Trialogues and change NPCs behaviour by Dialoggestures. Moreover, any Daedalus function can be added to NPCs AI queue via the AI_Function package.

zParserExtender

zParserExtender implements some Quality of Life features for dialogues. More information can be found in Dialogue constants article.

AF Script Packet

Enhanced Info Manager (implemented using Ikarus and LeGo) adds tons of customizations and additional features to dialogues. More information can be found in the AFSP Enhanced Information Manager article.

\ No newline at end of file diff --git a/pl/zengin/scripts/classes/c_item/index.html b/pl/zengin/scripts/classes/c_item/index.html deleted file mode 100644 index d6e45218a1..0000000000 --- a/pl/zengin/scripts/classes/c_item/index.html +++ /dev/null @@ -1,369 +0,0 @@ - C_ITEM - Gothic Modding Community

C_ITEM Daedalus class

Acknowledgment

Heavily inspired by the amazing documentation site Gothic library

The C_ITEM class is used to define new items in the game.

Class definition

Class definition as it is defined in Scripts/Content/_intern/Classes.d script file.

C_Item Daedalus class
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
-37
-38
-39
-40
-41
-42
-43
-44
-45
-46
-47
-48
-49
-50
-51
-52
-53
-54
-55
-56
-57
-58
-59
-60
-61
-62
-63
-64
-65
-66
-67
-68
-69
-70
-71
-72
-73
-74
class C_Item
-{
-    // For all Items
-    var int    id;                         // ID of the item
-    var string name;                       // Name of the item
-    var string nameID;                     // Name ID
-    var int    hp;                         // Current health of the item
-    var int    hp_max;                     // Maximum health of the item
-
-    var int    mainflag;                   // Item category flag
-    var int    flags;                      // Item type flag
-    var int    weight;                     // Weight of the item
-    var int    value;                      // Value of the item
-
-    // For weapons
-    var int    damageType;                 // Damage type
-    var int    damageTotal;                // Total amount of damage
-    var int    damage[DAM_INDEX_MAX];      // Array of damage types
-
-    // For armours
-    var int    wear;                       // Flag to specify where to wear an item
-    var int    protection[PROT_INDEX_MAX]; // Protection array of different damage types
-
-    // For food
-    var int    nutrition;                  // The amount of HP healed
-
-    // Benötigte Attribute zum Benutzen des Items
-    var int    cond_atr[3];                // Array of NPC attributes needed to equip the item
-    var int    cond_value[3];              // Array of values corresponding to the cond_atr array
-
-    // Attributes to be changed on equip
-    var int    change_atr[3];              // Array of attributes that will be changed on equip
-    var int    change_value[3];            // Array of values of the attributes defined in change_atr
-
-    // Parser functions
-    var func   magic;
-    var func   on_equip;                   // Called on equpping an item
-    var func   on_unequip;                 // Called on unequipping an item
-    var func   on_state[4];
-
-    var func   owner;                      // Owner of the item: instance name
-    var int    ownerGuild;                 // Owner of the item: guild
-    var int    disguiseGuild;              // NPC guild set when equipping an item
-
-    // 3DS model file
-    var string visual;                     // Item model file
-
-    // NPC mesh change, when equipping an item
-    var string visual_change;              // .asc file
-    var string effect;                     // Effect instance
-
-    var int    visual_skin;                // Texture variation
-
-    var string scemeName;                  // Animation sceme name
-    var int    material;                   // Material of the object
-
-    var int    munition;                   // Ammo instance
-
-    var int    spell;                      // ID if the spell that this item does
-    var int    range;                      // Range of the weapon
-
-    var int    mag_circle;                 // Circle of magic needed to use this item
-
-    var string description;                // The name of the item shown in the preview box
-    var string text[ITM_TEXT_MAX];         // Array of string describing the item (left side)
-    var int    count[ITM_TEXT_MAX];        // Array of integers (the right side)
-
-    // Parameters for displaying items in the inventory
-    var int    inv_zbias                   // How far away is the item from the screen
-    var int    inv_rotx                    // X-axis rotation
-    var int    inv_roty                    // Y-axis rotation
-    var int    inv_rotz                    // Z-axis rotation
-    var int    inv_animate                 // Should the item rotate in the inventory
-};
-

It has many member variables but not all of them are used for every item. It is not necessary to define every one of these variables for every item as it was discussed on InsideGothic.

Class members

A selection of the most important class members.

change_atr & change_value

change_atr stores the attributes that will be changed by the amount specified in change_value.

NPCs have these attributes:

1
-2
-3
-4
-5
-6
-7
-8
-9
const int ATR_HITPOINTS      =  0;  // Hit points
-const int ATR_HITPOINTS_MAX  =  1;  // Max hitpoints
-const int ATR_MANA           =  2;  // Mana
-const int ATR_MANA_MAX       =  3;  // Max mana
-
-const int ATR_STRENGTH       =  4;  // Strength
-const int ATR_DEXTERITY      =  5;  // Dexterity
-const int ATR_REGENERATEHP   =  6;  // HP regeneration per second
-const int ATR_REGENERATEMANA =  7;  // Mana regeneration per second
-

This can be used on all equipable items to change the attributes. As an example we can create a sword that has a 10 point dexterity bonus.

1
-2
-3
-4
-5
-6
-7
instance ItMw_testSword (C_Item)
-{
-    // some code
-    change_atr[0]   = ATR_DEXTERITY;
-    change_value[0] = 10;
-    // some code
-};
-

Warning

Do not change ATR_HITPOINTS, ATR_MANA, ATR_HITPOINTS_MAX or ATR_MANA_MAX as it will result in unwanted behaviour with max health or max mana.

You can change ATR_HITPOINTS_MAX and ATR_MANA_MAX attributes in on_equip and on_unequip

cond_atr & cond_value

cond_atr stores the attributes that will be checked as a requirement to equip an item, the amount specified in cond_value.

The next example sword is equipable only if the NPC has at least 5 strength. If the requirements are not met G_CanNotUse() is called.

1
-2
-3
-4
-5
-6
-7
instance ItMw_testSword (C_Item)
-{
-    // some code
-    cond_atr[2]     = ATR_STRENGTH;
-    cond_value[2]   = 5;
-    // some code
-};
-

Try injecting the code below zParserExtender to test it in game right away. It is compatible with G2NotR.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
instance ItMw_testSword (C_Item)
-{
-    name            = TXT_Spells[10]; // demonstrates the usage of direct constr array access
-
-    mainflag        = ITEM_KAT_NF;
-    flags           = ITEM_SWD;
-    material        = MAT_METAL;
-
-    value           = 10;
-
-    damageTotal     = 10;
-    damagetype      = DAM_EDGE;
-    range           = 100;
-
-    cond_atr[2]     = ATR_STRENGTH;
-    cond_value[2]   = 5;
-
-    change_atr[0]   = ATR_DEXTERITY;
-    change_value[0] = 10;
-
-    visual          = "ItMw_010_1h_Sword_short_01.3DS";
-
-    description     = name;
-
-    TEXT[2]         = NAME_Damage;      COUNT[2] = damageTotal;
-    TEXT[3]         = NAME_Str_needed;  COUNT[3] = cond_value[2];
-    TEXT[4]         = NAME_OneHanded;
-    TEXT[5]         = NAME_Value;       COUNT[5] = value;
-};
-
To insert it into the game use insert ItMw_testSword in console.

text & count arrays

These two arrays are used to put information into the item information box. Text and Count The maximum number of lines is 6. This is defined in the engine, but for script side class definition is declared in the scripts too.

const int ITM_TEXT_MAX = 6;
-
This example shows an item with all elements of TEXT and COUNT array filled.

Note

Please notice the last COUNT element. It did not take the value we entered, but shows 10 which is the value of the item. This behaviour can be changed with Ikarus or Union.

Item example

You can find the code below

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
instance ItMw_testSword (C_Item)
-{
-    name          = TXT_Spells[10];
-
-    mainflag      = ITEM_KAT_NF;
-    flags         = ITEM_SWD;
-    material      = MAT_METAL;
-
-    value         = 10;
-
-    damageTotal   = 10;
-    damagetype    = DAM_EDGE;
-    range         = 100;
-
-    cond_atr[2]   = ATR_STRENGTH;
-    cond_value[2] = 5;
-
-    change_atr[0] = ATR_DEXTERITY;
-    change_value[0] = 10;
-
-    visual        = "ItMw_010_1h_Sword_short_01.3DS";
-
-    description   = name;
-
-    TEXT[0]       = "Line 0";     COUNT[0]      = 0; 
-    TEXT[1]       = "Line 1";     COUNT[1]      = 1; 
-    TEXT[2]       = "Line 2";     COUNT[2]      = 2; 
-    TEXT[3]       = "Line 3";     COUNT[3]      = 3; 
-    TEXT[4]       = "Line 4";     COUNT[4]      = 34;
-    TEXT[5]       = "Line 5";     COUNT[5]      = 35;
-};
-

description & name

description - determines the name of the item in the inventory

name - determines the focus name of the item in the world

In the scripts you often find that the description is assigned the value of name.

1
-2
-3
-4
-5
-6
-7
instance ItMw_testSword (C_Item)
-{
-    name = "New amazing sword";
-    // ...
-    description   = name; // description now has the same value as '    // ...name'
-    // ...
-};
-
This is used in the case where you want to show the name of the item on focus too.

There is a second way used in the scripts though with, for example,magic scrolls - the focus name in the world is "Scroll" and in inventory the scroll carries the name of the spell. This is how it is done:

1
-2
-3
-4
-5
-6
-7
instance ItSc_InstantFireball (C_Item)
-{
-    name                 =    NAME_Spruchrolle; // const string = "Scroll"
-    // ...
-    description            =     NAME_SPL_InstantFireball; // const string = "Fireball"
-    // ...
-};
-

hp & hp_max

Both of these parameters are unused.

Trivia

In alpha ZenGin versions the player was able to destroy objects. This feature was abandoned during the course of the development.
This video shows the reconstruction of this feature.

\ No newline at end of file diff --git a/pl/zengin/scripts/classes/c_menu/index.html b/pl/zengin/scripts/classes/c_menu/index.html deleted file mode 100644 index 3a58bef7c9..0000000000 --- a/pl/zengin/scripts/classes/c_menu/index.html +++ /dev/null @@ -1,157 +0,0 @@ - C_MENU - Gothic Modding Community

C_MENU Daedalus class

Acknowledgment

Heavily inspired by the amazing documentation site Gothic library

Class C_Menu is responsible for the behavior and properties of the game menus (options, save etc.).

Class definition

Class definition as it is defined in Scripts/System/_intern/Menu.d script file.

C_Menu Daedalus class
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
class C_Menu 
-{
-    var     string  backPic;            // Menu background image
-    var     string  backWorld;          // Background ZEN-world of the game menu (Not used)
-    var     int     posx;               // The top left point of the menu on the screen horizontally (X-axis)
-    var     int     posy;               // The top left point of the menu on the screen vertically (Y-axis)
-    var     int     dimx;               // Menu width in virtual coordinates
-    var     int     dimy;               // Menu height in virtual coordinates
-    var     int     alpha;              // Menu transparency
-    var     string  musicTheme;         // Music track of the menu
-    var     int     eventTimerMSec;     // trigger time for the event EVENT_TIMER
-    var     string  items[150];         // Menu items
-    var     int     flags;              // Menu flags
-    var     int     defaultOutGame;     // Menu item highlighted by default when the game is not running
-    var     int     defaultInGame;      // Menu item highlighted by default when the game is running
-};
-

Class members

Variable Type Description
backPic string Menu background image
backWorld string Background ZEN-world of the game menu (Not used)
posx int The top left point of the menu on the screen horizontally (X-axis)
posy int The top left point of the menu on the screen vertically (Y-axis)
dimx int Menu width in virtual coordinates
dimy int Menu height in virtual coordinates
alpha int Menu transparency
musicTheme string Music track of the menu
eventTimerMSec int The timer that triggered the event in seconds
items string Menu items
flags int Menu flags
defaultOutGame int Menu item highlighted by default when the game is not running
defaultInGame int Menu item highlighted by default when the game is running

Class member overview

Description of the class member variables.

backPic

backPic is just a name of background image of the menu in .tga format.

backWorld

Deprecated setting

The background world of the game menu in .ZEN format.

posx

The horizontal position of the top left point of the menu on the screen, in virtual coordinates.

posy

The vertical position of the top left point of the menu on the screen, in virtual coordinates.

dimx

Menu width in virtual coordinates.

dimy

Menu height in virtual coordinates.

alpha

Menu transparency. Accepts values ​​from 0 to 255. Without the backPic property specified, the value of this parameter is ignored.

Note

Texture transparency can only be adjusted if the texture has an alpha channel.

musicTheme

Music theme of the menu.

1
-2
-3
-4
-5
-6
instance MENU_MAIN(C_MENU_DEF)
-{
-    ...
-    musictheme = "SYS_Menu";
-    ...
-};
-
All instances of musical themes are stored in a file Scripts/System/Music/MusicInst.d

eventTimerMSec

Defines the trigger time for the event EVENT_TIMER in seconds.

The list of constants for all menu events is described in the file Scripts/System/_intern/Menu.d

1
-2
-3
-4
-5
-6
-7
-8
-9
const int EVENT_UNDEF       = 0;    // Undefined
-const int EVENT_EXECUTE     = 1;    // Process start event
-const int EVENT_CHANGED     = 2;    // Menu parameter change event
-const int EVENT_LEAVE       = 3;    // Menu item focus loss event
-const int EVENT_TIMER       = 4;    // Timer fire event
-const int EVENT_CLOSE       = 5;    // Menu close event
-const int EVENT_INIT        = 6;    // Initialization event
-const int EVENT_SEL_PREV    = 7;    // Select event of the previous menu item
-const int EVENT_SEL_NEXT    = 8;    // Select event of the next menu item
-

items

An array of items belonging to this menu. It is possible to use up to 150 items in one menu. The same elements can be used for different menus. The element instance is specified as the value.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
// Menu
-instance MENU_MAIN(C_MENU_DEF)
-{
-    ...
-    items[0]        = "MENUITEM_MAIN_HEADLINE";         
-    items[1]        = "MENUITEM_MAIN_HEADLINE2";
-    items[2]        = "MENUITEM_MAIN_NEWGAME";
-    ...
-};
-
-// Menu elements: labels, checkboxes, sliders, etc.
-
-instance MENUITEM_MAIN_HEADLINE(C_MENU_ITEM_DEF)
-{
-    ...
-};
-
-instance MENUITEM_MAIN_HEADLINE2(C_MENU_ITEM_DEF)
-{
-    ...
-};
-
-instance MENUITEM_MAIN_NEWGAME(C_MENU_ITEM_DEF)
-{
-    ...
-};
-

flags

Menu flags.

The list of flag constants can be found in the file Scripts/System/_intern/Menu.d

1
-2
-3
-4
-5
-6
-7
const int MENU_OVERTOP          = 1;    // Show menu over previous menu or in game
-const int MENU_EXCLUSIVE        = 2;    // Close all previous menus. Only the active menu is displayed
-const int MENU_NOANI            = 4;    // No animation
-const int MENU_DONTSCALE_DIM    = 8;    // Don't Scale Menu Sizes
-const int MENU_DONTSCALE_POS    = 16;   // Empty flag
-const int MENU_ALIGN_CENTER     = 32;   // Center Align Menu
-const int MENU_SHOW_INFO        = 64;   // Display information at the bottom of the description menu from menu items text[1]
-
  • MENU_OVERTOP - Flag to display the menu over the previous menu. It is not advisable to use with a transparent menu.
  • MENU_EXCLUSIVE - Hide all menus except the active one. When closed, the previous menu is restored.
  • MENU_NOANI - Animation of minimizing and maximizing windows. The game is mainly used for dialogue windows. You can't enable or disable the animation of dialog windows through scripts. This is done using the animatedWindows setting in the Gothic.ini file.
  • MENU_DONTSCALE_DIM - Scale the menu to fit 640x480 resolution.
  • MENU_DONTSCALE_POS - Empty flag. Not used.
  • MENU_ALIGN_CENTER - Align the menu to the center of the screen.
  • MENU_SHOW_INFO - Display information at the bottom of menu description from menu item text[1].

defaultOutGame

The menu item that is highlighted by default when the game is not running.

A value of -1 enables automatic selection of the first selectable element.

Items with the ~IT_SELECTABLE flag are not selected.

defaultInGame

Menu item highlighted by default when the game is running.

A value of -1 enables automatic selection of the first selectable element.

Items with the ~IT_SELECTABLE flag are not selected.

\ No newline at end of file diff --git a/pl/zengin/scripts/classes/c_musicsys_cfg/index.html b/pl/zengin/scripts/classes/c_musicsys_cfg/index.html deleted file mode 100644 index bccff61583..0000000000 --- a/pl/zengin/scripts/classes/c_musicsys_cfg/index.html +++ /dev/null @@ -1,51 +0,0 @@ - C_MUSICSYS_CFG - Gothic Modding Community

C_MUSICSYS_CFG Daedalus class

Acknowledgment

Heavily inspired by the amazing documentation site Gothic library

Class C_MusicSys_CFG defines the global settings for the game's music.

An instance of this class is declared only once.

Class definition

Class definition as it is defined in Scripts/System/_intern/Music.d script file.

C_MusicSys_CFG Daedalus class
1
-2
-3
-4
-5
-6
-7
-8
-9
class C_MusicSys_CFG
-{
-    var float volume;               // Music volume
-    var int   bitResolution;        // Sound quality
-    var int   globalReverbEnabled;  // Enable global reverb
-    var int   sampleRate;           // Frequency
-    var int   numChannels;          // Sound channels
-    var int   reverbBufferSize;     // Reverb buffer size
-};
-

Class members

Variable Type Description
volume float Overall game music volume
bitResolution int Sound quality
globalReverbEnabled int Enable global reverb
sampleRate int Frequency
numChannels int Number of sound chanells
reverbBufferSize int The size of reverb buffer

Class member overview

Description of the class member variables.

volume

The overall volume of the background music (soundtrack). From 0.0 to 1.0.

bitResolution

Sound quality. 8 or 16 bit.

globalReverbEnabled

Enable global reverb.

sampleRate

Frequency. From 11050 to 44100.

numChannels

Number of sound channels. From 16 to 32.

reverbBufferSize

The size of the reverb buffer.

\ No newline at end of file diff --git a/pl/zengin/scripts/classes/c_musictheme/index.html b/pl/zengin/scripts/classes/c_musictheme/index.html deleted file mode 100644 index f9caf67d2e..0000000000 --- a/pl/zengin/scripts/classes/c_musictheme/index.html +++ /dev/null @@ -1,115 +0,0 @@ - C_MUSICTHEME - Gothic Modding Community

C_MUSICTHEME Daedalus class

Acknowledgment

Heavily inspired by the amazing documentation site Gothic library

Class C_MusicTheme describes musical themes.

Class definition

Class definition as it is defined in Scripts/System/_intern/Music.d script file.

C_MusicTheme Daedalus class
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
class C_MusicTheme
-{
-    var string      file;           // Sound file in DirectMusic `.sgt` format
-    var float       vol;            // Sound volume
-    var int         loop;           // Enable cycle
-    var float       reverbMix;      // Reverb mixing
-    var float       reverbTime;     // Reverb time
-    var int         transType;      // Type of transition to the next theme
-    var int         transSubType;   // Subtype of transition to the next theme song
-};
-

Class members

Variable Type Description
file string Sound file in DirectMusic .sgt format
vol float Sound volume
loop int Enable/disable cycle
reverbMix float Reverb mixing
reverbTime float Reverb time
transType int The type of transition to the next theme song
transSubType int The subtype of transition to the next theme song

Class member overview

Description of the class member variables.

file

DirectMusic sound in *.sgt format or MIDI file.

vol

The volume of the theme song. From 0.0 to 1.0.

loop

Enable/disable theme music looping. Disabled = 0. Enabled = 1.

reverbMix

Reverb mixing. Measured in decibels.

reverbTime

Reverberation time in milliseconds.

transType

The type of transition to the next theme song.

The list of constants for all transitions types is described in the file Scripts/System/_intern/Music.d

1
-2
-3
-4
-5
-6
-7
const int TRANSITION_TYPE_NONE          = 1;    // No transition
-const int TRANSITION_TYPE_GROOVE        = 2;    // Ripple
-const int TRANSITION_TYPE_FILL          = 3;    // Padding
-const int TRANSITION_TYPE_BREAK         = 4;    // Break
-const int TRANSITION_TYPE_INTRO         = 5;    // Introductory
-const int TRANSITION_TYPE_END           = 6;    // End topic
-const int TRANSITION_TYPE_ENDANDINTRO   = 7;    // End and start new
-

transSubType

The subtype of transition to the next theme song.

The list of constants for all transitions subtypes is described in the file Scripts/System/_intern/Music.d

1
-2
-3
const INT TRANSITION_SUB_TYPE_IMMEDIATE = 1;    // Instant transition
-const INT TRANSITION_SUB_TYPE_BEAT      = 2;    // Rhythmic transition
-const INT TRANSITION_SUB_TYPE_MEASURE   = 3;    // Gradual transition
-

Name features

The musical themes of the game are played depending on the game situation. By default, the theme with the _STD (standard) suffix is played. In case of a threat, the _THR (threat) theme will be played. During the combat the _FGT (fight) theme plays.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
instance WOO_DAY_STD(C_MUSICTHEME_STANDARD)
-{
-    file = "woo_daystd.sgt";
-};
-
-instance WOO_DAY_THR(C_MUSICTHEME_THREAT)
-{
-    file = "woo_daythr.sgt";
-};
-
-instance WOO_DAY_FGT(C_MUSICTHEME_FIGHT)
-{
-    file = "woo_dayfgt.sgt";
-};
-
In addition, the suffix _DAY_ and _NGT_ determines whether the theme should be played on day or night.
1
-2
-3
-4
-5
-6
-7
-8
-9
instance OWD_DAY_FGT(C_MUSICTHEME_FIGHT)
-{
-    file = "owp_dayfgt.sgt";
-};
-
-instance OWD_NGT_STD(C_MUSICTHEME_STANDARD)
-{
-    file = "owd_daystd.sgt";
-};
-

Tip

In G2 the C_MUSICTHEME_STANDARD, C_MUSICTHEME_THREAT and C_MUSICTHEME_FIGHT prototypes are used by default.

\ No newline at end of file diff --git a/pl/zengin/scripts/classes/c_svm/index.html b/pl/zengin/scripts/classes/c_svm/index.html deleted file mode 100644 index 8f253ad606..0000000000 --- a/pl/zengin/scripts/classes/c_svm/index.html +++ /dev/null @@ -1,77 +0,0 @@ - C_SVM - Gothic Modding Community

C_SVM Daedalus class

Acknowledgment

Heavily inspired by the amazing documentation site Gothic library

The C_SVM class is used to define sound dialogues (smalltalk, reactions) that are defined for every C_NPC.voice.

Class definition

C_SVM class is the only class with variable number of members. The C_SVM definition in the scripts dictates the content of the class. Every Gothic game has a different number of SVM entries. As an interesting information (more than anything else) we include a table with the numbers of voice lines and voices below.

Game voice lines voices
Gothic 1 136 17
Gothic Sequel 110 17 (30 planned)
Gothic 2 202 19
Gothic 2 Addon 235 19
Chronicles of Myrtana 1346 73
Returning New Balance 495 19

Rules

The number of instances is defined by a constant integer with a specified name read by the engine.

const int SVM_MODULES = 18;
-

Info

The value SVM_MODULES = 18 means 18 SVMs will be parsed by the engine and because the first one, SVM_0, is empty, the final number of voices is 18 - 1 = 17.

Instances of the C_SVM class must have the name SVM_XXX.

1
-2
-3
-4
instance svm_1(c_svm)
-{
-    // ...
-};
-
The first instance svm_0 is always empty, it is used internally by the engine.
instance svm_0(c_svm) {};
-

Usage in the scripts

While some defined SVMs are used automatically by the engine - the 20 smalltalk lines for example, others are used in the scripts.
To instruct the engine to run a specific SVM, external function AI_OutputSVM is used. In the original scripts it is wrapped in a script function B_Say.
To reference the SVM, you use the $ symbol followed by the name of the member variable in the C_SVM class definition.

1
-2
-3
-4
-5
-6
// some code
-    {
-        PrintScreen    ("Not enough skill points!", -1,-1,"FONT_OLD_20_WHITE.TGA",1);
-        B_Say (self, other, "$NOLEARNNOPOINTS");
-    };
-// some code
-
Here the $NOLEARNNOPOINTS references the var string NoLearnNoPoints in SVM.D. The voice is then chosen automatically by the engine.
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
class C_SVM
-{
-    //...
-
-    // Teacher comments
-    var string NoLearnNoPoints;       // NPC teacher doesn't teach - not enough learning points!
-    var string NoLearnOverMax;        // NPC teacher doesn't teach - cannot teach above 100 points!
-    var string NoLearnYouAlreadyKnow; // You have to know something to become a master!
-    var string NoLearnYoureBetter;    // You are better than the teacher!
-
-    //...
-};
-
\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/afsp/afsp_eim/index.html b/pl/zengin/scripts/extenders/afsp/afsp_eim/index.html deleted file mode 100644 index 7becaed827..0000000000 --- a/pl/zengin/scripts/extenders/afsp/afsp_eim/index.html +++ /dev/null @@ -1,469 +0,0 @@ - Enhanced Info Manager - Gothic Modding Community

Enhanced Information Manager

Warning

This is a quick paste-in of and old version of AFSP's documentation and the information should be taken with a grain of salt. It may not be up-to-date since AFSP is being developed all the time and this is only a demo page.

Enhanced Information Manager allows you to more precisely control the Information Manager (dialogue manager). Change color, font and much more! This package "scans" the dialogue string for modifiers and alters the string based on the modifiers you specify.

Initialization

To use this feature you have to:

  1. Add _headers_G[1/2]_EnhancedInfoManager.src or _headers_G[1/2]_All.src to your Gothic.src after Ikarus and LeGo initialization.
  2. Call G12_EnhancedInfoManager_Init(); from your INIT_GLOBAL() function in Startup.d

Change colour

Set font color for a dialogue choice.

h@[hex color value]
-
Set font color for highlighted dialogue choice.
hs@[hex color value]
-
Example
description = "h@2a85a3 hs@2ea9d1 This dialogue is blue.";
-

Change font

Set font itself for a dialogue choice.

f@[font name]
-
Set font itself for highlighted dialogue choice.
fs@[font name]
-
Example
description = "f@font_old_20_white.tga fs@font_old_10_white.tga This dialogue has a different font, when selected.";
-

Change text alignment

Align text left.

al@
-
Align text center.
ac@
-
Align text right.
ar@
-
Example
1
-2
-3
description = "al@ This dialogue has LEFT alignment.";
-description = "ac@ This dialogue has CENTER alignment.";
-description = "ar@ This dialogue has RIGHT alignment.";
-

Disable dialogue

Player cannot highlight (and select) this dialogue.

d@
-

Text input field

Input field allows you to turn a dialogue choice into an input text field.

a@
-
Example
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
INSTANCE DIA_Xardas_Password (C_Info)
-{
-    npc         = NONE_100_Xardas;
-    nr          = 1;
-    condition   = DIA_Xardas_Password_Condition;
-    information = DIA_Xardas_Password_Info;
-    permanent   = FALSE;
-    description = "a@ What is the password to get to the Mages of Water?";
-};
-
-FUNC INT DIA_Xardas_Password_Condition () {
-    return TRUE;
-};
-
-FUNC VOID DIA_Xardas_Password_Info () {
-    if (Hlp_StrCmp (InfoManagerAnswer, "TETRIANDOCH"))
-    {
-        PrintScreen ("Yes that is correct!", -1, -1, "font_old_10_white.tga", 3);
-    }
-    else
-    {
-        PrintScreen ("No that is wrong!", -1, -1, "font_old_10_white.tga", 3);
-    };
-};
-

Dialogue numbers

This feature shows a dialogue number next to the dialogue line (visual for Dialogue keyboard controls). To turn this on you just set InfoManagerNumKeysNumbers variable to true. (in your INIT_GLOBAL() function).

InfoManagerNumKeysNumbers = TRUE;
-

Dialogue keyboard controls

Note

This has also been fixed in Union and we noticed a strange behavior with different keyboard layouts.

This feature changes the way number keys affect dialogue selection. The first dialogue is no longer 0 and you highlight the dialogue option by pressing appropriate number.

InfoManagerNumKeysControls = TRUE;
-

Spinners

This is by far the most flashy feature of EIM as it allows you to use left/right arrow keys on a dialogue option to increase/decease numerical value. This can be used in many ways.

This feature is a bit more complex:

  1. Set up a standard dialogue

    Notice

    Notice we are using "dummy" as a description, since it is going to get updated. If something goes wrong the "dummy" string shows up and you can clearly tell something went wrong.

    1
    -2
    -3
    -4
    -5
    -6
    -7
    -8
    INSTANCE PC_Pan_Cook_Meat (C_Info)
    -{
    -    nr           = 1;
    -    condition    = PC_Pan_Cook_Meat_Condition;
    -    information  = PC_Pan_Cook_Meat_Info;
    -    permanent    = TRUE;
    -    description  = "dummy"; //Description is updated in PC_Pan_Cook_Meat_Condition
    -};
    -
  2. Most of the magic takes place in the condition function (apart from the code behind the scenes, of course).

     1
    - 2
    - 3
    - 4
    - 5
    - 6
    - 7
    - 8
    - 9
    -10
    -11
    -12
    -13
    -14
    -15
    -16
    -17
    -18
    -19
    -20
    -21
    -22
    -23
    -24
    -25
    -26
    -27
    -28
    -29
    -30
    -31
    -32
    -33
    -34
    -35
    -36
    -37
    -38
    -39
    -40
    -41
    -42
    -43
    -44
    -45
    -46
    -47
    -48
    -49
    -50
    -51
    -52
    var int selectedMeat; // global variable for this spinner value
    -
    -FUNC INT PC_Pan_Cook_Meat_Condition ()
    -{
    -    if (PLAYER_MOBSI_PRODUCTION == MOBSI_DIALOG_PAN)
    -    {
    -        var string lastSpinnerID;
    -
    -        var int total; total = NPC_HasItems (self, ItFoMuttonRaw);
    -
    -        if (selectedMeat == 0) { selectedMeat = 1; }; //Default initial value
    -
    -        //Check currently selected spinned ID --> is it this one?
    -        if (Hlp_StrCmp (InfoManagerSpinnerID, "CookMeat"))
    -        {
    -            //Setup spinner if spinner ID has changed
    -            if (!Hlp_StrCmp (InfoManagerSpinnerID, lastSpinnerID))
    -            {
    -                //Restore previous value
    -                InfoManagerSpinnerValue = selectedMeat;
    -            };
    -
    -            //Page Up/Down quantity
    -            InfoManagerSpinnerPageSize = 5;
    -
    -            //Min/Max value (Home/End keys)
    -            InfoManagerSpinnerValueMin = 1;
    -            InfoManagerSpinnerValueMax = total;
    -
    -            //Update number which is shown in description (in case it was changed by _HOOK_VIEWDIALOGCHOICE_HANDLEEVENT
    -            selectedMeat = InfoManagerSpinnerValue;
    -
    -        };
    -
    -        lastSpinnerID = InfoManagerSpinnerID; //Remember last active spinner ID
    -
    -        var string newDescription;
    -
    -        //Spinner ID 'CookMeat'
    -        newDescription = "s@CookMeat Cook some meat: ";
    -
    -        newDescription = ConcatStrings (newDescription, IntToString (selectedMeat));
    -        newDescription = ConcatStrings (newDescription, " / ");
    -        newDescription = ConcatStrings (newDescription, IntToString (total));
    -
    -        //Update description
    -        PC_Pan_Cook_Meat.description = newDescription;
    -        return TRUE;
    -    };
    -
    -    return FALSE;
    -};
    -
  3. We can use the spinner value stored in selectedMeat variable here in the info function to create the meat (or do other stuff with it).

     1
    - 2
    - 3
    - 4
    - 5
    - 6
    - 7
    - 8
    - 9
    -10
    -11
    -12
    -13
    -14
    -15
    -16
    -17
    -18
    FUNC VOID PC_Pan_Cook_Meat_Info () {
    -    //If we don't have any meat ... don't cook any :)
    -    if (!NPC_HasItems (self, ItFoMuttonRaw)) { return; };
    -
    -    //This should not happen - but you never know!
    -    if (selectedMeat < 1) { return; };
    -
    -    //This should not happen either! but just in case
    -    if (selectedMeat > (NPC_HasItems (self, ItFoMuttonRaw))) {
    -        selectedMeat = NPC_HasItems (self, ItFoMuttonRaw);
    -    };
    -
    -    NPC_RemoveInvItems (self, ItFoMuttonRaw, selectedMeat);
    -    CreateInvItems (self, ItFoMutton, selectedMeat);
    -
    -    //Reset value for next time
    -    selectedMeat = 1;
    -};
    -

Spinners: Full code example

Spinner example
  1
-  2
-  3
-  4
-  5
-  6
-  7
-  8
-  9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
-100
-101
-102
-103
-104
-105
-106
-107
-108
-109
INSTANCE PC_Pan_Cook_Meat (C_Info)
-{
-    nr           = 1;
-    condition    = PC_Pan_Cook_Meat_Condition;
-    information  = PC_Pan_Cook_Meat_Info;
-    permanent    = TRUE;
-    description  = "dummy"; //Description is updated in PC_Pan_Cook_Meat_Condition
-};
-
-var int selectedMeat;
-
-FUNC INT PC_Pan_Cook_Meat_Condition ()
-{
-    if (PLAYER_MOBSI_PRODUCTION == MOBSI_DIALOG_PAN)
-    {
-        var string lastSpinnerID;
-
-        var int total; total = NPC_HasItems (self, ItFoMuttonRaw);
-
-        if (selectedMeat == 0) { selectedMeat = 1; }; //Default initial value
-
-        //Check currently selected spinned ID --> is it this one?
-        if (Hlp_StrCmp (InfoManagerSpinnerID, "CookMeat"))
-        {
-            //Setup spinner if spinner ID has changed
-            if (!Hlp_StrCmp (InfoManagerSpinnerID, lastSpinnerID))
-            {
-                //Restore previous value
-                InfoManagerSpinnerValue = selectedMeat;
-            };
-
-            //Page Up/Down quantity
-            InfoManagerSpinnerPageSize = 5;
-
-            //Min/Max value (Home/End keys)
-            InfoManagerSpinnerValueMin = 1;
-            InfoManagerSpinnerValueMax = total;
-
-            //Update number which is shown in description (in case it was changed by _HOOK_VIEWDIALOGCHOICE_HANDLEEVENT
-            selectedMeat = InfoManagerSpinnerValue;
-        };
-
-        lastSpinnerID = InfoManagerSpinnerID; //Remember last active spinner ID
-
-        var string newDescription;
-
-        //Spinner ID 'CookMeat'
-        newDescription = "s@CookMeat Cook some meat: ";
-
-        newDescription = ConcatStrings (newDescription, IntToString (selectedMeat));
-        newDescription = ConcatStrings (newDescription, " / ");
-        newDescription = ConcatStrings (newDescription, IntToString (total));
-
-        //Update description
-        PC_Pan_Cook_Meat.description = newDescription;
-        return TRUE;
-    };
-
-    return FALSE;
-};
-
-FUNC VOID PC_Pan_Cook_Meat_Info ()
-{
-    //If we don't have any meat ... don't cook any :)
-    if (!NPC_HasItems (self, ItFoMuttonRaw)) { return; };
-
-    //This should not happen - but you never know!
-    if (selectedMeat < 1) { return; };
-
-    //This should not happen either! but just in case
-    if (selectedMeat > (NPC_HasItems (self, ItFoMuttonRaw)))
-    {
-        selectedMeat = NPC_HasItems (self, ItFoMuttonRaw);
-    };
-
-    NPC_RemoveInvItems (self, ItFoMuttonRaw, selectedMeat);
-    CreateInvItems (self, ItFoMutton, selectedMeat);
-
-    //Reset value for next time
-    InfoManagerSpinnerValue = 1;
-};
-
-INSTANCE PC_Pan_Cook_Meat_Exit (C_Info)
-{
-    nr          = 999;
-    condition   = PC_Pan_Cook_Meat_Exit_Condition;
-    information = PC_Pan_Cook_Meat_Exit_Info;
-    permanent   = TRUE;
-    description = "End";
-};
-
-FUNC INT PC_Pan_Cook_Meat_Exit_Condition ()
-{
-    if (PLAYER_MOBSI_PRODUCTION == MOBSI_DIALOG_PAN)
-    {
-        return TRUE;
-    };
-    return FALSE;
-};
-
-FUNC VOID PC_Pan_Cook_Meat_Exit_Info ()
-{
-    if (PLAYER_MOBSI_PRODUCTION != MOBSI_DIALOG_NONE)
-    {
-        PLAYER_MOBSI_PRODUCTION = MOBSI_DIALOG_NONE;
-        hero.aivar[AIV_INVINCIBLE] = FALSE;
-        AI_StopProcessInfos (hero);
-    };
-};
-
\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/afsp/index.html b/pl/zengin/scripts/extenders/afsp/index.html deleted file mode 100644 index 345017b3e2..0000000000 --- a/pl/zengin/scripts/extenders/afsp/index.html +++ /dev/null @@ -1,34 +0,0 @@ - AF Script Packet - Gothic Modding Community

AF Script Packet

Auronen & Fawkes' Script Packet is a script package built on top of Ikarus and LeGo. It implements many features and there is also a Union version which is in its infancy stage.

Note

AFSP's documentation is lacking (@Auronen: "My fault"). The authors will host the documentation on GMC.

Contacts
Authors Fawkes & Auronen
GitHub AFSP
Forum AFSP
\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/ikarus/constants/index.html b/pl/zengin/scripts/extenders/ikarus/constants/index.html deleted file mode 100644 index 877d915f82..0000000000 --- a/pl/zengin/scripts/extenders/ikarus/constants/index.html +++ /dev/null @@ -1,43 +0,0 @@ - Constants - Gothic Modding Community

Ikarus User Constants

In the Constants file, you'll find user variables that control various aspects, including the debug output of Ikarus. You can customize these variables to suit your needs.

MEM-Helper

  • const string MEM_FARFARAWAY
    Waypoint where the Mem-Helper is spawned (default: "TOT")
  • const string MEM_HELPER_NAME
    Name of the Mem-Helper (default: "MEMHLP")

Debug

  • const int zERR_ErrorBoxOnlyForFirst
    Controls whether only the first error should trigger an error box (default: 1).
  • const int zERR_StackTraceOnlyForFirst
    Determines if stack traces should be displayed only for the first error (default: 0).

MEM_Debug

The MEM_Debug function allows you to set up a custom message channel for debugging purposes. You can adjust the following variables to configure this channel:

  • const string zERR_DEBUG_PREFIX
    Specifies a prefix to be added to each debug message (default: "Debug: ").
  • const int zERR_DEBUG_TOSPY
    Controls whether MEM_Debug messages should be sent to zSpy (default: 1).
  • const int zERR_DEBUG_TYPE
    Specifies the message type for MEM_Debug messages when sent to zSpy (default: zERR_TYPE_INFO).
  • const int zERR_DEBUG_TOSCREEN
    Determines whether MEM_Debug messages should be printed to the screen (default: 0).
  • const int zERR_DEBUG_ERRORBOX
    Allows you to display an error box for MEM_Debug messages (default: 0).

Error message types

1
-2
-3
-4
-5
const int zERR_TYPE_OK    = 0; /* [ungenutzt]        */
-const int zERR_TYPE_INFO  = 1; /* MEM_Info           */
-const int zERR_TYPE_WARN  = 2; /* MEM_Warn           */
-const int zERR_TYPE_FAULT = 3; /* MEM_Error          */
-const int zERR_TYPE_FATAL = 4; /* [ungenutzt]        */
-
\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/ikarus/examples/index.html b/pl/zengin/scripts/extenders/ikarus/examples/index.html deleted file mode 100644 index 17421a4056..0000000000 --- a/pl/zengin/scripts/extenders/ikarus/examples/index.html +++ /dev/null @@ -1,371 +0,0 @@ - Examples - Gothic Modding Community

Ikarus examples

A collection of examples ported from the original Ikarus documentation.

Note

The original Ikarus documentation is a part of the code. You can find it in the GitHub repository.

Open focused chest or door

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
func void OpenFocussedChestOrDoor() 
-{
-    var oCNpc her; her = Hlp_GetNpc(hero);
-
-    // No focus vob at all?
-    if (!her.focus_vob) 
-    {
-        Print ("No focus!");
-        return;
-    };
-
-    // Focus vob not a lockable vob?
-    if (!Hlp_Is_oCMobLockable(her.focus_vob))
-    {
-        Print ("No chest or door in focus!");
-        return;
-    };
-
-    var oCMobLockable Lockable;
-    Lockable = MEM_PtrToInst (her.focus_vob);
-
-    if (Lockable.bitfield & oCMobLockable_bitfield_locked) 
-    {
-        Lockable.bitfield = Lockable.bitfield & ~ oCMobLockable_bitfield_locked;
-        Print (ConcatStrings ("Opened the following vob: ", Lockable._zCObject_objectName));
-    } 
-    else
-    {
-        Print (ConcatStrings ( Lockable._zCObject_objectName, "wasn't even complete!"));
-    };
-};
-
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
func void PrintCameraPos()
-{
-    // Initialize global instances (which only exist once):
-    // Initializes MEM_World, MEM_Game, etc. including MEM_Camera
-    MEM_InitGlobalInst();
-
-    /* The camera object is not a vob (but something abstract), 
-    do not know where and how there are position data.
-    I prefer to work on the camera vob : */
-    var zCVob camVob;
-    camVob = MEM_PtrToInst (MEM_Camera.connectedVob);
-
-    /* Here you have to know how the transformation matrix is structured:
-
-    It consists of three vectors, the x, y and z directions of the local coordinate system of the camera vob
-    in world coordinates (where z specifies the
-    line of sight). These vectors are
-    denoted by v1, v2, v3.
-    In addition, in the 4th column there is the translation,
-    that is, the position of the camera.
-
-    v1_x v2_x v3_x x
-    v1_y v2_y v3_y y
-    v1_z v3_z v3_z z
-    0 0 0 0
-
-    The matrix is stored row by row in memory.
-    Since we are interested in the last column are the indices
-    in the trafoWorld Array 3, 7 and 11 that we need. */
-
-    Print (ConcatStrings ("x: ",IntToString(roundf(camVob.trafoObjToWorld[3]))));
-    Print (ConcatStrings ("y: ",IntToString(roundf(camVob.trafoObjToWorld[7]))));
-    Print (ConcatStrings ("z: ",IntToString(roundf(camVob.trafoObjToWorld[11]))));
-};
-

Start rain

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
func void StartRain()
-{
-    // Initialize global instances
-    // This also includes Skycontroller
-    MEM_InitGlobalInst(); 
-
-    // start at the beginning of the day (12:00 noon)
-    MEM_SkyController.rainFX_timeStartRain = 0; // FLOATNULL constant
-    // end at the end of the day (12:00 noon of the next day)
-    MEM_SkyController.rainFX_timeStopRain = 1065353216; // FLOATONE constant
-
-    /* Note: The start and end times are floating point numbers.
-    * 0 stands for the beginning of the day 1 for the end of the day.
-    * a day in the game begins at 12:00 p.m.
-    * For the structure of the floating point format, google for IEEE-745.*/
-
-    /* Result: rain all day! (unless you are in a zone
-    * in which it snows, then snow all day) */
-};
-

Nested loop

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
-37
-38
-39
-40
-41
-42
-43
-44
-45
-46
-47
-48
// Should enumerate all pairs (x,y) with 0 <= x < max_x, 0 <= j < max_y
-
-func void printpairs(var int max_x, var int max_y)
-{
-    // Initialize labels
-    MEM_InitLabels();
-    // PrintDebug should be used, i.e. activate debug output
-    MEM_SetShowDebug (1);
-
-    var int x; var int y; x = 0;
-
-    // while (x < max_x)
-    var int x_loop; x_loop = MEM_StackPos.position;
-    if (x < max_x)
-    { 
-        y = 0;
-        // while (y < max_y) 
-        var int y_loop; y_loop = MEM_StackPos.position;
-        if (y < max_y)
-        { 
-            var string out; out = "(";
-            out = ConcatStrings (out, IntToString (x));
-            out = ConcatStrings (out, ", ");
-            out = ConcatStrings (out, IntToString (y));
-            out = ConcatStrings (out, ")");
-            PrintDebug (out);
-            y += 1;
-
-            // continue y_loop 
-            MEM_StackPos.position = y_loop;
-        };
-        x += 1;
-        // continue x_loop
-        MEM_StackPos.position = x_loop;
-    };
-};
-
-/*
-    Output of a call printpairs(4,2) would then be: 
-    00:36 Info: 5 U: Skript: (0, 0) .... 
-    00:36 Info: 5 U: Skript: (0, 1) .... 
-    00:36 Info: 5 U: Skript: (1, 0) .... 
-    00:36 Info: 5 U: Skript: (1, 1) .... 
-    00:36 Info: 5 U: Skript: (2, 0) .... 
-    00:36 Info: 5 U: Skript: (2, 1) .... 
-    00:36 Info: 5 U: Skript: (3, 0) .... 
-    00:36 Info: 5 U: Skript: (3, 1) .... 
-*/
-

Calling a function by their name

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
-37
-38
-39
// This example doesn't show why MEM_CallByString * is useful, but how to use the function.
-
-var zCVob someObject;
-func int MyFunction(var int param1, var string str1, var int param2, var string str2)
-{
-    Print (ConcatStrings (str1, str2)); //(*)
-    return 100 * param1 + param2;
-};
-
-func void foo()
-{ 
-    var int result;
-
-    // The following code is in this case equivalent to:
-    // result = MyFunction(42, "Hello", 23, "World!");
-
-    // Lay the call arguments on the call stack
-    MEM_PushIntParam (42);
-    MEM_PushStringParam ("Hello ");
-    MEM_PushIntParam (23);
-    MEM_PushStringParam ("World!");
-
-    MEM_CallByString ("MYFUNCTION");
-
-    // the function puts the result (of type int in this case) on the stack
-    // we pop the int result and save it to a variable
-    result = MEM_PopIntResult();
-
-    // print the result
-    Print (IntToString (result));
-};
-
-/*
-    Note: Since symbol indices are continuous and someObject's symbol index 
-    is simply given by someObject itself, could
-    MEM_CallByString("MYFUNCTION"); 
-    also be replaced here by 
-    MEM_CallByID(someObject + 1);
-*/
-
\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/ikarus/floats/index.html b/pl/zengin/scripts/extenders/ikarus/floats/index.html deleted file mode 100644 index e3caa6fe10..0000000000 --- a/pl/zengin/scripts/extenders/ikarus/floats/index.html +++ /dev/null @@ -1,80 +0,0 @@ - Floats - Gothic Modding Community

Floats

This part of ikarus implements support for 32 bit IEEE 754 floats in Daedalus. The script was originally created to edit zFLOAT and zREAL variables, but can also be used to arithmetic operations on real float values (not to be confused with Daedalus floats).

Initialization

The best way to initialize all Ikarus functions is to call MEM_InitAll() in the Init_Global() initialization function.

Warning

If you want to use Ikarus in Gothic 1, it is best to define your own Init_Global() function and call it from every world initialization function.

MEM_InitAll();
-

Implementation

float.d on GitHub

Functions

Danger

Ikarus floats are saved as int but it doesn't mean that you can use arithmetic operators on them. All operations on floats must be done with functions listed below.

mkf

(make float) Converts the input integer x to a float value.

func int mkf(var int x)
-
Parameters
  • var int x
    The input integer

Return value

The function returns the float representation of the input integer x.

truncf

(truncate float) Truncates the decimal part of the input float x.

func int truncf(var int x)
-
Parameters
  • var int x
    The input float

Return value

The function returns the integer part of the input float x by discarding the decimal part.

roundf

(round float) Rounds the input float x to the nearest integer value.

func int roundf(var int x)
-
Parameters
  • var int x
    The input float

Return value

The function returns the nearest integer value to the input float x. If the decimal part is exactly halfway between two integers, the function rounds to the nearest even integer.

addf

(add floats) Adds two ikarus floats together.

func int addf(var int x, var int y)
-
Parameters
  • var int x
    The first float
  • var int y
    The second float

Return value

The function returns the sum of the input floats x and y. (x + y)

subf

(subtract floats) Subtracts the second float from the first float.

func int subf(var int x, var int y)
-
Parameters
  • var int x
    The first float
  • var int y
    The second float

Return value

The function returns the difference between the first float x and the second float y. (x - y)

negf

(negate float) Negates the input float.

func int negf(var int x)
-
Parameters
  • var int x
    The input float

Return value

The function returns the negation of the input float x.

mulf

(multiply floats) Multiplies two ikarus floats.

func int mulf(var int x, var int y)
-
Parameters
  • var int x
    The first float
  • var int y
    The second float

Return value

The function returns the product of multiplying the input floats x and y. (x * y)

divf

(divide floats) Divides two ikarus floats.

func int divf(var int x, var int y)
-
Parameters
  • var int x
    The dividend float
  • var int y
    The divisor float

Return value

The function returns the quotient of dividing the input float x by y. (x / y)

invf

(inverse float) Computes the inverse of the input float.

func int invf(var int x)
-
Parameters
  • var int x
    The input float

Return value

The function returns the inverse of the x, calculated as 1/x.

gf

(greater) Checks if the first float is greater than the second float.

func int gf(var int x, var int y)
-
Parameters
  • var int x
    The first float
  • var int y
    The second float

Return value

The function returns TRUE if x is greater than y, FALSE is returned otherwise.

gef

(greater or equal) Checks if the first float is greater than or equal to the second float.

func int gef(var int x, var int y)
-
Parameters
  • var int x
    The first float
  • var int y
    The second float

Return value

The function returns TRUE if x is greater than or equal to y, FALSE is returned otherwise.

lf

(lower) Checks if the first float is less than the second float.

func int lf(var int x, var int y)
-
Parameters
  • var int x
    The first float
  • var int y
    The second float

Return value

The function returns TRUE if x is less than y, FALSE is returned otherwise.

lef

(lower or equal) Checks if the first float is less than or equal to the second float.

func int lef(var int x, var int y)
-
Parameters
  • var int x
    The first float
  • var int y
    The second float

Return value

The function returns TRUE if x is less than or equal to y, FALSE is returned otherwise.

sqrf

(square float) Calculates the square of the float.

func int sqrf(var int x)
-
Parameters
  • var int x
    The input float

Return value

The function returns the square of the input float x, computed as x * x.

sqrtf

(square root float) Calculates the square root of the float.

func int sqrtf(var int x)
-
Parameters
  • var int x
    The input float

Return value

The function returns the square root of the input float x.

sqrtf_approx

Calculates the approximate square root of a float.

func int sqrtf_approx(var int f)
-
Parameters
  • var int f
    The input float

Return value

The function returns the approximate square root of the input float as an ikarus float.

absf

(absolute value) Computes the absolute value of a float.

func int absf(var int x)
-
Parameters
  • var int x
    The input float

Return value

The function returns the absolute value of the input float x, which is the value without the negative sign (if present).

fracf

(fraction) Computes the fraction of two integers p and q.

func int fracf(var int p, var int q)
-
Parameters
  • var int p
    Numerator
  • var int q
    Denominator

Return value

The function returns the fraction of p divided by q as an ikarus float.

castFromIntf

Converts an ikarus float to a Daedalus float.

func float castFromIntf(var int f)
-
Parameters
  • var int f
    Ikarus float

Return Value

The function returns the value f as a Daedalus float.

castToIntf

Converts a Daedalus float to an ikarus float.

func int castToIntf(var float f)
-
Parameters
  • var float f
    Daedalus float

Return Value

The function returns the value f as an ikarus float.

toStringf

Converts a float value to its string representation.

func string toStringf(var int x)
-
Parameters
  • var int x
    Input float value

Return value

The function returns a string representation of the input float value.

printf

(print float) Prints the float on screen using Print().

func void printf(var int x)
-
Parameters
  • var int x
    The printed float

Examples

Simple operations

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
var int float1; float1 = mkf(5);        // Create an Ikarus float with value 5
-var int float2; float2 = mkf(2);        // Create an Ikarus float with value 2
-
-var int addResult; addResluts  = addf(float1, float2);     // Add float1 and float2
-var int subResult; subResults  = subf(float1, float2);     // Subtract float2 from float1
-var int mulResult; mulRelsults = mulf(float1, float2);     // Multiply float1 by float2
-var int divResult; divResults  = divf(float1, float2);     // Divide float1 by float2
-
-printf(addResult);   // Output: 7
-printf(subResult);   // Output: 3
-printf(mulResult);   // Output: 10
-printf(divResult);   // Output: 2.5
-
\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/ikarus/functions/arrays/index.html b/pl/zengin/scripts/extenders/ikarus/functions/arrays/index.html deleted file mode 100644 index 814969d07a..0000000000 --- a/pl/zengin/scripts/extenders/ikarus/functions/arrays/index.html +++ /dev/null @@ -1,52 +0,0 @@ - Arrays (zCArray) - Gothic Modding Community

Arrays (zCArray)

Set of function for working with ZenGin's zCArray data structure.

Initialization

The best way to initialize all Ikarus functions is to call MEM_InitAll() in the Init_Global() initialization function.

Warning

If you want to use Ikarus in Gothic 1, it is best to define your own Init_Global() function and call it from every world initialization function.

MEM_InitAll();
-

Implementation

Ikarus.d on GitHub

Functions

MEM_ArrayCreate

Creates an empty zCArray (allocates memory) and returns a pointer to it.

func int MEM_ArrayCreate()
-
Return value

The function returns a pointer to the created zCArray.

MEM_ArrayFree

Frees the memory allocated for a zCArray and its data.

func void MEM_ArrayFree(var int zCArray_ptr)
-
Parameters
  • var int zCArray_ptr
    Pointer to the zCArray to be freed

MEM_ArrayClear

Clears the data of a zCArray, freeing the memory used by its elements. The array becomes empty.

func void MEM_ArrayClear (var int zCArray_ptr)
-
Parameters
  • var int zCArray_ptr
    Pointer to the zCArray to be cleared

MEM_ArraySize

Returns the size (number of elements) of an array.

func int MEM_ArraySize(var int zCArray_ptr)
-
Parameters
  • var int zCArray_ptr
    Pointer to the zCArray

Return value

The function returns a number of a zCArray elements.

MEM_ArrayWrite

Writes a value at a specific position in the zCArray.

func void MEM_ArrayWrite(var int zCArray_ptr, var int pos, var int value)
-
Parameters
  • var int zCArray_ptr
    Pointer to the zCArray
  • var int pos
    Position in the array where the value will be written
  • var int value
    Value to be written

MEM_ArrayRead

Reads the value at a specific position in the zCArray.

func int MEM_ArrayRead(var int zCArray_ptr, var int pos)
-
Parameters
  • var int zCArray_ptr
    Pointer to the zCArray
  • var int pos
    Position in the array from which the value will be read

Return value

The function returns the value at a specific position in the zCArray.

MEM_ArrayInsert

Appends a value to the end of the zCArray. The array is automatically resized if it is too small.

func void MEM_ArrayInsert (var int zCArray_ptr, var int value)
-
Parameters
  • var int zCArray_ptr
    Pointer to the zCArray
  • var int value
    Value to be inserted

MEM_ArrayPush

Alias for MEM_ArrayInsert, inserts a value at the end of the zCArray.

func void MEM_ArrayPush (var int zCArray_ptr, var int value)
-
Parameters
  • var int zCArray_ptr
    Pointer to the zCArray
  • var int value
    Value to be inserted

MEM_ArrayPop

Removes and returns the last element from the zCArray.

func int MEM_ArrayPop(var int zCArray_ptr)
-
Parameters
  • var int zCArray_ptr
    Pointer to the zCArray

Return value

The function returns the element removed from the end of an array.

MEM_ArrayTop

Returns the last element of the zCArray without removing it.

func int MEM_ArrayTop(var int zCArray_ptr)
-
Parameters
  • var int zCArray_ptr
    Pointer to the zCArray

Return value

The function returns the last element of an array.

MEM_ArrayIndexOf

Searches the zCArray for the first occurrence of a value and returns its index.

func int MEM_ArrayIndexOf(var int zCArray_ptr, var int value)
-
Parameters
  • var int zCArray_ptr
    Pointer to the zCArray
  • var int value
    Value to search for

Return value

The function returns the index of a first occurrence of a value. If not found -1 is returned.

MEM_ArrayRemoveIndex

Removes the element at a specific index from the zCArray.

func void MEM_ArrayRemoveIndex (var int zCArray_ptr, var int index)
-
Parameters
  • var int zCArray_ptr
    Pointer to the zCArray
  • var int index
    Index of the element to be removed

MEM_ArrayRemoveValue

Removes all occurrences of a value from the zCArray.

func void MEM_ArrayRemoveValue (var int zCArray_ptr, var int value)
-
Parameters
  • var int zCArray_ptr
    Pointer to the zCArray
  • var int value
    Value to be removed

MEM_ArrayRemoveValueOnce

Removes the first occurrence of a value from the zCArray. If value is not found, a warning is issued.

func void MEM_ArrayRemoveValueOnce (var int zCArray_ptr, var int value)
-
Parameters
  • var int zCArray_ptr
    Pointer to the zCArray
  • var int value
    Value to be removed

MEM_ArraySort

Sorts the elements of the zCArray in ascending order.

func void MEM_ArraySort(var int zCArray_ptr)
-
Parameters
  • var int zCArray_ptr
    Pointer to the zCArray

MEM_ArrayUnique

Removes duplicate elements from the zCArray.

func void MEM_ArrayUnique(var int zCArray_ptr)
-
Parameters
  • var int zCArray_ptr
    Pointer to the zCArray

MEM_ArrayToString

Converts the zCArray to a string representation.

func string MEM_ArrayToString (var int zCArray_ptr)
-
Parameters
  • var int zCArray_ptr
    Pointer to the zCArray

Return value

The function returns a string representation of a given array.

\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/ikarus/functions/asm/index.html b/pl/zengin/scripts/extenders/ikarus/functions/asm/index.html deleted file mode 100644 index a4224cd4ea..0000000000 --- a/pl/zengin/scripts/extenders/ikarus/functions/asm/index.html +++ /dev/null @@ -1,87 +0,0 @@ - ASM - Gothic Modding Community

Ikarus Machine Code Implementation (ASM)

Machine code refers to a program or program segment written in machine language, which can be directly executed by a processor without further translation steps. The relevant machine language for us is that belonging to the x86 processor architecture. All machine instructions, what they do, and how they are encoded in machine language can be found in the Intel Manuals.

In practice, dealing with (abstract) machine instructions and manually translating them into (concrete) machine code is rarely necessary due to its complexity.

However, machine code can be useful for performing technical tasks that cannot be expressed in Daedalus directly. For example, the CALL package use the ASM function set as a basis.

Note

The functions in this chapter have the ASM_ prefix for Assembly (language). Assembly language is a human-readable language with one-to-one correspondences to machine language. Strictly speaking, the ASM_ prefix is misleading here, as it pertains to machine code rather than assembly language. However, conceptually, the two are closely related.

Initialization

The best way to initialize all Ikarus functions is to call MEM_InitAll() in the Init_Global() initialization function.

Warning

If you want to use Ikarus in Gothic 1, it is best to define your own Init_Global() function and call it from every world initialization function.

MEM_InitAll();
-

Implementation

Ikarus.d on GitHub

Opcodes

The code defines several constants that represent different machine code instructions. Each constant is assigned a hexadecimal value and corresponds to a specific machine code instruction. Here is a link to all instructions.

Internal Stack

The code includes an internal stack implementation, allowing the storage of data. The stack is already used at two points:

  • When calling an engine function, the address of the current run is stored in the internal stack.
  • When nesting the use of the CALL package, a push and pop operation is performed to manage the context.

The internal stack is implemented using an array, and the following functions are provided:

ASMINT_Push

Pushes the specified data onto the internal stack.

func void ASMINT_Push(var int data)
-
Parameters
  • var int data
    Data pushed onto internal stack

ASMINT_Pop

Pops and returns the topmost data from the internal stack.

func int ASMINT_Pop()
-
Return value

The function returns a data popped form the internal stack.

Functions (Core)

The ASM core functionality provides a framework for assembling machine code instructions and executing them. The following functions are included:

ASMINT_Init

Initializes the ASM system by creating an internal stack and finding function addresses.

func void ASMINT_Init()
-

Tip

It's worth noting that ASMINT_Ini is also invoked by the MEM_InitAll function.

ASM_Open

Changes the size of the memory allocated at the start o the dictation

The memory in which the machine code is stored is allocated at the beginning of the dictation. If this function isn't called a default size (see Constant below) is allocated by ASM or ASM_Here function. The 256 bytes is often sufficient for simple applications, but if more memory is required, this function must be called at the beginning of the dictation.

func void ASM_Open(var int space)
-
Parameters
  • var int space
    Space allocated for machine code (in bytes)

Constant

ASM_StandardStreamLength constant defines the default space available for an Assembler sequence (in bytes).

const int ASM_StandardStreamLength = 256;
-

ASM

Writes machine code instructions to the stream.

Using this function it is possible to dictate machine code little by little. The data bytes of the length (maximum 4!) are appended to the previously dictated part. This creates a program piece by piece that can be executed by the processor.

func void ASM(var int data, var int length)
-
Parameters
  • var int data
    The machine code instruction or its part
  • var int length
    Length of the data (max 4 bytes)

ASM_1

ASM with length parameter hardcoded to 1. Writes one byte machine code instructions to the stream.

func void ASM_1(var int data) 
-
Parameters
  • var int data
    One byte machine code instruction or its part

ASM_2

ASM with length parameter hardcoded to 2. Writes two bytes machine code instructions to the stream.

func void ASM_1(var int data) 
-
Parameters
  • var int data
    Two bytes machine code instruction or its part

ASM_3

ASM with length parameter hardcoded to 3. Writes three bytes machine code instructions to the stream.

func void ASM_1(var int data) 
-
Parameters
  • var int data
    Three bytes machine code instruction or its part

ASM_4

ASM with length parameter hardcoded to 4. Writes four bytes machine code instructions to the stream.

func void ASM_1(var int data) 
-
Parameters
  • var int data
    Four bytes machine code instruction or its part

ASM_Here

Provides, the address of the cursor, i.e., the address of the location that will be described next by a call to ASM. It is guaranteed that the location where the code is written is also the location where it will be executed.

func int ASM_Here()
-

Return value

The function returns an address that is the current position in the machine code stream.

ASM_Close

Finalizes the stream by adding a return instruction and returns the starting address of the stream. This pointer can now be passed to at any time and any number of times to execute the machine code.

Warning

The memory area obtained by ASM_Close must be released manually using MEM_Free to avoid memory leaks. It is probably sufficient for almost all practical purposes.

func int ASM_Close()
-
Return value

The function returns a starting address of the stream (pointer to the stream).

ASM_Run

Executes a machine code (stream) from a pointer.

Note

ASM_Run can also be used to call engine functions with no parameters and no relevant return value. In this case ptr would simply have to point to the function to be executed in the code segment.

func void ASM_Run(var int ptr)
-
Parameters
  • var int ptr
    Pointer to the executed code (returned form ASM_Close)

ASM_RunOnce

Executes the code dictated up to that point, similar to how an external function is executed. After that the code is released, and new code can be dictated.

func void ASM_RunOnce()
-

Example

The following function sets the NPC passed as slf as the player, as if you had pressed O in Marvin mode with this NPC in focus. This is so short because there is already a function for this exact purpose, it's just not normally accessible from the scripts. It is therefore sufficient to write assembly code that pushes the parameter of the function (the this pointer) into the appropriate register and then calls the function.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
func void SetAsPlayer(var C_NPC slf) { /* Address of the function */
-    const int oCNpc__SetAsPlayer = 7612064; //0x7426A0 (Gothic2.exe)
-
-    var int slfPtr;
-    slfPtr = MEM_InstToPtr (slf);
-
-    //mov ecx slfPtr
-    ASM_1(ASMINT_OP_movImToECX); /* move a value to ecx */
-    ASM_4(slfPtr); /* a value */
-
-    //call oCNpc__SetAsPlayer
-    ASM_1(ASMINT_OP_call);
-    ASM_4(oCNpc__SetAsPlayer - ASM_Here() - 4);
-
-    ASM_RunOnce(); /* return will be added automatically */
-};
-

Note

Call targets are specified relative to the instruction that would have been executed after the actual call instruction. Therefore, both ASM_Here() and the subtraction of 4 in the call parameter are necessary.

The above example describes, among other things, CALL__thiscall function form the CALL Package that can be also used to implement SetAsPlayer.

1
-2
-3
-4
func void SetAsPlayer(var C_NPC slf) { 
-    const int oCNpc__SetAsPlayer = 7612064;
-    CALL__thiscall(MEM_InstToPtr(slf), oCNpc__SetAsPlayer);
-};
-
\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/ikarus/functions/call/index.html b/pl/zengin/scripts/extenders/ikarus/functions/call/index.html deleted file mode 100644 index 868a1fae2e..0000000000 --- a/pl/zengin/scripts/extenders/ikarus/functions/call/index.html +++ /dev/null @@ -1,181 +0,0 @@ - CALL Package - Gothic Modding Community

CALL Package

This part of Ikarus makes possible to call engine functions directly from scripts.

In order to be able to invoke an engine function, you must know some of its properties. This includes the number and types of parameters, the type of return value, address of function and calling convention.

Knowledge about engine functions can be obtained using tools like IDA, which can analyze and convert GothicMod.exe / Gothic2.exe into a more human-readable format.

Info

In fact, machine code execution (ASM) is part of the CALL package, but due to its complexity, this functionality is discussed in a separate article.

Initialization

The best way to initialize all Ikarus functions is to call MEM_InitAll() in the Init_Global() initialization function.

Warning

If you want to use Ikarus in Gothic 1, it is best to define your own Init_Global() function and call it from every world initialization function.

MEM_InitAll();
-

Implementation

Ikarus.d on GitHub

Call modes

There are two modes:

Disposable

The simple mode that produces a disposable call that is used only once. All parameters are hardcoded.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
func int hero_GetAssessEnemy() {
-    const int oCNpc__GetPerceptionFunc = 7726080; //0x75E400
-
-    CALL_IntParam(_@(PERC_ASSESSENEMY));
-    CALL_PutRetValTo(_@(funcID));
-    CALL__thiscall(_@(hero), oCNpc__GetPerceptionFunc);
-
-    var int funcID;
-    return +funcID;
-};
-

Recyclable

The second version produces code that can be used more than once. Instead of the parameters the user specifies the address where the parameters are to be taken from. In addition to executing the code, the user will receive an address that he can use to repeat the call. This is much faster than rebuilding the call from scratch.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
func int Npc_GetPercFunc(var C_Npc npc, var int type) {
-    const int oCNpc__GetPerceptionFunc = 7726080; //0x75E400
-
-    var int npcPtr; npcPtr = _@(npc);
-
-    const int call = 0;
-    if (CALL_Begin(call)) {
-        CALL_IntParam(_@(type));
-        CALL_PutRetValTo(_@(funcID));
-        CALL__thiscall(_@(npcPtr), oCNpc__GetPerceptionFunc);
-        call = CALL_End();
-    };
-
-    var int funcID;
-    return +funcID;
-};
-

Receives a pointer. In case the pointer is non-zero, the code at this position is executed and 0 is returned. In case pointer is zero, the current mode is changed into recyclable mode, this means that the call functions expect instructions to build a recyclable call. This mode will continue until CALL_End(). This allows code like this:

Start and End

CALL_Open

Initializes a Recyclable call mode.

func void CALL_Open()
-

CALL_Begin

A practical wrapper for CALL_Open. Makes a call if it had been already created, initializes it otherwise.

func int CALL_Begin(var int ptr)
-
Parameters
  • var int ptr
    Zero if you need to create a new recyclable function to be called (usually, before first use). In this case CALL_Open is called and CALL_Begin returns 1.

Return Value

The function returns 1 if the new call has been created, 0 is returned otherwise.

CALL_Close

Finalizes a function call in recyclable mode, restoring the previous execution context.

func int CALL_Close()
-

CALL_End

Finalizes a function call, pushes the pointer onto the stack, and runs the associated assembly code (makes an actual call).

func int CALL_End()
-

Return Value

The function returns a pointer that could be used to repeat the call.

Tip

CALL_Close only finalizes the function call, returning the pointer, while CALL_End additionally handles pushing the pointer onto the stack and running associated assembly code.

Passing parameters

Parameters must be arranged on the machine stack from right to left i.e. from the parameter on the far right to the parameter on the far left. These functions generate machine code that will place parameters on the machine stack when executed.

Note

These functions do not impose any parameters on the Machine stack. Exactly it should say: You create the machine code that will put parameters on the machine stack when it is executed. And it is only carried out in the second step with the announcement of the calling convention.

CALL_IntParam

Passes an integer (int32) as a parameter to the called function.

func void CALL_IntParam(var int param)
-
Parameters
  • var int param
    Address of an integer to be passed

CALL_FloatParam

Passes an IEEE 7554 floating-point number (single / zREAL) as a parameter to the called function.

func void CALL_FloatParam(var int param)
-
Parameters
  • var int param
    Address of a float to be passed

CALL_PtrParam

Passes a pointer (void*) as a parameter to the called function.

func void CALL_PtrParam(var int param)
-
Parameters
  • var int param
    Pointer to be passed

CALL_zStringPtrParam

Passes a string (zString*) as a parameter to the called function.

func void CALL_zStringPtrParam(var string param)
-
Parameters
  • var string param
    String to be passed

Warning

This function only works when writing a disposable call!

CALL_cStringPtrParam

Passes a char array (char **) as a parameter to the called function.

func void CALL_cStringPtrParam(var string param)
-
Parameters
  • var string param
    String to be passed as character array`

Warning

This function only works when writing a disposable call!

CALL_StructParam

Passes a structure (struct) as a parameter to the called function.

func void CALL_StructParam(var int ptr, var int words)
-
Parameters
  • var int param
    Pointer to the object
  • var int words
    Size of a structure (1 word = 32 bits)

Note

CALL_IntParam, CALL_FloatParam, and CALL_PtrParam are functionally identical and are differentiated for code readability.

The call

The calling convention determines how the function's parameters are passed. IDA or another disassembler can be used to identify the convention used by a specific engine function.

The announcement of the calling convention, i.e. the call of one of the four functions below is also the time of calling the function. In particular, all parameters must already be specified at this point.

CALL__stdcall

Calls a function with __stdcall (Standard Call) calling convention.

func void CALL__stdcall(var int adr)
-
Parameters
  • var int adr
    Address of a function

CALL__thiscall

Calls a function with __thiscall calling convention. Used with a member functions.

func void CALL__thiscall(var int this, var int adr)
-
Parameters
  • var int this
    Pointer to the owner class object passed as a this parameter
  • var int adr
    Address of a function

CALL__cdecl

Calls a function with __cdecl calling convention. Used with non-Windows API and non-class functions.

func void CALL__cdecl (var int adr)
-
Parameters
  • var int adr
    Address of a function

CALL__fastcall

Calls a function with __fastcall calling convention.

func void CALL__fastcall(var int ecx, var int edx, var int adr)
-
Parameters
  • var int ecx
    First parameter of a function
  • var int edx
    Second parameter of a function
  • var int adr
    Address of a function

Return Value

As soon as the function call has taken place, i.e. after step 2, the return value can be queried. The following functions interpret the return value (usually this is the content of EAX immediately after the call) in the manner suggested in the function name. The result is then returned in a manner usable in Daedalus.

Note

Some return values are not stored in the EAX. In that case the call of the special function RetValIs is required to get the return value.

Following functions are provided: CALL_RetValIsFloat, CALL_RetValIszString, CALL_RetValIsStruct.

CALL_PutRetValTo

Simply places the return value to the given address (mostly the address of a daedalus integer). Must be called before The Call function.

func void CALL_PutRetValTo(var int adr)
-
Parameters
  • var int adr
    Destination address of the return value

CALL_RetValAsInt

Retrieves an integer returned by the called function.

func int CALL_RetValAsInt()
-
Return value

The function returns an integer returned by the previously called engine function.

CALL_RetValIsFloat

Specifies that the return value is a float. Must be called before The Call function to allow getting the return value with CALL_RetValAsFloat.

func void CALL_RetValIsFloat()
-

CALL_RetValAsFloat

Retrieves a float returned by the called function.

func int CALL_RetValAsFloat()
-
Return value

The function returns a float returned by the previously called engine function.

CALL_RetValAsPtr

Retrieves a pointer (void*) returned by the called function.

func int CALL_RetValAsPtr()
-
Return value

The function returns a pointer returned by the previously called engine function.

CALL_RetValIsStruct

Specifies that the return value is a Structure. Must be called before The Call function to allow getting the return value with CALL_RetValAsStructPtr.

func void CALL_RetValIsStruct(var int size)
-
Parameters
  • var int size
    Size of the returned structure in bytes

Danger

If the return value is a structure with a size larger than 32 bit, the space for the return value has to be allocated by the caller (this is us).The address to the allocated memory is expected on the stack as an additional parameter (pushed last).

Warning

It is in your responsibility to free the structure memory, when the return value is not needed any more.

CALL_RetValAsStructPtr

Retrieves a pointer to the structure returned by the called function and converts it to the instance. Can be used to make an assignment to an instance, for example an assignment to a var zCVob if the return value is a pointer to a zCVob.

func MEMINT_HelperClass CALL_RetValAsStructPtr()
-
Return value

The function returns an instance returned by the previously called engine function.

CALL_RetValIszString

Specifies that the return value is a zString (20 bytes structure). Must be called before The Call function to allow getting the return value with CALL_RetValAszStringPtr and CALL_RetValAszString.

func string CALL_RetValAszString()
-

Note

CALL_RetValAszStringPtr and CALL_RetValAszString are quite different and should not be confused. Using CALL_RetValAszString frees up memory that may still be needed. In a reverse with CALL_RetValAszStringPtr memory that is no longer needed is not freed and can cause memory leak.

CALL_RetValAszStringPtr

Retrieves a zString pointer and converts it to the daedalus string. (don't frees the memory)

func string CALL_RetValAszStringPtr()
-
Return value

The function returns a daedalus string form a zString returned by the previously called engine function.

CALL_RetValAszString

Retrieves a zString pointer and converts it to the daedalus string. (frees the memory)

func string CALL_RetValAszString()
-
Return value

The function returns a daedalus string form a zString returned by the previously called engine function.

Function author note

A zString is merely a special case of a structure, with the difference, that it is used as a primitive datatype. Nobody will be willing to use it as a pointer to some memory or an instance in Daedalus. This function copies the contents of the zString into a daedalus string and frees the zString afterwards.

Examples

Apply overlay (Disposable)

1
-2
-3
-4
-5
-6
-7
-8
// .text:0072D2C0:int __thiscall oCNpc::ApplyOverlay(class zSTRING const &)
-
-func void example1(){
-    const int oCNpc__ApplyOverlay = 7525056; //0x72D2C0 (G2A)
-    CALL_zStringPtrParam ("HUMANS_MILITIA.MDS");
-    CALL__thiscall (MEM_InstToPtr (hero), oCNpc__ApplyOverlay);
-    //We are not interested in the return value here.
-};
-

Get time as string (Disposable)

e.g. "7:30" for half past seven in the morning

1
-2
-3
-4
-5
-6
-7
-8
// .text:00780EC0:class zSTRING __thiscall oCWorldTimer::GetTimeString(void)
-
-func void example2(){
-    const int oCWorldTimer__GetTimeString = 7868096; //780EC0 (G2A)
-    CALL_RetValIszString();
-    CALL__thiscall (MEM_InstToPtr (MEM_WorldTimer), oCWorldTimer__GetTimeString );
-    PrintDebug (CALL_RetValAszString());
-};
-

Get the "sky time" (Disposable)

Sky time is a floating point value between 0 and 1 that jumps back from 1 to 0 at noon.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
// .text:00781240:float __thiscall oCWorldTimer::GetSkyTime(void)
-
-func int GetSkyTime() {
-    const int oCWorldTimer__GetSkyTime = 7868992; //0x781240
-    CALL_RetValIsFloat();
-    CALL__thiscall (MEM_InstToPtr (MEM_WorldTimer),
-    oCWorldTimer__GetSkyTime);
-
-    return CALL_RetValAsFloat();
-};
-

Delete Vob (Recyclable)

Call of the oCWorld.RemoveVob. MEM_DeleteVob is an ikarus built-in function.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
func void MEM_DeleteVob(var int vobPtr) {
-    var int world; world = MEM_Game._zCSession_world;
-
-    const int call = 0;
-    if (CALL_Begin(call)) {
-        /* oCWorld.RemoveVob */
-        CALL_IntParam(_@(vobPtr));
-        CALL__thiscall(_@(world), MEMINT_SwitchG1G2(7171824, 7864512));
-
-        call = CALL_End();
-    };
-};
-
\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/ikarus/functions/debug/index.html b/pl/zengin/scripts/extenders/ikarus/functions/debug/index.html deleted file mode 100644 index 49c09209af..0000000000 --- a/pl/zengin/scripts/extenders/ikarus/functions/debug/index.html +++ /dev/null @@ -1,46 +0,0 @@ - Debug - Gothic Modding Community

Debug

A set of debugging and error-handling functions for mod development with Ikarus.

Initialization

The best way to initialize all Ikarus functions is to call MEM_InitAll() in the Init_Global() initialization function.

Warning

If you want to use Ikarus in Gothic 1, it is best to define your own Init_Global() function and call it from every world initialization function.

MEM_InitAll();
-

Implementation

Ikarus.d on GitHub

Functions

MEM_CheckVersion

Checks if the version of Ikarus is the specified version or newer.

func int MEM_CheckVersion(var int base, var int major, var int minor)
-
Parameters
  • var int base
    Base version number
  • var int major
    Major revision number
  • var int minor
    Minor revision number

Return value

The function returns TRUE if the version of Ikarus is the specified version or newer, FALSE is returned otherwise.

MEM_SetShowDebug

Sets the variable that is also toggled by the toggle debug command. As a result, messages outputted by PrintDebug are directed to the zSpy

func void MEM_SetShowDebug(var int on)
-
Parameters
  • var int on
    Specifies whether to turn on (TRUE) or off (FALSE) debug information.

MEM_SendToSpy

Sends a message to the debugging console.

func void MEM_SendToSpy(var int errorType, var string text)
-
Parameters
  • var int errorType
    Type of error (e.g., zERR_TYPE_FAULT, zERR_TYPE_WARN, zERR_TYPE_INFO)
  • var string text
    The message to be sent.

MEM_ErrorBox

Displays an error message in a message box.

func void MEM_ErrorBox(var string text)
-
Parameters
  • var string text
    The error message to be displayed.

MEM_PrintStackTrace

Prints the stack trace.

func void MEM_PrintStackTrace()
-

MEM_Error

Handles a fatal error, displaying the error message and printing the stack trace.

func void MEM_Error(var string error)
-
Parameters
  • var string error
    The error message.

MEM_Warn

Handles a warning, displaying the warning message and printing the stack trace.

func void MEM_Warn(var string warn)
-
Parameters
  • var string warn
    The warning message.

MEM_Info

Handles an information message, printing it if enabled in the settings.

func void MEM_Info(var string info)
-
Parameters
  • var string info
    The information message.

MEM_AssertFail

Handles an assertion failure, reporting the error message as a fatal error.

func void MEM_AssertFail(var string assertFailText)
-
Parameters
  • var string assertFailText
    The assertion failure message.

MEM_Debug

Freely configurable debug channel. See how to setup it in the Constants article.

func void MEM_Debug(var string message)
-
Parameters
  • var string message
    The debug message.

MEMINT_SwitchG1G2

Switches between values based on the game version. Used mainly to change addresses in multi-platform hooks or function calls.

func int MEMINT_SwitchG1G2(var int g1Val, var int g2Val)
-
Parameters
  • var int g1Val The value to return if the game version is Gothic 1.
  • var int g2Val
    The value to return if the game version is Gothic 2.

Return value

The function returns an appropriate value based on the game version.

\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/ikarus/functions/ini_access/index.html b/pl/zengin/scripts/extenders/ikarus/functions/ini_access/index.html deleted file mode 100644 index d0461fb681..0000000000 --- a/pl/zengin/scripts/extenders/ikarus/functions/ini_access/index.html +++ /dev/null @@ -1,49 +0,0 @@ - Ini File Access - Gothic Modding Community

Dostęp do plików konfiguracyjnych

Ta część Ikarusa umożliwia dostęp do Gothic.ini i pliku konfiguracyjnego załadowanej modyfikacji.

Inicjalizacja

Najlepszym sposobem na zainicjowanie Ikarusa jest wywołanie MEM_InitAll() w funkcji Init_Global().

Warning

Jeżeli chcesz używać Ikarusa z Gothiciem 1, najlepiej będzie, jeśli zdefiniujesz własną funkcję Init_Global() i wywołasz ją w każdej funkcji inicjującej świat.

MEM_InitAll();
-

Implementacja

Ikarus.d na GitHubie

Funkcje odczytu

MEM_GetCommandLine

Zwraca zawartość linii poleceń przekazaną do Gothica.

func string MEM_GetCommandLine()
-
Zwracana wartość

Funkcja zwraca zawartość linii poleceń przekazaną do Gothica. Może to wyglądać na przykład tak:

"-TIME:7:35 -GAME:TEST_IKARUS.INI -ZREPARSE -ZWINDOW -ZLOG:5,S -DEVMODE -ZMAXFRAMERATE:30"

MEM_GetGothOpt

Przeszukuje Gothic.ini w poszukiwaniu opcji

func string MEM_GetGothOpt(var string sectionname, var string optionname)
-
Parametry
  • var string sectionname
    Nazwa sekcji np. [GAME]
  • var string optionname
    Szukana opcja np. playLogoVideos

Zwracana wartość

Funkcja zwraca wartość opcji w postaci ciągu znaków, albo pustą zmienną, gdy opcja nie istnieje w danej sekcji.

MEM_GetModOpt

Przeszukuje ini załadowanej modyfikacji w poszukiwaniu opcji.

func void MEM_GetModOpt(var string sectionname, var string optionname)
-
Parametry
  • var string sectionname
    Nazwa sekcji np. [INFO]
  • var string optionname
    Szukana opcja np. Title

Zwracana wartość

Funkcja zwraca wartość opcji w postaci ciągu znaków, albo pustą zmienną, gdy opcja nie istnieje w danej sekcji.

MEM_GothOptSectionExists

Sprawdza, czy dana sekcja istnieje w Gothic.ini

func int MEM_GothOptSectionExists(var string sectionname)
-
Parametry
  • var string sectionname
    Nazwa sekcji np. [GAME]

Zwracana wartość

Funkcja zwraca wartość TRUE jeśli sekcja istnieje, inaczej FALSE.

MEM_ModOptSectionExists

Sprawdza, czy dana sekcja istnieje w ini załadowanej modyfikacji.

func int MEM_ModOptSectionExists(var string sectionname)
-
Parametry
  • var string sectionname
    Nazwa sekcji np. [INFO]

Zwracana wartość

Funkcja zwraca wartość TRUE jeśli sekcja istnieje, inaczej FALSE.

MEM_GothOptExists

Sprawdza, czy dana opcja istnieje w Gothic.ini

func int MEM_GothOptExists(var string sectionname, var string optionname)
-
Parametry
  • var string sectionname
    Nazwa sekcji np. [GAME]
  • var string optionname
    Szukana opcja np. playLogoVideos

Zwracana wartość

Funkcja zwraca wartość TRUE jeśli opcja w danej sekcji istnieje, inaczej FALSE.

MEM_ModOptExists

Sprawdza, czy dana opcja istnieje w ini załadowanej modyfikacji.

func int MEM_ModOptExists(var string sectionname, var string optionname)
-
Parametry
  • var string sectionname
    Nazwa sekcji np. [INFO]
  • var string optionname
    Szukana opcja np. Title

Zwracana wartość

Funkcja zwraca wartość TRUE jeśli opcja w danej sekcji istnieje, inaczej FALSE.

Funkcje zapisu

Warning

Plik konfiguracyjny modyfikacji nigdy nie jest zapisywany na dysku, dlatego nie ma oddzielnej funkcji do jego zapisu.

MEM_SetGothOpt

Opcja option w sekcji section jest ustawiana na value. Jeśli sekcja i/lub opcja nie istnieje, zostanie utworzona.

func void MEM_SetGothOpt(var string section, var string option, var string value)
-
Parametry
  • var string section
    Sekcja, w której znajduje się opcja
  • var string option
    Opcja do zapisania/nadpisania
  • var string value
    Wartość, na jaką ustawiana jest opcja

MEM_ApplyGothOpt

Stosuje zmiany i zapisuje plik ini na dysku.

func void MEM_ApplyGothOpt()
-

Tip

Jeśli wprowadzasz nowe opcje, najlepiej kierować się paroma zasadami. Dobrą praktyką jest nazywanie swoich opcji tak, aby inni mogli je zrozumieć i umieszczanie ich w sekcji o takiej samej nazwie jak twój mod. Nie umieszczaj opcji swojej modyfikacji w sekcji [GAME] lub [PERFORMANCE].

Funkcje klawiszy

Gothic.ini zawiera przypisanie klawiszy fizycznych (np. "W") do klawiszy logicznych (np. "keyUp").

MEM_GetKey

Zwraca podstawowy klawisz przypisany do klawisza logicznego.

func int MEM_GetKey(var string name)
-
Parametry
  • var string name
    Nazwa klawisza logicznego

Zwracana wartość

Funkcja zwraca klawisz przypisany do klawisza logicznego.

MEM_GetSecondaryKey

Zwraca zapasowy klawisz przypisany do klawisza logicznego.

func int MEM_GetSecondaryKey(var string name)
-
Parametry
  • var string name
    Nazwa klawisza logicznego

Zwracana wartość

Funkcja zwraca klawisz przypisany do klawisza logicznego.

MEM_SetKeys

Ustawia klawisze klawiatury dla podanego klawisza logicznego.

func void MEM_SetKeys(var string name, var int primary, var int secondary)
-
Parametry

MEM_SetKey

Ustawia podstawowy klawisz klawiatury dla klawisza logicznego.

func void MEM_SetKey(var string name, var int key)
-
Parametry
  • var string name
    Nazwa klawisza logicznego
  • var int key
    Podstawowy klawisz do przypisania, można go pobrać z pliku Ikarus_Const_G1 / Ikarus_Const_G2.

MEM_SetSecondaryKey

Ustawia zapasowy klawisz klawiatury dla klawisza logicznego.

func void MEM_SetSecondaryKey(var string name, var int key)
-
Parametry
\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/ikarus/functions/jumps_loops/index.html b/pl/zengin/scripts/extenders/ikarus/functions/jumps_loops/index.html deleted file mode 100644 index 240e4b4c03..0000000000 --- a/pl/zengin/scripts/extenders/ikarus/functions/jumps_loops/index.html +++ /dev/null @@ -1,560 +0,0 @@ - Jumps and Loops - Gothic Modding Community

Jumps and Loops

Jumps

Jumps in Ikarus are implemented by direct manipulation of the stack pointer, achieved with two lines of code. These lines enable the change of the current position within the parser stack, representing machine-level code generated during script compilation. By querying and setting this position, the execution flow can be redirected to a new location in the code.

Initialization

To ensure the correct functioning of this jump mechanism, it is crucial to execute the MEM_InitLabels() function once after loading a saved game. The recommended practice is to integrate this initialization function within INIT_GLOBAL. It's only after MEM_InitLabels() has been called that accessing MEM_StackPos.position becomes valid.

func void MEM_InitLabels()
-

Tip

It's worth noting that MEM_InitLabels is also invoked by the MEM_InitAll function.

Usage

  • Label Initialization
    Before attempting a jump, it's important to initialize the label to which the jump is intended. Forward jumps, where the jump point is encountered before the jump target, can be challenging. Label initialization looks like that:
    1
    -2
    -3
    -4
    // [...]
    -var int label;
    -label = MEM_StackPos.position;
    -// [...]
    -
  • Actual jump
    After initializing the label you could simply jump to it by setting MEM_StackPos.position to the label.
    1
    -2
    -3
    // [...]
    -MEM_StackPos.position = label;
    -// [...]
    -

Jump flowchart

flowchart TD
-A(Start) --> B["var int label; \n label = MEM_StackPos.position;"];
-B --> C{Your code}
-C -->D["MEM_StackPos.position = label;"];
-C --> E(End)
-D --> |Jump| B;

Notes and warnings

  • Validity of Labels
    Labels become invalid after saving and loading. Consequently, labels should be used immediately, and there is generally no reason to persist them for an extended period.

  • Caution with Jumping
    Jumping between different functions without a clear understanding of the code structure can lead to unexpected issues. Similarly, using labels without a thorough comprehension of their purpose may result in undesired consequences. It's crucial to exercise caution, especially when making assignments involving labels.

Examples

The following code outputs the numbers from 0 to 42:

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
func void foo() {
-    /* Initialization */
-    MEM_InitLabels();
-    var int count; count = 0;
-
-    /* Record the execution position in label. */
-    var int label;
-    label = MEM_StackPos.position;
-    /* <---- label now points here,
-    * i.e. to the position AFTER the assignment of label. */
-
-    Print (ConcatStrings ("COUNT: ", IntToString (count)));
-    count += 1;
-
-    if (count <= 42) {
-        /* Replace the execution position,
-        * with the "<-----" the system then continues */
-        MEM_StackPos.position = label;
-    };
-
-    /* Once 43 is reached, the “loop” is exited. */
-};
-

The following code should enumerate all pairs (x,y) with 0 <= x < max_x, 0 <= y < max_y

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
-37
-38
-39
-40
-41
-42
-43
-44
-45
-46
func void printpairs(var int max_x, var int max_y)
-{
-    // Initialize labels
-    MEM_InitLabels();
-    // PrintDebug should be used, i.e. activate debug output
-    MEM_SetShowDebug (1);
-
-    var int x; var int y; x = 0;
-
-    // while (x < max_x)
-    var int x_loop; x_loop = MEM_StackPos.position;
-    if (x < max_x)
-    { 
-        y = 0;
-        // while (y < max_y) 
-        var int y_loop; y_loop = MEM_StackPos.position;
-        if (y < max_y)
-        { 
-            var string out; out = "(";
-            out = ConcatStrings (out, IntToString (x));
-            out = ConcatStrings (out, ", ");
-            out = ConcatStrings (out, IntToString (y));
-            out = ConcatStrings (out, ")");
-            PrintDebug (out);
-            y += 1;
-
-            // continue y_loop 
-            MEM_StackPos.position = y_loop;
-        };
-        x += 1;
-        // continue x_loop
-        MEM_StackPos.position = x_loop;
-    };
-};
-
-/*
-    Output of a call printpairs(4,2) would then be: 
-    00:36 Info: 5 U: Skript: (0, 0) .... 
-    00:36 Info: 5 U: Skript: (0, 1) .... 
-    00:36 Info: 5 U: Skript: (1, 0) .... 
-    00:36 Info: 5 U: Skript: (1, 1) .... 
-    00:36 Info: 5 U: Skript: (2, 0) .... 
-    00:36 Info: 5 U: Skript: (2, 1) .... 
-    00:36 Info: 5 U: Skript: (3, 0) .... 
-    00:36 Info: 5 U: Skript: (3, 1) .... 
-*/
-

Label and Goto

Besides the normal jumps Ikarus implements MEM_Label and MEM_Goto functions. They work similar to the stack manipulation with var int label but the interface is much more user-friendly and defining new variables is not needed.

MEM_Label

Function that works like a label = MEM_StackPos.position;. You could jump to it with MEM_Goto.

func void MEM_Label(var int lbl)
-
Parameters
  • var int lbl
    Number of the label, used for nested loop or multiple loops within one function

MEM_Goto

Function that works like a MEM_StackPos.position = label;. Executes a jump to a MEM_Label with specified number.

func void MEM_Goto(var int lbl)
-
Parameters
  • var int lbl
    Number of the label, the function will jump to

Usage

Usage of Label and Goto is probably self-explanatory, since it is same as in the regular Ikarus Jump. But before using it reading the Notes and warnings of the Jumps is recommended.

Label-Goto loop flowchart

flowchart TD
-A(Start) --> B["MEM_Label(0);"];
-B --> C{Your code}
-C -->D["MEM_Goto(0);"];
-C --> E(End)
-D --> |Jump| B;
Label-Goto loop
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
func void LabelGoto_test() {
-    var int i; 
-    MEM_Label(0);
-        MEM_Debug(IntToString(i));
-        i = i + 1;
-        if(i >= 4)
-        {
-            return;
-        };
-        MEM_Goto(0);
-};
-
-//  Results:
-//  Info:  0 Q:     Debug: 0
-//  Info:  0 Q:     Debug: 1
-//  Info:  0 Q:     Debug: 2
-//  Info:  0 Q:     Debug: 3
-

Examples

The following code outputs the numbers from 0 to 42:

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
func void foo() {
-    var int count; count = 0;
-
-    MEM_Label(0);
-    /* <---- label now points here,
-    * i.e. to the position AFTER the assignment of label. */
-
-    Print (ConcatStrings ("COUNT: ", IntToString (count)));
-    count += 1;
-
-    if (count <= 42) {
-        // Jump to the MEM_Label
-        MEM_Goto(0);
-    };
-
-    /* Once 43 is reached, the “loop” is exited. */
-};
-

The following code should enumerate all pairs (x,y) with 0 <= x < max_x, 0 <= y < max_y

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
-37
-38
-39
-40
-41
-42
func void printpairs(var int max_x, var int max_y)
-{
-    // PrintDebug should be used, i.e. activate debug output
-    MEM_SetShowDebug (1);
-
-    var int x; var int y; x = 0;
-
-    // while (x < max_x)
-    MEM_Label(0);
-    if (x < max_x)
-    { 
-        y = 0;
-        // while (y < max_y) 
-        MEM_Label(1);
-        if (y < max_y)
-        { 
-            var string out; out = "(";
-            out = ConcatStrings (out, IntToString (x));
-            out = ConcatStrings (out, ", ");
-            out = ConcatStrings (out, IntToString (y));
-            out = ConcatStrings (out, ")");
-            PrintDebug (out);
-            y += 1;
-
-            MEM_Goto(1);
-        };
-        x += 1;
-       MEM_Goto(0);
-    };
-};
-
-/*
-    Output of a call printpairs(4,2) would then be: 
-    00:36 Info: 5 U: Skript: (0, 0) .... 
-    00:36 Info: 5 U: Skript: (0, 1) .... 
-    00:36 Info: 5 U: Skript: (1, 0) .... 
-    00:36 Info: 5 U: Skript: (1, 1) .... 
-    00:36 Info: 5 U: Skript: (2, 0) .... 
-    00:36 Info: 5 U: Skript: (2, 1) .... 
-    00:36 Info: 5 U: Skript: (3, 0) .... 
-    00:36 Info: 5 U: Skript: (3, 1) .... 
-*/
-

While loop

Ikarus also implements a while loop. Its syntax isn't as good as the loop from zParserExtender, due to the daedalus limitations, but it works as a normal while loop that can be found in many programming languages.

Syntax

The Ikarus while loop consist of three things:

  • while function
    That works like a while statement and start of the brace while(var int b){.

    func void while(var int b)
    -
  • end constant
    That works like an ending brace }.

    const int end = -72;
    -
  • break and continue constant
    These two constants works like a regular break and continue statements in C.

    1
    -2
    const int break = -42;
    -const int continue = -23;
    -
while loop
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
func void while_test() {
-    var int value; value = 10;
-    while(value > 0); //{
-
-        if (value == 8)
-        {
-            continue;
-        };
-
-        if (value == 2)
-        {
-            break;
-        };
-    end; //}
-};
-

Examples

The following code outputs the numbers from 0 to 42:

1
-2
-3
-4
-5
-6
-7
-8
-9
func void foo() {
-    var int count; count = 0;
-    while(count <= 42); //{
-        Print (ConcatStrings ("COUNT: ", IntToString (count)));
-        count += 1;
-    end; //}
-
-    /* Once 43 is reached, the loop is exited. */
-}; 
-

The following code should enumerate all pairs (x,y) with 0 <= x < max_x, 0 <= y < max_y

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
func void printpairs(var int max_x, var int max_y)
-{
-    // PrintDebug should be used, i.e. activate debug output
-    MEM_SetShowDebug (1);
-
-    var int x; var int y; x = 0;
-
-    while(x < max_x); //{
-        y = 0;
-        while(y < max_y); //{  
-            var string out; out = "(";
-            out = ConcatStrings (out, IntToString (x));
-            out = ConcatStrings (out, ", ");
-            out = ConcatStrings (out, IntToString (y));
-            out = ConcatStrings (out, ")");
-            PrintDebug (out);
-            y += 1;
-        end; //}
-        x += 1;
-    end; //}
-};
-
-/*
-    Output of a call printpairs(4,2) would then be: 
-    00:36 Info: 5 U: Skript: (0, 0) .... 
-    00:36 Info: 5 U: Skript: (0, 1) .... 
-    00:36 Info: 5 U: Skript: (1, 0) .... 
-    00:36 Info: 5 U: Skript: (1, 1) .... 
-    00:36 Info: 5 U: Skript: (2, 0) .... 
-    00:36 Info: 5 U: Skript: (2, 1) .... 
-    00:36 Info: 5 U: Skript: (3, 0) .... 
-    00:36 Info: 5 U: Skript: (3, 1) .... 
-*/
-

Repeat loop

In addition Ikarus implements something called Repeat loop.

Initialization

To use Repeat loop you must first call MEM_InitRepeat() function once after loading a saved game. The recommended practice is to integrate this initialization function within INIT_GLOBAL.

func void MEM_InitRepeat()
-

Tip

It's worth noting that MEM_InitRepeat is also invoked by the MEM_InitAll function.

Syntax

Repeat loop has a syntax very similar to the while loop. It also uses end constant as an ending brace. break and continue statements can be used within it as well. The main difference is the main loop function Repeat that has following properties:

func void Repeat(var int variable, var int limit)
-
  • var int variable
    A variable that increase with every loop iteration.
  • var int limit
    A variable that defines the number of loop iterations. If variable >= limit the loop is exited.

Repeat loop flowchart

flowchart TD
-    A(Start) --> B["Repeat(i, limit)"] 
-    B --> C{i < limit}
-    C -->|true| D[Command]
-    D --> |i = i + 1| B
-    C --> |false| E(End)
Repeat loop
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
func void Repeat_test() {
-    Repeat(i, 4); var int i; //{
-        MEM_Debug(IntToString(i));
-    end; //}
-};
-
-//  Results:
-//  Info:  0 Q:     Debug: 0
-//  Info:  0 Q:     Debug: 1
-//  Info:  0 Q:     Debug: 2
-//  Info:  0 Q:     Debug: 3
-

Examples

The following code outputs the numbers from 0 to 42:

1
-2
-3
-4
-5
-6
-7
func void foo() {
-    Repeat(count, 43); var int count; //{
-        Print (ConcatStrings ("COUNT: ", IntToString (count)));
-    end; //}
-
-    /* Once 43 is reached, the loop is exited. */
-}; 
-

The following code should enumerate all pairs (x,y) with 0 <= x < max_x, 0 <= y < max_y

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
func void printpairs(var int max_x, var int max_y)
-{
-    // PrintDebug should be used, i.e. activate debug output
-    MEM_SetShowDebug (1);
-
-    var int x; var int y; x = 0;
-
-    Repeat(x, max_x); //{
-        y = 0;
-        Repeat(y, max_y); //{  
-            var string out; out = "(";
-            out = ConcatStrings (out, IntToString (x));
-            out = ConcatStrings (out, ", ");
-            out = ConcatStrings (out, IntToString (y));
-            out = ConcatStrings (out, ")");
-            PrintDebug (out);
-        end; //}
-    end; //}
-};
-
-/*
-    Output of a call printpairs(4,2) would then be: 
-    00:36 Info: 5 U: Skript: (0, 0) .... 
-    00:36 Info: 5 U: Skript: (0, 1) .... 
-    00:36 Info: 5 U: Skript: (1, 0) .... 
-    00:36 Info: 5 U: Skript: (1, 1) .... 
-    00:36 Info: 5 U: Skript: (2, 0) .... 
-    00:36 Info: 5 U: Skript: (2, 1) .... 
-    00:36 Info: 5 U: Skript: (3, 0) .... 
-    00:36 Info: 5 U: Skript: (3, 1) .... 
-*/
-
\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/ikarus/functions/keyboard/index.html b/pl/zengin/scripts/extenders/ikarus/functions/keyboard/index.html deleted file mode 100644 index f930c343c6..0000000000 --- a/pl/zengin/scripts/extenders/ikarus/functions/keyboard/index.html +++ /dev/null @@ -1,38 +0,0 @@ - Keyboard - Gothic Modding Community

Keyboard interaction

This part of Ikarus implements function that make interaction with keyboard possible.

Info

Keyboard interaction is also implemented with gameKeyEvents.d

Initialization

The best way to initialize all Ikarus functions is to call MEM_InitAll() in the Init_Global() initialization function.

Warning

If you want to use Ikarus in Gothic 1, it is best to define your own Init_Global() function and call it from every world initialization function.

MEM_InitAll();
-

Implementation

Ikarus.d on GitHub

Functions

Tip

Different players use different keys for specific actions! However, it is possible to get key assigned to the action from Gothic.ini. See Ini access.

MEM_KeyPressed

Checks if the key is hold right at the moment of function call.

func int MEM_KeyPressed(var int key)
-
Parameters
  • var int key
    Checked key

Return value

The function returns TRUE if the key is hold, FALSE is returned otherwise.

MEM_KeyState

Returns the state of the key.

func int MEM_KeyState(var int key)
-
Parameters
  • var int key
    Checked key

Return value

The function returns actual key state.

Key states

  • KEY_UP - The key is not pressed and was not pressed before. ("not pressed")
  • KEY_PRESSED - The key is pressed and was not previously pressed. ("new pressed")
  • KEY_HOLD - The key is pressed and was also pressed before. ("still pressed")
  • KEY_RELEASED - The key is not pressed and was previously pressed. ("let go")

KEY_PRESSED or KEY_RELEASED will be returned if the state of the key has changed since the last query.

KEY_UP or KEY_HOLD are returned if the state has not changed.

MEM_InsertKeyEvent

Makes the game think that the key was pressed.

func void MEM_InsertKeyEvent(var int key)
-
Parameters
  • var int key
    Key to be "pressed"
\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/ikarus/functions/mem_access/index.html b/pl/zengin/scripts/extenders/ikarus/functions/mem_access/index.html deleted file mode 100644 index ac0213c57b..0000000000 --- a/pl/zengin/scripts/extenders/ikarus/functions/mem_access/index.html +++ /dev/null @@ -1,53 +0,0 @@ - Memory Access - Gothic Modding Community

Elementary memory access

This part of Ikarus makes it possible to read and write memory as different data types - integers, strings, arrays of integers or strings and bytes.

If address <= 0, an error is thrown. Otherwise, an attempt is made to read or write at this address. If the address falls into invalid range, for example in a code segment, access violation will occur (Gothic crashes). In the case of string operations, it is also necessary that at the specified position a valid zString already exists.

Initialization

The best way to initialize all Ikarus functions is to call MEM_InitAll() in the Init_Global() initialization function.

Warning

If you want to use Ikarus in Gothic 1, it is best to define your own Init_Global() function and call it from every world initialization function.

MEM_InitAll();
-

Implementation

Ikarus.d on GitHub

Read functions

MEM_ReadInt

Reads int from the address.

func int MEM_ReadInt(var int address)
-
Parameters
  • var int address
    Memory address to read from

Return value

The function returns an integer value if the address is correct.

MEM_ReadString

Reads string from the address.

func string MEM_ReadString(var int address)
-
Parameters
  • var int address
    Memory address to read from

Return value

The function returns string if the address is correct.

MEM_ReadByte

Reads byte from the address.

func int MEM_ReadByte(var int address)
-
Parameters
  • var int address
    Memory address to read from

Return value

The function returns byte value if the address is correct.

MEM_ReadIntArray

Reads int from the array at the arrayAddress.

func int MEM_ReadIntArray(var int arrayAddress, var int offset)
-
Parameters
  • var int arrayAddress
    Memory address of array
  • var int offset
    Array offset (array index)

Return value

The function returns integer value from the array if the address is correct.

MEM_ReadStringArray

Info

MEM_ReadStringArray has been already moved to the LeGo PermMem package.

MEM_ReadByteArray

Reads byte from the array at the arrayAddress.

func int MEM_ReadByteArray(var int arrayAddress, var int offset)
-
Parameters
  • var int arrayAddress
    Memory address of array
  • var int offset
    Array offset (array index)

Return value

The function returns byte from the array if the address is correct.

Write functions

MEM_WriteInt

Writes int value in the address.

func void MEM_WriteInt(var int address, var int value)
-
Parameters
  • var int address
    Memory address to write into
  • var int value
    Integer value to write
Example

An example of using this function is the following Ikarus function, which turns debugging messages on and off:

1
-2
-3
-4
func void MEM_SetShowDebug(var int on)
-{
-    MEM_WriteInt(showDebugAddress, on);
-};
-

MEM_WriteString

Writes string in the address.

func void MEM_WriteString(var int address, var string value)
-
Parameters
  • var int address
    Memory address to write into
  • var int value
    String to write

MEM_WriteByte

Only the byte at address address is changed here, not a whole four-byte word. That is, the three subsequent bytes remain untouched. If 0 <= val < 256 does not apply in MEM_WriteByte, a warning is issued and val is trimmed accordingly. In particular, shouldn't be negative numbers are passed.

func void MEM_WriteByte(var int address, var int value)
-
Parameters
  • var int address
    Memory address to write into
  • var int value
    Byte to write

MEM_WriteIntArray

Writes int value in the array at arrayAddress.

func void MEM_WriteIntArray(var int arrayAddress, var int offset, var int value)
-
Parameters
  • var int arrayAddress
    Memory address of array
  • var int offset
    Array offset (array index)
  • var int value
    Integer value to write

MEM_WriteStringArray

Writes string value in the array at arrayAddress.

func void MEM_WriteStringArray(var int arrayAddress, var int offset, var string value)
-
Parameters
  • var int arrayAddress
    Memory address of array
  • var int offset
    Array offset (array index)
  • var string value
    String to write

MEM_WriteByteArray

Writes byte value in the array at arrayAddress.

func void MEM_WriteByteArray(var int arrayAddress, var int offset, var int value)
-
Parameters
  • var int arrayAddress
    Memory address of array
  • var int offset
    Array offset (array index)
  • var int value
    Byte to write
\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/ikarus/functions/mem_utility/index.html b/pl/zengin/scripts/extenders/ikarus/functions/mem_utility/index.html deleted file mode 100644 index 2c608fc0ed..0000000000 --- a/pl/zengin/scripts/extenders/ikarus/functions/mem_utility/index.html +++ /dev/null @@ -1,48 +0,0 @@ - Memory utility - Gothic Modding Community

Memory utility

Ikarus utility functions, for memory management and manipulation.

Initialization

The best way to initialize all Ikarus functions is to call MEM_InitAll() in the Init_Global() initialization function.

Warning

If you want to use Ikarus in Gothic 1, it is best to define your own Init_Global() function and call it from every world initialization function.

MEM_InitAll();
-

Implementation

Ikarus.d on GitHub

Functions

MEM_Alloc

Allocates a specified amount of memory and returns a pointer to the allocated memory area.

Danger

Gothic does not and cannot retain a reference to this memory area or release it, even when destroying the session. Therefore, memory should only be reserved under certain conditions:

  • It is guaranteed to exist and can be released again with MEM_Free after loading a save game.
  • Gothic is aware of this memory area and independently releases it.

It might be possible to create new objects with this function and permanently integrate them into the object structure of Gothic. However, extreme caution is advised, as object structures cannot be used, and manual handling is required.

This function is well-suited for building small elements like list items and integrating them into existing lists. The memory allocated by this function is always initialized to zero.

func int MEM_Alloc(var int amount)
-
Parameters
  • var int amount
    The amount of bytes to allocate

Return value

The function returns a pointer to the allocated memory area.

MEM_Realloc

Allocates a memory area of ​​size newsize and returns a pointer to this memory area. The memory area from location ptr is released.

If newsize >= oldsize, the first oldsize bytes from the old memory area are transferred to the new one. The additional memory is initialized with zero.

If newsize <= oldsize, all bytes of the new memory area are initialized with the corresponding values ​​of the old memory area.

This function is intended to create an allocated memory area enlarge or reduce. Existing data remains naturally way received.

func int MEM_Realloc(var int ptr, var int oldsize, var int newsize)
-
Parameters
  • var int ptr
    The original pointer to the memory block
  • var int oldsize
    The size of the original memory block
  • var int newsize
    The size of the new memory block

Return value

The function returns a pointer to the modified memory area.

MEM_Free

Releases an allocated memory area.

Danger

Great caution is advised, especially when attempting to destroy engine objects, as no destructors are called!

Releasing small things such as list elements can be done easily.

func void MEM_Free(var int ptr)
-
Parameters
  • var int ptr
    Pointer to the released memory block

MEM_Copy

Copies a specified number of words from the source address to the destination address.

func void MEM_Copy(var int src, var int dst, var int wordcount)
-
Parameters
  • var int src
    The source address to copy from
  • var int dst
    The destination address to copy to
  • var int wordCount
    The number of words to copy

MEM_CopyWords

Alias to MEM_Copy. Copies a specified number of words from the source address to the destination address.

func void MEM_CopyWords(var int src, var int dst, var int wordcount) 
-
Parameters
  • var int src
    The source address to copy from
  • var int dst
    The destination address to copy to
  • var int wordCount
    The number of words to copy

MEM_CopyBytes

Copies a specified number of bytes from the source address to the destination address

func void MEM_CopyBytes(var int src, var int dst, var int byteCount)
-
Parameters
  • var int src
    The source address to copy from
  • var int dst
    The destination address to copy to
  • var int byteCount
    The number of bytes to copy

MEM_Swap

Swaps a specified number of words between the source address and the destination address.

func void MEM_Swap(var int src, var int dst, var int wordCount)
-
Parameters
  • var int src
    The source address to swap from
  • var int dst
    The destination address to swap to
  • var int wordCount
    The number of words to swap

MEM_SwapWords

Alias to MEM_Swap. Swaps a specified number of words between the source address and the destination address.

func void MEM_SwapWords(var int src, var int dst, var int wordCount)
-
Parameters
  • var int src
    The source address to swap from
  • var int dst
    The destination address to swap to
  • var int wordCount
    The number of words to swap

MEM_SwapBytes

Swaps a specified number of bytes between the source address and the destination address.

func void MEM_SwapBytes(var int src, var int dst, var int byteCount)
-
Parameters
  • var int src
    The source address to swap from
  • var int dst
    The destination address to swap to
  • var int byteCount
    The number of bytes to swap

MEM_Clear

Sets a specified number of bytes in memory to zero.

func void MEM_Clear(var int ptr, var int size)
-
Parameters
  • var int ptr
    The memory address to start clearing from
  • var int size
    The number of bytes to clear

MEM_Compare

Compares a specified number of words between two memory blocks.

func int MEM_Compare(var int ptr0, var int ptr1, var int wordCount)
-
Parameters
  • var int ptr0
    The first memory block to compare
  • var int ptr1
    The second memory block to compare
  • var int wordCount
    The number of words to compare

Return value

The function returns TRUE if the memory blocks are equal, FALSE is returned otherwise.

MEM_CompareWords

Alias to MEM_Compare. Compares a specified number of words between two memory blocks.

func int MEM_CompareWords(var int ptr0, var int ptr1, var int wordCount)
-
Parameters
  • var int ptr0
    The first memory block to compare
  • var int ptr1
    The second memory block to compare
  • var int wordCount
    The number of words to compare

Return value

The function returns TRUE if the memory blocks are equal, FALSE is returned otherwise.

MEM_CompareBytes

Compares a specified number of bytes between two memory blocks.

func int MEM_CompareBytes(var int ptr1, var int ptr2, var int byteCount)
-
Parameters
  • var int ptr0
    The first memory block to compare
  • var int ptr1
    The second memory block to compare
  • var int wordCount
    The number of bytes to compare

Return value

The function returns TRUE if the memory blocks are equal, FALSE is returned otherwise.

\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/ikarus/functions/menu_access/index.html b/pl/zengin/scripts/extenders/ikarus/functions/menu_access/index.html deleted file mode 100644 index eeaf249bfa..0000000000 --- a/pl/zengin/scripts/extenders/ikarus/functions/menu_access/index.html +++ /dev/null @@ -1,37 +0,0 @@ - Access Menu Objects - Gothic Modding Community

Access Menu Objects

These Ikarus functions are intended to provide and simplify access to menu items (e.g. in the character menu).

Tip

Some menus are generated every time they are used, while others are generated once and then kept. For example, a character menu is only available after it was opened for the first time, after that it is kept in memory. Depending on what you actually want to do, it can make sense to introduce changes in the menu scripts.

Initialization

The best way to initialize all Ikarus functions is to call MEM_InitAll() in the Init_Global() initialization function.

Warning

If you want to use Ikarus in Gothic 1, it is best to define your own Init_Global() function and call it from every world initialization function.

MEM_InitAll();
-

Implementation

Ikarus.d on GitHub

Functions

MEM_GetMenuByString

func int MEM_GetMenuByString(var string menuName)
-

Parameters

  • var string menuName
    Name of the Gothic menu e.g. MENU_STATUS

Return value

The function returns the address of the menu if a menu with this name exists, null otherwise.

MEM_GetMenuItemByString

func int MEM_GetMenuItemByString(var string menuItemName)
-

Parameters

  • var string menuItemName
    Name of the Gothic menu item e.g. MENU_ITEM_PLAYERGUILD_TITLE

Return value

The function returns the address of the menu item if a menu item with this name exists, null otherwise.

\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/ikarus/functions/objects/index.html b/pl/zengin/scripts/extenders/ikarus/functions/objects/index.html deleted file mode 100644 index 072051cb06..0000000000 --- a/pl/zengin/scripts/extenders/ikarus/functions/objects/index.html +++ /dev/null @@ -1,155 +0,0 @@ - zCObjects - Gothic Modding Community

zCObjects

Set of functions for working with zCObject and its subclasses instances.

Initialization

The best way to initialize all Ikarus functions is to call MEM_InitAll() in the Init_Global() initialization function.

Warning

If you want to use Ikarus in Gothic 1, it is best to define your own Init_Global() function and call it from every world initialization function.

MEM_InitAll();
-

Implementation

Ikarus.d on GitHub

Global instances

Ikarus package introduces the following instances:

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
instance MEM_Game (oCGame);
-instance MEM_World(oWorld);
-instance MEM_Timer(zCTimer);
-instance MEM_WorldTimer(oCWorldTimer);
-instance MEM_Vobtree(zCTree);
-instance MEM_InfoMan(oCInfoManager);
-instance MEM_InformationMan (oCInformationManager);
-instance MEM_Waynet(zCWaynet);
-instance MEM_Camera(zCCamera);
-instance MEM_SkyController(zCSkyController_Outdoor);
-instance MEM_SpawnManager (oCSpawnManager);
-instance MEM_GameMananger (CGameManager);
-instance MEM_GameManager (CGameManager);
-instance MEM_Parser(zCParser);
-

The classes used here all have one thing in common: there is a maximum of one object of them at the same time (e.g. there is not two worlds or two sky at the same time).

MEM_InitGlobalInst function sets the offsets of these instances to the corresponding unique object. While it has been called, all of the above instances can be used.

MEM_InitGlobalInst

Initializes global instances of commonly used objects in the game (is called by the MEM_InitAll function).

func void MEM_InitGlobalInst()
-

Warning

MEM_InitGlobalInst must be executed once after loading a savegame. The easiest way is do it is to call this function from INIT_GLOBAL.

Functions

About zCClassDef

For every class (derived from zCObject) there is an "administrative object" of type zCClassDef. This encapsulates some useful information about all objects in this class.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
class zCClassDef {
-    var string className;            //zSTRING
-    var string baseClassName;        //zSTRING
-    var string scriptClassName;      //zSTRING
-    var int baseClassDef;            //zCClassDef*
-    var int createNewInstance;       //zCObject* ( *) (void) 
-    var int createNewInstanceBackup; //zCObject* ( *) (void)
-    var int classFlags;              //zDWORD
-    var int classSize;               //zDWORD
-    var int numLivingObjects;
-    var int numCtorCalled;
-    var int hashTable;               //zCObject**
-    var int objectList_array;        //zCObject**
-    var int objectList_numAlloc;     //int
-    var int objectList_numInArray;   //int
-    var int bitfield;
-};
-

Full Ikarus definition of this class, with members description can be found in Misc.d file. The class is same for G1 and G2A engines.

MEM_GetClassDef

Returns a pointer to the zCClassDef of the object. For more info see the About zCClassDef section above.

Passing these functions a pointer that does not point to a zCObject will most likely result in a crash lead.

func int MEM_GetClassDef(var int objPtr)
-
Parameters
  • var int objPtr
    A pointer to the object whose class definition is to be retrieved

Return value

The function returns a pointer to the zCClassDef of the object.

Example

This would return a pointer to the zCClassDef object that belongs to the oCNpc class.

1
-2
-3
-4
-5
func int example1
-{
-    var int her; her = MEM_InstToPtr(hero);
-    return MEM_GetClassDef(her);
-};
-

MEM_GetClassName

This function returns the name of the class to which an object belongs.

func string MEM_GetClassName(var int objPtr)
-
Parameters
  • var int objPtr
    A pointer to the object whose class name is to be retrieved

Return value

The function returns the objects class name as a string, if the object is invalid an empty string is returned.

Example

This would return a name of the oCNpc class as a string.

1
-2
-3
-4
-5
-6
func string example2
-{
-    var int her; her = MEM_InstToPtr(hero);
-    return MEM_GetClassName(her);
-};
-// return: "oCNpc"
-

MEM_CheckInheritance

Checks if an object is derived from a specific class definition.

func int MEM_CheckInheritance(var int objPtr, var int classDef)
-
Parameters
  • var int objPtr
    A pointer to the object to be checked
  • var int classDef
    A pointer to the class definition to check against

Return value

The function returns TRUE if the object is derived from the specified class definition, FALSE is returned otherwise.

Hlp_Is_*

In addition MEM_CheckInheritance function has some overloads with hardcoded classDef parameter.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
func int Hlp_Is_oCMobFire(var int ptr){};
-func int Hlp_Is_zCMover(var int ptr){};
-func int Hlp_Is_oCMob(var int ptr){};
-func int Hlp_Is_oCMobInter(var int ptr){};
-func int Hlp_Is_oCMobLockable(var int ptr){};
-func int Hlp_Is_oCMobContainer(var int ptr){};
-func int Hlp_Is_oCMobDoor(var int ptr){};
-func int Hlp_Is_oCMobBed(var int ptr){};
-func int Hlp_Is_oCMobSwitch(var int ptr){};
-func int Hlp_Is_oCMobWheel(var int ptr){};
-func int Hlp_Is_oCMobLadder(var int ptr){};
-func int Hlp_Is_oCNpc(var int ptr){};
-func int Hlp_Is_oCItem(var int ptr){};
-func int Hlp_Is_zCVobLight(var int ptr){};
-

The usage of these functions is probably obvious, they checks if the given object belongs to class given in the function name.

MEM_InsertVob

Inserts a Vob with the visual vis at the waypoint wp. If the visual or waypoint does not exist, this is the behaviour this function undefined.

Note

The inserted Vob is even an oCMob, so it can be given a focus name, for example. But you can treat it like a zCVob), if you don't need the additional properties.

func int MEM_InsertVob(var string vis, var string wp)
-
Parameters
  • var string vis
    Name of the inserted Vob visual ("FAKESCROLL.3DS", "FIRE.PFX", "SNA_BODY.ASC", "CHESTSMALL_NW_POOR_LOCKED.MDS", "ADD_PIRATEFLAG.MMS" etc.)
  • var string wp
    Name of the waypoint to insert Vob on

Return value

The function returns a pointer to the created object.

MEM_DeleteVob

Deletes a specific Vob form world.

func void MEM_DeleteVob(var int vobPtr)
-
Parameters
  • var int vobPtr
    Pointer to a zCVob object to be deleted

MEM_RenameVob

Renames the passed Vob to the newName that is also passed.

The object becomes this first removed from the Vob-hashtable, then unnamed and then again inserted into the Vob-hashtable under a new name.

func void MEM_RenameVob(var int vobPtr, var string newName)
-
Parameters
  • var int vobPtr
    Pointer to a zCVob object to be renamed
  • var string newName
    The new Name of the Vob

MEM_TriggerVob

Sends a trigger message to the Vob.

func void MEM_TriggerVob(var int vobPtr)
-
Parameters
  • var int vobPtr
    Pointer to a triggered zCVob

Danger

If triggering the Vob has immediate effects (even before MEM_TriggerVob is exited), the name of the Vob is corrupted during this time. It is not advisable to rename, trigger again or destroy the object at this moment, the behavior in such cases is untested.

MEM_UntriggerVob

Sends an untrigger message to the Vob.

func void MEM_TriggerVob(var int vobPtr)
-
Parameters
  • var int vobPtr
    Pointer to an untriggered zCVob

Danger

If untriggering the Vob has immediate effects (even before MEM_TriggerVob is exited), the name of the Vob is corrupted during this time. It is not advisable to rename, trigger again or destroy the object at this moment, the behavior in such cases is untested.

MEM_SearchVobByName

Returns the address of a zCVob named str if such a Vob exists.

func int MEM_SearchVobByName(var string str)
-
Parameters
  • var string str
    Name of searched zCVob

Return value

The function returns a pointer to the zCVob if the object with the given name exist. 0 is returned otherwise.

MEM_SearchAllVobsByName

Variation of MEM_SearchVobByName. Creates a zCArray in which all pointers are to Vobs with the name str. If no Vob with the name exists, an empty zCArray is created. A pointer to the created zCArray is then returned. This can be evaluated, but should be released again with MEM_ArrayFree before the end of the frame (before the player can load) to avoid memory leaks.

func int MEM_SearchAllVobsByName(var string str)
-
Parameters
  • var string str
    Name of searched zCVob

Return value

The function returns a pointer to the created zCArray, that contains pointers to the all Vobs with the specified name.

MEM_GetBufferCRC32

Calculates the CRC32 hash value from a byte array starting at the address specified by buf and having a length of buflen.

func int MEM_GetBufferCRC32(var int buf, var int buflen)
-
Parameters
  • var int buf
    Address of a byte array, the hash calculation will begin from

  • var int buflen
    The length of the byte array starting from the address specified by buf

Return value

The function returns the calculated CRC32 hash value.

MEM_GetStringHash

Calculates the CRC32 hash value for a string.

func int MEM_GetStringHash(var string str)
-
Parameters
  • var string str
    A string for which the hash value is to be calculated

Return value

The function returns an integer representing the calculated hash value for the input string.

\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/ikarus/functions/parser/index.html b/pl/zengin/scripts/extenders/ikarus/functions/parser/index.html deleted file mode 100644 index 3c18489294..0000000000 --- a/pl/zengin/scripts/extenders/ikarus/functions/parser/index.html +++ /dev/null @@ -1,110 +0,0 @@ - Parser stuff - Gothic Modding Community

zCParser related functions

This Ikarus part provides some useful functions to work with parser, its instances, symbols and stack.

Danger

Remember to always assign an instance to a correct class. If you assign an oCNpc pointer to oCItem class you won't be able to read any data from it.

Implementation

Ikarus.d on GitHub

Initialization

The best way to initialize all Ikarus functions is to call MEM_InitAll() in the Init_Global() initialization function.

Warning

If you want to use Ikarus in Gothic 1, it is best to define your own Init_Global() function and call it from every world initialization function.

MEM_InitAll();
-

MEM_ReinitParser

Parser operations are initialized with this function.

func void MEM_ReinitParser()
-

Tip

It's worth noting that MEM_ReinitParser is also invoked by the MEM_InitAll function.

Pointers and instances

MEM_PtrToInst

Returns an instance pointed to by the pointer. If the pointer is null an error is thrown.

func MEMINT_HelperClass MEM_PtrToInst(var int ptr)
-
Parameters
  • var int ptr
    Pointer to return an instance from

Shortcut

In addition there is a function _^ with the same signature and functionality as MEM_PtrToInst. It is used as a shortcut, since the converting pointer to instance is commonly used while working with Ikarus.

func MEMINT_HelperClass _^ (var int ptr)
-
Example

Following code

var oCNpc her; her = MEM_PtrToInst(heroPtr);
-
is equivalent to
var oCNpc her; her = _^(heroPtr);
-

MEM_NullToInst

Returns an instance from a null pointer.

func MEMINT_HelperClass MEM_NullToInst()
-

MEM_AssignInst

Takes an instance from a pointer and assigns it to a given instance. If the pointer is null an error is thrown.

func void MEM_AssignInst(var int inst, var int ptr)
-
Parameters
  • var int ptr
    Pointer to assign an instance from
  • var int inst
    Instance to which the pointer will be assigned
Example

Following code

1
-2
var oCNpc inst;
-MEM_AssignInst (inst, ptr); 
-
is equivalent to
1
-2
var oCNpc inst;
-inst = MEM_PtrToInst(ptr);
-

MEM_AssignInstNull

Assigns null pointer to a given instance.

func void MEM_AssignInstNull(var int inst)
-
Parameters
  • var int inst
    Instance to which the null pointer will be assigned

MEM_InstToPtr

Returns a pointer to given instance.

func int MEM_InstToPtr(var int inst)
-
Parameters
  • var int inst
    The instance to which the pointer is returned

MEM_InstGetOffset

Alias to MEM_InstToPtr. Returns a pointer to given instance.

func int MEM_InstGetOffset(var int inst)
-
Parameters
  • var int inst
    The instance to which the pointer is returned

MEM_CpyInst

Returns a copy of a given instance

func MEMINT_HelperClass MEM_CpyInst(var int inst)
-
Parameters
  • var int inst
    Instance to copy
example

Following code

selfCopy = MEM_CpyInst (self);
-
is equivalent to
selfCopy = MEM_PtrToInst (MEM_InstToPtr (self));
-

Call function

You don't always know at compile time when you want to call which function. For example, if you want to call the condition function of a mob that the player has in focus, you are at a loss at compile time because you have no idea which mob the player will choose. Ikarus provides a way to call functions based on their name or symbol index. In the example of the mob, the name of the condition function can simply be looked up in the mob.

Note

The functions below also work for externals without any restrictions.

Passing Parameters

If the function to be called has parameters, these must first be placed on the data stack. The parameters must be pushed in the correct order, from left to right.

MEM_PushIntParam

Passes an integer as a parameter to the called function.

func void MEM_PushIntParam (var int param)
-
Parameters
  • var int param
    Integer to pass as a function parameter

MEM_PushInstParam

Passes an instance as a parameter to the called function.

func void MEM_PushInstParam (var int inst)
-
Parameters
  • var int inst
    Instance to pass as a function parameter

MEM_PushStringParam

Passes a string as a parameter to the called function.

func void MEM_PushStringParam (var string str)
-
Parameters
  • var string str
    String to pass as a function parameter

The call

MEM_Call

Calls a function.

func void MEM_Call(var func fnc)
-
Parameters
  • var func fnc
    Function to be called

MEM_CallByID

Calls a function by its ID.

func void MEM_CallByID (var int symbID)
-
Parameters
  • var int symbID
    The ID of the function to be called

MEM_CallByPtr

Calls a function by its pointer.

func void MEM_CallByPtr(var int ptr)
-
Parameters
  • var int ptr
    The pointer of the function to be called

MEM_CallByOffset

Calls a function by its offset.

func void MEM_CallByOffset(var int offset)
-
Parameters
  • var int offset
    The offset of the function to be called

MEM_CallByString

Calls a function by its name.

func void MEM_CallByString (var string fnc)
-
Parameters
  • var string fnc
    The name of the function IN CAPITAL LETTERS.

Return value

If a function has a return value, it should be fetched from the data stack after it is called, otherwise stack overflows can occur under unfavorable circumstances (aside from that, you may simply want the return value because it contains important information).

MEM_PopIntResult

Retrieves an integer returned by the called function.

func int MEM_PopIntResult()
-
Return value

The function returns an integer returned by the previously called script function.

MEM_PopStringResult

Retrieves a daedalus string returned by the called function.

func string MEM_PopStringResult()
-
Return value

The function returns a string returned by the previously called script function.

MEM_PopInstResult

Retrieves an instance returned by the called function.

func MEMINT_HelperClass MEM_PopInstResult()
-
Return value

The function returns an instance returned by the previously called script function.

Function stuff

MEM_GetFuncID

Returns the ID of the given function.

func int MEM_GetFuncID(var func fnc)
-
Parameters
  • var func fnc
    The function whose ID is returned

MEM_GetFuncPtr

Returns the pointer of the given function.

func int MEM_GetFuncPtr(var func fnc)
-
Parameters
  • var func fnc
    The function whose pointer is returned

MEM_GetFuncOffset

Returns the offset of the given function.

func int MEM_GetFuncOffset(var func fnc)
-
Parameters
  • var func fnc
    The function whose offset is returned

MEM_GetFuncIDByOffset

MEM_GetFuncID, but with an offset as a parameter.

func int MEM_GetFuncIDByOffset(var int offset)
-
Parameters
  • var int offset
    Offset of a function whose ID is returned

Return value

The function returns an ID of a function with a given offset.

MEM_ReplaceFunc

Replaces the f1 function with f2 function so if you call the first function, the second function is called.

func void MEM_ReplaceFunc(var func f1, var func f2)
-
Parameters
  • var func f1
    Function to replace
  • var func f2
    Function called instead of f1

Parser stack

MEM_GetFrameBoundary

Returns the address/pointer to the boundary of a stack frame (ESP).

func int MEM_GetFrameBoundary()
-

MEM_GetCallerStackPos

Retrieves the stack position (pop position) of the caller's caller (look at the example for better understanding).

func int MEM_GetCallerStackPos()
-
Return value

The function returns an integer representing the stack position of the caller's caller.

Example

After calling B() from within A(), when MEM_GetCallerStackPos() is invoked in function B(), it retrieves the stack position of the caller's caller, which is function A() in this case. Therefore, the variable adr will contain the stack position of function A().

1
-2
-3
-4
-5
-6
-7
-8
func void A(){
-    B();
-};
-
-func void B(){
-    int adr; adr = MEM_GetCallerStackPos();
-    // Now, 'adr' will contain the stack position of A.
-};
-

MEM_SetCallerStackPos

Sets the stack position (pop position) of the caller's caller.

func void MEM_SetCallerStackPos(var int popPos)
-
Parameters
  • var int popPos
    An integer parameter representing the new stack position of the caller's caller

Get address

MEM_GetAddress_Init

Initializes the MEM_GetIntAddress, MEM_GetFloatAddress and MEM_GetStringAddress functions.

func void MEM_GetAddress_Init()
-

Tip

It's worth noting that MEM_GetAddress_Init is also invoked by the MEM_InitAll function.

MEM_GetIntAddress

Returns an address of a given integer.

func int MEM_GetIntAddress(var int i)
-
Parameters
  • var int i
    Integer whose address is returned

Shortcut

In addition there is a function _@ with the same signature and functionality as MEM_GetIntAddress.

func int _@(var int i)
-

MEM_GetFloatAddress

Returns an address of a given daedalus float.

func int MEM_GetFloatAddress(var float f)
-
Parameters
  • var float f
    Float whose address is returned

Shortcut

In addition there is a function _@f with the same signature and functionality as MEM_GetFloatAddress.

func int _@s(var string s)
-

MEM_GetStringAddress

Returns an address of a given string.

func int MEM_GetStringAddress(var string s)
-
Parameters
  • var string s
    String whose address is returned

Shortcut

In addition there is a function _@s with the same signature and functionality as MEM_GetStringAddress.

func int _@s(var string s)
-

STR_GetAddressInit

Alias to MEM_GetAddress_Init, kept for downward compatibility.

func void STR_GetAddressInit()
-

STR_GetAddress

Function similar to MEM_GetStringAddress. There is a guarantee, that this function works initialized i.e. invokes MEM_GetAddress_Init, but the first time may only return an address of a copy of the string.

func int STR_GetAddress(var string str)
-

Static arrays

Accessing static arrays like this below is very tedious in Daedalus.

var int myStaticArray[42];
-
It is not possible to access myStaticArray[i] with a variable index i, but only with a constant. This changes with the following functions.

Danger

Neither function performs any kind of validity check. If the value passed is not an array or offsets are beyond the boundaries of the array passed, the behavior is undefined.

MEM_InitStatArrs

Initializes static arrays read and write functions.

func void MEM_InitStatArrs()
-

MEM_WriteStatArr

Changes the value at the offset of a static integer-array.

func void MEM_WriteStatArr (var int array, var int offset, var int value)
-
Parameters
  • var int array
    Array which will be edited
  • var int offset
    Array index at which value will be edited
  • var int value
    The new value

MEM_ReadStatArr

Reads the value at the specific offset of a static integer-array.

func int MEM_ReadStatArr (var int array, var int offset)
-
Parameters
  • var int array
    Array to get a value from
  • var int offset
    Array index of the value to return

Return value

The function returns an integer value from the offset of a given static array.

MEM_WriteStatStringArr

Changes the value at the offset of a static string-array.

func void MEM_WriteStatStringArr(var string array, var int offset, var string value)
-
Parameters
  • var string array
    Array which will be edited
  • var int offset
    Array index at which value will be edited
  • var string value
    The new value

MEM_ReadStatStringArr

Reads the value at the specific offset of a static string-array.

func string MEM_ReadStatStringArr(var string array, var int offset)
-
Parameters
  • var string array
    Array to get a value from
  • var int offset
    Array index of the value to return

Return value

The function returns a string form the offset of a given static array.

Parser symbol

MEM_SetCurrParserSymb

Makes currParserSymb point to the symbol of the specified instance.

func void MEM_SetCurrParserSymb (var int inst)
-
Parameters
  • var int inst
    Instance to whose symbol currParserSymb will be set

currParserSymb

An instance representing current parser symbol.

INSTANCE currParserSymb (zCPar_Symbol);
-

MEM_FindParserSymbol

Returns the index of the parser symbol with name inst if such a symbol exists.

func int MEM_FindParserSymbol(var string inst)
-
Parameters
  • var string inst
    Name of the symbol to be found

Return value

The function returns the index of the parser symbol with name inst if such a symbol exists. If non exists, a warning is issued and -1 is returned.

MEM_GetSymbolIndex

Alias to MEM_FindParserSymbol. Returns the index of the parser symbol with name inst if such a symbol exists.

func int MEM_GetSymbolIndex(var string inst)
-
Parameters
  • var string inst
    Name of the symbol to be found

Return value

The function returns the index of the parser symbol with name inst if such a symbol exists. If non exists, a warning is issued and -1 is returned.

MEM_GetParserSymbol

Looks for the parser symbol with the name inst and returns a pointer to the appropriate zCPar_Symbol structure.

func int MEM_GetParserSymbol (var string inst)
-
Parameters
  • var string inst
    Name of the symbol to be found

Return value

The function returns the appropriate zCPar_Symbol structure of the parser symbol with name inst if such a symbol exists. If non exists, a warning is issued and 0 is returned.

MEM_GetSymbol

Alias to MEM_GetParserSymbol. Looks for the parser symbol with the name inst and returns a pointer to the appropriate zCPar_Symbol structure.

func int MEM_GetSymbol(var string inst)
-
Parameters
  • var string inst
    Name of the symbol to be found

Return value

The function returns the appropriate zCPar_Symbol structure of the parser symbol with name inst if such a symbol exists. If non exists, a warning is issued and 0 is returned.

MEM_GetSymbolByIndex

MEM_GetParserSymbol, but with ID (index) as a parameter.

func int MEM_GetSymbolByIndex(var int id)
-
Parameters
  • var string inst
    ID (index) of the symbol to be found

Return value

The function returns the appropriate zCPar_Symbol structure of the parser symbol with name inst if such a symbol exists. If non exists, a warning is issued and 0 is returned.

\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/ikarus/functions/preamble/index.html b/pl/zengin/scripts/extenders/ikarus/functions/preamble/index.html deleted file mode 100644 index 618f78c987..0000000000 --- a/pl/zengin/scripts/extenders/ikarus/functions/preamble/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/pl/zengin/scripts/extenders/ikarus/functions/string/index.html b/pl/zengin/scripts/extenders/ikarus/functions/string/index.html deleted file mode 100644 index 6ed6f06d6b..0000000000 --- a/pl/zengin/scripts/extenders/ikarus/functions/string/index.html +++ /dev/null @@ -1,138 +0,0 @@ - String operations - Gothic Modding Community

String operations

Collection of Ikarus functions to manipulate and format strings.

Initialization

The best way to initialize all Ikarus functions is to call MEM_InitAll() in the Init_Global() initialization function.

Warning

If you want to use Ikarus in Gothic 1, it is best to define your own Init_Global() function and call it from every world initialization function.

MEM_InitAll();
-

Implementation

Ikarus.d on GitHub

Functions

STR_GetCharAt

Returns the ASCII value of a character at a specific position in a string.

func int STR_GetCharAt (var string str, var int pos)
-
Parameters
  • var string str
    The input string
  • var int pos
    The position of the character

Return value

The function returns the ASCII value of the character at the specified position.

STR_Len

Returns the length of a string.

func int STR_Len (var string str)
-
Parameters
  • var string str
    The input string

Return value

The function returns the length of the string in characters.

STR_toChar

Converts a string to a pointer to its character array.

func int STR_toChar (var string str)
-
Parameters
  • var string str
    The input string

Return value

The function returns a pointer to the character array representing the input string str

STR_FromChar

Converts a character array to a string.

func string STR_FromChar(var int char)
-
Parameters
  • var int char
    Pointer to the character array

Return value

The function returns a string representation of the character array.

STR_SubStr

Extracts a substring from a given string.

func string STR_SubStr (var string str, var int start, var int count)
-
Parameters
  • var string str
    The input string
  • var int start
    The starting position of the substring
  • var int count
    The length of the substring

Return value

The function returns a substring, if the starting position is invalid an empty string is returned.

STR_Prefix

Extracts a prefix of a given string, similar to STR_SubStr, but with the starting position set to the first character of the string.

func string STR_Prefix (var string str, var int len)
-
Parameters
  • var string str
    The input string
  • var int count
    The length of the prefix

Return value

The function returns a prefix of the input string with the specified length.

STR_Compare

Compares two strings lexicographically and returns a result indicating their relative order.

func int STR_Compare(var string str1, var string str2)
-
Parameters
  • var string str1 The first string to compare
  • var string str2 The second string to compare

Return Value

The function returns an integer value representing the result of the comparison:

  • STR_GREATER (1): If str1 comes lexicographically after str2.
  • STR_EQUAL (0): If str1 is lexicographically equal to str2.
  • STR_SMALLER (-1): If str1 comes lexicographically before str2.
Examples

The comparison is based on lexicographic order, which is the order of characters as they appear in the ASCII table. Uppercase letters come before lowercase letters.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
int result1 = STR_Compare("A", "B");
-// The 'result1' variable now contains STR_SMALLER
-
-int result2 = STR_Compare("ABC", "ABC");
-// The 'result2' variable now contains STR_EQUAL
-
-int result3 = STR_Compare("AA", "A");
-// The 'result3' variable now contains STR_GREATER
-
-int result4 = STR_Compare("BA", "BB");
-// The 'result4' variable now contains STR_SMALLER
-
-int result5 = STR_Compare("B", "a");
-// The 'result5' variable now contains STR_SMALLER
-
-int result6 = STR_Compare("A", "");
-// The 'result6' variable now contains STR_GREATER
-

STR_ToInt

Converts a string to an integer.

func int STR_ToInt (var string str)
-
Parameters
  • var string str
    The input string

Return Value

The function returns an integer value of the string, if a string is invalid (doesn't contain an integer) zero is returned.

STR_IndexOf

Searches for a substring tok within a given string and returns the index of the first occurrence of tok, taking into account upper and lower case letters.

func int STR_IndexOf(var string str, var string tok)
-
Parameters
  • var string str
    The string in which to search for tok.
  • var string tok
    The substring to search for within str.

Return Value

The function returns the index at which the first occurrence of tok begins within str. If tok is not found in str, the function returns -1.

Examples
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
int index1 = STR_IndexOf("Hello World!", "Hell");
-// The 'index1' variable now contains 0
-
-int index2 = STR_IndexOf("Hello World!", "World");
-// The 'index2' variable now contains 6
-
-int index3 = STR_IndexOf("Hello World!", "Cake");
-// The 'index3' variable now contains -1
-
-int index4 = STR_IndexOf("Hello World!", "");
-// The 'index4' variable now contains 0
-
-int index5 = STR_IndexOf("Hello", "Hello World!");
-// The 'index5' variable now contains -1
-
-int index6 = STR_IndexOf("hello Hell!", "Hell");
-// The 'index6' variable now contains 6
-
-int index7 = STR_IndexOf("", "");
-// The 'index7' variable now contains 0
-

STR_SplitCount

Counts the number of parts a string splits into when using a specified separator.

func int STR_SplitCount(var string str, var string separator)
-
Parameters
  • var string str
    The input string to be split.
  • var string separator
    The separator character or string used to split the input string.

Return Value

The function returns a number of parts the input string splits into when using the specified separator.

Example
1
-2
-3
string inputStr = "This is a sentence.";
-int count = STR_SplitCount(inputStr, " ");
-// The 'count' variable now contains 4
-

STR_Split

Splits a string into multiple substrings based on a specified separator and returns the substring at a specified offset.

func string STR_Split(var string str, var string separator, var int offset)
-

Parameters

  • var string str
    The input string to be split.
  • var string separator
    The separator character or string used to split the input string.
  • var int offset
    The index of the substring to be returned after splitting. The index is zero-based.

Return Value

The function returns a substring at the specified offset after splitting the input string. If the offset is greater than or equal to the number of parts generated by splitting, an empty string is returned.

Example

1
-2
-3
-4
-5
-6
-7
func void foo() {
-    string inputStr = "This is a sentence.";
-    string tok1 = STR_Split(inputStr, " ", 0); // This
-    string tok2 = STR_Split(inputStr, " ", 1); // is
-    string tok3 = STR_Split(inputStr, " ", 2); // a
-    string tok4 = STR_Split(inputStr, " ", 3); // sentence
-};
-
At the end of the function, tok1 contains "This", tok2 contains "is", tok3 contains "a", and tok4 contains "sentence.".

STR_Upper

Converts a string to uppercase.

func string STR_Upper(var string str)
-
Parameters
  • var string str
    The input string

Return Value

The function returns a copy of str with all uppercase letters converted to their corresponding uppercase letters.

STR_Lower

Converts a string to lowercase.

func string STR_Lower(var string str)
-
Parameters
  • var string str
    The input string

Return Value

The function returns a copy of str with all lowercase letters converted to their corresponding uppercase letters.

\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/ikarus/functions/time_benchmark/index.html b/pl/zengin/scripts/extenders/ikarus/functions/time_benchmark/index.html deleted file mode 100644 index 1d19e78af7..0000000000 --- a/pl/zengin/scripts/extenders/ikarus/functions/time_benchmark/index.html +++ /dev/null @@ -1,64 +0,0 @@ - Time and Benchmark - Gothic Modding Community

Time and Benchmark

Set of functions to time measurement and Benchmark.

Initialization

The best way to initialize all Ikarus functions is to call MEM_InitAll() in the Init_Global() initialization function.

Warning

If you want to use Ikarus in Gothic 1, it is best to define your own Init_Global() function and call it from every world initialization function.

MEM_InitAll();
-

Implementation

Ikarus.d on GitHub

Time functions

MEM_GetSystemTime

Returns the elapsed time since Gothic started.

func int MEM_GetSystemTime()
-
Return value

The function returns the elapsed time since the start of Gothic in milliseconds. This value is used for timing measurements, in the BenchmarkMS functions.

MEM_GetPerformanceCounter

Call to the WinAPI QueryPerformanceCounter function.

func int MEM_GetPerformanceCounter()
-
Return value

The function returns a value representing the number of elapsed ticks since the system was started. This value is used for timing measurements, in the BenchmarkPC functions.

Benchmark functions

Tip

For reliable results, avoid measuring a single run of a function; instead, measure the total duration of multiple runs (e.g., 1000). This is crucial, especially for very fast functions, as a single run can distort the measurement. Use _N benchmark functions to include a parameter specifying the number of runs for function f.

Choose the parameter n to ensure meaningful results. If n executions take less than a millisecond, obtaining a return value in milliseconds has no sense. For very fast functions, the time spent in the benchmark function, not in f, significantly affects the measurement, falsifying the result. Reliable measurements are achievable only for functions with sufficient slowness.

For reference, here is a timing for some operations (in nanoseconds, i.e., billionths of a second):

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
- Function call (jumping back and forth): 30ns
-- Elementary calculation (e.g., i = i + 1): 130ns
-- Wld_IsTime: 200ns
-- MEM_ReadInt, MEM_WriteInt: 350ns
-- Hlp_StrCmp("Hello", "Hello"): 500ns
-- MEM_InstToPtr: 1400ns
-- (small) Allocate and free memory: 9700ns
-- CALL__stdcall (in empty function): 29000ns
-- MEM_GetParserSymb: 280000ns
-
-- Iteration of the benchmark function: 300ns
-

MEM_BenchmarkMS

Benchmark of the execution time for a specified function. (Milliseconds)

func int MEM_BenchmarkMS(var func f)
-
Parameters
  • var func f
    Function to benchmark

Return value

The function returns the duration of a function execution in milliseconds.

MEM_BenchmarkMMS

Benchmark of the execution time for a specified function. (microseconds)

func int MEM_BenchmarkMMS(var func f)
-
Parameters
  • var func f
    Function to benchmark

Return value

The function returns the duration of a function execution in microseconds.

MEM_BenchmarkPC

Benchmark of the execution time for a specified function, using the Performancecounter.

func int MEM_BenchmarkMS(var func f)
-
Parameters
  • var func f
    Function to benchmark

Return value

The function returns the number of Performancecounter ticks the function needs.

MEM_BenchmarkMS_N

MEM_BenchmarkMS, but with the parameter to specify the number of function runs.

func int MEM_BenchmarkMS_N(var func f, var int n)
-
Parameters
  • var func f
    Function to benchmark
  • var int n
    Number of runs

Return value

The function returns a summed duration of multiple (n) runs of the function in milliseconds.

MEM_BenchmarkMMS_N

MEM_BenchmarkMMS, but with the parameter to specify the number of function runs.

func int MEM_BenchmarkMMS_N(var func f, var int n)
-
Parameters
  • var func f
    Function to benchmark
  • var int n
    Number of runs

Return value

The function returns a summed duration of multiple (n) runs of the function in microseconds.

MEM_BenchmarkPC_N

MEM_BenchmarkPC, but with the parameter to specify the number of function runs.

func int MEM_BenchmarkPC_N(var func f, var int n)
-
Parameters
  • var func f
    Function to benchmark
  • var int n
    Number of runs

Return value

The function returns a summed number of Performancecounter ticks needed to execute function multiple (n) times.

\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/ikarus/functions/win_utilities/index.html b/pl/zengin/scripts/extenders/ikarus/functions/win_utilities/index.html deleted file mode 100644 index adf436b6e8..0000000000 --- a/pl/zengin/scripts/extenders/ikarus/functions/win_utilities/index.html +++ /dev/null @@ -1,55 +0,0 @@ - Windows Utilities - Gothic Modding Community

Windows Utilities

This part of Ikarus implements some WinAPI functions that can be used directly from Gothic scripts.

Initialization

The best way to initialize all Ikarus functions is to call MEM_InitAll() in the Init_Global() initialization function.

Warning

If you want to use Ikarus in Gothic 1, it is best to define your own Init_Global() function and call it from every world initialization function.

MEM_InitAll();
-

Implementation

Ikarus.d on GitHub

Functions

LoadLibrary

Loads the specified module into the address space of the calling process. Full documentation here.

func int LoadLibrary(var string lpFileName)
-
Parameters
  • var string lpFileName
    Name of loaded module

Return value

The function returns a handle to the module.

GetProcAddress

Retrieves the address from the specified dynamic-link library. Full documentation here.

func int GetProcAddress(var int hModule, var string lpProcName)
-
Parameters
  • var int hModule
    A handle to the DLL module that contains the function or variable. Can be obtained using the LoadLibrary function.
  • var string lpProcName
    The function or variable name.

Return value The function returns address of the function or variable.

FindKernelDllFunction

Uses GetProcAddress to find function inside the KERNEL32.DLL file.

func int FindKernelDllFunction(var string name)
-
Parameters
  • var string name
    Name of the looked function.

Return value

The function returns address of the function.

VirtualProtect

Changes the protection on a region of committed pages in the virtual address space of the calling process. Full documentation here.

func int VirtualProtect(var int lpAddress, var int dwSize, var int flNewProtect)
-
Parameters
  • var int lpAddress
    The address of the starting page of the region of pages whose access protection attributes are to be changed.
  • var int dwSize
    The size of the region whose access protection attributes are to be changed, in bytes.
  • var int flNewProtect
    The memory protection option. All options can be found here.

Return value

The function returns lpflOldProtectPtr - a pointer to a variable that receives the previous access protection value.

Author's comment:

I made lpflOldProtectPtr the return value and ignored the return Value of VirtualProtect.

MemoryProtectionOverride

Alias to VirtualProtect but with predefined PAGE_EXECUTE_READWRITE protection option

func void MemoryProtectionOverride(var int address, var int size)
-
Parameters
  • var int address
    The address of the starting page of the region of pages whose access protection attributes are to be changed.
  • var int size
    The size of the region whose access protection attributes are to be changed, in bytes.

MEM_MessageBox

Calls the WinAPI MessageBox function.

func int MEM_MessageBox(var string txt, var string caption, var int type)
-
Parameters
  • var string txt
    Content of the MessageBox.
  • var string caption
    Header of MessageBox.
  • var int type
    Type of MessageBox. All types listed here.

MEM_InfoBox

Alias to MEM_MessageBox with "Information:" header and MB_OK | MB_ICONINFORMATION type.

func void MEM_InfoBox(var string txt)
-
Parameters
  • var string txt
    Content of the InfoBox.

Examples

Sleep

Following function calls the Sleep function from the KERNEL32.DLL. A documentation of this function can be found here.

1
-2
-3
-4
-5
-6
-7
func void Sleep(var int ms) {
-    var int adr;
-    adr = GetProcAddress(LoadLibrary("KERNEL32.DLL"), "Sleep");
-
-    CALL_IntParam(ms);
-    CALL__stdcall(adr); // 0x007B47E6
-};
-
\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/ikarus/index.html b/pl/zengin/scripts/extenders/ikarus/index.html deleted file mode 100644 index 4918f44d8b..0000000000 --- a/pl/zengin/scripts/extenders/ikarus/index.html +++ /dev/null @@ -1,34 +0,0 @@ - Ikarus - Gothic Modding Community

Ikarus

Ikarus jest biblioteką Daedalusa - języka skryptowego Gothica. Wykorzystuje interpreter, aby umożliwić dowolny dostęp do pamięci i definiuje mnóstwo przydatnych funkcji do pracy z silnikiem.

Kontakt
Autor Sektenspinner i współtwórcy
GitHub Ikarus
Forum Ikarus

Notatka autora (Sektenspinner)

Ten pakiet skryptów nie bez powodu nazywa się Ikarus:

Można opuścić granice Dedala, ale można też rozbić się i spalić. Na przykład odczyt z nieprawidłowych adresów nie wywoła ostrzeżenia zSpy, ale spowoduje wyjście do pulpitu wraz z Access Violation. Nie jest to powód do paniki, ale wymaga tolerancji na frustrację (co może być ogólnie przydatne dla skrypterów).

Oczywiście tak spektakularnie wyglądające błędy można naprawić, a przy systematycznej pracy w skupieniu można osiągnąć coś sensownego.

W skrócie: wymagana jest dodatkowa ostrożność! Błąd prowadzący do awarii nie jest czymś, czego chciałbyś w wydanej wersji. Ale jeśli pracujesz czysto i intensywnie testujesz, nie jest to taka wielka sprawa.

Dobrym przyjacielem w debugowaniu awarii jest niewątpliwie PrintDebug. Umożliwia wysyłanie wiadomości do zSpy (na przykład w celu zawężenia miejsca wystąpienia awarii). Warto włączyć komunikaty debugowania za pomocą MEM_SetShowDebug i filtr tekstowy (Opcje -> Textfilter) w zSpy.

Note

Ikarus jest hostowany na GitHubie i posiada wbudowaną dokumentacje. Jej tłumaczenie jest w planach.

\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/ikarus/ini_access/index.html b/pl/zengin/scripts/extenders/ikarus/ini_access/index.html deleted file mode 100644 index 40bdff0db7..0000000000 --- a/pl/zengin/scripts/extenders/ikarus/ini_access/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/pl/zengin/scripts/extenders/ikarus/keyboard/index.html b/pl/zengin/scripts/extenders/ikarus/keyboard/index.html deleted file mode 100644 index 9d58a0c0c6..0000000000 --- a/pl/zengin/scripts/extenders/ikarus/keyboard/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/pl/zengin/scripts/extenders/ikarus/mem_access/index.html b/pl/zengin/scripts/extenders/ikarus/mem_access/index.html deleted file mode 100644 index f09e17255d..0000000000 --- a/pl/zengin/scripts/extenders/ikarus/mem_access/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/pl/zengin/scripts/extenders/ikarus/setup/index.html b/pl/zengin/scripts/extenders/ikarus/setup/index.html deleted file mode 100644 index bfa02ebe64..0000000000 --- a/pl/zengin/scripts/extenders/ikarus/setup/index.html +++ /dev/null @@ -1,138 +0,0 @@ - Setup - Gothic Modding Community

Ikarus Setup

Download

First you need to download ikarus from the official github repository. We recommend using the master branch as it contains the latest and most up-to-date version of Ikarus. However, you can also download a specific release if needed.

File location

Before unpacking the downloaded archive it's needed to create a dedicated folder in <Gothic-dir>\_work\Data\Scripts\Content directory. You can name this folder as you wish; in this guide, we'll refer to it as the "MOD" folder. Unpack the downloaded files into this newly created folder. The archiver should create a folder named Ikarus-master or Ikarus-X.X.X. For better readability change its name to the much simpler Ikarus.

Tip

It's a good practice to delete any unused files, so delete files for other gothic version than this you are using.

Parsing

Ikarus consists of three main parts, constants, classes and the Ikarus core. It's essential to parse these in a specific order. Additionally, there is a floats package which isn't essential, but it is highly recommended to parse it, especially if you are working with LeGo that depends on it.

The Ikarus Core is identical for both Gothic 1 and 2 and is contained in a single file, Ikarus.d. However, there are separate files for the constants and classes for each engine, and they must be parsed correctly. Ikarus uses a C_NPC and therefore has to be parsed after the C_NPC class (after the classes.d file). There are no other dependencies.

Since Ikarus 1.2.1 there is additional .src file for each game engine, to simplify adding files to Gothic.src

Warning

Following example is for Gothic 2. If you are using Gothic 1 replace the G2 at the end of the file/directory name with G1.

1
-2
-3
-4
-5
-6
_INTERN\CONSTANTS.D
-_INTERN\CLASSES.D
-MOD\IKARUS\Ikarus_Const_G2.d
-MOD\IKARUS\EngineClasses_G2\*.d
-MOD\IKARUS\Ikarus.d
-MOD\IKARUS\float.d
-
1
-2
-3
_INTERN\CONSTANTS.D
-_INTERN\CLASSES.D
-MOD\IKARUS\IKARUS_G2.SRC
-

Initialization

Before you can use Ikarus in your scripts, it must be properly initialized. The initialization process differs between Gothic 1 and Gothic 2.

MEM_InitAll

This is main ikarus initialization function, however it consists of some smaller initialization functions.

func void MEM_InitAll()
-
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
func void MEM_InitAll() {
-    if (!MEMINT_ReportVersionCheck()) {
-        return;
-    };
-
-    MEM_ReinitParser(); /* depends on nothing */
-    MEM_InitLabels(); /* depends in MEM_ReinitParser */
-    MEM_InitGlobalInst(); /* depends on MEM_ReinitParser */
-
-    /* now I can use MEM_ReplaceFunc, MEM_GetFuncID */
-    MEM_GetAddress_Init(); /* depends on MEM_ReinitParser and MEM_InitLabels */
-    /* now the nicer operators are available */
-
-    MEM_InitStatArrs(); /* depends on MEM_ReinitParser and MEM_InitLabels */
-    ASMINT_Init();
-
-    MEMINT_ReplaceLoggingFunctions();
-    MEMINT_ReplaceSlowFunctions();
-    MEM_InitRepeat();
-
-    /* takes a wail the first time it is called.
-        call it to avoid delay later */
-    var int dump; dump = MEM_GetFuncIDByOffset(0);
-};
-

Gothic 1

To initialize Ikarus in Gothic 1 you must define your own INIT_GLOBAL function at the top of the Startup.d file. Then the INIT_GLOBAL should be called in every INIT_<location> function (e.g. INIT_SURFACE,INIT_OLDCAMP etc.). INIT_SUB_<location> functions can be skipped in that process.

Then in your INIT_GLOBAL function you call MEM_InitAll() initialization function.

Startup.d
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
FUNC VOID INIT_GLOBAL()
-{
-    // Init Ikarus
-    MEM_InitAll ();
-};
-
-// [...]
-
-func VOID INIT_SURFACE ()
-{
-    Init_Global();
-    INIT_SUB_SURFACE ();
-};
-// [...]
-

Gothic 2

Gothic 2 has its own INIT_GLOBAL function, so the initialization process is much simpler. All you have to do is to call MEM_InitAll() in INIT_GLOBAL function located in the Startup.d file.

Startup.d
1
-2
-3
-4
-5
-6
-7
FUNC VOID INIT_GLOBAL()
-{
-    // Init Ikarus
-    MEM_InitAll ();
-};
-
-// [...]
-
\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/index.html b/pl/zengin/scripts/extenders/index.html deleted file mode 100644 index b40d88891e..0000000000 --- a/pl/zengin/scripts/extenders/index.html +++ /dev/null @@ -1,34 +0,0 @@ - Extendery Daedalusa - Gothic Modding Community

Extendery Daedalusa

Extendery to pakiety skryptowe rozszerzające składnię Daedalusa, która może być dosyć ograniczająca. Przez lata społeczność stworzyła całkiem sporo takich extenderów. Zanim pojawił się Union, standardową metodą na interfejs z silnikiem było wykorzystanie Ikarusa i zbudowanej na jego bazie kolekcji pakietów LeGo. Nie tak niedawno powstał dodatkowy pakiet skryptowy (a prace nad nim wciąż trwają) AF Script Packet, który oferuje jeszcze więcej funkcji i jest zbudowany na bazie Ikarusa i LeGo. Wraz z pojawieniem się Uniona i jego systemu pluginów powstał nowy extender o nazwie zParserExtender. Oczywiście również inne pluginy mogą implementować własne funkcje zewnętrzne. Wiele skryptów jest również rozsianych po forach Gothicowych, a dokumentacje niektórych z nich można znaleźć w sekcji Samodzielne.

\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/lego/ai_function/index.html b/pl/zengin/scripts/extenders/lego/ai_function/index.html deleted file mode 100644 index 1963f1c536..0000000000 --- a/pl/zengin/scripts/extenders/lego/ai_function/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/pl/zengin/scripts/extenders/lego/anim8/index.html b/pl/zengin/scripts/extenders/lego/anim8/index.html deleted file mode 100644 index db533d2cdf..0000000000 --- a/pl/zengin/scripts/extenders/lego/anim8/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/pl/zengin/scripts/extenders/lego/applications/anim8/index.html b/pl/zengin/scripts/extenders/lego/applications/anim8/index.html deleted file mode 100644 index a47c5718fb..0000000000 --- a/pl/zengin/scripts/extenders/lego/applications/anim8/index.html +++ /dev/null @@ -1,182 +0,0 @@ - Anim8 - Gothic Modding Community

Anim8

This package allows int or float values to be "animated" over a period of time. It is possible to string several commands together and to set the type of movement. The new version of PrintS from Interface uses Anim8.

Dependencies

Initialization

Initialize with LeGo_Anim8 flag.

LeGo_Init(LeGo_Anim8);
-

Implementation

Anim8.d on GitHub

Functions

Anim8_New

Creates a new Anim8 object that can be filled with commands.

func int Anim8_New(var int initialValue, var int IsFloat)
-
Parameters
  • var int initialValue
    The initial value to start animating from. Can be an integer, or an Ikarus float.
  • var int IsFloat
    If the initialValue is an Ikarus float, this parameter must be set to TRUE. If it is an integer, it must be set to FALSE.

Return value

The function returns handle of the Anim8 object.

Anim8_NewExt

Creates a new Anim8 object with advanced options. Extends the Anim8_New function.

func int Anim8_NewExt(var int value, var func handler, var int data, var int IsFloat)
-
Parameters
  • var int value
    The initial value to start animating from. Can be an integer, or an Ikarus float.
  • var func handler
    This function is called whenever the object is updated. The signature of the functions depends on the data value:
    data != 0: func void handler(var int data, var int value),
    data == 0: func void handler(var int value).
  • var int data
    Optional parameter to send an additional value to the handler function. If data == 0, it is ignored.
  • var int IsFloat
    If the initialValue is an Ikarus float, this parameter must be set to TRUE. If it is an integer, it must be set to FALSE.

Return value

The function returns handle of the Anim8 object.

Anim8_Delete

Deletes an Anim8 object created with Anim8_New.

func void Anim8_Delete(var int handle)
-
Parameters
  • var int handle
    Handle returned from Anim8_New

Anim8_Get

Get current value of the object.

func int Anim8_Get(var int handle)
-
Parameters
  • var int handle
    Handle returned from Anim8_New

Return value

The function returns value of the object.

Anim8_Set

Sets the value of the object.

func void Anim8_Set(var int handle, var int value)
-
Parameters
  • var int handle
    Handle returned from Anim8_New
  • var int value
    New value of the object

Anim8_Empty

Indicates whether the object is empty, i.e. has no more commands to process.

func int Anim8_Empty(var int handle)
-
Parameters
  • var int handle
    Handle returned from Anim8_New

Return value

The function returns TRUE if object is empty (has no more commands), FALSE is returned otherwise.

Anim8_RemoveIfEmpty

If desired, Anim8 can automatically delete an object after it is empty.

func void Anim8_RemoveIfEmpty(var int handle, var int on)
-
Parameters
  • var int handle
    Handle returned from Anim8_New
  • var int on
    TRUE: enable, FALSE: disable

Anim8_RemoveDataIfEmpty

With Anim8_NewExt handler and data can be set. If this function is called with TRUE, data is taken as a handle and delete(data) is called if the object is empty. Works only if Anim8_RemoveIfEmpty is also activated.

func void Anim8_RemoveDataIfEmpty(var int handle, var int on)
-
Parameters
  • var int handle
    Handle returned from Anim8_New
  • var int on
    TRUE: enable, FALSE: disable

Anim8

Packet core. Gives the object a new command to process.

func void Anim8(var int handle, var int target, var int span, var int interpol)
-
Parameters
  • var int handle
    Handle returned from Anim8_New
  • var int target
    Target value of this command. When the object's value has reached this value, the command is considered completed and deleted.
  • var int span
    Action duration in milliseconds
  • var int interpol
    What form of movement is used (See constants for this)

Anim8q

As already mentioned above, Anim8 can also process several commands one after the other. While Anim8 completely resets the object and deletes all commands, Anim8q just appends a new command to the list. This will be processed as soon as the previous one is completed.

func void Anim8q(var int handle, var int target, var int span, var int interpol)
-
Parameters
  • var int handle
    Handle returned from Anim8_New
  • var int target
    Target value of this command. When the object's value has reached this value, the command is considered completed and another one in the queue will start.
  • var int span
    Action duration in milliseconds
  • var int interpol
    What form of movement is used (See constants for this)

Anim8_CallOnRemove

Registers a function to be called when the object is deleted (e.g. by Anim8_RemoveIfEmpty)

func void Anim8_CallOnRemove(var int handle, var func dfnc)
-
Parameters
  • var int handle
    Handle returned from Anim8_New
  • var func dfnc
    This function is called when the object is deleted

Examples

Count up to a number

Count from 0 to 10 in 10 seconds. We use the Print_Ext function from Interface to display the text.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
func void Example1()
-{
-    // First we create a handle to a text:
-    var int MyText; MyText = Print_Ext(20, 20, "0", Font_Screen, COL_White, -1);
-
-    // After that we create a new, extended Anim8 object.
-    // It gets a handler and the handle to the text as data:
-    var int MyAnim8; MyAnim8 = Anim8_NewExt(0, MyLoop1, MyText, FALSE); 
-    // Start value 1, MyLoop1 as handler, MyText as data and no float
-
-    // Now the command to count to 10:
-    Anim8(MyAnim8, 10, 10000, A8_Constant); // With MyAnim8 to 10 within 10000ms with constant motion.
-
-    // So that the text and the Anim8 object are deleted after the process. 
-    // Now we have to do two more things:
-    Anim8_RemoveIfEmpty(MyAnim8, TRUE);
-    Anim8_RemoveDataIfEmpty(MyAnim8, TRUE);
-};
-
-func void MyLoop1(var int MyText, var int Number)
-{
-    var zCViewText t; t = _^(myText);
-
-    // Now the text is set to the value of the Anim8 object:
-    t.text = IntToString(Number);
-
-    // As I said, everything is deleted fully automatically
-};
-
A similar example can be found in the Interface examples.

Moving zCVob in loop

Now we make a vob constantly move back and forth, but without a mover. FrameFunctions are used for the loop:

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
-37
-38
-39
-40
-41
var zCVob MyVob;
-var int MyVobAni;
-
-func void Example2()
-{
-    // We use Ikarus to get a pointer to a known VOB:
-    MyVob = MEM_PtrToInst(MEM_SearchVobByName("MYVOB"));
-    // There must be a vob with the appropriate name in the world for this.
-
-    // Since the positions of a vob are floats, this time Anim8 must also use floats:
-    MyVobAni = Anim8_New(MyVob.trafoObjToWorld[3], TRUE);
-    // The X position of the vob serves as the starting value.
-    // We will also move it along this axis.
-
-    // Now start a loop that "nudges" the vob over and over again:
-    FF_Apply(MyVobLoop);
-};
-
-func void MyVobLoop()
-{
-    // We get the pointer to the VOB again
-    MyVob = MEM_PtrToInst(MEM_SearchVobByName("MYVOB"));
-
-    // Whenever there are no more commands, we add new ones:
-    if(Anim8_Empty(MyVobAni))
-    {
-        // First move by three meters:
-        Anim8(MyVobAni, addf(MyVob.trafoObjToWorld[3], mkf(300)), 1000, A8_SlowEnd);
-        // Then wait half a second:
-        Anim8q(MyVobAni, 0, 500, A8_Wait);
-        // And then back again:
-        Anim8q(MyVobAni, MyVob.trafoObjToWorld[3], 1000, A8_SlowEnd);
-        // And wait another half a second:
-        Anim8q(MyVobAni, 0, 500, A8_Wait);
-        // Note the 'q' in the follow-up commands.
-        // While Anim8 completely resets the command list, i.e. starts again, Anim8q appends the command to the queue.
-        // So you can tinker with a command sequence.
-    };
-    // Of course, we must set the "animated" value to the VOB itself
-    MyVob.trafoObjToWorld[3] = Anim8_Get(MyVobAni);
-};
-
\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/lego/applications/bars/index.html b/pl/zengin/scripts/extenders/lego/applications/bars/index.html deleted file mode 100644 index c11027e85e..0000000000 --- a/pl/zengin/scripts/extenders/lego/applications/bars/index.html +++ /dev/null @@ -1,165 +0,0 @@ - Bars - Gothic Modding Community

Bars - paski

Ten pakiet bardzo ułatwia dodawanie nowych pasków, dla wyświetlania np. wytrzymałości.

Zależności

Inicjalizacja

Zainicjuj za pomocą flagi LeGo_Bars.

LeGo_Init(LeGo_Bars);
-

Implementacja

Bars.d na GitHubie

Funkcje

Note

Jeśli prototyp GothicBar jest wybrany jako typ początkowy (GothicBar@ jako konstruktor), paski użytkownika są wizualnie nie do odróżnienia od tych używanych w Gothicu.

Bar_Create

Tworzy nowy pasek z instancji konstruktora.

func int Bar_Create(var int inst)
-

Parametry

  • var int inst
    Instancja konstruktora klasy Bar

Zwracana wartość

Funkcja zwraca handler do nowego paska.

Examples

var int bar; bar = Bar_Create(GothicBar@);

1
-2
var int bar; bar = Bar_Create(GothicBar@); // Tworzy nowy pasek
-Bar_SetPercent(bar, 50);                   // Ustawia jego wartość na 50%
-
1
-2
-3
-4
-5
func void Example_1()
-{
-    var int bar; bar = Bar_Create(GothicBar@); // Tworzy nowy pasek
-    Bar_SetPercent(bar, 50);                   // Ustawia jego wartość na 50%
-};
-

Bar_Delete

Usuwa pasek z ekranu i pamięci.

func void Bar_Delete(var int bar)
-

Parametry

  • var int bar
    Handler zwrócony przez Bar_Create

Bar_SetMax

Zmienia maksymalna wartość paska, ale nie aktualizuje jego długości (tylko Bar_SetPercent, Bar_SetPromille i Bar_SetValue to robią)

func void Bar_SetMax(var int bar, var int max)
-
Parametry
  • var int bar
    Handler zwrócony przez Bar_Create

  • var int max
    Nowa maksymalna wartość

Bar_SetValue

Ustawia wartość paska.

func void Bar_SetValue(var int bar, var int val)
-
Parametry
  • var int bar
    Handler zwrócony przez Bar_Create
  • var int val
    Nowa wartość paska

Bar_SetPercent

Ustawia wartość paska, ale w procentach (0..100).

func void Bar_SetPercent(var int bar, var int perc)
-
Parametry
  • var int bar
    Handler zwrócony przez Bar_Create
  • var int perc
    Nowa wartość paska w procentach

Bar_SetPromille

Ustawia wartość paska, ale w promilach (0..1000).

func void Bar_SetPromille(var int bar, var int pro)
-
Parametry
  • var int bar
    Handler zwrócony przez Bar_Create
  • var int pro
    Nowa wartość paska w promilach

Bar_Hide

Ukrywa pasek, ale go nie usuwa.

func void Bar_Hide(var int bar)
-
Parametry
  • var int bar
    Handler zwrócony przez Bar_Create

Bar_Show

Wyświetla pasek ponownie po użyciu Bar_Hide.

func void Bar_Show(var int bar)
-
Parametry
  • var int bar
    Handler zwrócony przez Bar_Create

Bar_MoveTo

Przenosi pasek do danej pozycji wirtualnej.

func void Bar_MoveTo(var int bar, var int x, var int y)
-
Parametry
  • var int bar
    Handler zwrócony przez Bar_Create
  • var int x
    Nowa pozycja w osi x
  • var int y
    Nowa pozycja w osi y

Bar_MoveToPxl

Przenosi pasek do danej pozycji wyrażonej w pikselach.

func void Bar_MoveToPxl(var int bar, var int x, var int y)
-
Parametry
  • var int bar
    Handler zwrócony przez Bar_Create
  • var int x
    Nowa pozycja w osi x
  • var int y
    Nowa pozycja w osi y

Bar_SetAlpha

Ustawia przezroczystość paska.

func void Bar_SetAlpha(var int bar, var int alpha)
-
Parametry
  • var int bar
    Handler zwrócony przez Bar_Create
  • var int alpha
    Wartość przezroczystości (0..255)

Bar_SetBarTexture

Ustawia teksturę wartości paska.

func void Bar_SetBarTexture(var int bar, var string barTex)
-
Parametry
  • var int bar
    Handler zwrócony przez Bar_Create
  • var string barTex
    Nowa tekstura

Bar_SetBackTexture

Ustawia teksturę tła paska.

func void Bar_SetBackTexture(var int bar, var string backTex)
-
Parametry
  • var int bar
    Handler zwrócony przez Bar_Create
  • var string backTex
    Nowa tekstura tła

Bar_Resize

Zmienia rozmiar istniejącego paska.

func void Bar_Resize(var int bar, var int width, var int height)
-
Parametry
  • var int bar
    Handler zwrócony przez Bar_Create
  • var int width
    Nowa szerokość
  • var int height
    Nowa szerokość

Bar_ResizePxl

Resize existing bar (in pixels).

func void Bar_ResizePxl(var int bar, var int x, var int y)
-
Parametry
  • var int bar
    Handler zwrócony przez Bar_Create
  • var int x
    Nowa szerokość w pikselach
  • var int y
    Nowa szerokość w pikselach

Przykłady

Note

Ten pakiet zakłada podstawowe zrozumienie modułu PermMem.

Dedykowany pasek doświadczenia

Pakiet Bars implementuje klasę Bar. Która wygląda tak:

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
class Bar
-{
-    var int x;          // Pozycja na ekranie w osi X (środka paska)
-    var int y;          // Pozycja na ekranie w osi Y (środka paska)
-    var int barTop;     // Pasek odstępu tła - góra/dół
-    var int barLeft;    // Pasek odstępu tła - lewo/prawo
-    var int width;      // Szerokość
-    var int height;     // Wysokość
-    var string backTex; // Tekstura tła
-    var string barTex;  // Tekstura wartości paska
-    var int value;      // Początkowa wartość
-    var int valueMax;   // Maksymalna wartość
-};
-
Prototyp GothicBar jest paskiem, który naśladuje standardowy pasek używany w grze.
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
prototype GothicBar(Bar)
-{
-    x = Print_Screen[PS_X] / 2;
-    y = Print_Screen[PS_Y] - 20;
-    barTop = 3;
-    barLeft = 7;
-    width = 180;
-    height = 20;
-    backTex = "Bar_Back.tga";
-    barTex = "Bar_Misc.tga";
-    value = 100;
-    valueMax = 100;
-};
-

O wiele łatwiej jest skonfigurować nową instancję przy użyciu tego prototypu. GothicBar bez zmian można znaleźć jako instancję GothicBar@, którą użyliśmy do stworzenia paska w powyższym przykładzie. GothicBar znajduje się na środku ekranu i wygląda tak samo, jak pasek wyświetlany podczas nurkowania.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
// Instancja stworzona z pomocą prototypu GothicBar 
-instance Bar_1(GothicBar)
-{
-    x = 100;
-    y = 20;
-};
-
-func void Example_1()
-{
-    // Example_1 może być wywołany np. w Init_Global
-    FF_ApplyOnce(Loop_1);
-};
-
-func void Loop_1()
-{
-    // Example_1 uruchamia tę pętlę.
-    // Tutaj pasek powinien być stworzony raz
-    // a potem sparowany z punktami doświadczenia:
-    var int MyBar;
-    if(!Hlp_IsValidHandle(MyBar))
-    {
-        MyBar = Bar_Create(Bar_1); // Our Bar_1
-    };
-    // Reszta jest chyba oczywista:
-    Bar_SetMax(MyBar, hero.exp_next);
-    Bar_SetValue(MyBar, hero.exp);
-};
-

Note

Jest to tłumaczenie artykułu napisanego oryginalnie przez Gottfrieda i Lehone i umieszczonego w oficjalnej dokumentacji pakietu LeGo.

\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/lego/applications/bloodsplats/index.html b/pl/zengin/scripts/extenders/lego/applications/bloodsplats/index.html deleted file mode 100644 index 0b36ee20e3..0000000000 --- a/pl/zengin/scripts/extenders/lego/applications/bloodsplats/index.html +++ /dev/null @@ -1,38 +0,0 @@ - Bloodsplats - Gothic Modding Community

Bloodsplats

If this package is activated, red blood splatters will appear on the screen when the hero takes damage. For this, the damage perception for the hero is redirected to _B_HeroDamage(). To use the Bloodsplats, the enclosed textures must be available. Also, the VFX "HERO_HURT" (also included) should be entered in the VfxInst.d to create an even better hit effect. All textures used here are from CGTextures.com. If you use Bloodsplats in your modification, this site must be noted in the credits.

Tip

See user constants to edit behavior of this packet.

Dependencies

Initialization

Initialize with LeGo_Bloodsplats flag.

LeGo_Init(LeGo_Bloodsplats);
-

Implementation

Bloodsplats.d on GitHub

Functions

Bloodsplat

Puts a blood splatter on the screen.

func void Bloodsplat(var int damage)
-
Parameters
  • var int damage
    The damage (affects the size of the splatter)

Bloodsplats_Rage

Pretty pointless feature that smears the entire screen.

func void Bloodsplats_Rage()
-

Npc_GetPercFunc

oCNpc::GetPerceptionFunc engine function wrapper

func int Npc_GetPercFunc(var C_Npc npc, var int type)
-
Parameters
  • var C_NPC npc
    NPC whose perception is checked
  • var int type
    Checked perception type (form Constant.d)

Return value

The function returns the state of NPCs selected perception.

\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/lego/applications/buffs/index.html b/pl/zengin/scripts/extenders/lego/applications/buffs/index.html deleted file mode 100644 index f3000ab9c6..0000000000 --- a/pl/zengin/scripts/extenders/lego/applications/buffs/index.html +++ /dev/null @@ -1,138 +0,0 @@ - Buffs - Gothic Modding Community

Buffs

This package allows you to easily create status effects that can affect any NPC. Status effects on the hero are displayed graphically in a bar.

Dependencies

Initialization

Initialize with LeGo_Buffs flag.

LeGo_Init(LeGo_Buffs);
-

Warning

This package is still experimental and not included in the LeGo_All initialization flag.

Implementation

Buffs.d on GitHub

Functions

Buff_Apply

Applies a status effect to an NPC.

func int Buff_Apply(var C_NPC npc, var int buff)
-
Parameters
  • var C_NPC npc
    NPC to be affected by this effect

  • var int buff
    The instance of the effect to apply to the NPC

Return value

The function returns the handle of the buff, which was just generated.

Buff_ApplyUnique

Buff_Apply, but nothing happens if a status effect of that kind is already on the NPC.

func int Buff_ApplyUnique(var C_NPC npc, var int buff)
-
Parameters
  • var C_NPC npc
    NPC to be affected by this effect

  • var int buff
    The instance of the effect to apply to the NPC

Return value

The function returns the handle of the buff, which was just generated or 0 if the buff is already applied on the NPC.

Buff_ApplyOrRefresh

Buff_Apply, but if a status effect of this type is already affecting the NPC, the duration will be reset.

func int Buff_ApplyOrRefresh(var C_NPC n, var int buff)
-
Parameters
  • var C_NPC npc
    NPC to be affected by this effect

  • var int buff
    The instance of the effect to apply to the NPC

Return value

The function returns the handle of the buff, which was just generated or refreshed.

Buff_Refresh

Resets the duration of the buff.

func void Buff_Refresh(var int buffHandle)
-
Parameters
  • var int buffHandle
    Handle of the buff to refresh

Buff_Remove

Removes the buff from the all NPCs.

func void Buff_Remove(var int buffHandle)
-
Parameters
  • var int buffHandle
    Handle of the buff to remove

Buff_RemoveAll

Removes the buffs form the NPC.

func void Buff_RemoveAll(var C_NPC npc, var int buffInstance)
-
Parameters
  • var C_NPC npc
    NPC whose buff should be removed

Buff_GetNpc

Returns a pointer to the NPC, which is affected by the buff.

func int Buff_GetNpc(var int buffHandle)
-
Parameters
  • var int buffHandle
    Handle of the buff

Return value

The function returns a pointer to the NPC, which is affected by the buff.

Buff_Has

Checks if the NPC already has an effect applied.

func int Buff_Has(var C_NPC npc, var int buff)
-
Parameters
  • var C_NPC npc
    Checked NPC

  • var int buff
    The instance of the effect

Return value

The function returns TRUE if the NPC has an effect applied. FALSE is returned otherwise.

SAVE_GetFuncID

Same as MEM_GetFuncID but gets the current instance.

func int SAVE_GetFuncID(var func f)
-
Parameters

var func f
Function whose ID is got

Return value

The function returns the ID of given function.

lCBuff class

The buffs package implements an lCBuff class, which looks like this:

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
class lCBuff
-{
-    var string name;    // buff name 
-    var int buffType;   // GOOD / NEUTRAL / BAD | 1 / 0 / -1
-    var int targetID;   // NPC that is currently affected by this buff
-    var int durationMS; // buff duration in milliseconds
-    var int tickMS;     // tick duration in milliseconds, first tick occurs at tickMS milliseconds
-    var int nextTickNr; // e.g. before the first tick this will be 0; OBSOLETE, remove when possible
-
-    var int OnApply; 
-    var int OnTick;
-    var int OnRemoved;
-
-    var string buffTex;  // associated texture - currently only used for buffs applied on the hero
-    // var int originID; // Who casted/created this buff?
-
-    // Internal, no need to set during instance construction
-    var int _startedTime;
-    var int _endTime;    // Not redundant with durationMS because buffs can be refreshed
-};
-

Examples

Delayed poison

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
instance deadly_poison(lCBuff)
-{
-    name = "Deadly poison";
-    bufftype = BUFF_BAD;
-
-    durationMS = 10*1000; // 10 seconds long
-    tickMS = 1000;        // Every second
-
-    buffTex = "POISON.TGA";
-};
-

Damage should also be added:

1
-2
-3
-4
-5
-6
-7
-8
func void deadly_poison_damage(var int buffHandle)
-{
-    var int ptr; ptr = Buff_GetNpc(buffHandle);
-    if (!ptr) { return; }; // Can happen if e.g. the world was changed
-
-    var C_NPC npc; npc = _^(ptr);
-    Npc_ChangeAttribute(npc, ATR_HITPOINTS, -3); // 3 damage
-};
-
For complicated technical reasons we use the function SAVE_GetFuncID instead of MEM_GetFuncID.
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
instance deadly_poison(lCBuff)
-{
-    name = "Deadly poison";
-    bufftype = BUFF_BAD;
-
-    durationMS = 10 * 1000; //10 seconds long
-    tickMS = 1000; // Every second
-
-    onTick = SAVE_GetFuncID(deadly_poison_damage); // The damage should be applied every second
-    buffTex = "POISON.TGA";
-};
-

For example, if this buff is now applied to the hero, by calling Buff_Apply(hero, deadly_poison), he loses a total of 30 HP over 10 seconds.

\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/lego/applications/buttons/index.html b/pl/zengin/scripts/extenders/lego/applications/buttons/index.html deleted file mode 100644 index 14d7fc9fb4..0000000000 --- a/pl/zengin/scripts/extenders/lego/applications/buttons/index.html +++ /dev/null @@ -1,57 +0,0 @@ - Buttons - Gothic Modding Community

Buttons

This package extends the handling of the mouse and allows creating rectangular buttons, which react to mouse (hover) entry and exit as well as a mouse click.

Dependencies

Initialization

Initialize with LeGo_Buttons flag.

LeGo_Init(LeGo_Buttons);
-

Implementation

Buffs.d on GitHub

Functions

Button_Create

Creates a button. It is initially hidden (not visible and does not react to the mouse). The three callback functions have the following signature void f(int handle).

func int Button_Create(var int posx, var int posy, var int width, var int height, var string tex, var func on_enter, var func on_leave, var func on_click)
-
Parameters
  • var int posx
    The horizontal position of the button in virtual coordinates
  • var int posy
    The vertical position of the button in virtual coordinates
  • var int width
    Width of the button in virtual coordinates
  • var int height
    Height of the button in virtual coordinates
  • var string tex
    Name of the button texture
  • var func on_enter
    This function is called when the mouse enters the button
  • var func on_leave
    This function is called when the mouse leaves the button
  • var func on_click
    This function is called when the user performs a mouse click on the button (left mouse button)

Return value

The function returns a handle to created button.

Button_CreatePxl

Button_Create with pixels instead of virtual coordinates.

func int Button_CreatePxl(var int posx, var int posy, var int width, var int height, var string tex, var func on_enter, var func on_leave, var func on_click)
-
Parameters
  • var int posx
    The horizontal position of the button in pixels
  • var int posy
    The vertical position of the button in pixels
  • var int width
    Width of the button in pixels
  • var int height
    Height of the button in pixels
  • var string tex
    Name of the button texture
  • var func on_enter
    This function is called when the mouse enters the button
  • var func on_leave
    This function is called when the mouse leaves the button
  • var func on_click
    This function is called when the user performs a mouse click on the button (left mouse button)

Return value

The function returns a handle to created button.

Button_Delete

Completely deletes a button.

func void Button_Delete(var int hndl)
-
Parameters
  • var int hndl
    Handle returned from Button_Create

Button_Show

Shows the button and makes it respond to the mouse.

func void Button_Show(var int hndl)
-
Parameters
  • var int hndl
    Handle returned from Button_Create

Button_Hide

Hides the button and disables it, so it is no longer responding to the mouse.

func void Button_Hide(var int hndl)
-
Parameters
  • var int hndl
    Handle returned from Button_Create

Button_SetTexture

Sets the texture of the button.

func void Button_SetTexture(var int hndl, var string tex)
-
Parameters
  • var int hndl
    Handle returned from Button_Create
  • var string tex
    Name of the new texture

Button_SetCaption

Displays a centered text on the button.

func void Button_SetCaption(var int hndl, var string caption, var string font)
-
Parameters
  • var int hndl
    Handle returned from Button_Create
  • var string caption
    The text to be displayed
  • var string font
    The font in which the text should be displayed

Button_CreateMouseover

Attaches a mouseover box to the cursor.

func void Button_CreateMouseover(var string text, var string font)
-
Parameters
  • var string text
    The text in the mouseover box
  • var string font
    The font of the text

Button_DeleteMouseover

Deletes the mouseover box.

func void Button_DeleteMouseover()
-

Button_Activate

Activates the button, so it reacts to the mouse. Does not change the visibility.

func void Button_Activate(var int hndl)
-
Parameters
  • var int hndl
    Handle returned from Button_Create

Button_Deactivate

Disables the button, so it no longer reacts to the mouse.

func void Button_Deactivate(var int hndl)
-
Parameters
  • var int hndl
    Handle returned from Button_Create

Button_SetUserData

Sets the user data of the button, an integer, to give the button individual information.

func void Button_SetUserData(var int hndl, var int data)
-
Parameters
  • var int hndl
    Handle returned from Button_Create
  • var int data
    Individual integer of the button (part of the internal _Button class)

Button_GetUserData

Gets the user data of the button.

func int Button_GetUserData(var int hndl)
-
Parameters
  • var int hndl
    Handle returned from Button_Create

Return value

The function returns the user data of the button.

Button_GetState

Gets the status of the button as a bit field. See User Constants.

func int Button_GetState(var int hndl)
-
Parameters
  • var int hndl
    Handle returned from Button_Create

Return value

The function returns the status of the button.

Button_Move

Moves the button by the given value in pixels. posx = posx + nposx

func void Button_Move(var int hndl, var int nposx, var int nposy)
-
Parameters
  • var int hndl
    Handle returned from Button_Create
  • var int nposx
    X-axis shift in pixels
  • var int nposy
    Y-axis shift in pixels

Button_MoveVrt

Moves the button by the given value in virtual coordinates. posx = posx + nposx

func void Button_Move(var int hndl, var int nposx, var int nposy)
-
Parameters
  • var int hndl
    Handle returned from Button_Create
  • var int nposx
    X-axis shift in virtual coordinates
  • var int nposy
    Y-axis shift in virtual coordinates

Button_MoveTo

Moves a button to the given position in pixels. posx = nposx

func void Button_MoveVrt(var int hndl, var int nposx, var int nposy)
-
Parameters
  • var int hndl
    Handle returned from Button_Create
  • var int nposx
    New horizontal position in pixels
  • var int nposy
    New vertical position in pixels

Button_MoveToVrt

Moves a button to the given position in virtual coordinates. posx = nvposx

func void Button_MoveVrt(var int hndl, var int nvposx, var int nvposy)
-
Parameters
  • var int hndl
    Handle returned from Button_Create
  • var int nvposx
    New horizontal position in virtual coordinates
  • var int nvposy
    New vertical position in virtual coordinates

Button_GetViewHandle

Returns the button's zCView as a handle.

func int Button_GetViewHandle(var int hndl)
-
Parameters
  • var int hndl
    Handle returned from Button_Create

Return value

The function returns the button's zCView as a handle.

Button_GetViewPtr

Returns the button's zCView as a pointer.

func int Button_GetViewPtr(var int hndl)
-
Parameters
  • var int hndl
    Handle returned from Button_Create

Return value

The function returns the button's zCView as a pointer.

Button_GetView

Returns the button's zCView as an object.

func zCView Button_GetView(var int hndl)
-
Parameters
  • var int hndl
    Handle returned from Button_Create

Return value

The function returns the button's zCView as an object.

Button_GetCaptionPtr

Returns the pointer to the text of the button.

func int Button_GetCaptionPtr(var int hndl)
-
Parameters
  • var int hndl
    Handle returned from Button_Create

Return value

The function returns the pointer to the text of the button.

\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/lego/applications/console_commands/index.html b/pl/zengin/scripts/extenders/lego/applications/console_commands/index.html deleted file mode 100644 index 81f70be944..0000000000 --- a/pl/zengin/scripts/extenders/lego/applications/console_commands/index.html +++ /dev/null @@ -1,84 +0,0 @@ - Console Commands - Gothic Modding Community

Console Commands - polecenia konsoli

Ten Pakiet pozwala na tworzenie nowych poleceń konsoli dostępnej po naciśnięciu klawisza F2 w trybie marvin.

Zależności

Inicjalizacja

Zainicjuj za pomocą flagi LeGo_ConsoleCommands.

LeGo_Init(LeGo_ConsoleCommands);
-

Implementacja

ConsoleCommands.d na GitHubie

Funkcje

CC_Register

Rejestruje nowe polecenie konsoli.

func void CC_Register(var func f, var string cmdPrefix, var string description)
-
Parametry
  • var func f
    Ta funkcja jest wykonywana po wprowadzeniu polecenia cmdPrefix w konsoli. Sygnatura funkcji to func string f(var string p0). Przekazany string to wszystko, co zostało określone w konsoli po faktycznym poleceniu. Zwracana wartość jest następnie wyświetlana w konsoli.
  • var string cmdPrefix
    Jest to polecenie, które można wprowadzić w konsoli.
  • var string description
    Ten tekst pojawia się obok polecenia (w zSpy), gdy używasz polecenia help w konsoli.

CC_Remove

Usuwa funkcje z konsoli komend.

func void CC_Remove(var func f)
-
Parametry
  • var func f
    Ta funkcja zostanie usunięta, a powiązane z nią polecenie przestanie działać.

CC_Active

Sprawdza, czy dana funkcja jest już częścią polecenia konsoli.

func int CC_Active(var func f)
-
Parametry
  • var func f
    Sprawdzana funkcja

Zwracana wartość

Funkcja zwraca TRUE jeśli znajdzie odpowiednią funkcję, inaczej FALSE.

Przykłady

Proste polecenie konsoli

Jako prosty przykład stwórzmy polecenie version, które wyświetli nam wersję modyfikacji. Po pierwsze, deklarujemy stałą zmienną string do przechowywania informacji o wersji.

const string Mod_Version = "Wersja modyfikacji - 0.1alpha";
-
Następnie tworzymy nową funkcję.

Note

Zwróć uwagę na poprawną sygnaturę funkcji. Jeśli będzie ona błędna, polecenie spowoduje awarię gry.

1
-2
-3
-4
-5
// Ta funkcja jest wywoływana przez nasze nowe polecenie
-func string CC_ModVersion(var string param)
-{
-    return Mod_Version;
-};
-
Następnie musimy zarejestrować polecenie. Dla wygody stworzyłem nową funkcję RegisterConsoleFunctions, która inicjuje wszystkie polecenia konsoli. Funkcja jest naprawdę prosta.
1
-2
-3
-4
func void RegisterConsoleFunctions()
-{
-    CC_Register (CC_ModVersion, "version", "Wersja mojej modyfikacji.");
-};
-
Na koniec musimy wywołać tę funkcję w INIT_GLOBAL.
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
func void INIT_GLOBAL()
-{
-    Game_InitGerman(); // tylko w G2
-
-    // Inicjalizacja Ikarusa
-    MEM_InitAll();
-
-    // Inicjalizacja LeGo
-    LeGo_Init(LeGo_ConsoleCommands);
-
-    // Tutaj rejstrujemy nasze polecenia
-    RegisterConsoleFunctions();
-
-    // Reszta kodu
-};
-
\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/lego/applications/cursor/index.html b/pl/zengin/scripts/extenders/lego/applications/cursor/index.html deleted file mode 100644 index dbe8fc0af9..0000000000 --- a/pl/zengin/scripts/extenders/lego/applications/cursor/index.html +++ /dev/null @@ -1,182 +0,0 @@ - Cursor - Gothic Modding Community

Cursor

This package implements Gothic in-game mouse cursor support. To visually display the cursor there is a Cursor.tga file in the resources, but the texture can be changed in user constants.

Warning

The cursor only works if the mouse is activated in the Gothic settings. It can be done directly from the scripts. See the Ini file access.

Dependencies

Initialization

Initialize with LeGo_Cursor flag.

LeGo_Init(LeGo_Cursor);
-

Implementation

Cursor.d on GitHub

Variables

  • var int Cursor_X
    Always contains the X coordinate of the mouse cursor.
  • var int Cursor_Y
    Always contains the Y coordinate of the mouse cursor.
  • var float Cursor_RelX
    Always contains the relative X coordinate of the mouse cursor as an Ikarus float.
  • var float Cursor_RelY
    Always contains the relative Y coordinate of the mouse cursor as an Ikarus float.
  • var int Cursor_Wheel
    Variable containing the value of the mouse wheel.
  • var int Cursor_Left
    Variable that always contains the KeyState of the left mouse button.
  • var int Cursor_Mid
    Variable that always contains the KeyState of the middle mouse button.
  • var int Cursor_Right
    Variable that always contains the KeyState of the right mouse button.
  • var int Cursor_Event
    An event handler that can send information about the mouse cursor. It can be used with all functions of the EventHandler package.
  • var int Cursor_NoEngine
    Variable that can prevent the engine from working. If is set to TRUE the engine no longer reacts to mouse movements.

Functions

Cursor_Hide

Hides the displayed mouse cursor.

func void Cursor_Hide()
-

Cursor_Show

Shows the mouse cursor.

func void Cursor_Show()
-

SetMouseEnabled

Can manually enable or disable the mouse.

func void SetMouseEnabled(var int enabled)
-
Parameters
  • var int enabled
    TRUE - Mouse activated

Examples

Click a button

We use a View to display a button to be clicked. The FrameFunctions take care of the loop to check whether a click was made.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
-37
-38
-39
-40
var int Button;
-func void Example1()
-{
-    // We show the cursor and at the same time a button to be clicked:
-    Cursor_Show();
-
-    // New View:
-    Button = View_CreatePxl(5, 5, 125, 50);
-    View_SetTexture(Button, "BUTTONTEX.TGA");
-    View_Open(Button);
-
-    // Optionally, mouse can be switched off for the engine:
-    Cursor_NoEngine = true; // -> The engine then no longer reacts to movements, so the camera does not move either
-
-    // Enable loop function:
-    FF_ApplyOnce(Button_Click);
-};
-
-func void Button_Click()
-{
-    if(Cursor_Left != KEY_PRESSED) { return; }; // Exit the function if the left mouse button was not pressed
-
-    if(Cursor_X >= 5 && Cursor_X <= 125
-    && Cursor_Y >= 5 && Cursor_Y <= 50) // Simply take over the coordinates of the view
-    { 
-        // Here the button was clicked.
-        // Remove button and end loop:
-        View_Close(Button);
-        View_Delete(Button);
-        Button = 0;
-
-        // Allow the engine to continue working:
-        Cursor_NoEngine = false;
-
-        FF_Remove(Button_Click);
-
-        // Hide the mouse:
-        Cursor_Hide();
-    };
-};
-

This also can be done by the Buttons package instead of View.

Event handler

Since LeGo 2.2 there is also an event handler (var int Cursor_Event) in the cursor package. This example briefly explains how it works:

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
func void Example2()
-{
-    // We register MyCursorListener as the handler/listener of the Cursor_Event:
-    Event_Add(Cursor_Event, MyCursorListener);
-
-    // From now on, MyCursorListener will be called whenever the cursor has something to report.
-};
-
-func void MyCursorListener(var int state)
-{
-    // The rest is self-explanatory:
-
-    if(state == CUR_WheelUp)
-    {
-        PrintS("Wheel up!");
-    };
-    if(state == CUR_WheelDown)
-    {
-        PrintS("Wheel down!");
-    };
-    if(state == CUR_LeftClick)
-    {
-        PrintS("Leftclick!");
-    };
-    if(state == CUR_RightClick)
-    {
-        PrintS("Rightclick!");
-    };
-    if(state == CUR_MidClick)
-    {
-        PrintS("Wheelclick!");
-    };
-};
-
Constants used in the example can be found in the user constants.
\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/lego/applications/dialoggestures/index.html b/pl/zengin/scripts/extenders/lego/applications/dialoggestures/index.html deleted file mode 100644 index 72905784b5..0000000000 --- a/pl/zengin/scripts/extenders/lego/applications/dialoggestures/index.html +++ /dev/null @@ -1,39 +0,0 @@ - Dialoggestures - Gothic Modding Community

Dialoggestures

This package can modify the NPCs' gestures during dialogue to better bring out emotions.

Dependencies

Initialization

N/A

Implementation

Dialoggestures.d on GitHub

Functions

DIAG

With this function the dialog gestures for all NPCs can be overridden. To understand the principle, it is recommended to take a look at the examples.

The full name of the animation can be described as follows:

DIAG_Prefix + aniName + DIAG_Suffix + ((rand() % (max - (min - 1))) + min).ToString("00");
-
DIAG_Prefix and DIAG_Suffix are user constants.

func void DIAG(var string AniName, var int Min, var int Max)
-
Parameters
  • var string AniName
    The new dialogue gesture
  • var int Min
    Lowest animation number
  • var int Max
    Highest animation number

DIAG_Reset

Resets the dialog gestures to the default.

func void DIAG_Reset()
-

DIAG_SetAni

Sets animation directly.

func void DIAG_SetAni(var string AniName)
-
Parameters
  • var string AniName
    Animation name

DIAG_SetMinMax

Sets animation numbers directly.

func void DIAG_SetMinMax(var int min, var int max)
-
Parameters
  • var int min
    Lowest animation number
  • var int max
    Highest animation number

Examples

Note

See Examples in the Trialoge article.

\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/lego/applications/focusnames/index.html b/pl/zengin/scripts/extenders/lego/applications/focusnames/index.html deleted file mode 100644 index c6bbed7c09..0000000000 --- a/pl/zengin/scripts/extenders/lego/applications/focusnames/index.html +++ /dev/null @@ -1,63 +0,0 @@ - Focusnames - Gothic Modding Community

Focusnames

This package colors the focus names of the NPCs in appropriate colors according to the behavior defined below (alpha values are taken into account). Also affects monsters. (Mobs/Items get Color_Neutral)

Dependencies

Initialization

Initialize with LeGo_Focusnames flag.

LeGo_Init(LeGo_Focusnames);
-

Implementation

Focusnames.d on GitHub

Usage

If you want to change colors for any behavior edit the following functions directly in Focusnames.d file.

Focusnames_Color_Friendly

1
-2
-3
-4
func int Focusnames_Color_Friendly()
-{
-    return RGBA(0, 255, 0, 255); // Green
-};
-

Focusnames_Color_Neutral

1
-2
-3
-4
func int Focusnames_Color_Neutral()
-{
-    return RGBA(255, 255, 255, 255); // White
-};
-

Focusnames_Color_Angry

1
-2
-3
-4
func int Focusnames_Color_Angry()
-{
-    return RGBA(255, 180, 0, 255); // Orange
-};
-

Focusnames_Color_Hostile

1
-2
-3
-4
func int Focusnames_Color_Hostile()
-{
-    return RGBA(255, 0, 0, 255); // Red
-};
-
\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/lego/applications/gamestate/index.html b/pl/zengin/scripts/extenders/lego/applications/gamestate/index.html deleted file mode 100644 index e8d7c132c2..0000000000 --- a/pl/zengin/scripts/extenders/lego/applications/gamestate/index.html +++ /dev/null @@ -1,177 +0,0 @@ - Gamestate - Gothic Modding Community

Gamestate - stan gry

Pakiet Gamestate pozwala sprawdzić stan gry (rozpoczęcie gry, ładowanie gry lub zmiana poziomu).

Zależności

Inicjalizacja

Zainicjuj za pomocą flagi LeGo_Gamestate.

LeGo_Init(LeGo_Gamestate);
-

Implementacja

Gamestate.d na GitHubie

Funkcje

Gamestate_AddListener

Dodaje listener/handler zmiany stanu gry.

func void Gamestate_AddListener(var func listener)
-
Parametry
  • var func listener
    Ta funkcja zostanie wywołana przy zmianie stanu gry. Bieżący stan gry jest przekazywany jako parametr.

Gamestate_RemoveListener

Usuwa listener zmiany stanu gry.

func void Gamestate_RemoveListener(var func listener)
-
Parametry
  • var func listener
    Listener do usunięcia.

Przykłady

Istnieją teraz dwie możliwości. Wszystko można zrobić bezpośrednio w Init_Global lub za pomocą EventHandler.

Init_Global

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
func void Init_Global()
-{
-    // [...]
-
-    LeGo_Init(LeGo_All);
-
-    if(Gamestate == Gamestate_NewGame) 
-    {
-        MEM_Info("Nowa gra rozpoczęta.");
-    }
-    else if(Gamestate == Gamestate_Loaded)
-    {
-        MEM_Info("Ładowanie gry.");
-    }
-    else if(Gamestate == Gamestate_WorldChange)
-    {
-        MEM_Info("Zmiana świata.");
-    }
-    else
-    {
-        MEM_Info("Brak zmiany stanu gry");
-    };
-};
-

Można to również zrobić tak:

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
func void Init_Global()
-{
-    // [...]
-
-    LeGo_Init(LeGo_All);
-
-    if(Gamestate == Gamestate_NewGame)
-    {
-        FF_Apply(MyLoop);
-        FF_Apply(My2ndLoop);
-    };
-};
-
Dałoby to taki sam efekt jak:
1
-2
-3
-4
-5
-6
-7
-8
-9
func void Init_Global()
-{
-    // [...]
-
-    LeGo_Init(LeGo_All);
-
-    FF_ApplyOnce(MyLoop);
-    FF_ApplyOnce(My2ndLoop);
-};
-

EventHandler

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
func void Init_Global()
-{
-    // [...]
-
-    LeGo_Init(LeGo_All);
-
-    Gamestate_AddListener(MyGamestateListener);
-};
-
-func void MyGamestateListener(var int state)
-{
-    if(state == Gamestate_NewGame)
-    {
-        MEM_Info("Nowa gra rozpoczęta.");
-    }
-    else if(state == Gamestate_Loaded)
-    {
-        MEM_Info("Ładowanie gry.");
-    }
-    else if(state == Gamestate_WorldChange)
-    {
-        MEM_Info("Zmiana świata.");
-    }
-    else
-    {
-        MEM_Info("Brak zmiany stanu gry.");
-    };
-};
-
Daje taki sam efekt jak przykład z Init_Global ale dla niektórych może lepiej wyglądać.

Note

Jest to tłumaczenie artykułu napisanego oryginalnie przez Gottfrieda i Lehone i umieszczonego w oficjalnej dokumentacji pakietu LeGo.

\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/lego/applications/names/index.html b/pl/zengin/scripts/extenders/lego/applications/names/index.html deleted file mode 100644 index 76d4f94103..0000000000 --- a/pl/zengin/scripts/extenders/lego/applications/names/index.html +++ /dev/null @@ -1,57 +0,0 @@ - Names - Gothic Modding Community

Names

Allows the user to change NPC name e.g. after he shows up.

Dependencies

Initialization

N/A

Implementation

Names.d on GitHub

Functions

SetName

Should be set in InitGlobal().

func void SetName(var C_NPC npc, var string name)
-
Parameters
  • var C_NPC npc
    The NPC to be named
  • var string name
    The name of the NPC

ShowName

Permanently displays the name set by SetName function above the npc.

func void ShowName(var C_NPC npc)
-
Parameters
  • var C_NPC npc
    The NPC whose name should be shown

Examples

Show the name of an NPC later

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
instance PAL_100_Friend(C_NPC)
-{
-    name = "Paladin";
-
-    // [...]
-};
-
-func void Init_Global()
-{
-    SetName(PAL_100_Friend, "Arto");
-};
-
At the start of the game, the name "Paladin" is displayed above PAL_100_Friend.

If ShowName(PAL_100_Friend); is used during a dialogue, the name "Arto" is permanently visible above the npc.

\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/lego/applications/render/index.html b/pl/zengin/scripts/extenders/lego/applications/render/index.html deleted file mode 100644 index f782e14003..0000000000 --- a/pl/zengin/scripts/extenders/lego/applications/render/index.html +++ /dev/null @@ -1,42 +0,0 @@ - Render - Gothic Modding Community

Render

With this package items can be rendered on the screen. Since items are rendered independently of the normal views, textures that are 'below' the items must also be managed by this package, this behaviour is managed by the priority system. The view with the highest priority is always rendered first, so it is at the bottom. In theory, any .3DS model can be rendered if you just create a suitable item script.

Dependencies

Initialization

Initialize with LeGo_Render flag.

LeGo_Init(LeGo_Render);
-

Warning

This package is still experimental and not included in LeGo_All initialization flag.

Implementation

Render.d on GitHub

Functions

Render_AddItemPrio

Generates the render of an item, with a manually specified priority.

func int Render_AddItemPrio(var int itemInst, var int x1, var int y1, var int x2, var int y2, var int priority)
-
Parameters
  • var int itemInst
    The instance of the item to render
  • var int x1 var int y1
    The top left coordinate of the view
  • var int x2 var int y2
    The bottom right coordinate of the view
  • var int priority
    The priority of this render object

Return value

The function returns a handle of the render object.

Render_AddItem

Generates the render of an item, with priority set to 0.

func int Render_AddItem(var int itemInst, var int x1, var int y1, var int x2, var int y2)
-
Parameters
  • var int itemInst
    The instance of the item to render
  • var int x1 var int y1
    The top left coordinate of the view
  • var int x2 var int y2
    The bottom right coordinate of the view

Return value

The function returns a handle of the render object.

Render_AddViewPrio

Generates the render of a View, with a manually specified priority.

func int Render_AddViewPrio(var int view, var int priority)
-
Parameters
  • var int view
    A handle to a View
  • var int priority
    The priority of this render object

Return value

The function returns a handle of the render object.

Render_AddView

Generates the render of a View, with priority set to 0.

func int Render_AddView(var int view)
-
Parameters
  • var int view
    A handle to a View

Return value

The function returns a handle of the render object.

Render_OpenView

Opens a render object. Only open render objects are displayed.

func void Render_OpenView(var int handle)
-
Parameters
  • var int handle
    Handle of a render object

Render_CloseView

Closes a render object. Only open render objects are displayed.

func void Render_CloseView(var int handle)
-
Parameters
  • var int handle
    Handle of a render object

Render_Remove

Deletes a render object. The associated view is deleted automatically.

func void Render_Remove(var int handle)
-
Parameters
  • var int handle
    Handle of a render object
\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/lego/applications/saves/index.html b/pl/zengin/scripts/extenders/lego/applications/saves/index.html deleted file mode 100644 index 5ee951d5f8..0000000000 --- a/pl/zengin/scripts/extenders/lego/applications/saves/index.html +++ /dev/null @@ -1,95 +0,0 @@ - Saves - Gothic Modding Community

Saves

Offers an open file stream that can read/write variables on save/load. It is used by PermMem, so you don't need to address it manually anymore.

Dependencies

Initialization

Initialize with LeGo_Saves flag.

LeGo_Init(LeGo_Saves);
-

Implementation

Saves.d on GitHub

Functions

BW_Savegame

Custom function. It creates a stream to its own memory file, this can be filled with the BW_* functions from the BinaryMachines.

func void BW_Savegame()
-

BR_Savegame

Custom function. It opens a stream to a previously saved memory file, which can be read from the BinaryMachines using the BR_* functions.

func void BR_Savegame()
-

Examples

Save a high score list

var string MyScoreList[10];
-

Since strings are not saved by the game by default, we use the functions from Saves.d to create an additional memory file that only belongs to us. At the top the Saves.d file has two functions: BW_Savegame and BR_Savegame. BinaryMachines functions are used to save or read the file, we don't need to do anything else than to use them here, the rest is done by Saves.d completely by itself. Therefore, we only modify these two functions.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
func void BW_Savegame() 
-{
-    // Save high score list
-    BW_String(MyScoreList[0]);
-    BW_String(MyScoreList[1]);
-    BW_String(MyScoreList[2]);
-    BW_String(MyScoreList[3]);
-    BW_String(MyScoreList[4]);
-    BW_String(MyScoreList[5]);
-    BW_String(MyScoreList[6]);
-    BW_String(MyScoreList[7]);
-    BW_String(MyScoreList[8]);
-    BW_String(MyScoreList[9]);
-};
-
-func void BR_Savegame() 
-{
-    // Load high score list
-    MyScoreList[0] = BR_String();
-    MyScoreList[1] = BR_String();
-    MyScoreList[2] = BR_String();
-    MyScoreList[3] = BR_String();
-    MyScoreList[4] = BR_String();
-    MyScoreList[5] = BR_String();
-    MyScoreList[6] = BR_String();
-    MyScoreList[7] = BR_String();
-    MyScoreList[8] = BR_String();
-    MyScoreList[9] = BR_String();
-};
-

Tip

Since LeGo 2.0, such things can be implemented much more elegantly with PermMem.

\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/lego/applications/trialoge/index.html b/pl/zengin/scripts/extenders/lego/applications/trialoge/index.html deleted file mode 100644 index 28ae05c8b7..0000000000 --- a/pl/zengin/scripts/extenders/lego/applications/trialoge/index.html +++ /dev/null @@ -1,225 +0,0 @@ - Trialoge - Gothic Modding Community

Trialogi

Ten pakiet pozwala na tworzenie rozmów z dowolną liczbą NPC i sterowanie kamerą podczas dialogu.

Zależności

Inicjalizacja

Zainicjuj za pomocą flagi LeGo_Trialoge.

LeGo_Init(LeGo_Trialoge);
-

Implementacja

Trialoge.d na GitHubie

Funkcje

EquipWeapon

Funkcja Sektenspinnera. Sprawia, że NPC wyposaża broń.

func void EquipWeapon(var C_NPC slf, var int ItemInstance)
-
Parametry
  • var C_NPC slf
    NPC który wyposaża broń
  • var int ItemInstance
    Instancja broni do wyposażenia

Konfiguracja

const int EquipWeapon_TogglesEquip = 1

Powyższa stała ustala zachowanie funkcji podczas próby założenia już założonej broni:

  • 0 - EquipWeapon nic nie zrobi
  • 1 - EquipWeapon zdejmie tą broń

Npc_GetArmor

Pobiera pancerz wyposażony przez NPC.

func int Npc_GetArmor(var C_NPC slf)
-
Parametry
  • var C_NPC slf
    NPC którego pancerz jest pobierany

Zwracana wartość

Funkcja zwraca ID instancji pancerza założonego przez NPC.

Npc_GetMeleeWeapon

Pobiera wyposażoną przez NPC broń białą.

func int Npc_GetMeleeWeapon(var C_NPC slf)
-
Parametry
  • var C_NPC slf
    NPC którego broń jest pobierana

Zwracana wartość

Funkcja zwraca ID instancji broni białej wyposażonej przez NPC.

Npc_GetRangedWeapon

Pobiera wyposażoną przez NPC broń dystansową.

func int Npc_GetRangedWeapon(var C_NPC slf)
-
Parametry
  • var C_NPC slf
    NPC którego broń jest pobierana

Zwracana wartość

Funkcja zwraca ID instancji broni dystansowej wyposażonej przez NPC.

Npc_TradeItem

Podmienia broń założoną przez NPC.

func void Npc_TradeItem(var c_npc slf, var int itm0, var int itm1) 
-
Parametry
  • var C_NPC slf
    NPC na którym wykonywana jest operacja
  • var int itm0
    ID instancji przedmiotu do usunięcia
  • var int itm1
    ID instancji przedmiotu do stworzenia i założenia

DiaCAM_Update

Funkcja Sektenspinnera. Aktualizuje kamerę dialogową. (Używana wewnętrznie)

func void DiaCAM_Update()
-

DiaCAM_Disable

Całkowicie wyłącza kamery dialogowe.

func void DiaCAM_Disable()
-

DiaCAM_Enable

Resetuje kamery dialogowe do ustawień domyślnych.

func void DiaCAM_Enable()
-

TRIA_Wait

Sprawia że self i other czekają na siebie, np. podczas dla synchronizacji po wywołaniu AI_GotoWP.

func void TRIA_Wait()
-

TRIA_Invite

Zaprasza NPC do rozmowy. Należy wywołać przed TRIA_Start.TRIA_Start.

func void TRIA_Invite(var C_NPC slf)
-
Parametry
  • var C_NPC slf
    Zapraszany NPC

TRIA_Start

Rozpoczyna trialog. Wcześniej wszyscy NPC powinni zostać zaproszeni przez TRIA_Invite.

func void TRIA_Start()
-

TRIA_Barrier

Robi to samo co TRIA_Wait, ale dotyczy wszystkich uczestniczących NPC.

func void TRIA_Barrier()
-

TRIA_Next

Ustawia podanego NPC na self.

func void TRIA_Next(var C_NPC n0)
-
Parametry
  • var C_NPC n0
    NPC ustawiany na self

TRIA_Cam

Rozpoczyna zdefiniowany wcześniej ruch kamery.

func void TRIA_Cam(var string evt)
-
Parametry
  • var string evt
    Nazwa ruchu kamery w Spacerze. Jeśli zostanie przekazany pusty ciąg znaków, nastąpi przerwanie ruchu kamery.

TRIA_Finish

Kończy trwający trialog. Musi być zawsze wywoływana na końcu, w przeciwnym razie dalsze trialogi nie będą mogły zostać rozpoczęte.

func void TRIA_Finish()
-

Przykłady

Prosty Trialog

Poniższa konwersacja zostanie zaimplementowana za pomocą trialogów:

  1. Arto: Wybacz bohaterze, ale nie możesz tędy przejść.
  2. Bohater: Dlaczego nie?
  3. Horka: Miasto zostało zamknięte.
  4. Bohater: Mam trochę złota przy sobie, możemy pohandlować?
  5. Squelto: Nie. Nie jesteśmy otwarci na przekupstwo.
  6. Bohater: Na pewno?
  7. Arto: Muszę prosić, abyś teraz odszedł.
  8. Bohater: Niech będzie...
     1
    - 2
    - 3
    - 4
    - 5
    - 6
    - 7
    - 8
    - 9
    -10
    -11
    -12
    -13
    -14
    -15
    -16
    -17
    -18
    -19
    -20
    -21
    -22
    -23
    -24
    -25
    -26
    -27
    -28
    -29
    -30
    -31
    -32
    -33
    -34
    -35
    -36
    -37
    -38
    -39
    -40
    -41
    -42
    -43
    -44
    -45
    -46
    -47
    -48
    -49
    -50
    -51
    -52
    -53
    -54
    -55
    -56
    -57
    -58
    -59
    -60
    -61
    -62
    -63
    -64
    -65
    -66
    -67
    -68
    -69
    -70
    -71
    -72
    -73
    -74
    -75
    -76
    -77
    -78
    -79
    -80
    -81
    -82
    -83
    -84
    -85
    -86
    -87
    -88
    instance TRIA_Test (C_INFO)
    -{
    -    npc         = PAL_100_Friend;
    -    nr          = 10;
    -    condition   = TRIA_Test_condition;
    -    information = TRIA_Test_info;
    -    important   = FALSE;
    -    permanent   = 1;
    -    description = "TRIALOGTEST";
    -};
    -
    -func int TRIA_Test_condition()
    -{
    -    return TRUE;
    -};
    -
    -func void TRIA_Test_info()
    -{
    -    var C_NPC Arto;       Arto = Hlp_GetNpc(PAL_100_Friend); // On jest właścicielem dialogu
    -    var C_NPC Horka;     Horka = Hlp_GetNpc(PAL_101_Horka);
    -    var C_NPC Squelto; Squelto = Hlp_GetNpc(PAL_102_Squelto);
    -
    -    TRIA_Invite(Horka);   // Zaproś Horka do dialogu
    -    TRIA_Invite(Squelto); // Zaproś Squelto do dialogu
    -    TRIA_Start();         // Rozpocznij rozmowę
    -    // Bohater i Arto nie muszą być zaproszeni. Domyślnie należą do dialogu.
    -
    -    // Bohater mówi do Arto (self = Arto, other = Hero)
    -    TRIA_Next(Arto);
    -
    -    DIAG_Reset();
    -
    -    AI_Output (self, other, "TRIA_TEST_00"); //Wybacz bohaterze, ale nie możesz tędy przejść.
    -
    -    // Bohater mówi teraz do Horka (self = Horka, other = Hero)
    -    TRIA_Next(Horka);
    -
    -    AI_Output (other, self, "TRIA_TEST_01"); //Dlaczego nie?
    -
    -    AI_GotoNpc(self, other);
    -    AI_TurnToNpc(other, self);
    -
    -    AI_Output (self, other, "TRIA_TEST_02"); //Miasto zostało zamknięte.
    -
    -    // Bohater rozgląda się wokoło w trakcie następnej sceny
    -    DIAG("Nervous", 1, 2);
    -
    -    AI_Output (other, self, "TRIA_TEST_03"); //Mam trochę złota przy sobie, możemy pohandlować?
    -
    -    // Bohater powinien ruszać się teraz znowu normalnie
    -    DIAG_Reset();
    -
    -    // Rozpocznij ruch kamery
    -    TRIA_Cam("CAMERASTART");
    -
    -    // Bohater mówi teraz do Squelto (self = Squelto, other = Hero)
    -    TRIA_Next(Squelto);
    -
    -    AI_TurnToNpc(other, self);
    -
    -    DIAG("No", 0, 1);
    -    AI_Output (self, other, "TRIA_TEST_04"); //Nie. Nie jesteśmy otwarci na przekupstwo.
    -
    -    // Bohater mówi ponowni do Arto (self = Arto, other = Hero)
    -    TRIA_Next(Arto);
    -
    -    // Bohater powinien teraz pytająco gestykulować
    -    DIAG("NotSure", 0, 1);
    -
    -    AI_Output(other, self, "TRIA_TEST_05"); //Na pewno?
    -
    -    AI_TurnToNpc(other, self);
    -
    -    // Zakończ ruch kamery
    -    TRIA_Cam("");
    -
    -    // Arto powinien zareagować wściekle
    -    DIAG("Angry", 0, 4);
    -
    -    AI_Output (self, other, "TRIA_TEST_06"); //Muszę prosić, abyś teraz odszedł.
    -
    -    // Bohater powinien ponownie poruszać się normalnie
    -    DIAG_Reset();
    -
    -    AI_Output (other, self, "TRIA_TEST_07"); //Niech będzie...
    -
    -    TRIA_Finish(); // Koniec
    -};
    -

Note

Dodatkowo w powyższym przykładzie użyty jest też pakiet Dialoggestures.

\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/lego/bars/index.html b/pl/zengin/scripts/extenders/lego/bars/index.html deleted file mode 100644 index d9593db1bf..0000000000 --- a/pl/zengin/scripts/extenders/lego/bars/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/pl/zengin/scripts/extenders/lego/bloodsplats/index.html b/pl/zengin/scripts/extenders/lego/bloodsplats/index.html deleted file mode 100644 index 07805ad05a..0000000000 --- a/pl/zengin/scripts/extenders/lego/bloodsplats/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/pl/zengin/scripts/extenders/lego/console_commands/index.html b/pl/zengin/scripts/extenders/lego/console_commands/index.html deleted file mode 100644 index 1dec884d9e..0000000000 --- a/pl/zengin/scripts/extenders/lego/console_commands/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/pl/zengin/scripts/extenders/lego/dialoggestures/index.html b/pl/zengin/scripts/extenders/lego/dialoggestures/index.html deleted file mode 100644 index f446c3350b..0000000000 --- a/pl/zengin/scripts/extenders/lego/dialoggestures/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/pl/zengin/scripts/extenders/lego/focusnames/index.html b/pl/zengin/scripts/extenders/lego/focusnames/index.html deleted file mode 100644 index 565bdc88c9..0000000000 --- a/pl/zengin/scripts/extenders/lego/focusnames/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/pl/zengin/scripts/extenders/lego/frame_functions/index.html b/pl/zengin/scripts/extenders/lego/frame_functions/index.html deleted file mode 100644 index 79d8a8e592..0000000000 --- a/pl/zengin/scripts/extenders/lego/frame_functions/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/pl/zengin/scripts/extenders/lego/gamestate/index.html b/pl/zengin/scripts/extenders/lego/gamestate/index.html deleted file mode 100644 index 66a81fdd74..0000000000 --- a/pl/zengin/scripts/extenders/lego/gamestate/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/pl/zengin/scripts/extenders/lego/index.html b/pl/zengin/scripts/extenders/lego/index.html deleted file mode 100644 index 7af944c7fc..0000000000 --- a/pl/zengin/scripts/extenders/lego/index.html +++ /dev/null @@ -1,34 +0,0 @@ - LeGo - Gothic Modding Community
\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/lego/int64/index.html b/pl/zengin/scripts/extenders/lego/int64/index.html deleted file mode 100644 index c45777f16c..0000000000 --- a/pl/zengin/scripts/extenders/lego/int64/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/pl/zengin/scripts/extenders/lego/item_helper/index.html b/pl/zengin/scripts/extenders/lego/item_helper/index.html deleted file mode 100644 index 157ce75b3a..0000000000 --- a/pl/zengin/scripts/extenders/lego/item_helper/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/pl/zengin/scripts/extenders/lego/locals/index.html b/pl/zengin/scripts/extenders/lego/locals/index.html deleted file mode 100644 index d871a56318..0000000000 --- a/pl/zengin/scripts/extenders/lego/locals/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/pl/zengin/scripts/extenders/lego/misc/index.html b/pl/zengin/scripts/extenders/lego/misc/index.html deleted file mode 100644 index 38bec415d2..0000000000 --- a/pl/zengin/scripts/extenders/lego/misc/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/pl/zengin/scripts/extenders/lego/names/index.html b/pl/zengin/scripts/extenders/lego/names/index.html deleted file mode 100644 index b6e6f05ae7..0000000000 --- a/pl/zengin/scripts/extenders/lego/names/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/pl/zengin/scripts/extenders/lego/random/index.html b/pl/zengin/scripts/extenders/lego/random/index.html deleted file mode 100644 index 80cf3eadb4..0000000000 --- a/pl/zengin/scripts/extenders/lego/random/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/pl/zengin/scripts/extenders/lego/talents/index.html b/pl/zengin/scripts/extenders/lego/talents/index.html deleted file mode 100644 index e1fa771490..0000000000 --- a/pl/zengin/scripts/extenders/lego/talents/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/pl/zengin/scripts/extenders/lego/timer/index.html b/pl/zengin/scripts/extenders/lego/timer/index.html deleted file mode 100644 index 79f96d8e26..0000000000 --- a/pl/zengin/scripts/extenders/lego/timer/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/pl/zengin/scripts/extenders/lego/tools/ai_function/index.html b/pl/zengin/scripts/extenders/lego/tools/ai_function/index.html deleted file mode 100644 index d0c125f670..0000000000 --- a/pl/zengin/scripts/extenders/lego/tools/ai_function/index.html +++ /dev/null @@ -1,71 +0,0 @@ - AI_Function - Gothic Modding Community

AI_Function - Funkcje AI

Ten pakiet umożliwia wywoływanie funkcji opóźnionych w czasie poprzez kolejkowanie ich w kolejce AI danego NPC. Może to być bardzo przydatne przy pisaniu przerywników filmowych na silniku lub implementacji nowych rutyn.

Zależności

Inicjalizacja

Zainicjuj za pomocą flagi LeGo_AI_Function.

LeGo_Init(LeGo_AI_Function);
-

Implementacja

AI_Function.d na GitHubie

Funkcje

Funkcja function jest wywoływana z opóźnieniem: dołącza do kolejki AI slf.

func void AI_Function(var C_NPC slf, var func function)
-
Parametry
  • var C_NPC slf
    NPC, do którego kolejki AI dołącza funkcja
  • var func function
    Funkcja wywoływana z opóźnieniem

Dodatkowo istnieją pewne przeciążenia AI_Function, które pozwalają na wywoływanie funkcji z parametrami.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
func void AI_Function_I  (var C_NPC slf, var func function, var int    param) {}; // Int
-func void AI_Function_N  (var C_NPC slf, var func function, var int    param) {}; // Instance (e.g. NPC)
-func void AI_Function_S  (var C_NPC slf, var func function, var string param) {}; // String
-func void AI_Function_II (var C_NPC slf, var func function, var int    param1, var int    param2) {}; // Int, Int
-func void AI_Function_NN (var C_NPC slf, var func function, var int    param1, var int    param2) {}; // Instance, Instance
-func void AI_Function_SS (var C_NPC slf, var func function, var string param1, var string param2) {}; // String, String
-func void AI_Function_IS (var C_NPC slf, var func function, var int    param1, var string param2) {}; // Int, String
-func void AI_Function_SI (var C_NPC slf, var func function, var string param1, var int    param2) {}; // String, Int
-func void AI_Function_NS (var C_NPC slf, var func function, var int    param1, var string param2) {}; // Instance, String
-func void AI_Function_SN (var C_NPC slf, var func function, var string param1, var int    param2) {}; // String, Instance
-func void AI_Function_IN (var C_NPC slf, var func function, var int    param1, var int    param2) {}; // Int, Instance
-func void AI_Function_NI (var C_NPC slf, var func function, var int    param1, var int    param2) {}; // Instance, Int
-
Nie można wywoływać funkcji z więcej niż dwoma parametrami, ale parametry można przekazywać pośrednio przez zmienne globalne.

W wywołanej funkcji dostęp do self można uzyskać w następujący sposób:

var oCNpc slf; slf = _^(ECX);
-

Info

Od LeGo 2.7.2 globalna instancja self jest dostarczana poprawnie i może być używana bezpośrednio.

Przykłady

Kolejkowanie prostej funkcji

Zanim funkcja zostanie wywołana, każdy NPC powinien najpierw zakończyć swoją kolejkę AI.

Tutaj bohater ma biec do Waypointu i dopiero po dotarciu na miejsce ma rozpocząć się ruch kamery.

1
-2
-3
-4
-5
-6
func void Example1() {
-    Npc_ClearAIQueue(hero);
-    AI_GotoWP(hero, "MYWAYPOINT");
-
-    AI_Function_S(hero, Wld_SendTrigger, "CAMERASTART");
-};
-
Gdy tylko bohater dotrze do Waypointu, wywoływane jest Wld_SendTrigger("CAMERASTART");.
\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/lego/tools/binary_machines/index.html b/pl/zengin/scripts/extenders/lego/tools/binary_machines/index.html deleted file mode 100644 index 3a907d4c44..0000000000 --- a/pl/zengin/scripts/extenders/lego/tools/binary_machines/index.html +++ /dev/null @@ -1,237 +0,0 @@ - BinaryMachines - Gothic Modding Community

BinaryMachines

Ten pakiet pozwala tworzyć i zapisywać własne pliki w dowolnym miejscu w systemie plików.

Zależności

Brak

Inicjalizacja

Brak

Implementacja

BinaryMachines.d na GitHub

BinaryWriter

BW_NewFile

Tworzy plik o nazwie file i otwiera strumień. Nie działa, jeśli strumień jest już otwarty.

func int BW_NewFile(var string file)
-
Parametry
  • var string file
    Nazwa tworzonego pliku

Zwracana wartość

Funkcja zwraca TRUE jeśli plik został pomyślnie utworzony i zainicjalizowany, w przeciwnym razie zwracane jest FALSE.

BW_Close

Zamyka aktualny strumień zapisu.

func void BW_Close()
-

BW

Zapisuje length bajtów z data do strumienia, maksymalnie 4 bajty.

func void BW(var int data, var int length)
-
Parametry
  • var int data
    Wartość bajtów
  • var int length
    Liczba bajtów

BW_Int

Zapisuje 4 bajty z data do strumienia. To samo co BW(data, 4).

func void BW_Int(var int data)
-
Parametry
  • var int data
    Wartość całkowita do zapisania

BW_Char

Zapisuje pierwszy znak z data do strumienia. To samo co BW(Str_GetCharAt(data, 0), 1).

func void BW_Char(var string data)
-
Parametry
  • var string data
    Znak do zapisania

BW_String

Zapisuje data zakończone znakiem \0 do strumienia.

func void BW_String(var string data)
-
Parametry
  • var string data
    Ciąg znaków do zapisania

BW_Byte

Zapisuje bajt z data do strumienia. To samo co BW(data, 1).

func void BW_Byte(var int data)
-
Parametry
  • var int data
    Wartość bajtowa do zapisania

BW_Bytes

Zapisuje length bajtów ze wskaźnika dataPtr do strumienia.

func void BW_Bytes(var int dataPtr, var int length)
-
Parametry
  • var int dataPtr
    Wskaźnik danych do zapisania
  • var int length
    Liczba bajtów

BW_Text

Zapisuje ciąg znaków do strumienia bez jego zakończenia. Nie można go już odczytać.

func void BW_Text(var string data)
-
Parametry
  • var string data
    Tekst do zapisania

BW_NextLine

Zapisuje akapit do strumienia.

func void BW_NextLine()
-

BinaryReader

BR_OpenFile

Otwiera plik o nazwie file i otwiera strumień. Nie działa, jeśli strumień jest już otwarty.

func int BR_OpenFile(var string file)
-
Parametry
  • var string file
    Plik, który ma być otwarty

Zwracana wartość

Funkcja zwraca TRUE jeśli plik został pomyślnie otworzony i zainicjalizowany, w przeciwnym razie zwracane jest FALSE.

BR_Close

Zamyka aktualny strumień odczytu.

func void BR_Close()
-

BR

Odczytuje bajty ze strumienia.

func int BR(var int length)
-
Parametry
  • var int length
    Liczba bajtów do odczytania (maksymalnie 4)

Zwracana wartość

Funkcja zwraca odczytaną wartość bajtów.

BR_Int

Odczytuje 4 bajty ze strumienia. To samo co BR(4).

func int BR_Int()
-
Zwracana wartość

Funkcja zwraca odczytaną liczbę całkowitą.

BR_Char

Odczytuje znak ze strumienia. To samo co BR(1).

func string BR_Char()
-
Zwracana wartość

Funkcja zwraca odczytany znak jako string.

BR_String

Odczytuje ciąg znaków zakończony znakiem \0 ze strumienia.

func string BR_String()
-
Zwracana wartość

Funkcja zwraca odczytany ciąg znaków.

BR_Byte

Odczytuje bajt ze strumienia.

func int BR_Byte()
-
Zwracana wartość

Funkcja zwraca odczytany bajt.

BR_Bytes

Odczytuje bajty ze strumienia.

func int BR_Bytes(var int length)
-
Parametry
  • var int length
    Liczba bajtów do odczytania

Zwracana wartość

Funkcja zwraca wskaźnik do odczytanych bajtów.

BR_TextLine

Odczytuje linię ze strumienia.

func string BR_TextLine()
-
Zwracana wartość

Funkcja zwraca odczytaną linię.

BR_Text

Odczytuje ciąg znaków o podanej długości ze strumienia.

func string BR_Text(var int length)
-
Parametry
  • var int length
    Liczba znaków do odczytania

Zwracana wartość

Funkcja zwraca odczytany ciąg znaków.

BR_NextLine

Zmienia pozycję odczytu na następny akapit, utworzony za pomocą BW_NextLine.

func void BR_NextLine()
-

Wywołania funkcji silnika

WIN_GetLastError

Wywołanie funkcji GetLastError z Win32 API.

func int WIN_GetLastError()
-
Zwracana wartość

Funkcja zwraca kod ostatniego błędu wątku wywołującego.

WIN_CreateFile

Wywołanie funkcji CreateFileA z Win32 API.

func int WIN_CreateFile(var string lpFileName,var int dwDesiredAccess,var int dwShareMode,var int lpSecurityAttributes,var int dwCreationDisposition,var int dwFlagsAndAttributes,var int hTemplateFile)
-
Parametry

Pełny opis parametrów można znaleźć tutaj

Zwracana wartość

Informacje o zwracanej wartości znajdziesz tutaj

WIN_WriteFile

Wywołanie funkcji WriteFile z Win32 API.

func void WIN_WriteFile(var int hFile,var int lpBuffer,var int nNumberOfBytesToWrite,var int lpNumberOfBytesWritten,var int lpOverlapped)
-
Parametry

Pełny opis parametrów można znaleźć tutaj

WIN_ReadFile

Wywołanie funkcji ReadFile z Win32 API.

func void WIN_ReadFile(var int hFile,var int lpBuffer,var int nNumberOfBytesToRead,var int lpNumberOfBytesRead,var int lpOverlapped)
-
Parametry

Pełny opis parametrów można znaleźć tutaj

WIN_CloseHandle

Wywołanie funkcji CloseHandle z Win32 API.

func void WIN_CloseHandle(var int hObject)
-
Parametry

Pełny opis parametrów można znaleźć tutaj

WIN_GetFileSize

Wywołanie funkcji GetFileSize z Win32 API.

func int WIN_GetFileSize(var int hFile,var int lpFileSizeHigh)
-
Parametry

Pełny opis parametrów można znaleźć tutaj

Zwracana wartość

Informacje o zwracanej wartości znajdziesz tutaj

Constants

Dodatkowo istnieją pewne stałe zdefiniowane do użycia z określonymi wywołaniami funkcji silnika.

1
-2
-3
-4
-5
-6
-7
-8
const int CREATE_ALWAYS = 2;
-const int OPEN_EXISTING = 3;
-const int GENERIC_ALL = 1073741824;
-const int GENERIC_READ = -2147483648;
-const int FILE_SHARE_READ = 1;
-const int FILE_SHARE_WRITE = 2;
-const int FILE_SHARE_DELETE = 4;
-const int FILE_ATTRIBUTE_NORMAL = 128;
-

Przykłady

Zapisywanie i wczytywanie zmiennych

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
const string filename = "System\MySave.sav";
-
-var string s0; // ciąg znaków
-var int    i1; // liczba całkowita
-var int    b2; // bajt
-var string c3; // znak
-
-func void SaveMyData()
-
-
-{
-    if(BW_NewFile(filename))  // Utwórz nowy plik:
-    { 
-        BW_String(s0);
-        BW_Int(i1);
-        BW_Byte(b2);
-        BW_Char(c3);          // Zapisz dane...
-        BW_Close();           // ...i zamknij.
-    };
-};
-
-func void LoadMyData() {
-    if(BR_OpenFile(filename)) // Spróbuj otworzyć plik:
-    { 
-        s0 = BR_String();
-        i1 = BR_Int();
-        b2 = BR_Byte();
-        c3 = BR_Char();       // Odczytaj wartości...
-        BR_Close();           // ...i zamknij.
-    }
-    else 
-    {
-        SaveMyData();         // W przeciwnym razie utwórz plik z zapisem.
-    };
-};
-

Gratulacje dla gracza

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
func void Certificate(var string Username, var int Score) 
-{
-    var string filename; filename = ConcatStrings(Username, "'s Certificate.txt");
-    BW_NewFile(filename); // Nazwa użytkownika + "s Certificate.txt". Plik jest w katalogu Gothic.
-    BW_Text("Gratulacje "); BW_Text(Username);
-    BW_TextLine("!");
-
-    BW_Text("Zdobyłeś ");
-    BW_Text(IntToString(Score)); // Nie BW_Int!
-    BW_TextLine(" punktów w tej grze.");
-
-    BW_NextLine();
-
-    BW_Text("Z wyrazami szacunku, Autor");
-    BW_Close();
-
-    /*
-       Przy wywołaniu:  Certificate("Player", 1000);
-       zostanie utworzony plik o nazwie 'Player's Certificate.txt', który zawierać będzie:
-
-        Gratulacje NazwaGracza!
-        Zdobyłeś 1000 punktów w tej grze.
-
-        Z wyrazami szacunku, Autor
-    */
-};
-

Położenie postaci NPC

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
func void BW_NpcPosition(var C_NPC slf) 
-{
-    var int ptr; ptr = MEM_Alloc(60);                // 16 * 4
-    MEM_CopyBytes(MEM_InstToPtr(slf) + 60, ptr, 60); // Skopiuj slf.trafoObjToWorld
-    BW_Bytes(ptr, 60);                               // Zapisz skopiowane 60 bajtów
-    MEM_Free(ptr);                                   // I posprzątaj...
-};
-
-func void BR_NpcPosition(var C_NPC slf) 
-{
-    var int ptr; ptr = BR_Bytes(60);                 // Odczytaj 60 bajtów
-    MEM_CopyBytes(ptr, MEM_InstToPtr(slf) + 60, 60); // Wklej z powrotem do slf
-    MEM_Free(ptr);                                   // I posprzątaj ponownie...
-};
-
-/*
-   Użycie standardowe:
-     BW_NewFile(file);
-     BW_NpcPosition(hero);
-     BW_Close();
-*/
-

Uwaga

Przykłady zostały pierwotnie napisane przez Gottfrieda i opublikowane na forum World of Gothic.

`

\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/lego/tools/event_handler/index.html b/pl/zengin/scripts/extenders/lego/tools/event_handler/index.html deleted file mode 100644 index aa7b820bc1..0000000000 --- a/pl/zengin/scripts/extenders/lego/tools/event_handler/index.html +++ /dev/null @@ -1,55 +0,0 @@ - EventHandler - Gothic Modding Community

EventHandler

This package allows to create new events and trigger them at desired times. The Gamestate package already uses it.

Warning

The EventHandler requires some basic understanding of the PermMem. The documentation can be found here.

Dependencies

Initialization

Initialize with LeGo_EventHandler flag.

LeGo_Init(LeGo_EventHandler);
-

Implementation

EventHandler.d on GitHub

Functions

Event_Create

Creates a new event and returns a handle to it.

func int Event_Create()
-
Return value

The function returns a new PermMem handle to an event.

Event_Delete

Alias to PermMem delete. Cleans up the handle.

func void Event_Delete(var int event)
-
Parameters
  • var int event
    Handle returned from Event_Create

Event_Empty

Checks whether the event is "empty", i.e. nothing will happen after its execution.

func int Event_Empty(var int event)
-
Parameters
  • var int event
    Handle returned from Event_Create

Return value

The function returns TRUE if event is empty, FALSE is returned otherwise.

Event_Has

Checks if function is added to the event.

func int Event_Has(var int event, var func function)
-
Parameters
  • var int event
    Handle returned from Event_Create
  • var func function
    Checked function

Return value

The function returns TRUE if function is added, FALSE is returned otherwise.

Event_Add

Adds an event handler function. The handler is called after running Event_Execute.

func void Event_Add(var int event, var func function)
-
Parameters
  • var int event
    Handle returned from Event_Create
  • var func function
    Function to be added

Event_AddOnce

Event_Add but checks if the handler function is already added, to prevent duplicates.

func void Event_AddOnce(var int event, var func function)
-
Parameters
  • var int event
    Handle returned from Event_Create
  • var func function
    Function to be added

Event_Remove

Removes the event handler function from the event.

func void Event_Remove(var int event, var func function)
-
Parameters
  • var int event
    Handle returned from Event_Create
  • var func function
    Function to be removed

Event_Execute

Core of the package. Calls all functions registered via Event_Add and Event_AddOnce.

func void Event_Execute(var int event, var int data)
-
Parameters
  • var int event
    Handle returned from Event_Create
  • var int data
    Int parameter passed to all executed functions

Ptr functions

Tip

The pointer functions are used internally by the previous functions. If you created an event with Event_Create use functions without Ptr in the name, but if you created event with EventPtr_Create use only Ptr functions. The normal user will probably never need the pointer versions, however the choice, which one to use is yours.

EventPtr_Create

Creates a new event and returns a pointer to it.

func int EventPtr_Create()
-
Return value

The function returns a new PermMem pointer to an event.

EventPtr_Delete

Alias to PermMem free. Cleans up the pointer.

func void EventPtr_Delete(var int eventPtr)
-
Parameters
  • var int eventPtr
    Pointer returned from EventPtr_Create

EventPtr_Empty

Checks whether the event is "empty", i.e. nothing will happen after its execution.

func int EventPtr_Empty(var int eventPtr)
-
Parameters
  • var int eventPtr
    Pointer returned from EventPtr_Create

Return value

The function returns TRUE if empty, FALSE is returned otherwise.

EventPtr_Has

Checks if function is added to an event.

func int EventPtr_Has(var int eventPtr, var func function)
-
Parameters
  • var int eventPtr
    Pointer returned from EventPtr_Create
  • var func function
    Checked function

Return value

The function returns TRUE if function is added, FALSE is returned otherwise.

EventPtr_HasI

EventPtr_Has but with function ID instead of pointer. Used mainly internally.

func int EventPtr_HasI(var int eventPtr, var int id)
-
Parameters
  • var int eventPtr
    Pointer returned from EventPtr_Create
  • var int id
    ID of checked function

Return value

The function returns TRUE if function is added, FALSE is returned otherwise.

EventPtr_Add

Adds an event handler function. The handler is called after running EventPtr_Execute.

func void EventPtr_Add(var int eventPtr, var func function)
-
Parameters
  • var int eventPtr
    Pointer returned from EventPtr_Create
  • var func function
    Function to be added

EventPtr_AddI

EventPtr_Add but with function ID instead of pointer. Used mainly internally.

func void EventPtr_AddI(var int eventPtr, var int id)
-
Parameters
  • var int eventPtr
    Pointer returned from EventPtr_Create
  • var int id
    ID of function to be added

EventPtr_AddOnce

Event_Add but checks if function is already added, to prevent duplicates.

func void EventPtr_AddOnce(var int eventPtr, var func function)
-
Parameters
  • var int eventPtr
    Pointer returned from EventPtr_Create
  • var func function
    Function to be added

EventPtr_AddOnceI

EventPtr_AddI but checks if function is already added, to prevent duplicates.

func void EventPtr_AddOnceI(var int eventPtr, var int id)
-
Parameters
  • var int eventPtr
    Pointer returned from EventPtr_Create
  • var int id
    ID of function to be added

EventPtr_Remove

Removes a function from the event's call list.

func void EventPtr_Remove(var int eventPtr, var func function)
-
Parameters
  • var int eventPtr
    Pointer returned from EventPtr_Create
  • var func function
    Function to be removed

EventPtr_RemoveI

EventPtr_Remove but with function ID instead of pointer. Used mainly internally.

func void EventPtr_RemoveI(var int eventPtr, var int id)
-
Parameters
  • var int eventPtr
    Pointer returned from EventPtr_Create
  • var int id
    ID of function to be removed

EventPtr_Execute

Core of the package. Calls all functions registered via EventPtr_Add and EventPtr_AddOnce.

func void EventPtr_Execute(var int eventPtr, var int data)
-
  • var int eventPtr
    Pointer returned from EventPtr_Create
  • var int data
    Int parameter passed to all executed functions

Examples

Note

This article has no built-in examples, but the best way to understand how EventHandler works is reading source code of the Gamestate package.

\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/lego/tools/frame_functions/index.html b/pl/zengin/scripts/extenders/lego/tools/frame_functions/index.html deleted file mode 100644 index 9623afb93c..0000000000 --- a/pl/zengin/scripts/extenders/lego/tools/frame_functions/index.html +++ /dev/null @@ -1,119 +0,0 @@ - FrameFunctions - Gothic Modding Community

FrameFunctions

The FrameFunctions package allows to call any number of functions called on every frame, or every specified time delay.

Dependencies

Initialization

Initialize with LeGo_FrameFunctions flag.

LeGo_Init(LeGo_FrameFunctions);
-

Implementation

FrameFunctions.d on GitHub

Functions

FF_Apply

Adds the Daedalus function function to the running FrameFunctions list. function is called each frame.

func void FF_Apply(var func function)
-
Parameters
  • var func function
    Name of the function

FF_ApplyGT

Adds the Daedalus function function to the running FrameFunctions list. function is called every frame except when the game is paused.

func void FF_ApplyGT(var func function)
-
Parameters
  • var func function
    Name of the function

FF_ApplyData

Adds the Daedalus function function to the running FrameFunctions list. The integer parameter data is passed to the function function.

func void FF_ApplyData(var func function, var int data)
-
Parameters
  • var func function
    Name of the function.
  • var int data
    Value passed to the function as a parameter

FF_ApplyExt

Adds the Daedalus function function to the running FrameFunctions list. The function function is called every delay milliseconds, and it runs only cycles number of times.

func void FF_ApplyExt(var func function, var int delay, var int cycles)
-
Parameters
  • var func function
    Name of the function
  • var int delay
    Delay between calls in milliseconds (0 = every frame)
  • var int cycles
    How many times should the function be called (-1 = endless)

FF_ApplyExtGT

Adds the Daedalus function function to the running FrameFunctions list. The function function is called every delay milliseconds, and it runs only cycles number of times. Gets called only when the game is not paused.

func void FF_ApplyExtGT(var func function, var int delay, var int cycles)
-
Parameters
  • var func function
    Name of the function
  • var int delay
    Delay between calls in milliseconds (0 = every frame)
  • var int cycles
    How many times should the function be called (-1 = endless)

FF_ApplyExtData

Adds the Daedalus function function to the running FrameFunctions list. The function function is called every delay milliseconds, and it runs only cycles number of times. The integer parameter data is passed to the function function.

func void FF_ApplyExtData(var func function, var int delay, var int cycles, var int data)
-
Parameters
  • var func function
    Name of the function.
  • var int delay
    Delay between calls in milliseconds (0 = every frame)
  • var int cycles
    How many times should the function be called (-1 = endless)
  • var int data
    Value passed to the function as a parameter

FF_ApplyExtDataGT

Adds the Daedalus function function to the running FrameFunctions list. The function function is called every delay milliseconds, and it runs only cycles number of times. The integer parameter data is passed to the function function. Gets called only when the game is not paused.

func void FF_ApplyExtData(var func function, var int delay, var int cycles, var int data)
-
Parameters
  • var func function
    Name of the function.
  • var int delay
    Delay between calls in milliseconds (0 = every frame)
  • var int cycles
    How many times should the function be called (-1 = endless)
  • var int data
    Value passed to the function as a parameter

FF_ApplyOnce

Alias to FF_Apply, which only adds the function once, even after multiple calls.

func void FF_ApplyOnce(var func function)
-
Parameters
  • var func function
    Name of the function

FF_ApplyOnceGT

Alias to FF_ApplyGT, which only adds the function once, even after multiple calls. Loop doesn't run if the game is paused.

func voidoften FF_ApplyOnceGT(var func function)
-
Parameters
  • var func function
    Name of the function.

FF_ApplyOnceData

Alias to FF_ApplyData, which only adds the function with the specified parameter once, even after multiple calls.

func void FF_ApplyOnceData(var func function, var int data)
-
Parameters
  • var func function
    Name of the function.
  • var int data
    Value passed to the function as a parameter

FF_ApplyOnceExt

Alias to FF_ApplyExt, which adds the function only once, after repeated calls.

func void FF_ApplyOnceExt(var func function, var int delay, var int cycles)
-
Parameters
  • var func function
    Name of the function
  • var int delay
    Delay between calls in milliseconds (0 = every frame)
  • var int cycles
    How many times should the function be called (-1 = endless)

FF_ApplyOnceExtGT

Alias to FF_ApplyExtGT, which adds the function only once after repeated calls. Loop doesn't run if the game is paused.

func void FF_ApplyOnceExtGT(var func function, var int delay, var int cycles)
-
Parameters
  • var func function
    Name of the function
  • var int delay
    Delay between calls in milliseconds (0 = every frame)
  • var int cycles
    How many times should the function be called (-1 = endless)

FF_ApplyOnceExtData

Alias to FF_ApplyExtData, which adds the function with the specified parameter only once, after repeated calls.

func void FF_ApplyOnceExtData(var func function, var int delay, var int cycles, var int data)
-
Parameters
  • var func function
    Name of the function
  • var int delay
    Delay between calls in milliseconds (0 = every frame)
  • var int cycles
    How many times should the function be called (-1 = endless)
  • var int data
    Value passed to the function as a parameter

FF_Active

Checks whether the function is active.

func int FF_Active(var func function)
-
Parameters
  • var func function
    Name of the function

Return value The function returns TRUE if the function is active, FALSE if it is not.

FF_ActiveData

Checks whether the function with the specified data is active.

func int FF_ActiveData(var func function, var int data)
-
Parameters
  • var func function
    Name of the function
  • var int data
    Value previously passed to the function

Return value The function returns TRUE if the function is active, FALSE if it is not.

FF_Remove

Stops a specific FrameFunction.

func void FF_Remove(var func function)
-
Parameters
  • var func function
    Name of the stopped function

FF_RemoveAll

Stops all intsnces of a specific FrameFunction.

func void FF_RemoveAll(var func function)
-
Parameters
  • var func function
    Name of the stopped function

FF_RemoveData

Stops a specific FrameFunction, with the specified value (see FF_ApplyExtData ).

func void FF_RemoveData(var func function, var int data)
-
Parameters
  • var func function
    Name of the stopped function
  • var int data
    Value previously passed to the function as a parameter

Examples

A function called every frame

In this example function MyFunc will be executed on every frame.

1
-2
-3
-4
-5
-6
func void Example1()
-{
-    FF_Apply(MyFunc);
-};
-
-func void MyFunc() {};
-
After the Example1 function is executed the function MyFunc is called on every frame.

The easiest and best way to run a function from the beginning is to call FF-Apply directly in the Init_Global (under LeGo_Init), there is a small problem: If the game is loaded, Init_Global is called a second time, the function is added to the list again and is therefore always called twice.

To avoid this effect, you should check whether the function is already active:

1
-2
-3
-4
-5
-6
-7
func void Example1()
-{
-    if(!FF_Active(MyFunc))
-    {
-        FF_Apply(MyFunc);
-    };
-};
-

However, since LeGo version 2.2 there is an even more pleasant method to do this:

1
-2
-3
-4
func void Example1()
-{
-    FF_ApplyOnce(MyFunc);
-};
-
FF_ApplyOnce function already implements the check for function activity.

Calling delayed function

Create a function, that is called once after 3 seconds.

1
-2
-3
-4
-5
-6
func void Example2()
-{
-    FF_ApplyExt(MyFunc2, 3000, 1); // 3000 ms = 3 s, this function is called only once
-};
-
-func void MyFunc2() {};
-

There is also a Once variant of this function, that prevents adding it twice into the frame function list.

1
-2
-3
-4
func void Example2()
-{
-    FF_ApplyOnceExt(MyFunc2, 3000, 1);
-};
-

Note

FF_ApplyExt(MyFunc, 0, -1) is the same as FF_Apply(MyFunc).

FrameFunction with Timer

Since LeGo 2.2, FrameFunctions package uses the Timer package, so it is possible to pause FrameFunctions at will:

1
-2
-3
-4
-5
-6
-7
-8
-9
func void Example3()
-{
-    FF_ApplyOnceExt(MyFunc3, 4000, 2);
-};
-
-func void MyFunc3()
-{
-    Timer_SetPaused(!Timer_GetPaused());
-};
-
This would pause the timer after 4 seconds and let it continue after 8 seconds.

Warning

Because the timer doesn't run, the frame function execution is stopped as well. This script won't work. If the timer is to be paused, it must be paused outside FrameFunctions.

Note

This is translation of article originally written by Gottfried and Lehona and hosted on LeGo's official documentation website.

\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/lego/tools/hashtables/index.html b/pl/zengin/scripts/extenders/lego/tools/hashtables/index.html deleted file mode 100644 index e5dd81780b..0000000000 --- a/pl/zengin/scripts/extenders/lego/tools/hashtables/index.html +++ /dev/null @@ -1,146 +0,0 @@ - Hashtables - Gothic Modding Community

Hashtables

Hashtables package is an implementation of hashtables in Gothic. Currently (version 2.8.0) only integers are supported as keys. The Hashtables grow automatically.

Dependencies

Initialization

Initialize with LeGo_PermMem flag.

LeGo_Init(LeGo_PermMem);
-

Implementation

Hashtable.d on GitHub

Functions

HT_CreateSized

Generates a hashtable of the specified size.

func int HT_CreateSized(var int size)
-
Parameters
  • var int size
    Size of the hashtable to be created

Return value

The function returns a handle to the created hashtable.

HT_Create

Generates a standard size hashtable.

func int HT_Create()
-
Return value

The function returns a handle to the created hashtable.

HT_Insert

Inserts a value into the Hashtable.

func void HT_Insert(var int handle, var int val, var int key)
-
Parameters
  • var int handle
    Handle of a hashtable
  • var int val
    The value to be inserted
  • var int key
    The key associated with the value

HT_Resize

Changes the size of the hashtable (usually not necessary as it happens automatically).

func void HT_Resize(var int handle, var int size)
-
Parameters
  • var int handle
    Handle of a hashtable
  • var int size
    The new size of the hashtable

HT_Get

Reads a value from the hashtable.

func int HT_Get(var int handle, var int key)
-
Parameters
  • var int handle
    Handle of a hashtable
  • var int key
    The key whose value is to be read

Return value

The function returns the value associated with the key.

HT_Has

Checks if the key already exist in hashtable.

func int HT_Has(var int handle, var int key)
-
Parameters
  • var int handle
    Handle of a hashtable
  • var int key
    The key to be checked Return value

The function returns TRUE if the key exist, FALSE is returned otherwise.

HT_Remove

Removes a key from the hashtable.

func void HT_Remove(var int handle, var int key)
-
Parameters
  • var int handle
    Handle of a hashtable
  • var int key
    The key to be removed

HT_Change

Changes the value of a key already existing in the hashtable.

func void HT_Change(var int handle, var int val, var int key)
-
Parameters
  • var int handle
    Handle of a hashtable
  • var int val
    The new value
  • var int key
    The key whose value is to be changed

HT_InsertOrChange

Inserts a value into the Hashtable, or changes the value if the key already exist into hashtable.

func void HT_InsertOrChange(var int handle, var int val, var int key)
-
Parameters
  • var int handle
    Handle of a hashtable
  • var int val
    The new value
  • var int key
    The key whose value is to be changed or associated with the value.

HT_GetNumber

Returns the number of entries in a hashtable.

func int HT_GetNumber(var int handle)
-
Parameters
  • var int handle
    Handle of a hashtable

Return value

The function returns the number of entries in the hashtable.

HT_ForEach

Performs a function for each value pair in the hashtable.

func void HT_ForEach(var int handle, var func fnc)
-
Parameters
  • var int handle
    Handle of a hashtable
  • var func fnc
    A function with signature void (int key, int val)

HT_Destroy

Deletes the hashtable.

func void HT_Destroy(var int handle)
-
Parameters
  • var int handle
    The handle of the hashtable to be deleted

Examples

Simple operations

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
-37
-38
-39
-40
-41
-42
-43
-44
-45
-46
-47
-48
-49
-50
func void PrintKeyValuePair(var int key, var int val)
-{
-    Print(ConcatStrings(ConcatStrings("Key: ", IntToString(key)), ConcatStrings(", Value: ", IntToString(val))));
-};
-
-func void example()
-{
-    // Create a new hashtable
-    var int hashtableHandle; hashtableHandle = HT_Create();
-
-    // Insert values into the hashtable
-    HT_Insert(hashtableHandle, 42, 1);
-    HT_Insert(hashtableHandle, 23, 2);
-    HT_Insert(hashtableHandle, 56, 3);
-
-    // Get a value from the hashtable
-    var int value; value = HT_Get(hashtableHandle, 2);
-    Print(ConcatStrings("Value associated with key 2: ", IntToString(value)));
-
-    // Check if a key exists in the hashtable
-    if (HT_Has(hashtableHandle, 3))
-    {
-        Print("Key 3 exists in the hashtable.");
-    }
-    else
-    {
-        Print("Key 3 does not exist in the hashtable.");
-    };
-
-    // Remove a key from the hashtable
-    HT_Remove(hashtableHandle, 1);
-
-    // Change the value associated with a key
-    HT_Change(hashtableHandle, 99, 3);
-
-    // Insert a value or change it if the key exists
-    HT_InsertOrChange(hashtableHandle, 123, 4);
-
-    // Get the number of entries in the hashtable
-    var int numEntries; numEntries = HT_GetNumber(hashtableHandle);
-    Print(ConcatStrings("Number of entries in the hashtable: ", IntToString(numEntries)));
-
-
-    // Iterate through the hashtable and print key-value pairs
-    // Function from top of the example is used here
-    HT_ForEach(hashtableHandle, PrintKeyValuePair);
-
-    // Destroy the hashtable
-    HT_Destroy(hashtableHandle);
-};
-
\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/lego/tools/hook_dae/index.html b/pl/zengin/scripts/extenders/lego/tools/hook_dae/index.html deleted file mode 100644 index 2aa39574ee..0000000000 --- a/pl/zengin/scripts/extenders/lego/tools/hook_dae/index.html +++ /dev/null @@ -1,244 +0,0 @@ - HookDaedalus - Gothic Modding Community

HookDaedalus

This package allows hooking daedalus functions. The principle is similar HookEngine. We have a function (hooked function) into which we would like to hook another function (hook function).

Tip

Having to hook a Daedalus function should be pretty rare, because you can simply adjust the corresponding function. However, it may become necessary in some contexts.

Dependencies

N/A

Initialization

N/A

Implementation

HookDaedalus.d on GitHub

Functions

HookDaedalusFunc

Hooks the function.

func void HookDaedalusFunc(var func hooked, var func hook)
-
Parameters
  • var func hooked
    Hooked function
  • var func hook
    Hook function

HookDaedalusFuncF

Alias to the HookDaedalusFunc function.

func void HookDaedalusFuncF(var func hooked, var func hook)
-
Parameters
  • var func hooked
    Hooked function
  • var func hook
    Hook function

HookDaedalusFuncI

HookDaedalusFunc but with function ID.

func void HookDaedalusFuncI(var int hookedID, var int hookID)
-
Parameters
  • var int hookedID
    ID of hooked function
  • var int hookID
    ID of hook function

HookDaedalusFuncS

HookDaedalusFunc but with function name.

func void HookDaedalusFuncS(var string hookedName, var string hookName)
-
Parameters
  • var string hookedName
    Name of hooked function
  • var string hookName
    Name of hook function

IsHookD

Checks whether a function is already hooking another. Each function can be hooked any number of times, but each function can only hook one other.

func int IsHookD(var int funcID)
-
Parameters
  • var int funcID Symbol index of a hook function

Return value

The function returns TRUE if the function is already hooking another, FALSE is returned otherwise.

ContinueCall

Continues the program run with the original function.

func void ContinueCall()
-

PassArgumentI

Passes an integer as an argument to the original function. Must be called before ContinueCall.

func void PassArgumentI(var int i)
-
Parameters
  • var int i
    Integer argument to forward

PassArgumentS

Passes a string as an argument to the original function. Must be called before ContinueCall.

func void PassArgumentS(var string s)
-
Parameters
  • var string s
    String argument to forward

PassArgumentN

Passes an instance as an argument to the original function. Must be called before ContinueCall.

func void PassArgumentN(var instance n)
-
Parameters
  • var instance n
    Instance argument to forward

Examples

Hook before function

We have a hook:

HookDaedalusFunc(hooked, hook);
-
The functions can look like that:
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
func void hooked() 
-{
-    Print("Original function");
-};
-
-func void hook() 
-{
-    Print("Our hook");
-    ContinueCall();
-};
-
The results should look like that
1
-2
Our hook
-Original function
-

Hook after function

We have the same hook:

HookDaedalusFunc(hooked, hook);
-
The functions are also similar, but the ContinueCall(); is called first:
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
func void hooked() 
-{
-    Print("Original function");
-};
-
-func void hook() 
-{
-    ContinueCall();
-    Print("Our hook");
-};
-
The results should look like that:
1
-2
Original function
-Our hook
-

Arguments and return values

If a function to be hooked expects parameters or returns a value, our hooking function should conform to that.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
func int hooked(var int i) 
-{
-     Print("Original function");
-     return i+1;
-};
-
-func int hook(var int i) 
-{
-     Print("Our hook");
-     PassArgumentI(i);
-     ContinueCall();
-};
-
In this case, we may not return the value at the end of the hook because the returned value will just stay on the stack. However, we shouldn't give up on calling PassArgumentI(i) to ensure that it is still on top of the stack when the program continues with hooked.

Manipulation of arguments and return values

We can also manipulate arguments and return values with our hook.

1
-2
-3
-4
-5
-6
-7
-8
-9
func int hook(var int i) 
-{
-    Print("Our hook");
-    PassArgumentI(i+1);     // add 1
-    ContinueCall();
-    i = MEM_PopIntResult();
-    i *= 2;                 // Multiply by 2
-    return i;
-};
-

Multiple hooks

A function can be hooked any number of times, but each function can only hook one. New hooks are always inserted after the previous one. The following example illustrates this quite well.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
-37
-38
-39
-40
-41
-42
-43
-44
-45
-46
-47
-48
-49
-50
-51
-52
-53
-54
-55
-56
-57
-58
HookDaedalusFunc(a, b); // B hooks A
-HookDaedalusFunc(a, c); // C hooks A to B
-HookDaedalusFunc(a, d); // D hooks A to C
-
-HookDaedalusFunc(c, b); // Ignored because B is already hooking a function
-
-var int i; i = a(1);
-
-
-// Hooked function
-func int a(var int i) 
-{
-    MEM_Info(ConcatStrings("---  A: ", IntToString(i)));
-    return i+1;
-};
-
-// First hook function:
-// Replaces `a` because the program run is not continued with ContinueCall
-func int b(var int i) 
-{
-    MEM_Info(ConcatStrings("  -- B: ", IntToString(i)));
-    return i;
-};
-
-// Second hook function:
-// Increments the argument before ContinueCall and then decrements the return value
-func int c(var int i) 
-{
-    MEM_Info(ConcatStrings(" -> C: ", IntToString(i)));
-    passArgumentI(i+1);
-    ContinueCall();
-
-    i = MEM_PopIntResult();
-    i -= 1;
-    MEM_Info(ConcatStrings(" <- C: ", IntToString(i)));
-    return i;
-};
-
-// Third hook function:
-// Increments the argument before ContinueCall and then decrements the return value
-func int d(var int i) 
-{
-    MEM_Info(ConcatStrings("-> D: ", IntToString(i)));
-    passArgumentI(i+1);
-    ContinueCall();
-
-    i = MEM_PopIntResult();
-    i -= 1;
-    MEM_Info(ConcatStrings("<- D: ", IntToString(i)));
-    return i;
-};
-
-// Output:
-// -> D: 1
-//  -> C: 2
-//   -- B: 3
-//  <- C: 2
-// <- D: 1
-
\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/lego/tools/hook_engine/index.html b/pl/zengin/scripts/extenders/lego/tools/hook_engine/index.html deleted file mode 100644 index 25169c5a28..0000000000 --- a/pl/zengin/scripts/extenders/lego/tools/hook_engine/index.html +++ /dev/null @@ -1,66 +0,0 @@ - HookEngine - Gothic Modding Community

HookEngine

This package allows you to hook anywhere in an engine function to run your own Daedalus code.

Tip

Zerxes has provided a list of all engine functions for G2, including the number of bytes to fill in for oldInstr. This list can be found here. This should make it possible for everyone to use the HookEngine effectively without IDA.

Dependencies

N/A

Initialization

N/A

Implementation

HookEngine.d on GitHub

Functions

HookEngine

Attaches a function to an engine function address.

func void HookEngine(var int address, var int oldInstr, var string function)
-
Parameters
  • var int address
    Address of an engine function to which the function should be attached.
  • var int oldInstr
    The length in bytes of the instruction to be found at address, at least 5 bytes. Can be seen in IDA.
  • var string function
    Name of Daedalus function to be called.

HookEngineS

Alias to the HookEngine function.

func void HookEngineS(var int address, var int oldInstr, var string function)
-
Parameters
  • var int address
    Address of an engine function to which the function should be attached.
  • var int oldInstr
    The length in bytes of the instruction to be found at address, at least 5 bytes. Can be seen in IDA.
  • var string function
    Name of Daedalus function to be called.

HookEngineI

Alias to HookEngine with funcID.

func void HookEngineI(var int address, var int oldInstr, var int funcID)
-
Parameters
  • var int address
    Address of an engine function to which the function should be attached.
  • var int oldInstr
    The length in bytes of the instruction to be found at address, at least 5 bytes. Can be seen in IDA.
  • var int funcID
    ID of Daedalus function to be called.

HookEngineF

Alias to HookEngine with func parameter.

func void HookEngineF(var int address, var int oldInstr, var func function)
-
Parameters
  • var int address
    Address of an engine function to which the function should be attached.
  • var int oldInstr
    The length in bytes of the instruction to be found at address, at least 5 bytes. Can be seen in IDA.
  • var func function
    Daedalus function to be called.

IsHooked

Checks if a hook is already present at a given address.

func var int IsHooked(var int address)
-
Parameters
  • var int address
    Address of an engine function.

Return value

The function returns TRUE if the hook already exists at the address, FALSE is returned otherwise.

IsHook

Checks if a hook with a certain function is already present at an address.

func var int IsHook(var int address, var string function)
-
Parameters
  • var int address
    Address of an engine function.
  • var string function
    Name of a function.

Return value

The function returns TRUE if the hook already exists at the address, FALSE is returned otherwise.

IsHookI

Alias to IsHook with a funcID as parameter.

func var int IsHookI(var int address, var int funcID)
-
Parameters
  • var int address
    Address of an engine function.
  • var int funcID
    ID of a function.

Return value

The function returns TRUE if the hook already exists at the address, FALSE is returned otherwise.

IsHookF

Alias to IsHook with a function as parameter.

func var int IsHookF(var int address, var func function)
-
Parameters
  • var int address
    Address of an engine function.
  • var func function
    Daedalus function.

Return value func parameter The function returns TRUE if the hook already exists at the address, FALSE is returned otherwise.

RemoveHook

Removes a function from a hook so that it is no longer called.

func void RemoveHook(var int address, var int oldInstr, var string function)
-
Parameters
  • var int address
    Address of an engine function to which the function should be attached.
  • var int oldInstr
    The length in bytes of the instruction to be found at address, at least 5 bytes. Can be seen in IDA.
  • var string function
    Name of Daedalus function that should no longer be called.

RemoveHookI

Alias to RemoveHook with funcID.

func void RemoveHook(var int address, var int oldInstr, var int funcID)
-
Parameters
  • var int address
    Address of an engine function to which the function should be attached.
  • var int oldInstr
    The length in bytes of the instruction to be found at address, at least 5 bytes. Can be seen in IDA.
  • var int funcID
    ID of Daedalus function that should no longer be called.

RemoveHookF

Alias for RemoveHook with func parameter.

func void RemoveHook(var int address, var int oldInstr, var func function)
-
Parameters
  • var int address
    Address of an engine function to which the function should be attached.
  • var int oldInstr
    The length in bytes of the instruction to be found at address, at least 5 bytes. Can be seen in IDA.
  • var func function
    Daedalus function that should no longer be called.

ReplaceEngineFunc

Replaces an engine function with a Daedalus function.

func void ReplaceEngineFunc(var int address, var int thiscall_numparams, var string replaceFunc)
-
Parameters
  • var int address
    Address of the engine function to be replaced.
  • var int thiscall_numparams
    Number of parameters passed to the engine function, if it is a stdcall or thiscall (otherwise 0).
  • var string replaceFunc
    Name of a Daedalus function to be called instead.

ReplaceEngineFuncI

Alias to ReplaceEngineFunc with funcID.

func void ReplaceEngineFunc(var int address, var int thiscall_numparams, var int funcID)
-
Parameters
  • var int address
    Address of the engine function to be replaced.
  • var int thiscall_numparams
    Number of parameters passed to the engine function, if it is a stdcall or thiscall (otherwise 0).
  • var int funcID
    ID of a Daedalus function to be called instead.

ReplaceEngineFuncF

Alias to ReplaceEngineFunc with func parameter.

func void ReplaceEngineFunc(var int address, var int thiscall_numparams, var func function)
-
Parameters
  • var int address
    Address of the engine function to be replaced.
  • var int thiscall_numparams
    Number of parameters passed to the engine function, if it is a stdcall or thiscall (otherwise 0).
  • var func function
    Daedalus function to be called instead.

DisableEngineFunc

Makes sure that an engine function is simply skipped. This is very delicate and will not always work so easily.

func void DisableEngineFunc(var int address, var int thiscall_numparams)
-
Parameters
  • var int address
    Address of the engine function to be skipped.
  • var int thiscall_numparams
    Number of parameters passed to the engine function, if it is a stdcall or thiscall (otherwise 0).

Hook_ReturnFalse

Simple function to replace return FALSE in hook.

func void Hook_ReturnFalse()
-

Hook_ReturnTrue

Simple function to replace return TRUE in hook.

func void Hook_ReturnTrue()
-

Registers

In addition the HookEngine package implement x86 32-bit registers that can be used to access hooked function parameters.

1
-2
-3
-4
-5
-6
-7
-8
var int EAX;
-var int ECX;
-var int EDX;
-var int EBX;
-var int ESP;
-var int EBP;
-var int ESI;
-var int EDI;    
-
\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/lego/tools/int64/index.html b/pl/zengin/scripts/extenders/lego/tools/int64/index.html deleted file mode 100644 index 2b936e0c28..0000000000 --- a/pl/zengin/scripts/extenders/lego/tools/int64/index.html +++ /dev/null @@ -1,58 +0,0 @@ - Int64 - Gothic Modding Community

Int64

Int64 implements basic arithmetic for 64-bit integers based on machine code (hence the function signatures are also in machine code style). Furthermore, Int64 offers the constructor int64@ for Int64 objects, but mk64 expects a pointer, not a handle.

Dependencies

N/A

Initialization

N/A

Implementation

Int64.d on GitHub

Functions

mk64

Writes lo and hi in one place (dest). Makes Int64, hi has to be -1 for negative 32bit lo.

func void mk64(var int dest, var int hi, var int lo)
-
Parameters
  • var int dest
    A pointer to an Int64 object or just 8 bytes of free memory.
  • var int hi
    High part of integer.
  • var int lo
    Low part of integer.
Examples

Function looks like that:

1
-2
-3
-4
    func void mk64(var int dest, var int lo, var int hi) {
-    MEM_WriteInt(dest, lo);
-    MEM_WriteInt(dest+4, hi);
-    };
-
So if you want to get 9876543210 low part should be set to 1286608618 and the high part to 2
1
-2
-3
-4
-5
-6
var int ptr; ptr = MEM_Alloc(8);
-var int low; low = 1286608618;
-var int high; high = 2;
-mk64(ptr, low, high);
-// ...
-MEM_Free(ptr);
-

neg64

Negates the integer: *dest <- -(*dest)

func void neg64(var int dest)
-
Parameters
  • var int dest
    A pointer to an Int64 object or just 8 bytes of free memory.

add64

Adds src to dest: *dest <- *dest + *src

func void add64(var int dest, var int src)
-
Parameters
  • var int dest
    A pointer to an Int64 object or just 8 bytes of free memory. Will be changed.
  • var int src
    A pointer to an Int64 object. Will not change.

sub64

Subtracts src from dest: *dest <- *dest - *src

func void sub64(var int dest, var int src)
-
Parameters
  • var int dest
    A pointer to an Int64 object or just 8 bytes of free memory. Will be changed.
  • var int src
    A pointer to an Int64 object. Will not change.

mul64

Multiplies dest by src: *dest <- (*dest) * (*src)

func void mul64(var int dest, var int src)
-
Parameters
  • var int dest
    A pointer to an Int64 object or just 8 bytes of free memory. Will be changed.
  • var int src
    A pointer to an Int64 object. Will not change.

div64

Divides dest by src: *dest <- *dest / *src

func void mul64(var int dest, var int src)
-
Parameters
  • var int dest
    A pointer to an Int64 object or just 8 bytes of free memory. Will be changed.
  • var int src
    A pointer to an Int64 object. Will not change.
\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/lego/tools/interface/index.html b/pl/zengin/scripts/extenders/lego/tools/interface/index.html deleted file mode 100644 index 5c28ebeca4..0000000000 --- a/pl/zengin/scripts/extenders/lego/tools/interface/index.html +++ /dev/null @@ -1,249 +0,0 @@ - Interface - Gothic Modding Community

Interface

This package offers a lot of useful functions to work with the 2D interface.

Dependencies

Initialization

Initialize with LeGo_Interface and LeGo_PrintS flag.

LeGo_Init(LeGo_Interface | LeGo_PrintS);
-

Implementation

Interface.d on GitHub

Functions

sysGetTime

Better alternative for MEM_GetSysTime() from Ikarus.

func int sysGetTime()
-
Return value

The function returns elapsed time since game (system) startup.

RGBA

Generates a full zColor.

func int RGBA(var int r, var int g, var int b, var int a)
-
Parameters
  • var int r
    Red channel value (0..255)
  • var int g
    Green channel value (0..255)
  • var int b
    Blue channel value (0..255)
  • var int a
    Alpha (0..255, 0 = invisible)

Return value

The function returns a zColor object.

ChangeAlpha

Overrides the alpha value of a given zColor.

func int ChangeAlpha(var int zCol, var int a)
-
Parameters
  • var int zCol
    zColor to modify
  • var int a
    New alpha value

Return value

The function returns a modified zColor object.

GetAlpha

Returns the alpha value of a given zColor.

func int GetAlpha(var int zCol)
-
Parameters
  • var int zCol
    zColor to get alpha from

Creates a new zCViewText on the screen with PermMem that can be freely edited.

func int Print_CreateText(var string text, var string font)
-
Parameters
  • var string text
    The text of the zCViewText
  • var string font
    Font of text

Return value

The function returns a handle to zCViewText.

Print_CreateText but returns pointer to zCViewText instead of handle.

func int Print_CreateTextPtr(var string text, var string font)
-
Parameters
  • var string text
    The text of the zCViewText
  • var string font
    Font of text

Return value

The function returns a pointer to zCViewText.

Print_CreateTextPtr but with additional parameter to chose color of text.

func int Print_CreateTextPtrColored(var string text, var string font, var int color)
-
Parameters
  • var string text
    The text of the zCViewText
  • var string font
    Font of text
  • var int color
    zColor e.g. generated with RGBA function

Return value

The function returns a pointer to zCViewText.

Returns zCViewText instance from handle.

func zCViewText Print_GetText(var int hndl)
-
Parameters
  • var int hndl
    Handle to zCViewText

Returns zCViewText pointer from handle.

func int Print_GetTextPtr(var int hndl)
-
Parameters
  • var int hndl
    Handle to zCViewText

Removes a zCViewText from the screen.

func void Print_DeleteText(var int hndl)
-
Parameters

Changes the alpha value of a given zCViewText.

func void Print_SetAlpha(var int hndl, var int a)
-
Parameters
  • var int hndl
    Handle to zCViewText
  • var int a
    New alpha value

PrintPtr_SetAlpha

Print_SetAlpha but with pointer to zCViewText instead of handle.

func void PrintPtr_SetAlpha(var int ptr, var int a)
-
Parameters
  • var int ptr
    Pointer to zCViewText
  • var int a
    New alpha value

Writes the current resolution to the Print_Screen array and the current aspect ratio to Print_Ratio variable.

func void Print_GetScreenSize()
-

An int array holding the current resolution. (Filled by Print_GetScreenSize)

int Print_Screen[2];
-
  • Print_Screen[PS_X] is the horizontal resolution

  • Print_Screen[PS_Y] is the vertical resolution

A float variable that holds the current aspect ratio. (Filled by Print_GetScreenSize)

int Print_Ratio;
-

PS_VMax

An int constant that holds the highest possible value of a virtual coordinate.

const int PS_VMax = 8192;
-

Convents pixel position to a virtual position.

func int Print_ToVirtual(var int pxl, var int dim)
-
Parameters
  • var int pxl
    Pixel position to convert
  • var int dim
    PS_X or PS_Y (see Print_Screen)

Return value

The function returns a virtual position of a given pixel position.

Print_ToVirtual but returns Ikarus float value instead of integer.

func int Print_ToVirtualF(var int pxl, var int dim)
-
Parameters
  • var int pxl
    Pixel position to convert
  • var int dim
    PS_X or PS_Y (see Print_Screen)

Return value

The function returns a virtual position of a given pixel position as Ikarus float.

Convents virtual position to a pixel position.

func int Print_ToPixel(var int vrt, var int dim)
-
Parameters
  • var int vrt
    Virtual position to convert
  • var int dim
    PS_X or PS_Y (see Print_Screen)

Return value

The function returns a pixel position of a given virtual position.

Print_ToPixel but returns Ikarus float value instead of integer.

func int Print_ToPixelF(var int vrt, var int dim)
-
Parameters
  • var int vrt
    Virtual position to convert
  • var int dim
    PS_X or PS_Y (see Print_Screen)

Return value

The function returns a pixel position of a given virtual position as Ikarus float.

Gets the size in the specified dimension in ratioed by the screen.

func int Print_ToRatio(var int size, var int dim)
-
Parameters
  • var int size
    Size to convert
  • var int dim
    PS_X or PS_Y (see Print_Screen)

Return value

The function returns size correctly calculated to the ratio.

Example

If you have a view and the view you need to be a square of 400 units, you would do:

1
-2
height = Print_ToRatio(400, PS_Y);
-width = 400;
-
This is because width is always the max in virtual coordinates - 8192 virtual points and the height has a different height based on the ratio, this function calculates it for you.

PS_X can be used in function, if you already have the height but need the width in the correct ratio.

Converts angle in degrees to radians.

func int Print_ToRadian(var int angle)
-
Parameters
  • var int angle
    Angle in degrees

Return value

The function returns calculated angle in radians.

Converts angle in radians to degrees.

func int Print_ToDegree(var int angle)
-
Parameters
  • var int angle
    Angle in radians

Return value

The function returns calculated angle in degrees.

Returns a pointer to a zCFont by its name.

func int Print_GetFontPtr(var string font)
-
Parameters
  • var string font
    Name of font

Returns a name of a zCFont from its pointer.

func string Print_GetFontName(var int fontPtr)
-
Parameters
  • var int fontPtr
    Pointer to font

Returns the width of a string in pixels.

func int Print_GetStringWidth(var string s, var string font)
-
Parameters
  • var string s
    Measured string
  • var string font
    Name of font

Print_GetStringWidth but with zCFont pointer instead of name.

func int Print_GetStringWidthPtr(var string s, var int font)
-
Parameters
  • var string s
    Measured string
  • var int font
    zCFont pointer

Returns the height of a string in pixels.

func int Print_GetFontHeight(var string font)
-
Parameters
  • var string font
    Name of font

Like the external PrintScreen, writes a text on the screen, but with more options.

func int Print_Ext(var int x, var int y, var string text, var string font, var int color, var int time)
-
Parameters
  • var int x
    X coordinate on the screen (virtual)
  • var int y
    Y coordinate on the screen (virtual)
  • var string text
    Displayed text
  • var string font
    Name of font
  • var int color
    zColor e.g. generated with RGBA function
  • var int time
    display time in milliseconds (-1 = permanent)

Return value

If time == -1, a valid handle is returned. If time != -1, the print is only volatile and no handle is returned.

Example
1
-2
-3
-4
-5
func void Example1()
-{
-    //           x, y, text,   font,        color,                time
-    Print_ExtPxl(2, 2, "Text", FONT_Screen, RGBA(255, 0, 0, 128), 500);
-};
-

Print_Ext but with pixel coordinates instead of virtual.

func int Print_ExtPxl(var int x, var int y, var string text, var string font, var int color, var int time)
-
Parameters
  • var int x
    X coordinate on the screen (pixel)
  • var int y
    Y coordinate on the screen (pixel)
  • var string text
    Displayed text
  • var string font
    Name of font
  • var int color
    zColor e.g. generated with RGBA function
  • var int time
    display time in milliseconds (-1 = permanent)

Return value

If time == -1, a valid handle is returned. If time != -1, the print is only volatile and no handle is returned.

Returns the longest line from text as a string, using default line separator tilde ~.

func string Print_LongestLine(var string text, var string font)
-
Parameters
  • var string text
    Measured text
  • var string font
    Name of font

Returns the longest line from text as a string, but you specify new line separator.

func string Print_LongestLineExt(var string text, var string font, var string separator)
-
Parameters
  • var string text
    Measured text
  • var string font
    Name of font
  • var string separator
    New line separator

Returns the longest line width in pixels, using default line separator tilde ~.

func int Print_LongestLineLength(var string text, var string font)
-
Parameters
  • var string text
    Measured text
  • var string font
    Name of font

Returns the longest line width in pixels, but allows you to specify new line separator.

func int Print_LongestLineLengthExt(var string text, var string font, var string separator)
-
Parameters
  • var string text
    Measured text
  • var string font
    Name of font
  • var string separator
    New line separator

Creates a text field (view with text) using virtual coordinates.

func int Print_TextField(var int x, var int y, var string text, var string font, var int height)
-
Parameters
  • var int x
    X coordinate (virtual)
  • var int y
    Y coordinate (virtual)
  • var string text
    Text to be printed
  • var string font
    Name of font
  • var int height
    A specific line height

Return value

The function returns a text field pointer. Here is how it is used:

1
-2
var zCView view; view = get(viewHndl);
-view.textLines_next = Print_TextField(x, y, text, FONT, fontHeight);
-

Print_TextField but with pixel coordinates.

func int Print_TextFieldPxl(var int x, var int y, var string text, var string font)
-
Parameters
  • var int x
    X coordinate (pixel)
  • var int y
    Y coordinate (pixel)
  • var string text
    Text to be printed
  • var string font
    Name of font

Return value

The function returns a text field pointer. Look at the Print_TextField return value to see an example.

Print_TextField but you specify the color of text.

func int Print_TextFieldColored(var int x, var int y, var string text, var string font, var int height, var int color)
-
Parameters
  • var int x
    X coordinate (virtual)
  • var int y
    Y coordinate (virtual)
  • var string text
    Text to be printed
  • var string font
    Name of font
  • var int height
    A specific line height
  • var int color
    zColor e.g. generated with RGBA function

Return value

The function returns a text field pointer. Look at the Print_TextField return value to see an example.

PrintS

Same function as the external Print, but with smooth animations. The effect can be changed as desired with the user constants.

func void PrintS(var string txt)
-
Parameters
  • var string txt
    Printed text

PrintS_Ext

PrintS but with an additional parameter to choose the color of the text.

func void PrintS_Ext(var string txt, var int color)
-
Parameters
  • var string txt
    Printed text
  • var int color
    zColor e.g. generated with RGBA function

AI_PrintS

Version of PrintS that enqueue in given NPCs AI queue.

func void AI_PrintS(var c_npc slf, var string txt)
-
Parameters
  • var c_npc slf
    NPC to whose AI queue the function is enqueued
  • var string txt
    Printed text

AI_PrintS_Ext

Version of PrintS_Ext that enqueue in given NPCs AI queue.

func void AI_PrintS_Ext(var c_npc slf, var string txt, var int color)
-
Parameters
  • var c_npc slf
    NPC to whose AI queue the function is enqueued
  • var string txt
    Printed text
  • var int color
    zColor e.g. generated with RGBA function

Examples

Manage a print via zCViewText

It is also possible to create the text only via Print_CreateText and set it yourself. In this example, a text should fly over the image from left to right and be deleted again. The movement is handled by Anim8:

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
var int MyText;
-var int MyAnim8;
-func void PrintMyScrollingText(var string text) {
-    MyText = Print_CreateText(text, FONT_Screen); // We create an empty text item with the font FONT_Screen
-
-    var zCViewText MyTextObject; MyTextObject = Print_GetText(MyText); // Now we get the empty text item in a zCViewText
-
-    MyTextObject.posx = 1;      // adjust position
-    MyTextObject.posy = 1;      // ATTENTION: These values are virtual, i.e.: 0 = far left, 8192 = far right (i.e. no pixel specification)
-                                // (But if I prefer to have pixel coordinates I could use e.g. Print_ToVirtual)
-    MyTextObject.timed = false; // The text should not be timed (not disappear)
-
-    // Anim8 will animate a text
-    // First we need a new Anim8 object:
-    MyAnim8 = Anim8_New(1, false); // Start position is 1 and this value is not a float
-
-    Anim8(MyAnim8, 8192, 2000, A8_Constant); // Target Position is 8192, Duration is 2000 milliseconds, and Movement Form is Constant
-
-    // Now all we need is a loop that matches the x value of the text to the value of Anim8:
-    FF_Apply(ScrollMyText);
-};
-
-func void ScrollMyText() {
-    var zCViewText MyTextObject; MyTextObject = Print_GetText(MyText); // Get the text as an object again
-
-    // And now compare the values:
-    MyTextObject.posx = Anim8_Get(MyAnim8);
-
-    // When Anim8 is done with that, we end the loop and delete the text:
-    if(Anim8_Empty(MyAnim8)) {
-        Print_DeleteText(MyText);
-        FF_Remove(ScrollMyText);
-        // The Anim8 object must of course also be deleted. We don't need it anymore.
-        Anim8_Delete(MyAnim8);
-    };
-};
-

Manage a print via zCViewText with LeGo 2.2+

In those days it was perhaps pleasant, but today it is no longer. Anim8 has seen a few improvements with LeGo 2.2 that make it much easier to create the same effect:

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
-37
-38
-39
-40
-41
-42
-43
-44
var int MyText;
-var int MyAnim8;
-func void PrintMyScrollingText(var string text) {
-    // Create and set text:
-    MyText = Print_CreateText(text, FONT_Screen);
-
-    var zCViewText MyTextObject; MyTextObject = Print_GetText(MyText);
-
-    MyTextObject.posx = 1;
-    MyTextObject.posy = 1;
-
-    MyTextObject.timed = false;
-
-    // But now comes the trick: We use Anim8_NewExt, this allows us to set a "Handler" and "Data".
-    MyAnim8 = Anim8_NewExt(1, ScrollMyText, MyText, false);
-
-    // ScrollMyText is passed as the handler and MyText as the data.
-    // In concrete terms, this means: ScrollMyText is always called
-    // when Anim8 has recalculated the position.
-    // Pass data and the new position as parameters. Let's see how it goes.
-
-    // Set the animation again as usual:
-    Anim8(MyAnim8, 8192, 2000, A8_Constant);
-
-    // And this time no FrameFunction.
-    // Instead, we tell Anim8 to clean up by itself when it's done:
-    Anim8_RemoveIfEmpty(MyAnim8, true);
-
-    // The text should also disappear by itself:
-    Anim8_RemoveDataIfEmpty(MyAnim8, true);
-
-    // Since MyText is a handle, this will work.
-    // If MyText were a pointer, RemoveDataIfEmpty should not be activated, it would lead to an error message.
-};
-
-func void ScrollMyText(var int MyText, var int Position) {
-     // Get the text as an object again
-    var zCViewText MyTextObject; MyTextObject = Print_GetText(MyText);
-
-    // And now compare the values:
-    MyTextObject.posx = Position;
-
-    // Since Anim8 does the deleting itself, we don't have to worry about that.
-};
-
\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/lego/tools/item_helper/index.html b/pl/zengin/scripts/extenders/lego/tools/item_helper/index.html deleted file mode 100644 index c7502889b8..0000000000 --- a/pl/zengin/scripts/extenders/lego/tools/item_helper/index.html +++ /dev/null @@ -1,35 +0,0 @@ - ItemHelper - Gothic Modding Community

ItemHelper - pomocnik do przedmiotów

Ten pakiet jest bardzo prosty - pobiera wskaźnik oCItem z instancji C_ITEM ważnej dla bieżącego świata i sesji.

Warning

Upewnij się, że każdy świat ma waypoint o nazwie TOT (po niemiecku "martwy"). Ikarus i LeGo potrzebują tego punktu nawigacyjnego, aby odradzać pomocniczych NPC. Jest to szczególnie ważne w Gothicu 1, ponieważ jego światy nie mają waypointu TOT.

Zależności

Nie dotyczy.

Inicjalizacja

Nie dotyczy.

Implementacja

ItemHelper.d na GitHubie

Funkcje

Itm_GetPtr

func int Itm_GetPtr(var int instance)
-
Parametry
  • var int instance
    Instancja C_ITEM, z której ma zostać pobrany wskaźnik

Zwracana wartość

Funkcja zwraca wskaźnik oCItem instancji C_ITEM.

\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/lego/tools/list/index.html b/pl/zengin/scripts/extenders/lego/tools/list/index.html deleted file mode 100644 index 45302df83e..0000000000 --- a/pl/zengin/scripts/extenders/lego/tools/list/index.html +++ /dev/null @@ -1,60 +0,0 @@ - List - Gothic Modding Community

List

The List package is a collection of functions designed to simplify the handling of zCList and zCListSort lists in daedalus. It offers a range of functions for creating, manipulating, and querying lists.

Dependencies

N/A

Initialization

N/A

Implementation

List.d on GitHub

Functions

Note

All functions, expect List_Compare come with an additional "S" at the end for objects of type zCListSort. (Example: List_NodeS .) Unlike most LeGo packages, pointers are used here, not handles!

List_Create

Creates a list with an initial value.

func int List_Create(var int data)
-
Parameters
  • var int data
    The value of the first list element.

Return value

The function returns a pointer to the created list.

List_Add

Appends a value to the end of the list.

func void List_Add(var int list, var int data)
-
Parameters
  • var int list
    The list to be used.
  • var int data
    The value to be appended.

List_AddFront

Adds a value before the first element of the list.

func void List_AddFront(var int list, var int data)
-
Parameters
  • var int list
    The list to be used.
  • var int data
    The value to be appended.

List_AddOffset

Inserts a value between two list elements.

func void List_AddOffset(var int list, var int offset, var int data)
-
Parameters
  • var int list
    The list to be used.
  • var int offset
    The number of the list element after which the value is inserted.
  • var int data
    The value to be appended.

List_Set

Sets a list element to a specific value.

func void List_Set(var int node, var int data)
-
Parameters
  • var int node
    Pointer to a list element.
  • var int data
    The value to be written into the list element.

List_Get

Retrieves the value of a list element.

func int List_Get(var int list, var int nr)
-
Parameters
  • var int list
    The list to be used.
  • var int nr
    The number of the list element.

Return value

The function returns the value of the specified list element.

List_Node

Returns a pointer to a list element.

func int List_Node(var int list, var int nr)
-
Parameters
  • var int list
    The list to be used.
  • var int nr
    The number of a list element.

Return value

The function returns a pointer to the specified list element.

List_Length

Returns the length of the list (number of all elements).

func int List_Length(var int list)
-
Parameters
  • var int list
    The list to be used.

Return value

The function returns the number of elements in the list.

List_HasLength

Checks if the list has the specified length.

func int List_HasLength(var int list, var int length)
-
Parameters
  • var int list
    The list to be used.
  • var int length
    The desired length.

Return value

The function returns a boolean value indicating whether the list has the specified length or not.

List_End

Returns the last list element of the list.

func int List_End(var int list)
-
Parameters
  • var int list
    The list to be used.

Return value

The function returns a pointer to the last list element.

List_Concat

Concatenates two lists.

func void List_Concat(var int list, var int list2)
-
Parameters
  • var int list
    The first list.
  • var int list2
    The second list. Its beginning is appended to the end of the first list.

List_Contains

Returns the last list element with a specific value.

func int List_Contains(var int list, var int data)
-
Parameters
  • var int list
    The list to be used.
  • var int data
    The value to search for.

Return value

The function returns the number of the last list element with the value data.

List_For

Calls a function for each list element, passing a pointer to the list element as a parameter.

func void List_For(var int list, var string function)
-
Parameters
  • var int list
    The list to be used.
  • var string function
    Name of a function to be called for each list element (void handler(var int node)).

List_ForF

Similar to List_For, but with a function parameter instead of a string.

func void ListForF(var int list, var func function)
-
Parameters
  • var int list
    The list to be used.
  • var func function
    The function to be called for each list element (void handler(var int node)).

List_ForI

Similar to List_For, but with a function parameter instead of a string.

func void List_ForI(var int list, var int funcID)
-
Parameters
  • var int list
    The list to be used.
  • var int funcID
    ID of a function to be called for each list element (void handler(var int node)).

List_Delete

Deletes a list element. All subsequent elements shift position.

func void List_Delete(var int list, var int nr)
-
Parameters
  • var int list
    The list to be used.
  • var int nr
    The number of the list element to be deleted.

List_Destroy

Destroys the entire list.

func void List_Destroy(var int list)
-
Parameters
  • var int list
    The list to be destroyed.

List_ToArray

Returns a pointer to a memory area containing all values of the list.

func int List_ToArray(var int list)
-
Parameters
  • var int list
    The list to be used.

Return value

The function returns a memory area containing all the values of the list.

List_MoveDown

Moves the specified list node down by one position in the list.

func void List_MoveDown(var int list, var int node)
-
Parameters
  • var int list
    The list in which the node is located.
  • var int node
    The node to be moved down.

List_MoveUp

Moves the specified list node up by one position in the list.

func void List_MoveUp(var int list, var int node)
-
Parameters
  • var int list
    The list in which the node is located.
  • var int node
    The node to be moved up.

List_InsertSorted

Inserts a value into a sorted list while preserving the sort order.

func void List_InsertSorted(var int list, var int data, var func compare)
-
Parameters:
  • var int list
    The list to insert the value into.
  • var int data
    The value to be inserted.
  • var func compare
    A comparison function used to determine the sort order.

List_Compare

func int List_Compare(var int data1, var int data2, var func compare)
-
Parameters:
  • var int data1
    The first integer value.
  • var int data2
    The second integer value.
  • var func compare
    One of comparison functions. Return value

The function returns the return value of specified comparison function.

Comparison Functions

The following comparison functions can be used as the compare parameter in the List_InsertSorted and List_Compare function:

List_CmpAscending

Compares two integer values in ascending order.

func int List_CmpAscending(var int data1, var int data2)
-
Parameters:
  • var int data1
    The first integer value.
  • var int data2
    The second integer value.

Return Value:

The function returns TRUE if data1 is greater than data2, FALSE is returned otherwise.

List_CmpDescending

Compares two integer values in descending order.

func int List_CmpDescending(var int data1, var int data2)
-
Parameters:
  • var int data1
    The first integer value.
  • var int data2
    The second integer value.

Return Value:

The function returns TRUE if data1 is less than data2, FALSE is returned otherwise.

List_CmpAscendingUnsigned

Compares two unsigned integer values in ascending order.

func int List_CmpAscendingUnsigned(var int data1, var int data2)
-
Parameters:
  • var int data1
    The first unsigned integer value.
  • var int data2
    The second unsigned integer value.

Return Value:

The function returns TRUE if data1 is greater than data2, FALSE is returned otherwise.

List_CmpDescendingUnsigned

Compares two unsigned integer values in descending order.

func int List_CmpDescendingUnsigned(var int data1, var int data2)
-
Parameters:
  • var int data1
    The first unsigned integer value.
  • var int data2
    The second unsigned integer value.

Return Value:

The function returns TRUE if data1 is less than data2, FALSE is returned otherwise.

\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/lego/tools/locals/index.html b/pl/zengin/scripts/extenders/lego/tools/locals/index.html deleted file mode 100644 index 31f742d198..0000000000 --- a/pl/zengin/scripts/extenders/lego/tools/locals/index.html +++ /dev/null @@ -1,51 +0,0 @@ - Locals - Gothic Modding Community

Locals

Daedalus doesn't offer any local variables, which can quickly lead to problems with recursive functions. The Locals package allows variables to be saved temporarily on a pseudo-stack. Locals is a very specific package. People who work normally with Daedalus will probably never need it. There is also the final function, which can be used to emulate something similar to the final clause in Java.

Dependencies

Initialization

N/A

Implementation

Locals.d on GitHub

Functions

Locals

All that has to be done to enable the Locals is to write this function at the beginning of the function that should receive "real" local variables.

func void locals()
-

Final

It is hard to explain how to use it, but very easy to understand once you've seen an example.

func int Final()
-
Example

With final() it is very easy to emulate Java's final clause, i.e. a block of code can be specified, which is executed after this function is exited, regardless of when or where the function is exited.

1
-2
-3
-4
-5
-6
-7
-8
func void testFinal()
-{
-    if (final())
-    {
-        MEM_InfoBox("Final was called.");
-    };
-    MEM_InfoBox("This will appear before Final");
-};
-
Few lines of code say more than a thousand words.
\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/lego/tools/misc/index.html b/pl/zengin/scripts/extenders/lego/tools/misc/index.html deleted file mode 100644 index 364f15cc9e..0000000000 --- a/pl/zengin/scripts/extenders/lego/tools/misc/index.html +++ /dev/null @@ -1,43 +0,0 @@ - Misc - Gothic Modding Community

Misc - różne

Pakiet Misc wprowadza różne funkcje pomocnicze, które nie pasowały do żadnego innego pakietu.

Zależności

Nie dotyczy.

Inicjalizacja

Nie dotyczy.

Implementacja

Misc.d na GitHubie

Stałe

Pakiet Misc implementuje satłą phi

const int phi = 1070141312; // PI/2
-
która w rzeczywistości jest liczbą pi podzieloną przez 2 zapisaną jako ikarusowy float.

Decymalnie: 1.5707...

Funkcje

atan2f

Oblicza arcus tangens kąta między początkiem a punktem (x, y).

func int atan2f(var int x, var int y)
-
Parametry
  • var int x
    Współrzędna x
  • var int y
    Współrzędna y

Zwracana wartość

Funkcja zwraca arcus tangens w radianach, jako ikarusowy float.

sin

Oblicza sinus kąta podanego w radianach.

func int sin(var int angle)
-
Parametry
  • var int angle
    Kąt w radianach jako ikarusowy float

Zwracana wartość

Funkcja zwraca sinus kąta, jako ikarusowy float.

cos

Oblicza cosinus kąta podanego w radianach.

func int cos(var int angle)
-
Parametry
  • var int angle
    Kąt w radianach jako ikarusowy float

Zwracana wartość

Funkcja zwraca cosinus kąta, jako ikarusowy float.

tan

Oblicza tangens kąta podanego w radianach.

func int tan(var int angle)
-
Parametry
  • var int angle
    Kąt w radianach jako ikarusowy float

Zwracana wartość

Funkcja zwraca tangens kąta, jako ikarusowy float.

asin

Oblicza arcus sinus

func int asin(var int sine)
-
Parametry
  • var int sine
    Sinus kąta jako ikarusowy float

Zwracana wartość

Funkcja zwraca arcus sinus kąta, jako ikarusowy float.

acos

Oblicza arcus cosinus

func int acos(var int cosine)
-
Parametry
  • var int cosine
    Cosinus kąta jako ikarusowy float

Zwracana wartość

Funkcja zwraca arcus cosinus kąta, jako ikarusowy float.

distance2D

Oblicza odległość między dwoma punktami na płaszczyźnie dwuwymiarowej.

func int distance2D(var int x1, var int x2, var int y1, var int y2)
-
Parametry
  • var int x1
    współrzędna x pierwszego punktu
  • var int x2
    współrzędna x drugiego punktu
  • var int y1
    współrzędna y pierwszego punktu
  • var int y2
    współrzędna y drugiego punktu

Zwracana wartość

Funkcja zwraca odległość między dwoma punktami.

distance2Df

Oblicza odległość między dwoma punktami na płaszczyźnie dwuwymiarowej, ale na liczbach zmiennoprzecinkowych (float).

func int distance2Df(var int x1, var int x2, var int y1, var int y2)
-
Parametry
  • var int x1
    współrzędna x pierwszego punktu
  • var int x2
    współrzędna x drugiego punktu
  • var int y1
    współrzędna y pierwszego punktu
  • var int y2
    współrzędna y drugiego punktu

Zwracana wartość

Funkcja zwraca odległość między dwoma punktami, jako ikarusowy float.

\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/lego/tools/permmem/index.html b/pl/zengin/scripts/extenders/lego/tools/permmem/index.html deleted file mode 100644 index fb4bbf1dee..0000000000 --- a/pl/zengin/scripts/extenders/lego/tools/permmem/index.html +++ /dev/null @@ -1,86 +0,0 @@ - PermMem - Gothic Modding Community

PermMem

PermMem is a powerful package that allows classes (or instances) to be used permanently even after loading or restarting by saving them to the ASCII .ZEN archive in the savegame directory. PermMem manages handles that are used to access instances, and provides various functions to manipulate these handles and instances.

Dependencies

Initialization

Initialize with LeGo_PermMem flag.

LeGo_Init(LeGo_PermMem);
-

Implementation

PermMem.d on GitHub

Functions

new

Creates a handle to a new instance of inst.

func int new(var int inst)
-
Parameters
  • var int inst
    A valid instance. Used as "constructor"

Return value

The function returns a new, valid PermMem handle.

create

Similar to new, but here a pointer is returned directly and not a handle. Caution! Not managed by PermMem!

func int create(var int inst)
-
Parameters
  • var int inst
    A valid instance. Used as "constructor"

Return value

The function returns a pointer to the new instance.

wrap

"Wraps" a handle "around" a pointer so that the pointer can be used with any function that expects handles. Only conditionally managed by PermMem.

func int wrap(var int inst, var int ptr)
-
Parameters
  • var int inst
    A valid instance. Determines the type of the handle
  • var int ptr
    Pointer to wrap

Return value

The function returns a handle with ptr as content.

clear

Cleans the handle. After that it is invalid.

func void clear(var int hndl)
-
Parameters
  • var int hndl
    Valid PermMem handle

release

Frees the handle. The reserved memory is not deleted, the handle becomes invalid.

func void release(var int hndl)
-
Parameters
  • var int hndl
    Valid PermMem handle

delete

Cleans the handle just like clear, only the destructor is also called.

func void delete(var int hndl)
-
Parameters
  • var int hndl
    Valid PermMem handle

free

Similar to delete, only here a pointer is destroyed and not a handle. Caution! Not managed by PermMem!

func void free(var int ptr, var int inst)
-
Parameters
  • var int ptr
    The pointer to be cleaned
  • var int inst
    Instance used in create function.

get

Returns the instance of the handle.

func instance get(var int hndl)
-
Parameters
  • var int hndl
    Valid PermMem handle

getPtr

Returns a pointer to instance of handle.

func int getPtr(var int hndl)
-
Parameters
  • var int hndl
    Valid PermMem handle

setPtr

Sets the pointer of a handle.

func void setPtr(var int hndl, var int ptr)
-
Parameters
  • var int hndl
    Valid PermMem handle
  • var int ptr
    New pointer for handle

getInst

Returns the instance used to create the given handle in new function.

func int getInst(var int hndl)
-
Parameters
  • var int hndl
    Valid PermMem handle

numHandles

Returns the number of handles managed by PermMem.

func int numHandles()
-

sizeof

Gets the size of the given instance's class.

func int sizeof(var int inst)
-
Parameters
  • var int inst
    Any instance

Return value

The function returns the size of a given instance's class in bytes.

Hlp_IsValidHandle

Indicates whether the handle exists and is managed by PermMem.

func int Hlp_IsValidHandle(var int hndl)
-
Parameters
  • var int hndl
    PermMem's handle

Return value

The function returns TRUE if the handle is valid (managed by PermMem), FALSE is returned otherwise.

Example

The example function that use Hlp_IsValidHandle is Bar_SetMax form LeGo Bars package. The function first checks if the handle is valid, then gets the instance and changes its parameters.

1
-2
-3
-4
-5
-6
func void Bar_SetMax(var int bar, var int max) 
-{
-    if(!Hlp_IsValidHandle(bar)) { return; };
-    var _bar b; b = get(bar);
-    b.valMax = max;
-};
-

foreachHndl

Executes a function for each handle of an instance.

func void foreachHndl(var int inst, var func fnc)
-
Parameters
  • var int inst
    The function is called for this instance
  • var int inst
    This function is called. The signature is function(int handle)

hasHndl

Checks if PermMem has a handle of this instance.

func int hasHndl(var int inst)
-
Parameters
  • var int inst
    Instance to be checked

Return value

The function returns TRUE if the PermMem has a handle of this instance, FALSE is returned otherwise.

MEM_ReadStringArray

Function moved to PermMem form Ikarus. Reads string from the array at the arrayAddress.

func string MEM_ReadStringArray(var int arrayAddress, var int index)
-
Parameters
  • var int arrayAddress
    Memory address of array
  • var int offset
    Array offset (array index)

Return value

The function returns string from the array if the address is correct.

PM_Exists

Checks if the specified field already exists in the archive. (used with archiver/unarchiver)

func int PM_Exists(var string name)
-
Parameters
  • var string name
    Name of the field

Return value

The function returns TRUE if the field exists in the archive, FALSE is returned otherwise.

Archiver

PM_SaveInt

Saves an integer to the archive.

func void PM_SaveInt (var string name, var int val)
-
Parameters
  • var string name
    Name of the field in saved archive
  • var int val
    Value of the saved integer

PM_SaveFloat

Saves a daedalus float to the archive.

func void PM_SaveFloat (var string name, var int flt)
-
Parameters
  • var string name
    Name of the field in saved archive
  • var int flt
    Value of the saved float

PM_SaveString

Saves a string to the archive.

func void PM_SaveString (var string name, var string val)
-
Parameters
  • var string name
    Name of the field in saved archive
  • var string val
    Saved string

PM_SaveFuncID

Saves a function ID to the archive.

func void PM_SaveFuncID(var string name, var int fnc)
-
Parameters
  • var string name
    Name of the field in saved archive
  • var int fnc
    Saved function ID

PM_SaveFuncOffset

Saves a function offset to the archive.

func void PM_SaveFuncOffset(var string name, var int fnc)
-
Parameters
  • var string name
    Name of the field in saved archive
  • var int fnc
    Saved function offset

PM_SaveFuncPtr

Saves a function pointer to the archive.

func void PM_SaveFuncPtr(var string name, var int fnc)
-
Parameters
  • var string name
    Name of the field in saved archive
  • var int fnc
    Saved function pointer

PM_SaveClassPtr

Saves a pointer of a class to the archive.

func void PM_SaveClassPtr(var string name, var int ptr, var string className)
-
Parameters
  • var string name
    Name of the field in saved archive
  • var int ptr
    Saved pointer
  • var string className
    Name of the class of stored pointer

PM_SaveClass

Saves a class like PM_SaveClassPtr.

func void PM_SaveClass(var string name, var int ptr, var string className)
-
Parameters
  • var string name
    Name of the field in saved archive
  • var int ptr
    Saved class pointer
  • var string className
    Name of the class of stored pointer

PM_SaveIntArray

Saves an array of integers.

func void PM_SaveIntArray(var string name, var int ptr, var int elements)
-
Parameters
  • var string name
    Name of the field in saved archive
  • var int ptr
    Pointer to the array
  • var int elements
    Number of elements in array

PM_SaveStringArray

Saves an array of integers.

func void PM_SaveStringArray(var string name, var int ptr, var int elements)
-
Parameters
  • var string name
    Name of the field in saved archive
  • var int ptr
    Pointer to the array
  • var int elements
    Number of elements in array

Unarchiver

PM_Load

Universal function to load integers, floats, class pointers and int arrays.

func int PM_Load(var string name)
-
Parameters
  • var string name
    Name of the loaded field

Return value The function returns the data existing in the archive at the given field.

PM_LoadInt

Returns an integer stored in the archive.

func int PM_LoadInt(var string name)
-
Parameters
  • var string name
    Name of the loaded field

PM_LoadFloat

Returns a daedalus float stored in the archive.

func int PM_LoadFloat(var string name)
-
Parameters
  • var string name
    Name of the loaded field

PM_LoadString

Returns a string stored in the archive.

func string PM_LoadString(var string name)
-
Parameters
  • var string name
    Name of the loaded field

PM_LoadFuncID

Returns a function ID stored in the archive.

func int PM_LoadFuncID(var string name)
-
Parameters
  • var string name
    Name of the loaded field

PM_LoadFuncOffset

Returns a function offset stored in the archive.

func int PM_LoadFuncOffset(var string name)
-
Parameters
  • var string name
    Name of the loaded field

PM_LoadFuncPtr

Returns a function pointer stored in the archive.

func int PM_LoadFuncPtr(var string name)
-
Parameters
  • var string name
    Name of the loaded field

PM_LoadClassPtr

Returns a class pointer stored in the archive.

func int PM_LoadClassPtr(var string name)
-
Parameters
  • var string name
    Name of the loaded field

PM_LoadClass

Loads a pointer to the class from the archive to destPtr.

func void PM_LoadClass(var string name, var int destPtr)
-
Parameters
  • var string name
    Name of the loaded field
  • var int destPtr
    Destination pointer, the address to where it will deserialize the saved data

PM_LoadArray

Returns a pointer to array stored in the archive.

func int PM_LoadArray(var string name)
-
Parameters
  • var string name
    Name of the loaded field

PM_LoadArrayToPtr

Loads a pointer to array from the archive to destPtr.

func void PM_LoadArrayToPtr(var string name, var int destPtr)
-
Parameters
  • var string name
    Name of the loaded field
  • var int destPtr
    Destination pointer, the address to where it will deserialize the saved data

PM_LoadToPtr

Universal function to load array or class pointer from the archive to destPtr.

func void PM_LoadToPtr(var string name, var int destPtr)
-
Parameters
  • var string name
    Name of the loaded field
  • var int destPtr
    Destination pointer, the address to where it will deserialize the saved data
\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/lego/tools/queue/index.html b/pl/zengin/scripts/extenders/lego/tools/queue/index.html deleted file mode 100644 index c6747176c3..0000000000 --- a/pl/zengin/scripts/extenders/lego/tools/queue/index.html +++ /dev/null @@ -1,48 +0,0 @@ - Queue - Gothic Modding Community

Queue

This package is an implementation of the Queue data structure and a queue for function calls.

Dependencies

Initialization

N/A

Implementation

Queue.d on GitHub

Queue

Q_Create

Creates a new queue and returns a handle to it.

func int Q_Create()
-
Return value

The function returns a handle to a queue.

Q_Enqueue

Appends an integer to the back of the queue

func void Q_Enqueue(var int queue, var int value)
-
Parameters
  • var int queue
    Handle of a queue
  • var int value
    The value to be appended to the queue

Q_IsEmpty

Checks if the queue is empty.

func int Q_IsEmpty(var int queue)
-
Parameters
  • var int queue
    Handle of a queue

Return value

The function returns TRUE if the queue is empty, FALSE is returned otherwise.

Q_Advance

Removes the oldest value from the queue and returns it.

func int Q_Advance(var int queue)
-
Parameters
  • var int queue
    Handle of a queue

Return value

The function returns the oldest value in the queue.

Q_Peek

Returns the oldest value in the queue without removing it.

func int Q_Peek(var int queue)
-
Parameters
  • var int queue
    Handle of a queue

Return value

The function returns the oldest value in the queue.

Q_For

Function with the funcID is called with every element of the list as parameter.
The list element is passed to the function as a zCList pointer.

func void Q_For(var int queue, var int funcID)
-
Parameters
  • var int queue
    Handle of a queue
  • var int funcID
    ID of function that is executed for all values in the queue (signature: void (zCList*))

Q_ForF

Like Q_For, but with function as a parameter instead of a function ID.

func void Q_ForF(var int queue, var func f)
-
Parameters
  • var int queue
    Handle of a queue
  • var func f
    This function is executed for all values in the queue (signature: void (zCList*))

CallbackQueue

CQ_Create

Creates a new callback queue and returns a handle to it.

func int CQ_Create()
-
Return value

The function returns a handle to a callback queue.

CQ_EnqueueNoData

Appends a function to the callback queue.

func void CQ_EnqueueNoData(var int queue, var func function)
-
Parameters
  • var int queue
    Handle of a callback queue
  • var func function
    A function with no return value, expecting no parameter

CQ_EnqueueData

Appends a function together with a value to the callback queue.

func void CQ_EnqueueData(var int queue, var func function, var int data)
-
Parameters
  • var int queue
    Handle of a callback queue
  • var func function
    A function with no return value, expecting an integer as a parameter.
  • var int data
    When calling function, this value is passed as a parameter

CQ_Enqueue

Appends a function together with an optional value to the callback queue. This function should not usually be used. Use CQ_EnqueueData and CQ_EnqueueNoData instead.

func void CQ_Enqueue(var int queue, var int funcID, var int data, var int hasData)
-
Parameters
  • var int queue
    Handle of a callback queue
  • var int funcID
    The function ID of a function to be appended to the callback queue.
  • var int data
    If hasData is not 0, this value is passed to the associated function.
  • var int hasData
    Must be 0 if the function does not expect an integer as a parameter, otherwise not 0.

CQ_IsEmpty

Checks if no function is in the callback queue.

func int CQ_IsEmpty(var int queue)
-
Parameters
  • var int queue
    Handle of a callback queue

Return value

The function returns TRUE if the callback queue is empty, FALSE is returned otherwise.

CQ_Advance

Executes the foremost function of the callback queue and removes it from the callback queue.

func void CQ_Advance(var int queue)
-
Parameters
  • var int queue
    Handle of a callback queue

CQ_Exhaust

Executes all functions contained in the callback queue.

func void CQ_Exhaust(var int queue)
-
Parameters
  • var int queue
    Handle of a callback queue
\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/lego/tools/random/index.html b/pl/zengin/scripts/extenders/lego/tools/random/index.html deleted file mode 100644 index f3e646e226..0000000000 --- a/pl/zengin/scripts/extenders/lego/tools/random/index.html +++ /dev/null @@ -1,40 +0,0 @@ - Random - Gothic Modding Community

Random

Provides more random randomization than Hlp_Random() function.

Dependencies

N/A

Initialization

Initialize with LeGo_Random flag.

LeGo_Init(LeGo_Random);
-

Implementation

Random.d on GitHub

Functions

r_Next

Returns a random number.

func int r_Next()
-
Return value

The function returns a random number.

r_Max

Returns a random number from 0 to max.

func int r_Max(var int max)
-
Parameters
  • var int max
    Maximum value of number

Return value

The function returns a random number from 0 to 'max'.

r_MinMax

Returns a random number from 'min' to 'max'.

func int r_MinMax(var int min, var int max)
-
Parameters
  • var int max
    Maximum value of number
  • var int min
    Minimum value of number

Return value

The function returns a random number from min to max.

r_Init

Initializes the random number generator. Happens optionally in LeGo_Init.

func void r_Init(var int seed)
-
Parameters
  • var int seed
    The initializing value

r_DefaultInit

Initializes the random number generator based on the current time.

func void r_DefaultInit()
-
\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/lego/tools/string_builder/index.html b/pl/zengin/scripts/extenders/lego/tools/string_builder/index.html deleted file mode 100644 index 666f59b2ba..0000000000 --- a/pl/zengin/scripts/extenders/lego/tools/string_builder/index.html +++ /dev/null @@ -1,155 +0,0 @@ - StringBuilder - Gothic Modding Community

StringBuilder

The StringBuilder is a package, designed to easily concatenate multiple elements into a string (without ConcatStrings and IntToString).

All created StringBuilders are transient. All functions starting from SB_InitBuffer, including it, use the active StringBuilder set with SB_New or SB_Use, so there is no var int stringBuilder parameter in functions. A look at the example explains what I mean.

Warning

The StringBuilder works with pointers, not handles like many other LeGo packages.

Dependencies

N/A

Initialization

N/A

Implementation

StringBuilder.d on GitHub

Functions

SB_New

Creates and returns a new StringBuilder. At the same time, this new StringBuilder is set as active. (See SB_Use.)

func int SB_New()
-
Return value

The function returns a pointer to a new StringBuilder.

SB_Use

Marks this StringBuilder as active. It can now be used with the functions.

func void SB_Use(var int sb)
-
Parameters
  • var int sb
    Pointer to a StringBuilder, returned from SB_New

SB_Get

Returns the active StringBuilder.

func int SB_Get()
-
Return value

The function returns the active StringBuilder object - last set with SB_Use or just created with SB_New.

SB_InitBuffer

If the size of the resulting string is already known, the buffer can be set manually. This is usually not necessary.

func void SB_InitBuffer(var int size)
-
Parameters
  • var int size
    Size in bytes. Warning! Only works if the StringBuilder has been newly created!

SB_Clear

Empties the current StringBuilder. It is not destroyed in the process, so it can be used again. If the object has a buffer allocated, the buffer is freed.

func void SB_Clear()
-

SB_Release

Releases the current stream of the StringBuilder. The StringBuilder is destroyed, and the stream can be obtained via SB_GetStream.

func void SB_Release()
-

SB_Destroy

Completely destroys the StringBuilder.

func void SB_Destroy()
-

SB_ToString

Returns a copy of the stream as a string.

func string SB_ToString()
-
Return value

The function returns the copy of the active StringBuilder as a string. If the StringBuilder object doesn't have a buffer allocated, an empty string is returned.

SB_ToStream

Returns a copy of the stream in raw format.

func int SB_ToStream()
-
Return value

The function returns a copy of the stream in raw format (char[])

SB_GetStream

Doesn't copy the stream, but returns it as it is.

func int SB_GetStream()
-
Return value

The function returns the stream as it is. SB_Destroy or SB_Clear destroy the returned pointer.

SB_Length

Returns the current length of the stream. Similar to STR_Len from Ikarus .

func int SB_Length()
-
Return value

The function returns the current length of the active StringBuilder.

SB_SetLength

Sets the length of the stream. When increasing, zero bytes are appended.

func void SB_SetLength(var int length)
-

Stream operations

SB

Appends a string, to the active StringBuilder.

func void SB(var string s)
-
Parameters
  • var string s
    The appended string

SBi

Appends an integer in text form, to the active StringBuilder.

func void SBi(var int i)
-
Parameters
  • var int i
    The appended integer

SBc

Appends a byte, to the active StringBuilder. (e.g. 82 for 'R' - An ASCII table can be quickly found)

func void SBc(var int c)
-
Parameters
  • var int c
    The appended byte (ASCII table character)

SBraw

Appends a raw bytes array, to the active StringBuilder.

func void SBraw(var int ptr, var int len)
-
Parameters
  • var int ptr
    Pointer to the appended array
  • var int len
    Length of an array

SBflt

Appends a Daedalus float in text form, to the active StringBuilder.

func void SBflt(var float x)
-
Parameters
  • var float x
    The appended Daedalus float value

SBf

Appends an Ikarus float in text form, to the active StringBuilder.

func void SBf(var int x)
-
Parameters
  • var float x
    The appended Ikarus float value

SBw

Appends a 4-byte raw data (interpreted as an integer x), to the active StringBuilder.

func void SBw(var int x)
-
Parameters
  • var int i
    The appended value

Independent Functions

STR_Escape

Makes escape sequences out of non-writable characters. For example, newline character \n becomes \\n, tab character \t becomes \\t, etc.

func string STR_Escape(var string s0)
-
Parameters
  • var string s0
    The string to be added escape sequences

Return value

The function returns a new string with escape sequences added for special characters.

STR_Unescape

Counterpart to STR_Escape. Escape sequences like \n, \r or \t are converted back.

func string STR_Unescape(var string s0)
-
Parameters
  • var string s0
    The string to be removed escape sequences

Return value

The function returns a new string with escape sequences replaced by their corresponding characters.

STR_StartsWith

Checks if the input string s starts with the specified prefix string.

func int STR_StartsWith(var string str, var string start) 
-
Parameters
  • var string str
    The string to be checked
  • var string start
    The searched prefix

Return value

The function returns TRUE if the string starts with the prefix, FALSE is returned otherwise.

Additional Functions

BuildStringSymbolsArray

Creates an array of all string symbols found in the parser's string table.

func int BuildStringSymbolsArray()
-
Return value

The function returns created array.

GetStringSymbolByAddr

Retrieves the symbol at the specified address from the string table.

func int BuildStringSymbolsArray()
-
Return value

The function returns a parser symbol at the given address.

Examples

Basic functionality

This is how function that builds a string looks without StringBuilder:

1
-2
-3
-4
-5
-6
-7
-8
func void PrintMyNumbers(var int x0, var int x1, var int x2) {
-    var string res;
-    res = ConcatStrings(IntToString(x0), ", ");
-    res = ConcatStrings(res, IntToString(x1));
-    res = ConcatStrings(res, ", ");
-    res = ConcatStrings(res, IntToString(x2));
-    PrintS(res);
-};
-
And now the function that uses StringBulider:
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
func void PrintMyNumbers(var int x0, var int x1, var int x2) {
-    var int s; s = SB_New();  // Create StringBuilder
-    SBi(x0);                  // Append Int
-    SB (", ");                // Append string
-    SBi(x1);                  // Append Int
-    SB (", ");                // Append string
-    SBi(x2);                  // Append Int
-    PrintS(SB_ToString());    // Get output as a string
-    SB_Destroy();             // Destroy StringBuilder
-};
-
Looks much more pleasant, right? But why do we create a StringBuilder and then not use it? The idea is the following: A StringBuilder is created with SB_New() and set as the active StringBuilder in the background. The package only supports one StringBuilder at a time, which will keep the pointer in case we want to use another StringBuilder in between.

Multiple StringBuilders

Simple example. We want to fill two StringBuilders at the same time and then return them combined:

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
func string Example2() {
-    // Create two StringBuilders:
-    var int s0; s0 = SB_New();
-    var int s1; s1 = SB_New();
-
-    // Set the first StringBuilder as active and fill it.
-    SB_Use(s0);
-    SB("Hello ");
-    SB("World!");
-
-    // Set the second StringBuilder as active and fill it.
-    SB_Use(s1);
-    SB("This is ");
-    SB("the hero speaking!");
-
-    // Now we want to combine the two StringBuilders.
-    // The system doesn't actually provide for such an operation, but it can still be done using a helper string
-    var string str; str = SB_ToString(); // This string now says “This is the hero speaking!”
-
-    SB_Use(s0);
-    SB(" ");
-    SB(str);
-
-    str = SB_ToString(); // Now "Hello world! This is the hero speaking!" are in the string.
-
-    // The rest is already known, we destroy StringBuilders
-    SB_Destroy();
-    SB_Use(s1);
-    SB_Destroy();
-
-    return str;
-};
-
\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/lego/tools/talents/index.html b/pl/zengin/scripts/extenders/lego/tools/talents/index.html deleted file mode 100644 index cbfcc1829a..0000000000 --- a/pl/zengin/scripts/extenders/lego/tools/talents/index.html +++ /dev/null @@ -1,40 +0,0 @@ - Talents - Gothic Modding Community

Talents - talenty

Ten pakiet robi dwie rzeczy:

  1. Zapisuje dowolną liczbę wartości dla określonego NPC (efektywne rozszerzenie tablicy AIVar).
  2. Pozwala zidentyfikować NPC za pomocą unikalnego ID.

Pakiet Talents używa jednego wolnego AIVara, domyślnie jest to AIVar z numerem 89, który można dostosować w Userconst.d AIV_TALENT.

Zależności

Inicjalizacja

Zainicjuj za pomocą flagi LeGo_PermMem.

LeGo_Init(LeGo_PermMem);
-

Implementacja

Talents.d na GitHubie

Funkcje

NPC_GetID

Zwraca unikalne ID dla podanego NPC.

func int NPC_GetID(var C_NPC slf)
-
Parametry
  • var C_NPC slf
    NPC

Zwracana wartość

Funkcja zwraca unikalne ID dla podanego NPC.

NPC_FindByID

Znajduje wskaźnik NPC o podanym ID.

func int NPC_FindByID(var int ID)
-
Parametry
  • var int ID
    ID postaci

Zwracana wartość

Funkcja zwraca wskaźnik podanej postaci (NPC).

TAL_CreateTalent

Tworzy talent, w którym możesz później zapisać wartość dla każdego NPC (tak jak w AIVarze).

func int TAL_CreateTalent()
-
Zwracana wartość

Funkcja zwraca wartość, która jest później wykorzystywana jako ID talentu.

TAL_SetValue

Ustawia nową wartość dla określonego talentu.

func void TAL_SetValue(var C_NPC npc, var int talent, var int value)
-
Parametry
  • var C_NPC npc
    NPC dla którego ustawiana jest wartość
  • var int talent
    ID talentu
  • var int value
    Ustawiana wartość

TAL_GetValue

Zwraca wartość talentu dla określonego NPC.

func int TAL_GetValue(var C_NPC npc, var int talent)
-
Parametry
  • var C_NPC npc
    NPC, którego wartość talentu jest zwracana
  • var int talent
    ID talentu
\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/lego/tools/timer/index.html b/pl/zengin/scripts/extenders/lego/tools/timer/index.html deleted file mode 100644 index b1d7865992..0000000000 --- a/pl/zengin/scripts/extenders/lego/tools/timer/index.html +++ /dev/null @@ -1,41 +0,0 @@ - Timer - Gothic Modding Community

Timer

Timer is a better alternative to the timers that Gothic offers. The FrameFunctions and Anim8 packages are already based on it. It isn't possible to modify the current time, as this would only cause difficulties.

Dependencies

N/A

Initialization

Initialize with LeGo_Timer flag.

LeGo_Init(LeGo_Timer);
-

Implementation

Timer.d on GitHub

Functions

Timer

Returns the current playing time. If a new game is started, the time is 0. It is measured in milliseconds.

func int Timer()
-
Return value

The function returns current playing time in milliseconds.

TimerGT

Returns the current game time, but the timer is paused when the game is paused (in the menu or status screen).

func int TimerGT()
-
Return value

The function returns current playing time in milliseconds, but without measuring time when game is paused.

TimerF

Alias to Timer function that returns the time as an Ikarus float value.

func int TimerF()
-
Return value

The function returns current playing time as an Ikarus float value.

Timer_SetPause

Pauses the timer (and thus all FrameFunctions and running animations).

func void Timer_SetPause(var int on)
-
Parameters
  • var int on
    Pause on/off

Timer_SetPauseInMenu

The timer can automatically pause when the game is paused. (status screen, main menu...)

func void Timer_SetPauseInMenu(var int on)
-
Parameters
  • var int on
    Automatic pause on/off

Timer_IsPaused

This can be used to query whether the timer is paused.

func int Timer_IsPaused()
-
Return value

The function returns TRUE if the timer is paused, FALSE is returned otherwise.

\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/lego/tools/view/index.html b/pl/zengin/scripts/extenders/lego/tools/view/index.html deleted file mode 100644 index af784e2768..0000000000 --- a/pl/zengin/scripts/extenders/lego/tools/view/index.html +++ /dev/null @@ -1,84 +0,0 @@ - View - Gothic Modding Community

View

This package can create textures on the screen and work with them in an extended manner.

Dependencies

Initialization

Initialize with LeGo_View flag.

LeGo_Init(LeGo_View);
-

Implementation

View.d on GitHub

Functions

View_Create

Creates a zCView with virtual coordinates.

func int View_Create(var int x1, var int y1, var int x2, var int y2) 
-
Parameters
  • var int x1/var int y1
    Top-left corner coordinates (virtual)
  • var int x2/var int y2
    Bottom-right corner coordinates (virtual)

Return value

The function returns a PermMem handle to a zCView.

View_CreatePxl

Alias for View_Create using pixel coordinates.

func int View_CreatePxl(var int x1, var int y1, var int x2, var int y2) 
-
Parameters
  • var int x1/var int y1
    Top-left corner coordinates (pixel)
  • var int x2/var int y2
    Bottom-right corner coordinates (pixel)

Return value

The function returns a PermMem handle to a zCView.

View_CreateCenter

Creates a zCView with virtual coordinates centered.

func int View_CreateCenter(var int x, var int y, var int width, var int height)
-
Parameters
  • var int x
    Horizontal position
  • var int y
    Vertical position
  • var int width
    Width of the view
  • var int height
    Height of the view

Return value

The function returns a PermMem handle to a zCView.

View_CreateCenterPxl

Alias for View_CreateCenter using pixel coordinates.

func int View_CreateCenterPxl(var int x, var int y, var int width, var int height)
-
Parameters
  • var int x
    Horizontal position
  • var int y
    Vertical position
  • var int width
    Width of the view
  • var int height
    Height of the view

Return value

The function returns a PermMem handle to a zCView.

View_Get

Alias for get form PermMem.

zCView View_Get(var int hndl)
-
Parameters

View_GetPtr

Alias for getPtr form PermMem.

func int View_GetPtr(var int hndl)
-
Parameters

View_Render

Renders a zCView. Should be used sparingly, as it works only in specific cases.

func void View_Render(var int hndl)
-
Parameters

View_SetTexture

Assigns a texture to a view. The key function of this package.

func void View_SetTexture(var int hndl, var string texture)
-
Parameters
  • var int hndl
    Handle created with View_Create
  • var string texture
    Filename of a texture

View_GetTexture

Gets the name of a previously assigned texture.

func string View_GetTexture(var int hndl)
-
Parameters

Return value

The function returns the previously assigned texture.

View_SetColor

Sets the color of a view.

func void View_SetColor(var int hndl, var int color)
-
Parameters
  • var int hndl
    Handle created with View_Create
  • var int color
    zColor, can be created with RGBA

View_GetColor

Gets the color of a view.

func int View_GetColor(var int hndl)
-
Parameters

Return value

The function returns the full zColor.

View_Open

Opens a view. It will be displayed on the screen.

func void View_Open(var int hndl)
-
Parameters

View_Close

Closes a view. It disappears from the screen but can still be used.

func void View_Close(var int hndl)
-
Parameters

View_Delete

Alias for delete.

`zCView` View_Delete(var int hndl)
-
Parameters

View_Resize

Scales a view to a virtual size. The top-left position of the view remains fixed.

func void View_Resize(var int hndl, var int width, var int height)
-
Parameters
  • var int hndl
    Handle created with View_Create
  • var int width
    New width of the view
  • var int height
    New height of the view

View_ResizePxl

Alias for View_Resize using pixel coordinates.

func void View_ResizePxl(var int hndl, var int width, var int height)
-
Parameters
  • var int hndl
    Handle created with View_Create
  • var int width
    New width of the view
  • var int height
    New height of the view

View_Move

Moves the view by virtual units.

func void View_Move(var int hndl, var int x, var int y)
-
Parameters
  • var int hndl
    Handle created with View_Create
  • var int x
    Shift left/right
  • var int y
    Shift up/down

View_MovePxl

Alias for View_Move using pixel coordinates.

func void View_MovePxl(var int hndl, var int x, var int y)
-
Parameters
  • var int hndl
    Handle created with View_Create
  • var int x
    Shift left/right
  • var int y
    Shift up/down

View_MoveTo

Moves the top-left corner of the view to a virtual position.

func void View_MoveTo(var int hndl, var int x, var int y)
-
Parameters
  • var int hndl
    Handle created with View_Create
  • var int x
    New horizontal position (-1 for no change)
  • var int y
    New vertical position (-1 for no change)

View_MoveToPxl

Alias for View_MoveTo using pixel coordinates.

func void View_MoveToPxl(var int hndl, var int x, var int y)
-
Parameters
  • var int hndl
    Handle created with View_Create
  • var int x
    New horizontal position (-1 for no change)
  • var int y
    New vertical position (-1 for no change)

View_AddText

Adds a text line to the view. The position is virtual and relative to the view's position. If the view is moved, the text moves as well.

func void View_AddText(var int hndl, var int x, var int y, var string text, var string font)
-
Parameters
  • var int hndl
    Handle created with View_Create
  • var int x
    Horizontal position
  • var int y
    Vertical position
  • var string text
    Added text
  • var string font
    Used Font

View_DeleteText

Removes all text added with View_AddText.

func void View_DeleteText(var int hndl)
-
Parameters

View_Top

Places the view above all others.

func void View_Top(var int hndl)
-
Parameters

Examples

Display a texture on the screen

Here a texture should be displayed over the entire screen:

1
-2
-3
-4
-5
-6
-7
func void Example1() {
-    var int View; 
-    View = View_Create(0, 0, PS_VMax, PS_VMax); // Virtual coordinates
-    View_SetTexture(View, "MyTexture.tga"); // Assign a texture to the view
-    // display the view on the screen:
-    View_Open(View);
-};
-

This would mean that the texture would be permanently visible on the screen (even after loading/saving/restarting). If we want it to disappear we have to use either View_Delete or View_Close.

Display a texture with pixel coordinates

Now a texture should be displayed at the top right and be 256 x 256 pixels in size:

1
-2
-3
-4
-5
-6
-7
func void Example2() {
-    Print_GetScreenSize();
-    var int View;
-    View = View_CreatePxl(Print_Screen[PS_X] - 256, 0, Print_Screen[PS_X], 256); // Pixel coordinates
-    View_SetTexture(View, "MYTEXTURE.TGA");
-    View_Open(View);
-};
-

To get the size of the screen we use the interface package.

\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/lego/trialoge/index.html b/pl/zengin/scripts/extenders/lego/trialoge/index.html deleted file mode 100644 index 91ea7a0823..0000000000 --- a/pl/zengin/scripts/extenders/lego/trialoge/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/pl/zengin/scripts/extenders/lego/various/userconstants/index.html b/pl/zengin/scripts/extenders/lego/various/userconstants/index.html deleted file mode 100644 index fa0b547c72..0000000000 --- a/pl/zengin/scripts/extenders/lego/various/userconstants/index.html +++ /dev/null @@ -1,34 +0,0 @@ - User constants - Gothic Modding Community

User constants

All constants that the user can either use or even change freely are defined in Userconst.d file.

Read only

These constants may only be used, not changed.

Anim8

These constants are used by Anim8 and Anim8q.

  • const int A8_Constant
    Constant movement speed
  • const int A8_SlowEnd
    Evenly decelerated movement
  • const int A8_SlowStart
    Evenly accelerated movement
  • const int A8_Wait
    Do nothing. The target value is ignored here

Buttons

The following bit masks can be applied to the status of a button:

  • const int BUTTON_ACTIVE
    The button is active, it reacts to the mouse
  • const int BUTTON_ENTERED
    The mouse is "within" the button

Interface

Dimensions

  • const int PS_X and const int PS_Y
    Use with Print_Screen or Print_ToVirtual functions
  • const int PS_VMax
    Highest possible value of a virtual coordinate

Colors

16 basic colors that can be used as zColor parameters

  • const int COL_Aqua
  • const int COL_Black
  • const int COL_Blue
  • const int COL_Fuchsia
  • const int COL_Gray
  • const int COL_Green
  • const int COL_Lime
  • const int COL_Maroon
  • const int COL_Navy
  • const int COL_Olive
  • const int COL_Purple
  • const int COL_Red
  • const int COL_Silver
  • const int COL_Teal
  • const int COL_White
  • const int COL_Yellow

Gamestate

Gamestate can assume these values:

  • const int Gamestate_NewGame
    New game started
  • const int Gamestate_Loaded
    A game has been loaded
  • const int Gamestate_WorldChange
    The world has changed
  • const int Gamestate_Saving
    The game is saved

Cursor

These constants are sent with Cursor_Event:

  • const int CUR_LeftClick
    The left mouse button was pressed
  • const int CUR_RightClick
    The right mouse button was pressed
  • const int CUR_MidClick
    The middle mouse button was pressed
  • const int CUR_WheelUp
    Mouse wheel up
  • const int CUR_WheelDown
    Mouse wheel down

Modifiable

These constants are often used by packages and may be changed freely.

Bloodsplats

  • const int BLOODSPLAT_NUM
    Maximum number on screen
  • const int BLOODSPLAT_TEX
    Highest Texture ID ("BLOODSPLAT" + texID + ".TGA")
  • const int BLOODSPLAT_DAM
    Texture size damage multiplier (damage * 2Bloodsplat_Dam)

Cursor

  • const string Cursor_Texture
    This texture is used to display the cursor (default: "CURSOR.TGA")

Interface

  • const string Print_LineSeperator
    Text boxes can be printed in multiple lines. This character separates the lines from each other.

PrintS

All position and size information is completely virtual:

  • const int PF_PrintX
    Start position on the X axis
  • const int PF_PrintY
    Start position on the Y axis
  • const int PF_TextHeight
    Space between individual lines

The times are given in ms:

  • const int PF_FadeInTime
    Time to fade in the text
  • const int PF_FadeOutTime
    Time to fade out the text
  • const int PF_MoveYTime
    Time needed to "slip down"
  • const int PF_WaitTime
    Time during which the print is fully visible

The font can be modified:

  • const string PF_Font
    Default: FONT_OLD_10_WHITE.TGA

Talents

  • const int AIV_TALENT
    Used AIVar

Dialoggestures

  • const string DIAG_Prefix
    Animation prefix ("DG_")
  • const string DIAG_Suffix
    Animation suffix ("_")
\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/standalone/gameKeyEvents/index.html b/pl/zengin/scripts/extenders/standalone/gameKeyEvents/index.html deleted file mode 100644 index 47321bfe16..0000000000 --- a/pl/zengin/scripts/extenders/standalone/gameKeyEvents/index.html +++ /dev/null @@ -1,48 +0,0 @@ - gameKeyEvents - Gothic Modding Community

gameKeyEvents

Quick overview

Author: mud-freak
Platform: G1, G2NotR
Category: Engine, Keys

gameKeyEvents.d is a script, which handles key events with the oCGame::HandleEvent hook. Better alternative for FrameFunction with MEM_KeyState with which you don't have to check whether any menu is opened or player is in dialogue or can move etc.

Author's description

I looked up the address within oCGame::HandleEvent. I made it into a universally usable script for Gothic 1 and Gothic 2.

One could argue now that this is not much different from a FrameFunction with MEM_KeyState. The difference is that this approach saves the extra work of checking if any menu is open, whether the player is in a dialog, whether the player may move, etc. Also this function is "event driven", meaning it is really only called when a key is pressed/held instead of every frame in vain. So it's arguably more performant.

Dependencies

Initialization

Call Game_KeyEventInit() in the Init_Global() or other initialization function.

Game_KeyEventInit();
-

Implementation

gameKeyEvents.d on WoG forum

Usage

To add a key pressing detection edit the main function Game_KeyEvent.

1
-2
-3
-4
-5
-6
-7
func int Game_KeyEvent(var int key, var int pressed) {
-    if (key == KEY_LBRACKET) && (pressed) {
-        // Here enter your code.
-        return TRUE;
-    };
-    return FALSE;
-};
-
  • To change detected key rename KEY_LBRACKET to your own key e.g. taken from Ikarus constants.
  • To detect pressing a key leave (pressed) unchanged but if you want to detect holding change it to (!pressed). That's because

    pressed is FALSE: key is held, pressed is TRUE: key press onset

  • To run code when a key is pressed, paste it or call a function where the comment is.
  • To detect more than one key add else if.
\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/standalone/index.html b/pl/zengin/scripts/extenders/standalone/index.html deleted file mode 100644 index 59517621bc..0000000000 --- a/pl/zengin/scripts/extenders/standalone/index.html +++ /dev/null @@ -1,34 +0,0 @@ - Samodzielne skrypty - Gothic Modding Community

Samodzielne skrypty

Przez lata moderzy Gothica stworzyli wiele przydatnych funkcji do wykorzystania ze skryptami Zengin. Ta sekcja zawiera dokumentację niektórych skryptów, które są „samodzielne”, co oznacza, że nie są częścią większych pakietów, ale często są to małe funkcje ułatwiające życie modderom.

Script Biny

Kilka osób wpadło na pomysł zebrania rozsianych po forach skryptów, w wyniku czego powstały tzw. Script Biny.

Warning

Script biny nie są często aktualizowane, więc najnowsze aktualizacje i nowe skrypty można znaleźć w wątku ScriptBin na niemieckim forum WoG.

WoG Script Bin

Script bin stworzony przez Kiridesa zawierający skrypty z niemieckiego forum WoG.

https://apps.kirides.de/wog-script-bin/

Repozytorium ScriptBin na GitHubie

Repozytorium GitHub stworzone przez Lehone, które zawiera skrypty niektórych modderów.

https://github.com/Lehona/ScriptBin

\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/standalone/setBarPositions/index.html b/pl/zengin/scripts/extenders/standalone/setBarPositions/index.html deleted file mode 100644 index 86b2310154..0000000000 --- a/pl/zengin/scripts/extenders/standalone/setBarPositions/index.html +++ /dev/null @@ -1,141 +0,0 @@ - setBarPositions - Gothic Modding Community

setBarPositions

Quick overview

Author: mud-freak
Platform: G1, G2NotR
Category: Engine, Interface

setBarPositions.d is a script that allows changing position of original gothic bars (HP, Mana, Swim, focus). Changes are directly in the engine, so bars are normally scaled.

Dependencies

Initialization

Call it in the Init_Global() or other initialization function. Set the manaAlwaysOn and swimAlwaysOn to TRUE/FALSE.

SetBarPositions_Init(manaAlwaysOn, swimAlwaysOn);
-

Implementation

setBarPositions.d on WoG forum

Usage

To change positions of bars edit the main function SetBarPosition. Look at the examples to see how you can adjust it to your preferences.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
func int SetBarPosition(var int barPtr) {
-    var oCViewStatusBar bar; bar = _^(barPtr);
-    var int x; var int y;
-
-    if (barPtr == MEM_Game.hpBar) {
-        // Original
-        x = Print_ToVirtual(10, PS_X);                                // 10 px from the left
-        y = PS_VMax - Print_ToVirtual(10 + bar.zCView_psizey, PS_Y);  // 10 px from the bottom
-
-    } else if (barPtr == MEM_Game.manaBar) {
-        // Original
-        x = PS_VMax - Print_ToVirtual(10 + bar.zCView_psizex, PS_X);  // 10 px from the right
-        y = PS_VMax - Print_ToVirtual(10 + bar.zCView_psizey, PS_Y);  // 10 px from the bottom
-
-    } else if (barPtr == MEM_Game.swimBar) {
-        // Original
-        x = (PS_VMax - bar.zCView_vsizex) / 2;                        // Centered
-        y = PS_VMax - Print_ToVirtual(10 + bar.zCView_psizey, PS_Y);  // 10 px from the bottom
-
-    } else if (barPtr == MEM_Game.focusBar) {
-        // Original
-        x = (PS_VMax - bar.zCView_vsizex) / 2;                        // Centered
-        y = Print_ToVirtual(10, PS_Y);                                // 10 px from the top
-    };
-
-    return x | (y << 14);
-};
-

Examples

All bars on the left side

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
/*
- * EXAMPLE: Stacked on the left
- */
-func int SetBarPosition(var int barPtr) {
-    var oCViewStatusBar bar; bar = _^(barPtr);
-    var int x; var int y;
-
-    if (barPtr == MEM_Game.hpBar) {
-        x = Print_ToVirtual(10, PS_X);
-        y = PS_VMax - Print_ToVirtual(6 + 3 * (4 + bar.zCView_psizey), PS_Y);
-
-    } else if (barPtr == MEM_Game.manaBar) {
-        x = Print_ToVirtual(10, PS_X);
-        y = PS_VMax - Print_ToVirtual(6 + 2 * (4 + bar.zCView_psizey), PS_Y);
-
-    } else if (barPtr == MEM_Game.swimBar) {
-        x = Print_ToVirtual(10, PS_X);
-        y = PS_VMax - Print_ToVirtual(6 + 1 * (4 + bar.zCView_psizey), PS_Y);
-
-    } else if (barPtr == MEM_Game.focusBar) {
-        // Original
-        x = (PS_VMax - bar.zCView_vsizex) / 2;                        // Centered
-        y = Print_ToVirtual(10, PS_Y);                                // 10 px from the top
-    };
-
-    return x | (y << 14);
-};
-
\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/zparserextender/c_trigger/index.html b/pl/zengin/scripts/extenders/zparserextender/c_trigger/index.html deleted file mode 100644 index 6db5ec0bd5..0000000000 --- a/pl/zengin/scripts/extenders/zparserextender/c_trigger/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/pl/zengin/scripts/extenders/zparserextender/classes/c_trigger/index.html b/pl/zengin/scripts/extenders/zparserextender/classes/c_trigger/index.html deleted file mode 100644 index 556a46d196..0000000000 --- a/pl/zengin/scripts/extenders/zparserextender/classes/c_trigger/index.html +++ /dev/null @@ -1,145 +0,0 @@ - C_Trigger class - Gothic Modding Community

Trigger functions and the C_Trigger class

zParserExtender also implements cyclical functions called triggers - not to be confused with triggers in ZEN files, similar to a part of the functionality implemented in LeGo AI_Functions. These functions are called independently after a specified period of time. These triggers can also store user information. Up to 16 int variables can be stored in each trigger as well as self, other and victim instances.

Class definition

To define a trigger, the C_Trigger class is used:

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
/// Union zParserExtender Trigger class
-class C_Trigger
-{
-    var int Delay; // defines the frequency (in milliseconds) at which the function will be called.
-    var int Enabled; // determines if the trigger is active. If the value is equal to zero, the trigger is destroyed.
-    var int AIVariables[16]; // user data, which can be set independently when creating trigger (yes, you can write there absolutely everything you want).
-
-    // Hidden variable members
-    /*
-        - Func   - The function that the trigger will call.
-        - Self   - The NPC that will be placed in `self` when the function is called.
-        - Other  - An NPC that will be placed in `other` when the function is called.
-        - Victim - The NPC that will be placed in `victim` when the function is called.
-    */
-};
-

Creating instances

There are two external functions that are used to create C_Trigger instance.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
// function returns a trigger with no NPC (self, other or victim) bound to it
-func C_Trigger AI_StartTriggerScript(   var string funcName,
-                                        var int delay) {};
-
-// function is extended, if certain participants need to be assigned to it
-func C_Trigger AI_StartTriggerScriptEx( var string funcName,
-                                        var int delay,
-                                        var C_Npc slf,
-                                        var C_Npc oth,
-                                        var C_Npc vct) {};
-

Both of these functions return an instance of C_Trigger instance. You can of course configure the instance after its creation. You can, for example, fill in the AIVariables with relevant data. The trigger function has the required signature if 'func int f()'. It must return a value indicating the state of the loop. If the function returns LOOP_END the trigger will be stopped and the instance deleted. If LOOP_CONTINUE is returned, the function will be called again after Delay ms have passed.

Poison example

1
-2
-3
-4
-5
-6
-7
-8
-9
// Implement a trigger to simulate the effect of poison debuff:
-// Let's create a trigger on function `c_loop` with a call interval of 1 second.
-// When the function is called, the instance hero will be placed in self (although it can be any other NPC if desired).
-// The rest of the instances are left null (not used).
-
-var C_Trigger trigger;
-trigger = AI_StartTriggerScriptEx("c_loop", 1000, hero, null, null);
-trigger.AIVariables[0] = 15; // how many times the function should be called
-trigger.AIVariables[1] = 5;  // how much damage to deal each iteration
-

The trigger function

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
func int c_loop()
-{
-    // Create a loop end check, if the number of
-    // available iterations has reached 0. If it did
-    // we stop the trigger by returning the LOOP_END value.
-    if (SelfTrigger.AIVariables[0] <= 0)
-    {
-        return Loop_end;
-    };
-
-    SelfTrigger.Delay -= 20;         // Accelerate loop each call by 20 ms
-    SelfTrigger.AIVariables[0] -= 1; // Reduce number of remaining repeats
-    self.Attribute[ATR_HITPOINTS] -= SelfTrigger.AIVariables[1]; // Take health from self
-    return LOOP_CONTINUE;
-};
-

Trigger scope

Triggers can be divided into two types:

  • Global trigger ( AI_StartTriggerScript ) trigger created using this function works in all worlds. A trigger is considered global by default if neither self nor other nor victim has been provided for it.
  • Local trigger ( AI_StartTriggerScriptEx) trigger created with this function only works in the world in which it was created. A trigger is considered local if it has been presented with at least one NPC in self, other or victim (not null). If you want to create a trigger without linking it to any NPC, it is recommended to simply pass hero as self to the trigger.

Saving

The plugin creates a new save archive to save the information of the triggers that does not conflict with any of the built-in save files.

Searching

To search for a specific trigger, for example by NPC, the trigger external functions can be used.

1
-2
-3
-4
-5
-6
-7
-8
-9
// This way you can disable all triggers running on the `hero` instance
-var C_Trigger trigger = FirstTrigger;
-var C_Trigger trigger_saved;
-while (!Hlp_IsNULL(trigger))
-{
-    trigger_saved = trigger;
-    trigger = AI_GetNextTriggerBySelf(hero);
-    trigger_saved.Enabled = false;
-};
-
\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/zparserextender/classes/helperclasses/index.html b/pl/zengin/scripts/extenders/zparserextender/classes/helperclasses/index.html deleted file mode 100644 index 0b2f3ae2c6..0000000000 --- a/pl/zengin/scripts/extenders/zparserextender/classes/helperclasses/index.html +++ /dev/null @@ -1,390 +0,0 @@ - Engine classes - Gothic Modding Community

Engine classes

zParserExtender implements various proxy classes that can be used to access game world objects.

Warning

It is not recommended to implement complex mechanics using these classes and functions. They are present as a simple backup option for accessing game world objects and for quick fixes.

C_VOB

This class represents basic pointer to a game world object.

C_Color

Represents color in the RGBA format

1
-2
-3
-4
-5
-6
-7
class C_Color
-{
-    var int R; // red channel value
-    var int G; // green channel value
-    var int B; // blue channel value
-    var int A; // alpha channel value
-};
-

zVEC3

Represents 3D position in the world (float version for internal functions)

1
-2
-3
-4
-5
-6
class zVEC3
-{
-    var float X; // X coordinate
-    var float Y; // Y coordinate
-    var float Z; // Z coordinate
-};
-

C_Position

Represents 3D position in the world

1
-2
-3
-4
-5
-6
class C_Position
-{
-    var int X; // X coordinate
-    var int Y; // Y coordinate
-    var int Z; // Z coordinate
-};
-
Externals:
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
/// Returns the current position of the object in the world
-/// 
-/// @param vob vob to ge the position of
-/// @return C_Position instance - position of the VOB
-func C_Position Vob_GetVobPosition( var C_Vob vob ) {};
-
-/// Sets the current position of the object in the world
-/// 
-/// @param vob vob to get the position of
-/// @param pos new position of the vob
-func void Vob_SetVobPosition( var C_Vob vob, var C_Position pos ) {};
-

Note

The following classes define properties of C_VOB objects or classes derived from it.

C_VOB_DATA

Represents universal zCVob class

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
class C_VOB_DATA
-{
-    var string Name;              // object name
-    var float VisualAlpha;        // object's transparency 0.0 - 1.0
-    var int ShowVisual;           // display the mode
-    var int DrawBBox3D;           // show objects bounding box
-    var int VisualAlphaEnabled;   // enables objects transparency
-    var int PhysicsEnabled;       // enables object's physics
-    var int IgnoredByTraceRay;    // allow any object collisions
-    var int CollDetectionStatic;  // allow collision with static world polygons
-    var int CollDetectionDynamic; // allow collision with dynamic world objects
-    var int CastDynShadow;        // display shadow of the object
-    var int LightColorStatDirty;  // allow static lighting of the object
-    var int LightColorDynDirty;   // allow dynamic lighting of the object
-    var int SleepingMode;         // sets object's activity mode (0 - inactive, 1 - active, 2 - AI only)
-    var int DontWriteIntoArchive; // turns of the serialization of this object to the save file 
-};
-
Externals:
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
/// Returns the universal data of the zCVob object
-///
-/// @param vob VOB to get the position of
-/// @return general vob data C_Vob_Data
-func C_Vob_Data Vob_GetVobData( var C_Vob vob ) {};
-
-/// Sets the universal data to a zCVob object
-///
-/// @param vob VOB to get the position of
-/// @param data general vob data C_Vob_Data
-func void Vob_SetVobData( var C_Vob vob, var C_Vob_Data data ) {};
-

C_LIGHT_DATA

Represents zCVobLight objects

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
class C_LIGHT_DATA
-{
-    var int R;                // red light intensity
-    var int G;                // green light intensity
-    var int B;                // blue light intensity
-    var int Range;            // radius
-    var int RangeInv;         // 
-    var int RangeBackup;      // 
-    var int RangeAniActFrame; // current light animation frame for the radius
-    var int RangeAniFPS;      // speed of light animation for the radius
-    var int ColorAniActFrame; // current light animation frame for colour
-    var int ColorAniFPS;      // speed of light animation for colour
-    var int SpotConeAngleDeg; // angle of cone light source
-    var int IsStatic;         // whether the source is static
-    var int RangeAniSmooth;   // [UNUSED]
-    var int RangeAniLoop;     // [UNUSED]
-    var int ColorAniSmooth;   // allows soft transitions between colours
-    var int ColorAniLoop;     // [UNUSED]
-    var int IsTurnedOn;       // whether the light source is on
-    var int LightQuality;     // source quality (when statically compiling light) (0 - high, 1 - medium, 2 - low)
-    var int LightType;        // type of source (at static light compilation) (0 - point, 1 - cone)
-};
-
Externals:
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
/// Returns zCVobLight object data
-///
-/// @param vobLight vobLight object
-/// @return C_Light_Data of the light
-func C_Light_Data Vob_GetLightData( var C_Vob vobLight ) {};
-
-/// Sets the data of a zCVobLight object
-///
-/// @param vobLight object to apply the light data to
-/// @param data C_Light_Data light data to be set
-func void Vob_SetLightData( var C_Vob vobLight, var C_Light_Data data ) {};
-
-/// Clears the list of animation colours for the light source
-///
-/// @param vobLight light vob
-func void Vob_ClearLightAniList( var C_Vob vobLight ) {};
-
-/// Adds a color to the colour list
-///
-/// @param vobLight object to apply the colour to
-/// @param col colour to be applied
-func void Vob_AddLightAniColor( var C_Vob vobLight, var C_Color col ) {};
-
-/// Adds a color to the colour list
-///
-/// @param vobLight object to apply the colour to
-/// @param r red colour channel
-/// @param g green colour channel 
-/// @param b blue colour channel
-func void Vob_AddLightAniColorRGB(  var C_Vob vobLight,
-                                    var int r,
-                                    var int g,
-                                    var int b ) {};
-

C_MOB_DATA

Represents data for the used oCMOB object

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
class C_MOB_DATA
-{
-    var string VisibleName;     // name shown above the object
-    var int Hitpoints;          // number of hitpoints
-    var int Damage;             // damage the object can cause
-    var int IsDestroyed;        // if the object is destroyed
-    var int Moveable;           // whether the object can be moved
-    var int Takeable;           // whether the object can be taken
-    var int FocusOverride;      // if the object will redefine focus in combat mode
-    var int SndMat;             // object's material (0 - wood, 1 - stone, 2 - metal, 3 - skin, 4 - clay, 5 - glass)
-    var string VisualDestroyed; // model when the object is destroyed
-    var string OwnerStr;        // name of the instance of the owner of the object
-    var string OwnerGuildStr;   // name of the guild of the object
-    var int Owner;              // instance of the owner
-    var int OwnerGuild;         // guild instance
-    var int FocusNameIndex;     // the script string of the displayed name
-};
-
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
/// Returns the data of the oCMOB object
-///
-/// @param mob oCMOB object
-/// @return mob data
-func C_Mob_Data Vob_GetMobData( var C_Vob mob ) {};
-
-/// Sets the data of the oCMOB object
-///
-/// @param mob oCMOB object
-/// @param data C_Mob_Data to be set 
-func void Vob_SetMobData( var C_Vob mob, var C_Mob_Data data ) {};
-

C_MOBINTER_DATA

Represents data for the interactive object oCMobInter

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
class C_MOBINTER_DATA
-{
-    var string TriggerTarget;   // object name which will be triggered by OnTrigger
-    var string UseWithItem;     // name of the object instance that is needed for interaction
-    var string Sceme;           // name of the scene that corresponds to the object and character animations
-    var string ConditionFunc;   // scripting condition under which the interaction can be performed
-    var string OnStateFuncName; // the name pattern of the functions that will be called when the object changes the state
-    var int State;              // the current state of the object
-    var int State_num;          // number of object's states
-    var int State_target        // current state of the object
-    var int Rewind;             // prohibits object updating
-    var int MobStateAni;        // current animation of the object
-    var int NpcStateAni;        // current character animation
-};
-
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
/// Returns the data of the oCMobInter object
-///
-/// @param mobInter oCMobInter object
-/// @return MobInter_Data of the object
-func MobInter_Data Vob_GetMobInterData( var C_Vob mobInter ) {};
-
-/// Sets the data of the oCMobInter object
-///
-/// @param mobInter oCMobInter object
-/// @param data MobInter_Data of the object
-func void Vob_SetMobInterData( var C_Vob mobInter, var C_MobInter_Data data ) {};
-

C_MOBLOCKABLE_DATA

Represents data for the locked interactive object oCMobLockable

1
-2
-3
-4
-5
-6
-7
-8
class C_MOBLOCKABLE_DATA
-{
-    var int Locked;         // whether the object is locked
-    var int AutoOpen;       // [UNUSED]
-    var int PickLockNr;     // current rotation number 
-    var string KeyInstance; // key instance name for the object
-    var string PickLockStr; // combination to open the object ("LRRLR")
-};
-
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
/// Returns the data of the oCMobLockable object
-///
-/// @param mobLock oCMobLockable object
-/// @param data MobInter_Data of the object
-func C_MobLockable_Data Vob_GetMobInterData( var C_Vob mobLock ) {};
-
-/// Sets the data of the oCMobLockable object
-///
-/// @param mobLock oCMobLockable object
-/// @param data C_MobLockable_Data of the object
-func void Vob_SetMobInterData( var C_Vob mobLock, var C_MobLockable_Data data ) {};
-
\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/zparserextender/daedalus_injection/hooks/index.html b/pl/zengin/scripts/extenders/zparserextender/daedalus_injection/hooks/index.html deleted file mode 100644 index f942c86293..0000000000 --- a/pl/zengin/scripts/extenders/zparserextender/daedalus_injection/hooks/index.html +++ /dev/null @@ -1,84 +0,0 @@ - Hooking - Gothic Modding Community

Hooking Daedalus

Daedalus hooking is one of the most powerful features of this plugin. Hooking is a mechanism that allows you to replace any scripted object with a new one. To do this, you must define a new object with the same type, name and in the same namespace.

Hook/replacement will be performed only if the MergeMode setting is set to true for the current script in the META block or in the parameter of the same name in the .ini file of the mod.

Warning

If you forget to turn on the MergeMode, the compilation will fail with the redefinition error.

When an object (instance, function or variable) is hooked/replaced, the original one is available under the same name with the _old suffix (PC_Hero -> PC_Hero_old). This allows you to refer to the old object.

Function hook example

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
func void ZS_Attack_Loop()
-{
-    // if the enemy is a player and has no weapon, then
-    // also sheath the weapon.
-    if (Npc_IsPlayer(other) && !Npc_HasReadiedWeapon(other))
-    {
-        return LOOP_END;
-    };
-
-    // otherwise call the original function
-    return ZS_Attack_Loop_Old();
-};
-

This kind of substitution works for instances and variables too.

Warning

While hooking an instances, you have to take care not to call the prototype. Prototype should be always changed back to the original class.

This is wrong
1
-2
-3
-4
-5
instance pc_hero(Npc_Default)
-{
-    pc_hero_old();
-    name = "Pepe";
-};
-
This leads to a double call of prototype Npc_Default which is considered an unsafe practice with undefined behaviour.

The correct way is to call it like this:

1
-2
-3
-4
-5
instance pc_hero(C_NPC) // no prototype Npc_Default
-{
-    pc_hero_old();
-    name = "Pepe";
-};  
-
This way the prototype is called in the original function pc_hero_old() and not for the second time when creating the new hooked instance.

Dialogue hook example

The hooking mechanism is designed to introduce new dialogues into the game as well as replacing old ones with hooks. The scripter can create new merchants, quests, dialogues, as well as attach svm phrases to them.

All new or replaced dialogues will immediately become available, including from saves. In the event that new dialogs are disabled (plugin or script removed), the engine will continue to keep them in the save file, which will allow the dialogs to return at any time with the same state they were in the last time.

Warning

Currently not working as intended (I think). The old dialogue is still used and as a result you will end up with both the old and the new dialogue (unless you edit the old condition function).

1
-2
-3
-4
-5
instance DIA_XARDAS_HELLO(C_INFO)
-{
-    DIA_XARDAS_HELLO_old();
-    important = FALSE;
-};
-
\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/zparserextender/daedalus_injection/index.html b/pl/zengin/scripts/extenders/zparserextender/daedalus_injection/index.html deleted file mode 100644 index 9eef5685e8..0000000000 --- a/pl/zengin/scripts/extenders/zparserextender/daedalus_injection/index.html +++ /dev/null @@ -1,34 +0,0 @@ - Daedalus Injection - Gothic Modding Community

Daedalus Injection

Script injection is a process of injecting Daedalus scripts on runtime without the need to recompile the scripts. This is essential for Union plugins that need to alter the scripts in a certain way, either for hotfixes or just for testing scripts without the need to recompile the whole .dat file.

To inject a script, simply put a .d or .src file in Gothic/System/Autorun directory and run the game.

Tip

Automatic injection does not extend to nested directories in the Autorun directory directly, but you can put a .src file into Autorun directory and the rest into a subdirectory to keep a cleaner structure.

Scripts in subdirectories can be accessed in two ways

  1. They are specified in a .src file
  2. The script file is an API script

API script

API scripts are .d files placed in Autorun subdirectories and are used as a dependency. It is assumed that the API script is not called on its own (or from a .src) file, but is called using the dependency keyword After in one of the injected script files' META block.

These scripts are meant to contain ready-made solution that need to be used by many other scripts as a dependency.

Warning

If the file specified in the After tag in the META block does not exist, the current file will not be parsed and injected since the dependency is missing, and it would fail. Due to this it is best to ship the dependency in the Autorun directory even if it comes from a different plugin.

\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/zparserextender/daedalus_injection/meta/index.html b/pl/zengin/scripts/extenders/zparserextender/daedalus_injection/meta/index.html deleted file mode 100644 index 5da8f24337..0000000000 --- a/pl/zengin/scripts/extenders/zparserextender/daedalus_injection/meta/index.html +++ /dev/null @@ -1,95 +0,0 @@ - META block - Gothic Modding Community

META block

The META block is optional. If it is specified, it has to be the very first thing in the file without any indent or a comment above it.

Syntax:

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
META
-{
-    Parser // specifies into which compiled file the scripts are going to be injected
-    /*
-        Code    Name              DAT file
-        ---     ------            -------
-        Game    parser            Gothic.dat
-        SFX     parserSoundFX     SFX.dat
-        PFX     parserParticleFX  ParticleFX.dat
-        VFX     parserVisualFX    VisualFX.dat
-        Camera  parserCamera      Camera.dat
-        Menu    parserMenu        Menu.dat
-        Music   parserMusic       Music.dat
-    */
-    MergeMode   // 0 - if conflict occurs = compilation error, 1 - if conflict occurs = hook
-    Engine      // comma separated list of engines for which the scripts will be injected 
-    /*
-        Code  Engine          Human readable name
-        ---   -----           -----------------------
-        G1    Gothic I        Gothic I Classic
-        G1A   Gothic Sequel   Gothic I Addon <3
-        G2    Gothic II       Gothic II Classic
-        G2A   Gothic II NoTR  Gothic II Addon
-    */
-
-    NativeWhile // use native while
-    Namespace   // namespace of this script file
-    Using       // comma separated list of namespaces, that are considered local for this script file
-    Mod         // specify for which mod should this code be injected
-    After       // comma separated list of scripts, after which this script should be parsed
-};
-
\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/zparserextender/daedalus_injection/other/index.html b/pl/zengin/scripts/extenders/zparserextender/daedalus_injection/other/index.html deleted file mode 100644 index 0620f4335a..0000000000 --- a/pl/zengin/scripts/extenders/zparserextender/daedalus_injection/other/index.html +++ /dev/null @@ -1,122 +0,0 @@ - Other features - Gothic Modding Community

Other functions of the extender

ini parameters

The choice of ini file depends on how the game was launched. If it was launched from Gothic.exe, then the parameters will be read from SystemPack.ini. If it was launched through GothicStarter.exe, then they will be read from the ini of the mod.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
[zParserExtender]
-LoadScript(obsolete) =
-;specifies a parser-script format script to run the scripts. The parameter is currently invalid.
-
-MergeMode = True
-;specifies whether injections will produce hooks.
-
-CompileDat = False
-;Determines if a copy of DAT file which has been modified by injection will be created.
-
-CompileOU = False
-;determines if a copy of an injection-modified OU file will be created.
-
-NativeWhile = False
-;Determines if a WHILE loop will be compiled. Defaults to False (for Ninja compatibility).
-
-MessagesLevel = 1
-;sets the output level. The higher the level, the more information will be printed to the debug console.
-
-StringIndexingMode = -1
-;defines string indexing mode (see string indexing). Default value is -1.
-;Default   = -1 - The default mode for the moment is Repair mode.
-;Disabled  =  0 - Do nothing with the indices.
-;TopSymbol =  1 - The plugin finds the uppermost unnamed string and sets a counter for it.
-;Repair    =  2 - The plugin goes through the whole string table and, if the indexing order is broken, puts the correct names. The counter is set on the basis of the search.
-

MARVIN console commands

zParserExtender adds console commands that save copies of the .dat files with the injected code.

Warning

If the mod uses Ikarus, the CompileDat option (in the .ini file) should be used since a fatal error may occur when using the command.

1
-2
-3
-4
-5
-6
-7
-8
-9
Parser SaveDat OU        - exports OU.Edited.bin
-Parser SaveDat Game      - exports Gothic.Edited.dat
-Parser SaveDat SFX       - exports SFX.Edited.dat
-Parser SaveDat PFX       - exports ParticleFX.Edited.dat
-Parser SaveDat VFX       - exports VisualFX.Edited.dat
-Parser SaveDat Camera    - exports Camera.Edited.dat
-Parser SaveDat Menu      - exports Menu.Edited.dat
-Parser SaveDat Music     - exports Music.Edited.dat
-Parser Export Stringlist - exports the full string table to Scripts\Exports\StringList.d
-

Launch options

Command line parameters can be passed to the game's exe via the command line or using GothicStarter_Mod.

1
-2
-3
-4
-5
-6
-7
-8
zReparse_OU     - parses and creates OU.bin
-zReparse_Game   - parses and creates Gothic.dat
-zReparse_SFX    - parses and creates SFX.dat
-zReparse_PFX    - parses and creates ParticleFX.dat
-zReparse_VFX    - parses and creates VisualFX.dat
-zReparse_Camera - parses and creates Camera.dat
-zReparse_Menu   - parses and creates Menu.dat
-zReparse_Music  - parses and creates Music.dat
-

Note

If you want to compile OU, you also have to include the Game parameter

-zReparse_Game -zReparse_OU

Const array access

The original zParser doesn't allow direct access to const string arrays. zParserExtender allows you to do so.

Example:

1
-2
-3
-4
func event GameInit()
-{
-    Hlp_MessageBox(TXT_INV_CAT[4]); // Prints "Artifacts"
-};
-

Other engine fixes

  1. When creating an item instance, the instance is placed into the global item instance
  2. On DAT file load, the engine restores the original symbol hierarchy
  3. When loading a save, the engine now skips unknown symbols, instead of crashing
\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/zparserextender/dialogues/index.html b/pl/zengin/scripts/extenders/zparserextender/dialogues/index.html deleted file mode 100644 index 096f1e4775..0000000000 --- a/pl/zengin/scripts/extenders/zparserextender/dialogues/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/pl/zengin/scripts/extenders/zparserextender/events/index.html b/pl/zengin/scripts/extenders/zparserextender/events/index.html deleted file mode 100644 index dc34083f74..0000000000 --- a/pl/zengin/scripts/extenders/zparserextender/events/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/pl/zengin/scripts/extenders/zparserextender/examples/signposts/index.html b/pl/zengin/scripts/extenders/zparserextender/examples/signposts/index.html deleted file mode 100644 index 6e41bf6742..0000000000 --- a/pl/zengin/scripts/extenders/zparserextender/examples/signposts/index.html +++ /dev/null @@ -1,367 +0,0 @@ - Sign post example - Gothic Modding Community

Sign post teleportation

This is a short "problem-solving" example, where we try to demonstrate the power of Daedalus injection using zParserExtender. GaroK asked me if there is a way to teleport to all the sign posts in Khorinis to gather information for a Gothic wiki article.
The goal is to introduce a function that will teleport you to every signpost in Khorinis with the press of a button.

The problem

In ZenGin you can teleport to named game objects with the goto vob {vobname} command. But since the signposts do not have a vobname defined, I had to figure out a different approach.

ASCII ZEN

We want to get all the signposts position from Khorinis. The game world was loaded into one of the available world editor, I found one of the signposts and noted the visual which dictates the model of the in-game object nw_misc_sign_01.3DS. Alternatively, you can find the standard vanilla objects from both games on this website.
Next, the world was saved as a ASCII ZEN format. This allows us to write a macro to search for all instances of objects with a specific visual and extract the position vector.

One signpost object
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
[% oCMOB:zCVob 47105 317]
-    pack=int:0
-    presetName=string:
-    bbox3DWS=rawFloat:7564.8291 127.361191 -80.5309067 7611.52441 377.422913 1.67681122 
-    trafoOSToWSRot=raw:73e1673f9c4ec33b15efd8be4465d7bba0fe7f3f30ea7137e5edd83eecaa353bb7e2673f
-    trafoOSToWSPos=vec3:7588.17627 252.391052 -39.4283791
-    vobName=string:
-    visual=string:NW_MISC_SIGN_01.3DS
-    showVisual=bool:1
-    visualCamAlign=enum:0
-    visualAniMode=enum:0
-    visualAniModeStrength=float:0
-    vobFarClipZScale=float:1
-    cdStatic=bool:1
-    cdDyn=bool:1
-    staticVob=bool:1
-    dynShadow=enum:0
-    zbias=int:0
-    isAmbient=bool:0
-    [visual zCProgMeshProto 53505 318]
-    []
-    [ai % 0 0]
-    []
-    focusName=string:MOBNAME_INCITY02
-    hitpoints=int:10
-    damage=int:0
-    moveable=bool:0
-    takeable=bool:0
-    focusOverride=bool:0
-    soundMaterial=enum:0
-    visualDestroyed=string:
-    owner=string:
-    ownerGuild=string:
-    isDestroyed=bool:0
-[]
-

Tip

You can also see that the focusName has a MOBNAME_INCITY02 string constant.
This constant is defined in the scripts and its content is used as the focus name.

const string MOBNAME_INCITY02 = "To Marketplace";
-

The injectable script

As it is an injectable script, we have to specify the META tag.
Lets tell zParserExtender to insert this code into the game parser.

1
-2
-3
-4
META
-{
-    Parser = Game
-};
-
We want to teleport the player and for this we will need the C_Position and C_Vob_Data classes.
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
class C_Position
-{
-    var int X; // X coordinate
-    var int Y; // Y coordinate
-    var int Z; // Z coordinate
-};
-
-class C_VOB_DATA
-{
-    var string Name;              // object name
-    var float VisualAlpha;        // object's transparency 0.0 - 1.0
-    var int ShowVisual;           // display the mode
-    var int DrawBBox3D;           // show objects bounding box
-    var int VisualAlphaEnabled;   // enables objects transparency
-    var int PhysicsEnabled;       // enables object's physics
-    var int IgnoredByTraceRay;    // allow any object collisions
-    var int CollDetectionStatic;  // allow collision with static world polygons
-    var int CollDetectionDynamic; // allow collision with dynamic world objects
-    var int CastDynShadow;        // display shadow of the object
-    var int LightColorStatDirty;  // allow static lighting of the object
-    var int LightColorDynDirty;   // allow dynamic lighting of the object
-    var int SleepingMode;         // sets object's activity mode (0 - inactive, 1 - active, 2 - AI only)
-    var int DontWriteIntoArchive; // turns of the serialization of this object to the save file 
-};
-
It turns out there is 54 instances of objects with the desired visual. Let us define const int NUM_OF_SIGNS = 54 and a const int MAX_COORDS = 3 * NUM_OF_SIGNS - we will store 3 times 54 integers - for every signpost a x, y and z coordinate. And lastly a const int array containing all the positions.
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
-37
-38
-39
-40
-41
-42
-43
-44
-45
-46
-47
-48
-49
-50
-51
-52
-53
-54
-55
-56
-57
-58
-59
-60
// Number of signs we want to jump to
-const int NUM_OF_SIGNS = 54;
-const int MAX_COORDS = 3 * NUM_OF_SIGNS;
-
-const int sign_coordinates[MAX_COORDS] = {
-    11974,  309,   6815,
-    12024,  310,   6778,
-    12411,  1668,  -22495,
-    19491,  1281,  1669,
-    19563,  1281,  1687,
-    20294,  2058,  12487,
-    20324,  2058,  12419,
-    21917,  2900,  -22751,
-    2600,   -57,   -4351,
-    26695,  2419,  4308,
-    26770,  2418,  4319,
-    26978,  2937,  6130,
-    27015,  2936,  6104,
-    27049,  2937,  6159,
-    2964,   2142,  14424,
-    31383,  3896,  4699,
-    31427,  3896,  4640,
-    35368,  3870,  -4374,
-    35435,  3870,  -4355,
-    35437,  3871,  -4399,
-    36205,  3333,  -27186,
-    37774,  3875,  -501,
-    37812,  3874,  -469,
-    37849,  3874,  -512,
-    38291,  3732,  -6699,
-    39276,  3926,  -3357,
-    39307,  3924,  -3313,
-    39351,  3924,  -3359,
-    39435,  4350,  10902,
-    39458,  4350,  10827,
-    40932,  3861,  -3054,
-    42454,  2838,  -19437,
-    5297,   387,   -2145,
-    5358,   387,   -2184,
-    5362,   387,   -2128,
-    54006,  1723,  -10316,
-    54035,  1723,  -10387,
-    551,    -62,   -1820,
-    61080,  2132,  -11622,
-    61155,  2132,  -11625,
-    6408,   392,   3598,
-    6432,   393,   3652,
-    7000,   387,   -1482,
-    73439,  3341,  -11307,
-    7588,   252,   -39,
-    7590,   252,   -109,
-    7642,   253,   -83,
-    7713,   387,   -4782,
-    7758,   386,   -4775,
-    7776,   388,   -4811,
-    8154,   1206,  -17022,
-    8855,   395,   -2402,
-    9704,   393,   5129,
-    9738,   392,   5108
-};
-
Next define a built in event GameLoop function, to check for a pressed key. If the key U is pressed, the jump_to_sign function is called.
1
-2
-3
-4
-5
-6
-7
-8
-9
// check for pressed U button every frame
-func event GameLoop()
-{
-    // if U is toggled, run the function
-    if (Hlp_KeyToggled(KEY_U))
-    {
-        jump_to_sign();
-    };
-};
-

Let's look at the jump_to_sign function now.
This function is called on every U key press and goes through all the signposts and teleports the player to them.
At the start of the function we check if the index is not out of bounds and if it is, sets it back to 0 and starts over.

1
-2
-3
-4
-5
    // if we reached the end, start over
-    if (tp_index >= NUM_OF_SIGNS)
-    {
-        tp_index = 0;
-    };
-
Notice the use of Str_Format function for the formatted output.
1
-2
-3
-4
-5
// give information to the player
-Print(Str_Format("Sign %i/%i", tp_index+1, NUM_OF_SIGNS));
-
-var C_Position pos;  pos  = Vob_GetVobPosition(hero);
-var C_Vob_Data data; data = Vob_GetVobData(hero);
-
Daedalus does not allow array access with variables (only constants and literals). To access the coordinate array we use a selection of parser functions.
Firstly we get the game parser ID. Then we can use the Par_GetSymbolValueIntArray to access the sign_coordinates array and assign the coordinates to the pos variable.
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
// get parser ID for the GAME parser
-var int game_par_id; game_par_id = Par_GetParserID("game");
-
-// get parser ID of the array
-var int arr_id; arr_id = Par_GetSymbolID(game_par_id ,"sign_coordinates");
-
-// access the coordinates from above array
-pos.x = Par_GetSymbolValueIntArray(game_par_id ,arr_id ,tp_index * 3    ); 
-pos.y = Par_GetSymbolValueIntArray(game_par_id ,arr_id ,tp_index * 3 + 1);
-pos.z = Par_GetSymbolValueIntArray(game_par_id ,arr_id ,tp_index * 3 + 2);
-
And now comes the big trick. If you try to just change the position the dynamic and static collision is going to stop you at the first wall, tree or a mountain. To disable it, we can use the C_Vob_Data helper class, get players data, and disable both the static a dynamic collision. First we create a backup of the values just so we can restore them back after the teleport.
1
-2
-3
-4
-5
-6
-7
// backup original collision detection
-var int dyn;   dyn = data.CollDetectionDynamic;
-var int stat; stat = data.CollDetectionStatic;
-
-// turn off collision detection 
-data.CollDetectionDynamic = 0;
-data.CollDetectionStatic  = 0;
-
Let us apply the changed data to the player and edit the position.
1
-2
-3
-4
-5
// apply the edited data to player
-Vob_SetVobData(hero, data);
-
-// move the player 
-Vob_SetVobPosition(hero, pos);
-
Restore the collision detection data from the backup we made and set it.
1
-2
-3
-4
-5
-6
// restore collision detection
-data.CollDetectionDynamic = dyn;
-data.CollDetectionStatic  = stat;
-
-// apply the edited data to player
-Vob_SetVobData(hero, data);
-
Finally, we advance the index to jump to another signpost.
1
-2
// advance the index
-tp_index += 1;
-
\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/zparserextender/extern/index.html b/pl/zengin/scripts/extenders/zparserextender/extern/index.html deleted file mode 100644 index cfee35ac90..0000000000 --- a/pl/zengin/scripts/extenders/zparserextender/extern/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/pl/zengin/scripts/extenders/zparserextender/externals/ai/index.html b/pl/zengin/scripts/extenders/zparserextender/externals/ai/index.html deleted file mode 100644 index deb65eeb9c..0000000000 --- a/pl/zengin/scripts/extenders/zparserextender/externals/ai/index.html +++ /dev/null @@ -1,66 +0,0 @@ - AI functions - Gothic Modding Community

AI - functions for working with AI

Functions to work with the new C_Trigger class and NPC's AI queue.

AI_CallScript

Adds a funcName function call to the AI queue

1
-2
-3
func void AI_CallScript(var string funcName,
-                        var C_NPC slf,
-                        var C_NPC oth) {};
-
  • funcName - name of the function to be called
  • slf - will be inserted into global self instance
  • oth - will be inserted into global other instance

AI_startTriggerScript

Creates a trigger script that calls function funcName once every interval in milliseconds

func C_Trigger AI_startTriggerScript(var string funcName, var int interval) {};
-
  • funcName - name of the function to be called
  • interval - call period in milliseconds
  • return - created C_Trigger instance

AI_startTriggerScriptEx

Extended version call - Creates a trigger script, that calls function funcName once every interval in milliseconds also updates the self, other and victim global instances based on slf, oth and vct parameters respectively

1
-2
-3
-4
-5
func C_Trigger AI_startTriggerScriptEx( var string funcName,
-                                        var int interval,
-                                        var C_NPC slf,
-                                        var C_NPC oth,
-                                        var C_NPC vct) {};
-
  • funcName - name of the function to be called
  • interval - call period in milliseconds
  • slf - will be inserted into global self instance
  • oth - will be inserted into global other instance
  • vct - will be inserted into global victim instance
  • return - created C_Trigger instance

AI_GetTriggerByID

Returns a C_Trigger instance from the array of active triggers by the array index ID

func C_Trigger AI_GetTriggerByID(var int ID) {};
-
  • ID - array id
  • return - active C_Trigger instance

AI_GetTriggersNum

Returns the number of active C_Trigger scripts

func int AI_GetTriggersNum() {};
-
  • return - number of active C_Trigger scripts

AI_GetTriggerNPC

Returns the npc associated with the C_Trigger script based on the ID selfID = 0; otherID = 1; victimID = 2;

func C_NPC AI_GetTriggerNPC(var C_Trigger trigger, var int npcID) {};
-
  • trigger - C_Trigger script
  • npcID - NPC id
  • return - active C_Trigger instance

AI_GetTriggerFunc

Returns the function associated with the specified C_Trigger

func func AI_GetTriggerFunc(var C_Trigger trigger) {};
-
  • trigger - C_Trigger script
  • return - trigger function

AI_GetTriggerFuncName

Returns the function name of a function associated with the specified C_Trigger

func string AI_GetTriggerFuncName(var C_Trigger trigger) {};
-
  • trigger - C_Trigger script
  • return - active C_Trigger instance

Ai_GetNextTriggerByFunc

Returns the next trigger in the active trigger array based on the trigger function, starting on the startTrigger trigger

func C_Trigger Ai_GetNextTriggerByFunc(var C_Trigger startTrigger, var func function) {};
-
  • startTrigger - C_Trigger script to start the search from
  • function - function to be matched
  • return - C_Trigger instance

Ai_GetNextTriggerByFuncName

Returns the next trigger in the active trigger array based on the trigger function name, starting on the startTrigger trigger

func C_Trigger Ai_GetNextTriggerByFuncName(var C_Trigger startTrigger, var string functionName) {};
-
  • startTrigger - C_Trigger script to start the search from
  • functionName - name of a function to be matched
  • return - C_Trigger instance

Ai_GetNextTriggerBySelf

Returns the next trigger in the active trigger array based on the self trigger parameter, starting on the startTrigger instance set in the trigger

func C_Trigger Ai_GetNextTriggerBySelf(var C_Trigger startTrigger, var C_NPC self) {};
-
  • startTrigger - C_Trigger script to start the search from
  • self - C_NPC instance
  • return - C_Trigger instance

Ai_GetNextTriggerByOther

Returns the next trigger in the active trigger array based on the other trigger parameter, starting on the startTrigger instance set in the trigger

func C_Trigger Ai_GetNextTriggerByOther(var C_Trigger startTrigger, var C_NPC other) {};
-
  • startTrigger - C_Trigger script to start the search from
  • other - C_NPC instance
  • return - C_Trigger instance

Ai_GetNextTriggerByVictim

Returns the next trigger in the active trigger array based on the victim trigger parameter, starting on the startTrigger instance set in the trigger

func C_Trigger Ai_GetNextTriggerByVictim( var C_Trigger startTrigger, var C_NPC victim ) {};
-
  • startTrigger - C_Trigger script to start the search from
  • victim - C_NPC instance
  • return - C_Trigger instance

Ai_GetNextTriggerByNPCs

Returns the next trigger in the active trigger array based on all the NPCs set in the trigger script self, other and victim, starting on the startTrigger instance set in the trigger

1
-2
-3
-4
func c_trigger Ai_GetNextTriggerByNPCs( var C_Trigger startTrigger,
-                                        var C_NPC self,
-                                        var C_NPC other,
-                                        var C_NPC victim) {};
-
  • startTrigger - C_Trigger script to start the search from
  • self - self C_NPC instance
  • other - other C_NPC instance
  • victim - victim C_NPC instance
  • return - C_Trigger instance
\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/zparserextender/externals/cast/index.html b/pl/zengin/scripts/extenders/zparserextender/externals/cast/index.html deleted file mode 100644 index b05b98daa6..0000000000 --- a/pl/zengin/scripts/extenders/zparserextender/externals/cast/index.html +++ /dev/null @@ -1,45 +0,0 @@ - CAST functions - Gothic Modding Community

CAST - data type conversion functions

External functions for data type conversion and pointer casting.

Cast_PointerToInstance

Converts memory address (pointer) to an instance

func instance Cast_PointerToInstance(var int address) {};
-
  • address - object pointer
  • return - instance of the object

Cast_InstanceToPointer

Converts instance to a memory address (pointer)

func int Cast_InstanceToPointer( var instance object) {};
-
  • object - object instance
  • return - memory address (pointer) of the object

Cast_PointerToNpc

Casts memory address (pointer) to an NPC

func C_NPC Cast_PointerToNpc( var int address) {};
-
  • address - npc pointer
  • return - NPC instance

Cast_PointerToItem

Casts memory address (pointer) to an Item

func C_ITEM Cast_PointerToItem( var int address) {};
-
  • address - item pointer
  • return - Item instance

Cast_InstanceIsNpc

Checks whether object is an NPC

func int Cast_InstanceIsNpc( var instance object) {};
-
  • object - object to check
  • return - TRUE or FALSE

Cast_InstanceIsItem

Checks whether object is an Item

func int Cast_InstanceIsItem( var instance object) {};
-
  • object - object to check
  • return - TRUE or FALSE

Cast_InstanceIsMob

Checks whether object is an MOB

func int Cast_InstanceIsMob( var instance object) {};
-
  • object - object to check
  • return - TRUE or FALSE

Cast_GetInstanceIndex

Returns symbolID of the object, returns -1 when not found

func int Cast_GetInstanceIndex( var instance object) {};
-
  • object - instance of an object
  • return - symbol table index, -1 when not found

Cast_GetClassID

Returns the class identifier of a class by its name

func int Cast_GetClassID( var string className ) {};
-
  • className - name of the class
  • return - class identifier

Cast_GetVobClassID

Returns class identifier of the zCObject vob class

func int Cast_GetVobClassID( var instance object ) {};
-
  • object - object instance
  • return - class zCObject identifier

Cast_CheckVobClassID

Checks if the classId class is the parent class of the object

func int Cast_CheckVobClassID( var int classId, var instance object ) {};
-
  • classId - class identifier, from Cast_GetClassID function
  • object - object instance
  • return - class zCObject identifier
\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/zparserextender/externals/events_vars/index.html b/pl/zengin/scripts/extenders/zparserextender/externals/events_vars/index.html deleted file mode 100644 index 64ea52846b..0000000000 --- a/pl/zengin/scripts/extenders/zparserextender/externals/events_vars/index.html +++ /dev/null @@ -1,55 +0,0 @@ - Event functions - Gothic Modding Community

Event functions and variables

On top of external functions, zParserExtender also adds these event functions and constants.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
/// Every event function with this name is executed once every frame
-func event GameLoop() {};
-
-/// Every event function with this name is executed once on game init
-func event GameInit() {};
-
-/// empty instance
-const instance null;
-
-/// not a number floating point constant
-const float NaN;
-
\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/zparserextender/externals/hlp/index.html b/pl/zengin/scripts/extenders/zparserextender/externals/hlp/index.html deleted file mode 100644 index 2a08f8d230..0000000000 --- a/pl/zengin/scripts/extenders/zparserextender/externals/hlp/index.html +++ /dev/null @@ -1,54 +0,0 @@ - HLP functions - Gothic Modding Community

HLP - help functions

Helper functions generally used for safety checks, to get specific information from the engine or to interface with the configuration .ini files.

Hlp_HasFocusVob

Returns TRUE, if a specified NPC has a Vob in focus

func int Hlp_HasFocusVob( var C_NPC npc ) {};
-
  • npc - NPC
  • return - TRUE if npc has a focus Vob, FALSE if it does not

Hlp_GetFocusVob

Returns NPC's focus Vob

func instance Hlp_GetFocusVob( var C_NPC npc ) {};
-
  • npc - NPC
  • return - focus vob

Hlp_GetFocusVobName

Returns the name of NPC's focus vob

func string Hlp_GetFocusVobName( var C_NPC npc ) {};
-
  • npc - NPC
  • return - focus vob name

Hlp_GetStringLength

Returns the length of a specified string

func int Hlp_GetStringLength( var string str ) {};
-
  • return - length of str

IsNAN

Checks whether floating point number is valid

func int IsNAN( var float value ) {};
-
  • return - TRUE if value is NaN, FALSE if value is a valid floating point number

Hlp_KeyToggled

Checks whether key is toggled

func int Hlp_KeyToggled( var int key ) {};
-
  • key - key code
  • return - TRUE if key is toggled, FALSE if key is not toggled

Hlp_KeyPressed

Checks whether key is pressed

func int Hlp_KeyPressed( var int key ) {};
-
  • key - key code
  • return - TRUE if key is pressed, FALSE if key is not pressed

Hlp_LogicalKeyToggled

Checks whether logical key is toggled

func int Hlp_LogicalKeyToggled( var int key ) {};
-
  • key - key code
  • return - TRUE if key is toggled, FALSE if key is not toggled

Hlp_GameOnPause

Checks whether the game is paused

func int Hlp_GameOnPause() {};
-
  • return - TRUE if the game is paused, FALSE if the game is not paused

Hlp_MessageBox

Opens a message box with a specified message

func void Hlp_MessageBox( var string message ) {};
-
  • message - message to be printed

Hlp_PrintConsole

Prints a message to the Union debug console

func void Hlp_PrintConsole(var string message) {};
-
  • message - message to be printed

Hlp_OptionIsExists

Checks whether the entry in section in .ini file optName exists

optName values

  • "Gothic"
  • "Mod"
  • "SystemPack"
func int Hlp_OptionIsExists(var string optName, var string section, var string entry) {};
-
  • optName - the .ini file
  • section - settings section like [GAME]
  • entry - one setting entry like playLogoVideos
  • return - TRUE if the option exists, FALSE if the option does not exist

Hlp_ReadOptionInt

Read an integer value from specified .ini file, section and entry.

optName values

  • "Gothic"
  • "Mod"
  • "SystemPack"
func int Hlp_ReadOptionInt(var string optName, var string section, var string entry, var int default) {};
-
  • optName - the .ini file
  • section - settings section like [GAME]
  • entry - one setting entry like playLogoVideos
  • default - default value - if the value is empty
  • return - the option value

Hlp_ReadOptionFloat

Read a floating point value from specified .ini file, section and entry.

optName values

  • "Gothic"
  • "Mod"
  • "SystemPack"
func float Hlp_ReadOptionFloat(var string optName, var string section, var string entry, var float default) {};
-
  • optName - the .ini file
  • section - settings section like [INTERFACE]
  • entry - one setting entry like scale
  • default - default value - if the value is empty
  • return - the option value

Hlp_ReadOptionString

Read a string value from specified .ini file, section and entry.

optName values

  • "Gothic"
  • "Mod"
  • "SystemPack"
func string Hlp_ReadOptionString(var string optName, var string section, var string entry, var string default) {};
-
  • optName - the .ini file
  • section - settings section like [INTERFACE]
  • entry - one setting entry like scale
  • default - default value - if the value is empty
  • return - the option value

Hlp_WriteOptionInt

Writes an integer value to specified .ini file, section and entry.

optName values

  • "Gothic"
  • "Mod"
  • "SystemPack"
func void Hlp_WriteOptionInt(var string optName, var string section, var string entry, var int value) {};
-
  • optName - the .ini file
  • section - settings section like [INTERFACE]
  • entry - one setting entry like scale
  • value - value to be written

Hlp_WriteOptionFloat

Writes a floating point value to specified .ini file, section and entry.

optName values

  • "Gothic"
  • "Mod"
  • "SystemPack"
func void Hlp_WriteOptionFloat(var string optName, var string section, var string entry, var float value) {};
-
  • optName - the .ini file
  • section - settings section like [INTERFACE]
  • entry - one setting entry like scale
  • value - value to be written

Hlp_WriteOptionString

Writes a string value to specified .ini file, section and entry.

optName values

  • "Gothic"
  • "Mod"
  • "SystemPack"
func void Hlp_WriteOptionString(var string optName, var string section, var string entry, var string value) {};
-
  • optName - the .ini file
  • section - settings section like [INTERFACE]
  • entry - one setting entry like scale
  • value - value to be written

Hlp_GetSteamPersonalName

Returns the name of the current Steam user Returns empty string when not run with Steam

func string Hlp_GetSteamPersonalName() {};
-
  • return - string containing the Steam username, or an empty string

Hlp_DoEvent

Calls every event function with the name funcName.

func void Hlp_DoEvent(var string funcName) {};
-
  • funcName - name of the event function to be called (all of them).
\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/zparserextender/externals/log/index.html b/pl/zengin/scripts/extenders/zparserextender/externals/log/index.html deleted file mode 100644 index 066fda3334..0000000000 --- a/pl/zengin/scripts/extenders/zparserextender/externals/log/index.html +++ /dev/null @@ -1,36 +0,0 @@ - Log functions - Gothic Modding Community

Log functions

As discussed on Inside Gothic, vanilla Gothic has no way of getting the status of a quest. These functions implement that functionality.

Log_GetTopicStatus

Returns the status of diary topic

  • -1 - Not found
  • 0 - Free
  • 1 - Running
  • 2 - Success
  • 3 - Failure
  • 4 - Obsolete
func int Log_GetTopicStatus(var string topic) {};
-
  • topic - name of the topic
  • return - topic status

Log_GetTopicSection

Returns the topic the diary topic is in

  • -1 - Not found
  • 0 - Missions
  • 1 - Notes
  • 2 - All
func int Log_GetTopicSection(var string topic) {};
-
  • topic - name of the topic
  • return - topic section
\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/zparserextender/externals/mdl/index.html b/pl/zengin/scripts/extenders/zparserextender/externals/mdl/index.html deleted file mode 100644 index 4184bb1dbd..0000000000 --- a/pl/zengin/scripts/extenders/zparserextender/externals/mdl/index.html +++ /dev/null @@ -1,46 +0,0 @@ - MDL functions - Gothic Modding Community

MDL - model functions

Functions to tweak animation and other model related settings.

Mdl_GetAnimationIndex

Returns animation's index for specified NPC based on animation's name

func int Mdl_GetAnimationIndex( var C_NPC npc, var string ani_name ) {};
-
  • npc - NPC with the animation
  • ani_name - name of the animation in uppercase
  • return - animation index

Mdl_GetAnimationName

Returns animation's name for specified NPC based on animation's index

func string Mdl_GetAnimationName( var C_NPC npc, var int ani_index ) {};
-
  • npc - NPC with the animation
  • ani_index - animation index
  • return - animation name

Mdl_AnimationIsExists

Checks whether animation exists

func int Mdl_AnimationIsExists( var C_NPC npc, var int ani_index ) {};
-
  • npc - NPC with the animation
  • ani_index - animation index
  • return - animation name

Mdl_AnimationIsActive

Checks whether animation is active (whether it is currently played)

func int Mdl_AnimationIsActive( var C_NPC npc, var int ani_index ) {};
-
  • npc - NPC with the animation
  • ani_index - animation index
  • return - TRUE if the animation is playing, FALSE if it is not playing

Mdl_SetAllAnimationsFPS

Set framerate for all animations

func void Mdl_SetAllAnimationsFPS( var C_NPC npc, var float fps ) {};
-
  • npc - NPC with the animation
  • fps - framerate

Mdl_ResetAllAnimationsFPS

Reset framerate for all animations to default value

func void Mdl_ResetAllAnimationsFPS( var C_NPC npc ) {};
-
  • npc - NPC with the animation

Mdl_SetAnimationFPS

Set framerate for animation specified by animation index

func void Mdl_SetAnimationFPS( var C_NPC npc, var int ani_index, var float fps ) {};
-
  • npc - NPC with the animation
  • ani_index - animation index
  • fps - framerate

Mdl_ResetAnimationFPS

Reset framerate to default for animation specified by animation index

func void Mdl_ResetAnimationFPS( var C_NPC npc, var int ani_index ) {};
-
  • npc - NPC with the animation
  • ani_index - animation index

Mdl_SetVisible

Set NPCs visibility

func void Mdl_SetVisible( var C_NPC npc, var int isVisible ) {};
-
  • npc - specified NPC
  • isVisible - TRUE - visible, FALSE - invisible

Mdl_ApplyOverlayMds_AtFirst

Applies or moves existing overlay to the top of the list

func void Mdl_ApplyOverlayMds_AtFirst( var string mdsName ) {};
-
  • mdsName - name of the overlay

Mdl_SetNpcSpeedMultiplier

Sets a multiplier for animation speed 1.0 = 100% speed (normal speed)

func void Mdl_SetNpcSpeedMultiplier( var C_Npc npc, var float multiplier ) {};
-
  • npc - npc to be affected
  • multiplier - speed of the animation

Mdl_ResetNpcSpeedMultiplier

Resets the animation speed of an NPC

func void Mdl_ResetNpcSpeedMultiplier( var C_Npc npc ) {};
-
  • npc - npc to be affected
\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/zparserextender/externals/menu/index.html b/pl/zengin/scripts/extenders/zparserextender/externals/menu/index.html deleted file mode 100644 index af7227544a..0000000000 --- a/pl/zengin/scripts/extenders/zparserextender/externals/menu/index.html +++ /dev/null @@ -1,56 +0,0 @@ - Menu function - Gothic Modding Community

Menu function

Find all C_MenuItem object instances by the mask and automatically places them in the current menu instance

func void Menu_SearchItems( var string mask ) {};
-
  • mask - regex like mask for searching

Example

This function is used in the Union Menu API script.
In this script the Menu_SearchItems external is used to collect all Union menu scripts that are placed into the Union & Plugins menu that will appear in the game if you use any of the plugins that use this feature.

Usage of Menu_SearchItems external function
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
instance MENU_OPT_UNION(C_MENU_DEF)
-{
-    Menu_SearchItems("MENUITEM_UNION_AUTO_*");
-    MENU_OPT_UNION_PY = 1200;
-    backpic           = MENU_BACK_PIC;
-    items[0]          = "UNION_MENUITEM_TITLE";
-    items[100]        = "UNION_MENUITEM_BACK";
-    defaultoutgame    = 0;
-    defaultingame     = 0;
-    Flags             = Flags | MENU_SHOW_INFO;
-};
-

In this case all instances are of the name MENUITEM_UNION_AUTO_* where * is a wildcard that can be substituted with anything. The plugin will search the scripts and find all instances (in the case of zGamePad it is MenuItem_Union_Auto_zGamePad)

This example comes from the zUnionMenu.d injectable API script that is part of the zGamePad plugin, GitHub link.

\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/zparserextender/externals/mob/index.html b/pl/zengin/scripts/extenders/zparserextender/externals/mob/index.html deleted file mode 100644 index c39b201b46..0000000000 --- a/pl/zengin/scripts/extenders/zparserextender/externals/mob/index.html +++ /dev/null @@ -1,45 +0,0 @@ - MOB functions - Gothic Modding Community

MOB - interactive object functions

Functions to manipulate interactive objects like destroying MOBs, setting lockpick combination and such.

Mob_Destroy

Marks oCMOB as destroyed, changes the visual to visualDestroyed (if present).

func void Mob_Destroy( var instance object ) {};
-
  • object - oCMOB to be destroyed

Mob_RemoveItem

Removes an item from a oCMobContainer

func void Mob_RemoveItem( var instance object, var int item ) {};
-
  • object - oCMobContainer object
  • item - item to be removed

Mob_RemoveItems

Removes specified number of items from a oCMobContainer

func void Mob_RemoveItems( var instance object, var int item, var int cnt ) {};
-
  • object - oCMobContainer object
  • item - item to be removed
  • cnt - number of items to be removed

Mob_InsertItem

Inserts an item into a oCMobContainer

func void Mob_InsertItem( var instance object, var int item ) {};
-
  • object - oCMobContainer object
  • item - item to be inserted

Mob_InsertItems

Inserts specified number of items into a oCMobContainer

func void Mob_InsertItems( var instance object, var int item, var int cnt ) {};
-
  • object - oCMobContainer object
  • item - item to be inserted
  • cnt - number of items to be inserted

Mob_GetLockCombination

Returns a lock combination of a oCMobContainer

func string Mob_GetLockCombination( var instance object ) {};
-
  • object - oCMobContainer object
  • return - lock combination

Mob_SetLockCombination

Sets a lock combination to a oCMobContainer

func void Mob_SetLockCombination( var instance object, var string comb ) {};
-
  • object - oCMobContainer object
  • comb - lock combination

Mob_IsLocked

Returns TRUE if the object is locked

func int Mob_IsLocked( var instance object ) {};
-
  • object - oCMobLockable object
  • return - TRUE if locked, FALSE if unlocked

Mob_SetLocked

Set the lock status of the object

func void Mob_SetLocked( var instance object, var int locked ) {};
-
  • object - oCMobLockable object
  • locked - lock or unlock the object

Mob_GetKeyInstance

Returns the key instance, that unlocks the object

func instance Mob_GetKeyInstance( var instance object ) {};
-
  • object - oCMobLockable object
  • return - the key C_ITEM instance

Mob_SetKeyInstance

Stets the key instance, that unlocks the object

func void Mob_SetKeyInstance( var instance object, var int key ) {};
-
  • object - oCMobLockable object
  • key - the key C_ITEM instance
\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/zparserextender/externals/npc/index.html b/pl/zengin/scripts/extenders/zparserextender/externals/npc/index.html deleted file mode 100644 index 16b49837df..0000000000 --- a/pl/zengin/scripts/extenders/zparserextender/externals/npc/index.html +++ /dev/null @@ -1,43 +0,0 @@ - NPC functions - Gothic Modding Community

NPC - character functions

NPC related functions.

Npc_SetAsHero

Changes players character to specified npc

func void Npc_SetAsHero( var C_NPC npc ) {};
-
  • npc - NPC to be set as players character

Npc_OpenInventory

Opens NPCs main inventory

func void Npc_OpenInventory( var C_NPC npc ) {};
-
  • npc - NPC

Npc_OpenInventorySteal

Opens the steal inventory of npc's focus NPC

func void Npc_OpenInventorySteal( var C_NPC npc ) {};
-
  • npc - NPC

Npc_OpenInventoryTrade

Start the trading dialogue with specified NPC

func void Npc_OpenInventoryTrade( var C_NPC npc ) {};
-
  • npc - NPC

Npc_GetLeftHandItem

Returns an item in NPC's left hand slot

func C_Item Npc_GetLeftHandItem( var C_Npc npc ) {};
-
  • npc - npc to be affected
  • return - found C_ITEM instance

Npc_GetRightHandItem

Returns an item in NPC's right hand slot

func C_Item Npc_GetRightHandItem( var C_Npc npc ) {};
-
  • npc - npc to be affected
  • return - found C_ITEM instance

Npc_GetSlotItem

Returns an item from a slot with the slotName

func C_Item Npc_GetSlotItem( var C_Npc npc, var string slotName ) {};
-
  • npc - npc to be affected
  • slotName - name of the slot
  • return - found C_ITEM instance

Npc_PutInSlot

Places an instance of the oCVom class (including items and NPCs) object into the slotName of the NPC The copyInInv parameter determines whether a copy of the object should remain in the character's inventory

func void Npc_PutInSlot(var C_Npc npc, var string slotName, var instance object, var int copyInInv) {};
-
  • npc - npc to remove the item from
  • slotName - name of the slot from which to remove the item
  • object - object to be inserted into the slot
  • copyInInv - should a copy of the object stay in character inventory

Npc_RemoveFromSlot

Removes an object from the slotName of the NPC. The dropIt parameter in Gothic 2 defines, whether object should drop out of the slot. In Gothic 1, this parameter is reserved and must be 0.

func void Npc_RemoveFromSlot(var C_Npc npc, var string slotName, var int dropIt) {};
-
  • npc - npc to remove the item from
  • slotName - name of the slot from which to remove the item
  • dropIt - should the object be dropped
\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/zparserextender/externals/par/index.html b/pl/zengin/scripts/extenders/zparserextender/externals/par/index.html deleted file mode 100644 index 13efc61700..0000000000 --- a/pl/zengin/scripts/extenders/zparserextender/externals/par/index.html +++ /dev/null @@ -1,51 +0,0 @@ - PAR functions - Gothic Modding Community

PAR - functions for parser manipulation

Parser functions are used to manipulate the parsers. Retrieve SymbolID, access arrays and such.

Par_GetParserID

Returns a parser ID of the parser with a parName name

Parser names:

  • "Game"
  • "SFX"
  • "PFX"
  • "VFX"
  • "Camera"
  • "Menu"
  • "Music"
func int Par_GetParserID(var string parName) {};
-
  • parName - parser name
  • return - parser ID

Par_GetSymbolID

Returns symbol ID for the symbol specified by its name

func int Par_GetSymbolID(var int parId, var string symName) {};
-
  • parID - parser ID
  • symName - symbol name
  • return - symbol ID

Par_GetSymbolLength

Returns symbol length (number of elements)

func int Par_GetSymbolLength(var int parId, var int symId) {};
-
  • parID - parser ID
  • symName - symbol name
  • return - symbol length

Par_GetSymbolValueInt

Returns the integer value of specified symbol

func int Par_GetSymbolValueInt(var int parId, var int symId) {};
-
  • parID - parser ID
  • symName - symbol name
  • return - symbol value

Par_GetSymbolValueFloat

Returns the float value of specified symbol

func float Par_GetSymbolValueFloat(var int parId, var int symId) {};
-
  • parID - parser ID
  • symName - symbol name
  • return - symbol value

Par_GetSymbolValueString

Returns the string value of specified symbol

func string Par_GetSymbolValueString(var int parId, var int symId) {};
-
  • parID - parser ID
  • symName - symbol name
  • return - symbol value

Par_GetSymbolValueInstance

Returns the instance value of specified symbol

func instance Par_GetSymbolValueInstance(var int parId, var int symId) {};
-
  • parID - parser ID
  • symName - symbol name
  • return - symbol value

Par_GetSymbolValueIntArray

Returns the value of specified integer array at the arrayID index

func int Par_GetSymbolValueIntArray(var int parId, var int symId, var int arrayId) {};
-
  • parID - parser ID
  • symName - symbol name
  • arrayID - array index
  • return - value

Par_GetSymbolValueFloatArray

Returns the value of specified float array at the arrayID index

func float Par_GetSymbolValueFloatArray(var int parId, var int symId, var int arrayId) {};
-
  • parID - parser ID
  • symName - symbol name
  • arrayID - array index
  • return - value

Par_GetSymbolValueStringArray

Returns the value of specified string array at the arrayID index

func string Par_GetSymbolValueStringArray(var int parId, var int symId, var int arrayId) {};
-
  • parID - parser ID
  • symName - symbol name
  • arrayID - array index
  • return - value

Par_SetSymbolValueInt

Sets a new integer value to specified symbol

func void Par_SetSymbolValueInt(var int value, var int parId, var int symId) {};
-
  • value - value to be set
  • parID - parser ID
  • symId - symbol ID

Par_SetSymbolValueFloat

Sets a new float value to specified symbol

func void Par_SetSymbolValueFloat(var float value, var int parId, var int symId) {};
-
  • value - value to be set
  • parID - parser ID
  • symId - symbol ID

Par_SetSymbolValueString

Sets a new string value to specified symbol

func void Par_SetSymbolValueString(var string value, var int parId, var int symId) {};
-
  • value - value to be set
  • parID - parser ID
  • symId - symbol ID

Par_SetSymbolValueInstance

Sets a new instance value to specified symbol

func void Par_SetSymbolValueInstance(var instance value, var int parId, var int symId, var int arrayId) {};
-
  • value - value to be set
  • parID - parser ID
  • symId - symbol ID

Par_SetSymbolValueIntArray

Sets a new integer value to specified integer array symbol

func void Par_SetSymbolValueIntArray(var int value, var int parId, var int symId, var int arrayId) {};
-
  • value - value to be set
  • parID - parser ID
  • symId - symbol ID
  • arrayId - array index

Par_SetSymbolValueFloatArray

Sets a new float value to specified float array symbol

func void Par_SetSymbolValueFloatArray(var float value, var int parId, var int symId, var int arrayId) {};
-
  • value - value to be set
  • parID - parser ID
  • symId - symbol ID
  • arrayId - array index

Par_SetSymbolValueStringArray

Sets a new string value to specified string array symbol

func void Par_SetSymbolValueStringArray(var string value, var int parId, var int symId, var int arrayId) {};
-
  • value - value to be set
  • parID - parser ID
  • symId - symbol ID
  • arrayId - array index
\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/zparserextender/externals/string/index.html b/pl/zengin/scripts/extenders/zparserextender/externals/string/index.html deleted file mode 100644 index e12b34a569..0000000000 --- a/pl/zengin/scripts/extenders/zparserextender/externals/string/index.html +++ /dev/null @@ -1,77 +0,0 @@ - String functions - Gothic Modding Community

String functions

Functions to manipulate and format strings.

Str_Format

Returns formatted string using format specifiers

Format specifiers:

  • %s - inserts a string
  • %i - inserts an integer number
  • %x - inserts an integer in hexadecimal
  • %f - inserts a floating point number
  • %b - inserts a logical expression
  • %p - inserts a pointer
func string Str_Format( var string format, ... ) {};
-
  • return - formatted string

Examples

Very powerful function, can be used to streamline strings used in the scripts as well as optimize them for translations.

Define constants containing the string with format specifiers.

1
-2
const string MENU_SAVE = "Slot %i - press ENTER to save in this slot.";
-const string MENU_LOAD = "Slot %i - press ENTER to load saved game.";
-
Then define two format functions as such:
1
-2
-3
-4
func string GetSaveSlotString (var int number)
-{
-    return Str_format(MENU_SAVE, number);
-};
-
1
-2
-3
-4
func string GetLoadSlotString (var int number)
-{
-    return Str_format(MENU_LOAD, number);
-};
-

Tip

Since the whole translatable string is saved in one constant, it is very easy for translators to change the word order. This was not possible to do without code change to the ConcatStrings function calls within the scripts.
With this simple change, translators have to translate only 2 strings instead of 30 (15 + 15 slots) and only 2 strings are compiled into the compiled Menu.dat file.

Str_GetLocalizedString

Returns a string in the current language, otherwise in English. Arguments MUST be encoded in UTF-8! The result string will be converted to appropriate ANSI string.

1
-2
-3
-4
func string Str_GetLocalizedString( var string russian,
-                                    var string english,
-                                    var string german,
-                                    var string polish ) {};
-
  • russian - Russian string
  • english - English string
  • german - German string
  • polish - Polish string
  • return - string in the current language

Str_GetLocalizedStringEx

Returns a string in the current language, otherwise in English. Offers additional languages

1
-2
-3
-4
-5
-6
-7
-8
func string Str_GetLocalizedStringEx(   var string russian,
-                                        var string english,
-                                        var string german,
-                                        var string polish,
-                                        var string romanian,
-                                        var string italian,
-                                        var string czech,
-                                        var string spanish ) {};
-
  • russian - Russian string
  • english - English string
  • german - German string
  • polish - Polish string
  • romanian - Romanian string
  • italian - Italian string
  • czech - Czech string
  • spanish - Spanish string
  • return - string in the current language

Str_UTF8_to_ANSI

Converts UTF-8 string into an ANSI string with codePage

func string Str_UTF8_to_ANSI( var string utf8, var int codePage ) {};
-
  • utf8 - string encoded in UTF8
  • codePage - codePage id, can be obtained from Str_GetCurrentCP
  • return -

Str_GetCurrentCP

Return the code page corresponding to the current language set in the Union System

func int Str_GetCurrentCP() {};
-
  • return - code page corresponding to the current language

Str_GetLength

Returns the length of a string

func int Str_GetLength( var int str ) {};
-
  • str - string to be measured
  • return - length of the string
\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/zparserextender/externals/vob/index.html b/pl/zengin/scripts/extenders/zparserextender/externals/vob/index.html deleted file mode 100644 index fc8a620e60..0000000000 --- a/pl/zengin/scripts/extenders/zparserextender/externals/vob/index.html +++ /dev/null @@ -1,55 +0,0 @@ - VOB functions - Gothic Modding Community

VOB - functions for object manipulation

VOB functions allow you to manipulate game world objects.

Vob_GetVobPosition

Returns the current position of the object in the world

func C_Position Vob_GetVobPosition( var C_Vob vob ) {};
-
  • vob - vob to ge the position of
  • return - C_Position instance - position of the VOB

Vob_SetVobPosition

Sets the current position of the object in the world

func void Vob_SetVobPosition( var C_Vob vob, var C_Position pos ) {};
-
  • vob - vob to get the position of
  • pos - new position of the vob

Vob_GetVobData

Returns the universal data of the zCVob object

func C_Vob_Data Vob_GetVobData( var C_Vob vob ) {};
-
  • vob - VOB to get the position of
  • return - general vob data C_Vob_Data

Vob_SetVobData

Sets the universal data to a zCVob object

func void Vob_SetVobData( var C_Vob vob, var C_Vob_Data data ) {};
-
  • vob - VOB to get the position of
  • data - general vob data C_Vob_Data

Vob_GetLightData

Returns zCVobLight object data

func C_Light_Data Vob_GetLightData( var C_Vob vobLight ) {};
-
  • vobLight - vobLight object
  • return - C_Light_Data of the light

Vob_SetLightData

Sets the data of a zCVobLight object

func void Vob_SetLightData( var C_Vob vobLight, var C_Light_Data data ) {};
-
  • vobLight - object to apply the light data to
  • data - C_Light_Data light data to be set

Vob_ClearLightAniList

Clears the list of animation colours for the light source

func void Vob_ClearLightAniList( var C_Vob vobLight ) {};
-
  • vobLight - light vob

Vob_AddLightAniColor

Adds a color to the colour list

func void Vob_AddLightAniColor( var C_Vob vobLight, var C_Color col ) {};
-
  • vobLight - object to apply the colour to
  • col - colour to be applied

Vob_AddLightAniColorRGB

Adds a color to the colour list

1
-2
-3
-4
func void Vob_AddLightAniColorRGB(  var C_Vob vobLight,
-                                    var int r,
-                                    var int g,
-                                    var int b ) {};
-
  • vobLight - object to apply the colour to
  • r - red colour channel
  • g - green colour channel
  • b - blue colour channel

Vob_GetMobData

Returns the data of the oCMOB object

func C_Mob_Data Vob_GetMobData( var C_Vob mob ) {};
-
  • mob - oCMOB object
  • return - mob data

Vob_SetMobData

Sets the data of the oCMOB object

func void Vob_SetMobData( var C_Vob mob, var C_Mob_Data data ) {};
-
  • mob - oCMOB object
  • data - C_Mob_Data to be set

Vob_GetMobInterData

Returns the data of the oCMobInter object

func MobInter_Data Vob_GetMobInterData( var C_Vob mobInter ) {};
-
  • mobInter - oCMobInter object
  • return - MobInter_Data of the object

Vob_SetMobInterData

Sets the data of the oCMobInter object

func void Vob_SetMobInterData( var C_Vob mobInter, var C_MobInter_Data data ) {};
-
  • mobInter - oCMobInter object
  • data - MobInter_Data of the object

Vob_GetMobInterData

Returns the data of the oCMobLockable object

func C_MobLockable_Data Vob_GetMobInterData( var C_Vob mobLock ) {};
-
  • mobLock - oCMobLockable object
  • data - MobInter_Data of the object
  • return - C_MobLockable_Data of the object

Vob_SetMobInterData

Sets the data of the oCMobLockable object

func void Vob_SetMobInterData( var C_Vob mobLock, var C_MobLockable_Data data ) {};
-
  • mobLock - oCMobLockable object
  • data - C_MobLockable_Data of the object
\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/zparserextender/externals/wld/index.html b/pl/zengin/scripts/extenders/zparserextender/externals/wld/index.html deleted file mode 100644 index 012b055099..0000000000 --- a/pl/zengin/scripts/extenders/zparserextender/externals/wld/index.html +++ /dev/null @@ -1,61 +0,0 @@ - WLD functions - Gothic Modding Community

WLD - world manipulation functions

Functions related to the world.

Wld_ChangeLevel

Trigger level change.

func void Wld_ChangeLevel( var string world, var string waypoint ) {};
-
  • world - name of the world
  • waypoint - target waypoint

Wld_FindVob

Return the VOB instance based on its name.

func instance Wld_FindVob( var string vobname ) {};
-
  • vobname - name of the vob
  • return - zCVob pointer

Wld_PlayEffectVob

Play a visual effect at specified vob

1
-2
-3
-4
-5
-6
func void Wld_PlayEffectVob(    var string effect,
-                                var instance pvob,
-                                var int level,
-                                var int damage,
-                                var int damage_type,
-                                var int damage_speed ) {};
-
  • effect - effect name
  • pvob - zCVob to play the effect at
  • level - effect level
  • damage - damage amount
  • damage_type - damage type
  • damage_speed - damage interval

Wld_PlayEffectAt

Play a visual effect at specified world coordinates

1
-2
-3
-4
-5
-6
func void Wld_PlayEffectAt( var string effect,
-                            var instance coord,
-                            var int level,
-                            var int damage,
-                            var int damage_type,
-                            var int damage_speed ) {};
-
  • effect - effect name
  • coord - world coordinates (zVEC3) to play the effect at
  • level - effect level
  • damage - damage amount
  • damage_type - damage type
  • damage_speed - damage interval

Wld_ToggleRain

Turns on the rain

func void Wld_ToggleRain( var float weight, var float time ) {};
-
  • weight - the strength of the rain
  • time - rain duration

Wld_SetWeatherType

Sets the weather type. Types:

0 - snow 1 - rain

func void Wld_SetWeatherType( var int type ) {};
-
  • type - weather type

Wld_GetWeatherType

Returns the weather type. Types:

0 - snow 1 - rain

func int Wld_GetWeatherType() {};
-
  • return - weather type
\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/zparserextender/helperclasses/index.html b/pl/zengin/scripts/extenders/zparserextender/helperclasses/index.html deleted file mode 100644 index cd2de661e8..0000000000 --- a/pl/zengin/scripts/extenders/zparserextender/helperclasses/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/pl/zengin/scripts/extenders/zparserextender/hooks/index.html b/pl/zengin/scripts/extenders/zparserextender/hooks/index.html deleted file mode 100644 index f421172fef..0000000000 --- a/pl/zengin/scripts/extenders/zparserextender/hooks/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/pl/zengin/scripts/extenders/zparserextender/index.html b/pl/zengin/scripts/extenders/zparserextender/index.html deleted file mode 100644 index 8112bf6b93..0000000000 --- a/pl/zengin/scripts/extenders/zparserextender/index.html +++ /dev/null @@ -1,34 +0,0 @@ - zParserExtender - Gothic Modding Community

zParserExtender

zParserExtender extends ZenGin's parser and adds many useful features. It significantly extends the functionality of scripts with added functionality and new external functions. It also enhances script compilation, allowing to compile OU files directly with the game and allowing for runtime script injection. Since the Union version 1.0m zParserExtender is fully integrated in Union itself.

Note

This is mostly a translation of the original release post

Contacts
Author Gratt
GitHub zParserExtender
Forum zParserExtender
\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/zparserextender/injection/hooks/index.html b/pl/zengin/scripts/extenders/zparserextender/injection/hooks/index.html deleted file mode 100644 index c25e6ad4e8..0000000000 --- a/pl/zengin/scripts/extenders/zparserextender/injection/hooks/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/pl/zengin/scripts/extenders/zparserextender/injection/index.html b/pl/zengin/scripts/extenders/zparserextender/injection/index.html deleted file mode 100644 index 25bb9292b1..0000000000 --- a/pl/zengin/scripts/extenders/zparserextender/injection/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/pl/zengin/scripts/extenders/zparserextender/injection/meta/index.html b/pl/zengin/scripts/extenders/zparserextender/injection/meta/index.html deleted file mode 100644 index 9d44507911..0000000000 --- a/pl/zengin/scripts/extenders/zparserextender/injection/meta/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/pl/zengin/scripts/extenders/zparserextender/injection/other/index.html b/pl/zengin/scripts/extenders/zparserextender/injection/other/index.html deleted file mode 100644 index 13ad843a76..0000000000 --- a/pl/zengin/scripts/extenders/zparserextender/injection/other/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/pl/zengin/scripts/extenders/zparserextender/meta/index.html b/pl/zengin/scripts/extenders/zparserextender/meta/index.html deleted file mode 100644 index ae843c19be..0000000000 --- a/pl/zengin/scripts/extenders/zparserextender/meta/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/pl/zengin/scripts/extenders/zparserextender/namespaces/index.html b/pl/zengin/scripts/extenders/zparserextender/namespaces/index.html deleted file mode 100644 index 7ff03419e2..0000000000 --- a/pl/zengin/scripts/extenders/zparserextender/namespaces/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/pl/zengin/scripts/extenders/zparserextender/other/index.html b/pl/zengin/scripts/extenders/zparserextender/other/index.html deleted file mode 100644 index 3bb6b4a53a..0000000000 --- a/pl/zengin/scripts/extenders/zparserextender/other/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/pl/zengin/scripts/extenders/zparserextender/syntax_extensions/dialogues/index.html b/pl/zengin/scripts/extenders/zparserextender/syntax_extensions/dialogues/index.html deleted file mode 100644 index 6b8b17f3d4..0000000000 --- a/pl/zengin/scripts/extenders/zparserextender/syntax_extensions/dialogues/index.html +++ /dev/null @@ -1,53 +0,0 @@ - Dialogue constants - Gothic Modding Community

Dialogue constants

To simplify dialogues, you can define up to 2 auxiliary variables or constants. Values corresponding to the current C_Info instance will be dynamically written there.

DIA_CurrentInstance

var int DIA_CurrentInstance
-
Contains the ID of the current C_Info instance. Can greatly simplify code or make it more reusable. Should be defined in scripts.
Example usage
1
-2
-3
Info_ClearChoices(DIA_CurrentInstance);
-Info_AddChoice(DIA_CurrentInstance, /*text*/, /*func*/);
-Npc_KnowsInfo(hero, DIA_CurrentInstance); // In this case DIA_CurrentInstance contains the last C_Info instance??
-
Create a wrapper function based on this variable
1
-2
-3
-4
func int C_HeroKnowsCurrentInfo()
-{
-    return Npc_KnowsInfo(hero, DIA_CurrentInstance);
-};
-

DIA_CurrentName

var string DIA_CurrentName;
-
Contains the name of the current instance of C_Info. Can be useful for debugging purposes. Should be defined in scripts. Usage scenarios:
1
-2
-3
Hlp_PrintConsole(DIA_CurrentName);
-Hlp_PrintConsole(Str_Format("%s[%s]", DIA_CurrentName, self.name);
-Hlp_StrCmp(DIA_CurrentName, "DIA_DiegoOw_Teach");
-
\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/zparserextender/syntax_extensions/events/index.html b/pl/zengin/scripts/extenders/zparserextender/syntax_extensions/events/index.html deleted file mode 100644 index 73a252d000..0000000000 --- a/pl/zengin/scripts/extenders/zparserextender/syntax_extensions/events/index.html +++ /dev/null @@ -1,57 +0,0 @@ - Event functions - Gothic Modding Community

Event functions

Event functions are functions sharing the same name. It can be defined multiple times but only once per file. Such functions are useful for implementing callback type functions. Every time an event is called, all instances of the same name will be called. The event is func with a return type event. Events are defined globally, meaning they ignore namespace they are in. To call an event from a script, use the external function Hlp_DoEvent(var string funcName).

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
func void GiveXP()
-{
-    Hlp_DoEvent("OnGiveXP");
-};
-
-func event OnGiveXP()
-{
-    // TODO
-    // This function can be defined in many files to do different things
-    // more appropriate for that file's context and all of them will be
-    // called, when function GiveXP (above) is called.
-};
-

Plugin implements two of these event functions

  • func event GameInit() - called when entering the main menu on game start
  • func event GameLoop() - called every frame when a world is loaded

Define these in any file in your scripts, they will be automatically called

\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/zparserextender/syntax_extensions/extern/index.html b/pl/zengin/scripts/extenders/zparserextender/syntax_extensions/extern/index.html deleted file mode 100644 index 4c6ae03271..0000000000 --- a/pl/zengin/scripts/extenders/zparserextender/syntax_extensions/extern/index.html +++ /dev/null @@ -1,41 +0,0 @@ - Extern binding - Gothic Modding Community

Extern binding

The extern binding allows you to secure your code against overriding or undefined symbol. Keyword extern before declaration means that if object of the same name exists, source object should be used. If not, a new one will be created.

1
-2
-3
-4
extern instance PC_Hero(C_Npc) 
-{
-    // TODO
-};
-
\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/zparserextender/syntax_extensions/namespaces/index.html b/pl/zengin/scripts/extenders/zparserextender/syntax_extensions/namespaces/index.html deleted file mode 100644 index ff76a567c4..0000000000 --- a/pl/zengin/scripts/extenders/zparserextender/syntax_extensions/namespaces/index.html +++ /dev/null @@ -1,298 +0,0 @@ - Namespaces - Gothic Modding Community

Namespaces

zParserExtender also implements namespaces. Namespaces ensure that all symbols inside the namespace are unique.

Defining a namespace

To define a namespace the new keyword namespace is used.

1
-2
-3
-4
-5
namespace zTestNamespace
-{
-    var int var01;
-    func void func01() { };
-};
-
1
-2
-3
-4
-5
-6
-7
META
-{
-    Namespace = zTestNamespace;
-};
-
-var int var01;
-func void func01() { };
-

Namespace nesting

Namespaces can be nested for finer control. In case of injection, the namespace defined in META is applied to all code inside the script.

To go deeper into the namespaces you use the namespace operator :. This code shows function with the same name within three different namespaces. The call in GameInit is made from the global namespace.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
namespace zTestNamespace01
-{
-    func void func01() { };
-};
-
-namespace zTestNamespace02
-{
-    func void func01() { };
-};
-
-namespace zTestNamespace03
-{
-    namespace zTestNamespace04
-    {
-        func void func01() { };
-    };
-};
-
-func event GameInit()
-{
-    // In this case, the reference is from global namespace to zTestNamespace
-    zTestNamespace01:func01();
-    zTestNamespace02:func01();
-    zTestNamespace03:zTestNamespace04:func01();
-};
-

Namespace traversal

To go up a namespace tree you use the namespace operator : without specifying a namespace. Number of operators determines how many levels you go up.

Exiting nested namespaces
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
func void func01()
-{
-    Hlp_MessageBox("#1");
-};
-
-namespace zTestNamespace01
-{
-    func void func01()
-    {
-        Hlp_MessageBox("#2");
-    };
-
-    namespace zTestNamespace02
-    {
-        func void func01()
-        {
-            Hlp_MessageBox("#3");
-        };
-
-        namespace zTestNamespace03
-        {
-            func void func01()
-            {
-                Hlp_MessageBox("#4");
-            };
-
-            func event GameInit()
-            {
-                :::func01(); // Calls the function 3 levels up
-                ::func01();  // Calls the function 2 levels up
-                :func01();   // Calls the function 1 level up
-                func01();    // Calls the function from the current namespace
-            };
-        };
-    };
-};
-

Optional namespace specification

There are three cases where the namespace prefix is optional

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
namespace zTestNamespace01
-{
-    func void func01()
-    {
-        Hlp_MessageBox("#1");
-    };
-
-    func event GameInit()
-    {
-        // Function call from the current namespace
-        func01();
-    };
-};
-
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
func void func01()
-{
-    Hlp_MessageBox("#1");
-};
-
-namespace zTestNamespace01
-{
-    func void func01()
-    {
-        Hlp_MessageBox("#2");
-    };
-
-    namespace zTestNamespace02
-    {
-        func event GameInit()
-        {
-            // Function call from the global namespace
-            func01();
-        };
-    };
-};
-
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
META
-{
-    using = zTestNamespace01;
-};
-
-namespace zTestNamespace01
-{
-    func void func01()
-    {
-        Hlp_MessageBox("#1");
-    };
-};
-
-func event GameInit()
-{
-    // Calls the function with the namespace specified in the META block
-    func01();
-};
-

Global namespace and Daedalus hooking

Namespace can not only be defined to an existing symbol but also to define new ones. Next code example shows how to implement a hook to a global instance.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
namespace zTestNamespace01
-{
-    const string Var01 = "New instance name";
-
-    // Hooking the global instance
-    instance :ItAr_Pir_L_Addon(C_Item)
-    {
-        ItAr_Pir_L_Addon_Old();
-        name = Var01;
-    };
-};
-
To hook an object, both signature and namespace has to match. It is syntactically allowed to hook an instance from a different space. Specify explicitly to which namespace the object will belong. This means that to hook instance ItAr_Pir_L_Addon from the namespace zTestNamespace01 to a global namespace, you have to refer to the global namespace using the namespace operator :. Since the function will be defined globally (as every symbol in ZenGin), it will be a part of the zTestNamespace01 which means that all functions will be local to this namespace.
\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/zparserextender/syntax_extensions/testelse/index.html b/pl/zengin/scripts/extenders/zparserextender/syntax_extensions/testelse/index.html deleted file mode 100644 index 103b761c8a..0000000000 --- a/pl/zengin/scripts/extenders/zparserextender/syntax_extensions/testelse/index.html +++ /dev/null @@ -1,50 +0,0 @@ - Test-else binding - Gothic Modding Community

Test-else statements

The test-else bind statement can be used to define sections of code to be compiled. If the code is within the boundaries of the inactive test-else branch, it will not be compiled. This operator can take values as input that are converted to logical values. For example, if an object is passed as an argument, the parser will check for its existence. If it is an engine tag, it will return the result of matching the current engine with the tag:

Valid values:

  • instance name - PC_HERO, ItMi_Gold, ...
  • engine tag - G1, G1A, G2, G2A
  • Steam Overlay activity - Steam

The result can be combined from several arguments. Round brackets () can be used to specify priority and expressions support the logical negation operator !, logical AND && and OR ||.

The operator can be used anywhere in the script file. It is syntactically similar to if else statement, but curly braces {} can be omitted for single-line operations. For example:

SteamActivated constant is set only when Steam is active
test Steam var const SteamActivated = 1;
-
Example of a logical expression with an else branch
1
-2
-3
-4
-5
-6
-7
-8
test SteamActivated && G2A 
-{
-    // TODO
-}
-else 
-{
-    // TODO
-}
-
\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/zparserextender/syntax_extensions/while/index.html b/pl/zengin/scripts/extenders/zparserextender/syntax_extensions/while/index.html deleted file mode 100644 index 4d2c1ae518..0000000000 --- a/pl/zengin/scripts/extenders/zparserextender/syntax_extensions/while/index.html +++ /dev/null @@ -1,62 +0,0 @@ - Pętla while - Gothic Modding Community

Natywna pętla WHILE

Podobnie jak Ikarus zParserExtender implementuje pętlę while.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
var int value; value = 10;
-while(value > 0)
-{
-    if (value == 8)
-    {
-        continue;
-    };
-
-    if (value == 2)
-    {
-        break;
-    };
-};
-

Note

Aby aktywować while konieczne jest ustawienie NativeWhile w SystemPack.ini

1
-2
[ZPARSE_EXTENDER]
-NativeWhile = true
-

Skompilowana pętla while działa w silniku vanilla bez pluginu.

\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/zparserextender/testelse/index.html b/pl/zengin/scripts/extenders/zparserextender/testelse/index.html deleted file mode 100644 index 54c26cdb73..0000000000 --- a/pl/zengin/scripts/extenders/zparserextender/testelse/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/pl/zengin/scripts/extenders/zparserextender/while/index.html b/pl/zengin/scripts/extenders/zparserextender/while/index.html deleted file mode 100644 index 84cdf313b4..0000000000 --- a/pl/zengin/scripts/extenders/zparserextender/while/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/pl/zengin/scripts/externals/doc/index.html b/pl/zengin/scripts/externals/doc/index.html deleted file mode 100644 index 2f7a9be29f..0000000000 --- a/pl/zengin/scripts/externals/doc/index.html +++ /dev/null @@ -1,299 +0,0 @@ - Doc functions - Gothic Modding Community

Doc external functions

Doc functions are used to control the document manager. They allow you to fine tune the display of maps, letters and books.

Doc_Create

Creates a new instance of the document manager and returns its ID.

func int Doc_Create() {};
-

Return value
Returns the ID of the document manager instance.

Example

1
-2
var int nDocID; // Variable to store the id in
-nDocID = Doc_Create();
-

Doc_CreateMap

Creates a new instance of the document manager with the arrow showing players position on the map and returns its ID.

func int Doc_CreateMap() {};
-

Return value
Returns the ID of the document manager instance.

Example

1
-2
var int nDocID; // Variable to store the id in
-nDocID = Doc_CreateMap();
-

Doc_SetLevel

Set a world level to a map. This maps the texture of the document to the bounding box of the provided level.

func void Doc_SetLevel(var int docID, var string level) {};
-

Parameters

  • var int docID - document manager ID
  • var string level - name of the ZEN file

Example

1
-2
nDocID = Doc_CreateMap();
-Doc_SetLevel(nDocID, "WORLD.ZEN");
-

Doc_SetLevelCoords

Warning

This function is only available in Gothic 2

Sets the map coordinates. This is used to map smaller portions of the world map to the document map to correctly show players position on the map.

func void Doc_SetLevelCoords(var int docID, var int left, var int top, var int right, var int bottom) {};
-

Parameters

  • var int docID - document manager ID
  • var int left - left coordinate
  • var int top - top coordinate
  • var int right - right coordinate
  • var int bottom - bottom coordinate

Example

Doc_SetLevelCoords(nDocID, -28000, 50500, 95500, -42500);
-

Doc_SetFont

Sets a font to be used on a page in a document with docID. Can be called multiple times to display different lines with different fonts.

func void Doc_SetFont(var int docID, var int page, var string font) {};
-

Parameters

  • var int docID - document manager ID
  • var int page - page index, if set to -1, fonts will be applied to all pages
  • var string font - font to be used

Example

Doc_SetFont(nDocID, -1, "FONT_10_BOOK.TGA");
-

Doc_SetPages

Sets the number of pages numOfPages of the document.

func void Doc_SetPages(var int docID, var int numOfPages) {};
-

Parameters

  • var int docID - document manager ID
  • var int numOfPages - number of pages

Example

1
-2
nDocID = Doc_Create();
-Doc_SetPages(nDocID, 2);
-

Doc_SetPage

Set page to have texture as a background with scale.

func void Doc_SetPage(var int docID, var int page, var string texture, var int scale) {};
-

Parameters

  • var int docID - document manager ID
  • var int page - page index, if set to -1, settings are applied to all pages
  • var string texture - texture of the background
  • var int scale - scale of the texture, TRUE to scale the page, FALSE to not scale

Example

1
-2
Doc_SetPage(nDocID, 0, "Book_Mage_L.tga", FALSE);
-Doc_SetPage(nDocID, 1, "Book_Mage_R.tga", FALSE);
-

Doc_SetMargins

Sets text margins of the page

1
-2
-3
-4
-5
-6
-7
func void Doc_SetMargins(var int docID,
-                         var int page,
-                         var int left,
-                         var int top,
-                         var int right,
-                         var int bottom,
-                         var int pixels) {};
-

Parameters

  • var int docID - document manager ID
  • var int page - page index, if set to -1, settings are applied to all pages
  • var int left - left margin
  • var int top - top margin
  • var int right - right margin
  • var int bottom - bottom margin
  • var int pixels - TRUE to use pixels, FALSE to use virtual coordinates

Warning

After a thorough examination of this external function in the decompiler, it looks like the function works in pixels only regardless of this parameter.

Example

Doc_SetMargins(nDocID, 0, 275, 20, 30, 20, TRUE);
-

Doc_PrintLine

Prints a line of text (font is set using Doc_SetFont) onto the document with docID, onto the page. Does not split the text into multiple lines if they do not fit onto the page.

func void Doc_PrintLine(var int docID, var int page, var string text) {};
-

Parameters

  • var int docID - document manager ID
  • var int page - page index
  • var string text - text to be printed

Example

1
-2
Doc_PrintLine(nDocID, 0, ""); // insert empty line
-Doc_PrintLine(nDocID, 0, "The Book");
-

Doc_PrintLines

Prints a line of text (font is set using Doc_SetFont) onto the document with docID, onto the page. Splits the text into multiple lines if they do not fit onto the page.

func void Doc_PrintLines(var int docID, var int page, var string text) {};
-

Parameters

  • var int docID - document manager ID
  • var int page - page index
  • var string text - text to be printed

Example

1
-2
Doc_PrintLines(nDocID, 0, "The war had been decided. Varant had lost its seaports, vital to army supplies. King Rhobar had not lingered on the battle fields for a long time, but left his generals to deal with the few remaining enemy troops. Varant had only one large force left, commanded by Lukkor, the most capable warlord of the Varant army, who had more than once turned defeat into victory.");
-Doc_PrintLines(nDocID, 0, "But now his army was trapped. The situation was hopeless, even though his army greatly outnumbered the enemy. Lee, a war hero from Myrtana, had lured him into this trap. The heavy cavalry had been unable to fight on the thick, swamped ground of the narrow valley. Lee's soldiers had occupied the range of hills surrounding the swamp, and they had struck repeatedly, decimating the army. The desperate sallies his troops had launched had been cut short in pools of blood. He was beaten.");
-

Doc_Show

Display the document using the document manager ID

func void Doc_Show(var int docID) {};
-

Parameters

  • var int docID - document manager ID

Example

1
-2
-3
-4
-5
-6
var int nDocID; // Variable to store the id in
-nDocID = Doc_Create();
-
-// ... document configuration
-
-Doc_Show(nDocID);
-

Externals with docu comments

  1
-  2
-  3
-  4
-  5
-  6
-  7
-  8
-  9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
-100
-101
-102
-103
-104
/// Creates a new instance of the document manager and returns its ID.
-///
-/// @return Returns the ID of the document manager instance.
-func int Doc_Create() {};
-
-/// Create a new instance of the document manager with the arrow showing players position on the map and returns its ID.
-///
-/// @return Returns the ID of the document manager instance.
-func int Doc_CreateMap() {};
-
-/// Prints a line of `text` onto the document with `docID`, onto the `page`.
-/// Does not line break
-/// 
-/// @param docID document manager ID
-/// @param page page index
-/// @param text text to be printed
-func void Doc_PrintLine(var int docID, var int page, var string text) {};
-
-/// Prints a line of `text` onto the document with `docID`, onto the `page`. The `text` is automatically split into multiple lines
-/// 
-/// @param docID document manager ID
-/// @param page page index
-/// @param text text to be printed
-func void Doc_PrintLines(var int docID, var int page, var string text) {};
-
-/// Sets a `font` to be used on a `page` in a document with `docID`. Can be called multiple times to display different lines with different fonts.
-///
-/// @param docID document manager ID
-/// @param page page index
-/// @param font font to be used
-func void Doc_SetFont(var int docID, var int page, var string font) {};
-
-/// Sets the number of pages `numOfPages` of the document.
-///
-/// @param docID document manager ID
-/// @param numOfPages number of pages
-func void Doc_SetPages(var int docID, var int numOfPages) {};
-
-/// Set `page` to have `texture` as a background with `scale`. 
-///
-/// @param docID document manager ID
-/// @param page page index, if set to `-1`, settings are applied to all pages
-/// @param texture texture of the background
-/// @param scale scale of the texture, if set to 1, there will be no resizing
-func void Doc_SetPage(var int docID, var int page, var string texture, var int scale) {};
-
-/// Set a world level to a map.
-///
-/// @param docID document manager ID
-/// @param level name of the ZEN file
-func void Doc_SetLevel(var int docID, var string level) {};
-
-/// Sets the map coordinates. 
-/// 
-/// @param docID document manager ID
-/// @param left left
-/// @param top top
-/// @param right top
-/// @param bottom bottom
-func void Doc_SetLevelCoords(var int docID, var int left, var int top, var int right, var int bottom) {};
-
-/// Sets text margins of the page
-///
-/// @param docID document manager ID
-/// @param page page index, if set to `-1`, settings are applied to all pages
-/// @param left left margin
-/// @param top top margin
-/// @param right right margin
-/// @param bottom bottom margin
-/// @param pixels `TRUE` to use pixels, `FALSE` to use virtual coordinates
-func void Doc_SetMargins(var int docID,
-                         var int page,
-                         var int left,
-                         var int top,
-                         var int right,
-                         var int bottom,
-                         var int pixels) {};
-
-/// Display the document using the document manager ID
-///
-/// @param docID document manager ID
-func void Doc_Show(var int docID) {};
-
-
-
-/// deprecated
-func void Doc_Open (var string Texture) {};
-
-/// deprecated
-func void Doc_Font(var string Font) {};
-
-/// deprecated
-func void Doc_Print (var string Text) {};
-
-/// deprecated
-func void Doc_MapCoordinates(var string s0,
-                             var float r1,
-                             var float r2,
-                             var float r3,
-                             var float r4,
-                             var float r5,
-                             var float r6,
-                             var float r7,
-                             var float r8) {};
-
\ No newline at end of file diff --git a/pl/zengin/scripts/externals/index.html b/pl/zengin/scripts/externals/index.html deleted file mode 100644 index 0173bc962d..0000000000 --- a/pl/zengin/scripts/externals/index.html +++ /dev/null @@ -1,34 +0,0 @@ - Externals - Gothic Modding Community

Externals

External functions are Daedalus functions (defined in the engine itself), that are used to interface with the engine. Gothic 1 and Gothic 2 implements slightly different set of external functions.
There are some external functions, that were used in the course of Gothic's development, but are now obsolete/deprecated because the underlying systems implemented in the engine were either turned off, or broken all together.

\ No newline at end of file diff --git a/pl/zengin/scripts/externals/log/index.html b/pl/zengin/scripts/externals/log/index.html deleted file mode 100644 index 661964f8e4..0000000000 --- a/pl/zengin/scripts/externals/log/index.html +++ /dev/null @@ -1,87 +0,0 @@ - Log functions - Gothic Modding Community

Log external functions

Log externals are used to manipulate players log and to track quest progress.

Log_CreateTopic

Creates a new log topic with the name topicName under the section logSection

func void Log_CreateTopic(var string topicName, var int logSection) {};
-
Parameters
  • var string topicName
    Unique string used to identify and name the topic
  • var int logSection
    Indicates in which section to create the topic in.
    Takes constants LOG_MISSION, LOG_NOTE as values

Log_AddEntry

Adds an entry to a log topic with the name topicName under the section logSection

func void Log_AddEntry(var string topicName, var string entry) {};
-
Parameters
  • var string topicName
    Unique string used to identify and name the topic
  • var string entry
    Content of the new entry

Info

In the engine the Log_AddEntry() is wrapped in a B_LogEntry() function. This function also handles printing the "New Journal Entry" message to the screen and playing the sound effect.

1
-2
-3
-4
-5
-6
-7
-8
-9
func void B_LogEntry(var string topic, var string entry)
-{
-    PrintDebugNpc(PD_ZS_DETAIL, "B_LogEntry"); // Logging
-
-    Log_AddEntry(topic, entry);
-
-    PrintScreen(NAME_NewLogEntry, -1, _YPOS_MESSAGE_LOGENTRY, "font_old_10_white.tga", _TIME_MESSAGE_LOGENTRY);
-    Snd_Play("LogEntry");
-};
-

Log_SetTopicStatus

Changes the status of the topic with the name topicName

func void Log_SetTopicStatus(var string topicName, var int status) {};
-
Parameters
  • var string topicName
    Unique string used to identify and name the topic
  • var int status
    The status to be set.
    Takes constants LOG_RUNNING, LOG_SUCCESS, LOG_FAILED, LOG_OBSOLETE as values

zParserExtender

The log external function selection is missing functions to retrieve the status of a log entry. There are only functions to read the log status (as discussed on Inside Gothic). As a result of this the original scriptwriters had to define additional variable to track the log status in the scripts, even though the value is being already tracked by the engine. zParserExtender fixes this by introducing new log external functions.

Externals with docu comments

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
/// Creates a new log topic with the name `topicName` under the section `logSection`
-/// 
-/// @param topicName unique string used to identify and name the topic
-/// @param logSection [LOG_MISSION, LOG_NOTE] indicates in which section to create the topic in
-func void Log_CreateTopic(var string topicName, var int logSection) {};
-
-/// Creates a new log topic with the name `topicName` under the section `logSection`
-/// 
-/// @param topicName unique string used to identify and name the topic
-/// @param logSection [LOG_MISSION, LOG_NOTE] indicates in which section to create the topic in
-func void Log_AddEntry(var string topicName, var string entry) {};
-
-/// Changes the status of the topic with the name `topicName`
-///
-/// @param topicName unique string used to identify and name the topic
-/// @param status [LOG_RUNNING, LOG_SUCCESS, LOG_FAILED, LOG_OBSOLETE] the status to be set
-func void Log_SetTopicStatus(var string topicName, var int status) {};
-
\ No newline at end of file diff --git a/pl/zengin/scripts/externals/mdl/index.html b/pl/zengin/scripts/externals/mdl/index.html deleted file mode 100644 index a256586cd8..0000000000 --- a/pl/zengin/scripts/externals/mdl/index.html +++ /dev/null @@ -1,281 +0,0 @@ - MDL functions - Gothic Modding Community

MDL functions

Functions to tweak animation and other model related settings.

Mdl_ApplyOverlayMDS

Apply an animation overlay with overlay_name for the specified npc

func void Mdl_ApplyOverlayMDS(var c_npc npc, var string overlay_name) {};
-

Parameters

  • var c_npc npc
    NPC to apply the overlay to
  • var string overlay_name
    Name of the animation overlay

Mdl_ApplyOverlayMDSTimed

Apply an animation overlay with overlay_name for the specified npc for duration milliseconds

func void Mdl_ApplyOverlayMDSTimed(var c_npc npc, var string overlay_name, var float duration) {};
-

Parameters

  • var c_npc npc
    NPC to apply the overlay to
  • var string overlay_name
    Name of the animation overlay
  • var float duration
    Overlay duration in milliseconds

Mdl_RemoveOverlayMDS

Remove the animation overlay overlay_name from specified npc

func void Mdl_RemoveOverlayMDS(var c_npc npc, var string overlay_name) {};
-

Parameters

  • var c_npc npc
    NPC to remove the overlay from
  • var string overlay_name
    Name of the animation overlay

Mdl_ApplyRandomAni

Assign a random animation ani2 to random animation list of animation ani1

func void Mdl_ApplyRandomAni(var c_npc npc, var string ani1, var string ani2) {};
-

Parameters

  • var c_npc npc
    NPC owning the animation
  • var string ani1
    The animation to assign random animation to
  • var string ani2
    Animation to be assigned

Mdl_ApplyRandomAniFreq

Sets the random animation frequency for animation ani1

func void Mdl_ApplyRandomAniFreq(var c_npc npc, var string ani1, var float frequency) {};
-

Parameters

  • var c_npc npc
    NPC owning the animation
  • var string ani1
    The animation to set the random frequency
  • var float frequency
    Number of seconds between random animations
Example
1
-2
-3
-4
// Attach T_WOUNDED_TRY animation to the S_WOUNDED animation
-Mdl_ApplyRandomAni(self, "S_WOUNDED", "T_WOUNDED_TRY");
-// Make the random animation attached play every 8 seconds
-Mdl_ApplyRandomAniFreq(self, "S_WOUNDED", 8);
-

Mdl_SetModelFatness

Set the procedural model fatness

func void Mdl_SetModelFatness(var c_npc npc, var float fatness) {};
-

Parameters

  • var c_npc npc
    NPC to apply the fatness to
  • var float fatness
    Fatness value

Mdl_SetModelScale

Set model scale per axis

func void Mdl_SetModelScale(var c_npc npc, var float x, var float y, var float z) {};
-

Parameters

  • var c_npc npc
    NPC to apply the scale to
  • var float x
    Scale along the x-axis, 1.0 = 100%, 1.5 = 150%, 0.9 = 90%
  • var float y
    Scale along the y-axis, 1.0 = 100%, 1.5 = 150%, 0.9 = 90%
  • var float z
    Scale along the z-axis, 1.0 = 100%, 1.5 = 150%, 0.9 = 90%

Mdl_SetVisualBody

Sets up the visual of an NPC

1
-2
-3
-4
-5
-6
-7
-8
func void Mdl_SetVisualBody(var instance npc,
-                            var string body_mesh,
-                            var int body_tex,
-                            var int skin,
-                            var string head_mesh,
-                            var int head_tex,
-                            var int teeth_tex,
-                            var int armor_inst       ) {};
-

Parameters

  • var instance npc
    NPC to be affected
  • var string body_mesh
    Mesh to be used as the body e.g. HUN_BODY_NAKED0
  • var int body_tex
    Body texture assigned to this body mesh
  • var int skin
    Body texture variant
  • var string head_mesh
    Head mesh
  • var int head_tex
    Head texture
  • var int teeth_tex
    Teeth texture
  • var int armor_inst
    Armor (C_ITEM instance) to be equipped or -1 for no armor

Mdl_SetVisual

Set the animation set (also dictates models you can set using the Mdl_SetVisualBody)

func void Mdl_SetVisual(var instance npc, var string animation_set) {};
-

Parameters

  • var instance npc
    NPC to apply the animation set to
  • var string animation_set
    Name of the MDS file that contains the animation set

Mdl_StartFaceAni

Start a face animation

1
-2
-3
-4
func void Mdl_StartFaceAni(var c_npc npc,
-                           var string name,
-                           var float intensity,
-                           var float holdtime) {};
-

Parameters

  • var c_npc npc
    NPC to apply the animation to
  • var string name
    Animation name
  • var float intensity
    Intensity of the animation 0.0 to 1.0
  • var float holdtime
    How long should the animation be held for -2 will use the MMS defined value, '-1' will make the hold time infinite

Mdl_ApplyRandomFaceAni

Start a random face animation

1
-2
-3
-4
-5
-6
-7
func void Mdl_ApplyRandomFaceAni(var c_npc npc,
-                                 var string name,
-                                 var float timemin,
-                                 var float timeminvar,
-                                 var float timemax,
-                                 var float timemaxvar,
-                                 var float probmin) {};
-

Parameters

  • var c_npc npc
    NPC to apply the animation to
  • var string name
    Animation name
  • var float timemin
    Minimum time after which the ani should be started (in seconds)
  • var float timeminvar
    Minimum boundary variation (in seconds)
  • var float timemax
    Maximum time after which the ani should be started (in seconds)
  • var float timemaxvar
    Maximum boundary variation (in seconds)
  • var float probmin
    Probability (0.0 to 1.0) to choose the lower boundary time

Externals with docu comments

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
-37
-38
-39
-40
-41
-42
-43
-44
-45
-46
-47
-48
-49
-50
-51
-52
-53
-54
-55
-56
-57
-58
-59
-60
-61
-62
-63
-64
-65
-66
-67
-68
-69
-70
-71
-72
-73
-74
-75
-76
-77
-78
-79
-80
-81
-82
-83
-84
-85
-86
-87
-88
-89
-90
-91
-92
-93
-94
-95
-96
-97
-98
-99
/// Apply an animation overlay with `overlay_name` for the specified `npc`
-/// 
-/// @param npc NPC to apply the overlay to
-/// @param overlay_name name of the animation overlay
-func void Mdl_ApplyOverlayMDS(var c_npc npc, var string overlay_name) {};
-
-/// Apply an animation overlay with `overlay_name` for the specified `npc` for `duration` milliseconds
-///
-/// @param npc NPC to apply the overlay to
-/// @param overlay_name name of the animation overlay
-/// @param duration overlay duration in milliseconds
-func void Mdl_ApplyOverlayMDSTimed(var c_npc npc, var string overlay_name, var float duration) {};
-
-/// Remove the animation overlay `overlay_name` from specified `npc` 
-/// 
-/// @param npc NPC to remove the overlay from
-/// @param overlay_name name of the animation overlay
-func void Mdl_RemoveOverlayMDS(var c_npc npc, var string overlay_name) {};
-
-/// Assign a random animation `ani2` to random animation list of animation `ani1`
-///
-/// @param npc NPC owning the animation
-/// @param ani1 the animation to assign random animation to
-/// @param ani2 animation to be assigned
-func void Mdl_ApplyRandomAni(var c_npc npc, var string ani1, var string ani2) {};
-
-/// Sets the random animation frequency for animation `ani1`
-///
-/// @param npc NPC owning the animation
-/// @param ani1 the animation to set the random frequency
-/// @param frequency number of seconds between random animations
-func void Mdl_ApplyRandomAniFreq(var c_npc npc, var string ani1, var float frequency) {};
-
-/// Set the procedural model fatness
-///
-/// @param npc NPC to apply the fatness to 
-/// @param fatness fatness value
-func void Mdl_SetModelFatness(var c_npc npc, var float fatness) {};
-
-/// Set model scale per axis
-///
-/// @param npc NPC to apply the scale to 
-/// @param x scale along the x axis, 1.0 = 100%, 1.5 = 150%, 0.9 = 90% 
-/// @param y scale along the y axis, 1.0 = 100%, 1.5 = 150%, 0.9 = 90% 
-/// @param z scale along the z axis, 1.0 = 100%, 1.5 = 150%, 0.9 = 90% 
-func void Mdl_SetModelScale(var c_npc npc, var float x, var float y, var float z) {};
-
-/// Sets up the visual of an NPC
-///
-/// @param npc NPC to be affected
-/// @param body_mesh mesh to be used as the body e.g. `HUN_BODY_NAKED0`
-/// @param body_tex body texture assigned to this body mesh
-/// @param skin body texture variant
-/// @param head_mesh head mesh
-/// @param head_tex head texture
-/// @param teeth_tex teeth texture
-/// @param armor_inst armor (C_ITEM instance) to be equipped or `-1` for no armor 
-func void Mdl_SetVisualBody(var instance npc,
-                            var string body_mesh,
-                            var int body_tex,
-                            var int skin,
-                            var string head_mesh,
-                            var int head_tex,
-                            var int teeth_tex,
-                            var int armor_inst       ) {};
-
-/// Set the animation set (also dictates models you can set using the `Mdl_SetVisualBody`)
-///
-/// @param npc NPC to apply the animation set to 
-/// @param animation_set name of the MDS file that contains the animation set
-func void Mdl_SetVisual(var instance npc, var string animation_set) {};
-
-/// Start a face animation
-///
-/// @param npc NPC to apply the animation to 
-/// @param name animation name
-/// @param intensity intensity of the animation 0.0 to 1.0
-/// @param holdtime how long should the animation be held for `-2` will use the MMS defined value, '-1' will make the hold time infinite
-func void Mdl_StartFaceAni(var c_npc npc,
-                           var string name,
-                           var float intensity,
-                           var float holdtime) {};
-
-/// Start a random face animation
-///
-/// @param npc NPC to apply the animation to 
-/// @param name animation name
-/// @param timemin minimum time after which the ani should be started (in seconds)
-/// @param timeminvar minimum boundary variation (in seconds)
-/// @param timemax maximum time after which the ani should be started (in seconds)
-/// @param timemaxvar maximum boundary variation (in seconds)
-/// @param probmin probability (0.0 to 1.0) to choose the lower boundary time
-func void Mdl_ApplyRandomFaceAni(var c_npc npc,
-                                 var string name,
-                                 var float timemin,
-                                 var float timeminvar,
-                                 var float timemax,
-                                 var float timemaxvar,
-                                 var float probmin) {};
-
\ No newline at end of file diff --git a/pl/zengin/scripts/index.html b/pl/zengin/scripts/index.html deleted file mode 100644 index 614e3ff1a6..0000000000 --- a/pl/zengin/scripts/index.html +++ /dev/null @@ -1,34 +0,0 @@ - Skrypty - Gothic Modding Community

Skrypty

ZenGin używa własnego języka skryptowego o nazwie Daedalus. Jest podobny do języka programowania C, więc jeśli wiesz trochę o programowaniu w C, to rozpoczęcie pracy będzie dość łatwe.

Katalog Scripts to miejsce, w którym znajdują się skrypty. Znajdziesz tam pliki skryptów Daedalusa - o rozszerzeniach .d i .src, które zawierają listę wszystkich plików do skompilowania.

Skrypty Daedalusa można edytować w dowolnym edytorze tekstu. Aby uzyskać przydatne funkcjonalności typu podświetlanie składni, możesz użyć narzędzi stworzonych przez społeczność, takich jak

\ No newline at end of file diff --git a/pl/zengin/sound/index.html b/pl/zengin/sound/index.html deleted file mode 100644 index 9793517809..0000000000 --- a/pl/zengin/sound/index.html +++ /dev/null @@ -1,35 +0,0 @@ - Sound - Gothic Modding Community

Sound

ZenGin uses .wav files for playing Sound Effects and Dubbing.

Info

In-game soundtrack isn't saved in .wav sound files. See Music.

Properties

Original gothic sound files has following properties:

SFX

Sound effects (SFX) are sounds made by monsters, spells, weapons etc. Sound effects are defined in multiple places, in .mds files as part of the animation EventBlocks, or in the SFX Daedalus scripts. Sounds are located in the _work/Data/Sound/SFX directory.

Speech

Dubbing for dialogues is located into _work/Data/Sound/Speech folder. Every single AI_Output has its own sound file with name defined in the function itself.

For this dialogue line

AI_Output(self,hero,"Info_Diego_Gamestart_11_00"); //I'm Diego.
-
the engine will play Info_Diego_Gamestart_11_00.wav sound file (if it exists).
\ No newline at end of file diff --git a/pl/zengin/sound/tutorials/change_sfx/index.html b/pl/zengin/sound/tutorials/change_sfx/index.html deleted file mode 100644 index 202487de82..0000000000 --- a/pl/zengin/sound/tutorials/change_sfx/index.html +++ /dev/null @@ -1,34 +0,0 @@ - Changing Sound Effect - Gothic Modding Community

Changing Sound Effect

This is Gothic VDFS. It is a tool that allows you to pack and unpack files in .VDF and .MOD format.

Screenshot_1

Let us start with unpacking "Sound" file:

  1. In the "(Viewer)" tab, in the "Filename", go to your Gothic or Gothic II/Data folder and choose "Sound.VDF".
  2. Create a folder on your desktop or any other easily accessible place on your computer. Name it however you want.
  3. Go to "Root path" and choose the folder you just created.
  4. Press "Extract volume" if you want to unpack all sound files.

The chosen file should be unpacking right now.
image

Here are the files we just extracted:
image

It can oftentimes be tricky to find the sound you are looking for, but we will leave that for later. Let's just see how can we change a sound file in the game now.

  1. Get yourself any short sound file.
  2. In order for the sound to work in the game, it needs to be in mono .wav format. A lot of programs let you convert a file such as Audacity, so do just that;
  3. Rename your converted file into "INV_CHANGE.WAV" and replace it in SFX folder you just extracted;
  4. Go back to Gothic VDFS, go to (Builder) tab;
  5. In "Filename" you choose how do you want your file to be called and its location. I recommend creating separate folder and putting it there. You can also name the file however you want, as long as it has higher time stamp (more on that later) than original Sounds file. To create it as .VDF file, choose "All file" in the "Save file as" and call it "Sounds.VDF";
  6. In "Root path" go to and choose "_WORK" folder;
  7. In the field just below "Comment", add a * character and then click on the + next to it;
  8. Press "Build", and if you did everything right, the folder is being packed back into .VDF file;

That's how a successful process looks like:
image

Now get the file you just created, and put it in your Gothic/Data folder replacing the old one. The file we just replaced changes the sound in main menu and the inventory. If you can hear it, congratulations, you did it!

\ No newline at end of file diff --git a/pl/zengin/textures/index.html b/pl/zengin/textures/index.html deleted file mode 100644 index c96216b412..0000000000 --- a/pl/zengin/textures/index.html +++ /dev/null @@ -1,34 +0,0 @@ - Textures - Gothic Modding Community

Textures

Textures are pictures that get projected onto a 3D models and on a 2D user interface in the game. We will discuss how to work with textures in this section.

\ No newline at end of file diff --git a/pl/zengin/tools/daedalus_tools/daedalus_language_server/index.html b/pl/zengin/tools/daedalus_tools/daedalus_language_server/index.html deleted file mode 100644 index 69a875f035..0000000000 --- a/pl/zengin/tools/daedalus_tools/daedalus_language_server/index.html +++ /dev/null @@ -1,34 +0,0 @@ - Daedalus Language Server - Gothic Modding Community
\ No newline at end of file diff --git a/pl/zengin/tools/dls/index.html b/pl/zengin/tools/dls/index.html deleted file mode 100644 index f1ea3a7574..0000000000 --- a/pl/zengin/tools/dls/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/pl/zengin/tools/gothic_sourcer/index.html b/pl/zengin/tools/gothic_sourcer/index.html deleted file mode 100644 index 44d8f03ef9..0000000000 --- a/pl/zengin/tools/gothic_sourcer/index.html +++ /dev/null @@ -1,34 +0,0 @@ - Gothic Sourcer - Gothic Modding Community

Gothic Sourcer

Gothic Sourcer can be used to do a lot of things.

Todo

TODO

\ No newline at end of file diff --git a/pl/zengin/tools/gothic_vdfs/index.html b/pl/zengin/tools/gothic_vdfs/index.html deleted file mode 100644 index 9bbd7ec638..0000000000 --- a/pl/zengin/tools/gothic_vdfs/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/pl/zengin/tools/index.html b/pl/zengin/tools/index.html deleted file mode 100644 index 6203e3bea7..0000000000 --- a/pl/zengin/tools/index.html +++ /dev/null @@ -1,34 +0,0 @@ - Tools - Gothic Modding Community

Tools

The community has developed many tools to help with the creation of Gothic mods.

Note

This list is a work in progress.

Daedalus

  • Daedalus Language Server - a VS Code/VS Codium extension that adds IDE like functionality for Daedalus scripting language
  • Ikarus - A daedalus library for the game Gothic. Exploits the interpreter to allow arbitrary memory access and defines a lot of useful functions for interfacing with the engine.
  • LeGo - A daedalus library for the game Gothic. It contains various packages to support modders.
  • AFSP - Fawkes' & Auronen's script package for Gothic 1 and Gothic 2: Night of the Raven.
  • Ninja - Ninja introduces the possibility of true modular modifications for the video games Gothic and Gothic 2 Night of the Raven.

VDFS tools

  • GothicVDFS - NicoDE's viewer, extractor and builder for .vdf and .mod volumes
  • VDFS Tool - Gratt's Union VDFS viewer, extractor, builder, optimizer and ZIP compressor for .vdf and .mod volumes

World Editors

  • Spacer - the original world editor for ZenGin, ships with the MDK
  • Union Gothic World Editor - Saturas' world editor, supports new object classes created with Union
  • Gothic World Editor - World editor for vanilla worlds, works with G1, G2 and G2 NotR worlds
  • Spacer.NET - A modernised version of Spacer available as a Gothic Mod.
\ No newline at end of file diff --git a/pl/zengin/tools/vdfs_tool/index.html b/pl/zengin/tools/vdfs_tool/index.html deleted file mode 100644 index ff3e73cc59..0000000000 --- a/pl/zengin/tools/vdfs_tool/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/pl/zengin/tools/vdfs_tools/gothic_vdfs/index.html b/pl/zengin/tools/vdfs_tools/gothic_vdfs/index.html deleted file mode 100644 index b8803ce251..0000000000 --- a/pl/zengin/tools/vdfs_tools/gothic_vdfs/index.html +++ /dev/null @@ -1,34 +0,0 @@ - GothicVDFS - Gothic Modding Community

GothicVDFS

Gothic VDFS is still the most popular VDFS tool. It was created by NicoDE.

Download

You can download the tool from NicoDE's website - direct link.

Quick overview

\ No newline at end of file diff --git a/pl/zengin/tools/vdfs_tools/vdfs_tool/index.html b/pl/zengin/tools/vdfs_tools/vdfs_tool/index.html deleted file mode 100644 index 6ae1f2ebdd..0000000000 --- a/pl/zengin/tools/vdfs_tools/vdfs_tool/index.html +++ /dev/null @@ -1,34 +0,0 @@ - VDFS Tool - Gothic Modding Community

VDFS Tool

VDFS Tool is a new program that supports new features introduced to VDFS by the Union team. Like ZIP compression or drag and drop support.

Download

You can download the tool from the post on WoP.ru - VDFS Tool or using the Resource Manager

Quick overview

\ No newline at end of file diff --git a/pl/zengin/tools/zSpy/index.html b/pl/zengin/tools/zSpy/index.html deleted file mode 100644 index d812a93387..0000000000 --- a/pl/zengin/tools/zSpy/index.html +++ /dev/null @@ -1,49 +0,0 @@ - zSpy - Gothic Modding Community

zSpy

zSpy is a debugging tool that displays most of the operations performed by the engine during the Gothic or Spacer running.

Example image of running zSpy

zSpy

Warning

zSpy must be started before Gothic or the Spacer is started so that the program can find it. Sometimes in Gothic I this has to be done manually, in Gothic II This is done by the GothicStarter_mod.

In order to be able to follow the messages in zSpy, Gothic should be started in the window. The corresponding startup option can be found in GothicStarter (mod). Within Gothic, when Marvin mode is activated, you can switch between window and full-screen mode at any time with the F3 key.

Log Level

With the -zlog# command in GothicStarter, you can specify how many messages zSpy will output. # can be a number between -1 and 9. Used for:

  • -1 - Disable every message (expect fatal errors)

  • 0 - Shows only warnings, faults and fatal errors

  • 1 - 9 - Display more information. Every Information has their priority. If you select 1, the program displays only messages with priority =< 1, with 5 only priority =< 5, and with 9, almost everything that Gothic can produce.

For general debugging, recommended value is 5.

Output

The zSpy issues its reports in the following form:

1
-2
Time  Type  Priority  User   Message              ...      <filename,       #line>
-00:21 Info:  3        B:     GOTHIC: Exiting game ... .... <oGameManager.cpp,#617>
-

Time

Time elapsed since the start of Gothic.exe

Type

Type of message. The following message types are distinguished:

  • Fatal: - Critical error causing application to close.

  • Fault: - A simple bug that will not cause the application to stop, but display or performance issues may occur.

  • Warn: - A warning of possible consequences. An error that follows soon afterwards could have something to do with it.

  • Info: - General information about the progress of the program.

Priority

Priority level of the message. Messages with lower priority (higher number) can be disabled. See log level.

User

User ID - a letter defined by every engine developer to highlight its logs

  • D - Dieter
  • U - Ulf
  • B - Bert
  • C - Carsten
  • A - Andre
  • X - Kurt

Message

The most important part. A message that contains:

  • Symbol representing a program module. The names are mostly self-explanatory, so there is no need to type them all (MDL = 3D models, PAR = Parser etc.).

  • The message for the user.

Configuration

In zSpy, you can customize the font and its color depending on the type of message.

In addition, you can configure the logging options:

  • Filtering various messages (Info, Warn, Fault, Fatal).
  • Auto show/hide zSpy when starting/stopping Gothic.
  • Saving the log file to a separate file.

Console commands

List of console commands related with zSpy.

Note

The list is work in progress. Console commands needs a separate article or section.

zerr level

Sets a level of logging.

zerr level <#>
-

zerr searchspy

Links zSpy with Gothic. Useful when you run zSpy when the game is already running.

zerr searchspy
-

zerr authors

Sets a filter to display only messages of one author.

zerr authors <letter>
-
  • <letter> - One of the letters listed here.

zerr rem

Includes a remark into the log.

zerr rem
-
Looks like that:
1
-2
-3
-4
00:46 Info:  3 B:       OPT: Blood-Details: Value=2 .... <oGameManager.cpp,#1302>
-00:57 ---------------
-00:57 ---------------
-01:01 Info:  3 B:     GMAN: Leaving Menu-Section .... <oGameManager.cpp,#1537>
-

zerr status

Displays a current status of zSpy in the console.

zerr status
-
\ No newline at end of file diff --git a/pl/zengin/union/index.html b/pl/zengin/union/index.html deleted file mode 100644 index 65d1f4baeb..0000000000 --- a/pl/zengin/union/index.html +++ /dev/null @@ -1,34 +0,0 @@ - Union - Gothic Modding Community

Union

Union is a system to patch and extend Gothic's engine the ZenGin. It allows you to load .dll files - ZenGin extensions created using the Gothic/Union SDK and .patch files - files designed to patch the game's executable. The Union installer also contains the SystemPack a collection of bug fixes and engine edits that improve performance.

Plug-ins

Union plugins are shipped in the form of a .dll library. This library contains the compiled C++ code with the Union SDK and an embedded .patch file.

Union SDK & Gothic API

Union software development kit is a collection of tools and the Gothic API that allow you to create Union plugins and alter the engine's behavior.
Gothic API is a set of 4 interfaces (each for one different ZenGin version) that allow you to interface with the engine, access the engine objects, change their behavior and introduce new classes and functionality.

PATCH file format

The .patch file contains one or more small programs that are designed to change the engine code (game executable). This is usually done to fix bugs. Union plug-ins contain an embedded .patch file and this file usually contains changes to the binary necessary for the proper function of the plug-in.

\ No newline at end of file diff --git a/pl/zengin/union/plugins/zbassmusic/index.html b/pl/zengin/union/plugins/zbassmusic/index.html deleted file mode 100644 index b633f4114e..0000000000 --- a/pl/zengin/union/plugins/zbassmusic/index.html +++ /dev/null @@ -1,34 +0,0 @@ - zBassMusic - Gothic Modding Community

zBassMusic

zBassMusic is a modern music system for Gothic I and Gothic II NotR based on BASS Audio Library made by Silver Ore Team. It replaces the old DirectMusic system to let the modders create music for Gothic as regular audio files instead of DirectMusic format.

Info

For the plugin documentation, visit the github site of a project. The documentation is build into the code.

Contacts
Authors Silver Ore Team - tehe
GitHub zBassMusic
Discord Gothic Modding Community server

Features

  • Music playback with modern audio formats like WAV, MP3, OGG
  • Out-of-the-box support for existing C_MUSICTHEME instances
  • Scriptable interface to take full control of music scheduling
  • Loading music files from VDFS volumes (excluding .sgt)
  • Backwards compatibility with DirectMusic .sgt files
\ No newline at end of file diff --git a/pl/zengin/union/plugins/zgamepad/controls/index.html b/pl/zengin/union/plugins/zgamepad/controls/index.html deleted file mode 100644 index 77bb4e0bd4..0000000000 --- a/pl/zengin/union/plugins/zgamepad/controls/index.html +++ /dev/null @@ -1,140 +0,0 @@ - Controls customization - Gothic Modding Community

Gamepad controls

The zGamePad plugin comes with a default control scheme, but it is possible to create your own. The plugin will search for any file with the .gamepad.overlay extension placed in Gothic/System directory or in any of the loaded .mod and .vdf archives.

Control file syntax

Gamepad controls are set using the .gamepad configuration file. This file encodes the controls for different actions in the game and the hint string in multiple languages.

Warning

The .gamepad file must be encoded in Unicode or UTF-8 to accommodate the multilingual hint strings.

Regions

The format supports code blocks specified by the #region and #endregion keywords. These regions do not have any syntactical meaning, they only offer a convenient way to collapse sections of the code in editors with the syntax highlighting capabilities such as Notepad++

Regions
1
-2
-3
-4
-5
-6
-7
#region strings
-    // TODO
-#endregion
-
-#region fight scheme
-    // TODO
-#endregion
-

Comments

Comments are useful for quick information or just to disable some old code that might come in handy later. The .gamepad file syntax supports C++ line comments using two forward slashes //.

Warning

Comments can only be used at the start of any given line!

Comments
1
-2
// this is a comment
-KeyRecord // this is NOT a comment
-

Strings

Strings are used for interactive hints. They should be defined at the top of the file. To define a string, use the keyword String. Strings have the following format:

Multilang string syntax
1
-2
-3
-4
String [id]
-    [langTag] [text]
-    [langTag] [text]
-    [langTag] [text]
-

Example

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
String interact
-    Rus "Взаимодействовать"
-    Eng "Interact"
-    Pol "Interakcja"
-    Deu "Interagieren"
-
-String remove_weapon
-    Rus "Убрать оружие"
-    Eng "Remove weapon"
-    Pol "Chowanie broni"
-    Deu "Waffe entfernen"
-
The string name must be unique and is used to reference the string while defining hints. The language tag matches the language in SystemPack.ini. If the file does not contain the user's language, English will be taken by default. If there is no English, then the first one.

Control bindings

A binding is a description of an event that includes emulation object and conditions. Hints are part of the binding.
The general structure of the bind starts with the keyword KeyRecord and has the following format:

Control binding
1
-2
-3
-4
-5
-6
KeyRecord [modifier]
-    Id          [key name]
-    Combination [gamepad keys]
-    Emulation   [engine logical and absolute keys]
-    Condition   [engine logical, absolute keys or logical functions]
-    Help        [name of the hint string]
-
  • Id - unique identifier used by other users to override this control binding
  • [modifier] - can be empty or take the value of Toggled If the value is empty, the control binding will work as long as the player holds down the specified button or button combination.
    If the value is Toggled, the control binding will work only when the player toggles the button or button combination. (One press to start sneaking, another press to stop sneaking)
  • Combination - these are the gamepad buttons that the player must press or hold to activate the control binding.
  • Emulation - specify which buttons will be emulated. You can specify absolute buttons, or that are defined in the game settings (logical).
  • Condition - specify the condition under which the control binding can be activated. To invert condition, use the operator ! before the operand (!Cond_IsOverlayTop, !JOY_B)
  • Help - name of the text string with a hint which will be displayed when the Conditions are met.

  • [gamepad keys] - Gamepad key list

  • [engine logical keys] - Engine logical key list
  • [engine absolute keys] - Engine absolute key list
  • [logical functions] - Logical function list

Tip

All operators are optional! This means that if a binding should only show a hint, it doesn't have to contain Combination.

Example

Control binding examples
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
KeyRecord
-    Id          StopUsingPicklock
-    Combination JOY_B
-    Emulation   KEY_DOWN
-    Condition   Cond_InterfaceIsOpen, Cond_UsesPicklock, !JOY_B
-
-KeyRecord Toggled
-    Id          ReturnToHumanForm
-    Combination JOY_A
-    Emulation   KEY_RETURN
-    Condition   Cond_InTransformation
-    Help        end_transform
-
-KeyRecord
-    Id          QuickRingSelectSlot
-    Combination JOY_RSTICK_FULL
-    Condition   !Cond_InventoryIsOpen, Cond_IsOverlayTop
-    Help        focus_item
-

Controls override

If you want to change or remove bindings from another controls file, use the KeyDisable keyword.
Default controls file

Controls override syntax
KeyDisable [fileName].[Id]
-
Where fileName is the name of the controls file without extension and id is a key of the binding.

Example

Controls override example
1
-2
-3
-4
-5
-6
-7
-8
// remove key from the main controls file
-KeyDisable Controls.ArrowDown
-
-// create new key based on the same buttons
-KeyRecord Toggled
-    Id          ArrowDownNew
-    Combination JOY_DOWN
-    Emulation   GAME_DOWN
-
\ No newline at end of file diff --git a/pl/zengin/union/plugins/zgamepad/index.html b/pl/zengin/union/plugins/zgamepad/index.html deleted file mode 100644 index f4b18516e2..0000000000 --- a/pl/zengin/union/plugins/zgamepad/index.html +++ /dev/null @@ -1,34 +0,0 @@ - zGamePad - Gothic Modding Community

zGamePad

zGamePad plugin adds gamepad support for ZenGin games.

Important

Visit the excellent original GitHub wiki page.

Contacts
Author Gratt
GitHub zGamePad
Forum zGamePad

Gamepad support

  • All xinput compatible (including emulators)
  • Xbox controller family
  • Dualshock 4
  • Dualsense
  • Nintendo Switch Joy-Cons
  • Nintendo Switch Pro Controller

Features

  • Natural Movements
    Intuitiveness and smoothness of movement controls is the main goal of this plugin. Touch the world of Gothic with your hands.
  • Interactive hints
    Interactive hints will help you in mastering the controls. You can always customize their appearance or disable them.
  • Quick access
    The plugin has two quick access rings - **weapons and items. Use them to always have access to your items.
  • Automatic save naming
    Sit comfortably. You do not have to reach for your keyboard, because the plugin itself will give a name to your saves.
  • Saves rotation
    The best alternative to quicksaves for gamepad controls.
  • Vibration response
    Immerse yourself in the game even more. Vibration will allow you to feel your character and everything that happens in the world.
  • Target locking
    The plugin will always help you win. Keeping the enemy in focus will allow you to fight much more effectively.
  • Stuck protection
    Oops! If you get stuck, hold both analogue sticks for a few seconds and the character will reset.
\ No newline at end of file diff --git a/pl/zengin/union/plugins/zgamepad/keys_engine_absolute/index.html b/pl/zengin/union/plugins/zgamepad/keys_engine_absolute/index.html deleted file mode 100644 index b9c61ac6fb..0000000000 --- a/pl/zengin/union/plugins/zgamepad/keys_engine_absolute/index.html +++ /dev/null @@ -1,383 +0,0 @@ - Engine absolute keys - Gothic Modding Community

Engine absolute keys

Absolute keys are the physical keys on your keyboard.

  1
-  2
-  3
-  4
-  5
-  6
-  7
-  8
-  9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
-100
-101
-102
-103
-104
-105
-106
-107
-108
-109
-110
-111
-112
-113
-114
-115
-116
-117
-118
-119
-120
-121
-122
-123
-124
-125
-126
-127
-128
-129
-130
-131
-132
-133
-134
-135
-136
-137
-138
-139
-140
-141
-142
-143
-144
-145
-146
-147
-148
-149
-150
-151
-152
-153
-154
-155
-156
-157
-158
-159
-160
-161
-162
-163
-164
-165
-166
-167
-168
-169
-170
-171
-172
-173
-174
-175
MOUSE_DX
-MOUSE_DY
-MOUSE_UP
-MOUSE_DOWN
-MOUSE_LEFT
-MOUSE_RIGHT
-MOUSE_WHEELUP
-MOUSE_WHEELDOWN
-MOUSE_BUTTONLEFT
-MOUSE_BUTTONRIGHT
-MOUSE_BUTTONMID
-MOUSE_XBUTTON1
-MOUSE_XBUTTON2
-MOUSE_XBUTTON3
-MOUSE_XBUTTON4
-MOUSE_XBUTTON5
-KEY_ESCAPE
-KEY_1
-KEY_2
-KEY_3
-KEY_4
-KEY_5
-KEY_6
-KEY_7
-KEY_8
-KEY_9
-KEY_0
-KEY_MINUS
-KEY_EQUALS
-KEY_BACK
-KEY_TAB
-KEY_Q
-KEY_W
-KEY_E
-KEY_R
-KEY_T
-KEY_Y
-KEY_U
-KEY_I
-KEY_O
-KEY_P
-KEY_LBRACKET
-KEY_RBRACKET
-KEY_RETURN
-KEY_LCONTROL
-KEY_A
-KEY_S
-KEY_D
-KEY_F
-KEY_G
-KEY_H
-KEY_J
-KEY_K
-KEY_L
-KEY_SEMICOLON
-KEY_APOSTROPHE
-KEY_GRAVE
-KEY_LSHIFT
-KEY_BACKSLASH
-KEY_Z
-KEY_X
-KEY_C
-KEY_V
-KEY_B
-KEY_N
-KEY_M
-KEY_COMMA
-KEY_PERIOD
-KEY_SLASH
-KEY_RSHIFT
-KEY_MULTIPLY
-KEY_LMENU
-KEY_SPACE
-KEY_CAPITAL
-KEY_F1
-KEY_F2
-KEY_F3
-KEY_F4
-KEY_F5
-KEY_F6
-KEY_F7
-KEY_F8
-KEY_F9
-KEY_F10
-KEY_NUMLOCK
-KEY_SCROLL
-KEY_NUMPAD7
-KEY_NUMPAD8
-KEY_NUMPAD9
-KEY_SUBTRACT
-KEY_NUMPAD4
-KEY_NUMPAD5
-KEY_NUMPAD6
-KEY_ADD
-KEY_NUMPAD1
-KEY_NUMPAD2
-KEY_NUMPAD3
-KEY_NUMPAD0
-KEY_DECIMAL
-KEY_OEM_102
-KEY_F11
-KEY_F12
-KEY_F13
-KEY_F14
-KEY_F15
-KEY_KANA
-KEY_ABNT_C1
-KEY_CONVERT
-KEY_NOCONVERT
-KEY_YEN
-KEY_ABNT_C2
-KEY_NUMPADEQUALS
-KEY_PREVTRACK
-KEY_AT
-KEY_COLON
-KEY_UNDERLINE
-KEY_KANJI
-KEY_STOP
-KEY_AX
-KEY_UNLABELED
-KEY_NEXTTRACK
-KEY_NUMPADENTER
-KEY_RCONTROL
-KEY_MUTE
-KEY_CALCULATOR
-KEY_PLAYPAUSE
-KEY_MEDIASTOP
-KEY_VOLUMEDOWN
-KEY_VOLUMEUP
-KEY_WEBHOME
-KEY_NUMPADCOMMA
-KEY_DIVIDE
-KEY_SYSRQ
-KEY_RMENU
-KEY_PAUSE
-KEY_HOME
-KEY_UP
-KEY_PRIOR
-KEY_LEFT
-KEY_RIGHT
-KEY_END
-KEY_DOWN
-KEY_NEXT
-KEY_INSERT
-KEY_DELETE
-KEY_LWIN
-KEY_RWIN
-KEY_APPS
-KEY_POWER
-KEY_SLEEP
-KEY_WAKE
-KEY_WEBSEARCH
-KEY_WEBFAVORITES
-KEY_WEBREFRESH
-KEY_WEBSTOP
-KEY_WEBFORWARD
-KEY_WEBBACK
-KEY_MYCOMPUTER
-KEY_MAIL
-KEY_MEDIASELECT
-KEY_BACKSPACE
-KEY_NUMPADSTAR
-KEY_LALT
-KEY_CAPSLOCK
-KEY_NUMPADMINUS
-KEY_NUMPADPLUS
-KEY_NUMPADPERIOD
-KEY_NUMPADSLASH
-KEY_RALT
-KEY_UPARROW
-KEY_PGUP
-KEY_LEFTARROW
-KEY_RIGHTARROW
-KEY_DOWNARROW
-KEY_PGDN
-
\ No newline at end of file diff --git a/pl/zengin/union/plugins/zgamepad/keys_engine_logical/index.html b/pl/zengin/union/plugins/zgamepad/keys_engine_logical/index.html deleted file mode 100644 index ec29b54eeb..0000000000 --- a/pl/zengin/union/plugins/zgamepad/keys_engine_logical/index.html +++ /dev/null @@ -1,87 +0,0 @@ - Engine logical keys - Gothic Modding Community

Engine logical keys

Logical keys are the keys you set in keyboard settings in the game menu. These can fill multiple roles in different situations and the gamepad controls can be set to emulate these logical keys.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
GAME_LEFT
-GAME_RIGHT
-GAME_UP
-GAME_DOWN
-GAME_ACTION
-GAME_SLOW
-GAME_ACTION2
-GAME_WEAPON
-GAME_SMOVE
-GAME_SMOVE2
-GAME_SHIFT
-GAME_END
-GAME_INVENTORY
-GAME_LOOK
-GAME_SNEAK
-GAME_STRAFELEFT
-GAME_STRAFERIGHT
-GAME_SCREEN_STATUS
-GAME_SCREEN_LOG
-GAME_SCREEN_MAP
-GAME_LOOK_FP
-GAME_LOCK_TARGET
-GAME_PARADE
-GAME_ACTIONLEFT
-GAME_ACTIONRIGHT
-GAME_LAME_POTION
-GAME_LAME_HEAL
-
\ No newline at end of file diff --git a/pl/zengin/union/plugins/zgamepad/keys_gamepad/index.html b/pl/zengin/union/plugins/zgamepad/keys_gamepad/index.html deleted file mode 100644 index d02a8df5c0..0000000000 --- a/pl/zengin/union/plugins/zgamepad/keys_gamepad/index.html +++ /dev/null @@ -1,85 +0,0 @@ - Gamepad keys - Gothic Modding Community

Gamepad keys

In order to set gamepad keys, you have to know the key codes as they are listed below.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
JOY_UP
-JOY_DOWN
-JOY_LEFT
-JOY_RIGHT
-JOY_MENU
-JOY_VIEW
-JOY_LSTICK
-JOY_RSTICK
-JOY_LB
-JOY_RB
-JOY_A
-JOY_B
-JOY_X
-JOY_Y
-JOY_LSTICK_LOWUP
-JOY_LSTICK_UP
-JOY_LSTICK_DOWN
-JOY_LSTICK_LEFT
-JOY_LSTICK_RIGHT
-JOY_RT
-JOY_LT
-JOY_DPAD
-JOY_UPDOWN
-JOY_LEFTRIGHT
-JOY_LSTICK_FULL
-JOY_RSTICK_FULL
-
\ No newline at end of file diff --git a/pl/zengin/union/plugins/zgamepad/logical_functions/index.html b/pl/zengin/union/plugins/zgamepad/logical_functions/index.html deleted file mode 100644 index 0254327f9b..0000000000 --- a/pl/zengin/union/plugins/zgamepad/logical_functions/index.html +++ /dev/null @@ -1,89 +0,0 @@ - Logical functions - Gothic Modding Community

Logical function names

Conditions for when to show or allow the control binding to work are specified using these logic functions. They describe different useful states of the game or user interface, allowing the user to set when will a certain control work.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
Cond_FightMode        - player is in the fight mode
-Cond_FightModeMelee   - player is in the melee fight mode
-Cond_FightModeRange   - player is in the ranged fight mode
-Cond_FightModeMagic   - player is in the magical fight mode
-Cond_CanShoot         - player is in the aim mode and can shoot now
-Cond_CanSneaking      - player is sneaking now
-Cond_Diving           - player is diving now
-Cond_HasFocusVob      - player has a focus vob
-Cond_HasFocusNpc      - player has a focus npc
-Cond_OnChooseWeapon   - weapon selection is active
-Cond_InventoryIsOpen  - inventory is open
-Cond_InTransformation - player is transformed
-Cond_VideoIsOpen      - video is playing
-Cond_CanLockTarget    - player in the fight mode now and can lock the focus vob
-Cond_G1               - this engine is a Gothic 1 (or sequel)
-Cond_G2               - this engine is a Gothic 2 NoTR (or classic)
-Cond_IsDialogTop      - dialog window is open on the top
-Cond_IsDocumentTop    - document object is open on the top
-Cond_IsOverlayTop     - gamepad overlay object is open on the top
-Cond_IsMenuTop        - game menu is open on the top
-Cond_OnSpellBook      - magic selection ring is active
-Cond_IsPlayerTalking  - player is talking to someone
-Cond_InterfaceIsOpen  - open any interface element
-Cond_HasLeftContainer - the left container is open (chest, plunder, trader)
-Cond_UsesPicklock     - player is picking a lock now
-Cond_IsOnTrade        - player is trading
-Cond_IsOverlayTop     - gamepad overlay object is open on the top
-Cond_IsMenuTop        - game menu is open on the top
-
\ No newline at end of file diff --git a/pl/zengin/union/sdk/events/index.html b/pl/zengin/union/sdk/events/index.html deleted file mode 100644 index 9049e9c74f..0000000000 --- a/pl/zengin/union/sdk/events/index.html +++ /dev/null @@ -1,179 +0,0 @@ - Game Events - Gothic Modding Community

Game Events

Union defines several Game Events that are dispatched when a specific event occurs in-game. Handlers are defined in Plugin.cpp and we can use them to execute our code during specific moments of the application lifetime.

Events

Initialization

Game_Entry

Executes at the entry point of the Gothic executable. During this time the engine classes are not yet initialized, so using them may cause an access violation. The entry point be used to execute some logic before Gothic loads itself.

1
-2
-3
void Game_Entry() {
-
-}
-

Game_DefineExternals

Executes before the Daedalus parser starts loading scripts. It's meant to define custom external functions.

1
-2
-3
void Game_DefineExternals() {
-
-}
-

Game_Init

Executes right after DAT files are loaded and just before the main menu shows up.

1
-2
-3
void Game_Init() {
-
-}
-

Level Change

Game_LoadBegin

Executes when we initiate a level change by one of the possible actions. The default plugin template uses a common LoadBegin() function to handle all events but we also can write different logic for different cases.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
void LoadBegin() {
-
-}
-
-// When player clicks "New Game"
-void Game_LoadBegin_NewGame() {
-    LoadBegin();
-}
-
-// When player loads a saved game
-void Game_LoadBegin_SaveGame() {
-    LoadBegin();
-}
-
-// When player changes ZEN by a trigger
-void Game_LoadBegin_ChangeLevel() {
-    LoadBegin();
-}
-

Game_LoadEnd

Executes when the level loading finishes. The default plugin template uses a common LoadEnd() function to handle all events but we also can write different logic for different cases.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
void LoadEnd() {
-
-}
-
-// When player clicks "New Game"
-void Game_LoadEnd_NewGame() {
-    LoadEnd();
-}
-
-// When player loads a saved game
-void Game_LoadEnd_SaveGame() {
-    LoadEnd();
-}
-
-// When player changes ZEN by a trigger
-void Game_LoadEnd_ChangeLevel() {
-    LoadEnd();
-}
-

Game_LoadBegin_Trigger

Executes when the player enters a trigger that initiates ZEN change.

1
-2
-3
void Game_LoadBegin_Trigger() {
-
-}
-

Game_LoadEnd_Trigger

Executes after the player has entered a trigger that initiates ZEN change.

1
-2
-3
void Game_LoadEnd_Trigger() {
-
-}
-

Game_ApplyOptions

Executes after Game_LoadEnd, when we save the game, and also when we exit the game. It's meant to be used to apply options from INI files.

1
-2
-3
void Game_ApplyOptions() {
-
-}
-

Game Loop

Game_PreLoop

Executes at the start of every frame.

1
-2
-3
void Game_PreLoop() {
-
-}
-

Game_Loop

Executes at every frame.

1
-2
-3
void Game_Loop() {
-
-}
-

Game_PostLoop

Executes at the end of every frame.

1
-2
-3
void Game_PostLoop() {
-
-}
-

Game_MenuLoop

Executes at every frame when the game menu is active.

1
-2
-3
void Game_MenuLoop() {
-
-}
-

Game_SaveBegin

Executes when the player started saving a game.

1
-2
-3
void Game_SaveBegin() {
-
-}
-

Game_SaveEnd

Executes when the game save finishes.

1
-2
-3
void Game_SaveEnd() {
-
-}
-

Game_Pause

Executes when the player opens the in-game menu.

1
-2
-3
void Game_Pause() {
-
-}
-

Game_Unpause

Executes when the player leaves the in-game menu and also when the player loads a saved game.

1
-2
-3
void Game_Unpause() {
-
-}
-

Shutdown

Game_Exit

Executes when the player exits the game.

1
-2
-3
void Game_Exit() {
-
-}
-
\ No newline at end of file diff --git a/pl/zengin/union/sdk/externals/index.html b/pl/zengin/union/sdk/externals/index.html deleted file mode 100644 index 64dbbbddb5..0000000000 --- a/pl/zengin/union/sdk/externals/index.html +++ /dev/null @@ -1,117 +0,0 @@ - Externals - Gothic Modding Community

Externals

Externals are functions defined by the Gothic engine that can be called from scripts. Union SDK provides symbols for pointers to global zCParser instances that we can use to interact with the parser and to define a custom external function.

1
-2
-3
-4
-5
-6
-7
extern zCParser*    parser;
-extern zCParser*&   parserSoundFX;
-extern zCParser*&   parserParticleFX;
-extern zCParser*&   parserVisualFX;
-extern zCParser*&   parserCamera;
-extern zCParser*&   parserMenu;
-extern zCParser*&   parserMusic;
-

Creating custom external

To create an external we need to define a function handler and register it in the parser. Before we start, it's good to write down a Daedalus function signature so we can see the return and argument types that will be important later.

func string AddNumbers(var int FirstArgument, var int SecondArgument, var string ThirdArgument)  {}
-

Function handler

External function handler signature must:

  • return int or bool
  • use __cdecl calling convention (default in C++)
  • take no arguments

Inside the handler, we can use the global parser to pop function arguments and push the return value from/to the stack. It's important to pop the arguments in reverse order and to pop all of them even if we are not going to use them. Similarly, the return value must always be set if any and must never be set if the function returns void. If we don't follow the rules, the stack may get corrupted and lead to the Gothic crash.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
// __cdecl is optional because it's the default calling convention
-int __cdecl AddNumbers_External()
-{
-    // Declare arguments
-    int FirstArgument;
-    int SecondArgument;
-    zSTRING ThirdArgument;
-
-    // Pop arguments from the stack **IN REVERSE ORDER**
-    parser->GetParameter(ThirdArgument);
-    parser->GetParameter(SecondArgument);
-    parser->GetParameter(FirstArgument);
-
-    // Execute function logic
-    int result = FirstArgument + SecondArgument;
-    zSTRING output = ThirdArgument + zSTRING(result);
-
-    // Push return value
-    parser->SetReturn(output);
-
-    // Return value is ignored, so 0 or 1 is fine.
-    return 0;
-}
-

Register external

Externals should be registered in the parser during the Game_DefineExternals game event. We need to call parser->DefineExternal with variadic arguments:

  • external function name in Daedalus
  • reference to function handler
  • return type
  • ...argument types
  • zPAR_TYPE_VOID indicates the end of the argument types list
1
-2
-3
void Game_DefineExternals() {
-    parser->DefineExternal("AddNumbers", AddNumbers_External, zPAR_TYPE_STRING, zPAR_TYPE_INT, zPAR_TYPE_INT, zPAR_TYPE_STRING, zPAR_TYPE_VOID);
-}
-

Available types are defined by an enum:

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
enum {
-    zPAR_TYPE_VOID,
-    zPAR_TYPE_FLOAT,
-    zPAR_TYPE_INT,
-    zPAR_TYPE_STRING,
-    zPAR_TYPE_CLASS,
-    zPAR_TYPE_FUNC,
-    zPAR_TYPE_PROTOTYPE,
-    zPAR_TYPE_INSTANCE
-};
-
\ No newline at end of file diff --git a/pl/zengin/union/sdk/getting_started/index.html b/pl/zengin/union/sdk/getting_started/index.html deleted file mode 100644 index 08d3c4aafb..0000000000 --- a/pl/zengin/union/sdk/getting_started/index.html +++ /dev/null @@ -1,78 +0,0 @@ - Getting Started - Gothic Modding Community

Getting Started

This article provides a beginner-friendly tutorial for setting up and compiling a Union project. Instructions for installing Union SDK are located at Union SDK.

Creating Union plugin

Create a Visual Studio project

To create a Union plugin project inside Visual Studio we need to use File -> New -> Project. On the next screen, we select "Union Plugin 1.0m", and click Next. For the project configuration, we should choose:

Key Value
Project name eg. MyPlugin
Location Directory where to store the source code
Solution Create new solution
Solution name eg. MyPlugin

We will also check "Place solution and project in the same directory" because our plugin consists of only one project, so there is no need to complicate the file structure.

File Structure

Folder / File Description
Engine SDK/ In this folder, we have the Gothic Engine API in the form of header files. Most of the files between engines are very similar to each other but they can't be used interchangeably because each engine has slightly different API and addresses of functions.
Engine SDK/User API/ These are empty files that are included in the corresponding engine headers. There are meant for placing additional methods extending classes that can be used for example in Hooks.
Plugin/System/ DLL entry point generated by Union. We shouldn't modify anything here.
Plugin/Workspace/Interface/ These are header files containing headers and source files important in correct order and an Interface.cpp file that merges all the code into one file.
Plugin/Workspace/Plugin/ Finally, this is the source code of the plugin and especially Plugin.cpp where we can create code executed on Game Events.

Build Configuration

Each Union plugin may target one or many versions of the Gothic engine and to select the proper API, Union SDK defines several build configurations for every engine, configuration, and also multiplatform build options. Each Target/Configuration combination is named [ENGINE] [CONFIGURATION].

Configurations:

  • Debug: Unoptimized build with debug symbols for development.
  • MD Release: Optimized build for release versions. Runtime Library: Multi-threaded DLL (/MD)
  • MT Release: Optimized build for release versions. Runtime Library: Multi-threaded (/MT)

Engines:

  • G1: Gothic I
  • G1A: Gothic Sequel
  • G2: Gothic II
  • G2A: Gothic II NotR
  • MP x2: Multiplatform target for both Gothic I (G1) and Gothic II NotR (G2A)
  • MP x4: Multiplatform target for all engine versions (Gothic I, Gothic Sequel, Gothic II, Gothic II NotR)

For learning Union, it's suggested to select G2A Debug for Gothic II NotR or G1 Debug for Gothic I.

Project Configuration

The Union plugin is a regular C++ Visual Studio project so it's possible to configure the project, compiler, linker, and debugger as we wish by going into Project -> Properties. For a starter, we should go to the General tab and check if Platform Toolset is installed and selected. If not, we should select one that's available on our system. Union was created with v100 but it also supports the newest toolkits, so it's best to select a modern one.

In the General tab, we can also specify the Output Directory where the plugin DLL will be placed after the build. During development, we can set it to <GOTHIC_DIR>/System/Autorun where <GOTHIC_DIR> is the root folder of the Gothic installation with Union that we will use for testing. Each DLL file placed in System/Autorun is automatically loaded by Union runtime.

Another method is to put the DLL in the System directory and modify Gothic.ini to include

1
-2
-3
[PLUGIN]
-# Plugin file names without .dll 
-PluginList = MyPlugin 
-

Build the plugin

After the initial configuration, we are ready to code something and see if our configuration is working. Let's collect some information about Union and display it with a MessageBox when the game starts. To do so, we locate the Plugin.cpp file and put our logic in one of the Game Events handlers. The best for that is Game_Init() because it's executed right after the engine loads every DAT file but before anything else:

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
void Game_Init() {
-    const CPlugin* myPlugin = CPlugin::GetCurrentPlugin();
-
-    CStringA gothicVersion;
-    switch (Union.GetEngineVersion()) {
-        case Engine_G1:  gothicVersion = "Gothic I";
-        case Engine_G1A:  gothicVersion = "Gothic Sequel";
-        case Engine_G2:  gothicVersion = "Gothic II";
-        case Engine_G2A:  gothicVersion = "Gothic II NoTR";
-    }
-
-    CStringA message = "Plugin: " + myPlugin->GetName() + "\n";
-    message = message + "Union Version: " + Union.GetUnionVersion().ToString() + "\n";
-    message = message + "Gothic Version: " + gothicVersion;
-
-    Message::Info(message, "Hello World");
-}
-

Now we can Build (F7) the project to create the DLL. If we have set up Output Directory before, the plugin will deploy directly to the game. Otherwise, we can copy it manually from Bin to <GOTHIC_DIR>/System/Autorun/MyPlugin.dll. When we launch the game, a MessageBox should appear right before the main menu: Union SDK MessageBox

Couldn't build the plugin?

If you could not build the plugin or it crashed the game, you have to do some debugging and find the root cause of that. For compilation errors look at the Visual Studio Output tab and read the errors.

If they say something about missing toolset, make sure that you selected a Platform Toolset that's installed.

If the proper toolset is selected but doesn't work, make sure that you are configuring the same Configuration that is used for building.

If the plugin was built but the game crashed, you probably selected Configuration for the wrong platform. Gothic 2 Night of the Raven is G2A and doesn't work with G2 or G1A. If you are playing Gothic II Classic from Steam, please be advised that it still uses the Night of The Raven engine so the plugin must target G2A.

Debugging

Union plugins are regular DLLs with executable code hooked to Gothic.exe and running on it, so they can be debugged using the same techniques as any other software.

Visual Studio Debugger

Visual Studio Debugger lets us set breakpoints on any line of code to stop the execution when we reach it. It also gives us a lot of information about the program state at this point. To use the debugger we only need to attach it to the Gothic.exe progress and compile the plugin with Debug configuration.

Option #1: Open Project -> Properties and in the Debugging tab, set Command to the path of our Gothic.exe. Then we can run "Local Windows Debugger" in Visual Studio and it starts Gothic with a debugger attached automatically.

Option #2: Open Debug -> Attach to process... and filter process list by "Gothic". Run the game separately and when the process appears in Visual Studio, select it and attach to it.

Caveats:

  • If we attach to the process early, we may get an "Exception thrown at 0x7B11DB86 (Shw32.dll) in Gothic2.exe: 0xC0000005: Access violation writing location 0x00ABD000." right at the beginning. It's fine, just click Continue and Gothic will start properly.
  • If a breakpoint hits when our cursor is locked by Gothic, we may not be able to get the cursor back until execution continues. In this case, we can still use Alt+Tab to switch to Visual Studio and use F5 to continue or F10 to step over. Disabling mouse support in the config may also fix this problem.

Printing to some output is probably the simplest form of debugging and Union provides us with several choices.

Logging to zSPY

zSPY can be accessed using a global zerr object. zSPY uses a message filtering system based on the first letter of the message, so our logs should follow the standard format used by other parts of ZenGine. Otherwise, the message may not be visible.

zerr->Message("X:   MyPlugin: message to zSPY");
-

Logging to Union console

Union console needs to be enabled inside SystemPack.ini first:

1
-2
[CORE]
-ShowDebugWindow = true
-
Then we can use a global cmd object behaving like C++ std::cout to log into the Union console:
cmd << "message to Union console";
-

Logging to Visual Studio

Visual Studio can also receive logs from our plugin using:

OutputDebugString("message to Visual Studio");
-
This method works only when we have a debugger attached, so it's not recommended for general logging.
\ No newline at end of file diff --git a/pl/zengin/union/sdk/hooks/index.html b/pl/zengin/union/sdk/hooks/index.html deleted file mode 100644 index 60f5e26481..0000000000 --- a/pl/zengin/union/sdk/hooks/index.html +++ /dev/null @@ -1,202 +0,0 @@ - Hooks - Gothic Modding Community

Hooks

Union provides a hooks system that lets us intercept calls to the engine functions and methods with our custom interceptor. To hook a function or method we need to know its address which can be acquired either from Engine SDK/[Engine]/Names_[Engine].hpp or from the engine classes headers Engine SDK/[Engine]/Headers.

Intercepting functions

To declare a hook we can use CInvoke class or HOOK AS macros.

1
-2
-3
CInvoke<function_type> Ivk_HookName(orignal_function_address, our_interceptor_function, hook_flags);
-
-HOOK Ivk_HookName AS(orignal_function_address, our_interceptor_function, hook_flags);
-

Regular functions

Regular functions are the functions declared outside of classes.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
// 0x0042C450 int __cdecl Apply_Options_Video(void)
-
-// Forward declaration
-int Apply_Options_Video(); 
-
-// Hook declaration
-CInvoke<int(*)()> Ivk_Apply_Options_Video(0x0042C450, &Apply_Options_Video);
-// Equivalent:
-// HOOK Ivk_Apply_Options_Video AS(0x0042C450, &Apply_Options_Video);
-
-// Implementation of interceptor
-int Apply_Options_Video() {
-    Message::Info("Before original Apply_Options_Video()");
-
-    // Original function can be called using CInvoke pointer.
-    int result = Ivk_Apply_Options_Video();
-
-    Message::Info("After original Apply_Options_Video()");
-
-    return result;
-}
-

Member function

Member functions are the functions declared as non-static class members and they take a class instance pointer as an implicit first argument (__thiscall calling convention). We can hook them in two ways using either a regular function or declaring a new method in User API.

Option #1 - Regular function

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
// 0x006015D0 public: virtual int __fastcall zCVob::Render(struct zTRenderContext &)
-
-// Forward declaration
-int __fastcall zCVob_Render(zCVob* _this, zTRenderContext& context);
-
-// Hook declaration
-CInvoke<int(__fastcall *)(zCVob* _this, zTRenderContext& context)> Ivk_zCVob_Render(0x006015D0, &zCVob_Render);
-// Equivalent:
-// HOOK Ivk_zCVob_Render AS(0x006015D0, &zCVob_Render);
-
-// Implementation of interceptor as regular function
-// Notice the first argument that's a pointer to class instance (this)
-int __fastcall zCVob_Render(zCVob* _this, zTRenderContext& context) {
-    if(_this == player) {
-        screen->PrintCX(1000, "Rendering a player zCVob");
-    }
-
-    // Call original method
-    return Ivk_zCVob_Render(_this, context);
-}
-

Option #2 - User API

In Engine SDK/User API we can find a .inc file for the class we are hooking and define a new member method there. In this case, we are looking for zCVob.inc:

1
-2
-3
-4
-5
-6
// Supported with union (c) 2020 Union team
-
-// User API for zCVob
-// Add your methods here
-
-int RenderUnion(zTRenderContext& context);
-

Then we can declare the hook pointing to our member method:

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
// 0x006015D0 public: virtual int __fastcall zCVob::Render(struct zTRenderContext &)
-
-// Hook declaration
-CInvoke<int(__fastcall zCVob::*)(zTRenderContext& context)> Ivk_zCVob_Render(0x006015D0, &zCVob::RenderUnion);
-// Equivalent:
-// HOOK Ivk_zCVob_Render AS(0x006015D0, &zCVob::RenderUnion);
-
-// Implementation of interceptor  method
-int zCVob::RenderUnion(zTRenderContext& context) {
-    if(this == player) {
-        screen->PrintCX(1000, "Rendering a player zCVob");
-    }
-
-    // Call original method
-    return Ivk_zCVob_Render(this, context);
-}
-

Hook flags

In the third argument of CInvoke we can provide hook flags. The default value is IVK_AUTO.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
enum EInterMode
-{
-    // Hook will not intercept the function.
-    IVK_DISABLED  = 1 << 1,
-
-    // Normal hook. If other hook is already defined for the same address, an error pops up.
-    IVK_NORMAL    = 1 << 2,
-
-    // Hook will automatically create an interception tree to allow multiple hooks for the same address.
-    IVK_AUTO      = 1 << 3,
-
-    // Overrides any hook defined for the same address before.
-    IVK_REDEFINE  = 1 << 4,
-
-    // Makes it impossible to override or disable the hook.
-    // It should be used only in very specific cases.
-    IVK_PROTECTED = 1 << 5,
-
-    // Same as IVK_DISABLED
-    IVK_READONLY  = IVK_DISABLED
-};
-

Credits

Examples are taken from the Union lessons in Russian created by Gratt on worldofplayers.ru/threads/41490/

\ No newline at end of file diff --git a/pl/zengin/union/sdk/index.html b/pl/zengin/union/sdk/index.html deleted file mode 100644 index ad060ab324..0000000000 --- a/pl/zengin/union/sdk/index.html +++ /dev/null @@ -1,34 +0,0 @@ - Union SDK - Gothic Modding Community

Union SDK

Union SDK is a software development kit for making Union plugins that directly interact with Gothic engines. It contains a project template for Visual Studio IDE, a C++ library for hooking into a Gothic executable, and Gothic API with methods' addresses for the engines of Gothic I, Gothic II, Gothic II NotR, and also for the not released Gothic Sequel.

Working with Union SDK requires at least basic knowledge of C++ programming. Knowledge of the x86 (32-bit) architecture, dynamically linked libraries, and reverse engineering is also welcomed as we need to understand what the Gothic engine does under the hood to use it effectively.

Requirements

Union SDK requires Visual Studio IDE, NET Framework 4.7.2, and Visual C++ 2010 libraries. They are available on Microsoft websites:

Resource Manager

The official installation of Union SDK is provided through Resource Manager. After the installation, Visual Studio will have a new project template "Union Plugin 1.0" that creates a basic Union plugin project.

\ No newline at end of file diff --git a/pl/zengin/union/zgamepad/controls/index.html b/pl/zengin/union/zgamepad/controls/index.html deleted file mode 100644 index 670983c4e4..0000000000 --- a/pl/zengin/union/zgamepad/controls/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/pl/zengin/union/zgamepad/index.html b/pl/zengin/union/zgamepad/index.html deleted file mode 100644 index 54b84281d0..0000000000 --- a/pl/zengin/union/zgamepad/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/pl/zengin/union/zgamepad/keys_engine_absolute/index.html b/pl/zengin/union/zgamepad/keys_engine_absolute/index.html deleted file mode 100644 index 5c4ab76f03..0000000000 --- a/pl/zengin/union/zgamepad/keys_engine_absolute/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/pl/zengin/union/zgamepad/keys_engine_logical/index.html b/pl/zengin/union/zgamepad/keys_engine_logical/index.html deleted file mode 100644 index b45c94bcb0..0000000000 --- a/pl/zengin/union/zgamepad/keys_engine_logical/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/pl/zengin/union/zgamepad/keys_gamepad/index.html b/pl/zengin/union/zgamepad/keys_gamepad/index.html deleted file mode 100644 index 0fefcd91d8..0000000000 --- a/pl/zengin/union/zgamepad/keys_gamepad/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/pl/zengin/union/zgamepad/logical_functions/index.html b/pl/zengin/union/zgamepad/logical_functions/index.html deleted file mode 100644 index 613f2db2a3..0000000000 --- a/pl/zengin/union/zgamepad/logical_functions/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/pl/zengin/video/index.html b/pl/zengin/video/index.html deleted file mode 100644 index 1d37499df1..0000000000 --- a/pl/zengin/video/index.html +++ /dev/null @@ -1,34 +0,0 @@ - Video - Gothic Modding Community

Video

To get a video cutscene, intro or outro into the game, the video needs to be in a proper format - BINK video format .bik.

Editing the video

The video you recorded and want to use has to be edited. My go-to editor for this is kdenlive. It works very well, it is free and open source, and it supports BINK video as an input, which is great if you want to include subtitles in the video.

My version of kdenlive does not know how to export video straight to .bik so I just export my video to .mp4 and then convert it with RAD Video Tools.

RAD Video Tools

RAD Video Tools is a tool for converting other video formats to BINK .bik that Gothic can use.

Warning

Gothic 1 bink implementation has some problems as you have to set the audio compression to 104 and above in RAD tools to get video to work in Gothic 1.

NicoDE's comment:

Add 100 to the audio compression level when encoding videos, e.g. 104 for level 4 with old sound format (should be mentioned in the RAD Video Tools documentation) for G1 without updated Miles libraries.

Note

Newest Union (1.0m at the time of writing) has a new patch for BINK video playback. The issue with sound should be fixed.

\ No newline at end of file diff --git a/pl/zengin/worlds/Classes/zCVob/index.html b/pl/zengin/worlds/Classes/zCVob/index.html deleted file mode 100644 index e36a956083..0000000000 --- a/pl/zengin/worlds/Classes/zCVob/index.html +++ /dev/null @@ -1,34 +0,0 @@ - zCVob - Gothic Modding Community

zCVob

zCVob is a base class for all objects placed in a world.

Acknowledgment

Heavily inspired by the amazing documentation site Gothic library

Class members

zCVob properties in spacer

Properties of a zCVob class are split into two parts. The Internals are hardly ever needed to be edited manually, they are changeed by e.g. moving an object in Spacer. On the other hand the Vob properties can only be changed by the Objects context menu in Spacer.

Internals

Vob

zCVob properties in spacer2

Properties of a zCVob class are split into two parts. The Internals are hardly ever needed to be edited manually, they are changeed by e.g. moving an object in Spacer. On the other hand the Vob properties can only be changed by the Objects context menu in Spacer.

Internals

Vob

Class member overview

pack

No Information provided.

presetName

The name of the template that was used to create the item.

bbox3DWS

Volume of virtual object. Defined by two opposite diagonal points of the BoundingBox (1x, 1y, 1z, 2x, 2y, 2z). The volume is needed to calculate collisions and interactions with other game objects. For example, with dynamic objects, which include characters (class C_NPC), items (class C_ITEM ), etc.

Interaction processing begins when object volumes intersect. For example, when the player enters the world change trigger area, the engine loads another game level based on the parameters this trigger. All this happens when the main character's BoundingBox intersects with the trigger's BoundingBox.

The BoundingBox can only be changed using the Edit the Bbox button in Spcaer.

trafoOSToWSRot

Orientation relative to the coordinate center.

Note

This refers to the center of coordinates of the .3DS file of the game world on which the ZEN file is built.

trafoOSToWSPos

Coordinates of the position in space relative to the center of coordinates.

The coordinates are set automatically the first time an instance of the class is inserted into the game world. You can change them either directly by entering numerical values ​​in the corresponding fields of the parameter, by moving the vob in spacer.

vobName

An identifier of a zCVob shown in the editor and sometimes used in scripts. The name can be left blank.

For some object classes, entering a name is required: zCVobSpot , zCVobWaypoint , zCTrigger , etc.

Danger

Setting a name for every static and insignificant object can lead to an error when parsing the game world.

visual

The name of the file that will be responsible for the visual display of the object.

Different file formats are used for different object classes:

  • *.3DS - Static objects
  • *.PFX - Particle effects
  • *.TGA - Textures
  • *.MDS, *.ASC - Interactive objects
  • *.MMS - Animated objects

showVisual

This option is responsible for displaying the object.

Accepted values:

  • TRUE - Display.
  • FALSE - Do not display.

visualCamAlign

Option to align objects relative to the camera.

Accepted values:

  • NONE - Not used.
  • YAW - The object always faces the player.
  • FULL - The object is aligned relative to the world axes.

Note

For example, in order for the grass model to always face the character, you need to set this parameter to YAW.

visualAniMode

Wind simulation option. Used in conjunction with the visualAniModeStrength parameter.

Accepted values:

  • NONE - Not used.
  • WIND - Strong wind effect. Acceptable for herbs.
  • WIND2 - Light wind effect. Acceptable for trees.

Warning

This option is only available in Gothic 2 (Spacer2).

visualAniModeStrength

Wind power animation multiplier. Small values such as 0.001 are typically used. Used in conjunction with the visualAniMode parameter.

Warning

This option is only available in Gothic 2 (Spacer2).

vobFarClipZScale

Sets the loading range of the VOB object. Depends on the VOB drawing distance specified using the zCZoneVobFarPlane object.

The range of values is from 0.0 to 2.0.

With a value of 0.0, the object is not visible, but collisions are calculated. With a value of 2.0, the VOB drawing range is identical to the VOB drawing range of objects specified by the zCZoneVobFarPlane object.

Warning

This option is only available in Gothic 2 (Spacer2).

CdStatic

Determines if the VOB will collide with the static objects (world mesh and other VOBs with cdStatic on).

Accepted values:

  • TRUE - Collision handling for static objects is enabled.
  • FALSE - Collision handling for static objects is disabled.

Tip

A situation often arises when objects “refuse” to move beyond a certain point on the surface. This happens when cdStatic is set to TRUE, i.e. the object cannot cross the surface another static object. In this case, it is enough to disable the cdStatic parameter for the duration of the move, and turn it on again after the move.

CdDyn

Determines if the VOB will collide with dynamic objects (NPCs, items, etc.). This basically determines if the object has collision during gameplay.

Accepted values:

  • TRUE - Collision handling for dynamic objects is enabled.
  • FALSE - Collision handling for dynamic objects is disabled.

staticVob

Determines if the VOB is taken into consideration in static lighting calculations in Indoor spaces. Usually enabled in decorative Vobs, but some of the interactive ones have it disabled.

Accepted values:

  • TRUE - Calculate the shadow of the object.
  • FALSE - Do not calculate the shadow of the object.

Note

The shadow is calculated when compiling light in Low, Middle or High mode.

dynShadow

Determine if the object will cast a shadow when affected by dynamic light (e.g. torches).

Accepted values:

  • DS_NONE - No shadow.
  • DS_BLOB - Casts a circular shadow.

zbias

Option to remove texture flickering if a .TGA file is used as rendering.

Warning

This option is only available in Gothic 2 (Spacer2).

isAmbient

Sets the calculation of refracted lighting of objects.

Accepted values:

  • TRUE - Calculate the refraction of light.
  • FALSE - Do not calculate light refraction.

Warning

This option is only available in Gothic 2 (Spacer2).

\ No newline at end of file diff --git a/pl/zengin/worlds/index.html b/pl/zengin/worlds/index.html deleted file mode 100644 index 63afcfcfd2..0000000000 --- a/pl/zengin/worlds/index.html +++ /dev/null @@ -1,34 +0,0 @@ - Worlds - Gothic Modding Community

Worlds

Acknowledgment

This article is heavily inspired by various tutorials from the polish TheModders forums.

Worlds, saved as .ZEN files in ZenGin, are archives that contain the world mesh (model), BSP tree and the information of all objects in the world. These objects are called VOBs ("virtual objects"). ZEN files can be saved in two ways; compiled and uncompiled. The compiled version is a full-fledged level with a terrain model. Uncompiled ZENs only save the VOB tree and are meant for specific use-cases.

Spacer is used to create these .ZEN files. There are also other world editors. The way of doing things can vary between these editors, so the specifics will be discussed in separate articles for those tools; at the same time, a lot of knowledge carries over between them. Also have in mind that Spacer is the least comfortable of the editors.

World contents

The content of worlds in Gothic can be roughly separated in the following way:

  • Base level mesh: terrain and buildings, sometimes also trees
  • VOBs: all interactive objects, items, foliage, small rocks, huts, furniture, ramps etc.

Asides from those elements, there are also many invisible VOBs, such as:

  • Waypoints - used for NPC navigation
  • Freepoints (zCVobSpot) - used mainly for NPC routines and roaming behavior for monsters
  • Startpoints - used only to spawn the player when starting a new game. Teleporting between levels is handled with scripts and uses freepoints to determine where the player will appear.
  • Sound emitters
  • Music zones
  • oCZoneMusic - music which plays inside the bounding box of this zone
  • oCZoneMusicDefault - default music which plays whenever the player is not inside some oCZoneMusic
  • Fog zones (zCZoneZFog) - areas which add fog, e.g. like in swamp areas where the sky is not visible. The setting to fade out the sky is optional though.
  • PFX - particle effects (fire, smoke, fireflies, falling leaves etc.)

Note

This list isn't exhaustive.

Creating a ZEN file

Before VOBs can be added to a world model, the world needs to be compiled. After importing a 3ds model, the world can be compiled as an outdoor or indoor world and saved as a ZEN.

The submeshes used in ZEN files have triangle count limits (it is also advisable to keep triangle count for each submesh under 50k for performance reasons). To get around this limitation and to parallelize work on various areas, it is possible to join multiple ZEN files together, which is done with special macros.

If you take a look at the original maps for Gothic 2, you can notice that they are in folders, where there's e.g. a file called NEWWORLD.ZEN and multiple .ZEN files with "part" in their name. The latter are the sub-zens used to create the full level.

However, a possibly more comfortable workflow is to have a single world mesh which is internally separated into multiple submeshes. This way triangle count limits won't be exceeded and the world won't need compiling from parts. As a trade-off, it is likely that it won't be possible for multiple people to work on the ZEN world at the same time.

Lighting

There are two light types in the game:

  • Static lights, which are baked onto the level. They can cast shadows (these only take static VOBs into consideration) and don't leak through walls. These have to be recompiled after making changes, but this process should only take moments. Static lights have the downside of only working in indoor worlds and in rooms which are closed with portals.
  • Dynamic lights are calculated during runtime, which allows them to move and change properties (their color, for example), but has a performance cost. Additionally, they don't look the best and will often leak through walls.

It is generally advised to use static lights whenever possible.

Portals

Portals are special parts of outdoor world meshes which separate interiors from exteriors. This allows the level to have dark areas: otherwise interiors are lit the same way as any outside area. Additionally, portals help with performance (interiors aren't rendered unless the player is nearby). Creation of portals has many caveats and will be discussed in a separate article. Portals are also related to NPC behavior (e.g. setting ownership of a room).

Optimisation

The game uses occlusion culling, which means that if an object is covered by another object, it is not rendered and saves performance. This means that the performance in a level can be boosted by a lot by creating city walls and mountains and valleys which separate areas.

Occlusion culling isn't a perfect process, so there's also the option of adding GHOSTOCCLUDERs, which are invisible walls which stop areas behind them from rendering. They are a part of the world mesh and are created by assigning a material called GHOSTOCCLUDER to chosen faces. The color of the material is traditionally purplish-blue or pink, but the material itself is not rendered in-game, so this is only to make them stand apart from the rest of the level during modelling. To get more technical, these occluder walls are used to help the BSP algorithm which runs during world compilation.

As mentioned before, another ways of optimisation are portals and limiting the number of dynamic lights. It is also not advisable to make many VOBs be affected by wind.

\ No newline at end of file diff --git a/pl/zengin/worlds/spacer/index.html b/pl/zengin/worlds/spacer/index.html deleted file mode 100644 index bbdef06b47..0000000000 --- a/pl/zengin/worlds/spacer/index.html +++ /dev/null @@ -1,45 +0,0 @@ - Spacer - Gothic Modding Community

Spacer

Spacer is the original world editor used to create maps in Gothic and it's installed by the MDK installer.

A good .ZEN file to start experimenting with Spacer is Toten Insel. It's a simple level which should load without issues for everyone. The map contains a custom texture, but it can be safely ignored.

Introduction

Upon launching Spacer, multiple windows will appear. They are:

  • The main viewport (black with text on launch)
  • The vobtree - allows to browse and select the objects already placed in a level
  • The object window - it has 3 tabs: Create, Modify and "...".
  • Toolbars - there's two of them and each button has a hover hint.
  • The help window - sometimes when clicking on something, this window will show a description. It's usually empty though.
  • The objectpages window - allows access to specific VOB settings. The contents of this window be changed with buttons on the horizontal toolbar.

Other windows dedicated to specific functionalities can also be opened or toggled (Window tab in the viewport or the horizontal toolbar).

When importing a mesh instead of a .ZEN file, some things will change. In this mode, objectpages has material data, one of the toolbars changes completely and the vobtree window changes into a texture browser.

Configuration

Before doing anything else, you will probably want to change a few settings first. Select Settings: View in the Settings tab in the main viewport to increase the viewport resolution. After doing that, press Align Toolwindows at Screen or Align Toolwindows at Spacer in the Window tab to clean up the window placement. You might still need to move some of the tool windows around after this, as they can overlap.

The most comfortable option we found was to set the resolution to something slightly smaller than the screen resolution (e.g. 1600:900 on a 1920:1080 screen) and then aligning the tool windows to screen.

To help with the control sensitivity issues, change the camera movement speed in the Settings: General.

Viewport controls

The camera has multiple modes of operation. Some of the controls may sound confusing, but will make sense once you try them.

Default selection mode

Arrows move the camera back and forward and rotate it sideways. A moves the camera up and Y lowers it.

PageUp and PageDown rotate the camera up and down. End resets this rotation.

Selecting VOBs is done by simply pointing at them with the mouse and clicking.

First-person selection mode

Toggled by the F3 button.

In this mode, you can point the camera with your mouse, and selection is done by pointing the green reticle at a VOB and clicking LMB. Arrows now move the camera parallel to itself (including sideways).

PageUp and PageDown still rotate the camera up and down, but it's better not to use them because it affects how the arrow movement behaves. End resets this rotation.

Default VOB movement mode

When a VOB is selected, press M to enter and exit this mode.

The arrows now move the VOB horizontally. Moving it up and down is done with A and Y.

The keys above the arrows now rotate the VOB:

  • Axis 1: Delete and PageDown
  • Axis 2: Insert and PageUp
  • Axis 3: Home and End

First-person VOB movement mode

When a VOB is selected, press T to enter and exit this mode.

The controls are the same as the default selection mode, but the camera is now placed at the selected VOB and it moves with the camera.

One caveat is that the controls are in the local space of the object. What this basically means is that if you rotated the object in any other way than horizontally, the movement and rotation will now be skewed.

Mixed VOB movement mode

When a VOB is selected, press C to enter and exit this mode. The VOB is now controlled like in the first-person movement mode, but the camera is not placed at the VOB: in other words, the camera remains in the same place.

General

Holding down Shift speeds up the camera in all of the modes. The numpad can be used for rotating instead of the buttons above the arrows. Both movement modes can be used from either of the selection modes. Movement modes can be selected from the vertical toolbar. This toolbar also has a "toggle camera position" button; this switches between two camera placements, which can be controlled independently.

The objects location can also be entered manually through the object window: open the Internals folder and select trafoOSToWSPos to input them at the bottom of the window. Don't forget to press "Apply". Unfortunately the rotation setting uses an odd format and can't be set manually.

Basic usage

This section covers some of the basic things done in the editor.

Inserting a VOB

  • In the Create tab in the Objects window, select the VOB type. Choose zcVob to add a simple decorative model.
  • Right click anywhere on the viewport
  • Select the insert option (Insert [zcVob] in this case)
  • A VOB without a mesh will be created in the middle of the screen. Try to not deselect it, but if you do, it can be found in the vobtree under the appropriate folder (zcVob in this case); it can be identified by a green dot.
  • In the Modify tab in the Object window, select "visual". Insert the model name in the text form at the bottom of the window. You can use pc_lob_sleeper3.3ds for now; this mesh should be present in both Gothic 1 and 2.
  • If you unpacked the meshes while installing the MDK or with GothicVDFS, you can also browse to the file using the file button next to the text form.
  • Make sure to click the Apply button. Do this after making any changes in the Object window or they will be lost.

Tip

You can use the VOB Bilder tool to comfortably browse model images and names. An online version is currently available here. The UI on the website is in Polish but it's simple enough to not matter.

  • To make the VOB have collision in-game, double click on cdDyn ("collision detection dynamic") to set it to true. Sometimes this is unadvised, e.g. with bushes or grass.

Tip

When placing pickable items, you can press the "apply physics on selected VOB" button in the vertical toolbar to make the item drop on the ground. It can save you a lot of work with placing those items. This won't work with a plain cVob though.

Common VOB settings

VOB settings vary depending on what the VOB type is. They all have common parameters of the base VOB class though. The full description of a zCVob class can be found here.

Issues

Spacer 2 received the last update in 2003 and is a very buggy tool. Here are some known issues.

Framerate dependence

The speed of camera in Spacer depends on the framerate. Depending on the angle of the camera and the level, Spacer can have huge framerate, which will make the camera move too quick.

You can try to limit the framerate of Spacer with external tools, but your mileage may vary. Such tools often only limit rendering using fake Vsync, but the underlying logic of the program can still run too fast.

Using the grid snap function can help when the framerate is high, but again: your mileage may vary.

Random freezes and crashes

Spacer will freeze or crash quite often at seemingly random moments. It is extremely important to save often and back up your work.

One of the common ways the editor can freeze is when rotating the camera vertically when the framerate is very high. In that case, changing the camera mode to F3 and back can sometimes help.

Copying VOBs

When copy-pasting a VOB in Spacer (right click menu), the new VOB might be created as a child of the original one and moving one of them will move both. This doesn't seem to be consistent, but it's worth checking before you accidentally ruin the careful placement of the original VOB.

Troubleshooting

You can have issues with loading a ZEN or a world model for a multitude of reasons. Here is some of the known ones.

  • Some terrain models aren't set up or exported properly.
  • Maps which use custom assets will cause issues or won't even load unless these assets are included in appropriate directories. The severity of this is different depending on the asset type. For example, textures will be replaced with a placeholder, but animations will cause crashes.

Note

This section is not exhaustive.

Creating ZENs

Presented here are the ways of working with new terrain models.

Compiling a world mesh

To create a completely new ZEN, you will first need a level mesh. These can be made from scratch or downloaded, but be aware that meshes, which aren't properly prepared won't compile correctly (you won't be able to move in the viewport). As with any other mesh in Gothic, it has to be in the 3ds format. It is recommended to place the mesh file somewhere in the _work/Data/Meshes (can be your own subfolder).

You can find free terrain models here if you want to practice this. Note that not all of them might compile properly; this one should be fine though.

First, load the mesh from the File tab of the viewport. To compile the mesh, press Compile World in the World tab. From here, multiple options are available:

  • Indoor/Outdoor: determines if the world will have a sky and the way that lighting behaves.
  • Detect leaks: might be related to checking if indoor ("underground") worlds have holes in them. In some games such holes can cause performance issues, perhaps it's the same here. Doesn't hurt to enable it.
  • Quick compile: self-explanatory, but the exact effects of this are unknown.
  • Polycheck: presumably checks if the model doesn't exceed triangle limits.
  • Editormode:

    • On: Spacer will load the mesh in editor mode, which allows you to change materials assigned to triangles and other mesh operations. It is more comfortable to do these things in an external 3D editor, but sometimes using this is recommended, e.g. for setting up portals. You can save the model as a .3ds in this mode.

    • Off: Spacer will create a ZEN where you can normally place VOBs. You can now save the world as a compiled ZEN and add VOBs to it.

Compiling a world from multiple meshes

First and foremost, the models used for this must be properly positioned and separated in your 3D editor of choice. Then each section must be exported as separate .3ds files. After that, compile each model and save it as a compiled ZEN. Place them in their own folder. You can place VOBs in those ZEN files, the VOB trees will be merged too.

Now, to join these zens together, you will need to define a macro in Tools>Macros. These are pretty much identical except for the ZEN list; for example, the Mining Colony ZEN in Gothic 2 (OLDWORLD.ZEN) is comprised of two models, and the macro looks like this:

1
-2
-3
-4
-5
-6
reset
-set error 3
-Load world oldworld\SURFACE.ZEN
-Load world oldworld\OLDCAMP.ZEN
-compile world outdoor
-compile light high
-

Then you double-click the macro name to run it and wait. The macro contains the reset directive, but it's worth doing it on a freshly opened Spacer instance just to be safe.

Keep in mind that compiling a world from multiple ZENs is meant as a final step in level production. This is because doing it will cause issues with culling and stop interiors from rendering (and thus stop you from editing it). Instead, the part ZENs are filled with VOBs separately and the world is compiled as a final step before testing the map.

Updating world meshes in a compiled ZEN

Ideally, updating the world mesh would be avoided, but it's an inevitable need when iterating a map design. Doing this in the original Spacer might not be impossible, but it is generally avoided and Spacer.NET or other editors are used for this instead.

\ No newline at end of file diff --git a/preferences/index.html b/preferences/index.html index 01d158fce9..11cedb8c02 100644 --- a/preferences/index.html +++ b/preferences/index.html @@ -1,4 +1,4 @@ - Preferences - Gothic Modding Community

Preferences

This page allows to set various preferences for reading the docs:

Color

You can change the feel of the site with a color change.

Reset colors

Font

You can change the font to another preset.

Custom CSS

You can add custom stylesheets.

\ No newline at end of file +

Preferences

This page allows to set various preferences for reading the docs:

Color

You can change the feel of the site with a color change.

Reset colors

Font

You can change the font to another preset.

Custom CSS

You can add custom stylesheets.

\ No newline at end of file diff --git a/search/search_index.json b/search/search_index.json index e9bc8853ef..50a376b571 100644 --- a/search/search_index.json +++ b/search/search_index.json @@ -1 +1 @@ -{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"","title":"Welcome to Gothic Modding Community page","text":""},{"location":"#welcome-to-gothic-modding-community-page","title":"Welcome to Gothic Modding Community page","text":"

This GitHub page is designed to contain community maintained set of articles, tutorials and documentation for everything Gothic.

First two Gothic games use engine called ZenGin, developed by Piranha Bytes and Mad Scientists. If you want to know more about the history of the development, there is a heap of information on the Gothic Archive.

The content here is not meant to be taken as the holy word of modding. We are just modders sharing our experiences, knowledge and our favorite work flows.

Feel free to open a pull request with your article or propose changes.

You can open a pull request in this repository

"},{"location":"notready/","title":"None","text":"

Warning

Sorry, this page is not ready yet!

"},{"location":"preferences/","title":"Preferences","text":""},{"location":"preferences/#preferences","title":"Preferences","text":"

This page allows to set various preferences for reading the docs:

"},{"location":"preferences/#color","title":"Color","text":"

You can change the feel of the site with a color change.

Select accent color:

Select hue color:

Reset colors

"},{"location":"preferences/#font","title":"Font","text":"

You can change the font to another preset.

Select font: Default OpenDyslexic

"},{"location":"preferences/#custom-css","title":"Custom CSS","text":"

You can add custom stylesheets. Input CSS:

"},{"location":"contribute/","title":"How to contribute","text":""},{"location":"contribute/#how-to-contribute","title":"How to contribute","text":"

The Gothic Modding Community is a community-driven project. We encourage people to contribute.

This site is built with a Static Site Generator MkDocs and the Material for MkDocs theme together with multiple other MkDocs plugins.

Prerequisites for contribution differ based on the scale and type of the contribution.

"},{"location":"contribute/#feedback","title":"Feedback","text":"

Using English, you can either open an issue via GitHub or join us on Discord.

"},{"location":"contribute/#direct-contribution","title":"Direct contribution","text":"

Direct contribution is made via creating a copy of this repository (a fork) and creating a pull request (PR) on GitHub with changes for approval.

Don't waste time

Please make sure that the content you are contributing does not already exist on the dev page. You can use the search tool to filter GMC for different keywords and contents.

How to edit the source files?

The source files for the articles are written using the Markdown .md file format (Markdown cheatsheet). Other than that, this site also uses Python Markdown Extensions which add more syntax rules like indented admonitions.

"},{"location":"contribute/#minor-changes","title":"Minor changes","text":"

Minor changes like fixing typos, grammatical errors or removing/adding words to paragraphs in a single file can be done quickly with the button in the upper right corner of each article. This will open up a GitHub editing interface which will create a fork with a patch branch after modifying the file and guide the user to open up the pull request.

Select the correct branch for the pull request

Make sure that the pull request is directed towards the dev or a special pre-merge branch and not the main branch.

"},{"location":"contribute/#major-changes","title":"Major changes","text":"

More elaborate changes like editing multiple files at once, adding new articles, images, other miscellaneous files or changing the configuration of the page are easier to make via external tools on your local PC. While most of these operations can be done with the GitHub interface, it is rather cumbersome, and it may be harder to spot issues during the process as changes are not immediately visible in the browser in their final form.

Some preparation is needed before working on the files as MkDocs requires an installation of Python on the system to run. GitHub works on top of git so an installation of git is also required. A basic familiarity with Terminal/Command Prompt/Powershell command line interfaces is helpful.

"},{"location":"contribute/#system-setup-video","title":"System setup (video)","text":"

Firstly, you should install Python. You can follow this step-by-step tutorial for Windows or macOS on how to install Python.

This video is from 2017?!

The process of installing Python hasn't changed since that point. However, please install the latest version of Python 3.

To work remotely with GitHub, you can install the latest version of git on your system following this tutorial.

If you just plan on editing the content of the articles with Markdown, you can simply install the latest version of Visual Studio Code for GUI git management and Markdown preview or work with any other familiar text editor and omit the environment setup.

If you are planning to do some elaborate Python programming, you can follow this step-by-step tutorial for Windows or macOS on how to set up an environment with Visual Studio Code.

"},{"location":"contribute/#system-setup-text","title":"System setup (text)","text":"

To prepare your system to run the project follow those instructions:

  1. Install the latest version of Python . Make sure to select the \"Add Python to PATH\" option during the installation process.

  2. Open up a Terminal/Command Prompt (cmd)/Powershell window.

  3. Check that Python was properly installed with this command (might need a terminal restart):

    python --version\n
  4. Install the latest version of git following this tutorial.

  5. Check that git was properly installed with this command (might need a terminal restart):

    git --version\n
  6. (optional) Install the latest version of Visual Studio Code for GUI git management and Markdown preview.

"},{"location":"contribute/#working-locally","title":"Working locally","text":"

In order to work locally:

  1. Create a fork on GitHub.
  2. On your local PC navigate to a directory where you want to clone your forked repository and open a Terminal window inside.
  3. Clone the forked repository, using this command:

    git clone https://github.com/user-name/forked-repository-name.git <DIR-PATH>\n

    Instead of https://github.com/user-name/forked-repository-name.git use your own link which can be found after clicking on the green <> Code button and selecting the HTTPS tab.

    Replace the <DIR-PATH> with a path to a directory or . if you're inside the directory you want the project files to be cloned into.

    This will automatically create a remote origin repository pointing to your own fork.

  4. Add the remote upstream repository using this command:

    git remote add upstream https://github.com/Gothic-Modding-Community/gmc.git\n
  5. (optional) Create a Virtual Environment and activate it.

    If you work on multiple Python projects, it might be worthwhile to create a Virtual Environment for each project to have separate library directories with installed modules/plugins.

    python -m venv venv\n

    This will create a venv directory inside the current Terminal directory. Please keep that name as it's added to the .gitignore project file.

    Depending on the system, use one of these commands to activate the virtual environment.

    Linux / macOS
    source venv/bin/activate\n
    Windows Powershell
    venv\\Scripts\\activate.ps1\n
    Windows Command Prompt (cmd)
    venv\\Scripts\\activate.bat\n

    After activation there will be a (venv) indicator near the Terminal prompt.

    Don't close the Terminal

    The virtual environment must be activated each time a new Terminal window is opened.

  6. Install MkDocs with plugins using this command:

    pip install -r requirements.txt\n

    This will install all dependencies.

  7. Fetch the git history from upstream using this command:

    git fetch upstream\n
  8. Checkout a new local branch based on the upstream dev branch:

    git checkout -b name-of-branch --track upstream/dev\n

    An appropriate name for a branch is either a feature name or short description of what it changes - for example 3ds-articles, fix-typos-for-contribution. They do not have to be elaborate, up-to 4 words suffices.

  9. Start a server with MkDocs using this command:

    mkdocs serve\n

    Visit the local site with this url http://127.0.0.1:8000/gmc/. Any time you make change to any file, the website will rebuild itself and your browser will auto-refresh.

    The server may be closed using the Control-C shortcut while in the terminal/console.

  10. When you are satisfied with a part of work, add and commit the files using these commands:

    git add .\ngit commit -m \"add 3 articles about ZenGin\"\n

    An appropriate commit message should be a sentence describing the changes.

  11. When you are finished with the work, push the branch to origin using this command:

    git push origin name-of-branch\n
  12. Create the pull request to the appropriate branch.

    After pushing your local branch to the remote origin, there will be a link available in the Terminal window. Use it to create the pull request using the pushed branch.

  13. Another contribution:

    Before contributing again, always use this command:

    git fetch upstream \n
    to make sure that you have an up-to-date upstream git history. Follow then from step 8.
    git status\n

    This command allows to check, if there are any changes in the project compared to the upstream repository.

"},{"location":"contribute/#build-preferences","title":"Build preferences","text":"

While working with the project, it's possible to set various environmental variables to configure it to your own preferences:

  • GMC_DEV_LOCALE - is a 2-character language identifier (ex. en, pl), it sets the development language of the site. This will enforce that language to be the default and only built language. Helps to decrease build time and allows to easily change the language without modyfying the config file. Because of changes in the mkdocs-static-i18n plugin, this is the only way to temporarily change the default language
  • GMC_BUILD_ALTERNATES - True or False value, activates the site build to also include alternate languages apart of the default language. Default behaviour is to omit alternates to decrease build time.
  • GMC_ENABLE_ON_PUBLISH - True or False value, activates all of the final build procedures, like adding of the last modified date, minifying of the resources etc.

Environmental variables can be set temporarily for the currently open Terminal window:

Linux
export GMC_DEV_LOCALE=en export GMC_BUILD_ALTERNATES=False; mkdocs serve\n
Windows Powershell
$env:GMC_DEV_LOCALE=\"en\"\n$env:GMC_BUILD_ALTERNATES=\"False\"\nmkdocs serve\n
Windows Command Prompt (cmd)
set GMC_DEV_LOCALE=en\nset GMC_BUILD_ALTERNATES=False\nmkdocs serve\n
"},{"location":"contribute/#build-performance","title":"Build performance","text":"

To speed up the build process during development make sure that only 1 language is built, and consider using the --dirtyreload option:

mkdocs serve --dirtyreload\n

This will cause only changed .md files to rebuild. However, if you make changes to a template in the overrides directory, no changes will be visible after the rebuild, because template modification requires a full rebuild.

"},{"location":"contribute/#submit-a-file","title":"Submit a file","text":"

If working with git or Markdown is not viable or possible for you, you can submit files in a Google Docs format on the GMC Discord server and we will format and upload it to the page.

Only New English Content

This option is limited to new content in English. We can't deal with translations in this manner. For translations send a translated .md file via a feedback channel, if you don't want to work directly with git, nor add the file via the GitHub interface.

"},{"location":"contribute/#translations","title":"Translations","text":"

To provide multilingual support, our site uses the MkDocs i18n plugin.

"},{"location":"contribute/#add-new-language-support","title":"Add new language support","text":"

To support a new language it needs to be added:

Indentation is important

You must preserve the correct amount of indentation, aka spacing between entries.

  1. In the mkdocs.yml configuration, in this example we're adding the xx language:

    plugins:\n  - i18n:\n      # ...\n      languages:\n        en:\n          name: en - English\n          build: true\n        xx:\n          name: xx - Language Name\n          build: true\n
  2. In the overrides/main.html file to add the announcement text for untranslated content:

    {%\n    set announcement = {\n        \"en\": \"This page has not yet been translated into LANGUAGE, therefore it is displayed in English.\",\n        \"xx\": \"yyy\",\n    }\n%}\n{%\n    set call_to_action = {\n        \"en\": \"Support us and translate!\",\n        \"xx\": \"yyy\",\n    }\n%}\n
  3. Visit the official theme site. Make sure that the theme translation is complete there. If it's not, just follow their contribution guide and come back here, there is no need to wait for the changes in the theme.

"},{"location":"contribute/#add-translated-pages","title":"Add translated pages","text":"

Each .md file in the docs directory can have a translated version. To add a translation for a given language create a copy with an added language suffix. For example index.md will become index.xx.md for the xx language based on the settings in the mkdocs.yml file.

Each untranslated article has the button in the upper right corner next to the title. It allows to quickly add the translation via the GitHub interface without the need for local file configuration.

"},{"location":"genome/","title":"Genome engine","text":""},{"location":"genome/#genome-engine","title":"Genome engine","text":"

Genome engine is new engine by Piranha Bytes created for the game Gothic 3 and later used for the Risen and ELEX series of games.

"},{"location":"genome/general_info/object_persistence/","title":"Object persistence","text":""},{"location":"genome/general_info/object_persistence/#object-persistence","title":"Object persistence","text":"

Please note the following warning about Risen 2, 3 and ELEX 1 and 2

The following information only applies to Gothic 3 (2006) and Risen (2009). While newer Genome engine games share the same overall concepts, they have significant implementation differences that warrant their own section.

The engine is, due to the nature of the games themselves, required to store and load a vast amount of different types of data from the user's hard-drive. In order to streamline this parsing and/or serialization process, Genome implements an object persistence system using its own built-in runtime type information (RTTI) system.

Any class derived from bCObjectBase may declare its own member properties in such a way that when the object is then written into a file using the bCAccessorPropertyObject class, its associated properties will be automatically serialized into the stream by using special preprocessor macros. When the object is read back from the file, the class will be automatically initialized using the stored members.

Additionally, classes may overload the Read and Write (OnRead and OnWrite in Risen 1) virtual methods that allow the class to save additional data required during parsing such as paths to other necessary files.

As this system is quite flexible, it is used to store most of the game's data, from meshes, animations and textures to level and quest data. This is quite different from ZenGin, as its object persistence system is only used for worlds, saves, output units and parts of compiled meshes.

"},{"location":"genome/general_info/object_persistence/#file-format","title":"File format","text":""},{"location":"genome/general_info/object_persistence/#files","title":"Files","text":"
struct bCIOStream\n{\n    char data[];\n};\n
struct eCArchiveFile\n{\n    char8_t  magic[8];  // \"GENOMFLE\"\n    uint16_t version;   // 0001\n    uint32_t offset;\n\n    char data[];\n\n    uint32_t magic;    // DEADBEEF\n    uint8_t  version;  // 01\n    uint32_t count;\n    for( Count )\n    {\n        uint16_t length;\n        char8_t  string[length];  // (ASCII)\n    }\n};\n
"},{"location":"genome/general_info/object_persistence/#bcaccessorpropertyobject","title":"bCAccessorPropertyObject","text":"
bCAccessorPropertyObject::Read \n{\n    uint16_t    version;    // 0x0001\n    bool        hasPropertyObject;\n    if (hasPropertyObject)\n    {\n        bCPropertyObjectSingleton::ReadObject\n        {\n            uint16_t    version;    // 0x0001\n            bool        isPersistable;    // 0x01 (GETrue)\n            bCString    className;\n            bCPropertyObjectFactory::ReadObject\n            {\n                uint16_t    version;        // 0x0001\n                bool        isRoot;            // 0x00 (GEFalse)\n                uint16_t    classVersion;\n                bTPropertyObject<%,%>::Read\n                {\n                    bCPropertyObjectBase::Read\n                    {\n                        uint16_t version;    // 0x00C9 (201)\n                    }\n                    uint32_t size;\n                }\n                bTPropertyObject<%,%>::ReadData\n                {\n                    bCPropertyObjectBase::ReadData\n                    {\n                        uint16_t version;    // 0x00C9 (201)\n                        uint32_t count;\n                        for (count)\n                        {\n                            bCString    name;\n                            bCString    type;\n                            uint16_t    version;    // 0x001E (30)\n                            uint32_t    size;\n                            uint8_t        value[size];\n                        }\n                    }\n                    %::Read\n                    {\n                        // ClassName::OnRead/OnWrite()\n                        // uint16_t ClassVersion; ...\n                    }\n                }\n            }\n        }\n    }\n}\n
"},{"location":"genome/general_info/object_persistence/#ecprocessibleelement","title":"eCProcessibleElement","text":"Gothic 3Risen
eCProcessibleElement::Load\n{\n    uint32_t magic; // 0xD0DEFADE\n    bCAccessorPropertyObject::Read\n    {\n        // Look above for bCAccessorPropertyObject definition\n    }\n}\n
eCProcessibleElement::Load\n{\n    bCAccessorPropertyObject::Read\n    {\n        // Look above for bCAccessorPropertyObject definition\n    }\n}\n
"},{"location":"genome/general_info/object_persistence/#implementation","title":"Implementation","text":""},{"location":"genome/general_info/object_persistence/#a-practical-example","title":"A practical example","text":"

Let's propose that we have a class which is declared like so:

class gCMyClass : public bCObjectRefBase\n{\npublic:\n\n    gCMyClass()                {}\n    virtual ~gCMyClass()    {}\n\n    virtual bEResult Write(bCOStream&); // OnWrite for Risen\n    virtual bEResult Read(bCIStream&);  // OnRead for Risen\n\nprivate:\n\n    DECLARE_PROPERTY(myInt, int);\n\n    int someData;\n\n};\n

The hypothetical class then implements these virtual functions:

bEResult gCMyClass::Write(bCOStream& file)\n{\n    file << someData;\n    return bEResult_Ok;\n}\n\nbEResult gCMyClass::Read(bCIStream& file)\n{\n    file >> someData;\n    return bEResult_Ok;\n}\n

We then initialize the class in the following way:

gCMyClass object;\nobject.myInt = 1;\nobject.someData = 1;\n

If we now serialized, or to use the engine's term \"archived\", this instance into an ASCII stream, the result would look like this:

\n
"},{"location":"genome/tools/","title":"Tools","text":""},{"location":"genome/tools/#tools","title":"Tools","text":"

Piranha Bytes did not release a modkit for their Genome engine, but the modding community has released a wide range of tools to work with the game's files and the engine itself.

Info

This page is under construction, for now, only handful of links are present.

"},{"location":"genome/tools/#gothic-3-sdk","title":"Gothic 3 SDK","text":"

Georgeto, inspired by NicoDE's Risen SDK, has created an SDK for Gothic 3. It can be used to manipulate the engine in the similar way Union is able to manipulate ZenGin. GitHub repository

"},{"location":"zengin/","title":"ZenGin","text":""},{"location":"zengin/#zengin","title":"ZenGin","text":"

The game engine ZenGin is used by Gothic 1 and 2. This section contains the documentation of the various aspects of ZenGin modding.

"},{"location":"zengin/meshes/","title":"Meshes","text":""},{"location":"zengin/meshes/#meshes","title":"Meshes","text":"

Everything about 3D models in ZenGin.

"},{"location":"zengin/music/","title":"Music","text":""},{"location":"zengin/music/#music","title":"Music","text":"

Zengin uses DirectMusic for playing in-game soundtrack. To edit Gothic music files you need the Direct Music Producer, a program released by Microsoft and provided with older DirectX SDK.

Warning

Music files can't be packed in the .vdf or .mod archives, all music files must be located in /_work/Data/Music directory.

"},{"location":"zengin/music/#file-formats","title":"File formats","text":"

The music directory contains these file types:

  • .dls - Downloadable Sound format file. This is the base for all other files. Contains:

    • Collections of virtual musical instruments.
    • Wave files instruments use.
  • .sty - Style file. Contains:

    • Bands - settings for virtual instruments from .dls.
    • Patterns - fragments of tracks, that can be later merged, looped and superimposed on each other
  • .sgt - File with properly connected patterns - the final track

"},{"location":"zengin/music/#alternative-music-system","title":"Alternative Music System","text":"

The zBassMusic plugin replaces Zengin's default music library with the much newer BASS library. This allows, among other things, to play music in such formats as .mp3 or .ogg, and to pack songs into .vdf and .mod archives.

"},{"location":"zengin/textures/","title":"Textures","text":""},{"location":"zengin/textures/#textures","title":"Textures","text":"

Textures are pictures that get projected onto a 3D models and on a 2D user interface in the game. We will discuss how to work with textures in this section.

"},{"location":"zengin/video/","title":"Video","text":""},{"location":"zengin/video/#video","title":"Video","text":"

To get a video cutscene, intro or outro into the game, the video needs to be in a proper format - BINK video format .bik.

"},{"location":"zengin/video/#editing-the-video","title":"Editing the video","text":"

The video you recorded and want to use has to be edited. My go-to editor for this is kdenlive. It works very well, it is free and open source, and it supports BINK video as an input, which is great if you want to include subtitles in the video.

My version of kdenlive does not know how to export video straight to .bik so I just export my video to .mp4 and then convert it with RAD Video Tools.

"},{"location":"zengin/video/#rad-video-tools","title":"RAD Video Tools","text":"

RAD Video Tools is a tool for converting other video formats to BINK .bik that Gothic can use.

Warning

Gothic 1 bink implementation has some problems as you have to set the audio compression to 104 and above in RAD tools to get video to work in Gothic 1.

NicoDE's comment:

Add 100 to the audio compression level when encoding videos, e.g. 104 for level 4 with old sound format (should be mentioned in the RAD Video Tools documentation) for G1 without updated Miles libraries.

Note

Newest Union (1.0m at the time of writing) has a new patch for BINK video playback. The issue with sound should be fixed.

"},{"location":"zengin/anims/","title":"Animation","text":""},{"location":"zengin/anims/#animation","title":"Animation","text":""},{"location":"zengin/anims/#animations-in-zengin","title":"Animations in ZenGin","text":"

Animations are (apart from maybe advanced programming work using Ikarus or Union) one of the most advanced modding techniques, since you not only must understand the way they work, but also know how to write the animation script and understand the whole scheme selection system, naming convention and of course know how to animate (that is my biggest problem :D). To get a new animation into ZenGin (the Gothic engine) is not difficult per se, I would describe it as tedious.

Luckily, there are tools to help us to achieve our goal - get a new animation to be used by the engine, and in effect, to be used and seen in the game.

To describe the whole process, I constructed this small tutorial, to help other people to get animations working and to spare them many hours of searching the excellent forum posts, that describe parts of the process. __

Excluding advanced programming work with Ikarus or Union, animations are arguably the most advanced modding discipline of ZenGin engine. Its difficulty stems for the fact that you not only have to understand the general concept, but also learn how to write the animation scripts and understand the whole scheme selection system, including naming conventions and, most important for last - actually know how to animate. Adding new animations into ZenGin is more tedious than actually difficult.

There are tool to help with this endeavor - to get a new animation implemented in the engine, and seeing its effects in game. Following tutorial has been constructed to help others to get their animations working without having to scour old forum posts for hours.

"},{"location":"zengin/anims/#prerequisites---tools--materials","title":"Prerequisites - Tools & Materials","text":"
  1. Gothic Mod Development Kit (MDK)
    • Gothic 1 MDK - link
    • Gothic 2 MDK - link
  2. Blender
  3. Kerrax's Import Export plugin - follow the installation instructions to install the plugin, make sure to set up the texture paths too
  4. Tool for decompiling animations GothicSourcer, or use phoenix or write your own using ZenLib
"},{"location":"zengin/anims/#the-workflow","title":"The workflow","text":"

This is the basic step-by-step workflow on how to get the animation into the game.

  1. Load the actor (character or object) into your 3D software
  2. Create your animation
  3. Export the animation as an .asc file
  4. Write the MDS file
  5. Run the game to compile your animations
  6. Test your animations in-game using a Daedalus script or a console command

Sounds simple enough, except there is a lot missing. Even though the steps start with loading the actor into blender, understanding the system of animations to get high quality assets into your mod is more important.

"},{"location":"zengin/anims/#animation-types","title":"Animation \"types\"","text":"

There are two main types of animations - skeletal and morphmesh animations. Character body animations are skeletal, and we animate the skeleton and the entire model (skin) moves around it. Morph mesh animation is, on the other hand, used for facial animations such as eating, blinking or talking and for animated meshes like wave water ferns or fish in Khorinis' harbor.

This guide focuses on skeletal animations. There are few different ones, all of which will have their own demonstration in the future. Categories are:

  1. Standalone animation - waving, bowing, eating
  2. MOBSI animations - bed, alchemy table, anvil
  3. Item animations - sweeping the floor with a broomstick, using the horn, playing the lute
  4. Mandatory animations - running, walking, sneaking
  5. Combined/interpolated animations - picking stuff up, aiming with a bow/crossbow

All of these animations are defined in an MDS file which will be talked about in the next sections.

"},{"location":"zengin/anims/events/","title":"None","text":"

Acknowledgment

This tutorial was possible thanks to Kerrax, VAM and their excelent articles (MDS, EventTags) and Avallach from theModders who provided valuable insight.

"},{"location":"zengin/anims/events/#animation-event-block-overview","title":"Animation event block overview","text":"

We often need to perform some other actions together with our animation, such as playing a sound effect, inserting item into NPC's hand or changing an item instance into a different one, like turning a raw steel into hot raw steel. These actions often need to be done at very specific moment during the animation playback, therefore they are defined using events(#aniamtion-events) in the event block which follows right after the animation definition. The event block is started and closed by curly brackets.

Example:

ani (\"s_RunL\" 1 \"s_RunL\" 0.0 0.1 M. \"Hum_RunLoop_M01.asc\" F 12 31) // animation\n{ // event block start\n\n    *eventSFXGrnd    (12    \"Run\") // animation event\n    *eventSFXGrnd    (24    \"Run\") // animation event\n    ...\n    *eventSFXGrnd    (30    \"Run\") // animation event\n} // event block end\n

Warning

Each animation can define a maximum of 16 events. Should you need more, split the animation into parts and use next_ani to chain them together.

"},{"location":"zengin/anims/events/#animation-events","title":"Animation events","text":"

Animation events are commands telling engine to do something. Event *eventSFXGrnd(12 \"Run\") will command the engine to play sound Run at the very moment (12th frame) the character lands food on the ground. So with that in mind here is the general syntax as well as each animation event in the game.

General Syntax:

    *EVENTNAME (FRAME KEYWORD \"INSTANCE\" [OPTIONAL] [A:VALUE] [B:VALUE])\n

FRAME - all events specify on what frame int the animation source file .ASC should this event happen

KEYWORD - some events expect very specific keywords.

\"INSTANCE\" - this indicates parameter is expected to be inside quotes, usually it;s slot/bone or item/sound instance name from the scrips

[OPTIONAL] - this is an example of the optional parameter. Optional parameters will be indicated by brackets [], if you don't specify them, the event will use the default value defined by the engine.

A:VALUE - some events that have more than one optional parameter use a prefix to know which was specified

NODE_NAME - will indicate any NODE should work, be it bones (BIP01...) or ZS_ slots (ZS_RIGHTHAND)

SLOT - this will indicate most likely only ZS_ slots will work.

Warning

Events should follow in ascending order by the frame they appear on. i. e. *eventTag(1 ...) must come before *eventTag(2 ...)

Event Description eventCamTremor camera shake eventMMStartAni start morph-mesh eventPFX create particle effect eventPFXStop destroy particle effect eventSwapMesh exchange item meshes between two slots eventSFX create sound effect eventSFXGRND create sound effect on the ground eventTag generic event, does action specified in parameters Defined in engine but never used ? eventPFXGRND create particle effect on the ground eventSetMesh ? modelTag same as eventTag, but applies to morphmesh?"},{"location":"zengin/anims/events/#eventcamtremor","title":"eventCamTremor","text":"

Earthquake effect (camera shake)

Example:

*eventCamTremor (12 1000    500   2  8 )\n

Syntax:

*eventCamTremor (FRAME RANGE DURATION MIN_AMPLIFIER MAX_AMPLIFIER)\n

eventCamTremor - is a keyword, for camera shake event

Let's describe all the parameters

FRAME - animation frame at which this event starts

RANGE - range from which the effect will be 'felt' defined in in-game centimeters (1000 is 10 meters in-game)

DURATION - duration of the effect in milliseconds

MIN_AMPLIFIER - minimum amount of shaking in in-game centimeters

MAX_AMPLIFIER - the maximum amount of shaking.

"},{"location":"zengin/anims/events/#eventmmstartani","title":"eventMMStartAni","text":"

Start the animation of the morph-mesh that is attached to the specified node. Mostly used to start NPC facial animations or to animate bows/crossbows shooting.

Example:

*eventMMStartAni    (14 \"T_HURT\")\n*eventMMStartAni    (6  \"S_SHOOT\"   \"ZS_RIGHTHAND\")\n*eventMMStartAni    (6  \"S_BOOK_NEXT_PAGE\"  \"ZS_RIGHTHAND\" I:0.5 H:5)\n

Syntax:

*eventMMStartAni (FRAME \"ANI_NAME\" [\"NODE_NAME\"] [I:INTENSITY] [H:HOLD_TIME])\n

FRAME - animation frame at which animation should start

ANI_NAME - name of the morph-mesh animation (specified in .MMS) file

NODE_NAME - node in the hierarchy, to which morph mesh is attached. If not specified, a default value of BIP01 HEAD will be used.

I:INTENSITY - float value to specify blending of morph animation with the current one ?

H:HOLD_TIME - time in seconds, how long will the animation \"stay\"

Both INTENSITY and HOLD_TIME can be specified in the MMS script. All gothic morph meshes specify those values in .MMS, therefore behavior when both specified in eventMMStartAni and .MMS file is unknown/untested

"},{"location":"zengin/anims/events/#eventpfx","title":"eventPfx","text":"

Start particle effect at the specified bone.

Example:

*eventPFX   (12     \"ZMODELLANDDUST\"    \"Bip01\" )\n*eventPFX   (2  1   \"DEMON_ATTACK\"      \"BIP01 R HAND\"  ATTACH)\n

Syntax:

*eventPFX (FRAME [PFX_HANDLE] \"PFX_NAME\" \"NODE_NAME\" [ATTACH])\n

FRAME - animation frame at which particle effect starts

PFX_NAME - name of the PFX instance

PFX_HANDLE - an optional integer value. Specifying this creates a 'handle' and allows stop the PFX later using eventPFXStop

NODE_NAME - node in the hierarchy. particle effect will be spawned at the node's position. If not specified, a default value of BIP01 will be used.

ATTACH - keyword, including this keyword, will make particle effect follow the node specified, otherwise, it will stay where it spawned.

Tip

ATTACH is used to create demons burning hand during the attack, while without this keyword dust particles are made to stay at the position where NPC landed after falling.

"},{"location":"zengin/anims/events/#eventpfxstop","title":"eventPFXStop","text":"

Stops particle effect previously started by eventPfx

Example:

*eventPFX       (2  1   \"DEMON_ATTACK\"      \"BIP01 R HAND\"  ATTACH) // starts pfx with handle 1\n...\n*eventPFXStop   (70 1) // stops pfx started above\n

Syntax:

*eventPFXStop (FRAME PFX_HANDLE)\n

FRAME - animation frame at which particle effect should disappear

PFX_HANDLE - an integer value. Handle of the particle effect, that should be destroyed. Particle effect must be spawned using the same handle by eventPfx first

"},{"location":"zengin/anims/events/#eventswapmesh","title":"eventSwapMesh","text":"

Move mesh from source NODE to target node. Item should be present in the node already. Only mesh of the Items is moved, engine internally still keeps a reference to items in the original slot? Never used in game?

Example:

*eventSwapMesh (5 \"ZS_CROSSBOW\" \"ZS_LEFTARM\")\n

Syntax:

*eventSWAPMESH      (FRAME \"SOURCE_NODE_NAME\" \"TARGET_NODE_NAME\")\n

FRAME - animation frame at which transport of the mesh should happen

SOURCE_NODE_NAME - source node containing the item.

TARGET_NODE_NAME - target node that the item should be moved to.

Note

In some rare occasions duplicates item

"},{"location":"zengin/anims/events/#eventsfx","title":"eventSfx","text":"

Play sound effect. It can be either SFX instance from scripts, or .WAV file.

Example:

*eventSFX   (0  \"Drown\")\n*eventSFX   (8  \"WHOOSH\"    EMPTY_SLOT)\n*eventSFX   (8  \"BAB_SIGH\" R:5000   EMPTY_SLOT)   \n

Syntax:

*eventPFX (FRAME \"SFX_NAME\" [R:RANGE] [EMPTY_SLOT])\n

FRAME - animation frame at which particle effect starts

SFX_NAME - name of the SFX instance or .WAV file

R:RANGE - an optional integer value. The range from which the effect will be 'heard' defined in in-game centimeters (1000 is 10 meters in-game)

[EMPTY_SLOT] - optional keyword. By default audio effects use a single audio channel (slot) per Model. That means every eventSFX request will cancel any currently playing effect. If EMPTY_SLOT is specified, audio will be played on the next available (empty) audio slot and other sounds will not be interrupted.

Note

A lot of original game animations contain EMTPY_SLOT instead of EMPTY_SLOT which was probably unintended. Gothic therefore acts as no keyword was provided, which causes a lot of sound interruptions. Therefore be mindful of spelling when copying original MDS scripts

"},{"location":"zengin/anims/events/#eventsfxgrnd","title":"eventSfxGrnd","text":"

the same as eventSfx with only one difference, the sound effect name is appended with the current material name.

Example:

*eventSFXGrnd (12 \"Run\")\n

Syntax:

*eventSFXGrnd (FRAME \"SFX_NAME\" [R:RANGE] [EMPTY_SLOT])\n

Depending on the material of the texture, the character is standing on, the game will add one of the following suffixes:

Spacer Material Suffix Gothic 1 Gothic 2a UNDEF _Undef \u2714\ufe0f \u2714\ufe0f EARTH _Earth \u2714\ufe0f \u2714\ufe0f SAND _Sand \u2714\ufe0f \u2714\ufe0f METAL _Metal \u2714\ufe0f \u2714\ufe0f WATER _Water \u2714\ufe0f \u2714\ufe0f WOOD _Wood \u2714\ufe0f \u2714\ufe0f SNOW _Snow \u274c \u2714\ufe0f STONE _Stone \u2714\ufe0f \u2714\ufe0f default _Stone \u2714\ufe0f \u2714\ufe0f

NPC running on grass texture, with material set to EARTH in world editor, will play sound Run_Earth by using *eventSFXGrnd (12 \"Run\") in run animation. _Earth suffix is determined and added by the engine.

"},{"location":"zengin/anims/events/#eventtag","title":"eventTag","text":"

This is a generic type of event that does different actions based on the first parameter after the frame parameter. It was probably later in development to extend MDS functionality without the need to expand parser itself. All parameters except FRAME are passed inside quotes Further parameters are specific for every EVENT_TAG_TYPE.

Waning

eventTag contrary to other events is validated only at runtime. If parameters are wrong, it won't work or might crash the game

Syntax:

*eventTag (FRAME \"EVENT_TAG_TYPE\" \"PARAMETER_1\"  \"PARAMETER_2\" ... \"PARAMETER_N\")\n

FRAME - Frame at which the event will execute. This parameter is always first and the same for all eventTags

EVENT_TAG_TYPE - a type of event = action that should happen.

Here is a list of event tag types:

EVENT TAG TYPE Description DEF_CREATE_ITEM Creates item into slot DEF_INSERT_ITEM Inserts item to slot from inventory DEF_REMOVE_ITEM Removes item from slot to inventory DEF_DESTROY_ITEM Destroys item in slot DEF_PLACE_ITEM ~~Places item from slot into mob slot~~ Destroys item in slot DEF_EXCHANGE_ITEM Removes item in slot and replaces with new item DEF_FIGHTMODE Sets npc into weapon stance DEF_PLACE_MUNITION Inserts munition into slot DEF_REMOVE_MUNITION Remove munition back to inventory DEF_DRAWSOUND Plays weapon drawing sound based on weapon material DEF_UNDRAWSOUND Plays weapon sheating sound based on weapon material DEF_SWAPMESH Moves items visual to different slot visually DEF_DRAWTORCH Inserts torch DEF_INV_TORCH Moves torch to different slot temporarily DEF_DROP_TORCH Drops torch from slot to world DEF_HIT_LIMB Defines node which deals damage DEF_DIR Defines attack direction DEF_DAM_MULTIPLIER Defines damage mutliplier DEF_PAR_FRAME Defines frame range for blocking DEF_OPT_FRAME Defines damage frames DEF_HIT_END Defines last frame to continue combo DEF_WINDOW Defines frame for combo continuation"},{"location":"zengin/anims/events/#def_create_item","title":"DEF_CREATE_ITEM","text":"

Creates a new item instance and inserts it into the specified slot. Item is not inserted permanently but only for the duration of interaction.

Example:

*eventTag    (4    \"DEF_CREATE_ITEM\"    \"ZS_RIGHTHAND\"    \"ItMw_1H_Mace_L_04\")\n

Syntax:

*eventTag (FRAME \"DEF_CREATE_ITEM\" \"SLOT\" \"ITEM_INSTANCE\")\n

SLOT - a name of the ZS_ slot, write in UPPERCASE

ITEM_INSTANCE - item instance from the scripts

Warning

This event tag most likely works only during Mob/Item interaction

"},{"location":"zengin/anims/events/#def_insert_item","title":"DEF_INSERT_ITEM","text":"

Insert the interaction item into the specified slot.

  • during mob interaction, inserted item instance is of instance taken from UseWithItem mob property.
  • during item interaction (i.e. drink potion) item that started the SceneName will be inserted.

In the example below: (1) inserts ItMiSwordrawhot that is defined in spacer into ZS_LEFTHAND, then (2) spawns ItMw_1H_Mace_L_04 (hammer) into ZS_RIGHTHAND for anvil interaction.

Example:

ani    (\"t_BSANVIL_S0_2_S1\"    1    \"s_BSANVIL_S1\"    0.0    0.0    M.    \"Hum_BSAnvil_Jue00.asc\"    F    4    9)\n{\n    *eventTag    (4    \"DEF_INSERT_ITEM\"    \"ZS_LEFTHAND\")    // (1)\n    *eventTag    (4    \"DEF_CREATE_ITEM\"    \"ZS_RIGHTHAND\"    \"ItMw_1H_Mace_L_04\")    // (2)\n}\n

Syntax:

*eventTag (FRAME \"DEF_INSERT_ITEM\" \"SLOT\")\n

SLOT - a name of the ZS_ slot, use UPPERCASE

ITEM_INSTANCE - item instance from the scripts

Warning

This event tag most likely works only during Mob/Item interaction

The well-known Gothic bug:

If player gets hit while drinking a potion, the effect of the potion is applied, but the potion remains in the inventory - the reason for the bug is that the potion item is inserted into hand using DEF_INSERT_ITEM and would be removed from the world at the end of the drinking animation, while the potion's effect (a script function that increases stats) is applied at the very beginning of the animation. When the player is hit, the drinking animation is interrupted, and the engine does not remove the item from the world.

"},{"location":"zengin/anims/events/#def_remove_item","title":"DEF_REMOVE_ITEM","text":"

Remove an item inserted into a slot via DEF_INSERT_ITEM from the slot back into the inventory.

Example:

*eventTag (0 \"DEF_REMOVE_ITEM\")\n

Syntax:

*eventTag (FRAME \"DEF_REMOVE_ITEM\")\n

Warning

This event tag most likely works only during Mob/Item interaction

"},{"location":"zengin/anims/events/#def_destroy_item","title":"DEF_DESTROY_ITEM","text":"

Destroys an item inserted into a slot via DEF_INSERT_ITEM. The item is removed from the world.

Example:

*eventTag (0 \"DEF_DESTROY_ITEM\")\n

Syntax:

*eventTag (FRAME \"DEF_DESTROY_ITEM\")\n

Warning

This event tag most likely works only during Mob/Item interaction

"},{"location":"zengin/anims/events/#def_place_item","title":"DEF_PLACE_ITEM","text":"

Remove the item inserted via eventTag DEF_INSERT_ITEM from the slot and the world. In terms of its action, eventTag DEF_PLACE_ITEM is a synonym for DEF_DESTROY_ITEM. Possibly fixed by SystemPack. See intended use.

Example:

*eventTag (0 \"DEF_PLACE_ITEM\")\n

Syntax:

*eventTag (FRAME \"DEF_PLACE_ITEM\")\n

Warning

This event tag most likely works only during Mob/Item interaction

Intended use

Presumably, the eventTag DEF_PLACE_ITEM was intended to have different behavior: If an NPC interacts with a MOB that has a ZS_SLOT node, then move the item inserted via DEF_INSERT_ITEM from the NPC node into the ZS_SLOT node on the MOB. An example would be orc priest hearts in the Temple of the Sleeper, Gothic 1.

// Sleeper Portal\nani (\"t_SPORTAL_Stand_2_S0\"     1    \"s_SPORTAL_S0\"     0.0    0.0    M.    \"Hum_SleeperPortal_M01.asc\"    F    0    19)\nani (\"s_SPORTAL_S0\"             1    \"s_SPORTAL_S0\"     0.0    0.0    M.    \"Hum_SleeperPortal_M01.asc\"    F    20    20)\nani (\"t_SPORTAL_S0_2_Stand\"     1    \"\"                 0.0    0.2    M.    \"Hum_SleeperPortal_M01.asc\"    R    0    19)\nani (\"t_SPORTAL_S0_2_S1\"        1    \"s_SPORTAL_S1\"     0.0    0.0    M.    \"Hum_SleeperPortal_M01.asc\"    F    21    90    FPS:10)\n{\n    *eventTag    (60    \"DEF_INSERT_ITEM\"    \"ZS_RIGHTHAND\")    // (1)\n    *eventTag    (90    \"DEF_PLACE_ITEM\")    // (2)\n}\nani (\"s_SPORTAL_S1\"             1    \"s_SPORTAL_S1\"     0.0    0.0    M.    \"Hum_SleeperPortal_M01.asc\"    F    91    91)\nani (\"t_SPORTAL_S1_2_Stand\"     1    \"\"                 0.0    0.2    M.    \"Hum_SleeperPortal_M01.asc\"    F    90    100)\n

During animation on 60th frame,(1) inserts orc priest sword from the inventory, and (2) on 90th frame, presumably, should have left the sword inserted into the heart sticking out. There is ZS_SLOT present to indicate the location of the sword after insertion into the heart.

In reality, (2) simply removes the sword from the world like DEF_DESTROY_ITEM. This was most likely an unrealized idea. In G2, eventTag DEF_PLACE_ITEM is not used.

"},{"location":"zengin/anims/events/#def_exchange_item","title":"DEF_EXCHANGE_ITEM","text":"

Replace an item in a slot with another item. Item present in the slot is removed from the slot and the world, new item specified in parameters is created and inserted in the same slot.

Example:

*eventTag (37 \"DEF_EXCHANGE_ITEM\" \"ZS_LEFTHAND\" \"ItMiSwordrawhot\")\n

Syntax:

*eventTag (FRAME \"DEF_EXCHANGE_ITEM\" \"SLOT\" \"ITEM_INSTANCE\")\n

SLOT - a name of the ZS_ slot, use UPPERCASE

ITEM_INSTANCE - item instance from the scripts

Warning

This event tag most likely works only during Mob/Item interaction

"},{"location":"zengin/anims/events/#def_fightmode","title":"DEF_FIGHTMODE","text":"

Set fight mode for the model. Used in transition animations to weapon stances like t_1h_2_1hRun.

Example:

*eventTag (5 \"DEF_FIGHTMODE\" \"FIST\")\n

Syntax:

*eventTag (FRAME \"DEF_FIGHTMODE\" \"FIGHT_MODE\")\n

FIGHT_MODE - fight modes are defined in the engine and can be one of the following:

  • \"\" - remove weapon
  • \"FIST\" - fists
  • \"1H\" or \"1HS\" - one-handed weapon
  • \"2H\" or \"2HS\" - two-handed weapon
  • \"BOW\" - bow
  • \"CBOW\" - crossbow
  • \"MAG\" - magic

Example: Parameter 1H sets fight mode for the actor (in the engine), but also exchanges sword from ZS_SWORD slot to the ZS_RIGHTHAND

"},{"location":"zengin/anims/events/#def_place_munition","title":"DEF_PLACE_MUNITION","text":"

Place ammunition, from inventory such as an arrow into the specified slot. Used in reloading animations after a bow/crossbow shot.

Example:

*eventTag (9 \"DEF_PLACE_MUNITION\" \"ZS_RIGHTHAND\")\n

Syntax:

*eventTag (FRAME \"DEF_PLACE_MUNITION\" \"SLOT\")\n

SLOT - slot where the ammunition is created. There are only two valid slot names: \"ZS_LEFTHAND\" and \"ZS_RIGHTHAND\".

Ammunition always corresponds to the equipped ranged weapon instance and its munition field in the C_ITEM instance

instance ItRw_Sld_Bow(C_Item)\n{\n    name = \"\u041b\u0443\u043a\";\n    mainflag = ITEM_KAT_FF;\n    flags = ITEM_BOW;\n    material = MAT_WOOD;\n    value = Value_SldBogen;\n    damageTotal = Damage_SldBogen;\n    damagetype = DAM_POINT;\n    munition = ItRw_Arrow;\n    cond_atr[2] = ATR_DEXTERITY;\n    cond_value[2] = Condition_SldBogen;\n    visual = \"ItRw_Sld_Bow.mms\";\n    description = name;\n    text[2] = NAME_Damage;\n    count[2] = damageTotal;\n    text[3] = NAME_Dex_needed;\n    count[3] = cond_value[2];\n    text[5] = NAME_Value;\n    count[5] = value;\n};\n
"},{"location":"zengin/anims/events/#def_remove_munition","title":"DEF_REMOVE_MUNITION","text":"

Remove ammunition previously placed by DEF_PLACE_MUNITION event

Example:

*eventTag (19 \"DEF_REMOVE_MUNITION\")\n

Syntax:

*eventTag (FRAME \"DEF_REMOVE_MUNITION\")\n
"},{"location":"zengin/anims/events/#def_drawsound","title":"DEF_DRAWSOUND","text":"

Play weapon drawing sound. Determined by drawn weapon material field in the C_ITEM instance

  • \u201cDrawSound_WO.wav\u201d - for MAT_WOOD;
  • \"DrawSound_ME.wav\" - for MAT_METAL.

Example:

*eventTag (19 \"DEF_DRAWSOUND\")\n

Syntax:

*eventTag (FRAME \"DEF_DRAWSOUND\")\n
"},{"location":"zengin/anims/events/#def_undrawsound","title":"DEF_UNDRAWSOUND","text":"

Play weapon sheathing sound. Determined by drawn weapon material field in the C_ITEM instance

  • \"UndrawSound_WO.wav\u201d - for MAT_WOOD;
  • \"UndrawSound_ME.wav\" - for MAT_METAL.

Example:

*eventTag (19 \"DEF_UNDRAWSOUND\")\n

Syntax:

*eventTag (FRAME \"DEF_UNDRAWSOUND\")\n
"},{"location":"zengin/anims/events/#def_swapmesh","title":"DEF_SWAPMESH","text":"

Swap items in the specified slots.

Example:

*eventTag (5 \"DEF_SWAPMESH\" \"ZS_CROSSBOW\" \"ZS_LEFTHAND\")\n

Syntax:

*eventTag (FRAME \"DEF_SWAPMESH\" \"SLOT1\" \"SLOT2\")\n

SLOT1 - name of the slot with item to be exchanged.

SLOT2 - name of the slot with item to be exchanged.

Warning

In case SLOT1 or SLOT2 is equal to \"ZS_LEFTHAND\" or \"ZS_RIGHTHAND\", the engine will attempt to put the model into fight mode similar to DEF_FIGHTMODE event. This can lead to game freezing.

Tip

This event is similar to the *eventSwapMesh. The main difference is *eventSwapMesh will swap only visuals (meshes) of the items, while eventTag DEF_SWAPMESH will swap items and their slot references. After a game reload, meshes would reset their positions if swapped using *eventSwapMesh. Additionally *eventSwapMesh does not try to set the model into fight mode.

"},{"location":"zengin/anims/events/#def_drawtorch","title":"DEF_DRAWTORCH","text":"

Does nothing? never used.

Example:

*eventTag (5 \"DEF_DRAWTORCH\")\n

Syntax:

*eventTag (FRAME \"DEF_DRAWTORCH\")\n
"},{"location":"zengin/anims/events/#def_inv_torch","title":"DEF_INV_TORCH","text":"

Temporarily return torch into inventory, for the duration of mob/item interaction. Does nothing if a torch is not present in ZS_LEFTHAND. Used before interacting with mobs like bed, or before performing eating animations that require a left hand.

Example:

*eventTag (5 \"DEF_INV_TORCH\")\n

Syntax:

*eventTag (FRAME \"DEF_INV_TORCH\")\n
"},{"location":"zengin/anims/events/#def_drop_torch","title":"DEF_DROP_TORCH","text":"

Drop the torch onto the ground if present in ZS_LEFTHAND.

Example:

*eventTag (5 \"DEF_DROP_TORCH\")\n

Syntax:

*eventTag (FRAME \"DEF_DROP_TORCH\")\n
"},{"location":"zengin/anims/events/#def_hit_limb","title":"DEF_HIT_LIMB","text":"

Set which node is dealing damage to others. This node is then used in calculations for collisions. Up to four slots can be specified.

Example:

// humans - fist attacks\n*eventTag (0     \"DEF_HIT_LIMB\"     \"BIP01 R HAND\")\n// humans - sword attacks\n*eventTag (0 \"DEF_HIT_LIMB\" \"ZS_RIGHTHAND\")\n// animals \neventTag (0 \"DEF_HIT_LIMB\"    \"BIP01 HEAD\")\n

Syntax:

*eventTag (FRAME \"DEF_HIT_LIMB\" \"SLOT1\" \"SLOT2\" \"SLOT3\" \"SLOT4\")\n
"},{"location":"zengin/anims/events/#def_dir","title":"DEF_DIR","text":"

Set the direction of the attack. Enemy block animation is determined by this information. Not used.

Example:

*eventTag (0 \"DEF_DIR\"  \"O\")\n*eventTag (0 \"DEF_DIR\"  \"L\")\n*eventTag (0 \"DEF_DIR\"  \"OUOL\") // combo attack - top, under, \n

Syntax:

*eventTag (FRAME \"DEF_DIR\" \"DIRECTIONS\")\n

DIRECTIONS - can be up to 10 characters, each character defines one attack direction during combo attack, default is O - capital letter O, not zero 0. Possible values are

  • O - (oben) from top/ over

  • U - (unter) from under

  • R - from right

  • L - from left

If the enemy is trying to block an attack with a defined direction it will choose a matching animation adding a direction suffix like t_1hParade_U for opponent's attack direction U

Note

Sadly this feature was unused in Gothic 1. All attacks use O direction and only defined animations for blocking are for said t_1hParade_O But can be easily restored with a few new animations and MDS file edits. In Gothic 2, blocking animation uses zero 0 instead of O which might indicate the feature no longer works.

"},{"location":"zengin/anims/events/#def_dam_multiplier","title":"DEF_DAM_MULTIPLIER","text":"

Set damage multiplier. For the attack animation. The damage will be multiplied by a provided number regardless of whether the attack is a critical attack or not.

Example:

*eventTag (0 \"DEF_DAM_MULTIPLIER\"    \"0.2\")\n*eventTag (0 \"DEF_DAM_MULTIPLIER\"    \"2.0\")\n

Syntax:

*eventTag (FRAME \"DEF_DAM_MULTIPLIER\" \"MULTIPLIER\")\n

MULTIPLIER - float value inside quotes

"},{"location":"zengin/anims/events/#def_par_frame","title":"DEF_PAR_FRAME","text":"

Set frame range during which damage is blocked. If not provided whole animation is blocking damage.

Example:

*eventTag (0 \"DEF_PAR_FRAME\"    \"1 8\")\n

Syntax:

*eventTag (FRAME \"DEF_PAR_FRAME\" \"START_FRAME_END_FRAME\")\n

START_FRAME_END_FRAME - Two integer numbers inside quotes. if \"0 0\" is provided, the animation will be blocking it's whole duration

"},{"location":"zengin/anims/events/#def_opt_frame","title":"DEF_OPT_FRAME","text":"

Set frames during which damage collisions should be evaluated. Damage is checked for collision with \"hit limb\". This event usually comes in pair with eventTags DEF_WINDOW and DEF_HIT_END

Example:

*eventTag (0 \"DEF_OPT_FRAME\" \"6\") // on hit attack, hit on 6th frame\n*eventTag (0 \"DEF_OPT_FRAME\"  \"6 30\") // 2 attack combo, hit at 6th and 30th frame\n

Syntax:

*eventTag (FRAME \"DEF_OPT_FRAME\" \"HIT_FRAME1 HIT_FRAME2 ... HIT_FRAME10\")\n

HIT_FRAME1 HIT_FRAME2 ... HIT_FRAME10 - specify 1 and up to 10 integers separated by space inside quotes. Each number represents frame at which damage should be done. Number of provided hit frames determines number of combos (max 10 possible).

"},{"location":"zengin/anims/events/#def_hit_end","title":"DEF_HIT_END","text":"

Set frames at which the combo is \u201ccut off\u201d if you do not press the \u201cup\u201d key (G1) or the left mouse button (G2) during the attack. Gothic has bug that in this case we will hear all the sound effects following this frame, and the animation ends with the character\u2019s characteristic twitching. The number of frames specified in this entry must match the number of frames of the eventTag DEF_OPT_FRAME.

Example:

*eventTag (0  \"DEF_HIT_END\"   \"32\") \n*eventTag (0  \"DEF_HIT_END\"   \"27 48 75\")      \n

Syntax:

*eventTag (FRAME \"DEF_HIT_END\" \"HIT_END1 HIT_END2 ... HIT_END10\")\n

HIT_END1 HIT_END2 ... HIT_END10 - specify 1 and up to 10 integers separated by space inside quotes. After this frame combo cannot be continued and model will continue animation until the current DEF_WINDOW - 1`. Which is usually animation returning to idle stance

"},{"location":"zengin/anims/events/#def_window","title":"DEF_WINDOW","text":"

Set a \u201cwindow\u201d in the animation - an interval of frames during which you need to press the \u201cup\u201d (G1) or the left mouse button (G2) to continue the combo strike.

Example:

*eventTag (0 \"DEF_WINDOW\"    \"9 19\") // one combo with window from 9-19 (can be chained)\n*eventTag (0  \"DEF_WINDOW\"    \"10 23 32 41 58 70\") // 3 combos with windows 10-23 then 32-41, 58-70\n

Syntax:

*eventTag (FRAME \"DEF_WINDOW\" \"HIT_1_WINDOW_START HIT_1_WINDOW_END HIT_2_WINDOW_START HIT_2_WINDOW_END  ...\")\n

HIT_1_WINDOW_START HIT_1_WINDOW_END HIT_2_WINDOW_START HIT_2_WINDOW_END - specify 1 and up to 20? integers separated by space inside quotes. A window consists of a start and end frame, therefore for each DEF_OPT_FRAME, you must provide 2 numbers.

  • HIT_WINDOW_START - First value of the pair defines frame from which attack can continue.
  • HIT_WINDOW_END - Second value is a little confusing. It defines START of the next attack animation. Ability to continue combo stops at DEF_HIT_END frames. Usually there are few frames of animation, where characters returns to idle position. HIT_WINDOW_END should be one frame after characters return to idle stance, which should also be first frame of the next attack
"},{"location":"zengin/anims/events/#attack-eventtags-explained","title":"Attack eventTags explained","text":"

This is original attack combo from Gothic 1

ani (\"s_1hAttack\"   1   \"s_1hAttack\"    0.0 0.1 M.  \"Hum_1hAttackComboT3_M05.asc\"   F   1   114)\n{\n    *eventTag       (0 \"DEF_HIT_LIMB\"   \"ZS_RIGHTHAND\")\n    *eventTag       (0 \"DEF_OPT_FRAME\"  \"4 36 73 107\") \n    *eventTag       (0 \"DEF_HIT_END\"    \"31 63 95 113\")\n    *eventTag       (0 \"DEF_WINDOW\"     \"10 33 42 65 78 97 110 113\")\n    *eventSFX       (4  \"Whoosh\"    EMPTY_SLOT  )\n    *eventSFX       (72 \"BACK\"  EMPTY_SLOT  )\n}\n

I will edit it slightly to make it more readable. Let's focus on the DEF_OPT_FRAME, DEF_HIT_END,

ani (\"s_1hAttack\"   1   \"s_1hAttack\"    0.0 0.1 M.  \"Hum_1hAttackComboT3_M05.asc\"   F   1   114)\n{\n    ...\n    *eventTag       (0 \"DEF_OPT_FRAME\"  \"4         36         73         107         \") \n    *eventTag       (0 \"DEF_HIT_END\"    \"      31         63       95             113\")\n    *eventTag       (0 \"DEF_WINDOW\"     \"   10   33     42  65   78  97     110   113\")\n    ...\n}\n

Let's focus only on the first combo.

ani (\"s_1hAttack\"   1   \"s_1hAttack\"    0.0 0.1 M.  \"Hum_1hAttackComboT3_M05.asc\"   F   1   114)\n{\n    ...\n    *eventTag       (0 \"DEF_OPT_FRAME\"  \"4          ...\") \n    *eventTag       (0 \"DEF_HIT_END\"    \"      31   ...\")\n    *eventTag       (0 \"DEF_WINDOW\"     \"   10   33 ...\")\n    ...\n}\n
Frames Animation Description 1 animation start 1..4 swing of the sword 4 sword is in the front of the model DEF_OPT_FRAME - test damage collisions at this frame 4..10 end of the sword swing 10 model stands ready to start next swing DEF_WINDOW - user can press key to advance combo from this frame. 10..31 slight idle 'shake' if player continues combo, animation playback will jump to the frame 33 (DEF_WINDOW second pair), from the animation perspective, next attack starts from pose similar to frame 10. If perfect inputs would be provided, animation would continue perfectly. 31 DEF_HIT_END - ends user input. 31..32 model returns to the idle position 32 idle position, standing with sword in hand animation will end here, if combo not continued (DEF_WINDOW second pair - 1) 33 first frame of the next attack (similar to frame 10) DEF_WINDOW second pair, start of next attack"},{"location":"zengin/anims/events/#eventpfxgrnd","title":"eventPfxGrnd","text":"

Not used anywhere in the original game. Could possibly spawn particle effect like eventPfx but with an added suffix similar to how eventSfxGrnd works. Needs to be investigated.

Syntax:

*eventPFXGRND (FRAME)\n
"},{"location":"zengin/anims/events/#eventsetmesh","title":"eventSetMesh","text":"

Unknown

Syntax:

*eventSETMESH (FRAME \"NODE_NAME\")\n
"},{"location":"zengin/anims/events/#modeltag","title":"modelTag","text":"

Should work similarly to eventTag, but can be defined inside aniEnum block and applies to all animations of the Model.

Syntax:

*modelTag (FRAME \"EVENT_TAG_TYPE\" \"PARAMETER1\" \"PARAMETER2\" \"PARAMETER3\" \"PARAMETER4\" ... )\n
"},{"location":"zengin/anims/mds/","title":"MDS - model animation script","text":""},{"location":"zengin/anims/mds/#mds---model-animation-script","title":"MDS - model animation script","text":"

Tip

The MDS syntax is very simple and scripts can be edited in any text editor. It is, however, easier to work in an editor with a proper syntax highlighting. Daedalus Language Server's dev branch already merged the MDS grammar for syntax highlighting, we can expect it in the next release.

Model animation script is a file describing what skeleton should be used, what body meshes work with this set of animations and how should the animations be named, how fast they run, what animation is supposed to start after the current one is finished and much more. These files are located in Gothic\\_work\\DATA\\Anims\\ directory.

Whilst the code seems long and terrifying, it is in fact rather simple, and this guide will try to explain it whole.

Don't forget to use the search

If you search this file for t_Yes, you will get an example of the first type of animation - \"standalone\"

To play the animation in game you use this console command play ani t_yes.

"},{"location":"zengin/anims/mds/#syntax-and-keywords","title":"Syntax and keywords","text":"

Let us get a quick look at the naming convention to get a basic idea what is going on before we start.

The first letter indicates a type of animation (transition - t_ - or state - s_). Then depending on the animation type we have:

Transition animation

t_Run_2_Sneak\n
Transition animation from the run animation to the sneak animation.
t_BSANVIL_Stand_2_S0\n
Transition animation for the blacksmith's anvil from standing to state 0.

State animation

s_Run\n
State animation for the looping animation.
s_BSANVIL_S0\n
State animation for the blacksmith's anvil and its first state."},{"location":"zengin/anims/mds/#ani","title":"ani","text":"

This is the main command you will be using while defining new animations.

Example:

ani    (\"t_Yes\" 2 \"\" 0.1 0.1 M. \"Hum_Yes_M01.asc\" F 1 44)\n
Syntax:
ani (ANI_NAME LAYER NEXT_ANI BLEND_IN BLEND_OUT FLAGS ASC_NAME ANI_DIR START_FRAME END_FRAME)\n
ani - is a keyword, we are defining new animation

Let's describe all the parameters

ANI_NAME - animation name, we use it in Daedalus as animation identifier

There is a naming convention, that is recommended and sometimes required to be used.

  • prefix t_ - transition animations
  • prefix s_ - state animations - they usually run in a loop
  • prefix c_ - animations used for animation combining/interpolation

LAYER - layer number for multi-layer animations

NEXT_ANI - name of the next animations

BLEND_IN - time in seconds describing animation blending at the start

If we set it to 0.5, it takes 0.5 seconds for this animation to take full effect. At 0.0 s the previous animation has full effect on the bones of the skeleton, at 0.1 s it is influenced by 20% by this animation and at 0.5s it is completely influenced by this animation and the previous one has no effect.

BLEND_OUT - time in seconds describing animation blending at the end

FLAGS - flags, that describe animation behavior

  • M - specifies a movement animation, the animation of the model translates into a changed position in the game world
  • R - the same as M but for rotation
  • E - this flag makes this animation run only, if the animation in the same layer are finished, this is used in the movement animations. The animation s_walk (walking loop animation) runs, when the player is walking,when he stops the transition animation to standing state is played t_walk_2_stand. This animation uses the E flag to wait for the walk cycle animation to finish, to smoothly transition into the standing state.
  • F - the engine ignores height coordinate - doesn't keep the model \"glued\" to the ground (falling/flying animation)
  • I - specifies idle animation - breathing, standing with a drawn weapon and moving the weapon

ASC_NAME - name of the source file exported from Blender

ANI_DIR - direction of the animation

  • F - forward
  • R - reverse

START_FRAME - on what frame from the source file the animation starts

END_FRAME - on what frame from the source file the animation ends

"},{"location":"zengin/anims/mds/#anialias","title":"aniAlias","text":"

Generally considered as one of the most useful commands, aniAlias is used to create an alias (hard link for UNIX users) for an already defined animation.

Example:

aniAlias (\"t_Sneak_2_Run\" 1 \"s_Run\" 0.0    0.1    M. \"t_Run_2_Sneak\" R)\n
Syntax:
aniAlias (ANI_NAME LAYER NEXT_ANI BLEND_IN BLEND_OUT FLAGS ALIAS_NAME ANI_DIR)\n

ANI_NAME - name of the new animation

LAYER - layer the animation is on

NEXT_ANI - name of the next animations

BLEND_IN - time in seconds describing animation blending at the start

BLEND_OUT - time in seconds describing animation blending at the end

FLAGS - flags, that describe animation behavior

ALIAS_NAME - name of the animation we want to use as a source for the alias

ANI_DIR - direction of the animation

If we look for the animation in the example we can see that there is a related one just one line above

ani            (\"t_Run_2_Sneak\" 1 \"s_Sneak\" 0.1 0.0 M. \"Hum_Sneak_M01.asc\"     F 0 10)\naniAlias    (\"t_Sneak_2_Run\" 1 \"s_Run\"      0.0 0.1 M. \"t_Run_2_Sneak\"      R)\n
In this example we are defining t_Sneak_2_Run animation and we are specifying that the animation after this one is finished will be s_Run and that it is being made by reversing animation t_Run_2_Sneak by specifying the R flag."},{"location":"zengin/anims/mds/#aniblend","title":"aniBlend","text":"

AniBlend is used to define animations that are a result of blending of two animations. This animation is not animated by hand, but it is dynamically generated by the engine during run-time.

Example

aniBlend (\"t_RunR_2_Run\" \"s_Run\" 0.2 0.2)\n
Syntax:
aniBlend (ANI_NAME NEXT_ANI BLEND_IN BLEND_OUT)\n

ANI_NAME - name of the new animation

NEXT_ANI - name of the next animations

BLEND_IN - time in seconds describing animation blending at the start

BLEND_OUT - time in seconds describing animation blending at the end

"},{"location":"zengin/anims/mds/#anisync","title":"aniSync","text":"

Not used in the game.

"},{"location":"zengin/anims/mds/#anibatch","title":"aniBatch","text":"

Not used in the game.

"},{"location":"zengin/anims/mds/#animation-state-machine","title":"Animation state machine","text":"

More complex animations such as MOBSI animations form a state machine - an animation set.

MDS script for the big chest
Model (\"CHESTBIG_OCCRATELARGE\")\n{\n    meshAndTree (\"CHESTBIG_OCCRATELARGE.asc\")\n\n    aniEnum\n    {\n// Closed chest\n        ani         (\"s_S0\"                 1   \"s_S0\"  0.0 0.0 M.  \"CHESTBIG_USE.asc\"  F   20  20)\n// Opening the chest \n        ani         (\"t_S0_2_S1\"            1   \"s_S1\"  0.0 0.0 M.  \"CHESTBIG_USE.ASC\"  F   50  79)\n        {\n            *eventSFX   (50 \"chest_try\")\n            *eventSFX   (55 \"chest_open\")\n        }\n// Opened chest\n        ani         (\"s_S1\"                 1   \"s_S1\"  0.0 0.0 M.  \"CHESTBIG_USE.asc\"  F   80  80)\n// Closing the chest\n        ani         (\"t_S1_2_S0\"            1   \"s_S0\"  0.0 0.0 M.  \"CHESTBIG_USE.asc\"  R   50  79)\n        {\n            *eventSFX   (78 \"chest_close\")\n        }\n// Pick lock broken\n        ani         (\"t_S0_Try\"             1   \"s_S0\"  0.0 0.0 M.  \"CHESTBIG_USE.asc\"          F   96  124)\n        {\n            *eventSFX   (100    \"chest_try\")\n            *eventSFX   (115    \"Hammer\")\n        }\n    }\n}\n
stateDiagram-v2\n    s_S0      : Closed chest\n    t_S0_2_S1 : Opening the chest\n    s_S1      : Opened chest\n    t_S1_2_S0 : Closing the chest\n    t_S0_Try  : Pick lock broken\n    [*] --> s_S0\n    s_S0 --> s_S0\n\n    s_S0 --> t_S0_2_S1\n    t_S0_2_S1 --> s_S1\n    s_S1 --> s_S1\n\n    s_S1 --> t_S1_2_S0\n    t_S1_2_S0 --> s_S0\n\n    s_S0 --> t_S0_Try\n    t_S0_Try --> s_S0
"},{"location":"zengin/anims/tutorials/standalone_animation/","title":"Standalone animation","text":""},{"location":"zengin/anims/tutorials/standalone_animation/#standalone-animation","title":"Standalone animation","text":"

Acknowledgment

This tutorial would not be possible without the ZenGin documentation available in the mod-kit. Further credits also go to Mark56 who helped me understand animations in the first place, Fawkes and his request for me to do some animations for his excellent mod - Replay Mod, and last but not least Flosha from the Phoenix team who was the one for whom I offered to write this tutorial to help with the development of the Phoenix project.

Let us start with the easiest animation - a very simple gesturing animation.

Info

You can find some of the videos that are mentioned in the text below in this play-list.

Firstly we have to have the animation source files ready. Best way to decompile them is using Gothic Sourcer. In GothicSourcer you choose Tools > Decompiler models > Dynamic (MDS or MSB) and choose an MDS file of your choice - Humans.mds in our case and then click the decompile button.

"},{"location":"zengin/anims/tutorials/standalone_animation/#animating","title":"Animating","text":"

Open Blender, File > Import > Kerrax ASCII model (.asc), navigate to the folder with your decompiled animation files and select HUM_BODY_NAKED0.ASC. This file contains the skeleton and skin model for human NPCs.

What bone hierarchy is this model using?

If you open the .mds file, you can see a command meshAndTree that specifies what model contains the skeleton. And there lies our answer:

Model (\"HuS\")\n{\n    meshAndTree (\"Hum_Body_Naked0.ASC\" DONT_USE_MESH)\n

A windows pops up and you can read some interesting information about the model you are about to import. We are interested in the fact that Completely replace current scene is ticked, we want to use Armature modifier, and we also want to Try to connect bones and Use sample meshes from folder. You should provide a path to a directory with the sample meshes - these are meshes for items, that usually go into slot bones. Lastly, the space transformation scale should be set to 0.01. This is because ZenGin works with centimeter units and one unit in Blender is a meter.

Click import and wait for the magic to happen.

This video shows a freshly imported model with all default meshes.

Note

If we now want to play (or edit) existing animation, we can now load it on top of this. Just as before File > Import > Kerrax ASCII model (.asc) and select different animation file (or armor file), for example Hum_SmokeHerb_Layer_M01.asc for an animation file.

Gothic characters are modular and you can change their heads on the fly, even during gameplay as seen in this amazing video from my dear friend and colleague Fawkes - Head changing. Let's add a head so that we can see how the whole body will behave while we are animating. File > Import > Kerrax ASCII model (.asc), navigate to your head model. You will have to decompile it like we did with the body itself. We will import HUM_HEAD_PONY.ASC. Please make sure to select the target bone for importing Bip01 Head, this will attach the head to the proper bone, just like the engine does it.

Now we have everything ready to start animating. The video shows the DopeSheet a nice way to edit keyframes.

DopeSheet

Blender's dope sheet can be used to copy entire sets of keyframes. It is useful if we want to create a looping animation.

We can import an animation into Blender as a base.

Tip

If you don't know the name of the animation, just go into the game and make your character perform the animation you want. While in MARVIN mode, you can press G and the animation information together with other info will be displayed right on the screen

In this video we can see that the idle standing animation is s_run. We want to make an animation that is going to start from this idle animation, so we will import it into blender. We find it by looking into the .mds file, look for s_run name and get the name of the file.

ani    (\"s_Run\" 1 \"s_Run\" 0.1 0.1 MI \"Hum_RunAmbient_M01.asc\" F 1 50)  \n
As we can see, we have to import the Hum_RunAmbient_M01.asc file.

Next goes the first trick. Since we want our animation to end exactly, as it started - ether because we want the hero to continue his standing animation, or we want to make a looping animation, we somehow have to copy the pose. We use the DopeSheet screen, to delete all keyframes and then copy the keyframe set from keyframe number 0 and drag it somewhere to the end of the timeline.

Once the animation is done, we have to export it into an asc format again, File > Export > Kerrax ASCII model (.asc) and then save it to _work\\data\\Anims\\asc\\ so the engine can see it and convert it. There are many options here that we will explore later, but we have tick Export animation and pick bones that we want to export - this is useful for animations that are played on different layers (dialogue gestures, scratching head, scratching a shoulder,...).

"},{"location":"zengin/anims/tutorials/standalone_animation/#animation-script","title":"Animation script","text":"

Now that we have exported the animation, we now have to define it in Humans.mds.

Open the file, scroll to the end and define a new animation.

Attention

All ani code has to be between the curly brackets, this means you have to insert it before the last two closing curly brackets } }.

Example:

ani (\"t_backpain\" 1 \"\" 0.0 0.0 M. \"Hum_back.ASC\" F 0 121)  \n

Save the Humans.mds file and try it in game. Nothing happens! The reason is that the mds has been already compiled, and we have to recompile it. The easiest is to go to Anims\\_compiled and delete HUMANS.MSB. Run the game and try to play the animation again (play ani t_backpain in MARVIN console) and now everything should work.

Amazing, now you have your first animation in the game. And you can use it to do some fun stuff, like in dialogues using the AI_PlayAni function.

"},{"location":"zengin/anims/tutorials/standalone_animation/#example-dialogue","title":"Example dialogue","text":"
instance DIA_Xardas_Back (C_INFO)\n{\n    npc         = NONE_100_Xardas;\n    nr          = 11;\n    condition   = DIA_Xardas_Back_Condition;\n    information = DIA_Xardas_Back_Info;\n    permanent   = TRUE;\n    description = \"What's wrong?\";\n};\n\nfunc int DIA_Xardas_Back_Condition () {\n    return TRUE;\n};\n\nfunc void DIA_Xardas_Back_Info () {\n    AI_Output (self, hero, \"DIA_Xardas_MOB_14_00\"); // My back hurts so much.\n\n    // This is our animation!!!!!\n    AI_PlayAni(self, \"T_BACKPAIN\"); \n    AI_Output (self, hero, \"DIA_Xardas_MOB_14_01\"); // How do YOU feel?\n\n    AI_Output (hero, self, \"DIA_Xardas_MOB_14_02\"); // My back is fine.\n    AI_StopProcessInfos(self);\n};\n
"},{"location":"zengin/general_info/directory_structure/","title":"ZenGin directory structure","text":""},{"location":"zengin/general_info/directory_structure/#zengin-directory-structure","title":"ZenGin directory structure","text":"

Modding is all about changing the game files. To achieve that, we have to know the directory (folder) structure of a Gothic game.

\u251c\u2500\u2500 Data\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 $Templates$\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 modvdf\n\u2502\u00a0\u00a0 \u2514\u2500\u2500 Plugins\n\u251c\u2500\u2500 Miles\n\u251c\u2500\u2500 Saves\n\u251c\u2500\u2500 System\n\u2502\u00a0\u00a0 \u2514\u2500\u2500 Autorun\n\u2514\u2500\u2500 _work\n    \u2514\u2500\u2500 DATA\n        \u251c\u2500\u2500 Anims\n        \u2502\u00a0\u00a0 \u2514\u2500\u2500 _Compiled\n        \u251c\u2500\u2500 Meshes\n        \u2502\u00a0\u00a0 \u2514\u2500\u2500 _Compiled\n        \u251c\u2500\u2500 Music\n        \u251c\u2500\u2500 Presets\n        \u251c\u2500\u2500 Scripts\n        \u2502\u00a0\u00a0 \u251c\u2500\u2500 _compiled\n        \u2502\u00a0\u00a0 \u2514\u2500\u2500 content\n        \u2502\u00a0\u00a0     \u2514\u2500\u2500 CUTSCENE\n        \u251c\u2500\u2500 Sound\n        \u251c\u2500\u2500 Textures\n        \u251c\u2500\u2500 Video\n        \u2514\u2500\u2500 Worlds\n
"},{"location":"zengin/general_info/directory_structure/#data","title":"Data","text":"

Data directory contains .vdf volumes of the game. These contain anims.vdf - animations, speech.vdf - dubbing, worlds.vdf - world ZEN files.

"},{"location":"zengin/general_info/directory_structure/#saves","title":"Saves","text":"

Contains saved games.

"},{"location":"zengin/general_info/directory_structure/#system","title":"System","text":"

The system directory contains the game executable, GothicStarter.exe, GothicStarter_mod.exe, configuration .ini files, mod .ini files and mod icons and description .rtf files.

system/Autorun is a Union specific directory, it serves as a default search directory for Daedalus injection scripts with zParserExtender and Union plugins.

"},{"location":"zengin/general_info/directory_structure/#_workdata","title":"_work/DATA","text":"

This is where the magic happens:

  • Anims - contains animations and animated models.
    • _compiled - contains compiled animations.
  • Meshes - contains meshes source and compiled files.
    • _compiled - contains compiled meshes.
  • Music - contains music files.
  • Presets - contains basic presets.
  • Scripts
    • _compiled - contains compiled scripts - .dat files.
    • Content - contains scripts that make up the content of the game.
    • System - contains scripts that make up the menu.
  • Sound - contains sound effects .wav or .ogg format (Union only).
  • Video - contains videos in .bik format.
"},{"location":"zengin/general_info/object_persistence/","title":"Object persistence","text":""},{"location":"zengin/general_info/object_persistence/#object-persistence","title":"Object persistence","text":"

In order to simplify the process of loading and saving data of various types to and from the user's hard-drive, ZenGin implements a simple object persistence system using the zCArchiver class and its derivatives that allow the individual engine classes to implement a routine specifying which data should be saved or loaded from disk and in which manner.

An object that is derived from the zCObject class may overload the Archive and Unarchive virtual methods. The class may then call on an interface provided by the zCArchiver class within these methods which allows it to directly read from or write to a stream using several modes. Those are ASCII and BinSafe by default. There are, however, more options, as is explained below.

"},{"location":"zengin/general_info/object_persistence/#archive-format","title":"Archive format","text":"

In order to better understand how this process works, it would be best to look at an example of a .ZEN file containing an instance of an oCWorld object.

"},{"location":"zengin/general_info/object_persistence/#header","title":"Header","text":"

When you open up a ZenGin archive, you will see the following at the start of the file:

ZenGin Archive\nver 1\nzCArchiverGeneric\nASCII\nsaveGame 0\ndate 7.1.2001 23:9:19\nuser roeske\nEND\nobjects 2594     \nEND\n

Let's look at each of these properties and what they mean:

ZenGin Archive

This simply specifies that the following data is an zCArchiver archive.

ver 1

Version specification. Can be either 0 or 1. Both Gothic 1 and 2 are already on version 1, although version 0 archives can also be occasionally found.

zCArchiverGeneric

Specifies which derived zCArchiver class should be used to read this archive. Accepted values are zCArchiverGeneric for ASCII and Binary archives, and zCArchiverBinSafe for BinSafe archives. More info below. This property might not be present in older archives.

ASCII

This is the most important part of the header as it specifies in which format should the data be stored. There are 4 different modes:

  • ASCII - The simplest one. It stores data in human-readable ASCII notation (not unlike JSON for example). This is usually used when saving data during development and/or testing, while the final version of said data will most likely be stored as BIN_SAFE.
  • ASCII_PROPS - Same as ASCII except with more additional data that the developer can specify for visual clarity. In practice, it is not used anywhere and mostly serves only to prettify debug info (try typing ZWORLD VOBPROPS in the console and look in zSpy ;) ).
  • BINARY - Binary representation of the class instance, which mostly copies the data 1:1 into/from the stream. In practice, this format is only used to store savefiles (.SAV).
  • BIN_SAFE - BinSafe, short for Binary Safe, is an extended version of Binary which stores type information along with the data itself. This is meant to make error checking for invalid data easier. There are other changes which are explained below. Most, if not all world files (.ZEN), are stored in this format.

saveGame 0

Specifies if this archive is a savefile. This property might not be present in older archives.

date 7.1.2001 23:9:19

The date at which this archive was created.

user roeske

The user which created the archive. This property might not be present in older archives.

END

Tells the parses that this is the end of the header.

We may additionally find a property called csum in version 0 archives which stores the checksum of the whole archive. This property is, however, unused and equals 00000000 by default.

In order to correctly read the archive's header across varying engine versions, one should not count on the properties always being in the same order or even being there at all.

If the archive utilizes zCArchiverGeneric then this header will also be followed by a short section specifying the number of object instances in this archive. This value will be used to initialize the objectList, which is an array of pointers where the addresses of loaded objects will be stored for later referencing. This property would be directly part of the main header in older versions.

objects 2594 END  \n

If the archive is created using zCArchiverBinSafe, this data will be stored in the following binary structure:

struct BinSafeArchiveHeader  \n{  \n    uint32_t version;     // Always equals 2 uint32_t objectCount;  // Serves the same function as \"objects n\" uint32_t chunkPos;    // Offset to chunk hash table};\n};  \n
"},{"location":"zengin/general_info/object_persistence/#contents","title":"Contents","text":"

Looking further into the archive, we see what appears to be a nested structure.

[% oCWorld:zCWorld 64513 0]\n    [VobTree % 0 0]\n        childs0=int:1\n        [% zCVobLevelCompo:zCVob 12289 1]\n            pack=int:0\n            presetName=string:\n            bbox3DWS=rawFloat:-71919.9609 -13091.8232 -59900 108999.992 20014.0352 67399.9922 \n            trafoOSToWSRot=raw:0000803f0000000000000000000000000000803f0000000000000000000000000000803f\n            trafoOSToWSPos=vec3:0 0 0\n            vobName=string:LEVEL-VOB\n            visual=string:SURFACE.3DS\n            showVisual=bool:0\n            visualCamAlign=enum:0\n            cdStatic=bool:1\n            cdDyn=bool:0\n            staticVob=bool:0\n            dynShadow=enum:0\n            [visual zCMesh 0 2]\n            []\n            [ai % 0 0]\n            []\n        []\n        ...\n

We primarily differentiate between chunks and properties within ZenGin archives:

"},{"location":"zengin/general_info/object_persistence/#chunks","title":"Chunks","text":"

A chunk is a structure that groups properties together. For most of the time, a chunk represents a class instance. This is, however, not always true as classes may arbitrarily create chunks as is needed. For example, the sample above contains a chunk called VobTree, which does not represent a class instance, but only serves to make the reading of the archive easier.

While in ASCII mode, the start of a chunk is represented using square brackets.

[% oCWorld:zCWorld 64513 0]

There are 4 pieces of data separated by spaces inside the start of each chunk, which are:

  • Object name - The name of the chunk to use while reading. If the chunk has no name, then it will be simply equal to %.
  • Class name - The name of the class which this chunk represents. Class names are stored with their full inheritance hierarchy (e.g. oCMobLadder:oCMobInter:oCMOB:zCVob). In case the chunk is not an object, but an arbitrary chunk, then this field will be equal to % (% can also mean that this chunk is a nullptr). In some cases you may encounter the symbol \u00a7 instead. This means that the object already exists and that the parser should look for it in the objectList using the object index. Using this mechanism, a single instance can be referenced multiple times without worrying about duplicity.
  • Class version - Used to ensure that the data being read is compatible with the current game/engine version, so that there are no mismatches in the data pattern. This value is different for every class and varies between game versions.
  • Object index - An index into the objectList under which this object will be stored. If the class name is equal to \u00a7, then this value will be used to retrieve an existing instance from the objectList.

If this is a Binary archive, the same data will be stored in the following binary structure:

struct BinaryObjectHeader\n{\n    uint32_t    objectSize;        // Size of the whole object in bytes\n    uint16_t    classVersion;\n    uint32_t    objectIndex;\n    char        objectName[];    // Null-terminated string\n    char        className[];    // Null-terminated string\n};\n

Oddly enough, if the archive is BinSafe, then the data will be encoded the same way as in ASCII mode, except that it will be stored as a type-checked property.

struct BinSafeObjectHeader\n{\n    uint32_t    type;    // 0x1 = TYPE_STRING\n    uint16_t    length;    // Length of the text\n    char        text[];    // [% oCWorld:zCWorld 64513 0]\n};\n

In ASCII mode [] represents the end of the current chunk.

"},{"location":"zengin/general_info/object_persistence/#properties","title":"Properties","text":"

We find properties inside the chunks which are key-value pairs that classes use to store the actual data. Each property stores its name, type and value. In ASCII mode the format for this isname=type:value.

For example:

visual=string:SURFACE.3DS

By default, zCArchiver allows to store properties of the following types:

  • Int - A regular 32-bit integer. In ASCII mode, int gets stored as name=int:1, while in Binary mode, it's just the raw value stored as 4 bytes.

  • Byte - A 8-bit integer. ASCII mode doesn't differentiate between Int and Byte, so this will be stored as name=int:1 regardless. Binary mode stores only the single byte.

  • Word - A 16-bit integer. ASCII mode doesn't differentiate between Int and Word, so this will be stored as name=int:1 regardless. Binary mode stores only the 2 bytes.

  • Float - A standard IEEE 754 32-bit floating point number. In ASCII mode the format is name=float:1.0, while in Binary mode the float gets stored raw as 4 bytes.

  • Bool - Stores a single-byte boolean value. In ASCII mode its name=bool:1 and in Binary mode it's a single byte.

  • String - An ASCII encoded string. While in ASCII mode, strings are stored as name=string:value. In Binary mode, strings are NULL terminated.

  • Vec3 - A three component vector, mainly used to store positional data. The ASCII mode format is name=vec3:1.0 1.0 1.0. In Binary mode the three components of the vector are stored in series, which equals to a total size of 12 bytes.

  • Color - A 32-bit color value stored as BGRA. In ASCII mode the color is stored as name=color:255 255 255 255 while in Binary mode it's just 4 raw bytes.

  • Raw - Raw binary data. In order to maintain readability, in ASCII mode this gets stored as a hex encoded string such as name=raw:63D15B07. In Binary mode, only the data itself is stored, without any other info. Be aware that due to this you must know the size of the data beforehand.

  • RawFloat - An array of floats, mainly used to store bounding boxes. In ASCII mode, the floats are stored as name=rawFloat:1.0 1.0 1.0 1.0 1.0 1.0. In Binary mode the floats are stored in series as raw bytes. Same as with Raw, you must know the size of the array beforehand.

  • Enum - An enum value. In ASCII mode, it gets stored as name=enum:1. In Binary mode, it behaves the same as Int.

As you might have noticed, binary mode doesn't perform any kind of checks on if it's reading the right property or even data of the correct type. This is why BinSafe mode exists, as it stores the property type in along with the data itself.

enum TYPE\n{\n    TYPE_STRING        = 0x1,\n    TYPE_INTEGER    = 0x2,\n    TYPE_FLOAT        = 0x3,\n    TYPE_BYTE        = 0x4,\n    TYPE_WORD        = 0x5,\n    TYPE_BOOL        = 0x6,\n    TYPE_VEC3        = 0x7,\n    TYPE_COLOR        = 0x8,\n    TYPE_RAW        = 0x9,\n    TYPE_RAWFLOAT    = 0x10,\n    TYPE_ENUM        = 0x11\n    TYPE_HASH        = 0x12,\n};\n\nstruct BinSafeProperty\n{\n    TYPE type;\n    union\n    {\n        struct\n        {\n            uint16_t    stringLength;\n            char        stringValue[];\n        }\n        uint32_t    integerOrHashOrEnumValue;\n        float        floatValue;\n        uint8_t        byteOrBoolValue;\n        zVEC3        vec3Value;\n        zCOLOR        colorValue;\n        struct\n        {\n            uint16_t    rawLength;\n            char        rawValue[];\n        }\n        struct\n        {\n            uint16_t    rawFloatLength;\n            float        rawFloatValue[];\n        }        \n    };\n};\n

Looking at the enumeration of types, you might notice that BinSafe mode has an additional property type called Hash. BinSafe archives include a hash table which is stored in the following manner:

struct BinSafeHashTable\n{\n    uint32_t chunkCount;\n    for (chunkCount)\n    {\n        uint16_t    stringLength;\n        uint16_t    linearValue;\n        uint32_t    hashValue;\n        char        text[stringLength];\n    }\n};\n

Instead of storing the raw value, properties may save a hash instead, which is then used to look up the corresponding value from the hash table.

"},{"location":"zengin/general_info/object_persistence/#implementation","title":"Implementation","text":"

As mentioned in the opening paragraph, classes may use the described functionality by overloading the Archive and Unarchive virtual methods, which pass an instance of zCArchiver by reference. When the class instance is then serialized and/or parsed, these methods are called and perform the desired serialization/parsing work.

The class uses methods provided by the zCArchiver instance within these routines. These methods return/accept a value of a specific type (e.g. ReadInt/WriteInt), while they do the actual reading/writing work behind the scenes based on the current mode (ASCII/Binary/BinSafe). The programmer writing the class then does not care whether the final archive will be saved as ASCII, Binary or BinSafe, as they only use the zCArchiver Read* and Write* methods.

"},{"location":"zengin/general_info/object_persistence/#a-practical-example","title":"A practical example","text":"

Let's propose that we have a class which is declared like so:

class zCMyClass : public zCObject\n{\npublic:\n\n    zCMyClass()                {}\n    virtual ~zCMyClass()    {}\n\n    virtual void Archive(zCArchiver&);\n    virtual void Unarchive(zCArchiver&);\n\n    int myInt;\n    zCMyClass* myObject;\n    zCMyClass* secondPointerToMyObject;\n\n};\n

The hypothetical class then implements these virtual functions:

void zCMyClass::Archive(zCArchiver& archiver)\n{\n    archiver.WriteInt(\"myInt\", myInt);\n\n    archiver.WriteObject(\"myObject\", myObject);\n\n    archiver.WriteChunkStart(\"myChunk\", 0);\n    archiver.WriteObject(\"secondPointerToMyObject\", secondPointerToMyObject);\n    archiver.WriteChunkEnd();\n}\n\nvoid zCMyClass::Unarchive(zCArchiver& archiver)\n{\n    archiver.ReadInt(\"myInt\", myInt);\n\n    myObject = dynamic_cast<zCMyClass*>(archiver.ReadObject(\"myObject\"));\n\n    archiver.ReadChunkStart(\"myChunk\");\n    secondPointerToMyObject = dynamic_cast<zCMyClass*>(archiver.ReadObject(\"secondPointerToMyObject\"));\n    archiver.ReadChunkEnd();\n}\n

We then initialize the class in the following way:

zCMyClass object;\n\nobject.myInt = 12121212;\n\nobject.myObject = new zCMyClass();\nobject.myObject->myInt = 34343434;\n\nobject.secondPointerToMyObject = object.myObject;\n

If we now serialized, or to use the engine's term \"archived\", this instance into an ASCII archive, the result would look like this:

ZenGin Archive\nver 1\nzCArchiverGeneric\nASCII\nsaveGame 0\ndate 3.7.2022 0:0:0\nuser GMC\nEND\nobjects 2     \nEND\n\n[% zCMyClass 0 0]\n    myInt=int:12121212\n    [myObject zCMyClass 0 1]\n        myInt=int:34343434\n        [myObject % 0 0]\n        []\n        [myChunk % 0 0]\n            [secondPointerToMyObject % 0 0]\n            []\n        []\n    []\n    [myChunk % 0 0]\n        [secondPointerToMyObject \u00a7 0 1]\n        []\n    []\n[]\n

Notice how secondPointerToMyObject doesn't have any contents. The character \u00a7 tells the parser that this object already exists in the objectList, and that instead of creating a new instance, it should return an existing instance which is stored under index 1 in the objectList. This allows an instance to be referenced from multiple places, without the need to worry about duplicity.

If we used Binary or BinSafe mode, we would see a big blob of binary data instead. This would, of course, store the exact same data, although in a slightly less human-readable format.

"},{"location":"zengin/general_info/object_persistence/#final-thoughts","title":"Final thoughts","text":"

We hope this helps you better understand the inner workings of ZenGin. If you want to see how Piranha Bytes went about implementing a much more advanced version of this system for their next engine, check out Genome's object persistence system.

"},{"location":"zengin/general_info/vdfs/","title":"VDFS","text":""},{"location":"zengin/general_info/vdfs/#vdfs","title":"VDFS","text":"

VDFS is the virtual file system used by ZenGin to distribute and store many, but not all, game assets.

"},{"location":"zengin/general_info/vdfs/#tools","title":"Tools","text":"

The community created variety of different modding tools for work with VDFS volumes over the times, such as:

GothicVDFS

  • Viewing
  • Extracting
  • Building .mod and .vdf archives

VDFS Tool

  • Viewing
  • Extracting
  • Building
  • Optimizing
  • Compressing .mod and .vdf archives
"},{"location":"zengin/scripts/","title":"Scripts","text":""},{"location":"zengin/scripts/#scripts","title":"Scripts","text":"

ZenGin uses its own scripting language called Daedalus. It is similar to C programming language, so if you know some C programming, it will be quite easy to get started.

The Scripts directory is where the scripts live. You will be able to find Daedalus script files - .d extension and .src files, that list all files to be compiled.

Daedalus scripts can be edited in any text editor. To get useful features like syntax highlighting you can use community developed tools like

  • Gothic Sourcer
  • Daedalus VS Code extension
"},{"location":"zengin/scripts/classes/c_info/","title":"C_INFO Daedalus class","text":""},{"location":"zengin/scripts/classes/c_info/#c_info-daedalus-class","title":"C_INFO Daedalus class","text":"

Acknowledgment

Heavily inspired by the amazing documentation site Gothic library.

The C_INFO class is used to define dialogues in the game.

"},{"location":"zengin/scripts/classes/c_info/#class-definition","title":"Class definition","text":"

Class definition as it is defined in Scripts/Content/_intern/Classes.d script file.

C_Info Daedalus class
class C_Info\n{\n    var int    npc;         // npc instance has the dialogue\n    var int    nr;          // number of the dialogue (for sorting)\n    var int    important;   // should the npc start the dialogue automatically\n    var func   condition;   // condition function\n    var func   information; // function called on selecting the dialogue\n    var string description; // text in the dialogue box\n    var int    trade;       // should the dialogue show the trade window\n    var int    permanent;   // should the dialogue be permanent or only one time deal\n};\n
"},{"location":"zengin/scripts/classes/c_info/#class-members","title":"Class members","text":"Variable Type Description npc int npc instance to have the dialogue nr int dialogue order number important int npc addresses player automatically condition func condition function whether the dialogue is shown or not information func function called on dialogue selection - contains the dialogue lines and other logic description string text shown in the dialogue box trade int is it a trade dialogue permanent int does the dialogue stay after being played once"},{"location":"zengin/scripts/classes/c_info/#class-member-overview","title":"Class member overview","text":"

Description of the class member variables.

"},{"location":"zengin/scripts/classes/c_info/#npc","title":"npc","text":"

Sets what NPC will have this dialogue instance. Set an NPC instance.

instance Info_Diego_Gamestart (C_INFO)\n{\n    npc    = PC_Thief; // NPC instance for Diego\n    // ...\n};\n
"},{"location":"zengin/scripts/classes/c_info/#nr","title":"nr","text":"

The nr member variables determines the order of shown dialogues. Dialogues are ordered in the ascending order - instances with higher nr are below instances with lower nr.

instance Info_Diego_Gamestart (C_INFO)\n{\n    // ...\n    nr = 1;\n    // ...\n};\n

Note

This is why the end dialogues usually have nr = 999; this is the highest number out of any dialogues therefore will always show up at the bottom. (999 is not the highest number the nr can store, it is just considered the highest number, as there will hardly be 998 dialogue instances for a single character)

"},{"location":"zengin/scripts/classes/c_info/#important","title":"important","text":"

The important member variable determines whether the NPC will automatically address the player or not.

  • important = TRUE - the NPC will address the player
  • important = FALSE - the player has to talk to the NPC

When important is set to TRUE, the description is not needed since the dialogue is never shown in the dialogue box.

Info

If there are multiple important dialogues that satisfy their condition function, they will be played in the order specified by nr.

Tip

important variable is of the type integer, and it is initialized by the engine to the value of 0. If you do not want your dialogue to be important, you can omit the important member variable since it will be initialized to 0 by the engine.

"},{"location":"zengin/scripts/classes/c_info/#condition","title":"condition","text":"

Condition function with signature func int f(). If the function returns TRUE the dialogue is displayed, if it returns FALSE it is not displayed. The function name does not have to follow a particular naming convention, but a naming convention is used throughout all the Gothic scripts: {DialogueName}_Condition.

Conditioned dialogueUnconditioned dialogue
instance Info_Diego_Gamestart (C_INFO)\n{\n    // ...\n    condition = Info_Diego_Gamestart_Condition;\n    // ...\n};\n\nfunc int Info_Diego_Gamestart_Condition()\n{\n    if (Kapitel < 2) // Show only when chapter is less than 2\n    {\n        return TRUE;\n    };\n    return FALSE; // Not needed, but added for readability\n};\n
instance Info_Diego_EXIT_Gamestart(C_INFO)\n{\n    // ...\n    condition = Info_Diego_EXIT_Gamestart_Condition;\n    // ...\n};\n\nfunc int Info_Diego_EXIT_Gamestart_Condition()\n{\n    return TRUE; // or return 1;\n};\n

Tip

It is unnecessary to return FALSE from dialogue conditions, but in other cases it can very rarely cause subtle bugs. It is thus good practice to always return some value, even if that is FALSE.

"},{"location":"zengin/scripts/classes/c_info/#information","title":"information","text":"

The information function contains the function name (without double quotes \"\" as func is a type in Daedalus) that is called when the dialogue option is selected. It contains the lines NPCs will say, items that will be transferred, quests related logic and much more. The function name does not have to follow a particular naming convention, but a naming convention is used throughout all the Gothic scripts: {DialogueName}_Info.

instance Info_Diego_Gamestart (C_INFO)\n{\n    npc         = PC_Thief;\n    nr          = 1;\n    condition   = Info_Diego_Gamestart_Condition;\n    information = Info_Diego_Gamestart_Info;\n    permanent   = FALSE;\n    important   = TRUE;\n};\n\nfunc int Info_Diego_Gamestart_Condition()\n{\n    if (Kapitel < 2)\n    {\n        return TRUE;\n    };\n    return FALSE;\n};\n\nfunc void Info_Diego_Gamestart_Info()\n{\n    AI_Output(self,hero,\"Info_Diego_Gamestart_11_00\"); //I'm Diego.\n    AI_Output(hero,self,\"Info_Diego_Gamestart_15_01\"); //I'm...\n    AI_Output(self,hero,\"Info_Diego_Gamestart_11_02\"); //I'm not interested in who you are. You've just arrived. I look after the new arrivals. That's all for now.\n    AI_Output(self,hero,\"Info_Diego_Gamestart_11_03\"); //If you plan to stay alive for a while, you should talk to me. But of course I won't keep you from choosing your own destruction. Well, what do you think?\n\n    B_Kapitelwechsel(1); // Show the chapter 1 screen\n};\n
"},{"location":"zengin/scripts/classes/c_info/#description","title":"description","text":"

Specify a string that will be shown in the dialogue window.

instance DIA_XARDAS_GMC(C_INFO)\n{\n    // ...\n    description = \"Hello, is this the GMC site?\";\n};\n

"},{"location":"zengin/scripts/classes/c_info/#trade","title":"trade","text":"

If trade is set to TRUE the trading interface will be launched after the content information function is finished.

Fisk's trade dialogue
instance  Stt_311_Fisk_Trade (C_INFO)\n{\n    npc         = Stt_311_Fisk;\n    nr          = 800;\n    condition   = Stt_311_Fisk_Trade_Condition;\n    information = Stt_311_Fisk_Trade_Info;\n    permanent   = TRUE;\n    description = \"Show me your goods.\";\n    trade       = TRUE;\n};\n\nfunc int  Stt_311_Fisk_Trade_Condition()\n{\n    return TRUE;\n};\n\nfunc void  Stt_311_Fisk_Trade_Info()\n{\n    AI_Output (other, self, \"Stt_311_Fisk_Trade_15_00\"); //Show me your goods.\n};\n

Trivia

Trade manager has been added to ZenGin not that long before the release of Gothic 1 (as discussed and discovered on Phoenix the Game Discord server with the acquisition of Gothic version 0.94k). In version 0.94 the trade manager worked quite differently and used a special (nowadays unused) Daedalus class C_ItemReact.

"},{"location":"zengin/scripts/classes/c_info/#permanent","title":"permanent","text":"

Dialogues with permanent = TRUE do not disappear after the dialogue is played. This is used for dialogues where you ask for directions or flavor dialogues for unnamed NPCs.

Bug

Frequently used external function Npc_KnowsInfo which returns true if the dialogue instance has been played has had a bug in the implementation for a long time. This bug made it impossible to use this function with dialogue instances with permanent = TRUE as it would always return FALSE. This has been fixed in Union 1.0m.

"},{"location":"zengin/scripts/classes/c_info/#lego","title":"LeGo","text":"

LeGo implements a lot of useful functions for dialogues. It makes it possible to create Trialogues and change NPCs behaviour by Dialoggestures. Moreover, any Daedalus function can be added to NPCs AI queue via the AI_Function package.

"},{"location":"zengin/scripts/classes/c_info/#zparserextender","title":"zParserExtender","text":"

zParserExtender implements some Quality of Life features for dialogues. More information can be found in Dialogue constants article.

"},{"location":"zengin/scripts/classes/c_info/#af-script-packet","title":"AF Script Packet","text":"

Enhanced Info Manager (implemented using Ikarus and LeGo) adds tons of customizations and additional features to dialogues. More information can be found in the AFSP Enhanced Information Manager article.

"},{"location":"zengin/scripts/classes/c_item/","title":"C_ITEM Daedalus class","text":""},{"location":"zengin/scripts/classes/c_item/#c_item-daedalus-class","title":"C_ITEM Daedalus class","text":"

Acknowledgment

Heavily inspired by the amazing documentation site Gothic library

The C_ITEM class is used to define new items in the game.

"},{"location":"zengin/scripts/classes/c_item/#class-definition","title":"Class definition","text":"

Class definition as it is defined in Scripts/Content/_intern/Classes.d script file.

C_Item Daedalus class
class C_Item\n{\n    // For all Items\n    var int    id;                         // ID of the item\n    var string name;                       // Name of the item\n    var string nameID;                     // Name ID\n    var int    hp;                         // Current health of the item\n    var int    hp_max;                     // Maximum health of the item\n\n    var int    mainflag;                   // Item category flag\n    var int    flags;                      // Item type flag\n    var int    weight;                     // Weight of the item\n    var int    value;                      // Value of the item\n\n    // For weapons\n    var int    damageType;                 // Damage type\n    var int    damageTotal;                // Total amount of damage\n    var int    damage[DAM_INDEX_MAX];      // Array of damage types\n\n    // For armours\n    var int    wear;                       // Flag to specify where to wear an item\n    var int    protection[PROT_INDEX_MAX]; // Protection array of different damage types\n\n    // For food\n    var int    nutrition;                  // The amount of HP healed\n\n    // Ben\u00f6tigte Attribute zum Benutzen des Items\n    var int    cond_atr[3];                // Array of NPC attributes needed to equip the item\n    var int    cond_value[3];              // Array of values corresponding to the cond_atr array\n\n    // Attributes to be changed on equip\n    var int    change_atr[3];              // Array of attributes that will be changed on equip\n    var int    change_value[3];            // Array of values of the attributes defined in change_atr\n\n    // Parser functions\n    var func   magic;\n    var func   on_equip;                   // Called on equpping an item\n    var func   on_unequip;                 // Called on unequipping an item\n    var func   on_state[4];\n\n    var func   owner;                      // Owner of the item: instance name\n    var int    ownerGuild;                 // Owner of the item: guild\n    var int    disguiseGuild;              // NPC guild set when equipping an item\n\n    // 3DS model file\n    var string visual;                     // Item model file\n\n    // NPC mesh change, when equipping an item\n    var string visual_change;              // .asc file\n    var string effect;                     // Effect instance\n\n    var int    visual_skin;                // Texture variation\n\n    var string scemeName;                  // Animation sceme name\n    var int    material;                   // Material of the object\n\n    var int    munition;                   // Ammo instance\n\n    var int    spell;                      // ID if the spell that this item does\n    var int    range;                      // Range of the weapon\n\n    var int    mag_circle;                 // Circle of magic needed to use this item\n\n    var string description;                // The name of the item shown in the preview box\n    var string text[ITM_TEXT_MAX];         // Array of string describing the item (left side)\n    var int    count[ITM_TEXT_MAX];        // Array of integers (the right side)\n\n    // Parameters for displaying items in the inventory\n    var int    inv_zbias                   // How far away is the item from the screen\n    var int    inv_rotx                    // X-axis rotation\n    var int    inv_roty                    // Y-axis rotation\n    var int    inv_rotz                    // Z-axis rotation\n    var int    inv_animate                 // Should the item rotate in the inventory\n};\n

It has many member variables but not all of them are used for every item. It is not necessary to define every one of these variables for every item as it was discussed on InsideGothic.

"},{"location":"zengin/scripts/classes/c_item/#class-members","title":"Class members","text":"

A selection of the most important class members.

"},{"location":"zengin/scripts/classes/c_item/#change_atr--change_value","title":"change_atr & change_value","text":"

change_atr stores the attributes that will be changed by the amount specified in change_value.

NPCs have these attributes:

const int ATR_HITPOINTS      =  0;  // Hit points\nconst int ATR_HITPOINTS_MAX  =  1;  // Max hitpoints\nconst int ATR_MANA           =  2;  // Mana\nconst int ATR_MANA_MAX       =  3;  // Max mana\n\nconst int ATR_STRENGTH       =  4;  // Strength\nconst int ATR_DEXTERITY      =  5;  // Dexterity\nconst int ATR_REGENERATEHP   =  6;  // HP regeneration per second\nconst int ATR_REGENERATEMANA =  7;  // Mana regeneration per second\n

This can be used on all equipable items to change the attributes. As an example we can create a sword that has a 10 point dexterity bonus.

instance ItMw_testSword (C_Item)\n{\n    // some code\n    change_atr[0]   = ATR_DEXTERITY;\n    change_value[0] = 10;\n    // some code\n};\n

Warning

Do not change ATR_HITPOINTS, ATR_MANA, ATR_HITPOINTS_MAX or ATR_MANA_MAX as it will result in unwanted behaviour with max health or max mana.

You can change ATR_HITPOINTS_MAX and ATR_MANA_MAX attributes in on_equip and on_unequip

"},{"location":"zengin/scripts/classes/c_item/#cond_atr--cond_value","title":"cond_atr & cond_value","text":"

cond_atr stores the attributes that will be checked as a requirement to equip an item, the amount specified in cond_value.

The next example sword is equipable only if the NPC has at least 5 strength. If the requirements are not met G_CanNotUse() is called.

instance ItMw_testSword (C_Item)\n{\n    // some code\n    cond_atr[2]     = ATR_STRENGTH;\n    cond_value[2]   = 5;\n    // some code\n};\n

Try injecting the code below zParserExtender to test it in game right away. It is compatible with G2NotR.

instance ItMw_testSword (C_Item)\n{\n    name            = TXT_Spells[10]; // demonstrates the usage of direct constr array access\n\n    mainflag        = ITEM_KAT_NF;\n    flags           = ITEM_SWD;\n    material        = MAT_METAL;\n\n    value           = 10;\n\n    damageTotal     = 10;\n    damagetype      = DAM_EDGE;\n    range           = 100;\n\n    cond_atr[2]     = ATR_STRENGTH;\n    cond_value[2]   = 5;\n\n    change_atr[0]   = ATR_DEXTERITY;\n    change_value[0] = 10;\n\n    visual          = \"ItMw_010_1h_Sword_short_01.3DS\";\n\n    description     = name;\n\n    TEXT[2]         = NAME_Damage;      COUNT[2] = damageTotal;\n    TEXT[3]         = NAME_Str_needed;  COUNT[3] = cond_value[2];\n    TEXT[4]         = NAME_OneHanded;\n    TEXT[5]         = NAME_Value;       COUNT[5] = value;\n};\n
To insert it into the game use insert ItMw_testSword in console."},{"location":"zengin/scripts/classes/c_item/#text--count-arrays","title":"text & count arrays","text":"

These two arrays are used to put information into the item information box. The maximum number of lines is 6. This is defined in the engine, but for script side class definition is declared in the scripts too.

const int ITM_TEXT_MAX = 6;\n
This example shows an item with all elements of TEXT and COUNT array filled.

Note

Please notice the last COUNT element. It did not take the value we entered, but shows 10 which is the value of the item. This behaviour can be changed with Ikarus or Union.

You can find the code below

instance ItMw_testSword (C_Item)\n{\n    name          = TXT_Spells[10];\n\n    mainflag      = ITEM_KAT_NF;\n    flags         = ITEM_SWD;\n    material      = MAT_METAL;\n\n    value         = 10;\n\n    damageTotal   = 10;\n    damagetype    = DAM_EDGE;\n    range         = 100;\n\n    cond_atr[2]   = ATR_STRENGTH;\n    cond_value[2] = 5;\n\n    change_atr[0] = ATR_DEXTERITY;\n    change_value[0] = 10;\n\n    visual        = \"ItMw_010_1h_Sword_short_01.3DS\";\n\n    description   = name;\n\n    TEXT[0]       = \"Line 0\";     COUNT[0]      = 0; \n    TEXT[1]       = \"Line 1\";     COUNT[1]      = 1; \n    TEXT[2]       = \"Line 2\";     COUNT[2]      = 2; \n    TEXT[3]       = \"Line 3\";     COUNT[3]      = 3; \n    TEXT[4]       = \"Line 4\";     COUNT[4]      = 34;\n    TEXT[5]       = \"Line 5\";     COUNT[5]      = 35;\n};\n
"},{"location":"zengin/scripts/classes/c_item/#description--name","title":"description & name","text":"

description - determines the name of the item in the inventory

name - determines the focus name of the item in the world

In the scripts you often find that the description is assigned the value of name.

instance ItMw_testSword (C_Item)\n{\n    name = \"New amazing sword\";\n    // ...\n    description   = name; // description now has the same value as '    // ...name'\n    // ...\n};\n
This is used in the case where you want to show the name of the item on focus too.

There is a second way used in the scripts though with, for example,magic scrolls - the focus name in the world is \"Scroll\" and in inventory the scroll carries the name of the spell. This is how it is done:

instance ItSc_InstantFireball (C_Item)\n{\n    name                 =    NAME_Spruchrolle; // const string = \"Scroll\"\n    // ...\n    description            =     NAME_SPL_InstantFireball; // const string = \"Fireball\"\n    // ...\n};\n
"},{"location":"zengin/scripts/classes/c_item/#hp--hp_max","title":"hp & hp_max","text":"

Both of these parameters are unused.

Trivia

In alpha ZenGin versions the player was able to destroy objects. This feature was abandoned during the course of the development. This video shows the reconstruction of this feature.

"},{"location":"zengin/scripts/classes/c_menu/","title":"C_MENU Daedalus class","text":""},{"location":"zengin/scripts/classes/c_menu/#c_menu-daedalus-class","title":"C_MENU Daedalus class","text":"

Acknowledgment

Heavily inspired by the amazing documentation site Gothic library

Class C_Menu is responsible for the behavior and properties of the game menus (options, save etc.).

"},{"location":"zengin/scripts/classes/c_menu/#class-definition","title":"Class definition","text":"

Class definition as it is defined in Scripts/System/_intern/Menu.d script file.

C_Menu Daedalus class
class C_Menu \n{\n    var     string  backPic;            // Menu background image\n    var     string  backWorld;          // Background ZEN-world of the game menu (Not used)\n    var     int     posx;               // The top left point of the menu on the screen horizontally (X-axis)\n    var     int     posy;               // The top left point of the menu on the screen vertically (Y-axis)\n    var     int     dimx;               // Menu width in virtual coordinates\n    var     int     dimy;               // Menu height in virtual coordinates\n    var     int     alpha;              // Menu transparency\n    var     string  musicTheme;         // Music track of the menu\n    var     int     eventTimerMSec;     // trigger time for the event EVENT_TIMER\n    var     string  items[150];         // Menu items\n    var     int     flags;              // Menu flags\n    var     int     defaultOutGame;     // Menu item highlighted by default when the game is not running\n    var     int     defaultInGame;      // Menu item highlighted by default when the game is running\n};\n
"},{"location":"zengin/scripts/classes/c_menu/#class-members","title":"Class members","text":"Variable Type Description backPic string Menu background image backWorld string Background ZEN-world of the game menu (Not used) posx int The top left point of the menu on the screen horizontally (X-axis) posy int The top left point of the menu on the screen vertically (Y-axis) dimx int Menu width in virtual coordinates dimy int Menu height in virtual coordinates alpha int Menu transparency musicTheme string Music track of the menu eventTimerMSec int The timer that triggered the event in seconds items string Menu items flags int Menu flags defaultOutGame int Menu item highlighted by default when the game is not running defaultInGame int Menu item highlighted by default when the game is running"},{"location":"zengin/scripts/classes/c_menu/#class-member-overview","title":"Class member overview","text":"

Description of the class member variables.

"},{"location":"zengin/scripts/classes/c_menu/#backpic","title":"backPic","text":"

backPic is just a name of background image of the menu in .tga format.

"},{"location":"zengin/scripts/classes/c_menu/#backworld","title":"backWorld","text":"

Deprecated setting

The background world of the game menu in .ZEN format.

"},{"location":"zengin/scripts/classes/c_menu/#posx","title":"posx","text":"

The horizontal position of the top left point of the menu on the screen, in virtual coordinates.

"},{"location":"zengin/scripts/classes/c_menu/#posy","title":"posy","text":"

The vertical position of the top left point of the menu on the screen, in virtual coordinates.

"},{"location":"zengin/scripts/classes/c_menu/#dimx","title":"dimx","text":"

Menu width in virtual coordinates.

"},{"location":"zengin/scripts/classes/c_menu/#dimy","title":"dimy","text":"

Menu height in virtual coordinates.

"},{"location":"zengin/scripts/classes/c_menu/#alpha","title":"alpha","text":"

Menu transparency. Accepts values \u200b\u200bfrom 0 to 255. Without the backPic property specified, the value of this parameter is ignored.

Note

Texture transparency can only be adjusted if the texture has an alpha channel.

"},{"location":"zengin/scripts/classes/c_menu/#musictheme","title":"musicTheme","text":"

Music theme of the menu.

instance MENU_MAIN(C_MENU_DEF)\n{\n    ...\n    musictheme = \"SYS_Menu\";\n    ...\n};\n
All instances of musical themes are stored in a file Scripts/System/Music/MusicInst.d"},{"location":"zengin/scripts/classes/c_menu/#eventtimermsec","title":"eventTimerMSec","text":"

Defines the trigger time for the event EVENT_TIMER in seconds.

The list of constants for all menu events is described in the file Scripts/System/_intern/Menu.d

const int EVENT_UNDEF       = 0;    // Undefined\nconst int EVENT_EXECUTE     = 1;    // Process start event\nconst int EVENT_CHANGED     = 2;    // Menu parameter change event\nconst int EVENT_LEAVE       = 3;    // Menu item focus loss event\nconst int EVENT_TIMER       = 4;    // Timer fire event\nconst int EVENT_CLOSE       = 5;    // Menu close event\nconst int EVENT_INIT        = 6;    // Initialization event\nconst int EVENT_SEL_PREV    = 7;    // Select event of the previous menu item\nconst int EVENT_SEL_NEXT    = 8;    // Select event of the next menu item\n
"},{"location":"zengin/scripts/classes/c_menu/#items","title":"items","text":"

An array of items belonging to this menu. It is possible to use up to 150 items in one menu. The same elements can be used for different menus. The element instance is specified as the value.

// Menu\ninstance MENU_MAIN(C_MENU_DEF)\n{\n    ...\n    items[0]        = \"MENUITEM_MAIN_HEADLINE\";         \n    items[1]        = \"MENUITEM_MAIN_HEADLINE2\";\n    items[2]        = \"MENUITEM_MAIN_NEWGAME\";\n    ...\n};\n\n// Menu elements: labels, checkboxes, sliders, etc.\n\ninstance MENUITEM_MAIN_HEADLINE(C_MENU_ITEM_DEF)\n{\n    ...\n};\n\ninstance MENUITEM_MAIN_HEADLINE2(C_MENU_ITEM_DEF)\n{\n    ...\n};\n\ninstance MENUITEM_MAIN_NEWGAME(C_MENU_ITEM_DEF)\n{\n    ...\n};\n
"},{"location":"zengin/scripts/classes/c_menu/#flags","title":"flags","text":"

Menu flags.

The list of flag constants can be found in the file Scripts/System/_intern/Menu.d

const int MENU_OVERTOP          = 1;    // Show menu over previous menu or in game\nconst int MENU_EXCLUSIVE        = 2;    // Close all previous menus. Only the active menu is displayed\nconst int MENU_NOANI            = 4;    // No animation\nconst int MENU_DONTSCALE_DIM    = 8;    // Don't Scale Menu Sizes\nconst int MENU_DONTSCALE_POS    = 16;   // Empty flag\nconst int MENU_ALIGN_CENTER     = 32;   // Center Align Menu\nconst int MENU_SHOW_INFO        = 64;   // Display information at the bottom of the description menu from menu items text[1]\n
  • MENU_OVERTOP - Flag to display the menu over the previous menu. It is not advisable to use with a transparent menu.
  • MENU_EXCLUSIVE - Hide all menus except the active one. When closed, the previous menu is restored.
  • MENU_NOANI - Animation of minimizing and maximizing windows. The game is mainly used for dialogue windows. You can't enable or disable the animation of dialog windows through scripts. This is done using the animatedWindows setting in the Gothic.ini file.
  • MENU_DONTSCALE_DIM - Scale the menu to fit 640x480 resolution.
  • MENU_DONTSCALE_POS - Empty flag. Not used.
  • MENU_ALIGN_CENTER - Align the menu to the center of the screen.
  • MENU_SHOW_INFO - Display information at the bottom of menu description from menu item text[1].
"},{"location":"zengin/scripts/classes/c_menu/#defaultoutgame","title":"defaultOutGame","text":"

The menu item that is highlighted by default when the game is not running.

A value of -1 enables automatic selection of the first selectable element.

Items with the ~IT_SELECTABLE flag are not selected.

"},{"location":"zengin/scripts/classes/c_menu/#defaultingame","title":"defaultInGame","text":"

Menu item highlighted by default when the game is running.

A value of -1 enables automatic selection of the first selectable element.

Items with the ~IT_SELECTABLE flag are not selected.

"},{"location":"zengin/scripts/classes/c_musicsys_cfg/","title":"C_MUSICSYS_CFG Daedalus class","text":""},{"location":"zengin/scripts/classes/c_musicsys_cfg/#c_musicsys_cfg-daedalus-class","title":"C_MUSICSYS_CFG Daedalus class","text":"

Acknowledgment

Heavily inspired by the amazing documentation site Gothic library

Class C_MusicSys_CFG defines the global settings for the game's music.

An instance of this class is declared only once.

"},{"location":"zengin/scripts/classes/c_musicsys_cfg/#class-definition","title":"Class definition","text":"

Class definition as it is defined in Scripts/System/_intern/Music.d script file.

C_MusicSys_CFG Daedalus class
class C_MusicSys_CFG\n{\n    var float volume;               // Music volume\n    var int   bitResolution;        // Sound quality\n    var int   globalReverbEnabled;  // Enable global reverb\n    var int   sampleRate;           // Frequency\n    var int   numChannels;          // Sound channels\n    var int   reverbBufferSize;     // Reverb buffer size\n};\n
"},{"location":"zengin/scripts/classes/c_musicsys_cfg/#class-members","title":"Class members","text":"Variable Type Description volume float Overall game music volume bitResolution int Sound quality globalReverbEnabled int Enable global reverb sampleRate int Frequency numChannels int Number of sound chanells reverbBufferSize int The size of reverb buffer"},{"location":"zengin/scripts/classes/c_musicsys_cfg/#class-member-overview","title":"Class member overview","text":"

Description of the class member variables.

"},{"location":"zengin/scripts/classes/c_musicsys_cfg/#volume","title":"volume","text":"

The overall volume of the background music (soundtrack). From 0.0 to 1.0.

"},{"location":"zengin/scripts/classes/c_musicsys_cfg/#bitresolution","title":"bitResolution","text":"

Sound quality. 8 or 16 bit.

"},{"location":"zengin/scripts/classes/c_musicsys_cfg/#globalreverbenabled","title":"globalReverbEnabled","text":"

Enable global reverb.

"},{"location":"zengin/scripts/classes/c_musicsys_cfg/#samplerate","title":"sampleRate","text":"

Frequency. From 11050 to 44100.

"},{"location":"zengin/scripts/classes/c_musicsys_cfg/#numchannels","title":"numChannels","text":"

Number of sound channels. From 16 to 32.

"},{"location":"zengin/scripts/classes/c_musicsys_cfg/#reverbbuffersize","title":"reverbBufferSize","text":"

The size of the reverb buffer.

"},{"location":"zengin/scripts/classes/c_musictheme/","title":"C_MUSICTHEME Daedalus class","text":""},{"location":"zengin/scripts/classes/c_musictheme/#c_musictheme-daedalus-class","title":"C_MUSICTHEME Daedalus class","text":"

Acknowledgment

Heavily inspired by the amazing documentation site Gothic library

Class C_MusicTheme describes musical themes.

"},{"location":"zengin/scripts/classes/c_musictheme/#class-definition","title":"Class definition","text":"

Class definition as it is defined in Scripts/System/_intern/Music.d script file.

C_MusicTheme Daedalus class
class C_MusicTheme\n{\n    var string      file;           // Sound file in DirectMusic `.sgt` format\n    var float       vol;            // Sound volume\n    var int         loop;           // Enable cycle\n    var float       reverbMix;      // Reverb mixing\n    var float       reverbTime;     // Reverb time\n    var int         transType;      // Type of transition to the next theme\n    var int         transSubType;   // Subtype of transition to the next theme song\n};\n
"},{"location":"zengin/scripts/classes/c_musictheme/#class-members","title":"Class members","text":"Variable Type Description file string Sound file in DirectMusic .sgt format vol float Sound volume loop int Enable/disable cycle reverbMix float Reverb mixing reverbTime float Reverb time transType int The type of transition to the next theme song transSubType int The subtype of transition to the next theme song"},{"location":"zengin/scripts/classes/c_musictheme/#class-member-overview","title":"Class member overview","text":"

Description of the class member variables.

"},{"location":"zengin/scripts/classes/c_musictheme/#file","title":"file","text":"

DirectMusic sound in *.sgt format or MIDI file.

"},{"location":"zengin/scripts/classes/c_musictheme/#vol","title":"vol","text":"

The volume of the theme song. From 0.0 to 1.0.

"},{"location":"zengin/scripts/classes/c_musictheme/#loop","title":"loop","text":"

Enable/disable theme music looping. Disabled = 0. Enabled = 1.

"},{"location":"zengin/scripts/classes/c_musictheme/#reverbmix","title":"reverbMix","text":"

Reverb mixing. Measured in decibels.

"},{"location":"zengin/scripts/classes/c_musictheme/#reverbtime","title":"reverbTime","text":"

Reverberation time in milliseconds.

"},{"location":"zengin/scripts/classes/c_musictheme/#transtype","title":"transType","text":"

The type of transition to the next theme song.

The list of constants for all transitions types is described in the file Scripts/System/_intern/Music.d

const int TRANSITION_TYPE_NONE          = 1;    // No transition\nconst int TRANSITION_TYPE_GROOVE        = 2;    // Ripple\nconst int TRANSITION_TYPE_FILL          = 3;    // Padding\nconst int TRANSITION_TYPE_BREAK         = 4;    // Break\nconst int TRANSITION_TYPE_INTRO         = 5;    // Introductory\nconst int TRANSITION_TYPE_END           = 6;    // End topic\nconst int TRANSITION_TYPE_ENDANDINTRO   = 7;    // End and start new\n
"},{"location":"zengin/scripts/classes/c_musictheme/#transsubtype","title":"transSubType","text":"

The subtype of transition to the next theme song.

The list of constants for all transitions subtypes is described in the file Scripts/System/_intern/Music.d

const INT TRANSITION_SUB_TYPE_IMMEDIATE = 1;    // Instant transition\nconst INT TRANSITION_SUB_TYPE_BEAT      = 2;    // Rhythmic transition\nconst INT TRANSITION_SUB_TYPE_MEASURE   = 3;    // Gradual transition\n
"},{"location":"zengin/scripts/classes/c_musictheme/#name-features","title":"Name features","text":"

The musical themes of the game are played depending on the game situation. By default, the theme with the _STD (standard) suffix is played. In case of a threat, the _THR (threat) theme will be played. During the combat the _FGT (fight) theme plays.

instance WOO_DAY_STD(C_MUSICTHEME_STANDARD)\n{\n    file = \"woo_daystd.sgt\";\n};\n\ninstance WOO_DAY_THR(C_MUSICTHEME_THREAT)\n{\n    file = \"woo_daythr.sgt\";\n};\n\ninstance WOO_DAY_FGT(C_MUSICTHEME_FIGHT)\n{\n    file = \"woo_dayfgt.sgt\";\n};\n
In addition, the suffix _DAY_ and _NGT_ determines whether the theme should be played on day or night.
instance OWD_DAY_FGT(C_MUSICTHEME_FIGHT)\n{\n    file = \"owp_dayfgt.sgt\";\n};\n\ninstance OWD_NGT_STD(C_MUSICTHEME_STANDARD)\n{\n    file = \"owd_daystd.sgt\";\n};\n

Tip

In G2 the C_MUSICTHEME_STANDARD, C_MUSICTHEME_THREAT and C_MUSICTHEME_FIGHT prototypes are used by default.

"},{"location":"zengin/scripts/classes/c_svm/","title":"C_SVM Daedalus class","text":""},{"location":"zengin/scripts/classes/c_svm/#c_svm-daedalus-class","title":"C_SVM Daedalus class","text":"

Acknowledgment

Heavily inspired by the amazing documentation site Gothic library

The C_SVM class is used to define sound dialogues (smalltalk, reactions) that are defined for every C_NPC.voice.

"},{"location":"zengin/scripts/classes/c_svm/#class-definition","title":"Class definition","text":"

C_SVM class is the only class with variable number of members. The C_SVM definition in the scripts dictates the content of the class. Every Gothic game has a different number of SVM entries. As an interesting information (more than anything else) we include a table with the numbers of voice lines and voices below.

Game voice lines voices Gothic 1 136 17 Gothic Sequel 110 17 (30 planned) Gothic 2 202 19 Gothic 2 Addon 235 19 Chronicles of Myrtana 1346 73 Returning New Balance 495 19"},{"location":"zengin/scripts/classes/c_svm/#rules","title":"Rules","text":"

The number of instances is defined by a constant integer with a specified name read by the engine.

const int SVM_MODULES = 18;\n

Info

The value SVM_MODULES = 18 means 18 SVMs will be parsed by the engine and because the first one, SVM_0, is empty, the final number of voices is 18 - 1 = 17.

Instances of the C_SVM class must have the name SVM_XXX.

instance svm_1(c_svm)\n{\n    // ...\n};\n
The first instance svm_0 is always empty, it is used internally by the engine.
instance svm_0(c_svm) {};\n
"},{"location":"zengin/scripts/classes/c_svm/#usage-in-the-scripts","title":"Usage in the scripts","text":"

While some defined SVMs are used automatically by the engine - the 20 smalltalk lines for example, others are used in the scripts. To instruct the engine to run a specific SVM, external function AI_OutputSVM is used. In the original scripts it is wrapped in a script function B_Say. To reference the SVM, you use the $ symbol followed by the name of the member variable in the C_SVM class definition.

// some code\n    {\n        PrintScreen    (\"Not enough skill points!\", -1,-1,\"FONT_OLD_20_WHITE.TGA\",1);\n        B_Say (self, other, \"$NOLEARNNOPOINTS\");\n    };\n// some code\n
Here the $NOLEARNNOPOINTS references the var string NoLearnNoPoints in SVM.D. The voice is then chosen automatically by the engine.
class C_SVM\n{\n    //...\n\n    // Teacher comments\n    var string NoLearnNoPoints;       // NPC teacher doesn't teach - not enough learning points!\n    var string NoLearnOverMax;        // NPC teacher doesn't teach - cannot teach above 100 points!\n    var string NoLearnYouAlreadyKnow; // You have to know something to become a master!\n    var string NoLearnYoureBetter;    // You are better than the teacher!\n\n    //...\n};\n
"},{"location":"zengin/scripts/extenders/","title":"Daedalus extenders","text":""},{"location":"zengin/scripts/extenders/#daedalus-extenders","title":"Daedalus extenders","text":"

The default scripting language Daedalus can be quite limiting. Over the years the community created quite a few extenders to, well, extend the functionality. Before Union came along, the standard to interface with the engine was the script library Ikarus and a collection of packages LeGo built on top of that. Not so recently, an additional script packet was made (and is actively being worked on) AF Script Packet that offers even more functionality and is built on top of Ikarus & LeGo. With the adoption of Union and plugins the Union system can use a new extender emerged called zParserExtender. Other Union plugins can, of course, implement their own external functions. A lot of scripts are also scattered on the Gothic forums, and documentation of some of them can be found in the Standalone section.

"},{"location":"zengin/scripts/extenders/afsp/","title":"AF Script Packet","text":""},{"location":"zengin/scripts/extenders/afsp/#af-script-packet","title":"AF Script Packet","text":"

Auronen & Fawkes' Script Packet is a script package built on top of Ikarus and LeGo. It implements many features and there is also a Union version which is in its infancy stage.

Note

AFSP's documentation is lacking (@Auronen: \"My fault\"). The authors will host the documentation on GMC.

Contacts Authors Fawkes & Auronen GitHub AFSP Forum AFSP"},{"location":"zengin/scripts/extenders/afsp/afsp_eim/","title":"Enhanced Information Manager","text":""},{"location":"zengin/scripts/extenders/afsp/afsp_eim/#enhanced-information-manager","title":"Enhanced Information Manager","text":"

Warning

This is a quick paste-in of and old version of AFSP's documentation and the information should be taken with a grain of salt. It may not be up-to-date since AFSP is being developed all the time and this is only a demo page.

Enhanced Information Manager allows you to more precisely control the Information Manager (dialogue manager). Change color, font and much more! This package \"scans\" the dialogue string for modifiers and alters the string based on the modifiers you specify.

"},{"location":"zengin/scripts/extenders/afsp/afsp_eim/#initialization","title":"Initialization","text":"

To use this feature you have to:

  1. Add _headers_G[1/2]_EnhancedInfoManager.src or _headers_G[1/2]_All.src to your Gothic.src after Ikarus and LeGo initialization.
  2. Call G12_EnhancedInfoManager_Init(); from your INIT_GLOBAL() function in Startup.d
"},{"location":"zengin/scripts/extenders/afsp/afsp_eim/#change-colour","title":"Change colour","text":"

Set font color for a dialogue choice.

h@[hex color value]\n
Set font color for highlighted dialogue choice.
hs@[hex color value]\n
Example
description = \"h@2a85a3 hs@2ea9d1 This dialogue is blue.\";\n
"},{"location":"zengin/scripts/extenders/afsp/afsp_eim/#change-font","title":"Change font","text":"

Set font itself for a dialogue choice.

f@[font name]\n
Set font itself for highlighted dialogue choice.
fs@[font name]\n
Example
description = \"f@font_old_20_white.tga fs@font_old_10_white.tga This dialogue has a different font, when selected.\";\n
"},{"location":"zengin/scripts/extenders/afsp/afsp_eim/#change-text-alignment","title":"Change text alignment","text":"

Align text left.

al@\n
Align text center.
ac@\n
Align text right.
ar@\n
Example
description = \"al@ This dialogue has LEFT alignment.\";\ndescription = \"ac@ This dialogue has CENTER alignment.\";\ndescription = \"ar@ This dialogue has RIGHT alignment.\";\n
"},{"location":"zengin/scripts/extenders/afsp/afsp_eim/#disable-dialogue","title":"Disable dialogue","text":"

Player cannot highlight (and select) this dialogue.

d@\n
"},{"location":"zengin/scripts/extenders/afsp/afsp_eim/#text-input-field","title":"Text input field","text":"

Input field allows you to turn a dialogue choice into an input text field.

a@\n
Example
INSTANCE DIA_Xardas_Password (C_Info)\n{\n    npc         = NONE_100_Xardas;\n    nr          = 1;\n    condition   = DIA_Xardas_Password_Condition;\n    information = DIA_Xardas_Password_Info;\n    permanent   = FALSE;\n    description = \"a@ What is the password to get to the Mages of Water?\";\n};\n\nFUNC INT DIA_Xardas_Password_Condition () {\n    return TRUE;\n};\n\nFUNC VOID DIA_Xardas_Password_Info () {\n    if (Hlp_StrCmp (InfoManagerAnswer, \"TETRIANDOCH\"))\n    {\n        PrintScreen (\"Yes that is correct!\", -1, -1, \"font_old_10_white.tga\", 3);\n    }\n    else\n    {\n        PrintScreen (\"No that is wrong!\", -1, -1, \"font_old_10_white.tga\", 3);\n    };\n};\n
"},{"location":"zengin/scripts/extenders/afsp/afsp_eim/#dialogue-numbers","title":"Dialogue numbers","text":"

This feature shows a dialogue number next to the dialogue line (visual for Dialogue keyboard controls). To turn this on you just set InfoManagerNumKeysNumbers variable to true. (in your INIT_GLOBAL() function).

InfoManagerNumKeysNumbers = TRUE;\n
"},{"location":"zengin/scripts/extenders/afsp/afsp_eim/#dialogue-keyboard-controls","title":"Dialogue keyboard controls","text":"

Note

This has also been fixed in Union and we noticed a strange behavior with different keyboard layouts.

This feature changes the way number keys affect dialogue selection. The first dialogue is no longer 0 and you highlight the dialogue option by pressing appropriate number.

InfoManagerNumKeysControls = TRUE;\n
"},{"location":"zengin/scripts/extenders/afsp/afsp_eim/#spinners","title":"Spinners","text":"

This is by far the most flashy feature of EIM as it allows you to use left/right arrow keys on a dialogue option to increase/decease numerical value. This can be used in many ways.

This feature is a bit more complex:

  1. Set up a standard dialogue

    Notice

    Notice we are using \"dummy\" as a description, since it is going to get updated. If something goes wrong the \"dummy\" string shows up and you can clearly tell something went wrong.

    INSTANCE PC_Pan_Cook_Meat (C_Info)\n{\n    nr           = 1;\n    condition    = PC_Pan_Cook_Meat_Condition;\n    information  = PC_Pan_Cook_Meat_Info;\n    permanent    = TRUE;\n    description  = \"dummy\"; //Description is updated in PC_Pan_Cook_Meat_Condition\n};\n
  2. Most of the magic takes place in the condition function (apart from the code behind the scenes, of course).

    var int selectedMeat; // global variable for this spinner value\n\nFUNC INT PC_Pan_Cook_Meat_Condition ()\n{\n    if (PLAYER_MOBSI_PRODUCTION == MOBSI_DIALOG_PAN)\n    {\n        var string lastSpinnerID;\n\n        var int total; total = NPC_HasItems (self, ItFoMuttonRaw);\n\n        if (selectedMeat == 0) { selectedMeat = 1; }; //Default initial value\n\n        //Check currently selected spinned ID --> is it this one?\n        if (Hlp_StrCmp (InfoManagerSpinnerID, \"CookMeat\"))\n        {\n            //Setup spinner if spinner ID has changed\n            if (!Hlp_StrCmp (InfoManagerSpinnerID, lastSpinnerID))\n            {\n                //Restore previous value\n                InfoManagerSpinnerValue = selectedMeat;\n            };\n\n            //Page Up/Down quantity\n            InfoManagerSpinnerPageSize = 5;\n\n            //Min/Max value (Home/End keys)\n            InfoManagerSpinnerValueMin = 1;\n            InfoManagerSpinnerValueMax = total;\n\n            //Update number which is shown in description (in case it was changed by _HOOK_VIEWDIALOGCHOICE_HANDLEEVENT\n            selectedMeat = InfoManagerSpinnerValue;\n\n        };\n\n        lastSpinnerID = InfoManagerSpinnerID; //Remember last active spinner ID\n\n        var string newDescription;\n\n        //Spinner ID 'CookMeat'\n        newDescription = \"s@CookMeat Cook some meat: \";\n\n        newDescription = ConcatStrings (newDescription, IntToString (selectedMeat));\n        newDescription = ConcatStrings (newDescription, \" / \");\n        newDescription = ConcatStrings (newDescription, IntToString (total));\n\n        //Update description\n        PC_Pan_Cook_Meat.description = newDescription;\n        return TRUE;\n    };\n\n    return FALSE;\n};\n
  3. We can use the spinner value stored in selectedMeat variable here in the info function to create the meat (or do other stuff with it).

    FUNC VOID PC_Pan_Cook_Meat_Info () {\n    //If we don't have any meat ... don't cook any :)\n    if (!NPC_HasItems (self, ItFoMuttonRaw)) { return; };\n\n    //This should not happen - but you never know!\n    if (selectedMeat < 1) { return; };\n\n    //This should not happen either! but just in case\n    if (selectedMeat > (NPC_HasItems (self, ItFoMuttonRaw))) {\n        selectedMeat = NPC_HasItems (self, ItFoMuttonRaw);\n    };\n\n    NPC_RemoveInvItems (self, ItFoMuttonRaw, selectedMeat);\n    CreateInvItems (self, ItFoMutton, selectedMeat);\n\n    //Reset value for next time\n    selectedMeat = 1;\n};\n
"},{"location":"zengin/scripts/extenders/afsp/afsp_eim/#spinners-full-code-example","title":"Spinners: Full code example","text":"Spinner example
INSTANCE PC_Pan_Cook_Meat (C_Info)\n{\n    nr           = 1;\n    condition    = PC_Pan_Cook_Meat_Condition;\n    information  = PC_Pan_Cook_Meat_Info;\n    permanent    = TRUE;\n    description  = \"dummy\"; //Description is updated in PC_Pan_Cook_Meat_Condition\n};\n\nvar int selectedMeat;\n\nFUNC INT PC_Pan_Cook_Meat_Condition ()\n{\n    if (PLAYER_MOBSI_PRODUCTION == MOBSI_DIALOG_PAN)\n    {\n        var string lastSpinnerID;\n\n        var int total; total = NPC_HasItems (self, ItFoMuttonRaw);\n\n        if (selectedMeat == 0) { selectedMeat = 1; }; //Default initial value\n\n        //Check currently selected spinned ID --> is it this one?\n        if (Hlp_StrCmp (InfoManagerSpinnerID, \"CookMeat\"))\n        {\n            //Setup spinner if spinner ID has changed\n            if (!Hlp_StrCmp (InfoManagerSpinnerID, lastSpinnerID))\n            {\n                //Restore previous value\n                InfoManagerSpinnerValue = selectedMeat;\n            };\n\n            //Page Up/Down quantity\n            InfoManagerSpinnerPageSize = 5;\n\n            //Min/Max value (Home/End keys)\n            InfoManagerSpinnerValueMin = 1;\n            InfoManagerSpinnerValueMax = total;\n\n            //Update number which is shown in description (in case it was changed by _HOOK_VIEWDIALOGCHOICE_HANDLEEVENT\n            selectedMeat = InfoManagerSpinnerValue;\n        };\n\n        lastSpinnerID = InfoManagerSpinnerID; //Remember last active spinner ID\n\n        var string newDescription;\n\n        //Spinner ID 'CookMeat'\n        newDescription = \"s@CookMeat Cook some meat: \";\n\n        newDescription = ConcatStrings (newDescription, IntToString (selectedMeat));\n        newDescription = ConcatStrings (newDescription, \" / \");\n        newDescription = ConcatStrings (newDescription, IntToString (total));\n\n        //Update description\n        PC_Pan_Cook_Meat.description = newDescription;\n        return TRUE;\n    };\n\n    return FALSE;\n};\n\nFUNC VOID PC_Pan_Cook_Meat_Info ()\n{\n    //If we don't have any meat ... don't cook any :)\n    if (!NPC_HasItems (self, ItFoMuttonRaw)) { return; };\n\n    //This should not happen - but you never know!\n    if (selectedMeat < 1) { return; };\n\n    //This should not happen either! but just in case\n    if (selectedMeat > (NPC_HasItems (self, ItFoMuttonRaw)))\n    {\n        selectedMeat = NPC_HasItems (self, ItFoMuttonRaw);\n    };\n\n    NPC_RemoveInvItems (self, ItFoMuttonRaw, selectedMeat);\n    CreateInvItems (self, ItFoMutton, selectedMeat);\n\n    //Reset value for next time\n    InfoManagerSpinnerValue = 1;\n};\n\nINSTANCE PC_Pan_Cook_Meat_Exit (C_Info)\n{\n    nr          = 999;\n    condition   = PC_Pan_Cook_Meat_Exit_Condition;\n    information = PC_Pan_Cook_Meat_Exit_Info;\n    permanent   = TRUE;\n    description = \"End\";\n};\n\nFUNC INT PC_Pan_Cook_Meat_Exit_Condition ()\n{\n    if (PLAYER_MOBSI_PRODUCTION == MOBSI_DIALOG_PAN)\n    {\n        return TRUE;\n    };\n    return FALSE;\n};\n\nFUNC VOID PC_Pan_Cook_Meat_Exit_Info ()\n{\n    if (PLAYER_MOBSI_PRODUCTION != MOBSI_DIALOG_NONE)\n    {\n        PLAYER_MOBSI_PRODUCTION = MOBSI_DIALOG_NONE;\n        hero.aivar[AIV_INVINCIBLE] = FALSE;\n        AI_StopProcessInfos (hero);\n    };\n};\n
"},{"location":"zengin/scripts/extenders/ikarus/","title":"Ikarus","text":""},{"location":"zengin/scripts/extenders/ikarus/#ikarus","title":"Ikarus","text":"

Ikarus is a Daedalus library for Gothic. It exploits the interpreter to allow arbitrary memory access and defines tonne of useful functions for interfacing with the engine.

Contacts Author Sektenspinner & contributors GitHub Ikarus Forum Ikarus

Author Note (by Sektenspinner)

This script package is not called Ikarus for nothing:

One can leave the boundaries of Daedalus behind, but may also crash and burn. For instance, reading from invalid addresses won't trigger a zSpy warning but will result in a desktop crash with an Access Violation. This is not a reason to panic but requires a tolerance for frustration (which can be useful for scripters in general).

Of course, such spectacular-looking errors can be fixed, and with focused and systematic work, something sensible can be achieved.

In short: Extra care is needed! A bug that leads to a crash is not something you want in the release version. But if you work cleanly and test extensively, it's not such a big deal.

A good friend in debugging crashes is undoubtedly PrintDebug. It allows sending messages to zSpy (for example, to narrow down where the crash is occurring). It's worth enabling debug messages by MEM_SetShowDebug and the text filter (Options -> Textfilter) in zSpy.

Note

Ikarus is hosted on GitHub and the documentation is built in. The translation is planned.

"},{"location":"zengin/scripts/extenders/ikarus/constants/","title":"Ikarus User Constants","text":""},{"location":"zengin/scripts/extenders/ikarus/constants/#ikarus-user-constants","title":"Ikarus User Constants","text":"

In the Constants file, you'll find user variables that control various aspects, including the debug output of Ikarus. You can customize these variables to suit your needs.

"},{"location":"zengin/scripts/extenders/ikarus/constants/#mem-helper","title":"MEM-Helper","text":"
  • const string MEM_FARFARAWAY Waypoint where the Mem-Helper is spawned (default: \"TOT\")
  • const string MEM_HELPER_NAME Name of the Mem-Helper (default: \"MEMHLP\")
"},{"location":"zengin/scripts/extenders/ikarus/constants/#debug","title":"Debug","text":"
  • const int zERR_ErrorBoxOnlyForFirst Controls whether only the first error should trigger an error box (default: 1).
  • const int zERR_StackTraceOnlyForFirst Determines if stack traces should be displayed only for the first error (default: 0).
"},{"location":"zengin/scripts/extenders/ikarus/constants/#mem_debug","title":"MEM_Debug","text":"

The MEM_Debug function allows you to set up a custom message channel for debugging purposes. You can adjust the following variables to configure this channel:

  • const string zERR_DEBUG_PREFIX Specifies a prefix to be added to each debug message (default: \"Debug: \").
  • const int zERR_DEBUG_TOSPY Controls whether MEM_Debug messages should be sent to zSpy (default: 1).
  • const int zERR_DEBUG_TYPE Specifies the message type for MEM_Debug messages when sent to zSpy (default: zERR_TYPE_INFO).
  • const int zERR_DEBUG_TOSCREEN Determines whether MEM_Debug messages should be printed to the screen (default: 0).
  • const int zERR_DEBUG_ERRORBOX Allows you to display an error box for MEM_Debug messages (default: 0).
"},{"location":"zengin/scripts/extenders/ikarus/constants/#error-message-types","title":"Error message types","text":"
const int zERR_TYPE_OK    = 0; /* [ungenutzt]        */\nconst int zERR_TYPE_INFO  = 1; /* MEM_Info           */\nconst int zERR_TYPE_WARN  = 2; /* MEM_Warn           */\nconst int zERR_TYPE_FAULT = 3; /* MEM_Error          */\nconst int zERR_TYPE_FATAL = 4; /* [ungenutzt]        */\n
"},{"location":"zengin/scripts/extenders/ikarus/examples/","title":"Ikarus examples","text":""},{"location":"zengin/scripts/extenders/ikarus/examples/#ikarus-examples","title":"Ikarus examples","text":"

A collection of examples ported from the original Ikarus documentation.

Note

The original Ikarus documentation is a part of the code. You can find it in the GitHub repository.

"},{"location":"zengin/scripts/extenders/ikarus/examples/#open-focused-chest-or-door","title":"Open focused chest or door","text":"
func void OpenFocussedChestOrDoor() \n{\n    var oCNpc her; her = Hlp_GetNpc(hero);\n\n    // No focus vob at all?\n    if (!her.focus_vob) \n    {\n        Print (\"No focus!\");\n        return;\n    };\n\n    // Focus vob not a lockable vob?\n    if (!Hlp_Is_oCMobLockable(her.focus_vob))\n    {\n        Print (\"No chest or door in focus!\");\n        return;\n    };\n\n    var oCMobLockable Lockable;\n    Lockable = MEM_PtrToInst (her.focus_vob);\n\n    if (Lockable.bitfield & oCMobLockable_bitfield_locked) \n    {\n        Lockable.bitfield = Lockable.bitfield & ~ oCMobLockable_bitfield_locked;\n        Print (ConcatStrings (\"Opened the following vob: \", Lockable._zCObject_objectName));\n    } \n    else\n    {\n        Print (ConcatStrings ( Lockable._zCObject_objectName, \"wasn't even complete!\"));\n    };\n};\n
"},{"location":"zengin/scripts/extenders/ikarus/examples/#print-camera-position","title":"Print camera position","text":"
func void PrintCameraPos()\n{\n    // Initialize global instances (which only exist once):\n    // Initializes MEM_World, MEM_Game, etc. including MEM_Camera\n    MEM_InitGlobalInst();\n\n    /* The camera object is not a vob (but something abstract), \n    do not know where and how there are position data.\n    I prefer to work on the camera vob : */\n    var zCVob camVob;\n    camVob = MEM_PtrToInst (MEM_Camera.connectedVob);\n\n    /* Here you have to know how the transformation matrix is structured:\n\n    It consists of three vectors, the x, y and z directions of the local coordinate system of the camera vob\n    in world coordinates (where z specifies the\n    line of sight). These vectors are\n    denoted by v1, v2, v3.\n    In addition, in the 4th column there is the translation,\n    that is, the position of the camera.\n\n    v1_x v2_x v3_x x\n    v1_y v2_y v3_y y\n    v1_z v3_z v3_z z\n    0 0 0 0\n\n    The matrix is stored row by row in memory.\n    Since we are interested in the last column are the indices\n    in the trafoWorld Array 3, 7 and 11 that we need. */\n\n    Print (ConcatStrings (\"x: \",IntToString(roundf(camVob.trafoObjToWorld[3]))));\n    Print (ConcatStrings (\"y: \",IntToString(roundf(camVob.trafoObjToWorld[7]))));\n    Print (ConcatStrings (\"z: \",IntToString(roundf(camVob.trafoObjToWorld[11]))));\n};\n
"},{"location":"zengin/scripts/extenders/ikarus/examples/#start-rain","title":"Start rain","text":"
func void StartRain()\n{\n    // Initialize global instances\n    // This also includes Skycontroller\n    MEM_InitGlobalInst(); \n\n    // start at the beginning of the day (12:00 noon)\n    MEM_SkyController.rainFX_timeStartRain = 0; // FLOATNULL constant\n    // end at the end of the day (12:00 noon of the next day)\n    MEM_SkyController.rainFX_timeStopRain = 1065353216; // FLOATONE constant\n\n    /* Note: The start and end times are floating point numbers.\n    * 0 stands for the beginning of the day 1 for the end of the day.\n    * a day in the game begins at 12:00 p.m.\n    * For the structure of the floating point format, google for IEEE-745.*/\n\n    /* Result: rain all day! (unless you are in a zone\n    * in which it snows, then snow all day) */\n};\n
"},{"location":"zengin/scripts/extenders/ikarus/examples/#nested-loop","title":"Nested loop","text":"
// Should enumerate all pairs (x,y) with 0 <= x < max_x, 0 <= j < max_y\n\nfunc void printpairs(var int max_x, var int max_y)\n{\n    // Initialize labels\n    MEM_InitLabels();\n    // PrintDebug should be used, i.e. activate debug output\n    MEM_SetShowDebug (1);\n\n    var int x; var int y; x = 0;\n\n    // while (x < max_x)\n    var int x_loop; x_loop = MEM_StackPos.position;\n    if (x < max_x)\n    { \n        y = 0;\n        // while (y < max_y) \n        var int y_loop; y_loop = MEM_StackPos.position;\n        if (y < max_y)\n        { \n            var string out; out = \"(\";\n            out = ConcatStrings (out, IntToString (x));\n            out = ConcatStrings (out, \", \");\n            out = ConcatStrings (out, IntToString (y));\n            out = ConcatStrings (out, \")\");\n            PrintDebug (out);\n            y += 1;\n\n            // continue y_loop \n            MEM_StackPos.position = y_loop;\n        };\n        x += 1;\n        // continue x_loop\n        MEM_StackPos.position = x_loop;\n    };\n};\n\n/*\n    Output of a call printpairs(4,2) would then be: \n    00:36 Info: 5 U: Skript: (0, 0) .... \n    00:36 Info: 5 U: Skript: (0, 1) .... \n    00:36 Info: 5 U: Skript: (1, 0) .... \n    00:36 Info: 5 U: Skript: (1, 1) .... \n    00:36 Info: 5 U: Skript: (2, 0) .... \n    00:36 Info: 5 U: Skript: (2, 1) .... \n    00:36 Info: 5 U: Skript: (3, 0) .... \n    00:36 Info: 5 U: Skript: (3, 1) .... \n*/\n
"},{"location":"zengin/scripts/extenders/ikarus/examples/#calling-a-function-by-their-name","title":"Calling a function by their name","text":"
// This example doesn't show why MEM_CallByString * is useful, but how to use the function.\n\nvar zCVob someObject;\nfunc int MyFunction(var int param1, var string str1, var int param2, var string str2)\n{\n    Print (ConcatStrings (str1, str2)); //(*)\n    return 100 * param1 + param2;\n};\n\nfunc void foo()\n{ \n    var int result;\n\n    // The following code is in this case equivalent to:\n    // result = MyFunction(42, \"Hello\", 23, \"World!\");\n\n    // Lay the call arguments on the call stack\n    MEM_PushIntParam (42);\n    MEM_PushStringParam (\"Hello \");\n    MEM_PushIntParam (23);\n    MEM_PushStringParam (\"World!\");\n\n    MEM_CallByString (\"MYFUNCTION\");\n\n    // the function puts the result (of type int in this case) on the stack\n    // we pop the int result and save it to a variable\n    result = MEM_PopIntResult();\n\n    // print the result\n    Print (IntToString (result));\n};\n\n/*\n    Note: Since symbol indices are continuous and someObject's symbol index \n    is simply given by someObject itself, could\n    MEM_CallByString(\"MYFUNCTION\"); \n    also be replaced here by \n    MEM_CallByID(someObject + 1);\n*/\n
"},{"location":"zengin/scripts/extenders/ikarus/floats/","title":"Floats","text":""},{"location":"zengin/scripts/extenders/ikarus/floats/#floats","title":"Floats","text":"

This part of ikarus implements support for 32 bit IEEE 754 floats in Daedalus. The script was originally created to edit zFLOAT and zREAL variables, but can also be used to arithmetic operations on real float values (not to be confused with Daedalus floats).

"},{"location":"zengin/scripts/extenders/ikarus/floats/#initialization","title":"Initialization","text":"

The best way to initialize all Ikarus functions is to call MEM_InitAll() in the Init_Global() initialization function.

Warning

If you want to use Ikarus in Gothic 1, it is best to define your own Init_Global() function and call it from every world initialization function.

MEM_InitAll();\n
"},{"location":"zengin/scripts/extenders/ikarus/floats/#implementation","title":"Implementation","text":"

float.d on GitHub

"},{"location":"zengin/scripts/extenders/ikarus/floats/#functions","title":"Functions","text":"

Danger

Ikarus floats are saved as int but it doesn't mean that you can use arithmetic operators on them. All operations on floats must be done with functions listed below.

"},{"location":"zengin/scripts/extenders/ikarus/floats/#mkf","title":"mkf","text":"

(make float) Converts the input integer x to a float value.

func int mkf(var int x)\n
Parameters
  • var int x The input integer

Return value

The function returns the float representation of the input integer x.

"},{"location":"zengin/scripts/extenders/ikarus/floats/#truncf","title":"truncf","text":"

(truncate float) Truncates the decimal part of the input float x.

func int truncf(var int x)\n
Parameters
  • var int x The input float

Return value

The function returns the integer part of the input float x by discarding the decimal part.

"},{"location":"zengin/scripts/extenders/ikarus/floats/#roundf","title":"roundf","text":"

(round float) Rounds the input float x to the nearest integer value.

func int roundf(var int x)\n
Parameters
  • var int x The input float

Return value

The function returns the nearest integer value to the input float x. If the decimal part is exactly halfway between two integers, the function rounds to the nearest even integer.

"},{"location":"zengin/scripts/extenders/ikarus/floats/#addf","title":"addf","text":"

(add floats) Adds two ikarus floats together.

func int addf(var int x, var int y)\n
Parameters
  • var int x The first float
  • var int y The second float

Return value

The function returns the sum of the input floats x and y. (x + y)

"},{"location":"zengin/scripts/extenders/ikarus/floats/#subf","title":"subf","text":"

(subtract floats) Subtracts the second float from the first float.

func int subf(var int x, var int y)\n
Parameters
  • var int x The first float
  • var int y The second float

Return value

The function returns the difference between the first float x and the second float y. (x - y)

"},{"location":"zengin/scripts/extenders/ikarus/floats/#negf","title":"negf","text":"

(negate float) Negates the input float.

func int negf(var int x)\n
Parameters
  • var int x The input float

Return value

The function returns the negation of the input float x.

"},{"location":"zengin/scripts/extenders/ikarus/floats/#mulf","title":"mulf","text":"

(multiply floats) Multiplies two ikarus floats.

func int mulf(var int x, var int y)\n
Parameters
  • var int x The first float
  • var int y The second float

Return value

The function returns the product of multiplying the input floats x and y. (x * y)

"},{"location":"zengin/scripts/extenders/ikarus/floats/#divf","title":"divf","text":"

(divide floats) Divides two ikarus floats.

func int divf(var int x, var int y)\n
Parameters
  • var int x The dividend float
  • var int y The divisor float

Return value

The function returns the quotient of dividing the input float x by y. (x / y)

"},{"location":"zengin/scripts/extenders/ikarus/floats/#invf","title":"invf","text":"

(inverse float) Computes the inverse of the input float.

func int invf(var int x)\n
Parameters
  • var int x The input float

Return value

The function returns the inverse of the x, calculated as 1/x.

"},{"location":"zengin/scripts/extenders/ikarus/floats/#gf","title":"gf","text":"

(greater) Checks if the first float is greater than the second float.

func int gf(var int x, var int y)\n
Parameters
  • var int x The first float
  • var int y The second float

Return value

The function returns TRUE if x is greater than y, FALSE is returned otherwise.

"},{"location":"zengin/scripts/extenders/ikarus/floats/#gef","title":"gef","text":"

(greater or equal) Checks if the first float is greater than or equal to the second float.

func int gef(var int x, var int y)\n
Parameters
  • var int x The first float
  • var int y The second float

Return value

The function returns TRUE if x is greater than or equal to y, FALSE is returned otherwise.

"},{"location":"zengin/scripts/extenders/ikarus/floats/#lf","title":"lf","text":"

(lower) Checks if the first float is less than the second float.

func int lf(var int x, var int y)\n
Parameters
  • var int x The first float
  • var int y The second float

Return value

The function returns TRUE if x is less than y, FALSE is returned otherwise.

"},{"location":"zengin/scripts/extenders/ikarus/floats/#lef","title":"lef","text":"

(lower or equal) Checks if the first float is less than or equal to the second float.

func int lef(var int x, var int y)\n
Parameters
  • var int x The first float
  • var int y The second float

Return value

The function returns TRUE if x is less than or equal to y, FALSE is returned otherwise.

"},{"location":"zengin/scripts/extenders/ikarus/floats/#sqrf","title":"sqrf","text":"

(square float) Calculates the square of the float.

func int sqrf(var int x)\n
Parameters
  • var int x The input float

Return value

The function returns the square of the input float x, computed as x * x.

"},{"location":"zengin/scripts/extenders/ikarus/floats/#sqrtf","title":"sqrtf","text":"

(square root float) Calculates the square root of the float.

func int sqrtf(var int x)\n
Parameters
  • var int x The input float

Return value

The function returns the square root of the input float x.

"},{"location":"zengin/scripts/extenders/ikarus/floats/#sqrtf_approx","title":"sqrtf_approx","text":"

Calculates the approximate square root of a float.

func int sqrtf_approx(var int f)\n
Parameters
  • var int f The input float

Return value

The function returns the approximate square root of the input float as an ikarus float.

"},{"location":"zengin/scripts/extenders/ikarus/floats/#absf","title":"absf","text":"

(absolute value) Computes the absolute value of a float.

func int absf(var int x)\n
Parameters
  • var int x The input float

Return value

The function returns the absolute value of the input float x, which is the value without the negative sign (if present).

"},{"location":"zengin/scripts/extenders/ikarus/floats/#fracf","title":"fracf","text":"

(fraction) Computes the fraction of two integers p and q.

func int fracf(var int p, var int q)\n
Parameters
  • var int p Numerator
  • var int q Denominator

Return value

The function returns the fraction of p divided by q as an ikarus float.

"},{"location":"zengin/scripts/extenders/ikarus/floats/#castfromintf","title":"castFromIntf","text":"

Converts an ikarus float to a Daedalus float.

func float castFromIntf(var int f)\n
Parameters
  • var int f Ikarus float

Return Value

The function returns the value f as a Daedalus float.

"},{"location":"zengin/scripts/extenders/ikarus/floats/#casttointf","title":"castToIntf","text":"

Converts a Daedalus float to an ikarus float.

func int castToIntf(var float f)\n
Parameters
  • var float f Daedalus float

Return Value

The function returns the value f as an ikarus float.

"},{"location":"zengin/scripts/extenders/ikarus/floats/#tostringf","title":"toStringf","text":"

Converts a float value to its string representation.

func string toStringf(var int x)\n
Parameters
  • var int x Input float value

Return value

The function returns a string representation of the input float value.

"},{"location":"zengin/scripts/extenders/ikarus/floats/#printf","title":"printf","text":"

(print float) Prints the float on screen using Print().

func void printf(var int x)\n
Parameters
  • var int x The printed float
"},{"location":"zengin/scripts/extenders/ikarus/floats/#examples","title":"Examples","text":""},{"location":"zengin/scripts/extenders/ikarus/floats/#simple-operations","title":"Simple operations","text":"
var int float1; float1 = mkf(5);        // Create an Ikarus float with value 5\nvar int float2; float2 = mkf(2);        // Create an Ikarus float with value 2\n\nvar int addResult; addResluts  = addf(float1, float2);     // Add float1 and float2\nvar int subResult; subResults  = subf(float1, float2);     // Subtract float2 from float1\nvar int mulResult; mulRelsults = mulf(float1, float2);     // Multiply float1 by float2\nvar int divResult; divResults  = divf(float1, float2);     // Divide float1 by float2\n\nprintf(addResult);   // Output: 7\nprintf(subResult);   // Output: 3\nprintf(mulResult);   // Output: 10\nprintf(divResult);   // Output: 2.5\n
"},{"location":"zengin/scripts/extenders/ikarus/setup/","title":"Ikarus Setup","text":""},{"location":"zengin/scripts/extenders/ikarus/setup/#ikarus-setup","title":"Ikarus Setup","text":""},{"location":"zengin/scripts/extenders/ikarus/setup/#download","title":"Download","text":"

First you need to download ikarus from the official github repository. We recommend using the master branch as it contains the latest and most up-to-date version of Ikarus. However, you can also download a specific release if needed.

"},{"location":"zengin/scripts/extenders/ikarus/setup/#file-location","title":"File location","text":"

Before unpacking the downloaded archive it's needed to create a dedicated folder in <Gothic-dir>\\_work\\Data\\Scripts\\Content directory. You can name this folder as you wish; in this guide, we'll refer to it as the \"MOD\" folder. Unpack the downloaded files into this newly created folder. The archiver should create a folder named Ikarus-master or Ikarus-X.X.X. For better readability change its name to the much simpler Ikarus.

Tip

It's a good practice to delete any unused files, so delete files for other gothic version than this you are using.

"},{"location":"zengin/scripts/extenders/ikarus/setup/#parsing","title":"Parsing","text":"

Ikarus consists of three main parts, constants, classes and the Ikarus core. It's essential to parse these in a specific order. Additionally, there is a floats package which isn't essential, but it is highly recommended to parse it, especially if you are working with LeGo that depends on it.

The Ikarus Core is identical for both Gothic 1 and 2 and is contained in a single file, Ikarus.d. However, there are separate files for the constants and classes for each engine, and they must be parsed correctly. Ikarus uses a C_NPC and therefore has to be parsed after the C_NPC class (after the classes.d file). There are no other dependencies.

Since Ikarus 1.2.1 there is additional .src file for each game engine, to simplify adding files to Gothic.src

Warning

Following example is for Gothic 2. If you are using Gothic 1 replace the G2 at the end of the file/directory name with G1.

Gothic.srcGothic.src (Ikarus 1.2.1+)
_INTERN\\CONSTANTS.D\n_INTERN\\CLASSES.D\nMOD\\IKARUS\\Ikarus_Const_G2.d\nMOD\\IKARUS\\EngineClasses_G2\\*.d\nMOD\\IKARUS\\Ikarus.d\nMOD\\IKARUS\\float.d\n
_INTERN\\CONSTANTS.D\n_INTERN\\CLASSES.D\nMOD\\IKARUS\\IKARUS_G2.SRC\n
"},{"location":"zengin/scripts/extenders/ikarus/setup/#initialization","title":"Initialization","text":"

Before you can use Ikarus in your scripts, it must be properly initialized. The initialization process differs between Gothic 1 and Gothic 2.

"},{"location":"zengin/scripts/extenders/ikarus/setup/#mem_initall","title":"MEM_InitAll","text":"

This is main ikarus initialization function, however it consists of some smaller initialization functions.

DeclarationDefinitionList of functions
func void MEM_InitAll()\n
func void MEM_InitAll() {\n    if (!MEMINT_ReportVersionCheck()) {\n        return;\n    };\n\n    MEM_ReinitParser(); /* depends on nothing */\n    MEM_InitLabels(); /* depends in MEM_ReinitParser */\n    MEM_InitGlobalInst(); /* depends on MEM_ReinitParser */\n\n    /* now I can use MEM_ReplaceFunc, MEM_GetFuncID */\n    MEM_GetAddress_Init(); /* depends on MEM_ReinitParser and MEM_InitLabels */\n    /* now the nicer operators are available */\n\n    MEM_InitStatArrs(); /* depends on MEM_ReinitParser and MEM_InitLabels */\n    ASMINT_Init();\n\n    MEMINT_ReplaceLoggingFunctions();\n    MEMINT_ReplaceSlowFunctions();\n    MEM_InitRepeat();\n\n    /* takes a wail the first time it is called.\n        call it to avoid delay later */\n    var int dump; dump = MEM_GetFuncIDByOffset(0);\n};\n
  • MEM_ReinitParser
  • MEM_InitLabels
  • MEM_InitGlobalInst
  • MEM_GetAddress_Init
  • MEM_InitStatArrs
  • ASMINT_Init
  • MEM_InitRepeat
"},{"location":"zengin/scripts/extenders/ikarus/setup/#gothic-1","title":"Gothic 1","text":"

To initialize Ikarus in Gothic 1 you must define your own INIT_GLOBAL function at the top of the Startup.d file. Then the INIT_GLOBAL should be called in every INIT_<location> function (e.g. INIT_SURFACE,INIT_OLDCAMP etc.). INIT_SUB_<location> functions can be skipped in that process.

Then in your INIT_GLOBAL function you call MEM_InitAll() initialization function.

Startup.d
FUNC VOID INIT_GLOBAL()\n{\n    // Init Ikarus\n    MEM_InitAll ();\n};\n\n// [...]\n\nfunc VOID INIT_SURFACE ()\n{\n    Init_Global();\n    INIT_SUB_SURFACE ();\n};\n// [...]\n
"},{"location":"zengin/scripts/extenders/ikarus/setup/#gothic-2","title":"Gothic 2","text":"

Gothic 2 has its own INIT_GLOBAL function, so the initialization process is much simpler. All you have to do is to call MEM_InitAll() in INIT_GLOBAL function located in the Startup.d file.

Startup.d
FUNC VOID INIT_GLOBAL()\n{\n    // Init Ikarus\n    MEM_InitAll ();\n};\n\n// [...]\n
"},{"location":"zengin/scripts/extenders/ikarus/functions/arrays/","title":"Arrays (zCArray)","text":""},{"location":"zengin/scripts/extenders/ikarus/functions/arrays/#arrays-zcarray","title":"Arrays (zCArray)","text":"

Set of function for working with ZenGin's zCArray data structure.

"},{"location":"zengin/scripts/extenders/ikarus/functions/arrays/#initialization","title":"Initialization","text":"

The best way to initialize all Ikarus functions is to call MEM_InitAll() in the Init_Global() initialization function.

Warning

If you want to use Ikarus in Gothic 1, it is best to define your own Init_Global() function and call it from every world initialization function.

MEM_InitAll();\n
"},{"location":"zengin/scripts/extenders/ikarus/functions/arrays/#implementation","title":"Implementation","text":"

Ikarus.d on GitHub

"},{"location":"zengin/scripts/extenders/ikarus/functions/arrays/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/ikarus/functions/arrays/#mem_arraycreate","title":"MEM_ArrayCreate","text":"

Creates an empty zCArray (allocates memory) and returns a pointer to it.

func int MEM_ArrayCreate()\n
Return value

The function returns a pointer to the created zCArray.

"},{"location":"zengin/scripts/extenders/ikarus/functions/arrays/#mem_arrayfree","title":"MEM_ArrayFree","text":"

Frees the memory allocated for a zCArray and its data.

func void MEM_ArrayFree(var int zCArray_ptr)\n
Parameters
  • var int zCArray_ptr Pointer to the zCArray to be freed
"},{"location":"zengin/scripts/extenders/ikarus/functions/arrays/#mem_arrayclear","title":"MEM_ArrayClear","text":"

Clears the data of a zCArray, freeing the memory used by its elements. The array becomes empty.

func void MEM_ArrayClear (var int zCArray_ptr)\n
Parameters
  • var int zCArray_ptr Pointer to the zCArray to be cleared
"},{"location":"zengin/scripts/extenders/ikarus/functions/arrays/#mem_arraysize","title":"MEM_ArraySize","text":"

Returns the size (number of elements) of an array.

func int MEM_ArraySize(var int zCArray_ptr)\n
Parameters
  • var int zCArray_ptr Pointer to the zCArray

Return value

The function returns a number of a zCArray elements.

"},{"location":"zengin/scripts/extenders/ikarus/functions/arrays/#mem_arraywrite","title":"MEM_ArrayWrite","text":"

Writes a value at a specific position in the zCArray.

func void MEM_ArrayWrite(var int zCArray_ptr, var int pos, var int value)\n
Parameters
  • var int zCArray_ptr Pointer to the zCArray
  • var int pos Position in the array where the value will be written
  • var int value Value to be written
"},{"location":"zengin/scripts/extenders/ikarus/functions/arrays/#mem_arrayread","title":"MEM_ArrayRead","text":"

Reads the value at a specific position in the zCArray.

func int MEM_ArrayRead(var int zCArray_ptr, var int pos)\n
Parameters
  • var int zCArray_ptr Pointer to the zCArray
  • var int pos Position in the array from which the value will be read

Return value

The function returns the value at a specific position in the zCArray.

"},{"location":"zengin/scripts/extenders/ikarus/functions/arrays/#mem_arrayinsert","title":"MEM_ArrayInsert","text":"

Appends a value to the end of the zCArray. The array is automatically resized if it is too small.

func void MEM_ArrayInsert (var int zCArray_ptr, var int value)\n
Parameters
  • var int zCArray_ptr Pointer to the zCArray
  • var int value Value to be inserted
"},{"location":"zengin/scripts/extenders/ikarus/functions/arrays/#mem_arraypush","title":"MEM_ArrayPush","text":"

Alias for MEM_ArrayInsert, inserts a value at the end of the zCArray.

func void MEM_ArrayPush (var int zCArray_ptr, var int value)\n
Parameters
  • var int zCArray_ptr Pointer to the zCArray
  • var int value Value to be inserted
"},{"location":"zengin/scripts/extenders/ikarus/functions/arrays/#mem_arraypop","title":"MEM_ArrayPop","text":"

Removes and returns the last element from the zCArray.

func int MEM_ArrayPop(var int zCArray_ptr)\n
Parameters
  • var int zCArray_ptr Pointer to the zCArray

Return value

The function returns the element removed from the end of an array.

"},{"location":"zengin/scripts/extenders/ikarus/functions/arrays/#mem_arraytop","title":"MEM_ArrayTop","text":"

Returns the last element of the zCArray without removing it.

func int MEM_ArrayTop(var int zCArray_ptr)\n
Parameters
  • var int zCArray_ptr Pointer to the zCArray

Return value

The function returns the last element of an array.

"},{"location":"zengin/scripts/extenders/ikarus/functions/arrays/#mem_arrayindexof","title":"MEM_ArrayIndexOf","text":"

Searches the zCArray for the first occurrence of a value and returns its index.

func int MEM_ArrayIndexOf(var int zCArray_ptr, var int value)\n
Parameters
  • var int zCArray_ptr Pointer to the zCArray
  • var int value Value to search for

Return value

The function returns the index of a first occurrence of a value. If not found -1 is returned.

"},{"location":"zengin/scripts/extenders/ikarus/functions/arrays/#mem_arrayremoveindex","title":"MEM_ArrayRemoveIndex","text":"

Removes the element at a specific index from the zCArray.

func void MEM_ArrayRemoveIndex (var int zCArray_ptr, var int index)\n
Parameters
  • var int zCArray_ptr Pointer to the zCArray
  • var int index Index of the element to be removed
"},{"location":"zengin/scripts/extenders/ikarus/functions/arrays/#mem_arrayremovevalue","title":"MEM_ArrayRemoveValue","text":"

Removes all occurrences of a value from the zCArray.

func void MEM_ArrayRemoveValue (var int zCArray_ptr, var int value)\n
Parameters
  • var int zCArray_ptr Pointer to the zCArray
  • var int value Value to be removed
"},{"location":"zengin/scripts/extenders/ikarus/functions/arrays/#mem_arrayremovevalueonce","title":"MEM_ArrayRemoveValueOnce","text":"

Removes the first occurrence of a value from the zCArray. If value is not found, a warning is issued.

func void MEM_ArrayRemoveValueOnce (var int zCArray_ptr, var int value)\n
Parameters
  • var int zCArray_ptr Pointer to the zCArray
  • var int value Value to be removed
"},{"location":"zengin/scripts/extenders/ikarus/functions/arrays/#mem_arraysort","title":"MEM_ArraySort","text":"

Sorts the elements of the zCArray in ascending order.

func void MEM_ArraySort(var int zCArray_ptr)\n
Parameters
  • var int zCArray_ptr Pointer to the zCArray
"},{"location":"zengin/scripts/extenders/ikarus/functions/arrays/#mem_arrayunique","title":"MEM_ArrayUnique","text":"

Removes duplicate elements from the zCArray.

func void MEM_ArrayUnique(var int zCArray_ptr)\n
Parameters
  • var int zCArray_ptr Pointer to the zCArray
"},{"location":"zengin/scripts/extenders/ikarus/functions/arrays/#mem_arraytostring","title":"MEM_ArrayToString","text":"

Converts the zCArray to a string representation.

func string MEM_ArrayToString (var int zCArray_ptr)\n
Parameters
  • var int zCArray_ptr Pointer to the zCArray

Return value

The function returns a string representation of a given array.

"},{"location":"zengin/scripts/extenders/ikarus/functions/asm/","title":"Ikarus Machine Code Implementation (ASM)","text":""},{"location":"zengin/scripts/extenders/ikarus/functions/asm/#ikarus-machine-code-implementation-asm","title":"Ikarus Machine Code Implementation (ASM)","text":"

Machine code refers to a program or program segment written in machine language, which can be directly executed by a processor without further translation steps. The relevant machine language for us is that belonging to the x86 processor architecture. All machine instructions, what they do, and how they are encoded in machine language can be found in the Intel Manuals.

In practice, dealing with (abstract) machine instructions and manually translating them into (concrete) machine code is rarely necessary due to its complexity.

However, machine code can be useful for performing technical tasks that cannot be expressed in Daedalus directly. For example, the CALL package use the ASM function set as a basis.

Note

The functions in this chapter have the ASM_ prefix for Assembly (language). Assembly language is a human-readable language with one-to-one correspondences to machine language. Strictly speaking, the ASM_ prefix is misleading here, as it pertains to machine code rather than assembly language. However, conceptually, the two are closely related.

"},{"location":"zengin/scripts/extenders/ikarus/functions/asm/#initialization","title":"Initialization","text":"

The best way to initialize all Ikarus functions is to call MEM_InitAll() in the Init_Global() initialization function.

Warning

If you want to use Ikarus in Gothic 1, it is best to define your own Init_Global() function and call it from every world initialization function.

MEM_InitAll();\n
"},{"location":"zengin/scripts/extenders/ikarus/functions/asm/#implementation","title":"Implementation","text":"

Ikarus.d on GitHub

"},{"location":"zengin/scripts/extenders/ikarus/functions/asm/#opcodes","title":"Opcodes","text":"

The code defines several constants that represent different machine code instructions. Each constant is assigned a hexadecimal value and corresponds to a specific machine code instruction. Here is a link to all instructions.

"},{"location":"zengin/scripts/extenders/ikarus/functions/asm/#internal-stack","title":"Internal Stack","text":"

The code includes an internal stack implementation, allowing the storage of data. The stack is already used at two points:

  • When calling an engine function, the address of the current run is stored in the internal stack.
  • When nesting the use of the CALL package, a push and pop operation is performed to manage the context.

The internal stack is implemented using an array, and the following functions are provided:

"},{"location":"zengin/scripts/extenders/ikarus/functions/asm/#asmint_push","title":"ASMINT_Push","text":"

Pushes the specified data onto the internal stack.

func void ASMINT_Push(var int data)\n
Parameters
  • var int data Data pushed onto internal stack
"},{"location":"zengin/scripts/extenders/ikarus/functions/asm/#asmint_pop","title":"ASMINT_Pop","text":"

Pops and returns the topmost data from the internal stack.

func int ASMINT_Pop()\n
Return value

The function returns a data popped form the internal stack.

"},{"location":"zengin/scripts/extenders/ikarus/functions/asm/#functions-core","title":"Functions (Core)","text":"

The ASM core functionality provides a framework for assembling machine code instructions and executing them. The following functions are included:

"},{"location":"zengin/scripts/extenders/ikarus/functions/asm/#asmint_init","title":"ASMINT_Init","text":"

Initializes the ASM system by creating an internal stack and finding function addresses.

func void ASMINT_Init()\n

Tip

It's worth noting that ASMINT_Ini is also invoked by the MEM_InitAll function.

"},{"location":"zengin/scripts/extenders/ikarus/functions/asm/#asm_open","title":"ASM_Open","text":"

Changes the size of the memory allocated at the start o the dictation

The memory in which the machine code is stored is allocated at the beginning of the dictation. If this function isn't called a default size (see Constant below) is allocated by ASM or ASM_Here function. The 256 bytes is often sufficient for simple applications, but if more memory is required, this function must be called at the beginning of the dictation.

func void ASM_Open(var int space)\n
Parameters
  • var int space Space allocated for machine code (in bytes)

Constant

ASM_StandardStreamLength constant defines the default space available for an Assembler sequence (in bytes).

const int ASM_StandardStreamLength = 256;\n
"},{"location":"zengin/scripts/extenders/ikarus/functions/asm/#asm","title":"ASM","text":"

Writes machine code instructions to the stream.

Using this function it is possible to dictate machine code little by little. The data bytes of the length (maximum 4!) are appended to the previously dictated part. This creates a program piece by piece that can be executed by the processor.

func void ASM(var int data, var int length)\n
Parameters
  • var int data The machine code instruction or its part
  • var int length Length of the data (max 4 bytes)
ASM_1ASM_2ASM_3ASM_4"},{"location":"zengin/scripts/extenders/ikarus/functions/asm/#asm_1","title":"ASM_1","text":"

ASM with length parameter hardcoded to 1. Writes one byte machine code instructions to the stream.

func void ASM_1(var int data) \n
Parameters
  • var int data One byte machine code instruction or its part
"},{"location":"zengin/scripts/extenders/ikarus/functions/asm/#asm_2","title":"ASM_2","text":"

ASM with length parameter hardcoded to 2. Writes two bytes machine code instructions to the stream.

func void ASM_1(var int data) \n
Parameters
  • var int data Two bytes machine code instruction or its part
"},{"location":"zengin/scripts/extenders/ikarus/functions/asm/#asm_3","title":"ASM_3","text":"

ASM with length parameter hardcoded to 3. Writes three bytes machine code instructions to the stream.

func void ASM_1(var int data) \n
Parameters
  • var int data Three bytes machine code instruction or its part
"},{"location":"zengin/scripts/extenders/ikarus/functions/asm/#asm_4","title":"ASM_4","text":"

ASM with length parameter hardcoded to 4. Writes four bytes machine code instructions to the stream.

func void ASM_1(var int data) \n
Parameters
  • var int data Four bytes machine code instruction or its part
"},{"location":"zengin/scripts/extenders/ikarus/functions/asm/#asm_here","title":"ASM_Here","text":"

Provides, the address of the cursor, i.e., the address of the location that will be described next by a call to ASM. It is guaranteed that the location where the code is written is also the location where it will be executed.

func int ASM_Here()\n

Return value

The function returns an address that is the current position in the machine code stream.

"},{"location":"zengin/scripts/extenders/ikarus/functions/asm/#asm_close","title":"ASM_Close","text":"

Finalizes the stream by adding a return instruction and returns the starting address of the stream. This pointer can now be passed to at any time and any number of times to execute the machine code.

Warning

The memory area obtained by ASM_Close must be released manually using MEM_Free to avoid memory leaks. It is probably sufficient for almost all practical purposes.

func int ASM_Close()\n
Return value

The function returns a starting address of the stream (pointer to the stream).

"},{"location":"zengin/scripts/extenders/ikarus/functions/asm/#asm_run","title":"ASM_Run","text":"

Executes a machine code (stream) from a pointer.

Note

ASM_Run can also be used to call engine functions with no parameters and no relevant return value. In this case ptr would simply have to point to the function to be executed in the code segment.

func void ASM_Run(var int ptr)\n
Parameters
  • var int ptr Pointer to the executed code (returned form ASM_Close)
"},{"location":"zengin/scripts/extenders/ikarus/functions/asm/#asm_runonce","title":"ASM_RunOnce","text":"

Executes the code dictated up to that point, similar to how an external function is executed. After that the code is released, and new code can be dictated.

func void ASM_RunOnce()\n
"},{"location":"zengin/scripts/extenders/ikarus/functions/asm/#example","title":"Example","text":"

The following function sets the NPC passed as slf as the player, as if you had pressed O in Marvin mode with this NPC in focus. This is so short because there is already a function for this exact purpose, it's just not normally accessible from the scripts. It is therefore sufficient to write assembly code that pushes the parameter of the function (the this pointer) into the appropriate register and then calls the function.

func void SetAsPlayer(var C_NPC slf) { /* Address of the function */\n    const int oCNpc__SetAsPlayer = 7612064; //0x7426A0 (Gothic2.exe)\n\n    var int slfPtr;\n    slfPtr = MEM_InstToPtr (slf);\n\n    //mov ecx slfPtr\n    ASM_1(ASMINT_OP_movImToECX); /* move a value to ecx */\n    ASM_4(slfPtr); /* a value */\n\n    //call oCNpc__SetAsPlayer\n    ASM_1(ASMINT_OP_call);\n    ASM_4(oCNpc__SetAsPlayer - ASM_Here() - 4);\n\n    ASM_RunOnce(); /* return will be added automatically */\n};\n

Note

Call targets are specified relative to the instruction that would have been executed after the actual call instruction. Therefore, both ASM_Here() and the subtraction of 4 in the call parameter are necessary.

The above example describes, among other things, CALL__thiscall function form the CALL Package that can be also used to implement SetAsPlayer.

func void SetAsPlayer(var C_NPC slf) { \n    const int oCNpc__SetAsPlayer = 7612064;\n    CALL__thiscall(MEM_InstToPtr(slf), oCNpc__SetAsPlayer);\n};\n
"},{"location":"zengin/scripts/extenders/ikarus/functions/call/","title":"CALL Package","text":""},{"location":"zengin/scripts/extenders/ikarus/functions/call/#call-package","title":"CALL Package","text":"

This part of Ikarus makes possible to call engine functions directly from scripts.

In order to be able to invoke an engine function, you must know some of its properties. This includes the number and types of parameters, the type of return value, address of function and calling convention.

Knowledge about engine functions can be obtained using tools like IDA, which can analyze and convert GothicMod.exe / Gothic2.exe into a more human-readable format.

Info

In fact, machine code execution (ASM) is part of the CALL package, but due to its complexity, this functionality is discussed in a separate article.

"},{"location":"zengin/scripts/extenders/ikarus/functions/call/#initialization","title":"Initialization","text":"

The best way to initialize all Ikarus functions is to call MEM_InitAll() in the Init_Global() initialization function.

Warning

If you want to use Ikarus in Gothic 1, it is best to define your own Init_Global() function and call it from every world initialization function.

MEM_InitAll();\n
"},{"location":"zengin/scripts/extenders/ikarus/functions/call/#implementation","title":"Implementation","text":"

Ikarus.d on GitHub

"},{"location":"zengin/scripts/extenders/ikarus/functions/call/#call-modes","title":"Call modes","text":"

There are two modes:

"},{"location":"zengin/scripts/extenders/ikarus/functions/call/#disposable","title":"Disposable","text":"

The simple mode that produces a disposable call that is used only once. All parameters are hardcoded.

func int hero_GetAssessEnemy() {\n    const int oCNpc__GetPerceptionFunc = 7726080; //0x75E400\n\n    CALL_IntParam(_@(PERC_ASSESSENEMY));\n    CALL_PutRetValTo(_@(funcID));\n    CALL__thiscall(_@(hero), oCNpc__GetPerceptionFunc);\n\n    var int funcID;\n    return +funcID;\n};\n
"},{"location":"zengin/scripts/extenders/ikarus/functions/call/#recyclable","title":"Recyclable","text":"

The second version produces code that can be used more than once. Instead of the parameters the user specifies the address where the parameters are to be taken from. In addition to executing the code, the user will receive an address that he can use to repeat the call. This is much faster than rebuilding the call from scratch.

func int Npc_GetPercFunc(var C_Npc npc, var int type) {\n    const int oCNpc__GetPerceptionFunc = 7726080; //0x75E400\n\n    var int npcPtr; npcPtr = _@(npc);\n\n    const int call = 0;\n    if (CALL_Begin(call)) {\n        CALL_IntParam(_@(type));\n        CALL_PutRetValTo(_@(funcID));\n        CALL__thiscall(_@(npcPtr), oCNpc__GetPerceptionFunc);\n        call = CALL_End();\n    };\n\n    var int funcID;\n    return +funcID;\n};\n

Receives a pointer. In case the pointer is non-zero, the code at this position is executed and 0 is returned. In case pointer is zero, the current mode is changed into recyclable mode, this means that the call functions expect instructions to build a recyclable call. This mode will continue until CALL_End(). This allows code like this:

"},{"location":"zengin/scripts/extenders/ikarus/functions/call/#start-and-end","title":"Start and End","text":""},{"location":"zengin/scripts/extenders/ikarus/functions/call/#call_open","title":"CALL_Open","text":"

Initializes a Recyclable call mode.

func void CALL_Open()\n
"},{"location":"zengin/scripts/extenders/ikarus/functions/call/#call_begin","title":"CALL_Begin","text":"

A practical wrapper for CALL_Open. Makes a call if it had been already created, initializes it otherwise.

func int CALL_Begin(var int ptr)\n
Parameters
  • var int ptr Zero if you need to create a new recyclable function to be called (usually, before first use). In this case CALL_Open is called and CALL_Begin returns 1.

Return Value

The function returns 1 if the new call has been created, 0 is returned otherwise.

"},{"location":"zengin/scripts/extenders/ikarus/functions/call/#call_close","title":"CALL_Close","text":"

Finalizes a function call in recyclable mode, restoring the previous execution context.

func int CALL_Close()\n
"},{"location":"zengin/scripts/extenders/ikarus/functions/call/#call_end","title":"CALL_End","text":"

Finalizes a function call, pushes the pointer onto the stack, and runs the associated assembly code (makes an actual call).

func int CALL_End()\n

Return Value

The function returns a pointer that could be used to repeat the call.

Tip

CALL_Close only finalizes the function call, returning the pointer, while CALL_End additionally handles pushing the pointer onto the stack and running associated assembly code.

"},{"location":"zengin/scripts/extenders/ikarus/functions/call/#passing-parameters","title":"Passing parameters","text":"

Parameters must be arranged on the machine stack from right to left i.e. from the parameter on the far right to the parameter on the far left. These functions generate machine code that will place parameters on the machine stack when executed.

Note

These functions do not impose any parameters on the Machine stack. Exactly it should say: You create the machine code that will put parameters on the machine stack when it is executed. And it is only carried out in the second step with the announcement of the calling convention.

"},{"location":"zengin/scripts/extenders/ikarus/functions/call/#call_intparam","title":"CALL_IntParam","text":"

Passes an integer (int32) as a parameter to the called function.

func void CALL_IntParam(var int param)\n
Parameters
  • var int param Address of an integer to be passed
"},{"location":"zengin/scripts/extenders/ikarus/functions/call/#call_floatparam","title":"CALL_FloatParam","text":"

Passes an IEEE 7554 floating-point number (single / zREAL) as a parameter to the called function.

func void CALL_FloatParam(var int param)\n
Parameters
  • var int param Address of a float to be passed
"},{"location":"zengin/scripts/extenders/ikarus/functions/call/#call_ptrparam","title":"CALL_PtrParam","text":"

Passes a pointer (void*) as a parameter to the called function.

func void CALL_PtrParam(var int param)\n
Parameters
  • var int param Pointer to be passed
"},{"location":"zengin/scripts/extenders/ikarus/functions/call/#call_zstringptrparam","title":"CALL_zStringPtrParam","text":"

Passes a string (zString*) as a parameter to the called function.

func void CALL_zStringPtrParam(var string param)\n
Parameters
  • var string param String to be passed

Warning

This function only works when writing a disposable call!

"},{"location":"zengin/scripts/extenders/ikarus/functions/call/#call_cstringptrparam","title":"CALL_cStringPtrParam","text":"

Passes a char array (char **) as a parameter to the called function.

func void CALL_cStringPtrParam(var string param)\n
Parameters
  • var string param String to be passed as character array`

Warning

This function only works when writing a disposable call!

"},{"location":"zengin/scripts/extenders/ikarus/functions/call/#call_structparam","title":"CALL_StructParam","text":"

Passes a structure (struct) as a parameter to the called function.

func void CALL_StructParam(var int ptr, var int words)\n
Parameters
  • var int param Pointer to the object
  • var int words Size of a structure (1 word = 32 bits)

Note

CALL_IntParam, CALL_FloatParam, and CALL_PtrParam are functionally identical and are differentiated for code readability.

"},{"location":"zengin/scripts/extenders/ikarus/functions/call/#the-call","title":"The call","text":"

The calling convention determines how the function's parameters are passed. IDA or another disassembler can be used to identify the convention used by a specific engine function.

The announcement of the calling convention, i.e. the call of one of the four functions below is also the time of calling the function. In particular, all parameters must already be specified at this point.

"},{"location":"zengin/scripts/extenders/ikarus/functions/call/#call__stdcall","title":"CALL__stdcall","text":"

Calls a function with __stdcall (Standard Call) calling convention.

func void CALL__stdcall(var int adr)\n
Parameters
  • var int adr Address of a function
"},{"location":"zengin/scripts/extenders/ikarus/functions/call/#call__thiscall","title":"CALL__thiscall","text":"

Calls a function with __thiscall calling convention. Used with a member functions.

func void CALL__thiscall(var int this, var int adr)\n
Parameters
  • var int this Pointer to the owner class object passed as a this parameter
  • var int adr Address of a function
"},{"location":"zengin/scripts/extenders/ikarus/functions/call/#call__cdecl","title":"CALL__cdecl","text":"

Calls a function with __cdecl calling convention. Used with non-Windows API and non-class functions.

func void CALL__cdecl (var int adr)\n
Parameters
  • var int adr Address of a function
"},{"location":"zengin/scripts/extenders/ikarus/functions/call/#call__fastcall","title":"CALL__fastcall","text":"

Calls a function with __fastcall calling convention.

func void CALL__fastcall(var int ecx, var int edx, var int adr)\n
Parameters
  • var int ecx First parameter of a function
  • var int edx Second parameter of a function
  • var int adr Address of a function
"},{"location":"zengin/scripts/extenders/ikarus/functions/call/#return-value","title":"Return Value","text":"

As soon as the function call has taken place, i.e. after step 2, the return value can be queried. The following functions interpret the return value (usually this is the content of EAX immediately after the call) in the manner suggested in the function name. The result is then returned in a manner usable in Daedalus.

Note

Some return values are not stored in the EAX. In that case the call of the special function RetValIs is required to get the return value.

Following functions are provided: CALL_RetValIsFloat, CALL_RetValIszString, CALL_RetValIsStruct.

"},{"location":"zengin/scripts/extenders/ikarus/functions/call/#call_putretvalto","title":"CALL_PutRetValTo","text":"

Simply places the return value to the given address (mostly the address of a daedalus integer). Must be called before The Call function.

func void CALL_PutRetValTo(var int adr)\n
Parameters
  • var int adr Destination address of the return value
"},{"location":"zengin/scripts/extenders/ikarus/functions/call/#call_retvalasint","title":"CALL_RetValAsInt","text":"

Retrieves an integer returned by the called function.

func int CALL_RetValAsInt()\n
Return value

The function returns an integer returned by the previously called engine function.

"},{"location":"zengin/scripts/extenders/ikarus/functions/call/#call_retvalisfloat","title":"CALL_RetValIsFloat","text":"

Specifies that the return value is a float. Must be called before The Call function to allow getting the return value with CALL_RetValAsFloat.

func void CALL_RetValIsFloat()\n
"},{"location":"zengin/scripts/extenders/ikarus/functions/call/#call_retvalasfloat","title":"CALL_RetValAsFloat","text":"

Retrieves a float returned by the called function.

func int CALL_RetValAsFloat()\n
Return value

The function returns a float returned by the previously called engine function.

"},{"location":"zengin/scripts/extenders/ikarus/functions/call/#call_retvalasptr","title":"CALL_RetValAsPtr","text":"

Retrieves a pointer (void*) returned by the called function.

func int CALL_RetValAsPtr()\n
Return value

The function returns a pointer returned by the previously called engine function.

"},{"location":"zengin/scripts/extenders/ikarus/functions/call/#call_retvalisstruct","title":"CALL_RetValIsStruct","text":"

Specifies that the return value is a Structure. Must be called before The Call function to allow getting the return value with CALL_RetValAsStructPtr.

func void CALL_RetValIsStruct(var int size)\n
Parameters
  • var int size Size of the returned structure in bytes

Danger

If the return value is a structure with a size larger than 32 bit, the space for the return value has to be allocated by the caller (this is us).The address to the allocated memory is expected on the stack as an additional parameter (pushed last).

Warning

It is in your responsibility to free the structure memory, when the return value is not needed any more.

"},{"location":"zengin/scripts/extenders/ikarus/functions/call/#call_retvalasstructptr","title":"CALL_RetValAsStructPtr","text":"

Retrieves a pointer to the structure returned by the called function and converts it to the instance. Can be used to make an assignment to an instance, for example an assignment to a var zCVob if the return value is a pointer to a zCVob.

func MEMINT_HelperClass CALL_RetValAsStructPtr()\n
Return value

The function returns an instance returned by the previously called engine function.

"},{"location":"zengin/scripts/extenders/ikarus/functions/call/#call_retvaliszstring","title":"CALL_RetValIszString","text":"

Specifies that the return value is a zString (20 bytes structure). Must be called before The Call function to allow getting the return value with CALL_RetValAszStringPtr and CALL_RetValAszString.

func string CALL_RetValAszString()\n

Note

CALL_RetValAszStringPtr and CALL_RetValAszString are quite different and should not be confused. Using CALL_RetValAszString frees up memory that may still be needed. In a reverse with CALL_RetValAszStringPtr memory that is no longer needed is not freed and can cause memory leak.

"},{"location":"zengin/scripts/extenders/ikarus/functions/call/#call_retvalaszstringptr","title":"CALL_RetValAszStringPtr","text":"

Retrieves a zString pointer and converts it to the daedalus string. (don't frees the memory)

func string CALL_RetValAszStringPtr()\n
Return value

The function returns a daedalus string form a zString returned by the previously called engine function.

"},{"location":"zengin/scripts/extenders/ikarus/functions/call/#call_retvalaszstring","title":"CALL_RetValAszString","text":"

Retrieves a zString pointer and converts it to the daedalus string. (frees the memory)

func string CALL_RetValAszString()\n
Return value

The function returns a daedalus string form a zString returned by the previously called engine function.

Function author note

A zString is merely a special case of a structure, with the difference, that it is used as a primitive datatype. Nobody will be willing to use it as a pointer to some memory or an instance in Daedalus. This function copies the contents of the zString into a daedalus string and frees the zString afterwards.

"},{"location":"zengin/scripts/extenders/ikarus/functions/call/#examples","title":"Examples","text":""},{"location":"zengin/scripts/extenders/ikarus/functions/call/#apply-overlay-disposable","title":"Apply overlay (Disposable)","text":"
// .text:0072D2C0:int __thiscall oCNpc::ApplyOverlay(class zSTRING const &)\n\nfunc void example1(){\n    const int oCNpc__ApplyOverlay = 7525056; //0x72D2C0 (G2A)\n    CALL_zStringPtrParam (\"HUMANS_MILITIA.MDS\");\n    CALL__thiscall (MEM_InstToPtr (hero), oCNpc__ApplyOverlay);\n    //We are not interested in the return value here.\n};\n
"},{"location":"zengin/scripts/extenders/ikarus/functions/call/#get-time-as-string-disposable","title":"Get time as string (Disposable)","text":"

e.g. \"7:30\" for half past seven in the morning

// .text:00780EC0:class zSTRING __thiscall oCWorldTimer::GetTimeString(void)\n\nfunc void example2(){\n    const int oCWorldTimer__GetTimeString = 7868096; //780EC0 (G2A)\n    CALL_RetValIszString();\n    CALL__thiscall (MEM_InstToPtr (MEM_WorldTimer), oCWorldTimer__GetTimeString );\n    PrintDebug (CALL_RetValAszString());\n};\n
"},{"location":"zengin/scripts/extenders/ikarus/functions/call/#get-the-sky-time-disposable","title":"Get the \"sky time\" (Disposable)","text":"

Sky time is a floating point value between 0 and 1 that jumps back from 1 to 0 at noon.

// .text:00781240:float __thiscall oCWorldTimer::GetSkyTime(void)\n\nfunc int GetSkyTime() {\n    const int oCWorldTimer__GetSkyTime = 7868992; //0x781240\n    CALL_RetValIsFloat();\n    CALL__thiscall (MEM_InstToPtr (MEM_WorldTimer),\n    oCWorldTimer__GetSkyTime);\n\n    return CALL_RetValAsFloat();\n};\n
"},{"location":"zengin/scripts/extenders/ikarus/functions/call/#delete-vob-recyclable","title":"Delete Vob (Recyclable)","text":"

Call of the oCWorld.RemoveVob. MEM_DeleteVob is an ikarus built-in function.

func void MEM_DeleteVob(var int vobPtr) {\n    var int world; world = MEM_Game._zCSession_world;\n\n    const int call = 0;\n    if (CALL_Begin(call)) {\n        /* oCWorld.RemoveVob */\n        CALL_IntParam(_@(vobPtr));\n        CALL__thiscall(_@(world), MEMINT_SwitchG1G2(7171824, 7864512));\n\n        call = CALL_End();\n    };\n};\n
"},{"location":"zengin/scripts/extenders/ikarus/functions/debug/","title":"Debug","text":""},{"location":"zengin/scripts/extenders/ikarus/functions/debug/#debug","title":"Debug","text":"

A set of debugging and error-handling functions for mod development with Ikarus.

"},{"location":"zengin/scripts/extenders/ikarus/functions/debug/#initialization","title":"Initialization","text":"

The best way to initialize all Ikarus functions is to call MEM_InitAll() in the Init_Global() initialization function.

Warning

If you want to use Ikarus in Gothic 1, it is best to define your own Init_Global() function and call it from every world initialization function.

MEM_InitAll();\n
"},{"location":"zengin/scripts/extenders/ikarus/functions/debug/#implementation","title":"Implementation","text":"

Ikarus.d on GitHub

"},{"location":"zengin/scripts/extenders/ikarus/functions/debug/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/ikarus/functions/debug/#mem_checkversion","title":"MEM_CheckVersion","text":"

Checks if the version of Ikarus is the specified version or newer.

func int MEM_CheckVersion(var int base, var int major, var int minor)\n
Parameters
  • var int base Base version number
  • var int major Major revision number
  • var int minor Minor revision number

Return value

The function returns TRUE if the version of Ikarus is the specified version or newer, FALSE is returned otherwise.

"},{"location":"zengin/scripts/extenders/ikarus/functions/debug/#mem_setshowdebug","title":"MEM_SetShowDebug","text":"

Sets the variable that is also toggled by the toggle debug command. As a result, messages outputted by PrintDebug are directed to the zSpy

func void MEM_SetShowDebug(var int on)\n
Parameters
  • var int on Specifies whether to turn on (TRUE) or off (FALSE) debug information.
"},{"location":"zengin/scripts/extenders/ikarus/functions/debug/#mem_sendtospy","title":"MEM_SendToSpy","text":"

Sends a message to the debugging console.

func void MEM_SendToSpy(var int errorType, var string text)\n
Parameters
  • var int errorType Type of error (e.g., zERR_TYPE_FAULT, zERR_TYPE_WARN, zERR_TYPE_INFO)
  • var string text The message to be sent.
"},{"location":"zengin/scripts/extenders/ikarus/functions/debug/#mem_errorbox","title":"MEM_ErrorBox","text":"

Displays an error message in a message box.

func void MEM_ErrorBox(var string text)\n
Parameters
  • var string text The error message to be displayed.
"},{"location":"zengin/scripts/extenders/ikarus/functions/debug/#mem_printstacktrace","title":"MEM_PrintStackTrace","text":"

Prints the stack trace.

func void MEM_PrintStackTrace()\n
"},{"location":"zengin/scripts/extenders/ikarus/functions/debug/#mem_error","title":"MEM_Error","text":"

Handles a fatal error, displaying the error message and printing the stack trace.

func void MEM_Error(var string error)\n
Parameters
  • var string error The error message.
"},{"location":"zengin/scripts/extenders/ikarus/functions/debug/#mem_warn","title":"MEM_Warn","text":"

Handles a warning, displaying the warning message and printing the stack trace.

func void MEM_Warn(var string warn)\n
Parameters
  • var string warn The warning message.
"},{"location":"zengin/scripts/extenders/ikarus/functions/debug/#mem_info","title":"MEM_Info","text":"

Handles an information message, printing it if enabled in the settings.

func void MEM_Info(var string info)\n
Parameters
  • var string info The information message.
"},{"location":"zengin/scripts/extenders/ikarus/functions/debug/#mem_assertfail","title":"MEM_AssertFail","text":"

Handles an assertion failure, reporting the error message as a fatal error.

func void MEM_AssertFail(var string assertFailText)\n
Parameters
  • var string assertFailText The assertion failure message.
"},{"location":"zengin/scripts/extenders/ikarus/functions/debug/#mem_debug","title":"MEM_Debug","text":"

Freely configurable debug channel. See how to setup it in the Constants article.

func void MEM_Debug(var string message)\n
Parameters
  • var string message The debug message.
"},{"location":"zengin/scripts/extenders/ikarus/functions/debug/#memint_switchg1g2","title":"MEMINT_SwitchG1G2","text":"

Switches between values based on the game version. Used mainly to change addresses in multi-platform hooks or function calls.

func int MEMINT_SwitchG1G2(var int g1Val, var int g2Val)\n
Parameters
  • var int g1Val The value to return if the game version is Gothic 1.
  • var int g2Val The value to return if the game version is Gothic 2.

Return value

The function returns an appropriate value based on the game version.

"},{"location":"zengin/scripts/extenders/ikarus/functions/ini_access/","title":"Configuration file access","text":""},{"location":"zengin/scripts/extenders/ikarus/functions/ini_access/#configuration-file-access","title":"Configuration file access","text":"

This part of Ikarus gives you access to Gothic.ini and loaded mod configuration files.

"},{"location":"zengin/scripts/extenders/ikarus/functions/ini_access/#initialization","title":"Initialization","text":"

The best way to initialize all Ikarus functions is to call MEM_InitAll() in the Init_Global() initialization function.

Warning

If you want to use Ikarus in Gothic 1, it is best to define your own Init_Global() function and call it from every world initialization function.

MEM_InitAll();\n
"},{"location":"zengin/scripts/extenders/ikarus/functions/ini_access/#implementation","title":"Implementation","text":"

Ikarus.d on GitHub

"},{"location":"zengin/scripts/extenders/ikarus/functions/ini_access/#read-functions","title":"Read functions","text":""},{"location":"zengin/scripts/extenders/ikarus/functions/ini_access/#mem_getcommandline","title":"MEM_GetCommandLine","text":"

Returns the contents of the command line passed to Gothic.

func string MEM_GetCommandLine()\n
Return value

The function returns contents of the command line passed to Gothic. This could, for example, look like this:

\"-TIME:7:35 -GAME:TEST_IKARUS.INI -ZREPARSE -ZWINDOW -ZLOG:5,S -DEVMODE -ZMAXFRAMERATE:30\"

"},{"location":"zengin/scripts/extenders/ikarus/functions/ini_access/#mem_getgothopt","title":"MEM_GetGothOpt","text":"

Searches the Gothic.ini for an option.

func string MEM_GetGothOpt(var string sectionname, var string optionname)\n
Parameters
  • var string sectionname Settings section like [GAME]
  • var string optionname One setting entry like playLogoVideos

Return value

The function returns an option value as a string or empty string if option was not found.

"},{"location":"zengin/scripts/extenders/ikarus/functions/ini_access/#mem_getmodopt","title":"MEM_GetModOpt","text":"

Searches the loaded mod ini file for option.

func void MEM_GetModOpt(var string sectionname, var string optionname)\n
Parameters
  • var string sectionname Settings section like [INFO]
  • var string optionname One setting entry like Title

Return value

The function returns an option value as a string or empty string if option was not found.

"},{"location":"zengin/scripts/extenders/ikarus/functions/ini_access/#mem_gothoptsectionexists","title":"MEM_GothOptSectionExists","text":"

Checks whether a section exists in Gothic.ini

func int MEM_GothOptSectionExists(var string sectionname)\n
Parameters
  • var string sectionname Settings section like [GAME]

Return value

The function returns TRUE if section exists FALSE is returned otherwise.

"},{"location":"zengin/scripts/extenders/ikarus/functions/ini_access/#mem_modoptsectionexists","title":"MEM_ModOptSectionExists","text":"

Checks whether a section exists in loaded mod ini file

func int MEM_ModOptSectionExists(var string sectionname)\n
Parameters
  • var string sectionname Settings section like [INFO]

Return value

The function returns TRUE if section exists FALSE is returned otherwise.

"},{"location":"zengin/scripts/extenders/ikarus/functions/ini_access/#mem_gothoptexists","title":"MEM_GothOptExists","text":"

Checks whether an option exists in Gothic.ini

func int MEM_GothOptExists(var string sectionname, var string optionname)\n
Parameters
  • var string sectionname Settings section like [GAME]
  • var string optionname One setting entry like playLogoVideos

Return value

The function returns TRUE if option in a section exist FALSE is returned otherwise.

"},{"location":"zengin/scripts/extenders/ikarus/functions/ini_access/#mem_modoptexists","title":"MEM_ModOptExists","text":"

Checks whether an option exists in loaded mod ini file

func int MEM_ModOptExists(var string sectionname, var string optionname)\n
Parameters
  • var string sectionname Settings section like [INFO]
  • var string optionname One setting entry like Title

Return value

The function returns TRUE if option in a section exist FALSE is returned otherwise.

"},{"location":"zengin/scripts/extenders/ikarus/functions/ini_access/#write-functions","title":"Write functions","text":"

Warning

Mod configuration is never saved to disk, therefore no separate functions exist for writing to it.

"},{"location":"zengin/scripts/extenders/ikarus/functions/ini_access/#mem_setgothopt","title":"MEM_SetGothOpt","text":"

The option option in the section section is set to the value. If the section and/or option does not exist, it will be created.

func void MEM_SetGothOpt(var string section, var string option, var string value)\n
Parameters
  • var string section The section where the option should be located
  • var string option Option to write/overwrite
  • var string value Value to set the option to
"},{"location":"zengin/scripts/extenders/ikarus/functions/ini_access/#mem_applygothopt","title":"MEM_ApplyGothOpt","text":"

Applies the changes and saves the ini to disk

func void MEM_ApplyGothOpt()\n

Tip

If you introduce new options, it is best to follow certain practices. It is a good practice to name your options in a clear manner and place them in a section named the same as your mod. Do not place your mod options into the [GAME] or [PERFORMANCE] sections.

"},{"location":"zengin/scripts/extenders/ikarus/functions/ini_access/#key-functions","title":"Key functions","text":"

The Gothic.ini contains the assignment of physical keys (e.g. \"W\") to logical keys (e.g. \"keyUp\").

"},{"location":"zengin/scripts/extenders/ikarus/functions/ini_access/#mem_getkey","title":"MEM_GetKey","text":"

Returns the primary key assigned to logical key.

func int MEM_GetKey(var string name)\n
Parameters
  • var string name Name of the logical key

Return value

The function returns key assigned to logical key

"},{"location":"zengin/scripts/extenders/ikarus/functions/ini_access/#mem_getsecondarykey","title":"MEM_GetSecondaryKey","text":"

Returns a secondary key assigned to logical key.

func int MEM_GetSecondaryKey(var string name)\n
Parameters
  • var string name Name of the logical key

Return value

The function returns key assigned to logical key

"},{"location":"zengin/scripts/extenders/ikarus/functions/ini_access/#mem_setkeys","title":"MEM_SetKeys","text":"

Sets keyboard keys of the logical key.

func void MEM_SetKeys(var string name, var int primary, var int secondary)\n
Parameters
  • var string name Name of the logical key
  • var int primary Primary key to be assigned, can be taken from Ikarus_Const_G1 / Ikarus_Const_G2 file.
  • var int secondary Secondary key to be assigned, can be taken from Ikarus_Const_G1 / Ikarus_Const_G2 file.
"},{"location":"zengin/scripts/extenders/ikarus/functions/ini_access/#mem_setkey","title":"MEM_SetKey","text":"

Sets the primary keyboard key of the logical key.

func void MEM_SetKey(var string name, var int key)\n
Parameters
  • var string name Name of the logical key
  • var int key Primary key to be assigned, can be taken from Ikarus_Const_G1 / Ikarus_Const_G2 file.
"},{"location":"zengin/scripts/extenders/ikarus/functions/ini_access/#mem_setsecondarykey","title":"MEM_SetSecondaryKey","text":"

Sets the secondary keyboard key of the logical key.

func void MEM_SetSecondaryKey(var string name, var int key)\n
Parameters
  • var string name Name of the logical key
  • var int key Secondary key to be assigned, can be taken from Ikarus_Const_G1 / Ikarus_Const_G2 file.
"},{"location":"zengin/scripts/extenders/ikarus/functions/jumps_loops/","title":"Jumps and Loops","text":""},{"location":"zengin/scripts/extenders/ikarus/functions/jumps_loops/#jumps-and-loops","title":"Jumps and Loops","text":""},{"location":"zengin/scripts/extenders/ikarus/functions/jumps_loops/#jumps","title":"Jumps","text":"

Jumps in Ikarus are implemented by direct manipulation of the stack pointer, achieved with two lines of code. These lines enable the change of the current position within the parser stack, representing machine-level code generated during script compilation. By querying and setting this position, the execution flow can be redirected to a new location in the code.

"},{"location":"zengin/scripts/extenders/ikarus/functions/jumps_loops/#initialization","title":"Initialization","text":"

To ensure the correct functioning of this jump mechanism, it is crucial to execute the MEM_InitLabels() function once after loading a saved game. The recommended practice is to integrate this initialization function within INIT_GLOBAL. It's only after MEM_InitLabels() has been called that accessing MEM_StackPos.position becomes valid.

func void MEM_InitLabels()\n

Tip

It's worth noting that MEM_InitLabels is also invoked by the MEM_InitAll function.

"},{"location":"zengin/scripts/extenders/ikarus/functions/jumps_loops/#usage","title":"Usage","text":"
  • Label Initialization Before attempting a jump, it's important to initialize the label to which the jump is intended. Forward jumps, where the jump point is encountered before the jump target, can be challenging. Label initialization looks like that:
    // [...]\nvar int label;\nlabel = MEM_StackPos.position;\n// [...]\n
  • Actual jump After initializing the label you could simply jump to it by setting MEM_StackPos.position to the label.
    // [...]\nMEM_StackPos.position = label;\n// [...]\n

Jump flowchart

flowchart TD\nA(Start) --> B[\"var int label; \\n label = MEM_StackPos.position;\"];\nB --> C{Your code}\nC -->D[\"MEM_StackPos.position = label;\"];\nC --> E(End)\nD --> |Jump| B;
"},{"location":"zengin/scripts/extenders/ikarus/functions/jumps_loops/#notes-and-warnings","title":"Notes and warnings","text":"
  • Validity of Labels Labels become invalid after saving and loading. Consequently, labels should be used immediately, and there is generally no reason to persist them for an extended period.

  • Caution with Jumping Jumping between different functions without a clear understanding of the code structure can lead to unexpected issues. Similarly, using labels without a thorough comprehension of their purpose may result in undesired consequences. It's crucial to exercise caution, especially when making assignments involving labels.

"},{"location":"zengin/scripts/extenders/ikarus/functions/jumps_loops/#examples","title":"Examples","text":"Simple jump 'loop'Nested jump 'loop'

The following code outputs the numbers from 0 to 42:

func void foo() {\n    /* Initialization */\n    MEM_InitLabels();\n    var int count; count = 0;\n\n    /* Record the execution position in label. */\n    var int label;\n    label = MEM_StackPos.position;\n    /* <---- label now points here,\n    * i.e. to the position AFTER the assignment of label. */\n\n    Print (ConcatStrings (\"COUNT: \", IntToString (count)));\n    count += 1;\n\n    if (count <= 42) {\n        /* Replace the execution position,\n        * with the \"<-----\" the system then continues */\n        MEM_StackPos.position = label;\n    };\n\n    /* Once 43 is reached, the \u201cloop\u201d is exited. */\n};\n

The following code should enumerate all pairs (x,y) with 0 <= x < max_x, 0 <= y < max_y

func void printpairs(var int max_x, var int max_y)\n{\n    // Initialize labels\n    MEM_InitLabels();\n    // PrintDebug should be used, i.e. activate debug output\n    MEM_SetShowDebug (1);\n\n    var int x; var int y; x = 0;\n\n    // while (x < max_x)\n    var int x_loop; x_loop = MEM_StackPos.position;\n    if (x < max_x)\n    { \n        y = 0;\n        // while (y < max_y) \n        var int y_loop; y_loop = MEM_StackPos.position;\n        if (y < max_y)\n        { \n            var string out; out = \"(\";\n            out = ConcatStrings (out, IntToString (x));\n            out = ConcatStrings (out, \", \");\n            out = ConcatStrings (out, IntToString (y));\n            out = ConcatStrings (out, \")\");\n            PrintDebug (out);\n            y += 1;\n\n            // continue y_loop \n            MEM_StackPos.position = y_loop;\n        };\n        x += 1;\n        // continue x_loop\n        MEM_StackPos.position = x_loop;\n    };\n};\n\n/*\n    Output of a call printpairs(4,2) would then be: \n    00:36 Info: 5 U: Skript: (0, 0) .... \n    00:36 Info: 5 U: Skript: (0, 1) .... \n    00:36 Info: 5 U: Skript: (1, 0) .... \n    00:36 Info: 5 U: Skript: (1, 1) .... \n    00:36 Info: 5 U: Skript: (2, 0) .... \n    00:36 Info: 5 U: Skript: (2, 1) .... \n    00:36 Info: 5 U: Skript: (3, 0) .... \n    00:36 Info: 5 U: Skript: (3, 1) .... \n*/\n
"},{"location":"zengin/scripts/extenders/ikarus/functions/jumps_loops/#label-and-goto","title":"Label and Goto","text":"

Besides the normal jumps Ikarus implements MEM_Label and MEM_Goto functions. They work similar to the stack manipulation with var int label but the interface is much more user-friendly and defining new variables is not needed.

"},{"location":"zengin/scripts/extenders/ikarus/functions/jumps_loops/#mem_label","title":"MEM_Label","text":"

Function that works like a label = MEM_StackPos.position;. You could jump to it with MEM_Goto.

func void MEM_Label(var int lbl)\n
Parameters
  • var int lbl Number of the label, used for nested loop or multiple loops within one function
"},{"location":"zengin/scripts/extenders/ikarus/functions/jumps_loops/#mem_goto","title":"MEM_Goto","text":"

Function that works like a MEM_StackPos.position = label;. Executes a jump to a MEM_Label with specified number.

func void MEM_Goto(var int lbl)\n
Parameters
  • var int lbl Number of the label, the function will jump to
"},{"location":"zengin/scripts/extenders/ikarus/functions/jumps_loops/#usage_1","title":"Usage","text":"

Usage of Label and Goto is probably self-explanatory, since it is same as in the regular Ikarus Jump. But before using it reading the Notes and warnings of the Jumps is recommended.

Label-Goto loop flowchart

flowchart TD\nA(Start) --> B[\"MEM_Label(0);\"];\nB --> C{Your code}\nC -->D[\"MEM_Goto(0);\"];\nC --> E(End)\nD --> |Jump| B;
Label-Goto loop
func void LabelGoto_test() {\n    var int i; \n    MEM_Label(0);\n        MEM_Debug(IntToString(i));\n        i = i + 1;\n        if(i >= 4)\n        {\n            return;\n        };\n        MEM_Goto(0);\n};\n\n//  Results:\n//  Info:  0 Q:     Debug: 0\n//  Info:  0 Q:     Debug: 1\n//  Info:  0 Q:     Debug: 2\n//  Info:  0 Q:     Debug: 3\n
"},{"location":"zengin/scripts/extenders/ikarus/functions/jumps_loops/#examples_1","title":"Examples","text":"Simple Label-Goto 'loop'Nested Label-Goto 'loop'

The following code outputs the numbers from 0 to 42:

func void foo() {\n    var int count; count = 0;\n\n    MEM_Label(0);\n    /* <---- label now points here,\n    * i.e. to the position AFTER the assignment of label. */\n\n    Print (ConcatStrings (\"COUNT: \", IntToString (count)));\n    count += 1;\n\n    if (count <= 42) {\n        // Jump to the MEM_Label\n        MEM_Goto(0);\n    };\n\n    /* Once 43 is reached, the \u201cloop\u201d is exited. */\n};\n

The following code should enumerate all pairs (x,y) with 0 <= x < max_x, 0 <= y < max_y

func void printpairs(var int max_x, var int max_y)\n{\n    // PrintDebug should be used, i.e. activate debug output\n    MEM_SetShowDebug (1);\n\n    var int x; var int y; x = 0;\n\n    // while (x < max_x)\n    MEM_Label(0);\n    if (x < max_x)\n    { \n        y = 0;\n        // while (y < max_y) \n        MEM_Label(1);\n        if (y < max_y)\n        { \n            var string out; out = \"(\";\n            out = ConcatStrings (out, IntToString (x));\n            out = ConcatStrings (out, \", \");\n            out = ConcatStrings (out, IntToString (y));\n            out = ConcatStrings (out, \")\");\n            PrintDebug (out);\n            y += 1;\n\n            MEM_Goto(1);\n        };\n        x += 1;\n       MEM_Goto(0);\n    };\n};\n\n/*\n    Output of a call printpairs(4,2) would then be: \n    00:36 Info: 5 U: Skript: (0, 0) .... \n    00:36 Info: 5 U: Skript: (0, 1) .... \n    00:36 Info: 5 U: Skript: (1, 0) .... \n    00:36 Info: 5 U: Skript: (1, 1) .... \n    00:36 Info: 5 U: Skript: (2, 0) .... \n    00:36 Info: 5 U: Skript: (2, 1) .... \n    00:36 Info: 5 U: Skript: (3, 0) .... \n    00:36 Info: 5 U: Skript: (3, 1) .... \n*/\n
"},{"location":"zengin/scripts/extenders/ikarus/functions/jumps_loops/#while-loop","title":"While loop","text":"

Ikarus also implements a while loop. Its syntax isn't as good as the loop from zParserExtender, due to the daedalus limitations, but it works as a normal while loop that can be found in many programming languages.

"},{"location":"zengin/scripts/extenders/ikarus/functions/jumps_loops/#syntax","title":"Syntax","text":"

The Ikarus while loop consist of three things:

  • while function That works like a while statement and start of the brace while(var int b){.

    func void while(var int b)\n
  • end constant That works like an ending brace }.

    const int end = -72;\n
  • break and continue constant These two constants works like a regular break and continue statements in C.

    const int break = -42;\nconst int continue = -23;\n
while loop
func void while_test() {\n    var int value; value = 10;\n    while(value > 0); //{\n\n        if (value == 8)\n        {\n            continue;\n        };\n\n        if (value == 2)\n        {\n            break;\n        };\n    end; //}\n};\n
"},{"location":"zengin/scripts/extenders/ikarus/functions/jumps_loops/#examples_2","title":"Examples","text":"Simple while loopNested while loop

The following code outputs the numbers from 0 to 42:

func void foo() {\n    var int count; count = 0;\n    while(count <= 42); //{\n        Print (ConcatStrings (\"COUNT: \", IntToString (count)));\n        count += 1;\n    end; //}\n\n    /* Once 43 is reached, the loop is exited. */\n}; \n

The following code should enumerate all pairs (x,y) with 0 <= x < max_x, 0 <= y < max_y

func void printpairs(var int max_x, var int max_y)\n{\n    // PrintDebug should be used, i.e. activate debug output\n    MEM_SetShowDebug (1);\n\n    var int x; var int y; x = 0;\n\n    while(x < max_x); //{\n        y = 0;\n        while(y < max_y); //{  \n            var string out; out = \"(\";\n            out = ConcatStrings (out, IntToString (x));\n            out = ConcatStrings (out, \", \");\n            out = ConcatStrings (out, IntToString (y));\n            out = ConcatStrings (out, \")\");\n            PrintDebug (out);\n            y += 1;\n        end; //}\n        x += 1;\n    end; //}\n};\n\n/*\n    Output of a call printpairs(4,2) would then be: \n    00:36 Info: 5 U: Skript: (0, 0) .... \n    00:36 Info: 5 U: Skript: (0, 1) .... \n    00:36 Info: 5 U: Skript: (1, 0) .... \n    00:36 Info: 5 U: Skript: (1, 1) .... \n    00:36 Info: 5 U: Skript: (2, 0) .... \n    00:36 Info: 5 U: Skript: (2, 1) .... \n    00:36 Info: 5 U: Skript: (3, 0) .... \n    00:36 Info: 5 U: Skript: (3, 1) .... \n*/\n
"},{"location":"zengin/scripts/extenders/ikarus/functions/jumps_loops/#repeat-loop","title":"Repeat loop","text":"

In addition Ikarus implements something called Repeat loop.

"},{"location":"zengin/scripts/extenders/ikarus/functions/jumps_loops/#initialization_1","title":"Initialization","text":"

To use Repeat loop you must first call MEM_InitRepeat() function once after loading a saved game. The recommended practice is to integrate this initialization function within INIT_GLOBAL.

func void MEM_InitRepeat()\n

Tip

It's worth noting that MEM_InitRepeat is also invoked by the MEM_InitAll function.

"},{"location":"zengin/scripts/extenders/ikarus/functions/jumps_loops/#syntax_1","title":"Syntax","text":"

Repeat loop has a syntax very similar to the while loop. It also uses end constant as an ending brace. break and continue statements can be used within it as well. The main difference is the main loop function Repeat that has following properties:

func void Repeat(var int variable, var int limit)\n
  • var int variable A variable that increase with every loop iteration.
  • var int limit A variable that defines the number of loop iterations. If variable >= limit the loop is exited.

Repeat loop flowchart

flowchart TD\n    A(Start) --> B[\"Repeat(i, limit)\"] \n    B --> C{i < limit}\n    C -->|true| D[Command]\n    D --> |i = i + 1| B\n    C --> |false| E(End)
Repeat loop
func void Repeat_test() {\n    Repeat(i, 4); var int i; //{\n        MEM_Debug(IntToString(i));\n    end; //}\n};\n\n//  Results:\n//  Info:  0 Q:     Debug: 0\n//  Info:  0 Q:     Debug: 1\n//  Info:  0 Q:     Debug: 2\n//  Info:  0 Q:     Debug: 3\n
"},{"location":"zengin/scripts/extenders/ikarus/functions/jumps_loops/#examples_3","title":"Examples","text":"Simple Repeat loopNested Repeat loop

The following code outputs the numbers from 0 to 42:

func void foo() {\n    Repeat(count, 43); var int count; //{\n        Print (ConcatStrings (\"COUNT: \", IntToString (count)));\n    end; //}\n\n    /* Once 43 is reached, the loop is exited. */\n}; \n

The following code should enumerate all pairs (x,y) with 0 <= x < max_x, 0 <= y < max_y

func void printpairs(var int max_x, var int max_y)\n{\n    // PrintDebug should be used, i.e. activate debug output\n    MEM_SetShowDebug (1);\n\n    var int x; var int y; x = 0;\n\n    Repeat(x, max_x); //{\n        y = 0;\n        Repeat(y, max_y); //{  \n            var string out; out = \"(\";\n            out = ConcatStrings (out, IntToString (x));\n            out = ConcatStrings (out, \", \");\n            out = ConcatStrings (out, IntToString (y));\n            out = ConcatStrings (out, \")\");\n            PrintDebug (out);\n        end; //}\n    end; //}\n};\n\n/*\n    Output of a call printpairs(4,2) would then be: \n    00:36 Info: 5 U: Skript: (0, 0) .... \n    00:36 Info: 5 U: Skript: (0, 1) .... \n    00:36 Info: 5 U: Skript: (1, 0) .... \n    00:36 Info: 5 U: Skript: (1, 1) .... \n    00:36 Info: 5 U: Skript: (2, 0) .... \n    00:36 Info: 5 U: Skript: (2, 1) .... \n    00:36 Info: 5 U: Skript: (3, 0) .... \n    00:36 Info: 5 U: Skript: (3, 1) .... \n*/\n
"},{"location":"zengin/scripts/extenders/ikarus/functions/keyboard/","title":"Keyboard interaction","text":""},{"location":"zengin/scripts/extenders/ikarus/functions/keyboard/#keyboard-interaction","title":"Keyboard interaction","text":"

This part of Ikarus implements function that make interaction with keyboard possible.

Info

Keyboard interaction is also implemented with gameKeyEvents.d

"},{"location":"zengin/scripts/extenders/ikarus/functions/keyboard/#initialization","title":"Initialization","text":"

The best way to initialize all Ikarus functions is to call MEM_InitAll() in the Init_Global() initialization function.

Warning

If you want to use Ikarus in Gothic 1, it is best to define your own Init_Global() function and call it from every world initialization function.

MEM_InitAll();\n
"},{"location":"zengin/scripts/extenders/ikarus/functions/keyboard/#implementation","title":"Implementation","text":"

Ikarus.d on GitHub

"},{"location":"zengin/scripts/extenders/ikarus/functions/keyboard/#functions","title":"Functions","text":"

Tip

Different players use different keys for specific actions! However, it is possible to get key assigned to the action from Gothic.ini. See Ini access.

"},{"location":"zengin/scripts/extenders/ikarus/functions/keyboard/#mem_keypressed","title":"MEM_KeyPressed","text":"

Checks if the key is hold right at the moment of function call.

func int MEM_KeyPressed(var int key)\n
Parameters
  • var int key Checked key

Return value

The function returns TRUE if the key is hold, FALSE is returned otherwise.

"},{"location":"zengin/scripts/extenders/ikarus/functions/keyboard/#mem_keystate","title":"MEM_KeyState","text":"

Returns the state of the key.

func int MEM_KeyState(var int key)\n
Parameters
  • var int key Checked key

Return value

The function returns actual key state.

Key states

  • KEY_UP - The key is not pressed and was not pressed before. (\"not pressed\")
  • KEY_PRESSED - The key is pressed and was not previously pressed. (\"new pressed\")
  • KEY_HOLD - The key is pressed and was also pressed before. (\"still pressed\")
  • KEY_RELEASED - The key is not pressed and was previously pressed. (\"let go\")

KEY_PRESSED or KEY_RELEASED will be returned if the state of the key has changed since the last query.

KEY_UP or KEY_HOLD are returned if the state has not changed.

"},{"location":"zengin/scripts/extenders/ikarus/functions/keyboard/#mem_insertkeyevent","title":"MEM_InsertKeyEvent","text":"

Makes the game think that the key was pressed.

func void MEM_InsertKeyEvent(var int key)\n
Parameters
  • var int key Key to be \"pressed\"
"},{"location":"zengin/scripts/extenders/ikarus/functions/mem_access/","title":"Elementary memory access","text":""},{"location":"zengin/scripts/extenders/ikarus/functions/mem_access/#elementary-memory-access","title":"Elementary memory access","text":"

This part of Ikarus makes it possible to read and write memory as different data types - integers, strings, arrays of integers or strings and bytes.

If address <= 0, an error is thrown. Otherwise, an attempt is made to read or write at this address. If the address falls into invalid range, for example in a code segment, access violation will occur (Gothic crashes). In the case of string operations, it is also necessary that at the specified position a valid zString already exists.

"},{"location":"zengin/scripts/extenders/ikarus/functions/mem_access/#initialization","title":"Initialization","text":"

The best way to initialize all Ikarus functions is to call MEM_InitAll() in the Init_Global() initialization function.

Warning

If you want to use Ikarus in Gothic 1, it is best to define your own Init_Global() function and call it from every world initialization function.

MEM_InitAll();\n
"},{"location":"zengin/scripts/extenders/ikarus/functions/mem_access/#implementation","title":"Implementation","text":"

Ikarus.d on GitHub

"},{"location":"zengin/scripts/extenders/ikarus/functions/mem_access/#read-functions","title":"Read functions","text":""},{"location":"zengin/scripts/extenders/ikarus/functions/mem_access/#mem_readint","title":"MEM_ReadInt","text":"

Reads int from the address.

func int MEM_ReadInt(var int address)\n
Parameters
  • var int address Memory address to read from

Return value

The function returns an integer value if the address is correct.

"},{"location":"zengin/scripts/extenders/ikarus/functions/mem_access/#mem_readstring","title":"MEM_ReadString","text":"

Reads string from the address.

func string MEM_ReadString(var int address)\n
Parameters
  • var int address Memory address to read from

Return value

The function returns string if the address is correct.

"},{"location":"zengin/scripts/extenders/ikarus/functions/mem_access/#mem_readbyte","title":"MEM_ReadByte","text":"

Reads byte from the address.

func int MEM_ReadByte(var int address)\n
Parameters
  • var int address Memory address to read from

Return value

The function returns byte value if the address is correct.

"},{"location":"zengin/scripts/extenders/ikarus/functions/mem_access/#mem_readintarray","title":"MEM_ReadIntArray","text":"

Reads int from the array at the arrayAddress.

func int MEM_ReadIntArray(var int arrayAddress, var int offset)\n
Parameters
  • var int arrayAddress Memory address of array
  • var int offset Array offset (array index)

Return value

The function returns integer value from the array if the address is correct.

"},{"location":"zengin/scripts/extenders/ikarus/functions/mem_access/#mem_readstringarray","title":"MEM_ReadStringArray","text":"

Info

MEM_ReadStringArray has been already moved to the LeGo PermMem package.

"},{"location":"zengin/scripts/extenders/ikarus/functions/mem_access/#mem_readbytearray","title":"MEM_ReadByteArray","text":"

Reads byte from the array at the arrayAddress.

func int MEM_ReadByteArray(var int arrayAddress, var int offset)\n
Parameters
  • var int arrayAddress Memory address of array
  • var int offset Array offset (array index)

Return value

The function returns byte from the array if the address is correct.

"},{"location":"zengin/scripts/extenders/ikarus/functions/mem_access/#write-functions","title":"Write functions","text":""},{"location":"zengin/scripts/extenders/ikarus/functions/mem_access/#mem_writeint","title":"MEM_WriteInt","text":"

Writes int value in the address.

func void MEM_WriteInt(var int address, var int value)\n
Parameters
  • var int address Memory address to write into
  • var int value Integer value to write
Example

An example of using this function is the following Ikarus function, which turns debugging messages on and off:

func void MEM_SetShowDebug(var int on)\n{\n    MEM_WriteInt(showDebugAddress, on);\n};\n
"},{"location":"zengin/scripts/extenders/ikarus/functions/mem_access/#mem_writestring","title":"MEM_WriteString","text":"

Writes string in the address.

func void MEM_WriteString(var int address, var string value)\n
Parameters
  • var int address Memory address to write into
  • var int value String to write
"},{"location":"zengin/scripts/extenders/ikarus/functions/mem_access/#mem_writebyte","title":"MEM_WriteByte","text":"

Only the byte at address address is changed here, not a whole four-byte word. That is, the three subsequent bytes remain untouched. If 0 <= val < 256 does not apply in MEM_WriteByte, a warning is issued and val is trimmed accordingly. In particular, shouldn't be negative numbers are passed.

func void MEM_WriteByte(var int address, var int value)\n
Parameters
  • var int address Memory address to write into
  • var int value Byte to write
"},{"location":"zengin/scripts/extenders/ikarus/functions/mem_access/#mem_writeintarray","title":"MEM_WriteIntArray","text":"

Writes int value in the array at arrayAddress.

func void MEM_WriteIntArray(var int arrayAddress, var int offset, var int value)\n
Parameters
  • var int arrayAddress Memory address of array
  • var int offset Array offset (array index)
  • var int value Integer value to write
"},{"location":"zengin/scripts/extenders/ikarus/functions/mem_access/#mem_writestringarray","title":"MEM_WriteStringArray","text":"

Writes string value in the array at arrayAddress.

func void MEM_WriteStringArray(var int arrayAddress, var int offset, var string value)\n
Parameters
  • var int arrayAddress Memory address of array
  • var int offset Array offset (array index)
  • var string value String to write
"},{"location":"zengin/scripts/extenders/ikarus/functions/mem_access/#mem_writebytearray","title":"MEM_WriteByteArray","text":"

Writes byte value in the array at arrayAddress.

func void MEM_WriteByteArray(var int arrayAddress, var int offset, var int value)\n
Parameters
  • var int arrayAddress Memory address of array
  • var int offset Array offset (array index)
  • var int value Byte to write
"},{"location":"zengin/scripts/extenders/ikarus/functions/mem_utility/","title":"Memory utility","text":""},{"location":"zengin/scripts/extenders/ikarus/functions/mem_utility/#memory-utility","title":"Memory utility","text":"

Ikarus utility functions, for memory management and manipulation.

"},{"location":"zengin/scripts/extenders/ikarus/functions/mem_utility/#initialization","title":"Initialization","text":"

The best way to initialize all Ikarus functions is to call MEM_InitAll() in the Init_Global() initialization function.

Warning

If you want to use Ikarus in Gothic 1, it is best to define your own Init_Global() function and call it from every world initialization function.

MEM_InitAll();\n
"},{"location":"zengin/scripts/extenders/ikarus/functions/mem_utility/#implementation","title":"Implementation","text":"

Ikarus.d on GitHub

"},{"location":"zengin/scripts/extenders/ikarus/functions/mem_utility/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/ikarus/functions/mem_utility/#mem_alloc","title":"MEM_Alloc","text":"

Allocates a specified amount of memory and returns a pointer to the allocated memory area.

Danger

Gothic does not and cannot retain a reference to this memory area or release it, even when destroying the session. Therefore, memory should only be reserved under certain conditions:

  • It is guaranteed to exist and can be released again with MEM_Free after loading a save game.
  • Gothic is aware of this memory area and independently releases it.

It might be possible to create new objects with this function and permanently integrate them into the object structure of Gothic. However, extreme caution is advised, as object structures cannot be used, and manual handling is required.

This function is well-suited for building small elements like list items and integrating them into existing lists. The memory allocated by this function is always initialized to zero.

func int MEM_Alloc(var int amount)\n
Parameters
  • var int amount The amount of bytes to allocate

Return value

The function returns a pointer to the allocated memory area.

"},{"location":"zengin/scripts/extenders/ikarus/functions/mem_utility/#mem_realloc","title":"MEM_Realloc","text":"

Allocates a memory area of \u200b\u200bsize newsize and returns a pointer to this memory area. The memory area from location ptr is released.

If newsize >= oldsize, the first oldsize bytes from the old memory area are transferred to the new one. The additional memory is initialized with zero.

If newsize <= oldsize, all bytes of the new memory area are initialized with the corresponding values \u200b\u200bof the old memory area.

This function is intended to create an allocated memory area enlarge or reduce. Existing data remains naturally way received.

func int MEM_Realloc(var int ptr, var int oldsize, var int newsize)\n
Parameters
  • var int ptr The original pointer to the memory block
  • var int oldsize The size of the original memory block
  • var int newsize The size of the new memory block

Return value

The function returns a pointer to the modified memory area.

"},{"location":"zengin/scripts/extenders/ikarus/functions/mem_utility/#mem_free","title":"MEM_Free","text":"

Releases an allocated memory area.

Danger

Great caution is advised, especially when attempting to destroy engine objects, as no destructors are called!

Releasing small things such as list elements can be done easily.

func void MEM_Free(var int ptr)\n
Parameters
  • var int ptr Pointer to the released memory block
"},{"location":"zengin/scripts/extenders/ikarus/functions/mem_utility/#mem_copy","title":"MEM_Copy","text":"

Copies a specified number of words from the source address to the destination address.

func void MEM_Copy(var int src, var int dst, var int wordcount)\n
Parameters
  • var int src The source address to copy from
  • var int dst The destination address to copy to
  • var int wordCount The number of words to copy
"},{"location":"zengin/scripts/extenders/ikarus/functions/mem_utility/#mem_copywords","title":"MEM_CopyWords","text":"

Alias to MEM_Copy. Copies a specified number of words from the source address to the destination address.

func void MEM_CopyWords(var int src, var int dst, var int wordcount) \n
Parameters
  • var int src The source address to copy from
  • var int dst The destination address to copy to
  • var int wordCount The number of words to copy
"},{"location":"zengin/scripts/extenders/ikarus/functions/mem_utility/#mem_copybytes","title":"MEM_CopyBytes","text":"

Copies a specified number of bytes from the source address to the destination address

func void MEM_CopyBytes(var int src, var int dst, var int byteCount)\n
Parameters
  • var int src The source address to copy from
  • var int dst The destination address to copy to
  • var int byteCount The number of bytes to copy
"},{"location":"zengin/scripts/extenders/ikarus/functions/mem_utility/#mem_swap","title":"MEM_Swap","text":"

Swaps a specified number of words between the source address and the destination address.

func void MEM_Swap(var int src, var int dst, var int wordCount)\n
Parameters
  • var int src The source address to swap from
  • var int dst The destination address to swap to
  • var int wordCount The number of words to swap
"},{"location":"zengin/scripts/extenders/ikarus/functions/mem_utility/#mem_swapwords","title":"MEM_SwapWords","text":"

Alias to MEM_Swap. Swaps a specified number of words between the source address and the destination address.

func void MEM_SwapWords(var int src, var int dst, var int wordCount)\n
Parameters
  • var int src The source address to swap from
  • var int dst The destination address to swap to
  • var int wordCount The number of words to swap
"},{"location":"zengin/scripts/extenders/ikarus/functions/mem_utility/#mem_swapbytes","title":"MEM_SwapBytes","text":"

Swaps a specified number of bytes between the source address and the destination address.

func void MEM_SwapBytes(var int src, var int dst, var int byteCount)\n
Parameters
  • var int src The source address to swap from
  • var int dst The destination address to swap to
  • var int byteCount The number of bytes to swap
"},{"location":"zengin/scripts/extenders/ikarus/functions/mem_utility/#mem_clear","title":"MEM_Clear","text":"

Sets a specified number of bytes in memory to zero.

func void MEM_Clear(var int ptr, var int size)\n
Parameters
  • var int ptr The memory address to start clearing from
  • var int size The number of bytes to clear
"},{"location":"zengin/scripts/extenders/ikarus/functions/mem_utility/#mem_compare","title":"MEM_Compare","text":"

Compares a specified number of words between two memory blocks.

func int MEM_Compare(var int ptr0, var int ptr1, var int wordCount)\n
Parameters
  • var int ptr0 The first memory block to compare
  • var int ptr1 The second memory block to compare
  • var int wordCount The number of words to compare

Return value

The function returns TRUE if the memory blocks are equal, FALSE is returned otherwise.

"},{"location":"zengin/scripts/extenders/ikarus/functions/mem_utility/#mem_comparewords","title":"MEM_CompareWords","text":"

Alias to MEM_Compare. Compares a specified number of words between two memory blocks.

func int MEM_CompareWords(var int ptr0, var int ptr1, var int wordCount)\n
Parameters
  • var int ptr0 The first memory block to compare
  • var int ptr1 The second memory block to compare
  • var int wordCount The number of words to compare

Return value

The function returns TRUE if the memory blocks are equal, FALSE is returned otherwise.

"},{"location":"zengin/scripts/extenders/ikarus/functions/mem_utility/#mem_comparebytes","title":"MEM_CompareBytes","text":"

Compares a specified number of bytes between two memory blocks.

func int MEM_CompareBytes(var int ptr1, var int ptr2, var int byteCount)\n
Parameters
  • var int ptr0 The first memory block to compare
  • var int ptr1 The second memory block to compare
  • var int wordCount The number of bytes to compare

Return value

The function returns TRUE if the memory blocks are equal, FALSE is returned otherwise.

"},{"location":"zengin/scripts/extenders/ikarus/functions/menu_access/","title":"Access Menu Objects","text":""},{"location":"zengin/scripts/extenders/ikarus/functions/menu_access/#access-menu-objects","title":"Access Menu Objects","text":"

These Ikarus functions are intended to provide and simplify access to menu items (e.g. in the character menu).

Tip

Some menus are generated every time they are used, while others are generated once and then kept. For example, a character menu is only available after it was opened for the first time, after that it is kept in memory. Depending on what you actually want to do, it can make sense to introduce changes in the menu scripts.

"},{"location":"zengin/scripts/extenders/ikarus/functions/menu_access/#initialization","title":"Initialization","text":"

The best way to initialize all Ikarus functions is to call MEM_InitAll() in the Init_Global() initialization function.

Warning

If you want to use Ikarus in Gothic 1, it is best to define your own Init_Global() function and call it from every world initialization function.

MEM_InitAll();\n
"},{"location":"zengin/scripts/extenders/ikarus/functions/menu_access/#implementation","title":"Implementation","text":"

Ikarus.d on GitHub

"},{"location":"zengin/scripts/extenders/ikarus/functions/menu_access/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/ikarus/functions/menu_access/#mem_getmenubystring","title":"MEM_GetMenuByString","text":"
func int MEM_GetMenuByString(var string menuName)\n

Parameters

  • var string menuName Name of the Gothic menu e.g. MENU_STATUS

Return value

The function returns the address of the menu if a menu with this name exists, null otherwise.

"},{"location":"zengin/scripts/extenders/ikarus/functions/menu_access/#mem_getmenuitembystring","title":"MEM_GetMenuItemByString","text":"
func int MEM_GetMenuItemByString(var string menuItemName)\n

Parameters

  • var string menuItemName Name of the Gothic menu item e.g. MENU_ITEM_PLAYERGUILD_TITLE

Return value

The function returns the address of the menu item if a menu item with this name exists, null otherwise.

"},{"location":"zengin/scripts/extenders/ikarus/functions/objects/","title":"zCObjects","text":""},{"location":"zengin/scripts/extenders/ikarus/functions/objects/#zcobjects","title":"zCObjects","text":"

Set of functions for working with zCObject and its subclasses instances.

"},{"location":"zengin/scripts/extenders/ikarus/functions/objects/#initialization","title":"Initialization","text":"

The best way to initialize all Ikarus functions is to call MEM_InitAll() in the Init_Global() initialization function.

Warning

If you want to use Ikarus in Gothic 1, it is best to define your own Init_Global() function and call it from every world initialization function.

MEM_InitAll();\n
"},{"location":"zengin/scripts/extenders/ikarus/functions/objects/#implementation","title":"Implementation","text":"

Ikarus.d on GitHub

"},{"location":"zengin/scripts/extenders/ikarus/functions/objects/#global-instances","title":"Global instances","text":"

Ikarus package introduces the following instances:

instance MEM_Game (oCGame);\ninstance MEM_World(oWorld);\ninstance MEM_Timer(zCTimer);\ninstance MEM_WorldTimer(oCWorldTimer);\ninstance MEM_Vobtree(zCTree);\ninstance MEM_InfoMan(oCInfoManager);\ninstance MEM_InformationMan (oCInformationManager);\ninstance MEM_Waynet(zCWaynet);\ninstance MEM_Camera(zCCamera);\ninstance MEM_SkyController(zCSkyController_Outdoor);\ninstance MEM_SpawnManager (oCSpawnManager);\ninstance MEM_GameMananger (CGameManager);\ninstance MEM_GameManager (CGameManager);\ninstance MEM_Parser(zCParser);\n

The classes used here all have one thing in common: there is a maximum of one object of them at the same time (e.g. there is not two worlds or two sky at the same time).

MEM_InitGlobalInst function sets the offsets of these instances to the corresponding unique object. While it has been called, all of the above instances can be used.

"},{"location":"zengin/scripts/extenders/ikarus/functions/objects/#mem_initglobalinst","title":"MEM_InitGlobalInst","text":"

Initializes global instances of commonly used objects in the game (is called by the MEM_InitAll function).

func void MEM_InitGlobalInst()\n

Warning

MEM_InitGlobalInst must be executed once after loading a savegame. The easiest way is do it is to call this function from INIT_GLOBAL.

"},{"location":"zengin/scripts/extenders/ikarus/functions/objects/#functions","title":"Functions","text":"About zCClassDef

For every class (derived from zCObject) there is an \"administrative object\" of type zCClassDef. This encapsulates some useful information about all objects in this class.

class zCClassDef {\n    var string className;            //zSTRING\n    var string baseClassName;        //zSTRING\n    var string scriptClassName;      //zSTRING\n    var int baseClassDef;            //zCClassDef*\n    var int createNewInstance;       //zCObject* ( *) (void) \n    var int createNewInstanceBackup; //zCObject* ( *) (void)\n    var int classFlags;              //zDWORD\n    var int classSize;               //zDWORD\n    var int numLivingObjects;\n    var int numCtorCalled;\n    var int hashTable;               //zCObject**\n    var int objectList_array;        //zCObject**\n    var int objectList_numAlloc;     //int\n    var int objectList_numInArray;   //int\n    var int bitfield;\n};\n

Full Ikarus definition of this class, with members description can be found in Misc.d file. The class is same for G1 and G2A engines.

"},{"location":"zengin/scripts/extenders/ikarus/functions/objects/#mem_getclassdef","title":"MEM_GetClassDef","text":"

Returns a pointer to the zCClassDef of the object. For more info see the About zCClassDef section above.

Passing these functions a pointer that does not point to a zCObject will most likely result in a crash lead.

func int MEM_GetClassDef(var int objPtr)\n
Parameters
  • var int objPtr A pointer to the object whose class definition is to be retrieved

Return value

The function returns a pointer to the zCClassDef of the object.

Example

This would return a pointer to the zCClassDef object that belongs to the oCNpc class.

func int example1\n{\n    var int her; her = MEM_InstToPtr(hero);\n    return MEM_GetClassDef(her);\n};\n
"},{"location":"zengin/scripts/extenders/ikarus/functions/objects/#mem_getclassname","title":"MEM_GetClassName","text":"

This function returns the name of the class to which an object belongs.

func string MEM_GetClassName(var int objPtr)\n
Parameters
  • var int objPtr A pointer to the object whose class name is to be retrieved

Return value

The function returns the objects class name as a string, if the object is invalid an empty string is returned.

Example

This would return a name of the oCNpc class as a string.

func string example2\n{\n    var int her; her = MEM_InstToPtr(hero);\n    return MEM_GetClassName(her);\n};\n// return: \"oCNpc\"\n
"},{"location":"zengin/scripts/extenders/ikarus/functions/objects/#mem_checkinheritance","title":"MEM_CheckInheritance","text":"

Checks if an object is derived from a specific class definition.

func int MEM_CheckInheritance(var int objPtr, var int classDef)\n
Parameters
  • var int objPtr A pointer to the object to be checked
  • var int classDef A pointer to the class definition to check against

Return value

The function returns TRUE if the object is derived from the specified class definition, FALSE is returned otherwise.

"},{"location":"zengin/scripts/extenders/ikarus/functions/objects/#hlp_is_","title":"Hlp_Is_*","text":"

In addition MEM_CheckInheritance function has some overloads with hardcoded classDef parameter.

func int Hlp_Is_oCMobFire(var int ptr){};\nfunc int Hlp_Is_zCMover(var int ptr){};\nfunc int Hlp_Is_oCMob(var int ptr){};\nfunc int Hlp_Is_oCMobInter(var int ptr){};\nfunc int Hlp_Is_oCMobLockable(var int ptr){};\nfunc int Hlp_Is_oCMobContainer(var int ptr){};\nfunc int Hlp_Is_oCMobDoor(var int ptr){};\nfunc int Hlp_Is_oCMobBed(var int ptr){};\nfunc int Hlp_Is_oCMobSwitch(var int ptr){};\nfunc int Hlp_Is_oCMobWheel(var int ptr){};\nfunc int Hlp_Is_oCMobLadder(var int ptr){};\nfunc int Hlp_Is_oCNpc(var int ptr){};\nfunc int Hlp_Is_oCItem(var int ptr){};\nfunc int Hlp_Is_zCVobLight(var int ptr){};\n

The usage of these functions is probably obvious, they checks if the given object belongs to class given in the function name.

"},{"location":"zengin/scripts/extenders/ikarus/functions/objects/#mem_insertvob","title":"MEM_InsertVob","text":"

Inserts a Vob with the visual vis at the waypoint wp. If the visual or waypoint does not exist, this is the behaviour this function undefined.

Note

The inserted Vob is even an oCMob, so it can be given a focus name, for example. But you can treat it like a zCVob), if you don't need the additional properties.

func int MEM_InsertVob(var string vis, var string wp)\n
Parameters
  • var string vis Name of the inserted Vob visual (\"FAKESCROLL.3DS\", \"FIRE.PFX\", \"SNA_BODY.ASC\", \"CHESTSMALL_NW_POOR_LOCKED.MDS\", \"ADD_PIRATEFLAG.MMS\" etc.)
  • var string wp Name of the waypoint to insert Vob on

Return value

The function returns a pointer to the created object.

"},{"location":"zengin/scripts/extenders/ikarus/functions/objects/#mem_deletevob","title":"MEM_DeleteVob","text":"

Deletes a specific Vob form world.

func void MEM_DeleteVob(var int vobPtr)\n
Parameters
  • var int vobPtr Pointer to a zCVob object to be deleted
"},{"location":"zengin/scripts/extenders/ikarus/functions/objects/#mem_renamevob","title":"MEM_RenameVob","text":"

Renames the passed Vob to the newName that is also passed.

The object becomes this first removed from the Vob-hashtable, then unnamed and then again inserted into the Vob-hashtable under a new name.

func void MEM_RenameVob(var int vobPtr, var string newName)\n
Parameters
  • var int vobPtr Pointer to a zCVob object to be renamed
  • var string newName The new Name of the Vob
MEM_TriggerVobMEM_UntriggerVob"},{"location":"zengin/scripts/extenders/ikarus/functions/objects/#mem_triggervob","title":"MEM_TriggerVob","text":"

Sends a trigger message to the Vob.

func void MEM_TriggerVob(var int vobPtr)\n
Parameters
  • var int vobPtr Pointer to a triggered zCVob

Danger

If triggering the Vob has immediate effects (even before MEM_TriggerVob is exited), the name of the Vob is corrupted during this time. It is not advisable to rename, trigger again or destroy the object at this moment, the behavior in such cases is untested.

"},{"location":"zengin/scripts/extenders/ikarus/functions/objects/#mem_untriggervob","title":"MEM_UntriggerVob","text":"

Sends an untrigger message to the Vob.

func void MEM_TriggerVob(var int vobPtr)\n
Parameters
  • var int vobPtr Pointer to an untriggered zCVob

Danger

If untriggering the Vob has immediate effects (even before MEM_TriggerVob is exited), the name of the Vob is corrupted during this time. It is not advisable to rename, trigger again or destroy the object at this moment, the behavior in such cases is untested.

"},{"location":"zengin/scripts/extenders/ikarus/functions/objects/#mem_searchvobbyname","title":"MEM_SearchVobByName","text":"

Returns the address of a zCVob named str if such a Vob exists.

func int MEM_SearchVobByName(var string str)\n
Parameters
  • var string str Name of searched zCVob

Return value

The function returns a pointer to the zCVob if the object with the given name exist. 0 is returned otherwise.

"},{"location":"zengin/scripts/extenders/ikarus/functions/objects/#mem_searchallvobsbyname","title":"MEM_SearchAllVobsByName","text":"

Variation of MEM_SearchVobByName. Creates a zCArray in which all pointers are to Vobs with the name str. If no Vob with the name exists, an empty zCArray is created. A pointer to the created zCArray is then returned. This can be evaluated, but should be released again with MEM_ArrayFree before the end of the frame (before the player can load) to avoid memory leaks.

func int MEM_SearchAllVobsByName(var string str)\n
Parameters
  • var string str Name of searched zCVob

Return value

The function returns a pointer to the created zCArray, that contains pointers to the all Vobs with the specified name.

"},{"location":"zengin/scripts/extenders/ikarus/functions/objects/#mem_getbuffercrc32","title":"MEM_GetBufferCRC32","text":"

Calculates the CRC32 hash value from a byte array starting at the address specified by buf and having a length of buflen.

func int MEM_GetBufferCRC32(var int buf, var int buflen)\n
Parameters
  • var int buf Address of a byte array, the hash calculation will begin from

  • var int buflen The length of the byte array starting from the address specified by buf

Return value

The function returns the calculated CRC32 hash value.

"},{"location":"zengin/scripts/extenders/ikarus/functions/objects/#mem_getstringhash","title":"MEM_GetStringHash","text":"

Calculates the CRC32 hash value for a string.

func int MEM_GetStringHash(var string str)\n
Parameters
  • var string str A string for which the hash value is to be calculated

Return value

The function returns an integer representing the calculated hash value for the input string.

"},{"location":"zengin/scripts/extenders/ikarus/functions/parser/","title":"`zCParser` related functions","text":""},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#zcparser-related-functions","title":"zCParser related functions","text":"

This Ikarus part provides some useful functions to work with parser, its instances, symbols and stack.

Danger

Remember to always assign an instance to a correct class. If you assign an oCNpc pointer to oCItem class you won't be able to read any data from it.

"},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#implementation","title":"Implementation","text":"

Ikarus.d on GitHub

"},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#initialization","title":"Initialization","text":"

The best way to initialize all Ikarus functions is to call MEM_InitAll() in the Init_Global() initialization function.

Warning

If you want to use Ikarus in Gothic 1, it is best to define your own Init_Global() function and call it from every world initialization function.

MEM_InitAll();\n
"},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_reinitparser","title":"MEM_ReinitParser","text":"

Parser operations are initialized with this function.

func void MEM_ReinitParser()\n

Tip

It's worth noting that MEM_ReinitParser is also invoked by the MEM_InitAll function.

"},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#pointers-and-instances","title":"Pointers and instances","text":""},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_ptrtoinst","title":"MEM_PtrToInst","text":"

Returns an instance pointed to by the pointer. If the pointer is null an error is thrown.

func MEMINT_HelperClass MEM_PtrToInst(var int ptr)\n
Parameters
  • var int ptr Pointer to return an instance from

Shortcut

In addition there is a function _^ with the same signature and functionality as MEM_PtrToInst. It is used as a shortcut, since the converting pointer to instance is commonly used while working with Ikarus.

func MEMINT_HelperClass _^ (var int ptr)\n
Example

Following code

var oCNpc her; her = MEM_PtrToInst(heroPtr);\n
is equivalent to
var oCNpc her; her = _^(heroPtr);\n
"},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_nulltoinst","title":"MEM_NullToInst","text":"

Returns an instance from a null pointer.

func MEMINT_HelperClass MEM_NullToInst()\n
"},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_assigninst","title":"MEM_AssignInst","text":"

Takes an instance from a pointer and assigns it to a given instance. If the pointer is null an error is thrown.

func void MEM_AssignInst(var int inst, var int ptr)\n
Parameters
  • var int ptr Pointer to assign an instance from
  • var int inst Instance to which the pointer will be assigned
Example

Following code

var oCNpc inst;\nMEM_AssignInst (inst, ptr); \n
is equivalent to
var oCNpc inst;\ninst = MEM_PtrToInst(ptr);\n
"},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_assigninstnull","title":"MEM_AssignInstNull","text":"

Assigns null pointer to a given instance.

func void MEM_AssignInstNull(var int inst)\n
Parameters
  • var int inst Instance to which the null pointer will be assigned
"},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_insttoptr","title":"MEM_InstToPtr","text":"

Returns a pointer to given instance.

func int MEM_InstToPtr(var int inst)\n
Parameters
  • var int inst The instance to which the pointer is returned
"},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_instgetoffset","title":"MEM_InstGetOffset","text":"

Alias to MEM_InstToPtr. Returns a pointer to given instance.

func int MEM_InstGetOffset(var int inst)\n
Parameters
  • var int inst The instance to which the pointer is returned
"},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_cpyinst","title":"MEM_CpyInst","text":"

Returns a copy of a given instance

func MEMINT_HelperClass MEM_CpyInst(var int inst)\n
Parameters
  • var int inst Instance to copy
example

Following code

selfCopy = MEM_CpyInst (self);\n
is equivalent to
selfCopy = MEM_PtrToInst (MEM_InstToPtr (self));\n
"},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#call-function","title":"Call function","text":"

You don't always know at compile time when you want to call which function. For example, if you want to call the condition function of a mob that the player has in focus, you are at a loss at compile time because you have no idea which mob the player will choose. Ikarus provides a way to call functions based on their name or symbol index. In the example of the mob, the name of the condition function can simply be looked up in the mob.

Note

The functions below also work for externals without any restrictions.

"},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#passing-parameters","title":"Passing Parameters","text":"

If the function to be called has parameters, these must first be placed on the data stack. The parameters must be pushed in the correct order, from left to right.

"},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_pushintparam","title":"MEM_PushIntParam","text":"

Passes an integer as a parameter to the called function.

func void MEM_PushIntParam (var int param)\n
Parameters
  • var int param Integer to pass as a function parameter
"},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_pushinstparam","title":"MEM_PushInstParam","text":"

Passes an instance as a parameter to the called function.

func void MEM_PushInstParam (var int inst)\n
Parameters
  • var int inst Instance to pass as a function parameter
"},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_pushstringparam","title":"MEM_PushStringParam","text":"

Passes a string as a parameter to the called function.

func void MEM_PushStringParam (var string str)\n
Parameters
  • var string str String to pass as a function parameter
"},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#the-call","title":"The call","text":""},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_call","title":"MEM_Call","text":"

Calls a function.

func void MEM_Call(var func fnc)\n
Parameters
  • var func fnc Function to be called
"},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_callbyid","title":"MEM_CallByID","text":"

Calls a function by its ID.

func void MEM_CallByID (var int symbID)\n
Parameters
  • var int symbID The ID of the function to be called
"},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_callbyptr","title":"MEM_CallByPtr","text":"

Calls a function by its pointer.

func void MEM_CallByPtr(var int ptr)\n
Parameters
  • var int ptr The pointer of the function to be called
"},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_callbyoffset","title":"MEM_CallByOffset","text":"

Calls a function by its offset.

func void MEM_CallByOffset(var int offset)\n
Parameters
  • var int offset The offset of the function to be called
"},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_callbystring","title":"MEM_CallByString","text":"

Calls a function by its name.

func void MEM_CallByString (var string fnc)\n
Parameters
  • var string fnc The name of the function IN CAPITAL LETTERS.
"},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#return-value","title":"Return value","text":"

If a function has a return value, it should be fetched from the data stack after it is called, otherwise stack overflows can occur under unfavorable circumstances (aside from that, you may simply want the return value because it contains important information).

"},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_popintresult","title":"MEM_PopIntResult","text":"

Retrieves an integer returned by the called function.

func int MEM_PopIntResult()\n
Return value

The function returns an integer returned by the previously called script function.

"},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_popstringresult","title":"MEM_PopStringResult","text":"

Retrieves a daedalus string returned by the called function.

func string MEM_PopStringResult()\n
Return value

The function returns a string returned by the previously called script function.

"},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_popinstresult","title":"MEM_PopInstResult","text":"

Retrieves an instance returned by the called function.

func MEMINT_HelperClass MEM_PopInstResult()\n
Return value

The function returns an instance returned by the previously called script function.

"},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#function-stuff","title":"Function stuff","text":""},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_getfuncid","title":"MEM_GetFuncID","text":"

Returns the ID of the given function.

func int MEM_GetFuncID(var func fnc)\n
Parameters
  • var func fnc The function whose ID is returned
"},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_getfuncptr","title":"MEM_GetFuncPtr","text":"

Returns the pointer of the given function.

func int MEM_GetFuncPtr(var func fnc)\n
Parameters
  • var func fnc The function whose pointer is returned
"},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_getfuncoffset","title":"MEM_GetFuncOffset","text":"

Returns the offset of the given function.

func int MEM_GetFuncOffset(var func fnc)\n
Parameters
  • var func fnc The function whose offset is returned
"},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_getfuncidbyoffset","title":"MEM_GetFuncIDByOffset","text":"

MEM_GetFuncID, but with an offset as a parameter.

func int MEM_GetFuncIDByOffset(var int offset)\n
Parameters
  • var int offset Offset of a function whose ID is returned

Return value

The function returns an ID of a function with a given offset.

"},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_replacefunc","title":"MEM_ReplaceFunc","text":"

Replaces the f1 function with f2 function so if you call the first function, the second function is called.

func void MEM_ReplaceFunc(var func f1, var func f2)\n
Parameters
  • var func f1 Function to replace
  • var func f2 Function called instead of f1
"},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#parser-stack","title":"Parser stack","text":""},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_getframeboundary","title":"MEM_GetFrameBoundary","text":"

Returns the address/pointer to the boundary of a stack frame (ESP).

func int MEM_GetFrameBoundary()\n
"},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_getcallerstackpos","title":"MEM_GetCallerStackPos","text":"

Retrieves the stack position (pop position) of the caller's caller (look at the example for better understanding).

func int MEM_GetCallerStackPos()\n
Return value

The function returns an integer representing the stack position of the caller's caller.

Example

After calling B() from within A(), when MEM_GetCallerStackPos() is invoked in function B(), it retrieves the stack position of the caller's caller, which is function A() in this case. Therefore, the variable adr will contain the stack position of function A().

func void A(){\n    B();\n};\n\nfunc void B(){\n    int adr; adr = MEM_GetCallerStackPos();\n    // Now, 'adr' will contain the stack position of A.\n};\n
"},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_setcallerstackpos","title":"MEM_SetCallerStackPos","text":"

Sets the stack position (pop position) of the caller's caller.

func void MEM_SetCallerStackPos(var int popPos)\n
Parameters
  • var int popPos An integer parameter representing the new stack position of the caller's caller
"},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#get-address","title":"Get address","text":""},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_getaddress_init","title":"MEM_GetAddress_Init","text":"

Initializes the MEM_GetIntAddress, MEM_GetFloatAddress and MEM_GetStringAddress functions.

func void MEM_GetAddress_Init()\n

Tip

It's worth noting that MEM_GetAddress_Init is also invoked by the MEM_InitAll function.

"},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_getintaddress","title":"MEM_GetIntAddress","text":"

Returns an address of a given integer.

func int MEM_GetIntAddress(var int i)\n
Parameters
  • var int i Integer whose address is returned

Shortcut

In addition there is a function _@ with the same signature and functionality as MEM_GetIntAddress.

func int _@(var int i)\n
"},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_getfloataddress","title":"MEM_GetFloatAddress","text":"

Returns an address of a given daedalus float.

func int MEM_GetFloatAddress(var float f)\n
Parameters
  • var float f Float whose address is returned

Shortcut

In addition there is a function _@f with the same signature and functionality as MEM_GetFloatAddress.

func int _@s(var string s)\n
"},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_getstringaddress","title":"MEM_GetStringAddress","text":"

Returns an address of a given string.

func int MEM_GetStringAddress(var string s)\n
Parameters
  • var string s String whose address is returned

Shortcut

In addition there is a function _@s with the same signature and functionality as MEM_GetStringAddress.

func int _@s(var string s)\n
"},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#str_getaddressinit","title":"STR_GetAddressInit","text":"

Alias to MEM_GetAddress_Init, kept for downward compatibility.

func void STR_GetAddressInit()\n
"},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#str_getaddress","title":"STR_GetAddress","text":"

Function similar to MEM_GetStringAddress. There is a guarantee, that this function works initialized i.e. invokes MEM_GetAddress_Init, but the first time may only return an address of a copy of the string.

func int STR_GetAddress(var string str)\n
"},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#static-arrays","title":"Static arrays","text":"

Accessing static arrays like this below is very tedious in Daedalus.

var int myStaticArray[42];\n
It is not possible to access myStaticArray[i] with a variable index i, but only with a constant. This changes with the following functions.

Danger

Neither function performs any kind of validity check. If the value passed is not an array or offsets are beyond the boundaries of the array passed, the behavior is undefined.

"},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_initstatarrs","title":"MEM_InitStatArrs","text":"

Initializes static arrays read and write functions.

func void MEM_InitStatArrs()\n
"},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_writestatarr","title":"MEM_WriteStatArr","text":"

Changes the value at the offset of a static integer-array.

func void MEM_WriteStatArr (var int array, var int offset, var int value)\n
Parameters
  • var int array Array which will be edited
  • var int offset Array index at which value will be edited
  • var int value The new value
"},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_readstatarr","title":"MEM_ReadStatArr","text":"

Reads the value at the specific offset of a static integer-array.

func int MEM_ReadStatArr (var int array, var int offset)\n
Parameters
  • var int array Array to get a value from
  • var int offset Array index of the value to return

Return value

The function returns an integer value from the offset of a given static array.

"},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_writestatstringarr","title":"MEM_WriteStatStringArr","text":"

Changes the value at the offset of a static string-array.

func void MEM_WriteStatStringArr(var string array, var int offset, var string value)\n
Parameters
  • var string array Array which will be edited
  • var int offset Array index at which value will be edited
  • var string value The new value
"},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_readstatstringarr","title":"MEM_ReadStatStringArr","text":"

Reads the value at the specific offset of a static string-array.

func string MEM_ReadStatStringArr(var string array, var int offset)\n
Parameters
  • var string array Array to get a value from
  • var int offset Array index of the value to return

Return value

The function returns a string form the offset of a given static array.

"},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#parser-symbol","title":"Parser symbol","text":""},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_setcurrparsersymb","title":"MEM_SetCurrParserSymb","text":"

Makes currParserSymb point to the symbol of the specified instance.

func void MEM_SetCurrParserSymb (var int inst)\n
Parameters
  • var int inst Instance to whose symbol currParserSymb will be set
"},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#currparsersymb","title":"currParserSymb","text":"

An instance representing current parser symbol.

INSTANCE currParserSymb (zCPar_Symbol);\n
"},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_findparsersymbol","title":"MEM_FindParserSymbol","text":"

Returns the index of the parser symbol with name inst if such a symbol exists.

func int MEM_FindParserSymbol(var string inst)\n
Parameters
  • var string inst Name of the symbol to be found

Return value

The function returns the index of the parser symbol with name inst if such a symbol exists. If non exists, a warning is issued and -1 is returned.

"},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_getsymbolindex","title":"MEM_GetSymbolIndex","text":"

Alias to MEM_FindParserSymbol. Returns the index of the parser symbol with name inst if such a symbol exists.

func int MEM_GetSymbolIndex(var string inst)\n
Parameters
  • var string inst Name of the symbol to be found

Return value

The function returns the index of the parser symbol with name inst if such a symbol exists. If non exists, a warning is issued and -1 is returned.

"},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_getparsersymbol","title":"MEM_GetParserSymbol","text":"

Looks for the parser symbol with the name inst and returns a pointer to the appropriate zCPar_Symbol structure.

func int MEM_GetParserSymbol (var string inst)\n
Parameters
  • var string inst Name of the symbol to be found

Return value

The function returns the appropriate zCPar_Symbol structure of the parser symbol with name inst if such a symbol exists. If non exists, a warning is issued and 0 is returned.

"},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_getsymbol","title":"MEM_GetSymbol","text":"

Alias to MEM_GetParserSymbol. Looks for the parser symbol with the name inst and returns a pointer to the appropriate zCPar_Symbol structure.

func int MEM_GetSymbol(var string inst)\n
Parameters
  • var string inst Name of the symbol to be found

Return value

The function returns the appropriate zCPar_Symbol structure of the parser symbol with name inst if such a symbol exists. If non exists, a warning is issued and 0 is returned.

"},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_getsymbolbyindex","title":"MEM_GetSymbolByIndex","text":"

MEM_GetParserSymbol, but with ID (index) as a parameter.

func int MEM_GetSymbolByIndex(var int id)\n
Parameters
  • var string inst ID (index) of the symbol to be found

Return value

The function returns the appropriate zCPar_Symbol structure of the parser symbol with name inst if such a symbol exists. If non exists, a warning is issued and 0 is returned.

"},{"location":"zengin/scripts/extenders/ikarus/functions/string/","title":"String operations","text":""},{"location":"zengin/scripts/extenders/ikarus/functions/string/#string-operations","title":"String operations","text":"

Collection of Ikarus functions to manipulate and format strings.

"},{"location":"zengin/scripts/extenders/ikarus/functions/string/#initialization","title":"Initialization","text":"

The best way to initialize all Ikarus functions is to call MEM_InitAll() in the Init_Global() initialization function.

Warning

If you want to use Ikarus in Gothic 1, it is best to define your own Init_Global() function and call it from every world initialization function.

MEM_InitAll();\n
"},{"location":"zengin/scripts/extenders/ikarus/functions/string/#implementation","title":"Implementation","text":"

Ikarus.d on GitHub

"},{"location":"zengin/scripts/extenders/ikarus/functions/string/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/ikarus/functions/string/#str_getcharat","title":"STR_GetCharAt","text":"

Returns the ASCII value of a character at a specific position in a string.

func int STR_GetCharAt (var string str, var int pos)\n
Parameters
  • var string str The input string
  • var int pos The position of the character

Return value

The function returns the ASCII value of the character at the specified position.

"},{"location":"zengin/scripts/extenders/ikarus/functions/string/#str_len","title":"STR_Len","text":"

Returns the length of a string.

func int STR_Len (var string str)\n
Parameters
  • var string str The input string

Return value

The function returns the length of the string in characters.

"},{"location":"zengin/scripts/extenders/ikarus/functions/string/#str_tochar","title":"STR_toChar","text":"

Converts a string to a pointer to its character array.

func int STR_toChar (var string str)\n
Parameters
  • var string str The input string

Return value

The function returns a pointer to the character array representing the input string str

"},{"location":"zengin/scripts/extenders/ikarus/functions/string/#str_fromchar","title":"STR_FromChar","text":"

Converts a character array to a string.

func string STR_FromChar(var int char)\n
Parameters
  • var int char Pointer to the character array

Return value

The function returns a string representation of the character array.

"},{"location":"zengin/scripts/extenders/ikarus/functions/string/#str_substr","title":"STR_SubStr","text":"

Extracts a substring from a given string.

func string STR_SubStr (var string str, var int start, var int count)\n
Parameters
  • var string str The input string
  • var int start The starting position of the substring
  • var int count The length of the substring

Return value

The function returns a substring, if the starting position is invalid an empty string is returned.

"},{"location":"zengin/scripts/extenders/ikarus/functions/string/#str_prefix","title":"STR_Prefix","text":"

Extracts a prefix of a given string, similar to STR_SubStr, but with the starting position set to the first character of the string.

func string STR_Prefix (var string str, var int len)\n
Parameters
  • var string str The input string
  • var int count The length of the prefix

Return value

The function returns a prefix of the input string with the specified length.

"},{"location":"zengin/scripts/extenders/ikarus/functions/string/#str_compare","title":"STR_Compare","text":"

Compares two strings lexicographically and returns a result indicating their relative order.

func int STR_Compare(var string str1, var string str2)\n
Parameters
  • var string str1 The first string to compare
  • var string str2 The second string to compare

Return Value

The function returns an integer value representing the result of the comparison:

  • STR_GREATER (1): If str1 comes lexicographically after str2.
  • STR_EQUAL (0): If str1 is lexicographically equal to str2.
  • STR_SMALLER (-1): If str1 comes lexicographically before str2.
Examples

The comparison is based on lexicographic order, which is the order of characters as they appear in the ASCII table. Uppercase letters come before lowercase letters.

int result1 = STR_Compare(\"A\", \"B\");\n// The 'result1' variable now contains STR_SMALLER\n\nint result2 = STR_Compare(\"ABC\", \"ABC\");\n// The 'result2' variable now contains STR_EQUAL\n\nint result3 = STR_Compare(\"AA\", \"A\");\n// The 'result3' variable now contains STR_GREATER\n\nint result4 = STR_Compare(\"BA\", \"BB\");\n// The 'result4' variable now contains STR_SMALLER\n\nint result5 = STR_Compare(\"B\", \"a\");\n// The 'result5' variable now contains STR_SMALLER\n\nint result6 = STR_Compare(\"A\", \"\");\n// The 'result6' variable now contains STR_GREATER\n
"},{"location":"zengin/scripts/extenders/ikarus/functions/string/#str_toint","title":"STR_ToInt","text":"

Converts a string to an integer.

func int STR_ToInt (var string str)\n
Parameters
  • var string str The input string

Return Value

The function returns an integer value of the string, if a string is invalid (doesn't contain an integer) zero is returned.

"},{"location":"zengin/scripts/extenders/ikarus/functions/string/#str_indexof","title":"STR_IndexOf","text":"

Searches for a substring tok within a given string and returns the index of the first occurrence of tok, taking into account upper and lower case letters.

func int STR_IndexOf(var string str, var string tok)\n
Parameters
  • var string str The string in which to search for tok.
  • var string tok The substring to search for within str.

Return Value

The function returns the index at which the first occurrence of tok begins within str. If tok is not found in str, the function returns -1.

Examples
int index1 = STR_IndexOf(\"Hello World!\", \"Hell\");\n// The 'index1' variable now contains 0\n\nint index2 = STR_IndexOf(\"Hello World!\", \"World\");\n// The 'index2' variable now contains 6\n\nint index3 = STR_IndexOf(\"Hello World!\", \"Cake\");\n// The 'index3' variable now contains -1\n\nint index4 = STR_IndexOf(\"Hello World!\", \"\");\n// The 'index4' variable now contains 0\n\nint index5 = STR_IndexOf(\"Hello\", \"Hello World!\");\n// The 'index5' variable now contains -1\n\nint index6 = STR_IndexOf(\"hello Hell!\", \"Hell\");\n// The 'index6' variable now contains 6\n\nint index7 = STR_IndexOf(\"\", \"\");\n// The 'index7' variable now contains 0\n
"},{"location":"zengin/scripts/extenders/ikarus/functions/string/#str_splitcount","title":"STR_SplitCount","text":"

Counts the number of parts a string splits into when using a specified separator.

func int STR_SplitCount(var string str, var string separator)\n
Parameters
  • var string str The input string to be split.
  • var string separator The separator character or string used to split the input string.

Return Value

The function returns a number of parts the input string splits into when using the specified separator.

Example
string inputStr = \"This is a sentence.\";\nint count = STR_SplitCount(inputStr, \" \");\n// The 'count' variable now contains 4\n
"},{"location":"zengin/scripts/extenders/ikarus/functions/string/#str_split","title":"STR_Split","text":"

Splits a string into multiple substrings based on a specified separator and returns the substring at a specified offset.

func string STR_Split(var string str, var string separator, var int offset)\n

Parameters

  • var string str The input string to be split.
  • var string separator The separator character or string used to split the input string.
  • var int offset The index of the substring to be returned after splitting. The index is zero-based.

Return Value

The function returns a substring at the specified offset after splitting the input string. If the offset is greater than or equal to the number of parts generated by splitting, an empty string is returned.

Example

func void foo() {\n    string inputStr = \"This is a sentence.\";\n    string tok1 = STR_Split(inputStr, \" \", 0); // This\n    string tok2 = STR_Split(inputStr, \" \", 1); // is\n    string tok3 = STR_Split(inputStr, \" \", 2); // a\n    string tok4 = STR_Split(inputStr, \" \", 3); // sentence\n};\n
At the end of the function, tok1 contains \"This\", tok2 contains \"is\", tok3 contains \"a\", and tok4 contains \"sentence.\"."},{"location":"zengin/scripts/extenders/ikarus/functions/string/#str_upper","title":"STR_Upper","text":"

Converts a string to uppercase.

func string STR_Upper(var string str)\n
Parameters
  • var string str The input string

Return Value

The function returns a copy of str with all uppercase letters converted to their corresponding uppercase letters.

"},{"location":"zengin/scripts/extenders/ikarus/functions/string/#str_lower","title":"STR_Lower","text":"

Converts a string to lowercase.

func string STR_Lower(var string str)\n
Parameters
  • var string str The input string

Return Value

The function returns a copy of str with all lowercase letters converted to their corresponding uppercase letters.

"},{"location":"zengin/scripts/extenders/ikarus/functions/time_benchmark/","title":"Time and Benchmark","text":""},{"location":"zengin/scripts/extenders/ikarus/functions/time_benchmark/#time-and-benchmark","title":"Time and Benchmark","text":"

Set of functions to time measurement and Benchmark.

"},{"location":"zengin/scripts/extenders/ikarus/functions/time_benchmark/#initialization","title":"Initialization","text":"

The best way to initialize all Ikarus functions is to call MEM_InitAll() in the Init_Global() initialization function.

Warning

If you want to use Ikarus in Gothic 1, it is best to define your own Init_Global() function and call it from every world initialization function.

MEM_InitAll();\n
"},{"location":"zengin/scripts/extenders/ikarus/functions/time_benchmark/#implementation","title":"Implementation","text":"

Ikarus.d on GitHub

"},{"location":"zengin/scripts/extenders/ikarus/functions/time_benchmark/#time-functions","title":"Time functions","text":""},{"location":"zengin/scripts/extenders/ikarus/functions/time_benchmark/#mem_getsystemtime","title":"MEM_GetSystemTime","text":"

Returns the elapsed time since Gothic started.

func int MEM_GetSystemTime()\n
Return value

The function returns the elapsed time since the start of Gothic in milliseconds. This value is used for timing measurements, in the BenchmarkMS functions.

"},{"location":"zengin/scripts/extenders/ikarus/functions/time_benchmark/#mem_getperformancecounter","title":"MEM_GetPerformanceCounter","text":"

Call to the WinAPI QueryPerformanceCounter function.

func int MEM_GetPerformanceCounter()\n
Return value

The function returns a value representing the number of elapsed ticks since the system was started. This value is used for timing measurements, in the BenchmarkPC functions.

"},{"location":"zengin/scripts/extenders/ikarus/functions/time_benchmark/#benchmark-functions","title":"Benchmark functions","text":"

Tip

For reliable results, avoid measuring a single run of a function; instead, measure the total duration of multiple runs (e.g., 1000). This is crucial, especially for very fast functions, as a single run can distort the measurement. Use _N benchmark functions to include a parameter specifying the number of runs for function f.

Choose the parameter n to ensure meaningful results. If n executions take less than a millisecond, obtaining a return value in milliseconds has no sense. For very fast functions, the time spent in the benchmark function, not in f, significantly affects the measurement, falsifying the result. Reliable measurements are achievable only for functions with sufficient slowness.

For reference, here is a timing for some operations (in nanoseconds, i.e., billionths of a second):

- Function call (jumping back and forth): 30ns\n- Elementary calculation (e.g., i = i + 1): 130ns\n- Wld_IsTime: 200ns\n- MEM_ReadInt, MEM_WriteInt: 350ns\n- Hlp_StrCmp(\"Hello\", \"Hello\"): 500ns\n- MEM_InstToPtr: 1400ns\n- (small) Allocate and free memory: 9700ns\n- CALL__stdcall (in empty function): 29000ns\n- MEM_GetParserSymb: 280000ns\n\n- Iteration of the benchmark function: 300ns\n
"},{"location":"zengin/scripts/extenders/ikarus/functions/time_benchmark/#mem_benchmarkms","title":"MEM_BenchmarkMS","text":"

Benchmark of the execution time for a specified function. (Milliseconds)

func int MEM_BenchmarkMS(var func f)\n
Parameters
  • var func f Function to benchmark

Return value

The function returns the duration of a function execution in milliseconds.

"},{"location":"zengin/scripts/extenders/ikarus/functions/time_benchmark/#mem_benchmarkmms","title":"MEM_BenchmarkMMS","text":"

Benchmark of the execution time for a specified function. (microseconds)

func int MEM_BenchmarkMMS(var func f)\n
Parameters
  • var func f Function to benchmark

Return value

The function returns the duration of a function execution in microseconds.

"},{"location":"zengin/scripts/extenders/ikarus/functions/time_benchmark/#mem_benchmarkpc","title":"MEM_BenchmarkPC","text":"

Benchmark of the execution time for a specified function, using the Performancecounter.

func int MEM_BenchmarkMS(var func f)\n
Parameters
  • var func f Function to benchmark

Return value

The function returns the number of Performancecounter ticks the function needs.

"},{"location":"zengin/scripts/extenders/ikarus/functions/time_benchmark/#mem_benchmarkms_n","title":"MEM_BenchmarkMS_N","text":"

MEM_BenchmarkMS, but with the parameter to specify the number of function runs.

func int MEM_BenchmarkMS_N(var func f, var int n)\n
Parameters
  • var func f Function to benchmark
  • var int n Number of runs

Return value

The function returns a summed duration of multiple (n) runs of the function in milliseconds.

"},{"location":"zengin/scripts/extenders/ikarus/functions/time_benchmark/#mem_benchmarkmms_n","title":"MEM_BenchmarkMMS_N","text":"

MEM_BenchmarkMMS, but with the parameter to specify the number of function runs.

func int MEM_BenchmarkMMS_N(var func f, var int n)\n
Parameters
  • var func f Function to benchmark
  • var int n Number of runs

Return value

The function returns a summed duration of multiple (n) runs of the function in microseconds.

"},{"location":"zengin/scripts/extenders/ikarus/functions/time_benchmark/#mem_benchmarkpc_n","title":"MEM_BenchmarkPC_N","text":"

MEM_BenchmarkPC, but with the parameter to specify the number of function runs.

func int MEM_BenchmarkPC_N(var func f, var int n)\n
Parameters
  • var func f Function to benchmark
  • var int n Number of runs

Return value

The function returns a summed number of Performancecounter ticks needed to execute function multiple (n) times.

"},{"location":"zengin/scripts/extenders/ikarus/functions/win_utilities/","title":"Windows Utilities","text":""},{"location":"zengin/scripts/extenders/ikarus/functions/win_utilities/#windows-utilities","title":"Windows Utilities","text":"

This part of Ikarus implements some WinAPI functions that can be used directly from Gothic scripts.

"},{"location":"zengin/scripts/extenders/ikarus/functions/win_utilities/#initialization","title":"Initialization","text":"

The best way to initialize all Ikarus functions is to call MEM_InitAll() in the Init_Global() initialization function.

Warning

If you want to use Ikarus in Gothic 1, it is best to define your own Init_Global() function and call it from every world initialization function.

MEM_InitAll();\n
"},{"location":"zengin/scripts/extenders/ikarus/functions/win_utilities/#implementation","title":"Implementation","text":"

Ikarus.d on GitHub

"},{"location":"zengin/scripts/extenders/ikarus/functions/win_utilities/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/ikarus/functions/win_utilities/#loadlibrary","title":"LoadLibrary","text":"

Loads the specified module into the address space of the calling process. Full documentation here.

func int LoadLibrary(var string lpFileName)\n
Parameters
  • var string lpFileName Name of loaded module

Return value

The function returns a handle to the module.

"},{"location":"zengin/scripts/extenders/ikarus/functions/win_utilities/#getprocaddress","title":"GetProcAddress","text":"

Retrieves the address from the specified dynamic-link library. Full documentation here.

func int GetProcAddress(var int hModule, var string lpProcName)\n
Parameters
  • var int hModule A handle to the DLL module that contains the function or variable. Can be obtained using the LoadLibrary function.
  • var string lpProcName The function or variable name.

Return value The function returns address of the function or variable.

"},{"location":"zengin/scripts/extenders/ikarus/functions/win_utilities/#findkerneldllfunction","title":"FindKernelDllFunction","text":"

Uses GetProcAddress to find function inside the KERNEL32.DLL file.

func int FindKernelDllFunction(var string name)\n
Parameters
  • var string name Name of the looked function.

Return value

The function returns address of the function.

"},{"location":"zengin/scripts/extenders/ikarus/functions/win_utilities/#virtualprotect","title":"VirtualProtect","text":"

Changes the protection on a region of committed pages in the virtual address space of the calling process. Full documentation here.

func int VirtualProtect(var int lpAddress, var int dwSize, var int flNewProtect)\n
Parameters
  • var int lpAddress The address of the starting page of the region of pages whose access protection attributes are to be changed.
  • var int dwSize The size of the region whose access protection attributes are to be changed, in bytes.
  • var int flNewProtect The memory protection option. All options can be found here.

Return value

The function returns lpflOldProtectPtr - a pointer to a variable that receives the previous access protection value.

Author's comment:

I made lpflOldProtectPtr the return value and ignored the return Value of VirtualProtect.

"},{"location":"zengin/scripts/extenders/ikarus/functions/win_utilities/#memoryprotectionoverride","title":"MemoryProtectionOverride","text":"

Alias to VirtualProtect but with predefined PAGE_EXECUTE_READWRITE protection option

func void MemoryProtectionOverride(var int address, var int size)\n
Parameters
  • var int address The address of the starting page of the region of pages whose access protection attributes are to be changed.
  • var int size The size of the region whose access protection attributes are to be changed, in bytes.
"},{"location":"zengin/scripts/extenders/ikarus/functions/win_utilities/#mem_messagebox","title":"MEM_MessageBox","text":"

Calls the WinAPI MessageBox function.

func int MEM_MessageBox(var string txt, var string caption, var int type)\n
Parameters
  • var string txt Content of the MessageBox.
  • var string caption Header of MessageBox.
  • var int type Type of MessageBox. All types listed here.
"},{"location":"zengin/scripts/extenders/ikarus/functions/win_utilities/#mem_infobox","title":"MEM_InfoBox","text":"

Alias to MEM_MessageBox with \"Information:\" header and MB_OK | MB_ICONINFORMATION type.

func void MEM_InfoBox(var string txt)\n
Parameters
  • var string txt Content of the InfoBox.
"},{"location":"zengin/scripts/extenders/ikarus/functions/win_utilities/#examples","title":"Examples","text":""},{"location":"zengin/scripts/extenders/ikarus/functions/win_utilities/#sleep","title":"Sleep","text":"

Following function calls the Sleep function from the KERNEL32.DLL. A documentation of this function can be found here.

func void Sleep(var int ms) {\n    var int adr;\n    adr = GetProcAddress(LoadLibrary(\"KERNEL32.DLL\"), \"Sleep\");\n\n    CALL_IntParam(ms);\n    CALL__stdcall(adr); // 0x007B47E6\n};\n
"},{"location":"zengin/scripts/extenders/lego/","title":"LeGo","text":""},{"location":"zengin/scripts/extenders/lego/#lego","title":"LeGo","text":"

LeGo (LehonaGottfried) is a script packet built on top of Ikarus.

Contacts Author Lehona, Gottfried & contributors GitHub LeGo Forum LeGo

Note

The code for LeGo is hosted on GitHub and LeGo has its very own documentation page.

"},{"location":"zengin/scripts/extenders/lego/applications/anim8/","title":"Anim8","text":""},{"location":"zengin/scripts/extenders/lego/applications/anim8/#anim8","title":"Anim8","text":"

This package allows int or float values to be \"animated\" over a period of time. It is possible to string several commands together and to set the type of movement. The new version of PrintS from Interface uses Anim8.

"},{"location":"zengin/scripts/extenders/lego/applications/anim8/#dependencies","title":"Dependencies","text":"
  • Floats
"},{"location":"zengin/scripts/extenders/lego/applications/anim8/#initialization","title":"Initialization","text":"

Initialize with LeGo_Anim8 flag.

LeGo_Init(LeGo_Anim8);\n
"},{"location":"zengin/scripts/extenders/lego/applications/anim8/#implementation","title":"Implementation","text":"

Anim8.d on GitHub

"},{"location":"zengin/scripts/extenders/lego/applications/anim8/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/applications/anim8/#anim8_new","title":"Anim8_New","text":"

Creates a new Anim8 object that can be filled with commands.

func int Anim8_New(var int initialValue, var int IsFloat)\n
Parameters
  • var int initialValue The initial value to start animating from. Can be an integer, or an Ikarus float.
  • var int IsFloat If the initialValue is an Ikarus float, this parameter must be set to TRUE. If it is an integer, it must be set to FALSE.

Return value

The function returns handle of the Anim8 object.

"},{"location":"zengin/scripts/extenders/lego/applications/anim8/#anim8_newext","title":"Anim8_NewExt","text":"

Creates a new Anim8 object with advanced options. Extends the Anim8_New function.

func int Anim8_NewExt(var int value, var func handler, var int data, var int IsFloat)\n
Parameters
  • var int value The initial value to start animating from. Can be an integer, or an Ikarus float.
  • var func handler This function is called whenever the object is updated. The signature of the functions depends on the data value: data != 0: func void handler(var int data, var int value), data == 0: func void handler(var int value).
  • var int data Optional parameter to send an additional value to the handler function. If data == 0, it is ignored.
  • var int IsFloat If the initialValue is an Ikarus float, this parameter must be set to TRUE. If it is an integer, it must be set to FALSE.

Return value

The function returns handle of the Anim8 object.

"},{"location":"zengin/scripts/extenders/lego/applications/anim8/#anim8_delete","title":"Anim8_Delete","text":"

Deletes an Anim8 object created with Anim8_New.

func void Anim8_Delete(var int handle)\n
Parameters
  • var int handle Handle returned from Anim8_New
"},{"location":"zengin/scripts/extenders/lego/applications/anim8/#anim8_get","title":"Anim8_Get","text":"

Get current value of the object.

func int Anim8_Get(var int handle)\n
Parameters
  • var int handle Handle returned from Anim8_New

Return value

The function returns value of the object.

"},{"location":"zengin/scripts/extenders/lego/applications/anim8/#anim8_set","title":"Anim8_Set","text":"

Sets the value of the object.

func void Anim8_Set(var int handle, var int value)\n
Parameters
  • var int handle Handle returned from Anim8_New
  • var int value New value of the object
"},{"location":"zengin/scripts/extenders/lego/applications/anim8/#anim8_empty","title":"Anim8_Empty","text":"

Indicates whether the object is empty, i.e. has no more commands to process.

func int Anim8_Empty(var int handle)\n
Parameters
  • var int handle Handle returned from Anim8_New

Return value

The function returns TRUE if object is empty (has no more commands), FALSE is returned otherwise.

"},{"location":"zengin/scripts/extenders/lego/applications/anim8/#anim8_removeifempty","title":"Anim8_RemoveIfEmpty","text":"

If desired, Anim8 can automatically delete an object after it is empty.

func void Anim8_RemoveIfEmpty(var int handle, var int on)\n
Parameters
  • var int handle Handle returned from Anim8_New
  • var int on TRUE: enable, FALSE: disable
"},{"location":"zengin/scripts/extenders/lego/applications/anim8/#anim8_removedataifempty","title":"Anim8_RemoveDataIfEmpty","text":"

With Anim8_NewExt handler and data can be set. If this function is called with TRUE, data is taken as a handle and delete(data) is called if the object is empty. Works only if Anim8_RemoveIfEmpty is also activated.

func void Anim8_RemoveDataIfEmpty(var int handle, var int on)\n
Parameters
  • var int handle Handle returned from Anim8_New
  • var int on TRUE: enable, FALSE: disable
"},{"location":"zengin/scripts/extenders/lego/applications/anim8/#anim8_1","title":"Anim8","text":"

Packet core. Gives the object a new command to process.

func void Anim8(var int handle, var int target, var int span, var int interpol)\n
Parameters
  • var int handle Handle returned from Anim8_New
  • var int target Target value of this command. When the object's value has reached this value, the command is considered completed and deleted.
  • var int span Action duration in milliseconds
  • var int interpol What form of movement is used (See constants for this)
"},{"location":"zengin/scripts/extenders/lego/applications/anim8/#anim8q","title":"Anim8q","text":"

As already mentioned above, Anim8 can also process several commands one after the other. While Anim8 completely resets the object and deletes all commands, Anim8q just appends a new command to the list. This will be processed as soon as the previous one is completed.

func void Anim8q(var int handle, var int target, var int span, var int interpol)\n
Parameters
  • var int handle Handle returned from Anim8_New
  • var int target Target value of this command. When the object's value has reached this value, the command is considered completed and another one in the queue will start.
  • var int span Action duration in milliseconds
  • var int interpol What form of movement is used (See constants for this)
"},{"location":"zengin/scripts/extenders/lego/applications/anim8/#anim8_callonremove","title":"Anim8_CallOnRemove","text":"

Registers a function to be called when the object is deleted (e.g. by Anim8_RemoveIfEmpty)

func void Anim8_CallOnRemove(var int handle, var func dfnc)\n
Parameters
  • var int handle Handle returned from Anim8_New
  • var func dfnc This function is called when the object is deleted
"},{"location":"zengin/scripts/extenders/lego/applications/anim8/#examples","title":"Examples","text":""},{"location":"zengin/scripts/extenders/lego/applications/anim8/#count-up-to-a-number","title":"Count up to a number","text":"

Count from 0 to 10 in 10 seconds. We use the Print_Ext function from Interface to display the text.

func void Example1()\n{\n    // First we create a handle to a text:\n    var int MyText; MyText = Print_Ext(20, 20, \"0\", Font_Screen, COL_White, -1);\n\n    // After that we create a new, extended Anim8 object.\n    // It gets a handler and the handle to the text as data:\n    var int MyAnim8; MyAnim8 = Anim8_NewExt(0, MyLoop1, MyText, FALSE); \n    // Start value 1, MyLoop1 as handler, MyText as data and no float\n\n    // Now the command to count to 10:\n    Anim8(MyAnim8, 10, 10000, A8_Constant); // With MyAnim8 to 10 within 10000ms with constant motion.\n\n    // So that the text and the Anim8 object are deleted after the process. \n    // Now we have to do two more things:\n    Anim8_RemoveIfEmpty(MyAnim8, TRUE);\n    Anim8_RemoveDataIfEmpty(MyAnim8, TRUE);\n};\n\nfunc void MyLoop1(var int MyText, var int Number)\n{\n    var zCViewText t; t = _^(myText);\n\n    // Now the text is set to the value of the Anim8 object:\n    t.text = IntToString(Number);\n\n    // As I said, everything is deleted fully automatically\n};\n
A similar example can be found in the Interface examples."},{"location":"zengin/scripts/extenders/lego/applications/anim8/#moving-zcvob-in-loop","title":"Moving zCVob in loop","text":"

Now we make a vob constantly move back and forth, but without a mover. FrameFunctions are used for the loop:

var zCVob MyVob;\nvar int MyVobAni;\n\nfunc void Example2()\n{\n    // We use Ikarus to get a pointer to a known VOB:\n    MyVob = MEM_PtrToInst(MEM_SearchVobByName(\"MYVOB\"));\n    // There must be a vob with the appropriate name in the world for this.\n\n    // Since the positions of a vob are floats, this time Anim8 must also use floats:\n    MyVobAni = Anim8_New(MyVob.trafoObjToWorld[3], TRUE);\n    // The X position of the vob serves as the starting value.\n    // We will also move it along this axis.\n\n    // Now start a loop that \"nudges\" the vob over and over again:\n    FF_Apply(MyVobLoop);\n};\n\nfunc void MyVobLoop()\n{\n    // We get the pointer to the VOB again\n    MyVob = MEM_PtrToInst(MEM_SearchVobByName(\"MYVOB\"));\n\n    // Whenever there are no more commands, we add new ones:\n    if(Anim8_Empty(MyVobAni))\n    {\n        // First move by three meters:\n        Anim8(MyVobAni, addf(MyVob.trafoObjToWorld[3], mkf(300)), 1000, A8_SlowEnd);\n        // Then wait half a second:\n        Anim8q(MyVobAni, 0, 500, A8_Wait);\n        // And then back again:\n        Anim8q(MyVobAni, MyVob.trafoObjToWorld[3], 1000, A8_SlowEnd);\n        // And wait another half a second:\n        Anim8q(MyVobAni, 0, 500, A8_Wait);\n        // Note the 'q' in the follow-up commands.\n        // While Anim8 completely resets the command list, i.e. starts again, Anim8q appends the command to the queue.\n        // So you can tinker with a command sequence.\n    };\n    // Of course, we must set the \"animated\" value to the VOB itself\n    MyVob.trafoObjToWorld[3] = Anim8_Get(MyVobAni);\n};\n
"},{"location":"zengin/scripts/extenders/lego/applications/bars/","title":"Bars","text":""},{"location":"zengin/scripts/extenders/lego/applications/bars/#bars","title":"Bars","text":"

This package makes it very easy to add new bars, for e.g. stamina.

"},{"location":"zengin/scripts/extenders/lego/applications/bars/#dependencies","title":"Dependencies","text":"
  • PermMem
  • View
"},{"location":"zengin/scripts/extenders/lego/applications/bars/#initialization","title":"Initialization","text":"

Initialize with LeGo_Bars flag.

LeGo_Init(LeGo_Bars);\n
"},{"location":"zengin/scripts/extenders/lego/applications/bars/#implementation","title":"Implementation","text":"

Bars.d on GitHub

"},{"location":"zengin/scripts/extenders/lego/applications/bars/#functions","title":"Functions","text":"

Note

If the GothicBar prototype is selected as the initial type (GothicBar@ as the constructor), the user's own bars are visually indistinguishable from those used in Gothic.

"},{"location":"zengin/scripts/extenders/lego/applications/bars/#bar_create","title":"Bar_Create","text":"

Creates a new bar from a constructor instance.

func int Bar_Create(var int inst)\n

Parameters

  • var int inst Constructor instance of Bar class

Return value

The function returns the address of the new bar, aka the handle.

Examples

var int bar; bar = Bar_Create(GothicBar@);

var int bar; bar = Bar_Create(GothicBar@); // Create a new bar\nBar_SetPercent(bar, 50);                   // And set the value to 50%\n
func void Example_1()\n{\n    var int bar; bar = Bar_Create(GothicBar@); // Create a new bar\n    Bar_SetPercent(bar, 50);                   // And set the value to 50%\n};\n
"},{"location":"zengin/scripts/extenders/lego/applications/bars/#bar_delete","title":"Bar_Delete","text":"

Deletes a bar from the screen and from memory.

func void Bar_Delete(var int bar)\n

Parameters

  • var int bar Handle returned from Bar_Create
"},{"location":"zengin/scripts/extenders/lego/applications/bars/#bar_setmax","title":"Bar_SetMax","text":"

Changes a bar's maximum value but does not update its bar length (only Bar_SetPercent, Bar_SetPromille and Bar_SetValue)

func void Bar_SetMax(var int bar, var int max)\n
Parameters
  • var int bar Handle returned from Bar_Create

  • var int max New maximum value

"},{"location":"zengin/scripts/extenders/lego/applications/bars/#bar_setvalue","title":"Bar_SetValue","text":"

Sets the value of the bar.

func void Bar_SetValue(var int bar, var int val)\n
Parameters
  • var int bar Handle returned from Bar_Create
  • var int val New value of the bar
"},{"location":"zengin/scripts/extenders/lego/applications/bars/#bar_setpercent","title":"Bar_SetPercent","text":"

Sets the value of the bar but as a percentage (0..100).

func void Bar_SetPercent(var int bar, var int perc)\n
Parameters
  • var int bar Handle returned from Bar_Create
  • var int perc New value of the bar in percent
"},{"location":"zengin/scripts/extenders/lego/applications/bars/#bar_setpromille","title":"Bar_SetPromille","text":"

Sets the value of the bar but per mille (0..1000).

func void Bar_SetPromille(var int bar, var int pro)\n
Parameters
  • var int bar Handle returned from Bar_Create
  • var int pro New value of the bar in per mille
"},{"location":"zengin/scripts/extenders/lego/applications/bars/#bar_hide","title":"Bar_Hide","text":"

Hides a bar. It will not be deleted.

func void Bar_Hide(var int bar)\n
Parameters
  • var int bar Handle returned from Bar_Create
"},{"location":"zengin/scripts/extenders/lego/applications/bars/#bar_show","title":"Bar_Show","text":"

Displays a bar again after using Bar_Hide.

func void Bar_Show(var int bar)\n
Parameters
  • var int bar Handle returned from Bar_Create
"},{"location":"zengin/scripts/extenders/lego/applications/bars/#bar_moveto","title":"Bar_MoveTo","text":"

Move the bar to virtual position.

func void Bar_MoveTo(var int bar, var int x, var int y)\n
Parameters
  • var int bar Handle returned from Bar_Create
  • var int x New horizontal position in virtual coordinates
  • var int y New vertical position in virtual coordinates
"},{"location":"zengin/scripts/extenders/lego/applications/bars/#bar_movetopxl","title":"Bar_MoveToPxl","text":"

Move the bar to pixel position.

func void Bar_MoveToPxl(var int bar, var int x, var int y)\n
Parameters
  • var int bar Handle returned from Bar_Create
  • var int x New horizontal position in pixels
  • var int y New vertical position in pixels
"},{"location":"zengin/scripts/extenders/lego/applications/bars/#bar_setalpha","title":"Bar_SetAlpha","text":"

Sets the transparency of the bar.

func void Bar_SetAlpha(var int bar, var int alpha)\n
Parameters
  • var int bar Handle returned from Bar_Create
  • var int alpha Transparency value (0..255)
"},{"location":"zengin/scripts/extenders/lego/applications/bars/#bar_setbartexture","title":"Bar_SetBarTexture","text":"

Sets the foreground texture of the bar.

func void Bar_SetBarTexture(var int bar, var string barTex)\n
Parameters
  • var int bar Handle returned from Bar_Create
  • var string barTex The new foreground texture
"},{"location":"zengin/scripts/extenders/lego/applications/bars/#bar_setbacktexture","title":"Bar_SetBackTexture","text":"

Sets the background texture of the bar.

func void Bar_SetBackTexture(var int bar, var string backTex)\n
Parameters
  • var int bar Handle returned from Bar_Create
  • var string backTex The new background texture
"},{"location":"zengin/scripts/extenders/lego/applications/bars/#bar_resize","title":"Bar_Resize","text":"

Resize an existing bar.

func void Bar_Resize(var int bar, var int width, var int height)\n
Parameters
  • var int bar Handle returned from Bar_Create
  • var int width New width in virtual coordinates
  • var int height New height in virtual coordinates
"},{"location":"zengin/scripts/extenders/lego/applications/bars/#bar_resizepxl","title":"Bar_ResizePxl","text":"

Resize existing bar (in pixels).

func void Bar_ResizePxl(var int bar, var int x, var int y)\n
Parameters
  • var int bar Handle returned from Bar_Create
  • var int x New width in pixels
  • var int y New height in pixels
"},{"location":"zengin/scripts/extenders/lego/applications/bars/#examples","title":"Examples","text":"

Note

The bars assume a certain basic understanding of the PermMem module.

"},{"location":"zengin/scripts/extenders/lego/applications/bars/#a-dedicated-experience-bar","title":"A dedicated experience bar","text":"

Bars implement the Bar class. It looks like this:

class Bar\n{\n    var int x;          // X position on the screen (middle of the bar)\n    var int y;          // Y position on the screen (middle of the bar)\n    var int barTop;     // Top/bottom margin\n    var int barLeft;    // Left/right margin\n    var int width;      // Bar width\n    var int height;     // Bar height\n    var string backTex; // Background texture\n    var string barTex;  // Actual bar texture\n    var int value;      // Current value\n    var int valueMax;   // Maximum value\n};\n
The GothicBar prototype is a bar, which mimics the standard Gothic status bar.
prototype GothicBar(Bar)\n{\n    x = Print_Screen[PS_X] / 2;\n    y = Print_Screen[PS_Y] - 20;\n    barTop = 3;\n    barLeft = 7;\n    width = 180;\n    height = 20;\n    backTex = \"Bar_Back.tga\";\n    barTex = \"Bar_Misc.tga\";\n    value = 100;\n    valueMax = 100;\n};\n

It is much easier to set up a new instance using this prototype. GothicBar without modifications can be found as the GothicBar@ instance, which we used to create the bar in the example above. GothicBar is located in the middle of the screen and looks exactly like the Gothic underwater bar.

// Instance created from \ninstance Bar_1(GothicBar)\n{\n    x = 100;\n    y = 20;\n};\n\nfunc void Example_1()\n{\n    // Example_1 could e.g. be called in Init_Global\n    FF_ApplyOnce(Loop_1);\n};\n\nfunc void Loop_1()\n{\n    // Example_1 gets this loop running.\n    // Here the bar should be constructed once\n    // and then adapted to the EXP of the hero:\n    var int MyBar;\n    if(!Hlp_IsValidHandle(MyBar))\n    {\n        MyBar = Bar_Create(Bar_1); // Our Bar_1\n    };\n    // The rest is probably self-explanatory:\n    Bar_SetMax(MyBar, hero.exp_next);\n    Bar_SetValue(MyBar, hero.exp);\n};\n

Note

This is translation of article originally written by Gottfried and Lehona and hosted on LeGo's official documentation website.

"},{"location":"zengin/scripts/extenders/lego/applications/bloodsplats/","title":"Bloodsplats","text":""},{"location":"zengin/scripts/extenders/lego/applications/bloodsplats/#bloodsplats","title":"Bloodsplats","text":"

If this package is activated, red blood splatters will appear on the screen when the hero takes damage. For this, the damage perception for the hero is redirected to _B_HeroDamage(). To use the Bloodsplats, the enclosed textures must be available. Also, the VFX \"HERO_HURT\" (also included) should be entered in the VfxInst.d to create an even better hit effect. All textures used here are from CGTextures.com. If you use Bloodsplats in your modification, this site must be noted in the credits.

Tip

See user constants to edit behavior of this packet.

"},{"location":"zengin/scripts/extenders/lego/applications/bloodsplats/#dependencies","title":"Dependencies","text":"
  • Floats
  • View
  • Random
  • Anim8
"},{"location":"zengin/scripts/extenders/lego/applications/bloodsplats/#initialization","title":"Initialization","text":"

Initialize with LeGo_Bloodsplats flag.

LeGo_Init(LeGo_Bloodsplats);\n
"},{"location":"zengin/scripts/extenders/lego/applications/bloodsplats/#implementation","title":"Implementation","text":"

Bloodsplats.d on GitHub

"},{"location":"zengin/scripts/extenders/lego/applications/bloodsplats/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/applications/bloodsplats/#bloodsplat","title":"Bloodsplat","text":"

Puts a blood splatter on the screen.

func void Bloodsplat(var int damage)\n
Parameters
  • var int damage The damage (affects the size of the splatter)
"},{"location":"zengin/scripts/extenders/lego/applications/bloodsplats/#bloodsplats_rage","title":"Bloodsplats_Rage","text":"

Pretty pointless feature that smears the entire screen.

func void Bloodsplats_Rage()\n
"},{"location":"zengin/scripts/extenders/lego/applications/bloodsplats/#npc_getpercfunc","title":"Npc_GetPercFunc","text":"

oCNpc::GetPerceptionFunc engine function wrapper

func int Npc_GetPercFunc(var C_Npc npc, var int type)\n
Parameters
  • var C_NPC npc NPC whose perception is checked
  • var int type Checked perception type (form Constant.d)

Return value

The function returns the state of NPCs selected perception.

"},{"location":"zengin/scripts/extenders/lego/applications/buffs/","title":"Buffs","text":""},{"location":"zengin/scripts/extenders/lego/applications/buffs/#buffs","title":"Buffs","text":"

This package allows you to easily create status effects that can affect any NPC. Status effects on the hero are displayed graphically in a bar.

"},{"location":"zengin/scripts/extenders/lego/applications/buffs/#dependencies","title":"Dependencies","text":"
  • PermMem
  • FrameFunctions
"},{"location":"zengin/scripts/extenders/lego/applications/buffs/#initialization","title":"Initialization","text":"

Initialize with LeGo_Buffs flag.

LeGo_Init(LeGo_Buffs);\n

Warning

This package is still experimental and not included in the LeGo_All initialization flag.

"},{"location":"zengin/scripts/extenders/lego/applications/buffs/#implementation","title":"Implementation","text":"

Buffs.d on GitHub

"},{"location":"zengin/scripts/extenders/lego/applications/buffs/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/applications/buffs/#buff_apply","title":"Buff_Apply","text":"

Applies a status effect to an NPC.

func int Buff_Apply(var C_NPC npc, var int buff)\n
Parameters
  • var C_NPC npc NPC to be affected by this effect

  • var int buff The instance of the effect to apply to the NPC

Return value

The function returns the handle of the buff, which was just generated.

"},{"location":"zengin/scripts/extenders/lego/applications/buffs/#buff_applyunique","title":"Buff_ApplyUnique","text":"

Buff_Apply, but nothing happens if a status effect of that kind is already on the NPC.

func int Buff_ApplyUnique(var C_NPC npc, var int buff)\n
Parameters
  • var C_NPC npc NPC to be affected by this effect

  • var int buff The instance of the effect to apply to the NPC

Return value

The function returns the handle of the buff, which was just generated or 0 if the buff is already applied on the NPC.

"},{"location":"zengin/scripts/extenders/lego/applications/buffs/#buff_applyorrefresh","title":"Buff_ApplyOrRefresh","text":"

Buff_Apply, but if a status effect of this type is already affecting the NPC, the duration will be reset.

func int Buff_ApplyOrRefresh(var C_NPC n, var int buff)\n
Parameters
  • var C_NPC npc NPC to be affected by this effect

  • var int buff The instance of the effect to apply to the NPC

Return value

The function returns the handle of the buff, which was just generated or refreshed.

"},{"location":"zengin/scripts/extenders/lego/applications/buffs/#buff_refresh","title":"Buff_Refresh","text":"

Resets the duration of the buff.

func void Buff_Refresh(var int buffHandle)\n
Parameters
  • var int buffHandle Handle of the buff to refresh
"},{"location":"zengin/scripts/extenders/lego/applications/buffs/#buff_remove","title":"Buff_Remove","text":"

Removes the buff from the all NPCs.

func void Buff_Remove(var int buffHandle)\n
Parameters
  • var int buffHandle Handle of the buff to remove
"},{"location":"zengin/scripts/extenders/lego/applications/buffs/#buff_removeall","title":"Buff_RemoveAll","text":"

Removes the buffs form the NPC.

func void Buff_RemoveAll(var C_NPC npc, var int buffInstance)\n
Parameters
  • var C_NPC npc NPC whose buff should be removed
"},{"location":"zengin/scripts/extenders/lego/applications/buffs/#buff_getnpc","title":"Buff_GetNpc","text":"

Returns a pointer to the NPC, which is affected by the buff.

func int Buff_GetNpc(var int buffHandle)\n
Parameters
  • var int buffHandle Handle of the buff

Return value

The function returns a pointer to the NPC, which is affected by the buff.

"},{"location":"zengin/scripts/extenders/lego/applications/buffs/#buff_has","title":"Buff_Has","text":"

Checks if the NPC already has an effect applied.

func int Buff_Has(var C_NPC npc, var int buff)\n
Parameters
  • var C_NPC npc Checked NPC

  • var int buff The instance of the effect

Return value

The function returns TRUE if the NPC has an effect applied. FALSE is returned otherwise.

"},{"location":"zengin/scripts/extenders/lego/applications/buffs/#save_getfuncid","title":"SAVE_GetFuncID","text":"

Same as MEM_GetFuncID but gets the current instance.

func int SAVE_GetFuncID(var func f)\n
Parameters

var func f Function whose ID is got

Return value

The function returns the ID of given function.

"},{"location":"zengin/scripts/extenders/lego/applications/buffs/#lcbuff-class","title":"lCBuff class","text":"

The buffs package implements an lCBuff class, which looks like this:

class lCBuff\n{\n    var string name;    // buff name \n    var int buffType;   // GOOD / NEUTRAL / BAD | 1 / 0 / -1\n    var int targetID;   // NPC that is currently affected by this buff\n    var int durationMS; // buff duration in milliseconds\n    var int tickMS;     // tick duration in milliseconds, first tick occurs at tickMS milliseconds\n    var int nextTickNr; // e.g. before the first tick this will be 0; OBSOLETE, remove when possible\n\n    var int OnApply; \n    var int OnTick;\n    var int OnRemoved;\n\n    var string buffTex;  // associated texture - currently only used for buffs applied on the hero\n    // var int originID; // Who casted/created this buff?\n\n    // Internal, no need to set during instance construction\n    var int _startedTime;\n    var int _endTime;    // Not redundant with durationMS because buffs can be refreshed\n};\n
"},{"location":"zengin/scripts/extenders/lego/applications/buffs/#examples","title":"Examples","text":""},{"location":"zengin/scripts/extenders/lego/applications/buffs/#delayed-poison","title":"Delayed poison","text":"
instance deadly_poison(lCBuff)\n{\n    name = \"Deadly poison\";\n    bufftype = BUFF_BAD;\n\n    durationMS = 10*1000; // 10 seconds long\n    tickMS = 1000;        // Every second\n\n    buffTex = \"POISON.TGA\";\n};\n

Damage should also be added:

func void deadly_poison_damage(var int buffHandle)\n{\n    var int ptr; ptr = Buff_GetNpc(buffHandle);\n    if (!ptr) { return; }; // Can happen if e.g. the world was changed\n\n    var C_NPC npc; npc = _^(ptr);\n    Npc_ChangeAttribute(npc, ATR_HITPOINTS, -3); // 3 damage\n};\n
For complicated technical reasons we use the function SAVE_GetFuncID instead of MEM_GetFuncID.
instance deadly_poison(lCBuff)\n{\n    name = \"Deadly poison\";\n    bufftype = BUFF_BAD;\n\n    durationMS = 10 * 1000; //10 seconds long\n    tickMS = 1000; // Every second\n\n    onTick = SAVE_GetFuncID(deadly_poison_damage); // The damage should be applied every second\n    buffTex = \"POISON.TGA\";\n};\n

For example, if this buff is now applied to the hero, by calling Buff_Apply(hero, deadly_poison), he loses a total of 30 HP over 10 seconds.

"},{"location":"zengin/scripts/extenders/lego/applications/buttons/","title":"Buttons","text":""},{"location":"zengin/scripts/extenders/lego/applications/buttons/#buttons","title":"Buttons","text":"

This package extends the handling of the mouse and allows creating rectangular buttons, which react to mouse (hover) entry and exit as well as a mouse click.

"},{"location":"zengin/scripts/extenders/lego/applications/buttons/#dependencies","title":"Dependencies","text":"
  • PermMem
  • View
"},{"location":"zengin/scripts/extenders/lego/applications/buttons/#initialization","title":"Initialization","text":"

Initialize with LeGo_Buttons flag.

LeGo_Init(LeGo_Buttons);\n
"},{"location":"zengin/scripts/extenders/lego/applications/buttons/#implementation","title":"Implementation","text":"

Buffs.d on GitHub

"},{"location":"zengin/scripts/extenders/lego/applications/buttons/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/applications/buttons/#button_create","title":"Button_Create","text":"

Creates a button. It is initially hidden (not visible and does not react to the mouse). The three callback functions have the following signature void f(int handle).

func int Button_Create(var int posx, var int posy, var int width, var int height, var string tex, var func on_enter, var func on_leave, var func on_click)\n
Parameters
  • var int posx The horizontal position of the button in virtual coordinates
  • var int posy The vertical position of the button in virtual coordinates
  • var int width Width of the button in virtual coordinates
  • var int height Height of the button in virtual coordinates
  • var string tex Name of the button texture
  • var func on_enter This function is called when the mouse enters the button
  • var func on_leave This function is called when the mouse leaves the button
  • var func on_click This function is called when the user performs a mouse click on the button (left mouse button)

Return value

The function returns a handle to created button.

"},{"location":"zengin/scripts/extenders/lego/applications/buttons/#button_createpxl","title":"Button_CreatePxl","text":"

Button_Create with pixels instead of virtual coordinates.

func int Button_CreatePxl(var int posx, var int posy, var int width, var int height, var string tex, var func on_enter, var func on_leave, var func on_click)\n
Parameters
  • var int posx The horizontal position of the button in pixels
  • var int posy The vertical position of the button in pixels
  • var int width Width of the button in pixels
  • var int height Height of the button in pixels
  • var string tex Name of the button texture
  • var func on_enter This function is called when the mouse enters the button
  • var func on_leave This function is called when the mouse leaves the button
  • var func on_click This function is called when the user performs a mouse click on the button (left mouse button)

Return value

The function returns a handle to created button.

"},{"location":"zengin/scripts/extenders/lego/applications/buttons/#button_delete","title":"Button_Delete","text":"

Completely deletes a button.

func void Button_Delete(var int hndl)\n
Parameters
  • var int hndl Handle returned from Button_Create
"},{"location":"zengin/scripts/extenders/lego/applications/buttons/#button_show","title":"Button_Show","text":"

Shows the button and makes it respond to the mouse.

func void Button_Show(var int hndl)\n
Parameters
  • var int hndl Handle returned from Button_Create
"},{"location":"zengin/scripts/extenders/lego/applications/buttons/#button_hide","title":"Button_Hide","text":"

Hides the button and disables it, so it is no longer responding to the mouse.

func void Button_Hide(var int hndl)\n
Parameters
  • var int hndl Handle returned from Button_Create
"},{"location":"zengin/scripts/extenders/lego/applications/buttons/#button_settexture","title":"Button_SetTexture","text":"

Sets the texture of the button.

func void Button_SetTexture(var int hndl, var string tex)\n
Parameters
  • var int hndl Handle returned from Button_Create
  • var string tex Name of the new texture
"},{"location":"zengin/scripts/extenders/lego/applications/buttons/#button_setcaption","title":"Button_SetCaption","text":"

Displays a centered text on the button.

func void Button_SetCaption(var int hndl, var string caption, var string font)\n
Parameters
  • var int hndl Handle returned from Button_Create
  • var string caption The text to be displayed
  • var string font The font in which the text should be displayed
"},{"location":"zengin/scripts/extenders/lego/applications/buttons/#button_createmouseover","title":"Button_CreateMouseover","text":"

Attaches a mouseover box to the cursor.

func void Button_CreateMouseover(var string text, var string font)\n
Parameters
  • var string text The text in the mouseover box
  • var string font The font of the text
"},{"location":"zengin/scripts/extenders/lego/applications/buttons/#button_deletemouseover","title":"Button_DeleteMouseover","text":"

Deletes the mouseover box.

func void Button_DeleteMouseover()\n
"},{"location":"zengin/scripts/extenders/lego/applications/buttons/#button_activate","title":"Button_Activate","text":"

Activates the button, so it reacts to the mouse. Does not change the visibility.

func void Button_Activate(var int hndl)\n
Parameters
  • var int hndl Handle returned from Button_Create
"},{"location":"zengin/scripts/extenders/lego/applications/buttons/#button_deactivate","title":"Button_Deactivate","text":"

Disables the button, so it no longer reacts to the mouse.

func void Button_Deactivate(var int hndl)\n
Parameters
  • var int hndl Handle returned from Button_Create
"},{"location":"zengin/scripts/extenders/lego/applications/buttons/#button_setuserdata","title":"Button_SetUserData","text":"

Sets the user data of the button, an integer, to give the button individual information.

func void Button_SetUserData(var int hndl, var int data)\n
Parameters
  • var int hndl Handle returned from Button_Create
  • var int data Individual integer of the button (part of the internal _Button class)
"},{"location":"zengin/scripts/extenders/lego/applications/buttons/#button_getuserdata","title":"Button_GetUserData","text":"

Gets the user data of the button.

func int Button_GetUserData(var int hndl)\n
Parameters
  • var int hndl Handle returned from Button_Create

Return value

The function returns the user data of the button.

"},{"location":"zengin/scripts/extenders/lego/applications/buttons/#button_getstate","title":"Button_GetState","text":"

Gets the status of the button as a bit field. See User Constants.

func int Button_GetState(var int hndl)\n
Parameters
  • var int hndl Handle returned from Button_Create

Return value

The function returns the status of the button.

"},{"location":"zengin/scripts/extenders/lego/applications/buttons/#button_move","title":"Button_Move","text":"

Moves the button by the given value in pixels. posx = posx + nposx

func void Button_Move(var int hndl, var int nposx, var int nposy)\n
Parameters
  • var int hndl Handle returned from Button_Create
  • var int nposx X-axis shift in pixels
  • var int nposy Y-axis shift in pixels
"},{"location":"zengin/scripts/extenders/lego/applications/buttons/#button_movevrt","title":"Button_MoveVrt","text":"

Moves the button by the given value in virtual coordinates. posx = posx + nposx

func void Button_Move(var int hndl, var int nposx, var int nposy)\n
Parameters
  • var int hndl Handle returned from Button_Create
  • var int nposx X-axis shift in virtual coordinates
  • var int nposy Y-axis shift in virtual coordinates
"},{"location":"zengin/scripts/extenders/lego/applications/buttons/#button_moveto","title":"Button_MoveTo","text":"

Moves a button to the given position in pixels. posx = nposx

func void Button_MoveVrt(var int hndl, var int nposx, var int nposy)\n
Parameters
  • var int hndl Handle returned from Button_Create
  • var int nposx New horizontal position in pixels
  • var int nposy New vertical position in pixels
"},{"location":"zengin/scripts/extenders/lego/applications/buttons/#button_movetovrt","title":"Button_MoveToVrt","text":"

Moves a button to the given position in virtual coordinates. posx = nvposx

func void Button_MoveVrt(var int hndl, var int nvposx, var int nvposy)\n
Parameters
  • var int hndl Handle returned from Button_Create
  • var int nvposx New horizontal position in virtual coordinates
  • var int nvposy New vertical position in virtual coordinates
"},{"location":"zengin/scripts/extenders/lego/applications/buttons/#button_getviewhandle","title":"Button_GetViewHandle","text":"

Returns the button's zCView as a handle.

func int Button_GetViewHandle(var int hndl)\n
Parameters
  • var int hndl Handle returned from Button_Create

Return value

The function returns the button's zCView as a handle.

"},{"location":"zengin/scripts/extenders/lego/applications/buttons/#button_getviewptr","title":"Button_GetViewPtr","text":"

Returns the button's zCView as a pointer.

func int Button_GetViewPtr(var int hndl)\n
Parameters
  • var int hndl Handle returned from Button_Create

Return value

The function returns the button's zCView as a pointer.

"},{"location":"zengin/scripts/extenders/lego/applications/buttons/#button_getview","title":"Button_GetView","text":"

Returns the button's zCView as an object.

func zCView Button_GetView(var int hndl)\n
Parameters
  • var int hndl Handle returned from Button_Create

Return value

The function returns the button's zCView as an object.

"},{"location":"zengin/scripts/extenders/lego/applications/buttons/#button_getcaptionptr","title":"Button_GetCaptionPtr","text":"

Returns the pointer to the text of the button.

func int Button_GetCaptionPtr(var int hndl)\n
Parameters
  • var int hndl Handle returned from Button_Create

Return value

The function returns the pointer to the text of the button.

"},{"location":"zengin/scripts/extenders/lego/applications/console_commands/","title":"Console Commands","text":""},{"location":"zengin/scripts/extenders/lego/applications/console_commands/#console-commands","title":"Console Commands","text":"

This package allows you to create new console commands.

"},{"location":"zengin/scripts/extenders/lego/applications/console_commands/#dependencies","title":"Dependencies","text":"
  • PermMem
  • HookEngine
"},{"location":"zengin/scripts/extenders/lego/applications/console_commands/#initialization","title":"Initialization","text":"

Initialize with LeGo_ConsoleCommands flag.

LeGo_Init(LeGo_ConsoleCommands);\n
"},{"location":"zengin/scripts/extenders/lego/applications/console_commands/#implementation","title":"Implementation","text":"

ConsoleCommands.d on GitHub

"},{"location":"zengin/scripts/extenders/lego/applications/console_commands/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/applications/console_commands/#cc_register","title":"CC_Register","text":"

Registers a new console command.

func void CC_Register(var func f, var string cmdPrefix, var string description)\n
Parameters
  • var func f This function is executed when the cmdPrefix command is entered in the console. The function signature is func string f(var string p0). The string passed is everything that was specified in the console after the actual command. The return value is then displayed in the console.
  • var string cmdPrefix This is a command, which can be entered in the console.
  • var string description This text appears next to the command (in zSpy) when you use the help command in the console.
"},{"location":"zengin/scripts/extenders/lego/applications/console_commands/#cc_remove","title":"CC_Remove","text":"

Removes a function from the console commands.

func void CC_Remove(var func f)\n
Parameters
  • var func f This function will be removed, i.e. the associated command will no longer work.
"},{"location":"zengin/scripts/extenders/lego/applications/console_commands/#cc_active","title":"CC_Active","text":"

Checks whether the function passed is already part of a console command.

func int CC_Active(var func f)\n
Parameters
  • var func f Function being checked

Return value

The function returns TRUE if there is a corresponding function, FALSE is returned otherwise.

"},{"location":"zengin/scripts/extenders/lego/applications/console_commands/#examples","title":"Examples","text":""},{"location":"zengin/scripts/extenders/lego/applications/console_commands/#basic-command-example","title":"Basic command example","text":"

As a basic example - let us create a version command, which prints a version of our modification. Firstly, we declare a constant string variable to hold the version string to be shown.

const string Mod_Version = \"My mod version 0.1alpha\";\n
Next we create the command function.

Note

Notice the correct function signature. If you do not adhere to the correct function signature, the command will crash the game.

// This function is called by our console\nfunc string CC_ModVersion(var string param)\n{\n    return Mod_Version;\n};\n
We then have to register the functions. For convenience, I created a new RegisterConsoleFunctions function to initialize all console commands. The function is really simple.
func void RegisterConsoleFunctions()\n{\n    CC_Register (CC_ModVersion, \"version\", \"Version of my amazing mod.\");\n};\n
Lastly, we have to call this function from INIT_GLOBAL function.
func void INIT_GLOBAL()\n{\n    // will be called for every world (from INIT_<LevelName>)\n    Game_InitGerman();\n\n    // Ikarus initialization\n    MEM_InitAll();\n\n    // LeGo initialization\n    LeGo_Init(LeGo_ConsoleCommands);\n\n    // Here we register all of our commands\n    RegisterConsoleFunctions();\n\n    // the rest of the code \n};\n
"},{"location":"zengin/scripts/extenders/lego/applications/cursor/","title":"Cursor","text":""},{"location":"zengin/scripts/extenders/lego/applications/cursor/#cursor","title":"Cursor","text":"

This package implements Gothic in-game mouse cursor support. To visually display the cursor there is a Cursor.tga file in the resources, but the texture can be changed in user constants.

Warning

The cursor only works if the mouse is activated in the Gothic settings. It can be done directly from the scripts. See the Ini file access.

"},{"location":"zengin/scripts/extenders/lego/applications/cursor/#dependencies","title":"Dependencies","text":"
  • Floats
  • FrameFunctions
  • View
"},{"location":"zengin/scripts/extenders/lego/applications/cursor/#initialization","title":"Initialization","text":"

Initialize with LeGo_Cursor flag.

LeGo_Init(LeGo_Cursor);\n
"},{"location":"zengin/scripts/extenders/lego/applications/cursor/#implementation","title":"Implementation","text":"

Cursor.d on GitHub

"},{"location":"zengin/scripts/extenders/lego/applications/cursor/#variables","title":"Variables","text":"
  • var int Cursor_X Always contains the X coordinate of the mouse cursor.
  • var int Cursor_Y Always contains the Y coordinate of the mouse cursor.
  • var float Cursor_RelX Always contains the relative X coordinate of the mouse cursor as an Ikarus float.
  • var float Cursor_RelY Always contains the relative Y coordinate of the mouse cursor as an Ikarus float.
  • var int Cursor_Wheel Variable containing the value of the mouse wheel.
  • var int Cursor_Left Variable that always contains the KeyState of the left mouse button.
  • var int Cursor_Mid Variable that always contains the KeyState of the middle mouse button.
  • var int Cursor_Right Variable that always contains the KeyState of the right mouse button.
  • var int Cursor_Event An event handler that can send information about the mouse cursor. It can be used with all functions of the EventHandler package.
  • var int Cursor_NoEngine Variable that can prevent the engine from working. If is set to TRUE the engine no longer reacts to mouse movements.
"},{"location":"zengin/scripts/extenders/lego/applications/cursor/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/applications/cursor/#cursor_hide","title":"Cursor_Hide","text":"

Hides the displayed mouse cursor.

func void Cursor_Hide()\n
"},{"location":"zengin/scripts/extenders/lego/applications/cursor/#cursor_show","title":"Cursor_Show","text":"

Shows the mouse cursor.

func void Cursor_Show()\n
"},{"location":"zengin/scripts/extenders/lego/applications/cursor/#setmouseenabled","title":"SetMouseEnabled","text":"

Can manually enable or disable the mouse.

func void SetMouseEnabled(var int enabled)\n
Parameters
  • var int enabled TRUE - Mouse activated
"},{"location":"zengin/scripts/extenders/lego/applications/cursor/#examples","title":"Examples","text":""},{"location":"zengin/scripts/extenders/lego/applications/cursor/#click-a-button","title":"Click a button","text":"

We use a View to display a button to be clicked. The FrameFunctions take care of the loop to check whether a click was made.

var int Button;\nfunc void Example1()\n{\n    // We show the cursor and at the same time a button to be clicked:\n    Cursor_Show();\n\n    // New View:\n    Button = View_CreatePxl(5, 5, 125, 50);\n    View_SetTexture(Button, \"BUTTONTEX.TGA\");\n    View_Open(Button);\n\n    // Optionally, mouse can be switched off for the engine:\n    Cursor_NoEngine = true; // -> The engine then no longer reacts to movements, so the camera does not move either\n\n    // Enable loop function:\n    FF_ApplyOnce(Button_Click);\n};\n\nfunc void Button_Click()\n{\n    if(Cursor_Left != KEY_PRESSED) { return; }; // Exit the function if the left mouse button was not pressed\n\n    if(Cursor_X >= 5 && Cursor_X <= 125\n    && Cursor_Y >= 5 && Cursor_Y <= 50) // Simply take over the coordinates of the view\n    { \n        // Here the button was clicked.\n        // Remove button and end loop:\n        View_Close(Button);\n        View_Delete(Button);\n        Button = 0;\n\n        // Allow the engine to continue working:\n        Cursor_NoEngine = false;\n\n        FF_Remove(Button_Click);\n\n        // Hide the mouse:\n        Cursor_Hide();\n    };\n};\n

This also can be done by the Buttons package instead of View.

"},{"location":"zengin/scripts/extenders/lego/applications/cursor/#event-handler","title":"Event handler","text":"

Since LeGo 2.2 there is also an event handler (var int Cursor_Event) in the cursor package. This example briefly explains how it works:

func void Example2()\n{\n    // We register MyCursorListener as the handler/listener of the Cursor_Event:\n    Event_Add(Cursor_Event, MyCursorListener);\n\n    // From now on, MyCursorListener will be called whenever the cursor has something to report.\n};\n\nfunc void MyCursorListener(var int state)\n{\n    // The rest is self-explanatory:\n\n    if(state == CUR_WheelUp)\n    {\n        PrintS(\"Wheel up!\");\n    };\n    if(state == CUR_WheelDown)\n    {\n        PrintS(\"Wheel down!\");\n    };\n    if(state == CUR_LeftClick)\n    {\n        PrintS(\"Leftclick!\");\n    };\n    if(state == CUR_RightClick)\n    {\n        PrintS(\"Rightclick!\");\n    };\n    if(state == CUR_MidClick)\n    {\n        PrintS(\"Wheelclick!\");\n    };\n};\n
Constants used in the example can be found in the user constants."},{"location":"zengin/scripts/extenders/lego/applications/dialoggestures/","title":"Dialoggestures","text":""},{"location":"zengin/scripts/extenders/lego/applications/dialoggestures/#dialoggestures","title":"Dialoggestures","text":"

This package can modify the NPCs' gestures during dialogue to better bring out emotions.

"},{"location":"zengin/scripts/extenders/lego/applications/dialoggestures/#dependencies","title":"Dependencies","text":"
  • AI_Function
"},{"location":"zengin/scripts/extenders/lego/applications/dialoggestures/#initialization","title":"Initialization","text":"

N/A

"},{"location":"zengin/scripts/extenders/lego/applications/dialoggestures/#implementation","title":"Implementation","text":"

Dialoggestures.d on GitHub

"},{"location":"zengin/scripts/extenders/lego/applications/dialoggestures/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/applications/dialoggestures/#diag","title":"DIAG","text":"

With this function the dialog gestures for all NPCs can be overridden. To understand the principle, it is recommended to take a look at the examples.

The full name of the animation can be described as follows:

DIAG_Prefix + aniName + DIAG_Suffix + ((rand() % (max - (min - 1))) + min).ToString(\"00\");\n
DIAG_Prefix and DIAG_Suffix are user constants.

func void DIAG(var string AniName, var int Min, var int Max)\n
Parameters
  • var string AniName The new dialogue gesture
  • var int Min Lowest animation number
  • var int Max Highest animation number
"},{"location":"zengin/scripts/extenders/lego/applications/dialoggestures/#diag_reset","title":"DIAG_Reset","text":"

Resets the dialog gestures to the default.

func void DIAG_Reset()\n
"},{"location":"zengin/scripts/extenders/lego/applications/dialoggestures/#diag_setani","title":"DIAG_SetAni","text":"

Sets animation directly.

func void DIAG_SetAni(var string AniName)\n
Parameters
  • var string AniName Animation name
"},{"location":"zengin/scripts/extenders/lego/applications/dialoggestures/#diag_setminmax","title":"DIAG_SetMinMax","text":"

Sets animation numbers directly.

func void DIAG_SetMinMax(var int min, var int max)\n
Parameters
  • var int min Lowest animation number
  • var int max Highest animation number
"},{"location":"zengin/scripts/extenders/lego/applications/dialoggestures/#examples","title":"Examples","text":"

Note

See Examples in the Trialoge article.

"},{"location":"zengin/scripts/extenders/lego/applications/focusnames/","title":"Focusnames","text":""},{"location":"zengin/scripts/extenders/lego/applications/focusnames/#focusnames","title":"Focusnames","text":"

This package colors the focus names of the NPCs in appropriate colors according to the behavior defined below (alpha values are taken into account). Also affects monsters. (Mobs/Items get Color_Neutral)

"},{"location":"zengin/scripts/extenders/lego/applications/focusnames/#dependencies","title":"Dependencies","text":"
  • Interface
  • HookEngine
"},{"location":"zengin/scripts/extenders/lego/applications/focusnames/#initialization","title":"Initialization","text":"

Initialize with LeGo_Focusnames flag.

LeGo_Init(LeGo_Focusnames);\n
"},{"location":"zengin/scripts/extenders/lego/applications/focusnames/#implementation","title":"Implementation","text":"

Focusnames.d on GitHub

"},{"location":"zengin/scripts/extenders/lego/applications/focusnames/#usage","title":"Usage","text":"

If you want to change colors for any behavior edit the following functions directly in Focusnames.d file.

"},{"location":"zengin/scripts/extenders/lego/applications/focusnames/#focusnames_color_friendly","title":"Focusnames_Color_Friendly","text":"
func int Focusnames_Color_Friendly()\n{\n    return RGBA(0, 255, 0, 255); // Green\n};\n
"},{"location":"zengin/scripts/extenders/lego/applications/focusnames/#focusnames_color_neutral","title":"Focusnames_Color_Neutral","text":"
func int Focusnames_Color_Neutral()\n{\n    return RGBA(255, 255, 255, 255); // White\n};\n
"},{"location":"zengin/scripts/extenders/lego/applications/focusnames/#focusnames_color_angry","title":"Focusnames_Color_Angry","text":"
func int Focusnames_Color_Angry()\n{\n    return RGBA(255, 180, 0, 255); // Orange\n};\n
"},{"location":"zengin/scripts/extenders/lego/applications/focusnames/#focusnames_color_hostile","title":"Focusnames_Color_Hostile","text":"
func int Focusnames_Color_Hostile()\n{\n    return RGBA(255, 0, 0, 255); // Red\n};\n
"},{"location":"zengin/scripts/extenders/lego/applications/gamestate/","title":"Gamestate","text":""},{"location":"zengin/scripts/extenders/lego/applications/gamestate/#gamestate","title":"Gamestate","text":"

Gamestate package allows to check for different game states (game start, game load or level change).

"},{"location":"zengin/scripts/extenders/lego/applications/gamestate/#dependencies","title":"Dependencies","text":"
  • EventHandler
  • Saves
"},{"location":"zengin/scripts/extenders/lego/applications/gamestate/#initialization","title":"Initialization","text":"

Initialize with LeGo_Gamestate flag.

LeGo_Init(LeGo_Gamestate);\n
"},{"location":"zengin/scripts/extenders/lego/applications/gamestate/#implementation","title":"Implementation","text":"

Gamestate.d on GitHub

"},{"location":"zengin/scripts/extenders/lego/applications/gamestate/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/applications/gamestate/#gamestate_addlistener","title":"Gamestate_AddListener","text":"

Adds a listener/handler to the game-state event.

func void Gamestate_AddListener(var func listener)\n
Parameters
  • var func listener This function will be called on a game-state change. The current game-state is passed as a parameter.
"},{"location":"zengin/scripts/extenders/lego/applications/gamestate/#gamestate_removelistener","title":"Gamestate_RemoveListener","text":"

Removes game-state listener.

func void Gamestate_RemoveListener(var func listener)\n
Parameters
  • var func listener Listener function to be removed.
"},{"location":"zengin/scripts/extenders/lego/applications/gamestate/#examples","title":"Examples","text":"

There are now two possibilities. Everything can be done directly into the Init_Global, or with EventHandler.

"},{"location":"zengin/scripts/extenders/lego/applications/gamestate/#init_global","title":"Init_Global","text":"
func void Init_Global()\n{\n    // [...]\n\n    LeGo_Init(LeGo_All);\n\n    if(Gamestate == Gamestate_NewGame) \n    {\n        MEM_Info(\"New game started.\");\n    }\n    else if(Gamestate == Gamestate_Loaded)\n    {\n        MEM_Info(\"Game loaded.\");\n    }\n    else if(Gamestate == Gamestate_WorldChange)\n    {\n        MEM_Info(\"Worldshift.\");\n    }\n    else\n    {\n        MEM_Info(\"I don't pass.\");\n    };\n};\n

It can also be done like that:

func void Init_Global()\n{\n    // [...]\n\n    LeGo_Init(LeGo_All);\n\n    if(Gamestate == Gamestate_NewGame)\n    {\n        FF_Apply(MyLoop);\n        FF_Apply(My2ndLoop);\n    };\n};\n
This would have the same effect as:
func void Init_Global()\n{\n    // [...]\n\n    LeGo_Init(LeGo_All);\n\n    FF_ApplyOnce(MyLoop);\n    FF_ApplyOnce(My2ndLoop);\n};\n
"},{"location":"zengin/scripts/extenders/lego/applications/gamestate/#eventhandler","title":"EventHandler","text":"
func void Init_Global()\n{\n    // [...]\n\n    LeGo_Init(LeGo_All);\n\n    Gamestate_AddListener(MyGamestateListener);\n};\n\nfunc void MyGamestateListener(var int state)\n{\n    if(state == Gamestate_NewGame)\n    {\n        MEM_Info(\"New game started.\");\n    }\n    else if(state == Gamestate_Loaded)\n    {\n        MEM_Info(\"Game loaded.\");\n    }\n    else if(state == Gamestate_WorldChange)\n    {\n        MEM_Info(\"Worldshift.\");\n    }\n    else\n    {\n        MEM_Info(\"I don't pass.\");\n    };\n};\n
This is the same as the Init_Global example, but it may look more elegant to some.

Note

This is translation of article originally written by Gottfried and Lehona and hosted on LeGo's official documentation website.

"},{"location":"zengin/scripts/extenders/lego/applications/names/","title":"Names","text":""},{"location":"zengin/scripts/extenders/lego/applications/names/#names","title":"Names","text":"

Allows the user to change NPC name e.g. after he shows up.

"},{"location":"zengin/scripts/extenders/lego/applications/names/#dependencies","title":"Dependencies","text":"
  • Talents
"},{"location":"zengin/scripts/extenders/lego/applications/names/#initialization","title":"Initialization","text":"

N/A

"},{"location":"zengin/scripts/extenders/lego/applications/names/#implementation","title":"Implementation","text":"

Names.d on GitHub

"},{"location":"zengin/scripts/extenders/lego/applications/names/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/applications/names/#setname","title":"SetName","text":"

Should be set in InitGlobal().

func void SetName(var C_NPC npc, var string name)\n
Parameters
  • var C_NPC npc The NPC to be named
  • var string name The name of the NPC
"},{"location":"zengin/scripts/extenders/lego/applications/names/#showname","title":"ShowName","text":"

Permanently displays the name set by SetName function above the npc.

func void ShowName(var C_NPC npc)\n
Parameters
  • var C_NPC npc The NPC whose name should be shown
"},{"location":"zengin/scripts/extenders/lego/applications/names/#examples","title":"Examples","text":""},{"location":"zengin/scripts/extenders/lego/applications/names/#show-the-name-of-an-npc-later","title":"Show the name of an NPC later","text":"
instance PAL_100_Friend(C_NPC)\n{\n    name = \"Paladin\";\n\n    // [...]\n};\n\nfunc void Init_Global()\n{\n    SetName(PAL_100_Friend, \"Arto\");\n};\n
At the start of the game, the name \"Paladin\" is displayed above PAL_100_Friend.

If ShowName(PAL_100_Friend); is used during a dialogue, the name \"Arto\" is permanently visible above the npc.

"},{"location":"zengin/scripts/extenders/lego/applications/render/","title":"Render","text":""},{"location":"zengin/scripts/extenders/lego/applications/render/#render","title":"Render","text":"

With this package items can be rendered on the screen. Since items are rendered independently of the normal views, textures that are 'below' the items must also be managed by this package, this behaviour is managed by the priority system. The view with the highest priority is always rendered first, so it is at the bottom. In theory, any .3DS model can be rendered if you just create a suitable item script.

"},{"location":"zengin/scripts/extenders/lego/applications/render/#dependencies","title":"Dependencies","text":"
  • List
  • View
  • PermMem
"},{"location":"zengin/scripts/extenders/lego/applications/render/#initialization","title":"Initialization","text":"

Initialize with LeGo_Render flag.

LeGo_Init(LeGo_Render);\n

Warning

This package is still experimental and not included in LeGo_All initialization flag.

"},{"location":"zengin/scripts/extenders/lego/applications/render/#implementation","title":"Implementation","text":"

Render.d on GitHub

"},{"location":"zengin/scripts/extenders/lego/applications/render/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/applications/render/#render_additemprio","title":"Render_AddItemPrio","text":"

Generates the render of an item, with a manually specified priority.

func int Render_AddItemPrio(var int itemInst, var int x1, var int y1, var int x2, var int y2, var int priority)\n
Parameters
  • var int itemInst The instance of the item to render
  • var int x1 var int y1 The top left coordinate of the view
  • var int x2 var int y2 The bottom right coordinate of the view
  • var int priority The priority of this render object

Return value

The function returns a handle of the render object.

"},{"location":"zengin/scripts/extenders/lego/applications/render/#render_additem","title":"Render_AddItem","text":"

Generates the render of an item, with priority set to 0.

func int Render_AddItem(var int itemInst, var int x1, var int y1, var int x2, var int y2)\n
Parameters
  • var int itemInst The instance of the item to render
  • var int x1 var int y1 The top left coordinate of the view
  • var int x2 var int y2 The bottom right coordinate of the view

Return value

The function returns a handle of the render object.

"},{"location":"zengin/scripts/extenders/lego/applications/render/#render_addviewprio","title":"Render_AddViewPrio","text":"

Generates the render of a View, with a manually specified priority.

func int Render_AddViewPrio(var int view, var int priority)\n
Parameters
  • var int view A handle to a View
  • var int priority The priority of this render object

Return value

The function returns a handle of the render object.

"},{"location":"zengin/scripts/extenders/lego/applications/render/#render_addview","title":"Render_AddView","text":"

Generates the render of a View, with priority set to 0.

func int Render_AddView(var int view)\n
Parameters
  • var int view A handle to a View

Return value

The function returns a handle of the render object.

"},{"location":"zengin/scripts/extenders/lego/applications/render/#render_openview","title":"Render_OpenView","text":"

Opens a render object. Only open render objects are displayed.

func void Render_OpenView(var int handle)\n
Parameters
  • var int handle Handle of a render object
"},{"location":"zengin/scripts/extenders/lego/applications/render/#render_closeview","title":"Render_CloseView","text":"

Closes a render object. Only open render objects are displayed.

func void Render_CloseView(var int handle)\n
Parameters
  • var int handle Handle of a render object
"},{"location":"zengin/scripts/extenders/lego/applications/render/#render_remove","title":"Render_Remove","text":"

Deletes a render object. The associated view is deleted automatically.

func void Render_Remove(var int handle)\n
Parameters
  • var int handle Handle of a render object
"},{"location":"zengin/scripts/extenders/lego/applications/saves/","title":"Saves","text":""},{"location":"zengin/scripts/extenders/lego/applications/saves/#saves","title":"Saves","text":"

Offers an open file stream that can read/write variables on save/load. It is used by PermMem, so you don't need to address it manually anymore.

"},{"location":"zengin/scripts/extenders/lego/applications/saves/#dependencies","title":"Dependencies","text":"
  • BinaryMachines
"},{"location":"zengin/scripts/extenders/lego/applications/saves/#initialization","title":"Initialization","text":"

Initialize with LeGo_Saves flag.

LeGo_Init(LeGo_Saves);\n
"},{"location":"zengin/scripts/extenders/lego/applications/saves/#implementation","title":"Implementation","text":"

Saves.d on GitHub

"},{"location":"zengin/scripts/extenders/lego/applications/saves/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/applications/saves/#bw_savegame","title":"BW_Savegame","text":"

Custom function. It creates a stream to its own memory file, this can be filled with the BW_* functions from the BinaryMachines.

func void BW_Savegame()\n
"},{"location":"zengin/scripts/extenders/lego/applications/saves/#br_savegame","title":"BR_Savegame","text":"

Custom function. It opens a stream to a previously saved memory file, which can be read from the BinaryMachines using the BR_* functions.

func void BR_Savegame()\n
"},{"location":"zengin/scripts/extenders/lego/applications/saves/#examples","title":"Examples","text":""},{"location":"zengin/scripts/extenders/lego/applications/saves/#save-a-high-score-list","title":"Save a high score list","text":"
var string MyScoreList[10];\n

Since strings are not saved by the game by default, we use the functions from Saves.d to create an additional memory file that only belongs to us. At the top the Saves.d file has two functions: BW_Savegame and BR_Savegame. BinaryMachines functions are used to save or read the file, we don't need to do anything else than to use them here, the rest is done by Saves.d completely by itself. Therefore, we only modify these two functions.

func void BW_Savegame() \n{\n    // Save high score list\n    BW_String(MyScoreList[0]);\n    BW_String(MyScoreList[1]);\n    BW_String(MyScoreList[2]);\n    BW_String(MyScoreList[3]);\n    BW_String(MyScoreList[4]);\n    BW_String(MyScoreList[5]);\n    BW_String(MyScoreList[6]);\n    BW_String(MyScoreList[7]);\n    BW_String(MyScoreList[8]);\n    BW_String(MyScoreList[9]);\n};\n\nfunc void BR_Savegame() \n{\n    // Load high score list\n    MyScoreList[0] = BR_String();\n    MyScoreList[1] = BR_String();\n    MyScoreList[2] = BR_String();\n    MyScoreList[3] = BR_String();\n    MyScoreList[4] = BR_String();\n    MyScoreList[5] = BR_String();\n    MyScoreList[6] = BR_String();\n    MyScoreList[7] = BR_String();\n    MyScoreList[8] = BR_String();\n    MyScoreList[9] = BR_String();\n};\n

Tip

Since LeGo 2.0, such things can be implemented much more elegantly with PermMem.

"},{"location":"zengin/scripts/extenders/lego/applications/trialoge/","title":"Trialoge","text":""},{"location":"zengin/scripts/extenders/lego/applications/trialoge/#trialoge","title":"Trialoge","text":"

This package allows you to create conversations with any number of NPCs and control the camera during the dialog.

"},{"location":"zengin/scripts/extenders/lego/applications/trialoge/#dependencies","title":"Dependencies","text":"
  • AI_Function
"},{"location":"zengin/scripts/extenders/lego/applications/trialoge/#initialization","title":"Initialization","text":"

Initialize with LeGo_Trialoge flag.

LeGo_Init(LeGo_Trialoge);\n
"},{"location":"zengin/scripts/extenders/lego/applications/trialoge/#implementation","title":"Implementation","text":"

Trialoge.d on GitHub

"},{"location":"zengin/scripts/extenders/lego/applications/trialoge/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/applications/trialoge/#equipweapon","title":"EquipWeapon","text":"

Sektenspinner's function. Makes NPC equip a weapon.

func void EquipWeapon(var C_NPC slf, var int ItemInstance)\n
Parameters
  • var C_NPC slf NPC to have a weapon equipped
  • var int ItemInstance Weapon instance ID to be equipped

Configuration

const int EquipWeapon_TogglesEquip = 1

Above constant configures the behaviour of the function when trying to equip an already equipped weapon:

  • 0 - EquipWeapon will do nothing
  • 1 - EquipWeapon will unequip this weapon
"},{"location":"zengin/scripts/extenders/lego/applications/trialoge/#npc_getarmor","title":"Npc_GetArmor","text":"

Returns NPC's equipped armor.

func int Npc_GetArmor(var C_NPC slf)\n
Parameters
  • var C_NPC slf NPC to get the armor from

Return value

The function returns instance of armor worn by the NPC.

"},{"location":"zengin/scripts/extenders/lego/applications/trialoge/#npc_getmeleeweapon","title":"Npc_GetMeleeWeapon","text":"

Returns NPC's equipped melee weapon.

func int Npc_GetMeleeWeapon(var C_NPC slf)\n
Parameters
  • var C_NPC slf NPC to get the weapon from

Return value

The function returns instance ID of melee weapon equipped by the NPC.

"},{"location":"zengin/scripts/extenders/lego/applications/trialoge/#npc_getrangedweapon","title":"Npc_GetRangedWeapon","text":"

Returns NPC's equipped ranged weapon.

func int Npc_GetRangedWeapon(var c_npc slf)\n
Parameters
  • var C_NPC slf NPC to get the weapon from

Return value

The function returns instance ID of ranged weapon equipped by the NPC.

"},{"location":"zengin/scripts/extenders/lego/applications/trialoge/#npc_tradeitem","title":"Npc_TradeItem","text":"

Swaps NPCs equipped weapon.

func void Npc_TradeItem(var c_npc slf, var int itm0, var int itm1) \n
Parameters
  • var C_NPC slf NPC to perform operation on
  • var int itm0 instance ID of item to remove
  • var int itm1 instance ID of item to create and equip
"},{"location":"zengin/scripts/extenders/lego/applications/trialoge/#diacam_update","title":"DiaCAM_Update","text":"

Sektenspinner's function that updates the dialogue camera. (Used internally.)

func void DiaCAM_Update()\n
"},{"location":"zengin/scripts/extenders/lego/applications/trialoge/#diacam_disable","title":"DiaCAM_Disable","text":"

Completely disable the dialogue cameras.

func void DiaCAM_Disable()\n
"},{"location":"zengin/scripts/extenders/lego/applications/trialoge/#diacam_enable","title":"DiaCAM_Enable","text":"

Resets the dialogue cameras to the default settings.

func void DiaCAM_Enable()\n
"},{"location":"zengin/scripts/extenders/lego/applications/trialoge/#tria_wait","title":"TRIA_Wait","text":"

Makes self and other wait for each other, e.g. for AI_GotoWP actions for synchronization.

func void TRIA_Wait()\n
"},{"location":"zengin/scripts/extenders/lego/applications/trialoge/#tria_invite","title":"TRIA_Invite","text":"

Invites an NPC into a conversation. Must be called before TRIA_Start.

func void TRIA_Invite(var C_NPC slf)\n
Parameters
  • var C_NPC slf The invited NPC
"},{"location":"zengin/scripts/extenders/lego/applications/trialoge/#tria_start","title":"TRIA_Start","text":"

Starts trialogues. Before that, all NPCs should be invited by TRIA_Invite.

func void TRIA_Start()\n
"},{"location":"zengin/scripts/extenders/lego/applications/trialoge/#tria_barrier","title":"TRIA_Barrier","text":"

Similar to TRIA_Wait but applies to all participating NPCs.

func void TRIA_Barrier()\n
"},{"location":"zengin/scripts/extenders/lego/applications/trialoge/#tria_next","title":"TRIA_Next","text":"

Sets the called npc to self.

func void TRIA_Next(var C_NPC n0)\n
Parameters
  • var C_NPC n0 NPC to set to self
"},{"location":"zengin/scripts/extenders/lego/applications/trialoge/#tria_cam","title":"TRIA_Cam","text":"

Starts a tracking shot.

func void TRIA_Cam(var string evt)\n
Parameters
  • var string evt The name of the tracking shot in Spacer. If \"\" is passed, the running trace shot will be aborted.
"},{"location":"zengin/scripts/extenders/lego/applications/trialoge/#tria_finish","title":"TRIA_Finish","text":"

Ends an ongoing trialogue. Must always be called at the end, otherwise no further trialogues can be started.

func void TRIA_Finish()\n
"},{"location":"zengin/scripts/extenders/lego/applications/trialoge/#examples","title":"Examples","text":""},{"location":"zengin/scripts/extenders/lego/applications/trialoge/#a-simple-trialogue","title":"A Simple Trialogue","text":"

The following conversation is resolved via the trialogues:

  1. Arto: I'm sorry Hero, but you can't pass here.
  2. Hero: Why not?
  3. Horka: The city has been closed.
  4. Hero: I have some gold with me, can we trade?
  5. Squelto: No. We are not open to bribery.
  6. Hero: Sure?
  7. Arto: I have to ask you to leave now.
  8. Hero: Well...
    instance TRIA_Test (C_INFO)\n{\n    npc         = PAL_100_Friend;\n    nr          = 10;\n    condition   = TRIA_Test_condition;\n    information = TRIA_Test_info;\n    important   = FALSE;\n    permanent   = 1;\n    description = \"TRIALOGTEST\";\n};\n\nfunc int TRIA_Test_condition()\n{\n    return TRUE;\n};\n\nfunc void TRIA_Test_info()\n{\n    var C_NPC Arto; Arto       = Hlp_GetNpc(PAL_100_Friend); // He is the owner of dialogue\n    var C_NPC Horka; Horka     = Hlp_GetNpc(PAL_101_Horka);\n    var C_NPC Squelto; Squelto = Hlp_GetNpc(PAL_102_Squelto);\n\n    TRIA_Invite(Horka);   // Invite Horka into this dialogue\n    TRIA_Invite(Squelto); // Invite Squelto into this dialog\n    TRIA_Start();         // Start the conversation\n    // The hero and Arto do not have to/may not be invited. They are in dialogue anyway.\n\n    // Hero now talks to Arto (self = Arto, other = Hero)\n    TRIA_Next(Arto);\n\n    DIAG_Reset();\n\n    AI_Output (self, other, \"TRIA_TEST_00\"); //Sorry hero, but you can't pass here.\n\n    // Hero now talks to Horka (self = Horka, other = Hero)\n    TRIA_Next(Horka);\n\n    AI_Output (other, self, \"TRIA_TEST_01\"); //Why not?\n\n    AI_GotoNpc(self, other);\n    AI_TurnToNpc(other, self);\n\n    AI_Output (self, other, \"TRIA_TEST_02\"); //The city has been closed.\n\n    // Hero looks around conspiratorially during the next sentence\n    DIAG(\"Nervous\", 1, 2);\n\n    AI_Output (other, self, \"TRIA_TEST_03\"); //I have some gold with me, can we trade?\n\n    // Hero should now move normally again\n    DIAG_Reset();\n\n    // Start tracking shot\n    TRIA_Cam(\"CAMERASTART\");\n\n    // Hero now talks to Squelto (self = Squelto, other = Hero)\n    TRIA_Next(Squelto);\n\n    AI_TurnToNpc(other, self);\n\n    DIAG(\"No\", 0, 1);\n    AI_Output (self, other, \"TRIA_TEST_04\"); //No. We are not open to bribery.\n\n    // Hero talks to Arto again (self = Arto, other = Hero)\n    TRIA_Next(Arto);\n\n    // Hero should now articulate questioningly\n    DIAG(\"NotSure\", 0, 1);\n\n    AI_Output (other, self, \"TRIA_TEST_05\"); //Sure?\n\n    AI_TurnToNpc(other, self);\n\n    // tracking shot end\n    TRIA_Cam(\"\");\n\n    // Arto should react angrily\n    DIAG(\"Angry\", 0, 4);\n\n    AI_Output (self, other, \"TRIA_TEST_06\"); //I have to ask you to leave now\n\n    // Hero should now move normally again\n    DIAG_Reset();\n\n    AI_Output (other, self, \"TRIA_TEST_07\"); //Well...\n\n    TRIA_Finish(); // End\n};\n

Note

In addition, here are still Dialoggestures used.

"},{"location":"zengin/scripts/extenders/lego/tools/ai_function/","title":"AI_Function","text":""},{"location":"zengin/scripts/extenders/lego/tools/ai_function/#ai_function","title":"AI_Function","text":"

This package allows time-delayed functions to be called by enqueuing the functions in the AI queue of the NPC in question. This can be very useful in writing cutscenes on engine or implementing new routines.

"},{"location":"zengin/scripts/extenders/lego/tools/ai_function/#dependencies","title":"Dependencies","text":"
  • HookEngine
"},{"location":"zengin/scripts/extenders/lego/tools/ai_function/#initialization","title":"Initialization","text":"

Initialize with LeGo_AI_Function flag.

LeGo_Init(LeGo_AI_Function);\n
"},{"location":"zengin/scripts/extenders/lego/tools/ai_function/#implementation","title":"Implementation","text":"

AI_Function.d on GitHub

"},{"location":"zengin/scripts/extenders/lego/tools/ai_function/#functions","title":"Functions","text":"

The script function function is called with a delay: it joins the AI queue of slf.

func void AI_Function(var C_NPC slf, var func function)\n
Parameters
  • var C_NPC slf NPC in whose AI queue the function is queued
  • var func function Name of function to be queued

Additionally, there are some overloads of AI_Function, which allow to call functions with parameters.

func void AI_Function_I  (var C_NPC slf, var func function, var int    param) {}; // Int\nfunc void AI_Function_N  (var C_NPC slf, var func function, var int    param) {}; // Instance (e.g. NPC)\nfunc void AI_Function_S  (var C_NPC slf, var func function, var string param) {}; // String\nfunc void AI_Function_II (var C_NPC slf, var func function, var int    param1, var int    param2) {}; // Int, Int\nfunc void AI_Function_NN (var C_NPC slf, var func function, var int    param1, var int    param2) {}; // Instance, Instance\nfunc void AI_Function_SS (var C_NPC slf, var func function, var string param1, var string param2) {}; // String, String\nfunc void AI_Function_IS (var C_NPC slf, var func function, var int    param1, var string param2) {}; // Int, String\nfunc void AI_Function_SI (var C_NPC slf, var func function, var string param1, var int    param2) {}; // String, Int\nfunc void AI_Function_NS (var C_NPC slf, var func function, var int    param1, var string param2) {}; // Instance, String\nfunc void AI_Function_SN (var C_NPC slf, var func function, var string param1, var int    param2) {}; // String, Instance\nfunc void AI_Function_IN (var C_NPC slf, var func function, var int    param1, var int    param2) {}; // Int, Instance\nfunc void AI_Function_NI (var C_NPC slf, var func function, var int    param1, var int    param2) {}; // Instance, Int\n
Functions with more than two parameters cannot be called, but parameters can be passed indirectly via global variables.

In the called function, self can be accessed as follows:

var oCNpc slf; slf = _^(ECX);\n

Info

From LeGo 2.7.2 the global instance self is provided correctly and can be used directly.

"},{"location":"zengin/scripts/extenders/lego/tools/ai_function/#examples","title":"Examples","text":""},{"location":"zengin/scripts/extenders/lego/tools/ai_function/#enqueueing-a-simple-function","title":"Enqueueing a simple function","text":"

Before a function is called, any Npc should first complete its AI queue.

Here the hero is supposed to run to a waypoint, and only when he has arrived is to start a tracking shot.

func void Example1() {\n    Npc_ClearAIQueue(hero);\n    AI_GotoWP(hero, \"MYWAYPOINT\");\n\n    AI_Function_S(hero, Wld_SendTrigger, \"CAMERASTART\");\n};\n
As soon as the hero has reached the waypoint, Wld_SendTrigger(\"CAMERASTART\"); is called."},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/","title":"BinaryMachines","text":""},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#binarymachines","title":"BinaryMachines","text":"

This package allows you to create and write your own files anywhere in the file system.

"},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#dependencies","title":"Dependencies","text":"

N/A

"},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#initialization","title":"Initialization","text":"

N/A

"},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#implementation","title":"Implementation","text":"

BinaryMachines.d on GitHub

"},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#binarywriter","title":"BinaryWriter","text":""},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#bw_newfile","title":"BW_NewFile","text":"

Creates the file with the file name and opens a stream. Doesn't work if a stream is already open.

func int BW_NewFile(var string file)\n
Parameters
  • var string file Name of created file

Return value

The function returns TRUE if the file is successfully created and initialized, FALSE is returned otherwise.

"},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#bw_close","title":"BW_Close","text":"

Closes the current write stream.

func void BW_Close()\n
"},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#bw","title":"BW","text":"

Writes length bytes from the data to the stream, maximum 4 bytes.

func void BW(var int data, var int length)\n
Parameters
  • var int data Value of bytes
  • var int length Number of bytes
"},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#bw_int","title":"BW_Int","text":"

Writes 4 bytes from the data to the stream. Same as BW(data, 4).

func void BW_Int(var int data)\n
Parameters
  • var int data Integer value to write
"},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#bw_char","title":"BW_Char","text":"

Writes the first character from the data to the stream. Same as BW(Str_GetCharAt(data, 0), 1).

func void BW_Char(var string data)\n
Parameters
  • var string data Char to write
"},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#bw_string","title":"BW_String","text":"

Writes the data terminated with \\0 to the stream.

func void BW_String(var string data)\n
Parameters
  • var string data String to write
"},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#bw_byte","title":"BW_Byte","text":"

Writes a byte from the data to the stream. Same as BW(data, 1).

func void BW_Byte(var int data)\n
Parameters
  • var int data Byte value to write
"},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#bw_bytes","title":"BW_Bytes","text":"

Writes length of bytes from the pointer dataPtr to the stream.

func void BW_Bytes(var int dataPtr, var int length)\n
Parameters
  • var int dataPtr Pointer of data to write
  • var int length Number of bytes
"},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#bw_text","title":"BW_Text","text":"

Writes the string to the stream without terminating it. So it can no longer be read.

func void BW_Text(var string data)\n
Parameters
  • var string data Text to write
"},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#bw_nextline","title":"BW_NextLine","text":"

Writes a paragraph to the stream.

func void BW_NextLine()\n
"},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#binaryreader","title":"BinaryReader","text":""},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#br_openfile","title":"BR_OpenFile","text":"

Opens the file with the file name and opens a stream. Doesn't work if a stream is already open.

func int BR_OpenFile(var string file)\n
Parameters
  • var string file File to be opened

Return value

The function returns TRUE if the file is successfully opened and initialized, FALSEis returned otherwise.

"},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#br_close","title":"BR_Close","text":"

Closes the current read stream.

func void BR_Close()\n
"},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#br","title":"BR","text":"

Reads bytes from the stream.

func int BR(var int length)\n
Parameters
  • var int length Number of bytes to read (maximum 4)

Return value

The function returns the value of read bytes.

"},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#br_int","title":"BR_Int","text":"

Reads 4 bytes from the stream. Same as BR(4).

func int BR_Int()\n
Return value

The function returns the read integer.

"},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#br_char","title":"BR_Char","text":"

Reads a character from the stream. Same as BR(1).

func string BR_Char()\n
Return value

The function returns the read character as a string.

"},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#br_string","title":"BR_String","text":"

Reads a string terminated by \\0 from the stream.

func string BR_String()\n
Return value

The function returns the read string.

"},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#br_byte","title":"BR_Byte","text":"

Reads a byte from the stream.

func int BR_Byte()\n
Return value

The function returns the read byte.

"},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#br_bytes","title":"BR_Bytes","text":"

Reads bytes from the stream.

func int BR_Bytes(var int length)\n
Parameters
  • var int length Number of bytes to read

Return value

The function returns a pointer to the read bytes.

"},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#br_textline","title":"BR_TextLine","text":"

Reads a line from the stream.

func string BR_TextLine()\n
Return value

The function returns the read line.

"},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#br_text","title":"BR_Text","text":"

Reads a string of the given length from a stream.

func string BR_Text(var int length)\n
Parameters
  • var int length Number of characters to read

Return value

The function returns the read string.

"},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#br_nextline","title":"BR_NextLine","text":"

Changes the read position to the next paragraph, created with BW_NextLine

func void BR_NextLine()\n
"},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#enginecalls","title":"Enginecalls","text":""},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#win_getlasterror","title":"WIN_GetLastError","text":"

Call of a Win32 API GetLastError function

func int WIN_GetLastError()\n
Return value

The function returns calling thread's last-error code.

"},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#win_createfile","title":"WIN_CreateFile","text":"

Call of a Win32 API CreateFileA function

func int WIN_CreateFile(var string lpFileName,var int dwDesiredAccess,var int dwShareMode,var int lpSecurityAttributes,var int dwCreationDisposition,var int dwFlagsAndAttributes,var int hTemplateFile)\n
Parameters

Full description of parameters can be found here

Return value

Information about return value can be found here

"},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#win_writefile","title":"WIN_WriteFile","text":"

Call of a Win32 API WriteFile function

func void WIN_WriteFile(var int hFile,var int lpBuffer,var int nNumberOfBytesToWrite,var int lpNumberOfBytesWritten,var int lpOverlapped)\n
Parameters

Full description of parameters can be found here

"},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#win_readfile","title":"WIN_ReadFile","text":"

Call of a Win32 API ReadFile function

func void WIN_ReadFile(var int hFile,var int lpBuffer,var int nNumberOfBytesToRead,var int lpNumberOfBytesRead,var int lpOverlapped)\n
Parameters

Full description of parameters can be found here

"},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#win_closehandle","title":"WIN_CloseHandle","text":"

Call of a Win32 API CloseHandle function

func void WIN_CloseHandle(var int hObject)\n
Parameters

Full description of parameters can be found here

"},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#win_getfilesize","title":"WIN_GetFileSize","text":"

Call of a Win32 API GetFileSize function

func int WIN_GetFileSize(var int hFile,var int lpFileSizeHigh)\n
Parameters

Full description of parameters can be found here

Return value

Information about return value can be found here

"},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#constants","title":"Constants","text":"

In addition there are some constants defined for use with the specific engine calls.

const int CREATE_ALWAYS = 2;\nconst int OPEN_EXISTING = 3;\nconst int GENERIC_ALL = 1073741824;\nconst int GENERIC_READ = -2147483648;\nconst int FILE_SHARE_READ = 1;\nconst int FILE_SHARE_WRITE = 2;\nconst int FILE_SHARE_DELETE = 4;\nconst int FILE_ATTRIBUTE_NORMAL = 128;\n
"},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#examples","title":"Examples","text":""},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#save-and-load-variables","title":"Save and load variables","text":"
const string filename = \"System\\MySave.sav\";\n\nvar string s0; // string\nvar int    i1; // int\nvar int    b2; // byte\nvar string c3; // char\n\nfunc void SaveMyData() \n{\n    if(BW_NewFile(filename))  // Create a new file:\n    { \n        BW_String(s0);\n        BW_Int(i1);\n        BW_Byte(b2);\n        BW_Char(c3);          // Save stuff..\n        BW_Close();           // ..and close.\n    };\n};\n\nfunc void LoadMyData() {\n    if(BR_OpenFile(filename)) // Try to open file:\n    { \n        s0 = BR_String();\n        i1 = BR_Int();\n        b2 = BR_Byte();\n        c3 = BR_Char();       // Read in values..\n        BR_Close();           // ..and close.\n    }\n    else \n    {\n        SaveMyData();         // Otherwise create a save file.\n    };\n};\n
"},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#congratulate-the-player","title":"Congratulate the player","text":"
func void Certificate(var string Username, var int Score) \n{\n    var string filename; filename = ConcatStrings(Username, \"'s Certificate.txt\");\n    BW_NewFile(filename); // Username + \"s Certificate.txt\". The file is then in the Gothic directory.\n    BW_Text(\"Congratulations \"); BW_Text(Username);\n    BW_TextLine(\"!\");\n\n    BW_Text(\"You have reached \");\n    BW_Text(IntToString(Score)); // Not BW_Int!\n    BW_TextLine(\" Points in this fun game.\");\n\n    BW_NextLine();\n\n    BW_Text(\"Best regards, Author\");\n    BW_Close();\n\n    /*\n       When calling:  Certificate(\"Player\", 1000);\n       a file with the name 'Player's Certificate.txt' would come out which would contain the following:\n\n        Congratulations Player\n        You have reached 1000 Points in this fun game.\n\n        Best regards, Author\n    */\n};\n
"},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#the-location-of-an-npcs","title":"The location of an NPCs","text":"
func void BW_NpcPosition(var C_NPC slf) \n{\n    var int ptr; ptr = MEM_Alloc(60);                // 16 * 4\n    MEM_CopyBytes(MEM_InstToPtr(slf) + 60, ptr, 60); // Copy slf.trafoObjToWorld\n    BW_Bytes(ptr, 60);                               // Writes the 60 copied bytes\n    MEM_Free(ptr);                                   // And clean up..\n};\n\nfunc void BR_NpcPosition(var C_NPC slf) \n{\n    var int ptr; ptr = BR_Bytes(60);                 // Read 60 bytes\n    MEM_CopyBytes(ptr, MEM_InstToPtr(slf) + 60, 60); // Paste back into slf\n    MEM_Free(ptr);                                   // And clean up again..\n};\n\n/*\n   Normal use:\n     BW_NewFile(file);\n     BW_NpcPosition(hero);\n     BW_Close();\n*/\n

Note

Examples originally written by Gottfried and posted on World of Gothic forum.

"},{"location":"zengin/scripts/extenders/lego/tools/event_handler/","title":"EventHandler","text":""},{"location":"zengin/scripts/extenders/lego/tools/event_handler/#eventhandler","title":"EventHandler","text":"

This package allows to create new events and trigger them at desired times. The Gamestate package already uses it.

Warning

The EventHandler requires some basic understanding of the PermMem. The documentation can be found here.

"},{"location":"zengin/scripts/extenders/lego/tools/event_handler/#dependencies","title":"Dependencies","text":"
  • PermMem
"},{"location":"zengin/scripts/extenders/lego/tools/event_handler/#initialization","title":"Initialization","text":"

Initialize with LeGo_EventHandler flag.

LeGo_Init(LeGo_EventHandler);\n
"},{"location":"zengin/scripts/extenders/lego/tools/event_handler/#implementation","title":"Implementation","text":"

EventHandler.d on GitHub

"},{"location":"zengin/scripts/extenders/lego/tools/event_handler/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/tools/event_handler/#event_create","title":"Event_Create","text":"

Creates a new event and returns a handle to it.

func int Event_Create()\n
Return value

The function returns a new PermMem handle to an event.

"},{"location":"zengin/scripts/extenders/lego/tools/event_handler/#event_delete","title":"Event_Delete","text":"

Alias to PermMem delete. Cleans up the handle.

func void Event_Delete(var int event)\n
Parameters
  • var int event Handle returned from Event_Create
"},{"location":"zengin/scripts/extenders/lego/tools/event_handler/#event_empty","title":"Event_Empty","text":"

Checks whether the event is \"empty\", i.e. nothing will happen after its execution.

func int Event_Empty(var int event)\n
Parameters
  • var int event Handle returned from Event_Create

Return value

The function returns TRUE if event is empty, FALSE is returned otherwise.

"},{"location":"zengin/scripts/extenders/lego/tools/event_handler/#event_has","title":"Event_Has","text":"

Checks if function is added to the event.

func int Event_Has(var int event, var func function)\n
Parameters
  • var int event Handle returned from Event_Create
  • var func function Checked function

Return value

The function returns TRUE if function is added, FALSE is returned otherwise.

"},{"location":"zengin/scripts/extenders/lego/tools/event_handler/#event_add","title":"Event_Add","text":"

Adds an event handler function. The handler is called after running Event_Execute.

func void Event_Add(var int event, var func function)\n
Parameters
  • var int event Handle returned from Event_Create
  • var func function Function to be added
"},{"location":"zengin/scripts/extenders/lego/tools/event_handler/#event_addonce","title":"Event_AddOnce","text":"

Event_Add but checks if the handler function is already added, to prevent duplicates.

func void Event_AddOnce(var int event, var func function)\n
Parameters
  • var int event Handle returned from Event_Create
  • var func function Function to be added
"},{"location":"zengin/scripts/extenders/lego/tools/event_handler/#event_remove","title":"Event_Remove","text":"

Removes the event handler function from the event.

func void Event_Remove(var int event, var func function)\n
Parameters
  • var int event Handle returned from Event_Create
  • var func function Function to be removed
"},{"location":"zengin/scripts/extenders/lego/tools/event_handler/#event_execute","title":"Event_Execute","text":"

Core of the package. Calls all functions registered via Event_Add and Event_AddOnce.

func void Event_Execute(var int event, var int data)\n
Parameters
  • var int event Handle returned from Event_Create
  • var int data Int parameter passed to all executed functions
"},{"location":"zengin/scripts/extenders/lego/tools/event_handler/#ptr-functions","title":"Ptr functions","text":"

Tip

The pointer functions are used internally by the previous functions. If you created an event with Event_Create use functions without Ptr in the name, but if you created event with EventPtr_Create use only Ptr functions. The normal user will probably never need the pointer versions, however the choice, which one to use is yours.

"},{"location":"zengin/scripts/extenders/lego/tools/event_handler/#eventptr_create","title":"EventPtr_Create","text":"

Creates a new event and returns a pointer to it.

func int EventPtr_Create()\n
Return value

The function returns a new PermMem pointer to an event.

"},{"location":"zengin/scripts/extenders/lego/tools/event_handler/#eventptr_delete","title":"EventPtr_Delete","text":"

Alias to PermMem free. Cleans up the pointer.

func void EventPtr_Delete(var int eventPtr)\n
Parameters
  • var int eventPtr Pointer returned from EventPtr_Create
"},{"location":"zengin/scripts/extenders/lego/tools/event_handler/#eventptr_empty","title":"EventPtr_Empty","text":"

Checks whether the event is \"empty\", i.e. nothing will happen after its execution.

func int EventPtr_Empty(var int eventPtr)\n
Parameters
  • var int eventPtr Pointer returned from EventPtr_Create

Return value

The function returns TRUE if empty, FALSE is returned otherwise.

"},{"location":"zengin/scripts/extenders/lego/tools/event_handler/#eventptr_has","title":"EventPtr_Has","text":"

Checks if function is added to an event.

func int EventPtr_Has(var int eventPtr, var func function)\n
Parameters
  • var int eventPtr Pointer returned from EventPtr_Create
  • var func function Checked function

Return value

The function returns TRUE if function is added, FALSE is returned otherwise.

"},{"location":"zengin/scripts/extenders/lego/tools/event_handler/#eventptr_hasi","title":"EventPtr_HasI","text":"

EventPtr_Has but with function ID instead of pointer. Used mainly internally.

func int EventPtr_HasI(var int eventPtr, var int id)\n
Parameters
  • var int eventPtr Pointer returned from EventPtr_Create
  • var int id ID of checked function

Return value

The function returns TRUE if function is added, FALSE is returned otherwise.

"},{"location":"zengin/scripts/extenders/lego/tools/event_handler/#eventptr_add","title":"EventPtr_Add","text":"

Adds an event handler function. The handler is called after running EventPtr_Execute.

func void EventPtr_Add(var int eventPtr, var func function)\n
Parameters
  • var int eventPtr Pointer returned from EventPtr_Create
  • var func function Function to be added
"},{"location":"zengin/scripts/extenders/lego/tools/event_handler/#eventptr_addi","title":"EventPtr_AddI","text":"

EventPtr_Add but with function ID instead of pointer. Used mainly internally.

func void EventPtr_AddI(var int eventPtr, var int id)\n
Parameters
  • var int eventPtr Pointer returned from EventPtr_Create
  • var int id ID of function to be added
"},{"location":"zengin/scripts/extenders/lego/tools/event_handler/#eventptr_addonce","title":"EventPtr_AddOnce","text":"

Event_Add but checks if function is already added, to prevent duplicates.

func void EventPtr_AddOnce(var int eventPtr, var func function)\n
Parameters
  • var int eventPtr Pointer returned from EventPtr_Create
  • var func function Function to be added
"},{"location":"zengin/scripts/extenders/lego/tools/event_handler/#eventptr_addoncei","title":"EventPtr_AddOnceI","text":"

EventPtr_AddI but checks if function is already added, to prevent duplicates.

func void EventPtr_AddOnceI(var int eventPtr, var int id)\n
Parameters
  • var int eventPtr Pointer returned from EventPtr_Create
  • var int id ID of function to be added
"},{"location":"zengin/scripts/extenders/lego/tools/event_handler/#eventptr_remove","title":"EventPtr_Remove","text":"

Removes a function from the event's call list.

func void EventPtr_Remove(var int eventPtr, var func function)\n
Parameters
  • var int eventPtr Pointer returned from EventPtr_Create
  • var func function Function to be removed
"},{"location":"zengin/scripts/extenders/lego/tools/event_handler/#eventptr_removei","title":"EventPtr_RemoveI","text":"

EventPtr_Remove but with function ID instead of pointer. Used mainly internally.

func void EventPtr_RemoveI(var int eventPtr, var int id)\n
Parameters
  • var int eventPtr Pointer returned from EventPtr_Create
  • var int id ID of function to be removed
"},{"location":"zengin/scripts/extenders/lego/tools/event_handler/#eventptr_execute","title":"EventPtr_Execute","text":"

Core of the package. Calls all functions registered via EventPtr_Add and EventPtr_AddOnce.

func void EventPtr_Execute(var int eventPtr, var int data)\n
  • var int eventPtr Pointer returned from EventPtr_Create
  • var int data Int parameter passed to all executed functions
"},{"location":"zengin/scripts/extenders/lego/tools/event_handler/#examples","title":"Examples","text":"

Note

This article has no built-in examples, but the best way to understand how EventHandler works is reading source code of the Gamestate package.

"},{"location":"zengin/scripts/extenders/lego/tools/frame_functions/","title":"FrameFunctions","text":""},{"location":"zengin/scripts/extenders/lego/tools/frame_functions/#framefunctions","title":"FrameFunctions","text":"

The FrameFunctions package allows to call any number of functions called on every frame, or every specified time delay.

"},{"location":"zengin/scripts/extenders/lego/tools/frame_functions/#dependencies","title":"Dependencies","text":"
  • Floats
  • PermMem
  • HookEngine
  • Timer
"},{"location":"zengin/scripts/extenders/lego/tools/frame_functions/#initialization","title":"Initialization","text":"

Initialize with LeGo_FrameFunctions flag.

LeGo_Init(LeGo_FrameFunctions);\n
"},{"location":"zengin/scripts/extenders/lego/tools/frame_functions/#implementation","title":"Implementation","text":"

FrameFunctions.d on GitHub

"},{"location":"zengin/scripts/extenders/lego/tools/frame_functions/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/tools/frame_functions/#ff_apply","title":"FF_Apply","text":"

Adds the Daedalus function function to the running FrameFunctions list. function is called each frame.

func void FF_Apply(var func function)\n
Parameters
  • var func function Name of the function
"},{"location":"zengin/scripts/extenders/lego/tools/frame_functions/#ff_applygt","title":"FF_ApplyGT","text":"

Adds the Daedalus function function to the running FrameFunctions list. function is called every frame except when the game is paused.

func void FF_ApplyGT(var func function)\n
Parameters
  • var func function Name of the function
"},{"location":"zengin/scripts/extenders/lego/tools/frame_functions/#ff_applydata","title":"FF_ApplyData","text":"

Adds the Daedalus function function to the running FrameFunctions list. The integer parameter data is passed to the function function.

func void FF_ApplyData(var func function, var int data)\n
Parameters
  • var func function Name of the function.
  • var int data Value passed to the function as a parameter
"},{"location":"zengin/scripts/extenders/lego/tools/frame_functions/#ff_applyext","title":"FF_ApplyExt","text":"

Adds the Daedalus function function to the running FrameFunctions list. The function function is called every delay milliseconds, and it runs only cycles number of times.

func void FF_ApplyExt(var func function, var int delay, var int cycles)\n
Parameters
  • var func function Name of the function
  • var int delay Delay between calls in milliseconds (0 = every frame)
  • var int cycles How many times should the function be called (-1 = endless)
"},{"location":"zengin/scripts/extenders/lego/tools/frame_functions/#ff_applyextgt","title":"FF_ApplyExtGT","text":"

Adds the Daedalus function function to the running FrameFunctions list. The function function is called every delay milliseconds, and it runs only cycles number of times. Gets called only when the game is not paused.

func void FF_ApplyExtGT(var func function, var int delay, var int cycles)\n
Parameters
  • var func function Name of the function
  • var int delay Delay between calls in milliseconds (0 = every frame)
  • var int cycles How many times should the function be called (-1 = endless)
"},{"location":"zengin/scripts/extenders/lego/tools/frame_functions/#ff_applyextdata","title":"FF_ApplyExtData","text":"

Adds the Daedalus function function to the running FrameFunctions list. The function function is called every delay milliseconds, and it runs only cycles number of times. The integer parameter data is passed to the function function.

func void FF_ApplyExtData(var func function, var int delay, var int cycles, var int data)\n
Parameters
  • var func function Name of the function.
  • var int delay Delay between calls in milliseconds (0 = every frame)
  • var int cycles How many times should the function be called (-1 = endless)
  • var int data Value passed to the function as a parameter
"},{"location":"zengin/scripts/extenders/lego/tools/frame_functions/#ff_applyextdatagt","title":"FF_ApplyExtDataGT","text":"

Adds the Daedalus function function to the running FrameFunctions list. The function function is called every delay milliseconds, and it runs only cycles number of times. The integer parameter data is passed to the function function. Gets called only when the game is not paused.

func void FF_ApplyExtData(var func function, var int delay, var int cycles, var int data)\n
Parameters
  • var func function Name of the function.
  • var int delay Delay between calls in milliseconds (0 = every frame)
  • var int cycles How many times should the function be called (-1 = endless)
  • var int data Value passed to the function as a parameter
"},{"location":"zengin/scripts/extenders/lego/tools/frame_functions/#ff_applyonce","title":"FF_ApplyOnce","text":"

Alias to FF_Apply, which only adds the function once, even after multiple calls.

func void FF_ApplyOnce(var func function)\n
Parameters
  • var func function Name of the function
"},{"location":"zengin/scripts/extenders/lego/tools/frame_functions/#ff_applyoncegt","title":"FF_ApplyOnceGT","text":"

Alias to FF_ApplyGT, which only adds the function once, even after multiple calls. Loop doesn't run if the game is paused.

func voidoften FF_ApplyOnceGT(var func function)\n
Parameters
  • var func function Name of the function.
"},{"location":"zengin/scripts/extenders/lego/tools/frame_functions/#ff_applyoncedata","title":"FF_ApplyOnceData","text":"

Alias to FF_ApplyData, which only adds the function with the specified parameter once, even after multiple calls.

func void FF_ApplyOnceData(var func function, var int data)\n
Parameters
  • var func function Name of the function.
  • var int data Value passed to the function as a parameter
"},{"location":"zengin/scripts/extenders/lego/tools/frame_functions/#ff_applyonceext","title":"FF_ApplyOnceExt","text":"

Alias to FF_ApplyExt, which adds the function only once, after repeated calls.

func void FF_ApplyOnceExt(var func function, var int delay, var int cycles)\n
Parameters
  • var func function Name of the function
  • var int delay Delay between calls in milliseconds (0 = every frame)
  • var int cycles How many times should the function be called (-1 = endless)
"},{"location":"zengin/scripts/extenders/lego/tools/frame_functions/#ff_applyonceextgt","title":"FF_ApplyOnceExtGT","text":"

Alias to FF_ApplyExtGT, which adds the function only once after repeated calls. Loop doesn't run if the game is paused.

func void FF_ApplyOnceExtGT(var func function, var int delay, var int cycles)\n
Parameters
  • var func function Name of the function
  • var int delay Delay between calls in milliseconds (0 = every frame)
  • var int cycles How many times should the function be called (-1 = endless)
"},{"location":"zengin/scripts/extenders/lego/tools/frame_functions/#ff_applyonceextdata","title":"FF_ApplyOnceExtData","text":"

Alias to FF_ApplyExtData, which adds the function with the specified parameter only once, after repeated calls.

func void FF_ApplyOnceExtData(var func function, var int delay, var int cycles, var int data)\n
Parameters
  • var func function Name of the function
  • var int delay Delay between calls in milliseconds (0 = every frame)
  • var int cycles How many times should the function be called (-1 = endless)
  • var int data Value passed to the function as a parameter
"},{"location":"zengin/scripts/extenders/lego/tools/frame_functions/#ff_active","title":"FF_Active","text":"

Checks whether the function is active.

func int FF_Active(var func function)\n
Parameters
  • var func function Name of the function

Return value The function returns TRUE if the function is active, FALSE if it is not.

"},{"location":"zengin/scripts/extenders/lego/tools/frame_functions/#ff_activedata","title":"FF_ActiveData","text":"

Checks whether the function with the specified data is active.

func int FF_ActiveData(var func function, var int data)\n
Parameters
  • var func function Name of the function
  • var int data Value previously passed to the function

Return value The function returns TRUE if the function is active, FALSE if it is not.

"},{"location":"zengin/scripts/extenders/lego/tools/frame_functions/#ff_remove","title":"FF_Remove","text":"

Stops a specific FrameFunction.

func void FF_Remove(var func function)\n
Parameters
  • var func function Name of the stopped function
"},{"location":"zengin/scripts/extenders/lego/tools/frame_functions/#ff_removeall","title":"FF_RemoveAll","text":"

Stops all intsnces of a specific FrameFunction.

func void FF_RemoveAll(var func function)\n
Parameters
  • var func function Name of the stopped function
"},{"location":"zengin/scripts/extenders/lego/tools/frame_functions/#ff_removedata","title":"FF_RemoveData","text":"

Stops a specific FrameFunction, with the specified value (see FF_ApplyExtData ).

func void FF_RemoveData(var func function, var int data)\n
Parameters
  • var func function Name of the stopped function
  • var int data Value previously passed to the function as a parameter
"},{"location":"zengin/scripts/extenders/lego/tools/frame_functions/#examples","title":"Examples","text":""},{"location":"zengin/scripts/extenders/lego/tools/frame_functions/#a-function-called-every-frame","title":"A function called every frame","text":"

In this example function MyFunc will be executed on every frame.

func void Example1()\n{\n    FF_Apply(MyFunc);\n};\n\nfunc void MyFunc() {};\n
After the Example1 function is executed the function MyFunc is called on every frame.

The easiest and best way to run a function from the beginning is to call FF-Apply directly in the Init_Global (under LeGo_Init), there is a small problem: If the game is loaded, Init_Global is called a second time, the function is added to the list again and is therefore always called twice.

To avoid this effect, you should check whether the function is already active:

func void Example1()\n{\n    if(!FF_Active(MyFunc))\n    {\n        FF_Apply(MyFunc);\n    };\n};\n

However, since LeGo version 2.2 there is an even more pleasant method to do this:

func void Example1()\n{\n    FF_ApplyOnce(MyFunc);\n};\n
FF_ApplyOnce function already implements the check for function activity."},{"location":"zengin/scripts/extenders/lego/tools/frame_functions/#calling-delayed-function","title":"Calling delayed function","text":"

Create a function, that is called once after 3 seconds.

func void Example2()\n{\n    FF_ApplyExt(MyFunc2, 3000, 1); // 3000 ms = 3 s, this function is called only once\n};\n\nfunc void MyFunc2() {};\n

There is also a Once variant of this function, that prevents adding it twice into the frame function list.

func void Example2()\n{\n    FF_ApplyOnceExt(MyFunc2, 3000, 1);\n};\n

Note

FF_ApplyExt(MyFunc, 0, -1) is the same as FF_Apply(MyFunc).

"},{"location":"zengin/scripts/extenders/lego/tools/frame_functions/#framefunction-with-timer","title":"FrameFunction with Timer","text":"

Since LeGo 2.2, FrameFunctions package uses the Timer package, so it is possible to pause FrameFunctions at will:

func void Example3()\n{\n    FF_ApplyOnceExt(MyFunc3, 4000, 2);\n};\n\nfunc void MyFunc3()\n{\n    Timer_SetPaused(!Timer_GetPaused());\n};\n
This would pause the timer after 4 seconds and let it continue after 8 seconds.

Warning

Because the timer doesn't run, the frame function execution is stopped as well. This script won't work. If the timer is to be paused, it must be paused outside FrameFunctions.

Note

This is translation of article originally written by Gottfried and Lehona and hosted on LeGo's official documentation website.

"},{"location":"zengin/scripts/extenders/lego/tools/hashtables/","title":"Hashtables","text":""},{"location":"zengin/scripts/extenders/lego/tools/hashtables/#hashtables","title":"Hashtables","text":"

Hashtables package is an implementation of hashtables in Gothic. Currently (version 2.8.0) only integers are supported as keys. The Hashtables grow automatically.

"},{"location":"zengin/scripts/extenders/lego/tools/hashtables/#dependencies","title":"Dependencies","text":"
  • PermMem
"},{"location":"zengin/scripts/extenders/lego/tools/hashtables/#initialization","title":"Initialization","text":"

Initialize with LeGo_PermMem flag.

LeGo_Init(LeGo_PermMem);\n
"},{"location":"zengin/scripts/extenders/lego/tools/hashtables/#implementation","title":"Implementation","text":"

Hashtable.d on GitHub

"},{"location":"zengin/scripts/extenders/lego/tools/hashtables/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/tools/hashtables/#ht_createsized","title":"HT_CreateSized","text":"

Generates a hashtable of the specified size.

func int HT_CreateSized(var int size)\n
Parameters
  • var int size Size of the hashtable to be created

Return value

The function returns a handle to the created hashtable.

"},{"location":"zengin/scripts/extenders/lego/tools/hashtables/#ht_create","title":"HT_Create","text":"

Generates a standard size hashtable.

func int HT_Create()\n
Return value

The function returns a handle to the created hashtable.

"},{"location":"zengin/scripts/extenders/lego/tools/hashtables/#ht_insert","title":"HT_Insert","text":"

Inserts a value into the Hashtable.

func void HT_Insert(var int handle, var int val, var int key)\n
Parameters
  • var int handle Handle of a hashtable
  • var int val The value to be inserted
  • var int key The key associated with the value
"},{"location":"zengin/scripts/extenders/lego/tools/hashtables/#ht_resize","title":"HT_Resize","text":"

Changes the size of the hashtable (usually not necessary as it happens automatically).

func void HT_Resize(var int handle, var int size)\n
Parameters
  • var int handle Handle of a hashtable
  • var int size The new size of the hashtable
"},{"location":"zengin/scripts/extenders/lego/tools/hashtables/#ht_get","title":"HT_Get","text":"

Reads a value from the hashtable.

func int HT_Get(var int handle, var int key)\n
Parameters
  • var int handle Handle of a hashtable
  • var int key The key whose value is to be read

Return value

The function returns the value associated with the key.

"},{"location":"zengin/scripts/extenders/lego/tools/hashtables/#ht_has","title":"HT_Has","text":"

Checks if the key already exist in hashtable.

func int HT_Has(var int handle, var int key)\n
Parameters
  • var int handle Handle of a hashtable
  • var int key The key to be checked Return value

The function returns TRUE if the key exist, FALSE is returned otherwise.

"},{"location":"zengin/scripts/extenders/lego/tools/hashtables/#ht_remove","title":"HT_Remove","text":"

Removes a key from the hashtable.

func void HT_Remove(var int handle, var int key)\n
Parameters
  • var int handle Handle of a hashtable
  • var int key The key to be removed
"},{"location":"zengin/scripts/extenders/lego/tools/hashtables/#ht_change","title":"HT_Change","text":"

Changes the value of a key already existing in the hashtable.

func void HT_Change(var int handle, var int val, var int key)\n
Parameters
  • var int handle Handle of a hashtable
  • var int val The new value
  • var int key The key whose value is to be changed
"},{"location":"zengin/scripts/extenders/lego/tools/hashtables/#ht_insertorchange","title":"HT_InsertOrChange","text":"

Inserts a value into the Hashtable, or changes the value if the key already exist into hashtable.

func void HT_InsertOrChange(var int handle, var int val, var int key)\n
Parameters
  • var int handle Handle of a hashtable
  • var int val The new value
  • var int key The key whose value is to be changed or associated with the value.
"},{"location":"zengin/scripts/extenders/lego/tools/hashtables/#ht_getnumber","title":"HT_GetNumber","text":"

Returns the number of entries in a hashtable.

func int HT_GetNumber(var int handle)\n
Parameters
  • var int handle Handle of a hashtable

Return value

The function returns the number of entries in the hashtable.

"},{"location":"zengin/scripts/extenders/lego/tools/hashtables/#ht_foreach","title":"HT_ForEach","text":"

Performs a function for each value pair in the hashtable.

func void HT_ForEach(var int handle, var func fnc)\n
Parameters
  • var int handle Handle of a hashtable
  • var func fnc A function with signature void (int key, int val)
"},{"location":"zengin/scripts/extenders/lego/tools/hashtables/#ht_destroy","title":"HT_Destroy","text":"

Deletes the hashtable.

func void HT_Destroy(var int handle)\n
Parameters
  • var int handle The handle of the hashtable to be deleted
"},{"location":"zengin/scripts/extenders/lego/tools/hashtables/#examples","title":"Examples","text":""},{"location":"zengin/scripts/extenders/lego/tools/hashtables/#simple-operations","title":"Simple operations","text":"
func void PrintKeyValuePair(var int key, var int val)\n{\n    Print(ConcatStrings(ConcatStrings(\"Key: \", IntToString(key)), ConcatStrings(\", Value: \", IntToString(val))));\n};\n\nfunc void example()\n{\n    // Create a new hashtable\n    var int hashtableHandle; hashtableHandle = HT_Create();\n\n    // Insert values into the hashtable\n    HT_Insert(hashtableHandle, 42, 1);\n    HT_Insert(hashtableHandle, 23, 2);\n    HT_Insert(hashtableHandle, 56, 3);\n\n    // Get a value from the hashtable\n    var int value; value = HT_Get(hashtableHandle, 2);\n    Print(ConcatStrings(\"Value associated with key 2: \", IntToString(value)));\n\n    // Check if a key exists in the hashtable\n    if (HT_Has(hashtableHandle, 3))\n    {\n        Print(\"Key 3 exists in the hashtable.\");\n    }\n    else\n    {\n        Print(\"Key 3 does not exist in the hashtable.\");\n    };\n\n    // Remove a key from the hashtable\n    HT_Remove(hashtableHandle, 1);\n\n    // Change the value associated with a key\n    HT_Change(hashtableHandle, 99, 3);\n\n    // Insert a value or change it if the key exists\n    HT_InsertOrChange(hashtableHandle, 123, 4);\n\n    // Get the number of entries in the hashtable\n    var int numEntries; numEntries = HT_GetNumber(hashtableHandle);\n    Print(ConcatStrings(\"Number of entries in the hashtable: \", IntToString(numEntries)));\n\n\n    // Iterate through the hashtable and print key-value pairs\n    // Function from top of the example is used here\n    HT_ForEach(hashtableHandle, PrintKeyValuePair);\n\n    // Destroy the hashtable\n    HT_Destroy(hashtableHandle);\n};\n
"},{"location":"zengin/scripts/extenders/lego/tools/hook_dae/","title":"HookDaedalus","text":""},{"location":"zengin/scripts/extenders/lego/tools/hook_dae/#hookdaedalus","title":"HookDaedalus","text":"

This package allows hooking daedalus functions. The principle is similar HookEngine. We have a function (hooked function) into which we would like to hook another function (hook function).

Tip

Having to hook a Daedalus function should be pretty rare, because you can simply adjust the corresponding function. However, it may become necessary in some contexts.

"},{"location":"zengin/scripts/extenders/lego/tools/hook_dae/#dependencies","title":"Dependencies","text":"

N/A

"},{"location":"zengin/scripts/extenders/lego/tools/hook_dae/#initialization","title":"Initialization","text":"

N/A

"},{"location":"zengin/scripts/extenders/lego/tools/hook_dae/#implementation","title":"Implementation","text":"

HookDaedalus.d on GitHub

"},{"location":"zengin/scripts/extenders/lego/tools/hook_dae/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/tools/hook_dae/#hookdaedalusfunc","title":"HookDaedalusFunc","text":"

Hooks the function.

func void HookDaedalusFunc(var func hooked, var func hook)\n
Parameters
  • var func hooked Hooked function
  • var func hook Hook function
"},{"location":"zengin/scripts/extenders/lego/tools/hook_dae/#hookdaedalusfuncf","title":"HookDaedalusFuncF","text":"

Alias to the HookDaedalusFunc function.

func void HookDaedalusFuncF(var func hooked, var func hook)\n
Parameters
  • var func hooked Hooked function
  • var func hook Hook function
"},{"location":"zengin/scripts/extenders/lego/tools/hook_dae/#hookdaedalusfunci","title":"HookDaedalusFuncI","text":"

HookDaedalusFunc but with function ID.

func void HookDaedalusFuncI(var int hookedID, var int hookID)\n
Parameters
  • var int hookedID ID of hooked function
  • var int hookID ID of hook function
"},{"location":"zengin/scripts/extenders/lego/tools/hook_dae/#hookdaedalusfuncs","title":"HookDaedalusFuncS","text":"

HookDaedalusFunc but with function name.

func void HookDaedalusFuncS(var string hookedName, var string hookName)\n
Parameters
  • var string hookedName Name of hooked function
  • var string hookName Name of hook function
"},{"location":"zengin/scripts/extenders/lego/tools/hook_dae/#ishookd","title":"IsHookD","text":"

Checks whether a function is already hooking another. Each function can be hooked any number of times, but each function can only hook one other.

func int IsHookD(var int funcID)\n
Parameters
  • var int funcID Symbol index of a hook function

Return value

The function returns TRUE if the function is already hooking another, FALSE is returned otherwise.

"},{"location":"zengin/scripts/extenders/lego/tools/hook_dae/#continuecall","title":"ContinueCall","text":"

Continues the program run with the original function.

func void ContinueCall()\n
"},{"location":"zengin/scripts/extenders/lego/tools/hook_dae/#passargumenti","title":"PassArgumentI","text":"

Passes an integer as an argument to the original function. Must be called before ContinueCall.

func void PassArgumentI(var int i)\n
Parameters
  • var int i Integer argument to forward
"},{"location":"zengin/scripts/extenders/lego/tools/hook_dae/#passarguments","title":"PassArgumentS","text":"

Passes a string as an argument to the original function. Must be called before ContinueCall.

func void PassArgumentS(var string s)\n
Parameters
  • var string s String argument to forward
"},{"location":"zengin/scripts/extenders/lego/tools/hook_dae/#passargumentn","title":"PassArgumentN","text":"

Passes an instance as an argument to the original function. Must be called before ContinueCall.

func void PassArgumentN(var instance n)\n
Parameters
  • var instance n Instance argument to forward
"},{"location":"zengin/scripts/extenders/lego/tools/hook_dae/#examples","title":"Examples","text":""},{"location":"zengin/scripts/extenders/lego/tools/hook_dae/#hook-before-function","title":"Hook before function","text":"

We have a hook:

HookDaedalusFunc(hooked, hook);\n
The functions can look like that:
func void hooked() \n{\n    Print(\"Original function\");\n};\n\nfunc void hook() \n{\n    Print(\"Our hook\");\n    ContinueCall();\n};\n
The results should look like that
Our hook\nOriginal function\n
"},{"location":"zengin/scripts/extenders/lego/tools/hook_dae/#hook-after-function","title":"Hook after function","text":"

We have the same hook:

HookDaedalusFunc(hooked, hook);\n
The functions are also similar, but the ContinueCall(); is called first:
func void hooked() \n{\n    Print(\"Original function\");\n};\n\nfunc void hook() \n{\n    ContinueCall();\n    Print(\"Our hook\");\n};\n
The results should look like that:
Original function\nOur hook\n
"},{"location":"zengin/scripts/extenders/lego/tools/hook_dae/#arguments-and-return-values","title":"Arguments and return values","text":"

If a function to be hooked expects parameters or returns a value, our hooking function should conform to that.

func int hooked(var int i) \n{\n     Print(\"Original function\");\n     return i+1;\n};\n\nfunc int hook(var int i) \n{\n     Print(\"Our hook\");\n     PassArgumentI(i);\n     ContinueCall();\n};\n
In this case, we may not return the value at the end of the hook because the returned value will just stay on the stack. However, we shouldn't give up on calling PassArgumentI(i) to ensure that it is still on top of the stack when the program continues with hooked."},{"location":"zengin/scripts/extenders/lego/tools/hook_dae/#manipulation-of-arguments-and-return-values","title":"Manipulation of arguments and return values","text":"

We can also manipulate arguments and return values with our hook.

func int hook(var int i) \n{\n    Print(\"Our hook\");\n    PassArgumentI(i+1);     // add 1\n    ContinueCall();\n    i = MEM_PopIntResult();\n    i *= 2;                 // Multiply by 2\n    return i;\n};\n
"},{"location":"zengin/scripts/extenders/lego/tools/hook_dae/#multiple-hooks","title":"Multiple hooks","text":"

A function can be hooked any number of times, but each function can only hook one. New hooks are always inserted after the previous one. The following example illustrates this quite well.

HookDaedalusFunc(a, b); // B hooks A\nHookDaedalusFunc(a, c); // C hooks A to B\nHookDaedalusFunc(a, d); // D hooks A to C\n\nHookDaedalusFunc(c, b); // Ignored because B is already hooking a function\n\nvar int i; i = a(1);\n\n\n// Hooked function\nfunc int a(var int i) \n{\n    MEM_Info(ConcatStrings(\"---  A: \", IntToString(i)));\n    return i+1;\n};\n\n// First hook function:\n// Replaces `a` because the program run is not continued with ContinueCall\nfunc int b(var int i) \n{\n    MEM_Info(ConcatStrings(\"  -- B: \", IntToString(i)));\n    return i;\n};\n\n// Second hook function:\n// Increments the argument before ContinueCall and then decrements the return value\nfunc int c(var int i) \n{\n    MEM_Info(ConcatStrings(\" -> C: \", IntToString(i)));\n    passArgumentI(i+1);\n    ContinueCall();\n\n    i = MEM_PopIntResult();\n    i -= 1;\n    MEM_Info(ConcatStrings(\" <- C: \", IntToString(i)));\n    return i;\n};\n\n// Third hook function:\n// Increments the argument before ContinueCall and then decrements the return value\nfunc int d(var int i) \n{\n    MEM_Info(ConcatStrings(\"-> D: \", IntToString(i)));\n    passArgumentI(i+1);\n    ContinueCall();\n\n    i = MEM_PopIntResult();\n    i -= 1;\n    MEM_Info(ConcatStrings(\"<- D: \", IntToString(i)));\n    return i;\n};\n\n// Output:\n// -> D: 1\n//  -> C: 2\n//   -- B: 3\n//  <- C: 2\n// <- D: 1\n
"},{"location":"zengin/scripts/extenders/lego/tools/hook_engine/","title":"HookEngine","text":""},{"location":"zengin/scripts/extenders/lego/tools/hook_engine/#hookengine","title":"HookEngine","text":"

This package allows you to hook anywhere in an engine function to run your own Daedalus code.

Tip

Zerxes has provided a list of all engine functions for G2, including the number of bytes to fill in for oldInstr. This list can be found here. This should make it possible for everyone to use the HookEngine effectively without IDA.

"},{"location":"zengin/scripts/extenders/lego/tools/hook_engine/#dependencies","title":"Dependencies","text":"

N/A

"},{"location":"zengin/scripts/extenders/lego/tools/hook_engine/#initialization","title":"Initialization","text":"

N/A

"},{"location":"zengin/scripts/extenders/lego/tools/hook_engine/#implementation","title":"Implementation","text":"

HookEngine.d on GitHub

"},{"location":"zengin/scripts/extenders/lego/tools/hook_engine/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/tools/hook_engine/#hookengine_1","title":"HookEngine","text":"

Attaches a function to an engine function address.

func void HookEngine(var int address, var int oldInstr, var string function)\n
Parameters
  • var int address Address of an engine function to which the function should be attached.
  • var int oldInstr The length in bytes of the instruction to be found at address, at least 5 bytes. Can be seen in IDA.
  • var string function Name of Daedalus function to be called.
"},{"location":"zengin/scripts/extenders/lego/tools/hook_engine/#hookengines","title":"HookEngineS","text":"

Alias to the HookEngine function.

func void HookEngineS(var int address, var int oldInstr, var string function)\n
Parameters
  • var int address Address of an engine function to which the function should be attached.
  • var int oldInstr The length in bytes of the instruction to be found at address, at least 5 bytes. Can be seen in IDA.
  • var string function Name of Daedalus function to be called.
"},{"location":"zengin/scripts/extenders/lego/tools/hook_engine/#hookenginei","title":"HookEngineI","text":"

Alias to HookEngine with funcID.

func void HookEngineI(var int address, var int oldInstr, var int funcID)\n
Parameters
  • var int address Address of an engine function to which the function should be attached.
  • var int oldInstr The length in bytes of the instruction to be found at address, at least 5 bytes. Can be seen in IDA.
  • var int funcID ID of Daedalus function to be called.
"},{"location":"zengin/scripts/extenders/lego/tools/hook_engine/#hookenginef","title":"HookEngineF","text":"

Alias to HookEngine with func parameter.

func void HookEngineF(var int address, var int oldInstr, var func function)\n
Parameters
  • var int address Address of an engine function to which the function should be attached.
  • var int oldInstr The length in bytes of the instruction to be found at address, at least 5 bytes. Can be seen in IDA.
  • var func function Daedalus function to be called.
"},{"location":"zengin/scripts/extenders/lego/tools/hook_engine/#ishooked","title":"IsHooked","text":"

Checks if a hook is already present at a given address.

func var int IsHooked(var int address)\n
Parameters
  • var int address Address of an engine function.

Return value

The function returns TRUE if the hook already exists at the address, FALSE is returned otherwise.

"},{"location":"zengin/scripts/extenders/lego/tools/hook_engine/#ishook","title":"IsHook","text":"

Checks if a hook with a certain function is already present at an address.

func var int IsHook(var int address, var string function)\n
Parameters
  • var int address Address of an engine function.
  • var string function Name of a function.

Return value

The function returns TRUE if the hook already exists at the address, FALSE is returned otherwise.

"},{"location":"zengin/scripts/extenders/lego/tools/hook_engine/#ishooki","title":"IsHookI","text":"

Alias to IsHook with a funcID as parameter.

func var int IsHookI(var int address, var int funcID)\n
Parameters
  • var int address Address of an engine function.
  • var int funcID ID of a function.

Return value

The function returns TRUE if the hook already exists at the address, FALSE is returned otherwise.

"},{"location":"zengin/scripts/extenders/lego/tools/hook_engine/#ishookf","title":"IsHookF","text":"

Alias to IsHook with a function as parameter.

func var int IsHookF(var int address, var func function)\n
Parameters
  • var int address Address of an engine function.
  • var func function Daedalus function.

Return value func parameter The function returns TRUE if the hook already exists at the address, FALSE is returned otherwise.

"},{"location":"zengin/scripts/extenders/lego/tools/hook_engine/#removehook","title":"RemoveHook","text":"

Removes a function from a hook so that it is no longer called.

func void RemoveHook(var int address, var int oldInstr, var string function)\n
Parameters
  • var int address Address of an engine function to which the function should be attached.
  • var int oldInstr The length in bytes of the instruction to be found at address, at least 5 bytes. Can be seen in IDA.
  • var string function Name of Daedalus function that should no longer be called.
"},{"location":"zengin/scripts/extenders/lego/tools/hook_engine/#removehooki","title":"RemoveHookI","text":"

Alias to RemoveHook with funcID.

func void RemoveHook(var int address, var int oldInstr, var int funcID)\n
Parameters
  • var int address Address of an engine function to which the function should be attached.
  • var int oldInstr The length in bytes of the instruction to be found at address, at least 5 bytes. Can be seen in IDA.
  • var int funcID ID of Daedalus function that should no longer be called.
"},{"location":"zengin/scripts/extenders/lego/tools/hook_engine/#removehookf","title":"RemoveHookF","text":"

Alias for RemoveHook with func parameter.

func void RemoveHook(var int address, var int oldInstr, var func function)\n
Parameters
  • var int address Address of an engine function to which the function should be attached.
  • var int oldInstr The length in bytes of the instruction to be found at address, at least 5 bytes. Can be seen in IDA.
  • var func function Daedalus function that should no longer be called.
"},{"location":"zengin/scripts/extenders/lego/tools/hook_engine/#replaceenginefunc","title":"ReplaceEngineFunc","text":"

Replaces an engine function with a Daedalus function.

func void ReplaceEngineFunc(var int address, var int thiscall_numparams, var string replaceFunc)\n
Parameters
  • var int address Address of the engine function to be replaced.
  • var int thiscall_numparams Number of parameters passed to the engine function, if it is a stdcall or thiscall (otherwise 0).
  • var string replaceFunc Name of a Daedalus function to be called instead.
"},{"location":"zengin/scripts/extenders/lego/tools/hook_engine/#replaceenginefunci","title":"ReplaceEngineFuncI","text":"

Alias to ReplaceEngineFunc with funcID.

func void ReplaceEngineFunc(var int address, var int thiscall_numparams, var int funcID)\n
Parameters
  • var int address Address of the engine function to be replaced.
  • var int thiscall_numparams Number of parameters passed to the engine function, if it is a stdcall or thiscall (otherwise 0).
  • var int funcID ID of a Daedalus function to be called instead.
"},{"location":"zengin/scripts/extenders/lego/tools/hook_engine/#replaceenginefuncf","title":"ReplaceEngineFuncF","text":"

Alias to ReplaceEngineFunc with func parameter.

func void ReplaceEngineFunc(var int address, var int thiscall_numparams, var func function)\n
Parameters
  • var int address Address of the engine function to be replaced.
  • var int thiscall_numparams Number of parameters passed to the engine function, if it is a stdcall or thiscall (otherwise 0).
  • var func function Daedalus function to be called instead.
"},{"location":"zengin/scripts/extenders/lego/tools/hook_engine/#disableenginefunc","title":"DisableEngineFunc","text":"

Makes sure that an engine function is simply skipped. This is very delicate and will not always work so easily.

func void DisableEngineFunc(var int address, var int thiscall_numparams)\n
Parameters
  • var int address Address of the engine function to be skipped.
  • var int thiscall_numparams Number of parameters passed to the engine function, if it is a stdcall or thiscall (otherwise 0).
"},{"location":"zengin/scripts/extenders/lego/tools/hook_engine/#hook_returnfalse","title":"Hook_ReturnFalse","text":"

Simple function to replace return FALSE in hook.

func void Hook_ReturnFalse()\n
"},{"location":"zengin/scripts/extenders/lego/tools/hook_engine/#hook_returntrue","title":"Hook_ReturnTrue","text":"

Simple function to replace return TRUE in hook.

func void Hook_ReturnTrue()\n
"},{"location":"zengin/scripts/extenders/lego/tools/hook_engine/#registers","title":"Registers","text":"

In addition the HookEngine package implement x86 32-bit registers that can be used to access hooked function parameters.

var int EAX;\nvar int ECX;\nvar int EDX;\nvar int EBX;\nvar int ESP;\nvar int EBP;\nvar int ESI;\nvar int EDI;    \n
"},{"location":"zengin/scripts/extenders/lego/tools/int64/","title":"Int64","text":""},{"location":"zengin/scripts/extenders/lego/tools/int64/#int64","title":"Int64","text":"

Int64 implements basic arithmetic for 64-bit integers based on machine code (hence the function signatures are also in machine code style). Furthermore, Int64 offers the constructor int64@ for Int64 objects, but mk64 expects a pointer, not a handle.

"},{"location":"zengin/scripts/extenders/lego/tools/int64/#dependencies","title":"Dependencies","text":"

N/A

"},{"location":"zengin/scripts/extenders/lego/tools/int64/#initialization","title":"Initialization","text":"

N/A

"},{"location":"zengin/scripts/extenders/lego/tools/int64/#implementation","title":"Implementation","text":"

Int64.d on GitHub

"},{"location":"zengin/scripts/extenders/lego/tools/int64/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/tools/int64/#mk64","title":"mk64","text":"

Writes lo and hi in one place (dest). Makes Int64, hi has to be -1 for negative 32bit lo.

func void mk64(var int dest, var int hi, var int lo)\n
Parameters
  • var int dest A pointer to an Int64 object or just 8 bytes of free memory.
  • var int hi High part of integer.
  • var int lo Low part of integer.
Examples

Function looks like that:

    func void mk64(var int dest, var int lo, var int hi) {\n    MEM_WriteInt(dest, lo);\n    MEM_WriteInt(dest+4, hi);\n    };\n
So if you want to get 9876543210 low part should be set to 1286608618 and the high part to 2
var int ptr; ptr = MEM_Alloc(8);\nvar int low; low = 1286608618;\nvar int high; high = 2;\nmk64(ptr, low, high);\n// ...\nMEM_Free(ptr);\n
"},{"location":"zengin/scripts/extenders/lego/tools/int64/#neg64","title":"neg64","text":"

Negates the integer: *dest <- -(*dest)

func void neg64(var int dest)\n
Parameters
  • var int dest A pointer to an Int64 object or just 8 bytes of free memory.
"},{"location":"zengin/scripts/extenders/lego/tools/int64/#add64","title":"add64","text":"

Adds src to dest: *dest <- *dest + *src

func void add64(var int dest, var int src)\n
Parameters
  • var int dest A pointer to an Int64 object or just 8 bytes of free memory. Will be changed.
  • var int src A pointer to an Int64 object. Will not change.
"},{"location":"zengin/scripts/extenders/lego/tools/int64/#sub64","title":"sub64","text":"

Subtracts src from dest: *dest <- *dest - *src

func void sub64(var int dest, var int src)\n
Parameters
  • var int dest A pointer to an Int64 object or just 8 bytes of free memory. Will be changed.
  • var int src A pointer to an Int64 object. Will not change.
"},{"location":"zengin/scripts/extenders/lego/tools/int64/#mul64","title":"mul64","text":"

Multiplies dest by src: *dest <- (*dest) * (*src)

func void mul64(var int dest, var int src)\n
Parameters
  • var int dest A pointer to an Int64 object or just 8 bytes of free memory. Will be changed.
  • var int src A pointer to an Int64 object. Will not change.
"},{"location":"zengin/scripts/extenders/lego/tools/int64/#div64","title":"div64","text":"

Divides dest by src: *dest <- *dest / *src

func void mul64(var int dest, var int src)\n
Parameters
  • var int dest A pointer to an Int64 object or just 8 bytes of free memory. Will be changed.
  • var int src A pointer to an Int64 object. Will not change.
"},{"location":"zengin/scripts/extenders/lego/tools/interface/","title":"Interface","text":""},{"location":"zengin/scripts/extenders/lego/tools/interface/#interface","title":"Interface","text":"

This package offers a lot of useful functions to work with the 2D interface.

"},{"location":"zengin/scripts/extenders/lego/tools/interface/#dependencies","title":"Dependencies","text":"
  • AI_Function
  • Anim8
  • HookEngine
  • PermMem
"},{"location":"zengin/scripts/extenders/lego/tools/interface/#initialization","title":"Initialization","text":"

Initialize with LeGo_Interface and LeGo_PrintS flag.

LeGo_Init(LeGo_Interface | LeGo_PrintS);\n
"},{"location":"zengin/scripts/extenders/lego/tools/interface/#implementation","title":"Implementation","text":"

Interface.d on GitHub

"},{"location":"zengin/scripts/extenders/lego/tools/interface/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/tools/interface/#sysgettime","title":"sysGetTime","text":"

Better alternative for MEM_GetSysTime() from Ikarus.

func int sysGetTime()\n
Return value

The function returns elapsed time since game (system) startup.

"},{"location":"zengin/scripts/extenders/lego/tools/interface/#rgba","title":"RGBA","text":"

Generates a full zColor.

func int RGBA(var int r, var int g, var int b, var int a)\n
Parameters
  • var int r Red channel value (0..255)
  • var int g Green channel value (0..255)
  • var int b Blue channel value (0..255)
  • var int a Alpha (0..255, 0 = invisible)

Return value

The function returns a zColor object.

"},{"location":"zengin/scripts/extenders/lego/tools/interface/#changealpha","title":"ChangeAlpha","text":"

Overrides the alpha value of a given zColor.

func int ChangeAlpha(var int zCol, var int a)\n
Parameters
  • var int zCol zColor to modify
  • var int a New alpha value

Return value

The function returns a modified zColor object.

"},{"location":"zengin/scripts/extenders/lego/tools/interface/#getalpha","title":"GetAlpha","text":"

Returns the alpha value of a given zColor.

func int GetAlpha(var int zCol)\n
Parameters
  • var int zCol zColor to get alpha from
"},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_createtext","title":"Print_CreateText","text":"

Creates a new zCViewText on the screen with PermMem that can be freely edited.

func int Print_CreateText(var string text, var string font)\n
Parameters
  • var string text The text of the zCViewText
  • var string font Font of text

Return value

The function returns a handle to zCViewText.

"},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_createtextptr","title":"Print_CreateTextPtr","text":"

Print_CreateText but returns pointer to zCViewText instead of handle.

func int Print_CreateTextPtr(var string text, var string font)\n
Parameters
  • var string text The text of the zCViewText
  • var string font Font of text

Return value

The function returns a pointer to zCViewText.

"},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_createtextptrcolored","title":"Print_CreateTextPtrColored","text":"

Print_CreateTextPtr but with additional parameter to chose color of text.

func int Print_CreateTextPtrColored(var string text, var string font, var int color)\n
Parameters
  • var string text The text of the zCViewText
  • var string font Font of text
  • var int color zColor e.g. generated with RGBA function

Return value

The function returns a pointer to zCViewText.

"},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_gettext","title":"Print_GetText","text":"

Returns zCViewText instance from handle.

func zCViewText Print_GetText(var int hndl)\n
Parameters
  • var int hndl Handle to zCViewText
"},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_gettextptr","title":"Print_GetTextPtr","text":"

Returns zCViewText pointer from handle.

func int Print_GetTextPtr(var int hndl)\n
Parameters
  • var int hndl Handle to zCViewText
"},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_deletetext","title":"Print_DeleteText","text":"

Removes a zCViewText from the screen.

func void Print_DeleteText(var int hndl)\n
Parameters
  • var int hndl Handle to zCViewText (form Print_CreateText or Print_Ext)
"},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_setalpha","title":"Print_SetAlpha","text":"

Changes the alpha value of a given zCViewText.

func void Print_SetAlpha(var int hndl, var int a)\n
Parameters
  • var int hndl Handle to zCViewText
  • var int a New alpha value
"},{"location":"zengin/scripts/extenders/lego/tools/interface/#printptr_setalpha","title":"PrintPtr_SetAlpha","text":"

Print_SetAlpha but with pointer to zCViewText instead of handle.

func void PrintPtr_SetAlpha(var int ptr, var int a)\n
Parameters
  • var int ptr Pointer to zCViewText
  • var int a New alpha value
"},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_getscreensize","title":"Print_GetScreenSize","text":"

Writes the current resolution to the Print_Screen array and the current aspect ratio to Print_Ratio variable.

func void Print_GetScreenSize()\n
"},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_screen","title":"Print_Screen","text":"

An int array holding the current resolution. (Filled by Print_GetScreenSize)

int Print_Screen[2];\n
  • Print_Screen[PS_X] is the horizontal resolution

  • Print_Screen[PS_Y] is the vertical resolution

"},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_ratio","title":"Print_Ratio","text":"

A float variable that holds the current aspect ratio. (Filled by Print_GetScreenSize)

int Print_Ratio;\n
"},{"location":"zengin/scripts/extenders/lego/tools/interface/#ps_vmax","title":"PS_VMax","text":"

An int constant that holds the highest possible value of a virtual coordinate.

const int PS_VMax = 8192;\n
"},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_tovirtual","title":"Print_ToVirtual","text":"

Convents pixel position to a virtual position.

func int Print_ToVirtual(var int pxl, var int dim)\n
Parameters
  • var int pxl Pixel position to convert
  • var int dim PS_X or PS_Y (see Print_Screen)

Return value

The function returns a virtual position of a given pixel position.

"},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_tovirtualf","title":"Print_ToVirtualF","text":"

Print_ToVirtual but returns Ikarus float value instead of integer.

func int Print_ToVirtualF(var int pxl, var int dim)\n
Parameters
  • var int pxl Pixel position to convert
  • var int dim PS_X or PS_Y (see Print_Screen)

Return value

The function returns a virtual position of a given pixel position as Ikarus float.

"},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_topixel","title":"Print_ToPixel","text":"

Convents virtual position to a pixel position.

func int Print_ToPixel(var int vrt, var int dim)\n
Parameters
  • var int vrt Virtual position to convert
  • var int dim PS_X or PS_Y (see Print_Screen)

Return value

The function returns a pixel position of a given virtual position.

"},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_topixelf","title":"Print_ToPixelF","text":"

Print_ToPixel but returns Ikarus float value instead of integer.

func int Print_ToPixelF(var int vrt, var int dim)\n
Parameters
  • var int vrt Virtual position to convert
  • var int dim PS_X or PS_Y (see Print_Screen)

Return value

The function returns a pixel position of a given virtual position as Ikarus float.

"},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_toratio","title":"Print_ToRatio","text":"

Gets the size in the specified dimension in ratioed by the screen.

func int Print_ToRatio(var int size, var int dim)\n
Parameters
  • var int size Size to convert
  • var int dim PS_X or PS_Y (see Print_Screen)

Return value

The function returns size correctly calculated to the ratio.

Example

If you have a view and the view you need to be a square of 400 units, you would do:

height = Print_ToRatio(400, PS_Y);\nwidth = 400;\n
This is because width is always the max in virtual coordinates - 8192 virtual points and the height has a different height based on the ratio, this function calculates it for you.

PS_X can be used in function, if you already have the height but need the width in the correct ratio.

"},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_toradian","title":"Print_ToRadian","text":"

Converts angle in degrees to radians.

func int Print_ToRadian(var int angle)\n
Parameters
  • var int angle Angle in degrees

Return value

The function returns calculated angle in radians.

"},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_todegree","title":"Print_ToDegree","text":"

Converts angle in radians to degrees.

func int Print_ToDegree(var int angle)\n
Parameters
  • var int angle Angle in radians

Return value

The function returns calculated angle in degrees.

"},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_getfontptr","title":"Print_GetFontPtr","text":"

Returns a pointer to a zCFont by its name.

func int Print_GetFontPtr(var string font)\n
Parameters
  • var string font Name of font
"},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_getfontname","title":"Print_GetFontName","text":"

Returns a name of a zCFont from its pointer.

func string Print_GetFontName(var int fontPtr)\n
Parameters
  • var int fontPtr Pointer to font
"},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_getstringwidth","title":"Print_GetStringWidth","text":"

Returns the width of a string in pixels.

func int Print_GetStringWidth(var string s, var string font)\n
Parameters
  • var string s Measured string
  • var string font Name of font
"},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_getstringwidthptr","title":"Print_GetStringWidthPtr","text":"

Print_GetStringWidth but with zCFont pointer instead of name.

func int Print_GetStringWidthPtr(var string s, var int font)\n
Parameters
  • var string s Measured string
  • var int font zCFont pointer
"},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_getfontheight","title":"Print_GetFontHeight","text":"

Returns the height of a string in pixels.

func int Print_GetFontHeight(var string font)\n
Parameters
  • var string font Name of font
"},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_ext","title":"Print_Ext","text":"

Like the external PrintScreen, writes a text on the screen, but with more options.

func int Print_Ext(var int x, var int y, var string text, var string font, var int color, var int time)\n
Parameters
  • var int x X coordinate on the screen (virtual)
  • var int y Y coordinate on the screen (virtual)
  • var string text Displayed text
  • var string font Name of font
  • var int color zColor e.g. generated with RGBA function
  • var int time display time in milliseconds (-1 = permanent)

Return value

If time == -1, a valid handle is returned. If time != -1, the print is only volatile and no handle is returned.

Example
func void Example1()\n{\n    //           x, y, text,   font,        color,                time\n    Print_ExtPxl(2, 2, \"Text\", FONT_Screen, RGBA(255, 0, 0, 128), 500);\n};\n
"},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_extpxl","title":"Print_ExtPxl","text":"

Print_Ext but with pixel coordinates instead of virtual.

func int Print_ExtPxl(var int x, var int y, var string text, var string font, var int color, var int time)\n
Parameters
  • var int x X coordinate on the screen (pixel)
  • var int y Y coordinate on the screen (pixel)
  • var string text Displayed text
  • var string font Name of font
  • var int color zColor e.g. generated with RGBA function
  • var int time display time in milliseconds (-1 = permanent)

Return value

If time == -1, a valid handle is returned. If time != -1, the print is only volatile and no handle is returned.

"},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_longestline","title":"Print_LongestLine","text":"

Returns the longest line from text as a string, using default line separator tilde ~.

func string Print_LongestLine(var string text, var string font)\n
Parameters
  • var string text Measured text
  • var string font Name of font
"},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_longestlineext","title":"Print_LongestLineExt","text":"

Returns the longest line from text as a string, but you specify new line separator.

func string Print_LongestLineExt(var string text, var string font, var string separator)\n
Parameters
  • var string text Measured text
  • var string font Name of font
  • var string separator New line separator
"},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_longestlinelength","title":"Print_LongestLineLength","text":"

Returns the longest line width in pixels, using default line separator tilde ~.

func int Print_LongestLineLength(var string text, var string font)\n
Parameters
  • var string text Measured text
  • var string font Name of font
"},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_longestlinelengthext","title":"Print_LongestLineLengthExt","text":"

Returns the longest line width in pixels, but allows you to specify new line separator.

func int Print_LongestLineLengthExt(var string text, var string font, var string separator)\n
Parameters
  • var string text Measured text
  • var string font Name of font
  • var string separator New line separator
"},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_textfield","title":"Print_TextField","text":"

Creates a text field (view with text) using virtual coordinates.

func int Print_TextField(var int x, var int y, var string text, var string font, var int height)\n
Parameters
  • var int x X coordinate (virtual)
  • var int y Y coordinate (virtual)
  • var string text Text to be printed
  • var string font Name of font
  • var int height A specific line height

Return value

The function returns a text field pointer. Here is how it is used:

var zCView view; view = get(viewHndl);\nview.textLines_next = Print_TextField(x, y, text, FONT, fontHeight);\n
"},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_textfieldpxl","title":"Print_TextFieldPxl","text":"

Print_TextField but with pixel coordinates.

func int Print_TextFieldPxl(var int x, var int y, var string text, var string font)\n
Parameters
  • var int x X coordinate (pixel)
  • var int y Y coordinate (pixel)
  • var string text Text to be printed
  • var string font Name of font

Return value

The function returns a text field pointer. Look at the Print_TextField return value to see an example.

"},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_textfieldcolored","title":"Print_TextFieldColored","text":"

Print_TextField but you specify the color of text.

func int Print_TextFieldColored(var int x, var int y, var string text, var string font, var int height, var int color)\n
Parameters
  • var int x X coordinate (virtual)
  • var int y Y coordinate (virtual)
  • var string text Text to be printed
  • var string font Name of font
  • var int height A specific line height
  • var int color zColor e.g. generated with RGBA function

Return value

The function returns a text field pointer. Look at the Print_TextField return value to see an example.

"},{"location":"zengin/scripts/extenders/lego/tools/interface/#prints","title":"PrintS","text":"

Same function as the external Print, but with smooth animations. The effect can be changed as desired with the user constants.

func void PrintS(var string txt)\n
Parameters
  • var string txt Printed text
"},{"location":"zengin/scripts/extenders/lego/tools/interface/#prints_ext","title":"PrintS_Ext","text":"

PrintS but with an additional parameter to choose the color of the text.

func void PrintS_Ext(var string txt, var int color)\n
Parameters
  • var string txt Printed text
  • var int color zColor e.g. generated with RGBA function
"},{"location":"zengin/scripts/extenders/lego/tools/interface/#ai_prints","title":"AI_PrintS","text":"

Version of PrintS that enqueue in given NPCs AI queue.

func void AI_PrintS(var c_npc slf, var string txt)\n
Parameters
  • var c_npc slf NPC to whose AI queue the function is enqueued
  • var string txt Printed text
"},{"location":"zengin/scripts/extenders/lego/tools/interface/#ai_prints_ext","title":"AI_PrintS_Ext","text":"

Version of PrintS_Ext that enqueue in given NPCs AI queue.

func void AI_PrintS_Ext(var c_npc slf, var string txt, var int color)\n
Parameters
  • var c_npc slf NPC to whose AI queue the function is enqueued
  • var string txt Printed text
  • var int color zColor e.g. generated with RGBA function
"},{"location":"zengin/scripts/extenders/lego/tools/interface/#examples","title":"Examples","text":""},{"location":"zengin/scripts/extenders/lego/tools/interface/#manage-a-print-via-zcviewtext","title":"Manage a print via zCViewText","text":"

It is also possible to create the text only via Print_CreateText and set it yourself. In this example, a text should fly over the image from left to right and be deleted again. The movement is handled by Anim8:

var int MyText;\nvar int MyAnim8;\nfunc void PrintMyScrollingText(var string text) {\n    MyText = Print_CreateText(text, FONT_Screen); // We create an empty text item with the font FONT_Screen\n\n    var zCViewText MyTextObject; MyTextObject = Print_GetText(MyText); // Now we get the empty text item in a zCViewText\n\n    MyTextObject.posx = 1;      // adjust position\n    MyTextObject.posy = 1;      // ATTENTION: These values are virtual, i.e.: 0 = far left, 8192 = far right (i.e. no pixel specification)\n                                // (But if I prefer to have pixel coordinates I could use e.g. Print_ToVirtual)\n    MyTextObject.timed = false; // The text should not be timed (not disappear)\n\n    // Anim8 will animate a text\n    // First we need a new Anim8 object:\n    MyAnim8 = Anim8_New(1, false); // Start position is 1 and this value is not a float\n\n    Anim8(MyAnim8, 8192, 2000, A8_Constant); // Target Position is 8192, Duration is 2000 milliseconds, and Movement Form is Constant\n\n    // Now all we need is a loop that matches the x value of the text to the value of Anim8:\n    FF_Apply(ScrollMyText);\n};\n\nfunc void ScrollMyText() {\n    var zCViewText MyTextObject; MyTextObject = Print_GetText(MyText); // Get the text as an object again\n\n    // And now compare the values:\n    MyTextObject.posx = Anim8_Get(MyAnim8);\n\n    // When Anim8 is done with that, we end the loop and delete the text:\n    if(Anim8_Empty(MyAnim8)) {\n        Print_DeleteText(MyText);\n        FF_Remove(ScrollMyText);\n        // The Anim8 object must of course also be deleted. We don't need it anymore.\n        Anim8_Delete(MyAnim8);\n    };\n};\n
"},{"location":"zengin/scripts/extenders/lego/tools/interface/#manage-a-print-via-zcviewtext-with-lego-22","title":"Manage a print via zCViewText with LeGo 2.2+","text":"

In those days it was perhaps pleasant, but today it is no longer. Anim8 has seen a few improvements with LeGo 2.2 that make it much easier to create the same effect:

var int MyText;\nvar int MyAnim8;\nfunc void PrintMyScrollingText(var string text) {\n    // Create and set text:\n    MyText = Print_CreateText(text, FONT_Screen);\n\n    var zCViewText MyTextObject; MyTextObject = Print_GetText(MyText);\n\n    MyTextObject.posx = 1;\n    MyTextObject.posy = 1;\n\n    MyTextObject.timed = false;\n\n    // But now comes the trick: We use Anim8_NewExt, this allows us to set a \"Handler\" and \"Data\".\n    MyAnim8 = Anim8_NewExt(1, ScrollMyText, MyText, false);\n\n    // ScrollMyText is passed as the handler and MyText as the data.\n    // In concrete terms, this means: ScrollMyText is always called\n    // when Anim8 has recalculated the position.\n    // Pass data and the new position as parameters. Let's see how it goes.\n\n    // Set the animation again as usual:\n    Anim8(MyAnim8, 8192, 2000, A8_Constant);\n\n    // And this time no FrameFunction.\n    // Instead, we tell Anim8 to clean up by itself when it's done:\n    Anim8_RemoveIfEmpty(MyAnim8, true);\n\n    // The text should also disappear by itself:\n    Anim8_RemoveDataIfEmpty(MyAnim8, true);\n\n    // Since MyText is a handle, this will work.\n    // If MyText were a pointer, RemoveDataIfEmpty should not be activated, it would lead to an error message.\n};\n\nfunc void ScrollMyText(var int MyText, var int Position) {\n     // Get the text as an object again\n    var zCViewText MyTextObject; MyTextObject = Print_GetText(MyText);\n\n    // And now compare the values:\n    MyTextObject.posx = Position;\n\n    // Since Anim8 does the deleting itself, we don't have to worry about that.\n};\n
"},{"location":"zengin/scripts/extenders/lego/tools/item_helper/","title":"ItemHelper","text":""},{"location":"zengin/scripts/extenders/lego/tools/item_helper/#itemhelper","title":"ItemHelper","text":"

This package is very simple - it retrieves a oCItem pointer from an C_ITEM instance valid for the current world and session.

Warning

Make sure every world has waypoint with name TOT (\"dead\" in German). Ikarus & LeGo need this waypoint to spawn helper NPCs. This is especially important in Gothic 1 since G1 vanilla worlds do not have the TOT waypoint.

"},{"location":"zengin/scripts/extenders/lego/tools/item_helper/#dependencies","title":"Dependencies","text":"

N/A

"},{"location":"zengin/scripts/extenders/lego/tools/item_helper/#initialization","title":"Initialization","text":"

N/A

"},{"location":"zengin/scripts/extenders/lego/tools/item_helper/#implementation","title":"Implementation","text":"

ItemHelper.d on GitHub

"},{"location":"zengin/scripts/extenders/lego/tools/item_helper/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/tools/item_helper/#itm_getptr","title":"Itm_GetPtr","text":"
func int Itm_GetPtr(var int instance)\n
Parameters
  • var int instance C_ITEM instance to get the pointer of

Return value The function returns oCItem pointer of the C_ITEM instance.

"},{"location":"zengin/scripts/extenders/lego/tools/list/","title":"List","text":""},{"location":"zengin/scripts/extenders/lego/tools/list/#list","title":"List","text":"

The List package is a collection of functions designed to simplify the handling of zCList and zCListSort lists in daedalus. It offers a range of functions for creating, manipulating, and querying lists.

"},{"location":"zengin/scripts/extenders/lego/tools/list/#dependencies","title":"Dependencies","text":"

N/A

"},{"location":"zengin/scripts/extenders/lego/tools/list/#initialization","title":"Initialization","text":"

N/A

"},{"location":"zengin/scripts/extenders/lego/tools/list/#implementation","title":"Implementation","text":"

List.d on GitHub

"},{"location":"zengin/scripts/extenders/lego/tools/list/#functions","title":"Functions","text":"

Note

All functions, expect List_Compare come with an additional \"S\" at the end for objects of type zCListSort. (Example: List_NodeS .) Unlike most LeGo packages, pointers are used here, not handles!

"},{"location":"zengin/scripts/extenders/lego/tools/list/#list_create","title":"List_Create","text":"

Creates a list with an initial value.

func int List_Create(var int data)\n
Parameters
  • var int data The value of the first list element.

Return value

The function returns a pointer to the created list.

"},{"location":"zengin/scripts/extenders/lego/tools/list/#list_add","title":"List_Add","text":"

Appends a value to the end of the list.

func void List_Add(var int list, var int data)\n
Parameters
  • var int list The list to be used.
  • var int data The value to be appended.
"},{"location":"zengin/scripts/extenders/lego/tools/list/#list_addfront","title":"List_AddFront","text":"

Adds a value before the first element of the list.

func void List_AddFront(var int list, var int data)\n
Parameters
  • var int list The list to be used.
  • var int data The value to be appended.
"},{"location":"zengin/scripts/extenders/lego/tools/list/#list_addoffset","title":"List_AddOffset","text":"

Inserts a value between two list elements.

func void List_AddOffset(var int list, var int offset, var int data)\n
Parameters
  • var int list The list to be used.
  • var int offset The number of the list element after which the value is inserted.
  • var int data The value to be appended.
"},{"location":"zengin/scripts/extenders/lego/tools/list/#list_set","title":"List_Set","text":"

Sets a list element to a specific value.

func void List_Set(var int node, var int data)\n
Parameters
  • var int node Pointer to a list element.
  • var int data The value to be written into the list element.
"},{"location":"zengin/scripts/extenders/lego/tools/list/#list_get","title":"List_Get","text":"

Retrieves the value of a list element.

func int List_Get(var int list, var int nr)\n
Parameters
  • var int list The list to be used.
  • var int nr The number of the list element.

Return value

The function returns the value of the specified list element.

"},{"location":"zengin/scripts/extenders/lego/tools/list/#list_node","title":"List_Node","text":"

Returns a pointer to a list element.

func int List_Node(var int list, var int nr)\n
Parameters
  • var int list The list to be used.
  • var int nr The number of a list element.

Return value

The function returns a pointer to the specified list element.

"},{"location":"zengin/scripts/extenders/lego/tools/list/#list_length","title":"List_Length","text":"

Returns the length of the list (number of all elements).

func int List_Length(var int list)\n
Parameters
  • var int list The list to be used.

Return value

The function returns the number of elements in the list.

"},{"location":"zengin/scripts/extenders/lego/tools/list/#list_haslength","title":"List_HasLength","text":"

Checks if the list has the specified length.

func int List_HasLength(var int list, var int length)\n
Parameters
  • var int list The list to be used.
  • var int length The desired length.

Return value

The function returns a boolean value indicating whether the list has the specified length or not.

"},{"location":"zengin/scripts/extenders/lego/tools/list/#list_end","title":"List_End","text":"

Returns the last list element of the list.

func int List_End(var int list)\n
Parameters
  • var int list The list to be used.

Return value

The function returns a pointer to the last list element.

"},{"location":"zengin/scripts/extenders/lego/tools/list/#list_concat","title":"List_Concat","text":"

Concatenates two lists.

func void List_Concat(var int list, var int list2)\n
Parameters
  • var int list The first list.
  • var int list2 The second list. Its beginning is appended to the end of the first list.
"},{"location":"zengin/scripts/extenders/lego/tools/list/#list_contains","title":"List_Contains","text":"

Returns the last list element with a specific value.

func int List_Contains(var int list, var int data)\n
Parameters
  • var int list The list to be used.
  • var int data The value to search for.

Return value

The function returns the number of the last list element with the value data.

"},{"location":"zengin/scripts/extenders/lego/tools/list/#list_for","title":"List_For","text":"

Calls a function for each list element, passing a pointer to the list element as a parameter.

func void List_For(var int list, var string function)\n
Parameters
  • var int list The list to be used.
  • var string function Name of a function to be called for each list element (void handler(var int node)).
"},{"location":"zengin/scripts/extenders/lego/tools/list/#list_forf","title":"List_ForF","text":"

Similar to List_For, but with a function parameter instead of a string.

func void ListForF(var int list, var func function)\n
Parameters
  • var int list The list to be used.
  • var func function The function to be called for each list element (void handler(var int node)).
"},{"location":"zengin/scripts/extenders/lego/tools/list/#list_fori","title":"List_ForI","text":"

Similar to List_For, but with a function parameter instead of a string.

func void List_ForI(var int list, var int funcID)\n
Parameters
  • var int list The list to be used.
  • var int funcID ID of a function to be called for each list element (void handler(var int node)).
"},{"location":"zengin/scripts/extenders/lego/tools/list/#list_delete","title":"List_Delete","text":"

Deletes a list element. All subsequent elements shift position.

func void List_Delete(var int list, var int nr)\n
Parameters
  • var int list The list to be used.
  • var int nr The number of the list element to be deleted.
"},{"location":"zengin/scripts/extenders/lego/tools/list/#list_destroy","title":"List_Destroy","text":"

Destroys the entire list.

func void List_Destroy(var int list)\n
Parameters
  • var int list The list to be destroyed.
"},{"location":"zengin/scripts/extenders/lego/tools/list/#list_toarray","title":"List_ToArray","text":"

Returns a pointer to a memory area containing all values of the list.

func int List_ToArray(var int list)\n
Parameters
  • var int list The list to be used.

Return value

The function returns a memory area containing all the values of the list.

"},{"location":"zengin/scripts/extenders/lego/tools/list/#list_movedown","title":"List_MoveDown","text":"

Moves the specified list node down by one position in the list.

func void List_MoveDown(var int list, var int node)\n
Parameters
  • var int list The list in which the node is located.
  • var int node The node to be moved down.
"},{"location":"zengin/scripts/extenders/lego/tools/list/#list_moveup","title":"List_MoveUp","text":"

Moves the specified list node up by one position in the list.

func void List_MoveUp(var int list, var int node)\n
Parameters
  • var int list The list in which the node is located.
  • var int node The node to be moved up.
"},{"location":"zengin/scripts/extenders/lego/tools/list/#list_insertsorted","title":"List_InsertSorted","text":"

Inserts a value into a sorted list while preserving the sort order.

func void List_InsertSorted(var int list, var int data, var func compare)\n
Parameters:
  • var int list The list to insert the value into.
  • var int data The value to be inserted.
  • var func compare A comparison function used to determine the sort order.
"},{"location":"zengin/scripts/extenders/lego/tools/list/#list_compare","title":"List_Compare","text":"
func int List_Compare(var int data1, var int data2, var func compare)\n
Parameters:
  • var int data1 The first integer value.
  • var int data2 The second integer value.
  • var func compare One of comparison functions. Return value

The function returns the return value of specified comparison function.

"},{"location":"zengin/scripts/extenders/lego/tools/list/#comparison-functions","title":"Comparison Functions","text":"

The following comparison functions can be used as the compare parameter in the List_InsertSorted and List_Compare function:

"},{"location":"zengin/scripts/extenders/lego/tools/list/#list_cmpascending","title":"List_CmpAscending","text":"

Compares two integer values in ascending order.

func int List_CmpAscending(var int data1, var int data2)\n
Parameters:
  • var int data1 The first integer value.
  • var int data2 The second integer value.

Return Value:

The function returns TRUE if data1 is greater than data2, FALSE is returned otherwise.

"},{"location":"zengin/scripts/extenders/lego/tools/list/#list_cmpdescending","title":"List_CmpDescending","text":"

Compares two integer values in descending order.

func int List_CmpDescending(var int data1, var int data2)\n
Parameters:
  • var int data1 The first integer value.
  • var int data2 The second integer value.

Return Value:

The function returns TRUE if data1 is less than data2, FALSE is returned otherwise.

"},{"location":"zengin/scripts/extenders/lego/tools/list/#list_cmpascendingunsigned","title":"List_CmpAscendingUnsigned","text":"

Compares two unsigned integer values in ascending order.

func int List_CmpAscendingUnsigned(var int data1, var int data2)\n
Parameters:
  • var int data1 The first unsigned integer value.
  • var int data2 The second unsigned integer value.

Return Value:

The function returns TRUE if data1 is greater than data2, FALSE is returned otherwise.

"},{"location":"zengin/scripts/extenders/lego/tools/list/#list_cmpdescendingunsigned","title":"List_CmpDescendingUnsigned","text":"

Compares two unsigned integer values in descending order.

func int List_CmpDescendingUnsigned(var int data1, var int data2)\n
Parameters:
  • var int data1 The first unsigned integer value.
  • var int data2 The second unsigned integer value.

Return Value:

The function returns TRUE if data1 is less than data2, FALSE is returned otherwise.

"},{"location":"zengin/scripts/extenders/lego/tools/locals/","title":"Locals","text":""},{"location":"zengin/scripts/extenders/lego/tools/locals/#locals","title":"Locals","text":"

Daedalus doesn't offer any local variables, which can quickly lead to problems with recursive functions. The Locals package allows variables to be saved temporarily on a pseudo-stack. Locals is a very specific package. People who work normally with Daedalus will probably never need it. There is also the final function, which can be used to emulate something similar to the final clause in Java.

"},{"location":"zengin/scripts/extenders/lego/tools/locals/#dependencies","title":"Dependencies","text":"
  • StringBuilder
"},{"location":"zengin/scripts/extenders/lego/tools/locals/#initialization","title":"Initialization","text":"

N/A

"},{"location":"zengin/scripts/extenders/lego/tools/locals/#implementation","title":"Implementation","text":"

Locals.d on GitHub

"},{"location":"zengin/scripts/extenders/lego/tools/locals/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/tools/locals/#locals_1","title":"Locals","text":"

All that has to be done to enable the Locals is to write this function at the beginning of the function that should receive \"real\" local variables.

func void locals()\n
"},{"location":"zengin/scripts/extenders/lego/tools/locals/#final","title":"Final","text":"

It is hard to explain how to use it, but very easy to understand once you've seen an example.

func int Final()\n
Example

With final() it is very easy to emulate Java's final clause, i.e. a block of code can be specified, which is executed after this function is exited, regardless of when or where the function is exited.

func void testFinal()\n{\n    if (final())\n    {\n        MEM_InfoBox(\"Final was called.\");\n    };\n    MEM_InfoBox(\"This will appear before Final\");\n};\n
Few lines of code say more than a thousand words."},{"location":"zengin/scripts/extenders/lego/tools/misc/","title":"Misc","text":""},{"location":"zengin/scripts/extenders/lego/tools/misc/#misc","title":"Misc","text":"

The Misc package introduces various helper functions that did not fit into any other package.

"},{"location":"zengin/scripts/extenders/lego/tools/misc/#dependencies","title":"Dependencies","text":"
  • Floats
"},{"location":"zengin/scripts/extenders/lego/tools/misc/#initialization","title":"Initialization","text":"

N/A

"},{"location":"zengin/scripts/extenders/lego/tools/misc/#implementation","title":"Implementation","text":"

Misc.d on GitHub

"},{"location":"zengin/scripts/extenders/lego/tools/misc/#constants","title":"Constants","text":"

Misc package implements the phi constant

const int phi = 1070141312; // PI/2\n
which is actually pi divided by 2 saved as an ikarus float.

Decimal: 1.5707...

"},{"location":"zengin/scripts/extenders/lego/tools/misc/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/tools/misc/#atan2f","title":"atan2f","text":"

Calculates the arcus tangent of an angle between the origin and (x, y) point.

func int atan2f(var int x, var int y)\n
Parameters
  • var int x X-coordinate
  • var int y Y-coordinate

Return value

The function returns arcus tangent in radians as Ikarus float.

"},{"location":"zengin/scripts/extenders/lego/tools/misc/#sin","title":"sin","text":"

Calculates the sine of an angle given in radians.

func int sin(var int angle)\n
Parameters
  • var int angle The angle in radians as a Ikarus float

Return value

The function returns sine of the angle as Ikarus float.

"},{"location":"zengin/scripts/extenders/lego/tools/misc/#cos","title":"cos","text":"

Calculates the cosine of an angle given in radians.

func int cos(var int angle)\n
Parameters
  • var int angle The angle in radians as a Ikarus float

Return value

The function returns cosine of the angle as Ikarus float.

"},{"location":"zengin/scripts/extenders/lego/tools/misc/#tan","title":"tan","text":"

Calculates the tangent of an angle given in radians.

func int tan(var int angle)\n
Parameters
  • var int angle The angle in radians as a Ikarus float

Return value

The function returns tangent of the angle as Ikarus float.

"},{"location":"zengin/scripts/extenders/lego/tools/misc/#asin","title":"asin","text":"

Calculates the arcus sine.

func int asin(var int sine)\n
Parameters
  • var int sine The sine of an angle as a Ikarus float

Return value

The function returns arcus sine of the angle as Ikarus float.

"},{"location":"zengin/scripts/extenders/lego/tools/misc/#acos","title":"acos","text":"

Calculates the arcus cosine

func int acos(var int cosine)\n
Parameters
  • var int cosine The cosine of an angle as a Ikarus float

Return value

The function returns arcus cosine of the angle as Ikarus float.

"},{"location":"zengin/scripts/extenders/lego/tools/misc/#distance2d","title":"distance2D","text":"

Calculates the distance between two points on a two-dimensional plane.

func int distance2D(var int x1, var int x2, var int y1, var int y2)\n
Parameters
  • var int x1 X-coordinate of the first point
  • var int x2 X-coordinate of the second point
  • var int y1 Y-coordinate of the first point
  • var int y2 Y-coordinate of the second point

Return value

The function returns the distance between the two points.

"},{"location":"zengin/scripts/extenders/lego/tools/misc/#distance2df","title":"distance2Df","text":"

Calculates the distance between two points on a two-dimensional plane but parameters and return values are Ikarus floats.

func int distance2Df(var int x1, var int x2, var int y1, var int y2)\n
Parameters
  • var int x1 X-coordinate of the first point
  • var int x2 X-coordinate of the second point
  • var int y1 Y-coordinate of the first point
  • var int y2 Y-coordinate of the second point

Return value

The function returns the distance between the two points as Ikarus float.

"},{"location":"zengin/scripts/extenders/lego/tools/permmem/","title":"PermMem","text":""},{"location":"zengin/scripts/extenders/lego/tools/permmem/#permmem","title":"PermMem","text":"

PermMem is a powerful package that allows classes (or instances) to be used permanently even after loading or restarting by saving them to the ASCII .ZEN archive in the savegame directory. PermMem manages handles that are used to access instances, and provides various functions to manipulate these handles and instances.

"},{"location":"zengin/scripts/extenders/lego/tools/permmem/#dependencies","title":"Dependencies","text":"
  • Saves
  • Locals
"},{"location":"zengin/scripts/extenders/lego/tools/permmem/#initialization","title":"Initialization","text":"

Initialize with LeGo_PermMem flag.

LeGo_Init(LeGo_PermMem);\n
"},{"location":"zengin/scripts/extenders/lego/tools/permmem/#implementation","title":"Implementation","text":"

PermMem.d on GitHub

"},{"location":"zengin/scripts/extenders/lego/tools/permmem/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/tools/permmem/#new","title":"new","text":"

Creates a handle to a new instance of inst.

func int new(var int inst)\n
Parameters
  • var int inst A valid instance. Used as \"constructor\"

Return value

The function returns a new, valid PermMem handle.

"},{"location":"zengin/scripts/extenders/lego/tools/permmem/#create","title":"create","text":"

Similar to new, but here a pointer is returned directly and not a handle. Caution! Not managed by PermMem!

func int create(var int inst)\n
Parameters
  • var int inst A valid instance. Used as \"constructor\"

Return value

The function returns a pointer to the new instance.

"},{"location":"zengin/scripts/extenders/lego/tools/permmem/#wrap","title":"wrap","text":"

\"Wraps\" a handle \"around\" a pointer so that the pointer can be used with any function that expects handles. Only conditionally managed by PermMem.

func int wrap(var int inst, var int ptr)\n
Parameters
  • var int inst A valid instance. Determines the type of the handle
  • var int ptr Pointer to wrap

Return value

The function returns a handle with ptr as content.

"},{"location":"zengin/scripts/extenders/lego/tools/permmem/#clear","title":"clear","text":"

Cleans the handle. After that it is invalid.

func void clear(var int hndl)\n
Parameters
  • var int hndl Valid PermMem handle
"},{"location":"zengin/scripts/extenders/lego/tools/permmem/#release","title":"release","text":"

Frees the handle. The reserved memory is not deleted, the handle becomes invalid.

func void release(var int hndl)\n
Parameters
  • var int hndl Valid PermMem handle
"},{"location":"zengin/scripts/extenders/lego/tools/permmem/#delete","title":"delete","text":"

Cleans the handle just like clear, only the destructor is also called.

func void delete(var int hndl)\n
Parameters
  • var int hndl Valid PermMem handle
"},{"location":"zengin/scripts/extenders/lego/tools/permmem/#free","title":"free","text":"

Similar to delete, only here a pointer is destroyed and not a handle. Caution! Not managed by PermMem!

func void free(var int ptr, var int inst)\n
Parameters
  • var int ptr The pointer to be cleaned
  • var int inst Instance used in create function.
"},{"location":"zengin/scripts/extenders/lego/tools/permmem/#get","title":"get","text":"

Returns the instance of the handle.

func instance get(var int hndl)\n
Parameters
  • var int hndl Valid PermMem handle
"},{"location":"zengin/scripts/extenders/lego/tools/permmem/#getptr","title":"getPtr","text":"

Returns a pointer to instance of handle.

func int getPtr(var int hndl)\n
Parameters
  • var int hndl Valid PermMem handle
"},{"location":"zengin/scripts/extenders/lego/tools/permmem/#setptr","title":"setPtr","text":"

Sets the pointer of a handle.

func void setPtr(var int hndl, var int ptr)\n
Parameters
  • var int hndl Valid PermMem handle
  • var int ptr New pointer for handle
"},{"location":"zengin/scripts/extenders/lego/tools/permmem/#getinst","title":"getInst","text":"

Returns the instance used to create the given handle in new function.

func int getInst(var int hndl)\n
Parameters
  • var int hndl Valid PermMem handle
"},{"location":"zengin/scripts/extenders/lego/tools/permmem/#numhandles","title":"numHandles","text":"

Returns the number of handles managed by PermMem.

func int numHandles()\n
"},{"location":"zengin/scripts/extenders/lego/tools/permmem/#sizeof","title":"sizeof","text":"

Gets the size of the given instance's class.

func int sizeof(var int inst)\n
Parameters
  • var int inst Any instance

Return value

The function returns the size of a given instance's class in bytes.

"},{"location":"zengin/scripts/extenders/lego/tools/permmem/#hlp_isvalidhandle","title":"Hlp_IsValidHandle","text":"

Indicates whether the handle exists and is managed by PermMem.

func int Hlp_IsValidHandle(var int hndl)\n
Parameters
  • var int hndl PermMem's handle

Return value

The function returns TRUE if the handle is valid (managed by PermMem), FALSE is returned otherwise.

Example

The example function that use Hlp_IsValidHandle is Bar_SetMax form LeGo Bars package. The function first checks if the handle is valid, then gets the instance and changes its parameters.

func void Bar_SetMax(var int bar, var int max) \n{\n    if(!Hlp_IsValidHandle(bar)) { return; };\n    var _bar b; b = get(bar);\n    b.valMax = max;\n};\n
"},{"location":"zengin/scripts/extenders/lego/tools/permmem/#foreachhndl","title":"foreachHndl","text":"

Executes a function for each handle of an instance.

func void foreachHndl(var int inst, var func fnc)\n
Parameters
  • var int inst The function is called for this instance
  • var int inst This function is called. The signature is function(int handle)
"},{"location":"zengin/scripts/extenders/lego/tools/permmem/#hashndl","title":"hasHndl","text":"

Checks if PermMem has a handle of this instance.

func int hasHndl(var int inst)\n
Parameters
  • var int inst Instance to be checked

Return value

The function returns TRUE if the PermMem has a handle of this instance, FALSE is returned otherwise.

"},{"location":"zengin/scripts/extenders/lego/tools/permmem/#mem_readstringarray","title":"MEM_ReadStringArray","text":"

Function moved to PermMem form Ikarus. Reads string from the array at the arrayAddress.

func string MEM_ReadStringArray(var int arrayAddress, var int index)\n
Parameters
  • var int arrayAddress Memory address of array
  • var int offset Array offset (array index)

Return value

The function returns string from the array if the address is correct.

"},{"location":"zengin/scripts/extenders/lego/tools/permmem/#pm_exists","title":"PM_Exists","text":"

Checks if the specified field already exists in the archive. (used with archiver/unarchiver)

func int PM_Exists(var string name)\n
Parameters
  • var string name Name of the field

Return value

The function returns TRUE if the field exists in the archive, FALSE is returned otherwise.

"},{"location":"zengin/scripts/extenders/lego/tools/permmem/#archiver","title":"Archiver","text":""},{"location":"zengin/scripts/extenders/lego/tools/permmem/#pm_saveint","title":"PM_SaveInt","text":"

Saves an integer to the archive.

func void PM_SaveInt (var string name, var int val)\n
Parameters
  • var string name Name of the field in saved archive
  • var int val Value of the saved integer
"},{"location":"zengin/scripts/extenders/lego/tools/permmem/#pm_savefloat","title":"PM_SaveFloat","text":"

Saves a daedalus float to the archive.

func void PM_SaveFloat (var string name, var int flt)\n
Parameters
  • var string name Name of the field in saved archive
  • var int flt Value of the saved float
"},{"location":"zengin/scripts/extenders/lego/tools/permmem/#pm_savestring","title":"PM_SaveString","text":"

Saves a string to the archive.

func void PM_SaveString (var string name, var string val)\n
Parameters
  • var string name Name of the field in saved archive
  • var string val Saved string
"},{"location":"zengin/scripts/extenders/lego/tools/permmem/#pm_savefuncid","title":"PM_SaveFuncID","text":"

Saves a function ID to the archive.

func void PM_SaveFuncID(var string name, var int fnc)\n
Parameters
  • var string name Name of the field in saved archive
  • var int fnc Saved function ID
"},{"location":"zengin/scripts/extenders/lego/tools/permmem/#pm_savefuncoffset","title":"PM_SaveFuncOffset","text":"

Saves a function offset to the archive.

func void PM_SaveFuncOffset(var string name, var int fnc)\n
Parameters
  • var string name Name of the field in saved archive
  • var int fnc Saved function offset
"},{"location":"zengin/scripts/extenders/lego/tools/permmem/#pm_savefuncptr","title":"PM_SaveFuncPtr","text":"

Saves a function pointer to the archive.

func void PM_SaveFuncPtr(var string name, var int fnc)\n
Parameters
  • var string name Name of the field in saved archive
  • var int fnc Saved function pointer
"},{"location":"zengin/scripts/extenders/lego/tools/permmem/#pm_saveclassptr","title":"PM_SaveClassPtr","text":"

Saves a pointer of a class to the archive.

func void PM_SaveClassPtr(var string name, var int ptr, var string className)\n
Parameters
  • var string name Name of the field in saved archive
  • var int ptr Saved pointer
  • var string className Name of the class of stored pointer
"},{"location":"zengin/scripts/extenders/lego/tools/permmem/#pm_saveclass","title":"PM_SaveClass","text":"

Saves a class like PM_SaveClassPtr.

func void PM_SaveClass(var string name, var int ptr, var string className)\n
Parameters
  • var string name Name of the field in saved archive
  • var int ptr Saved class pointer
  • var string className Name of the class of stored pointer
"},{"location":"zengin/scripts/extenders/lego/tools/permmem/#pm_saveintarray","title":"PM_SaveIntArray","text":"

Saves an array of integers.

func void PM_SaveIntArray(var string name, var int ptr, var int elements)\n
Parameters
  • var string name Name of the field in saved archive
  • var int ptr Pointer to the array
  • var int elements Number of elements in array
"},{"location":"zengin/scripts/extenders/lego/tools/permmem/#pm_savestringarray","title":"PM_SaveStringArray","text":"

Saves an array of integers.

func void PM_SaveStringArray(var string name, var int ptr, var int elements)\n
Parameters
  • var string name Name of the field in saved archive
  • var int ptr Pointer to the array
  • var int elements Number of elements in array
"},{"location":"zengin/scripts/extenders/lego/tools/permmem/#unarchiver","title":"Unarchiver","text":""},{"location":"zengin/scripts/extenders/lego/tools/permmem/#pm_load","title":"PM_Load","text":"

Universal function to load integers, floats, class pointers and int arrays.

func int PM_Load(var string name)\n
Parameters
  • var string name Name of the loaded field

Return value The function returns the data existing in the archive at the given field.

"},{"location":"zengin/scripts/extenders/lego/tools/permmem/#pm_loadint","title":"PM_LoadInt","text":"

Returns an integer stored in the archive.

func int PM_LoadInt(var string name)\n
Parameters
  • var string name Name of the loaded field
"},{"location":"zengin/scripts/extenders/lego/tools/permmem/#pm_loadfloat","title":"PM_LoadFloat","text":"

Returns a daedalus float stored in the archive.

func int PM_LoadFloat(var string name)\n
Parameters
  • var string name Name of the loaded field
"},{"location":"zengin/scripts/extenders/lego/tools/permmem/#pm_loadstring","title":"PM_LoadString","text":"

Returns a string stored in the archive.

func string PM_LoadString(var string name)\n
Parameters
  • var string name Name of the loaded field
"},{"location":"zengin/scripts/extenders/lego/tools/permmem/#pm_loadfuncid","title":"PM_LoadFuncID","text":"

Returns a function ID stored in the archive.

func int PM_LoadFuncID(var string name)\n
Parameters
  • var string name Name of the loaded field
"},{"location":"zengin/scripts/extenders/lego/tools/permmem/#pm_loadfuncoffset","title":"PM_LoadFuncOffset","text":"

Returns a function offset stored in the archive.

func int PM_LoadFuncOffset(var string name)\n
Parameters
  • var string name Name of the loaded field
"},{"location":"zengin/scripts/extenders/lego/tools/permmem/#pm_loadfuncptr","title":"PM_LoadFuncPtr","text":"

Returns a function pointer stored in the archive.

func int PM_LoadFuncPtr(var string name)\n
Parameters
  • var string name Name of the loaded field
"},{"location":"zengin/scripts/extenders/lego/tools/permmem/#pm_loadclassptr","title":"PM_LoadClassPtr","text":"

Returns a class pointer stored in the archive.

func int PM_LoadClassPtr(var string name)\n
Parameters
  • var string name Name of the loaded field
"},{"location":"zengin/scripts/extenders/lego/tools/permmem/#pm_loadclass","title":"PM_LoadClass","text":"

Loads a pointer to the class from the archive to destPtr.

func void PM_LoadClass(var string name, var int destPtr)\n
Parameters
  • var string name Name of the loaded field
  • var int destPtr Destination pointer, the address to where it will deserialize the saved data
"},{"location":"zengin/scripts/extenders/lego/tools/permmem/#pm_loadarray","title":"PM_LoadArray","text":"

Returns a pointer to array stored in the archive.

func int PM_LoadArray(var string name)\n
Parameters
  • var string name Name of the loaded field
"},{"location":"zengin/scripts/extenders/lego/tools/permmem/#pm_loadarraytoptr","title":"PM_LoadArrayToPtr","text":"

Loads a pointer to array from the archive to destPtr.

func void PM_LoadArrayToPtr(var string name, var int destPtr)\n
Parameters
  • var string name Name of the loaded field
  • var int destPtr Destination pointer, the address to where it will deserialize the saved data
"},{"location":"zengin/scripts/extenders/lego/tools/permmem/#pm_loadtoptr","title":"PM_LoadToPtr","text":"

Universal function to load array or class pointer from the archive to destPtr.

func void PM_LoadToPtr(var string name, var int destPtr)\n
Parameters
  • var string name Name of the loaded field
  • var int destPtr Destination pointer, the address to where it will deserialize the saved data
"},{"location":"zengin/scripts/extenders/lego/tools/queue/","title":"Queue","text":""},{"location":"zengin/scripts/extenders/lego/tools/queue/#queue","title":"Queue","text":"

This package is an implementation of the Queue data structure and a queue for function calls.

"},{"location":"zengin/scripts/extenders/lego/tools/queue/#dependencies","title":"Dependencies","text":"
  • PermMem
"},{"location":"zengin/scripts/extenders/lego/tools/queue/#initialization","title":"Initialization","text":"

N/A

"},{"location":"zengin/scripts/extenders/lego/tools/queue/#implementation","title":"Implementation","text":"

Queue.d on GitHub

"},{"location":"zengin/scripts/extenders/lego/tools/queue/#queue_1","title":"Queue","text":""},{"location":"zengin/scripts/extenders/lego/tools/queue/#q_create","title":"Q_Create","text":"

Creates a new queue and returns a handle to it.

func int Q_Create()\n
Return value

The function returns a handle to a queue.

"},{"location":"zengin/scripts/extenders/lego/tools/queue/#q_enqueue","title":"Q_Enqueue","text":"

Appends an integer to the back of the queue

func void Q_Enqueue(var int queue, var int value)\n
Parameters
  • var int queue Handle of a queue
  • var int value The value to be appended to the queue
"},{"location":"zengin/scripts/extenders/lego/tools/queue/#q_isempty","title":"Q_IsEmpty","text":"

Checks if the queue is empty.

func int Q_IsEmpty(var int queue)\n
Parameters
  • var int queue Handle of a queue

Return value

The function returns TRUE if the queue is empty, FALSE is returned otherwise.

"},{"location":"zengin/scripts/extenders/lego/tools/queue/#q_advance","title":"Q_Advance","text":"

Removes the oldest value from the queue and returns it.

func int Q_Advance(var int queue)\n
Parameters
  • var int queue Handle of a queue

Return value

The function returns the oldest value in the queue.

"},{"location":"zengin/scripts/extenders/lego/tools/queue/#q_peek","title":"Q_Peek","text":"

Returns the oldest value in the queue without removing it.

func int Q_Peek(var int queue)\n
Parameters
  • var int queue Handle of a queue

Return value

The function returns the oldest value in the queue.

"},{"location":"zengin/scripts/extenders/lego/tools/queue/#q_for","title":"Q_For","text":"

Function with the funcID is called with every element of the list as parameter. The list element is passed to the function as a zCList pointer.

func void Q_For(var int queue, var int funcID)\n
Parameters
  • var int queue Handle of a queue
  • var int funcID ID of function that is executed for all values in the queue (signature: void (zCList*))
"},{"location":"zengin/scripts/extenders/lego/tools/queue/#q_forf","title":"Q_ForF","text":"

Like Q_For, but with function as a parameter instead of a function ID.

func void Q_ForF(var int queue, var func f)\n
Parameters
  • var int queue Handle of a queue
  • var func f This function is executed for all values in the queue (signature: void (zCList*))
"},{"location":"zengin/scripts/extenders/lego/tools/queue/#callbackqueue","title":"CallbackQueue","text":""},{"location":"zengin/scripts/extenders/lego/tools/queue/#cq_create","title":"CQ_Create","text":"

Creates a new callback queue and returns a handle to it.

func int CQ_Create()\n
Return value

The function returns a handle to a callback queue.

"},{"location":"zengin/scripts/extenders/lego/tools/queue/#cq_enqueuenodata","title":"CQ_EnqueueNoData","text":"

Appends a function to the callback queue.

func void CQ_EnqueueNoData(var int queue, var func function)\n
Parameters
  • var int queue Handle of a callback queue
  • var func function A function with no return value, expecting no parameter
"},{"location":"zengin/scripts/extenders/lego/tools/queue/#cq_enqueuedata","title":"CQ_EnqueueData","text":"

Appends a function together with a value to the callback queue.

func void CQ_EnqueueData(var int queue, var func function, var int data)\n
Parameters
  • var int queue Handle of a callback queue
  • var func function A function with no return value, expecting an integer as a parameter.
  • var int data When calling function, this value is passed as a parameter
"},{"location":"zengin/scripts/extenders/lego/tools/queue/#cq_enqueue","title":"CQ_Enqueue","text":"

Appends a function together with an optional value to the callback queue. This function should not usually be used. Use CQ_EnqueueData and CQ_EnqueueNoData instead.

func void CQ_Enqueue(var int queue, var int funcID, var int data, var int hasData)\n
Parameters
  • var int queue Handle of a callback queue
  • var int funcID The function ID of a function to be appended to the callback queue.
  • var int data If hasData is not 0, this value is passed to the associated function.
  • var int hasData Must be 0 if the function does not expect an integer as a parameter, otherwise not 0.
"},{"location":"zengin/scripts/extenders/lego/tools/queue/#cq_isempty","title":"CQ_IsEmpty","text":"

Checks if no function is in the callback queue.

func int CQ_IsEmpty(var int queue)\n
Parameters
  • var int queue Handle of a callback queue

Return value

The function returns TRUE if the callback queue is empty, FALSE is returned otherwise.

"},{"location":"zengin/scripts/extenders/lego/tools/queue/#cq_advance","title":"CQ_Advance","text":"

Executes the foremost function of the callback queue and removes it from the callback queue.

func void CQ_Advance(var int queue)\n
Parameters
  • var int queue Handle of a callback queue
"},{"location":"zengin/scripts/extenders/lego/tools/queue/#cq_exhaust","title":"CQ_Exhaust","text":"

Executes all functions contained in the callback queue.

func void CQ_Exhaust(var int queue)\n
Parameters
  • var int queue Handle of a callback queue
"},{"location":"zengin/scripts/extenders/lego/tools/random/","title":"Random","text":""},{"location":"zengin/scripts/extenders/lego/tools/random/#random","title":"Random","text":"

Provides more random randomization than Hlp_Random() function.

"},{"location":"zengin/scripts/extenders/lego/tools/random/#dependencies","title":"Dependencies","text":"

N/A

"},{"location":"zengin/scripts/extenders/lego/tools/random/#initialization","title":"Initialization","text":"

Initialize with LeGo_Random flag.

LeGo_Init(LeGo_Random);\n
"},{"location":"zengin/scripts/extenders/lego/tools/random/#implementation","title":"Implementation","text":"

Random.d on GitHub

"},{"location":"zengin/scripts/extenders/lego/tools/random/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/tools/random/#r_next","title":"r_Next","text":"

Returns a random number.

func int r_Next()\n
Return value

The function returns a random number.

"},{"location":"zengin/scripts/extenders/lego/tools/random/#r_max","title":"r_Max","text":"

Returns a random number from 0 to max.

func int r_Max(var int max)\n
Parameters
  • var int max Maximum value of number

Return value

The function returns a random number from 0 to 'max'.

"},{"location":"zengin/scripts/extenders/lego/tools/random/#r_minmax","title":"r_MinMax","text":"

Returns a random number from 'min' to 'max'.

func int r_MinMax(var int min, var int max)\n
Parameters
  • var int max Maximum value of number
  • var int min Minimum value of number

Return value

The function returns a random number from min to max.

"},{"location":"zengin/scripts/extenders/lego/tools/random/#r_init","title":"r_Init","text":"

Initializes the random number generator. Happens optionally in LeGo_Init.

func void r_Init(var int seed)\n
Parameters
  • var int seed The initializing value
"},{"location":"zengin/scripts/extenders/lego/tools/random/#r_defaultinit","title":"r_DefaultInit","text":"

Initializes the random number generator based on the current time.

func void r_DefaultInit()\n
"},{"location":"zengin/scripts/extenders/lego/tools/string_builder/","title":"StringBuilder","text":""},{"location":"zengin/scripts/extenders/lego/tools/string_builder/#stringbuilder","title":"StringBuilder","text":"

The StringBuilder is a package, designed to easily concatenate multiple elements into a string (without ConcatStrings and IntToString).

All created StringBuilders are transient. All functions starting from SB_InitBuffer, including it, use the active StringBuilder set with SB_New or SB_Use, so there is no var int stringBuilder parameter in functions. A look at the example explains what I mean.

Warning

The StringBuilder works with pointers, not handles like many other LeGo packages.

"},{"location":"zengin/scripts/extenders/lego/tools/string_builder/#dependencies","title":"Dependencies","text":"

N/A

"},{"location":"zengin/scripts/extenders/lego/tools/string_builder/#initialization","title":"Initialization","text":"

N/A

"},{"location":"zengin/scripts/extenders/lego/tools/string_builder/#implementation","title":"Implementation","text":"

StringBuilder.d on GitHub

"},{"location":"zengin/scripts/extenders/lego/tools/string_builder/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/tools/string_builder/#sb_new","title":"SB_New","text":"

Creates and returns a new StringBuilder. At the same time, this new StringBuilder is set as active. (See SB_Use.)

func int SB_New()\n
Return value

The function returns a pointer to a new StringBuilder.

"},{"location":"zengin/scripts/extenders/lego/tools/string_builder/#sb_use","title":"SB_Use","text":"

Marks this StringBuilder as active. It can now be used with the functions.

func void SB_Use(var int sb)\n
Parameters
  • var int sb Pointer to a StringBuilder, returned from SB_New
"},{"location":"zengin/scripts/extenders/lego/tools/string_builder/#sb_get","title":"SB_Get","text":"

Returns the active StringBuilder.

func int SB_Get()\n
Return value

The function returns the active StringBuilder object - last set with SB_Use or just created with SB_New.

"},{"location":"zengin/scripts/extenders/lego/tools/string_builder/#sb_initbuffer","title":"SB_InitBuffer","text":"

If the size of the resulting string is already known, the buffer can be set manually. This is usually not necessary.

func void SB_InitBuffer(var int size)\n
Parameters
  • var int size Size in bytes. Warning! Only works if the StringBuilder has been newly created!
"},{"location":"zengin/scripts/extenders/lego/tools/string_builder/#sb_clear","title":"SB_Clear","text":"

Empties the current StringBuilder. It is not destroyed in the process, so it can be used again. If the object has a buffer allocated, the buffer is freed.

func void SB_Clear()\n
"},{"location":"zengin/scripts/extenders/lego/tools/string_builder/#sb_release","title":"SB_Release","text":"

Releases the current stream of the StringBuilder. The StringBuilder is destroyed, and the stream can be obtained via SB_GetStream.

func void SB_Release()\n
"},{"location":"zengin/scripts/extenders/lego/tools/string_builder/#sb_destroy","title":"SB_Destroy","text":"

Completely destroys the StringBuilder.

func void SB_Destroy()\n
"},{"location":"zengin/scripts/extenders/lego/tools/string_builder/#sb_tostring","title":"SB_ToString","text":"

Returns a copy of the stream as a string.

func string SB_ToString()\n
Return value

The function returns the copy of the active StringBuilder as a string. If the StringBuilder object doesn't have a buffer allocated, an empty string is returned.

"},{"location":"zengin/scripts/extenders/lego/tools/string_builder/#sb_tostream","title":"SB_ToStream","text":"

Returns a copy of the stream in raw format.

func int SB_ToStream()\n
Return value

The function returns a copy of the stream in raw format (char[])

"},{"location":"zengin/scripts/extenders/lego/tools/string_builder/#sb_getstream","title":"SB_GetStream","text":"

Doesn't copy the stream, but returns it as it is.

func int SB_GetStream()\n
Return value

The function returns the stream as it is. SB_Destroy or SB_Clear destroy the returned pointer.

"},{"location":"zengin/scripts/extenders/lego/tools/string_builder/#sb_length","title":"SB_Length","text":"

Returns the current length of the stream. Similar to STR_Len from Ikarus .

func int SB_Length()\n
Return value

The function returns the current length of the active StringBuilder.

"},{"location":"zengin/scripts/extenders/lego/tools/string_builder/#sb_setlength","title":"SB_SetLength","text":"

Sets the length of the stream. When increasing, zero bytes are appended.

func void SB_SetLength(var int length)\n
"},{"location":"zengin/scripts/extenders/lego/tools/string_builder/#stream-operations","title":"Stream operations","text":""},{"location":"zengin/scripts/extenders/lego/tools/string_builder/#sb","title":"SB","text":"

Appends a string, to the active StringBuilder.

func void SB(var string s)\n
Parameters
  • var string s The appended string
"},{"location":"zengin/scripts/extenders/lego/tools/string_builder/#sbi","title":"SBi","text":"

Appends an integer in text form, to the active StringBuilder.

func void SBi(var int i)\n
Parameters
  • var int i The appended integer
"},{"location":"zengin/scripts/extenders/lego/tools/string_builder/#sbc","title":"SBc","text":"

Appends a byte, to the active StringBuilder. (e.g. 82 for 'R' - An ASCII table can be quickly found)

func void SBc(var int c)\n
Parameters
  • var int c The appended byte (ASCII table character)
"},{"location":"zengin/scripts/extenders/lego/tools/string_builder/#sbraw","title":"SBraw","text":"

Appends a raw bytes array, to the active StringBuilder.

func void SBraw(var int ptr, var int len)\n
Parameters
  • var int ptr Pointer to the appended array
  • var int len Length of an array
"},{"location":"zengin/scripts/extenders/lego/tools/string_builder/#sbflt","title":"SBflt","text":"

Appends a Daedalus float in text form, to the active StringBuilder.

func void SBflt(var float x)\n
Parameters
  • var float x The appended Daedalus float value
"},{"location":"zengin/scripts/extenders/lego/tools/string_builder/#sbf","title":"SBf","text":"

Appends an Ikarus float in text form, to the active StringBuilder.

func void SBf(var int x)\n
Parameters
  • var float x The appended Ikarus float value
"},{"location":"zengin/scripts/extenders/lego/tools/string_builder/#sbw","title":"SBw","text":"

Appends a 4-byte raw data (interpreted as an integer x), to the active StringBuilder.

func void SBw(var int x)\n
Parameters
  • var int i The appended value
"},{"location":"zengin/scripts/extenders/lego/tools/string_builder/#independent-functions","title":"Independent Functions","text":""},{"location":"zengin/scripts/extenders/lego/tools/string_builder/#str_escape","title":"STR_Escape","text":"

Makes escape sequences out of non-writable characters. For example, newline character \\n becomes \\\\n, tab character \\t becomes \\\\t, etc.

func string STR_Escape(var string s0)\n
Parameters
  • var string s0 The string to be added escape sequences

Return value

The function returns a new string with escape sequences added for special characters.

"},{"location":"zengin/scripts/extenders/lego/tools/string_builder/#str_unescape","title":"STR_Unescape","text":"

Counterpart to STR_Escape. Escape sequences like \\n, \\r or \\t are converted back.

func string STR_Unescape(var string s0)\n
Parameters
  • var string s0 The string to be removed escape sequences

Return value

The function returns a new string with escape sequences replaced by their corresponding characters.

"},{"location":"zengin/scripts/extenders/lego/tools/string_builder/#str_startswith","title":"STR_StartsWith","text":"

Checks if the input string s starts with the specified prefix string.

func int STR_StartsWith(var string str, var string start) \n
Parameters
  • var string str The string to be checked
  • var string start The searched prefix

Return value

The function returns TRUE if the string starts with the prefix, FALSE is returned otherwise.

"},{"location":"zengin/scripts/extenders/lego/tools/string_builder/#additional-functions","title":"Additional Functions","text":""},{"location":"zengin/scripts/extenders/lego/tools/string_builder/#buildstringsymbolsarray","title":"BuildStringSymbolsArray","text":"

Creates an array of all string symbols found in the parser's string table.

func int BuildStringSymbolsArray()\n
Return value

The function returns created array.

"},{"location":"zengin/scripts/extenders/lego/tools/string_builder/#getstringsymbolbyaddr","title":"GetStringSymbolByAddr","text":"

Retrieves the symbol at the specified address from the string table.

func int BuildStringSymbolsArray()\n
Return value

The function returns a parser symbol at the given address.

"},{"location":"zengin/scripts/extenders/lego/tools/string_builder/#examples","title":"Examples","text":""},{"location":"zengin/scripts/extenders/lego/tools/string_builder/#basic-functionality","title":"Basic functionality","text":"

This is how function that builds a string looks without StringBuilder:

func void PrintMyNumbers(var int x0, var int x1, var int x2) {\n    var string res;\n    res = ConcatStrings(IntToString(x0), \", \");\n    res = ConcatStrings(res, IntToString(x1));\n    res = ConcatStrings(res, \", \");\n    res = ConcatStrings(res, IntToString(x2));\n    PrintS(res);\n};\n
And now the function that uses StringBulider:
func void PrintMyNumbers(var int x0, var int x1, var int x2) {\n    var int s; s = SB_New();  // Create StringBuilder\n    SBi(x0);                  // Append Int\n    SB (\", \");                // Append string\n    SBi(x1);                  // Append Int\n    SB (\", \");                // Append string\n    SBi(x2);                  // Append Int\n    PrintS(SB_ToString());    // Get output as a string\n    SB_Destroy();             // Destroy StringBuilder\n};\n
Looks much more pleasant, right? But why do we create a StringBuilder and then not use it? The idea is the following: A StringBuilder is created with SB_New() and set as the active StringBuilder in the background. The package only supports one StringBuilder at a time, which will keep the pointer in case we want to use another StringBuilder in between."},{"location":"zengin/scripts/extenders/lego/tools/string_builder/#multiple-stringbuilders","title":"Multiple StringBuilders","text":"

Simple example. We want to fill two StringBuilders at the same time and then return them combined:

func string Example2() {\n    // Create two StringBuilders:\n    var int s0; s0 = SB_New();\n    var int s1; s1 = SB_New();\n\n    // Set the first StringBuilder as active and fill it.\n    SB_Use(s0);\n    SB(\"Hello \");\n    SB(\"World!\");\n\n    // Set the second StringBuilder as active and fill it.\n    SB_Use(s1);\n    SB(\"This is \");\n    SB(\"the hero speaking!\");\n\n    // Now we want to combine the two StringBuilders.\n    // The system doesn't actually provide for such an operation, but it can still be done using a helper string\n    var string str; str = SB_ToString(); // This string now says \u201cThis is the hero speaking!\u201d\n\n    SB_Use(s0);\n    SB(\" \");\n    SB(str);\n\n    str = SB_ToString(); // Now \"Hello world! This is the hero speaking!\" are in the string.\n\n    // The rest is already known, we destroy StringBuilders\n    SB_Destroy();\n    SB_Use(s1);\n    SB_Destroy();\n\n    return str;\n};\n
"},{"location":"zengin/scripts/extenders/lego/tools/talents/","title":"Talents","text":""},{"location":"zengin/scripts/extenders/lego/tools/talents/#talents","title":"Talents","text":"

The Talents package does two things:

  1. save any number of values for a specific NPC (effectively AIVar array extension).
  2. identify NPC by unique ID.

Talents package uses one free AIVar variables, the default is AIVar with the index 89 that can be customized in Userconst.d the AIV_TALENT constant.

"},{"location":"zengin/scripts/extenders/lego/tools/talents/#dependencies","title":"Dependencies","text":"
  • PermMem
"},{"location":"zengin/scripts/extenders/lego/tools/talents/#initialization","title":"Initialization","text":"

Initialize with LeGo_PermMem flag.

LeGo_Init(LeGo_PermMem);\n
"},{"location":"zengin/scripts/extenders/lego/tools/talents/#implementation","title":"Implementation","text":"

Talents.d on GitHub

"},{"location":"zengin/scripts/extenders/lego/tools/talents/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/tools/talents/#npc_getid","title":"Npc_GetID","text":"

Returns unique ID specific for provided NPC.

func int Npc_GetID(var C_NPC slf)\n
Parameters
  • var C_NPC slf NPC to get ID

Return value

The function returns NPCs unique ID.

"},{"location":"zengin/scripts/extenders/lego/tools/talents/#npc_findbyid","title":"Npc_FindByID","text":"

Finds the NPC pointer of an NPC with the given ID.

func int Npc_FindByID(var int ID)\n
Parameters
  • var int ID NPC ID

Return value

The function returns NPC pointer.

"},{"location":"zengin/scripts/extenders/lego/tools/talents/#tal_createtalent","title":"TAL_CreateTalent","text":"

Creates a talent into which you can later save a value for every NPC (just like AI_Var).

func int TAL_CreateTalent()\n
Return value

The function returns value that can be later used as a talent ID.

"},{"location":"zengin/scripts/extenders/lego/tools/talents/#tal_setvalue","title":"TAL_SetValue","text":"

Sets a new value to the specified talent.

func void TAL_SetValue(var C_NPC npc, var int talent, var int value)\n
Parameters
  • var C_NPC npc Set the talent value for this NPC
  • var int talent Talent ID
  • var int value Value to be set
"},{"location":"zengin/scripts/extenders/lego/tools/talents/#tal_getvalue","title":"TAL_GetValue","text":"

Returns the value of a saved talent for specified NPC.

func int TAL_GetValue(var C_NPC npc, var int talent)\n
Parameters
  • var C_NPC npc Get the talent value from this NPC
  • var int talent Talent ID
"},{"location":"zengin/scripts/extenders/lego/tools/timer/","title":"Timer","text":""},{"location":"zengin/scripts/extenders/lego/tools/timer/#timer","title":"Timer","text":"

Timer is a better alternative to the timers that Gothic offers. The FrameFunctions and Anim8 packages are already based on it. It isn't possible to modify the current time, as this would only cause difficulties.

"},{"location":"zengin/scripts/extenders/lego/tools/timer/#dependencies","title":"Dependencies","text":"

N/A

"},{"location":"zengin/scripts/extenders/lego/tools/timer/#initialization","title":"Initialization","text":"

Initialize with LeGo_Timer flag.

LeGo_Init(LeGo_Timer);\n
"},{"location":"zengin/scripts/extenders/lego/tools/timer/#implementation","title":"Implementation","text":"

Timer.d on GitHub

"},{"location":"zengin/scripts/extenders/lego/tools/timer/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/tools/timer/#timer_1","title":"Timer","text":"

Returns the current playing time. If a new game is started, the time is 0. It is measured in milliseconds.

func int Timer()\n
Return value

The function returns current playing time in milliseconds.

"},{"location":"zengin/scripts/extenders/lego/tools/timer/#timergt","title":"TimerGT","text":"

Returns the current game time, but the timer is paused when the game is paused (in the menu or status screen).

func int TimerGT()\n
Return value

The function returns current playing time in milliseconds, but without measuring time when game is paused.

"},{"location":"zengin/scripts/extenders/lego/tools/timer/#timerf","title":"TimerF","text":"

Alias to Timer function that returns the time as an Ikarus float value.

func int TimerF()\n
Return value

The function returns current playing time as an Ikarus float value.

"},{"location":"zengin/scripts/extenders/lego/tools/timer/#timer_setpause","title":"Timer_SetPause","text":"

Pauses the timer (and thus all FrameFunctions and running animations).

func void Timer_SetPause(var int on)\n
Parameters
  • var int on Pause on/off
"},{"location":"zengin/scripts/extenders/lego/tools/timer/#timer_setpauseinmenu","title":"Timer_SetPauseInMenu","text":"

The timer can automatically pause when the game is paused. (status screen, main menu...)

func void Timer_SetPauseInMenu(var int on)\n
Parameters
  • var int on Automatic pause on/off
"},{"location":"zengin/scripts/extenders/lego/tools/timer/#timer_ispaused","title":"Timer_IsPaused","text":"

This can be used to query whether the timer is paused.

func int Timer_IsPaused()\n
Return value

The function returns TRUE if the timer is paused, FALSE is returned otherwise.

"},{"location":"zengin/scripts/extenders/lego/tools/view/","title":"View","text":""},{"location":"zengin/scripts/extenders/lego/tools/view/#view","title":"View","text":"

This package can create textures on the screen and work with them in an extended manner.

"},{"location":"zengin/scripts/extenders/lego/tools/view/#dependencies","title":"Dependencies","text":"
  • PermMem
  • Interface
"},{"location":"zengin/scripts/extenders/lego/tools/view/#initialization","title":"Initialization","text":"

Initialize with LeGo_View flag.

LeGo_Init(LeGo_View);\n
"},{"location":"zengin/scripts/extenders/lego/tools/view/#implementation","title":"Implementation","text":"

View.d on GitHub

"},{"location":"zengin/scripts/extenders/lego/tools/view/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/tools/view/#view_create","title":"View_Create","text":"

Creates a zCView with virtual coordinates.

func int View_Create(var int x1, var int y1, var int x2, var int y2) \n
Parameters
  • var int x1/var int y1 Top-left corner coordinates (virtual)
  • var int x2/var int y2 Bottom-right corner coordinates (virtual)

Return value

The function returns a PermMem handle to a zCView.

"},{"location":"zengin/scripts/extenders/lego/tools/view/#view_createpxl","title":"View_CreatePxl","text":"

Alias for View_Create using pixel coordinates.

func int View_CreatePxl(var int x1, var int y1, var int x2, var int y2) \n
Parameters
  • var int x1/var int y1 Top-left corner coordinates (pixel)
  • var int x2/var int y2 Bottom-right corner coordinates (pixel)

Return value

The function returns a PermMem handle to a zCView.

"},{"location":"zengin/scripts/extenders/lego/tools/view/#view_createcenter","title":"View_CreateCenter","text":"

Creates a zCView with virtual coordinates centered.

func int View_CreateCenter(var int x, var int y, var int width, var int height)\n
Parameters
  • var int x Horizontal position
  • var int y Vertical position
  • var int width Width of the view
  • var int height Height of the view

Return value

The function returns a PermMem handle to a zCView.

"},{"location":"zengin/scripts/extenders/lego/tools/view/#view_createcenterpxl","title":"View_CreateCenterPxl","text":"

Alias for View_CreateCenter using pixel coordinates.

func int View_CreateCenterPxl(var int x, var int y, var int width, var int height)\n
Parameters
  • var int x Horizontal position
  • var int y Vertical position
  • var int width Width of the view
  • var int height Height of the view

Return value

The function returns a PermMem handle to a zCView.

"},{"location":"zengin/scripts/extenders/lego/tools/view/#view_get","title":"View_Get","text":"

Alias for get form PermMem.

zCView View_Get(var int hndl)\n
Parameters
  • var int hndl Handle created with View_Create
"},{"location":"zengin/scripts/extenders/lego/tools/view/#view_getptr","title":"View_GetPtr","text":"

Alias for getPtr form PermMem.

func int View_GetPtr(var int hndl)\n
Parameters
  • var int hndl Handle created with View_Create
"},{"location":"zengin/scripts/extenders/lego/tools/view/#view_render","title":"View_Render","text":"

Renders a zCView. Should be used sparingly, as it works only in specific cases.

func void View_Render(var int hndl)\n
Parameters
  • var int hndl Handle created with View_Create
"},{"location":"zengin/scripts/extenders/lego/tools/view/#view_settexture","title":"View_SetTexture","text":"

Assigns a texture to a view. The key function of this package.

func void View_SetTexture(var int hndl, var string texture)\n
Parameters
  • var int hndl Handle created with View_Create
  • var string texture Filename of a texture
"},{"location":"zengin/scripts/extenders/lego/tools/view/#view_gettexture","title":"View_GetTexture","text":"

Gets the name of a previously assigned texture.

func string View_GetTexture(var int hndl)\n
Parameters
  • var int hndl Handle created with View_Create

Return value

The function returns the previously assigned texture.

"},{"location":"zengin/scripts/extenders/lego/tools/view/#view_setcolor","title":"View_SetColor","text":"

Sets the color of a view.

func void View_SetColor(var int hndl, var int color)\n
Parameters
  • var int hndl Handle created with View_Create
  • var int color zColor, can be created with RGBA
"},{"location":"zengin/scripts/extenders/lego/tools/view/#view_getcolor","title":"View_GetColor","text":"

Gets the color of a view.

func int View_GetColor(var int hndl)\n
Parameters
  • var int hndl Handle created with View_Create

Return value

The function returns the full zColor.

"},{"location":"zengin/scripts/extenders/lego/tools/view/#view_open","title":"View_Open","text":"

Opens a view. It will be displayed on the screen.

func void View_Open(var int hndl)\n
Parameters
  • var int hndl Handle created with View_Create
"},{"location":"zengin/scripts/extenders/lego/tools/view/#view_close","title":"View_Close","text":"

Closes a view. It disappears from the screen but can still be used.

func void View_Close(var int hndl)\n
Parameters
  • var int hndl Handle created with View_Create
"},{"location":"zengin/scripts/extenders/lego/tools/view/#view_delete","title":"View_Delete","text":"

Alias for delete.

`zCView` View_Delete(var int hndl)\n
Parameters
  • var int hndl Handle created with View_Create
"},{"location":"zengin/scripts/extenders/lego/tools/view/#view_resize","title":"View_Resize","text":"

Scales a view to a virtual size. The top-left position of the view remains fixed.

func void View_Resize(var int hndl, var int width, var int height)\n
Parameters
  • var int hndl Handle created with View_Create
  • var int width New width of the view
  • var int height New height of the view
"},{"location":"zengin/scripts/extenders/lego/tools/view/#view_resizepxl","title":"View_ResizePxl","text":"

Alias for View_Resize using pixel coordinates.

func void View_ResizePxl(var int hndl, var int width, var int height)\n
Parameters
  • var int hndl Handle created with View_Create
  • var int width New width of the view
  • var int height New height of the view
"},{"location":"zengin/scripts/extenders/lego/tools/view/#view_move","title":"View_Move","text":"

Moves the view by virtual units.

func void View_Move(var int hndl, var int x, var int y)\n
Parameters
  • var int hndl Handle created with View_Create
  • var int x Shift left/right
  • var int y Shift up/down
"},{"location":"zengin/scripts/extenders/lego/tools/view/#view_movepxl","title":"View_MovePxl","text":"

Alias for View_Move using pixel coordinates.

func void View_MovePxl(var int hndl, var int x, var int y)\n
Parameters
  • var int hndl Handle created with View_Create
  • var int x Shift left/right
  • var int y Shift up/down
"},{"location":"zengin/scripts/extenders/lego/tools/view/#view_moveto","title":"View_MoveTo","text":"

Moves the top-left corner of the view to a virtual position.

func void View_MoveTo(var int hndl, var int x, var int y)\n
Parameters
  • var int hndl Handle created with View_Create
  • var int x New horizontal position (-1 for no change)
  • var int y New vertical position (-1 for no change)
"},{"location":"zengin/scripts/extenders/lego/tools/view/#view_movetopxl","title":"View_MoveToPxl","text":"

Alias for View_MoveTo using pixel coordinates.

func void View_MoveToPxl(var int hndl, var int x, var int y)\n
Parameters
  • var int hndl Handle created with View_Create
  • var int x New horizontal position (-1 for no change)
  • var int y New vertical position (-1 for no change)
"},{"location":"zengin/scripts/extenders/lego/tools/view/#view_addtext","title":"View_AddText","text":"

Adds a text line to the view. The position is virtual and relative to the view's position. If the view is moved, the text moves as well.

func void View_AddText(var int hndl, var int x, var int y, var string text, var string font)\n
Parameters
  • var int hndl Handle created with View_Create
  • var int x Horizontal position
  • var int y Vertical position
  • var string text Added text
  • var string font Used Font
"},{"location":"zengin/scripts/extenders/lego/tools/view/#view_deletetext","title":"View_DeleteText","text":"

Removes all text added with View_AddText.

func void View_DeleteText(var int hndl)\n
Parameters
  • var int hndl Handle created with View_Create
"},{"location":"zengin/scripts/extenders/lego/tools/view/#view_top","title":"View_Top","text":"

Places the view above all others.

func void View_Top(var int hndl)\n
Parameters
  • var int hndl Handle created with View_Create
"},{"location":"zengin/scripts/extenders/lego/tools/view/#examples","title":"Examples","text":""},{"location":"zengin/scripts/extenders/lego/tools/view/#display-a-texture-on-the-screen","title":"Display a texture on the screen","text":"

Here a texture should be displayed over the entire screen:

func void Example1() {\n    var int View; \n    View = View_Create(0, 0, PS_VMax, PS_VMax); // Virtual coordinates\n    View_SetTexture(View, \"MyTexture.tga\"); // Assign a texture to the view\n    // display the view on the screen:\n    View_Open(View);\n};\n

This would mean that the texture would be permanently visible on the screen (even after loading/saving/restarting). If we want it to disappear we have to use either View_Delete or View_Close.

"},{"location":"zengin/scripts/extenders/lego/tools/view/#display-a-texture-with-pixel-coordinates","title":"Display a texture with pixel coordinates","text":"

Now a texture should be displayed at the top right and be 256 x 256 pixels in size:

func void Example2() {\n    Print_GetScreenSize();\n    var int View;\n    View = View_CreatePxl(Print_Screen[PS_X] - 256, 0, Print_Screen[PS_X], 256); // Pixel coordinates\n    View_SetTexture(View, \"MYTEXTURE.TGA\");\n    View_Open(View);\n};\n

To get the size of the screen we use the interface package.

"},{"location":"zengin/scripts/extenders/lego/various/userconstants/","title":"User constants","text":""},{"location":"zengin/scripts/extenders/lego/various/userconstants/#user-constants","title":"User constants","text":"

All constants that the user can either use or even change freely are defined in Userconst.d file.

"},{"location":"zengin/scripts/extenders/lego/various/userconstants/#read-only","title":"Read only","text":"

These constants may only be used, not changed.

"},{"location":"zengin/scripts/extenders/lego/various/userconstants/#anim8","title":"Anim8","text":"

These constants are used by Anim8 and Anim8q.

  • const int A8_Constant Constant movement speed
  • const int A8_SlowEnd Evenly decelerated movement
  • const int A8_SlowStart Evenly accelerated movement
  • const int A8_Wait Do nothing. The target value is ignored here
"},{"location":"zengin/scripts/extenders/lego/various/userconstants/#buttons","title":"Buttons","text":"

The following bit masks can be applied to the status of a button:

  • const int BUTTON_ACTIVE The button is active, it reacts to the mouse
  • const int BUTTON_ENTERED The mouse is \"within\" the button
"},{"location":"zengin/scripts/extenders/lego/various/userconstants/#interface","title":"Interface","text":"

Dimensions

  • const int PS_X and const int PS_Y Use with Print_Screen or Print_ToVirtual functions
  • const int PS_VMax Highest possible value of a virtual coordinate

Colors

16 basic colors that can be used as zColor parameters

  • const int COL_Aqua
  • const int COL_Black
  • const int COL_Blue
  • const int COL_Fuchsia
  • const int COL_Gray
  • const int COL_Green
  • const int COL_Lime
  • const int COL_Maroon
  • const int COL_Navy
  • const int COL_Olive
  • const int COL_Purple
  • const int COL_Red
  • const int COL_Silver
  • const int COL_Teal
  • const int COL_White
  • const int COL_Yellow
"},{"location":"zengin/scripts/extenders/lego/various/userconstants/#gamestate","title":"Gamestate","text":"

Gamestate can assume these values:

  • const int Gamestate_NewGame New game started
  • const int Gamestate_Loaded A game has been loaded
  • const int Gamestate_WorldChange The world has changed
  • const int Gamestate_Saving The game is saved
"},{"location":"zengin/scripts/extenders/lego/various/userconstants/#cursor","title":"Cursor","text":"

These constants are sent with Cursor_Event:

  • const int CUR_LeftClick The left mouse button was pressed
  • const int CUR_RightClick The right mouse button was pressed
  • const int CUR_MidClick The middle mouse button was pressed
  • const int CUR_WheelUp Mouse wheel up
  • const int CUR_WheelDown Mouse wheel down
"},{"location":"zengin/scripts/extenders/lego/various/userconstants/#modifiable","title":"Modifiable","text":"

These constants are often used by packages and may be changed freely.

"},{"location":"zengin/scripts/extenders/lego/various/userconstants/#bloodsplats","title":"Bloodsplats","text":"
  • const int BLOODSPLAT_NUM Maximum number on screen
  • const int BLOODSPLAT_TEX Highest Texture ID (\"BLOODSPLAT\" + texID + \".TGA\")
  • const int BLOODSPLAT_DAM Texture size damage multiplier (damage * 2Bloodsplat_Dam)
"},{"location":"zengin/scripts/extenders/lego/various/userconstants/#cursor_1","title":"Cursor","text":"
  • const string Cursor_Texture This texture is used to display the cursor (default: \"CURSOR.TGA\")
"},{"location":"zengin/scripts/extenders/lego/various/userconstants/#interface_1","title":"Interface","text":"
  • const string Print_LineSeperator Text boxes can be printed in multiple lines. This character separates the lines from each other.
"},{"location":"zengin/scripts/extenders/lego/various/userconstants/#prints","title":"PrintS","text":"

All position and size information is completely virtual:

  • const int PF_PrintX Start position on the X axis
  • const int PF_PrintY Start position on the Y axis
  • const int PF_TextHeight Space between individual lines

The times are given in ms:

  • const int PF_FadeInTime Time to fade in the text
  • const int PF_FadeOutTime Time to fade out the text
  • const int PF_MoveYTime Time needed to \"slip down\"
  • const int PF_WaitTime Time during which the print is fully visible

The font can be modified:

  • const string PF_Font Default: FONT_OLD_10_WHITE.TGA
"},{"location":"zengin/scripts/extenders/lego/various/userconstants/#talents","title":"Talents","text":"
  • const int AIV_TALENT Used AIVar
"},{"location":"zengin/scripts/extenders/lego/various/userconstants/#dialoggestures","title":"Dialoggestures","text":"
  • const string DIAG_Prefix Animation prefix (\"DG_\")
  • const string DIAG_Suffix Animation suffix (\"_\")
"},{"location":"zengin/scripts/extenders/standalone/","title":"Standalone Scripts","text":""},{"location":"zengin/scripts/extenders/standalone/#standalone-scripts","title":"Standalone Scripts","text":"

Over the years Gothic modders have created many useful features to use with Zengin scripts. This section contains documentation for some scripts that are \"standalone\", meaning they are not part of larger packages, but are often small features to make modders lives easier.

"},{"location":"zengin/scripts/extenders/standalone/#script-bins","title":"Script Bins","text":"

A few people came up with the idea of collecting scripts scattered on the forums, which resulted in the so-called Script Bins.

Warning

Script bins aren't updated frequently, so for the latest updates and new scripts also check the ScriptBin WoG thread.

"},{"location":"zengin/scripts/extenders/standalone/#wog-script-bin","title":"WoG Script Bin","text":"

Script bin made by Kirides containing scripts from German WoG forum.

https://apps.kirides.de/wog-script-bin/

"},{"location":"zengin/scripts/extenders/standalone/#scriptbin-github-repository","title":"ScriptBin GitHub repository","text":"

Lehona has created a GitHub repository that contains scripts from some of the modders.

https://github.com/Lehona/ScriptBin

"},{"location":"zengin/scripts/extenders/standalone/gameKeyEvents/","title":"gameKeyEvents","text":""},{"location":"zengin/scripts/extenders/standalone/gameKeyEvents/#gamekeyevents","title":"gameKeyEvents","text":"

Quick overview

Author: mud-freak Platform: G1, G2NotR Category: Engine, Keys

gameKeyEvents.d is a script, which handles key events with the oCGame::HandleEvent hook. Better alternative for FrameFunction with MEM_KeyState with which you don't have to check whether any menu is opened or player is in dialogue or can move etc.

Author's description

I looked up the address within oCGame::HandleEvent. I made it into a universally usable script for Gothic 1 and Gothic 2.

One could argue now that this is not much different from a FrameFunction with MEM_KeyState. The difference is that this approach saves the extra work of checking if any menu is open, whether the player is in a dialog, whether the player may move, etc. Also this function is \"event driven\", meaning it is really only called when a key is pressed/held instead of every frame in vain. So it's arguably more performant.

"},{"location":"zengin/scripts/extenders/standalone/gameKeyEvents/#dependencies","title":"Dependencies","text":"
  • Ikarus
  • HookEngine
"},{"location":"zengin/scripts/extenders/standalone/gameKeyEvents/#initialization","title":"Initialization","text":"

Call Game_KeyEventInit() in the Init_Global() or other initialization function.

Game_KeyEventInit();\n
"},{"location":"zengin/scripts/extenders/standalone/gameKeyEvents/#implementation","title":"Implementation","text":"

gameKeyEvents.d on WoG forum

"},{"location":"zengin/scripts/extenders/standalone/gameKeyEvents/#usage","title":"Usage","text":"

To add a key pressing detection edit the main function Game_KeyEvent.

func int Game_KeyEvent(var int key, var int pressed) {\n    if (key == KEY_LBRACKET) && (pressed) {\n        // Here enter your code.\n        return TRUE;\n    };\n    return FALSE;\n};\n
  • To change detected key rename KEY_LBRACKET to your own key e.g. taken from Ikarus constants.
  • To detect pressing a key leave (pressed) unchanged but if you want to detect holding change it to (!pressed). That's because

    pressed is FALSE: key is held, pressed is TRUE: key press onset

  • To run code when a key is pressed, paste it or call a function where the comment is.
  • To detect more than one key add else if.
"},{"location":"zengin/scripts/extenders/standalone/setBarPositions/","title":"setBarPositions","text":""},{"location":"zengin/scripts/extenders/standalone/setBarPositions/#setbarpositions","title":"setBarPositions","text":"

Quick overview

Author: mud-freak Platform: G1, G2NotR Category: Engine, Interface

setBarPositions.d is a script that allows changing position of original gothic bars (HP, Mana, Swim, focus). Changes are directly in the engine, so bars are normally scaled.

"},{"location":"zengin/scripts/extenders/standalone/setBarPositions/#dependencies","title":"Dependencies","text":"
  • Ikarus
  • HookEngine
"},{"location":"zengin/scripts/extenders/standalone/setBarPositions/#initialization","title":"Initialization","text":"

Call it in the Init_Global() or other initialization function. Set the manaAlwaysOn and swimAlwaysOn to TRUE/FALSE.

SetBarPositions_Init(manaAlwaysOn, swimAlwaysOn);\n
"},{"location":"zengin/scripts/extenders/standalone/setBarPositions/#implementation","title":"Implementation","text":"

setBarPositions.d on WoG forum

"},{"location":"zengin/scripts/extenders/standalone/setBarPositions/#usage","title":"Usage","text":"

To change positions of bars edit the main function SetBarPosition. Look at the examples to see how you can adjust it to your preferences.

func int SetBarPosition(var int barPtr) {\n    var oCViewStatusBar bar; bar = _^(barPtr);\n    var int x; var int y;\n\n    if (barPtr == MEM_Game.hpBar) {\n        // Original\n        x = Print_ToVirtual(10, PS_X);                                // 10 px from the left\n        y = PS_VMax - Print_ToVirtual(10 + bar.zCView_psizey, PS_Y);  // 10 px from the bottom\n\n    } else if (barPtr == MEM_Game.manaBar) {\n        // Original\n        x = PS_VMax - Print_ToVirtual(10 + bar.zCView_psizex, PS_X);  // 10 px from the right\n        y = PS_VMax - Print_ToVirtual(10 + bar.zCView_psizey, PS_Y);  // 10 px from the bottom\n\n    } else if (barPtr == MEM_Game.swimBar) {\n        // Original\n        x = (PS_VMax - bar.zCView_vsizex) / 2;                        // Centered\n        y = PS_VMax - Print_ToVirtual(10 + bar.zCView_psizey, PS_Y);  // 10 px from the bottom\n\n    } else if (barPtr == MEM_Game.focusBar) {\n        // Original\n        x = (PS_VMax - bar.zCView_vsizex) / 2;                        // Centered\n        y = Print_ToVirtual(10, PS_Y);                                // 10 px from the top\n    };\n\n    return x | (y << 14);\n};\n
"},{"location":"zengin/scripts/extenders/standalone/setBarPositions/#examples","title":"Examples","text":""},{"location":"zengin/scripts/extenders/standalone/setBarPositions/#all-bars-on-the-left-side","title":"All bars on the left side","text":"
/*\n * EXAMPLE: Stacked on the left\n */\nfunc int SetBarPosition(var int barPtr) {\n    var oCViewStatusBar bar; bar = _^(barPtr);\n    var int x; var int y;\n\n    if (barPtr == MEM_Game.hpBar) {\n        x = Print_ToVirtual(10, PS_X);\n        y = PS_VMax - Print_ToVirtual(6 + 3 * (4 + bar.zCView_psizey), PS_Y);\n\n    } else if (barPtr == MEM_Game.manaBar) {\n        x = Print_ToVirtual(10, PS_X);\n        y = PS_VMax - Print_ToVirtual(6 + 2 * (4 + bar.zCView_psizey), PS_Y);\n\n    } else if (barPtr == MEM_Game.swimBar) {\n        x = Print_ToVirtual(10, PS_X);\n        y = PS_VMax - Print_ToVirtual(6 + 1 * (4 + bar.zCView_psizey), PS_Y);\n\n    } else if (barPtr == MEM_Game.focusBar) {\n        // Original\n        x = (PS_VMax - bar.zCView_vsizex) / 2;                        // Centered\n        y = Print_ToVirtual(10, PS_Y);                                // 10 px from the top\n    };\n\n    return x | (y << 14);\n};\n
"},{"location":"zengin/scripts/extenders/zparserextender/","title":"zParserExtender","text":""},{"location":"zengin/scripts/extenders/zparserextender/#zparserextender","title":"zParserExtender","text":"

zParserExtender extends ZenGin's parser and adds many useful features. It significantly extends the functionality of scripts with added functionality and new external functions. It also enhances script compilation, allowing to compile OU files directly with the game and allowing for runtime script injection. Since the Union version 1.0m zParserExtender is fully integrated in Union itself.

Note

This is mostly a translation of the original release post

Contacts Author Gratt GitHub zParserExtender Forum zParserExtender"},{"location":"zengin/scripts/extenders/zparserextender/classes/c_trigger/","title":"Trigger functions and the `C_Trigger` class","text":""},{"location":"zengin/scripts/extenders/zparserextender/classes/c_trigger/#trigger-functions-and-the-c_trigger-class","title":"Trigger functions and the C_Trigger class","text":"

zParserExtender also implements cyclical functions called triggers - not to be confused with triggers in ZEN files, similar to a part of the functionality implemented in LeGo AI_Functions. These functions are called independently after a specified period of time. These triggers can also store user information. Up to 16 int variables can be stored in each trigger as well as self, other and victim instances.

"},{"location":"zengin/scripts/extenders/zparserextender/classes/c_trigger/#class-definition","title":"Class definition","text":"

To define a trigger, the C_Trigger class is used:

/// Union zParserExtender Trigger class\nclass C_Trigger\n{\n    var int Delay; // defines the frequency (in milliseconds) at which the function will be called.\n    var int Enabled; // determines if the trigger is active. If the value is equal to zero, the trigger is destroyed.\n    var int AIVariables[16]; // user data, which can be set independently when creating trigger (yes, you can write there absolutely everything you want).\n\n    // Hidden variable members\n    /*\n        - Func   - The function that the trigger will call.\n        - Self   - The NPC that will be placed in `self` when the function is called.\n        - Other  - An NPC that will be placed in `other` when the function is called.\n        - Victim - The NPC that will be placed in `victim` when the function is called.\n    */\n};\n
"},{"location":"zengin/scripts/extenders/zparserextender/classes/c_trigger/#creating-instances","title":"Creating instances","text":"

There are two external functions that are used to create C_Trigger instance.

// function returns a trigger with no NPC (self, other or victim) bound to it\nfunc C_Trigger AI_StartTriggerScript(   var string funcName,\n                                        var int delay) {};\n\n// function is extended, if certain participants need to be assigned to it\nfunc C_Trigger AI_StartTriggerScriptEx( var string funcName,\n                                        var int delay,\n                                        var C_Npc slf,\n                                        var C_Npc oth,\n                                        var C_Npc vct) {};\n

Both of these functions return an instance of C_Trigger instance. You can of course configure the instance after its creation. You can, for example, fill in the AIVariables with relevant data. The trigger function has the required signature if 'func int f()'. It must return a value indicating the state of the loop. If the function returns LOOP_END the trigger will be stopped and the instance deleted. If LOOP_CONTINUE is returned, the function will be called again after Delay ms have passed.

"},{"location":"zengin/scripts/extenders/zparserextender/classes/c_trigger/#poison-example","title":"Poison example","text":"
// Implement a trigger to simulate the effect of poison debuff:\n// Let's create a trigger on function `c_loop` with a call interval of 1 second.\n// When the function is called, the instance hero will be placed in self (although it can be any other NPC if desired).\n// The rest of the instances are left null (not used).\n\nvar C_Trigger trigger;\ntrigger = AI_StartTriggerScriptEx(\"c_loop\", 1000, hero, null, null);\ntrigger.AIVariables[0] = 15; // how many times the function should be called\ntrigger.AIVariables[1] = 5;  // how much damage to deal each iteration\n

The trigger function

func int c_loop()\n{\n    // Create a loop end check, if the number of\n    // available iterations has reached 0. If it did\n    // we stop the trigger by returning the LOOP_END value.\n    if (SelfTrigger.AIVariables[0] <= 0)\n    {\n        return Loop_end;\n    };\n\n    SelfTrigger.Delay -= 20;         // Accelerate loop each call by 20 ms\n    SelfTrigger.AIVariables[0] -= 1; // Reduce number of remaining repeats\n    self.Attribute[ATR_HITPOINTS] -= SelfTrigger.AIVariables[1]; // Take health from self\n    return LOOP_CONTINUE;\n};\n
"},{"location":"zengin/scripts/extenders/zparserextender/classes/c_trigger/#trigger-scope","title":"Trigger scope","text":"

Triggers can be divided into two types:

  • Global trigger ( AI_StartTriggerScript ) trigger created using this function works in all worlds. A trigger is considered global by default if neither self nor other nor victim has been provided for it.
  • Local trigger ( AI_StartTriggerScriptEx) trigger created with this function only works in the world in which it was created. A trigger is considered local if it has been presented with at least one NPC in self, other or victim (not null). If you want to create a trigger without linking it to any NPC, it is recommended to simply pass hero as self to the trigger.
"},{"location":"zengin/scripts/extenders/zparserextender/classes/c_trigger/#saving","title":"Saving","text":"

The plugin creates a new save archive to save the information of the triggers that does not conflict with any of the built-in save files.

"},{"location":"zengin/scripts/extenders/zparserextender/classes/c_trigger/#searching","title":"Searching","text":"

To search for a specific trigger, for example by NPC, the trigger external functions can be used.

// This way you can disable all triggers running on the `hero` instance\nvar C_Trigger trigger = FirstTrigger;\nvar C_Trigger trigger_saved;\nwhile (!Hlp_IsNULL(trigger))\n{\n    trigger_saved = trigger;\n    trigger = AI_GetNextTriggerBySelf(hero);\n    trigger_saved.Enabled = false;\n};\n
"},{"location":"zengin/scripts/extenders/zparserextender/classes/helperclasses/","title":"Engine classes","text":""},{"location":"zengin/scripts/extenders/zparserextender/classes/helperclasses/#engine-classes","title":"Engine classes","text":"

zParserExtender implements various proxy classes that can be used to access game world objects.

Warning

It is not recommended to implement complex mechanics using these classes and functions. They are present as a simple backup option for accessing game world objects and for quick fixes.

"},{"location":"zengin/scripts/extenders/zparserextender/classes/helperclasses/#c_vob","title":"C_VOB","text":"

This class represents basic pointer to a game world object.

"},{"location":"zengin/scripts/extenders/zparserextender/classes/helperclasses/#c_color","title":"C_Color","text":"

Represents color in the RGBA format

class C_Color\n{\n    var int R; // red channel value\n    var int G; // green channel value\n    var int B; // blue channel value\n    var int A; // alpha channel value\n};\n
"},{"location":"zengin/scripts/extenders/zparserextender/classes/helperclasses/#zvec3","title":"zVEC3","text":"

Represents 3D position in the world (float version for internal functions)

class zVEC3\n{\n    var float X; // X coordinate\n    var float Y; // Y coordinate\n    var float Z; // Z coordinate\n};\n
"},{"location":"zengin/scripts/extenders/zparserextender/classes/helperclasses/#c_position","title":"C_Position","text":"

Represents 3D position in the world

class C_Position\n{\n    var int X; // X coordinate\n    var int Y; // Y coordinate\n    var int Z; // Z coordinate\n};\n
Externals:
/// Returns the current position of the object in the world\n/// \n/// @param vob vob to ge the position of\n/// @return C_Position instance - position of the VOB\nfunc C_Position Vob_GetVobPosition( var C_Vob vob ) {};\n\n/// Sets the current position of the object in the world\n/// \n/// @param vob vob to get the position of\n/// @param pos new position of the vob\nfunc void Vob_SetVobPosition( var C_Vob vob, var C_Position pos ) {};\n

Note

The following classes define properties of C_VOB objects or classes derived from it.

"},{"location":"zengin/scripts/extenders/zparserextender/classes/helperclasses/#c_vob_data","title":"C_VOB_DATA","text":"

Represents universal zCVob class

class C_VOB_DATA\n{\n    var string Name;              // object name\n    var float VisualAlpha;        // object's transparency 0.0 - 1.0\n    var int ShowVisual;           // display the mode\n    var int DrawBBox3D;           // show objects bounding box\n    var int VisualAlphaEnabled;   // enables objects transparency\n    var int PhysicsEnabled;       // enables object's physics\n    var int IgnoredByTraceRay;    // allow any object collisions\n    var int CollDetectionStatic;  // allow collision with static world polygons\n    var int CollDetectionDynamic; // allow collision with dynamic world objects\n    var int CastDynShadow;        // display shadow of the object\n    var int LightColorStatDirty;  // allow static lighting of the object\n    var int LightColorDynDirty;   // allow dynamic lighting of the object\n    var int SleepingMode;         // sets object's activity mode (0 - inactive, 1 - active, 2 - AI only)\n    var int DontWriteIntoArchive; // turns of the serialization of this object to the save file \n};\n
Externals:
/// Returns the universal data of the zCVob object\n///\n/// @param vob VOB to get the position of\n/// @return general vob data C_Vob_Data\nfunc C_Vob_Data Vob_GetVobData( var C_Vob vob ) {};\n\n/// Sets the universal data to a zCVob object\n///\n/// @param vob VOB to get the position of\n/// @param data general vob data C_Vob_Data\nfunc void Vob_SetVobData( var C_Vob vob, var C_Vob_Data data ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/classes/helperclasses/#c_light_data","title":"C_LIGHT_DATA","text":"

Represents zCVobLight objects

class C_LIGHT_DATA\n{\n    var int R;                // red light intensity\n    var int G;                // green light intensity\n    var int B;                // blue light intensity\n    var int Range;            // radius\n    var int RangeInv;         // \n    var int RangeBackup;      // \n    var int RangeAniActFrame; // current light animation frame for the radius\n    var int RangeAniFPS;      // speed of light animation for the radius\n    var int ColorAniActFrame; // current light animation frame for colour\n    var int ColorAniFPS;      // speed of light animation for colour\n    var int SpotConeAngleDeg; // angle of cone light source\n    var int IsStatic;         // whether the source is static\n    var int RangeAniSmooth;   // [UNUSED]\n    var int RangeAniLoop;     // [UNUSED]\n    var int ColorAniSmooth;   // allows soft transitions between colours\n    var int ColorAniLoop;     // [UNUSED]\n    var int IsTurnedOn;       // whether the light source is on\n    var int LightQuality;     // source quality (when statically compiling light) (0 - high, 1 - medium, 2 - low)\n    var int LightType;        // type of source (at static light compilation) (0 - point, 1 - cone)\n};\n
Externals:
/// Returns zCVobLight object data\n///\n/// @param vobLight vobLight object\n/// @return C_Light_Data of the light\nfunc C_Light_Data Vob_GetLightData( var C_Vob vobLight ) {};\n\n/// Sets the data of a zCVobLight object\n///\n/// @param vobLight object to apply the light data to\n/// @param data C_Light_Data light data to be set\nfunc void Vob_SetLightData( var C_Vob vobLight, var C_Light_Data data ) {};\n\n/// Clears the list of animation colours for the light source\n///\n/// @param vobLight light vob\nfunc void Vob_ClearLightAniList( var C_Vob vobLight ) {};\n\n/// Adds a color to the colour list\n///\n/// @param vobLight object to apply the colour to\n/// @param col colour to be applied\nfunc void Vob_AddLightAniColor( var C_Vob vobLight, var C_Color col ) {};\n\n/// Adds a color to the colour list\n///\n/// @param vobLight object to apply the colour to\n/// @param r red colour channel\n/// @param g green colour channel \n/// @param b blue colour channel\nfunc void Vob_AddLightAniColorRGB(  var C_Vob vobLight,\n                                    var int r,\n                                    var int g,\n                                    var int b ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/classes/helperclasses/#c_mob_data","title":"C_MOB_DATA","text":"

Represents data for the used oCMOB object

class C_MOB_DATA\n{\n    var string VisibleName;     // name shown above the object\n    var int Hitpoints;          // number of hitpoints\n    var int Damage;             // damage the object can cause\n    var int IsDestroyed;        // if the object is destroyed\n    var int Moveable;           // whether the object can be moved\n    var int Takeable;           // whether the object can be taken\n    var int FocusOverride;      // if the object will redefine focus in combat mode\n    var int SndMat;             // object's material (0 - wood, 1 - stone, 2 - metal, 3 - skin, 4 - clay, 5 - glass)\n    var string VisualDestroyed; // model when the object is destroyed\n    var string OwnerStr;        // name of the instance of the owner of the object\n    var string OwnerGuildStr;   // name of the guild of the object\n    var int Owner;              // instance of the owner\n    var int OwnerGuild;         // guild instance\n    var int FocusNameIndex;     // the script string of the displayed name\n};\n
/// Returns the data of the oCMOB object\n///\n/// @param mob oCMOB object\n/// @return mob data\nfunc C_Mob_Data Vob_GetMobData( var C_Vob mob ) {};\n\n/// Sets the data of the oCMOB object\n///\n/// @param mob oCMOB object\n/// @param data C_Mob_Data to be set \nfunc void Vob_SetMobData( var C_Vob mob, var C_Mob_Data data ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/classes/helperclasses/#c_mobinter_data","title":"C_MOBINTER_DATA","text":"

Represents data for the interactive object oCMobInter

class C_MOBINTER_DATA\n{\n    var string TriggerTarget;   // object name which will be triggered by OnTrigger\n    var string UseWithItem;     // name of the object instance that is needed for interaction\n    var string Sceme;           // name of the scene that corresponds to the object and character animations\n    var string ConditionFunc;   // scripting condition under which the interaction can be performed\n    var string OnStateFuncName; // the name pattern of the functions that will be called when the object changes the state\n    var int State;              // the current state of the object\n    var int State_num;          // number of object's states\n    var int State_target        // current state of the object\n    var int Rewind;             // prohibits object updating\n    var int MobStateAni;        // current animation of the object\n    var int NpcStateAni;        // current character animation\n};\n
/// Returns the data of the oCMobInter object\n///\n/// @param mobInter oCMobInter object\n/// @return MobInter_Data of the object\nfunc MobInter_Data Vob_GetMobInterData( var C_Vob mobInter ) {};\n\n/// Sets the data of the oCMobInter object\n///\n/// @param mobInter oCMobInter object\n/// @param data MobInter_Data of the object\nfunc void Vob_SetMobInterData( var C_Vob mobInter, var C_MobInter_Data data ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/classes/helperclasses/#c_moblockable_data","title":"C_MOBLOCKABLE_DATA","text":"

Represents data for the locked interactive object oCMobLockable

class C_MOBLOCKABLE_DATA\n{\n    var int Locked;         // whether the object is locked\n    var int AutoOpen;       // [UNUSED]\n    var int PickLockNr;     // current rotation number \n    var string KeyInstance; // key instance name for the object\n    var string PickLockStr; // combination to open the object (\"LRRLR\")\n};\n
/// Returns the data of the oCMobLockable object\n///\n/// @param mobLock oCMobLockable object\n/// @param data MobInter_Data of the object\nfunc C_MobLockable_Data Vob_GetMobInterData( var C_Vob mobLock ) {};\n\n/// Sets the data of the oCMobLockable object\n///\n/// @param mobLock oCMobLockable object\n/// @param data C_MobLockable_Data of the object\nfunc void Vob_SetMobInterData( var C_Vob mobLock, var C_MobLockable_Data data ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/daedalus_injection/","title":"Daedalus Injection","text":""},{"location":"zengin/scripts/extenders/zparserextender/daedalus_injection/#daedalus-injection","title":"Daedalus Injection","text":"

Script injection is a process of injecting Daedalus scripts on runtime without the need to recompile the scripts. This is essential for Union plugins that need to alter the scripts in a certain way, either for hotfixes or just for testing scripts without the need to recompile the whole .dat file.

To inject a script, simply put a .d or .src file in Gothic/System/Autorun directory and run the game.

Tip

Automatic injection does not extend to nested directories in the Autorun directory directly, but you can put a .src file into Autorun directory and the rest into a subdirectory to keep a cleaner structure.

Scripts in subdirectories can be accessed in two ways

  1. They are specified in a .src file
  2. The script file is an API script
"},{"location":"zengin/scripts/extenders/zparserextender/daedalus_injection/#api-script","title":"API script","text":"

API scripts are .d files placed in Autorun subdirectories and are used as a dependency. It is assumed that the API script is not called on its own (or from a .src) file, but is called using the dependency keyword After in one of the injected script files' META block.

These scripts are meant to contain ready-made solution that need to be used by many other scripts as a dependency.

Warning

If the file specified in the After tag in the META block does not exist, the current file will not be parsed and injected since the dependency is missing, and it would fail. Due to this it is best to ship the dependency in the Autorun directory even if it comes from a different plugin.

"},{"location":"zengin/scripts/extenders/zparserextender/daedalus_injection/hooks/","title":"Hooking Daedalus","text":""},{"location":"zengin/scripts/extenders/zparserextender/daedalus_injection/hooks/#hooking-daedalus","title":"Hooking Daedalus","text":"

Daedalus hooking is one of the most powerful features of this plugin. Hooking is a mechanism that allows you to replace any scripted object with a new one. To do this, you must define a new object with the same type, name and in the same namespace.

Hook/replacement will be performed only if the MergeMode setting is set to true for the current script in the META block or in the parameter of the same name in the .ini file of the mod.

Warning

If you forget to turn on the MergeMode, the compilation will fail with the redefinition error.

When an object (instance, function or variable) is hooked/replaced, the original one is available under the same name with the _old suffix (PC_Hero -> PC_Hero_old). This allows you to refer to the old object.

"},{"location":"zengin/scripts/extenders/zparserextender/daedalus_injection/hooks/#function-hook-example","title":"Function hook example","text":"
func void ZS_Attack_Loop()\n{\n    // if the enemy is a player and has no weapon, then\n    // also sheath the weapon.\n    if (Npc_IsPlayer(other) && !Npc_HasReadiedWeapon(other))\n    {\n        return LOOP_END;\n    };\n\n    // otherwise call the original function\n    return ZS_Attack_Loop_Old();\n};\n

This kind of substitution works for instances and variables too.

Warning

While hooking an instances, you have to take care not to call the prototype. Prototype should be always changed back to the original class.

This is wrong
instance pc_hero(Npc_Default)\n{\n    pc_hero_old();\n    name = \"Pepe\";\n};\n
This leads to a double call of prototype Npc_Default which is considered an unsafe practice with undefined behaviour.

The correct way is to call it like this:

instance pc_hero(C_NPC) // no prototype Npc_Default\n{\n    pc_hero_old();\n    name = \"Pepe\";\n};  \n
This way the prototype is called in the original function pc_hero_old() and not for the second time when creating the new hooked instance."},{"location":"zengin/scripts/extenders/zparserextender/daedalus_injection/hooks/#dialogue-hook-example","title":"Dialogue hook example","text":"

The hooking mechanism is designed to introduce new dialogues into the game as well as replacing old ones with hooks. The scripter can create new merchants, quests, dialogues, as well as attach svm phrases to them.

All new or replaced dialogues will immediately become available, including from saves. In the event that new dialogs are disabled (plugin or script removed), the engine will continue to keep them in the save file, which will allow the dialogs to return at any time with the same state they were in the last time.

Warning

Currently not working as intended (I think). The old dialogue is still used and as a result you will end up with both the old and the new dialogue (unless you edit the old condition function).

instance DIA_XARDAS_HELLO(C_INFO)\n{\n    DIA_XARDAS_HELLO_old();\n    important = FALSE;\n};\n
"},{"location":"zengin/scripts/extenders/zparserextender/daedalus_injection/meta/","title":"META block","text":""},{"location":"zengin/scripts/extenders/zparserextender/daedalus_injection/meta/#meta-block","title":"META block","text":"

The META block is optional. If it is specified, it has to be the very first thing in the file without any indent or a comment above it.

Syntax:

META\n{\n    Parser // specifies into which compiled file the scripts are going to be injected\n    /*\n        Code    Name              DAT file\n        ---     ------            -------\n        Game    parser            Gothic.dat\n        SFX     parserSoundFX     SFX.dat\n        PFX     parserParticleFX  ParticleFX.dat\n        VFX     parserVisualFX    VisualFX.dat\n        Camera  parserCamera      Camera.dat\n        Menu    parserMenu        Menu.dat\n        Music   parserMusic       Music.dat\n    */\n    MergeMode   // 0 - if conflict occurs = compilation error, 1 - if conflict occurs = hook\n    Engine      // comma separated list of engines for which the scripts will be injected \n    /*\n        Code  Engine          Human readable name\n        ---   -----           -----------------------\n        G1    Gothic I        Gothic I Classic\n        G1A   Gothic Sequel   Gothic I Addon <3\n        G2    Gothic II       Gothic II Classic\n        G2A   Gothic II NoTR  Gothic II Addon\n    */\n\n    NativeWhile // use native while\n    Namespace   // namespace of this script file\n    Using       // comma separated list of namespaces, that are considered local for this script file\n    Mod         // specify for which mod should this code be injected\n    After       // comma separated list of scripts, after which this script should be parsed\n};\n
"},{"location":"zengin/scripts/extenders/zparserextender/daedalus_injection/other/","title":"Other functions of the extender","text":""},{"location":"zengin/scripts/extenders/zparserextender/daedalus_injection/other/#other-functions-of-the-extender","title":"Other functions of the extender","text":""},{"location":"zengin/scripts/extenders/zparserextender/daedalus_injection/other/#ini-parameters","title":"ini parameters","text":"

The choice of ini file depends on how the game was launched. If it was launched from Gothic.exe, then the parameters will be read from SystemPack.ini. If it was launched through GothicStarter.exe, then they will be read from the ini of the mod.

[zParserExtender]\nLoadScript(obsolete) =\n;specifies a parser-script format script to run the scripts. The parameter is currently invalid.\n\nMergeMode = True\n;specifies whether injections will produce hooks.\n\nCompileDat = False\n;Determines if a copy of DAT file which has been modified by injection will be created.\n\nCompileOU = False\n;determines if a copy of an injection-modified OU file will be created.\n\nNativeWhile = False\n;Determines if a WHILE loop will be compiled. Defaults to False (for Ninja compatibility).\n\nMessagesLevel = 1\n;sets the output level. The higher the level, the more information will be printed to the debug console.\n\nStringIndexingMode = -1\n;defines string indexing mode (see string indexing). Default value is -1.\n;Default   = -1 - The default mode for the moment is Repair mode.\n;Disabled  =  0 - Do nothing with the indices.\n;TopSymbol =  1 - The plugin finds the uppermost unnamed string and sets a counter for it.\n;Repair    =  2 - The plugin goes through the whole string table and, if the indexing order is broken, puts the correct names. The counter is set on the basis of the search.\n
"},{"location":"zengin/scripts/extenders/zparserextender/daedalus_injection/other/#marvin-console-commands","title":"MARVIN console commands","text":"

zParserExtender adds console commands that save copies of the .dat files with the injected code.

Warning

If the mod uses Ikarus, the CompileDat option (in the .ini file) should be used since a fatal error may occur when using the command.

Parser SaveDat OU        - exports OU.Edited.bin\nParser SaveDat Game      - exports Gothic.Edited.dat\nParser SaveDat SFX       - exports SFX.Edited.dat\nParser SaveDat PFX       - exports ParticleFX.Edited.dat\nParser SaveDat VFX       - exports VisualFX.Edited.dat\nParser SaveDat Camera    - exports Camera.Edited.dat\nParser SaveDat Menu      - exports Menu.Edited.dat\nParser SaveDat Music     - exports Music.Edited.dat\nParser Export Stringlist - exports the full string table to Scripts\\Exports\\StringList.d\n
"},{"location":"zengin/scripts/extenders/zparserextender/daedalus_injection/other/#launch-options","title":"Launch options","text":"

Command line parameters can be passed to the game's exe via the command line or using GothicStarter_Mod.

zReparse_OU     - parses and creates OU.bin\nzReparse_Game   - parses and creates Gothic.dat\nzReparse_SFX    - parses and creates SFX.dat\nzReparse_PFX    - parses and creates ParticleFX.dat\nzReparse_VFX    - parses and creates VisualFX.dat\nzReparse_Camera - parses and creates Camera.dat\nzReparse_Menu   - parses and creates Menu.dat\nzReparse_Music  - parses and creates Music.dat\n

Note

If you want to compile OU, you also have to include the Game parameter

-zReparse_Game -zReparse_OU

"},{"location":"zengin/scripts/extenders/zparserextender/daedalus_injection/other/#const-array-access","title":"Const array access","text":"

The original zParser doesn't allow direct access to const string arrays. zParserExtender allows you to do so.

Example:

func event GameInit()\n{\n    Hlp_MessageBox(TXT_INV_CAT[4]); // Prints \"Artifacts\"\n};\n
"},{"location":"zengin/scripts/extenders/zparserextender/daedalus_injection/other/#other-engine-fixes","title":"Other engine fixes","text":"
  1. When creating an item instance, the instance is placed into the global item instance
  2. On DAT file load, the engine restores the original symbol hierarchy
  3. When loading a save, the engine now skips unknown symbols, instead of crashing
"},{"location":"zengin/scripts/extenders/zparserextender/examples/signposts/","title":"Sign post teleportation","text":""},{"location":"zengin/scripts/extenders/zparserextender/examples/signposts/#sign-post-teleportation","title":"Sign post teleportation","text":"

This is a short \"problem-solving\" example, where we try to demonstrate the power of Daedalus injection using zParserExtender. GaroK asked me if there is a way to teleport to all the sign posts in Khorinis to gather information for a Gothic wiki article. The goal is to introduce a function that will teleport you to every signpost in Khorinis with the press of a button.

"},{"location":"zengin/scripts/extenders/zparserextender/examples/signposts/#the-problem","title":"The problem","text":"

In ZenGin you can teleport to named game objects with the goto vob {vobname} command. But since the signposts do not have a vobname defined, I had to figure out a different approach.

"},{"location":"zengin/scripts/extenders/zparserextender/examples/signposts/#ascii-zen","title":"ASCII ZEN","text":"

We want to get all the signposts position from Khorinis. The game world was loaded into one of the available world editor, I found one of the signposts and noted the visual which dictates the model of the in-game object nw_misc_sign_01.3DS. Alternatively, you can find the standard vanilla objects from both games on this website. Next, the world was saved as a ASCII ZEN format. This allows us to write a macro to search for all instances of objects with a specific visual and extract the position vector.

One signpost object
[% oCMOB:zCVob 47105 317]\n    pack=int:0\n    presetName=string:\n    bbox3DWS=rawFloat:7564.8291 127.361191 -80.5309067 7611.52441 377.422913 1.67681122 \n    trafoOSToWSRot=raw:73e1673f9c4ec33b15efd8be4465d7bba0fe7f3f30ea7137e5edd83eecaa353bb7e2673f\n    trafoOSToWSPos=vec3:7588.17627 252.391052 -39.4283791\n    vobName=string:\n    visual=string:NW_MISC_SIGN_01.3DS\n    showVisual=bool:1\n    visualCamAlign=enum:0\n    visualAniMode=enum:0\n    visualAniModeStrength=float:0\n    vobFarClipZScale=float:1\n    cdStatic=bool:1\n    cdDyn=bool:1\n    staticVob=bool:1\n    dynShadow=enum:0\n    zbias=int:0\n    isAmbient=bool:0\n    [visual zCProgMeshProto 53505 318]\n    []\n    [ai % 0 0]\n    []\n    focusName=string:MOBNAME_INCITY02\n    hitpoints=int:10\n    damage=int:0\n    moveable=bool:0\n    takeable=bool:0\n    focusOverride=bool:0\n    soundMaterial=enum:0\n    visualDestroyed=string:\n    owner=string:\n    ownerGuild=string:\n    isDestroyed=bool:0\n[]\n

Tip

You can also see that the focusName has a MOBNAME_INCITY02 string constant. This constant is defined in the scripts and its content is used as the focus name.

const string MOBNAME_INCITY02 = \"To Marketplace\";\n
"},{"location":"zengin/scripts/extenders/zparserextender/examples/signposts/#the-injectable-script","title":"The injectable script","text":"

As it is an injectable script, we have to specify the META tag. Lets tell zParserExtender to insert this code into the game parser.

META\n{\n    Parser = Game\n};\n
We want to teleport the player and for this we will need the C_Position and C_Vob_Data classes.
class C_Position\n{\n    var int X; // X coordinate\n    var int Y; // Y coordinate\n    var int Z; // Z coordinate\n};\n\nclass C_VOB_DATA\n{\n    var string Name;              // object name\n    var float VisualAlpha;        // object's transparency 0.0 - 1.0\n    var int ShowVisual;           // display the mode\n    var int DrawBBox3D;           // show objects bounding box\n    var int VisualAlphaEnabled;   // enables objects transparency\n    var int PhysicsEnabled;       // enables object's physics\n    var int IgnoredByTraceRay;    // allow any object collisions\n    var int CollDetectionStatic;  // allow collision with static world polygons\n    var int CollDetectionDynamic; // allow collision with dynamic world objects\n    var int CastDynShadow;        // display shadow of the object\n    var int LightColorStatDirty;  // allow static lighting of the object\n    var int LightColorDynDirty;   // allow dynamic lighting of the object\n    var int SleepingMode;         // sets object's activity mode (0 - inactive, 1 - active, 2 - AI only)\n    var int DontWriteIntoArchive; // turns of the serialization of this object to the save file \n};\n
It turns out there is 54 instances of objects with the desired visual. Let us define const int NUM_OF_SIGNS = 54 and a const int MAX_COORDS = 3 * NUM_OF_SIGNS - we will store 3 times 54 integers - for every signpost a x, y and z coordinate. And lastly a const int array containing all the positions.
// Number of signs we want to jump to\nconst int NUM_OF_SIGNS = 54;\nconst int MAX_COORDS = 3 * NUM_OF_SIGNS;\n\nconst int sign_coordinates[MAX_COORDS] = {\n    11974,  309,   6815,\n    12024,  310,   6778,\n    12411,  1668,  -22495,\n    19491,  1281,  1669,\n    19563,  1281,  1687,\n    20294,  2058,  12487,\n    20324,  2058,  12419,\n    21917,  2900,  -22751,\n    2600,   -57,   -4351,\n    26695,  2419,  4308,\n    26770,  2418,  4319,\n    26978,  2937,  6130,\n    27015,  2936,  6104,\n    27049,  2937,  6159,\n    2964,   2142,  14424,\n    31383,  3896,  4699,\n    31427,  3896,  4640,\n    35368,  3870,  -4374,\n    35435,  3870,  -4355,\n    35437,  3871,  -4399,\n    36205,  3333,  -27186,\n    37774,  3875,  -501,\n    37812,  3874,  -469,\n    37849,  3874,  -512,\n    38291,  3732,  -6699,\n    39276,  3926,  -3357,\n    39307,  3924,  -3313,\n    39351,  3924,  -3359,\n    39435,  4350,  10902,\n    39458,  4350,  10827,\n    40932,  3861,  -3054,\n    42454,  2838,  -19437,\n    5297,   387,   -2145,\n    5358,   387,   -2184,\n    5362,   387,   -2128,\n    54006,  1723,  -10316,\n    54035,  1723,  -10387,\n    551,    -62,   -1820,\n    61080,  2132,  -11622,\n    61155,  2132,  -11625,\n    6408,   392,   3598,\n    6432,   393,   3652,\n    7000,   387,   -1482,\n    73439,  3341,  -11307,\n    7588,   252,   -39,\n    7590,   252,   -109,\n    7642,   253,   -83,\n    7713,   387,   -4782,\n    7758,   386,   -4775,\n    7776,   388,   -4811,\n    8154,   1206,  -17022,\n    8855,   395,   -2402,\n    9704,   393,   5129,\n    9738,   392,   5108\n};\n
Next define a built in event GameLoop function, to check for a pressed key. If the key U is pressed, the jump_to_sign function is called.
// check for pressed U button every frame\nfunc event GameLoop()\n{\n    // if U is toggled, run the function\n    if (Hlp_KeyToggled(KEY_U))\n    {\n        jump_to_sign();\n    };\n};\n

Let's look at the jump_to_sign function now. This function is called on every U key press and goes through all the signposts and teleports the player to them. At the start of the function we check if the index is not out of bounds and if it is, sets it back to 0 and starts over.

    // if we reached the end, start over\n    if (tp_index >= NUM_OF_SIGNS)\n    {\n        tp_index = 0;\n    };\n
Notice the use of Str_Format function for the formatted output.
// give information to the player\nPrint(Str_Format(\"Sign %i/%i\", tp_index+1, NUM_OF_SIGNS));\n\nvar C_Position pos;  pos  = Vob_GetVobPosition(hero);\nvar C_Vob_Data data; data = Vob_GetVobData(hero);\n
Daedalus does not allow array access with variables (only constants and literals). To access the coordinate array we use a selection of parser functions. Firstly we get the game parser ID. Then we can use the Par_GetSymbolValueIntArray to access the sign_coordinates array and assign the coordinates to the pos variable.
// get parser ID for the GAME parser\nvar int game_par_id; game_par_id = Par_GetParserID(\"game\");\n\n// get parser ID of the array\nvar int arr_id; arr_id = Par_GetSymbolID(game_par_id ,\"sign_coordinates\");\n\n// access the coordinates from above array\npos.x = Par_GetSymbolValueIntArray(game_par_id ,arr_id ,tp_index * 3    ); \npos.y = Par_GetSymbolValueIntArray(game_par_id ,arr_id ,tp_index * 3 + 1);\npos.z = Par_GetSymbolValueIntArray(game_par_id ,arr_id ,tp_index * 3 + 2);\n
And now comes the big trick. If you try to just change the position the dynamic and static collision is going to stop you at the first wall, tree or a mountain. To disable it, we can use the C_Vob_Data helper class, get players data, and disable both the static a dynamic collision. First we create a backup of the values just so we can restore them back after the teleport.
// backup original collision detection\nvar int dyn;   dyn = data.CollDetectionDynamic;\nvar int stat; stat = data.CollDetectionStatic;\n\n// turn off collision detection \ndata.CollDetectionDynamic = 0;\ndata.CollDetectionStatic  = 0;\n
Let us apply the changed data to the player and edit the position.
// apply the edited data to player\nVob_SetVobData(hero, data);\n\n// move the player \nVob_SetVobPosition(hero, pos);\n
Restore the collision detection data from the backup we made and set it.
// restore collision detection\ndata.CollDetectionDynamic = dyn;\ndata.CollDetectionStatic  = stat;\n\n// apply the edited data to player\nVob_SetVobData(hero, data);\n
Finally, we advance the index to jump to another signpost.
// advance the index\ntp_index += 1;\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/ai/","title":"AI - functions for working with AI","text":""},{"location":"zengin/scripts/extenders/zparserextender/externals/ai/#ai---functions-for-working-with-ai","title":"AI - functions for working with AI","text":"

Functions to work with the new C_Trigger class and NPC's AI queue.

"},{"location":"zengin/scripts/extenders/zparserextender/externals/ai/#ai_callscript","title":"AI_CallScript","text":"

Adds a funcName function call to the AI queue

func void AI_CallScript(var string funcName,\n                        var C_NPC slf,\n                        var C_NPC oth) {};\n
  • funcName - name of the function to be called
  • slf - will be inserted into global self instance
  • oth - will be inserted into global other instance
"},{"location":"zengin/scripts/extenders/zparserextender/externals/ai/#ai_starttriggerscript","title":"AI_startTriggerScript","text":"

Creates a trigger script that calls function funcName once every interval in milliseconds

func C_Trigger AI_startTriggerScript(var string funcName, var int interval) {};\n
  • funcName - name of the function to be called
  • interval - call period in milliseconds
  • return - created C_Trigger instance
"},{"location":"zengin/scripts/extenders/zparserextender/externals/ai/#ai_starttriggerscriptex","title":"AI_startTriggerScriptEx","text":"

Extended version call - Creates a trigger script, that calls function funcName once every interval in milliseconds also updates the self, other and victim global instances based on slf, oth and vct parameters respectively

func C_Trigger AI_startTriggerScriptEx( var string funcName,\n                                        var int interval,\n                                        var C_NPC slf,\n                                        var C_NPC oth,\n                                        var C_NPC vct) {};\n
  • funcName - name of the function to be called
  • interval - call period in milliseconds
  • slf - will be inserted into global self instance
  • oth - will be inserted into global other instance
  • vct - will be inserted into global victim instance
  • return - created C_Trigger instance
"},{"location":"zengin/scripts/extenders/zparserextender/externals/ai/#ai_gettriggerbyid","title":"AI_GetTriggerByID","text":"

Returns a C_Trigger instance from the array of active triggers by the array index ID

func C_Trigger AI_GetTriggerByID(var int ID) {};\n
  • ID - array id
  • return - active C_Trigger instance
"},{"location":"zengin/scripts/extenders/zparserextender/externals/ai/#ai_gettriggersnum","title":"AI_GetTriggersNum","text":"

Returns the number of active C_Trigger scripts

func int AI_GetTriggersNum() {};\n
  • return - number of active C_Trigger scripts
"},{"location":"zengin/scripts/extenders/zparserextender/externals/ai/#ai_gettriggernpc","title":"AI_GetTriggerNPC","text":"

Returns the npc associated with the C_Trigger script based on the ID selfID = 0; otherID = 1; victimID = 2;

func C_NPC AI_GetTriggerNPC(var C_Trigger trigger, var int npcID) {};\n
  • trigger - C_Trigger script
  • npcID - NPC id
  • return - active C_Trigger instance
"},{"location":"zengin/scripts/extenders/zparserextender/externals/ai/#ai_gettriggerfunc","title":"AI_GetTriggerFunc","text":"

Returns the function associated with the specified C_Trigger

func func AI_GetTriggerFunc(var C_Trigger trigger) {};\n
  • trigger - C_Trigger script
  • return - trigger function
"},{"location":"zengin/scripts/extenders/zparserextender/externals/ai/#ai_gettriggerfuncname","title":"AI_GetTriggerFuncName","text":"

Returns the function name of a function associated with the specified C_Trigger

func string AI_GetTriggerFuncName(var C_Trigger trigger) {};\n
  • trigger - C_Trigger script
  • return - active C_Trigger instance
"},{"location":"zengin/scripts/extenders/zparserextender/externals/ai/#ai_getnexttriggerbyfunc","title":"Ai_GetNextTriggerByFunc","text":"

Returns the next trigger in the active trigger array based on the trigger function, starting on the startTrigger trigger

func C_Trigger Ai_GetNextTriggerByFunc(var C_Trigger startTrigger, var func function) {};\n
  • startTrigger - C_Trigger script to start the search from
  • function - function to be matched
  • return - C_Trigger instance
"},{"location":"zengin/scripts/extenders/zparserextender/externals/ai/#ai_getnexttriggerbyfuncname","title":"Ai_GetNextTriggerByFuncName","text":"

Returns the next trigger in the active trigger array based on the trigger function name, starting on the startTrigger trigger

func C_Trigger Ai_GetNextTriggerByFuncName(var C_Trigger startTrigger, var string functionName) {};\n
  • startTrigger - C_Trigger script to start the search from
  • functionName - name of a function to be matched
  • return - C_Trigger instance
"},{"location":"zengin/scripts/extenders/zparserextender/externals/ai/#ai_getnexttriggerbyself","title":"Ai_GetNextTriggerBySelf","text":"

Returns the next trigger in the active trigger array based on the self trigger parameter, starting on the startTrigger instance set in the trigger

func C_Trigger Ai_GetNextTriggerBySelf(var C_Trigger startTrigger, var C_NPC self) {};\n
  • startTrigger - C_Trigger script to start the search from
  • self - C_NPC instance
  • return - C_Trigger instance
"},{"location":"zengin/scripts/extenders/zparserextender/externals/ai/#ai_getnexttriggerbyother","title":"Ai_GetNextTriggerByOther","text":"

Returns the next trigger in the active trigger array based on the other trigger parameter, starting on the startTrigger instance set in the trigger

func C_Trigger Ai_GetNextTriggerByOther(var C_Trigger startTrigger, var C_NPC other) {};\n
  • startTrigger - C_Trigger script to start the search from
  • other - C_NPC instance
  • return - C_Trigger instance
"},{"location":"zengin/scripts/extenders/zparserextender/externals/ai/#ai_getnexttriggerbyvictim","title":"Ai_GetNextTriggerByVictim","text":"

Returns the next trigger in the active trigger array based on the victim trigger parameter, starting on the startTrigger instance set in the trigger

func C_Trigger Ai_GetNextTriggerByVictim( var C_Trigger startTrigger, var C_NPC victim ) {};\n
  • startTrigger - C_Trigger script to start the search from
  • victim - C_NPC instance
  • return - C_Trigger instance
"},{"location":"zengin/scripts/extenders/zparserextender/externals/ai/#ai_getnexttriggerbynpcs","title":"Ai_GetNextTriggerByNPCs","text":"

Returns the next trigger in the active trigger array based on all the NPCs set in the trigger script self, other and victim, starting on the startTrigger instance set in the trigger

func c_trigger Ai_GetNextTriggerByNPCs( var C_Trigger startTrigger,\n                                        var C_NPC self,\n                                        var C_NPC other,\n                                        var C_NPC victim) {};\n
  • startTrigger - C_Trigger script to start the search from
  • self - self C_NPC instance
  • other - other C_NPC instance
  • victim - victim C_NPC instance
  • return - C_Trigger instance
"},{"location":"zengin/scripts/extenders/zparserextender/externals/cast/","title":"CAST - data type conversion functions","text":""},{"location":"zengin/scripts/extenders/zparserextender/externals/cast/#cast---data-type-conversion-functions","title":"CAST - data type conversion functions","text":"

External functions for data type conversion and pointer casting.

"},{"location":"zengin/scripts/extenders/zparserextender/externals/cast/#cast_pointertoinstance","title":"Cast_PointerToInstance","text":"

Converts memory address (pointer) to an instance

func instance Cast_PointerToInstance(var int address) {};\n
  • address - object pointer
  • return - instance of the object
"},{"location":"zengin/scripts/extenders/zparserextender/externals/cast/#cast_instancetopointer","title":"Cast_InstanceToPointer","text":"

Converts instance to a memory address (pointer)

func int Cast_InstanceToPointer( var instance object) {};\n
  • object - object instance
  • return - memory address (pointer) of the object
"},{"location":"zengin/scripts/extenders/zparserextender/externals/cast/#cast_pointertonpc","title":"Cast_PointerToNpc","text":"

Casts memory address (pointer) to an NPC

func C_NPC Cast_PointerToNpc( var int address) {};\n
  • address - npc pointer
  • return - NPC instance
"},{"location":"zengin/scripts/extenders/zparserextender/externals/cast/#cast_pointertoitem","title":"Cast_PointerToItem","text":"

Casts memory address (pointer) to an Item

func C_ITEM Cast_PointerToItem( var int address) {};\n
  • address - item pointer
  • return - Item instance
"},{"location":"zengin/scripts/extenders/zparserextender/externals/cast/#cast_instanceisnpc","title":"Cast_InstanceIsNpc","text":"

Checks whether object is an NPC

func int Cast_InstanceIsNpc( var instance object) {};\n
  • object - object to check
  • return - TRUE or FALSE
"},{"location":"zengin/scripts/extenders/zparserextender/externals/cast/#cast_instanceisitem","title":"Cast_InstanceIsItem","text":"

Checks whether object is an Item

func int Cast_InstanceIsItem( var instance object) {};\n
  • object - object to check
  • return - TRUE or FALSE
"},{"location":"zengin/scripts/extenders/zparserextender/externals/cast/#cast_instanceismob","title":"Cast_InstanceIsMob","text":"

Checks whether object is an MOB

func int Cast_InstanceIsMob( var instance object) {};\n
  • object - object to check
  • return - TRUE or FALSE
"},{"location":"zengin/scripts/extenders/zparserextender/externals/cast/#cast_getinstanceindex","title":"Cast_GetInstanceIndex","text":"

Returns symbolID of the object, returns -1 when not found

func int Cast_GetInstanceIndex( var instance object) {};\n
  • object - instance of an object
  • return - symbol table index, -1 when not found
"},{"location":"zengin/scripts/extenders/zparserextender/externals/cast/#cast_getclassid","title":"Cast_GetClassID","text":"

Returns the class identifier of a class by its name

func int Cast_GetClassID( var string className ) {};\n
  • className - name of the class
  • return - class identifier
"},{"location":"zengin/scripts/extenders/zparserextender/externals/cast/#cast_getvobclassid","title":"Cast_GetVobClassID","text":"

Returns class identifier of the zCObject vob class

func int Cast_GetVobClassID( var instance object ) {};\n
  • object - object instance
  • return - class zCObject identifier
"},{"location":"zengin/scripts/extenders/zparserextender/externals/cast/#cast_checkvobclassid","title":"Cast_CheckVobClassID","text":"

Checks if the classId class is the parent class of the object

func int Cast_CheckVobClassID( var int classId, var instance object ) {};\n
  • classId - class identifier, from Cast_GetClassID function
  • object - object instance
  • return - class zCObject identifier
"},{"location":"zengin/scripts/extenders/zparserextender/externals/events_vars/","title":"Event functions and variables","text":""},{"location":"zengin/scripts/extenders/zparserextender/externals/events_vars/#event-functions-and-variables","title":"Event functions and variables","text":"

On top of external functions, zParserExtender also adds these event functions and constants.

/// Every event function with this name is executed once every frame\nfunc event GameLoop() {};\n\n/// Every event function with this name is executed once on game init\nfunc event GameInit() {};\n\n/// empty instance\nconst instance null;\n\n/// not a number floating point constant\nconst float NaN;\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/hlp/","title":"HLP - help functions","text":""},{"location":"zengin/scripts/extenders/zparserextender/externals/hlp/#hlp---help-functions","title":"HLP - help functions","text":"

Helper functions generally used for safety checks, to get specific information from the engine or to interface with the configuration .ini files.

"},{"location":"zengin/scripts/extenders/zparserextender/externals/hlp/#hlp_hasfocusvob","title":"Hlp_HasFocusVob","text":"

Returns TRUE, if a specified NPC has a Vob in focus

func int Hlp_HasFocusVob( var C_NPC npc ) {};\n
  • npc - NPC
  • return - TRUE if npc has a focus Vob, FALSE if it does not
"},{"location":"zengin/scripts/extenders/zparserextender/externals/hlp/#hlp_getfocusvob","title":"Hlp_GetFocusVob","text":"

Returns NPC's focus Vob

func instance Hlp_GetFocusVob( var C_NPC npc ) {};\n
  • npc - NPC
  • return - focus vob
"},{"location":"zengin/scripts/extenders/zparserextender/externals/hlp/#hlp_getfocusvobname","title":"Hlp_GetFocusVobName","text":"

Returns the name of NPC's focus vob

func string Hlp_GetFocusVobName( var C_NPC npc ) {};\n
  • npc - NPC
  • return - focus vob name
"},{"location":"zengin/scripts/extenders/zparserextender/externals/hlp/#hlp_getstringlength","title":"Hlp_GetStringLength","text":"

Returns the length of a specified string

func int Hlp_GetStringLength( var string str ) {};\n
  • return - length of str
"},{"location":"zengin/scripts/extenders/zparserextender/externals/hlp/#isnan","title":"IsNAN","text":"

Checks whether floating point number is valid

func int IsNAN( var float value ) {};\n
  • return - TRUE if value is NaN, FALSE if value is a valid floating point number
"},{"location":"zengin/scripts/extenders/zparserextender/externals/hlp/#hlp_keytoggled","title":"Hlp_KeyToggled","text":"

Checks whether key is toggled

func int Hlp_KeyToggled( var int key ) {};\n
  • key - key code
  • return - TRUE if key is toggled, FALSE if key is not toggled
"},{"location":"zengin/scripts/extenders/zparserextender/externals/hlp/#hlp_keypressed","title":"Hlp_KeyPressed","text":"

Checks whether key is pressed

func int Hlp_KeyPressed( var int key ) {};\n
  • key - key code
  • return - TRUE if key is pressed, FALSE if key is not pressed
"},{"location":"zengin/scripts/extenders/zparserextender/externals/hlp/#hlp_logicalkeytoggled","title":"Hlp_LogicalKeyToggled","text":"

Checks whether logical key is toggled

func int Hlp_LogicalKeyToggled( var int key ) {};\n
  • key - key code
  • return - TRUE if key is toggled, FALSE if key is not toggled
"},{"location":"zengin/scripts/extenders/zparserextender/externals/hlp/#hlp_gameonpause","title":"Hlp_GameOnPause","text":"

Checks whether the game is paused

func int Hlp_GameOnPause() {};\n
  • return - TRUE if the game is paused, FALSE if the game is not paused
"},{"location":"zengin/scripts/extenders/zparserextender/externals/hlp/#hlp_messagebox","title":"Hlp_MessageBox","text":"

Opens a message box with a specified message

func void Hlp_MessageBox( var string message ) {};\n
  • message - message to be printed
"},{"location":"zengin/scripts/extenders/zparserextender/externals/hlp/#hlp_printconsole","title":"Hlp_PrintConsole","text":"

Prints a message to the Union debug console

func void Hlp_PrintConsole(var string message) {};\n
  • message - message to be printed
"},{"location":"zengin/scripts/extenders/zparserextender/externals/hlp/#hlp_optionisexists","title":"Hlp_OptionIsExists","text":"

Checks whether the entry in section in .ini file optName exists

optName values

  • \"Gothic\"
  • \"Mod\"
  • \"SystemPack\"
func int Hlp_OptionIsExists(var string optName, var string section, var string entry) {};\n
  • optName - the .ini file
  • section - settings section like [GAME]
  • entry - one setting entry like playLogoVideos
  • return - TRUE if the option exists, FALSE if the option does not exist
"},{"location":"zengin/scripts/extenders/zparserextender/externals/hlp/#hlp_readoptionint","title":"Hlp_ReadOptionInt","text":"

Read an integer value from specified .ini file, section and entry.

optName values

  • \"Gothic\"
  • \"Mod\"
  • \"SystemPack\"
func int Hlp_ReadOptionInt(var string optName, var string section, var string entry, var int default) {};\n
  • optName - the .ini file
  • section - settings section like [GAME]
  • entry - one setting entry like playLogoVideos
  • default - default value - if the value is empty
  • return - the option value
"},{"location":"zengin/scripts/extenders/zparserextender/externals/hlp/#hlp_readoptionfloat","title":"Hlp_ReadOptionFloat","text":"

Read a floating point value from specified .ini file, section and entry.

optName values

  • \"Gothic\"
  • \"Mod\"
  • \"SystemPack\"
func float Hlp_ReadOptionFloat(var string optName, var string section, var string entry, var float default) {};\n
  • optName - the .ini file
  • section - settings section like [INTERFACE]
  • entry - one setting entry like scale
  • default - default value - if the value is empty
  • return - the option value
"},{"location":"zengin/scripts/extenders/zparserextender/externals/hlp/#hlp_readoptionstring","title":"Hlp_ReadOptionString","text":"

Read a string value from specified .ini file, section and entry.

optName values

  • \"Gothic\"
  • \"Mod\"
  • \"SystemPack\"
func string Hlp_ReadOptionString(var string optName, var string section, var string entry, var string default) {};\n
  • optName - the .ini file
  • section - settings section like [INTERFACE]
  • entry - one setting entry like scale
  • default - default value - if the value is empty
  • return - the option value
"},{"location":"zengin/scripts/extenders/zparserextender/externals/hlp/#hlp_writeoptionint","title":"Hlp_WriteOptionInt","text":"

Writes an integer value to specified .ini file, section and entry.

optName values

  • \"Gothic\"
  • \"Mod\"
  • \"SystemPack\"
func void Hlp_WriteOptionInt(var string optName, var string section, var string entry, var int value) {};\n
  • optName - the .ini file
  • section - settings section like [INTERFACE]
  • entry - one setting entry like scale
  • value - value to be written
"},{"location":"zengin/scripts/extenders/zparserextender/externals/hlp/#hlp_writeoptionfloat","title":"Hlp_WriteOptionFloat","text":"

Writes a floating point value to specified .ini file, section and entry.

optName values

  • \"Gothic\"
  • \"Mod\"
  • \"SystemPack\"
func void Hlp_WriteOptionFloat(var string optName, var string section, var string entry, var float value) {};\n
  • optName - the .ini file
  • section - settings section like [INTERFACE]
  • entry - one setting entry like scale
  • value - value to be written
"},{"location":"zengin/scripts/extenders/zparserextender/externals/hlp/#hlp_writeoptionstring","title":"Hlp_WriteOptionString","text":"

Writes a string value to specified .ini file, section and entry.

optName values

  • \"Gothic\"
  • \"Mod\"
  • \"SystemPack\"
func void Hlp_WriteOptionString(var string optName, var string section, var string entry, var string value) {};\n
  • optName - the .ini file
  • section - settings section like [INTERFACE]
  • entry - one setting entry like scale
  • value - value to be written
"},{"location":"zengin/scripts/extenders/zparserextender/externals/hlp/#hlp_getsteampersonalname","title":"Hlp_GetSteamPersonalName","text":"

Returns the name of the current Steam user Returns empty string when not run with Steam

func string Hlp_GetSteamPersonalName() {};\n
  • return - string containing the Steam username, or an empty string
"},{"location":"zengin/scripts/extenders/zparserextender/externals/hlp/#hlp_doevent","title":"Hlp_DoEvent","text":"

Calls every event function with the name funcName.

func void Hlp_DoEvent(var string funcName) {};\n
  • funcName - name of the event function to be called (all of them).
"},{"location":"zengin/scripts/extenders/zparserextender/externals/log/","title":"Log functions","text":""},{"location":"zengin/scripts/extenders/zparserextender/externals/log/#log-functions","title":"Log functions","text":"

As discussed on Inside Gothic, vanilla Gothic has no way of getting the status of a quest. These functions implement that functionality.

"},{"location":"zengin/scripts/extenders/zparserextender/externals/log/#log_gettopicstatus","title":"Log_GetTopicStatus","text":"

Returns the status of diary topic

  • -1 - Not found
  • 0 - Free
  • 1 - Running
  • 2 - Success
  • 3 - Failure
  • 4 - Obsolete
func int Log_GetTopicStatus(var string topic) {};\n
  • topic - name of the topic
  • return - topic status
"},{"location":"zengin/scripts/extenders/zparserextender/externals/log/#log_gettopicsection","title":"Log_GetTopicSection","text":"

Returns the topic the diary topic is in

  • -1 - Not found
  • 0 - Missions
  • 1 - Notes
  • 2 - All
func int Log_GetTopicSection(var string topic) {};\n
  • topic - name of the topic
  • return - topic section
"},{"location":"zengin/scripts/extenders/zparserextender/externals/mdl/","title":"MDL - model functions","text":""},{"location":"zengin/scripts/extenders/zparserextender/externals/mdl/#mdl---model-functions","title":"MDL - model functions","text":"

Functions to tweak animation and other model related settings.

"},{"location":"zengin/scripts/extenders/zparserextender/externals/mdl/#mdl_getanimationindex","title":"Mdl_GetAnimationIndex","text":"

Returns animation's index for specified NPC based on animation's name

func int Mdl_GetAnimationIndex( var C_NPC npc, var string ani_name ) {};\n
  • npc - NPC with the animation
  • ani_name - name of the animation in uppercase
  • return - animation index
"},{"location":"zengin/scripts/extenders/zparserextender/externals/mdl/#mdl_getanimationname","title":"Mdl_GetAnimationName","text":"

Returns animation's name for specified NPC based on animation's index

func string Mdl_GetAnimationName( var C_NPC npc, var int ani_index ) {};\n
  • npc - NPC with the animation
  • ani_index - animation index
  • return - animation name
"},{"location":"zengin/scripts/extenders/zparserextender/externals/mdl/#mdl_animationisexists","title":"Mdl_AnimationIsExists","text":"

Checks whether animation exists

func int Mdl_AnimationIsExists( var C_NPC npc, var int ani_index ) {};\n
  • npc - NPC with the animation
  • ani_index - animation index
  • return - animation name
"},{"location":"zengin/scripts/extenders/zparserextender/externals/mdl/#mdl_animationisactive","title":"Mdl_AnimationIsActive","text":"

Checks whether animation is active (whether it is currently played)

func int Mdl_AnimationIsActive( var C_NPC npc, var int ani_index ) {};\n
  • npc - NPC with the animation
  • ani_index - animation index
  • return - TRUE if the animation is playing, FALSE if it is not playing
"},{"location":"zengin/scripts/extenders/zparserextender/externals/mdl/#mdl_setallanimationsfps","title":"Mdl_SetAllAnimationsFPS","text":"

Set framerate for all animations

func void Mdl_SetAllAnimationsFPS( var C_NPC npc, var float fps ) {};\n
  • npc - NPC with the animation
  • fps - framerate
"},{"location":"zengin/scripts/extenders/zparserextender/externals/mdl/#mdl_resetallanimationsfps","title":"Mdl_ResetAllAnimationsFPS","text":"

Reset framerate for all animations to default value

func void Mdl_ResetAllAnimationsFPS( var C_NPC npc ) {};\n
  • npc - NPC with the animation
"},{"location":"zengin/scripts/extenders/zparserextender/externals/mdl/#mdl_setanimationfps","title":"Mdl_SetAnimationFPS","text":"

Set framerate for animation specified by animation index

func void Mdl_SetAnimationFPS( var C_NPC npc, var int ani_index, var float fps ) {};\n
  • npc - NPC with the animation
  • ani_index - animation index
  • fps - framerate
"},{"location":"zengin/scripts/extenders/zparserextender/externals/mdl/#mdl_resetanimationfps","title":"Mdl_ResetAnimationFPS","text":"

Reset framerate to default for animation specified by animation index

func void Mdl_ResetAnimationFPS( var C_NPC npc, var int ani_index ) {};\n
  • npc - NPC with the animation
  • ani_index - animation index
"},{"location":"zengin/scripts/extenders/zparserextender/externals/mdl/#mdl_setvisible","title":"Mdl_SetVisible","text":"

Set NPCs visibility

func void Mdl_SetVisible( var C_NPC npc, var int isVisible ) {};\n
  • npc - specified NPC
  • isVisible - TRUE - visible, FALSE - invisible
"},{"location":"zengin/scripts/extenders/zparserextender/externals/mdl/#mdl_applyoverlaymds_atfirst","title":"Mdl_ApplyOverlayMds_AtFirst","text":"

Applies or moves existing overlay to the top of the list

func void Mdl_ApplyOverlayMds_AtFirst( var string mdsName ) {};\n
  • mdsName - name of the overlay
"},{"location":"zengin/scripts/extenders/zparserextender/externals/mdl/#mdl_setnpcspeedmultiplier","title":"Mdl_SetNpcSpeedMultiplier","text":"

Sets a multiplier for animation speed 1.0 = 100% speed (normal speed)

func void Mdl_SetNpcSpeedMultiplier( var C_Npc npc, var float multiplier ) {};\n
  • npc - npc to be affected
  • multiplier - speed of the animation
"},{"location":"zengin/scripts/extenders/zparserextender/externals/mdl/#mdl_resetnpcspeedmultiplier","title":"Mdl_ResetNpcSpeedMultiplier","text":"

Resets the animation speed of an NPC

func void Mdl_ResetNpcSpeedMultiplier( var C_Npc npc ) {};\n
  • npc - npc to be affected
"},{"location":"zengin/scripts/extenders/zparserextender/externals/menu/","title":"Menu function","text":""},{"location":"zengin/scripts/extenders/zparserextender/externals/menu/#menu-function","title":"Menu function","text":""},{"location":"zengin/scripts/extenders/zparserextender/externals/menu/#menu_searchitems","title":"Menu_SearchItems","text":"

Find all C_MenuItem object instances by the mask and automatically places them in the current menu instance

func void Menu_SearchItems( var string mask ) {};\n
  • mask - regex like mask for searching
"},{"location":"zengin/scripts/extenders/zparserextender/externals/menu/#example","title":"Example","text":"

This function is used in the Union Menu API script. In this script the Menu_SearchItems external is used to collect all Union menu scripts that are placed into the Union & Plugins menu that will appear in the game if you use any of the plugins that use this feature.

Usage of Menu_SearchItems external function
instance MENU_OPT_UNION(C_MENU_DEF)\n{\n    Menu_SearchItems(\"MENUITEM_UNION_AUTO_*\");\n    MENU_OPT_UNION_PY = 1200;\n    backpic           = MENU_BACK_PIC;\n    items[0]          = \"UNION_MENUITEM_TITLE\";\n    items[100]        = \"UNION_MENUITEM_BACK\";\n    defaultoutgame    = 0;\n    defaultingame     = 0;\n    Flags             = Flags | MENU_SHOW_INFO;\n};\n

In this case all instances are of the name MENUITEM_UNION_AUTO_* where * is a wildcard that can be substituted with anything. The plugin will search the scripts and find all instances (in the case of zGamePad it is MenuItem_Union_Auto_zGamePad)

This example comes from the zUnionMenu.d injectable API script that is part of the zGamePad plugin, GitHub link.

"},{"location":"zengin/scripts/extenders/zparserextender/externals/mob/","title":"MOB - interactive object functions","text":""},{"location":"zengin/scripts/extenders/zparserextender/externals/mob/#mob---interactive-object-functions","title":"MOB - interactive object functions","text":"

Functions to manipulate interactive objects like destroying MOBs, setting lockpick combination and such.

"},{"location":"zengin/scripts/extenders/zparserextender/externals/mob/#mob_destroy","title":"Mob_Destroy","text":"

Marks oCMOB as destroyed, changes the visual to visualDestroyed (if present).

func void Mob_Destroy( var instance object ) {};\n
  • object - oCMOB to be destroyed
"},{"location":"zengin/scripts/extenders/zparserextender/externals/mob/#mob_removeitem","title":"Mob_RemoveItem","text":"

Removes an item from a oCMobContainer

func void Mob_RemoveItem( var instance object, var int item ) {};\n
  • object - oCMobContainer object
  • item - item to be removed
"},{"location":"zengin/scripts/extenders/zparserextender/externals/mob/#mob_removeitems","title":"Mob_RemoveItems","text":"

Removes specified number of items from a oCMobContainer

func void Mob_RemoveItems( var instance object, var int item, var int cnt ) {};\n
  • object - oCMobContainer object
  • item - item to be removed
  • cnt - number of items to be removed
"},{"location":"zengin/scripts/extenders/zparserextender/externals/mob/#mob_insertitem","title":"Mob_InsertItem","text":"

Inserts an item into a oCMobContainer

func void Mob_InsertItem( var instance object, var int item ) {};\n
  • object - oCMobContainer object
  • item - item to be inserted
"},{"location":"zengin/scripts/extenders/zparserextender/externals/mob/#mob_insertitems","title":"Mob_InsertItems","text":"

Inserts specified number of items into a oCMobContainer

func void Mob_InsertItems( var instance object, var int item, var int cnt ) {};\n
  • object - oCMobContainer object
  • item - item to be inserted
  • cnt - number of items to be inserted
"},{"location":"zengin/scripts/extenders/zparserextender/externals/mob/#mob_getlockcombination","title":"Mob_GetLockCombination","text":"

Returns a lock combination of a oCMobContainer

func string Mob_GetLockCombination( var instance object ) {};\n
  • object - oCMobContainer object
  • return - lock combination
"},{"location":"zengin/scripts/extenders/zparserextender/externals/mob/#mob_setlockcombination","title":"Mob_SetLockCombination","text":"

Sets a lock combination to a oCMobContainer

func void Mob_SetLockCombination( var instance object, var string comb ) {};\n
  • object - oCMobContainer object
  • comb - lock combination
"},{"location":"zengin/scripts/extenders/zparserextender/externals/mob/#mob_islocked","title":"Mob_IsLocked","text":"

Returns TRUE if the object is locked

func int Mob_IsLocked( var instance object ) {};\n
  • object - oCMobLockable object
  • return - TRUE if locked, FALSE if unlocked
"},{"location":"zengin/scripts/extenders/zparserextender/externals/mob/#mob_setlocked","title":"Mob_SetLocked","text":"

Set the lock status of the object

func void Mob_SetLocked( var instance object, var int locked ) {};\n
  • object - oCMobLockable object
  • locked - lock or unlock the object
"},{"location":"zengin/scripts/extenders/zparserextender/externals/mob/#mob_getkeyinstance","title":"Mob_GetKeyInstance","text":"

Returns the key instance, that unlocks the object

func instance Mob_GetKeyInstance( var instance object ) {};\n
  • object - oCMobLockable object
  • return - the key C_ITEM instance
"},{"location":"zengin/scripts/extenders/zparserextender/externals/mob/#mob_setkeyinstance","title":"Mob_SetKeyInstance","text":"

Stets the key instance, that unlocks the object

func void Mob_SetKeyInstance( var instance object, var int key ) {};\n
  • object - oCMobLockable object
  • key - the key C_ITEM instance
"},{"location":"zengin/scripts/extenders/zparserextender/externals/npc/","title":"NPC - character functions","text":""},{"location":"zengin/scripts/extenders/zparserextender/externals/npc/#npc---character-functions","title":"NPC - character functions","text":"

NPC related functions.

"},{"location":"zengin/scripts/extenders/zparserextender/externals/npc/#npc_setashero","title":"Npc_SetAsHero","text":"

Changes players character to specified npc

func void Npc_SetAsHero( var C_NPC npc ) {};\n
  • npc - NPC to be set as players character
"},{"location":"zengin/scripts/extenders/zparserextender/externals/npc/#npc_openinventory","title":"Npc_OpenInventory","text":"

Opens NPCs main inventory

func void Npc_OpenInventory( var C_NPC npc ) {};\n
  • npc - NPC
"},{"location":"zengin/scripts/extenders/zparserextender/externals/npc/#npc_openinventorysteal","title":"Npc_OpenInventorySteal","text":"

Opens the steal inventory of npc's focus NPC

func void Npc_OpenInventorySteal( var C_NPC npc ) {};\n
  • npc - NPC
"},{"location":"zengin/scripts/extenders/zparserextender/externals/npc/#npc_openinventorytrade","title":"Npc_OpenInventoryTrade","text":"

Start the trading dialogue with specified NPC

func void Npc_OpenInventoryTrade( var C_NPC npc ) {};\n
  • npc - NPC
"},{"location":"zengin/scripts/extenders/zparserextender/externals/npc/#npc_getlefthanditem","title":"Npc_GetLeftHandItem","text":"

Returns an item in NPC's left hand slot

func C_Item Npc_GetLeftHandItem( var C_Npc npc ) {};\n
  • npc - npc to be affected
  • return - found C_ITEM instance
"},{"location":"zengin/scripts/extenders/zparserextender/externals/npc/#npc_getrighthanditem","title":"Npc_GetRightHandItem","text":"

Returns an item in NPC's right hand slot

func C_Item Npc_GetRightHandItem( var C_Npc npc ) {};\n
  • npc - npc to be affected
  • return - found C_ITEM instance
"},{"location":"zengin/scripts/extenders/zparserextender/externals/npc/#npc_getslotitem","title":"Npc_GetSlotItem","text":"

Returns an item from a slot with the slotName

func C_Item Npc_GetSlotItem( var C_Npc npc, var string slotName ) {};\n
  • npc - npc to be affected
  • slotName - name of the slot
  • return - found C_ITEM instance
"},{"location":"zengin/scripts/extenders/zparserextender/externals/npc/#npc_putinslot","title":"Npc_PutInSlot","text":"

Places an instance of the oCVom class (including items and NPCs) object into the slotName of the NPC The copyInInv parameter determines whether a copy of the object should remain in the character's inventory

func void Npc_PutInSlot(var C_Npc npc, var string slotName, var instance object, var int copyInInv) {};\n
  • npc - npc to remove the item from
  • slotName - name of the slot from which to remove the item
  • object - object to be inserted into the slot
  • copyInInv - should a copy of the object stay in character inventory
"},{"location":"zengin/scripts/extenders/zparserextender/externals/npc/#npc_removefromslot","title":"Npc_RemoveFromSlot","text":"

Removes an object from the slotName of the NPC. The dropIt parameter in Gothic 2 defines, whether object should drop out of the slot. In Gothic 1, this parameter is reserved and must be 0.

func void Npc_RemoveFromSlot(var C_Npc npc, var string slotName, var int dropIt) {};\n
  • npc - npc to remove the item from
  • slotName - name of the slot from which to remove the item
  • dropIt - should the object be dropped
"},{"location":"zengin/scripts/extenders/zparserextender/externals/par/","title":"PAR - functions for parser manipulation","text":""},{"location":"zengin/scripts/extenders/zparserextender/externals/par/#par---functions-for-parser-manipulation","title":"PAR - functions for parser manipulation","text":"

Parser functions are used to manipulate the parsers. Retrieve SymbolID, access arrays and such.

"},{"location":"zengin/scripts/extenders/zparserextender/externals/par/#par_getparserid","title":"Par_GetParserID","text":"

Returns a parser ID of the parser with a parName name

Parser names:

  • \"Game\"
  • \"SFX\"
  • \"PFX\"
  • \"VFX\"
  • \"Camera\"
  • \"Menu\"
  • \"Music\"
func int Par_GetParserID(var string parName) {};\n
  • parName - parser name
  • return - parser ID
"},{"location":"zengin/scripts/extenders/zparserextender/externals/par/#par_getsymbolid","title":"Par_GetSymbolID","text":"

Returns symbol ID for the symbol specified by its name

func int Par_GetSymbolID(var int parId, var string symName) {};\n
  • parID - parser ID
  • symName - symbol name
  • return - symbol ID
"},{"location":"zengin/scripts/extenders/zparserextender/externals/par/#par_getsymbollength","title":"Par_GetSymbolLength","text":"

Returns symbol length (number of elements)

func int Par_GetSymbolLength(var int parId, var int symId) {};\n
  • parID - parser ID
  • symName - symbol name
  • return - symbol length
"},{"location":"zengin/scripts/extenders/zparserextender/externals/par/#par_getsymbolvalueint","title":"Par_GetSymbolValueInt","text":"

Returns the integer value of specified symbol

func int Par_GetSymbolValueInt(var int parId, var int symId) {};\n
  • parID - parser ID
  • symName - symbol name
  • return - symbol value
"},{"location":"zengin/scripts/extenders/zparserextender/externals/par/#par_getsymbolvaluefloat","title":"Par_GetSymbolValueFloat","text":"

Returns the float value of specified symbol

func float Par_GetSymbolValueFloat(var int parId, var int symId) {};\n
  • parID - parser ID
  • symName - symbol name
  • return - symbol value
"},{"location":"zengin/scripts/extenders/zparserextender/externals/par/#par_getsymbolvaluestring","title":"Par_GetSymbolValueString","text":"

Returns the string value of specified symbol

func string Par_GetSymbolValueString(var int parId, var int symId) {};\n
  • parID - parser ID
  • symName - symbol name
  • return - symbol value
"},{"location":"zengin/scripts/extenders/zparserextender/externals/par/#par_getsymbolvalueinstance","title":"Par_GetSymbolValueInstance","text":"

Returns the instance value of specified symbol

func instance Par_GetSymbolValueInstance(var int parId, var int symId) {};\n
  • parID - parser ID
  • symName - symbol name
  • return - symbol value
"},{"location":"zengin/scripts/extenders/zparserextender/externals/par/#par_getsymbolvalueintarray","title":"Par_GetSymbolValueIntArray","text":"

Returns the value of specified integer array at the arrayID index

func int Par_GetSymbolValueIntArray(var int parId, var int symId, var int arrayId) {};\n
  • parID - parser ID
  • symName - symbol name
  • arrayID - array index
  • return - value
"},{"location":"zengin/scripts/extenders/zparserextender/externals/par/#par_getsymbolvaluefloatarray","title":"Par_GetSymbolValueFloatArray","text":"

Returns the value of specified float array at the arrayID index

func float Par_GetSymbolValueFloatArray(var int parId, var int symId, var int arrayId) {};\n
  • parID - parser ID
  • symName - symbol name
  • arrayID - array index
  • return - value
"},{"location":"zengin/scripts/extenders/zparserextender/externals/par/#par_getsymbolvaluestringarray","title":"Par_GetSymbolValueStringArray","text":"

Returns the value of specified string array at the arrayID index

func string Par_GetSymbolValueStringArray(var int parId, var int symId, var int arrayId) {};\n
  • parID - parser ID
  • symName - symbol name
  • arrayID - array index
  • return - value
"},{"location":"zengin/scripts/extenders/zparserextender/externals/par/#par_setsymbolvalueint","title":"Par_SetSymbolValueInt","text":"

Sets a new integer value to specified symbol

func void Par_SetSymbolValueInt(var int value, var int parId, var int symId) {};\n
  • value - value to be set
  • parID - parser ID
  • symId - symbol ID
"},{"location":"zengin/scripts/extenders/zparserextender/externals/par/#par_setsymbolvaluefloat","title":"Par_SetSymbolValueFloat","text":"

Sets a new float value to specified symbol

func void Par_SetSymbolValueFloat(var float value, var int parId, var int symId) {};\n
  • value - value to be set
  • parID - parser ID
  • symId - symbol ID
"},{"location":"zengin/scripts/extenders/zparserextender/externals/par/#par_setsymbolvaluestring","title":"Par_SetSymbolValueString","text":"

Sets a new string value to specified symbol

func void Par_SetSymbolValueString(var string value, var int parId, var int symId) {};\n
  • value - value to be set
  • parID - parser ID
  • symId - symbol ID
"},{"location":"zengin/scripts/extenders/zparserextender/externals/par/#par_setsymbolvalueinstance","title":"Par_SetSymbolValueInstance","text":"

Sets a new instance value to specified symbol

func void Par_SetSymbolValueInstance(var instance value, var int parId, var int symId, var int arrayId) {};\n
  • value - value to be set
  • parID - parser ID
  • symId - symbol ID
"},{"location":"zengin/scripts/extenders/zparserextender/externals/par/#par_setsymbolvalueintarray","title":"Par_SetSymbolValueIntArray","text":"

Sets a new integer value to specified integer array symbol

func void Par_SetSymbolValueIntArray(var int value, var int parId, var int symId, var int arrayId) {};\n
  • value - value to be set
  • parID - parser ID
  • symId - symbol ID
  • arrayId - array index
"},{"location":"zengin/scripts/extenders/zparserextender/externals/par/#par_setsymbolvaluefloatarray","title":"Par_SetSymbolValueFloatArray","text":"

Sets a new float value to specified float array symbol

func void Par_SetSymbolValueFloatArray(var float value, var int parId, var int symId, var int arrayId) {};\n
  • value - value to be set
  • parID - parser ID
  • symId - symbol ID
  • arrayId - array index
"},{"location":"zengin/scripts/extenders/zparserextender/externals/par/#par_setsymbolvaluestringarray","title":"Par_SetSymbolValueStringArray","text":"

Sets a new string value to specified string array symbol

func void Par_SetSymbolValueStringArray(var string value, var int parId, var int symId, var int arrayId) {};\n
  • value - value to be set
  • parID - parser ID
  • symId - symbol ID
  • arrayId - array index
"},{"location":"zengin/scripts/extenders/zparserextender/externals/string/","title":"String functions","text":""},{"location":"zengin/scripts/extenders/zparserextender/externals/string/#string-functions","title":"String functions","text":"

Functions to manipulate and format strings.

"},{"location":"zengin/scripts/extenders/zparserextender/externals/string/#str_format","title":"Str_Format","text":"

Returns formatted string using format specifiers

Format specifiers:

  • %s - inserts a string
  • %i - inserts an integer number
  • %x - inserts an integer in hexadecimal
  • %f - inserts a floating point number
  • %b - inserts a logical expression
  • %p - inserts a pointer
func string Str_Format( var string format, ... ) {};\n
  • return - formatted string
"},{"location":"zengin/scripts/extenders/zparserextender/externals/string/#examples","title":"Examples","text":"

Very powerful function, can be used to streamline strings used in the scripts as well as optimize them for translations.

Define constants containing the string with format specifiers.

const string MENU_SAVE = \"Slot %i - press ENTER to save in this slot.\";\nconst string MENU_LOAD = \"Slot %i - press ENTER to load saved game.\";\n
Then define two format functions as such:
func string GetSaveSlotString (var int number)\n{\n    return Str_format(MENU_SAVE, number);\n};\n
func string GetLoadSlotString (var int number)\n{\n    return Str_format(MENU_LOAD, number);\n};\n

Tip

Since the whole translatable string is saved in one constant, it is very easy for translators to change the word order. This was not possible to do without code change to the ConcatStrings function calls within the scripts. With this simple change, translators have to translate only 2 strings instead of 30 (15 + 15 slots) and only 2 strings are compiled into the compiled Menu.dat file.

"},{"location":"zengin/scripts/extenders/zparserextender/externals/string/#str_getlocalizedstring","title":"Str_GetLocalizedString","text":"

Returns a string in the current language, otherwise in English. Arguments MUST be encoded in UTF-8! The result string will be converted to appropriate ANSI string.

func string Str_GetLocalizedString( var string russian,\n                                    var string english,\n                                    var string german,\n                                    var string polish ) {};\n
  • russian - Russian string
  • english - English string
  • german - German string
  • polish - Polish string
  • return - string in the current language
"},{"location":"zengin/scripts/extenders/zparserextender/externals/string/#str_getlocalizedstringex","title":"Str_GetLocalizedStringEx","text":"

Returns a string in the current language, otherwise in English. Offers additional languages

func string Str_GetLocalizedStringEx(   var string russian,\n                                        var string english,\n                                        var string german,\n                                        var string polish,\n                                        var string romanian,\n                                        var string italian,\n                                        var string czech,\n                                        var string spanish ) {};\n
  • russian - Russian string
  • english - English string
  • german - German string
  • polish - Polish string
  • romanian - Romanian string
  • italian - Italian string
  • czech - Czech string
  • spanish - Spanish string
  • return - string in the current language
"},{"location":"zengin/scripts/extenders/zparserextender/externals/string/#str_utf8_to_ansi","title":"Str_UTF8_to_ANSI","text":"

Converts UTF-8 string into an ANSI string with codePage

func string Str_UTF8_to_ANSI( var string utf8, var int codePage ) {};\n
  • utf8 - string encoded in UTF8
  • codePage - codePage id, can be obtained from Str_GetCurrentCP
  • return -
"},{"location":"zengin/scripts/extenders/zparserextender/externals/string/#str_getcurrentcp","title":"Str_GetCurrentCP","text":"

Return the code page corresponding to the current language set in the Union System

func int Str_GetCurrentCP() {};\n
  • return - code page corresponding to the current language
"},{"location":"zengin/scripts/extenders/zparserextender/externals/string/#str_getlength","title":"Str_GetLength","text":"

Returns the length of a string

func int Str_GetLength( var int str ) {};\n
  • str - string to be measured
  • return - length of the string
"},{"location":"zengin/scripts/extenders/zparserextender/externals/vob/","title":"VOB - functions for object manipulation","text":""},{"location":"zengin/scripts/extenders/zparserextender/externals/vob/#vob---functions-for-object-manipulation","title":"VOB - functions for object manipulation","text":"

VOB functions allow you to manipulate game world objects.

"},{"location":"zengin/scripts/extenders/zparserextender/externals/vob/#vob_getvobposition","title":"Vob_GetVobPosition","text":"

Returns the current position of the object in the world

func C_Position Vob_GetVobPosition( var C_Vob vob ) {};\n
  • vob - vob to ge the position of
  • return - C_Position instance - position of the VOB
"},{"location":"zengin/scripts/extenders/zparserextender/externals/vob/#vob_setvobposition","title":"Vob_SetVobPosition","text":"

Sets the current position of the object in the world

func void Vob_SetVobPosition( var C_Vob vob, var C_Position pos ) {};\n
  • vob - vob to get the position of
  • pos - new position of the vob
"},{"location":"zengin/scripts/extenders/zparserextender/externals/vob/#vob_getvobdata","title":"Vob_GetVobData","text":"

Returns the universal data of the zCVob object

func C_Vob_Data Vob_GetVobData( var C_Vob vob ) {};\n
  • vob - VOB to get the position of
  • return - general vob data C_Vob_Data
"},{"location":"zengin/scripts/extenders/zparserextender/externals/vob/#vob_setvobdata","title":"Vob_SetVobData","text":"

Sets the universal data to a zCVob object

func void Vob_SetVobData( var C_Vob vob, var C_Vob_Data data ) {};\n
  • vob - VOB to get the position of
  • data - general vob data C_Vob_Data
"},{"location":"zengin/scripts/extenders/zparserextender/externals/vob/#vob_getlightdata","title":"Vob_GetLightData","text":"

Returns zCVobLight object data

func C_Light_Data Vob_GetLightData( var C_Vob vobLight ) {};\n
  • vobLight - vobLight object
  • return - C_Light_Data of the light
"},{"location":"zengin/scripts/extenders/zparserextender/externals/vob/#vob_setlightdata","title":"Vob_SetLightData","text":"

Sets the data of a zCVobLight object

func void Vob_SetLightData( var C_Vob vobLight, var C_Light_Data data ) {};\n
  • vobLight - object to apply the light data to
  • data - C_Light_Data light data to be set
"},{"location":"zengin/scripts/extenders/zparserextender/externals/vob/#vob_clearlightanilist","title":"Vob_ClearLightAniList","text":"

Clears the list of animation colours for the light source

func void Vob_ClearLightAniList( var C_Vob vobLight ) {};\n
  • vobLight - light vob
"},{"location":"zengin/scripts/extenders/zparserextender/externals/vob/#vob_addlightanicolor","title":"Vob_AddLightAniColor","text":"

Adds a color to the colour list

func void Vob_AddLightAniColor( var C_Vob vobLight, var C_Color col ) {};\n
  • vobLight - object to apply the colour to
  • col - colour to be applied
"},{"location":"zengin/scripts/extenders/zparserextender/externals/vob/#vob_addlightanicolorrgb","title":"Vob_AddLightAniColorRGB","text":"

Adds a color to the colour list

func void Vob_AddLightAniColorRGB(  var C_Vob vobLight,\n                                    var int r,\n                                    var int g,\n                                    var int b ) {};\n
  • vobLight - object to apply the colour to
  • r - red colour channel
  • g - green colour channel
  • b - blue colour channel
"},{"location":"zengin/scripts/extenders/zparserextender/externals/vob/#vob_getmobdata","title":"Vob_GetMobData","text":"

Returns the data of the oCMOB object

func C_Mob_Data Vob_GetMobData( var C_Vob mob ) {};\n
  • mob - oCMOB object
  • return - mob data
"},{"location":"zengin/scripts/extenders/zparserextender/externals/vob/#vob_setmobdata","title":"Vob_SetMobData","text":"

Sets the data of the oCMOB object

func void Vob_SetMobData( var C_Vob mob, var C_Mob_Data data ) {};\n
  • mob - oCMOB object
  • data - C_Mob_Data to be set
"},{"location":"zengin/scripts/extenders/zparserextender/externals/vob/#vob_getmobinterdata","title":"Vob_GetMobInterData","text":"

Returns the data of the oCMobInter object

func MobInter_Data Vob_GetMobInterData( var C_Vob mobInter ) {};\n
  • mobInter - oCMobInter object
  • return - MobInter_Data of the object
"},{"location":"zengin/scripts/extenders/zparserextender/externals/vob/#vob_setmobinterdata","title":"Vob_SetMobInterData","text":"

Sets the data of the oCMobInter object

func void Vob_SetMobInterData( var C_Vob mobInter, var C_MobInter_Data data ) {};\n
  • mobInter - oCMobInter object
  • data - MobInter_Data of the object
"},{"location":"zengin/scripts/extenders/zparserextender/externals/vob/#vob_getmobinterdata_1","title":"Vob_GetMobInterData","text":"

Returns the data of the oCMobLockable object

func C_MobLockable_Data Vob_GetMobInterData( var C_Vob mobLock ) {};\n
  • mobLock - oCMobLockable object
  • data - MobInter_Data of the object
  • return - C_MobLockable_Data of the object
"},{"location":"zengin/scripts/extenders/zparserextender/externals/vob/#vob_setmobinterdata_1","title":"Vob_SetMobInterData","text":"

Sets the data of the oCMobLockable object

func void Vob_SetMobInterData( var C_Vob mobLock, var C_MobLockable_Data data ) {};\n
  • mobLock - oCMobLockable object
  • data - C_MobLockable_Data of the object
"},{"location":"zengin/scripts/extenders/zparserextender/externals/wld/","title":"WLD - world manipulation functions","text":""},{"location":"zengin/scripts/extenders/zparserextender/externals/wld/#wld---world-manipulation-functions","title":"WLD - world manipulation functions","text":"

Functions related to the world.

"},{"location":"zengin/scripts/extenders/zparserextender/externals/wld/#wld_changelevel","title":"Wld_ChangeLevel","text":"

Trigger level change.

func void Wld_ChangeLevel( var string world, var string waypoint ) {};\n
  • world - name of the world
  • waypoint - target waypoint
"},{"location":"zengin/scripts/extenders/zparserextender/externals/wld/#wld_findvob","title":"Wld_FindVob","text":"

Return the VOB instance based on its name.

func instance Wld_FindVob( var string vobname ) {};\n
  • vobname - name of the vob
  • return - zCVob pointer
"},{"location":"zengin/scripts/extenders/zparserextender/externals/wld/#wld_playeffectvob","title":"Wld_PlayEffectVob","text":"

Play a visual effect at specified vob

func void Wld_PlayEffectVob(    var string effect,\n                                var instance pvob,\n                                var int level,\n                                var int damage,\n                                var int damage_type,\n                                var int damage_speed ) {};\n
  • effect - effect name
  • pvob - zCVob to play the effect at
  • level - effect level
  • damage - damage amount
  • damage_type - damage type
  • damage_speed - damage interval
"},{"location":"zengin/scripts/extenders/zparserextender/externals/wld/#wld_playeffectat","title":"Wld_PlayEffectAt","text":"

Play a visual effect at specified world coordinates

func void Wld_PlayEffectAt( var string effect,\n                            var instance coord,\n                            var int level,\n                            var int damage,\n                            var int damage_type,\n                            var int damage_speed ) {};\n
  • effect - effect name
  • coord - world coordinates (zVEC3) to play the effect at
  • level - effect level
  • damage - damage amount
  • damage_type - damage type
  • damage_speed - damage interval
"},{"location":"zengin/scripts/extenders/zparserextender/externals/wld/#wld_togglerain","title":"Wld_ToggleRain","text":"

Turns on the rain

func void Wld_ToggleRain( var float weight, var float time ) {};\n
  • weight - the strength of the rain
  • time - rain duration
"},{"location":"zengin/scripts/extenders/zparserextender/externals/wld/#wld_setweathertype","title":"Wld_SetWeatherType","text":"

Sets the weather type. Types:

0 - snow 1 - rain

func void Wld_SetWeatherType( var int type ) {};\n
  • type - weather type
"},{"location":"zengin/scripts/extenders/zparserextender/externals/wld/#wld_getweathertype","title":"Wld_GetWeatherType","text":"

Returns the weather type. Types:

0 - snow 1 - rain

func int Wld_GetWeatherType() {};\n
  • return - weather type
"},{"location":"zengin/scripts/extenders/zparserextender/syntax_extensions/dialogues/","title":"Dialogue constants","text":""},{"location":"zengin/scripts/extenders/zparserextender/syntax_extensions/dialogues/#dialogue-constants","title":"Dialogue constants","text":"

To simplify dialogues, you can define up to 2 auxiliary variables or constants. Values corresponding to the current C_Info instance will be dynamically written there.

"},{"location":"zengin/scripts/extenders/zparserextender/syntax_extensions/dialogues/#dia_currentinstance","title":"DIA_CurrentInstance","text":"
var int DIA_CurrentInstance\n
Contains the ID of the current C_Info instance. Can greatly simplify code or make it more reusable. Should be defined in scripts. Example usage
Info_ClearChoices(DIA_CurrentInstance);\nInfo_AddChoice(DIA_CurrentInstance, /*text*/, /*func*/);\nNpc_KnowsInfo(hero, DIA_CurrentInstance); // In this case DIA_CurrentInstance contains the last C_Info instance??\n
Create a wrapper function based on this variable
func int C_HeroKnowsCurrentInfo()\n{\n    return Npc_KnowsInfo(hero, DIA_CurrentInstance);\n};\n
"},{"location":"zengin/scripts/extenders/zparserextender/syntax_extensions/dialogues/#dia_currentname","title":"DIA_CurrentName","text":"
var string DIA_CurrentName;\n
Contains the name of the current instance of C_Info. Can be useful for debugging purposes. Should be defined in scripts. Usage scenarios:
Hlp_PrintConsole(DIA_CurrentName);\nHlp_PrintConsole(Str_Format(\"%s[%s]\", DIA_CurrentName, self.name);\nHlp_StrCmp(DIA_CurrentName, \"DIA_DiegoOw_Teach\");\n
"},{"location":"zengin/scripts/extenders/zparserextender/syntax_extensions/events/","title":"Event functions","text":""},{"location":"zengin/scripts/extenders/zparserextender/syntax_extensions/events/#event-functions","title":"Event functions","text":"

Event functions are functions sharing the same name. It can be defined multiple times but only once per file. Such functions are useful for implementing callback type functions. Every time an event is called, all instances of the same name will be called. The event is func with a return type event. Events are defined globally, meaning they ignore namespace they are in. To call an event from a script, use the external function Hlp_DoEvent(var string funcName).

func void GiveXP()\n{\n    Hlp_DoEvent(\"OnGiveXP\");\n};\n\nfunc event OnGiveXP()\n{\n    // TODO\n    // This function can be defined in many files to do different things\n    // more appropriate for that file's context and all of them will be\n    // called, when function GiveXP (above) is called.\n};\n

Plugin implements two of these event functions

  • func event GameInit() - called when entering the main menu on game start
  • func event GameLoop() - called every frame when a world is loaded

Define these in any file in your scripts, they will be automatically called

"},{"location":"zengin/scripts/extenders/zparserextender/syntax_extensions/extern/","title":"Extern binding","text":""},{"location":"zengin/scripts/extenders/zparserextender/syntax_extensions/extern/#extern-binding","title":"Extern binding","text":"

The extern binding allows you to secure your code against overriding or undefined symbol. Keyword extern before declaration means that if object of the same name exists, source object should be used. If not, a new one will be created.

extern instance PC_Hero(C_Npc) \n{\n    // TODO\n};\n
"},{"location":"zengin/scripts/extenders/zparserextender/syntax_extensions/namespaces/","title":"Namespaces","text":""},{"location":"zengin/scripts/extenders/zparserextender/syntax_extensions/namespaces/#namespaces","title":"Namespaces","text":"

zParserExtender also implements namespaces. Namespaces ensure that all symbols inside the namespace are unique.

"},{"location":"zengin/scripts/extenders/zparserextender/syntax_extensions/namespaces/#defining-a-namespace","title":"Defining a namespace","text":"

To define a namespace the new keyword namespace is used.

Regular scriptsInjectable scripts
namespace zTestNamespace\n{\n    var int var01;\n    func void func01() { };\n};\n
META\n{\n    Namespace = zTestNamespace;\n};\n\nvar int var01;\nfunc void func01() { };\n
"},{"location":"zengin/scripts/extenders/zparserextender/syntax_extensions/namespaces/#namespace-nesting","title":"Namespace nesting","text":"

Namespaces can be nested for finer control. In case of injection, the namespace defined in META is applied to all code inside the script.

To go deeper into the namespaces you use the namespace operator :. This code shows function with the same name within three different namespaces. The call in GameInit is made from the global namespace.

namespace zTestNamespace01\n{\n    func void func01() { };\n};\n\nnamespace zTestNamespace02\n{\n    func void func01() { };\n};\n\nnamespace zTestNamespace03\n{\n    namespace zTestNamespace04\n    {\n        func void func01() { };\n    };\n};\n\nfunc event GameInit()\n{\n    // In this case, the reference is from global namespace to zTestNamespace\n    zTestNamespace01:func01();\n    zTestNamespace02:func01();\n    zTestNamespace03:zTestNamespace04:func01();\n};\n
"},{"location":"zengin/scripts/extenders/zparserextender/syntax_extensions/namespaces/#namespace-traversal","title":"Namespace traversal","text":"

To go up a namespace tree you use the namespace operator : without specifying a namespace. Number of operators determines how many levels you go up.

Exiting nested namespaces
func void func01()\n{\n    Hlp_MessageBox(\"#1\");\n};\n\nnamespace zTestNamespace01\n{\n    func void func01()\n    {\n        Hlp_MessageBox(\"#2\");\n    };\n\n    namespace zTestNamespace02\n    {\n        func void func01()\n        {\n            Hlp_MessageBox(\"#3\");\n        };\n\n        namespace zTestNamespace03\n        {\n            func void func01()\n            {\n                Hlp_MessageBox(\"#4\");\n            };\n\n            func event GameInit()\n            {\n                :::func01(); // Calls the function 3 levels up\n                ::func01();  // Calls the function 2 levels up\n                :func01();   // Calls the function 1 level up\n                func01();    // Calls the function from the current namespace\n            };\n        };\n    };\n};\n
"},{"location":"zengin/scripts/extenders/zparserextender/syntax_extensions/namespaces/#optional-namespace-specification","title":"Optional namespace specification","text":"

There are three cases where the namespace prefix is optional

Shares the same namespaceIf the function is in higher level namespaceIf using is specified in the META block
namespace zTestNamespace01\n{\n    func void func01()\n    {\n        Hlp_MessageBox(\"#1\");\n    };\n\n    func event GameInit()\n    {\n        // Function call from the current namespace\n        func01();\n    };\n};\n
func void func01()\n{\n    Hlp_MessageBox(\"#1\");\n};\n\nnamespace zTestNamespace01\n{\n    func void func01()\n    {\n        Hlp_MessageBox(\"#2\");\n    };\n\n    namespace zTestNamespace02\n    {\n        func event GameInit()\n        {\n            // Function call from the global namespace\n            func01();\n        };\n    };\n};\n
META\n{\n    using = zTestNamespace01;\n};\n\nnamespace zTestNamespace01\n{\n    func void func01()\n    {\n        Hlp_MessageBox(\"#1\");\n    };\n};\n\nfunc event GameInit()\n{\n    // Calls the function with the namespace specified in the META block\n    func01();\n};\n
"},{"location":"zengin/scripts/extenders/zparserextender/syntax_extensions/namespaces/#global-namespace-and-daedalus-hooking","title":"Global namespace and Daedalus hooking","text":"

Namespace can not only be defined to an existing symbol but also to define new ones. Next code example shows how to implement a hook to a global instance.

namespace zTestNamespace01\n{\n    const string Var01 = \"New instance name\";\n\n    // Hooking the global instance\n    instance :ItAr_Pir_L_Addon(C_Item)\n    {\n        ItAr_Pir_L_Addon_Old();\n        name = Var01;\n    };\n};\n
To hook an object, both signature and namespace has to match. It is syntactically allowed to hook an instance from a different space. Specify explicitly to which namespace the object will belong. This means that to hook instance ItAr_Pir_L_Addon from the namespace zTestNamespace01 to a global namespace, you have to refer to the global namespace using the namespace operator :. Since the function will be defined globally (as every symbol in ZenGin), it will be a part of the zTestNamespace01 which means that all functions will be local to this namespace."},{"location":"zengin/scripts/extenders/zparserextender/syntax_extensions/testelse/","title":"Test-else statements","text":""},{"location":"zengin/scripts/extenders/zparserextender/syntax_extensions/testelse/#test-else-statements","title":"Test-else statements","text":"

The test-else bind statement can be used to define sections of code to be compiled. If the code is within the boundaries of the inactive test-else branch, it will not be compiled. This operator can take values as input that are converted to logical values. For example, if an object is passed as an argument, the parser will check for its existence. If it is an engine tag, it will return the result of matching the current engine with the tag:

Valid values:

  • instance name - PC_HERO, ItMi_Gold, ...
  • engine tag - G1, G1A, G2, G2A
  • Steam Overlay activity - Steam

The result can be combined from several arguments. Round brackets () can be used to specify priority and expressions support the logical negation operator !, logical AND && and OR ||.

The operator can be used anywhere in the script file. It is syntactically similar to if else statement, but curly braces {} can be omitted for single-line operations. For example:

SteamActivated constant is set only when Steam is active
test Steam var const SteamActivated = 1;\n
Example of a logical expression with an else branch
test SteamActivated && G2A \n{\n    // TODO\n}\nelse \n{\n    // TODO\n}\n
"},{"location":"zengin/scripts/extenders/zparserextender/syntax_extensions/while/","title":"Native WHILE loop","text":""},{"location":"zengin/scripts/extenders/zparserextender/syntax_extensions/while/#native-while-loop","title":"Native WHILE loop","text":"

Just like Ikarus zParserExtender implements a while loop.

var int value; value = 10;\nwhile(value > 0)\n{\n    if (value == 8)\n    {\n        continue;\n    };\n\n    if (value == 2)\n    {\n        break;\n    };\n};\n

Note

To activate while it is necessary to set NativeWhile setting in SystemPack.ini

[ZPARSE_EXTENDER]\nNativeWhile = true\n

Compiled while loop works in vanilla engine without the plugin.

"},{"location":"zengin/scripts/externals/","title":"Externals","text":""},{"location":"zengin/scripts/externals/#externals","title":"Externals","text":"

External functions are Daedalus functions (defined in the engine itself), that are used to interface with the engine. Gothic 1 and Gothic 2 implements slightly different set of external functions. There are some external functions, that were used in the course of Gothic's development, but are now obsolete/deprecated because the underlying systems implemented in the engine were either turned off, or broken all together.

"},{"location":"zengin/scripts/externals/doc/","title":"Doc external functions","text":""},{"location":"zengin/scripts/externals/doc/#doc-external-functions","title":"Doc external functions","text":"

Doc functions are used to control the document manager. They allow you to fine tune the display of maps, letters and books.

"},{"location":"zengin/scripts/externals/doc/#doc_create","title":"Doc_Create","text":"

Creates a new instance of the document manager and returns its ID.

func int Doc_Create() {};\n

Return value Returns the ID of the document manager instance.

Example

var int nDocID; // Variable to store the id in\nnDocID = Doc_Create();\n
"},{"location":"zengin/scripts/externals/doc/#doc_createmap","title":"Doc_CreateMap","text":"

Creates a new instance of the document manager with the arrow showing players position on the map and returns its ID.

func int Doc_CreateMap() {};\n

Return value Returns the ID of the document manager instance.

Example

var int nDocID; // Variable to store the id in\nnDocID = Doc_CreateMap();\n
"},{"location":"zengin/scripts/externals/doc/#doc_setlevel","title":"Doc_SetLevel","text":"

Set a world level to a map. This maps the texture of the document to the bounding box of the provided level.

func void Doc_SetLevel(var int docID, var string level) {};\n

Parameters

  • var int docID - document manager ID
  • var string level - name of the ZEN file

Example

nDocID = Doc_CreateMap();\nDoc_SetLevel(nDocID, \"WORLD.ZEN\");\n
"},{"location":"zengin/scripts/externals/doc/#doc_setlevelcoords","title":"Doc_SetLevelCoords","text":"

Warning

This function is only available in Gothic 2

Sets the map coordinates. This is used to map smaller portions of the world map to the document map to correctly show players position on the map.

func void Doc_SetLevelCoords(var int docID, var int left, var int top, var int right, var int bottom) {};\n

Parameters

  • var int docID - document manager ID
  • var int left - left coordinate
  • var int top - top coordinate
  • var int right - right coordinate
  • var int bottom - bottom coordinate

Example

Doc_SetLevelCoords(nDocID, -28000, 50500, 95500, -42500);\n
"},{"location":"zengin/scripts/externals/doc/#doc_setfont","title":"Doc_SetFont","text":"

Sets a font to be used on a page in a document with docID. Can be called multiple times to display different lines with different fonts.

func void Doc_SetFont(var int docID, var int page, var string font) {};\n

Parameters

  • var int docID - document manager ID
  • var int page - page index, if set to -1, fonts will be applied to all pages
  • var string font - font to be used

Example

Doc_SetFont(nDocID, -1, \"FONT_10_BOOK.TGA\");\n
"},{"location":"zengin/scripts/externals/doc/#doc_setpages","title":"Doc_SetPages","text":"

Sets the number of pages numOfPages of the document.

func void Doc_SetPages(var int docID, var int numOfPages) {};\n

Parameters

  • var int docID - document manager ID
  • var int numOfPages - number of pages

Example

nDocID = Doc_Create();\nDoc_SetPages(nDocID, 2);\n
"},{"location":"zengin/scripts/externals/doc/#doc_setpage","title":"Doc_SetPage","text":"

Set page to have texture as a background with scale.

func void Doc_SetPage(var int docID, var int page, var string texture, var int scale) {};\n

Parameters

  • var int docID - document manager ID
  • var int page - page index, if set to -1, settings are applied to all pages
  • var string texture - texture of the background
  • var int scale - scale of the texture, TRUE to scale the page, FALSE to not scale

Example

Doc_SetPage(nDocID, 0, \"Book_Mage_L.tga\", FALSE);\nDoc_SetPage(nDocID, 1, \"Book_Mage_R.tga\", FALSE);\n
"},{"location":"zengin/scripts/externals/doc/#doc_setmargins","title":"Doc_SetMargins","text":"

Sets text margins of the page

func void Doc_SetMargins(var int docID,\n                         var int page,\n                         var int left,\n                         var int top,\n                         var int right,\n                         var int bottom,\n                         var int pixels) {};\n

Parameters

  • var int docID - document manager ID
  • var int page - page index, if set to -1, settings are applied to all pages
  • var int left - left margin
  • var int top - top margin
  • var int right - right margin
  • var int bottom - bottom margin
  • var int pixels - TRUE to use pixels, FALSE to use virtual coordinates

Warning

After a thorough examination of this external function in the decompiler, it looks like the function works in pixels only regardless of this parameter.

Example

Doc_SetMargins(nDocID, 0, 275, 20, 30, 20, TRUE);\n
"},{"location":"zengin/scripts/externals/doc/#doc_printline","title":"Doc_PrintLine","text":"

Prints a line of text (font is set using Doc_SetFont) onto the document with docID, onto the page. Does not split the text into multiple lines if they do not fit onto the page.

func void Doc_PrintLine(var int docID, var int page, var string text) {};\n

Parameters

  • var int docID - document manager ID
  • var int page - page index
  • var string text - text to be printed

Example

Doc_PrintLine(nDocID, 0, \"\"); // insert empty line\nDoc_PrintLine(nDocID, 0, \"The Book\");\n
"},{"location":"zengin/scripts/externals/doc/#doc_printlines","title":"Doc_PrintLines","text":"

Prints a line of text (font is set using Doc_SetFont) onto the document with docID, onto the page. Splits the text into multiple lines if they do not fit onto the page.

func void Doc_PrintLines(var int docID, var int page, var string text) {};\n

Parameters

  • var int docID - document manager ID
  • var int page - page index
  • var string text - text to be printed

Example

Doc_PrintLines(nDocID, 0, \"The war had been decided. Varant had lost its seaports, vital to army supplies. King Rhobar had not lingered on the battle fields for a long time, but left his generals to deal with the few remaining enemy troops. Varant had only one large force left, commanded by Lukkor, the most capable warlord of the Varant army, who had more than once turned defeat into victory.\");\nDoc_PrintLines(nDocID, 0, \"But now his army was trapped. The situation was hopeless, even though his army greatly outnumbered the enemy. Lee, a war hero from Myrtana, had lured him into this trap. The heavy cavalry had been unable to fight on the thick, swamped ground of the narrow valley. Lee's soldiers had occupied the range of hills surrounding the swamp, and they had struck repeatedly, decimating the army. The desperate sallies his troops had launched had been cut short in pools of blood. He was beaten.\");\n
"},{"location":"zengin/scripts/externals/doc/#doc_show","title":"Doc_Show","text":"

Display the document using the document manager ID

func void Doc_Show(var int docID) {};\n

Parameters

  • var int docID - document manager ID

Example

var int nDocID; // Variable to store the id in\nnDocID = Doc_Create();\n\n// ... document configuration\n\nDoc_Show(nDocID);\n
"},{"location":"zengin/scripts/externals/doc/#externals-with-docu-comments","title":"Externals with docu comments","text":"
/// Creates a new instance of the document manager and returns its ID.\n///\n/// @return Returns the ID of the document manager instance.\nfunc int Doc_Create() {};\n\n/// Create a new instance of the document manager with the arrow showing players position on the map and returns its ID.\n///\n/// @return Returns the ID of the document manager instance.\nfunc int Doc_CreateMap() {};\n\n/// Prints a line of `text` onto the document with `docID`, onto the `page`.\n/// Does not line break\n/// \n/// @param docID document manager ID\n/// @param page page index\n/// @param text text to be printed\nfunc void Doc_PrintLine(var int docID, var int page, var string text) {};\n\n/// Prints a line of `text` onto the document with `docID`, onto the `page`. The `text` is automatically split into multiple lines\n/// \n/// @param docID document manager ID\n/// @param page page index\n/// @param text text to be printed\nfunc void Doc_PrintLines(var int docID, var int page, var string text) {};\n\n/// Sets a `font` to be used on a `page` in a document with `docID`. Can be called multiple times to display different lines with different fonts.\n///\n/// @param docID document manager ID\n/// @param page page index\n/// @param font font to be used\nfunc void Doc_SetFont(var int docID, var int page, var string font) {};\n\n/// Sets the number of pages `numOfPages` of the document.\n///\n/// @param docID document manager ID\n/// @param numOfPages number of pages\nfunc void Doc_SetPages(var int docID, var int numOfPages) {};\n\n/// Set `page` to have `texture` as a background with `scale`. \n///\n/// @param docID document manager ID\n/// @param page page index, if set to `-1`, settings are applied to all pages\n/// @param texture texture of the background\n/// @param scale scale of the texture, if set to 1, there will be no resizing\nfunc void Doc_SetPage(var int docID, var int page, var string texture, var int scale) {};\n\n/// Set a world level to a map.\n///\n/// @param docID document manager ID\n/// @param level name of the ZEN file\nfunc void Doc_SetLevel(var int docID, var string level) {};\n\n/// Sets the map coordinates. \n/// \n/// @param docID document manager ID\n/// @param left left\n/// @param top top\n/// @param right top\n/// @param bottom bottom\nfunc void Doc_SetLevelCoords(var int docID, var int left, var int top, var int right, var int bottom) {};\n\n/// Sets text margins of the page\n///\n/// @param docID document manager ID\n/// @param page page index, if set to `-1`, settings are applied to all pages\n/// @param left left margin\n/// @param top top margin\n/// @param right right margin\n/// @param bottom bottom margin\n/// @param pixels `TRUE` to use pixels, `FALSE` to use virtual coordinates\nfunc void Doc_SetMargins(var int docID,\n                         var int page,\n                         var int left,\n                         var int top,\n                         var int right,\n                         var int bottom,\n                         var int pixels) {};\n\n/// Display the document using the document manager ID\n///\n/// @param docID document manager ID\nfunc void Doc_Show(var int docID) {};\n\n\n\n/// deprecated\nfunc void Doc_Open (var string Texture) {};\n\n/// deprecated\nfunc void Doc_Font(var string Font) {};\n\n/// deprecated\nfunc void Doc_Print (var string Text) {};\n\n/// deprecated\nfunc void Doc_MapCoordinates(var string s0,\n                             var float r1,\n                             var float r2,\n                             var float r3,\n                             var float r4,\n                             var float r5,\n                             var float r6,\n                             var float r7,\n                             var float r8) {};\n
"},{"location":"zengin/scripts/externals/log/","title":"Log external functions","text":""},{"location":"zengin/scripts/externals/log/#log-external-functions","title":"Log external functions","text":"

Log externals are used to manipulate players log and to track quest progress.

"},{"location":"zengin/scripts/externals/log/#log_createtopic","title":"Log_CreateTopic","text":"

Creates a new log topic with the name topicName under the section logSection

func void Log_CreateTopic(var string topicName, var int logSection) {};\n
Parameters
  • var string topicName Unique string used to identify and name the topic
  • var int logSection Indicates in which section to create the topic in. Takes constants LOG_MISSION, LOG_NOTE as values
"},{"location":"zengin/scripts/externals/log/#log_addentry","title":"Log_AddEntry","text":"

Adds an entry to a log topic with the name topicName under the section logSection

func void Log_AddEntry(var string topicName, var string entry) {};\n
Parameters
  • var string topicName Unique string used to identify and name the topic
  • var string entry Content of the new entry

Info

In the engine the Log_AddEntry() is wrapped in a B_LogEntry() function. This function also handles printing the \"New Journal Entry\" message to the screen and playing the sound effect.

func void B_LogEntry(var string topic, var string entry)\n{\n    PrintDebugNpc(PD_ZS_DETAIL, \"B_LogEntry\"); // Logging\n\n    Log_AddEntry(topic, entry);\n\n    PrintScreen(NAME_NewLogEntry, -1, _YPOS_MESSAGE_LOGENTRY, \"font_old_10_white.tga\", _TIME_MESSAGE_LOGENTRY);\n    Snd_Play(\"LogEntry\");\n};\n
"},{"location":"zengin/scripts/externals/log/#log_settopicstatus","title":"Log_SetTopicStatus","text":"

Changes the status of the topic with the name topicName

func void Log_SetTopicStatus(var string topicName, var int status) {};\n
Parameters
  • var string topicName Unique string used to identify and name the topic
  • var int status The status to be set. Takes constants LOG_RUNNING, LOG_SUCCESS, LOG_FAILED, LOG_OBSOLETE as values
"},{"location":"zengin/scripts/externals/log/#zparserextender","title":"zParserExtender","text":"

The log external function selection is missing functions to retrieve the status of a log entry. There are only functions to read the log status (as discussed on Inside Gothic). As a result of this the original scriptwriters had to define additional variable to track the log status in the scripts, even though the value is being already tracked by the engine. zParserExtender fixes this by introducing new log external functions.

"},{"location":"zengin/scripts/externals/log/#externals-with-docu-comments","title":"Externals with docu comments","text":"
/// Creates a new log topic with the name `topicName` under the section `logSection`\n/// \n/// @param topicName unique string used to identify and name the topic\n/// @param logSection [LOG_MISSION, LOG_NOTE] indicates in which section to create the topic in\nfunc void Log_CreateTopic(var string topicName, var int logSection) {};\n\n/// Creates a new log topic with the name `topicName` under the section `logSection`\n/// \n/// @param topicName unique string used to identify and name the topic\n/// @param logSection [LOG_MISSION, LOG_NOTE] indicates in which section to create the topic in\nfunc void Log_AddEntry(var string topicName, var string entry) {};\n\n/// Changes the status of the topic with the name `topicName`\n///\n/// @param topicName unique string used to identify and name the topic\n/// @param status [LOG_RUNNING, LOG_SUCCESS, LOG_FAILED, LOG_OBSOLETE] the status to be set\nfunc void Log_SetTopicStatus(var string topicName, var int status) {};\n
"},{"location":"zengin/scripts/externals/mdl/","title":"MDL functions","text":""},{"location":"zengin/scripts/externals/mdl/#mdl-functions","title":"MDL functions","text":"

Functions to tweak animation and other model related settings.

"},{"location":"zengin/scripts/externals/mdl/#mdl_applyoverlaymds","title":"Mdl_ApplyOverlayMDS","text":"

Apply an animation overlay with overlay_name for the specified npc

func void Mdl_ApplyOverlayMDS(var c_npc npc, var string overlay_name) {};\n

Parameters

  • var c_npc npc NPC to apply the overlay to
  • var string overlay_name Name of the animation overlay
"},{"location":"zengin/scripts/externals/mdl/#mdl_applyoverlaymdstimed","title":"Mdl_ApplyOverlayMDSTimed","text":"

Apply an animation overlay with overlay_name for the specified npc for duration milliseconds

func void Mdl_ApplyOverlayMDSTimed(var c_npc npc, var string overlay_name, var float duration) {};\n

Parameters

  • var c_npc npc NPC to apply the overlay to
  • var string overlay_name Name of the animation overlay
  • var float duration Overlay duration in milliseconds
"},{"location":"zengin/scripts/externals/mdl/#mdl_removeoverlaymds","title":"Mdl_RemoveOverlayMDS","text":"

Remove the animation overlay overlay_name from specified npc

func void Mdl_RemoveOverlayMDS(var c_npc npc, var string overlay_name) {};\n

Parameters

  • var c_npc npc NPC to remove the overlay from
  • var string overlay_name Name of the animation overlay
"},{"location":"zengin/scripts/externals/mdl/#mdl_applyrandomani","title":"Mdl_ApplyRandomAni","text":"

Assign a random animation ani2 to random animation list of animation ani1

func void Mdl_ApplyRandomAni(var c_npc npc, var string ani1, var string ani2) {};\n

Parameters

  • var c_npc npc NPC owning the animation
  • var string ani1 The animation to assign random animation to
  • var string ani2 Animation to be assigned
"},{"location":"zengin/scripts/externals/mdl/#mdl_applyrandomanifreq","title":"Mdl_ApplyRandomAniFreq","text":"

Sets the random animation frequency for animation ani1

func void Mdl_ApplyRandomAniFreq(var c_npc npc, var string ani1, var float frequency) {};\n

Parameters

  • var c_npc npc NPC owning the animation
  • var string ani1 The animation to set the random frequency
  • var float frequency Number of seconds between random animations
Example
// Attach T_WOUNDED_TRY animation to the S_WOUNDED animation\nMdl_ApplyRandomAni(self, \"S_WOUNDED\", \"T_WOUNDED_TRY\");\n// Make the random animation attached play every 8 seconds\nMdl_ApplyRandomAniFreq(self, \"S_WOUNDED\", 8);\n
"},{"location":"zengin/scripts/externals/mdl/#mdl_setmodelfatness","title":"Mdl_SetModelFatness","text":"

Set the procedural model fatness

func void Mdl_SetModelFatness(var c_npc npc, var float fatness) {};\n

Parameters

  • var c_npc npc NPC to apply the fatness to
  • var float fatness Fatness value
"},{"location":"zengin/scripts/externals/mdl/#mdl_setmodelscale","title":"Mdl_SetModelScale","text":"

Set model scale per axis

func void Mdl_SetModelScale(var c_npc npc, var float x, var float y, var float z) {};\n

Parameters

  • var c_npc npc NPC to apply the scale to
  • var float x Scale along the x-axis, 1.0 = 100%, 1.5 = 150%, 0.9 = 90%
  • var float y Scale along the y-axis, 1.0 = 100%, 1.5 = 150%, 0.9 = 90%
  • var float z Scale along the z-axis, 1.0 = 100%, 1.5 = 150%, 0.9 = 90%
"},{"location":"zengin/scripts/externals/mdl/#mdl_setvisualbody","title":"Mdl_SetVisualBody","text":"

Sets up the visual of an NPC

func void Mdl_SetVisualBody(var instance npc,\n                            var string body_mesh,\n                            var int body_tex,\n                            var int skin,\n                            var string head_mesh,\n                            var int head_tex,\n                            var int teeth_tex,\n                            var int armor_inst       ) {};\n

Parameters

  • var instance npc NPC to be affected
  • var string body_mesh Mesh to be used as the body e.g. HUN_BODY_NAKED0
  • var int body_tex Body texture assigned to this body mesh
  • var int skin Body texture variant
  • var string head_mesh Head mesh
  • var int head_tex Head texture
  • var int teeth_tex Teeth texture
  • var int armor_inst Armor (C_ITEM instance) to be equipped or -1 for no armor
"},{"location":"zengin/scripts/externals/mdl/#mdl_setvisual","title":"Mdl_SetVisual","text":"

Set the animation set (also dictates models you can set using the Mdl_SetVisualBody)

func void Mdl_SetVisual(var instance npc, var string animation_set) {};\n

Parameters

  • var instance npc NPC to apply the animation set to
  • var string animation_set Name of the MDS file that contains the animation set
"},{"location":"zengin/scripts/externals/mdl/#mdl_startfaceani","title":"Mdl_StartFaceAni","text":"

Start a face animation

func void Mdl_StartFaceAni(var c_npc npc,\n                           var string name,\n                           var float intensity,\n                           var float holdtime) {};\n

Parameters

  • var c_npc npc NPC to apply the animation to
  • var string name Animation name
  • var float intensity Intensity of the animation 0.0 to 1.0
  • var float holdtime How long should the animation be held for -2 will use the MMS defined value, '-1' will make the hold time infinite
"},{"location":"zengin/scripts/externals/mdl/#mdl_applyrandomfaceani","title":"Mdl_ApplyRandomFaceAni","text":"

Start a random face animation

func void Mdl_ApplyRandomFaceAni(var c_npc npc,\n                                 var string name,\n                                 var float timemin,\n                                 var float timeminvar,\n                                 var float timemax,\n                                 var float timemaxvar,\n                                 var float probmin) {};\n

Parameters

  • var c_npc npc NPC to apply the animation to
  • var string name Animation name
  • var float timemin Minimum time after which the ani should be started (in seconds)
  • var float timeminvar Minimum boundary variation (in seconds)
  • var float timemax Maximum time after which the ani should be started (in seconds)
  • var float timemaxvar Maximum boundary variation (in seconds)
  • var float probmin Probability (0.0 to 1.0) to choose the lower boundary time
"},{"location":"zengin/scripts/externals/mdl/#externals-with-docu-comments","title":"Externals with docu comments","text":"
/// Apply an animation overlay with `overlay_name` for the specified `npc`\n/// \n/// @param npc NPC to apply the overlay to\n/// @param overlay_name name of the animation overlay\nfunc void Mdl_ApplyOverlayMDS(var c_npc npc, var string overlay_name) {};\n\n/// Apply an animation overlay with `overlay_name` for the specified `npc` for `duration` milliseconds\n///\n/// @param npc NPC to apply the overlay to\n/// @param overlay_name name of the animation overlay\n/// @param duration overlay duration in milliseconds\nfunc void Mdl_ApplyOverlayMDSTimed(var c_npc npc, var string overlay_name, var float duration) {};\n\n/// Remove the animation overlay `overlay_name` from specified `npc` \n/// \n/// @param npc NPC to remove the overlay from\n/// @param overlay_name name of the animation overlay\nfunc void Mdl_RemoveOverlayMDS(var c_npc npc, var string overlay_name) {};\n\n/// Assign a random animation `ani2` to random animation list of animation `ani1`\n///\n/// @param npc NPC owning the animation\n/// @param ani1 the animation to assign random animation to\n/// @param ani2 animation to be assigned\nfunc void Mdl_ApplyRandomAni(var c_npc npc, var string ani1, var string ani2) {};\n\n/// Sets the random animation frequency for animation `ani1`\n///\n/// @param npc NPC owning the animation\n/// @param ani1 the animation to set the random frequency\n/// @param frequency number of seconds between random animations\nfunc void Mdl_ApplyRandomAniFreq(var c_npc npc, var string ani1, var float frequency) {};\n\n/// Set the procedural model fatness\n///\n/// @param npc NPC to apply the fatness to \n/// @param fatness fatness value\nfunc void Mdl_SetModelFatness(var c_npc npc, var float fatness) {};\n\n/// Set model scale per axis\n///\n/// @param npc NPC to apply the scale to \n/// @param x scale along the x axis, 1.0 = 100%, 1.5 = 150%, 0.9 = 90% \n/// @param y scale along the y axis, 1.0 = 100%, 1.5 = 150%, 0.9 = 90% \n/// @param z scale along the z axis, 1.0 = 100%, 1.5 = 150%, 0.9 = 90% \nfunc void Mdl_SetModelScale(var c_npc npc, var float x, var float y, var float z) {};\n\n/// Sets up the visual of an NPC\n///\n/// @param npc NPC to be affected\n/// @param body_mesh mesh to be used as the body e.g. `HUN_BODY_NAKED0`\n/// @param body_tex body texture assigned to this body mesh\n/// @param skin body texture variant\n/// @param head_mesh head mesh\n/// @param head_tex head texture\n/// @param teeth_tex teeth texture\n/// @param armor_inst armor (C_ITEM instance) to be equipped or `-1` for no armor \nfunc void Mdl_SetVisualBody(var instance npc,\n                            var string body_mesh,\n                            var int body_tex,\n                            var int skin,\n                            var string head_mesh,\n                            var int head_tex,\n                            var int teeth_tex,\n                            var int armor_inst       ) {};\n\n/// Set the animation set (also dictates models you can set using the `Mdl_SetVisualBody`)\n///\n/// @param npc NPC to apply the animation set to \n/// @param animation_set name of the MDS file that contains the animation set\nfunc void Mdl_SetVisual(var instance npc, var string animation_set) {};\n\n/// Start a face animation\n///\n/// @param npc NPC to apply the animation to \n/// @param name animation name\n/// @param intensity intensity of the animation 0.0 to 1.0\n/// @param holdtime how long should the animation be held for `-2` will use the MMS defined value, '-1' will make the hold time infinite\nfunc void Mdl_StartFaceAni(var c_npc npc,\n                           var string name,\n                           var float intensity,\n                           var float holdtime) {};\n\n/// Start a random face animation\n///\n/// @param npc NPC to apply the animation to \n/// @param name animation name\n/// @param timemin minimum time after which the ani should be started (in seconds)\n/// @param timeminvar minimum boundary variation (in seconds)\n/// @param timemax maximum time after which the ani should be started (in seconds)\n/// @param timemaxvar maximum boundary variation (in seconds)\n/// @param probmin probability (0.0 to 1.0) to choose the lower boundary time\nfunc void Mdl_ApplyRandomFaceAni(var c_npc npc,\n                                 var string name,\n                                 var float timemin,\n                                 var float timeminvar,\n                                 var float timemax,\n                                 var float timemaxvar,\n                                 var float probmin) {};\n
"},{"location":"zengin/sound/","title":"Sound","text":""},{"location":"zengin/sound/#sound","title":"Sound","text":"

ZenGin uses .wav files for playing Sound Effects and Dubbing.

Info

In-game soundtrack isn't saved in .wav sound files. See Music.

"},{"location":"zengin/sound/#properties","title":"Properties","text":"

Original gothic sound files has following properties:

  • One channel (Mono)
  • 44100 Hz frequency
  • 32-bit depth
"},{"location":"zengin/sound/#sfx","title":"SFX","text":"

Sound effects (SFX) are sounds made by monsters, spells, weapons etc. Sound effects are defined in multiple places, in .mds files as part of the animation EventBlocks, or in the SFX Daedalus scripts. Sounds are located in the _work/Data/Sound/SFX directory.

"},{"location":"zengin/sound/#speech","title":"Speech","text":"

Dubbing for dialogues is located into _work/Data/Sound/Speech folder. Every single AI_Output has its own sound file with name defined in the function itself.

For this dialogue line

AI_Output(self,hero,\"Info_Diego_Gamestart_11_00\"); //I'm Diego.\n
the engine will play Info_Diego_Gamestart_11_00.wav sound file (if it exists)."},{"location":"zengin/sound/tutorials/change_sfx/","title":"Changing Sound Effect","text":""},{"location":"zengin/sound/tutorials/change_sfx/#changing-sound-effect","title":"Changing Sound Effect","text":"

This is Gothic VDFS. It is a tool that allows you to pack and unpack files in .VDF and .MOD format.

Let us start with unpacking \"Sound\" file:

  1. In the \"(Viewer)\" tab, in the \"Filename\", go to your Gothic or Gothic II/Data folder and choose \"Sound.VDF\".
  2. Create a folder on your desktop or any other easily accessible place on your computer. Name it however you want.
  3. Go to \"Root path\" and choose the folder you just created.
  4. Press \"Extract volume\" if you want to unpack all sound files.

The chosen file should be unpacking right now.

Here are the files we just extracted:

It can oftentimes be tricky to find the sound you are looking for, but we will leave that for later. Let's just see how can we change a sound file in the game now.

  1. Get yourself any short sound file.
  2. In order for the sound to work in the game, it needs to be in mono .wav format. A lot of programs let you convert a file such as Audacity, so do just that;
  3. Rename your converted file into \"INV_CHANGE.WAV\" and replace it in SFX folder you just extracted;
  4. Go back to Gothic VDFS, go to (Builder) tab;
  5. In \"Filename\" you choose how do you want your file to be called and its location. I recommend creating separate folder and putting it there. You can also name the file however you want, as long as it has higher time stamp (more on that later) than original Sounds file. To create it as .VDF file, choose \"All file\" in the \"Save file as\" and call it \"Sounds.VDF\";
  6. In \"Root path\" go to and choose \"_WORK\" folder;
  7. In the field just below \"Comment\", add a * character and then click on the + next to it;
  8. Press \"Build\", and if you did everything right, the folder is being packed back into .VDF file;

That's how a successful process looks like:

Now get the file you just created, and put it in your Gothic/Data folder replacing the old one. The file we just replaced changes the sound in main menu and the inventory. If you can hear it, congratulations, you did it!

"},{"location":"zengin/tools/","title":"Tools","text":""},{"location":"zengin/tools/#tools","title":"Tools","text":"

The community has developed many tools to help with the creation of Gothic mods.

Note

This list is a work in progress.

Daedalus

  • Daedalus Language Server - a VS Code/VS Codium extension that adds IDE like functionality for Daedalus scripting language
  • Ikarus - A daedalus library for the game Gothic. Exploits the interpreter to allow arbitrary memory access and defines a lot of useful functions for interfacing with the engine.
  • LeGo - A daedalus library for the game Gothic. It contains various packages to support modders.
  • AFSP - Fawkes' & Auronen's script package for Gothic 1 and Gothic 2: Night of the Raven.
  • Ninja - Ninja introduces the possibility of true modular modifications for the video games Gothic and Gothic 2 Night of the Raven.

VDFS tools

  • GothicVDFS - NicoDE's viewer, extractor and builder for .vdf and .mod volumes
  • VDFS Tool - Gratt's Union VDFS viewer, extractor, builder, optimizer and ZIP compressor for .vdf and .mod volumes

World Editors

  • Spacer - the original world editor for ZenGin, ships with the MDK
  • Union Gothic World Editor - Saturas' world editor, supports new object classes created with Union
  • Gothic World Editor - World editor for vanilla worlds, works with G1, G2 and G2 NotR worlds
  • Spacer.NET - A modernised version of Spacer available as a Gothic Mod.
"},{"location":"zengin/tools/gothic_sourcer/","title":"Gothic Sourcer","text":""},{"location":"zengin/tools/gothic_sourcer/#gothic-sourcer","title":"Gothic Sourcer","text":"

Gothic Sourcer can be used to do a lot of things.

Todo

TODO

"},{"location":"zengin/tools/zSpy/","title":"zSpy","text":""},{"location":"zengin/tools/zSpy/#zspy","title":"zSpy","text":"

zSpy is a debugging tool that displays most of the operations performed by the engine during the Gothic or Spacer running.

Example image of running zSpy

Warning

zSpy must be started before Gothic or the Spacer is started so that the program can find it. Sometimes in Gothic I this has to be done manually, in Gothic II This is done by the GothicStarter_mod.

In order to be able to follow the messages in zSpy, Gothic should be started in the window. The corresponding startup option can be found in GothicStarter (mod). Within Gothic, when Marvin mode is activated, you can switch between window and full-screen mode at any time with the F3 key.

"},{"location":"zengin/tools/zSpy/#log-level","title":"Log Level","text":"

With the -zlog# command in GothicStarter, you can specify how many messages zSpy will output. # can be a number between -1 and 9. Used for:

  • -1 - Disable every message (expect fatal errors)

  • 0 - Shows only warnings, faults and fatal errors

  • 1 - 9 - Display more information. Every Information has their priority. If you select 1, the program displays only messages with priority =< 1, with 5 only priority =< 5, and with 9, almost everything that Gothic can produce.

For general debugging, recommended value is 5.

"},{"location":"zengin/tools/zSpy/#output","title":"Output","text":"

The zSpy issues its reports in the following form:

Time  Type  Priority  User   Message              ...      <filename,       #line>\n00:21 Info:  3        B:     GOTHIC: Exiting game ... .... <oGameManager.cpp,#617>\n
"},{"location":"zengin/tools/zSpy/#time","title":"Time","text":"

Time elapsed since the start of Gothic.exe

"},{"location":"zengin/tools/zSpy/#type","title":"Type","text":"

Type of message. The following message types are distinguished:

  • Fatal: - Critical error causing application to close.

  • Fault: - A simple bug that will not cause the application to stop, but display or performance issues may occur.

  • Warn: - A warning of possible consequences. An error that follows soon afterwards could have something to do with it.

  • Info: - General information about the progress of the program.

"},{"location":"zengin/tools/zSpy/#priority","title":"Priority","text":"

Priority level of the message. Messages with lower priority (higher number) can be disabled. See log level.

"},{"location":"zengin/tools/zSpy/#user","title":"User","text":"

User ID - a letter defined by every engine developer to highlight its logs

  • D - Dieter
  • U - Ulf
  • B - Bert
  • C - Carsten
  • A - Andre
  • X - Kurt
"},{"location":"zengin/tools/zSpy/#message","title":"Message","text":"

The most important part. A message that contains:

  • Symbol representing a program module. The names are mostly self-explanatory, so there is no need to type them all (MDL = 3D models, PAR = Parser etc.).

  • The message for the user.

"},{"location":"zengin/tools/zSpy/#configuration","title":"Configuration","text":"

In zSpy, you can customize the font and its color depending on the type of message.

In addition, you can configure the logging options:

  • Filtering various messages (Info, Warn, Fault, Fatal).
  • Auto show/hide zSpy when starting/stopping Gothic.
  • Saving the log file to a separate file.
"},{"location":"zengin/tools/zSpy/#console-commands","title":"Console commands","text":"

List of console commands related with zSpy.

Note

The list is work in progress. Console commands needs a separate article or section.

"},{"location":"zengin/tools/zSpy/#zerr-level","title":"zerr level","text":"

Sets a level of logging.

zerr level <#>\n
  • <#> - max message priority. See log level.
"},{"location":"zengin/tools/zSpy/#zerr-searchspy","title":"zerr searchspy","text":"

Links zSpy with Gothic. Useful when you run zSpy when the game is already running.

zerr searchspy\n
"},{"location":"zengin/tools/zSpy/#zerr-authors","title":"zerr authors","text":"

Sets a filter to display only messages of one author.

zerr authors <letter>\n
  • <letter> - One of the letters listed here.
"},{"location":"zengin/tools/zSpy/#zerr-rem","title":"zerr rem","text":"

Includes a remark into the log.

zerr rem\n
Looks like that:
00:46 Info:  3 B:       OPT: Blood-Details: Value=2 .... <oGameManager.cpp,#1302>\n00:57 ---------------\n00:57 ---------------\n01:01 Info:  3 B:     GMAN: Leaving Menu-Section .... <oGameManager.cpp,#1537>\n
"},{"location":"zengin/tools/zSpy/#zerr-status","title":"zerr status","text":"

Displays a current status of zSpy in the console.

zerr status\n
"},{"location":"zengin/tools/daedalus_tools/daedalus_language_server/","title":"Daedalus Language Server","text":""},{"location":"zengin/tools/daedalus_tools/daedalus_language_server/#daedalus-language-server","title":"Daedalus Language Server","text":"

Daedalus Language Server

Todo

TODO

"},{"location":"zengin/tools/vdfs_tools/gothic_vdfs/","title":"GothicVDFS","text":""},{"location":"zengin/tools/vdfs_tools/gothic_vdfs/#gothicvdfs","title":"GothicVDFS","text":"

Gothic VDFS is still the most popular VDFS tool. It was created by NicoDE.

"},{"location":"zengin/tools/vdfs_tools/gothic_vdfs/#download","title":"Download","text":"

You can download the tool from NicoDE's website - direct link.

"},{"location":"zengin/tools/vdfs_tools/gothic_vdfs/#quick-overview","title":"Quick overview","text":""},{"location":"zengin/tools/vdfs_tools/vdfs_tool/","title":"VDFS Tool","text":""},{"location":"zengin/tools/vdfs_tools/vdfs_tool/#vdfs-tool","title":"VDFS Tool","text":"

VDFS Tool is a new program that supports new features introduced to VDFS by the Union team. Like ZIP compression or drag and drop support.

"},{"location":"zengin/tools/vdfs_tools/vdfs_tool/#download","title":"Download","text":"

You can download the tool from the post on WoP.ru - VDFS Tool or using the Resource Manager

"},{"location":"zengin/tools/vdfs_tools/vdfs_tool/#quick-overview","title":"Quick overview","text":""},{"location":"zengin/union/","title":"Union","text":""},{"location":"zengin/union/#union","title":"Union","text":"

Union is a system to patch and extend Gothic's engine the ZenGin. It allows you to load .dll files - ZenGin extensions created using the Gothic/Union SDK and .patch files - files designed to patch the game's executable. The Union installer also contains the SystemPack a collection of bug fixes and engine edits that improve performance.

"},{"location":"zengin/union/#plug-ins","title":"Plug-ins","text":"

Union plugins are shipped in the form of a .dll library. This library contains the compiled C++ code with the Union SDK and an embedded .patch file.

"},{"location":"zengin/union/#union-sdk--gothic-api","title":"Union SDK & Gothic API","text":"

Union software development kit is a collection of tools and the Gothic API that allow you to create Union plugins and alter the engine's behavior. Gothic API is a set of 4 interfaces (each for one different ZenGin version) that allow you to interface with the engine, access the engine objects, change their behavior and introduce new classes and functionality.

"},{"location":"zengin/union/#patch-file-format","title":"PATCH file format","text":"

The .patch file contains one or more small programs that are designed to change the engine code (game executable). This is usually done to fix bugs. Union plug-ins contain an embedded .patch file and this file usually contains changes to the binary necessary for the proper function of the plug-in.

"},{"location":"zengin/union/plugins/zbassmusic/","title":"zBassMusic","text":""},{"location":"zengin/union/plugins/zbassmusic/#zbassmusic","title":"zBassMusic","text":"

zBassMusic is a modern music system for Gothic I and Gothic II NotR based on BASS Audio Library made by Silver Ore Team. It replaces the old DirectMusic system to let the modders create music for Gothic as regular audio files instead of DirectMusic format.

Info

For the plugin documentation, visit the github site of a project. The documentation is build into the code.

Contacts Authors Silver Ore Team - tehe GitHub zBassMusic Discord Gothic Modding Community server"},{"location":"zengin/union/plugins/zbassmusic/#features","title":"Features","text":"
  • Music playback with modern audio formats like WAV, MP3, OGG
  • Out-of-the-box support for existing C_MUSICTHEME instances
  • Scriptable interface to take full control of music scheduling
  • Loading music files from VDFS volumes (excluding .sgt)
  • Backwards compatibility with DirectMusic .sgt files
"},{"location":"zengin/union/plugins/zgamepad/","title":"zGamePad","text":""},{"location":"zengin/union/plugins/zgamepad/#zgamepad","title":"zGamePad","text":"

zGamePad plugin adds gamepad support for ZenGin games.

Important

Visit the excellent original GitHub wiki page.

Contacts Author Gratt GitHub zGamePad Forum zGamePad"},{"location":"zengin/union/plugins/zgamepad/#gamepad-support","title":"Gamepad support","text":"
  • All xinput compatible (including emulators)
  • Xbox controller family
  • Dualshock 4
  • Dualsense
  • Nintendo Switch Joy-Cons
  • Nintendo Switch Pro Controller
"},{"location":"zengin/union/plugins/zgamepad/#features","title":"Features","text":"
  • Natural Movements Intuitiveness and smoothness of movement controls is the main goal of this plugin. Touch the world of Gothic with your hands.
  • Interactive hints Interactive hints will help you in mastering the controls. You can always customize their appearance or disable them.
  • Quick access The plugin has two quick access rings - **weapons and items. Use them to always have access to your items.
  • Automatic save naming Sit comfortably. You do not have to reach for your keyboard, because the plugin itself will give a name to your saves.
  • Saves rotation The best alternative to quicksaves for gamepad controls.
  • Vibration response Immerse yourself in the game even more. Vibration will allow you to feel your character and everything that happens in the world.
  • Target locking The plugin will always help you win. Keeping the enemy in focus will allow you to fight much more effectively.
  • Stuck protection Oops! If you get stuck, hold both analogue sticks for a few seconds and the character will reset.
"},{"location":"zengin/union/plugins/zgamepad/controls/","title":"Gamepad controls","text":""},{"location":"zengin/union/plugins/zgamepad/controls/#gamepad-controls","title":"Gamepad controls","text":"

The zGamePad plugin comes with a default control scheme, but it is possible to create your own. The plugin will search for any file with the .gamepad.overlay extension placed in Gothic/System directory or in any of the loaded .mod and .vdf archives.

"},{"location":"zengin/union/plugins/zgamepad/controls/#control-file-syntax","title":"Control file syntax","text":"

Gamepad controls are set using the .gamepad configuration file. This file encodes the controls for different actions in the game and the hint string in multiple languages.

Warning

The .gamepad file must be encoded in Unicode or UTF-8 to accommodate the multilingual hint strings.

"},{"location":"zengin/union/plugins/zgamepad/controls/#regions","title":"Regions","text":"

The format supports code blocks specified by the #region and #endregion keywords. These regions do not have any syntactical meaning, they only offer a convenient way to collapse sections of the code in editors with the syntax highlighting capabilities such as Notepad++

Regions
#region strings\n    // TODO\n#endregion\n\n#region fight scheme\n    // TODO\n#endregion\n
"},{"location":"zengin/union/plugins/zgamepad/controls/#comments","title":"Comments","text":"

Comments are useful for quick information or just to disable some old code that might come in handy later. The .gamepad file syntax supports C++ line comments using two forward slashes //.

Warning

Comments can only be used at the start of any given line!

Comments
// this is a comment\nKeyRecord // this is NOT a comment\n
"},{"location":"zengin/union/plugins/zgamepad/controls/#strings","title":"Strings","text":"

Strings are used for interactive hints. They should be defined at the top of the file. To define a string, use the keyword String. Strings have the following format:

Multilang string syntax
String [id]\n    [langTag] [text]\n    [langTag] [text]\n    [langTag] [text]\n
"},{"location":"zengin/union/plugins/zgamepad/controls/#example","title":"Example","text":"
String interact\n    Rus \"\u0412\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c\"\n    Eng \"Interact\"\n    Pol \"Interakcja\"\n    Deu \"Interagieren\"\n\nString remove_weapon\n    Rus \"\u0423\u0431\u0440\u0430\u0442\u044c \u043e\u0440\u0443\u0436\u0438\u0435\"\n    Eng \"Remove weapon\"\n    Pol \"Chowanie broni\"\n    Deu \"Waffe entfernen\"\n
The string name must be unique and is used to reference the string while defining hints. The language tag matches the language in SystemPack.ini. If the file does not contain the user's language, English will be taken by default. If there is no English, then the first one."},{"location":"zengin/union/plugins/zgamepad/controls/#control-bindings","title":"Control bindings","text":"

A binding is a description of an event that includes emulation object and conditions. Hints are part of the binding. The general structure of the bind starts with the keyword KeyRecord and has the following format:

Control binding
KeyRecord [modifier]\n    Id          [key name]\n    Combination [gamepad keys]\n    Emulation   [engine logical and absolute keys]\n    Condition   [engine logical, absolute keys or logical functions]\n    Help        [name of the hint string]\n
  • Id - unique identifier used by other users to override this control binding
  • [modifier] - can be empty or take the value of Toggled If the value is empty, the control binding will work as long as the player holds down the specified button or button combination. If the value is Toggled, the control binding will work only when the player toggles the button or button combination. (One press to start sneaking, another press to stop sneaking)
  • Combination - these are the gamepad buttons that the player must press or hold to activate the control binding.
  • Emulation - specify which buttons will be emulated. You can specify absolute buttons, or that are defined in the game settings (logical).
  • Condition - specify the condition under which the control binding can be activated. To invert condition, use the operator ! before the operand (!Cond_IsOverlayTop, !JOY_B)
  • Help - name of the text string with a hint which will be displayed when the Conditions are met.

  • [gamepad keys] - Gamepad key list

  • [engine logical keys] - Engine logical key list
  • [engine absolute keys] - Engine absolute key list
  • [logical functions] - Logical function list

Tip

All operators are optional! This means that if a binding should only show a hint, it doesn't have to contain Combination.

"},{"location":"zengin/union/plugins/zgamepad/controls/#example_1","title":"Example","text":"Control binding examples
KeyRecord\n    Id          StopUsingPicklock\n    Combination JOY_B\n    Emulation   KEY_DOWN\n    Condition   Cond_InterfaceIsOpen, Cond_UsesPicklock, !JOY_B\n\nKeyRecord Toggled\n    Id          ReturnToHumanForm\n    Combination JOY_A\n    Emulation   KEY_RETURN\n    Condition   Cond_InTransformation\n    Help        end_transform\n\nKeyRecord\n    Id          QuickRingSelectSlot\n    Combination JOY_RSTICK_FULL\n    Condition   !Cond_InventoryIsOpen, Cond_IsOverlayTop\n    Help        focus_item\n
"},{"location":"zengin/union/plugins/zgamepad/controls/#controls-override","title":"Controls override","text":"

If you want to change or remove bindings from another controls file, use the KeyDisable keyword. Default controls file

Controls override syntax
KeyDisable [fileName].[Id]\n
Where fileName is the name of the controls file without extension and id is a key of the binding."},{"location":"zengin/union/plugins/zgamepad/controls/#example_2","title":"Example","text":"Controls override example
// remove key from the main controls file\nKeyDisable Controls.ArrowDown\n\n// create new key based on the same buttons\nKeyRecord Toggled\n    Id          ArrowDownNew\n    Combination JOY_DOWN\n    Emulation   GAME_DOWN\n
"},{"location":"zengin/union/plugins/zgamepad/keys_engine_absolute/","title":"Engine absolute keys","text":""},{"location":"zengin/union/plugins/zgamepad/keys_engine_absolute/#engine-absolute-keys","title":"Engine absolute keys","text":"

Absolute keys are the physical keys on your keyboard.

MOUSE_DX\nMOUSE_DY\nMOUSE_UP\nMOUSE_DOWN\nMOUSE_LEFT\nMOUSE_RIGHT\nMOUSE_WHEELUP\nMOUSE_WHEELDOWN\nMOUSE_BUTTONLEFT\nMOUSE_BUTTONRIGHT\nMOUSE_BUTTONMID\nMOUSE_XBUTTON1\nMOUSE_XBUTTON2\nMOUSE_XBUTTON3\nMOUSE_XBUTTON4\nMOUSE_XBUTTON5\nKEY_ESCAPE\nKEY_1\nKEY_2\nKEY_3\nKEY_4\nKEY_5\nKEY_6\nKEY_7\nKEY_8\nKEY_9\nKEY_0\nKEY_MINUS\nKEY_EQUALS\nKEY_BACK\nKEY_TAB\nKEY_Q\nKEY_W\nKEY_E\nKEY_R\nKEY_T\nKEY_Y\nKEY_U\nKEY_I\nKEY_O\nKEY_P\nKEY_LBRACKET\nKEY_RBRACKET\nKEY_RETURN\nKEY_LCONTROL\nKEY_A\nKEY_S\nKEY_D\nKEY_F\nKEY_G\nKEY_H\nKEY_J\nKEY_K\nKEY_L\nKEY_SEMICOLON\nKEY_APOSTROPHE\nKEY_GRAVE\nKEY_LSHIFT\nKEY_BACKSLASH\nKEY_Z\nKEY_X\nKEY_C\nKEY_V\nKEY_B\nKEY_N\nKEY_M\nKEY_COMMA\nKEY_PERIOD\nKEY_SLASH\nKEY_RSHIFT\nKEY_MULTIPLY\nKEY_LMENU\nKEY_SPACE\nKEY_CAPITAL\nKEY_F1\nKEY_F2\nKEY_F3\nKEY_F4\nKEY_F5\nKEY_F6\nKEY_F7\nKEY_F8\nKEY_F9\nKEY_F10\nKEY_NUMLOCK\nKEY_SCROLL\nKEY_NUMPAD7\nKEY_NUMPAD8\nKEY_NUMPAD9\nKEY_SUBTRACT\nKEY_NUMPAD4\nKEY_NUMPAD5\nKEY_NUMPAD6\nKEY_ADD\nKEY_NUMPAD1\nKEY_NUMPAD2\nKEY_NUMPAD3\nKEY_NUMPAD0\nKEY_DECIMAL\nKEY_OEM_102\nKEY_F11\nKEY_F12\nKEY_F13\nKEY_F14\nKEY_F15\nKEY_KANA\nKEY_ABNT_C1\nKEY_CONVERT\nKEY_NOCONVERT\nKEY_YEN\nKEY_ABNT_C2\nKEY_NUMPADEQUALS\nKEY_PREVTRACK\nKEY_AT\nKEY_COLON\nKEY_UNDERLINE\nKEY_KANJI\nKEY_STOP\nKEY_AX\nKEY_UNLABELED\nKEY_NEXTTRACK\nKEY_NUMPADENTER\nKEY_RCONTROL\nKEY_MUTE\nKEY_CALCULATOR\nKEY_PLAYPAUSE\nKEY_MEDIASTOP\nKEY_VOLUMEDOWN\nKEY_VOLUMEUP\nKEY_WEBHOME\nKEY_NUMPADCOMMA\nKEY_DIVIDE\nKEY_SYSRQ\nKEY_RMENU\nKEY_PAUSE\nKEY_HOME\nKEY_UP\nKEY_PRIOR\nKEY_LEFT\nKEY_RIGHT\nKEY_END\nKEY_DOWN\nKEY_NEXT\nKEY_INSERT\nKEY_DELETE\nKEY_LWIN\nKEY_RWIN\nKEY_APPS\nKEY_POWER\nKEY_SLEEP\nKEY_WAKE\nKEY_WEBSEARCH\nKEY_WEBFAVORITES\nKEY_WEBREFRESH\nKEY_WEBSTOP\nKEY_WEBFORWARD\nKEY_WEBBACK\nKEY_MYCOMPUTER\nKEY_MAIL\nKEY_MEDIASELECT\nKEY_BACKSPACE\nKEY_NUMPADSTAR\nKEY_LALT\nKEY_CAPSLOCK\nKEY_NUMPADMINUS\nKEY_NUMPADPLUS\nKEY_NUMPADPERIOD\nKEY_NUMPADSLASH\nKEY_RALT\nKEY_UPARROW\nKEY_PGUP\nKEY_LEFTARROW\nKEY_RIGHTARROW\nKEY_DOWNARROW\nKEY_PGDN\n
"},{"location":"zengin/union/plugins/zgamepad/keys_engine_logical/","title":"Engine logical keys","text":""},{"location":"zengin/union/plugins/zgamepad/keys_engine_logical/#engine-logical-keys","title":"Engine logical keys","text":"

Logical keys are the keys you set in keyboard settings in the game menu. These can fill multiple roles in different situations and the gamepad controls can be set to emulate these logical keys.

GAME_LEFT\nGAME_RIGHT\nGAME_UP\nGAME_DOWN\nGAME_ACTION\nGAME_SLOW\nGAME_ACTION2\nGAME_WEAPON\nGAME_SMOVE\nGAME_SMOVE2\nGAME_SHIFT\nGAME_END\nGAME_INVENTORY\nGAME_LOOK\nGAME_SNEAK\nGAME_STRAFELEFT\nGAME_STRAFERIGHT\nGAME_SCREEN_STATUS\nGAME_SCREEN_LOG\nGAME_SCREEN_MAP\nGAME_LOOK_FP\nGAME_LOCK_TARGET\nGAME_PARADE\nGAME_ACTIONLEFT\nGAME_ACTIONRIGHT\nGAME_LAME_POTION\nGAME_LAME_HEAL\n
"},{"location":"zengin/union/plugins/zgamepad/keys_gamepad/","title":"Gamepad keys","text":""},{"location":"zengin/union/plugins/zgamepad/keys_gamepad/#gamepad-keys","title":"Gamepad keys","text":"

In order to set gamepad keys, you have to know the key codes as they are listed below.

JOY_UP\nJOY_DOWN\nJOY_LEFT\nJOY_RIGHT\nJOY_MENU\nJOY_VIEW\nJOY_LSTICK\nJOY_RSTICK\nJOY_LB\nJOY_RB\nJOY_A\nJOY_B\nJOY_X\nJOY_Y\nJOY_LSTICK_LOWUP\nJOY_LSTICK_UP\nJOY_LSTICK_DOWN\nJOY_LSTICK_LEFT\nJOY_LSTICK_RIGHT\nJOY_RT\nJOY_LT\nJOY_DPAD\nJOY_UPDOWN\nJOY_LEFTRIGHT\nJOY_LSTICK_FULL\nJOY_RSTICK_FULL\n
"},{"location":"zengin/union/plugins/zgamepad/logical_functions/","title":"Logical function names","text":""},{"location":"zengin/union/plugins/zgamepad/logical_functions/#logical-function-names","title":"Logical function names","text":"

Conditions for when to show or allow the control binding to work are specified using these logic functions. They describe different useful states of the game or user interface, allowing the user to set when will a certain control work.

Cond_FightMode        - player is in the fight mode\nCond_FightModeMelee   - player is in the melee fight mode\nCond_FightModeRange   - player is in the ranged fight mode\nCond_FightModeMagic   - player is in the magical fight mode\nCond_CanShoot         - player is in the aim mode and can shoot now\nCond_CanSneaking      - player is sneaking now\nCond_Diving           - player is diving now\nCond_HasFocusVob      - player has a focus vob\nCond_HasFocusNpc      - player has a focus npc\nCond_OnChooseWeapon   - weapon selection is active\nCond_InventoryIsOpen  - inventory is open\nCond_InTransformation - player is transformed\nCond_VideoIsOpen      - video is playing\nCond_CanLockTarget    - player in the fight mode now and can lock the focus vob\nCond_G1               - this engine is a Gothic 1 (or sequel)\nCond_G2               - this engine is a Gothic 2 NoTR (or classic)\nCond_IsDialogTop      - dialog window is open on the top\nCond_IsDocumentTop    - document object is open on the top\nCond_IsOverlayTop     - gamepad overlay object is open on the top\nCond_IsMenuTop        - game menu is open on the top\nCond_OnSpellBook      - magic selection ring is active\nCond_IsPlayerTalking  - player is talking to someone\nCond_InterfaceIsOpen  - open any interface element\nCond_HasLeftContainer - the left container is open (chest, plunder, trader)\nCond_UsesPicklock     - player is picking a lock now\nCond_IsOnTrade        - player is trading\nCond_IsOverlayTop     - gamepad overlay object is open on the top\nCond_IsMenuTop        - game menu is open on the top\n
"},{"location":"zengin/union/sdk/","title":"Union SDK","text":""},{"location":"zengin/union/sdk/#union-sdk","title":"Union SDK","text":"

Union SDK is a software development kit for making Union plugins that directly interact with Gothic engines. It contains a project template for Visual Studio IDE, a C++ library for hooking into a Gothic executable, and Gothic API with methods' addresses for the engines of Gothic I, Gothic II, Gothic II NotR, and also for the not released Gothic Sequel.

Working with Union SDK requires at least basic knowledge of C++ programming. Knowledge of the x86 (32-bit) architecture, dynamically linked libraries, and reverse engineering is also welcomed as we need to understand what the Gothic engine does under the hood to use it effectively.

"},{"location":"zengin/union/sdk/#requirements","title":"Requirements","text":"

Union SDK requires Visual Studio IDE, NET Framework 4.7.2, and Visual C++ 2010 libraries. They are available on Microsoft websites:

  • Visual Studio - https://visualstudio.microsoft.com/vs/
  • NET Framework 4.7.2 - https://dotnet.microsoft.com/download/dotnet-framework/net472
  • Visual C++ 2010 - https://www.microsoft.com/download/details.aspx?id=26999
"},{"location":"zengin/union/sdk/#resource-manager","title":"Resource Manager","text":"

The official installation of Union SDK is provided through Resource Manager. After the installation, Visual Studio will have a new project template \"Union Plugin 1.0\" that creates a basic Union plugin project.

"},{"location":"zengin/union/sdk/events/","title":"Game Events","text":""},{"location":"zengin/union/sdk/events/#game-events","title":"Game Events","text":"

Union defines several Game Events that are dispatched when a specific event occurs in-game. Handlers are defined in Plugin.cpp and we can use them to execute our code during specific moments of the application lifetime.

"},{"location":"zengin/union/sdk/events/#events","title":"Events","text":""},{"location":"zengin/union/sdk/events/#initialization","title":"Initialization","text":""},{"location":"zengin/union/sdk/events/#game_entry","title":"Game_Entry","text":"

Executes at the entry point of the Gothic executable. During this time the engine classes are not yet initialized, so using them may cause an access violation. The entry point be used to execute some logic before Gothic loads itself.

void Game_Entry() {\n\n}\n
"},{"location":"zengin/union/sdk/events/#game_defineexternals","title":"Game_DefineExternals","text":"

Executes before the Daedalus parser starts loading scripts. It's meant to define custom external functions.

void Game_DefineExternals() {\n\n}\n
"},{"location":"zengin/union/sdk/events/#game_init","title":"Game_Init","text":"

Executes right after DAT files are loaded and just before the main menu shows up.

void Game_Init() {\n\n}\n
"},{"location":"zengin/union/sdk/events/#level-change","title":"Level Change","text":""},{"location":"zengin/union/sdk/events/#game_loadbegin","title":"Game_LoadBegin","text":"

Executes when we initiate a level change by one of the possible actions. The default plugin template uses a common LoadBegin() function to handle all events but we also can write different logic for different cases.

void LoadBegin() {\n\n}\n\n// When player clicks \"New Game\"\nvoid Game_LoadBegin_NewGame() {\n    LoadBegin();\n}\n\n// When player loads a saved game\nvoid Game_LoadBegin_SaveGame() {\n    LoadBegin();\n}\n\n// When player changes ZEN by a trigger\nvoid Game_LoadBegin_ChangeLevel() {\n    LoadBegin();\n}\n
"},{"location":"zengin/union/sdk/events/#game_loadend","title":"Game_LoadEnd","text":"

Executes when the level loading finishes. The default plugin template uses a common LoadEnd() function to handle all events but we also can write different logic for different cases.

void LoadEnd() {\n\n}\n\n// When player clicks \"New Game\"\nvoid Game_LoadEnd_NewGame() {\n    LoadEnd();\n}\n\n// When player loads a saved game\nvoid Game_LoadEnd_SaveGame() {\n    LoadEnd();\n}\n\n// When player changes ZEN by a trigger\nvoid Game_LoadEnd_ChangeLevel() {\n    LoadEnd();\n}\n
"},{"location":"zengin/union/sdk/events/#game_loadbegin_trigger","title":"Game_LoadBegin_Trigger","text":"

Executes when the player enters a trigger that initiates ZEN change.

void Game_LoadBegin_Trigger() {\n\n}\n
"},{"location":"zengin/union/sdk/events/#game_loadend_trigger","title":"Game_LoadEnd_Trigger","text":"

Executes after the player has entered a trigger that initiates ZEN change.

void Game_LoadEnd_Trigger() {\n\n}\n
"},{"location":"zengin/union/sdk/events/#game_applyoptions","title":"Game_ApplyOptions","text":"

Executes after Game_LoadEnd, when we save the game, and also when we exit the game. It's meant to be used to apply options from INI files.

void Game_ApplyOptions() {\n\n}\n
"},{"location":"zengin/union/sdk/events/#game-loop","title":"Game Loop","text":""},{"location":"zengin/union/sdk/events/#game_preloop","title":"Game_PreLoop","text":"

Executes at the start of every frame.

void Game_PreLoop() {\n\n}\n
"},{"location":"zengin/union/sdk/events/#game_loop","title":"Game_Loop","text":"

Executes at every frame.

void Game_Loop() {\n\n}\n
"},{"location":"zengin/union/sdk/events/#game_postloop","title":"Game_PostLoop","text":"

Executes at the end of every frame.

void Game_PostLoop() {\n\n}\n
"},{"location":"zengin/union/sdk/events/#game_menuloop","title":"Game_MenuLoop","text":"

Executes at every frame when the game menu is active.

void Game_MenuLoop() {\n\n}\n
"},{"location":"zengin/union/sdk/events/#game_savebegin","title":"Game_SaveBegin","text":"

Executes when the player started saving a game.

void Game_SaveBegin() {\n\n}\n
"},{"location":"zengin/union/sdk/events/#game_saveend","title":"Game_SaveEnd","text":"

Executes when the game save finishes.

void Game_SaveEnd() {\n\n}\n
"},{"location":"zengin/union/sdk/events/#game_pause","title":"Game_Pause","text":"

Executes when the player opens the in-game menu.

void Game_Pause() {\n\n}\n
"},{"location":"zengin/union/sdk/events/#game_unpause","title":"Game_Unpause","text":"

Executes when the player leaves the in-game menu and also when the player loads a saved game.

void Game_Unpause() {\n\n}\n
"},{"location":"zengin/union/sdk/events/#shutdown","title":"Shutdown","text":""},{"location":"zengin/union/sdk/events/#game_exit","title":"Game_Exit","text":"

Executes when the player exits the game.

void Game_Exit() {\n\n}\n
"},{"location":"zengin/union/sdk/externals/","title":"Externals","text":""},{"location":"zengin/union/sdk/externals/#externals","title":"Externals","text":"

Externals are functions defined by the Gothic engine that can be called from scripts. Union SDK provides symbols for pointers to global zCParser instances that we can use to interact with the parser and to define a custom external function.

extern zCParser*    parser;\nextern zCParser*&   parserSoundFX;\nextern zCParser*&   parserParticleFX;\nextern zCParser*&   parserVisualFX;\nextern zCParser*&   parserCamera;\nextern zCParser*&   parserMenu;\nextern zCParser*&   parserMusic;\n
"},{"location":"zengin/union/sdk/externals/#creating-custom-external","title":"Creating custom external","text":"

To create an external we need to define a function handler and register it in the parser. Before we start, it's good to write down a Daedalus function signature so we can see the return and argument types that will be important later.

func string AddNumbers(var int FirstArgument, var int SecondArgument, var string ThirdArgument)  {}\n
"},{"location":"zengin/union/sdk/externals/#function-handler","title":"Function handler","text":"

External function handler signature must:

  • return int or bool
  • use __cdecl calling convention (default in C++)
  • take no arguments

Inside the handler, we can use the global parser to pop function arguments and push the return value from/to the stack. It's important to pop the arguments in reverse order and to pop all of them even if we are not going to use them. Similarly, the return value must always be set if any and must never be set if the function returns void. If we don't follow the rules, the stack may get corrupted and lead to the Gothic crash.

// __cdecl is optional because it's the default calling convention\nint __cdecl AddNumbers_External()\n{\n    // Declare arguments\n    int FirstArgument;\n    int SecondArgument;\n    zSTRING ThirdArgument;\n\n    // Pop arguments from the stack **IN REVERSE ORDER**\n    parser->GetParameter(ThirdArgument);\n    parser->GetParameter(SecondArgument);\n    parser->GetParameter(FirstArgument);\n\n    // Execute function logic\n    int result = FirstArgument + SecondArgument;\n    zSTRING output = ThirdArgument + zSTRING(result);\n\n    // Push return value\n    parser->SetReturn(output);\n\n    // Return value is ignored, so 0 or 1 is fine.\n    return 0;\n}\n
"},{"location":"zengin/union/sdk/externals/#register-external","title":"Register external","text":"

Externals should be registered in the parser during the Game_DefineExternals game event. We need to call parser->DefineExternal with variadic arguments:

  • external function name in Daedalus
  • reference to function handler
  • return type
  • ...argument types
  • zPAR_TYPE_VOID indicates the end of the argument types list
void Game_DefineExternals() {\n    parser->DefineExternal(\"AddNumbers\", AddNumbers_External, zPAR_TYPE_STRING, zPAR_TYPE_INT, zPAR_TYPE_INT, zPAR_TYPE_STRING, zPAR_TYPE_VOID);\n}\n

Available types are defined by an enum:

enum {\n    zPAR_TYPE_VOID,\n    zPAR_TYPE_FLOAT,\n    zPAR_TYPE_INT,\n    zPAR_TYPE_STRING,\n    zPAR_TYPE_CLASS,\n    zPAR_TYPE_FUNC,\n    zPAR_TYPE_PROTOTYPE,\n    zPAR_TYPE_INSTANCE\n};\n
"},{"location":"zengin/union/sdk/getting_started/","title":"Getting Started","text":""},{"location":"zengin/union/sdk/getting_started/#getting-started","title":"Getting Started","text":"

This article provides a beginner-friendly tutorial for setting up and compiling a Union project. Instructions for installing Union SDK are located at Union SDK.

"},{"location":"zengin/union/sdk/getting_started/#creating-union-plugin","title":"Creating Union plugin","text":""},{"location":"zengin/union/sdk/getting_started/#create-a-visual-studio-project","title":"Create a Visual Studio project","text":"

To create a Union plugin project inside Visual Studio we need to use File -> New -> Project. On the next screen, we select \"Union Plugin 1.0m\", and click Next. For the project configuration, we should choose:

Key Value Project name eg. MyPlugin Location Directory where to store the source code Solution Create new solution Solution name eg. MyPlugin

We will also check \"Place solution and project in the same directory\" because our plugin consists of only one project, so there is no need to complicate the file structure.

"},{"location":"zengin/union/sdk/getting_started/#file-structure","title":"File Structure","text":"Folder / File Description Engine\u00a0SDK/ In this folder, we have the Gothic Engine API in the form of header files. Most of the files between engines are very similar to each other but they can't be used interchangeably because each engine has slightly different API and addresses of functions. Engine\u00a0SDK/User\u00a0API/ These are empty files that are included in the corresponding engine headers. There are meant for placing additional methods extending classes that can be used for example in Hooks. Plugin/System/ DLL entry point generated by Union. We shouldn't modify anything here. Plugin/Workspace/Interface/ These are header files containing headers and source files important in correct order and an Interface.cpp file that merges all the code into one file. Plugin/Workspace/Plugin/ Finally, this is the source code of the plugin and especially Plugin.cpp where we can create code executed on Game Events."},{"location":"zengin/union/sdk/getting_started/#build-configuration","title":"Build Configuration","text":"

Each Union plugin may target one or many versions of the Gothic engine and to select the proper API, Union SDK defines several build configurations for every engine, configuration, and also multiplatform build options. Each Target/Configuration combination is named [ENGINE] [CONFIGURATION].

Configurations:

  • Debug: Unoptimized build with debug symbols for development.
  • MD Release: Optimized build for release versions. Runtime Library: Multi-threaded DLL (/MD)
  • MT Release: Optimized build for release versions. Runtime Library: Multi-threaded (/MT)

Engines:

  • G1: Gothic I
  • G1A: Gothic Sequel
  • G2: Gothic II
  • G2A: Gothic II NotR
  • MP x2: Multiplatform target for both Gothic I (G1) and Gothic II NotR (G2A)
  • MP x4: Multiplatform target for all engine versions (Gothic I, Gothic Sequel, Gothic II, Gothic II NotR)

For learning Union, it's suggested to select G2A Debug for Gothic II NotR or G1 Debug for Gothic I.

"},{"location":"zengin/union/sdk/getting_started/#project-configuration","title":"Project Configuration","text":"

The Union plugin is a regular C++ Visual Studio project so it's possible to configure the project, compiler, linker, and debugger as we wish by going into Project -> Properties. For a starter, we should go to the General tab and check if Platform Toolset is installed and selected. If not, we should select one that's available on our system. Union was created with v100 but it also supports the newest toolkits, so it's best to select a modern one.

In the General tab, we can also specify the Output Directory where the plugin DLL will be placed after the build. During development, we can set it to <GOTHIC_DIR>/System/Autorun where <GOTHIC_DIR> is the root folder of the Gothic installation with Union that we will use for testing. Each DLL file placed in System/Autorun is automatically loaded by Union runtime.

Another method is to put the DLL in the System directory and modify Gothic.ini to include

[PLUGIN]\n# Plugin file names without .dll \nPluginList = MyPlugin \n
"},{"location":"zengin/union/sdk/getting_started/#build-the-plugin","title":"Build the plugin","text":"

After the initial configuration, we are ready to code something and see if our configuration is working. Let's collect some information about Union and display it with a MessageBox when the game starts. To do so, we locate the Plugin.cpp file and put our logic in one of the Game Events handlers. The best for that is Game_Init() because it's executed right after the engine loads every DAT file but before anything else:

void Game_Init() {\n    const CPlugin* myPlugin = CPlugin::GetCurrentPlugin();\n\n    CStringA gothicVersion;\n    switch (Union.GetEngineVersion()) {\n        case Engine_G1:  gothicVersion = \"Gothic I\";\n        case Engine_G1A:  gothicVersion = \"Gothic Sequel\";\n        case Engine_G2:  gothicVersion = \"Gothic II\";\n        case Engine_G2A:  gothicVersion = \"Gothic II NoTR\";\n    }\n\n    CStringA message = \"Plugin: \" + myPlugin->GetName() + \"\\n\";\n    message = message + \"Union Version: \" + Union.GetUnionVersion().ToString() + \"\\n\";\n    message = message + \"Gothic Version: \" + gothicVersion;\n\n    Message::Info(message, \"Hello World\");\n}\n

Now we can Build (F7) the project to create the DLL. If we have set up Output Directory before, the plugin will deploy directly to the game. Otherwise, we can copy it manually from Bin to <GOTHIC_DIR>/System/Autorun/MyPlugin.dll. When we launch the game, a MessageBox should appear right before the main menu:

"},{"location":"zengin/union/sdk/getting_started/#couldnt-build-the-plugin","title":"Couldn't build the plugin?","text":"

If you could not build the plugin or it crashed the game, you have to do some debugging and find the root cause of that. For compilation errors look at the Visual Studio Output tab and read the errors.

If they say something about missing toolset, make sure that you selected a Platform Toolset that's installed.

If the proper toolset is selected but doesn't work, make sure that you are configuring the same Configuration that is used for building.

If the plugin was built but the game crashed, you probably selected Configuration for the wrong platform. Gothic 2 Night of the Raven is G2A and doesn't work with G2 or G1A. If you are playing Gothic II Classic from Steam, please be advised that it still uses the Night of The Raven engine so the plugin must target G2A.

"},{"location":"zengin/union/sdk/getting_started/#debugging","title":"Debugging","text":"

Union plugins are regular DLLs with executable code hooked to Gothic.exe and running on it, so they can be debugged using the same techniques as any other software.

"},{"location":"zengin/union/sdk/getting_started/#visual-studio-debugger","title":"Visual Studio Debugger","text":"

Visual Studio Debugger lets us set breakpoints on any line of code to stop the execution when we reach it. It also gives us a lot of information about the program state at this point. To use the debugger we only need to attach it to the Gothic.exe progress and compile the plugin with Debug configuration.

Option #1: Open Project -> Properties and in the Debugging tab, set Command to the path of our Gothic.exe. Then we can run \"Local Windows Debugger\" in Visual Studio and it starts Gothic with a debugger attached automatically.

Option #2: Open Debug -> Attach to process... and filter process list by \"Gothic\". Run the game separately and when the process appears in Visual Studio, select it and attach to it.

Caveats:

  • If we attach to the process early, we may get an \"Exception thrown at 0x7B11DB86 (Shw32.dll) in Gothic2.exe: 0xC0000005: Access violation writing location 0x00ABD000.\" right at the beginning. It's fine, just click Continue and Gothic will start properly.
  • If a breakpoint hits when our cursor is locked by Gothic, we may not be able to get the cursor back until execution continues. In this case, we can still use Alt+Tab to switch to Visual Studio and use F5 to continue or F10 to step over. Disabling mouse support in the config may also fix this problem.
"},{"location":"zengin/union/sdk/getting_started/#print-debugging","title":"Print Debugging","text":"

Printing to some output is probably the simplest form of debugging and Union provides us with several choices.

"},{"location":"zengin/union/sdk/getting_started/#logging-to-zspy","title":"Logging to zSPY","text":"

zSPY can be accessed using a global zerr object. zSPY uses a message filtering system based on the first letter of the message, so our logs should follow the standard format used by other parts of ZenGine. Otherwise, the message may not be visible.

zerr->Message(\"X:   MyPlugin: message to zSPY\");\n
"},{"location":"zengin/union/sdk/getting_started/#logging-to-union-console","title":"Logging to Union console","text":"

Union console needs to be enabled inside SystemPack.ini first:

[CORE]\nShowDebugWindow = true\n
Then we can use a global cmd object behaving like C++ std::cout to log into the Union console:
cmd << \"message to Union console\";\n
"},{"location":"zengin/union/sdk/getting_started/#logging-to-visual-studio","title":"Logging to Visual Studio","text":"

Visual Studio can also receive logs from our plugin using:

OutputDebugString(\"message to Visual Studio\");\n
This method works only when we have a debugger attached, so it's not recommended for general logging."},{"location":"zengin/union/sdk/hooks/","title":"Hooks","text":""},{"location":"zengin/union/sdk/hooks/#hooks","title":"Hooks","text":"

Union provides a hooks system that lets us intercept calls to the engine functions and methods with our custom interceptor. To hook a function or method we need to know its address which can be acquired either from Engine SDK/[Engine]/Names_[Engine].hpp or from the engine classes headers Engine SDK/[Engine]/Headers.

"},{"location":"zengin/union/sdk/hooks/#intercepting-functions","title":"Intercepting functions","text":"

To declare a hook we can use CInvoke class or HOOK AS macros.

CInvoke<function_type> Ivk_HookName(orignal_function_address, our_interceptor_function, hook_flags);\n\nHOOK Ivk_HookName AS(orignal_function_address, our_interceptor_function, hook_flags);\n
"},{"location":"zengin/union/sdk/hooks/#regular-functions","title":"Regular functions","text":"

Regular functions are the functions declared outside of classes.

// 0x0042C450 int __cdecl Apply_Options_Video(void)\n\n// Forward declaration\nint Apply_Options_Video(); \n\n// Hook declaration\nCInvoke<int(*)()> Ivk_Apply_Options_Video(0x0042C450, &Apply_Options_Video);\n// Equivalent:\n// HOOK Ivk_Apply_Options_Video AS(0x0042C450, &Apply_Options_Video);\n\n// Implementation of interceptor\nint Apply_Options_Video() {\n    Message::Info(\"Before original Apply_Options_Video()\");\n\n    // Original function can be called using CInvoke pointer.\n    int result = Ivk_Apply_Options_Video();\n\n    Message::Info(\"After original Apply_Options_Video()\");\n\n    return result;\n}\n
"},{"location":"zengin/union/sdk/hooks/#member-function","title":"Member function","text":"

Member functions are the functions declared as non-static class members and they take a class instance pointer as an implicit first argument (__thiscall calling convention). We can hook them in two ways using either a regular function or declaring a new method in User API.

"},{"location":"zengin/union/sdk/hooks/#option-1---regular-function","title":"Option #1 - Regular function","text":"
// 0x006015D0 public: virtual int __fastcall zCVob::Render(struct zTRenderContext &)\n\n// Forward declaration\nint __fastcall zCVob_Render(zCVob* _this, zTRenderContext& context);\n\n// Hook declaration\nCInvoke<int(__fastcall *)(zCVob* _this, zTRenderContext& context)> Ivk_zCVob_Render(0x006015D0, &zCVob_Render);\n// Equivalent:\n// HOOK Ivk_zCVob_Render AS(0x006015D0, &zCVob_Render);\n\n// Implementation of interceptor as regular function\n// Notice the first argument that's a pointer to class instance (this)\nint __fastcall zCVob_Render(zCVob* _this, zTRenderContext& context) {\n    if(_this == player) {\n        screen->PrintCX(1000, \"Rendering a player zCVob\");\n    }\n\n    // Call original method\n    return Ivk_zCVob_Render(_this, context);\n}\n
"},{"location":"zengin/union/sdk/hooks/#option-2---user-api","title":"Option #2 - User API","text":"

In Engine SDK/User API we can find a .inc file for the class we are hooking and define a new member method there. In this case, we are looking for zCVob.inc:

// Supported with union (c) 2020 Union team\n\n// User API for zCVob\n// Add your methods here\n\nint RenderUnion(zTRenderContext& context);\n

Then we can declare the hook pointing to our member method:

// 0x006015D0 public: virtual int __fastcall zCVob::Render(struct zTRenderContext &)\n\n// Hook declaration\nCInvoke<int(__fastcall zCVob::*)(zTRenderContext& context)> Ivk_zCVob_Render(0x006015D0, &zCVob::RenderUnion);\n// Equivalent:\n// HOOK Ivk_zCVob_Render AS(0x006015D0, &zCVob::RenderUnion);\n\n// Implementation of interceptor  method\nint zCVob::RenderUnion(zTRenderContext& context) {\n    if(this == player) {\n        screen->PrintCX(1000, \"Rendering a player zCVob\");\n    }\n\n    // Call original method\n    return Ivk_zCVob_Render(this, context);\n}\n
"},{"location":"zengin/union/sdk/hooks/#hook-flags","title":"Hook flags","text":"

In the third argument of CInvoke we can provide hook flags. The default value is IVK_AUTO.

enum EInterMode\n{\n    // Hook will not intercept the function.\n    IVK_DISABLED  = 1 << 1,\n\n    // Normal hook. If other hook is already defined for the same address, an error pops up.\n    IVK_NORMAL    = 1 << 2,\n\n    // Hook will automatically create an interception tree to allow multiple hooks for the same address.\n    IVK_AUTO      = 1 << 3,\n\n    // Overrides any hook defined for the same address before.\n    IVK_REDEFINE  = 1 << 4,\n\n    // Makes it impossible to override or disable the hook.\n    // It should be used only in very specific cases.\n    IVK_PROTECTED = 1 << 5,\n\n    // Same as IVK_DISABLED\n    IVK_READONLY  = IVK_DISABLED\n};\n
"},{"location":"zengin/union/sdk/hooks/#credits","title":"Credits","text":"

Examples are taken from the Union lessons in Russian created by Gratt on worldofplayers.ru/threads/41490/

"},{"location":"zengin/worlds/","title":"Worlds","text":""},{"location":"zengin/worlds/#worlds","title":"Worlds","text":"

Acknowledgment

This article is heavily inspired by various tutorials from the polish TheModders forums.

Worlds, saved as .ZEN files in ZenGin, are archives that contain the world mesh (model), BSP tree and the information of all objects in the world. These objects are called VOBs (\"virtual objects\"). ZEN files can be saved in two ways; compiled and uncompiled. The compiled version is a full-fledged level with a terrain model. Uncompiled ZENs only save the VOB tree and are meant for specific use-cases.

Spacer is used to create these .ZEN files. There are also other world editors. The way of doing things can vary between these editors, so the specifics will be discussed in separate articles for those tools; at the same time, a lot of knowledge carries over between them. Also have in mind that Spacer is the least comfortable of the editors.

"},{"location":"zengin/worlds/#world-contents","title":"World contents","text":"

The content of worlds in Gothic can be roughly separated in the following way:

  • Base level mesh: terrain and buildings, sometimes also trees
  • VOBs: all interactive objects, items, foliage, small rocks, huts, furniture, ramps etc.

Asides from those elements, there are also many invisible VOBs, such as:

  • Waypoints - used for NPC navigation
  • Freepoints (zCVobSpot) - used mainly for NPC routines and roaming behavior for monsters
  • Startpoints - used only to spawn the player when starting a new game. Teleporting between levels is handled with scripts and uses freepoints to determine where the player will appear.
  • Sound emitters
  • Music zones
  • oCZoneMusic - music which plays inside the bounding box of this zone
  • oCZoneMusicDefault - default music which plays whenever the player is not inside some oCZoneMusic
  • Fog zones (zCZoneZFog) - areas which add fog, e.g. like in swamp areas where the sky is not visible. The setting to fade out the sky is optional though.
  • PFX - particle effects (fire, smoke, fireflies, falling leaves etc.)

Note

This list isn't exhaustive.

"},{"location":"zengin/worlds/#creating-a-zen-file","title":"Creating a ZEN file","text":"

Before VOBs can be added to a world model, the world needs to be compiled. After importing a 3ds model, the world can be compiled as an outdoor or indoor world and saved as a ZEN.

The submeshes used in ZEN files have triangle count limits (it is also advisable to keep triangle count for each submesh under 50k for performance reasons). To get around this limitation and to parallelize work on various areas, it is possible to join multiple ZEN files together, which is done with special macros.

If you take a look at the original maps for Gothic 2, you can notice that they are in folders, where there's e.g. a file called NEWWORLD.ZEN and multiple .ZEN files with \"part\" in their name. The latter are the sub-zens used to create the full level.

However, a possibly more comfortable workflow is to have a single world mesh which is internally separated into multiple submeshes. This way triangle count limits won't be exceeded and the world won't need compiling from parts. As a trade-off, it is likely that it won't be possible for multiple people to work on the ZEN world at the same time.

"},{"location":"zengin/worlds/#lighting","title":"Lighting","text":"

There are two light types in the game:

  • Static lights, which are baked onto the level. They can cast shadows (these only take static VOBs into consideration) and don't leak through walls. These have to be recompiled after making changes, but this process should only take moments. Static lights have the downside of only working in indoor worlds and in rooms which are closed with portals.
  • Dynamic lights are calculated during runtime, which allows them to move and change properties (their color, for example), but has a performance cost. Additionally, they don't look the best and will often leak through walls.

It is generally advised to use static lights whenever possible.

"},{"location":"zengin/worlds/#portals","title":"Portals","text":"

Portals are special parts of outdoor world meshes which separate interiors from exteriors. This allows the level to have dark areas: otherwise interiors are lit the same way as any outside area. Additionally, portals help with performance (interiors aren't rendered unless the player is nearby). Creation of portals has many caveats and will be discussed in a separate article. Portals are also related to NPC behavior (e.g. setting ownership of a room).

"},{"location":"zengin/worlds/#optimisation","title":"Optimisation","text":"

The game uses occlusion culling, which means that if an object is covered by another object, it is not rendered and saves performance. This means that the performance in a level can be boosted by a lot by creating city walls and mountains and valleys which separate areas.

Occlusion culling isn't a perfect process, so there's also the option of adding GHOSTOCCLUDERs, which are invisible walls which stop areas behind them from rendering. They are a part of the world mesh and are created by assigning a material called GHOSTOCCLUDER to chosen faces. The color of the material is traditionally purplish-blue or pink, but the material itself is not rendered in-game, so this is only to make them stand apart from the rest of the level during modelling. To get more technical, these occluder walls are used to help the BSP algorithm which runs during world compilation.

As mentioned before, another ways of optimisation are portals and limiting the number of dynamic lights. It is also not advisable to make many VOBs be affected by wind.

"},{"location":"zengin/worlds/spacer/","title":"Spacer","text":""},{"location":"zengin/worlds/spacer/#spacer","title":"Spacer","text":"

Spacer is the original world editor used to create maps in Gothic and it's installed by the MDK installer.

A good .ZEN file to start experimenting with Spacer is Toten Insel. It's a simple level which should load without issues for everyone. The map contains a custom texture, but it can be safely ignored.

"},{"location":"zengin/worlds/spacer/#introduction","title":"Introduction","text":"

Upon launching Spacer, multiple windows will appear. They are:

  • The main viewport (black with text on launch)
  • The vobtree - allows to browse and select the objects already placed in a level
  • The object window - it has 3 tabs: Create, Modify and \"...\".
  • Toolbars - there's two of them and each button has a hover hint.
  • The help window - sometimes when clicking on something, this window will show a description. It's usually empty though.
  • The objectpages window - allows access to specific VOB settings. The contents of this window be changed with buttons on the horizontal toolbar.

Other windows dedicated to specific functionalities can also be opened or toggled (Window tab in the viewport or the horizontal toolbar).

When importing a mesh instead of a .ZEN file, some things will change. In this mode, objectpages has material data, one of the toolbars changes completely and the vobtree window changes into a texture browser.

"},{"location":"zengin/worlds/spacer/#configuration","title":"Configuration","text":"

Before doing anything else, you will probably want to change a few settings first. Select Settings: View in the Settings tab in the main viewport to increase the viewport resolution. After doing that, press Align Toolwindows at Screen or Align Toolwindows at Spacer in the Window tab to clean up the window placement. You might still need to move some of the tool windows around after this, as they can overlap.

The most comfortable option we found was to set the resolution to something slightly smaller than the screen resolution (e.g. 1600:900 on a 1920:1080 screen) and then aligning the tool windows to screen.

To help with the control sensitivity issues, change the camera movement speed in the Settings: General.

"},{"location":"zengin/worlds/spacer/#viewport-controls","title":"Viewport controls","text":"

The camera has multiple modes of operation. Some of the controls may sound confusing, but will make sense once you try them.

Default selection mode

Arrows move the camera back and forward and rotate it sideways. A moves the camera up and Y lowers it.

PageUp and PageDown rotate the camera up and down. End resets this rotation.

Selecting VOBs is done by simply pointing at them with the mouse and clicking.

First-person selection mode

Toggled by the F3 button.

In this mode, you can point the camera with your mouse, and selection is done by pointing the green reticle at a VOB and clicking LMB. Arrows now move the camera parallel to itself (including sideways).

PageUp and PageDown still rotate the camera up and down, but it's better not to use them because it affects how the arrow movement behaves. End resets this rotation.

Default VOB movement mode

When a VOB is selected, press M to enter and exit this mode.

The arrows now move the VOB horizontally. Moving it up and down is done with A and Y.

The keys above the arrows now rotate the VOB:

  • Axis 1: Delete and PageDown
  • Axis 2: Insert and PageUp
  • Axis 3: Home and End

First-person VOB movement mode

When a VOB is selected, press T to enter and exit this mode.

The controls are the same as the default selection mode, but the camera is now placed at the selected VOB and it moves with the camera.

One caveat is that the controls are in the local space of the object. What this basically means is that if you rotated the object in any other way than horizontally, the movement and rotation will now be skewed.

Mixed VOB movement mode

When a VOB is selected, press C to enter and exit this mode. The VOB is now controlled like in the first-person movement mode, but the camera is not placed at the VOB: in other words, the camera remains in the same place.

General

Holding down Shift speeds up the camera in all of the modes. The numpad can be used for rotating instead of the buttons above the arrows. Both movement modes can be used from either of the selection modes. Movement modes can be selected from the vertical toolbar. This toolbar also has a \"toggle camera position\" button; this switches between two camera placements, which can be controlled independently.

The objects location can also be entered manually through the object window: open the Internals folder and select trafoOSToWSPos to input them at the bottom of the window. Don't forget to press \"Apply\". Unfortunately the rotation setting uses an odd format and can't be set manually.

"},{"location":"zengin/worlds/spacer/#basic-usage","title":"Basic usage","text":"

This section covers some of the basic things done in the editor.

"},{"location":"zengin/worlds/spacer/#inserting-a-vob","title":"Inserting a VOB","text":"
  • In the Create tab in the Objects window, select the VOB type. Choose zcVob to add a simple decorative model.
  • Right click anywhere on the viewport
  • Select the insert option (Insert [zcVob] in this case)
  • A VOB without a mesh will be created in the middle of the screen. Try to not deselect it, but if you do, it can be found in the vobtree under the appropriate folder (zcVob in this case); it can be identified by a green dot.
  • In the Modify tab in the Object window, select \"visual\". Insert the model name in the text form at the bottom of the window. You can use pc_lob_sleeper3.3ds for now; this mesh should be present in both Gothic 1 and 2.
  • If you unpacked the meshes while installing the MDK or with GothicVDFS, you can also browse to the file using the file button next to the text form.
  • Make sure to click the Apply button. Do this after making any changes in the Object window or they will be lost.

Tip

You can use the VOB Bilder tool to comfortably browse model images and names. An online version is currently available here. The UI on the website is in Polish but it's simple enough to not matter.

  • To make the VOB have collision in-game, double click on cdDyn (\"collision detection dynamic\") to set it to true. Sometimes this is unadvised, e.g. with bushes or grass.

Tip

When placing pickable items, you can press the \"apply physics on selected VOB\" button in the vertical toolbar to make the item drop on the ground. It can save you a lot of work with placing those items. This won't work with a plain cVob though.

"},{"location":"zengin/worlds/spacer/#common-vob-settings","title":"Common VOB settings","text":"

VOB settings vary depending on what the VOB type is. They all have common parameters of the base VOB class though. The full description of a zCVob class can be found here.

"},{"location":"zengin/worlds/spacer/#issues","title":"Issues","text":"

Spacer 2 received the last update in 2003 and is a very buggy tool. Here are some known issues.

Framerate dependence

The speed of camera in Spacer depends on the framerate. Depending on the angle of the camera and the level, Spacer can have huge framerate, which will make the camera move too quick.

You can try to limit the framerate of Spacer with external tools, but your mileage may vary. Such tools often only limit rendering using fake Vsync, but the underlying logic of the program can still run too fast.

Using the grid snap function can help when the framerate is high, but again: your mileage may vary.

Random freezes and crashes

Spacer will freeze or crash quite often at seemingly random moments. It is extremely important to save often and back up your work.

One of the common ways the editor can freeze is when rotating the camera vertically when the framerate is very high. In that case, changing the camera mode to F3 and back can sometimes help.

Copying VOBs

When copy-pasting a VOB in Spacer (right click menu), the new VOB might be created as a child of the original one and moving one of them will move both. This doesn't seem to be consistent, but it's worth checking before you accidentally ruin the careful placement of the original VOB.

"},{"location":"zengin/worlds/spacer/#troubleshooting","title":"Troubleshooting","text":"

You can have issues with loading a ZEN or a world model for a multitude of reasons. Here is some of the known ones.

  • Some terrain models aren't set up or exported properly.
  • Maps which use custom assets will cause issues or won't even load unless these assets are included in appropriate directories. The severity of this is different depending on the asset type. For example, textures will be replaced with a placeholder, but animations will cause crashes.

Note

This section is not exhaustive.

"},{"location":"zengin/worlds/spacer/#creating-zens","title":"Creating ZENs","text":"

Presented here are the ways of working with new terrain models.

"},{"location":"zengin/worlds/spacer/#compiling-a-world-mesh","title":"Compiling a world mesh","text":"

To create a completely new ZEN, you will first need a level mesh. These can be made from scratch or downloaded, but be aware that meshes, which aren't properly prepared won't compile correctly (you won't be able to move in the viewport). As with any other mesh in Gothic, it has to be in the 3ds format. It is recommended to place the mesh file somewhere in the _work/Data/Meshes (can be your own subfolder).

You can find free terrain models here if you want to practice this. Note that not all of them might compile properly; this one should be fine though.

First, load the mesh from the File tab of the viewport. To compile the mesh, press Compile World in the World tab. From here, multiple options are available:

  • Indoor/Outdoor: determines if the world will have a sky and the way that lighting behaves.
  • Detect leaks: might be related to checking if indoor (\"underground\") worlds have holes in them. In some games such holes can cause performance issues, perhaps it's the same here. Doesn't hurt to enable it.
  • Quick compile: self-explanatory, but the exact effects of this are unknown.
  • Polycheck: presumably checks if the model doesn't exceed triangle limits.
  • Editormode:

    • On: Spacer will load the mesh in editor mode, which allows you to change materials assigned to triangles and other mesh operations. It is more comfortable to do these things in an external 3D editor, but sometimes using this is recommended, e.g. for setting up portals. You can save the model as a .3ds in this mode.

    • Off: Spacer will create a ZEN where you can normally place VOBs. You can now save the world as a compiled ZEN and add VOBs to it.

"},{"location":"zengin/worlds/spacer/#compiling-a-world-from-multiple-meshes","title":"Compiling a world from multiple meshes","text":"

First and foremost, the models used for this must be properly positioned and separated in your 3D editor of choice. Then each section must be exported as separate .3ds files. After that, compile each model and save it as a compiled ZEN. Place them in their own folder. You can place VOBs in those ZEN files, the VOB trees will be merged too.

Now, to join these zens together, you will need to define a macro in Tools>Macros. These are pretty much identical except for the ZEN list; for example, the Mining Colony ZEN in Gothic 2 (OLDWORLD.ZEN) is comprised of two models, and the macro looks like this:

reset\nset error 3\nLoad world oldworld\\SURFACE.ZEN\nLoad world oldworld\\OLDCAMP.ZEN\ncompile world outdoor\ncompile light high\n

Then you double-click the macro name to run it and wait. The macro contains the reset directive, but it's worth doing it on a freshly opened Spacer instance just to be safe.

Keep in mind that compiling a world from multiple ZENs is meant as a final step in level production. This is because doing it will cause issues with culling and stop interiors from rendering (and thus stop you from editing it). Instead, the part ZENs are filled with VOBs separately and the world is compiled as a final step before testing the map.

"},{"location":"zengin/worlds/spacer/#updating-world-meshes-in-a-compiled-zen","title":"Updating world meshes in a compiled ZEN","text":"

Ideally, updating the world mesh would be avoided, but it's an inevitable need when iterating a map design. Doing this in the original Spacer might not be impossible, but it is generally avoided and Spacer.NET or other editors are used for this instead.

"},{"location":"zengin/worlds/Classes/zCVob/","title":"zCVob","text":""},{"location":"zengin/worlds/Classes/zCVob/#zcvob","title":"zCVob","text":"

zCVob is a base class for all objects placed in a world.

Acknowledgment

Heavily inspired by the amazing documentation site Gothic library

"},{"location":"zengin/worlds/Classes/zCVob/#class-members","title":"Class members","text":"G1G2A

Properties of a zCVob class are split into two parts. The Internals are hardly ever needed to be edited manually, they are changeed by e.g. moving an object in Spacer. On the other hand the Vob properties can only be changed by the Objects context menu in Spacer.

Internals

  • pack
  • presetName
  • bbox3DWS
  • trafoOSToWSRot
  • trafoOSToWSPos

Vob

  • vobName
  • visual
  • showVisual
  • visualCamAlign
  • CdStatic
  • CdDyn
  • staticVob
  • dynShadow

Properties of a zCVob class are split into two parts. The Internals are hardly ever needed to be edited manually, they are changeed by e.g. moving an object in Spacer. On the other hand the Vob properties can only be changed by the Objects context menu in Spacer.

Internals

  • pack
  • presetName
  • bbox3DWS
  • trafoOSToWSRot
  • trafoOSToWSPos

Vob

  • vobName
  • visual
  • showVisual
  • visualCamAlign
  • visualAniMode
  • visualAniModeStrength
  • vobFarClipZScale
  • CdStatic
  • CdDyn
  • staticVob
  • dynShadow
  • zbias
  • isAmbient
"},{"location":"zengin/worlds/Classes/zCVob/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCVob/#pack","title":"pack","text":"

No Information provided.

"},{"location":"zengin/worlds/Classes/zCVob/#presetname","title":"presetName","text":"

The name of the template that was used to create the item.

"},{"location":"zengin/worlds/Classes/zCVob/#bbox3dws","title":"bbox3DWS","text":"

Volume of virtual object. Defined by two opposite diagonal points of the BoundingBox (1x, 1y, 1z, 2x, 2y, 2z). The volume is needed to calculate collisions and interactions with other game objects. For example, with dynamic objects, which include characters (class C_NPC), items (class C_ITEM ), etc.

Interaction processing begins when object volumes intersect. For example, when the player enters the world change trigger area, the engine loads another game level based on the parameters this trigger. All this happens when the main character's BoundingBox intersects with the trigger's BoundingBox.

The BoundingBox can only be changed using the Edit the Bbox button in Spcaer.

"},{"location":"zengin/worlds/Classes/zCVob/#trafoostowsrot","title":"trafoOSToWSRot","text":"

Orientation relative to the coordinate center.

Note

This refers to the center of coordinates of the .3DS file of the game world on which the ZEN file is built.

"},{"location":"zengin/worlds/Classes/zCVob/#trafoostowspos","title":"trafoOSToWSPos","text":"

Coordinates of the position in space relative to the center of coordinates.

The coordinates are set automatically the first time an instance of the class is inserted into the game world. You can change them either directly by entering numerical values \u200b\u200bin the corresponding fields of the parameter, by moving the vob in spacer.

"},{"location":"zengin/worlds/Classes/zCVob/#vobname","title":"vobName","text":"

An identifier of a zCVob shown in the editor and sometimes used in scripts. The name can be left blank.

For some object classes, entering a name is required: zCVobSpot , zCVobWaypoint , zCTrigger , etc.

Danger

Setting a name for every static and insignificant object can lead to an error when parsing the game world.

"},{"location":"zengin/worlds/Classes/zCVob/#visual","title":"visual","text":"

The name of the file that will be responsible for the visual display of the object.

Different file formats are used for different object classes:

  • *.3DS - Static objects
  • *.PFX - Particle effects
  • *.TGA - Textures
  • *.MDS, *.ASC - Interactive objects
  • *.MMS - Animated objects
"},{"location":"zengin/worlds/Classes/zCVob/#showvisual","title":"showVisual","text":"

This option is responsible for displaying the object.

Accepted values:

  • TRUE - Display.
  • FALSE - Do not display.
"},{"location":"zengin/worlds/Classes/zCVob/#visualcamalign","title":"visualCamAlign","text":"

Option to align objects relative to the camera.

Accepted values:

  • NONE - Not used.
  • YAW - The object always faces the player.
  • FULL - The object is aligned relative to the world axes.

Note

For example, in order for the grass model to always face the character, you need to set this parameter to YAW.

"},{"location":"zengin/worlds/Classes/zCVob/#visualanimode","title":"visualAniMode","text":"

Wind simulation option. Used in conjunction with the visualAniModeStrength parameter.

Accepted values:

  • NONE - Not used.
  • WIND - Strong wind effect. Acceptable for herbs.
  • WIND2 - Light wind effect. Acceptable for trees.

Warning

This option is only available in Gothic 2 (Spacer2).

"},{"location":"zengin/worlds/Classes/zCVob/#visualanimodestrength","title":"visualAniModeStrength","text":"

Wind power animation multiplier. Small values such as 0.001 are typically used. Used in conjunction with the visualAniMode parameter.

Warning

This option is only available in Gothic 2 (Spacer2).

"},{"location":"zengin/worlds/Classes/zCVob/#vobfarclipzscale","title":"vobFarClipZScale","text":"

Sets the loading range of the VOB object. Depends on the VOB drawing distance specified using the zCZoneVobFarPlane object.

The range of values is from 0.0 to 2.0.

With a value of 0.0, the object is not visible, but collisions are calculated. With a value of 2.0, the VOB drawing range is identical to the VOB drawing range of objects specified by the zCZoneVobFarPlane object.

Warning

This option is only available in Gothic 2 (Spacer2).

"},{"location":"zengin/worlds/Classes/zCVob/#cdstatic","title":"CdStatic","text":"

Determines if the VOB will collide with the static objects (world mesh and other VOBs with cdStatic on).

Accepted values:

  • TRUE - Collision handling for static objects is enabled.
  • FALSE - Collision handling for static objects is disabled.

Tip

A situation often arises when objects \u201crefuse\u201d to move beyond a certain point on the surface. This happens when cdStatic is set to TRUE, i.e. the object cannot cross the surface another static object. In this case, it is enough to disable the cdStatic parameter for the duration of the move, and turn it on again after the move.

"},{"location":"zengin/worlds/Classes/zCVob/#cddyn","title":"CdDyn","text":"

Determines if the VOB will collide with dynamic objects (NPCs, items, etc.). This basically determines if the object has collision during gameplay.

Accepted values:

  • TRUE - Collision handling for dynamic objects is enabled.
  • FALSE - Collision handling for dynamic objects is disabled.
"},{"location":"zengin/worlds/Classes/zCVob/#staticvob","title":"staticVob","text":"

Determines if the VOB is taken into consideration in static lighting calculations in Indoor spaces. Usually enabled in decorative Vobs, but some of the interactive ones have it disabled.

Accepted values:

  • TRUE - Calculate the shadow of the object.
  • FALSE - Do not calculate the shadow of the object.

Note

The shadow is calculated when compiling light in Low, Middle or High mode.

"},{"location":"zengin/worlds/Classes/zCVob/#dynshadow","title":"dynShadow","text":"

Determine if the object will cast a shadow when affected by dynamic light (e.g. torches).

Accepted values:

  • DS_NONE - No shadow.
  • DS_BLOB - Casts a circular shadow.
"},{"location":"zengin/worlds/Classes/zCVob/#zbias","title":"zbias","text":"

Option to remove texture flickering if a .TGA file is used as rendering.

Warning

This option is only available in Gothic 2 (Spacer2).

"},{"location":"zengin/worlds/Classes/zCVob/#isambient","title":"isAmbient","text":"

Sets the calculation of refracted lighting of objects.

Accepted values:

  • TRUE - Calculate the refraction of light.
  • FALSE - Do not calculate light refraction.

Warning

This option is only available in Gothic 2 (Spacer2).

"},{"location":"pl/","title":"Witamy na stronie Gothic Modding Community","text":""},{"location":"pl/#witamy-na-stronie-gothic-modding-community","title":"Witamy na stronie Gothic Modding Community","text":"

Ta strona GitHub jest zaprojektowana w celu zawarcia zbioru artyku\u0142\u00f3w, poradnik\u00f3w oraz innej dokumentacji o Gothicu utrzymywanych przez spo\u0142eczno\u015b\u0107.

Dwie pierwsze cz\u0119\u015bci gier Gothic korzystaj\u0105 z silnika o nazwie ZenGin, stworzonego przez Piranha Bytes oraz grup\u0119 programist\u00f3w o nazwie Mad Scientists. Je\u017celi chcesz wiedzie\u0107 wi\u0119cej o historii tworzenia, to jest masa informacji na Gothic Archive.

Zawarto\u015b\u0107 strony nie jest przeznaczona, aby by\u0107 uznan\u0105 za \u015bwi\u0119te s\u0142owa moddingu. Jeste\u015bmy tylko modderami dziel\u0105cymi si\u0119 do\u015bwiadczeniami, wiedz\u0105 oraz naszym ulubionym tokiem pracy.

Nie kr\u0119puj si\u0119, aby otworzy\u0107 pro\u015bb\u0119 o po\u0142\u0105czenie (ang. pull request) z twoim artyku\u0142em, lub z propozycj\u0105 zmian. Po wi\u0119cej informacji jak to zrobi\u0107 zobacz, Jak Si\u0119 Udzieli\u0107.

Mo\u017cesz otworzy\u0107 pro\u015bb\u0119 o po\u0142\u0105czenie wzgl\u0119dem tego repozytorium.

"},{"location":"pl/preferences/","title":"Preferencje","text":""},{"location":"pl/preferences/#preferencje","title":"Preferencje","text":"

Ta strona pozwala ustawi\u0107 r\u00f3\u017cne preferencje do czytania dokumentacji:

"},{"location":"pl/preferences/#kolor","title":"Kolor","text":"

Mo\u017cesz zmieni\u0107 nastr\u00f3j strony poprzez zmian\u0119 koloru.

Wybierz kolor akcentuj\u0105cy:

Wybierz kolor odcienia:

Zresetuj kolory

"},{"location":"pl/preferences/#czcionka","title":"Czcionka","text":"

Mo\u017cesz zmieni\u0107 czcionk\u0119 na predefiniowany.

Wybierz czcionk\u0119: Domy\u015blna OpenDyslexic

"},{"location":"pl/preferences/#w\u0142asny-css","title":"W\u0142asny CSS","text":"

Mo\u017cesz doda\u0107 niestandardowe arkusze styl\u00f3w. Wprowad\u017a CSS:

"},{"location":"pl/contribute/","title":"Jak si\u0119 udzieli\u0107","text":""},{"location":"pl/contribute/#jak-si\u0119-udzieli\u0107","title":"Jak si\u0119 udzieli\u0107","text":"

Gothic Modding Community jest projektem nap\u0119dzanym przed spo\u0142eczno\u015b\u0107. Zach\u0119camy osoby do wnoszenia swojego wk\u0142adu.

Ta strona jest budowana przy pomocy statycznego generatora stron MkDocs oraz sk\u00f3rki Material for MkDocs, wraz z wieloma innymi wtyczkami do MkDocs.

Zale\u017cnie od skali i typu kontrybucji, trzeba spe\u0142ni\u0107 inne wymagania wst\u0119pne.

"},{"location":"pl/contribute/#zg\u0142oszenia","title":"Zg\u0142oszenia","text":"

Po angielsku mo\u017cna zg\u0142osi\u0107 problem lub inny komentarz o funkcjonowaniu strony poprzez otworzenie problemu (ang. issue) na serwisie GitHub albo do\u0142\u0105cz do nas na platformie Discord.

"},{"location":"pl/contribute/#wk\u0142ad-bezpo\u015bredni","title":"Wk\u0142ad bezpo\u015bredni","text":"

Wk\u0142ad bezpo\u015bredni wykonuje si\u0119 poprzez stworzenie kopii tego repozytorium (ang. fork) oraz stworzenie pro\u015bby o po\u0142\u0105czenie (ang. pull request PR) na serwisie GitHub wraz ze zmianami do zatwierdzenia.

Nie zmarnuj czasu

Prosz\u0119 si\u0119 upewni\u0107, \u017ce tre\u015b\u0107, jaka zostanie dodana, nie wyst\u0119puje ju\u017c na wersji dev strony. Mo\u017cna skorzysta\u0107 z funkcjonalno\u015bci wyszukiwania, \u017ceby przefiltrowa\u0107 GMC r\u00f3\u017cnymi s\u0142owami kluczowymi i tre\u015bciami.

Jak edytowa\u0107 pliki \u017ar\u00f3d\u0142owe?

Pliki \u017ar\u00f3d\u0142owe artyku\u0142\u00f3w s\u0105 pisane wykorzystuj\u0105c format plik\u00f3w Markdown .md (Markdown cheatsheet). Poza tym ta strona wykorzystuje wtyczk\u0119 Python Markdown Extensions, kt\u00f3ra rozszerza sk\u0142adni\u0119 o dodatkowe zasady pozwalaj\u0105ce na wstawienie wzmianek jak ta, kt\u00f3r\u0105 w\u0142a\u015bnie czytasz.

"},{"location":"pl/contribute/#mniejsze-zmiany","title":"Mniejsze zmiany","text":"

Mniejsze zmiany, jak poprawianie b\u0142\u0119d\u00f3w ortograficzny, gramatycznych, czy usuwanie/dodawanie s\u0142\u00f3w do akapit\u00f3w w jednym pliku, mog\u0105 by\u0107 zrobione szybko poprzez klikni\u0119cie przycisku w prawym g\u00f3rnym rogu artyku\u0142u. Otworzy to interfejs edytowania pliku w serwisie GitHub, kt\u00f3re po zapisaniu zmian, automatycznie utworzy kopi\u0119 (ang. fork) oraz ga\u0142\u0105\u017a (ang. brach) z \u0142atk\u0105, a nast\u0119pnie otworzy pro\u015bb\u0119 o po\u0142\u0105czenie (ang. pull request) wzgl\u0119dem ga\u0142\u0119zi dev.

Poprawna ga\u0142\u0105\u017a dla pro\u015bby o po\u0142\u0105czenie

Upewnij si\u0119, \u017ce pro\u015bba o po\u0142\u0105czenie (ang. pull request) jest skierowana do ga\u0142\u0119zi dev albo specjalnej ga\u0142\u0119zi pre-merge, a nie do ga\u0142\u0119zi main.

"},{"location":"pl/contribute/#wi\u0119ksze-zmiany","title":"Wi\u0119ksze zmiany","text":"

Bardziej z\u0142o\u017cone zmiany takie jak, edycja wielu plik\u00f3w naraz, dodawanie nowych artyku\u0142\u00f3w, obrazk\u00f3w, czy innych plik\u00f3w, albo zmiana konfiguracji strony jest \u0142atwiej zrobi\u0107 poprzez u\u017cycie zewn\u0119trznych narz\u0119dzi na lokalnym PC. Wi\u0119kszo\u015b\u0107 z tych operacji mo\u017cna zrobi\u0107 poprzez interfejs serwisu GitHub, ale jest to raczej uci\u0105\u017cliwe oraz trudniej zauwa\u017cy\u0107 problemy wynikaj\u0105ce z procesu zmian, poniewa\u017c nie s\u0105 one widoczne w przegl\u0105darce w ich ostatecznej formie.

Troch\u0119 przygotowa\u0144 jest potrzebnych przed rozpocz\u0119ciem prac nad plikami, poniewa\u017c do dzia\u0142ania MkDocs wymaga zainstalowanego w systemie Pythona. GitHub dzia\u0142a nad systemem kontroli wersji git, wi\u0119c jego instalacja jest te\u017c wymagana. Podstawowa znajomo\u015b\u0107 obs\u0142ugi Terminala/Konsoli polece\u0144/Powershell jest pomocna.

"},{"location":"pl/contribute/#przygotowanie-systemu-wideo","title":"Przygotowanie Systemu (wideo)","text":"

Po pierwsze, trzeba zainstalowa\u0107 Python. Mo\u017cna pod\u0105\u017ca\u0107 wed\u0142ug tego poradnika krok po kroku dla Windowsa albo macOS jak zainstalowa\u0107 Python.

Wideo jest z 2017?!

Proces instalacji Pythona nie zmieni\u0142 si\u0119 od tamtego czasu. Jednak\u017ce prosz\u0119 instalowa\u0107 najnowsz\u0105 wersj\u0119 Python 3.

Aby m\u00f3c pracowa\u0107 zdalnie z GitHub, mo\u017cna zainstalowa\u0107 najnowsz\u0105 wersj\u0119 git, pod\u0105\u017caj\u0105c wed\u0142ug tego poradnika.

Je\u017celi planujesz tylko edytowa\u0107 zawarto\u015b\u0107 artyku\u0142\u00f3w Markdown, mo\u017cesz po prostu zainstalowa\u0107 najnowsz\u0105 wersj\u0119 Visual Studio Code, \u017ceby mie\u0107 interfejs graficzny do zarz\u0105dzania git oraz podgl\u0105d Markdown, albo pracuj z dowolnym znanym edytorem tekstu i omi\u0144 konfiguracj\u0119 \u015brodowiska.

Je\u017celi planujesz bardziej z\u0142o\u017cone programowanie w Python, mo\u017cesz pod\u0105\u017cy\u0107 wed\u0142ug tego poradnika krok po kroku dla Windowsa lub macOS jak skonfigurowa\u0107 \u015brodowisko developerskie z Visual Studio Code (VS Code).

"},{"location":"pl/contribute/#przygotowanie-systemu-tekst","title":"Przygotowanie Systemu (tekst)","text":"

\u017beby przygotowa\u0107 system do uruchomienia projektu lokalnie, pod\u0105\u017caj wed\u0142ug tych instrukcji.

  1. Zainstaluj najnowsz\u0105 wersj\u0119 Pythona. Upewnij si\u0119, \u017ceby zaznaczy\u0107 opcj\u0119 \"Add Python to PATH\" podczas instalacji.

  2. Otw\u00f3rz okno Terminala/Konsoli polece\u0144/PowerShell.

  3. Sprawd\u017a, \u017ce instalacja Pythona by\u0142a pomy\u015blna, korzystaj\u0105c z tego polecenia (mo\u017cliwa jest potrzeba restartu okna konsoli):

    python --version\n
  4. Zainstaluj najnowsz\u0105 wersj\u0119 git, pod\u0105\u017caj\u0105c wed\u0142ug tego poradnika.

  5. Sprawd\u017a, \u017ce instalacja git by\u0142a pomy\u015blna, korzystaj\u0105c z tego polecenia (mo\u017cliwa jest potrzeba restartu okna konsoli):

    git --version\n
  6. (opcjonalne) Zainstaluj najnowsz\u0105 wersj\u0119 Visual Studio Code dla interfejsu graficznego do zarz\u0105dzania git i podgl\u0105dem Markdown.

"},{"location":"pl/contribute/#praca-lokalna","title":"Praca lokalna","text":"

Aby m\u00f3c pracowa\u0107 lokalnie:

  1. Stw\u00f3rz kopi\u0119 (ang. fork) na serwisie GitHub.
  2. Na lokalnym PC nawiguj do folderu, w kt\u00f3rym chcesz sklonowa\u0107 kopi\u0119 repozytorium, oraz otw\u00f3rz okno konsoli wewn\u0105trz niego.
  3. Sklonuj kopi\u0119 repozytorium, korzystaj\u0105c z tego polecenia:

    git clone https://github.com/user-name/forked-repository-name.git <DIR-PATH>\n

    Zamiast https://github.com/user-name/forked-repository-name.git skorzystaj z w\u0142asnego linku, kt\u00f3ry jest widoczny po klikni\u0119ciu zielonego przycisku <> Code i wybraniu zak\u0142adki HTTPS.

    Zamie\u0144 <DIR-PATH> ze \u015bcie\u017ck\u0105 do folderu, do kt\u00f3rego ma by\u0107 sklonowane repozytorium albo . je\u017celi ju\u017c jeste\u015b wewn\u0105trz folderu gdzie pliki projektu maj\u0105 si\u0119 znajdowa\u0107.

    To automatycznie utworzy zdalne repozytorium origin skierowane wzgl\u0119dem twojej kopii.

  4. Dodaj zdalne repozytorium upstream korzystaj\u0105c z tego polecenia:

    git remote add upstream https://github.com/Gothic-Modding-Community/gmc.git\n
  5. (opcjonalne) Stw\u00f3rz wirtualne \u015brodowisko i aktywuj je.

    Je\u017celi pracujesz przy kilku projektach Python, warto stworzy\u0107 wirtualne \u015brodowisko (ang. Virtual Environment) dla ka\u017cdego z tych projekt\u00f3w, \u017ceby ka\u017cdy m\u00f3g\u0142 korzysta\u0107 z w\u0142asnego folderu bibliotek z zainstalowanymi modu\u0142ami/wtyczkami.

    python -m venv venv\n

    To utworzy folder venv wewn\u0105trz obecnie wybranego folderu w oknie konsoli. Prosz\u0119, zostaw t\u0119 nazw\u0119, poniewa\u017c jest dodana do pliku .gitignore projektu.

    Zale\u017cnie od systemu, skorzystaj z jednego z tych polece\u0144 do aktywacji wirtualnego \u015brodowiska.

    Linux / macOS
    source venv/bin/activate\n
    Windows Powershell
    venv\\Scripts\\activate.ps1\n
    Windows Konsola Polece\u0144 (cmd)
    venv\\Scripts\\activate.bat\n

    Po aktywacji indykator (venv) b\u0119dzie wy\u015bwietlany przy nazwie folderu w oknie polece\u0144.

    Nie zamykaj okna polece\u0144

    Wirtualne \u015brodowisko musi by\u0107 ponownie aktywowane, przy ka\u017cdym otwarciu okna polece\u0144.

  6. Zainstaluj MkDocs wraz z wtyczkami korzystaj\u0105c z tego polecenia:

    pip install -r requirements.txt\n

    To zainstaluje wszystkie zale\u017cno\u015bci.

  7. Pobierz (ang. fetch) stan historii git z repozytorium upstream korzystaj\u0105c z tego polecenia:

    git fetch upstream\n
  8. Otw\u00f3rz (ang. checkout) lokaln\u0105 ga\u0142\u0105\u017a opieraj\u0105c\u0105 si\u0119 o ga\u0142\u0105\u017a dev repozytorium upstream korzystaj\u0105c z tego polecenia:

    git checkout -b name-of-branch --track upstream/dev\n

    W miejscu name-of-branch podaj kr\u00f3tk\u0105 nazw\u0119 po angielsku. Odpowiedni\u0105 nazw\u0105 ga\u0142\u0119zi jest albo nazwa funkcjonalno\u015bci, albo kr\u00f3tki opis wprowadzonych zmian np. 3ds-articles, fix-typos-for-contribution. Nie musz\u0105 by\u0107 zbyt skomplikowane, do 4 s\u0142\u00f3w wystarczy.

  9. Uruchom serwer ze zbudowan\u0105 stron\u0105 projektu, korzystaj\u0105c z tego polecenia:

    mkdocs serve\n

    Odwied\u017a lokaln\u0105 stron\u0119 pod tym adresem http://127.0.0.1:8000/gmc/. Po ka\u017cdej zmianie w plikach projektu strona automatycznie si\u0119 przebuduje i po chwili przegl\u0105darka automatycznie si\u0119 od\u015bwie\u017cy.

    Serwer mo\u017ce by\u0107 zamkni\u0119ty poprzez skorzystanie ze skr\u00f3tu klawiszowego Control-C w trakcie gdy okno polece\u0144 jest aktywne.

  10. Je\u017celi uko\u0144czysz fragment swojej pracy, dodaj pliki i wstaw wpis do historii gita (ang. commit) korzystaj\u0105c z tego polecenia:

    git add .\ngit commit -m \"add 3 articles about ZenGin\"\n

    Jak wida\u0107 wiadomo\u015b\u0107 (ang. message) / nazwa do wpisu historii r\u00f3wnie\u017c powinna by\u0107 w j\u0119zyku angielskim. Odpowiedni\u0105 wiadomo\u015bci\u0105 jest zdanie opisuj\u0105ce zmiany.

  11. Po sko\u0144czeniu wszystkich prac wy\u015blij (ang. push) swoj\u0105 ga\u0142\u0105\u017a do zdalnego repozytorium origin, korzystaj\u0105c z tego polecenia:

    git push origin name-of-branch\n
  12. Stw\u00f3rz pro\u015bb\u0119 o po\u0142\u0105czenie (ang. pull request) wzgl\u0119dem odpowiedniej ga\u0142\u0119zi.

    Po wys\u0142aniu lokalnej ga\u0142\u0119zi do zdalnego repozytorium origin w oknie polece\u0144 b\u0119dzie dost\u0119pne \u0142\u0105cze, kt\u00f3re otworzy stron\u0119 tworzenia pro\u015bby o po\u0142\u0105czenie. Upewnij si\u0119, \u017ce jest skierowana wzgl\u0119dem ga\u0142\u0119zi dev oraz, \u017ce posiada wszystkie wprowadzone zmiany.

  13. Kolejna kontrybucja:

    Przed kolejn\u0105 kontrybucj\u0105, zawsze skorzystaj z tego polecenia:

    git fetch upstream \n
    \u017ceby mie\u0107 pewno\u015b\u0107, \u017ce posiadasz najnowsz\u0105 histori\u0119 zmian z repozytorium upstream. Nast\u0119pnie pod\u0105\u017caj ponownie od 8. podpunktu i zawsze tw\u00f3rz now\u0105 ga\u0142\u0105\u017a przed wprowadzeniem zmian.
    git status\n

    Tym poleceniem mo\u017cesz sprawdzi\u0107, czy nie masz \u017cadnych zmian w strukturze projektu wzgl\u0119dem repozytorium upstream.

"},{"location":"pl/contribute/#preferencje-budowy-strony","title":"Preferencje budowy strony","text":"

Podczas pracy z projektem mo\u017cna ustawi\u0107 r\u00f3\u017cne zmienne \u015brodowiskowe, \u017ceby przystosowa\u0107 konfiguracj\u0119 do w\u0142asnych preferencji:

  • GMC_DEV_LOCALE - to dwuznakowy identyfikator j\u0119zyka (np. en, pl), ustawia j\u0119zyk testowy. To ustawi ten j\u0119zyki jako domy\u015blny oraz jedyny renderowany podczas budowy strony. Pomaga w zmniejszeniu czasu budowy strony oraz pozwala na \u0142atwe zmienianie j\u0119zyka zamiast modyfikowania pliku konfiguracyjnego. Przez zmiany w pluginie mkdocs-static-i18n jest to jedyny spos\u00f3b na tymczasow\u0105 zmian\u0119 domy\u015blnego j\u0119zyka
  • GMC_BUILD_ALTERNATES - warto\u015b\u0107 True albo False, aktywuje budowanie strony wraz z alternatywnymi j\u0119zykami. Domy\u015blnie alternatywne j\u0119zyki s\u0105 pomijane, aby zmenijszy\u0107 czas budowy strony.
  • GMC_ENABLE_ON_PUBLISH - warto\u015b\u0107 True albo False, aktywuje wszystkie finalne procesy, jak dodanie daty ostatniej aktualizacji, minimalizacja zasob\u00f3w itp.

Dla otwartego okna polece\u0144 mo\u017cna tymczasowo je ustawi\u0107:

Linux
export GMC_DEV_LOCALE=en export GMC_BUILD_ALTERNATES=False; mkdocs serve\n
Windows Powershell
$env:GMC_DEV_LOCALE=\"en\"\n$env:GMC_BUILD_ALTERNATES=\"False\"\nmkdocs serve\n
Windows Konsola Polece\u0144 (cmd)
set GMC_DEV_LOCALE=en\nset GMC_BUILD_ALTERNATES=False\nmkdocs serve\n
"},{"location":"pl/contribute/#wydajno\u015b\u0107-budowy-strony","title":"Wydajno\u015b\u0107 budowy strony","text":"

Aby przy\u015bpieszy\u0107 proces budowy strony podczas pracy, upewnij si\u0119, \u017ce tylko 1 j\u0119zyk jest budowany i rozwa\u017c u\u017cycie opcji --dirtyreload:

mkdocs serve --dirtyreload\n

To sprawi, \u017ce tylko zmienione pliki .md b\u0119d\u0105 na nowo budowane. Jednak\u017ce, zmiany plik\u00f3w szablonowych (ang. template) w folderze overrides nie b\u0119d\u0105 widoczne, poniewa\u017c takie zmiany wymagaj\u0105 pe\u0142nej przebudowy.

"},{"location":"pl/contribute/#prze\u015blij-plik","title":"Prze\u015blij plik","text":"

Je\u017celi praca z git albo Markdown jest nieprzyst\u0119pna lub niemo\u017cliwa to mo\u017cesz przes\u0142a\u0107 plik w formacie Google Docs na serwer Discord GMC, sformatujemy go i dodamy tre\u015b\u0107 do strony.

Tylko nowa zawarto\u015b\u0107 po angielsku

Ta opcja jest ograniczona tylko dla nowej tre\u015bci w j\u0119zyku angielskim. Nie mo\u017cemy wykorzysta\u0107 tego sposobu dla t\u0142umacze\u0144. Dla t\u0142umacze\u0144 wy\u015blij przet\u0142umaczony plik .md poprzez zg\u0142oszenie, je\u017celi nie chcesz pracowa\u0107 bezpo\u015brednio z git, ani doda\u0107 pliku poprzez interfejs GitHub.

"},{"location":"pl/contribute/#translations","title":"T\u0142umaczenia","text":"

\u017beby dostarczy\u0107 wsparcie dla wielu j\u0119zyk\u00f3w, nasza strona korzysta ze wtyczki MkDocs i18n.

"},{"location":"pl/contribute/#dodaj-wsparcie-dla-nowego-j\u0119zyka","title":"Dodaj wsparcie dla nowego j\u0119zyka","text":"

\u017beby wspiera\u0107 nowy j\u0119zyk, musi by\u0107 dodany:

Wci\u0119cia maj\u0105 znaczenie

Musisz zachowa\u0107 poprawn\u0105 ilo\u015b\u0107 wci\u0119\u0107, czyli odst\u0119p\u00f3w mi\u0119dzy wpisami.

  1. W konfiguracji mkdocs.yml, w tym przyk\u0142adzie dodajemy j\u0119zyk xx:

    plugins:\n  - i18n:\n      # ...\n      languages:\n        en:\n          name: en - English\n          build: true\n        xx:\n          name: xx - Language Name\n          build: true\n
  2. W pliku overrides/main.html, \u017ceby doda\u0107 tekst og\u0142oszenia dla zawarto\u015bci nieprzet\u0142umaczonej:

    {%\n    set announcement = {\n        \"en\": \"This page has not yet been translated into LANGUAGE, therefore it is displayed in English.\",\n        \"xx\": \"yyy\",\n    }\n%}\n{%\n    set call_to_action = {\n        \"en\": \"Support us and translate!\",\n        \"xx\": \"yyy\",\n    }\n%}\n
  3. Odwied\u017a oficjaln\u0105 stron\u0119 sk\u00f3rki. Upewnij si\u0119, \u017ce t\u0142umaczenie sk\u00f3rki jest tam kompletne. Je\u017celi nie jest, pod\u0105\u017caj wed\u0142ug poradnika kontrybucji sk\u00f3rki i wr\u00f3\u0107 tutaj, nie trzeba czeka\u0107 na zmiany w sk\u00f3rce.

"},{"location":"pl/contribute/#dodaj-przet\u0142umaczone-strony","title":"Dodaj przet\u0142umaczone strony","text":"

Ka\u017cdy plik .md w folderze docs mo\u017ce mie\u0107 przet\u0142umaczon\u0105 wersj\u0119. \u017beby doda\u0107 t\u0142umaczenie strony dla danego j\u0119zyka, stw\u00f3rz kopi\u0119 strony z dodan\u0105 ko\u0144c\u00f3wk\u0105 tego j\u0119zyka. Na przyk\u0142ad index.md b\u0119dzie index.xx.md dla j\u0119zyka xx bazuj\u0105c na ustawieniach z pliku mkdocs.yml.

Ka\u017cdy nieprzet\u0142umaczony artyku\u0142 posiada przycisk w g\u00f3rnym prawym rogu obok tytu\u0142u. Pozwala na szybkie dodanie t\u0142umaczenia poprzez interfejs serwisu GitHub bez potrzeby konfiguracji plik\u00f3w lokalnie.

"},{"location":"pl/genome/","title":"Genome Engine","text":""},{"location":"pl/genome/#genome-engine","title":"Genome Engine","text":"

Genome Engine to nowy silnik autorstwa Piranha Bytes stworzony na potrzeby gry Gothic 3, a nast\u0119pnie wykorzystany w serii gier Risen i ELEX.

"},{"location":"pl/zengin/#zengin","title":"ZenGin","text":"

Silnik gry ZenGin jest u\u017cywany w grach Gothic 1 i 2. Ta sekcja zawiera dokumentacj\u0119 r\u00f3\u017cnych aspekt\u00f3w modowania ZenGin.

"},{"location":"pl/zengin/music/","title":"Muzyka","text":""},{"location":"pl/zengin/music/#muzyka","title":"Muzyka","text":"

Zengin u\u017cywa DirectMusic do odtwarzania \u015bcie\u017cki d\u017awi\u0119kowej w grze. Aby edytowa\u0107 pliki muzyczne Gothica, potrzebujesz programu Direct Music Producer, kt\u00f3ry zosta\u0142 wydany przez Microsoft i by\u0142 dostarczany do starszych zestaw\u00f3w SDK DirectX.

Ostrze\u017cenie

Pliki muzyczne nie mog\u0105 by\u0107 spakowane do archiw\u00f3w .vdf lub .mod, wszystkie takie pliki musz\u0105 znajdowa\u0107 si\u0119 w katalogu /_work/Data/Music.

"},{"location":"pl/zengin/music/#formaty-plik\u00f3w","title":"Formaty plik\u00f3w","text":"

Katalog Music zawiera nast\u0119puj\u0105ce typy plik\u00f3w:

  • .dls - Plik formatu Downloadable Sound. Jest baz\u0105 dla wszystkich innych plik\u00f3w. Zawiera:

    • Kolekcje wirtualnych instrument\u00f3w muzycznych.
    • Pliki .wav u\u017cywane przez instrumenty.
  • .sty - Plik stylu. Zawiera:

    • Zespo\u0142y (Bands) - ustawienia instrument\u00f3w wirtualnych z .dls.
    • Wzory (Patterns) - fragmenty utwor\u00f3w, kt\u00f3re mo\u017cna p\u00f3\u017aniej \u0142\u0105czy\u0107, zap\u0119tla\u0107 i nak\u0142ada\u0107 na siebie.
  • .sgt - Plik z odpowiednio po\u0142\u0105czonymi wzorami (patternami) - ko\u0144cowy utw\u00f3r

"},{"location":"pl/zengin/music/#alternatywny-system-muzyczny","title":"Alternatywny System Muzyczny","text":"

Plugin zBassMusic zast\u0119puje domy\u015bln\u0105 bibliotek\u0119 muzyczn\u0105 Zengina, du\u017co nowsz\u0105 bibliotek\u0105 BASS. Umo\u017cliwia to mi\u0119dzy innymi odtwarzanie muzyki w takich formatach jak .mp3 lub .ogg, oraz pakownie utwor\u00f3w do archiw\u00f3w .vdf i .mod.

"},{"location":"pl/zengin/scripts/","title":"Skrypty","text":""},{"location":"pl/zengin/scripts/#skrypty","title":"Skrypty","text":"

ZenGin u\u017cywa w\u0142asnego j\u0119zyka skryptowego o nazwie Daedalus. Jest podobny do j\u0119zyka programowania C, wi\u0119c je\u015bli wiesz troch\u0119 o programowaniu w C, to rozpocz\u0119cie pracy b\u0119dzie do\u015b\u0107 \u0142atwe.

Katalog Scripts to miejsce, w kt\u00f3rym znajduj\u0105 si\u0119 skrypty. Znajdziesz tam pliki skrypt\u00f3w Daedalusa - o rozszerzeniach .d i .src, kt\u00f3re zawieraj\u0105 list\u0119 wszystkich plik\u00f3w do skompilowania.

Skrypty Daedalusa mo\u017cna edytowa\u0107 w dowolnym edytorze tekstu. Aby uzyska\u0107 przydatne funkcjonalno\u015bci typu pod\u015bwietlanie sk\u0142adni, mo\u017cesz u\u017cy\u0107 narz\u0119dzi stworzonych przez spo\u0142eczno\u015b\u0107, takich jak

  • Gothic Sourcer
  • Daedalus VS Code extension
"},{"location":"pl/zengin/scripts/extenders/","title":"Extendery Daedalusa","text":""},{"location":"pl/zengin/scripts/extenders/#extendery-daedalusa","title":"Extendery Daedalusa","text":"

Extendery to pakiety skryptowe rozszerzaj\u0105ce sk\u0142adni\u0119 Daedalusa, kt\u00f3ra mo\u017ce by\u0107 dosy\u0107 ograniczaj\u0105ca. Przez lata spo\u0142eczno\u015b\u0107 stworzy\u0142a ca\u0142kiem sporo takich extender\u00f3w. Zanim pojawi\u0142 si\u0119 Union, standardow\u0105 metod\u0105 na interfejs z silnikiem by\u0142o wykorzystanie Ikarusa i zbudowanej na jego bazie kolekcji pakiet\u00f3w LeGo. Nie tak niedawno powsta\u0142 dodatkowy pakiet skryptowy (a prace nad nim wci\u0105\u017c trwaj\u0105) AF Script Packet, kt\u00f3ry oferuje jeszcze wi\u0119cej funkcji i jest zbudowany na bazie Ikarusa i LeGo. Wraz z pojawieniem si\u0119 Uniona i jego systemu plugin\u00f3w powsta\u0142 nowy extender o nazwie zParserExtender. Oczywi\u015bcie r\u00f3wnie\u017c inne pluginy mog\u0105 implementowa\u0107 w\u0142asne funkcje zewn\u0119trzne. Wiele skrypt\u00f3w jest r\u00f3wnie\u017c rozsianych po forach Gothicowych, a dokumentacje niekt\u00f3rych z nich mo\u017cna znale\u017a\u0107 w sekcji Samodzielne.

"},{"location":"pl/zengin/scripts/extenders/ikarus/#ikarus","title":"Ikarus","text":"

Ikarus jest bibliotek\u0105 Daedalusa - j\u0119zyka skryptowego Gothica. Wykorzystuje interpreter, aby umo\u017cliwi\u0107 dowolny dost\u0119p do pami\u0119ci i definiuje mn\u00f3stwo przydatnych funkcji do pracy z silnikiem.

Kontakt Autor Sektenspinner i wsp\u00f3\u0142tw\u00f3rcy GitHub Ikarus Forum Ikarus

Notatka autora (Sektenspinner)

Ten pakiet skrypt\u00f3w nie bez powodu nazywa si\u0119 Ikarus:

Mo\u017cna opu\u015bci\u0107 granice Dedala, ale mo\u017cna te\u017c rozbi\u0107 si\u0119 i spali\u0107. Na przyk\u0142ad odczyt z nieprawid\u0142owych adres\u00f3w nie wywo\u0142a ostrze\u017cenia zSpy, ale spowoduje wyj\u015bcie do pulpitu wraz z Access Violation. Nie jest to pow\u00f3d do paniki, ale wymaga tolerancji na frustracj\u0119 (co mo\u017ce by\u0107 og\u00f3lnie przydatne dla skrypter\u00f3w).

Oczywi\u015bcie tak spektakularnie wygl\u0105daj\u0105ce b\u0142\u0119dy mo\u017cna naprawi\u0107, a przy systematycznej pracy w skupieniu mo\u017cna osi\u0105gn\u0105\u0107 co\u015b sensownego.

W skr\u00f3cie: wymagana jest dodatkowa ostro\u017cno\u015b\u0107! B\u0142\u0105d prowadz\u0105cy do awarii nie jest czym\u015b, czego chcia\u0142by\u015b w wydanej wersji. Ale je\u015bli pracujesz czysto i intensywnie testujesz, nie jest to taka wielka sprawa.

Dobrym przyjacielem w debugowaniu awarii jest niew\u0105tpliwie PrintDebug. Umo\u017cliwia wysy\u0142anie wiadomo\u015bci do zSpy (na przyk\u0142ad w celu zaw\u0119\u017cenia miejsca wyst\u0105pienia awarii). Warto w\u0142\u0105czy\u0107 komunikaty debugowania za pomoc\u0105 MEM_SetShowDebug i filtr tekstowy (Opcje -> Textfilter) w zSpy.

Note

Ikarus jest hostowany na GitHubie i posiada wbudowan\u0105 dokumentacje. Jej t\u0142umaczenie jest w planach.

"},{"location":"pl/zengin/scripts/extenders/ikarus/functions/ini_access/","title":"Dost\u0119p do plik\u00f3w konfiguracyjnych","text":""},{"location":"pl/zengin/scripts/extenders/ikarus/functions/ini_access/#dost\u0119p-do-plik\u00f3w-konfiguracyjnych","title":"Dost\u0119p do plik\u00f3w konfiguracyjnych","text":"

Ta cz\u0119\u015b\u0107 Ikarusa umo\u017cliwia dost\u0119p do Gothic.ini i pliku konfiguracyjnego za\u0142adowanej modyfikacji.

"},{"location":"pl/zengin/scripts/extenders/ikarus/functions/ini_access/#inicjalizacja","title":"Inicjalizacja","text":"

Najlepszym sposobem na zainicjowanie Ikarusa jest wywo\u0142anie MEM_InitAll() w funkcji Init_Global().

Warning

Je\u017celi chcesz u\u017cywa\u0107 Ikarusa z Gothiciem 1, najlepiej b\u0119dzie, je\u015bli zdefiniujesz w\u0142asn\u0105 funkcj\u0119 Init_Global() i wywo\u0142asz j\u0105 w ka\u017cdej funkcji inicjuj\u0105cej \u015bwiat.

MEM_InitAll();\n
"},{"location":"pl/zengin/scripts/extenders/ikarus/functions/ini_access/#implementacja","title":"Implementacja","text":"

Ikarus.d na GitHubie

"},{"location":"pl/zengin/scripts/extenders/ikarus/functions/ini_access/#funkcje-odczytu","title":"Funkcje odczytu","text":""},{"location":"pl/zengin/scripts/extenders/ikarus/functions/ini_access/#mem_getcommandline","title":"MEM_GetCommandLine","text":"

Zwraca zawarto\u015b\u0107 linii polece\u0144 przekazan\u0105 do Gothica.

func string MEM_GetCommandLine()\n
Zwracana warto\u015b\u0107

Funkcja zwraca zawarto\u015b\u0107 linii polece\u0144 przekazan\u0105 do Gothica. Mo\u017ce to wygl\u0105da\u0107 na przyk\u0142ad tak:

\"-TIME:7:35 -GAME:TEST_IKARUS.INI -ZREPARSE -ZWINDOW -ZLOG:5,S -DEVMODE -ZMAXFRAMERATE:30\"

"},{"location":"pl/zengin/scripts/extenders/ikarus/functions/ini_access/#mem_getgothopt","title":"MEM_GetGothOpt","text":"

Przeszukuje Gothic.ini w poszukiwaniu opcji

func string MEM_GetGothOpt(var string sectionname, var string optionname)\n
Parametry
  • var string sectionname Nazwa sekcji np. [GAME]
  • var string optionname Szukana opcja np. playLogoVideos

Zwracana warto\u015b\u0107

Funkcja zwraca warto\u015b\u0107 opcji w postaci ci\u0105gu znak\u00f3w, albo pust\u0105 zmienn\u0105, gdy opcja nie istnieje w danej sekcji.

"},{"location":"pl/zengin/scripts/extenders/ikarus/functions/ini_access/#mem_getmodopt","title":"MEM_GetModOpt","text":"

Przeszukuje ini za\u0142adowanej modyfikacji w poszukiwaniu opcji.

func void MEM_GetModOpt(var string sectionname, var string optionname)\n
Parametry
  • var string sectionname Nazwa sekcji np. [INFO]
  • var string optionname Szukana opcja np. Title

Zwracana warto\u015b\u0107

Funkcja zwraca warto\u015b\u0107 opcji w postaci ci\u0105gu znak\u00f3w, albo pust\u0105 zmienn\u0105, gdy opcja nie istnieje w danej sekcji.

"},{"location":"pl/zengin/scripts/extenders/ikarus/functions/ini_access/#mem_gothoptsectionexists","title":"MEM_GothOptSectionExists","text":"

Sprawdza, czy dana sekcja istnieje w Gothic.ini

func int MEM_GothOptSectionExists(var string sectionname)\n
Parametry
  • var string sectionname Nazwa sekcji np. [GAME]

Zwracana warto\u015b\u0107

Funkcja zwraca warto\u015b\u0107 TRUE je\u015bli sekcja istnieje, inaczej FALSE.

"},{"location":"pl/zengin/scripts/extenders/ikarus/functions/ini_access/#mem_modoptsectionexists","title":"MEM_ModOptSectionExists","text":"

Sprawdza, czy dana sekcja istnieje w ini za\u0142adowanej modyfikacji.

func int MEM_ModOptSectionExists(var string sectionname)\n
Parametry
  • var string sectionname Nazwa sekcji np. [INFO]

Zwracana warto\u015b\u0107

Funkcja zwraca warto\u015b\u0107 TRUE je\u015bli sekcja istnieje, inaczej FALSE.

"},{"location":"pl/zengin/scripts/extenders/ikarus/functions/ini_access/#mem_gothoptexists","title":"MEM_GothOptExists","text":"

Sprawdza, czy dana opcja istnieje w Gothic.ini

func int MEM_GothOptExists(var string sectionname, var string optionname)\n
Parametry
  • var string sectionname Nazwa sekcji np. [GAME]
  • var string optionname Szukana opcja np. playLogoVideos

Zwracana warto\u015b\u0107

Funkcja zwraca warto\u015b\u0107 TRUE je\u015bli opcja w danej sekcji istnieje, inaczej FALSE.

"},{"location":"pl/zengin/scripts/extenders/ikarus/functions/ini_access/#mem_modoptexists","title":"MEM_ModOptExists","text":"

Sprawdza, czy dana opcja istnieje w ini za\u0142adowanej modyfikacji.

func int MEM_ModOptExists(var string sectionname, var string optionname)\n
Parametry
  • var string sectionname Nazwa sekcji np. [INFO]
  • var string optionname Szukana opcja np. Title

Zwracana warto\u015b\u0107

Funkcja zwraca warto\u015b\u0107 TRUE je\u015bli opcja w danej sekcji istnieje, inaczej FALSE.

"},{"location":"pl/zengin/scripts/extenders/ikarus/functions/ini_access/#funkcje-zapisu","title":"Funkcje zapisu","text":"

Warning

Plik konfiguracyjny modyfikacji nigdy nie jest zapisywany na dysku, dlatego nie ma oddzielnej funkcji do jego zapisu.

"},{"location":"pl/zengin/scripts/extenders/ikarus/functions/ini_access/#mem_setgothopt","title":"MEM_SetGothOpt","text":"

Opcja option w sekcji section jest ustawiana na value. Je\u015bli sekcja i/lub opcja nie istnieje, zostanie utworzona.

func void MEM_SetGothOpt(var string section, var string option, var string value)\n
Parametry
  • var string section Sekcja, w kt\u00f3rej znajduje si\u0119 opcja
  • var string option Opcja do zapisania/nadpisania
  • var string value Warto\u015b\u0107, na jak\u0105 ustawiana jest opcja
"},{"location":"pl/zengin/scripts/extenders/ikarus/functions/ini_access/#mem_applygothopt","title":"MEM_ApplyGothOpt","text":"

Stosuje zmiany i zapisuje plik ini na dysku.

func void MEM_ApplyGothOpt()\n

Tip

Je\u015bli wprowadzasz nowe opcje, najlepiej kierowa\u0107 si\u0119 paroma zasadami. Dobr\u0105 praktyk\u0105 jest nazywanie swoich opcji tak, aby inni mogli je zrozumie\u0107 i umieszczanie ich w sekcji o takiej samej nazwie jak tw\u00f3j mod. Nie umieszczaj opcji swojej modyfikacji w sekcji [GAME] lub [PERFORMANCE].

"},{"location":"pl/zengin/scripts/extenders/ikarus/functions/ini_access/#funkcje-klawiszy","title":"Funkcje klawiszy","text":"

Gothic.ini zawiera przypisanie klawiszy fizycznych (np. \"W\") do klawiszy logicznych (np. \"keyUp\").

"},{"location":"pl/zengin/scripts/extenders/ikarus/functions/ini_access/#mem_getkey","title":"MEM_GetKey","text":"

Zwraca podstawowy klawisz przypisany do klawisza logicznego.

func int MEM_GetKey(var string name)\n
Parametry
  • var string name Nazwa klawisza logicznego

Zwracana warto\u015b\u0107

Funkcja zwraca klawisz przypisany do klawisza logicznego.

"},{"location":"pl/zengin/scripts/extenders/ikarus/functions/ini_access/#mem_getsecondarykey","title":"MEM_GetSecondaryKey","text":"

Zwraca zapasowy klawisz przypisany do klawisza logicznego.

func int MEM_GetSecondaryKey(var string name)\n
Parametry
  • var string name Nazwa klawisza logicznego

Zwracana warto\u015b\u0107

Funkcja zwraca klawisz przypisany do klawisza logicznego.

"},{"location":"pl/zengin/scripts/extenders/ikarus/functions/ini_access/#mem_setkeys","title":"MEM_SetKeys","text":"

Ustawia klawisze klawiatury dla podanego klawisza logicznego.

func void MEM_SetKeys(var string name, var int primary, var int secondary)\n
Parametry
  • var string name Nazwa klawisza logicznego
  • var int primary Podstawowy klawisz do przypisania, mo\u017cna go pobra\u0107 z pliku Ikarus_Const_G1 / Ikarus_Const_G2.
  • var int secondary Zapasowy klawisz do przypisania, mo\u017cna go pobra\u0107 z pliku Ikarus_Const_G1 / Ikarus_Const_G2.
"},{"location":"pl/zengin/scripts/extenders/ikarus/functions/ini_access/#mem_setkey","title":"MEM_SetKey","text":"

Ustawia podstawowy klawisz klawiatury dla klawisza logicznego.

func void MEM_SetKey(var string name, var int key)\n
Parametry
  • var string name Nazwa klawisza logicznego
  • var int key Podstawowy klawisz do przypisania, mo\u017cna go pobra\u0107 z pliku Ikarus_Const_G1 / Ikarus_Const_G2.
"},{"location":"pl/zengin/scripts/extenders/ikarus/functions/ini_access/#mem_setsecondarykey","title":"MEM_SetSecondaryKey","text":"

Ustawia zapasowy klawisz klawiatury dla klawisza logicznego.

func void MEM_SetSecondaryKey(var string name, var int key)\n
Parametry
  • var string name Nazwa klawisza logicznego
  • var int key Zapasowy klawisz do przypisania, mo\u017cna go pobra\u0107 z pliku Ikarus_Const_G1 / Ikarus_Const_G2.
"},{"location":"pl/zengin/scripts/extenders/lego/#lego","title":"LeGo","text":"

LeGo (LehonaGottfried) to pakiet skryptowy zbudowany na bazie Ikarusa.

Kontakt Autor Lehona, Gottfried i wsp\u00f3\u0142tw\u00f3rcy GitHub LeGo Forum LeGo

Note

Kod LeGo jest hostowany na GitHubie, a sam pakiet skryptowy ma w\u0142asn\u0105 stron\u0119 z dokumentacj\u0105.

"},{"location":"pl/zengin/scripts/extenders/lego/applications/bars/","title":"Bars - paski","text":""},{"location":"pl/zengin/scripts/extenders/lego/applications/bars/#bars---paski","title":"Bars - paski","text":"

Ten pakiet bardzo u\u0142atwia dodawanie nowych pask\u00f3w, dla wy\u015bwietlania np. wytrzyma\u0142o\u015bci.

"},{"location":"pl/zengin/scripts/extenders/lego/applications/bars/#zale\u017cno\u015bci","title":"Zale\u017cno\u015bci","text":"
  • PermMem
  • View
"},{"location":"pl/zengin/scripts/extenders/lego/applications/bars/#inicjalizacja","title":"Inicjalizacja","text":"

Zainicjuj za pomoc\u0105 flagi LeGo_Bars.

LeGo_Init(LeGo_Bars);\n
"},{"location":"pl/zengin/scripts/extenders/lego/applications/bars/#implementacja","title":"Implementacja","text":"

Bars.d na GitHubie

"},{"location":"pl/zengin/scripts/extenders/lego/applications/bars/#funkcje","title":"Funkcje","text":"

Note

Je\u015bli prototyp GothicBar jest wybrany jako typ pocz\u0105tkowy (GothicBar@ jako konstruktor), paski u\u017cytkownika s\u0105 wizualnie nie do odr\u00f3\u017cnienia od tych u\u017cywanych w Gothicu.

"},{"location":"pl/zengin/scripts/extenders/lego/applications/bars/#bar_create","title":"Bar_Create","text":"

Tworzy nowy pasek z instancji konstruktora.

func int Bar_Create(var int inst)\n

Parametry

  • var int inst Instancja konstruktora klasy Bar

Zwracana warto\u015b\u0107

Funkcja zwraca handler do nowego paska.

Examples

var int bar; bar = Bar_Create(GothicBar@);

var int bar; bar = Bar_Create(GothicBar@); // Tworzy nowy pasek\nBar_SetPercent(bar, 50);                   // Ustawia jego warto\u015b\u0107 na 50%\n
func void Example_1()\n{\n    var int bar; bar = Bar_Create(GothicBar@); // Tworzy nowy pasek\n    Bar_SetPercent(bar, 50);                   // Ustawia jego warto\u015b\u0107 na 50%\n};\n
"},{"location":"pl/zengin/scripts/extenders/lego/applications/bars/#bar_delete","title":"Bar_Delete","text":"

Usuwa pasek z ekranu i pami\u0119ci.

func void Bar_Delete(var int bar)\n

Parametry

  • var int bar Handler zwr\u00f3cony przez Bar_Create
"},{"location":"pl/zengin/scripts/extenders/lego/applications/bars/#bar_setmax","title":"Bar_SetMax","text":"

Zmienia maksymalna warto\u015b\u0107 paska, ale nie aktualizuje jego d\u0142ugo\u015bci (tylko Bar_SetPercent, Bar_SetPromille i Bar_SetValue to robi\u0105)

func void Bar_SetMax(var int bar, var int max)\n
Parametry
  • var int bar Handler zwr\u00f3cony przez Bar_Create

  • var int max Nowa maksymalna warto\u015b\u0107

"},{"location":"pl/zengin/scripts/extenders/lego/applications/bars/#bar_setvalue","title":"Bar_SetValue","text":"

Ustawia warto\u015b\u0107 paska.

func void Bar_SetValue(var int bar, var int val)\n
Parametry
  • var int bar Handler zwr\u00f3cony przez Bar_Create
  • var int val Nowa warto\u015b\u0107 paska
"},{"location":"pl/zengin/scripts/extenders/lego/applications/bars/#bar_setpercent","title":"Bar_SetPercent","text":"

Ustawia warto\u015b\u0107 paska, ale w procentach (0..100).

func void Bar_SetPercent(var int bar, var int perc)\n
Parametry
  • var int bar Handler zwr\u00f3cony przez Bar_Create
  • var int perc Nowa warto\u015b\u0107 paska w procentach
"},{"location":"pl/zengin/scripts/extenders/lego/applications/bars/#bar_setpromille","title":"Bar_SetPromille","text":"

Ustawia warto\u015b\u0107 paska, ale w promilach (0..1000).

func void Bar_SetPromille(var int bar, var int pro)\n
Parametry
  • var int bar Handler zwr\u00f3cony przez Bar_Create
  • var int pro Nowa warto\u015b\u0107 paska w promilach
"},{"location":"pl/zengin/scripts/extenders/lego/applications/bars/#bar_hide","title":"Bar_Hide","text":"

Ukrywa pasek, ale go nie usuwa.

func void Bar_Hide(var int bar)\n
Parametry
  • var int bar Handler zwr\u00f3cony przez Bar_Create
"},{"location":"pl/zengin/scripts/extenders/lego/applications/bars/#bar_show","title":"Bar_Show","text":"

Wy\u015bwietla pasek ponownie po u\u017cyciu Bar_Hide.

func void Bar_Show(var int bar)\n
Parametry
  • var int bar Handler zwr\u00f3cony przez Bar_Create
"},{"location":"pl/zengin/scripts/extenders/lego/applications/bars/#bar_moveto","title":"Bar_MoveTo","text":"

Przenosi pasek do danej pozycji wirtualnej.

func void Bar_MoveTo(var int bar, var int x, var int y)\n
Parametry
  • var int bar Handler zwr\u00f3cony przez Bar_Create
  • var int x Nowa pozycja w osi x
  • var int y Nowa pozycja w osi y
"},{"location":"pl/zengin/scripts/extenders/lego/applications/bars/#bar_movetopxl","title":"Bar_MoveToPxl","text":"

Przenosi pasek do danej pozycji wyra\u017conej w pikselach.

func void Bar_MoveToPxl(var int bar, var int x, var int y)\n
Parametry
  • var int bar Handler zwr\u00f3cony przez Bar_Create
  • var int x Nowa pozycja w osi x
  • var int y Nowa pozycja w osi y
"},{"location":"pl/zengin/scripts/extenders/lego/applications/bars/#bar_setalpha","title":"Bar_SetAlpha","text":"

Ustawia przezroczysto\u015b\u0107 paska.

func void Bar_SetAlpha(var int bar, var int alpha)\n
Parametry
  • var int bar Handler zwr\u00f3cony przez Bar_Create
  • var int alpha Warto\u015b\u0107 przezroczysto\u015bci (0..255)
"},{"location":"pl/zengin/scripts/extenders/lego/applications/bars/#bar_setbartexture","title":"Bar_SetBarTexture","text":"

Ustawia tekstur\u0119 warto\u015bci paska.

func void Bar_SetBarTexture(var int bar, var string barTex)\n
Parametry
  • var int bar Handler zwr\u00f3cony przez Bar_Create
  • var string barTex Nowa tekstura
"},{"location":"pl/zengin/scripts/extenders/lego/applications/bars/#bar_setbacktexture","title":"Bar_SetBackTexture","text":"

Ustawia tekstur\u0119 t\u0142a paska.

func void Bar_SetBackTexture(var int bar, var string backTex)\n
Parametry
  • var int bar Handler zwr\u00f3cony przez Bar_Create
  • var string backTex Nowa tekstura t\u0142a
"},{"location":"pl/zengin/scripts/extenders/lego/applications/bars/#bar_resize","title":"Bar_Resize","text":"

Zmienia rozmiar istniej\u0105cego paska.

func void Bar_Resize(var int bar, var int width, var int height)\n
Parametry
  • var int bar Handler zwr\u00f3cony przez Bar_Create
  • var int width Nowa szeroko\u015b\u0107
  • var int height Nowa szeroko\u015b\u0107
"},{"location":"pl/zengin/scripts/extenders/lego/applications/bars/#bar_resizepxl","title":"Bar_ResizePxl","text":"

Resize existing bar (in pixels).

func void Bar_ResizePxl(var int bar, var int x, var int y)\n
Parametry
  • var int bar Handler zwr\u00f3cony przez Bar_Create
  • var int x Nowa szeroko\u015b\u0107 w pikselach
  • var int y Nowa szeroko\u015b\u0107 w pikselach
"},{"location":"pl/zengin/scripts/extenders/lego/applications/bars/#przyk\u0142ady","title":"Przyk\u0142ady","text":"

Note

Ten pakiet zak\u0142ada podstawowe zrozumienie modu\u0142u PermMem.

"},{"location":"pl/zengin/scripts/extenders/lego/applications/bars/#dedykowany-pasek-do\u015bwiadczenia","title":"Dedykowany pasek do\u015bwiadczenia","text":"

Pakiet Bars implementuje klas\u0119 Bar. Kt\u00f3ra wygl\u0105da tak:

class Bar\n{\n    var int x;          // Pozycja na ekranie w osi X (\u015brodka paska)\n    var int y;          // Pozycja na ekranie w osi Y (\u015brodka paska)\n    var int barTop;     // Pasek odst\u0119pu t\u0142a - g\u00f3ra/d\u00f3\u0142\n    var int barLeft;    // Pasek odst\u0119pu t\u0142a - lewo/prawo\n    var int width;      // Szeroko\u015b\u0107\n    var int height;     // Wysoko\u015b\u0107\n    var string backTex; // Tekstura t\u0142a\n    var string barTex;  // Tekstura warto\u015bci paska\n    var int value;      // Pocz\u0105tkowa warto\u015b\u0107\n    var int valueMax;   // Maksymalna warto\u015b\u0107\n};\n
Prototyp GothicBar jest paskiem, kt\u00f3ry na\u015bladuje standardowy pasek u\u017cywany w grze.
prototype GothicBar(Bar)\n{\n    x = Print_Screen[PS_X] / 2;\n    y = Print_Screen[PS_Y] - 20;\n    barTop = 3;\n    barLeft = 7;\n    width = 180;\n    height = 20;\n    backTex = \"Bar_Back.tga\";\n    barTex = \"Bar_Misc.tga\";\n    value = 100;\n    valueMax = 100;\n};\n

O wiele \u0142atwiej jest skonfigurowa\u0107 now\u0105 instancj\u0119 przy u\u017cyciu tego prototypu. GothicBar bez zmian mo\u017cna znale\u017a\u0107 jako instancj\u0119 GothicBar@, kt\u00f3r\u0105 u\u017cyli\u015bmy do stworzenia paska w powy\u017cszym przyk\u0142adzie. GothicBar znajduje si\u0119 na \u015brodku ekranu i wygl\u0105da tak samo, jak pasek wy\u015bwietlany podczas nurkowania.

// Instancja stworzona z pomoc\u0105 prototypu GothicBar \ninstance Bar_1(GothicBar)\n{\n    x = 100;\n    y = 20;\n};\n\nfunc void Example_1()\n{\n    // Example_1 mo\u017ce by\u0107 wywo\u0142any np. w Init_Global\n    FF_ApplyOnce(Loop_1);\n};\n\nfunc void Loop_1()\n{\n    // Example_1 uruchamia t\u0119 p\u0119tl\u0119.\n    // Tutaj pasek powinien by\u0107 stworzony raz\n    // a potem sparowany z punktami do\u015bwiadczenia:\n    var int MyBar;\n    if(!Hlp_IsValidHandle(MyBar))\n    {\n        MyBar = Bar_Create(Bar_1); // Our Bar_1\n    };\n    // Reszta jest chyba oczywista:\n    Bar_SetMax(MyBar, hero.exp_next);\n    Bar_SetValue(MyBar, hero.exp);\n};\n

Note

Jest to t\u0142umaczenie artyku\u0142u napisanego oryginalnie przez Gottfrieda i Lehone i umieszczonego w oficjalnej dokumentacji pakietu LeGo.

"},{"location":"pl/zengin/scripts/extenders/lego/applications/console_commands/","title":"Console Commands - polecenia konsoli","text":""},{"location":"pl/zengin/scripts/extenders/lego/applications/console_commands/#console-commands---polecenia-konsoli","title":"Console Commands - polecenia konsoli","text":"

Ten Pakiet pozwala na tworzenie nowych polece\u0144 konsoli dost\u0119pnej po naci\u015bni\u0119ciu klawisza F2 w trybie marvin.

"},{"location":"pl/zengin/scripts/extenders/lego/applications/console_commands/#zale\u017cno\u015bci","title":"Zale\u017cno\u015bci","text":"
  • PermMem
  • HookEngine
"},{"location":"pl/zengin/scripts/extenders/lego/applications/console_commands/#inicjalizacja","title":"Inicjalizacja","text":"

Zainicjuj za pomoc\u0105 flagi LeGo_ConsoleCommands.

LeGo_Init(LeGo_ConsoleCommands);\n
"},{"location":"pl/zengin/scripts/extenders/lego/applications/console_commands/#implementacja","title":"Implementacja","text":"

ConsoleCommands.d na GitHubie

"},{"location":"pl/zengin/scripts/extenders/lego/applications/console_commands/#funkcje","title":"Funkcje","text":""},{"location":"pl/zengin/scripts/extenders/lego/applications/console_commands/#cc_register","title":"CC_Register","text":"

Rejestruje nowe polecenie konsoli.

func void CC_Register(var func f, var string cmdPrefix, var string description)\n
Parametry
  • var func f Ta funkcja jest wykonywana po wprowadzeniu polecenia cmdPrefix w konsoli. Sygnatura funkcji to func string f(var string p0). Przekazany string to wszystko, co zosta\u0142o okre\u015blone w konsoli po faktycznym poleceniu. Zwracana warto\u015b\u0107 jest nast\u0119pnie wy\u015bwietlana w konsoli.
  • var string cmdPrefix Jest to polecenie, kt\u00f3re mo\u017cna wprowadzi\u0107 w konsoli.
  • var string description Ten tekst pojawia si\u0119 obok polecenia (w zSpy), gdy u\u017cywasz polecenia help w konsoli.
"},{"location":"pl/zengin/scripts/extenders/lego/applications/console_commands/#cc_remove","title":"CC_Remove","text":"

Usuwa funkcje z konsoli komend.

func void CC_Remove(var func f)\n
Parametry
  • var func f Ta funkcja zostanie usuni\u0119ta, a powi\u0105zane z ni\u0105 polecenie przestanie dzia\u0142a\u0107.
"},{"location":"pl/zengin/scripts/extenders/lego/applications/console_commands/#cc_active","title":"CC_Active","text":"

Sprawdza, czy dana funkcja jest ju\u017c cz\u0119\u015bci\u0105 polecenia konsoli.

func int CC_Active(var func f)\n
Parametry
  • var func f Sprawdzana funkcja

Zwracana warto\u015b\u0107

Funkcja zwraca TRUE je\u015bli znajdzie odpowiedni\u0105 funkcj\u0119, inaczej FALSE.

"},{"location":"pl/zengin/scripts/extenders/lego/applications/console_commands/#przyk\u0142ady","title":"Przyk\u0142ady","text":""},{"location":"pl/zengin/scripts/extenders/lego/applications/console_commands/#proste-polecenie-konsoli","title":"Proste polecenie konsoli","text":"

Jako prosty przyk\u0142ad stw\u00f3rzmy polecenie version, kt\u00f3re wy\u015bwietli nam wersj\u0119 modyfikacji. Po pierwsze, deklarujemy sta\u0142\u0105 zmienn\u0105 string do przechowywania informacji o wersji.

const string Mod_Version = \"Wersja modyfikacji - 0.1alpha\";\n
Nast\u0119pnie tworzymy now\u0105 funkcj\u0119.

Note

Zwr\u00f3\u0107 uwag\u0119 na poprawn\u0105 sygnatur\u0119 funkcji. Je\u015bli b\u0119dzie ona b\u0142\u0119dna, polecenie spowoduje awari\u0119 gry.

// Ta funkcja jest wywo\u0142ywana przez nasze nowe polecenie\nfunc string CC_ModVersion(var string param)\n{\n    return Mod_Version;\n};\n
Nast\u0119pnie musimy zarejestrowa\u0107 polecenie. Dla wygody stworzy\u0142em now\u0105 funkcj\u0119 RegisterConsoleFunctions, kt\u00f3ra inicjuje wszystkie polecenia konsoli. Funkcja jest naprawd\u0119 prosta.
func void RegisterConsoleFunctions()\n{\n    CC_Register (CC_ModVersion, \"version\", \"Wersja mojej modyfikacji.\");\n};\n
Na koniec musimy wywo\u0142a\u0107 t\u0119 funkcj\u0119 w INIT_GLOBAL.
func void INIT_GLOBAL()\n{\n    Game_InitGerman(); // tylko w G2\n\n    // Inicjalizacja Ikarusa\n    MEM_InitAll();\n\n    // Inicjalizacja LeGo\n    LeGo_Init(LeGo_ConsoleCommands);\n\n    // Tutaj rejstrujemy nasze polecenia\n    RegisterConsoleFunctions();\n\n    // Reszta kodu\n};\n
"},{"location":"pl/zengin/scripts/extenders/lego/applications/gamestate/","title":"Gamestate - stan gry","text":""},{"location":"pl/zengin/scripts/extenders/lego/applications/gamestate/#gamestate---stan-gry","title":"Gamestate - stan gry","text":"

Pakiet Gamestate pozwala sprawdzi\u0107 stan gry (rozpocz\u0119cie gry, \u0142adowanie gry lub zmiana poziomu).

"},{"location":"pl/zengin/scripts/extenders/lego/applications/gamestate/#zale\u017cno\u015bci","title":"Zale\u017cno\u015bci","text":"
  • EventHandler
  • Saves
"},{"location":"pl/zengin/scripts/extenders/lego/applications/gamestate/#inicjalizacja","title":"Inicjalizacja","text":"

Zainicjuj za pomoc\u0105 flagi LeGo_Gamestate.

LeGo_Init(LeGo_Gamestate);\n
"},{"location":"pl/zengin/scripts/extenders/lego/applications/gamestate/#implementacja","title":"Implementacja","text":"

Gamestate.d na GitHubie

"},{"location":"pl/zengin/scripts/extenders/lego/applications/gamestate/#funkcje","title":"Funkcje","text":""},{"location":"pl/zengin/scripts/extenders/lego/applications/gamestate/#gamestate_addlistener","title":"Gamestate_AddListener","text":"

Dodaje listener/handler zmiany stanu gry.

func void Gamestate_AddListener(var func listener)\n
Parametry
  • var func listener Ta funkcja zostanie wywo\u0142ana przy zmianie stanu gry. Bie\u017c\u0105cy stan gry jest przekazywany jako parametr.
"},{"location":"pl/zengin/scripts/extenders/lego/applications/gamestate/#gamestate_removelistener","title":"Gamestate_RemoveListener","text":"

Usuwa listener zmiany stanu gry.

func void Gamestate_RemoveListener(var func listener)\n
Parametry
  • var func listener Listener do usuni\u0119cia.
"},{"location":"pl/zengin/scripts/extenders/lego/applications/gamestate/#przyk\u0142ady","title":"Przyk\u0142ady","text":"

Istniej\u0105 teraz dwie mo\u017cliwo\u015bci. Wszystko mo\u017cna zrobi\u0107 bezpo\u015brednio w Init_Global lub za pomoc\u0105 EventHandler.

"},{"location":"pl/zengin/scripts/extenders/lego/applications/gamestate/#init_global","title":"Init_Global","text":"
func void Init_Global()\n{\n    // [...]\n\n    LeGo_Init(LeGo_All);\n\n    if(Gamestate == Gamestate_NewGame) \n    {\n        MEM_Info(\"Nowa gra rozpocz\u0119ta.\");\n    }\n    else if(Gamestate == Gamestate_Loaded)\n    {\n        MEM_Info(\"\u0141adowanie gry.\");\n    }\n    else if(Gamestate == Gamestate_WorldChange)\n    {\n        MEM_Info(\"Zmiana \u015bwiata.\");\n    }\n    else\n    {\n        MEM_Info(\"Brak zmiany stanu gry\");\n    };\n};\n

Mo\u017cna to r\u00f3wnie\u017c zrobi\u0107 tak:

func void Init_Global()\n{\n    // [...]\n\n    LeGo_Init(LeGo_All);\n\n    if(Gamestate == Gamestate_NewGame)\n    {\n        FF_Apply(MyLoop);\n        FF_Apply(My2ndLoop);\n    };\n};\n
Da\u0142oby to taki sam efekt jak:
func void Init_Global()\n{\n    // [...]\n\n    LeGo_Init(LeGo_All);\n\n    FF_ApplyOnce(MyLoop);\n    FF_ApplyOnce(My2ndLoop);\n};\n
"},{"location":"pl/zengin/scripts/extenders/lego/applications/gamestate/#eventhandler","title":"EventHandler","text":"
func void Init_Global()\n{\n    // [...]\n\n    LeGo_Init(LeGo_All);\n\n    Gamestate_AddListener(MyGamestateListener);\n};\n\nfunc void MyGamestateListener(var int state)\n{\n    if(state == Gamestate_NewGame)\n    {\n        MEM_Info(\"Nowa gra rozpocz\u0119ta.\");\n    }\n    else if(state == Gamestate_Loaded)\n    {\n        MEM_Info(\"\u0141adowanie gry.\");\n    }\n    else if(state == Gamestate_WorldChange)\n    {\n        MEM_Info(\"Zmiana \u015bwiata.\");\n    }\n    else\n    {\n        MEM_Info(\"Brak zmiany stanu gry.\");\n    };\n};\n
Daje taki sam efekt jak przyk\u0142ad z Init_Global ale dla niekt\u00f3rych mo\u017ce lepiej wygl\u0105da\u0107.

Note

Jest to t\u0142umaczenie artyku\u0142u napisanego oryginalnie przez Gottfrieda i Lehone i umieszczonego w oficjalnej dokumentacji pakietu LeGo.

"},{"location":"pl/zengin/scripts/extenders/lego/applications/trialoge/","title":"Trialogi","text":""},{"location":"pl/zengin/scripts/extenders/lego/applications/trialoge/#trialogi","title":"Trialogi","text":"

Ten pakiet pozwala na tworzenie rozm\u00f3w z dowoln\u0105 liczb\u0105 NPC i sterowanie kamer\u0105 podczas dialogu.

"},{"location":"pl/zengin/scripts/extenders/lego/applications/trialoge/#zale\u017cno\u015bci","title":"Zale\u017cno\u015bci","text":"
  • AI_Function
"},{"location":"pl/zengin/scripts/extenders/lego/applications/trialoge/#inicjalizacja","title":"Inicjalizacja","text":"

Zainicjuj za pomoc\u0105 flagi LeGo_Trialoge.

LeGo_Init(LeGo_Trialoge);\n
"},{"location":"pl/zengin/scripts/extenders/lego/applications/trialoge/#implementacja","title":"Implementacja","text":"

Trialoge.d na GitHubie

"},{"location":"pl/zengin/scripts/extenders/lego/applications/trialoge/#funkcje","title":"Funkcje","text":""},{"location":"pl/zengin/scripts/extenders/lego/applications/trialoge/#equipweapon","title":"EquipWeapon","text":"

Funkcja Sektenspinnera. Sprawia, \u017ce NPC wyposa\u017ca bro\u0144.

func void EquipWeapon(var C_NPC slf, var int ItemInstance)\n
Parametry
  • var C_NPC slf NPC kt\u00f3ry wyposa\u017ca bro\u0144
  • var int ItemInstance Instancja broni do wyposa\u017cenia

Konfiguracja

const int EquipWeapon_TogglesEquip = 1

Powy\u017csza sta\u0142a ustala zachowanie funkcji podczas pr\u00f3by za\u0142o\u017cenia ju\u017c za\u0142o\u017conej broni:

  • 0 - EquipWeapon nic nie zrobi
  • 1 - EquipWeapon zdejmie t\u0105 bro\u0144
"},{"location":"pl/zengin/scripts/extenders/lego/applications/trialoge/#npc_getarmor","title":"Npc_GetArmor","text":"

Pobiera pancerz wyposa\u017cony przez NPC.

func int Npc_GetArmor(var C_NPC slf)\n
Parametry
  • var C_NPC slf NPC kt\u00f3rego pancerz jest pobierany

Zwracana warto\u015b\u0107

Funkcja zwraca ID instancji pancerza za\u0142o\u017conego przez NPC.

"},{"location":"pl/zengin/scripts/extenders/lego/applications/trialoge/#npc_getmeleeweapon","title":"Npc_GetMeleeWeapon","text":"

Pobiera wyposa\u017con\u0105 przez NPC bro\u0144 bia\u0142\u0105.

func int Npc_GetMeleeWeapon(var C_NPC slf)\n
Parametry
  • var C_NPC slf NPC kt\u00f3rego bro\u0144 jest pobierana

Zwracana warto\u015b\u0107

Funkcja zwraca ID instancji broni bia\u0142ej wyposa\u017conej przez NPC.

"},{"location":"pl/zengin/scripts/extenders/lego/applications/trialoge/#npc_getrangedweapon","title":"Npc_GetRangedWeapon","text":"

Pobiera wyposa\u017con\u0105 przez NPC bro\u0144 dystansow\u0105.

func int Npc_GetRangedWeapon(var C_NPC slf)\n
Parametry
  • var C_NPC slf NPC kt\u00f3rego bro\u0144 jest pobierana

Zwracana warto\u015b\u0107

Funkcja zwraca ID instancji broni dystansowej wyposa\u017conej przez NPC.

"},{"location":"pl/zengin/scripts/extenders/lego/applications/trialoge/#npc_tradeitem","title":"Npc_TradeItem","text":"

Podmienia bro\u0144 za\u0142o\u017con\u0105 przez NPC.

func void Npc_TradeItem(var c_npc slf, var int itm0, var int itm1) \n
Parametry
  • var C_NPC slf NPC na kt\u00f3rym wykonywana jest operacja
  • var int itm0 ID instancji przedmiotu do usuni\u0119cia
  • var int itm1 ID instancji przedmiotu do stworzenia i za\u0142o\u017cenia
"},{"location":"pl/zengin/scripts/extenders/lego/applications/trialoge/#diacam_update","title":"DiaCAM_Update","text":"

Funkcja Sektenspinnera. Aktualizuje kamer\u0119 dialogow\u0105. (U\u017cywana wewn\u0119trznie)

func void DiaCAM_Update()\n
"},{"location":"pl/zengin/scripts/extenders/lego/applications/trialoge/#diacam_disable","title":"DiaCAM_Disable","text":"

Ca\u0142kowicie wy\u0142\u0105cza kamery dialogowe.

func void DiaCAM_Disable()\n
"},{"location":"pl/zengin/scripts/extenders/lego/applications/trialoge/#diacam_enable","title":"DiaCAM_Enable","text":"

Resetuje kamery dialogowe do ustawie\u0144 domy\u015blnych.

func void DiaCAM_Enable()\n
"},{"location":"pl/zengin/scripts/extenders/lego/applications/trialoge/#tria_wait","title":"TRIA_Wait","text":"

Sprawia \u017ce self i other czekaj\u0105 na siebie, np. podczas dla synchronizacji po wywo\u0142aniu AI_GotoWP.

func void TRIA_Wait()\n
"},{"location":"pl/zengin/scripts/extenders/lego/applications/trialoge/#tria_invite","title":"TRIA_Invite","text":"

Zaprasza NPC do rozmowy. Nale\u017cy wywo\u0142a\u0107 przed TRIA_Start.TRIA_Start.

func void TRIA_Invite(var C_NPC slf)\n
Parametry
  • var C_NPC slf Zapraszany NPC
"},{"location":"pl/zengin/scripts/extenders/lego/applications/trialoge/#tria_start","title":"TRIA_Start","text":"

Rozpoczyna trialog. Wcze\u015bniej wszyscy NPC powinni zosta\u0107 zaproszeni przez TRIA_Invite.

func void TRIA_Start()\n
"},{"location":"pl/zengin/scripts/extenders/lego/applications/trialoge/#tria_barrier","title":"TRIA_Barrier","text":"

Robi to samo co TRIA_Wait, ale dotyczy wszystkich uczestnicz\u0105cych NPC.

func void TRIA_Barrier()\n
"},{"location":"pl/zengin/scripts/extenders/lego/applications/trialoge/#tria_next","title":"TRIA_Next","text":"

Ustawia podanego NPC na self.

func void TRIA_Next(var C_NPC n0)\n
Parametry
  • var C_NPC n0 NPC ustawiany na self
"},{"location":"pl/zengin/scripts/extenders/lego/applications/trialoge/#tria_cam","title":"TRIA_Cam","text":"

Rozpoczyna zdefiniowany wcze\u015bniej ruch kamery.

func void TRIA_Cam(var string evt)\n
Parametry
  • var string evt Nazwa ruchu kamery w Spacerze. Je\u015bli zostanie przekazany pusty ci\u0105g znak\u00f3w, nast\u0105pi przerwanie ruchu kamery.
"},{"location":"pl/zengin/scripts/extenders/lego/applications/trialoge/#tria_finish","title":"TRIA_Finish","text":"

Ko\u0144czy trwaj\u0105cy trialog. Musi by\u0107 zawsze wywo\u0142ywana na ko\u0144cu, w przeciwnym razie dalsze trialogi nie b\u0119d\u0105 mog\u0142y zosta\u0107 rozpocz\u0119te.

func void TRIA_Finish()\n
"},{"location":"pl/zengin/scripts/extenders/lego/applications/trialoge/#przyk\u0142ady","title":"Przyk\u0142ady","text":""},{"location":"pl/zengin/scripts/extenders/lego/applications/trialoge/#prosty-trialog","title":"Prosty Trialog","text":"

Poni\u017csza konwersacja zostanie zaimplementowana za pomoc\u0105 trialog\u00f3w:

  1. Arto: Wybacz bohaterze, ale nie mo\u017cesz t\u0119dy przej\u015b\u0107.
  2. Bohater: Dlaczego nie?
  3. Horka: Miasto zosta\u0142o zamkni\u0119te.
  4. Bohater: Mam troch\u0119 z\u0142ota przy sobie, mo\u017cemy pohandlowa\u0107?
  5. Squelto: Nie. Nie jeste\u015bmy otwarci na przekupstwo.
  6. Bohater: Na pewno?
  7. Arto: Musz\u0119 prosi\u0107, aby\u015b teraz odszed\u0142.
  8. Bohater: Niech b\u0119dzie...
    instance TRIA_Test (C_INFO)\n{\n    npc         = PAL_100_Friend;\n    nr          = 10;\n    condition   = TRIA_Test_condition;\n    information = TRIA_Test_info;\n    important   = FALSE;\n    permanent   = 1;\n    description = \"TRIALOGTEST\";\n};\n\nfunc int TRIA_Test_condition()\n{\n    return TRUE;\n};\n\nfunc void TRIA_Test_info()\n{\n    var C_NPC Arto;       Arto = Hlp_GetNpc(PAL_100_Friend); // On jest w\u0142a\u015bcicielem dialogu\n    var C_NPC Horka;     Horka = Hlp_GetNpc(PAL_101_Horka);\n    var C_NPC Squelto; Squelto = Hlp_GetNpc(PAL_102_Squelto);\n\n    TRIA_Invite(Horka);   // Zapro\u015b Horka do dialogu\n    TRIA_Invite(Squelto); // Zapro\u015b Squelto do dialogu\n    TRIA_Start();         // Rozpocznij rozmow\u0119\n    // Bohater i Arto nie musz\u0105 by\u0107 zaproszeni. Domy\u015blnie nale\u017c\u0105 do dialogu.\n\n    // Bohater m\u00f3wi do Arto (self = Arto, other = Hero)\n    TRIA_Next(Arto);\n\n    DIAG_Reset();\n\n    AI_Output (self, other, \"TRIA_TEST_00\"); //Wybacz bohaterze, ale nie mo\u017cesz t\u0119dy przej\u015b\u0107.\n\n    // Bohater m\u00f3wi teraz do Horka (self = Horka, other = Hero)\n    TRIA_Next(Horka);\n\n    AI_Output (other, self, \"TRIA_TEST_01\"); //Dlaczego nie?\n\n    AI_GotoNpc(self, other);\n    AI_TurnToNpc(other, self);\n\n    AI_Output (self, other, \"TRIA_TEST_02\"); //Miasto zosta\u0142o zamkni\u0119te.\n\n    // Bohater rozgl\u0105da si\u0119 woko\u0142o w trakcie nast\u0119pnej sceny\n    DIAG(\"Nervous\", 1, 2);\n\n    AI_Output (other, self, \"TRIA_TEST_03\"); //Mam troch\u0119 z\u0142ota przy sobie, mo\u017cemy pohandlowa\u0107?\n\n    // Bohater powinien rusza\u0107 si\u0119 teraz znowu normalnie\n    DIAG_Reset();\n\n    // Rozpocznij ruch kamery\n    TRIA_Cam(\"CAMERASTART\");\n\n    // Bohater m\u00f3wi teraz do Squelto (self = Squelto, other = Hero)\n    TRIA_Next(Squelto);\n\n    AI_TurnToNpc(other, self);\n\n    DIAG(\"No\", 0, 1);\n    AI_Output (self, other, \"TRIA_TEST_04\"); //Nie. Nie jeste\u015bmy otwarci na przekupstwo.\n\n    // Bohater m\u00f3wi ponowni do Arto (self = Arto, other = Hero)\n    TRIA_Next(Arto);\n\n    // Bohater powinien teraz pytaj\u0105co gestykulowa\u0107\n    DIAG(\"NotSure\", 0, 1);\n\n    AI_Output(other, self, \"TRIA_TEST_05\"); //Na pewno?\n\n    AI_TurnToNpc(other, self);\n\n    // Zako\u0144cz ruch kamery\n    TRIA_Cam(\"\");\n\n    // Arto powinien zareagowa\u0107 w\u015bciekle\n    DIAG(\"Angry\", 0, 4);\n\n    AI_Output (self, other, \"TRIA_TEST_06\"); //Musz\u0119 prosi\u0107, aby\u015b teraz odszed\u0142.\n\n    // Bohater powinien ponownie porusza\u0107 si\u0119 normalnie\n    DIAG_Reset();\n\n    AI_Output (other, self, \"TRIA_TEST_07\"); //Niech b\u0119dzie...\n\n    TRIA_Finish(); // Koniec\n};\n

Note

Dodatkowo w powy\u017cszym przyk\u0142adzie u\u017cyty jest te\u017c pakiet Dialoggestures.

"},{"location":"pl/zengin/scripts/extenders/lego/tools/ai_function/","title":"AI_Function - Funkcje AI","text":""},{"location":"pl/zengin/scripts/extenders/lego/tools/ai_function/#ai_function---funkcje-ai","title":"AI_Function - Funkcje AI","text":"

Ten pakiet umo\u017cliwia wywo\u0142ywanie funkcji op\u00f3\u017anionych w czasie poprzez kolejkowanie ich w kolejce AI danego NPC. Mo\u017ce to by\u0107 bardzo przydatne przy pisaniu przerywnik\u00f3w filmowych na silniku lub implementacji nowych rutyn.

"},{"location":"pl/zengin/scripts/extenders/lego/tools/ai_function/#zale\u017cno\u015bci","title":"Zale\u017cno\u015bci","text":"
  • HookEngine
"},{"location":"pl/zengin/scripts/extenders/lego/tools/ai_function/#inicjalizacja","title":"Inicjalizacja","text":"

Zainicjuj za pomoc\u0105 flagi LeGo_AI_Function.

LeGo_Init(LeGo_AI_Function);\n
"},{"location":"pl/zengin/scripts/extenders/lego/tools/ai_function/#implementacja","title":"Implementacja","text":"

AI_Function.d na GitHubie

"},{"location":"pl/zengin/scripts/extenders/lego/tools/ai_function/#funkcje","title":"Funkcje","text":"

Funkcja function jest wywo\u0142ywana z op\u00f3\u017anieniem: do\u0142\u0105cza do kolejki AI slf.

func void AI_Function(var C_NPC slf, var func function)\n
Parametry
  • var C_NPC slf NPC, do kt\u00f3rego kolejki AI do\u0142\u0105cza funkcja
  • var func function Funkcja wywo\u0142ywana z op\u00f3\u017anieniem

Dodatkowo istniej\u0105 pewne przeci\u0105\u017cenia AI_Function, kt\u00f3re pozwalaj\u0105 na wywo\u0142ywanie funkcji z parametrami.

func void AI_Function_I  (var C_NPC slf, var func function, var int    param) {}; // Int\nfunc void AI_Function_N  (var C_NPC slf, var func function, var int    param) {}; // Instance (e.g. NPC)\nfunc void AI_Function_S  (var C_NPC slf, var func function, var string param) {}; // String\nfunc void AI_Function_II (var C_NPC slf, var func function, var int    param1, var int    param2) {}; // Int, Int\nfunc void AI_Function_NN (var C_NPC slf, var func function, var int    param1, var int    param2) {}; // Instance, Instance\nfunc void AI_Function_SS (var C_NPC slf, var func function, var string param1, var string param2) {}; // String, String\nfunc void AI_Function_IS (var C_NPC slf, var func function, var int    param1, var string param2) {}; // Int, String\nfunc void AI_Function_SI (var C_NPC slf, var func function, var string param1, var int    param2) {}; // String, Int\nfunc void AI_Function_NS (var C_NPC slf, var func function, var int    param1, var string param2) {}; // Instance, String\nfunc void AI_Function_SN (var C_NPC slf, var func function, var string param1, var int    param2) {}; // String, Instance\nfunc void AI_Function_IN (var C_NPC slf, var func function, var int    param1, var int    param2) {}; // Int, Instance\nfunc void AI_Function_NI (var C_NPC slf, var func function, var int    param1, var int    param2) {}; // Instance, Int\n
Nie mo\u017cna wywo\u0142ywa\u0107 funkcji z wi\u0119cej ni\u017c dwoma parametrami, ale parametry mo\u017cna przekazywa\u0107 po\u015brednio przez zmienne globalne.

W wywo\u0142anej funkcji dost\u0119p do self mo\u017cna uzyska\u0107 w nast\u0119puj\u0105cy spos\u00f3b:

var oCNpc slf; slf = _^(ECX);\n

Info

Od LeGo 2.7.2 globalna instancja self jest dostarczana poprawnie i mo\u017ce by\u0107 u\u017cywana bezpo\u015brednio.

"},{"location":"pl/zengin/scripts/extenders/lego/tools/ai_function/#przyk\u0142ady","title":"Przyk\u0142ady","text":""},{"location":"pl/zengin/scripts/extenders/lego/tools/ai_function/#kolejkowanie-prostej-funkcji","title":"Kolejkowanie prostej funkcji","text":"

Zanim funkcja zostanie wywo\u0142ana, ka\u017cdy NPC powinien najpierw zako\u0144czy\u0107 swoj\u0105 kolejk\u0119 AI.

Tutaj bohater ma biec do Waypointu i dopiero po dotarciu na miejsce ma rozpocz\u0105\u0107 si\u0119 ruch kamery.

func void Example1() {\n    Npc_ClearAIQueue(hero);\n    AI_GotoWP(hero, \"MYWAYPOINT\");\n\n    AI_Function_S(hero, Wld_SendTrigger, \"CAMERASTART\");\n};\n
Gdy tylko bohater dotrze do Waypointu, wywo\u0142ywane jest Wld_SendTrigger(\"CAMERASTART\");."},{"location":"pl/zengin/scripts/extenders/lego/tools/binary_machines/#binarymachines","title":"BinaryMachines","text":"

Ten pakiet pozwala tworzy\u0107 i zapisywa\u0107 w\u0142asne pliki w dowolnym miejscu w systemie plik\u00f3w.

"},{"location":"pl/zengin/scripts/extenders/lego/tools/binary_machines/#zale\u017cno\u015bci","title":"Zale\u017cno\u015bci","text":"

Brak

"},{"location":"pl/zengin/scripts/extenders/lego/tools/binary_machines/#inicjalizacja","title":"Inicjalizacja","text":"

Brak

"},{"location":"pl/zengin/scripts/extenders/lego/tools/binary_machines/#implementacja","title":"Implementacja","text":"

BinaryMachines.d na GitHub

"},{"location":"pl/zengin/scripts/extenders/lego/tools/binary_machines/#bw_newfile","title":"BW_NewFile","text":"

Tworzy plik o nazwie file i otwiera strumie\u0144. Nie dzia\u0142a, je\u015bli strumie\u0144 jest ju\u017c otwarty.

func int BW_NewFile(var string file)\n
Parametry
  • var string file Nazwa tworzonego pliku

Zwracana warto\u015b\u0107

Funkcja zwraca TRUE je\u015bli plik zosta\u0142 pomy\u015blnie utworzony i zainicjalizowany, w przeciwnym razie zwracane jest FALSE.

"},{"location":"pl/zengin/scripts/extenders/lego/tools/binary_machines/#bw_close","title":"BW_Close","text":"

Zamyka aktualny strumie\u0144 zapisu.

func void BW_Close()\n
"},{"location":"pl/zengin/scripts/extenders/lego/tools/binary_machines/#bw","title":"BW","text":"

Zapisuje length bajt\u00f3w z data do strumienia, maksymalnie 4 bajty.

func void BW(var int data, var int length)\n
Parametry
  • var int data Warto\u015b\u0107 bajt\u00f3w
  • var int length Liczba bajt\u00f3w
"},{"location":"pl/zengin/scripts/extenders/lego/tools/binary_machines/#bw_int","title":"BW_Int","text":"

Zapisuje 4 bajty z data do strumienia. To samo co BW(data, 4).

func void BW_Int(var int data)\n
Parametry
  • var int data Warto\u015b\u0107 ca\u0142kowita do zapisania
"},{"location":"pl/zengin/scripts/extenders/lego/tools/binary_machines/#bw_char","title":"BW_Char","text":"

Zapisuje pierwszy znak z data do strumienia. To samo co BW(Str_GetCharAt(data, 0), 1).

func void BW_Char(var string data)\n
Parametry
  • var string data Znak do zapisania
"},{"location":"pl/zengin/scripts/extenders/lego/tools/binary_machines/#bw_string","title":"BW_String","text":"

Zapisuje data zako\u0144czone znakiem \\0 do strumienia.

func void BW_String(var string data)\n
Parametry
  • var string data Ci\u0105g znak\u00f3w do zapisania
"},{"location":"pl/zengin/scripts/extenders/lego/tools/binary_machines/#bw_byte","title":"BW_Byte","text":"

Zapisuje bajt z data do strumienia. To samo co BW(data, 1).

func void BW_Byte(var int data)\n
Parametry
  • var int data Warto\u015b\u0107 bajtowa do zapisania
"},{"location":"pl/zengin/scripts/extenders/lego/tools/binary_machines/#bw_bytes","title":"BW_Bytes","text":"

Zapisuje length bajt\u00f3w ze wska\u017anika dataPtr do strumienia.

func void BW_Bytes(var int dataPtr, var int length)\n
Parametry
  • var int dataPtr Wska\u017anik danych do zapisania
  • var int length Liczba bajt\u00f3w
"},{"location":"pl/zengin/scripts/extenders/lego/tools/binary_machines/#bw_text","title":"BW_Text","text":"

Zapisuje ci\u0105g znak\u00f3w do strumienia bez jego zako\u0144czenia. Nie mo\u017cna go ju\u017c odczyta\u0107.

func void BW_Text(var string data)\n
Parametry
  • var string data Tekst do zapisania
"},{"location":"pl/zengin/scripts/extenders/lego/tools/binary_machines/#bw_nextline","title":"BW_NextLine","text":"

Zapisuje akapit do strumienia.

func void BW_NextLine()\n
"},{"location":"pl/zengin/scripts/extenders/lego/tools/binary_machines/#br_openfile","title":"BR_OpenFile","text":"

Otwiera plik o nazwie file i otwiera strumie\u0144. Nie dzia\u0142a, je\u015bli strumie\u0144 jest ju\u017c otwarty.

func int BR_OpenFile(var string file)\n
Parametry
  • var string file Plik, kt\u00f3ry ma by\u0107 otwarty

Zwracana warto\u015b\u0107

Funkcja zwraca TRUE je\u015bli plik zosta\u0142 pomy\u015blnie otworzony i zainicjalizowany, w przeciwnym razie zwracane jest FALSE.

"},{"location":"pl/zengin/scripts/extenders/lego/tools/binary_machines/#br_close","title":"BR_Close","text":"

Zamyka aktualny strumie\u0144 odczytu.

func void BR_Close()\n
"},{"location":"pl/zengin/scripts/extenders/lego/tools/binary_machines/#br","title":"BR","text":"

Odczytuje bajty ze strumienia.

func int BR(var int length)\n
Parametry
  • var int length Liczba bajt\u00f3w do odczytania (maksymalnie 4)

Zwracana warto\u015b\u0107

Funkcja zwraca odczytan\u0105 warto\u015b\u0107 bajt\u00f3w.

"},{"location":"pl/zengin/scripts/extenders/lego/tools/binary_machines/#br_int","title":"BR_Int","text":"

Odczytuje 4 bajty ze strumienia. To samo co BR(4).

func int BR_Int()\n
Zwracana warto\u015b\u0107

Funkcja zwraca odczytan\u0105 liczb\u0119 ca\u0142kowit\u0105.

"},{"location":"pl/zengin/scripts/extenders/lego/tools/binary_machines/#br_char","title":"BR_Char","text":"

Odczytuje znak ze strumienia. To samo co BR(1).

func string BR_Char()\n
Zwracana warto\u015b\u0107

Funkcja zwraca odczytany znak jako string.

"},{"location":"pl/zengin/scripts/extenders/lego/tools/binary_machines/#br_string","title":"BR_String","text":"

Odczytuje ci\u0105g znak\u00f3w zako\u0144czony znakiem \\0 ze strumienia.

func string BR_String()\n
Zwracana warto\u015b\u0107

Funkcja zwraca odczytany ci\u0105g znak\u00f3w.

"},{"location":"pl/zengin/scripts/extenders/lego/tools/binary_machines/#br_byte","title":"BR_Byte","text":"

Odczytuje bajt ze strumienia.

func int BR_Byte()\n
Zwracana warto\u015b\u0107

Funkcja zwraca odczytany bajt.

"},{"location":"pl/zengin/scripts/extenders/lego/tools/binary_machines/#br_bytes","title":"BR_Bytes","text":"

Odczytuje bajty ze strumienia.

func int BR_Bytes(var int length)\n
Parametry
  • var int length Liczba bajt\u00f3w do odczytania

Zwracana warto\u015b\u0107

Funkcja zwraca wska\u017anik do odczytanych bajt\u00f3w.

"},{"location":"pl/zengin/scripts/extenders/lego/tools/binary_machines/#br_textline","title":"BR_TextLine","text":"

Odczytuje lini\u0119 ze strumienia.

func string BR_TextLine()\n
Zwracana warto\u015b\u0107

Funkcja zwraca odczytan\u0105 lini\u0119.

"},{"location":"pl/zengin/scripts/extenders/lego/tools/binary_machines/#br_text","title":"BR_Text","text":"

Odczytuje ci\u0105g znak\u00f3w o podanej d\u0142ugo\u015bci ze strumienia.

func string BR_Text(var int length)\n
Parametry
  • var int length Liczba znak\u00f3w do odczytania

Zwracana warto\u015b\u0107

Funkcja zwraca odczytany ci\u0105g znak\u00f3w.

"},{"location":"pl/zengin/scripts/extenders/lego/tools/binary_machines/#br_nextline","title":"BR_NextLine","text":"

Zmienia pozycj\u0119 odczytu na nast\u0119pny akapit, utworzony za pomoc\u0105 BW_NextLine.

func void BR_NextLine()\n
"},{"location":"pl/zengin/scripts/extenders/lego/tools/binary_machines/#wywo\u0142ania-funkcji-silnika","title":"Wywo\u0142ania funkcji silnika","text":""},{"location":"pl/zengin/scripts/extenders/lego/tools/binary_machines/#win_getlasterror","title":"WIN_GetLastError","text":"

Wywo\u0142anie funkcji GetLastError z Win32 API.

func int WIN_GetLastError()\n
Zwracana warto\u015b\u0107

Funkcja zwraca kod ostatniego b\u0142\u0119du w\u0105tku wywo\u0142uj\u0105cego.

"},{"location":"pl/zengin/scripts/extenders/lego/tools/binary_machines/#win_createfile","title":"WIN_CreateFile","text":"

Wywo\u0142anie funkcji CreateFileA z Win32 API.

func int WIN_CreateFile(var string lpFileName,var int dwDesiredAccess,var int dwShareMode,var int lpSecurityAttributes,var int dwCreationDisposition,var int dwFlagsAndAttributes,var int hTemplateFile)\n
Parametry

Pe\u0142ny opis parametr\u00f3w mo\u017cna znale\u017a\u0107 tutaj

Zwracana warto\u015b\u0107

Informacje o zwracanej warto\u015bci znajdziesz tutaj

"},{"location":"pl/zengin/scripts/extenders/lego/tools/binary_machines/#win_writefile","title":"WIN_WriteFile","text":"

Wywo\u0142anie funkcji WriteFile z Win32 API.

func void WIN_WriteFile(var int hFile,var int lpBuffer,var int nNumberOfBytesToWrite,var int lpNumberOfBytesWritten,var int lpOverlapped)\n
Parametry

Pe\u0142ny opis parametr\u00f3w mo\u017cna znale\u017a\u0107 tutaj

"},{"location":"pl/zengin/scripts/extenders/lego/tools/binary_machines/#win_readfile","title":"WIN_ReadFile","text":"

Wywo\u0142anie funkcji ReadFile z Win32 API.

func void WIN_ReadFile(var int hFile,var int lpBuffer,var int nNumberOfBytesToRead,var int lpNumberOfBytesRead,var int lpOverlapped)\n
Parametry

Pe\u0142ny opis parametr\u00f3w mo\u017cna znale\u017a\u0107 tutaj

"},{"location":"pl/zengin/scripts/extenders/lego/tools/binary_machines/#win_closehandle","title":"WIN_CloseHandle","text":"

Wywo\u0142anie funkcji CloseHandle z Win32 API.

func void WIN_CloseHandle(var int hObject)\n
Parametry

Pe\u0142ny opis parametr\u00f3w mo\u017cna znale\u017a\u0107 tutaj

"},{"location":"pl/zengin/scripts/extenders/lego/tools/binary_machines/#win_getfilesize","title":"WIN_GetFileSize","text":"

Wywo\u0142anie funkcji GetFileSize z Win32 API.

func int WIN_GetFileSize(var int hFile,var int lpFileSizeHigh)\n
Parametry

Pe\u0142ny opis parametr\u00f3w mo\u017cna znale\u017a\u0107 tutaj

Zwracana warto\u015b\u0107

Informacje o zwracanej warto\u015bci znajdziesz tutaj

"},{"location":"pl/zengin/scripts/extenders/lego/tools/binary_machines/#constants","title":"Constants","text":"

Dodatkowo istniej\u0105 pewne sta\u0142e zdefiniowane do u\u017cycia z okre\u015blonymi wywo\u0142aniami funkcji silnika.

const int CREATE_ALWAYS = 2;\nconst int OPEN_EXISTING = 3;\nconst int GENERIC_ALL = 1073741824;\nconst int GENERIC_READ = -2147483648;\nconst int FILE_SHARE_READ = 1;\nconst int FILE_SHARE_WRITE = 2;\nconst int FILE_SHARE_DELETE = 4;\nconst int FILE_ATTRIBUTE_NORMAL = 128;\n
"},{"location":"pl/zengin/scripts/extenders/lego/tools/binary_machines/#przyk\u0142ady","title":"Przyk\u0142ady","text":""},{"location":"pl/zengin/scripts/extenders/lego/tools/binary_machines/#zapisywanie-i-wczytywanie-zmiennych","title":"Zapisywanie i wczytywanie zmiennych","text":"
const string filename = \"System\\MySave.sav\";\n\nvar string s0; // ci\u0105g znak\u00f3w\nvar int    i1; // liczba ca\u0142kowita\nvar int    b2; // bajt\nvar string c3; // znak\n\nfunc void SaveMyData()\n\n\n{\n    if(BW_NewFile(filename))  // Utw\u00f3rz nowy plik:\n    { \n        BW_String(s0);\n        BW_Int(i1);\n        BW_Byte(b2);\n        BW_Char(c3);          // Zapisz dane...\n        BW_Close();           // ...i zamknij.\n    };\n};\n\nfunc void LoadMyData() {\n    if(BR_OpenFile(filename)) // Spr\u00f3buj otworzy\u0107 plik:\n    { \n        s0 = BR_String();\n        i1 = BR_Int();\n        b2 = BR_Byte();\n        c3 = BR_Char();       // Odczytaj warto\u015bci...\n        BR_Close();           // ...i zamknij.\n    }\n    else \n    {\n        SaveMyData();         // W przeciwnym razie utw\u00f3rz plik z zapisem.\n    };\n};\n
"},{"location":"pl/zengin/scripts/extenders/lego/tools/binary_machines/#gratulacje-dla-gracza","title":"Gratulacje dla gracza","text":"
func void Certificate(var string Username, var int Score) \n{\n    var string filename; filename = ConcatStrings(Username, \"'s Certificate.txt\");\n    BW_NewFile(filename); // Nazwa u\u017cytkownika + \"s Certificate.txt\". Plik jest w katalogu Gothic.\n    BW_Text(\"Gratulacje \"); BW_Text(Username);\n    BW_TextLine(\"!\");\n\n    BW_Text(\"Zdoby\u0142e\u015b \");\n    BW_Text(IntToString(Score)); // Nie BW_Int!\n    BW_TextLine(\" punkt\u00f3w w tej grze.\");\n\n    BW_NextLine();\n\n    BW_Text(\"Z wyrazami szacunku, Autor\");\n    BW_Close();\n\n    /*\n       Przy wywo\u0142aniu:  Certificate(\"Player\", 1000);\n       zostanie utworzony plik o nazwie 'Player's Certificate.txt', kt\u00f3ry zawiera\u0107 b\u0119dzie:\n\n        Gratulacje NazwaGracza!\n        Zdoby\u0142e\u015b 1000 punkt\u00f3w w tej grze.\n\n        Z wyrazami szacunku, Autor\n    */\n};\n
"},{"location":"pl/zengin/scripts/extenders/lego/tools/binary_machines/#po\u0142o\u017cenie-postaci-npc","title":"Po\u0142o\u017cenie postaci NPC","text":"
func void BW_NpcPosition(var C_NPC slf) \n{\n    var int ptr; ptr = MEM_Alloc(60);                // 16 * 4\n    MEM_CopyBytes(MEM_InstToPtr(slf) + 60, ptr, 60); // Skopiuj slf.trafoObjToWorld\n    BW_Bytes(ptr, 60);                               // Zapisz skopiowane 60 bajt\u00f3w\n    MEM_Free(ptr);                                   // I posprz\u0105taj...\n};\n\nfunc void BR_NpcPosition(var C_NPC slf) \n{\n    var int ptr; ptr = BR_Bytes(60);                 // Odczytaj 60 bajt\u00f3w\n    MEM_CopyBytes(ptr, MEM_InstToPtr(slf) + 60, 60); // Wklej z powrotem do slf\n    MEM_Free(ptr);                                   // I posprz\u0105taj ponownie...\n};\n\n/*\n   U\u017cycie standardowe:\n     BW_NewFile(file);\n     BW_NpcPosition(hero);\n     BW_Close();\n*/\n

Uwaga

Przyk\u0142ady zosta\u0142y pierwotnie napisane przez Gottfrieda i opublikowane na forum World of Gothic.

`

"},{"location":"pl/zengin/scripts/extenders/lego/tools/item_helper/","title":"ItemHelper - pomocnik do przedmiot\u00f3w","text":""},{"location":"pl/zengin/scripts/extenders/lego/tools/item_helper/#itemhelper---pomocnik-do-przedmiot\u00f3w","title":"ItemHelper - pomocnik do przedmiot\u00f3w","text":"

Ten pakiet jest bardzo prosty - pobiera wska\u017anik oCItem z instancji C_ITEM wa\u017cnej dla bie\u017c\u0105cego \u015bwiata i sesji.

Warning

Upewnij si\u0119, \u017ce ka\u017cdy \u015bwiat ma waypoint o nazwie TOT (po niemiecku \"martwy\"). Ikarus i LeGo potrzebuj\u0105 tego punktu nawigacyjnego, aby odradza\u0107 pomocniczych NPC. Jest to szczeg\u00f3lnie wa\u017cne w Gothicu 1, poniewa\u017c jego \u015bwiaty nie maj\u0105 waypointu TOT.

"},{"location":"pl/zengin/scripts/extenders/lego/tools/item_helper/#zale\u017cno\u015bci","title":"Zale\u017cno\u015bci","text":"

Nie dotyczy.

"},{"location":"pl/zengin/scripts/extenders/lego/tools/item_helper/#inicjalizacja","title":"Inicjalizacja","text":"

Nie dotyczy.

"},{"location":"pl/zengin/scripts/extenders/lego/tools/item_helper/#implementacja","title":"Implementacja","text":"

ItemHelper.d na GitHubie

"},{"location":"pl/zengin/scripts/extenders/lego/tools/item_helper/#funkcje","title":"Funkcje","text":""},{"location":"pl/zengin/scripts/extenders/lego/tools/item_helper/#itm_getptr","title":"Itm_GetPtr","text":"
func int Itm_GetPtr(var int instance)\n
Parametry
  • var int instance Instancja C_ITEM, z kt\u00f3rej ma zosta\u0107 pobrany wska\u017anik

Zwracana warto\u015b\u0107

Funkcja zwraca wska\u017anik oCItem instancji C_ITEM.

"},{"location":"pl/zengin/scripts/extenders/lego/tools/misc/","title":"Misc - r\u00f3\u017cne","text":""},{"location":"pl/zengin/scripts/extenders/lego/tools/misc/#misc---r\u00f3\u017cne","title":"Misc - r\u00f3\u017cne","text":"

Pakiet Misc wprowadza r\u00f3\u017cne funkcje pomocnicze, kt\u00f3re nie pasowa\u0142y do \u017cadnego innego pakietu.

"},{"location":"pl/zengin/scripts/extenders/lego/tools/misc/#zale\u017cno\u015bci","title":"Zale\u017cno\u015bci","text":"

Nie dotyczy.

"},{"location":"pl/zengin/scripts/extenders/lego/tools/misc/#inicjalizacja","title":"Inicjalizacja","text":"

Nie dotyczy.

"},{"location":"pl/zengin/scripts/extenders/lego/tools/misc/#implementacja","title":"Implementacja","text":"

Misc.d na GitHubie

"},{"location":"pl/zengin/scripts/extenders/lego/tools/misc/#sta\u0142e","title":"Sta\u0142e","text":"

Pakiet Misc implementuje sat\u0142\u0105 phi

const int phi = 1070141312; // PI/2\n
kt\u00f3ra w rzeczywisto\u015bci jest liczb\u0105 pi podzielon\u0105 przez 2 zapisan\u0105 jako ikarusowy float.

Decymalnie: 1.5707...

"},{"location":"pl/zengin/scripts/extenders/lego/tools/misc/#funkcje","title":"Funkcje","text":""},{"location":"pl/zengin/scripts/extenders/lego/tools/misc/#atan2f","title":"atan2f","text":"

Oblicza arcus tangens k\u0105ta mi\u0119dzy pocz\u0105tkiem a punktem (x, y).

func int atan2f(var int x, var int y)\n
Parametry
  • var int x Wsp\u00f3\u0142rz\u0119dna x
  • var int y Wsp\u00f3\u0142rz\u0119dna y

Zwracana warto\u015b\u0107

Funkcja zwraca arcus tangens w radianach, jako ikarusowy float.

"},{"location":"pl/zengin/scripts/extenders/lego/tools/misc/#sin","title":"sin","text":"

Oblicza sinus k\u0105ta podanego w radianach.

func int sin(var int angle)\n
Parametry
  • var int angle K\u0105t w radianach jako ikarusowy float

Zwracana warto\u015b\u0107

Funkcja zwraca sinus k\u0105ta, jako ikarusowy float.

"},{"location":"pl/zengin/scripts/extenders/lego/tools/misc/#cos","title":"cos","text":"

Oblicza cosinus k\u0105ta podanego w radianach.

func int cos(var int angle)\n
Parametry
  • var int angle K\u0105t w radianach jako ikarusowy float

Zwracana warto\u015b\u0107

Funkcja zwraca cosinus k\u0105ta, jako ikarusowy float.

"},{"location":"pl/zengin/scripts/extenders/lego/tools/misc/#tan","title":"tan","text":"

Oblicza tangens k\u0105ta podanego w radianach.

func int tan(var int angle)\n
Parametry
  • var int angle K\u0105t w radianach jako ikarusowy float

Zwracana warto\u015b\u0107

Funkcja zwraca tangens k\u0105ta, jako ikarusowy float.

"},{"location":"pl/zengin/scripts/extenders/lego/tools/misc/#asin","title":"asin","text":"

Oblicza arcus sinus

func int asin(var int sine)\n
Parametry
  • var int sine Sinus k\u0105ta jako ikarusowy float

Zwracana warto\u015b\u0107

Funkcja zwraca arcus sinus k\u0105ta, jako ikarusowy float.

"},{"location":"pl/zengin/scripts/extenders/lego/tools/misc/#acos","title":"acos","text":"

Oblicza arcus cosinus

func int acos(var int cosine)\n
Parametry
  • var int cosine Cosinus k\u0105ta jako ikarusowy float

Zwracana warto\u015b\u0107

Funkcja zwraca arcus cosinus k\u0105ta, jako ikarusowy float.

"},{"location":"pl/zengin/scripts/extenders/lego/tools/misc/#distance2d","title":"distance2D","text":"

Oblicza odleg\u0142o\u015b\u0107 mi\u0119dzy dwoma punktami na p\u0142aszczy\u017anie dwuwymiarowej.

func int distance2D(var int x1, var int x2, var int y1, var int y2)\n
Parametry
  • var int x1 wsp\u00f3\u0142rz\u0119dna x pierwszego punktu
  • var int x2 wsp\u00f3\u0142rz\u0119dna x drugiego punktu
  • var int y1 wsp\u00f3\u0142rz\u0119dna y pierwszego punktu
  • var int y2 wsp\u00f3\u0142rz\u0119dna y drugiego punktu

Zwracana warto\u015b\u0107

Funkcja zwraca odleg\u0142o\u015b\u0107 mi\u0119dzy dwoma punktami.

"},{"location":"pl/zengin/scripts/extenders/lego/tools/misc/#distance2df","title":"distance2Df","text":"

Oblicza odleg\u0142o\u015b\u0107 mi\u0119dzy dwoma punktami na p\u0142aszczy\u017anie dwuwymiarowej, ale na liczbach zmiennoprzecinkowych (float).

func int distance2Df(var int x1, var int x2, var int y1, var int y2)\n
Parametry
  • var int x1 wsp\u00f3\u0142rz\u0119dna x pierwszego punktu
  • var int x2 wsp\u00f3\u0142rz\u0119dna x drugiego punktu
  • var int y1 wsp\u00f3\u0142rz\u0119dna y pierwszego punktu
  • var int y2 wsp\u00f3\u0142rz\u0119dna y drugiego punktu

Zwracana warto\u015b\u0107

Funkcja zwraca odleg\u0142o\u015b\u0107 mi\u0119dzy dwoma punktami, jako ikarusowy float.

"},{"location":"pl/zengin/scripts/extenders/lego/tools/talents/","title":"Talents - talenty","text":""},{"location":"pl/zengin/scripts/extenders/lego/tools/talents/#talents---talenty","title":"Talents - talenty","text":"

Ten pakiet robi dwie rzeczy:

  1. Zapisuje dowoln\u0105 liczb\u0119 warto\u015bci dla okre\u015blonego NPC (efektywne rozszerzenie tablicy AIVar).
  2. Pozwala zidentyfikowa\u0107 NPC za pomoc\u0105 unikalnego ID.

Pakiet Talents u\u017cywa jednego wolnego AIVara, domy\u015blnie jest to AIVar z numerem 89, kt\u00f3ry mo\u017cna dostosowa\u0107 w Userconst.d AIV_TALENT.

"},{"location":"pl/zengin/scripts/extenders/lego/tools/talents/#zale\u017cno\u015bci","title":"Zale\u017cno\u015bci","text":"
  • PermMem
"},{"location":"pl/zengin/scripts/extenders/lego/tools/talents/#inicjalizacja","title":"Inicjalizacja","text":"

Zainicjuj za pomoc\u0105 flagi LeGo_PermMem.

LeGo_Init(LeGo_PermMem);\n
"},{"location":"pl/zengin/scripts/extenders/lego/tools/talents/#implementacja","title":"Implementacja","text":"

Talents.d na GitHubie

"},{"location":"pl/zengin/scripts/extenders/lego/tools/talents/#funkcje","title":"Funkcje","text":""},{"location":"pl/zengin/scripts/extenders/lego/tools/talents/#npc_getid","title":"NPC_GetID","text":"

Zwraca unikalne ID dla podanego NPC.

func int NPC_GetID(var C_NPC slf)\n
Parametry
  • var C_NPC slf NPC

Zwracana warto\u015b\u0107

Funkcja zwraca unikalne ID dla podanego NPC.

"},{"location":"pl/zengin/scripts/extenders/lego/tools/talents/#npc_findbyid","title":"NPC_FindByID","text":"

Znajduje wska\u017anik NPC o podanym ID.

func int NPC_FindByID(var int ID)\n
Parametry
  • var int ID ID postaci

Zwracana warto\u015b\u0107

Funkcja zwraca wska\u017anik podanej postaci (NPC).

"},{"location":"pl/zengin/scripts/extenders/lego/tools/talents/#tal_createtalent","title":"TAL_CreateTalent","text":"

Tworzy talent, w kt\u00f3rym mo\u017cesz p\u00f3\u017aniej zapisa\u0107 warto\u015b\u0107 dla ka\u017cdego NPC (tak jak w AIVarze).

func int TAL_CreateTalent()\n
Zwracana warto\u015b\u0107

Funkcja zwraca warto\u015b\u0107, kt\u00f3ra jest p\u00f3\u017aniej wykorzystywana jako ID talentu.

"},{"location":"pl/zengin/scripts/extenders/lego/tools/talents/#tal_setvalue","title":"TAL_SetValue","text":"

Ustawia now\u0105 warto\u015b\u0107 dla okre\u015blonego talentu.

func void TAL_SetValue(var C_NPC npc, var int talent, var int value)\n
Parametry
  • var C_NPC npc NPC dla kt\u00f3rego ustawiana jest warto\u015b\u0107
  • var int talent ID talentu
  • var int value Ustawiana warto\u015b\u0107
"},{"location":"pl/zengin/scripts/extenders/lego/tools/talents/#tal_getvalue","title":"TAL_GetValue","text":"

Zwraca warto\u015b\u0107 talentu dla okre\u015blonego NPC.

func int TAL_GetValue(var C_NPC npc, var int talent)\n
Parametry
  • var C_NPC npc NPC, kt\u00f3rego warto\u015b\u0107 talentu jest zwracana
  • var int talent ID talentu
"},{"location":"pl/zengin/scripts/extenders/standalone/","title":"Samodzielne skrypty","text":""},{"location":"pl/zengin/scripts/extenders/standalone/#samodzielne-skrypty","title":"Samodzielne skrypty","text":"

Przez lata moderzy Gothica stworzyli wiele przydatnych funkcji do wykorzystania ze skryptami Zengin. Ta sekcja zawiera dokumentacj\u0119 niekt\u00f3rych skrypt\u00f3w, kt\u00f3re s\u0105 \u201esamodzielne\u201d, co oznacza, \u017ce nie s\u0105 cz\u0119\u015bci\u0105 wi\u0119kszych pakiet\u00f3w, ale cz\u0119sto s\u0105 to ma\u0142e funkcje u\u0142atwiaj\u0105ce \u017cycie modderom.

"},{"location":"pl/zengin/scripts/extenders/standalone/#script-biny","title":"Script Biny","text":"

Kilka os\u00f3b wpad\u0142o na pomys\u0142 zebrania rozsianych po forach skrypt\u00f3w, w wyniku czego powsta\u0142y tzw. Script Biny.

Warning

Script biny nie s\u0105 cz\u0119sto aktualizowane, wi\u0119c najnowsze aktualizacje i nowe skrypty mo\u017cna znale\u017a\u0107 w w\u0105tku ScriptBin na niemieckim forum WoG.

"},{"location":"pl/zengin/scripts/extenders/standalone/#wog-script-bin","title":"WoG Script Bin","text":"

Script bin stworzony przez Kiridesa zawieraj\u0105cy skrypty z niemieckiego forum WoG.

https://apps.kirides.de/wog-script-bin/

"},{"location":"pl/zengin/scripts/extenders/standalone/#repozytorium-scriptbin-na-githubie","title":"Repozytorium ScriptBin na GitHubie","text":"

Repozytorium GitHub stworzone przez Lehone, kt\u00f3re zawiera skrypty niekt\u00f3rych modder\u00f3w.

https://github.com/Lehona/ScriptBin

"},{"location":"pl/zengin/scripts/extenders/zparserextender/syntax_extensions/while/","title":"Natywna p\u0119tla WHILE","text":""},{"location":"pl/zengin/scripts/extenders/zparserextender/syntax_extensions/while/#natywna-p\u0119tla-while","title":"Natywna p\u0119tla WHILE","text":"

Podobnie jak Ikarus zParserExtender implementuje p\u0119tl\u0119 while.

var int value; value = 10;\nwhile(value > 0)\n{\n    if (value == 8)\n    {\n        continue;\n    };\n\n    if (value == 2)\n    {\n        break;\n    };\n};\n

Note

Aby aktywowa\u0107 while konieczne jest ustawienie NativeWhile w SystemPack.ini

[ZPARSE_EXTENDER]\nNativeWhile = true\n

Skompilowana p\u0119tla while dzia\u0142a w silniku vanilla bez pluginu.

"},{"location":"cs/","title":"V\u00edtejte na str\u00e1nce Gothic Modding Community","text":""},{"location":"cs/#v\u00edtejte-na-str\u00e1nce-gothic-modding-community","title":"V\u00edtejte na str\u00e1nce Gothic Modding Community","text":"

Tato Github str\u00e1nka obsahuje komunitou vytvo\u0159en\u00e9 a udr\u017eovan\u00e9 \u010dl\u00e1nky, n\u00e1vody a dokumentaci o v\u0161em, co se t\u00fdk\u00e1 her Gothic.

Prvn\u00ed dv\u011b hry s\u00e9rie Gothic b\u011b\u017e\u00ed na enginu, kter\u00fd se jmenuje ZenGin, vyvinut\u00e9m studiem Piranha Bytes a skupinou program\u00e1tor\u016f Mad Scientists. Pokud se chcete o historii v\u00fdvoje dozv\u011bd\u011bt v\u00edce, hromadu informac\u00ed m\u016f\u017eete naj\u00edt na str\u00e1nce Gothic Archive.

Obsah t\u00e9to str\u00e1nky by nem\u011bl b\u00fdt br\u00e1n jako jedin\u00fd validn\u00ed zp\u016fsob moddingu. Jsme pouze nad\u0161enci, kte\u0159\u00ed sd\u00edl\u00ed sv\u00e9 zku\u0161enosti, znalosti a na\u0161e nejobl\u00edben\u011bj\u0161\u00ed postupy.

Nev\u00e1hejte otev\u0159\u00edt pull request s va\u0161\u00edm \u010dl\u00e1nkem nebo n\u00e1vrhy na zm\u011bny.

Pull request m\u016f\u017eete otev\u0159\u00edt v tomto repozit\u00e1\u0159i.

"}]} \ No newline at end of file +{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"","title":"Welcome to Gothic Modding Community page","text":""},{"location":"#welcome-to-gothic-modding-community-page","title":"Welcome to Gothic Modding Community page","text":"

This GitHub page is designed to contain community maintained set of articles, tutorials and documentation for everything Gothic.

Info

The content here is not meant to be taken as the holy word of modding. We are just modders sharing our experiences, knowledge and our favorite work flows.

  • Discord Server

    If you have any modding related questions, or just want to talk join our discord server.

    Discord

  • Contribution

    Feel free to open a pull request with your article or propose changes. Here is detailed contribution guide.

    How to Contibute

  • Gothic Archive

    First two Gothic games use engine called ZenGin, developed by Piranha Bytes and Mad Scientists. If you want to know more about the history of the development, there is a heap of information on the Gothic Archive.

    Gothic Archive

  • Repository

    Check out our GitHub repository for the site's source code and updates.

    GitHub

"},{"location":"notready/","title":"None","text":"

Warning

Sorry, this page is not ready yet!

"},{"location":"preferences/","title":"Preferences","text":""},{"location":"preferences/#preferences","title":"Preferences","text":"

This page allows to set various preferences for reading the docs:

"},{"location":"preferences/#color","title":"Color","text":"

You can change the feel of the site with a color change.

Select accent color:

Select hue color:

Reset colors

"},{"location":"preferences/#font","title":"Font","text":"

You can change the font to another preset.

Select font: Default OpenDyslexic

"},{"location":"preferences/#custom-css","title":"Custom CSS","text":"

You can add custom stylesheets. Input CSS:

"},{"location":"contribute/","title":"How to contribute","text":""},{"location":"contribute/#how-to-contribute","title":"How to contribute","text":"

The Gothic Modding Community is a community-driven project. We encourage people to contribute.

This site is built with a Static Site Generator MkDocs and the Material for MkDocs theme together with multiple other MkDocs plugins.

Prerequisites for contribution differ based on the scale and type of the contribution.

"},{"location":"contribute/#feedback","title":"Feedback","text":"

Using English, you can either open an issue via GitHub or join us on Discord.

"},{"location":"contribute/#direct-contribution","title":"Direct contribution","text":"

Direct contribution is made via creating a copy of this repository (a fork) and creating a pull request (PR) on GitHub with changes for approval.

Don't waste time

Please make sure that the content you are contributing does not already exist on the dev page. You can use the search tool to filter GMC for different keywords and contents.

How to edit the source files?

The source files for the articles are written using the Markdown .md file format (Markdown cheatsheet). Other than that, this site also uses Python Markdown Extensions which add more syntax rules like indented admonitions.

"},{"location":"contribute/#minor-changes","title":"Minor changes","text":"

Minor changes like fixing typos, grammatical errors or removing/adding words to paragraphs in a single file can be done quickly with the button in the upper right corner of each article. This will open up a GitHub editing interface which will create a fork with a patch branch after modifying the file and guide the user to open up the pull request.

Select the correct branch for the pull request

Make sure that the pull request is directed towards the dev or a special pre-merge branch and not the main branch.

"},{"location":"contribute/#major-changes","title":"Major changes","text":"

More elaborate changes like editing multiple files at once, adding new articles, images, other miscellaneous files or changing the configuration of the page are easier to make via external tools on your local PC. While most of these operations can be done with the GitHub interface, it is rather cumbersome, and it may be harder to spot issues during the process as changes are not immediately visible in the browser in their final form.

Some preparation is needed before working on the files as MkDocs requires an installation of Python on the system to run. GitHub works on top of git so an installation of git is also required. A basic familiarity with Terminal/Command Prompt/Powershell command line interfaces is helpful.

"},{"location":"contribute/#system-setup-video","title":"System setup (video)","text":"

Firstly, you should install Python. You can follow this step-by-step tutorial for Windows or macOS on how to install Python.

This video is from 2017?!

The process of installing Python hasn't changed since that point. However, please install the latest version of Python 3.

To work remotely with GitHub, you can install the latest version of git on your system following this tutorial.

If you just plan on editing the content of the articles with Markdown, you can simply install the latest version of Visual Studio Code for GUI git management and Markdown preview or work with any other familiar text editor and omit the environment setup.

If you are planning to do some elaborate Python programming, you can follow this step-by-step tutorial for Windows or macOS on how to set up an environment with Visual Studio Code.

"},{"location":"contribute/#system-setup-text","title":"System setup (text)","text":"

To prepare your system to run the project follow those instructions:

  1. Install the latest version of Python . Make sure to select the \"Add Python to PATH\" option during the installation process.

  2. Open up a Terminal/Command Prompt (cmd)/Powershell window.

  3. Check that Python was properly installed with this command (might need a terminal restart):

    python --version\n
  4. Install the latest version of git following this tutorial.

  5. Check that git was properly installed with this command (might need a terminal restart):

    git --version\n
  6. (optional) Install the latest version of Visual Studio Code for GUI git management and Markdown preview.

"},{"location":"contribute/#working-locally","title":"Working locally","text":"

In order to work locally:

  1. Create a fork on GitHub.
  2. On your local PC navigate to a directory where you want to clone your forked repository and open a Terminal window inside.
  3. Clone the forked repository, using this command:

    git clone https://github.com/user-name/forked-repository-name.git <DIR-PATH>\n

    Instead of https://github.com/user-name/forked-repository-name.git use your own link which can be found after clicking on the green <> Code button and selecting the HTTPS tab.

    Replace the <DIR-PATH> with a path to a directory or . if you're inside the directory you want the project files to be cloned into.

    This will automatically create a remote origin repository pointing to your own fork.

  4. Add the remote upstream repository using this command:

    git remote add upstream https://github.com/Gothic-Modding-Community/gmc.git\n
  5. (optional) Create a Virtual Environment and activate it.

    If you work on multiple Python projects, it might be worthwhile to create a Virtual Environment for each project to have separate library directories with installed modules/plugins.

    python -m venv venv\n

    This will create a venv directory inside the current Terminal directory. Please keep that name as it's added to the .gitignore project file.

    Depending on the system, use one of these commands to activate the virtual environment.

    Linux / macOS
    source venv/bin/activate\n
    Windows Powershell
    venv\\Scripts\\activate.ps1\n
    Windows Command Prompt (cmd)
    venv\\Scripts\\activate.bat\n

    After activation there will be a (venv) indicator near the Terminal prompt.

    Don't close the Terminal

    The virtual environment must be activated each time a new Terminal window is opened.

  6. Install MkDocs with plugins using this command:

    pip install -r requirements.txt\n

    This will install all dependencies.

  7. Fetch the git history from upstream using this command:

    git fetch upstream\n
  8. Checkout a new local branch based on the upstream dev branch:

    git checkout -b name-of-branch --track upstream/dev\n

    An appropriate name for a branch is either a feature name or short description of what it changes - for example 3ds-articles, fix-typos-for-contribution. They do not have to be elaborate, up-to 4 words suffices.

  9. Start a server with MkDocs using this command:

    mkdocs serve\n

    Visit the local site with this url http://127.0.0.1:8000/gmc/. Any time you make change to any file, the website will rebuild itself and your browser will auto-refresh.

    The server may be closed using the Control-C shortcut while in the terminal/console.

  10. When you are satisfied with a part of work, add and commit the files using these commands:

    git add .\ngit commit -m \"add 3 articles about ZenGin\"\n

    An appropriate commit message should be a sentence describing the changes.

  11. When you are finished with the work, push the branch to origin using this command:

    git push origin name-of-branch\n
  12. Create the pull request to the appropriate branch.

    After pushing your local branch to the remote origin, there will be a link available in the Terminal window. Use it to create the pull request using the pushed branch.

  13. Another contribution:

    Before contributing again, always use this command:

    git fetch upstream \n
    to make sure that you have an up-to-date upstream git history. Follow then from step 8.
    git status\n

    This command allows to check, if there are any changes in the project compared to the upstream repository.

"},{"location":"contribute/#build-preferences","title":"Build preferences","text":"

While working with the project, it's possible to set various environmental variables to configure it to your own preferences:

  • GMC_DEV_LOCALE - is a 2-character language identifier (ex. en, pl), it sets the development language of the site. This will enforce that language to be the default and only built language. Helps to decrease build time and allows to easily change the language without modyfying the config file. Because of changes in the mkdocs-static-i18n plugin, this is the only way to temporarily change the default language
  • GMC_BUILD_ALTERNATES - True or False value, activates the site build to also include alternate languages apart of the default language. Default behaviour is to omit alternates to decrease build time.
  • GMC_ENABLE_ON_PUBLISH - True or False value, activates all of the final build procedures, like adding of the last modified date, minifying of the resources etc.

Environmental variables can be set temporarily for the currently open Terminal window:

Linux
export GMC_DEV_LOCALE=en export GMC_BUILD_ALTERNATES=False; mkdocs serve\n
Windows Powershell
$env:GMC_DEV_LOCALE=\"en\"\n$env:GMC_BUILD_ALTERNATES=\"False\"\nmkdocs serve\n
Windows Command Prompt (cmd)
set GMC_DEV_LOCALE=en\nset GMC_BUILD_ALTERNATES=False\nmkdocs serve\n
"},{"location":"contribute/#build-performance","title":"Build performance","text":"

To speed up the build process during development make sure that only 1 language is built, and consider using the --dirtyreload option:

mkdocs serve --dirtyreload\n

This will cause only changed .md files to rebuild. However, if you make changes to a template in the overrides directory, no changes will be visible after the rebuild, because template modification requires a full rebuild.

"},{"location":"contribute/#submit-a-file","title":"Submit a file","text":"

If working with git or Markdown is not viable or possible for you, you can submit files in a Google Docs format on the GMC Discord server and we will format and upload it to the page.

Only New English Content

This option is limited to new content in English. We can't deal with translations in this manner. For translations send a translated .md file via a feedback channel, if you don't want to work directly with git, nor add the file via the GitHub interface.

"},{"location":"contribute/#translations","title":"Translations","text":"

To provide multilingual support, our site uses the MkDocs i18n plugin.

"},{"location":"contribute/#add-new-language-support","title":"Add new language support","text":"

To support a new language it needs to be added:

Indentation is important

You must preserve the correct amount of indentation, aka spacing between entries.

  1. In the mkdocs.yml configuration, in this example we're adding the xx language:

    plugins:\n  - i18n:\n      # ...\n      languages:\n        en:\n          name: en - English\n          build: true\n        xx:\n          name: xx - Language Name\n          build: true\n
  2. In the overrides/main.html file to add the announcement text for untranslated content:

    {%\n    set announcement = {\n        \"en\": \"This page has not yet been translated into LANGUAGE, therefore it is displayed in English.\",\n        \"xx\": \"yyy\",\n    }\n%}\n{%\n    set call_to_action = {\n        \"en\": \"Support us and translate!\",\n        \"xx\": \"yyy\",\n    }\n%}\n
  3. Visit the official theme site. Make sure that the theme translation is complete there. If it's not, just follow their contribution guide and come back here, there is no need to wait for the changes in the theme.

"},{"location":"contribute/#add-translated-pages","title":"Add translated pages","text":"

Each .md file in the docs directory can have a translated version. To add a translation for a given language create a copy with an added language suffix. For example index.md will become index.xx.md for the xx language based on the settings in the mkdocs.yml file.

Each untranslated article has the button in the upper right corner next to the title. It allows to quickly add the translation via the GitHub interface without the need for local file configuration.

"},{"location":"genome/","title":"Genome engine","text":""},{"location":"genome/#genome-engine","title":"Genome engine","text":"

Genome engine is new engine by Piranha Bytes created for the game Gothic 3 and later used for the Risen and ELEX series of games.

"},{"location":"genome/general_info/object_persistence/","title":"Object persistence","text":""},{"location":"genome/general_info/object_persistence/#object-persistence","title":"Object persistence","text":"

Please note the following warning about Risen 2, 3 and ELEX 1 and 2

The following information only applies to Gothic 3 (2006) and Risen (2009). While newer Genome engine games share the same overall concepts, they have significant implementation differences that warrant their own section.

The engine is, due to the nature of the games themselves, required to store and load a vast amount of different types of data from the user's hard-drive. In order to streamline this parsing and/or serialization process, Genome implements an object persistence system using its own built-in runtime type information (RTTI) system.

Any class derived from bCObjectBase may declare its own member properties in such a way that when the object is then written into a file using the bCAccessorPropertyObject class, its associated properties will be automatically serialized into the stream by using special preprocessor macros. When the object is read back from the file, the class will be automatically initialized using the stored members.

Additionally, classes may overload the Read and Write (OnRead and OnWrite in Risen 1) virtual methods that allow the class to save additional data required during parsing such as paths to other necessary files.

As this system is quite flexible, it is used to store most of the game's data, from meshes, animations and textures to level and quest data. This is quite different from ZenGin, as its object persistence system is only used for worlds, saves, output units and parts of compiled meshes.

"},{"location":"genome/general_info/object_persistence/#file-format","title":"File format","text":""},{"location":"genome/general_info/object_persistence/#files","title":"Files","text":"
struct bCIOStream\n{\n    char data[];\n};\n
struct eCArchiveFile\n{\n    char8_t  magic[8];  // \"GENOMFLE\"\n    uint16_t version;   // 0001\n    uint32_t offset;\n\n    char data[];\n\n    uint32_t magic;    // DEADBEEF\n    uint8_t  version;  // 01\n    uint32_t count;\n    for( Count )\n    {\n        uint16_t length;\n        char8_t  string[length];  // (ASCII)\n    }\n};\n
"},{"location":"genome/general_info/object_persistence/#bcaccessorpropertyobject","title":"bCAccessorPropertyObject","text":"
bCAccessorPropertyObject::Read \n{\n    uint16_t    version;    // 0x0001\n    bool        hasPropertyObject;\n    if (hasPropertyObject)\n    {\n        bCPropertyObjectSingleton::ReadObject\n        {\n            uint16_t    version;    // 0x0001\n            bool        isPersistable;    // 0x01 (GETrue)\n            bCString    className;\n            bCPropertyObjectFactory::ReadObject\n            {\n                uint16_t    version;        // 0x0001\n                bool        isRoot;            // 0x00 (GEFalse)\n                uint16_t    classVersion;\n                bTPropertyObject<%,%>::Read\n                {\n                    bCPropertyObjectBase::Read\n                    {\n                        uint16_t version;    // 0x00C9 (201)\n                    }\n                    uint32_t size;\n                }\n                bTPropertyObject<%,%>::ReadData\n                {\n                    bCPropertyObjectBase::ReadData\n                    {\n                        uint16_t version;    // 0x00C9 (201)\n                        uint32_t count;\n                        for (count)\n                        {\n                            bCString    name;\n                            bCString    type;\n                            uint16_t    version;    // 0x001E (30)\n                            uint32_t    size;\n                            uint8_t        value[size];\n                        }\n                    }\n                    %::Read\n                    {\n                        // ClassName::OnRead/OnWrite()\n                        // uint16_t ClassVersion; ...\n                    }\n                }\n            }\n        }\n    }\n}\n
"},{"location":"genome/general_info/object_persistence/#ecprocessibleelement","title":"eCProcessibleElement","text":"Gothic 3Risen
eCProcessibleElement::Load\n{\n    uint32_t magic; // 0xD0DEFADE\n    bCAccessorPropertyObject::Read\n    {\n        // Look above for bCAccessorPropertyObject definition\n    }\n}\n
eCProcessibleElement::Load\n{\n    bCAccessorPropertyObject::Read\n    {\n        // Look above for bCAccessorPropertyObject definition\n    }\n}\n
"},{"location":"genome/general_info/object_persistence/#implementation","title":"Implementation","text":""},{"location":"genome/general_info/object_persistence/#a-practical-example","title":"A practical example","text":"

Let's propose that we have a class which is declared like so:

class gCMyClass : public bCObjectRefBase\n{\npublic:\n\n    gCMyClass()                {}\n    virtual ~gCMyClass()    {}\n\n    virtual bEResult Write(bCOStream&); // OnWrite for Risen\n    virtual bEResult Read(bCIStream&);  // OnRead for Risen\n\nprivate:\n\n    DECLARE_PROPERTY(myInt, int);\n\n    int someData;\n\n};\n

The hypothetical class then implements these virtual functions:

bEResult gCMyClass::Write(bCOStream& file)\n{\n    file << someData;\n    return bEResult_Ok;\n}\n\nbEResult gCMyClass::Read(bCIStream& file)\n{\n    file >> someData;\n    return bEResult_Ok;\n}\n

We then initialize the class in the following way:

gCMyClass object;\nobject.myInt = 1;\nobject.someData = 1;\n

If we now serialized, or to use the engine's term \"archived\", this instance into an ASCII stream, the result would look like this:

\n
"},{"location":"genome/tools/","title":"Tools","text":""},{"location":"genome/tools/#tools","title":"Tools","text":"

Piranha Bytes did not release a modkit for their Genome engine, but the modding community has released a wide range of tools to work with the game's files and the engine itself.

Info

This page is under construction, for now, only handful of links are present.

"},{"location":"genome/tools/#gothic-3-sdk","title":"Gothic 3 SDK","text":"

Georgeto, inspired by NicoDE's Risen SDK, has created an SDK for Gothic 3. It can be used to manipulate the engine in the similar way Union is able to manipulate ZenGin. GitHub repository

"},{"location":"blog/community-news/introducing-community-posts/","title":"Introducing Community Posts","text":"","tags":["Documentation","i18n","MkDocs"]},{"location":"blog/community-news/introducing-community-posts/#introducing-community-posts","title":"Introducing Community Posts","text":"

Enabled by the built-in Blog plugin of Material for MkDocs.

Welcome to the new blog section of the GMC, where users can share tutorials, guides, analytical articles, useful snippets, promote their modding tools, and more.

This addition brings greater flexibility to content creation on our website.

","tags":["Documentation","i18n","MkDocs"]},{"location":"blog/community-news/introducing-community-posts/#why-a-blog","title":"Why a blog?","text":"

Throughout the history of the Gothic Modding Community, we've encountered a recurring issue: some content doesn't fit neatly into the \"docs\" format. To address this, we needed a new section. Initially, we considered a simple new area, but then the Blog plugin was announced for the Community version of the Material theme. We decided to wait for its release.

While waiting, we added support for i18n localization to attract new users for translation and content creation. However, despite our efforts, we didn't gain many regular contributors. Additionally, delays caused by the GitHub/PayPal issues further postponed the Blog plugin's release.

The Blog plugin eventually arrived in the Community version. Unfortunately, we discovered that the mkdocs-static-i18n plugin couldn't handle the internally generated blog pages. We hoped for a fix upstream, but the issue persisted.

","tags":["Documentation","i18n","MkDocs"]},{"location":"blog/community-news/introducing-community-posts/#i18n-support","title":"i18n support","text":"

Not supported

As of July 02, 2024, the i18n plugin doesn't support blog pages.

Given the complexity of this issue, it likely requires overriding the Blog plugin's internal code. This could prevent users with localization from updating, creating a problematic situation for @ultrabug, who would need to constantly make fixes. The issue is further complicated by different versions of the Blog plugin for the Community and Insiders editions.

This applies to us as well. Despite many fixes and patches added to our docs on top of other plugins, we don't plan to add i18n support for the blog ourselves to maintain general flexibility. Especially since our community is still primarily composed of English speakers.

","tags":["Documentation","i18n","MkDocs"]},{"location":"blog/community-news/introducing-community-posts/#who-can-add-posts-what-topics-are-allowed","title":"Who can add posts, what topics are allowed?","text":"

We don't plan to restrict posts too much. As long as they are not meme content, they will likely be accepted. For up-to-date guidelines, you can read the [how-to guide].

","tags":["Documentation","i18n","MkDocs"]},{"location":"blog/community-news/introducing-community-posts/#comments","title":"Comments","text":"

Let us know what do you think about the new feature!

","tags":["Documentation","i18n","MkDocs"]},{"location":"blog/tutorials/guidelines-for-community-posts/","title":"Guidelines For Community Posts","text":"","tags":["Best Practices","Documentation","How-To","MkDocs"]},{"location":"blog/tutorials/guidelines-for-community-posts/#guidelines-for-community-posts","title":"Guidelines For Community Posts","text":"

Question: What are the requirements for my blog post to be added here? Answer: There are almost no requirements, other than managing files properly.

Also read the general contribution guide for setup instructions.

","tags":["Best Practices","Documentation","How-To","MkDocs"]},{"location":"blog/tutorials/guidelines-for-community-posts/#technical-requirements","title":"Technical Requirements","text":"","tags":["Best Practices","Documentation","How-To","MkDocs"]},{"location":"blog/tutorials/guidelines-for-community-posts/#creation-date","title":"Creation Date","text":"

Each post must have a creation date used for sorting and ordering. The date key can be a simple string with the creation date or, an object structure with sub-keys created and updated.

date: 2024-07-01\n

Reference

","tags":["Best Practices","Documentation","How-To","MkDocs"]},{"location":"blog/tutorials/guidelines-for-community-posts/#at-least-one-category","title":"At Least One Category","text":"

This blog uses category-based URLs instead of default time-based post URLs. The categories key is a list of strings.

categories:\n  - Tutorials\n

Reference

","tags":["Best Practices","Documentation","How-To","MkDocs"]},{"location":"blog/tutorials/guidelines-for-community-posts/#mandatory-opinionated-requirements","title":"Mandatory Opinionated Requirements","text":"","tags":["Best Practices","Documentation","How-To","MkDocs"]},{"location":"blog/tutorials/guidelines-for-community-posts/#use-categories-defined-in-the-mkdocsyml-config","title":"Use Categories Defined in the mkdocs.yml Config","text":"

Some categories can be used for slugs, while others cannot. If you want to add a new one, please ask first. To see an up-to-date list, check the categories_allowed option in the mkdocs.yml file. For more granularity, use tags, which offer more flexibility. You can see the index of used tags here.

","tags":["Best Practices","Documentation","How-To","MkDocs"]},{"location":"blog/tutorials/guidelines-for-community-posts/#keep-the-files-organized","title":"Keep the Files Organized","text":"

Place posts in the blog/posts directory under a subdirectory matching the category slug (lowercase with _ in place of spaces):

Filenames should use _ for spaces and should be lowercase.

blog/posts/community_news/welcome.md\nblog/posts/tutorials/how_to_write_blog_posts.md\n

For assets specific to the blog section:

Note the lack of posts.

assets/blog/images/tutorials/image.png\n
","tags":["Best Practices","Documentation","How-To","MkDocs"]},{"location":"blog/tutorials/guidelines-for-community-posts/#assets-like-images-need-to-be-placed-under-the-overrides-path","title":"Assets Like Images Need to Be Placed Under the overrides Path","text":"

Due to the rest of the site using multiple languages (i18n), assets are kept in the overrides directory to reduce duplication of files after the build. The overrides directory is placed on top of the built directory so all relative paths are the same as if the files were in the docs directory. Use a couple of ../ to get to the root of the built site and access the asset:

../../../assets/images/gmc_logo.png\n

So in the example before:

../../../assets/blog/images/tutorials/image.png\n
","tags":["Best Practices","Documentation","How-To","MkDocs"]},{"location":"blog/tutorials/guidelines-for-community-posts/#optional-opinionated-recommendations","title":"Optional Opinionated Recommendations","text":"","tags":["Best Practices","Documentation","How-To","MkDocs"]},{"location":"blog/tutorials/guidelines-for-community-posts/#keep-keys-and-values-in-the-front-matter-in-alphabetical-order","title":"Keep Keys and Values in the Front-Matter in Alphabetical Order","text":"

This will make it easier to spot mistakes.

","tags":["Best Practices","Documentation","How-To","MkDocs"]},{"location":"blog/tutorials/guidelines-for-community-posts/#maintain-a-strict-line-width-limit","title":"Maintain a Strict Line Width Limit","text":"

It will make it easier to read and spot mistakes in Markdown. mkdocs-material uses an 80-character limit, which is a bit narrow. Currently, the CSS settings for the width of the content are roughly ~140 characters, which is a bit wide. This Markdown file uses a 100-character limit. Keep things reasonable and use the same width throughout the file, and do not break lines prematurely.

","tags":["Best Practices","Documentation","How-To","MkDocs"]},{"location":"blog/tutorials/guidelines-for-community-posts/#use-alternative-link-definitions","title":"Use Alternative Link Definitions","text":"

To avoid issues with long lines, define links before the next heading using this syntax: [text]: url. Then you can organically use the [text] in your paragraph, and it will be converted to a URL, or use [text][defined url] to wrap the text using a defined URL.

","tags":["Best Practices","Documentation","How-To","MkDocs"]},{"location":"blog/tutorials/guidelines-for-community-posts/#avoid-name-conflicts","title":"Avoid Name Conflicts","text":"

If a name conflict occurs, don't resort to adding a lazy -2 at the end. Instead, ensure your name is distinct for better searchability. For example, instead of result.png, use a more specific name like blender_modifier_result.png or the slug of the blog post you're writing.

","tags":["Best Practices","Documentation","How-To","MkDocs"]},{"location":"blog/tutorials/guidelines-for-community-posts/#add-a-h2-comments-heading-at-the-bottom","title":"Add a H2 Comments Heading at the Bottom","text":"

This will add a TOC element for users to easily skip the post and read the comments. The RSS plugin also expects this heading to exist.

","tags":["Best Practices","Documentation","How-To","MkDocs"]},{"location":"blog/tutorials/guidelines-for-community-posts/#comments","title":"Comments","text":"

Let us know what you think about these guidelines!

","tags":["Best Practices","Documentation","How-To","MkDocs"]},{"location":"blog/category/community-news/","title":"Community News","text":""},{"location":"blog/category/tutorials/","title":"Tutorials","text":""},{"location":"blog/tags/","title":"Tags","text":""},{"location":"blog/tags/#tags","title":"Tags","text":""},{"location":"blog/tags/#best-practices","title":"Best Practices","text":"
  • Guidelines For Community Posts
"},{"location":"blog/tags/#documentation","title":"Documentation","text":"
  • Introducing Community Posts
  • Guidelines For Community Posts
"},{"location":"blog/tags/#how-to","title":"How-To","text":"
  • Guidelines For Community Posts
"},{"location":"blog/tags/#mkdocs","title":"MkDocs","text":"
  • Introducing Community Posts
  • Guidelines For Community Posts
"},{"location":"blog/tags/#i18n","title":"i18n","text":"
  • Introducing Community Posts
"},{"location":"pl/","title":"Witamy na stronie Gothic Modding Community","text":""},{"location":"pl/#witamy-na-stronie-gothic-modding-community","title":"Witamy na stronie Gothic Modding Community","text":"

Ta strona GitHub jest zaprojektowana w celu zawarcia zbioru artyku\u0142\u00f3w, poradnik\u00f3w oraz innej dokumentacji o Gothicu utrzymywanych przez spo\u0142eczno\u015b\u0107.

Informacja

Zawarto\u015b\u0107 strony nie jest przeznaczona, aby by\u0107 uznan\u0105 za \u015bwi\u0119te s\u0142owa moddingu. Jeste\u015bmy tylko modderami dziel\u0105cymi si\u0119 do\u015bwiadczeniami, wiedz\u0105 oraz naszym ulubionym tokiem pracy.

  • Serwer Discord

    Je\u015bli masz jakie\u015b pytania zwi\u0105zane z modowaniem lub po prostu chcesz porozmawia\u0107, do\u0142\u0105cz do naszego serwera Discord.

    Discord

  • Udzielanie si\u0119

    Nie kr\u0119puj si\u0119, aby otworzy\u0107 pro\u015bb\u0119 o po\u0142\u0105czenie (ang. pull request) z twoim artyku\u0142em, lub z propozycj\u0105 zmian. Tutaj znajdziesz pe\u0142n\u0105 instrukcje jak to zrobi\u0107.

    Jak Si\u0119 Udzieli\u0107

  • Gothic Archive

    Dwie pierwsze cz\u0119\u015bci gier Gothic korzystaj\u0105 z silnika o nazwie ZenGin, stworzonego przez Piranha Bytes oraz grup\u0119 programist\u00f3w o nazwie Mad Scientists. Je\u017celi chcesz wiedzie\u0107 wi\u0119cej o historii tworzenia, to jest masa informacji na Gothic Archive.

    Gothic Archive

  • Repozytorium

    Sprawd\u017a nasze repozytorium GitHub, aby uzyska\u0107 kod \u017ar\u00f3d\u0142owy strony i informacje o aktualizacjach.

    GitHub

"},{"location":"pl/preferences/","title":"Preferencje","text":""},{"location":"pl/preferences/#preferencje","title":"Preferencje","text":"

Ta strona pozwala ustawi\u0107 r\u00f3\u017cne preferencje do czytania dokumentacji:

"},{"location":"pl/preferences/#kolor","title":"Kolor","text":"

Mo\u017cesz zmieni\u0107 nastr\u00f3j strony poprzez zmian\u0119 koloru.

Wybierz kolor akcentuj\u0105cy:

Wybierz kolor odcienia:

Zresetuj kolory

"},{"location":"pl/preferences/#czcionka","title":"Czcionka","text":"

Mo\u017cesz zmieni\u0107 czcionk\u0119 na predefiniowany.

Wybierz czcionk\u0119: Domy\u015blna OpenDyslexic

"},{"location":"pl/preferences/#w\u0142asny-css","title":"W\u0142asny CSS","text":"

Mo\u017cesz doda\u0107 niestandardowe arkusze styl\u00f3w. Wprowad\u017a CSS:

"},{"location":"pl/contribute/","title":"Jak si\u0119 udzieli\u0107","text":""},{"location":"pl/contribute/#jak-si\u0119-udzieli\u0107","title":"Jak si\u0119 udzieli\u0107","text":"

Gothic Modding Community jest projektem nap\u0119dzanym przed spo\u0142eczno\u015b\u0107. Zach\u0119camy osoby do wnoszenia swojego wk\u0142adu.

Ta strona jest budowana przy pomocy statycznego generatora stron MkDocs oraz sk\u00f3rki Material for MkDocs, wraz z wieloma innymi wtyczkami do MkDocs.

Zale\u017cnie od skali i typu kontrybucji, trzeba spe\u0142ni\u0107 inne wymagania wst\u0119pne.

"},{"location":"pl/contribute/#zg\u0142oszenia","title":"Zg\u0142oszenia","text":"

Po angielsku mo\u017cna zg\u0142osi\u0107 problem lub inny komentarz o funkcjonowaniu strony poprzez otworzenie problemu (ang. issue) na serwisie GitHub albo do\u0142\u0105cz do nas na platformie Discord.

"},{"location":"pl/contribute/#wk\u0142ad-bezpo\u015bredni","title":"Wk\u0142ad bezpo\u015bredni","text":"

Wk\u0142ad bezpo\u015bredni wykonuje si\u0119 poprzez stworzenie kopii tego repozytorium (ang. fork) oraz stworzenie pro\u015bby o po\u0142\u0105czenie (ang. pull request PR) na serwisie GitHub wraz ze zmianami do zatwierdzenia.

Nie zmarnuj czasu

Prosz\u0119 si\u0119 upewni\u0107, \u017ce tre\u015b\u0107, jaka zostanie dodana, nie wyst\u0119puje ju\u017c na wersji dev strony. Mo\u017cna skorzysta\u0107 z funkcjonalno\u015bci wyszukiwania, \u017ceby przefiltrowa\u0107 GMC r\u00f3\u017cnymi s\u0142owami kluczowymi i tre\u015bciami.

Jak edytowa\u0107 pliki \u017ar\u00f3d\u0142owe?

Pliki \u017ar\u00f3d\u0142owe artyku\u0142\u00f3w s\u0105 pisane wykorzystuj\u0105c format plik\u00f3w Markdown .md (Markdown cheatsheet). Poza tym ta strona wykorzystuje wtyczk\u0119 Python Markdown Extensions, kt\u00f3ra rozszerza sk\u0142adni\u0119 o dodatkowe zasady pozwalaj\u0105ce na wstawienie wzmianek jak ta, kt\u00f3r\u0105 w\u0142a\u015bnie czytasz.

"},{"location":"pl/contribute/#mniejsze-zmiany","title":"Mniejsze zmiany","text":"

Mniejsze zmiany, jak poprawianie b\u0142\u0119d\u00f3w ortograficzny, gramatycznych, czy usuwanie/dodawanie s\u0142\u00f3w do akapit\u00f3w w jednym pliku, mog\u0105 by\u0107 zrobione szybko poprzez klikni\u0119cie przycisku w prawym g\u00f3rnym rogu artyku\u0142u. Otworzy to interfejs edytowania pliku w serwisie GitHub, kt\u00f3re po zapisaniu zmian, automatycznie utworzy kopi\u0119 (ang. fork) oraz ga\u0142\u0105\u017a (ang. brach) z \u0142atk\u0105, a nast\u0119pnie otworzy pro\u015bb\u0119 o po\u0142\u0105czenie (ang. pull request) wzgl\u0119dem ga\u0142\u0119zi dev.

Poprawna ga\u0142\u0105\u017a dla pro\u015bby o po\u0142\u0105czenie

Upewnij si\u0119, \u017ce pro\u015bba o po\u0142\u0105czenie (ang. pull request) jest skierowana do ga\u0142\u0119zi dev albo specjalnej ga\u0142\u0119zi pre-merge, a nie do ga\u0142\u0119zi main.

"},{"location":"pl/contribute/#wi\u0119ksze-zmiany","title":"Wi\u0119ksze zmiany","text":"

Bardziej z\u0142o\u017cone zmiany takie jak, edycja wielu plik\u00f3w naraz, dodawanie nowych artyku\u0142\u00f3w, obrazk\u00f3w, czy innych plik\u00f3w, albo zmiana konfiguracji strony jest \u0142atwiej zrobi\u0107 poprzez u\u017cycie zewn\u0119trznych narz\u0119dzi na lokalnym PC. Wi\u0119kszo\u015b\u0107 z tych operacji mo\u017cna zrobi\u0107 poprzez interfejs serwisu GitHub, ale jest to raczej uci\u0105\u017cliwe oraz trudniej zauwa\u017cy\u0107 problemy wynikaj\u0105ce z procesu zmian, poniewa\u017c nie s\u0105 one widoczne w przegl\u0105darce w ich ostatecznej formie.

Troch\u0119 przygotowa\u0144 jest potrzebnych przed rozpocz\u0119ciem prac nad plikami, poniewa\u017c do dzia\u0142ania MkDocs wymaga zainstalowanego w systemie Pythona. GitHub dzia\u0142a nad systemem kontroli wersji git, wi\u0119c jego instalacja jest te\u017c wymagana. Podstawowa znajomo\u015b\u0107 obs\u0142ugi Terminala/Konsoli polece\u0144/Powershell jest pomocna.

"},{"location":"pl/contribute/#przygotowanie-systemu-wideo","title":"Przygotowanie Systemu (wideo)","text":"

Po pierwsze, trzeba zainstalowa\u0107 Python. Mo\u017cna pod\u0105\u017ca\u0107 wed\u0142ug tego poradnika krok po kroku dla Windowsa albo macOS jak zainstalowa\u0107 Python.

Wideo jest z 2017?!

Proces instalacji Pythona nie zmieni\u0142 si\u0119 od tamtego czasu. Jednak\u017ce prosz\u0119 instalowa\u0107 najnowsz\u0105 wersj\u0119 Python 3.

Aby m\u00f3c pracowa\u0107 zdalnie z GitHub, mo\u017cna zainstalowa\u0107 najnowsz\u0105 wersj\u0119 git, pod\u0105\u017caj\u0105c wed\u0142ug tego poradnika.

Je\u017celi planujesz tylko edytowa\u0107 zawarto\u015b\u0107 artyku\u0142\u00f3w Markdown, mo\u017cesz po prostu zainstalowa\u0107 najnowsz\u0105 wersj\u0119 Visual Studio Code, \u017ceby mie\u0107 interfejs graficzny do zarz\u0105dzania git oraz podgl\u0105d Markdown, albo pracuj z dowolnym znanym edytorem tekstu i omi\u0144 konfiguracj\u0119 \u015brodowiska.

Je\u017celi planujesz bardziej z\u0142o\u017cone programowanie w Python, mo\u017cesz pod\u0105\u017cy\u0107 wed\u0142ug tego poradnika krok po kroku dla Windowsa lub macOS jak skonfigurowa\u0107 \u015brodowisko developerskie z Visual Studio Code (VS Code).

"},{"location":"pl/contribute/#przygotowanie-systemu-tekst","title":"Przygotowanie Systemu (tekst)","text":"

\u017beby przygotowa\u0107 system do uruchomienia projektu lokalnie, pod\u0105\u017caj wed\u0142ug tych instrukcji.

  1. Zainstaluj najnowsz\u0105 wersj\u0119 Pythona. Upewnij si\u0119, \u017ceby zaznaczy\u0107 opcj\u0119 \"Add Python to PATH\" podczas instalacji.

  2. Otw\u00f3rz okno Terminala/Konsoli polece\u0144/PowerShell.

  3. Sprawd\u017a, \u017ce instalacja Pythona by\u0142a pomy\u015blna, korzystaj\u0105c z tego polecenia (mo\u017cliwa jest potrzeba restartu okna konsoli):

    python --version\n
  4. Zainstaluj najnowsz\u0105 wersj\u0119 git, pod\u0105\u017caj\u0105c wed\u0142ug tego poradnika.

  5. Sprawd\u017a, \u017ce instalacja git by\u0142a pomy\u015blna, korzystaj\u0105c z tego polecenia (mo\u017cliwa jest potrzeba restartu okna konsoli):

    git --version\n
  6. (opcjonalne) Zainstaluj najnowsz\u0105 wersj\u0119 Visual Studio Code dla interfejsu graficznego do zarz\u0105dzania git i podgl\u0105dem Markdown.

"},{"location":"pl/contribute/#praca-lokalna","title":"Praca lokalna","text":"

Aby m\u00f3c pracowa\u0107 lokalnie:

  1. Stw\u00f3rz kopi\u0119 (ang. fork) na serwisie GitHub.
  2. Na lokalnym PC nawiguj do folderu, w kt\u00f3rym chcesz sklonowa\u0107 kopi\u0119 repozytorium, oraz otw\u00f3rz okno konsoli wewn\u0105trz niego.
  3. Sklonuj kopi\u0119 repozytorium, korzystaj\u0105c z tego polecenia:

    git clone https://github.com/user-name/forked-repository-name.git <DIR-PATH>\n

    Zamiast https://github.com/user-name/forked-repository-name.git skorzystaj z w\u0142asnego linku, kt\u00f3ry jest widoczny po klikni\u0119ciu zielonego przycisku <> Code i wybraniu zak\u0142adki HTTPS.

    Zamie\u0144 <DIR-PATH> ze \u015bcie\u017ck\u0105 do folderu, do kt\u00f3rego ma by\u0107 sklonowane repozytorium albo . je\u017celi ju\u017c jeste\u015b wewn\u0105trz folderu gdzie pliki projektu maj\u0105 si\u0119 znajdowa\u0107.

    To automatycznie utworzy zdalne repozytorium origin skierowane wzgl\u0119dem twojej kopii.

  4. Dodaj zdalne repozytorium upstream korzystaj\u0105c z tego polecenia:

    git remote add upstream https://github.com/Gothic-Modding-Community/gmc.git\n
  5. (opcjonalne) Stw\u00f3rz wirtualne \u015brodowisko i aktywuj je.

    Je\u017celi pracujesz przy kilku projektach Python, warto stworzy\u0107 wirtualne \u015brodowisko (ang. Virtual Environment) dla ka\u017cdego z tych projekt\u00f3w, \u017ceby ka\u017cdy m\u00f3g\u0142 korzysta\u0107 z w\u0142asnego folderu bibliotek z zainstalowanymi modu\u0142ami/wtyczkami.

    python -m venv venv\n

    To utworzy folder venv wewn\u0105trz obecnie wybranego folderu w oknie konsoli. Prosz\u0119, zostaw t\u0119 nazw\u0119, poniewa\u017c jest dodana do pliku .gitignore projektu.

    Zale\u017cnie od systemu, skorzystaj z jednego z tych polece\u0144 do aktywacji wirtualnego \u015brodowiska.

    Linux / macOS
    source venv/bin/activate\n
    Windows Powershell
    venv\\Scripts\\activate.ps1\n
    Windows Konsola Polece\u0144 (cmd)
    venv\\Scripts\\activate.bat\n

    Po aktywacji indykator (venv) b\u0119dzie wy\u015bwietlany przy nazwie folderu w oknie polece\u0144.

    Nie zamykaj okna polece\u0144

    Wirtualne \u015brodowisko musi by\u0107 ponownie aktywowane, przy ka\u017cdym otwarciu okna polece\u0144.

  6. Zainstaluj MkDocs wraz z wtyczkami korzystaj\u0105c z tego polecenia:

    pip install -r requirements.txt\n

    To zainstaluje wszystkie zale\u017cno\u015bci.

  7. Pobierz (ang. fetch) stan historii git z repozytorium upstream korzystaj\u0105c z tego polecenia:

    git fetch upstream\n
  8. Otw\u00f3rz (ang. checkout) lokaln\u0105 ga\u0142\u0105\u017a opieraj\u0105c\u0105 si\u0119 o ga\u0142\u0105\u017a dev repozytorium upstream korzystaj\u0105c z tego polecenia:

    git checkout -b name-of-branch --track upstream/dev\n

    W miejscu name-of-branch podaj kr\u00f3tk\u0105 nazw\u0119 po angielsku. Odpowiedni\u0105 nazw\u0105 ga\u0142\u0119zi jest albo nazwa funkcjonalno\u015bci, albo kr\u00f3tki opis wprowadzonych zmian np. 3ds-articles, fix-typos-for-contribution. Nie musz\u0105 by\u0107 zbyt skomplikowane, do 4 s\u0142\u00f3w wystarczy.

  9. Uruchom serwer ze zbudowan\u0105 stron\u0105 projektu, korzystaj\u0105c z tego polecenia:

    mkdocs serve\n

    Odwied\u017a lokaln\u0105 stron\u0119 pod tym adresem http://127.0.0.1:8000/gmc/. Po ka\u017cdej zmianie w plikach projektu strona automatycznie si\u0119 przebuduje i po chwili przegl\u0105darka automatycznie si\u0119 od\u015bwie\u017cy.

    Serwer mo\u017ce by\u0107 zamkni\u0119ty poprzez skorzystanie ze skr\u00f3tu klawiszowego Control-C w trakcie gdy okno polece\u0144 jest aktywne.

  10. Je\u017celi uko\u0144czysz fragment swojej pracy, dodaj pliki i wstaw wpis do historii gita (ang. commit) korzystaj\u0105c z tego polecenia:

    git add .\ngit commit -m \"add 3 articles about ZenGin\"\n

    Jak wida\u0107 wiadomo\u015b\u0107 (ang. message) / nazwa do wpisu historii r\u00f3wnie\u017c powinna by\u0107 w j\u0119zyku angielskim. Odpowiedni\u0105 wiadomo\u015bci\u0105 jest zdanie opisuj\u0105ce zmiany.

  11. Po sko\u0144czeniu wszystkich prac wy\u015blij (ang. push) swoj\u0105 ga\u0142\u0105\u017a do zdalnego repozytorium origin, korzystaj\u0105c z tego polecenia:

    git push origin name-of-branch\n
  12. Stw\u00f3rz pro\u015bb\u0119 o po\u0142\u0105czenie (ang. pull request) wzgl\u0119dem odpowiedniej ga\u0142\u0119zi.

    Po wys\u0142aniu lokalnej ga\u0142\u0119zi do zdalnego repozytorium origin w oknie polece\u0144 b\u0119dzie dost\u0119pne \u0142\u0105cze, kt\u00f3re otworzy stron\u0119 tworzenia pro\u015bby o po\u0142\u0105czenie. Upewnij si\u0119, \u017ce jest skierowana wzgl\u0119dem ga\u0142\u0119zi dev oraz, \u017ce posiada wszystkie wprowadzone zmiany.

  13. Kolejna kontrybucja:

    Przed kolejn\u0105 kontrybucj\u0105, zawsze skorzystaj z tego polecenia:

    git fetch upstream \n
    \u017ceby mie\u0107 pewno\u015b\u0107, \u017ce posiadasz najnowsz\u0105 histori\u0119 zmian z repozytorium upstream. Nast\u0119pnie pod\u0105\u017caj ponownie od 8. podpunktu i zawsze tw\u00f3rz now\u0105 ga\u0142\u0105\u017a przed wprowadzeniem zmian.
    git status\n

    Tym poleceniem mo\u017cesz sprawdzi\u0107, czy nie masz \u017cadnych zmian w strukturze projektu wzgl\u0119dem repozytorium upstream.

"},{"location":"pl/contribute/#preferencje-budowy-strony","title":"Preferencje budowy strony","text":"

Podczas pracy z projektem mo\u017cna ustawi\u0107 r\u00f3\u017cne zmienne \u015brodowiskowe, \u017ceby przystosowa\u0107 konfiguracj\u0119 do w\u0142asnych preferencji:

  • GMC_DEV_LOCALE - to dwuznakowy identyfikator j\u0119zyka (np. en, pl), ustawia j\u0119zyk testowy. To ustawi ten j\u0119zyki jako domy\u015blny oraz jedyny renderowany podczas budowy strony. Pomaga w zmniejszeniu czasu budowy strony oraz pozwala na \u0142atwe zmienianie j\u0119zyka zamiast modyfikowania pliku konfiguracyjnego. Przez zmiany w pluginie mkdocs-static-i18n jest to jedyny spos\u00f3b na tymczasow\u0105 zmian\u0119 domy\u015blnego j\u0119zyka
  • GMC_BUILD_ALTERNATES - warto\u015b\u0107 True albo False, aktywuje budowanie strony wraz z alternatywnymi j\u0119zykami. Domy\u015blnie alternatywne j\u0119zyki s\u0105 pomijane, aby zmenijszy\u0107 czas budowy strony.
  • GMC_ENABLE_ON_PUBLISH - warto\u015b\u0107 True albo False, aktywuje wszystkie finalne procesy, jak dodanie daty ostatniej aktualizacji, minimalizacja zasob\u00f3w itp.

Dla otwartego okna polece\u0144 mo\u017cna tymczasowo je ustawi\u0107:

Linux
export GMC_DEV_LOCALE=en export GMC_BUILD_ALTERNATES=False; mkdocs serve\n
Windows Powershell
$env:GMC_DEV_LOCALE=\"en\"\n$env:GMC_BUILD_ALTERNATES=\"False\"\nmkdocs serve\n
Windows Konsola Polece\u0144 (cmd)
set GMC_DEV_LOCALE=en\nset GMC_BUILD_ALTERNATES=False\nmkdocs serve\n
"},{"location":"pl/contribute/#wydajno\u015b\u0107-budowy-strony","title":"Wydajno\u015b\u0107 budowy strony","text":"

Aby przy\u015bpieszy\u0107 proces budowy strony podczas pracy, upewnij si\u0119, \u017ce tylko 1 j\u0119zyk jest budowany i rozwa\u017c u\u017cycie opcji --dirtyreload:

mkdocs serve --dirtyreload\n

To sprawi, \u017ce tylko zmienione pliki .md b\u0119d\u0105 na nowo budowane. Jednak\u017ce, zmiany plik\u00f3w szablonowych (ang. template) w folderze overrides nie b\u0119d\u0105 widoczne, poniewa\u017c takie zmiany wymagaj\u0105 pe\u0142nej przebudowy.

"},{"location":"pl/contribute/#prze\u015blij-plik","title":"Prze\u015blij plik","text":"

Je\u017celi praca z git albo Markdown jest nieprzyst\u0119pna lub niemo\u017cliwa to mo\u017cesz przes\u0142a\u0107 plik w formacie Google Docs na serwer Discord GMC, sformatujemy go i dodamy tre\u015b\u0107 do strony.

Tylko nowa zawarto\u015b\u0107 po angielsku

Ta opcja jest ograniczona tylko dla nowej tre\u015bci w j\u0119zyku angielskim. Nie mo\u017cemy wykorzysta\u0107 tego sposobu dla t\u0142umacze\u0144. Dla t\u0142umacze\u0144 wy\u015blij przet\u0142umaczony plik .md poprzez zg\u0142oszenie, je\u017celi nie chcesz pracowa\u0107 bezpo\u015brednio z git, ani doda\u0107 pliku poprzez interfejs GitHub.

"},{"location":"pl/contribute/#translations","title":"T\u0142umaczenia","text":"

\u017beby dostarczy\u0107 wsparcie dla wielu j\u0119zyk\u00f3w, nasza strona korzysta ze wtyczki MkDocs i18n.

"},{"location":"pl/contribute/#dodaj-wsparcie-dla-nowego-j\u0119zyka","title":"Dodaj wsparcie dla nowego j\u0119zyka","text":"

\u017beby wspiera\u0107 nowy j\u0119zyk, musi by\u0107 dodany:

Wci\u0119cia maj\u0105 znaczenie

Musisz zachowa\u0107 poprawn\u0105 ilo\u015b\u0107 wci\u0119\u0107, czyli odst\u0119p\u00f3w mi\u0119dzy wpisami.

  1. W konfiguracji mkdocs.yml, w tym przyk\u0142adzie dodajemy j\u0119zyk xx:

    plugins:\n  - i18n:\n      # ...\n      languages:\n        en:\n          name: en - English\n          build: true\n        xx:\n          name: xx - Language Name\n          build: true\n
  2. W pliku overrides/main.html, \u017ceby doda\u0107 tekst og\u0142oszenia dla zawarto\u015bci nieprzet\u0142umaczonej:

    {%\n    set announcement = {\n        \"en\": \"This page has not yet been translated into LANGUAGE, therefore it is displayed in English.\",\n        \"xx\": \"yyy\",\n    }\n%}\n{%\n    set call_to_action = {\n        \"en\": \"Support us and translate!\",\n        \"xx\": \"yyy\",\n    }\n%}\n
  3. Odwied\u017a oficjaln\u0105 stron\u0119 sk\u00f3rki. Upewnij si\u0119, \u017ce t\u0142umaczenie sk\u00f3rki jest tam kompletne. Je\u017celi nie jest, pod\u0105\u017caj wed\u0142ug poradnika kontrybucji sk\u00f3rki i wr\u00f3\u0107 tutaj, nie trzeba czeka\u0107 na zmiany w sk\u00f3rce.

"},{"location":"pl/contribute/#dodaj-przet\u0142umaczone-strony","title":"Dodaj przet\u0142umaczone strony","text":"

Ka\u017cdy plik .md w folderze docs mo\u017ce mie\u0107 przet\u0142umaczon\u0105 wersj\u0119. \u017beby doda\u0107 t\u0142umaczenie strony dla danego j\u0119zyka, stw\u00f3rz kopi\u0119 strony z dodan\u0105 ko\u0144c\u00f3wk\u0105 tego j\u0119zyka. Na przyk\u0142ad index.md b\u0119dzie index.xx.md dla j\u0119zyka xx bazuj\u0105c na ustawieniach z pliku mkdocs.yml.

Ka\u017cdy nieprzet\u0142umaczony artyku\u0142 posiada przycisk w g\u00f3rnym prawym rogu obok tytu\u0142u. Pozwala na szybkie dodanie t\u0142umaczenia poprzez interfejs serwisu GitHub bez potrzeby konfiguracji plik\u00f3w lokalnie.

"},{"location":"pl/genome/","title":"Genome Engine","text":""},{"location":"pl/genome/#genome-engine","title":"Genome Engine","text":"

Genome Engine to nowy silnik autorstwa Piranha Bytes stworzony na potrzeby gry Gothic 3, a nast\u0119pnie wykorzystany w serii gier Risen i ELEX.

"},{"location":"cs/","title":"V\u00edtejte na str\u00e1nce Gothic Modding Community","text":""},{"location":"cs/#v\u00edtejte-na-str\u00e1nce-gothic-modding-community","title":"V\u00edtejte na str\u00e1nce Gothic Modding Community","text":"

Tato Github str\u00e1nka obsahuje komunitou vytvo\u0159en\u00e9 a udr\u017eovan\u00e9 \u010dl\u00e1nky, n\u00e1vody a dokumentaci o v\u0161em, co se t\u00fdk\u00e1 her Gothic.

Prvn\u00ed dv\u011b hry s\u00e9rie Gothic b\u011b\u017e\u00ed na enginu, kter\u00fd se jmenuje ZenGin, vyvinut\u00e9m studiem Piranha Bytes a skupinou program\u00e1tor\u016f Mad Scientists. Pokud se chcete o historii v\u00fdvoje dozv\u011bd\u011bt v\u00edce, hromadu informac\u00ed m\u016f\u017eete naj\u00edt na str\u00e1nce Gothic Archive.

Obsah t\u00e9to str\u00e1nky by nem\u011bl b\u00fdt br\u00e1n jako jedin\u00fd validn\u00ed zp\u016fsob moddingu. Jsme pouze nad\u0161enci, kte\u0159\u00ed sd\u00edl\u00ed sv\u00e9 zku\u0161enosti, znalosti a na\u0161e nejobl\u00edben\u011bj\u0161\u00ed postupy.

Nev\u00e1hejte otev\u0159\u00edt pull request s va\u0161\u00edm \u010dl\u00e1nkem nebo n\u00e1vrhy na zm\u011bny.

Pull request m\u016f\u017eete otev\u0159\u00edt v tomto repozit\u00e1\u0159i.

"}]} \ No newline at end of file diff --git a/sitemap.xml b/sitemap.xml index 0a266f4bb4..19a8c26ab1 100644 --- a/sitemap.xml +++ b/sitemap.xml @@ -1,431 +1,41 @@ - https://auronen.cokoliv.eu/gmc/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/notready/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/preferences/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/contribute/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/genome/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/genome/general_info/object_persistence/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/genome/tools/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/meshes/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/music/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/textures/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/video/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/anims/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/anims/events/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/anims/mds/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/anims/tutorials/standalone_animation/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/general_info/directory_structure/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/general_info/object_persistence/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/general_info/vdfs/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/classes/c_info/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/classes/c_item/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/classes/c_menu/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/classes/c_musicsys_cfg/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/classes/c_musictheme/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/classes/c_svm/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/afsp/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/afsp/afsp_eim/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/ikarus/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/ikarus/constants/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/ikarus/examples/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/ikarus/floats/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/ikarus/setup/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/ikarus/functions/arrays/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/ikarus/functions/asm/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/ikarus/functions/call/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/ikarus/functions/debug/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/ikarus/functions/ini_access/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/ikarus/functions/jumps_loops/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/ikarus/functions/keyboard/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/ikarus/functions/mem_access/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/ikarus/functions/mem_utility/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/ikarus/functions/menu_access/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/ikarus/functions/objects/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/ikarus/functions/parser/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/ikarus/functions/string/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/ikarus/functions/time_benchmark/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/ikarus/functions/win_utilities/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/lego/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/lego/applications/anim8/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/lego/applications/bars/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/lego/applications/bloodsplats/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/lego/applications/buffs/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/lego/applications/buttons/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/lego/applications/console_commands/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/lego/applications/cursor/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/lego/applications/dialoggestures/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/lego/applications/focusnames/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/lego/applications/gamestate/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/lego/applications/names/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/lego/applications/render/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/lego/applications/saves/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/lego/applications/trialoge/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/lego/tools/ai_function/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/lego/tools/binary_machines/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/lego/tools/event_handler/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/lego/tools/frame_functions/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/lego/tools/hashtables/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/lego/tools/hook_dae/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/lego/tools/hook_engine/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/lego/tools/int64/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/lego/tools/interface/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/lego/tools/item_helper/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/lego/tools/list/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/lego/tools/locals/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/lego/tools/misc/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/lego/tools/permmem/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/lego/tools/queue/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/lego/tools/random/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/lego/tools/string_builder/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/lego/tools/talents/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/lego/tools/timer/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/lego/tools/view/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/lego/various/userconstants/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/standalone/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/standalone/gameKeyEvents/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/standalone/setBarPositions/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/zparserextender/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/zparserextender/classes/c_trigger/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/zparserextender/classes/helperclasses/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/zparserextender/daedalus_injection/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/zparserextender/daedalus_injection/hooks/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/zparserextender/daedalus_injection/meta/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/zparserextender/daedalus_injection/other/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/zparserextender/examples/signposts/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/zparserextender/externals/ai/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/zparserextender/externals/cast/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/zparserextender/externals/events_vars/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/zparserextender/externals/hlp/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/zparserextender/externals/log/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/zparserextender/externals/mdl/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/zparserextender/externals/menu/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/zparserextender/externals/mob/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/zparserextender/externals/npc/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/zparserextender/externals/par/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/zparserextender/externals/string/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/zparserextender/externals/vob/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/zparserextender/externals/wld/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/zparserextender/syntax_extensions/dialogues/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/zparserextender/syntax_extensions/events/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/zparserextender/syntax_extensions/extern/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/zparserextender/syntax_extensions/namespaces/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/zparserextender/syntax_extensions/testelse/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/extenders/zparserextender/syntax_extensions/while/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/externals/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/externals/doc/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/externals/log/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/scripts/externals/mdl/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/sound/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/sound/tutorials/change_sfx/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/tools/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/tools/gothic_sourcer/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/tools/zSpy/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/tools/daedalus_tools/daedalus_language_server/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/tools/vdfs_tools/gothic_vdfs/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/tools/vdfs_tools/vdfs_tool/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/union/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/union/plugins/zbassmusic/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/union/plugins/zgamepad/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/union/plugins/zgamepad/controls/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/union/plugins/zgamepad/keys_engine_absolute/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/union/plugins/zgamepad/keys_engine_logical/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/union/plugins/zgamepad/keys_gamepad/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/union/plugins/zgamepad/logical_functions/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/union/sdk/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/union/sdk/events/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/union/sdk/externals/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/union/sdk/getting_started/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/union/sdk/hooks/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/worlds/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/worlds/spacer/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/zengin/worlds/Classes/zCVob/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/notready/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/preferences/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/contribute/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/genome/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/genome/general_info/object_persistence/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/genome/tools/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/meshes/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/music/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/textures/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/video/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/anims/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/anims/events/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/anims/mds/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/anims/tutorials/standalone_animation/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/general_info/directory_structure/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/general_info/object_persistence/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/general_info/vdfs/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/classes/c_info/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/classes/c_item/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/classes/c_menu/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/classes/c_musicsys_cfg/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/classes/c_musictheme/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/classes/c_svm/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/afsp/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/afsp/afsp_eim/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/ikarus/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/ikarus/constants/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/ikarus/examples/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/ikarus/floats/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/ikarus/setup/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/ikarus/functions/arrays/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/ikarus/functions/asm/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/ikarus/functions/call/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/ikarus/functions/debug/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/ikarus/functions/ini_access/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/ikarus/functions/jumps_loops/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/ikarus/functions/keyboard/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/ikarus/functions/mem_access/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/ikarus/functions/mem_utility/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/ikarus/functions/menu_access/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/ikarus/functions/objects/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/ikarus/functions/parser/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/ikarus/functions/string/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/ikarus/functions/time_benchmark/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/ikarus/functions/win_utilities/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/lego/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/lego/applications/anim8/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/lego/applications/bars/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/lego/applications/bloodsplats/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/lego/applications/buffs/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/lego/applications/buttons/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/lego/applications/console_commands/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/lego/applications/cursor/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/lego/applications/dialoggestures/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/lego/applications/focusnames/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/lego/applications/gamestate/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/lego/applications/names/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/lego/applications/render/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/lego/applications/saves/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/lego/applications/trialoge/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/lego/tools/ai_function/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/lego/tools/binary_machines/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/lego/tools/event_handler/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/lego/tools/frame_functions/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/lego/tools/hashtables/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/lego/tools/hook_dae/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/lego/tools/hook_engine/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/lego/tools/int64/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/lego/tools/interface/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/lego/tools/item_helper/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/lego/tools/list/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/lego/tools/locals/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/lego/tools/misc/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/lego/tools/permmem/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/lego/tools/queue/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/lego/tools/random/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/lego/tools/string_builder/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/lego/tools/talents/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/lego/tools/timer/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/lego/tools/view/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/lego/various/userconstants/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/standalone/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/standalone/gameKeyEvents/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/standalone/setBarPositions/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/zparserextender/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/zparserextender/classes/c_trigger/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/zparserextender/classes/helperclasses/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/zparserextender/daedalus_injection/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/zparserextender/daedalus_injection/hooks/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/zparserextender/daedalus_injection/meta/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/zparserextender/daedalus_injection/other/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/zparserextender/examples/signposts/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/zparserextender/externals/ai/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/zparserextender/externals/cast/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/zparserextender/externals/events_vars/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/zparserextender/externals/hlp/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/zparserextender/externals/log/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/zparserextender/externals/mdl/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/zparserextender/externals/menu/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/zparserextender/externals/mob/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/zparserextender/externals/npc/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/zparserextender/externals/par/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/zparserextender/externals/string/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/zparserextender/externals/vob/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/zparserextender/externals/wld/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/zparserextender/syntax_extensions/dialogues/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/zparserextender/syntax_extensions/events/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/zparserextender/syntax_extensions/extern/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/zparserextender/syntax_extensions/namespaces/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/zparserextender/syntax_extensions/testelse/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/extenders/zparserextender/syntax_extensions/while/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/externals/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/externals/doc/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/externals/log/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/scripts/externals/mdl/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/sound/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/sound/tutorials/change_sfx/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/tools/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/tools/gothic_sourcer/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/tools/zSpy/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/tools/daedalus_tools/daedalus_language_server/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/tools/vdfs_tools/gothic_vdfs/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/tools/vdfs_tools/vdfs_tool/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/union/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/union/plugins/zbassmusic/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/union/plugins/zgamepad/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/union/plugins/zgamepad/controls/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/union/plugins/zgamepad/keys_engine_absolute/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/union/plugins/zgamepad/keys_engine_logical/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/union/plugins/zgamepad/keys_gamepad/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/union/plugins/zgamepad/logical_functions/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/union/sdk/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/union/sdk/events/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/union/sdk/externals/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/union/sdk/getting_started/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/union/sdk/hooks/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/worlds/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/worlds/spacer/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/pl/zengin/worlds/Classes/zCVob/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/notready/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/preferences/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/contribute/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/genome/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/genome/general_info/object_persistence/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/genome/tools/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/meshes/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/music/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/textures/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/video/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/anims/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/anims/events/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/anims/mds/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/anims/tutorials/standalone_animation/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/general_info/directory_structure/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/general_info/object_persistence/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/general_info/vdfs/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/classes/c_info/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/classes/c_item/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/classes/c_menu/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/classes/c_musicsys_cfg/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/classes/c_musictheme/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/classes/c_svm/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/afsp/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/afsp/afsp_eim/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/ikarus/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/ikarus/constants/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/ikarus/examples/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/ikarus/floats/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/ikarus/setup/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/ikarus/functions/arrays/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/ikarus/functions/asm/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/ikarus/functions/call/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/ikarus/functions/debug/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/ikarus/functions/ini_access/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/ikarus/functions/jumps_loops/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/ikarus/functions/keyboard/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/ikarus/functions/mem_access/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/ikarus/functions/mem_utility/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/ikarus/functions/menu_access/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/ikarus/functions/objects/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/ikarus/functions/parser/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/ikarus/functions/string/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/ikarus/functions/time_benchmark/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/ikarus/functions/win_utilities/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/lego/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/lego/applications/anim8/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/lego/applications/bars/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/lego/applications/bloodsplats/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/lego/applications/buffs/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/lego/applications/buttons/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/lego/applications/console_commands/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/lego/applications/cursor/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/lego/applications/dialoggestures/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/lego/applications/focusnames/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/lego/applications/gamestate/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/lego/applications/names/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/lego/applications/render/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/lego/applications/saves/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/lego/applications/trialoge/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/lego/tools/ai_function/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/lego/tools/binary_machines/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/lego/tools/event_handler/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/lego/tools/frame_functions/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/lego/tools/hashtables/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/lego/tools/hook_dae/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/lego/tools/hook_engine/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/lego/tools/int64/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/lego/tools/interface/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/lego/tools/item_helper/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/lego/tools/list/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/lego/tools/locals/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/lego/tools/misc/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/lego/tools/permmem/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/lego/tools/queue/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/lego/tools/random/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/lego/tools/string_builder/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/lego/tools/talents/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/lego/tools/timer/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/lego/tools/view/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/lego/various/userconstants/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/standalone/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/standalone/gameKeyEvents/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/standalone/setBarPositions/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/zparserextender/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/zparserextender/classes/c_trigger/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/zparserextender/classes/helperclasses/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/zparserextender/daedalus_injection/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/zparserextender/daedalus_injection/hooks/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/zparserextender/daedalus_injection/meta/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/zparserextender/daedalus_injection/other/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/zparserextender/examples/signposts/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/zparserextender/externals/ai/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/zparserextender/externals/cast/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/zparserextender/externals/events_vars/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/zparserextender/externals/hlp/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/zparserextender/externals/log/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/zparserextender/externals/mdl/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/zparserextender/externals/menu/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/zparserextender/externals/mob/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/zparserextender/externals/npc/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/zparserextender/externals/par/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/zparserextender/externals/string/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/zparserextender/externals/vob/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/zparserextender/externals/wld/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/zparserextender/syntax_extensions/dialogues/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/zparserextender/syntax_extensions/events/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/zparserextender/syntax_extensions/extern/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/zparserextender/syntax_extensions/namespaces/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/zparserextender/syntax_extensions/testelse/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/extenders/zparserextender/syntax_extensions/while/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/externals/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/externals/doc/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/externals/log/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/scripts/externals/mdl/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/sound/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/sound/tutorials/change_sfx/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/tools/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/tools/gothic_sourcer/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/tools/zSpy/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/tools/daedalus_tools/daedalus_language_server/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/tools/vdfs_tools/gothic_vdfs/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/tools/vdfs_tools/vdfs_tool/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/union/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/union/plugins/zbassmusic/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/union/plugins/zgamepad/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/union/plugins/zgamepad/controls/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/union/plugins/zgamepad/keys_engine_absolute/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/union/plugins/zgamepad/keys_engine_logical/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/union/plugins/zgamepad/keys_gamepad/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/union/plugins/zgamepad/logical_functions/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/union/sdk/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/union/sdk/events/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/union/sdk/externals/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/union/sdk/getting_started/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/union/sdk/hooks/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/worlds/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/worlds/spacer/ 2024-02-09 daily - https://auronen.cokoliv.eu/gmc/cs/zengin/worlds/Classes/zCVob/ 2024-02-09 daily \ No newline at end of file + https://auronen.cokoliv.eu/gmc/ 2024-06-30 daily + https://auronen.cokoliv.eu/gmc/notready/ 2024-06-30 daily + https://auronen.cokoliv.eu/gmc/preferences/ 2024-06-30 daily + https://auronen.cokoliv.eu/gmc/contribute/ 2024-06-30 daily + https://auronen.cokoliv.eu/gmc/genome/ 2024-06-30 daily + https://auronen.cokoliv.eu/gmc/genome/general_info/object_persistence/ 2024-06-30 daily + https://auronen.cokoliv.eu/gmc/genome/tools/ 2024-06-30 daily + https://auronen.cokoliv.eu/gmc/blog/ 2024-06-30 daily + https://auronen.cokoliv.eu/gmc/blog/community-news/introducing-community-posts/ 2024-06-30 daily + https://auronen.cokoliv.eu/gmc/blog/tutorials/guidelines-for-community-posts/ 2024-06-30 daily + https://auronen.cokoliv.eu/gmc/blog/category/community-news/ 2024-06-30 daily + https://auronen.cokoliv.eu/gmc/blog/category/tutorials/ 2024-06-30 daily + https://auronen.cokoliv.eu/gmc/blog/tags/ 2024-06-30 daily + https://auronen.cokoliv.eu/gmc/pl/ 2024-06-30 daily + https://auronen.cokoliv.eu/gmc/pl/notready/ 2024-06-30 daily + https://auronen.cokoliv.eu/gmc/pl/preferences/ 2024-06-30 daily + https://auronen.cokoliv.eu/gmc/pl/contribute/ 2024-06-30 daily + https://auronen.cokoliv.eu/gmc/pl/genome/ 2024-06-30 daily + https://auronen.cokoliv.eu/gmc/pl/genome/general_info/object_persistence/ 2024-06-30 daily + https://auronen.cokoliv.eu/gmc/pl/genome/tools/ 2024-06-30 daily + https://auronen.cokoliv.eu/gmc/pl/blog/ 2024-06-30 daily + https://auronen.cokoliv.eu/gmc/pl/blog/community-news/introducing-community-posts/ 2024-06-30 daily + https://auronen.cokoliv.eu/gmc/pl/blog/tutorials/guidelines-for-community-posts/ 2024-06-30 daily + https://auronen.cokoliv.eu/gmc/pl/blog/category/community-news/ 2024-06-30 daily + https://auronen.cokoliv.eu/gmc/pl/blog/category/tutorials/ 2024-06-30 daily + https://auronen.cokoliv.eu/gmc/pl/blog/tags/ 2024-06-30 daily + https://auronen.cokoliv.eu/gmc/cs/ 2024-06-30 daily + https://auronen.cokoliv.eu/gmc/cs/notready/ 2024-06-30 daily + https://auronen.cokoliv.eu/gmc/cs/preferences/ 2024-06-30 daily + https://auronen.cokoliv.eu/gmc/cs/contribute/ 2024-06-30 daily + https://auronen.cokoliv.eu/gmc/cs/genome/ 2024-06-30 daily + https://auronen.cokoliv.eu/gmc/cs/genome/general_info/object_persistence/ 2024-06-30 daily + https://auronen.cokoliv.eu/gmc/cs/genome/tools/ 2024-06-30 daily + https://auronen.cokoliv.eu/gmc/cs/blog/ 2024-06-30 daily + https://auronen.cokoliv.eu/gmc/cs/blog/community-news/introducing-community-posts/ 2024-06-30 daily + https://auronen.cokoliv.eu/gmc/cs/blog/tutorials/guidelines-for-community-posts/ 2024-06-30 daily + https://auronen.cokoliv.eu/gmc/cs/blog/category/community-news/ 2024-06-30 daily + https://auronen.cokoliv.eu/gmc/cs/blog/category/tutorials/ 2024-06-30 daily + https://auronen.cokoliv.eu/gmc/cs/blog/tags/ 2024-06-30 daily \ No newline at end of file diff --git a/sitemap.xml.gz b/sitemap.xml.gz index 24a4e97996..577c8f7d58 100644 Binary files a/sitemap.xml.gz and b/sitemap.xml.gz differ diff --git a/zengin/anims/events/index.html b/zengin/anims/events/index.html deleted file mode 100644 index 3e3b6af6dc..0000000000 --- a/zengin/anims/events/index.html +++ /dev/null @@ -1,265 +0,0 @@ - Events - Gothic Modding Community

Events

Acknowledgment

This tutorial was possible thanks to Kerrax, VAM and their excelent articles (MDS, EventTags) and Avallach from theModders who provided valuable insight.

Animation event block overview

We often need to perform some other actions together with our animation, such as playing a sound effect, inserting item into NPC's hand or changing an item instance into a different one, like turning a raw steel into hot raw steel. These actions often need to be done at very specific moment during the animation playback, therefore they are defined using events(#aniamtion-events) in the event block which follows right after the animation definition. The event block is started and closed by curly brackets.

Example:

1
-2
-3
-4
-5
-6
-7
-8
ani ("s_RunL" 1 "s_RunL" 0.0 0.1 M. "Hum_RunLoop_M01.asc" F 12 31) // animation
-{ // event block start
-
-    *eventSFXGrnd    (12    "Run") // animation event
-    *eventSFXGrnd    (24    "Run") // animation event
-    ...
-    *eventSFXGrnd    (30    "Run") // animation event
-} // event block end
-

Warning

Each animation can define a maximum of 16 events. Should you need more, split the animation into parts and use next_ani to chain them together.

Animation events

Animation events are commands telling engine to do something. Event *eventSFXGrnd(12 "Run") will command the engine to play sound Run at the very moment (12th frame) the character lands food on the ground. So with that in mind here is the general syntax as well as each animation event in the game.

General Syntax:

    *EVENTNAME (FRAME KEYWORD "INSTANCE" [OPTIONAL] [A:VALUE] [B:VALUE])
-

FRAME - all events specify on what frame int the animation source file .ASC should this event happen

KEYWORD - some events expect very specific keywords.

"INSTANCE" - this indicates parameter is expected to be inside quotes, usually it;s slot/bone or item/sound instance name from the scrips

[OPTIONAL] - this is an example of the optional parameter. Optional parameters will be indicated by brackets [], if you don't specify them, the event will use the default value defined by the engine.

A:VALUE - some events that have more than one optional parameter use a prefix to know which was specified

NODE_NAME - will indicate any NODE should work, be it bones (BIP01...) or ZS_ slots (ZS_RIGHTHAND)

SLOT - this will indicate most likely only ZS_ slots will work.

Warning

Events should follow in ascending order by the frame they appear on. i. e. *eventTag(1 ...) must come before *eventTag(2 ...)

Event Description
eventCamTremor camera shake
eventMMStartAni start morph-mesh
eventPFX create particle effect
eventPFXStop destroy particle effect
eventSwapMesh exchange item meshes between two slots
eventSFX create sound effect
eventSFXGRND create sound effect on the ground
eventTag generic event, does action specified in parameters
Defined in engine but never used ?
eventPFXGRND create particle effect on the ground
eventSetMesh ?
modelTag same as eventTag, but applies to morphmesh?

eventCamTremor

Earthquake effect (camera shake)

Example:

*eventCamTremor (12 1000    500   2  8 )
-

Syntax:

*eventCamTremor (FRAME RANGE DURATION MIN_AMPLIFIER MAX_AMPLIFIER)
-

eventCamTremor - is a keyword, for camera shake event

Let's describe all the parameters

FRAME - animation frame at which this event starts

RANGE - range from which the effect will be 'felt' defined in in-game centimeters (1000 is 10 meters in-game)

DURATION - duration of the effect in milliseconds

MIN_AMPLIFIER - minimum amount of shaking in in-game centimeters

MAX_AMPLIFIER - the maximum amount of shaking.

eventMMStartAni

Start the animation of the morph-mesh that is attached to the specified node. Mostly used to start NPC facial animations or to animate bows/crossbows shooting.

Example:

1
-2
-3
*eventMMStartAni    (14 "T_HURT")
-*eventMMStartAni    (6  "S_SHOOT"   "ZS_RIGHTHAND")
-*eventMMStartAni    (6  "S_BOOK_NEXT_PAGE"  "ZS_RIGHTHAND" I:0.5 H:5)
-

Syntax:

*eventMMStartAni (FRAME "ANI_NAME" ["NODE_NAME"] [I:INTENSITY] [H:HOLD_TIME])
-

FRAME - animation frame at which animation should start

ANI_NAME - name of the morph-mesh animation (specified in .MMS) file

NODE_NAME - node in the hierarchy, to which morph mesh is attached. If not specified, a default value of BIP01 HEAD will be used.

I:INTENSITY - float value to specify blending of morph animation with the current one ?

H:HOLD_TIME - time in seconds, how long will the animation "stay"

Both INTENSITY and HOLD_TIME can be specified in the MMS script. All gothic morph meshes specify those values in .MMS, therefore behavior when both specified in eventMMStartAni and .MMS file is unknown/untested

eventPfx

Start particle effect at the specified bone.

Example:

1
-2
*eventPFX   (12     "ZMODELLANDDUST"    "Bip01" )
-*eventPFX   (2  1   "DEMON_ATTACK"      "BIP01 R HAND"  ATTACH)
-

Syntax:

*eventPFX (FRAME [PFX_HANDLE] "PFX_NAME" "NODE_NAME" [ATTACH])
-

FRAME - animation frame at which particle effect starts

PFX_NAME - name of the PFX instance

PFX_HANDLE - an optional integer value. Specifying this creates a 'handle' and allows stop the PFX later using eventPFXStop

NODE_NAME - node in the hierarchy. particle effect will be spawned at the node's position. If not specified, a default value of BIP01 will be used.

ATTACH - keyword, including this keyword, will make particle effect follow the node specified, otherwise, it will stay where it spawned.

Tip

ATTACH is used to create demons burning hand during the attack, while without this keyword dust particles are made to stay at the position where NPC landed after falling.

eventPFXStop

Stops particle effect previously started by eventPfx

Example:

1
-2
-3
*eventPFX       (2  1   "DEMON_ATTACK"      "BIP01 R HAND"  ATTACH) // starts pfx with handle 1
-...
-*eventPFXStop   (70 1) // stops pfx started above
-

Syntax:

*eventPFXStop (FRAME PFX_HANDLE)
-

FRAME - animation frame at which particle effect should disappear

PFX_HANDLE - an integer value. Handle of the particle effect, that should be destroyed. Particle effect must be spawned using the same handle by eventPfx first

eventSwapMesh

Move mesh from source NODE to target node. Item should be present in the node already. Only mesh of the Items is moved, engine internally still keeps a reference to items in the original slot? Never used in game?

Example:

*eventSwapMesh (5 "ZS_CROSSBOW" "ZS_LEFTARM")
-

Syntax:

*eventSWAPMESH      (FRAME "SOURCE_NODE_NAME" "TARGET_NODE_NAME")
-

FRAME - animation frame at which transport of the mesh should happen

SOURCE_NODE_NAME - source node containing the item.

TARGET_NODE_NAME - target node that the item should be moved to.

Note

In some rare occasions duplicates item

eventSfx

Play sound effect. It can be either SFX instance from scripts, or .WAV file.

Example:

1
-2
-3
*eventSFX   (0  "Drown")
-*eventSFX   (8  "WHOOSH"    EMPTY_SLOT)
-*eventSFX   (8  "BAB_SIGH" R:5000   EMPTY_SLOT)   
-

Syntax:

*eventPFX (FRAME "SFX_NAME" [R:RANGE] [EMPTY_SLOT])
-

FRAME - animation frame at which particle effect starts

SFX_NAME - name of the SFX instance or .WAV file

R:RANGE - an optional integer value. The range from which the effect will be 'heard' defined in in-game centimeters (1000 is 10 meters in-game)

[EMPTY_SLOT] - optional keyword. By default audio effects use a single audio channel (slot) per Model. That means every eventSFX request will cancel any currently playing effect. If EMPTY_SLOT is specified, audio will be played on the next available (empty) audio slot and other sounds will not be interrupted.

Note

A lot of original game animations contain EMTPY_SLOT instead of EMPTY_SLOT which was probably unintended. Gothic therefore acts as no keyword was provided, which causes a lot of sound interruptions. Therefore be mindful of spelling when copying original MDS scripts

eventSfxGrnd

the same as eventSfx with only one difference, the sound effect name is appended with the current material name.

Example:

*eventSFXGrnd (12 "Run")
-

Syntax:

*eventSFXGrnd (FRAME "SFX_NAME" [R:RANGE] [EMPTY_SLOT])
-

Depending on the material of the texture, the character is standing on, the game will add one of the following suffixes:

Spacer Material Suffix Gothic 1 Gothic 2a
UNDEF _Undef ✔️ ✔️
EARTH _Earth ✔️ ✔️
SAND _Sand ✔️ ✔️
METAL _Metal ✔️ ✔️
WATER _Water ✔️ ✔️
WOOD _Wood ✔️ ✔️
SNOW _Snow ✔️
STONE _Stone ✔️ ✔️
default _Stone ✔️ ✔️

NPC running on grass texture, with material set to EARTH in world editor, will play sound Run_Earth by using *eventSFXGrnd (12 "Run") in run animation. _Earth suffix is determined and added by the engine.

eventTag

This is a generic type of event that does different actions based on the first parameter after the frame parameter. It was probably later in development to extend MDS functionality without the need to expand parser itself. All parameters except FRAME are passed inside quotes Further parameters are specific for every EVENT_TAG_TYPE.

Waning

eventTag contrary to other events is validated only at runtime. If parameters are wrong, it won't work or might crash the game

Syntax:

*eventTag (FRAME "EVENT_TAG_TYPE" "PARAMETER_1"  "PARAMETER_2" ... "PARAMETER_N")
-

FRAME - Frame at which the event will execute. This parameter is always first and the same for all eventTags

EVENT_TAG_TYPE - a type of event = action that should happen.

Here is a list of event tag types:

EVENT TAG TYPE Description
DEF_CREATE_ITEM Creates item into slot
DEF_INSERT_ITEM Inserts item to slot from inventory
DEF_REMOVE_ITEM Removes item from slot to inventory
DEF_DESTROY_ITEM Destroys item in slot
DEF_PLACE_ITEM ~~Places item from slot into mob slot~~ Destroys item in slot
DEF_EXCHANGE_ITEM Removes item in slot and replaces with new item
DEF_FIGHTMODE Sets npc into weapon stance
DEF_PLACE_MUNITION Inserts munition into slot
DEF_REMOVE_MUNITION Remove munition back to inventory
DEF_DRAWSOUND Plays weapon drawing sound based on weapon material
DEF_UNDRAWSOUND Plays weapon sheating sound based on weapon material
DEF_SWAPMESH Moves items visual to different slot visually
DEF_DRAWTORCH Inserts torch
DEF_INV_TORCH Moves torch to different slot temporarily
DEF_DROP_TORCH Drops torch from slot to world
DEF_HIT_LIMB Defines node which deals damage
DEF_DIR Defines attack direction
DEF_DAM_MULTIPLIER Defines damage mutliplier
DEF_PAR_FRAME Defines frame range for blocking
DEF_OPT_FRAME Defines damage frames
DEF_HIT_END Defines last frame to continue combo
DEF_WINDOW Defines frame for combo continuation

DEF_CREATE_ITEM

Creates a new item instance and inserts it into the specified slot. Item is not inserted permanently but only for the duration of interaction.

Example:

*eventTag    (4    "DEF_CREATE_ITEM"    "ZS_RIGHTHAND"    "ItMw_1H_Mace_L_04")
-

Syntax:

*eventTag (FRAME "DEF_CREATE_ITEM" "SLOT" "ITEM_INSTANCE")
-

SLOT - a name of the ZS_ slot, write in UPPERCASE

ITEM_INSTANCE - item instance from the scripts

Warning

This event tag most likely works only during Mob/Item interaction

DEF_INSERT_ITEM

Insert the interaction item into the specified slot.

  • during mob interaction, inserted item instance is of instance taken from UseWithItem mob property.
  • during item interaction (i.e. drink potion) item that started the SceneName will be inserted.

In the example below: (1) inserts ItMiSwordrawhot that is defined in spacer into ZS_LEFTHAND, then (2) spawns ItMw_1H_Mace_L_04 (hammer) into ZS_RIGHTHAND for anvil interaction.

Example:

1
-2
-3
-4
-5
ani    ("t_BSANVIL_S0_2_S1"    1    "s_BSANVIL_S1"    0.0    0.0    M.    "Hum_BSAnvil_Jue00.asc"    F    4    9)
-{
-    *eventTag    (4    "DEF_INSERT_ITEM"    "ZS_LEFTHAND")    // (1)
-    *eventTag    (4    "DEF_CREATE_ITEM"    "ZS_RIGHTHAND"    "ItMw_1H_Mace_L_04")    // (2)
-}
-

Syntax:

*eventTag (FRAME "DEF_INSERT_ITEM" "SLOT")
-

SLOT - a name of the ZS_ slot, use UPPERCASE

ITEM_INSTANCE - item instance from the scripts

Warning

This event tag most likely works only during Mob/Item interaction

The well-known Gothic bug:

If player gets hit while drinking a potion, the effect of the potion is applied, but the potion remains in the inventory - the reason for the bug is that the potion item is inserted into hand using DEF_INSERT_ITEM and would be removed from the world at the end of the drinking animation, while the potion's effect (a script function that increases stats) is applied at the very beginning of the animation. When the player is hit, the drinking animation is interrupted, and the engine does not remove the item from the world.

DEF_REMOVE_ITEM

Remove an item inserted into a slot via DEF_INSERT_ITEM from the slot back into the inventory.

Example:

*eventTag (0 "DEF_REMOVE_ITEM")
-

Syntax:

*eventTag (FRAME "DEF_REMOVE_ITEM")
-

Warning

This event tag most likely works only during Mob/Item interaction

DEF_DESTROY_ITEM

Destroys an item inserted into a slot via DEF_INSERT_ITEM. The item is removed from the world.

Example:

*eventTag (0 "DEF_DESTROY_ITEM")
-

Syntax:

*eventTag (FRAME "DEF_DESTROY_ITEM")
-

Warning

This event tag most likely works only during Mob/Item interaction

DEF_PLACE_ITEM

Remove the item inserted via eventTag DEF_INSERT_ITEM from the slot and the world. In terms of its action, eventTag DEF_PLACE_ITEM is a synonym for DEF_DESTROY_ITEM. Possibly fixed by SystemPack. See intended use.

Example:

*eventTag (0 "DEF_PLACE_ITEM")
-

Syntax:

*eventTag (FRAME "DEF_PLACE_ITEM")
-

Warning

This event tag most likely works only during Mob/Item interaction

Intended use

Presumably, the eventTag DEF_PLACE_ITEM was intended to have different behavior: If an NPC interacts with a MOB that has a ZS_SLOT node, then move the item inserted via DEF_INSERT_ITEM from the NPC node into the ZS_SLOT node on the MOB. An example would be orc priest hearts in the Temple of the Sleeper, Gothic 1.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
// Sleeper Portal
-ani ("t_SPORTAL_Stand_2_S0"     1    "s_SPORTAL_S0"     0.0    0.0    M.    "Hum_SleeperPortal_M01.asc"    F    0    19)
-ani ("s_SPORTAL_S0"             1    "s_SPORTAL_S0"     0.0    0.0    M.    "Hum_SleeperPortal_M01.asc"    F    20    20)
-ani ("t_SPORTAL_S0_2_Stand"     1    ""                 0.0    0.2    M.    "Hum_SleeperPortal_M01.asc"    R    0    19)
-ani ("t_SPORTAL_S0_2_S1"        1    "s_SPORTAL_S1"     0.0    0.0    M.    "Hum_SleeperPortal_M01.asc"    F    21    90    FPS:10)
-{
-    *eventTag    (60    "DEF_INSERT_ITEM"    "ZS_RIGHTHAND")    // (1)
-    *eventTag    (90    "DEF_PLACE_ITEM")    // (2)
-}
-ani ("s_SPORTAL_S1"             1    "s_SPORTAL_S1"     0.0    0.0    M.    "Hum_SleeperPortal_M01.asc"    F    91    91)
-ani ("t_SPORTAL_S1_2_Stand"     1    ""                 0.0    0.2    M.    "Hum_SleeperPortal_M01.asc"    F    90    100)
-

During animation on 60th frame,(1) inserts orc priest sword from the inventory, and (2) on 90th frame, presumably, should have left the sword inserted into the heart sticking out. There is ZS_SLOT present to indicate the location of the sword after insertion into the heart.

In reality, (2) simply removes the sword from the world like DEF_DESTROY_ITEM. This was most likely an unrealized idea. In G2, eventTag DEF_PLACE_ITEM is not used.

DEF_EXCHANGE_ITEM

Replace an item in a slot with another item. Item present in the slot is removed from the slot and the world, new item specified in parameters is created and inserted in the same slot.

Example:

*eventTag (37 "DEF_EXCHANGE_ITEM" "ZS_LEFTHAND" "ItMiSwordrawhot")
-

Syntax:

*eventTag (FRAME "DEF_EXCHANGE_ITEM" "SLOT" "ITEM_INSTANCE")
-

SLOT - a name of the ZS_ slot, use UPPERCASE

ITEM_INSTANCE - item instance from the scripts

Warning

This event tag most likely works only during Mob/Item interaction

DEF_FIGHTMODE

Set fight mode for the model. Used in transition animations to weapon stances like t_1h_2_1hRun.

Example:

*eventTag (5 "DEF_FIGHTMODE" "FIST")
-

Syntax:

*eventTag (FRAME "DEF_FIGHTMODE" "FIGHT_MODE")
-

FIGHT_MODE - fight modes are defined in the engine and can be one of the following:

  • "" - remove weapon
  • "FIST" - fists
  • "1H" or "1HS" - one-handed weapon
  • "2H" or "2HS" - two-handed weapon
  • "BOW" - bow
  • "CBOW" - crossbow
  • "MAG" - magic

Example: Parameter 1H sets fight mode for the actor (in the engine), but also exchanges sword from ZS_SWORD slot to the ZS_RIGHTHAND

DEF_PLACE_MUNITION

Place ammunition, from inventory such as an arrow into the specified slot. Used in reloading animations after a bow/crossbow shot.

Example:

*eventTag (9 "DEF_PLACE_MUNITION" "ZS_RIGHTHAND")
-

Syntax:

*eventTag (FRAME "DEF_PLACE_MUNITION" "SLOT")
-

SLOT - slot where the ammunition is created. There are only two valid slot names: "ZS_LEFTHAND" and "ZS_RIGHTHAND".

Ammunition always corresponds to the equipped ranged weapon instance and its munition field in the C_ITEM instance

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
instance ItRw_Sld_Bow(C_Item)
-{
-    name = "Лук";
-    mainflag = ITEM_KAT_FF;
-    flags = ITEM_BOW;
-    material = MAT_WOOD;
-    value = Value_SldBogen;
-    damageTotal = Damage_SldBogen;
-    damagetype = DAM_POINT;
-    munition = ItRw_Arrow;
-    cond_atr[2] = ATR_DEXTERITY;
-    cond_value[2] = Condition_SldBogen;
-    visual = "ItRw_Sld_Bow.mms";
-    description = name;
-    text[2] = NAME_Damage;
-    count[2] = damageTotal;
-    text[3] = NAME_Dex_needed;
-    count[3] = cond_value[2];
-    text[5] = NAME_Value;
-    count[5] = value;
-};
-

DEF_REMOVE_MUNITION

Remove ammunition previously placed by DEF_PLACE_MUNITION event

Example:

*eventTag (19 "DEF_REMOVE_MUNITION")
-

Syntax:

*eventTag (FRAME "DEF_REMOVE_MUNITION")
-

DEF_DRAWSOUND

Play weapon drawing sound. Determined by drawn weapon material field in the C_ITEM instance

  • “DrawSound_WO.wav” - for MAT_WOOD;
  • "DrawSound_ME.wav" - for MAT_METAL.

Example:

*eventTag (19 "DEF_DRAWSOUND")
-

Syntax:

*eventTag (FRAME "DEF_DRAWSOUND")
-

DEF_UNDRAWSOUND

Play weapon sheathing sound. Determined by drawn weapon material field in the C_ITEM instance

  • "UndrawSound_WO.wav” - for MAT_WOOD;
  • "UndrawSound_ME.wav" - for MAT_METAL.

Example:

*eventTag (19 "DEF_UNDRAWSOUND")
-

Syntax:

*eventTag (FRAME "DEF_UNDRAWSOUND")
-

DEF_SWAPMESH

Swap items in the specified slots.

Example:

*eventTag (5 "DEF_SWAPMESH" "ZS_CROSSBOW" "ZS_LEFTHAND")
-

Syntax:

*eventTag (FRAME "DEF_SWAPMESH" "SLOT1" "SLOT2")
-

SLOT1 - name of the slot with item to be exchanged.

SLOT2 - name of the slot with item to be exchanged.

Warning

In case SLOT1 or SLOT2 is equal to "ZS_LEFTHAND" or "ZS_RIGHTHAND", the engine will attempt to put the model into fight mode similar to DEF_FIGHTMODE event. This can lead to game freezing.

Tip

This event is similar to the *eventSwapMesh. The main difference is *eventSwapMesh will swap only visuals (meshes) of the items, while eventTag DEF_SWAPMESH will swap items and their slot references. After a game reload, meshes would reset their positions if swapped using *eventSwapMesh. Additionally *eventSwapMesh does not try to set the model into fight mode.

DEF_DRAWTORCH

Does nothing? never used.

Example:

*eventTag (5 "DEF_DRAWTORCH")
-

Syntax:

*eventTag (FRAME "DEF_DRAWTORCH")
-

DEF_INV_TORCH

Temporarily return torch into inventory, for the duration of mob/item interaction. Does nothing if a torch is not present in ZS_LEFTHAND. Used before interacting with mobs like bed, or before performing eating animations that require a left hand.

Example:

*eventTag (5 "DEF_INV_TORCH")
-

Syntax:

*eventTag (FRAME "DEF_INV_TORCH")
-

DEF_DROP_TORCH

Drop the torch onto the ground if present in ZS_LEFTHAND.

Example:

*eventTag (5 "DEF_DROP_TORCH")
-

Syntax:

*eventTag (FRAME "DEF_DROP_TORCH")
-

DEF_HIT_LIMB

Set which node is dealing damage to others. This node is then used in calculations for collisions. Up to four slots can be specified.

Example:

1
-2
-3
-4
-5
-6
// humans - fist attacks
-*eventTag (0     "DEF_HIT_LIMB"     "BIP01 R HAND")
-// humans - sword attacks
-*eventTag (0 "DEF_HIT_LIMB" "ZS_RIGHTHAND")
-// animals 
-eventTag (0 "DEF_HIT_LIMB"    "BIP01 HEAD")
-

Syntax:

*eventTag (FRAME "DEF_HIT_LIMB" "SLOT1" "SLOT2" "SLOT3" "SLOT4")
-

DEF_DIR

Set the direction of the attack. Enemy block animation is determined by this information. Not used.

Example:

1
-2
-3
*eventTag (0 "DEF_DIR"  "O")
-*eventTag (0 "DEF_DIR"  "L")
-*eventTag (0 "DEF_DIR"  "OUOL") // combo attack - top, under, 
-

Syntax:

*eventTag (FRAME "DEF_DIR" "DIRECTIONS")
-

DIRECTIONS - can be up to 10 characters, each character defines one attack direction during combo attack, default is O - capital letter O, not zero 0. Possible values are

  • O - (oben) from top/ over

  • U - (unter) from under

  • R - from right

  • L - from left

If the enemy is trying to block an attack with a defined direction it will choose a matching animation adding a direction suffix like t_1hParade_U for opponent's attack direction U

Note

Sadly this feature was unused in Gothic 1. All attacks use O direction and only defined animations for blocking are for said t_1hParade_O But can be easily restored with a few new animations and MDS file edits. In Gothic 2, blocking animation uses zero 0 instead of O which might indicate the feature no longer works.

DEF_DAM_MULTIPLIER

Set damage multiplier. For the attack animation. The damage will be multiplied by a provided number regardless of whether the attack is a critical attack or not.

Example:

1
-2
*eventTag (0 "DEF_DAM_MULTIPLIER"    "0.2")
-*eventTag (0 "DEF_DAM_MULTIPLIER"    "2.0")
-

Syntax:

*eventTag (FRAME "DEF_DAM_MULTIPLIER" "MULTIPLIER")
-

MULTIPLIER - float value inside quotes

DEF_PAR_FRAME

Set frame range during which damage is blocked. If not provided whole animation is blocking damage.

Example:

*eventTag (0 "DEF_PAR_FRAME"    "1 8")
-

Syntax:

*eventTag (FRAME "DEF_PAR_FRAME" "START_FRAME_END_FRAME")
-

START_FRAME_END_FRAME - Two integer numbers inside quotes. if "0 0" is provided, the animation will be blocking it's whole duration

DEF_OPT_FRAME

Set frames during which damage collisions should be evaluated. Damage is checked for collision with "hit limb". This event usually comes in pair with eventTags DEF_WINDOW and DEF_HIT_END

Example:

1
-2
*eventTag (0 "DEF_OPT_FRAME" "6") // on hit attack, hit on 6th frame
-*eventTag (0 "DEF_OPT_FRAME"  "6 30") // 2 attack combo, hit at 6th and 30th frame
-

Syntax:

*eventTag (FRAME "DEF_OPT_FRAME" "HIT_FRAME1 HIT_FRAME2 ... HIT_FRAME10")
-

HIT_FRAME1 HIT_FRAME2 ... HIT_FRAME10 - specify 1 and up to 10 integers separated by space inside quotes. Each number represents frame at which damage should be done. Number of provided hit frames determines number of combos (max 10 possible).

DEF_HIT_END

Set frames at which the combo is “cut off” if you do not press the “up” key (G1) or the left mouse button (G2) during the attack. Gothic has bug that in this case we will hear all the sound effects following this frame, and the animation ends with the character’s characteristic twitching. The number of frames specified in this entry must match the number of frames of the eventTag DEF_OPT_FRAME.

Example:

1
-2
*eventTag (0  "DEF_HIT_END"   "32") 
-*eventTag (0  "DEF_HIT_END"   "27 48 75")      
-

Syntax:

*eventTag (FRAME "DEF_HIT_END" "HIT_END1 HIT_END2 ... HIT_END10")
-

HIT_END1 HIT_END2 ... HIT_END10 - specify 1 and up to 10 integers separated by space inside quotes. After this frame combo cannot be continued and model will continue animation until the current DEF_WINDOW - 1`. Which is usually animation returning to idle stance

DEF_WINDOW

Set a “window” in the animation - an interval of frames during which you need to press the “up” (G1) or the left mouse button (G2) to continue the combo strike.

Example:

1
-2
*eventTag (0 "DEF_WINDOW"    "9 19") // one combo with window from 9-19 (can be chained)
-*eventTag (0  "DEF_WINDOW"    "10 23 32 41 58 70") // 3 combos with windows 10-23 then 32-41, 58-70
-

Syntax:

*eventTag (FRAME "DEF_WINDOW" "HIT_1_WINDOW_START HIT_1_WINDOW_END HIT_2_WINDOW_START HIT_2_WINDOW_END  ...")
-

HIT_1_WINDOW_START HIT_1_WINDOW_END HIT_2_WINDOW_START HIT_2_WINDOW_END - specify 1 and up to 20? integers separated by space inside quotes. A window consists of a start and end frame, therefore for each DEF_OPT_FRAME, you must provide 2 numbers.

  • HIT_WINDOW_START - First value of the pair defines frame from which attack can continue.
  • HIT_WINDOW_END - Second value is a little confusing. It defines START of the next attack animation. Ability to continue combo stops at DEF_HIT_END frames. Usually there are few frames of animation, where characters returns to idle position. HIT_WINDOW_END should be one frame after characters return to idle stance, which should also be first frame of the next attack

Attack eventTags explained

This is original attack combo from Gothic 1

1
-2
-3
-4
-5
-6
-7
-8
-9
ani ("s_1hAttack"   1   "s_1hAttack"    0.0 0.1 M.  "Hum_1hAttackComboT3_M05.asc"   F   1   114)
-{
-    *eventTag       (0 "DEF_HIT_LIMB"   "ZS_RIGHTHAND")
-    *eventTag       (0 "DEF_OPT_FRAME"  "4 36 73 107") 
-    *eventTag       (0 "DEF_HIT_END"    "31 63 95 113")
-    *eventTag       (0 "DEF_WINDOW"     "10 33 42 65 78 97 110 113")
-    *eventSFX       (4  "Whoosh"    EMPTY_SLOT  )
-    *eventSFX       (72 "BACK"  EMPTY_SLOT  )
-}
-

I will edit it slightly to make it more readable. Let's focus on the DEF_OPT_FRAME, DEF_HIT_END,

1
-2
-3
-4
-5
-6
-7
-8
ani ("s_1hAttack"   1   "s_1hAttack"    0.0 0.1 M.  "Hum_1hAttackComboT3_M05.asc"   F   1   114)
-{
-    ...
-    *eventTag       (0 "DEF_OPT_FRAME"  "4         36         73         107         ") 
-    *eventTag       (0 "DEF_HIT_END"    "      31         63       95             113")
-    *eventTag       (0 "DEF_WINDOW"     "   10   33     42  65   78  97     110   113")
-    ...
-}
-

Let's focus only on the first combo.

1
-2
-3
-4
-5
-6
-7
-8
ani ("s_1hAttack"   1   "s_1hAttack"    0.0 0.1 M.  "Hum_1hAttackComboT3_M05.asc"   F   1   114)
-{
-    ...
-    *eventTag       (0 "DEF_OPT_FRAME"  "4          ...") 
-    *eventTag       (0 "DEF_HIT_END"    "      31   ...")
-    *eventTag       (0 "DEF_WINDOW"     "   10   33 ...")
-    ...
-}
-
Frames Animation Description
1 animation start
1..4 swing of the sword
4 sword is in the front of the model DEF_OPT_FRAME - test damage collisions at this frame
4..10 end of the sword swing
10 model stands ready to start next swing DEF_WINDOW - user can press key to advance combo from this frame.
10..31 slight idle 'shake' if player continues combo, animation playback will jump to the frame 33 (DEF_WINDOW second pair), from the animation perspective, next attack starts from pose similar to frame 10. If perfect inputs would be provided, animation would continue perfectly.
31 DEF_HIT_END - ends user input.
31..32 model returns to the idle position
32 idle position, standing with sword in hand animation will end here, if combo not continued (DEF_WINDOW second pair - 1)
33 first frame of the next attack (similar to frame 10) DEF_WINDOW second pair, start of next attack

eventPfxGrnd

Not used anywhere in the original game. Could possibly spawn particle effect like eventPfx but with an added suffix similar to how eventSfxGrnd works. Needs to be investigated.

Syntax:

*eventPFXGRND (FRAME)
-

eventSetMesh

Unknown

Syntax:

*eventSETMESH (FRAME "NODE_NAME")
-

modelTag

Should work similarly to eventTag, but can be defined inside aniEnum block and applies to all animations of the Model.

Syntax:

*modelTag (FRAME "EVENT_TAG_TYPE" "PARAMETER1" "PARAMETER2" "PARAMETER3" "PARAMETER4" ... )
-
\ No newline at end of file diff --git a/zengin/anims/index.html b/zengin/anims/index.html deleted file mode 100644 index d5bd95fa38..0000000000 --- a/zengin/anims/index.html +++ /dev/null @@ -1,34 +0,0 @@ - Animation - Gothic Modding Community

Animation

Animations in ZenGin

Animations are (apart from maybe advanced programming work using Ikarus or Union) one of the most advanced modding techniques, since you not only must understand the way they work, but also know how to write the animation script and understand the whole scheme selection system, naming convention and of course know how to animate (that is my biggest problem :D). To get a new animation into ZenGin (the Gothic engine) is not difficult per se, I would describe it as tedious.

Luckily, there are tools to help us to achieve our goal - get a new animation to be used by the engine, and in effect, to be used and seen in the game.

To describe the whole process, I constructed this small tutorial, to help other people to get animations working and to spare them many hours of searching the excellent forum posts, that describe parts of the process.
__

Excluding advanced programming work with Ikarus or Union, animations are arguably the most advanced modding discipline of ZenGin engine. Its difficulty stems for the fact that you not only have to understand the general concept, but also learn how to write the animation scripts and understand the whole scheme selection system, including naming conventions and, most important for last - actually know how to animate. Adding new animations into ZenGin is more tedious than actually difficult.

There are tool to help with this endeavor - to get a new animation implemented in the engine, and seeing its effects in game. Following tutorial has been constructed to help others to get their animations working without having to scour old forum posts for hours.

Prerequisites - Tools & Materials

  1. Gothic Mod Development Kit (MDK)
    • Gothic 1 MDK - link
    • Gothic 2 MDK - link
  2. Blender
  3. Kerrax's Import Export plugin - follow the installation instructions to install the plugin, make sure to set up the texture paths too
  4. Tool for decompiling animations GothicSourcer, or use phoenix or write your own using ZenLib

The workflow

This is the basic step-by-step workflow on how to get the animation into the game.

  1. Load the actor (character or object) into your 3D software
  2. Create your animation
  3. Export the animation as an .asc file
  4. Write the MDS file
  5. Run the game to compile your animations
  6. Test your animations in-game using a Daedalus script or a console command

Sounds simple enough, except there is a lot missing. Even though the steps start with loading the actor into blender, understanding the system of animations to get high quality assets into your mod is more important.

Animation "types"

There are two main types of animations - skeletal and morphmesh animations. Character body animations are skeletal, and we animate the skeleton and the entire model (skin) moves around it. Morph mesh animation is, on the other hand, used for facial animations such as eating, blinking or talking and for animated meshes like wave water ferns or fish in Khorinis' harbor.

This guide focuses on skeletal animations. There are few different ones, all of which will have their own demonstration in the future. Categories are:

  1. Standalone animation - waving, bowing, eating
  2. MOBSI animations - bed, alchemy table, anvil
  3. Item animations - sweeping the floor with a broomstick, using the horn, playing the lute
  4. Mandatory animations - running, walking, sneaking
  5. Combined/interpolated animations - picking stuff up, aiming with a bow/crossbow

All of these animations are defined in an MDS file which will be talked about in the next sections.

\ No newline at end of file diff --git a/zengin/anims/mds/index.html b/zengin/anims/mds/index.html deleted file mode 100644 index c3d7931603..0000000000 --- a/zengin/anims/mds/index.html +++ /dev/null @@ -1,121 +0,0 @@ - MDS ModelScript - Gothic Modding Community

MDS - model animation script

Tip

The MDS syntax is very simple and scripts can be edited in any text editor. It is, however, easier to work in an editor with a proper syntax highlighting. Daedalus Language Server's dev branch already merged the MDS grammar for syntax highlighting, we can expect it in the next release.

Model animation script is a file describing what skeleton should be used, what body meshes work with this set of animations and how should the animations be named, how fast they run, what animation is supposed to start after the current one is finished and much more. These files are located in Gothic\_work\DATA\Anims\ directory.

Whilst the code seems long and terrifying, it is in fact rather simple, and this guide will try to explain it whole.

Don't forget to use the search

If you search this file for t_Yes, you will get an example of the first type of animation - "standalone"

To play the animation in game you use this console command play ani t_yes.

Syntax and keywords

Let us get a quick look at the naming convention to get a basic idea what is going on before we start.

The first letter indicates a type of animation (transition - t_ - or state - s_). Then depending on the animation type we have:

Transition animation

t_Run_2_Sneak
-
Transition animation from the run animation to the sneak animation.
t_BSANVIL_Stand_2_S0
-
Transition animation for the blacksmith's anvil from standing to state 0.

State animation

s_Run
-
State animation for the looping animation.
s_BSANVIL_S0
-
State animation for the blacksmith's anvil and its first state.

ani

This is the main command you will be using while defining new animations.

Example:

ani    ("t_Yes" 2 "" 0.1 0.1 M. "Hum_Yes_M01.asc" F 1 44)
-
Syntax:
ani (ANI_NAME LAYER NEXT_ANI BLEND_IN BLEND_OUT FLAGS ASC_NAME ANI_DIR START_FRAME END_FRAME)
-
ani - is a keyword, we are defining new animation

Let's describe all the parameters

ANI_NAME - animation name, we use it in Daedalus as animation identifier

There is a naming convention, that is recommended and sometimes required to be used.

  • prefix t_ - transition animations
  • prefix s_ - state animations - they usually run in a loop
  • prefix c_ - animations used for animation combining/interpolation

LAYER - layer number for multi-layer animations

NEXT_ANI - name of the next animations

BLEND_IN - time in seconds describing animation blending at the start

If we set it to 0.5, it takes 0.5 seconds for this animation to take full effect. At 0.0 s the previous animation has full effect on the bones of the skeleton, at 0.1 s it is influenced by 20% by this animation and at 0.5s it is completely influenced by this animation and the previous one has no effect.

BLEND_OUT - time in seconds describing animation blending at the end

FLAGS - flags, that describe animation behavior

  • M - specifies a movement animation, the animation of the model translates into a changed position in the game world
  • R - the same as M but for rotation
  • E - this flag makes this animation run only, if the animation in the same layer are finished, this is used in the movement animations. The animation s_walk (walking loop animation) runs, when the player is walking,when he stops the transition animation to standing state is played t_walk_2_stand. This animation uses the E flag to wait for the walk cycle animation to finish, to smoothly transition into the standing state.
  • F - the engine ignores height coordinate - doesn't keep the model "glued" to the ground (falling/flying animation)
  • I - specifies idle animation - breathing, standing with a drawn weapon and moving the weapon

ASC_NAME - name of the source file exported from Blender

ANI_DIR - direction of the animation

  • F - forward
  • R - reverse

START_FRAME - on what frame from the source file the animation starts

END_FRAME - on what frame from the source file the animation ends

aniAlias

Generally considered as one of the most useful commands, aniAlias is used to create an alias (hard link for UNIX users) for an already defined animation.

Example:

aniAlias ("t_Sneak_2_Run" 1 "s_Run" 0.0    0.1    M. "t_Run_2_Sneak" R)
-
Syntax:
aniAlias (ANI_NAME LAYER NEXT_ANI BLEND_IN BLEND_OUT FLAGS ALIAS_NAME ANI_DIR)
-

ANI_NAME - name of the new animation

LAYER - layer the animation is on

NEXT_ANI - name of the next animations

BLEND_IN - time in seconds describing animation blending at the start

BLEND_OUT - time in seconds describing animation blending at the end

FLAGS - flags, that describe animation behavior

ALIAS_NAME - name of the animation we want to use as a source for the alias

ANI_DIR - direction of the animation

If we look for the animation in the example we can see that there is a related one just one line above

1
-2
ani            ("t_Run_2_Sneak" 1 "s_Sneak" 0.1 0.0 M. "Hum_Sneak_M01.asc"     F 0 10)
-aniAlias    ("t_Sneak_2_Run" 1 "s_Run"      0.0 0.1 M. "t_Run_2_Sneak"      R)
-
In this example we are defining t_Sneak_2_Run animation and we are specifying that the animation after this one is finished will be s_Run and that it is being made by reversing animation t_Run_2_Sneak by specifying the R flag.

aniBlend

AniBlend is used to define animations that are a result of blending of two animations. This animation is not animated by hand, but it is dynamically generated by the engine during run-time.

Example

aniBlend ("t_RunR_2_Run" "s_Run" 0.2 0.2)
-
Syntax:
aniBlend (ANI_NAME NEXT_ANI BLEND_IN BLEND_OUT)
-

ANI_NAME - name of the new animation

NEXT_ANI - name of the next animations

BLEND_IN - time in seconds describing animation blending at the start

BLEND_OUT - time in seconds describing animation blending at the end

aniSync

Not used in the game.

aniBatch

Not used in the game.

Animation state machine

More complex animations such as MOBSI animations form a state machine - an animation set.

MDS script for the big chest
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
Model ("CHESTBIG_OCCRATELARGE")
-{
-    meshAndTree ("CHESTBIG_OCCRATELARGE.asc")
-
-    aniEnum
-    {
-// Closed chest
-        ani         ("s_S0"                 1   "s_S0"  0.0 0.0 M.  "CHESTBIG_USE.asc"  F   20  20)
-// Opening the chest 
-        ani         ("t_S0_2_S1"            1   "s_S1"  0.0 0.0 M.  "CHESTBIG_USE.ASC"  F   50  79)
-        {
-            *eventSFX   (50 "chest_try")
-            *eventSFX   (55 "chest_open")
-        }
-// Opened chest
-        ani         ("s_S1"                 1   "s_S1"  0.0 0.0 M.  "CHESTBIG_USE.asc"  F   80  80)
-// Closing the chest
-        ani         ("t_S1_2_S0"            1   "s_S0"  0.0 0.0 M.  "CHESTBIG_USE.asc"  R   50  79)
-        {
-            *eventSFX   (78 "chest_close")
-        }
-// Pick lock broken
-        ani         ("t_S0_Try"             1   "s_S0"  0.0 0.0 M.  "CHESTBIG_USE.asc"          F   96  124)
-        {
-            *eventSFX   (100    "chest_try")
-            *eventSFX   (115    "Hammer")
-        }
-    }
-}
-
stateDiagram-v2
-    s_S0      : Closed chest
-    t_S0_2_S1 : Opening the chest
-    s_S1      : Opened chest
-    t_S1_2_S0 : Closing the chest
-    t_S0_Try  : Pick lock broken
-    [*] --> s_S0
-    s_S0 --> s_S0
-
-    s_S0 --> t_S0_2_S1
-    t_S0_2_S1 --> s_S1
-    s_S1 --> s_S1
-
-    s_S1 --> t_S1_2_S0
-    t_S1_2_S0 --> s_S0
-
-    s_S0 --> t_S0_Try
-    t_S0_Try --> s_S0
\ No newline at end of file diff --git a/zengin/anims/standalone_ani/index.html b/zengin/anims/standalone_ani/index.html deleted file mode 100644 index 40570b3c17..0000000000 --- a/zengin/anims/standalone_ani/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/zengin/anims/tutorials/standalone_animation/index.html b/zengin/anims/tutorials/standalone_animation/index.html deleted file mode 100644 index 41bf353b62..0000000000 --- a/zengin/anims/tutorials/standalone_animation/index.html +++ /dev/null @@ -1,88 +0,0 @@ - Standalone animation - Gothic Modding Community

Standalone animation

Acknowledgment

This tutorial would not be possible without the ZenGin documentation available in the mod-kit. Further credits also go to Mark56 who helped me understand animations in the first place, Fawkes and his request for me to do some animations for his excellent mod - Replay Mod, and last but not least Flosha from the Phoenix team who was the one for whom I offered to write this tutorial to help with the development of the Phoenix project.

Let us start with the easiest animation - a very simple gesturing animation.

Info

You can find some of the videos that are mentioned in the text below in this play-list.

Firstly we have to have the animation source files ready. Best way to decompile them is using Gothic Sourcer. In GothicSourcer you choose Tools > Decompiler models > Dynamic (MDS or MSB) and choose an MDS file of your choice - Humans.mds in our case and then click the decompile button.

Animating

Open Blender, File > Import > Kerrax ASCII model (.asc), navigate to the folder with your decompiled animation files and select HUM_BODY_NAKED0.ASC. This file contains the skeleton and skin model for human NPCs.

What bone hierarchy is this model using?

If you open the .mds file, you can see a command meshAndTree that specifies what model contains the skeleton. And there lies our answer:

1
-2
-3
Model ("HuS")
-{
-    meshAndTree ("Hum_Body_Naked0.ASC" DONT_USE_MESH)
-

A windows pops up and you can read some interesting information about the model you are about to import. We are interested in the fact that Completely replace current scene is ticked, we want to use Armature modifier, and we also want to Try to connect bones and Use sample meshes from folder. You should provide a path to a directory with the sample meshes - these are meshes for items, that usually go into slot bones. Lastly, the space transformation scale should be set to 0.01. This is because ZenGin works with centimeter units and one unit in Blender is a meter.

Click import and wait for the magic to happen.

This video shows a freshly imported model with all default meshes.

Note

If we now want to play (or edit) existing animation, we can now load it on top of this. Just as before File > Import > Kerrax ASCII model (.asc) and select different animation file (or armor file), for example Hum_SmokeHerb_Layer_M01.asc for an animation file.

Gothic characters are modular and you can change their heads on the fly, even during gameplay as seen in this amazing video from my dear friend and colleague Fawkes - Head changing. Let's add a head so that we can see how the whole body will behave while we are animating. File > Import > Kerrax ASCII model (.asc), navigate to your head model. You will have to decompile it like we did with the body itself. We will import HUM_HEAD_PONY.ASC. Please make sure to select the target bone for importing Bip01 Head, this will attach the head to the proper bone, just like the engine does it.

Now we have everything ready to start animating. The video shows the DopeSheet a nice way to edit keyframes.

DopeSheet

Blender's dope sheet can be used to copy entire sets of keyframes. It is useful if we want to create a looping animation.

We can import an animation into Blender as a base.

Tip

If you don't know the name of the animation, just go into the game and make your character perform the animation you want. While in MARVIN mode, you can press G and the animation information together with other info will be displayed right on the screen

In this video we can see that the idle standing animation is s_run. We want to make an animation that is going to start from this idle animation, so we will import it into blender. We find it by looking into the .mds file, look for s_run name and get the name of the file.

ani    ("s_Run" 1 "s_Run" 0.1 0.1 MI "Hum_RunAmbient_M01.asc" F 1 50)  
-
As we can see, we have to import the Hum_RunAmbient_M01.asc file.

Next goes the first trick. Since we want our animation to end exactly, as it started - ether because we want the hero to continue his standing animation, or we want to make a looping animation, we somehow have to copy the pose. We use the DopeSheet screen, to delete all keyframes and then copy the keyframe set from keyframe number 0 and drag it somewhere to the end of the timeline.

Once the animation is done, we have to export it into an asc format again, File > Export > Kerrax ASCII model (.asc) and then save it to _work\data\Anims\asc\ so the engine can see it and convert it.
There are many options here that we will explore later, but we have tick Export animation and pick bones that we want to export - this is useful for animations that are played on different layers (dialogue gestures, scratching head, scratching a shoulder,...).

Animation script

Now that we have exported the animation, we now have to define it in Humans.mds.

Open the file, scroll to the end and define a new animation.

Attention

All ani code has to be between the curly brackets, this means you have to insert it before the last two closing curly brackets } }.

Example:

ani ("t_backpain" 1 "" 0.0 0.0 M. "Hum_back.ASC" F 0 121)  
-

Save the Humans.mds file and try it in game. Nothing happens! The reason is that the mds has been already compiled, and we have to recompile it. The easiest is to go to Anims\_compiled and delete HUMANS.MSB.
Run the game and try to play the animation again (play ani t_backpain in MARVIN console) and now everything should work.

Amazing, now you have your first animation in the game. And you can use it to do some fun stuff, like in dialogues using the AI_PlayAni function.

Example dialogue

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
instance DIA_Xardas_Back (C_INFO)
-{
-    npc         = NONE_100_Xardas;
-    nr          = 11;
-    condition   = DIA_Xardas_Back_Condition;
-    information = DIA_Xardas_Back_Info;
-    permanent   = TRUE;
-    description = "What's wrong?";
-};
-
-func int DIA_Xardas_Back_Condition () {
-    return TRUE;
-};
-
-func void DIA_Xardas_Back_Info () {
-    AI_Output (self, hero, "DIA_Xardas_MOB_14_00"); // My back hurts so much.
-
-    // This is our animation!!!!!
-    AI_PlayAni(self, "T_BACKPAIN"); 
-    AI_Output (self, hero, "DIA_Xardas_MOB_14_01"); // How do YOU feel?
-
-    AI_Output (hero, self, "DIA_Xardas_MOB_14_02"); // My back is fine.
-    AI_StopProcessInfos(self);
-};
-

\ No newline at end of file diff --git a/zengin/general_info/directory_structure/index.html b/zengin/general_info/directory_structure/index.html deleted file mode 100644 index 138769c747..0000000000 --- a/zengin/general_info/directory_structure/index.html +++ /dev/null @@ -1,81 +0,0 @@ - Directory structure - Gothic Modding Community

ZenGin directory structure

Modding is all about changing the game files. To achieve that, we have to know the directory (folder) structure of a Gothic game.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
├── Data
-│   ├── $Templates$
-│   ├── modvdf
-│   └── Plugins
-├── Miles
-├── Saves
-├── System
-│   └── Autorun
-└── _work
-    └── DATA
-        ├── Anims
-        │   └── _Compiled
-        ├── Meshes
-        │   └── _Compiled
-        ├── Music
-        ├── Presets
-        ├── Scripts
-        │   ├── _compiled
-        │   └── content
-        │       └── CUTSCENE
-        ├── Sound
-        ├── Textures
-        ├── Video
-        └── Worlds
-

Data

Data directory contains .vdf volumes of the game. These contain anims.vdf - animations, speech.vdf - dubbing, worlds.vdf - world ZEN files.

Saves

Contains saved games.

System

The system directory contains the game executable, GothicStarter.exe, GothicStarter_mod.exe, configuration .ini files, mod .ini files and mod icons and description .rtf files.

system/Autorun is a Union specific directory, it serves as a default search directory for Daedalus injection scripts with zParserExtender and Union plugins.

_work/DATA

This is where the magic happens:

  • Anims - contains animations and animated models.
    • _compiled - contains compiled animations.
  • Meshes - contains meshes source and compiled files.
    • _compiled - contains compiled meshes.
  • Music - contains music files.
  • Presets - contains basic presets.
  • Scripts
    • _compiled - contains compiled scripts - .dat files.
    • Content - contains scripts that make up the content of the game.
    • System - contains scripts that make up the menu.
  • Sound - contains sound effects .wav or .ogg format (Union only).
  • Video - contains videos in .bik format.
\ No newline at end of file diff --git a/zengin/general_info/object_persistence/index.html b/zengin/general_info/object_persistence/index.html deleted file mode 100644 index 2e7269dbe6..0000000000 --- a/zengin/general_info/object_persistence/index.html +++ /dev/null @@ -1,376 +0,0 @@ - Object persistence - Gothic Modding Community

Object persistence

In order to simplify the process of loading and saving data of various types to and from the user's hard-drive, ZenGin implements a simple object persistence system using the zCArchiver class and its derivatives that allow the individual engine classes to implement a routine specifying which data should be saved or loaded from disk and in which manner.

An object that is derived from the zCObject class may overload the Archive and Unarchive virtual methods. The class may then call on an interface provided by the zCArchiver class within these methods which allows it to directly read from or write to a stream using several modes. Those are ASCII and BinSafe by default. There are, however, more options, as is explained below.

Archive format

In order to better understand how this process works, it would be best to look at an example of a .ZEN file containing an instance of an oCWorld object.

When you open up a ZenGin archive, you will see the following at the start of the file:

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
ZenGin Archive
-ver 1
-zCArchiverGeneric
-ASCII
-saveGame 0
-date 7.1.2001 23:9:19
-user roeske
-END
-objects 2594     
-END
-

Let's look at each of these properties and what they mean:

ZenGin Archive

This simply specifies that the following data is an zCArchiver archive.

ver 1

Version specification. Can be either 0 or 1. Both Gothic 1 and 2 are already on version 1, although version 0 archives can also be occasionally found.

zCArchiverGeneric

Specifies which derived zCArchiver class should be used to read this archive. Accepted values are zCArchiverGeneric for ASCII and Binary archives, and zCArchiverBinSafe for BinSafe archives. More info below.
This property might not be present in older archives.

ASCII

This is the most important part of the header as it specifies in which format should the data be stored. There are 4 different modes:

  • ASCII - The simplest one. It stores data in human-readable ASCII notation (not unlike JSON for example). This is usually used when saving data during development and/or testing, while the final version of said data will most likely be stored as BIN_SAFE.
  • ASCII_PROPS - Same as ASCII except with more additional data that the developer can specify for visual clarity. In practice, it is not used anywhere and mostly serves only to prettify debug info (try typing ZWORLD VOBPROPS in the console and look in zSpy ;) ).
  • BINARY - Binary representation of the class instance, which mostly copies the data 1:1 into/from the stream. In practice, this format is only used to store savefiles (.SAV).
  • BIN_SAFE - BinSafe, short for Binary Safe, is an extended version of Binary which stores type information along with the data itself. This is meant to make error checking for invalid data easier. There are other changes which are explained below. Most, if not all world files (.ZEN), are stored in this format.

saveGame 0

Specifies if this archive is a savefile. This property might not be present in older archives.

date 7.1.2001 23:9:19

The date at which this archive was created.

user roeske

The user which created the archive. This property might not be present in older archives.

END

Tells the parses that this is the end of the header.

We may additionally find a property called csum in version 0 archives which stores the checksum of the whole archive. This property is, however, unused and equals 00000000 by default.

In order to correctly read the archive's header across varying engine versions, one should not count on the properties always being in the same order or even being there at all.

If the archive utilizes zCArchiverGeneric then this header will also be followed by a short section specifying the number of object instances in this archive. This value will be used to initialize the objectList, which is an array of pointers where the addresses of loaded objects will be stored for later referencing. This property would be directly part of the main header in older versions.

objects 2594 END  
-

If the archive is created using zCArchiverBinSafe, this data will be stored in the following binary structure:

1
-2
-3
-4
struct BinSafeArchiveHeader  
-{  
-    uint32_t version;     // Always equals 2 uint32_t objectCount;  // Serves the same function as "objects n" uint32_t chunkPos;    // Offset to chunk hash table};
-};  
-

Contents

Looking further into the archive, we see what appears to be a nested structure.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
[% oCWorld:zCWorld 64513 0]
-    [VobTree % 0 0]
-        childs0=int:1
-        [% zCVobLevelCompo:zCVob 12289 1]
-            pack=int:0
-            presetName=string:
-            bbox3DWS=rawFloat:-71919.9609 -13091.8232 -59900 108999.992 20014.0352 67399.9922 
-            trafoOSToWSRot=raw:0000803f0000000000000000000000000000803f0000000000000000000000000000803f
-            trafoOSToWSPos=vec3:0 0 0
-            vobName=string:LEVEL-VOB
-            visual=string:SURFACE.3DS
-            showVisual=bool:0
-            visualCamAlign=enum:0
-            cdStatic=bool:1
-            cdDyn=bool:0
-            staticVob=bool:0
-            dynShadow=enum:0
-            [visual zCMesh 0 2]
-            []
-            [ai % 0 0]
-            []
-        []
-        ...
-

We primarily differentiate between chunks and properties within ZenGin archives:

Chunks

A chunk is a structure that groups properties together. For most of the time, a chunk represents a class instance. This is, however, not always true as classes may arbitrarily create chunks as is needed. For example, the sample above contains a chunk called VobTree, which does not represent a class instance, but only serves to make the reading of the archive easier.

While in ASCII mode, the start of a chunk is represented using square brackets.

[% oCWorld:zCWorld 64513 0]

There are 4 pieces of data separated by spaces inside the start of each chunk, which are:

  • Object name - The name of the chunk to use while reading. If the chunk has no name, then it will be simply equal to %.
  • Class name - The name of the class which this chunk represents. Class names are stored with their full inheritance hierarchy (e.g. oCMobLadder:oCMobInter:oCMOB:zCVob). In case the chunk is not an object, but an arbitrary chunk, then this field will be equal to % (% can also mean that this chunk is a nullptr). In some cases you may encounter the symbol § instead. This means that the object already exists and that the parser should look for it in the objectList using the object index. Using this mechanism, a single instance can be referenced multiple times without worrying about duplicity.
  • Class version - Used to ensure that the data being read is compatible with the current game/engine version, so that there are no mismatches in the data pattern. This value is different for every class and varies between game versions.
  • Object index - An index into the objectList under which this object will be stored. If the class name is equal to §, then this value will be used to retrieve an existing instance from the objectList.

If this is a Binary archive, the same data will be stored in the following binary structure:

1
-2
-3
-4
-5
-6
-7
-8
struct BinaryObjectHeader
-{
-    uint32_t    objectSize;        // Size of the whole object in bytes
-    uint16_t    classVersion;
-    uint32_t    objectIndex;
-    char        objectName[];    // Null-terminated string
-    char        className[];    // Null-terminated string
-};
-

Oddly enough, if the archive is BinSafe, then the data will be encoded the same way as in ASCII mode, except that it will be stored as a type-checked property.

1
-2
-3
-4
-5
-6
struct BinSafeObjectHeader
-{
-    uint32_t    type;    // 0x1 = TYPE_STRING
-    uint16_t    length;    // Length of the text
-    char        text[];    // [% oCWorld:zCWorld 64513 0]
-};
-

In ASCII mode [] represents the end of the current chunk.

Properties

We find properties inside the chunks which are key-value pairs that classes use to store the actual data. Each property stores its name, type and value. In ASCII mode the format for this isname=type:value.

For example:

visual=string:SURFACE.3DS

By default, zCArchiver allows to store properties of the following types:

  • Int - A regular 32-bit integer. In ASCII mode, int gets stored as name=int:1, while in Binary mode, it's just the raw value stored as 4 bytes.

  • Byte - A 8-bit integer. ASCII mode doesn't differentiate between Int and Byte, so this will be stored as name=int:1 regardless. Binary mode stores only the single byte.

  • Word - A 16-bit integer. ASCII mode doesn't differentiate between Int and Word, so this will be stored as name=int:1 regardless. Binary mode stores only the 2 bytes.

  • Float - A standard IEEE 754 32-bit floating point number. In ASCII mode the format is name=float:1.0, while in Binary mode the float gets stored raw as 4 bytes.

  • Bool - Stores a single-byte boolean value. In ASCII mode its name=bool:1 and in Binary mode it's a single byte.

  • String - An ASCII encoded string. While in ASCII mode, strings are stored as name=string:value. In Binary mode, strings are NULL terminated.

  • Vec3 - A three component vector, mainly used to store positional data. The ASCII mode format is name=vec3:1.0 1.0 1.0. In Binary mode the three components of the vector are stored in series, which equals to a total size of 12 bytes.

  • Color - A 32-bit color value stored as BGRA. In ASCII mode the color is stored as name=color:255 255 255 255 while in Binary mode it's just 4 raw bytes.

  • Raw - Raw binary data. In order to maintain readability, in ASCII mode this gets stored as a hex encoded string such as name=raw:63D15B07. In Binary mode, only the data itself is stored, without any other info. Be aware that due to this you must know the size of the data beforehand.

  • RawFloat - An array of floats, mainly used to store bounding boxes. In ASCII mode, the floats are stored as name=rawFloat:1.0 1.0 1.0 1.0 1.0 1.0. In Binary mode the floats are stored in series as raw bytes. Same as with Raw, you must know the size of the array beforehand.

  • Enum - An enum value. In ASCII mode, it gets stored as name=enum:1. In Binary mode, it behaves the same as Int.

As you might have noticed, binary mode doesn't perform any kind of checks on if it's reading the right property or even data of the correct type. This is why BinSafe mode exists, as it stores the property type in along with the data itself.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
-37
-38
-39
-40
-41
-42
-43
enum TYPE
-{
-    TYPE_STRING        = 0x1,
-    TYPE_INTEGER    = 0x2,
-    TYPE_FLOAT        = 0x3,
-    TYPE_BYTE        = 0x4,
-    TYPE_WORD        = 0x5,
-    TYPE_BOOL        = 0x6,
-    TYPE_VEC3        = 0x7,
-    TYPE_COLOR        = 0x8,
-    TYPE_RAW        = 0x9,
-    TYPE_RAWFLOAT    = 0x10,
-    TYPE_ENUM        = 0x11
-    TYPE_HASH        = 0x12,
-};
-
-struct BinSafeProperty
-{
-    TYPE type;
-    union
-    {
-        struct
-        {
-            uint16_t    stringLength;
-            char        stringValue[];
-        }
-        uint32_t    integerOrHashOrEnumValue;
-        float        floatValue;
-        uint8_t        byteOrBoolValue;
-        zVEC3        vec3Value;
-        zCOLOR        colorValue;
-        struct
-        {
-            uint16_t    rawLength;
-            char        rawValue[];
-        }
-        struct
-        {
-            uint16_t    rawFloatLength;
-            float        rawFloatValue[];
-        }        
-    };
-};
-

Looking at the enumeration of types, you might notice that BinSafe mode has an additional property type called Hash. BinSafe archives include a hash table which is stored in the following manner:

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
struct BinSafeHashTable
-{
-    uint32_t chunkCount;
-    for (chunkCount)
-    {
-        uint16_t    stringLength;
-        uint16_t    linearValue;
-        uint32_t    hashValue;
-        char        text[stringLength];
-    }
-};
-

Instead of storing the raw value, properties may save a hash instead, which is then used to look up the corresponding value from the hash table.

Implementation

As mentioned in the opening paragraph, classes may use the described functionality by overloading the Archive and Unarchive virtual methods, which pass an instance of zCArchiver by reference. When the class instance is then serialized and/or parsed, these methods are called and perform the desired serialization/parsing work.

The class uses methods provided by the zCArchiver instance within these routines. These methods return/accept a value of a specific type (e.g. ReadInt/WriteInt), while they do the actual reading/writing work behind the scenes based on the current mode (ASCII/Binary/BinSafe). The programmer writing the class then does not care whether the final archive will be saved as ASCII, Binary or BinSafe, as they only use the zCArchiver Read* and Write* methods.

A practical example

Let's propose that we have a class which is declared like so:

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
class zCMyClass : public zCObject
-{
-public:
-
-    zCMyClass()                {}
-    virtual ~zCMyClass()    {}
-
-    virtual void Archive(zCArchiver&);
-    virtual void Unarchive(zCArchiver&);
-
-    int myInt;
-    zCMyClass* myObject;
-    zCMyClass* secondPointerToMyObject;
-
-};
-

The hypothetical class then implements these virtual functions:

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
void zCMyClass::Archive(zCArchiver& archiver)
-{
-    archiver.WriteInt("myInt", myInt);
-
-    archiver.WriteObject("myObject", myObject);
-
-    archiver.WriteChunkStart("myChunk", 0);
-    archiver.WriteObject("secondPointerToMyObject", secondPointerToMyObject);
-    archiver.WriteChunkEnd();
-}
-
-void zCMyClass::Unarchive(zCArchiver& archiver)
-{
-    archiver.ReadInt("myInt", myInt);
-
-    myObject = dynamic_cast<zCMyClass*>(archiver.ReadObject("myObject"));
-
-    archiver.ReadChunkStart("myChunk");
-    secondPointerToMyObject = dynamic_cast<zCMyClass*>(archiver.ReadObject("secondPointerToMyObject"));
-    archiver.ReadChunkEnd();
-}
-

We then initialize the class in the following way:

1
-2
-3
-4
-5
-6
-7
-8
zCMyClass object;
-
-object.myInt = 12121212;
-
-object.myObject = new zCMyClass();
-object.myObject->myInt = 34343434;
-
-object.secondPointerToMyObject = object.myObject;
-

If we now serialized, or to use the engine's term "archived", this instance into an ASCII archive, the result would look like this:

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
ZenGin Archive
-ver 1
-zCArchiverGeneric
-ASCII
-saveGame 0
-date 3.7.2022 0:0:0
-user GMC
-END
-objects 2     
-END
-
-[% zCMyClass 0 0]
-    myInt=int:12121212
-    [myObject zCMyClass 0 1]
-        myInt=int:34343434
-        [myObject % 0 0]
-        []
-        [myChunk % 0 0]
-            [secondPointerToMyObject % 0 0]
-            []
-        []
-    []
-    [myChunk % 0 0]
-        [secondPointerToMyObject § 0 1]
-        []
-    []
-[]
-

Notice how secondPointerToMyObject doesn't have any contents. The character § tells the parser that this object already exists in the objectList, and that instead of creating a new instance, it should return an existing instance which is stored under index 1 in the objectList.
This allows an instance to be referenced from multiple places, without the need to worry about duplicity.

If we used Binary or BinSafe mode, we would see a big blob of binary data instead. This would, of course, store the exact same data, although in a slightly less human-readable format.

Final thoughts

We hope this helps you better understand the inner workings of ZenGin. If you want to see how Piranha Bytes went about implementing a much more advanced version of this system for their next engine, check out Genome's object persistence system.

\ No newline at end of file diff --git a/zengin/general_info/vdfs/index.html b/zengin/general_info/vdfs/index.html deleted file mode 100644 index 464ae2505f..0000000000 --- a/zengin/general_info/vdfs/index.html +++ /dev/null @@ -1,34 +0,0 @@ - VDFS virtual file system - Gothic Modding Community

VDFS

VDFS is the virtual file system used by ZenGin to distribute and store many, but not all, game assets.

Tools

The community created variety of different modding tools for work with VDFS volumes over the times, such as:

GothicVDFS

  • Viewing
  • Extracting
  • Building .mod and .vdf archives

VDFS Tool

  • Viewing
  • Extracting
  • Building
  • Optimizing
  • Compressing .mod and .vdf archives
\ No newline at end of file diff --git a/zengin/index.html b/zengin/index.html deleted file mode 100644 index d2234bae53..0000000000 --- a/zengin/index.html +++ /dev/null @@ -1,34 +0,0 @@ - ZenGin - Gothic Modding Community

ZenGin

The game engine ZenGin is used by Gothic 1 and 2. This section contains the documentation of the various aspects of ZenGin modding.

\ No newline at end of file diff --git a/zengin/meshes/index.html b/zengin/meshes/index.html deleted file mode 100644 index 2ff555c573..0000000000 --- a/zengin/meshes/index.html +++ /dev/null @@ -1,34 +0,0 @@ - Meshes - Gothic Modding Community

Meshes

Everything about 3D models in ZenGin.

\ No newline at end of file diff --git a/zengin/music/index.html b/zengin/music/index.html deleted file mode 100644 index 1443cab6f4..0000000000 --- a/zengin/music/index.html +++ /dev/null @@ -1,34 +0,0 @@ - Music - Gothic Modding Community

Music

Zengin uses DirectMusic for playing in-game soundtrack. To edit Gothic music files you need the Direct Music Producer, a program released by Microsoft and provided with older DirectX SDK.

Warning

Music files can't be packed in the .vdf or .mod archives, all music files must be located in /_work/Data/Music directory.

File formats

The music directory contains these file types:

  • .dls - Downloadable Sound format file. This is the base for all other files. Contains:

    • Collections of virtual musical instruments.
    • Wave files instruments use.
  • .sty - Style file. Contains:

    • Bands - settings for virtual instruments from .dls.
    • Patterns - fragments of tracks, that can be later merged, looped and superimposed on each other
  • .sgt - File with properly connected patterns - the final track

Alternative Music System

The zBassMusic plugin replaces Zengin's default music library with the much newer BASS library. This allows, among other things, to play music in such formats as .mp3 or .ogg, and to pack songs into .vdf and .mod archives.

\ No newline at end of file diff --git a/zengin/scripts/classes/c_info/index.html b/zengin/scripts/classes/c_info/index.html deleted file mode 100644 index e90d7b9256..0000000000 --- a/zengin/scripts/classes/c_info/index.html +++ /dev/null @@ -1,228 +0,0 @@ - C_INFO - Gothic Modding Community

C_INFO Daedalus class

Acknowledgment

Heavily inspired by the amazing documentation site Gothic library.

The C_INFO class is used to define dialogues in the game.

Class definition

Class definition as it is defined in Scripts/Content/_intern/Classes.d script file.

C_Info Daedalus class
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
class C_Info
-{
-    var int    npc;         // npc instance has the dialogue
-    var int    nr;          // number of the dialogue (for sorting)
-    var int    important;   // should the npc start the dialogue automatically
-    var func   condition;   // condition function
-    var func   information; // function called on selecting the dialogue
-    var string description; // text in the dialogue box
-    var int    trade;       // should the dialogue show the trade window
-    var int    permanent;   // should the dialogue be permanent or only one time deal
-};
-

Class members

Variable Type Description
npc int npc instance to have the dialogue
nr int dialogue order number
important int npc addresses player automatically
condition func condition function whether the dialogue is shown or not
information func function called on dialogue selection - contains the dialogue lines and other logic
description string text shown in the dialogue box
trade int is it a trade dialogue
permanent int does the dialogue stay after being played once

Class member overview

Description of the class member variables.

npc

Sets what NPC will have this dialogue instance. Set an NPC instance.

1
-2
-3
-4
-5
instance Info_Diego_Gamestart (C_INFO)
-{
-    npc    = PC_Thief; // NPC instance for Diego
-    // ...
-};
-

nr

The nr member variables determines the order of shown dialogues. Dialogues are ordered in the ascending order - instances with higher nr are below instances with lower nr.

1
-2
-3
-4
-5
-6
instance Info_Diego_Gamestart (C_INFO)
-{
-    // ...
-    nr = 1;
-    // ...
-};
-

Note

This is why the end dialogues usually have nr = 999; this is the highest number out of any dialogues therefore will always show up at the bottom. (999 is not the highest number the nr can store, it is just considered the highest number, as there will hardly be 998 dialogue instances for a single character)

important

The important member variable determines whether the NPC will automatically address the player or not.

  • important = TRUE - the NPC will address the player
  • important = FALSE - the player has to talk to the NPC

When important is set to TRUE, the description is not needed since the dialogue is never shown in the dialogue box.

Info

If there are multiple important dialogues that satisfy their condition function, they will be played in the order specified by nr.

Tip

important variable is of the type integer, and it is initialized by the engine to the value of 0. If you do not want your dialogue to be important, you can omit the important member variable since it will be initialized to 0 by the engine.

condition

Condition function with signature func int f(). If the function returns TRUE the dialogue is displayed, if it returns FALSE it is not displayed. The function name does not have to follow a particular naming convention, but a naming convention is used throughout all the Gothic scripts: {DialogueName}_Condition.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
instance Info_Diego_Gamestart (C_INFO)
-{
-    // ...
-    condition = Info_Diego_Gamestart_Condition;
-    // ...
-};
-
-func int Info_Diego_Gamestart_Condition()
-{
-    if (Kapitel < 2) // Show only when chapter is less than 2
-    {
-        return TRUE;
-    };
-    return FALSE; // Not needed, but added for readability
-};
-
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
instance Info_Diego_EXIT_Gamestart(C_INFO)
-{
-    // ...
-    condition = Info_Diego_EXIT_Gamestart_Condition;
-    // ...
-};
-
-func int Info_Diego_EXIT_Gamestart_Condition()
-{
-    return TRUE; // or return 1;
-};
-

Tip

It is unnecessary to return FALSE from dialogue conditions, but in other cases it can very rarely cause subtle bugs. It is thus good practice to always return some value, even if that is FALSE.

information

The information function contains the function name (without double quotes "" as func is a type in Daedalus) that is called when the dialogue option is selected. It contains the lines NPCs will say, items that will be transferred, quests related logic and much more. The function name does not have to follow a particular naming convention, but a naming convention is used throughout all the Gothic scripts: {DialogueName}_Info.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
instance Info_Diego_Gamestart (C_INFO)
-{
-    npc         = PC_Thief;
-    nr          = 1;
-    condition   = Info_Diego_Gamestart_Condition;
-    information = Info_Diego_Gamestart_Info;
-    permanent   = FALSE;
-    important   = TRUE;
-};
-
-func int Info_Diego_Gamestart_Condition()
-{
-    if (Kapitel < 2)
-    {
-        return TRUE;
-    };
-    return FALSE;
-};
-
-func void Info_Diego_Gamestart_Info()
-{
-    AI_Output(self,hero,"Info_Diego_Gamestart_11_00"); //I'm Diego.
-    AI_Output(hero,self,"Info_Diego_Gamestart_15_01"); //I'm...
-    AI_Output(self,hero,"Info_Diego_Gamestart_11_02"); //I'm not interested in who you are. You've just arrived. I look after the new arrivals. That's all for now.
-    AI_Output(self,hero,"Info_Diego_Gamestart_11_03"); //If you plan to stay alive for a while, you should talk to me. But of course I won't keep you from choosing your own destruction. Well, what do you think?
-
-    B_Kapitelwechsel(1); // Show the chapter 1 screen
-};
-

description

Specify a string that will be shown in the dialogue window.

1
-2
-3
-4
-5
instance DIA_XARDAS_GMC(C_INFO)
-{
-    // ...
-    description = "Hello, is this the GMC site?";
-};
-

Description

trade

If trade is set to TRUE the trading interface will be launched after the content information function is finished.

Fisk's trade dialogue
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
instance  Stt_311_Fisk_Trade (C_INFO)
-{
-    npc         = Stt_311_Fisk;
-    nr          = 800;
-    condition   = Stt_311_Fisk_Trade_Condition;
-    information = Stt_311_Fisk_Trade_Info;
-    permanent   = TRUE;
-    description = "Show me your goods.";
-    trade       = TRUE;
-};
-
-func int  Stt_311_Fisk_Trade_Condition()
-{
-    return TRUE;
-};
-
-func void  Stt_311_Fisk_Trade_Info()
-{
-    AI_Output (other, self, "Stt_311_Fisk_Trade_15_00"); //Show me your goods.
-};
-

Trivia

Trade manager has been added to ZenGin not that long before the release of Gothic 1 (as discussed and discovered on Phoenix the Game Discord server with the acquisition of Gothic version 0.94k). In version 0.94 the trade manager worked quite differently and used a special (nowadays unused) Daedalus class C_ItemReact.

permanent

Dialogues with permanent = TRUE do not disappear after the dialogue is played. This is used for dialogues where you ask for directions or flavor dialogues for unnamed NPCs.

Bug

Frequently used external function Npc_KnowsInfo which returns true if the dialogue instance has been played has had a bug in the implementation for a long time. This bug made it impossible to use this function with dialogue instances with permanent = TRUE as it would always return FALSE. This has been fixed in Union 1.0m.

LeGo

LeGo implements a lot of useful functions for dialogues. It makes it possible to create Trialogues and change NPCs behaviour by Dialoggestures. Moreover, any Daedalus function can be added to NPCs AI queue via the AI_Function package.

zParserExtender

zParserExtender implements some Quality of Life features for dialogues. More information can be found in Dialogue constants article.

AF Script Packet

Enhanced Info Manager (implemented using Ikarus and LeGo) adds tons of customizations and additional features to dialogues. More information can be found in the AFSP Enhanced Information Manager article.

\ No newline at end of file diff --git a/zengin/scripts/classes/c_item/index.html b/zengin/scripts/classes/c_item/index.html deleted file mode 100644 index 5b89aae3c7..0000000000 --- a/zengin/scripts/classes/c_item/index.html +++ /dev/null @@ -1,369 +0,0 @@ - C_ITEM - Gothic Modding Community

C_ITEM Daedalus class

Acknowledgment

Heavily inspired by the amazing documentation site Gothic library

The C_ITEM class is used to define new items in the game.

Class definition

Class definition as it is defined in Scripts/Content/_intern/Classes.d script file.

C_Item Daedalus class
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
-37
-38
-39
-40
-41
-42
-43
-44
-45
-46
-47
-48
-49
-50
-51
-52
-53
-54
-55
-56
-57
-58
-59
-60
-61
-62
-63
-64
-65
-66
-67
-68
-69
-70
-71
-72
-73
-74
class C_Item
-{
-    // For all Items
-    var int    id;                         // ID of the item
-    var string name;                       // Name of the item
-    var string nameID;                     // Name ID
-    var int    hp;                         // Current health of the item
-    var int    hp_max;                     // Maximum health of the item
-
-    var int    mainflag;                   // Item category flag
-    var int    flags;                      // Item type flag
-    var int    weight;                     // Weight of the item
-    var int    value;                      // Value of the item
-
-    // For weapons
-    var int    damageType;                 // Damage type
-    var int    damageTotal;                // Total amount of damage
-    var int    damage[DAM_INDEX_MAX];      // Array of damage types
-
-    // For armours
-    var int    wear;                       // Flag to specify where to wear an item
-    var int    protection[PROT_INDEX_MAX]; // Protection array of different damage types
-
-    // For food
-    var int    nutrition;                  // The amount of HP healed
-
-    // Benötigte Attribute zum Benutzen des Items
-    var int    cond_atr[3];                // Array of NPC attributes needed to equip the item
-    var int    cond_value[3];              // Array of values corresponding to the cond_atr array
-
-    // Attributes to be changed on equip
-    var int    change_atr[3];              // Array of attributes that will be changed on equip
-    var int    change_value[3];            // Array of values of the attributes defined in change_atr
-
-    // Parser functions
-    var func   magic;
-    var func   on_equip;                   // Called on equpping an item
-    var func   on_unequip;                 // Called on unequipping an item
-    var func   on_state[4];
-
-    var func   owner;                      // Owner of the item: instance name
-    var int    ownerGuild;                 // Owner of the item: guild
-    var int    disguiseGuild;              // NPC guild set when equipping an item
-
-    // 3DS model file
-    var string visual;                     // Item model file
-
-    // NPC mesh change, when equipping an item
-    var string visual_change;              // .asc file
-    var string effect;                     // Effect instance
-
-    var int    visual_skin;                // Texture variation
-
-    var string scemeName;                  // Animation sceme name
-    var int    material;                   // Material of the object
-
-    var int    munition;                   // Ammo instance
-
-    var int    spell;                      // ID if the spell that this item does
-    var int    range;                      // Range of the weapon
-
-    var int    mag_circle;                 // Circle of magic needed to use this item
-
-    var string description;                // The name of the item shown in the preview box
-    var string text[ITM_TEXT_MAX];         // Array of string describing the item (left side)
-    var int    count[ITM_TEXT_MAX];        // Array of integers (the right side)
-
-    // Parameters for displaying items in the inventory
-    var int    inv_zbias                   // How far away is the item from the screen
-    var int    inv_rotx                    // X-axis rotation
-    var int    inv_roty                    // Y-axis rotation
-    var int    inv_rotz                    // Z-axis rotation
-    var int    inv_animate                 // Should the item rotate in the inventory
-};
-

It has many member variables but not all of them are used for every item. It is not necessary to define every one of these variables for every item as it was discussed on InsideGothic.

Class members

A selection of the most important class members.

change_atr & change_value

change_atr stores the attributes that will be changed by the amount specified in change_value.

NPCs have these attributes:

1
-2
-3
-4
-5
-6
-7
-8
-9
const int ATR_HITPOINTS      =  0;  // Hit points
-const int ATR_HITPOINTS_MAX  =  1;  // Max hitpoints
-const int ATR_MANA           =  2;  // Mana
-const int ATR_MANA_MAX       =  3;  // Max mana
-
-const int ATR_STRENGTH       =  4;  // Strength
-const int ATR_DEXTERITY      =  5;  // Dexterity
-const int ATR_REGENERATEHP   =  6;  // HP regeneration per second
-const int ATR_REGENERATEMANA =  7;  // Mana regeneration per second
-

This can be used on all equipable items to change the attributes. As an example we can create a sword that has a 10 point dexterity bonus.

1
-2
-3
-4
-5
-6
-7
instance ItMw_testSword (C_Item)
-{
-    // some code
-    change_atr[0]   = ATR_DEXTERITY;
-    change_value[0] = 10;
-    // some code
-};
-

Warning

Do not change ATR_HITPOINTS, ATR_MANA, ATR_HITPOINTS_MAX or ATR_MANA_MAX as it will result in unwanted behaviour with max health or max mana.

You can change ATR_HITPOINTS_MAX and ATR_MANA_MAX attributes in on_equip and on_unequip

cond_atr & cond_value

cond_atr stores the attributes that will be checked as a requirement to equip an item, the amount specified in cond_value.

The next example sword is equipable only if the NPC has at least 5 strength. If the requirements are not met G_CanNotUse() is called.

1
-2
-3
-4
-5
-6
-7
instance ItMw_testSword (C_Item)
-{
-    // some code
-    cond_atr[2]     = ATR_STRENGTH;
-    cond_value[2]   = 5;
-    // some code
-};
-

Try injecting the code below zParserExtender to test it in game right away. It is compatible with G2NotR.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
instance ItMw_testSword (C_Item)
-{
-    name            = TXT_Spells[10]; // demonstrates the usage of direct constr array access
-
-    mainflag        = ITEM_KAT_NF;
-    flags           = ITEM_SWD;
-    material        = MAT_METAL;
-
-    value           = 10;
-
-    damageTotal     = 10;
-    damagetype      = DAM_EDGE;
-    range           = 100;
-
-    cond_atr[2]     = ATR_STRENGTH;
-    cond_value[2]   = 5;
-
-    change_atr[0]   = ATR_DEXTERITY;
-    change_value[0] = 10;
-
-    visual          = "ItMw_010_1h_Sword_short_01.3DS";
-
-    description     = name;
-
-    TEXT[2]         = NAME_Damage;      COUNT[2] = damageTotal;
-    TEXT[3]         = NAME_Str_needed;  COUNT[3] = cond_value[2];
-    TEXT[4]         = NAME_OneHanded;
-    TEXT[5]         = NAME_Value;       COUNT[5] = value;
-};
-
To insert it into the game use insert ItMw_testSword in console.

text & count arrays

These two arrays are used to put information into the item information box. Text and Count The maximum number of lines is 6. This is defined in the engine, but for script side class definition is declared in the scripts too.

const int ITM_TEXT_MAX = 6;
-
This example shows an item with all elements of TEXT and COUNT array filled.

Note

Please notice the last COUNT element. It did not take the value we entered, but shows 10 which is the value of the item. This behaviour can be changed with Ikarus or Union.

Item example

You can find the code below

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
instance ItMw_testSword (C_Item)
-{
-    name          = TXT_Spells[10];
-
-    mainflag      = ITEM_KAT_NF;
-    flags         = ITEM_SWD;
-    material      = MAT_METAL;
-
-    value         = 10;
-
-    damageTotal   = 10;
-    damagetype    = DAM_EDGE;
-    range         = 100;
-
-    cond_atr[2]   = ATR_STRENGTH;
-    cond_value[2] = 5;
-
-    change_atr[0] = ATR_DEXTERITY;
-    change_value[0] = 10;
-
-    visual        = "ItMw_010_1h_Sword_short_01.3DS";
-
-    description   = name;
-
-    TEXT[0]       = "Line 0";     COUNT[0]      = 0; 
-    TEXT[1]       = "Line 1";     COUNT[1]      = 1; 
-    TEXT[2]       = "Line 2";     COUNT[2]      = 2; 
-    TEXT[3]       = "Line 3";     COUNT[3]      = 3; 
-    TEXT[4]       = "Line 4";     COUNT[4]      = 34;
-    TEXT[5]       = "Line 5";     COUNT[5]      = 35;
-};
-

description & name

description - determines the name of the item in the inventory

name - determines the focus name of the item in the world

In the scripts you often find that the description is assigned the value of name.

1
-2
-3
-4
-5
-6
-7
instance ItMw_testSword (C_Item)
-{
-    name = "New amazing sword";
-    // ...
-    description   = name; // description now has the same value as '    // ...name'
-    // ...
-};
-
This is used in the case where you want to show the name of the item on focus too.

There is a second way used in the scripts though with, for example,magic scrolls - the focus name in the world is "Scroll" and in inventory the scroll carries the name of the spell. This is how it is done:

1
-2
-3
-4
-5
-6
-7
instance ItSc_InstantFireball (C_Item)
-{
-    name                 =    NAME_Spruchrolle; // const string = "Scroll"
-    // ...
-    description            =     NAME_SPL_InstantFireball; // const string = "Fireball"
-    // ...
-};
-

hp & hp_max

Both of these parameters are unused.

Trivia

In alpha ZenGin versions the player was able to destroy objects. This feature was abandoned during the course of the development.
This video shows the reconstruction of this feature.

\ No newline at end of file diff --git a/zengin/scripts/classes/c_menu/index.html b/zengin/scripts/classes/c_menu/index.html deleted file mode 100644 index e145429aad..0000000000 --- a/zengin/scripts/classes/c_menu/index.html +++ /dev/null @@ -1,157 +0,0 @@ - C_MENU - Gothic Modding Community

C_MENU Daedalus class

Acknowledgment

Heavily inspired by the amazing documentation site Gothic library

Class C_Menu is responsible for the behavior and properties of the game menus (options, save etc.).

Class definition

Class definition as it is defined in Scripts/System/_intern/Menu.d script file.

C_Menu Daedalus class
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
class C_Menu 
-{
-    var     string  backPic;            // Menu background image
-    var     string  backWorld;          // Background ZEN-world of the game menu (Not used)
-    var     int     posx;               // The top left point of the menu on the screen horizontally (X-axis)
-    var     int     posy;               // The top left point of the menu on the screen vertically (Y-axis)
-    var     int     dimx;               // Menu width in virtual coordinates
-    var     int     dimy;               // Menu height in virtual coordinates
-    var     int     alpha;              // Menu transparency
-    var     string  musicTheme;         // Music track of the menu
-    var     int     eventTimerMSec;     // trigger time for the event EVENT_TIMER
-    var     string  items[150];         // Menu items
-    var     int     flags;              // Menu flags
-    var     int     defaultOutGame;     // Menu item highlighted by default when the game is not running
-    var     int     defaultInGame;      // Menu item highlighted by default when the game is running
-};
-

Class members

Variable Type Description
backPic string Menu background image
backWorld string Background ZEN-world of the game menu (Not used)
posx int The top left point of the menu on the screen horizontally (X-axis)
posy int The top left point of the menu on the screen vertically (Y-axis)
dimx int Menu width in virtual coordinates
dimy int Menu height in virtual coordinates
alpha int Menu transparency
musicTheme string Music track of the menu
eventTimerMSec int The timer that triggered the event in seconds
items string Menu items
flags int Menu flags
defaultOutGame int Menu item highlighted by default when the game is not running
defaultInGame int Menu item highlighted by default when the game is running

Class member overview

Description of the class member variables.

backPic

backPic is just a name of background image of the menu in .tga format.

backWorld

Deprecated setting

The background world of the game menu in .ZEN format.

posx

The horizontal position of the top left point of the menu on the screen, in virtual coordinates.

posy

The vertical position of the top left point of the menu on the screen, in virtual coordinates.

dimx

Menu width in virtual coordinates.

dimy

Menu height in virtual coordinates.

alpha

Menu transparency. Accepts values ​​from 0 to 255. Without the backPic property specified, the value of this parameter is ignored.

Note

Texture transparency can only be adjusted if the texture has an alpha channel.

musicTheme

Music theme of the menu.

1
-2
-3
-4
-5
-6
instance MENU_MAIN(C_MENU_DEF)
-{
-    ...
-    musictheme = "SYS_Menu";
-    ...
-};
-
All instances of musical themes are stored in a file Scripts/System/Music/MusicInst.d

eventTimerMSec

Defines the trigger time for the event EVENT_TIMER in seconds.

The list of constants for all menu events is described in the file Scripts/System/_intern/Menu.d

1
-2
-3
-4
-5
-6
-7
-8
-9
const int EVENT_UNDEF       = 0;    // Undefined
-const int EVENT_EXECUTE     = 1;    // Process start event
-const int EVENT_CHANGED     = 2;    // Menu parameter change event
-const int EVENT_LEAVE       = 3;    // Menu item focus loss event
-const int EVENT_TIMER       = 4;    // Timer fire event
-const int EVENT_CLOSE       = 5;    // Menu close event
-const int EVENT_INIT        = 6;    // Initialization event
-const int EVENT_SEL_PREV    = 7;    // Select event of the previous menu item
-const int EVENT_SEL_NEXT    = 8;    // Select event of the next menu item
-

items

An array of items belonging to this menu. It is possible to use up to 150 items in one menu. The same elements can be used for different menus. The element instance is specified as the value.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
// Menu
-instance MENU_MAIN(C_MENU_DEF)
-{
-    ...
-    items[0]        = "MENUITEM_MAIN_HEADLINE";         
-    items[1]        = "MENUITEM_MAIN_HEADLINE2";
-    items[2]        = "MENUITEM_MAIN_NEWGAME";
-    ...
-};
-
-// Menu elements: labels, checkboxes, sliders, etc.
-
-instance MENUITEM_MAIN_HEADLINE(C_MENU_ITEM_DEF)
-{
-    ...
-};
-
-instance MENUITEM_MAIN_HEADLINE2(C_MENU_ITEM_DEF)
-{
-    ...
-};
-
-instance MENUITEM_MAIN_NEWGAME(C_MENU_ITEM_DEF)
-{
-    ...
-};
-

flags

Menu flags.

The list of flag constants can be found in the file Scripts/System/_intern/Menu.d

1
-2
-3
-4
-5
-6
-7
const int MENU_OVERTOP          = 1;    // Show menu over previous menu or in game
-const int MENU_EXCLUSIVE        = 2;    // Close all previous menus. Only the active menu is displayed
-const int MENU_NOANI            = 4;    // No animation
-const int MENU_DONTSCALE_DIM    = 8;    // Don't Scale Menu Sizes
-const int MENU_DONTSCALE_POS    = 16;   // Empty flag
-const int MENU_ALIGN_CENTER     = 32;   // Center Align Menu
-const int MENU_SHOW_INFO        = 64;   // Display information at the bottom of the description menu from menu items text[1]
-
  • MENU_OVERTOP - Flag to display the menu over the previous menu. It is not advisable to use with a transparent menu.
  • MENU_EXCLUSIVE - Hide all menus except the active one. When closed, the previous menu is restored.
  • MENU_NOANI - Animation of minimizing and maximizing windows. The game is mainly used for dialogue windows. You can't enable or disable the animation of dialog windows through scripts. This is done using the animatedWindows setting in the Gothic.ini file.
  • MENU_DONTSCALE_DIM - Scale the menu to fit 640x480 resolution.
  • MENU_DONTSCALE_POS - Empty flag. Not used.
  • MENU_ALIGN_CENTER - Align the menu to the center of the screen.
  • MENU_SHOW_INFO - Display information at the bottom of menu description from menu item text[1].

defaultOutGame

The menu item that is highlighted by default when the game is not running.

A value of -1 enables automatic selection of the first selectable element.

Items with the ~IT_SELECTABLE flag are not selected.

defaultInGame

Menu item highlighted by default when the game is running.

A value of -1 enables automatic selection of the first selectable element.

Items with the ~IT_SELECTABLE flag are not selected.

\ No newline at end of file diff --git a/zengin/scripts/classes/c_musicsys_cfg/index.html b/zengin/scripts/classes/c_musicsys_cfg/index.html deleted file mode 100644 index 95b364a4e8..0000000000 --- a/zengin/scripts/classes/c_musicsys_cfg/index.html +++ /dev/null @@ -1,51 +0,0 @@ - C_MUSICSYS_CFG - Gothic Modding Community

C_MUSICSYS_CFG Daedalus class

Acknowledgment

Heavily inspired by the amazing documentation site Gothic library

Class C_MusicSys_CFG defines the global settings for the game's music.

An instance of this class is declared only once.

Class definition

Class definition as it is defined in Scripts/System/_intern/Music.d script file.

C_MusicSys_CFG Daedalus class
1
-2
-3
-4
-5
-6
-7
-8
-9
class C_MusicSys_CFG
-{
-    var float volume;               // Music volume
-    var int   bitResolution;        // Sound quality
-    var int   globalReverbEnabled;  // Enable global reverb
-    var int   sampleRate;           // Frequency
-    var int   numChannels;          // Sound channels
-    var int   reverbBufferSize;     // Reverb buffer size
-};
-

Class members

Variable Type Description
volume float Overall game music volume
bitResolution int Sound quality
globalReverbEnabled int Enable global reverb
sampleRate int Frequency
numChannels int Number of sound chanells
reverbBufferSize int The size of reverb buffer

Class member overview

Description of the class member variables.

volume

The overall volume of the background music (soundtrack). From 0.0 to 1.0.

bitResolution

Sound quality. 8 or 16 bit.

globalReverbEnabled

Enable global reverb.

sampleRate

Frequency. From 11050 to 44100.

numChannels

Number of sound channels. From 16 to 32.

reverbBufferSize

The size of the reverb buffer.

\ No newline at end of file diff --git a/zengin/scripts/classes/c_musictheme/index.html b/zengin/scripts/classes/c_musictheme/index.html deleted file mode 100644 index 9bb1fc452d..0000000000 --- a/zengin/scripts/classes/c_musictheme/index.html +++ /dev/null @@ -1,115 +0,0 @@ - C_MUSICTHEME - Gothic Modding Community

C_MUSICTHEME Daedalus class

Acknowledgment

Heavily inspired by the amazing documentation site Gothic library

Class C_MusicTheme describes musical themes.

Class definition

Class definition as it is defined in Scripts/System/_intern/Music.d script file.

C_MusicTheme Daedalus class
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
class C_MusicTheme
-{
-    var string      file;           // Sound file in DirectMusic `.sgt` format
-    var float       vol;            // Sound volume
-    var int         loop;           // Enable cycle
-    var float       reverbMix;      // Reverb mixing
-    var float       reverbTime;     // Reverb time
-    var int         transType;      // Type of transition to the next theme
-    var int         transSubType;   // Subtype of transition to the next theme song
-};
-

Class members

Variable Type Description
file string Sound file in DirectMusic .sgt format
vol float Sound volume
loop int Enable/disable cycle
reverbMix float Reverb mixing
reverbTime float Reverb time
transType int The type of transition to the next theme song
transSubType int The subtype of transition to the next theme song

Class member overview

Description of the class member variables.

file

DirectMusic sound in *.sgt format or MIDI file.

vol

The volume of the theme song. From 0.0 to 1.0.

loop

Enable/disable theme music looping. Disabled = 0. Enabled = 1.

reverbMix

Reverb mixing. Measured in decibels.

reverbTime

Reverberation time in milliseconds.

transType

The type of transition to the next theme song.

The list of constants for all transitions types is described in the file Scripts/System/_intern/Music.d

1
-2
-3
-4
-5
-6
-7
const int TRANSITION_TYPE_NONE          = 1;    // No transition
-const int TRANSITION_TYPE_GROOVE        = 2;    // Ripple
-const int TRANSITION_TYPE_FILL          = 3;    // Padding
-const int TRANSITION_TYPE_BREAK         = 4;    // Break
-const int TRANSITION_TYPE_INTRO         = 5;    // Introductory
-const int TRANSITION_TYPE_END           = 6;    // End topic
-const int TRANSITION_TYPE_ENDANDINTRO   = 7;    // End and start new
-

transSubType

The subtype of transition to the next theme song.

The list of constants for all transitions subtypes is described in the file Scripts/System/_intern/Music.d

1
-2
-3
const INT TRANSITION_SUB_TYPE_IMMEDIATE = 1;    // Instant transition
-const INT TRANSITION_SUB_TYPE_BEAT      = 2;    // Rhythmic transition
-const INT TRANSITION_SUB_TYPE_MEASURE   = 3;    // Gradual transition
-

Name features

The musical themes of the game are played depending on the game situation. By default, the theme with the _STD (standard) suffix is played. In case of a threat, the _THR (threat) theme will be played. During the combat the _FGT (fight) theme plays.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
instance WOO_DAY_STD(C_MUSICTHEME_STANDARD)
-{
-    file = "woo_daystd.sgt";
-};
-
-instance WOO_DAY_THR(C_MUSICTHEME_THREAT)
-{
-    file = "woo_daythr.sgt";
-};
-
-instance WOO_DAY_FGT(C_MUSICTHEME_FIGHT)
-{
-    file = "woo_dayfgt.sgt";
-};
-
In addition, the suffix _DAY_ and _NGT_ determines whether the theme should be played on day or night.
1
-2
-3
-4
-5
-6
-7
-8
-9
instance OWD_DAY_FGT(C_MUSICTHEME_FIGHT)
-{
-    file = "owp_dayfgt.sgt";
-};
-
-instance OWD_NGT_STD(C_MUSICTHEME_STANDARD)
-{
-    file = "owd_daystd.sgt";
-};
-

Tip

In G2 the C_MUSICTHEME_STANDARD, C_MUSICTHEME_THREAT and C_MUSICTHEME_FIGHT prototypes are used by default.

\ No newline at end of file diff --git a/zengin/scripts/classes/c_svm/index.html b/zengin/scripts/classes/c_svm/index.html deleted file mode 100644 index 6d532c2b33..0000000000 --- a/zengin/scripts/classes/c_svm/index.html +++ /dev/null @@ -1,77 +0,0 @@ - C_SVM - Gothic Modding Community

C_SVM Daedalus class

Acknowledgment

Heavily inspired by the amazing documentation site Gothic library

The C_SVM class is used to define sound dialogues (smalltalk, reactions) that are defined for every C_NPC.voice.

Class definition

C_SVM class is the only class with variable number of members. The C_SVM definition in the scripts dictates the content of the class. Every Gothic game has a different number of SVM entries. As an interesting information (more than anything else) we include a table with the numbers of voice lines and voices below.

Game voice lines voices
Gothic 1 136 17
Gothic Sequel 110 17 (30 planned)
Gothic 2 202 19
Gothic 2 Addon 235 19
Chronicles of Myrtana 1346 73
Returning New Balance 495 19

Rules

The number of instances is defined by a constant integer with a specified name read by the engine.

const int SVM_MODULES = 18;
-

Info

The value SVM_MODULES = 18 means 18 SVMs will be parsed by the engine and because the first one, SVM_0, is empty, the final number of voices is 18 - 1 = 17.

Instances of the C_SVM class must have the name SVM_XXX.

1
-2
-3
-4
instance svm_1(c_svm)
-{
-    // ...
-};
-
The first instance svm_0 is always empty, it is used internally by the engine.
instance svm_0(c_svm) {};
-

Usage in the scripts

While some defined SVMs are used automatically by the engine - the 20 smalltalk lines for example, others are used in the scripts.
To instruct the engine to run a specific SVM, external function AI_OutputSVM is used. In the original scripts it is wrapped in a script function B_Say.
To reference the SVM, you use the $ symbol followed by the name of the member variable in the C_SVM class definition.

1
-2
-3
-4
-5
-6
// some code
-    {
-        PrintScreen    ("Not enough skill points!", -1,-1,"FONT_OLD_20_WHITE.TGA",1);
-        B_Say (self, other, "$NOLEARNNOPOINTS");
-    };
-// some code
-
Here the $NOLEARNNOPOINTS references the var string NoLearnNoPoints in SVM.D. The voice is then chosen automatically by the engine.
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
class C_SVM
-{
-    //...
-
-    // Teacher comments
-    var string NoLearnNoPoints;       // NPC teacher doesn't teach - not enough learning points!
-    var string NoLearnOverMax;        // NPC teacher doesn't teach - cannot teach above 100 points!
-    var string NoLearnYouAlreadyKnow; // You have to know something to become a master!
-    var string NoLearnYoureBetter;    // You are better than the teacher!
-
-    //...
-};
-
\ No newline at end of file diff --git a/zengin/scripts/extenders/afsp/afsp_eim/index.html b/zengin/scripts/extenders/afsp/afsp_eim/index.html deleted file mode 100644 index 9bacf41841..0000000000 --- a/zengin/scripts/extenders/afsp/afsp_eim/index.html +++ /dev/null @@ -1,469 +0,0 @@ - Enhanced Info Manager - Gothic Modding Community

Enhanced Information Manager

Warning

This is a quick paste-in of and old version of AFSP's documentation and the information should be taken with a grain of salt. It may not be up-to-date since AFSP is being developed all the time and this is only a demo page.

Enhanced Information Manager allows you to more precisely control the Information Manager (dialogue manager). Change color, font and much more! This package "scans" the dialogue string for modifiers and alters the string based on the modifiers you specify.

Initialization

To use this feature you have to:

  1. Add _headers_G[1/2]_EnhancedInfoManager.src or _headers_G[1/2]_All.src to your Gothic.src after Ikarus and LeGo initialization.
  2. Call G12_EnhancedInfoManager_Init(); from your INIT_GLOBAL() function in Startup.d

Change colour

Set font color for a dialogue choice.

h@[hex color value]
-
Set font color for highlighted dialogue choice.
hs@[hex color value]
-
Example
description = "h@2a85a3 hs@2ea9d1 This dialogue is blue.";
-

Change font

Set font itself for a dialogue choice.

f@[font name]
-
Set font itself for highlighted dialogue choice.
fs@[font name]
-
Example
description = "f@font_old_20_white.tga fs@font_old_10_white.tga This dialogue has a different font, when selected.";
-

Change text alignment

Align text left.

al@
-
Align text center.
ac@
-
Align text right.
ar@
-
Example
1
-2
-3
description = "al@ This dialogue has LEFT alignment.";
-description = "ac@ This dialogue has CENTER alignment.";
-description = "ar@ This dialogue has RIGHT alignment.";
-

Disable dialogue

Player cannot highlight (and select) this dialogue.

d@
-

Text input field

Input field allows you to turn a dialogue choice into an input text field.

a@
-
Example
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
INSTANCE DIA_Xardas_Password (C_Info)
-{
-    npc         = NONE_100_Xardas;
-    nr          = 1;
-    condition   = DIA_Xardas_Password_Condition;
-    information = DIA_Xardas_Password_Info;
-    permanent   = FALSE;
-    description = "a@ What is the password to get to the Mages of Water?";
-};
-
-FUNC INT DIA_Xardas_Password_Condition () {
-    return TRUE;
-};
-
-FUNC VOID DIA_Xardas_Password_Info () {
-    if (Hlp_StrCmp (InfoManagerAnswer, "TETRIANDOCH"))
-    {
-        PrintScreen ("Yes that is correct!", -1, -1, "font_old_10_white.tga", 3);
-    }
-    else
-    {
-        PrintScreen ("No that is wrong!", -1, -1, "font_old_10_white.tga", 3);
-    };
-};
-

Dialogue numbers

This feature shows a dialogue number next to the dialogue line (visual for Dialogue keyboard controls). To turn this on you just set InfoManagerNumKeysNumbers variable to true. (in your INIT_GLOBAL() function).

InfoManagerNumKeysNumbers = TRUE;
-

Dialogue keyboard controls

Note

This has also been fixed in Union and we noticed a strange behavior with different keyboard layouts.

This feature changes the way number keys affect dialogue selection. The first dialogue is no longer 0 and you highlight the dialogue option by pressing appropriate number.

InfoManagerNumKeysControls = TRUE;
-

Spinners

This is by far the most flashy feature of EIM as it allows you to use left/right arrow keys on a dialogue option to increase/decease numerical value. This can be used in many ways.

This feature is a bit more complex:

  1. Set up a standard dialogue

    Notice

    Notice we are using "dummy" as a description, since it is going to get updated. If something goes wrong the "dummy" string shows up and you can clearly tell something went wrong.

    1
    -2
    -3
    -4
    -5
    -6
    -7
    -8
    INSTANCE PC_Pan_Cook_Meat (C_Info)
    -{
    -    nr           = 1;
    -    condition    = PC_Pan_Cook_Meat_Condition;
    -    information  = PC_Pan_Cook_Meat_Info;
    -    permanent    = TRUE;
    -    description  = "dummy"; //Description is updated in PC_Pan_Cook_Meat_Condition
    -};
    -
  2. Most of the magic takes place in the condition function (apart from the code behind the scenes, of course).

     1
    - 2
    - 3
    - 4
    - 5
    - 6
    - 7
    - 8
    - 9
    -10
    -11
    -12
    -13
    -14
    -15
    -16
    -17
    -18
    -19
    -20
    -21
    -22
    -23
    -24
    -25
    -26
    -27
    -28
    -29
    -30
    -31
    -32
    -33
    -34
    -35
    -36
    -37
    -38
    -39
    -40
    -41
    -42
    -43
    -44
    -45
    -46
    -47
    -48
    -49
    -50
    -51
    -52
    var int selectedMeat; // global variable for this spinner value
    -
    -FUNC INT PC_Pan_Cook_Meat_Condition ()
    -{
    -    if (PLAYER_MOBSI_PRODUCTION == MOBSI_DIALOG_PAN)
    -    {
    -        var string lastSpinnerID;
    -
    -        var int total; total = NPC_HasItems (self, ItFoMuttonRaw);
    -
    -        if (selectedMeat == 0) { selectedMeat = 1; }; //Default initial value
    -
    -        //Check currently selected spinned ID --> is it this one?
    -        if (Hlp_StrCmp (InfoManagerSpinnerID, "CookMeat"))
    -        {
    -            //Setup spinner if spinner ID has changed
    -            if (!Hlp_StrCmp (InfoManagerSpinnerID, lastSpinnerID))
    -            {
    -                //Restore previous value
    -                InfoManagerSpinnerValue = selectedMeat;
    -            };
    -
    -            //Page Up/Down quantity
    -            InfoManagerSpinnerPageSize = 5;
    -
    -            //Min/Max value (Home/End keys)
    -            InfoManagerSpinnerValueMin = 1;
    -            InfoManagerSpinnerValueMax = total;
    -
    -            //Update number which is shown in description (in case it was changed by _HOOK_VIEWDIALOGCHOICE_HANDLEEVENT
    -            selectedMeat = InfoManagerSpinnerValue;
    -
    -        };
    -
    -        lastSpinnerID = InfoManagerSpinnerID; //Remember last active spinner ID
    -
    -        var string newDescription;
    -
    -        //Spinner ID 'CookMeat'
    -        newDescription = "s@CookMeat Cook some meat: ";
    -
    -        newDescription = ConcatStrings (newDescription, IntToString (selectedMeat));
    -        newDescription = ConcatStrings (newDescription, " / ");
    -        newDescription = ConcatStrings (newDescription, IntToString (total));
    -
    -        //Update description
    -        PC_Pan_Cook_Meat.description = newDescription;
    -        return TRUE;
    -    };
    -
    -    return FALSE;
    -};
    -
  3. We can use the spinner value stored in selectedMeat variable here in the info function to create the meat (or do other stuff with it).

     1
    - 2
    - 3
    - 4
    - 5
    - 6
    - 7
    - 8
    - 9
    -10
    -11
    -12
    -13
    -14
    -15
    -16
    -17
    -18
    FUNC VOID PC_Pan_Cook_Meat_Info () {
    -    //If we don't have any meat ... don't cook any :)
    -    if (!NPC_HasItems (self, ItFoMuttonRaw)) { return; };
    -
    -    //This should not happen - but you never know!
    -    if (selectedMeat < 1) { return; };
    -
    -    //This should not happen either! but just in case
    -    if (selectedMeat > (NPC_HasItems (self, ItFoMuttonRaw))) {
    -        selectedMeat = NPC_HasItems (self, ItFoMuttonRaw);
    -    };
    -
    -    NPC_RemoveInvItems (self, ItFoMuttonRaw, selectedMeat);
    -    CreateInvItems (self, ItFoMutton, selectedMeat);
    -
    -    //Reset value for next time
    -    selectedMeat = 1;
    -};
    -

Spinners: Full code example

Spinner example
  1
-  2
-  3
-  4
-  5
-  6
-  7
-  8
-  9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
-100
-101
-102
-103
-104
-105
-106
-107
-108
-109
INSTANCE PC_Pan_Cook_Meat (C_Info)
-{
-    nr           = 1;
-    condition    = PC_Pan_Cook_Meat_Condition;
-    information  = PC_Pan_Cook_Meat_Info;
-    permanent    = TRUE;
-    description  = "dummy"; //Description is updated in PC_Pan_Cook_Meat_Condition
-};
-
-var int selectedMeat;
-
-FUNC INT PC_Pan_Cook_Meat_Condition ()
-{
-    if (PLAYER_MOBSI_PRODUCTION == MOBSI_DIALOG_PAN)
-    {
-        var string lastSpinnerID;
-
-        var int total; total = NPC_HasItems (self, ItFoMuttonRaw);
-
-        if (selectedMeat == 0) { selectedMeat = 1; }; //Default initial value
-
-        //Check currently selected spinned ID --> is it this one?
-        if (Hlp_StrCmp (InfoManagerSpinnerID, "CookMeat"))
-        {
-            //Setup spinner if spinner ID has changed
-            if (!Hlp_StrCmp (InfoManagerSpinnerID, lastSpinnerID))
-            {
-                //Restore previous value
-                InfoManagerSpinnerValue = selectedMeat;
-            };
-
-            //Page Up/Down quantity
-            InfoManagerSpinnerPageSize = 5;
-
-            //Min/Max value (Home/End keys)
-            InfoManagerSpinnerValueMin = 1;
-            InfoManagerSpinnerValueMax = total;
-
-            //Update number which is shown in description (in case it was changed by _HOOK_VIEWDIALOGCHOICE_HANDLEEVENT
-            selectedMeat = InfoManagerSpinnerValue;
-        };
-
-        lastSpinnerID = InfoManagerSpinnerID; //Remember last active spinner ID
-
-        var string newDescription;
-
-        //Spinner ID 'CookMeat'
-        newDescription = "s@CookMeat Cook some meat: ";
-
-        newDescription = ConcatStrings (newDescription, IntToString (selectedMeat));
-        newDescription = ConcatStrings (newDescription, " / ");
-        newDescription = ConcatStrings (newDescription, IntToString (total));
-
-        //Update description
-        PC_Pan_Cook_Meat.description = newDescription;
-        return TRUE;
-    };
-
-    return FALSE;
-};
-
-FUNC VOID PC_Pan_Cook_Meat_Info ()
-{
-    //If we don't have any meat ... don't cook any :)
-    if (!NPC_HasItems (self, ItFoMuttonRaw)) { return; };
-
-    //This should not happen - but you never know!
-    if (selectedMeat < 1) { return; };
-
-    //This should not happen either! but just in case
-    if (selectedMeat > (NPC_HasItems (self, ItFoMuttonRaw)))
-    {
-        selectedMeat = NPC_HasItems (self, ItFoMuttonRaw);
-    };
-
-    NPC_RemoveInvItems (self, ItFoMuttonRaw, selectedMeat);
-    CreateInvItems (self, ItFoMutton, selectedMeat);
-
-    //Reset value for next time
-    InfoManagerSpinnerValue = 1;
-};
-
-INSTANCE PC_Pan_Cook_Meat_Exit (C_Info)
-{
-    nr          = 999;
-    condition   = PC_Pan_Cook_Meat_Exit_Condition;
-    information = PC_Pan_Cook_Meat_Exit_Info;
-    permanent   = TRUE;
-    description = "End";
-};
-
-FUNC INT PC_Pan_Cook_Meat_Exit_Condition ()
-{
-    if (PLAYER_MOBSI_PRODUCTION == MOBSI_DIALOG_PAN)
-    {
-        return TRUE;
-    };
-    return FALSE;
-};
-
-FUNC VOID PC_Pan_Cook_Meat_Exit_Info ()
-{
-    if (PLAYER_MOBSI_PRODUCTION != MOBSI_DIALOG_NONE)
-    {
-        PLAYER_MOBSI_PRODUCTION = MOBSI_DIALOG_NONE;
-        hero.aivar[AIV_INVINCIBLE] = FALSE;
-        AI_StopProcessInfos (hero);
-    };
-};
-
\ No newline at end of file diff --git a/zengin/scripts/extenders/afsp/index.html b/zengin/scripts/extenders/afsp/index.html deleted file mode 100644 index 8218d2bce6..0000000000 --- a/zengin/scripts/extenders/afsp/index.html +++ /dev/null @@ -1,34 +0,0 @@ - AF Script Packet - Gothic Modding Community

AF Script Packet

Auronen & Fawkes' Script Packet is a script package built on top of Ikarus and LeGo. It implements many features and there is also a Union version which is in its infancy stage.

Note

AFSP's documentation is lacking (@Auronen: "My fault"). The authors will host the documentation on GMC.

Contacts
Authors Fawkes & Auronen
GitHub AFSP
Forum AFSP
\ No newline at end of file diff --git a/zengin/scripts/extenders/ikarus/constants/index.html b/zengin/scripts/extenders/ikarus/constants/index.html deleted file mode 100644 index 70ae08f0b5..0000000000 --- a/zengin/scripts/extenders/ikarus/constants/index.html +++ /dev/null @@ -1,43 +0,0 @@ - Constants - Gothic Modding Community

Ikarus User Constants

In the Constants file, you'll find user variables that control various aspects, including the debug output of Ikarus. You can customize these variables to suit your needs.

MEM-Helper

  • const string MEM_FARFARAWAY
    Waypoint where the Mem-Helper is spawned (default: "TOT")
  • const string MEM_HELPER_NAME
    Name of the Mem-Helper (default: "MEMHLP")

Debug

  • const int zERR_ErrorBoxOnlyForFirst
    Controls whether only the first error should trigger an error box (default: 1).
  • const int zERR_StackTraceOnlyForFirst
    Determines if stack traces should be displayed only for the first error (default: 0).

MEM_Debug

The MEM_Debug function allows you to set up a custom message channel for debugging purposes. You can adjust the following variables to configure this channel:

  • const string zERR_DEBUG_PREFIX
    Specifies a prefix to be added to each debug message (default: "Debug: ").
  • const int zERR_DEBUG_TOSPY
    Controls whether MEM_Debug messages should be sent to zSpy (default: 1).
  • const int zERR_DEBUG_TYPE
    Specifies the message type for MEM_Debug messages when sent to zSpy (default: zERR_TYPE_INFO).
  • const int zERR_DEBUG_TOSCREEN
    Determines whether MEM_Debug messages should be printed to the screen (default: 0).
  • const int zERR_DEBUG_ERRORBOX
    Allows you to display an error box for MEM_Debug messages (default: 0).

Error message types

1
-2
-3
-4
-5
const int zERR_TYPE_OK    = 0; /* [ungenutzt]        */
-const int zERR_TYPE_INFO  = 1; /* MEM_Info           */
-const int zERR_TYPE_WARN  = 2; /* MEM_Warn           */
-const int zERR_TYPE_FAULT = 3; /* MEM_Error          */
-const int zERR_TYPE_FATAL = 4; /* [ungenutzt]        */
-
\ No newline at end of file diff --git a/zengin/scripts/extenders/ikarus/examples/index.html b/zengin/scripts/extenders/ikarus/examples/index.html deleted file mode 100644 index 6b856c55c4..0000000000 --- a/zengin/scripts/extenders/ikarus/examples/index.html +++ /dev/null @@ -1,371 +0,0 @@ - Examples - Gothic Modding Community

Ikarus examples

A collection of examples ported from the original Ikarus documentation.

Note

The original Ikarus documentation is a part of the code. You can find it in the GitHub repository.

Open focused chest or door

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
func void OpenFocussedChestOrDoor() 
-{
-    var oCNpc her; her = Hlp_GetNpc(hero);
-
-    // No focus vob at all?
-    if (!her.focus_vob) 
-    {
-        Print ("No focus!");
-        return;
-    };
-
-    // Focus vob not a lockable vob?
-    if (!Hlp_Is_oCMobLockable(her.focus_vob))
-    {
-        Print ("No chest or door in focus!");
-        return;
-    };
-
-    var oCMobLockable Lockable;
-    Lockable = MEM_PtrToInst (her.focus_vob);
-
-    if (Lockable.bitfield & oCMobLockable_bitfield_locked) 
-    {
-        Lockable.bitfield = Lockable.bitfield & ~ oCMobLockable_bitfield_locked;
-        Print (ConcatStrings ("Opened the following vob: ", Lockable._zCObject_objectName));
-    } 
-    else
-    {
-        Print (ConcatStrings ( Lockable._zCObject_objectName, "wasn't even complete!"));
-    };
-};
-
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
func void PrintCameraPos()
-{
-    // Initialize global instances (which only exist once):
-    // Initializes MEM_World, MEM_Game, etc. including MEM_Camera
-    MEM_InitGlobalInst();
-
-    /* The camera object is not a vob (but something abstract), 
-    do not know where and how there are position data.
-    I prefer to work on the camera vob : */
-    var zCVob camVob;
-    camVob = MEM_PtrToInst (MEM_Camera.connectedVob);
-
-    /* Here you have to know how the transformation matrix is structured:
-
-    It consists of three vectors, the x, y and z directions of the local coordinate system of the camera vob
-    in world coordinates (where z specifies the
-    line of sight). These vectors are
-    denoted by v1, v2, v3.
-    In addition, in the 4th column there is the translation,
-    that is, the position of the camera.
-
-    v1_x v2_x v3_x x
-    v1_y v2_y v3_y y
-    v1_z v3_z v3_z z
-    0 0 0 0
-
-    The matrix is stored row by row in memory.
-    Since we are interested in the last column are the indices
-    in the trafoWorld Array 3, 7 and 11 that we need. */
-
-    Print (ConcatStrings ("x: ",IntToString(roundf(camVob.trafoObjToWorld[3]))));
-    Print (ConcatStrings ("y: ",IntToString(roundf(camVob.trafoObjToWorld[7]))));
-    Print (ConcatStrings ("z: ",IntToString(roundf(camVob.trafoObjToWorld[11]))));
-};
-

Start rain

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
func void StartRain()
-{
-    // Initialize global instances
-    // This also includes Skycontroller
-    MEM_InitGlobalInst(); 
-
-    // start at the beginning of the day (12:00 noon)
-    MEM_SkyController.rainFX_timeStartRain = 0; // FLOATNULL constant
-    // end at the end of the day (12:00 noon of the next day)
-    MEM_SkyController.rainFX_timeStopRain = 1065353216; // FLOATONE constant
-
-    /* Note: The start and end times are floating point numbers.
-    * 0 stands for the beginning of the day 1 for the end of the day.
-    * a day in the game begins at 12:00 p.m.
-    * For the structure of the floating point format, google for IEEE-745.*/
-
-    /* Result: rain all day! (unless you are in a zone
-    * in which it snows, then snow all day) */
-};
-

Nested loop

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
-37
-38
-39
-40
-41
-42
-43
-44
-45
-46
-47
-48
// Should enumerate all pairs (x,y) with 0 <= x < max_x, 0 <= j < max_y
-
-func void printpairs(var int max_x, var int max_y)
-{
-    // Initialize labels
-    MEM_InitLabels();
-    // PrintDebug should be used, i.e. activate debug output
-    MEM_SetShowDebug (1);
-
-    var int x; var int y; x = 0;
-
-    // while (x < max_x)
-    var int x_loop; x_loop = MEM_StackPos.position;
-    if (x < max_x)
-    { 
-        y = 0;
-        // while (y < max_y) 
-        var int y_loop; y_loop = MEM_StackPos.position;
-        if (y < max_y)
-        { 
-            var string out; out = "(";
-            out = ConcatStrings (out, IntToString (x));
-            out = ConcatStrings (out, ", ");
-            out = ConcatStrings (out, IntToString (y));
-            out = ConcatStrings (out, ")");
-            PrintDebug (out);
-            y += 1;
-
-            // continue y_loop 
-            MEM_StackPos.position = y_loop;
-        };
-        x += 1;
-        // continue x_loop
-        MEM_StackPos.position = x_loop;
-    };
-};
-
-/*
-    Output of a call printpairs(4,2) would then be: 
-    00:36 Info: 5 U: Skript: (0, 0) .... 
-    00:36 Info: 5 U: Skript: (0, 1) .... 
-    00:36 Info: 5 U: Skript: (1, 0) .... 
-    00:36 Info: 5 U: Skript: (1, 1) .... 
-    00:36 Info: 5 U: Skript: (2, 0) .... 
-    00:36 Info: 5 U: Skript: (2, 1) .... 
-    00:36 Info: 5 U: Skript: (3, 0) .... 
-    00:36 Info: 5 U: Skript: (3, 1) .... 
-*/
-

Calling a function by their name

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
-37
-38
-39
// This example doesn't show why MEM_CallByString * is useful, but how to use the function.
-
-var zCVob someObject;
-func int MyFunction(var int param1, var string str1, var int param2, var string str2)
-{
-    Print (ConcatStrings (str1, str2)); //(*)
-    return 100 * param1 + param2;
-};
-
-func void foo()
-{ 
-    var int result;
-
-    // The following code is in this case equivalent to:
-    // result = MyFunction(42, "Hello", 23, "World!");
-
-    // Lay the call arguments on the call stack
-    MEM_PushIntParam (42);
-    MEM_PushStringParam ("Hello ");
-    MEM_PushIntParam (23);
-    MEM_PushStringParam ("World!");
-
-    MEM_CallByString ("MYFUNCTION");
-
-    // the function puts the result (of type int in this case) on the stack
-    // we pop the int result and save it to a variable
-    result = MEM_PopIntResult();
-
-    // print the result
-    Print (IntToString (result));
-};
-
-/*
-    Note: Since symbol indices are continuous and someObject's symbol index 
-    is simply given by someObject itself, could
-    MEM_CallByString("MYFUNCTION"); 
-    also be replaced here by 
-    MEM_CallByID(someObject + 1);
-*/
-
\ No newline at end of file diff --git a/zengin/scripts/extenders/ikarus/floats/index.html b/zengin/scripts/extenders/ikarus/floats/index.html deleted file mode 100644 index a99a7933b1..0000000000 --- a/zengin/scripts/extenders/ikarus/floats/index.html +++ /dev/null @@ -1,80 +0,0 @@ - Floats - Gothic Modding Community

Floats

This part of ikarus implements support for 32 bit IEEE 754 floats in Daedalus. The script was originally created to edit zFLOAT and zREAL variables, but can also be used to arithmetic operations on real float values (not to be confused with Daedalus floats).

Initialization

The best way to initialize all Ikarus functions is to call MEM_InitAll() in the Init_Global() initialization function.

Warning

If you want to use Ikarus in Gothic 1, it is best to define your own Init_Global() function and call it from every world initialization function.

MEM_InitAll();
-

Implementation

float.d on GitHub

Functions

Danger

Ikarus floats are saved as int but it doesn't mean that you can use arithmetic operators on them. All operations on floats must be done with functions listed below.

mkf

(make float) Converts the input integer x to a float value.

func int mkf(var int x)
-
Parameters
  • var int x
    The input integer

Return value

The function returns the float representation of the input integer x.

truncf

(truncate float) Truncates the decimal part of the input float x.

func int truncf(var int x)
-
Parameters
  • var int x
    The input float

Return value

The function returns the integer part of the input float x by discarding the decimal part.

roundf

(round float) Rounds the input float x to the nearest integer value.

func int roundf(var int x)
-
Parameters
  • var int x
    The input float

Return value

The function returns the nearest integer value to the input float x. If the decimal part is exactly halfway between two integers, the function rounds to the nearest even integer.

addf

(add floats) Adds two ikarus floats together.

func int addf(var int x, var int y)
-
Parameters
  • var int x
    The first float
  • var int y
    The second float

Return value

The function returns the sum of the input floats x and y. (x + y)

subf

(subtract floats) Subtracts the second float from the first float.

func int subf(var int x, var int y)
-
Parameters
  • var int x
    The first float
  • var int y
    The second float

Return value

The function returns the difference between the first float x and the second float y. (x - y)

negf

(negate float) Negates the input float.

func int negf(var int x)
-
Parameters
  • var int x
    The input float

Return value

The function returns the negation of the input float x.

mulf

(multiply floats) Multiplies two ikarus floats.

func int mulf(var int x, var int y)
-
Parameters
  • var int x
    The first float
  • var int y
    The second float

Return value

The function returns the product of multiplying the input floats x and y. (x * y)

divf

(divide floats) Divides two ikarus floats.

func int divf(var int x, var int y)
-
Parameters
  • var int x
    The dividend float
  • var int y
    The divisor float

Return value

The function returns the quotient of dividing the input float x by y. (x / y)

invf

(inverse float) Computes the inverse of the input float.

func int invf(var int x)
-
Parameters
  • var int x
    The input float

Return value

The function returns the inverse of the x, calculated as 1/x.

gf

(greater) Checks if the first float is greater than the second float.

func int gf(var int x, var int y)
-
Parameters
  • var int x
    The first float
  • var int y
    The second float

Return value

The function returns TRUE if x is greater than y, FALSE is returned otherwise.

gef

(greater or equal) Checks if the first float is greater than or equal to the second float.

func int gef(var int x, var int y)
-
Parameters
  • var int x
    The first float
  • var int y
    The second float

Return value

The function returns TRUE if x is greater than or equal to y, FALSE is returned otherwise.

lf

(lower) Checks if the first float is less than the second float.

func int lf(var int x, var int y)
-
Parameters
  • var int x
    The first float
  • var int y
    The second float

Return value

The function returns TRUE if x is less than y, FALSE is returned otherwise.

lef

(lower or equal) Checks if the first float is less than or equal to the second float.

func int lef(var int x, var int y)
-
Parameters
  • var int x
    The first float
  • var int y
    The second float

Return value

The function returns TRUE if x is less than or equal to y, FALSE is returned otherwise.

sqrf

(square float) Calculates the square of the float.

func int sqrf(var int x)
-
Parameters
  • var int x
    The input float

Return value

The function returns the square of the input float x, computed as x * x.

sqrtf

(square root float) Calculates the square root of the float.

func int sqrtf(var int x)
-
Parameters
  • var int x
    The input float

Return value

The function returns the square root of the input float x.

sqrtf_approx

Calculates the approximate square root of a float.

func int sqrtf_approx(var int f)
-
Parameters
  • var int f
    The input float

Return value

The function returns the approximate square root of the input float as an ikarus float.

absf

(absolute value) Computes the absolute value of a float.

func int absf(var int x)
-
Parameters
  • var int x
    The input float

Return value

The function returns the absolute value of the input float x, which is the value without the negative sign (if present).

fracf

(fraction) Computes the fraction of two integers p and q.

func int fracf(var int p, var int q)
-
Parameters
  • var int p
    Numerator
  • var int q
    Denominator

Return value

The function returns the fraction of p divided by q as an ikarus float.

castFromIntf

Converts an ikarus float to a Daedalus float.

func float castFromIntf(var int f)
-
Parameters
  • var int f
    Ikarus float

Return Value

The function returns the value f as a Daedalus float.

castToIntf

Converts a Daedalus float to an ikarus float.

func int castToIntf(var float f)
-
Parameters
  • var float f
    Daedalus float

Return Value

The function returns the value f as an ikarus float.

toStringf

Converts a float value to its string representation.

func string toStringf(var int x)
-
Parameters
  • var int x
    Input float value

Return value

The function returns a string representation of the input float value.

printf

(print float) Prints the float on screen using Print().

func void printf(var int x)
-
Parameters
  • var int x
    The printed float

Examples

Simple operations

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
var int float1; float1 = mkf(5);        // Create an Ikarus float with value 5
-var int float2; float2 = mkf(2);        // Create an Ikarus float with value 2
-
-var int addResult; addResluts  = addf(float1, float2);     // Add float1 and float2
-var int subResult; subResults  = subf(float1, float2);     // Subtract float2 from float1
-var int mulResult; mulRelsults = mulf(float1, float2);     // Multiply float1 by float2
-var int divResult; divResults  = divf(float1, float2);     // Divide float1 by float2
-
-printf(addResult);   // Output: 7
-printf(subResult);   // Output: 3
-printf(mulResult);   // Output: 10
-printf(divResult);   // Output: 2.5
-
\ No newline at end of file diff --git a/zengin/scripts/extenders/ikarus/functions/arrays/index.html b/zengin/scripts/extenders/ikarus/functions/arrays/index.html deleted file mode 100644 index a2fd5339b8..0000000000 --- a/zengin/scripts/extenders/ikarus/functions/arrays/index.html +++ /dev/null @@ -1,52 +0,0 @@ - Arrays (zCArray) - Gothic Modding Community

Arrays (zCArray)

Set of function for working with ZenGin's zCArray data structure.

Initialization

The best way to initialize all Ikarus functions is to call MEM_InitAll() in the Init_Global() initialization function.

Warning

If you want to use Ikarus in Gothic 1, it is best to define your own Init_Global() function and call it from every world initialization function.

MEM_InitAll();
-

Implementation

Ikarus.d on GitHub

Functions

MEM_ArrayCreate

Creates an empty zCArray (allocates memory) and returns a pointer to it.

func int MEM_ArrayCreate()
-
Return value

The function returns a pointer to the created zCArray.

MEM_ArrayFree

Frees the memory allocated for a zCArray and its data.

func void MEM_ArrayFree(var int zCArray_ptr)
-
Parameters
  • var int zCArray_ptr
    Pointer to the zCArray to be freed

MEM_ArrayClear

Clears the data of a zCArray, freeing the memory used by its elements. The array becomes empty.

func void MEM_ArrayClear (var int zCArray_ptr)
-
Parameters
  • var int zCArray_ptr
    Pointer to the zCArray to be cleared

MEM_ArraySize

Returns the size (number of elements) of an array.

func int MEM_ArraySize(var int zCArray_ptr)
-
Parameters
  • var int zCArray_ptr
    Pointer to the zCArray

Return value

The function returns a number of a zCArray elements.

MEM_ArrayWrite

Writes a value at a specific position in the zCArray.

func void MEM_ArrayWrite(var int zCArray_ptr, var int pos, var int value)
-
Parameters
  • var int zCArray_ptr
    Pointer to the zCArray
  • var int pos
    Position in the array where the value will be written
  • var int value
    Value to be written

MEM_ArrayRead

Reads the value at a specific position in the zCArray.

func int MEM_ArrayRead(var int zCArray_ptr, var int pos)
-
Parameters
  • var int zCArray_ptr
    Pointer to the zCArray
  • var int pos
    Position in the array from which the value will be read

Return value

The function returns the value at a specific position in the zCArray.

MEM_ArrayInsert

Appends a value to the end of the zCArray. The array is automatically resized if it is too small.

func void MEM_ArrayInsert (var int zCArray_ptr, var int value)
-
Parameters
  • var int zCArray_ptr
    Pointer to the zCArray
  • var int value
    Value to be inserted

MEM_ArrayPush

Alias for MEM_ArrayInsert, inserts a value at the end of the zCArray.

func void MEM_ArrayPush (var int zCArray_ptr, var int value)
-
Parameters
  • var int zCArray_ptr
    Pointer to the zCArray
  • var int value
    Value to be inserted

MEM_ArrayPop

Removes and returns the last element from the zCArray.

func int MEM_ArrayPop(var int zCArray_ptr)
-
Parameters
  • var int zCArray_ptr
    Pointer to the zCArray

Return value

The function returns the element removed from the end of an array.

MEM_ArrayTop

Returns the last element of the zCArray without removing it.

func int MEM_ArrayTop(var int zCArray_ptr)
-
Parameters
  • var int zCArray_ptr
    Pointer to the zCArray

Return value

The function returns the last element of an array.

MEM_ArrayIndexOf

Searches the zCArray for the first occurrence of a value and returns its index.

func int MEM_ArrayIndexOf(var int zCArray_ptr, var int value)
-
Parameters
  • var int zCArray_ptr
    Pointer to the zCArray
  • var int value
    Value to search for

Return value

The function returns the index of a first occurrence of a value. If not found -1 is returned.

MEM_ArrayRemoveIndex

Removes the element at a specific index from the zCArray.

func void MEM_ArrayRemoveIndex (var int zCArray_ptr, var int index)
-
Parameters
  • var int zCArray_ptr
    Pointer to the zCArray
  • var int index
    Index of the element to be removed

MEM_ArrayRemoveValue

Removes all occurrences of a value from the zCArray.

func void MEM_ArrayRemoveValue (var int zCArray_ptr, var int value)
-
Parameters
  • var int zCArray_ptr
    Pointer to the zCArray
  • var int value
    Value to be removed

MEM_ArrayRemoveValueOnce

Removes the first occurrence of a value from the zCArray. If value is not found, a warning is issued.

func void MEM_ArrayRemoveValueOnce (var int zCArray_ptr, var int value)
-
Parameters
  • var int zCArray_ptr
    Pointer to the zCArray
  • var int value
    Value to be removed

MEM_ArraySort

Sorts the elements of the zCArray in ascending order.

func void MEM_ArraySort(var int zCArray_ptr)
-
Parameters
  • var int zCArray_ptr
    Pointer to the zCArray

MEM_ArrayUnique

Removes duplicate elements from the zCArray.

func void MEM_ArrayUnique(var int zCArray_ptr)
-
Parameters
  • var int zCArray_ptr
    Pointer to the zCArray

MEM_ArrayToString

Converts the zCArray to a string representation.

func string MEM_ArrayToString (var int zCArray_ptr)
-
Parameters
  • var int zCArray_ptr
    Pointer to the zCArray

Return value

The function returns a string representation of a given array.

\ No newline at end of file diff --git a/zengin/scripts/extenders/ikarus/functions/asm/index.html b/zengin/scripts/extenders/ikarus/functions/asm/index.html deleted file mode 100644 index e1495c212c..0000000000 --- a/zengin/scripts/extenders/ikarus/functions/asm/index.html +++ /dev/null @@ -1,87 +0,0 @@ - ASM - Gothic Modding Community

Ikarus Machine Code Implementation (ASM)

Machine code refers to a program or program segment written in machine language, which can be directly executed by a processor without further translation steps. The relevant machine language for us is that belonging to the x86 processor architecture. All machine instructions, what they do, and how they are encoded in machine language can be found in the Intel Manuals.

In practice, dealing with (abstract) machine instructions and manually translating them into (concrete) machine code is rarely necessary due to its complexity.

However, machine code can be useful for performing technical tasks that cannot be expressed in Daedalus directly. For example, the CALL package use the ASM function set as a basis.

Note

The functions in this chapter have the ASM_ prefix for Assembly (language). Assembly language is a human-readable language with one-to-one correspondences to machine language. Strictly speaking, the ASM_ prefix is misleading here, as it pertains to machine code rather than assembly language. However, conceptually, the two are closely related.

Initialization

The best way to initialize all Ikarus functions is to call MEM_InitAll() in the Init_Global() initialization function.

Warning

If you want to use Ikarus in Gothic 1, it is best to define your own Init_Global() function and call it from every world initialization function.

MEM_InitAll();
-

Implementation

Ikarus.d on GitHub

Opcodes

The code defines several constants that represent different machine code instructions. Each constant is assigned a hexadecimal value and corresponds to a specific machine code instruction. Here is a link to all instructions.

Internal Stack

The code includes an internal stack implementation, allowing the storage of data. The stack is already used at two points:

  • When calling an engine function, the address of the current run is stored in the internal stack.
  • When nesting the use of the CALL package, a push and pop operation is performed to manage the context.

The internal stack is implemented using an array, and the following functions are provided:

ASMINT_Push

Pushes the specified data onto the internal stack.

func void ASMINT_Push(var int data)
-
Parameters
  • var int data
    Data pushed onto internal stack

ASMINT_Pop

Pops and returns the topmost data from the internal stack.

func int ASMINT_Pop()
-
Return value

The function returns a data popped form the internal stack.

Functions (Core)

The ASM core functionality provides a framework for assembling machine code instructions and executing them. The following functions are included:

ASMINT_Init

Initializes the ASM system by creating an internal stack and finding function addresses.

func void ASMINT_Init()
-

Tip

It's worth noting that ASMINT_Ini is also invoked by the MEM_InitAll function.

ASM_Open

Changes the size of the memory allocated at the start o the dictation

The memory in which the machine code is stored is allocated at the beginning of the dictation. If this function isn't called a default size (see Constant below) is allocated by ASM or ASM_Here function. The 256 bytes is often sufficient for simple applications, but if more memory is required, this function must be called at the beginning of the dictation.

func void ASM_Open(var int space)
-
Parameters
  • var int space
    Space allocated for machine code (in bytes)

Constant

ASM_StandardStreamLength constant defines the default space available for an Assembler sequence (in bytes).

const int ASM_StandardStreamLength = 256;
-

ASM

Writes machine code instructions to the stream.

Using this function it is possible to dictate machine code little by little. The data bytes of the length (maximum 4!) are appended to the previously dictated part. This creates a program piece by piece that can be executed by the processor.

func void ASM(var int data, var int length)
-
Parameters
  • var int data
    The machine code instruction or its part
  • var int length
    Length of the data (max 4 bytes)

ASM_1

ASM with length parameter hardcoded to 1. Writes one byte machine code instructions to the stream.

func void ASM_1(var int data) 
-
Parameters
  • var int data
    One byte machine code instruction or its part

ASM_2

ASM with length parameter hardcoded to 2. Writes two bytes machine code instructions to the stream.

func void ASM_1(var int data) 
-
Parameters
  • var int data
    Two bytes machine code instruction or its part

ASM_3

ASM with length parameter hardcoded to 3. Writes three bytes machine code instructions to the stream.

func void ASM_1(var int data) 
-
Parameters
  • var int data
    Three bytes machine code instruction or its part

ASM_4

ASM with length parameter hardcoded to 4. Writes four bytes machine code instructions to the stream.

func void ASM_1(var int data) 
-
Parameters
  • var int data
    Four bytes machine code instruction or its part

ASM_Here

Provides, the address of the cursor, i.e., the address of the location that will be described next by a call to ASM. It is guaranteed that the location where the code is written is also the location where it will be executed.

func int ASM_Here()
-

Return value

The function returns an address that is the current position in the machine code stream.

ASM_Close

Finalizes the stream by adding a return instruction and returns the starting address of the stream. This pointer can now be passed to at any time and any number of times to execute the machine code.

Warning

The memory area obtained by ASM_Close must be released manually using MEM_Free to avoid memory leaks. It is probably sufficient for almost all practical purposes.

func int ASM_Close()
-
Return value

The function returns a starting address of the stream (pointer to the stream).

ASM_Run

Executes a machine code (stream) from a pointer.

Note

ASM_Run can also be used to call engine functions with no parameters and no relevant return value. In this case ptr would simply have to point to the function to be executed in the code segment.

func void ASM_Run(var int ptr)
-
Parameters
  • var int ptr
    Pointer to the executed code (returned form ASM_Close)

ASM_RunOnce

Executes the code dictated up to that point, similar to how an external function is executed. After that the code is released, and new code can be dictated.

func void ASM_RunOnce()
-

Example

The following function sets the NPC passed as slf as the player, as if you had pressed O in Marvin mode with this NPC in focus. This is so short because there is already a function for this exact purpose, it's just not normally accessible from the scripts. It is therefore sufficient to write assembly code that pushes the parameter of the function (the this pointer) into the appropriate register and then calls the function.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
func void SetAsPlayer(var C_NPC slf) { /* Address of the function */
-    const int oCNpc__SetAsPlayer = 7612064; //0x7426A0 (Gothic2.exe)
-
-    var int slfPtr;
-    slfPtr = MEM_InstToPtr (slf);
-
-    //mov ecx slfPtr
-    ASM_1(ASMINT_OP_movImToECX); /* move a value to ecx */
-    ASM_4(slfPtr); /* a value */
-
-    //call oCNpc__SetAsPlayer
-    ASM_1(ASMINT_OP_call);
-    ASM_4(oCNpc__SetAsPlayer - ASM_Here() - 4);
-
-    ASM_RunOnce(); /* return will be added automatically */
-};
-

Note

Call targets are specified relative to the instruction that would have been executed after the actual call instruction. Therefore, both ASM_Here() and the subtraction of 4 in the call parameter are necessary.

The above example describes, among other things, CALL__thiscall function form the CALL Package that can be also used to implement SetAsPlayer.

1
-2
-3
-4
func void SetAsPlayer(var C_NPC slf) { 
-    const int oCNpc__SetAsPlayer = 7612064;
-    CALL__thiscall(MEM_InstToPtr(slf), oCNpc__SetAsPlayer);
-};
-
\ No newline at end of file diff --git a/zengin/scripts/extenders/ikarus/functions/call/index.html b/zengin/scripts/extenders/ikarus/functions/call/index.html deleted file mode 100644 index 1602725437..0000000000 --- a/zengin/scripts/extenders/ikarus/functions/call/index.html +++ /dev/null @@ -1,181 +0,0 @@ - CALL Package - Gothic Modding Community

CALL Package

This part of Ikarus makes possible to call engine functions directly from scripts.

In order to be able to invoke an engine function, you must know some of its properties. This includes the number and types of parameters, the type of return value, address of function and calling convention.

Knowledge about engine functions can be obtained using tools like IDA, which can analyze and convert GothicMod.exe / Gothic2.exe into a more human-readable format.

Info

In fact, machine code execution (ASM) is part of the CALL package, but due to its complexity, this functionality is discussed in a separate article.

Initialization

The best way to initialize all Ikarus functions is to call MEM_InitAll() in the Init_Global() initialization function.

Warning

If you want to use Ikarus in Gothic 1, it is best to define your own Init_Global() function and call it from every world initialization function.

MEM_InitAll();
-

Implementation

Ikarus.d on GitHub

Call modes

There are two modes:

Disposable

The simple mode that produces a disposable call that is used only once. All parameters are hardcoded.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
func int hero_GetAssessEnemy() {
-    const int oCNpc__GetPerceptionFunc = 7726080; //0x75E400
-
-    CALL_IntParam(_@(PERC_ASSESSENEMY));
-    CALL_PutRetValTo(_@(funcID));
-    CALL__thiscall(_@(hero), oCNpc__GetPerceptionFunc);
-
-    var int funcID;
-    return +funcID;
-};
-

Recyclable

The second version produces code that can be used more than once. Instead of the parameters the user specifies the address where the parameters are to be taken from. In addition to executing the code, the user will receive an address that he can use to repeat the call. This is much faster than rebuilding the call from scratch.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
func int Npc_GetPercFunc(var C_Npc npc, var int type) {
-    const int oCNpc__GetPerceptionFunc = 7726080; //0x75E400
-
-    var int npcPtr; npcPtr = _@(npc);
-
-    const int call = 0;
-    if (CALL_Begin(call)) {
-        CALL_IntParam(_@(type));
-        CALL_PutRetValTo(_@(funcID));
-        CALL__thiscall(_@(npcPtr), oCNpc__GetPerceptionFunc);
-        call = CALL_End();
-    };
-
-    var int funcID;
-    return +funcID;
-};
-

Receives a pointer. In case the pointer is non-zero, the code at this position is executed and 0 is returned. In case pointer is zero, the current mode is changed into recyclable mode, this means that the call functions expect instructions to build a recyclable call. This mode will continue until CALL_End(). This allows code like this:

Start and End

CALL_Open

Initializes a Recyclable call mode.

func void CALL_Open()
-

CALL_Begin

A practical wrapper for CALL_Open. Makes a call if it had been already created, initializes it otherwise.

func int CALL_Begin(var int ptr)
-
Parameters
  • var int ptr
    Zero if you need to create a new recyclable function to be called (usually, before first use). In this case CALL_Open is called and CALL_Begin returns 1.

Return Value

The function returns 1 if the new call has been created, 0 is returned otherwise.

CALL_Close

Finalizes a function call in recyclable mode, restoring the previous execution context.

func int CALL_Close()
-

CALL_End

Finalizes a function call, pushes the pointer onto the stack, and runs the associated assembly code (makes an actual call).

func int CALL_End()
-

Return Value

The function returns a pointer that could be used to repeat the call.

Tip

CALL_Close only finalizes the function call, returning the pointer, while CALL_End additionally handles pushing the pointer onto the stack and running associated assembly code.

Passing parameters

Parameters must be arranged on the machine stack from right to left i.e. from the parameter on the far right to the parameter on the far left. These functions generate machine code that will place parameters on the machine stack when executed.

Note

These functions do not impose any parameters on the Machine stack. Exactly it should say: You create the machine code that will put parameters on the machine stack when it is executed. And it is only carried out in the second step with the announcement of the calling convention.

CALL_IntParam

Passes an integer (int32) as a parameter to the called function.

func void CALL_IntParam(var int param)
-
Parameters
  • var int param
    Address of an integer to be passed

CALL_FloatParam

Passes an IEEE 7554 floating-point number (single / zREAL) as a parameter to the called function.

func void CALL_FloatParam(var int param)
-
Parameters
  • var int param
    Address of a float to be passed

CALL_PtrParam

Passes a pointer (void*) as a parameter to the called function.

func void CALL_PtrParam(var int param)
-
Parameters
  • var int param
    Pointer to be passed

CALL_zStringPtrParam

Passes a string (zString*) as a parameter to the called function.

func void CALL_zStringPtrParam(var string param)
-
Parameters
  • var string param
    String to be passed

Warning

This function only works when writing a disposable call!

CALL_cStringPtrParam

Passes a char array (char **) as a parameter to the called function.

func void CALL_cStringPtrParam(var string param)
-
Parameters
  • var string param
    String to be passed as character array`

Warning

This function only works when writing a disposable call!

CALL_StructParam

Passes a structure (struct) as a parameter to the called function.

func void CALL_StructParam(var int ptr, var int words)
-
Parameters
  • var int param
    Pointer to the object
  • var int words
    Size of a structure (1 word = 32 bits)

Note

CALL_IntParam, CALL_FloatParam, and CALL_PtrParam are functionally identical and are differentiated for code readability.

The call

The calling convention determines how the function's parameters are passed. IDA or another disassembler can be used to identify the convention used by a specific engine function.

The announcement of the calling convention, i.e. the call of one of the four functions below is also the time of calling the function. In particular, all parameters must already be specified at this point.

CALL__stdcall

Calls a function with __stdcall (Standard Call) calling convention.

func void CALL__stdcall(var int adr)
-
Parameters
  • var int adr
    Address of a function

CALL__thiscall

Calls a function with __thiscall calling convention. Used with a member functions.

func void CALL__thiscall(var int this, var int adr)
-
Parameters
  • var int this
    Pointer to the owner class object passed as a this parameter
  • var int adr
    Address of a function

CALL__cdecl

Calls a function with __cdecl calling convention. Used with non-Windows API and non-class functions.

func void CALL__cdecl (var int adr)
-
Parameters
  • var int adr
    Address of a function

CALL__fastcall

Calls a function with __fastcall calling convention.

func void CALL__fastcall(var int ecx, var int edx, var int adr)
-
Parameters
  • var int ecx
    First parameter of a function
  • var int edx
    Second parameter of a function
  • var int adr
    Address of a function

Return Value

As soon as the function call has taken place, i.e. after step 2, the return value can be queried. The following functions interpret the return value (usually this is the content of EAX immediately after the call) in the manner suggested in the function name. The result is then returned in a manner usable in Daedalus.

Note

Some return values are not stored in the EAX. In that case the call of the special function RetValIs is required to get the return value.

Following functions are provided: CALL_RetValIsFloat, CALL_RetValIszString, CALL_RetValIsStruct.

CALL_PutRetValTo

Simply places the return value to the given address (mostly the address of a daedalus integer). Must be called before The Call function.

func void CALL_PutRetValTo(var int adr)
-
Parameters
  • var int adr
    Destination address of the return value

CALL_RetValAsInt

Retrieves an integer returned by the called function.

func int CALL_RetValAsInt()
-
Return value

The function returns an integer returned by the previously called engine function.

CALL_RetValIsFloat

Specifies that the return value is a float. Must be called before The Call function to allow getting the return value with CALL_RetValAsFloat.

func void CALL_RetValIsFloat()
-

CALL_RetValAsFloat

Retrieves a float returned by the called function.

func int CALL_RetValAsFloat()
-
Return value

The function returns a float returned by the previously called engine function.

CALL_RetValAsPtr

Retrieves a pointer (void*) returned by the called function.

func int CALL_RetValAsPtr()
-
Return value

The function returns a pointer returned by the previously called engine function.

CALL_RetValIsStruct

Specifies that the return value is a Structure. Must be called before The Call function to allow getting the return value with CALL_RetValAsStructPtr.

func void CALL_RetValIsStruct(var int size)
-
Parameters
  • var int size
    Size of the returned structure in bytes

Danger

If the return value is a structure with a size larger than 32 bit, the space for the return value has to be allocated by the caller (this is us).The address to the allocated memory is expected on the stack as an additional parameter (pushed last).

Warning

It is in your responsibility to free the structure memory, when the return value is not needed any more.

CALL_RetValAsStructPtr

Retrieves a pointer to the structure returned by the called function and converts it to the instance. Can be used to make an assignment to an instance, for example an assignment to a var zCVob if the return value is a pointer to a zCVob.

func MEMINT_HelperClass CALL_RetValAsStructPtr()
-
Return value

The function returns an instance returned by the previously called engine function.

CALL_RetValIszString

Specifies that the return value is a zString (20 bytes structure). Must be called before The Call function to allow getting the return value with CALL_RetValAszStringPtr and CALL_RetValAszString.

func string CALL_RetValAszString()
-

Note

CALL_RetValAszStringPtr and CALL_RetValAszString are quite different and should not be confused. Using CALL_RetValAszString frees up memory that may still be needed. In a reverse with CALL_RetValAszStringPtr memory that is no longer needed is not freed and can cause memory leak.

CALL_RetValAszStringPtr

Retrieves a zString pointer and converts it to the daedalus string. (don't frees the memory)

func string CALL_RetValAszStringPtr()
-
Return value

The function returns a daedalus string form a zString returned by the previously called engine function.

CALL_RetValAszString

Retrieves a zString pointer and converts it to the daedalus string. (frees the memory)

func string CALL_RetValAszString()
-
Return value

The function returns a daedalus string form a zString returned by the previously called engine function.

Function author note

A zString is merely a special case of a structure, with the difference, that it is used as a primitive datatype. Nobody will be willing to use it as a pointer to some memory or an instance in Daedalus. This function copies the contents of the zString into a daedalus string and frees the zString afterwards.

Examples

Apply overlay (Disposable)

1
-2
-3
-4
-5
-6
-7
-8
// .text:0072D2C0:int __thiscall oCNpc::ApplyOverlay(class zSTRING const &)
-
-func void example1(){
-    const int oCNpc__ApplyOverlay = 7525056; //0x72D2C0 (G2A)
-    CALL_zStringPtrParam ("HUMANS_MILITIA.MDS");
-    CALL__thiscall (MEM_InstToPtr (hero), oCNpc__ApplyOverlay);
-    //We are not interested in the return value here.
-};
-

Get time as string (Disposable)

e.g. "7:30" for half past seven in the morning

1
-2
-3
-4
-5
-6
-7
-8
// .text:00780EC0:class zSTRING __thiscall oCWorldTimer::GetTimeString(void)
-
-func void example2(){
-    const int oCWorldTimer__GetTimeString = 7868096; //780EC0 (G2A)
-    CALL_RetValIszString();
-    CALL__thiscall (MEM_InstToPtr (MEM_WorldTimer), oCWorldTimer__GetTimeString );
-    PrintDebug (CALL_RetValAszString());
-};
-

Get the "sky time" (Disposable)

Sky time is a floating point value between 0 and 1 that jumps back from 1 to 0 at noon.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
// .text:00781240:float __thiscall oCWorldTimer::GetSkyTime(void)
-
-func int GetSkyTime() {
-    const int oCWorldTimer__GetSkyTime = 7868992; //0x781240
-    CALL_RetValIsFloat();
-    CALL__thiscall (MEM_InstToPtr (MEM_WorldTimer),
-    oCWorldTimer__GetSkyTime);
-
-    return CALL_RetValAsFloat();
-};
-

Delete Vob (Recyclable)

Call of the oCWorld.RemoveVob. MEM_DeleteVob is an ikarus built-in function.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
func void MEM_DeleteVob(var int vobPtr) {
-    var int world; world = MEM_Game._zCSession_world;
-
-    const int call = 0;
-    if (CALL_Begin(call)) {
-        /* oCWorld.RemoveVob */
-        CALL_IntParam(_@(vobPtr));
-        CALL__thiscall(_@(world), MEMINT_SwitchG1G2(7171824, 7864512));
-
-        call = CALL_End();
-    };
-};
-
\ No newline at end of file diff --git a/zengin/scripts/extenders/ikarus/functions/debug/index.html b/zengin/scripts/extenders/ikarus/functions/debug/index.html deleted file mode 100644 index 5c1b294847..0000000000 --- a/zengin/scripts/extenders/ikarus/functions/debug/index.html +++ /dev/null @@ -1,46 +0,0 @@ - Debug - Gothic Modding Community

Debug

A set of debugging and error-handling functions for mod development with Ikarus.

Initialization

The best way to initialize all Ikarus functions is to call MEM_InitAll() in the Init_Global() initialization function.

Warning

If you want to use Ikarus in Gothic 1, it is best to define your own Init_Global() function and call it from every world initialization function.

MEM_InitAll();
-

Implementation

Ikarus.d on GitHub

Functions

MEM_CheckVersion

Checks if the version of Ikarus is the specified version or newer.

func int MEM_CheckVersion(var int base, var int major, var int minor)
-
Parameters
  • var int base
    Base version number
  • var int major
    Major revision number
  • var int minor
    Minor revision number

Return value

The function returns TRUE if the version of Ikarus is the specified version or newer, FALSE is returned otherwise.

MEM_SetShowDebug

Sets the variable that is also toggled by the toggle debug command. As a result, messages outputted by PrintDebug are directed to the zSpy

func void MEM_SetShowDebug(var int on)
-
Parameters
  • var int on
    Specifies whether to turn on (TRUE) or off (FALSE) debug information.

MEM_SendToSpy

Sends a message to the debugging console.

func void MEM_SendToSpy(var int errorType, var string text)
-
Parameters
  • var int errorType
    Type of error (e.g., zERR_TYPE_FAULT, zERR_TYPE_WARN, zERR_TYPE_INFO)
  • var string text
    The message to be sent.

MEM_ErrorBox

Displays an error message in a message box.

func void MEM_ErrorBox(var string text)
-
Parameters
  • var string text
    The error message to be displayed.

MEM_PrintStackTrace

Prints the stack trace.

func void MEM_PrintStackTrace()
-

MEM_Error

Handles a fatal error, displaying the error message and printing the stack trace.

func void MEM_Error(var string error)
-
Parameters
  • var string error
    The error message.

MEM_Warn

Handles a warning, displaying the warning message and printing the stack trace.

func void MEM_Warn(var string warn)
-
Parameters
  • var string warn
    The warning message.

MEM_Info

Handles an information message, printing it if enabled in the settings.

func void MEM_Info(var string info)
-
Parameters
  • var string info
    The information message.

MEM_AssertFail

Handles an assertion failure, reporting the error message as a fatal error.

func void MEM_AssertFail(var string assertFailText)
-
Parameters
  • var string assertFailText
    The assertion failure message.

MEM_Debug

Freely configurable debug channel. See how to setup it in the Constants article.

func void MEM_Debug(var string message)
-
Parameters
  • var string message
    The debug message.

MEMINT_SwitchG1G2

Switches between values based on the game version. Used mainly to change addresses in multi-platform hooks or function calls.

func int MEMINT_SwitchG1G2(var int g1Val, var int g2Val)
-
Parameters
  • var int g1Val The value to return if the game version is Gothic 1.
  • var int g2Val
    The value to return if the game version is Gothic 2.

Return value

The function returns an appropriate value based on the game version.

\ No newline at end of file diff --git a/zengin/scripts/extenders/ikarus/functions/ini_access/index.html b/zengin/scripts/extenders/ikarus/functions/ini_access/index.html deleted file mode 100644 index 7197bfa02b..0000000000 --- a/zengin/scripts/extenders/ikarus/functions/ini_access/index.html +++ /dev/null @@ -1,49 +0,0 @@ - Ini File Access - Gothic Modding Community

Configuration file access

This part of Ikarus gives you access to Gothic.ini and loaded mod configuration files.

Initialization

The best way to initialize all Ikarus functions is to call MEM_InitAll() in the Init_Global() initialization function.

Warning

If you want to use Ikarus in Gothic 1, it is best to define your own Init_Global() function and call it from every world initialization function.

MEM_InitAll();
-

Implementation

Ikarus.d on GitHub

Read functions

MEM_GetCommandLine

Returns the contents of the command line passed to Gothic.

func string MEM_GetCommandLine()
-
Return value

The function returns contents of the command line passed to Gothic. This could, for example, look like this:

"-TIME:7:35 -GAME:TEST_IKARUS.INI -ZREPARSE -ZWINDOW -ZLOG:5,S -DEVMODE -ZMAXFRAMERATE:30"

MEM_GetGothOpt

Searches the Gothic.ini for an option.

func string MEM_GetGothOpt(var string sectionname, var string optionname)
-
Parameters
  • var string sectionname
    Settings section like [GAME]
  • var string optionname
    One setting entry like playLogoVideos

Return value

The function returns an option value as a string or empty string if option was not found.

MEM_GetModOpt

Searches the loaded mod ini file for option.

func void MEM_GetModOpt(var string sectionname, var string optionname)
-
Parameters
  • var string sectionname
    Settings section like [INFO]
  • var string optionname
    One setting entry like Title

Return value

The function returns an option value as a string or empty string if option was not found.

MEM_GothOptSectionExists

Checks whether a section exists in Gothic.ini

func int MEM_GothOptSectionExists(var string sectionname)
-
Parameters
  • var string sectionname
    Settings section like [GAME]

Return value

The function returns TRUE if section exists FALSE is returned otherwise.

MEM_ModOptSectionExists

Checks whether a section exists in loaded mod ini file

func int MEM_ModOptSectionExists(var string sectionname)
-
Parameters
  • var string sectionname
    Settings section like [INFO]

Return value

The function returns TRUE if section exists FALSE is returned otherwise.

MEM_GothOptExists

Checks whether an option exists in Gothic.ini

func int MEM_GothOptExists(var string sectionname, var string optionname)
-
Parameters
  • var string sectionname
    Settings section like [GAME]
  • var string optionname
    One setting entry like playLogoVideos

Return value

The function returns TRUE if option in a section exist FALSE is returned otherwise.

MEM_ModOptExists

Checks whether an option exists in loaded mod ini file

func int MEM_ModOptExists(var string sectionname, var string optionname)
-
Parameters
  • var string sectionname
    Settings section like [INFO]
  • var string optionname
    One setting entry like Title

Return value

The function returns TRUE if option in a section exist FALSE is returned otherwise.

Write functions

Warning

Mod configuration is never saved to disk, therefore no separate functions exist for writing to it.

MEM_SetGothOpt

The option option in the section section is set to the value. If the section and/or option does not exist, it will be created.

func void MEM_SetGothOpt(var string section, var string option, var string value)
-
Parameters
  • var string section
    The section where the option should be located
  • var string option
    Option to write/overwrite
  • var string value
    Value to set the option to

MEM_ApplyGothOpt

Applies the changes and saves the ini to disk

func void MEM_ApplyGothOpt()
-

Tip

If you introduce new options, it is best to follow certain practices. It is a good practice to name your options in a clear manner and place them in a section named the same as your mod. Do not place your mod options into the [GAME] or [PERFORMANCE] sections.

Key functions

The Gothic.ini contains the assignment of physical keys (e.g. "W") to logical keys (e.g. "keyUp").

MEM_GetKey

Returns the primary key assigned to logical key.

func int MEM_GetKey(var string name)
-
Parameters
  • var string name
    Name of the logical key

Return value

The function returns key assigned to logical key

MEM_GetSecondaryKey

Returns a secondary key assigned to logical key.

func int MEM_GetSecondaryKey(var string name)
-
Parameters
  • var string name
    Name of the logical key

Return value

The function returns key assigned to logical key

MEM_SetKeys

Sets keyboard keys of the logical key.

func void MEM_SetKeys(var string name, var int primary, var int secondary)
-
Parameters

MEM_SetKey

Sets the primary keyboard key of the logical key.

func void MEM_SetKey(var string name, var int key)
-
Parameters

MEM_SetSecondaryKey

Sets the secondary keyboard key of the logical key.

func void MEM_SetSecondaryKey(var string name, var int key)
-
Parameters
\ No newline at end of file diff --git a/zengin/scripts/extenders/ikarus/functions/jumps_loops/index.html b/zengin/scripts/extenders/ikarus/functions/jumps_loops/index.html deleted file mode 100644 index 25808edecc..0000000000 --- a/zengin/scripts/extenders/ikarus/functions/jumps_loops/index.html +++ /dev/null @@ -1,560 +0,0 @@ - Jumps and Loops - Gothic Modding Community

Jumps and Loops

Jumps

Jumps in Ikarus are implemented by direct manipulation of the stack pointer, achieved with two lines of code. These lines enable the change of the current position within the parser stack, representing machine-level code generated during script compilation. By querying and setting this position, the execution flow can be redirected to a new location in the code.

Initialization

To ensure the correct functioning of this jump mechanism, it is crucial to execute the MEM_InitLabels() function once after loading a saved game. The recommended practice is to integrate this initialization function within INIT_GLOBAL. It's only after MEM_InitLabels() has been called that accessing MEM_StackPos.position becomes valid.

func void MEM_InitLabels()
-

Tip

It's worth noting that MEM_InitLabels is also invoked by the MEM_InitAll function.

Usage

  • Label Initialization
    Before attempting a jump, it's important to initialize the label to which the jump is intended. Forward jumps, where the jump point is encountered before the jump target, can be challenging. Label initialization looks like that:
    1
    -2
    -3
    -4
    // [...]
    -var int label;
    -label = MEM_StackPos.position;
    -// [...]
    -
  • Actual jump
    After initializing the label you could simply jump to it by setting MEM_StackPos.position to the label.
    1
    -2
    -3
    // [...]
    -MEM_StackPos.position = label;
    -// [...]
    -

Jump flowchart

flowchart TD
-A(Start) --> B["var int label; \n label = MEM_StackPos.position;"];
-B --> C{Your code}
-C -->D["MEM_StackPos.position = label;"];
-C --> E(End)
-D --> |Jump| B;

Notes and warnings

  • Validity of Labels
    Labels become invalid after saving and loading. Consequently, labels should be used immediately, and there is generally no reason to persist them for an extended period.

  • Caution with Jumping
    Jumping between different functions without a clear understanding of the code structure can lead to unexpected issues. Similarly, using labels without a thorough comprehension of their purpose may result in undesired consequences. It's crucial to exercise caution, especially when making assignments involving labels.

Examples

The following code outputs the numbers from 0 to 42:

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
func void foo() {
-    /* Initialization */
-    MEM_InitLabels();
-    var int count; count = 0;
-
-    /* Record the execution position in label. */
-    var int label;
-    label = MEM_StackPos.position;
-    /* <---- label now points here,
-    * i.e. to the position AFTER the assignment of label. */
-
-    Print (ConcatStrings ("COUNT: ", IntToString (count)));
-    count += 1;
-
-    if (count <= 42) {
-        /* Replace the execution position,
-        * with the "<-----" the system then continues */
-        MEM_StackPos.position = label;
-    };
-
-    /* Once 43 is reached, the “loop” is exited. */
-};
-

The following code should enumerate all pairs (x,y) with 0 <= x < max_x, 0 <= y < max_y

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
-37
-38
-39
-40
-41
-42
-43
-44
-45
-46
func void printpairs(var int max_x, var int max_y)
-{
-    // Initialize labels
-    MEM_InitLabels();
-    // PrintDebug should be used, i.e. activate debug output
-    MEM_SetShowDebug (1);
-
-    var int x; var int y; x = 0;
-
-    // while (x < max_x)
-    var int x_loop; x_loop = MEM_StackPos.position;
-    if (x < max_x)
-    { 
-        y = 0;
-        // while (y < max_y) 
-        var int y_loop; y_loop = MEM_StackPos.position;
-        if (y < max_y)
-        { 
-            var string out; out = "(";
-            out = ConcatStrings (out, IntToString (x));
-            out = ConcatStrings (out, ", ");
-            out = ConcatStrings (out, IntToString (y));
-            out = ConcatStrings (out, ")");
-            PrintDebug (out);
-            y += 1;
-
-            // continue y_loop 
-            MEM_StackPos.position = y_loop;
-        };
-        x += 1;
-        // continue x_loop
-        MEM_StackPos.position = x_loop;
-    };
-};
-
-/*
-    Output of a call printpairs(4,2) would then be: 
-    00:36 Info: 5 U: Skript: (0, 0) .... 
-    00:36 Info: 5 U: Skript: (0, 1) .... 
-    00:36 Info: 5 U: Skript: (1, 0) .... 
-    00:36 Info: 5 U: Skript: (1, 1) .... 
-    00:36 Info: 5 U: Skript: (2, 0) .... 
-    00:36 Info: 5 U: Skript: (2, 1) .... 
-    00:36 Info: 5 U: Skript: (3, 0) .... 
-    00:36 Info: 5 U: Skript: (3, 1) .... 
-*/
-

Label and Goto

Besides the normal jumps Ikarus implements MEM_Label and MEM_Goto functions. They work similar to the stack manipulation with var int label but the interface is much more user-friendly and defining new variables is not needed.

MEM_Label

Function that works like a label = MEM_StackPos.position;. You could jump to it with MEM_Goto.

func void MEM_Label(var int lbl)
-
Parameters
  • var int lbl
    Number of the label, used for nested loop or multiple loops within one function

MEM_Goto

Function that works like a MEM_StackPos.position = label;. Executes a jump to a MEM_Label with specified number.

func void MEM_Goto(var int lbl)
-
Parameters
  • var int lbl
    Number of the label, the function will jump to

Usage

Usage of Label and Goto is probably self-explanatory, since it is same as in the regular Ikarus Jump. But before using it reading the Notes and warnings of the Jumps is recommended.

Label-Goto loop flowchart

flowchart TD
-A(Start) --> B["MEM_Label(0);"];
-B --> C{Your code}
-C -->D["MEM_Goto(0);"];
-C --> E(End)
-D --> |Jump| B;
Label-Goto loop
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
func void LabelGoto_test() {
-    var int i; 
-    MEM_Label(0);
-        MEM_Debug(IntToString(i));
-        i = i + 1;
-        if(i >= 4)
-        {
-            return;
-        };
-        MEM_Goto(0);
-};
-
-//  Results:
-//  Info:  0 Q:     Debug: 0
-//  Info:  0 Q:     Debug: 1
-//  Info:  0 Q:     Debug: 2
-//  Info:  0 Q:     Debug: 3
-

Examples

The following code outputs the numbers from 0 to 42:

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
func void foo() {
-    var int count; count = 0;
-
-    MEM_Label(0);
-    /* <---- label now points here,
-    * i.e. to the position AFTER the assignment of label. */
-
-    Print (ConcatStrings ("COUNT: ", IntToString (count)));
-    count += 1;
-
-    if (count <= 42) {
-        // Jump to the MEM_Label
-        MEM_Goto(0);
-    };
-
-    /* Once 43 is reached, the “loop” is exited. */
-};
-

The following code should enumerate all pairs (x,y) with 0 <= x < max_x, 0 <= y < max_y

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
-37
-38
-39
-40
-41
-42
func void printpairs(var int max_x, var int max_y)
-{
-    // PrintDebug should be used, i.e. activate debug output
-    MEM_SetShowDebug (1);
-
-    var int x; var int y; x = 0;
-
-    // while (x < max_x)
-    MEM_Label(0);
-    if (x < max_x)
-    { 
-        y = 0;
-        // while (y < max_y) 
-        MEM_Label(1);
-        if (y < max_y)
-        { 
-            var string out; out = "(";
-            out = ConcatStrings (out, IntToString (x));
-            out = ConcatStrings (out, ", ");
-            out = ConcatStrings (out, IntToString (y));
-            out = ConcatStrings (out, ")");
-            PrintDebug (out);
-            y += 1;
-
-            MEM_Goto(1);
-        };
-        x += 1;
-       MEM_Goto(0);
-    };
-};
-
-/*
-    Output of a call printpairs(4,2) would then be: 
-    00:36 Info: 5 U: Skript: (0, 0) .... 
-    00:36 Info: 5 U: Skript: (0, 1) .... 
-    00:36 Info: 5 U: Skript: (1, 0) .... 
-    00:36 Info: 5 U: Skript: (1, 1) .... 
-    00:36 Info: 5 U: Skript: (2, 0) .... 
-    00:36 Info: 5 U: Skript: (2, 1) .... 
-    00:36 Info: 5 U: Skript: (3, 0) .... 
-    00:36 Info: 5 U: Skript: (3, 1) .... 
-*/
-

While loop

Ikarus also implements a while loop. Its syntax isn't as good as the loop from zParserExtender, due to the daedalus limitations, but it works as a normal while loop that can be found in many programming languages.

Syntax

The Ikarus while loop consist of three things:

  • while function
    That works like a while statement and start of the brace while(var int b){.

    func void while(var int b)
    -
  • end constant
    That works like an ending brace }.

    const int end = -72;
    -
  • break and continue constant
    These two constants works like a regular break and continue statements in C.

    1
    -2
    const int break = -42;
    -const int continue = -23;
    -
while loop
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
func void while_test() {
-    var int value; value = 10;
-    while(value > 0); //{
-
-        if (value == 8)
-        {
-            continue;
-        };
-
-        if (value == 2)
-        {
-            break;
-        };
-    end; //}
-};
-

Examples

The following code outputs the numbers from 0 to 42:

1
-2
-3
-4
-5
-6
-7
-8
-9
func void foo() {
-    var int count; count = 0;
-    while(count <= 42); //{
-        Print (ConcatStrings ("COUNT: ", IntToString (count)));
-        count += 1;
-    end; //}
-
-    /* Once 43 is reached, the loop is exited. */
-}; 
-

The following code should enumerate all pairs (x,y) with 0 <= x < max_x, 0 <= y < max_y

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
func void printpairs(var int max_x, var int max_y)
-{
-    // PrintDebug should be used, i.e. activate debug output
-    MEM_SetShowDebug (1);
-
-    var int x; var int y; x = 0;
-
-    while(x < max_x); //{
-        y = 0;
-        while(y < max_y); //{  
-            var string out; out = "(";
-            out = ConcatStrings (out, IntToString (x));
-            out = ConcatStrings (out, ", ");
-            out = ConcatStrings (out, IntToString (y));
-            out = ConcatStrings (out, ")");
-            PrintDebug (out);
-            y += 1;
-        end; //}
-        x += 1;
-    end; //}
-};
-
-/*
-    Output of a call printpairs(4,2) would then be: 
-    00:36 Info: 5 U: Skript: (0, 0) .... 
-    00:36 Info: 5 U: Skript: (0, 1) .... 
-    00:36 Info: 5 U: Skript: (1, 0) .... 
-    00:36 Info: 5 U: Skript: (1, 1) .... 
-    00:36 Info: 5 U: Skript: (2, 0) .... 
-    00:36 Info: 5 U: Skript: (2, 1) .... 
-    00:36 Info: 5 U: Skript: (3, 0) .... 
-    00:36 Info: 5 U: Skript: (3, 1) .... 
-*/
-

Repeat loop

In addition Ikarus implements something called Repeat loop.

Initialization

To use Repeat loop you must first call MEM_InitRepeat() function once after loading a saved game. The recommended practice is to integrate this initialization function within INIT_GLOBAL.

func void MEM_InitRepeat()
-

Tip

It's worth noting that MEM_InitRepeat is also invoked by the MEM_InitAll function.

Syntax

Repeat loop has a syntax very similar to the while loop. It also uses end constant as an ending brace. break and continue statements can be used within it as well. The main difference is the main loop function Repeat that has following properties:

func void Repeat(var int variable, var int limit)
-
  • var int variable
    A variable that increase with every loop iteration.
  • var int limit
    A variable that defines the number of loop iterations. If variable >= limit the loop is exited.

Repeat loop flowchart

flowchart TD
-    A(Start) --> B["Repeat(i, limit)"] 
-    B --> C{i < limit}
-    C -->|true| D[Command]
-    D --> |i = i + 1| B
-    C --> |false| E(End)
Repeat loop
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
func void Repeat_test() {
-    Repeat(i, 4); var int i; //{
-        MEM_Debug(IntToString(i));
-    end; //}
-};
-
-//  Results:
-//  Info:  0 Q:     Debug: 0
-//  Info:  0 Q:     Debug: 1
-//  Info:  0 Q:     Debug: 2
-//  Info:  0 Q:     Debug: 3
-

Examples

The following code outputs the numbers from 0 to 42:

1
-2
-3
-4
-5
-6
-7
func void foo() {
-    Repeat(count, 43); var int count; //{
-        Print (ConcatStrings ("COUNT: ", IntToString (count)));
-    end; //}
-
-    /* Once 43 is reached, the loop is exited. */
-}; 
-

The following code should enumerate all pairs (x,y) with 0 <= x < max_x, 0 <= y < max_y

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
func void printpairs(var int max_x, var int max_y)
-{
-    // PrintDebug should be used, i.e. activate debug output
-    MEM_SetShowDebug (1);
-
-    var int x; var int y; x = 0;
-
-    Repeat(x, max_x); //{
-        y = 0;
-        Repeat(y, max_y); //{  
-            var string out; out = "(";
-            out = ConcatStrings (out, IntToString (x));
-            out = ConcatStrings (out, ", ");
-            out = ConcatStrings (out, IntToString (y));
-            out = ConcatStrings (out, ")");
-            PrintDebug (out);
-        end; //}
-    end; //}
-};
-
-/*
-    Output of a call printpairs(4,2) would then be: 
-    00:36 Info: 5 U: Skript: (0, 0) .... 
-    00:36 Info: 5 U: Skript: (0, 1) .... 
-    00:36 Info: 5 U: Skript: (1, 0) .... 
-    00:36 Info: 5 U: Skript: (1, 1) .... 
-    00:36 Info: 5 U: Skript: (2, 0) .... 
-    00:36 Info: 5 U: Skript: (2, 1) .... 
-    00:36 Info: 5 U: Skript: (3, 0) .... 
-    00:36 Info: 5 U: Skript: (3, 1) .... 
-*/
-
\ No newline at end of file diff --git a/zengin/scripts/extenders/ikarus/functions/keyboard/index.html b/zengin/scripts/extenders/ikarus/functions/keyboard/index.html deleted file mode 100644 index 5cb0a1b2d7..0000000000 --- a/zengin/scripts/extenders/ikarus/functions/keyboard/index.html +++ /dev/null @@ -1,38 +0,0 @@ - Keyboard - Gothic Modding Community

Keyboard interaction

This part of Ikarus implements function that make interaction with keyboard possible.

Info

Keyboard interaction is also implemented with gameKeyEvents.d

Initialization

The best way to initialize all Ikarus functions is to call MEM_InitAll() in the Init_Global() initialization function.

Warning

If you want to use Ikarus in Gothic 1, it is best to define your own Init_Global() function and call it from every world initialization function.

MEM_InitAll();
-

Implementation

Ikarus.d on GitHub

Functions

Tip

Different players use different keys for specific actions! However, it is possible to get key assigned to the action from Gothic.ini. See Ini access.

MEM_KeyPressed

Checks if the key is hold right at the moment of function call.

func int MEM_KeyPressed(var int key)
-
Parameters
  • var int key
    Checked key

Return value

The function returns TRUE if the key is hold, FALSE is returned otherwise.

MEM_KeyState

Returns the state of the key.

func int MEM_KeyState(var int key)
-
Parameters
  • var int key
    Checked key

Return value

The function returns actual key state.

Key states

  • KEY_UP - The key is not pressed and was not pressed before. ("not pressed")
  • KEY_PRESSED - The key is pressed and was not previously pressed. ("new pressed")
  • KEY_HOLD - The key is pressed and was also pressed before. ("still pressed")
  • KEY_RELEASED - The key is not pressed and was previously pressed. ("let go")

KEY_PRESSED or KEY_RELEASED will be returned if the state of the key has changed since the last query.

KEY_UP or KEY_HOLD are returned if the state has not changed.

MEM_InsertKeyEvent

Makes the game think that the key was pressed.

func void MEM_InsertKeyEvent(var int key)
-
Parameters
  • var int key
    Key to be "pressed"
\ No newline at end of file diff --git a/zengin/scripts/extenders/ikarus/functions/mem_access/index.html b/zengin/scripts/extenders/ikarus/functions/mem_access/index.html deleted file mode 100644 index 1a2e60999e..0000000000 --- a/zengin/scripts/extenders/ikarus/functions/mem_access/index.html +++ /dev/null @@ -1,53 +0,0 @@ - Memory Access - Gothic Modding Community

Elementary memory access

This part of Ikarus makes it possible to read and write memory as different data types - integers, strings, arrays of integers or strings and bytes.

If address <= 0, an error is thrown. Otherwise, an attempt is made to read or write at this address. If the address falls into invalid range, for example in a code segment, access violation will occur (Gothic crashes). In the case of string operations, it is also necessary that at the specified position a valid zString already exists.

Initialization

The best way to initialize all Ikarus functions is to call MEM_InitAll() in the Init_Global() initialization function.

Warning

If you want to use Ikarus in Gothic 1, it is best to define your own Init_Global() function and call it from every world initialization function.

MEM_InitAll();
-

Implementation

Ikarus.d on GitHub

Read functions

MEM_ReadInt

Reads int from the address.

func int MEM_ReadInt(var int address)
-
Parameters
  • var int address
    Memory address to read from

Return value

The function returns an integer value if the address is correct.

MEM_ReadString

Reads string from the address.

func string MEM_ReadString(var int address)
-
Parameters
  • var int address
    Memory address to read from

Return value

The function returns string if the address is correct.

MEM_ReadByte

Reads byte from the address.

func int MEM_ReadByte(var int address)
-
Parameters
  • var int address
    Memory address to read from

Return value

The function returns byte value if the address is correct.

MEM_ReadIntArray

Reads int from the array at the arrayAddress.

func int MEM_ReadIntArray(var int arrayAddress, var int offset)
-
Parameters
  • var int arrayAddress
    Memory address of array
  • var int offset
    Array offset (array index)

Return value

The function returns integer value from the array if the address is correct.

MEM_ReadStringArray

Info

MEM_ReadStringArray has been already moved to the LeGo PermMem package.

MEM_ReadByteArray

Reads byte from the array at the arrayAddress.

func int MEM_ReadByteArray(var int arrayAddress, var int offset)
-
Parameters
  • var int arrayAddress
    Memory address of array
  • var int offset
    Array offset (array index)

Return value

The function returns byte from the array if the address is correct.

Write functions

MEM_WriteInt

Writes int value in the address.

func void MEM_WriteInt(var int address, var int value)
-
Parameters
  • var int address
    Memory address to write into
  • var int value
    Integer value to write
Example

An example of using this function is the following Ikarus function, which turns debugging messages on and off:

1
-2
-3
-4
func void MEM_SetShowDebug(var int on)
-{
-    MEM_WriteInt(showDebugAddress, on);
-};
-

MEM_WriteString

Writes string in the address.

func void MEM_WriteString(var int address, var string value)
-
Parameters
  • var int address
    Memory address to write into
  • var int value
    String to write

MEM_WriteByte

Only the byte at address address is changed here, not a whole four-byte word. That is, the three subsequent bytes remain untouched. If 0 <= val < 256 does not apply in MEM_WriteByte, a warning is issued and val is trimmed accordingly. In particular, shouldn't be negative numbers are passed.

func void MEM_WriteByte(var int address, var int value)
-
Parameters
  • var int address
    Memory address to write into
  • var int value
    Byte to write

MEM_WriteIntArray

Writes int value in the array at arrayAddress.

func void MEM_WriteIntArray(var int arrayAddress, var int offset, var int value)
-
Parameters
  • var int arrayAddress
    Memory address of array
  • var int offset
    Array offset (array index)
  • var int value
    Integer value to write

MEM_WriteStringArray

Writes string value in the array at arrayAddress.

func void MEM_WriteStringArray(var int arrayAddress, var int offset, var string value)
-
Parameters
  • var int arrayAddress
    Memory address of array
  • var int offset
    Array offset (array index)
  • var string value
    String to write

MEM_WriteByteArray

Writes byte value in the array at arrayAddress.

func void MEM_WriteByteArray(var int arrayAddress, var int offset, var int value)
-
Parameters
  • var int arrayAddress
    Memory address of array
  • var int offset
    Array offset (array index)
  • var int value
    Byte to write
\ No newline at end of file diff --git a/zengin/scripts/extenders/ikarus/functions/mem_utility/index.html b/zengin/scripts/extenders/ikarus/functions/mem_utility/index.html deleted file mode 100644 index 142768cd1e..0000000000 --- a/zengin/scripts/extenders/ikarus/functions/mem_utility/index.html +++ /dev/null @@ -1,48 +0,0 @@ - Memory utility - Gothic Modding Community

Memory utility

Ikarus utility functions, for memory management and manipulation.

Initialization

The best way to initialize all Ikarus functions is to call MEM_InitAll() in the Init_Global() initialization function.

Warning

If you want to use Ikarus in Gothic 1, it is best to define your own Init_Global() function and call it from every world initialization function.

MEM_InitAll();
-

Implementation

Ikarus.d on GitHub

Functions

MEM_Alloc

Allocates a specified amount of memory and returns a pointer to the allocated memory area.

Danger

Gothic does not and cannot retain a reference to this memory area or release it, even when destroying the session. Therefore, memory should only be reserved under certain conditions:

  • It is guaranteed to exist and can be released again with MEM_Free after loading a save game.
  • Gothic is aware of this memory area and independently releases it.

It might be possible to create new objects with this function and permanently integrate them into the object structure of Gothic. However, extreme caution is advised, as object structures cannot be used, and manual handling is required.

This function is well-suited for building small elements like list items and integrating them into existing lists. The memory allocated by this function is always initialized to zero.

func int MEM_Alloc(var int amount)
-
Parameters
  • var int amount
    The amount of bytes to allocate

Return value

The function returns a pointer to the allocated memory area.

MEM_Realloc

Allocates a memory area of ​​size newsize and returns a pointer to this memory area. The memory area from location ptr is released.

If newsize >= oldsize, the first oldsize bytes from the old memory area are transferred to the new one. The additional memory is initialized with zero.

If newsize <= oldsize, all bytes of the new memory area are initialized with the corresponding values ​​of the old memory area.

This function is intended to create an allocated memory area enlarge or reduce. Existing data remains naturally way received.

func int MEM_Realloc(var int ptr, var int oldsize, var int newsize)
-
Parameters
  • var int ptr
    The original pointer to the memory block
  • var int oldsize
    The size of the original memory block
  • var int newsize
    The size of the new memory block

Return value

The function returns a pointer to the modified memory area.

MEM_Free

Releases an allocated memory area.

Danger

Great caution is advised, especially when attempting to destroy engine objects, as no destructors are called!

Releasing small things such as list elements can be done easily.

func void MEM_Free(var int ptr)
-
Parameters
  • var int ptr
    Pointer to the released memory block

MEM_Copy

Copies a specified number of words from the source address to the destination address.

func void MEM_Copy(var int src, var int dst, var int wordcount)
-
Parameters
  • var int src
    The source address to copy from
  • var int dst
    The destination address to copy to
  • var int wordCount
    The number of words to copy

MEM_CopyWords

Alias to MEM_Copy. Copies a specified number of words from the source address to the destination address.

func void MEM_CopyWords(var int src, var int dst, var int wordcount) 
-
Parameters
  • var int src
    The source address to copy from
  • var int dst
    The destination address to copy to
  • var int wordCount
    The number of words to copy

MEM_CopyBytes

Copies a specified number of bytes from the source address to the destination address

func void MEM_CopyBytes(var int src, var int dst, var int byteCount)
-
Parameters
  • var int src
    The source address to copy from
  • var int dst
    The destination address to copy to
  • var int byteCount
    The number of bytes to copy

MEM_Swap

Swaps a specified number of words between the source address and the destination address.

func void MEM_Swap(var int src, var int dst, var int wordCount)
-
Parameters
  • var int src
    The source address to swap from
  • var int dst
    The destination address to swap to
  • var int wordCount
    The number of words to swap

MEM_SwapWords

Alias to MEM_Swap. Swaps a specified number of words between the source address and the destination address.

func void MEM_SwapWords(var int src, var int dst, var int wordCount)
-
Parameters
  • var int src
    The source address to swap from
  • var int dst
    The destination address to swap to
  • var int wordCount
    The number of words to swap

MEM_SwapBytes

Swaps a specified number of bytes between the source address and the destination address.

func void MEM_SwapBytes(var int src, var int dst, var int byteCount)
-
Parameters
  • var int src
    The source address to swap from
  • var int dst
    The destination address to swap to
  • var int byteCount
    The number of bytes to swap

MEM_Clear

Sets a specified number of bytes in memory to zero.

func void MEM_Clear(var int ptr, var int size)
-
Parameters
  • var int ptr
    The memory address to start clearing from
  • var int size
    The number of bytes to clear

MEM_Compare

Compares a specified number of words between two memory blocks.

func int MEM_Compare(var int ptr0, var int ptr1, var int wordCount)
-
Parameters
  • var int ptr0
    The first memory block to compare
  • var int ptr1
    The second memory block to compare
  • var int wordCount
    The number of words to compare

Return value

The function returns TRUE if the memory blocks are equal, FALSE is returned otherwise.

MEM_CompareWords

Alias to MEM_Compare. Compares a specified number of words between two memory blocks.

func int MEM_CompareWords(var int ptr0, var int ptr1, var int wordCount)
-
Parameters
  • var int ptr0
    The first memory block to compare
  • var int ptr1
    The second memory block to compare
  • var int wordCount
    The number of words to compare

Return value

The function returns TRUE if the memory blocks are equal, FALSE is returned otherwise.

MEM_CompareBytes

Compares a specified number of bytes between two memory blocks.

func int MEM_CompareBytes(var int ptr1, var int ptr2, var int byteCount)
-
Parameters
  • var int ptr0
    The first memory block to compare
  • var int ptr1
    The second memory block to compare
  • var int wordCount
    The number of bytes to compare

Return value

The function returns TRUE if the memory blocks are equal, FALSE is returned otherwise.

\ No newline at end of file diff --git a/zengin/scripts/extenders/ikarus/functions/menu_access/index.html b/zengin/scripts/extenders/ikarus/functions/menu_access/index.html deleted file mode 100644 index 51e61bea9d..0000000000 --- a/zengin/scripts/extenders/ikarus/functions/menu_access/index.html +++ /dev/null @@ -1,37 +0,0 @@ - Access Menu Objects - Gothic Modding Community

Access Menu Objects

These Ikarus functions are intended to provide and simplify access to menu items (e.g. in the character menu).

Tip

Some menus are generated every time they are used, while others are generated once and then kept. For example, a character menu is only available after it was opened for the first time, after that it is kept in memory. Depending on what you actually want to do, it can make sense to introduce changes in the menu scripts.

Initialization

The best way to initialize all Ikarus functions is to call MEM_InitAll() in the Init_Global() initialization function.

Warning

If you want to use Ikarus in Gothic 1, it is best to define your own Init_Global() function and call it from every world initialization function.

MEM_InitAll();
-

Implementation

Ikarus.d on GitHub

Functions

MEM_GetMenuByString

func int MEM_GetMenuByString(var string menuName)
-

Parameters

  • var string menuName
    Name of the Gothic menu e.g. MENU_STATUS

Return value

The function returns the address of the menu if a menu with this name exists, null otherwise.

MEM_GetMenuItemByString

func int MEM_GetMenuItemByString(var string menuItemName)
-

Parameters

  • var string menuItemName
    Name of the Gothic menu item e.g. MENU_ITEM_PLAYERGUILD_TITLE

Return value

The function returns the address of the menu item if a menu item with this name exists, null otherwise.

\ No newline at end of file diff --git a/zengin/scripts/extenders/ikarus/functions/objects/index.html b/zengin/scripts/extenders/ikarus/functions/objects/index.html deleted file mode 100644 index 2dc46c8944..0000000000 --- a/zengin/scripts/extenders/ikarus/functions/objects/index.html +++ /dev/null @@ -1,155 +0,0 @@ - zCObjects - Gothic Modding Community

zCObjects

Set of functions for working with zCObject and its subclasses instances.

Initialization

The best way to initialize all Ikarus functions is to call MEM_InitAll() in the Init_Global() initialization function.

Warning

If you want to use Ikarus in Gothic 1, it is best to define your own Init_Global() function and call it from every world initialization function.

MEM_InitAll();
-

Implementation

Ikarus.d on GitHub

Global instances

Ikarus package introduces the following instances:

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
instance MEM_Game (oCGame);
-instance MEM_World(oWorld);
-instance MEM_Timer(zCTimer);
-instance MEM_WorldTimer(oCWorldTimer);
-instance MEM_Vobtree(zCTree);
-instance MEM_InfoMan(oCInfoManager);
-instance MEM_InformationMan (oCInformationManager);
-instance MEM_Waynet(zCWaynet);
-instance MEM_Camera(zCCamera);
-instance MEM_SkyController(zCSkyController_Outdoor);
-instance MEM_SpawnManager (oCSpawnManager);
-instance MEM_GameMananger (CGameManager);
-instance MEM_GameManager (CGameManager);
-instance MEM_Parser(zCParser);
-

The classes used here all have one thing in common: there is a maximum of one object of them at the same time (e.g. there is not two worlds or two sky at the same time).

MEM_InitGlobalInst function sets the offsets of these instances to the corresponding unique object. While it has been called, all of the above instances can be used.

MEM_InitGlobalInst

Initializes global instances of commonly used objects in the game (is called by the MEM_InitAll function).

func void MEM_InitGlobalInst()
-

Warning

MEM_InitGlobalInst must be executed once after loading a savegame. The easiest way is do it is to call this function from INIT_GLOBAL.

Functions

About zCClassDef

For every class (derived from zCObject) there is an "administrative object" of type zCClassDef. This encapsulates some useful information about all objects in this class.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
class zCClassDef {
-    var string className;            //zSTRING
-    var string baseClassName;        //zSTRING
-    var string scriptClassName;      //zSTRING
-    var int baseClassDef;            //zCClassDef*
-    var int createNewInstance;       //zCObject* ( *) (void) 
-    var int createNewInstanceBackup; //zCObject* ( *) (void)
-    var int classFlags;              //zDWORD
-    var int classSize;               //zDWORD
-    var int numLivingObjects;
-    var int numCtorCalled;
-    var int hashTable;               //zCObject**
-    var int objectList_array;        //zCObject**
-    var int objectList_numAlloc;     //int
-    var int objectList_numInArray;   //int
-    var int bitfield;
-};
-

Full Ikarus definition of this class, with members description can be found in Misc.d file. The class is same for G1 and G2A engines.

MEM_GetClassDef

Returns a pointer to the zCClassDef of the object. For more info see the About zCClassDef section above.

Passing these functions a pointer that does not point to a zCObject will most likely result in a crash lead.

func int MEM_GetClassDef(var int objPtr)
-
Parameters
  • var int objPtr
    A pointer to the object whose class definition is to be retrieved

Return value

The function returns a pointer to the zCClassDef of the object.

Example

This would return a pointer to the zCClassDef object that belongs to the oCNpc class.

1
-2
-3
-4
-5
func int example1
-{
-    var int her; her = MEM_InstToPtr(hero);
-    return MEM_GetClassDef(her);
-};
-

MEM_GetClassName

This function returns the name of the class to which an object belongs.

func string MEM_GetClassName(var int objPtr)
-
Parameters
  • var int objPtr
    A pointer to the object whose class name is to be retrieved

Return value

The function returns the objects class name as a string, if the object is invalid an empty string is returned.

Example

This would return a name of the oCNpc class as a string.

1
-2
-3
-4
-5
-6
func string example2
-{
-    var int her; her = MEM_InstToPtr(hero);
-    return MEM_GetClassName(her);
-};
-// return: "oCNpc"
-

MEM_CheckInheritance

Checks if an object is derived from a specific class definition.

func int MEM_CheckInheritance(var int objPtr, var int classDef)
-
Parameters
  • var int objPtr
    A pointer to the object to be checked
  • var int classDef
    A pointer to the class definition to check against

Return value

The function returns TRUE if the object is derived from the specified class definition, FALSE is returned otherwise.

Hlp_Is_*

In addition MEM_CheckInheritance function has some overloads with hardcoded classDef parameter.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
func int Hlp_Is_oCMobFire(var int ptr){};
-func int Hlp_Is_zCMover(var int ptr){};
-func int Hlp_Is_oCMob(var int ptr){};
-func int Hlp_Is_oCMobInter(var int ptr){};
-func int Hlp_Is_oCMobLockable(var int ptr){};
-func int Hlp_Is_oCMobContainer(var int ptr){};
-func int Hlp_Is_oCMobDoor(var int ptr){};
-func int Hlp_Is_oCMobBed(var int ptr){};
-func int Hlp_Is_oCMobSwitch(var int ptr){};
-func int Hlp_Is_oCMobWheel(var int ptr){};
-func int Hlp_Is_oCMobLadder(var int ptr){};
-func int Hlp_Is_oCNpc(var int ptr){};
-func int Hlp_Is_oCItem(var int ptr){};
-func int Hlp_Is_zCVobLight(var int ptr){};
-

The usage of these functions is probably obvious, they checks if the given object belongs to class given in the function name.

MEM_InsertVob

Inserts a Vob with the visual vis at the waypoint wp. If the visual or waypoint does not exist, this is the behaviour this function undefined.

Note

The inserted Vob is even an oCMob, so it can be given a focus name, for example. But you can treat it like a zCVob), if you don't need the additional properties.

func int MEM_InsertVob(var string vis, var string wp)
-
Parameters
  • var string vis
    Name of the inserted Vob visual ("FAKESCROLL.3DS", "FIRE.PFX", "SNA_BODY.ASC", "CHESTSMALL_NW_POOR_LOCKED.MDS", "ADD_PIRATEFLAG.MMS" etc.)
  • var string wp
    Name of the waypoint to insert Vob on

Return value

The function returns a pointer to the created object.

MEM_DeleteVob

Deletes a specific Vob form world.

func void MEM_DeleteVob(var int vobPtr)
-
Parameters
  • var int vobPtr
    Pointer to a zCVob object to be deleted

MEM_RenameVob

Renames the passed Vob to the newName that is also passed.

The object becomes this first removed from the Vob-hashtable, then unnamed and then again inserted into the Vob-hashtable under a new name.

func void MEM_RenameVob(var int vobPtr, var string newName)
-
Parameters
  • var int vobPtr
    Pointer to a zCVob object to be renamed
  • var string newName
    The new Name of the Vob

MEM_TriggerVob

Sends a trigger message to the Vob.

func void MEM_TriggerVob(var int vobPtr)
-
Parameters
  • var int vobPtr
    Pointer to a triggered zCVob

Danger

If triggering the Vob has immediate effects (even before MEM_TriggerVob is exited), the name of the Vob is corrupted during this time. It is not advisable to rename, trigger again or destroy the object at this moment, the behavior in such cases is untested.

MEM_UntriggerVob

Sends an untrigger message to the Vob.

func void MEM_TriggerVob(var int vobPtr)
-
Parameters
  • var int vobPtr
    Pointer to an untriggered zCVob

Danger

If untriggering the Vob has immediate effects (even before MEM_TriggerVob is exited), the name of the Vob is corrupted during this time. It is not advisable to rename, trigger again or destroy the object at this moment, the behavior in such cases is untested.

MEM_SearchVobByName

Returns the address of a zCVob named str if such a Vob exists.

func int MEM_SearchVobByName(var string str)
-
Parameters
  • var string str
    Name of searched zCVob

Return value

The function returns a pointer to the zCVob if the object with the given name exist. 0 is returned otherwise.

MEM_SearchAllVobsByName

Variation of MEM_SearchVobByName. Creates a zCArray in which all pointers are to Vobs with the name str. If no Vob with the name exists, an empty zCArray is created. A pointer to the created zCArray is then returned. This can be evaluated, but should be released again with MEM_ArrayFree before the end of the frame (before the player can load) to avoid memory leaks.

func int MEM_SearchAllVobsByName(var string str)
-
Parameters
  • var string str
    Name of searched zCVob

Return value

The function returns a pointer to the created zCArray, that contains pointers to the all Vobs with the specified name.

MEM_GetBufferCRC32

Calculates the CRC32 hash value from a byte array starting at the address specified by buf and having a length of buflen.

func int MEM_GetBufferCRC32(var int buf, var int buflen)
-
Parameters
  • var int buf
    Address of a byte array, the hash calculation will begin from

  • var int buflen
    The length of the byte array starting from the address specified by buf

Return value

The function returns the calculated CRC32 hash value.

MEM_GetStringHash

Calculates the CRC32 hash value for a string.

func int MEM_GetStringHash(var string str)
-
Parameters
  • var string str
    A string for which the hash value is to be calculated

Return value

The function returns an integer representing the calculated hash value for the input string.

\ No newline at end of file diff --git a/zengin/scripts/extenders/ikarus/functions/parser/index.html b/zengin/scripts/extenders/ikarus/functions/parser/index.html deleted file mode 100644 index c3cccd6281..0000000000 --- a/zengin/scripts/extenders/ikarus/functions/parser/index.html +++ /dev/null @@ -1,110 +0,0 @@ - Parser stuff - Gothic Modding Community

zCParser related functions

This Ikarus part provides some useful functions to work with parser, its instances, symbols and stack.

Danger

Remember to always assign an instance to a correct class. If you assign an oCNpc pointer to oCItem class you won't be able to read any data from it.

Implementation

Ikarus.d on GitHub

Initialization

The best way to initialize all Ikarus functions is to call MEM_InitAll() in the Init_Global() initialization function.

Warning

If you want to use Ikarus in Gothic 1, it is best to define your own Init_Global() function and call it from every world initialization function.

MEM_InitAll();
-

MEM_ReinitParser

Parser operations are initialized with this function.

func void MEM_ReinitParser()
-

Tip

It's worth noting that MEM_ReinitParser is also invoked by the MEM_InitAll function.

Pointers and instances

MEM_PtrToInst

Returns an instance pointed to by the pointer. If the pointer is null an error is thrown.

func MEMINT_HelperClass MEM_PtrToInst(var int ptr)
-
Parameters
  • var int ptr
    Pointer to return an instance from

Shortcut

In addition there is a function _^ with the same signature and functionality as MEM_PtrToInst. It is used as a shortcut, since the converting pointer to instance is commonly used while working with Ikarus.

func MEMINT_HelperClass _^ (var int ptr)
-
Example

Following code

var oCNpc her; her = MEM_PtrToInst(heroPtr);
-
is equivalent to
var oCNpc her; her = _^(heroPtr);
-

MEM_NullToInst

Returns an instance from a null pointer.

func MEMINT_HelperClass MEM_NullToInst()
-

MEM_AssignInst

Takes an instance from a pointer and assigns it to a given instance. If the pointer is null an error is thrown.

func void MEM_AssignInst(var int inst, var int ptr)
-
Parameters
  • var int ptr
    Pointer to assign an instance from
  • var int inst
    Instance to which the pointer will be assigned
Example

Following code

1
-2
var oCNpc inst;
-MEM_AssignInst (inst, ptr); 
-
is equivalent to
1
-2
var oCNpc inst;
-inst = MEM_PtrToInst(ptr);
-

MEM_AssignInstNull

Assigns null pointer to a given instance.

func void MEM_AssignInstNull(var int inst)
-
Parameters
  • var int inst
    Instance to which the null pointer will be assigned

MEM_InstToPtr

Returns a pointer to given instance.

func int MEM_InstToPtr(var int inst)
-
Parameters
  • var int inst
    The instance to which the pointer is returned

MEM_InstGetOffset

Alias to MEM_InstToPtr. Returns a pointer to given instance.

func int MEM_InstGetOffset(var int inst)
-
Parameters
  • var int inst
    The instance to which the pointer is returned

MEM_CpyInst

Returns a copy of a given instance

func MEMINT_HelperClass MEM_CpyInst(var int inst)
-
Parameters
  • var int inst
    Instance to copy
example

Following code

selfCopy = MEM_CpyInst (self);
-
is equivalent to
selfCopy = MEM_PtrToInst (MEM_InstToPtr (self));
-

Call function

You don't always know at compile time when you want to call which function. For example, if you want to call the condition function of a mob that the player has in focus, you are at a loss at compile time because you have no idea which mob the player will choose. Ikarus provides a way to call functions based on their name or symbol index. In the example of the mob, the name of the condition function can simply be looked up in the mob.

Note

The functions below also work for externals without any restrictions.

Passing Parameters

If the function to be called has parameters, these must first be placed on the data stack. The parameters must be pushed in the correct order, from left to right.

MEM_PushIntParam

Passes an integer as a parameter to the called function.

func void MEM_PushIntParam (var int param)
-
Parameters
  • var int param
    Integer to pass as a function parameter

MEM_PushInstParam

Passes an instance as a parameter to the called function.

func void MEM_PushInstParam (var int inst)
-
Parameters
  • var int inst
    Instance to pass as a function parameter

MEM_PushStringParam

Passes a string as a parameter to the called function.

func void MEM_PushStringParam (var string str)
-
Parameters
  • var string str
    String to pass as a function parameter

The call

MEM_Call

Calls a function.

func void MEM_Call(var func fnc)
-
Parameters
  • var func fnc
    Function to be called

MEM_CallByID

Calls a function by its ID.

func void MEM_CallByID (var int symbID)
-
Parameters
  • var int symbID
    The ID of the function to be called

MEM_CallByPtr

Calls a function by its pointer.

func void MEM_CallByPtr(var int ptr)
-
Parameters
  • var int ptr
    The pointer of the function to be called

MEM_CallByOffset

Calls a function by its offset.

func void MEM_CallByOffset(var int offset)
-
Parameters
  • var int offset
    The offset of the function to be called

MEM_CallByString

Calls a function by its name.

func void MEM_CallByString (var string fnc)
-
Parameters
  • var string fnc
    The name of the function IN CAPITAL LETTERS.

Return value

If a function has a return value, it should be fetched from the data stack after it is called, otherwise stack overflows can occur under unfavorable circumstances (aside from that, you may simply want the return value because it contains important information).

MEM_PopIntResult

Retrieves an integer returned by the called function.

func int MEM_PopIntResult()
-
Return value

The function returns an integer returned by the previously called script function.

MEM_PopStringResult

Retrieves a daedalus string returned by the called function.

func string MEM_PopStringResult()
-
Return value

The function returns a string returned by the previously called script function.

MEM_PopInstResult

Retrieves an instance returned by the called function.

func MEMINT_HelperClass MEM_PopInstResult()
-
Return value

The function returns an instance returned by the previously called script function.

Function stuff

MEM_GetFuncID

Returns the ID of the given function.

func int MEM_GetFuncID(var func fnc)
-
Parameters
  • var func fnc
    The function whose ID is returned

MEM_GetFuncPtr

Returns the pointer of the given function.

func int MEM_GetFuncPtr(var func fnc)
-
Parameters
  • var func fnc
    The function whose pointer is returned

MEM_GetFuncOffset

Returns the offset of the given function.

func int MEM_GetFuncOffset(var func fnc)
-
Parameters
  • var func fnc
    The function whose offset is returned

MEM_GetFuncIDByOffset

MEM_GetFuncID, but with an offset as a parameter.

func int MEM_GetFuncIDByOffset(var int offset)
-
Parameters
  • var int offset
    Offset of a function whose ID is returned

Return value

The function returns an ID of a function with a given offset.

MEM_ReplaceFunc

Replaces the f1 function with f2 function so if you call the first function, the second function is called.

func void MEM_ReplaceFunc(var func f1, var func f2)
-
Parameters
  • var func f1
    Function to replace
  • var func f2
    Function called instead of f1

Parser stack

MEM_GetFrameBoundary

Returns the address/pointer to the boundary of a stack frame (ESP).

func int MEM_GetFrameBoundary()
-

MEM_GetCallerStackPos

Retrieves the stack position (pop position) of the caller's caller (look at the example for better understanding).

func int MEM_GetCallerStackPos()
-
Return value

The function returns an integer representing the stack position of the caller's caller.

Example

After calling B() from within A(), when MEM_GetCallerStackPos() is invoked in function B(), it retrieves the stack position of the caller's caller, which is function A() in this case. Therefore, the variable adr will contain the stack position of function A().

1
-2
-3
-4
-5
-6
-7
-8
func void A(){
-    B();
-};
-
-func void B(){
-    int adr; adr = MEM_GetCallerStackPos();
-    // Now, 'adr' will contain the stack position of A.
-};
-

MEM_SetCallerStackPos

Sets the stack position (pop position) of the caller's caller.

func void MEM_SetCallerStackPos(var int popPos)
-
Parameters
  • var int popPos
    An integer parameter representing the new stack position of the caller's caller

Get address

MEM_GetAddress_Init

Initializes the MEM_GetIntAddress, MEM_GetFloatAddress and MEM_GetStringAddress functions.

func void MEM_GetAddress_Init()
-

Tip

It's worth noting that MEM_GetAddress_Init is also invoked by the MEM_InitAll function.

MEM_GetIntAddress

Returns an address of a given integer.

func int MEM_GetIntAddress(var int i)
-
Parameters
  • var int i
    Integer whose address is returned

Shortcut

In addition there is a function _@ with the same signature and functionality as MEM_GetIntAddress.

func int _@(var int i)
-

MEM_GetFloatAddress

Returns an address of a given daedalus float.

func int MEM_GetFloatAddress(var float f)
-
Parameters
  • var float f
    Float whose address is returned

Shortcut

In addition there is a function _@f with the same signature and functionality as MEM_GetFloatAddress.

func int _@s(var string s)
-

MEM_GetStringAddress

Returns an address of a given string.

func int MEM_GetStringAddress(var string s)
-
Parameters
  • var string s
    String whose address is returned

Shortcut

In addition there is a function _@s with the same signature and functionality as MEM_GetStringAddress.

func int _@s(var string s)
-

STR_GetAddressInit

Alias to MEM_GetAddress_Init, kept for downward compatibility.

func void STR_GetAddressInit()
-

STR_GetAddress

Function similar to MEM_GetStringAddress. There is a guarantee, that this function works initialized i.e. invokes MEM_GetAddress_Init, but the first time may only return an address of a copy of the string.

func int STR_GetAddress(var string str)
-

Static arrays

Accessing static arrays like this below is very tedious in Daedalus.

var int myStaticArray[42];
-
It is not possible to access myStaticArray[i] with a variable index i, but only with a constant. This changes with the following functions.

Danger

Neither function performs any kind of validity check. If the value passed is not an array or offsets are beyond the boundaries of the array passed, the behavior is undefined.

MEM_InitStatArrs

Initializes static arrays read and write functions.

func void MEM_InitStatArrs()
-

MEM_WriteStatArr

Changes the value at the offset of a static integer-array.

func void MEM_WriteStatArr (var int array, var int offset, var int value)
-
Parameters
  • var int array
    Array which will be edited
  • var int offset
    Array index at which value will be edited
  • var int value
    The new value

MEM_ReadStatArr

Reads the value at the specific offset of a static integer-array.

func int MEM_ReadStatArr (var int array, var int offset)
-
Parameters
  • var int array
    Array to get a value from
  • var int offset
    Array index of the value to return

Return value

The function returns an integer value from the offset of a given static array.

MEM_WriteStatStringArr

Changes the value at the offset of a static string-array.

func void MEM_WriteStatStringArr(var string array, var int offset, var string value)
-
Parameters
  • var string array
    Array which will be edited
  • var int offset
    Array index at which value will be edited
  • var string value
    The new value

MEM_ReadStatStringArr

Reads the value at the specific offset of a static string-array.

func string MEM_ReadStatStringArr(var string array, var int offset)
-
Parameters
  • var string array
    Array to get a value from
  • var int offset
    Array index of the value to return

Return value

The function returns a string form the offset of a given static array.

Parser symbol

MEM_SetCurrParserSymb

Makes currParserSymb point to the symbol of the specified instance.

func void MEM_SetCurrParserSymb (var int inst)
-
Parameters
  • var int inst
    Instance to whose symbol currParserSymb will be set

currParserSymb

An instance representing current parser symbol.

INSTANCE currParserSymb (zCPar_Symbol);
-

MEM_FindParserSymbol

Returns the index of the parser symbol with name inst if such a symbol exists.

func int MEM_FindParserSymbol(var string inst)
-
Parameters
  • var string inst
    Name of the symbol to be found

Return value

The function returns the index of the parser symbol with name inst if such a symbol exists. If non exists, a warning is issued and -1 is returned.

MEM_GetSymbolIndex

Alias to MEM_FindParserSymbol. Returns the index of the parser symbol with name inst if such a symbol exists.

func int MEM_GetSymbolIndex(var string inst)
-
Parameters
  • var string inst
    Name of the symbol to be found

Return value

The function returns the index of the parser symbol with name inst if such a symbol exists. If non exists, a warning is issued and -1 is returned.

MEM_GetParserSymbol

Looks for the parser symbol with the name inst and returns a pointer to the appropriate zCPar_Symbol structure.

func int MEM_GetParserSymbol (var string inst)
-
Parameters
  • var string inst
    Name of the symbol to be found

Return value

The function returns the appropriate zCPar_Symbol structure of the parser symbol with name inst if such a symbol exists. If non exists, a warning is issued and 0 is returned.

MEM_GetSymbol

Alias to MEM_GetParserSymbol. Looks for the parser symbol with the name inst and returns a pointer to the appropriate zCPar_Symbol structure.

func int MEM_GetSymbol(var string inst)
-
Parameters
  • var string inst
    Name of the symbol to be found

Return value

The function returns the appropriate zCPar_Symbol structure of the parser symbol with name inst if such a symbol exists. If non exists, a warning is issued and 0 is returned.

MEM_GetSymbolByIndex

MEM_GetParserSymbol, but with ID (index) as a parameter.

func int MEM_GetSymbolByIndex(var int id)
-
Parameters
  • var string inst
    ID (index) of the symbol to be found

Return value

The function returns the appropriate zCPar_Symbol structure of the parser symbol with name inst if such a symbol exists. If non exists, a warning is issued and 0 is returned.

\ No newline at end of file diff --git a/zengin/scripts/extenders/ikarus/functions/preamble/index.html b/zengin/scripts/extenders/ikarus/functions/preamble/index.html deleted file mode 100644 index 618f78c987..0000000000 --- a/zengin/scripts/extenders/ikarus/functions/preamble/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/zengin/scripts/extenders/ikarus/functions/string/index.html b/zengin/scripts/extenders/ikarus/functions/string/index.html deleted file mode 100644 index 9fd8032e81..0000000000 --- a/zengin/scripts/extenders/ikarus/functions/string/index.html +++ /dev/null @@ -1,138 +0,0 @@ - String operations - Gothic Modding Community

String operations

Collection of Ikarus functions to manipulate and format strings.

Initialization

The best way to initialize all Ikarus functions is to call MEM_InitAll() in the Init_Global() initialization function.

Warning

If you want to use Ikarus in Gothic 1, it is best to define your own Init_Global() function and call it from every world initialization function.

MEM_InitAll();
-

Implementation

Ikarus.d on GitHub

Functions

STR_GetCharAt

Returns the ASCII value of a character at a specific position in a string.

func int STR_GetCharAt (var string str, var int pos)
-
Parameters
  • var string str
    The input string
  • var int pos
    The position of the character

Return value

The function returns the ASCII value of the character at the specified position.

STR_Len

Returns the length of a string.

func int STR_Len (var string str)
-
Parameters
  • var string str
    The input string

Return value

The function returns the length of the string in characters.

STR_toChar

Converts a string to a pointer to its character array.

func int STR_toChar (var string str)
-
Parameters
  • var string str
    The input string

Return value

The function returns a pointer to the character array representing the input string str

STR_FromChar

Converts a character array to a string.

func string STR_FromChar(var int char)
-
Parameters
  • var int char
    Pointer to the character array

Return value

The function returns a string representation of the character array.

STR_SubStr

Extracts a substring from a given string.

func string STR_SubStr (var string str, var int start, var int count)
-
Parameters
  • var string str
    The input string
  • var int start
    The starting position of the substring
  • var int count
    The length of the substring

Return value

The function returns a substring, if the starting position is invalid an empty string is returned.

STR_Prefix

Extracts a prefix of a given string, similar to STR_SubStr, but with the starting position set to the first character of the string.

func string STR_Prefix (var string str, var int len)
-
Parameters
  • var string str
    The input string
  • var int count
    The length of the prefix

Return value

The function returns a prefix of the input string with the specified length.

STR_Compare

Compares two strings lexicographically and returns a result indicating their relative order.

func int STR_Compare(var string str1, var string str2)
-
Parameters
  • var string str1 The first string to compare
  • var string str2 The second string to compare

Return Value

The function returns an integer value representing the result of the comparison:

  • STR_GREATER (1): If str1 comes lexicographically after str2.
  • STR_EQUAL (0): If str1 is lexicographically equal to str2.
  • STR_SMALLER (-1): If str1 comes lexicographically before str2.
Examples

The comparison is based on lexicographic order, which is the order of characters as they appear in the ASCII table. Uppercase letters come before lowercase letters.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
int result1 = STR_Compare("A", "B");
-// The 'result1' variable now contains STR_SMALLER
-
-int result2 = STR_Compare("ABC", "ABC");
-// The 'result2' variable now contains STR_EQUAL
-
-int result3 = STR_Compare("AA", "A");
-// The 'result3' variable now contains STR_GREATER
-
-int result4 = STR_Compare("BA", "BB");
-// The 'result4' variable now contains STR_SMALLER
-
-int result5 = STR_Compare("B", "a");
-// The 'result5' variable now contains STR_SMALLER
-
-int result6 = STR_Compare("A", "");
-// The 'result6' variable now contains STR_GREATER
-

STR_ToInt

Converts a string to an integer.

func int STR_ToInt (var string str)
-
Parameters
  • var string str
    The input string

Return Value

The function returns an integer value of the string, if a string is invalid (doesn't contain an integer) zero is returned.

STR_IndexOf

Searches for a substring tok within a given string and returns the index of the first occurrence of tok, taking into account upper and lower case letters.

func int STR_IndexOf(var string str, var string tok)
-
Parameters
  • var string str
    The string in which to search for tok.
  • var string tok
    The substring to search for within str.

Return Value

The function returns the index at which the first occurrence of tok begins within str. If tok is not found in str, the function returns -1.

Examples
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
int index1 = STR_IndexOf("Hello World!", "Hell");
-// The 'index1' variable now contains 0
-
-int index2 = STR_IndexOf("Hello World!", "World");
-// The 'index2' variable now contains 6
-
-int index3 = STR_IndexOf("Hello World!", "Cake");
-// The 'index3' variable now contains -1
-
-int index4 = STR_IndexOf("Hello World!", "");
-// The 'index4' variable now contains 0
-
-int index5 = STR_IndexOf("Hello", "Hello World!");
-// The 'index5' variable now contains -1
-
-int index6 = STR_IndexOf("hello Hell!", "Hell");
-// The 'index6' variable now contains 6
-
-int index7 = STR_IndexOf("", "");
-// The 'index7' variable now contains 0
-

STR_SplitCount

Counts the number of parts a string splits into when using a specified separator.

func int STR_SplitCount(var string str, var string separator)
-
Parameters
  • var string str
    The input string to be split.
  • var string separator
    The separator character or string used to split the input string.

Return Value

The function returns a number of parts the input string splits into when using the specified separator.

Example
1
-2
-3
string inputStr = "This is a sentence.";
-int count = STR_SplitCount(inputStr, " ");
-// The 'count' variable now contains 4
-

STR_Split

Splits a string into multiple substrings based on a specified separator and returns the substring at a specified offset.

func string STR_Split(var string str, var string separator, var int offset)
-

Parameters

  • var string str
    The input string to be split.
  • var string separator
    The separator character or string used to split the input string.
  • var int offset
    The index of the substring to be returned after splitting. The index is zero-based.

Return Value

The function returns a substring at the specified offset after splitting the input string. If the offset is greater than or equal to the number of parts generated by splitting, an empty string is returned.

Example

1
-2
-3
-4
-5
-6
-7
func void foo() {
-    string inputStr = "This is a sentence.";
-    string tok1 = STR_Split(inputStr, " ", 0); // This
-    string tok2 = STR_Split(inputStr, " ", 1); // is
-    string tok3 = STR_Split(inputStr, " ", 2); // a
-    string tok4 = STR_Split(inputStr, " ", 3); // sentence
-};
-
At the end of the function, tok1 contains "This", tok2 contains "is", tok3 contains "a", and tok4 contains "sentence.".

STR_Upper

Converts a string to uppercase.

func string STR_Upper(var string str)
-
Parameters
  • var string str
    The input string

Return Value

The function returns a copy of str with all uppercase letters converted to their corresponding uppercase letters.

STR_Lower

Converts a string to lowercase.

func string STR_Lower(var string str)
-
Parameters
  • var string str
    The input string

Return Value

The function returns a copy of str with all lowercase letters converted to their corresponding uppercase letters.

\ No newline at end of file diff --git a/zengin/scripts/extenders/ikarus/functions/time_benchmark/index.html b/zengin/scripts/extenders/ikarus/functions/time_benchmark/index.html deleted file mode 100644 index 86173a0ce3..0000000000 --- a/zengin/scripts/extenders/ikarus/functions/time_benchmark/index.html +++ /dev/null @@ -1,64 +0,0 @@ - Time and Benchmark - Gothic Modding Community

Time and Benchmark

Set of functions to time measurement and Benchmark.

Initialization

The best way to initialize all Ikarus functions is to call MEM_InitAll() in the Init_Global() initialization function.

Warning

If you want to use Ikarus in Gothic 1, it is best to define your own Init_Global() function and call it from every world initialization function.

MEM_InitAll();
-

Implementation

Ikarus.d on GitHub

Time functions

MEM_GetSystemTime

Returns the elapsed time since Gothic started.

func int MEM_GetSystemTime()
-
Return value

The function returns the elapsed time since the start of Gothic in milliseconds. This value is used for timing measurements, in the BenchmarkMS functions.

MEM_GetPerformanceCounter

Call to the WinAPI QueryPerformanceCounter function.

func int MEM_GetPerformanceCounter()
-
Return value

The function returns a value representing the number of elapsed ticks since the system was started. This value is used for timing measurements, in the BenchmarkPC functions.

Benchmark functions

Tip

For reliable results, avoid measuring a single run of a function; instead, measure the total duration of multiple runs (e.g., 1000). This is crucial, especially for very fast functions, as a single run can distort the measurement. Use _N benchmark functions to include a parameter specifying the number of runs for function f.

Choose the parameter n to ensure meaningful results. If n executions take less than a millisecond, obtaining a return value in milliseconds has no sense. For very fast functions, the time spent in the benchmark function, not in f, significantly affects the measurement, falsifying the result. Reliable measurements are achievable only for functions with sufficient slowness.

For reference, here is a timing for some operations (in nanoseconds, i.e., billionths of a second):

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
- Function call (jumping back and forth): 30ns
-- Elementary calculation (e.g., i = i + 1): 130ns
-- Wld_IsTime: 200ns
-- MEM_ReadInt, MEM_WriteInt: 350ns
-- Hlp_StrCmp("Hello", "Hello"): 500ns
-- MEM_InstToPtr: 1400ns
-- (small) Allocate and free memory: 9700ns
-- CALL__stdcall (in empty function): 29000ns
-- MEM_GetParserSymb: 280000ns
-
-- Iteration of the benchmark function: 300ns
-

MEM_BenchmarkMS

Benchmark of the execution time for a specified function. (Milliseconds)

func int MEM_BenchmarkMS(var func f)
-
Parameters
  • var func f
    Function to benchmark

Return value

The function returns the duration of a function execution in milliseconds.

MEM_BenchmarkMMS

Benchmark of the execution time for a specified function. (microseconds)

func int MEM_BenchmarkMMS(var func f)
-
Parameters
  • var func f
    Function to benchmark

Return value

The function returns the duration of a function execution in microseconds.

MEM_BenchmarkPC

Benchmark of the execution time for a specified function, using the Performancecounter.

func int MEM_BenchmarkMS(var func f)
-
Parameters
  • var func f
    Function to benchmark

Return value

The function returns the number of Performancecounter ticks the function needs.

MEM_BenchmarkMS_N

MEM_BenchmarkMS, but with the parameter to specify the number of function runs.

func int MEM_BenchmarkMS_N(var func f, var int n)
-
Parameters
  • var func f
    Function to benchmark
  • var int n
    Number of runs

Return value

The function returns a summed duration of multiple (n) runs of the function in milliseconds.

MEM_BenchmarkMMS_N

MEM_BenchmarkMMS, but with the parameter to specify the number of function runs.

func int MEM_BenchmarkMMS_N(var func f, var int n)
-
Parameters
  • var func f
    Function to benchmark
  • var int n
    Number of runs

Return value

The function returns a summed duration of multiple (n) runs of the function in microseconds.

MEM_BenchmarkPC_N

MEM_BenchmarkPC, but with the parameter to specify the number of function runs.

func int MEM_BenchmarkPC_N(var func f, var int n)
-
Parameters
  • var func f
    Function to benchmark
  • var int n
    Number of runs

Return value

The function returns a summed number of Performancecounter ticks needed to execute function multiple (n) times.

\ No newline at end of file diff --git a/zengin/scripts/extenders/ikarus/functions/win_utilities/index.html b/zengin/scripts/extenders/ikarus/functions/win_utilities/index.html deleted file mode 100644 index 8ddd404a30..0000000000 --- a/zengin/scripts/extenders/ikarus/functions/win_utilities/index.html +++ /dev/null @@ -1,55 +0,0 @@ - Windows Utilities - Gothic Modding Community

Windows Utilities

This part of Ikarus implements some WinAPI functions that can be used directly from Gothic scripts.

Initialization

The best way to initialize all Ikarus functions is to call MEM_InitAll() in the Init_Global() initialization function.

Warning

If you want to use Ikarus in Gothic 1, it is best to define your own Init_Global() function and call it from every world initialization function.

MEM_InitAll();
-

Implementation

Ikarus.d on GitHub

Functions

LoadLibrary

Loads the specified module into the address space of the calling process. Full documentation here.

func int LoadLibrary(var string lpFileName)
-
Parameters
  • var string lpFileName
    Name of loaded module

Return value

The function returns a handle to the module.

GetProcAddress

Retrieves the address from the specified dynamic-link library. Full documentation here.

func int GetProcAddress(var int hModule, var string lpProcName)
-
Parameters
  • var int hModule
    A handle to the DLL module that contains the function or variable. Can be obtained using the LoadLibrary function.
  • var string lpProcName
    The function or variable name.

Return value The function returns address of the function or variable.

FindKernelDllFunction

Uses GetProcAddress to find function inside the KERNEL32.DLL file.

func int FindKernelDllFunction(var string name)
-
Parameters
  • var string name
    Name of the looked function.

Return value

The function returns address of the function.

VirtualProtect

Changes the protection on a region of committed pages in the virtual address space of the calling process. Full documentation here.

func int VirtualProtect(var int lpAddress, var int dwSize, var int flNewProtect)
-
Parameters
  • var int lpAddress
    The address of the starting page of the region of pages whose access protection attributes are to be changed.
  • var int dwSize
    The size of the region whose access protection attributes are to be changed, in bytes.
  • var int flNewProtect
    The memory protection option. All options can be found here.

Return value

The function returns lpflOldProtectPtr - a pointer to a variable that receives the previous access protection value.

Author's comment:

I made lpflOldProtectPtr the return value and ignored the return Value of VirtualProtect.

MemoryProtectionOverride

Alias to VirtualProtect but with predefined PAGE_EXECUTE_READWRITE protection option

func void MemoryProtectionOverride(var int address, var int size)
-
Parameters
  • var int address
    The address of the starting page of the region of pages whose access protection attributes are to be changed.
  • var int size
    The size of the region whose access protection attributes are to be changed, in bytes.

MEM_MessageBox

Calls the WinAPI MessageBox function.

func int MEM_MessageBox(var string txt, var string caption, var int type)
-
Parameters
  • var string txt
    Content of the MessageBox.
  • var string caption
    Header of MessageBox.
  • var int type
    Type of MessageBox. All types listed here.

MEM_InfoBox

Alias to MEM_MessageBox with "Information:" header and MB_OK | MB_ICONINFORMATION type.

func void MEM_InfoBox(var string txt)
-
Parameters
  • var string txt
    Content of the InfoBox.

Examples

Sleep

Following function calls the Sleep function from the KERNEL32.DLL. A documentation of this function can be found here.

1
-2
-3
-4
-5
-6
-7
func void Sleep(var int ms) {
-    var int adr;
-    adr = GetProcAddress(LoadLibrary("KERNEL32.DLL"), "Sleep");
-
-    CALL_IntParam(ms);
-    CALL__stdcall(adr); // 0x007B47E6
-};
-
\ No newline at end of file diff --git a/zengin/scripts/extenders/ikarus/index.html b/zengin/scripts/extenders/ikarus/index.html deleted file mode 100644 index bbfdf9479f..0000000000 --- a/zengin/scripts/extenders/ikarus/index.html +++ /dev/null @@ -1,34 +0,0 @@ - Ikarus - Gothic Modding Community

Ikarus

Ikarus is a Daedalus library for Gothic. It exploits the interpreter to allow arbitrary memory access and defines tonne of useful functions for interfacing with the engine.

Contacts
Author Sektenspinner & contributors
GitHub Ikarus
Forum Ikarus

Author Note (by Sektenspinner)

This script package is not called Ikarus for nothing:

One can leave the boundaries of Daedalus behind, but may also crash and burn. For instance, reading from invalid addresses won't trigger a zSpy warning but will result in a desktop crash with an Access Violation. This is not a reason to panic but requires a tolerance for frustration (which can be useful for scripters in general).

Of course, such spectacular-looking errors can be fixed, and with focused and systematic work, something sensible can be achieved.

In short: Extra care is needed! A bug that leads to a crash is not something you want in the release version. But if you work cleanly and test extensively, it's not such a big deal.

A good friend in debugging crashes is undoubtedly PrintDebug. It allows sending messages to zSpy (for example, to narrow down where the crash is occurring). It's worth enabling debug messages by MEM_SetShowDebug and the text filter (Options -> Textfilter) in zSpy.

Note

Ikarus is hosted on GitHub and the documentation is built in. The translation is planned.

\ No newline at end of file diff --git a/zengin/scripts/extenders/ikarus/ini_access/index.html b/zengin/scripts/extenders/ikarus/ini_access/index.html deleted file mode 100644 index 40bdff0db7..0000000000 --- a/zengin/scripts/extenders/ikarus/ini_access/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/zengin/scripts/extenders/ikarus/keyboard/index.html b/zengin/scripts/extenders/ikarus/keyboard/index.html deleted file mode 100644 index 9d58a0c0c6..0000000000 --- a/zengin/scripts/extenders/ikarus/keyboard/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/zengin/scripts/extenders/ikarus/mem_access/index.html b/zengin/scripts/extenders/ikarus/mem_access/index.html deleted file mode 100644 index f09e17255d..0000000000 --- a/zengin/scripts/extenders/ikarus/mem_access/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/zengin/scripts/extenders/ikarus/setup/index.html b/zengin/scripts/extenders/ikarus/setup/index.html deleted file mode 100644 index f3e3987acb..0000000000 --- a/zengin/scripts/extenders/ikarus/setup/index.html +++ /dev/null @@ -1,138 +0,0 @@ - Setup - Gothic Modding Community

Ikarus Setup

Download

First you need to download ikarus from the official github repository. We recommend using the master branch as it contains the latest and most up-to-date version of Ikarus. However, you can also download a specific release if needed.

File location

Before unpacking the downloaded archive it's needed to create a dedicated folder in <Gothic-dir>\_work\Data\Scripts\Content directory. You can name this folder as you wish; in this guide, we'll refer to it as the "MOD" folder. Unpack the downloaded files into this newly created folder. The archiver should create a folder named Ikarus-master or Ikarus-X.X.X. For better readability change its name to the much simpler Ikarus.

Tip

It's a good practice to delete any unused files, so delete files for other gothic version than this you are using.

Parsing

Ikarus consists of three main parts, constants, classes and the Ikarus core. It's essential to parse these in a specific order. Additionally, there is a floats package which isn't essential, but it is highly recommended to parse it, especially if you are working with LeGo that depends on it.

The Ikarus Core is identical for both Gothic 1 and 2 and is contained in a single file, Ikarus.d. However, there are separate files for the constants and classes for each engine, and they must be parsed correctly. Ikarus uses a C_NPC and therefore has to be parsed after the C_NPC class (after the classes.d file). There are no other dependencies.

Since Ikarus 1.2.1 there is additional .src file for each game engine, to simplify adding files to Gothic.src

Warning

Following example is for Gothic 2. If you are using Gothic 1 replace the G2 at the end of the file/directory name with G1.

1
-2
-3
-4
-5
-6
_INTERN\CONSTANTS.D
-_INTERN\CLASSES.D
-MOD\IKARUS\Ikarus_Const_G2.d
-MOD\IKARUS\EngineClasses_G2\*.d
-MOD\IKARUS\Ikarus.d
-MOD\IKARUS\float.d
-
1
-2
-3
_INTERN\CONSTANTS.D
-_INTERN\CLASSES.D
-MOD\IKARUS\IKARUS_G2.SRC
-

Initialization

Before you can use Ikarus in your scripts, it must be properly initialized. The initialization process differs between Gothic 1 and Gothic 2.

MEM_InitAll

This is main ikarus initialization function, however it consists of some smaller initialization functions.

func void MEM_InitAll()
-
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
func void MEM_InitAll() {
-    if (!MEMINT_ReportVersionCheck()) {
-        return;
-    };
-
-    MEM_ReinitParser(); /* depends on nothing */
-    MEM_InitLabels(); /* depends in MEM_ReinitParser */
-    MEM_InitGlobalInst(); /* depends on MEM_ReinitParser */
-
-    /* now I can use MEM_ReplaceFunc, MEM_GetFuncID */
-    MEM_GetAddress_Init(); /* depends on MEM_ReinitParser and MEM_InitLabels */
-    /* now the nicer operators are available */
-
-    MEM_InitStatArrs(); /* depends on MEM_ReinitParser and MEM_InitLabels */
-    ASMINT_Init();
-
-    MEMINT_ReplaceLoggingFunctions();
-    MEMINT_ReplaceSlowFunctions();
-    MEM_InitRepeat();
-
-    /* takes a wail the first time it is called.
-        call it to avoid delay later */
-    var int dump; dump = MEM_GetFuncIDByOffset(0);
-};
-

Gothic 1

To initialize Ikarus in Gothic 1 you must define your own INIT_GLOBAL function at the top of the Startup.d file. Then the INIT_GLOBAL should be called in every INIT_<location> function (e.g. INIT_SURFACE,INIT_OLDCAMP etc.). INIT_SUB_<location> functions can be skipped in that process.

Then in your INIT_GLOBAL function you call MEM_InitAll() initialization function.

Startup.d
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
FUNC VOID INIT_GLOBAL()
-{
-    // Init Ikarus
-    MEM_InitAll ();
-};
-
-// [...]
-
-func VOID INIT_SURFACE ()
-{
-    Init_Global();
-    INIT_SUB_SURFACE ();
-};
-// [...]
-

Gothic 2

Gothic 2 has its own INIT_GLOBAL function, so the initialization process is much simpler. All you have to do is to call MEM_InitAll() in INIT_GLOBAL function located in the Startup.d file.

Startup.d
1
-2
-3
-4
-5
-6
-7
FUNC VOID INIT_GLOBAL()
-{
-    // Init Ikarus
-    MEM_InitAll ();
-};
-
-// [...]
-
\ No newline at end of file diff --git a/zengin/scripts/extenders/index.html b/zengin/scripts/extenders/index.html deleted file mode 100644 index 8f30833792..0000000000 --- a/zengin/scripts/extenders/index.html +++ /dev/null @@ -1,34 +0,0 @@ - Daedalus extenders - Gothic Modding Community

Daedalus extenders

The default scripting language Daedalus can be quite limiting. Over the years the community created quite a few extenders to, well, extend the functionality. Before Union came along, the standard to interface with the engine was the script library Ikarus and a collection of packages LeGo built on top of that. Not so recently, an additional script packet was made (and is actively being worked on) AF Script Packet that offers even more functionality and is built on top of Ikarus & LeGo.
With the adoption of Union and plugins the Union system can use a new extender emerged called zParserExtender. Other Union plugins can, of course, implement their own external functions. A lot of scripts are also scattered on the Gothic forums, and documentation of some of them can be found in the Standalone section.

\ No newline at end of file diff --git a/zengin/scripts/extenders/lego/ai_function/index.html b/zengin/scripts/extenders/lego/ai_function/index.html deleted file mode 100644 index 1963f1c536..0000000000 --- a/zengin/scripts/extenders/lego/ai_function/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/zengin/scripts/extenders/lego/anim8/index.html b/zengin/scripts/extenders/lego/anim8/index.html deleted file mode 100644 index db533d2cdf..0000000000 --- a/zengin/scripts/extenders/lego/anim8/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/zengin/scripts/extenders/lego/applications/LeGo_applications.d b/zengin/scripts/extenders/lego/applications/LeGo_applications.d deleted file mode 100644 index 9aad19ad0d..0000000000 --- a/zengin/scripts/extenders/lego/applications/LeGo_applications.d +++ /dev/null @@ -1,651 +0,0 @@ -// ========================================================= -// -// Anim8 -// -// ========================================================= - -/// Creates a new Anim8 object that can be filled with commands. -/// -/// @param initialValue The initial value to start animating from. Can be an integer, or an Ikarus float. -/// @param IsFloat If the initialValue is an Ikarus float, this parameter must be set to TRUE. If it is an integer, it must be set to FALSE. -/// @return The function returns handle of the Anim8 object. -func int Anim8_New(var int initialValue, var int IsFloat) {}; - -/// Creates a new Anim8 object with advanced options. Extends the Anim8_New function. -/// -/// @param value The initial value to start animating from. Can be an integer, or an Ikarus float. -/// @param handler This function is called whenever the object is updated. -/// @param data Optional parameter to send an additional value to the handler function. If data == 0, it is ignored. -/// @param IsFloat If the initialValue is an Ikarus float, this parameter must be set to TRUE. If it is an integer, it must be set to FALSE. -/// @return The function returns handle of the Anim8 object. -func int Anim8_NewExt(var int value, var func handler, var int data, var int IsFloat) {}; - -/// Deletes an Anim8 object created with Anim8_New. -/// -/// @param handle Handle returned from Anim8_New. -func void Anim8_Delete(var int handle) {}; - -/// Get current value of the object. -/// -/// @param handle Handle returned from Anim8_New. -/// @return The function returns value of the object. -func int Anim8_Get(var int handle) {}; - -/// Sets the value of the object. -/// -/// @param handle Handle returned from Anim8_New. -/// @param value New value of the object. -func void Anim8_Set(var int handle, var int value) {}; - -/// Indicates whether the object is empty, i.e. has no more commands to process. -/// -/// @param handle Handle returned from Anim8_New. -/// @return The function returns TRUE if object is empty (has no more commands), FALSE is returned otherwise. -func int Anim8_Empty(var int handle) {}; - -/// If desired, Anim8 can automatically delete an object after it is empty. -/// -/// @param handle Handle returned from Anim8_New. -/// @param on TRUE: enable, FALSE: disable. -func void Anim8_RemoveIfEmpty(var int handle, var int on) {}; - -/// With Anim8_NewExt handler and data can be set. If this function is called with TRUE, data is taken as a handle and delete(data) is called if the object is empty. Works only if Anim8_RemoveIfEmpty is also activated. -/// -/// @param handle Handle returned from Anim8_New. -/// @param on TRUE: enable, FALSE: disable. -func void Anim8_RemoveDataIfEmpty(var int handle, var int on) {}; - -/// Packet core. Gives the object a new command to process. -/// -/// @param handle Handle returned from Anim8_New. -/// @param target Target value of this command. When the object's value has reached this value, the command is considered completed and deleted. -/// @param span Action duration in milliseconds. -/// @param interpol What form of movement is used (See constants for this). -func void Anim8(var int handle, var int target, var int span, var int interpol) {}; - -/// As already mentioned above, Anim8 can also process several commands one after the other. While Anim8 completely resets the object and deletes all commands, Anim8q just appends a new command to the list. This will be processed as soon as the previous one is completed. -/// -/// @param handle Handle returned from Anim8_New. -/// @param target Target value of this command. When the object's value has reached this value, the command is considered completed and another one in the queue will start. -/// @param span Action duration in milliseconds. -/// @param interpol What form of movement is used (See constants for this). -func void Anim8q(var int handle, var int target, var int span, var int interpol) {}; - -/// Registers a function to be called when the object is deleted (e.g. by Anim8_RemoveIfEmpty) -/// -/// @param handle Handle returned from Anim8_New. -/// @param dfnc This function is called when the object is deleted. -func void Anim8_CallOnRemove(var int handle, var func dfnc) {}; - -// ========================================================= -// -// Bars -// -// ========================================================= - -/// Creates a new bar from a constructor instance. -/// -/// @param inst Constructor instance of Bar class -/// @return The function returns the address of the new bar, aka the handle. -func int Bar_Create(var int inst) {}; - -/// Deletes a bar from the screen and from memory. -/// -/// @param bar Handle returned from Bar_Create -func void Bar_Delete(var int bar) {}; - -/// Changes a bar's maximum value but does not update its bar length (only Bar_SetPercent, Bar_SetPromille, and Bar_SetValue) -/// -/// @param bar Handle returned from Bar_Create -/// @param max New maximum value -func void Bar_SetMax(var int bar, var int max) {}; - -/// Sets the value of the bar. -/// -/// @param bar Handle returned from Bar_Create -/// @param val New value of the bar -func void Bar_SetValue(var int bar, var int val) {}; - -/// Sets the value of the bar but as a percentage (0..100). -/// -/// @param bar Handle returned from Bar_Create -/// @param perc New value of the bar in percent -func void Bar_SetPercent(var int bar, var int perc) {}; - -/// Sets the value of the bar but per mille (0..1000). -/// -/// @param bar Handle returned from Bar_Create -/// @param pro New value of the bar in per mille -func void Bar_SetPromille(var int bar, var int pro) {}; - -/// Hides a bar. It will not be deleted. -/// -/// @param bar Handle returned from Bar_Create -func void Bar_Hide(var int bar) {}; - -/// Displays a bar again after using Bar_Hide. -/// -/// @param bar Handle returned from Bar_Create -func void Bar_Show(var int bar) {}; - -/// Move the bar to a virtual position. -/// -/// @param bar Handle returned from Bar_Create -/// @param x New horizontal position in virtual coordinates -/// @param y New vertical position in virtual coordinates -func void Bar_MoveTo(var int bar, var int x, var int y) {}; - -/// Move the bar to pixel position. -/// -/// @param bar Handle returned from Bar_Create -/// @param x New horizontal position in pixels -/// @param y New vertical position in pixels -func void Bar_MoveToPxl(var int bar, var int x, var int y) {}; - -/// Sets the transparency of the bar. -/// -/// @param bar Handle returned from Bar_Create -/// @param alpha Transparency value (0..255) -func void Bar_SetAlpha(var int bar, var int alpha) {}; - -/// Sets the foreground texture of the bar. -/// -/// @param bar Handle returned from Bar_Create -/// @param barTex The new foreground texture -func void Bar_SetBarTexture(var int bar, var string barTex) {}; - -/// Sets the background texture of the bar. -/// -/// @param bar Handle returned from Bar_Create -/// @param backTex The new background texture -func void Bar_SetBackTexture(var int bar, var string backTex) {}; - -/// Resize an existing bar. -/// -/// @param bar Handle returned from Bar_Create -/// @param width New width in virtual coordinates -/// @param height New height in virtual coordinates -func void Bar_Resize(var int bar, var int width, var int height) {}; - -/// Resize existing bar (in pixels). -/// -/// @param bar Handle returned from Bar_Create -/// @param x New width in pixels -/// @param y New height in pixels -func void Bar_ResizePxl(var int bar, var int x, var y) {}; - -// ========================================================= -// -// Bloodsplats -// -// ========================================================= - -/// Puts a blood splatter on the screen. -/// -/// @param damage The damage (affects the size of the splatter) -func void Bloodsplat(var int damage) {}; - -/// Pretty pointless feature that smears the entire screen. -func void Bloodsplats_Rage() {}; - -/// `oCNpc::GetPerceptionFunc` engine function wrapper. -/// -/// @param npc NPC whose perception is checked -/// @param type Checked perception type (from Constants.d) -/// @return The function returns the state of NPCs selected perception. -func int Npc_GetPercFunc(var C_Npc npc, var int type) {}; - -// ========================================================= -// -// Buffs -// -// ========================================================= - -/// Applies a status effect to an NPC. -/// -/// @param npc NPC to be affected by this effect -/// @param buff The instance of the effect to apply to the NPC -/// @return The function returns the handle of the buff, which was just generated. -func int Buff_Apply(var C_NPC npc, var int buff) {}; - -/// Buff_Apply, but nothing happens if a status effect of that kind is already on the NPC. -/// -/// @param npc NPC to be affected by this effect -/// @param buff The instance of the effect to apply to the NPC -/// @return The function returns the handle of the buff, which was just generated or 0 if the buff is already applied on the NPC. -func int Buff_ApplyUnique(var C_NPC npc, var int buff) {}; - -/// Buff_Apply, but if a status effect of this type is already affecting the NPC, the duration will be reset. -/// -/// @param npc NPC to be affected by this effect -/// @param buff The instance of the effect to apply to the NPC -/// @return The function returns the handle of the buff, which was just generated or refreshed. -func int Buff_ApplyOrRefresh(var C_NPC n, var int buff) {}; - -/// Resets the duration of the buff. -/// -/// @param buffHandle Handle of the buff to refresh -func void Buff_Refresh(var int buffHandle) {}; - -/// Removes the buff from all NPCs. -/// -/// @param buffHandle Handle of the buff to remove -func void Buff_Remove(var int buffHandle) {}; - -/// Removes the buffs from the NPC. -/// -/// @param npc NPC whose buff should be removed -/// @param buffInstance The instance of the buff to remove -func void Buff_RemoveAll(var C_NPC npc, var int buffInstance) {}; - -/// Returns a pointer to the NPC, which is affected by the buff. -/// -/// @param buffHandle Handle of the buff -/// @return The function returns a pointer to the NPC, which is affected by the buff. -func int Buff_GetNpc(var int buffHandle) {}; - -/// Checks if the NPC already has an effect applied. -/// -/// @param npc Checked NPC -/// @param buff The instance of the effect -/// @return The function returns TRUE if the NPC has an effect applied. FALSE is returned otherwise. -func int Buff_Has(var C_NPC npc, var int buff) {}; - -/// Same as MEM_GetFuncID but gets the current instance. -/// -/// @param f Function whose ID is got -/// @return The function returns the ID of the given function. -func int SAVE_GetFuncID(var func f) {}; - -// ========================================================= -// -// Buttons -// -// ========================================================= - -/// Creates a button. It is initially hidden (not visible and does not react to the mouse). -/// -/// @param posx The horizontal position of the button in virtual coordinates -/// @param posy The vertical position of the button in virtual coordinates -/// @param width Width of the button in virtual coordinates -/// @param height Height of the button in virtual coordinates -/// @param tex Name of the button texture -/// @param on_enter This function is called when the mouse enters the button -/// @param on_leave This function is called when the mouse leaves the button -/// @param on_click This function is called when the user performs a mouse click on the button (left mouse button) -/// @return The function returns a handle to created button. -func int Button_Create(var int posx, var int posy, var int width, var int height, var string tex, var func on_enter, var func on_leave, var func on_click) {}; - -/// Button_Create with pixels instead of virtual coordinates. -/// -/// @param posx The horizontal position of the button in pixels -/// @param posy The vertical position of the button in pixels -/// @param width Width of the button in pixels -/// @param height Height of the button in pixels -/// @param tex Name of the button texture -/// @param on_enter This function is called when the mouse enters the button -/// @param on_leave This function is called when the mouse leaves the button -/// @param on_click This function is called when the user performs a mouse click on the button (left mouse button) -/// @return The function returns a handle to created button. -func int Button_CreatePxl(var int posx, var int posy, var int width, var int height, var string tex, var func on_enter, var func on_leave, var func on_click) {}; - -/// Completely deletes a button. -/// -/// @param hndl Handle returned from `Button_Create` -func void Button_Delete(var int hndl) {}; - -/// Shows the button and makes it respond to the mouse. -/// -/// @param hndl Handle returned from `Button_Create` -func void Button_Show(var int hndl) {}; - -/// Hides the button and disables it, so it is no longer responding to the mouse. -/// -/// @param hndl Handle returned from `Button_Create` -func void Button_Hide(var int hndl) {}; - -/// Sets the texture of the button. -/// -/// @param hndl Handle returned from `Button_Create` -/// @param tex Name of the new texture -func void Button_SetTexture(var int hndl, var string tex) {}; - -/// Displays a centered text on the button. -/// -/// @param hndl Handle returned from `Button_Create` -/// @param caption The text to be displayed -/// @param font The font in which the text should be displayed -func void Button_SetCaption(var int hndl, var string caption, var string font) {}; - -/// Attaches a mouseover box to the cursor. -/// -/// @param text The text in the mouseover box -/// @param font The font of the text -func void Button_CreateMouseover(var string text, var string font) {}; - -/// Deletes the mouseover box. -func void Button_DeleteMouseover() {}; - -/// Activates the button, so it reacts to the mouse. Does not change the visibility. -/// -/// @param hndl Handle returned from `Button_Create` -func void Button_Activate(var int hndl) {}; - -/// Disables the button, so it no longer reacts to the mouse. -/// -/// @param hndl Handle returned from `Button_Create` -func void Button_Deactivate(var int hndl) {}; - -/// Sets the user data of the button, an integer, to give the button individual information. -/// -/// @param hndl Handle returned from `Button_Create` -/// @param data Individual integer of the button (part of the internal `_Button` class) -func void Button_SetUserData(var int hndl, var int data) {}; - -/// Gets the user data of the button. -/// -/// @param hndl Handle returned from `Button_Create` -/// @return The function returns the user data of the button. -func int Button_GetUserData(var int hndl) {}; - -/// Gets the status of the button as a bit field. See User Constants for possible states. -/// -/// @param hndl Handle returned from `Button_Create` -/// @return The function returns the status of the button. -func int Button_GetState(var int hndl) {}; - -/// Moves the button by the given value in pixels. `posx = posx + nposx` -/// -/// @param hndl Handle returned from `Button_Create` -/// @param nposx X-axis shift in pixels -/// @param nposy Y-axis shift in pixels -func void Button_Move(var int hndl, var int nposx, var int nposy) {}; - -/// Moves the button by the given value in virtual coordinates. `posx = posx + nposx` -/// -/// @param hndl Handle returned from `Button_Create` -/// @param nposx X-axis shift in virtual coordinates -/// @param nposy Y-axis shift in virtual coordinates -func void Button_MoveVrt(var int hndl, var int nposx, var int nposy) {}; - -/// Moves a button to the given position in pixels. `posx = nposx` -/// -/// @param hndl Handle returned from `Button_Create` -/// @param nposx New horizontal position in pixels -/// @param nposy New vertical position in pixels -func void Button_MoveTo(var int hndl, var int nposx, var int nposy) {}; - -/// Moves a button to the given position in virtual coordinates. `posx = nvposx` -/// -/// @param hndl Handle returned from `Button_Create` -/// @param nvposx New horizontal position in virtual coordinates -/// @param nvposy New vertical position in virtual coordinates -func void Button_MoveToVrt(var int hndl, var int nvposx, var int nvposy) {}; - -/// Returns the button's `zCView` as a handle. -/// -/// @param hndl Handle returned from `Button_Create` -/// @return The function returns the button's `zCView` as a handle. -func int Button_GetViewHandle(var int hndl) {}; - -/// Returns the button's `zCView` as a pointer. -/// -/// @param hndl Handle returned from `Button_Create` -/// @return The function returns the button's `zCView` as a pointer. -func int Button_GetViewPtr(var int hndl) {}; - -/// Returns the button's `zCView` as an object. -/// -/// @param hndl Handle returned from `Button_Create` -/// @return The function returns the button's `zCView` as an object. -func zCView Button_GetView(var int hndl) {}; - -/// Returns the pointer to the text of the button. -/// -/// @param hndl Handle returned from `Button_Create` -/// @return The function returns the pointer to the text of the button. -func int Button_GetCaptionPtr(var int hndl) {}; - -// ========================================================= -// -// ConsoleCommands -// -// ========================================================= - -/// Registers a new console command. -/// -/// @param f This function is executed when the cmdPrefix command is entered in the console. -/// The function signature is func string f(var string p0). -/// The string passed is everything that was specified in the console after the actual command. -/// The return value is then displayed in the console. -/// @param cmdPrefix This is a command, which can be entered in the console. -/// @param description This text appears next to the command (in zSpy) when you use the help command in the console. -func void CC_Register(var func f, var string cmdPrefix, var string description) {}; - -/// Removes a function from the console commands. -/// -/// @param f This function will be removed, i.e. the associated command will no longer work. -func void CC_Remove(var func f) {}; - -/// Checks whether the function passed is already part of a console command. -/// -/// @param f Function being checked -/// @return The function returns TRUE if there is a corresponding function, FALSE is returned otherwise. -func int CC_Active(var func f) {}; - -// ========================================================= -// -// Cursor -// -// ========================================================= - -/// Hides the displayed mouse cursor. -func void Cursor_Hide() {}; - -/// Shows the mouse cursor. -func void Cursor_Show() {}; - -/// Can manually enable or disable the mouse. -/// -/// @param enabled TRUE - Mouse activated -func void SetMouseEnabled(var int enabled) {}; - -// ========================================================= -// -// Dialoggestures -// -// ========================================================= - -/// With this function the dialog gestures for all NPCs can be overridden. -/// -/// The full name of the animation can be described as follows: -/// "DIAG_Prefix" + aniName + "DIAG_Suffix" + ((rand() % (max - (min - 1))) + min).ToString("00"); -/// -/// "DIAG_Prefix" and "DIAG_Suffix" are user constants. -/// -/// @param AniName The new dialogue gesture -/// @param Min Lowest animation number -/// @param Max Highest animation number -func void DIAG(var string AniName, var int Min, var int Max) {}; - -/// Resets the dialog gestures to the default. -func void DIAG_Reset() {}; - -/// Sets animation directly. -/// -/// @param AniName Animation name -func void DIAG_SetAni(var string AniName) {}; - -/// Sets animation numbers directly. -/// -/// @param Min Lowest animation number -/// @param Max Highest animation number -func void DIAG_SetMinMax(var int Min, var int Max) {}; - -// ========================================================= -// -// Gamestate -// -// ========================================================= - -/// Adds a listener/handler to the game-state event. -/// -/// @param listener This function will be called on a game-state change. The current game-state is passed as a parameter. -func void Gamestate_AddListener(var func listener) {}; - -/// Removes game-state listener. -/// -/// @param listener Listener function to be removed. -func void Gamestate_RemoveListener(var func listener) {}; - -// ========================================================= -// -// Names -// -// ========================================================= - -/// Should be set in InitGlobal(). -/// -/// @param npc The NPC to be named -/// @param name The name of the NPC -func void SetName(var C_NPC npc, var string name) {}; - -/// Permanently displays the name set by SetName function above the NPC. -/// -/// @param npc The NPC whose name should be shown -func void ShowName(var C_NPC npc) {}; - -// ========================================================= -// -// Render -// -// ========================================================= - -/// Generates the render of an item, with a manually specified priority. -/// -/// @param itemInst The instance of the item to render -/// @param x1 The top left coordinate of the view -/// @param y1 The top left coordinate of the view -/// @param x2 The bottom right coordinate of the view -/// @param y2 The bottom right coordinate of the view -/// @param priority The priority of this render object -/// -/// @return A handle of the render object -func int Render_AddItemPrio(var int itemInst, var int x1, var int y1, var int x2, var int y2, var int priority) {}; - -/// Generates the render of an item, with priority set to 0. -/// -/// @param itemInst The instance of the item to render -/// @param x1 The top left coordinate of the view -/// @param y1 The top left coordinate of the view -/// @param x2 The bottom right coordinate of the view -/// @param y2 The bottom right coordinate of the view -/// -/// @return A handle of the render object -func int Render_AddItem(var int itemInst, var int x1, var int y1, var int x2, var int y2) {}; - -/// Generates the render of a View, with a manually specified priority. -/// -/// @param view A handle to a View -/// @param priority The priority of this render object -/// -/// @return A handle of the render object -func int Render_AddViewPrio(var int view, var int priority) {}; - -/// Generates the render of a View, with priority set to 0. -/// -/// @param view A handle to a View -/// -/// @return A handle of the render object -func int Render_AddView(var int view) {}; - -/// Opens a render object. Only open render objects are displayed. -/// -/// @param handle Handle of a render object -func void Render_OpenView(var int handle) {}; - -/// Closes a render object. Only open render objects are displayed. -/// -/// @param handle Handle of a render object -func void Render_CloseView(var int handle) {}; - -/// Deletes a render object. The associated view is deleted automatically. -/// -/// @param handle Handle of a render object -func void Render_Remove(var int handle) {}; - -// ========================================================= -// -// Trialoge -// -// ========================================================= - -/// Sektenspinner's function. Makes NPC equip a weapon. -/// -/// @param slf NPC to have a weapon equipped -/// @param ItemInstance Weapon instance ID to be equipped -func void EquipWeapon(var C_NPC slf, var int ItemInstance) {}; - -/// Returns NPC's equipped armor. -/// -/// @param slf NPC to get the armor from -/// -/// @return Instance of armor worn by the NPC -func int Npc_GetArmor(var C_NPC slf) {}; - -/// Returns NPC's equipped melee weapon. -/// -/// @param slf NPC to get the weapon from -/// -/// @return Instance ID of the melee weapon equipped by the NPC -func int Npc_GetMeleeWeapon(var C_NPC slf) {}; - -/// Returns NPC's equipped ranged weapon. -/// -/// @param slf NPC to get the weapon from -/// -/// @return Instance ID of the ranged weapon equipped by the NPC -func int Npc_GetRangedWeapon(var C_NPC slf) {}; - -/// Swaps NPCs equipped weapon. -/// -/// @param slf NPC to perform the operation on -/// @param itm0 Instance ID of the item to remove -/// @param itm1 Instance ID of the item to create and equip -func void Npc_TradeItem(var C_NPC slf, var int itm0, var int itm1) {}; - -/// Sektenspinner's function that updates the dialogue camera. (Used internally.) -func void DiaCAM_Update() {}; - -/// Completely disable the dialogue cameras. -func void DiaCAM_Disable() {}; - -/// Resets the dialogue cameras to the default settings. -func void DiaCAM_Enable() {}; - -/// Makes self and other wait for each other, e.g., for AI_GotoWP actions for synchronization. -func void TRIA_Wait() {}; - -/// Invites an NPC into a conversation. Must be called before TRIA_Start. -/// -/// @param slf The invited NPC -func void TRIA_Invite(var C_NPC slf) {}; - -/// Starts trialogues. Before that, all NPCs should be invited by TRIA_Invite. -func void TRIA_Start() {}; - -/// Similar to TRIA_Wait but applies to all participating NPCs. -func void TRIA_Barrier() {}; - -/// Sets the called npc to self. -/// -/// @param n0 NPC to set to self -func void TRIA_Next(var C_NPC n0) {}; - -/// Starts a tracking shot. -/// -/// @param evt The name of the tracking shot in Spacer. If an empty string is passed, the running tracking shot will be aborted. -func void TRIA_Cam(var string evt) {}; - -/// Ends an ongoing trialogue. Must always be called at the end; otherwise, no further trialogues can be started. -func void TRIA_Finish() {}; diff --git a/zengin/scripts/extenders/lego/applications/anim8/index.html b/zengin/scripts/extenders/lego/applications/anim8/index.html deleted file mode 100644 index ade1e2f774..0000000000 --- a/zengin/scripts/extenders/lego/applications/anim8/index.html +++ /dev/null @@ -1,182 +0,0 @@ - Anim8 - Gothic Modding Community

Anim8

This package allows int or float values to be "animated" over a period of time. It is possible to string several commands together and to set the type of movement. The new version of PrintS from Interface uses Anim8.

Dependencies

Initialization

Initialize with LeGo_Anim8 flag.

LeGo_Init(LeGo_Anim8);
-

Implementation

Anim8.d on GitHub

Functions

Anim8_New

Creates a new Anim8 object that can be filled with commands.

func int Anim8_New(var int initialValue, var int IsFloat)
-
Parameters
  • var int initialValue
    The initial value to start animating from. Can be an integer, or an Ikarus float.
  • var int IsFloat
    If the initialValue is an Ikarus float, this parameter must be set to TRUE. If it is an integer, it must be set to FALSE.

Return value

The function returns handle of the Anim8 object.

Anim8_NewExt

Creates a new Anim8 object with advanced options. Extends the Anim8_New function.

func int Anim8_NewExt(var int value, var func handler, var int data, var int IsFloat)
-
Parameters
  • var int value
    The initial value to start animating from. Can be an integer, or an Ikarus float.
  • var func handler
    This function is called whenever the object is updated. The signature of the functions depends on the data value:
    data != 0: func void handler(var int data, var int value),
    data == 0: func void handler(var int value).
  • var int data
    Optional parameter to send an additional value to the handler function. If data == 0, it is ignored.
  • var int IsFloat
    If the initialValue is an Ikarus float, this parameter must be set to TRUE. If it is an integer, it must be set to FALSE.

Return value

The function returns handle of the Anim8 object.

Anim8_Delete

Deletes an Anim8 object created with Anim8_New.

func void Anim8_Delete(var int handle)
-
Parameters
  • var int handle
    Handle returned from Anim8_New

Anim8_Get

Get current value of the object.

func int Anim8_Get(var int handle)
-
Parameters
  • var int handle
    Handle returned from Anim8_New

Return value

The function returns value of the object.

Anim8_Set

Sets the value of the object.

func void Anim8_Set(var int handle, var int value)
-
Parameters
  • var int handle
    Handle returned from Anim8_New
  • var int value
    New value of the object

Anim8_Empty

Indicates whether the object is empty, i.e. has no more commands to process.

func int Anim8_Empty(var int handle)
-
Parameters
  • var int handle
    Handle returned from Anim8_New

Return value

The function returns TRUE if object is empty (has no more commands), FALSE is returned otherwise.

Anim8_RemoveIfEmpty

If desired, Anim8 can automatically delete an object after it is empty.

func void Anim8_RemoveIfEmpty(var int handle, var int on)
-
Parameters
  • var int handle
    Handle returned from Anim8_New
  • var int on
    TRUE: enable, FALSE: disable

Anim8_RemoveDataIfEmpty

With Anim8_NewExt handler and data can be set. If this function is called with TRUE, data is taken as a handle and delete(data) is called if the object is empty. Works only if Anim8_RemoveIfEmpty is also activated.

func void Anim8_RemoveDataIfEmpty(var int handle, var int on)
-
Parameters
  • var int handle
    Handle returned from Anim8_New
  • var int on
    TRUE: enable, FALSE: disable

Anim8

Packet core. Gives the object a new command to process.

func void Anim8(var int handle, var int target, var int span, var int interpol)
-
Parameters
  • var int handle
    Handle returned from Anim8_New
  • var int target
    Target value of this command. When the object's value has reached this value, the command is considered completed and deleted.
  • var int span
    Action duration in milliseconds
  • var int interpol
    What form of movement is used (See constants for this)

Anim8q

As already mentioned above, Anim8 can also process several commands one after the other. While Anim8 completely resets the object and deletes all commands, Anim8q just appends a new command to the list. This will be processed as soon as the previous one is completed.

func void Anim8q(var int handle, var int target, var int span, var int interpol)
-
Parameters
  • var int handle
    Handle returned from Anim8_New
  • var int target
    Target value of this command. When the object's value has reached this value, the command is considered completed and another one in the queue will start.
  • var int span
    Action duration in milliseconds
  • var int interpol
    What form of movement is used (See constants for this)

Anim8_CallOnRemove

Registers a function to be called when the object is deleted (e.g. by Anim8_RemoveIfEmpty)

func void Anim8_CallOnRemove(var int handle, var func dfnc)
-
Parameters
  • var int handle
    Handle returned from Anim8_New
  • var func dfnc
    This function is called when the object is deleted

Examples

Count up to a number

Count from 0 to 10 in 10 seconds. We use the Print_Ext function from Interface to display the text.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
func void Example1()
-{
-    // First we create a handle to a text:
-    var int MyText; MyText = Print_Ext(20, 20, "0", Font_Screen, COL_White, -1);
-
-    // After that we create a new, extended Anim8 object.
-    // It gets a handler and the handle to the text as data:
-    var int MyAnim8; MyAnim8 = Anim8_NewExt(0, MyLoop1, MyText, FALSE); 
-    // Start value 1, MyLoop1 as handler, MyText as data and no float
-
-    // Now the command to count to 10:
-    Anim8(MyAnim8, 10, 10000, A8_Constant); // With MyAnim8 to 10 within 10000ms with constant motion.
-
-    // So that the text and the Anim8 object are deleted after the process. 
-    // Now we have to do two more things:
-    Anim8_RemoveIfEmpty(MyAnim8, TRUE);
-    Anim8_RemoveDataIfEmpty(MyAnim8, TRUE);
-};
-
-func void MyLoop1(var int MyText, var int Number)
-{
-    var zCViewText t; t = _^(myText);
-
-    // Now the text is set to the value of the Anim8 object:
-    t.text = IntToString(Number);
-
-    // As I said, everything is deleted fully automatically
-};
-
A similar example can be found in the Interface examples.

Moving zCVob in loop

Now we make a vob constantly move back and forth, but without a mover. FrameFunctions are used for the loop:

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
-37
-38
-39
-40
-41
var zCVob MyVob;
-var int MyVobAni;
-
-func void Example2()
-{
-    // We use Ikarus to get a pointer to a known VOB:
-    MyVob = MEM_PtrToInst(MEM_SearchVobByName("MYVOB"));
-    // There must be a vob with the appropriate name in the world for this.
-
-    // Since the positions of a vob are floats, this time Anim8 must also use floats:
-    MyVobAni = Anim8_New(MyVob.trafoObjToWorld[3], TRUE);
-    // The X position of the vob serves as the starting value.
-    // We will also move it along this axis.
-
-    // Now start a loop that "nudges" the vob over and over again:
-    FF_Apply(MyVobLoop);
-};
-
-func void MyVobLoop()
-{
-    // We get the pointer to the VOB again
-    MyVob = MEM_PtrToInst(MEM_SearchVobByName("MYVOB"));
-
-    // Whenever there are no more commands, we add new ones:
-    if(Anim8_Empty(MyVobAni))
-    {
-        // First move by three meters:
-        Anim8(MyVobAni, addf(MyVob.trafoObjToWorld[3], mkf(300)), 1000, A8_SlowEnd);
-        // Then wait half a second:
-        Anim8q(MyVobAni, 0, 500, A8_Wait);
-        // And then back again:
-        Anim8q(MyVobAni, MyVob.trafoObjToWorld[3], 1000, A8_SlowEnd);
-        // And wait another half a second:
-        Anim8q(MyVobAni, 0, 500, A8_Wait);
-        // Note the 'q' in the follow-up commands.
-        // While Anim8 completely resets the command list, i.e. starts again, Anim8q appends the command to the queue.
-        // So you can tinker with a command sequence.
-    };
-    // Of course, we must set the "animated" value to the VOB itself
-    MyVob.trafoObjToWorld[3] = Anim8_Get(MyVobAni);
-};
-
\ No newline at end of file diff --git a/zengin/scripts/extenders/lego/applications/bars/index.html b/zengin/scripts/extenders/lego/applications/bars/index.html deleted file mode 100644 index b467941d2b..0000000000 --- a/zengin/scripts/extenders/lego/applications/bars/index.html +++ /dev/null @@ -1,165 +0,0 @@ - Bars - Gothic Modding Community

Bars

This package makes it very easy to add new bars, for e.g. stamina.

Dependencies

Initialization

Initialize with LeGo_Bars flag.

LeGo_Init(LeGo_Bars);
-

Implementation

Bars.d on GitHub

Functions

Note

If the GothicBar prototype is selected as the initial type (GothicBar@ as the constructor), the user's own bars are visually indistinguishable from those used in Gothic.

Bar_Create

Creates a new bar from a constructor instance.

func int Bar_Create(var int inst)
-

Parameters

  • var int inst
    Constructor instance of Bar class

Return value

The function returns the address of the new bar, aka the handle.

Examples

var int bar; bar = Bar_Create(GothicBar@);

1
-2
var int bar; bar = Bar_Create(GothicBar@); // Create a new bar
-Bar_SetPercent(bar, 50);                   // And set the value to 50%
-
1
-2
-3
-4
-5
func void Example_1()
-{
-    var int bar; bar = Bar_Create(GothicBar@); // Create a new bar
-    Bar_SetPercent(bar, 50);                   // And set the value to 50%
-};
-

Bar_Delete

Deletes a bar from the screen and from memory.

func void Bar_Delete(var int bar)
-

Parameters

  • var int bar
    Handle returned from Bar_Create

Bar_SetMax

Changes a bar's maximum value but does not update its bar length (only Bar_SetPercent, Bar_SetPromille and Bar_SetValue)

func void Bar_SetMax(var int bar, var int max)
-
Parameters
  • var int bar
    Handle returned from Bar_Create

  • var int max
    New maximum value

Bar_SetValue

Sets the value of the bar.

func void Bar_SetValue(var int bar, var int val)
-
Parameters
  • var int bar
    Handle returned from Bar_Create
  • var int val
    New value of the bar

Bar_SetPercent

Sets the value of the bar but as a percentage (0..100).

func void Bar_SetPercent(var int bar, var int perc)
-
Parameters
  • var int bar
    Handle returned from Bar_Create
  • var int perc
    New value of the bar in percent

Bar_SetPromille

Sets the value of the bar but per mille (0..1000).

func void Bar_SetPromille(var int bar, var int pro)
-
Parameters
  • var int bar
    Handle returned from Bar_Create
  • var int pro
    New value of the bar in per mille

Bar_Hide

Hides a bar. It will not be deleted.

func void Bar_Hide(var int bar)
-
Parameters
  • var int bar
    Handle returned from Bar_Create

Bar_Show

Displays a bar again after using Bar_Hide.

func void Bar_Show(var int bar)
-
Parameters
  • var int bar
    Handle returned from Bar_Create

Bar_MoveTo

Move the bar to virtual position.

func void Bar_MoveTo(var int bar, var int x, var int y)
-
Parameters
  • var int bar
    Handle returned from Bar_Create
  • var int x
    New horizontal position in virtual coordinates
  • var int y
    New vertical position in virtual coordinates

Bar_MoveToPxl

Move the bar to pixel position.

func void Bar_MoveToPxl(var int bar, var int x, var int y)
-
Parameters
  • var int bar
    Handle returned from Bar_Create
  • var int x
    New horizontal position in pixels
  • var int y
    New vertical position in pixels

Bar_SetAlpha

Sets the transparency of the bar.

func void Bar_SetAlpha(var int bar, var int alpha)
-
Parameters
  • var int bar
    Handle returned from Bar_Create
  • var int alpha
    Transparency value (0..255)

Bar_SetBarTexture

Sets the foreground texture of the bar.

func void Bar_SetBarTexture(var int bar, var string barTex)
-
Parameters
  • var int bar
    Handle returned from Bar_Create
  • var string barTex
    The new foreground texture

Bar_SetBackTexture

Sets the background texture of the bar.

func void Bar_SetBackTexture(var int bar, var string backTex)
-
Parameters
  • var int bar
    Handle returned from Bar_Create
  • var string backTex
    The new background texture

Bar_Resize

Resize an existing bar.

func void Bar_Resize(var int bar, var int width, var int height)
-
Parameters
  • var int bar
    Handle returned from Bar_Create
  • var int width
    New width in virtual coordinates
  • var int height
    New height in virtual coordinates

Bar_ResizePxl

Resize existing bar (in pixels).

func void Bar_ResizePxl(var int bar, var int x, var int y)
-
Parameters
  • var int bar
    Handle returned from Bar_Create
  • var int x
    New width in pixels
  • var int y
    New height in pixels

Examples

Note

The bars assume a certain basic understanding of the PermMem module.

A dedicated experience bar

Bars implement the Bar class. It looks like this:

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
class Bar
-{
-    var int x;          // X position on the screen (middle of the bar)
-    var int y;          // Y position on the screen (middle of the bar)
-    var int barTop;     // Top/bottom margin
-    var int barLeft;    // Left/right margin
-    var int width;      // Bar width
-    var int height;     // Bar height
-    var string backTex; // Background texture
-    var string barTex;  // Actual bar texture
-    var int value;      // Current value
-    var int valueMax;   // Maximum value
-};
-
The GothicBar prototype is a bar, which mimics the standard Gothic status bar.
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
prototype GothicBar(Bar)
-{
-    x = Print_Screen[PS_X] / 2;
-    y = Print_Screen[PS_Y] - 20;
-    barTop = 3;
-    barLeft = 7;
-    width = 180;
-    height = 20;
-    backTex = "Bar_Back.tga";
-    barTex = "Bar_Misc.tga";
-    value = 100;
-    valueMax = 100;
-};
-

It is much easier to set up a new instance using this prototype. GothicBar without modifications can be found as the GothicBar@ instance, which we used to create the bar in the example above. GothicBar is located in the middle of the screen and looks exactly like the Gothic underwater bar.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
// Instance created from 
-instance Bar_1(GothicBar)
-{
-    x = 100;
-    y = 20;
-};
-
-func void Example_1()
-{
-    // Example_1 could e.g. be called in Init_Global
-    FF_ApplyOnce(Loop_1);
-};
-
-func void Loop_1()
-{
-    // Example_1 gets this loop running.
-    // Here the bar should be constructed once
-    // and then adapted to the EXP of the hero:
-    var int MyBar;
-    if(!Hlp_IsValidHandle(MyBar))
-    {
-        MyBar = Bar_Create(Bar_1); // Our Bar_1
-    };
-    // The rest is probably self-explanatory:
-    Bar_SetMax(MyBar, hero.exp_next);
-    Bar_SetValue(MyBar, hero.exp);
-};
-

Note

This is translation of article originally written by Gottfried and Lehona and hosted on LeGo's official documentation website.

\ No newline at end of file diff --git a/zengin/scripts/extenders/lego/applications/bloodsplats/index.html b/zengin/scripts/extenders/lego/applications/bloodsplats/index.html deleted file mode 100644 index 6e6c78bb19..0000000000 --- a/zengin/scripts/extenders/lego/applications/bloodsplats/index.html +++ /dev/null @@ -1,38 +0,0 @@ - Bloodsplats - Gothic Modding Community

Bloodsplats

If this package is activated, red blood splatters will appear on the screen when the hero takes damage. For this, the damage perception for the hero is redirected to _B_HeroDamage(). To use the Bloodsplats, the enclosed textures must be available. Also, the VFX "HERO_HURT" (also included) should be entered in the VfxInst.d to create an even better hit effect. All textures used here are from CGTextures.com. If you use Bloodsplats in your modification, this site must be noted in the credits.

Tip

See user constants to edit behavior of this packet.

Dependencies

Initialization

Initialize with LeGo_Bloodsplats flag.

LeGo_Init(LeGo_Bloodsplats);
-

Implementation

Bloodsplats.d on GitHub

Functions

Bloodsplat

Puts a blood splatter on the screen.

func void Bloodsplat(var int damage)
-
Parameters
  • var int damage
    The damage (affects the size of the splatter)

Bloodsplats_Rage

Pretty pointless feature that smears the entire screen.

func void Bloodsplats_Rage()
-

Npc_GetPercFunc

oCNpc::GetPerceptionFunc engine function wrapper

func int Npc_GetPercFunc(var C_Npc npc, var int type)
-
Parameters
  • var C_NPC npc
    NPC whose perception is checked
  • var int type
    Checked perception type (form Constant.d)

Return value

The function returns the state of NPCs selected perception.

\ No newline at end of file diff --git a/zengin/scripts/extenders/lego/applications/buffs/index.html b/zengin/scripts/extenders/lego/applications/buffs/index.html deleted file mode 100644 index 07e2348ea3..0000000000 --- a/zengin/scripts/extenders/lego/applications/buffs/index.html +++ /dev/null @@ -1,138 +0,0 @@ - Buffs - Gothic Modding Community

Buffs

This package allows you to easily create status effects that can affect any NPC. Status effects on the hero are displayed graphically in a bar.

Dependencies

Initialization

Initialize with LeGo_Buffs flag.

LeGo_Init(LeGo_Buffs);
-

Warning

This package is still experimental and not included in the LeGo_All initialization flag.

Implementation

Buffs.d on GitHub

Functions

Buff_Apply

Applies a status effect to an NPC.

func int Buff_Apply(var C_NPC npc, var int buff)
-
Parameters
  • var C_NPC npc
    NPC to be affected by this effect

  • var int buff
    The instance of the effect to apply to the NPC

Return value

The function returns the handle of the buff, which was just generated.

Buff_ApplyUnique

Buff_Apply, but nothing happens if a status effect of that kind is already on the NPC.

func int Buff_ApplyUnique(var C_NPC npc, var int buff)
-
Parameters
  • var C_NPC npc
    NPC to be affected by this effect

  • var int buff
    The instance of the effect to apply to the NPC

Return value

The function returns the handle of the buff, which was just generated or 0 if the buff is already applied on the NPC.

Buff_ApplyOrRefresh

Buff_Apply, but if a status effect of this type is already affecting the NPC, the duration will be reset.

func int Buff_ApplyOrRefresh(var C_NPC n, var int buff)
-
Parameters
  • var C_NPC npc
    NPC to be affected by this effect

  • var int buff
    The instance of the effect to apply to the NPC

Return value

The function returns the handle of the buff, which was just generated or refreshed.

Buff_Refresh

Resets the duration of the buff.

func void Buff_Refresh(var int buffHandle)
-
Parameters
  • var int buffHandle
    Handle of the buff to refresh

Buff_Remove

Removes the buff from the all NPCs.

func void Buff_Remove(var int buffHandle)
-
Parameters
  • var int buffHandle
    Handle of the buff to remove

Buff_RemoveAll

Removes the buffs form the NPC.

func void Buff_RemoveAll(var C_NPC npc, var int buffInstance)
-
Parameters
  • var C_NPC npc
    NPC whose buff should be removed

Buff_GetNpc

Returns a pointer to the NPC, which is affected by the buff.

func int Buff_GetNpc(var int buffHandle)
-
Parameters
  • var int buffHandle
    Handle of the buff

Return value

The function returns a pointer to the NPC, which is affected by the buff.

Buff_Has

Checks if the NPC already has an effect applied.

func int Buff_Has(var C_NPC npc, var int buff)
-
Parameters
  • var C_NPC npc
    Checked NPC

  • var int buff
    The instance of the effect

Return value

The function returns TRUE if the NPC has an effect applied. FALSE is returned otherwise.

SAVE_GetFuncID

Same as MEM_GetFuncID but gets the current instance.

func int SAVE_GetFuncID(var func f)
-
Parameters

var func f
Function whose ID is got

Return value

The function returns the ID of given function.

lCBuff class

The buffs package implements an lCBuff class, which looks like this:

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
class lCBuff
-{
-    var string name;    // buff name 
-    var int buffType;   // GOOD / NEUTRAL / BAD | 1 / 0 / -1
-    var int targetID;   // NPC that is currently affected by this buff
-    var int durationMS; // buff duration in milliseconds
-    var int tickMS;     // tick duration in milliseconds, first tick occurs at tickMS milliseconds
-    var int nextTickNr; // e.g. before the first tick this will be 0; OBSOLETE, remove when possible
-
-    var int OnApply; 
-    var int OnTick;
-    var int OnRemoved;
-
-    var string buffTex;  // associated texture - currently only used for buffs applied on the hero
-    // var int originID; // Who casted/created this buff?
-
-    // Internal, no need to set during instance construction
-    var int _startedTime;
-    var int _endTime;    // Not redundant with durationMS because buffs can be refreshed
-};
-

Examples

Delayed poison

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
instance deadly_poison(lCBuff)
-{
-    name = "Deadly poison";
-    bufftype = BUFF_BAD;
-
-    durationMS = 10*1000; // 10 seconds long
-    tickMS = 1000;        // Every second
-
-    buffTex = "POISON.TGA";
-};
-

Damage should also be added:

1
-2
-3
-4
-5
-6
-7
-8
func void deadly_poison_damage(var int buffHandle)
-{
-    var int ptr; ptr = Buff_GetNpc(buffHandle);
-    if (!ptr) { return; }; // Can happen if e.g. the world was changed
-
-    var C_NPC npc; npc = _^(ptr);
-    Npc_ChangeAttribute(npc, ATR_HITPOINTS, -3); // 3 damage
-};
-
For complicated technical reasons we use the function SAVE_GetFuncID instead of MEM_GetFuncID.
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
instance deadly_poison(lCBuff)
-{
-    name = "Deadly poison";
-    bufftype = BUFF_BAD;
-
-    durationMS = 10 * 1000; //10 seconds long
-    tickMS = 1000; // Every second
-
-    onTick = SAVE_GetFuncID(deadly_poison_damage); // The damage should be applied every second
-    buffTex = "POISON.TGA";
-};
-

For example, if this buff is now applied to the hero, by calling Buff_Apply(hero, deadly_poison), he loses a total of 30 HP over 10 seconds.

\ No newline at end of file diff --git a/zengin/scripts/extenders/lego/applications/buttons/index.html b/zengin/scripts/extenders/lego/applications/buttons/index.html deleted file mode 100644 index bd24a59f87..0000000000 --- a/zengin/scripts/extenders/lego/applications/buttons/index.html +++ /dev/null @@ -1,57 +0,0 @@ - Buttons - Gothic Modding Community

Buttons

This package extends the handling of the mouse and allows creating rectangular buttons, which react to mouse (hover) entry and exit as well as a mouse click.

Dependencies

Initialization

Initialize with LeGo_Buttons flag.

LeGo_Init(LeGo_Buttons);
-

Implementation

Buffs.d on GitHub

Functions

Button_Create

Creates a button. It is initially hidden (not visible and does not react to the mouse). The three callback functions have the following signature void f(int handle).

func int Button_Create(var int posx, var int posy, var int width, var int height, var string tex, var func on_enter, var func on_leave, var func on_click)
-
Parameters
  • var int posx
    The horizontal position of the button in virtual coordinates
  • var int posy
    The vertical position of the button in virtual coordinates
  • var int width
    Width of the button in virtual coordinates
  • var int height
    Height of the button in virtual coordinates
  • var string tex
    Name of the button texture
  • var func on_enter
    This function is called when the mouse enters the button
  • var func on_leave
    This function is called when the mouse leaves the button
  • var func on_click
    This function is called when the user performs a mouse click on the button (left mouse button)

Return value

The function returns a handle to created button.

Button_CreatePxl

Button_Create with pixels instead of virtual coordinates.

func int Button_CreatePxl(var int posx, var int posy, var int width, var int height, var string tex, var func on_enter, var func on_leave, var func on_click)
-
Parameters
  • var int posx
    The horizontal position of the button in pixels
  • var int posy
    The vertical position of the button in pixels
  • var int width
    Width of the button in pixels
  • var int height
    Height of the button in pixels
  • var string tex
    Name of the button texture
  • var func on_enter
    This function is called when the mouse enters the button
  • var func on_leave
    This function is called when the mouse leaves the button
  • var func on_click
    This function is called when the user performs a mouse click on the button (left mouse button)

Return value

The function returns a handle to created button.

Button_Delete

Completely deletes a button.

func void Button_Delete(var int hndl)
-
Parameters
  • var int hndl
    Handle returned from Button_Create

Button_Show

Shows the button and makes it respond to the mouse.

func void Button_Show(var int hndl)
-
Parameters
  • var int hndl
    Handle returned from Button_Create

Button_Hide

Hides the button and disables it, so it is no longer responding to the mouse.

func void Button_Hide(var int hndl)
-
Parameters
  • var int hndl
    Handle returned from Button_Create

Button_SetTexture

Sets the texture of the button.

func void Button_SetTexture(var int hndl, var string tex)
-
Parameters
  • var int hndl
    Handle returned from Button_Create
  • var string tex
    Name of the new texture

Button_SetCaption

Displays a centered text on the button.

func void Button_SetCaption(var int hndl, var string caption, var string font)
-
Parameters
  • var int hndl
    Handle returned from Button_Create
  • var string caption
    The text to be displayed
  • var string font
    The font in which the text should be displayed

Button_CreateMouseover

Attaches a mouseover box to the cursor.

func void Button_CreateMouseover(var string text, var string font)
-
Parameters
  • var string text
    The text in the mouseover box
  • var string font
    The font of the text

Button_DeleteMouseover

Deletes the mouseover box.

func void Button_DeleteMouseover()
-

Button_Activate

Activates the button, so it reacts to the mouse. Does not change the visibility.

func void Button_Activate(var int hndl)
-
Parameters
  • var int hndl
    Handle returned from Button_Create

Button_Deactivate

Disables the button, so it no longer reacts to the mouse.

func void Button_Deactivate(var int hndl)
-
Parameters
  • var int hndl
    Handle returned from Button_Create

Button_SetUserData

Sets the user data of the button, an integer, to give the button individual information.

func void Button_SetUserData(var int hndl, var int data)
-
Parameters
  • var int hndl
    Handle returned from Button_Create
  • var int data
    Individual integer of the button (part of the internal _Button class)

Button_GetUserData

Gets the user data of the button.

func int Button_GetUserData(var int hndl)
-
Parameters
  • var int hndl
    Handle returned from Button_Create

Return value

The function returns the user data of the button.

Button_GetState

Gets the status of the button as a bit field. See User Constants.

func int Button_GetState(var int hndl)
-
Parameters
  • var int hndl
    Handle returned from Button_Create

Return value

The function returns the status of the button.

Button_Move

Moves the button by the given value in pixels. posx = posx + nposx

func void Button_Move(var int hndl, var int nposx, var int nposy)
-
Parameters
  • var int hndl
    Handle returned from Button_Create
  • var int nposx
    X-axis shift in pixels
  • var int nposy
    Y-axis shift in pixels

Button_MoveVrt

Moves the button by the given value in virtual coordinates. posx = posx + nposx

func void Button_Move(var int hndl, var int nposx, var int nposy)
-
Parameters
  • var int hndl
    Handle returned from Button_Create
  • var int nposx
    X-axis shift in virtual coordinates
  • var int nposy
    Y-axis shift in virtual coordinates

Button_MoveTo

Moves a button to the given position in pixels. posx = nposx

func void Button_MoveVrt(var int hndl, var int nposx, var int nposy)
-
Parameters
  • var int hndl
    Handle returned from Button_Create
  • var int nposx
    New horizontal position in pixels
  • var int nposy
    New vertical position in pixels

Button_MoveToVrt

Moves a button to the given position in virtual coordinates. posx = nvposx

func void Button_MoveVrt(var int hndl, var int nvposx, var int nvposy)
-
Parameters
  • var int hndl
    Handle returned from Button_Create
  • var int nvposx
    New horizontal position in virtual coordinates
  • var int nvposy
    New vertical position in virtual coordinates

Button_GetViewHandle

Returns the button's zCView as a handle.

func int Button_GetViewHandle(var int hndl)
-
Parameters
  • var int hndl
    Handle returned from Button_Create

Return value

The function returns the button's zCView as a handle.

Button_GetViewPtr

Returns the button's zCView as a pointer.

func int Button_GetViewPtr(var int hndl)
-
Parameters
  • var int hndl
    Handle returned from Button_Create

Return value

The function returns the button's zCView as a pointer.

Button_GetView

Returns the button's zCView as an object.

func zCView Button_GetView(var int hndl)
-
Parameters
  • var int hndl
    Handle returned from Button_Create

Return value

The function returns the button's zCView as an object.

Button_GetCaptionPtr

Returns the pointer to the text of the button.

func int Button_GetCaptionPtr(var int hndl)
-
Parameters
  • var int hndl
    Handle returned from Button_Create

Return value

The function returns the pointer to the text of the button.

\ No newline at end of file diff --git a/zengin/scripts/extenders/lego/applications/console_commands/index.html b/zengin/scripts/extenders/lego/applications/console_commands/index.html deleted file mode 100644 index 6e5f6fdedb..0000000000 --- a/zengin/scripts/extenders/lego/applications/console_commands/index.html +++ /dev/null @@ -1,86 +0,0 @@ - Console Commands - Gothic Modding Community

Console Commands

This package allows you to create new console commands.

Dependencies

Initialization

Initialize with LeGo_ConsoleCommands flag.

LeGo_Init(LeGo_ConsoleCommands);
-

Implementation

ConsoleCommands.d on GitHub

Functions

CC_Register

Registers a new console command.

func void CC_Register(var func f, var string cmdPrefix, var string description)
-
Parameters
  • var func f
    This function is executed when the cmdPrefix command is entered in the console. The function signature is func string f(var string p0). The string passed is everything that was specified in the console after the actual command. The return value is then displayed in the console.
  • var string cmdPrefix
    This is a command, which can be entered in the console.
  • var string description
    This text appears next to the command (in zSpy) when you use the help command in the console.

CC_Remove

Removes a function from the console commands.

func void CC_Remove(var func f)
-
Parameters
  • var func f
    This function will be removed, i.e. the associated command will no longer work.

CC_Active

Checks whether the function passed is already part of a console command.

func int CC_Active(var func f)
-
Parameters
  • var func f
    Function being checked

Return value

The function returns TRUE if there is a corresponding function, FALSE is returned otherwise.

Examples

Basic command example

As a basic example - let us create a version command, which prints a version of our modification.
Firstly, we declare a constant string variable to hold the version string to be shown.

const string Mod_Version = "My mod version 0.1alpha";
-
Next we create the command function.

Note

Notice the correct function signature. If you do not adhere to the correct function signature, the command will crash the game.

1
-2
-3
-4
-5
// This function is called by our console
-func string CC_ModVersion(var string param)
-{
-    return Mod_Version;
-};
-
We then have to register the functions. For convenience, I created a new RegisterConsoleFunctions function to initialize all console commands. The function is really simple.
1
-2
-3
-4
func void RegisterConsoleFunctions()
-{
-    CC_Register (CC_ModVersion, "version", "Version of my amazing mod.");
-};
-
Lastly, we have to call this function from INIT_GLOBAL function.
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
func void INIT_GLOBAL()
-{
-    // will be called for every world (from INIT_<LevelName>)
-    Game_InitGerman();
-
-    // Ikarus initialization
-    MEM_InitAll();
-
-    // LeGo initialization
-    LeGo_Init(LeGo_ConsoleCommands);
-
-    // Here we register all of our commands
-    RegisterConsoleFunctions();
-
-    // the rest of the code 
-};
-
\ No newline at end of file diff --git a/zengin/scripts/extenders/lego/applications/cursor/index.html b/zengin/scripts/extenders/lego/applications/cursor/index.html deleted file mode 100644 index e0f219047c..0000000000 --- a/zengin/scripts/extenders/lego/applications/cursor/index.html +++ /dev/null @@ -1,182 +0,0 @@ - Cursor - Gothic Modding Community

Cursor

This package implements Gothic in-game mouse cursor support. To visually display the cursor there is a Cursor.tga file in the resources, but the texture can be changed in user constants.

Warning

The cursor only works if the mouse is activated in the Gothic settings. It can be done directly from the scripts. See the Ini file access.

Dependencies

Initialization

Initialize with LeGo_Cursor flag.

LeGo_Init(LeGo_Cursor);
-

Implementation

Cursor.d on GitHub

Variables

  • var int Cursor_X
    Always contains the X coordinate of the mouse cursor.
  • var int Cursor_Y
    Always contains the Y coordinate of the mouse cursor.
  • var float Cursor_RelX
    Always contains the relative X coordinate of the mouse cursor as an Ikarus float.
  • var float Cursor_RelY
    Always contains the relative Y coordinate of the mouse cursor as an Ikarus float.
  • var int Cursor_Wheel
    Variable containing the value of the mouse wheel.
  • var int Cursor_Left
    Variable that always contains the KeyState of the left mouse button.
  • var int Cursor_Mid
    Variable that always contains the KeyState of the middle mouse button.
  • var int Cursor_Right
    Variable that always contains the KeyState of the right mouse button.
  • var int Cursor_Event
    An event handler that can send information about the mouse cursor. It can be used with all functions of the EventHandler package.
  • var int Cursor_NoEngine
    Variable that can prevent the engine from working. If is set to TRUE the engine no longer reacts to mouse movements.

Functions

Cursor_Hide

Hides the displayed mouse cursor.

func void Cursor_Hide()
-

Cursor_Show

Shows the mouse cursor.

func void Cursor_Show()
-

SetMouseEnabled

Can manually enable or disable the mouse.

func void SetMouseEnabled(var int enabled)
-
Parameters
  • var int enabled
    TRUE - Mouse activated

Examples

Click a button

We use a View to display a button to be clicked. The FrameFunctions take care of the loop to check whether a click was made.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
-37
-38
-39
-40
var int Button;
-func void Example1()
-{
-    // We show the cursor and at the same time a button to be clicked:
-    Cursor_Show();
-
-    // New View:
-    Button = View_CreatePxl(5, 5, 125, 50);
-    View_SetTexture(Button, "BUTTONTEX.TGA");
-    View_Open(Button);
-
-    // Optionally, mouse can be switched off for the engine:
-    Cursor_NoEngine = true; // -> The engine then no longer reacts to movements, so the camera does not move either
-
-    // Enable loop function:
-    FF_ApplyOnce(Button_Click);
-};
-
-func void Button_Click()
-{
-    if(Cursor_Left != KEY_PRESSED) { return; }; // Exit the function if the left mouse button was not pressed
-
-    if(Cursor_X >= 5 && Cursor_X <= 125
-    && Cursor_Y >= 5 && Cursor_Y <= 50) // Simply take over the coordinates of the view
-    { 
-        // Here the button was clicked.
-        // Remove button and end loop:
-        View_Close(Button);
-        View_Delete(Button);
-        Button = 0;
-
-        // Allow the engine to continue working:
-        Cursor_NoEngine = false;
-
-        FF_Remove(Button_Click);
-
-        // Hide the mouse:
-        Cursor_Hide();
-    };
-};
-

This also can be done by the Buttons package instead of View.

Event handler

Since LeGo 2.2 there is also an event handler (var int Cursor_Event) in the cursor package. This example briefly explains how it works:

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
func void Example2()
-{
-    // We register MyCursorListener as the handler/listener of the Cursor_Event:
-    Event_Add(Cursor_Event, MyCursorListener);
-
-    // From now on, MyCursorListener will be called whenever the cursor has something to report.
-};
-
-func void MyCursorListener(var int state)
-{
-    // The rest is self-explanatory:
-
-    if(state == CUR_WheelUp)
-    {
-        PrintS("Wheel up!");
-    };
-    if(state == CUR_WheelDown)
-    {
-        PrintS("Wheel down!");
-    };
-    if(state == CUR_LeftClick)
-    {
-        PrintS("Leftclick!");
-    };
-    if(state == CUR_RightClick)
-    {
-        PrintS("Rightclick!");
-    };
-    if(state == CUR_MidClick)
-    {
-        PrintS("Wheelclick!");
-    };
-};
-
Constants used in the example can be found in the user constants.
\ No newline at end of file diff --git a/zengin/scripts/extenders/lego/applications/dialoggestures/index.html b/zengin/scripts/extenders/lego/applications/dialoggestures/index.html deleted file mode 100644 index a793e6cb93..0000000000 --- a/zengin/scripts/extenders/lego/applications/dialoggestures/index.html +++ /dev/null @@ -1,39 +0,0 @@ - Dialoggestures - Gothic Modding Community

Dialoggestures

This package can modify the NPCs' gestures during dialogue to better bring out emotions.

Dependencies

Initialization

N/A

Implementation

Dialoggestures.d on GitHub

Functions

DIAG

With this function the dialog gestures for all NPCs can be overridden. To understand the principle, it is recommended to take a look at the examples.

The full name of the animation can be described as follows:

DIAG_Prefix + aniName + DIAG_Suffix + ((rand() % (max - (min - 1))) + min).ToString("00");
-
DIAG_Prefix and DIAG_Suffix are user constants.

func void DIAG(var string AniName, var int Min, var int Max)
-
Parameters
  • var string AniName
    The new dialogue gesture
  • var int Min
    Lowest animation number
  • var int Max
    Highest animation number

DIAG_Reset

Resets the dialog gestures to the default.

func void DIAG_Reset()
-

DIAG_SetAni

Sets animation directly.

func void DIAG_SetAni(var string AniName)
-
Parameters
  • var string AniName
    Animation name

DIAG_SetMinMax

Sets animation numbers directly.

func void DIAG_SetMinMax(var int min, var int max)
-
Parameters
  • var int min
    Lowest animation number
  • var int max
    Highest animation number

Examples

Note

See Examples in the Trialoge article.

\ No newline at end of file diff --git a/zengin/scripts/extenders/lego/applications/focusnames/index.html b/zengin/scripts/extenders/lego/applications/focusnames/index.html deleted file mode 100644 index 0d6591ba39..0000000000 --- a/zengin/scripts/extenders/lego/applications/focusnames/index.html +++ /dev/null @@ -1,63 +0,0 @@ - Focusnames - Gothic Modding Community

Focusnames

This package colors the focus names of the NPCs in appropriate colors according to the behavior defined below (alpha values are taken into account). Also affects monsters. (Mobs/Items get Color_Neutral)

Dependencies

Initialization

Initialize with LeGo_Focusnames flag.

LeGo_Init(LeGo_Focusnames);
-

Implementation

Focusnames.d on GitHub

Usage

If you want to change colors for any behavior edit the following functions directly in Focusnames.d file.

Focusnames_Color_Friendly

1
-2
-3
-4
func int Focusnames_Color_Friendly()
-{
-    return RGBA(0, 255, 0, 255); // Green
-};
-

Focusnames_Color_Neutral

1
-2
-3
-4
func int Focusnames_Color_Neutral()
-{
-    return RGBA(255, 255, 255, 255); // White
-};
-

Focusnames_Color_Angry

1
-2
-3
-4
func int Focusnames_Color_Angry()
-{
-    return RGBA(255, 180, 0, 255); // Orange
-};
-

Focusnames_Color_Hostile

1
-2
-3
-4
func int Focusnames_Color_Hostile()
-{
-    return RGBA(255, 0, 0, 255); // Red
-};
-
\ No newline at end of file diff --git a/zengin/scripts/extenders/lego/applications/gamestate/index.html b/zengin/scripts/extenders/lego/applications/gamestate/index.html deleted file mode 100644 index ef4eefc2be..0000000000 --- a/zengin/scripts/extenders/lego/applications/gamestate/index.html +++ /dev/null @@ -1,177 +0,0 @@ - Gamestate - Gothic Modding Community

Gamestate

Gamestate package allows to check for different game states (game start, game load or level change).

Dependencies

Initialization

Initialize with LeGo_Gamestate flag.

LeGo_Init(LeGo_Gamestate);
-

Implementation

Gamestate.d on GitHub

Functions

Gamestate_AddListener

Adds a listener/handler to the game-state event.

func void Gamestate_AddListener(var func listener)
-
Parameters
  • var func listener
    This function will be called on a game-state change. The current game-state is passed as a parameter.

Gamestate_RemoveListener

Removes game-state listener.

func void Gamestate_RemoveListener(var func listener)
-
Parameters
  • var func listener
    Listener function to be removed.

Examples

There are now two possibilities. Everything can be done directly into the Init_Global, or with EventHandler.

Init_Global

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
func void Init_Global()
-{
-    // [...]
-
-    LeGo_Init(LeGo_All);
-
-    if(Gamestate == Gamestate_NewGame) 
-    {
-        MEM_Info("New game started.");
-    }
-    else if(Gamestate == Gamestate_Loaded)
-    {
-        MEM_Info("Game loaded.");
-    }
-    else if(Gamestate == Gamestate_WorldChange)
-    {
-        MEM_Info("Worldshift.");
-    }
-    else
-    {
-        MEM_Info("I don't pass.");
-    };
-};
-

It can also be done like that:

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
func void Init_Global()
-{
-    // [...]
-
-    LeGo_Init(LeGo_All);
-
-    if(Gamestate == Gamestate_NewGame)
-    {
-        FF_Apply(MyLoop);
-        FF_Apply(My2ndLoop);
-    };
-};
-
This would have the same effect as:
1
-2
-3
-4
-5
-6
-7
-8
-9
func void Init_Global()
-{
-    // [...]
-
-    LeGo_Init(LeGo_All);
-
-    FF_ApplyOnce(MyLoop);
-    FF_ApplyOnce(My2ndLoop);
-};
-

EventHandler

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
func void Init_Global()
-{
-    // [...]
-
-    LeGo_Init(LeGo_All);
-
-    Gamestate_AddListener(MyGamestateListener);
-};
-
-func void MyGamestateListener(var int state)
-{
-    if(state == Gamestate_NewGame)
-    {
-        MEM_Info("New game started.");
-    }
-    else if(state == Gamestate_Loaded)
-    {
-        MEM_Info("Game loaded.");
-    }
-    else if(state == Gamestate_WorldChange)
-    {
-        MEM_Info("Worldshift.");
-    }
-    else
-    {
-        MEM_Info("I don't pass.");
-    };
-};
-
This is the same as the Init_Global example, but it may look more elegant to some.

Note

This is translation of article originally written by Gottfried and Lehona and hosted on LeGo's official documentation website.

\ No newline at end of file diff --git a/zengin/scripts/extenders/lego/applications/names/index.html b/zengin/scripts/extenders/lego/applications/names/index.html deleted file mode 100644 index fd73d52910..0000000000 --- a/zengin/scripts/extenders/lego/applications/names/index.html +++ /dev/null @@ -1,57 +0,0 @@ - Names - Gothic Modding Community

Names

Allows the user to change NPC name e.g. after he shows up.

Dependencies

Initialization

N/A

Implementation

Names.d on GitHub

Functions

SetName

Should be set in InitGlobal().

func void SetName(var C_NPC npc, var string name)
-
Parameters
  • var C_NPC npc
    The NPC to be named
  • var string name
    The name of the NPC

ShowName

Permanently displays the name set by SetName function above the npc.

func void ShowName(var C_NPC npc)
-
Parameters
  • var C_NPC npc
    The NPC whose name should be shown

Examples

Show the name of an NPC later

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
instance PAL_100_Friend(C_NPC)
-{
-    name = "Paladin";
-
-    // [...]
-};
-
-func void Init_Global()
-{
-    SetName(PAL_100_Friend, "Arto");
-};
-
At the start of the game, the name "Paladin" is displayed above PAL_100_Friend.

If ShowName(PAL_100_Friend); is used during a dialogue, the name "Arto" is permanently visible above the npc.

\ No newline at end of file diff --git a/zengin/scripts/extenders/lego/applications/render/index.html b/zengin/scripts/extenders/lego/applications/render/index.html deleted file mode 100644 index db1c779f3c..0000000000 --- a/zengin/scripts/extenders/lego/applications/render/index.html +++ /dev/null @@ -1,42 +0,0 @@ - Render - Gothic Modding Community

Render

With this package items can be rendered on the screen. Since items are rendered independently of the normal views, textures that are 'below' the items must also be managed by this package, this behaviour is managed by the priority system. The view with the highest priority is always rendered first, so it is at the bottom. In theory, any .3DS model can be rendered if you just create a suitable item script.

Dependencies

Initialization

Initialize with LeGo_Render flag.

LeGo_Init(LeGo_Render);
-

Warning

This package is still experimental and not included in LeGo_All initialization flag.

Implementation

Render.d on GitHub

Functions

Render_AddItemPrio

Generates the render of an item, with a manually specified priority.

func int Render_AddItemPrio(var int itemInst, var int x1, var int y1, var int x2, var int y2, var int priority)
-
Parameters
  • var int itemInst
    The instance of the item to render
  • var int x1 var int y1
    The top left coordinate of the view
  • var int x2 var int y2
    The bottom right coordinate of the view
  • var int priority
    The priority of this render object

Return value

The function returns a handle of the render object.

Render_AddItem

Generates the render of an item, with priority set to 0.

func int Render_AddItem(var int itemInst, var int x1, var int y1, var int x2, var int y2)
-
Parameters
  • var int itemInst
    The instance of the item to render
  • var int x1 var int y1
    The top left coordinate of the view
  • var int x2 var int y2
    The bottom right coordinate of the view

Return value

The function returns a handle of the render object.

Render_AddViewPrio

Generates the render of a View, with a manually specified priority.

func int Render_AddViewPrio(var int view, var int priority)
-
Parameters
  • var int view
    A handle to a View
  • var int priority
    The priority of this render object

Return value

The function returns a handle of the render object.

Render_AddView

Generates the render of a View, with priority set to 0.

func int Render_AddView(var int view)
-
Parameters
  • var int view
    A handle to a View

Return value

The function returns a handle of the render object.

Render_OpenView

Opens a render object. Only open render objects are displayed.

func void Render_OpenView(var int handle)
-
Parameters
  • var int handle
    Handle of a render object

Render_CloseView

Closes a render object. Only open render objects are displayed.

func void Render_CloseView(var int handle)
-
Parameters
  • var int handle
    Handle of a render object

Render_Remove

Deletes a render object. The associated view is deleted automatically.

func void Render_Remove(var int handle)
-
Parameters
  • var int handle
    Handle of a render object
\ No newline at end of file diff --git a/zengin/scripts/extenders/lego/applications/saves/index.html b/zengin/scripts/extenders/lego/applications/saves/index.html deleted file mode 100644 index 72547b9513..0000000000 --- a/zengin/scripts/extenders/lego/applications/saves/index.html +++ /dev/null @@ -1,95 +0,0 @@ - Saves - Gothic Modding Community

Saves

Offers an open file stream that can read/write variables on save/load. It is used by PermMem, so you don't need to address it manually anymore.

Dependencies

Initialization

Initialize with LeGo_Saves flag.

LeGo_Init(LeGo_Saves);
-

Implementation

Saves.d on GitHub

Functions

BW_Savegame

Custom function. It creates a stream to its own memory file, this can be filled with the BW_* functions from the BinaryMachines.

func void BW_Savegame()
-

BR_Savegame

Custom function. It opens a stream to a previously saved memory file, which can be read from the BinaryMachines using the BR_* functions.

func void BR_Savegame()
-

Examples

Save a high score list

var string MyScoreList[10];
-

Since strings are not saved by the game by default, we use the functions from Saves.d to create an additional memory file that only belongs to us. At the top the Saves.d file has two functions: BW_Savegame and BR_Savegame. BinaryMachines functions are used to save or read the file, we don't need to do anything else than to use them here, the rest is done by Saves.d completely by itself. Therefore, we only modify these two functions.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
func void BW_Savegame() 
-{
-    // Save high score list
-    BW_String(MyScoreList[0]);
-    BW_String(MyScoreList[1]);
-    BW_String(MyScoreList[2]);
-    BW_String(MyScoreList[3]);
-    BW_String(MyScoreList[4]);
-    BW_String(MyScoreList[5]);
-    BW_String(MyScoreList[6]);
-    BW_String(MyScoreList[7]);
-    BW_String(MyScoreList[8]);
-    BW_String(MyScoreList[9]);
-};
-
-func void BR_Savegame() 
-{
-    // Load high score list
-    MyScoreList[0] = BR_String();
-    MyScoreList[1] = BR_String();
-    MyScoreList[2] = BR_String();
-    MyScoreList[3] = BR_String();
-    MyScoreList[4] = BR_String();
-    MyScoreList[5] = BR_String();
-    MyScoreList[6] = BR_String();
-    MyScoreList[7] = BR_String();
-    MyScoreList[8] = BR_String();
-    MyScoreList[9] = BR_String();
-};
-

Tip

Since LeGo 2.0, such things can be implemented much more elegantly with PermMem.

\ No newline at end of file diff --git a/zengin/scripts/extenders/lego/applications/trialoge/index.html b/zengin/scripts/extenders/lego/applications/trialoge/index.html deleted file mode 100644 index 286f4b59be..0000000000 --- a/zengin/scripts/extenders/lego/applications/trialoge/index.html +++ /dev/null @@ -1,225 +0,0 @@ - Trialoge - Gothic Modding Community

Trialoge

This package allows you to create conversations with any number of NPCs and control the camera during the dialog.

Dependencies

Initialization

Initialize with LeGo_Trialoge flag.

LeGo_Init(LeGo_Trialoge);
-

Implementation

Trialoge.d on GitHub

Functions

EquipWeapon

Sektenspinner's function. Makes NPC equip a weapon.

func void EquipWeapon(var C_NPC slf, var int ItemInstance)
-
Parameters
  • var C_NPC slf
    NPC to have a weapon equipped
  • var int ItemInstance
    Weapon instance ID to be equipped

Configuration

const int EquipWeapon_TogglesEquip = 1

Above constant configures the behaviour of the function when trying to equip an already equipped weapon:

  • 0 - EquipWeapon will do nothing
  • 1 - EquipWeapon will unequip this weapon

Npc_GetArmor

Returns NPC's equipped armor.

func int Npc_GetArmor(var C_NPC slf)
-
Parameters
  • var C_NPC slf
    NPC to get the armor from

Return value

The function returns instance of armor worn by the NPC.

Npc_GetMeleeWeapon

Returns NPC's equipped melee weapon.

func int Npc_GetMeleeWeapon(var C_NPC slf)
-
Parameters
  • var C_NPC slf
    NPC to get the weapon from

Return value

The function returns instance ID of melee weapon equipped by the NPC.

Npc_GetRangedWeapon

Returns NPC's equipped ranged weapon.

func int Npc_GetRangedWeapon(var c_npc slf)
-
Parameters
  • var C_NPC slf
    NPC to get the weapon from

Return value

The function returns instance ID of ranged weapon equipped by the NPC.

Npc_TradeItem

Swaps NPCs equipped weapon.

func void Npc_TradeItem(var c_npc slf, var int itm0, var int itm1) 
-
Parameters
  • var C_NPC slf
    NPC to perform operation on
  • var int itm0
    instance ID of item to remove
  • var int itm1
    instance ID of item to create and equip

DiaCAM_Update

Sektenspinner's function that updates the dialogue camera. (Used internally.)

func void DiaCAM_Update()
-

DiaCAM_Disable

Completely disable the dialogue cameras.

func void DiaCAM_Disable()
-

DiaCAM_Enable

Resets the dialogue cameras to the default settings.

func void DiaCAM_Enable()
-

TRIA_Wait

Makes self and other wait for each other, e.g. for AI_GotoWP actions for synchronization.

func void TRIA_Wait()
-

TRIA_Invite

Invites an NPC into a conversation. Must be called before TRIA_Start.

func void TRIA_Invite(var C_NPC slf)
-
Parameters
  • var C_NPC slf
    The invited NPC

TRIA_Start

Starts trialogues. Before that, all NPCs should be invited by TRIA_Invite.

func void TRIA_Start()
-

TRIA_Barrier

Similar to TRIA_Wait but applies to all participating NPCs.

func void TRIA_Barrier()
-

TRIA_Next

Sets the called npc to self.

func void TRIA_Next(var C_NPC n0)
-
Parameters
  • var C_NPC n0
    NPC to set to self

TRIA_Cam

Starts a tracking shot.

func void TRIA_Cam(var string evt)
-
Parameters
  • var string evt
    The name of the tracking shot in Spacer. If "" is passed, the running trace shot will be aborted.

TRIA_Finish

Ends an ongoing trialogue. Must always be called at the end, otherwise no further trialogues can be started.

func void TRIA_Finish()
-

Examples

A Simple Trialogue

The following conversation is resolved via the trialogues:

  1. Arto: I'm sorry Hero, but you can't pass here.
  2. Hero: Why not?
  3. Horka: The city has been closed.
  4. Hero: I have some gold with me, can we trade?
  5. Squelto: No. We are not open to bribery.
  6. Hero: Sure?
  7. Arto: I have to ask you to leave now.
  8. Hero: Well...
     1
    - 2
    - 3
    - 4
    - 5
    - 6
    - 7
    - 8
    - 9
    -10
    -11
    -12
    -13
    -14
    -15
    -16
    -17
    -18
    -19
    -20
    -21
    -22
    -23
    -24
    -25
    -26
    -27
    -28
    -29
    -30
    -31
    -32
    -33
    -34
    -35
    -36
    -37
    -38
    -39
    -40
    -41
    -42
    -43
    -44
    -45
    -46
    -47
    -48
    -49
    -50
    -51
    -52
    -53
    -54
    -55
    -56
    -57
    -58
    -59
    -60
    -61
    -62
    -63
    -64
    -65
    -66
    -67
    -68
    -69
    -70
    -71
    -72
    -73
    -74
    -75
    -76
    -77
    -78
    -79
    -80
    -81
    -82
    -83
    -84
    -85
    -86
    -87
    -88
    instance TRIA_Test (C_INFO)
    -{
    -    npc         = PAL_100_Friend;
    -    nr          = 10;
    -    condition   = TRIA_Test_condition;
    -    information = TRIA_Test_info;
    -    important   = FALSE;
    -    permanent   = 1;
    -    description = "TRIALOGTEST";
    -};
    -
    -func int TRIA_Test_condition()
    -{
    -    return TRUE;
    -};
    -
    -func void TRIA_Test_info()
    -{
    -    var C_NPC Arto; Arto       = Hlp_GetNpc(PAL_100_Friend); // He is the owner of dialogue
    -    var C_NPC Horka; Horka     = Hlp_GetNpc(PAL_101_Horka);
    -    var C_NPC Squelto; Squelto = Hlp_GetNpc(PAL_102_Squelto);
    -
    -    TRIA_Invite(Horka);   // Invite Horka into this dialogue
    -    TRIA_Invite(Squelto); // Invite Squelto into this dialog
    -    TRIA_Start();         // Start the conversation
    -    // The hero and Arto do not have to/may not be invited. They are in dialogue anyway.
    -
    -    // Hero now talks to Arto (self = Arto, other = Hero)
    -    TRIA_Next(Arto);
    -
    -    DIAG_Reset();
    -
    -    AI_Output (self, other, "TRIA_TEST_00"); //Sorry hero, but you can't pass here.
    -
    -    // Hero now talks to Horka (self = Horka, other = Hero)
    -    TRIA_Next(Horka);
    -
    -    AI_Output (other, self, "TRIA_TEST_01"); //Why not?
    -
    -    AI_GotoNpc(self, other);
    -    AI_TurnToNpc(other, self);
    -
    -    AI_Output (self, other, "TRIA_TEST_02"); //The city has been closed.
    -
    -    // Hero looks around conspiratorially during the next sentence
    -    DIAG("Nervous", 1, 2);
    -
    -    AI_Output (other, self, "TRIA_TEST_03"); //I have some gold with me, can we trade?
    -
    -    // Hero should now move normally again
    -    DIAG_Reset();
    -
    -    // Start tracking shot
    -    TRIA_Cam("CAMERASTART");
    -
    -    // Hero now talks to Squelto (self = Squelto, other = Hero)
    -    TRIA_Next(Squelto);
    -
    -    AI_TurnToNpc(other, self);
    -
    -    DIAG("No", 0, 1);
    -    AI_Output (self, other, "TRIA_TEST_04"); //No. We are not open to bribery.
    -
    -    // Hero talks to Arto again (self = Arto, other = Hero)
    -    TRIA_Next(Arto);
    -
    -    // Hero should now articulate questioningly
    -    DIAG("NotSure", 0, 1);
    -
    -    AI_Output (other, self, "TRIA_TEST_05"); //Sure?
    -
    -    AI_TurnToNpc(other, self);
    -
    -    // tracking shot end
    -    TRIA_Cam("");
    -
    -    // Arto should react angrily
    -    DIAG("Angry", 0, 4);
    -
    -    AI_Output (self, other, "TRIA_TEST_06"); //I have to ask you to leave now
    -
    -    // Hero should now move normally again
    -    DIAG_Reset();
    -
    -    AI_Output (other, self, "TRIA_TEST_07"); //Well...
    -
    -    TRIA_Finish(); // End
    -};
    -

Note

In addition, here are still Dialoggestures used.

\ No newline at end of file diff --git a/zengin/scripts/extenders/lego/bars/index.html b/zengin/scripts/extenders/lego/bars/index.html deleted file mode 100644 index d9593db1bf..0000000000 --- a/zengin/scripts/extenders/lego/bars/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/zengin/scripts/extenders/lego/bloodsplats/index.html b/zengin/scripts/extenders/lego/bloodsplats/index.html deleted file mode 100644 index 07805ad05a..0000000000 --- a/zengin/scripts/extenders/lego/bloodsplats/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/zengin/scripts/extenders/lego/console_commands/index.html b/zengin/scripts/extenders/lego/console_commands/index.html deleted file mode 100644 index 1dec884d9e..0000000000 --- a/zengin/scripts/extenders/lego/console_commands/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/zengin/scripts/extenders/lego/dialoggestures/index.html b/zengin/scripts/extenders/lego/dialoggestures/index.html deleted file mode 100644 index f446c3350b..0000000000 --- a/zengin/scripts/extenders/lego/dialoggestures/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/zengin/scripts/extenders/lego/focusnames/index.html b/zengin/scripts/extenders/lego/focusnames/index.html deleted file mode 100644 index 565bdc88c9..0000000000 --- a/zengin/scripts/extenders/lego/focusnames/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/zengin/scripts/extenders/lego/frame_functions/index.html b/zengin/scripts/extenders/lego/frame_functions/index.html deleted file mode 100644 index 79d8a8e592..0000000000 --- a/zengin/scripts/extenders/lego/frame_functions/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/zengin/scripts/extenders/lego/gamestate/index.html b/zengin/scripts/extenders/lego/gamestate/index.html deleted file mode 100644 index 66a81fdd74..0000000000 --- a/zengin/scripts/extenders/lego/gamestate/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/zengin/scripts/extenders/lego/index.html b/zengin/scripts/extenders/lego/index.html deleted file mode 100644 index d0f792ae4a..0000000000 --- a/zengin/scripts/extenders/lego/index.html +++ /dev/null @@ -1,34 +0,0 @@ - LeGo - Gothic Modding Community
\ No newline at end of file diff --git a/zengin/scripts/extenders/lego/int64/index.html b/zengin/scripts/extenders/lego/int64/index.html deleted file mode 100644 index c45777f16c..0000000000 --- a/zengin/scripts/extenders/lego/int64/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/zengin/scripts/extenders/lego/item_helper/index.html b/zengin/scripts/extenders/lego/item_helper/index.html deleted file mode 100644 index 157ce75b3a..0000000000 --- a/zengin/scripts/extenders/lego/item_helper/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/zengin/scripts/extenders/lego/locals/index.html b/zengin/scripts/extenders/lego/locals/index.html deleted file mode 100644 index d871a56318..0000000000 --- a/zengin/scripts/extenders/lego/locals/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/zengin/scripts/extenders/lego/misc/index.html b/zengin/scripts/extenders/lego/misc/index.html deleted file mode 100644 index 38bec415d2..0000000000 --- a/zengin/scripts/extenders/lego/misc/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/zengin/scripts/extenders/lego/names/index.html b/zengin/scripts/extenders/lego/names/index.html deleted file mode 100644 index b6e6f05ae7..0000000000 --- a/zengin/scripts/extenders/lego/names/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/zengin/scripts/extenders/lego/random/index.html b/zengin/scripts/extenders/lego/random/index.html deleted file mode 100644 index 80cf3eadb4..0000000000 --- a/zengin/scripts/extenders/lego/random/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/zengin/scripts/extenders/lego/talents/index.html b/zengin/scripts/extenders/lego/talents/index.html deleted file mode 100644 index e1fa771490..0000000000 --- a/zengin/scripts/extenders/lego/talents/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/zengin/scripts/extenders/lego/timer/index.html b/zengin/scripts/extenders/lego/timer/index.html deleted file mode 100644 index 79f96d8e26..0000000000 --- a/zengin/scripts/extenders/lego/timer/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/zengin/scripts/extenders/lego/tools/LeGo_tools.d b/zengin/scripts/extenders/lego/tools/LeGo_tools.d deleted file mode 100644 index e0802d8232..0000000000 --- a/zengin/scripts/extenders/lego/tools/LeGo_tools.d +++ /dev/null @@ -1,2001 +0,0 @@ -// ========================================================= -// -// AI_Function -// -// ========================================================= - -/// Queues the `function` to be called with a delay in the AI queue of `slf`. -/// -/// @param slf NPC in whose AI queue the function is queued -/// @param function Name of the function to be queued -func void AI_Function(var C_NPC slf, var func function) {}; - -/// Queues the `function` with an integer parameter to be called with a delay in the AI queue of `slf`. -/// -/// @param slf NPC in whose AI queue the function is queued -/// @param function Name of the function to be queued -/// @param param Integer parameter for the function -func void AI_Function_I(var C_NPC slf, var func function, var int param) {}; - -/// Queues the `function` with an NPC instance parameter to be called with a delay in the AI queue of `slf`. -/// -/// @param slf NPC in whose AI queue the function is queued -/// @param function Name of the function to be queued -/// @param param NPC instance parameter for the function -func void AI_Function_N(var C_NPC slf, var func function, var int param) {}; - -/// Queues the `function` with a string parameter to be called with a delay in the AI queue of `slf`. -/// -/// @param slf NPC in whose AI queue the function is queued -/// @param function Name of the function to be queued -/// @param param String parameter for the function -func void AI_Function_S(var C_NPC slf, var func function, var string param) {}; - -/// Queues the `function` with two integer parameters to be called with a delay in the AI queue of `slf`. -/// -/// @param slf NPC in whose AI queue the function is queued -/// @param function Name of the function to be queued -/// @param param1 First integer parameter for the function -/// @param param2 Second integer parameter for the function -func void AI_Function_II(var C_NPC slf, var func function, var int param1, var int param2) {}; - -/// Queues the `function` with two NPC instance parameters to be called with a delay in the AI queue of `slf`. -/// -/// @param slf NPC in whose AI queue the function is queued -/// @param function Name of the function to be queued -/// @param param1 First NPC instance parameter for the function -/// @param param2 Second NPC instance parameter for the function -func void AI_Function_NN(var C_NPC slf, var func function, var int param1, var int param2) {}; - -/// Queues the `function` with two string parameters to be called with a delay in the AI queue of `slf`. -/// -/// @param slf NPC in whose AI queue the function is queued -/// @param function Name of the function to be queued -/// @param param1 First string parameter for the function -/// @param param2 Second string parameter for the function -func void AI_Function_SS(var C_NPC slf, var func function, var string param1, var string param2) {}; - -/// Queues the `function` with an integer and a string parameter to be called with a delay in the AI queue of `slf`. -/// -/// @param slf NPC in whose AI queue the function is queued -/// @param function Name of the function to be queued -/// @param param1 Integer parameter for the function -/// @param param2 String parameter for the function -func void AI_Function_IS(var C_NPC slf, var func function, var int param1, var string param2) {}; - -/// Queues the `function` with a string and an integer parameter to be called with a delay in the AI queue of `slf`. -/// -/// @param slf NPC in whose AI queue the function is queued -/// @param function Name of the function to be queued -/// @param param1 String parameter for the function -/// @param param2 Integer parameter for the function -func void AI_Function_SI(var C_NPC slf, var func function, var string param1, var int param2) {}; - -/// Queues the `function` with an NPC instance and a string parameter to be called with a delay in the AI queue of `slf`. -/// -/// @param slf NPC in whose AI queue the function is queued -/// @param function Name of the function to be queued -/// @param param1 NPC instance parameter for the function -/// @param param2 String parameter for the function -func void AI_Function_NS(var C_NPC slf, var func function, var int param1, var string param2) {}; - -/// Queues the `function` with a string and an NPC instance parameter to be called with a delay in the AI queue of `slf`. -/// -/// @param slf NPC in whose AI queue the function is queued -/// @param function Name of the function to be queued -/// @param param1 String parameter for the function -/// @param param2 NPC instance parameter for the function -func void AI_Function_SN(var C_NPC slf, var func function, var string param1, var int param2) {}; - -/// Queues the `function` with an integer and an NPC instance parameter to be called with a delay in the AI queue of `slf`. -/// -/// @param slf NPC in whose AI queue the function is queued -/// @param function Name of the function to be queued -/// @param param1 Integer parameter for the function -/// @param param2 NPC instance parameter for the function -func void AI_Function_IN(var C_NPC slf, var func function, var int param1, var int param2) {}; - -/// Queues the `function` with an NPC instance and an integer parameter to be called with a delay in the AI queue of `slf`. -/// -/// @param slf NPC in whose AI queue the function is queued -/// @param function Name of the function to be queued -/// @param param1 NPC instance parameter for the function -/// @param param2 Integer parameter for the function -func void AI_Function_NI(var C_NPC slf, var func function, var int param1, var int param2) {}; - -// ========================================================= -// -// BinaryMachines -// -// ========================================================= - -/// Creates the file with the specified `file` name and opens a stream. Fails if a stream is already open. -/// -/// @param file Name of the created file -/// @return Returns TRUE if the file is successfully created and initialized; otherwise, FALSE. -func int BW_NewFile(var string file) {}; - -/// Closes the current write stream. -func void BW_Close() {}; - -/// Writes `length` bytes from `data` to the stream, up to a maximum of 4 bytes. -/// -/// @param data Value of bytes -/// @param length Number of bytes -func void BW(var int data, var int length) {}; - -/// Writes 4 bytes from `data` to the stream, equivalent to `BW(data, 4)`. -/// -/// @param data Integer value to write -func void BW_Int(var int data) {}; - -/// Writes the first character from `data` to the stream, equivalent to `BW(Str_GetCharAt(data, 0), 1)`. -/// -/// @param data Char to write -func void BW_Char(var string data) {}; - -/// Writes `data` terminated with '\0' to the stream. -/// -/// @param data String to write -func void BW_String(var string data) {}; - -/// Writes a byte from `data` to the stream, equivalent to `BW(data, 1)`. -/// -/// @param data Byte value to write -func void BW_Byte(var int data) {}; - -/// Writes `length` of bytes from the pointer `dataPtr` to the stream. -/// -/// @param dataPtr Pointer to the data to write -/// @param length Number of bytes -func void BW_Bytes(var int dataPtr, var int length) {}; - -/// Writes the string `data` to the stream without terminating it, making it unreadable. -/// -/// @param data Text to write -func void BW_Text(var string data) {}; - -/// Writes a paragraph to the stream. -func void BW_NextLine() {}; - -/// Opens the file with the specified `file` name and opens a stream. Fails if a stream is already open. -/// -/// @param file File to be opened -/// @return Returns TRUE if the file is successfully opened and initialized; otherwise, FALSE. -func int BR_OpenFile(var string file) {}; - -/// Closes the current read stream. -func void BR_Close() {}; - -/// Reads bytes from the stream, up to a maximum of 4 bytes. -/// -/// @param length Number of bytes to read -/// @return Returns the value of read bytes -func int BR(var int length) {}; - -/// Reads 4 bytes from the stream, equivalent to `BR(4)`. -/// -/// @return Returns the read integer -func int BR_Int() {}; - -/// Reads a character from the stream, equivalent to `BR(1)`. -/// -/// @return Returns the read character as a string -func string BR_Char() {}; - -/// Reads a string terminated by '\0' from the stream. -/// -/// @return Returns the read string -func string BR_String() {}; - -/// Reads a byte from the stream. -/// -/// @return Returns the read byte -func int BR_Byte() {}; - -/// Reads bytes from the stream. -/// -/// @param length Number of bytes to read -/// @return Returns a pointer to the read bytes -func int BR_Bytes(var int length) {}; - -/// Reads a line from the stream. -/// -/// @return Returns the read line -func string BR_TextLine() {}; - -/// Reads a string of the given `length` from the stream. -/// -/// @param length Number of characters to read -/// @return Returns the read string -func string BR_Text(var int length) {}; - -/// Changes the read position to the next paragraph created with `BW_NextLine`. -func void BR_NextLine() {}; - -// ========================================================= -// -// EventHandler -// -// ========================================================= - -/// Creates a new event and returns a handle to it. -/// -/// @return The function returns a new PermMem handle to an event. -func int Event_Create() {}; - -/// Alias to PermMem `delete`. Cleans up the handle. -/// -/// @param event Handle returned from `Event_Create` -func void Event_Delete(var int event) {}; - -/// Checks whether the event is "empty," i.e., nothing will happen after its execution. -/// -/// @param event Handle returned from `Event_Create` -/// @return The function returns TRUE if the event is empty; otherwise, FALSE. -func int Event_Empty(var int event) {}; - -/// Checks if `function` is added to the event. -/// -/// @param event Handle returned from `Event_Create` -/// @param function Checked function -/// @return The function returns TRUE if the function is added; otherwise, FALSE. -func int Event_Has(var int event, var func function) {}; - -/// Adds an event handler function. The handler is called after running `Event_Execute`. -/// -/// @param event Handle returned from `Event_Create` -/// @param function Function to be added -func void Event_Add(var int event, var func function) {}; - -/// `Event_Add` but checks if the handler function is already added to prevent duplicates. -/// -/// @param event Handle returned from `Event_Create` -/// @param function Function to be added -func void Event_AddOnce(var int event, var func function) {}; - -/// Removes the event handler `function` from the event. -/// -/// @param event Handle returned from `Event_Create` -/// @param function Function to be removed -func void Event_Remove(var int event, var func function) {}; - -/// Core of the package. Calls all functions registered via `Event_Add` and `Event_AddOnce`. -/// -/// @param event Handle returned from `Event_Create` -/// @param data Int parameter passed to all executed functions -func void Event_Execute(var int event, var int data) {}; - -/// Creates a new event and returns a pointer to it. -/// -/// @return The function returns a new PermMem pointer to an event. -func int EventPtr_Create() {}; - -/// Alias to PermMem `free`. Cleans up the pointer. -/// -/// @param eventPtr Pointer returned from `EventPtr_Create` -func void EventPtr_Delete(var int eventPtr) {}; - -/// Checks whether the event is "empty," i.e., nothing will happen after its execution. -/// -/// @param eventPtr Pointer returned from `EventPtr_Create` -/// @return The function returns TRUE if empty; otherwise, FALSE. -func int EventPtr_Empty(var int eventPtr) {}; - -/// Checks if `function` is added to an event. -/// -/// @param eventPtr Pointer returned from `EventPtr_Create` -/// @param function Checked function -/// @return The function returns TRUE if the function is added; otherwise, FALSE. -func int EventPtr_Has(var int eventPtr, var func function) {}; - -/// `EventPtr_Has` but with function ID instead of a pointer. Used mainly internally. -/// -/// @param eventPtr Pointer returned from `EventPtr_Create` -/// @param id ID of the checked function -/// @return The function returns TRUE if the function is added; otherwise, FALSE. -func int EventPtr_HasI(var int eventPtr, var int id) {}; - -/// Adds an event handler function. The handler is called after running `EventPtr_Execute`. -/// -/// @param eventPtr Pointer returned from `EventPtr_Create` -/// @param function Function to be added -func void EventPtr_Add(var int eventPtr, var func function) {}; - -/// `EventPtr_Add` but checks if the handler function is already added to prevent duplicates. -/// -/// @param eventPtr Pointer returned from `EventPtr_Create` -/// @param function Function to be added -func void EventPtr_AddOnce(var int eventPtr, var func function) {}; - -/// `EventPtr_AddI` but checks if the handler function is already added to prevent duplicates. -/// -/// @param eventPtr Pointer returned from `EventPtr_Create` -/// @param id ID of function to be added -func void EventPtr_AddOnceI(var int eventPtr, var int id) {}; - -/// Removes a function from the event's call list. -/// -/// @param eventPtr Pointer returned from `EventPtr_Create` -/// @param function Function to be removed -func void EventPtr_Remove(var int eventPtr, var func function) {}; - -/// `EventPtr_RemoveI` but with function ID instead of a pointer. Used mainly internally. -/// -/// @param eventPtr Pointer returned from `EventPtr_Create` -/// @param id ID of function to be removed -func void EventPtr_RemoveI(var int eventPtr, var int id) {}; - -/// Core of the package. Calls all functions registered via `EventPtr_Add` and `EventPtr_AddOnce`. -/// -/// @param eventPtr Pointer returned from `EventPtr_Create` -/// @param data Int parameter passed to all executed functions -func void EventPtr_Execute(var int eventPtr, var int data) {}; - -// ========================================================= -// -// FrameFunctions -// -// ========================================================= - -/// Adds the Daedalus function FF_Apply to the running FrameFunctions list. FF_Apply is called each frame. -/// -/// @param function Name of the function -func void FF_Apply(var func function) {}; - -/// Adds the Daedalus function FF_ApplyGT to the running FrameFunctions list. FF_ApplyGT is called every frame except when the game is paused. -/// -/// @param function Name of the function -func void FF_ApplyGT(var func function) {}; - -/// Adds the Daedalus function FF_ApplyData to the running FrameFunctions list. The integer parameter data is passed to the function FF_ApplyData. -/// -/// @param function Name of the function. -/// @param data Value passed to the function as a parameter -func void FF_ApplyData(var func function, var int data) {}; - -/// Adds the Daedalus function FF_ApplyExt to the running FrameFunctions list. The function FF_ApplyExt is called every delay milliseconds, and it runs only cycles number of times. -/// -/// @param function Name of the function -/// @param delay Delay between calls in milliseconds (0 = every frame) -/// @param cycles How many times should the function be called (-1 = endless) -func void FF_ApplyExt(var func function, var int delay, var int cycles) {}; - -/// Adds the Daedalus function FF_ApplyExtGT to the running FrameFunctions list. The function FF_ApplyExtGT is called every delay milliseconds, and it runs only cycles number of times. Gets called only when the game is not paused. -/// -/// @param function Name of the function -/// @param delay Delay between calls in milliseconds (0 = every frame) -/// @param cycles How many times should the function be called (-1 = endless) -func void FF_ApplyExtGT(var func function, var int delay, var int cycles) {}; - -/// Adds the Daedalus function FF_ApplyExtData to the running FrameFunctions list. The function FF_ApplyExtData is called every delay milliseconds, and it runs only cycles number of times. The integer parameter data is passed to the function FF_ApplyExtData. -/// -/// @param function Name of the function. -/// @param delay Delay between calls in milliseconds (0 = every frame) -/// @param cycles How many times should the function be called (-1 = endless) -/// @param data Value passed to the function as a parameter -func void FF_ApplyExtData(var func function, var int delay, var int cycles, var int data) {}; - -/// Adds the Daedalus function FF_ApplyExtDataGT to the running FrameFunctions list. The function FF_ApplyExtDataGT is called every delay milliseconds, and it runs only cycles number of times. The integer parameter data is passed to the function FF_ApplyExtDataGT. Gets called only when the game is not paused. -/// -/// @param function Name of the function. -/// @param delay Delay between calls in milliseconds (0 = every frame) -/// @param cycles How many times should the function be called (-1 = endless) -/// @param data Value passed to the function as a parameter -func void FF_ApplyExtDataGT(var func function, var int delay, var int cycles, var int data) {}; - -/// Alias to FF_Apply, which only adds the function once, even after multiple calls. -/// -/// @param function Name of the function -func void FF_ApplyOnce(var func function) {}; - -/// Alias to FF_ApplyGT, which only adds the function once, even after multiple calls. Loop doesn't run if the game is paused. -/// -/// @param function Name of the function. -func void FF_ApplyOnceGT(var func function) {}; - -/// Alias to FF_ApplyData, which only adds the function with the specified parameter once, even after multiple calls. -/// -/// @param function Name of the function. -/// @param data Value passed to the function as a parameter -func void FF_ApplyOnceData(var func function, var int data) {}; - -/// Alias to FF_ApplyExt, which adds the function only once, after repeated calls. -/// -/// @param function Name of the function -/// @param delay Delay between calls in milliseconds (0 = every frame) -/// @param cycles How many times should the function be called (-1 = endless) -func void FF_ApplyOnceExt(var func function, var int delay, var int cycles) {}; - -/// Alias to FF_ApplyExtGT, which adds the function only once after repeated calls. Loop doesn't run if the game is paused. -/// -/// @param function Name of the function -/// @param delay Delay between calls in milliseconds (0 = every frame) -/// @param cycles How many times should the function be called (-1 = endless) -func void FF_ApplyOnceExtGT(var func function, var int delay, var int cycles) {}; - -/// Alias to FF_ApplyExtData, which adds the function with the specified parameter only once, after repeated calls. -/// -/// @param function Name of the function -/// @param delay Delay between calls in milliseconds (0 = every frame) -/// @param cycles How many times should the function be called (-1 = endless) -/// @param data Value passed to the function as a parameter -func void FF_ApplyOnceExtData(var func function, var int delay, var int cycles, var int data) {}; - -/// Checks whether the function is active. -/// -/// @param function Name of the function -/// @return The function returns TRUE if the function is active; otherwise, FALSE. -func int FF_Active(var func function) {}; - -/// Checks whether the function with the specified data is active. -/// -/// @param function Name of the function -/// @param data Value previously passed to the function -/// @return The function returns TRUE if the function is active; otherwise, FALSE. -func int FF_ActiveData(var func function, var int data) {}; - -/// Stops a specific FrameFunction. -/// -/// @param function Name of the stopped function -func void FF_Remove(var func function) {}; - -/// Stops all instances of a specific FrameFunction. -/// -/// @param function Name of the stopped function -func void FF_RemoveAll(var func function) {}; - -/// Stops a specific FrameFunction, with the specified value (see FF_ApplyExtData). -/// -/// @param function Name of the stopped function -/// @param data Value previously passed to the function as a parameter -func void FF_RemoveData(var func function, var int data) {}; - -// ========================================================= -// -// Hashtables -// -// ========================================================= - -/// Generates a hashtable of the specified size. -/// -/// @param size Size of the hashtable to be created -/// @return A handle to the created hashtable. -func int HT_CreateSized(var int size) {}; - -/// Generates a standard size hashtable. -/// -/// @return A handle to the created hashtable. -func int HT_Create() {}; - -/// Inserts a value into the Hashtable. -/// -/// @param handle Handle of a hashtable -/// @param val The value to be inserted -/// @param key The key associated with the value -func void HT_Insert(var int handle, var int val, var int key) {}; - -/// Changes the size of the hashtable (usually not necessary as it happens automatically). -/// -/// @param handle Handle of a hashtable -/// @param size The new size of the hashtable -func void HT_Resize(var int handle, var int size) {}; - -/// Reads a value from the hashtable. -/// -/// @param handle Handle of a hashtable -/// @param key The key whose value is to be read -/// @return The value associated with the key. -func int HT_Get(var int handle, var int key) {}; - -/// Checks if the key already exists in the hashtable. -/// -/// @param handle Handle of a hashtable -/// @param key The key to be checked -/// @return TRUE if the key exists, FALSE otherwise. -func int HT_Has(var int handle, var int key) {}; - -/// Removes a key from the hashtable. -/// -/// @param handle Handle of a hashtable -/// @param key The key to be removed -func void HT_Remove(var int handle, var int key) {}; - -/// Changes the value of a key already existing in the hashtable. -/// -/// @param handle Handle of a hashtable -/// @param val The new value -/// @param key The key whose value is to be changed -func void HT_Change(var int handle, var int val, var int key) {}; - -/// Inserts a value into the Hashtable, or changes the value if the key already exists in the hashtable. -/// -/// @param handle Handle of a hashtable -/// @param val The new value -/// @param key The key whose value is to be changed or associated with the value. -func void HT_InsertOrChange(var int handle, var int val, var int key) {}; - -/// Returns the number of entries in a hashtable. -/// -/// @param handle Handle of a hashtable -/// @return The number of entries in the hashtable. -func int HT_GetNumber(var int handle) {}; - -/// Performs a function for each value pair in the hashtable. -/// -/// @param handle Handle of a hashtable -/// @param fnc A function with signature void (int key, int val) -func void HT_ForEach(var int handle, var func fnc) {}; - -/// Deletes the hashtable. -/// -/// @param handle The handle of the hashtable to be deleted -func void HT_Destroy(var int handle) {}; - -// ========================================================= -// -// HookDaedalus -// -// ========================================================= - -/// Hooks the function. -/// -/// @param hooked Hooked function -/// @param hook Hook function -func void HookDaedalusFunc(var func hooked, var func hook) {}; - -/// Alias to the HookDaedalusFunc function. -/// -/// @param hooked Hooked function -/// @param hook Hook function -func void HookDaedalusFuncF(var func hooked, var func hook) {}; - -/// Hooks a function by its ID. -/// -/// @param hookedID ID of hooked function -/// @param hookID ID of hook function -func void HookDaedalusFuncI(var int hookedID, var int hookID) {}; - -/// Hooks a function by its name. -/// -/// @param hookedName Name of hooked function -/// @param hookName Name of hook function -func void HookDaedalusFuncS(var string hookedName, var string hookName) {}; - -/// Checks whether a function is already hooking another. -/// -/// @param funcID Symbol index of a hook function -/// @return TRUE if the function is already hooking another, FALSE otherwise. -func int IsHookD(var int funcID) {}; - -/// Continues the program run with the original function. -func void ContinueCall() {}; - -/// Passes an integer as an argument to the original function. Must be called before ContinueCall. -/// -/// @param i Integer argument to forward -func void PassArgumentI(var int i) {}; - -/// Passes a string as an argument to the original function. Must be called before ContinueCall. -/// -/// @param s String argument to forward -func void PassArgumentS(var string s) {}; - -/// Passes an instance as an argument to the original function. Must be called before ContinueCall. -/// -/// @param n Instance argument to forward -func void PassArgumentN(var instance n) {}; - -// ========================================================= -// -// HookEngine -// -// ========================================================= - -/// Attaches a function to an engine function address. -/// -/// @param address Address of an engine function to which the function should be attached. -/// @param oldInstr The length in bytes of the instruction to be found at `address`, at least 5 bytes. Can be seen in IDA. -/// @param function Name of Daedalus function to be called. -func void HookEngine(var int address, var int oldInstr, var string function) {}; - -/// Alias to the HookEngine function. -/// -/// @param address Address of an engine function to which the function should be attached. -/// @param oldInstr The length in bytes of the instruction to be found at `address`, at least 5 bytes. Can be seen in IDA. -/// @param function Name of Daedalus function to be called. -func void HookEngineS(var int address, var int oldInstr, var string function) {}; - -/// Alias to HookEngine with funcID. -/// -/// @param address Address of an engine function to which the function should be attached. -/// @param oldInstr The length in bytes of the instruction to be found at `address`, at least 5 bytes. Can be seen in IDA. -/// @param funcID ID of Daedalus function to be called. -func void HookEngineI(var int address, var int oldInstr, var int funcID) {}; - -/// Alias to HookEngine with func parameter. -/// -/// @param address Address of an engine function to which the function should be attached. -/// @param oldInstr The length in bytes of the instruction to be found at `address`, at least 5 bytes. Can be seen in IDA. -/// @param function Daedalus function to be called. -func void HookEngineF(var int address, var int oldInstr, var func function) {}; - -/// Checks if a hook is already present at a given address. -/// -/// @param address Address of an engine function. -/// @return TRUE if the hook already exists at the address, FALSE otherwise. -func var int IsHooked(var int address) {}; - -/// Checks if a hook with a certain function is already present at an address. -/// -/// @param address Address of an engine function. -/// @param function Name of a function. -/// @return TRUE if the hook already exists at the address, FALSE otherwise. -func var int IsHook(var int address, var string function) {}; - -/// Alias to IsHook with funcID as parameter. -/// -/// @param address Address of an engine function. -/// @param funcID ID of a function. -/// @return TRUE if the hook already exists at the address, FALSE otherwise. -func var int IsHookI(var int address, var int funcID) {}; - -/// Alias to IsHook with function as parameter. -/// -/// @param address Address of an engine function. -/// @param function Daedalus function. -/// @return TRUE if the hook already exists at the address, FALSE otherwise. -func var int IsHookF(var int address, var func function) {}; - -/// Removes a function from a hook so that it is no longer called. -/// -/// @param address Address of an engine function to which the function should be attached. -/// @param oldInstr The length in bytes of the instruction to be found at `address`, at least 5 bytes. Can be seen in IDA. -/// @param function Name of Daedalus function that should no longer be called. -func void RemoveHook(var int address, var int oldInstr, var string function) {}; - -/// Alias to RemoveHook with funcID. -/// -/// @param address Address of an engine function to which the function should be attached. -/// @param oldInstr The length in bytes of the instruction to be found at `address`, at least 5 bytes. Can be seen in IDA. -/// @param funcID ID of Daedalus function that should no longer be called. -func void RemoveHookI(var int address, var int oldInstr, var int funcID) {}; - -/// Alias for RemoveHook with func parameter. -/// -/// @param address Address of an engine function to which the function should be attached. -/// @param oldInstr The length in bytes of the instruction to be found at `address`, at least 5 bytes. Can be seen in IDA. -/// @param function Daedalus function that should no longer be called. -func void RemoveHookF(var int address, var int oldInstr, var func function) {}; - -/// Replaces an engine function with a Daedalus function. -/// -/// @param address Address of the engine function to be replaced. -/// @param thiscall_numparams Number of parameters passed to the engine function, if it is a stdcall or thiscall (otherwise 0). -/// @param replaceFunc Name of a Daedalus function to be called instead. -func void ReplaceEngineFunc(var int address, var int thiscall_numparams, var string replaceFunc) {}; - -/// Alias to ReplaceEngineFunc with funcID. -/// -/// @param address Address of the engine function to be replaced. -/// @param thiscall_numparams Number of parameters passed to the engine function, if it is a stdcall or thiscall (otherwise 0). -/// @param funcID ID of a Daedalus function to be called instead. -func void ReplaceEngineFuncI(var int address, var int thiscall_numparams, var int funcID) {}; - -/// Alias to ReplaceEngineFunc with func parameter. -/// -/// @param address Address of the engine function to be replaced. -/// @param thiscall_numparams Number of parameters passed to the engine function, if it is a stdcall or thiscall (otherwise 0). -/// @param function Daedalus function to be called instead. -func void ReplaceEngineFuncF(var int address, var int thiscall_numparams, var func function) {}; - -/// Makes sure that an engine function is simply skipped. This is very delicate and will not always work so easily. -/// -/// @param address Address of the engine function to be skipped. -/// @param thiscall_numparams Number of parameters passed to the engine function, if it is a stdcall or thiscall (otherwise 0). -func void DisableEngineFunc(var int address, var int thiscall_numparams) {}; - -/// Simple function to replace `return FALSE` in hook. -func void Hook_ReturnFalse() {}; - -/// Simple function to replace `return TRUE` in hook. -func void Hook_ReturnTrue() {}; - -// ========================================================= -// -// Int64 -// -// ========================================================= - -/// Writes `lo` and `hi` in one place (dest). Makes Int64, `hi` has to be `-1` for negative 32bit `lo`. -/// -/// @param dest A pointer to an Int64 object or just 8 bytes of free memory. -/// @param hi High part of integer. -/// @param lo Low part of integer. -func void mk64(var int dest, var int hi, var int lo) {}; - -/// Negates the integer: `*dest <- -(*dest)` -/// -/// @param dest A pointer to an Int64 object or just 8 bytes of free memory. -func void neg64(var int dest) {}; - -/// Adds `src` to `dest`: `*dest <- *dest + *src` -/// -/// @param dest A pointer to an Int64 object or just 8 bytes of free memory. Will be changed. -/// @param src A pointer to an Int64 object. Will not change. -func void add64(var int dest, var int src) {}; - -/// Subtracts `src` from `dest`: `*dest <- *dest - *src` -/// -/// @param dest A pointer to an Int64 object or just 8 bytes of free memory. Will be changed. -/// @param src A pointer to an Int64 object. Will not change. -func void sub64(var int dest, var int src) {}; - -/// Multiplies `dest` by `src`: `*dest <- (*dest) * (*src)` -/// -/// @param dest A pointer to an Int64 object or just 8 bytes of free memory. Will be changed. -/// @param src A pointer to an Int64 object. Will not change. -func void mul64(var int dest, var int src) {}; - -/// Divides `dest` by `src`: `*dest <- *dest / *src` -/// -/// @param dest A pointer to an Int64 object or just 8 bytes of free memory. Will be changed. -/// @param src A pointer to an Int64 object. Will not change. -func void div64(var int dest, var int src) {}; - -// ========================================================= -// -// Interface -// -// ========================================================= - -/// Better alternative for MEM_GetSysTime() from Ikarus. -/// -/// @return The function returns elapsed time since game (system) startup. -func int sysGetTime() {}; - -/// Generates a full zColor. -/// -/// @param r Red channel value (0..255) -/// @param g Green channel value (0..255) -/// @param b Blue channel value (0..255) -/// @param a Alpha (0..255, 0 = invisible) -/// -/// @return The function returns a zColor object. -func int RGBA(var int r, var int g, var int b, var int a) {}; - -/// Overrides the alpha value of a given zColor. -/// -/// @param zCol zColor to modify -/// @param a New alpha value -/// -/// @return The function returns a modified zColor object. -func int ChangeAlpha(var int zCol, var int a) {}; - -/// Returns the alpha value of a given zColor. -/// -/// @param zCol zColor to get alpha from -func int GetAlpha(var int zCol) {}; - -/// Creates a new zCViewText on the screen with PermMem that can be freely edited. -/// -/// @param text The text of the zCViewText -/// @param font Font of text -/// -/// @return The function returns a handle to zCViewText. -func int Print_CreateText(var string text, var string font) {}; - -/// Print_CreateText but returns a pointer to zCViewText instead of a handle. -/// -/// @param text The text of the zCViewText -/// @param font Font of text -/// -/// @return The function returns a pointer to zCViewText. -func int Print_CreateTextPtr(var string text, var string font) {}; - -/// Print_CreateTextPtr but with an additional parameter to choose the color of text. -/// -/// @param text The text of the zCViewText -/// @param font Font of text -/// @param color zColor, e.g., generated with RGBA function -/// -/// @return The function returns a pointer to zCViewText. -func int Print_CreateTextPtrColored(var string text, var string font, var int color) {}; - -/// Returns zCViewText instance from handle. -/// -/// @param hndl Handle to zCViewText -func zCViewText Print_GetText(var int hndl) {}; - -/// Returns zCViewText pointer from handle. -/// -/// @param hndl Handle to zCViewText -func int Print_GetTextPtr(var int hndl) {}; - -/// Removes a zCViewText from the screen. -/// -/// @param hndl Handle to zCViewText (from Print_CreateText or Print_Ext) -func void Print_DeleteText(var int hndl) {}; - -/// Changes the alpha value of a given zCViewText. -/// -/// @param hndl Handle to zCViewText -/// @param a New alpha value -func void Print_SetAlpha(var int hndl, var int a) {}; - -/// Print_SetAlpha but with a pointer to zCViewText instead of a handle. -/// -/// @param ptr Pointer to zCViewText -/// @param a New alpha value -func void PrintPtr_SetAlpha(var int ptr, var int a) {}; - -/// Writes the current resolution to the Print_Screen array and the current aspect ratio to Print_Ratio variable. -func void Print_GetScreenSize() {}; - -/// Converts pixel position to a virtual position. -/// -/// @param pxl Pixel position to convert -/// @param dim PS_X or PS_Y (see Print_Screen) -/// -/// @return The function returns a virtual position of a given pixel position. -func int Print_ToVirtual(var int pxl, var int dim) {}; - -/// Print_ToVirtualF but returns Ikarus float value instead of an integer. -/// -/// @param pxl Pixel position to convert -/// @param dim PS_X or PS_Y (see Print_Screen) -/// -/// @return The function returns a virtual position of a given pixel position as an Ikarus float. -func int Print_ToVirtualF(var int pxl, var int dim) {}; - -/// Converts virtual position to a pixel position. -/// -/// @param vrt Virtual position to convert -/// @param dim PS_X or PS_Y (see Print_Screen) -/// -/// @return The function returns a pixel position of a given virtual position. -func int Print_ToPixel(var int vrt, var int dim) {}; - -/// Print_ToPixelF but returns Ikarus float value instead of an integer. -/// -/// @param vrt Virtual position to convert -/// @param dim PS_X or PS_Y (see Print_Screen) -/// -/// @return The function returns a pixel position of a given virtual position as an Ikarus float. -func int Print_ToPixelF(var int vrt, var int dim) {}; - -/// Gets the size in the specified dimension ratioed by the screen. -/// -/// @param size Size to convert -/// @param dim PS_X or PS_Y (see Print_Screen) -/// -/// @return The function returns size correctly calculated to the ratio. -func int Print_ToRatio(var int size, var int dim) {}; - -/// Converts angle in degrees to radians. -/// -/// @param angle Angle in degrees -/// -/// @return The function returns a calculated angle in radians. -func int Print_ToRadian(var int angle) {}; - -/// Converts angle in radians to degrees. -/// -/// @param angle Angle in radians -/// -/// @return The function returns a calculated angle in degrees. -func int Print_ToDegree(var int angle) {}; - -/// Returns a pointer to a zCFont by its name. -/// -/// @param font Name of font -func int Print_GetFontPtr(var string font) {}; - -/// Returns a name of a zCFont from its pointer. -/// -/// @param fontPtr Pointer to font -func string Print_GetFontName(var int fontPtr) {}; - -/// Returns the width of a string in pixels. -/// -/// @param s Measured string -/// @param font Name of font -/// -/// @return The function returns the width of the string in pixels. -func int Print_GetStringWidth(var string s, var string font) {}; - -/// Print_GetStringWidthPtr but with a zCFont pointer instead of a name. -/// -/// @param s Measured string -/// @param font zCFont pointer -/// -/// @return The function returns the width of the string in pixels. -func int Print_GetStringWidthPtr(var string s, var int font) {}; - -/// Returns the height of a string in pixels. -/// -/// @param font Name of font -/// -/// @return The function returns the height of a string in pixels. -func int Print_GetFontHeight(var string font) {}; - -/// Like the external PrintScreen, writes a text on the screen, but with more options. -/// -/// @param x X coordinate on the screen (virtual) -/// @param y Y coordinate on the screen (virtual) -/// @param text Displayed text -/// @param font Name of font -/// @param color zColor, e.g., generated with RGBA function -/// @param time Display time in milliseconds (-1 = permanent) -/// -/// @return If time == -1, a valid handle is returned. If time != -1, the print is only volatile and no handle is returned. -func int Print_Ext(var int x, var int y, var string text, var string font, var int color, var int time) {}; - -/// Print_ExtPxl but with pixel coordinates instead of virtual. -/// -/// @param x X coordinate on the screen (pixel) -/// @param y Y coordinate on the screen (pixel) -/// @param text Displayed text -/// @param font Name of font -/// @param color zColor, e.g., generated with RGBA function -/// @param time Display time in milliseconds (-1 = permanent) -/// -/// @return If time == -1, a valid handle is returned. If time != -1, the print is only volatile and no handle is returned. -func int Print_ExtPxl(var int x, var int y, var string text, var string font, var int color, var int time) {}; - -/// Returns the longest line from text as a string, using the default line separator tilde ~. -/// -/// @param text Measured text -/// @param font Name of font -/// -/// @return The function returns the longest line from text as a string. -func string Print_LongestLine(var string text, var string font) {}; - -/// Returns the longest line from text as a string, but you specify a new line separator. -/// -/// @param text Measured text -/// @param font Name of font -/// @param separator New line separator -/// -/// @return The function returns the longest line from text as a string. -func string Print_LongestLineExt(var string text, var string font, var string separator) {}; - -/// Returns the longest line width in pixels, using the default line separator tilde ~. -/// -/// @param text Measured text -/// @param font Name of font -/// -/// @return The function returns the longest line width in pixels. -func int Print_LongestLineLength(var string text, var string font) {}; - -/// Returns the longest line width in pixels, but allows you to specify a new line separator. -/// -/// @param text Measured text -/// @param font Name of font -/// @param separator New line separator -/// -/// @return The function returns the longest line width in pixels. -func int Print_LongestLineLengthExt(var string text, var string font, var string separator) {}; - -/// Creates a text field (view with text) using virtual coordinates. -/// -/// @param x X coordinate (virtual) -/// @param y Y coordinate (virtual) -/// @param text Text to be printed -/// @param font Name of font -/// @param height A specific line height -/// -/// @return The function returns a text field pointer. Look at the Print_TextField return value to see an example. -func int Print_TextField(var int x, var int y, var string text, var string font, var int height) {}; - -/// Print_TextFieldPxl but with pixel coordinates. -/// -/// @param x X coordinate (pixel) -/// @param y Y coordinate (pixel) -/// @param text Text to be printed -/// @param font Name of font -/// -/// @return The function returns a text field pointer. Look at the Print_TextField return value to see an example. -func int Print_TextFieldPxl(var int x, var int y, var string text, var string font) {}; - -/// Print_TextFieldColored but you specify the color of the text. -/// -/// @param x X coordinate (virtual) -/// @param y Y coordinate (virtual) -/// @param text Text to be printed -/// @param font Name of font -/// @param height A specific line height -/// @param color zColor, e.g., generated with RGBA function -/// -/// @return The function returns a text field pointer. Look at the Print_TextField return value to see an example. -func int Print_TextFieldColored(var int x, var int y, var string text, var string font, var int height, var int color) {}; - -/// Same function as the external Print, but with smooth animations. The effect can be changed as desired with the user constants. -/// -/// @param txt Printed text -func void PrintS(var string txt) {}; - -/// PrintS but with an additional parameter to choose the color of the text. -/// -/// @param txt Printed text -/// @param color zColor, e.g., generated with RGBA function -func void PrintS_Ext(var string txt, var int color) {}; - -/// Version of PrintS that enqueues in the given NPC's AI queue. -/// -/// @param slf NPC to whose AI queue the function is enqueued -/// @param txt Printed text -func void AI_PrintS(var c_npc slf, var string txt) {}; - -/// Version of PrintS_Ext that enqueues in the given NPC's AI queue. -/// -/// @param slf NPC to whose AI queue the function is enqueued -/// @param txt Printed text -/// @param color zColor, e.g., generated with RGBA function -func void AI_PrintS_Ext(var c_npc slf, var string txt, var int color) {}; - -// ========================================================= -// -// ItemHelper -// -// ========================================================= - -/// Gets an oCItem pointer from a C_ITEM instance. -/// -/// @param instance C_ITEM instance to get the pointer of -/// -/// @return The function returns an oCItem pointer of the C_ITEM instance. -func int ITM_GetPtr(var int instance) {}; - -// ========================================================= -// -// List -// -// ========================================================= - -/// Creates a new list with an initial value. -/// -/// @param data The value of the first list element. -/// -/// @return The function returns a pointer to the created list. -func int List_Create(var int data) {}; - -/// Appends a value to the end of the list. -/// -/// @param list The list to which the value is appended. -/// @param data The value to be appended. -func void List_Add(var int list, var int data) {}; - -/// Adds a value before the first element of the list. -/// -/// @param list The list to which the value is added. -/// @param data The value to be added. -func void List_AddFront(var int list, var int data) {}; - -/// Inserts a value between two list elements. -/// -/// @param list The list in which the value is inserted. -/// @param offset The number of the list element after which the value is inserted. -/// @param data The value to be inserted. -func void List_AddOffset(var int list, var int offset, var int data) {}; - -/// Sets a list element to a specific value. -/// -/// @param node Pointer to the list element. -/// @param data The value to be written into the list element. -func void List_Set(var int node, var int data) {}; - -/// Retrieves the value of a list element. -/// -/// @param list The list from which the element is retrieved. -/// @param nr The number of the list element. -/// -/// @return The function returns the value of the specified list element. -func int List_Get(var int list, var int nr) {}; - -/// Returns a pointer to a list element. -/// -/// @param list The list from which the element is retrieved. -/// @param nr The number of a list element. -/// -/// @return The function returns a pointer to the specified list element. -func int List_Node(var int list, var int nr) {}; - -/// Returns the length of the list (the number of all elements). -/// -/// @param list The list for which the length is calculated. -/// -/// @return The function returns the number of elements in the list. -func int List_Length(var int list) {}; - -/// Checks if the list has the specified length. -/// -/// @param list The list to check. -/// @param length The desired length. -/// -/// @return The function returns a boolean value indicating whether the list has the specified length or not. -func int List_HasLength(var int list, var int length) {}; - -/// Returns the last list element of the list. -/// -/// @param list The list from which the last element is retrieved. -/// -/// @return The function returns a pointer to the last list element. -func int List_End(var int list) {}; - -/// Concatenates two lists. -/// -/// @param list The first list. -/// @param list2 The second list. Its beginning is appended to the end of the first list. -func void List_Concat(var int list, var int list2) {}; - -/// Returns the last list element with a specific value. -/// -/// @param list The list in which to search for the value. -/// @param data The value to search for. -/// -/// @return The function returns the number of the last list element with the value data. -func int List_Contains(var int list, var int data) {}; - -/// Calls a function for each list element, passing a pointer to the list element as a parameter. -/// -/// @param list The list to iterate over. -/// @param function Name of a function to be called for each list element (void handler(var int node)). -func void List_For(var int list, var string function) {}; - -/// Similar to List_For, but with a function parameter instead of a string. -/// -/// @param list The list to iterate over. -/// @param function The function to be called for each list element (void handler(var int node)). -func void ListForF(var int list, var func function) {}; - -/// Similar to List_For, but with a function parameter instead of a string. -/// -/// @param list The list to iterate over. -/// @param funcID ID of a function to be called for each list element (void handler(var int node)). -func void List_ForI(var int list, var int funcID) {}; - -/// Deletes a list element. All subsequent elements shift position. -/// -/// @param list The list from which an element is deleted. -/// @param nr The number of the list element to be deleted. -func void List_Delete(var int list, var int nr) {}; - -/// Destroys the entire list. -/// -/// @param list The list to be destroyed. -func void List_Destroy(var int list) {}; - -/// Returns a pointer to a memory area containing all values of the list. -/// -/// @param list The list to be converted to an array. -/// -/// @return The function returns a memory area containing all the values of the list. -func int List_ToArray(var int list) {}; - -/// Moves the specified list node down by one position in the list. -/// -/// @param list The list in which the node is located. -/// @param node The node to be moved down. -func void List_MoveDown(var int list, var int node) {}; - -/// Moves the specified list node up by one position in the list. -/// -/// @param list The list in which the node is located. -/// @param node The node to be moved up. -func void List_MoveUp(var int list, var int node) {}; - -/// Inserts a value into a sorted list while preserving the sort order. -/// -/// @param list The list to insert the value into. -/// @param data The value to be inserted. -/// @param compare A comparison function used to determine the sort order. -func void List_InsertSorted(var int list, var int data, var func compare) {}; - -/// Creates a new list with an initial value (for zCListSort). -/// -/// @param data The value of the first list element. -/// -/// @return The function returns a pointer to the created list. -func int List_CreateS(var int data) {}; - -/// Appends a value to the end of the list (for zCListSort). -/// -/// @param list The list to which the value is appended. -/// @param data The value to be appended. -func void List_AddS(var int list, var int data) {}; - -/// Adds a value before the first element of the list (for zCListSort). -/// -/// @param list The list to which the value is added. -/// @param data The value to be added. -func void List_AddFrontS(var int list, var int data) {}; - -/// Inserts a value between two list elements (for zCListSort). -/// -/// @param list The list in which the value is inserted. -/// @param offset The number of the list element after which the value is inserted. -/// @param data The value to be inserted. -func void List_AddOffsetS(var int list, var int offset, var int data) {}; - -/// Sets a list element to a specific value (for zCListSort). -/// -/// @param node Pointer to the list element. -/// @param data The value to be written into the list element. -func void List_SetS(var int node, var int data) {}; - -/// Retrieves the value of a list element (for zCListSort). -/// -/// @param list The list from which the element is retrieved. -/// @param nr The number of the list element. -/// -/// @return The function returns the value of the specified list element. -func int List_GetS(var int list, var int nr) {}; - -/// Returns a pointer to a list element (for zCListSort). -/// -/// @param list The list from which the element is retrieved. -/// @param nr The number of a list element. -/// -/// @return The function returns a pointer to the specified list element. -func int List_NodeS(var int list, var int nr) {}; - -/// Returns the length of the list (the number of all elements) (for zCListSort). -/// -/// @param list The list for which the length is calculated. -/// -/// @return The function returns the number of elements in the list. -func int List_LengthS(var int list) {}; - -/// Checks if the list has the specified length (for zCListSort). -/// -/// @param list The list to check. -/// @param length The desired length. -/// -/// @return The function returns a boolean value indicating whether the list has the specified length or not. -func int List_HasLengthS(var int list, var int length) {}; - -/// Returns the last list element of the list (for zCListSort). -/// -/// @param list The list from which the last element is retrieved. -/// -/// @return The function returns a pointer to the last list element. -func int List_EndS(var int list) {}; - -/// Concatenates two lists (for zCListSort). -/// -/// @param list The first list. -/// @param list2 The second list. Its beginning is appended to the end of the first list. -func void List_ConcatS(var int list, var int list2) {}; - -/// Returns the last list element with a specific value (for zCListSort). -/// -/// @param list The list in which to search for the value. -/// @param data The value to search for. -/// -/// @return The function returns the number of the last list element with the value data. -func int List_ContainsS(var int list, var int data) {}; - -/// Calls a function for each list element, passing a pointer to the list element as a parameter (for zCListSort). -/// -/// @param list The list to iterate over. -/// @param function Name of a function to be called for each list element (void handler(var int node)). -func void List_ForS(var int list, var string function) {}; - -/// Similar to List_For, but with a function parameter instead of a string (for zCListSort). -/// -/// @param list The list to iterate over. -/// @param function The function to be called for each list element (void handler(var int node)). -func void ListForFS(var int list, var func function) {}; - -/// Similar to List_For, but with a function parameter instead of a string (for zCListSort). -/// -/// @param list The list to iterate over. -/// @param funcID ID of a function to be called for each list element (void handler(var int node)). -func void List_ForIS(var int list, var int funcID) {}; - -/// Deletes a list element. All subsequent elements shift position (for zCListSort). -/// -/// @param list The list from which an element is deleted. -/// @param nr The number of the list element to be deleted. -func void List_DeleteS(var int list, var int nr) {}; - -/// Destroys the entire list (for zCListSort). -/// -/// @param list The list to be destroyed. -func void List_DestroyS(var int list) {}; - -/// Returns a pointer to a memory area containing all values of the list (for zCListSort). -/// -/// @param list The list to be converted to an array. -/// -/// @return The function returns a memory area containing all the values of the list. -func int List_ToArrayS(var int list) {}; - -/// Moves the specified list node down by one position in the list (for zCListSort). -/// -/// @param list The list in which the node is located. -/// @param node The node to be moved down. -func void List_MoveDownS(var int list, var int node) {}; - -/// Moves the specified list node up by one position in the list (for zCListSort). -/// -/// @param list The list in which the node is located. -/// @param node The node to be moved up. -func void List_MoveUpS(var int list, var int node) {}; - -/// Inserts a value into a sorted list while preserving the sort order (for zCListSort). -/// -/// @param list The list to insert the value into. -/// @param data The value to be inserted. -/// @param compare A comparison function used to determine the sort order. -func void List_InsertSortedS(var int list, var int data, var func compare) {}; - -/// Compares two integer values using a specified comparison function. -/// -/// @param data1 The first integer value. -/// @param data2 The second integer value. -/// @param compare One of the comparison functions to use for the comparison. -/// -/// @return The return value of the specified comparison function. -func int List_Compare(var int data1, var int data2, var func compare) {}; - -/// Compares two integer values in ascending order. -/// -/// @param data1 The first integer value. -/// @param data2 The second integer value. -/// -/// @return The function returns TRUE if data1 is greater than data2, FALSE otherwise. -func int List_CmpAscending(var int data1, var int data2) {}; - -/// Compares two integer values in descending order. -/// -/// @param data1 The first integer value. -/// @param data2 The second integer value. -/// -/// @return The function returns TRUE if data1 is less than data2, FALSE otherwise. -func int List_CmpDescending(var int data1, var int data2) {}; - -/// Compares two unsigned integer values in ascending order. -/// -/// @param data1 The first unsigned integer value. -/// @param data2 The second unsigned integer value. -/// -/// @return The function returns TRUE if data1 is greater than data2, FALSE otherwise. -func int List_CmpAscendingUnsigned(var int data1, var int data2) {}; - -/// Compares two unsigned integer values in descending order. -/// -/// @param data1 The first unsigned integer value. -/// @param data2 The second unsigned integer value. -/// -/// @return The function returns TRUE if data1 is less than data2, FALSE otherwise. -func int List_CmpDescendingUnsigned(var int data1, var int data2) {}; - -// ========================================================= -// -// Locals -// -// ========================================================= - -/// Activates the 'Locals' feature in a function. -/// -/// This function is used to enable the 'Locals' feature in your code. It should be added at the -/// beginning of the function that should receive "real" local variables. -func void locals() {}; - -/// Create a block of code to be executed when a function is exited. -/// -/// The 'Final' function is used to create a block of code that is executed after the function it -/// is defined in is exited, regardless of when or where the function is exited. It can be used to -/// emulate Java's 'final' clause. -/// -/// @return 1 if the 'Final' block is executed, 0 otherwise. -func int Final() {}; - -// ========================================================= -// -// Misc -// -// ========================================================= - -/// Calculates the arcus tangent of an angle between the origin and a point (x, y). -/// -/// @param x The X-coordinate. -/// @param y The Y-coordinate. -/// -/// @return The arcus tangent in radians as an Ikarus float. -func float atan2f(var int x, var int y) {}; - -/// Calculates the sine of an angle given in radians. -/// -/// @param angle The angle in radians as an Ikarus float. -/// -/// @return The sine of the angle. -func float sin(var float angle) {}; - -/// Calculates the cosine of an angle given in radians. -/// -/// @param angle The angle in radians as an Ikarus float. -/// -/// @return The cosine of the angle. -func float cos(var float angle) {}; - -/// Calculates the tangent of an angle given in radians. -/// -/// @param angle The angle in radians as an Ikarus float. -/// -/// @return The tangent of the angle. -func float tan(var float angle) {}; - -/// Calculates the arcus sine. -/// -/// @param sine The sine of an angle as an Ikarus float. -/// -/// @return The arcus sine of the angle. -func float asin(var float sine) {}; - -/// Calculates the arcus cosine. -/// -/// @param cosine The cosine of an angle as an Ikarus float. -/// -/// @return The arcus cosine of the angle. -func float acos(var float cosine) {}; - -/// Calculates the distance between two points on a two-dimensional plane. -/// -/// @param x1 The X-coordinate of the first point. -/// @param x2 The X-coordinate of the second point. -/// @param y1 The Y-coordinate of the first point. -/// @param y2 The Y-coordinate of the second point. -/// -/// @return The distance between the two points. -func int distance2D(var int x1, var int x2, var int y1, var int y2) {}; - -/// Calculates the distance between two points on a two-dimensional plane with Ikarus floats. -/// -/// @param x1 The X-coordinate of the first point. -/// @param x2 The X-coordinate of the second point. -/// @param y1 The Y-coordinate of the first point. -/// @param y2 The Y-coordinate of the second point. -/// -/// @return The distance between the two points as an Ikarus float. -func float distance2Df(var float x1, var float x2, var float y1, var float y2) {}; - -// ========================================================= -// -// PermMem -// -// ========================================================= - -/// Creates a handle to a new instance of `inst`. -/// -/// @param inst A valid instance used as a "constructor". -/// -/// @return A new, valid PermMem handle. -func int new(var int inst) {}; - -/// Similar to `new`, but here a pointer is returned directly and not a handle. Caution! Not managed by PermMem! -/// -/// @param inst A valid instance used as a "constructor". -/// -/// @return A pointer to the new instance. -func int create(var int inst) {}; - -/// "Wraps" a handle "around" a pointer so that the pointer can be used with any function that expects handles. Only conditionally managed by PermMem. -/// -/// @param inst A valid instance determining the type of the handle. -/// @param ptr Pointer to wrap. -/// -/// @return A handle with `ptr` as content. -func int wrap(var int inst, var int ptr) {}; - -/// Cleans the handle. After that, it is invalid. -/// -/// @param hndl Valid PermMem handle. -func void clear(var int hndl) {}; - -/// Frees the handle. The reserved memory is not deleted; the handle becomes invalid. -/// -/// @param hndl Valid PermMem handle. -func void release(var int hndl) {}; - -/// Cleans the handle just like `clear`, but the destructor is also called. -/// -/// @param hndl Valid PermMem handle. -func void delete(var int hndl) {}; - -/// Cleans the handle just like `clear`, but the destructor is also called. -/// -/// @param ptr The pointer to be cleaned. -/// @param inst Instance used in `create` function. -func void free(var int ptr, var int inst) {}; - -/// Returns the instance of the handle. -/// -/// @param hndl Valid PermMem handle. -/// -/// @return The instance of the handle. -func instance get(var int hndl) {}; - -/// Returns a pointer to the instance of the handle. -/// -/// @param hndl Valid PermMem handle. -/// -/// @return A pointer to the instance of the handle. -func int getPtr(var int hndl) {}; - -/// Sets the pointer of a handle. -/// -/// @param hndl Valid PermMem handle. -/// @param ptr New pointer for the handle. -func void setPtr(var int hndl, var int ptr) {}; - -/// Returns the instance used to create the given handle in `new` function. -/// -/// @param hndl Valid PermMem handle. -/// -/// @return The instance used to create the handle in the `new` function. -func int getInst(var int hndl) {}; - -/// Returns the number of handles managed by PermMem. -/// -/// @return The number of handles managed by PermMem. -func int numHandles() {}; - -/// Returns the size of the instance's class in bytes. -/// -/// @param inst Any instance. -/// -/// @return The size of the instance's class in bytes. -func int sizeof(var int inst) {}; - -/// Indicates whether the handle exists and is managed by PermMem. -/// -/// @param hndl PermMem's handle. -/// -/// @return TRUE if the handle is valid (managed by PermMem), FALSE otherwise. -func int Hlp_IsValidHandle(var int hndl) {}; - -/// Executes a function for each handle of an instance. -/// -/// @param inst The function is called for this instance. -/// @param fnc The function is called. The signature is `function(int handle)`. -func void foreachHndl(var int inst, var func fnc) {}; - -/// Checks if PermMem has a handle of this instance. -/// -/// @param inst Instance to be checked. -/// -/// @return TRUE if PermMem has a handle of this instance, FALSE otherwise. -func int hasHndl(var int inst) {}; - -/// Function moved to PermMem from Ikarus. Reads string from the array at the `arrayAddress`. -/// -/// @param arrayAddress Memory address of the array. -/// @param index Array offset (array index). -/// -/// @return String from the array if the address is correct. -func string MEM_ReadStringArray(var int arrayAddress, var int index) {}; - -/// Checks if the specified field already exists in the archive (used with archiver/unarchiver). -/// -/// @param name Name of the field. -/// -/// @return TRUE if the field exists in the archive, FALSE otherwise. -func int PM_Exists(var string name) {}; - -/// Universal function to load integers, floats, class pointers, and int arrays. -/// -/// @param name Name of the loaded field. -/// -/// @return The data existing in the archive at the given field. -func int PM_Load(var string name) {}; - -/// Returns an integer stored in the archive. -/// -/// @param name Name of the loaded field. -/// -/// @return The integer value stored in the archive. -func int PM_LoadInt(var string name) {}; - -/// Returns a daedalus float stored in the archive. -/// -/// @param name Name of the loaded field. -/// -/// @return The daedalus float stored in the archive. -func int PM_LoadFloat(var string name) {}; - -/// Returns a string stored in the archive. -/// -/// @param name Name of the loaded field. -/// -/// @return The string stored in the archive. -func string PM_LoadString(var string name) {}; - -/// Returns a function ID stored in the archive. -/// -/// @param name Name of the loaded field. -/// -/// @return The function ID stored in the archive. -func int PM_LoadFuncID(var string name) {}; - -/// Returns a function offset stored in the archive. -/// -/// @param name Name of the loaded field. -/// -/// @return The function offset stored in the archive. -func int PM_LoadFuncOffset(var string name) {}; - -/// Returns a function pointer stored in the archive. -/// -/// @param name Name of the loaded field. -/// -/// @return The function pointer stored in the archive. -func int PM_LoadFuncPtr(var string name) {}; - -/// Returns a class pointer stored in the archive. -/// -/// @param name Name of the loaded field. -/// -/// @return The class pointer stored in the archive. -func int PM_LoadClassPtr(var string name) {}; - -/// Loads a pointer to the class from the archive to `destPtr`. -/// -/// @param name Name of the loaded field. -/// @param destPtr Destination pointer, the address to where it will deserialize the saved data. -func void PM_LoadClass(var string name, var int destPtr) {}; - -/// Returns a pointer to array stored in the archive. -/// -/// @param name Name of the loaded field. -/// -/// @return A pointer to the array stored in the archive. -func int PM_LoadArray(var string name) {}; - -/// Loads a pointer to array from the archive to `destPtr`. -/// -/// @param name Name of the loaded field. -/// @param destPtr Destination pointer, the address to where it will deserialize the saved data. -func void PM_LoadArrayToPtr(var string name, var int destPtr) {}; - -/// Universal function to load array or class pointer from the archive to `destPtr`. -/// -/// @param name Name of the loaded field. -/// @param destPtr Destination pointer, the address to where it will deserialize the saved data. -func void PM_LoadToPtr(var string name, var int destPtr) {}; - -// ========================================================= -// -// Queue -// -// ========================================================= - -/// Creates a new queue and returns a handle to it. -/// -/// @return A handle to a queue. -func int Q_Create() {}; - -/// Appends an integer to the back of the queue. -/// -/// @param queue Handle of a queue. -/// @param value The value to be appended to the queue. -func void Q_Enqueue(var int queue, var int value) {}; - -/// Checks if the queue is empty. -/// -/// @param queue Handle of a queue. -/// -/// @return TRUE if the queue is empty, FALSE otherwise. -func int Q_IsEmpty(var int queue) {}; - -/// Removes the oldest value from the queue and returns it. -/// -/// @param queue Handle of a queue. -/// -/// @return The oldest value in the queue. -func int Q_Advance(var int queue) {}; - -/// Returns the oldest value in the queue without removing it. -/// -/// @param queue Handle of a queue. -/// -/// @return The oldest value in the queue. -func int Q_Peek(var int queue) {}; - -/// Function with the `funcID` is called with every element of the list as a parameter. The list element is passed to the function as a `zCList` pointer. -/// -/// @param queue Handle of a queue. -/// @param funcID ID of function that is executed for all values in the queue (signature: `void (zCList*)`). -func void Q_For(var int queue, var int funcID) {}; - -/// Like `Q_For`, but with function as a parameter instead of a function ID. -/// -/// @param queue Handle of a queue. -/// @param f This function is executed for all values in the queue (signature: `void (zCList*)`). -func void Q_ForF(var int queue, var func f) {}; - -/// Creates a new callback queue and returns a handle to it. -/// -/// @return A handle to a callback queue. -func int CQ_Create() {}; - -/// Appends a function to the callback queue. -/// -/// @param queue Handle of a callback queue. -/// @param function A function with no return value, expecting no parameter. -func void CQ_EnqueueNoData(var int queue, var func function) {}; - -/// Appends a function together with a value to the callback queue. -/// -/// @param queue Handle of a callback queue. -/// @param function A function with no return value, expecting an integer as a parameter. -/// @param data When calling `function`, this value is passed as a parameter. -func void CQ_EnqueueData(var int queue, var func function, var int data) {}; - -/// Appends a function together with an optional value to the callback queue. -/// This function should not usually be used. Use `CQ_EnqueueData` and `CQ_EnqueueNoData` instead. -/// -/// @param queue Handle of a callback queue. -/// @param funcID The function ID of a function to be appended to the callback queue. -/// @param data If hasData is not 0, this value is passed to the associated function. -/// @param hasData Must be 0 if the function does not expect an integer as a parameter, otherwise not 0. -func void CQ_Enqueue(var int queue, var int funcID, var int data, var int hasData) {}; - -/// Checks if no function is in the callback queue. -/// -/// @param queue Handle of a callback queue. -/// -/// @return TRUE if the callback queue is empty, FALSE otherwise. -func int CQ_IsEmpty(var int queue) {}; - -/// Executes the foremost function of the callback queue and removes it from the callback queue. -/// -/// @param queue Handle of a callback queue. -func void CQ_Advance(var int queue) {}; - -/// Executes all functions contained in the callback queue. -/// -/// @param queue Handle of a callback queue. -func void CQ_Exhaust(var int queue) {}; - -// ========================================================= -// -// Random -// -// ========================================================= - -/// Returns a random number. -/// -/// @return A random number. -func int r_Next() {}; - -/// Returns a random number from 0 to `max`. -/// -/// @param max Maximum value of the number. -/// -/// @return A random number from 0 to `max`. -func int r_Max(var int max) {}; - -/// Returns a random number from `min` to `max`. -/// -/// @param max Maximum value of the number. -/// @param min Minimum value of the number. -/// -/// @return A random number from `min` to `max`. -func int r_MinMax(var int min, var int max) {}; - -/// Initializes the random number generator. Happens optionally in `LeGo_Init`. -/// -/// @param seed The initializing value. -func void r_Init(var int seed) {}; - -/// Initializes the random number generator based on the current time. -func void r_DefaultInit() {}; - -// ========================================================= -// -// StringBuilder -// -// ========================================================= - -/// Creates and returns a new `StringBuilder`. At the same time, this new `StringBuilder` is set as active. -/// -/// @return A pointer to a new `StringBuilder`. -func int SB_New() {}; - -/// Marks this `StringBuilder` as active. It can now be used with the functions. -/// -/// @param sb Pointer to a `StringBuilder`, returned from `SB_New`. -func void SB_Use(var int sb) {}; - -/// Returns the active `StringBuilder`. -/// -/// @return The active `StringBuilder` object - last set with `SB_Use` or just created with `SB_New`. -func int SB_Get() {}; - -/// If the size of the resulting string is already known, the buffer can be set manually. This is usually not necessary. -/// -/// @param size Size in bytes. Warning! Only works if the `StringBuilder` has been newly created! -func void SB_InitBuffer(var int size) {}; - -/// Empties the current `StringBuilder`. It is not destroyed in the process, so it can be used again. If the object has a buffer allocated, the buffer is freed. -func void SB_Clear() {}; - -/// Releases the current stream of the `StringBuilder`. The `StringBuilder` is destroyed, and the stream can be obtained via `SB_GetStream`. -func void SB_Release() {}; - -/// Completely destroys the `StringBuilder`. -func void SB_Destroy() {}; - -/// Returns a copy of the stream as a string. -/// -/// @return A copy of the active `StringBuilder` as a string. If the `StringBuilder` object doesn't have a buffer allocated, an empty string is returned. -func string SB_ToString() {}; - -/// Returns a copy of the stream in raw format. -/// -/// @return A copy of the stream in raw format (`char[]`). -func int SB_ToStream() {}; - -/// Doesn't copy the stream but returns it as it is. -/// -/// @return The stream as it is. `SB_Destroy` or `SB_Clear` destroy the returned pointer. -func int SB_GetStream() {}; - -/// Returns the current length of the stream. Similar to `STR_Len` from Ikarus. -/// -/// @return The current length of the active `StringBuilder`. -func int SB_Length() {}; - -/// Sets the length of the stream. When increasing, zero bytes are appended. -/// -/// @param length The new length of the stream. -func void SB_SetLength(var int length) {}; - -/// Appends a string to the active `StringBuilder`. -/// -/// @param s The appended string. -func void SB(var string s) {}; - -/// Appends an integer in text form to the active `StringBuilder`. -/// -/// @param i The appended integer. -func void SBi(var int i) {}; - -/// Appends a byte to the active `StringBuilder`. (e.g., 82 for 'R' - An ASCII table can be quickly found) -/// -/// @param c The appended byte (ASCII table character). -func void SBc(var int c) {}; - -/// Appends a raw bytes array to the active `StringBuilder`. -/// -/// @param ptr Pointer to the appended array. -/// @param len Length of an array. -func void SBraw(var int ptr, var int len) {}; - -/// Appends a Daedalus float in text form to the active `StringBuilder`. -/// -/// @param x The appended Daedalus float value. -func void SBflt(var float x) {}; - -/// Appends an Ikarus float in text form to the active `StringBuilder`. -/// -/// @param x The appended Ikarus float value. -func void SBf(var int x) {}; - -/// Appends a 4-byte raw data (interpreted as an integer `x`) to the active `StringBuilder`. -/// -/// @param x The appended value. -func void SBw(var int x) {}; - -/// Makes escape sequences out of non-writable characters. For example, newline character '\n' becomes '\\n', tab character '\t' becomes '\\t', etc. -/// -/// @param s0 The string to be added escape sequences. -/// -/// @return A new string with escape sequences added for special characters. -func string STR_Escape(var string s0) {}; - -/// Counterpart to `STR_Escape`. Escape sequences like '\n', '\r' or '\t' are converted back. -/// -/// @param s0 The string to be removed escape sequences. -/// -/// @return A new string with escape sequences replaced by their corresponding characters. -func string STR_Unescape(var string s0) {}; - -/// Checks if the input string `str` starts with the specified prefix string. -/// -/// @param str The string to be checked. -/// @param start The searched prefix. -/// -/// @return `TRUE` if the string starts with the prefix, `FALSE` is returned otherwise. -func int STR_StartsWith(var string str, var string start) {}; - -/// Creates an array of all string symbols found in the parser's string table. -/// -/// @return The created array. -func int BuildStringSymbolsArray() {}; - -/// Retrieves the symbol at the specified address from the string table. -/// -/// @param address The address of the symbol. -/// -/// @return A parser symbol at the given address. -func int GetStringSymbolByAddr(var int address) {}; - -// ========================================================= -// -// Talents -// -// ========================================================= - -/// Returns a unique ID specific for the provided NPC. -/// -/// @param slf NPC to get ID. -/// -/// @return The function returns the NPC's unique ID. -func int Npc_GetID(var C_NPC slf) {}; - -/// Finds the NPC pointer of an NPC with the given ID. -/// -/// @param ID NPC ID. -/// -/// @return The function returns the NPC pointer. -func int Npc_FindByID(var int ID) {}; - -/// Creates a talent into which you can later save a value for every NPC (just like `AI_Var`). -/// -/// @return A value that can be later used as a talent ID. -func int TAL_CreateTalent() {}; - -/// Sets a new value to the specified talent. -/// -/// @param npc Set the talent value for this NPC. -/// @param talent Talent ID. -/// @param value Value to be set. -func void TAL_SetValue(var C_NPC npc, var int talent, var int value) {}; - -/// Returns the value of a saved talent for the specified NPC. -/// -/// @param npc Get the talent value from this NPC. -/// @param talent Talent ID. -/// -/// @return The function returns the value of the saved talent for the specified NPC. -func int TAL_GetValue(var C_NPC npc, var int talent) {}; - -// ========================================================= -// -// Timer -// -// ========================================================= - -/// Returns the current playing time. If a new game is started, the time is 0. It is measured in milliseconds. -/// -/// @return The function returns current playing time in milliseconds. -func int Timer() {}; - -/// Returns the current game time, but the timer is paused when the game is paused (in the menu or status screen). -/// -/// @return The function returns current playing time in milliseconds, but without measuring time when the game is paused. -func int TimerGT() {}; - -/// Alias to the `Timer` function that returns the time as an Ikarus float value. -/// -/// @return The function returns current playing time as an Ikarus float value. -func int TimerF() {}; - -/// Pauses the timer (and thus all FrameFunctions and running animations). -/// -/// @param on Pause on/off. -func void Timer_SetPause(var int on) {}; - -/// The timer can automatically pause when the game is paused (status screen, main menu...). -/// -/// @param on Automatic pause on/off. -func void Timer_SetPauseInMenu(var int on) {}; - -/// This can be used to query whether the timer is paused. -/// -/// @return The function returns TRUE if the timer is paused, FALSE is returned otherwise. -func int Timer_IsPaused() {}; diff --git a/zengin/scripts/extenders/lego/tools/ai_function/index.html b/zengin/scripts/extenders/lego/tools/ai_function/index.html deleted file mode 100644 index 96aa06e3ac..0000000000 --- a/zengin/scripts/extenders/lego/tools/ai_function/index.html +++ /dev/null @@ -1,71 +0,0 @@ - AI_Function - Gothic Modding Community

AI_Function

This package allows time-delayed functions to be called by enqueuing the functions in the AI queue of the NPC in question. This can be very useful in writing cutscenes on engine or implementing new routines.

Dependencies

Initialization

Initialize with LeGo_AI_Function flag.

LeGo_Init(LeGo_AI_Function);
-

Implementation

AI_Function.d on GitHub

Functions

The script function function is called with a delay: it joins the AI queue of slf.

func void AI_Function(var C_NPC slf, var func function)
-
Parameters
  • var C_NPC slf
    NPC in whose AI queue the function is queued
  • var func function
    Name of function to be queued

Additionally, there are some overloads of AI_Function, which allow to call functions with parameters.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
func void AI_Function_I  (var C_NPC slf, var func function, var int    param) {}; // Int
-func void AI_Function_N  (var C_NPC slf, var func function, var int    param) {}; // Instance (e.g. NPC)
-func void AI_Function_S  (var C_NPC slf, var func function, var string param) {}; // String
-func void AI_Function_II (var C_NPC slf, var func function, var int    param1, var int    param2) {}; // Int, Int
-func void AI_Function_NN (var C_NPC slf, var func function, var int    param1, var int    param2) {}; // Instance, Instance
-func void AI_Function_SS (var C_NPC slf, var func function, var string param1, var string param2) {}; // String, String
-func void AI_Function_IS (var C_NPC slf, var func function, var int    param1, var string param2) {}; // Int, String
-func void AI_Function_SI (var C_NPC slf, var func function, var string param1, var int    param2) {}; // String, Int
-func void AI_Function_NS (var C_NPC slf, var func function, var int    param1, var string param2) {}; // Instance, String
-func void AI_Function_SN (var C_NPC slf, var func function, var string param1, var int    param2) {}; // String, Instance
-func void AI_Function_IN (var C_NPC slf, var func function, var int    param1, var int    param2) {}; // Int, Instance
-func void AI_Function_NI (var C_NPC slf, var func function, var int    param1, var int    param2) {}; // Instance, Int
-
Functions with more than two parameters cannot be called, but parameters can be passed indirectly via global variables.

In the called function, self can be accessed as follows:

var oCNpc slf; slf = _^(ECX);
-

Info

From LeGo 2.7.2 the global instance self is provided correctly and can be used directly.

Examples

Enqueueing a simple function

Before a function is called, any Npc should first complete its AI queue.

Here the hero is supposed to run to a waypoint, and only when he has arrived is to start a tracking shot.

1
-2
-3
-4
-5
-6
func void Example1() {
-    Npc_ClearAIQueue(hero);
-    AI_GotoWP(hero, "MYWAYPOINT");
-
-    AI_Function_S(hero, Wld_SendTrigger, "CAMERASTART");
-};
-
As soon as the hero has reached the waypoint, Wld_SendTrigger("CAMERASTART"); is called.
\ No newline at end of file diff --git a/zengin/scripts/extenders/lego/tools/binary_machines/index.html b/zengin/scripts/extenders/lego/tools/binary_machines/index.html deleted file mode 100644 index e3faca7298..0000000000 --- a/zengin/scripts/extenders/lego/tools/binary_machines/index.html +++ /dev/null @@ -1,233 +0,0 @@ - BinaryMachines - Gothic Modding Community

BinaryMachines

This package allows you to create and write your own files anywhere in the file system.

Dependencies

N/A

Initialization

N/A

Implementation

BinaryMachines.d on GitHub

BinaryWriter

BW_NewFile

Creates the file with the file name and opens a stream. Doesn't work if a stream is already open.

func int BW_NewFile(var string file)
-
Parameters
  • var string file
    Name of created file

Return value

The function returns TRUE if the file is successfully created and initialized, FALSE is returned otherwise.

BW_Close

Closes the current write stream.

func void BW_Close()
-

BW

Writes length bytes from the data to the stream, maximum 4 bytes.

func void BW(var int data, var int length)
-
Parameters
  • var int data
    Value of bytes
  • var int length
    Number of bytes

BW_Int

Writes 4 bytes from the data to the stream. Same as BW(data, 4).

func void BW_Int(var int data)
-
Parameters
  • var int data
    Integer value to write

BW_Char

Writes the first character from the data to the stream. Same as BW(Str_GetCharAt(data, 0), 1).

func void BW_Char(var string data)
-
Parameters
  • var string data
    Char to write

BW_String

Writes the data terminated with \0 to the stream.

func void BW_String(var string data)
-
Parameters
  • var string data
    String to write

BW_Byte

Writes a byte from the data to the stream. Same as BW(data, 1).

func void BW_Byte(var int data)
-
Parameters
  • var int data
    Byte value to write

BW_Bytes

Writes length of bytes from the pointer dataPtr to the stream.

func void BW_Bytes(var int dataPtr, var int length)
-
Parameters
  • var int dataPtr
    Pointer of data to write
  • var int length
    Number of bytes

BW_Text

Writes the string to the stream without terminating it. So it can no longer be read.

func void BW_Text(var string data)
-
Parameters
  • var string data
    Text to write

BW_NextLine

Writes a paragraph to the stream.

func void BW_NextLine()
-

BinaryReader

BR_OpenFile

Opens the file with the file name and opens a stream. Doesn't work if a stream is already open.

func int BR_OpenFile(var string file)
-
Parameters
  • var string file
    File to be opened

Return value

The function returns TRUE if the file is successfully opened and initialized, FALSEis returned otherwise.

BR_Close

Closes the current read stream.

func void BR_Close()
-

BR

Reads bytes from the stream.

func int BR(var int length)
-
Parameters
  • var int length
    Number of bytes to read (maximum 4)

Return value

The function returns the value of read bytes.

BR_Int

Reads 4 bytes from the stream. Same as BR(4).

func int BR_Int()
-
Return value

The function returns the read integer.

BR_Char

Reads a character from the stream. Same as BR(1).

func string BR_Char()
-
Return value

The function returns the read character as a string.

BR_String

Reads a string terminated by \0 from the stream.

func string BR_String()
-
Return value

The function returns the read string.

BR_Byte

Reads a byte from the stream.

func int BR_Byte()
-
Return value

The function returns the read byte.

BR_Bytes

Reads bytes from the stream.

func int BR_Bytes(var int length)
-
Parameters
  • var int length
    Number of bytes to read

Return value

The function returns a pointer to the read bytes.

BR_TextLine

Reads a line from the stream.

func string BR_TextLine()
-
Return value

The function returns the read line.

BR_Text

Reads a string of the given length from a stream.

func string BR_Text(var int length)
-
Parameters
  • var int length
    Number of characters to read

Return value

The function returns the read string.

BR_NextLine

Changes the read position to the next paragraph, created with BW_NextLine

func void BR_NextLine()
-

Enginecalls

WIN_GetLastError

Call of a Win32 API GetLastError function

func int WIN_GetLastError()
-
Return value

The function returns calling thread's last-error code.

WIN_CreateFile

Call of a Win32 API CreateFileA function

func int WIN_CreateFile(var string lpFileName,var int dwDesiredAccess,var int dwShareMode,var int lpSecurityAttributes,var int dwCreationDisposition,var int dwFlagsAndAttributes,var int hTemplateFile)
-
Parameters

Full description of parameters can be found here

Return value

Information about return value can be found here

WIN_WriteFile

Call of a Win32 API WriteFile function

func void WIN_WriteFile(var int hFile,var int lpBuffer,var int nNumberOfBytesToWrite,var int lpNumberOfBytesWritten,var int lpOverlapped)
-
Parameters

Full description of parameters can be found here

WIN_ReadFile

Call of a Win32 API ReadFile function

func void WIN_ReadFile(var int hFile,var int lpBuffer,var int nNumberOfBytesToRead,var int lpNumberOfBytesRead,var int lpOverlapped)
-
Parameters

Full description of parameters can be found here

WIN_CloseHandle

Call of a Win32 API CloseHandle function

func void WIN_CloseHandle(var int hObject)
-
Parameters

Full description of parameters can be found here

WIN_GetFileSize

Call of a Win32 API GetFileSize function

func int WIN_GetFileSize(var int hFile,var int lpFileSizeHigh)
-
Parameters

Full description of parameters can be found here

Return value

Information about return value can be found here

Constants

In addition there are some constants defined for use with the specific engine calls.

1
-2
-3
-4
-5
-6
-7
-8
const int CREATE_ALWAYS = 2;
-const int OPEN_EXISTING = 3;
-const int GENERIC_ALL = 1073741824;
-const int GENERIC_READ = -2147483648;
-const int FILE_SHARE_READ = 1;
-const int FILE_SHARE_WRITE = 2;
-const int FILE_SHARE_DELETE = 4;
-const int FILE_ATTRIBUTE_NORMAL = 128;
-

Examples

Save and load variables

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
const string filename = "System\MySave.sav";
-
-var string s0; // string
-var int    i1; // int
-var int    b2; // byte
-var string c3; // char
-
-func void SaveMyData() 
-{
-    if(BW_NewFile(filename))  // Create a new file:
-    { 
-        BW_String(s0);
-        BW_Int(i1);
-        BW_Byte(b2);
-        BW_Char(c3);          // Save stuff..
-        BW_Close();           // ..and close.
-    };
-};
-
-func void LoadMyData() {
-    if(BR_OpenFile(filename)) // Try to open file:
-    { 
-        s0 = BR_String();
-        i1 = BR_Int();
-        b2 = BR_Byte();
-        c3 = BR_Char();       // Read in values..
-        BR_Close();           // ..and close.
-    }
-    else 
-    {
-        SaveMyData();         // Otherwise create a save file.
-    };
-};
-

Congratulate the player

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
func void Certificate(var string Username, var int Score) 
-{
-    var string filename; filename = ConcatStrings(Username, "'s Certificate.txt");
-    BW_NewFile(filename); // Username + "s Certificate.txt". The file is then in the Gothic directory.
-    BW_Text("Congratulations "); BW_Text(Username);
-    BW_TextLine("!");
-
-    BW_Text("You have reached ");
-    BW_Text(IntToString(Score)); // Not BW_Int!
-    BW_TextLine(" Points in this fun game.");
-
-    BW_NextLine();
-
-    BW_Text("Best regards, Author");
-    BW_Close();
-
-    /*
-       When calling:  Certificate("Player", 1000);
-       a file with the name 'Player's Certificate.txt' would come out which would contain the following:
-
-        Congratulations Player
-        You have reached 1000 Points in this fun game.
-
-        Best regards, Author
-    */
-};
-

The location of an NPCs

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
func void BW_NpcPosition(var C_NPC slf) 
-{
-    var int ptr; ptr = MEM_Alloc(60);                // 16 * 4
-    MEM_CopyBytes(MEM_InstToPtr(slf) + 60, ptr, 60); // Copy slf.trafoObjToWorld
-    BW_Bytes(ptr, 60);                               // Writes the 60 copied bytes
-    MEM_Free(ptr);                                   // And clean up..
-};
-
-func void BR_NpcPosition(var C_NPC slf) 
-{
-    var int ptr; ptr = BR_Bytes(60);                 // Read 60 bytes
-    MEM_CopyBytes(ptr, MEM_InstToPtr(slf) + 60, 60); // Paste back into slf
-    MEM_Free(ptr);                                   // And clean up again..
-};
-
-/*
-   Normal use:
-     BW_NewFile(file);
-     BW_NpcPosition(hero);
-     BW_Close();
-*/
-

Note

Examples originally written by Gottfried and posted on World of Gothic forum.

\ No newline at end of file diff --git a/zengin/scripts/extenders/lego/tools/event_handler/index.html b/zengin/scripts/extenders/lego/tools/event_handler/index.html deleted file mode 100644 index 5c45769950..0000000000 --- a/zengin/scripts/extenders/lego/tools/event_handler/index.html +++ /dev/null @@ -1,55 +0,0 @@ - EventHandler - Gothic Modding Community

EventHandler

This package allows to create new events and trigger them at desired times. The Gamestate package already uses it.

Warning

The EventHandler requires some basic understanding of the PermMem. The documentation can be found here.

Dependencies

Initialization

Initialize with LeGo_EventHandler flag.

LeGo_Init(LeGo_EventHandler);
-

Implementation

EventHandler.d on GitHub

Functions

Event_Create

Creates a new event and returns a handle to it.

func int Event_Create()
-
Return value

The function returns a new PermMem handle to an event.

Event_Delete

Alias to PermMem delete. Cleans up the handle.

func void Event_Delete(var int event)
-
Parameters
  • var int event
    Handle returned from Event_Create

Event_Empty

Checks whether the event is "empty", i.e. nothing will happen after its execution.

func int Event_Empty(var int event)
-
Parameters
  • var int event
    Handle returned from Event_Create

Return value

The function returns TRUE if event is empty, FALSE is returned otherwise.

Event_Has

Checks if function is added to the event.

func int Event_Has(var int event, var func function)
-
Parameters
  • var int event
    Handle returned from Event_Create
  • var func function
    Checked function

Return value

The function returns TRUE if function is added, FALSE is returned otherwise.

Event_Add

Adds an event handler function. The handler is called after running Event_Execute.

func void Event_Add(var int event, var func function)
-
Parameters
  • var int event
    Handle returned from Event_Create
  • var func function
    Function to be added

Event_AddOnce

Event_Add but checks if the handler function is already added, to prevent duplicates.

func void Event_AddOnce(var int event, var func function)
-
Parameters
  • var int event
    Handle returned from Event_Create
  • var func function
    Function to be added

Event_Remove

Removes the event handler function from the event.

func void Event_Remove(var int event, var func function)
-
Parameters
  • var int event
    Handle returned from Event_Create
  • var func function
    Function to be removed

Event_Execute

Core of the package. Calls all functions registered via Event_Add and Event_AddOnce.

func void Event_Execute(var int event, var int data)
-
Parameters
  • var int event
    Handle returned from Event_Create
  • var int data
    Int parameter passed to all executed functions

Ptr functions

Tip

The pointer functions are used internally by the previous functions. If you created an event with Event_Create use functions without Ptr in the name, but if you created event with EventPtr_Create use only Ptr functions. The normal user will probably never need the pointer versions, however the choice, which one to use is yours.

EventPtr_Create

Creates a new event and returns a pointer to it.

func int EventPtr_Create()
-
Return value

The function returns a new PermMem pointer to an event.

EventPtr_Delete

Alias to PermMem free. Cleans up the pointer.

func void EventPtr_Delete(var int eventPtr)
-
Parameters
  • var int eventPtr
    Pointer returned from EventPtr_Create

EventPtr_Empty

Checks whether the event is "empty", i.e. nothing will happen after its execution.

func int EventPtr_Empty(var int eventPtr)
-
Parameters
  • var int eventPtr
    Pointer returned from EventPtr_Create

Return value

The function returns TRUE if empty, FALSE is returned otherwise.

EventPtr_Has

Checks if function is added to an event.

func int EventPtr_Has(var int eventPtr, var func function)
-
Parameters
  • var int eventPtr
    Pointer returned from EventPtr_Create
  • var func function
    Checked function

Return value

The function returns TRUE if function is added, FALSE is returned otherwise.

EventPtr_HasI

EventPtr_Has but with function ID instead of pointer. Used mainly internally.

func int EventPtr_HasI(var int eventPtr, var int id)
-
Parameters
  • var int eventPtr
    Pointer returned from EventPtr_Create
  • var int id
    ID of checked function

Return value

The function returns TRUE if function is added, FALSE is returned otherwise.

EventPtr_Add

Adds an event handler function. The handler is called after running EventPtr_Execute.

func void EventPtr_Add(var int eventPtr, var func function)
-
Parameters
  • var int eventPtr
    Pointer returned from EventPtr_Create
  • var func function
    Function to be added

EventPtr_AddI

EventPtr_Add but with function ID instead of pointer. Used mainly internally.

func void EventPtr_AddI(var int eventPtr, var int id)
-
Parameters
  • var int eventPtr
    Pointer returned from EventPtr_Create
  • var int id
    ID of function to be added

EventPtr_AddOnce

Event_Add but checks if function is already added, to prevent duplicates.

func void EventPtr_AddOnce(var int eventPtr, var func function)
-
Parameters
  • var int eventPtr
    Pointer returned from EventPtr_Create
  • var func function
    Function to be added

EventPtr_AddOnceI

EventPtr_AddI but checks if function is already added, to prevent duplicates.

func void EventPtr_AddOnceI(var int eventPtr, var int id)
-
Parameters
  • var int eventPtr
    Pointer returned from EventPtr_Create
  • var int id
    ID of function to be added

EventPtr_Remove

Removes a function from the event's call list.

func void EventPtr_Remove(var int eventPtr, var func function)
-
Parameters
  • var int eventPtr
    Pointer returned from EventPtr_Create
  • var func function
    Function to be removed

EventPtr_RemoveI

EventPtr_Remove but with function ID instead of pointer. Used mainly internally.

func void EventPtr_RemoveI(var int eventPtr, var int id)
-
Parameters
  • var int eventPtr
    Pointer returned from EventPtr_Create
  • var int id
    ID of function to be removed

EventPtr_Execute

Core of the package. Calls all functions registered via EventPtr_Add and EventPtr_AddOnce.

func void EventPtr_Execute(var int eventPtr, var int data)
-
  • var int eventPtr
    Pointer returned from EventPtr_Create
  • var int data
    Int parameter passed to all executed functions

Examples

Note

This article has no built-in examples, but the best way to understand how EventHandler works is reading source code of the Gamestate package.

\ No newline at end of file diff --git a/zengin/scripts/extenders/lego/tools/frame_functions/index.html b/zengin/scripts/extenders/lego/tools/frame_functions/index.html deleted file mode 100644 index cdade36438..0000000000 --- a/zengin/scripts/extenders/lego/tools/frame_functions/index.html +++ /dev/null @@ -1,119 +0,0 @@ - FrameFunctions - Gothic Modding Community

FrameFunctions

The FrameFunctions package allows to call any number of functions called on every frame, or every specified time delay.

Dependencies

Initialization

Initialize with LeGo_FrameFunctions flag.

LeGo_Init(LeGo_FrameFunctions);
-

Implementation

FrameFunctions.d on GitHub

Functions

FF_Apply

Adds the Daedalus function function to the running FrameFunctions list. function is called each frame.

func void FF_Apply(var func function)
-
Parameters
  • var func function
    Name of the function

FF_ApplyGT

Adds the Daedalus function function to the running FrameFunctions list. function is called every frame except when the game is paused.

func void FF_ApplyGT(var func function)
-
Parameters
  • var func function
    Name of the function

FF_ApplyData

Adds the Daedalus function function to the running FrameFunctions list. The integer parameter data is passed to the function function.

func void FF_ApplyData(var func function, var int data)
-
Parameters
  • var func function
    Name of the function.
  • var int data
    Value passed to the function as a parameter

FF_ApplyExt

Adds the Daedalus function function to the running FrameFunctions list. The function function is called every delay milliseconds, and it runs only cycles number of times.

func void FF_ApplyExt(var func function, var int delay, var int cycles)
-
Parameters
  • var func function
    Name of the function
  • var int delay
    Delay between calls in milliseconds (0 = every frame)
  • var int cycles
    How many times should the function be called (-1 = endless)

FF_ApplyExtGT

Adds the Daedalus function function to the running FrameFunctions list. The function function is called every delay milliseconds, and it runs only cycles number of times. Gets called only when the game is not paused.

func void FF_ApplyExtGT(var func function, var int delay, var int cycles)
-
Parameters
  • var func function
    Name of the function
  • var int delay
    Delay between calls in milliseconds (0 = every frame)
  • var int cycles
    How many times should the function be called (-1 = endless)

FF_ApplyExtData

Adds the Daedalus function function to the running FrameFunctions list. The function function is called every delay milliseconds, and it runs only cycles number of times. The integer parameter data is passed to the function function.

func void FF_ApplyExtData(var func function, var int delay, var int cycles, var int data)
-
Parameters
  • var func function
    Name of the function.
  • var int delay
    Delay between calls in milliseconds (0 = every frame)
  • var int cycles
    How many times should the function be called (-1 = endless)
  • var int data
    Value passed to the function as a parameter

FF_ApplyExtDataGT

Adds the Daedalus function function to the running FrameFunctions list. The function function is called every delay milliseconds, and it runs only cycles number of times. The integer parameter data is passed to the function function. Gets called only when the game is not paused.

func void FF_ApplyExtData(var func function, var int delay, var int cycles, var int data)
-
Parameters
  • var func function
    Name of the function.
  • var int delay
    Delay between calls in milliseconds (0 = every frame)
  • var int cycles
    How many times should the function be called (-1 = endless)
  • var int data
    Value passed to the function as a parameter

FF_ApplyOnce

Alias to FF_Apply, which only adds the function once, even after multiple calls.

func void FF_ApplyOnce(var func function)
-
Parameters
  • var func function
    Name of the function

FF_ApplyOnceGT

Alias to FF_ApplyGT, which only adds the function once, even after multiple calls. Loop doesn't run if the game is paused.

func voidoften FF_ApplyOnceGT(var func function)
-
Parameters
  • var func function
    Name of the function.

FF_ApplyOnceData

Alias to FF_ApplyData, which only adds the function with the specified parameter once, even after multiple calls.

func void FF_ApplyOnceData(var func function, var int data)
-
Parameters
  • var func function
    Name of the function.
  • var int data
    Value passed to the function as a parameter

FF_ApplyOnceExt

Alias to FF_ApplyExt, which adds the function only once, after repeated calls.

func void FF_ApplyOnceExt(var func function, var int delay, var int cycles)
-
Parameters
  • var func function
    Name of the function
  • var int delay
    Delay between calls in milliseconds (0 = every frame)
  • var int cycles
    How many times should the function be called (-1 = endless)

FF_ApplyOnceExtGT

Alias to FF_ApplyExtGT, which adds the function only once after repeated calls. Loop doesn't run if the game is paused.

func void FF_ApplyOnceExtGT(var func function, var int delay, var int cycles)
-
Parameters
  • var func function
    Name of the function
  • var int delay
    Delay between calls in milliseconds (0 = every frame)
  • var int cycles
    How many times should the function be called (-1 = endless)

FF_ApplyOnceExtData

Alias to FF_ApplyExtData, which adds the function with the specified parameter only once, after repeated calls.

func void FF_ApplyOnceExtData(var func function, var int delay, var int cycles, var int data)
-
Parameters
  • var func function
    Name of the function
  • var int delay
    Delay between calls in milliseconds (0 = every frame)
  • var int cycles
    How many times should the function be called (-1 = endless)
  • var int data
    Value passed to the function as a parameter

FF_Active

Checks whether the function is active.

func int FF_Active(var func function)
-
Parameters
  • var func function
    Name of the function

Return value The function returns TRUE if the function is active, FALSE if it is not.

FF_ActiveData

Checks whether the function with the specified data is active.

func int FF_ActiveData(var func function, var int data)
-
Parameters
  • var func function
    Name of the function
  • var int data
    Value previously passed to the function

Return value The function returns TRUE if the function is active, FALSE if it is not.

FF_Remove

Stops a specific FrameFunction.

func void FF_Remove(var func function)
-
Parameters
  • var func function
    Name of the stopped function

FF_RemoveAll

Stops all intsnces of a specific FrameFunction.

func void FF_RemoveAll(var func function)
-
Parameters
  • var func function
    Name of the stopped function

FF_RemoveData

Stops a specific FrameFunction, with the specified value (see FF_ApplyExtData ).

func void FF_RemoveData(var func function, var int data)
-
Parameters
  • var func function
    Name of the stopped function
  • var int data
    Value previously passed to the function as a parameter

Examples

A function called every frame

In this example function MyFunc will be executed on every frame.

1
-2
-3
-4
-5
-6
func void Example1()
-{
-    FF_Apply(MyFunc);
-};
-
-func void MyFunc() {};
-
After the Example1 function is executed the function MyFunc is called on every frame.

The easiest and best way to run a function from the beginning is to call FF-Apply directly in the Init_Global (under LeGo_Init), there is a small problem: If the game is loaded, Init_Global is called a second time, the function is added to the list again and is therefore always called twice.

To avoid this effect, you should check whether the function is already active:

1
-2
-3
-4
-5
-6
-7
func void Example1()
-{
-    if(!FF_Active(MyFunc))
-    {
-        FF_Apply(MyFunc);
-    };
-};
-

However, since LeGo version 2.2 there is an even more pleasant method to do this:

1
-2
-3
-4
func void Example1()
-{
-    FF_ApplyOnce(MyFunc);
-};
-
FF_ApplyOnce function already implements the check for function activity.

Calling delayed function

Create a function, that is called once after 3 seconds.

1
-2
-3
-4
-5
-6
func void Example2()
-{
-    FF_ApplyExt(MyFunc2, 3000, 1); // 3000 ms = 3 s, this function is called only once
-};
-
-func void MyFunc2() {};
-

There is also a Once variant of this function, that prevents adding it twice into the frame function list.

1
-2
-3
-4
func void Example2()
-{
-    FF_ApplyOnceExt(MyFunc2, 3000, 1);
-};
-

Note

FF_ApplyExt(MyFunc, 0, -1) is the same as FF_Apply(MyFunc).

FrameFunction with Timer

Since LeGo 2.2, FrameFunctions package uses the Timer package, so it is possible to pause FrameFunctions at will:

1
-2
-3
-4
-5
-6
-7
-8
-9
func void Example3()
-{
-    FF_ApplyOnceExt(MyFunc3, 4000, 2);
-};
-
-func void MyFunc3()
-{
-    Timer_SetPaused(!Timer_GetPaused());
-};
-
This would pause the timer after 4 seconds and let it continue after 8 seconds.

Warning

Because the timer doesn't run, the frame function execution is stopped as well. This script won't work. If the timer is to be paused, it must be paused outside FrameFunctions.

Note

This is translation of article originally written by Gottfried and Lehona and hosted on LeGo's official documentation website.

\ No newline at end of file diff --git a/zengin/scripts/extenders/lego/tools/hashtables/index.html b/zengin/scripts/extenders/lego/tools/hashtables/index.html deleted file mode 100644 index 987989a91f..0000000000 --- a/zengin/scripts/extenders/lego/tools/hashtables/index.html +++ /dev/null @@ -1,146 +0,0 @@ - Hashtables - Gothic Modding Community

Hashtables

Hashtables package is an implementation of hashtables in Gothic. Currently (version 2.8.0) only integers are supported as keys. The Hashtables grow automatically.

Dependencies

Initialization

Initialize with LeGo_PermMem flag.

LeGo_Init(LeGo_PermMem);
-

Implementation

Hashtable.d on GitHub

Functions

HT_CreateSized

Generates a hashtable of the specified size.

func int HT_CreateSized(var int size)
-
Parameters
  • var int size
    Size of the hashtable to be created

Return value

The function returns a handle to the created hashtable.

HT_Create

Generates a standard size hashtable.

func int HT_Create()
-
Return value

The function returns a handle to the created hashtable.

HT_Insert

Inserts a value into the Hashtable.

func void HT_Insert(var int handle, var int val, var int key)
-
Parameters
  • var int handle
    Handle of a hashtable
  • var int val
    The value to be inserted
  • var int key
    The key associated with the value

HT_Resize

Changes the size of the hashtable (usually not necessary as it happens automatically).

func void HT_Resize(var int handle, var int size)
-
Parameters
  • var int handle
    Handle of a hashtable
  • var int size
    The new size of the hashtable

HT_Get

Reads a value from the hashtable.

func int HT_Get(var int handle, var int key)
-
Parameters
  • var int handle
    Handle of a hashtable
  • var int key
    The key whose value is to be read

Return value

The function returns the value associated with the key.

HT_Has

Checks if the key already exist in hashtable.

func int HT_Has(var int handle, var int key)
-
Parameters
  • var int handle
    Handle of a hashtable
  • var int key
    The key to be checked Return value

The function returns TRUE if the key exist, FALSE is returned otherwise.

HT_Remove

Removes a key from the hashtable.

func void HT_Remove(var int handle, var int key)
-
Parameters
  • var int handle
    Handle of a hashtable
  • var int key
    The key to be removed

HT_Change

Changes the value of a key already existing in the hashtable.

func void HT_Change(var int handle, var int val, var int key)
-
Parameters
  • var int handle
    Handle of a hashtable
  • var int val
    The new value
  • var int key
    The key whose value is to be changed

HT_InsertOrChange

Inserts a value into the Hashtable, or changes the value if the key already exist into hashtable.

func void HT_InsertOrChange(var int handle, var int val, var int key)
-
Parameters
  • var int handle
    Handle of a hashtable
  • var int val
    The new value
  • var int key
    The key whose value is to be changed or associated with the value.

HT_GetNumber

Returns the number of entries in a hashtable.

func int HT_GetNumber(var int handle)
-
Parameters
  • var int handle
    Handle of a hashtable

Return value

The function returns the number of entries in the hashtable.

HT_ForEach

Performs a function for each value pair in the hashtable.

func void HT_ForEach(var int handle, var func fnc)
-
Parameters
  • var int handle
    Handle of a hashtable
  • var func fnc
    A function with signature void (int key, int val)

HT_Destroy

Deletes the hashtable.

func void HT_Destroy(var int handle)
-
Parameters
  • var int handle
    The handle of the hashtable to be deleted

Examples

Simple operations

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
-37
-38
-39
-40
-41
-42
-43
-44
-45
-46
-47
-48
-49
-50
func void PrintKeyValuePair(var int key, var int val)
-{
-    Print(ConcatStrings(ConcatStrings("Key: ", IntToString(key)), ConcatStrings(", Value: ", IntToString(val))));
-};
-
-func void example()
-{
-    // Create a new hashtable
-    var int hashtableHandle; hashtableHandle = HT_Create();
-
-    // Insert values into the hashtable
-    HT_Insert(hashtableHandle, 42, 1);
-    HT_Insert(hashtableHandle, 23, 2);
-    HT_Insert(hashtableHandle, 56, 3);
-
-    // Get a value from the hashtable
-    var int value; value = HT_Get(hashtableHandle, 2);
-    Print(ConcatStrings("Value associated with key 2: ", IntToString(value)));
-
-    // Check if a key exists in the hashtable
-    if (HT_Has(hashtableHandle, 3))
-    {
-        Print("Key 3 exists in the hashtable.");
-    }
-    else
-    {
-        Print("Key 3 does not exist in the hashtable.");
-    };
-
-    // Remove a key from the hashtable
-    HT_Remove(hashtableHandle, 1);
-
-    // Change the value associated with a key
-    HT_Change(hashtableHandle, 99, 3);
-
-    // Insert a value or change it if the key exists
-    HT_InsertOrChange(hashtableHandle, 123, 4);
-
-    // Get the number of entries in the hashtable
-    var int numEntries; numEntries = HT_GetNumber(hashtableHandle);
-    Print(ConcatStrings("Number of entries in the hashtable: ", IntToString(numEntries)));
-
-
-    // Iterate through the hashtable and print key-value pairs
-    // Function from top of the example is used here
-    HT_ForEach(hashtableHandle, PrintKeyValuePair);
-
-    // Destroy the hashtable
-    HT_Destroy(hashtableHandle);
-};
-
\ No newline at end of file diff --git a/zengin/scripts/extenders/lego/tools/hook_dae/index.html b/zengin/scripts/extenders/lego/tools/hook_dae/index.html deleted file mode 100644 index df3f1fda07..0000000000 --- a/zengin/scripts/extenders/lego/tools/hook_dae/index.html +++ /dev/null @@ -1,244 +0,0 @@ - HookDaedalus - Gothic Modding Community

HookDaedalus

This package allows hooking daedalus functions. The principle is similar HookEngine. We have a function (hooked function) into which we would like to hook another function (hook function).

Tip

Having to hook a Daedalus function should be pretty rare, because you can simply adjust the corresponding function. However, it may become necessary in some contexts.

Dependencies

N/A

Initialization

N/A

Implementation

HookDaedalus.d on GitHub

Functions

HookDaedalusFunc

Hooks the function.

func void HookDaedalusFunc(var func hooked, var func hook)
-
Parameters
  • var func hooked
    Hooked function
  • var func hook
    Hook function

HookDaedalusFuncF

Alias to the HookDaedalusFunc function.

func void HookDaedalusFuncF(var func hooked, var func hook)
-
Parameters
  • var func hooked
    Hooked function
  • var func hook
    Hook function

HookDaedalusFuncI

HookDaedalusFunc but with function ID.

func void HookDaedalusFuncI(var int hookedID, var int hookID)
-
Parameters
  • var int hookedID
    ID of hooked function
  • var int hookID
    ID of hook function

HookDaedalusFuncS

HookDaedalusFunc but with function name.

func void HookDaedalusFuncS(var string hookedName, var string hookName)
-
Parameters
  • var string hookedName
    Name of hooked function
  • var string hookName
    Name of hook function

IsHookD

Checks whether a function is already hooking another. Each function can be hooked any number of times, but each function can only hook one other.

func int IsHookD(var int funcID)
-
Parameters
  • var int funcID Symbol index of a hook function

Return value

The function returns TRUE if the function is already hooking another, FALSE is returned otherwise.

ContinueCall

Continues the program run with the original function.

func void ContinueCall()
-

PassArgumentI

Passes an integer as an argument to the original function. Must be called before ContinueCall.

func void PassArgumentI(var int i)
-
Parameters
  • var int i
    Integer argument to forward

PassArgumentS

Passes a string as an argument to the original function. Must be called before ContinueCall.

func void PassArgumentS(var string s)
-
Parameters
  • var string s
    String argument to forward

PassArgumentN

Passes an instance as an argument to the original function. Must be called before ContinueCall.

func void PassArgumentN(var instance n)
-
Parameters
  • var instance n
    Instance argument to forward

Examples

Hook before function

We have a hook:

HookDaedalusFunc(hooked, hook);
-
The functions can look like that:
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
func void hooked() 
-{
-    Print("Original function");
-};
-
-func void hook() 
-{
-    Print("Our hook");
-    ContinueCall();
-};
-
The results should look like that
1
-2
Our hook
-Original function
-

Hook after function

We have the same hook:

HookDaedalusFunc(hooked, hook);
-
The functions are also similar, but the ContinueCall(); is called first:
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
func void hooked() 
-{
-    Print("Original function");
-};
-
-func void hook() 
-{
-    ContinueCall();
-    Print("Our hook");
-};
-
The results should look like that:
1
-2
Original function
-Our hook
-

Arguments and return values

If a function to be hooked expects parameters or returns a value, our hooking function should conform to that.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
func int hooked(var int i) 
-{
-     Print("Original function");
-     return i+1;
-};
-
-func int hook(var int i) 
-{
-     Print("Our hook");
-     PassArgumentI(i);
-     ContinueCall();
-};
-
In this case, we may not return the value at the end of the hook because the returned value will just stay on the stack. However, we shouldn't give up on calling PassArgumentI(i) to ensure that it is still on top of the stack when the program continues with hooked.

Manipulation of arguments and return values

We can also manipulate arguments and return values with our hook.

1
-2
-3
-4
-5
-6
-7
-8
-9
func int hook(var int i) 
-{
-    Print("Our hook");
-    PassArgumentI(i+1);     // add 1
-    ContinueCall();
-    i = MEM_PopIntResult();
-    i *= 2;                 // Multiply by 2
-    return i;
-};
-

Multiple hooks

A function can be hooked any number of times, but each function can only hook one. New hooks are always inserted after the previous one. The following example illustrates this quite well.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
-37
-38
-39
-40
-41
-42
-43
-44
-45
-46
-47
-48
-49
-50
-51
-52
-53
-54
-55
-56
-57
-58
HookDaedalusFunc(a, b); // B hooks A
-HookDaedalusFunc(a, c); // C hooks A to B
-HookDaedalusFunc(a, d); // D hooks A to C
-
-HookDaedalusFunc(c, b); // Ignored because B is already hooking a function
-
-var int i; i = a(1);
-
-
-// Hooked function
-func int a(var int i) 
-{
-    MEM_Info(ConcatStrings("---  A: ", IntToString(i)));
-    return i+1;
-};
-
-// First hook function:
-// Replaces `a` because the program run is not continued with ContinueCall
-func int b(var int i) 
-{
-    MEM_Info(ConcatStrings("  -- B: ", IntToString(i)));
-    return i;
-};
-
-// Second hook function:
-// Increments the argument before ContinueCall and then decrements the return value
-func int c(var int i) 
-{
-    MEM_Info(ConcatStrings(" -> C: ", IntToString(i)));
-    passArgumentI(i+1);
-    ContinueCall();
-
-    i = MEM_PopIntResult();
-    i -= 1;
-    MEM_Info(ConcatStrings(" <- C: ", IntToString(i)));
-    return i;
-};
-
-// Third hook function:
-// Increments the argument before ContinueCall and then decrements the return value
-func int d(var int i) 
-{
-    MEM_Info(ConcatStrings("-> D: ", IntToString(i)));
-    passArgumentI(i+1);
-    ContinueCall();
-
-    i = MEM_PopIntResult();
-    i -= 1;
-    MEM_Info(ConcatStrings("<- D: ", IntToString(i)));
-    return i;
-};
-
-// Output:
-// -> D: 1
-//  -> C: 2
-//   -- B: 3
-//  <- C: 2
-// <- D: 1
-
\ No newline at end of file diff --git a/zengin/scripts/extenders/lego/tools/hook_engine/index.html b/zengin/scripts/extenders/lego/tools/hook_engine/index.html deleted file mode 100644 index 1213a14976..0000000000 --- a/zengin/scripts/extenders/lego/tools/hook_engine/index.html +++ /dev/null @@ -1,66 +0,0 @@ - HookEngine - Gothic Modding Community

HookEngine

This package allows you to hook anywhere in an engine function to run your own Daedalus code.

Tip

Zerxes has provided a list of all engine functions for G2, including the number of bytes to fill in for oldInstr. This list can be found here. This should make it possible for everyone to use the HookEngine effectively without IDA.

Dependencies

N/A

Initialization

N/A

Implementation

HookEngine.d on GitHub

Functions

HookEngine

Attaches a function to an engine function address.

func void HookEngine(var int address, var int oldInstr, var string function)
-
Parameters
  • var int address
    Address of an engine function to which the function should be attached.
  • var int oldInstr
    The length in bytes of the instruction to be found at address, at least 5 bytes. Can be seen in IDA.
  • var string function
    Name of Daedalus function to be called.

HookEngineS

Alias to the HookEngine function.

func void HookEngineS(var int address, var int oldInstr, var string function)
-
Parameters
  • var int address
    Address of an engine function to which the function should be attached.
  • var int oldInstr
    The length in bytes of the instruction to be found at address, at least 5 bytes. Can be seen in IDA.
  • var string function
    Name of Daedalus function to be called.

HookEngineI

Alias to HookEngine with funcID.

func void HookEngineI(var int address, var int oldInstr, var int funcID)
-
Parameters
  • var int address
    Address of an engine function to which the function should be attached.
  • var int oldInstr
    The length in bytes of the instruction to be found at address, at least 5 bytes. Can be seen in IDA.
  • var int funcID
    ID of Daedalus function to be called.

HookEngineF

Alias to HookEngine with func parameter.

func void HookEngineF(var int address, var int oldInstr, var func function)
-
Parameters
  • var int address
    Address of an engine function to which the function should be attached.
  • var int oldInstr
    The length in bytes of the instruction to be found at address, at least 5 bytes. Can be seen in IDA.
  • var func function
    Daedalus function to be called.

IsHooked

Checks if a hook is already present at a given address.

func var int IsHooked(var int address)
-
Parameters
  • var int address
    Address of an engine function.

Return value

The function returns TRUE if the hook already exists at the address, FALSE is returned otherwise.

IsHook

Checks if a hook with a certain function is already present at an address.

func var int IsHook(var int address, var string function)
-
Parameters
  • var int address
    Address of an engine function.
  • var string function
    Name of a function.

Return value

The function returns TRUE if the hook already exists at the address, FALSE is returned otherwise.

IsHookI

Alias to IsHook with a funcID as parameter.

func var int IsHookI(var int address, var int funcID)
-
Parameters
  • var int address
    Address of an engine function.
  • var int funcID
    ID of a function.

Return value

The function returns TRUE if the hook already exists at the address, FALSE is returned otherwise.

IsHookF

Alias to IsHook with a function as parameter.

func var int IsHookF(var int address, var func function)
-
Parameters
  • var int address
    Address of an engine function.
  • var func function
    Daedalus function.

Return value func parameter The function returns TRUE if the hook already exists at the address, FALSE is returned otherwise.

RemoveHook

Removes a function from a hook so that it is no longer called.

func void RemoveHook(var int address, var int oldInstr, var string function)
-
Parameters
  • var int address
    Address of an engine function to which the function should be attached.
  • var int oldInstr
    The length in bytes of the instruction to be found at address, at least 5 bytes. Can be seen in IDA.
  • var string function
    Name of Daedalus function that should no longer be called.

RemoveHookI

Alias to RemoveHook with funcID.

func void RemoveHook(var int address, var int oldInstr, var int funcID)
-
Parameters
  • var int address
    Address of an engine function to which the function should be attached.
  • var int oldInstr
    The length in bytes of the instruction to be found at address, at least 5 bytes. Can be seen in IDA.
  • var int funcID
    ID of Daedalus function that should no longer be called.

RemoveHookF

Alias for RemoveHook with func parameter.

func void RemoveHook(var int address, var int oldInstr, var func function)
-
Parameters
  • var int address
    Address of an engine function to which the function should be attached.
  • var int oldInstr
    The length in bytes of the instruction to be found at address, at least 5 bytes. Can be seen in IDA.
  • var func function
    Daedalus function that should no longer be called.

ReplaceEngineFunc

Replaces an engine function with a Daedalus function.

func void ReplaceEngineFunc(var int address, var int thiscall_numparams, var string replaceFunc)
-
Parameters
  • var int address
    Address of the engine function to be replaced.
  • var int thiscall_numparams
    Number of parameters passed to the engine function, if it is a stdcall or thiscall (otherwise 0).
  • var string replaceFunc
    Name of a Daedalus function to be called instead.

ReplaceEngineFuncI

Alias to ReplaceEngineFunc with funcID.

func void ReplaceEngineFunc(var int address, var int thiscall_numparams, var int funcID)
-
Parameters
  • var int address
    Address of the engine function to be replaced.
  • var int thiscall_numparams
    Number of parameters passed to the engine function, if it is a stdcall or thiscall (otherwise 0).
  • var int funcID
    ID of a Daedalus function to be called instead.

ReplaceEngineFuncF

Alias to ReplaceEngineFunc with func parameter.

func void ReplaceEngineFunc(var int address, var int thiscall_numparams, var func function)
-
Parameters
  • var int address
    Address of the engine function to be replaced.
  • var int thiscall_numparams
    Number of parameters passed to the engine function, if it is a stdcall or thiscall (otherwise 0).
  • var func function
    Daedalus function to be called instead.

DisableEngineFunc

Makes sure that an engine function is simply skipped. This is very delicate and will not always work so easily.

func void DisableEngineFunc(var int address, var int thiscall_numparams)
-
Parameters
  • var int address
    Address of the engine function to be skipped.
  • var int thiscall_numparams
    Number of parameters passed to the engine function, if it is a stdcall or thiscall (otherwise 0).

Hook_ReturnFalse

Simple function to replace return FALSE in hook.

func void Hook_ReturnFalse()
-

Hook_ReturnTrue

Simple function to replace return TRUE in hook.

func void Hook_ReturnTrue()
-

Registers

In addition the HookEngine package implement x86 32-bit registers that can be used to access hooked function parameters.

1
-2
-3
-4
-5
-6
-7
-8
var int EAX;
-var int ECX;
-var int EDX;
-var int EBX;
-var int ESP;
-var int EBP;
-var int ESI;
-var int EDI;    
-
\ No newline at end of file diff --git a/zengin/scripts/extenders/lego/tools/int64/index.html b/zengin/scripts/extenders/lego/tools/int64/index.html deleted file mode 100644 index 72354d1501..0000000000 --- a/zengin/scripts/extenders/lego/tools/int64/index.html +++ /dev/null @@ -1,58 +0,0 @@ - Int64 - Gothic Modding Community

Int64

Int64 implements basic arithmetic for 64-bit integers based on machine code (hence the function signatures are also in machine code style). Furthermore, Int64 offers the constructor int64@ for Int64 objects, but mk64 expects a pointer, not a handle.

Dependencies

N/A

Initialization

N/A

Implementation

Int64.d on GitHub

Functions

mk64

Writes lo and hi in one place (dest). Makes Int64, hi has to be -1 for negative 32bit lo.

func void mk64(var int dest, var int hi, var int lo)
-
Parameters
  • var int dest
    A pointer to an Int64 object or just 8 bytes of free memory.
  • var int hi
    High part of integer.
  • var int lo
    Low part of integer.
Examples

Function looks like that:

1
-2
-3
-4
    func void mk64(var int dest, var int lo, var int hi) {
-    MEM_WriteInt(dest, lo);
-    MEM_WriteInt(dest+4, hi);
-    };
-
So if you want to get 9876543210 low part should be set to 1286608618 and the high part to 2
1
-2
-3
-4
-5
-6
var int ptr; ptr = MEM_Alloc(8);
-var int low; low = 1286608618;
-var int high; high = 2;
-mk64(ptr, low, high);
-// ...
-MEM_Free(ptr);
-

neg64

Negates the integer: *dest <- -(*dest)

func void neg64(var int dest)
-
Parameters
  • var int dest
    A pointer to an Int64 object or just 8 bytes of free memory.

add64

Adds src to dest: *dest <- *dest + *src

func void add64(var int dest, var int src)
-
Parameters
  • var int dest
    A pointer to an Int64 object or just 8 bytes of free memory. Will be changed.
  • var int src
    A pointer to an Int64 object. Will not change.

sub64

Subtracts src from dest: *dest <- *dest - *src

func void sub64(var int dest, var int src)
-
Parameters
  • var int dest
    A pointer to an Int64 object or just 8 bytes of free memory. Will be changed.
  • var int src
    A pointer to an Int64 object. Will not change.

mul64

Multiplies dest by src: *dest <- (*dest) * (*src)

func void mul64(var int dest, var int src)
-
Parameters
  • var int dest
    A pointer to an Int64 object or just 8 bytes of free memory. Will be changed.
  • var int src
    A pointer to an Int64 object. Will not change.

div64

Divides dest by src: *dest <- *dest / *src

func void mul64(var int dest, var int src)
-
Parameters
  • var int dest
    A pointer to an Int64 object or just 8 bytes of free memory. Will be changed.
  • var int src
    A pointer to an Int64 object. Will not change.
\ No newline at end of file diff --git a/zengin/scripts/extenders/lego/tools/interface/index.html b/zengin/scripts/extenders/lego/tools/interface/index.html deleted file mode 100644 index 26863d48dd..0000000000 --- a/zengin/scripts/extenders/lego/tools/interface/index.html +++ /dev/null @@ -1,249 +0,0 @@ - Interface - Gothic Modding Community

Interface

This package offers a lot of useful functions to work with the 2D interface.

Dependencies

Initialization

Initialize with LeGo_Interface and LeGo_PrintS flag.

LeGo_Init(LeGo_Interface | LeGo_PrintS);
-

Implementation

Interface.d on GitHub

Functions

sysGetTime

Better alternative for MEM_GetSysTime() from Ikarus.

func int sysGetTime()
-
Return value

The function returns elapsed time since game (system) startup.

RGBA

Generates a full zColor.

func int RGBA(var int r, var int g, var int b, var int a)
-
Parameters
  • var int r
    Red channel value (0..255)
  • var int g
    Green channel value (0..255)
  • var int b
    Blue channel value (0..255)
  • var int a
    Alpha (0..255, 0 = invisible)

Return value

The function returns a zColor object.

ChangeAlpha

Overrides the alpha value of a given zColor.

func int ChangeAlpha(var int zCol, var int a)
-
Parameters
  • var int zCol
    zColor to modify
  • var int a
    New alpha value

Return value

The function returns a modified zColor object.

GetAlpha

Returns the alpha value of a given zColor.

func int GetAlpha(var int zCol)
-
Parameters
  • var int zCol
    zColor to get alpha from

Creates a new zCViewText on the screen with PermMem that can be freely edited.

func int Print_CreateText(var string text, var string font)
-
Parameters
  • var string text
    The text of the zCViewText
  • var string font
    Font of text

Return value

The function returns a handle to zCViewText.

Print_CreateText but returns pointer to zCViewText instead of handle.

func int Print_CreateTextPtr(var string text, var string font)
-
Parameters
  • var string text
    The text of the zCViewText
  • var string font
    Font of text

Return value

The function returns a pointer to zCViewText.

Print_CreateTextPtr but with additional parameter to chose color of text.

func int Print_CreateTextPtrColored(var string text, var string font, var int color)
-
Parameters
  • var string text
    The text of the zCViewText
  • var string font
    Font of text
  • var int color
    zColor e.g. generated with RGBA function

Return value

The function returns a pointer to zCViewText.

Returns zCViewText instance from handle.

func zCViewText Print_GetText(var int hndl)
-
Parameters
  • var int hndl
    Handle to zCViewText

Returns zCViewText pointer from handle.

func int Print_GetTextPtr(var int hndl)
-
Parameters
  • var int hndl
    Handle to zCViewText

Removes a zCViewText from the screen.

func void Print_DeleteText(var int hndl)
-
Parameters

Changes the alpha value of a given zCViewText.

func void Print_SetAlpha(var int hndl, var int a)
-
Parameters
  • var int hndl
    Handle to zCViewText
  • var int a
    New alpha value

PrintPtr_SetAlpha

Print_SetAlpha but with pointer to zCViewText instead of handle.

func void PrintPtr_SetAlpha(var int ptr, var int a)
-
Parameters
  • var int ptr
    Pointer to zCViewText
  • var int a
    New alpha value

Writes the current resolution to the Print_Screen array and the current aspect ratio to Print_Ratio variable.

func void Print_GetScreenSize()
-

An int array holding the current resolution. (Filled by Print_GetScreenSize)

int Print_Screen[2];
-
  • Print_Screen[PS_X] is the horizontal resolution

  • Print_Screen[PS_Y] is the vertical resolution

A float variable that holds the current aspect ratio. (Filled by Print_GetScreenSize)

int Print_Ratio;
-

PS_VMax

An int constant that holds the highest possible value of a virtual coordinate.

const int PS_VMax = 8192;
-

Convents pixel position to a virtual position.

func int Print_ToVirtual(var int pxl, var int dim)
-
Parameters
  • var int pxl
    Pixel position to convert
  • var int dim
    PS_X or PS_Y (see Print_Screen)

Return value

The function returns a virtual position of a given pixel position.

Print_ToVirtual but returns Ikarus float value instead of integer.

func int Print_ToVirtualF(var int pxl, var int dim)
-
Parameters
  • var int pxl
    Pixel position to convert
  • var int dim
    PS_X or PS_Y (see Print_Screen)

Return value

The function returns a virtual position of a given pixel position as Ikarus float.

Convents virtual position to a pixel position.

func int Print_ToPixel(var int vrt, var int dim)
-
Parameters
  • var int vrt
    Virtual position to convert
  • var int dim
    PS_X or PS_Y (see Print_Screen)

Return value

The function returns a pixel position of a given virtual position.

Print_ToPixel but returns Ikarus float value instead of integer.

func int Print_ToPixelF(var int vrt, var int dim)
-
Parameters
  • var int vrt
    Virtual position to convert
  • var int dim
    PS_X or PS_Y (see Print_Screen)

Return value

The function returns a pixel position of a given virtual position as Ikarus float.

Gets the size in the specified dimension in ratioed by the screen.

func int Print_ToRatio(var int size, var int dim)
-
Parameters
  • var int size
    Size to convert
  • var int dim
    PS_X or PS_Y (see Print_Screen)

Return value

The function returns size correctly calculated to the ratio.

Example

If you have a view and the view you need to be a square of 400 units, you would do:

1
-2
height = Print_ToRatio(400, PS_Y);
-width = 400;
-
This is because width is always the max in virtual coordinates - 8192 virtual points and the height has a different height based on the ratio, this function calculates it for you.

PS_X can be used in function, if you already have the height but need the width in the correct ratio.

Converts angle in degrees to radians.

func int Print_ToRadian(var int angle)
-
Parameters
  • var int angle
    Angle in degrees

Return value

The function returns calculated angle in radians.

Converts angle in radians to degrees.

func int Print_ToDegree(var int angle)
-
Parameters
  • var int angle
    Angle in radians

Return value

The function returns calculated angle in degrees.

Returns a pointer to a zCFont by its name.

func int Print_GetFontPtr(var string font)
-
Parameters
  • var string font
    Name of font

Returns a name of a zCFont from its pointer.

func string Print_GetFontName(var int fontPtr)
-
Parameters
  • var int fontPtr
    Pointer to font

Returns the width of a string in pixels.

func int Print_GetStringWidth(var string s, var string font)
-
Parameters
  • var string s
    Measured string
  • var string font
    Name of font

Print_GetStringWidth but with zCFont pointer instead of name.

func int Print_GetStringWidthPtr(var string s, var int font)
-
Parameters
  • var string s
    Measured string
  • var int font
    zCFont pointer

Returns the height of a string in pixels.

func int Print_GetFontHeight(var string font)
-
Parameters
  • var string font
    Name of font

Like the external PrintScreen, writes a text on the screen, but with more options.

func int Print_Ext(var int x, var int y, var string text, var string font, var int color, var int time)
-
Parameters
  • var int x
    X coordinate on the screen (virtual)
  • var int y
    Y coordinate on the screen (virtual)
  • var string text
    Displayed text
  • var string font
    Name of font
  • var int color
    zColor e.g. generated with RGBA function
  • var int time
    display time in milliseconds (-1 = permanent)

Return value

If time == -1, a valid handle is returned. If time != -1, the print is only volatile and no handle is returned.

Example
1
-2
-3
-4
-5
func void Example1()
-{
-    //           x, y, text,   font,        color,                time
-    Print_ExtPxl(2, 2, "Text", FONT_Screen, RGBA(255, 0, 0, 128), 500);
-};
-

Print_Ext but with pixel coordinates instead of virtual.

func int Print_ExtPxl(var int x, var int y, var string text, var string font, var int color, var int time)
-
Parameters
  • var int x
    X coordinate on the screen (pixel)
  • var int y
    Y coordinate on the screen (pixel)
  • var string text
    Displayed text
  • var string font
    Name of font
  • var int color
    zColor e.g. generated with RGBA function
  • var int time
    display time in milliseconds (-1 = permanent)

Return value

If time == -1, a valid handle is returned. If time != -1, the print is only volatile and no handle is returned.

Returns the longest line from text as a string, using default line separator tilde ~.

func string Print_LongestLine(var string text, var string font)
-
Parameters
  • var string text
    Measured text
  • var string font
    Name of font

Returns the longest line from text as a string, but you specify new line separator.

func string Print_LongestLineExt(var string text, var string font, var string separator)
-
Parameters
  • var string text
    Measured text
  • var string font
    Name of font
  • var string separator
    New line separator

Returns the longest line width in pixels, using default line separator tilde ~.

func int Print_LongestLineLength(var string text, var string font)
-
Parameters
  • var string text
    Measured text
  • var string font
    Name of font

Returns the longest line width in pixels, but allows you to specify new line separator.

func int Print_LongestLineLengthExt(var string text, var string font, var string separator)
-
Parameters
  • var string text
    Measured text
  • var string font
    Name of font
  • var string separator
    New line separator

Creates a text field (view with text) using virtual coordinates.

func int Print_TextField(var int x, var int y, var string text, var string font, var int height)
-
Parameters
  • var int x
    X coordinate (virtual)
  • var int y
    Y coordinate (virtual)
  • var string text
    Text to be printed
  • var string font
    Name of font
  • var int height
    A specific line height

Return value

The function returns a text field pointer. Here is how it is used:

1
-2
var zCView view; view = get(viewHndl);
-view.textLines_next = Print_TextField(x, y, text, FONT, fontHeight);
-

Print_TextField but with pixel coordinates.

func int Print_TextFieldPxl(var int x, var int y, var string text, var string font)
-
Parameters
  • var int x
    X coordinate (pixel)
  • var int y
    Y coordinate (pixel)
  • var string text
    Text to be printed
  • var string font
    Name of font

Return value

The function returns a text field pointer. Look at the Print_TextField return value to see an example.

Print_TextField but you specify the color of text.

func int Print_TextFieldColored(var int x, var int y, var string text, var string font, var int height, var int color)
-
Parameters
  • var int x
    X coordinate (virtual)
  • var int y
    Y coordinate (virtual)
  • var string text
    Text to be printed
  • var string font
    Name of font
  • var int height
    A specific line height
  • var int color
    zColor e.g. generated with RGBA function

Return value

The function returns a text field pointer. Look at the Print_TextField return value to see an example.

PrintS

Same function as the external Print, but with smooth animations. The effect can be changed as desired with the user constants.

func void PrintS(var string txt)
-
Parameters
  • var string txt
    Printed text

PrintS_Ext

PrintS but with an additional parameter to choose the color of the text.

func void PrintS_Ext(var string txt, var int color)
-
Parameters
  • var string txt
    Printed text
  • var int color
    zColor e.g. generated with RGBA function

AI_PrintS

Version of PrintS that enqueue in given NPCs AI queue.

func void AI_PrintS(var c_npc slf, var string txt)
-
Parameters
  • var c_npc slf
    NPC to whose AI queue the function is enqueued
  • var string txt
    Printed text

AI_PrintS_Ext

Version of PrintS_Ext that enqueue in given NPCs AI queue.

func void AI_PrintS_Ext(var c_npc slf, var string txt, var int color)
-
Parameters
  • var c_npc slf
    NPC to whose AI queue the function is enqueued
  • var string txt
    Printed text
  • var int color
    zColor e.g. generated with RGBA function

Examples

Manage a print via zCViewText

It is also possible to create the text only via Print_CreateText and set it yourself. In this example, a text should fly over the image from left to right and be deleted again. The movement is handled by Anim8:

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
var int MyText;
-var int MyAnim8;
-func void PrintMyScrollingText(var string text) {
-    MyText = Print_CreateText(text, FONT_Screen); // We create an empty text item with the font FONT_Screen
-
-    var zCViewText MyTextObject; MyTextObject = Print_GetText(MyText); // Now we get the empty text item in a zCViewText
-
-    MyTextObject.posx = 1;      // adjust position
-    MyTextObject.posy = 1;      // ATTENTION: These values are virtual, i.e.: 0 = far left, 8192 = far right (i.e. no pixel specification)
-                                // (But if I prefer to have pixel coordinates I could use e.g. Print_ToVirtual)
-    MyTextObject.timed = false; // The text should not be timed (not disappear)
-
-    // Anim8 will animate a text
-    // First we need a new Anim8 object:
-    MyAnim8 = Anim8_New(1, false); // Start position is 1 and this value is not a float
-
-    Anim8(MyAnim8, 8192, 2000, A8_Constant); // Target Position is 8192, Duration is 2000 milliseconds, and Movement Form is Constant
-
-    // Now all we need is a loop that matches the x value of the text to the value of Anim8:
-    FF_Apply(ScrollMyText);
-};
-
-func void ScrollMyText() {
-    var zCViewText MyTextObject; MyTextObject = Print_GetText(MyText); // Get the text as an object again
-
-    // And now compare the values:
-    MyTextObject.posx = Anim8_Get(MyAnim8);
-
-    // When Anim8 is done with that, we end the loop and delete the text:
-    if(Anim8_Empty(MyAnim8)) {
-        Print_DeleteText(MyText);
-        FF_Remove(ScrollMyText);
-        // The Anim8 object must of course also be deleted. We don't need it anymore.
-        Anim8_Delete(MyAnim8);
-    };
-};
-

Manage a print via zCViewText with LeGo 2.2+

In those days it was perhaps pleasant, but today it is no longer. Anim8 has seen a few improvements with LeGo 2.2 that make it much easier to create the same effect:

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
-37
-38
-39
-40
-41
-42
-43
-44
var int MyText;
-var int MyAnim8;
-func void PrintMyScrollingText(var string text) {
-    // Create and set text:
-    MyText = Print_CreateText(text, FONT_Screen);
-
-    var zCViewText MyTextObject; MyTextObject = Print_GetText(MyText);
-
-    MyTextObject.posx = 1;
-    MyTextObject.posy = 1;
-
-    MyTextObject.timed = false;
-
-    // But now comes the trick: We use Anim8_NewExt, this allows us to set a "Handler" and "Data".
-    MyAnim8 = Anim8_NewExt(1, ScrollMyText, MyText, false);
-
-    // ScrollMyText is passed as the handler and MyText as the data.
-    // In concrete terms, this means: ScrollMyText is always called
-    // when Anim8 has recalculated the position.
-    // Pass data and the new position as parameters. Let's see how it goes.
-
-    // Set the animation again as usual:
-    Anim8(MyAnim8, 8192, 2000, A8_Constant);
-
-    // And this time no FrameFunction.
-    // Instead, we tell Anim8 to clean up by itself when it's done:
-    Anim8_RemoveIfEmpty(MyAnim8, true);
-
-    // The text should also disappear by itself:
-    Anim8_RemoveDataIfEmpty(MyAnim8, true);
-
-    // Since MyText is a handle, this will work.
-    // If MyText were a pointer, RemoveDataIfEmpty should not be activated, it would lead to an error message.
-};
-
-func void ScrollMyText(var int MyText, var int Position) {
-     // Get the text as an object again
-    var zCViewText MyTextObject; MyTextObject = Print_GetText(MyText);
-
-    // And now compare the values:
-    MyTextObject.posx = Position;
-
-    // Since Anim8 does the deleting itself, we don't have to worry about that.
-};
-
\ No newline at end of file diff --git a/zengin/scripts/extenders/lego/tools/item_helper/index.html b/zengin/scripts/extenders/lego/tools/item_helper/index.html deleted file mode 100644 index f0aee96788..0000000000 --- a/zengin/scripts/extenders/lego/tools/item_helper/index.html +++ /dev/null @@ -1,35 +0,0 @@ - ItemHelper - Gothic Modding Community

ItemHelper

This package is very simple - it retrieves a oCItem pointer from an C_ITEM instance valid for the current world and session.

Warning

Make sure every world has waypoint with name TOT ("dead" in German). Ikarus & LeGo need this waypoint to spawn helper NPCs.
This is especially important in Gothic 1 since G1 vanilla worlds do not have the TOT waypoint.

Dependencies

N/A

Initialization

N/A

Implementation

ItemHelper.d on GitHub

Functions

Itm_GetPtr

func int Itm_GetPtr(var int instance)
-
Parameters
  • var int instance
    C_ITEM instance to get the pointer of

Return value The function returns oCItem pointer of the C_ITEM instance.

\ No newline at end of file diff --git a/zengin/scripts/extenders/lego/tools/list/index.html b/zengin/scripts/extenders/lego/tools/list/index.html deleted file mode 100644 index be22f6719b..0000000000 --- a/zengin/scripts/extenders/lego/tools/list/index.html +++ /dev/null @@ -1,60 +0,0 @@ - List - Gothic Modding Community

List

The List package is a collection of functions designed to simplify the handling of zCList and zCListSort lists in daedalus. It offers a range of functions for creating, manipulating, and querying lists.

Dependencies

N/A

Initialization

N/A

Implementation

List.d on GitHub

Functions

Note

All functions, expect List_Compare come with an additional "S" at the end for objects of type zCListSort. (Example: List_NodeS .) Unlike most LeGo packages, pointers are used here, not handles!

List_Create

Creates a list with an initial value.

func int List_Create(var int data)
-
Parameters
  • var int data
    The value of the first list element.

Return value

The function returns a pointer to the created list.

List_Add

Appends a value to the end of the list.

func void List_Add(var int list, var int data)
-
Parameters
  • var int list
    The list to be used.
  • var int data
    The value to be appended.

List_AddFront

Adds a value before the first element of the list.

func void List_AddFront(var int list, var int data)
-
Parameters
  • var int list
    The list to be used.
  • var int data
    The value to be appended.

List_AddOffset

Inserts a value between two list elements.

func void List_AddOffset(var int list, var int offset, var int data)
-
Parameters
  • var int list
    The list to be used.
  • var int offset
    The number of the list element after which the value is inserted.
  • var int data
    The value to be appended.

List_Set

Sets a list element to a specific value.

func void List_Set(var int node, var int data)
-
Parameters
  • var int node
    Pointer to a list element.
  • var int data
    The value to be written into the list element.

List_Get

Retrieves the value of a list element.

func int List_Get(var int list, var int nr)
-
Parameters
  • var int list
    The list to be used.
  • var int nr
    The number of the list element.

Return value

The function returns the value of the specified list element.

List_Node

Returns a pointer to a list element.

func int List_Node(var int list, var int nr)
-
Parameters
  • var int list
    The list to be used.
  • var int nr
    The number of a list element.

Return value

The function returns a pointer to the specified list element.

List_Length

Returns the length of the list (number of all elements).

func int List_Length(var int list)
-
Parameters
  • var int list
    The list to be used.

Return value

The function returns the number of elements in the list.

List_HasLength

Checks if the list has the specified length.

func int List_HasLength(var int list, var int length)
-
Parameters
  • var int list
    The list to be used.
  • var int length
    The desired length.

Return value

The function returns a boolean value indicating whether the list has the specified length or not.

List_End

Returns the last list element of the list.

func int List_End(var int list)
-
Parameters
  • var int list
    The list to be used.

Return value

The function returns a pointer to the last list element.

List_Concat

Concatenates two lists.

func void List_Concat(var int list, var int list2)
-
Parameters
  • var int list
    The first list.
  • var int list2
    The second list. Its beginning is appended to the end of the first list.

List_Contains

Returns the last list element with a specific value.

func int List_Contains(var int list, var int data)
-
Parameters
  • var int list
    The list to be used.
  • var int data
    The value to search for.

Return value

The function returns the number of the last list element with the value data.

List_For

Calls a function for each list element, passing a pointer to the list element as a parameter.

func void List_For(var int list, var string function)
-
Parameters
  • var int list
    The list to be used.
  • var string function
    Name of a function to be called for each list element (void handler(var int node)).

List_ForF

Similar to List_For, but with a function parameter instead of a string.

func void ListForF(var int list, var func function)
-
Parameters
  • var int list
    The list to be used.
  • var func function
    The function to be called for each list element (void handler(var int node)).

List_ForI

Similar to List_For, but with a function parameter instead of a string.

func void List_ForI(var int list, var int funcID)
-
Parameters
  • var int list
    The list to be used.
  • var int funcID
    ID of a function to be called for each list element (void handler(var int node)).

List_Delete

Deletes a list element. All subsequent elements shift position.

func void List_Delete(var int list, var int nr)
-
Parameters
  • var int list
    The list to be used.
  • var int nr
    The number of the list element to be deleted.

List_Destroy

Destroys the entire list.

func void List_Destroy(var int list)
-
Parameters
  • var int list
    The list to be destroyed.

List_ToArray

Returns a pointer to a memory area containing all values of the list.

func int List_ToArray(var int list)
-
Parameters
  • var int list
    The list to be used.

Return value

The function returns a memory area containing all the values of the list.

List_MoveDown

Moves the specified list node down by one position in the list.

func void List_MoveDown(var int list, var int node)
-
Parameters
  • var int list
    The list in which the node is located.
  • var int node
    The node to be moved down.

List_MoveUp

Moves the specified list node up by one position in the list.

func void List_MoveUp(var int list, var int node)
-
Parameters
  • var int list
    The list in which the node is located.
  • var int node
    The node to be moved up.

List_InsertSorted

Inserts a value into a sorted list while preserving the sort order.

func void List_InsertSorted(var int list, var int data, var func compare)
-
Parameters:
  • var int list
    The list to insert the value into.
  • var int data
    The value to be inserted.
  • var func compare
    A comparison function used to determine the sort order.

List_Compare

func int List_Compare(var int data1, var int data2, var func compare)
-
Parameters:
  • var int data1
    The first integer value.
  • var int data2
    The second integer value.
  • var func compare
    One of comparison functions. Return value

The function returns the return value of specified comparison function.

Comparison Functions

The following comparison functions can be used as the compare parameter in the List_InsertSorted and List_Compare function:

List_CmpAscending

Compares two integer values in ascending order.

func int List_CmpAscending(var int data1, var int data2)
-
Parameters:
  • var int data1
    The first integer value.
  • var int data2
    The second integer value.

Return Value:

The function returns TRUE if data1 is greater than data2, FALSE is returned otherwise.

List_CmpDescending

Compares two integer values in descending order.

func int List_CmpDescending(var int data1, var int data2)
-
Parameters:
  • var int data1
    The first integer value.
  • var int data2
    The second integer value.

Return Value:

The function returns TRUE if data1 is less than data2, FALSE is returned otherwise.

List_CmpAscendingUnsigned

Compares two unsigned integer values in ascending order.

func int List_CmpAscendingUnsigned(var int data1, var int data2)
-
Parameters:
  • var int data1
    The first unsigned integer value.
  • var int data2
    The second unsigned integer value.

Return Value:

The function returns TRUE if data1 is greater than data2, FALSE is returned otherwise.

List_CmpDescendingUnsigned

Compares two unsigned integer values in descending order.

func int List_CmpDescendingUnsigned(var int data1, var int data2)
-
Parameters:
  • var int data1
    The first unsigned integer value.
  • var int data2
    The second unsigned integer value.

Return Value:

The function returns TRUE if data1 is less than data2, FALSE is returned otherwise.

\ No newline at end of file diff --git a/zengin/scripts/extenders/lego/tools/locals/index.html b/zengin/scripts/extenders/lego/tools/locals/index.html deleted file mode 100644 index 75f8e118ac..0000000000 --- a/zengin/scripts/extenders/lego/tools/locals/index.html +++ /dev/null @@ -1,51 +0,0 @@ - Locals - Gothic Modding Community

Locals

Daedalus doesn't offer any local variables, which can quickly lead to problems with recursive functions. The Locals package allows variables to be saved temporarily on a pseudo-stack. Locals is a very specific package. People who work normally with Daedalus will probably never need it. There is also the final function, which can be used to emulate something similar to the final clause in Java.

Dependencies

Initialization

N/A

Implementation

Locals.d on GitHub

Functions

Locals

All that has to be done to enable the Locals is to write this function at the beginning of the function that should receive "real" local variables.

func void locals()
-

Final

It is hard to explain how to use it, but very easy to understand once you've seen an example.

func int Final()
-
Example

With final() it is very easy to emulate Java's final clause, i.e. a block of code can be specified, which is executed after this function is exited, regardless of when or where the function is exited.

1
-2
-3
-4
-5
-6
-7
-8
func void testFinal()
-{
-    if (final())
-    {
-        MEM_InfoBox("Final was called.");
-    };
-    MEM_InfoBox("This will appear before Final");
-};
-
Few lines of code say more than a thousand words.
\ No newline at end of file diff --git a/zengin/scripts/extenders/lego/tools/misc/index.html b/zengin/scripts/extenders/lego/tools/misc/index.html deleted file mode 100644 index d78edf595c..0000000000 --- a/zengin/scripts/extenders/lego/tools/misc/index.html +++ /dev/null @@ -1,43 +0,0 @@ - Misc - Gothic Modding Community

Misc

The Misc package introduces various helper functions that did not fit into any other package.

Dependencies

Initialization

N/A

Implementation

Misc.d on GitHub

Constants

Misc package implements the phi constant

const int phi = 1070141312; // PI/2
-
which is actually pi divided by 2 saved as an ikarus float.

Decimal: 1.5707...

Functions

atan2f

Calculates the arcus tangent of an angle between the origin and (x, y) point.

func int atan2f(var int x, var int y)
-
Parameters
  • var int x
    X-coordinate
  • var int y
    Y-coordinate

Return value

The function returns arcus tangent in radians as Ikarus float.

sin

Calculates the sine of an angle given in radians.

func int sin(var int angle)
-
Parameters
  • var int angle
    The angle in radians as a Ikarus float

Return value

The function returns sine of the angle as Ikarus float.

cos

Calculates the cosine of an angle given in radians.

func int cos(var int angle)
-
Parameters
  • var int angle
    The angle in radians as a Ikarus float

Return value

The function returns cosine of the angle as Ikarus float.

tan

Calculates the tangent of an angle given in radians.

func int tan(var int angle)
-
Parameters
  • var int angle
    The angle in radians as a Ikarus float

Return value

The function returns tangent of the angle as Ikarus float.

asin

Calculates the arcus sine.

func int asin(var int sine)
-
Parameters
  • var int sine
    The sine of an angle as a Ikarus float

Return value

The function returns arcus sine of the angle as Ikarus float.

acos

Calculates the arcus cosine

func int acos(var int cosine)
-
Parameters
  • var int cosine
    The cosine of an angle as a Ikarus float

Return value

The function returns arcus cosine of the angle as Ikarus float.

distance2D

Calculates the distance between two points on a two-dimensional plane.

func int distance2D(var int x1, var int x2, var int y1, var int y2)
-
Parameters
  • var int x1
    X-coordinate of the first point
  • var int x2
    X-coordinate of the second point
  • var int y1
    Y-coordinate of the first point
  • var int y2
    Y-coordinate of the second point

Return value

The function returns the distance between the two points.

distance2Df

Calculates the distance between two points on a two-dimensional plane but parameters and return values are Ikarus floats.

func int distance2Df(var int x1, var int x2, var int y1, var int y2)
-
Parameters
  • var int x1
    X-coordinate of the first point
  • var int x2
    X-coordinate of the second point
  • var int y1
    Y-coordinate of the first point
  • var int y2
    Y-coordinate of the second point

Return value

The function returns the distance between the two points as Ikarus float.

\ No newline at end of file diff --git a/zengin/scripts/extenders/lego/tools/permmem/index.html b/zengin/scripts/extenders/lego/tools/permmem/index.html deleted file mode 100644 index 966c829ea0..0000000000 --- a/zengin/scripts/extenders/lego/tools/permmem/index.html +++ /dev/null @@ -1,86 +0,0 @@ - PermMem - Gothic Modding Community

PermMem

PermMem is a powerful package that allows classes (or instances) to be used permanently even after loading or restarting by saving them to the ASCII .ZEN archive in the savegame directory. PermMem manages handles that are used to access instances, and provides various functions to manipulate these handles and instances.

Dependencies

Initialization

Initialize with LeGo_PermMem flag.

LeGo_Init(LeGo_PermMem);
-

Implementation

PermMem.d on GitHub

Functions

new

Creates a handle to a new instance of inst.

func int new(var int inst)
-
Parameters
  • var int inst
    A valid instance. Used as "constructor"

Return value

The function returns a new, valid PermMem handle.

create

Similar to new, but here a pointer is returned directly and not a handle. Caution! Not managed by PermMem!

func int create(var int inst)
-
Parameters
  • var int inst
    A valid instance. Used as "constructor"

Return value

The function returns a pointer to the new instance.

wrap

"Wraps" a handle "around" a pointer so that the pointer can be used with any function that expects handles. Only conditionally managed by PermMem.

func int wrap(var int inst, var int ptr)
-
Parameters
  • var int inst
    A valid instance. Determines the type of the handle
  • var int ptr
    Pointer to wrap

Return value

The function returns a handle with ptr as content.

clear

Cleans the handle. After that it is invalid.

func void clear(var int hndl)
-
Parameters
  • var int hndl
    Valid PermMem handle

release

Frees the handle. The reserved memory is not deleted, the handle becomes invalid.

func void release(var int hndl)
-
Parameters
  • var int hndl
    Valid PermMem handle

delete

Cleans the handle just like clear, only the destructor is also called.

func void delete(var int hndl)
-
Parameters
  • var int hndl
    Valid PermMem handle

free

Similar to delete, only here a pointer is destroyed and not a handle. Caution! Not managed by PermMem!

func void free(var int ptr, var int inst)
-
Parameters
  • var int ptr
    The pointer to be cleaned
  • var int inst
    Instance used in create function.

get

Returns the instance of the handle.

func instance get(var int hndl)
-
Parameters
  • var int hndl
    Valid PermMem handle

getPtr

Returns a pointer to instance of handle.

func int getPtr(var int hndl)
-
Parameters
  • var int hndl
    Valid PermMem handle

setPtr

Sets the pointer of a handle.

func void setPtr(var int hndl, var int ptr)
-
Parameters
  • var int hndl
    Valid PermMem handle
  • var int ptr
    New pointer for handle

getInst

Returns the instance used to create the given handle in new function.

func int getInst(var int hndl)
-
Parameters
  • var int hndl
    Valid PermMem handle

numHandles

Returns the number of handles managed by PermMem.

func int numHandles()
-

sizeof

Gets the size of the given instance's class.

func int sizeof(var int inst)
-
Parameters
  • var int inst
    Any instance

Return value

The function returns the size of a given instance's class in bytes.

Hlp_IsValidHandle

Indicates whether the handle exists and is managed by PermMem.

func int Hlp_IsValidHandle(var int hndl)
-
Parameters
  • var int hndl
    PermMem's handle

Return value

The function returns TRUE if the handle is valid (managed by PermMem), FALSE is returned otherwise.

Example

The example function that use Hlp_IsValidHandle is Bar_SetMax form LeGo Bars package. The function first checks if the handle is valid, then gets the instance and changes its parameters.

1
-2
-3
-4
-5
-6
func void Bar_SetMax(var int bar, var int max) 
-{
-    if(!Hlp_IsValidHandle(bar)) { return; };
-    var _bar b; b = get(bar);
-    b.valMax = max;
-};
-

foreachHndl

Executes a function for each handle of an instance.

func void foreachHndl(var int inst, var func fnc)
-
Parameters
  • var int inst
    The function is called for this instance
  • var int inst
    This function is called. The signature is function(int handle)

hasHndl

Checks if PermMem has a handle of this instance.

func int hasHndl(var int inst)
-
Parameters
  • var int inst
    Instance to be checked

Return value

The function returns TRUE if the PermMem has a handle of this instance, FALSE is returned otherwise.

MEM_ReadStringArray

Function moved to PermMem form Ikarus. Reads string from the array at the arrayAddress.

func string MEM_ReadStringArray(var int arrayAddress, var int index)
-
Parameters
  • var int arrayAddress
    Memory address of array
  • var int offset
    Array offset (array index)

Return value

The function returns string from the array if the address is correct.

PM_Exists

Checks if the specified field already exists in the archive. (used with archiver/unarchiver)

func int PM_Exists(var string name)
-
Parameters
  • var string name
    Name of the field

Return value

The function returns TRUE if the field exists in the archive, FALSE is returned otherwise.

Archiver

PM_SaveInt

Saves an integer to the archive.

func void PM_SaveInt (var string name, var int val)
-
Parameters
  • var string name
    Name of the field in saved archive
  • var int val
    Value of the saved integer

PM_SaveFloat

Saves a daedalus float to the archive.

func void PM_SaveFloat (var string name, var int flt)
-
Parameters
  • var string name
    Name of the field in saved archive
  • var int flt
    Value of the saved float

PM_SaveString

Saves a string to the archive.

func void PM_SaveString (var string name, var string val)
-
Parameters
  • var string name
    Name of the field in saved archive
  • var string val
    Saved string

PM_SaveFuncID

Saves a function ID to the archive.

func void PM_SaveFuncID(var string name, var int fnc)
-
Parameters
  • var string name
    Name of the field in saved archive
  • var int fnc
    Saved function ID

PM_SaveFuncOffset

Saves a function offset to the archive.

func void PM_SaveFuncOffset(var string name, var int fnc)
-
Parameters
  • var string name
    Name of the field in saved archive
  • var int fnc
    Saved function offset

PM_SaveFuncPtr

Saves a function pointer to the archive.

func void PM_SaveFuncPtr(var string name, var int fnc)
-
Parameters
  • var string name
    Name of the field in saved archive
  • var int fnc
    Saved function pointer

PM_SaveClassPtr

Saves a pointer of a class to the archive.

func void PM_SaveClassPtr(var string name, var int ptr, var string className)
-
Parameters
  • var string name
    Name of the field in saved archive
  • var int ptr
    Saved pointer
  • var string className
    Name of the class of stored pointer

PM_SaveClass

Saves a class like PM_SaveClassPtr.

func void PM_SaveClass(var string name, var int ptr, var string className)
-
Parameters
  • var string name
    Name of the field in saved archive
  • var int ptr
    Saved class pointer
  • var string className
    Name of the class of stored pointer

PM_SaveIntArray

Saves an array of integers.

func void PM_SaveIntArray(var string name, var int ptr, var int elements)
-
Parameters
  • var string name
    Name of the field in saved archive
  • var int ptr
    Pointer to the array
  • var int elements
    Number of elements in array

PM_SaveStringArray

Saves an array of integers.

func void PM_SaveStringArray(var string name, var int ptr, var int elements)
-
Parameters
  • var string name
    Name of the field in saved archive
  • var int ptr
    Pointer to the array
  • var int elements
    Number of elements in array

Unarchiver

PM_Load

Universal function to load integers, floats, class pointers and int arrays.

func int PM_Load(var string name)
-
Parameters
  • var string name
    Name of the loaded field

Return value The function returns the data existing in the archive at the given field.

PM_LoadInt

Returns an integer stored in the archive.

func int PM_LoadInt(var string name)
-
Parameters
  • var string name
    Name of the loaded field

PM_LoadFloat

Returns a daedalus float stored in the archive.

func int PM_LoadFloat(var string name)
-
Parameters
  • var string name
    Name of the loaded field

PM_LoadString

Returns a string stored in the archive.

func string PM_LoadString(var string name)
-
Parameters
  • var string name
    Name of the loaded field

PM_LoadFuncID

Returns a function ID stored in the archive.

func int PM_LoadFuncID(var string name)
-
Parameters
  • var string name
    Name of the loaded field

PM_LoadFuncOffset

Returns a function offset stored in the archive.

func int PM_LoadFuncOffset(var string name)
-
Parameters
  • var string name
    Name of the loaded field

PM_LoadFuncPtr

Returns a function pointer stored in the archive.

func int PM_LoadFuncPtr(var string name)
-
Parameters
  • var string name
    Name of the loaded field

PM_LoadClassPtr

Returns a class pointer stored in the archive.

func int PM_LoadClassPtr(var string name)
-
Parameters
  • var string name
    Name of the loaded field

PM_LoadClass

Loads a pointer to the class from the archive to destPtr.

func void PM_LoadClass(var string name, var int destPtr)
-
Parameters
  • var string name
    Name of the loaded field
  • var int destPtr
    Destination pointer, the address to where it will deserialize the saved data

PM_LoadArray

Returns a pointer to array stored in the archive.

func int PM_LoadArray(var string name)
-
Parameters
  • var string name
    Name of the loaded field

PM_LoadArrayToPtr

Loads a pointer to array from the archive to destPtr.

func void PM_LoadArrayToPtr(var string name, var int destPtr)
-
Parameters
  • var string name
    Name of the loaded field
  • var int destPtr
    Destination pointer, the address to where it will deserialize the saved data

PM_LoadToPtr

Universal function to load array or class pointer from the archive to destPtr.

func void PM_LoadToPtr(var string name, var int destPtr)
-
Parameters
  • var string name
    Name of the loaded field
  • var int destPtr
    Destination pointer, the address to where it will deserialize the saved data
\ No newline at end of file diff --git a/zengin/scripts/extenders/lego/tools/queue/index.html b/zengin/scripts/extenders/lego/tools/queue/index.html deleted file mode 100644 index 8e8249ab98..0000000000 --- a/zengin/scripts/extenders/lego/tools/queue/index.html +++ /dev/null @@ -1,48 +0,0 @@ - Queue - Gothic Modding Community

Queue

This package is an implementation of the Queue data structure and a queue for function calls.

Dependencies

Initialization

N/A

Implementation

Queue.d on GitHub

Queue

Q_Create

Creates a new queue and returns a handle to it.

func int Q_Create()
-
Return value

The function returns a handle to a queue.

Q_Enqueue

Appends an integer to the back of the queue

func void Q_Enqueue(var int queue, var int value)
-
Parameters
  • var int queue
    Handle of a queue
  • var int value
    The value to be appended to the queue

Q_IsEmpty

Checks if the queue is empty.

func int Q_IsEmpty(var int queue)
-
Parameters
  • var int queue
    Handle of a queue

Return value

The function returns TRUE if the queue is empty, FALSE is returned otherwise.

Q_Advance

Removes the oldest value from the queue and returns it.

func int Q_Advance(var int queue)
-
Parameters
  • var int queue
    Handle of a queue

Return value

The function returns the oldest value in the queue.

Q_Peek

Returns the oldest value in the queue without removing it.

func int Q_Peek(var int queue)
-
Parameters
  • var int queue
    Handle of a queue

Return value

The function returns the oldest value in the queue.

Q_For

Function with the funcID is called with every element of the list as parameter.
The list element is passed to the function as a zCList pointer.

func void Q_For(var int queue, var int funcID)
-
Parameters
  • var int queue
    Handle of a queue
  • var int funcID
    ID of function that is executed for all values in the queue (signature: void (zCList*))

Q_ForF

Like Q_For, but with function as a parameter instead of a function ID.

func void Q_ForF(var int queue, var func f)
-
Parameters
  • var int queue
    Handle of a queue
  • var func f
    This function is executed for all values in the queue (signature: void (zCList*))

CallbackQueue

CQ_Create

Creates a new callback queue and returns a handle to it.

func int CQ_Create()
-
Return value

The function returns a handle to a callback queue.

CQ_EnqueueNoData

Appends a function to the callback queue.

func void CQ_EnqueueNoData(var int queue, var func function)
-
Parameters
  • var int queue
    Handle of a callback queue
  • var func function
    A function with no return value, expecting no parameter

CQ_EnqueueData

Appends a function together with a value to the callback queue.

func void CQ_EnqueueData(var int queue, var func function, var int data)
-
Parameters
  • var int queue
    Handle of a callback queue
  • var func function
    A function with no return value, expecting an integer as a parameter.
  • var int data
    When calling function, this value is passed as a parameter

CQ_Enqueue

Appends a function together with an optional value to the callback queue. This function should not usually be used. Use CQ_EnqueueData and CQ_EnqueueNoData instead.

func void CQ_Enqueue(var int queue, var int funcID, var int data, var int hasData)
-
Parameters
  • var int queue
    Handle of a callback queue
  • var int funcID
    The function ID of a function to be appended to the callback queue.
  • var int data
    If hasData is not 0, this value is passed to the associated function.
  • var int hasData
    Must be 0 if the function does not expect an integer as a parameter, otherwise not 0.

CQ_IsEmpty

Checks if no function is in the callback queue.

func int CQ_IsEmpty(var int queue)
-
Parameters
  • var int queue
    Handle of a callback queue

Return value

The function returns TRUE if the callback queue is empty, FALSE is returned otherwise.

CQ_Advance

Executes the foremost function of the callback queue and removes it from the callback queue.

func void CQ_Advance(var int queue)
-
Parameters
  • var int queue
    Handle of a callback queue

CQ_Exhaust

Executes all functions contained in the callback queue.

func void CQ_Exhaust(var int queue)
-
Parameters
  • var int queue
    Handle of a callback queue
\ No newline at end of file diff --git a/zengin/scripts/extenders/lego/tools/random/index.html b/zengin/scripts/extenders/lego/tools/random/index.html deleted file mode 100644 index 9b10059f0e..0000000000 --- a/zengin/scripts/extenders/lego/tools/random/index.html +++ /dev/null @@ -1,40 +0,0 @@ - Random - Gothic Modding Community

Random

Provides more random randomization than Hlp_Random() function.

Dependencies

N/A

Initialization

Initialize with LeGo_Random flag.

LeGo_Init(LeGo_Random);
-

Implementation

Random.d on GitHub

Functions

r_Next

Returns a random number.

func int r_Next()
-
Return value

The function returns a random number.

r_Max

Returns a random number from 0 to max.

func int r_Max(var int max)
-
Parameters
  • var int max
    Maximum value of number

Return value

The function returns a random number from 0 to 'max'.

r_MinMax

Returns a random number from 'min' to 'max'.

func int r_MinMax(var int min, var int max)
-
Parameters
  • var int max
    Maximum value of number
  • var int min
    Minimum value of number

Return value

The function returns a random number from min to max.

r_Init

Initializes the random number generator. Happens optionally in LeGo_Init.

func void r_Init(var int seed)
-
Parameters
  • var int seed
    The initializing value

r_DefaultInit

Initializes the random number generator based on the current time.

func void r_DefaultInit()
-
\ No newline at end of file diff --git a/zengin/scripts/extenders/lego/tools/string_builder/index.html b/zengin/scripts/extenders/lego/tools/string_builder/index.html deleted file mode 100644 index 501e5e354a..0000000000 --- a/zengin/scripts/extenders/lego/tools/string_builder/index.html +++ /dev/null @@ -1,155 +0,0 @@ - StringBuilder - Gothic Modding Community

StringBuilder

The StringBuilder is a package, designed to easily concatenate multiple elements into a string (without ConcatStrings and IntToString).

All created StringBuilders are transient. All functions starting from SB_InitBuffer, including it, use the active StringBuilder set with SB_New or SB_Use, so there is no var int stringBuilder parameter in functions. A look at the example explains what I mean.

Warning

The StringBuilder works with pointers, not handles like many other LeGo packages.

Dependencies

N/A

Initialization

N/A

Implementation

StringBuilder.d on GitHub

Functions

SB_New

Creates and returns a new StringBuilder. At the same time, this new StringBuilder is set as active. (See SB_Use.)

func int SB_New()
-
Return value

The function returns a pointer to a new StringBuilder.

SB_Use

Marks this StringBuilder as active. It can now be used with the functions.

func void SB_Use(var int sb)
-
Parameters
  • var int sb
    Pointer to a StringBuilder, returned from SB_New

SB_Get

Returns the active StringBuilder.

func int SB_Get()
-
Return value

The function returns the active StringBuilder object - last set with SB_Use or just created with SB_New.

SB_InitBuffer

If the size of the resulting string is already known, the buffer can be set manually. This is usually not necessary.

func void SB_InitBuffer(var int size)
-
Parameters
  • var int size
    Size in bytes. Warning! Only works if the StringBuilder has been newly created!

SB_Clear

Empties the current StringBuilder. It is not destroyed in the process, so it can be used again. If the object has a buffer allocated, the buffer is freed.

func void SB_Clear()
-

SB_Release

Releases the current stream of the StringBuilder. The StringBuilder is destroyed, and the stream can be obtained via SB_GetStream.

func void SB_Release()
-

SB_Destroy

Completely destroys the StringBuilder.

func void SB_Destroy()
-

SB_ToString

Returns a copy of the stream as a string.

func string SB_ToString()
-
Return value

The function returns the copy of the active StringBuilder as a string. If the StringBuilder object doesn't have a buffer allocated, an empty string is returned.

SB_ToStream

Returns a copy of the stream in raw format.

func int SB_ToStream()
-
Return value

The function returns a copy of the stream in raw format (char[])

SB_GetStream

Doesn't copy the stream, but returns it as it is.

func int SB_GetStream()
-
Return value

The function returns the stream as it is. SB_Destroy or SB_Clear destroy the returned pointer.

SB_Length

Returns the current length of the stream. Similar to STR_Len from Ikarus .

func int SB_Length()
-
Return value

The function returns the current length of the active StringBuilder.

SB_SetLength

Sets the length of the stream. When increasing, zero bytes are appended.

func void SB_SetLength(var int length)
-

Stream operations

SB

Appends a string, to the active StringBuilder.

func void SB(var string s)
-
Parameters
  • var string s
    The appended string

SBi

Appends an integer in text form, to the active StringBuilder.

func void SBi(var int i)
-
Parameters
  • var int i
    The appended integer

SBc

Appends a byte, to the active StringBuilder. (e.g. 82 for 'R' - An ASCII table can be quickly found)

func void SBc(var int c)
-
Parameters
  • var int c
    The appended byte (ASCII table character)

SBraw

Appends a raw bytes array, to the active StringBuilder.

func void SBraw(var int ptr, var int len)
-
Parameters
  • var int ptr
    Pointer to the appended array
  • var int len
    Length of an array

SBflt

Appends a Daedalus float in text form, to the active StringBuilder.

func void SBflt(var float x)
-
Parameters
  • var float x
    The appended Daedalus float value

SBf

Appends an Ikarus float in text form, to the active StringBuilder.

func void SBf(var int x)
-
Parameters
  • var float x
    The appended Ikarus float value

SBw

Appends a 4-byte raw data (interpreted as an integer x), to the active StringBuilder.

func void SBw(var int x)
-
Parameters
  • var int i
    The appended value

Independent Functions

STR_Escape

Makes escape sequences out of non-writable characters. For example, newline character \n becomes \\n, tab character \t becomes \\t, etc.

func string STR_Escape(var string s0)
-
Parameters
  • var string s0
    The string to be added escape sequences

Return value

The function returns a new string with escape sequences added for special characters.

STR_Unescape

Counterpart to STR_Escape. Escape sequences like \n, \r or \t are converted back.

func string STR_Unescape(var string s0)
-
Parameters
  • var string s0
    The string to be removed escape sequences

Return value

The function returns a new string with escape sequences replaced by their corresponding characters.

STR_StartsWith

Checks if the input string s starts with the specified prefix string.

func int STR_StartsWith(var string str, var string start) 
-
Parameters
  • var string str
    The string to be checked
  • var string start
    The searched prefix

Return value

The function returns TRUE if the string starts with the prefix, FALSE is returned otherwise.

Additional Functions

BuildStringSymbolsArray

Creates an array of all string symbols found in the parser's string table.

func int BuildStringSymbolsArray()
-
Return value

The function returns created array.

GetStringSymbolByAddr

Retrieves the symbol at the specified address from the string table.

func int BuildStringSymbolsArray()
-
Return value

The function returns a parser symbol at the given address.

Examples

Basic functionality

This is how function that builds a string looks without StringBuilder:

1
-2
-3
-4
-5
-6
-7
-8
func void PrintMyNumbers(var int x0, var int x1, var int x2) {
-    var string res;
-    res = ConcatStrings(IntToString(x0), ", ");
-    res = ConcatStrings(res, IntToString(x1));
-    res = ConcatStrings(res, ", ");
-    res = ConcatStrings(res, IntToString(x2));
-    PrintS(res);
-};
-
And now the function that uses StringBulider:
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
func void PrintMyNumbers(var int x0, var int x1, var int x2) {
-    var int s; s = SB_New();  // Create StringBuilder
-    SBi(x0);                  // Append Int
-    SB (", ");                // Append string
-    SBi(x1);                  // Append Int
-    SB (", ");                // Append string
-    SBi(x2);                  // Append Int
-    PrintS(SB_ToString());    // Get output as a string
-    SB_Destroy();             // Destroy StringBuilder
-};
-
Looks much more pleasant, right? But why do we create a StringBuilder and then not use it? The idea is the following: A StringBuilder is created with SB_New() and set as the active StringBuilder in the background. The package only supports one StringBuilder at a time, which will keep the pointer in case we want to use another StringBuilder in between.

Multiple StringBuilders

Simple example. We want to fill two StringBuilders at the same time and then return them combined:

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
func string Example2() {
-    // Create two StringBuilders:
-    var int s0; s0 = SB_New();
-    var int s1; s1 = SB_New();
-
-    // Set the first StringBuilder as active and fill it.
-    SB_Use(s0);
-    SB("Hello ");
-    SB("World!");
-
-    // Set the second StringBuilder as active and fill it.
-    SB_Use(s1);
-    SB("This is ");
-    SB("the hero speaking!");
-
-    // Now we want to combine the two StringBuilders.
-    // The system doesn't actually provide for such an operation, but it can still be done using a helper string
-    var string str; str = SB_ToString(); // This string now says “This is the hero speaking!”
-
-    SB_Use(s0);
-    SB(" ");
-    SB(str);
-
-    str = SB_ToString(); // Now "Hello world! This is the hero speaking!" are in the string.
-
-    // The rest is already known, we destroy StringBuilders
-    SB_Destroy();
-    SB_Use(s1);
-    SB_Destroy();
-
-    return str;
-};
-
\ No newline at end of file diff --git a/zengin/scripts/extenders/lego/tools/talents/index.html b/zengin/scripts/extenders/lego/tools/talents/index.html deleted file mode 100644 index 3708b98b43..0000000000 --- a/zengin/scripts/extenders/lego/tools/talents/index.html +++ /dev/null @@ -1,40 +0,0 @@ - Talents - Gothic Modding Community

Talents

The Talents package does two things:

  1. save any number of values for a specific NPC (effectively AIVar array extension).
  2. identify NPC by unique ID.

Talents package uses one free AIVar variables, the default is AIVar with the index 89 that can be customized in Userconst.d the AIV_TALENT constant.

Dependencies

Initialization

Initialize with LeGo_PermMem flag.

LeGo_Init(LeGo_PermMem);
-

Implementation

Talents.d on GitHub

Functions

Npc_GetID

Returns unique ID specific for provided NPC.

func int Npc_GetID(var C_NPC slf)
-
Parameters
  • var C_NPC slf
    NPC to get ID

Return value

The function returns NPCs unique ID.

Npc_FindByID

Finds the NPC pointer of an NPC with the given ID.

func int Npc_FindByID(var int ID)
-
Parameters
  • var int ID
    NPC ID

Return value

The function returns NPC pointer.

TAL_CreateTalent

Creates a talent into which you can later save a value for every NPC (just like AI_Var).

func int TAL_CreateTalent()
-
Return value

The function returns value that can be later used as a talent ID.

TAL_SetValue

Sets a new value to the specified talent.

func void TAL_SetValue(var C_NPC npc, var int talent, var int value)
-
Parameters
  • var C_NPC npc
    Set the talent value for this NPC
  • var int talent
    Talent ID
  • var int value
    Value to be set

TAL_GetValue

Returns the value of a saved talent for specified NPC.

func int TAL_GetValue(var C_NPC npc, var int talent)
-
Parameters
  • var C_NPC npc
    Get the talent value from this NPC
  • var int talent
    Talent ID
\ No newline at end of file diff --git a/zengin/scripts/extenders/lego/tools/timer/index.html b/zengin/scripts/extenders/lego/tools/timer/index.html deleted file mode 100644 index f1be52a739..0000000000 --- a/zengin/scripts/extenders/lego/tools/timer/index.html +++ /dev/null @@ -1,41 +0,0 @@ - Timer - Gothic Modding Community

Timer

Timer is a better alternative to the timers that Gothic offers. The FrameFunctions and Anim8 packages are already based on it. It isn't possible to modify the current time, as this would only cause difficulties.

Dependencies

N/A

Initialization

Initialize with LeGo_Timer flag.

LeGo_Init(LeGo_Timer);
-

Implementation

Timer.d on GitHub

Functions

Timer

Returns the current playing time. If a new game is started, the time is 0. It is measured in milliseconds.

func int Timer()
-
Return value

The function returns current playing time in milliseconds.

TimerGT

Returns the current game time, but the timer is paused when the game is paused (in the menu or status screen).

func int TimerGT()
-
Return value

The function returns current playing time in milliseconds, but without measuring time when game is paused.

TimerF

Alias to Timer function that returns the time as an Ikarus float value.

func int TimerF()
-
Return value

The function returns current playing time as an Ikarus float value.

Timer_SetPause

Pauses the timer (and thus all FrameFunctions and running animations).

func void Timer_SetPause(var int on)
-
Parameters
  • var int on
    Pause on/off

Timer_SetPauseInMenu

The timer can automatically pause when the game is paused. (status screen, main menu...)

func void Timer_SetPauseInMenu(var int on)
-
Parameters
  • var int on
    Automatic pause on/off

Timer_IsPaused

This can be used to query whether the timer is paused.

func int Timer_IsPaused()
-
Return value

The function returns TRUE if the timer is paused, FALSE is returned otherwise.

\ No newline at end of file diff --git a/zengin/scripts/extenders/lego/tools/view/index.html b/zengin/scripts/extenders/lego/tools/view/index.html deleted file mode 100644 index d56646f40d..0000000000 --- a/zengin/scripts/extenders/lego/tools/view/index.html +++ /dev/null @@ -1,84 +0,0 @@ - View - Gothic Modding Community

View

This package can create textures on the screen and work with them in an extended manner.

Dependencies

Initialization

Initialize with LeGo_View flag.

LeGo_Init(LeGo_View);
-

Implementation

View.d on GitHub

Functions

View_Create

Creates a zCView with virtual coordinates.

func int View_Create(var int x1, var int y1, var int x2, var int y2) 
-
Parameters
  • var int x1/var int y1
    Top-left corner coordinates (virtual)
  • var int x2/var int y2
    Bottom-right corner coordinates (virtual)

Return value

The function returns a PermMem handle to a zCView.

View_CreatePxl

Alias for View_Create using pixel coordinates.

func int View_CreatePxl(var int x1, var int y1, var int x2, var int y2) 
-
Parameters
  • var int x1/var int y1
    Top-left corner coordinates (pixel)
  • var int x2/var int y2
    Bottom-right corner coordinates (pixel)

Return value

The function returns a PermMem handle to a zCView.

View_CreateCenter

Creates a zCView with virtual coordinates centered.

func int View_CreateCenter(var int x, var int y, var int width, var int height)
-
Parameters
  • var int x
    Horizontal position
  • var int y
    Vertical position
  • var int width
    Width of the view
  • var int height
    Height of the view

Return value

The function returns a PermMem handle to a zCView.

View_CreateCenterPxl

Alias for View_CreateCenter using pixel coordinates.

func int View_CreateCenterPxl(var int x, var int y, var int width, var int height)
-
Parameters
  • var int x
    Horizontal position
  • var int y
    Vertical position
  • var int width
    Width of the view
  • var int height
    Height of the view

Return value

The function returns a PermMem handle to a zCView.

View_Get

Alias for get form PermMem.

zCView View_Get(var int hndl)
-
Parameters

View_GetPtr

Alias for getPtr form PermMem.

func int View_GetPtr(var int hndl)
-
Parameters

View_Render

Renders a zCView. Should be used sparingly, as it works only in specific cases.

func void View_Render(var int hndl)
-
Parameters

View_SetTexture

Assigns a texture to a view. The key function of this package.

func void View_SetTexture(var int hndl, var string texture)
-
Parameters
  • var int hndl
    Handle created with View_Create
  • var string texture
    Filename of a texture

View_GetTexture

Gets the name of a previously assigned texture.

func string View_GetTexture(var int hndl)
-
Parameters

Return value

The function returns the previously assigned texture.

View_SetColor

Sets the color of a view.

func void View_SetColor(var int hndl, var int color)
-
Parameters
  • var int hndl
    Handle created with View_Create
  • var int color
    zColor, can be created with RGBA

View_GetColor

Gets the color of a view.

func int View_GetColor(var int hndl)
-
Parameters

Return value

The function returns the full zColor.

View_Open

Opens a view. It will be displayed on the screen.

func void View_Open(var int hndl)
-
Parameters

View_Close

Closes a view. It disappears from the screen but can still be used.

func void View_Close(var int hndl)
-
Parameters

View_Delete

Alias for delete.

`zCView` View_Delete(var int hndl)
-
Parameters

View_Resize

Scales a view to a virtual size. The top-left position of the view remains fixed.

func void View_Resize(var int hndl, var int width, var int height)
-
Parameters
  • var int hndl
    Handle created with View_Create
  • var int width
    New width of the view
  • var int height
    New height of the view

View_ResizePxl

Alias for View_Resize using pixel coordinates.

func void View_ResizePxl(var int hndl, var int width, var int height)
-
Parameters
  • var int hndl
    Handle created with View_Create
  • var int width
    New width of the view
  • var int height
    New height of the view

View_Move

Moves the view by virtual units.

func void View_Move(var int hndl, var int x, var int y)
-
Parameters
  • var int hndl
    Handle created with View_Create
  • var int x
    Shift left/right
  • var int y
    Shift up/down

View_MovePxl

Alias for View_Move using pixel coordinates.

func void View_MovePxl(var int hndl, var int x, var int y)
-
Parameters
  • var int hndl
    Handle created with View_Create
  • var int x
    Shift left/right
  • var int y
    Shift up/down

View_MoveTo

Moves the top-left corner of the view to a virtual position.

func void View_MoveTo(var int hndl, var int x, var int y)
-
Parameters
  • var int hndl
    Handle created with View_Create
  • var int x
    New horizontal position (-1 for no change)
  • var int y
    New vertical position (-1 for no change)

View_MoveToPxl

Alias for View_MoveTo using pixel coordinates.

func void View_MoveToPxl(var int hndl, var int x, var int y)
-
Parameters
  • var int hndl
    Handle created with View_Create
  • var int x
    New horizontal position (-1 for no change)
  • var int y
    New vertical position (-1 for no change)

View_AddText

Adds a text line to the view. The position is virtual and relative to the view's position. If the view is moved, the text moves as well.

func void View_AddText(var int hndl, var int x, var int y, var string text, var string font)
-
Parameters
  • var int hndl
    Handle created with View_Create
  • var int x
    Horizontal position
  • var int y
    Vertical position
  • var string text
    Added text
  • var string font
    Used Font

View_DeleteText

Removes all text added with View_AddText.

func void View_DeleteText(var int hndl)
-
Parameters

View_Top

Places the view above all others.

func void View_Top(var int hndl)
-
Parameters

Examples

Display a texture on the screen

Here a texture should be displayed over the entire screen:

1
-2
-3
-4
-5
-6
-7
func void Example1() {
-    var int View; 
-    View = View_Create(0, 0, PS_VMax, PS_VMax); // Virtual coordinates
-    View_SetTexture(View, "MyTexture.tga"); // Assign a texture to the view
-    // display the view on the screen:
-    View_Open(View);
-};
-

This would mean that the texture would be permanently visible on the screen (even after loading/saving/restarting). If we want it to disappear we have to use either View_Delete or View_Close.

Display a texture with pixel coordinates

Now a texture should be displayed at the top right and be 256 x 256 pixels in size:

1
-2
-3
-4
-5
-6
-7
func void Example2() {
-    Print_GetScreenSize();
-    var int View;
-    View = View_CreatePxl(Print_Screen[PS_X] - 256, 0, Print_Screen[PS_X], 256); // Pixel coordinates
-    View_SetTexture(View, "MYTEXTURE.TGA");
-    View_Open(View);
-};
-

To get the size of the screen we use the interface package.

\ No newline at end of file diff --git a/zengin/scripts/extenders/lego/trialoge/index.html b/zengin/scripts/extenders/lego/trialoge/index.html deleted file mode 100644 index 91ea7a0823..0000000000 --- a/zengin/scripts/extenders/lego/trialoge/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/zengin/scripts/extenders/lego/various/userconstants/index.html b/zengin/scripts/extenders/lego/various/userconstants/index.html deleted file mode 100644 index f18164fda3..0000000000 --- a/zengin/scripts/extenders/lego/various/userconstants/index.html +++ /dev/null @@ -1,34 +0,0 @@ - User constants - Gothic Modding Community

User constants

All constants that the user can either use or even change freely are defined in Userconst.d file.

Read only

These constants may only be used, not changed.

Anim8

These constants are used by Anim8 and Anim8q.

  • const int A8_Constant
    Constant movement speed
  • const int A8_SlowEnd
    Evenly decelerated movement
  • const int A8_SlowStart
    Evenly accelerated movement
  • const int A8_Wait
    Do nothing. The target value is ignored here

Buttons

The following bit masks can be applied to the status of a button:

  • const int BUTTON_ACTIVE
    The button is active, it reacts to the mouse
  • const int BUTTON_ENTERED
    The mouse is "within" the button

Interface

Dimensions

  • const int PS_X and const int PS_Y
    Use with Print_Screen or Print_ToVirtual functions
  • const int PS_VMax
    Highest possible value of a virtual coordinate

Colors

16 basic colors that can be used as zColor parameters

  • const int COL_Aqua
  • const int COL_Black
  • const int COL_Blue
  • const int COL_Fuchsia
  • const int COL_Gray
  • const int COL_Green
  • const int COL_Lime
  • const int COL_Maroon
  • const int COL_Navy
  • const int COL_Olive
  • const int COL_Purple
  • const int COL_Red
  • const int COL_Silver
  • const int COL_Teal
  • const int COL_White
  • const int COL_Yellow

Gamestate

Gamestate can assume these values:

  • const int Gamestate_NewGame
    New game started
  • const int Gamestate_Loaded
    A game has been loaded
  • const int Gamestate_WorldChange
    The world has changed
  • const int Gamestate_Saving
    The game is saved

Cursor

These constants are sent with Cursor_Event:

  • const int CUR_LeftClick
    The left mouse button was pressed
  • const int CUR_RightClick
    The right mouse button was pressed
  • const int CUR_MidClick
    The middle mouse button was pressed
  • const int CUR_WheelUp
    Mouse wheel up
  • const int CUR_WheelDown
    Mouse wheel down

Modifiable

These constants are often used by packages and may be changed freely.

Bloodsplats

  • const int BLOODSPLAT_NUM
    Maximum number on screen
  • const int BLOODSPLAT_TEX
    Highest Texture ID ("BLOODSPLAT" + texID + ".TGA")
  • const int BLOODSPLAT_DAM
    Texture size damage multiplier (damage * 2Bloodsplat_Dam)

Cursor

  • const string Cursor_Texture
    This texture is used to display the cursor (default: "CURSOR.TGA")

Interface

  • const string Print_LineSeperator
    Text boxes can be printed in multiple lines. This character separates the lines from each other.

PrintS

All position and size information is completely virtual:

  • const int PF_PrintX
    Start position on the X axis
  • const int PF_PrintY
    Start position on the Y axis
  • const int PF_TextHeight
    Space between individual lines

The times are given in ms:

  • const int PF_FadeInTime
    Time to fade in the text
  • const int PF_FadeOutTime
    Time to fade out the text
  • const int PF_MoveYTime
    Time needed to "slip down"
  • const int PF_WaitTime
    Time during which the print is fully visible

The font can be modified:

  • const string PF_Font
    Default: FONT_OLD_10_WHITE.TGA

Talents

  • const int AIV_TALENT
    Used AIVar

Dialoggestures

  • const string DIAG_Prefix
    Animation prefix ("DG_")
  • const string DIAG_Suffix
    Animation suffix ("_")
\ No newline at end of file diff --git a/zengin/scripts/extenders/standalone/gameKeyEvents/index.html b/zengin/scripts/extenders/standalone/gameKeyEvents/index.html deleted file mode 100644 index 5cff0e0758..0000000000 --- a/zengin/scripts/extenders/standalone/gameKeyEvents/index.html +++ /dev/null @@ -1,48 +0,0 @@ - gameKeyEvents - Gothic Modding Community

gameKeyEvents

Quick overview

Author: mud-freak
Platform: G1, G2NotR
Category: Engine, Keys

gameKeyEvents.d is a script, which handles key events with the oCGame::HandleEvent hook. Better alternative for FrameFunction with MEM_KeyState with which you don't have to check whether any menu is opened or player is in dialogue or can move etc.

Author's description

I looked up the address within oCGame::HandleEvent. I made it into a universally usable script for Gothic 1 and Gothic 2.

One could argue now that this is not much different from a FrameFunction with MEM_KeyState. The difference is that this approach saves the extra work of checking if any menu is open, whether the player is in a dialog, whether the player may move, etc. Also this function is "event driven", meaning it is really only called when a key is pressed/held instead of every frame in vain. So it's arguably more performant.

Dependencies

Initialization

Call Game_KeyEventInit() in the Init_Global() or other initialization function.

Game_KeyEventInit();
-

Implementation

gameKeyEvents.d on WoG forum

Usage

To add a key pressing detection edit the main function Game_KeyEvent.

1
-2
-3
-4
-5
-6
-7
func int Game_KeyEvent(var int key, var int pressed) {
-    if (key == KEY_LBRACKET) && (pressed) {
-        // Here enter your code.
-        return TRUE;
-    };
-    return FALSE;
-};
-
  • To change detected key rename KEY_LBRACKET to your own key e.g. taken from Ikarus constants.
  • To detect pressing a key leave (pressed) unchanged but if you want to detect holding change it to (!pressed). That's because

    pressed is FALSE: key is held, pressed is TRUE: key press onset

  • To run code when a key is pressed, paste it or call a function where the comment is.
  • To detect more than one key add else if.
\ No newline at end of file diff --git a/zengin/scripts/extenders/standalone/index.html b/zengin/scripts/extenders/standalone/index.html deleted file mode 100644 index 11da007bde..0000000000 --- a/zengin/scripts/extenders/standalone/index.html +++ /dev/null @@ -1,34 +0,0 @@ - Standalone Scripts - Gothic Modding Community

Standalone Scripts

Over the years Gothic modders have created many useful features to use with Zengin scripts. This section contains documentation for some scripts that are "standalone", meaning they are not part of larger packages, but are often small features to make modders lives easier.

Script Bins

A few people came up with the idea of collecting scripts scattered on the forums, which resulted in the so-called Script Bins.

Warning

Script bins aren't updated frequently, so for the latest updates and new scripts also check the ScriptBin WoG thread.

WoG Script Bin

Script bin made by Kirides containing scripts from German WoG forum.

https://apps.kirides.de/wog-script-bin/

ScriptBin GitHub repository

Lehona has created a GitHub repository that contains scripts from some of the modders.

https://github.com/Lehona/ScriptBin

\ No newline at end of file diff --git a/zengin/scripts/extenders/standalone/setBarPositions/index.html b/zengin/scripts/extenders/standalone/setBarPositions/index.html deleted file mode 100644 index c7053a4005..0000000000 --- a/zengin/scripts/extenders/standalone/setBarPositions/index.html +++ /dev/null @@ -1,141 +0,0 @@ - setBarPositions - Gothic Modding Community

setBarPositions

Quick overview

Author: mud-freak
Platform: G1, G2NotR
Category: Engine, Interface

setBarPositions.d is a script that allows changing position of original gothic bars (HP, Mana, Swim, focus). Changes are directly in the engine, so bars are normally scaled.

Dependencies

Initialization

Call it in the Init_Global() or other initialization function. Set the manaAlwaysOn and swimAlwaysOn to TRUE/FALSE.

SetBarPositions_Init(manaAlwaysOn, swimAlwaysOn);
-

Implementation

setBarPositions.d on WoG forum

Usage

To change positions of bars edit the main function SetBarPosition. Look at the examples to see how you can adjust it to your preferences.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
func int SetBarPosition(var int barPtr) {
-    var oCViewStatusBar bar; bar = _^(barPtr);
-    var int x; var int y;
-
-    if (barPtr == MEM_Game.hpBar) {
-        // Original
-        x = Print_ToVirtual(10, PS_X);                                // 10 px from the left
-        y = PS_VMax - Print_ToVirtual(10 + bar.zCView_psizey, PS_Y);  // 10 px from the bottom
-
-    } else if (barPtr == MEM_Game.manaBar) {
-        // Original
-        x = PS_VMax - Print_ToVirtual(10 + bar.zCView_psizex, PS_X);  // 10 px from the right
-        y = PS_VMax - Print_ToVirtual(10 + bar.zCView_psizey, PS_Y);  // 10 px from the bottom
-
-    } else if (barPtr == MEM_Game.swimBar) {
-        // Original
-        x = (PS_VMax - bar.zCView_vsizex) / 2;                        // Centered
-        y = PS_VMax - Print_ToVirtual(10 + bar.zCView_psizey, PS_Y);  // 10 px from the bottom
-
-    } else if (barPtr == MEM_Game.focusBar) {
-        // Original
-        x = (PS_VMax - bar.zCView_vsizex) / 2;                        // Centered
-        y = Print_ToVirtual(10, PS_Y);                                // 10 px from the top
-    };
-
-    return x | (y << 14);
-};
-

Examples

All bars on the left side

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
/*
- * EXAMPLE: Stacked on the left
- */
-func int SetBarPosition(var int barPtr) {
-    var oCViewStatusBar bar; bar = _^(barPtr);
-    var int x; var int y;
-
-    if (barPtr == MEM_Game.hpBar) {
-        x = Print_ToVirtual(10, PS_X);
-        y = PS_VMax - Print_ToVirtual(6 + 3 * (4 + bar.zCView_psizey), PS_Y);
-
-    } else if (barPtr == MEM_Game.manaBar) {
-        x = Print_ToVirtual(10, PS_X);
-        y = PS_VMax - Print_ToVirtual(6 + 2 * (4 + bar.zCView_psizey), PS_Y);
-
-    } else if (barPtr == MEM_Game.swimBar) {
-        x = Print_ToVirtual(10, PS_X);
-        y = PS_VMax - Print_ToVirtual(6 + 1 * (4 + bar.zCView_psizey), PS_Y);
-
-    } else if (barPtr == MEM_Game.focusBar) {
-        // Original
-        x = (PS_VMax - bar.zCView_vsizex) / 2;                        // Centered
-        y = Print_ToVirtual(10, PS_Y);                                // 10 px from the top
-    };
-
-    return x | (y << 14);
-};
-
\ No newline at end of file diff --git a/zengin/scripts/extenders/zparserextender/c_trigger/index.html b/zengin/scripts/extenders/zparserextender/c_trigger/index.html deleted file mode 100644 index 6db5ec0bd5..0000000000 --- a/zengin/scripts/extenders/zparserextender/c_trigger/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/zengin/scripts/extenders/zparserextender/classes/c_trigger/index.html b/zengin/scripts/extenders/zparserextender/classes/c_trigger/index.html deleted file mode 100644 index b5045d3e12..0000000000 --- a/zengin/scripts/extenders/zparserextender/classes/c_trigger/index.html +++ /dev/null @@ -1,145 +0,0 @@ - C_Trigger class - Gothic Modding Community

Trigger functions and the C_Trigger class

zParserExtender also implements cyclical functions called triggers - not to be confused with triggers in ZEN files, similar to a part of the functionality implemented in LeGo AI_Functions. These functions are called independently after a specified period of time. These triggers can also store user information. Up to 16 int variables can be stored in each trigger as well as self, other and victim instances.

Class definition

To define a trigger, the C_Trigger class is used:

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
/// Union zParserExtender Trigger class
-class C_Trigger
-{
-    var int Delay; // defines the frequency (in milliseconds) at which the function will be called.
-    var int Enabled; // determines if the trigger is active. If the value is equal to zero, the trigger is destroyed.
-    var int AIVariables[16]; // user data, which can be set independently when creating trigger (yes, you can write there absolutely everything you want).
-
-    // Hidden variable members
-    /*
-        - Func   - The function that the trigger will call.
-        - Self   - The NPC that will be placed in `self` when the function is called.
-        - Other  - An NPC that will be placed in `other` when the function is called.
-        - Victim - The NPC that will be placed in `victim` when the function is called.
-    */
-};
-

Creating instances

There are two external functions that are used to create C_Trigger instance.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
// function returns a trigger with no NPC (self, other or victim) bound to it
-func C_Trigger AI_StartTriggerScript(   var string funcName,
-                                        var int delay) {};
-
-// function is extended, if certain participants need to be assigned to it
-func C_Trigger AI_StartTriggerScriptEx( var string funcName,
-                                        var int delay,
-                                        var C_Npc slf,
-                                        var C_Npc oth,
-                                        var C_Npc vct) {};
-

Both of these functions return an instance of C_Trigger instance. You can of course configure the instance after its creation. You can, for example, fill in the AIVariables with relevant data. The trigger function has the required signature if 'func int f()'. It must return a value indicating the state of the loop. If the function returns LOOP_END the trigger will be stopped and the instance deleted. If LOOP_CONTINUE is returned, the function will be called again after Delay ms have passed.

Poison example

1
-2
-3
-4
-5
-6
-7
-8
-9
// Implement a trigger to simulate the effect of poison debuff:
-// Let's create a trigger on function `c_loop` with a call interval of 1 second.
-// When the function is called, the instance hero will be placed in self (although it can be any other NPC if desired).
-// The rest of the instances are left null (not used).
-
-var C_Trigger trigger;
-trigger = AI_StartTriggerScriptEx("c_loop", 1000, hero, null, null);
-trigger.AIVariables[0] = 15; // how many times the function should be called
-trigger.AIVariables[1] = 5;  // how much damage to deal each iteration
-

The trigger function

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
func int c_loop()
-{
-    // Create a loop end check, if the number of
-    // available iterations has reached 0. If it did
-    // we stop the trigger by returning the LOOP_END value.
-    if (SelfTrigger.AIVariables[0] <= 0)
-    {
-        return Loop_end;
-    };
-
-    SelfTrigger.Delay -= 20;         // Accelerate loop each call by 20 ms
-    SelfTrigger.AIVariables[0] -= 1; // Reduce number of remaining repeats
-    self.Attribute[ATR_HITPOINTS] -= SelfTrigger.AIVariables[1]; // Take health from self
-    return LOOP_CONTINUE;
-};
-

Trigger scope

Triggers can be divided into two types:

  • Global trigger ( AI_StartTriggerScript ) trigger created using this function works in all worlds. A trigger is considered global by default if neither self nor other nor victim has been provided for it.
  • Local trigger ( AI_StartTriggerScriptEx) trigger created with this function only works in the world in which it was created. A trigger is considered local if it has been presented with at least one NPC in self, other or victim (not null). If you want to create a trigger without linking it to any NPC, it is recommended to simply pass hero as self to the trigger.

Saving

The plugin creates a new save archive to save the information of the triggers that does not conflict with any of the built-in save files.

Searching

To search for a specific trigger, for example by NPC, the trigger external functions can be used.

1
-2
-3
-4
-5
-6
-7
-8
-9
// This way you can disable all triggers running on the `hero` instance
-var C_Trigger trigger = FirstTrigger;
-var C_Trigger trigger_saved;
-while (!Hlp_IsNULL(trigger))
-{
-    trigger_saved = trigger;
-    trigger = AI_GetNextTriggerBySelf(hero);
-    trigger_saved.Enabled = false;
-};
-
\ No newline at end of file diff --git a/zengin/scripts/extenders/zparserextender/classes/helperclasses/index.html b/zengin/scripts/extenders/zparserextender/classes/helperclasses/index.html deleted file mode 100644 index a24b62950d..0000000000 --- a/zengin/scripts/extenders/zparserextender/classes/helperclasses/index.html +++ /dev/null @@ -1,390 +0,0 @@ - Engine classes - Gothic Modding Community

Engine classes

zParserExtender implements various proxy classes that can be used to access game world objects.

Warning

It is not recommended to implement complex mechanics using these classes and functions. They are present as a simple backup option for accessing game world objects and for quick fixes.

C_VOB

This class represents basic pointer to a game world object.

C_Color

Represents color in the RGBA format

1
-2
-3
-4
-5
-6
-7
class C_Color
-{
-    var int R; // red channel value
-    var int G; // green channel value
-    var int B; // blue channel value
-    var int A; // alpha channel value
-};
-

zVEC3

Represents 3D position in the world (float version for internal functions)

1
-2
-3
-4
-5
-6
class zVEC3
-{
-    var float X; // X coordinate
-    var float Y; // Y coordinate
-    var float Z; // Z coordinate
-};
-

C_Position

Represents 3D position in the world

1
-2
-3
-4
-5
-6
class C_Position
-{
-    var int X; // X coordinate
-    var int Y; // Y coordinate
-    var int Z; // Z coordinate
-};
-
Externals:
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
/// Returns the current position of the object in the world
-/// 
-/// @param vob vob to ge the position of
-/// @return C_Position instance - position of the VOB
-func C_Position Vob_GetVobPosition( var C_Vob vob ) {};
-
-/// Sets the current position of the object in the world
-/// 
-/// @param vob vob to get the position of
-/// @param pos new position of the vob
-func void Vob_SetVobPosition( var C_Vob vob, var C_Position pos ) {};
-

Note

The following classes define properties of C_VOB objects or classes derived from it.

C_VOB_DATA

Represents universal zCVob class

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
class C_VOB_DATA
-{
-    var string Name;              // object name
-    var float VisualAlpha;        // object's transparency 0.0 - 1.0
-    var int ShowVisual;           // display the mode
-    var int DrawBBox3D;           // show objects bounding box
-    var int VisualAlphaEnabled;   // enables objects transparency
-    var int PhysicsEnabled;       // enables object's physics
-    var int IgnoredByTraceRay;    // allow any object collisions
-    var int CollDetectionStatic;  // allow collision with static world polygons
-    var int CollDetectionDynamic; // allow collision with dynamic world objects
-    var int CastDynShadow;        // display shadow of the object
-    var int LightColorStatDirty;  // allow static lighting of the object
-    var int LightColorDynDirty;   // allow dynamic lighting of the object
-    var int SleepingMode;         // sets object's activity mode (0 - inactive, 1 - active, 2 - AI only)
-    var int DontWriteIntoArchive; // turns of the serialization of this object to the save file 
-};
-
Externals:
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
/// Returns the universal data of the zCVob object
-///
-/// @param vob VOB to get the position of
-/// @return general vob data C_Vob_Data
-func C_Vob_Data Vob_GetVobData( var C_Vob vob ) {};
-
-/// Sets the universal data to a zCVob object
-///
-/// @param vob VOB to get the position of
-/// @param data general vob data C_Vob_Data
-func void Vob_SetVobData( var C_Vob vob, var C_Vob_Data data ) {};
-

C_LIGHT_DATA

Represents zCVobLight objects

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
class C_LIGHT_DATA
-{
-    var int R;                // red light intensity
-    var int G;                // green light intensity
-    var int B;                // blue light intensity
-    var int Range;            // radius
-    var int RangeInv;         // 
-    var int RangeBackup;      // 
-    var int RangeAniActFrame; // current light animation frame for the radius
-    var int RangeAniFPS;      // speed of light animation for the radius
-    var int ColorAniActFrame; // current light animation frame for colour
-    var int ColorAniFPS;      // speed of light animation for colour
-    var int SpotConeAngleDeg; // angle of cone light source
-    var int IsStatic;         // whether the source is static
-    var int RangeAniSmooth;   // [UNUSED]
-    var int RangeAniLoop;     // [UNUSED]
-    var int ColorAniSmooth;   // allows soft transitions between colours
-    var int ColorAniLoop;     // [UNUSED]
-    var int IsTurnedOn;       // whether the light source is on
-    var int LightQuality;     // source quality (when statically compiling light) (0 - high, 1 - medium, 2 - low)
-    var int LightType;        // type of source (at static light compilation) (0 - point, 1 - cone)
-};
-
Externals:
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
/// Returns zCVobLight object data
-///
-/// @param vobLight vobLight object
-/// @return C_Light_Data of the light
-func C_Light_Data Vob_GetLightData( var C_Vob vobLight ) {};
-
-/// Sets the data of a zCVobLight object
-///
-/// @param vobLight object to apply the light data to
-/// @param data C_Light_Data light data to be set
-func void Vob_SetLightData( var C_Vob vobLight, var C_Light_Data data ) {};
-
-/// Clears the list of animation colours for the light source
-///
-/// @param vobLight light vob
-func void Vob_ClearLightAniList( var C_Vob vobLight ) {};
-
-/// Adds a color to the colour list
-///
-/// @param vobLight object to apply the colour to
-/// @param col colour to be applied
-func void Vob_AddLightAniColor( var C_Vob vobLight, var C_Color col ) {};
-
-/// Adds a color to the colour list
-///
-/// @param vobLight object to apply the colour to
-/// @param r red colour channel
-/// @param g green colour channel 
-/// @param b blue colour channel
-func void Vob_AddLightAniColorRGB(  var C_Vob vobLight,
-                                    var int r,
-                                    var int g,
-                                    var int b ) {};
-

C_MOB_DATA

Represents data for the used oCMOB object

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
class C_MOB_DATA
-{
-    var string VisibleName;     // name shown above the object
-    var int Hitpoints;          // number of hitpoints
-    var int Damage;             // damage the object can cause
-    var int IsDestroyed;        // if the object is destroyed
-    var int Moveable;           // whether the object can be moved
-    var int Takeable;           // whether the object can be taken
-    var int FocusOverride;      // if the object will redefine focus in combat mode
-    var int SndMat;             // object's material (0 - wood, 1 - stone, 2 - metal, 3 - skin, 4 - clay, 5 - glass)
-    var string VisualDestroyed; // model when the object is destroyed
-    var string OwnerStr;        // name of the instance of the owner of the object
-    var string OwnerGuildStr;   // name of the guild of the object
-    var int Owner;              // instance of the owner
-    var int OwnerGuild;         // guild instance
-    var int FocusNameIndex;     // the script string of the displayed name
-};
-
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
/// Returns the data of the oCMOB object
-///
-/// @param mob oCMOB object
-/// @return mob data
-func C_Mob_Data Vob_GetMobData( var C_Vob mob ) {};
-
-/// Sets the data of the oCMOB object
-///
-/// @param mob oCMOB object
-/// @param data C_Mob_Data to be set 
-func void Vob_SetMobData( var C_Vob mob, var C_Mob_Data data ) {};
-

C_MOBINTER_DATA

Represents data for the interactive object oCMobInter

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
class C_MOBINTER_DATA
-{
-    var string TriggerTarget;   // object name which will be triggered by OnTrigger
-    var string UseWithItem;     // name of the object instance that is needed for interaction
-    var string Sceme;           // name of the scene that corresponds to the object and character animations
-    var string ConditionFunc;   // scripting condition under which the interaction can be performed
-    var string OnStateFuncName; // the name pattern of the functions that will be called when the object changes the state
-    var int State;              // the current state of the object
-    var int State_num;          // number of object's states
-    var int State_target        // current state of the object
-    var int Rewind;             // prohibits object updating
-    var int MobStateAni;        // current animation of the object
-    var int NpcStateAni;        // current character animation
-};
-
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
/// Returns the data of the oCMobInter object
-///
-/// @param mobInter oCMobInter object
-/// @return MobInter_Data of the object
-func MobInter_Data Vob_GetMobInterData( var C_Vob mobInter ) {};
-
-/// Sets the data of the oCMobInter object
-///
-/// @param mobInter oCMobInter object
-/// @param data MobInter_Data of the object
-func void Vob_SetMobInterData( var C_Vob mobInter, var C_MobInter_Data data ) {};
-

C_MOBLOCKABLE_DATA

Represents data for the locked interactive object oCMobLockable

1
-2
-3
-4
-5
-6
-7
-8
class C_MOBLOCKABLE_DATA
-{
-    var int Locked;         // whether the object is locked
-    var int AutoOpen;       // [UNUSED]
-    var int PickLockNr;     // current rotation number 
-    var string KeyInstance; // key instance name for the object
-    var string PickLockStr; // combination to open the object ("LRRLR")
-};
-
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
/// Returns the data of the oCMobLockable object
-///
-/// @param mobLock oCMobLockable object
-/// @param data MobInter_Data of the object
-func C_MobLockable_Data Vob_GetMobInterData( var C_Vob mobLock ) {};
-
-/// Sets the data of the oCMobLockable object
-///
-/// @param mobLock oCMobLockable object
-/// @param data C_MobLockable_Data of the object
-func void Vob_SetMobInterData( var C_Vob mobLock, var C_MobLockable_Data data ) {};
-
\ No newline at end of file diff --git a/zengin/scripts/extenders/zparserextender/daedalus_injection/hooks/index.html b/zengin/scripts/extenders/zparserextender/daedalus_injection/hooks/index.html deleted file mode 100644 index 097ff0687f..0000000000 --- a/zengin/scripts/extenders/zparserextender/daedalus_injection/hooks/index.html +++ /dev/null @@ -1,84 +0,0 @@ - Hooking - Gothic Modding Community

Hooking Daedalus

Daedalus hooking is one of the most powerful features of this plugin. Hooking is a mechanism that allows you to replace any scripted object with a new one. To do this, you must define a new object with the same type, name and in the same namespace.

Hook/replacement will be performed only if the MergeMode setting is set to true for the current script in the META block or in the parameter of the same name in the .ini file of the mod.

Warning

If you forget to turn on the MergeMode, the compilation will fail with the redefinition error.

When an object (instance, function or variable) is hooked/replaced, the original one is available under the same name with the _old suffix (PC_Hero -> PC_Hero_old). This allows you to refer to the old object.

Function hook example

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
func void ZS_Attack_Loop()
-{
-    // if the enemy is a player and has no weapon, then
-    // also sheath the weapon.
-    if (Npc_IsPlayer(other) && !Npc_HasReadiedWeapon(other))
-    {
-        return LOOP_END;
-    };
-
-    // otherwise call the original function
-    return ZS_Attack_Loop_Old();
-};
-

This kind of substitution works for instances and variables too.

Warning

While hooking an instances, you have to take care not to call the prototype. Prototype should be always changed back to the original class.

This is wrong
1
-2
-3
-4
-5
instance pc_hero(Npc_Default)
-{
-    pc_hero_old();
-    name = "Pepe";
-};
-
This leads to a double call of prototype Npc_Default which is considered an unsafe practice with undefined behaviour.

The correct way is to call it like this:

1
-2
-3
-4
-5
instance pc_hero(C_NPC) // no prototype Npc_Default
-{
-    pc_hero_old();
-    name = "Pepe";
-};  
-
This way the prototype is called in the original function pc_hero_old() and not for the second time when creating the new hooked instance.

Dialogue hook example

The hooking mechanism is designed to introduce new dialogues into the game as well as replacing old ones with hooks. The scripter can create new merchants, quests, dialogues, as well as attach svm phrases to them.

All new or replaced dialogues will immediately become available, including from saves. In the event that new dialogs are disabled (plugin or script removed), the engine will continue to keep them in the save file, which will allow the dialogs to return at any time with the same state they were in the last time.

Warning

Currently not working as intended (I think). The old dialogue is still used and as a result you will end up with both the old and the new dialogue (unless you edit the old condition function).

1
-2
-3
-4
-5
instance DIA_XARDAS_HELLO(C_INFO)
-{
-    DIA_XARDAS_HELLO_old();
-    important = FALSE;
-};
-
\ No newline at end of file diff --git a/zengin/scripts/extenders/zparserextender/daedalus_injection/index.html b/zengin/scripts/extenders/zparserextender/daedalus_injection/index.html deleted file mode 100644 index 9c7d8e44c7..0000000000 --- a/zengin/scripts/extenders/zparserextender/daedalus_injection/index.html +++ /dev/null @@ -1,34 +0,0 @@ - Daedalus Injection - Gothic Modding Community

Daedalus Injection

Script injection is a process of injecting Daedalus scripts on runtime without the need to recompile the scripts. This is essential for Union plugins that need to alter the scripts in a certain way, either for hotfixes or just for testing scripts without the need to recompile the whole .dat file.

To inject a script, simply put a .d or .src file in Gothic/System/Autorun directory and run the game.

Tip

Automatic injection does not extend to nested directories in the Autorun directory directly, but you can put a .src file into Autorun directory and the rest into a subdirectory to keep a cleaner structure.

Scripts in subdirectories can be accessed in two ways

  1. They are specified in a .src file
  2. The script file is an API script

API script

API scripts are .d files placed in Autorun subdirectories and are used as a dependency. It is assumed that the API script is not called on its own (or from a .src) file, but is called using the dependency keyword After in one of the injected script files' META block.

These scripts are meant to contain ready-made solution that need to be used by many other scripts as a dependency.

Warning

If the file specified in the After tag in the META block does not exist, the current file will not be parsed and injected since the dependency is missing, and it would fail. Due to this it is best to ship the dependency in the Autorun directory even if it comes from a different plugin.

\ No newline at end of file diff --git a/zengin/scripts/extenders/zparserextender/daedalus_injection/meta/index.html b/zengin/scripts/extenders/zparserextender/daedalus_injection/meta/index.html deleted file mode 100644 index 9bad5b021a..0000000000 --- a/zengin/scripts/extenders/zparserextender/daedalus_injection/meta/index.html +++ /dev/null @@ -1,95 +0,0 @@ - META block - Gothic Modding Community

META block

The META block is optional. If it is specified, it has to be the very first thing in the file without any indent or a comment above it.

Syntax:

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
META
-{
-    Parser // specifies into which compiled file the scripts are going to be injected
-    /*
-        Code    Name              DAT file
-        ---     ------            -------
-        Game    parser            Gothic.dat
-        SFX     parserSoundFX     SFX.dat
-        PFX     parserParticleFX  ParticleFX.dat
-        VFX     parserVisualFX    VisualFX.dat
-        Camera  parserCamera      Camera.dat
-        Menu    parserMenu        Menu.dat
-        Music   parserMusic       Music.dat
-    */
-    MergeMode   // 0 - if conflict occurs = compilation error, 1 - if conflict occurs = hook
-    Engine      // comma separated list of engines for which the scripts will be injected 
-    /*
-        Code  Engine          Human readable name
-        ---   -----           -----------------------
-        G1    Gothic I        Gothic I Classic
-        G1A   Gothic Sequel   Gothic I Addon <3
-        G2    Gothic II       Gothic II Classic
-        G2A   Gothic II NoTR  Gothic II Addon
-    */
-
-    NativeWhile // use native while
-    Namespace   // namespace of this script file
-    Using       // comma separated list of namespaces, that are considered local for this script file
-    Mod         // specify for which mod should this code be injected
-    After       // comma separated list of scripts, after which this script should be parsed
-};
-
\ No newline at end of file diff --git a/zengin/scripts/extenders/zparserextender/daedalus_injection/other/index.html b/zengin/scripts/extenders/zparserextender/daedalus_injection/other/index.html deleted file mode 100644 index 8fbb540f9e..0000000000 --- a/zengin/scripts/extenders/zparserextender/daedalus_injection/other/index.html +++ /dev/null @@ -1,122 +0,0 @@ - Other features - Gothic Modding Community

Other functions of the extender

ini parameters

The choice of ini file depends on how the game was launched. If it was launched from Gothic.exe, then the parameters will be read from SystemPack.ini. If it was launched through GothicStarter.exe, then they will be read from the ini of the mod.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
[zParserExtender]
-LoadScript(obsolete) =
-;specifies a parser-script format script to run the scripts. The parameter is currently invalid.
-
-MergeMode = True
-;specifies whether injections will produce hooks.
-
-CompileDat = False
-;Determines if a copy of DAT file which has been modified by injection will be created.
-
-CompileOU = False
-;determines if a copy of an injection-modified OU file will be created.
-
-NativeWhile = False
-;Determines if a WHILE loop will be compiled. Defaults to False (for Ninja compatibility).
-
-MessagesLevel = 1
-;sets the output level. The higher the level, the more information will be printed to the debug console.
-
-StringIndexingMode = -1
-;defines string indexing mode (see string indexing). Default value is -1.
-;Default   = -1 - The default mode for the moment is Repair mode.
-;Disabled  =  0 - Do nothing with the indices.
-;TopSymbol =  1 - The plugin finds the uppermost unnamed string and sets a counter for it.
-;Repair    =  2 - The plugin goes through the whole string table and, if the indexing order is broken, puts the correct names. The counter is set on the basis of the search.
-

MARVIN console commands

zParserExtender adds console commands that save copies of the .dat files with the injected code.

Warning

If the mod uses Ikarus, the CompileDat option (in the .ini file) should be used since a fatal error may occur when using the command.

1
-2
-3
-4
-5
-6
-7
-8
-9
Parser SaveDat OU        - exports OU.Edited.bin
-Parser SaveDat Game      - exports Gothic.Edited.dat
-Parser SaveDat SFX       - exports SFX.Edited.dat
-Parser SaveDat PFX       - exports ParticleFX.Edited.dat
-Parser SaveDat VFX       - exports VisualFX.Edited.dat
-Parser SaveDat Camera    - exports Camera.Edited.dat
-Parser SaveDat Menu      - exports Menu.Edited.dat
-Parser SaveDat Music     - exports Music.Edited.dat
-Parser Export Stringlist - exports the full string table to Scripts\Exports\StringList.d
-

Launch options

Command line parameters can be passed to the game's exe via the command line or using GothicStarter_Mod.

1
-2
-3
-4
-5
-6
-7
-8
zReparse_OU     - parses and creates OU.bin
-zReparse_Game   - parses and creates Gothic.dat
-zReparse_SFX    - parses and creates SFX.dat
-zReparse_PFX    - parses and creates ParticleFX.dat
-zReparse_VFX    - parses and creates VisualFX.dat
-zReparse_Camera - parses and creates Camera.dat
-zReparse_Menu   - parses and creates Menu.dat
-zReparse_Music  - parses and creates Music.dat
-

Note

If you want to compile OU, you also have to include the Game parameter

-zReparse_Game -zReparse_OU

Const array access

The original zParser doesn't allow direct access to const string arrays. zParserExtender allows you to do so.

Example:

1
-2
-3
-4
func event GameInit()
-{
-    Hlp_MessageBox(TXT_INV_CAT[4]); // Prints "Artifacts"
-};
-

Other engine fixes

  1. When creating an item instance, the instance is placed into the global item instance
  2. On DAT file load, the engine restores the original symbol hierarchy
  3. When loading a save, the engine now skips unknown symbols, instead of crashing
\ No newline at end of file diff --git a/zengin/scripts/extenders/zparserextender/dialogues/index.html b/zengin/scripts/extenders/zparserextender/dialogues/index.html deleted file mode 100644 index 096f1e4775..0000000000 --- a/zengin/scripts/extenders/zparserextender/dialogues/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/zengin/scripts/extenders/zparserextender/events/index.html b/zengin/scripts/extenders/zparserextender/events/index.html deleted file mode 100644 index dc34083f74..0000000000 --- a/zengin/scripts/extenders/zparserextender/events/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/zengin/scripts/extenders/zparserextender/examples/signposts/index.html b/zengin/scripts/extenders/zparserextender/examples/signposts/index.html deleted file mode 100644 index c244063aec..0000000000 --- a/zengin/scripts/extenders/zparserextender/examples/signposts/index.html +++ /dev/null @@ -1,367 +0,0 @@ - Sign post example - Gothic Modding Community

Sign post teleportation

This is a short "problem-solving" example, where we try to demonstrate the power of Daedalus injection using zParserExtender. GaroK asked me if there is a way to teleport to all the sign posts in Khorinis to gather information for a Gothic wiki article.
The goal is to introduce a function that will teleport you to every signpost in Khorinis with the press of a button.

The problem

In ZenGin you can teleport to named game objects with the goto vob {vobname} command. But since the signposts do not have a vobname defined, I had to figure out a different approach.

ASCII ZEN

We want to get all the signposts position from Khorinis. The game world was loaded into one of the available world editor, I found one of the signposts and noted the visual which dictates the model of the in-game object nw_misc_sign_01.3DS. Alternatively, you can find the standard vanilla objects from both games on this website.
Next, the world was saved as a ASCII ZEN format. This allows us to write a macro to search for all instances of objects with a specific visual and extract the position vector.

One signpost object
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
[% oCMOB:zCVob 47105 317]
-    pack=int:0
-    presetName=string:
-    bbox3DWS=rawFloat:7564.8291 127.361191 -80.5309067 7611.52441 377.422913 1.67681122 
-    trafoOSToWSRot=raw:73e1673f9c4ec33b15efd8be4465d7bba0fe7f3f30ea7137e5edd83eecaa353bb7e2673f
-    trafoOSToWSPos=vec3:7588.17627 252.391052 -39.4283791
-    vobName=string:
-    visual=string:NW_MISC_SIGN_01.3DS
-    showVisual=bool:1
-    visualCamAlign=enum:0
-    visualAniMode=enum:0
-    visualAniModeStrength=float:0
-    vobFarClipZScale=float:1
-    cdStatic=bool:1
-    cdDyn=bool:1
-    staticVob=bool:1
-    dynShadow=enum:0
-    zbias=int:0
-    isAmbient=bool:0
-    [visual zCProgMeshProto 53505 318]
-    []
-    [ai % 0 0]
-    []
-    focusName=string:MOBNAME_INCITY02
-    hitpoints=int:10
-    damage=int:0
-    moveable=bool:0
-    takeable=bool:0
-    focusOverride=bool:0
-    soundMaterial=enum:0
-    visualDestroyed=string:
-    owner=string:
-    ownerGuild=string:
-    isDestroyed=bool:0
-[]
-

Tip

You can also see that the focusName has a MOBNAME_INCITY02 string constant.
This constant is defined in the scripts and its content is used as the focus name.

const string MOBNAME_INCITY02 = "To Marketplace";
-

The injectable script

As it is an injectable script, we have to specify the META tag.
Lets tell zParserExtender to insert this code into the game parser.

1
-2
-3
-4
META
-{
-    Parser = Game
-};
-
We want to teleport the player and for this we will need the C_Position and C_Vob_Data classes.
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
class C_Position
-{
-    var int X; // X coordinate
-    var int Y; // Y coordinate
-    var int Z; // Z coordinate
-};
-
-class C_VOB_DATA
-{
-    var string Name;              // object name
-    var float VisualAlpha;        // object's transparency 0.0 - 1.0
-    var int ShowVisual;           // display the mode
-    var int DrawBBox3D;           // show objects bounding box
-    var int VisualAlphaEnabled;   // enables objects transparency
-    var int PhysicsEnabled;       // enables object's physics
-    var int IgnoredByTraceRay;    // allow any object collisions
-    var int CollDetectionStatic;  // allow collision with static world polygons
-    var int CollDetectionDynamic; // allow collision with dynamic world objects
-    var int CastDynShadow;        // display shadow of the object
-    var int LightColorStatDirty;  // allow static lighting of the object
-    var int LightColorDynDirty;   // allow dynamic lighting of the object
-    var int SleepingMode;         // sets object's activity mode (0 - inactive, 1 - active, 2 - AI only)
-    var int DontWriteIntoArchive; // turns of the serialization of this object to the save file 
-};
-
It turns out there is 54 instances of objects with the desired visual. Let us define const int NUM_OF_SIGNS = 54 and a const int MAX_COORDS = 3 * NUM_OF_SIGNS - we will store 3 times 54 integers - for every signpost a x, y and z coordinate. And lastly a const int array containing all the positions.
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
-37
-38
-39
-40
-41
-42
-43
-44
-45
-46
-47
-48
-49
-50
-51
-52
-53
-54
-55
-56
-57
-58
-59
-60
// Number of signs we want to jump to
-const int NUM_OF_SIGNS = 54;
-const int MAX_COORDS = 3 * NUM_OF_SIGNS;
-
-const int sign_coordinates[MAX_COORDS] = {
-    11974,  309,   6815,
-    12024,  310,   6778,
-    12411,  1668,  -22495,
-    19491,  1281,  1669,
-    19563,  1281,  1687,
-    20294,  2058,  12487,
-    20324,  2058,  12419,
-    21917,  2900,  -22751,
-    2600,   -57,   -4351,
-    26695,  2419,  4308,
-    26770,  2418,  4319,
-    26978,  2937,  6130,
-    27015,  2936,  6104,
-    27049,  2937,  6159,
-    2964,   2142,  14424,
-    31383,  3896,  4699,
-    31427,  3896,  4640,
-    35368,  3870,  -4374,
-    35435,  3870,  -4355,
-    35437,  3871,  -4399,
-    36205,  3333,  -27186,
-    37774,  3875,  -501,
-    37812,  3874,  -469,
-    37849,  3874,  -512,
-    38291,  3732,  -6699,
-    39276,  3926,  -3357,
-    39307,  3924,  -3313,
-    39351,  3924,  -3359,
-    39435,  4350,  10902,
-    39458,  4350,  10827,
-    40932,  3861,  -3054,
-    42454,  2838,  -19437,
-    5297,   387,   -2145,
-    5358,   387,   -2184,
-    5362,   387,   -2128,
-    54006,  1723,  -10316,
-    54035,  1723,  -10387,
-    551,    -62,   -1820,
-    61080,  2132,  -11622,
-    61155,  2132,  -11625,
-    6408,   392,   3598,
-    6432,   393,   3652,
-    7000,   387,   -1482,
-    73439,  3341,  -11307,
-    7588,   252,   -39,
-    7590,   252,   -109,
-    7642,   253,   -83,
-    7713,   387,   -4782,
-    7758,   386,   -4775,
-    7776,   388,   -4811,
-    8154,   1206,  -17022,
-    8855,   395,   -2402,
-    9704,   393,   5129,
-    9738,   392,   5108
-};
-
Next define a built in event GameLoop function, to check for a pressed key. If the key U is pressed, the jump_to_sign function is called.
1
-2
-3
-4
-5
-6
-7
-8
-9
// check for pressed U button every frame
-func event GameLoop()
-{
-    // if U is toggled, run the function
-    if (Hlp_KeyToggled(KEY_U))
-    {
-        jump_to_sign();
-    };
-};
-

Let's look at the jump_to_sign function now.
This function is called on every U key press and goes through all the signposts and teleports the player to them.
At the start of the function we check if the index is not out of bounds and if it is, sets it back to 0 and starts over.

1
-2
-3
-4
-5
    // if we reached the end, start over
-    if (tp_index >= NUM_OF_SIGNS)
-    {
-        tp_index = 0;
-    };
-
Notice the use of Str_Format function for the formatted output.
1
-2
-3
-4
-5
// give information to the player
-Print(Str_Format("Sign %i/%i", tp_index+1, NUM_OF_SIGNS));
-
-var C_Position pos;  pos  = Vob_GetVobPosition(hero);
-var C_Vob_Data data; data = Vob_GetVobData(hero);
-
Daedalus does not allow array access with variables (only constants and literals). To access the coordinate array we use a selection of parser functions.
Firstly we get the game parser ID. Then we can use the Par_GetSymbolValueIntArray to access the sign_coordinates array and assign the coordinates to the pos variable.
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
// get parser ID for the GAME parser
-var int game_par_id; game_par_id = Par_GetParserID("game");
-
-// get parser ID of the array
-var int arr_id; arr_id = Par_GetSymbolID(game_par_id ,"sign_coordinates");
-
-// access the coordinates from above array
-pos.x = Par_GetSymbolValueIntArray(game_par_id ,arr_id ,tp_index * 3    ); 
-pos.y = Par_GetSymbolValueIntArray(game_par_id ,arr_id ,tp_index * 3 + 1);
-pos.z = Par_GetSymbolValueIntArray(game_par_id ,arr_id ,tp_index * 3 + 2);
-
And now comes the big trick. If you try to just change the position the dynamic and static collision is going to stop you at the first wall, tree or a mountain. To disable it, we can use the C_Vob_Data helper class, get players data, and disable both the static a dynamic collision. First we create a backup of the values just so we can restore them back after the teleport.
1
-2
-3
-4
-5
-6
-7
// backup original collision detection
-var int dyn;   dyn = data.CollDetectionDynamic;
-var int stat; stat = data.CollDetectionStatic;
-
-// turn off collision detection 
-data.CollDetectionDynamic = 0;
-data.CollDetectionStatic  = 0;
-
Let us apply the changed data to the player and edit the position.
1
-2
-3
-4
-5
// apply the edited data to player
-Vob_SetVobData(hero, data);
-
-// move the player 
-Vob_SetVobPosition(hero, pos);
-
Restore the collision detection data from the backup we made and set it.
1
-2
-3
-4
-5
-6
// restore collision detection
-data.CollDetectionDynamic = dyn;
-data.CollDetectionStatic  = stat;
-
-// apply the edited data to player
-Vob_SetVobData(hero, data);
-
Finally, we advance the index to jump to another signpost.
1
-2
// advance the index
-tp_index += 1;
-
\ No newline at end of file diff --git a/zengin/scripts/extenders/zparserextender/extern/index.html b/zengin/scripts/extenders/zparserextender/extern/index.html deleted file mode 100644 index cfee35ac90..0000000000 --- a/zengin/scripts/extenders/zparserextender/extern/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/zengin/scripts/extenders/zparserextender/externals/ai/index.html b/zengin/scripts/extenders/zparserextender/externals/ai/index.html deleted file mode 100644 index a16fb7148a..0000000000 --- a/zengin/scripts/extenders/zparserextender/externals/ai/index.html +++ /dev/null @@ -1,66 +0,0 @@ - AI functions - Gothic Modding Community

AI - functions for working with AI

Functions to work with the new C_Trigger class and NPC's AI queue.

AI_CallScript

Adds a funcName function call to the AI queue

1
-2
-3
func void AI_CallScript(var string funcName,
-                        var C_NPC slf,
-                        var C_NPC oth) {};
-
  • funcName - name of the function to be called
  • slf - will be inserted into global self instance
  • oth - will be inserted into global other instance

AI_startTriggerScript

Creates a trigger script that calls function funcName once every interval in milliseconds

func C_Trigger AI_startTriggerScript(var string funcName, var int interval) {};
-
  • funcName - name of the function to be called
  • interval - call period in milliseconds
  • return - created C_Trigger instance

AI_startTriggerScriptEx

Extended version call - Creates a trigger script, that calls function funcName once every interval in milliseconds also updates the self, other and victim global instances based on slf, oth and vct parameters respectively

1
-2
-3
-4
-5
func C_Trigger AI_startTriggerScriptEx( var string funcName,
-                                        var int interval,
-                                        var C_NPC slf,
-                                        var C_NPC oth,
-                                        var C_NPC vct) {};
-
  • funcName - name of the function to be called
  • interval - call period in milliseconds
  • slf - will be inserted into global self instance
  • oth - will be inserted into global other instance
  • vct - will be inserted into global victim instance
  • return - created C_Trigger instance

AI_GetTriggerByID

Returns a C_Trigger instance from the array of active triggers by the array index ID

func C_Trigger AI_GetTriggerByID(var int ID) {};
-
  • ID - array id
  • return - active C_Trigger instance

AI_GetTriggersNum

Returns the number of active C_Trigger scripts

func int AI_GetTriggersNum() {};
-
  • return - number of active C_Trigger scripts

AI_GetTriggerNPC

Returns the npc associated with the C_Trigger script based on the ID selfID = 0; otherID = 1; victimID = 2;

func C_NPC AI_GetTriggerNPC(var C_Trigger trigger, var int npcID) {};
-
  • trigger - C_Trigger script
  • npcID - NPC id
  • return - active C_Trigger instance

AI_GetTriggerFunc

Returns the function associated with the specified C_Trigger

func func AI_GetTriggerFunc(var C_Trigger trigger) {};
-
  • trigger - C_Trigger script
  • return - trigger function

AI_GetTriggerFuncName

Returns the function name of a function associated with the specified C_Trigger

func string AI_GetTriggerFuncName(var C_Trigger trigger) {};
-
  • trigger - C_Trigger script
  • return - active C_Trigger instance

Ai_GetNextTriggerByFunc

Returns the next trigger in the active trigger array based on the trigger function, starting on the startTrigger trigger

func C_Trigger Ai_GetNextTriggerByFunc(var C_Trigger startTrigger, var func function) {};
-
  • startTrigger - C_Trigger script to start the search from
  • function - function to be matched
  • return - C_Trigger instance

Ai_GetNextTriggerByFuncName

Returns the next trigger in the active trigger array based on the trigger function name, starting on the startTrigger trigger

func C_Trigger Ai_GetNextTriggerByFuncName(var C_Trigger startTrigger, var string functionName) {};
-
  • startTrigger - C_Trigger script to start the search from
  • functionName - name of a function to be matched
  • return - C_Trigger instance

Ai_GetNextTriggerBySelf

Returns the next trigger in the active trigger array based on the self trigger parameter, starting on the startTrigger instance set in the trigger

func C_Trigger Ai_GetNextTriggerBySelf(var C_Trigger startTrigger, var C_NPC self) {};
-
  • startTrigger - C_Trigger script to start the search from
  • self - C_NPC instance
  • return - C_Trigger instance

Ai_GetNextTriggerByOther

Returns the next trigger in the active trigger array based on the other trigger parameter, starting on the startTrigger instance set in the trigger

func C_Trigger Ai_GetNextTriggerByOther(var C_Trigger startTrigger, var C_NPC other) {};
-
  • startTrigger - C_Trigger script to start the search from
  • other - C_NPC instance
  • return - C_Trigger instance

Ai_GetNextTriggerByVictim

Returns the next trigger in the active trigger array based on the victim trigger parameter, starting on the startTrigger instance set in the trigger

func C_Trigger Ai_GetNextTriggerByVictim( var C_Trigger startTrigger, var C_NPC victim ) {};
-
  • startTrigger - C_Trigger script to start the search from
  • victim - C_NPC instance
  • return - C_Trigger instance

Ai_GetNextTriggerByNPCs

Returns the next trigger in the active trigger array based on all the NPCs set in the trigger script self, other and victim, starting on the startTrigger instance set in the trigger

1
-2
-3
-4
func c_trigger Ai_GetNextTriggerByNPCs( var C_Trigger startTrigger,
-                                        var C_NPC self,
-                                        var C_NPC other,
-                                        var C_NPC victim) {};
-
  • startTrigger - C_Trigger script to start the search from
  • self - self C_NPC instance
  • other - other C_NPC instance
  • victim - victim C_NPC instance
  • return - C_Trigger instance
\ No newline at end of file diff --git a/zengin/scripts/extenders/zparserextender/externals/cast/index.html b/zengin/scripts/extenders/zparserextender/externals/cast/index.html deleted file mode 100644 index fa3ffd6f6b..0000000000 --- a/zengin/scripts/extenders/zparserextender/externals/cast/index.html +++ /dev/null @@ -1,45 +0,0 @@ - CAST functions - Gothic Modding Community

CAST - data type conversion functions

External functions for data type conversion and pointer casting.

Cast_PointerToInstance

Converts memory address (pointer) to an instance

func instance Cast_PointerToInstance(var int address) {};
-
  • address - object pointer
  • return - instance of the object

Cast_InstanceToPointer

Converts instance to a memory address (pointer)

func int Cast_InstanceToPointer( var instance object) {};
-
  • object - object instance
  • return - memory address (pointer) of the object

Cast_PointerToNpc

Casts memory address (pointer) to an NPC

func C_NPC Cast_PointerToNpc( var int address) {};
-
  • address - npc pointer
  • return - NPC instance

Cast_PointerToItem

Casts memory address (pointer) to an Item

func C_ITEM Cast_PointerToItem( var int address) {};
-
  • address - item pointer
  • return - Item instance

Cast_InstanceIsNpc

Checks whether object is an NPC

func int Cast_InstanceIsNpc( var instance object) {};
-
  • object - object to check
  • return - TRUE or FALSE

Cast_InstanceIsItem

Checks whether object is an Item

func int Cast_InstanceIsItem( var instance object) {};
-
  • object - object to check
  • return - TRUE or FALSE

Cast_InstanceIsMob

Checks whether object is an MOB

func int Cast_InstanceIsMob( var instance object) {};
-
  • object - object to check
  • return - TRUE or FALSE

Cast_GetInstanceIndex

Returns symbolID of the object, returns -1 when not found

func int Cast_GetInstanceIndex( var instance object) {};
-
  • object - instance of an object
  • return - symbol table index, -1 when not found

Cast_GetClassID

Returns the class identifier of a class by its name

func int Cast_GetClassID( var string className ) {};
-
  • className - name of the class
  • return - class identifier

Cast_GetVobClassID

Returns class identifier of the zCObject vob class

func int Cast_GetVobClassID( var instance object ) {};
-
  • object - object instance
  • return - class zCObject identifier

Cast_CheckVobClassID

Checks if the classId class is the parent class of the object

func int Cast_CheckVobClassID( var int classId, var instance object ) {};
-
  • classId - class identifier, from Cast_GetClassID function
  • object - object instance
  • return - class zCObject identifier
\ No newline at end of file diff --git a/zengin/scripts/extenders/zparserextender/externals/events_vars/index.html b/zengin/scripts/extenders/zparserextender/externals/events_vars/index.html deleted file mode 100644 index 8cda237d92..0000000000 --- a/zengin/scripts/extenders/zparserextender/externals/events_vars/index.html +++ /dev/null @@ -1,55 +0,0 @@ - Event functions - Gothic Modding Community

Event functions and variables

On top of external functions, zParserExtender also adds these event functions and constants.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
/// Every event function with this name is executed once every frame
-func event GameLoop() {};
-
-/// Every event function with this name is executed once on game init
-func event GameInit() {};
-
-/// empty instance
-const instance null;
-
-/// not a number floating point constant
-const float NaN;
-
\ No newline at end of file diff --git a/zengin/scripts/extenders/zparserextender/externals/hlp/index.html b/zengin/scripts/extenders/zparserextender/externals/hlp/index.html deleted file mode 100644 index 80faf5c46f..0000000000 --- a/zengin/scripts/extenders/zparserextender/externals/hlp/index.html +++ /dev/null @@ -1,54 +0,0 @@ - HLP functions - Gothic Modding Community

HLP - help functions

Helper functions generally used for safety checks, to get specific information from the engine or to interface with the configuration .ini files.

Hlp_HasFocusVob

Returns TRUE, if a specified NPC has a Vob in focus

func int Hlp_HasFocusVob( var C_NPC npc ) {};
-
  • npc - NPC
  • return - TRUE if npc has a focus Vob, FALSE if it does not

Hlp_GetFocusVob

Returns NPC's focus Vob

func instance Hlp_GetFocusVob( var C_NPC npc ) {};
-
  • npc - NPC
  • return - focus vob

Hlp_GetFocusVobName

Returns the name of NPC's focus vob

func string Hlp_GetFocusVobName( var C_NPC npc ) {};
-
  • npc - NPC
  • return - focus vob name

Hlp_GetStringLength

Returns the length of a specified string

func int Hlp_GetStringLength( var string str ) {};
-
  • return - length of str

IsNAN

Checks whether floating point number is valid

func int IsNAN( var float value ) {};
-
  • return - TRUE if value is NaN, FALSE if value is a valid floating point number

Hlp_KeyToggled

Checks whether key is toggled

func int Hlp_KeyToggled( var int key ) {};
-
  • key - key code
  • return - TRUE if key is toggled, FALSE if key is not toggled

Hlp_KeyPressed

Checks whether key is pressed

func int Hlp_KeyPressed( var int key ) {};
-
  • key - key code
  • return - TRUE if key is pressed, FALSE if key is not pressed

Hlp_LogicalKeyToggled

Checks whether logical key is toggled

func int Hlp_LogicalKeyToggled( var int key ) {};
-
  • key - key code
  • return - TRUE if key is toggled, FALSE if key is not toggled

Hlp_GameOnPause

Checks whether the game is paused

func int Hlp_GameOnPause() {};
-
  • return - TRUE if the game is paused, FALSE if the game is not paused

Hlp_MessageBox

Opens a message box with a specified message

func void Hlp_MessageBox( var string message ) {};
-
  • message - message to be printed

Hlp_PrintConsole

Prints a message to the Union debug console

func void Hlp_PrintConsole(var string message) {};
-
  • message - message to be printed

Hlp_OptionIsExists

Checks whether the entry in section in .ini file optName exists

optName values

  • "Gothic"
  • "Mod"
  • "SystemPack"
func int Hlp_OptionIsExists(var string optName, var string section, var string entry) {};
-
  • optName - the .ini file
  • section - settings section like [GAME]
  • entry - one setting entry like playLogoVideos
  • return - TRUE if the option exists, FALSE if the option does not exist

Hlp_ReadOptionInt

Read an integer value from specified .ini file, section and entry.

optName values

  • "Gothic"
  • "Mod"
  • "SystemPack"
func int Hlp_ReadOptionInt(var string optName, var string section, var string entry, var int default) {};
-
  • optName - the .ini file
  • section - settings section like [GAME]
  • entry - one setting entry like playLogoVideos
  • default - default value - if the value is empty
  • return - the option value

Hlp_ReadOptionFloat

Read a floating point value from specified .ini file, section and entry.

optName values

  • "Gothic"
  • "Mod"
  • "SystemPack"
func float Hlp_ReadOptionFloat(var string optName, var string section, var string entry, var float default) {};
-
  • optName - the .ini file
  • section - settings section like [INTERFACE]
  • entry - one setting entry like scale
  • default - default value - if the value is empty
  • return - the option value

Hlp_ReadOptionString

Read a string value from specified .ini file, section and entry.

optName values

  • "Gothic"
  • "Mod"
  • "SystemPack"
func string Hlp_ReadOptionString(var string optName, var string section, var string entry, var string default) {};
-
  • optName - the .ini file
  • section - settings section like [INTERFACE]
  • entry - one setting entry like scale
  • default - default value - if the value is empty
  • return - the option value

Hlp_WriteOptionInt

Writes an integer value to specified .ini file, section and entry.

optName values

  • "Gothic"
  • "Mod"
  • "SystemPack"
func void Hlp_WriteOptionInt(var string optName, var string section, var string entry, var int value) {};
-
  • optName - the .ini file
  • section - settings section like [INTERFACE]
  • entry - one setting entry like scale
  • value - value to be written

Hlp_WriteOptionFloat

Writes a floating point value to specified .ini file, section and entry.

optName values

  • "Gothic"
  • "Mod"
  • "SystemPack"
func void Hlp_WriteOptionFloat(var string optName, var string section, var string entry, var float value) {};
-
  • optName - the .ini file
  • section - settings section like [INTERFACE]
  • entry - one setting entry like scale
  • value - value to be written

Hlp_WriteOptionString

Writes a string value to specified .ini file, section and entry.

optName values

  • "Gothic"
  • "Mod"
  • "SystemPack"
func void Hlp_WriteOptionString(var string optName, var string section, var string entry, var string value) {};
-
  • optName - the .ini file
  • section - settings section like [INTERFACE]
  • entry - one setting entry like scale
  • value - value to be written

Hlp_GetSteamPersonalName

Returns the name of the current Steam user Returns empty string when not run with Steam

func string Hlp_GetSteamPersonalName() {};
-
  • return - string containing the Steam username, or an empty string

Hlp_DoEvent

Calls every event function with the name funcName.

func void Hlp_DoEvent(var string funcName) {};
-
  • funcName - name of the event function to be called (all of them).
\ No newline at end of file diff --git a/zengin/scripts/extenders/zparserextender/externals/log/index.html b/zengin/scripts/extenders/zparserextender/externals/log/index.html deleted file mode 100644 index bb60e93858..0000000000 --- a/zengin/scripts/extenders/zparserextender/externals/log/index.html +++ /dev/null @@ -1,36 +0,0 @@ - Log functions - Gothic Modding Community

Log functions

As discussed on Inside Gothic, vanilla Gothic has no way of getting the status of a quest. These functions implement that functionality.

Log_GetTopicStatus

Returns the status of diary topic

  • -1 - Not found
  • 0 - Free
  • 1 - Running
  • 2 - Success
  • 3 - Failure
  • 4 - Obsolete
func int Log_GetTopicStatus(var string topic) {};
-
  • topic - name of the topic
  • return - topic status

Log_GetTopicSection

Returns the topic the diary topic is in

  • -1 - Not found
  • 0 - Missions
  • 1 - Notes
  • 2 - All
func int Log_GetTopicSection(var string topic) {};
-
  • topic - name of the topic
  • return - topic section
\ No newline at end of file diff --git a/zengin/scripts/extenders/zparserextender/externals/mdl/index.html b/zengin/scripts/extenders/zparserextender/externals/mdl/index.html deleted file mode 100644 index 07515b9d3a..0000000000 --- a/zengin/scripts/extenders/zparserextender/externals/mdl/index.html +++ /dev/null @@ -1,46 +0,0 @@ - MDL functions - Gothic Modding Community

MDL - model functions

Functions to tweak animation and other model related settings.

Mdl_GetAnimationIndex

Returns animation's index for specified NPC based on animation's name

func int Mdl_GetAnimationIndex( var C_NPC npc, var string ani_name ) {};
-
  • npc - NPC with the animation
  • ani_name - name of the animation in uppercase
  • return - animation index

Mdl_GetAnimationName

Returns animation's name for specified NPC based on animation's index

func string Mdl_GetAnimationName( var C_NPC npc, var int ani_index ) {};
-
  • npc - NPC with the animation
  • ani_index - animation index
  • return - animation name

Mdl_AnimationIsExists

Checks whether animation exists

func int Mdl_AnimationIsExists( var C_NPC npc, var int ani_index ) {};
-
  • npc - NPC with the animation
  • ani_index - animation index
  • return - animation name

Mdl_AnimationIsActive

Checks whether animation is active (whether it is currently played)

func int Mdl_AnimationIsActive( var C_NPC npc, var int ani_index ) {};
-
  • npc - NPC with the animation
  • ani_index - animation index
  • return - TRUE if the animation is playing, FALSE if it is not playing

Mdl_SetAllAnimationsFPS

Set framerate for all animations

func void Mdl_SetAllAnimationsFPS( var C_NPC npc, var float fps ) {};
-
  • npc - NPC with the animation
  • fps - framerate

Mdl_ResetAllAnimationsFPS

Reset framerate for all animations to default value

func void Mdl_ResetAllAnimationsFPS( var C_NPC npc ) {};
-
  • npc - NPC with the animation

Mdl_SetAnimationFPS

Set framerate for animation specified by animation index

func void Mdl_SetAnimationFPS( var C_NPC npc, var int ani_index, var float fps ) {};
-
  • npc - NPC with the animation
  • ani_index - animation index
  • fps - framerate

Mdl_ResetAnimationFPS

Reset framerate to default for animation specified by animation index

func void Mdl_ResetAnimationFPS( var C_NPC npc, var int ani_index ) {};
-
  • npc - NPC with the animation
  • ani_index - animation index

Mdl_SetVisible

Set NPCs visibility

func void Mdl_SetVisible( var C_NPC npc, var int isVisible ) {};
-
  • npc - specified NPC
  • isVisible - TRUE - visible, FALSE - invisible

Mdl_ApplyOverlayMds_AtFirst

Applies or moves existing overlay to the top of the list

func void Mdl_ApplyOverlayMds_AtFirst( var string mdsName ) {};
-
  • mdsName - name of the overlay

Mdl_SetNpcSpeedMultiplier

Sets a multiplier for animation speed 1.0 = 100% speed (normal speed)

func void Mdl_SetNpcSpeedMultiplier( var C_Npc npc, var float multiplier ) {};
-
  • npc - npc to be affected
  • multiplier - speed of the animation

Mdl_ResetNpcSpeedMultiplier

Resets the animation speed of an NPC

func void Mdl_ResetNpcSpeedMultiplier( var C_Npc npc ) {};
-
  • npc - npc to be affected
\ No newline at end of file diff --git a/zengin/scripts/extenders/zparserextender/externals/menu/index.html b/zengin/scripts/extenders/zparserextender/externals/menu/index.html deleted file mode 100644 index 46eb1faa99..0000000000 --- a/zengin/scripts/extenders/zparserextender/externals/menu/index.html +++ /dev/null @@ -1,56 +0,0 @@ - Menu function - Gothic Modding Community

Menu function

Find all C_MenuItem object instances by the mask and automatically places them in the current menu instance

func void Menu_SearchItems( var string mask ) {};
-
  • mask - regex like mask for searching

Example

This function is used in the Union Menu API script.
In this script the Menu_SearchItems external is used to collect all Union menu scripts that are placed into the Union & Plugins menu that will appear in the game if you use any of the plugins that use this feature.

Usage of Menu_SearchItems external function
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
instance MENU_OPT_UNION(C_MENU_DEF)
-{
-    Menu_SearchItems("MENUITEM_UNION_AUTO_*");
-    MENU_OPT_UNION_PY = 1200;
-    backpic           = MENU_BACK_PIC;
-    items[0]          = "UNION_MENUITEM_TITLE";
-    items[100]        = "UNION_MENUITEM_BACK";
-    defaultoutgame    = 0;
-    defaultingame     = 0;
-    Flags             = Flags | MENU_SHOW_INFO;
-};
-

In this case all instances are of the name MENUITEM_UNION_AUTO_* where * is a wildcard that can be substituted with anything. The plugin will search the scripts and find all instances (in the case of zGamePad it is MenuItem_Union_Auto_zGamePad)

This example comes from the zUnionMenu.d injectable API script that is part of the zGamePad plugin, GitHub link.

\ No newline at end of file diff --git a/zengin/scripts/extenders/zparserextender/externals/mob/index.html b/zengin/scripts/extenders/zparserextender/externals/mob/index.html deleted file mode 100644 index f68f0eee55..0000000000 --- a/zengin/scripts/extenders/zparserextender/externals/mob/index.html +++ /dev/null @@ -1,45 +0,0 @@ - MOB functions - Gothic Modding Community

MOB - interactive object functions

Functions to manipulate interactive objects like destroying MOBs, setting lockpick combination and such.

Mob_Destroy

Marks oCMOB as destroyed, changes the visual to visualDestroyed (if present).

func void Mob_Destroy( var instance object ) {};
-
  • object - oCMOB to be destroyed

Mob_RemoveItem

Removes an item from a oCMobContainer

func void Mob_RemoveItem( var instance object, var int item ) {};
-
  • object - oCMobContainer object
  • item - item to be removed

Mob_RemoveItems

Removes specified number of items from a oCMobContainer

func void Mob_RemoveItems( var instance object, var int item, var int cnt ) {};
-
  • object - oCMobContainer object
  • item - item to be removed
  • cnt - number of items to be removed

Mob_InsertItem

Inserts an item into a oCMobContainer

func void Mob_InsertItem( var instance object, var int item ) {};
-
  • object - oCMobContainer object
  • item - item to be inserted

Mob_InsertItems

Inserts specified number of items into a oCMobContainer

func void Mob_InsertItems( var instance object, var int item, var int cnt ) {};
-
  • object - oCMobContainer object
  • item - item to be inserted
  • cnt - number of items to be inserted

Mob_GetLockCombination

Returns a lock combination of a oCMobContainer

func string Mob_GetLockCombination( var instance object ) {};
-
  • object - oCMobContainer object
  • return - lock combination

Mob_SetLockCombination

Sets a lock combination to a oCMobContainer

func void Mob_SetLockCombination( var instance object, var string comb ) {};
-
  • object - oCMobContainer object
  • comb - lock combination

Mob_IsLocked

Returns TRUE if the object is locked

func int Mob_IsLocked( var instance object ) {};
-
  • object - oCMobLockable object
  • return - TRUE if locked, FALSE if unlocked

Mob_SetLocked

Set the lock status of the object

func void Mob_SetLocked( var instance object, var int locked ) {};
-
  • object - oCMobLockable object
  • locked - lock or unlock the object

Mob_GetKeyInstance

Returns the key instance, that unlocks the object

func instance Mob_GetKeyInstance( var instance object ) {};
-
  • object - oCMobLockable object
  • return - the key C_ITEM instance

Mob_SetKeyInstance

Stets the key instance, that unlocks the object

func void Mob_SetKeyInstance( var instance object, var int key ) {};
-
  • object - oCMobLockable object
  • key - the key C_ITEM instance
\ No newline at end of file diff --git a/zengin/scripts/extenders/zparserextender/externals/npc/index.html b/zengin/scripts/extenders/zparserextender/externals/npc/index.html deleted file mode 100644 index c8330d0072..0000000000 --- a/zengin/scripts/extenders/zparserextender/externals/npc/index.html +++ /dev/null @@ -1,43 +0,0 @@ - NPC functions - Gothic Modding Community

NPC - character functions

NPC related functions.

Npc_SetAsHero

Changes players character to specified npc

func void Npc_SetAsHero( var C_NPC npc ) {};
-
  • npc - NPC to be set as players character

Npc_OpenInventory

Opens NPCs main inventory

func void Npc_OpenInventory( var C_NPC npc ) {};
-
  • npc - NPC

Npc_OpenInventorySteal

Opens the steal inventory of npc's focus NPC

func void Npc_OpenInventorySteal( var C_NPC npc ) {};
-
  • npc - NPC

Npc_OpenInventoryTrade

Start the trading dialogue with specified NPC

func void Npc_OpenInventoryTrade( var C_NPC npc ) {};
-
  • npc - NPC

Npc_GetLeftHandItem

Returns an item in NPC's left hand slot

func C_Item Npc_GetLeftHandItem( var C_Npc npc ) {};
-
  • npc - npc to be affected
  • return - found C_ITEM instance

Npc_GetRightHandItem

Returns an item in NPC's right hand slot

func C_Item Npc_GetRightHandItem( var C_Npc npc ) {};
-
  • npc - npc to be affected
  • return - found C_ITEM instance

Npc_GetSlotItem

Returns an item from a slot with the slotName

func C_Item Npc_GetSlotItem( var C_Npc npc, var string slotName ) {};
-
  • npc - npc to be affected
  • slotName - name of the slot
  • return - found C_ITEM instance

Npc_PutInSlot

Places an instance of the oCVom class (including items and NPCs) object into the slotName of the NPC The copyInInv parameter determines whether a copy of the object should remain in the character's inventory

func void Npc_PutInSlot(var C_Npc npc, var string slotName, var instance object, var int copyInInv) {};
-
  • npc - npc to remove the item from
  • slotName - name of the slot from which to remove the item
  • object - object to be inserted into the slot
  • copyInInv - should a copy of the object stay in character inventory

Npc_RemoveFromSlot

Removes an object from the slotName of the NPC. The dropIt parameter in Gothic 2 defines, whether object should drop out of the slot. In Gothic 1, this parameter is reserved and must be 0.

func void Npc_RemoveFromSlot(var C_Npc npc, var string slotName, var int dropIt) {};
-
  • npc - npc to remove the item from
  • slotName - name of the slot from which to remove the item
  • dropIt - should the object be dropped
\ No newline at end of file diff --git a/zengin/scripts/extenders/zparserextender/externals/par/index.html b/zengin/scripts/extenders/zparserextender/externals/par/index.html deleted file mode 100644 index b051238179..0000000000 --- a/zengin/scripts/extenders/zparserextender/externals/par/index.html +++ /dev/null @@ -1,51 +0,0 @@ - PAR functions - Gothic Modding Community

PAR - functions for parser manipulation

Parser functions are used to manipulate the parsers. Retrieve SymbolID, access arrays and such.

Par_GetParserID

Returns a parser ID of the parser with a parName name

Parser names:

  • "Game"
  • "SFX"
  • "PFX"
  • "VFX"
  • "Camera"
  • "Menu"
  • "Music"
func int Par_GetParserID(var string parName) {};
-
  • parName - parser name
  • return - parser ID

Par_GetSymbolID

Returns symbol ID for the symbol specified by its name

func int Par_GetSymbolID(var int parId, var string symName) {};
-
  • parID - parser ID
  • symName - symbol name
  • return - symbol ID

Par_GetSymbolLength

Returns symbol length (number of elements)

func int Par_GetSymbolLength(var int parId, var int symId) {};
-
  • parID - parser ID
  • symName - symbol name
  • return - symbol length

Par_GetSymbolValueInt

Returns the integer value of specified symbol

func int Par_GetSymbolValueInt(var int parId, var int symId) {};
-
  • parID - parser ID
  • symName - symbol name
  • return - symbol value

Par_GetSymbolValueFloat

Returns the float value of specified symbol

func float Par_GetSymbolValueFloat(var int parId, var int symId) {};
-
  • parID - parser ID
  • symName - symbol name
  • return - symbol value

Par_GetSymbolValueString

Returns the string value of specified symbol

func string Par_GetSymbolValueString(var int parId, var int symId) {};
-
  • parID - parser ID
  • symName - symbol name
  • return - symbol value

Par_GetSymbolValueInstance

Returns the instance value of specified symbol

func instance Par_GetSymbolValueInstance(var int parId, var int symId) {};
-
  • parID - parser ID
  • symName - symbol name
  • return - symbol value

Par_GetSymbolValueIntArray

Returns the value of specified integer array at the arrayID index

func int Par_GetSymbolValueIntArray(var int parId, var int symId, var int arrayId) {};
-
  • parID - parser ID
  • symName - symbol name
  • arrayID - array index
  • return - value

Par_GetSymbolValueFloatArray

Returns the value of specified float array at the arrayID index

func float Par_GetSymbolValueFloatArray(var int parId, var int symId, var int arrayId) {};
-
  • parID - parser ID
  • symName - symbol name
  • arrayID - array index
  • return - value

Par_GetSymbolValueStringArray

Returns the value of specified string array at the arrayID index

func string Par_GetSymbolValueStringArray(var int parId, var int symId, var int arrayId) {};
-
  • parID - parser ID
  • symName - symbol name
  • arrayID - array index
  • return - value

Par_SetSymbolValueInt

Sets a new integer value to specified symbol

func void Par_SetSymbolValueInt(var int value, var int parId, var int symId) {};
-
  • value - value to be set
  • parID - parser ID
  • symId - symbol ID

Par_SetSymbolValueFloat

Sets a new float value to specified symbol

func void Par_SetSymbolValueFloat(var float value, var int parId, var int symId) {};
-
  • value - value to be set
  • parID - parser ID
  • symId - symbol ID

Par_SetSymbolValueString

Sets a new string value to specified symbol

func void Par_SetSymbolValueString(var string value, var int parId, var int symId) {};
-
  • value - value to be set
  • parID - parser ID
  • symId - symbol ID

Par_SetSymbolValueInstance

Sets a new instance value to specified symbol

func void Par_SetSymbolValueInstance(var instance value, var int parId, var int symId, var int arrayId) {};
-
  • value - value to be set
  • parID - parser ID
  • symId - symbol ID

Par_SetSymbolValueIntArray

Sets a new integer value to specified integer array symbol

func void Par_SetSymbolValueIntArray(var int value, var int parId, var int symId, var int arrayId) {};
-
  • value - value to be set
  • parID - parser ID
  • symId - symbol ID
  • arrayId - array index

Par_SetSymbolValueFloatArray

Sets a new float value to specified float array symbol

func void Par_SetSymbolValueFloatArray(var float value, var int parId, var int symId, var int arrayId) {};
-
  • value - value to be set
  • parID - parser ID
  • symId - symbol ID
  • arrayId - array index

Par_SetSymbolValueStringArray

Sets a new string value to specified string array symbol

func void Par_SetSymbolValueStringArray(var string value, var int parId, var int symId, var int arrayId) {};
-
  • value - value to be set
  • parID - parser ID
  • symId - symbol ID
  • arrayId - array index
\ No newline at end of file diff --git a/zengin/scripts/extenders/zparserextender/externals/string/index.html b/zengin/scripts/extenders/zparserextender/externals/string/index.html deleted file mode 100644 index 807f051e34..0000000000 --- a/zengin/scripts/extenders/zparserextender/externals/string/index.html +++ /dev/null @@ -1,77 +0,0 @@ - String functions - Gothic Modding Community

String functions

Functions to manipulate and format strings.

Str_Format

Returns formatted string using format specifiers

Format specifiers:

  • %s - inserts a string
  • %i - inserts an integer number
  • %x - inserts an integer in hexadecimal
  • %f - inserts a floating point number
  • %b - inserts a logical expression
  • %p - inserts a pointer
func string Str_Format( var string format, ... ) {};
-
  • return - formatted string

Examples

Very powerful function, can be used to streamline strings used in the scripts as well as optimize them for translations.

Define constants containing the string with format specifiers.

1
-2
const string MENU_SAVE = "Slot %i - press ENTER to save in this slot.";
-const string MENU_LOAD = "Slot %i - press ENTER to load saved game.";
-
Then define two format functions as such:
1
-2
-3
-4
func string GetSaveSlotString (var int number)
-{
-    return Str_format(MENU_SAVE, number);
-};
-
1
-2
-3
-4
func string GetLoadSlotString (var int number)
-{
-    return Str_format(MENU_LOAD, number);
-};
-

Tip

Since the whole translatable string is saved in one constant, it is very easy for translators to change the word order. This was not possible to do without code change to the ConcatStrings function calls within the scripts.
With this simple change, translators have to translate only 2 strings instead of 30 (15 + 15 slots) and only 2 strings are compiled into the compiled Menu.dat file.

Str_GetLocalizedString

Returns a string in the current language, otherwise in English. Arguments MUST be encoded in UTF-8! The result string will be converted to appropriate ANSI string.

1
-2
-3
-4
func string Str_GetLocalizedString( var string russian,
-                                    var string english,
-                                    var string german,
-                                    var string polish ) {};
-
  • russian - Russian string
  • english - English string
  • german - German string
  • polish - Polish string
  • return - string in the current language

Str_GetLocalizedStringEx

Returns a string in the current language, otherwise in English. Offers additional languages

1
-2
-3
-4
-5
-6
-7
-8
func string Str_GetLocalizedStringEx(   var string russian,
-                                        var string english,
-                                        var string german,
-                                        var string polish,
-                                        var string romanian,
-                                        var string italian,
-                                        var string czech,
-                                        var string spanish ) {};
-
  • russian - Russian string
  • english - English string
  • german - German string
  • polish - Polish string
  • romanian - Romanian string
  • italian - Italian string
  • czech - Czech string
  • spanish - Spanish string
  • return - string in the current language

Str_UTF8_to_ANSI

Converts UTF-8 string into an ANSI string with codePage

func string Str_UTF8_to_ANSI( var string utf8, var int codePage ) {};
-
  • utf8 - string encoded in UTF8
  • codePage - codePage id, can be obtained from Str_GetCurrentCP
  • return -

Str_GetCurrentCP

Return the code page corresponding to the current language set in the Union System

func int Str_GetCurrentCP() {};
-
  • return - code page corresponding to the current language

Str_GetLength

Returns the length of a string

func int Str_GetLength( var int str ) {};
-
  • str - string to be measured
  • return - length of the string
\ No newline at end of file diff --git a/zengin/scripts/extenders/zparserextender/externals/vob/index.html b/zengin/scripts/extenders/zparserextender/externals/vob/index.html deleted file mode 100644 index 4e4fe343eb..0000000000 --- a/zengin/scripts/extenders/zparserextender/externals/vob/index.html +++ /dev/null @@ -1,55 +0,0 @@ - VOB functions - Gothic Modding Community

VOB - functions for object manipulation

VOB functions allow you to manipulate game world objects.

Vob_GetVobPosition

Returns the current position of the object in the world

func C_Position Vob_GetVobPosition( var C_Vob vob ) {};
-
  • vob - vob to ge the position of
  • return - C_Position instance - position of the VOB

Vob_SetVobPosition

Sets the current position of the object in the world

func void Vob_SetVobPosition( var C_Vob vob, var C_Position pos ) {};
-
  • vob - vob to get the position of
  • pos - new position of the vob

Vob_GetVobData

Returns the universal data of the zCVob object

func C_Vob_Data Vob_GetVobData( var C_Vob vob ) {};
-
  • vob - VOB to get the position of
  • return - general vob data C_Vob_Data

Vob_SetVobData

Sets the universal data to a zCVob object

func void Vob_SetVobData( var C_Vob vob, var C_Vob_Data data ) {};
-
  • vob - VOB to get the position of
  • data - general vob data C_Vob_Data

Vob_GetLightData

Returns zCVobLight object data

func C_Light_Data Vob_GetLightData( var C_Vob vobLight ) {};
-
  • vobLight - vobLight object
  • return - C_Light_Data of the light

Vob_SetLightData

Sets the data of a zCVobLight object

func void Vob_SetLightData( var C_Vob vobLight, var C_Light_Data data ) {};
-
  • vobLight - object to apply the light data to
  • data - C_Light_Data light data to be set

Vob_ClearLightAniList

Clears the list of animation colours for the light source

func void Vob_ClearLightAniList( var C_Vob vobLight ) {};
-
  • vobLight - light vob

Vob_AddLightAniColor

Adds a color to the colour list

func void Vob_AddLightAniColor( var C_Vob vobLight, var C_Color col ) {};
-
  • vobLight - object to apply the colour to
  • col - colour to be applied

Vob_AddLightAniColorRGB

Adds a color to the colour list

1
-2
-3
-4
func void Vob_AddLightAniColorRGB(  var C_Vob vobLight,
-                                    var int r,
-                                    var int g,
-                                    var int b ) {};
-
  • vobLight - object to apply the colour to
  • r - red colour channel
  • g - green colour channel
  • b - blue colour channel

Vob_GetMobData

Returns the data of the oCMOB object

func C_Mob_Data Vob_GetMobData( var C_Vob mob ) {};
-
  • mob - oCMOB object
  • return - mob data

Vob_SetMobData

Sets the data of the oCMOB object

func void Vob_SetMobData( var C_Vob mob, var C_Mob_Data data ) {};
-
  • mob - oCMOB object
  • data - C_Mob_Data to be set

Vob_GetMobInterData

Returns the data of the oCMobInter object

func MobInter_Data Vob_GetMobInterData( var C_Vob mobInter ) {};
-
  • mobInter - oCMobInter object
  • return - MobInter_Data of the object

Vob_SetMobInterData

Sets the data of the oCMobInter object

func void Vob_SetMobInterData( var C_Vob mobInter, var C_MobInter_Data data ) {};
-
  • mobInter - oCMobInter object
  • data - MobInter_Data of the object

Vob_GetMobInterData

Returns the data of the oCMobLockable object

func C_MobLockable_Data Vob_GetMobInterData( var C_Vob mobLock ) {};
-
  • mobLock - oCMobLockable object
  • data - MobInter_Data of the object
  • return - C_MobLockable_Data of the object

Vob_SetMobInterData

Sets the data of the oCMobLockable object

func void Vob_SetMobInterData( var C_Vob mobLock, var C_MobLockable_Data data ) {};
-
  • mobLock - oCMobLockable object
  • data - C_MobLockable_Data of the object
\ No newline at end of file diff --git a/zengin/scripts/extenders/zparserextender/externals/wld/index.html b/zengin/scripts/extenders/zparserextender/externals/wld/index.html deleted file mode 100644 index e628126095..0000000000 --- a/zengin/scripts/extenders/zparserextender/externals/wld/index.html +++ /dev/null @@ -1,61 +0,0 @@ - WLD functions - Gothic Modding Community

WLD - world manipulation functions

Functions related to the world.

Wld_ChangeLevel

Trigger level change.

func void Wld_ChangeLevel( var string world, var string waypoint ) {};
-
  • world - name of the world
  • waypoint - target waypoint

Wld_FindVob

Return the VOB instance based on its name.

func instance Wld_FindVob( var string vobname ) {};
-
  • vobname - name of the vob
  • return - zCVob pointer

Wld_PlayEffectVob

Play a visual effect at specified vob

1
-2
-3
-4
-5
-6
func void Wld_PlayEffectVob(    var string effect,
-                                var instance pvob,
-                                var int level,
-                                var int damage,
-                                var int damage_type,
-                                var int damage_speed ) {};
-
  • effect - effect name
  • pvob - zCVob to play the effect at
  • level - effect level
  • damage - damage amount
  • damage_type - damage type
  • damage_speed - damage interval

Wld_PlayEffectAt

Play a visual effect at specified world coordinates

1
-2
-3
-4
-5
-6
func void Wld_PlayEffectAt( var string effect,
-                            var instance coord,
-                            var int level,
-                            var int damage,
-                            var int damage_type,
-                            var int damage_speed ) {};
-
  • effect - effect name
  • coord - world coordinates (zVEC3) to play the effect at
  • level - effect level
  • damage - damage amount
  • damage_type - damage type
  • damage_speed - damage interval

Wld_ToggleRain

Turns on the rain

func void Wld_ToggleRain( var float weight, var float time ) {};
-
  • weight - the strength of the rain
  • time - rain duration

Wld_SetWeatherType

Sets the weather type. Types:

0 - snow 1 - rain

func void Wld_SetWeatherType( var int type ) {};
-
  • type - weather type

Wld_GetWeatherType

Returns the weather type. Types:

0 - snow 1 - rain

func int Wld_GetWeatherType() {};
-
  • return - weather type
\ No newline at end of file diff --git a/zengin/scripts/extenders/zparserextender/externals/zPE_externals.d b/zengin/scripts/extenders/zparserextender/externals/zPE_externals.d deleted file mode 100644 index c23a4d235c..0000000000 --- a/zengin/scripts/extenders/zparserextender/externals/zPE_externals.d +++ /dev/null @@ -1,1014 +0,0 @@ -// zParserExtender externals with docu comments for DLS implementation -// documentation links lead to the Gothic Modding Community documentation github page -// -// zParserExtender: https://github.com/Gratt-5r2/zparserextender -// GMC: https://github.com/Gothic-Modding-Community/gmc - -// ========================================================= -// -// AI functions -// -// ========================================================= - -/// Adds a `funcName` function call to the AI queue -/// -/// @param funcName name of the function to be called -/// @param slf will be inserted into global `self` instance -/// @param oth will be inserted into global `other` instance -func void AI_CallScript(var string funcName, - var C_NPC slf, - var C_NPC oth) {}; - -/// Creates a trigger script that calls function `funcName` once every `interval` in milliseconds -/// -/// @param funcName name of the function to be called -/// @param interval call period in milliseconds -/// @return created C_Trigger instance -func C_Trigger AI_startTriggerScript(var string funcName, var int interval) {}; - -/// Extended version call - Creates a trigger script, that calls function `funcName` once every -/// `interval` in milliseconds also updates the `self`, `other` and `victim` global instances -/// based on `slf`, `oth` and `vct` parameters respectively -/// -/// @param funcName name of the function to be called -/// @param interval call period in milliseconds -/// @param slf will be inserted into global `self` instance -/// @param oth will be inserted into global `other` instance -/// @param vct will be inserted into global `victim` instance -/// @return created C_Trigger instance -func C_Trigger AI_startTriggerScriptEx( var string funcName, - var int interval, - var C_NPC slf, - var C_NPC oth, - var C_NPC vct) {}; - -/// Returns a C_Trigger instance from the array of active triggers by the array index `ID` -/// -/// @param ID array id -/// @return active C_Trigger instance -func C_Trigger AI_GetTriggerByID(var int ID) {}; - -/// Returns the number of active C_Trigger scripts -/// -/// @return number of active C_Trigger scripts -func int AI_GetTriggersNum() {}; - -const int selfID = 0; -const int otherID = 1; -const int victimID = 2; - -/// Returns the npc associated with the C_Trigger script based on the ID -/// selfID = 0; -/// otherID = 1; -/// victimID = 2; -/// -/// @param trigger C_Trigger script -/// @param npcID [selfID, otherID, victimID] NPC id -/// @return active C_Trigger instance -func C_NPC AI_GetTriggerNPC(var C_Trigger trigger, var int npcID) {}; - -/// Returns the function associated with the specified C_Trigger -/// -/// @param trigger C_Trigger script -/// @return trigger function -func func AI_GetTriggerFunc(var C_Trigger trigger) {}; - -/// Returns the function name of a function associated with the specified C_Trigger -/// -/// @param trigger C_Trigger script -/// @return active C_Trigger instance -func string AI_GetTriggerFuncName(var C_Trigger trigger) {}; - -/// Returns the next trigger in the active trigger array based on the trigger function, -/// starting on the `startTrigger` trigger -/// -/// @param startTrigger C_Trigger script to start the search from -/// @param function function to be matched -/// @return C_Trigger instance -func C_Trigger Ai_GetNextTriggerByFunc(var C_Trigger startTrigger, var func function) {}; - -/// Returns the next trigger in the active trigger array based on the trigger function -/// name, starting on the `startTrigger` trigger -/// -/// @param startTrigger C_Trigger script to start the search from -/// @param functionName name of a function to be matched -/// @return C_Trigger instance -func C_Trigger Ai_GetNextTriggerByFuncName(var C_Trigger startTrigger, var string functionName) {}; - -/// Returns the next trigger in the active trigger array based on the `self` trigger -/// parameter, starting on the `startTrigger` instance set in the trigger -/// -/// @param startTrigger C_Trigger script to start the search from -/// @param self C_NPC instance -/// @return C_Trigger instance -func C_Trigger Ai_GetNextTriggerBySelf(var C_Trigger startTrigger, var C_NPC self) {}; - -/// Returns the next trigger in the active trigger array based on the `other` trigger -/// parameter, starting on the `startTrigger` instance set in the trigger -/// -/// @param startTrigger C_Trigger script to start the search from -/// @param other C_NPC instance -/// @return C_Trigger instance -func C_Trigger Ai_GetNextTriggerByOther(var C_Trigger startTrigger, var C_NPC other) {}; - -/// Returns the next trigger in the active trigger array based on the `victim` trigger -/// parameter, starting on the `startTrigger` instance set in the trigger -/// -/// @param startTrigger C_Trigger script to start the search from -/// @param victim C_NPC instance -/// @return C_Trigger instance -func C_Trigger Ai_GetNextTriggerByVictim(var C_Trigger startTrigger, var C_NPC victim) {}; - -/// Returns the next trigger in the active trigger array based on all the NPCs -/// set in the trigger script `self`, `other` and `victim`, -/// starting on the `startTrigger` instance set in the trigger -/// -/// @param startTrigger C_Trigger script to start the search from -/// @param self self C_NPC instance -/// @param other other C_NPC instance -/// @param victim victim C_NPC instance -/// @return C_Trigger instance -func c_trigger Ai_GetNextTriggerByNPCs(var C_Trigger startTrigger, - var C_NPC self, - var C_NPC other, - var C_NPC victim) {}; - - -// ========================================================= -// -// CAST functions -// -// ========================================================= - -/// Converts memory address (pointer) to an instance -/// -/// @param address object pointer -/// @return instance of the object -func instance Cast_PointerToInstance(var int address) {}; - -/// Converts instance to a memory address (pointer) -/// -/// @param object object instance -/// @return memory address (pointer) of the object -func int Cast_InstanceToPointer( var instance object) {}; - -/// Casts memory address (pointer) to an NPC -/// -/// @param address npc pointer -/// @return NPC instance -func C_NPC Cast_PointerToNpc( var int address) {}; - -/// Casts memory address (pointer) to an Item -/// -/// @param address item pointer -/// @return Item instance -func C_ITEM Cast_PointerToItem( var int address) {}; - -/// Checks whether object is an NPC -/// -/// @param object object to check -/// @return `TRUE` or `FALSE` -func int Cast_InstanceIsNpc( var instance object) {}; - -/// Checks whether object is an Item -/// -/// @param object object to check -/// @return `TRUE` or `FALSE` -func int Cast_InstanceIsItem( var instance object) {}; - -/// Checks whether object is an MOB -/// -/// @param object object to check -/// @return `TRUE` or `FALSE` -func int Cast_InstanceIsMob( var instance object) {}; - -/// Returns symbolID of the object, returns -1 when not found -/// -/// @param object instance of an object -/// @return symbol table index, -1 when not found -func int Cast_GetInstanceIndex( var instance object) {}; - -/// Returns the class identifier of a class by its name -/// -/// @param className name of the class -/// @return class identifier -func int Cast_GetClassID( var string className ) {}; - -/// Returns class identifier of the zCObject vob class -/// -/// @param object object instance -/// @return class zCObject identifier -func int Cast_GetVobClassID( var instance object ) {}; - -/// Checks if the classId class is the parent class of the object -/// -/// @param classId class identifier, from Cast_GetClassID function -/// @param object object instance -/// @return class zCObject identifier -func int Cast_CheckVobClassID( var int classId, var instance object ) {}; - - -// ========================================================= -// -// HLP functions -// -// ========================================================= - -/// Returns `TRUE`, if a specified NPC has a Vob in focus -/// -/// @param npc NPC -/// @return `TRUE` if npc has a focus Vob, `FALSE` if it does not -func int Hlp_HasFocusVob( var C_NPC npc ) {}; - -/// Returns NPC's focus Vob -/// -/// @param npc NPC -/// @return focus vob -func instance Hlp_GetFocusVob( var C_NPC npc ) {}; - -/// Returns the name of NPC's focus vob -/// -/// @param npc NPC -/// @return focus vob name -func string Hlp_GetFocusVobName( var C_NPC npc ) {}; - -/// Returns the length of a specified string -/// -/// @return str input string -/// @return length of `str` -func int Hlp_GetStringLength( var string str ) {}; - -/// Checks whether floating point number is valid -/// -/// @return `TRUE` if `value` is NaN, `FALSE` if `value` is a valid floating point number -func int IsNAN( var float value ) {}; - -/// Checks whether `key` is toggled -/// -/// @param key key code -/// @return `TRUE` if key is toggled, `FALSE` if key is not toggled -func int Hlp_KeyToggled( var int key ) {}; - -/// Checks whether `key` is pressed -/// -/// @param key key code -/// @return `TRUE` if key is pressed, `FALSE` if key is not pressed -func int Hlp_KeyPressed( var int key ) {}; - -/// Checks whether logical `key` is toggled -/// -/// @param key key code -/// @return `TRUE` if key is toggled, `FALSE` if key is not toggled -func int Hlp_LogicalKeyToggled( var int key ) {}; - -/// Checks whether the game is paused -/// -/// @return `TRUE` if the game is paused, `FALSE` if the game is not paused -func int Hlp_GameOnPause() {}; - -/// Opens a message box with a specified message -/// -/// @param message message to be printed -func void Hlp_MessageBox( var string message ) {}; - -/// Prints a message to the Union debug console -/// -/// @param message message to be printed -func void Hlp_PrintConsole(var string message) {}; - -/// Checks whether the `entry` in `section` in `.ini` file `optName` exists -/// -/// `optName` values -/// - `Gothic` -/// - `Mod` -/// - `SystemPack` -/// -/// @param optName the `.ini` file -/// @param section settings section like `[GAME]` -/// @param entry one setting entry like `playLogoVideos` -/// @return `TRUE` if the option exists, `FALSE` if the option does not exist -func int Hlp_OptionIsExists(var string optName, var string section, var string entry) {}; - -/// Read an integer value from specified `.ini` file, section and entry. -/// -/// `optName` values -/// - `Gothic` -/// - `Mod` -/// - `SystemPack` -/// -/// @param optName the `.ini` file -/// @param section settings section like `[GAME]` -/// @param entry one setting entry like `playLogoVideos` -/// @param default default value - if the value is empty -/// @return the option value -func int Hlp_ReadOptionInt(var string optName, var string section, var string entry, var int default) {}; - -/// Read a floating point value from specified `.ini` file, section and entry. -/// -/// `optName` values -/// - `Gothic` -/// - `Mod` -/// - `SystemPack` -/// -/// @param optName the `.ini` file -/// @param section settings section like `[INTERFACE]` -/// @param entry one setting entry like `scale` -/// @param default default value - if the value is empty -/// @return the option value -func float Hlp_ReadOptionFloat(var string optName, var string section, var string entry, var float default) {}; - -/// Read a string value from specified `.ini` file, section and entry. -/// -/// `optName` values -/// - `Gothic` -/// - `Mod` -/// - `SystemPack` -/// -/// @param optName the `.ini` file -/// @param section settings section like `[INTERFACE]` -/// @param entry one setting entry like `scale` -/// @param default default value - if the value is empty -/// @return the option value -func string Hlp_ReadOptionString(var string optName, var string section, var string entry, var string default) {}; - -/// Writes an integer value to specified `.ini` file, section and entry. -/// -/// `optName` values -/// - `Gothic` -/// - `Mod` -/// - `SystemPack` -/// -/// @param optName the `.ini` file -/// @param section settings section like `[INTERFACE]` -/// @param entry one setting entry like `scale` -/// @param value value to be written -func void Hlp_WriteOptionInt(var string optName, var string section, var string entry, var int value) {}; - -/// Writes a floating point value to specified `.ini` file, section and entry. -/// -/// `optName` values -/// - `Gothic` -/// - `Mod` -/// - `SystemPack` -/// -/// @param optName the `.ini` file -/// @param section settings section like `[INTERFACE]` -/// @param entry one setting entry like `scale` -/// @param value value to be written -func void Hlp_WriteOptionFloat(var string optName, var string section, var string entry, var float value) {}; - -/// Writes a string value to specified `.ini` file, section and entry. -/// -/// `optName` values: `Gothic`, `Mod`, `SystemPack` -/// -/// @param optName the `.ini` file -/// @param section settings section like `[INTERFACE]` -/// @param entry one setting entry like `scale` -/// @param value value to be written -func void Hlp_WriteOptionString(var string optName, var string section, var string entry, var string value) {}; - -/// Returns the name of the current Steam user -/// Returns empty string when not run with Steam -/// -/// @return string containing the Steam username, or an empty string -func string Hlp_GetSteamPersonalName() {}; - -// ========================================================= -// -// LOG functions -// -// ========================================================= - -/// Returns the status of diary topic -/// `-1` - Not found -/// `0` - Free -/// `1` - Running -/// `2` - Success -/// `3` - Failure -/// `4` - Obsolete -/// -/// @param topic name of the topic -/// @return topic status -func int Log_GetTopicStatus(var string topic) {}; - -/// Returns the topic the diary topic is in -/// `-1` - Not found -/// `0` - Missions -/// `1` - Notes -/// `2` - All -/// -/// @param topic name of the topic -/// @return topic section -func int Log_GetTopicSection(var string topic) {}; - -// ========================================================= -// -// MDL functions -// -// ========================================================= - -/// Returns animation's index for specified NPC based on animation's name -/// -/// @param npc NPC with the animation -/// @param ani_name name of the animation in uppercase -/// @return animation index -func int Mdl_GetAnimationIndex( var C_NPC npc, var string ani_name ) {}; - -/// Returns animation's name for specified NPC based on animation's index -/// -/// @param npc NPC with the animation -/// @param ani_index animation index -/// @return animation name -func string Mdl_GetAnimationName( var C_NPC npc, var int ani_index ) {}; - -/// Checks whether animation exists -/// -/// @param npc NPC with the animation -/// @param ani_index animation index -/// @return animation name -func int Mdl_AnimationIsExists( var C_NPC npc, var int ani_index ) {}; - -/// Checks whether animation is active (whether it is currently played) -/// -/// @param npc NPC with the animation -/// @param ani_index animation index -/// @return `TRUE` if the animation is playing, `FALSE` if it is not playing -func int Mdl_AnimationIsActive( var C_NPC npc, var int ani_index ) {}; - -/// Set framerate for all animations -/// -/// @param npc NPC with the animation -/// @param fps framerate -func void Mdl_SetAllAnimationsFPS( var C_NPC npc, var float fps ) {}; - -/// Reset framerate for all animations to default value -/// -/// @param npc NPC with the animation -func void Mdl_ResetAllAnimationsFPS( var C_NPC npc ) {}; - -/// Set framerate for animation specified by animation index -/// -/// @param npc NPC with the animation -/// @param ani_index animation index -/// @param fps framerate -func void Mdl_SetAnimationFPS( var C_NPC npc, var int ani_index, var float fps ) {}; - -/// Reset framerate to default for animation specified by animation index -/// -/// @param npc NPC with the animation -/// @param ani_index animation index -func void Mdl_ResetAnimationFPS( var C_NPC npc, var int ani_index ) {}; - -/// Set NPCs visibility -/// -/// @param npc specified NPC -/// @param isVisible [TRUE, FALSE] `TRUE` - visible, `FALSE` - invisible -func void Mdl_SetVisible( var C_NPC npc, var int isVisible ) {}; - -/// Applies or moves existing overlay to the top of the list -/// -/// @param mdsName name of the overlay -func void Mdl_ApplyOverlayMds_AtFirst( var string mdsName ) {}; - -/// Sets a multiplier for animation speed -/// 1.0 = 100% speed (normal speed) -/// -/// @param npc npc to be affected -/// @param multiplier speed of the animation -func void Mdl_SetNpcSpeedMultiplier( var C_Npc npc, var float multiplier ) {}; - -/// Resets the animation speed of an NPC -/// -/// @param npc npc to be affected -func void Mdl_ResetNpcSpeedMultiplier( var C_Npc npc ) {}; - -// ========================================================= -// -// MENU functions -// -// ========================================================= - -/// Find all C_MenuItem object instances by the mask and automatically places them in the current menu instance -/// -/// @param mask regex like mask for searching -/// [Menu_SearchItems on GMC](https://gothic-modding-community.github.io/gmc/zengin/scripts/extenders/zparserextender/externals/menu/) -func void Menu_SearchItems( var string mask ) {}; - -// ========================================================= -// -// MOB functions -// -// ========================================================= - -/// Marks oCMOB as destroyed, changes the visual to visualDestroyed (if present). -/// -/// @param object oCMOB to be destroyed -func void Mob_Destroy( var instance object ) {}; - -/// Removes an item from a oCMobContainer -/// -/// @param object oCMobContainer object -/// @param item {C_ITEM} item to be removed -func void Mob_RemoveItem( var instance object, var int item ) {}; - -/// Removes specified number of items from a oCMobContainer -/// -/// @param object oCMobContainer object -/// @param item {C_ITEM} item to be removed -/// @param cnt number of items to be removed -func void Mob_RemoveItems( var instance object, var int item, var int cnt ) {}; - -/// Inserts an item into a oCMobContainer -/// -/// @param object oCMobContainer object -/// @param item {C_ITEM} item to be inserted -func void Mob_InsertItem( var instance object, var int item ) {}; - -/// Inserts specified number of items into a oCMobContainer -/// -/// @param object oCMobContainer object -/// @param item {C_ITEM} item to be inserted -/// @param cnt number of items to be inserted -func void Mob_InsertItems( var instance object, var int item, var int cnt ) {}; - -/// Returns a lock combination of a oCMobContainer -/// -/// @param object oCMobContainer object -/// @return lock combination -func string Mob_GetLockCombination( var instance object ) {}; - -/// Sets a lock combination to a oCMobContainer -/// -/// @param object oCMobContainer object -/// @param comb lock combination -func void Mob_SetLockCombination( var instance object, var string comb ) {}; - -/// Returns `TRUE` if the object is locked -/// -/// @param object oCMobLockable object -/// @return `TRUE` if locked, `FALSE` if unlocked -func int Mob_IsLocked( var instance object ) {}; - -/// Set the lock status of the object -/// -/// @param object oCMobLockable object -/// @param locked [TRUE, FALSE] lock or unlock the object -func void Mob_SetLocked( var instance object, var int locked ) {}; - -/// Returns the key instance, that unlocks the object -/// -/// @param object oCMobLockable object -/// @return the key C_ITEM instance -func instance Mob_GetKeyInstance( var instance object ) {}; - -/// Stets the key instance, that unlocks the object -/// -/// @param object oCMobLockable object -/// @param key the key C_ITEM instance -func void Mob_SetKeyInstance( var instance object, var int key ) {}; - -// ========================================================= -// -// NPC functions -// -// ========================================================= - -/// Changes players character to specified `npc` -/// -/// @param npc NPC to be set as players character -func void Npc_SetAsHero( var C_NPC npc ) {}; - -/// Opens NPCs main inventory -/// -/// @param npc NPC -func void Npc_OpenInventory( var C_NPC npc ) {}; - -/// Opens the steal inventory of `npc`'s focus NPC -/// -/// @param npc NPC -func void Npc_OpenInventorySteal( var C_NPC npc ) {}; - -/// Start the trading dialogue with specified NPC -/// -/// @param npc NPC -func void Npc_OpenInventoryTrade( var C_NPC npc ) {}; - -/// Returns an item in NPC's left hand slot -/// -/// @param npc npc to be affected -/// @return found C_ITEM instance -func C_Item Npc_GetLeftHandItem( var C_Npc npc ) {}; - -/// Returns an item in NPC's right hand slot -/// -/// @param npc npc to be affected -/// @return found C_ITEM instance -func C_Item Npc_GetRightHandItem( var C_Npc npc ) {}; - -/// Returns an item from a slot with the slotName -/// -/// @param npc npc to be affected -/// @param slotName name of the slot -/// @return found C_ITEM instance -func C_Item Npc_GetSlotItem( var C_Npc npc, var string slotName ) {}; - -/// Places an instance of the oCVom class (including items and NPCs) object into the slotName of the NPC -/// The copyInInv parameter determines whether a copy of the object should remain in the character's inventory -/// -/// @param npc npc to remove the item from -/// @param slotName name of the slot from which to remove the item -/// @param object object to be inserted into the slot -/// @param copyInInv should a copy of the object stay in character inventory -func void Npc_PutInSlot(var C_Npc npc, var string slotName, var instance object, var int copyInInv) {}; - -/// Removes an object from the slotName of the NPC. -/// The dropIt parameter in Gothic 2 defines, whether object should drop out of the slot. In Gothic 1, this parameter is reserved and must be 0. -/// -/// @param npc npc to remove the item from -/// @param slotName name of the slot from which to remove the item -/// @param dropIt should the object be dropped -func void Npc_RemoveFromSlot(var C_Npc npc, var string slotName, var int dropIt) {}; - -// ========================================================= -// -// PAR functions -// -// ========================================================= - -/// Returns a parser ID of the parser with a `parName` name -/// -/// Parser names: -/// - "Game" -/// - "SFX" -/// - "PFX" -/// - "VFX" -/// - "Camera" -/// - "Menu" -/// - "Music" -/// -/// @param parName parser name -/// @return parser ID -func int Par_GetParserID(var string parName) {}; - -/// Returns symbol ID for the symbol specified by its name -/// -/// @param parID parser ID -/// @param symName symbol name -/// @return symbol ID -func int Par_GetSymbolID(var int parId, var string symName) {}; - -/// Returns symbol length (number of elements) -/// -/// @param parID parser ID -/// @param symName symbol name -/// @return symbol length -func int Par_GetSymbolLength(var int parId, var int symId) {}; - -/// Returns the integer value of specified symbol -/// -/// @param parID parser ID -/// @param symName symbol name -/// @return symbol value -func int Par_GetSymbolValueInt(var int parId, var int symId) {}; - -/// Returns the float value of specified symbol -/// -/// @param parID parser ID -/// @param symName symbol name -/// @return symbol value -func float Par_GetSymbolValueFloat(var int parId, var int symId) {}; - -/// Returns the string value of specified symbol -/// -/// @param parID parser ID -/// @param symName symbol name -/// @return symbol value -func string Par_GetSymbolValueString(var int parId, var int symId) {}; - -/// Returns the instance value of specified symbol -/// -/// @param parID parser ID -/// @param symName symbol name -/// @return symbol value -func instance Par_GetSymbolValueInstance(var int parId, var int symId) {}; - -/// Returns the value of specified integer array at the `arrayID` index -/// -/// @param parID parser ID -/// @param symName symbol name -/// @param arrayID array index -/// @return value -func int Par_GetSymbolValueIntArray(var int parId, var int symId, var int arrayId) {}; - -/// Returns the value of specified float array at the `arrayID` index -/// -/// @param parID parser ID -/// @param symName symbol name -/// @param arrayID array index -/// @return value -func float Par_GetSymbolValueFloatArray(var int parId, var int symId, var int arrayId) {}; - -/// Returns the value of specified string array at the `arrayID` index -/// -/// @param parID parser ID -/// @param symName symbol name -/// @param arrayID array index -/// @return value -func string Par_GetSymbolValueStringArray(var int parId, var int symId, var int arrayId) {}; - -/// Sets a new integer value to specified symbol -/// -/// @param value value to be set -/// @param parID parser ID -/// @param symId symbol ID -func void Par_SetSymbolValueInt(var int value, var int parId, var int symId) {}; - -/// Sets a new float value to specified symbol -/// -/// @param value value to be set -/// @param parID parser ID -/// @param symId symbol ID -func void Par_SetSymbolValueFloat(var float value, var int parId, var int symId) {}; - -/// Sets a new string value to specified symbol -/// -/// @param value value to be set -/// @param parID parser ID -/// @param symId symbol ID -func void Par_SetSymbolValueString(var string value, var int parId, var int symId) {}; - -/// Sets a new instance value to specified symbol -/// -/// @param value value to be set -/// @param parID parser ID -/// @param symId symbol ID -func void Par_SetSymbolValueInstance(var instance value, var int parId, var int symId, var int arrayId) {}; - -/// Sets a new integer value to specified integer array symbol -/// -/// @param value value to be set -/// @param parID parser ID -/// @param symId symbol ID -/// @param arrayId array index -func void Par_SetSymbolValueIntArray(var int value, var int parId, var int symId, var int arrayId) {}; - -/// Sets a new float value to specified float array symbol -/// -/// @param value value to be set -/// @param parID parser ID -/// @param symId symbol ID -/// @param arrayId array index -func void Par_SetSymbolValueFloatArray(var float value, var int parId, var int symId, var int arrayId) {}; - -/// Sets a new string value to specified string array symbol -/// -/// @param value value to be set -/// @param parID parser ID -/// @param symId symbol ID -/// @param arrayId array index -func void Par_SetSymbolValueStringArray(var string value, var int parId, var int symId, var int arrayId) {}; - -// ========================================================= -// -// String functions -// -// ========================================================= - -/// Returns formatted string using format specifiers -/// -/// Format specifiers: -/// %s - inserts a string -/// %i - inserts an integer number -/// %x - inserts an integer in hexadecimal -/// %f - inserts a floating point number -/// %b - inserts a logical expression -/// %p - inserts a pointer -/// -/// @return formatted string -//TODO: func string Str_Format( var string format, ... ) {}; - -/// Returns a string in the current language, otherwise in English. -/// Arguments MUST be encoded in UTF-8! The result string will be converted to appropriate ANSI string. -/// -/// @param russian Russian string -/// @param english English string -/// @param german German string -/// @param polish Polish string -/// -/// @return string in the current language -func string Str_GetLocalizedString( var string russian, - var string english, - var string german, - var string polish ) {}; - -/// Returns a string in the current language, otherwise in English. -/// Offers additional languages -/// -/// @param russian Russian string -/// @param english English string -/// @param german German string -/// @param polish Polish string -/// @param romanian Romanian string -/// @param italian Italian string -/// @param czech Czech string -/// @param spanish Spanish string -/// -/// @return string in the current language -func string Str_GetLocalizedStringEx( var string russian, - var string english, - var string german, - var string polish, - var string romanian, - var string italian, - var string czech, - var string spanish ) {}; - -/// Converts UTF-8 string into an ANSI string with codePage -/// -/// @param utf8 string encoded in UTF8 -/// @param codePage codePage id, can be obtained from Str_GetCurrentCP -func string Str_UTF8_to_ANSI( var string utf8, var int codePage ) {}; - -/// Return the code page corresponding to the current language set in the Union System -/// -/// @return code page corresponding to the current language -func int Str_GetCurrentCP() {}; - -/// Returns the length of a string -/// -/// @param str string to be measured -/// @return length of the string -func int Str_GetLength( var int str ) {}; - -// ========================================================= -// -// VOB functions -// -// ========================================================= - -/// Returns the current position of the object in the world -/// -/// @param vob vob to ge the position of -/// @return C_Position instance - position of the VOB -func C_Position Vob_GetVobPosition( var C_Vob vob ) {}; - -/// Sets the current position of the object in the world -/// -/// @param vob vob to get the position of -/// @param pos new position of the vob -func void Vob_SetVobPosition( var C_Vob vob, var C_Position pos ) {}; - -/// Returns the universal data of the zCVob object -/// -/// @param vob VOB to get the position of -/// @return general vob data C_Vob_Data -func C_Vob_Data Vob_GetVobData( var C_Vob vob ) {}; - -/// Sets the universal data to a zCVob object -/// -/// @param vob VOB to get the position of -/// @param data general vob data C_Vob_Data -func void Vob_SetVobData( var C_Vob vob, var C_Vob_Data data ) {}; - -/// Returns zCVobLight object data -/// -/// @param vobLight vobLight object -/// @return C_Light_Data of the light -func C_Light_Data Vob_GetLightData( var C_Vob vobLight ) {}; - -/// Sets the data of a zCVobLight object -/// -/// @param vobLight object to apply the light data to -/// @param data C_Light_Data light data to be set -func void Vob_SetLightData( var C_Vob vobLight, var C_Light_Data data ) {}; - -/// Clears the list of animation colours for the light source -/// -/// @param vobLight light vob -func void Vob_ClearLightAniList( var C_Vob vobLight ) {}; - -/// Adds a color to the colour list -/// -/// @param vobLight object to apply the colour to -/// @param col colour to be applied -func void Vob_AddLightAniColor( var C_Vob vobLight, var C_Color col ) {}; - -/// Adds a color to the colour list -/// -/// @param vobLight object to apply the colour to -/// @param r red colour channel -/// @param g green colour channel -/// @param b blue colour channel -func void Vob_AddLightAniColorRGB( var C_Vob vobLight, - var int r, - var int g, - var int b ) {}; - -/// Returns the data of the oCMOB object -/// -/// @param mob oCMOB object -/// @return mob data -func C_Mob_Data Vob_GetMobData( var C_Vob mob ) {}; - -/// Sets the data of the oCMOB object -/// -/// @param mob oCMOB object -/// @param data C_Mob_Data to be set -func void Vob_SetMobData( var C_Vob mob, var C_Mob_Data data ) {}; - -/// Returns the data of the oCMobInter object -/// -/// @param mobInter oCMobInter object -/// @return MobInter_Data of the object -func MobInter_Data Vob_GetMobInterData( var C_Vob mobInter ) {}; - -/// Sets the data of the oCMobInter object -/// -/// @param mobInter oCMobInter object -/// @param data MobInter_Data of the object -func void Vob_SetMobInterData( var C_Vob mobInter, var C_MobInter_Data data ) {}; - -/// Returns the data of the oCMobLockable object -/// -/// @param mobLock oCMobLockable object -/// @param data MobInter_Data of the object -/// return C_MobLockable_Data of the object -func C_MobLockable_Data Vob_GetMobInterData( var C_Vob mobLock ) {}; - -/// Sets the data of the oCMobLockable object -/// -/// @param mobLock oCMobLockable object -/// @param data C_MobLockable_Data of the object -func void Vob_SetMobInterData( var C_Vob mobLock, var C_MobLockable_Data data ) {}; - -// ========================================================= -// -// WLD functions -// -// ========================================================= - -/// Trigger level change. -/// -/// @param world name of the world -/// @param waypoint target waypoint -func void Wld_ChangeLevel( var string world, var string waypoint ) {}; - -/// Return the VOB instance based on its name. -/// -/// @param vobname name of the vob -/// @param return zCVob pointer -func instance Wld_FindVob( var string vobname ) {}; - -/// Play a visual effect at specified vob -/// -/// @param effect effect name -/// @param pvob Vob to play the effect at -/// @param level effect level -/// @param damage damage amount -/// @param damage_type damage type -/// @param damage_speed damage interval -func void Wld_PlayEffectVob( var string effect, - var instance pvob, - var int level, - var int damage, - var int damage_type, - var int damage_speed ) {}; - -/// Play a visual effect at specified world coordinates -/// -/// @param effect effect name -/// @param coord world coordinates to play the effect at -/// @param level effect level -/// @param damage damage amount -/// @param damage_type damage type -/// @param damage_speed damage interval -func void Wld_PlayEffectAt( var string effect, - var instance coord, - var int level, - var int damage, - var int damage_type, - var int damage_speed ) {}; - -/// Turns on the rain -/// -/// @param weight the strength of the rain -/// @param time rain duration -func void Wld_ToggleRain( var float weight, var float time ) {}; - -/// Sets the weather type. -/// Types: -/// -/// `0` - snow -/// `1` - rain -/// -/// @param type weather type -func void Wld_SetWeatherType( var int type ) {}; - -/// Returns the weather type. -/// Types: -/// -/// `0` - snow -/// `1` - rain -/// -/// @return weather type -func int Wld_GetWeatherType() {}; \ No newline at end of file diff --git a/zengin/scripts/extenders/zparserextender/helperclasses/index.html b/zengin/scripts/extenders/zparserextender/helperclasses/index.html deleted file mode 100644 index cd2de661e8..0000000000 --- a/zengin/scripts/extenders/zparserextender/helperclasses/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/zengin/scripts/extenders/zparserextender/hooks/index.html b/zengin/scripts/extenders/zparserextender/hooks/index.html deleted file mode 100644 index f421172fef..0000000000 --- a/zengin/scripts/extenders/zparserextender/hooks/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/zengin/scripts/extenders/zparserextender/index.html b/zengin/scripts/extenders/zparserextender/index.html deleted file mode 100644 index 62da65cde4..0000000000 --- a/zengin/scripts/extenders/zparserextender/index.html +++ /dev/null @@ -1,34 +0,0 @@ - zParserExtender - Gothic Modding Community

zParserExtender

zParserExtender extends ZenGin's parser and adds many useful features. It significantly extends the functionality of scripts with added functionality and new external functions. It also enhances script compilation, allowing to compile OU files directly with the game and allowing for runtime script injection. Since the Union version 1.0m zParserExtender is fully integrated in Union itself.

Note

This is mostly a translation of the original release post

Contacts
Author Gratt
GitHub zParserExtender
Forum zParserExtender
\ No newline at end of file diff --git a/zengin/scripts/extenders/zparserextender/injection/hooks/index.html b/zengin/scripts/extenders/zparserextender/injection/hooks/index.html deleted file mode 100644 index c25e6ad4e8..0000000000 --- a/zengin/scripts/extenders/zparserextender/injection/hooks/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/zengin/scripts/extenders/zparserextender/injection/index.html b/zengin/scripts/extenders/zparserextender/injection/index.html deleted file mode 100644 index 25bb9292b1..0000000000 --- a/zengin/scripts/extenders/zparserextender/injection/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/zengin/scripts/extenders/zparserextender/injection/meta/index.html b/zengin/scripts/extenders/zparserextender/injection/meta/index.html deleted file mode 100644 index 9d44507911..0000000000 --- a/zengin/scripts/extenders/zparserextender/injection/meta/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/zengin/scripts/extenders/zparserextender/injection/other/index.html b/zengin/scripts/extenders/zparserextender/injection/other/index.html deleted file mode 100644 index 13ad843a76..0000000000 --- a/zengin/scripts/extenders/zparserextender/injection/other/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/zengin/scripts/extenders/zparserextender/meta/index.html b/zengin/scripts/extenders/zparserextender/meta/index.html deleted file mode 100644 index ae843c19be..0000000000 --- a/zengin/scripts/extenders/zparserextender/meta/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/zengin/scripts/extenders/zparserextender/namespaces/index.html b/zengin/scripts/extenders/zparserextender/namespaces/index.html deleted file mode 100644 index 7ff03419e2..0000000000 --- a/zengin/scripts/extenders/zparserextender/namespaces/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/zengin/scripts/extenders/zparserextender/other/index.html b/zengin/scripts/extenders/zparserextender/other/index.html deleted file mode 100644 index 3bb6b4a53a..0000000000 --- a/zengin/scripts/extenders/zparserextender/other/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/zengin/scripts/extenders/zparserextender/syntax_extensions/dialogues/index.html b/zengin/scripts/extenders/zparserextender/syntax_extensions/dialogues/index.html deleted file mode 100644 index 0cb0f3c7a5..0000000000 --- a/zengin/scripts/extenders/zparserextender/syntax_extensions/dialogues/index.html +++ /dev/null @@ -1,53 +0,0 @@ - Dialogue constants - Gothic Modding Community

Dialogue constants

To simplify dialogues, you can define up to 2 auxiliary variables or constants. Values corresponding to the current C_Info instance will be dynamically written there.

DIA_CurrentInstance

var int DIA_CurrentInstance
-
Contains the ID of the current C_Info instance. Can greatly simplify code or make it more reusable. Should be defined in scripts.
Example usage
1
-2
-3
Info_ClearChoices(DIA_CurrentInstance);
-Info_AddChoice(DIA_CurrentInstance, /*text*/, /*func*/);
-Npc_KnowsInfo(hero, DIA_CurrentInstance); // In this case DIA_CurrentInstance contains the last C_Info instance??
-
Create a wrapper function based on this variable
1
-2
-3
-4
func int C_HeroKnowsCurrentInfo()
-{
-    return Npc_KnowsInfo(hero, DIA_CurrentInstance);
-};
-

DIA_CurrentName

var string DIA_CurrentName;
-
Contains the name of the current instance of C_Info. Can be useful for debugging purposes. Should be defined in scripts. Usage scenarios:
1
-2
-3
Hlp_PrintConsole(DIA_CurrentName);
-Hlp_PrintConsole(Str_Format("%s[%s]", DIA_CurrentName, self.name);
-Hlp_StrCmp(DIA_CurrentName, "DIA_DiegoOw_Teach");
-
\ No newline at end of file diff --git a/zengin/scripts/extenders/zparserextender/syntax_extensions/events/index.html b/zengin/scripts/extenders/zparserextender/syntax_extensions/events/index.html deleted file mode 100644 index 2e39e7782a..0000000000 --- a/zengin/scripts/extenders/zparserextender/syntax_extensions/events/index.html +++ /dev/null @@ -1,57 +0,0 @@ - Event functions - Gothic Modding Community

Event functions

Event functions are functions sharing the same name. It can be defined multiple times but only once per file. Such functions are useful for implementing callback type functions. Every time an event is called, all instances of the same name will be called. The event is func with a return type event. Events are defined globally, meaning they ignore namespace they are in. To call an event from a script, use the external function Hlp_DoEvent(var string funcName).

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
func void GiveXP()
-{
-    Hlp_DoEvent("OnGiveXP");
-};
-
-func event OnGiveXP()
-{
-    // TODO
-    // This function can be defined in many files to do different things
-    // more appropriate for that file's context and all of them will be
-    // called, when function GiveXP (above) is called.
-};
-

Plugin implements two of these event functions

  • func event GameInit() - called when entering the main menu on game start
  • func event GameLoop() - called every frame when a world is loaded

Define these in any file in your scripts, they will be automatically called

\ No newline at end of file diff --git a/zengin/scripts/extenders/zparserextender/syntax_extensions/extern/index.html b/zengin/scripts/extenders/zparserextender/syntax_extensions/extern/index.html deleted file mode 100644 index 207cdab8df..0000000000 --- a/zengin/scripts/extenders/zparserextender/syntax_extensions/extern/index.html +++ /dev/null @@ -1,41 +0,0 @@ - Extern binding - Gothic Modding Community

Extern binding

The extern binding allows you to secure your code against overriding or undefined symbol. Keyword extern before declaration means that if object of the same name exists, source object should be used. If not, a new one will be created.

1
-2
-3
-4
extern instance PC_Hero(C_Npc) 
-{
-    // TODO
-};
-
\ No newline at end of file diff --git a/zengin/scripts/extenders/zparserextender/syntax_extensions/namespaces/index.html b/zengin/scripts/extenders/zparserextender/syntax_extensions/namespaces/index.html deleted file mode 100644 index 4cbf5bc023..0000000000 --- a/zengin/scripts/extenders/zparserextender/syntax_extensions/namespaces/index.html +++ /dev/null @@ -1,298 +0,0 @@ - Namespaces - Gothic Modding Community

Namespaces

zParserExtender also implements namespaces. Namespaces ensure that all symbols inside the namespace are unique.

Defining a namespace

To define a namespace the new keyword namespace is used.

1
-2
-3
-4
-5
namespace zTestNamespace
-{
-    var int var01;
-    func void func01() { };
-};
-
1
-2
-3
-4
-5
-6
-7
META
-{
-    Namespace = zTestNamespace;
-};
-
-var int var01;
-func void func01() { };
-

Namespace nesting

Namespaces can be nested for finer control. In case of injection, the namespace defined in META is applied to all code inside the script.

To go deeper into the namespaces you use the namespace operator :. This code shows function with the same name within three different namespaces. The call in GameInit is made from the global namespace.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
namespace zTestNamespace01
-{
-    func void func01() { };
-};
-
-namespace zTestNamespace02
-{
-    func void func01() { };
-};
-
-namespace zTestNamespace03
-{
-    namespace zTestNamespace04
-    {
-        func void func01() { };
-    };
-};
-
-func event GameInit()
-{
-    // In this case, the reference is from global namespace to zTestNamespace
-    zTestNamespace01:func01();
-    zTestNamespace02:func01();
-    zTestNamespace03:zTestNamespace04:func01();
-};
-

Namespace traversal

To go up a namespace tree you use the namespace operator : without specifying a namespace. Number of operators determines how many levels you go up.

Exiting nested namespaces
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
func void func01()
-{
-    Hlp_MessageBox("#1");
-};
-
-namespace zTestNamespace01
-{
-    func void func01()
-    {
-        Hlp_MessageBox("#2");
-    };
-
-    namespace zTestNamespace02
-    {
-        func void func01()
-        {
-            Hlp_MessageBox("#3");
-        };
-
-        namespace zTestNamespace03
-        {
-            func void func01()
-            {
-                Hlp_MessageBox("#4");
-            };
-
-            func event GameInit()
-            {
-                :::func01(); // Calls the function 3 levels up
-                ::func01();  // Calls the function 2 levels up
-                :func01();   // Calls the function 1 level up
-                func01();    // Calls the function from the current namespace
-            };
-        };
-    };
-};
-

Optional namespace specification

There are three cases where the namespace prefix is optional

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
namespace zTestNamespace01
-{
-    func void func01()
-    {
-        Hlp_MessageBox("#1");
-    };
-
-    func event GameInit()
-    {
-        // Function call from the current namespace
-        func01();
-    };
-};
-
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
func void func01()
-{
-    Hlp_MessageBox("#1");
-};
-
-namespace zTestNamespace01
-{
-    func void func01()
-    {
-        Hlp_MessageBox("#2");
-    };
-
-    namespace zTestNamespace02
-    {
-        func event GameInit()
-        {
-            // Function call from the global namespace
-            func01();
-        };
-    };
-};
-
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
META
-{
-    using = zTestNamespace01;
-};
-
-namespace zTestNamespace01
-{
-    func void func01()
-    {
-        Hlp_MessageBox("#1");
-    };
-};
-
-func event GameInit()
-{
-    // Calls the function with the namespace specified in the META block
-    func01();
-};
-

Global namespace and Daedalus hooking

Namespace can not only be defined to an existing symbol but also to define new ones. Next code example shows how to implement a hook to a global instance.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
namespace zTestNamespace01
-{
-    const string Var01 = "New instance name";
-
-    // Hooking the global instance
-    instance :ItAr_Pir_L_Addon(C_Item)
-    {
-        ItAr_Pir_L_Addon_Old();
-        name = Var01;
-    };
-};
-
To hook an object, both signature and namespace has to match. It is syntactically allowed to hook an instance from a different space. Specify explicitly to which namespace the object will belong. This means that to hook instance ItAr_Pir_L_Addon from the namespace zTestNamespace01 to a global namespace, you have to refer to the global namespace using the namespace operator :. Since the function will be defined globally (as every symbol in ZenGin), it will be a part of the zTestNamespace01 which means that all functions will be local to this namespace.
\ No newline at end of file diff --git a/zengin/scripts/extenders/zparserextender/syntax_extensions/testelse/index.html b/zengin/scripts/extenders/zparserextender/syntax_extensions/testelse/index.html deleted file mode 100644 index 596112ed23..0000000000 --- a/zengin/scripts/extenders/zparserextender/syntax_extensions/testelse/index.html +++ /dev/null @@ -1,50 +0,0 @@ - Test-else binding - Gothic Modding Community

Test-else statements

The test-else bind statement can be used to define sections of code to be compiled. If the code is within the boundaries of the inactive test-else branch, it will not be compiled. This operator can take values as input that are converted to logical values. For example, if an object is passed as an argument, the parser will check for its existence. If it is an engine tag, it will return the result of matching the current engine with the tag:

Valid values:

  • instance name - PC_HERO, ItMi_Gold, ...
  • engine tag - G1, G1A, G2, G2A
  • Steam Overlay activity - Steam

The result can be combined from several arguments. Round brackets () can be used to specify priority and expressions support the logical negation operator !, logical AND && and OR ||.

The operator can be used anywhere in the script file. It is syntactically similar to if else statement, but curly braces {} can be omitted for single-line operations. For example:

SteamActivated constant is set only when Steam is active
test Steam var const SteamActivated = 1;
-
Example of a logical expression with an else branch
1
-2
-3
-4
-5
-6
-7
-8
test SteamActivated && G2A 
-{
-    // TODO
-}
-else 
-{
-    // TODO
-}
-
\ No newline at end of file diff --git a/zengin/scripts/extenders/zparserextender/syntax_extensions/while/index.html b/zengin/scripts/extenders/zparserextender/syntax_extensions/while/index.html deleted file mode 100644 index 40cbe1f0fc..0000000000 --- a/zengin/scripts/extenders/zparserextender/syntax_extensions/while/index.html +++ /dev/null @@ -1,62 +0,0 @@ - While loop - Gothic Modding Community

Native WHILE loop

Just like Ikarus zParserExtender implements a while loop.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
var int value; value = 10;
-while(value > 0)
-{
-    if (value == 8)
-    {
-        continue;
-    };
-
-    if (value == 2)
-    {
-        break;
-    };
-};
-

Note

To activate while it is necessary to set NativeWhile setting in SystemPack.ini

1
-2
[ZPARSE_EXTENDER]
-NativeWhile = true
-

Compiled while loop works in vanilla engine without the plugin.

\ No newline at end of file diff --git a/zengin/scripts/extenders/zparserextender/testelse/index.html b/zengin/scripts/extenders/zparserextender/testelse/index.html deleted file mode 100644 index 54c26cdb73..0000000000 --- a/zengin/scripts/extenders/zparserextender/testelse/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/zengin/scripts/extenders/zparserextender/while/index.html b/zengin/scripts/extenders/zparserextender/while/index.html deleted file mode 100644 index 84cdf313b4..0000000000 --- a/zengin/scripts/extenders/zparserextender/while/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/zengin/scripts/externals/doc/index.html b/zengin/scripts/externals/doc/index.html deleted file mode 100644 index 921118e7cc..0000000000 --- a/zengin/scripts/externals/doc/index.html +++ /dev/null @@ -1,299 +0,0 @@ - Doc functions - Gothic Modding Community

Doc external functions

Doc functions are used to control the document manager. They allow you to fine tune the display of maps, letters and books.

Doc_Create

Creates a new instance of the document manager and returns its ID.

func int Doc_Create() {};
-

Return value
Returns the ID of the document manager instance.

Example

1
-2
var int nDocID; // Variable to store the id in
-nDocID = Doc_Create();
-

Doc_CreateMap

Creates a new instance of the document manager with the arrow showing players position on the map and returns its ID.

func int Doc_CreateMap() {};
-

Return value
Returns the ID of the document manager instance.

Example

1
-2
var int nDocID; // Variable to store the id in
-nDocID = Doc_CreateMap();
-

Doc_SetLevel

Set a world level to a map. This maps the texture of the document to the bounding box of the provided level.

func void Doc_SetLevel(var int docID, var string level) {};
-

Parameters

  • var int docID - document manager ID
  • var string level - name of the ZEN file

Example

1
-2
nDocID = Doc_CreateMap();
-Doc_SetLevel(nDocID, "WORLD.ZEN");
-

Doc_SetLevelCoords

Warning

This function is only available in Gothic 2

Sets the map coordinates. This is used to map smaller portions of the world map to the document map to correctly show players position on the map.

func void Doc_SetLevelCoords(var int docID, var int left, var int top, var int right, var int bottom) {};
-

Parameters

  • var int docID - document manager ID
  • var int left - left coordinate
  • var int top - top coordinate
  • var int right - right coordinate
  • var int bottom - bottom coordinate

Example

Doc_SetLevelCoords(nDocID, -28000, 50500, 95500, -42500);
-

Doc_SetFont

Sets a font to be used on a page in a document with docID. Can be called multiple times to display different lines with different fonts.

func void Doc_SetFont(var int docID, var int page, var string font) {};
-

Parameters

  • var int docID - document manager ID
  • var int page - page index, if set to -1, fonts will be applied to all pages
  • var string font - font to be used

Example

Doc_SetFont(nDocID, -1, "FONT_10_BOOK.TGA");
-

Doc_SetPages

Sets the number of pages numOfPages of the document.

func void Doc_SetPages(var int docID, var int numOfPages) {};
-

Parameters

  • var int docID - document manager ID
  • var int numOfPages - number of pages

Example

1
-2
nDocID = Doc_Create();
-Doc_SetPages(nDocID, 2);
-

Doc_SetPage

Set page to have texture as a background with scale.

func void Doc_SetPage(var int docID, var int page, var string texture, var int scale) {};
-

Parameters

  • var int docID - document manager ID
  • var int page - page index, if set to -1, settings are applied to all pages
  • var string texture - texture of the background
  • var int scale - scale of the texture, TRUE to scale the page, FALSE to not scale

Example

1
-2
Doc_SetPage(nDocID, 0, "Book_Mage_L.tga", FALSE);
-Doc_SetPage(nDocID, 1, "Book_Mage_R.tga", FALSE);
-

Doc_SetMargins

Sets text margins of the page

1
-2
-3
-4
-5
-6
-7
func void Doc_SetMargins(var int docID,
-                         var int page,
-                         var int left,
-                         var int top,
-                         var int right,
-                         var int bottom,
-                         var int pixels) {};
-

Parameters

  • var int docID - document manager ID
  • var int page - page index, if set to -1, settings are applied to all pages
  • var int left - left margin
  • var int top - top margin
  • var int right - right margin
  • var int bottom - bottom margin
  • var int pixels - TRUE to use pixels, FALSE to use virtual coordinates

Warning

After a thorough examination of this external function in the decompiler, it looks like the function works in pixels only regardless of this parameter.

Example

Doc_SetMargins(nDocID, 0, 275, 20, 30, 20, TRUE);
-

Doc_PrintLine

Prints a line of text (font is set using Doc_SetFont) onto the document with docID, onto the page. Does not split the text into multiple lines if they do not fit onto the page.

func void Doc_PrintLine(var int docID, var int page, var string text) {};
-

Parameters

  • var int docID - document manager ID
  • var int page - page index
  • var string text - text to be printed

Example

1
-2
Doc_PrintLine(nDocID, 0, ""); // insert empty line
-Doc_PrintLine(nDocID, 0, "The Book");
-

Doc_PrintLines

Prints a line of text (font is set using Doc_SetFont) onto the document with docID, onto the page. Splits the text into multiple lines if they do not fit onto the page.

func void Doc_PrintLines(var int docID, var int page, var string text) {};
-

Parameters

  • var int docID - document manager ID
  • var int page - page index
  • var string text - text to be printed

Example

1
-2
Doc_PrintLines(nDocID, 0, "The war had been decided. Varant had lost its seaports, vital to army supplies. King Rhobar had not lingered on the battle fields for a long time, but left his generals to deal with the few remaining enemy troops. Varant had only one large force left, commanded by Lukkor, the most capable warlord of the Varant army, who had more than once turned defeat into victory.");
-Doc_PrintLines(nDocID, 0, "But now his army was trapped. The situation was hopeless, even though his army greatly outnumbered the enemy. Lee, a war hero from Myrtana, had lured him into this trap. The heavy cavalry had been unable to fight on the thick, swamped ground of the narrow valley. Lee's soldiers had occupied the range of hills surrounding the swamp, and they had struck repeatedly, decimating the army. The desperate sallies his troops had launched had been cut short in pools of blood. He was beaten.");
-

Doc_Show

Display the document using the document manager ID

func void Doc_Show(var int docID) {};
-

Parameters

  • var int docID - document manager ID

Example

1
-2
-3
-4
-5
-6
var int nDocID; // Variable to store the id in
-nDocID = Doc_Create();
-
-// ... document configuration
-
-Doc_Show(nDocID);
-

Externals with docu comments

  1
-  2
-  3
-  4
-  5
-  6
-  7
-  8
-  9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
-100
-101
-102
-103
-104
/// Creates a new instance of the document manager and returns its ID.
-///
-/// @return Returns the ID of the document manager instance.
-func int Doc_Create() {};
-
-/// Create a new instance of the document manager with the arrow showing players position on the map and returns its ID.
-///
-/// @return Returns the ID of the document manager instance.
-func int Doc_CreateMap() {};
-
-/// Prints a line of `text` onto the document with `docID`, onto the `page`.
-/// Does not line break
-/// 
-/// @param docID document manager ID
-/// @param page page index
-/// @param text text to be printed
-func void Doc_PrintLine(var int docID, var int page, var string text) {};
-
-/// Prints a line of `text` onto the document with `docID`, onto the `page`. The `text` is automatically split into multiple lines
-/// 
-/// @param docID document manager ID
-/// @param page page index
-/// @param text text to be printed
-func void Doc_PrintLines(var int docID, var int page, var string text) {};
-
-/// Sets a `font` to be used on a `page` in a document with `docID`. Can be called multiple times to display different lines with different fonts.
-///
-/// @param docID document manager ID
-/// @param page page index
-/// @param font font to be used
-func void Doc_SetFont(var int docID, var int page, var string font) {};
-
-/// Sets the number of pages `numOfPages` of the document.
-///
-/// @param docID document manager ID
-/// @param numOfPages number of pages
-func void Doc_SetPages(var int docID, var int numOfPages) {};
-
-/// Set `page` to have `texture` as a background with `scale`. 
-///
-/// @param docID document manager ID
-/// @param page page index, if set to `-1`, settings are applied to all pages
-/// @param texture texture of the background
-/// @param scale scale of the texture, if set to 1, there will be no resizing
-func void Doc_SetPage(var int docID, var int page, var string texture, var int scale) {};
-
-/// Set a world level to a map.
-///
-/// @param docID document manager ID
-/// @param level name of the ZEN file
-func void Doc_SetLevel(var int docID, var string level) {};
-
-/// Sets the map coordinates. 
-/// 
-/// @param docID document manager ID
-/// @param left left
-/// @param top top
-/// @param right top
-/// @param bottom bottom
-func void Doc_SetLevelCoords(var int docID, var int left, var int top, var int right, var int bottom) {};
-
-/// Sets text margins of the page
-///
-/// @param docID document manager ID
-/// @param page page index, if set to `-1`, settings are applied to all pages
-/// @param left left margin
-/// @param top top margin
-/// @param right right margin
-/// @param bottom bottom margin
-/// @param pixels `TRUE` to use pixels, `FALSE` to use virtual coordinates
-func void Doc_SetMargins(var int docID,
-                         var int page,
-                         var int left,
-                         var int top,
-                         var int right,
-                         var int bottom,
-                         var int pixels) {};
-
-/// Display the document using the document manager ID
-///
-/// @param docID document manager ID
-func void Doc_Show(var int docID) {};
-
-
-
-/// deprecated
-func void Doc_Open (var string Texture) {};
-
-/// deprecated
-func void Doc_Font(var string Font) {};
-
-/// deprecated
-func void Doc_Print (var string Text) {};
-
-/// deprecated
-func void Doc_MapCoordinates(var string s0,
-                             var float r1,
-                             var float r2,
-                             var float r3,
-                             var float r4,
-                             var float r5,
-                             var float r6,
-                             var float r7,
-                             var float r8) {};
-
\ No newline at end of file diff --git a/zengin/scripts/externals/externals.d b/zengin/scripts/externals/externals.d deleted file mode 100644 index 6750beba60..0000000000 --- a/zengin/scripts/externals/externals.d +++ /dev/null @@ -1,353 +0,0 @@ -func void AI_AimAt(var c_npc attacker, var c_npc target) {}; -func void AI_AlignToFP(var c_npc self) {}; -func void AI_AlignToWP(var c_npc self) {}; -func void AI_AskText(var c_npc self, var func funcyes, var func funcno, var string stryes, var string strno) {}; -func void AI_Ask(var c_npc self, var func anseryes, var func answerno) {}; -func void AI_Attack(var c_npc self) {}; -func void AI_CanSeeNpc(var instance n0, var instance n1, var func f2) {}; -func void AI_CombatReactToDamage(var instance n0) {}; -func void AI_ContinueRoutine(var c_npc self) {}; -func void AI_Defend(var c_npc self) {}; -func void AI_Dodge(var c_npc npc) {}; -func void AI_DrawWeapon(var c_npc n0) {}; -func void AI_DropItem(var c_npc self, var int itemid) {}; -func void AI_DropMob(var instance n0) {}; -func void AI_EquipArmor(var c_npc owner, var c_item armor_from_owners_inventory) {}; -func void AI_EquipBestArmor(var c_npc self) {}; -func void AI_EquipBestMeleeWeapon(var c_npc self) {}; -func void AI_EquipBestRangedWeapon(var c_npc self) {}; -func void AI_FinishingMove(var c_npc self, var c_npc other) {}; -func void AI_Flee(var c_npc self) {}; -func void AI_GotoFP(var c_npc self, var string fpname) {}; -func void AI_GotoItem(var c_npc self, var c_item item) {}; -func void AI_GotoNextFP(var c_npc self, var string fpname) {}; -func void AI_GotoNpc(var c_npc self, var c_npc other) {}; -func void AI_GotoSound(var c_npc n0) {}; -func void AI_GotoWP(var c_npc n0, var string s0) {}; -func void AI_LookAtNpc(var c_npc self, var c_npc other) {}; -func void AI_LookAt(var c_npc self, var string name) {}; -func void AI_LookForItem(var c_npc self, var int instance) {}; -func void AI_OutputSVM_Overlay(var c_npc self, var c_npc target, var string svmname) {}; -func void AI_OutputSVM(var c_npc self, var c_npc target, var string svmname) {}; -func void AI_Output(var c_npc self, var c_npc target, var string outputname) {}; -func void AI_PlayAniBS(var c_npc npc, var string aniname, var int bodystate) {}; -func void AI_PlayAni(var c_npc n0, var string s0) {}; -func void AI_PlayCutscene(var c_npc self, var string csname) {}; -func void AI_PlayFX(var instance n0, var instance n1, var string s2) {}; -func void AI_PointAtNpc(var c_npc self, var c_npc other) {}; -func void AI_PointAt(var c_npc self, var string name) {}; -func int AI_PrintScreen(var string s0, var int i1, var int i2, var string s3, var int i4) {}; -func void AI_ProcessInfos(var instance n0) {}; -func void AI_Quicklook(var c_npc self, var c_npc other) {}; -func void AI_QuickLook(var instance n0, var instance n1) {}; -func void AI_ReadyMeleeWeapon(var c_npc self) {}; -func void AI_ReadyRangedWeapon(var c_npc self) {}; -func void AI_ReadySpell(var c_npc self, var int spellid, var int investmana) {}; -func void AI_RemoveWeapon(var c_npc n0) {}; -func void AI_SetNpcsToState(var c_npc self, var func aistatefunc, var int radius) {}; -func void AI_SetWalkmode(var c_npc n, var int n0) {}; -func void AI_SetWalkMode(var instance n0, var int i1) {}; -func void AI_ShootAt(var c_npc attacker, var c_npc target) {}; -func void AI_Snd_Play(var instance n0, var string s1) {}; -func void AI_Snd_Play3D(var instance n0, var instance n1, var string s2) {}; -func void AI_StandUpQuick(var c_npc self) {}; -func void AI_StandUp(var c_npc self) {}; -func void AI_StartState(var c_npc self, var func what, var int statebehaviour, var string wpname) {}; -func void AI_StopAim(var c_npc attacker) {}; -func void AI_StopFX(var instance n0, var string s1) {}; -func void AI_StopLookAt(var c_npc self) {}; -func void AI_StopPointAt(var c_npc self) {}; -func void AI_StopProcessInfos(var c_npc npc) {}; -func void AI_TakeItem(var c_npc self, var c_item item) {}; -func void AI_TakeMob(var instance n0, var string s1) {}; -func void AI_Teleport(var c_npc self, var string waypoint) {}; -func void AI_TurnAway(var c_npc n0, var c_npc n1) {}; -func void AI_TurnToNpc(var c_npc n0, var c_npc n1) {}; -func void AI_TurnToSound(var c_npc self) {}; -func void AI_UnequipArmor(var c_npc self) {}; -func void AI_UnequipWeapons(var c_npc self) {}; -func void AI_UnreadySpell(var c_npc self) {}; -func void AI_UseItemToState(var c_npc self, var int iteminstance, var int state) {}; -func void AI_UseItem(var c_npc self, var int iteminstance) {}; -func int AI_UseMob(var c_npc self, var string schemename, var int targetstate) {}; -func void AI_WaitForQuestion(var c_npc self, var func scriptfunc) {}; -func void AI_WaitMS(var instance n0, var int i1) {}; -func void AI_WaitTillEnd(var c_npc self, var c_npc other) {}; -func void AI_Wait(var c_npc n0, var float n1) {}; -func void AI_WhirlAroundToSource(var instance n0) {}; -func void AI_WhirlAround(var c_npc self, var c_npc other) {}; -func void Apply_Options_Audio() {}; -func void Apply_Options_Controls() {}; -func void Apply_Options_Game() {}; -func void Apply_Options_Performance() {}; -func void Apply_Options_Video() {}; -func string ConcatStrings(var string str1, var string str2) {}; -func void CreateInvItems(var c_npc n0, var int n1, var int n2) {}; -func void CreateInvItem(var c_npc n0, var int n1) {}; - -func int Doc_Create() {}; -func int Doc_CreateMap() {}; -func void Doc_Font (var string Font) {}; -func void Doc_Font(var string s0) {}; -func void Doc_MapCoordinates (var string Level, var float GameX1, var float GameY1, var float PixelX1, var float PixelY1, var float GameX2, var float GameY2, var float PixelX2, var float PixelY2) {}; -func void Doc_MapCoordinates(var string s0, var float r1, var float r2, var float r3, var float r4, var float r5, var float r6, var float r7, var float r8) {}; -func void Doc_Open(var string s0) {}; -func void Doc_Open (var string Texture) {}; -func void Doc_PrintLines(var int document, var int page, var string text) {}; -func void Doc_PrintLine(var int document, var int page, var string text) {}; -func void Doc_Print(var string s0) {}; -func void Doc_Print (var string Text) {}; -func void Doc_SetFont(var int document, var int page, var string font) {}; -func void Doc_SetLevelCoords(var int document, var int left, var int top, var int right, var int bottom) {}; -func void Doc_SetLevel(var int document, var string level) {}; -func void Doc_SetMargins(var int document, var int page, var int left, var int top, var int right, var int bottom, var int pixels) {}; -func void Doc_SetPages(var int document, var int count) {}; -func void Doc_SetPage(var int document, var int page, var string texture, var int scale) {}; -func void Doc_Show(var int document) {}; - -func void EquipItem(var c_npc n0, var int n1) {}; -func void ExitGame() {}; -func void ExitSession() {}; -func int FloatToInt(var float x) {}; -func string FloatToString(var float r0) {}; -func void Game_InitEnglish() {}; -func void Game_InitGerman() {}; -func int Hlp_CutscenePlayed(var string csname) {}; -func int Hlp_GetInstanceID(var c_item item) {}; -func c_npc Hlp_GetNpc(var int instancename) {}; -func int Hlp_IsItem(var c_item item, var int instancename) {}; -func int Hlp_IsValidItem(var c_item item) {}; -func int Hlp_IsValidNpc(var c_npc self) {}; -func int Hlp_Random(var int n0) {}; -func int Hlp_StrCmp(var string s1, var string s2) {}; -func void Info_AddChoice(var int i0, var string s1, var func f2) {}; -func void Info_ClearChoices(var int i0) {}; -func int InfoManager_HasFinished() {}; -func void IntroduceChapter(var string titel, var string untertitel, var string texture, var string sound, var int waittime) {}; -func float IntToFloat(var int x) {}; -func string IntToString(var int x) {}; - -/// Creates a new log topic with the name `topicName` under the section `logSection` -/// -/// @param topicName unique string used to identify and name the topic -/// @param logSection [LOG_MISSION, LOG_NOTE] indicates in which section to create the topic in -func void Log_CreateTopic(var string topicName, var int logSection) {}; -/// Adds an entry to a log topic with the name `topicName` under the section `logSection` -/// -/// @param topicName unique string used to identify and name the topic -/// @param entry content of the new entry -func void Log_AddEntry(var string topicName, var string entry) {}; -/// Changes the status of the topic with the name `topicName` -/// -/// @param topicName unique string used to identify and name the topic -/// @param status [LOG_RUNNING, LOG_SUCCESS, LOG_FAILED, LOG_OBSOLETE] the status to be set -func void Log_SetTopicStatus(var string TopicName, var int status) {}; - -func void Mdl_ApplyOverlayMDSTimed(var c_npc self, var string overlayname, var float timeticks) {}; -func void Mdl_ApplyOverlayMdsTimed(var instance n0, var string s1, var int i2) {}; -func void Mdl_ApplyOverlayMds(var c_npc n0, var string s1) {}; -func void Mdl_ApplyOverlayMDS(var instance n0, var string s1) {}; -func void Mdl_ApplyRandomAniFreq(var c_npc n0, var string s1, var float f2) {}; -func void Mdl_ApplyRandomAni(var c_npc n0, var string s1, var string s2) {}; -func void Mdl_ApplyRandomFaceAni(var c_npc self, var string name, var float timemin, var float timeminvar, var float timemax, var float timemaxvar, var float probmin) {}; -func void Mdl_RemoveOverlayMDS(var c_npc self, var string overlayname) {}; -func void Mdl_SetModelFatness(var c_npc self, var float fatness) {}; -func void Mdl_SetModelScale(var c_npc self, var float x, var float y, var float z) {}; -func void Mdl_SetVisualBody(var instance n0, var string s1, var int i2, var int i3, var string s4, var int i5, var int i6, var int i7) {}; -func void Mdl_SetVisual(var instance n0, var string s1) {}; -func void Mdl_StartFaceAni(var c_npc self, var string name, var float intensity, var float holdtime) {}; - -func void Mis_AddMissionEntry(var instance n0, var string s1) {}; -func int Mis_GetStatus(var int missionname) {}; -func int Mis_OnTime(var int missionname) {}; -func void Mis_RemoveMission(var instance n0) {}; -func void Mis_SetStatus(var int missionname, var int newstatus) {}; -func void Mob_CreateItems(var string mobname, var int iteminstance, var int amount) {}; -func int Mob_HasItems(var string mobname, var int iteminstance) {}; -func int Npc_AreWeStronger(var c_npc self, var c_npc other) {}; -func int Npc_CanSeeItem(var c_npc npc1, var c_item item) {}; -func int Npc_CanSeeNpcFreeLOS(var c_npc self, var c_npc other) {}; -func int Npc_CanSeeNpc(var c_npc npc1, var c_npc npc2) {}; -func int Npc_CanSeeSource(var c_npc self) {}; -func void Npc_ClearAIQueue(var c_npc self) {}; -func void Npc_ClearInventory(var instance n0) {}; -func void Npc_CreateSpell(var c_npc self, var int spellnr) {}; -func int Npc_DeleteNews(var instance n0, var int i1) {}; -func void Npc_ExchangeRoutine(var c_npc self, var string routinename) {}; -func int Npc_GetActiveSpellCat(var c_npc self) {}; -func int Npc_GetActiveSpellIsScroll(var instance n0) {}; -func int Npc_GetActiveSpellLevel(var c_npc self) {}; -func int Npc_GetActiveSpell(var c_npc self) {}; -func int Npc_GetAttitude(var c_npc self, var c_npc other) {}; -func int Npc_GetBodyState(var c_npc self) {}; -func int Npc_GetComrades(var instance n0) {}; -func string Npc_GetDetectedMob(var c_npc self) {}; -func int Npc_GetDistToItem(var c_npc npc, var c_item item) {}; -func int Npc_GetDistToNpc(var c_npc npc1, var c_npc npc2) {}; -func int Npc_GetDistToPlayer(var c_npc npc1) {}; -func int Npc_GetDistToWP(var c_npc self, var string wpname) {}; -func c_item Npc_GetEquippedArmor(var c_npc n0) {}; -func c_item Npc_GetEquippedMeleeWeapon(var c_npc n0) {}; -func c_item Npc_GetEquippedRangedWeapon(var c_npc n0) {}; -func int Npc_GetGuildAttitude(var c_npc npc, var c_npc npc) {}; -func int Npc_GetHeightToItem(var instance n0, var instance n1) {}; -func int Npc_GetHeightToNpc(var c_npc npc1, var c_npc npc2) {}; -func int Npc_GetInvItemBySlot(var c_npc self, var int category, var int slotnr) {}; -func c_item Npc_GetInvItem(var c_npc self, var int iteminstance) {}; -func int Npc_GetLastHitSpellCat(var c_npc self) {}; -func int Npc_GetLastHitSpellID(var c_npc self) {}; -func instance Npc_GetLookAtTarget(var instance n0) {}; -func string Npc_GetNearestWP(var c_npc self) {}; -func c_npc Npc_GetNewsOffender(var c_npc self, var int newsnumber) {}; -func c_npc Npc_GetNewsVictim(var c_npc self, var int newsnumber) {}; -func c_npc Npc_GetNewsWitness(var c_npc self, var int newsnumber) {}; -func int Npc_GetNextTarget(var c_npc self) {}; -func string Npc_GetNextWP(var c_npc self) {}; -func int Npc_GetPermAttitude(var c_npc self, var c_npc other) {}; -func int Npc_GetPortalGuild(var instance n0) {}; -func instance Npc_GetPortalOwner(var instance n0) {}; -func c_item Npc_GetReadiedWeapon(var c_npc n0) {}; -func int Npc_GetStateTime(var c_npc self) {}; -func int Npc_GetTalentSkill(var instance n0, var int i1) {}; -func int Npc_GetTalentValue(var instance n0, var int i1) {}; -func int Npc_GetTarget(var c_npc self) {}; -func int Npc_GetTrueGuild(var c_npc npc) {}; -func int NPC_GiveInfo(var c_npc npc, var int important) {}; -func int Npc_GiveInfo(var instance n0, var int i1) {}; -func void Npc_GiveItem(var c_npc n0, var c_item n1, var c_npc n2) {}; -func int Npc_HasBodyFlag(var c_npc self, var int bodyflag) {}; -func int Npc_HasDetectedNpc(var c_npc self, var c_npc other) {}; -func int Npc_HasEquippedArmor(var c_npc self) {}; -func int Npc_HasEquippedMeleeWeapon(var c_npc self) {}; -func int Npc_HasEquippedRangedWeapon(var c_npc self) {}; -func int Npc_HasEquippedWeapon(var c_npc self) {}; -func int Npc_HasFightTalent(var c_npc self, var int tal) {}; -func int Npc_HasItems(var c_npc n0, var int iteminstance) {}; -func int Npc_HasNews(var c_npc self, var int newsid, var c_npc offender, var c_npc victim) {}; -func int Npc_HasOffered(var c_npc self, var c_npc other, var int iteminstance) {}; -func int Npc_HasRangedWeaponWithAmmo(var c_npc npc) {}; -func int Npc_HasReadiedMeleeWeapon(var c_npc self) {}; -func int Npc_HasReadiedRangedWeapon(var c_npc self) {}; -func int Npc_HasReadiedWeapon(var c_npc self) {}; -func int Npc_HasSpell(var c_npc self, var int spellid) {}; -func int Npc_HasTalent(var c_npc self, var int tal) {}; -func void Npc_ChangeAttribute(var c_npc self, var int atr, var int value) {}; -func int Npc_CheckAvailableMission(var c_npc npc, var int missionstate, var int important) {}; -func int Npc_CheckInfo(var c_npc npc, var int important) {}; -func int Npc_CheckOfferMission(var c_npc npc, var int important) {}; -func int Npc_CheckRunningMission(var c_npc npc, var int important) {}; -func int Npc_IsAiming(var c_npc self, var c_npc other) {}; -func int Npc_IsDead(var c_npc n0) {}; -func int Npc_IsDetectedMobOwnedByGuild(var c_npc user, var int ownerguild) {}; -func int Npc_IsDetectedMobOwnedByNpc(var c_npc user, var c_npc owner) {}; -func int Npc_IsDrawingSpell(var instance n0) {}; -func int Npc_IsDrawingWeapon(var instance n0) {}; -func int Npc_IsInCutscene(var c_npc self) {}; -func int Npc_IsInFightMode(var c_npc self, var int fmode) {}; -func int Npc_IsInPlayersRoom(var instance n0) {}; -func int Npc_IsInRoutine(var c_npc self, var func state) {}; -func int Npc_IsInState(var c_npc self, var func state) {}; -func int Npc_IsNear(var c_npc self, var c_npc other) {}; -func int Npc_IsNewsGossip(var c_npc self, var int newsnumber) {}; -func int Npc_IsNextTargetAvailable(var c_npc self) {}; -func int Npc_IsOnFP(var c_npc self, var string name) {}; -func int Npc_IsPlayerInMyRoom(var c_npc npc) {}; -func int Npc_IsPlayer(var c_npc player) {}; -func int Npc_IsVoiceActive(var instance n0) {}; -func int Npc_IsWayBlocked(var c_npc self) {}; -func int Npc_KnowsInfo(var c_npc self, var int infoinstance) {}; -func int Npc_KnowsPlayer(var c_npc self, var c_npc player) {}; -func void Npc_LearnSpell(var c_npc self, var int spellnr) {}; -func void Npc_MemoryEntryGuild(var c_npc self, var int source, var c_npc offender, var int newsid, var c_npc victimguild) {}; -func void Npc_MemoryEntry(var c_npc self, var int source, var c_npc offender, var int newsid, var c_npc victim) {}; -func int Npc_OwnedByGuild(var c_item item, var int guild) {}; -func int Npc_OwnedByNpc(var c_item item, var c_npc npc) {}; -func void Npc_PercDisable(var c_npc self, var int percid) {}; -func void Npc_PerceiveAll(var c_npc self) {}; -func void Npc_PercEnable(var c_npc self, var int percid, var func function) {}; -func void Npc_PlayAni(var instance n0, var string s1) {}; -func int Npc_RefuseTalk(var c_npc self) {}; -func void Npc_RemoveInvItems(var c_npc owner, var int iteminstance, var int amount) {}; -func void Npc_RemoveInvItem(var c_npc owner, var int iteminstance) {}; -func void Npc_SendPassivePerc(var c_npc npc1, var int perc_type, var c_npc npc2, var c_npc npc3) {}; -func void Npc_SendSinglePerc(var c_npc self, var c_npc target, var int percid) {}; -func int Npc_SetActiveSpellInfo(var c_npc npc, var int i1) {}; -func void Npc_SetAttitude(var c_npc self, var int att) {}; -func void Npc_SetKnowsPlayer(var c_npc self, var c_npc player) {}; -func void Npc_SetPercTime(var c_npc self, var float seconds) {}; -func void Npc_SetRefuseTalk(var c_npc self, var int timesec) {}; -func void Npc_SetStateTime(var c_npc self, var int seconds) {}; -func void Npc_SetTalentSkill(var instance n0, var int i1, var int i2) {}; -func void Npc_SetTalentValue(var instance n0, var int i1, var int i2) {}; -func void Npc_SetTarget(var c_npc self, var c_npc other) {}; -func void Npc_SetTeleportPos(var c_npc self) {}; -func void Npc_SetTempAttitude(var c_npc self, var int att) {}; -func void Npc_SetToFightMode(var c_npc self, var int weapon) {}; -func void Npc_SetToFistMode(var c_npc self) {}; -func int Npc_SetTrueGuild(var c_npc npc, var int guildid) {}; -func int Npc_StartItemReactModules(var c_npc self, var c_npc other, var c_item item) {}; -func void Npc_StopAni(var instance n0, var string s1) {}; -func int Npc_WasInState(var c_npc self, var func state) {}; -func int Npc_WasPlayerInMyRoom(var c_npc npc) {}; -func void Perc_SetRange(var int percid, var int range) {}; -func int PlayVideoEx(var string filename, var int screenblend, var int exitsession) {}; -func int PlayVideo(var string filename) {}; -func void PrintDebugCh(var int ch, var string text) {}; -func void PrintDebugInstCh(var int ch, var string text) {}; -func void PrintDebugInst(var string text) {}; -func void PrintDebug(var string s) {}; -func int PrintDialog(var int i0, var string s1, var int i2, var int i3, var string s4, var int i5) {}; -func void PrintMulti(var string s0, var string s1, var string s2, var string s3, var string s4) {}; -func void PrintScreen(var string msg, var int posx, var int posy, var string font, var int timesec) {}; -func void Print(var string s0) {}; -func void Rtn_Exchange(var string oldroutine, var string newroutine) {}; -func void SetPercentDone(var int percentdone) {}; -func int Snd_GetDistToSource(var c_npc self) {}; -func int Snd_IsSourceItem(var c_npc self) {}; -func int Snd_IsSourceNpc(var c_npc self) {}; -func void Snd_Play(var string s0) {}; -func void Snd_Play3D(var c_npc n0, var string s1) {}; -func void TA_BeginOverlay(var c_npc self) {}; -func void TA_CS(var c_npc self, var string csname, var string rolename) {}; -func void TA_EndOverlay(var c_npc self) {}; -func void Tal_Configure(var int i0, var int i1) {}; -func void TA_Min(var c_npc self, var int start_h, var int start_m, var int stop_h, var int stop_m, var func state, var string waypoint) {}; -func void TA_RemoveOverlay(var c_npc self) {}; -func void TA(var c_npc self, var int start_h, var int stop_h, var func state, var string waypoint) {}; -func void Update_ChoiceBox(var string s0) {}; -func void Wld_AssignRoomToGuild(var string s0, var int guild) {}; -func void Wld_AssignRoomToNpc(var string s0, var c_npc roomowner) {}; -func int Wld_DetectItem(var c_npc self, var int flags) {}; -func int Wld_DetectNpcExAtt(var instance n0, var int i1, var func f2, var int i3, var int i4, var int i5) {}; -func int Wld_DetectNpcEx(var instance n0, var int i1, var func f2, var int i3, var int i4) {}; -func int Wld_DetectNpc(var c_npc self, var int instance, var func aistate, var int guild) {}; -func int Wld_DetectPlayer(var c_npc self) {}; -func void Wld_ExchangeGuildAttitudes(var string name) {}; -func int Wld_GetDay() {}; -func int Wld_GetFormerPlayerPortalGuild() {}; -func c_npc Wld_GetFormerPlayerPortalOwner() {}; -func int Wld_GetGuildAttitude(var int guild1, var int guild2) {}; -func int Wld_GetMobState(var c_npc self, var string schemename) {}; -func int Wld_GetPlayerPortalGuild() {}; -func c_npc Wld_GetPlayerPortalOwner() {}; -func void Wld_InsertItem(var int iteminstance, var string spawnpoint) {}; -func void Wld_InsertNpcAndRespawn(var int instance, var string spawnpoint, var float spawndelay) {}; -func void Wld_InsertNpc(var int npcinstance, var string spawnpoint) {}; -func void Wld_InsertObject(var string s0, var string s1) {}; -func int Wld_IsFPAvailable(var c_npc self, var string fpname) {}; -func int Wld_IsFpAvailable(var instance n0, var string s1) {}; -func int Wld_IsMobAvailable(var c_npc self, var string schemename) {}; -func int Wld_IsNextFPAvailable(var c_npc self, var string fpname) {}; -func int Wld_IsNextFpAvailable(var instance n0, var string s1) {}; -func int Wld_IsRaining() {}; -func int Wld_IsTime(var int hour1, var int min1, var int hour2, var int min2) {}; -func void Wld_PlayEffect(var string effectinstance, var int originvob, var int targetvob, var int effectlevel, var int damage, var int damagetype, var int bisprojectile) {}; -func int Wld_RemoveItem(var c_item item) {}; -func void Wld_RemoveNpc(var int i0) {}; -func void Wld_SendTrigger(var string vobname) {}; -func void Wld_SendUntrigger(var string vobname) {}; -func void Wld_SetGuildAttitude(var int guild1, var int attitude, var int guild2) {}; -func void Wld_SetMobRoutine(var int hour1, var int min1, var string objname, var int state) {}; -func void Wld_SetObjectRoutine(var int hour1, var int min1, var string objname, var int state) {}; -func void Wld_SetTime(var int hour, var int min) {}; -func void Wld_SpawnNpcRange(var instance n0, var int i1, var int i2, var float r3) {}; diff --git a/zengin/scripts/externals/externals_clean.d b/zengin/scripts/externals/externals_clean.d deleted file mode 100644 index 0d67d9eea6..0000000000 --- a/zengin/scripts/externals/externals_clean.d +++ /dev/null @@ -1,350 +0,0 @@ -func void AI_AimAt(var c_npc attacker, var c_npc target) {}; -func void AI_AlignToFP(var c_npc self) {}; -func void AI_AlignToWP(var c_npc self) {}; -func void AI_AskText(var c_npc self, var func funcyes, var func funcno, var string stryes, var string strno) {}; -func void AI_Ask(var c_npc self, var func anseryes, var func answerno) {}; -func void AI_Attack(var c_npc self) {}; -func void AI_CanSeeNpc(var instance n0, var instance n1, var func f2) {}; -func void AI_CombatReactToDamage(var instance n0) {}; -func void AI_ContinueRoutine(var c_npc self) {}; -func void AI_Defend(var c_npc self) {}; -func void AI_Dodge(var c_npc npc) {}; -func void AI_DrawWeapon(var c_npc n0) {}; -func void AI_DropItem(var c_npc self, var int itemid) {}; -func void AI_DropMob(var instance n0) {}; -func void AI_EquipArmor(var c_npc owner, var c_item armor_from_owners_inventory) {}; -func void AI_EquipBestArmor(var c_npc self) {}; -func void AI_EquipBestMeleeWeapon(var c_npc self) {}; -func void AI_EquipBestRangedWeapon(var c_npc self) {}; -func void AI_FinishingMove(var c_npc self, var c_npc other) {}; -func void AI_Flee(var c_npc self) {}; -func void AI_GotoFP(var c_npc self, var string fpname) {}; -func void AI_GotoItem(var c_npc self, var c_item item) {}; -func void AI_GotoNextFP(var c_npc self, var string fpname) {}; -func void AI_GotoNpc(var c_npc self, var c_npc other) {}; -func void AI_GotoSound(var c_npc n0) {}; -func void AI_GotoWP(var c_npc n0, var string s0) {}; -func void AI_LookAtNpc(var c_npc self, var c_npc other) {}; -func void AI_LookAt(var c_npc self, var string name) {}; -func void AI_LookForItem(var c_npc self, var int instance) {}; -func void AI_OutputSVM_Overlay(var c_npc self, var c_npc target, var string svmname) {}; -func void AI_OutputSVM(var c_npc self, var c_npc target, var string svmname) {}; -func void AI_Output(var c_npc self, var c_npc target, var string outputname) {}; -func void AI_PlayAniBS(var c_npc npc, var string aniname, var int bodystate) {}; -func void AI_PlayAni(var c_npc n0, var string s0) {}; -func void AI_PlayCutscene(var c_npc self, var string csname) {}; -func void AI_PlayFX(var instance n0, var instance n1, var string s2) {}; -func void AI_PointAtNpc(var c_npc self, var c_npc other) {}; -func void AI_PointAt(var c_npc self, var string name) {}; -func int AI_PrintScreen(var string s0, var int i1, var int i2, var string s3, var int i4) {}; -func void AI_ProcessInfos(var instance n0) {}; -func void AI_Quicklook(var c_npc self, var c_npc other) {}; -func void AI_QuickLook(var instance n0, var instance n1) {}; -func void AI_ReadyMeleeWeapon(var c_npc self) {}; -func void AI_ReadyRangedWeapon(var c_npc self) {}; -func void AI_ReadySpell(var c_npc self, var int spellid, var int investmana) {}; -func void AI_RemoveWeapon(var c_npc n0) {}; -func void AI_SetNpcsToState(var c_npc self, var func aistatefunc, var int radius) {}; -func void AI_SetWalkmode(var c_npc n, var int n0) {}; -func void AI_SetWalkMode(var instance n0, var int i1) {}; -func void AI_ShootAt(var c_npc attacker, var c_npc target) {}; -func void AI_Snd_Play(var instance n0, var string s1) {}; -func void AI_Snd_Play3D(var instance n0, var instance n1, var string s2) {}; -func void AI_StandUpQuick(var c_npc self) {}; -func void AI_StandUp(var c_npc self) {}; -func void AI_StartState(var c_npc self, var func what, var int statebehaviour, var string wpname) {}; -func void AI_StopAim(var c_npc attacker) {}; -func void AI_StopFX(var instance n0, var string s1) {}; -func void AI_StopLookAt(var c_npc self) {}; -func void AI_StopPointAt(var c_npc self) {}; -func void AI_StopProcessInfos(var c_npc npc) {}; -func void AI_TakeItem(var c_npc self, var c_item item) {}; -func void AI_TakeMob(var instance n0, var string s1) {}; -func void AI_Teleport(var c_npc self, var string waypoint) {}; -func void AI_TurnAway(var c_npc n0, var c_npc n1) {}; -func void AI_TurnToNpc(var c_npc n0, var c_npc n1) {}; -func void AI_TurnToSound(var c_npc self) {}; -func void AI_UnequipArmor(var c_npc self) {}; -func void AI_UnequipWeapons(var c_npc self) {}; -func void AI_UnreadySpell(var c_npc self) {}; -func void AI_UseItemToState(var c_npc self, var int iteminstance, var int state) {}; -func void AI_UseItem(var c_npc self, var int iteminstance) {}; -func int AI_UseMob(var c_npc self, var string schemename, var int targetstate) {}; -func void AI_WaitForQuestion(var c_npc self, var func scriptfunc) {}; -func void AI_WaitMS(var instance n0, var int i1) {}; -func void AI_WaitTillEnd(var c_npc self, var c_npc other) {}; -func void AI_Wait(var c_npc n0, var float n1) {}; -func void AI_WhirlAroundToSource(var instance n0) {}; -func void AI_WhirlAround(var c_npc self, var c_npc other) {}; -func void Apply_Options_Audio() {}; -func void Apply_Options_Controls() {}; -func void Apply_Options_Game() {}; -func void Apply_Options_Performance() {}; -func void Apply_Options_Video() {}; -func string ConcatStrings(var string str1, var string str2) {}; -func void CreateInvItems(var c_npc n0, var int n1, var int n2) {}; -func void CreateInvItem(var c_npc n0, var int n1) {}; -func int Doc_Create() {}; -func int Doc_CreateMap() {}; -func void Doc_Font (var string Font) {}; -func void Doc_Font(var string s0) {}; -func void Doc_MapCoordinates (var string Level, var float GameX1, var float GameY1, var float PixelX1, var float PixelY1, var float GameX2, var float GameY2, var float PixelX2, var float PixelY2) {}; -func void Doc_MapCoordinates(var string s0, var float r1, var float r2, var float r3, var float r4, var float r5, var float r6, var float r7, var float r8) {}; -func void Doc_Open(var string s0) {}; -func void Doc_Open (var string Texture) {}; -func void Doc_PrintLines(var int document, var int page, var string text) {}; -func void Doc_PrintLine(var int document, var int page, var string text) {}; -func void Doc_Print(var string s0) {}; -func void Doc_Print (var string Text) {}; -func void Doc_SetFont(var int document, var int page, var string font) {}; -func void Doc_SetLevelCoords(var int document, var int left, var int top, var int right, var int bottom) {}; -func void Doc_SetLevel(var int document, var string level) {}; -func void Doc_SetMargins(var int document, var int page, var int left, var int top, var int right, var int bottom, var int pixels) {}; -func void Doc_SetPages(var int document, var int count) {}; -func void Doc_SetPage(var int document, var int page, var string texture, var int scale) {}; -func void Doc_Show(var int document) {}; -func void EquipItem(var c_npc n0, var int n1) {}; -func void ExitGame() {}; -func void ExitSession() {}; -func int FloatToInt(var float x) {}; -func string FloatToString(var float r0) {}; -func void Game_InitEnglish() {}; -func void Game_InitGerman() {}; -func int Hlp_CutscenePlayed(var string csname) {}; -func int Hlp_GetInstanceID(var c_item item) {}; -func c_npc Hlp_GetNpc(var int instancename) {}; -func int Hlp_IsItem(var c_item item, var int instancename) {}; -func int Hlp_IsValidItem(var c_item item) {}; -func int Hlp_IsValidNpc(var c_npc self) {}; -func int Hlp_Random(var int n0) {}; -func int Hlp_StrCmp(var string s1, var string s2) {}; -func void Info_AddChoice(var int i0, var string s1, var func f2) {}; -func void Info_ClearChoices(var int i0) {}; -func int InfoManager_HasFinished() {}; -func void IntroduceChapter(var string titel, var string untertitel, var string texture, var string sound, var int waittime) {}; -func float IntToFloat(var int x) {}; -func string IntToString(var int x) {}; - -/// Creates a new log topic with the name `topicName` under the section `logSection` -/// -/// @param topicName unique string used to identify and name the topic -/// @param logSection [LOG_MISSION, LOG_NOTE] indicates in which section to create the topic in -func void Log_CreateTopic(var string topicName, var int logSection) {}; -/// Adds an entry to a log topic with the name `topicName` under the section `logSection` -/// -/// @param topicName unique string used to identify and name the topic -/// @param entry content of the new entry -func void Log_AddEntry(var string topicName, var string entry) {}; -/// Changes the status of the topic with the name `topicName` -/// -/// @param topicName unique string used to identify and name the topic -/// @param status [LOG_RUNNING, LOG_SUCCESS, LOG_FAILED, LOG_OBSOLETE] the status to be set -func void Log_SetTopicStatus(var string TopicName, var int status) {}; - -func void Mdl_ApplyOverlayMDSTimed(var c_npc self, var string overlayname, var float timeticks) {}; -func void Mdl_ApplyOverlayMdsTimed(var instance n0, var string s1, var int i2) {}; -func void Mdl_ApplyOverlayMds(var c_npc n0, var string s1) {}; -func void Mdl_ApplyOverlayMDS(var instance n0, var string s1) {}; -func void Mdl_ApplyRandomAniFreq(var c_npc n0, var string s1, var float f2) {}; -func void Mdl_ApplyRandomAni(var c_npc n0, var string s1, var string s2) {}; -func void Mdl_ApplyRandomFaceAni(var c_npc self, var string name, var float timemin, var float timeminvar, var float timemax, var float timemaxvar, var float probmin) {}; -func void Mdl_RemoveOverlayMDS(var c_npc self, var string overlayname) {}; -func void Mdl_SetModelFatness(var c_npc self, var float fatness) {}; -func void Mdl_SetModelScale(var c_npc self, var float x, var float y, var float z) {}; -func void Mdl_SetVisualBody(var instance n0, var string s1, var int i2, var int i3, var string s4, var int i5, var int i6, var int i7) {}; -func void Mdl_SetVisual(var instance n0, var string s1) {}; -func void Mdl_StartFaceAni(var c_npc self, var string name, var float intensity, var float holdtime) {}; -func void Mis_AddMissionEntry(var instance n0, var string s1) {}; -func int Mis_GetStatus(var int missionname) {}; -func int Mis_OnTime(var int missionname) {}; -func void Mis_RemoveMission(var instance n0) {}; -func void Mis_SetStatus(var int missionname, var int newstatus) {}; -func void Mob_CreateItems(var string mobname, var int iteminstance, var int amount) {}; -func int Mob_HasItems(var string mobname, var int iteminstance) {}; -func int Npc_AreWeStronger(var c_npc self, var c_npc other) {}; -func int Npc_CanSeeItem(var c_npc npc1, var c_item item) {}; -func int Npc_CanSeeNpcFreeLOS(var c_npc self, var c_npc other) {}; -func int Npc_CanSeeNpc(var c_npc npc1, var c_npc npc2) {}; -func int Npc_CanSeeSource(var c_npc self) {}; -func void Npc_ClearAIQueue(var c_npc self) {}; -func void Npc_ClearInventory(var instance n0) {}; -func void Npc_CreateSpell(var c_npc self, var int spellnr) {}; -func int Npc_DeleteNews(var instance n0, var int i1) {}; -func void Npc_ExchangeRoutine(var c_npc self, var string routinename) {}; -func int Npc_GetActiveSpellCat(var c_npc self) {}; -func int Npc_GetActiveSpellIsScroll(var instance n0) {}; -func int Npc_GetActiveSpellLevel(var c_npc self) {}; -func int Npc_GetActiveSpell(var c_npc self) {}; -func int Npc_GetAttitude(var c_npc self, var c_npc other) {}; -func int Npc_GetBodyState(var c_npc self) {}; -func int Npc_GetComrades(var instance n0) {}; -func string Npc_GetDetectedMob(var c_npc self) {}; -func int Npc_GetDistToItem(var c_npc npc, var c_item item) {}; -func int Npc_GetDistToNpc(var c_npc npc1, var c_npc npc2) {}; -func int Npc_GetDistToPlayer(var c_npc npc1) {}; -func int Npc_GetDistToWP(var c_npc self, var string wpname) {}; -func c_item Npc_GetEquippedArmor(var c_npc n0) {}; -func c_item Npc_GetEquippedMeleeWeapon(var c_npc n0) {}; -func c_item Npc_GetEquippedRangedWeapon(var c_npc n0) {}; -func int Npc_GetGuildAttitude(var c_npc npc, var c_npc npc) {}; -func int Npc_GetHeightToItem(var instance n0, var instance n1) {}; -func int Npc_GetHeightToNpc(var c_npc npc1, var c_npc npc2) {}; -func int Npc_GetInvItemBySlot(var c_npc self, var int category, var int slotnr) {}; -func c_item Npc_GetInvItem(var c_npc self, var int iteminstance) {}; -func int Npc_GetLastHitSpellCat(var c_npc self) {}; -func int Npc_GetLastHitSpellID(var c_npc self) {}; -func instance Npc_GetLookAtTarget(var instance n0) {}; -func string Npc_GetNearestWP(var c_npc self) {}; -func c_npc Npc_GetNewsOffender(var c_npc self, var int newsnumber) {}; -func c_npc Npc_GetNewsVictim(var c_npc self, var int newsnumber) {}; -func c_npc Npc_GetNewsWitness(var c_npc self, var int newsnumber) {}; -func int Npc_GetNextTarget(var c_npc self) {}; -func string Npc_GetNextWP(var c_npc self) {}; -func int Npc_GetPermAttitude(var c_npc self, var c_npc other) {}; -func int Npc_GetPortalGuild(var instance n0) {}; -func instance Npc_GetPortalOwner(var instance n0) {}; -func c_item Npc_GetReadiedWeapon(var c_npc n0) {}; -func int Npc_GetStateTime(var c_npc self) {}; -func int Npc_GetTalentSkill(var instance n0, var int i1) {}; -func int Npc_GetTalentValue(var instance n0, var int i1) {}; -func int Npc_GetTarget(var c_npc self) {}; -func int Npc_GetTrueGuild(var c_npc npc) {}; -func int NPC_GiveInfo(var c_npc npc, var int important) {}; -func int Npc_GiveInfo(var instance n0, var int i1) {}; -func void Npc_GiveItem(var c_npc n0, var c_item n1, var c_npc n2) {}; -func int Npc_HasBodyFlag(var c_npc self, var int bodyflag) {}; -func int Npc_HasDetectedNpc(var c_npc self, var c_npc other) {}; -func int Npc_HasEquippedArmor(var c_npc self) {}; -func int Npc_HasEquippedMeleeWeapon(var c_npc self) {}; -func int Npc_HasEquippedRangedWeapon(var c_npc self) {}; -func int Npc_HasEquippedWeapon(var c_npc self) {}; -func int Npc_HasFightTalent(var c_npc self, var int tal) {}; -func int Npc_HasItems(var c_npc n0, var int iteminstance) {}; -func int Npc_HasNews(var c_npc self, var int newsid, var c_npc offender, var c_npc victim) {}; -func int Npc_HasOffered(var c_npc self, var c_npc other, var int iteminstance) {}; -func int Npc_HasRangedWeaponWithAmmo(var c_npc npc) {}; -func int Npc_HasReadiedMeleeWeapon(var c_npc self) {}; -func int Npc_HasReadiedRangedWeapon(var c_npc self) {}; -func int Npc_HasReadiedWeapon(var c_npc self) {}; -func int Npc_HasSpell(var c_npc self, var int spellid) {}; -func int Npc_HasTalent(var c_npc self, var int tal) {}; -func void Npc_ChangeAttribute(var c_npc self, var int atr, var int value) {}; -func int Npc_CheckAvailableMission(var c_npc npc, var int missionstate, var int important) {}; -func int Npc_CheckInfo(var c_npc npc, var int important) {}; -func int Npc_CheckOfferMission(var c_npc npc, var int important) {}; -func int Npc_CheckRunningMission(var c_npc npc, var int important) {}; -func int Npc_IsAiming(var c_npc self, var c_npc other) {}; -func int Npc_IsDead(var c_npc n0) {}; -func int Npc_IsDetectedMobOwnedByGuild(var c_npc user, var int ownerguild) {}; -func int Npc_IsDetectedMobOwnedByNpc(var c_npc user, var c_npc owner) {}; -func int Npc_IsDrawingSpell(var instance n0) {}; -func int Npc_IsDrawingWeapon(var instance n0) {}; -func int Npc_IsInCutscene(var c_npc self) {}; -func int Npc_IsInFightMode(var c_npc self, var int fmode) {}; -func int Npc_IsInPlayersRoom(var instance n0) {}; -func int Npc_IsInRoutine(var c_npc self, var func state) {}; -func int Npc_IsInState(var c_npc self, var func state) {}; -func int Npc_IsNear(var c_npc self, var c_npc other) {}; -func int Npc_IsNewsGossip(var c_npc self, var int newsnumber) {}; -func int Npc_IsNextTargetAvailable(var c_npc self) {}; -func int Npc_IsOnFP(var c_npc self, var string name) {}; -func int Npc_IsPlayerInMyRoom(var c_npc npc) {}; -func int Npc_IsPlayer(var c_npc player) {}; -func int Npc_IsVoiceActive(var instance n0) {}; -func int Npc_IsWayBlocked(var c_npc self) {}; -func int Npc_KnowsInfo(var c_npc self, var int infoinstance) {}; -func int Npc_KnowsPlayer(var c_npc self, var c_npc player) {}; -func void Npc_LearnSpell(var c_npc self, var int spellnr) {}; -func void Npc_MemoryEntryGuild(var c_npc self, var int source, var c_npc offender, var int newsid, var c_npc victimguild) {}; -func void Npc_MemoryEntry(var c_npc self, var int source, var c_npc offender, var int newsid, var c_npc victim) {}; -func int Npc_OwnedByGuild(var c_item item, var int guild) {}; -func int Npc_OwnedByNpc(var c_item item, var c_npc npc) {}; -func void Npc_PercDisable(var c_npc self, var int percid) {}; -func void Npc_PerceiveAll(var c_npc self) {}; -func void Npc_PercEnable(var c_npc self, var int percid, var func function) {}; -func void Npc_PlayAni(var instance n0, var string s1) {}; -func int Npc_RefuseTalk(var c_npc self) {}; -func void Npc_RemoveInvItems(var c_npc owner, var int iteminstance, var int amount) {}; -func void Npc_RemoveInvItem(var c_npc owner, var int iteminstance) {}; -func void Npc_SendPassivePerc(var c_npc npc1, var int perc_type, var c_npc npc2, var c_npc npc3) {}; -func void Npc_SendSinglePerc(var c_npc self, var c_npc target, var int percid) {}; -func int Npc_SetActiveSpellInfo(var c_npc npc, var int i1) {}; -func void Npc_SetAttitude(var c_npc self, var int att) {}; -func void Npc_SetKnowsPlayer(var c_npc self, var c_npc player) {}; -func void Npc_SetPercTime(var c_npc self, var float seconds) {}; -func void Npc_SetRefuseTalk(var c_npc self, var int timesec) {}; -func void Npc_SetStateTime(var c_npc self, var int seconds) {}; -func void Npc_SetTalentSkill(var instance n0, var int i1, var int i2) {}; -func void Npc_SetTalentValue(var instance n0, var int i1, var int i2) {}; -func void Npc_SetTarget(var c_npc self, var c_npc other) {}; -func void Npc_SetTeleportPos(var c_npc self) {}; -func void Npc_SetTempAttitude(var c_npc self, var int att) {}; -func void Npc_SetToFightMode(var c_npc self, var int weapon) {}; -func void Npc_SetToFistMode(var c_npc self) {}; -func int Npc_SetTrueGuild(var c_npc npc, var int guildid) {}; -func int Npc_StartItemReactModules(var c_npc self, var c_npc other, var c_item item) {}; -func void Npc_StopAni(var instance n0, var string s1) {}; -func int Npc_WasInState(var c_npc self, var func state) {}; -func int Npc_WasPlayerInMyRoom(var c_npc npc) {}; -func void Perc_SetRange(var int percid, var int range) {}; -func int PlayVideoEx(var string filename, var int screenblend, var int exitsession) {}; -func int PlayVideo(var string filename) {}; -func void PrintDebugCh(var int ch, var string text) {}; -func void PrintDebugInstCh(var int ch, var string text) {}; -func void PrintDebugInst(var string text) {}; -func void PrintDebug(var string s) {}; -func int PrintDialog(var int i0, var string s1, var int i2, var int i3, var string s4, var int i5) {}; -func void PrintMulti(var string s0, var string s1, var string s2, var string s3, var string s4) {}; -func void PrintScreen(var string msg, var int posx, var int posy, var string font, var int timesec) {}; -func void Print(var string s0) {}; -func void Rtn_Exchange(var string oldroutine, var string newroutine) {}; -func void SetPercentDone(var int percentdone) {}; -func int Snd_GetDistToSource(var c_npc self) {}; -func int Snd_IsSourceItem(var c_npc self) {}; -func int Snd_IsSourceNpc(var c_npc self) {}; -func void Snd_Play(var string s0) {}; -func void Snd_Play3D(var c_npc n0, var string s1) {}; -func void TA_BeginOverlay(var c_npc self) {}; -func void TA_CS(var c_npc self, var string csname, var string rolename) {}; -func void TA_EndOverlay(var c_npc self) {}; -func void Tal_Configure(var int i0, var int i1) {}; -func void TA_Min(var c_npc self, var int start_h, var int start_m, var int stop_h, var int stop_m, var func state, var string waypoint) {}; -func void TA_RemoveOverlay(var c_npc self) {}; -func void TA(var c_npc self, var int start_h, var int stop_h, var func state, var string waypoint) {}; -func void Update_ChoiceBox(var string s0) {}; -func void Wld_AssignRoomToGuild(var string s0, var int guild) {}; -func void Wld_AssignRoomToNpc(var string s0, var c_npc roomowner) {}; -func int Wld_DetectItem(var c_npc self, var int flags) {}; -func int Wld_DetectNpcExAtt(var instance n0, var int i1, var func f2, var int i3, var int i4, var int i5) {}; -func int Wld_DetectNpcEx(var instance n0, var int i1, var func f2, var int i3, var int i4) {}; -func int Wld_DetectNpc(var c_npc self, var int instance, var func aistate, var int guild) {}; -func int Wld_DetectPlayer(var c_npc self) {}; -func void Wld_ExchangeGuildAttitudes(var string name) {}; -func int Wld_GetDay() {}; -func int Wld_GetFormerPlayerPortalGuild() {}; -func c_npc Wld_GetFormerPlayerPortalOwner() {}; -func int Wld_GetGuildAttitude(var int guild1, var int guild2) {}; -func int Wld_GetMobState(var c_npc self, var string schemename) {}; -func int Wld_GetPlayerPortalGuild() {}; -func c_npc Wld_GetPlayerPortalOwner() {}; -func void Wld_InsertItem(var int iteminstance, var string spawnpoint) {}; -func void Wld_InsertNpcAndRespawn(var int instance, var string spawnpoint, var float spawndelay) {}; -func void Wld_InsertNpc(var int npcinstance, var string spawnpoint) {}; -func void Wld_InsertObject(var string s0, var string s1) {}; -func int Wld_IsFPAvailable(var c_npc self, var string fpname) {}; -func int Wld_IsFpAvailable(var instance n0, var string s1) {}; -func int Wld_IsMobAvailable(var c_npc self, var string schemename) {}; -func int Wld_IsNextFPAvailable(var c_npc self, var string fpname) {}; -func int Wld_IsNextFpAvailable(var instance n0, var string s1) {}; -func int Wld_IsRaining() {}; -func int Wld_IsTime(var int hour1, var int min1, var int hour2, var int min2) {}; -func void Wld_PlayEffect(var string effectinstance, var int originvob, var int targetvob, var int effectlevel, var int damage, var int damagetype, var int bisprojectile) {}; -func int Wld_RemoveItem(var c_item item) {}; -func void Wld_RemoveNpc(var int i0) {}; -func void Wld_SendTrigger(var string vobname) {}; -func void Wld_SendUntrigger(var string vobname) {}; -func void Wld_SetGuildAttitude(var int guild1, var int attitude, var int guild2) {}; -func void Wld_SetMobRoutine(var int hour1, var int min1, var string objname, var int state) {}; -func void Wld_SetObjectRoutine(var int hour1, var int min1, var string objname, var int state) {}; -func void Wld_SetTime(var int hour, var int min) {}; -func void Wld_SpawnNpcRange(var instance n0, var int i1, var int i2, var float r3) {}; diff --git a/zengin/scripts/externals/index.html b/zengin/scripts/externals/index.html deleted file mode 100644 index cb56d7b2a5..0000000000 --- a/zengin/scripts/externals/index.html +++ /dev/null @@ -1,34 +0,0 @@ - Externals - Gothic Modding Community

Externals

External functions are Daedalus functions (defined in the engine itself), that are used to interface with the engine. Gothic 1 and Gothic 2 implements slightly different set of external functions.
There are some external functions, that were used in the course of Gothic's development, but are now obsolete/deprecated because the underlying systems implemented in the engine were either turned off, or broken all together.

\ No newline at end of file diff --git a/zengin/scripts/externals/log/index.html b/zengin/scripts/externals/log/index.html deleted file mode 100644 index 5c6d7adc64..0000000000 --- a/zengin/scripts/externals/log/index.html +++ /dev/null @@ -1,87 +0,0 @@ - Log functions - Gothic Modding Community

Log external functions

Log externals are used to manipulate players log and to track quest progress.

Log_CreateTopic

Creates a new log topic with the name topicName under the section logSection

func void Log_CreateTopic(var string topicName, var int logSection) {};
-
Parameters
  • var string topicName
    Unique string used to identify and name the topic
  • var int logSection
    Indicates in which section to create the topic in.
    Takes constants LOG_MISSION, LOG_NOTE as values

Log_AddEntry

Adds an entry to a log topic with the name topicName under the section logSection

func void Log_AddEntry(var string topicName, var string entry) {};
-
Parameters
  • var string topicName
    Unique string used to identify and name the topic
  • var string entry
    Content of the new entry

Info

In the engine the Log_AddEntry() is wrapped in a B_LogEntry() function. This function also handles printing the "New Journal Entry" message to the screen and playing the sound effect.

1
-2
-3
-4
-5
-6
-7
-8
-9
func void B_LogEntry(var string topic, var string entry)
-{
-    PrintDebugNpc(PD_ZS_DETAIL, "B_LogEntry"); // Logging
-
-    Log_AddEntry(topic, entry);
-
-    PrintScreen(NAME_NewLogEntry, -1, _YPOS_MESSAGE_LOGENTRY, "font_old_10_white.tga", _TIME_MESSAGE_LOGENTRY);
-    Snd_Play("LogEntry");
-};
-

Log_SetTopicStatus

Changes the status of the topic with the name topicName

func void Log_SetTopicStatus(var string topicName, var int status) {};
-
Parameters
  • var string topicName
    Unique string used to identify and name the topic
  • var int status
    The status to be set.
    Takes constants LOG_RUNNING, LOG_SUCCESS, LOG_FAILED, LOG_OBSOLETE as values

zParserExtender

The log external function selection is missing functions to retrieve the status of a log entry. There are only functions to read the log status (as discussed on Inside Gothic). As a result of this the original scriptwriters had to define additional variable to track the log status in the scripts, even though the value is being already tracked by the engine. zParserExtender fixes this by introducing new log external functions.

Externals with docu comments

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
/// Creates a new log topic with the name `topicName` under the section `logSection`
-/// 
-/// @param topicName unique string used to identify and name the topic
-/// @param logSection [LOG_MISSION, LOG_NOTE] indicates in which section to create the topic in
-func void Log_CreateTopic(var string topicName, var int logSection) {};
-
-/// Creates a new log topic with the name `topicName` under the section `logSection`
-/// 
-/// @param topicName unique string used to identify and name the topic
-/// @param logSection [LOG_MISSION, LOG_NOTE] indicates in which section to create the topic in
-func void Log_AddEntry(var string topicName, var string entry) {};
-
-/// Changes the status of the topic with the name `topicName`
-///
-/// @param topicName unique string used to identify and name the topic
-/// @param status [LOG_RUNNING, LOG_SUCCESS, LOG_FAILED, LOG_OBSOLETE] the status to be set
-func void Log_SetTopicStatus(var string topicName, var int status) {};
-
\ No newline at end of file diff --git a/zengin/scripts/externals/mdl/index.html b/zengin/scripts/externals/mdl/index.html deleted file mode 100644 index c017cf1f9c..0000000000 --- a/zengin/scripts/externals/mdl/index.html +++ /dev/null @@ -1,281 +0,0 @@ - MDL functions - Gothic Modding Community

MDL functions

Functions to tweak animation and other model related settings.

Mdl_ApplyOverlayMDS

Apply an animation overlay with overlay_name for the specified npc

func void Mdl_ApplyOverlayMDS(var c_npc npc, var string overlay_name) {};
-

Parameters

  • var c_npc npc
    NPC to apply the overlay to
  • var string overlay_name
    Name of the animation overlay

Mdl_ApplyOverlayMDSTimed

Apply an animation overlay with overlay_name for the specified npc for duration milliseconds

func void Mdl_ApplyOverlayMDSTimed(var c_npc npc, var string overlay_name, var float duration) {};
-

Parameters

  • var c_npc npc
    NPC to apply the overlay to
  • var string overlay_name
    Name of the animation overlay
  • var float duration
    Overlay duration in milliseconds

Mdl_RemoveOverlayMDS

Remove the animation overlay overlay_name from specified npc

func void Mdl_RemoveOverlayMDS(var c_npc npc, var string overlay_name) {};
-

Parameters

  • var c_npc npc
    NPC to remove the overlay from
  • var string overlay_name
    Name of the animation overlay

Mdl_ApplyRandomAni

Assign a random animation ani2 to random animation list of animation ani1

func void Mdl_ApplyRandomAni(var c_npc npc, var string ani1, var string ani2) {};
-

Parameters

  • var c_npc npc
    NPC owning the animation
  • var string ani1
    The animation to assign random animation to
  • var string ani2
    Animation to be assigned

Mdl_ApplyRandomAniFreq

Sets the random animation frequency for animation ani1

func void Mdl_ApplyRandomAniFreq(var c_npc npc, var string ani1, var float frequency) {};
-

Parameters

  • var c_npc npc
    NPC owning the animation
  • var string ani1
    The animation to set the random frequency
  • var float frequency
    Number of seconds between random animations
Example
1
-2
-3
-4
// Attach T_WOUNDED_TRY animation to the S_WOUNDED animation
-Mdl_ApplyRandomAni(self, "S_WOUNDED", "T_WOUNDED_TRY");
-// Make the random animation attached play every 8 seconds
-Mdl_ApplyRandomAniFreq(self, "S_WOUNDED", 8);
-

Mdl_SetModelFatness

Set the procedural model fatness

func void Mdl_SetModelFatness(var c_npc npc, var float fatness) {};
-

Parameters

  • var c_npc npc
    NPC to apply the fatness to
  • var float fatness
    Fatness value

Mdl_SetModelScale

Set model scale per axis

func void Mdl_SetModelScale(var c_npc npc, var float x, var float y, var float z) {};
-

Parameters

  • var c_npc npc
    NPC to apply the scale to
  • var float x
    Scale along the x-axis, 1.0 = 100%, 1.5 = 150%, 0.9 = 90%
  • var float y
    Scale along the y-axis, 1.0 = 100%, 1.5 = 150%, 0.9 = 90%
  • var float z
    Scale along the z-axis, 1.0 = 100%, 1.5 = 150%, 0.9 = 90%

Mdl_SetVisualBody

Sets up the visual of an NPC

1
-2
-3
-4
-5
-6
-7
-8
func void Mdl_SetVisualBody(var instance npc,
-                            var string body_mesh,
-                            var int body_tex,
-                            var int skin,
-                            var string head_mesh,
-                            var int head_tex,
-                            var int teeth_tex,
-                            var int armor_inst       ) {};
-

Parameters

  • var instance npc
    NPC to be affected
  • var string body_mesh
    Mesh to be used as the body e.g. HUN_BODY_NAKED0
  • var int body_tex
    Body texture assigned to this body mesh
  • var int skin
    Body texture variant
  • var string head_mesh
    Head mesh
  • var int head_tex
    Head texture
  • var int teeth_tex
    Teeth texture
  • var int armor_inst
    Armor (C_ITEM instance) to be equipped or -1 for no armor

Mdl_SetVisual

Set the animation set (also dictates models you can set using the Mdl_SetVisualBody)

func void Mdl_SetVisual(var instance npc, var string animation_set) {};
-

Parameters

  • var instance npc
    NPC to apply the animation set to
  • var string animation_set
    Name of the MDS file that contains the animation set

Mdl_StartFaceAni

Start a face animation

1
-2
-3
-4
func void Mdl_StartFaceAni(var c_npc npc,
-                           var string name,
-                           var float intensity,
-                           var float holdtime) {};
-

Parameters

  • var c_npc npc
    NPC to apply the animation to
  • var string name
    Animation name
  • var float intensity
    Intensity of the animation 0.0 to 1.0
  • var float holdtime
    How long should the animation be held for -2 will use the MMS defined value, '-1' will make the hold time infinite

Mdl_ApplyRandomFaceAni

Start a random face animation

1
-2
-3
-4
-5
-6
-7
func void Mdl_ApplyRandomFaceAni(var c_npc npc,
-                                 var string name,
-                                 var float timemin,
-                                 var float timeminvar,
-                                 var float timemax,
-                                 var float timemaxvar,
-                                 var float probmin) {};
-

Parameters

  • var c_npc npc
    NPC to apply the animation to
  • var string name
    Animation name
  • var float timemin
    Minimum time after which the ani should be started (in seconds)
  • var float timeminvar
    Minimum boundary variation (in seconds)
  • var float timemax
    Maximum time after which the ani should be started (in seconds)
  • var float timemaxvar
    Maximum boundary variation (in seconds)
  • var float probmin
    Probability (0.0 to 1.0) to choose the lower boundary time

Externals with docu comments

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
-37
-38
-39
-40
-41
-42
-43
-44
-45
-46
-47
-48
-49
-50
-51
-52
-53
-54
-55
-56
-57
-58
-59
-60
-61
-62
-63
-64
-65
-66
-67
-68
-69
-70
-71
-72
-73
-74
-75
-76
-77
-78
-79
-80
-81
-82
-83
-84
-85
-86
-87
-88
-89
-90
-91
-92
-93
-94
-95
-96
-97
-98
-99
/// Apply an animation overlay with `overlay_name` for the specified `npc`
-/// 
-/// @param npc NPC to apply the overlay to
-/// @param overlay_name name of the animation overlay
-func void Mdl_ApplyOverlayMDS(var c_npc npc, var string overlay_name) {};
-
-/// Apply an animation overlay with `overlay_name` for the specified `npc` for `duration` milliseconds
-///
-/// @param npc NPC to apply the overlay to
-/// @param overlay_name name of the animation overlay
-/// @param duration overlay duration in milliseconds
-func void Mdl_ApplyOverlayMDSTimed(var c_npc npc, var string overlay_name, var float duration) {};
-
-/// Remove the animation overlay `overlay_name` from specified `npc` 
-/// 
-/// @param npc NPC to remove the overlay from
-/// @param overlay_name name of the animation overlay
-func void Mdl_RemoveOverlayMDS(var c_npc npc, var string overlay_name) {};
-
-/// Assign a random animation `ani2` to random animation list of animation `ani1`
-///
-/// @param npc NPC owning the animation
-/// @param ani1 the animation to assign random animation to
-/// @param ani2 animation to be assigned
-func void Mdl_ApplyRandomAni(var c_npc npc, var string ani1, var string ani2) {};
-
-/// Sets the random animation frequency for animation `ani1`
-///
-/// @param npc NPC owning the animation
-/// @param ani1 the animation to set the random frequency
-/// @param frequency number of seconds between random animations
-func void Mdl_ApplyRandomAniFreq(var c_npc npc, var string ani1, var float frequency) {};
-
-/// Set the procedural model fatness
-///
-/// @param npc NPC to apply the fatness to 
-/// @param fatness fatness value
-func void Mdl_SetModelFatness(var c_npc npc, var float fatness) {};
-
-/// Set model scale per axis
-///
-/// @param npc NPC to apply the scale to 
-/// @param x scale along the x axis, 1.0 = 100%, 1.5 = 150%, 0.9 = 90% 
-/// @param y scale along the y axis, 1.0 = 100%, 1.5 = 150%, 0.9 = 90% 
-/// @param z scale along the z axis, 1.0 = 100%, 1.5 = 150%, 0.9 = 90% 
-func void Mdl_SetModelScale(var c_npc npc, var float x, var float y, var float z) {};
-
-/// Sets up the visual of an NPC
-///
-/// @param npc NPC to be affected
-/// @param body_mesh mesh to be used as the body e.g. `HUN_BODY_NAKED0`
-/// @param body_tex body texture assigned to this body mesh
-/// @param skin body texture variant
-/// @param head_mesh head mesh
-/// @param head_tex head texture
-/// @param teeth_tex teeth texture
-/// @param armor_inst armor (C_ITEM instance) to be equipped or `-1` for no armor 
-func void Mdl_SetVisualBody(var instance npc,
-                            var string body_mesh,
-                            var int body_tex,
-                            var int skin,
-                            var string head_mesh,
-                            var int head_tex,
-                            var int teeth_tex,
-                            var int armor_inst       ) {};
-
-/// Set the animation set (also dictates models you can set using the `Mdl_SetVisualBody`)
-///
-/// @param npc NPC to apply the animation set to 
-/// @param animation_set name of the MDS file that contains the animation set
-func void Mdl_SetVisual(var instance npc, var string animation_set) {};
-
-/// Start a face animation
-///
-/// @param npc NPC to apply the animation to 
-/// @param name animation name
-/// @param intensity intensity of the animation 0.0 to 1.0
-/// @param holdtime how long should the animation be held for `-2` will use the MMS defined value, '-1' will make the hold time infinite
-func void Mdl_StartFaceAni(var c_npc npc,
-                           var string name,
-                           var float intensity,
-                           var float holdtime) {};
-
-/// Start a random face animation
-///
-/// @param npc NPC to apply the animation to 
-/// @param name animation name
-/// @param timemin minimum time after which the ani should be started (in seconds)
-/// @param timeminvar minimum boundary variation (in seconds)
-/// @param timemax maximum time after which the ani should be started (in seconds)
-/// @param timemaxvar maximum boundary variation (in seconds)
-/// @param probmin probability (0.0 to 1.0) to choose the lower boundary time
-func void Mdl_ApplyRandomFaceAni(var c_npc npc,
-                                 var string name,
-                                 var float timemin,
-                                 var float timeminvar,
-                                 var float timemax,
-                                 var float timemaxvar,
-                                 var float probmin) {};
-
\ No newline at end of file diff --git a/zengin/scripts/index.html b/zengin/scripts/index.html deleted file mode 100644 index 632d3dd569..0000000000 --- a/zengin/scripts/index.html +++ /dev/null @@ -1,34 +0,0 @@ - Scripts - Gothic Modding Community

Scripts

ZenGin uses its own scripting language called Daedalus. It is similar to C programming language, so if you know some C programming, it will be quite easy to get started.

The Scripts directory is where the scripts live. You will be able to find Daedalus script files - .d extension and .src files, that list all files to be compiled.

Daedalus scripts can be edited in any text editor. To get useful features like syntax highlighting you can use community developed tools like

\ No newline at end of file diff --git a/zengin/sound/index.html b/zengin/sound/index.html deleted file mode 100644 index b9fdb26e6b..0000000000 --- a/zengin/sound/index.html +++ /dev/null @@ -1,35 +0,0 @@ - Sound - Gothic Modding Community

Sound

ZenGin uses .wav files for playing Sound Effects and Dubbing.

Info

In-game soundtrack isn't saved in .wav sound files. See Music.

Properties

Original gothic sound files has following properties:

SFX

Sound effects (SFX) are sounds made by monsters, spells, weapons etc. Sound effects are defined in multiple places, in .mds files as part of the animation EventBlocks, or in the SFX Daedalus scripts. Sounds are located in the _work/Data/Sound/SFX directory.

Speech

Dubbing for dialogues is located into _work/Data/Sound/Speech folder. Every single AI_Output has its own sound file with name defined in the function itself.

For this dialogue line

AI_Output(self,hero,"Info_Diego_Gamestart_11_00"); //I'm Diego.
-
the engine will play Info_Diego_Gamestart_11_00.wav sound file (if it exists).
\ No newline at end of file diff --git a/zengin/sound/tutorials/change_sfx/index.html b/zengin/sound/tutorials/change_sfx/index.html deleted file mode 100644 index 5c804b693f..0000000000 --- a/zengin/sound/tutorials/change_sfx/index.html +++ /dev/null @@ -1,34 +0,0 @@ - Changing Sound Effect - Gothic Modding Community

Changing Sound Effect

This is Gothic VDFS. It is a tool that allows you to pack and unpack files in .VDF and .MOD format.

Screenshot_1

Let us start with unpacking "Sound" file:

  1. In the "(Viewer)" tab, in the "Filename", go to your Gothic or Gothic II/Data folder and choose "Sound.VDF".
  2. Create a folder on your desktop or any other easily accessible place on your computer. Name it however you want.
  3. Go to "Root path" and choose the folder you just created.
  4. Press "Extract volume" if you want to unpack all sound files.

The chosen file should be unpacking right now.
image

Here are the files we just extracted:
image

It can oftentimes be tricky to find the sound you are looking for, but we will leave that for later. Let's just see how can we change a sound file in the game now.

  1. Get yourself any short sound file.
  2. In order for the sound to work in the game, it needs to be in mono .wav format. A lot of programs let you convert a file such as Audacity, so do just that;
  3. Rename your converted file into "INV_CHANGE.WAV" and replace it in SFX folder you just extracted;
  4. Go back to Gothic VDFS, go to (Builder) tab;
  5. In "Filename" you choose how do you want your file to be called and its location. I recommend creating separate folder and putting it there. You can also name the file however you want, as long as it has higher time stamp (more on that later) than original Sounds file. To create it as .VDF file, choose "All file" in the "Save file as" and call it "Sounds.VDF";
  6. In "Root path" go to and choose "_WORK" folder;
  7. In the field just below "Comment", add a * character and then click on the + next to it;
  8. Press "Build", and if you did everything right, the folder is being packed back into .VDF file;

That's how a successful process looks like:
image

Now get the file you just created, and put it in your Gothic/Data folder replacing the old one. The file we just replaced changes the sound in main menu and the inventory. If you can hear it, congratulations, you did it!

\ No newline at end of file diff --git a/zengin/textures/index.html b/zengin/textures/index.html deleted file mode 100644 index fd5ccc744b..0000000000 --- a/zengin/textures/index.html +++ /dev/null @@ -1,34 +0,0 @@ - Textures - Gothic Modding Community

Textures

Textures are pictures that get projected onto a 3D models and on a 2D user interface in the game. We will discuss how to work with textures in this section.

\ No newline at end of file diff --git a/zengin/tools/daedalus_tools/daedalus_language_server/index.html b/zengin/tools/daedalus_tools/daedalus_language_server/index.html deleted file mode 100644 index 1a6c0b8140..0000000000 --- a/zengin/tools/daedalus_tools/daedalus_language_server/index.html +++ /dev/null @@ -1,34 +0,0 @@ - Daedalus Language Server - Gothic Modding Community
\ No newline at end of file diff --git a/zengin/tools/dls/index.html b/zengin/tools/dls/index.html deleted file mode 100644 index f1ea3a7574..0000000000 --- a/zengin/tools/dls/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/zengin/tools/gothic_sourcer/index.html b/zengin/tools/gothic_sourcer/index.html deleted file mode 100644 index bab40ae75e..0000000000 --- a/zengin/tools/gothic_sourcer/index.html +++ /dev/null @@ -1,34 +0,0 @@ - Gothic Sourcer - Gothic Modding Community

Gothic Sourcer

Gothic Sourcer can be used to do a lot of things.

Todo

TODO

\ No newline at end of file diff --git a/zengin/tools/gothic_vdfs/index.html b/zengin/tools/gothic_vdfs/index.html deleted file mode 100644 index 9bbd7ec638..0000000000 --- a/zengin/tools/gothic_vdfs/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/zengin/tools/index.html b/zengin/tools/index.html deleted file mode 100644 index f0b8e06f34..0000000000 --- a/zengin/tools/index.html +++ /dev/null @@ -1,34 +0,0 @@ - Tools - Gothic Modding Community

Tools

The community has developed many tools to help with the creation of Gothic mods.

Note

This list is a work in progress.

Daedalus

  • Daedalus Language Server - a VS Code/VS Codium extension that adds IDE like functionality for Daedalus scripting language
  • Ikarus - A daedalus library for the game Gothic. Exploits the interpreter to allow arbitrary memory access and defines a lot of useful functions for interfacing with the engine.
  • LeGo - A daedalus library for the game Gothic. It contains various packages to support modders.
  • AFSP - Fawkes' & Auronen's script package for Gothic 1 and Gothic 2: Night of the Raven.
  • Ninja - Ninja introduces the possibility of true modular modifications for the video games Gothic and Gothic 2 Night of the Raven.

VDFS tools

  • GothicVDFS - NicoDE's viewer, extractor and builder for .vdf and .mod volumes
  • VDFS Tool - Gratt's Union VDFS viewer, extractor, builder, optimizer and ZIP compressor for .vdf and .mod volumes

World Editors

  • Spacer - the original world editor for ZenGin, ships with the MDK
  • Union Gothic World Editor - Saturas' world editor, supports new object classes created with Union
  • Gothic World Editor - World editor for vanilla worlds, works with G1, G2 and G2 NotR worlds
  • Spacer.NET - A modernised version of Spacer available as a Gothic Mod.
\ No newline at end of file diff --git a/zengin/tools/vdfs_tool/index.html b/zengin/tools/vdfs_tool/index.html deleted file mode 100644 index ff3e73cc59..0000000000 --- a/zengin/tools/vdfs_tool/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/zengin/tools/vdfs_tools/gothic_vdfs/index.html b/zengin/tools/vdfs_tools/gothic_vdfs/index.html deleted file mode 100644 index 991b6a59b4..0000000000 --- a/zengin/tools/vdfs_tools/gothic_vdfs/index.html +++ /dev/null @@ -1,34 +0,0 @@ - GothicVDFS - Gothic Modding Community

GothicVDFS

Gothic VDFS is still the most popular VDFS tool. It was created by NicoDE.

Download

You can download the tool from NicoDE's website - direct link.

Quick overview

\ No newline at end of file diff --git a/zengin/tools/vdfs_tools/vdfs_tool/index.html b/zengin/tools/vdfs_tools/vdfs_tool/index.html deleted file mode 100644 index 17620a0c8e..0000000000 --- a/zengin/tools/vdfs_tools/vdfs_tool/index.html +++ /dev/null @@ -1,34 +0,0 @@ - VDFS Tool - Gothic Modding Community

VDFS Tool

VDFS Tool is a new program that supports new features introduced to VDFS by the Union team. Like ZIP compression or drag and drop support.

Download

You can download the tool from the post on WoP.ru - VDFS Tool or using the Resource Manager

Quick overview

\ No newline at end of file diff --git a/zengin/tools/zSpy/index.html b/zengin/tools/zSpy/index.html deleted file mode 100644 index f9d4b83b5b..0000000000 --- a/zengin/tools/zSpy/index.html +++ /dev/null @@ -1,49 +0,0 @@ - zSpy - Gothic Modding Community

zSpy

zSpy is a debugging tool that displays most of the operations performed by the engine during the Gothic or Spacer running.

Example image of running zSpy

zSpy

Warning

zSpy must be started before Gothic or the Spacer is started so that the program can find it. Sometimes in Gothic I this has to be done manually, in Gothic II This is done by the GothicStarter_mod.

In order to be able to follow the messages in zSpy, Gothic should be started in the window. The corresponding startup option can be found in GothicStarter (mod). Within Gothic, when Marvin mode is activated, you can switch between window and full-screen mode at any time with the F3 key.

Log Level

With the -zlog# command in GothicStarter, you can specify how many messages zSpy will output. # can be a number between -1 and 9. Used for:

  • -1 - Disable every message (expect fatal errors)

  • 0 - Shows only warnings, faults and fatal errors

  • 1 - 9 - Display more information. Every Information has their priority. If you select 1, the program displays only messages with priority =< 1, with 5 only priority =< 5, and with 9, almost everything that Gothic can produce.

For general debugging, recommended value is 5.

Output

The zSpy issues its reports in the following form:

1
-2
Time  Type  Priority  User   Message              ...      <filename,       #line>
-00:21 Info:  3        B:     GOTHIC: Exiting game ... .... <oGameManager.cpp,#617>
-

Time

Time elapsed since the start of Gothic.exe

Type

Type of message. The following message types are distinguished:

  • Fatal: - Critical error causing application to close.

  • Fault: - A simple bug that will not cause the application to stop, but display or performance issues may occur.

  • Warn: - A warning of possible consequences. An error that follows soon afterwards could have something to do with it.

  • Info: - General information about the progress of the program.

Priority

Priority level of the message. Messages with lower priority (higher number) can be disabled. See log level.

User

User ID - a letter defined by every engine developer to highlight its logs

  • D - Dieter
  • U - Ulf
  • B - Bert
  • C - Carsten
  • A - Andre
  • X - Kurt

Message

The most important part. A message that contains:

  • Symbol representing a program module. The names are mostly self-explanatory, so there is no need to type them all (MDL = 3D models, PAR = Parser etc.).

  • The message for the user.

Configuration

In zSpy, you can customize the font and its color depending on the type of message.

In addition, you can configure the logging options:

  • Filtering various messages (Info, Warn, Fault, Fatal).
  • Auto show/hide zSpy when starting/stopping Gothic.
  • Saving the log file to a separate file.

Console commands

List of console commands related with zSpy.

Note

The list is work in progress. Console commands needs a separate article or section.

zerr level

Sets a level of logging.

zerr level <#>
-

zerr searchspy

Links zSpy with Gothic. Useful when you run zSpy when the game is already running.

zerr searchspy
-

zerr authors

Sets a filter to display only messages of one author.

zerr authors <letter>
-
  • <letter> - One of the letters listed here.

zerr rem

Includes a remark into the log.

zerr rem
-
Looks like that:
1
-2
-3
-4
00:46 Info:  3 B:       OPT: Blood-Details: Value=2 .... <oGameManager.cpp,#1302>
-00:57 ---------------
-00:57 ---------------
-01:01 Info:  3 B:     GMAN: Leaving Menu-Section .... <oGameManager.cpp,#1537>
-

zerr status

Displays a current status of zSpy in the console.

zerr status
-
\ No newline at end of file diff --git a/zengin/union/index.html b/zengin/union/index.html deleted file mode 100644 index 149f3f7f3b..0000000000 --- a/zengin/union/index.html +++ /dev/null @@ -1,34 +0,0 @@ - Union - Gothic Modding Community

Union

Union is a system to patch and extend Gothic's engine the ZenGin. It allows you to load .dll files - ZenGin extensions created using the Gothic/Union SDK and .patch files - files designed to patch the game's executable. The Union installer also contains the SystemPack a collection of bug fixes and engine edits that improve performance.

Plug-ins

Union plugins are shipped in the form of a .dll library. This library contains the compiled C++ code with the Union SDK and an embedded .patch file.

Union SDK & Gothic API

Union software development kit is a collection of tools and the Gothic API that allow you to create Union plugins and alter the engine's behavior.
Gothic API is a set of 4 interfaces (each for one different ZenGin version) that allow you to interface with the engine, access the engine objects, change their behavior and introduce new classes and functionality.

PATCH file format

The .patch file contains one or more small programs that are designed to change the engine code (game executable). This is usually done to fix bugs. Union plug-ins contain an embedded .patch file and this file usually contains changes to the binary necessary for the proper function of the plug-in.

\ No newline at end of file diff --git a/zengin/union/plugins/zbassmusic/index.html b/zengin/union/plugins/zbassmusic/index.html deleted file mode 100644 index 475f0fb003..0000000000 --- a/zengin/union/plugins/zbassmusic/index.html +++ /dev/null @@ -1,34 +0,0 @@ - zBassMusic - Gothic Modding Community

zBassMusic

zBassMusic is a modern music system for Gothic I and Gothic II NotR based on BASS Audio Library made by Silver Ore Team. It replaces the old DirectMusic system to let the modders create music for Gothic as regular audio files instead of DirectMusic format.

Info

For the plugin documentation, visit the github site of a project. The documentation is build into the code.

Contacts
Authors Silver Ore Team - tehe
GitHub zBassMusic
Discord Gothic Modding Community server

Features

  • Music playback with modern audio formats like WAV, MP3, OGG
  • Out-of-the-box support for existing C_MUSICTHEME instances
  • Scriptable interface to take full control of music scheduling
  • Loading music files from VDFS volumes (excluding .sgt)
  • Backwards compatibility with DirectMusic .sgt files
\ No newline at end of file diff --git a/zengin/union/plugins/zgamepad/controls/index.html b/zengin/union/plugins/zgamepad/controls/index.html deleted file mode 100644 index 819690d077..0000000000 --- a/zengin/union/plugins/zgamepad/controls/index.html +++ /dev/null @@ -1,140 +0,0 @@ - Controls customization - Gothic Modding Community

Gamepad controls

The zGamePad plugin comes with a default control scheme, but it is possible to create your own. The plugin will search for any file with the .gamepad.overlay extension placed in Gothic/System directory or in any of the loaded .mod and .vdf archives.

Control file syntax

Gamepad controls are set using the .gamepad configuration file. This file encodes the controls for different actions in the game and the hint string in multiple languages.

Warning

The .gamepad file must be encoded in Unicode or UTF-8 to accommodate the multilingual hint strings.

Regions

The format supports code blocks specified by the #region and #endregion keywords. These regions do not have any syntactical meaning, they only offer a convenient way to collapse sections of the code in editors with the syntax highlighting capabilities such as Notepad++

Regions
1
-2
-3
-4
-5
-6
-7
#region strings
-    // TODO
-#endregion
-
-#region fight scheme
-    // TODO
-#endregion
-

Comments

Comments are useful for quick information or just to disable some old code that might come in handy later. The .gamepad file syntax supports C++ line comments using two forward slashes //.

Warning

Comments can only be used at the start of any given line!

Comments
1
-2
// this is a comment
-KeyRecord // this is NOT a comment
-

Strings

Strings are used for interactive hints. They should be defined at the top of the file. To define a string, use the keyword String. Strings have the following format:

Multilang string syntax
1
-2
-3
-4
String [id]
-    [langTag] [text]
-    [langTag] [text]
-    [langTag] [text]
-

Example

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
String interact
-    Rus "Взаимодействовать"
-    Eng "Interact"
-    Pol "Interakcja"
-    Deu "Interagieren"
-
-String remove_weapon
-    Rus "Убрать оружие"
-    Eng "Remove weapon"
-    Pol "Chowanie broni"
-    Deu "Waffe entfernen"
-
The string name must be unique and is used to reference the string while defining hints. The language tag matches the language in SystemPack.ini. If the file does not contain the user's language, English will be taken by default. If there is no English, then the first one.

Control bindings

A binding is a description of an event that includes emulation object and conditions. Hints are part of the binding.
The general structure of the bind starts with the keyword KeyRecord and has the following format:

Control binding
1
-2
-3
-4
-5
-6
KeyRecord [modifier]
-    Id          [key name]
-    Combination [gamepad keys]
-    Emulation   [engine logical and absolute keys]
-    Condition   [engine logical, absolute keys or logical functions]
-    Help        [name of the hint string]
-
  • Id - unique identifier used by other users to override this control binding
  • [modifier] - can be empty or take the value of Toggled If the value is empty, the control binding will work as long as the player holds down the specified button or button combination.
    If the value is Toggled, the control binding will work only when the player toggles the button or button combination. (One press to start sneaking, another press to stop sneaking)
  • Combination - these are the gamepad buttons that the player must press or hold to activate the control binding.
  • Emulation - specify which buttons will be emulated. You can specify absolute buttons, or that are defined in the game settings (logical).
  • Condition - specify the condition under which the control binding can be activated. To invert condition, use the operator ! before the operand (!Cond_IsOverlayTop, !JOY_B)
  • Help - name of the text string with a hint which will be displayed when the Conditions are met.

  • [gamepad keys] - Gamepad key list

  • [engine logical keys] - Engine logical key list
  • [engine absolute keys] - Engine absolute key list
  • [logical functions] - Logical function list

Tip

All operators are optional! This means that if a binding should only show a hint, it doesn't have to contain Combination.

Example

Control binding examples
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
KeyRecord
-    Id          StopUsingPicklock
-    Combination JOY_B
-    Emulation   KEY_DOWN
-    Condition   Cond_InterfaceIsOpen, Cond_UsesPicklock, !JOY_B
-
-KeyRecord Toggled
-    Id          ReturnToHumanForm
-    Combination JOY_A
-    Emulation   KEY_RETURN
-    Condition   Cond_InTransformation
-    Help        end_transform
-
-KeyRecord
-    Id          QuickRingSelectSlot
-    Combination JOY_RSTICK_FULL
-    Condition   !Cond_InventoryIsOpen, Cond_IsOverlayTop
-    Help        focus_item
-

Controls override

If you want to change or remove bindings from another controls file, use the KeyDisable keyword.
Default controls file

Controls override syntax
KeyDisable [fileName].[Id]
-
Where fileName is the name of the controls file without extension and id is a key of the binding.

Example

Controls override example
1
-2
-3
-4
-5
-6
-7
-8
// remove key from the main controls file
-KeyDisable Controls.ArrowDown
-
-// create new key based on the same buttons
-KeyRecord Toggled
-    Id          ArrowDownNew
-    Combination JOY_DOWN
-    Emulation   GAME_DOWN
-
\ No newline at end of file diff --git a/zengin/union/plugins/zgamepad/index.html b/zengin/union/plugins/zgamepad/index.html deleted file mode 100644 index 198cb49bee..0000000000 --- a/zengin/union/plugins/zgamepad/index.html +++ /dev/null @@ -1,34 +0,0 @@ - zGamePad - Gothic Modding Community

zGamePad

zGamePad plugin adds gamepad support for ZenGin games.

Important

Visit the excellent original GitHub wiki page.

Contacts
Author Gratt
GitHub zGamePad
Forum zGamePad

Gamepad support

  • All xinput compatible (including emulators)
  • Xbox controller family
  • Dualshock 4
  • Dualsense
  • Nintendo Switch Joy-Cons
  • Nintendo Switch Pro Controller

Features

  • Natural Movements
    Intuitiveness and smoothness of movement controls is the main goal of this plugin. Touch the world of Gothic with your hands.
  • Interactive hints
    Interactive hints will help you in mastering the controls. You can always customize their appearance or disable them.
  • Quick access
    The plugin has two quick access rings - **weapons and items. Use them to always have access to your items.
  • Automatic save naming
    Sit comfortably. You do not have to reach for your keyboard, because the plugin itself will give a name to your saves.
  • Saves rotation
    The best alternative to quicksaves for gamepad controls.
  • Vibration response
    Immerse yourself in the game even more. Vibration will allow you to feel your character and everything that happens in the world.
  • Target locking
    The plugin will always help you win. Keeping the enemy in focus will allow you to fight much more effectively.
  • Stuck protection
    Oops! If you get stuck, hold both analogue sticks for a few seconds and the character will reset.
\ No newline at end of file diff --git a/zengin/union/plugins/zgamepad/keys_engine_absolute/index.html b/zengin/union/plugins/zgamepad/keys_engine_absolute/index.html deleted file mode 100644 index 03182dbf64..0000000000 --- a/zengin/union/plugins/zgamepad/keys_engine_absolute/index.html +++ /dev/null @@ -1,383 +0,0 @@ - Engine absolute keys - Gothic Modding Community

Engine absolute keys

Absolute keys are the physical keys on your keyboard.

  1
-  2
-  3
-  4
-  5
-  6
-  7
-  8
-  9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
-100
-101
-102
-103
-104
-105
-106
-107
-108
-109
-110
-111
-112
-113
-114
-115
-116
-117
-118
-119
-120
-121
-122
-123
-124
-125
-126
-127
-128
-129
-130
-131
-132
-133
-134
-135
-136
-137
-138
-139
-140
-141
-142
-143
-144
-145
-146
-147
-148
-149
-150
-151
-152
-153
-154
-155
-156
-157
-158
-159
-160
-161
-162
-163
-164
-165
-166
-167
-168
-169
-170
-171
-172
-173
-174
-175
MOUSE_DX
-MOUSE_DY
-MOUSE_UP
-MOUSE_DOWN
-MOUSE_LEFT
-MOUSE_RIGHT
-MOUSE_WHEELUP
-MOUSE_WHEELDOWN
-MOUSE_BUTTONLEFT
-MOUSE_BUTTONRIGHT
-MOUSE_BUTTONMID
-MOUSE_XBUTTON1
-MOUSE_XBUTTON2
-MOUSE_XBUTTON3
-MOUSE_XBUTTON4
-MOUSE_XBUTTON5
-KEY_ESCAPE
-KEY_1
-KEY_2
-KEY_3
-KEY_4
-KEY_5
-KEY_6
-KEY_7
-KEY_8
-KEY_9
-KEY_0
-KEY_MINUS
-KEY_EQUALS
-KEY_BACK
-KEY_TAB
-KEY_Q
-KEY_W
-KEY_E
-KEY_R
-KEY_T
-KEY_Y
-KEY_U
-KEY_I
-KEY_O
-KEY_P
-KEY_LBRACKET
-KEY_RBRACKET
-KEY_RETURN
-KEY_LCONTROL
-KEY_A
-KEY_S
-KEY_D
-KEY_F
-KEY_G
-KEY_H
-KEY_J
-KEY_K
-KEY_L
-KEY_SEMICOLON
-KEY_APOSTROPHE
-KEY_GRAVE
-KEY_LSHIFT
-KEY_BACKSLASH
-KEY_Z
-KEY_X
-KEY_C
-KEY_V
-KEY_B
-KEY_N
-KEY_M
-KEY_COMMA
-KEY_PERIOD
-KEY_SLASH
-KEY_RSHIFT
-KEY_MULTIPLY
-KEY_LMENU
-KEY_SPACE
-KEY_CAPITAL
-KEY_F1
-KEY_F2
-KEY_F3
-KEY_F4
-KEY_F5
-KEY_F6
-KEY_F7
-KEY_F8
-KEY_F9
-KEY_F10
-KEY_NUMLOCK
-KEY_SCROLL
-KEY_NUMPAD7
-KEY_NUMPAD8
-KEY_NUMPAD9
-KEY_SUBTRACT
-KEY_NUMPAD4
-KEY_NUMPAD5
-KEY_NUMPAD6
-KEY_ADD
-KEY_NUMPAD1
-KEY_NUMPAD2
-KEY_NUMPAD3
-KEY_NUMPAD0
-KEY_DECIMAL
-KEY_OEM_102
-KEY_F11
-KEY_F12
-KEY_F13
-KEY_F14
-KEY_F15
-KEY_KANA
-KEY_ABNT_C1
-KEY_CONVERT
-KEY_NOCONVERT
-KEY_YEN
-KEY_ABNT_C2
-KEY_NUMPADEQUALS
-KEY_PREVTRACK
-KEY_AT
-KEY_COLON
-KEY_UNDERLINE
-KEY_KANJI
-KEY_STOP
-KEY_AX
-KEY_UNLABELED
-KEY_NEXTTRACK
-KEY_NUMPADENTER
-KEY_RCONTROL
-KEY_MUTE
-KEY_CALCULATOR
-KEY_PLAYPAUSE
-KEY_MEDIASTOP
-KEY_VOLUMEDOWN
-KEY_VOLUMEUP
-KEY_WEBHOME
-KEY_NUMPADCOMMA
-KEY_DIVIDE
-KEY_SYSRQ
-KEY_RMENU
-KEY_PAUSE
-KEY_HOME
-KEY_UP
-KEY_PRIOR
-KEY_LEFT
-KEY_RIGHT
-KEY_END
-KEY_DOWN
-KEY_NEXT
-KEY_INSERT
-KEY_DELETE
-KEY_LWIN
-KEY_RWIN
-KEY_APPS
-KEY_POWER
-KEY_SLEEP
-KEY_WAKE
-KEY_WEBSEARCH
-KEY_WEBFAVORITES
-KEY_WEBREFRESH
-KEY_WEBSTOP
-KEY_WEBFORWARD
-KEY_WEBBACK
-KEY_MYCOMPUTER
-KEY_MAIL
-KEY_MEDIASELECT
-KEY_BACKSPACE
-KEY_NUMPADSTAR
-KEY_LALT
-KEY_CAPSLOCK
-KEY_NUMPADMINUS
-KEY_NUMPADPLUS
-KEY_NUMPADPERIOD
-KEY_NUMPADSLASH
-KEY_RALT
-KEY_UPARROW
-KEY_PGUP
-KEY_LEFTARROW
-KEY_RIGHTARROW
-KEY_DOWNARROW
-KEY_PGDN
-
\ No newline at end of file diff --git a/zengin/union/plugins/zgamepad/keys_engine_logical/index.html b/zengin/union/plugins/zgamepad/keys_engine_logical/index.html deleted file mode 100644 index 0ecc969d0b..0000000000 --- a/zengin/union/plugins/zgamepad/keys_engine_logical/index.html +++ /dev/null @@ -1,87 +0,0 @@ - Engine logical keys - Gothic Modding Community

Engine logical keys

Logical keys are the keys you set in keyboard settings in the game menu. These can fill multiple roles in different situations and the gamepad controls can be set to emulate these logical keys.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
GAME_LEFT
-GAME_RIGHT
-GAME_UP
-GAME_DOWN
-GAME_ACTION
-GAME_SLOW
-GAME_ACTION2
-GAME_WEAPON
-GAME_SMOVE
-GAME_SMOVE2
-GAME_SHIFT
-GAME_END
-GAME_INVENTORY
-GAME_LOOK
-GAME_SNEAK
-GAME_STRAFELEFT
-GAME_STRAFERIGHT
-GAME_SCREEN_STATUS
-GAME_SCREEN_LOG
-GAME_SCREEN_MAP
-GAME_LOOK_FP
-GAME_LOCK_TARGET
-GAME_PARADE
-GAME_ACTIONLEFT
-GAME_ACTIONRIGHT
-GAME_LAME_POTION
-GAME_LAME_HEAL
-
\ No newline at end of file diff --git a/zengin/union/plugins/zgamepad/keys_gamepad/index.html b/zengin/union/plugins/zgamepad/keys_gamepad/index.html deleted file mode 100644 index 28d1ef3a66..0000000000 --- a/zengin/union/plugins/zgamepad/keys_gamepad/index.html +++ /dev/null @@ -1,85 +0,0 @@ - Gamepad keys - Gothic Modding Community

Gamepad keys

In order to set gamepad keys, you have to know the key codes as they are listed below.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
JOY_UP
-JOY_DOWN
-JOY_LEFT
-JOY_RIGHT
-JOY_MENU
-JOY_VIEW
-JOY_LSTICK
-JOY_RSTICK
-JOY_LB
-JOY_RB
-JOY_A
-JOY_B
-JOY_X
-JOY_Y
-JOY_LSTICK_LOWUP
-JOY_LSTICK_UP
-JOY_LSTICK_DOWN
-JOY_LSTICK_LEFT
-JOY_LSTICK_RIGHT
-JOY_RT
-JOY_LT
-JOY_DPAD
-JOY_UPDOWN
-JOY_LEFTRIGHT
-JOY_LSTICK_FULL
-JOY_RSTICK_FULL
-
\ No newline at end of file diff --git a/zengin/union/plugins/zgamepad/logical_functions/index.html b/zengin/union/plugins/zgamepad/logical_functions/index.html deleted file mode 100644 index 3bf16bcc87..0000000000 --- a/zengin/union/plugins/zgamepad/logical_functions/index.html +++ /dev/null @@ -1,89 +0,0 @@ - Logical functions - Gothic Modding Community

Logical function names

Conditions for when to show or allow the control binding to work are specified using these logic functions. They describe different useful states of the game or user interface, allowing the user to set when will a certain control work.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
Cond_FightMode        - player is in the fight mode
-Cond_FightModeMelee   - player is in the melee fight mode
-Cond_FightModeRange   - player is in the ranged fight mode
-Cond_FightModeMagic   - player is in the magical fight mode
-Cond_CanShoot         - player is in the aim mode and can shoot now
-Cond_CanSneaking      - player is sneaking now
-Cond_Diving           - player is diving now
-Cond_HasFocusVob      - player has a focus vob
-Cond_HasFocusNpc      - player has a focus npc
-Cond_OnChooseWeapon   - weapon selection is active
-Cond_InventoryIsOpen  - inventory is open
-Cond_InTransformation - player is transformed
-Cond_VideoIsOpen      - video is playing
-Cond_CanLockTarget    - player in the fight mode now and can lock the focus vob
-Cond_G1               - this engine is a Gothic 1 (or sequel)
-Cond_G2               - this engine is a Gothic 2 NoTR (or classic)
-Cond_IsDialogTop      - dialog window is open on the top
-Cond_IsDocumentTop    - document object is open on the top
-Cond_IsOverlayTop     - gamepad overlay object is open on the top
-Cond_IsMenuTop        - game menu is open on the top
-Cond_OnSpellBook      - magic selection ring is active
-Cond_IsPlayerTalking  - player is talking to someone
-Cond_InterfaceIsOpen  - open any interface element
-Cond_HasLeftContainer - the left container is open (chest, plunder, trader)
-Cond_UsesPicklock     - player is picking a lock now
-Cond_IsOnTrade        - player is trading
-Cond_IsOverlayTop     - gamepad overlay object is open on the top
-Cond_IsMenuTop        - game menu is open on the top
-
\ No newline at end of file diff --git a/zengin/union/sdk/events/index.html b/zengin/union/sdk/events/index.html deleted file mode 100644 index 0caf2b01e2..0000000000 --- a/zengin/union/sdk/events/index.html +++ /dev/null @@ -1,179 +0,0 @@ - Game Events - Gothic Modding Community

Game Events

Union defines several Game Events that are dispatched when a specific event occurs in-game. Handlers are defined in Plugin.cpp and we can use them to execute our code during specific moments of the application lifetime.

Events

Initialization

Game_Entry

Executes at the entry point of the Gothic executable. During this time the engine classes are not yet initialized, so using them may cause an access violation. The entry point be used to execute some logic before Gothic loads itself.

1
-2
-3
void Game_Entry() {
-
-}
-

Game_DefineExternals

Executes before the Daedalus parser starts loading scripts. It's meant to define custom external functions.

1
-2
-3
void Game_DefineExternals() {
-
-}
-

Game_Init

Executes right after DAT files are loaded and just before the main menu shows up.

1
-2
-3
void Game_Init() {
-
-}
-

Level Change

Game_LoadBegin

Executes when we initiate a level change by one of the possible actions. The default plugin template uses a common LoadBegin() function to handle all events but we also can write different logic for different cases.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
void LoadBegin() {
-
-}
-
-// When player clicks "New Game"
-void Game_LoadBegin_NewGame() {
-    LoadBegin();
-}
-
-// When player loads a saved game
-void Game_LoadBegin_SaveGame() {
-    LoadBegin();
-}
-
-// When player changes ZEN by a trigger
-void Game_LoadBegin_ChangeLevel() {
-    LoadBegin();
-}
-

Game_LoadEnd

Executes when the level loading finishes. The default plugin template uses a common LoadEnd() function to handle all events but we also can write different logic for different cases.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
void LoadEnd() {
-
-}
-
-// When player clicks "New Game"
-void Game_LoadEnd_NewGame() {
-    LoadEnd();
-}
-
-// When player loads a saved game
-void Game_LoadEnd_SaveGame() {
-    LoadEnd();
-}
-
-// When player changes ZEN by a trigger
-void Game_LoadEnd_ChangeLevel() {
-    LoadEnd();
-}
-

Game_LoadBegin_Trigger

Executes when the player enters a trigger that initiates ZEN change.

1
-2
-3
void Game_LoadBegin_Trigger() {
-
-}
-

Game_LoadEnd_Trigger

Executes after the player has entered a trigger that initiates ZEN change.

1
-2
-3
void Game_LoadEnd_Trigger() {
-
-}
-

Game_ApplyOptions

Executes after Game_LoadEnd, when we save the game, and also when we exit the game. It's meant to be used to apply options from INI files.

1
-2
-3
void Game_ApplyOptions() {
-
-}
-

Game Loop

Game_PreLoop

Executes at the start of every frame.

1
-2
-3
void Game_PreLoop() {
-
-}
-

Game_Loop

Executes at every frame.

1
-2
-3
void Game_Loop() {
-
-}
-

Game_PostLoop

Executes at the end of every frame.

1
-2
-3
void Game_PostLoop() {
-
-}
-

Game_MenuLoop

Executes at every frame when the game menu is active.

1
-2
-3
void Game_MenuLoop() {
-
-}
-

Game_SaveBegin

Executes when the player started saving a game.

1
-2
-3
void Game_SaveBegin() {
-
-}
-

Game_SaveEnd

Executes when the game save finishes.

1
-2
-3
void Game_SaveEnd() {
-
-}
-

Game_Pause

Executes when the player opens the in-game menu.

1
-2
-3
void Game_Pause() {
-
-}
-

Game_Unpause

Executes when the player leaves the in-game menu and also when the player loads a saved game.

1
-2
-3
void Game_Unpause() {
-
-}
-

Shutdown

Game_Exit

Executes when the player exits the game.

1
-2
-3
void Game_Exit() {
-
-}
-
\ No newline at end of file diff --git a/zengin/union/sdk/externals/index.html b/zengin/union/sdk/externals/index.html deleted file mode 100644 index 22aec392c9..0000000000 --- a/zengin/union/sdk/externals/index.html +++ /dev/null @@ -1,117 +0,0 @@ - Externals - Gothic Modding Community

Externals

Externals are functions defined by the Gothic engine that can be called from scripts. Union SDK provides symbols for pointers to global zCParser instances that we can use to interact with the parser and to define a custom external function.

1
-2
-3
-4
-5
-6
-7
extern zCParser*    parser;
-extern zCParser*&   parserSoundFX;
-extern zCParser*&   parserParticleFX;
-extern zCParser*&   parserVisualFX;
-extern zCParser*&   parserCamera;
-extern zCParser*&   parserMenu;
-extern zCParser*&   parserMusic;
-

Creating custom external

To create an external we need to define a function handler and register it in the parser. Before we start, it's good to write down a Daedalus function signature so we can see the return and argument types that will be important later.

func string AddNumbers(var int FirstArgument, var int SecondArgument, var string ThirdArgument)  {}
-

Function handler

External function handler signature must:

  • return int or bool
  • use __cdecl calling convention (default in C++)
  • take no arguments

Inside the handler, we can use the global parser to pop function arguments and push the return value from/to the stack. It's important to pop the arguments in reverse order and to pop all of them even if we are not going to use them. Similarly, the return value must always be set if any and must never be set if the function returns void. If we don't follow the rules, the stack may get corrupted and lead to the Gothic crash.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
// __cdecl is optional because it's the default calling convention
-int __cdecl AddNumbers_External()
-{
-    // Declare arguments
-    int FirstArgument;
-    int SecondArgument;
-    zSTRING ThirdArgument;
-
-    // Pop arguments from the stack **IN REVERSE ORDER**
-    parser->GetParameter(ThirdArgument);
-    parser->GetParameter(SecondArgument);
-    parser->GetParameter(FirstArgument);
-
-    // Execute function logic
-    int result = FirstArgument + SecondArgument;
-    zSTRING output = ThirdArgument + zSTRING(result);
-
-    // Push return value
-    parser->SetReturn(output);
-
-    // Return value is ignored, so 0 or 1 is fine.
-    return 0;
-}
-

Register external

Externals should be registered in the parser during the Game_DefineExternals game event. We need to call parser->DefineExternal with variadic arguments:

  • external function name in Daedalus
  • reference to function handler
  • return type
  • ...argument types
  • zPAR_TYPE_VOID indicates the end of the argument types list
1
-2
-3
void Game_DefineExternals() {
-    parser->DefineExternal("AddNumbers", AddNumbers_External, zPAR_TYPE_STRING, zPAR_TYPE_INT, zPAR_TYPE_INT, zPAR_TYPE_STRING, zPAR_TYPE_VOID);
-}
-

Available types are defined by an enum:

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
enum {
-    zPAR_TYPE_VOID,
-    zPAR_TYPE_FLOAT,
-    zPAR_TYPE_INT,
-    zPAR_TYPE_STRING,
-    zPAR_TYPE_CLASS,
-    zPAR_TYPE_FUNC,
-    zPAR_TYPE_PROTOTYPE,
-    zPAR_TYPE_INSTANCE
-};
-
\ No newline at end of file diff --git a/zengin/union/sdk/getting_started/index.html b/zengin/union/sdk/getting_started/index.html deleted file mode 100644 index d6b0b63f3b..0000000000 --- a/zengin/union/sdk/getting_started/index.html +++ /dev/null @@ -1,78 +0,0 @@ - Getting Started - Gothic Modding Community

Getting Started

This article provides a beginner-friendly tutorial for setting up and compiling a Union project. Instructions for installing Union SDK are located at Union SDK.

Creating Union plugin

Create a Visual Studio project

To create a Union plugin project inside Visual Studio we need to use File -> New -> Project. On the next screen, we select "Union Plugin 1.0m", and click Next. For the project configuration, we should choose:

Key Value
Project name eg. MyPlugin
Location Directory where to store the source code
Solution Create new solution
Solution name eg. MyPlugin

We will also check "Place solution and project in the same directory" because our plugin consists of only one project, so there is no need to complicate the file structure.

File Structure

Folder / File Description
Engine SDK/ In this folder, we have the Gothic Engine API in the form of header files. Most of the files between engines are very similar to each other but they can't be used interchangeably because each engine has slightly different API and addresses of functions.
Engine SDK/User API/ These are empty files that are included in the corresponding engine headers. There are meant for placing additional methods extending classes that can be used for example in Hooks.
Plugin/System/ DLL entry point generated by Union. We shouldn't modify anything here.
Plugin/Workspace/Interface/ These are header files containing headers and source files important in correct order and an Interface.cpp file that merges all the code into one file.
Plugin/Workspace/Plugin/ Finally, this is the source code of the plugin and especially Plugin.cpp where we can create code executed on Game Events.

Build Configuration

Each Union plugin may target one or many versions of the Gothic engine and to select the proper API, Union SDK defines several build configurations for every engine, configuration, and also multiplatform build options. Each Target/Configuration combination is named [ENGINE] [CONFIGURATION].

Configurations:

  • Debug: Unoptimized build with debug symbols for development.
  • MD Release: Optimized build for release versions. Runtime Library: Multi-threaded DLL (/MD)
  • MT Release: Optimized build for release versions. Runtime Library: Multi-threaded (/MT)

Engines:

  • G1: Gothic I
  • G1A: Gothic Sequel
  • G2: Gothic II
  • G2A: Gothic II NotR
  • MP x2: Multiplatform target for both Gothic I (G1) and Gothic II NotR (G2A)
  • MP x4: Multiplatform target for all engine versions (Gothic I, Gothic Sequel, Gothic II, Gothic II NotR)

For learning Union, it's suggested to select G2A Debug for Gothic II NotR or G1 Debug for Gothic I.

Project Configuration

The Union plugin is a regular C++ Visual Studio project so it's possible to configure the project, compiler, linker, and debugger as we wish by going into Project -> Properties. For a starter, we should go to the General tab and check if Platform Toolset is installed and selected. If not, we should select one that's available on our system. Union was created with v100 but it also supports the newest toolkits, so it's best to select a modern one.

In the General tab, we can also specify the Output Directory where the plugin DLL will be placed after the build. During development, we can set it to <GOTHIC_DIR>/System/Autorun where <GOTHIC_DIR> is the root folder of the Gothic installation with Union that we will use for testing. Each DLL file placed in System/Autorun is automatically loaded by Union runtime.

Another method is to put the DLL in the System directory and modify Gothic.ini to include

1
-2
-3
[PLUGIN]
-# Plugin file names without .dll 
-PluginList = MyPlugin 
-

Build the plugin

After the initial configuration, we are ready to code something and see if our configuration is working. Let's collect some information about Union and display it with a MessageBox when the game starts. To do so, we locate the Plugin.cpp file and put our logic in one of the Game Events handlers. The best for that is Game_Init() because it's executed right after the engine loads every DAT file but before anything else:

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
void Game_Init() {
-    const CPlugin* myPlugin = CPlugin::GetCurrentPlugin();
-
-    CStringA gothicVersion;
-    switch (Union.GetEngineVersion()) {
-        case Engine_G1:  gothicVersion = "Gothic I";
-        case Engine_G1A:  gothicVersion = "Gothic Sequel";
-        case Engine_G2:  gothicVersion = "Gothic II";
-        case Engine_G2A:  gothicVersion = "Gothic II NoTR";
-    }
-
-    CStringA message = "Plugin: " + myPlugin->GetName() + "\n";
-    message = message + "Union Version: " + Union.GetUnionVersion().ToString() + "\n";
-    message = message + "Gothic Version: " + gothicVersion;
-
-    Message::Info(message, "Hello World");
-}
-

Now we can Build (F7) the project to create the DLL. If we have set up Output Directory before, the plugin will deploy directly to the game. Otherwise, we can copy it manually from Bin to <GOTHIC_DIR>/System/Autorun/MyPlugin.dll. When we launch the game, a MessageBox should appear right before the main menu: Union SDK MessageBox

Couldn't build the plugin?

If you could not build the plugin or it crashed the game, you have to do some debugging and find the root cause of that. For compilation errors look at the Visual Studio Output tab and read the errors.

If they say something about missing toolset, make sure that you selected a Platform Toolset that's installed.

If the proper toolset is selected but doesn't work, make sure that you are configuring the same Configuration that is used for building.

If the plugin was built but the game crashed, you probably selected Configuration for the wrong platform. Gothic 2 Night of the Raven is G2A and doesn't work with G2 or G1A. If you are playing Gothic II Classic from Steam, please be advised that it still uses the Night of The Raven engine so the plugin must target G2A.

Debugging

Union plugins are regular DLLs with executable code hooked to Gothic.exe and running on it, so they can be debugged using the same techniques as any other software.

Visual Studio Debugger

Visual Studio Debugger lets us set breakpoints on any line of code to stop the execution when we reach it. It also gives us a lot of information about the program state at this point. To use the debugger we only need to attach it to the Gothic.exe progress and compile the plugin with Debug configuration.

Option #1: Open Project -> Properties and in the Debugging tab, set Command to the path of our Gothic.exe. Then we can run "Local Windows Debugger" in Visual Studio and it starts Gothic with a debugger attached automatically.

Option #2: Open Debug -> Attach to process... and filter process list by "Gothic". Run the game separately and when the process appears in Visual Studio, select it and attach to it.

Caveats:

  • If we attach to the process early, we may get an "Exception thrown at 0x7B11DB86 (Shw32.dll) in Gothic2.exe: 0xC0000005: Access violation writing location 0x00ABD000." right at the beginning. It's fine, just click Continue and Gothic will start properly.
  • If a breakpoint hits when our cursor is locked by Gothic, we may not be able to get the cursor back until execution continues. In this case, we can still use Alt+Tab to switch to Visual Studio and use F5 to continue or F10 to step over. Disabling mouse support in the config may also fix this problem.

Printing to some output is probably the simplest form of debugging and Union provides us with several choices.

Logging to zSPY

zSPY can be accessed using a global zerr object. zSPY uses a message filtering system based on the first letter of the message, so our logs should follow the standard format used by other parts of ZenGine. Otherwise, the message may not be visible.

zerr->Message("X:   MyPlugin: message to zSPY");
-

Logging to Union console

Union console needs to be enabled inside SystemPack.ini first:

1
-2
[CORE]
-ShowDebugWindow = true
-
Then we can use a global cmd object behaving like C++ std::cout to log into the Union console:
cmd << "message to Union console";
-

Logging to Visual Studio

Visual Studio can also receive logs from our plugin using:

OutputDebugString("message to Visual Studio");
-
This method works only when we have a debugger attached, so it's not recommended for general logging.
\ No newline at end of file diff --git a/zengin/union/sdk/hooks/index.html b/zengin/union/sdk/hooks/index.html deleted file mode 100644 index 7055ec61af..0000000000 --- a/zengin/union/sdk/hooks/index.html +++ /dev/null @@ -1,202 +0,0 @@ - Hooks - Gothic Modding Community

Hooks

Union provides a hooks system that lets us intercept calls to the engine functions and methods with our custom interceptor. To hook a function or method we need to know its address which can be acquired either from Engine SDK/[Engine]/Names_[Engine].hpp or from the engine classes headers Engine SDK/[Engine]/Headers.

Intercepting functions

To declare a hook we can use CInvoke class or HOOK AS macros.

1
-2
-3
CInvoke<function_type> Ivk_HookName(orignal_function_address, our_interceptor_function, hook_flags);
-
-HOOK Ivk_HookName AS(orignal_function_address, our_interceptor_function, hook_flags);
-

Regular functions

Regular functions are the functions declared outside of classes.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
// 0x0042C450 int __cdecl Apply_Options_Video(void)
-
-// Forward declaration
-int Apply_Options_Video(); 
-
-// Hook declaration
-CInvoke<int(*)()> Ivk_Apply_Options_Video(0x0042C450, &Apply_Options_Video);
-// Equivalent:
-// HOOK Ivk_Apply_Options_Video AS(0x0042C450, &Apply_Options_Video);
-
-// Implementation of interceptor
-int Apply_Options_Video() {
-    Message::Info("Before original Apply_Options_Video()");
-
-    // Original function can be called using CInvoke pointer.
-    int result = Ivk_Apply_Options_Video();
-
-    Message::Info("After original Apply_Options_Video()");
-
-    return result;
-}
-

Member function

Member functions are the functions declared as non-static class members and they take a class instance pointer as an implicit first argument (__thiscall calling convention). We can hook them in two ways using either a regular function or declaring a new method in User API.

Option #1 - Regular function

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
// 0x006015D0 public: virtual int __fastcall zCVob::Render(struct zTRenderContext &)
-
-// Forward declaration
-int __fastcall zCVob_Render(zCVob* _this, zTRenderContext& context);
-
-// Hook declaration
-CInvoke<int(__fastcall *)(zCVob* _this, zTRenderContext& context)> Ivk_zCVob_Render(0x006015D0, &zCVob_Render);
-// Equivalent:
-// HOOK Ivk_zCVob_Render AS(0x006015D0, &zCVob_Render);
-
-// Implementation of interceptor as regular function
-// Notice the first argument that's a pointer to class instance (this)
-int __fastcall zCVob_Render(zCVob* _this, zTRenderContext& context) {
-    if(_this == player) {
-        screen->PrintCX(1000, "Rendering a player zCVob");
-    }
-
-    // Call original method
-    return Ivk_zCVob_Render(_this, context);
-}
-

Option #2 - User API

In Engine SDK/User API we can find a .inc file for the class we are hooking and define a new member method there. In this case, we are looking for zCVob.inc:

1
-2
-3
-4
-5
-6
// Supported with union (c) 2020 Union team
-
-// User API for zCVob
-// Add your methods here
-
-int RenderUnion(zTRenderContext& context);
-

Then we can declare the hook pointing to our member method:

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
// 0x006015D0 public: virtual int __fastcall zCVob::Render(struct zTRenderContext &)
-
-// Hook declaration
-CInvoke<int(__fastcall zCVob::*)(zTRenderContext& context)> Ivk_zCVob_Render(0x006015D0, &zCVob::RenderUnion);
-// Equivalent:
-// HOOK Ivk_zCVob_Render AS(0x006015D0, &zCVob::RenderUnion);
-
-// Implementation of interceptor  method
-int zCVob::RenderUnion(zTRenderContext& context) {
-    if(this == player) {
-        screen->PrintCX(1000, "Rendering a player zCVob");
-    }
-
-    // Call original method
-    return Ivk_zCVob_Render(this, context);
-}
-

Hook flags

In the third argument of CInvoke we can provide hook flags. The default value is IVK_AUTO.

 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
enum EInterMode
-{
-    // Hook will not intercept the function.
-    IVK_DISABLED  = 1 << 1,
-
-    // Normal hook. If other hook is already defined for the same address, an error pops up.
-    IVK_NORMAL    = 1 << 2,
-
-    // Hook will automatically create an interception tree to allow multiple hooks for the same address.
-    IVK_AUTO      = 1 << 3,
-
-    // Overrides any hook defined for the same address before.
-    IVK_REDEFINE  = 1 << 4,
-
-    // Makes it impossible to override or disable the hook.
-    // It should be used only in very specific cases.
-    IVK_PROTECTED = 1 << 5,
-
-    // Same as IVK_DISABLED
-    IVK_READONLY  = IVK_DISABLED
-};
-

Credits

Examples are taken from the Union lessons in Russian created by Gratt on worldofplayers.ru/threads/41490/

\ No newline at end of file diff --git a/zengin/union/sdk/index.html b/zengin/union/sdk/index.html deleted file mode 100644 index 20ef23e57a..0000000000 --- a/zengin/union/sdk/index.html +++ /dev/null @@ -1,34 +0,0 @@ - Union SDK - Gothic Modding Community

Union SDK

Union SDK is a software development kit for making Union plugins that directly interact with Gothic engines. It contains a project template for Visual Studio IDE, a C++ library for hooking into a Gothic executable, and Gothic API with methods' addresses for the engines of Gothic I, Gothic II, Gothic II NotR, and also for the not released Gothic Sequel.

Working with Union SDK requires at least basic knowledge of C++ programming. Knowledge of the x86 (32-bit) architecture, dynamically linked libraries, and reverse engineering is also welcomed as we need to understand what the Gothic engine does under the hood to use it effectively.

Requirements

Union SDK requires Visual Studio IDE, NET Framework 4.7.2, and Visual C++ 2010 libraries. They are available on Microsoft websites:

Resource Manager

The official installation of Union SDK is provided through Resource Manager. After the installation, Visual Studio will have a new project template "Union Plugin 1.0" that creates a basic Union plugin project.

\ No newline at end of file diff --git a/zengin/union/zgamepad/controls/index.html b/zengin/union/zgamepad/controls/index.html deleted file mode 100644 index 670983c4e4..0000000000 --- a/zengin/union/zgamepad/controls/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/zengin/union/zgamepad/index.html b/zengin/union/zgamepad/index.html deleted file mode 100644 index 54b84281d0..0000000000 --- a/zengin/union/zgamepad/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/zengin/union/zgamepad/keys_engine_absolute/index.html b/zengin/union/zgamepad/keys_engine_absolute/index.html deleted file mode 100644 index 5c4ab76f03..0000000000 --- a/zengin/union/zgamepad/keys_engine_absolute/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/zengin/union/zgamepad/keys_engine_logical/index.html b/zengin/union/zgamepad/keys_engine_logical/index.html deleted file mode 100644 index b45c94bcb0..0000000000 --- a/zengin/union/zgamepad/keys_engine_logical/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/zengin/union/zgamepad/keys_gamepad/index.html b/zengin/union/zgamepad/keys_gamepad/index.html deleted file mode 100644 index 0fefcd91d8..0000000000 --- a/zengin/union/zgamepad/keys_gamepad/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/zengin/union/zgamepad/logical_functions/index.html b/zengin/union/zgamepad/logical_functions/index.html deleted file mode 100644 index 613f2db2a3..0000000000 --- a/zengin/union/zgamepad/logical_functions/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Redirecting... - - - - - - -Redirecting... - - diff --git a/zengin/video/index.html b/zengin/video/index.html deleted file mode 100644 index 1ddca07bd2..0000000000 --- a/zengin/video/index.html +++ /dev/null @@ -1,34 +0,0 @@ - Video - Gothic Modding Community

Video

To get a video cutscene, intro or outro into the game, the video needs to be in a proper format - BINK video format .bik.

Editing the video

The video you recorded and want to use has to be edited. My go-to editor for this is kdenlive. It works very well, it is free and open source, and it supports BINK video as an input, which is great if you want to include subtitles in the video.

My version of kdenlive does not know how to export video straight to .bik so I just export my video to .mp4 and then convert it with RAD Video Tools.

RAD Video Tools

RAD Video Tools is a tool for converting other video formats to BINK .bik that Gothic can use.

Warning

Gothic 1 bink implementation has some problems as you have to set the audio compression to 104 and above in RAD tools to get video to work in Gothic 1.

NicoDE's comment:

Add 100 to the audio compression level when encoding videos, e.g. 104 for level 4 with old sound format (should be mentioned in the RAD Video Tools documentation) for G1 without updated Miles libraries.

Note

Newest Union (1.0m at the time of writing) has a new patch for BINK video playback. The issue with sound should be fixed.

\ No newline at end of file diff --git a/zengin/worlds/Classes/zCVob/index.html b/zengin/worlds/Classes/zCVob/index.html deleted file mode 100644 index a14f9ec4ef..0000000000 --- a/zengin/worlds/Classes/zCVob/index.html +++ /dev/null @@ -1,34 +0,0 @@ - zCVob - Gothic Modding Community

zCVob

zCVob is a base class for all objects placed in a world.

Acknowledgment

Heavily inspired by the amazing documentation site Gothic library

Class members

zCVob properties in spacer

Properties of a zCVob class are split into two parts. The Internals are hardly ever needed to be edited manually, they are changeed by e.g. moving an object in Spacer. On the other hand the Vob properties can only be changed by the Objects context menu in Spacer.

Internals

Vob

zCVob properties in spacer2

Properties of a zCVob class are split into two parts. The Internals are hardly ever needed to be edited manually, they are changeed by e.g. moving an object in Spacer. On the other hand the Vob properties can only be changed by the Objects context menu in Spacer.

Internals

Vob

Class member overview

pack

No Information provided.

presetName

The name of the template that was used to create the item.

bbox3DWS

Volume of virtual object. Defined by two opposite diagonal points of the BoundingBox (1x, 1y, 1z, 2x, 2y, 2z). The volume is needed to calculate collisions and interactions with other game objects. For example, with dynamic objects, which include characters (class C_NPC), items (class C_ITEM ), etc.

Interaction processing begins when object volumes intersect. For example, when the player enters the world change trigger area, the engine loads another game level based on the parameters this trigger. All this happens when the main character's BoundingBox intersects with the trigger's BoundingBox.

The BoundingBox can only be changed using the Edit the Bbox button in Spcaer.

trafoOSToWSRot

Orientation relative to the coordinate center.

Note

This refers to the center of coordinates of the .3DS file of the game world on which the ZEN file is built.

trafoOSToWSPos

Coordinates of the position in space relative to the center of coordinates.

The coordinates are set automatically the first time an instance of the class is inserted into the game world. You can change them either directly by entering numerical values ​​in the corresponding fields of the parameter, by moving the vob in spacer.

vobName

An identifier of a zCVob shown in the editor and sometimes used in scripts. The name can be left blank.

For some object classes, entering a name is required: zCVobSpot , zCVobWaypoint , zCTrigger , etc.

Danger

Setting a name for every static and insignificant object can lead to an error when parsing the game world.

visual

The name of the file that will be responsible for the visual display of the object.

Different file formats are used for different object classes:

  • *.3DS - Static objects
  • *.PFX - Particle effects
  • *.TGA - Textures
  • *.MDS, *.ASC - Interactive objects
  • *.MMS - Animated objects

showVisual

This option is responsible for displaying the object.

Accepted values:

  • TRUE - Display.
  • FALSE - Do not display.

visualCamAlign

Option to align objects relative to the camera.

Accepted values:

  • NONE - Not used.
  • YAW - The object always faces the player.
  • FULL - The object is aligned relative to the world axes.

Note

For example, in order for the grass model to always face the character, you need to set this parameter to YAW.

visualAniMode

Wind simulation option. Used in conjunction with the visualAniModeStrength parameter.

Accepted values:

  • NONE - Not used.
  • WIND - Strong wind effect. Acceptable for herbs.
  • WIND2 - Light wind effect. Acceptable for trees.

Warning

This option is only available in Gothic 2 (Spacer2).

visualAniModeStrength

Wind power animation multiplier. Small values such as 0.001 are typically used. Used in conjunction with the visualAniMode parameter.

Warning

This option is only available in Gothic 2 (Spacer2).

vobFarClipZScale

Sets the loading range of the VOB object. Depends on the VOB drawing distance specified using the zCZoneVobFarPlane object.

The range of values is from 0.0 to 2.0.

With a value of 0.0, the object is not visible, but collisions are calculated. With a value of 2.0, the VOB drawing range is identical to the VOB drawing range of objects specified by the zCZoneVobFarPlane object.

Warning

This option is only available in Gothic 2 (Spacer2).

CdStatic

Determines if the VOB will collide with the static objects (world mesh and other VOBs with cdStatic on).

Accepted values:

  • TRUE - Collision handling for static objects is enabled.
  • FALSE - Collision handling for static objects is disabled.

Tip

A situation often arises when objects “refuse” to move beyond a certain point on the surface. This happens when cdStatic is set to TRUE, i.e. the object cannot cross the surface another static object. In this case, it is enough to disable the cdStatic parameter for the duration of the move, and turn it on again after the move.

CdDyn

Determines if the VOB will collide with dynamic objects (NPCs, items, etc.). This basically determines if the object has collision during gameplay.

Accepted values:

  • TRUE - Collision handling for dynamic objects is enabled.
  • FALSE - Collision handling for dynamic objects is disabled.

staticVob

Determines if the VOB is taken into consideration in static lighting calculations in Indoor spaces. Usually enabled in decorative Vobs, but some of the interactive ones have it disabled.

Accepted values:

  • TRUE - Calculate the shadow of the object.
  • FALSE - Do not calculate the shadow of the object.

Note

The shadow is calculated when compiling light in Low, Middle or High mode.

dynShadow

Determine if the object will cast a shadow when affected by dynamic light (e.g. torches).

Accepted values:

  • DS_NONE - No shadow.
  • DS_BLOB - Casts a circular shadow.

zbias

Option to remove texture flickering if a .TGA file is used as rendering.

Warning

This option is only available in Gothic 2 (Spacer2).

isAmbient

Sets the calculation of refracted lighting of objects.

Accepted values:

  • TRUE - Calculate the refraction of light.
  • FALSE - Do not calculate light refraction.

Warning

This option is only available in Gothic 2 (Spacer2).

\ No newline at end of file diff --git a/zengin/worlds/index.html b/zengin/worlds/index.html deleted file mode 100644 index 91ad97456c..0000000000 --- a/zengin/worlds/index.html +++ /dev/null @@ -1,34 +0,0 @@ - Worlds - Gothic Modding Community

Worlds

Acknowledgment

This article is heavily inspired by various tutorials from the polish TheModders forums.

Worlds, saved as .ZEN files in ZenGin, are archives that contain the world mesh (model), BSP tree and the information of all objects in the world. These objects are called VOBs ("virtual objects"). ZEN files can be saved in two ways; compiled and uncompiled. The compiled version is a full-fledged level with a terrain model. Uncompiled ZENs only save the VOB tree and are meant for specific use-cases.

Spacer is used to create these .ZEN files. There are also other world editors. The way of doing things can vary between these editors, so the specifics will be discussed in separate articles for those tools; at the same time, a lot of knowledge carries over between them. Also have in mind that Spacer is the least comfortable of the editors.

World contents

The content of worlds in Gothic can be roughly separated in the following way:

  • Base level mesh: terrain and buildings, sometimes also trees
  • VOBs: all interactive objects, items, foliage, small rocks, huts, furniture, ramps etc.

Asides from those elements, there are also many invisible VOBs, such as:

  • Waypoints - used for NPC navigation
  • Freepoints (zCVobSpot) - used mainly for NPC routines and roaming behavior for monsters
  • Startpoints - used only to spawn the player when starting a new game. Teleporting between levels is handled with scripts and uses freepoints to determine where the player will appear.
  • Sound emitters
  • Music zones
  • oCZoneMusic - music which plays inside the bounding box of this zone
  • oCZoneMusicDefault - default music which plays whenever the player is not inside some oCZoneMusic
  • Fog zones (zCZoneZFog) - areas which add fog, e.g. like in swamp areas where the sky is not visible. The setting to fade out the sky is optional though.
  • PFX - particle effects (fire, smoke, fireflies, falling leaves etc.)

Note

This list isn't exhaustive.

Creating a ZEN file

Before VOBs can be added to a world model, the world needs to be compiled. After importing a 3ds model, the world can be compiled as an outdoor or indoor world and saved as a ZEN.

The submeshes used in ZEN files have triangle count limits (it is also advisable to keep triangle count for each submesh under 50k for performance reasons). To get around this limitation and to parallelize work on various areas, it is possible to join multiple ZEN files together, which is done with special macros.

If you take a look at the original maps for Gothic 2, you can notice that they are in folders, where there's e.g. a file called NEWWORLD.ZEN and multiple .ZEN files with "part" in their name. The latter are the sub-zens used to create the full level.

However, a possibly more comfortable workflow is to have a single world mesh which is internally separated into multiple submeshes. This way triangle count limits won't be exceeded and the world won't need compiling from parts. As a trade-off, it is likely that it won't be possible for multiple people to work on the ZEN world at the same time.

Lighting

There are two light types in the game:

  • Static lights, which are baked onto the level. They can cast shadows (these only take static VOBs into consideration) and don't leak through walls. These have to be recompiled after making changes, but this process should only take moments. Static lights have the downside of only working in indoor worlds and in rooms which are closed with portals.
  • Dynamic lights are calculated during runtime, which allows them to move and change properties (their color, for example), but has a performance cost. Additionally, they don't look the best and will often leak through walls.

It is generally advised to use static lights whenever possible.

Portals

Portals are special parts of outdoor world meshes which separate interiors from exteriors. This allows the level to have dark areas: otherwise interiors are lit the same way as any outside area. Additionally, portals help with performance (interiors aren't rendered unless the player is nearby). Creation of portals has many caveats and will be discussed in a separate article. Portals are also related to NPC behavior (e.g. setting ownership of a room).

Optimisation

The game uses occlusion culling, which means that if an object is covered by another object, it is not rendered and saves performance. This means that the performance in a level can be boosted by a lot by creating city walls and mountains and valleys which separate areas.

Occlusion culling isn't a perfect process, so there's also the option of adding GHOSTOCCLUDERs, which are invisible walls which stop areas behind them from rendering. They are a part of the world mesh and are created by assigning a material called GHOSTOCCLUDER to chosen faces. The color of the material is traditionally purplish-blue or pink, but the material itself is not rendered in-game, so this is only to make them stand apart from the rest of the level during modelling. To get more technical, these occluder walls are used to help the BSP algorithm which runs during world compilation.

As mentioned before, another ways of optimisation are portals and limiting the number of dynamic lights. It is also not advisable to make many VOBs be affected by wind.

\ No newline at end of file diff --git a/zengin/worlds/spacer/index.html b/zengin/worlds/spacer/index.html deleted file mode 100644 index bf9ac85226..0000000000 --- a/zengin/worlds/spacer/index.html +++ /dev/null @@ -1,45 +0,0 @@ - Spacer - Gothic Modding Community

Spacer

Spacer is the original world editor used to create maps in Gothic and it's installed by the MDK installer.

A good .ZEN file to start experimenting with Spacer is Toten Insel. It's a simple level which should load without issues for everyone. The map contains a custom texture, but it can be safely ignored.

Introduction

Upon launching Spacer, multiple windows will appear. They are:

  • The main viewport (black with text on launch)
  • The vobtree - allows to browse and select the objects already placed in a level
  • The object window - it has 3 tabs: Create, Modify and "...".
  • Toolbars - there's two of them and each button has a hover hint.
  • The help window - sometimes when clicking on something, this window will show a description. It's usually empty though.
  • The objectpages window - allows access to specific VOB settings. The contents of this window be changed with buttons on the horizontal toolbar.

Other windows dedicated to specific functionalities can also be opened or toggled (Window tab in the viewport or the horizontal toolbar).

When importing a mesh instead of a .ZEN file, some things will change. In this mode, objectpages has material data, one of the toolbars changes completely and the vobtree window changes into a texture browser.

Configuration

Before doing anything else, you will probably want to change a few settings first. Select Settings: View in the Settings tab in the main viewport to increase the viewport resolution. After doing that, press Align Toolwindows at Screen or Align Toolwindows at Spacer in the Window tab to clean up the window placement. You might still need to move some of the tool windows around after this, as they can overlap.

The most comfortable option we found was to set the resolution to something slightly smaller than the screen resolution (e.g. 1600:900 on a 1920:1080 screen) and then aligning the tool windows to screen.

To help with the control sensitivity issues, change the camera movement speed in the Settings: General.

Viewport controls

The camera has multiple modes of operation. Some of the controls may sound confusing, but will make sense once you try them.

Default selection mode

Arrows move the camera back and forward and rotate it sideways. A moves the camera up and Y lowers it.

PageUp and PageDown rotate the camera up and down. End resets this rotation.

Selecting VOBs is done by simply pointing at them with the mouse and clicking.

First-person selection mode

Toggled by the F3 button.

In this mode, you can point the camera with your mouse, and selection is done by pointing the green reticle at a VOB and clicking LMB. Arrows now move the camera parallel to itself (including sideways).

PageUp and PageDown still rotate the camera up and down, but it's better not to use them because it affects how the arrow movement behaves. End resets this rotation.

Default VOB movement mode

When a VOB is selected, press M to enter and exit this mode.

The arrows now move the VOB horizontally. Moving it up and down is done with A and Y.

The keys above the arrows now rotate the VOB:

  • Axis 1: Delete and PageDown
  • Axis 2: Insert and PageUp
  • Axis 3: Home and End

First-person VOB movement mode

When a VOB is selected, press T to enter and exit this mode.

The controls are the same as the default selection mode, but the camera is now placed at the selected VOB and it moves with the camera.

One caveat is that the controls are in the local space of the object. What this basically means is that if you rotated the object in any other way than horizontally, the movement and rotation will now be skewed.

Mixed VOB movement mode

When a VOB is selected, press C to enter and exit this mode. The VOB is now controlled like in the first-person movement mode, but the camera is not placed at the VOB: in other words, the camera remains in the same place.

General

Holding down Shift speeds up the camera in all of the modes. The numpad can be used for rotating instead of the buttons above the arrows. Both movement modes can be used from either of the selection modes. Movement modes can be selected from the vertical toolbar. This toolbar also has a "toggle camera position" button; this switches between two camera placements, which can be controlled independently.

The objects location can also be entered manually through the object window: open the Internals folder and select trafoOSToWSPos to input them at the bottom of the window. Don't forget to press "Apply". Unfortunately the rotation setting uses an odd format and can't be set manually.

Basic usage

This section covers some of the basic things done in the editor.

Inserting a VOB

  • In the Create tab in the Objects window, select the VOB type. Choose zcVob to add a simple decorative model.
  • Right click anywhere on the viewport
  • Select the insert option (Insert [zcVob] in this case)
  • A VOB without a mesh will be created in the middle of the screen. Try to not deselect it, but if you do, it can be found in the vobtree under the appropriate folder (zcVob in this case); it can be identified by a green dot.
  • In the Modify tab in the Object window, select "visual". Insert the model name in the text form at the bottom of the window. You can use pc_lob_sleeper3.3ds for now; this mesh should be present in both Gothic 1 and 2.
  • If you unpacked the meshes while installing the MDK or with GothicVDFS, you can also browse to the file using the file button next to the text form.
  • Make sure to click the Apply button. Do this after making any changes in the Object window or they will be lost.

Tip

You can use the VOB Bilder tool to comfortably browse model images and names. An online version is currently available here. The UI on the website is in Polish but it's simple enough to not matter.

  • To make the VOB have collision in-game, double click on cdDyn ("collision detection dynamic") to set it to true. Sometimes this is unadvised, e.g. with bushes or grass.

Tip

When placing pickable items, you can press the "apply physics on selected VOB" button in the vertical toolbar to make the item drop on the ground. It can save you a lot of work with placing those items. This won't work with a plain cVob though.

Common VOB settings

VOB settings vary depending on what the VOB type is. They all have common parameters of the base VOB class though. The full description of a zCVob class can be found here.

Issues

Spacer 2 received the last update in 2003 and is a very buggy tool. Here are some known issues.

Framerate dependence

The speed of camera in Spacer depends on the framerate. Depending on the angle of the camera and the level, Spacer can have huge framerate, which will make the camera move too quick.

You can try to limit the framerate of Spacer with external tools, but your mileage may vary. Such tools often only limit rendering using fake Vsync, but the underlying logic of the program can still run too fast.

Using the grid snap function can help when the framerate is high, but again: your mileage may vary.

Random freezes and crashes

Spacer will freeze or crash quite often at seemingly random moments. It is extremely important to save often and back up your work.

One of the common ways the editor can freeze is when rotating the camera vertically when the framerate is very high. In that case, changing the camera mode to F3 and back can sometimes help.

Copying VOBs

When copy-pasting a VOB in Spacer (right click menu), the new VOB might be created as a child of the original one and moving one of them will move both. This doesn't seem to be consistent, but it's worth checking before you accidentally ruin the careful placement of the original VOB.

Troubleshooting

You can have issues with loading a ZEN or a world model for a multitude of reasons. Here is some of the known ones.

  • Some terrain models aren't set up or exported properly.
  • Maps which use custom assets will cause issues or won't even load unless these assets are included in appropriate directories. The severity of this is different depending on the asset type. For example, textures will be replaced with a placeholder, but animations will cause crashes.

Note

This section is not exhaustive.

Creating ZENs

Presented here are the ways of working with new terrain models.

Compiling a world mesh

To create a completely new ZEN, you will first need a level mesh. These can be made from scratch or downloaded, but be aware that meshes, which aren't properly prepared won't compile correctly (you won't be able to move in the viewport). As with any other mesh in Gothic, it has to be in the 3ds format. It is recommended to place the mesh file somewhere in the _work/Data/Meshes (can be your own subfolder).

You can find free terrain models here if you want to practice this. Note that not all of them might compile properly; this one should be fine though.

First, load the mesh from the File tab of the viewport. To compile the mesh, press Compile World in the World tab. From here, multiple options are available:

  • Indoor/Outdoor: determines if the world will have a sky and the way that lighting behaves.
  • Detect leaks: might be related to checking if indoor ("underground") worlds have holes in them. In some games such holes can cause performance issues, perhaps it's the same here. Doesn't hurt to enable it.
  • Quick compile: self-explanatory, but the exact effects of this are unknown.
  • Polycheck: presumably checks if the model doesn't exceed triangle limits.
  • Editormode:

    • On: Spacer will load the mesh in editor mode, which allows you to change materials assigned to triangles and other mesh operations. It is more comfortable to do these things in an external 3D editor, but sometimes using this is recommended, e.g. for setting up portals. You can save the model as a .3ds in this mode.

    • Off: Spacer will create a ZEN where you can normally place VOBs. You can now save the world as a compiled ZEN and add VOBs to it.

Compiling a world from multiple meshes

First and foremost, the models used for this must be properly positioned and separated in your 3D editor of choice. Then each section must be exported as separate .3ds files. After that, compile each model and save it as a compiled ZEN. Place them in their own folder. You can place VOBs in those ZEN files, the VOB trees will be merged too.

Now, to join these zens together, you will need to define a macro in Tools>Macros. These are pretty much identical except for the ZEN list; for example, the Mining Colony ZEN in Gothic 2 (OLDWORLD.ZEN) is comprised of two models, and the macro looks like this:

1
-2
-3
-4
-5
-6
reset
-set error 3
-Load world oldworld\SURFACE.ZEN
-Load world oldworld\OLDCAMP.ZEN
-compile world outdoor
-compile light high
-

Then you double-click the macro name to run it and wait. The macro contains the reset directive, but it's worth doing it on a freshly opened Spacer instance just to be safe.

Keep in mind that compiling a world from multiple ZENs is meant as a final step in level production. This is because doing it will cause issues with culling and stop interiors from rendering (and thus stop you from editing it). Instead, the part ZENs are filled with VOBs separately and the world is compiled as a final step before testing the map.

Updating world meshes in a compiled ZEN

Ideally, updating the world mesh would be avoided, but it's an inevitable need when iterating a map design. Doing this in the original Spacer might not be impossible, but it is generally avoided and Spacer.NET or other editors are used for this instead.

\ No newline at end of file

Syntax and keywords