mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2024-11-25 13:35:12 +00:00
Merge branch 'unstable' into level-scripts
This commit is contained in:
commit
52e705c9d8
24 changed files with 2358 additions and 1599 deletions
17
Makefile
17
Makefile
|
@ -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
|
@ -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)
|
||||
|
|
|
@ -9,7 +9,9 @@ Developers:
|
|||
theclashingfritz
|
||||
|
||||
Contributors:
|
||||
Agent X
|
||||
AloXado320
|
||||
Altiami
|
||||
Amy54Desu
|
||||
anzz1
|
||||
Avery
|
||||
|
|
37
data/dynos_col_load.cpp
Normal file
37
data/dynos_col_load.cpp
Normal 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
32
data/dynos_col_write.cpp
Normal 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
322
data/dynos_gfx_write.cpp
Normal 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
Binary file not shown.
28
docs/lua/examples/water-level.lua
Normal file
28
docs/lua/examples/water-level.lua
Normal 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)
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
BIN
res/icon.ico
BIN
res/icon.ico
Binary file not shown.
Before Width: | Height: | Size: 401 KiB |
|
@ -1 +0,0 @@
|
|||
id ICON res/icon.ico
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue