-
Notifications
You must be signed in to change notification settings - Fork 0
Writing Your First Module
Please complete the Environment Setup first before you continue with this page.
Every module consists of data, internal and external API and the actual implementation. We'll take a look at an example of what a module could look like in chronological order.
// #include other modules before y_hooks
#include <YSI_Coding\y_hooks>On the very top of the module script, y_hooks needs to be included. This allows us to hook callbacks which we will need for the implementation part at the end. If your module makes use of the external API of another module, it needs to be included here BEFORE the inclusion of y_hooks.
#define SOMESTRING_LEN 32Defines/constants related to the module can just be put beneath the inclusion of y_hooks. Here, we define the maximum of a string length for the data that follows.
enum MODULE_1_DATA {
mod1_someString[SOMESTRING_LEN],
mod1_someInt,
Float:mod1_someFloat
}
static moduleInfo[MODULE_1_DATA];The module-internal data can only be access from within the module itself. In this example, we have a string with the predefined length of 32, an integer and a float. Each of these variables in the enumerator can be accessed via the moduleInfo accessor variable. This accessor must be static in order to limit its scope to the module.
stock Mod1_GetModuleString(string[], size) {
strcat(string, moduleInfo[mod1_someString], size);
return 1;
}
stock Mod1_SetModuleString(const newString[]) {
new oldString[SOMESTRING_LEN];
Mod1_GetModuleString(oldString, sizeof(oldString));
format(moduleInfo[mod1_someString], sizeof(moduleInfo[mod1_someString]), newString);
CallLocalFunction("OnSomeStringModified", "as", oldString, newString);
return 1;
}
stock Float:Mod1_GetModuleFloat() {
return moduleInfo[mod1_someFloat];
}
stock Mod1_SetModuleFloat(Float:float) {
moduleInfo[mod1_someFloat] = float;
return 1;
}
stock Mod1_GetModuleInt() {
return moduleInfo[mod1_someInt];
}
stock Mod1_SetModuleInt(integer) {
moduleInfo[mod1_someInt] = integer;
return 1;
}The external API is a set of functions accessible from other modules. In this example, we provide access to each of our static variables with a getter and a setter function. The stock keyword prevents the compiler from spitting out a warning in case they're not used.
static stock printModuleInfo() {
new string[SOMESTRING_LEN];
Mod1_GetModuleString(string, sizeof(string));
printf("mod1_someString: %s\nmod1_someFloat: %.2f\nmod1_someInt: %d", string, Mod1_GetModuleFloat(), Mod1_GetModuleInt());
return 1;
}The internal API is meant for module-internal use only. Here, we have a simple function that prints out the contents of our module-internal data. The static here is mandatory, the stock is optional.
forward OnSomeStringModified(const oldString[], const newString[]);
public OnSomeStringModified(const oldString[], const newString[]) {
printf("public: oldString: %s | newString: %s", oldString, newString);
return 1;
}You may have noticed that our Mod1_SetModuleString(const newString[]) internal function calls a custom callback named OnSomeStringModified(...) which means that is is called whenever we set mod1_someString with our Mod1_SetModuleString(const newString[]) function. This custom callback needs to be implemented in the module as well so it can later be hooked from other modules. Here, we just let it print out the old string and the new string of the mod1_someString variable.
hook OnGameModeInit() {
print("---------------------------------------------------------------\n");
print("[module1]");
print("\nTesting module interface:");
Mod1_SetModuleString("Hello Module1!");
Mod1_SetModuleFloat(3.41);
Mod1_SetModuleInt(1337);
printModuleInfo();
return 1;
}The implementation is the part that actually brings your module to life. Choose the callbacks you need, hook them and start scripting! In this example, we set the module variables and print them out.
For a full example, please check out the code in this repository.