# Features ## `OnCodeInit` Called first to generate code. No advanced YSI features are available here (including hooking this callback). If the JIT plugin is in use, this is called from `OnJITCompile`, which means it is the main place to perform code generation. This is why not many YSI features are available - because they might not have been set up yet. ```pawn ReturnFive() { // To be changed to be correct! return 3; } public OnCodeInit() { // Generate some code. new ctx[AsmContext]; // Target `ReturnFive` for rewriting. AsmInitPtr(ctx, addressof (ReturnFive<>), 16); // Write the correct code (`ctx` is used implicitly here). @emit PROC @emit CONST.pri 5 @emit RETN // Basic ALS forwarding only! #if defined Example_OnCodeInit Example_OnCodeInit(); #endif return 1; } #undef OnCodeInit #define OnCodeInit Example_OnCodeInit #if defined Example_OnCodeInit forward Example_OnCodeInit(); #endif ``` ## `OnScriptInit` Called when this script starts. This is the most important callback as it is called once first, regardless of the script type, and all YSI features are now available. ```pawn // Hooks are now available, as are all other YSI features. hook OnScriptInit() { printf("================================"); printf("|| ||"); printf("|| My Mode Started! ||"); printf("|| ||"); printf("================================"); printf("|| ||"); printf("|| Context information: ||"); printf("|| ||"); printf("|| - Gamemode? %s ||", Server_IsGameMode() ? ("yes") : ("no ")); printf("|| - Filterscript? %s ||", Server_IsFilterscript() ? ("yes") : ("no ")); printf("|| - JIT plugin? % ||", Server_JITExists() ? ("yes") : ("no ")); printf("|| %s ||" , Server_JITComplete() ? ("(compiled)") : ("(failed) ")); printf("|| - CrashDetect plugin? %s ||", Server_CrashDetectExists() ? ("yes") : ("no ")); printf("|| ||"); printf("================================"); } ``` ## `PREINIT__` This is a macro for more light-weight initialisations. It is called just before `OnScriptInit`, and is used for minor variables and settings. Note that each `INIT__` function must have a unique name, unlike hooks*. ```pawn PREINIT__ VehicleStreamer() { printf("Vehicle Streamer installed"); } ``` \* Technically hooks also need a unique name, but that is taken care of by y_unique. ## `POSTINIT__` This is identical to `PREINIT__`, but called after `OnScriptInit`. ```pawn POSTINIT__ VehicleStreamer() { printf("Vehicle Streamer initialised"); } ``` ## `PREEXIT__` This is identical to `PREINIT__`, but called before `OnScriptExit`. ## `POSTEXIT__` This is identical to `PREINIT__`, but called after `OnScriptExit`. ```pawn POSTINIT__ VehicleStreamer() { printf("Vehicle Streamer initialised"); } ``` ## `FINAL__` Creates a run-time constant, with compiler enforcement. The value is set in the global scope. ```pawn #include #include FINAL__ gMaxPlayers = GetMaxPlayers(); main() { // Set correctly. printf("%d", gMaxPlayers); // Compile-time error gMaxPlayers = 44; } ``` This is also usable as `final` (without `YSI_NO_KEYWORD_final`). Tags are also checked: ```pawn FINAL__ Float:gMaxPlayers = GetMaxPlayers(); // Tag mismatch warning. ``` ## `OnScriptExit` Called when this script ends, regardless of the type. ```pawn hook OnScriptExit() { printf("================================"); printf("|| ||"); printf("|| My Mode Ended! ||"); printf("|| ||"); printf("================================"); printf("|| ||"); printf("|| It was a %s ||", Server_IsGameMode() ? ("gamemode ") : ("filterscript")); printf("|| ||"); printf("================================"); } ```