mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2026-07-06 22:47:01 +00:00
Merge remote-tracking branch 'origin/dev' into shaders
This commit is contained in:
commit
0193cfdede
910 changed files with 1666 additions and 68826 deletions
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
sm64coopdx is an online multiplayer project for the Super Mario 64 PC port that synchronizes all entities and every level for multiple players. The project was started by the Coop Deluxe Team. The purpose is to actively maintain and improve, but also continue sm64ex-coop, created by djoslin0. More features, customization, and power to the Lua API allow modders and players to enjoy Super Mario 64 more than ever!
|
||||
|
||||
Feel free to report bugs or contribute to the project.
|
||||
Feel free to report bugs or contribute to the project.
|
||||
|
||||
## Initial Goal (Accomplished)
|
||||
Create a mod for the PC port where multiple people can play together online.
|
||||
|
|
@ -11,8 +11,9 @@ Unlike previous multiplayer projects, this one synchronizes enemies and events.
|
|||
|
||||
Interestingly enough though, the goal of the project has slowly evolved over time from simply just making a Super Mario 64 multiplayer mod to constantly maintaining and improving the project (notably the Lua API.)
|
||||
|
||||
## Lua
|
||||
sm64coopdx is moddable via Lua, similar to Roblox and Garry's Mod's Lua APIs. To get started, click [here](docs/lua/lua.md) to see the Lua documentation.
|
||||
## Documentation
|
||||
|
||||
sm64coopdx is moddable via Lua, similar to Roblox and Garry's Mod's Lua APIs. To get started, click [here](docs/lua/lua.md) to see the Lua documentation. If you want to contribute to the repo, you can view the C documentation [here](docs/c/c.md).
|
||||
|
||||
## Wiki
|
||||
The wiki is made using GitHub's wiki feature, you can go to the wiki tab or click [here](https://github.com/coop-deluxe/sm64coopdx/wiki).
|
||||
|
|
|
|||
|
|
@ -118,6 +118,7 @@ override_disallowed_functions = {
|
|||
"src/game/mario.h": [ " init_mario" ],
|
||||
"src/pc/djui/djui_console.h": [ " djui_console_create", "djui_console_message_create", "djui_console_message_dequeue" ],
|
||||
"src/pc/djui/djui_chat_message.h": [ "create_from" ],
|
||||
"src/pc/djui/djui_hud_utils.h": [ "djui_hud_clear_interp_data" ],
|
||||
"src/game/interaction.h": [ "process_interaction", "_handle_" ],
|
||||
"src/game/sound_init.h": [ "_loop_", "thread4_", "set_sound_mode" ],
|
||||
"src/pc/network/network_utils.h": [ "network_get_player_text_color[^_]" ],
|
||||
|
|
|
|||
|
|
@ -4750,6 +4750,15 @@ GRAB_POS_BOWSER = 3 --- @type MarioGrabPosGSCId
|
|||
--- | `GRAB_POS_HEAVY_OBJ`
|
||||
--- | `GRAB_POS_BOWSER`
|
||||
|
||||
--- @type integer
|
||||
MOD_FS_COMPRESSION_MIN = 0
|
||||
|
||||
--- @type integer
|
||||
MOD_FS_COMPRESSION_MAX = 9
|
||||
|
||||
--- @type integer
|
||||
MOD_FS_COMPRESSION_DEFAULT = 1
|
||||
|
||||
--- @type integer
|
||||
MOD_FS_MAX_SIZE = 0x2000000
|
||||
|
||||
|
|
@ -8323,10 +8332,11 @@ HOOK_ON_FIND_FLOOR = 62 --- @type LuaHookedEventType
|
|||
HOOK_ON_FIND_WATER_LEVEL = 63 --- @type LuaHookedEventType
|
||||
HOOK_ON_FIND_POISON_GAS_LEVEL = 64 --- @type LuaHookedEventType
|
||||
HOOK_ON_FIND_SURFACE_ON_RAY = 65 --- @type LuaHookedEventType
|
||||
HOOK_ON_REFRESH_SHADERS = 66 --- @type LuaHookedEventType
|
||||
HOOK_ON_VERTEX_SHADER_CREATE = 67 --- @type LuaHookedEventType
|
||||
HOOK_ON_FRAGMENT_SHADER_CREATE = 68 --- @type LuaHookedEventType
|
||||
HOOK_MAX = 69 --- @type LuaHookedEventType
|
||||
HOOK_ON_DYNOS_PACK_TOGGLED = 66 --- @type LuaHookedEventType
|
||||
HOOK_ON_REFRESH_SHADERS = 67 --- @type LuaHookedEventType
|
||||
HOOK_ON_VERTEX_SHADER_CREATE = 68 --- @type LuaHookedEventType
|
||||
HOOK_ON_FRAGMENT_SHADER_CREATE = 69 --- @type LuaHookedEventType
|
||||
HOOK_MAX = 70 --- @type LuaHookedEventType
|
||||
|
||||
--- @alias LuaHookedEventType
|
||||
--- | `HOOK_UPDATE`
|
||||
|
|
@ -8395,6 +8405,7 @@ HOOK_MAX = 69 --- @type LuaHookedEventType
|
|||
--- | `HOOK_ON_FIND_WATER_LEVEL`
|
||||
--- | `HOOK_ON_FIND_POISON_GAS_LEVEL`
|
||||
--- | `HOOK_ON_FIND_SURFACE_ON_RAY`
|
||||
--- | `HOOK_ON_DYNOS_PACK_TOGGLED`
|
||||
--- | `HOOK_ON_REFRESH_SHADERS`
|
||||
--- | `HOOK_ON_VERTEX_SHADER_CREATE`
|
||||
--- | `HOOK_ON_FRAGMENT_SHADER_CREATE`
|
||||
|
|
|
|||
|
|
@ -3837,7 +3837,7 @@ function djui_hud_set_font(fontType)
|
|||
end
|
||||
|
||||
--- @return DjuiColor
|
||||
--- Gets the current DJUI HUD color
|
||||
--- Gets the current DJUI HUD global color
|
||||
function djui_hud_get_color()
|
||||
-- ...
|
||||
end
|
||||
|
|
@ -3846,16 +3846,36 @@ end
|
|||
--- @param g integer
|
||||
--- @param b integer
|
||||
--- @param a integer
|
||||
--- Sets the current DJUI HUD color
|
||||
--- Sets the current DJUI HUD global color
|
||||
function djui_hud_set_color(r, g, b, a)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- Resets the current DJUI HUD color
|
||||
--- Resets the current DJUI HUD global color
|
||||
function djui_hud_reset_color()
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @return DjuiColor
|
||||
--- Gets the current DJUI HUD text default color. This color is overridden by color codes
|
||||
function djui_hud_get_text_color()
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param r integer
|
||||
--- @param g integer
|
||||
--- @param b integer
|
||||
--- @param a integer
|
||||
--- Sets the current DJUI HUD text default color. This color is overridden by color codes
|
||||
function djui_hud_set_text_color(r, g, b, a)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- Resets the current DJUI HUD text default color. This color is overridden by color codes
|
||||
function djui_hud_reset_text_color()
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @return integer rotation
|
||||
--- @return number pivotX
|
||||
--- @return number pivotY
|
||||
|
|
@ -4013,8 +4033,9 @@ function djui_hud_reset_scissor()
|
|||
end
|
||||
|
||||
--- @param message string
|
||||
--- @return number
|
||||
--- Measures the length of `message` in the current font
|
||||
--- @return number width
|
||||
--- @return number height
|
||||
--- Measures the width and height of `message` in the current font
|
||||
function djui_hud_measure_text(message)
|
||||
-- ...
|
||||
end
|
||||
|
|
@ -7742,6 +7763,14 @@ function mod_fs_file_set_public(file, pub)
|
|||
-- ...
|
||||
end
|
||||
|
||||
--- @param file ModFsFile
|
||||
--- @param level integer
|
||||
--- @return boolean
|
||||
--- Sets the compression level of the provided modfs `file`. Must be between 0 (no compression) and 9 (most compression). Returns true on success.
|
||||
function mod_fs_file_set_compression(file, level)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param hide boolean
|
||||
--- Hides script errors raised by `mod_fs` functions. Errors messages are still generated and can be retrieved with `mod_fs_get_last_error()`
|
||||
function mod_fs_hide_errors(hide)
|
||||
|
|
@ -7762,10 +7791,18 @@ function mod_storage_save(key, value)
|
|||
-- ...
|
||||
end
|
||||
|
||||
--- @param key string
|
||||
--- @param value integer
|
||||
--- @return boolean
|
||||
--- Saves a `key` corresponding to an integer `value` to mod storage
|
||||
function mod_storage_save_integer(key, value)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param key string
|
||||
--- @param value number
|
||||
--- @return boolean
|
||||
--- Saves a `key` corresponding to a float `value` to mod storage
|
||||
--- Saves a `key` corresponding to a number `value` to mod storage
|
||||
function mod_storage_save_number(key, value)
|
||||
-- ...
|
||||
end
|
||||
|
|
@ -7785,9 +7822,16 @@ function mod_storage_load(key)
|
|||
-- ...
|
||||
end
|
||||
|
||||
--- @param key string
|
||||
--- @return integer
|
||||
--- Loads an integer `value` from a `key` in mod storage
|
||||
function mod_storage_load_integer(key)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param key string
|
||||
--- @return number
|
||||
--- Loads a float `value` from a `key` in mod storage
|
||||
--- Loads a number `value` from a `key` in mod storage
|
||||
function mod_storage_load_number(key)
|
||||
-- ...
|
||||
end
|
||||
|
|
@ -9077,12 +9121,6 @@ function cur_obj_check_anim_frame_in_range(startFrame, rangeLength)
|
|||
-- ...
|
||||
end
|
||||
|
||||
--- @param a0 Pointer_integer
|
||||
--- @return integer
|
||||
function cur_obj_check_frame_prior_current_frame(a0)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param m MarioState
|
||||
--- @return integer
|
||||
function mario_is_in_air_action(m)
|
||||
|
|
|
|||
|
|
@ -1249,6 +1249,7 @@
|
|||
--- @field public filepath string
|
||||
--- @field public size integer
|
||||
--- @field public offset integer
|
||||
--- @field public compressionLevel integer
|
||||
--- @field public isText boolean
|
||||
--- @field public isPublic boolean
|
||||
--- @field public read_bool fun(file: ModFsFile): boolean
|
||||
|
|
@ -1270,6 +1271,7 @@
|
|||
--- @field public erase fun(file: ModFsFile, length: integer): boolean
|
||||
--- @field public set_text_mode fun(file: ModFsFile, text: boolean): boolean
|
||||
--- @field public set_public fun(file: ModFsFile, pub: boolean): boolean
|
||||
--- @field public set_compression fun(file: ModFsFile, level: integer): boolean
|
||||
|
||||
--- @class NametagsSettings
|
||||
--- @field public showHealth boolean
|
||||
|
|
|
|||
|
|
@ -22,7 +22,8 @@ extern "C" {
|
|||
#define FUNCTION_BHV 2
|
||||
#define FUNCTION_LVL 3
|
||||
|
||||
#define MOD_PACK_INDEX 99
|
||||
#define MOD_PACK_INDEX -1 // the pack index for actors loaded from mods
|
||||
#define PACK_MOD_INDEX -1 // the mod index for actors loaded from packs
|
||||
|
||||
//
|
||||
// Enums
|
||||
|
|
|
|||
|
|
@ -94,6 +94,9 @@ GfxData *DynOS_Actor_LoadFromBinary(const SysPath &aPackFolder, const char *aAct
|
|||
BinFile *_File = DynOS_Bin_Decompress(aFilename);
|
||||
if (_File) {
|
||||
_GfxData = New<GfxData>();
|
||||
if (aAddToPack) {
|
||||
_GfxData->mModIndex = PACK_MOD_INDEX;
|
||||
}
|
||||
for (bool _Done = false; !_Done;) {
|
||||
switch (_File->Read<u8>()) {
|
||||
case DATA_TYPE_LIGHT: DynOS_Lights_Load (_File, _GfxData); break;
|
||||
|
|
|
|||
|
|
@ -465,6 +465,10 @@ void *DynOS_Pointer_Load(BinFile *aFile, GfxData *aGfxData, u32 aValue, u8 aFunc
|
|||
// LUAV
|
||||
if (aValue == LUA_VAR_CODE) {
|
||||
String token; token.Read(aFile);
|
||||
if (aGfxData->mModIndex == PACK_MOD_INDEX) {
|
||||
sys_fatal("Invalid use of Lua function in DynOS pack: %s", token.begin());
|
||||
return NULL;
|
||||
}
|
||||
for (s32 i = 0; i < aGfxData->mLuaTokenList.Count(); i++) {
|
||||
if (token == aGfxData->mLuaTokenList[i]) {
|
||||
return (void*)(uintptr_t)(i+1);
|
||||
|
|
|
|||
|
|
@ -220,7 +220,7 @@ void DynOS_Actor_Override(struct Object* obj, void** aSharedChild) {
|
|||
obj->behavior == smlua_override_behavior(bhvMetalCap) ||
|
||||
obj->behavior == smlua_override_behavior(bhvVanishCap))) {
|
||||
struct NetworkPlayer* np = network_player_from_global_index(obj->globalPlayerIndex);
|
||||
if (np && np->localIndex > 0 && configDynosLocalPlayerModelOnly) {
|
||||
if (np && np->localIndex > 0 && configDynosLocalPlayerModelOnly && it->second.mPackIndex != MOD_PACK_INDEX) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2087,7 +2087,7 @@ static String DynOS_Builtin_Func_CheckMisuse_Internal(s32 aIndex, const char* aD
|
|||
if (aFuncType != builtinFunc.type && (
|
||||
aIndex == i || (aDataName && strcmp(aDataName, builtinFunc.name) == 0) || aData == builtinFunc.func)) {
|
||||
return String(
|
||||
"Invalid use of function %s: trying to assign %s function to %s",
|
||||
"Invalid use of %s function in %s: %s",
|
||||
builtinFunc.name,
|
||||
sDynosBuiltinFuncTypeNames[builtinFunc.type],
|
||||
sDynosBuiltinFuncTypeNames[aFuncType]
|
||||
|
|
|
|||
|
|
@ -151,7 +151,7 @@ PackData* DynOS_Pack_Add(const SysPath& aPath) {
|
|||
const char* displayName = aPath.c_str();
|
||||
const char* ctoken = displayName;
|
||||
while (*ctoken != '\0') {
|
||||
if (*ctoken == '/' || *ctoken == '\\') {
|
||||
if (*ctoken == *PATH_SEPARATOR || *ctoken == *PATH_SEPARATOR_ALT) {
|
||||
if (*(ctoken + 1) != '\0') {
|
||||
displayName = (ctoken + 1);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -502,6 +502,22 @@ bool DynOS_Tex_Get(const char* aTexName, struct TextureInfo* aOutTexInfo) {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// check override
|
||||
auto &_DynosOverrideTextures = DynosOverrideTextures();
|
||||
auto it = _DynosOverrideTextures.find(info->texture);
|
||||
if (it != _DynosOverrideTextures.end() && it->second) {
|
||||
auto *_Node = it->second->node;
|
||||
auto &_Data = _Node->mData;
|
||||
CONVERT_TEXINFO(aTexName);
|
||||
|
||||
// must link to the vanilla built in texture
|
||||
// so that the texture is correctly overridden
|
||||
// when DynOS_Tex_RetrieveNode is called.
|
||||
aOutTexInfo->texture = info->texture;
|
||||
return true;
|
||||
}
|
||||
|
||||
*aOutTexInfo = *info;
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
16
docs/c/c.md
Normal file
16
docs/c/c.md
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
# C Reference
|
||||
|
||||
## Naming Convention
|
||||
|
||||
- Variable names should use `camelCase`
|
||||
- Function names should use `snake_case`
|
||||
- Struct names should use `PascalCase`
|
||||
- Filenames should use `snake_case`
|
||||
- Global variables, or variables that can be accessed in any file, should be prefixed with a `g` (i.e. `gGlobalTimer`)
|
||||
- Static variables, or variables that are only accessed in a single file, should be prefixed with an `s` (i.e. `sOverrideCameraCollision`)
|
||||
- For creating a pointer, `Type *value;` is the proper convention, not `Type* value;`.
|
||||
|
||||
## Sections
|
||||
- [SMLua](sections/smlua.md)
|
||||
- [Config File](sections/configfile.md)
|
||||
- [DJUI](sections/djui.md)
|
||||
38
docs/c/sections/configfile.md
Normal file
38
docs/c/sections/configfile.md
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
## [:rewind: C Reference](../c.md)
|
||||
|
||||
# Config File
|
||||
|
||||
The configuration file is where all of the user's settings are stored. It's a decently easy to use system that allows you to add entries to the config file and use it with ease.
|
||||
|
||||
## Configuring the config file
|
||||
|
||||
Entries for the config file are handled in 2 files, `configfile.c`, and `configfile.h`, both are found in the `src/pc` directory.
|
||||
|
||||
To add an entry, at the top of the file there are a bunch of different variables. Go to wherever you deem appropriate and add your entry. A config file has these valid types:
|
||||
|
||||
```c
|
||||
enum ConfigOptionType {
|
||||
CONFIG_TYPE_BOOL,
|
||||
CONFIG_TYPE_UINT,
|
||||
CONFIG_TYPE_FLOAT,
|
||||
CONFIG_TYPE_BIND,
|
||||
CONFIG_TYPE_STRING,
|
||||
CONFIG_TYPE_U64,
|
||||
CONFIG_TYPE_COLOR,
|
||||
};
|
||||
```
|
||||
|
||||
In the `options` array, you can add in your config file entry. Go to the same place you deemed appropriate, and add in your entry. An entry consists of a name, this is the key used to find your value. It then takes in a type, which is the type of the value. It lastly takes in that value set. These are the possible types of value:
|
||||
|
||||
```c
|
||||
union {
|
||||
bool *boolValue;
|
||||
unsigned int *uintValue;
|
||||
float *floatValue;
|
||||
char *stringValue;
|
||||
u64 *u64Value;
|
||||
u8 (*colorValue)[3];
|
||||
};
|
||||
```
|
||||
|
||||
Lastly, head to the header file, or `configfile.h`, and add your variable there.
|
||||
121
docs/c/sections/djui.md
Normal file
121
docs/c/sections/djui.md
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
## [:rewind: C Reference](../c.md)
|
||||
|
||||
# DJUI
|
||||
|
||||
DJUI, or djoslin0 User Interface, is a custom UI framework for making panels, buttons, and other elements easy to work with.
|
||||
|
||||
## How it works
|
||||
|
||||
Before we get into a list of elements, first we need to clear something up:
|
||||
|
||||
- The DJUI found in Lua is not necessarily the same you will be working with in C. Lua is much more barebones, whereas C mainly uses panels. This documentation does not apply to Lua.
|
||||
|
||||
Now getting back on track, DJUI panels and elements aren't used directly, they're used via DJUI functions. There's quite the list of them, with each element having it's own unique list of functions if necessary. Thankfully, DJUI removes a lot of headache by unifying all elements to contain a `DjuiBase`.
|
||||
|
||||
Every DJUI element has a `DjuiBase`. This base contains properties such as the width, height, position, anchor, color, and more. You can configure a base with it's list of functions. A list of functions can be found in `djui_base.h`, which is found in `src/pc/djui`, along with all the other DJUI files, you'll see this functions pop up.
|
||||
|
||||
There's a few key constants to keep in mind.
|
||||
|
||||
- `DjuiScreenValueType` is a size type. You can make it relative, `DJUI_SVT_RELATIVE`, so a multiplier of the parent's size, or absolute, `DJUI_SVT_ABSOLUTE`, so it's the pixel size set.
|
||||
- `DjuiHAlign` and `DjuiVAlign`, which is the alignment of a base.
|
||||
|
||||
```c
|
||||
enum DjuiScreenValueType { DJUI_SVT_ABSOLUTE, DJUI_SVT_RELATIVE, DJUI_SVT_ASPECT_RATIO };
|
||||
enum DjuiHAlign { DJUI_HALIGN_LEFT, DJUI_HALIGN_CENTER, DJUI_HALIGN_RIGHT };
|
||||
enum DjuiVAlign { DJUI_VALIGN_TOP, DJUI_VALIGN_CENTER, DJUI_VALIGN_BOTTOM };
|
||||
```
|
||||
|
||||
## DJUI Elements
|
||||
|
||||
Working with DJUI elements is easy. Let's take `DjuiText` as an example.
|
||||
|
||||
```c
|
||||
struct DjuiText {
|
||||
struct DjuiBase base;
|
||||
char* message;
|
||||
const struct DjuiFont* font;
|
||||
f32 fontScale;
|
||||
struct DjuiColor dropShadow;
|
||||
enum DjuiHAlign textHAlign;
|
||||
enum DjuiVAlign textVAlign;
|
||||
};
|
||||
```
|
||||
|
||||
Every DJUI element always has a `DjuiBase`, and it's always the first field of the element. In this element there are multiple custom options, but most of it is still configured with functions.
|
||||
|
||||
```c
|
||||
...
|
||||
void djui_text_set_text(struct DjuiText* text, const char* message);
|
||||
void djui_text_set_font(struct DjuiText* text, const struct DjuiFont* font);
|
||||
void djui_text_set_font_scale(struct DjuiText* text, f32 fontScale);
|
||||
void djui_text_set_drop_shadow(struct DjuiText* text, f32 r, f32 g, f32 b, f32 a);
|
||||
void djui_text_set_alignment(struct DjuiText* text, enum DjuiHAlign hAlign, enum DjuiVAlign vAlign);
|
||||
...
|
||||
struct DjuiText* djui_text_create(struct DjuiBase* parent, const char* message);
|
||||
```
|
||||
|
||||
I didn't show all the functions, but as you can see an element can have quite the amount of functions to configure itself.
|
||||
|
||||
Each element has a dedicated creation function. For text, it's `djui_text_create`. A create function allocates memory for the element and adds it's base as a child of the base it was created from. Parent and children management is done through bases. All create functions take in a parent, along with element specific parameters.
|
||||
|
||||
Let's analyze one of these panels.
|
||||
|
||||
```c
|
||||
static void djui_panel_sound_value_change(UNUSED struct DjuiBase* caller) {
|
||||
audio_custom_update_volume();
|
||||
}
|
||||
|
||||
void djui_panel_sound_create(struct DjuiBase* caller) {
|
||||
struct DjuiThreePanel* panel = djui_panel_menu_create(DLANG(SOUND, SOUND), false);
|
||||
struct DjuiBase* body = djui_three_panel_get_body(panel);
|
||||
{
|
||||
djui_slider_create(body, DLANG(SOUND, MASTER_VOLUME), &configMasterVolume, 0, 127, djui_panel_sound_value_change);
|
||||
djui_slider_create(body, DLANG(SOUND, MUSIC_VOLUME), &configMusicVolume, 0, 127, djui_panel_sound_value_change);
|
||||
djui_slider_create(body, DLANG(SOUND, SFX_VOLUME), &configSfxVolume, 0, 127, djui_panel_sound_value_change);
|
||||
djui_slider_create(body, DLANG(SOUND, ENV_VOLUME), &configEnvVolume, 0, 127, djui_panel_sound_value_change);
|
||||
djui_checkbox_create(body, DLANG(SOUND, FADEOUT), &configFadeoutDistantSounds, NULL);
|
||||
djui_checkbox_create(body, DLANG(SOUND, MUTE_FOCUS_LOSS), &configMuteFocusLoss, NULL);
|
||||
djui_button_create(body, DLANG(MENU, BACK), DJUI_BUTTON_STYLE_BACK, djui_panel_menu_back);
|
||||
}
|
||||
|
||||
djui_panel_add(caller, panel, NULL);
|
||||
}
|
||||
```
|
||||
|
||||
Let's look at the `djui_panel_sound_create`.
|
||||
|
||||
- First, a three panel is created by using the `djui_panel_menu_create` function. This is a custom create function specifically designed for creating panels in the main menu or the pause menu. Not all panels require it, some use `djui_three_panel_create`, which is the original panel create function.
|
||||
- `DjuiThreePanel` is a panel containing 3 sections, the header, the body, and the footer. Most of the time the footer is unused, but the header and body are almost always used.
|
||||
- We get the body that is created from the three panel using the `djui_three_panel_get_body` function. This gets the body section of the three panel.
|
||||
- Multiple different elements are created.
|
||||
- `djui_slider_create` takes in it's parent, the name of the slider, a reference to the value (unsigned int) so it can be changed, which typically points to somewhere in the config, the ranges, so a minimum range and a maximum range, and a function for what happens when it's changed.
|
||||
- The on change functions can always be `NULL`, but they are very useful. In this scenario, `djui_panel_sound_value_change` is called, which calls `audio_custom_update_volume`, so the volume is updated to match the slider.
|
||||
- `DLANG` is the language system, it takes in a header key and a normal key. You can see a list of language keys and values in `lang/English.ini`, or any language of your choosing.
|
||||
- `djui_checkbox_create` takes in it's parent, the name of the checkbox, a reference to a boolean, and an on change function call.
|
||||
- As you can see, the on change function call is set to `NULL`, since there's no need for one.
|
||||
- `djui_button_create` takes in it's parent, a name, the style of the button, and a on press function.
|
||||
- To add a panel to the pause menu the `djui_panel_add` function is used, the caller being the previous panel, panel being the current panel, and the last argument being the base that the cursor should go to by default.
|
||||
|
||||
This gets a lot of the basics out of the way, but you can configure a base even more using the base functions. Let's go over some important flow elements.
|
||||
|
||||
### Flow Layout
|
||||
|
||||
`DjuiFlowLayout` allows you to decide how new elements are added. It's actually used by the panel created using `djui_panel_menu_create` internally. A flow layout handles margins, and decides how elements flow. You can have elements flow up, down, left, right, any direction, and you can define the exact size of the margin.
|
||||
|
||||
```c
|
||||
enum DjuiFlowDirection { DJUI_FLOW_DIR_DOWN, DJUI_FLOW_DIR_UP, DJUI_FLOW_DIR_RIGHT, DJUI_FLOW_DIR_LEFT };
|
||||
|
||||
void djui_flow_layout_set_flow_direction(struct DjuiFlowLayout* layout, enum DjuiFlowDirection flowDirection);
|
||||
void djui_flow_layout_set_margin(struct DjuiFlowLayout* layout, f32 margin);
|
||||
void djui_flow_layout_set_margin_type(struct DjuiFlowLayout* layout, enum DjuiScreenValueType marginType);
|
||||
|
||||
struct DjuiFlowLayout* djui_flow_layout_create(struct DjuiBase* parent);
|
||||
```
|
||||
|
||||
You can configure it's size and position via it's base, like any other element.
|
||||
|
||||
When configuring children inside the flow layout, if you scale the base by the relative, only the amount of space currently available is up for sale. So if you create 2 side by side in a flow layout, you would need to calculate it expecting that room not being available. So the first button would take up half the space, or 0.5, and then the next button would need to take up the rest of that space, or 1.0.
|
||||
|
||||
### Rect Container
|
||||
|
||||
A rect container is just an invisible `DjuiRect`. It's just an empty container, so unlike a flow layout, it's children need to behave, and it doesn't hold your hand. The space is not shared between them, so if you use a relative size and tell 2 buttons to use half the space, the full space will be used.
|
||||
131
docs/c/sections/smlua.md
Normal file
131
docs/c/sections/smlua.md
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
## [:rewind: C Reference](../c.md)
|
||||
|
||||
# SMLua
|
||||
|
||||
SMLua is what allows Lua to communicate with SM64. It's the backbone of the modding api, and it contains multiple features that makes development in C convenient.
|
||||
|
||||
## Autogen
|
||||
|
||||
Autogen is the system in place to allow C functions to be generated into Lua functions automatically.
|
||||
|
||||
Autogen can be ran by running `autogen/autogen.sh` in the root directory of your project.
|
||||
|
||||
Autogen needs to be ran for a variety of reasons:
|
||||
|
||||
- Anytime a function's name, parameter, or description is changed
|
||||
- Anytime a struct's name, or variable is changed
|
||||
- Anytime a enum's name, or contents is changed
|
||||
- Anytime a new function or struct is added
|
||||
- Anytime a hook event is added or modified
|
||||
- And much more
|
||||
|
||||
## Adding functions, structs, and constants to autogen
|
||||
|
||||
Constants, functions, and structs are each handled in their own files.
|
||||
|
||||
- `convert_constants.py`
|
||||
- `convert_functions.py`
|
||||
- `convert_structs.py`
|
||||
|
||||
Each file is laid out differently to account for their own needs, the only thing that's the same in each is `in_files`, which tells autogen to look for functions, constants, or structs in a specific file
|
||||
|
||||
### Constants
|
||||
|
||||
Constants is the least used one, so it has the least to go over.
|
||||
|
||||
- `exclude_constants` tells autogen to ignore specific constants. For instance, in `djui_console.h`, we don't want to include `CONSOLE_MAX_TMP_BUFFER`, Lua has no need for that constant, so we exclude it.
|
||||
- `include_constants` tells autogen to add specific constants, and ignore every other constant in that file. For instance, in `mod_storage.h`, there's a bunch of constants we don't want exposed to Lua, so instead of excluding them, we include the few we actually need.
|
||||
|
||||
### Functions
|
||||
|
||||
Functions have quite a bit of options, so let's go over it:
|
||||
|
||||
- `override_allowed_functions` is similar to `include_constants`, it tells autogen to add specific functions and ignore all other functions in the file. It proves especially useful for functions since frequently files contains tons of functions that shouldn't be exposed to Lua.
|
||||
- `override_disallowed_functions` is similar to `exclude_constants`, it tells autogen to ignore specific functions.
|
||||
- `override_hide_functions` tells autogen to not document the function. It still exists in SMLua, and Lua can call it, but it can't see it. This is typically used for deprecated functions.
|
||||
- `override_function_version_excludes` excludes functions from a specific version of the game. It doesn't have too much of a use anymore, so you can ignore it.
|
||||
|
||||
Functions have a unique feature of being able to be documented. In a header file where autogen reads the function and generates documentation and generates an SMLua implementation, you can define a description for the function above it. An example of it and the syntax is as the following:
|
||||
|
||||
```c
|
||||
/* |description|Behavior init function for NPC Toad|descriptionEnd| */
|
||||
void bhv_toad_message_init(void);
|
||||
```
|
||||
|
||||
It can also be multiline:
|
||||
|
||||
```c
|
||||
/* |description|
|
||||
Checks if Mario's current animation has reached its final frame (i.e., the last valid frame in the animation).
|
||||
Useful for deciding when to transition out of an animation-driven action
|
||||
|descriptionEnd| */
|
||||
s32 is_anim_at_end(struct MarioState *m);
|
||||
```
|
||||
|
||||
### Structs
|
||||
|
||||
Structs have the most options, so let's go through it:
|
||||
|
||||
- `override_field_types` changes the type of a field in a struct to something else. It pretty much lies to lua about what it actually is. This usually isn't useful, but in specific scenarios it can be.
|
||||
- `override_field_mutable` tells autogen to make a specific field mutable and also make every other field immutable.
|
||||
- `override_field_invisible` tells autogen to hide a field from Lua. Unlike `override_hide_functions`, it makes the value not accessible at all.
|
||||
- `override_field_deprecated` tells autogen to mark certain fields as deprecated.
|
||||
- `override_field_immutable` tells autogen to make certain fields immutable.
|
||||
- `override_field_version_excludes` tells autogen to exclude specific fields depending on your version. Similarly to `override_function_version_excludes`, it doesn't have too much of a use anymore, so you can ignore it.
|
||||
- `override_allowed_structs` tells autogen to make specific structs visible and tangible to Lua, but remove all other structs from Lua.
|
||||
|
||||
## Hook Events
|
||||
|
||||
Hook events are partially done through autogen and manual C code. Documentation for hooks is manually written out in [hooks.md](../../lua/guides/hooks.md), and sometimes the implementation of a hook event is done manually.
|
||||
|
||||
### Defining a hook event
|
||||
|
||||
Hook events are defined in 2 places, `smlua_hooks.h`, found in `src/pc/lua`, and `smlua_hook_events.inl`, also found in `src/pc/lua`.
|
||||
|
||||
If you want to create a hook, first go to `smlua_hooks.h` and find the `LuaHookedEventType` enum.
|
||||
|
||||
Scroll down to the bottom until you find `HOOK_MAX`. `HOOK_MAX` should always be at the very bottom of the enum, so move your custom hook one spot above it. Add your custom hook there.
|
||||
|
||||
Next, go to `smlua_hook_events.inl`. This is where the magic happens.
|
||||
|
||||
You can define your custom hook with `SMLUA_EVENT_HOOK`. Let's go over how it works and what the parameters are:
|
||||
|
||||
- The very first parameter is your hook defined in `smlua_hook.h`
|
||||
- The next parameter is the hook event return type, here are the options:
|
||||
|
||||
```c
|
||||
enum LuaHookedEventReturn {
|
||||
HOOK_RETURN_NEVER, // Never returns before calling all hooks for a given event, returns true if there is at least one successful callback call
|
||||
HOOK_RETURN_ON_SUCCESSFUL_CALL, // Returns true on first successful callback call, skipping next hooks for a given event
|
||||
HOOK_RETURN_ON_OUTPUT_SET, // Returns true on output set after a successful call, skipping next hooks for a given event
|
||||
};
|
||||
```
|
||||
|
||||
- To reiterate, `HOOK_RETURN_NEVER` should be used if your hook should always go to every single mod. If you don't use `HOOK_RETURN_NEVER`, your hook may only be ran for one instance.
|
||||
- `HOOK_RETURN_ON_SUCCESSFUL_CALL` should be used if you don't want any other mods to use a hook call if the call succeeds for the first mod handling it. It's only used a few times, but it can come in handy.
|
||||
- `HOOK_RETURN_ON_OUTPUT_SET` should be used if you don't want any mod to access a hook that had it's output set by Lua.
|
||||
- If these 3 hook return types don't cover what you are looking for, you need to make a custom implementation, mark this parameter with an `_` if you want to do a custom implementation.
|
||||
- Every argument after is the parameters and return values for Lua, and they are optional. Parameters come first, insert the parameters you want Lua to receive, for instance, `struct MarioState* m` to allow Lua to receive a mario state in the hook event call.
|
||||
- After parameters comes output, or return values. This is optional. To define an output parameter, use the `OUTPUT` macro.
|
||||
- Here is an example hook showcasing this:
|
||||
|
||||
```c
|
||||
// Never end the hook early, so use HOOK_RETURN_NEVER, pass in the current mario state and the hazard types as parameters to lua. Request a boolean from Lua to decide if the hazard should be registered or not.
|
||||
SMLUA_EVENT_HOOK(HOOK_ALLOW_HAZARD_SURFACE, HOOK_RETURN_NEVER, struct MarioState *m, s32 hazardType, OUTPUT bool *allowHazard)
|
||||
```
|
||||
|
||||
### Calling a hook event from C
|
||||
|
||||
Hook events can be called via the `smlua_call_event_hooks`. The best way to explain this function is with an example. Let's use that same hook, `HOOK_ALLOW_HAZARD_SURFACE`.
|
||||
|
||||
```c
|
||||
bool allowHazard = true;
|
||||
smlua_call_event_hooks(HOOK_ALLOW_HAZARD_SURFACE, m, HAZARD_TYPE_LAVA_WALL, &allowHazard);
|
||||
```
|
||||
|
||||
- First, the hook name defined in the `LuaHookedEventType` is inserted.
|
||||
- Each parameter that comes after that follows the same layout as defined in the `SMLUA_EVENT_HOOK` call, including the output.
|
||||
- The output should be a reference so the function can properly set the variable.
|
||||
- If Lua doesn't return anything, the output passed into the function stays as what it was originally, so it serves as a default value. That's why `allowHazard` is set to true.
|
||||
|
||||
After all these changes, remember to rerun autogen. Once that's done, you should have your hook into the game, test it and make sure everything works!
|
||||
|
|
@ -2224,6 +2224,9 @@
|
|||
<br />
|
||||
|
||||
## [mod_fs.h](#mod_fs.h)
|
||||
- MOD_FS_COMPRESSION_MIN
|
||||
- MOD_FS_COMPRESSION_MAX
|
||||
- MOD_FS_COMPRESSION_DEFAULT
|
||||
- MOD_FS_MAX_SIZE
|
||||
- MOD_FS_MAX_FILES
|
||||
- MOD_FS_MAX_PATH
|
||||
|
|
@ -3612,10 +3615,11 @@
|
|||
| HOOK_ON_FIND_WATER_LEVEL | 63 |
|
||||
| HOOK_ON_FIND_POISON_GAS_LEVEL | 64 |
|
||||
| HOOK_ON_FIND_SURFACE_ON_RAY | 65 |
|
||||
| HOOK_ON_REFRESH_SHADERS | 66 |
|
||||
| HOOK_ON_VERTEX_SHADER_CREATE | 67 |
|
||||
| HOOK_ON_FRAGMENT_SHADER_CREATE | 68 |
|
||||
| HOOK_MAX | 69 |
|
||||
| HOOK_ON_DYNOS_PACK_TOGGLED | 66 |
|
||||
| HOOK_ON_REFRESH_SHADERS | 67 |
|
||||
| HOOK_ON_VERTEX_SHADER_CREATE | 68 |
|
||||
| HOOK_ON_FRAGMENT_SHADER_CREATE | 69 |
|
||||
| HOOK_MAX | 70 |
|
||||
- MAX_HOOKED_BEHAVIORS
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
|
|
|||
|
|
@ -1,18 +1,5 @@
|
|||
-- name: Matrix Code
|
||||
-- description: Run /matrix and a builtin texture name to replace with the digital rain
|
||||
-- deluxe: true
|
||||
|
||||
if SM64COOPDX_VERSION == nil then
|
||||
local first = false
|
||||
hook_event(HOOK_ON_LEVEL_INIT, function()
|
||||
if not first then
|
||||
first = true
|
||||
play_sound(SOUND_MENU_CAMERA_BUZZ, gMarioStates[0].marioObj.header.gfx.cameraToObject)
|
||||
djui_chat_message_create("\\#ff7f7f\\Matrix Code is not supported with sm64ex-coop\nas it uses sm64coopdx exclusive Lua functionality.\n\\#dcdcdc\\To use this mod, try out sm64coopdx at\n\\#7f7fff\\https://sm64coopdx.com")
|
||||
end
|
||||
end)
|
||||
return
|
||||
end
|
||||
|
||||
local sMatrixFrames = {}
|
||||
for i = 0, 10 do
|
||||
|
|
|
|||
|
|
@ -2858,7 +2858,7 @@ Sets the current DJUI HUD font
|
|||
## [djui_hud_get_color](#djui_hud_get_color)
|
||||
|
||||
### Description
|
||||
Gets the current DJUI HUD color
|
||||
Gets the current DJUI HUD global color
|
||||
|
||||
### Lua Example
|
||||
`local djuiColorValue = djui_hud_get_color()`
|
||||
|
|
@ -2879,7 +2879,7 @@ Gets the current DJUI HUD color
|
|||
## [djui_hud_set_color](#djui_hud_set_color)
|
||||
|
||||
### Description
|
||||
Sets the current DJUI HUD color
|
||||
Sets the current DJUI HUD global color
|
||||
|
||||
### Lua Example
|
||||
`djui_hud_set_color(r, g, b, a)`
|
||||
|
|
@ -2905,7 +2905,7 @@ Sets the current DJUI HUD color
|
|||
## [djui_hud_reset_color](#djui_hud_reset_color)
|
||||
|
||||
### Description
|
||||
Resets the current DJUI HUD color
|
||||
Resets the current DJUI HUD global color
|
||||
|
||||
### Lua Example
|
||||
`djui_hud_reset_color()`
|
||||
|
|
@ -2923,6 +2923,74 @@ Resets the current DJUI HUD color
|
|||
|
||||
<br />
|
||||
|
||||
## [djui_hud_get_text_color](#djui_hud_get_text_color)
|
||||
|
||||
### Description
|
||||
Gets the current DJUI HUD text default color. This color is overridden by color codes
|
||||
|
||||
### Lua Example
|
||||
`local djuiColorValue = djui_hud_get_text_color()`
|
||||
|
||||
### Parameters
|
||||
- None
|
||||
|
||||
### Returns
|
||||
- [DjuiColor](structs.md#DjuiColor)
|
||||
|
||||
### C Prototype
|
||||
`struct DjuiColor* djui_hud_get_text_color(void);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [djui_hud_set_text_color](#djui_hud_set_text_color)
|
||||
|
||||
### Description
|
||||
Sets the current DJUI HUD text default color. This color is overridden by color codes
|
||||
|
||||
### Lua Example
|
||||
`djui_hud_set_text_color(r, g, b, a)`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
| ----- | ---- |
|
||||
| r | `integer` |
|
||||
| g | `integer` |
|
||||
| b | `integer` |
|
||||
| a | `integer` |
|
||||
|
||||
### Returns
|
||||
- None
|
||||
|
||||
### C Prototype
|
||||
`void djui_hud_set_text_color(u8 r, u8 g, u8 b, u8 a);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [djui_hud_reset_text_color](#djui_hud_reset_text_color)
|
||||
|
||||
### Description
|
||||
Resets the current DJUI HUD text default color. This color is overridden by color codes
|
||||
|
||||
### Lua Example
|
||||
`djui_hud_reset_text_color()`
|
||||
|
||||
### Parameters
|
||||
- None
|
||||
|
||||
### Returns
|
||||
- None
|
||||
|
||||
### C Prototype
|
||||
`void djui_hud_reset_text_color(void);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [djui_hud_get_rotation](#djui_hud_get_rotation)
|
||||
|
||||
### Description
|
||||
|
|
@ -3443,10 +3511,10 @@ Resets the scissor rectangle to a fullscreen state
|
|||
## [djui_hud_measure_text](#djui_hud_measure_text)
|
||||
|
||||
### Description
|
||||
Measures the length of `message` in the current font
|
||||
Measures the width and height of `message` in the current font
|
||||
|
||||
### Lua Example
|
||||
`local numberValue = djui_hud_measure_text(message)`
|
||||
`local width, height = djui_hud_measure_text(message)`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
|
|
@ -3455,9 +3523,10 @@ Measures the length of `message` in the current font
|
|||
|
||||
### Returns
|
||||
- `number`
|
||||
- `number`
|
||||
|
||||
### C Prototype
|
||||
`f32 djui_hud_measure_text(const char* message);`
|
||||
`void djui_hud_measure_text(const char* message, RET f32 *width, RET f32 *height);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
|
|
|
|||
|
|
@ -2117,6 +2117,30 @@ Marks the provided modfs `file` as public (i.e. readable by other mods). Returns
|
|||
|
||||
<br />
|
||||
|
||||
## [mod_fs_file_set_compression](#mod_fs_file_set_compression)
|
||||
|
||||
### Description
|
||||
Sets the compression level of the provided modfs `file`. Must be between 0 (no compression) and 9 (most compression). Returns true on success.
|
||||
|
||||
### Lua Example
|
||||
`local booleanValue = mod_fs_file_set_compression(file, level)`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
| ----- | ---- |
|
||||
| file | [ModFsFile](structs.md#ModFsFile) |
|
||||
| level | `integer` |
|
||||
|
||||
### Returns
|
||||
- `boolean`
|
||||
|
||||
### C Prototype
|
||||
`bool mod_fs_file_set_compression(struct ModFsFile *file, s32 level);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [mod_fs_hide_errors](#mod_fs_hide_errors)
|
||||
|
||||
### Description
|
||||
|
|
@ -2191,10 +2215,34 @@ Saves a `key` corresponding to a string `value` to mod storage
|
|||
|
||||
<br />
|
||||
|
||||
## [mod_storage_save_integer](#mod_storage_save_integer)
|
||||
|
||||
### Description
|
||||
Saves a `key` corresponding to an integer `value` to mod storage
|
||||
|
||||
### Lua Example
|
||||
`local booleanValue = mod_storage_save_integer(key, value)`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
| ----- | ---- |
|
||||
| key | `string` |
|
||||
| value | `integer` |
|
||||
|
||||
### Returns
|
||||
- `boolean`
|
||||
|
||||
### C Prototype
|
||||
`bool mod_storage_save_integer(const char* key, lua_Integer value);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [mod_storage_save_number](#mod_storage_save_number)
|
||||
|
||||
### Description
|
||||
Saves a `key` corresponding to a float `value` to mod storage
|
||||
Saves a `key` corresponding to a number `value` to mod storage
|
||||
|
||||
### Lua Example
|
||||
`local booleanValue = mod_storage_save_number(key, value)`
|
||||
|
|
@ -2209,7 +2257,7 @@ Saves a `key` corresponding to a float `value` to mod storage
|
|||
- `boolean`
|
||||
|
||||
### C Prototype
|
||||
`bool mod_storage_save_number(const char* key, f32 value);`
|
||||
`bool mod_storage_save_number(const char* key, lua_Number value);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
|
|
@ -2262,10 +2310,33 @@ Loads a string `value` from a `key` in mod storage
|
|||
|
||||
<br />
|
||||
|
||||
## [mod_storage_load_integer](#mod_storage_load_integer)
|
||||
|
||||
### Description
|
||||
Loads an integer `value` from a `key` in mod storage
|
||||
|
||||
### Lua Example
|
||||
`local integerValue = mod_storage_load_integer(key)`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
| ----- | ---- |
|
||||
| key | `string` |
|
||||
|
||||
### Returns
|
||||
- `integer`
|
||||
|
||||
### C Prototype
|
||||
`lua_Integer mod_storage_load_integer(const char* key);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [mod_storage_load_number](#mod_storage_load_number)
|
||||
|
||||
### Description
|
||||
Loads a float `value` from a `key` in mod storage
|
||||
Loads a number `value` from a `key` in mod storage
|
||||
|
||||
### Lua Example
|
||||
`local numberValue = mod_storage_load_number(key)`
|
||||
|
|
@ -2279,7 +2350,7 @@ Loads a float `value` from a `key` in mod storage
|
|||
- `number`
|
||||
|
||||
### C Prototype
|
||||
`f32 mod_storage_load_number(const char* key);`
|
||||
`lua_Number mod_storage_load_number(const char* key);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
|
|
|
|||
|
|
@ -1615,26 +1615,6 @@ Multiplies a vector by the transpose of a matrix of the form: `| ? ? ? 0 |` `| ?
|
|||
|
||||
<br />
|
||||
|
||||
## [cur_obj_check_frame_prior_current_frame](#cur_obj_check_frame_prior_current_frame)
|
||||
|
||||
### Lua Example
|
||||
`local integerValue = cur_obj_check_frame_prior_current_frame(a0)`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
| ----- | ---- |
|
||||
| a0 | `Pointer` <`integer`> |
|
||||
|
||||
### Returns
|
||||
- `integer`
|
||||
|
||||
### C Prototype
|
||||
`s32 cur_obj_check_frame_prior_current_frame(s16 *a0);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [mario_is_in_air_action](#mario_is_in_air_action)
|
||||
|
||||
### Lua Example
|
||||
|
|
|
|||
|
|
@ -760,6 +760,9 @@
|
|||
- [djui_hud_get_color](functions-3.md#djui_hud_get_color)
|
||||
- [djui_hud_set_color](functions-3.md#djui_hud_set_color)
|
||||
- [djui_hud_reset_color](functions-3.md#djui_hud_reset_color)
|
||||
- [djui_hud_get_text_color](functions-3.md#djui_hud_get_text_color)
|
||||
- [djui_hud_set_text_color](functions-3.md#djui_hud_set_text_color)
|
||||
- [djui_hud_reset_text_color](functions-3.md#djui_hud_reset_text_color)
|
||||
- [djui_hud_get_rotation](functions-3.md#djui_hud_get_rotation)
|
||||
- [djui_hud_set_rotation](functions-3.md#djui_hud_set_rotation)
|
||||
- [djui_hud_set_rotation_interpolated](functions-3.md#djui_hud_set_rotation_interpolated)
|
||||
|
|
@ -1396,6 +1399,7 @@
|
|||
- [mod_fs_file_erase](functions-5.md#mod_fs_file_erase)
|
||||
- [mod_fs_file_set_text_mode](functions-5.md#mod_fs_file_set_text_mode)
|
||||
- [mod_fs_file_set_public](functions-5.md#mod_fs_file_set_public)
|
||||
- [mod_fs_file_set_compression](functions-5.md#mod_fs_file_set_compression)
|
||||
- [mod_fs_hide_errors](functions-5.md#mod_fs_hide_errors)
|
||||
- [mod_fs_get_last_error](functions-5.md#mod_fs_get_last_error)
|
||||
|
||||
|
|
@ -1403,9 +1407,11 @@
|
|||
|
||||
- mod_storage.h
|
||||
- [mod_storage_save](functions-5.md#mod_storage_save)
|
||||
- [mod_storage_save_integer](functions-5.md#mod_storage_save_integer)
|
||||
- [mod_storage_save_number](functions-5.md#mod_storage_save_number)
|
||||
- [mod_storage_save_bool](functions-5.md#mod_storage_save_bool)
|
||||
- [mod_storage_load](functions-5.md#mod_storage_load)
|
||||
- [mod_storage_load_integer](functions-5.md#mod_storage_load_integer)
|
||||
- [mod_storage_load_number](functions-5.md#mod_storage_load_number)
|
||||
- [mod_storage_load_bool](functions-5.md#mod_storage_load_bool)
|
||||
- [mod_storage_load_all](functions-5.md#mod_storage_load_all)
|
||||
|
|
@ -1609,7 +1615,6 @@
|
|||
- [cur_obj_check_if_at_animation_end](functions-6.md#cur_obj_check_if_at_animation_end)
|
||||
- [cur_obj_check_anim_frame](functions-6.md#cur_obj_check_anim_frame)
|
||||
- [cur_obj_check_anim_frame_in_range](functions-6.md#cur_obj_check_anim_frame_in_range)
|
||||
- [cur_obj_check_frame_prior_current_frame](functions-6.md#cur_obj_check_frame_prior_current_frame)
|
||||
- [mario_is_in_air_action](functions-6.md#mario_is_in_air_action)
|
||||
- [mario_is_dive_sliding](functions-6.md#mario_is_dive_sliding)
|
||||
- [cur_obj_set_y_vel_and_animation](functions-6.md#cur_obj_set_y_vel_and_animation)
|
||||
|
|
|
|||
|
|
@ -157,6 +157,7 @@ The lua functions sent to `hook_event()` will be automatically called by SM64 wh
|
|||
| HOOK_ON_FIND_WATER_LEVEL | Called after water level detection completes. Return a number to override the water level | `number` x, `number` z, `number` waterLevel |
|
||||
| HOOK_ON_FIND_POISON_GAS_LEVEL | Called after poison gas level detection completes. Return a number to override the gas level | `number` x, `number` z, `number` gasLevel |
|
||||
| HOOK_ON_FIND_SURFACE_ON_RAY | Called after ray-surface intersection completes. Return `surface` to override the hit surface, or `surface, hitPos` to override both | `Vec3f` orig, `Vec3f` dir, [Surface](../structs.md#Surface) hitSurface, `Vec3f` hitPos |
|
||||
| HOOK_ON_DYNOS_PACK_TOGGLED | Called after a DynOS pack is toggled | `string` dynosPackName, `boolean` enabled |
|
||||
| HOOK_ON_REFRESH_SHADERS | Called when a shader is refreshed | |
|
||||
| HOOK_ON_VERTEX_SHADER_CREATE | Called when a vertex shader is created. Return a string to override the shader | [ColorCombiner](../structs.md#ColorCombiner) cc, `integer` shaderIndex |
|
||||
| HOOK_ON_FRAGMENT_SHADER_CREATE | Called when a fragment shader is created. Return a string to override the shader | [ColorCombiner](../structs.md#ColorCombiner) cc, `integer` shaderIndex |
|
||||
|
|
|
|||
|
|
@ -126,6 +126,7 @@ print("The ModFS file " .. file.filepath .. " is " .. file.size .. " bytes long.
|
|||
| erase | [`mod_fs_file_erase`](../functions-5.md#mod_fs_file_erase) |
|
||||
| set_text_mode | [`mod_fs_file_set_text_mode`](../functions-5.md#mod_fs_file_set_text_mode) |
|
||||
| set_public | [`mod_fs_file_set_public`](../functions-5.md#mod_fs_file_set_public) |
|
||||
| set_compression | [`mod_fs_file_set_compression`](../functions-5.md#mod_fs_file_set_compression) |
|
||||
|
||||
Methods can be called in Lua with the colon `:` character:
|
||||
```lua
|
||||
|
|
@ -270,3 +271,16 @@ The mod has to explicitly call the method `save` to save its ModFS on the disk.
|
|||
```lua
|
||||
modFs:save()
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
## Compression
|
||||
|
||||
ModFS files can each have their compression level explicitly set. By default this is set to 1 for minimal compression.<br>
|
||||
Although it makes no difference to the total size limit, changing the compression level can be useful if you are trying to optimize for CPU time.<br>
|
||||
The compression level can be any integer between 0-9.<br>
|
||||
```lua
|
||||
file:set_compression(MOD_FS_COMPRESSION_MIN) -- no compression, good for small data that changes frequently
|
||||
|
||||
file:set_compression(MOD_FS_COMPRESSION_MAX) -- max compression, good for large data that is read infrequently
|
||||
```
|
||||
|
|
@ -1,18 +1,12 @@
|
|||
# Lua Reference
|
||||
|
||||
The Lua scripting API is in early development.
|
||||
|
||||
Expect many more things to be supported in the future.
|
||||
|
||||
<br />
|
||||
|
||||
## How to install Lua mods
|
||||
Lua scripts you make can be placed either the `mods` folder in the base directory, or in `<SAVE FILE LOCATION>/mods`
|
||||
Lua scripts you make can be placed either the `mods` folder in the base directory, or in `<SAVE FILE LOCATION>/mods`. You can also drag and drop mods into the window to install them.
|
||||
|
||||
Save file locations:
|
||||
- Windows: `%appdata%/sm64ex-coop`
|
||||
- Linux: `~/.local/share/sm64ex-coop`
|
||||
- MacOS: `~/Library/Application Support/sm64ex-coop`
|
||||
- Windows: `%appdata%/sm64coopdx`
|
||||
- Linux: `~/.local/share/sm64coopdx`
|
||||
- MacOS: `~/Library/Application Support/sm64coopdx`
|
||||
|
||||
<br />
|
||||
|
||||
|
|
@ -30,7 +24,7 @@ Save file locations:
|
|||
- [Structs](structs.md)
|
||||
|
||||
### Guides
|
||||
- [Setting up Visual Studio Code](guides/vs-code-setup.md)
|
||||
- [Setting up Visual Studio Code](guides/vs-code-setup.md)
|
||||
- [Hooks](guides/hooks.md)
|
||||
- [gMarioStates](guides/mario-state.md)
|
||||
- [Behavior Object Lists](guides/object-lists.md)
|
||||
|
|
|
|||
|
|
@ -1841,6 +1841,7 @@
|
|||
| filepath | `string` | read-only |
|
||||
| size | `integer` | read-only |
|
||||
| offset | `integer` | read-only |
|
||||
| compressionLevel | `integer` | read-only |
|
||||
| isText | `boolean` | read-only |
|
||||
| isPublic | `boolean` | read-only |
|
||||
|
||||
|
|
@ -1867,6 +1868,7 @@
|
|||
| erase | [`mod_fs_file_erase`](functions-5.md#mod_fs_file_erase) |
|
||||
| set_text_mode | [`mod_fs_file_set_text_mode`](functions-5.md#mod_fs_file_set_text_mode) |
|
||||
| set_public | [`mod_fs_file_set_public`](functions-5.md#mod_fs_file_set_public) |
|
||||
| set_compression | [`mod_fs_file_set_compression`](functions-5.md#mod_fs_file_set_compression) |
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -199,6 +199,7 @@ INFO_TITLE = "INFO"
|
|||
WARN_DISCORD = "Pozvat hráče pravým kliknutím na jejich profil a potom kliknout na \n'\\#d0d0ff\\Pozvat do Hry\\#dcdcdc\\'.\n\nMůžete pozvat i kanály a servery pomocí kliknutí na tlačíto \\#d0d0ff\\plus\\#dcdcdc\\ vedle okna na chat.\n\nHerní aktivita \\#ffa0a0\\musí být\\#dcdcdc\\ zapnutá ve vašich\nDiscord nastavení.\n\nZobranení jako neviditelný \\#ffa0a0\\zabrání\\#dcdcdc\\ posílání pozvánek."
|
||||
WARN_DISCORD2 = "\\#ffa0a0\\Chyba:\\#dcdcdc\\ Discord se nepodařilo najít.\n\\#a0a0a0\\Zkuste zavřít hru, restartovat Discord a znovu hru otevřít"
|
||||
WARN_SOCKET = "Ujistěte se, že je vaše brána firewall správně nakonfigurována.\nPřímá připojení \\#ffa0a0\\vyžadují\\#dcdcdc\\, abyste v routeru nakonfigurovali přesměrování portů pro přijetí příchozích IPv4 připojení.\n\nPřesměrujte port '\\#d0d0ff\\%d\\#dcdcdc\\' pro UDP. IPv6 je také podporováno."
|
||||
WARN_SOCKET_HIDE = "OK, do not show this again"
|
||||
HOST = "Hostovat"
|
||||
|
||||
[HOST_MODS]
|
||||
|
|
|
|||
|
|
@ -199,6 +199,7 @@ INFO_TITLE = "INFORMATIE"
|
|||
WARN_DISCORD = "Nodig je vrienden uit door op hun reachts klik op hun username te gebruiken en op '\\#d0d0ff\\Invite to Game\\#dcdcdc\\' te klikken.\n\nJe kan kanalen van servers ook uitnodigen door op de \\#d0d0ff\\plus\\#dcdcdc\\ knop te drukken naast de plek waar je chat.\n\nGame activiteit \\#ffa0a0\\moet\\#dcdcdc\\ aaan staan in je \nDiscord gebruikers opties.\n\nOp offline staan \\#ffa0a0\\houd uitnodigingen versturen tegen.\\#dcdcdc\\ "
|
||||
WARN_DISCORD2 = "\\#ffa0a0\\Error:\\#dcdcdc\\ Kan Discord niet vinden.\n\\#a0a0a0\\Probeer om het spel af te sluiten, Discord opnieuw opstarten, en het spel weer op starten."
|
||||
WARN_SOCKET = "Zorg ervoor dat uw firewall correct is geconfigureerd.\nDirecte verbindingen \\#ffa0a0\\vereisen\\#dcdcdc\\ dat u poortdoorschakeling configureert in uw router om IPv4 inkomende verbindingen te accepteren.\n\nSchakel poort '\\#d0d0ff\\%d\\#dcdcdc\\' door voor UDP. IPv6 wordt ook ondersteund."
|
||||
WARN_SOCKET_HIDE = "OK, do not show this again"
|
||||
HOST = "Organisator"
|
||||
|
||||
[HOST_MODS]
|
||||
|
|
|
|||
|
|
@ -199,6 +199,7 @@ INFO_TITLE = "INFO"
|
|||
WARN_DISCORD = "Invite friends by right clicking their name on Discord and clicking on\n'\\#d0d0ff\\Invite to Game\\#dcdcdc\\'.\n\nYou can invite channels of servers as well by clicking the \\#d0d0ff\\plus\\#dcdcdc\\ button next to the place where you enter chat.\n\nGame Activity \\#ffa0a0\\must be\\#dcdcdc\\ enabled in your\nDiscord user settings.\n\nAppearing offline \\#ffa0a0\\will prevent\\#dcdcdc\\ invites from being sent."
|
||||
WARN_DISCORD2 = "\\#ffa0a0\\Error:\\#dcdcdc\\ Could not detect Discord.\n\n\\#a0a0a0\\Try closing the game,\nrestarting Discord,\nand opening the game again."
|
||||
WARN_SOCKET = "Make sure your firewall is properly configured.\nDirect connections \\#ffa0a0\\requires you\\#dcdcdc\\ to configure port forwarding in your router to accept IPv4 inbound connections.\n\nForward port '\\#d0d0ff\\%d\\#dcdcdc\\' for UDP. IPv6 is also supported."
|
||||
WARN_SOCKET_HIDE = "OK, do not show this again"
|
||||
HOST = "Host"
|
||||
|
||||
[HOST_MODS]
|
||||
|
|
|
|||
|
|
@ -199,6 +199,7 @@ INFO_TITLE = "INFORMATIONS"
|
|||
WARN_DISCORD = "Invitez des amis en faisant un clic droit sur \nleur pseudo Discord puis en cliquant sur \n'\\#d0d0ff\\Inviter à rejoindre\\#dcdcdc\\'.\n\nVous pouvez envoyer des invitations dans les chats de serveurs en cliquant\nsur le bouton \\#d0d0ff\\+\\#dcdcdc\\ à coté de la barre de chat.\n\nLe statut d'activité \\#ffa0a0\\doit-être\\#dcdcdc\\ activé dans les paramètres utilisateurs Discord.\n\nApparaître hors-ligne \\#ffa0a0\\empêchera\\#dcdcdc\\ les invitations\nd'être envoyées."
|
||||
WARN_DISCORD2 = "\\#ffa0a0\\Erreur:\\#dcdcdc\\ Discord n'est pas détecté.\n\n\\#a0a0a0\\Essayez de fermer le jeu,\nrelancer Discord,\net relancer le jeu."
|
||||
WARN_SOCKET = "Assurez-vous que votre pare-feu est correctement configuré.\nLes connexions directes \\#ffa0a0\\vous oblige\\#dcdcdc\\ à configurer le transfert de port sur votre routeur pour accepter les connexions entrantes IPv4.\n\nRedirigez le port '\\#d0d0ff\\%d\\#dcdcdc\\' pour UDP. IPv6 est également pris en charge."
|
||||
WARN_SOCKET_HIDE = "OK, do not show this again"
|
||||
HOST = "Héberger"
|
||||
|
||||
[HOST_MODS]
|
||||
|
|
|
|||
|
|
@ -199,6 +199,7 @@ INFO_TITLE = "INFO"
|
|||
WARN_DISCORD = "Lade Freunde über Discord ein, indem du rechtsklick auf ihren Namen machst und '\\#d0d0ff\\Zum Spiel einladen\\#dcdcdc\\' auswählst. Kanäle können auch über das \\#d0d0ff\\Plus-Symbol\\#dcdcdc\\ eingeladen werden. Stelle sicher, dass die Spielaktivität in den Discord-Einstellungen aktiviert ist. Wenn du offline angezeigt wirst, kannst du keine Einladungen senden."
|
||||
WARN_DISCORD2 = "\\#ffa0a0\\Fehlermeldung:\\#dcdcdc\\ Discord nicht gefunden. Versuche das Spiel zu schließen, Discord zu starten und dann das Spiel erneut zu öffnen."
|
||||
WARN_SOCKET = "Stelle sicher, dass Deine Firewall ordnungsgemäß konfiguriert ist. Direkte Verbindungen \\#ffa0a0\\erfordern\\#dcdcdc\\ die Konfiguration der Portweiterleitung (Port Forwarding) in Deinem Router, um eingehende IPv4-Verbindungen zu akzeptieren.\n\nLeite den Port '\\#d0d0ff\\%d\\#dcdcdc\\' für UDP weiter. IPv6 wird ebenfalls unterstützt."
|
||||
WARN_SOCKET_HIDE = "OK, do not show this again"
|
||||
HOST = "Hosten"
|
||||
|
||||
[HOST_MODS]
|
||||
|
|
|
|||
|
|
@ -197,6 +197,7 @@ INFO_TITLE = "INFO"
|
|||
WARN_DISCORD = "Invita gli amici facendo tasto destro sul loro nome in Discord e cliccando\n'\\#d0d0ff\\Invito a giocare\\#dcdcdc\\'.\n\npuoi invitare anche i canali dei server cliccando il pulsante \\#d0d0ff\\+\\#dcdcdc\\ vicino al posto dove scrivi.\n\nLo Stato delle Attività \\#ffa0a0\\deve essere\\#dcdcdc\\ attivo nelle\nimpostazioni utente di Discord.\n\nApparire offline \\#ffa0a0\\ti impedirà\\#dcdcdc\\ di inviare inviti."
|
||||
WARN_DISCORD2 = "\\#ffa0a0\\Errore:\\#dcdcdc\\ Impossibile individuare Discord.\n\n\\#a0a0a0\\prova a chiudre il gioco,\nriavviare Discord,\ne aprire di nuovo il gioco."
|
||||
WARN_SOCKET = "Assicurati che il tuo firewall sia configurato correttamente.\nLe connessioni dirette \\#ffa0a0\\richiedono\\#dcdcdc\\ di configurare l'inoltro delle porte del tuo router per accettare connessioni in entrata IPv4.\n\nInoltra la porta '\\#d0d0ff\\%d\\#dcdcdc\\' per UDP. Anche IPv6 è supportato."
|
||||
WARN_SOCKET_HIDE = "OK, do not show this again"
|
||||
HOST = "Crea"
|
||||
|
||||
[HOST_MODS]
|
||||
|
|
|
|||
|
|
@ -199,6 +199,7 @@ INFO_TITLE = "INFO"
|
|||
WARN_DISCORD = "招待したいフレンドを右クリックしてn'\\#d0d0ff\\ゲームに招待\\#dcdcdc\\'.\n\nを押すと招待できます。サーバー内のチャンネルにも、チャット入力欄の横にある\\#d0d0ff\\+\\#dcdcdc\\マークから招待メッセージを送信できます。\n\nDiscordのユーザー設定からゲーム アクティビティを\\#ffa0a0\\必ず\\#dcdcdc\\有効にしてください。\n\n\nステータスをオフラインに設定していると、招待の送信が\\#ffa0a0\\妨げられる\\#dcdcdc\\可能性があります。"
|
||||
WARN_DISCORD2 = "\\#ffa0a0\\エラー:\\#dcdcdc\\Discordを検出できませんでした。\n\\#a0a0a0\\ゲームを終了してDiscordを再起動してから、もう一度お試しください。"
|
||||
WARN_SOCKET = "ファイアウォールの設定が正しく完了していることを確認してください。\nダイレクト接続には\\#ffa0a0\\あなた自身が\\#dcdcdc\\ルーターでIPv4の接続を受け入れるようにポートフォワーディング設定を行う必要があります。\n\nUDPポート'\\#d0d0ff\\%d\\#dcdcdc\\'を解放してください。IPv6も使用可能です。"
|
||||
WARN_SOCKET_HIDE = "OK, do not show this again"
|
||||
HOST = "ルームを作る"
|
||||
|
||||
[HOST_MODS]
|
||||
|
|
|
|||
|
|
@ -199,6 +199,7 @@ INFO_TITLE = "INFORMACJA"
|
|||
WARN_DISCORD = "Zaproś znajomych do gry, klikając PPM w ich nazwę na Discordzie, a potem klikając\n'\\#d0d0ff\\Zaproś do gry\\#c8c8c8\\'.\n\nMożesz zapraszać na kanałach serwerów klikając w \\#d0d0ff\\plusik\\#c8c8c8\\ obok paska czatu.\n\n \\#ffa0a0\\Należy\\#c8c8c8\\ mieć włączoną Aktywność w grze w\nUstawieniach użytkownika Discorda.\n\nTryb offline \\#ffa0a0\\uniemożliwi\\#c8c8c8\\ wysyłanie zaproszeń."
|
||||
WARN_DISCORD2 = "\\#ffa0a0\\Błąd:\\#c8c8c8\\ Nie wykryto Discorda.\n\n\\#a0a0a0\\Spróbuj zamknąć grę,\nzrestartować Discorda\ni uruchomić grę ponownie."
|
||||
WARN_SOCKET = "Upewnij się, że twoja zapora jest poprawnie skonfigurowana.\nBezpośrednie połączenia \\#ffa0a0\\wymagają\\#dcdcdc\\ skonfigurowania przekierowania portów w routerze, aby akceptować przychodzące połączenia IPv4.\n\nPrzekieruj port '\\#d0d0ff\\%d\\#dcdcdc\\' dla UDP. IPv6 jest również obsługiwane."
|
||||
WARN_SOCKET_HIDE = "OK, do not show this again"
|
||||
HOST = "Hostuj"
|
||||
|
||||
[HOST_MODS]
|
||||
|
|
|
|||
|
|
@ -199,6 +199,7 @@ INFO_TITLE = "INFO"
|
|||
WARN_DISCORD = "Convide amigos clicando com o botão direito do mouse em seus nomes no Discord e selecionando\n'\\#d0d0ff\\Convidar para o jogo\\#dcdcdc\\'.\n\nVocê também pode enviar convites em canais de servidores clicando no sinal de \\#d0d0ff\\mais\\#dcdcdc\\ na caixa de texto abaixo das mensagens.\n\nÉ preciso configurar a \\#ffa0a0\\privacidade das atividades\\#dcdcdc\\ nas\nsuas configurações do Discord.\n\nSe seu status estiver como offline, você \\#ffa0a0\\não poderá\\#dcdcdc\\ enviar convites."
|
||||
WARN_DISCORD2 = "\\#ffa0a0\\Erro:\\#dcdcdc\\ Discord não detectado.\n\n\\#a0a0a0\\Tente fechar o jogo,\nreiniciar o Discord,\ne abrir o jogo novamente."
|
||||
WARN_SOCKET = "Verifique se o seu firewall está bem configurado.\nPara usar a conexão direta, você precisa \\#ffa0a0\\configurar o encaminhamento de porta em seu roteador\\#dcdcdc\\ para aceitar a entrada de conexões IPv4.\n\nEncaminhe a porta '\\#d0d0ff\\%d\\#dcdcdc\\' para UDP. Também há suporte para IPv6."
|
||||
WARN_SOCKET_HIDE = "OK, não me mostre isso novamente"
|
||||
HOST = "Criar"
|
||||
|
||||
[HOST_MODS]
|
||||
|
|
|
|||
|
|
@ -198,6 +198,7 @@ INFO_TITLE = "INFO"
|
|||
WARN_DISCORD = "Пригласите друзей, щелкнув правой кнопкой мыши их имя в Дискорд, и, выбрав\n'\\#d0d0ff\\Пригласить в игру\\#dcdcdc\\'.\n\nВы также можете пригласить каналы серверов, нажав кнопку \\#d0d0ff\\плюс,\\#dcdcdc\\ кнопку рядом с местом входа в чат.\n\nИгровая активность \\#ffa0a0\\должна быть\\#dcdcdc\\ включена в ваших\n настройках Дискорда.\n\nИспользование офлайн статуса \\#ffa0a0\\предотвратит отправку \\#dcdcdc\\ приглашений."
|
||||
WARN_DISCORD2 = "\\#ffa0a0\\Error:\\#dcdcdc\\ Не удалось обнаружить Дискорд.\n\n\\#a0a0a0\\Попробуйте закрыть игру,\nперезапустите Дискорд,\nи снова откройте игру."
|
||||
WARN_SOCKET = "Убедитесь, что ваш файрвол настроен правильно.\nПрямые подключения \\#ffa0a0\\требуют от вас\\#dcdcdc\\ настройки проброса портов на вашем маршрутизаторе для приeма входящих подключений по IPv4.\n\nПеренаправьте порт '\\#d0d0ff\\%d\\#dcdcdc\\' для UDP. IPv6 также поддерживается."
|
||||
WARN_SOCKET_HIDE = "ОК, больше не показывать"
|
||||
HOST = "Хост"
|
||||
|
||||
[HOST_MODS]
|
||||
|
|
|
|||
|
|
@ -199,6 +199,7 @@ INFO_TITLE = "INFO"
|
|||
WARN_DISCORD = "Invita a amigos haciendo click derecho en su nombre en Discord y seleccionando\n'\\#d0d0ff\\Invitar a unirse\\#dcdcdc\\'.\n\nPuedes invitar en canales de un servidor también presionando el botón \\#d0d0ff\\+\\#dcdcdc\\ al lado del cuadro de texto del chat.\n\nEl estado de Actividad Actual \\#ffa0a0\\debe estar\\#dcdcdc\\ activado en tus ajustes de Discord.\n\nEstar invisible \\#ffa0a0\\te prevendrá\\#dcdcdc\\ de crear invitaciones."
|
||||
WARN_DISCORD2 = "\\#ffa0a0\\Error:\\#dcdcdc\\ No se ha detectado Discord.\n\n\\#a0a0a0\\Prueba a cerrar el juego,\nreiniciar Discord,\ny abrir el juego de nuevo."
|
||||
WARN_SOCKET = "Asegúrate de que tu firewall esté configurado correctamente.\nLas conexiones directas \\#ffa0a0\\requieren que\\#dcdcdc\\ configures el reenvío de puertos en tu router para aceptar conexiones entrantes IPv4.\n\nReenvía el puerto '\\#d0d0ff\\%d\\#dcdcdc\\' para UDP. IPv6 también es compatible."
|
||||
WARN_SOCKET_HIDE = "OK, no volver a mostrar esto"
|
||||
HOST = "Crear"
|
||||
|
||||
[HOST_MODS]
|
||||
|
|
|
|||
|
|
@ -1,93 +0,0 @@
|
|||
--- Don't add any functional code to this file ---
|
||||
--- @meta
|
||||
|
||||
--- @class LuigiState
|
||||
|
||||
--- @class ToadState
|
||||
|
||||
--- @class WarioState
|
||||
|
||||
--- @class WaluigiState
|
||||
|
||||
--- @class ToadetteState
|
||||
--- @field public averageForwardVel number
|
||||
|
||||
--- @class PeachState
|
||||
|
||||
--- @class DaisyState
|
||||
|
||||
--- @class YoshiState
|
||||
|
||||
--- @class BirdoState
|
||||
--- @field public spitTimer integer
|
||||
--- @field public framesSinceShoot integer
|
||||
--- @field public flameCharge integer
|
||||
|
||||
--- @class SpikeState
|
||||
|
||||
--- @class PaulineState
|
||||
|
||||
--- @class RosalinaState
|
||||
--- @field public canSpin boolean
|
||||
--- @field public orbitObjActive boolean
|
||||
--- @field public orbitObjDist number
|
||||
--- @field public orbitObjAngle integer
|
||||
|
||||
--- @class WapeachState
|
||||
|
||||
--- @class DonkeyKongState
|
||||
|
||||
--- @class SonicState
|
||||
--- @field public spinCharge integer
|
||||
--- @field public groundYVel integer
|
||||
--- @field public prevForwardVel integer
|
||||
--- @field public peakHeight integer
|
||||
--- @field public actionADone boolean
|
||||
--- @field public actionBDone boolean
|
||||
--- @field public bounced boolean
|
||||
--- @field public spindashState integer
|
||||
--- @field public instashieldTimer integer
|
||||
--- @field public oxygen integer
|
||||
--- @field public prevVelY number
|
||||
--- @field public prevHeight number
|
||||
--- @field public physTimer integer
|
||||
--- @field public lastforwardPos Vec3f
|
||||
--- @field public realFVel number
|
||||
|
||||
--- @class CharacterState
|
||||
--- @field public mario MarioState
|
||||
--- @field public luigi LuigiState
|
||||
--- @field public toad ToadState
|
||||
--- @field public wario WarioState
|
||||
--- @field public waluigi WaluigiState
|
||||
--- @field public toadette ToadetteState
|
||||
--- @field public peach PeachState
|
||||
--- @field public daisy DaisyState
|
||||
--- @field public yoshi YoshiState
|
||||
--- @field public birdo BirdoState
|
||||
--- @field public spike SpikeState
|
||||
--- @field public pauline PaulineState
|
||||
--- @field public rosalina RosalinaState
|
||||
--- @field public wapeach WapeachState
|
||||
--- @field public donkeyKong DonkeyKongState
|
||||
--- @field public sonic SonicState
|
||||
|
||||
--- @alias SonicMouthGSCId
|
||||
--- | `SONIC_MOUTH_NORMAL`
|
||||
--- | `SONIC_MOUTH_FROWN`
|
||||
--- | `SONIC_MOUTH_GRIMACING`
|
||||
--- | `SONIC_MOUTH_HAPPY`
|
||||
--- | `SONIC_MOUTH_GRIN`
|
||||
--- | `SONIC_MOUTH_ATTACKED`
|
||||
--- | `SONIC_MOUTH_SHOCKED`
|
||||
--- | `SONIC_MOUTH_SURPRISED`
|
||||
--- | `SONIC_MOUTH_NEUTRAL`
|
||||
|
||||
--- @alias SonicMouthSideGSCId
|
||||
--- | `SONIC_MOUTH_LEFT`
|
||||
--- | `SONIC_MOUTH_RIGHT`
|
||||
|
||||
--- @alias HandParam
|
||||
--- | `SONIC_HAND_RIGHT`
|
||||
--- | `SONIC_HAND_LEFT`
|
||||
--- | `WAPEACH_HAND_AXE`
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
-- Environment inclusions --
|
||||
--[[
|
||||
We only need to include character select rn
|
||||
]]
|
||||
|
||||
charSelect = charSelect
|
||||
|
||||
if not charSelect then return end
|
||||
_ENV = setmetatable(_G, { __index = charSelect })
|
||||
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
--- Misc Functions ---
|
||||
|
||||
--- @param m MarioState
|
||||
--- @param name string
|
||||
--- @param accel? number
|
||||
--- Plays a custom animation for MarioState `m`
|
||||
function play_custom_anim(m, name, accel)
|
||||
accel = accel or 0x10000
|
||||
|
||||
m.marioObj.header.gfx.animInfo.animAccel = accel
|
||||
|
||||
if (smlua_anim_util_get_current_animation_name(m.marioObj) ~= name or m.marioObj.header.gfx.animInfo.animID ~= -1) then
|
||||
m.marioObj.header.gfx.animInfo.animID = -1
|
||||
set_anim_to_frame(m, 0)
|
||||
end
|
||||
|
||||
smlua_anim_util_set_animation(m.marioObj, name)
|
||||
end
|
||||
|
||||
--- @param str string
|
||||
--- @param splitAt? string
|
||||
function string.split(str, splitAt)
|
||||
if splitAt == nil then
|
||||
splitAt = " "
|
||||
end
|
||||
local result = {}
|
||||
for match in str:gmatch(string.format("[^%s]+", splitAt)) do
|
||||
table.insert(result, match)
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
|
@ -1,148 +0,0 @@
|
|||
local colObjLists = { OBJ_LIST_GENACTOR, OBJ_LIST_PUSHABLE, OBJ_LIST_SURFACE, OBJ_LIST_DESTRUCTIVE }
|
||||
|
||||
local bhvBlacklist = {
|
||||
[id_bhvBowser] = true,
|
||||
[id_bhvDoor] = true,
|
||||
[id_bhvDoorWarp] = true,
|
||||
[id_bhvStarDoor] = true,
|
||||
[id_bhvUnlockDoorStar] = true,
|
||||
[id_bhvToadMessage] = true,
|
||||
[id_bhvFireSpitter] = true,
|
||||
[id_bhvExplosion] = true
|
||||
}
|
||||
|
||||
---@param o Object
|
||||
---@param o2 Object
|
||||
local function attack_bounce(o, o2)
|
||||
o2.oVelY = 15.0
|
||||
play_sound(SOUND_ACTION_BONK, o2.header.gfx.cameraToObject)
|
||||
end
|
||||
|
||||
---@param o Object
|
||||
---@param o2 Object
|
||||
local function attack_bully(o, o2)
|
||||
o2.oBullyLastNetworkPlayerIndex = o.globalPlayerIndex
|
||||
o2.oMoveAngleYaw = o.oMoveAngleYaw
|
||||
o2.oForwardVel = 30.0
|
||||
|
||||
o2.oInteractStatus = o2.oInteractStatus | ATTACK_FAST_ATTACK | INT_STATUS_WAS_ATTACKED | INT_STATUS_INTERACTED
|
||||
end
|
||||
|
||||
---@param o Object
|
||||
---@param o2 Object
|
||||
local function attack_bully_strong(o, o2)
|
||||
o2.oBullyLastNetworkPlayerIndex = o.globalPlayerIndex
|
||||
o2.oMoveAngleYaw = o.oMoveAngleYaw
|
||||
o2.oForwardVel = 50.0
|
||||
o2.oVelY = 30.0
|
||||
|
||||
o2.oInteractStatus = o2.oInteractStatus | ATTACK_FAST_ATTACK | INT_STATUS_WAS_ATTACKED | INT_STATUS_INTERACTED
|
||||
end
|
||||
|
||||
---@param o Object
|
||||
---@param o2 Object
|
||||
local function attack_mrblizzard(o, o2)
|
||||
if o2.prevObj then
|
||||
o2.prevObj.oAction = 2
|
||||
o2.prevObj = nil
|
||||
o2.oMrBlizzardHeldObj = nil
|
||||
end
|
||||
o2.oAction = MR_BLIZZARD_ACT_DEATH
|
||||
end
|
||||
|
||||
---@param o Object
|
||||
---@param o2 Object
|
||||
local function attack_bullet_bill(o, o2)
|
||||
spawn_mist_particles_with_sound(SOUND_GENERAL2_BOBOMB_EXPLOSION)
|
||||
o2.oAction = 4
|
||||
o2.oTimer = 0
|
||||
end
|
||||
|
||||
---@param o Object
|
||||
---@param o2 Object
|
||||
local function attack_chuckya(o, o2)
|
||||
o2.oAction = 2
|
||||
o2.oVelY = 30
|
||||
o2.oMoveAngleYaw = o.oMoveAngleYaw
|
||||
o2.oForwardVel = 25
|
||||
end
|
||||
|
||||
---@param o Object
|
||||
---@param o2 Object
|
||||
local function attack_whomp(o, o2)
|
||||
o2.oAction = 8
|
||||
end
|
||||
|
||||
---@param o Object
|
||||
---@param o2 Object
|
||||
local function attack_kingbobomb(o, o2)
|
||||
if o2.oFlags & OBJ_FLAG_HOLDABLE ~= 0 and o2.oAction ~= 8 then
|
||||
o2.oVelY = 30
|
||||
o2.oForwardVel = 30
|
||||
o2.oMoveAngleYaw = o.oMoveAngleYaw
|
||||
o2.oMoveFlags = 0
|
||||
o2.oAction = 4
|
||||
end
|
||||
end
|
||||
|
||||
---@param o Object
|
||||
---@param o2 Object
|
||||
local function attack_wooden_post(o, o2)
|
||||
o2.oWoodenPostMarioPounding = 1
|
||||
o2.oWoodenPostSpeedY = -100.0
|
||||
cur_obj_play_sound_2(SOUND_GENERAL_POUND_WOOD_POST)
|
||||
end
|
||||
|
||||
-- lists for edge case interactions
|
||||
|
||||
bhvWapeachAxeAttacks = {
|
||||
[id_bhvSmallBully] = attack_bully_strong,
|
||||
[id_bhvBigBully] = attack_bully_strong,
|
||||
[id_bhvBigBullyWithMinions] = attack_bully_strong,
|
||||
[id_bhvSmallChillBully] = attack_bully_strong,
|
||||
[id_bhvBigChillBully] = attack_bully_strong,
|
||||
[id_bhvMrBlizzard] = attack_mrblizzard,
|
||||
[id_bhvBulletBill] = attack_bullet_bill,
|
||||
[id_bhvSmallWhomp] = attack_whomp,
|
||||
[id_bhvChuckya] = attack_chuckya,
|
||||
[id_bhvWoodenPost] = attack_wooden_post,
|
||||
}
|
||||
|
||||
---@param o Object
|
||||
---@param spAttacksList table<BehaviorId,function>
|
||||
---@param getTarget? boolean
|
||||
function obj_process_attacks(o, spAttacksList, getTarget)
|
||||
-- players
|
||||
if o.oInteractType == 0 then
|
||||
local m = nearest_mario_state_to_object(o)
|
||||
if m and m.playerIndex == 0 and m.marioObj.globalPlayerIndex ~= o.globalPlayerIndex
|
||||
and m.action & (ACT_FLAG_INVULNERABLE | ACT_FLAG_INTANGIBLE) == 0 and m.invincTimer == 0
|
||||
and obj_check_hitbox_overlap(m.marioObj, o) then
|
||||
if spAttacksList[id_bhvMario] then
|
||||
spAttacksList[id_bhvMario](o, m)
|
||||
else
|
||||
take_damage_and_knock_back(m, o)
|
||||
end
|
||||
if getTarget then return m.marioObj end
|
||||
end
|
||||
end
|
||||
-- other objects
|
||||
for i, list in ipairs(colObjLists) do
|
||||
local o2 = obj_get_first(list)
|
||||
while o2 do
|
||||
if o ~= o2 and o2.oInteractStatus & INT_STATUS_INTERACTED == 0 and o2.oIntangibleTimer == 0 and obj_check_hitbox_overlap(o, o2) then
|
||||
local bhv = get_id_from_behavior(o2.behavior)
|
||||
if not bhvBlacklist[bhv] then
|
||||
if spAttacksList[bhv] then
|
||||
spAttacksList[bhv](o, o2)
|
||||
else
|
||||
o2.oInteractStatus = o2.oInteractStatus | ATTACK_FAST_ATTACK | INT_STATUS_WAS_ATTACKED |
|
||||
INT_STATUS_INTERACTED
|
||||
end
|
||||
if getTarget then return o2 end
|
||||
end
|
||||
end
|
||||
o2 = obj_get_next(o2)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
--- Vars that all movesets use --
|
||||
|
||||
--- @type CharacterState[]
|
||||
gCharacterStates = {}
|
||||
for i = 0, (MAX_PLAYERS - 1) do
|
||||
gCharacterStates[i] = {}
|
||||
local m = gMarioStates[i]
|
||||
local e = gCharacterStates[i]
|
||||
e.mario = m
|
||||
e.luigi = {}
|
||||
e.toad = {}
|
||||
e.wario = {}
|
||||
e.waluigi = {}
|
||||
e.toadette = {}
|
||||
e.peach = {}
|
||||
e.daisy = {}
|
||||
e.yoshi = {}
|
||||
e.birdo = {}
|
||||
e.spike = {}
|
||||
e.pauline = {}
|
||||
e.rosalina = {}
|
||||
e.wapeach = {}
|
||||
e.donkeyKong = {}
|
||||
e.sonic = {}
|
||||
|
||||
e.toadette.averageForwardVel = 0
|
||||
|
||||
e.birdo.spitTimer = 0
|
||||
e.birdo.framesSinceShoot = 255
|
||||
e.birdo.flameCharge = 0
|
||||
|
||||
e.rosalina.canSpin = true
|
||||
e.rosalina.orbitObjActive = false
|
||||
e.rosalina.orbitObjDist = 0
|
||||
e.rosalina.orbitObjAngle = 0
|
||||
|
||||
e.sonic.spinCharge = 0
|
||||
e.sonic.groundYVel = 0
|
||||
e.sonic.prevForwardVel = 0
|
||||
e.sonic.peakHeight = 0
|
||||
e.sonic.actionADone = false
|
||||
e.sonic.actionBDone = false
|
||||
e.sonic.bounced = false
|
||||
e.sonic.spindashState = 0
|
||||
e.sonic.instashieldTimer = 0
|
||||
e.sonic.oxygen = 900 -- 30 seconds
|
||||
e.sonic.prevVelY = 0
|
||||
e.sonic.prevHeight = 0
|
||||
e.sonic.physTimer = 0
|
||||
e.sonic.lastforwardPos = gVec3fZero()
|
||||
e.sonic.realFVel = 0
|
||||
end
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue