diff --git a/blog/community-news/introducing-community-posts/index.html b/blog/community-news/introducing-community-posts/index.html index a6c69f9fef..c39c03f8e3 100644 --- a/blog/community-news/introducing-community-posts/index.html +++ b/blog/community-news/introducing-community-posts/index.html @@ -31,7 +31,7 @@ const gGMC_PAGE_LOCALE = "en"; const gGMC_FILE_LOCALE = "en"; const gGMC_TRANSLATE_SVG = ''; -

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!

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!

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!

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 +

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/draw3d/index.html b/cs/zengin/scripts/extenders/lego/tools/draw3d/index.html index b138a72284..e78c054b65 100644 --- a/cs/zengin/scripts/extenders/lego/tools/draw3d/index.html +++ b/cs/zengin/scripts/extenders/lego/tools/draw3d/index.html @@ -266,4 +266,4 @@ // EraseBBox(hndl); // Or delete including the handle }; }; -
\ No newline at end of file +
\ 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 index 4ffe996e5c..adac4adc84 100644 --- a/cs/zengin/scripts/extenders/lego/tools/event_handler/index.html +++ b/cs/zengin/scripts/extenders/lego/tools/event_handler/index.html @@ -52,4 +52,4 @@ Parameters

EventPtr_Remove

EventPtr_Remove

Removes a function from the event's call list.

func void EventPtr_Remove(var int eventPtr, var func function)
 
Parameters

EventPtr_RemoveI

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

EventPtr_Execute

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)
-

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 +

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 index acd9584c43..c47aa49333 100644 --- a/cs/zengin/scripts/extenders/lego/tools/frame_functions/index.html +++ b/cs/zengin/scripts/extenders/lego/tools/frame_functions/index.html @@ -116,4 +116,4 @@ { 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 + 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 index 9af086e585..602a95cee6 100644 --- a/cs/zengin/scripts/extenders/lego/tools/hashtables/index.html +++ b/cs/zengin/scripts/extenders/lego/tools/hashtables/index.html @@ -143,4 +143,4 @@ // Destroy the hashtable HT_Destroy(hashtableHandle); }; -
\ No newline at end of file +
\ 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 index 06f86bce5b..cc381b7b48 100644 --- a/cs/zengin/scripts/extenders/lego/tools/hook_dae/index.html +++ b/cs/zengin/scripts/extenders/lego/tools/hook_dae/index.html @@ -241,4 +241,4 @@ // -- B: 3 // <- C: 2 // <- D: 1 -
\ No newline at end of file +
\ 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 index 429edf3613..2f8730a5b4 100644 --- a/cs/zengin/scripts/extenders/lego/tools/hook_engine/index.html +++ b/cs/zengin/scripts/extenders/lego/tools/hook_engine/index.html @@ -63,4 +63,4 @@ var int EBP; var int ESI; var int EDI; -
\ No newline at end of file +
\ 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 index 67d9893450..8087795779 100644 --- a/cs/zengin/scripts/extenders/lego/tools/int64/index.html +++ b/cs/zengin/scripts/extenders/lego/tools/int64/index.html @@ -55,4 +55,4 @@ Parameters

sub64

sub64

Subtracts src from dest: *dest <- *dest - *src

func void sub64(var int dest, var int src)
 
Parameters

mul64

mul64

Multiplies dest by src: *dest <- (*dest) * (*src)

func void mul64(var int dest, var int src)
 
Parameters

div64

div64

Divides dest by src: *dest <- *dest / *src

func void mul64(var int dest, var int src)
-
Parameters
\ No newline at end of file + Parameters
\ 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 index 41d4d30651..742b611562 100644 --- a/cs/zengin/scripts/extenders/lego/tools/interface/index.html +++ b/cs/zengin/scripts/extenders/lego/tools/interface/index.html @@ -246,4 +246,4 @@ // Since Anim8 does the deleting itself, we don't have to worry about that. }; -
\ No newline at end of file +
\ 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 index b11aa4471b..431ca9383b 100644 --- a/cs/zengin/scripts/extenders/lego/tools/item_helper/index.html +++ b/cs/zengin/scripts/extenders/lego/tools/item_helper/index.html @@ -32,4 +32,4 @@ const gGMC_FILE_LOCALE = "en"; const gGMC_TRANSLATE_SVG = '';

ItemHelper

Info

Dependencies:
- None
Implementation:
ItemHelper.d on GitHub

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.

Initialization

N/A

Functions

Itm_GetPtr

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 + Parameters

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 index d6e0a01e02..e642612525 100644 --- a/cs/zengin/scripts/extenders/lego/tools/list/index.html +++ b/cs/zengin/scripts/extenders/lego/tools/list/index.html @@ -57,4 +57,4 @@ Parameters:

Return Value:

The function returns TRUE if data1 is greater than data2, FALSE is returned otherwise.

List_CmpDescending

List_CmpDescending

Compares two integer values in descending order.

func int List_CmpDescending(var int data1, var int data2)
 
Parameters:

Return Value:

The function returns TRUE if data1 is less than data2, FALSE is returned otherwise.

List_CmpAscendingUnsigned

List_CmpAscendingUnsigned

Compares two unsigned integer values in ascending order.

func int List_CmpAscendingUnsigned(var int data1, var int data2)
 
Parameters:

Return Value:

The function returns TRUE if data1 is greater than data2, FALSE is returned otherwise.

List_CmpDescendingUnsigned

List_CmpDescendingUnsigned

Compares two unsigned integer values in descending order.

func int List_CmpDescendingUnsigned(var int data1, var int data2)
-
Parameters:

Return Value:

The function returns TRUE if data1 is less than data2, FALSE is returned otherwise.

\ No newline at end of file + Parameters:

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 index 8f31eb6c59..555ded891c 100644 --- a/cs/zengin/scripts/extenders/lego/tools/locals/index.html +++ b/cs/zengin/scripts/extenders/lego/tools/locals/index.html @@ -48,4 +48,4 @@ }; MEM_InfoBox("This will appear before Final"); }; - Few lines of code say more than a thousand words.
\ No newline at end of file + 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 index aa13de1ba9..9f485b2a75 100644 --- a/cs/zengin/scripts/extenders/lego/tools/misc/index.html +++ b/cs/zengin/scripts/extenders/lego/tools/misc/index.html @@ -40,4 +40,4 @@ Parameters

Return value

The function returns arcus sine of the angle as Ikarus float.

acos

acos

Calculates the arcus cosine

func int acos(var int cosine)
 
Parameters

Return value

The function returns arcus cosine of the angle as Ikarus float.

distance2D

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

Return value

The function returns the distance between the two points.

distance2Df

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

Return value

The function returns the distance between the two points as Ikarus float.

\ No newline at end of file + Parameters

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 index b048824cf1..d34e1e8c44 100644 --- a/cs/zengin/scripts/extenders/lego/tools/permmem/index.html +++ b/cs/zengin/scripts/extenders/lego/tools/permmem/index.html @@ -83,4 +83,4 @@ Parameters

PM_LoadArray

PM_LoadArray

Returns a pointer to array stored in the archive.

func int PM_LoadArray(var string name)
 
Parameters

PM_LoadArrayToPtr

PM_LoadArrayToPtr

Loads a pointer to array from the archive to destPtr.

func void PM_LoadArrayToPtr(var string name, var int destPtr)
 
Parameters

PM_LoadToPtr

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
\ No newline at end of file + Parameters
\ 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 index 7767e23b74..55d11437dc 100644 --- a/cs/zengin/scripts/extenders/lego/tools/queue/index.html +++ b/cs/zengin/scripts/extenders/lego/tools/queue/index.html @@ -45,4 +45,4 @@ Parameters

CQ_IsEmpty

CQ_IsEmpty

Checks if no function is in the callback queue.

func int CQ_IsEmpty(var int queue)
 
Parameters

Return value

The function returns TRUE if the callback queue is empty, FALSE is returned otherwise.

CQ_Advance

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

CQ_Exhaust

CQ_Exhaust

Executes all functions contained in the callback queue.

func void CQ_Exhaust(var int queue)
-
Parameters
\ No newline at end of file + Parameters
\ 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 index 3a4af50e04..98bdbe7abb 100644 --- a/cs/zengin/scripts/extenders/lego/tools/random/index.html +++ b/cs/zengin/scripts/extenders/lego/tools/random/index.html @@ -37,4 +37,4 @@ Parameters

Return value

The function returns a random number from 0 to 'max'.

r_MinMax

r_MinMax

Returns a random number from 'min' to 'max'.

func int r_MinMax(var int min, var int max)
 
Parameters

Return value

The function returns a random number from min to max.

r_Init

r_Init

Initializes the random number generator. Happens optionally in LeGo_Init.

func void r_Init(var int seed)
 
Parameters

r_DefaultInit

r_DefaultInit

Initializes the random number generator based on the current time.

func void r_DefaultInit()
-
\ No newline at end of file +
\ 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 index e73dd51aaa..97b9e1a5d6 100644 --- a/cs/zengin/scripts/extenders/lego/tools/string_builder/index.html +++ b/cs/zengin/scripts/extenders/lego/tools/string_builder/index.html @@ -152,4 +152,4 @@ return str; }; -
\ No newline at end of file +
\ 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 index 9f6b02e131..9d1ad2421f 100644 --- a/cs/zengin/scripts/extenders/lego/tools/talents/index.html +++ b/cs/zengin/scripts/extenders/lego/tools/talents/index.html @@ -37,4 +37,4 @@ Parameters

Return value

The function returns NPC pointer.

TAL_CreateTalent

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

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

TAL_GetValue

TAL_GetValue

Returns the value of a saved talent for specified NPC.

func int TAL_GetValue(var C_NPC npc, var int talent)
-
Parameters
\ No newline at end of file + Parameters
\ 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 index dfa7b3687b..0529adae04 100644 --- a/cs/zengin/scripts/extenders/lego/tools/timer/index.html +++ b/cs/zengin/scripts/extenders/lego/tools/timer/index.html @@ -38,4 +38,4 @@ Return value

The function returns current playing time as an Ikarus float value.

Timer_SetPause

Timer_SetPause

Pauses the timer (and thus all FrameFunctions and running animations).

func void Timer_SetPause(var int on)
 
Parameters

Timer_SetPauseInMenu

Timer_SetPauseInMenu

The timer can automatically pause when the game is paused. (status screen, main menu...)

func void Timer_SetPauseInMenu(var int on)
 
Parameters

Timer_IsPaused

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 + 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 index d997a82b11..e85e4f90fa 100644 --- a/cs/zengin/scripts/extenders/lego/tools/view/index.html +++ b/cs/zengin/scripts/extenders/lego/tools/view/index.html @@ -81,4 +81,4 @@ 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 +

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/standalone/gameKeyEvents/index.html b/cs/zengin/scripts/extenders/standalone/gameKeyEvents/index.html index 832e1f224b..456ce947c3 100644 --- a/cs/zengin/scripts/extenders/standalone/gameKeyEvents/index.html +++ b/cs/zengin/scripts/extenders/standalone/gameKeyEvents/index.html @@ -45,4 +45,4 @@ }; return FALSE; }; -
\ No newline at end of file +
\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/standalone/index.html b/cs/zengin/scripts/extenders/standalone/index.html index 65a4ee031c..820e3ddc3f 100644 --- a/cs/zengin/scripts/extenders/standalone/index.html +++ b/cs/zengin/scripts/extenders/standalone/index.html @@ -31,4 +31,4 @@ const gGMC_PAGE_LOCALE = "cs"; const gGMC_FILE_LOCALE = "en"; const gGMC_TRANSLATE_SVG = ''; -

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 +

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 index f5ef786290..5c9b2c6b23 100644 --- a/cs/zengin/scripts/extenders/standalone/setBarPositions/index.html +++ b/cs/zengin/scripts/extenders/standalone/setBarPositions/index.html @@ -138,4 +138,4 @@ return x | (y << 14); }; -
\ No newline at end of file +
\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/zparserextender/classes/c_trigger/index.html b/cs/zengin/scripts/extenders/zparserextender/classes/c_trigger/index.html index 5dc0465e23..920fccd244 100644 --- a/cs/zengin/scripts/extenders/zparserextender/classes/c_trigger/index.html +++ b/cs/zengin/scripts/extenders/zparserextender/classes/c_trigger/index.html @@ -142,4 +142,4 @@ trigger = AI_GetNextTriggerBySelf(hero); trigger_saved.Enabled = false; }; -
\ No newline at end of file +
\ 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 index 5cf21a930d..b269b02e03 100644 --- a/cs/zengin/scripts/extenders/zparserextender/classes/helperclasses/index.html +++ b/cs/zengin/scripts/extenders/zparserextender/classes/helperclasses/index.html @@ -387,4 +387,4 @@ /// @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 +
\ 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 index 9e4bf7d75c..0f648da86d 100644 --- a/cs/zengin/scripts/extenders/zparserextender/daedalus_injection/hooks/index.html +++ b/cs/zengin/scripts/extenders/zparserextender/daedalus_injection/hooks/index.html @@ -81,4 +81,4 @@ DIA_XARDAS_HELLO_old(); important = FALSE; }; -
\ No newline at end of file +
\ 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 index 192fdd0be5..43e256b226 100644 --- a/cs/zengin/scripts/extenders/zparserextender/daedalus_injection/index.html +++ b/cs/zengin/scripts/extenders/zparserextender/daedalus_injection/index.html @@ -31,4 +31,4 @@ const gGMC_PAGE_LOCALE = "cs"; const gGMC_FILE_LOCALE = "en"; const gGMC_TRANSLATE_SVG = ''; -

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 +

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 index e96d7d3416..24f9f18de0 100644 --- a/cs/zengin/scripts/extenders/zparserextender/daedalus_injection/meta/index.html +++ b/cs/zengin/scripts/extenders/zparserextender/daedalus_injection/meta/index.html @@ -92,4 +92,4 @@ 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 +
\ 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 index 2caf7e17e8..40c2b3e32f 100644 --- a/cs/zengin/scripts/extenders/zparserextender/daedalus_injection/other/index.html +++ b/cs/zengin/scripts/extenders/zparserextender/daedalus_injection/other/index.html @@ -119,4 +119,4 @@ { 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 +

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/examples/signposts/index.html b/cs/zengin/scripts/extenders/zparserextender/examples/signposts/index.html index b3a32b3d54..9797f77372 100644 --- a/cs/zengin/scripts/extenders/zparserextender/examples/signposts/index.html +++ b/cs/zengin/scripts/extenders/zparserextender/examples/signposts/index.html @@ -364,4 +364,4 @@ Finally, we advance the index to jump to another signpost.
// advance the index
 tp_index += 1;
-
\ No newline at end of file +
\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/zparserextender/externals/ai/index.html b/cs/zengin/scripts/extenders/zparserextender/externals/ai/index.html index 3b1b723250..914ad83dca 100644 --- a/cs/zengin/scripts/extenders/zparserextender/externals/ai/index.html +++ b/cs/zengin/scripts/extenders/zparserextender/externals/ai/index.html @@ -63,4 +63,4 @@ var C_NPC self, var C_NPC other, var C_NPC victim) {}; -
\ No newline at end of file +
\ 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 index 3fcb2b14e0..e3fc7ed266 100644 --- a/cs/zengin/scripts/extenders/zparserextender/externals/cast/index.html +++ b/cs/zengin/scripts/extenders/zparserextender/externals/cast/index.html @@ -42,4 +42,4 @@

Cast_GetClassID

Cast_GetClassID

Returns the class identifier of a class by its name

func int Cast_GetClassID( var string className ) {};
 

Cast_GetVobClassID

Cast_GetVobClassID

Returns class identifier of the zCObject vob class

func int Cast_GetVobClassID( var instance object ) {};
 

Cast_CheckVobClassID

Cast_CheckVobClassID

Checks if the classId class is the parent class of the object

func int Cast_CheckVobClassID( var int classId, var instance object ) {};
-
\ No newline at end of file +
\ 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 index 9dd70fd7a7..d9fadbf4f2 100644 --- a/cs/zengin/scripts/extenders/zparserextender/externals/events_vars/index.html +++ b/cs/zengin/scripts/extenders/zparserextender/externals/events_vars/index.html @@ -52,4 +52,4 @@ /// not a number floating point constant const float NaN; -
\ No newline at end of file +
\ 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 index 05d1f2a73d..5740c28d44 100644 --- a/cs/zengin/scripts/extenders/zparserextender/externals/hlp/index.html +++ b/cs/zengin/scripts/extenders/zparserextender/externals/hlp/index.html @@ -85,4 +85,4 @@

Hlp_WriteOptionString

Hlp_WriteOptionString

Writes a string value to specified .ini file, section and entry.

optName values

func void Hlp_WriteOptionString(var string optName, var string section, var string entry, var string value) {};
 

Hlp_GetSteamPersonalName

Hlp_GetSteamPersonalName

Returns the name of the current Steam user Returns empty string when not run with Steam

func string Hlp_GetSteamPersonalName() {};
 

Hlp_DoEvent

Hlp_DoEvent

Calls every event function with the name funcName.

func void Hlp_DoEvent(var string funcName) {};
-
\ No newline at end of file +
\ 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 index cd73030e2a..ec0340ff88 100644 --- a/cs/zengin/scripts/extenders/zparserextender/externals/log/index.html +++ b/cs/zengin/scripts/extenders/zparserextender/externals/log/index.html @@ -33,4 +33,4 @@ const gGMC_TRANSLATE_SVG = '';

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

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

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 +
\ 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 index b32e9403e2..c51e2cbaae 100644 --- a/cs/zengin/scripts/extenders/zparserextender/externals/mdl/index.html +++ b/cs/zengin/scripts/extenders/zparserextender/externals/mdl/index.html @@ -43,4 +43,4 @@

Mdl_ApplyOverlayMds_AtFirst

Mdl_ApplyOverlayMds_AtFirst

Applies or moves existing overlay to the top of the list

func void Mdl_ApplyOverlayMds_AtFirst( var string mdsName ) {};
 

Mdl_SetNpcSpeedMultiplier

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 ) {};
 

Mdl_ResetNpcSpeedMultiplier

Mdl_ResetNpcSpeedMultiplier

Resets the animation speed of an NPC

func void Mdl_ResetNpcSpeedMultiplier( var C_Npc npc ) {};
-
\ No newline at end of file +
\ 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 index 7bd91d5f96..5f6c9d88cc 100644 --- a/cs/zengin/scripts/extenders/zparserextender/externals/menu/index.html +++ b/cs/zengin/scripts/extenders/zparserextender/externals/menu/index.html @@ -53,4 +53,4 @@ 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 +

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 index 0223a0a5b0..f956d9295f 100644 --- a/cs/zengin/scripts/extenders/zparserextender/externals/mob/index.html +++ b/cs/zengin/scripts/extenders/zparserextender/externals/mob/index.html @@ -42,4 +42,4 @@

Mob_SetLocked

Mob_SetLocked

Set the lock status of the object

func void Mob_SetLocked( var instance object, var int locked ) {};
 

Mob_GetKeyInstance

Mob_GetKeyInstance

Returns the key instance, that unlocks the object

func instance Mob_GetKeyInstance( var instance object ) {};
 

Mob_SetKeyInstance

Mob_SetKeyInstance

Stets the key instance, that unlocks the object

func void Mob_SetKeyInstance( var instance object, var int key ) {};
-
\ No newline at end of file +
\ 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 index 051d6ad872..6b82947c5c 100644 --- a/cs/zengin/scripts/extenders/zparserextender/externals/npc/index.html +++ b/cs/zengin/scripts/extenders/zparserextender/externals/npc/index.html @@ -40,4 +40,4 @@

Npc_GetSlotItem

Npc_GetSlotItem

Returns an item from a slot with the slotName

func C_Item Npc_GetSlotItem( var C_Npc npc, var string slotName ) {};
 

Npc_PutInSlot

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_RemoveFromSlot

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) {};
-
\ No newline at end of file +
\ 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 index 3d836741a5..40235caa3e 100644 --- a/cs/zengin/scripts/extenders/zparserextender/externals/par/index.html +++ b/cs/zengin/scripts/extenders/zparserextender/externals/par/index.html @@ -48,4 +48,4 @@

Par_SetSymbolValueIntArray

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) {};
 

Par_SetSymbolValueFloatArray

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) {};
 

Par_SetSymbolValueStringArray

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) {};
-
\ No newline at end of file +
\ 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 index 03fafa2404..9b384c63b1 100644 --- a/cs/zengin/scripts/extenders/zparserextender/externals/string/index.html +++ b/cs/zengin/scripts/extenders/zparserextender/externals/string/index.html @@ -74,4 +74,4 @@

Str_UTF8_to_ANSI

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 ) {};
 

Str_GetCurrentCP

Str_GetCurrentCP

Return the code page corresponding to the current language set in the Union System

func int Str_GetCurrentCP() {};
 

Str_GetLength

Str_GetLength

Returns the length of a string

func int Str_GetLength( var int str ) {};
-
\ No newline at end of file +
\ 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 index 415c6aa573..1c23b89967 100644 --- a/cs/zengin/scripts/extenders/zparserextender/externals/vob/index.html +++ b/cs/zengin/scripts/extenders/zparserextender/externals/vob/index.html @@ -52,4 +52,4 @@

Vob_SetMobInterData

Vob_SetMobInterData

Sets the data of the oCMobInter object

func void Vob_SetMobInterData( var C_Vob mobInter, var C_MobInter_Data data ) {};
 

Vob_GetMobInterData

Vob_GetMobInterData

Returns the data of the oCMobLockable object

func C_MobLockable_Data Vob_GetMobInterData( var C_Vob mobLock ) {};
 

Vob_SetMobInterData

Vob_SetMobInterData

Sets the data of the oCMobLockable object

func void Vob_SetMobInterData( var C_Vob mobLock, var C_MobLockable_Data data ) {};
-
\ No newline at end of file +
\ 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 index 98c23a5056..4b0993ed64 100644 --- a/cs/zengin/scripts/extenders/zparserextender/externals/wld/index.html +++ b/cs/zengin/scripts/extenders/zparserextender/externals/wld/index.html @@ -58,4 +58,4 @@

Wld_ToggleRain

Wld_ToggleRain

Turns on the rain

func void Wld_ToggleRain( var float weight, var float time ) {};
 

Wld_SetWeatherType

Wld_SetWeatherType

Sets the weather type. Types:

0 - snow 1 - rain

func void Wld_SetWeatherType( var int type ) {};
 

Wld_GetWeatherType

Wld_GetWeatherType

Returns the weather type. Types:

0 - snow 1 - rain

func int Wld_GetWeatherType() {};
-
\ No newline at end of file +
\ No newline at end of file diff --git a/cs/zengin/scripts/extenders/zparserextender/index.html b/cs/zengin/scripts/extenders/zparserextender/index.html index cd3e291b2f..32785db319 100644 --- a/cs/zengin/scripts/extenders/zparserextender/index.html +++ b/cs/zengin/scripts/extenders/zparserextender/index.html @@ -31,4 +31,4 @@ const gGMC_PAGE_LOCALE = "cs"; const gGMC_FILE_LOCALE = "en"; const gGMC_TRANSLATE_SVG = ''; -

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 +

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/syntax_extensions/dialogues/index.html b/cs/zengin/scripts/extenders/zparserextender/syntax_extensions/dialogues/index.html index 2373ceafb6..04afc9a343 100644 --- a/cs/zengin/scripts/extenders/zparserextender/syntax_extensions/dialogues/index.html +++ b/cs/zengin/scripts/extenders/zparserextender/syntax_extensions/dialogues/index.html @@ -50,4 +50,4 @@ 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 +
\ 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 index 91041a97a9..3c28d79aab 100644 --- a/cs/zengin/scripts/extenders/zparserextender/syntax_extensions/events/index.html +++ b/cs/zengin/scripts/extenders/zparserextender/syntax_extensions/events/index.html @@ -54,4 +54,4 @@ // 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

Define these in any file in your scripts, they will be automatically called

\ No newline at end of file +

Plugin implements two of these event functions

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 index 56e14f853b..ebe77ba1c5 100644 --- a/cs/zengin/scripts/extenders/zparserextender/syntax_extensions/extern/index.html +++ b/cs/zengin/scripts/extenders/zparserextender/syntax_extensions/extern/index.html @@ -38,4 +38,4 @@ { // TODO }; -
\ No newline at end of file +
\ 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 index 3a9f5eec82..45978fbbd7 100644 --- a/cs/zengin/scripts/extenders/zparserextender/syntax_extensions/namespaces/index.html +++ b/cs/zengin/scripts/extenders/zparserextender/syntax_extensions/namespaces/index.html @@ -295,4 +295,4 @@ 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 + 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 index 43ed12b8b5..0802a0bac5 100644 --- a/cs/zengin/scripts/extenders/zparserextender/syntax_extensions/testelse/index.html +++ b/cs/zengin/scripts/extenders/zparserextender/syntax_extensions/testelse/index.html @@ -47,4 +47,4 @@ { // TODO } -
\ No newline at end of file +
\ 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 index 4d1a9dcd92..796e4c86c5 100644 --- a/cs/zengin/scripts/extenders/zparserextender/syntax_extensions/while/index.html +++ b/cs/zengin/scripts/extenders/zparserextender/syntax_extensions/while/index.html @@ -59,4 +59,4 @@

Note

To activate while it is necessary to set NativeWhile setting in SystemPack.ini

[ZPARSE_EXTENDER]
 NativeWhile = true
-

Compiled while loop works in vanilla engine without the plugin.

\ No newline at end of file +

Compiled while loop works in vanilla engine without the plugin.

\ No newline at end of file diff --git a/cs/zengin/scripts/externals/doc/index.html b/cs/zengin/scripts/externals/doc/index.html index 04268e596a..dcda6240c3 100644 --- a/cs/zengin/scripts/externals/doc/index.html +++ b/cs/zengin/scripts/externals/doc/index.html @@ -296,4 +296,4 @@ var float r6, var float r7, var float r8) {}; -
\ No newline at end of file +
\ No newline at end of file diff --git a/cs/zengin/scripts/externals/index.html b/cs/zengin/scripts/externals/index.html index 224b1c660d..f79b66db3e 100644 --- a/cs/zengin/scripts/externals/index.html +++ b/cs/zengin/scripts/externals/index.html @@ -31,4 +31,4 @@ const gGMC_PAGE_LOCALE = "cs"; const gGMC_FILE_LOCALE = "en"; const gGMC_TRANSLATE_SVG = ''; -

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 +

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 index 4ebc6b96cd..997277b7a8 100644 --- a/cs/zengin/scripts/externals/log/index.html +++ b/cs/zengin/scripts/externals/log/index.html @@ -84,4 +84,4 @@ /// @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 +
\ No newline at end of file diff --git a/cs/zengin/scripts/externals/mdl/index.html b/cs/zengin/scripts/externals/mdl/index.html index 303b5c4824..65acbc6c35 100644 --- a/cs/zengin/scripts/externals/mdl/index.html +++ b/cs/zengin/scripts/externals/mdl/index.html @@ -278,4 +278,4 @@ var float timemax, var float timemaxvar, var float probmin) {}; -
\ No newline at end of file +
\ No newline at end of file diff --git a/cs/zengin/sound/index.html b/cs/zengin/sound/index.html index f2a7e36ad5..d3e2f3690a 100644 --- a/cs/zengin/sound/index.html +++ b/cs/zengin/sound/index.html @@ -32,4 +32,4 @@ const gGMC_FILE_LOCALE = "en"; const gGMC_TRANSLATE_SVG = '';

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 + 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 index 52dfdebb71..859f56c5c7 100644 --- a/cs/zengin/sound/tutorials/change_sfx/index.html +++ b/cs/zengin/sound/tutorials/change_sfx/index.html @@ -31,4 +31,4 @@ const gGMC_PAGE_LOCALE = "cs"; const gGMC_FILE_LOCALE = "en"; const gGMC_TRANSLATE_SVG = ''; -

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 +

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/tools/gothic_sourcer/index.html b/cs/zengin/tools/gothic_sourcer/index.html index ebe145996c..a8215c2be4 100644 --- a/cs/zengin/tools/gothic_sourcer/index.html +++ b/cs/zengin/tools/gothic_sourcer/index.html @@ -31,4 +31,4 @@ const gGMC_PAGE_LOCALE = "cs"; const gGMC_FILE_LOCALE = "en"; const gGMC_TRANSLATE_SVG = ''; -

Gothic Sourcer

Gothic Sourcer can be used to do a lot of things.

Todo

TODO

\ No newline at end of file +

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/index.html b/cs/zengin/tools/index.html index 4a936f4794..b737e5c19c 100644 --- a/cs/zengin/tools/index.html +++ b/cs/zengin/tools/index.html @@ -31,4 +31,4 @@ const gGMC_PAGE_LOCALE = "cs"; const gGMC_FILE_LOCALE = "en"; const gGMC_TRANSLATE_SVG = ''; -

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.
  • DecDat - Daedalus .DAT files decompiler.
  • Redefix - OutputUnits compiler and updater.

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.

Libraries

  • ZenKit - A library to load, save and use almost all ZenGin asset files

Debugging

  • zSpy - Debugging tool that displays most of the operations performed by the engine during the Gothic or Spacer running, ships with the MDK.
\ No newline at end of file +

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.
  • DecDat - Daedalus .DAT files decompiler.
  • Redefix - OutputUnits compiler and updater.

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.

Libraries

  • ZenKit - A library to load, save and use almost all ZenGin asset files

Debugging

  • zSpy - Debugging tool that displays most of the operations performed by the engine during the Gothic or Spacer running, ships with the MDK.
\ No newline at end of file diff --git a/cs/zengin/tools/zSplitDialogs/index.html b/cs/zengin/tools/zSplitDialogs/index.html index 763c5297c6..89b15c5cc2 100644 --- a/cs/zengin/tools/zSplitDialogs/index.html +++ b/cs/zengin/tools/zSplitDialogs/index.html @@ -34,4 +34,4 @@

zSplitDialogs

The plugin for a dubbing creators. And not only.

Union plugin by Top Layer, which gives possibility to extract dialogues from compiled scripts simply by putting zSplitDialogs.vdf file into Data\ directory and run the game. You can configure, that already dubbed subtitles will be outputed.

The output is the Dialogs\ directory with .txt files with a structure as follow:

Example of a plugin output

zSpy

Download

Source code

The usage

  • Install Union 1.0l+ (zParserExtender is needed - it is inside Union since 1.0l version)
  • Put zSplitDialogs.vdf into Data\ directory
  • Start game
  • Dialogues will be created in Dialogs\ directory

At first run, in gothic.ini will be created following section:

[ZSPLITDIALOGS]
 UnvoicedOnly=0
-

You can change value to 1 to receive only unvoiced subtitles.

\ No newline at end of file +

You can change value to 1 to receive only unvoiced subtitles.

\ No newline at end of file diff --git a/cs/zengin/tools/zSpy/index.html b/cs/zengin/tools/zSpy/index.html index 39ff7e3013..b3c11f6571 100644 --- a/cs/zengin/tools/zSpy/index.html +++ b/cs/zengin/tools/zSpy/index.html @@ -46,4 +46,4 @@ 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 +
\ No newline at end of file diff --git a/feed_rss_created.xml b/feed_rss_created.xml index e268c344cd..95485b3c14 100644 --- a/feed_rss_created.xml +++ b/feed_rss_created.xml @@ -1 +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:20:39 -0000 Sun, 30 Jun 2024 18:20:39 -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 + 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:22:54 -0000 Sun, 30 Jun 2024 18:22:54 -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 index 333f596431..957b8cb231 100644 --- a/feed_rss_updated.xml +++ b/feed_rss_updated.xml @@ -1 +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:20:39 -0000 Sun, 30 Jun 2024 18:20:39 -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 + 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:22:54 -0000 Sun, 30 Jun 2024 18:22:54 -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:21:29 +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:21:29 +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:21:29 +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 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/ 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/ 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/pl/blog/community-news/introducing-community-posts/index.html b/pl/blog/community-news/introducing-community-posts/index.html index 72c9024c6d..96eeb9643c 100644 --- a/pl/blog/community-news/introducing-community-posts/index.html +++ b/pl/blog/community-news/introducing-community-posts/index.html @@ -31,7 +31,7 @@ const gGMC_PAGE_LOCALE = "pl"; const gGMC_FILE_LOCALE = "en"; const gGMC_TRANSLATE_SVG = ''; -

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!

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 +
\ 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 index 8bb67ac5c1..ecdd2aaee5 100644 --- a/pl/zengin/scripts/extenders/lego/tools/event_handler/index.html +++ b/pl/zengin/scripts/extenders/lego/tools/event_handler/index.html @@ -52,4 +52,4 @@ Parameters

EventPtr_Remove

EventPtr_Remove

Removes a function from the event's call list.

func void EventPtr_Remove(var int eventPtr, var func function)
 
Parameters

EventPtr_RemoveI

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

EventPtr_Execute

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)
-

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 +

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 index d9733af03e..fe319d66f3 100644 --- a/pl/zengin/scripts/extenders/lego/tools/frame_functions/index.html +++ b/pl/zengin/scripts/extenders/lego/tools/frame_functions/index.html @@ -116,4 +116,4 @@ { 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 + 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 index be3915eb2f..3c0951600e 100644 --- a/pl/zengin/scripts/extenders/lego/tools/hashtables/index.html +++ b/pl/zengin/scripts/extenders/lego/tools/hashtables/index.html @@ -143,4 +143,4 @@ // Destroy the hashtable HT_Destroy(hashtableHandle); }; -
\ No newline at end of file +
\ 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 index 985034303d..a07d108c20 100644 --- a/pl/zengin/scripts/extenders/lego/tools/hook_dae/index.html +++ b/pl/zengin/scripts/extenders/lego/tools/hook_dae/index.html @@ -241,4 +241,4 @@ // -- B: 3 // <- C: 2 // <- D: 1 -
\ No newline at end of file +
\ 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 index fc485d458b..ac79665065 100644 --- a/pl/zengin/scripts/extenders/lego/tools/hook_engine/index.html +++ b/pl/zengin/scripts/extenders/lego/tools/hook_engine/index.html @@ -63,4 +63,4 @@ var int EBP; var int ESI; var int EDI; -
\ No newline at end of file +
\ 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 index 9752ef59f1..25dda38357 100644 --- a/pl/zengin/scripts/extenders/lego/tools/int64/index.html +++ b/pl/zengin/scripts/extenders/lego/tools/int64/index.html @@ -55,4 +55,4 @@ Parameters

sub64

sub64

Subtracts src from dest: *dest <- *dest - *src

func void sub64(var int dest, var int src)
 
Parameters

mul64

mul64

Multiplies dest by src: *dest <- (*dest) * (*src)

func void mul64(var int dest, var int src)
 
Parameters

div64

div64

Divides dest by src: *dest <- *dest / *src

func void mul64(var int dest, var int src)
-
Parameters
\ No newline at end of file + Parameters
\ 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 index c9440efbcb..15e5526142 100644 --- a/pl/zengin/scripts/extenders/lego/tools/interface/index.html +++ b/pl/zengin/scripts/extenders/lego/tools/interface/index.html @@ -246,4 +246,4 @@ // Since Anim8 does the deleting itself, we don't have to worry about that. }; -
\ No newline at end of file +
\ 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 index eeffea09ed..e084683595 100644 --- a/pl/zengin/scripts/extenders/lego/tools/list/index.html +++ b/pl/zengin/scripts/extenders/lego/tools/list/index.html @@ -57,4 +57,4 @@ Parameters:

Return Value:

The function returns TRUE if data1 is greater than data2, FALSE is returned otherwise.

List_CmpDescending

List_CmpDescending

Compares two integer values in descending order.

func int List_CmpDescending(var int data1, var int data2)
 
Parameters:

Return Value:

The function returns TRUE if data1 is less than data2, FALSE is returned otherwise.

List_CmpAscendingUnsigned

List_CmpAscendingUnsigned

Compares two unsigned integer values in ascending order.

func int List_CmpAscendingUnsigned(var int data1, var int data2)
 
Parameters:

Return Value:

The function returns TRUE if data1 is greater than data2, FALSE is returned otherwise.

List_CmpDescendingUnsigned

List_CmpDescendingUnsigned

Compares two unsigned integer values in descending order.

func int List_CmpDescendingUnsigned(var int data1, var int data2)
-
Parameters:

Return Value:

The function returns TRUE if data1 is less than data2, FALSE is returned otherwise.

\ No newline at end of file + Parameters:

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 index 8f984523e0..226060c2d5 100644 --- a/pl/zengin/scripts/extenders/lego/tools/locals/index.html +++ b/pl/zengin/scripts/extenders/lego/tools/locals/index.html @@ -48,4 +48,4 @@ }; MEM_InfoBox("This will appear before Final"); }; - Few lines of code say more than a thousand words.
\ No newline at end of file + 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/permmem/index.html b/pl/zengin/scripts/extenders/lego/tools/permmem/index.html index 5618ea127e..8f37d6dc42 100644 --- a/pl/zengin/scripts/extenders/lego/tools/permmem/index.html +++ b/pl/zengin/scripts/extenders/lego/tools/permmem/index.html @@ -83,4 +83,4 @@ Parameters

PM_LoadArray

PM_LoadArray

Returns a pointer to array stored in the archive.

func int PM_LoadArray(var string name)
 
Parameters

PM_LoadArrayToPtr

PM_LoadArrayToPtr

Loads a pointer to array from the archive to destPtr.

func void PM_LoadArrayToPtr(var string name, var int destPtr)
 
Parameters

PM_LoadToPtr

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
\ No newline at end of file + Parameters
\ 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 index 33373a5165..7b77107aab 100644 --- a/pl/zengin/scripts/extenders/lego/tools/queue/index.html +++ b/pl/zengin/scripts/extenders/lego/tools/queue/index.html @@ -45,4 +45,4 @@ Parameters

CQ_IsEmpty

CQ_IsEmpty

Checks if no function is in the callback queue.

func int CQ_IsEmpty(var int queue)
 
Parameters

Return value

The function returns TRUE if the callback queue is empty, FALSE is returned otherwise.

CQ_Advance

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

CQ_Exhaust

CQ_Exhaust

Executes all functions contained in the callback queue.

func void CQ_Exhaust(var int queue)
-
Parameters
\ No newline at end of file + Parameters
\ 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 index 2745ea2a8c..7e6e21229c 100644 --- a/pl/zengin/scripts/extenders/lego/tools/random/index.html +++ b/pl/zengin/scripts/extenders/lego/tools/random/index.html @@ -37,4 +37,4 @@ Parameters

Return value

The function returns a random number from 0 to 'max'.

r_MinMax

r_MinMax

Returns a random number from 'min' to 'max'.

func int r_MinMax(var int min, var int max)
 
Parameters

Return value

The function returns a random number from min to max.

r_Init

r_Init

Initializes the random number generator. Happens optionally in LeGo_Init.

func void r_Init(var int seed)
 
Parameters

r_DefaultInit

r_DefaultInit

Initializes the random number generator based on the current time.

func void r_DefaultInit()
-
\ No newline at end of file +
\ 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 index 6434254541..a959dd6236 100644 --- a/pl/zengin/scripts/extenders/lego/tools/string_builder/index.html +++ b/pl/zengin/scripts/extenders/lego/tools/string_builder/index.html @@ -152,4 +152,4 @@ return str; }; -
\ No newline at end of file +
\ 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 index 8965dcc7c7..72835540be 100644 --- a/pl/zengin/scripts/extenders/lego/tools/timer/index.html +++ b/pl/zengin/scripts/extenders/lego/tools/timer/index.html @@ -38,4 +38,4 @@ Return value

The function returns current playing time as an Ikarus float value.

Timer_SetPause

Timer_SetPause

Pauses the timer (and thus all FrameFunctions and running animations).

func void Timer_SetPause(var int on)
 
Parameters

Timer_SetPauseInMenu

Timer_SetPauseInMenu

The timer can automatically pause when the game is paused. (status screen, main menu...)

func void Timer_SetPauseInMenu(var int on)
 
Parameters

Timer_IsPaused

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 + 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 index c237eb3127..08704d6931 100644 --- a/pl/zengin/scripts/extenders/lego/tools/view/index.html +++ b/pl/zengin/scripts/extenders/lego/tools/view/index.html @@ -81,4 +81,4 @@ 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 +

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/standalone/gameKeyEvents/index.html b/pl/zengin/scripts/extenders/standalone/gameKeyEvents/index.html index b65ab9278d..f67ded1a0f 100644 --- a/pl/zengin/scripts/extenders/standalone/gameKeyEvents/index.html +++ b/pl/zengin/scripts/extenders/standalone/gameKeyEvents/index.html @@ -45,4 +45,4 @@ }; return FALSE; }; -
\ No newline at end of file +
\ 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 index 47755e3826..fe8aa5b554 100644 --- a/pl/zengin/scripts/extenders/standalone/setBarPositions/index.html +++ b/pl/zengin/scripts/extenders/standalone/setBarPositions/index.html @@ -138,4 +138,4 @@ return x | (y << 14); }; -
\ No newline at end of file +
\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/zparserextender/classes/c_trigger/index.html b/pl/zengin/scripts/extenders/zparserextender/classes/c_trigger/index.html index 4f5aa4ed95..d3ccca9061 100644 --- a/pl/zengin/scripts/extenders/zparserextender/classes/c_trigger/index.html +++ b/pl/zengin/scripts/extenders/zparserextender/classes/c_trigger/index.html @@ -142,4 +142,4 @@ trigger = AI_GetNextTriggerBySelf(hero); trigger_saved.Enabled = false; }; -
\ No newline at end of file +
\ 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 index 4173fd4015..55ebc28f38 100644 --- a/pl/zengin/scripts/extenders/zparserextender/classes/helperclasses/index.html +++ b/pl/zengin/scripts/extenders/zparserextender/classes/helperclasses/index.html @@ -387,4 +387,4 @@ /// @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 +
\ 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 index 9ab77b0f94..bc87c006c0 100644 --- a/pl/zengin/scripts/extenders/zparserextender/daedalus_injection/hooks/index.html +++ b/pl/zengin/scripts/extenders/zparserextender/daedalus_injection/hooks/index.html @@ -81,4 +81,4 @@ DIA_XARDAS_HELLO_old(); important = FALSE; }; -
\ No newline at end of file +
\ 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 index a4652250ed..0e9b316519 100644 --- a/pl/zengin/scripts/extenders/zparserextender/daedalus_injection/index.html +++ b/pl/zengin/scripts/extenders/zparserextender/daedalus_injection/index.html @@ -31,4 +31,4 @@ const gGMC_PAGE_LOCALE = "pl"; const gGMC_FILE_LOCALE = "en"; const gGMC_TRANSLATE_SVG = ''; -

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 +

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 index d3f5f8e270..2a956789f3 100644 --- a/pl/zengin/scripts/extenders/zparserextender/daedalus_injection/meta/index.html +++ b/pl/zengin/scripts/extenders/zparserextender/daedalus_injection/meta/index.html @@ -92,4 +92,4 @@ 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 +
\ 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 index c53a16c642..34a8c84770 100644 --- a/pl/zengin/scripts/extenders/zparserextender/daedalus_injection/other/index.html +++ b/pl/zengin/scripts/extenders/zparserextender/daedalus_injection/other/index.html @@ -119,4 +119,4 @@ { 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 +

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/examples/signposts/index.html b/pl/zengin/scripts/extenders/zparserextender/examples/signposts/index.html index 415dad315a..b4ec7ab4f0 100644 --- a/pl/zengin/scripts/extenders/zparserextender/examples/signposts/index.html +++ b/pl/zengin/scripts/extenders/zparserextender/examples/signposts/index.html @@ -364,4 +364,4 @@ Finally, we advance the index to jump to another signpost.
// advance the index
 tp_index += 1;
-
\ No newline at end of file +
\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/zparserextender/externals/ai/index.html b/pl/zengin/scripts/extenders/zparserextender/externals/ai/index.html index 32481f71e9..2efacb8696 100644 --- a/pl/zengin/scripts/extenders/zparserextender/externals/ai/index.html +++ b/pl/zengin/scripts/extenders/zparserextender/externals/ai/index.html @@ -63,4 +63,4 @@ var C_NPC self, var C_NPC other, var C_NPC victim) {}; -
\ No newline at end of file +
\ 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 index 42d579e21d..a63e2771e9 100644 --- a/pl/zengin/scripts/extenders/zparserextender/externals/cast/index.html +++ b/pl/zengin/scripts/extenders/zparserextender/externals/cast/index.html @@ -42,4 +42,4 @@

Cast_GetClassID

Cast_GetClassID

Returns the class identifier of a class by its name

func int Cast_GetClassID( var string className ) {};
 

Cast_GetVobClassID

Cast_GetVobClassID

Returns class identifier of the zCObject vob class

func int Cast_GetVobClassID( var instance object ) {};
 

Cast_CheckVobClassID

Cast_CheckVobClassID

Checks if the classId class is the parent class of the object

func int Cast_CheckVobClassID( var int classId, var instance object ) {};
-
\ No newline at end of file +
\ 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 index 34acdf4398..915d70da8b 100644 --- a/pl/zengin/scripts/extenders/zparserextender/externals/events_vars/index.html +++ b/pl/zengin/scripts/extenders/zparserextender/externals/events_vars/index.html @@ -52,4 +52,4 @@ /// not a number floating point constant const float NaN; -
\ No newline at end of file +
\ 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 index 06745a906b..8cbf5639da 100644 --- a/pl/zengin/scripts/extenders/zparserextender/externals/hlp/index.html +++ b/pl/zengin/scripts/extenders/zparserextender/externals/hlp/index.html @@ -85,4 +85,4 @@

Hlp_WriteOptionString

Hlp_WriteOptionString

Writes a string value to specified .ini file, section and entry.

optName values

func void Hlp_WriteOptionString(var string optName, var string section, var string entry, var string value) {};
 

Hlp_GetSteamPersonalName

Hlp_GetSteamPersonalName

Returns the name of the current Steam user Returns empty string when not run with Steam

func string Hlp_GetSteamPersonalName() {};
 

Hlp_DoEvent

Hlp_DoEvent

Calls every event function with the name funcName.

func void Hlp_DoEvent(var string funcName) {};
-
\ No newline at end of file +
\ 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 index 517ef472c8..4ff3376656 100644 --- a/pl/zengin/scripts/extenders/zparserextender/externals/log/index.html +++ b/pl/zengin/scripts/extenders/zparserextender/externals/log/index.html @@ -33,4 +33,4 @@ const gGMC_TRANSLATE_SVG = '';

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

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

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 +
\ 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 index 295443d43f..b7d7420e35 100644 --- a/pl/zengin/scripts/extenders/zparserextender/externals/mdl/index.html +++ b/pl/zengin/scripts/extenders/zparserextender/externals/mdl/index.html @@ -43,4 +43,4 @@

Mdl_ApplyOverlayMds_AtFirst

Mdl_ApplyOverlayMds_AtFirst

Applies or moves existing overlay to the top of the list

func void Mdl_ApplyOverlayMds_AtFirst( var string mdsName ) {};
 

Mdl_SetNpcSpeedMultiplier

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 ) {};
 

Mdl_ResetNpcSpeedMultiplier

Mdl_ResetNpcSpeedMultiplier

Resets the animation speed of an NPC

func void Mdl_ResetNpcSpeedMultiplier( var C_Npc npc ) {};
-
\ No newline at end of file +
\ 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 index dec5df0317..1c0fab5f70 100644 --- a/pl/zengin/scripts/extenders/zparserextender/externals/menu/index.html +++ b/pl/zengin/scripts/extenders/zparserextender/externals/menu/index.html @@ -53,4 +53,4 @@ 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 +

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 index e1b04b0b04..c740823cb9 100644 --- a/pl/zengin/scripts/extenders/zparserextender/externals/mob/index.html +++ b/pl/zengin/scripts/extenders/zparserextender/externals/mob/index.html @@ -42,4 +42,4 @@

Mob_SetLocked

Mob_SetLocked

Set the lock status of the object

func void Mob_SetLocked( var instance object, var int locked ) {};
 

Mob_GetKeyInstance

Mob_GetKeyInstance

Returns the key instance, that unlocks the object

func instance Mob_GetKeyInstance( var instance object ) {};
 

Mob_SetKeyInstance

Mob_SetKeyInstance

Stets the key instance, that unlocks the object

func void Mob_SetKeyInstance( var instance object, var int key ) {};
-
\ No newline at end of file +
\ 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 index a4bfd0b095..7a86b48c8f 100644 --- a/pl/zengin/scripts/extenders/zparserextender/externals/npc/index.html +++ b/pl/zengin/scripts/extenders/zparserextender/externals/npc/index.html @@ -40,4 +40,4 @@

Npc_GetSlotItem

Npc_GetSlotItem

Returns an item from a slot with the slotName

func C_Item Npc_GetSlotItem( var C_Npc npc, var string slotName ) {};
 

Npc_PutInSlot

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_RemoveFromSlot

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) {};
-
\ No newline at end of file +
\ 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 index a5ad2c6fe5..c3ba4b9aef 100644 --- a/pl/zengin/scripts/extenders/zparserextender/externals/par/index.html +++ b/pl/zengin/scripts/extenders/zparserextender/externals/par/index.html @@ -48,4 +48,4 @@

Par_SetSymbolValueIntArray

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) {};
 

Par_SetSymbolValueFloatArray

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) {};
 

Par_SetSymbolValueStringArray

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) {};
-
\ No newline at end of file +
\ 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 index 67ab2bf0e4..ddab138992 100644 --- a/pl/zengin/scripts/extenders/zparserextender/externals/string/index.html +++ b/pl/zengin/scripts/extenders/zparserextender/externals/string/index.html @@ -74,4 +74,4 @@

Str_UTF8_to_ANSI

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 ) {};
 

Str_GetCurrentCP

Str_GetCurrentCP

Return the code page corresponding to the current language set in the Union System

func int Str_GetCurrentCP() {};
 

Str_GetLength

Str_GetLength

Returns the length of a string

func int Str_GetLength( var int str ) {};
-
\ No newline at end of file +
\ 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 index 2f7e572bbb..625ecbba46 100644 --- a/pl/zengin/scripts/extenders/zparserextender/externals/vob/index.html +++ b/pl/zengin/scripts/extenders/zparserextender/externals/vob/index.html @@ -52,4 +52,4 @@

Vob_SetMobInterData

Vob_SetMobInterData

Sets the data of the oCMobInter object

func void Vob_SetMobInterData( var C_Vob mobInter, var C_MobInter_Data data ) {};
 

Vob_GetMobInterData

Vob_GetMobInterData

Returns the data of the oCMobLockable object

func C_MobLockable_Data Vob_GetMobInterData( var C_Vob mobLock ) {};
 

Vob_SetMobInterData

Vob_SetMobInterData

Sets the data of the oCMobLockable object

func void Vob_SetMobInterData( var C_Vob mobLock, var C_MobLockable_Data data ) {};
-
\ No newline at end of file +
\ 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 index f3dbf05844..c8d3603518 100644 --- a/pl/zengin/scripts/extenders/zparserextender/externals/wld/index.html +++ b/pl/zengin/scripts/extenders/zparserextender/externals/wld/index.html @@ -58,4 +58,4 @@

Wld_ToggleRain

Wld_ToggleRain

Turns on the rain

func void Wld_ToggleRain( var float weight, var float time ) {};
 

Wld_SetWeatherType

Wld_SetWeatherType

Sets the weather type. Types:

0 - snow 1 - rain

func void Wld_SetWeatherType( var int type ) {};
 

Wld_GetWeatherType

Wld_GetWeatherType

Returns the weather type. Types:

0 - snow 1 - rain

func int Wld_GetWeatherType() {};
-
\ No newline at end of file +
\ No newline at end of file diff --git a/pl/zengin/scripts/extenders/zparserextender/index.html b/pl/zengin/scripts/extenders/zparserextender/index.html index e467a79374..f3ac474dfd 100644 --- a/pl/zengin/scripts/extenders/zparserextender/index.html +++ b/pl/zengin/scripts/extenders/zparserextender/index.html @@ -31,4 +31,4 @@ const gGMC_PAGE_LOCALE = "pl"; const gGMC_FILE_LOCALE = "en"; const gGMC_TRANSLATE_SVG = ''; -

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 +

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/syntax_extensions/dialogues/index.html b/pl/zengin/scripts/extenders/zparserextender/syntax_extensions/dialogues/index.html index e5915a2144..75ad9cdab5 100644 --- a/pl/zengin/scripts/extenders/zparserextender/syntax_extensions/dialogues/index.html +++ b/pl/zengin/scripts/extenders/zparserextender/syntax_extensions/dialogues/index.html @@ -50,4 +50,4 @@ 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 +
\ 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 index ea73aba497..011f2706ba 100644 --- a/pl/zengin/scripts/extenders/zparserextender/syntax_extensions/events/index.html +++ b/pl/zengin/scripts/extenders/zparserextender/syntax_extensions/events/index.html @@ -54,4 +54,4 @@ // 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

Define these in any file in your scripts, they will be automatically called

\ No newline at end of file +

Plugin implements two of these event functions

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 index 1d04c1ce75..c8634c1441 100644 --- a/pl/zengin/scripts/extenders/zparserextender/syntax_extensions/extern/index.html +++ b/pl/zengin/scripts/extenders/zparserextender/syntax_extensions/extern/index.html @@ -38,4 +38,4 @@ { // TODO }; -
\ No newline at end of file +
\ 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 index a0b328bc42..b6b58b16be 100644 --- a/pl/zengin/scripts/extenders/zparserextender/syntax_extensions/namespaces/index.html +++ b/pl/zengin/scripts/extenders/zparserextender/syntax_extensions/namespaces/index.html @@ -295,4 +295,4 @@ 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 + 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 index 63d4ec7f3d..ca18d30793 100644 --- a/pl/zengin/scripts/extenders/zparserextender/syntax_extensions/testelse/index.html +++ b/pl/zengin/scripts/extenders/zparserextender/syntax_extensions/testelse/index.html @@ -47,4 +47,4 @@ { // TODO } -
\ No newline at end of file +
\ No newline at end of file diff --git a/pl/zengin/scripts/externals/doc/index.html b/pl/zengin/scripts/externals/doc/index.html index b5daf6da23..c6807d56e8 100644 --- a/pl/zengin/scripts/externals/doc/index.html +++ b/pl/zengin/scripts/externals/doc/index.html @@ -296,4 +296,4 @@ var float r6, var float r7, var float r8) {}; -
\ No newline at end of file +
\ No newline at end of file diff --git a/pl/zengin/scripts/externals/index.html b/pl/zengin/scripts/externals/index.html index e56669d239..8f7494664a 100644 --- a/pl/zengin/scripts/externals/index.html +++ b/pl/zengin/scripts/externals/index.html @@ -31,4 +31,4 @@ const gGMC_PAGE_LOCALE = "pl"; const gGMC_FILE_LOCALE = "en"; const gGMC_TRANSLATE_SVG = ''; -

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 +

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 index d625192f9f..fc8ee7073d 100644 --- a/pl/zengin/scripts/externals/log/index.html +++ b/pl/zengin/scripts/externals/log/index.html @@ -84,4 +84,4 @@ /// @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 +
\ No newline at end of file diff --git a/pl/zengin/scripts/externals/mdl/index.html b/pl/zengin/scripts/externals/mdl/index.html index 32a32b990c..9e5b8f93e1 100644 --- a/pl/zengin/scripts/externals/mdl/index.html +++ b/pl/zengin/scripts/externals/mdl/index.html @@ -278,4 +278,4 @@ var float timemax, var float timemaxvar, var float probmin) {}; -
\ No newline at end of file +
\ 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 index 5e65d8654f..9e7024c487 100644 --- a/pl/zengin/sound/tutorials/change_sfx/index.html +++ b/pl/zengin/sound/tutorials/change_sfx/index.html @@ -31,4 +31,4 @@ const gGMC_PAGE_LOCALE = "pl"; const gGMC_FILE_LOCALE = "en"; const gGMC_TRANSLATE_SVG = ''; -

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 +

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/tools/gothic_sourcer/index.html b/pl/zengin/tools/gothic_sourcer/index.html index 7b0debffd7..6f9aa39500 100644 --- a/pl/zengin/tools/gothic_sourcer/index.html +++ b/pl/zengin/tools/gothic_sourcer/index.html @@ -31,4 +31,4 @@ const gGMC_PAGE_LOCALE = "pl"; const gGMC_FILE_LOCALE = "en"; const gGMC_TRANSLATE_SVG = ''; -

Gothic Sourcer

Gothic Sourcer can be used to do a lot of things.

Todo

TODO

\ No newline at end of file +

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/index.html b/pl/zengin/tools/index.html index c90012f070..a6230df565 100644 --- a/pl/zengin/tools/index.html +++ b/pl/zengin/tools/index.html @@ -31,4 +31,4 @@ const gGMC_PAGE_LOCALE = "pl"; const gGMC_FILE_LOCALE = "en"; const gGMC_TRANSLATE_SVG = ''; -

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.
  • DecDat - Daedalus .DAT files decompiler.
  • Redefix - OutputUnits compiler and updater.

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.

Libraries

  • ZenKit - A library to load, save and use almost all ZenGin asset files

Debugging

  • zSpy - Debugging tool that displays most of the operations performed by the engine during the Gothic or Spacer running, ships with the MDK.
\ No newline at end of file +

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.
  • DecDat - Daedalus .DAT files decompiler.
  • Redefix - OutputUnits compiler and updater.

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.

Libraries

  • ZenKit - A library to load, save and use almost all ZenGin asset files

Debugging

  • zSpy - Debugging tool that displays most of the operations performed by the engine during the Gothic or Spacer running, ships with the MDK.
\ No newline at end of file diff --git a/pl/zengin/tools/zSplitDialogs/index.html b/pl/zengin/tools/zSplitDialogs/index.html index ef338c018d..def627eb50 100644 --- a/pl/zengin/tools/zSplitDialogs/index.html +++ b/pl/zengin/tools/zSplitDialogs/index.html @@ -34,4 +34,4 @@

zSplitDialogs

The plugin for a dubbing creators. And not only.

Union plugin by Top Layer, which gives possibility to extract dialogues from compiled scripts simply by putting zSplitDialogs.vdf file into Data\ directory and run the game. You can configure, that already dubbed subtitles will be outputed.

The output is the Dialogs\ directory with .txt files with a structure as follow:

Example of a plugin output

zSpy

Download

Source code

The usage

  • Install Union 1.0l+ (zParserExtender is needed - it is inside Union since 1.0l version)
  • Put zSplitDialogs.vdf into Data\ directory
  • Start game
  • Dialogues will be created in Dialogs\ directory

At first run, in gothic.ini will be created following section:

[ZSPLITDIALOGS]
 UnvoicedOnly=0
-

You can change value to 1 to receive only unvoiced subtitles.

\ No newline at end of file +

You can change value to 1 to receive only unvoiced subtitles.

\ No newline at end of file diff --git a/pl/zengin/tools/zSpy/index.html b/pl/zengin/tools/zSpy/index.html index 65a839505c..a3bcd30c54 100644 --- a/pl/zengin/tools/zSpy/index.html +++ b/pl/zengin/tools/zSpy/index.html @@ -46,4 +46,4 @@ 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 +
\ No newline at end of file diff --git a/search/search_index.json b/search/search_index.json index 787a16f718..89d81ae634 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.

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.

"},{"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:

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:

"},{"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)
  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.

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:

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

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

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

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.

"},{"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.

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

ASC_NAME - name of the source file exported from Blender

ANI_DIR - direction of the animation

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:

"},{"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:

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:

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:

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

VDFS Tool

"},{"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

"},{"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.

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
"},{"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_menuitem/","title":"C_MENU_ITEM Daedalus class","text":""},{"location":"zengin/scripts/classes/c_menuitem/#c_menu_item-daedalus-class","title":"C_MENU_ITEM Daedalus class","text":"

Acknowledgment

Heavily inspired by the amazing documentation site Gothic library

Class C_Menu_Item describes the elements of the game menu (sliders, checkboxes, buttons, etc.) .

"},{"location":"zengin/scripts/classes/c_menuitem/#class-definition","title":"Class definition","text":"

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

C_Menu_Item Daedalus class
CONST INT MAX_USERSTRINGS       = 10;\nCONST INT MAX_ITEMS             = 150;\nCONST INT MAX_EVENTS            = 10;\nCONST INT MAX_SEL_ACTIONS       = 5;\nCONST INT MAX_USERVARS          = 4;\n\nclass C_Menu_Item\n{\n    var     string  fontName;                       // Font of the menu item.\n    var     string  text[MAX_USERSTRINGS];          // Text of the interface element.\n    var     string  backPic;                        // Background image of menu items.\n    var     string  alphaMode;                      // Transparency blending mode of menu items.\n    var     int     alpha;                          // Transparency of the menu item.\n    var     int     type;                           // Type of the interface element.\n    var     int     onSelAction[MAX_SEL_ACTIONS];   // Array of commands executed when selecting the menu item.\n    var     string  onSelAction_S[MAX_SEL_ACTIONS]; // Arguments for commands specified in the onSelAction property.\n    var     string  onChgSetOption;                 // Gothic.ini file parameter modified by this menu item.\n    var     string  onChgSetOptionSection;          // Section of the Gothic.ini file where the modified parameter is located.\n    var     func    onEventAction[MAX_EVENTS];      // Call the required function by a constant identifier.\n    var     int     posx;                           // Top-left point of the menu item on the screen horizontally (X-axis).\n    var     int     posy;                           // Top-left point of the menu item on the screen vertically (Y-axis).\n    var     int     dimx;                           // Width of the menu item in virtual coordinates.\n    var     int     dimy;                           // Height of the menu item in virtual coordinates.\n    var     float   sizeStartScale;                 // Initial size of the item. Not used.\n    var     int     flags;                          // Flags of the menu item.\n    var     float   openDelayTime;                  // Delay before opening the item. Not used.\n    var     float   openDuration;                   // Opening time. Not used.\n    var     float   userFloat[MAX_USERVARS];        // Digital settings of menu items.\n    var     string  userString[MAX_USERVARS];       // String settings of menu items.\n    var     int     frameSizeX;                     // Text offset inside the frame on the X-axis.\n    var     int     frameSizeY;                     // Text offset inside the frame on the Y-axis.\n    var     string  hideIfOptionSectionSet;         // Section of Gothic.ini file where the option determining the display of this menu item is located.\n    var     string  hideIfOptionSet;                // Gothic.ini file parameter determining the display of this menu item.\n    var     int     hideOnValue;                    // Value of the Gothic.ini file parameter at which this interface element is not displayed.\n}; \n
"},{"location":"zengin/scripts/classes/c_menuitem/#class-members","title":"Class members","text":"Property Type Description fontName string Font of the menu item. text string Text of the interface element. backPic string Background image of menu items. alphaMode string Transparency blending mode of menu items. alpha int Transparency of the menu item. type int Type of the interface element. onSelAction int Array of commands executed when selecting the menu item. onSelAction_S string Arguments for commands specified in the onSelAction property. onChgSetOption string Gothic.ini file parameter modified by this menu item. onChgSetOptionSection string Section of the Gothic.ini file where the modified parameter is located. onEventAction Func Call the required function by a constant identifier. posx int Top-left point of the menu item on the screen horizontally (X-axis). posy int Top-left point of the menu item on the screen vertically (Y-axis). dimx int Width of the menu item in virtual coordinates. dimy int Height of the menu item in virtual coordinates. sizeStartScale float Initial size of the item. Not used. flags int Flags of the menu item. openDelayTime float Delay before opening the item. Not used. openDuration float Opening time. Not used. userFloat float Digital settings of menu items. userString string String settings of menu items. frameSizeX int Text offset inside the frame on the X-axis. frameSizeY int Text offset inside the frame on the Y-axis. hideIfOptionSectionSet string Section of Gothic.ini file where the option determining the display of this menu item is located. hideIfOptionSet string Gothic.ini file parameter determining the display of this menu item. hideOnValue int Value of the Gothic.ini file parameter at which this interface element is not displayed."},{"location":"zengin/scripts/classes/c_menuitem/#class-member-overview","title":"Class member overview","text":"

Description of the class member variables.

"},{"location":"zengin/scripts/classes/c_menuitem/#fontname","title":"fontName","text":"

*.TGA file defining the font of the displayed text of the menu item.

To create a color change effect, two fonts are needed:

This creates a highlighting effect.

"},{"location":"zengin/scripts/classes/c_menuitem/#text","title":"text","text":"

Text inside a menu item.

Used to determine possible values \u200b\u200bfor game settings. See onChgSetOptionSection.

Also used to display hints about the item at the bottom of the menu when the MENU_SHOW_INFO flag is set.

// Text displayed in the element\n\ntext[0] = \"New Game\";\n\n// Text in the interface element responsible for game settings\n// One of the presented options is displayed\n\ntext[0] = \"off|on\";\n\n// Tooltip for the selected element\n// Index 1 is used for tooltips, not 0\n\ntext[1] = \"Start a new adventure\";\n
"},{"location":"zengin/scripts/classes/c_menuitem/#backpic","title":"backPic","text":"

Background image of the menu item in *.TGA format.

instance MENUITEM_MAIN_NEWGAME(C_MENU_ITEM_DEF)\n{\n    backpic = \"Inv_Slot_Highlighted.tga\";\n}\n
"},{"location":"zengin/scripts/classes/c_menuitem/#alphamode","title":"alphaMode","text":"

Texture transparency blending mode. Used in conjunction with the alpha property. This parameter's value is ignored if the backPic property is not specified.

Supported modes:

"},{"location":"zengin/scripts/classes/c_menuitem/#alpha","title":"alpha","text":"

Menu element transparency. Accepts values \u200b\u200bfrom 0 to 255. Without specifying the backPic property, the value of this parameter is ignored.

The alpha channel rendering mode is determined using the alphaMode property.

"},{"location":"zengin/scripts/classes/c_menuitem/#type","title":"type","text":"

Interface element type. Some interface elements have their own settings determined by the userFloat and userString properties.

Constants for menu item types are described in the file Scripts/System/_intern/Menu.d.

CONST INT MENU_ITEM_UNDEF       = 0; // Undefined\nCONST INT MENU_ITEM_TEXT        = 1; // Text\nCONST INT MENU_ITEM_SLIDER      = 2; // Slider\nCONST INT MENU_ITEM_INPUT       = 3; // Input field\nCONST INT MENU_ITEM_CURSOR      = 4; \nCONST INT MENU_ITEM_CHOICEBOX   = 5; // Checkbox\nCONST INT MENU_ITEM_BUTTON      = 6; // Button\nCONST INT MENU_ITEM_LISTBOX     = 7; // Frame\n
"},{"location":"zengin/scripts/classes/c_menuitem/#onselaction","title":"onSelAction","text":"

Array of commands executed when selecting the menu item.

Each command receives parameters in the onSelAction_S property.

Constants are described in the file Scripts/System/_intern/Menu.d.

CONST INT SEL_ACTION_UNDEF          = 0; // No action. Used when setting game parameters, calling functions...\nCONST INT SEL_ACTION_BACK           = 1; // Return to the previous menu or game\nCONST INT SEL_ACTION_STARTMENU      = 2; // Open a menu\nCONST INT SEL_ACTION_STARTITEM      = 3; // Special command for save slots\nCONST INT SEL_ACTION_CLOSE          = 4; // Close menu or game\nCONST INT SEL_ACTION_CONCOMMANDS    = 5; // Execute console command\nCONST INT SEL_ACTION_PLAY_SOUND     = 6; // Play sound from C_SFX instance\nCONST INT SEL_ACTION_EXECCOMMANDS   = 7; // Execute command specified in the onSelAction_S field using RUN or EFFECT commands\n
"},{"location":"zengin/scripts/classes/c_menuitem/#onselaction_s","title":"onSelAction_S","text":"

Arguments for commands specified in the onSelAction property.

Below are commands and their arguments:

"},{"location":"zengin/scripts/classes/c_menuitem/#onchgsetoption","title":"onChgSetOption","text":"

Parameter of the Gothic.ini file that will be modified by this menu item.

instance MENUITEM_GAME_FIGHTFOCUS_CHOICE(C_MENU_ITEM_DEF)\n{\n    text[0]     =   \"none|box|lighten|both\";\n    // [...]\n    onChgSetOption         = \"highlightMeleeFocus\"; // INI parameter\n    onChgSetOptionSection  = \"GAME\"; // INI section\n    // [...]\n};\n

The text[0] property of such an element usually specifies possible values of the modified parameter. Values are listed using the | symbol.

Make sure that the number of parameter options in the menu corresponds to the number of options in the Gothic.ini file.

highlightMeleeFocus=2\n; ... here you can turn on an optional focus highlight effect during fighting\n
"},{"location":"zengin/scripts/classes/c_menuitem/#onchgsetoptionsection","title":"onChgSetOptionSection","text":"

The section of the Gothic.ini file in which the parameter being changed is located.

See onChgSetOption above.

"},{"location":"zengin/scripts/classes/c_menuitem/#oneventaction","title":"onEventAction","text":"

Allows a user to call a function on a specified event.

The list of constants 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

For example, you can use the function associated with the constant EVENT_EXECUTE to call a script function.

instance MENUITEM_MAIN_INTRO(C_MENU_ITEM_DEF) \n{\n    text[0]     = \"Play Intro\";\n    text[1]     = \"Play introduction sequence\";\n    // [...]\n    onEventAction[EVENT_EXECUTE] = ShowIntro;\n};\n\nfunc int ShowIntro()\n{\n    PlayVideo(\"intro.bik\");\n    return 1;\n};\n
"},{"location":"zengin/scripts/classes/c_menuitem/#posx","title":"posx","text":"

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

Virtual coordinates

Virtual coordinates divide the menu into 8192 parts (0 - 8191) horizontally and vertically. The position of the menu item is calculated based on these values.

"},{"location":"zengin/scripts/classes/c_menuitem/#posy","title":"posy","text":"

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

"},{"location":"zengin/scripts/classes/c_menuitem/#dimx","title":"dimx","text":"

The width of the menu item in virtual coordinates.

Tip

To automatically determine the width, enter -1. In this case, the width is calculated based on the text contained in the element.

"},{"location":"zengin/scripts/classes/c_menuitem/#dimy","title":"dimy","text":"

The height of the menu item in virtual coordinates.

Tip

To automatically determine the element's height, enter a value of -1. In this case, the height is calculated taking into account the text contained in the element.

"},{"location":"zengin/scripts/classes/c_menuitem/#sizestartscale","title":"sizeStartScale","text":"

Deprecated setting

Size of the menu item at the beginning.

"},{"location":"zengin/scripts/classes/c_menuitem/#flags","title":"flags","text":"

Flags of the menu item.

Constants for all flags are described in the file Scripts/System/_intern/Menu.d.

const int IT_CHROMAKEYED            = 1;\nconst int IT_TRANSPARENT            = 2;\nconst int IT_SELECTABLE             = 4;        // Element can be selected\nconst int IT_MOVEABLE               = 8;\nconst int IT_TXT_CENTER             = 16;       // Align text to center\nconst int IT_DISABLED               = 32;       // Interactive item\nconst int IT_FADE                   = 64;\nconst int IT_EFFECTS_NEXT           = 128;      // Flag for influencing an adjacent menu item\nconst int IT_ONLY_OUT_GAME          = 256;      // Element available only outside the game\nconst int IT_ONLY_IN_GAME           = 512;      // Element available only in-game\nconst int IT_PERF_OPTION            = 1 << 10;  // Option responsible for performance\nconst int IT_MULTILINE              = 1 << 11;  // Multi-line text element\nconst int IT_NEEDS_APPLY            = 1 << 12;  // Need to apply a settings. Used when changing screen resolution\nconst int IT_NEEDS_RESTART          = 1 << 13;  // The game need to be restarted\nconst int IT_EXTENDED_MENU          = 1 << 14;  // Advanced menu flag\n
"},{"location":"zengin/scripts/classes/c_menuitem/#opendelaytime","title":"openDelayTime","text":"

Deprecated setting

Delay before opening a menu item.

"},{"location":"zengin/scripts/classes/c_menuitem/#openduration","title":"openDuration","text":"

Deprecated setting

The time the menu item was opened.

"},{"location":"zengin/scripts/classes/c_menuitem/#userfloat","title":"userFloat","text":"

Numerical settings of the interface element. Depending on the interface element, the purpose of the property changes. See type.

"},{"location":"zengin/scripts/classes/c_menuitem/#userstring","title":"userString","text":"

String settings of the interface element. The purpose of the property changes depending on the interface element. See type`.

"},{"location":"zengin/scripts/classes/c_menuitem/#framesizex","title":"frameSizeX","text":"

Indentation of text inside the frame along the X axis. This applies the padding to both sides of the frame. Measured in virtual coordinates from 0 to 4095.

Frames are a special tool designed to work with the log of tasks and quests.

Used for elements of type MENU_ITEM_LISTBOX.

instance MENU_ITEM_LIST_MISSIONS_ACT(C_MENU_ITEM_DEF)\n{\n    backpic         = \"NW_Misc_CaveWall_01.tga\";\n    type            = MENU_ITEM_LISTBOX;\n    text[0]         = \"Act Missions\";\n    // [...]\n    userstring[0]   = \"CURRENTMISSIONS\";\n    framesizex      = 2000;\n    framesizey      = 2000;\n};\n

As a result, we get the following frame (Source: Gothic-Library):

And the width and height of the frame are set, as for all elements, by the dimx and dimy properties.

"},{"location":"zengin/scripts/classes/c_menuitem/#framesizey","title":"frameSizeY","text":"

Indentation of text inside the frame along the Y axis. In this case, the indentation is applied at the top and bottom of the frame. Measured in virtual coordinates from 0 to 4095.

See frameSizeX above.

"},{"location":"zengin/scripts/classes/c_menuitem/#hideifoptionsectionset","title":"hideIfOptionSectionSet","text":"

The section of the Gothic.ini file with the option which value of determines the display of this menu item.

This property works together with the hideIfOptionSet and hideOnValue properties.

In the example below, the interface element will not be displayed until the useGothic1Controls parameter in the GAME section is set to 1, i.e., enabled.

instance MENU_ITEM_NEXTMENU(C_MENU_ITEM_DEF)\n{\n    text[0]     = \"More keys...\";\n    text[1]     = \"Configure further control keys\";\n    // [...]\n    hideifoptionsectionset  = \"GAME\";\n    hideifoptionset         = \"useGothic1Controls\";\n    hideonvalue             = 1;\n};\n

Tip

Gothic.ini settings can also be changed through the main menu. See onChgSetOption and onChgSetOptionSection.

"},{"location":"zengin/scripts/classes/c_menuitem/#hideifoptionset","title":"hideIfOptionSet","text":"

The Gothic.ini file parameter, the value of which determines the display of this menu item.

See hideIfOptionSectionSet.

"},{"location":"zengin/scripts/classes/c_menuitem/#hideonvalue","title":"hideOnValue","text":"

The value of the Gothic.ini file parameter at which this interface element is not displayed.

See hideIfOptionSectionSet.

"},{"location":"zengin/scripts/classes/c_menuitem/#predefined-instances","title":"Predefined instances","text":"

There are a lot of predefined class instances in the menu C_MENU_ITEM performing a strictly defined function. They cannot be renamed, but they can be configured to a certain extent.

Instance Description MENUITEM_LOADSAVE_THUMBPIC Save picture in the Save/Load menu. MENUITEM_LOADSAVE_LEVELNAME_VALUE The name of the level of the selected Save/Load menu item. MENUITEM_LOADSAVE_DATETIME_VALUE The date the selected Save/Load menu item was saved. MENUITEM_LOADSAVE_GAMETIME_VALUE Game time for saving the selected Save/Load menu item. MENUITEM_LOADSAVE_PLAYTIME_VALUE Total play time of the selected Save/Load menu item. MENUITEM_SAVE_SLOT1 - MENUITEM_SAVE_SLOT20 Save menu slots. MENUITEM_LOAD_SLOT1 - MENUITEM_LOAD_SLOT20 Load menu slots. MENU_ITEM_LIST_MISSIONS_ACT Frame with a list of current tasks in the journal. MENU_ITEM_LIST_MISSIONS_FAILED Frame with a list of failed tasks in the log. MENU_ITEM_LIST_MISSIONS_OLD Frame with a list of old tasks in the journal. MENU_ITEM_LIST_LOG Frame of general information in the task log. MENU_ITEM_CONTENT_VIEWER Job log window. MENU_ITEM_DAY Current day in the quest log window. MENU_ITEM_TIME Current time in the task log window. MENU_ITEM_PLAYERGUILD Character's guild in the statistics window. MENU_ITEM_TALENT_0_TITLE - MENU_ITEM_TALENT_16_TITLE The name of the character's talent. Array indexes are used TXT_TALENTS from the Text.d file. There may be more elements, depending on the talents realized in the game. MENU_ITEM_TALENT_0_SKILL - MENU_ITEM_TALENT_16_SKILL Character's talent level. Array indexes are used TXT_TALENTS_SKILLS from the Text.d file. MENU_ITEM_EXP The character's current experience value in the statistics window. MENU_ITEM_LEVEL Current character level in the statistics window. MENU_ITEM_LEVEL_NEXT The amount of experience required to obtain the next level in the statistics window. MENU_ITEM_LEARN The number of available training points in the statistics window. MENU_ITEM_ATTRIBUTE_1 - MENU_ITEM_ATTRIBUTE_4 Character attributes in the statistics window. MENU_ITEM_ARMOR_1 - MENU_ITEM_ARMOR_4 Character protection in the statistics window."},{"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.

Danger

Make sure that you use proper naming convention for MusicThemes and oCZoneMusic vobs. The theme with OC_ prefix will play in a zone with name like OLDCAMP_OC or any other ending with _OC

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":""},{"location":"zengin/scripts/extenders/ikarus/constants/#debug","title":"Debug","text":""},{"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:

"},{"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":"

mkf

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

func int mkf(var int x)\n
Parameters

Return value

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

"},{"location":"zengin/scripts/extenders/ikarus/floats/#truncf","title":"truncf","text":"

truncf

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

func int truncf(var int x)\n
Parameters

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":"

roundf

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

func int roundf(var int x)\n
Parameters

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":"

addf

(add floats) Adds two ikarus floats together.

func int addf(var int x, var int y)\n
Parameters

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":"

subf

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

func int subf(var int x, var int y)\n
Parameters

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":"

negf

(negate float) Negates the input float.

func int negf(var int x)\n
Parameters

Return value

The function returns the negation of the input float x.

"},{"location":"zengin/scripts/extenders/ikarus/floats/#mulf","title":"mulf","text":"

mulf

(multiply floats) Multiplies two ikarus floats.

func int mulf(var int x, var int y)\n
Parameters

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":"

divf

(divide floats) Divides two ikarus floats.

func int divf(var int x, var int y)\n
Parameters

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":"

invf

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

func int invf(var int x)\n
Parameters

Return value

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

"},{"location":"zengin/scripts/extenders/ikarus/floats/#gf","title":"gf","text":"

gf

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

func int gf(var int x, var int y)\n
Parameters

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":"

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)\n
Parameters

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":"

lf

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

func int lf(var int x, var int y)\n
Parameters

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":"

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)\n
Parameters

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":"
!!! function \"`sqrf`\"\n(square float) Calculates the square of the float.\n```dae\nfunc int sqrf(var int x)\n```\n**Parameters**\n\n- `#!dae var int x`  \n    The input float\n\n**Return value**\n\nThe function returns the square of the input float `x`, computed as `x * x`.\n
"},{"location":"zengin/scripts/extenders/ikarus/floats/#sqrtf","title":"sqrtf","text":"
!!! function \"`sqrtf`\"\n(square root float) Calculates the square root of the float.\n```dae\nfunc int sqrtf(var int x)\n```\n**Parameters**\n\n- `#!dae var int x`  \n    The input float\n\n**Return value**\n\nThe function returns the square root of the input float `x`.\n
"},{"location":"zengin/scripts/extenders/ikarus/floats/#sqrtf_approx","title":"sqrtf_approx","text":"

sqrtf_approx

Calculates the approximate square root of a float.

func int sqrtf_approx(var int f)\n
Parameters

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":"

absf

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

func int absf(var int x)\n
Parameters

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":"

fracf

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

func int fracf(var int p, var int q)\n
Parameters

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":"

castFromIntf

Converts an ikarus float to a Daedalus float.

func float castFromIntf(var int f)\n
Parameters

Return Value

The function returns the value f as a Daedalus float.

"},{"location":"zengin/scripts/extenders/ikarus/floats/#casttointf","title":"castToIntf","text":"

castToIntf

Converts a Daedalus float to an ikarus float.

func int castToIntf(var float f)\n
Parameters

Return Value

The function returns the value f as an ikarus float.

"},{"location":"zengin/scripts/extenders/ikarus/floats/#tostringf","title":"toStringf","text":"

toStringf

Converts a float value to its string representation.

func string toStringf(var int x)\n
Parameters

Return value

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

"},{"location":"zengin/scripts/extenders/ikarus/floats/#printf","title":"printf","text":"

printf

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

func void printf(var int x)\n
Parameters "},{"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
"},{"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":"

MEM_ArrayCreate

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":"

MEM_ArrayFree

Frees the memory allocated for a zCArray and its data.

func void MEM_ArrayFree(var int zCArray_ptr)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/arrays/#mem_arrayclear","title":"MEM_ArrayClear","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/arrays/#mem_arraysize","title":"MEM_ArraySize","text":"

MEM_ArraySize

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

func int MEM_ArraySize(var int zCArray_ptr)\n
Parameters

Return value

The function returns a number of a zCArray elements.

"},{"location":"zengin/scripts/extenders/ikarus/functions/arrays/#mem_arraywrite","title":"MEM_ArrayWrite","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/arrays/#mem_arrayread","title":"MEM_ArrayRead","text":"

MEM_ArrayRead

Reads the value at a specific position in the zCArray.

func int MEM_ArrayRead(var int zCArray_ptr, var int pos)\n
Parameters

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":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/arrays/#mem_arraypush","title":"MEM_ArrayPush","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/arrays/#mem_arraypop","title":"MEM_ArrayPop","text":"

MEM_ArrayPop

Removes and returns the last element from the zCArray.

func int MEM_ArrayPop(var int zCArray_ptr)\n
Parameters

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":"

MEM_ArrayTop

Returns the last element of the zCArray without removing it.

func int MEM_ArrayTop(var int zCArray_ptr)\n
Parameters

Return value

The function returns the last element of an array.

"},{"location":"zengin/scripts/extenders/ikarus/functions/arrays/#mem_arrayindexof","title":"MEM_ArrayIndexOf","text":"

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)\n
Parameters

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":"

MEM_ArrayRemoveIndex

Removes the element at a specific index from the zCArray.

func void MEM_ArrayRemoveIndex (var int zCArray_ptr, var int index)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/arrays/#mem_arrayremovevalue","title":"MEM_ArrayRemoveValue","text":"

MEM_ArrayRemoveValue

Removes all occurrences of a value from the zCArray.

func void MEM_ArrayRemoveValue (var int zCArray_ptr, var int value)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/arrays/#mem_arrayremovevalueonce","title":"MEM_ArrayRemoveValueOnce","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/arrays/#mem_arraysort","title":"MEM_ArraySort","text":"

MEM_ArraySort

Sorts the elements of the zCArray in ascending order.

func void MEM_ArraySort(var int zCArray_ptr)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/arrays/#mem_arrayunique","title":"MEM_ArrayUnique","text":"

MEM_ArrayUnique

Removes duplicate elements from the zCArray.

func void MEM_ArrayUnique(var int zCArray_ptr)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/arrays/#mem_arraytostring","title":"MEM_ArrayToString","text":"

MEM_ArrayToString

Converts the zCArray to a string representation.

func string MEM_ArrayToString (var int zCArray_ptr)\n
Parameters

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:

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":"

ASMINT_Push

Pushes the specified data onto the internal stack.

func void ASMINT_Push(var int data)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/asm/#asmint_pop","title":"ASMINT_Pop","text":"

ASMINT_Pop

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":"

ASMINT_Init

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":"

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)\n
Parameters

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":"

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)\n
Parameters ASM_1ASM_2ASM_3ASM_4"},{"location":"zengin/scripts/extenders/ikarus/functions/asm/#asm_1","title":"ASM_1","text":"

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) \n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/asm/#asm_2","title":"ASM_2","text":"

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) \n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/asm/#asm_3","title":"ASM_3","text":"

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) \n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/asm/#asm_4","title":"ASM_4","text":"

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) \n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/asm/#asm_here","title":"ASM_Here","text":"

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()\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":"

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()\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":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/asm/#asm_runonce","title":"ASM_RunOnce","text":"

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()\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":"

CALL_Open

Initializes a Recyclable call mode.

func void CALL_Open()\n
"},{"location":"zengin/scripts/extenders/ikarus/functions/call/#call_begin","title":"CALL_Begin","text":"

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)\n
Parameters

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":"

CALL_Close

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":"

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()\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":"

CALL_IntParam

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

func void CALL_IntParam(var int param)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/call/#call_floatparam","title":"CALL_FloatParam","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/call/#call_ptrparam","title":"CALL_PtrParam","text":"

CALL_PtrParam

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

func void CALL_PtrParam(var int param)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/call/#call_zstringptrparam","title":"CALL_zStringPtrParam","text":"

CALL_zStringPtrParam

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

func void CALL_zStringPtrParam(var string param)\n
Parameters

Warning

This function only works when writing a disposable call!

"},{"location":"zengin/scripts/extenders/ikarus/functions/call/#call_cstringptrparam","title":"CALL_cStringPtrParam","text":"

CALL_cStringPtrParam

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

func void CALL_cStringPtrParam(var string param)\n
Parameters

Warning

This function only works when writing a disposable call!

"},{"location":"zengin/scripts/extenders/ikarus/functions/call/#call_structparam","title":"CALL_StructParam","text":"

CALL_StructParam

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

func void CALL_StructParam(var int ptr, var int words)\n
Parameters

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":"

CALL__stdcall

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

func void CALL__stdcall(var int adr)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/call/#call__thiscall","title":"CALL__thiscall","text":"

CALL__thiscall

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

func void CALL__thiscall(var int this, var int adr)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/call/#call__cdecl","title":"CALL__cdecl","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/call/#call__fastcall","title":"CALL__fastcall","text":"

CALL__fastcall

Calls a function with __fastcall calling convention.

func void CALL__fastcall(var int ecx, var int edx, var int adr)\n
Parameters "},{"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":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/call/#call_retvalasint","title":"CALL_RetValAsInt","text":"

CALL_RetValAsInt

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":"

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()\n
"},{"location":"zengin/scripts/extenders/ikarus/functions/call/#call_retvalasfloat","title":"CALL_RetValAsFloat","text":"

CALL_RetValAsFloat

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":"

CALL_RetValAsPtr

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":"

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)\n
Parameters

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":"

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()\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":"

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()\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":"

CALL_RetValAszStringPtr

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":"

CALL_RetValAszString

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":"

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)\n
Parameters

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":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/debug/#mem_sendtospy","title":"MEM_SendToSpy","text":"

MEM_SendToSpy

Sends a message to the debugging console.

func void MEM_SendToSpy(var int errorType, var string text)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/debug/#mem_errorbox","title":"MEM_ErrorBox","text":"

MEM_ErrorBox

Displays an error message in a message box.

func void MEM_ErrorBox(var string text)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/debug/#mem_printstacktrace","title":"MEM_PrintStackTrace","text":"

MEM_PrintStackTrace

Prints the stack trace.

func void MEM_PrintStackTrace()\n
"},{"location":"zengin/scripts/extenders/ikarus/functions/debug/#mem_error","title":"MEM_Error","text":"

MEM_Error

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

func void MEM_Error(var string error)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/debug/#mem_warn","title":"MEM_Warn","text":"

MEM_Warn

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

func void MEM_Warn(var string warn)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/debug/#mem_info","title":"MEM_Info","text":"

MEM_Info

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

func void MEM_Info(var string info)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/debug/#mem_assertfail","title":"MEM_AssertFail","text":"

MEM_AssertFail

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

func void MEM_AssertFail(var string assertFailText)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/debug/#mem_debug","title":"MEM_Debug","text":"

MEM_Debug

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

func void MEM_Debug(var string message)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/debug/#memint_switchg1g2","title":"MEMINT_SwitchG1G2","text":"

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)\n
Parameters

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":"

MEM_GetCommandLine

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":"

MEM_GetGothOpt

Searches the Gothic.ini for an option.

func string MEM_GetGothOpt(var string sectionname, var string optionname)\n
Parameters

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":"

MEM_GetModOpt

Searches the loaded mod ini file for option.

func void MEM_GetModOpt(var string sectionname, var string optionname)\n
Parameters

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":"

MEM_GothOptSectionExists

Checks whether a section exists in Gothic.ini

func int MEM_GothOptSectionExists(var string sectionname)\n
Parameters

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":"

MEM_ModOptSectionExists

Checks whether a section exists in loaded mod ini file

func int MEM_ModOptSectionExists(var string sectionname)\n
Parameters

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":"

MEM_GothOptExists

Checks whether an option exists in Gothic.ini

func int MEM_GothOptExists(var string sectionname, var string optionname)\n
Parameters

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":"

MEM_ModOptExists

Checks whether an option exists in loaded mod ini file

func int MEM_ModOptExists(var string sectionname, var string optionname)\n
Parameters

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":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/ini_access/#mem_applygothopt","title":"MEM_ApplyGothOpt","text":"

MEM_ApplyGothOpt

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":"

MEM_GetKey

Returns the primary key assigned to logical key.

func int MEM_GetKey(var string name)\n
Parameters

Return value

The function returns key assigned to logical key

"},{"location":"zengin/scripts/extenders/ikarus/functions/ini_access/#mem_getsecondarykey","title":"MEM_GetSecondaryKey","text":"

MEM_GetSecondaryKey

Returns a secondary key assigned to logical key.

func int MEM_GetSecondaryKey(var string name)\n
Parameters

Return value

The function returns key assigned to logical key

"},{"location":"zengin/scripts/extenders/ikarus/functions/ini_access/#mem_setkeys","title":"MEM_SetKeys","text":"

MEM_SetKeys

Sets keyboard keys of the logical key.

func void MEM_SetKeys(var string name, var int primary, var int secondary)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/ini_access/#mem_setkey","title":"MEM_SetKey","text":"

MEM_SetKey

Sets the primary keyboard key of the logical key.

func void MEM_SetKey(var string name, var int key)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/ini_access/#mem_setsecondarykey","title":"MEM_SetSecondaryKey","text":"

MEM_SetSecondaryKey

Sets the secondary keyboard key of the logical key.

func void MEM_SetSecondaryKey(var string name, var int key)\n
Parameters "},{"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":"

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":""},{"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":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/jumps_loops/#mem_goto","title":"MEM_Goto","text":"

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)\n
Parameters "},{"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 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

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":"

MEM_KeyPressed

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

func int MEM_KeyPressed(var int key)\n
Parameters

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":"

MEM_KeyState

Returns the state of the key.

func int MEM_KeyState(var int key)\n
Parameters

Return value

The function returns actual key state.

Key states

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":"

MEM_InsertKeyEvent

Makes the game think that the key was pressed.

func void MEM_InsertKeyEvent(var int key)\n
Parameters "},{"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":"

MEM_ReadInt

Reads int from the address.

func int MEM_ReadInt(var int address)\n
Parameters

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":"

MEM_ReadString

Reads string from the address.

func string MEM_ReadString(var int address)\n
Parameters

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":"

MEM_ReadByte

Reads byte from the address.

func int MEM_ReadByte(var int address)\n
Parameters

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":"

MEM_ReadIntArray

Reads int from the array at the arrayAddress.

func int MEM_ReadIntArray(var int arrayAddress, var int offset)\n
Parameters

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":"

MEM_ReadByteArray

Reads byte from the array at the arrayAddress.

func int MEM_ReadByteArray(var int arrayAddress, var int offset)\n
Parameters

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":"

MEM_WriteInt

Writes int value in the address.

func void MEM_WriteInt(var int address, var int value)\n
Parameters 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":"

MEM_WriteString

Writes string in the address.

func void MEM_WriteString(var int address, var string value)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/mem_access/#mem_writebyte","title":"MEM_WriteByte","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/mem_access/#mem_writeintarray","title":"MEM_WriteIntArray","text":"

MEM_WriteIntArray

Writes int value in the array at arrayAddress.

func void MEM_WriteIntArray(var int arrayAddress, var int offset, var int value)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/mem_access/#mem_writestringarray","title":"MEM_WriteStringArray","text":"

MEM_WriteStringArray

Writes string value in the array at arrayAddress.

func void MEM_WriteStringArray(var int arrayAddress, var int offset, var string value)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/mem_access/#mem_writebytearray","title":"MEM_WriteByteArray","text":"

MEM_WriteByteArray

Writes byte value in the array at arrayAddress.

func void MEM_WriteByteArray(var int arrayAddress, var int offset, var int value)\n
Parameters "},{"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":"

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 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

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":"

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)\n
Parameters

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":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/mem_utility/#mem_copy","title":"MEM_Copy","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/mem_utility/#mem_copywords","title":"MEM_CopyWords","text":"

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) \n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/mem_utility/#mem_copybytes","title":"MEM_CopyBytes","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/mem_utility/#mem_swap","title":"MEM_Swap","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/mem_utility/#mem_swapwords","title":"MEM_SwapWords","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/mem_utility/#mem_swapbytes","title":"MEM_SwapBytes","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/mem_utility/#mem_clear","title":"MEM_Clear","text":"

MEM_Clear

Sets a specified number of bytes in memory to zero.

func void MEM_Clear(var int ptr, var int size)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/mem_utility/#mem_compare","title":"MEM_Compare","text":"

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)\n
Parameters

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":"

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)\n
Parameters

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":"

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)\n
Parameters

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":"

MEM_GetMenuByString

func int MEM_GetMenuByString(var string menuName)\n

Parameters

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":"

MEM_GetMenuItemByString

func int MEM_GetMenuItemByString(var string menuItemName)\n

Parameters

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":"Ikarus `zCObject` manipulation functions","text":""},{"location":"zengin/scripts/extenders/ikarus/functions/objects/#ikarus-zcobject-manipulation-functions","title":"Ikarus zCObject manipulation functions","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":"

MEM_InitGlobalInst

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":"

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)\n
Parameters

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":"

MEM_GetClassName

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

func string MEM_GetClassName(var int objPtr)\n
Parameters

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":"

MEM_CheckInheritance

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

func int MEM_CheckInheritance(var int objPtr, var int classDef)\n
Parameters

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":"

Hlp_Is_*

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":"

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)\n
Parameters

Return value

The function returns a pointer to the created object.

"},{"location":"zengin/scripts/extenders/ikarus/functions/objects/#mem_deletevob","title":"MEM_DeleteVob","text":"

MEM_DeleteVob

Deletes a specific Vob form world.

func void MEM_DeleteVob(var int vobPtr)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/objects/#mem_renamevob","title":"MEM_RenameVob","text":"

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)\n
Parameters MEM_TriggerVobMEM_UntriggerVob"},{"location":"zengin/scripts/extenders/ikarus/functions/objects/#mem_triggervob","title":"MEM_TriggerVob","text":"

MEM_TriggerVob

Sends a trigger message to the Vob.

func void MEM_TriggerVob(var int vobPtr)\n
Parameters

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":"

MEM_UntriggerVob

Sends an untrigger message to the Vob.

func void MEM_TriggerVob(var int vobPtr)\n
Parameters

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":"

MEM_SearchVobByName

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

func int MEM_SearchVobByName(var string str)\n
Parameters

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":"

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)\n
Parameters

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":"

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)\n
Parameters

Return value

The function returns the calculated CRC32 hash value.

"},{"location":"zengin/scripts/extenders/ikarus/functions/objects/#mem_getstringhash","title":"MEM_GetStringHash","text":"

MEM_GetStringHash

Calculates the CRC32 hash value for a string.

func int MEM_GetStringHash(var string str)\n
Parameters

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":"

MEM_ReinitParser

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":"

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)\n
Parameters

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":"

MEM_NullToInst

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":"

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)\n
Parameters 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":"

MEM_AssignInstNull

Assigns null pointer to a given instance.

func void MEM_AssignInstNull(var int inst)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_insttoptr","title":"MEM_InstToPtr","text":"

MEM_InstToPtr

Returns a pointer to given instance.

func int MEM_InstToPtr(var int inst)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_instgetoffset","title":"MEM_InstGetOffset","text":"

MEM_InstGetOffset

Alias to MEM_InstToPtr. Returns a pointer to given instance.

func int MEM_InstGetOffset(var int inst)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_cpyinst","title":"MEM_CpyInst","text":"

MEM_CpyInst

Returns a copy of a given instance

func MEMINT_HelperClass MEM_CpyInst(var int inst)\n
Parameters 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":"

MEM_PushIntParam

Passes an integer as a parameter to the called function.

func void MEM_PushIntParam (var int param)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_pushinstparam","title":"MEM_PushInstParam","text":"

MEM_PushInstParam

Passes an instance as a parameter to the called function.

func void MEM_PushInstParam (var int inst)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_pushstringparam","title":"MEM_PushStringParam","text":"
!!! function \"`MEM_PushStringParam`\"\nPasses a string as a parameter to the called function.\n```dae\nfunc void MEM_PushStringParam (var string str)\n```\n**Parameters**\n\n- `#!dae var string str`  \n    String to pass as a function parameter\n
"},{"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":"

MEM_Call

Calls a function.

func void MEM_Call(var func fnc)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_callbyid","title":"MEM_CallByID","text":"

MEM_CallByID

Calls a function by its ID.

func void MEM_CallByID (var int symbID)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_callbyptr","title":"MEM_CallByPtr","text":"

MEM_CallByPtr

Calls a function by its pointer.

func void MEM_CallByPtr(var int ptr)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_callbyoffset","title":"MEM_CallByOffset","text":"

MEM_CallByOffset

Calls a function by its offset.

func void MEM_CallByOffset(var int offset)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_callbystring","title":"MEM_CallByString","text":"

MEM_CallByString

Calls a function by its name.

func void MEM_CallByString (var string fnc)\n
Parameters "},{"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":"

MEM_PopIntResult

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":"

MEM_PopStringResult

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":"

MEM_PopInstResult

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":"

MEM_GetFuncID

Returns the ID of the given function.

func int MEM_GetFuncID(var func fnc)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_getfuncptr","title":"MEM_GetFuncPtr","text":"

MEM_GetFuncPtr

Returns the pointer of the given function.

func int MEM_GetFuncPtr(var func fnc)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_getfuncoffset","title":"MEM_GetFuncOffset","text":"

MEM_GetFuncOffset

Returns the offset of the given function.

func int MEM_GetFuncOffset(var func fnc)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_getfuncidbyoffset","title":"MEM_GetFuncIDByOffset","text":"

MEM_GetFuncIDByOffset

MEM_GetFuncID, but with an offset as a parameter.

func int MEM_GetFuncIDByOffset(var int offset)\n
Parameters

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":"

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)\n
Parameters "},{"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":"

MEM_GetFrameBoundary

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":"

MEM_GetCallerStackPos

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":"

MEM_SetCallerStackPos

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

func void MEM_SetCallerStackPos(var int popPos)\n
Parameters "},{"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":"

MEM_GetAddress_Init

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":"

MEM_GetIntAddress

Returns an address of a given integer.

func int MEM_GetIntAddress(var int i)\n
Parameters

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":"

MEM_GetFloatAddress

Returns an address of a given daedalus float.

func int MEM_GetFloatAddress(var float f)\n
Parameters

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":"

MEM_GetStringAddress

Returns an address of a given string.

func int MEM_GetStringAddress(var string s)\n
Parameters

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":"

STR_GetAddressInit

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":"

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)\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":"

MEM_InitStatArrs

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":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_readstatarr","title":"MEM_ReadStatArr","text":"

MEM_ReadStatArr

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

func int MEM_ReadStatArr (var int array, var int offset)\n
Parameters

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":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_readstatstringarr","title":"MEM_ReadStatStringArr","text":"

MEM_ReadStatStringArr

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

func string MEM_ReadStatStringArr(var string array, var int offset)\n
Parameters

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":"

MEM_SetCurrParserSymb

Makes currParserSymb point to the symbol of the specified instance.

func void MEM_SetCurrParserSymb (var int inst)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#currparsersymb","title":"currParserSymb","text":"

currParserSymb

An instance representing current parser symbol.

INSTANCE currParserSymb (zCPar_Symbol);\n
"},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_findparsersymbol","title":"MEM_FindParserSymbol","text":"

MEM_FindParserSymbol

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

func int MEM_FindParserSymbol(var string inst)\n
Parameters

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":"

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)\n
Parameters

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":"

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)\n
Parameters

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":"

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)\n
Parameters

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_GetSymbolByIndex

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

func int MEM_GetSymbolByIndex(var int id)\n
Parameters

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":"

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)\n
Parameters

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":"

STR_Len

Returns the length of a string.

func int STR_Len (var string str)\n
Parameters

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":"

STR_toChar

Converts a string to a pointer to its character array.

func int STR_toChar (var string str)\n
Parameters

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":"

STR_FromChar

Converts a character array to a string.

func string STR_FromChar(var int char)\n
Parameters

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":"

STR_SubStr

Extracts a substring from a given string.

func string STR_SubStr (var string str, var int start, var int count)\n
Parameters

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":"

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)\n
Parameters

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":"

STR_Compare

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

func int STR_Compare(var string str1, var string str2)\n
Parameters

Return Value

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

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":"

STR_ToInt

Converts a string to an integer.

func int STR_ToInt (var string str)\n
Parameters

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":"

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)\n
Parameters

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":"

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)\n
Parameters

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":"

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)\n

Parameters

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":"

STR_Upper

Converts a string to uppercase.

func string STR_Upper(var string str)\n
Parameters

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":"

STR_Lower

Converts a string to lowercase.

func string STR_Lower(var string str)\n
Parameters

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":"

MEM_GetSystemTime

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":"

MEM_GetPerformanceCounter

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":"

MEM_BenchmarkMS

Benchmark of the execution time for a specified function. (Milliseconds)

func int MEM_BenchmarkMS(var func f)\n
Parameters

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":"

MEM_BenchmarkMMS

Benchmark of the execution time for a specified function. (microseconds)

func int MEM_BenchmarkMMS(var func f)\n
Parameters

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":"

MEM_BenchmarkPC

Benchmark of the execution time for a specified function, using the Performancecounter.

func int MEM_BenchmarkMS(var func f)\n
Parameters

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_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)\n
Parameters

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_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)\n
Parameters

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_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)\n
Parameters

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":"

LoadLibrary

Loads the specified module into the address space of the calling process. Full documentation here.

func int LoadLibrary(var string lpFileName)\n
Parameters

Return value

The function returns a handle to the module.

"},{"location":"zengin/scripts/extenders/ikarus/functions/win_utilities/#getprocaddress","title":"GetProcAddress","text":"

GetProcAddress

Retrieves the address from the specified dynamic-link library. Full documentation here.

func int GetProcAddress(var int hModule, var string lpProcName)\n
Parameters

Return value The function returns address of the function or variable.

"},{"location":"zengin/scripts/extenders/ikarus/functions/win_utilities/#findkerneldllfunction","title":"FindKernelDllFunction","text":"

FindKernelDllFunction

Uses GetProcAddress to find function inside the KERNEL32.DLL file.

func int FindKernelDllFunction(var string name)\n
Parameters

Return value

The function returns address of the function.

"},{"location":"zengin/scripts/extenders/ikarus/functions/win_utilities/#virtualprotect","title":"VirtualProtect","text":"

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)\n
Parameters

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":"

MemoryProtectionOverride

Alias to VirtualProtect but with predefined PAGE_EXECUTE_READWRITE protection option

func void MemoryProtectionOverride(var int address, var int size)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/win_utilities/#mem_messagebox","title":"MEM_MessageBox","text":"

MEM_MessageBox

Calls the WinAPI MessageBox function.

func int MEM_MessageBox(var string txt, var string caption, var int type)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/win_utilities/#mem_infobox","title":"MEM_InfoBox","text":"

MEM_InfoBox

Alias to MEM_MessageBox with \"Information:\" header and MB_OK | MB_ICONINFORMATION type.

func void MEM_InfoBox(var string txt)\n
Parameters "},{"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/setup/","title":"LeGo Setup","text":""},{"location":"zengin/scripts/extenders/lego/setup/#lego-setup","title":"LeGo Setup","text":"

Danger

LeGo depends on Ikarus script packet, if you didn't install it yet check the Ikarus Setup. This guide assumes that you already have Ikarus running.

"},{"location":"zengin/scripts/extenders/lego/setup/#download","title":"Download","text":"

First you need to download LeGo from the official github repository. We recommend using the dev branch as it contains the latest and most up-to-date version of the package. However, you can also download a specific release if needed.

"},{"location":"zengin/scripts/extenders/lego/setup/#file-location","title":"File location","text":"

If you followed the Ikarus Setup guide you probably have a \"MOD\" (or any other named) folder inside the <Gothic-dir>\\_work\\Data\\Scripts\\Content directory. If not create it.

Unpack the downloaded files into this folder. The archiver should create a folder named LeGo-dev or LeGo-X.X.X. For better readability change its name to just LeGo.

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/lego/setup/#parsing","title":"Parsing","text":"

LeGo has a special header files, one for each supported engine version. All you need to do is to include them in Gothic.src right after the Ikarus files.

Gothic.src (G1)Gothic.src (G2)
_INTERN\\CONSTANTS.D\n_INTERN\\CLASSES.D\nMOD\\IKARUS\\IKARUS_G1.SRC\nMOD\\LEGO\\HEADER_G1.SRC\n
_INTERN\\CONSTANTS.D\n_INTERN\\CLASSES.D\nMOD\\IKARUS\\IKARUS_G2.SRC\nMOD\\LEGO\\HEADER_G2.SRC\n
"},{"location":"zengin/scripts/extenders/lego/setup/#initialization","title":"Initialization","text":"

Before you can use LeGo and its packages, it must be properly initialized.

Warning

Gothic 1 by default doesn't have its own INIT_GLOBAL function inside Startup.d file. If you haven't created it yet see how to do it here.

You initialize LeGo by calling the LeGo_Init(var int flags) function and specifying the flags.

Init AllExclude packagesInit specific packages

With LeGo_All flag you initialize all packages, excluding experimental Buffs and Render.

Startup.d
FUNC VOID INIT_GLOBAL()\n{\n    // Init Ikarus\n    MEM_InitAll ();\n    // Init LeGo\n    LeGo_Init(LeGo_All)\n};\n

By the bitwise NOT operator you can exclude specific packages from LeGo_All flag.

Startup.d
FUNC VOID INIT_GLOBAL()\n{\n    // Init Ikarus\n    MEM_InitAll ();\n    // Init LeGo\n    LeGo_Init(LeGo_All &~ (LeGo_Focusnames | LeGo_Bloodsplats));\n};\n

You could also init specific packages with bitwise OR.

Startup.d
FUNC VOID INIT_GLOBAL()\n{\n    // Init Ikarus\n    MEM_InitAll ();\n    // Init LeGo\n    LeGo_Init(LeGo_AI_Function | LeGo_Saves);\n};\n
"},{"location":"zengin/scripts/extenders/lego/userconstants/","title":"User constants","text":""},{"location":"zengin/scripts/extenders/lego/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/userconstants/#read-only","title":"Read only","text":"

These constants may only be used, not changed.

"},{"location":"zengin/scripts/extenders/lego/userconstants/#anim8","title":"Anim8","text":"

These constants are used by Anim8 and Anim8q.

"},{"location":"zengin/scripts/extenders/lego/userconstants/#buttons","title":"Buttons","text":"

The following bit masks can be applied to the status of a button:

"},{"location":"zengin/scripts/extenders/lego/userconstants/#interface","title":"Interface","text":"

Dimensions

Colors

16 basic colors that can be used as zColor parameters

"},{"location":"zengin/scripts/extenders/lego/userconstants/#gamestate","title":"Gamestate","text":"

Gamestate can assume these values:

"},{"location":"zengin/scripts/extenders/lego/userconstants/#cursor","title":"Cursor","text":"

These constants are sent with Cursor_Event:

"},{"location":"zengin/scripts/extenders/lego/userconstants/#modifiable","title":"Modifiable","text":"

These constants are often used by packages and may be changed freely.

"},{"location":"zengin/scripts/extenders/lego/userconstants/#bloodsplats","title":"Bloodsplats","text":""},{"location":"zengin/scripts/extenders/lego/userconstants/#cursor_1","title":"Cursor","text":""},{"location":"zengin/scripts/extenders/lego/userconstants/#interface_1","title":"Interface","text":""},{"location":"zengin/scripts/extenders/lego/userconstants/#prints","title":"PrintS","text":"

All position and size information is completely virtual:

The times are given in ms:

The font can be modified:

"},{"location":"zengin/scripts/extenders/lego/userconstants/#talents","title":"Talents","text":""},{"location":"zengin/scripts/extenders/lego/userconstants/#dialoggestures","title":"Dialoggestures","text":""},{"location":"zengin/scripts/extenders/lego/applications/anim8/","title":"Anim8","text":""},{"location":"zengin/scripts/extenders/lego/applications/anim8/#anim8","title":"Anim8","text":"

Info

Dependencies: - Floats Implementation: Anim8.d on GitHub

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/#initialization","title":"Initialization","text":"

Initialize with LeGo_Anim8 flag.

LeGo_Init(LeGo_Anim8);\n
"},{"location":"zengin/scripts/extenders/lego/applications/anim8/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/applications/anim8/#anim8_new","title":"Anim8_New","text":"

Anim8_New

Creates a new Anim8 object that can be filled with commands.

func int Anim8_New(var int initialValue, var int IsFloat)\n
Parameters

Return value

The function returns handle of the Anim8 object.

"},{"location":"zengin/scripts/extenders/lego/applications/anim8/#anim8_newext","title":"Anim8_NewExt","text":"

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)\n
Parameters

Return value

The function returns handle of the Anim8 object.

"},{"location":"zengin/scripts/extenders/lego/applications/anim8/#anim8_delete","title":"Anim8_Delete","text":"

Anim8_Delete

Deletes an Anim8 object created with Anim8_New.

func void Anim8_Delete(var int handle)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/anim8/#anim8_get","title":"Anim8_Get","text":"

Anim8_Get

Get current value of the object.

func int Anim8_Get(var int handle)\n
Parameters

Return value

The function returns value of the object.

"},{"location":"zengin/scripts/extenders/lego/applications/anim8/#anim8_set","title":"Anim8_Set","text":"

Anim8_Set

Sets the value of the object.

func void Anim8_Set(var int handle, var int value)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/anim8/#anim8_empty","title":"Anim8_Empty","text":"

Anim8_Empty

Indicates whether the object is empty, i.e. has no more commands to process.

func int Anim8_Empty(var int handle)\n
Parameters

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":"

Anim8_RemoveIfEmpty

If desired, Anim8 can automatically delete an object after it is empty.

func void Anim8_RemoveIfEmpty(var int handle, var int on)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/anim8/#anim8_removedataifempty","title":"Anim8_RemoveDataIfEmpty","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/anim8/#anim8_1","title":"Anim8","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/anim8/#anim8q","title":"Anim8q","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/anim8/#anim8_callonremove","title":"Anim8_CallOnRemove","text":"

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)\n
Parameters "},{"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":"

Info

Dependencies: - PermMem - View Implementation: Bars.d on GitHub

This package makes it very easy to add new bars, for e.g. stamina.

"},{"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/#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":"

Bar_Create

Creates a new bar from a constructor instance.

func int Bar_Create(var int inst)\n

Parameters

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":"

Bar_Delete

Deletes a bar from the screen and from memory.

func void Bar_Delete(var int bar)\n

Parameters

"},{"location":"zengin/scripts/extenders/lego/applications/bars/#bar_setmax","title":"Bar_SetMax","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/bars/#bar_setvalue","title":"Bar_SetValue","text":"

Bar_SetValue

Sets the value of the bar.

func void Bar_SetValue(var int bar, var int val)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/bars/#bar_setpercent","title":"Bar_SetPercent","text":"

Bar_SetPercent

Sets the value of the bar but as a percentage (0..100).

func void Bar_SetPercent(var int bar, var int perc)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/bars/#bar_setpromille","title":"Bar_SetPromille","text":"

Bar_SetPromille

Sets the value of the bar but per mille (0..1000).

func void Bar_SetPromille(var int bar, var int pro)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/bars/#bar_hide","title":"Bar_Hide","text":"

Bar_Hide

Hides a bar. It will not be deleted.

func void Bar_Hide(var int bar)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/bars/#bar_show","title":"Bar_Show","text":"

Bar_Show

Displays a bar again after using Bar_Hide.

func void Bar_Show(var int bar)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/bars/#bar_moveto","title":"Bar_MoveTo","text":"

Bar_MoveTo

Move the bar to virtual position.

func void Bar_MoveTo(var int bar, var int x, var int y)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/bars/#bar_movetopxl","title":"Bar_MoveToPxl","text":"

Bar_MoveToPxl

Move the bar to pixel position.

func void Bar_MoveToPxl(var int bar, var int x, var int y)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/bars/#bar_setalpha","title":"Bar_SetAlpha","text":"

Bar_SetAlpha

Sets the transparency of the bar.

func void Bar_SetAlpha(var int bar, var int alpha)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/bars/#bar_setbartexture","title":"Bar_SetBarTexture","text":"

Bar_SetBarTexture

Sets the foreground texture of the bar.

func void Bar_SetBarTexture(var int bar, var string barTex)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/bars/#bar_setbacktexture","title":"Bar_SetBackTexture","text":"

Bar_SetBackTexture

Sets the background texture of the bar.

func void Bar_SetBackTexture(var int bar, var string backTex)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/bars/#bar_resize","title":"Bar_Resize","text":"

Bar_Resize

Resize an existing bar.

func void Bar_Resize(var int bar, var int width, var int height)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/bars/#bar_resizepxl","title":"Bar_ResizePxl","text":"

Bar_ResizePxl

Resize existing bar (in pixels).

func void Bar_ResizePxl(var int bar, var int x, var int y)\n
Parameters "},{"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":"

Info

Dependencies: - Floats - View - Random - Anim8 Implementation: Bloodsplats.d on GitHub

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/#initialization","title":"Initialization","text":"

Initialize with LeGo_Bloodsplats flag.

LeGo_Init(LeGo_Bloodsplats);\n
"},{"location":"zengin/scripts/extenders/lego/applications/bloodsplats/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/applications/bloodsplats/#bloodsplat","title":"Bloodsplat","text":"

Bloodsplat

Puts a blood splatter on the screen.

func void Bloodsplat(var int damage)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/bloodsplats/#bloodsplats_rage","title":"Bloodsplats_Rage","text":"

Bloodsplats_Rage

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":"

Npc_GetPercFunc

oCNpc::GetPerceptionFunc engine function wrapper

func int Npc_GetPercFunc(var C_Npc npc, var int type)\n
Parameters

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":"

Info

Dependencies: - PermMem - FrameFunctions Implementation: Buffs.d on GitHub

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/#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/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/applications/buffs/#buff_apply","title":"Buff_Apply","text":"

Buff_Apply

Applies a status effect to an NPC.

func int Buff_Apply(var C_NPC npc, var int buff)\n
Parameters

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_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)\n
Parameters

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_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)\n
Parameters

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":"

Buff_Refresh

Resets the duration of the buff.

func void Buff_Refresh(var int buffHandle)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/buffs/#buff_remove","title":"Buff_Remove","text":"

Buff_Remove

Removes the buff from the all NPCs.

func void Buff_Remove(var int buffHandle)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/buffs/#buff_removeall","title":"Buff_RemoveAll","text":"

Buff_RemoveAll

Removes the buffs form the NPC.

func void Buff_RemoveAll(var C_NPC npc, var int buffInstance)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/buffs/#buff_getnpc","title":"Buff_GetNpc","text":"

Buff_GetNpc

Returns a pointer to the NPC, which is affected by the buff.

func int Buff_GetNpc(var int buffHandle)\n
Parameters

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":"

Buff_Has

Checks if the NPC already has an effect applied.

func int Buff_Has(var C_NPC npc, var int buff)\n
Parameters

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":"

SAVE_GetFuncID

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":"

Info

Dependencies: - PermMem - View Implementation: Buffs.d on GitHub

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/#initialization","title":"Initialization","text":"

Initialize with LeGo_Buttons flag.

LeGo_Init(LeGo_Buttons);\n
"},{"location":"zengin/scripts/extenders/lego/applications/buttons/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/applications/buttons/#button_create","title":"Button_Create","text":"

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)\n
Parameters

Return value

The function returns a handle to created button.

"},{"location":"zengin/scripts/extenders/lego/applications/buttons/#button_createpxl","title":"Button_CreatePxl","text":"

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)\n
Parameters

Return value

The function returns a handle to created button.

"},{"location":"zengin/scripts/extenders/lego/applications/buttons/#button_delete","title":"Button_Delete","text":"

Button_Delete

Completely deletes a button.

func void Button_Delete(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/buttons/#button_show","title":"Button_Show","text":"

Button_Show

Shows the button and makes it respond to the mouse.

func void Button_Show(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/buttons/#button_hide","title":"Button_Hide","text":"

Button_Hide

Hides the button and disables it, so it is no longer responding to the mouse.

func void Button_Hide(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/buttons/#button_settexture","title":"Button_SetTexture","text":"

Button_SetTexture

Sets the texture of the button.

func void Button_SetTexture(var int hndl, var string tex)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/buttons/#button_setcaption","title":"Button_SetCaption","text":"

Button_SetCaption

Displays a centered text on the button.

func void Button_SetCaption(var int hndl, var string caption, var string font)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/buttons/#button_createmouseover","title":"Button_CreateMouseover","text":"

Button_CreateMouseover

Attaches a mouseover box to the cursor.

func void Button_CreateMouseover(var string text, var string font)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/buttons/#button_deletemouseover","title":"Button_DeleteMouseover","text":"

Button_DeleteMouseover

Deletes the mouseover box.

func void Button_DeleteMouseover()\n
"},{"location":"zengin/scripts/extenders/lego/applications/buttons/#button_activate","title":"Button_Activate","text":"

Button_Activate

Activates the button, so it reacts to the mouse. Does not change the visibility.

func void Button_Activate(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/buttons/#button_deactivate","title":"Button_Deactivate","text":"

Button_Deactivate

Disables the button, so it no longer reacts to the mouse.

func void Button_Deactivate(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/buttons/#button_setuserdata","title":"Button_SetUserData","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/buttons/#button_getuserdata","title":"Button_GetUserData","text":"

Button_GetUserData

Gets the user data of the button.

func int Button_GetUserData(var int hndl)\n
Parameters

Return value

The function returns the user data of the button.

"},{"location":"zengin/scripts/extenders/lego/applications/buttons/#button_getstate","title":"Button_GetState","text":"

Button_GetState

Gets the status of the button as a bit field. See User Constants.

func int Button_GetState(var int hndl)\n
Parameters

Return value

The function returns the status of the button.

"},{"location":"zengin/scripts/extenders/lego/applications/buttons/#button_move","title":"Button_Move","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/buttons/#button_movevrt","title":"Button_MoveVrt","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/buttons/#button_moveto","title":"Button_MoveTo","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/buttons/#button_movetovrt","title":"Button_MoveToVrt","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/buttons/#button_getviewhandle","title":"Button_GetViewHandle","text":"

Button_GetViewHandle

Returns the button's zCView as a handle.

func int Button_GetViewHandle(var int hndl)\n
Parameters

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":"

Button_GetViewPtr

Returns the button's zCView as a pointer.

func int Button_GetViewPtr(var int hndl)\n
Parameters

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":"

Button_GetView

Returns the button's zCView as an object.

func zCView Button_GetView(var int hndl)\n
Parameters

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":"

Button_GetCaptionPtr

Returns the pointer to the text of the button.

func int Button_GetCaptionPtr(var int hndl)\n
Parameters

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":"

Info

Dependencies: - PermMem - HookEngine Implementation: ConsoleCommands.d on GitHub

This package allows you to create new console commands.

"},{"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/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/applications/console_commands/#cc_register","title":"CC_Register","text":"

CC_Register

Registers a new console command.

func void CC_Register(var func f, var string cmdPrefix, var string description)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/console_commands/#cc_remove","title":"CC_Remove","text":"

CC_Remove

Removes a function from the console commands.

func void CC_Remove(var func f)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/console_commands/#cc_active","title":"CC_Active","text":"

CC_Active

Checks whether the function passed is already part of a console command.

func int CC_Active(var func f)\n
Parameters

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":"

Info

Dependencies: - Floats - FrameFunctions - View Implementation: Cursor.d on GitHub

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/#initialization","title":"Initialization","text":"

Initialize with LeGo_Cursor flag.

LeGo_Init(LeGo_Cursor);\n
"},{"location":"zengin/scripts/extenders/lego/applications/cursor/#variables","title":"Variables","text":""},{"location":"zengin/scripts/extenders/lego/applications/cursor/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/applications/cursor/#cursor_hide","title":"Cursor_Hide","text":"

Cursor_Hide

Hides the displayed mouse cursor.

func void Cursor_Hide()\n
"},{"location":"zengin/scripts/extenders/lego/applications/cursor/#cursor_show","title":"Cursor_Show","text":"

Cursor_Show

Shows the mouse cursor.

func void Cursor_Show()\n
"},{"location":"zengin/scripts/extenders/lego/applications/cursor/#setmouseenabled","title":"SetMouseEnabled","text":"

SetMouseEnabled

Can manually enable or disable the mouse.

func void SetMouseEnabled(var int enabled)\n
Parameters "},{"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":"

Info

Dependencies: - AI_Function Implementation: Dialoggestures.d on GitHub

This package can modify the NPCs' gestures during dialogue to better bring out emotions.

"},{"location":"zengin/scripts/extenders/lego/applications/dialoggestures/#initialization","title":"Initialization","text":"

N/A

"},{"location":"zengin/scripts/extenders/lego/applications/dialoggestures/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/applications/dialoggestures/#diag","title":"DIAG","text":"

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\");\n
DIAG_Prefix and DIAG_Suffix are user constants.

func void DIAG(var string AniName, var int Min, var int Max)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/dialoggestures/#diag_reset","title":"DIAG_Reset","text":"

DIAG_Reset

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":"

DIAG_SetAni

Sets animation directly.

func void DIAG_SetAni(var string AniName)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/dialoggestures/#diag_setminmax","title":"DIAG_SetMinMax","text":"

DIAG_SetMinMax

Sets animation numbers directly.

func void DIAG_SetMinMax(var int min, var int max)\n
Parameters "},{"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":"

Info

Dependencies: - Interface - HookEngine Implementation: Focusnames.d on GitHub

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/#initialization","title":"Initialization","text":"

Initialize with LeGo_Focusnames flag.

LeGo_Init(LeGo_Focusnames);\n
"},{"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":"

Focusnames_Color_Friendly

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":"

Focusnames_Color_Neutral

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":"

Focusnames_Color_Angry

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":"

Focusnames_Color_Hostile

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":"

Info

Dependencies: - EventHandler - Saves Implementation: Gamestate.d on GitHub

Gamestate package allows to check for different game states (game start, game load or level change).

"},{"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/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/applications/gamestate/#gamestate_addlistener","title":"Gamestate_AddListener","text":"

Gamestate_AddListener

Adds a listener/handler to the game-state event.

func void Gamestate_AddListener(var func listener)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/gamestate/#gamestate_removelistener","title":"Gamestate_RemoveListener","text":"

Gamestate_RemoveListener

Removes game-state listener.

func void Gamestate_RemoveListener(var func listener)\n
Parameters "},{"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":"

Info

Dependencies: - Talents Implementation: Names.d on GitHub

Allows the user to change NPC name e.g. after he shows up.

"},{"location":"zengin/scripts/extenders/lego/applications/names/#initialization","title":"Initialization","text":"

N/A

"},{"location":"zengin/scripts/extenders/lego/applications/names/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/applications/names/#setname","title":"SetName","text":"

SetName

Should be set in InitGlobal().

func void SetName(var C_NPC npc, var string name)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/names/#showname","title":"ShowName","text":"

ShowName

Permanently displays the name set by SetName function above the npc.

func void ShowName(var C_NPC npc)\n
Parameters "},{"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":"

Info

Dependencies: - List - View - PermMem Implementation: Render.d on GitHub

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/#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/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/applications/render/#render_additemprio","title":"Render_AddItemPrio","text":"

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)\n
Parameters

Return value

The function returns a handle of the render object.

"},{"location":"zengin/scripts/extenders/lego/applications/render/#render_additem","title":"Render_AddItem","text":"

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)\n
Parameters

Return value

The function returns a handle of the render object.

"},{"location":"zengin/scripts/extenders/lego/applications/render/#render_addviewprio","title":"Render_AddViewPrio","text":"

Render_AddViewPrio

Generates the render of a View, with a manually specified priority.

func int Render_AddViewPrio(var int view, var int priority)\n
Parameters

Return value

The function returns a handle of the render object.

"},{"location":"zengin/scripts/extenders/lego/applications/render/#render_addview","title":"Render_AddView","text":"

Render_AddView

Generates the render of a View, with priority set to 0.

func int Render_AddView(var int view)\n
Parameters

Return value

The function returns a handle of the render object.

"},{"location":"zengin/scripts/extenders/lego/applications/render/#render_openview","title":"Render_OpenView","text":"

Render_OpenView

Opens a render object. Only open render objects are displayed.

func void Render_OpenView(var int handle)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/render/#render_closeview","title":"Render_CloseView","text":"

Render_CloseView

Closes a render object. Only open render objects are displayed.

func void Render_CloseView(var int handle)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/render/#render_remove","title":"Render_Remove","text":"

Render_Remove

Deletes a render object. The associated view is deleted automatically.

func void Render_Remove(var int handle)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/saves/","title":"Saves","text":""},{"location":"zengin/scripts/extenders/lego/applications/saves/#saves","title":"Saves","text":"

Info

Dependencies: - BinaryMachines Implementation: Saves.d on GitHub

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/#initialization","title":"Initialization","text":"

Initialize with LeGo_Saves flag.

LeGo_Init(LeGo_Saves);\n
"},{"location":"zengin/scripts/extenders/lego/applications/saves/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/applications/saves/#bw_savegame","title":"BW_Savegame","text":"

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()\n
"},{"location":"zengin/scripts/extenders/lego/applications/saves/#br_savegame","title":"BR_Savegame","text":"

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()\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":"

Info

Dependencies: - AI_Function Implementation: Trialoge.d on GitHub

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/#initialization","title":"Initialization","text":"

Initialize with LeGo_Trialoge flag.

LeGo_Init(LeGo_Trialoge);\n
"},{"location":"zengin/scripts/extenders/lego/applications/trialoge/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/applications/trialoge/#equipweapon","title":"EquipWeapon","text":"

EquipWeapon

Sektenspinner's function. Makes NPC equip a weapon.

func void EquipWeapon(var C_NPC slf, var int ItemInstance)\n
Parameters

Configuration

const int EquipWeapon_TogglesEquip = 1

Above constant configures the behaviour of the function when trying to equip an already equipped weapon:

"},{"location":"zengin/scripts/extenders/lego/applications/trialoge/#npc_getarmor","title":"Npc_GetArmor","text":"

Npc_GetArmor

Returns NPC's equipped armor.

func int Npc_GetArmor(var C_NPC slf)\n
Parameters

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":"

Npc_GetMeleeWeapon

Returns NPC's equipped melee weapon.

func int Npc_GetMeleeWeapon(var C_NPC slf)\n
Parameters

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":"

Npc_GetRangedWeapon

Returns NPC's equipped ranged weapon.

func int Npc_GetRangedWeapon(var c_npc slf)\n
Parameters

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":"

Npc_TradeItem

Swaps NPCs equipped weapon.

func void Npc_TradeItem(var c_npc slf, var int itm0, var int itm1) \n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/trialoge/#diacam_update","title":"DiaCAM_Update","text":"

DiaCAM_Update

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":"

DiaCAM_Disable

Completely disable the dialogue cameras.

func void DiaCAM_Disable()\n
"},{"location":"zengin/scripts/extenders/lego/applications/trialoge/#diacam_enable","title":"DiaCAM_Enable","text":"

DiaCAM_Enable

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":"

TRIA_Wait

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":"

TRIA_Invite

Invites an NPC into a conversation. Must be called before TRIA_Start.

func void TRIA_Invite(var C_NPC slf)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/trialoge/#tria_start","title":"TRIA_Start","text":"

TRIA_Start

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":"

TRIA_Barrier

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":"

TRIA_Next

Sets the called npc to self.

func void TRIA_Next(var C_NPC n0)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/trialoge/#tria_cam","title":"TRIA_Cam","text":"

TRIA_Cam

Starts a tracking shot.

func void TRIA_Cam(var string evt)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/trialoge/#tria_finish","title":"TRIA_Finish","text":"

TRIA_Finish

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":"

Info

Dependencies: - HookEngine Implementation: AI_Function.d on GitHub

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/#initialization","title":"Initialization","text":"

Initialize with LeGo_AI_Function flag.

LeGo_Init(LeGo_AI_Function);\n
"},{"location":"zengin/scripts/extenders/lego/tools/ai_function/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/tools/ai_function/#ai_function_1","title":"AI_Function","text":"

AI_Function

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

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":"

Info

Dependencies: - None Implementation: BinaryMachines.d on GitHub

This package allows you to create and write your own files anywhere in the file system.

"},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#initialization","title":"Initialization","text":"

N/A

"},{"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":"

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)\n
Parameters

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":"

BW_Close

Closes the current write stream.

func void BW_Close()\n
"},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#bw","title":"BW","text":"

BW

Writes length bytes from the data to the stream, maximum 4 bytes.

func void BW(var int data, var int length)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#bw_int","title":"BW_Int","text":"

BW_Int

Writes 4 bytes from the data to the stream. Same as BW(data, 4).

func void BW_Int(var int data)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#bw_char","title":"BW_Char","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#bw_string","title":"BW_String","text":"

BW_String

Writes the data terminated with \\0 to the stream.

func void BW_String(var string data)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#bw_byte","title":"BW_Byte","text":"

BW_Byte

Writes a byte from the data to the stream. Same as BW(data, 1).

func void BW_Byte(var int data)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#bw_bytes","title":"BW_Bytes","text":"

BW_Bytes

Writes length of bytes from the pointer dataPtr to the stream.

func void BW_Bytes(var int dataPtr, var int length)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#bw_text","title":"BW_Text","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#bw_nextline","title":"BW_NextLine","text":"

BW_NextLine

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":"

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)\n
Parameters

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":"

BR_Close

Closes the current read stream.

func void BR_Close()\n
"},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#br","title":"BR","text":"

BR

Reads bytes from the stream.

func int BR(var int length)\n
Parameters

Return value

The function returns the value of read bytes.

"},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#br_int","title":"BR_Int","text":"

BR_Int

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":"

BR_Char

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":"

BR_String

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":"

BR_Byte

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":"

BR_Bytes

Reads bytes from the stream.

func int BR_Bytes(var int length)\n
Parameters

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":"

BR_TextLine

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":"

BR_Text

Reads a string of the given length from a stream.

func string BR_Text(var int length)\n
Parameters

Return value

The function returns the read string.

"},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#br_nextline","title":"BR_NextLine","text":"

BR_NextLine

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":"

WIN_GetLastError

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":"

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)\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":"

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)\n
Parameters

Full description of parameters can be found here

"},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#win_readfile","title":"WIN_ReadFile","text":"

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)\n
Parameters

Full description of parameters can be found here

"},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#win_closehandle","title":"WIN_CloseHandle","text":"

WIN_CloseHandle

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":"

WIN_GetFileSize

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/draw3d/","title":"Draw3D","text":""},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#draw3d","title":"Draw3D","text":"

Info

Dependencies: - PermMem - HookEngine Implementation: Draw3D.d on GitHub

This package allows you to draw various shapes (such as lines or bounding boxes) in three-dimensional space. This makes debugging visualizations of coordinates in the world possible.

"},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#initialization","title":"Initialization","text":"

Initialize with LeGo_Draw3D flag.

LeGo_Init(LeGo_Draw3D);\n
"},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#line","title":"Line","text":""},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#drawline","title":"DrawLine","text":"

DrawLine

Creates and draws a new line and returns its handle.

func int DrawLine(var int startPosPtr, var int endPosPtr, var int color)\n
Parameters

Return value

The function returns a new PermMem handle to the line.

"},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#drawline3","title":"DrawLine3","text":"

DrawLine3

DrawLine, but with world coordinates as parameters, instead of zVEC3 pointers.

func int DrawLine3(var int x1, var int y1, var int z1,var int x2, var int y2, var int z2,var int color)\n
Parameters

Return value

The function returns a new PermMem handle to the line.

"},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#drawlineaddr","title":"DrawLineAddr","text":"

DrawLineAddr

DrawLine, but with the address of a line as parameter.

func int DrawLineAddr(var int linePtr, var int color)\n
Parameters

Return value

The function returns a new PermMem handle to the line.

"},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#updateline","title":"UpdateLine","text":"

UpdateLine

Changes the coordinates of a specific line.

func void UpdateLine(var int hndl, var int startPosPtr, var int endPosPtr)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#updateline3","title":"UpdateLine3","text":"

UpdateLine3

UpdateLine, but with world coordinates as parameters, instead of zVEC3 pointers.

func void UpdateLine3(var int hndl,var int x1, var int y1, var int z1,var int x2, var int y2, var int z2)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#updatelineaddr","title":"UpdateLineAddr","text":"

UpdateLineAddr

UpdateLine, but with the address of a line as parameter.

func void UpdateLineAddr(var int hndl, var int linePtr)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#setlinecolor","title":"SetLineColor","text":"

SetLineColor

Changes the color of a specific line.

func void SetLineColor(var int hndl, var int color)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#eraseline","title":"EraseLine","text":"

EraseLine

Deletes a line from the world and the handle.

func void EraseLine(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#linevisible","title":"LineVisible","text":"

LineVisible

Returns whether a line is visible.

func int LineVisible(var int hndl)\n
Parameters

Return value

The function returns TRUE if the line is visible/displayed. FALSE is returned otherwise.

"},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#showline","title":"ShowLine","text":"

ShowLine

Displays the line.

func void ShowLine(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#hideline","title":"HideLine","text":"

HideLine

Hides the line.

func void HideLine(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#toggleline","title":"ToggleLine","text":"

ToggleLine

Changes the visibility of a line. If displayed - hide, if hidden - display.

func void ToggleLine(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#sphere","title":"Sphere","text":""},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#drawsphere","title":"DrawSphere","text":"

DrawSphere

Creates and draws a new sphere (visualized as a circle) and returns its handle.

func int DrawSphere(var int centerPosPtr, var int radius, var int color)\n
Parameters

Return value

The function returns a new PermMem handle to the sphere.

"},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#drawsphere3","title":"DrawSphere3","text":"

DrawSphere3

DrawSphere, but with world coordinates as parameters, instead of zVEC3 pointers.

func int DrawSphere3(var int x1, var int y1, var int z1, var int radius, var int color)\n
Parameters

Return value

The function returns a new PermMem handle to the sphere.

"},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#drawsphereaddr","title":"DrawSphereAddr","text":"

DrawSphereAddr

DrawSphere, but with the address of a sphere as a parameter.

func int DrawSphereAddr(var int spherePtr, var int color)\n
Parameters

Return value

The function returns a new PermMem handle to the sphere.

"},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#updatesphere","title":"UpdateSphere","text":"

UpdateSphere

Changes the coordinates and/or size of an existing sphere.

func void UpdateSphere(var int hndl, var int centerPosPtr, var int radius)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#updatesphere3","title":"UpdateSphere3","text":"

UpdateSphere3

UpdateSphere, but with world coordinates as parameters, instead of zVEC3 pointers.

func void UpdateSphere3(var int hndl, var int x1, var int y1, var int z1, var int radius)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#updatesphereaddr","title":"UpdateSphereAddr","text":"

UpdateSphereAddr

UpdateSphere, but with the address of a sphere as a parameter.

func void UpdateSphereAddr(var int hndl, var int spherePtr)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#setspherecolor","title":"SetSphereColor","text":"

SetSphereColor

Changes the color of a specific sphere.

func void SetSphereColor(var int hndl, var int color)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#erasesphere","title":"EraseSphere","text":"

EraseSphere

Deletes a sphere from the world and its handle.

func void EraseSphere(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#spherevisible","title":"SphereVisible","text":"

SphereVisible

Returns whether a sphere is visible.

func int SphereVisible(var int hndl)\n
Parameters

Return value

The function returns TRUE if the sphere is visible/displayed. FALSE is returned otherwise.

"},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#showsphere","title":"ShowSphere","text":"

ShowSphere

Displays the sphere.

func void ShowSphere(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#hidesphere","title":"HideSphere","text":"

HideSphere

Hides the sphere.

func void HideSphere(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#togglesphere","title":"ToggleSphere","text":"

ToggleSphere

Changes the visibility of a sphere. If displayed - hide, if hidden - display.

func void ToggleSphere(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#bounding-box","title":"Bounding Box","text":""},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#drawbbox","title":"DrawBBox","text":"

DrawBBox

Creates and draws a new bounding box and returns its handle.

func int DrawBBox(var int startPosPtr, var int endPosPtr, var int color)\n
Parameters

Return value

The function returns a new PermMem handle to the bounding box.

"},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#drawbbox3","title":"DrawBBox3","text":"

DrawBBox3

DrawBBox, but with world coordinates as parameters, instead of zVEC3 pointers.

func int DrawBBox3(var int x1, var int y1, var int z1, var int x2, var int y2, var int z2, var int color)\n
Parameters

Return value

The function returns a new PermMem handle to the bounding box.

"},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#drawbboxaddr","title":"DrawBBoxAddr","text":"

DrawBBoxAddr

DrawBBox, but with the address of a bounding box as a parameter.

func int DrawBBoxAddr(var int bboxPtr, var int color)\n
Parameters

Return value

The function returns a new PermMem handle to the bounding box.

"},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#updatebbox","title":"UpdateBBox","text":"

UpdateBBox

Changes the coordinates of an existing bounding box.

func void UpdateBBox(var int hndl, var int startPosPtr, var int endPosPtr)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#updatebbox3","title":"UpdateBBox3","text":"

UpdateBBox3

UpdateBBox, but with world coordinates as parameters, instead of zVEC3 pointers.

func void UpdateBBox3(var int hndl, var int x1, var int y1, var int z1, var int x2, var int y2, var int z2)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#updatebboxaddr","title":"UpdateBBoxAddr","text":"

UpdateBBoxAddr

UpdateBBox, but with the address of a bounding box as a parameter.

func void UpdateBBoxAddr(var int hndl, var int bboxPtr)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#setbboxcolor","title":"SetBBoxColor","text":"

SetBBoxColor

Changes the color of a specific bounding box.

func void SetBBoxColor(var int hndl, var int color)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#erasebbox","title":"EraseBBox","text":"

EraseBBox

Deletes a bounding box from the world and its handle.

func void EraseBBox(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#bboxvisible","title":"BBoxVisible","text":"

BBoxVisible

Returns whether a bounding box is visible.

func int BBoxVisible(var int hndl)\n
Parameters

Return value

The function returns TRUE if the bounding box is visible/displayed. FALSE is returned otherwise.

"},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#showbbox","title":"ShowBBox","text":"

ShowBBox

Displays the bounding box.

func void ShowBBox(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#hidebbox","title":"HideBBox","text":"

HideBBox

Hides the bounding box.

func void HideBBox(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#togglebbox","title":"ToggleBBox","text":"

ToggleBBox

Changes the visibility of a bounding box. If displayed - hide, if hidden - display.

func void ToggleBBox(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#oriented-bounding-box","title":"Oriented Bounding Box","text":""},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#drawobboxaddr","title":"DrawOBBoxAddr","text":"

DrawOBBoxAddr

Creates and draws a new oriented bounding box based on the address of an oriented bounding box and returns its handle.

func int DrawOBBoxAddr(var int oBBoxPtr, var int color)\n
Parameters

Return value

The function returns a new PermMem handle to the oriented bounding box.

"},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#updateobboxaddr","title":"UpdateOBBoxAddr","text":"

UpdateOBBoxAddr

Changes the coordinates and orientation of an existing oriented bounding box.

func void UpdateOBBoxAddr(var int hndl, var int oBBoxPtr)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#setobboxcolor","title":"SetOBBoxColor","text":"

SetOBBoxColor

Changes the color of a specific oriented bounding box.

func void SetOBBoxColor(var int hndl, var int color)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#eraseobbox","title":"EraseOBBox","text":"

EraseOBBox

Deletes an oriented bounding box from the world and its handle.

func void EraseOBBox(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#obboxvisible","title":"OBBoxVisible","text":"

OBBoxVisible

Returns whether an oriented bounding box is visible.

func int OBBoxVisible(var int hndl)\n
Parameters

Return value

The function returns TRUE if the oriented bounding box is visible/displayed. FALSE is returned otherwise.

"},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#showobbox","title":"ShowOBBox","text":"

ShowOBBox

Displays the oriented bounding box.

func void ShowOBBox(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#hideobbox","title":"HideOBBox","text":"

HideOBBox

Hides the oriented bounding box.

func void HideOBBox(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#toggleobbox","title":"ToggleOBBox","text":"

ToggleOBBox

Changes the visibility of an oriented bounding box. If displayed - hide, if hidden - display.

func void ToggleOBBox(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#eraseall","title":"EraseAll","text":"

EraseAll

Deletes all draw elements and their handles from the world.

func void EraseAll()\n
"},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#examples","title":"Examples","text":"

World coordinates are not particularly informative. This package aims to help and allows visualizing world coordinates in the form of lines, spheres (as circles), bounding boxes, and oriented bounding boxes in three-dimensional space.

"},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#visualizing-straight-line-to-an-npc","title":"Visualizing Straight Line to an NPC","text":"

To draw a line between two NPCs, you only need the coordinates of the two NPCs.

func void Example_1() {\n    var zCVob her; her = Hlp_GetNpc(hero);\n    var int point1[3];\n    point1[0] = her.trafoObjToWorld[3];\n    point1[1] = her.trafoObjToWorld[7];\n    point1[2] = her.trafoObjToWorld[11];\n\n    var zCVob oth; oth = Hlp_GetNpc(PC_ThiefOW);\n    var int point2[3];\n    point2[0] = oth.trafoObjToWorld[3];\n    point2[1] = oth.trafoObjToWorld[7];\n    point2[2] = oth.trafoObjToWorld[11];\n\n    var int hndl;\n\n    if (!Hlp_IsValidHandle(hndl)) {\n        hndl = DrawLine(_@(point1), _@(point2), zCOLOR_GREEN);\n    } else {\n        UpdateLine(hndl, _@(point1), _@(point2));\n    };\n};\n

This function can now be called continuously using FrameFunction to continuously adjust the straight line according to the positions of the characters.

FF_Apply(Example_1);\n

Alternatively, you can write the function as follows:

func void Example_1() {\n    var zCVob her; her = Hlp_GetNpc(hero);\n    var zCVob oth; oth = Hlp_GetNpc(PC_ThiefOW);\n\n    var int hndl;\n\n    if (!Hlp_IsValidHandle(hndl)) {\n        hndl = DrawLine3(her.trafoObjToWorld[3], her.trafoObjToWorld[7], her.trafoObjToWorld[11],\n                         oth.trafoObjToWorld[3], oth.trafoObjToWorld[7], oth.trafoObjToWorld[11],\n                         zCOLOR_GREEN);\n    } else {\n        UpdateLine3(hndl, her.trafoObjToWorld[3], her.trafoObjToWorld[7], her.trafoObjToWorld[11],\n                          oth.trafoObjToWorld[3], oth.trafoObjToWorld[7], oth.trafoObjToWorld[11]);\n    };\n};\n
"},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#visualizing-a-distance-of-5-meters","title":"Visualizing a Distance of 5 Meters","text":"

It becomes more interesting when dealing with \"abstract\" coordinates. For instance, you can visualize a \"safety distance\" around the player using a bounding box or a sphere, to check AI reactions at certain distances.

//*******************\n//   Bounding Box\n//*******************\nfunc void Example_2() {\n    var zCVob her; her = Hlp_GetNpc(hero);\n\n    // Safety distance around the player (5 meters)\n    var int distance; distance = mkf(500);\n\n    // Lower corner of the bounding box\n    var int point1[3];\n    point1[0] = subf(her.trafoObjToWorld[3],  distance);\n    point1[1] = subf(her.trafoObjToWorld[7],  distance);\n    point1[2] = subf(her.trafoObjToWorld[11], distance);\n\n    // Upper corner of the bounding box (diagonally opposite)\n    var int point2[3];\n    point2[0] = addf(her.trafoObjToWorld[3],  distance);\n    point2[1] = addf(her.trafoObjToWorld[7],  distance);\n    point2[2] = addf(her.trafoObjToWorld[11], distance);\n\n    var int hndl;\n\n    if (!Hlp_IsValidHandle(hndl)) {\n        hndl = DrawBBox(_@(point1), _@(point2), zCOLOR_BLUE);\n    } else {\n        UpdateBBox(hndl, _@(point1), _@(point2));\n    };\n};\n

To draw a sphere with a radius of 5 meters centered at a specific point, you only need the coordinates of the sphere's center.

//*******************\n//      Sphere\n//*******************\nfunc void Example_2() {\n    var zCVob her; her = Hlp_GetNpc(hero);\n    var int centerPoint[3];\n    centerPoint[0] = her.trafoObjToWorld[3];\n    centerPoint[1] = her.trafoObjToWorld[7];\n    centerPoint[2] = her.trafoObjToWorld[11];\n\n    var int hndl;\n\n    if (!Hlp_IsValidHandle(hndl)) {\n        hndl = DrawSphere(_@(centerPoint), 500, zCOLOR_BLUE);\n    } else {\n        UpdateSphere(hndl, _@(centerPoint), 500);\n    };\n};\n

Similarly, you could continuously update the bounding box/sphere using a FrameFunction.

"},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#changing-color-or-hidingdeleting-draw-elements","title":"Changing Color or Hiding/Deleting Draw Elements","text":"

If you want to visualize an AI reaction, for example, you can change the color. Color values can be created using the RGBA function based on RGB values.

func void ObserveIntruder(var int hndl, var C_NPC oth) {\n    if (Npc_HasDetectedNpc(oth, hero)) {\n        // Color is now red, position and size of the bounding box remain unchanged\n        SetBBoxColor(hndl, zCOLOR_RED); // zCOLOR_RED == RGBA(255, 0, 0, 255)\n    };\n};\n

Draw elements can also be easily hidden or completely deleted.

func void CheckDialog(var int hndl) {\n    if (!InfoManager_HasFinished()) {\n        // Hide bounding box during dialogs\n        HideBBox(hndl);\n\n        // EraseBBox(hndl); // Or delete including the handle\n    };\n};\n
"},{"location":"zengin/scripts/extenders/lego/tools/event_handler/","title":"EventHandler","text":""},{"location":"zengin/scripts/extenders/lego/tools/event_handler/#eventhandler","title":"EventHandler","text":"

Info

Dependencies: - PermMem Implementation: EventHandler.d on GitHub

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/#initialization","title":"Initialization","text":"

Initialize with LeGo_EventHandler flag.

LeGo_Init(LeGo_EventHandler);\n
"},{"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":"

Event_Create

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":"

Event_Delete

Alias to PermMem delete. Cleans up the handle.

func void Event_Delete(var int event)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/event_handler/#event_empty","title":"Event_Empty","text":"

Event_Empty

Checks whether the event is \"empty\", i.e. nothing will happen after its execution.

func int Event_Empty(var int event)\n
Parameters

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":"

Event_Has

Checks if function is added to the event.

func int Event_Has(var int event, var func function)\n
Parameters

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":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/event_handler/#event_addonce","title":"Event_AddOnce","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/event_handler/#event_remove","title":"Event_Remove","text":"

Event_Remove

Removes the event handler function from the event.

func void Event_Remove(var int event, var func function)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/event_handler/#event_execute","title":"Event_Execute","text":"

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)\n
Parameters "},{"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":"

EventPtr_Create

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":"

EventPtr_Delete

Alias to PermMem free. Cleans up the pointer.

func void EventPtr_Delete(var int eventPtr)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/event_handler/#eventptr_empty","title":"EventPtr_Empty","text":"

EventPtr_Empty

Checks whether the event is \"empty\", i.e. nothing will happen after its execution.

func int EventPtr_Empty(var int eventPtr)\n
Parameters

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":"

EventPtr_Has

Checks if function is added to an event.

func int EventPtr_Has(var int eventPtr, var func function)\n
Parameters

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_HasI

EventPtr_Has but with function ID instead of pointer. Used mainly internally.

func int EventPtr_HasI(var int eventPtr, var int id)\n
Parameters

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":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/event_handler/#eventptr_addi","title":"EventPtr_AddI","text":"

EventPtr_AddI

EventPtr_Add but with function ID instead of pointer. Used mainly internally.

func void EventPtr_AddI(var int eventPtr, var int id)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/event_handler/#eventptr_addonce","title":"EventPtr_AddOnce","text":"

EventPtr_AddOnce

Event_Add but checks if function is already added, to prevent duplicates.

func void EventPtr_AddOnce(var int eventPtr, var func function)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/event_handler/#eventptr_addoncei","title":"EventPtr_AddOnceI","text":"

EventPtr_AddOnceI

EventPtr_AddI but checks if function is already added, to prevent duplicates.

func void EventPtr_AddOnceI(var int eventPtr, var int id)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/event_handler/#eventptr_remove","title":"EventPtr_Remove","text":"

EventPtr_Remove

Removes a function from the event's call list.

func void EventPtr_Remove(var int eventPtr, var func function)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/event_handler/#eventptr_removei","title":"EventPtr_RemoveI","text":"

EventPtr_RemoveI

EventPtr_Remove but with function ID instead of pointer. Used mainly internally.

func void EventPtr_RemoveI(var int eventPtr, var int id)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/event_handler/#eventptr_execute","title":"EventPtr_Execute","text":"

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)\n
"},{"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":"

Info

Dependencies: - Floats - PermMem - HookEngine - Timer Implementation: FrameFunctions.d on GitHub

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/#initialization","title":"Initialization","text":"

Initialize with LeGo_FrameFunctions flag.

LeGo_Init(LeGo_FrameFunctions);\n
"},{"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":"

FF_Apply

Adds the Daedalus function function to the running FrameFunctions list. function is called each frame.

func void FF_Apply(var func function)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/frame_functions/#ff_applygt","title":"FF_ApplyGT","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/frame_functions/#ff_applydata","title":"FF_ApplyData","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/frame_functions/#ff_applyext","title":"FF_ApplyExt","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/frame_functions/#ff_applyextgt","title":"FF_ApplyExtGT","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/frame_functions/#ff_applyextdata","title":"FF_ApplyExtData","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/frame_functions/#ff_applyextdatagt","title":"FF_ApplyExtDataGT","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/frame_functions/#ff_applyonce","title":"FF_ApplyOnce","text":"

FF_ApplyOnce

Alias to FF_Apply, which only adds the function once, even after multiple calls.

func void FF_ApplyOnce(var func function)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/frame_functions/#ff_applyoncegt","title":"FF_ApplyOnceGT","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/frame_functions/#ff_applyoncedata","title":"FF_ApplyOnceData","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/frame_functions/#ff_applyonceext","title":"FF_ApplyOnceExt","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/frame_functions/#ff_applyonceextgt","title":"FF_ApplyOnceExtGT","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/frame_functions/#ff_applyonceextdata","title":"FF_ApplyOnceExtData","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/frame_functions/#ff_active","title":"FF_Active","text":"

FF_Active

Checks whether the function is active.

func int FF_Active(var func function)\n
Parameters

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":"

FF_ActiveData

Checks whether the function with the specified data is active.

func int FF_ActiveData(var func function, var int data)\n
Parameters

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":"

FF_Remove

Stops a specific FrameFunction.

func void FF_Remove(var func function)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/frame_functions/#ff_removeall","title":"FF_RemoveAll","text":"

FF_RemoveAll

Stops all intsnces of a specific FrameFunction.

func void FF_RemoveAll(var func function)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/frame_functions/#ff_removedata","title":"FF_RemoveData","text":"

FF_RemoveData

Stops a specific FrameFunction, with the specified value (see FF_ApplyExtData ).

func void FF_RemoveData(var func function, var int data)\n
Parameters "},{"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":"

Info

Dependencies: - PermMem Implementation: Hashtable.d on GitHub

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/#initialization","title":"Initialization","text":"

Initialize with LeGo_PermMem flag.

LeGo_Init(LeGo_PermMem);\n
"},{"location":"zengin/scripts/extenders/lego/tools/hashtables/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/tools/hashtables/#ht_createsized","title":"HT_CreateSized","text":"

HT_CreateSized

Generates a hashtable of the specified size.

func int HT_CreateSized(var int size)\n
Parameters

Return value

The function returns a handle to the created hashtable.

"},{"location":"zengin/scripts/extenders/lego/tools/hashtables/#ht_create","title":"HT_Create","text":"

HT_Create

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":"

HT_Insert

Inserts a value into the Hashtable.

func void HT_Insert(var int handle, var int val, var int key)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/hashtables/#ht_resize","title":"HT_Resize","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/hashtables/#ht_get","title":"HT_Get","text":"

HT_Get

Reads a value from the hashtable.

func int HT_Get(var int handle, var int key)\n
Parameters

Return value

The function returns the value associated with the key.

"},{"location":"zengin/scripts/extenders/lego/tools/hashtables/#ht_has","title":"HT_Has","text":"

HT_Has

Checks if the key already exist in hashtable.

func int HT_Has(var int handle, var int key)\n
Parameters

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":"

HT_Remove

Removes a key from the hashtable.

func void HT_Remove(var int handle, var int key)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/hashtables/#ht_change","title":"HT_Change","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/hashtables/#ht_insertorchange","title":"HT_InsertOrChange","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/hashtables/#ht_getnumber","title":"HT_GetNumber","text":"

HT_GetNumber

Returns the number of entries in a hashtable.

func int HT_GetNumber(var int handle)\n
Parameters

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":"

HT_ForEach

Performs a function for each value pair in the hashtable.

func void HT_ForEach(var int handle, var func fnc)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/hashtables/#ht_destroy","title":"HT_Destroy","text":"

HT_Destroy

Deletes the hashtable.

func void HT_Destroy(var int handle)\n
Parameters "},{"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":"

Info

Dependencies: - None Implementation: HookDaedalus.d on GitHub

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/#initialization","title":"Initialization","text":"

N/A

"},{"location":"zengin/scripts/extenders/lego/tools/hook_dae/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/tools/hook_dae/#hookdaedalusfunc","title":"HookDaedalusFunc","text":"

HookDaedalusFunc

Hooks the function.

func void HookDaedalusFunc(var func hooked, var func hook)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/hook_dae/#hookdaedalusfuncf","title":"HookDaedalusFuncF","text":"

HookDaedalusFuncF

Alias to the HookDaedalusFunc function.

func void HookDaedalusFuncF(var func hooked, var func hook)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/hook_dae/#hookdaedalusfunci","title":"HookDaedalusFuncI","text":"

HookDaedalusFuncI

HookDaedalusFunc but with function ID.

func void HookDaedalusFuncI(var int hookedID, var int hookID)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/hook_dae/#hookdaedalusfuncs","title":"HookDaedalusFuncS","text":"

HookDaedalusFuncS

HookDaedalusFunc but with function name.

func void HookDaedalusFuncS(var string hookedName, var string hookName)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/hook_dae/#ishookd","title":"IsHookD","text":"

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)\n
Parameters

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":"

ContinueCall

Continues the program run with the original function.

func void ContinueCall()\n
"},{"location":"zengin/scripts/extenders/lego/tools/hook_dae/#passargumenti","title":"PassArgumentI","text":"

PassArgumentI

Passes an integer as an argument to the original function. Must be called before ContinueCall.

func void PassArgumentI(var int i)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/hook_dae/#passarguments","title":"PassArgumentS","text":"

PassArgumentS

Passes a string as an argument to the original function. Must be called before ContinueCall.

func void PassArgumentS(var string s)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/hook_dae/#passargumentn","title":"PassArgumentN","text":"

PassArgumentN

Passes an instance as an argument to the original function. Must be called before ContinueCall.

func void PassArgumentN(var instance n)\n
Parameters "},{"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":"

Info

Dependencies: - None Implementation: HookEngine.d on GitHub

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/#initialization","title":"Initialization","text":"

N/A

"},{"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":"

HookEngine

Attaches a function to an engine function address.

func void HookEngine(var int address, var int oldInstr, var string function)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/hook_engine/#hookengines","title":"HookEngineS","text":"

HookEngineS

Alias to the HookEngine function.

func void HookEngineS(var int address, var int oldInstr, var string function)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/hook_engine/#hookenginei","title":"HookEngineI","text":"

HookEngineI

Alias to HookEngine with funcID.

func void HookEngineI(var int address, var int oldInstr, var int funcID)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/hook_engine/#hookenginef","title":"HookEngineF","text":"

HookEngineF

Alias to HookEngine with func parameter.

func void HookEngineF(var int address, var int oldInstr, var func function)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/hook_engine/#ishooked","title":"IsHooked","text":"

IsHooked

Checks if a hook is already present at a given address.

func var int IsHooked(var int address)\n
Parameters

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":"

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)\n
Parameters

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":"

IsHookI

Alias to IsHook with a funcID as parameter.

func var int IsHookI(var int address, var int funcID)\n
Parameters

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":"

IsHookF

Alias to IsHook with a function as parameter.

func var int IsHookF(var int address, var func function)\n
Parameters

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":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/hook_engine/#removehooki","title":"RemoveHookI","text":"

RemoveHookI

Alias to RemoveHook with funcID.

func void RemoveHook(var int address, var int oldInstr, var int funcID)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/hook_engine/#removehookf","title":"RemoveHookF","text":"

RemoveHookF

Alias for RemoveHook with func parameter.

func void RemoveHook(var int address, var int oldInstr, var func function)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/hook_engine/#replaceenginefunc","title":"ReplaceEngineFunc","text":"

ReplaceEngineFunc

Replaces an engine function with a Daedalus function.

func void ReplaceEngineFunc(var int address, var int thiscall_numparams, var string replaceFunc)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/hook_engine/#replaceenginefunci","title":"ReplaceEngineFuncI","text":"

ReplaceEngineFuncI

Alias to ReplaceEngineFunc with funcID.

func void ReplaceEngineFunc(var int address, var int thiscall_numparams, var int funcID)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/hook_engine/#replaceenginefuncf","title":"ReplaceEngineFuncF","text":"

ReplaceEngineFuncF

Alias to ReplaceEngineFunc with func parameter.

func void ReplaceEngineFunc(var int address, var int thiscall_numparams, var func function)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/hook_engine/#disableenginefunc","title":"DisableEngineFunc","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/hook_engine/#hook_returnfalse","title":"Hook_ReturnFalse","text":"

Hook_ReturnFalse

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":"

Hook_ReturnTrue

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":"

Info

Dependencies: - None Implementation: Int64.d on GitHub

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/#initialization","title":"Initialization","text":"

N/A

"},{"location":"zengin/scripts/extenders/lego/tools/int64/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/tools/int64/#mk64","title":"mk64","text":"

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)\n
Parameters 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":"

neg64

Negates the integer: *dest <- -(*dest)

func void neg64(var int dest)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/int64/#add64","title":"add64","text":"

add64

Adds src to dest: *dest <- *dest + *src

func void add64(var int dest, var int src)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/int64/#sub64","title":"sub64","text":"

sub64

Subtracts src from dest: *dest <- *dest - *src

func void sub64(var int dest, var int src)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/int64/#mul64","title":"mul64","text":"

mul64

Multiplies dest by src: *dest <- (*dest) * (*src)

func void mul64(var int dest, var int src)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/int64/#div64","title":"div64","text":"

div64

Divides dest by src: *dest <- *dest / *src

func void mul64(var int dest, var int src)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/interface/","title":"Interface","text":""},{"location":"zengin/scripts/extenders/lego/tools/interface/#interface","title":"Interface","text":"

Info

Dependencies: - AI_Function - Anim8 - HookEngine - PermMem Implementation: Interface.d on GitHub

This package offers a lot of useful functions to work with the 2D interface.

"},{"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/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/tools/interface/#sysgettime","title":"sysGetTime","text":"

sysGetTime

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":"

RGBA

Generates a full zColor.

func int RGBA(var int r, var int g, var int b, var int a)\n
Parameters

Return value

The function returns a zColor object.

"},{"location":"zengin/scripts/extenders/lego/tools/interface/#changealpha","title":"ChangeAlpha","text":"

ChangeAlpha

Overrides the alpha value of a given zColor.

func int ChangeAlpha(var int zCol, var int a)\n
Parameters

Return value

The function returns a modified zColor object.

"},{"location":"zengin/scripts/extenders/lego/tools/interface/#getalpha","title":"GetAlpha","text":"

GetAlpha

Returns the alpha value of a given zColor.

func int GetAlpha(var int zCol)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_createtext","title":"Print_CreateText","text":"

Print_CreateText

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

Return value

The function returns a handle to zCViewText.

"},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_createtextptr","title":"Print_CreateTextPtr","text":"

Print_CreateTextPtr

Print_CreateText but returns pointer to zCViewText instead of handle.

func int Print_CreateTextPtr(var string text, var string font)\n
Parameters

Return value

The function returns a pointer to zCViewText.

"},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_createtextptrcolored","title":"Print_CreateTextPtrColored","text":"

Print_CreateTextPtrColored

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

Return value

The function returns a pointer to zCViewText.

"},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_gettext","title":"Print_GetText","text":"

Print_GetText

Returns zCViewText instance from handle.

func zCViewText Print_GetText(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_gettextptr","title":"Print_GetTextPtr","text":"

Print_GetTextPtr

Returns zCViewText pointer from handle.

func int Print_GetTextPtr(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_deletetext","title":"Print_DeleteText","text":"

Print_DeleteText

Removes a zCViewText from the screen.

func void Print_DeleteText(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_setalpha","title":"Print_SetAlpha","text":"

Print_SetAlpha

Changes the alpha value of a given zCViewText.

func void Print_SetAlpha(var int hndl, var int a)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/interface/#printptr_setalpha","title":"PrintPtr_SetAlpha","text":"

PrintPtr_SetAlpha

Print_SetAlpha but with pointer to zCViewText instead of handle.

func void PrintPtr_SetAlpha(var int ptr, var int a)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_getscreensize","title":"Print_GetScreenSize","text":"

Print_GetScreenSize

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":"

Print_Screen

An int array holding the current resolution. (Filled by Print_GetScreenSize)

int Print_Screen[2];\n
"},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_ratio","title":"Print_Ratio","text":"

Print_Ratio

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":"

PS_VMax

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":"

Print_ToVirtual

Convents pixel position to a virtual position.

func int Print_ToVirtual(var int pxl, var int dim)\n
Parameters

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_ToVirtualF

Print_ToVirtual but returns Ikarus float value instead of integer.

func int Print_ToVirtualF(var int pxl, var int dim)\n
Parameters

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":"

Print_ToPixel

Convents virtual position to a pixel position.

func int Print_ToPixel(var int vrt, var int dim)\n
Parameters

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_ToPixelF

Print_ToPixel but returns Ikarus float value instead of integer.

func int Print_ToPixelF(var int vrt, var int dim)\n
Parameters

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":"

Print_ToRatio

Gets the size in the specified dimension in ratioed by the screen.

func int Print_ToRatio(var int size, var int dim)\n
Parameters

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":"

Print_ToRadian

Converts angle in degrees to radians.

func int Print_ToRadian(var int angle)\n
Parameters

Return value

The function returns calculated angle in radians.

"},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_todegree","title":"Print_ToDegree","text":"

Print_ToDegree

Converts angle in radians to degrees.

func int Print_ToDegree(var int angle)\n
Parameters

Return value

The function returns calculated angle in degrees.

"},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_getfontptr","title":"Print_GetFontPtr","text":"

Print_GetFontPtr

Returns a pointer to a zCFont by its name.

func int Print_GetFontPtr(var string font)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_getfontname","title":"Print_GetFontName","text":"

Print_GetFontName

Returns a name of a zCFont from its pointer.

func string Print_GetFontName(var int fontPtr)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_getstringwidth","title":"Print_GetStringWidth","text":"

Print_GetStringWidth

Returns the width of a string in pixels.

func int Print_GetStringWidth(var string s, var string font)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_getstringwidthptr","title":"Print_GetStringWidthPtr","text":"

Print_GetStringWidthPtr

Print_GetStringWidth but with zCFont pointer instead of name.

func int Print_GetStringWidthPtr(var string s, var int font)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_getfontheight","title":"Print_GetFontHeight","text":"

Print_GetFontHeight

Returns the height of a string in pixels.

func int Print_GetFontHeight(var string font)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_ext","title":"Print_Ext","text":"

Print_Ext

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

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_ExtPxl

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

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":"

Print_LongestLine

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 "},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_longestlineext","title":"Print_LongestLineExt","text":"

Print_LongestLineExt

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 "},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_longestlinelength","title":"Print_LongestLineLength","text":"

Print_LongestLineLength

Returns the longest line width in pixels, using default line separator tilde ~.

func int Print_LongestLineLength(var string text, var string font)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_longestlinelengthext","title":"Print_LongestLineLengthExt","text":"

Print_LongestLineLengthExt

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 "},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_textfield","title":"Print_TextField","text":"

Print_TextField

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

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_TextFieldPxl

Print_TextField but with pixel coordinates.

func int Print_TextFieldPxl(var int x, var int y, var string text, var string font)\n
Parameters

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_TextFieldColored

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

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":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/interface/#prints_ext","title":"PrintS_Ext","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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/interface/#ai_prints","title":"AI_PrintS","text":"

AI_PrintS

Version of PrintS that enqueue in given NPCs AI queue.

func void AI_PrintS(var c_npc slf, var string txt)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/interface/#ai_prints_ext","title":"AI_PrintS_Ext","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)\n
Parameters "},{"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":"

Info

Dependencies: - None Implementation: ItemHelper.d on GitHub

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/#initialization","title":"Initialization","text":"

N/A

"},{"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":"

Itm_GetPtr

func int Itm_GetPtr(var int instance)\n
Parameters

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":"

Info

Dependencies: - None Implementation: List.d on GitHub

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/#initialization","title":"Initialization","text":"

N/A

"},{"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":"

List_Create

Creates a list with an initial value.

func int List_Create(var int data)\n
Parameters

Return value

The function returns a pointer to the created list.

"},{"location":"zengin/scripts/extenders/lego/tools/list/#list_add","title":"List_Add","text":"

List_Add

Appends a value to the end of the list.

func void List_Add(var int list, var int data)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/list/#list_addfront","title":"List_AddFront","text":"

List_AddFront

Adds a value before the first element of the list.

func void List_AddFront(var int list, var int data)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/list/#list_addoffset","title":"List_AddOffset","text":"

List_AddOffset

Inserts a value between two list elements.

func void List_AddOffset(var int list, var int offset, var int data)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/list/#list_set","title":"List_Set","text":"

List_Set

Sets a list element to a specific value.

func void List_Set(var int node, var int data)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/list/#list_get","title":"List_Get","text":"

List_Get

Retrieves the value of a list element.

func int List_Get(var int list, var int nr)\n
Parameters

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":"

List_Node

Returns a pointer to a list element.

func int List_Node(var int list, var int nr)\n
Parameters

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":"

List_Length

Returns the length of the list (number of all elements).

func int List_Length(var int list)\n
Parameters

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":"

List_HasLength

Checks if the list has the specified length.

func int List_HasLength(var int list, var int length)\n
Parameters

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":"

List_End

Returns the last list element of the list.

func int List_End(var int list)\n
Parameters

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":"

List_Concat

Concatenates two lists.

func void List_Concat(var int list, var int list2)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/list/#list_contains","title":"List_Contains","text":"

List_Contains

Returns the last list element with a specific value.

func int List_Contains(var int list, var int data)\n
Parameters

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":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/list/#list_forf","title":"List_ForF","text":"

List_ForF

Similar to List_For, but with a function parameter instead of a string.

func void ListForF(var int list, var func function)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/list/#list_fori","title":"List_ForI","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/list/#list_delete","title":"List_Delete","text":"

List_Delete

Deletes a list element. All subsequent elements shift position.

func void List_Delete(var int list, var int nr)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/list/#list_destroy","title":"List_Destroy","text":"

List_Destroy

Destroys the entire list.

func void List_Destroy(var int list)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/list/#list_toarray","title":"List_ToArray","text":"

List_ToArray

Returns a pointer to a memory area containing all values of the list.

func int List_ToArray(var int list)\n
Parameters

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":"

List_MoveDown

Moves the specified list node down by one position in the list.

func void List_MoveDown(var int list, var int node)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/list/#list_moveup","title":"List_MoveUp","text":"

List_MoveUp

Moves the specified list node up by one position in the list.

func void List_MoveUp(var int list, var int node)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/list/#list_insertsorted","title":"List_InsertSorted","text":"

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)\n
Parameters: "},{"location":"zengin/scripts/extenders/lego/tools/list/#list_compare","title":"List_Compare","text":"

List_Compare

func int List_Compare(var int data1, var int data2, var func compare)\n
Parameters:

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":"

List_CmpAscending

Compares two integer values in ascending order.

func int List_CmpAscending(var int data1, var int data2)\n
Parameters:

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":"

List_CmpDescending

Compares two integer values in descending order.

func int List_CmpDescending(var int data1, var int data2)\n
Parameters:

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":"

List_CmpAscendingUnsigned

Compares two unsigned integer values in ascending order.

func int List_CmpAscendingUnsigned(var int data1, var int data2)\n
Parameters:

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":"

List_CmpDescendingUnsigned

Compares two unsigned integer values in descending order.

func int List_CmpDescendingUnsigned(var int data1, var int data2)\n
Parameters:

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":"

Info

Dependencies: - StringBuilder Implementation: Locals.d on GitHub

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/#initialization","title":"Initialization","text":"

N/A

"},{"location":"zengin/scripts/extenders/lego/tools/locals/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/tools/locals/#locals_1","title":"Locals","text":"

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()\n
"},{"location":"zengin/scripts/extenders/lego/tools/locals/#final","title":"Final","text":"

Final

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":"

Info

Dependencies: - Floats Implementation: Misc.d on GitHub

The Misc package introduces various helper functions that did not fit into any other package.

"},{"location":"zengin/scripts/extenders/lego/tools/misc/#initialization","title":"Initialization","text":"

N/A

"},{"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":"

atan2f

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

Return value

The function returns arcus tangent in radians as Ikarus float.

"},{"location":"zengin/scripts/extenders/lego/tools/misc/#sin","title":"sin","text":"

sin

Calculates the sine of an angle given in radians.

func int sin(var int angle)\n
Parameters

Return value

The function returns sine of the angle as Ikarus float.

"},{"location":"zengin/scripts/extenders/lego/tools/misc/#cos","title":"cos","text":"

cos

Calculates the cosine of an angle given in radians.

func int cos(var int angle)\n
Parameters

Return value

The function returns cosine of the angle as Ikarus float.

"},{"location":"zengin/scripts/extenders/lego/tools/misc/#tan","title":"tan","text":"

tan

Calculates the tangent of an angle given in radians.

func int tan(var int angle)\n
Parameters

Return value

The function returns tangent of the angle as Ikarus float.

"},{"location":"zengin/scripts/extenders/lego/tools/misc/#asin","title":"asin","text":"

asin

Calculates the arcus sine.

func int asin(var int sine)\n
Parameters

Return value

The function returns arcus sine of the angle as Ikarus float.

"},{"location":"zengin/scripts/extenders/lego/tools/misc/#acos","title":"acos","text":"

acos

Calculates the arcus cosine

func int acos(var int cosine)\n
Parameters

Return value

The function returns arcus cosine of the angle as Ikarus float.

"},{"location":"zengin/scripts/extenders/lego/tools/misc/#distance2d","title":"distance2D","text":"

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)\n
Parameters

Return value

The function returns the distance between the two points.

"},{"location":"zengin/scripts/extenders/lego/tools/misc/#distance2df","title":"distance2Df","text":"

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)\n
Parameters

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":"

Info

Dependencies: - Saves - Locals Implementation: PermMem.d on GitHub

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/#initialization","title":"Initialization","text":"

Initialize with LeGo_PermMem flag.

LeGo_Init(LeGo_PermMem);\n
"},{"location":"zengin/scripts/extenders/lego/tools/permmem/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/tools/permmem/#new","title":"new","text":"

new

Creates a handle to a new instance of inst.

func int new(var int inst)\n
Parameters

Return value

The function returns a new, valid PermMem handle.

"},{"location":"zengin/scripts/extenders/lego/tools/permmem/#create","title":"create","text":"

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)\n
Parameters

Return value

The function returns a pointer to the new instance.

"},{"location":"zengin/scripts/extenders/lego/tools/permmem/#wrap","title":"wrap","text":"

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)\n
Parameters

Return value

The function returns a handle with ptr as content.

"},{"location":"zengin/scripts/extenders/lego/tools/permmem/#clear","title":"clear","text":"

clear

Cleans the handle. After that it is invalid.

func void clear(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/permmem/#release","title":"release","text":"

release

Frees the handle. The reserved memory is not deleted, the handle becomes invalid.

func void release(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/permmem/#delete","title":"delete","text":"

delete

Cleans the handle just like clear, only the destructor is also called.

func void delete(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/permmem/#free","title":"free","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/permmem/#get","title":"get","text":"

get

Returns the instance of the handle.

func instance get(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/permmem/#getptr","title":"getPtr","text":"

getPtr

Returns a pointer to instance of handle.

func int getPtr(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/permmem/#setptr","title":"setPtr","text":"

setPtr

Sets the pointer of a handle.

func void setPtr(var int hndl, var int ptr)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/permmem/#getinst","title":"getInst","text":"

getInst

Returns the instance used to create the given handle in new function.

func int getInst(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/permmem/#numhandles","title":"numHandles","text":"

numHandles

Returns the number of handles managed by PermMem.

func int numHandles()\n
"},{"location":"zengin/scripts/extenders/lego/tools/permmem/#sizeof","title":"sizeof","text":"

sizeof

Gets the size of the given instance's class.

func int sizeof(var int inst)\n
Parameters

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":"

Hlp_IsValidHandle

Indicates whether the handle exists and is managed by PermMem.

func int Hlp_IsValidHandle(var int hndl)\n
Parameters

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":"

foreachHndl

Executes a function for each handle of an instance.

func void foreachHndl(var int inst, var func fnc)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/permmem/#hashndl","title":"hasHndl","text":"

hasHndl

Checks if PermMem has a handle of this instance.

func int hasHndl(var int inst)\n
Parameters

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":"

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)\n
Parameters

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":"

PM_Exists

Checks if the specified field already exists in the archive. (used with archiver/unarchiver)

func int PM_Exists(var string name)\n
Parameters

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":"

PM_SaveInt

Saves an integer to the archive.

func void PM_SaveInt (var string name, var int val)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/permmem/#pm_savefloat","title":"PM_SaveFloat","text":"

PM_SaveFloat

Saves a daedalus float to the archive.

func void PM_SaveFloat (var string name, var int flt)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/permmem/#pm_savestring","title":"PM_SaveString","text":"

PM_SaveString

Saves a string to the archive.

func void PM_SaveString (var string name, var string val)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/permmem/#pm_savefuncid","title":"PM_SaveFuncID","text":"

PM_SaveFuncID

Saves a function ID to the archive.

func void PM_SaveFuncID(var string name, var int fnc)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/permmem/#pm_savefuncoffset","title":"PM_SaveFuncOffset","text":"

PM_SaveFuncOffset

Saves a function offset to the archive.

func void PM_SaveFuncOffset(var string name, var int fnc)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/permmem/#pm_savefuncptr","title":"PM_SaveFuncPtr","text":"

PM_SaveFuncPtr

Saves a function pointer to the archive.

func void PM_SaveFuncPtr(var string name, var int fnc)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/permmem/#pm_saveclassptr","title":"PM_SaveClassPtr","text":"

PM_SaveClassPtr

Saves a pointer of a class to the archive.

func void PM_SaveClassPtr(var string name, var int ptr, var string className)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/permmem/#pm_saveclass","title":"PM_SaveClass","text":"

PM_SaveClass

Saves a class like PM_SaveClassPtr.

func void PM_SaveClass(var string name, var int ptr, var string className)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/permmem/#pm_saveintarray","title":"PM_SaveIntArray","text":"

PM_SaveIntArray

Saves an array of integers.

func void PM_SaveIntArray(var string name, var int ptr, var int elements)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/permmem/#pm_savestringarray","title":"PM_SaveStringArray","text":"

PM_SaveStringArray

Saves an array of integers.

func void PM_SaveStringArray(var string name, var int ptr, var int elements)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/permmem/#unarchiver","title":"Unarchiver","text":""},{"location":"zengin/scripts/extenders/lego/tools/permmem/#pm_load","title":"PM_Load","text":"

PM_Load

Universal function to load integers, floats, class pointers and int arrays.

func int PM_Load(var string name)\n
Parameters

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":"

PM_LoadInt

Returns an integer stored in the archive.

func int PM_LoadInt(var string name)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/permmem/#pm_loadfloat","title":"PM_LoadFloat","text":"

PM_LoadFloat

Returns a daedalus float stored in the archive.

func int PM_LoadFloat(var string name)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/permmem/#pm_loadstring","title":"PM_LoadString","text":"

PM_LoadString

Returns a string stored in the archive.

func string PM_LoadString(var string name)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/permmem/#pm_loadfuncid","title":"PM_LoadFuncID","text":"

PM_LoadFuncID

Returns a function ID stored in the archive.

func int PM_LoadFuncID(var string name)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/permmem/#pm_loadfuncoffset","title":"PM_LoadFuncOffset","text":"

PM_LoadFuncOffset

Returns a function offset stored in the archive.

func int PM_LoadFuncOffset(var string name)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/permmem/#pm_loadfuncptr","title":"PM_LoadFuncPtr","text":"

PM_LoadFuncPtr

Returns a function pointer stored in the archive.

func int PM_LoadFuncPtr(var string name)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/permmem/#pm_loadclassptr","title":"PM_LoadClassPtr","text":"

PM_LoadClassPtr

Returns a class pointer stored in the archive.

func int PM_LoadClassPtr(var string name)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/permmem/#pm_loadclass","title":"PM_LoadClass","text":"

PM_LoadClass

Loads a pointer to the class from the archive to destPtr.

func void PM_LoadClass(var string name, var int destPtr)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/permmem/#pm_loadarray","title":"PM_LoadArray","text":"

PM_LoadArray

Returns a pointer to array stored in the archive.

func int PM_LoadArray(var string name)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/permmem/#pm_loadarraytoptr","title":"PM_LoadArrayToPtr","text":"

PM_LoadArrayToPtr

Loads a pointer to array from the archive to destPtr.

func void PM_LoadArrayToPtr(var string name, var int destPtr)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/permmem/#pm_loadtoptr","title":"PM_LoadToPtr","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/queue/","title":"Queue","text":""},{"location":"zengin/scripts/extenders/lego/tools/queue/#queue","title":"Queue","text":"

Info

Dependencies: - PermMem Implementation: Queue.d on GitHub

This package is an implementation of the Queue data structure and a queue for function calls.

"},{"location":"zengin/scripts/extenders/lego/tools/queue/#initialization","title":"Initialization","text":"

N/A

"},{"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":"

Q_Create

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":"

Q_Enqueue

Appends an integer to the back of the queue

func void Q_Enqueue(var int queue, var int value)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/queue/#q_isempty","title":"Q_IsEmpty","text":"

Q_IsEmpty

Checks if the queue is empty.

func int Q_IsEmpty(var int queue)\n
Parameters

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":"

Q_Advance

Removes the oldest value from the queue and returns it.

func int Q_Advance(var int queue)\n
Parameters

Return value

The function returns the oldest value in the queue.

"},{"location":"zengin/scripts/extenders/lego/tools/queue/#q_peek","title":"Q_Peek","text":"

Q_Peek

Returns the oldest value in the queue without removing it.

func int Q_Peek(var int queue)\n
Parameters

Return value

The function returns the oldest value in the queue.

"},{"location":"zengin/scripts/extenders/lego/tools/queue/#q_for","title":"Q_For","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/queue/#q_forf","title":"Q_ForF","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/queue/#callbackqueue","title":"CallbackQueue","text":""},{"location":"zengin/scripts/extenders/lego/tools/queue/#cq_create","title":"CQ_Create","text":"

CQ_Create

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":"

CQ_EnqueueNoData

Appends a function to the callback queue.

func void CQ_EnqueueNoData(var int queue, var func function)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/queue/#cq_enqueuedata","title":"CQ_EnqueueData","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/queue/#cq_enqueue","title":"CQ_Enqueue","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/queue/#cq_isempty","title":"CQ_IsEmpty","text":"

CQ_IsEmpty

Checks if no function is in the callback queue.

func int CQ_IsEmpty(var int queue)\n
Parameters

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":"

CQ_Advance

Executes the foremost function of the callback queue and removes it from the callback queue.

func void CQ_Advance(var int queue)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/queue/#cq_exhaust","title":"CQ_Exhaust","text":"

CQ_Exhaust

Executes all functions contained in the callback queue.

func void CQ_Exhaust(var int queue)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/random/","title":"Random","text":""},{"location":"zengin/scripts/extenders/lego/tools/random/#random","title":"Random","text":"

Info

Dependencies: - None Implementation: Random.d on GitHub

Provides more random randomization than Hlp_Random() function.

"},{"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/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/tools/random/#r_next","title":"r_Next","text":"

r_Next

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":"

r_Max

Returns a random number from 0 to max.

func int r_Max(var int max)\n
Parameters

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":"

r_MinMax

Returns a random number from 'min' to 'max'.

func int r_MinMax(var int min, var int max)\n
Parameters

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":"

r_Init

Initializes the random number generator. Happens optionally in LeGo_Init.

func void r_Init(var int seed)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/random/#r_defaultinit","title":"r_DefaultInit","text":"

r_DefaultInit

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":"

Info

Dependencies: - None Implementation: StringBuilder.d on GitHub

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/#initialization","title":"Initialization","text":"

N/A

"},{"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":"

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()\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":"

SB_Use

Marks this StringBuilder as active. It can now be used with the functions.

func void SB_Use(var int sb)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/string_builder/#sb_get","title":"SB_Get","text":"

SB_Get

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":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/string_builder/#sb_clear","title":"SB_Clear","text":"

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()\n
"},{"location":"zengin/scripts/extenders/lego/tools/string_builder/#sb_release","title":"SB_Release","text":"

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()\n
"},{"location":"zengin/scripts/extenders/lego/tools/string_builder/#sb_destroy","title":"SB_Destroy","text":"

SB_Destroy

Completely destroys the StringBuilder.

func void SB_Destroy()\n
"},{"location":"zengin/scripts/extenders/lego/tools/string_builder/#sb_tostring","title":"SB_ToString","text":"

SB_ToString

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":"

SB_ToStream

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":"

SB_GetStream

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":"

SB_Length

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":"

SB_SetLength

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":"

SB

Appends a string, to the active StringBuilder.

func void SB(var string s)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/string_builder/#sbi","title":"SBi","text":"

SBi

Appends an integer in text form, to the active StringBuilder.

func void SBi(var int i)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/string_builder/#sbc","title":"SBc","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/string_builder/#sbraw","title":"SBraw","text":"

SBraw

Appends a raw bytes array, to the active StringBuilder.

func void SBraw(var int ptr, var int len)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/string_builder/#sbflt","title":"SBflt","text":"

SBflt

Appends a Daedalus float in text form, to the active StringBuilder.

func void SBflt(var float x)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/string_builder/#sbf","title":"SBf","text":"

SBf

Appends an Ikarus float in text form, to the active StringBuilder.

func void SBf(var int x)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/string_builder/#sbw","title":"SBw","text":"

SBw

Appends a 4-byte raw data (interpreted as an integer x), to the active StringBuilder.

func void SBw(var int x)\n
Parameters "},{"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":"

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)\n
Parameters

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":"

STR_Unescape

Counterpart to STR_Escape. Escape sequences like \\n, \\r or \\t are converted back.

func string STR_Unescape(var string s0)\n
Parameters

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":"

STR_StartsWith

Checks if the input string s starts with the specified prefix string.

func int STR_StartsWith(var string str, var string start) \n
Parameters

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":"

BuildStringSymbolsArray

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":"

GetStringSymbolByAddr

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":"

Info

Dependencies: - PermMem Implementation: Talents.d on GitHub

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/#initialization","title":"Initialization","text":"

Initialize with LeGo_PermMem flag.

LeGo_Init(LeGo_PermMem);\n
"},{"location":"zengin/scripts/extenders/lego/tools/talents/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/tools/talents/#npc_getid","title":"Npc_GetID","text":"

Npc_GetID

Returns unique ID specific for provided NPC.

func int Npc_GetID(var C_NPC slf)\n
Parameters

Return value

The function returns NPCs unique ID.

"},{"location":"zengin/scripts/extenders/lego/tools/talents/#npc_findbyid","title":"Npc_FindByID","text":"

Npc_FindByID

Finds the NPC pointer of an NPC with the given ID.

func int Npc_FindByID(var int ID)\n
Parameters

Return value

The function returns NPC pointer.

"},{"location":"zengin/scripts/extenders/lego/tools/talents/#tal_createtalent","title":"TAL_CreateTalent","text":"

TAL_CreateTalent

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":"

TAL_SetValue

Sets a new value to the specified talent.

func void TAL_SetValue(var C_NPC npc, var int talent, var int value)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/talents/#tal_getvalue","title":"TAL_GetValue","text":"

TAL_GetValue

Returns the value of a saved talent for specified NPC.

func int TAL_GetValue(var C_NPC npc, var int talent)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/timer/","title":"Timer","text":""},{"location":"zengin/scripts/extenders/lego/tools/timer/#timer","title":"Timer","text":"

Info

Dependencies: - None Implementation: Timer.d on GitHub

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/#initialization","title":"Initialization","text":"

Initialize with LeGo_Timer flag.

LeGo_Init(LeGo_Timer);\n
"},{"location":"zengin/scripts/extenders/lego/tools/timer/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/tools/timer/#timer_1","title":"Timer","text":"

Timer

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":"

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()\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":"

TimerF

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":"

Timer_SetPause

Pauses the timer (and thus all FrameFunctions and running animations).

func void Timer_SetPause(var int on)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/timer/#timer_setpauseinmenu","title":"Timer_SetPauseInMenu","text":"

Timer_SetPauseInMenu

The timer can automatically pause when the game is paused. (status screen, main menu...)

func void Timer_SetPauseInMenu(var int on)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/timer/#timer_ispaused","title":"Timer_IsPaused","text":"

Timer_IsPaused

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":"

Info

Dependencies: - PermMem - Interface Implementation: View.d on GitHub

This package can create textures on the screen and work with them in an extended manner.

"},{"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/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/tools/view/#view_create","title":"View_Create","text":"

View_Create

Creates a zCView with virtual coordinates.

func int View_Create(var int x1, var int y1, var int x2, var int y2) \n
Parameters

Return value

The function returns a PermMem handle to a zCView.

"},{"location":"zengin/scripts/extenders/lego/tools/view/#view_createpxl","title":"View_CreatePxl","text":"

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) \n
Parameters

Return value

The function returns a PermMem handle to a zCView.

"},{"location":"zengin/scripts/extenders/lego/tools/view/#view_createcenter","title":"View_CreateCenter","text":"

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)\n
Parameters

Return value

The function returns a PermMem handle to a zCView.

"},{"location":"zengin/scripts/extenders/lego/tools/view/#view_createcenterpxl","title":"View_CreateCenterPxl","text":"

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)\n
Parameters

Return value

The function returns a PermMem handle to a zCView.

"},{"location":"zengin/scripts/extenders/lego/tools/view/#view_get","title":"View_Get","text":"

View_Get

Alias for get form PermMem.

zCView View_Get(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/view/#view_getptr","title":"View_GetPtr","text":"

View_GetPtr

Alias for getPtr form PermMem.

func int View_GetPtr(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/view/#view_render","title":"View_Render","text":"

View_Render

Renders a zCView. Should be used sparingly, as it works only in specific cases.

func void View_Render(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/view/#view_settexture","title":"View_SetTexture","text":"

View_SetTexture

Assigns a texture to a view. The key function of this package.

func void View_SetTexture(var int hndl, var string texture)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/view/#view_gettexture","title":"View_GetTexture","text":"

View_GetTexture

Gets the name of a previously assigned texture.

func string View_GetTexture(var int hndl)\n
Parameters

Return value

The function returns the previously assigned texture.

"},{"location":"zengin/scripts/extenders/lego/tools/view/#view_setcolor","title":"View_SetColor","text":"

View_SetColor

Sets the color of a view.

func void View_SetColor(var int hndl, var int color)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/view/#view_getcolor","title":"View_GetColor","text":"

View_GetColor

Gets the color of a view.

func int View_GetColor(var int hndl)\n
Parameters

Return value

The function returns the full zColor.

"},{"location":"zengin/scripts/extenders/lego/tools/view/#view_open","title":"View_Open","text":"

View_Open

Opens a view. It will be displayed on the screen.

func void View_Open(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/view/#view_close","title":"View_Close","text":"

View_Close

Closes a view. It disappears from the screen but can still be used.

func void View_Close(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/view/#view_delete","title":"View_Delete","text":"

View_Delete

Alias for delete.

`zCView` View_Delete(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/view/#view_resize","title":"View_Resize","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/view/#view_resizepxl","title":"View_ResizePxl","text":"

View_ResizePxl

Alias for View_Resize using pixel coordinates.

func void View_ResizePxl(var int hndl, var int width, var int height)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/view/#view_move","title":"View_Move","text":"

View_Move

Moves the view by virtual units.

func void View_Move(var int hndl, var int x, var int y)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/view/#view_movepxl","title":"View_MovePxl","text":"

View_MovePxl

Alias for View_Move using pixel coordinates.

func void View_MovePxl(var int hndl, var int x, var int y)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/view/#view_moveto","title":"View_MoveTo","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/view/#view_movetopxl","title":"View_MoveToPxl","text":"

View_MoveToPxl

Alias for View_MoveTo using pixel coordinates.

func void View_MoveToPxl(var int hndl, var int x, var int y)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/view/#view_addtext","title":"View_AddText","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/view/#view_deletetext","title":"View_DeleteText","text":"

View_DeleteText

Removes all text added with View_AddText.

func void View_DeleteText(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/view/#view_top","title":"View_Top","text":"

View_Top

Places the view above all others.

func void View_Top(var int hndl)\n
Parameters "},{"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/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":""},{"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
"},{"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":""},{"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:

"},{"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":"

AI_CallScript

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
"},{"location":"zengin/scripts/extenders/zparserextender/externals/ai/#ai_starttriggerscript","title":"AI_startTriggerScript","text":"

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) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/ai/#ai_starttriggerscriptex","title":"AI_startTriggerScriptEx","text":"

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

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
"},{"location":"zengin/scripts/extenders/zparserextender/externals/ai/#ai_gettriggerbyid","title":"AI_GetTriggerByID","text":"

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) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/ai/#ai_gettriggersnum","title":"AI_GetTriggersNum","text":"

AI_GetTriggersNum

Returns the number of active C_Trigger scripts

func int AI_GetTriggersNum() {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/ai/#ai_gettriggernpc","title":"AI_GetTriggerNPC","text":"

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) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/ai/#ai_gettriggerfunc","title":"AI_GetTriggerFunc","text":"

AI_GetTriggerFunc

Returns the function associated with the specified C_Trigger

func func AI_GetTriggerFunc(var C_Trigger trigger) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/ai/#ai_gettriggerfuncname","title":"AI_GetTriggerFuncName","text":"

AI_GetTriggerFuncName

Returns the function name of a function associated with the specified C_Trigger

func string AI_GetTriggerFuncName(var C_Trigger trigger) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/ai/#ai_getnexttriggerbyfunc","title":"Ai_GetNextTriggerByFunc","text":"

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) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/ai/#ai_getnexttriggerbyfuncname","title":"Ai_GetNextTriggerByFuncName","text":"

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) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/ai/#ai_getnexttriggerbyself","title":"Ai_GetNextTriggerBySelf","text":"

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) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/ai/#ai_getnexttriggerbyother","title":"Ai_GetNextTriggerByOther","text":"

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) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/ai/#ai_getnexttriggerbyvictim","title":"Ai_GetNextTriggerByVictim","text":"

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 ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/ai/#ai_getnexttriggerbynpcs","title":"Ai_GetNextTriggerByNPCs","text":"

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

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
"},{"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":"

Cast_PointerToInstance

Converts memory address (pointer) to an instance

func instance Cast_PointerToInstance(var int address) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/cast/#cast_instancetopointer","title":"Cast_InstanceToPointer","text":"

Cast_InstanceToPointer

Converts instance to a memory address (pointer)

func int Cast_InstanceToPointer( var instance object) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/cast/#cast_pointertonpc","title":"Cast_PointerToNpc","text":"

Cast_PointerToNpc

Casts memory address (pointer) to an NPC

func C_NPC Cast_PointerToNpc( var int address) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/cast/#cast_pointertoitem","title":"Cast_PointerToItem","text":"

Cast_PointerToItem

Casts memory address (pointer) to an Item

func C_ITEM Cast_PointerToItem( var int address) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/cast/#cast_instanceisnpc","title":"Cast_InstanceIsNpc","text":"

Cast_InstanceIsNpc

Checks whether object is an NPC

func int Cast_InstanceIsNpc( var instance object) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/cast/#cast_instanceisitem","title":"Cast_InstanceIsItem","text":"

Cast_InstanceIsItem

Checks whether object is an Item

func int Cast_InstanceIsItem( var instance object) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/cast/#cast_instanceismob","title":"Cast_InstanceIsMob","text":"

Cast_InstanceIsMob

Checks whether object is an MOB

func int Cast_InstanceIsMob( var instance object) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/cast/#cast_getinstanceindex","title":"Cast_GetInstanceIndex","text":"

Cast_GetInstanceIndex

Returns symbolID of the object, returns -1 when not found

func int Cast_GetInstanceIndex( var instance object) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/cast/#cast_getclassid","title":"Cast_GetClassID","text":"

Cast_GetClassID

Returns the class identifier of a class by its name

func int Cast_GetClassID( var string className ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/cast/#cast_getvobclassid","title":"Cast_GetVobClassID","text":"

Cast_GetVobClassID

Returns class identifier of the zCObject vob class

func int Cast_GetVobClassID( var instance object ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/cast/#cast_checkvobclassid","title":"Cast_CheckVobClassID","text":"

Cast_CheckVobClassID

Checks if the classId class is the parent class of the object

func int Cast_CheckVobClassID( var int classId, var instance object ) {};\n
"},{"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":"

Hlp_HasFocusVob

Returns TRUE, if a specified NPC has a Vob in focus

func int Hlp_HasFocusVob( var C_NPC npc ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/hlp/#hlp_getfocusvob","title":"Hlp_GetFocusVob","text":"

Hlp_GetFocusVob

Returns NPC's focus Vob

func instance Hlp_GetFocusVob( var C_NPC npc ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/hlp/#hlp_getfocusvobname","title":"Hlp_GetFocusVobName","text":"

Hlp_GetFocusVobName

Returns the name of NPC's focus vob

func string Hlp_GetFocusVobName( var C_NPC npc ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/hlp/#hlp_getstringlength","title":"Hlp_GetStringLength","text":"

Hlp_GetStringLength

Returns the length of a specified string

func int Hlp_GetStringLength( var string str ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/hlp/#isnan","title":"IsNAN","text":"

IsNAN

Checks whether floating point number is valid

func int IsNAN( var float value ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/hlp/#hlp_keytoggled","title":"Hlp_KeyToggled","text":"

Hlp_KeyToggled

Checks whether key is toggled

func int Hlp_KeyToggled( var int key ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/hlp/#hlp_keypressed","title":"Hlp_KeyPressed","text":"

Hlp_KeyPressed

Checks whether key is pressed

func int Hlp_KeyPressed( var int key ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/hlp/#hlp_logicalkeytoggled","title":"Hlp_LogicalKeyToggled","text":"

Hlp_LogicalKeyToggled

Checks whether logical key is toggled

func int Hlp_LogicalKeyToggled( var int key ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/hlp/#hlp_gameonpause","title":"Hlp_GameOnPause","text":"

Hlp_GameOnPause

Checks whether the game is paused

func int Hlp_GameOnPause() {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/hlp/#hlp_messagebox","title":"Hlp_MessageBox","text":"

Hlp_MessageBox

Opens a message box with a specified message

func void Hlp_MessageBox( var string message ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/hlp/#hlp_printconsole","title":"Hlp_PrintConsole","text":"

Hlp_PrintConsole

Prints a message to the Union debug console

func void Hlp_PrintConsole(var string message) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/hlp/#hlp_optionisexists","title":"Hlp_OptionIsExists","text":"

Hlp_OptionIsExists

Checks whether the entry in section in .ini file optName exists

optName values

func int Hlp_OptionIsExists(var string optName, var string section, var string entry) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/hlp/#hlp_readoptionint","title":"Hlp_ReadOptionInt","text":"

Hlp_ReadOptionInt

Read an integer value from specified .ini file, section and entry.

optName values

func int Hlp_ReadOptionInt(var string optName, var string section, var string entry, var int default) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/hlp/#hlp_readoptionfloat","title":"Hlp_ReadOptionFloat","text":"
!!! function \"`Hlp_ReadOptionFloat`\"\nRead a floating point value from specified `.ini` file, section and entry.\n\n`optName` values\n\n- `#!dae \"Gothic\"`\n- `#!dae \"Mod\"`\n- `#!dae \"SystemPack\"`\n\n```dae\nfunc float Hlp_ReadOptionFloat(var string optName, var string section, var string entry, var float default) {};\n```\n\n- `optName` - the `.ini` file\n- `section` - settings section like `[INTERFACE]`\n- `entry` - one setting entry like `scale`\n- `default` - default value - if the value is empty\n- `return` - the option value\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/hlp/#hlp_readoptionstring","title":"Hlp_ReadOptionString","text":"

Hlp_ReadOptionString

Read a string value from specified .ini file, section and entry.

optName values

func string Hlp_ReadOptionString(var string optName, var string section, var string entry, var string default) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/hlp/#hlp_writeoptionint","title":"Hlp_WriteOptionInt","text":"

Hlp_WriteOptionInt

Writes an integer value to specified .ini file, section and entry.

optName values

func void Hlp_WriteOptionInt(var string optName, var string section, var string entry, var int value) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/hlp/#hlp_writeoptionfloat","title":"Hlp_WriteOptionFloat","text":"

Hlp_WriteOptionFloat

Writes a floating point value to specified .ini file, section and entry.

optName values

func void Hlp_WriteOptionFloat(var string optName, var string section, var string entry, var float value) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/hlp/#hlp_writeoptionstring","title":"Hlp_WriteOptionString","text":"

Hlp_WriteOptionString

Writes a string value to specified .ini file, section and entry.

optName values

func void Hlp_WriteOptionString(var string optName, var string section, var string entry, var string value) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/hlp/#hlp_getsteampersonalname","title":"Hlp_GetSteamPersonalName","text":"

Hlp_GetSteamPersonalName

Returns the name of the current Steam user Returns empty string when not run with Steam

func string Hlp_GetSteamPersonalName() {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/hlp/#hlp_doevent","title":"Hlp_DoEvent","text":"

Hlp_DoEvent

Calls every event function with the name funcName.

func void Hlp_DoEvent(var string funcName) {};\n
"},{"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":"

Log_GetTopicStatus

Returns the status of diary topic

func int Log_GetTopicStatus(var string topic) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/log/#log_gettopicsection","title":"Log_GetTopicSection","text":"

Log_GetTopicSection

Returns the topic the diary topic is in

func int Log_GetTopicSection(var string topic) {};\n
"},{"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":"

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 ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/mdl/#mdl_getanimationname","title":"Mdl_GetAnimationName","text":"

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 ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/mdl/#mdl_animationisexists","title":"Mdl_AnimationIsExists","text":"

Mdl_AnimationIsExists

Checks whether animation exists

func int Mdl_AnimationIsExists( var C_NPC npc, var int ani_index ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/mdl/#mdl_animationisactive","title":"Mdl_AnimationIsActive","text":"

Mdl_AnimationIsActive

Checks whether animation is active (whether it is currently played)

func int Mdl_AnimationIsActive( var C_NPC npc, var int ani_index ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/mdl/#mdl_setallanimationsfps","title":"Mdl_SetAllAnimationsFPS","text":"

Mdl_SetAllAnimationsFPS

Set framerate for all animations

func void Mdl_SetAllAnimationsFPS( var C_NPC npc, var float fps ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/mdl/#mdl_resetallanimationsfps","title":"Mdl_ResetAllAnimationsFPS","text":"

Mdl_ResetAllAnimationsFPS

Reset framerate for all animations to default value

func void Mdl_ResetAllAnimationsFPS( var C_NPC npc ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/mdl/#mdl_setanimationfps","title":"Mdl_SetAnimationFPS","text":"

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 ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/mdl/#mdl_resetanimationfps","title":"Mdl_ResetAnimationFPS","text":"

Mdl_ResetAnimationFPS

Reset framerate to default for animation specified by animation index

func void Mdl_ResetAnimationFPS( var C_NPC npc, var int ani_index ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/mdl/#mdl_setvisible","title":"Mdl_SetVisible","text":"

Mdl_SetVisible

Set NPCs visibility

func void Mdl_SetVisible( var C_NPC npc, var int isVisible ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/mdl/#mdl_applyoverlaymds_atfirst","title":"Mdl_ApplyOverlayMds_AtFirst","text":"

Mdl_ApplyOverlayMds_AtFirst

Applies or moves existing overlay to the top of the list

func void Mdl_ApplyOverlayMds_AtFirst( var string mdsName ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/mdl/#mdl_setnpcspeedmultiplier","title":"Mdl_SetNpcSpeedMultiplier","text":"

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 ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/mdl/#mdl_resetnpcspeedmultiplier","title":"Mdl_ResetNpcSpeedMultiplier","text":"

Mdl_ResetNpcSpeedMultiplier

Resets the animation speed of an NPC

func void Mdl_ResetNpcSpeedMultiplier( var C_Npc npc ) {};\n
"},{"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":"

Menu_SearchItems

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
"},{"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":"

Mob_Destroy

Marks oCMOB as destroyed, changes the visual to visualDestroyed (if present).

func void Mob_Destroy( var instance object ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/mob/#mob_removeitem","title":"Mob_RemoveItem","text":"

Mob_RemoveItem

Removes an item from a oCMobContainer

func void Mob_RemoveItem( var instance object, var int item ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/mob/#mob_removeitems","title":"Mob_RemoveItems","text":"

Mob_RemoveItems

Removes specified number of items from a oCMobContainer

func void Mob_RemoveItems( var instance object, var int item, var int cnt ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/mob/#mob_insertitem","title":"Mob_InsertItem","text":"

Mob_InsertItem

Inserts an item into a oCMobContainer

func void Mob_InsertItem( var instance object, var int item ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/mob/#mob_insertitems","title":"Mob_InsertItems","text":"

Mob_InsertItems

Inserts specified number of items into a oCMobContainer

func void Mob_InsertItems( var instance object, var int item, var int cnt ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/mob/#mob_getlockcombination","title":"Mob_GetLockCombination","text":"

Mob_GetLockCombination

Returns a lock combination of a oCMobContainer

func string Mob_GetLockCombination( var instance object ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/mob/#mob_setlockcombination","title":"Mob_SetLockCombination","text":"

Mob_SetLockCombination

Sets a lock combination to a oCMobContainer

func void Mob_SetLockCombination( var instance object, var string comb ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/mob/#mob_islocked","title":"Mob_IsLocked","text":"

Mob_IsLocked

Returns TRUE if the object is locked

func int Mob_IsLocked( var instance object ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/mob/#mob_setlocked","title":"Mob_SetLocked","text":"

Mob_SetLocked

Set the lock status of the object

func void Mob_SetLocked( var instance object, var int locked ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/mob/#mob_getkeyinstance","title":"Mob_GetKeyInstance","text":"

Mob_GetKeyInstance

Returns the key instance, that unlocks the object

func instance Mob_GetKeyInstance( var instance object ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/mob/#mob_setkeyinstance","title":"Mob_SetKeyInstance","text":"

Mob_SetKeyInstance

Stets the key instance, that unlocks the object

func void Mob_SetKeyInstance( var instance object, var int key ) {};\n
"},{"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":"

Npc_SetAsHero

Changes players character to specified npc

func void Npc_SetAsHero( var C_NPC npc ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/npc/#npc_openinventory","title":"Npc_OpenInventory","text":"

Npc_OpenInventory

Opens NPCs main inventory

func void Npc_OpenInventory( var C_NPC npc ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/npc/#npc_openinventorysteal","title":"Npc_OpenInventorySteal","text":"

Npc_OpenInventorySteal

Opens the steal inventory of npc's focus NPC

func void Npc_OpenInventorySteal( var C_NPC npc ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/npc/#npc_openinventorytrade","title":"Npc_OpenInventoryTrade","text":"

Npc_OpenInventoryTrade

Start the trading dialogue with specified NPC

func void Npc_OpenInventoryTrade( var C_NPC npc ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/npc/#npc_getlefthanditem","title":"Npc_GetLeftHandItem","text":"

Npc_GetLeftHandItem

Returns an item in NPC's left hand slot

func C_Item Npc_GetLeftHandItem( var C_Npc npc ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/npc/#npc_getrighthanditem","title":"Npc_GetRightHandItem","text":"

Npc_GetRightHandItem

Returns an item in NPC's right hand slot

func C_Item Npc_GetRightHandItem( var C_Npc npc ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/npc/#npc_getslotitem","title":"Npc_GetSlotItem","text":"

Npc_GetSlotItem

Returns an item from a slot with the slotName

func C_Item Npc_GetSlotItem( var C_Npc npc, var string slotName ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/npc/#npc_putinslot","title":"Npc_PutInSlot","text":"

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) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/npc/#npc_removefromslot","title":"Npc_RemoveFromSlot","text":"

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) {};\n
"},{"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":"

Par_GetParserID

Returns a parser ID of the parser with a parName name

Parser names:

func int Par_GetParserID(var string parName) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/par/#par_getsymbolid","title":"Par_GetSymbolID","text":"

Par_GetSymbolID

Returns symbol ID for the symbol specified by its name

func int Par_GetSymbolID(var int parId, var string symName) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/par/#par_getsymbollength","title":"Par_GetSymbolLength","text":"

Par_GetSymbolLength

Returns symbol length (number of elements)

func int Par_GetSymbolLength(var int parId, var int symId) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/par/#par_getsymbolvalueint","title":"Par_GetSymbolValueInt","text":"

Par_GetSymbolValueInt

Returns the integer value of specified symbol

func int Par_GetSymbolValueInt(var int parId, var int symId) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/par/#par_getsymbolvaluefloat","title":"Par_GetSymbolValueFloat","text":"

Par_GetSymbolValueFloat

Returns the float value of specified symbol

func float Par_GetSymbolValueFloat(var int parId, var int symId) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/par/#par_getsymbolvaluestring","title":"Par_GetSymbolValueString","text":"

Par_GetSymbolValueString

Returns the string value of specified symbol

func string Par_GetSymbolValueString(var int parId, var int symId) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/par/#par_getsymbolvalueinstance","title":"Par_GetSymbolValueInstance","text":"

Par_GetSymbolValueInstance

Returns the instance value of specified symbol

func instance Par_GetSymbolValueInstance(var int parId, var int symId) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/par/#par_getsymbolvalueintarray","title":"Par_GetSymbolValueIntArray","text":"

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) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/par/#par_getsymbolvaluefloatarray","title":"Par_GetSymbolValueFloatArray","text":"

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) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/par/#par_getsymbolvaluestringarray","title":"Par_GetSymbolValueStringArray","text":"

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) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/par/#par_setsymbolvalueint","title":"Par_SetSymbolValueInt","text":"

Par_SetSymbolValueInt

Sets a new integer value to specified symbol

func void Par_SetSymbolValueInt(var int value, var int parId, var int symId) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/par/#par_setsymbolvaluefloat","title":"Par_SetSymbolValueFloat","text":"

Par_SetSymbolValueFloat

Sets a new float value to specified symbol

func void Par_SetSymbolValueFloat(var float value, var int parId, var int symId) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/par/#par_setsymbolvaluestring","title":"Par_SetSymbolValueString","text":"

Par_SetSymbolValueString

Sets a new string value to specified symbol

func void Par_SetSymbolValueString(var string value, var int parId, var int symId) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/par/#par_setsymbolvalueinstance","title":"Par_SetSymbolValueInstance","text":"

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) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/par/#par_setsymbolvalueintarray","title":"Par_SetSymbolValueIntArray","text":"

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) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/par/#par_setsymbolvaluefloatarray","title":"Par_SetSymbolValueFloatArray","text":"

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) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/par/#par_setsymbolvaluestringarray","title":"Par_SetSymbolValueStringArray","text":"

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) {};\n
"},{"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":"

Str_Format

Returns formatted string using format specifiers

Format specifiers:

func string Str_Format( var string format, ... ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/string/#examples","title":"Examples","text":"

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.

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":"

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.

func string Str_GetLocalizedString( var string russian,\n                                    var string english,\n                                    var string german,\n                                    var string polish ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/string/#str_getlocalizedstringex","title":"Str_GetLocalizedStringEx","text":"

Str_GetLocalizedStringEx

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
"},{"location":"zengin/scripts/extenders/zparserextender/externals/string/#str_utf8_to_ansi","title":"Str_UTF8_to_ANSI","text":"

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 ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/string/#str_getcurrentcp","title":"Str_GetCurrentCP","text":"

Str_GetCurrentCP

Return the code page corresponding to the current language set in the Union System

func int Str_GetCurrentCP() {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/string/#str_getlength","title":"Str_GetLength","text":"

Str_GetLength

Returns the length of a string

func int Str_GetLength( var int str ) {};\n
"},{"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":"

Vob_GetVobPosition

Returns the current position of the object in the world

func C_Position Vob_GetVobPosition( var C_Vob vob ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/vob/#vob_setvobposition","title":"Vob_SetVobPosition","text":"

Vob_SetVobPosition

Sets the current position of the object in the world

func void Vob_SetVobPosition( var C_Vob vob, var C_Position pos ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/vob/#vob_getvobdata","title":"Vob_GetVobData","text":"

Vob_GetVobData

Returns the universal data of the zCVob object

func C_Vob_Data Vob_GetVobData( var C_Vob vob ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/vob/#vob_setvobdata","title":"Vob_SetVobData","text":"

Vob_SetVobData

Sets the universal data to a zCVob object

func void Vob_SetVobData( var C_Vob vob, var C_Vob_Data data ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/vob/#vob_getlightdata","title":"Vob_GetLightData","text":"

Vob_GetLightData

Returns zCVobLight object data

func C_Light_Data Vob_GetLightData( var C_Vob vobLight ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/vob/#vob_setlightdata","title":"Vob_SetLightData","text":"

Vob_SetLightData

Sets the data of a zCVobLight object

func void Vob_SetLightData( var C_Vob vobLight, var C_Light_Data data ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/vob/#vob_clearlightanilist","title":"Vob_ClearLightAniList","text":"

Vob_ClearLightAniList

Clears the list of animation colours for the light source

func void Vob_ClearLightAniList( var C_Vob vobLight ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/vob/#vob_addlightanicolor","title":"Vob_AddLightAniColor","text":"

Vob_AddLightAniColor

Adds a color to the colour list

func void Vob_AddLightAniColor( var C_Vob vobLight, var C_Color col ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/vob/#vob_addlightanicolorrgb","title":"Vob_AddLightAniColorRGB","text":"

Vob_AddLightAniColorRGB

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
"},{"location":"zengin/scripts/extenders/zparserextender/externals/vob/#vob_getmobdata","title":"Vob_GetMobData","text":"

Vob_GetMobData

Returns the data of the oCMOB object

func C_Mob_Data Vob_GetMobData( var C_Vob mob ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/vob/#vob_setmobdata","title":"Vob_SetMobData","text":"

Vob_SetMobData

Sets the data of the oCMOB object

func void Vob_SetMobData( var C_Vob mob, var C_Mob_Data data ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/vob/#vob_getmobinterdata","title":"Vob_GetMobInterData","text":"

Vob_GetMobInterData

Returns the data of the oCMobInter object

func MobInter_Data Vob_GetMobInterData( var C_Vob mobInter ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/vob/#vob_setmobinterdata","title":"Vob_SetMobInterData","text":"

Vob_SetMobInterData

Sets the data of the oCMobInter object

func void Vob_SetMobInterData( var C_Vob mobInter, var C_MobInter_Data data ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/vob/#vob_getmobinterdata_1","title":"Vob_GetMobInterData","text":"

Vob_GetMobInterData

Returns the data of the oCMobLockable object

func C_MobLockable_Data Vob_GetMobInterData( var C_Vob mobLock ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/vob/#vob_setmobinterdata_1","title":"Vob_SetMobInterData","text":"

Vob_SetMobInterData

Sets the data of the oCMobLockable object

func void Vob_SetMobInterData( var C_Vob mobLock, var C_MobLockable_Data data ) {};\n
"},{"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":"

Wld_ChangeLevel

Trigger level change.

func void Wld_ChangeLevel( var string world, var string waypoint ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/wld/#wld_findvob","title":"Wld_FindVob","text":"

Wld_FindVob

Return the VOB instance based on its name.

func instance Wld_FindVob( var string vobname ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/wld/#wld_playeffectvob","title":"Wld_PlayEffectVob","text":"

Wld_PlayEffectVob

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
"},{"location":"zengin/scripts/extenders/zparserextender/externals/wld/#wld_playeffectat","title":"Wld_PlayEffectAt","text":"

Wld_PlayEffectAt

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
"},{"location":"zengin/scripts/extenders/zparserextender/externals/wld/#wld_togglerain","title":"Wld_ToggleRain","text":"

Wld_ToggleRain

Turns on the rain

func void Wld_ToggleRain( var float weight, var float time ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/wld/#wld_setweathertype","title":"Wld_SetWeatherType","text":"

Wld_SetWeatherType

Sets the weather type. Types:

0 - snow 1 - rain

func void Wld_SetWeatherType( var int type ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/wld/#wld_getweathertype","title":"Wld_GetWeatherType","text":"

Wld_GetWeatherType

Returns the weather type. Types:

0 - snow 1 - rain

func int Wld_GetWeatherType() {};\n
"},{"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

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:

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":"

Doc_Create

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":"

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() {};\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":"

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) {};\n

Parameters

Example

nDocID = Doc_CreateMap();\nDoc_SetLevel(nDocID, \"WORLD.ZEN\");\n
"},{"location":"zengin/scripts/externals/doc/#doc_setlevelcoords","title":"Doc_SetLevelCoords","text":"

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) {};\n

Parameters

Example

Doc_SetLevelCoords(nDocID, -28000, 50500, 95500, -42500);\n
"},{"location":"zengin/scripts/externals/doc/#doc_setfont","title":"Doc_SetFont","text":"

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) {};\n

Parameters

Example

Doc_SetFont(nDocID, -1, \"FONT_10_BOOK.TGA\");\n
"},{"location":"zengin/scripts/externals/doc/#doc_setpages","title":"Doc_SetPages","text":"

Doc_SetPages

Sets the number of pages numOfPages of the document.

func void Doc_SetPages(var int docID, var int numOfPages) {};\n

Parameters

Example

nDocID = Doc_Create();\nDoc_SetPages(nDocID, 2);\n
"},{"location":"zengin/scripts/externals/doc/#doc_setpage","title":"Doc_SetPage","text":"

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) {};\n

Parameters

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":"

Doc_SetMargins

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

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":"

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) {};\n

Parameters

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":"

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) {};\n

Parameters

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":"

Doc_Show

Display the document using the document manager ID

func void Doc_Show(var int docID) {};\n

Parameters

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":"

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) {};\n
Parameters "},{"location":"zengin/scripts/externals/log/#log_addentry","title":"Log_AddEntry","text":"

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) {};\n
Parameters

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":"

Log_SetTopicStatus

Changes the status of the topic with the name topicName

func void Log_SetTopicStatus(var string topicName, var int status) {};\n
Parameters "},{"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":"

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) {};\n

Parameters

"},{"location":"zengin/scripts/externals/mdl/#mdl_applyoverlaymdstimed","title":"Mdl_ApplyOverlayMDSTimed","text":"

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) {};\n

Parameters

"},{"location":"zengin/scripts/externals/mdl/#mdl_removeoverlaymds","title":"Mdl_RemoveOverlayMDS","text":"

Mdl_RemoveOverlayMDS

Remove the animation overlay overlay_name from specified npc

func void Mdl_RemoveOverlayMDS(var c_npc npc, var string overlay_name) {};\n

Parameters

"},{"location":"zengin/scripts/externals/mdl/#mdl_applyrandomani","title":"Mdl_ApplyRandomAni","text":"

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) {};\n

Parameters

"},{"location":"zengin/scripts/externals/mdl/#mdl_applyrandomanifreq","title":"Mdl_ApplyRandomAniFreq","text":"

Mdl_ApplyRandomAniFreq

Sets the random animation frequency for animation ani1

func void Mdl_ApplyRandomAniFreq(var c_npc npc, var string ani1, var float frequency) {};\n

Parameters

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":"

Mdl_SetModelFatness

Set the procedural model fatness

func void Mdl_SetModelFatness(var c_npc npc, var float fatness) {};\n

Parameters

"},{"location":"zengin/scripts/externals/mdl/#mdl_setmodelscale","title":"Mdl_SetModelScale","text":"

Mdl_SetModelScale

Set model scale per axis

func void Mdl_SetModelScale(var c_npc npc, var float x, var float y, var float z) {};\n

Parameters

"},{"location":"zengin/scripts/externals/mdl/#mdl_setvisualbody","title":"Mdl_SetVisualBody","text":"

Mdl_SetVisualBody

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

"},{"location":"zengin/scripts/externals/mdl/#mdl_setvisual","title":"Mdl_SetVisual","text":"

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) {};\n

Parameters

"},{"location":"zengin/scripts/externals/mdl/#mdl_startfaceani","title":"Mdl_StartFaceAni","text":"

Mdl_StartFaceAni

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

"},{"location":"zengin/scripts/externals/mdl/#mdl_applyrandomfaceani","title":"Mdl_ApplyRandomFaceAni","text":"

Mdl_ApplyRandomFaceAni

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

"},{"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:

"},{"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

VDFS tools

World Editors

Libraries

Debugging

"},{"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/zSplitDialogs/","title":"zSplitDialogs","text":""},{"location":"zengin/tools/zSplitDialogs/#zsplitdialogs","title":"zSplitDialogs","text":"

The plugin for a dubbing creators. And not only.

Union plugin by Top Layer, which gives possibility to extract dialogues from compiled scripts simply by putting zSplitDialogs.vdf file into Data\\ directory and run the game. You can configure, that already dubbed subtitles will be outputed.

The output is the Dialogs\\ directory with .txt files with a structure as follow:

Example of a plugin output

"},{"location":"zengin/tools/zSplitDialogs/#download","title":"Download","text":""},{"location":"zengin/tools/zSplitDialogs/#source-code","title":"Source code","text":""},{"location":"zengin/tools/zSplitDialogs/#the-usage","title":"The usage","text":"

At first run, in gothic.ini will be created following section:

[ZSPLITDIALOGS]\nUnvoicedOnly=0\n

You can change value to 1 to receive only unvoiced subtitles.

"},{"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:

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:

"},{"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

"},{"location":"zengin/tools/zSpy/#message","title":"Message","text":"

The most important part. A message that contains:

"},{"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:

"},{"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
"},{"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
"},{"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/daedalus_tools/decdat/","title":"DecDat","text":""},{"location":"zengin/tools/daedalus_tools/decdat/#decdat","title":"DecDat","text":"

DecDat1 is a daedalus scripts decompiler orginaly created by Gottfried. Its goal is to replace Gothic Sourcer's decompiler, which wouldn't been able to decompile scripts with Ikarus and LeGo. However, that doesn't mean that DecDat is able to produce data that can be compiled again. This tool should be used mainly for research and educational purposes. Source code is available here.

"},{"location":"zengin/tools/daedalus_tools/decdat/#instalation","title":"Instalation","text":"

The tool is written in Java, allowing it to be executed seamlessly on both Windows and Linux operating systems. To utilize the tool, ensure that Java is installed on your system. We recommend using the Java version available here. Once you have your Java installed, download the latest tool version from GitHub releases page, and run the DecDat.jar file.

"},{"location":"zengin/tools/daedalus_tools/decdat/#usage","title":"Usage","text":"

After opening a DecDat you will see a following window.

To import a .DAT file click at File -> Open DAT... select the file encoding, the file itself and optionally OU.BIN file if you want to parse dialogues.

And that's it, now you have a .DAT file loaded into app, and you can export the code or search for a specific part.

  1. The original DecDat release post can be found here.\u00a0\u21a9

"},{"location":"zengin/tools/libraries/zenkit/","title":"ZenKit","text":""},{"location":"zengin/tools/libraries/zenkit/#zenkit","title":"ZenKit","text":"

ZenKit is a C++-library for loading and saving proprietary ZenGin files and is intended to be a successor to Andre Taulien's ZenLib. ZenKit wrappers for Java and C# are also available in the form of ZenKitCS and ZenKit4J which are also published to NuGet and Maven Central respectively.

ZenKit is used as the file loading and scripting backend for OpenGothic and has recently found adoption in GothicVR.

"},{"location":"zengin/tools/libraries/zenkit/#file-support","title":"File Support","text":"

The following file types and operations are supported by ZenKit. Requests to support additional file types are welcome and can be submitted to the GitHub repository.

File Type Extension Load1 Save2 Comment Model Animation .MAN \u2713 Yes \u2718 No \u2014 Model Hierarchy .MDH \u2713 Yes \u2713 Yes \u2014 Model Mesh .MDM \u2713 Yes \u2713 Yes Saving is only partially supported Model .MDL \u2713 Yes \u2713 Yes Saving is only partially supported Morph Mesh .MMB \u2713 Yes \u2718 No \u2014 Multi Resolution Mesh .MRM \u2713 Yes \u2713 Yes \u2014 Mesh .MSH \u2713 Yes \u2713 Yes Saving is only partially supported Daedalus Script .DAT \u2713 Yes \u2718 No A VM implementation is available (see Daedalus VM) Texture .TEX \u2713 Yes ~ Yes There is currently no API to alter image data Font .FNT \u2713 Yes \u2713 Yes \u2014 ZenGin Archive .ZEN \u2713 Yes \u2713 Yes \u2014 Text/Cutscenes .BIN, .CSL, .DAT, .LSC \u2713 Yes \u2713 Yes \u2014 Model Script .MDS, .MSB \u2713 Yes \u2718 No \u2014 Virtual File System .VDF \u2713 Yes \u2713 Yes Allows full integration with the host file system"},{"location":"zengin/tools/libraries/zenkit/#daedalus-vm","title":"Daedalus VM","text":"

Along facilities to read and write most resource files you might find in a typical Gothic installation, ZenKit also includes a virtual machine which can execute Daedalus scripts. An extensive API is available to inspect the files, add external handlers and bind Daedalus classes into C++-structs. Bindings for the original classes are available as an extension to ZenKit and available to the C# and Java wrappers natively.

"},{"location":"zengin/tools/libraries/zenkit/#documentation","title":"Documentation","text":"

Additional documentation for ZenKit can be found at zk.gothickit.dev.

  1. ZenKit is able to fully load these files\u00a0\u21a9

  2. ZenKit is able to save these files at least partially\u00a0\u21a9

"},{"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[^1]","text":""},{"location":"zengin/tools/vdfs_tools/vdfs_tool/#vdfs-tool","title":"VDFS Tool1","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 using the Resource Manager or directly from the post on WoP.ru - VDFS Tool.

"},{"location":"zengin/tools/vdfs_tools/vdfs_tool/#features","title":"Features","text":""},{"location":"zengin/tools/vdfs_tools/vdfs_tool/#volume-compression","title":"Volume compression","text":"

Volumes are compressed using the classic zip algorithm. The zlib library for buffer compression and decompression was taken as a basis. In order for the game to decompress the volume in real time without loss of performance, a special interface Gratt-5r2/ZippedStream was implemented and built into vdfs32g. The essence of the interface is that it allows you to pack and read files in blocks of a given size and keep unpacked data in memory in a specific range.

Warning

Compresed .mod and .vdf archives works only with Union installed.

"},{"location":"zengin/tools/vdfs_tools/vdfs_tool/#volume-optimization","title":"Volume optimization","text":"

Optimization refers to the procedure of identifying files with the same content and combining them under a common data source.

"},{"location":"zengin/tools/vdfs_tools/vdfs_tool/#file-explorer-interface","title":"File Explorer Interface","text":"

The program interface has a set of standard file explorer operations - copying, pasting, renaming, searching, etc.

"},{"location":"zengin/tools/vdfs_tools/vdfs_tool/#dragdrop","title":"Drag&Drop","text":"

The function allows you to drag files into the program, as well as pull them out of it. For this function to work correctly, user (administrator) rights must match for the program and Explorer.

"},{"location":"zengin/tools/vdfs_tools/vdfs_tool/#updating-a-volume-in-1-click","title":"Updating a volume in 1 click","text":"

The program analyzes shared files in the volume and in the game directories (Ctrl + U). If there are physical copies, when you save the volume, updated files will be written to it.

"},{"location":"zengin/tools/vdfs_tools/vdfs_tool/#opening-files-directly-from-a-volume","title":"Opening files directly from a volume","text":"

To avoid wasting time unpacking the volume, double-click on the file of interest, after which it will be opened.

  1. This is mostly a translation of the orginal release post.\u00a0\u21a9

"},{"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 games based on ZenGin. It replaces the original DirectMusic system with a custom engine built on top of BASS Library to provide easier workflow for composers and additional functions for the perfect soundtrack design.

Info

The plugin has its very own docuentation site, if you are interested in including zBassMusic into your project see the detailed User Guide.

Contacts Authors Silver Ore Team - tehe GitHub zBassMusic Discord Gothic Modding Community server"},{"location":"zengin/union/plugins/zbassmusic/#features","title":"Features","text":""},{"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":""},{"location":"zengin/union/plugins/zgamepad/#features","title":"Features","text":""},{"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

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:

"},{"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:

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:

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:

Engines:

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:\n            gothicVersion = \"Gothic I\";\n            break;\n        case Engine_G1A:\n            gothicVersion = \"Gothic Sequel\";\n            break;\n        case Engine_G2:\n            gothicVersion = \"Gothic II\";\n            break;\n        case Engine_G2A:\n            gothicVersion = \"Gothic II NoTR\";\n            break;\n        default:\n            gothicVersion = \"Not possible case. Engine version doesn't match any known engine.\";\n            break;\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:

"},{"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:

Asides from those elements, there are also many invisible VOBs, such as:

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:

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:

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:

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":"

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.

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.

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:

"},{"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/zCMaterial/","title":"zCMaterial","text":""},{"location":"zengin/worlds/Classes/zCMaterial/#zcmaterial","title":"zCMaterial","text":"

Quick Infos

Class Name: zCMaterial Sources: \u2014 spacerhilfedatei.sph \u2014 gothic-library.ru

zCMaterial class describes the properties of the game materials.

Danger

zCMaterial objects are only saved in binary .ZEN files.

"},{"location":"zengin/worlds/Classes/zCMaterial/#class-members","title":"Class members","text":"Gothic 1Gothic 2 "},{"location":"zengin/worlds/Classes/zCMaterial/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCMaterial/#defaultmapping","title":"defaultMapping","text":"

Default material mapping.

"},{"location":"zengin/worlds/Classes/zCMaterial/#name","title":"name","text":"

Material name. In most cases corresponds to the name of the texture map.

"},{"location":"zengin/worlds/Classes/zCMaterial/#matgroup","title":"matGroup","text":"

Sound accompaniment of the material. Must be specified to produce the correct sounds when moving across the specified material.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCMaterial/#color","title":"color","text":"

Texture replacement color in RGBA format. Polygon is in this color until engine applies the texture.

"},{"location":"zengin/worlds/Classes/zCMaterial/#smoothangle","title":"smoothAngle","text":"

Defines the angle of material smoothing between two faces.

"},{"location":"zengin/worlds/Classes/zCMaterial/#texture","title":"texture","text":"

Defines the name of the texture file used for the material, which also determines whether the texture is animated or static.

To create animated textures, add a suffix to the file name _A0, e.g., NW_Fire_A0.TGA, NW_Fire_A1.TGA etc. The texture NW_Fire_A0.TGA is the first frame. The game engine will automatically search your hard drive for remaining animation files.

"},{"location":"zengin/worlds/Classes/zCMaterial/#texscale","title":"texScale","text":"

Defines the scaling along the X and Y axes. Assigns the necessary texture coordinates to polygons.

"},{"location":"zengin/worlds/Classes/zCMaterial/#texanifps","title":"texAniFPS","text":"

Defines the FPS (frames per seconds) of texture animation, but only if the texture is animated (NAME_A0.*).

"},{"location":"zengin/worlds/Classes/zCMaterial/#texanimapmode","title":"texAniMapMode","text":"

Texture animation mode.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCMaterial/#texanimapdir","title":"texAniMapDir","text":"

Defines the direction and movement speed of animated textures. The values should be significantly lower than 1 (For example 0.00005).

Danger

The animation movement is only enabled when texAniMapMode is set to LINEAR mode.

"},{"location":"zengin/worlds/Classes/zCMaterial/#nocolldet","title":"noCollDet","text":"

Defines if collision detection is disabled.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCMaterial/#nolightmap","title":"noLightmap","text":"

Defines if light map is disabled.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCMaterial/#loddontcollapse","title":"lodDontCollapse","text":"

If you activate this option, the texture will not degrade when the camera moves away.

Accepted values:

Note

To prevent the texture from being distorted, you can cancel the creation of a MipMap. It is advisable to use for small objects.

"},{"location":"zengin/worlds/Classes/zCMaterial/#detailobject","title":"detailObject","text":"

An option that allows you to complement the material with an additional texture.

"},{"location":"zengin/worlds/Classes/zCMaterial/#detailobjectscale","title":"detailObjectScale","text":"

Tiling of the overlay image selected in the detailObject property.

Warning

This option is only available in Gothic II (Spacer2).

"},{"location":"zengin/worlds/Classes/zCMaterial/#forceoccluder","title":"forceOccluder","text":"

No information provided.

Accepted values:

Warning

This option is only available in Gothic II (Spacer2).

"},{"location":"zengin/worlds/Classes/zCMaterial/#environmentalmapping","title":"environmentalMapping","text":"

Environment mapping mode. Creates glare on the texture.

Accepted values:

Warning

This option is only available in Gothic II (Spacer2).

"},{"location":"zengin/worlds/Classes/zCMaterial/#environmentalmappingstrength","title":"environmentalMappingStrength","text":"

The strength of environmental reflection on a model.

Warning

This option is only available in Gothic II (Spacer2).

"},{"location":"zengin/worlds/Classes/zCMaterial/#wavemode","title":"waveMode","text":"

Enable wave simulation mode. For example, AMBIENT_GROUND is used for water textures.

Accepted values:

Warning

This option is only available in Gothic II (Spacer2).

"},{"location":"zengin/worlds/Classes/zCMaterial/#wavespeed","title":"waveSpeed","text":"

Wave speed.

Accepted values:

Warning

This option is only available in Gothic II (Spacer2).

"},{"location":"zengin/worlds/Classes/zCMaterial/#wavemaxamplitude","title":"waveMaxAmplitude","text":"

Maximum wave amplitude.

Warning

This option is only available in Gothic II (Spacer2).

"},{"location":"zengin/worlds/Classes/zCMaterial/#wavegridsize","title":"waveGridSize","text":"

Wave mesh size.

Warning

This option is only available in Gothic II (Spacer2).

"},{"location":"zengin/worlds/Classes/zCMaterial/#ignoresunlight","title":"ignoreSunLight","text":"

Defines if the material ignores sunlight (doesn't cast shadows).

Accepted values:

Warning

This option is only available in Gothic II (Spacer2).

"},{"location":"zengin/worlds/Classes/zCMaterial/#alphafunc","title":"alphaFunc","text":"

Alpha channel blending function.

Accepted values:

Warning

This option is only available in Gothic II (Spacer2).

"},{"location":"zengin/worlds/Classes/zCVob/","title":"zCVob","text":""},{"location":"zengin/worlds/Classes/zCVob/#zcvob","title":"zCVob","text":"

Quick Infos

Class Name: zCVob Version Identifiers: \u2014 Gothic I: 12289 \u2014 Gothic II: 52224 Sources: \u2014 spacerhilfedatei.sph \u2014 gothic-library.ru \u2014 zk.gothickit.dev

Represents so-called virtual objects which appear in the game world. zCVob is the base class for all virtual objects which include everything from static models like boxes to interactive elements like doors and chests and invisible trigger objects.

"},{"location":"zengin/worlds/Classes/zCVob/#class-members","title":"Class members","text":"

Properties of a zCVob class are split into two parts. The Internals are hardly ever needed to be edited manually, they are changed 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.

Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCVob/#pack","title":"pack","text":"

Internal property which indicates how the data associated with this virtual object is stored.

"},{"location":"zengin/worlds/Classes/zCVob/#presetname","title":"presetName","text":"

The name of the template that was used to create this virtual object.

"},{"location":"zengin/worlds/Classes/zCVob/#bbox3dws","title":"bbox3DWS","text":"

The 3-dimensional bounding box of this virtual object. Defined by two opposite diagonal points (1x, 1y, 1z, 2x, 2y, 2z). This is used in conjunction with cdStatic and cdDyn calculate collisions and interactions with other game objects (NPCs, items, 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 Spacer.

"},{"location":"zengin/worlds/Classes/zCVob/#trafoostowsrot","title":"trafoOSToWSRot","text":"

The rotation of this virtual object in world space, represented by a 3x3 rotation matrix.

"},{"location":"zengin/worlds/Classes/zCVob/#trafoostowspos","title":"trafoOSToWSPos","text":"

Coordinates of the object in world space relative to the center.

Note

This refers to the center of coordinates of the .3DS file of the game world on which the ZEN file is built.

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.

"},{"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 visual component associated with this object, usually a name of a file.

Following formats are supported:

"},{"location":"zengin/worlds/Classes/zCVob/#showvisual","title":"showVisual","text":"

Indicates whether this object should display its visual.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/#visualcamalign","title":"visualCamAlign","text":"

Option to align objects relative to the camera.

Accepted values:

Note

This may be used with grass or flowers which only consist of a 2-dimensional sprite to have it always face the camera.

"},{"location":"zengin/worlds/Classes/zCVob/#visualanimode","title":"visualAniMode","text":"

Wind simulation option. Used in conjunction with the visualAniModeStrength parameter.

Accepted values:

Warning

This option is only available in Gothic II (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 II (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 zCVob drawing range is the same as the draw distance specified in zCZoneVobFarPlane object.

Warning

This option is only available in Gothic II (Spacer2).

"},{"location":"zengin/worlds/Classes/zCVob/#cdstatic","title":"cdStatic","text":"

Determines if the virtual object will collide with the static objects (world mesh and other VOBs with cdStatic on).

Accepted values:

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 virtual object will collide with dynamic objects (NPCs, items, etc.). This basically determines if the object has collision during gameplay.

Accepted values:

"},{"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:

Note

The shadow is calculated when compiling light in Low, Middle or High mode.

"},{"location":"zengin/worlds/Classes/zCVob/#dynshadow","title":"dynShadow","text":"

Indicates whether the object will cast a shadow when affected by dynamic light (e.g. torches).

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/#zbias","title":"zbias","text":"

The depth-bias for this virtual object.

Can be used remove texture flickering if a .TGA file is used as rendering.

Warning

This option is only available in Gothic II (Spacer2).

"},{"location":"zengin/worlds/Classes/zCVob/#isambient","title":"isAmbient","text":"

Indicates that this virtual object is ambient. It looks like this setting was a system used during development when access to the game's source code was available. Basically, the global variable zCWorld::s_bAmbientVobsEnabled could be used to hide or show virtual objects which have the isAmbient flag set. In release builds, this variable is always set to true, thus the isAmbient flag does not have any perceivable effect on the game. It follows, that this field should be ignored by most implementations.

Warning

This option is only available in Gothic II (Spacer2).

"},{"location":"zengin/worlds/Classes/zCVob/#sleepmode","title":"sleepMode","text":"

Unknown.

Warning

This property is only available in saved games.

"},{"location":"zengin/worlds/Classes/zCVob/#nextontimer","title":"nextOnTimer","text":"

Unknown.

Warning

This property is only available in saved games.

"},{"location":"zengin/worlds/Classes/zCVob/zCCSCamera/","title":"zCCSCamera","text":""},{"location":"zengin/worlds/Classes/zCVob/zCCSCamera/#zccscamera","title":"zCCSCamera","text":"

Quick Infos

Type: Virtual Object Format Name: ZenGin Archive File Extension: .ZEN Class Name: zCCSCamera Version Identifiers: \u2014 Gothic I: 30720 \u2014 Gothic II: 33793 ZenKit Class: VCutsceneCamera Sources: \u2014 gothic-library.ru \u2014 zk.gothickit.dev

"},{"location":"zengin/worlds/Classes/zCVob/zCCSCamera/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCCSCamera/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCVob/zCCSCamera/#camtrjfor","title":"camTrjFOR","text":"

The coordinate system of the key frames of the camera trajectory.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCCSCamera/#targettrjfor","title":"targetTrjFOR","text":"

The keyframe coordinate system of the target camera trajectory.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCCSCamera/#loopmode","title":"loopMode","text":"

The repetition mode of the camera animation.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCCSCamera/#spllerpmode","title":"splLerpMode","text":"

Adjust camera orientation while moving.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCCSCamera/#ignoreforvobrotcam","title":"ignoreFORVobRotCam","text":"

Determines whether the orientation to reference VOB objects should be taken into account when passing through key frames.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCCSCamera/#ignoreforvobrottarget","title":"ignoreFORVobRotTarget","text":"

Determines the need to take into account the orientation of target key frames to reference VOB objects.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCCSCamera/#adapttosurroundings","title":"adaptToSurroundings","text":"

Indicates the need for dynamic adaptation to the environment.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCCSCamera/#easetofirstkey","title":"easeToFirstKey","text":"

Gives a smooth transition of camera position from the first keyframe to the last, if possible.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCCSCamera/#easefromlastkey","title":"easeFromLastKey","text":"

Gives a smooth transition of camera position from the last keyframe to the first, if possible.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCCSCamera/#totaltime","title":"totalTime","text":"

The duration of the camera animation in seconds.

"},{"location":"zengin/worlds/Classes/zCVob/zCCSCamera/#autocamfocusvobname","title":"autoCamFocusVobName","text":"

The name of the VOB object which the camera will automatically focus.

"},{"location":"zengin/worlds/Classes/zCVob/zCCSCamera/#autocamplayermovable","title":"autoCamPlayerMovable","text":"

Indicates whether the player will be able to move when moving the camera animation.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCCSCamera/#autocamuntriggeronlastkey","title":"autoCamUntriggerOnLastKey","text":"

Emit an OnUntrigger event after reaching the last animation frame.

"},{"location":"zengin/worlds/Classes/zCVob/zCCSCamera/#autocamuntriggeronlastkeydelay","title":"autoCamUntriggerOnLastKeyDelay","text":"

Unclear.

"},{"location":"zengin/worlds/Classes/zCVob/zCCSCamera/#numpos","title":"numPos","text":"

The number of position key frames for the camera animation.

Warning

This property is not available in the Spacer.

"},{"location":"zengin/worlds/Classes/zCVob/zCCSCamera/#numtargets","title":"numTargets","text":"

The number of target key frames for the camera animation.

Warning

This property is not available in the Spacer.

"},{"location":"zengin/worlds/Classes/zCVob/zCCSCamera/#paused","title":"paused","text":"

Unknown.

Warning

This property is only available in saved games made using Gothic II.

"},{"location":"zengin/worlds/Classes/zCVob/zCCSCamera/#started","title":"started","text":"

Unknown.

Warning

This property is only available in saved games made using Gothic II.

"},{"location":"zengin/worlds/Classes/zCVob/zCCSCamera/#gototimemode","title":"gotoTimeMode","text":"

Unknown.

Warning

This property is only available in saved games made using Gothic II.

"},{"location":"zengin/worlds/Classes/zCVob/zCCSCamera/#cstime","title":"csTime","text":"

Unknown.

Warning

This property is only available in saved games made using Gothic II.

  1. A list of position key frames. The number of items is indicated by the numPos property.\u00a0\u21a9\u21a9\u21a9\u21a9

  2. A list of target key frames. The number of items is indicated by the numTargets property.\u00a0\u21a9\u21a9\u21a9\u21a9

"},{"location":"zengin/worlds/Classes/zCVob/zCCamTrj_KeyFrame/","title":"zCCamTrj_KeyFrame","text":""},{"location":"zengin/worlds/Classes/zCVob/zCCamTrj_KeyFrame/#zccamtrj_keyframe","title":"zCCamTrj_KeyFrame","text":"

Quick Infos

Type: Virtual Object Format Name: ZenGin Archive File Extension: .ZEN Class Name: zCCamTrj_KeyFrame Version Identifiers: \u2014 Gothic I: 12289 \u2014 Gothic II: 52224 ZenKit Class: VCameraTrajectoryFrame Sources: \u2014 gothic-library.ru \u2014 zk.gothickit.dev

"},{"location":"zengin/worlds/Classes/zCVob/zCCamTrj_KeyFrame/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCCamTrj_KeyFrame/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCVob/zCCamTrj_KeyFrame/#time","title":"time","text":"

Unclear.

"},{"location":"zengin/worlds/Classes/zCVob/zCCamTrj_KeyFrame/#anglerolldeg","title":"angleRollDeg","text":"

The camera rotation angle of the frame along the Z axis.

"},{"location":"zengin/worlds/Classes/zCVob/zCCamTrj_KeyFrame/#camfovscale","title":"camFOVScale","text":"

Focal zoom of the camera's field of view (FOV) of the frame. Use reasonable values to avoid dizzying effects.

"},{"location":"zengin/worlds/Classes/zCVob/zCCamTrj_KeyFrame/#motiontype","title":"motionType","text":"

The type of camera movement for the frame.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCCamTrj_KeyFrame/#motiontypefov","title":"motionTypeFOV","text":"

The type of focus change for the frame.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCCamTrj_KeyFrame/#motiontyperoll","title":"motionTypeRoll","text":"

The type of rotation for the frame.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCCamTrj_KeyFrame/#motiontypetimescale","title":"motionTypeTimeScale","text":"

Unclear.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCCamTrj_KeyFrame/#tension","title":"tension","text":"

Defines the bend of the camera motion curve at the specified key. Larger values result in a sharper bend.

"},{"location":"zengin/worlds/Classes/zCVob/zCCamTrj_KeyFrame/#bias","title":"bias","text":"

Determines the slope of a line in one direction. The direction of the slope is determined by the sign, and the steepness by the value.

"},{"location":"zengin/worlds/Classes/zCVob/zCCamTrj_KeyFrame/#continuity","title":"continuity","text":"

Determines the amount of curve discontinuity at this animation key.

"},{"location":"zengin/worlds/Classes/zCVob/zCCamTrj_KeyFrame/#timescale","title":"timeScale","text":"

Unknown.

"},{"location":"zengin/worlds/Classes/zCVob/zCCamTrj_KeyFrame/#timeisfixed","title":"timeIsFixed","text":"

An auxiliary flag indicating the time of the key frame, which cannot be changed automatically.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCCamTrj_KeyFrame/#originalpose","title":"originalPose","text":"

Unknown.

Warning

This property is not available in the Spacer.

"},{"location":"zengin/worlds/Classes/zCVob/zCVobLevelCompo/","title":"zCVobLevelCompo","text":""},{"location":"zengin/worlds/Classes/zCVob/zCVobLevelCompo/#zcvoblevelcompo","title":"zCVobLevelCompo","text":"

Quick Infos

Class Name: zCVobLevelCompo Version Identifiers: \u2014 Gothic I: 12289 \u2014 Gothic II: 52224 Sources: \u2014 gothic-library.ru \u2014 zk.gothickit.dev

Used as root objects of game levels. Only used to group together other VObjects. Only one of the zCVobLevelCompo objects will have a visual which corresponds to the mesh of the world it exists in. Generally, it can be ignored and has no relevance to other VObjects in the hierarchy.

"},{"location":"zengin/worlds/Classes/zCVob/zCVobLevelCompo/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCVobLight/","title":"zCVobLight","text":""},{"location":"zengin/worlds/Classes/zCVob/zCVobLight/#zcvoblight","title":"zCVobLight","text":"

Quick Infos

Type: Virtual Object Format Name: ZenGin Archive File Extension: .ZEN Class Name: zCVobLight Version Identifiers: \u2014 Gothic I: 46080 \u2014 Gothic II: 39168 ZenKit Class: VLight Sources: \u2014 spacerhilfedatei.sph \u2014 gothic-library.ru \u2014 zk.gothickit.dev

Represents a virtual light source which lights up nearby game objects. Point and spot light sources are supported and may be animated with different colors and ranges.

"},{"location":"zengin/worlds/Classes/zCVob/zCVobLight/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCVobLight/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCVob/zCVobLight/#lightpresetinuse","title":"lightPresetInUse","text":"

The name of the selected light template. Templates can be found in _work/data/Presets/LightPresets.zen. This property is irrelevant for most use-cases.

"},{"location":"zengin/worlds/Classes/zCVob/zCVobLight/#lighttype","title":"lightType","text":"

The type of the light source.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCVobLight/#range","title":"range","text":"

The range in which this light source illuminates objects.

"},{"location":"zengin/worlds/Classes/zCVob/zCVobLight/#color","title":"color","text":"

The color of this light source in RGBA form.

"},{"location":"zengin/worlds/Classes/zCVob/zCVobLight/#spotconeangle","title":"spotConeAngle","text":"

The angle of the beam cone for spotlights. Only relevant if lightType is SPOT, ignored otherwise.

"},{"location":"zengin/worlds/Classes/zCVob/zCVobLight/#lightstatic","title":"lightStatic","text":"

Determines whether this is a static light or not. Static lights are baked into the world when its lighting is compiled. This makes static lights faster at runtime, but it also means, that they cannot change in any way after the world is compiled.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCVobLight/#lightquality","title":"lightQuality","text":"

Determines the quality of the light source. What exactly changes with these values is unknown.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCVobLight/#lensflarefx","title":"lensflareFX","text":"

The name of the lensflare effect associated with this light. Empty if there is no associated lensflare effect.

"},{"location":"zengin/worlds/Classes/zCVob/zCVobLight/#turnedon","title":"turnedOn","text":"

Whether this dynamic light is turned on.

Accepted values:

Warning

This value is only valid for dynamic lights. Check lightStatic before use.

"},{"location":"zengin/worlds/Classes/zCVob/zCVobLight/#rangeaniscale","title":"rangeAniScale","text":"

Frames for the light's range animation. Its value is a space-separated list of floats where each float is one key frame of the animation. A value of 1.0 corresponds to the initial range of the light source, a value of 2.0 corresponds to double the initial range and a value of 0.5 means half the initial range. The range animation is further controlled by rangeAniFPS and rangeAniSmooth.

Warning

This value is only valid for dynamic lights. Check lightStatic before use.

"},{"location":"zengin/worlds/Classes/zCVob/zCVobLight/#rangeanifps","title":"rangeAniFPS","text":"

The speed of the range animation in frames per second. The animation frames are defined in rangeAniScale

Warning

This value is only valid for dynamic lights. Check lightStatic before use.

"},{"location":"zengin/worlds/Classes/zCVob/zCVobLight/#rangeanismooth","title":"rangeAniSmooth","text":"

Whether the range animation should smoothly interpolate between keyframes.

Accepted values:

Warning

This value is only valid for dynamic lights. Check lightStatic before use.

"},{"location":"zengin/worlds/Classes/zCVob/zCVobLight/#coloranilist","title":"colorAniList","text":"

Frames for the light's color animation. Its value is a space-separated list of colors where each element can either be an RGB color consisting of three integers enclosed by parentheses or a greyscale color consisting of a single integer. For example: (255 0 0) 100 (255 50 180) would result in #ff0000 #646464, #ff32b4. The color animation is further controlled by colorAniFPS and colorAniSmooth.

Warning

This value is only valid for dynamic lights. Check lightStatic before use.

"},{"location":"zengin/worlds/Classes/zCVob/zCVobLight/#coloranifps","title":"colorAniFPS","text":"

The speed of the color animation in frames per second. The animation frames are defined in colorAniList

Warning

This value is only valid for dynamic lights. Check lightStatic before use.

"},{"location":"zengin/worlds/Classes/zCVob/zCVobLight/#coloranismooth","title":"colorAniSmooth","text":"

Whether the color animation should smoothly interpolate between keyframes.

Accepted values:

Warning

This value is only valid for dynamic lights. Check lightStatic before use.

"},{"location":"zengin/worlds/Classes/zCVob/zCVobLight/#canmove","title":"canMove","text":"

Unknown.

Warning

This value is only valid for dynamic lights in Gothic II. Check lightstatic before use.

"},{"location":"zengin/worlds/Classes/zCVob/zCVobSpot/","title":"zCVobSpot","text":""},{"location":"zengin/worlds/Classes/zCVob/zCVobSpot/#zcvobspot","title":"zCVobSpot","text":"

Quick Infos

Class Name: zCVobSpot Version Identifiers: \u2014 Gothic I: 12289 \u2014 Gothic II: 52224 Sources: \u2014 spacerhilfedatei.sph \u2014 gothic-library.ru \u2014 zk.gothickit.dev

Spot objects are used to mark a position and orientation in virtual space. They are equivalent in function to way net free points and can be used in scripts to spawn other objects at their location.

"},{"location":"zengin/worlds/Classes/zCVob/zCVobSpot/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCVobStair/","title":"zCVobStair","text":""},{"location":"zengin/worlds/Classes/zCVob/zCVobStair/#zcvobstair","title":"zCVobStair","text":"

Quick Infos

Class Name: zCVobStair Version Identifiers: \u2014 Gothic I: 12289 \u2014 Gothic II: Unused Sources: \u2014 spacerhilfedatei.sph \u2014 gothic-library.ru \u2014 zk.gothickit.dev

Used to mark staircase models in Gothic I only. This type of VObject was taken into account by the NPC pathfinding routines to properly ascend and descend staircases.

Warning

This VObject is only available in Gothic I.

"},{"location":"zengin/worlds/Classes/zCVob/zCVobStair/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save)

Unavailable.

Unavailable.

"},{"location":"zengin/worlds/Classes/zCVob/zCVobStartpoint/","title":"zCVobStartpoint","text":""},{"location":"zengin/worlds/Classes/zCVob/zCVobStartpoint/#zcvobstartpoint","title":"zCVobStartpoint","text":"

Quick Infos

Class Name: zCVobStartpoint Version Identifiers: \u2014 Gothic I: 12289 \u2014 Gothic II: 52224 Sources: \u2014 spacerhilfedatei.sph \u2014 gothic-library.ru \u2014 zk.gothickit.dev

Marks the players initial position when loading in the game level. Behaves like zCVobSpot but causes the game to put the player at its location and in its orientation when the world is loaded.

"},{"location":"zengin/worlds/Classes/zCVob/zCVobStartpoint/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/oCVob/","title":"oCVob","text":""},{"location":"zengin/worlds/Classes/zCVob/oCVob/#ocvob","title":"oCVob","text":"

Quick Infos

Class Name: oCVob Version Identifiers: \u2014 Gothic I: 12289 \u2014 Gothic II: Unused Sources: \u2014 zk.gothickit.dev

Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCItem/","title":"oCItem","text":""},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCItem/#ocitem","title":"oCItem","text":"

Quick Infos

Class Name: oCItem Version Identifiers: \u2014 Gothic I: 0 \u2014 Gothic II: 0 Sources: \u2014 gothic-library.ru \u2014 zk.gothickit.dev

Represents an item in the game world. Items are special VObjects which are tied to a script instance which defines their attributes. They have physics enabled and can be targeted and picked up by the player.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCItem/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCItem/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCItem/#iteminstance","title":"itemInstance","text":"

The name of the script instance representing the item.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCItem/#amount","title":"amount","text":"

Unknown.

Warning

This property is only available in saved games.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCItem/#flags","title":"flags","text":"

Unknown.

Warning

This property is only available in saved games.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/","title":"oCMOB","text":""},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/#ocmob","title":"oCMOB","text":"

Quick Infos

Class Name: oCMOB Version Identifiers: \u2014 Gothic I: 47105 \u2014 Gothic II: 47105 Sources: \u2014 spacerhilfedatei.sph \u2014 gothic-library.ru \u2014 zk.gothickit.dev

A VObject which can optionally be moved and/or carried.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/#focusname","title":"focusName","text":"

The name of the object as seen in-game when focusing it.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/#hitpoints","title":"hitpoints","text":"

The number of hitpoints of the object.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/#damage","title":"damage","text":"

The damage dealt by the object when being used.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/#moveable","title":"moveable","text":"

Whether the object can be moved by the player.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/#takeable","title":"takeable","text":"

Whether the object can be carried by the player.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/#focusoverride","title":"focusOverride","text":"

Unknown.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/#soundmaterial","title":"soundMaterial","text":"

The sound to play when the object is hit.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/#visualdestroyed","title":"visualDestroyed","text":"

The name of the visual to use when the object is destroyed. Behaves like zCVob.visual.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/#owner","title":"owner","text":"

The name of the script instance of the NPC who is the owner of this object.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/#ownerguild","title":"ownerGuild","text":"

The name of the guild this object belongs to. This name corresponds to the script constant for each guild (i.e. GIL_BAU), found in Constants.d.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/#isdestroyed","title":"isDestroyed","text":"

Unknown.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/","title":"oCMobInter","text":""},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/#ocmobinter","title":"oCMobInter","text":"

Quick Infos

Class Name: oCMobInter Version Identifiers: \u2014 Gothic I: 35585 \u2014 Gothic II: 35585 Sources: \u2014 spacerhilfedatei.sph \u2014 gothic-library.ru \u2014 zk.gothickit.dev

Interactive objects can be interacted with by NPCs and the player. Every time the object is interacted with, an OnTrigger event is sent to the triggerTarget object.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/#statenum","title":"stateNum","text":"

Unknown.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/#triggertarget","title":"triggerTarget","text":"

The name of the VObject(s) to send an OnTrigger event to when this object is interacted with. Controlled by the rewind property.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/#usewithitem","title":"useWithItem","text":"

The name of the item which the player or NPC must have in their inventory in order to interact with the object. Corresponds to the name of the item instance in the scripts.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/#conditionfunc","title":"conditionFunc","text":"

The name of a script function which, when called, determines whether the object can be interacted with. The script function returns an int which is either 0, if the object should be disabled and 1 if it should be enabled.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/#onstatefunc","title":"onStateFunc","text":"

The name of a script function to be called when the object is being used.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/#rewind","title":"rewind","text":"

Determines whether an OnTrigger event should be sent every time the object is interacted with or only the first time.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobBed/","title":"oCMobBed","text":""},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobBed/#ocmobbed","title":"oCMobBed","text":"

Quick Infos

Type: Virtual Object Format Name: ZenGin Archive File Extension: .ZEN Class Name: oCMobBed Version Identifiers: \u2014 Gothic I: 35585 \u2014 Gothic II: 35585 ZenKit Class: VBed Sources: \u2014 spacerhilfedatei.sph \u2014 zk.gothickit.dev

VObject marking beds for NPCs and the player to sleep on. In the original Gothic I, there is a bug which prevents oCMobBeds from working correctly, so it is recommended to instead use oCMobDoor and attach the visual of a bed when targeting that platform.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobBed/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobFire/","title":"oCMobFire","text":""},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobFire/#ocmobfire","title":"oCMobFire","text":"

Quick Infos

Class Name: oCMobFire Version Identifiers: \u2014 Gothic I: 18433 \u2014 Gothic II: 18433 Sources: \u2014 gothic-library.ru \u2014 zk.gothickit.dev

An object with an integrated fire effect. Only supports rigged models as visuals.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobFire/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobFire/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobFire/#fireslot","title":"fireSlot","text":"

The bone of the rigged model to place the fire effect at.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobFire/#firevobtreename","title":"fireVobtreeName","text":"

The name of the template file which contains the configuration of the fire effect. For example: FIRETREE_MEDIUM.ZEN.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobLadder/","title":"oCMobLadder","text":""},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobLadder/#ocmobladder","title":"oCMobLadder","text":"

Quick Infos

Class Name: oCMobLadder Version Identifiers: \u2014 Gothic I: 35585 \u2014 Gothic II: 35585 Sources: \u2014 spacerhilfedatei.sph \u2014 gothic-library.ru \u2014 zk.gothickit.dev

A VObject representing a ladder. NPCs can interact with ladders by climbing.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobLadder/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobSwitch/","title":"oCMobSwitch","text":""},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobSwitch/#ocmobswitch","title":"oCMobSwitch","text":"

Quick Infos

Class Name: oCMobSwitch Version Identifiers: \u2014 Gothic I: 35585 \u2014 Gothic II: 35585 Sources: \u2014 spacerhilfedatei.sph \u2014 zk.gothickit.dev

A VObject representing a switch with two states.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobSwitch/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobWheel/","title":"oCMobWheel","text":""},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobWheel/#ocmobwheel","title":"oCMobWheel","text":"

Quick Infos

Class Name: oCMobWheel Version Identifiers: \u2014 Gothic I: 35585 \u2014 Gothic II: 35585 Sources: \u2014 spacerhilfedatei.sph \u2014 zk.gothickit.dev

A wheel with four different states. For example, this is used for the gates of the old camp in Gothic I.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobWheel/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobLockable/","title":"oCMobLockable","text":""},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobLockable/#ocmoblockable","title":"oCMobLockable","text":"

Quick Infos

Class Name: oCMobLockable Version Identifiers: \u2014 Gothic I: 12289 \u2014 Gothic II: 52224 Sources: \u2014 zk.gothickit.dev

The base class for many lockable objects like containers and doors.

Warning

This object is an abstract base class and cannot be instantiated by itself.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobLockable/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobLockable/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobLockable/#locked","title":"locked","text":"

Determines whether the container is locked.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobLockable/#keyinstance","title":"keyInstance","text":"

The name of the item script instance which unlocks the container.

Tip

Only relevant if the container is locked.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobLockable/#picklockstr","title":"pickLockStr","text":"

The combination which unlocks this container when picking the lock. Each character of the string is either R or L where R stands for \"Right\" and L stands for \"Left\". If empty, the lock can not be picked. Example: LRRLLRL.

Tip

Only relevant if the container is locked.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobLockable/oCMobContainer/","title":"oCMobContainer","text":""},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobLockable/oCMobContainer/#ocmobcontainer","title":"oCMobContainer","text":"

Quick Infos

Class Name: oCMobContainer Version Identifiers: \u2014 Gothic I: 64513 \u2014 Gothic II: 64513 Sources: \u2014 spacerhilfedatei.sph \u2014 gothic-library.ru \u2014 zk.gothickit.dev

An object which contains items.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobLockable/oCMobContainer/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobLockable/oCMobContainer/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobLockable/oCMobContainer/#contains","title":"contains","text":"

The items found inside the container as a comma-separated list. Each element of the list starts with the name of the item script instance and is optionally followed by a colon and a number, indicating the number of that item to be found inside. Example: ItMi_Gold:75, ItFo_Fish:2, ItMi_Quartz.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobLockable/oCMobContainer/#numofentries","title":"NumOfEntries","text":"

The number of items in the container.

Warning

This property is only available in saved games.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobLockable/oCMobDoor/","title":"oCMobDoor","text":""},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobLockable/oCMobDoor/#ocmobdoor","title":"oCMobDoor","text":"

Quick Infos

Class Name: oCMobDoor Version Identifiers: \u2014 Gothic I: 64513 \u2014 Gothic II: 64513 Sources: \u2014 gothic-library.ru \u2014 zk.gothickit.dev

A VObject representing a door. This is also used for NPCs navigating the waynet.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobLockable/oCMobDoor/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCEffect/","title":"zCEffect","text":""},{"location":"zengin/worlds/Classes/zCVob/zCEffect/#zceffect","title":"zCEffect","text":"

Quick Infos

Class Name: zCEffect Version Identifiers: \u2014 Gothic I: 12289 \u2014 Gothic II: 52224 Sources: \u2014 zk.gothickit.dev

The base class for many visual and sound effects.

Warning

This object is an abstract base class and cannot be instantiated by itself.

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCEarthquake/","title":"zCEarthquake","text":""},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCEarthquake/#zcearthquake","title":"zCEarthquake","text":"

Quick Infos

Class Name: zCEarthquake Version Identifiers: \u2014 Gothic I: Unused \u2014 Gothic II: 52224 Sources: \u2014 spacerhilfedatei.sph \u2014 gothic-library.ru \u2014 zk.gothickit.dev

A VObject used to create an earthquake effect when it receives an OnTrigger event. An earthquake is represented by a shaking camera.

Warning

This VObject is only available in Gothic II.

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCEarthquake/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save)

Unavailable

Unavailable

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCEarthquake/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCEarthquake/#radius","title":"radius","text":"

The radius of the earthquake effect

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCEarthquake/#timesec","title":"timeSec","text":"

The duration of the earthquake effect in seconds.

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCEarthquake/#amplitudecm","title":"amplitudeCM","text":"

The amplitude of the earthquake effect.

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCPFXControler/","title":"zCPFXController","text":""},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCPFXControler/#zcpfxcontroller","title":"zCPFXController","text":"

Quick Infos

Class Name: zCPFXControler Version Identifiers: \u2014 Gothic I: 12289 \u2014 Gothic II: 52224 Sources: \u2014 spacerhilfedatei.sph \u2014 gothic-library.ru \u2014 zk.gothickit.dev

A particle system in virtual space. Its effect can be activated and deactivated using the OnTrigger and OnUntrigger events.

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCPFXControler/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCPFXControler/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCPFXControler/#pfxname","title":"pfxName","text":"

The name of the particle effect. Corresponds to a .ZEN file containing the particle system definition.

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCPFXControler/#killvobwhendone","title":"killVobWhenDone","text":"

Disable the particle effect after it runs once.

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCPFXControler/#pfxstarton","title":"pfxStartOn","text":"

Whether to start the particle effect when the level is loaded.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCVobAnimate/","title":"zCVobAnimate","text":""},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCVobAnimate/#zcvobanimate","title":"zCVobAnimate","text":"

Quick Infos

Class Name: zCVobAnimate Version Identifiers: \u2014 Gothic I: 12289 \u2014 Gothic II: 52224 Sources: \u2014 spacerhilfedatei.sph \u2014 gothic-library.ru \u2014 zk.gothickit.dev

A VObject used to create animated models. The visual of such objects can either be a morph mesh or a model with a skeletal animation (i.e. a model script). The animation of these objects can be started and stopped using OnTrigger and OnUntrigger events.

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCVobAnimate/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCVobAnimate/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCVobAnimate/#starton","title":"startOn","text":"

Whether to start this animation when loading the level.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCVobAnimate/#isrunning","title":"isRunning","text":"

Unknown.

Warning

This property is only available in saved games.

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCVobLensFlare/","title":"zCVobLensFlare","text":""},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCVobLensFlare/#zcvoblensflare","title":"zCVobLensFlare","text":"

Quick Infos

Class Name: zCVobLensFlare Version Identifiers: \u2014 Gothic I: 64704 \u2014 Gothic II: 193 Sources: \u2014 spacerhilfedatei.sph \u2014 gothic-library.ru \u2014 zk.gothickit.dev

Represents a lens flare effect. Behaves exactly like the base zCVob but has a lens flare effect.

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCVobLensFlare/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCVobLensFlare/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCVobLensFlare/#lensflarefx","title":"lensflareFX","text":"

The name of the lens flare effect. Must be one of the effects listed in /_work/data/Presets/Lensflare.zen.

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCVobScreenFX/","title":"zCVobScreenFX","text":""},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCVobScreenFX/#zcvobscreenfx","title":"zCVobScreenFX","text":"

Quick Infos

Class Name: zCVobScreenFX Version Identifiers: \u2014 Gothic I: 12289 \u2014 Gothic II: 52224 Sources: \u2014 spacerhilfedatei.sph \u2014 gothic-library.ru \u2014 zk.gothickit.dev

Screen effect VObjects are used to create special effects. They are used for field-of-view changes, adding black bars for a cinematic feel to the game and other post-processing effects.

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCVobScreenFX/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCTouchAnimate/","title":"zCTouchAnimate","text":""},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCTouchAnimate/#zctouchanimate","title":"zCTouchAnimate","text":"

Quick Infos

Class Name: zCTouchAnimate Version Identifiers: \u2014 Gothic I: 12289 \u2014 Gothic II: 20483 Sources: \u2014 spacerhilfedatei.sph \u2014 gothic-library.ru

A VObject that plays its animation when it receives an OnTick event (basically when something touches it).

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCTouchAnimate/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCTouchAnimate/#presentation","title":"Presentation","text":"

Following video shows the behaviour of this VObject.

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCTouchAnimate/zCTouchAnimateSound/","title":"zCTouchAnimateSound","text":""},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCTouchAnimate/zCTouchAnimateSound/#zctouchanimatesound","title":"zCTouchAnimateSound","text":"

Quick Infos

Class Name: zCTouchAnimateSound Version Identifiers: \u2014 Gothic I: 12289 \u2014 Gothic II: 20483 Sources: \u2014 spacerhilfedatei.sph \u2014 gothic-library.ru

Object similar to zCTouchAnimate, but allowing to specify a sound that plays on the event activation.

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCTouchAnimate/zCTouchAnimateSound/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCTouchAnimate/zCTouchAnimateSound/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCTouchAnimate/zCTouchAnimateSound/#sfxtouch","title":"sfxTouch","text":"

The name of the sound produced upon contact with an object.

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCTouchAnimate/zCTouchAnimateSound/#presentation","title":"Presentation","text":"

Following video shows the behaviour of this VObject.

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCTouchDamage/","title":"zCTouchDamage","text":""},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCTouchDamage/#zctouchdamage","title":"zCTouchDamage","text":"

Quick Infos

Class Name: zCTouchDamage Version Identifiers: \u2014 Gothic I: 36865 \u2014 Gothic II: 36865 Source: \u2014 spacerhilfedatei.sph \u2014 gothic-library.ru \u2014 zk.gothickit.dev

A VObject which damages other VObjects colliding with it.

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCTouchDamage/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCTouchDamage/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCTouchDamage/#damage","title":"damage","text":"

The amount of damage being dealt.

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCTouchDamage/#barrier","title":"Barrier","text":"

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCTouchDamage/#blunt","title":"Blunt","text":"

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCTouchDamage/#edge","title":"Edge","text":"

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCTouchDamage/#fire","title":"Fire","text":"

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCTouchDamage/#fly","title":"Fly","text":"

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCTouchDamage/#magic","title":"Magic","text":"

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCTouchDamage/#point","title":"Point","text":"

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCTouchDamage/#fall","title":"Fall","text":"

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCTouchDamage/#damagerepeatdelaysec","title":"damageRepeatDelaySec","text":"

The delay between damage ticks when applying continuous damage. If set to 0, only deals the damage once per collision. If set to a value greater than 0, deals damage every damageRepeatDelaySec seconds.

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCTouchDamage/#damagevoldownscale","title":"damageVolDownScale","text":"

A scale value used in conjunction with damageCollType. Its function depends on the type of collision detection used.

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCTouchDamage/#damagecolltype","title":"damageCollType","text":"

The type of collision detection to use for damage calculations.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCTouchDamage/oCTouchDamage/","title":"oCTouchDamage","text":""},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCTouchDamage/oCTouchDamage/#octouchdamage","title":"oCTouchDamage","text":"

Quick Infos

Class Name: oCTouchDamage Version Identifiers: \u2014 Gothic I: 36865 \u2014 Gothic II: 36865 ZenKit Class: VTouchDamage Sources: \u2014 zk.gothickit.dev

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCTouchDamage/oCTouchDamage/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/","title":"zCTriggerBase","text":""},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/#zctriggerbase","title":"zCTriggerBase","text":"

Quick Infos

Class Name: zCTriggerBase Version Identifiers: \u2014 Gothic I: 12289 \u2014 Gothic II: 52224 Sources: \u2014 zk.gothickit.dev

The base class for many triggers.

Warning

This object is an abstract base class and cannot be instantiated by itself.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/#triggertarget","title":"triggerTarget","text":"

The name of VObject to send OnTrigger and OnUntrigger events to after processing.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCCodeMaster/","title":"zCCodeMaster","text":""},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCCodeMaster/#zccodemaster","title":"zCCodeMaster","text":"

Quick Infos

Class Name: zCCodeMaster Version Identifiers: \u2014 Gothic I: 0 \u2014 Gothic II: 0 Source: \u2014 spacerhilfedatei.sph \u2014 gothic-library.ru \u2014 zk.gothickit.dev

zCCodeMaster VObjects keep a list of 'slave' VObjects and keep track of events received by them. If the master receives an OnTrigger event from a slave, it remembers that it did. After it has receives an OnTrigger message from all slaves, it emits an OnTrigger event to the triggerTarget. Receiving or sending an OnTrigger event is also referred to as an 'activation' for this purpose.

Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCCodeMaster/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCCodeMaster/#orderrelevant","title":"orderRelevant","text":"

Controls whether the master should keep track of the order it receives messages from its slaves.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCCodeMaster/#firstfalseisfailure","title":"firstFalseIsFailure","text":"

Controls when the slave activation sequence is considered to be incorrect. After the sequence is marked as incorrect an OnTrigger event is sent to triggerTargetFailure.

Accepted values:

Warning

Only relevant if orderRelevant is set to TRUE.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCCodeMaster/#triggertargetfailure","title":"triggerTargetFailure","text":"

The name of the VObject to emit an OnTrigger event to if the activation sequence fails. This is controlled by firstFalseIsFailure.

Warning

Only relevant if orderRelevant is set to TRUE.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCCodeMaster/#untriggercancels","title":"untriggerCancels","text":"

Controls whether slaves can emit OnUntrigger events to the master VObject to mark themselves as deactivated.

Accepted values:

Warning

Only relevant if orderRelevant is set to FALSE.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCCodeMaster/#slavevobname","title":"slaveVobName","text":"

The name of a slave VObject.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCCodeMaster/#numslavestriggered","title":"numSlavesTriggered","text":"

Unknown.

Warning

This property is only available in saved games.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCMessageFilter/","title":"zCMessageFilter","text":""},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCMessageFilter/#zcmessagefilter","title":"zCMessageFilter","text":"

Quick Infos

Class Name: zCMessageFilter Version Identifiers: \u2014 Gothic I: 0 \u2014 Gothic II: 0 Sources: \u2014 spacerhilfedatei.sph \u2014 zk.gothickit.dev

Transforms any incoming OnTrigger and OnUntrigger events before passing them on to the trigger target. All OnTrigger and OnUntrigger messages received by this zCMessageFilter VObject are transformed according to onTrigger and onUntrigger and then passed on to the VObject with the name specified in the triggerTarget.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCMessageFilter/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCMessageFilter/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCMessageFilter/#ontrigger","title":"onTrigger","text":"

The type of event to emit to the triggerTarget if this VObject receives an OnTrigger message.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCMessageFilter/#onuntrigger","title":"onUntrigger","text":"

The type of event to emit to the triggerTarget if this VObject receives an OnUntrigger message.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCMoverControler/","title":"zCMoverControler","text":""},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCMoverControler/#zcmovercontroler","title":"zCMoverControler","text":"

Quick Infos

Class Name: zCMoverControler Version Identifiers: \u2014 Gothic I: 0 \u2014 Gothic II: 0 Sources: \u2014 spacerhilfedatei.sph \u2014 gothic-library.ru \u2014 zk.gothickit.dev

A VObject used to control zCMover objects of type NSTATE_SINGLE_KEYS specifically. zCMoverControler objects react to incoming OnTrigger events to send a pre-configured event to the target mover object named by the triggerTarget propery, controlling its animation. Mover controllers can make movers go to a specific keyframe in their animation or just step one keyframe back and forth at a time.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCMoverControler/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCMoverControler/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCMoverControler/#movermessage","title":"moverMessage","text":"

The type of event to emit to the triggerTarget when this controller receives an OnTrigger event.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCMoverControler/#gotofixedkey","title":"gotoFixedKey","text":"

The keyframe of the mover referred to by triggerTarget to move to.

Warning

Only relevant if moverMessage is GOTO_KEY_FIXED_DIRECTLY or GOTO_KEY_FIXED_ORDER.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTriggerUntouch/","title":"zCTriggerUntouch","text":""},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTriggerUntouch/#zctriggeruntouch","title":"zCTriggerUntouch","text":"

Quick Infos

Class Name: zCTriggerUntouch Version Identifiers: \u2014 Gothic I: 52224 \u2014 Gothic II: 52224 Sources: \u2014 spacerhilfedatei.sph \u2014 zk.gothickit.dev

A trigger which fires an OnTrigger event to its triggerTarget if any OnUntouch event is emitted from an inanimate object within the object's bounding box.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTriggerUntouch/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTriggerWorldStart/","title":"zCTriggerWorldStart","text":""},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTriggerWorldStart/#zctriggerworldstart","title":"zCTriggerWorldStart","text":"

Quick Infos

Class Name: zCTriggerWorldStart Version Identifiers: \u2014 Gothic I: 52224 \u2014 Gothic II: 52224 Sources: \u2014 spacerhilfedatei.sph \u2014 zk.gothickit.dev

A special trigger which fires an OnTrigger event to its triggerTarget when the world is loaded and started.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTriggerWorldStart/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTriggerWorldStart/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTriggerWorldStart/#fireonlyfirsttime","title":"fireOnlyFirstTime","text":"

Determines whether to fire the OnTrigger event only the first time the world is loaded.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/","title":"zCTrigger","text":""},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/#zctrigger","title":"zCTrigger","text":"

Quick Infos

Class Name: zCTrigger Version Identifiers: \u2014 Gothic I: 47105 \u2014 Gothic II: 47105 Sources: \u2014 spacerhilfedatei.sph \u2014 gothic-library.ru \u2014 zk.gothickit.dev

VObject to process and relay specific filtered events. When a zCTrigger receives an OnTrigger, OnDamage, or OnTouch event it checks whether the event source (an oCNpc, the player or another VObject) should be acknowledged (see respondToNPC, respondToPC and respondToObject respectively). It then verifies if it should react to the specific event by checking the reactToOnTrigger, reactToOnDamage and reactToOnTouch properties. If both checks succeed, an OnTrigger event is sent to the triggerTarget and the trigger is considered to be activated. zCTrigger objects can be enabled and disabled by firing OnEnable, OnDisable and OnToggleEnabled events at them.

Tip

The respondTo{Object,PC,NPC,VobName} properties are logically linked by and \"or\" expression.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/#reacttoontrigger","title":"reactToOnTrigger","text":"

Whether this trigger should react to OnTrigger events.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/#reacttoontouch","title":"reactToOnTouch","text":"

Whether this trigger should react to OnTouch events.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/#reacttoondamage","title":"reactToOnDamage","text":"

Whether this trigger should react to OnDamage events.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/#respondtoobject","title":"respondToObject","text":"

Whether this trigger should process events coming from inanimate objects.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/#respondtopc","title":"respondToPC","text":"

Whether this trigger should process events coming from the player.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/#respondtonpc","title":"respondToNPC","text":"

Whether this trigger should process events coming from NPCs.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/#startenabled","title":"startEnabled","text":"

Determines whether the trigger is initially enabled. Enabled triggers will process incoming events and send outgoing events while disabled triggers do not. Triggers can be activated and deactivated at runtime by sending them OnEnable, OnDisable or OnToggleEnabled events.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/#respondtovobname","title":"respondToVobName","text":"

Whether this trigger should process events coming from VObjects with this name. If empty, match no VObject name directly.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/#numcanbeactivated","title":"numCanBeActivated","text":"

The number of times the trigger will process incoming events. If set to -1 the trigger will process an infinite number of events.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/#retriggerwaitsec","title":"retriggerWaitSec","text":"

The number of seconds that have to elapse after processing an event before the trigger will process additional events. All events received by the trigger during that time are ignored.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/#damagethreshold","title":"damageThreshold","text":"

The amount of damage which must be dealt for the trigger to react to an OnDamage event.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/#firedelaysec","title":"fireDelaySec","text":"

The number of seconds to wait before emitting the OnTrigger event after processing.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/#senduntrigger","title":"sendUntrigger","text":"

Whether to send and OnUntrigger event to the triggerTarget after the trigger receives an OnUntrigger or OnUntouch event. Only fires the OnUntrigger event if reactToOnTrigger and reactToOnTouch are set to TRUE respectively.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/#nexttimetriggerable","title":"nextTimeTriggerable","text":"

Unknown.

Warning

This property is only available in saved games.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/#savedothervob","title":"savedOtherVob","text":"

Unknown.

Warning

This property is only available in saved games.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/#countcanbeactivated","title":"countCanBeActivated","text":"

Unknown.

Warning

This property is only available in saved games.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/#isenabled","title":"isEnabled","text":"

Unknown.

Warning

This property is only available in saved games made using Gothic II.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/oCCSTrigger/","title":"oCCSTrigger","text":""},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/oCCSTrigger/#occstrigger","title":"oCCSTrigger","text":"

Quick Infos

Class Name: oCCSTrigger Version Identifiers: \u2014 Gothic I: 24577 \u2014 Gothic II: 24577 Sources: \u2014 spacerhilfedatei.sph \u2014 gothic-library.ru \u2014 zk.gothickit.dev

A special trigger VObject which can start a cutscene. The triggerTarget must be the name of the cutscene (without the extension) to be started. For this to work, the cutscene must already be loaded. OnUntrigger events are ignored by oCCSTriggers.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/oCCSTrigger/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/oCTriggerChangeLevel/","title":"oCTriggerChangeLevel","text":""},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/oCTriggerChangeLevel/#octriggerchangelevel","title":"oCTriggerChangeLevel","text":"

Quick Infos

Class Name: oCTriggerChangeLevel Version Identifiers: \u2014 Gothic I: 24577 \u2014 Gothic II: 24577 Sources: \u2014 spacerhilfedatei.sph \u2014 zk.gothickit.dev

A special zCTrigger which in addition to performing all other trigger actions also causes the engine to load another level when activated.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/oCTriggerChangeLevel/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/oCTriggerChangeLevel/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/oCTriggerChangeLevel/#levelname","title":"levelName","text":"

The name of the level to load including the file extension.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/oCTriggerChangeLevel/#startvobname","title":"startVobName","text":"

The name of the VObject in the new level to place the player at.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/oCTriggerScript/","title":"oCTriggerScript","text":""},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/oCTriggerScript/#octriggerscript","title":"oCTriggerScript","text":"

Quick Infos

Class Name: oCTriggerScript Version Identifiers: \u2014 Gothic I: 24577 \u2014 Gothic II: 24577 Sources: \u2014 spacerhilfedatei.sph \u2014 zk.gothickit.dev

A special zCTrigger which in addition to performing all other trigger actions also calls a script function when the trigger is activated. OnUntrigger events do not result in the script function being called.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/oCTriggerScript/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/oCTriggerScript/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/oCTriggerScript/#scriptfunc","title":"scriptFunc","text":"

The name script function to call when the trigger successfully processes a message.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCMover/","title":"zCMover","text":""},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCMover/#zcmover","title":"zCMover","text":"

Quick Infos

Class Name: zCMover Version Identifiers: \u2014 Gothic I: 39936 \u2014 Gothic II: 39936 Sources: \u2014 spacerhilfedatei.sph \u2014 gothic-library.ru \u2014 zk.gothickit.dev

A VObject which can move along a pre-determined path in response to an event. Movers can be controlled through a set of keyframes or the animation of their visuals. If the visual has an attached animation to be used as the mover's animation, it must have the following animations which are run depending on the mover's state: S_OPEN, S_CLOSED, T_CLOSED_2_OPEN, T_OPEN_2_CLOSED, S_LOCKED, S_UNLOCKED, T_UNLOCKED_TO_LOCKED, T_LOCKED_TO_UNLOCKED.

Each mover is in one of three states, \"open\", \"closed\" or \"moving\". Keyframe 0 (or S_OPEN when using the visual's animation) corresponds to the \"open\" state while the last keyframe (or S_CLOSED) corresponds to the \"closed\" state. When transitioning between the \"open\" and \"closed\" states, the mover is in the \"moving\" state during which it sequentially moves between its keyframes (or runs the T_CLOSED_2_OPEN or T_OPEN_TO_CLOSED animations). Movers with their moverBehavior set to NSTATE_SINGLE_KEYS are an exception to this rule: each keyframe can individually be addressed as a state.

Movers are specialized triggers. Before beginning their animation, movers first filter the incoming events as per the zCTrigger's rules and only start the animation if the event passes through the filters. When the mover reaches the \"open\" state after being activated, it emits an OnTrigger event according to the fire behavior set for the zCTrigger. Similarly, when it reaches the \"closed\" state it emits an OnUntrigger event.

Movers can be enabled and disabled using the OnEnable, OnDisable and OnToggleDisabled events.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCMover/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCMover/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCMover/#moverbehavior","title":"moverBehavior","text":"

Controls how the mover behaves in response to events (\"activation\").

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCMover/#touchblockerdamage","title":"touchBlockerDamage","text":"

The amount of damage to deal to objects in the way of the mover.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCMover/#stayopentimesec","title":"stayOpenTimeSec","text":"

The number of seconds a mover with the 2STATE_OPEN_TIMED behavior stays in the \"open\" state until transitioning to the \"closed\" state again.

Warning

Only relevant if moverBehavior is 2STATE_OPEN_TIMED.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCMover/#moverlocked","title":"moverLocked","text":"

Unclear.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCMover/#autolinkenabled","title":"autoLinkEnabled","text":"

Determines whether the position of the object triggering the mover should be tied to the mover's position.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCMover/#autorotate","title":"autoRotate","text":"

Whether to automatically rotate the mover along its movement trajectory. For example, this is used for making fish always face in the direction they're moving.

Accepted values:

Warning

Only available in Gothic II.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCMover/#numkeyframes","title":"numKeyframes","text":"

Unclear.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCMover/#movespeed","title":"moveSpeed","text":"

The movement speed for transitioning between keyframes in units per millisecond.

Warning

Only relevant if manually specified keyframes are used. Ignored when using the visual for the animation.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCMover/#poslerptype","title":"posLerpType","text":"

Defines how the mover should interpolate between the keyframe positions. Only affects the mover's position, never its rotation.

Accepted values:

Warning

Only relevant if manually specified keyframes are used. Ignored when using the visual for the animation.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCMover/#speedtype","title":"speedType","text":"

Controls the acceleration and deceleration behavior of the mover.

Accepted values:

Warning

Only relevant if manually specified keyframes are used. Ignored when using the visual for the animation.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCMover/#sfxopenstart","title":"sfxOpenStart","text":"

The name of the sound to play at the beginning of the opening sequence.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCMover/#sfxopenend","title":"sfxOpenEnd","text":"

The name of the sound to play at the end of the opening sequence.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCMover/#sfxmoving","title":"sfxMoving","text":"

The name of the sound to play in a loop while the mover is transitioning between keyframes.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCMover/#sfxclosestart","title":"sfxCloseStart","text":"

The name of the sound to play at the beginning of the closing sequence.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCMover/#sfxcloseend","title":"sfxCloseEnd","text":"

The name of the sound to play at the end of the closing sequence.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCMover/#sfxlock","title":"sfxLock","text":"

The name of the sound to play when locking a mover.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCMover/#sfxunlock","title":"sfxUnlock","text":"

The name of the sound to play when unlocking a mover.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCMover/#sfxuselocked","title":"sfxUseLocked","text":"

The name of the sound to play when using a locked mover.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCMover/#actkeyposdelta","title":"actKeyPosDelta","text":"

Unknown.

Warning

This property is only available in saved games.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCMover/#actkeyframef","title":"actKeyframeF","text":"

Unknown.

Warning

This property is only available in saved games.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCMover/#actkeyframe","title":"actKeyframe","text":"

Unknown.

Warning

This property is only available in saved games.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCMover/#nextkeyframe","title":"nextKeyframe","text":"

Unknown.

Warning

This property is only available in saved games.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCMover/#movespeedunit","title":"moveSpeedUnit","text":"

Unknown.

Warning

This property is only available in saved games.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCMover/#advancedir","title":"advanceDir","text":"

Unknown.

Warning

This property is only available in saved games.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCMover/#moverstate","title":"moverState","text":"

Unknown.

Warning

This property is only available in saved games.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCMover/#numtriggerevents","title":"numTriggerEvents","text":"

Unknown.

Warning

This property is only available in saved games.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCMover/#stayopentimedest","title":"stayOpenTimeDest","text":"

Unknown.

Warning

This property is only available in saved games.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCTriggerList/","title":"zCTriggerList","text":""},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCTriggerList/#zctriggerlist","title":"zCTriggerList","text":"

Quick Infos

Class Name: zCTriggerList Version Identifiers: \u2014 Gothic I: 59776 \u2014 Gothic II: 5505 Sources: \u2014 spacerhilfedatei.sph \u2014 gothic-library.ru \u2014 zk.gothickit.dev

A special trigger which emits the OnTrigger events emitted by the zCTrigger to multiple targets. How the events are sent can be configured through listProcess. The triggerTarget and fireDelaySec properties of zCTrigger should be ignored.

OnUntrigger events sent to the trigger list are propagated to all targets in the list.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCTriggerList/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCTriggerList/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCTriggerList/#listprocess","title":"listProcess","text":"

Controls how events are sent to the targets.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCTriggerList/#triggertarget","title":"triggerTarget","text":"

The name of the VObject to send events to. Behaves like triggerTarget.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCTriggerList/#firedelay","title":"fireDelay","text":"

The delay after which to fire the event to the target. Behaves like fireDelaySec.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCTriggerList/#acttarget","title":"actTarget","text":"

Unknown.

Warning

This property is only available in saved games.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCTriggerList/#sendontrigger","title":"sendOnTrigger","text":"

Unknown.

Warning

This property is only available in saved games.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCTriggerTeleport/","title":"zCTriggerTeleport","text":""},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCTriggerTeleport/#zctriggerteleport","title":"zCTriggerTeleport","text":"

Quick Infos

Class Name: zCTriggerTeleport Version Identifiers: \u2014 Gothic I: 59776 \u2014 Gothic II: 45570 Sources: \u2014 spacerhilfedatei.sph \u2014 gothic-library.ru

This VObject allows teleporting a hero to the waypoint.

Note

To make trigger work, you must set the value of the cdDyn parameter to True and specify the Waypoint in triggerTarget parameter.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCTriggerTeleport/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCTriggerTeleport/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCTriggerTeleport/#sfxteleport","title":"sfxTeleport","text":"

Sound accompaniment of character teleport.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/","title":"zCZone","text":""},{"location":"zengin/worlds/Classes/zCVob/zCZone/#zczone","title":"zCZone","text":"

Quick Infos

Class Name: zCZone Version Identifiers: \u2014 Gothic I: 12289 \u2014 Gothic II: 52224 Sources: \u2014 zk.gothickit.dev

The base class for effect zones.

Warning

This object is an abstract base class and cannot be instantiated by itself.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCZone/oCZoneMusic/","title":"oCZoneMusic","text":""},{"location":"zengin/worlds/Classes/zCVob/zCZone/oCZoneMusic/#oczonemusic","title":"oCZoneMusic","text":"

Quick Infos

Class Name: oCZoneMusic Version Identifiers: \u2014 Gothic I: 0 \u2014 Gothic II: 0 Sources: \u2014 spacerhilfedatei.sph \u2014 gothic-library.ru \u2014 zk.gothickit.dev

A VObject which defines the music to be played within its bounding box. Music zones may overlap; if they do, their priority property determines which music zone should be used. The camera object is used to test which music zone applies. If no music zone applies the music defined in the optional oCZoneMusicDefault is used.

The name of the music theme to be played is defined by the vobName. Notice that end of the name is taken as a C_MUSICTHEME prefix. For example zone OLDCAMP_OC will play theme starting with OC_.

Tip

If the suffix _NCI or _NCO is added to the end of the zone name, it snows instead of rains in the zone.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/oCZoneMusic/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCZone/oCZoneMusic/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCVob/zCZone/oCZoneMusic/#enabled","title":"enabled","text":"

Whether the music zone is enabled when loading the level. When disabled, no music will be played in the zone.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/oCZoneMusic/#priority","title":"priority","text":"

The priority of the music zone if two zones overlap. A higher number means a higher priority. 0 is the lowest possible priority.

Warning

Only relevant if two zCZoneMusic zones overlap.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/oCZoneMusic/#ellipsoid","title":"ellipsoid","text":"

Determines the shape of the zone.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/oCZoneMusic/#reverblevel","title":"reverbLevel","text":"

Unclear.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/oCZoneMusic/#volumelevel","title":"volumeLevel","text":"

Unclear.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/oCZoneMusic/#loop","title":"loop","text":"

Unclear.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/oCZoneMusic/#local_enabled","title":"local_enabled","text":"

Unknown.

Warning

This property is only available in saved games.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/oCZoneMusic/#dayentrancedone","title":"dayEntranceDone","text":"

Unknown.

Warning

This property is only available in saved games.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/oCZoneMusic/#nightentrancedone","title":"nightEntranceDone","text":"

Unknown.

Warning

This property is only available in saved games.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/oCZoneMusic/oCZoneMusicDefault/","title":"oCZoneMusicDefault","text":""},{"location":"zengin/worlds/Classes/zCVob/zCZone/oCZoneMusic/oCZoneMusicDefault/#oczonemusicdefault","title":"oCZoneMusicDefault","text":"

Quick Infos

Class Name: oCZoneMusicDefault Version Identifiers: \u2014 Gothic I: 0 \u2014 Gothic II: 0 Sources: \u2014 spacerhilfedatei.sph \u2014 zk.gothickit.dev

Determines the default music to be played when the camera is outside any oCZoneMusic zones. The volume-related options of the zone are ignored. There may only be one oCZoneMusicDefault object in a world.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/oCZoneMusic/oCZoneMusicDefault/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCVobSound/","title":"zCVobSound","text":""},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCVobSound/#zcvobsound","title":"zCVobSound","text":"

Quick Infos

Class Name: zCVobSound Version Identifiers: \u2014 Gothic I: 12289 \u2014 Gothic II: 12289 Sources: \u2014 spacerhilfedatei.sph \u2014 gothic-library.ru \u2014 zk.gothickit.dev

Emits a sound defined by a script instance in a given radius. The sound playback can be activated by sending an OnTrigger event to the VObject and sending an OnUntrigger event disables the sound playback.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCVobSound/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCVobSound/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCVobSound/#sndvolume","title":"sndVolume","text":"

The volume of the sound effect in percent (0-100).

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCVobSound/#sndmode","title":"sndMode","text":"

Determines how the sound effect is played.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCVobSound/#sndranddelay","title":"sndRandDelay","text":"

The average delay between repetitions in seconds if sndMode is RANDOM.

Warning

Only relevant if sndMode is RANDOM.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCVobSound/#sndranddelayvar","title":"sndRandDelayVar","text":"

The maximum deviation of the random delay between repetitions if sndMode is RANDOM. The resulting delay will be a value between sndRandDelay \u00b1 sndRandDelayVar.

Warning

Only relevant if sndMode is RANDOM.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCVobSound/#sndstarton","title":"sndStartOn","text":"

Whether to start the sound when loading the world.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCVobSound/#sndambient3d","title":"sndAmbient3D","text":"

Determines whether the sound is an omnidirectional ambient sound. It will change volume depending on the distance to this VObject, but it won't sound as if this VObject is emitting the effect.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCVobSound/#sndobstruction","title":"sndObstruction","text":"

Whether to dampen the sound when there is no direct path from the VObject to the listener.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCVobSound/#sndconeangle","title":"sndConeAngle","text":"

When set to a value other than 0, determines a cone in front of the VObject in which the sound can be heard. To listeners outside of that cone, the sound is not heard. Only values between 0 and 360 are valid.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCVobSound/#sndvoltype","title":"sndVolType","text":"

Determines the type of volume used to check whether the sound can be heard.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCVobSound/#sndradius","title":"sndRadius","text":"

The radius in which the sound can be heard.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCVobSound/#sndname","title":"sndName","text":"

The name of the script instance describing the sound.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCVobSound/#soundisrunning","title":"soundIsRunning","text":"

Unknown.

Warning

This property is only available in saved games.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCVobSound/#soundallowedtorun","title":"soundAllowedToRun","text":"

Unknown.

Warning

This property is only available in saved games.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCVobSound/zCVobSoundDaytime/","title":"zCVobSoundDaytime","text":""},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCVobSound/zCVobSoundDaytime/#zcvobsounddaytime","title":"zCVobSoundDaytime","text":"

Quick Infos

Class Name: zCVobSoundDaytime Version Identifiers: \u2014 Gothic I: 12289 \u2014 Gothic II: 12289 Sources: \u2014 spacerhilfedatei.sph \u2014 gothic-library.ru \u2014 zk.gothickit.dev

Emits a sound defined by a script instance in a given radius during a given time during the day. Optionally, another sound can be defined which is played outside the defined time range (example: birds during the day and crickets at night).

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCVobSound/zCVobSoundDaytime/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCVobSound/zCVobSoundDaytime/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCVobSound/zCVobSoundDaytime/#sndstarttime","title":"sndStartTime","text":"

The time of day after which the sound can be heard (13.5 corresponds to 13:30). Must be less than sndEndTime.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCVobSound/zCVobSoundDaytime/#sndendtime","title":"sndEndTime","text":"

The time of day after which the sound can no longer be heard (13.5 corresponds to 13:30). Must be greater than sndStartTime.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCVobSound/zCVobSoundDaytime/#sndname2","title":"sndName2","text":"

The name of the script instance describing the sound to play outside the hours defined by sndStartTime and sndendtime. May be empty.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCZoneVobFarPlane/","title":"zCZoneVobFarPlane","text":""},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCZoneVobFarPlane/#zczonevobfarplane","title":"zCZoneVobFarPlane","text":"

Quick Infos

Class Name: zCZoneVobFarPlane Version Identifiers: \u2014 Gothic I: 12289 \u2014 Gothic II: 52224 Sources: \u2014 gothic-library.ru \u2014 zk.gothickit.dev

A VObject which defines the loading range of VObjects within its bounding box.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCZoneVobFarPlane/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCZoneVobFarPlane/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCZoneVobFarPlane/#vobfarplanez","title":"vobFarPlaneZ","text":"

The loading range of VObject within.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCZoneVobFarPlane/#innerrangeperc","title":"innerRangePerc","text":"

Unknown.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCZoneVobFarPlane/zCZoneVobFarPlaneDefault/","title":"zCZoneVobFarPlaneDefault","text":""},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCZoneVobFarPlane/zCZoneVobFarPlaneDefault/#zczonevobfarplanedefault","title":"zCZoneVobFarPlaneDefault","text":"

Quick Infos

Class Name: zCZoneVobFarPlaneDefault Version Identifiers: \u2014 Gothic I: 12289 \u2014 Gothic II: 52224 Sources: \u2014 gothic-library.ru \u2014 zk.gothickit.dev

A VObject which defines the default loading range of VObjects in the entire world. There may only be one of these objects in each world. Its effect can be overridden using zCZoneVobFarPlane objects.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCZoneVobFarPlane/zCZoneVobFarPlaneDefault/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCZoneZFog/","title":"zCZoneZFog","text":""},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCZoneZFog/#zczonezfog","title":"zCZoneZFog","text":"

Quick Infos

Class Name: zCZoneZFog Version Identifiers: \u2014 Gothic I: 12289 \u2014 Gothic II: 52224 Sources: \u2014 gothic-library.ru \u2014 zk.gothickit.dev

A VObject which causes fog to appear within its bounding box.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCZoneZFog/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCZoneZFog/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCZoneZFog/#fograngecenter","title":"fogRangeCenter","text":"

The maximum distance of visibility if the player is in the center of the fog object.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCZoneZFog/#innerrangeperc","title":"innerRangePerc","text":"

Unknown.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCZoneZFog/#fogcolor","title":"fogColor","text":"

The color of the fog.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCZoneZFog/#fadeoutsky","title":"fadeOutSky","text":"

Whether to hide the sky when the player is inside the fog.

Accepted values:

Warning

This property is only available in Gothic II.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCZoneZFog/#overridecolor","title":"overrideColor","text":"

Unclear.

Warning

This property is only available in Gothic II.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCZoneZFog/zCZoneZFogDefault/","title":"zCZoneZFogDefault","text":""},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCZoneZFog/zCZoneZFogDefault/#zczonezfogdefault","title":"zCZoneZFogDefault","text":"

Quick Infos

Class Name: zCZoneZFogDefault Version Identifiers: \u2014 Gothic I: 12289 \u2014 Gothic II: 52224 Sources: \u2014 gothic-library.ru \u2014 zk.gothickit.dev

A VObject which defines the default fog for the entire world. There may only be one of these objects in each world. Its effect can be overridden using zCZoneZFog objects.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCZoneZFog/zCZoneZFogDefault/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"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":""},{"location":"blog/tags/#documentation","title":"Documentation","text":""},{"location":"blog/tags/#how-to","title":"How-To","text":""},{"location":"blog/tags/#mkdocs","title":"MkDocs","text":""},{"location":"blog/tags/#i18n","title":"i18n","text":""},{"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.

"},{"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:

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:

"},{"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

"},{"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":"

MEM_GetCommandLine

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":"

MEM_GetGothOpt

Przeszukuje Gothic.ini w poszukiwaniu opcji

func string MEM_GetGothOpt(var string sectionname, var string optionname)\n
Parametry

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":"

MEM_GetModOpt

Przeszukuje ini za\u0142adowanej modyfikacji w poszukiwaniu opcji.

func void MEM_GetModOpt(var string sectionname, var string optionname)\n
Parametry

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":"

MEM_GothOptSectionExists

Sprawdza, czy dana sekcja istnieje w Gothic.ini

func int MEM_GothOptSectionExists(var string sectionname)\n
Parametry

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":"

MEM_ModOptSectionExists

Sprawdza, czy dana sekcja istnieje w ini za\u0142adowanej modyfikacji.

func int MEM_ModOptSectionExists(var string sectionname)\n
Parametry

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":"

MEM_GothOptExists

Sprawdza, czy dana opcja istnieje w Gothic.ini

func int MEM_GothOptExists(var string sectionname, var string optionname)\n
Parametry

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":"

MEM_ModOptExists

Sprawdza, czy dana opcja istnieje w ini za\u0142adowanej modyfikacji.

func int MEM_ModOptExists(var string sectionname, var string optionname)\n
Parametry

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":"

MEM_SetGothOpt

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 "},{"location":"pl/zengin/scripts/extenders/ikarus/functions/ini_access/#mem_applygothopt","title":"MEM_ApplyGothOpt","text":"

MEM_ApplyGothOpt

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":"

MEM_GetKey

Zwraca podstawowy klawisz przypisany do klawisza logicznego.

func int MEM_GetKey(var string name)\n
Parametry

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":"

MEM_GetSecondaryKey

Zwraca zapasowy klawisz przypisany do klawisza logicznego.

func int MEM_GetSecondaryKey(var string name)\n
Parametry

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":"

MEM_SetKeys

Ustawia klawisze klawiatury dla podanego klawisza logicznego.

func void MEM_SetKeys(var string name, var int primary, var int secondary)\n
Parametry "},{"location":"pl/zengin/scripts/extenders/ikarus/functions/ini_access/#mem_setkey","title":"MEM_SetKey","text":"

MEM_SetKey

Ustawia podstawowy klawisz klawiatury dla klawisza logicznego.

func void MEM_SetKey(var string name, var int key)\n
Parametry "},{"location":"pl/zengin/scripts/extenders/ikarus/functions/ini_access/#mem_setsecondarykey","title":"MEM_SetSecondaryKey","text":"

MEM_SetSecondaryKey

Ustawia zapasowy klawisz klawiatury dla klawisza logicznego.

func void MEM_SetSecondaryKey(var string name, var int key)\n
Parametry "},{"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":"

Info

Zale\u017cno\u015bci: - PermMem - View Implementacja: Bars.d na GitHubie

Ten pakiet bardzo u\u0142atwia dodawanie nowych pask\u00f3w, dla wy\u015bwietlania np. wytrzyma\u0142o\u015bci.

"},{"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/#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":"

Bar_Create

Tworzy nowy pasek z instancji konstruktora.

func int Bar_Create(var int inst)\n

Parametry

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":"

Bar_Delete

Usuwa pasek z ekranu i pami\u0119ci.

func void Bar_Delete(var int bar)\n

Parametry

"},{"location":"pl/zengin/scripts/extenders/lego/applications/bars/#bar_setmax","title":"Bar_SetMax","text":"

Bar_SetMax

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 "},{"location":"pl/zengin/scripts/extenders/lego/applications/bars/#bar_setvalue","title":"Bar_SetValue","text":"

Bar_SetValue

Ustawia warto\u015b\u0107 paska.

func void Bar_SetValue(var int bar, var int val)\n
Parametry "},{"location":"pl/zengin/scripts/extenders/lego/applications/bars/#bar_setpercent","title":"Bar_SetPercent","text":"

Bar_SetPercent

Ustawia warto\u015b\u0107 paska, ale w procentach (0..100).

func void Bar_SetPercent(var int bar, var int perc)\n
Parametry "},{"location":"pl/zengin/scripts/extenders/lego/applications/bars/#bar_setpromille","title":"Bar_SetPromille","text":"

Bar_SetPromille

Ustawia warto\u015b\u0107 paska, ale w promilach (0..1000).

func void Bar_SetPromille(var int bar, var int pro)\n
Parametry "},{"location":"pl/zengin/scripts/extenders/lego/applications/bars/#bar_hide","title":"Bar_Hide","text":"

Bar_Hide

Ukrywa pasek, ale go nie usuwa.

func void Bar_Hide(var int bar)\n
Parametry "},{"location":"pl/zengin/scripts/extenders/lego/applications/bars/#bar_show","title":"Bar_Show","text":"

Bar_Show

Wy\u015bwietla pasek ponownie po u\u017cyciu Bar_Hide.

func void Bar_Show(var int bar)\n
Parametry "},{"location":"pl/zengin/scripts/extenders/lego/applications/bars/#bar_moveto","title":"Bar_MoveTo","text":"

Bar_MoveTo

Przenosi pasek do danej pozycji wirtualnej.

func void Bar_MoveTo(var int bar, var int x, var int y)\n
Parametry "},{"location":"pl/zengin/scripts/extenders/lego/applications/bars/#bar_movetopxl","title":"Bar_MoveToPxl","text":"

Bar_MoveToPxl

Przenosi pasek do danej pozycji wyra\u017conej w pikselach.

func void Bar_MoveToPxl(var int bar, var int x, var int y)\n
Parametry "},{"location":"pl/zengin/scripts/extenders/lego/applications/bars/#bar_setalpha","title":"Bar_SetAlpha","text":"

Bar_SetAlpha

Ustawia przezroczysto\u015b\u0107 paska.

func void Bar_SetAlpha(var int bar, var int alpha)\n
Parametry "},{"location":"pl/zengin/scripts/extenders/lego/applications/bars/#bar_setbartexture","title":"Bar_SetBarTexture","text":"

Bar_SetBarTexture

Ustawia tekstur\u0119 warto\u015bci paska.

func void Bar_SetBarTexture(var int bar, var string barTex)\n
Parametry "},{"location":"pl/zengin/scripts/extenders/lego/applications/bars/#bar_setbacktexture","title":"Bar_SetBackTexture","text":"

Bar_SetBackTexture

Ustawia tekstur\u0119 t\u0142a paska.

func void Bar_SetBackTexture(var int bar, var string backTex)\n
Parametry "},{"location":"pl/zengin/scripts/extenders/lego/applications/bars/#bar_resize","title":"Bar_Resize","text":"

Bar_Resize

Zmienia rozmiar istniej\u0105cego paska.

func void Bar_Resize(var int bar, var int width, var int height)\n
Parametry "},{"location":"pl/zengin/scripts/extenders/lego/applications/bars/#bar_resizepxl","title":"Bar_ResizePxl","text":"

Bar_ResizePxl

Resize existing bar (in pixels).

func void Bar_ResizePxl(var int bar, var int x, var int y)\n
Parametry "},{"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":"

Info

Zale\u017cno\u015bci: - PermMem - HookEngine Implementacja: ConsoleCommands.d na GitHubie

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/#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/#funkcje","title":"Funkcje","text":""},{"location":"pl/zengin/scripts/extenders/lego/applications/console_commands/#cc_register","title":"CC_Register","text":"

CC_Register

Rejestruje nowe polecenie konsoli.

func void CC_Register(var func f, var string cmdPrefix, var string description)\n
Parametry "},{"location":"pl/zengin/scripts/extenders/lego/applications/console_commands/#cc_remove","title":"CC_Remove","text":"

CC_Remove

Usuwa funkcje z konsoli komend.

func void CC_Remove(var func f)\n
Parametry "},{"location":"pl/zengin/scripts/extenders/lego/applications/console_commands/#cc_active","title":"CC_Active","text":"

CC_Active

Sprawdza, czy dana funkcja jest ju\u017c cz\u0119\u015bci\u0105 polecenia konsoli.

func int CC_Active(var func f)\n
Parametry

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":"

Info

Zale\u017cno\u015bci: - EventHandler - Saves Implementacja: Gamestate.d na GitHubie

Pakiet Gamestate pozwala sprawdzi\u0107 stan gry (rozpocz\u0119cie gry, \u0142adowanie gry lub zmiana poziomu).

"},{"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/#funkcje","title":"Funkcje","text":""},{"location":"pl/zengin/scripts/extenders/lego/applications/gamestate/#gamestate_addlistener","title":"Gamestate_AddListener","text":"

Gamestate_AddListener

Dodaje listener/handler zmiany stanu gry.

func void Gamestate_AddListener(var func listener)\n
Parametry "},{"location":"pl/zengin/scripts/extenders/lego/applications/gamestate/#gamestate_removelistener","title":"Gamestate_RemoveListener","text":"

Gamestate_RemoveListener

Usuwa listener zmiany stanu gry.

func void Gamestate_RemoveListener(var func listener)\n
Parametry "},{"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":"

Info

Zale\u017cno\u015bci: - AI_Function Implementacja: Trialoge.d na GitHubie

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/#inicjalizacja","title":"Inicjalizacja","text":"

Zainicjuj za pomoc\u0105 flagi LeGo_Trialoge.

LeGo_Init(LeGo_Trialoge);\n
"},{"location":"pl/zengin/scripts/extenders/lego/applications/trialoge/#funkcje","title":"Funkcje","text":""},{"location":"pl/zengin/scripts/extenders/lego/applications/trialoge/#equipweapon","title":"EquipWeapon","text":"

EquipWeapon

Funkcja Sektenspinnera. Sprawia, \u017ce NPC wyposa\u017ca bro\u0144.

func void EquipWeapon(var C_NPC slf, var int ItemInstance)\n
Parametry

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:

"},{"location":"pl/zengin/scripts/extenders/lego/applications/trialoge/#npc_getarmor","title":"Npc_GetArmor","text":"

Npc_GetArmor

Pobiera pancerz wyposa\u017cony przez NPC.

func int Npc_GetArmor(var C_NPC slf)\n
Parametry

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":"

Npc_GetMeleeWeapon

Pobiera wyposa\u017con\u0105 przez NPC bro\u0144 bia\u0142\u0105.

func int Npc_GetMeleeWeapon(var C_NPC slf)\n
Parametry

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":"

Npc_GetRangedWeapon

Pobiera wyposa\u017con\u0105 przez NPC bro\u0144 dystansow\u0105.

func int Npc_GetRangedWeapon(var C_NPC slf)\n
Parametry

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":"

Npc_TradeItem

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 "},{"location":"pl/zengin/scripts/extenders/lego/applications/trialoge/#diacam_update","title":"DiaCAM_Update","text":"

DiaCAM_Update

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":"

DiaCAM_Disable

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":"

DiaCAM_Enable

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":"

TRIA_Wait

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":"

TRIA_Invite

Zaprasza NPC do rozmowy. Nale\u017cy wywo\u0142a\u0107 przed TRIA_Start.TRIA_Start.

func void TRIA_Invite(var C_NPC slf)\n
Parametry "},{"location":"pl/zengin/scripts/extenders/lego/applications/trialoge/#tria_start","title":"TRIA_Start","text":"

TRIA_Start

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":"

TRIA_Barrier

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":"

TRIA_Next

Ustawia podanego NPC na self.

func void TRIA_Next(var C_NPC n0)\n
Parametry "},{"location":"pl/zengin/scripts/extenders/lego/applications/trialoge/#tria_cam","title":"TRIA_Cam","text":"

TRIA_Cam

Rozpoczyna zdefiniowany wcze\u015bniej ruch kamery.

func void TRIA_Cam(var string evt)\n
Parametry "},{"location":"pl/zengin/scripts/extenders/lego/applications/trialoge/#tria_finish","title":"TRIA_Finish","text":"

TRIA_Finish

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":""},{"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

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":"

Info

Zale\u017cno\u015bci: - Brak Implementacja: BinaryMachines.d na GitHub

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/#inicjalizacja","title":"Inicjalizacja","text":"

Brak

"},{"location":"pl/zengin/scripts/extenders/lego/tools/binary_machines/#bw_newfile","title":"BW_NewFile","text":"

BW_NewFile

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

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":"

BW_Close

Zamyka aktualny strumie\u0144 zapisu.

func void BW_Close()\n
"},{"location":"pl/zengin/scripts/extenders/lego/tools/binary_machines/#bw","title":"BW","text":"

BW

Zapisuje length bajt\u00f3w z data do strumienia, maksymalnie 4 bajty.

func void BW(var int data, var int length)\n
Parametry "},{"location":"pl/zengin/scripts/extenders/lego/tools/binary_machines/#bw_int","title":"BW_Int","text":"

BW_Int

Zapisuje 4 bajty z data do strumienia. To samo co BW(data, 4).

func void BW_Int(var int data)\n
Parametry "},{"location":"pl/zengin/scripts/extenders/lego/tools/binary_machines/#bw_char","title":"BW_Char","text":"

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)\n
Parametry "},{"location":"pl/zengin/scripts/extenders/lego/tools/binary_machines/#bw_string","title":"BW_String","text":"

BW_String

Zapisuje data zako\u0144czone znakiem \\0 do strumienia.

func void BW_String(var string data)\n
Parametry "},{"location":"pl/zengin/scripts/extenders/lego/tools/binary_machines/#bw_byte","title":"BW_Byte","text":"

BW_Byte

Zapisuje bajt z data do strumienia. To samo co BW(data, 1).

func void BW_Byte(var int data)\n
Parametry "},{"location":"pl/zengin/scripts/extenders/lego/tools/binary_machines/#bw_bytes","title":"BW_Bytes","text":"

BW_Bytes

Zapisuje length bajt\u00f3w ze wska\u017anika dataPtr do strumienia.

func void BW_Bytes(var int dataPtr, var int length)\n
Parametry "},{"location":"pl/zengin/scripts/extenders/lego/tools/binary_machines/#bw_text","title":"BW_Text","text":"

BW_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 "},{"location":"pl/zengin/scripts/extenders/lego/tools/binary_machines/#bw_nextline","title":"BW_NextLine","text":"

BW_NextLine

Zapisuje akapit do strumienia.

func void BW_NextLine()\n
"},{"location":"pl/zengin/scripts/extenders/lego/tools/binary_machines/#br_openfile","title":"BR_OpenFile","text":"

BR_OpenFile

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

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":"

BR_Close

Zamyka aktualny strumie\u0144 odczytu.

func void BR_Close()\n
"},{"location":"pl/zengin/scripts/extenders/lego/tools/binary_machines/#br","title":"BR","text":"

BR

Odczytuje bajty ze strumienia.

func int BR(var int length)\n
Parametry

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":"

BR_Int

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":"

BR_Char

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":"

BR_String

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":"

BR_Byte

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":"

BR_Bytes

Odczytuje bajty ze strumienia.

func int BR_Bytes(var int length)\n
Parametry

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":"

BR_TextLine

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":"

BR_Text

Odczytuje ci\u0105g znak\u00f3w o podanej d\u0142ugo\u015bci ze strumienia.

func string BR_Text(var int length)\n
Parametry

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":"

BR_NextLine

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":"

WIN_GetLastError

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":"

WIN_CreateFile

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":"

WIN_WriteFile

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":"

WIN_ReadFile

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":"

WIN_CloseHandle

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":"

WIN_GetFileSize

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":"

Info

Zale\u017cno\u015bci: - Brak Implementacja: ItemHelper.d na GitHubie

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/#inicjalizacja","title":"Inicjalizacja","text":"

Nie dotyczy.

"},{"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":"

Itm_GetPtr

func int Itm_GetPtr(var int instance)\n
Parametry

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":"

Info

Zale\u017cno\u015bci: - Nie dotyczy. Implementacja: Misc.d na GitHubie

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/#inicjalizacja","title":"Inicjalizacja","text":"

Nie dotyczy.

"},{"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":"

atan2f

Oblicza arcus tangens k\u0105ta mi\u0119dzy pocz\u0105tkiem a punktem (x, y).

func int atan2f(var int x, var int y)\n
Parametry

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":"

sin

Oblicza sinus k\u0105ta podanego w radianach.

func int sin(var int angle)\n
Parametry

Zwracana warto\u015b\u0107

Funkcja zwraca sinus k\u0105ta, jako ikarusowy float.

"},{"location":"pl/zengin/scripts/extenders/lego/tools/misc/#cos","title":"cos","text":"

cos

Oblicza cosinus k\u0105ta podanego w radianach.

func int cos(var int angle)\n
Parametry

Zwracana warto\u015b\u0107

Funkcja zwraca cosinus k\u0105ta, jako ikarusowy float.

"},{"location":"pl/zengin/scripts/extenders/lego/tools/misc/#tan","title":"tan","text":"

tan

Oblicza tangens k\u0105ta podanego w radianach.

func int tan(var int angle)\n
Parametry

Zwracana warto\u015b\u0107

Funkcja zwraca tangens k\u0105ta, jako ikarusowy float.

"},{"location":"pl/zengin/scripts/extenders/lego/tools/misc/#asin","title":"asin","text":"

asin

Oblicza arcus sinus

func int asin(var int sine)\n
Parametry

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":"

acos

Oblicza arcus cosinus

func int acos(var int cosine)\n
Parametry

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":"

distance2D

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

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":"

distance2Df

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

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":"

Info

Zale\u017cno\u015bci: - PermMem Implementacja: Talents.d na GitHubie

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/#inicjalizacja","title":"Inicjalizacja","text":"

Zainicjuj za pomoc\u0105 flagi LeGo_PermMem.

LeGo_Init(LeGo_PermMem);\n
"},{"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":"

NPC_GetID

Zwraca unikalne ID dla podanego NPC.

func int NPC_GetID(var C_NPC slf)\n
Parametry

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":"

NPC_FindByID

Znajduje wska\u017anik NPC o podanym ID.

func int NPC_FindByID(var int ID)\n
Parametry

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":"

TAL_CreateTalent

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":"

TAL_SetValue

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 "},{"location":"pl/zengin/scripts/extenders/lego/tools/talents/#tal_getvalue","title":"TAL_GetValue","text":"

TAL_GetValue

Zwraca warto\u015b\u0107 talentu dla okre\u015blonego NPC.

func int TAL_GetValue(var C_NPC npc, var int talent)\n
Parametry "},{"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":"pl/zengin/sound/","title":"D\u017awi\u0119k","text":""},{"location":"pl/zengin/sound/#d\u017awi\u0119k","title":"D\u017awi\u0119k","text":"

ZenGin u\u017cywa plik\u00f3w .wav do odtwarzania efekt\u00f3w d\u017awi\u0119kowych i dubbingu.

Informacja

\u015acie\u017cka d\u017awi\u0119kowa w grze nie jest zapisywana w plikach d\u017awi\u0119kowych .wav. Zobacz Muzyka.

"},{"location":"pl/zengin/sound/#w\u0142a\u015bciwo\u015bci","title":"W\u0142a\u015bciwo\u015bci","text":"

Oryginalne pliki d\u017awi\u0119kowe gothica maj\u0105 nast\u0119puj\u0105ce w\u0142a\u015bciwo\u015bci:

"},{"location":"pl/zengin/sound/#efekty-d\u017awi\u0119kowe","title":"Efekty d\u017awi\u0119kowe","text":"

Efekty d\u017awi\u0119kowe (SFX) to d\u017awi\u0119ki wydawane przez potwory, zakl\u0119cia, bro\u0144 itp. Efekty d\u017awi\u0119kowe s\u0105 definiowane w wielu miejscach, w plikach .mds jako cz\u0119\u015b\u0107 animacji EventBlocks, lub w skryptach SFX Daedalus. D\u017awi\u0119ki znajduj\u0105 si\u0119 w katalogu _work/Data/Sound/SFX.

"},{"location":"pl/zengin/sound/#speech","title":"Speech","text":"

Dubbing dla dialog\u00f3w znajduje si\u0119 w folderze _work/Data/Sound/Speech. Ka\u017cde pojedyncze AI_Output ma sw\u00f3j w\u0142asny plik d\u017awi\u0119kowy o nazwie zdefiniowanej w samej funkcji.

W przypadku tej linii dialogowej

AI_Output(self,hero,\"Info_Diego_Gamestart_11_00\"); //Jestem Diego.\n
silnik odtworzy plik d\u017awi\u0119kowy Info_Diego_Gamestart_11_00.wav (je\u015bli istnieje)."},{"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.

"},{"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:

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:

"},{"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)
  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.

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:

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

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

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

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.

"},{"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.

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

ASC_NAME - name of the source file exported from Blender

ANI_DIR - direction of the animation

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:

"},{"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:

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:

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:

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

VDFS Tool

"},{"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

"},{"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.

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
"},{"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_menuitem/","title":"C_MENU_ITEM Daedalus class","text":""},{"location":"zengin/scripts/classes/c_menuitem/#c_menu_item-daedalus-class","title":"C_MENU_ITEM Daedalus class","text":"

Acknowledgment

Heavily inspired by the amazing documentation site Gothic library

Class C_Menu_Item describes the elements of the game menu (sliders, checkboxes, buttons, etc.) .

"},{"location":"zengin/scripts/classes/c_menuitem/#class-definition","title":"Class definition","text":"

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

C_Menu_Item Daedalus class
CONST INT MAX_USERSTRINGS       = 10;\nCONST INT MAX_ITEMS             = 150;\nCONST INT MAX_EVENTS            = 10;\nCONST INT MAX_SEL_ACTIONS       = 5;\nCONST INT MAX_USERVARS          = 4;\n\nclass C_Menu_Item\n{\n    var     string  fontName;                       // Font of the menu item.\n    var     string  text[MAX_USERSTRINGS];          // Text of the interface element.\n    var     string  backPic;                        // Background image of menu items.\n    var     string  alphaMode;                      // Transparency blending mode of menu items.\n    var     int     alpha;                          // Transparency of the menu item.\n    var     int     type;                           // Type of the interface element.\n    var     int     onSelAction[MAX_SEL_ACTIONS];   // Array of commands executed when selecting the menu item.\n    var     string  onSelAction_S[MAX_SEL_ACTIONS]; // Arguments for commands specified in the onSelAction property.\n    var     string  onChgSetOption;                 // Gothic.ini file parameter modified by this menu item.\n    var     string  onChgSetOptionSection;          // Section of the Gothic.ini file where the modified parameter is located.\n    var     func    onEventAction[MAX_EVENTS];      // Call the required function by a constant identifier.\n    var     int     posx;                           // Top-left point of the menu item on the screen horizontally (X-axis).\n    var     int     posy;                           // Top-left point of the menu item on the screen vertically (Y-axis).\n    var     int     dimx;                           // Width of the menu item in virtual coordinates.\n    var     int     dimy;                           // Height of the menu item in virtual coordinates.\n    var     float   sizeStartScale;                 // Initial size of the item. Not used.\n    var     int     flags;                          // Flags of the menu item.\n    var     float   openDelayTime;                  // Delay before opening the item. Not used.\n    var     float   openDuration;                   // Opening time. Not used.\n    var     float   userFloat[MAX_USERVARS];        // Digital settings of menu items.\n    var     string  userString[MAX_USERVARS];       // String settings of menu items.\n    var     int     frameSizeX;                     // Text offset inside the frame on the X-axis.\n    var     int     frameSizeY;                     // Text offset inside the frame on the Y-axis.\n    var     string  hideIfOptionSectionSet;         // Section of Gothic.ini file where the option determining the display of this menu item is located.\n    var     string  hideIfOptionSet;                // Gothic.ini file parameter determining the display of this menu item.\n    var     int     hideOnValue;                    // Value of the Gothic.ini file parameter at which this interface element is not displayed.\n}; \n
"},{"location":"zengin/scripts/classes/c_menuitem/#class-members","title":"Class members","text":"Property Type Description fontName string Font of the menu item. text string Text of the interface element. backPic string Background image of menu items. alphaMode string Transparency blending mode of menu items. alpha int Transparency of the menu item. type int Type of the interface element. onSelAction int Array of commands executed when selecting the menu item. onSelAction_S string Arguments for commands specified in the onSelAction property. onChgSetOption string Gothic.ini file parameter modified by this menu item. onChgSetOptionSection string Section of the Gothic.ini file where the modified parameter is located. onEventAction Func Call the required function by a constant identifier. posx int Top-left point of the menu item on the screen horizontally (X-axis). posy int Top-left point of the menu item on the screen vertically (Y-axis). dimx int Width of the menu item in virtual coordinates. dimy int Height of the menu item in virtual coordinates. sizeStartScale float Initial size of the item. Not used. flags int Flags of the menu item. openDelayTime float Delay before opening the item. Not used. openDuration float Opening time. Not used. userFloat float Digital settings of menu items. userString string String settings of menu items. frameSizeX int Text offset inside the frame on the X-axis. frameSizeY int Text offset inside the frame on the Y-axis. hideIfOptionSectionSet string Section of Gothic.ini file where the option determining the display of this menu item is located. hideIfOptionSet string Gothic.ini file parameter determining the display of this menu item. hideOnValue int Value of the Gothic.ini file parameter at which this interface element is not displayed."},{"location":"zengin/scripts/classes/c_menuitem/#class-member-overview","title":"Class member overview","text":"

Description of the class member variables.

"},{"location":"zengin/scripts/classes/c_menuitem/#fontname","title":"fontName","text":"

*.TGA file defining the font of the displayed text of the menu item.

To create a color change effect, two fonts are needed:

This creates a highlighting effect.

"},{"location":"zengin/scripts/classes/c_menuitem/#text","title":"text","text":"

Text inside a menu item.

Used to determine possible values \u200b\u200bfor game settings. See onChgSetOptionSection.

Also used to display hints about the item at the bottom of the menu when the MENU_SHOW_INFO flag is set.

// Text displayed in the element\n\ntext[0] = \"New Game\";\n\n// Text in the interface element responsible for game settings\n// One of the presented options is displayed\n\ntext[0] = \"off|on\";\n\n// Tooltip for the selected element\n// Index 1 is used for tooltips, not 0\n\ntext[1] = \"Start a new adventure\";\n
"},{"location":"zengin/scripts/classes/c_menuitem/#backpic","title":"backPic","text":"

Background image of the menu item in *.TGA format.

instance MENUITEM_MAIN_NEWGAME(C_MENU_ITEM_DEF)\n{\n    backpic = \"Inv_Slot_Highlighted.tga\";\n}\n
"},{"location":"zengin/scripts/classes/c_menuitem/#alphamode","title":"alphaMode","text":"

Texture transparency blending mode. Used in conjunction with the alpha property. This parameter's value is ignored if the backPic property is not specified.

Supported modes:

"},{"location":"zengin/scripts/classes/c_menuitem/#alpha","title":"alpha","text":"

Menu element transparency. Accepts values \u200b\u200bfrom 0 to 255. Without specifying the backPic property, the value of this parameter is ignored.

The alpha channel rendering mode is determined using the alphaMode property.

"},{"location":"zengin/scripts/classes/c_menuitem/#type","title":"type","text":"

Interface element type. Some interface elements have their own settings determined by the userFloat and userString properties.

Constants for menu item types are described in the file Scripts/System/_intern/Menu.d.

CONST INT MENU_ITEM_UNDEF       = 0; // Undefined\nCONST INT MENU_ITEM_TEXT        = 1; // Text\nCONST INT MENU_ITEM_SLIDER      = 2; // Slider\nCONST INT MENU_ITEM_INPUT       = 3; // Input field\nCONST INT MENU_ITEM_CURSOR      = 4; \nCONST INT MENU_ITEM_CHOICEBOX   = 5; // Checkbox\nCONST INT MENU_ITEM_BUTTON      = 6; // Button\nCONST INT MENU_ITEM_LISTBOX     = 7; // Frame\n
"},{"location":"zengin/scripts/classes/c_menuitem/#onselaction","title":"onSelAction","text":"

Array of commands executed when selecting the menu item.

Each command receives parameters in the onSelAction_S property.

Constants are described in the file Scripts/System/_intern/Menu.d.

CONST INT SEL_ACTION_UNDEF          = 0; // No action. Used when setting game parameters, calling functions...\nCONST INT SEL_ACTION_BACK           = 1; // Return to the previous menu or game\nCONST INT SEL_ACTION_STARTMENU      = 2; // Open a menu\nCONST INT SEL_ACTION_STARTITEM      = 3; // Special command for save slots\nCONST INT SEL_ACTION_CLOSE          = 4; // Close menu or game\nCONST INT SEL_ACTION_CONCOMMANDS    = 5; // Execute console command\nCONST INT SEL_ACTION_PLAY_SOUND     = 6; // Play sound from C_SFX instance\nCONST INT SEL_ACTION_EXECCOMMANDS   = 7; // Execute command specified in the onSelAction_S field using RUN or EFFECT commands\n
"},{"location":"zengin/scripts/classes/c_menuitem/#onselaction_s","title":"onSelAction_S","text":"

Arguments for commands specified in the onSelAction property.

Below are commands and their arguments:

"},{"location":"zengin/scripts/classes/c_menuitem/#onchgsetoption","title":"onChgSetOption","text":"

Parameter of the Gothic.ini file that will be modified by this menu item.

instance MENUITEM_GAME_FIGHTFOCUS_CHOICE(C_MENU_ITEM_DEF)\n{\n    text[0]     =   \"none|box|lighten|both\";\n    // [...]\n    onChgSetOption         = \"highlightMeleeFocus\"; // INI parameter\n    onChgSetOptionSection  = \"GAME\"; // INI section\n    // [...]\n};\n

The text[0] property of such an element usually specifies possible values of the modified parameter. Values are listed using the | symbol.

Make sure that the number of parameter options in the menu corresponds to the number of options in the Gothic.ini file.

highlightMeleeFocus=2\n; ... here you can turn on an optional focus highlight effect during fighting\n
"},{"location":"zengin/scripts/classes/c_menuitem/#onchgsetoptionsection","title":"onChgSetOptionSection","text":"

The section of the Gothic.ini file in which the parameter being changed is located.

See onChgSetOption above.

"},{"location":"zengin/scripts/classes/c_menuitem/#oneventaction","title":"onEventAction","text":"

Allows a user to call a function on a specified event.

The list of constants 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

For example, you can use the function associated with the constant EVENT_EXECUTE to call a script function.

instance MENUITEM_MAIN_INTRO(C_MENU_ITEM_DEF) \n{\n    text[0]     = \"Play Intro\";\n    text[1]     = \"Play introduction sequence\";\n    // [...]\n    onEventAction[EVENT_EXECUTE] = ShowIntro;\n};\n\nfunc int ShowIntro()\n{\n    PlayVideo(\"intro.bik\");\n    return 1;\n};\n
"},{"location":"zengin/scripts/classes/c_menuitem/#posx","title":"posx","text":"

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

Virtual coordinates

Virtual coordinates divide the menu into 8192 parts (0 - 8191) horizontally and vertically. The position of the menu item is calculated based on these values.

"},{"location":"zengin/scripts/classes/c_menuitem/#posy","title":"posy","text":"

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

"},{"location":"zengin/scripts/classes/c_menuitem/#dimx","title":"dimx","text":"

The width of the menu item in virtual coordinates.

Tip

To automatically determine the width, enter -1. In this case, the width is calculated based on the text contained in the element.

"},{"location":"zengin/scripts/classes/c_menuitem/#dimy","title":"dimy","text":"

The height of the menu item in virtual coordinates.

Tip

To automatically determine the element's height, enter a value of -1. In this case, the height is calculated taking into account the text contained in the element.

"},{"location":"zengin/scripts/classes/c_menuitem/#sizestartscale","title":"sizeStartScale","text":"

Deprecated setting

Size of the menu item at the beginning.

"},{"location":"zengin/scripts/classes/c_menuitem/#flags","title":"flags","text":"

Flags of the menu item.

Constants for all flags are described in the file Scripts/System/_intern/Menu.d.

const int IT_CHROMAKEYED            = 1;\nconst int IT_TRANSPARENT            = 2;\nconst int IT_SELECTABLE             = 4;        // Element can be selected\nconst int IT_MOVEABLE               = 8;\nconst int IT_TXT_CENTER             = 16;       // Align text to center\nconst int IT_DISABLED               = 32;       // Interactive item\nconst int IT_FADE                   = 64;\nconst int IT_EFFECTS_NEXT           = 128;      // Flag for influencing an adjacent menu item\nconst int IT_ONLY_OUT_GAME          = 256;      // Element available only outside the game\nconst int IT_ONLY_IN_GAME           = 512;      // Element available only in-game\nconst int IT_PERF_OPTION            = 1 << 10;  // Option responsible for performance\nconst int IT_MULTILINE              = 1 << 11;  // Multi-line text element\nconst int IT_NEEDS_APPLY            = 1 << 12;  // Need to apply a settings. Used when changing screen resolution\nconst int IT_NEEDS_RESTART          = 1 << 13;  // The game need to be restarted\nconst int IT_EXTENDED_MENU          = 1 << 14;  // Advanced menu flag\n
"},{"location":"zengin/scripts/classes/c_menuitem/#opendelaytime","title":"openDelayTime","text":"

Deprecated setting

Delay before opening a menu item.

"},{"location":"zengin/scripts/classes/c_menuitem/#openduration","title":"openDuration","text":"

Deprecated setting

The time the menu item was opened.

"},{"location":"zengin/scripts/classes/c_menuitem/#userfloat","title":"userFloat","text":"

Numerical settings of the interface element. Depending on the interface element, the purpose of the property changes. See type.

"},{"location":"zengin/scripts/classes/c_menuitem/#userstring","title":"userString","text":"

String settings of the interface element. The purpose of the property changes depending on the interface element. See type`.

"},{"location":"zengin/scripts/classes/c_menuitem/#framesizex","title":"frameSizeX","text":"

Indentation of text inside the frame along the X axis. This applies the padding to both sides of the frame. Measured in virtual coordinates from 0 to 4095.

Frames are a special tool designed to work with the log of tasks and quests.

Used for elements of type MENU_ITEM_LISTBOX.

instance MENU_ITEM_LIST_MISSIONS_ACT(C_MENU_ITEM_DEF)\n{\n    backpic         = \"NW_Misc_CaveWall_01.tga\";\n    type            = MENU_ITEM_LISTBOX;\n    text[0]         = \"Act Missions\";\n    // [...]\n    userstring[0]   = \"CURRENTMISSIONS\";\n    framesizex      = 2000;\n    framesizey      = 2000;\n};\n

As a result, we get the following frame (Source: Gothic-Library):

And the width and height of the frame are set, as for all elements, by the dimx and dimy properties.

"},{"location":"zengin/scripts/classes/c_menuitem/#framesizey","title":"frameSizeY","text":"

Indentation of text inside the frame along the Y axis. In this case, the indentation is applied at the top and bottom of the frame. Measured in virtual coordinates from 0 to 4095.

See frameSizeX above.

"},{"location":"zengin/scripts/classes/c_menuitem/#hideifoptionsectionset","title":"hideIfOptionSectionSet","text":"

The section of the Gothic.ini file with the option which value of determines the display of this menu item.

This property works together with the hideIfOptionSet and hideOnValue properties.

In the example below, the interface element will not be displayed until the useGothic1Controls parameter in the GAME section is set to 1, i.e., enabled.

instance MENU_ITEM_NEXTMENU(C_MENU_ITEM_DEF)\n{\n    text[0]     = \"More keys...\";\n    text[1]     = \"Configure further control keys\";\n    // [...]\n    hideifoptionsectionset  = \"GAME\";\n    hideifoptionset         = \"useGothic1Controls\";\n    hideonvalue             = 1;\n};\n

Tip

Gothic.ini settings can also be changed through the main menu. See onChgSetOption and onChgSetOptionSection.

"},{"location":"zengin/scripts/classes/c_menuitem/#hideifoptionset","title":"hideIfOptionSet","text":"

The Gothic.ini file parameter, the value of which determines the display of this menu item.

See hideIfOptionSectionSet.

"},{"location":"zengin/scripts/classes/c_menuitem/#hideonvalue","title":"hideOnValue","text":"

The value of the Gothic.ini file parameter at which this interface element is not displayed.

See hideIfOptionSectionSet.

"},{"location":"zengin/scripts/classes/c_menuitem/#predefined-instances","title":"Predefined instances","text":"

There are a lot of predefined class instances in the menu C_MENU_ITEM performing a strictly defined function. They cannot be renamed, but they can be configured to a certain extent.

Instance Description MENUITEM_LOADSAVE_THUMBPIC Save picture in the Save/Load menu. MENUITEM_LOADSAVE_LEVELNAME_VALUE The name of the level of the selected Save/Load menu item. MENUITEM_LOADSAVE_DATETIME_VALUE The date the selected Save/Load menu item was saved. MENUITEM_LOADSAVE_GAMETIME_VALUE Game time for saving the selected Save/Load menu item. MENUITEM_LOADSAVE_PLAYTIME_VALUE Total play time of the selected Save/Load menu item. MENUITEM_SAVE_SLOT1 - MENUITEM_SAVE_SLOT20 Save menu slots. MENUITEM_LOAD_SLOT1 - MENUITEM_LOAD_SLOT20 Load menu slots. MENU_ITEM_LIST_MISSIONS_ACT Frame with a list of current tasks in the journal. MENU_ITEM_LIST_MISSIONS_FAILED Frame with a list of failed tasks in the log. MENU_ITEM_LIST_MISSIONS_OLD Frame with a list of old tasks in the journal. MENU_ITEM_LIST_LOG Frame of general information in the task log. MENU_ITEM_CONTENT_VIEWER Job log window. MENU_ITEM_DAY Current day in the quest log window. MENU_ITEM_TIME Current time in the task log window. MENU_ITEM_PLAYERGUILD Character's guild in the statistics window. MENU_ITEM_TALENT_0_TITLE - MENU_ITEM_TALENT_16_TITLE The name of the character's talent. Array indexes are used TXT_TALENTS from the Text.d file. There may be more elements, depending on the talents realized in the game. MENU_ITEM_TALENT_0_SKILL - MENU_ITEM_TALENT_16_SKILL Character's talent level. Array indexes are used TXT_TALENTS_SKILLS from the Text.d file. MENU_ITEM_EXP The character's current experience value in the statistics window. MENU_ITEM_LEVEL Current character level in the statistics window. MENU_ITEM_LEVEL_NEXT The amount of experience required to obtain the next level in the statistics window. MENU_ITEM_LEARN The number of available training points in the statistics window. MENU_ITEM_ATTRIBUTE_1 - MENU_ITEM_ATTRIBUTE_4 Character attributes in the statistics window. MENU_ITEM_ARMOR_1 - MENU_ITEM_ARMOR_4 Character protection in the statistics window."},{"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.

Danger

Make sure that you use proper naming convention for MusicThemes and oCZoneMusic vobs. The theme with OC_ prefix will play in a zone with name like OLDCAMP_OC or any other ending with _OC

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":""},{"location":"zengin/scripts/extenders/ikarus/constants/#debug","title":"Debug","text":""},{"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:

"},{"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":"

mkf

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

func int mkf(var int x)\n
Parameters

Return value

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

"},{"location":"zengin/scripts/extenders/ikarus/floats/#truncf","title":"truncf","text":"

truncf

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

func int truncf(var int x)\n
Parameters

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":"

roundf

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

func int roundf(var int x)\n
Parameters

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":"

addf

(add floats) Adds two ikarus floats together.

func int addf(var int x, var int y)\n
Parameters

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":"

subf

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

func int subf(var int x, var int y)\n
Parameters

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":"

negf

(negate float) Negates the input float.

func int negf(var int x)\n
Parameters

Return value

The function returns the negation of the input float x.

"},{"location":"zengin/scripts/extenders/ikarus/floats/#mulf","title":"mulf","text":"

mulf

(multiply floats) Multiplies two ikarus floats.

func int mulf(var int x, var int y)\n
Parameters

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":"

divf

(divide floats) Divides two ikarus floats.

func int divf(var int x, var int y)\n
Parameters

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":"

invf

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

func int invf(var int x)\n
Parameters

Return value

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

"},{"location":"zengin/scripts/extenders/ikarus/floats/#gf","title":"gf","text":"

gf

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

func int gf(var int x, var int y)\n
Parameters

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":"

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)\n
Parameters

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":"

lf

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

func int lf(var int x, var int y)\n
Parameters

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":"

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)\n
Parameters

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":"
!!! function \"`sqrf`\"\n(square float) Calculates the square of the float.\n```dae\nfunc int sqrf(var int x)\n```\n**Parameters**\n\n- `#!dae var int x`  \n    The input float\n\n**Return value**\n\nThe function returns the square of the input float `x`, computed as `x * x`.\n
"},{"location":"zengin/scripts/extenders/ikarus/floats/#sqrtf","title":"sqrtf","text":"
!!! function \"`sqrtf`\"\n(square root float) Calculates the square root of the float.\n```dae\nfunc int sqrtf(var int x)\n```\n**Parameters**\n\n- `#!dae var int x`  \n    The input float\n\n**Return value**\n\nThe function returns the square root of the input float `x`.\n
"},{"location":"zengin/scripts/extenders/ikarus/floats/#sqrtf_approx","title":"sqrtf_approx","text":"

sqrtf_approx

Calculates the approximate square root of a float.

func int sqrtf_approx(var int f)\n
Parameters

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":"

absf

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

func int absf(var int x)\n
Parameters

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":"

fracf

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

func int fracf(var int p, var int q)\n
Parameters

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":"

castFromIntf

Converts an ikarus float to a Daedalus float.

func float castFromIntf(var int f)\n
Parameters

Return Value

The function returns the value f as a Daedalus float.

"},{"location":"zengin/scripts/extenders/ikarus/floats/#casttointf","title":"castToIntf","text":"

castToIntf

Converts a Daedalus float to an ikarus float.

func int castToIntf(var float f)\n
Parameters

Return Value

The function returns the value f as an ikarus float.

"},{"location":"zengin/scripts/extenders/ikarus/floats/#tostringf","title":"toStringf","text":"

toStringf

Converts a float value to its string representation.

func string toStringf(var int x)\n
Parameters

Return value

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

"},{"location":"zengin/scripts/extenders/ikarus/floats/#printf","title":"printf","text":"

printf

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

func void printf(var int x)\n
Parameters "},{"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
"},{"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":"

MEM_ArrayCreate

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":"

MEM_ArrayFree

Frees the memory allocated for a zCArray and its data.

func void MEM_ArrayFree(var int zCArray_ptr)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/arrays/#mem_arrayclear","title":"MEM_ArrayClear","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/arrays/#mem_arraysize","title":"MEM_ArraySize","text":"

MEM_ArraySize

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

func int MEM_ArraySize(var int zCArray_ptr)\n
Parameters

Return value

The function returns a number of a zCArray elements.

"},{"location":"zengin/scripts/extenders/ikarus/functions/arrays/#mem_arraywrite","title":"MEM_ArrayWrite","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/arrays/#mem_arrayread","title":"MEM_ArrayRead","text":"

MEM_ArrayRead

Reads the value at a specific position in the zCArray.

func int MEM_ArrayRead(var int zCArray_ptr, var int pos)\n
Parameters

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":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/arrays/#mem_arraypush","title":"MEM_ArrayPush","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/arrays/#mem_arraypop","title":"MEM_ArrayPop","text":"

MEM_ArrayPop

Removes and returns the last element from the zCArray.

func int MEM_ArrayPop(var int zCArray_ptr)\n
Parameters

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":"

MEM_ArrayTop

Returns the last element of the zCArray without removing it.

func int MEM_ArrayTop(var int zCArray_ptr)\n
Parameters

Return value

The function returns the last element of an array.

"},{"location":"zengin/scripts/extenders/ikarus/functions/arrays/#mem_arrayindexof","title":"MEM_ArrayIndexOf","text":"

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)\n
Parameters

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":"

MEM_ArrayRemoveIndex

Removes the element at a specific index from the zCArray.

func void MEM_ArrayRemoveIndex (var int zCArray_ptr, var int index)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/arrays/#mem_arrayremovevalue","title":"MEM_ArrayRemoveValue","text":"

MEM_ArrayRemoveValue

Removes all occurrences of a value from the zCArray.

func void MEM_ArrayRemoveValue (var int zCArray_ptr, var int value)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/arrays/#mem_arrayremovevalueonce","title":"MEM_ArrayRemoveValueOnce","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/arrays/#mem_arraysort","title":"MEM_ArraySort","text":"

MEM_ArraySort

Sorts the elements of the zCArray in ascending order.

func void MEM_ArraySort(var int zCArray_ptr)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/arrays/#mem_arrayunique","title":"MEM_ArrayUnique","text":"

MEM_ArrayUnique

Removes duplicate elements from the zCArray.

func void MEM_ArrayUnique(var int zCArray_ptr)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/arrays/#mem_arraytostring","title":"MEM_ArrayToString","text":"

MEM_ArrayToString

Converts the zCArray to a string representation.

func string MEM_ArrayToString (var int zCArray_ptr)\n
Parameters

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:

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":"

ASMINT_Push

Pushes the specified data onto the internal stack.

func void ASMINT_Push(var int data)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/asm/#asmint_pop","title":"ASMINT_Pop","text":"

ASMINT_Pop

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":"

ASMINT_Init

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":"

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)\n
Parameters

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":"

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)\n
Parameters ASM_1ASM_2ASM_3ASM_4"},{"location":"zengin/scripts/extenders/ikarus/functions/asm/#asm_1","title":"ASM_1","text":"

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) \n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/asm/#asm_2","title":"ASM_2","text":"

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) \n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/asm/#asm_3","title":"ASM_3","text":"

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) \n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/asm/#asm_4","title":"ASM_4","text":"

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) \n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/asm/#asm_here","title":"ASM_Here","text":"

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()\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":"

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()\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":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/asm/#asm_runonce","title":"ASM_RunOnce","text":"

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()\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":"

CALL_Open

Initializes a Recyclable call mode.

func void CALL_Open()\n
"},{"location":"zengin/scripts/extenders/ikarus/functions/call/#call_begin","title":"CALL_Begin","text":"

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)\n
Parameters

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":"

CALL_Close

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":"

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()\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":"

CALL_IntParam

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

func void CALL_IntParam(var int param)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/call/#call_floatparam","title":"CALL_FloatParam","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/call/#call_ptrparam","title":"CALL_PtrParam","text":"

CALL_PtrParam

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

func void CALL_PtrParam(var int param)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/call/#call_zstringptrparam","title":"CALL_zStringPtrParam","text":"

CALL_zStringPtrParam

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

func void CALL_zStringPtrParam(var string param)\n
Parameters

Warning

This function only works when writing a disposable call!

"},{"location":"zengin/scripts/extenders/ikarus/functions/call/#call_cstringptrparam","title":"CALL_cStringPtrParam","text":"

CALL_cStringPtrParam

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

func void CALL_cStringPtrParam(var string param)\n
Parameters

Warning

This function only works when writing a disposable call!

"},{"location":"zengin/scripts/extenders/ikarus/functions/call/#call_structparam","title":"CALL_StructParam","text":"

CALL_StructParam

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

func void CALL_StructParam(var int ptr, var int words)\n
Parameters

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":"

CALL__stdcall

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

func void CALL__stdcall(var int adr)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/call/#call__thiscall","title":"CALL__thiscall","text":"

CALL__thiscall

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

func void CALL__thiscall(var int this, var int adr)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/call/#call__cdecl","title":"CALL__cdecl","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/call/#call__fastcall","title":"CALL__fastcall","text":"

CALL__fastcall

Calls a function with __fastcall calling convention.

func void CALL__fastcall(var int ecx, var int edx, var int adr)\n
Parameters "},{"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":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/call/#call_retvalasint","title":"CALL_RetValAsInt","text":"

CALL_RetValAsInt

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":"

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()\n
"},{"location":"zengin/scripts/extenders/ikarus/functions/call/#call_retvalasfloat","title":"CALL_RetValAsFloat","text":"

CALL_RetValAsFloat

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":"

CALL_RetValAsPtr

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":"

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)\n
Parameters

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":"

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()\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":"

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()\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":"

CALL_RetValAszStringPtr

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":"

CALL_RetValAszString

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":"

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)\n
Parameters

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":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/debug/#mem_sendtospy","title":"MEM_SendToSpy","text":"

MEM_SendToSpy

Sends a message to the debugging console.

func void MEM_SendToSpy(var int errorType, var string text)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/debug/#mem_errorbox","title":"MEM_ErrorBox","text":"

MEM_ErrorBox

Displays an error message in a message box.

func void MEM_ErrorBox(var string text)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/debug/#mem_printstacktrace","title":"MEM_PrintStackTrace","text":"

MEM_PrintStackTrace

Prints the stack trace.

func void MEM_PrintStackTrace()\n
"},{"location":"zengin/scripts/extenders/ikarus/functions/debug/#mem_error","title":"MEM_Error","text":"

MEM_Error

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

func void MEM_Error(var string error)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/debug/#mem_warn","title":"MEM_Warn","text":"

MEM_Warn

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

func void MEM_Warn(var string warn)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/debug/#mem_info","title":"MEM_Info","text":"

MEM_Info

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

func void MEM_Info(var string info)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/debug/#mem_assertfail","title":"MEM_AssertFail","text":"

MEM_AssertFail

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

func void MEM_AssertFail(var string assertFailText)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/debug/#mem_debug","title":"MEM_Debug","text":"

MEM_Debug

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

func void MEM_Debug(var string message)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/debug/#memint_switchg1g2","title":"MEMINT_SwitchG1G2","text":"

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)\n
Parameters

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":"

MEM_GetCommandLine

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":"

MEM_GetGothOpt

Searches the Gothic.ini for an option.

func string MEM_GetGothOpt(var string sectionname, var string optionname)\n
Parameters

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":"

MEM_GetModOpt

Searches the loaded mod ini file for option.

func void MEM_GetModOpt(var string sectionname, var string optionname)\n
Parameters

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":"

MEM_GothOptSectionExists

Checks whether a section exists in Gothic.ini

func int MEM_GothOptSectionExists(var string sectionname)\n
Parameters

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":"

MEM_ModOptSectionExists

Checks whether a section exists in loaded mod ini file

func int MEM_ModOptSectionExists(var string sectionname)\n
Parameters

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":"

MEM_GothOptExists

Checks whether an option exists in Gothic.ini

func int MEM_GothOptExists(var string sectionname, var string optionname)\n
Parameters

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":"

MEM_ModOptExists

Checks whether an option exists in loaded mod ini file

func int MEM_ModOptExists(var string sectionname, var string optionname)\n
Parameters

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":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/ini_access/#mem_applygothopt","title":"MEM_ApplyGothOpt","text":"

MEM_ApplyGothOpt

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":"

MEM_GetKey

Returns the primary key assigned to logical key.

func int MEM_GetKey(var string name)\n
Parameters

Return value

The function returns key assigned to logical key

"},{"location":"zengin/scripts/extenders/ikarus/functions/ini_access/#mem_getsecondarykey","title":"MEM_GetSecondaryKey","text":"

MEM_GetSecondaryKey

Returns a secondary key assigned to logical key.

func int MEM_GetSecondaryKey(var string name)\n
Parameters

Return value

The function returns key assigned to logical key

"},{"location":"zengin/scripts/extenders/ikarus/functions/ini_access/#mem_setkeys","title":"MEM_SetKeys","text":"

MEM_SetKeys

Sets keyboard keys of the logical key.

func void MEM_SetKeys(var string name, var int primary, var int secondary)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/ini_access/#mem_setkey","title":"MEM_SetKey","text":"

MEM_SetKey

Sets the primary keyboard key of the logical key.

func void MEM_SetKey(var string name, var int key)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/ini_access/#mem_setsecondarykey","title":"MEM_SetSecondaryKey","text":"

MEM_SetSecondaryKey

Sets the secondary keyboard key of the logical key.

func void MEM_SetSecondaryKey(var string name, var int key)\n
Parameters "},{"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":"

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":""},{"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":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/jumps_loops/#mem_goto","title":"MEM_Goto","text":"

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)\n
Parameters "},{"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 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

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":"

MEM_KeyPressed

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

func int MEM_KeyPressed(var int key)\n
Parameters

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":"

MEM_KeyState

Returns the state of the key.

func int MEM_KeyState(var int key)\n
Parameters

Return value

The function returns actual key state.

Key states

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":"

MEM_InsertKeyEvent

Makes the game think that the key was pressed.

func void MEM_InsertKeyEvent(var int key)\n
Parameters "},{"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":"

MEM_ReadInt

Reads int from the address.

func int MEM_ReadInt(var int address)\n
Parameters

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":"

MEM_ReadString

Reads string from the address.

func string MEM_ReadString(var int address)\n
Parameters

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":"

MEM_ReadByte

Reads byte from the address.

func int MEM_ReadByte(var int address)\n
Parameters

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":"

MEM_ReadIntArray

Reads int from the array at the arrayAddress.

func int MEM_ReadIntArray(var int arrayAddress, var int offset)\n
Parameters

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":"

MEM_ReadByteArray

Reads byte from the array at the arrayAddress.

func int MEM_ReadByteArray(var int arrayAddress, var int offset)\n
Parameters

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":"

MEM_WriteInt

Writes int value in the address.

func void MEM_WriteInt(var int address, var int value)\n
Parameters 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":"

MEM_WriteString

Writes string in the address.

func void MEM_WriteString(var int address, var string value)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/mem_access/#mem_writebyte","title":"MEM_WriteByte","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/mem_access/#mem_writeintarray","title":"MEM_WriteIntArray","text":"

MEM_WriteIntArray

Writes int value in the array at arrayAddress.

func void MEM_WriteIntArray(var int arrayAddress, var int offset, var int value)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/mem_access/#mem_writestringarray","title":"MEM_WriteStringArray","text":"

MEM_WriteStringArray

Writes string value in the array at arrayAddress.

func void MEM_WriteStringArray(var int arrayAddress, var int offset, var string value)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/mem_access/#mem_writebytearray","title":"MEM_WriteByteArray","text":"

MEM_WriteByteArray

Writes byte value in the array at arrayAddress.

func void MEM_WriteByteArray(var int arrayAddress, var int offset, var int value)\n
Parameters "},{"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":"

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 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

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":"

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)\n
Parameters

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":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/mem_utility/#mem_copy","title":"MEM_Copy","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/mem_utility/#mem_copywords","title":"MEM_CopyWords","text":"

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) \n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/mem_utility/#mem_copybytes","title":"MEM_CopyBytes","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/mem_utility/#mem_swap","title":"MEM_Swap","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/mem_utility/#mem_swapwords","title":"MEM_SwapWords","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/mem_utility/#mem_swapbytes","title":"MEM_SwapBytes","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/mem_utility/#mem_clear","title":"MEM_Clear","text":"

MEM_Clear

Sets a specified number of bytes in memory to zero.

func void MEM_Clear(var int ptr, var int size)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/mem_utility/#mem_compare","title":"MEM_Compare","text":"

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)\n
Parameters

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":"

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)\n
Parameters

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":"

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)\n
Parameters

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":"

MEM_GetMenuByString

func int MEM_GetMenuByString(var string menuName)\n

Parameters

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":"

MEM_GetMenuItemByString

func int MEM_GetMenuItemByString(var string menuItemName)\n

Parameters

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":"Ikarus `zCObject` manipulation functions","text":""},{"location":"zengin/scripts/extenders/ikarus/functions/objects/#ikarus-zcobject-manipulation-functions","title":"Ikarus zCObject manipulation functions","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":"

MEM_InitGlobalInst

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":"

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)\n
Parameters

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":"

MEM_GetClassName

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

func string MEM_GetClassName(var int objPtr)\n
Parameters

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":"

MEM_CheckInheritance

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

func int MEM_CheckInheritance(var int objPtr, var int classDef)\n
Parameters

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":"

Hlp_Is_*

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":"

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)\n
Parameters

Return value

The function returns a pointer to the created object.

"},{"location":"zengin/scripts/extenders/ikarus/functions/objects/#mem_deletevob","title":"MEM_DeleteVob","text":"

MEM_DeleteVob

Deletes a specific Vob form world.

func void MEM_DeleteVob(var int vobPtr)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/objects/#mem_renamevob","title":"MEM_RenameVob","text":"

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)\n
Parameters MEM_TriggerVobMEM_UntriggerVob"},{"location":"zengin/scripts/extenders/ikarus/functions/objects/#mem_triggervob","title":"MEM_TriggerVob","text":"

MEM_TriggerVob

Sends a trigger message to the Vob.

func void MEM_TriggerVob(var int vobPtr)\n
Parameters

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":"

MEM_UntriggerVob

Sends an untrigger message to the Vob.

func void MEM_TriggerVob(var int vobPtr)\n
Parameters

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":"

MEM_SearchVobByName

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

func int MEM_SearchVobByName(var string str)\n
Parameters

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":"

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)\n
Parameters

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":"

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)\n
Parameters

Return value

The function returns the calculated CRC32 hash value.

"},{"location":"zengin/scripts/extenders/ikarus/functions/objects/#mem_getstringhash","title":"MEM_GetStringHash","text":"

MEM_GetStringHash

Calculates the CRC32 hash value for a string.

func int MEM_GetStringHash(var string str)\n
Parameters

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":"

MEM_ReinitParser

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":"

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)\n
Parameters

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":"

MEM_NullToInst

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":"

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)\n
Parameters 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":"

MEM_AssignInstNull

Assigns null pointer to a given instance.

func void MEM_AssignInstNull(var int inst)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_insttoptr","title":"MEM_InstToPtr","text":"

MEM_InstToPtr

Returns a pointer to given instance.

func int MEM_InstToPtr(var int inst)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_instgetoffset","title":"MEM_InstGetOffset","text":"

MEM_InstGetOffset

Alias to MEM_InstToPtr. Returns a pointer to given instance.

func int MEM_InstGetOffset(var int inst)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_cpyinst","title":"MEM_CpyInst","text":"

MEM_CpyInst

Returns a copy of a given instance

func MEMINT_HelperClass MEM_CpyInst(var int inst)\n
Parameters 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":"

MEM_PushIntParam

Passes an integer as a parameter to the called function.

func void MEM_PushIntParam (var int param)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_pushinstparam","title":"MEM_PushInstParam","text":"

MEM_PushInstParam

Passes an instance as a parameter to the called function.

func void MEM_PushInstParam (var int inst)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_pushstringparam","title":"MEM_PushStringParam","text":"
!!! function \"`MEM_PushStringParam`\"\nPasses a string as a parameter to the called function.\n```dae\nfunc void MEM_PushStringParam (var string str)\n```\n**Parameters**\n\n- `#!dae var string str`  \n    String to pass as a function parameter\n
"},{"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":"

MEM_Call

Calls a function.

func void MEM_Call(var func fnc)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_callbyid","title":"MEM_CallByID","text":"

MEM_CallByID

Calls a function by its ID.

func void MEM_CallByID (var int symbID)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_callbyptr","title":"MEM_CallByPtr","text":"

MEM_CallByPtr

Calls a function by its pointer.

func void MEM_CallByPtr(var int ptr)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_callbyoffset","title":"MEM_CallByOffset","text":"

MEM_CallByOffset

Calls a function by its offset.

func void MEM_CallByOffset(var int offset)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_callbystring","title":"MEM_CallByString","text":"

MEM_CallByString

Calls a function by its name.

func void MEM_CallByString (var string fnc)\n
Parameters "},{"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":"

MEM_PopIntResult

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":"

MEM_PopStringResult

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":"

MEM_PopInstResult

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":"

MEM_GetFuncID

Returns the ID of the given function.

func int MEM_GetFuncID(var func fnc)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_getfuncptr","title":"MEM_GetFuncPtr","text":"

MEM_GetFuncPtr

Returns the pointer of the given function.

func int MEM_GetFuncPtr(var func fnc)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_getfuncoffset","title":"MEM_GetFuncOffset","text":"

MEM_GetFuncOffset

Returns the offset of the given function.

func int MEM_GetFuncOffset(var func fnc)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_getfuncidbyoffset","title":"MEM_GetFuncIDByOffset","text":"

MEM_GetFuncIDByOffset

MEM_GetFuncID, but with an offset as a parameter.

func int MEM_GetFuncIDByOffset(var int offset)\n
Parameters

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":"

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)\n
Parameters "},{"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":"

MEM_GetFrameBoundary

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":"

MEM_GetCallerStackPos

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":"

MEM_SetCallerStackPos

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

func void MEM_SetCallerStackPos(var int popPos)\n
Parameters "},{"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":"

MEM_GetAddress_Init

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":"

MEM_GetIntAddress

Returns an address of a given integer.

func int MEM_GetIntAddress(var int i)\n
Parameters

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":"

MEM_GetFloatAddress

Returns an address of a given daedalus float.

func int MEM_GetFloatAddress(var float f)\n
Parameters

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":"

MEM_GetStringAddress

Returns an address of a given string.

func int MEM_GetStringAddress(var string s)\n
Parameters

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":"

STR_GetAddressInit

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":"

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)\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":"

MEM_InitStatArrs

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":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_readstatarr","title":"MEM_ReadStatArr","text":"

MEM_ReadStatArr

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

func int MEM_ReadStatArr (var int array, var int offset)\n
Parameters

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":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_readstatstringarr","title":"MEM_ReadStatStringArr","text":"

MEM_ReadStatStringArr

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

func string MEM_ReadStatStringArr(var string array, var int offset)\n
Parameters

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":"

MEM_SetCurrParserSymb

Makes currParserSymb point to the symbol of the specified instance.

func void MEM_SetCurrParserSymb (var int inst)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#currparsersymb","title":"currParserSymb","text":"

currParserSymb

An instance representing current parser symbol.

INSTANCE currParserSymb (zCPar_Symbol);\n
"},{"location":"zengin/scripts/extenders/ikarus/functions/parser/#mem_findparsersymbol","title":"MEM_FindParserSymbol","text":"

MEM_FindParserSymbol

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

func int MEM_FindParserSymbol(var string inst)\n
Parameters

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":"

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)\n
Parameters

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":"

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)\n
Parameters

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":"

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)\n
Parameters

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_GetSymbolByIndex

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

func int MEM_GetSymbolByIndex(var int id)\n
Parameters

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":"

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)\n
Parameters

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":"

STR_Len

Returns the length of a string.

func int STR_Len (var string str)\n
Parameters

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":"

STR_toChar

Converts a string to a pointer to its character array.

func int STR_toChar (var string str)\n
Parameters

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":"

STR_FromChar

Converts a character array to a string.

func string STR_FromChar(var int char)\n
Parameters

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":"

STR_SubStr

Extracts a substring from a given string.

func string STR_SubStr (var string str, var int start, var int count)\n
Parameters

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":"

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)\n
Parameters

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":"

STR_Compare

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

func int STR_Compare(var string str1, var string str2)\n
Parameters

Return Value

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

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":"

STR_ToInt

Converts a string to an integer.

func int STR_ToInt (var string str)\n
Parameters

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":"

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)\n
Parameters

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":"

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)\n
Parameters

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":"

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)\n

Parameters

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":"

STR_Upper

Converts a string to uppercase.

func string STR_Upper(var string str)\n
Parameters

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":"

STR_Lower

Converts a string to lowercase.

func string STR_Lower(var string str)\n
Parameters

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":"

MEM_GetSystemTime

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":"

MEM_GetPerformanceCounter

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":"

MEM_BenchmarkMS

Benchmark of the execution time for a specified function. (Milliseconds)

func int MEM_BenchmarkMS(var func f)\n
Parameters

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":"

MEM_BenchmarkMMS

Benchmark of the execution time for a specified function. (microseconds)

func int MEM_BenchmarkMMS(var func f)\n
Parameters

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":"

MEM_BenchmarkPC

Benchmark of the execution time for a specified function, using the Performancecounter.

func int MEM_BenchmarkMS(var func f)\n
Parameters

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_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)\n
Parameters

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_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)\n
Parameters

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_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)\n
Parameters

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":"

LoadLibrary

Loads the specified module into the address space of the calling process. Full documentation here.

func int LoadLibrary(var string lpFileName)\n
Parameters

Return value

The function returns a handle to the module.

"},{"location":"zengin/scripts/extenders/ikarus/functions/win_utilities/#getprocaddress","title":"GetProcAddress","text":"

GetProcAddress

Retrieves the address from the specified dynamic-link library. Full documentation here.

func int GetProcAddress(var int hModule, var string lpProcName)\n
Parameters

Return value The function returns address of the function or variable.

"},{"location":"zengin/scripts/extenders/ikarus/functions/win_utilities/#findkerneldllfunction","title":"FindKernelDllFunction","text":"

FindKernelDllFunction

Uses GetProcAddress to find function inside the KERNEL32.DLL file.

func int FindKernelDllFunction(var string name)\n
Parameters

Return value

The function returns address of the function.

"},{"location":"zengin/scripts/extenders/ikarus/functions/win_utilities/#virtualprotect","title":"VirtualProtect","text":"

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)\n
Parameters

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":"

MemoryProtectionOverride

Alias to VirtualProtect but with predefined PAGE_EXECUTE_READWRITE protection option

func void MemoryProtectionOverride(var int address, var int size)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/win_utilities/#mem_messagebox","title":"MEM_MessageBox","text":"

MEM_MessageBox

Calls the WinAPI MessageBox function.

func int MEM_MessageBox(var string txt, var string caption, var int type)\n
Parameters "},{"location":"zengin/scripts/extenders/ikarus/functions/win_utilities/#mem_infobox","title":"MEM_InfoBox","text":"

MEM_InfoBox

Alias to MEM_MessageBox with \"Information:\" header and MB_OK | MB_ICONINFORMATION type.

func void MEM_InfoBox(var string txt)\n
Parameters "},{"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/setup/","title":"LeGo Setup","text":""},{"location":"zengin/scripts/extenders/lego/setup/#lego-setup","title":"LeGo Setup","text":"

Danger

LeGo depends on Ikarus script packet, if you didn't install it yet check the Ikarus Setup. This guide assumes that you already have Ikarus running.

"},{"location":"zengin/scripts/extenders/lego/setup/#download","title":"Download","text":"

First you need to download LeGo from the official github repository. We recommend using the dev branch as it contains the latest and most up-to-date version of the package. However, you can also download a specific release if needed.

"},{"location":"zengin/scripts/extenders/lego/setup/#file-location","title":"File location","text":"

If you followed the Ikarus Setup guide you probably have a \"MOD\" (or any other named) folder inside the <Gothic-dir>\\_work\\Data\\Scripts\\Content directory. If not create it.

Unpack the downloaded files into this folder. The archiver should create a folder named LeGo-dev or LeGo-X.X.X. For better readability change its name to just LeGo.

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/lego/setup/#parsing","title":"Parsing","text":"

LeGo has a special header files, one for each supported engine version. All you need to do is to include them in Gothic.src right after the Ikarus files.

Gothic.src (G1)Gothic.src (G2)
_INTERN\\CONSTANTS.D\n_INTERN\\CLASSES.D\nMOD\\IKARUS\\IKARUS_G1.SRC\nMOD\\LEGO\\HEADER_G1.SRC\n
_INTERN\\CONSTANTS.D\n_INTERN\\CLASSES.D\nMOD\\IKARUS\\IKARUS_G2.SRC\nMOD\\LEGO\\HEADER_G2.SRC\n
"},{"location":"zengin/scripts/extenders/lego/setup/#initialization","title":"Initialization","text":"

Before you can use LeGo and its packages, it must be properly initialized.

Warning

Gothic 1 by default doesn't have its own INIT_GLOBAL function inside Startup.d file. If you haven't created it yet see how to do it here.

You initialize LeGo by calling the LeGo_Init(var int flags) function and specifying the flags.

Init AllExclude packagesInit specific packages

With LeGo_All flag you initialize all packages, excluding experimental Buffs and Render.

Startup.d
FUNC VOID INIT_GLOBAL()\n{\n    // Init Ikarus\n    MEM_InitAll ();\n    // Init LeGo\n    LeGo_Init(LeGo_All)\n};\n

By the bitwise NOT operator you can exclude specific packages from LeGo_All flag.

Startup.d
FUNC VOID INIT_GLOBAL()\n{\n    // Init Ikarus\n    MEM_InitAll ();\n    // Init LeGo\n    LeGo_Init(LeGo_All &~ (LeGo_Focusnames | LeGo_Bloodsplats));\n};\n

You could also init specific packages with bitwise OR.

Startup.d
FUNC VOID INIT_GLOBAL()\n{\n    // Init Ikarus\n    MEM_InitAll ();\n    // Init LeGo\n    LeGo_Init(LeGo_AI_Function | LeGo_Saves);\n};\n
"},{"location":"zengin/scripts/extenders/lego/userconstants/","title":"User constants","text":""},{"location":"zengin/scripts/extenders/lego/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/userconstants/#read-only","title":"Read only","text":"

These constants may only be used, not changed.

"},{"location":"zengin/scripts/extenders/lego/userconstants/#anim8","title":"Anim8","text":"

These constants are used by Anim8 and Anim8q.

"},{"location":"zengin/scripts/extenders/lego/userconstants/#buttons","title":"Buttons","text":"

The following bit masks can be applied to the status of a button:

"},{"location":"zengin/scripts/extenders/lego/userconstants/#interface","title":"Interface","text":"

Dimensions

Colors

16 basic colors that can be used as zColor parameters

"},{"location":"zengin/scripts/extenders/lego/userconstants/#gamestate","title":"Gamestate","text":"

Gamestate can assume these values:

"},{"location":"zengin/scripts/extenders/lego/userconstants/#cursor","title":"Cursor","text":"

These constants are sent with Cursor_Event:

"},{"location":"zengin/scripts/extenders/lego/userconstants/#modifiable","title":"Modifiable","text":"

These constants are often used by packages and may be changed freely.

"},{"location":"zengin/scripts/extenders/lego/userconstants/#bloodsplats","title":"Bloodsplats","text":""},{"location":"zengin/scripts/extenders/lego/userconstants/#cursor_1","title":"Cursor","text":""},{"location":"zengin/scripts/extenders/lego/userconstants/#interface_1","title":"Interface","text":""},{"location":"zengin/scripts/extenders/lego/userconstants/#prints","title":"PrintS","text":"

All position and size information is completely virtual:

The times are given in ms:

The font can be modified:

"},{"location":"zengin/scripts/extenders/lego/userconstants/#talents","title":"Talents","text":""},{"location":"zengin/scripts/extenders/lego/userconstants/#dialoggestures","title":"Dialoggestures","text":""},{"location":"zengin/scripts/extenders/lego/applications/anim8/","title":"Anim8","text":""},{"location":"zengin/scripts/extenders/lego/applications/anim8/#anim8","title":"Anim8","text":"

Info

Dependencies: - Floats Implementation: Anim8.d on GitHub

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/#initialization","title":"Initialization","text":"

Initialize with LeGo_Anim8 flag.

LeGo_Init(LeGo_Anim8);\n
"},{"location":"zengin/scripts/extenders/lego/applications/anim8/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/applications/anim8/#anim8_new","title":"Anim8_New","text":"

Anim8_New

Creates a new Anim8 object that can be filled with commands.

func int Anim8_New(var int initialValue, var int IsFloat)\n
Parameters

Return value

The function returns handle of the Anim8 object.

"},{"location":"zengin/scripts/extenders/lego/applications/anim8/#anim8_newext","title":"Anim8_NewExt","text":"

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)\n
Parameters

Return value

The function returns handle of the Anim8 object.

"},{"location":"zengin/scripts/extenders/lego/applications/anim8/#anim8_delete","title":"Anim8_Delete","text":"

Anim8_Delete

Deletes an Anim8 object created with Anim8_New.

func void Anim8_Delete(var int handle)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/anim8/#anim8_get","title":"Anim8_Get","text":"

Anim8_Get

Get current value of the object.

func int Anim8_Get(var int handle)\n
Parameters

Return value

The function returns value of the object.

"},{"location":"zengin/scripts/extenders/lego/applications/anim8/#anim8_set","title":"Anim8_Set","text":"

Anim8_Set

Sets the value of the object.

func void Anim8_Set(var int handle, var int value)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/anim8/#anim8_empty","title":"Anim8_Empty","text":"

Anim8_Empty

Indicates whether the object is empty, i.e. has no more commands to process.

func int Anim8_Empty(var int handle)\n
Parameters

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":"

Anim8_RemoveIfEmpty

If desired, Anim8 can automatically delete an object after it is empty.

func void Anim8_RemoveIfEmpty(var int handle, var int on)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/anim8/#anim8_removedataifempty","title":"Anim8_RemoveDataIfEmpty","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/anim8/#anim8_1","title":"Anim8","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/anim8/#anim8q","title":"Anim8q","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/anim8/#anim8_callonremove","title":"Anim8_CallOnRemove","text":"

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)\n
Parameters "},{"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":"

Info

Dependencies: - PermMem - View Implementation: Bars.d on GitHub

This package makes it very easy to add new bars, for e.g. stamina.

"},{"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/#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":"

Bar_Create

Creates a new bar from a constructor instance.

func int Bar_Create(var int inst)\n

Parameters

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":"

Bar_Delete

Deletes a bar from the screen and from memory.

func void Bar_Delete(var int bar)\n

Parameters

"},{"location":"zengin/scripts/extenders/lego/applications/bars/#bar_setmax","title":"Bar_SetMax","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/bars/#bar_setvalue","title":"Bar_SetValue","text":"

Bar_SetValue

Sets the value of the bar.

func void Bar_SetValue(var int bar, var int val)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/bars/#bar_setpercent","title":"Bar_SetPercent","text":"

Bar_SetPercent

Sets the value of the bar but as a percentage (0..100).

func void Bar_SetPercent(var int bar, var int perc)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/bars/#bar_setpromille","title":"Bar_SetPromille","text":"

Bar_SetPromille

Sets the value of the bar but per mille (0..1000).

func void Bar_SetPromille(var int bar, var int pro)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/bars/#bar_hide","title":"Bar_Hide","text":"

Bar_Hide

Hides a bar. It will not be deleted.

func void Bar_Hide(var int bar)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/bars/#bar_show","title":"Bar_Show","text":"

Bar_Show

Displays a bar again after using Bar_Hide.

func void Bar_Show(var int bar)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/bars/#bar_moveto","title":"Bar_MoveTo","text":"

Bar_MoveTo

Move the bar to virtual position.

func void Bar_MoveTo(var int bar, var int x, var int y)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/bars/#bar_movetopxl","title":"Bar_MoveToPxl","text":"

Bar_MoveToPxl

Move the bar to pixel position.

func void Bar_MoveToPxl(var int bar, var int x, var int y)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/bars/#bar_setalpha","title":"Bar_SetAlpha","text":"

Bar_SetAlpha

Sets the transparency of the bar.

func void Bar_SetAlpha(var int bar, var int alpha)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/bars/#bar_setbartexture","title":"Bar_SetBarTexture","text":"

Bar_SetBarTexture

Sets the foreground texture of the bar.

func void Bar_SetBarTexture(var int bar, var string barTex)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/bars/#bar_setbacktexture","title":"Bar_SetBackTexture","text":"

Bar_SetBackTexture

Sets the background texture of the bar.

func void Bar_SetBackTexture(var int bar, var string backTex)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/bars/#bar_resize","title":"Bar_Resize","text":"

Bar_Resize

Resize an existing bar.

func void Bar_Resize(var int bar, var int width, var int height)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/bars/#bar_resizepxl","title":"Bar_ResizePxl","text":"

Bar_ResizePxl

Resize existing bar (in pixels).

func void Bar_ResizePxl(var int bar, var int x, var int y)\n
Parameters "},{"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":"

Info

Dependencies: - Floats - View - Random - Anim8 Implementation: Bloodsplats.d on GitHub

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/#initialization","title":"Initialization","text":"

Initialize with LeGo_Bloodsplats flag.

LeGo_Init(LeGo_Bloodsplats);\n
"},{"location":"zengin/scripts/extenders/lego/applications/bloodsplats/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/applications/bloodsplats/#bloodsplat","title":"Bloodsplat","text":"

Bloodsplat

Puts a blood splatter on the screen.

func void Bloodsplat(var int damage)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/bloodsplats/#bloodsplats_rage","title":"Bloodsplats_Rage","text":"

Bloodsplats_Rage

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":"

Npc_GetPercFunc

oCNpc::GetPerceptionFunc engine function wrapper

func int Npc_GetPercFunc(var C_Npc npc, var int type)\n
Parameters

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":"

Info

Dependencies: - PermMem - FrameFunctions Implementation: Buffs.d on GitHub

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/#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/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/applications/buffs/#buff_apply","title":"Buff_Apply","text":"

Buff_Apply

Applies a status effect to an NPC.

func int Buff_Apply(var C_NPC npc, var int buff)\n
Parameters

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_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)\n
Parameters

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_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)\n
Parameters

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":"

Buff_Refresh

Resets the duration of the buff.

func void Buff_Refresh(var int buffHandle)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/buffs/#buff_remove","title":"Buff_Remove","text":"

Buff_Remove

Removes the buff from the all NPCs.

func void Buff_Remove(var int buffHandle)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/buffs/#buff_removeall","title":"Buff_RemoveAll","text":"

Buff_RemoveAll

Removes the buffs form the NPC.

func void Buff_RemoveAll(var C_NPC npc, var int buffInstance)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/buffs/#buff_getnpc","title":"Buff_GetNpc","text":"

Buff_GetNpc

Returns a pointer to the NPC, which is affected by the buff.

func int Buff_GetNpc(var int buffHandle)\n
Parameters

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":"

Buff_Has

Checks if the NPC already has an effect applied.

func int Buff_Has(var C_NPC npc, var int buff)\n
Parameters

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":"

SAVE_GetFuncID

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":"

Info

Dependencies: - PermMem - View Implementation: Buffs.d on GitHub

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/#initialization","title":"Initialization","text":"

Initialize with LeGo_Buttons flag.

LeGo_Init(LeGo_Buttons);\n
"},{"location":"zengin/scripts/extenders/lego/applications/buttons/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/applications/buttons/#button_create","title":"Button_Create","text":"

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)\n
Parameters

Return value

The function returns a handle to created button.

"},{"location":"zengin/scripts/extenders/lego/applications/buttons/#button_createpxl","title":"Button_CreatePxl","text":"

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)\n
Parameters

Return value

The function returns a handle to created button.

"},{"location":"zengin/scripts/extenders/lego/applications/buttons/#button_delete","title":"Button_Delete","text":"

Button_Delete

Completely deletes a button.

func void Button_Delete(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/buttons/#button_show","title":"Button_Show","text":"

Button_Show

Shows the button and makes it respond to the mouse.

func void Button_Show(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/buttons/#button_hide","title":"Button_Hide","text":"

Button_Hide

Hides the button and disables it, so it is no longer responding to the mouse.

func void Button_Hide(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/buttons/#button_settexture","title":"Button_SetTexture","text":"

Button_SetTexture

Sets the texture of the button.

func void Button_SetTexture(var int hndl, var string tex)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/buttons/#button_setcaption","title":"Button_SetCaption","text":"

Button_SetCaption

Displays a centered text on the button.

func void Button_SetCaption(var int hndl, var string caption, var string font)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/buttons/#button_createmouseover","title":"Button_CreateMouseover","text":"

Button_CreateMouseover

Attaches a mouseover box to the cursor.

func void Button_CreateMouseover(var string text, var string font)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/buttons/#button_deletemouseover","title":"Button_DeleteMouseover","text":"

Button_DeleteMouseover

Deletes the mouseover box.

func void Button_DeleteMouseover()\n
"},{"location":"zengin/scripts/extenders/lego/applications/buttons/#button_activate","title":"Button_Activate","text":"

Button_Activate

Activates the button, so it reacts to the mouse. Does not change the visibility.

func void Button_Activate(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/buttons/#button_deactivate","title":"Button_Deactivate","text":"

Button_Deactivate

Disables the button, so it no longer reacts to the mouse.

func void Button_Deactivate(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/buttons/#button_setuserdata","title":"Button_SetUserData","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/buttons/#button_getuserdata","title":"Button_GetUserData","text":"

Button_GetUserData

Gets the user data of the button.

func int Button_GetUserData(var int hndl)\n
Parameters

Return value

The function returns the user data of the button.

"},{"location":"zengin/scripts/extenders/lego/applications/buttons/#button_getstate","title":"Button_GetState","text":"

Button_GetState

Gets the status of the button as a bit field. See User Constants.

func int Button_GetState(var int hndl)\n
Parameters

Return value

The function returns the status of the button.

"},{"location":"zengin/scripts/extenders/lego/applications/buttons/#button_move","title":"Button_Move","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/buttons/#button_movevrt","title":"Button_MoveVrt","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/buttons/#button_moveto","title":"Button_MoveTo","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/buttons/#button_movetovrt","title":"Button_MoveToVrt","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/buttons/#button_getviewhandle","title":"Button_GetViewHandle","text":"

Button_GetViewHandle

Returns the button's zCView as a handle.

func int Button_GetViewHandle(var int hndl)\n
Parameters

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":"

Button_GetViewPtr

Returns the button's zCView as a pointer.

func int Button_GetViewPtr(var int hndl)\n
Parameters

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":"

Button_GetView

Returns the button's zCView as an object.

func zCView Button_GetView(var int hndl)\n
Parameters

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":"

Button_GetCaptionPtr

Returns the pointer to the text of the button.

func int Button_GetCaptionPtr(var int hndl)\n
Parameters

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":"

Info

Dependencies: - PermMem - HookEngine Implementation: ConsoleCommands.d on GitHub

This package allows you to create new console commands.

"},{"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/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/applications/console_commands/#cc_register","title":"CC_Register","text":"

CC_Register

Registers a new console command.

func void CC_Register(var func f, var string cmdPrefix, var string description)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/console_commands/#cc_remove","title":"CC_Remove","text":"

CC_Remove

Removes a function from the console commands.

func void CC_Remove(var func f)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/console_commands/#cc_active","title":"CC_Active","text":"

CC_Active

Checks whether the function passed is already part of a console command.

func int CC_Active(var func f)\n
Parameters

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":"

Info

Dependencies: - Floats - FrameFunctions - View Implementation: Cursor.d on GitHub

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/#initialization","title":"Initialization","text":"

Initialize with LeGo_Cursor flag.

LeGo_Init(LeGo_Cursor);\n
"},{"location":"zengin/scripts/extenders/lego/applications/cursor/#variables","title":"Variables","text":""},{"location":"zengin/scripts/extenders/lego/applications/cursor/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/applications/cursor/#cursor_hide","title":"Cursor_Hide","text":"

Cursor_Hide

Hides the displayed mouse cursor.

func void Cursor_Hide()\n
"},{"location":"zengin/scripts/extenders/lego/applications/cursor/#cursor_show","title":"Cursor_Show","text":"

Cursor_Show

Shows the mouse cursor.

func void Cursor_Show()\n
"},{"location":"zengin/scripts/extenders/lego/applications/cursor/#setmouseenabled","title":"SetMouseEnabled","text":"

SetMouseEnabled

Can manually enable or disable the mouse.

func void SetMouseEnabled(var int enabled)\n
Parameters "},{"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":"

Info

Dependencies: - AI_Function Implementation: Dialoggestures.d on GitHub

This package can modify the NPCs' gestures during dialogue to better bring out emotions.

"},{"location":"zengin/scripts/extenders/lego/applications/dialoggestures/#initialization","title":"Initialization","text":"

N/A

"},{"location":"zengin/scripts/extenders/lego/applications/dialoggestures/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/applications/dialoggestures/#diag","title":"DIAG","text":"

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\");\n
DIAG_Prefix and DIAG_Suffix are user constants.

func void DIAG(var string AniName, var int Min, var int Max)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/dialoggestures/#diag_reset","title":"DIAG_Reset","text":"

DIAG_Reset

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":"

DIAG_SetAni

Sets animation directly.

func void DIAG_SetAni(var string AniName)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/dialoggestures/#diag_setminmax","title":"DIAG_SetMinMax","text":"

DIAG_SetMinMax

Sets animation numbers directly.

func void DIAG_SetMinMax(var int min, var int max)\n
Parameters "},{"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":"

Info

Dependencies: - Interface - HookEngine Implementation: Focusnames.d on GitHub

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/#initialization","title":"Initialization","text":"

Initialize with LeGo_Focusnames flag.

LeGo_Init(LeGo_Focusnames);\n
"},{"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":"

Focusnames_Color_Friendly

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":"

Focusnames_Color_Neutral

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":"

Focusnames_Color_Angry

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":"

Focusnames_Color_Hostile

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":"

Info

Dependencies: - EventHandler - Saves Implementation: Gamestate.d on GitHub

Gamestate package allows to check for different game states (game start, game load or level change).

"},{"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/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/applications/gamestate/#gamestate_addlistener","title":"Gamestate_AddListener","text":"

Gamestate_AddListener

Adds a listener/handler to the game-state event.

func void Gamestate_AddListener(var func listener)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/gamestate/#gamestate_removelistener","title":"Gamestate_RemoveListener","text":"

Gamestate_RemoveListener

Removes game-state listener.

func void Gamestate_RemoveListener(var func listener)\n
Parameters "},{"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":"

Info

Dependencies: - Talents Implementation: Names.d on GitHub

Allows the user to change NPC name e.g. after he shows up.

"},{"location":"zengin/scripts/extenders/lego/applications/names/#initialization","title":"Initialization","text":"

N/A

"},{"location":"zengin/scripts/extenders/lego/applications/names/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/applications/names/#setname","title":"SetName","text":"

SetName

Should be set in InitGlobal().

func void SetName(var C_NPC npc, var string name)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/names/#showname","title":"ShowName","text":"

ShowName

Permanently displays the name set by SetName function above the npc.

func void ShowName(var C_NPC npc)\n
Parameters "},{"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":"

Info

Dependencies: - List - View - PermMem Implementation: Render.d on GitHub

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/#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/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/applications/render/#render_additemprio","title":"Render_AddItemPrio","text":"

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)\n
Parameters

Return value

The function returns a handle of the render object.

"},{"location":"zengin/scripts/extenders/lego/applications/render/#render_additem","title":"Render_AddItem","text":"

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)\n
Parameters

Return value

The function returns a handle of the render object.

"},{"location":"zengin/scripts/extenders/lego/applications/render/#render_addviewprio","title":"Render_AddViewPrio","text":"

Render_AddViewPrio

Generates the render of a View, with a manually specified priority.

func int Render_AddViewPrio(var int view, var int priority)\n
Parameters

Return value

The function returns a handle of the render object.

"},{"location":"zengin/scripts/extenders/lego/applications/render/#render_addview","title":"Render_AddView","text":"

Render_AddView

Generates the render of a View, with priority set to 0.

func int Render_AddView(var int view)\n
Parameters

Return value

The function returns a handle of the render object.

"},{"location":"zengin/scripts/extenders/lego/applications/render/#render_openview","title":"Render_OpenView","text":"

Render_OpenView

Opens a render object. Only open render objects are displayed.

func void Render_OpenView(var int handle)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/render/#render_closeview","title":"Render_CloseView","text":"

Render_CloseView

Closes a render object. Only open render objects are displayed.

func void Render_CloseView(var int handle)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/render/#render_remove","title":"Render_Remove","text":"

Render_Remove

Deletes a render object. The associated view is deleted automatically.

func void Render_Remove(var int handle)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/saves/","title":"Saves","text":""},{"location":"zengin/scripts/extenders/lego/applications/saves/#saves","title":"Saves","text":"

Info

Dependencies: - BinaryMachines Implementation: Saves.d on GitHub

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/#initialization","title":"Initialization","text":"

Initialize with LeGo_Saves flag.

LeGo_Init(LeGo_Saves);\n
"},{"location":"zengin/scripts/extenders/lego/applications/saves/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/applications/saves/#bw_savegame","title":"BW_Savegame","text":"

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()\n
"},{"location":"zengin/scripts/extenders/lego/applications/saves/#br_savegame","title":"BR_Savegame","text":"

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()\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":"

Info

Dependencies: - AI_Function Implementation: Trialoge.d on GitHub

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/#initialization","title":"Initialization","text":"

Initialize with LeGo_Trialoge flag.

LeGo_Init(LeGo_Trialoge);\n
"},{"location":"zengin/scripts/extenders/lego/applications/trialoge/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/applications/trialoge/#equipweapon","title":"EquipWeapon","text":"

EquipWeapon

Sektenspinner's function. Makes NPC equip a weapon.

func void EquipWeapon(var C_NPC slf, var int ItemInstance)\n
Parameters

Configuration

const int EquipWeapon_TogglesEquip = 1

Above constant configures the behaviour of the function when trying to equip an already equipped weapon:

"},{"location":"zengin/scripts/extenders/lego/applications/trialoge/#npc_getarmor","title":"Npc_GetArmor","text":"

Npc_GetArmor

Returns NPC's equipped armor.

func int Npc_GetArmor(var C_NPC slf)\n
Parameters

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":"

Npc_GetMeleeWeapon

Returns NPC's equipped melee weapon.

func int Npc_GetMeleeWeapon(var C_NPC slf)\n
Parameters

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":"

Npc_GetRangedWeapon

Returns NPC's equipped ranged weapon.

func int Npc_GetRangedWeapon(var c_npc slf)\n
Parameters

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":"

Npc_TradeItem

Swaps NPCs equipped weapon.

func void Npc_TradeItem(var c_npc slf, var int itm0, var int itm1) \n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/trialoge/#diacam_update","title":"DiaCAM_Update","text":"

DiaCAM_Update

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":"

DiaCAM_Disable

Completely disable the dialogue cameras.

func void DiaCAM_Disable()\n
"},{"location":"zengin/scripts/extenders/lego/applications/trialoge/#diacam_enable","title":"DiaCAM_Enable","text":"

DiaCAM_Enable

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":"

TRIA_Wait

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":"

TRIA_Invite

Invites an NPC into a conversation. Must be called before TRIA_Start.

func void TRIA_Invite(var C_NPC slf)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/trialoge/#tria_start","title":"TRIA_Start","text":"

TRIA_Start

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":"

TRIA_Barrier

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":"

TRIA_Next

Sets the called npc to self.

func void TRIA_Next(var C_NPC n0)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/trialoge/#tria_cam","title":"TRIA_Cam","text":"

TRIA_Cam

Starts a tracking shot.

func void TRIA_Cam(var string evt)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/applications/trialoge/#tria_finish","title":"TRIA_Finish","text":"

TRIA_Finish

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":"

Info

Dependencies: - HookEngine Implementation: AI_Function.d on GitHub

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/#initialization","title":"Initialization","text":"

Initialize with LeGo_AI_Function flag.

LeGo_Init(LeGo_AI_Function);\n
"},{"location":"zengin/scripts/extenders/lego/tools/ai_function/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/tools/ai_function/#ai_function_1","title":"AI_Function","text":"

AI_Function

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

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":"

Info

Dependencies: - None Implementation: BinaryMachines.d on GitHub

This package allows you to create and write your own files anywhere in the file system.

"},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#initialization","title":"Initialization","text":"

N/A

"},{"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":"

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)\n
Parameters

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":"

BW_Close

Closes the current write stream.

func void BW_Close()\n
"},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#bw","title":"BW","text":"

BW

Writes length bytes from the data to the stream, maximum 4 bytes.

func void BW(var int data, var int length)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#bw_int","title":"BW_Int","text":"

BW_Int

Writes 4 bytes from the data to the stream. Same as BW(data, 4).

func void BW_Int(var int data)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#bw_char","title":"BW_Char","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#bw_string","title":"BW_String","text":"

BW_String

Writes the data terminated with \\0 to the stream.

func void BW_String(var string data)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#bw_byte","title":"BW_Byte","text":"

BW_Byte

Writes a byte from the data to the stream. Same as BW(data, 1).

func void BW_Byte(var int data)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#bw_bytes","title":"BW_Bytes","text":"

BW_Bytes

Writes length of bytes from the pointer dataPtr to the stream.

func void BW_Bytes(var int dataPtr, var int length)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#bw_text","title":"BW_Text","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#bw_nextline","title":"BW_NextLine","text":"

BW_NextLine

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":"

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)\n
Parameters

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":"

BR_Close

Closes the current read stream.

func void BR_Close()\n
"},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#br","title":"BR","text":"

BR

Reads bytes from the stream.

func int BR(var int length)\n
Parameters

Return value

The function returns the value of read bytes.

"},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#br_int","title":"BR_Int","text":"

BR_Int

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":"

BR_Char

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":"

BR_String

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":"

BR_Byte

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":"

BR_Bytes

Reads bytes from the stream.

func int BR_Bytes(var int length)\n
Parameters

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":"

BR_TextLine

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":"

BR_Text

Reads a string of the given length from a stream.

func string BR_Text(var int length)\n
Parameters

Return value

The function returns the read string.

"},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#br_nextline","title":"BR_NextLine","text":"

BR_NextLine

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":"

WIN_GetLastError

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":"

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)\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":"

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)\n
Parameters

Full description of parameters can be found here

"},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#win_readfile","title":"WIN_ReadFile","text":"

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)\n
Parameters

Full description of parameters can be found here

"},{"location":"zengin/scripts/extenders/lego/tools/binary_machines/#win_closehandle","title":"WIN_CloseHandle","text":"

WIN_CloseHandle

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":"

WIN_GetFileSize

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/draw3d/","title":"Draw3D","text":""},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#draw3d","title":"Draw3D","text":"

Info

Dependencies: - PermMem - HookEngine Implementation: Draw3D.d on GitHub

This package allows you to draw various shapes (such as lines or bounding boxes) in three-dimensional space. This makes debugging visualizations of coordinates in the world possible.

"},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#initialization","title":"Initialization","text":"

Initialize with LeGo_Draw3D flag.

LeGo_Init(LeGo_Draw3D);\n
"},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#line","title":"Line","text":""},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#drawline","title":"DrawLine","text":"

DrawLine

Creates and draws a new line and returns its handle.

func int DrawLine(var int startPosPtr, var int endPosPtr, var int color)\n
Parameters

Return value

The function returns a new PermMem handle to the line.

"},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#drawline3","title":"DrawLine3","text":"

DrawLine3

DrawLine, but with world coordinates as parameters, instead of zVEC3 pointers.

func int DrawLine3(var int x1, var int y1, var int z1,var int x2, var int y2, var int z2,var int color)\n
Parameters

Return value

The function returns a new PermMem handle to the line.

"},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#drawlineaddr","title":"DrawLineAddr","text":"

DrawLineAddr

DrawLine, but with the address of a line as parameter.

func int DrawLineAddr(var int linePtr, var int color)\n
Parameters

Return value

The function returns a new PermMem handle to the line.

"},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#updateline","title":"UpdateLine","text":"

UpdateLine

Changes the coordinates of a specific line.

func void UpdateLine(var int hndl, var int startPosPtr, var int endPosPtr)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#updateline3","title":"UpdateLine3","text":"

UpdateLine3

UpdateLine, but with world coordinates as parameters, instead of zVEC3 pointers.

func void UpdateLine3(var int hndl,var int x1, var int y1, var int z1,var int x2, var int y2, var int z2)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#updatelineaddr","title":"UpdateLineAddr","text":"

UpdateLineAddr

UpdateLine, but with the address of a line as parameter.

func void UpdateLineAddr(var int hndl, var int linePtr)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#setlinecolor","title":"SetLineColor","text":"

SetLineColor

Changes the color of a specific line.

func void SetLineColor(var int hndl, var int color)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#eraseline","title":"EraseLine","text":"

EraseLine

Deletes a line from the world and the handle.

func void EraseLine(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#linevisible","title":"LineVisible","text":"

LineVisible

Returns whether a line is visible.

func int LineVisible(var int hndl)\n
Parameters

Return value

The function returns TRUE if the line is visible/displayed. FALSE is returned otherwise.

"},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#showline","title":"ShowLine","text":"

ShowLine

Displays the line.

func void ShowLine(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#hideline","title":"HideLine","text":"

HideLine

Hides the line.

func void HideLine(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#toggleline","title":"ToggleLine","text":"

ToggleLine

Changes the visibility of a line. If displayed - hide, if hidden - display.

func void ToggleLine(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#sphere","title":"Sphere","text":""},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#drawsphere","title":"DrawSphere","text":"

DrawSphere

Creates and draws a new sphere (visualized as a circle) and returns its handle.

func int DrawSphere(var int centerPosPtr, var int radius, var int color)\n
Parameters

Return value

The function returns a new PermMem handle to the sphere.

"},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#drawsphere3","title":"DrawSphere3","text":"

DrawSphere3

DrawSphere, but with world coordinates as parameters, instead of zVEC3 pointers.

func int DrawSphere3(var int x1, var int y1, var int z1, var int radius, var int color)\n
Parameters

Return value

The function returns a new PermMem handle to the sphere.

"},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#drawsphereaddr","title":"DrawSphereAddr","text":"

DrawSphereAddr

DrawSphere, but with the address of a sphere as a parameter.

func int DrawSphereAddr(var int spherePtr, var int color)\n
Parameters

Return value

The function returns a new PermMem handle to the sphere.

"},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#updatesphere","title":"UpdateSphere","text":"

UpdateSphere

Changes the coordinates and/or size of an existing sphere.

func void UpdateSphere(var int hndl, var int centerPosPtr, var int radius)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#updatesphere3","title":"UpdateSphere3","text":"

UpdateSphere3

UpdateSphere, but with world coordinates as parameters, instead of zVEC3 pointers.

func void UpdateSphere3(var int hndl, var int x1, var int y1, var int z1, var int radius)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#updatesphereaddr","title":"UpdateSphereAddr","text":"

UpdateSphereAddr

UpdateSphere, but with the address of a sphere as a parameter.

func void UpdateSphereAddr(var int hndl, var int spherePtr)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#setspherecolor","title":"SetSphereColor","text":"

SetSphereColor

Changes the color of a specific sphere.

func void SetSphereColor(var int hndl, var int color)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#erasesphere","title":"EraseSphere","text":"

EraseSphere

Deletes a sphere from the world and its handle.

func void EraseSphere(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#spherevisible","title":"SphereVisible","text":"

SphereVisible

Returns whether a sphere is visible.

func int SphereVisible(var int hndl)\n
Parameters

Return value

The function returns TRUE if the sphere is visible/displayed. FALSE is returned otherwise.

"},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#showsphere","title":"ShowSphere","text":"

ShowSphere

Displays the sphere.

func void ShowSphere(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#hidesphere","title":"HideSphere","text":"

HideSphere

Hides the sphere.

func void HideSphere(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#togglesphere","title":"ToggleSphere","text":"

ToggleSphere

Changes the visibility of a sphere. If displayed - hide, if hidden - display.

func void ToggleSphere(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#bounding-box","title":"Bounding Box","text":""},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#drawbbox","title":"DrawBBox","text":"

DrawBBox

Creates and draws a new bounding box and returns its handle.

func int DrawBBox(var int startPosPtr, var int endPosPtr, var int color)\n
Parameters

Return value

The function returns a new PermMem handle to the bounding box.

"},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#drawbbox3","title":"DrawBBox3","text":"

DrawBBox3

DrawBBox, but with world coordinates as parameters, instead of zVEC3 pointers.

func int DrawBBox3(var int x1, var int y1, var int z1, var int x2, var int y2, var int z2, var int color)\n
Parameters

Return value

The function returns a new PermMem handle to the bounding box.

"},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#drawbboxaddr","title":"DrawBBoxAddr","text":"

DrawBBoxAddr

DrawBBox, but with the address of a bounding box as a parameter.

func int DrawBBoxAddr(var int bboxPtr, var int color)\n
Parameters

Return value

The function returns a new PermMem handle to the bounding box.

"},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#updatebbox","title":"UpdateBBox","text":"

UpdateBBox

Changes the coordinates of an existing bounding box.

func void UpdateBBox(var int hndl, var int startPosPtr, var int endPosPtr)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#updatebbox3","title":"UpdateBBox3","text":"

UpdateBBox3

UpdateBBox, but with world coordinates as parameters, instead of zVEC3 pointers.

func void UpdateBBox3(var int hndl, var int x1, var int y1, var int z1, var int x2, var int y2, var int z2)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#updatebboxaddr","title":"UpdateBBoxAddr","text":"

UpdateBBoxAddr

UpdateBBox, but with the address of a bounding box as a parameter.

func void UpdateBBoxAddr(var int hndl, var int bboxPtr)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#setbboxcolor","title":"SetBBoxColor","text":"

SetBBoxColor

Changes the color of a specific bounding box.

func void SetBBoxColor(var int hndl, var int color)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#erasebbox","title":"EraseBBox","text":"

EraseBBox

Deletes a bounding box from the world and its handle.

func void EraseBBox(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#bboxvisible","title":"BBoxVisible","text":"

BBoxVisible

Returns whether a bounding box is visible.

func int BBoxVisible(var int hndl)\n
Parameters

Return value

The function returns TRUE if the bounding box is visible/displayed. FALSE is returned otherwise.

"},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#showbbox","title":"ShowBBox","text":"

ShowBBox

Displays the bounding box.

func void ShowBBox(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#hidebbox","title":"HideBBox","text":"

HideBBox

Hides the bounding box.

func void HideBBox(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#togglebbox","title":"ToggleBBox","text":"

ToggleBBox

Changes the visibility of a bounding box. If displayed - hide, if hidden - display.

func void ToggleBBox(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#oriented-bounding-box","title":"Oriented Bounding Box","text":""},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#drawobboxaddr","title":"DrawOBBoxAddr","text":"

DrawOBBoxAddr

Creates and draws a new oriented bounding box based on the address of an oriented bounding box and returns its handle.

func int DrawOBBoxAddr(var int oBBoxPtr, var int color)\n
Parameters

Return value

The function returns a new PermMem handle to the oriented bounding box.

"},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#updateobboxaddr","title":"UpdateOBBoxAddr","text":"

UpdateOBBoxAddr

Changes the coordinates and orientation of an existing oriented bounding box.

func void UpdateOBBoxAddr(var int hndl, var int oBBoxPtr)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#setobboxcolor","title":"SetOBBoxColor","text":"

SetOBBoxColor

Changes the color of a specific oriented bounding box.

func void SetOBBoxColor(var int hndl, var int color)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#eraseobbox","title":"EraseOBBox","text":"

EraseOBBox

Deletes an oriented bounding box from the world and its handle.

func void EraseOBBox(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#obboxvisible","title":"OBBoxVisible","text":"

OBBoxVisible

Returns whether an oriented bounding box is visible.

func int OBBoxVisible(var int hndl)\n
Parameters

Return value

The function returns TRUE if the oriented bounding box is visible/displayed. FALSE is returned otherwise.

"},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#showobbox","title":"ShowOBBox","text":"

ShowOBBox

Displays the oriented bounding box.

func void ShowOBBox(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#hideobbox","title":"HideOBBox","text":"

HideOBBox

Hides the oriented bounding box.

func void HideOBBox(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#toggleobbox","title":"ToggleOBBox","text":"

ToggleOBBox

Changes the visibility of an oriented bounding box. If displayed - hide, if hidden - display.

func void ToggleOBBox(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#eraseall","title":"EraseAll","text":"

EraseAll

Deletes all draw elements and their handles from the world.

func void EraseAll()\n
"},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#examples","title":"Examples","text":"

World coordinates are not particularly informative. This package aims to help and allows visualizing world coordinates in the form of lines, spheres (as circles), bounding boxes, and oriented bounding boxes in three-dimensional space.

"},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#visualizing-straight-line-to-an-npc","title":"Visualizing Straight Line to an NPC","text":"

To draw a line between two NPCs, you only need the coordinates of the two NPCs.

func void Example_1() {\n    var zCVob her; her = Hlp_GetNpc(hero);\n    var int point1[3];\n    point1[0] = her.trafoObjToWorld[3];\n    point1[1] = her.trafoObjToWorld[7];\n    point1[2] = her.trafoObjToWorld[11];\n\n    var zCVob oth; oth = Hlp_GetNpc(PC_ThiefOW);\n    var int point2[3];\n    point2[0] = oth.trafoObjToWorld[3];\n    point2[1] = oth.trafoObjToWorld[7];\n    point2[2] = oth.trafoObjToWorld[11];\n\n    var int hndl;\n\n    if (!Hlp_IsValidHandle(hndl)) {\n        hndl = DrawLine(_@(point1), _@(point2), zCOLOR_GREEN);\n    } else {\n        UpdateLine(hndl, _@(point1), _@(point2));\n    };\n};\n

This function can now be called continuously using FrameFunction to continuously adjust the straight line according to the positions of the characters.

FF_Apply(Example_1);\n

Alternatively, you can write the function as follows:

func void Example_1() {\n    var zCVob her; her = Hlp_GetNpc(hero);\n    var zCVob oth; oth = Hlp_GetNpc(PC_ThiefOW);\n\n    var int hndl;\n\n    if (!Hlp_IsValidHandle(hndl)) {\n        hndl = DrawLine3(her.trafoObjToWorld[3], her.trafoObjToWorld[7], her.trafoObjToWorld[11],\n                         oth.trafoObjToWorld[3], oth.trafoObjToWorld[7], oth.trafoObjToWorld[11],\n                         zCOLOR_GREEN);\n    } else {\n        UpdateLine3(hndl, her.trafoObjToWorld[3], her.trafoObjToWorld[7], her.trafoObjToWorld[11],\n                          oth.trafoObjToWorld[3], oth.trafoObjToWorld[7], oth.trafoObjToWorld[11]);\n    };\n};\n
"},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#visualizing-a-distance-of-5-meters","title":"Visualizing a Distance of 5 Meters","text":"

It becomes more interesting when dealing with \"abstract\" coordinates. For instance, you can visualize a \"safety distance\" around the player using a bounding box or a sphere, to check AI reactions at certain distances.

//*******************\n//   Bounding Box\n//*******************\nfunc void Example_2() {\n    var zCVob her; her = Hlp_GetNpc(hero);\n\n    // Safety distance around the player (5 meters)\n    var int distance; distance = mkf(500);\n\n    // Lower corner of the bounding box\n    var int point1[3];\n    point1[0] = subf(her.trafoObjToWorld[3],  distance);\n    point1[1] = subf(her.trafoObjToWorld[7],  distance);\n    point1[2] = subf(her.trafoObjToWorld[11], distance);\n\n    // Upper corner of the bounding box (diagonally opposite)\n    var int point2[3];\n    point2[0] = addf(her.trafoObjToWorld[3],  distance);\n    point2[1] = addf(her.trafoObjToWorld[7],  distance);\n    point2[2] = addf(her.trafoObjToWorld[11], distance);\n\n    var int hndl;\n\n    if (!Hlp_IsValidHandle(hndl)) {\n        hndl = DrawBBox(_@(point1), _@(point2), zCOLOR_BLUE);\n    } else {\n        UpdateBBox(hndl, _@(point1), _@(point2));\n    };\n};\n

To draw a sphere with a radius of 5 meters centered at a specific point, you only need the coordinates of the sphere's center.

//*******************\n//      Sphere\n//*******************\nfunc void Example_2() {\n    var zCVob her; her = Hlp_GetNpc(hero);\n    var int centerPoint[3];\n    centerPoint[0] = her.trafoObjToWorld[3];\n    centerPoint[1] = her.trafoObjToWorld[7];\n    centerPoint[2] = her.trafoObjToWorld[11];\n\n    var int hndl;\n\n    if (!Hlp_IsValidHandle(hndl)) {\n        hndl = DrawSphere(_@(centerPoint), 500, zCOLOR_BLUE);\n    } else {\n        UpdateSphere(hndl, _@(centerPoint), 500);\n    };\n};\n

Similarly, you could continuously update the bounding box/sphere using a FrameFunction.

"},{"location":"zengin/scripts/extenders/lego/tools/draw3d/#changing-color-or-hidingdeleting-draw-elements","title":"Changing Color or Hiding/Deleting Draw Elements","text":"

If you want to visualize an AI reaction, for example, you can change the color. Color values can be created using the RGBA function based on RGB values.

func void ObserveIntruder(var int hndl, var C_NPC oth) {\n    if (Npc_HasDetectedNpc(oth, hero)) {\n        // Color is now red, position and size of the bounding box remain unchanged\n        SetBBoxColor(hndl, zCOLOR_RED); // zCOLOR_RED == RGBA(255, 0, 0, 255)\n    };\n};\n

Draw elements can also be easily hidden or completely deleted.

func void CheckDialog(var int hndl) {\n    if (!InfoManager_HasFinished()) {\n        // Hide bounding box during dialogs\n        HideBBox(hndl);\n\n        // EraseBBox(hndl); // Or delete including the handle\n    };\n};\n
"},{"location":"zengin/scripts/extenders/lego/tools/event_handler/","title":"EventHandler","text":""},{"location":"zengin/scripts/extenders/lego/tools/event_handler/#eventhandler","title":"EventHandler","text":"

Info

Dependencies: - PermMem Implementation: EventHandler.d on GitHub

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/#initialization","title":"Initialization","text":"

Initialize with LeGo_EventHandler flag.

LeGo_Init(LeGo_EventHandler);\n
"},{"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":"

Event_Create

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":"

Event_Delete

Alias to PermMem delete. Cleans up the handle.

func void Event_Delete(var int event)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/event_handler/#event_empty","title":"Event_Empty","text":"

Event_Empty

Checks whether the event is \"empty\", i.e. nothing will happen after its execution.

func int Event_Empty(var int event)\n
Parameters

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":"

Event_Has

Checks if function is added to the event.

func int Event_Has(var int event, var func function)\n
Parameters

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":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/event_handler/#event_addonce","title":"Event_AddOnce","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/event_handler/#event_remove","title":"Event_Remove","text":"

Event_Remove

Removes the event handler function from the event.

func void Event_Remove(var int event, var func function)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/event_handler/#event_execute","title":"Event_Execute","text":"

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)\n
Parameters "},{"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":"

EventPtr_Create

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":"

EventPtr_Delete

Alias to PermMem free. Cleans up the pointer.

func void EventPtr_Delete(var int eventPtr)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/event_handler/#eventptr_empty","title":"EventPtr_Empty","text":"

EventPtr_Empty

Checks whether the event is \"empty\", i.e. nothing will happen after its execution.

func int EventPtr_Empty(var int eventPtr)\n
Parameters

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":"

EventPtr_Has

Checks if function is added to an event.

func int EventPtr_Has(var int eventPtr, var func function)\n
Parameters

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_HasI

EventPtr_Has but with function ID instead of pointer. Used mainly internally.

func int EventPtr_HasI(var int eventPtr, var int id)\n
Parameters

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":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/event_handler/#eventptr_addi","title":"EventPtr_AddI","text":"

EventPtr_AddI

EventPtr_Add but with function ID instead of pointer. Used mainly internally.

func void EventPtr_AddI(var int eventPtr, var int id)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/event_handler/#eventptr_addonce","title":"EventPtr_AddOnce","text":"

EventPtr_AddOnce

Event_Add but checks if function is already added, to prevent duplicates.

func void EventPtr_AddOnce(var int eventPtr, var func function)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/event_handler/#eventptr_addoncei","title":"EventPtr_AddOnceI","text":"

EventPtr_AddOnceI

EventPtr_AddI but checks if function is already added, to prevent duplicates.

func void EventPtr_AddOnceI(var int eventPtr, var int id)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/event_handler/#eventptr_remove","title":"EventPtr_Remove","text":"

EventPtr_Remove

Removes a function from the event's call list.

func void EventPtr_Remove(var int eventPtr, var func function)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/event_handler/#eventptr_removei","title":"EventPtr_RemoveI","text":"

EventPtr_RemoveI

EventPtr_Remove but with function ID instead of pointer. Used mainly internally.

func void EventPtr_RemoveI(var int eventPtr, var int id)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/event_handler/#eventptr_execute","title":"EventPtr_Execute","text":"

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)\n
"},{"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":"

Info

Dependencies: - Floats - PermMem - HookEngine - Timer Implementation: FrameFunctions.d on GitHub

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/#initialization","title":"Initialization","text":"

Initialize with LeGo_FrameFunctions flag.

LeGo_Init(LeGo_FrameFunctions);\n
"},{"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":"

FF_Apply

Adds the Daedalus function function to the running FrameFunctions list. function is called each frame.

func void FF_Apply(var func function)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/frame_functions/#ff_applygt","title":"FF_ApplyGT","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/frame_functions/#ff_applydata","title":"FF_ApplyData","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/frame_functions/#ff_applyext","title":"FF_ApplyExt","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/frame_functions/#ff_applyextgt","title":"FF_ApplyExtGT","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/frame_functions/#ff_applyextdata","title":"FF_ApplyExtData","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/frame_functions/#ff_applyextdatagt","title":"FF_ApplyExtDataGT","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/frame_functions/#ff_applyonce","title":"FF_ApplyOnce","text":"

FF_ApplyOnce

Alias to FF_Apply, which only adds the function once, even after multiple calls.

func void FF_ApplyOnce(var func function)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/frame_functions/#ff_applyoncegt","title":"FF_ApplyOnceGT","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/frame_functions/#ff_applyoncedata","title":"FF_ApplyOnceData","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/frame_functions/#ff_applyonceext","title":"FF_ApplyOnceExt","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/frame_functions/#ff_applyonceextgt","title":"FF_ApplyOnceExtGT","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/frame_functions/#ff_applyonceextdata","title":"FF_ApplyOnceExtData","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/frame_functions/#ff_active","title":"FF_Active","text":"

FF_Active

Checks whether the function is active.

func int FF_Active(var func function)\n
Parameters

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":"

FF_ActiveData

Checks whether the function with the specified data is active.

func int FF_ActiveData(var func function, var int data)\n
Parameters

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":"

FF_Remove

Stops a specific FrameFunction.

func void FF_Remove(var func function)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/frame_functions/#ff_removeall","title":"FF_RemoveAll","text":"

FF_RemoveAll

Stops all intsnces of a specific FrameFunction.

func void FF_RemoveAll(var func function)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/frame_functions/#ff_removedata","title":"FF_RemoveData","text":"

FF_RemoveData

Stops a specific FrameFunction, with the specified value (see FF_ApplyExtData ).

func void FF_RemoveData(var func function, var int data)\n
Parameters "},{"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":"

Info

Dependencies: - PermMem Implementation: Hashtable.d on GitHub

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/#initialization","title":"Initialization","text":"

Initialize with LeGo_PermMem flag.

LeGo_Init(LeGo_PermMem);\n
"},{"location":"zengin/scripts/extenders/lego/tools/hashtables/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/tools/hashtables/#ht_createsized","title":"HT_CreateSized","text":"

HT_CreateSized

Generates a hashtable of the specified size.

func int HT_CreateSized(var int size)\n
Parameters

Return value

The function returns a handle to the created hashtable.

"},{"location":"zengin/scripts/extenders/lego/tools/hashtables/#ht_create","title":"HT_Create","text":"

HT_Create

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":"

HT_Insert

Inserts a value into the Hashtable.

func void HT_Insert(var int handle, var int val, var int key)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/hashtables/#ht_resize","title":"HT_Resize","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/hashtables/#ht_get","title":"HT_Get","text":"

HT_Get

Reads a value from the hashtable.

func int HT_Get(var int handle, var int key)\n
Parameters

Return value

The function returns the value associated with the key.

"},{"location":"zengin/scripts/extenders/lego/tools/hashtables/#ht_has","title":"HT_Has","text":"

HT_Has

Checks if the key already exist in hashtable.

func int HT_Has(var int handle, var int key)\n
Parameters

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":"

HT_Remove

Removes a key from the hashtable.

func void HT_Remove(var int handle, var int key)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/hashtables/#ht_change","title":"HT_Change","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/hashtables/#ht_insertorchange","title":"HT_InsertOrChange","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/hashtables/#ht_getnumber","title":"HT_GetNumber","text":"

HT_GetNumber

Returns the number of entries in a hashtable.

func int HT_GetNumber(var int handle)\n
Parameters

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":"

HT_ForEach

Performs a function for each value pair in the hashtable.

func void HT_ForEach(var int handle, var func fnc)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/hashtables/#ht_destroy","title":"HT_Destroy","text":"

HT_Destroy

Deletes the hashtable.

func void HT_Destroy(var int handle)\n
Parameters "},{"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":"

Info

Dependencies: - None Implementation: HookDaedalus.d on GitHub

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/#initialization","title":"Initialization","text":"

N/A

"},{"location":"zengin/scripts/extenders/lego/tools/hook_dae/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/tools/hook_dae/#hookdaedalusfunc","title":"HookDaedalusFunc","text":"

HookDaedalusFunc

Hooks the function.

func void HookDaedalusFunc(var func hooked, var func hook)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/hook_dae/#hookdaedalusfuncf","title":"HookDaedalusFuncF","text":"

HookDaedalusFuncF

Alias to the HookDaedalusFunc function.

func void HookDaedalusFuncF(var func hooked, var func hook)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/hook_dae/#hookdaedalusfunci","title":"HookDaedalusFuncI","text":"

HookDaedalusFuncI

HookDaedalusFunc but with function ID.

func void HookDaedalusFuncI(var int hookedID, var int hookID)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/hook_dae/#hookdaedalusfuncs","title":"HookDaedalusFuncS","text":"

HookDaedalusFuncS

HookDaedalusFunc but with function name.

func void HookDaedalusFuncS(var string hookedName, var string hookName)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/hook_dae/#ishookd","title":"IsHookD","text":"

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)\n
Parameters

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":"

ContinueCall

Continues the program run with the original function.

func void ContinueCall()\n
"},{"location":"zengin/scripts/extenders/lego/tools/hook_dae/#passargumenti","title":"PassArgumentI","text":"

PassArgumentI

Passes an integer as an argument to the original function. Must be called before ContinueCall.

func void PassArgumentI(var int i)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/hook_dae/#passarguments","title":"PassArgumentS","text":"

PassArgumentS

Passes a string as an argument to the original function. Must be called before ContinueCall.

func void PassArgumentS(var string s)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/hook_dae/#passargumentn","title":"PassArgumentN","text":"

PassArgumentN

Passes an instance as an argument to the original function. Must be called before ContinueCall.

func void PassArgumentN(var instance n)\n
Parameters "},{"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":"

Info

Dependencies: - None Implementation: HookEngine.d on GitHub

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/#initialization","title":"Initialization","text":"

N/A

"},{"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":"

HookEngine

Attaches a function to an engine function address.

func void HookEngine(var int address, var int oldInstr, var string function)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/hook_engine/#hookengines","title":"HookEngineS","text":"

HookEngineS

Alias to the HookEngine function.

func void HookEngineS(var int address, var int oldInstr, var string function)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/hook_engine/#hookenginei","title":"HookEngineI","text":"

HookEngineI

Alias to HookEngine with funcID.

func void HookEngineI(var int address, var int oldInstr, var int funcID)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/hook_engine/#hookenginef","title":"HookEngineF","text":"

HookEngineF

Alias to HookEngine with func parameter.

func void HookEngineF(var int address, var int oldInstr, var func function)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/hook_engine/#ishooked","title":"IsHooked","text":"

IsHooked

Checks if a hook is already present at a given address.

func var int IsHooked(var int address)\n
Parameters

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":"

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)\n
Parameters

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":"

IsHookI

Alias to IsHook with a funcID as parameter.

func var int IsHookI(var int address, var int funcID)\n
Parameters

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":"

IsHookF

Alias to IsHook with a function as parameter.

func var int IsHookF(var int address, var func function)\n
Parameters

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":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/hook_engine/#removehooki","title":"RemoveHookI","text":"

RemoveHookI

Alias to RemoveHook with funcID.

func void RemoveHook(var int address, var int oldInstr, var int funcID)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/hook_engine/#removehookf","title":"RemoveHookF","text":"

RemoveHookF

Alias for RemoveHook with func parameter.

func void RemoveHook(var int address, var int oldInstr, var func function)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/hook_engine/#replaceenginefunc","title":"ReplaceEngineFunc","text":"

ReplaceEngineFunc

Replaces an engine function with a Daedalus function.

func void ReplaceEngineFunc(var int address, var int thiscall_numparams, var string replaceFunc)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/hook_engine/#replaceenginefunci","title":"ReplaceEngineFuncI","text":"

ReplaceEngineFuncI

Alias to ReplaceEngineFunc with funcID.

func void ReplaceEngineFunc(var int address, var int thiscall_numparams, var int funcID)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/hook_engine/#replaceenginefuncf","title":"ReplaceEngineFuncF","text":"

ReplaceEngineFuncF

Alias to ReplaceEngineFunc with func parameter.

func void ReplaceEngineFunc(var int address, var int thiscall_numparams, var func function)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/hook_engine/#disableenginefunc","title":"DisableEngineFunc","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/hook_engine/#hook_returnfalse","title":"Hook_ReturnFalse","text":"

Hook_ReturnFalse

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":"

Hook_ReturnTrue

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":"

Info

Dependencies: - None Implementation: Int64.d on GitHub

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/#initialization","title":"Initialization","text":"

N/A

"},{"location":"zengin/scripts/extenders/lego/tools/int64/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/tools/int64/#mk64","title":"mk64","text":"

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)\n
Parameters 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":"

neg64

Negates the integer: *dest <- -(*dest)

func void neg64(var int dest)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/int64/#add64","title":"add64","text":"

add64

Adds src to dest: *dest <- *dest + *src

func void add64(var int dest, var int src)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/int64/#sub64","title":"sub64","text":"

sub64

Subtracts src from dest: *dest <- *dest - *src

func void sub64(var int dest, var int src)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/int64/#mul64","title":"mul64","text":"

mul64

Multiplies dest by src: *dest <- (*dest) * (*src)

func void mul64(var int dest, var int src)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/int64/#div64","title":"div64","text":"

div64

Divides dest by src: *dest <- *dest / *src

func void mul64(var int dest, var int src)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/interface/","title":"Interface","text":""},{"location":"zengin/scripts/extenders/lego/tools/interface/#interface","title":"Interface","text":"

Info

Dependencies: - AI_Function - Anim8 - HookEngine - PermMem Implementation: Interface.d on GitHub

This package offers a lot of useful functions to work with the 2D interface.

"},{"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/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/tools/interface/#sysgettime","title":"sysGetTime","text":"

sysGetTime

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":"

RGBA

Generates a full zColor.

func int RGBA(var int r, var int g, var int b, var int a)\n
Parameters

Return value

The function returns a zColor object.

"},{"location":"zengin/scripts/extenders/lego/tools/interface/#changealpha","title":"ChangeAlpha","text":"

ChangeAlpha

Overrides the alpha value of a given zColor.

func int ChangeAlpha(var int zCol, var int a)\n
Parameters

Return value

The function returns a modified zColor object.

"},{"location":"zengin/scripts/extenders/lego/tools/interface/#getalpha","title":"GetAlpha","text":"

GetAlpha

Returns the alpha value of a given zColor.

func int GetAlpha(var int zCol)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_createtext","title":"Print_CreateText","text":"

Print_CreateText

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

Return value

The function returns a handle to zCViewText.

"},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_createtextptr","title":"Print_CreateTextPtr","text":"

Print_CreateTextPtr

Print_CreateText but returns pointer to zCViewText instead of handle.

func int Print_CreateTextPtr(var string text, var string font)\n
Parameters

Return value

The function returns a pointer to zCViewText.

"},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_createtextptrcolored","title":"Print_CreateTextPtrColored","text":"

Print_CreateTextPtrColored

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

Return value

The function returns a pointer to zCViewText.

"},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_gettext","title":"Print_GetText","text":"

Print_GetText

Returns zCViewText instance from handle.

func zCViewText Print_GetText(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_gettextptr","title":"Print_GetTextPtr","text":"

Print_GetTextPtr

Returns zCViewText pointer from handle.

func int Print_GetTextPtr(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_deletetext","title":"Print_DeleteText","text":"

Print_DeleteText

Removes a zCViewText from the screen.

func void Print_DeleteText(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_setalpha","title":"Print_SetAlpha","text":"

Print_SetAlpha

Changes the alpha value of a given zCViewText.

func void Print_SetAlpha(var int hndl, var int a)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/interface/#printptr_setalpha","title":"PrintPtr_SetAlpha","text":"

PrintPtr_SetAlpha

Print_SetAlpha but with pointer to zCViewText instead of handle.

func void PrintPtr_SetAlpha(var int ptr, var int a)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_getscreensize","title":"Print_GetScreenSize","text":"

Print_GetScreenSize

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":"

Print_Screen

An int array holding the current resolution. (Filled by Print_GetScreenSize)

int Print_Screen[2];\n
"},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_ratio","title":"Print_Ratio","text":"

Print_Ratio

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":"

PS_VMax

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":"

Print_ToVirtual

Convents pixel position to a virtual position.

func int Print_ToVirtual(var int pxl, var int dim)\n
Parameters

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_ToVirtualF

Print_ToVirtual but returns Ikarus float value instead of integer.

func int Print_ToVirtualF(var int pxl, var int dim)\n
Parameters

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":"

Print_ToPixel

Convents virtual position to a pixel position.

func int Print_ToPixel(var int vrt, var int dim)\n
Parameters

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_ToPixelF

Print_ToPixel but returns Ikarus float value instead of integer.

func int Print_ToPixelF(var int vrt, var int dim)\n
Parameters

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":"

Print_ToRatio

Gets the size in the specified dimension in ratioed by the screen.

func int Print_ToRatio(var int size, var int dim)\n
Parameters

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":"

Print_ToRadian

Converts angle in degrees to radians.

func int Print_ToRadian(var int angle)\n
Parameters

Return value

The function returns calculated angle in radians.

"},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_todegree","title":"Print_ToDegree","text":"

Print_ToDegree

Converts angle in radians to degrees.

func int Print_ToDegree(var int angle)\n
Parameters

Return value

The function returns calculated angle in degrees.

"},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_getfontptr","title":"Print_GetFontPtr","text":"

Print_GetFontPtr

Returns a pointer to a zCFont by its name.

func int Print_GetFontPtr(var string font)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_getfontname","title":"Print_GetFontName","text":"

Print_GetFontName

Returns a name of a zCFont from its pointer.

func string Print_GetFontName(var int fontPtr)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_getstringwidth","title":"Print_GetStringWidth","text":"

Print_GetStringWidth

Returns the width of a string in pixels.

func int Print_GetStringWidth(var string s, var string font)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_getstringwidthptr","title":"Print_GetStringWidthPtr","text":"

Print_GetStringWidthPtr

Print_GetStringWidth but with zCFont pointer instead of name.

func int Print_GetStringWidthPtr(var string s, var int font)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_getfontheight","title":"Print_GetFontHeight","text":"

Print_GetFontHeight

Returns the height of a string in pixels.

func int Print_GetFontHeight(var string font)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_ext","title":"Print_Ext","text":"

Print_Ext

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

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_ExtPxl

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

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":"

Print_LongestLine

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 "},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_longestlineext","title":"Print_LongestLineExt","text":"

Print_LongestLineExt

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 "},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_longestlinelength","title":"Print_LongestLineLength","text":"

Print_LongestLineLength

Returns the longest line width in pixels, using default line separator tilde ~.

func int Print_LongestLineLength(var string text, var string font)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_longestlinelengthext","title":"Print_LongestLineLengthExt","text":"

Print_LongestLineLengthExt

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 "},{"location":"zengin/scripts/extenders/lego/tools/interface/#print_textfield","title":"Print_TextField","text":"

Print_TextField

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

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_TextFieldPxl

Print_TextField but with pixel coordinates.

func int Print_TextFieldPxl(var int x, var int y, var string text, var string font)\n
Parameters

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_TextFieldColored

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

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":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/interface/#prints_ext","title":"PrintS_Ext","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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/interface/#ai_prints","title":"AI_PrintS","text":"

AI_PrintS

Version of PrintS that enqueue in given NPCs AI queue.

func void AI_PrintS(var c_npc slf, var string txt)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/interface/#ai_prints_ext","title":"AI_PrintS_Ext","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)\n
Parameters "},{"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":"

Info

Dependencies: - None Implementation: ItemHelper.d on GitHub

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/#initialization","title":"Initialization","text":"

N/A

"},{"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":"

Itm_GetPtr

func int Itm_GetPtr(var int instance)\n
Parameters

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":"

Info

Dependencies: - None Implementation: List.d on GitHub

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/#initialization","title":"Initialization","text":"

N/A

"},{"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":"

List_Create

Creates a list with an initial value.

func int List_Create(var int data)\n
Parameters

Return value

The function returns a pointer to the created list.

"},{"location":"zengin/scripts/extenders/lego/tools/list/#list_add","title":"List_Add","text":"

List_Add

Appends a value to the end of the list.

func void List_Add(var int list, var int data)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/list/#list_addfront","title":"List_AddFront","text":"

List_AddFront

Adds a value before the first element of the list.

func void List_AddFront(var int list, var int data)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/list/#list_addoffset","title":"List_AddOffset","text":"

List_AddOffset

Inserts a value between two list elements.

func void List_AddOffset(var int list, var int offset, var int data)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/list/#list_set","title":"List_Set","text":"

List_Set

Sets a list element to a specific value.

func void List_Set(var int node, var int data)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/list/#list_get","title":"List_Get","text":"

List_Get

Retrieves the value of a list element.

func int List_Get(var int list, var int nr)\n
Parameters

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":"

List_Node

Returns a pointer to a list element.

func int List_Node(var int list, var int nr)\n
Parameters

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":"

List_Length

Returns the length of the list (number of all elements).

func int List_Length(var int list)\n
Parameters

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":"

List_HasLength

Checks if the list has the specified length.

func int List_HasLength(var int list, var int length)\n
Parameters

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":"

List_End

Returns the last list element of the list.

func int List_End(var int list)\n
Parameters

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":"

List_Concat

Concatenates two lists.

func void List_Concat(var int list, var int list2)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/list/#list_contains","title":"List_Contains","text":"

List_Contains

Returns the last list element with a specific value.

func int List_Contains(var int list, var int data)\n
Parameters

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":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/list/#list_forf","title":"List_ForF","text":"

List_ForF

Similar to List_For, but with a function parameter instead of a string.

func void ListForF(var int list, var func function)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/list/#list_fori","title":"List_ForI","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/list/#list_delete","title":"List_Delete","text":"

List_Delete

Deletes a list element. All subsequent elements shift position.

func void List_Delete(var int list, var int nr)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/list/#list_destroy","title":"List_Destroy","text":"

List_Destroy

Destroys the entire list.

func void List_Destroy(var int list)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/list/#list_toarray","title":"List_ToArray","text":"

List_ToArray

Returns a pointer to a memory area containing all values of the list.

func int List_ToArray(var int list)\n
Parameters

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":"

List_MoveDown

Moves the specified list node down by one position in the list.

func void List_MoveDown(var int list, var int node)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/list/#list_moveup","title":"List_MoveUp","text":"

List_MoveUp

Moves the specified list node up by one position in the list.

func void List_MoveUp(var int list, var int node)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/list/#list_insertsorted","title":"List_InsertSorted","text":"

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)\n
Parameters: "},{"location":"zengin/scripts/extenders/lego/tools/list/#list_compare","title":"List_Compare","text":"

List_Compare

func int List_Compare(var int data1, var int data2, var func compare)\n
Parameters:

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":"

List_CmpAscending

Compares two integer values in ascending order.

func int List_CmpAscending(var int data1, var int data2)\n
Parameters:

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":"

List_CmpDescending

Compares two integer values in descending order.

func int List_CmpDescending(var int data1, var int data2)\n
Parameters:

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":"

List_CmpAscendingUnsigned

Compares two unsigned integer values in ascending order.

func int List_CmpAscendingUnsigned(var int data1, var int data2)\n
Parameters:

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":"

List_CmpDescendingUnsigned

Compares two unsigned integer values in descending order.

func int List_CmpDescendingUnsigned(var int data1, var int data2)\n
Parameters:

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":"

Info

Dependencies: - StringBuilder Implementation: Locals.d on GitHub

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/#initialization","title":"Initialization","text":"

N/A

"},{"location":"zengin/scripts/extenders/lego/tools/locals/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/tools/locals/#locals_1","title":"Locals","text":"

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()\n
"},{"location":"zengin/scripts/extenders/lego/tools/locals/#final","title":"Final","text":"

Final

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":"

Info

Dependencies: - Floats Implementation: Misc.d on GitHub

The Misc package introduces various helper functions that did not fit into any other package.

"},{"location":"zengin/scripts/extenders/lego/tools/misc/#initialization","title":"Initialization","text":"

N/A

"},{"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":"

atan2f

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

Return value

The function returns arcus tangent in radians as Ikarus float.

"},{"location":"zengin/scripts/extenders/lego/tools/misc/#sin","title":"sin","text":"

sin

Calculates the sine of an angle given in radians.

func int sin(var int angle)\n
Parameters

Return value

The function returns sine of the angle as Ikarus float.

"},{"location":"zengin/scripts/extenders/lego/tools/misc/#cos","title":"cos","text":"

cos

Calculates the cosine of an angle given in radians.

func int cos(var int angle)\n
Parameters

Return value

The function returns cosine of the angle as Ikarus float.

"},{"location":"zengin/scripts/extenders/lego/tools/misc/#tan","title":"tan","text":"

tan

Calculates the tangent of an angle given in radians.

func int tan(var int angle)\n
Parameters

Return value

The function returns tangent of the angle as Ikarus float.

"},{"location":"zengin/scripts/extenders/lego/tools/misc/#asin","title":"asin","text":"

asin

Calculates the arcus sine.

func int asin(var int sine)\n
Parameters

Return value

The function returns arcus sine of the angle as Ikarus float.

"},{"location":"zengin/scripts/extenders/lego/tools/misc/#acos","title":"acos","text":"

acos

Calculates the arcus cosine

func int acos(var int cosine)\n
Parameters

Return value

The function returns arcus cosine of the angle as Ikarus float.

"},{"location":"zengin/scripts/extenders/lego/tools/misc/#distance2d","title":"distance2D","text":"

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)\n
Parameters

Return value

The function returns the distance between the two points.

"},{"location":"zengin/scripts/extenders/lego/tools/misc/#distance2df","title":"distance2Df","text":"

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)\n
Parameters

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":"

Info

Dependencies: - Saves - Locals Implementation: PermMem.d on GitHub

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/#initialization","title":"Initialization","text":"

Initialize with LeGo_PermMem flag.

LeGo_Init(LeGo_PermMem);\n
"},{"location":"zengin/scripts/extenders/lego/tools/permmem/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/tools/permmem/#new","title":"new","text":"

new

Creates a handle to a new instance of inst.

func int new(var int inst)\n
Parameters

Return value

The function returns a new, valid PermMem handle.

"},{"location":"zengin/scripts/extenders/lego/tools/permmem/#create","title":"create","text":"

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)\n
Parameters

Return value

The function returns a pointer to the new instance.

"},{"location":"zengin/scripts/extenders/lego/tools/permmem/#wrap","title":"wrap","text":"

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)\n
Parameters

Return value

The function returns a handle with ptr as content.

"},{"location":"zengin/scripts/extenders/lego/tools/permmem/#clear","title":"clear","text":"

clear

Cleans the handle. After that it is invalid.

func void clear(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/permmem/#release","title":"release","text":"

release

Frees the handle. The reserved memory is not deleted, the handle becomes invalid.

func void release(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/permmem/#delete","title":"delete","text":"

delete

Cleans the handle just like clear, only the destructor is also called.

func void delete(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/permmem/#free","title":"free","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/permmem/#get","title":"get","text":"

get

Returns the instance of the handle.

func instance get(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/permmem/#getptr","title":"getPtr","text":"

getPtr

Returns a pointer to instance of handle.

func int getPtr(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/permmem/#setptr","title":"setPtr","text":"

setPtr

Sets the pointer of a handle.

func void setPtr(var int hndl, var int ptr)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/permmem/#getinst","title":"getInst","text":"

getInst

Returns the instance used to create the given handle in new function.

func int getInst(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/permmem/#numhandles","title":"numHandles","text":"

numHandles

Returns the number of handles managed by PermMem.

func int numHandles()\n
"},{"location":"zengin/scripts/extenders/lego/tools/permmem/#sizeof","title":"sizeof","text":"

sizeof

Gets the size of the given instance's class.

func int sizeof(var int inst)\n
Parameters

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":"

Hlp_IsValidHandle

Indicates whether the handle exists and is managed by PermMem.

func int Hlp_IsValidHandle(var int hndl)\n
Parameters

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":"

foreachHndl

Executes a function for each handle of an instance.

func void foreachHndl(var int inst, var func fnc)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/permmem/#hashndl","title":"hasHndl","text":"

hasHndl

Checks if PermMem has a handle of this instance.

func int hasHndl(var int inst)\n
Parameters

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":"

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)\n
Parameters

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":"

PM_Exists

Checks if the specified field already exists in the archive. (used with archiver/unarchiver)

func int PM_Exists(var string name)\n
Parameters

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":"

PM_SaveInt

Saves an integer to the archive.

func void PM_SaveInt (var string name, var int val)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/permmem/#pm_savefloat","title":"PM_SaveFloat","text":"

PM_SaveFloat

Saves a daedalus float to the archive.

func void PM_SaveFloat (var string name, var int flt)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/permmem/#pm_savestring","title":"PM_SaveString","text":"

PM_SaveString

Saves a string to the archive.

func void PM_SaveString (var string name, var string val)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/permmem/#pm_savefuncid","title":"PM_SaveFuncID","text":"

PM_SaveFuncID

Saves a function ID to the archive.

func void PM_SaveFuncID(var string name, var int fnc)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/permmem/#pm_savefuncoffset","title":"PM_SaveFuncOffset","text":"

PM_SaveFuncOffset

Saves a function offset to the archive.

func void PM_SaveFuncOffset(var string name, var int fnc)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/permmem/#pm_savefuncptr","title":"PM_SaveFuncPtr","text":"

PM_SaveFuncPtr

Saves a function pointer to the archive.

func void PM_SaveFuncPtr(var string name, var int fnc)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/permmem/#pm_saveclassptr","title":"PM_SaveClassPtr","text":"

PM_SaveClassPtr

Saves a pointer of a class to the archive.

func void PM_SaveClassPtr(var string name, var int ptr, var string className)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/permmem/#pm_saveclass","title":"PM_SaveClass","text":"

PM_SaveClass

Saves a class like PM_SaveClassPtr.

func void PM_SaveClass(var string name, var int ptr, var string className)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/permmem/#pm_saveintarray","title":"PM_SaveIntArray","text":"

PM_SaveIntArray

Saves an array of integers.

func void PM_SaveIntArray(var string name, var int ptr, var int elements)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/permmem/#pm_savestringarray","title":"PM_SaveStringArray","text":"

PM_SaveStringArray

Saves an array of integers.

func void PM_SaveStringArray(var string name, var int ptr, var int elements)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/permmem/#unarchiver","title":"Unarchiver","text":""},{"location":"zengin/scripts/extenders/lego/tools/permmem/#pm_load","title":"PM_Load","text":"

PM_Load

Universal function to load integers, floats, class pointers and int arrays.

func int PM_Load(var string name)\n
Parameters

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":"

PM_LoadInt

Returns an integer stored in the archive.

func int PM_LoadInt(var string name)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/permmem/#pm_loadfloat","title":"PM_LoadFloat","text":"

PM_LoadFloat

Returns a daedalus float stored in the archive.

func int PM_LoadFloat(var string name)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/permmem/#pm_loadstring","title":"PM_LoadString","text":"

PM_LoadString

Returns a string stored in the archive.

func string PM_LoadString(var string name)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/permmem/#pm_loadfuncid","title":"PM_LoadFuncID","text":"

PM_LoadFuncID

Returns a function ID stored in the archive.

func int PM_LoadFuncID(var string name)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/permmem/#pm_loadfuncoffset","title":"PM_LoadFuncOffset","text":"

PM_LoadFuncOffset

Returns a function offset stored in the archive.

func int PM_LoadFuncOffset(var string name)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/permmem/#pm_loadfuncptr","title":"PM_LoadFuncPtr","text":"

PM_LoadFuncPtr

Returns a function pointer stored in the archive.

func int PM_LoadFuncPtr(var string name)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/permmem/#pm_loadclassptr","title":"PM_LoadClassPtr","text":"

PM_LoadClassPtr

Returns a class pointer stored in the archive.

func int PM_LoadClassPtr(var string name)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/permmem/#pm_loadclass","title":"PM_LoadClass","text":"

PM_LoadClass

Loads a pointer to the class from the archive to destPtr.

func void PM_LoadClass(var string name, var int destPtr)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/permmem/#pm_loadarray","title":"PM_LoadArray","text":"

PM_LoadArray

Returns a pointer to array stored in the archive.

func int PM_LoadArray(var string name)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/permmem/#pm_loadarraytoptr","title":"PM_LoadArrayToPtr","text":"

PM_LoadArrayToPtr

Loads a pointer to array from the archive to destPtr.

func void PM_LoadArrayToPtr(var string name, var int destPtr)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/permmem/#pm_loadtoptr","title":"PM_LoadToPtr","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/queue/","title":"Queue","text":""},{"location":"zengin/scripts/extenders/lego/tools/queue/#queue","title":"Queue","text":"

Info

Dependencies: - PermMem Implementation: Queue.d on GitHub

This package is an implementation of the Queue data structure and a queue for function calls.

"},{"location":"zengin/scripts/extenders/lego/tools/queue/#initialization","title":"Initialization","text":"

N/A

"},{"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":"

Q_Create

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":"

Q_Enqueue

Appends an integer to the back of the queue

func void Q_Enqueue(var int queue, var int value)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/queue/#q_isempty","title":"Q_IsEmpty","text":"

Q_IsEmpty

Checks if the queue is empty.

func int Q_IsEmpty(var int queue)\n
Parameters

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":"

Q_Advance

Removes the oldest value from the queue and returns it.

func int Q_Advance(var int queue)\n
Parameters

Return value

The function returns the oldest value in the queue.

"},{"location":"zengin/scripts/extenders/lego/tools/queue/#q_peek","title":"Q_Peek","text":"

Q_Peek

Returns the oldest value in the queue without removing it.

func int Q_Peek(var int queue)\n
Parameters

Return value

The function returns the oldest value in the queue.

"},{"location":"zengin/scripts/extenders/lego/tools/queue/#q_for","title":"Q_For","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/queue/#q_forf","title":"Q_ForF","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/queue/#callbackqueue","title":"CallbackQueue","text":""},{"location":"zengin/scripts/extenders/lego/tools/queue/#cq_create","title":"CQ_Create","text":"

CQ_Create

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":"

CQ_EnqueueNoData

Appends a function to the callback queue.

func void CQ_EnqueueNoData(var int queue, var func function)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/queue/#cq_enqueuedata","title":"CQ_EnqueueData","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/queue/#cq_enqueue","title":"CQ_Enqueue","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/queue/#cq_isempty","title":"CQ_IsEmpty","text":"

CQ_IsEmpty

Checks if no function is in the callback queue.

func int CQ_IsEmpty(var int queue)\n
Parameters

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":"

CQ_Advance

Executes the foremost function of the callback queue and removes it from the callback queue.

func void CQ_Advance(var int queue)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/queue/#cq_exhaust","title":"CQ_Exhaust","text":"

CQ_Exhaust

Executes all functions contained in the callback queue.

func void CQ_Exhaust(var int queue)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/random/","title":"Random","text":""},{"location":"zengin/scripts/extenders/lego/tools/random/#random","title":"Random","text":"

Info

Dependencies: - None Implementation: Random.d on GitHub

Provides more random randomization than Hlp_Random() function.

"},{"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/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/tools/random/#r_next","title":"r_Next","text":"

r_Next

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":"

r_Max

Returns a random number from 0 to max.

func int r_Max(var int max)\n
Parameters

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":"

r_MinMax

Returns a random number from 'min' to 'max'.

func int r_MinMax(var int min, var int max)\n
Parameters

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":"

r_Init

Initializes the random number generator. Happens optionally in LeGo_Init.

func void r_Init(var int seed)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/random/#r_defaultinit","title":"r_DefaultInit","text":"

r_DefaultInit

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":"

Info

Dependencies: - None Implementation: StringBuilder.d on GitHub

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/#initialization","title":"Initialization","text":"

N/A

"},{"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":"

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()\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":"

SB_Use

Marks this StringBuilder as active. It can now be used with the functions.

func void SB_Use(var int sb)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/string_builder/#sb_get","title":"SB_Get","text":"

SB_Get

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":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/string_builder/#sb_clear","title":"SB_Clear","text":"

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()\n
"},{"location":"zengin/scripts/extenders/lego/tools/string_builder/#sb_release","title":"SB_Release","text":"

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()\n
"},{"location":"zengin/scripts/extenders/lego/tools/string_builder/#sb_destroy","title":"SB_Destroy","text":"

SB_Destroy

Completely destroys the StringBuilder.

func void SB_Destroy()\n
"},{"location":"zengin/scripts/extenders/lego/tools/string_builder/#sb_tostring","title":"SB_ToString","text":"

SB_ToString

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":"

SB_ToStream

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":"

SB_GetStream

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":"

SB_Length

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":"

SB_SetLength

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":"

SB

Appends a string, to the active StringBuilder.

func void SB(var string s)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/string_builder/#sbi","title":"SBi","text":"

SBi

Appends an integer in text form, to the active StringBuilder.

func void SBi(var int i)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/string_builder/#sbc","title":"SBc","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/string_builder/#sbraw","title":"SBraw","text":"

SBraw

Appends a raw bytes array, to the active StringBuilder.

func void SBraw(var int ptr, var int len)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/string_builder/#sbflt","title":"SBflt","text":"

SBflt

Appends a Daedalus float in text form, to the active StringBuilder.

func void SBflt(var float x)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/string_builder/#sbf","title":"SBf","text":"

SBf

Appends an Ikarus float in text form, to the active StringBuilder.

func void SBf(var int x)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/string_builder/#sbw","title":"SBw","text":"

SBw

Appends a 4-byte raw data (interpreted as an integer x), to the active StringBuilder.

func void SBw(var int x)\n
Parameters "},{"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":"

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)\n
Parameters

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":"

STR_Unescape

Counterpart to STR_Escape. Escape sequences like \\n, \\r or \\t are converted back.

func string STR_Unescape(var string s0)\n
Parameters

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":"

STR_StartsWith

Checks if the input string s starts with the specified prefix string.

func int STR_StartsWith(var string str, var string start) \n
Parameters

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":"

BuildStringSymbolsArray

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":"

GetStringSymbolByAddr

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":"

Info

Dependencies: - PermMem Implementation: Talents.d on GitHub

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/#initialization","title":"Initialization","text":"

Initialize with LeGo_PermMem flag.

LeGo_Init(LeGo_PermMem);\n
"},{"location":"zengin/scripts/extenders/lego/tools/talents/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/tools/talents/#npc_getid","title":"Npc_GetID","text":"

Npc_GetID

Returns unique ID specific for provided NPC.

func int Npc_GetID(var C_NPC slf)\n
Parameters

Return value

The function returns NPCs unique ID.

"},{"location":"zengin/scripts/extenders/lego/tools/talents/#npc_findbyid","title":"Npc_FindByID","text":"

Npc_FindByID

Finds the NPC pointer of an NPC with the given ID.

func int Npc_FindByID(var int ID)\n
Parameters

Return value

The function returns NPC pointer.

"},{"location":"zengin/scripts/extenders/lego/tools/talents/#tal_createtalent","title":"TAL_CreateTalent","text":"

TAL_CreateTalent

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":"

TAL_SetValue

Sets a new value to the specified talent.

func void TAL_SetValue(var C_NPC npc, var int talent, var int value)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/talents/#tal_getvalue","title":"TAL_GetValue","text":"

TAL_GetValue

Returns the value of a saved talent for specified NPC.

func int TAL_GetValue(var C_NPC npc, var int talent)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/timer/","title":"Timer","text":""},{"location":"zengin/scripts/extenders/lego/tools/timer/#timer","title":"Timer","text":"

Info

Dependencies: - None Implementation: Timer.d on GitHub

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/#initialization","title":"Initialization","text":"

Initialize with LeGo_Timer flag.

LeGo_Init(LeGo_Timer);\n
"},{"location":"zengin/scripts/extenders/lego/tools/timer/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/tools/timer/#timer_1","title":"Timer","text":"

Timer

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":"

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()\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":"

TimerF

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":"

Timer_SetPause

Pauses the timer (and thus all FrameFunctions and running animations).

func void Timer_SetPause(var int on)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/timer/#timer_setpauseinmenu","title":"Timer_SetPauseInMenu","text":"

Timer_SetPauseInMenu

The timer can automatically pause when the game is paused. (status screen, main menu...)

func void Timer_SetPauseInMenu(var int on)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/timer/#timer_ispaused","title":"Timer_IsPaused","text":"

Timer_IsPaused

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":"

Info

Dependencies: - PermMem - Interface Implementation: View.d on GitHub

This package can create textures on the screen and work with them in an extended manner.

"},{"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/#functions","title":"Functions","text":""},{"location":"zengin/scripts/extenders/lego/tools/view/#view_create","title":"View_Create","text":"

View_Create

Creates a zCView with virtual coordinates.

func int View_Create(var int x1, var int y1, var int x2, var int y2) \n
Parameters

Return value

The function returns a PermMem handle to a zCView.

"},{"location":"zengin/scripts/extenders/lego/tools/view/#view_createpxl","title":"View_CreatePxl","text":"

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) \n
Parameters

Return value

The function returns a PermMem handle to a zCView.

"},{"location":"zengin/scripts/extenders/lego/tools/view/#view_createcenter","title":"View_CreateCenter","text":"

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)\n
Parameters

Return value

The function returns a PermMem handle to a zCView.

"},{"location":"zengin/scripts/extenders/lego/tools/view/#view_createcenterpxl","title":"View_CreateCenterPxl","text":"

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)\n
Parameters

Return value

The function returns a PermMem handle to a zCView.

"},{"location":"zengin/scripts/extenders/lego/tools/view/#view_get","title":"View_Get","text":"

View_Get

Alias for get form PermMem.

zCView View_Get(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/view/#view_getptr","title":"View_GetPtr","text":"

View_GetPtr

Alias for getPtr form PermMem.

func int View_GetPtr(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/view/#view_render","title":"View_Render","text":"

View_Render

Renders a zCView. Should be used sparingly, as it works only in specific cases.

func void View_Render(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/view/#view_settexture","title":"View_SetTexture","text":"

View_SetTexture

Assigns a texture to a view. The key function of this package.

func void View_SetTexture(var int hndl, var string texture)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/view/#view_gettexture","title":"View_GetTexture","text":"

View_GetTexture

Gets the name of a previously assigned texture.

func string View_GetTexture(var int hndl)\n
Parameters

Return value

The function returns the previously assigned texture.

"},{"location":"zengin/scripts/extenders/lego/tools/view/#view_setcolor","title":"View_SetColor","text":"

View_SetColor

Sets the color of a view.

func void View_SetColor(var int hndl, var int color)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/view/#view_getcolor","title":"View_GetColor","text":"

View_GetColor

Gets the color of a view.

func int View_GetColor(var int hndl)\n
Parameters

Return value

The function returns the full zColor.

"},{"location":"zengin/scripts/extenders/lego/tools/view/#view_open","title":"View_Open","text":"

View_Open

Opens a view. It will be displayed on the screen.

func void View_Open(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/view/#view_close","title":"View_Close","text":"

View_Close

Closes a view. It disappears from the screen but can still be used.

func void View_Close(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/view/#view_delete","title":"View_Delete","text":"

View_Delete

Alias for delete.

`zCView` View_Delete(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/view/#view_resize","title":"View_Resize","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/view/#view_resizepxl","title":"View_ResizePxl","text":"

View_ResizePxl

Alias for View_Resize using pixel coordinates.

func void View_ResizePxl(var int hndl, var int width, var int height)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/view/#view_move","title":"View_Move","text":"

View_Move

Moves the view by virtual units.

func void View_Move(var int hndl, var int x, var int y)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/view/#view_movepxl","title":"View_MovePxl","text":"

View_MovePxl

Alias for View_Move using pixel coordinates.

func void View_MovePxl(var int hndl, var int x, var int y)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/view/#view_moveto","title":"View_MoveTo","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/view/#view_movetopxl","title":"View_MoveToPxl","text":"

View_MoveToPxl

Alias for View_MoveTo using pixel coordinates.

func void View_MoveToPxl(var int hndl, var int x, var int y)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/view/#view_addtext","title":"View_AddText","text":"

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)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/view/#view_deletetext","title":"View_DeleteText","text":"

View_DeleteText

Removes all text added with View_AddText.

func void View_DeleteText(var int hndl)\n
Parameters "},{"location":"zengin/scripts/extenders/lego/tools/view/#view_top","title":"View_Top","text":"

View_Top

Places the view above all others.

func void View_Top(var int hndl)\n
Parameters "},{"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/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":""},{"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
"},{"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":""},{"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:

"},{"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":"

AI_CallScript

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
"},{"location":"zengin/scripts/extenders/zparserextender/externals/ai/#ai_starttriggerscript","title":"AI_startTriggerScript","text":"

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) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/ai/#ai_starttriggerscriptex","title":"AI_startTriggerScriptEx","text":"

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

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
"},{"location":"zengin/scripts/extenders/zparserextender/externals/ai/#ai_gettriggerbyid","title":"AI_GetTriggerByID","text":"

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) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/ai/#ai_gettriggersnum","title":"AI_GetTriggersNum","text":"

AI_GetTriggersNum

Returns the number of active C_Trigger scripts

func int AI_GetTriggersNum() {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/ai/#ai_gettriggernpc","title":"AI_GetTriggerNPC","text":"

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) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/ai/#ai_gettriggerfunc","title":"AI_GetTriggerFunc","text":"

AI_GetTriggerFunc

Returns the function associated with the specified C_Trigger

func func AI_GetTriggerFunc(var C_Trigger trigger) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/ai/#ai_gettriggerfuncname","title":"AI_GetTriggerFuncName","text":"

AI_GetTriggerFuncName

Returns the function name of a function associated with the specified C_Trigger

func string AI_GetTriggerFuncName(var C_Trigger trigger) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/ai/#ai_getnexttriggerbyfunc","title":"Ai_GetNextTriggerByFunc","text":"

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) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/ai/#ai_getnexttriggerbyfuncname","title":"Ai_GetNextTriggerByFuncName","text":"

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) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/ai/#ai_getnexttriggerbyself","title":"Ai_GetNextTriggerBySelf","text":"

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) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/ai/#ai_getnexttriggerbyother","title":"Ai_GetNextTriggerByOther","text":"

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) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/ai/#ai_getnexttriggerbyvictim","title":"Ai_GetNextTriggerByVictim","text":"

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 ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/ai/#ai_getnexttriggerbynpcs","title":"Ai_GetNextTriggerByNPCs","text":"

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

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
"},{"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":"

Cast_PointerToInstance

Converts memory address (pointer) to an instance

func instance Cast_PointerToInstance(var int address) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/cast/#cast_instancetopointer","title":"Cast_InstanceToPointer","text":"

Cast_InstanceToPointer

Converts instance to a memory address (pointer)

func int Cast_InstanceToPointer( var instance object) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/cast/#cast_pointertonpc","title":"Cast_PointerToNpc","text":"

Cast_PointerToNpc

Casts memory address (pointer) to an NPC

func C_NPC Cast_PointerToNpc( var int address) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/cast/#cast_pointertoitem","title":"Cast_PointerToItem","text":"

Cast_PointerToItem

Casts memory address (pointer) to an Item

func C_ITEM Cast_PointerToItem( var int address) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/cast/#cast_instanceisnpc","title":"Cast_InstanceIsNpc","text":"

Cast_InstanceIsNpc

Checks whether object is an NPC

func int Cast_InstanceIsNpc( var instance object) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/cast/#cast_instanceisitem","title":"Cast_InstanceIsItem","text":"

Cast_InstanceIsItem

Checks whether object is an Item

func int Cast_InstanceIsItem( var instance object) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/cast/#cast_instanceismob","title":"Cast_InstanceIsMob","text":"

Cast_InstanceIsMob

Checks whether object is an MOB

func int Cast_InstanceIsMob( var instance object) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/cast/#cast_getinstanceindex","title":"Cast_GetInstanceIndex","text":"

Cast_GetInstanceIndex

Returns symbolID of the object, returns -1 when not found

func int Cast_GetInstanceIndex( var instance object) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/cast/#cast_getclassid","title":"Cast_GetClassID","text":"

Cast_GetClassID

Returns the class identifier of a class by its name

func int Cast_GetClassID( var string className ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/cast/#cast_getvobclassid","title":"Cast_GetVobClassID","text":"

Cast_GetVobClassID

Returns class identifier of the zCObject vob class

func int Cast_GetVobClassID( var instance object ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/cast/#cast_checkvobclassid","title":"Cast_CheckVobClassID","text":"

Cast_CheckVobClassID

Checks if the classId class is the parent class of the object

func int Cast_CheckVobClassID( var int classId, var instance object ) {};\n
"},{"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":"

Hlp_HasFocusVob

Returns TRUE, if a specified NPC has a Vob in focus

func int Hlp_HasFocusVob( var C_NPC npc ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/hlp/#hlp_getfocusvob","title":"Hlp_GetFocusVob","text":"

Hlp_GetFocusVob

Returns NPC's focus Vob

func instance Hlp_GetFocusVob( var C_NPC npc ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/hlp/#hlp_getfocusvobname","title":"Hlp_GetFocusVobName","text":"

Hlp_GetFocusVobName

Returns the name of NPC's focus vob

func string Hlp_GetFocusVobName( var C_NPC npc ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/hlp/#hlp_getstringlength","title":"Hlp_GetStringLength","text":"

Hlp_GetStringLength

Returns the length of a specified string

func int Hlp_GetStringLength( var string str ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/hlp/#isnan","title":"IsNAN","text":"

IsNAN

Checks whether floating point number is valid

func int IsNAN( var float value ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/hlp/#hlp_keytoggled","title":"Hlp_KeyToggled","text":"

Hlp_KeyToggled

Checks whether key is toggled

func int Hlp_KeyToggled( var int key ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/hlp/#hlp_keypressed","title":"Hlp_KeyPressed","text":"

Hlp_KeyPressed

Checks whether key is pressed

func int Hlp_KeyPressed( var int key ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/hlp/#hlp_logicalkeytoggled","title":"Hlp_LogicalKeyToggled","text":"

Hlp_LogicalKeyToggled

Checks whether logical key is toggled

func int Hlp_LogicalKeyToggled( var int key ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/hlp/#hlp_gameonpause","title":"Hlp_GameOnPause","text":"

Hlp_GameOnPause

Checks whether the game is paused

func int Hlp_GameOnPause() {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/hlp/#hlp_messagebox","title":"Hlp_MessageBox","text":"

Hlp_MessageBox

Opens a message box with a specified message

func void Hlp_MessageBox( var string message ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/hlp/#hlp_printconsole","title":"Hlp_PrintConsole","text":"

Hlp_PrintConsole

Prints a message to the Union debug console

func void Hlp_PrintConsole(var string message) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/hlp/#hlp_optionisexists","title":"Hlp_OptionIsExists","text":"

Hlp_OptionIsExists

Checks whether the entry in section in .ini file optName exists

optName values

func int Hlp_OptionIsExists(var string optName, var string section, var string entry) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/hlp/#hlp_readoptionint","title":"Hlp_ReadOptionInt","text":"

Hlp_ReadOptionInt

Read an integer value from specified .ini file, section and entry.

optName values

func int Hlp_ReadOptionInt(var string optName, var string section, var string entry, var int default) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/hlp/#hlp_readoptionfloat","title":"Hlp_ReadOptionFloat","text":"
!!! function \"`Hlp_ReadOptionFloat`\"\nRead a floating point value from specified `.ini` file, section and entry.\n\n`optName` values\n\n- `#!dae \"Gothic\"`\n- `#!dae \"Mod\"`\n- `#!dae \"SystemPack\"`\n\n```dae\nfunc float Hlp_ReadOptionFloat(var string optName, var string section, var string entry, var float default) {};\n```\n\n- `optName` - the `.ini` file\n- `section` - settings section like `[INTERFACE]`\n- `entry` - one setting entry like `scale`\n- `default` - default value - if the value is empty\n- `return` - the option value\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/hlp/#hlp_readoptionstring","title":"Hlp_ReadOptionString","text":"

Hlp_ReadOptionString

Read a string value from specified .ini file, section and entry.

optName values

func string Hlp_ReadOptionString(var string optName, var string section, var string entry, var string default) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/hlp/#hlp_writeoptionint","title":"Hlp_WriteOptionInt","text":"

Hlp_WriteOptionInt

Writes an integer value to specified .ini file, section and entry.

optName values

func void Hlp_WriteOptionInt(var string optName, var string section, var string entry, var int value) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/hlp/#hlp_writeoptionfloat","title":"Hlp_WriteOptionFloat","text":"

Hlp_WriteOptionFloat

Writes a floating point value to specified .ini file, section and entry.

optName values

func void Hlp_WriteOptionFloat(var string optName, var string section, var string entry, var float value) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/hlp/#hlp_writeoptionstring","title":"Hlp_WriteOptionString","text":"

Hlp_WriteOptionString

Writes a string value to specified .ini file, section and entry.

optName values

func void Hlp_WriteOptionString(var string optName, var string section, var string entry, var string value) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/hlp/#hlp_getsteampersonalname","title":"Hlp_GetSteamPersonalName","text":"

Hlp_GetSteamPersonalName

Returns the name of the current Steam user Returns empty string when not run with Steam

func string Hlp_GetSteamPersonalName() {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/hlp/#hlp_doevent","title":"Hlp_DoEvent","text":"

Hlp_DoEvent

Calls every event function with the name funcName.

func void Hlp_DoEvent(var string funcName) {};\n
"},{"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":"

Log_GetTopicStatus

Returns the status of diary topic

func int Log_GetTopicStatus(var string topic) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/log/#log_gettopicsection","title":"Log_GetTopicSection","text":"

Log_GetTopicSection

Returns the topic the diary topic is in

func int Log_GetTopicSection(var string topic) {};\n
"},{"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":"

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 ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/mdl/#mdl_getanimationname","title":"Mdl_GetAnimationName","text":"

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 ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/mdl/#mdl_animationisexists","title":"Mdl_AnimationIsExists","text":"

Mdl_AnimationIsExists

Checks whether animation exists

func int Mdl_AnimationIsExists( var C_NPC npc, var int ani_index ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/mdl/#mdl_animationisactive","title":"Mdl_AnimationIsActive","text":"

Mdl_AnimationIsActive

Checks whether animation is active (whether it is currently played)

func int Mdl_AnimationIsActive( var C_NPC npc, var int ani_index ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/mdl/#mdl_setallanimationsfps","title":"Mdl_SetAllAnimationsFPS","text":"

Mdl_SetAllAnimationsFPS

Set framerate for all animations

func void Mdl_SetAllAnimationsFPS( var C_NPC npc, var float fps ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/mdl/#mdl_resetallanimationsfps","title":"Mdl_ResetAllAnimationsFPS","text":"

Mdl_ResetAllAnimationsFPS

Reset framerate for all animations to default value

func void Mdl_ResetAllAnimationsFPS( var C_NPC npc ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/mdl/#mdl_setanimationfps","title":"Mdl_SetAnimationFPS","text":"

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 ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/mdl/#mdl_resetanimationfps","title":"Mdl_ResetAnimationFPS","text":"

Mdl_ResetAnimationFPS

Reset framerate to default for animation specified by animation index

func void Mdl_ResetAnimationFPS( var C_NPC npc, var int ani_index ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/mdl/#mdl_setvisible","title":"Mdl_SetVisible","text":"

Mdl_SetVisible

Set NPCs visibility

func void Mdl_SetVisible( var C_NPC npc, var int isVisible ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/mdl/#mdl_applyoverlaymds_atfirst","title":"Mdl_ApplyOverlayMds_AtFirst","text":"

Mdl_ApplyOverlayMds_AtFirst

Applies or moves existing overlay to the top of the list

func void Mdl_ApplyOverlayMds_AtFirst( var string mdsName ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/mdl/#mdl_setnpcspeedmultiplier","title":"Mdl_SetNpcSpeedMultiplier","text":"

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 ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/mdl/#mdl_resetnpcspeedmultiplier","title":"Mdl_ResetNpcSpeedMultiplier","text":"

Mdl_ResetNpcSpeedMultiplier

Resets the animation speed of an NPC

func void Mdl_ResetNpcSpeedMultiplier( var C_Npc npc ) {};\n
"},{"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":"

Menu_SearchItems

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
"},{"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":"

Mob_Destroy

Marks oCMOB as destroyed, changes the visual to visualDestroyed (if present).

func void Mob_Destroy( var instance object ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/mob/#mob_removeitem","title":"Mob_RemoveItem","text":"

Mob_RemoveItem

Removes an item from a oCMobContainer

func void Mob_RemoveItem( var instance object, var int item ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/mob/#mob_removeitems","title":"Mob_RemoveItems","text":"

Mob_RemoveItems

Removes specified number of items from a oCMobContainer

func void Mob_RemoveItems( var instance object, var int item, var int cnt ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/mob/#mob_insertitem","title":"Mob_InsertItem","text":"

Mob_InsertItem

Inserts an item into a oCMobContainer

func void Mob_InsertItem( var instance object, var int item ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/mob/#mob_insertitems","title":"Mob_InsertItems","text":"

Mob_InsertItems

Inserts specified number of items into a oCMobContainer

func void Mob_InsertItems( var instance object, var int item, var int cnt ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/mob/#mob_getlockcombination","title":"Mob_GetLockCombination","text":"

Mob_GetLockCombination

Returns a lock combination of a oCMobContainer

func string Mob_GetLockCombination( var instance object ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/mob/#mob_setlockcombination","title":"Mob_SetLockCombination","text":"

Mob_SetLockCombination

Sets a lock combination to a oCMobContainer

func void Mob_SetLockCombination( var instance object, var string comb ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/mob/#mob_islocked","title":"Mob_IsLocked","text":"

Mob_IsLocked

Returns TRUE if the object is locked

func int Mob_IsLocked( var instance object ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/mob/#mob_setlocked","title":"Mob_SetLocked","text":"

Mob_SetLocked

Set the lock status of the object

func void Mob_SetLocked( var instance object, var int locked ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/mob/#mob_getkeyinstance","title":"Mob_GetKeyInstance","text":"

Mob_GetKeyInstance

Returns the key instance, that unlocks the object

func instance Mob_GetKeyInstance( var instance object ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/mob/#mob_setkeyinstance","title":"Mob_SetKeyInstance","text":"

Mob_SetKeyInstance

Stets the key instance, that unlocks the object

func void Mob_SetKeyInstance( var instance object, var int key ) {};\n
"},{"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":"

Npc_SetAsHero

Changes players character to specified npc

func void Npc_SetAsHero( var C_NPC npc ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/npc/#npc_openinventory","title":"Npc_OpenInventory","text":"

Npc_OpenInventory

Opens NPCs main inventory

func void Npc_OpenInventory( var C_NPC npc ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/npc/#npc_openinventorysteal","title":"Npc_OpenInventorySteal","text":"

Npc_OpenInventorySteal

Opens the steal inventory of npc's focus NPC

func void Npc_OpenInventorySteal( var C_NPC npc ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/npc/#npc_openinventorytrade","title":"Npc_OpenInventoryTrade","text":"

Npc_OpenInventoryTrade

Start the trading dialogue with specified NPC

func void Npc_OpenInventoryTrade( var C_NPC npc ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/npc/#npc_getlefthanditem","title":"Npc_GetLeftHandItem","text":"

Npc_GetLeftHandItem

Returns an item in NPC's left hand slot

func C_Item Npc_GetLeftHandItem( var C_Npc npc ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/npc/#npc_getrighthanditem","title":"Npc_GetRightHandItem","text":"

Npc_GetRightHandItem

Returns an item in NPC's right hand slot

func C_Item Npc_GetRightHandItem( var C_Npc npc ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/npc/#npc_getslotitem","title":"Npc_GetSlotItem","text":"

Npc_GetSlotItem

Returns an item from a slot with the slotName

func C_Item Npc_GetSlotItem( var C_Npc npc, var string slotName ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/npc/#npc_putinslot","title":"Npc_PutInSlot","text":"

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) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/npc/#npc_removefromslot","title":"Npc_RemoveFromSlot","text":"

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) {};\n
"},{"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":"

Par_GetParserID

Returns a parser ID of the parser with a parName name

Parser names:

func int Par_GetParserID(var string parName) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/par/#par_getsymbolid","title":"Par_GetSymbolID","text":"

Par_GetSymbolID

Returns symbol ID for the symbol specified by its name

func int Par_GetSymbolID(var int parId, var string symName) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/par/#par_getsymbollength","title":"Par_GetSymbolLength","text":"

Par_GetSymbolLength

Returns symbol length (number of elements)

func int Par_GetSymbolLength(var int parId, var int symId) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/par/#par_getsymbolvalueint","title":"Par_GetSymbolValueInt","text":"

Par_GetSymbolValueInt

Returns the integer value of specified symbol

func int Par_GetSymbolValueInt(var int parId, var int symId) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/par/#par_getsymbolvaluefloat","title":"Par_GetSymbolValueFloat","text":"

Par_GetSymbolValueFloat

Returns the float value of specified symbol

func float Par_GetSymbolValueFloat(var int parId, var int symId) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/par/#par_getsymbolvaluestring","title":"Par_GetSymbolValueString","text":"

Par_GetSymbolValueString

Returns the string value of specified symbol

func string Par_GetSymbolValueString(var int parId, var int symId) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/par/#par_getsymbolvalueinstance","title":"Par_GetSymbolValueInstance","text":"

Par_GetSymbolValueInstance

Returns the instance value of specified symbol

func instance Par_GetSymbolValueInstance(var int parId, var int symId) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/par/#par_getsymbolvalueintarray","title":"Par_GetSymbolValueIntArray","text":"

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) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/par/#par_getsymbolvaluefloatarray","title":"Par_GetSymbolValueFloatArray","text":"

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) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/par/#par_getsymbolvaluestringarray","title":"Par_GetSymbolValueStringArray","text":"

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) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/par/#par_setsymbolvalueint","title":"Par_SetSymbolValueInt","text":"

Par_SetSymbolValueInt

Sets a new integer value to specified symbol

func void Par_SetSymbolValueInt(var int value, var int parId, var int symId) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/par/#par_setsymbolvaluefloat","title":"Par_SetSymbolValueFloat","text":"

Par_SetSymbolValueFloat

Sets a new float value to specified symbol

func void Par_SetSymbolValueFloat(var float value, var int parId, var int symId) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/par/#par_setsymbolvaluestring","title":"Par_SetSymbolValueString","text":"

Par_SetSymbolValueString

Sets a new string value to specified symbol

func void Par_SetSymbolValueString(var string value, var int parId, var int symId) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/par/#par_setsymbolvalueinstance","title":"Par_SetSymbolValueInstance","text":"

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) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/par/#par_setsymbolvalueintarray","title":"Par_SetSymbolValueIntArray","text":"

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) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/par/#par_setsymbolvaluefloatarray","title":"Par_SetSymbolValueFloatArray","text":"

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) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/par/#par_setsymbolvaluestringarray","title":"Par_SetSymbolValueStringArray","text":"

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) {};\n
"},{"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":"

Str_Format

Returns formatted string using format specifiers

Format specifiers:

func string Str_Format( var string format, ... ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/string/#examples","title":"Examples","text":"

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.

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":"

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.

func string Str_GetLocalizedString( var string russian,\n                                    var string english,\n                                    var string german,\n                                    var string polish ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/string/#str_getlocalizedstringex","title":"Str_GetLocalizedStringEx","text":"

Str_GetLocalizedStringEx

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
"},{"location":"zengin/scripts/extenders/zparserextender/externals/string/#str_utf8_to_ansi","title":"Str_UTF8_to_ANSI","text":"

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 ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/string/#str_getcurrentcp","title":"Str_GetCurrentCP","text":"

Str_GetCurrentCP

Return the code page corresponding to the current language set in the Union System

func int Str_GetCurrentCP() {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/string/#str_getlength","title":"Str_GetLength","text":"

Str_GetLength

Returns the length of a string

func int Str_GetLength( var int str ) {};\n
"},{"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":"

Vob_GetVobPosition

Returns the current position of the object in the world

func C_Position Vob_GetVobPosition( var C_Vob vob ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/vob/#vob_setvobposition","title":"Vob_SetVobPosition","text":"

Vob_SetVobPosition

Sets the current position of the object in the world

func void Vob_SetVobPosition( var C_Vob vob, var C_Position pos ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/vob/#vob_getvobdata","title":"Vob_GetVobData","text":"

Vob_GetVobData

Returns the universal data of the zCVob object

func C_Vob_Data Vob_GetVobData( var C_Vob vob ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/vob/#vob_setvobdata","title":"Vob_SetVobData","text":"

Vob_SetVobData

Sets the universal data to a zCVob object

func void Vob_SetVobData( var C_Vob vob, var C_Vob_Data data ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/vob/#vob_getlightdata","title":"Vob_GetLightData","text":"

Vob_GetLightData

Returns zCVobLight object data

func C_Light_Data Vob_GetLightData( var C_Vob vobLight ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/vob/#vob_setlightdata","title":"Vob_SetLightData","text":"

Vob_SetLightData

Sets the data of a zCVobLight object

func void Vob_SetLightData( var C_Vob vobLight, var C_Light_Data data ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/vob/#vob_clearlightanilist","title":"Vob_ClearLightAniList","text":"

Vob_ClearLightAniList

Clears the list of animation colours for the light source

func void Vob_ClearLightAniList( var C_Vob vobLight ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/vob/#vob_addlightanicolor","title":"Vob_AddLightAniColor","text":"

Vob_AddLightAniColor

Adds a color to the colour list

func void Vob_AddLightAniColor( var C_Vob vobLight, var C_Color col ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/vob/#vob_addlightanicolorrgb","title":"Vob_AddLightAniColorRGB","text":"

Vob_AddLightAniColorRGB

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
"},{"location":"zengin/scripts/extenders/zparserextender/externals/vob/#vob_getmobdata","title":"Vob_GetMobData","text":"

Vob_GetMobData

Returns the data of the oCMOB object

func C_Mob_Data Vob_GetMobData( var C_Vob mob ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/vob/#vob_setmobdata","title":"Vob_SetMobData","text":"

Vob_SetMobData

Sets the data of the oCMOB object

func void Vob_SetMobData( var C_Vob mob, var C_Mob_Data data ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/vob/#vob_getmobinterdata","title":"Vob_GetMobInterData","text":"

Vob_GetMobInterData

Returns the data of the oCMobInter object

func MobInter_Data Vob_GetMobInterData( var C_Vob mobInter ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/vob/#vob_setmobinterdata","title":"Vob_SetMobInterData","text":"

Vob_SetMobInterData

Sets the data of the oCMobInter object

func void Vob_SetMobInterData( var C_Vob mobInter, var C_MobInter_Data data ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/vob/#vob_getmobinterdata_1","title":"Vob_GetMobInterData","text":"

Vob_GetMobInterData

Returns the data of the oCMobLockable object

func C_MobLockable_Data Vob_GetMobInterData( var C_Vob mobLock ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/vob/#vob_setmobinterdata_1","title":"Vob_SetMobInterData","text":"

Vob_SetMobInterData

Sets the data of the oCMobLockable object

func void Vob_SetMobInterData( var C_Vob mobLock, var C_MobLockable_Data data ) {};\n
"},{"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":"

Wld_ChangeLevel

Trigger level change.

func void Wld_ChangeLevel( var string world, var string waypoint ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/wld/#wld_findvob","title":"Wld_FindVob","text":"

Wld_FindVob

Return the VOB instance based on its name.

func instance Wld_FindVob( var string vobname ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/wld/#wld_playeffectvob","title":"Wld_PlayEffectVob","text":"

Wld_PlayEffectVob

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
"},{"location":"zengin/scripts/extenders/zparserextender/externals/wld/#wld_playeffectat","title":"Wld_PlayEffectAt","text":"

Wld_PlayEffectAt

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
"},{"location":"zengin/scripts/extenders/zparserextender/externals/wld/#wld_togglerain","title":"Wld_ToggleRain","text":"

Wld_ToggleRain

Turns on the rain

func void Wld_ToggleRain( var float weight, var float time ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/wld/#wld_setweathertype","title":"Wld_SetWeatherType","text":"

Wld_SetWeatherType

Sets the weather type. Types:

0 - snow 1 - rain

func void Wld_SetWeatherType( var int type ) {};\n
"},{"location":"zengin/scripts/extenders/zparserextender/externals/wld/#wld_getweathertype","title":"Wld_GetWeatherType","text":"

Wld_GetWeatherType

Returns the weather type. Types:

0 - snow 1 - rain

func int Wld_GetWeatherType() {};\n
"},{"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

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:

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":"

Doc_Create

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":"

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() {};\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":"

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) {};\n

Parameters

Example

nDocID = Doc_CreateMap();\nDoc_SetLevel(nDocID, \"WORLD.ZEN\");\n
"},{"location":"zengin/scripts/externals/doc/#doc_setlevelcoords","title":"Doc_SetLevelCoords","text":"

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) {};\n

Parameters

Example

Doc_SetLevelCoords(nDocID, -28000, 50500, 95500, -42500);\n
"},{"location":"zengin/scripts/externals/doc/#doc_setfont","title":"Doc_SetFont","text":"

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) {};\n

Parameters

Example

Doc_SetFont(nDocID, -1, \"FONT_10_BOOK.TGA\");\n
"},{"location":"zengin/scripts/externals/doc/#doc_setpages","title":"Doc_SetPages","text":"

Doc_SetPages

Sets the number of pages numOfPages of the document.

func void Doc_SetPages(var int docID, var int numOfPages) {};\n

Parameters

Example

nDocID = Doc_Create();\nDoc_SetPages(nDocID, 2);\n
"},{"location":"zengin/scripts/externals/doc/#doc_setpage","title":"Doc_SetPage","text":"

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) {};\n

Parameters

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":"

Doc_SetMargins

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

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":"

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) {};\n

Parameters

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":"

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) {};\n

Parameters

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":"

Doc_Show

Display the document using the document manager ID

func void Doc_Show(var int docID) {};\n

Parameters

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":"

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) {};\n
Parameters "},{"location":"zengin/scripts/externals/log/#log_addentry","title":"Log_AddEntry","text":"

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) {};\n
Parameters

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":"

Log_SetTopicStatus

Changes the status of the topic with the name topicName

func void Log_SetTopicStatus(var string topicName, var int status) {};\n
Parameters "},{"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":"

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) {};\n

Parameters

"},{"location":"zengin/scripts/externals/mdl/#mdl_applyoverlaymdstimed","title":"Mdl_ApplyOverlayMDSTimed","text":"

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) {};\n

Parameters

"},{"location":"zengin/scripts/externals/mdl/#mdl_removeoverlaymds","title":"Mdl_RemoveOverlayMDS","text":"

Mdl_RemoveOverlayMDS

Remove the animation overlay overlay_name from specified npc

func void Mdl_RemoveOverlayMDS(var c_npc npc, var string overlay_name) {};\n

Parameters

"},{"location":"zengin/scripts/externals/mdl/#mdl_applyrandomani","title":"Mdl_ApplyRandomAni","text":"

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) {};\n

Parameters

"},{"location":"zengin/scripts/externals/mdl/#mdl_applyrandomanifreq","title":"Mdl_ApplyRandomAniFreq","text":"

Mdl_ApplyRandomAniFreq

Sets the random animation frequency for animation ani1

func void Mdl_ApplyRandomAniFreq(var c_npc npc, var string ani1, var float frequency) {};\n

Parameters

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":"

Mdl_SetModelFatness

Set the procedural model fatness

func void Mdl_SetModelFatness(var c_npc npc, var float fatness) {};\n

Parameters

"},{"location":"zengin/scripts/externals/mdl/#mdl_setmodelscale","title":"Mdl_SetModelScale","text":"

Mdl_SetModelScale

Set model scale per axis

func void Mdl_SetModelScale(var c_npc npc, var float x, var float y, var float z) {};\n

Parameters

"},{"location":"zengin/scripts/externals/mdl/#mdl_setvisualbody","title":"Mdl_SetVisualBody","text":"

Mdl_SetVisualBody

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

"},{"location":"zengin/scripts/externals/mdl/#mdl_setvisual","title":"Mdl_SetVisual","text":"

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) {};\n

Parameters

"},{"location":"zengin/scripts/externals/mdl/#mdl_startfaceani","title":"Mdl_StartFaceAni","text":"

Mdl_StartFaceAni

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

"},{"location":"zengin/scripts/externals/mdl/#mdl_applyrandomfaceani","title":"Mdl_ApplyRandomFaceAni","text":"

Mdl_ApplyRandomFaceAni

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

"},{"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:

"},{"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

VDFS tools

World Editors

Libraries

Debugging

"},{"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/zSplitDialogs/","title":"zSplitDialogs","text":""},{"location":"zengin/tools/zSplitDialogs/#zsplitdialogs","title":"zSplitDialogs","text":"

The plugin for a dubbing creators. And not only.

Union plugin by Top Layer, which gives possibility to extract dialogues from compiled scripts simply by putting zSplitDialogs.vdf file into Data\\ directory and run the game. You can configure, that already dubbed subtitles will be outputed.

The output is the Dialogs\\ directory with .txt files with a structure as follow:

Example of a plugin output

"},{"location":"zengin/tools/zSplitDialogs/#download","title":"Download","text":""},{"location":"zengin/tools/zSplitDialogs/#source-code","title":"Source code","text":""},{"location":"zengin/tools/zSplitDialogs/#the-usage","title":"The usage","text":"

At first run, in gothic.ini will be created following section:

[ZSPLITDIALOGS]\nUnvoicedOnly=0\n

You can change value to 1 to receive only unvoiced subtitles.

"},{"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:

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:

"},{"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

"},{"location":"zengin/tools/zSpy/#message","title":"Message","text":"

The most important part. A message that contains:

"},{"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:

"},{"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
"},{"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
"},{"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/daedalus_tools/decdat/","title":"DecDat","text":""},{"location":"zengin/tools/daedalus_tools/decdat/#decdat","title":"DecDat","text":"

DecDat1 is a daedalus scripts decompiler orginaly created by Gottfried. Its goal is to replace Gothic Sourcer's decompiler, which wouldn't been able to decompile scripts with Ikarus and LeGo. However, that doesn't mean that DecDat is able to produce data that can be compiled again. This tool should be used mainly for research and educational purposes. Source code is available here.

"},{"location":"zengin/tools/daedalus_tools/decdat/#instalation","title":"Instalation","text":"

The tool is written in Java, allowing it to be executed seamlessly on both Windows and Linux operating systems. To utilize the tool, ensure that Java is installed on your system. We recommend using the Java version available here. Once you have your Java installed, download the latest tool version from GitHub releases page, and run the DecDat.jar file.

"},{"location":"zengin/tools/daedalus_tools/decdat/#usage","title":"Usage","text":"

After opening a DecDat you will see a following window.

To import a .DAT file click at File -> Open DAT... select the file encoding, the file itself and optionally OU.BIN file if you want to parse dialogues.

And that's it, now you have a .DAT file loaded into app, and you can export the code or search for a specific part.

  1. The original DecDat release post can be found here.\u00a0\u21a9

"},{"location":"zengin/tools/libraries/zenkit/","title":"ZenKit","text":""},{"location":"zengin/tools/libraries/zenkit/#zenkit","title":"ZenKit","text":"

ZenKit is a C++-library for loading and saving proprietary ZenGin files and is intended to be a successor to Andre Taulien's ZenLib. ZenKit wrappers for Java and C# are also available in the form of ZenKitCS and ZenKit4J which are also published to NuGet and Maven Central respectively.

ZenKit is used as the file loading and scripting backend for OpenGothic and has recently found adoption in GothicVR.

"},{"location":"zengin/tools/libraries/zenkit/#file-support","title":"File Support","text":"

The following file types and operations are supported by ZenKit. Requests to support additional file types are welcome and can be submitted to the GitHub repository.

File Type Extension Load1 Save2 Comment Model Animation .MAN \u2713 Yes \u2718 No \u2014 Model Hierarchy .MDH \u2713 Yes \u2713 Yes \u2014 Model Mesh .MDM \u2713 Yes \u2713 Yes Saving is only partially supported Model .MDL \u2713 Yes \u2713 Yes Saving is only partially supported Morph Mesh .MMB \u2713 Yes \u2718 No \u2014 Multi Resolution Mesh .MRM \u2713 Yes \u2713 Yes \u2014 Mesh .MSH \u2713 Yes \u2713 Yes Saving is only partially supported Daedalus Script .DAT \u2713 Yes \u2718 No A VM implementation is available (see Daedalus VM) Texture .TEX \u2713 Yes ~ Yes There is currently no API to alter image data Font .FNT \u2713 Yes \u2713 Yes \u2014 ZenGin Archive .ZEN \u2713 Yes \u2713 Yes \u2014 Text/Cutscenes .BIN, .CSL, .DAT, .LSC \u2713 Yes \u2713 Yes \u2014 Model Script .MDS, .MSB \u2713 Yes \u2718 No \u2014 Virtual File System .VDF \u2713 Yes \u2713 Yes Allows full integration with the host file system"},{"location":"zengin/tools/libraries/zenkit/#daedalus-vm","title":"Daedalus VM","text":"

Along facilities to read and write most resource files you might find in a typical Gothic installation, ZenKit also includes a virtual machine which can execute Daedalus scripts. An extensive API is available to inspect the files, add external handlers and bind Daedalus classes into C++-structs. Bindings for the original classes are available as an extension to ZenKit and available to the C# and Java wrappers natively.

"},{"location":"zengin/tools/libraries/zenkit/#documentation","title":"Documentation","text":"

Additional documentation for ZenKit can be found at zk.gothickit.dev.

  1. ZenKit is able to fully load these files\u00a0\u21a9

  2. ZenKit is able to save these files at least partially\u00a0\u21a9

"},{"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[^1]","text":""},{"location":"zengin/tools/vdfs_tools/vdfs_tool/#vdfs-tool","title":"VDFS Tool1","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 using the Resource Manager or directly from the post on WoP.ru - VDFS Tool.

"},{"location":"zengin/tools/vdfs_tools/vdfs_tool/#features","title":"Features","text":""},{"location":"zengin/tools/vdfs_tools/vdfs_tool/#volume-compression","title":"Volume compression","text":"

Volumes are compressed using the classic zip algorithm. The zlib library for buffer compression and decompression was taken as a basis. In order for the game to decompress the volume in real time without loss of performance, a special interface Gratt-5r2/ZippedStream was implemented and built into vdfs32g. The essence of the interface is that it allows you to pack and read files in blocks of a given size and keep unpacked data in memory in a specific range.

Warning

Compresed .mod and .vdf archives works only with Union installed.

"},{"location":"zengin/tools/vdfs_tools/vdfs_tool/#volume-optimization","title":"Volume optimization","text":"

Optimization refers to the procedure of identifying files with the same content and combining them under a common data source.

"},{"location":"zengin/tools/vdfs_tools/vdfs_tool/#file-explorer-interface","title":"File Explorer Interface","text":"

The program interface has a set of standard file explorer operations - copying, pasting, renaming, searching, etc.

"},{"location":"zengin/tools/vdfs_tools/vdfs_tool/#dragdrop","title":"Drag&Drop","text":"

The function allows you to drag files into the program, as well as pull them out of it. For this function to work correctly, user (administrator) rights must match for the program and Explorer.

"},{"location":"zengin/tools/vdfs_tools/vdfs_tool/#updating-a-volume-in-1-click","title":"Updating a volume in 1 click","text":"

The program analyzes shared files in the volume and in the game directories (Ctrl + U). If there are physical copies, when you save the volume, updated files will be written to it.

"},{"location":"zengin/tools/vdfs_tools/vdfs_tool/#opening-files-directly-from-a-volume","title":"Opening files directly from a volume","text":"

To avoid wasting time unpacking the volume, double-click on the file of interest, after which it will be opened.

  1. This is mostly a translation of the orginal release post.\u00a0\u21a9

"},{"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 games based on ZenGin. It replaces the original DirectMusic system with a custom engine built on top of BASS Library to provide easier workflow for composers and additional functions for the perfect soundtrack design.

Info

The plugin has its very own docuentation site, if you are interested in including zBassMusic into your project see the detailed User Guide.

Contacts Authors Silver Ore Team - tehe GitHub zBassMusic Discord Gothic Modding Community server"},{"location":"zengin/union/plugins/zbassmusic/#features","title":"Features","text":""},{"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":""},{"location":"zengin/union/plugins/zgamepad/#features","title":"Features","text":""},{"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

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:

"},{"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:

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:

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:

Engines:

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:\n            gothicVersion = \"Gothic I\";\n            break;\n        case Engine_G1A:\n            gothicVersion = \"Gothic Sequel\";\n            break;\n        case Engine_G2:\n            gothicVersion = \"Gothic II\";\n            break;\n        case Engine_G2A:\n            gothicVersion = \"Gothic II NoTR\";\n            break;\n        default:\n            gothicVersion = \"Not possible case. Engine version doesn't match any known engine.\";\n            break;\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:

"},{"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:

Asides from those elements, there are also many invisible VOBs, such as:

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:

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:

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:

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":"

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.

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.

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:

"},{"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/zCMaterial/","title":"zCMaterial","text":""},{"location":"zengin/worlds/Classes/zCMaterial/#zcmaterial","title":"zCMaterial","text":"

Quick Infos

Class Name: zCMaterial Sources: \u2014 spacerhilfedatei.sph \u2014 gothic-library.ru

zCMaterial class describes the properties of the game materials.

Danger

zCMaterial objects are only saved in binary .ZEN files.

"},{"location":"zengin/worlds/Classes/zCMaterial/#class-members","title":"Class members","text":"Gothic 1Gothic 2 "},{"location":"zengin/worlds/Classes/zCMaterial/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCMaterial/#defaultmapping","title":"defaultMapping","text":"

Default material mapping.

"},{"location":"zengin/worlds/Classes/zCMaterial/#name","title":"name","text":"

Material name. In most cases corresponds to the name of the texture map.

"},{"location":"zengin/worlds/Classes/zCMaterial/#matgroup","title":"matGroup","text":"

Sound accompaniment of the material. Must be specified to produce the correct sounds when moving across the specified material.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCMaterial/#color","title":"color","text":"

Texture replacement color in RGBA format. Polygon is in this color until engine applies the texture.

"},{"location":"zengin/worlds/Classes/zCMaterial/#smoothangle","title":"smoothAngle","text":"

Defines the angle of material smoothing between two faces.

"},{"location":"zengin/worlds/Classes/zCMaterial/#texture","title":"texture","text":"

Defines the name of the texture file used for the material, which also determines whether the texture is animated or static.

To create animated textures, add a suffix to the file name _A0, e.g., NW_Fire_A0.TGA, NW_Fire_A1.TGA etc. The texture NW_Fire_A0.TGA is the first frame. The game engine will automatically search your hard drive for remaining animation files.

"},{"location":"zengin/worlds/Classes/zCMaterial/#texscale","title":"texScale","text":"

Defines the scaling along the X and Y axes. Assigns the necessary texture coordinates to polygons.

"},{"location":"zengin/worlds/Classes/zCMaterial/#texanifps","title":"texAniFPS","text":"

Defines the FPS (frames per seconds) of texture animation, but only if the texture is animated (NAME_A0.*).

"},{"location":"zengin/worlds/Classes/zCMaterial/#texanimapmode","title":"texAniMapMode","text":"

Texture animation mode.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCMaterial/#texanimapdir","title":"texAniMapDir","text":"

Defines the direction and movement speed of animated textures. The values should be significantly lower than 1 (For example 0.00005).

Danger

The animation movement is only enabled when texAniMapMode is set to LINEAR mode.

"},{"location":"zengin/worlds/Classes/zCMaterial/#nocolldet","title":"noCollDet","text":"

Defines if collision detection is disabled.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCMaterial/#nolightmap","title":"noLightmap","text":"

Defines if light map is disabled.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCMaterial/#loddontcollapse","title":"lodDontCollapse","text":"

If you activate this option, the texture will not degrade when the camera moves away.

Accepted values:

Note

To prevent the texture from being distorted, you can cancel the creation of a MipMap. It is advisable to use for small objects.

"},{"location":"zengin/worlds/Classes/zCMaterial/#detailobject","title":"detailObject","text":"

An option that allows you to complement the material with an additional texture.

"},{"location":"zengin/worlds/Classes/zCMaterial/#detailobjectscale","title":"detailObjectScale","text":"

Tiling of the overlay image selected in the detailObject property.

Warning

This option is only available in Gothic II (Spacer2).

"},{"location":"zengin/worlds/Classes/zCMaterial/#forceoccluder","title":"forceOccluder","text":"

No information provided.

Accepted values:

Warning

This option is only available in Gothic II (Spacer2).

"},{"location":"zengin/worlds/Classes/zCMaterial/#environmentalmapping","title":"environmentalMapping","text":"

Environment mapping mode. Creates glare on the texture.

Accepted values:

Warning

This option is only available in Gothic II (Spacer2).

"},{"location":"zengin/worlds/Classes/zCMaterial/#environmentalmappingstrength","title":"environmentalMappingStrength","text":"

The strength of environmental reflection on a model.

Warning

This option is only available in Gothic II (Spacer2).

"},{"location":"zengin/worlds/Classes/zCMaterial/#wavemode","title":"waveMode","text":"

Enable wave simulation mode. For example, AMBIENT_GROUND is used for water textures.

Accepted values:

Warning

This option is only available in Gothic II (Spacer2).

"},{"location":"zengin/worlds/Classes/zCMaterial/#wavespeed","title":"waveSpeed","text":"

Wave speed.

Accepted values:

Warning

This option is only available in Gothic II (Spacer2).

"},{"location":"zengin/worlds/Classes/zCMaterial/#wavemaxamplitude","title":"waveMaxAmplitude","text":"

Maximum wave amplitude.

Warning

This option is only available in Gothic II (Spacer2).

"},{"location":"zengin/worlds/Classes/zCMaterial/#wavegridsize","title":"waveGridSize","text":"

Wave mesh size.

Warning

This option is only available in Gothic II (Spacer2).

"},{"location":"zengin/worlds/Classes/zCMaterial/#ignoresunlight","title":"ignoreSunLight","text":"

Defines if the material ignores sunlight (doesn't cast shadows).

Accepted values:

Warning

This option is only available in Gothic II (Spacer2).

"},{"location":"zengin/worlds/Classes/zCMaterial/#alphafunc","title":"alphaFunc","text":"

Alpha channel blending function.

Accepted values:

Warning

This option is only available in Gothic II (Spacer2).

"},{"location":"zengin/worlds/Classes/zCVob/","title":"zCVob","text":""},{"location":"zengin/worlds/Classes/zCVob/#zcvob","title":"zCVob","text":"

Quick Infos

Class Name: zCVob Version Identifiers: \u2014 Gothic I: 12289 \u2014 Gothic II: 52224 Sources: \u2014 spacerhilfedatei.sph \u2014 gothic-library.ru \u2014 zk.gothickit.dev

Represents so-called virtual objects which appear in the game world. zCVob is the base class for all virtual objects which include everything from static models like boxes to interactive elements like doors and chests and invisible trigger objects.

"},{"location":"zengin/worlds/Classes/zCVob/#class-members","title":"Class members","text":"

Properties of a zCVob class are split into two parts. The Internals are hardly ever needed to be edited manually, they are changed 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.

Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCVob/#pack","title":"pack","text":"

Internal property which indicates how the data associated with this virtual object is stored.

"},{"location":"zengin/worlds/Classes/zCVob/#presetname","title":"presetName","text":"

The name of the template that was used to create this virtual object.

"},{"location":"zengin/worlds/Classes/zCVob/#bbox3dws","title":"bbox3DWS","text":"

The 3-dimensional bounding box of this virtual object. Defined by two opposite diagonal points (1x, 1y, 1z, 2x, 2y, 2z). This is used in conjunction with cdStatic and cdDyn calculate collisions and interactions with other game objects (NPCs, items, 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 Spacer.

"},{"location":"zengin/worlds/Classes/zCVob/#trafoostowsrot","title":"trafoOSToWSRot","text":"

The rotation of this virtual object in world space, represented by a 3x3 rotation matrix.

"},{"location":"zengin/worlds/Classes/zCVob/#trafoostowspos","title":"trafoOSToWSPos","text":"

Coordinates of the object in world space relative to the center.

Note

This refers to the center of coordinates of the .3DS file of the game world on which the ZEN file is built.

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.

"},{"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 visual component associated with this object, usually a name of a file.

Following formats are supported:

"},{"location":"zengin/worlds/Classes/zCVob/#showvisual","title":"showVisual","text":"

Indicates whether this object should display its visual.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/#visualcamalign","title":"visualCamAlign","text":"

Option to align objects relative to the camera.

Accepted values:

Note

This may be used with grass or flowers which only consist of a 2-dimensional sprite to have it always face the camera.

"},{"location":"zengin/worlds/Classes/zCVob/#visualanimode","title":"visualAniMode","text":"

Wind simulation option. Used in conjunction with the visualAniModeStrength parameter.

Accepted values:

Warning

This option is only available in Gothic II (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 II (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 zCVob drawing range is the same as the draw distance specified in zCZoneVobFarPlane object.

Warning

This option is only available in Gothic II (Spacer2).

"},{"location":"zengin/worlds/Classes/zCVob/#cdstatic","title":"cdStatic","text":"

Determines if the virtual object will collide with the static objects (world mesh and other VOBs with cdStatic on).

Accepted values:

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 virtual object will collide with dynamic objects (NPCs, items, etc.). This basically determines if the object has collision during gameplay.

Accepted values:

"},{"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:

Note

The shadow is calculated when compiling light in Low, Middle or High mode.

"},{"location":"zengin/worlds/Classes/zCVob/#dynshadow","title":"dynShadow","text":"

Indicates whether the object will cast a shadow when affected by dynamic light (e.g. torches).

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/#zbias","title":"zbias","text":"

The depth-bias for this virtual object.

Can be used remove texture flickering if a .TGA file is used as rendering.

Warning

This option is only available in Gothic II (Spacer2).

"},{"location":"zengin/worlds/Classes/zCVob/#isambient","title":"isAmbient","text":"

Indicates that this virtual object is ambient. It looks like this setting was a system used during development when access to the game's source code was available. Basically, the global variable zCWorld::s_bAmbientVobsEnabled could be used to hide or show virtual objects which have the isAmbient flag set. In release builds, this variable is always set to true, thus the isAmbient flag does not have any perceivable effect on the game. It follows, that this field should be ignored by most implementations.

Warning

This option is only available in Gothic II (Spacer2).

"},{"location":"zengin/worlds/Classes/zCVob/#sleepmode","title":"sleepMode","text":"

Unknown.

Warning

This property is only available in saved games.

"},{"location":"zengin/worlds/Classes/zCVob/#nextontimer","title":"nextOnTimer","text":"

Unknown.

Warning

This property is only available in saved games.

"},{"location":"zengin/worlds/Classes/zCVob/zCCSCamera/","title":"zCCSCamera","text":""},{"location":"zengin/worlds/Classes/zCVob/zCCSCamera/#zccscamera","title":"zCCSCamera","text":"

Quick Infos

Type: Virtual Object Format Name: ZenGin Archive File Extension: .ZEN Class Name: zCCSCamera Version Identifiers: \u2014 Gothic I: 30720 \u2014 Gothic II: 33793 ZenKit Class: VCutsceneCamera Sources: \u2014 gothic-library.ru \u2014 zk.gothickit.dev

"},{"location":"zengin/worlds/Classes/zCVob/zCCSCamera/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCCSCamera/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCVob/zCCSCamera/#camtrjfor","title":"camTrjFOR","text":"

The coordinate system of the key frames of the camera trajectory.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCCSCamera/#targettrjfor","title":"targetTrjFOR","text":"

The keyframe coordinate system of the target camera trajectory.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCCSCamera/#loopmode","title":"loopMode","text":"

The repetition mode of the camera animation.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCCSCamera/#spllerpmode","title":"splLerpMode","text":"

Adjust camera orientation while moving.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCCSCamera/#ignoreforvobrotcam","title":"ignoreFORVobRotCam","text":"

Determines whether the orientation to reference VOB objects should be taken into account when passing through key frames.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCCSCamera/#ignoreforvobrottarget","title":"ignoreFORVobRotTarget","text":"

Determines the need to take into account the orientation of target key frames to reference VOB objects.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCCSCamera/#adapttosurroundings","title":"adaptToSurroundings","text":"

Indicates the need for dynamic adaptation to the environment.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCCSCamera/#easetofirstkey","title":"easeToFirstKey","text":"

Gives a smooth transition of camera position from the first keyframe to the last, if possible.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCCSCamera/#easefromlastkey","title":"easeFromLastKey","text":"

Gives a smooth transition of camera position from the last keyframe to the first, if possible.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCCSCamera/#totaltime","title":"totalTime","text":"

The duration of the camera animation in seconds.

"},{"location":"zengin/worlds/Classes/zCVob/zCCSCamera/#autocamfocusvobname","title":"autoCamFocusVobName","text":"

The name of the VOB object which the camera will automatically focus.

"},{"location":"zengin/worlds/Classes/zCVob/zCCSCamera/#autocamplayermovable","title":"autoCamPlayerMovable","text":"

Indicates whether the player will be able to move when moving the camera animation.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCCSCamera/#autocamuntriggeronlastkey","title":"autoCamUntriggerOnLastKey","text":"

Emit an OnUntrigger event after reaching the last animation frame.

"},{"location":"zengin/worlds/Classes/zCVob/zCCSCamera/#autocamuntriggeronlastkeydelay","title":"autoCamUntriggerOnLastKeyDelay","text":"

Unclear.

"},{"location":"zengin/worlds/Classes/zCVob/zCCSCamera/#numpos","title":"numPos","text":"

The number of position key frames for the camera animation.

Warning

This property is not available in the Spacer.

"},{"location":"zengin/worlds/Classes/zCVob/zCCSCamera/#numtargets","title":"numTargets","text":"

The number of target key frames for the camera animation.

Warning

This property is not available in the Spacer.

"},{"location":"zengin/worlds/Classes/zCVob/zCCSCamera/#paused","title":"paused","text":"

Unknown.

Warning

This property is only available in saved games made using Gothic II.

"},{"location":"zengin/worlds/Classes/zCVob/zCCSCamera/#started","title":"started","text":"

Unknown.

Warning

This property is only available in saved games made using Gothic II.

"},{"location":"zengin/worlds/Classes/zCVob/zCCSCamera/#gototimemode","title":"gotoTimeMode","text":"

Unknown.

Warning

This property is only available in saved games made using Gothic II.

"},{"location":"zengin/worlds/Classes/zCVob/zCCSCamera/#cstime","title":"csTime","text":"

Unknown.

Warning

This property is only available in saved games made using Gothic II.

  1. A list of position key frames. The number of items is indicated by the numPos property.\u00a0\u21a9\u21a9\u21a9\u21a9

  2. A list of target key frames. The number of items is indicated by the numTargets property.\u00a0\u21a9\u21a9\u21a9\u21a9

"},{"location":"zengin/worlds/Classes/zCVob/zCCamTrj_KeyFrame/","title":"zCCamTrj_KeyFrame","text":""},{"location":"zengin/worlds/Classes/zCVob/zCCamTrj_KeyFrame/#zccamtrj_keyframe","title":"zCCamTrj_KeyFrame","text":"

Quick Infos

Type: Virtual Object Format Name: ZenGin Archive File Extension: .ZEN Class Name: zCCamTrj_KeyFrame Version Identifiers: \u2014 Gothic I: 12289 \u2014 Gothic II: 52224 ZenKit Class: VCameraTrajectoryFrame Sources: \u2014 gothic-library.ru \u2014 zk.gothickit.dev

"},{"location":"zengin/worlds/Classes/zCVob/zCCamTrj_KeyFrame/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCCamTrj_KeyFrame/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCVob/zCCamTrj_KeyFrame/#time","title":"time","text":"

Unclear.

"},{"location":"zengin/worlds/Classes/zCVob/zCCamTrj_KeyFrame/#anglerolldeg","title":"angleRollDeg","text":"

The camera rotation angle of the frame along the Z axis.

"},{"location":"zengin/worlds/Classes/zCVob/zCCamTrj_KeyFrame/#camfovscale","title":"camFOVScale","text":"

Focal zoom of the camera's field of view (FOV) of the frame. Use reasonable values to avoid dizzying effects.

"},{"location":"zengin/worlds/Classes/zCVob/zCCamTrj_KeyFrame/#motiontype","title":"motionType","text":"

The type of camera movement for the frame.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCCamTrj_KeyFrame/#motiontypefov","title":"motionTypeFOV","text":"

The type of focus change for the frame.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCCamTrj_KeyFrame/#motiontyperoll","title":"motionTypeRoll","text":"

The type of rotation for the frame.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCCamTrj_KeyFrame/#motiontypetimescale","title":"motionTypeTimeScale","text":"

Unclear.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCCamTrj_KeyFrame/#tension","title":"tension","text":"

Defines the bend of the camera motion curve at the specified key. Larger values result in a sharper bend.

"},{"location":"zengin/worlds/Classes/zCVob/zCCamTrj_KeyFrame/#bias","title":"bias","text":"

Determines the slope of a line in one direction. The direction of the slope is determined by the sign, and the steepness by the value.

"},{"location":"zengin/worlds/Classes/zCVob/zCCamTrj_KeyFrame/#continuity","title":"continuity","text":"

Determines the amount of curve discontinuity at this animation key.

"},{"location":"zengin/worlds/Classes/zCVob/zCCamTrj_KeyFrame/#timescale","title":"timeScale","text":"

Unknown.

"},{"location":"zengin/worlds/Classes/zCVob/zCCamTrj_KeyFrame/#timeisfixed","title":"timeIsFixed","text":"

An auxiliary flag indicating the time of the key frame, which cannot be changed automatically.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCCamTrj_KeyFrame/#originalpose","title":"originalPose","text":"

Unknown.

Warning

This property is not available in the Spacer.

"},{"location":"zengin/worlds/Classes/zCVob/zCVobLevelCompo/","title":"zCVobLevelCompo","text":""},{"location":"zengin/worlds/Classes/zCVob/zCVobLevelCompo/#zcvoblevelcompo","title":"zCVobLevelCompo","text":"

Quick Infos

Class Name: zCVobLevelCompo Version Identifiers: \u2014 Gothic I: 12289 \u2014 Gothic II: 52224 Sources: \u2014 gothic-library.ru \u2014 zk.gothickit.dev

Used as root objects of game levels. Only used to group together other VObjects. Only one of the zCVobLevelCompo objects will have a visual which corresponds to the mesh of the world it exists in. Generally, it can be ignored and has no relevance to other VObjects in the hierarchy.

"},{"location":"zengin/worlds/Classes/zCVob/zCVobLevelCompo/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCVobLight/","title":"zCVobLight","text":""},{"location":"zengin/worlds/Classes/zCVob/zCVobLight/#zcvoblight","title":"zCVobLight","text":"

Quick Infos

Type: Virtual Object Format Name: ZenGin Archive File Extension: .ZEN Class Name: zCVobLight Version Identifiers: \u2014 Gothic I: 46080 \u2014 Gothic II: 39168 ZenKit Class: VLight Sources: \u2014 spacerhilfedatei.sph \u2014 gothic-library.ru \u2014 zk.gothickit.dev

Represents a virtual light source which lights up nearby game objects. Point and spot light sources are supported and may be animated with different colors and ranges.

"},{"location":"zengin/worlds/Classes/zCVob/zCVobLight/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCVobLight/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCVob/zCVobLight/#lightpresetinuse","title":"lightPresetInUse","text":"

The name of the selected light template. Templates can be found in _work/data/Presets/LightPresets.zen. This property is irrelevant for most use-cases.

"},{"location":"zengin/worlds/Classes/zCVob/zCVobLight/#lighttype","title":"lightType","text":"

The type of the light source.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCVobLight/#range","title":"range","text":"

The range in which this light source illuminates objects.

"},{"location":"zengin/worlds/Classes/zCVob/zCVobLight/#color","title":"color","text":"

The color of this light source in RGBA form.

"},{"location":"zengin/worlds/Classes/zCVob/zCVobLight/#spotconeangle","title":"spotConeAngle","text":"

The angle of the beam cone for spotlights. Only relevant if lightType is SPOT, ignored otherwise.

"},{"location":"zengin/worlds/Classes/zCVob/zCVobLight/#lightstatic","title":"lightStatic","text":"

Determines whether this is a static light or not. Static lights are baked into the world when its lighting is compiled. This makes static lights faster at runtime, but it also means, that they cannot change in any way after the world is compiled.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCVobLight/#lightquality","title":"lightQuality","text":"

Determines the quality of the light source. What exactly changes with these values is unknown.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCVobLight/#lensflarefx","title":"lensflareFX","text":"

The name of the lensflare effect associated with this light. Empty if there is no associated lensflare effect.

"},{"location":"zengin/worlds/Classes/zCVob/zCVobLight/#turnedon","title":"turnedOn","text":"

Whether this dynamic light is turned on.

Accepted values:

Warning

This value is only valid for dynamic lights. Check lightStatic before use.

"},{"location":"zengin/worlds/Classes/zCVob/zCVobLight/#rangeaniscale","title":"rangeAniScale","text":"

Frames for the light's range animation. Its value is a space-separated list of floats where each float is one key frame of the animation. A value of 1.0 corresponds to the initial range of the light source, a value of 2.0 corresponds to double the initial range and a value of 0.5 means half the initial range. The range animation is further controlled by rangeAniFPS and rangeAniSmooth.

Warning

This value is only valid for dynamic lights. Check lightStatic before use.

"},{"location":"zengin/worlds/Classes/zCVob/zCVobLight/#rangeanifps","title":"rangeAniFPS","text":"

The speed of the range animation in frames per second. The animation frames are defined in rangeAniScale

Warning

This value is only valid for dynamic lights. Check lightStatic before use.

"},{"location":"zengin/worlds/Classes/zCVob/zCVobLight/#rangeanismooth","title":"rangeAniSmooth","text":"

Whether the range animation should smoothly interpolate between keyframes.

Accepted values:

Warning

This value is only valid for dynamic lights. Check lightStatic before use.

"},{"location":"zengin/worlds/Classes/zCVob/zCVobLight/#coloranilist","title":"colorAniList","text":"

Frames for the light's color animation. Its value is a space-separated list of colors where each element can either be an RGB color consisting of three integers enclosed by parentheses or a greyscale color consisting of a single integer. For example: (255 0 0) 100 (255 50 180) would result in #ff0000 #646464, #ff32b4. The color animation is further controlled by colorAniFPS and colorAniSmooth.

Warning

This value is only valid for dynamic lights. Check lightStatic before use.

"},{"location":"zengin/worlds/Classes/zCVob/zCVobLight/#coloranifps","title":"colorAniFPS","text":"

The speed of the color animation in frames per second. The animation frames are defined in colorAniList

Warning

This value is only valid for dynamic lights. Check lightStatic before use.

"},{"location":"zengin/worlds/Classes/zCVob/zCVobLight/#coloranismooth","title":"colorAniSmooth","text":"

Whether the color animation should smoothly interpolate between keyframes.

Accepted values:

Warning

This value is only valid for dynamic lights. Check lightStatic before use.

"},{"location":"zengin/worlds/Classes/zCVob/zCVobLight/#canmove","title":"canMove","text":"

Unknown.

Warning

This value is only valid for dynamic lights in Gothic II. Check lightstatic before use.

"},{"location":"zengin/worlds/Classes/zCVob/zCVobSpot/","title":"zCVobSpot","text":""},{"location":"zengin/worlds/Classes/zCVob/zCVobSpot/#zcvobspot","title":"zCVobSpot","text":"

Quick Infos

Class Name: zCVobSpot Version Identifiers: \u2014 Gothic I: 12289 \u2014 Gothic II: 52224 Sources: \u2014 spacerhilfedatei.sph \u2014 gothic-library.ru \u2014 zk.gothickit.dev

Spot objects are used to mark a position and orientation in virtual space. They are equivalent in function to way net free points and can be used in scripts to spawn other objects at their location.

"},{"location":"zengin/worlds/Classes/zCVob/zCVobSpot/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCVobStair/","title":"zCVobStair","text":""},{"location":"zengin/worlds/Classes/zCVob/zCVobStair/#zcvobstair","title":"zCVobStair","text":"

Quick Infos

Class Name: zCVobStair Version Identifiers: \u2014 Gothic I: 12289 \u2014 Gothic II: Unused Sources: \u2014 spacerhilfedatei.sph \u2014 gothic-library.ru \u2014 zk.gothickit.dev

Used to mark staircase models in Gothic I only. This type of VObject was taken into account by the NPC pathfinding routines to properly ascend and descend staircases.

Warning

This VObject is only available in Gothic I.

"},{"location":"zengin/worlds/Classes/zCVob/zCVobStair/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save)

Unavailable.

Unavailable.

"},{"location":"zengin/worlds/Classes/zCVob/zCVobStartpoint/","title":"zCVobStartpoint","text":""},{"location":"zengin/worlds/Classes/zCVob/zCVobStartpoint/#zcvobstartpoint","title":"zCVobStartpoint","text":"

Quick Infos

Class Name: zCVobStartpoint Version Identifiers: \u2014 Gothic I: 12289 \u2014 Gothic II: 52224 Sources: \u2014 spacerhilfedatei.sph \u2014 gothic-library.ru \u2014 zk.gothickit.dev

Marks the players initial position when loading in the game level. Behaves like zCVobSpot but causes the game to put the player at its location and in its orientation when the world is loaded.

"},{"location":"zengin/worlds/Classes/zCVob/zCVobStartpoint/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/oCVob/","title":"oCVob","text":""},{"location":"zengin/worlds/Classes/zCVob/oCVob/#ocvob","title":"oCVob","text":"

Quick Infos

Class Name: oCVob Version Identifiers: \u2014 Gothic I: 12289 \u2014 Gothic II: Unused Sources: \u2014 zk.gothickit.dev

Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCItem/","title":"oCItem","text":""},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCItem/#ocitem","title":"oCItem","text":"

Quick Infos

Class Name: oCItem Version Identifiers: \u2014 Gothic I: 0 \u2014 Gothic II: 0 Sources: \u2014 gothic-library.ru \u2014 zk.gothickit.dev

Represents an item in the game world. Items are special VObjects which are tied to a script instance which defines their attributes. They have physics enabled and can be targeted and picked up by the player.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCItem/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCItem/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCItem/#iteminstance","title":"itemInstance","text":"

The name of the script instance representing the item.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCItem/#amount","title":"amount","text":"

Unknown.

Warning

This property is only available in saved games.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCItem/#flags","title":"flags","text":"

Unknown.

Warning

This property is only available in saved games.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/","title":"oCMOB","text":""},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/#ocmob","title":"oCMOB","text":"

Quick Infos

Class Name: oCMOB Version Identifiers: \u2014 Gothic I: 47105 \u2014 Gothic II: 47105 Sources: \u2014 spacerhilfedatei.sph \u2014 gothic-library.ru \u2014 zk.gothickit.dev

A VObject which can optionally be moved and/or carried.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/#focusname","title":"focusName","text":"

The name of the object as seen in-game when focusing it.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/#hitpoints","title":"hitpoints","text":"

The number of hitpoints of the object.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/#damage","title":"damage","text":"

The damage dealt by the object when being used.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/#moveable","title":"moveable","text":"

Whether the object can be moved by the player.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/#takeable","title":"takeable","text":"

Whether the object can be carried by the player.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/#focusoverride","title":"focusOverride","text":"

Unknown.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/#soundmaterial","title":"soundMaterial","text":"

The sound to play when the object is hit.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/#visualdestroyed","title":"visualDestroyed","text":"

The name of the visual to use when the object is destroyed. Behaves like zCVob.visual.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/#owner","title":"owner","text":"

The name of the script instance of the NPC who is the owner of this object.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/#ownerguild","title":"ownerGuild","text":"

The name of the guild this object belongs to. This name corresponds to the script constant for each guild (i.e. GIL_BAU), found in Constants.d.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/#isdestroyed","title":"isDestroyed","text":"

Unknown.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/","title":"oCMobInter","text":""},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/#ocmobinter","title":"oCMobInter","text":"

Quick Infos

Class Name: oCMobInter Version Identifiers: \u2014 Gothic I: 35585 \u2014 Gothic II: 35585 Sources: \u2014 spacerhilfedatei.sph \u2014 gothic-library.ru \u2014 zk.gothickit.dev

Interactive objects can be interacted with by NPCs and the player. Every time the object is interacted with, an OnTrigger event is sent to the triggerTarget object.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/#statenum","title":"stateNum","text":"

Unknown.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/#triggertarget","title":"triggerTarget","text":"

The name of the VObject(s) to send an OnTrigger event to when this object is interacted with. Controlled by the rewind property.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/#usewithitem","title":"useWithItem","text":"

The name of the item which the player or NPC must have in their inventory in order to interact with the object. Corresponds to the name of the item instance in the scripts.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/#conditionfunc","title":"conditionFunc","text":"

The name of a script function which, when called, determines whether the object can be interacted with. The script function returns an int which is either 0, if the object should be disabled and 1 if it should be enabled.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/#onstatefunc","title":"onStateFunc","text":"

The name of a script function to be called when the object is being used.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/#rewind","title":"rewind","text":"

Determines whether an OnTrigger event should be sent every time the object is interacted with or only the first time.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobBed/","title":"oCMobBed","text":""},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobBed/#ocmobbed","title":"oCMobBed","text":"

Quick Infos

Type: Virtual Object Format Name: ZenGin Archive File Extension: .ZEN Class Name: oCMobBed Version Identifiers: \u2014 Gothic I: 35585 \u2014 Gothic II: 35585 ZenKit Class: VBed Sources: \u2014 spacerhilfedatei.sph \u2014 zk.gothickit.dev

VObject marking beds for NPCs and the player to sleep on. In the original Gothic I, there is a bug which prevents oCMobBeds from working correctly, so it is recommended to instead use oCMobDoor and attach the visual of a bed when targeting that platform.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobBed/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobFire/","title":"oCMobFire","text":""},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobFire/#ocmobfire","title":"oCMobFire","text":"

Quick Infos

Class Name: oCMobFire Version Identifiers: \u2014 Gothic I: 18433 \u2014 Gothic II: 18433 Sources: \u2014 gothic-library.ru \u2014 zk.gothickit.dev

An object with an integrated fire effect. Only supports rigged models as visuals.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobFire/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobFire/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobFire/#fireslot","title":"fireSlot","text":"

The bone of the rigged model to place the fire effect at.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobFire/#firevobtreename","title":"fireVobtreeName","text":"

The name of the template file which contains the configuration of the fire effect. For example: FIRETREE_MEDIUM.ZEN.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobLadder/","title":"oCMobLadder","text":""},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobLadder/#ocmobladder","title":"oCMobLadder","text":"

Quick Infos

Class Name: oCMobLadder Version Identifiers: \u2014 Gothic I: 35585 \u2014 Gothic II: 35585 Sources: \u2014 spacerhilfedatei.sph \u2014 gothic-library.ru \u2014 zk.gothickit.dev

A VObject representing a ladder. NPCs can interact with ladders by climbing.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobLadder/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobSwitch/","title":"oCMobSwitch","text":""},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobSwitch/#ocmobswitch","title":"oCMobSwitch","text":"

Quick Infos

Class Name: oCMobSwitch Version Identifiers: \u2014 Gothic I: 35585 \u2014 Gothic II: 35585 Sources: \u2014 spacerhilfedatei.sph \u2014 zk.gothickit.dev

A VObject representing a switch with two states.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobSwitch/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobWheel/","title":"oCMobWheel","text":""},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobWheel/#ocmobwheel","title":"oCMobWheel","text":"

Quick Infos

Class Name: oCMobWheel Version Identifiers: \u2014 Gothic I: 35585 \u2014 Gothic II: 35585 Sources: \u2014 spacerhilfedatei.sph \u2014 zk.gothickit.dev

A wheel with four different states. For example, this is used for the gates of the old camp in Gothic I.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobWheel/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobLockable/","title":"oCMobLockable","text":""},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobLockable/#ocmoblockable","title":"oCMobLockable","text":"

Quick Infos

Class Name: oCMobLockable Version Identifiers: \u2014 Gothic I: 12289 \u2014 Gothic II: 52224 Sources: \u2014 zk.gothickit.dev

The base class for many lockable objects like containers and doors.

Warning

This object is an abstract base class and cannot be instantiated by itself.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobLockable/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobLockable/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobLockable/#locked","title":"locked","text":"

Determines whether the container is locked.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobLockable/#keyinstance","title":"keyInstance","text":"

The name of the item script instance which unlocks the container.

Tip

Only relevant if the container is locked.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobLockable/#picklockstr","title":"pickLockStr","text":"

The combination which unlocks this container when picking the lock. Each character of the string is either R or L where R stands for \"Right\" and L stands for \"Left\". If empty, the lock can not be picked. Example: LRRLLRL.

Tip

Only relevant if the container is locked.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobLockable/oCMobContainer/","title":"oCMobContainer","text":""},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobLockable/oCMobContainer/#ocmobcontainer","title":"oCMobContainer","text":"

Quick Infos

Class Name: oCMobContainer Version Identifiers: \u2014 Gothic I: 64513 \u2014 Gothic II: 64513 Sources: \u2014 spacerhilfedatei.sph \u2014 gothic-library.ru \u2014 zk.gothickit.dev

An object which contains items.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobLockable/oCMobContainer/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobLockable/oCMobContainer/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobLockable/oCMobContainer/#contains","title":"contains","text":"

The items found inside the container as a comma-separated list. Each element of the list starts with the name of the item script instance and is optionally followed by a colon and a number, indicating the number of that item to be found inside. Example: ItMi_Gold:75, ItFo_Fish:2, ItMi_Quartz.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobLockable/oCMobContainer/#numofentries","title":"NumOfEntries","text":"

The number of items in the container.

Warning

This property is only available in saved games.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobLockable/oCMobDoor/","title":"oCMobDoor","text":""},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobLockable/oCMobDoor/#ocmobdoor","title":"oCMobDoor","text":"

Quick Infos

Class Name: oCMobDoor Version Identifiers: \u2014 Gothic I: 64513 \u2014 Gothic II: 64513 Sources: \u2014 gothic-library.ru \u2014 zk.gothickit.dev

A VObject representing a door. This is also used for NPCs navigating the waynet.

"},{"location":"zengin/worlds/Classes/zCVob/oCVob/oCMOB/oCMobInter/oCMobLockable/oCMobDoor/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCEffect/","title":"zCEffect","text":""},{"location":"zengin/worlds/Classes/zCVob/zCEffect/#zceffect","title":"zCEffect","text":"

Quick Infos

Class Name: zCEffect Version Identifiers: \u2014 Gothic I: 12289 \u2014 Gothic II: 52224 Sources: \u2014 zk.gothickit.dev

The base class for many visual and sound effects.

Warning

This object is an abstract base class and cannot be instantiated by itself.

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCEarthquake/","title":"zCEarthquake","text":""},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCEarthquake/#zcearthquake","title":"zCEarthquake","text":"

Quick Infos

Class Name: zCEarthquake Version Identifiers: \u2014 Gothic I: Unused \u2014 Gothic II: 52224 Sources: \u2014 spacerhilfedatei.sph \u2014 gothic-library.ru \u2014 zk.gothickit.dev

A VObject used to create an earthquake effect when it receives an OnTrigger event. An earthquake is represented by a shaking camera.

Warning

This VObject is only available in Gothic II.

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCEarthquake/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save)

Unavailable

Unavailable

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCEarthquake/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCEarthquake/#radius","title":"radius","text":"

The radius of the earthquake effect

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCEarthquake/#timesec","title":"timeSec","text":"

The duration of the earthquake effect in seconds.

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCEarthquake/#amplitudecm","title":"amplitudeCM","text":"

The amplitude of the earthquake effect.

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCPFXControler/","title":"zCPFXController","text":""},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCPFXControler/#zcpfxcontroller","title":"zCPFXController","text":"

Quick Infos

Class Name: zCPFXControler Version Identifiers: \u2014 Gothic I: 12289 \u2014 Gothic II: 52224 Sources: \u2014 spacerhilfedatei.sph \u2014 gothic-library.ru \u2014 zk.gothickit.dev

A particle system in virtual space. Its effect can be activated and deactivated using the OnTrigger and OnUntrigger events.

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCPFXControler/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCPFXControler/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCPFXControler/#pfxname","title":"pfxName","text":"

The name of the particle effect. Corresponds to a .ZEN file containing the particle system definition.

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCPFXControler/#killvobwhendone","title":"killVobWhenDone","text":"

Disable the particle effect after it runs once.

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCPFXControler/#pfxstarton","title":"pfxStartOn","text":"

Whether to start the particle effect when the level is loaded.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCVobAnimate/","title":"zCVobAnimate","text":""},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCVobAnimate/#zcvobanimate","title":"zCVobAnimate","text":"

Quick Infos

Class Name: zCVobAnimate Version Identifiers: \u2014 Gothic I: 12289 \u2014 Gothic II: 52224 Sources: \u2014 spacerhilfedatei.sph \u2014 gothic-library.ru \u2014 zk.gothickit.dev

A VObject used to create animated models. The visual of such objects can either be a morph mesh or a model with a skeletal animation (i.e. a model script). The animation of these objects can be started and stopped using OnTrigger and OnUntrigger events.

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCVobAnimate/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCVobAnimate/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCVobAnimate/#starton","title":"startOn","text":"

Whether to start this animation when loading the level.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCVobAnimate/#isrunning","title":"isRunning","text":"

Unknown.

Warning

This property is only available in saved games.

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCVobLensFlare/","title":"zCVobLensFlare","text":""},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCVobLensFlare/#zcvoblensflare","title":"zCVobLensFlare","text":"

Quick Infos

Class Name: zCVobLensFlare Version Identifiers: \u2014 Gothic I: 64704 \u2014 Gothic II: 193 Sources: \u2014 spacerhilfedatei.sph \u2014 gothic-library.ru \u2014 zk.gothickit.dev

Represents a lens flare effect. Behaves exactly like the base zCVob but has a lens flare effect.

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCVobLensFlare/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCVobLensFlare/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCVobLensFlare/#lensflarefx","title":"lensflareFX","text":"

The name of the lens flare effect. Must be one of the effects listed in /_work/data/Presets/Lensflare.zen.

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCVobScreenFX/","title":"zCVobScreenFX","text":""},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCVobScreenFX/#zcvobscreenfx","title":"zCVobScreenFX","text":"

Quick Infos

Class Name: zCVobScreenFX Version Identifiers: \u2014 Gothic I: 12289 \u2014 Gothic II: 52224 Sources: \u2014 spacerhilfedatei.sph \u2014 gothic-library.ru \u2014 zk.gothickit.dev

Screen effect VObjects are used to create special effects. They are used for field-of-view changes, adding black bars for a cinematic feel to the game and other post-processing effects.

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCVobScreenFX/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCTouchAnimate/","title":"zCTouchAnimate","text":""},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCTouchAnimate/#zctouchanimate","title":"zCTouchAnimate","text":"

Quick Infos

Class Name: zCTouchAnimate Version Identifiers: \u2014 Gothic I: 12289 \u2014 Gothic II: 20483 Sources: \u2014 spacerhilfedatei.sph \u2014 gothic-library.ru

A VObject that plays its animation when it receives an OnTick event (basically when something touches it).

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCTouchAnimate/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCTouchAnimate/#presentation","title":"Presentation","text":"

Following video shows the behaviour of this VObject.

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCTouchAnimate/zCTouchAnimateSound/","title":"zCTouchAnimateSound","text":""},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCTouchAnimate/zCTouchAnimateSound/#zctouchanimatesound","title":"zCTouchAnimateSound","text":"

Quick Infos

Class Name: zCTouchAnimateSound Version Identifiers: \u2014 Gothic I: 12289 \u2014 Gothic II: 20483 Sources: \u2014 spacerhilfedatei.sph \u2014 gothic-library.ru

Object similar to zCTouchAnimate, but allowing to specify a sound that plays on the event activation.

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCTouchAnimate/zCTouchAnimateSound/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCTouchAnimate/zCTouchAnimateSound/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCTouchAnimate/zCTouchAnimateSound/#sfxtouch","title":"sfxTouch","text":"

The name of the sound produced upon contact with an object.

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCTouchAnimate/zCTouchAnimateSound/#presentation","title":"Presentation","text":"

Following video shows the behaviour of this VObject.

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCTouchDamage/","title":"zCTouchDamage","text":""},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCTouchDamage/#zctouchdamage","title":"zCTouchDamage","text":"

Quick Infos

Class Name: zCTouchDamage Version Identifiers: \u2014 Gothic I: 36865 \u2014 Gothic II: 36865 Source: \u2014 spacerhilfedatei.sph \u2014 gothic-library.ru \u2014 zk.gothickit.dev

A VObject which damages other VObjects colliding with it.

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCTouchDamage/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCTouchDamage/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCTouchDamage/#damage","title":"damage","text":"

The amount of damage being dealt.

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCTouchDamage/#barrier","title":"Barrier","text":"

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCTouchDamage/#blunt","title":"Blunt","text":"

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCTouchDamage/#edge","title":"Edge","text":"

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCTouchDamage/#fire","title":"Fire","text":"

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCTouchDamage/#fly","title":"Fly","text":"

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCTouchDamage/#magic","title":"Magic","text":"

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCTouchDamage/#point","title":"Point","text":"

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCTouchDamage/#fall","title":"Fall","text":"

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCTouchDamage/#damagerepeatdelaysec","title":"damageRepeatDelaySec","text":"

The delay between damage ticks when applying continuous damage. If set to 0, only deals the damage once per collision. If set to a value greater than 0, deals damage every damageRepeatDelaySec seconds.

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCTouchDamage/#damagevoldownscale","title":"damageVolDownScale","text":"

A scale value used in conjunction with damageCollType. Its function depends on the type of collision detection used.

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCTouchDamage/#damagecolltype","title":"damageCollType","text":"

The type of collision detection to use for damage calculations.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCTouchDamage/oCTouchDamage/","title":"oCTouchDamage","text":""},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCTouchDamage/oCTouchDamage/#octouchdamage","title":"oCTouchDamage","text":"

Quick Infos

Class Name: oCTouchDamage Version Identifiers: \u2014 Gothic I: 36865 \u2014 Gothic II: 36865 ZenKit Class: VTouchDamage Sources: \u2014 zk.gothickit.dev

"},{"location":"zengin/worlds/Classes/zCVob/zCEffect/zCTouchDamage/oCTouchDamage/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/","title":"zCTriggerBase","text":""},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/#zctriggerbase","title":"zCTriggerBase","text":"

Quick Infos

Class Name: zCTriggerBase Version Identifiers: \u2014 Gothic I: 12289 \u2014 Gothic II: 52224 Sources: \u2014 zk.gothickit.dev

The base class for many triggers.

Warning

This object is an abstract base class and cannot be instantiated by itself.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/#triggertarget","title":"triggerTarget","text":"

The name of VObject to send OnTrigger and OnUntrigger events to after processing.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCCodeMaster/","title":"zCCodeMaster","text":""},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCCodeMaster/#zccodemaster","title":"zCCodeMaster","text":"

Quick Infos

Class Name: zCCodeMaster Version Identifiers: \u2014 Gothic I: 0 \u2014 Gothic II: 0 Source: \u2014 spacerhilfedatei.sph \u2014 gothic-library.ru \u2014 zk.gothickit.dev

zCCodeMaster VObjects keep a list of 'slave' VObjects and keep track of events received by them. If the master receives an OnTrigger event from a slave, it remembers that it did. After it has receives an OnTrigger message from all slaves, it emits an OnTrigger event to the triggerTarget. Receiving or sending an OnTrigger event is also referred to as an 'activation' for this purpose.

Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCCodeMaster/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCCodeMaster/#orderrelevant","title":"orderRelevant","text":"

Controls whether the master should keep track of the order it receives messages from its slaves.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCCodeMaster/#firstfalseisfailure","title":"firstFalseIsFailure","text":"

Controls when the slave activation sequence is considered to be incorrect. After the sequence is marked as incorrect an OnTrigger event is sent to triggerTargetFailure.

Accepted values:

Warning

Only relevant if orderRelevant is set to TRUE.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCCodeMaster/#triggertargetfailure","title":"triggerTargetFailure","text":"

The name of the VObject to emit an OnTrigger event to if the activation sequence fails. This is controlled by firstFalseIsFailure.

Warning

Only relevant if orderRelevant is set to TRUE.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCCodeMaster/#untriggercancels","title":"untriggerCancels","text":"

Controls whether slaves can emit OnUntrigger events to the master VObject to mark themselves as deactivated.

Accepted values:

Warning

Only relevant if orderRelevant is set to FALSE.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCCodeMaster/#slavevobname","title":"slaveVobName","text":"

The name of a slave VObject.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCCodeMaster/#numslavestriggered","title":"numSlavesTriggered","text":"

Unknown.

Warning

This property is only available in saved games.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCMessageFilter/","title":"zCMessageFilter","text":""},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCMessageFilter/#zcmessagefilter","title":"zCMessageFilter","text":"

Quick Infos

Class Name: zCMessageFilter Version Identifiers: \u2014 Gothic I: 0 \u2014 Gothic II: 0 Sources: \u2014 spacerhilfedatei.sph \u2014 zk.gothickit.dev

Transforms any incoming OnTrigger and OnUntrigger events before passing them on to the trigger target. All OnTrigger and OnUntrigger messages received by this zCMessageFilter VObject are transformed according to onTrigger and onUntrigger and then passed on to the VObject with the name specified in the triggerTarget.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCMessageFilter/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCMessageFilter/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCMessageFilter/#ontrigger","title":"onTrigger","text":"

The type of event to emit to the triggerTarget if this VObject receives an OnTrigger message.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCMessageFilter/#onuntrigger","title":"onUntrigger","text":"

The type of event to emit to the triggerTarget if this VObject receives an OnUntrigger message.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCMoverControler/","title":"zCMoverControler","text":""},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCMoverControler/#zcmovercontroler","title":"zCMoverControler","text":"

Quick Infos

Class Name: zCMoverControler Version Identifiers: \u2014 Gothic I: 0 \u2014 Gothic II: 0 Sources: \u2014 spacerhilfedatei.sph \u2014 gothic-library.ru \u2014 zk.gothickit.dev

A VObject used to control zCMover objects of type NSTATE_SINGLE_KEYS specifically. zCMoverControler objects react to incoming OnTrigger events to send a pre-configured event to the target mover object named by the triggerTarget propery, controlling its animation. Mover controllers can make movers go to a specific keyframe in their animation or just step one keyframe back and forth at a time.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCMoverControler/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCMoverControler/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCMoverControler/#movermessage","title":"moverMessage","text":"

The type of event to emit to the triggerTarget when this controller receives an OnTrigger event.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCMoverControler/#gotofixedkey","title":"gotoFixedKey","text":"

The keyframe of the mover referred to by triggerTarget to move to.

Warning

Only relevant if moverMessage is GOTO_KEY_FIXED_DIRECTLY or GOTO_KEY_FIXED_ORDER.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTriggerUntouch/","title":"zCTriggerUntouch","text":""},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTriggerUntouch/#zctriggeruntouch","title":"zCTriggerUntouch","text":"

Quick Infos

Class Name: zCTriggerUntouch Version Identifiers: \u2014 Gothic I: 52224 \u2014 Gothic II: 52224 Sources: \u2014 spacerhilfedatei.sph \u2014 zk.gothickit.dev

A trigger which fires an OnTrigger event to its triggerTarget if any OnUntouch event is emitted from an inanimate object within the object's bounding box.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTriggerUntouch/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTriggerWorldStart/","title":"zCTriggerWorldStart","text":""},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTriggerWorldStart/#zctriggerworldstart","title":"zCTriggerWorldStart","text":"

Quick Infos

Class Name: zCTriggerWorldStart Version Identifiers: \u2014 Gothic I: 52224 \u2014 Gothic II: 52224 Sources: \u2014 spacerhilfedatei.sph \u2014 zk.gothickit.dev

A special trigger which fires an OnTrigger event to its triggerTarget when the world is loaded and started.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTriggerWorldStart/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTriggerWorldStart/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTriggerWorldStart/#fireonlyfirsttime","title":"fireOnlyFirstTime","text":"

Determines whether to fire the OnTrigger event only the first time the world is loaded.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/","title":"zCTrigger","text":""},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/#zctrigger","title":"zCTrigger","text":"

Quick Infos

Class Name: zCTrigger Version Identifiers: \u2014 Gothic I: 47105 \u2014 Gothic II: 47105 Sources: \u2014 spacerhilfedatei.sph \u2014 gothic-library.ru \u2014 zk.gothickit.dev

VObject to process and relay specific filtered events. When a zCTrigger receives an OnTrigger, OnDamage, or OnTouch event it checks whether the event source (an oCNpc, the player or another VObject) should be acknowledged (see respondToNPC, respondToPC and respondToObject respectively). It then verifies if it should react to the specific event by checking the reactToOnTrigger, reactToOnDamage and reactToOnTouch properties. If both checks succeed, an OnTrigger event is sent to the triggerTarget and the trigger is considered to be activated. zCTrigger objects can be enabled and disabled by firing OnEnable, OnDisable and OnToggleEnabled events at them.

Tip

The respondTo{Object,PC,NPC,VobName} properties are logically linked by and \"or\" expression.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/#reacttoontrigger","title":"reactToOnTrigger","text":"

Whether this trigger should react to OnTrigger events.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/#reacttoontouch","title":"reactToOnTouch","text":"

Whether this trigger should react to OnTouch events.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/#reacttoondamage","title":"reactToOnDamage","text":"

Whether this trigger should react to OnDamage events.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/#respondtoobject","title":"respondToObject","text":"

Whether this trigger should process events coming from inanimate objects.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/#respondtopc","title":"respondToPC","text":"

Whether this trigger should process events coming from the player.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/#respondtonpc","title":"respondToNPC","text":"

Whether this trigger should process events coming from NPCs.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/#startenabled","title":"startEnabled","text":"

Determines whether the trigger is initially enabled. Enabled triggers will process incoming events and send outgoing events while disabled triggers do not. Triggers can be activated and deactivated at runtime by sending them OnEnable, OnDisable or OnToggleEnabled events.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/#respondtovobname","title":"respondToVobName","text":"

Whether this trigger should process events coming from VObjects with this name. If empty, match no VObject name directly.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/#numcanbeactivated","title":"numCanBeActivated","text":"

The number of times the trigger will process incoming events. If set to -1 the trigger will process an infinite number of events.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/#retriggerwaitsec","title":"retriggerWaitSec","text":"

The number of seconds that have to elapse after processing an event before the trigger will process additional events. All events received by the trigger during that time are ignored.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/#damagethreshold","title":"damageThreshold","text":"

The amount of damage which must be dealt for the trigger to react to an OnDamage event.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/#firedelaysec","title":"fireDelaySec","text":"

The number of seconds to wait before emitting the OnTrigger event after processing.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/#senduntrigger","title":"sendUntrigger","text":"

Whether to send and OnUntrigger event to the triggerTarget after the trigger receives an OnUntrigger or OnUntouch event. Only fires the OnUntrigger event if reactToOnTrigger and reactToOnTouch are set to TRUE respectively.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/#nexttimetriggerable","title":"nextTimeTriggerable","text":"

Unknown.

Warning

This property is only available in saved games.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/#savedothervob","title":"savedOtherVob","text":"

Unknown.

Warning

This property is only available in saved games.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/#countcanbeactivated","title":"countCanBeActivated","text":"

Unknown.

Warning

This property is only available in saved games.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/#isenabled","title":"isEnabled","text":"

Unknown.

Warning

This property is only available in saved games made using Gothic II.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/oCCSTrigger/","title":"oCCSTrigger","text":""},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/oCCSTrigger/#occstrigger","title":"oCCSTrigger","text":"

Quick Infos

Class Name: oCCSTrigger Version Identifiers: \u2014 Gothic I: 24577 \u2014 Gothic II: 24577 Sources: \u2014 spacerhilfedatei.sph \u2014 gothic-library.ru \u2014 zk.gothickit.dev

A special trigger VObject which can start a cutscene. The triggerTarget must be the name of the cutscene (without the extension) to be started. For this to work, the cutscene must already be loaded. OnUntrigger events are ignored by oCCSTriggers.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/oCCSTrigger/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/oCTriggerChangeLevel/","title":"oCTriggerChangeLevel","text":""},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/oCTriggerChangeLevel/#octriggerchangelevel","title":"oCTriggerChangeLevel","text":"

Quick Infos

Class Name: oCTriggerChangeLevel Version Identifiers: \u2014 Gothic I: 24577 \u2014 Gothic II: 24577 Sources: \u2014 spacerhilfedatei.sph \u2014 zk.gothickit.dev

A special zCTrigger which in addition to performing all other trigger actions also causes the engine to load another level when activated.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/oCTriggerChangeLevel/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/oCTriggerChangeLevel/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/oCTriggerChangeLevel/#levelname","title":"levelName","text":"

The name of the level to load including the file extension.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/oCTriggerChangeLevel/#startvobname","title":"startVobName","text":"

The name of the VObject in the new level to place the player at.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/oCTriggerScript/","title":"oCTriggerScript","text":""},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/oCTriggerScript/#octriggerscript","title":"oCTriggerScript","text":"

Quick Infos

Class Name: oCTriggerScript Version Identifiers: \u2014 Gothic I: 24577 \u2014 Gothic II: 24577 Sources: \u2014 spacerhilfedatei.sph \u2014 zk.gothickit.dev

A special zCTrigger which in addition to performing all other trigger actions also calls a script function when the trigger is activated. OnUntrigger events do not result in the script function being called.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/oCTriggerScript/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/oCTriggerScript/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/oCTriggerScript/#scriptfunc","title":"scriptFunc","text":"

The name script function to call when the trigger successfully processes a message.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCMover/","title":"zCMover","text":""},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCMover/#zcmover","title":"zCMover","text":"

Quick Infos

Class Name: zCMover Version Identifiers: \u2014 Gothic I: 39936 \u2014 Gothic II: 39936 Sources: \u2014 spacerhilfedatei.sph \u2014 gothic-library.ru \u2014 zk.gothickit.dev

A VObject which can move along a pre-determined path in response to an event. Movers can be controlled through a set of keyframes or the animation of their visuals. If the visual has an attached animation to be used as the mover's animation, it must have the following animations which are run depending on the mover's state: S_OPEN, S_CLOSED, T_CLOSED_2_OPEN, T_OPEN_2_CLOSED, S_LOCKED, S_UNLOCKED, T_UNLOCKED_TO_LOCKED, T_LOCKED_TO_UNLOCKED.

Each mover is in one of three states, \"open\", \"closed\" or \"moving\". Keyframe 0 (or S_OPEN when using the visual's animation) corresponds to the \"open\" state while the last keyframe (or S_CLOSED) corresponds to the \"closed\" state. When transitioning between the \"open\" and \"closed\" states, the mover is in the \"moving\" state during which it sequentially moves between its keyframes (or runs the T_CLOSED_2_OPEN or T_OPEN_TO_CLOSED animations). Movers with their moverBehavior set to NSTATE_SINGLE_KEYS are an exception to this rule: each keyframe can individually be addressed as a state.

Movers are specialized triggers. Before beginning their animation, movers first filter the incoming events as per the zCTrigger's rules and only start the animation if the event passes through the filters. When the mover reaches the \"open\" state after being activated, it emits an OnTrigger event according to the fire behavior set for the zCTrigger. Similarly, when it reaches the \"closed\" state it emits an OnUntrigger event.

Movers can be enabled and disabled using the OnEnable, OnDisable and OnToggleDisabled events.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCMover/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCMover/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCMover/#moverbehavior","title":"moverBehavior","text":"

Controls how the mover behaves in response to events (\"activation\").

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCMover/#touchblockerdamage","title":"touchBlockerDamage","text":"

The amount of damage to deal to objects in the way of the mover.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCMover/#stayopentimesec","title":"stayOpenTimeSec","text":"

The number of seconds a mover with the 2STATE_OPEN_TIMED behavior stays in the \"open\" state until transitioning to the \"closed\" state again.

Warning

Only relevant if moverBehavior is 2STATE_OPEN_TIMED.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCMover/#moverlocked","title":"moverLocked","text":"

Unclear.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCMover/#autolinkenabled","title":"autoLinkEnabled","text":"

Determines whether the position of the object triggering the mover should be tied to the mover's position.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCMover/#autorotate","title":"autoRotate","text":"

Whether to automatically rotate the mover along its movement trajectory. For example, this is used for making fish always face in the direction they're moving.

Accepted values:

Warning

Only available in Gothic II.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCMover/#numkeyframes","title":"numKeyframes","text":"

Unclear.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCMover/#movespeed","title":"moveSpeed","text":"

The movement speed for transitioning between keyframes in units per millisecond.

Warning

Only relevant if manually specified keyframes are used. Ignored when using the visual for the animation.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCMover/#poslerptype","title":"posLerpType","text":"

Defines how the mover should interpolate between the keyframe positions. Only affects the mover's position, never its rotation.

Accepted values:

Warning

Only relevant if manually specified keyframes are used. Ignored when using the visual for the animation.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCMover/#speedtype","title":"speedType","text":"

Controls the acceleration and deceleration behavior of the mover.

Accepted values:

Warning

Only relevant if manually specified keyframes are used. Ignored when using the visual for the animation.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCMover/#sfxopenstart","title":"sfxOpenStart","text":"

The name of the sound to play at the beginning of the opening sequence.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCMover/#sfxopenend","title":"sfxOpenEnd","text":"

The name of the sound to play at the end of the opening sequence.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCMover/#sfxmoving","title":"sfxMoving","text":"

The name of the sound to play in a loop while the mover is transitioning between keyframes.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCMover/#sfxclosestart","title":"sfxCloseStart","text":"

The name of the sound to play at the beginning of the closing sequence.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCMover/#sfxcloseend","title":"sfxCloseEnd","text":"

The name of the sound to play at the end of the closing sequence.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCMover/#sfxlock","title":"sfxLock","text":"

The name of the sound to play when locking a mover.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCMover/#sfxunlock","title":"sfxUnlock","text":"

The name of the sound to play when unlocking a mover.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCMover/#sfxuselocked","title":"sfxUseLocked","text":"

The name of the sound to play when using a locked mover.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCMover/#actkeyposdelta","title":"actKeyPosDelta","text":"

Unknown.

Warning

This property is only available in saved games.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCMover/#actkeyframef","title":"actKeyframeF","text":"

Unknown.

Warning

This property is only available in saved games.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCMover/#actkeyframe","title":"actKeyframe","text":"

Unknown.

Warning

This property is only available in saved games.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCMover/#nextkeyframe","title":"nextKeyframe","text":"

Unknown.

Warning

This property is only available in saved games.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCMover/#movespeedunit","title":"moveSpeedUnit","text":"

Unknown.

Warning

This property is only available in saved games.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCMover/#advancedir","title":"advanceDir","text":"

Unknown.

Warning

This property is only available in saved games.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCMover/#moverstate","title":"moverState","text":"

Unknown.

Warning

This property is only available in saved games.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCMover/#numtriggerevents","title":"numTriggerEvents","text":"

Unknown.

Warning

This property is only available in saved games.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCMover/#stayopentimedest","title":"stayOpenTimeDest","text":"

Unknown.

Warning

This property is only available in saved games.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCTriggerList/","title":"zCTriggerList","text":""},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCTriggerList/#zctriggerlist","title":"zCTriggerList","text":"

Quick Infos

Class Name: zCTriggerList Version Identifiers: \u2014 Gothic I: 59776 \u2014 Gothic II: 5505 Sources: \u2014 spacerhilfedatei.sph \u2014 gothic-library.ru \u2014 zk.gothickit.dev

A special trigger which emits the OnTrigger events emitted by the zCTrigger to multiple targets. How the events are sent can be configured through listProcess. The triggerTarget and fireDelaySec properties of zCTrigger should be ignored.

OnUntrigger events sent to the trigger list are propagated to all targets in the list.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCTriggerList/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCTriggerList/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCTriggerList/#listprocess","title":"listProcess","text":"

Controls how events are sent to the targets.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCTriggerList/#triggertarget","title":"triggerTarget","text":"

The name of the VObject to send events to. Behaves like triggerTarget.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCTriggerList/#firedelay","title":"fireDelay","text":"

The delay after which to fire the event to the target. Behaves like fireDelaySec.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCTriggerList/#acttarget","title":"actTarget","text":"

Unknown.

Warning

This property is only available in saved games.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCTriggerList/#sendontrigger","title":"sendOnTrigger","text":"

Unknown.

Warning

This property is only available in saved games.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCTriggerTeleport/","title":"zCTriggerTeleport","text":""},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCTriggerTeleport/#zctriggerteleport","title":"zCTriggerTeleport","text":"

Quick Infos

Class Name: zCTriggerTeleport Version Identifiers: \u2014 Gothic I: 59776 \u2014 Gothic II: 45570 Sources: \u2014 spacerhilfedatei.sph \u2014 gothic-library.ru

This VObject allows teleporting a hero to the waypoint.

Note

To make trigger work, you must set the value of the cdDyn parameter to True and specify the Waypoint in triggerTarget parameter.

"},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCTriggerTeleport/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCTriggerTeleport/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCVob/zCTriggerBase/zCTrigger/zCTriggerTeleport/#sfxteleport","title":"sfxTeleport","text":"

Sound accompaniment of character teleport.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/","title":"zCZone","text":""},{"location":"zengin/worlds/Classes/zCVob/zCZone/#zczone","title":"zCZone","text":"

Quick Infos

Class Name: zCZone Version Identifiers: \u2014 Gothic I: 12289 \u2014 Gothic II: 52224 Sources: \u2014 zk.gothickit.dev

The base class for effect zones.

Warning

This object is an abstract base class and cannot be instantiated by itself.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCZone/oCZoneMusic/","title":"oCZoneMusic","text":""},{"location":"zengin/worlds/Classes/zCVob/zCZone/oCZoneMusic/#oczonemusic","title":"oCZoneMusic","text":"

Quick Infos

Class Name: oCZoneMusic Version Identifiers: \u2014 Gothic I: 0 \u2014 Gothic II: 0 Sources: \u2014 spacerhilfedatei.sph \u2014 gothic-library.ru \u2014 zk.gothickit.dev

A VObject which defines the music to be played within its bounding box. Music zones may overlap; if they do, their priority property determines which music zone should be used. The camera object is used to test which music zone applies. If no music zone applies the music defined in the optional oCZoneMusicDefault is used.

The name of the music theme to be played is defined by the vobName. Notice that end of the name is taken as a C_MUSICTHEME prefix. For example zone OLDCAMP_OC will play theme starting with OC_.

Tip

If the suffix _NCI or _NCO is added to the end of the zone name, it snows instead of rains in the zone.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/oCZoneMusic/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCZone/oCZoneMusic/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCVob/zCZone/oCZoneMusic/#enabled","title":"enabled","text":"

Whether the music zone is enabled when loading the level. When disabled, no music will be played in the zone.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/oCZoneMusic/#priority","title":"priority","text":"

The priority of the music zone if two zones overlap. A higher number means a higher priority. 0 is the lowest possible priority.

Warning

Only relevant if two zCZoneMusic zones overlap.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/oCZoneMusic/#ellipsoid","title":"ellipsoid","text":"

Determines the shape of the zone.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/oCZoneMusic/#reverblevel","title":"reverbLevel","text":"

Unclear.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/oCZoneMusic/#volumelevel","title":"volumeLevel","text":"

Unclear.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/oCZoneMusic/#loop","title":"loop","text":"

Unclear.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/oCZoneMusic/#local_enabled","title":"local_enabled","text":"

Unknown.

Warning

This property is only available in saved games.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/oCZoneMusic/#dayentrancedone","title":"dayEntranceDone","text":"

Unknown.

Warning

This property is only available in saved games.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/oCZoneMusic/#nightentrancedone","title":"nightEntranceDone","text":"

Unknown.

Warning

This property is only available in saved games.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/oCZoneMusic/oCZoneMusicDefault/","title":"oCZoneMusicDefault","text":""},{"location":"zengin/worlds/Classes/zCVob/zCZone/oCZoneMusic/oCZoneMusicDefault/#oczonemusicdefault","title":"oCZoneMusicDefault","text":"

Quick Infos

Class Name: oCZoneMusicDefault Version Identifiers: \u2014 Gothic I: 0 \u2014 Gothic II: 0 Sources: \u2014 spacerhilfedatei.sph \u2014 zk.gothickit.dev

Determines the default music to be played when the camera is outside any oCZoneMusic zones. The volume-related options of the zone are ignored. There may only be one oCZoneMusicDefault object in a world.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/oCZoneMusic/oCZoneMusicDefault/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCVobSound/","title":"zCVobSound","text":""},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCVobSound/#zcvobsound","title":"zCVobSound","text":"

Quick Infos

Class Name: zCVobSound Version Identifiers: \u2014 Gothic I: 12289 \u2014 Gothic II: 12289 Sources: \u2014 spacerhilfedatei.sph \u2014 gothic-library.ru \u2014 zk.gothickit.dev

Emits a sound defined by a script instance in a given radius. The sound playback can be activated by sending an OnTrigger event to the VObject and sending an OnUntrigger event disables the sound playback.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCVobSound/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCVobSound/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCVobSound/#sndvolume","title":"sndVolume","text":"

The volume of the sound effect in percent (0-100).

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCVobSound/#sndmode","title":"sndMode","text":"

Determines how the sound effect is played.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCVobSound/#sndranddelay","title":"sndRandDelay","text":"

The average delay between repetitions in seconds if sndMode is RANDOM.

Warning

Only relevant if sndMode is RANDOM.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCVobSound/#sndranddelayvar","title":"sndRandDelayVar","text":"

The maximum deviation of the random delay between repetitions if sndMode is RANDOM. The resulting delay will be a value between sndRandDelay \u00b1 sndRandDelayVar.

Warning

Only relevant if sndMode is RANDOM.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCVobSound/#sndstarton","title":"sndStartOn","text":"

Whether to start the sound when loading the world.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCVobSound/#sndambient3d","title":"sndAmbient3D","text":"

Determines whether the sound is an omnidirectional ambient sound. It will change volume depending on the distance to this VObject, but it won't sound as if this VObject is emitting the effect.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCVobSound/#sndobstruction","title":"sndObstruction","text":"

Whether to dampen the sound when there is no direct path from the VObject to the listener.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCVobSound/#sndconeangle","title":"sndConeAngle","text":"

When set to a value other than 0, determines a cone in front of the VObject in which the sound can be heard. To listeners outside of that cone, the sound is not heard. Only values between 0 and 360 are valid.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCVobSound/#sndvoltype","title":"sndVolType","text":"

Determines the type of volume used to check whether the sound can be heard.

Accepted values:

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCVobSound/#sndradius","title":"sndRadius","text":"

The radius in which the sound can be heard.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCVobSound/#sndname","title":"sndName","text":"

The name of the script instance describing the sound.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCVobSound/#soundisrunning","title":"soundIsRunning","text":"

Unknown.

Warning

This property is only available in saved games.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCVobSound/#soundallowedtorun","title":"soundAllowedToRun","text":"

Unknown.

Warning

This property is only available in saved games.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCVobSound/zCVobSoundDaytime/","title":"zCVobSoundDaytime","text":""},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCVobSound/zCVobSoundDaytime/#zcvobsounddaytime","title":"zCVobSoundDaytime","text":"

Quick Infos

Class Name: zCVobSoundDaytime Version Identifiers: \u2014 Gothic I: 12289 \u2014 Gothic II: 12289 Sources: \u2014 spacerhilfedatei.sph \u2014 gothic-library.ru \u2014 zk.gothickit.dev

Emits a sound defined by a script instance in a given radius during a given time during the day. Optionally, another sound can be defined which is played outside the defined time range (example: birds during the day and crickets at night).

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCVobSound/zCVobSoundDaytime/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCVobSound/zCVobSoundDaytime/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCVobSound/zCVobSoundDaytime/#sndstarttime","title":"sndStartTime","text":"

The time of day after which the sound can be heard (13.5 corresponds to 13:30). Must be less than sndEndTime.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCVobSound/zCVobSoundDaytime/#sndendtime","title":"sndEndTime","text":"

The time of day after which the sound can no longer be heard (13.5 corresponds to 13:30). Must be greater than sndStartTime.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCVobSound/zCVobSoundDaytime/#sndname2","title":"sndName2","text":"

The name of the script instance describing the sound to play outside the hours defined by sndStartTime and sndendtime. May be empty.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCZoneVobFarPlane/","title":"zCZoneVobFarPlane","text":""},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCZoneVobFarPlane/#zczonevobfarplane","title":"zCZoneVobFarPlane","text":"

Quick Infos

Class Name: zCZoneVobFarPlane Version Identifiers: \u2014 Gothic I: 12289 \u2014 Gothic II: 52224 Sources: \u2014 gothic-library.ru \u2014 zk.gothickit.dev

A VObject which defines the loading range of VObjects within its bounding box.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCZoneVobFarPlane/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCZoneVobFarPlane/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCZoneVobFarPlane/#vobfarplanez","title":"vobFarPlaneZ","text":"

The loading range of VObject within.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCZoneVobFarPlane/#innerrangeperc","title":"innerRangePerc","text":"

Unknown.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCZoneVobFarPlane/zCZoneVobFarPlaneDefault/","title":"zCZoneVobFarPlaneDefault","text":""},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCZoneVobFarPlane/zCZoneVobFarPlaneDefault/#zczonevobfarplanedefault","title":"zCZoneVobFarPlaneDefault","text":"

Quick Infos

Class Name: zCZoneVobFarPlaneDefault Version Identifiers: \u2014 Gothic I: 12289 \u2014 Gothic II: 52224 Sources: \u2014 gothic-library.ru \u2014 zk.gothickit.dev

A VObject which defines the default loading range of VObjects in the entire world. There may only be one of these objects in each world. Its effect can be overridden using zCZoneVobFarPlane objects.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCZoneVobFarPlane/zCZoneVobFarPlaneDefault/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCZoneZFog/","title":"zCZoneZFog","text":""},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCZoneZFog/#zczonezfog","title":"zCZoneZFog","text":"

Quick Infos

Class Name: zCZoneZFog Version Identifiers: \u2014 Gothic I: 12289 \u2014 Gothic II: 52224 Sources: \u2014 gothic-library.ru \u2014 zk.gothickit.dev

A VObject which causes fog to appear within its bounding box.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCZoneZFog/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCZoneZFog/#class-member-overview","title":"Class member overview","text":""},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCZoneZFog/#fograngecenter","title":"fogRangeCenter","text":"

The maximum distance of visibility if the player is in the center of the fog object.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCZoneZFog/#innerrangeperc","title":"innerRangePerc","text":"

Unknown.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCZoneZFog/#fogcolor","title":"fogColor","text":"

The color of the fog.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCZoneZFog/#fadeoutsky","title":"fadeOutSky","text":"

Whether to hide the sky when the player is inside the fog.

Accepted values:

Warning

This property is only available in Gothic II.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCZoneZFog/#overridecolor","title":"overrideColor","text":"

Unclear.

Warning

This property is only available in Gothic II.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCZoneZFog/zCZoneZFogDefault/","title":"zCZoneZFogDefault","text":""},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCZoneZFog/zCZoneZFogDefault/#zczonezfogdefault","title":"zCZoneZFogDefault","text":"

Quick Infos

Class Name: zCZoneZFogDefault Version Identifiers: \u2014 Gothic I: 12289 \u2014 Gothic II: 52224 Sources: \u2014 gothic-library.ru \u2014 zk.gothickit.dev

A VObject which defines the default fog for the entire world. There may only be one of these objects in each world. Its effect can be overridden using zCZoneZFog objects.

"},{"location":"zengin/worlds/Classes/zCVob/zCZone/zCZoneZFog/zCZoneZFogDefault/#class-members","title":"Class members","text":"Gothic 1Gothic 2Gothic 1 (Save)Gothic 2 (Save) "},{"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":""},{"location":"blog/tags/#documentation","title":"Documentation","text":""},{"location":"blog/tags/#how-to","title":"How-To","text":""},{"location":"blog/tags/#mkdocs","title":"MkDocs","text":""},{"location":"blog/tags/#i18n","title":"i18n","text":""},{"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.

"},{"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:

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:

"},{"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

"},{"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":"

MEM_GetCommandLine

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":"

MEM_GetGothOpt

Przeszukuje Gothic.ini w poszukiwaniu opcji

func string MEM_GetGothOpt(var string sectionname, var string optionname)\n
Parametry

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":"

MEM_GetModOpt

Przeszukuje ini za\u0142adowanej modyfikacji w poszukiwaniu opcji.

func void MEM_GetModOpt(var string sectionname, var string optionname)\n
Parametry

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":"

MEM_GothOptSectionExists

Sprawdza, czy dana sekcja istnieje w Gothic.ini

func int MEM_GothOptSectionExists(var string sectionname)\n
Parametry

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":"

MEM_ModOptSectionExists

Sprawdza, czy dana sekcja istnieje w ini za\u0142adowanej modyfikacji.

func int MEM_ModOptSectionExists(var string sectionname)\n
Parametry

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":"

MEM_GothOptExists

Sprawdza, czy dana opcja istnieje w Gothic.ini

func int MEM_GothOptExists(var string sectionname, var string optionname)\n
Parametry

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":"

MEM_ModOptExists

Sprawdza, czy dana opcja istnieje w ini za\u0142adowanej modyfikacji.

func int MEM_ModOptExists(var string sectionname, var string optionname)\n
Parametry

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":"

MEM_SetGothOpt

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 "},{"location":"pl/zengin/scripts/extenders/ikarus/functions/ini_access/#mem_applygothopt","title":"MEM_ApplyGothOpt","text":"

MEM_ApplyGothOpt

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":"

MEM_GetKey

Zwraca podstawowy klawisz przypisany do klawisza logicznego.

func int MEM_GetKey(var string name)\n
Parametry

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":"

MEM_GetSecondaryKey

Zwraca zapasowy klawisz przypisany do klawisza logicznego.

func int MEM_GetSecondaryKey(var string name)\n
Parametry

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":"

MEM_SetKeys

Ustawia klawisze klawiatury dla podanego klawisza logicznego.

func void MEM_SetKeys(var string name, var int primary, var int secondary)\n
Parametry "},{"location":"pl/zengin/scripts/extenders/ikarus/functions/ini_access/#mem_setkey","title":"MEM_SetKey","text":"

MEM_SetKey

Ustawia podstawowy klawisz klawiatury dla klawisza logicznego.

func void MEM_SetKey(var string name, var int key)\n
Parametry "},{"location":"pl/zengin/scripts/extenders/ikarus/functions/ini_access/#mem_setsecondarykey","title":"MEM_SetSecondaryKey","text":"

MEM_SetSecondaryKey

Ustawia zapasowy klawisz klawiatury dla klawisza logicznego.

func void MEM_SetSecondaryKey(var string name, var int key)\n
Parametry "},{"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":"

Info

Zale\u017cno\u015bci: - PermMem - View Implementacja: Bars.d na GitHubie

Ten pakiet bardzo u\u0142atwia dodawanie nowych pask\u00f3w, dla wy\u015bwietlania np. wytrzyma\u0142o\u015bci.

"},{"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/#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":"

Bar_Create

Tworzy nowy pasek z instancji konstruktora.

func int Bar_Create(var int inst)\n

Parametry

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":"

Bar_Delete

Usuwa pasek z ekranu i pami\u0119ci.

func void Bar_Delete(var int bar)\n

Parametry

"},{"location":"pl/zengin/scripts/extenders/lego/applications/bars/#bar_setmax","title":"Bar_SetMax","text":"

Bar_SetMax

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 "},{"location":"pl/zengin/scripts/extenders/lego/applications/bars/#bar_setvalue","title":"Bar_SetValue","text":"

Bar_SetValue

Ustawia warto\u015b\u0107 paska.

func void Bar_SetValue(var int bar, var int val)\n
Parametry "},{"location":"pl/zengin/scripts/extenders/lego/applications/bars/#bar_setpercent","title":"Bar_SetPercent","text":"

Bar_SetPercent

Ustawia warto\u015b\u0107 paska, ale w procentach (0..100).

func void Bar_SetPercent(var int bar, var int perc)\n
Parametry "},{"location":"pl/zengin/scripts/extenders/lego/applications/bars/#bar_setpromille","title":"Bar_SetPromille","text":"

Bar_SetPromille

Ustawia warto\u015b\u0107 paska, ale w promilach (0..1000).

func void Bar_SetPromille(var int bar, var int pro)\n
Parametry "},{"location":"pl/zengin/scripts/extenders/lego/applications/bars/#bar_hide","title":"Bar_Hide","text":"

Bar_Hide

Ukrywa pasek, ale go nie usuwa.

func void Bar_Hide(var int bar)\n
Parametry "},{"location":"pl/zengin/scripts/extenders/lego/applications/bars/#bar_show","title":"Bar_Show","text":"

Bar_Show

Wy\u015bwietla pasek ponownie po u\u017cyciu Bar_Hide.

func void Bar_Show(var int bar)\n
Parametry "},{"location":"pl/zengin/scripts/extenders/lego/applications/bars/#bar_moveto","title":"Bar_MoveTo","text":"

Bar_MoveTo

Przenosi pasek do danej pozycji wirtualnej.

func void Bar_MoveTo(var int bar, var int x, var int y)\n
Parametry "},{"location":"pl/zengin/scripts/extenders/lego/applications/bars/#bar_movetopxl","title":"Bar_MoveToPxl","text":"

Bar_MoveToPxl

Przenosi pasek do danej pozycji wyra\u017conej w pikselach.

func void Bar_MoveToPxl(var int bar, var int x, var int y)\n
Parametry "},{"location":"pl/zengin/scripts/extenders/lego/applications/bars/#bar_setalpha","title":"Bar_SetAlpha","text":"

Bar_SetAlpha

Ustawia przezroczysto\u015b\u0107 paska.

func void Bar_SetAlpha(var int bar, var int alpha)\n
Parametry "},{"location":"pl/zengin/scripts/extenders/lego/applications/bars/#bar_setbartexture","title":"Bar_SetBarTexture","text":"

Bar_SetBarTexture

Ustawia tekstur\u0119 warto\u015bci paska.

func void Bar_SetBarTexture(var int bar, var string barTex)\n
Parametry "},{"location":"pl/zengin/scripts/extenders/lego/applications/bars/#bar_setbacktexture","title":"Bar_SetBackTexture","text":"

Bar_SetBackTexture

Ustawia tekstur\u0119 t\u0142a paska.

func void Bar_SetBackTexture(var int bar, var string backTex)\n
Parametry "},{"location":"pl/zengin/scripts/extenders/lego/applications/bars/#bar_resize","title":"Bar_Resize","text":"

Bar_Resize

Zmienia rozmiar istniej\u0105cego paska.

func void Bar_Resize(var int bar, var int width, var int height)\n
Parametry "},{"location":"pl/zengin/scripts/extenders/lego/applications/bars/#bar_resizepxl","title":"Bar_ResizePxl","text":"

Bar_ResizePxl

Resize existing bar (in pixels).

func void Bar_ResizePxl(var int bar, var int x, var int y)\n
Parametry "},{"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":"

Info

Zale\u017cno\u015bci: - PermMem - HookEngine Implementacja: ConsoleCommands.d na GitHubie

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/#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/#funkcje","title":"Funkcje","text":""},{"location":"pl/zengin/scripts/extenders/lego/applications/console_commands/#cc_register","title":"CC_Register","text":"

CC_Register

Rejestruje nowe polecenie konsoli.

func void CC_Register(var func f, var string cmdPrefix, var string description)\n
Parametry "},{"location":"pl/zengin/scripts/extenders/lego/applications/console_commands/#cc_remove","title":"CC_Remove","text":"

CC_Remove

Usuwa funkcje z konsoli komend.

func void CC_Remove(var func f)\n
Parametry "},{"location":"pl/zengin/scripts/extenders/lego/applications/console_commands/#cc_active","title":"CC_Active","text":"

CC_Active

Sprawdza, czy dana funkcja jest ju\u017c cz\u0119\u015bci\u0105 polecenia konsoli.

func int CC_Active(var func f)\n
Parametry

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":"

Info

Zale\u017cno\u015bci: - EventHandler - Saves Implementacja: Gamestate.d na GitHubie

Pakiet Gamestate pozwala sprawdzi\u0107 stan gry (rozpocz\u0119cie gry, \u0142adowanie gry lub zmiana poziomu).

"},{"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/#funkcje","title":"Funkcje","text":""},{"location":"pl/zengin/scripts/extenders/lego/applications/gamestate/#gamestate_addlistener","title":"Gamestate_AddListener","text":"

Gamestate_AddListener

Dodaje listener/handler zmiany stanu gry.

func void Gamestate_AddListener(var func listener)\n
Parametry "},{"location":"pl/zengin/scripts/extenders/lego/applications/gamestate/#gamestate_removelistener","title":"Gamestate_RemoveListener","text":"

Gamestate_RemoveListener

Usuwa listener zmiany stanu gry.

func void Gamestate_RemoveListener(var func listener)\n
Parametry "},{"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":"

Info

Zale\u017cno\u015bci: - AI_Function Implementacja: Trialoge.d na GitHubie

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/#inicjalizacja","title":"Inicjalizacja","text":"

Zainicjuj za pomoc\u0105 flagi LeGo_Trialoge.

LeGo_Init(LeGo_Trialoge);\n
"},{"location":"pl/zengin/scripts/extenders/lego/applications/trialoge/#funkcje","title":"Funkcje","text":""},{"location":"pl/zengin/scripts/extenders/lego/applications/trialoge/#equipweapon","title":"EquipWeapon","text":"

EquipWeapon

Funkcja Sektenspinnera. Sprawia, \u017ce NPC wyposa\u017ca bro\u0144.

func void EquipWeapon(var C_NPC slf, var int ItemInstance)\n
Parametry

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:

"},{"location":"pl/zengin/scripts/extenders/lego/applications/trialoge/#npc_getarmor","title":"Npc_GetArmor","text":"

Npc_GetArmor

Pobiera pancerz wyposa\u017cony przez NPC.

func int Npc_GetArmor(var C_NPC slf)\n
Parametry

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":"

Npc_GetMeleeWeapon

Pobiera wyposa\u017con\u0105 przez NPC bro\u0144 bia\u0142\u0105.

func int Npc_GetMeleeWeapon(var C_NPC slf)\n
Parametry

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":"

Npc_GetRangedWeapon

Pobiera wyposa\u017con\u0105 przez NPC bro\u0144 dystansow\u0105.

func int Npc_GetRangedWeapon(var C_NPC slf)\n
Parametry

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":"

Npc_TradeItem

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 "},{"location":"pl/zengin/scripts/extenders/lego/applications/trialoge/#diacam_update","title":"DiaCAM_Update","text":"

DiaCAM_Update

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":"

DiaCAM_Disable

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":"

DiaCAM_Enable

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":"

TRIA_Wait

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":"

TRIA_Invite

Zaprasza NPC do rozmowy. Nale\u017cy wywo\u0142a\u0107 przed TRIA_Start.TRIA_Start.

func void TRIA_Invite(var C_NPC slf)\n
Parametry "},{"location":"pl/zengin/scripts/extenders/lego/applications/trialoge/#tria_start","title":"TRIA_Start","text":"

TRIA_Start

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":"

TRIA_Barrier

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":"

TRIA_Next

Ustawia podanego NPC na self.

func void TRIA_Next(var C_NPC n0)\n
Parametry "},{"location":"pl/zengin/scripts/extenders/lego/applications/trialoge/#tria_cam","title":"TRIA_Cam","text":"

TRIA_Cam

Rozpoczyna zdefiniowany wcze\u015bniej ruch kamery.

func void TRIA_Cam(var string evt)\n
Parametry "},{"location":"pl/zengin/scripts/extenders/lego/applications/trialoge/#tria_finish","title":"TRIA_Finish","text":"

TRIA_Finish

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":""},{"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

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":"

Info

Zale\u017cno\u015bci: - Brak Implementacja: BinaryMachines.d na GitHub

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/#inicjalizacja","title":"Inicjalizacja","text":"

Brak

"},{"location":"pl/zengin/scripts/extenders/lego/tools/binary_machines/#bw_newfile","title":"BW_NewFile","text":"

BW_NewFile

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

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":"

BW_Close

Zamyka aktualny strumie\u0144 zapisu.

func void BW_Close()\n
"},{"location":"pl/zengin/scripts/extenders/lego/tools/binary_machines/#bw","title":"BW","text":"

BW

Zapisuje length bajt\u00f3w z data do strumienia, maksymalnie 4 bajty.

func void BW(var int data, var int length)\n
Parametry "},{"location":"pl/zengin/scripts/extenders/lego/tools/binary_machines/#bw_int","title":"BW_Int","text":"

BW_Int

Zapisuje 4 bajty z data do strumienia. To samo co BW(data, 4).

func void BW_Int(var int data)\n
Parametry "},{"location":"pl/zengin/scripts/extenders/lego/tools/binary_machines/#bw_char","title":"BW_Char","text":"

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)\n
Parametry "},{"location":"pl/zengin/scripts/extenders/lego/tools/binary_machines/#bw_string","title":"BW_String","text":"

BW_String

Zapisuje data zako\u0144czone znakiem \\0 do strumienia.

func void BW_String(var string data)\n
Parametry "},{"location":"pl/zengin/scripts/extenders/lego/tools/binary_machines/#bw_byte","title":"BW_Byte","text":"

BW_Byte

Zapisuje bajt z data do strumienia. To samo co BW(data, 1).

func void BW_Byte(var int data)\n
Parametry "},{"location":"pl/zengin/scripts/extenders/lego/tools/binary_machines/#bw_bytes","title":"BW_Bytes","text":"

BW_Bytes

Zapisuje length bajt\u00f3w ze wska\u017anika dataPtr do strumienia.

func void BW_Bytes(var int dataPtr, var int length)\n
Parametry "},{"location":"pl/zengin/scripts/extenders/lego/tools/binary_machines/#bw_text","title":"BW_Text","text":"

BW_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 "},{"location":"pl/zengin/scripts/extenders/lego/tools/binary_machines/#bw_nextline","title":"BW_NextLine","text":"

BW_NextLine

Zapisuje akapit do strumienia.

func void BW_NextLine()\n
"},{"location":"pl/zengin/scripts/extenders/lego/tools/binary_machines/#br_openfile","title":"BR_OpenFile","text":"

BR_OpenFile

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

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":"

BR_Close

Zamyka aktualny strumie\u0144 odczytu.

func void BR_Close()\n
"},{"location":"pl/zengin/scripts/extenders/lego/tools/binary_machines/#br","title":"BR","text":"

BR

Odczytuje bajty ze strumienia.

func int BR(var int length)\n
Parametry

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":"

BR_Int

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":"

BR_Char

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":"

BR_String

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":"

BR_Byte

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":"

BR_Bytes

Odczytuje bajty ze strumienia.

func int BR_Bytes(var int length)\n
Parametry

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":"

BR_TextLine

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":"

BR_Text

Odczytuje ci\u0105g znak\u00f3w o podanej d\u0142ugo\u015bci ze strumienia.

func string BR_Text(var int length)\n
Parametry

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":"

BR_NextLine

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":"

WIN_GetLastError

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":"

WIN_CreateFile

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":"

WIN_WriteFile

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":"

WIN_ReadFile

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":"

WIN_CloseHandle

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":"

WIN_GetFileSize

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":"

Info

Zale\u017cno\u015bci: - Brak Implementacja: ItemHelper.d na GitHubie

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/#inicjalizacja","title":"Inicjalizacja","text":"

Nie dotyczy.

"},{"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":"

Itm_GetPtr

func int Itm_GetPtr(var int instance)\n
Parametry

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":"

Info

Zale\u017cno\u015bci: - Nie dotyczy. Implementacja: Misc.d na GitHubie

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/#inicjalizacja","title":"Inicjalizacja","text":"

Nie dotyczy.

"},{"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":"

atan2f

Oblicza arcus tangens k\u0105ta mi\u0119dzy pocz\u0105tkiem a punktem (x, y).

func int atan2f(var int x, var int y)\n
Parametry

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":"

sin

Oblicza sinus k\u0105ta podanego w radianach.

func int sin(var int angle)\n
Parametry

Zwracana warto\u015b\u0107

Funkcja zwraca sinus k\u0105ta, jako ikarusowy float.

"},{"location":"pl/zengin/scripts/extenders/lego/tools/misc/#cos","title":"cos","text":"

cos

Oblicza cosinus k\u0105ta podanego w radianach.

func int cos(var int angle)\n
Parametry

Zwracana warto\u015b\u0107

Funkcja zwraca cosinus k\u0105ta, jako ikarusowy float.

"},{"location":"pl/zengin/scripts/extenders/lego/tools/misc/#tan","title":"tan","text":"

tan

Oblicza tangens k\u0105ta podanego w radianach.

func int tan(var int angle)\n
Parametry

Zwracana warto\u015b\u0107

Funkcja zwraca tangens k\u0105ta, jako ikarusowy float.

"},{"location":"pl/zengin/scripts/extenders/lego/tools/misc/#asin","title":"asin","text":"

asin

Oblicza arcus sinus

func int asin(var int sine)\n
Parametry

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":"

acos

Oblicza arcus cosinus

func int acos(var int cosine)\n
Parametry

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":"

distance2D

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

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":"

distance2Df

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

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":"

Info

Zale\u017cno\u015bci: - PermMem Implementacja: Talents.d na GitHubie

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/#inicjalizacja","title":"Inicjalizacja","text":"

Zainicjuj za pomoc\u0105 flagi LeGo_PermMem.

LeGo_Init(LeGo_PermMem);\n
"},{"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":"

NPC_GetID

Zwraca unikalne ID dla podanego NPC.

func int NPC_GetID(var C_NPC slf)\n
Parametry

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":"

NPC_FindByID

Znajduje wska\u017anik NPC o podanym ID.

func int NPC_FindByID(var int ID)\n
Parametry

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":"

TAL_CreateTalent

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":"

TAL_SetValue

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 "},{"location":"pl/zengin/scripts/extenders/lego/tools/talents/#tal_getvalue","title":"TAL_GetValue","text":"

TAL_GetValue

Zwraca warto\u015b\u0107 talentu dla okre\u015blonego NPC.

func int TAL_GetValue(var C_NPC npc, var int talent)\n
Parametry "},{"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":"pl/zengin/sound/","title":"D\u017awi\u0119k","text":""},{"location":"pl/zengin/sound/#d\u017awi\u0119k","title":"D\u017awi\u0119k","text":"

ZenGin u\u017cywa plik\u00f3w .wav do odtwarzania efekt\u00f3w d\u017awi\u0119kowych i dubbingu.

Informacja

\u015acie\u017cka d\u017awi\u0119kowa w grze nie jest zapisywana w plikach d\u017awi\u0119kowych .wav. Zobacz Muzyka.

"},{"location":"pl/zengin/sound/#w\u0142a\u015bciwo\u015bci","title":"W\u0142a\u015bciwo\u015bci","text":"

Oryginalne pliki d\u017awi\u0119kowe gothica maj\u0105 nast\u0119puj\u0105ce w\u0142a\u015bciwo\u015bci:

"},{"location":"pl/zengin/sound/#efekty-d\u017awi\u0119kowe","title":"Efekty d\u017awi\u0119kowe","text":"

Efekty d\u017awi\u0119kowe (SFX) to d\u017awi\u0119ki wydawane przez potwory, zakl\u0119cia, bro\u0144 itp. Efekty d\u017awi\u0119kowe s\u0105 definiowane w wielu miejscach, w plikach .mds jako cz\u0119\u015b\u0107 animacji EventBlocks, lub w skryptach SFX Daedalus. D\u017awi\u0119ki znajduj\u0105 si\u0119 w katalogu _work/Data/Sound/SFX.

"},{"location":"pl/zengin/sound/#speech","title":"Speech","text":"

Dubbing dla dialog\u00f3w znajduje si\u0119 w folderze _work/Data/Sound/Speech. Ka\u017cde pojedyncze AI_Output ma sw\u00f3j w\u0142asny plik d\u017awi\u0119kowy o nazwie zdefiniowanej w samej funkcji.

W przypadku tej linii dialogowej

AI_Output(self,hero,\"Info_Diego_Gamestart_11_00\"); //Jestem Diego.\n
silnik odtworzy plik d\u017awi\u0119kowy Info_Diego_Gamestart_11_00.wav (je\u015bli istnieje)."},{"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/zengin/scripts/extenders/lego/tools/binary_machines/index.html b/zengin/scripts/extenders/lego/tools/binary_machines/index.html index 443cc3069a..00a3c5149e 100644 --- a/zengin/scripts/extenders/lego/tools/binary_machines/index.html +++ b/zengin/scripts/extenders/lego/tools/binary_machines/index.html @@ -230,4 +230,4 @@ BW_NpcPosition(hero); BW_Close(); */ -

Note

Examples originally written by Gottfried and posted on World of Gothic forum.

\ No newline at end of file +

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/draw3d/index.html b/zengin/scripts/extenders/lego/tools/draw3d/index.html index 5e8e9c7499..fbcb512d91 100644 --- a/zengin/scripts/extenders/lego/tools/draw3d/index.html +++ b/zengin/scripts/extenders/lego/tools/draw3d/index.html @@ -266,4 +266,4 @@ // EraseBBox(hndl); // Or delete including the handle }; }; -
\ No newline at end of file +
\ 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 index 6029216b0a..80ac3953b5 100644 --- a/zengin/scripts/extenders/lego/tools/event_handler/index.html +++ b/zengin/scripts/extenders/lego/tools/event_handler/index.html @@ -52,4 +52,4 @@ Parameters

EventPtr_Remove

EventPtr_Remove

Removes a function from the event's call list.

func void EventPtr_Remove(var int eventPtr, var func function)
 
Parameters

EventPtr_RemoveI

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

EventPtr_Execute

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)
-

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 +

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 index 89e978ce0e..32b63ab93f 100644 --- a/zengin/scripts/extenders/lego/tools/frame_functions/index.html +++ b/zengin/scripts/extenders/lego/tools/frame_functions/index.html @@ -116,4 +116,4 @@ { 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 + 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 index 201ab46687..dbf0fcc24d 100644 --- a/zengin/scripts/extenders/lego/tools/hashtables/index.html +++ b/zengin/scripts/extenders/lego/tools/hashtables/index.html @@ -143,4 +143,4 @@ // Destroy the hashtable HT_Destroy(hashtableHandle); }; -
\ No newline at end of file +
\ 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 index 7dd7dced61..357759fbd6 100644 --- a/zengin/scripts/extenders/lego/tools/hook_dae/index.html +++ b/zengin/scripts/extenders/lego/tools/hook_dae/index.html @@ -241,4 +241,4 @@ // -- B: 3 // <- C: 2 // <- D: 1 -
\ No newline at end of file +
\ 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 index 7c26ee77ea..2ba6464c1f 100644 --- a/zengin/scripts/extenders/lego/tools/hook_engine/index.html +++ b/zengin/scripts/extenders/lego/tools/hook_engine/index.html @@ -63,4 +63,4 @@ var int EBP; var int ESI; var int EDI; -
\ No newline at end of file +
\ 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 index 86db1eec41..39b2a17835 100644 --- a/zengin/scripts/extenders/lego/tools/int64/index.html +++ b/zengin/scripts/extenders/lego/tools/int64/index.html @@ -55,4 +55,4 @@ Parameters

sub64

sub64

Subtracts src from dest: *dest <- *dest - *src

func void sub64(var int dest, var int src)
 
Parameters

mul64

mul64

Multiplies dest by src: *dest <- (*dest) * (*src)

func void mul64(var int dest, var int src)
 
Parameters

div64

div64

Divides dest by src: *dest <- *dest / *src

func void mul64(var int dest, var int src)
-
Parameters
\ No newline at end of file + Parameters
\ 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 index 4c2911cbee..5ed3776f90 100644 --- a/zengin/scripts/extenders/lego/tools/interface/index.html +++ b/zengin/scripts/extenders/lego/tools/interface/index.html @@ -246,4 +246,4 @@ // Since Anim8 does the deleting itself, we don't have to worry about that. }; -
\ No newline at end of file +
\ 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 index 2f2da5a0e8..3d026ddbc9 100644 --- a/zengin/scripts/extenders/lego/tools/item_helper/index.html +++ b/zengin/scripts/extenders/lego/tools/item_helper/index.html @@ -32,4 +32,4 @@ const gGMC_FILE_LOCALE = "en"; const gGMC_TRANSLATE_SVG = '';

ItemHelper

Info

Dependencies:
- None
Implementation:
ItemHelper.d on GitHub

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.

Initialization

N/A

Functions

Itm_GetPtr

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 + Parameters

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 index 58ea6a0cda..3aaa1227cc 100644 --- a/zengin/scripts/extenders/lego/tools/list/index.html +++ b/zengin/scripts/extenders/lego/tools/list/index.html @@ -57,4 +57,4 @@ Parameters:

Return Value:

The function returns TRUE if data1 is greater than data2, FALSE is returned otherwise.

List_CmpDescending

List_CmpDescending

Compares two integer values in descending order.

func int List_CmpDescending(var int data1, var int data2)
 
Parameters:

Return Value:

The function returns TRUE if data1 is less than data2, FALSE is returned otherwise.

List_CmpAscendingUnsigned

List_CmpAscendingUnsigned

Compares two unsigned integer values in ascending order.

func int List_CmpAscendingUnsigned(var int data1, var int data2)
 
Parameters:

Return Value:

The function returns TRUE if data1 is greater than data2, FALSE is returned otherwise.

List_CmpDescendingUnsigned

List_CmpDescendingUnsigned

Compares two unsigned integer values in descending order.

func int List_CmpDescendingUnsigned(var int data1, var int data2)
-
Parameters:

Return Value:

The function returns TRUE if data1 is less than data2, FALSE is returned otherwise.

\ No newline at end of file + Parameters:

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 index 639c8ddd83..a4c6e2a27f 100644 --- a/zengin/scripts/extenders/lego/tools/locals/index.html +++ b/zengin/scripts/extenders/lego/tools/locals/index.html @@ -48,4 +48,4 @@ }; MEM_InfoBox("This will appear before Final"); }; - Few lines of code say more than a thousand words.
\ No newline at end of file + 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 index 789c0bf6ca..28336dc6de 100644 --- a/zengin/scripts/extenders/lego/tools/misc/index.html +++ b/zengin/scripts/extenders/lego/tools/misc/index.html @@ -40,4 +40,4 @@ Parameters

Return value

The function returns arcus sine of the angle as Ikarus float.

acos

acos

Calculates the arcus cosine

func int acos(var int cosine)
 
Parameters

Return value

The function returns arcus cosine of the angle as Ikarus float.

distance2D

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

Return value

The function returns the distance between the two points.

distance2Df

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

Return value

The function returns the distance between the two points as Ikarus float.

\ No newline at end of file + Parameters

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 index 90b5ad13aa..05008fc329 100644 --- a/zengin/scripts/extenders/lego/tools/permmem/index.html +++ b/zengin/scripts/extenders/lego/tools/permmem/index.html @@ -83,4 +83,4 @@ Parameters

PM_LoadArray

PM_LoadArray

Returns a pointer to array stored in the archive.

func int PM_LoadArray(var string name)
 
Parameters

PM_LoadArrayToPtr

PM_LoadArrayToPtr

Loads a pointer to array from the archive to destPtr.

func void PM_LoadArrayToPtr(var string name, var int destPtr)
 
Parameters

PM_LoadToPtr

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
\ No newline at end of file + Parameters
\ 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 index df44c1373a..22fb9be495 100644 --- a/zengin/scripts/extenders/lego/tools/queue/index.html +++ b/zengin/scripts/extenders/lego/tools/queue/index.html @@ -45,4 +45,4 @@ Parameters

CQ_IsEmpty

CQ_IsEmpty

Checks if no function is in the callback queue.

func int CQ_IsEmpty(var int queue)
 
Parameters

Return value

The function returns TRUE if the callback queue is empty, FALSE is returned otherwise.

CQ_Advance

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

CQ_Exhaust

CQ_Exhaust

Executes all functions contained in the callback queue.

func void CQ_Exhaust(var int queue)
-
Parameters
\ No newline at end of file + Parameters
\ 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 index 3ac86d5507..63d58d75cf 100644 --- a/zengin/scripts/extenders/lego/tools/random/index.html +++ b/zengin/scripts/extenders/lego/tools/random/index.html @@ -37,4 +37,4 @@ Parameters

Return value

The function returns a random number from 0 to 'max'.

r_MinMax

r_MinMax

Returns a random number from 'min' to 'max'.

func int r_MinMax(var int min, var int max)
 
Parameters

Return value

The function returns a random number from min to max.

r_Init

r_Init

Initializes the random number generator. Happens optionally in LeGo_Init.

func void r_Init(var int seed)
 
Parameters

r_DefaultInit

r_DefaultInit

Initializes the random number generator based on the current time.

func void r_DefaultInit()
-
\ No newline at end of file +
\ 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 index 6636177318..36c435bb9f 100644 --- a/zengin/scripts/extenders/lego/tools/string_builder/index.html +++ b/zengin/scripts/extenders/lego/tools/string_builder/index.html @@ -152,4 +152,4 @@ return str; }; -
\ No newline at end of file +
\ 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 index 899739ad07..58ee465c3e 100644 --- a/zengin/scripts/extenders/lego/tools/talents/index.html +++ b/zengin/scripts/extenders/lego/tools/talents/index.html @@ -37,4 +37,4 @@ Parameters

Return value

The function returns NPC pointer.

TAL_CreateTalent

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

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

TAL_GetValue

TAL_GetValue

Returns the value of a saved talent for specified NPC.

func int TAL_GetValue(var C_NPC npc, var int talent)
-
Parameters
\ No newline at end of file + Parameters
\ 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 index f6b0048d10..15ec883edd 100644 --- a/zengin/scripts/extenders/lego/tools/timer/index.html +++ b/zengin/scripts/extenders/lego/tools/timer/index.html @@ -38,4 +38,4 @@ Return value

The function returns current playing time as an Ikarus float value.

Timer_SetPause

Timer_SetPause

Pauses the timer (and thus all FrameFunctions and running animations).

func void Timer_SetPause(var int on)
 
Parameters

Timer_SetPauseInMenu

Timer_SetPauseInMenu

The timer can automatically pause when the game is paused. (status screen, main menu...)

func void Timer_SetPauseInMenu(var int on)
 
Parameters

Timer_IsPaused

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 + 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 index 6c1a06bd63..097d8bf57a 100644 --- a/zengin/scripts/extenders/lego/tools/view/index.html +++ b/zengin/scripts/extenders/lego/tools/view/index.html @@ -81,4 +81,4 @@ 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 +

To get the size of the screen we use the interface package.

\ No newline at end of file diff --git a/zengin/scripts/extenders/standalone/gameKeyEvents/index.html b/zengin/scripts/extenders/standalone/gameKeyEvents/index.html index 06b274cf31..86ce1036d2 100644 --- a/zengin/scripts/extenders/standalone/gameKeyEvents/index.html +++ b/zengin/scripts/extenders/standalone/gameKeyEvents/index.html @@ -45,4 +45,4 @@ }; return FALSE; }; -
\ No newline at end of file +
\ No newline at end of file diff --git a/zengin/scripts/extenders/standalone/index.html b/zengin/scripts/extenders/standalone/index.html index a95234b79a..097b877d3d 100644 --- a/zengin/scripts/extenders/standalone/index.html +++ b/zengin/scripts/extenders/standalone/index.html @@ -31,4 +31,4 @@ const gGMC_PAGE_LOCALE = "en"; const gGMC_FILE_LOCALE = "en"; const gGMC_TRANSLATE_SVG = ''; -

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 +

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 index b7cb73ff91..426f8c3ebd 100644 --- a/zengin/scripts/extenders/standalone/setBarPositions/index.html +++ b/zengin/scripts/extenders/standalone/setBarPositions/index.html @@ -138,4 +138,4 @@ return x | (y << 14); }; -
\ No newline at end of file +
\ No newline at end of file diff --git a/zengin/scripts/extenders/zparserextender/classes/c_trigger/index.html b/zengin/scripts/extenders/zparserextender/classes/c_trigger/index.html index a210a78fd9..ab514f5b3b 100644 --- a/zengin/scripts/extenders/zparserextender/classes/c_trigger/index.html +++ b/zengin/scripts/extenders/zparserextender/classes/c_trigger/index.html @@ -142,4 +142,4 @@ trigger = AI_GetNextTriggerBySelf(hero); trigger_saved.Enabled = false; }; -
\ No newline at end of file +
\ 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 index 490929a01b..90ebdba498 100644 --- a/zengin/scripts/extenders/zparserextender/classes/helperclasses/index.html +++ b/zengin/scripts/extenders/zparserextender/classes/helperclasses/index.html @@ -387,4 +387,4 @@ /// @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 +
\ 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 index 1ff0d0bf21..3aafa2f6e4 100644 --- a/zengin/scripts/extenders/zparserextender/daedalus_injection/hooks/index.html +++ b/zengin/scripts/extenders/zparserextender/daedalus_injection/hooks/index.html @@ -81,4 +81,4 @@ DIA_XARDAS_HELLO_old(); important = FALSE; }; -
\ No newline at end of file +
\ 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 index 81e18b7c20..832b67be01 100644 --- a/zengin/scripts/extenders/zparserextender/daedalus_injection/index.html +++ b/zengin/scripts/extenders/zparserextender/daedalus_injection/index.html @@ -31,4 +31,4 @@ const gGMC_PAGE_LOCALE = "en"; const gGMC_FILE_LOCALE = "en"; const gGMC_TRANSLATE_SVG = ''; -

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 +

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 index 523a3da0e2..05d7d80daa 100644 --- a/zengin/scripts/extenders/zparserextender/daedalus_injection/meta/index.html +++ b/zengin/scripts/extenders/zparserextender/daedalus_injection/meta/index.html @@ -92,4 +92,4 @@ 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 +
\ 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 index 761d08030b..9852451753 100644 --- a/zengin/scripts/extenders/zparserextender/daedalus_injection/other/index.html +++ b/zengin/scripts/extenders/zparserextender/daedalus_injection/other/index.html @@ -119,4 +119,4 @@ { 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 +

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/examples/signposts/index.html b/zengin/scripts/extenders/zparserextender/examples/signposts/index.html index eedd7d55cc..3b4c2d7be0 100644 --- a/zengin/scripts/extenders/zparserextender/examples/signposts/index.html +++ b/zengin/scripts/extenders/zparserextender/examples/signposts/index.html @@ -364,4 +364,4 @@ Finally, we advance the index to jump to another signpost.
// advance the index
 tp_index += 1;
-
\ No newline at end of file +
\ No newline at end of file diff --git a/zengin/scripts/extenders/zparserextender/externals/ai/index.html b/zengin/scripts/extenders/zparserextender/externals/ai/index.html index e806754e58..08c5b43642 100644 --- a/zengin/scripts/extenders/zparserextender/externals/ai/index.html +++ b/zengin/scripts/extenders/zparserextender/externals/ai/index.html @@ -63,4 +63,4 @@ var C_NPC self, var C_NPC other, var C_NPC victim) {}; -
\ No newline at end of file +
\ 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 index 4c8a270b8f..e43dbc415d 100644 --- a/zengin/scripts/extenders/zparserextender/externals/cast/index.html +++ b/zengin/scripts/extenders/zparserextender/externals/cast/index.html @@ -42,4 +42,4 @@

Cast_GetClassID

Cast_GetClassID

Returns the class identifier of a class by its name

func int Cast_GetClassID( var string className ) {};
 

Cast_GetVobClassID

Cast_GetVobClassID

Returns class identifier of the zCObject vob class

func int Cast_GetVobClassID( var instance object ) {};
 

Cast_CheckVobClassID

Cast_CheckVobClassID

Checks if the classId class is the parent class of the object

func int Cast_CheckVobClassID( var int classId, var instance object ) {};
-
\ No newline at end of file +
\ 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 index 5f63794789..4e0de8a141 100644 --- a/zengin/scripts/extenders/zparserextender/externals/events_vars/index.html +++ b/zengin/scripts/extenders/zparserextender/externals/events_vars/index.html @@ -52,4 +52,4 @@ /// not a number floating point constant const float NaN; -
\ No newline at end of file +
\ 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 index 00a5d45a1f..1e63c5ea7b 100644 --- a/zengin/scripts/extenders/zparserextender/externals/hlp/index.html +++ b/zengin/scripts/extenders/zparserextender/externals/hlp/index.html @@ -85,4 +85,4 @@

Hlp_WriteOptionString

Hlp_WriteOptionString

Writes a string value to specified .ini file, section and entry.

optName values

func void Hlp_WriteOptionString(var string optName, var string section, var string entry, var string value) {};
 

Hlp_GetSteamPersonalName

Hlp_GetSteamPersonalName

Returns the name of the current Steam user Returns empty string when not run with Steam

func string Hlp_GetSteamPersonalName() {};
 

Hlp_DoEvent

Hlp_DoEvent

Calls every event function with the name funcName.

func void Hlp_DoEvent(var string funcName) {};
-
\ No newline at end of file +
\ 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 index 2a8861453b..006456c579 100644 --- a/zengin/scripts/extenders/zparserextender/externals/log/index.html +++ b/zengin/scripts/extenders/zparserextender/externals/log/index.html @@ -33,4 +33,4 @@ const gGMC_TRANSLATE_SVG = '';

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

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

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 +
\ 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 index cb6f09db07..0cedd11f53 100644 --- a/zengin/scripts/extenders/zparserextender/externals/mdl/index.html +++ b/zengin/scripts/extenders/zparserextender/externals/mdl/index.html @@ -43,4 +43,4 @@

Mdl_ApplyOverlayMds_AtFirst

Mdl_ApplyOverlayMds_AtFirst

Applies or moves existing overlay to the top of the list

func void Mdl_ApplyOverlayMds_AtFirst( var string mdsName ) {};
 

Mdl_SetNpcSpeedMultiplier

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 ) {};
 

Mdl_ResetNpcSpeedMultiplier

Mdl_ResetNpcSpeedMultiplier

Resets the animation speed of an NPC

func void Mdl_ResetNpcSpeedMultiplier( var C_Npc npc ) {};
-
\ No newline at end of file +
\ 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 index 07e6439412..6c46f2899a 100644 --- a/zengin/scripts/extenders/zparserextender/externals/menu/index.html +++ b/zengin/scripts/extenders/zparserextender/externals/menu/index.html @@ -53,4 +53,4 @@ 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 +

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 index 544758cd0b..7ad878bf63 100644 --- a/zengin/scripts/extenders/zparserextender/externals/mob/index.html +++ b/zengin/scripts/extenders/zparserextender/externals/mob/index.html @@ -42,4 +42,4 @@

Mob_SetLocked

Mob_SetLocked

Set the lock status of the object

func void Mob_SetLocked( var instance object, var int locked ) {};
 

Mob_GetKeyInstance

Mob_GetKeyInstance

Returns the key instance, that unlocks the object

func instance Mob_GetKeyInstance( var instance object ) {};
 

Mob_SetKeyInstance

Mob_SetKeyInstance

Stets the key instance, that unlocks the object

func void Mob_SetKeyInstance( var instance object, var int key ) {};
-
\ No newline at end of file +
\ 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 index d04baffd95..1ff62a3ed8 100644 --- a/zengin/scripts/extenders/zparserextender/externals/npc/index.html +++ b/zengin/scripts/extenders/zparserextender/externals/npc/index.html @@ -40,4 +40,4 @@

Npc_GetSlotItem

Npc_GetSlotItem

Returns an item from a slot with the slotName

func C_Item Npc_GetSlotItem( var C_Npc npc, var string slotName ) {};
 

Npc_PutInSlot

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_RemoveFromSlot

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) {};
-
\ No newline at end of file +
\ 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 index 5a68abcd47..4da6a32750 100644 --- a/zengin/scripts/extenders/zparserextender/externals/par/index.html +++ b/zengin/scripts/extenders/zparserextender/externals/par/index.html @@ -48,4 +48,4 @@

Par_SetSymbolValueIntArray

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) {};
 

Par_SetSymbolValueFloatArray

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) {};
 

Par_SetSymbolValueStringArray

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) {};
-
\ No newline at end of file +
\ 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 index 51a93cd507..303a6126c3 100644 --- a/zengin/scripts/extenders/zparserextender/externals/string/index.html +++ b/zengin/scripts/extenders/zparserextender/externals/string/index.html @@ -74,4 +74,4 @@

Str_UTF8_to_ANSI

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 ) {};
 

Str_GetCurrentCP

Str_GetCurrentCP

Return the code page corresponding to the current language set in the Union System

func int Str_GetCurrentCP() {};
 

Str_GetLength

Str_GetLength

Returns the length of a string

func int Str_GetLength( var int str ) {};
-
\ No newline at end of file +
\ 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 index f3dafedfd2..57ad506a2a 100644 --- a/zengin/scripts/extenders/zparserextender/externals/vob/index.html +++ b/zengin/scripts/extenders/zparserextender/externals/vob/index.html @@ -52,4 +52,4 @@

Vob_SetMobInterData

Vob_SetMobInterData

Sets the data of the oCMobInter object

func void Vob_SetMobInterData( var C_Vob mobInter, var C_MobInter_Data data ) {};
 

Vob_GetMobInterData

Vob_GetMobInterData

Returns the data of the oCMobLockable object

func C_MobLockable_Data Vob_GetMobInterData( var C_Vob mobLock ) {};
 

Vob_SetMobInterData

Vob_SetMobInterData

Sets the data of the oCMobLockable object

func void Vob_SetMobInterData( var C_Vob mobLock, var C_MobLockable_Data data ) {};
-
\ No newline at end of file +
\ 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 index 63b71d1e99..a0a0ac1266 100644 --- a/zengin/scripts/extenders/zparserextender/externals/wld/index.html +++ b/zengin/scripts/extenders/zparserextender/externals/wld/index.html @@ -58,4 +58,4 @@

Wld_ToggleRain

Wld_ToggleRain

Turns on the rain

func void Wld_ToggleRain( var float weight, var float time ) {};
 

Wld_SetWeatherType

Wld_SetWeatherType

Sets the weather type. Types:

0 - snow 1 - rain

func void Wld_SetWeatherType( var int type ) {};
 

Wld_GetWeatherType

Wld_GetWeatherType

Returns the weather type. Types:

0 - snow 1 - rain

func int Wld_GetWeatherType() {};
-
\ No newline at end of file +
\ No newline at end of file diff --git a/zengin/scripts/extenders/zparserextender/index.html b/zengin/scripts/extenders/zparserextender/index.html index b98d74bb7c..9a41a96800 100644 --- a/zengin/scripts/extenders/zparserextender/index.html +++ b/zengin/scripts/extenders/zparserextender/index.html @@ -31,4 +31,4 @@ const gGMC_PAGE_LOCALE = "en"; const gGMC_FILE_LOCALE = "en"; const gGMC_TRANSLATE_SVG = ''; -

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 +

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/syntax_extensions/dialogues/index.html b/zengin/scripts/extenders/zparserextender/syntax_extensions/dialogues/index.html index e93fb02363..0ec22670eb 100644 --- a/zengin/scripts/extenders/zparserextender/syntax_extensions/dialogues/index.html +++ b/zengin/scripts/extenders/zparserextender/syntax_extensions/dialogues/index.html @@ -50,4 +50,4 @@ 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 +
\ 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 index 6cc2cdb6e8..432c7e9b63 100644 --- a/zengin/scripts/extenders/zparserextender/syntax_extensions/events/index.html +++ b/zengin/scripts/extenders/zparserextender/syntax_extensions/events/index.html @@ -54,4 +54,4 @@ // 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

Define these in any file in your scripts, they will be automatically called

\ No newline at end of file +

Plugin implements two of these event functions

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 index c3f893d72e..c6581c3ddd 100644 --- a/zengin/scripts/extenders/zparserextender/syntax_extensions/extern/index.html +++ b/zengin/scripts/extenders/zparserextender/syntax_extensions/extern/index.html @@ -38,4 +38,4 @@ { // TODO }; -
\ No newline at end of file +
\ 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 index 0cddd89dc0..b06bce81d6 100644 --- a/zengin/scripts/extenders/zparserextender/syntax_extensions/namespaces/index.html +++ b/zengin/scripts/extenders/zparserextender/syntax_extensions/namespaces/index.html @@ -295,4 +295,4 @@ 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 + 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 index bf1a223224..00306ef54f 100644 --- a/zengin/scripts/extenders/zparserextender/syntax_extensions/testelse/index.html +++ b/zengin/scripts/extenders/zparserextender/syntax_extensions/testelse/index.html @@ -47,4 +47,4 @@ { // TODO } -
\ No newline at end of file +
\ 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 index 9f41aec1e6..d728b94635 100644 --- a/zengin/scripts/extenders/zparserextender/syntax_extensions/while/index.html +++ b/zengin/scripts/extenders/zparserextender/syntax_extensions/while/index.html @@ -59,4 +59,4 @@

Note

To activate while it is necessary to set NativeWhile setting in SystemPack.ini

[ZPARSE_EXTENDER]
 NativeWhile = true
-

Compiled while loop works in vanilla engine without the plugin.

\ No newline at end of file +

Compiled while loop works in vanilla engine without the plugin.

\ No newline at end of file diff --git a/zengin/scripts/externals/doc/index.html b/zengin/scripts/externals/doc/index.html index 21087ce988..d05f47cd49 100644 --- a/zengin/scripts/externals/doc/index.html +++ b/zengin/scripts/externals/doc/index.html @@ -296,4 +296,4 @@ var float r6, var float r7, var float r8) {}; -
\ No newline at end of file +
\ No newline at end of file diff --git a/zengin/scripts/externals/index.html b/zengin/scripts/externals/index.html index 253d892c14..5886497c19 100644 --- a/zengin/scripts/externals/index.html +++ b/zengin/scripts/externals/index.html @@ -31,4 +31,4 @@ const gGMC_PAGE_LOCALE = "en"; const gGMC_FILE_LOCALE = "en"; const gGMC_TRANSLATE_SVG = ''; -

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 +

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 index 6926866a76..bfc88572e1 100644 --- a/zengin/scripts/externals/log/index.html +++ b/zengin/scripts/externals/log/index.html @@ -84,4 +84,4 @@ /// @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 +
\ No newline at end of file diff --git a/zengin/scripts/externals/mdl/index.html b/zengin/scripts/externals/mdl/index.html index 8ed0f951f6..f8e0c8fef2 100644 --- a/zengin/scripts/externals/mdl/index.html +++ b/zengin/scripts/externals/mdl/index.html @@ -278,4 +278,4 @@ var float timemax, var float timemaxvar, var float probmin) {}; -
\ No newline at end of file +
\ No newline at end of file diff --git a/zengin/sound/index.html b/zengin/sound/index.html index 61d969da1e..fe84081c86 100644 --- a/zengin/sound/index.html +++ b/zengin/sound/index.html @@ -32,4 +32,4 @@ const gGMC_FILE_LOCALE = "en"; const gGMC_TRANSLATE_SVG = '';

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 + 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 index 21483c0a7d..da5e29dcd5 100644 --- a/zengin/sound/tutorials/change_sfx/index.html +++ b/zengin/sound/tutorials/change_sfx/index.html @@ -31,4 +31,4 @@ const gGMC_PAGE_LOCALE = "en"; const gGMC_FILE_LOCALE = "en"; const gGMC_TRANSLATE_SVG = ''; -

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 +

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/tools/gothic_sourcer/index.html b/zengin/tools/gothic_sourcer/index.html index 1b3a6aecf7..cffdbbfd24 100644 --- a/zengin/tools/gothic_sourcer/index.html +++ b/zengin/tools/gothic_sourcer/index.html @@ -31,4 +31,4 @@ const gGMC_PAGE_LOCALE = "en"; const gGMC_FILE_LOCALE = "en"; const gGMC_TRANSLATE_SVG = ''; -

Gothic Sourcer

Gothic Sourcer can be used to do a lot of things.

Todo

TODO

\ No newline at end of file +

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/index.html b/zengin/tools/index.html index 66ae6e8b0d..fd09e3b9c7 100644 --- a/zengin/tools/index.html +++ b/zengin/tools/index.html @@ -31,4 +31,4 @@ const gGMC_PAGE_LOCALE = "en"; const gGMC_FILE_LOCALE = "en"; const gGMC_TRANSLATE_SVG = ''; -

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.
  • DecDat - Daedalus .DAT files decompiler.
  • Redefix - OutputUnits compiler and updater.

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.

Libraries

  • ZenKit - A library to load, save and use almost all ZenGin asset files

Debugging

  • zSpy - Debugging tool that displays most of the operations performed by the engine during the Gothic or Spacer running, ships with the MDK.
\ No newline at end of file +

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.
  • DecDat - Daedalus .DAT files decompiler.
  • Redefix - OutputUnits compiler and updater.

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.

Libraries

  • ZenKit - A library to load, save and use almost all ZenGin asset files

Debugging

  • zSpy - Debugging tool that displays most of the operations performed by the engine during the Gothic or Spacer running, ships with the MDK.
\ No newline at end of file diff --git a/zengin/tools/zSplitDialogs/index.html b/zengin/tools/zSplitDialogs/index.html index 974c0cad43..6e4f7e245f 100644 --- a/zengin/tools/zSplitDialogs/index.html +++ b/zengin/tools/zSplitDialogs/index.html @@ -34,4 +34,4 @@

zSplitDialogs

The plugin for a dubbing creators. And not only.

Union plugin by Top Layer, which gives possibility to extract dialogues from compiled scripts simply by putting zSplitDialogs.vdf file into Data\ directory and run the game. You can configure, that already dubbed subtitles will be outputed.

The output is the Dialogs\ directory with .txt files with a structure as follow:

Example of a plugin output

zSpy

Download

Source code

The usage

  • Install Union 1.0l+ (zParserExtender is needed - it is inside Union since 1.0l version)
  • Put zSplitDialogs.vdf into Data\ directory
  • Start game
  • Dialogues will be created in Dialogs\ directory

At first run, in gothic.ini will be created following section:

[ZSPLITDIALOGS]
 UnvoicedOnly=0
-

You can change value to 1 to receive only unvoiced subtitles.

\ No newline at end of file +

You can change value to 1 to receive only unvoiced subtitles.

\ No newline at end of file diff --git a/zengin/tools/zSpy/index.html b/zengin/tools/zSpy/index.html index 097bebb8c6..bf2e2eb65d 100644 --- a/zengin/tools/zSpy/index.html +++ b/zengin/tools/zSpy/index.html @@ -46,4 +46,4 @@ 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 +
\ No newline at end of file