Merge branch 'unstable' into level-scripts

This commit is contained in:
MysterD 2022-04-06 01:36:33 -07:00
commit 52e705c9d8
24 changed files with 2358 additions and 1599 deletions

View file

@ -58,9 +58,6 @@ DISCORD_SDK ?= 1
# Enable docker build workarounds
DOCKERBUILD ?= 0
# Should It compile with windows Icon
ICON ?= 1
# Various workarounds for weird toolchains
NO_BZERO_BCOPY ?= 0
@ -832,20 +829,6 @@ else
# endif
endif
# Icon
ifeq ($(WINDOWS_BUILD),1)
ifeq ($(ICON),1)
Command := mkdir $(BUILD_DIR)/res
Reponse := $(shell $(call Command))
Command := windres -o $(BUILD_DIR)/res/icon.o -i res/icon.rc
Reponse := $(shell $(call Command))
LDFLAGS += $(BUILD_DIR)/res/icon.o
endif
endif
# Coop specific libraries
# Lua

File diff suppressed because it is too large Load diff

View file

@ -6,12 +6,30 @@ function get_behavior_from_id(id)
-- ...
end
--- @param id BehaviorId
--- @return string
function get_behavior_name_from_id(id)
-- ...
end
--- @param behavior Pointer_BehaviorScript
--- @return BehaviorId
function get_id_from_behavior(behavior)
-- ...
end
--- @param name string
--- @return BehaviorId
function get_id_from_behavior_name(name)
-- ...
end
--- @param behavior Pointer_BehaviorScript
--- @return BehaviorId
function get_id_from_vanilla_behavior(behavior)
-- ...
end
--- @param c Camera
--- @param goal number
--- @param inc number
@ -4135,6 +4153,12 @@ function allocate_mario_action(actFlags)
-- ...
end
--- @param index integer
--- @return number
function get_environment_region(index)
-- ...
end
--- @param m MarioState
--- @param index integer
--- @return number
@ -4171,6 +4195,13 @@ function hud_show()
-- ...
end
--- @param index integer
--- @param value integer
--- @return nil
function set_environment_region(index, value)
-- ...
end
--- @param name string
--- @return Pointer_LevelScript
function smlua_level_util_get(name)

View file

@ -9,7 +9,9 @@ Developers:
theclashingfritz
Contributors:
Agent X
AloXado320
Altiami
Amy54Desu
anzz1
Avery

37
data/dynos_col_load.cpp Normal file
View file

@ -0,0 +1,37 @@
#include "dynos.cpp.h"
//
// Load collision from binary
//
static DataNode<Collision>* LoadCollisionData(FILE *aFile) {
DataNode<Collision> *_Node = New<DataNode<Collision>>();
// Name
_Node->mName.Read(aFile);
// Data
_Node->mSize = ReadBytes<u32>(aFile);
_Node->mData = New<Collision>(_Node->mSize);
for (u32 i = 0; i != _Node->mSize; ++i) {
_Node->mData[i] = ReadBytes<Collision>(aFile);
}
return _Node;
}
DataNode<Collision>* DynOS_Col_LoadFromBinary(const SysPath &aPackFolder, const char *aCollisionName) {
// Load data from binary file
DataNode<Collision>* collisionNode = NULL;
SysPath _Filename = fstring("%s/%s.col", aPackFolder.begin(), aCollisionName);
FILE *_File = fopen(_Filename.c_str(), "rb");
if (_File) {
u8 type = ReadBytes<u8>(_File);
if (type == DATA_TYPE_COLLISION) {
collisionNode = LoadCollisionData(_File);
}
fclose(_File);
}
return collisionNode;
}

32
data/dynos_col_write.cpp Normal file
View file

@ -0,0 +1,32 @@
#include "dynos.cpp.h"
//
// Collisions
//
static void WriteCollisionData(FILE* aFile, GfxData* aGfxData, DataNode<Collision> *aNode) {
if (!aNode->mData) return;
// Name
WriteBytes<u8>(aFile, DATA_TYPE_COLLISION);
aNode->mName.Write(aFile);
// Data
WriteBytes<u32>(aFile, aNode->mSize);
for (u32 i = 0; i != aNode->mSize; ++i) {
WriteBytes<Collision>(aFile, aNode->mData[i]);
}
}
bool DynOS_Col_WriteBinary(const SysPath &aOutputFilename, GfxData *aGfxData, DataNode<Collision>* _Node) {
FILE *_File = fopen(aOutputFilename.c_str(), "wb");
if (!_File) {
PrintError(" ERROR: Unable to create file \"%s\"", aOutputFilename.c_str());
return false;
}
WriteCollisionData(_File, aGfxData, _Node);
fclose(_File);
return true;
}

322
data/dynos_gfx_write.cpp Normal file
View file

@ -0,0 +1,322 @@
#include "dynos.cpp.h"
//
// Pointers
//
typedef Pair<String, u32> PointerData;
static PointerData GetDataFromPointer(const void* aPtr, GfxData* aGfxData) {
// Lights
for (auto& _Node : aGfxData->mLights) {
if (&_Node->mData->l[0] == aPtr) { // Light *, not Lights1 *
return { _Node->mName, 1 };
}
if (&_Node->mData->a == aPtr) { // Ambient *, not Lights1 *
return { _Node->mName, 2 };
}
}
// Textures
for (auto& _Node : aGfxData->mTextures) {
if (_Node == aPtr) {
return { _Node->mName, 0 };
}
}
// Display lists
for (auto& _Node : aGfxData->mDisplayLists) {
if (_Node == aPtr) {
return { _Node->mName, 0 };
}
}
// Geo layouts
for (auto& _Node : aGfxData->mGeoLayouts) {
if (_Node->mData == aPtr) {
return { _Node->mName, 0 };
}
}
// Vertices
String _VtxArrayName = "";
uintptr_t _VtxArrayStart = 0;
for (auto& _Node : aGfxData->mVertices) {
if (_Node->mData == aPtr) {
return { _Node->mName, 0 };
}
if ((uintptr_t)_Node->mData <= (uintptr_t)aPtr &&
(uintptr_t)_Node->mData >= _VtxArrayStart) {
_VtxArrayName = _Node->mName;
_VtxArrayStart = (uintptr_t)_Node->mData;
}
}
return { _VtxArrayName, (u32)((const Vtx*)aPtr - (const Vtx*)_VtxArrayStart) };
}
static void WritePointer(FILE* aFile, const void* aPtr, GfxData* aGfxData) {
// NULL
if (!aPtr) {
WriteBytes<u32>(aFile, 0);
return;
}
// Geo function
s32 _GeoFunctionIndex = DynOS_Geo_GetFunctionIndex(aPtr);
if (_GeoFunctionIndex != -1) {
WriteBytes<u32>(aFile, FUNCTION_CODE);
WriteBytes<s32>(aFile, _GeoFunctionIndex);
return;
}
// Pointer
PointerData _PtrData = GetDataFromPointer(aPtr, aGfxData);
WriteBytes<u32>(aFile, POINTER_CODE);
_PtrData.first.Write(aFile);
WriteBytes<u32>(aFile, _PtrData.second);
}
//
// Lights
//
static void WriteLightData(FILE* aFile, GfxData* aGfxData, DataNode<Lights1> *aNode) {
if (!aNode->mData) return;
// Header
WriteBytes<u8>(aFile, DATA_TYPE_LIGHT);
aNode->mName.Write(aFile);
// Data
WriteBytes<Lights1>(aFile, *aNode->mData);
}
//
// Textures
//
static void WriteTextureData(FILE* aFile, GfxData* aGfxData, DataNode<TexData> *aNode) {
if (!aNode->mData) return;
// Header
WriteBytes<u8>(aFile, DATA_TYPE_TEXTURE);
aNode->mName.Write(aFile);
// Data
aNode->mData->mPngData.Write(aFile);
}
//
// Vertices
//
static void WriteVertexData(FILE* aFile, GfxData* aGfxData, DataNode<Vtx> *aNode) {
if (!aNode->mData) return;
// Header
WriteBytes<u8>(aFile, DATA_TYPE_VERTEX);
aNode->mName.Write(aFile);
// Data
WriteBytes<u32>(aFile, aNode->mSize);
for (u32 i = 0; i != aNode->mSize; ++i) {
WriteBytes<s16>(aFile, aNode->mData[i].n.ob[0]);
WriteBytes<s16>(aFile, aNode->mData[i].n.ob[1]);
WriteBytes<s16>(aFile, aNode->mData[i].n.ob[2]);
WriteBytes<s16>(aFile, aNode->mData[i].n.flag);
WriteBytes<s16>(aFile, aNode->mData[i].n.tc[0]);
WriteBytes<s16>(aFile, aNode->mData[i].n.tc[1]);
WriteBytes<s8> (aFile, aNode->mData[i].n.n[0]);
WriteBytes<s8> (aFile, aNode->mData[i].n.n[1]);
WriteBytes<s8> (aFile, aNode->mData[i].n.n[2]);
WriteBytes<u8> (aFile, aNode->mData[i].n.a);
}
}
//
// Display lists
//
static void WriteDisplayListData(FILE *aFile, GfxData *aGfxData, DataNode<Gfx> *aNode) {
if (!aNode->mData) return;
// Header
WriteBytes<u8>(aFile, DATA_TYPE_DISPLAY_LIST);
aNode->mName.Write(aFile);
// Data
WriteBytes<u32>(aFile, aNode->mSize);
for (u32 i = 0; i != aNode->mSize; ++i) {
Gfx *_Head = &aNode->mData[i];
if (aGfxData->mPointerList.Find((void *) _Head) != -1) {
WriteBytes<u32>(aFile, _Head->words.w0);
WritePointer(aFile, (const void *) _Head->words.w1, aGfxData);
} else {
WriteBytes<u32>(aFile, _Head->words.w0);
WriteBytes<u32>(aFile, _Head->words.w1);
}
}
}
//
// Geo layouts
//
static void WriteGeoLayoutData(FILE *aFile, GfxData *aGfxData, DataNode<GeoLayout> *aNode) {
if (!aNode->mData) return;
// Header
WriteBytes<u8>(aFile, DATA_TYPE_GEO_LAYOUT);
aNode->mName.Write(aFile);
// Data
WriteBytes<u32>(aFile, aNode->mSize);
for (u32 i = 0; i != aNode->mSize; ++i) {
GeoLayout *_Head = &aNode->mData[i];
if (aGfxData->mPointerList.Find((void *) _Head) != -1) {
WritePointer(aFile, (const void *) (*_Head), aGfxData);
} else {
WriteBytes<u32>(aFile, *((u32 *) _Head));
}
}
}
//
// Animation data
//
static void WriteAnimationData(FILE* aFile, GfxData* aGfxData) {
for (auto& _Node : aGfxData->mAnimations) {
// Value buffer
s32 _ValueBufferIdx = aGfxData->mAnimValues.FindIf([&_Node](const AnimBuffer<s16> *aAnimBuffer) { return aAnimBuffer->first == _Node->mData->mValues.first; });
if (_ValueBufferIdx == -1) {
continue;
}
// Index buffer
s32 _IndexBufferIdx = aGfxData->mAnimIndices.FindIf([&_Node](const AnimBuffer<u16> *aAnimBuffer) { return aAnimBuffer->first == _Node->mData->mIndex.first; });
if (_IndexBufferIdx == -1) {
continue;
}
// Unk0A buffer
s32 _Unk0ABufferIdx = aGfxData->mAnimIndices.FindIf([&_Node](const AnimBuffer<u16> *aAnimBuffer) { return aAnimBuffer->first == _Node->mData->mUnk0A.first; });
if (_Unk0ABufferIdx == -1) {
continue;
}
// Header
WriteBytes<u8>(aFile, DATA_TYPE_ANIMATION);
_Node->mName.Write(aFile);
// Data
WriteBytes<s16>(aFile, _Node->mData->mFlags);
WriteBytes<s16>(aFile, _Node->mData->mUnk02);
WriteBytes<s16>(aFile, _Node->mData->mUnk04);
WriteBytes<s16>(aFile, _Node->mData->mUnk06);
WriteBytes<s16>(aFile, _Node->mData->mUnk08);
WriteBytes<s16>(aFile, (aGfxData->mAnimIndices[_Unk0ABufferIdx]->second.Count() / 6) - 1);
WriteBytes<u32>(aFile, _Node->mData->mLength);
aGfxData->mAnimValues[_ValueBufferIdx]->second.Write(aFile);
aGfxData->mAnimIndices[_IndexBufferIdx]->second.Write(aFile);
}
}
//
// Animation table
//
static void WriteAnimationTable(FILE* aFile, GfxData* aGfxData) {
for (auto& _AnimName : aGfxData->mAnimationTable) {
// Header
WriteBytes<u8>(aFile, DATA_TYPE_ANIMATION_TABLE);
// Data
_AnimName.first.Write(aFile);
}
}
//
// Write
//
bool DynOS_Gfx_WriteBinary(const SysPath &aOutputFilename, GfxData *aGfxData) {
FILE *_File = fopen(aOutputFilename.c_str(), "wb");
if (!_File) {
PrintError(" ERROR: Unable to create file \"%s\"", aOutputFilename.c_str());
return false;
}
for (u64 i = 0; i != aGfxData->mLoadIndex; ++i) {
for (auto &_Node : aGfxData->mLights) {
if (_Node->mLoadIndex == i) {
WriteLightData(_File, aGfxData, _Node);
}
}
for (auto &_Node : aGfxData->mTextures) {
if (_Node->mLoadIndex == i) {
WriteTextureData(_File, aGfxData, _Node);
}
}
for (auto &_Node : aGfxData->mVertices) {
if (_Node->mLoadIndex == i) {
WriteVertexData(_File, aGfxData, _Node);
}
}
for (auto &_Node : aGfxData->mDisplayLists) {
if (_Node->mLoadIndex == i) {
WriteDisplayListData(_File, aGfxData, _Node);
}
}
for (auto &_Node : aGfxData->mGeoLayouts) {
if (_Node->mLoadIndex == i) {
WriteGeoLayoutData(_File, aGfxData, _Node);
}
}
}
WriteAnimationData(_File, aGfxData);
WriteAnimationTable(_File, aGfxData);
fclose(_File);
return true;
}
//
// Free
//
void DynOS_Gfx_Free(GfxData* aGfxData) {
if (aGfxData) {
for (auto& _Node : aGfxData->mLights) {
Delete(_Node->mData);
Delete(_Node);
}
for (auto& _Node : aGfxData->mTextures) {
Delete(_Node->mData);
Delete(_Node);
}
for (auto& _Node : aGfxData->mVertices) {
Delete(_Node->mData);
Delete(_Node);
}
for (auto& _Node : aGfxData->mDisplayLists) {
Delete(_Node->mData);
Delete(_Node);
}
for (auto& _Node : aGfxData->mGeoLayouts) {
Delete(_Node->mData);
Delete(_Node);
}
for (auto& _Node : aGfxData->mAnimations) {
Delete(_Node->mData);
Delete(_Node);
}
for (auto& _Node : aGfxData->mCollisions) {
Delete(_Node->mData);
Delete(_Node);
}
Delete(aGfxData);
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,28 @@
-- name: Water Height Changer
-- description: Use /waterset and /waterget to manipulate water height.
function on_get_command(msg)
if not network_is_server() then
djui_chat_message_create("You need to be the host!")
return true
end
djui_chat_message_create(tostring(get_environment_region(1)))
djui_chat_message_create(tostring(get_environment_region(2)))
return false
end
function on_set_command(msg)
if not network_is_server() then
djui_chat_message_create("You need to be the host!")
return true
end
local num = tonumber(msg)
set_environment_region(1, num)
set_environment_region(2, num)
return false
end
hook_chat_command("waterset", "to set the first two water levels", on_set_command)
hook_chat_command("waterget", "to get the first two water levels", on_get_command)

View file

@ -11,7 +11,10 @@
- behavior_table.h
- [get_behavior_from_id](#get_behavior_from_id)
- [get_behavior_name_from_id](#get_behavior_name_from_id)
- [get_id_from_behavior](#get_id_from_behavior)
- [get_id_from_behavior_name](#get_id_from_behavior_name)
- [get_id_from_vanilla_behavior](#get_id_from_vanilla_behavior)
<br />
@ -727,12 +730,14 @@
- smlua_misc_utils.h
- [allocate_mario_action](#allocate_mario_action)
- [get_environment_region](#get_environment_region)
- [get_hand_foot_pos_x](#get_hand_foot_pos_x)
- [get_hand_foot_pos_y](#get_hand_foot_pos_y)
- [get_hand_foot_pos_z](#get_hand_foot_pos_z)
- [get_network_area_timer](#get_network_area_timer)
- [hud_hide](#hud_hide)
- [hud_show](#hud_show)
- [set_environment_region](#set_environment_region)
- [smlua_level_util_get](#smlua_level_util_get)
- [warp_exit_level](#warp_exit_level)
- [warp_restart_level](#warp_restart_level)
@ -913,6 +918,26 @@ The `reliable` field will ensure that the packet arrives, but should be used spa
<br />
## [get_behavior_name_from_id](#get_behavior_name_from_id)
### Lua Example
`local stringValue = get_behavior_name_from_id(id)`
### Parameters
| Field | Type |
| ----- | ---- |
| id | [enum BehaviorId](constants.md#enum-BehaviorId) |
### Returns
- `string`
### C Prototype
`const char* get_behavior_name_from_id(enum BehaviorId id);`
[:arrow_up_small:](#)
<br />
## [get_id_from_behavior](#get_id_from_behavior)
### Lua Example
@ -933,6 +958,46 @@ The `reliable` field will ensure that the packet arrives, but should be used spa
<br />
## [get_id_from_behavior_name](#get_id_from_behavior_name)
### Lua Example
`local enumValue = get_id_from_behavior_name(name)`
### Parameters
| Field | Type |
| ----- | ---- |
| name | `string` |
### Returns
[enum BehaviorId](constants.md#enum-BehaviorId)
### C Prototype
`enum BehaviorId get_id_from_behavior_name(const char* name);`
[:arrow_up_small:](#)
<br />
## [get_id_from_vanilla_behavior](#get_id_from_vanilla_behavior)
### Lua Example
`local enumValue = get_id_from_vanilla_behavior(behavior)`
### Parameters
| Field | Type |
| ----- | ---- |
| behavior | `Pointer` <`BehaviorScript`> |
### Returns
[enum BehaviorId](constants.md#enum-BehaviorId)
### C Prototype
`enum BehaviorId get_id_from_vanilla_behavior(const BehaviorScript* behavior);`
[:arrow_up_small:](#)
<br />
---
# functions from camera.h
@ -13659,6 +13724,26 @@ The `reliable` field will ensure that the packet arrives, but should be used spa
<br />
## [get_environment_region](#get_environment_region)
### Lua Example
`local numberValue = get_environment_region(index)`
### Parameters
| Field | Type |
| ----- | ---- |
| index | `integer` |
### Returns
- `number`
### C Prototype
`f32 get_environment_region(u8 index);`
[:arrow_up_small:](#)
<br />
## [get_hand_foot_pos_x](#get_hand_foot_pos_x)
### Lua Example
@ -13776,6 +13861,27 @@ The `reliable` field will ensure that the packet arrives, but should be used spa
<br />
## [set_environment_region](#set_environment_region)
### Lua Example
`set_environment_region(index, value)`
### Parameters
| Field | Type |
| ----- | ---- |
| index | `integer` |
| value | `integer` |
### Returns
- None
### C Prototype
`void set_environment_region(u8 index, s32 value);`
[:arrow_up_small:](#)
<br />
## [smlua_level_util_get](#smlua_level_util_get)
### Lua Example

View file

@ -54,8 +54,9 @@ All of this is a holdover from when there were only two players. It was a reason
- [Custom Surface Collisions](examples/big-paddle)
- [Custom Box Model](examples/custom-box-model)
- [Custom Player Model](examples/koopa-player-model)
- [Moonjump](examples/Moonjump.lua)
- [Instant Clip](examples/Instant_Clip.lua)
- [Moonjump](examples/moonjump.lua)
- [Instant Clip](examples/instant-clip.lua)
- [Water Height Changer](examples/water-level.lua)
## Example Lua mods (large)
- [Extended Moveset](../../mods/extended-moveset.lua)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 401 KiB

View file

@ -1 +0,0 @@
id ICON res/icon.ico

View file

@ -946,9 +946,11 @@ u32 interact_star_or_key(struct MarioState *m, UNUSED u32 interactType, struct O
}
save_file_do_save(gCurrSaveFileNum - 1, TRUE);
if (!noExit || gServerSettings.stayInLevelAfterStar != 2) {
return set_mario_action(m, starGrabAction, noExit + 2 * grandStar);
if (noExit && gServerSettings.stayInLevelAfterStar == 2) {
return TRUE;
}
return set_mario_action(m, starGrabAction, noExit + 2 * grandStar);
}
return FALSE;

View file

@ -1530,6 +1530,7 @@ void update_mario_inputs(struct MarioState *m) {
/* End of developer stuff */
if ((m->action == ACT_END_PEACH_CUTSCENE || m->action == ACT_CREDITS_CUTSCENE) && m->controller->buttonPressed & START_BUTTON) {
gCurrCreditsEntry = NULL;
gCurrActStarNum = 0;
gCurrActNum = 0;
gChangeLevel = 16;

View file

@ -2807,6 +2807,7 @@ static s32 act_credits_cutscene(struct MarioState *m) {
m->actionState += 2;
}
if (gCurrCreditsEntry != NULL) {
if (m->playerIndex == 0) {
s32 width = m->actionState * 640 / 100;
s32 height = m->actionState * 480 / 100;
@ -2819,7 +2820,9 @@ static s32 act_credits_cutscene(struct MarioState *m) {
override_viewport_and_clip(&sEndCutsceneVp, 0, 0, 0, 0);
}
}
}
if (gCurrCreditsEntry != NULL) {
if (m->actionTimer == TIMER_CREDITS_PROGRESS && m->playerIndex == 0) {
reset_cutscene_msg_fade();
}
@ -2833,7 +2836,7 @@ static s32 act_credits_cutscene(struct MarioState *m) {
}
m->marioObj->header.gfx.angle[1] += (gCurrCreditsEntry->unk02 & 0xC0) << 8;
}
return FALSE;
}

File diff suppressed because it is too large Load diff

View file

@ -41,6 +41,17 @@ int smlua_func_get_behavior_from_id(lua_State* L) {
return 1;
}
int smlua_func_get_behavior_name_from_id(lua_State* L) {
if(!smlua_functions_valid_param_count(L, 1)) { return 0; }
int id = smlua_to_integer(L, 1);
if (!gSmLuaConvertSuccess) { return 0; }
lua_pushstring(L, get_behavior_name_from_id(id));
return 1;
}
int smlua_func_get_id_from_behavior(lua_State* L) {
if(!smlua_functions_valid_param_count(L, 1)) { return 0; }
@ -52,6 +63,28 @@ int smlua_func_get_id_from_behavior(lua_State* L) {
return 1;
}
int smlua_func_get_id_from_behavior_name(lua_State* L) {
if(!smlua_functions_valid_param_count(L, 1)) { return 0; }
const char* name = smlua_to_string(L, 1);
if (!gSmLuaConvertSuccess) { return 0; }
lua_pushinteger(L, get_id_from_behavior_name(name));
return 1;
}
int smlua_func_get_id_from_vanilla_behavior(lua_State* L) {
if(!smlua_functions_valid_param_count(L, 1)) { return 0; }
const BehaviorScript* behavior = (const BehaviorScript*)smlua_to_cpointer(L, 1, LVT_BEHAVIORSCRIPT_P);
if (!gSmLuaConvertSuccess) { return 0; }
lua_pushinteger(L, get_id_from_vanilla_behavior(behavior));
return 1;
}
//////////////
// camera.h //
//////////////
@ -9200,6 +9233,17 @@ int smlua_func_allocate_mario_action(lua_State* L) {
return 1;
}
int smlua_func_get_environment_region(lua_State* L) {
if(!smlua_functions_valid_param_count(L, 1)) { return 0; }
u8 index = smlua_to_integer(L, 1);
if (!gSmLuaConvertSuccess) { return 0; }
lua_pushnumber(L, get_environment_region(index));
return 1;
}
int smlua_func_get_hand_foot_pos_x(lua_State* L) {
if(!smlua_functions_valid_param_count(L, 2)) { return 0; }
@ -9266,6 +9310,19 @@ int smlua_func_hud_show(UNUSED lua_State* L) {
return 1;
}
int smlua_func_set_environment_region(lua_State* L) {
if(!smlua_functions_valid_param_count(L, 2)) { return 0; }
u8 index = smlua_to_integer(L, 1);
if (!gSmLuaConvertSuccess) { return 0; }
s32 value = smlua_to_integer(L, 2);
if (!gSmLuaConvertSuccess) { return 0; }
set_environment_region(index, value);
return 1;
}
int smlua_func_smlua_level_util_get(lua_State* L) {
if(!smlua_functions_valid_param_count(L, 1)) { return 0; }
@ -10031,7 +10088,10 @@ void smlua_bind_functions_autogen(void) {
// behavior_table.h
smlua_bind_function(L, "get_behavior_from_id", smlua_func_get_behavior_from_id);
smlua_bind_function(L, "get_behavior_name_from_id", smlua_func_get_behavior_name_from_id);
smlua_bind_function(L, "get_id_from_behavior", smlua_func_get_id_from_behavior);
smlua_bind_function(L, "get_id_from_behavior_name", smlua_func_get_id_from_behavior_name);
smlua_bind_function(L, "get_id_from_vanilla_behavior", smlua_func_get_id_from_vanilla_behavior);
// camera.h
smlua_bind_function(L, "approach_camera_height", smlua_func_approach_camera_height);
@ -10714,12 +10774,14 @@ void smlua_bind_functions_autogen(void) {
// smlua_misc_utils.h
smlua_bind_function(L, "allocate_mario_action", smlua_func_allocate_mario_action);
smlua_bind_function(L, "get_environment_region", smlua_func_get_environment_region);
smlua_bind_function(L, "get_hand_foot_pos_x", smlua_func_get_hand_foot_pos_x);
smlua_bind_function(L, "get_hand_foot_pos_y", smlua_func_get_hand_foot_pos_y);
smlua_bind_function(L, "get_hand_foot_pos_z", smlua_func_get_hand_foot_pos_z);
smlua_bind_function(L, "get_network_area_timer", smlua_func_get_network_area_timer);
smlua_bind_function(L, "hud_hide", smlua_func_hud_hide);
smlua_bind_function(L, "hud_show", smlua_func_hud_show);
smlua_bind_function(L, "set_environment_region", smlua_func_set_environment_region);
smlua_bind_function(L, "smlua_level_util_get", smlua_func_smlua_level_util_get);
smlua_bind_function(L, "warp_exit_level", smlua_func_warp_exit_level);
smlua_bind_function(L, "warp_restart_level", smlua_func_warp_restart_level);

View file

@ -7,6 +7,8 @@
#include "smlua_misc_utils.h"
#include "pc/debuglog.h"
#include "game/object_list_processor.h"
u32 get_network_area_timer(void) {
return gNetworkAreaTimer;
}
@ -58,3 +60,16 @@ f32 get_hand_foot_pos_z(struct MarioState* m, u8 index) {
LevelScript* smlua_level_util_get(const char* name) {
return dynos_level_get(name);
}
f32 get_environment_region(u8 index) {
if (gEnvironmentRegions != NULL && index <= gEnvironmentRegions[0]) {
return gEnvironmentRegions[6 * (int)index];
}
return -11000;
}
void set_environment_region(u8 index, s32 value) {
if (gEnvironmentRegions != NULL && index <= gEnvironmentRegions[0]) {
gEnvironmentRegions[6 * (int)index] = value;
}
}

View file

@ -18,5 +18,7 @@ f32 get_hand_foot_pos_y(struct MarioState* m, u8 index);
f32 get_hand_foot_pos_z(struct MarioState* m, u8 index);
LevelScript* smlua_level_util_get(const char* name);
f32 get_environment_region(u8 index);
void set_environment_region(u8 index, s32 value);
#endif

View file

@ -298,6 +298,26 @@ static bool mod_load_files(struct Mod* mod, char* modName, char* fullPath) {
return true;
}
static void mod_set_loading_order(struct Mod* mod) {
if (mod->fileCount <= 1) {
return;
}
// TODO: add a way to specify the loading order of a mod's files?
// By default, this is the alphabetical order on relative path
for (s32 i = 1; i < mod->fileCount; ++i) {
struct ModFile file = mod->files[i];
for (s32 j = 0; j < i; ++j) {
if (strcmp(file.relativePath, mod->files[j].relativePath) < 0) {
memmove(mod->files + j + 1, mod->files + j, sizeof(struct ModFile) * (i - j));
memcpy(mod->files + j, &file, sizeof(struct ModFile));
break;
}
}
}
}
static void mod_extract_fields(struct Mod* mod) {
// get full path
char path[SYS_MAX_PATH] = { 0 };
@ -439,6 +459,9 @@ bool mod_load(struct Mods* mods, char* basePath, char* modName) {
return false;
}
// set loading order
mod_set_loading_order(mod);
// extract fields
mod_extract_fields(mod);

View file

@ -170,6 +170,11 @@ void network_receive_mod_list(struct Packet* p) {
packet_read(p, &relativePathLength, sizeof(u16));
packet_read(p, file->relativePath, relativePathLength * sizeof(u8));
packet_read(p, &file->size, sizeof(u64));
if (mod->isDirectory && !strstr(file->relativePath, "actors")) {
char tmp[SYS_MAX_PATH];
snprintf(tmp, SYS_MAX_PATH, "%s-%s", mod->relativePath, file->relativePath);
memcpy(file->relativePath, tmp, strlen(tmp) + 1);
}
normalize_path(file->relativePath);
LOG_INFO(" '%s': %llu", file->relativePath, (u64)file->size);
}