mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2026-05-08 01:41:41 +00:00
Merge branch 'dev' into screen-shader-effects
This commit is contained in:
commit
a194f4eaa1
876 changed files with 791 additions and 68644 deletions
|
|
@ -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[^_]" ],
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -7762,10 +7783,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 +7814,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 +9113,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)
|
||||
|
|
|
|||
|
|
@ -3,7 +3,9 @@
|
|||
extern "C" {
|
||||
#include "include/surface_terrains.h"
|
||||
#include "include/level_misc_macros.h"
|
||||
#include "include/special_presets.h"
|
||||
#include "include/special_preset_names.h"
|
||||
#include "src/engine/surface_load.h"
|
||||
}
|
||||
|
||||
// Free data pointers, but keep nodes and tokens intact
|
||||
|
|
@ -34,12 +36,32 @@ struct CollisionValidationData {
|
|||
u32 vtxCount;
|
||||
u32 triAlloc;
|
||||
u32 triCount;
|
||||
s16 surfaceType;
|
||||
u32 specialAlloc;
|
||||
u32 specialCount;
|
||||
u32 waterBoxAlloc;
|
||||
u32 waterBoxCount;
|
||||
};
|
||||
|
||||
static u8 GetSpecialObjectType(u8 preset) {
|
||||
for (s32 i = 0; i < ARRAY_COUNT(SpecialObjectPresets); ++i) {
|
||||
if (SpecialObjectPresets[i].preset_id == preset) {
|
||||
return SpecialObjectPresets[i].type;
|
||||
}
|
||||
}
|
||||
return SPTYPE_UNKNOWN;
|
||||
}
|
||||
|
||||
static const char *GetCorrectSpecialObjectCommand(u8 presetType) {
|
||||
switch (presetType) {
|
||||
case SPTYPE_NO_YROT_OR_PARAMS: return "SPECIAL_OBJECT";
|
||||
case SPTYPE_YROT_NO_PARAMS: return "SPECIAL_OBJECT_WITH_YAW";
|
||||
case SPTYPE_PARAMS_AND_YROT: return "SPECIAL_OBJECT_WITH_YAW_AND_PARAM";
|
||||
case SPTYPE_DEF_PARAM_AND_YROT: return "SPECIAL_OBJECT_WITH_YAW";
|
||||
default: return "";
|
||||
}
|
||||
}
|
||||
|
||||
static void ValidateColSectionChange(GfxData* aGfxData, struct CollisionValidationData& aColValData, u8 section) {
|
||||
if (aColValData.section == COL_SECTION_END) {
|
||||
PrintDataError("Found new col section after COL_END");
|
||||
|
|
@ -67,51 +89,70 @@ static void ValidateColInit(GfxData* aGfxData, struct CollisionValidationData& a
|
|||
ValidateColSectionChange(aGfxData, aColValData, COL_SECTION_VTX);
|
||||
}
|
||||
|
||||
static void ValidateColVertexInit(GfxData* aGfxData, struct CollisionValidationData& aColValData, s16 arg0) {
|
||||
static void ValidateColVertexInit(GfxData* aGfxData, struct CollisionValidationData& aColValData, s16 vertexCount) {
|
||||
if (strcmp(aColValData.lastSymbol, "COL_INIT") != 0) {
|
||||
PrintDataError("COL_VERTEX_INIT found outside of vertex section");
|
||||
}
|
||||
if (arg0 < 0) {
|
||||
PrintDataError("COL_VERTEX_INIT with a negative count: %d", arg0);
|
||||
if (vertexCount < 0) {
|
||||
PrintDataError("COL_VERTEX_INIT with a negative count: %d", vertexCount);
|
||||
}
|
||||
aColValData.vtxAlloc = arg0;
|
||||
aColValData.vtxAlloc = vertexCount;
|
||||
aColValData.vtxCount = 0;
|
||||
}
|
||||
|
||||
static void ValidateColVertex(GfxData* aGfxData, struct CollisionValidationData& aColValData, s16 arg0, s16 arg1, s16 arg2) {
|
||||
static void ValidateColVertex(GfxData* aGfxData, struct CollisionValidationData& aColValData, s16 x, s16 y, s16 z) {
|
||||
if (aColValData.section != COL_SECTION_VTX) {
|
||||
PrintDataError("COL_VERTEX found outside of vertex section");
|
||||
}
|
||||
aColValData.vtxCount++;
|
||||
}
|
||||
|
||||
static void ValidateColTriInit(GfxData* aGfxData, struct CollisionValidationData& aColValData, s16 arg0, s16 arg1) {
|
||||
if (arg1 < 0) {
|
||||
PrintDataError("COL_TRI_INIT with a negative count: %d", arg1);
|
||||
static void ValidateColTriInit(GfxData* aGfxData, struct CollisionValidationData& aColValData, s16 surfaceType, s16 triangleCount) {
|
||||
if (triangleCount < 0) {
|
||||
PrintDataError("COL_TRI_INIT with a negative count: %d", triangleCount);
|
||||
}
|
||||
ValidateColSectionChange(aGfxData, aColValData, COL_SECTION_TRI);
|
||||
aColValData.triAlloc = arg1;
|
||||
aColValData.triAlloc = triangleCount;
|
||||
aColValData.triCount = 0;
|
||||
aColValData.surfaceType = surfaceType;
|
||||
}
|
||||
|
||||
static void ValidateColTri(GfxData* aGfxData, struct CollisionValidationData& aColValData, s16 arg0, s16 arg1, s16 arg2) {
|
||||
static void ValidateColTri(GfxData* aGfxData, struct CollisionValidationData& aColValData, s16 vertex0, s16 vertex1, s16 vertex2) {
|
||||
if (aColValData.section != COL_SECTION_TRI) {
|
||||
PrintDataError("COL_TRI found outside of triangle section");
|
||||
}
|
||||
if (arg0 < 0 || arg0 > aColValData.vtxCount) {
|
||||
PrintDataError("COL_TRI used vertex outside of known range for first param: %d", arg0);
|
||||
if (surface_has_force(aColValData.surfaceType)) {
|
||||
PrintDataError("COL_TRI cannot be used by surface types with a force parameter: %d (use COL_TRI_SPECIAL instead)", aColValData.surfaceType);
|
||||
}
|
||||
if (arg1 < 0 || arg1 > aColValData.vtxCount) {
|
||||
PrintDataError("COL_TRI used vertex outside of known range for second param: %d", arg1);
|
||||
if (vertex0 < 0 || vertex0 > aColValData.vtxCount) {
|
||||
PrintDataError("COL_TRI used vertex outside of known range for first param: %d", vertex0);
|
||||
}
|
||||
if (arg2 < 0 || arg2 > aColValData.vtxCount) {
|
||||
PrintDataError("COL_TRI used vertex outside of known range for third param: %d", arg2);
|
||||
if (vertex1 < 0 || vertex1 > aColValData.vtxCount) {
|
||||
PrintDataError("COL_TRI used vertex outside of known range for second param: %d", vertex1);
|
||||
}
|
||||
if (vertex2 < 0 || vertex2 > aColValData.vtxCount) {
|
||||
PrintDataError("COL_TRI used vertex outside of known range for third param: %d", vertex2);
|
||||
}
|
||||
aColValData.triCount++;
|
||||
}
|
||||
|
||||
static void ValidateColTriSpecial(GfxData* aGfxData, struct CollisionValidationData& aColValData, s16 arg0, s16 arg1, s16 arg2, s16 arg3) {
|
||||
ValidateColTri(aGfxData, aColValData, arg0, arg1, arg2);
|
||||
static void ValidateColTriSpecial(GfxData* aGfxData, struct CollisionValidationData& aColValData, s16 vertex0, s16 vertex1, s16 vertex2, s16 force) {
|
||||
if (aColValData.section != COL_SECTION_TRI) {
|
||||
PrintDataError("COL_TRI_SPECIAL found outside of triangle section");
|
||||
}
|
||||
if (!surface_has_force(aColValData.surfaceType)) {
|
||||
PrintDataError("COL_TRI_SPECIAL cannot be used by surface types with no force parameter: %d (use COL_TRI instead)", aColValData.surfaceType);
|
||||
}
|
||||
if (vertex0 < 0 || vertex0 > aColValData.vtxCount) {
|
||||
PrintDataError("COL_TRI_SPECIAL used vertex outside of known range for first param: %d", vertex0);
|
||||
}
|
||||
if (vertex1 < 0 || vertex1 > aColValData.vtxCount) {
|
||||
PrintDataError("COL_TRI_SPECIAL used vertex outside of known range for second param: %d", vertex1);
|
||||
}
|
||||
if (vertex2 < 0 || vertex2 > aColValData.vtxCount) {
|
||||
PrintDataError("COL_TRI_SPECIAL used vertex outside of known range for third param: %d", vertex2);
|
||||
}
|
||||
aColValData.triCount++;
|
||||
}
|
||||
|
||||
static void ValidateColStop(GfxData* aGfxData, struct CollisionValidationData& aColValData) {
|
||||
|
|
@ -122,49 +163,70 @@ static void ValidateColEnd(GfxData* aGfxData, struct CollisionValidationData& aC
|
|||
ValidateColSectionChange(aGfxData, aColValData, COL_SECTION_END);
|
||||
}
|
||||
|
||||
static void ValidateColSpecialInit(GfxData* aGfxData, struct CollisionValidationData& aColValData, s16 arg0) {
|
||||
if (arg0 < 0) {
|
||||
PrintDataError("COL_SPECIAL_INIT with a negative count: %d", arg0);
|
||||
static void ValidateColSpecialInit(GfxData* aGfxData, struct CollisionValidationData& aColValData, s16 specialCount) {
|
||||
if (specialCount < 0) {
|
||||
PrintDataError("COL_SPECIAL_INIT with a negative count: %d", specialCount);
|
||||
}
|
||||
ValidateColSectionChange(aGfxData, aColValData, COL_SECTION_SPECIAL);
|
||||
aColValData.specialAlloc = arg0;
|
||||
aColValData.specialAlloc = specialCount;
|
||||
aColValData.specialCount = 0;
|
||||
}
|
||||
|
||||
static void ValidateColWaterBoxInit(GfxData* aGfxData, struct CollisionValidationData& aColValData, s16 arg0) {
|
||||
if (arg0 < 0) {
|
||||
PrintDataError("COL_WATER_BOX_INIT with a negative count: %d", arg0);
|
||||
static void ValidateColWaterBoxInit(GfxData* aGfxData, struct CollisionValidationData& aColValData, s16 waterBoxCount) {
|
||||
if (waterBoxCount < 0) {
|
||||
PrintDataError("COL_WATER_BOX_INIT with a negative count: %d", waterBoxCount);
|
||||
}
|
||||
ValidateColSectionChange(aGfxData, aColValData, COL_SECTION_WATER_BOX);
|
||||
aColValData.waterBoxAlloc = arg0;
|
||||
aColValData.waterBoxAlloc = waterBoxCount;
|
||||
aColValData.waterBoxCount = 0;
|
||||
}
|
||||
|
||||
static void ValidateColWaterBox(GfxData* aGfxData, struct CollisionValidationData& aColValData, s16 arg0, s16 arg1, s16 arg2, s16 arg3, s16 arg4, s16 arg5) {
|
||||
static void ValidateColWaterBox(GfxData* aGfxData, struct CollisionValidationData& aColValData, s16 id, s16 x1, s16 z1, s16 x2, s16 z2, s16 y) {
|
||||
if (aColValData.section != COL_SECTION_WATER_BOX) {
|
||||
PrintDataError("COL_WATER_BOX found outside of water box section");
|
||||
}
|
||||
aColValData.waterBoxCount++;
|
||||
}
|
||||
|
||||
static void ValidateColSpecialObject(GfxData* aGfxData, struct CollisionValidationData& aColValData, s16 arg0, s16 arg1, s16 arg2, s16 arg3) {
|
||||
static void ValidateColSpecialObject(GfxData* aGfxData, struct CollisionValidationData& aColValData, s16 preset, s16 posX, s16 posY, s16 posZ) {
|
||||
if (aColValData.section != COL_SECTION_SPECIAL) {
|
||||
PrintDataError("SPECIAL_OBJECT found outside of special section");
|
||||
}
|
||||
aColValData.specialCount++;
|
||||
}
|
||||
|
||||
static void ValidateColSpecialObjectWithYaw(GfxData* aGfxData, struct CollisionValidationData& aColValData, s16 arg0, s16 arg1, s16 arg2, s16 arg3, s16 arg4) {
|
||||
if (aColValData.section != COL_SECTION_SPECIAL) {
|
||||
PrintDataError("SPECIAL_OBJECT_WITH_YAW found outside of special section");
|
||||
u8 presetType = GetSpecialObjectType(preset);
|
||||
if (presetType == SPTYPE_UNKNOWN) {
|
||||
PrintDataError("SPECIAL_OBJECT has invalid preset: %d", preset);
|
||||
}
|
||||
if (presetType != SPTYPE_NO_YROT_OR_PARAMS) {
|
||||
PrintDataError("SPECIAL_OBJECT cannot be used with preset: %d (use %s instead)", preset, GetCorrectSpecialObjectCommand(presetType));
|
||||
}
|
||||
aColValData.specialCount++;
|
||||
}
|
||||
|
||||
static void ValidateColSpecialObjectWithYawAndParam(GfxData* aGfxData, struct CollisionValidationData& aColValData, s16 arg0, s16 arg1, s16 arg2, s16 arg3, s16 arg4, s16 arg5) {
|
||||
static void ValidateColSpecialObjectWithYaw(GfxData* aGfxData, struct CollisionValidationData& aColValData, s16 preset, s16 posX, s16 posY, s16 posZ, s16 yaw) {
|
||||
if (aColValData.section != COL_SECTION_SPECIAL) {
|
||||
PrintDataError("SPECIAL_OBJECT_WITH_YAW found outside of special section");
|
||||
}
|
||||
u8 presetType = GetSpecialObjectType(preset);
|
||||
if (presetType == SPTYPE_UNKNOWN) {
|
||||
PrintDataError("SPECIAL_OBJECT_WITH_YAW has invalid preset: %d", preset);
|
||||
}
|
||||
if (presetType != SPTYPE_YROT_NO_PARAMS && presetType != SPTYPE_DEF_PARAM_AND_YROT) {
|
||||
PrintDataError("SPECIAL_OBJECT_WITH_YAW cannot be used with preset: %d (use %s instead)", preset, GetCorrectSpecialObjectCommand(presetType));
|
||||
}
|
||||
aColValData.specialCount++;
|
||||
}
|
||||
|
||||
static void ValidateColSpecialObjectWithYawAndParam(GfxData* aGfxData, struct CollisionValidationData& aColValData, s16 preset, s16 posX, s16 posY, s16 posZ, s16 yaw, s16 param) {
|
||||
if (aColValData.section != COL_SECTION_SPECIAL) {
|
||||
PrintDataError("SPECIAL_OBJECT_WITH_YAW_AND_PARAM found outside of special section");
|
||||
}
|
||||
u8 presetType = GetSpecialObjectType(preset);
|
||||
if (presetType == SPTYPE_UNKNOWN) {
|
||||
PrintDataError("SPECIAL_OBJECT_WITH_YAW_AND_PARAM has invalid preset: %d", preset);
|
||||
}
|
||||
if (presetType != SPTYPE_PARAMS_AND_YROT) {
|
||||
PrintDataError("SPECIAL_OBJECT_WITH_YAW_AND_PARAM cannot be used with preset: %d (use %s instead)", preset, GetCorrectSpecialObjectCommand(presetType));
|
||||
}
|
||||
aColValData.specialCount++;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ extern "C" {
|
|||
#include "behavior_data.h"
|
||||
#include "pc/lua/smlua_hooks.h"
|
||||
|
||||
s8 geo_get_processing_mario_index(void);
|
||||
s8 geo_get_processing_mario_index(struct Object *obj);
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -77,7 +77,7 @@ void DynOS_Anim_Swap(void *aPtr) {
|
|||
|
||||
// Animation index
|
||||
s32 _AnimIndex = -1;
|
||||
s8 index = geo_get_processing_mario_index();
|
||||
s8 index = geo_get_processing_mario_index(_Object);
|
||||
if (index != -1) {
|
||||
_AnimIndex = RetrieveCurrentMarioAnimationIndex(index);
|
||||
|
||||
|
|
|
|||
|
|
@ -2037,6 +2037,7 @@ static const DynosBuiltinFunction sDynosBuiltinFuncs[] = {
|
|||
define_builtin_function(bhv_ambient_light_update, FUNCTION_BHV),
|
||||
define_builtin_function(bhv_point_light_init, FUNCTION_BHV),
|
||||
define_builtin_function(bhv_point_light_loop, FUNCTION_BHV),
|
||||
define_builtin_function(geo_switch_character_type_ext, FUNCTION_GEO),
|
||||
};
|
||||
|
||||
static const char *sDynosBuiltinFuncTypeNames[] = {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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:](#)
|
||||
|
||||
|
|
|
|||
|
|
@ -2191,10 +2191,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 +2233,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 +2286,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 +2326,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)
|
||||
|
|
@ -1403,9 +1406,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 +1614,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)
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -100,6 +100,7 @@ N64_BINDS = "N64 Ovládání"
|
|||
EXTRA_BINDS = "Extra Ovládání"
|
||||
BACKGROUND_GAMEPAD = "Ovladač v pozadí"
|
||||
DISABLE_GAMEPADS = "Zakažte gamepady"
|
||||
EXTENDED_REPORTS = "Rozšířené zprávy"
|
||||
GAMEPAD = "Použít ovladač"
|
||||
DEADZONE = "Deadzone"
|
||||
RUMBLE_STRENGTH = "Síla vibrace"
|
||||
|
|
|
|||
|
|
@ -100,6 +100,7 @@ N64_BINDS = "N64 Toetsen"
|
|||
EXTRA_BINDS = "Extra Toetsen"
|
||||
BACKGROUND_GAMEPAD = "Achtergrond Gamepad"
|
||||
DISABLE_GAMEPADS = "Gamepads uitschakelen"
|
||||
EXTENDED_REPORTS = "Uitgebreide rapporten"
|
||||
GAMEPAD = "Gamepad"
|
||||
DEADZONE = "Doode-zone"
|
||||
RUMBLE_STRENGTH = "Rommel Kracht"
|
||||
|
|
|
|||
|
|
@ -100,6 +100,7 @@ N64_BINDS = "N64 Binds"
|
|||
EXTRA_BINDS = "Extra Binds"
|
||||
BACKGROUND_GAMEPAD = "Background Gamepad"
|
||||
DISABLE_GAMEPADS = "Disable Gamepads"
|
||||
EXTENDED_REPORTS = "Extended Reports"
|
||||
GAMEPAD = "Gamepad"
|
||||
DEADZONE = "Deadzone"
|
||||
RUMBLE_STRENGTH = "Rumble Strength"
|
||||
|
|
|
|||
|
|
@ -100,6 +100,7 @@ N64_BINDS = "Touches N64"
|
|||
EXTRA_BINDS = "Touches Supplémentaires"
|
||||
BACKGROUND_GAMEPAD = "Manette en arrière plan"
|
||||
DISABLE_GAMEPADS = "Désactiver les manettes de jeu"
|
||||
EXTENDED_REPORTS = "Rapports détaillés"
|
||||
GAMEPAD = "Manette"
|
||||
DEADZONE = "Zone Morte"
|
||||
RUMBLE_STRENGTH = "Vibrations"
|
||||
|
|
|
|||
|
|
@ -99,6 +99,7 @@ CONTROLS = "STEUERUNG"
|
|||
N64_BINDS = "N64-Einstellungen"
|
||||
EXTRA_BINDS = "Zusätzliche Einstellungen"
|
||||
BACKGROUND_GAMEPAD = "Hintergrund-Gamepad"
|
||||
EXTENDED_REPORTS = "Erweiterte Berichte"
|
||||
DISABLE_GAMEPADS = "Gamepads deaktivieren"
|
||||
GAMEPAD = "Gamepad"
|
||||
DEADZONE = "Tote Zone"
|
||||
|
|
|
|||
|
|
@ -98,6 +98,7 @@ CONTROLS = "CONTROLLI"
|
|||
N64_BINDS = "Comandi N64"
|
||||
EXTRA_BINDS = "Comandi Extra"
|
||||
BACKGROUND_GAMEPAD = "Attivi in Background"
|
||||
EXTENDED_REPORTS = "Rapporti estesi"
|
||||
DISABLE_GAMEPADS = "Disabilita i Gamepad"
|
||||
GAMEPAD = "Controller"
|
||||
DEADZONE = "Zona Morta"
|
||||
|
|
|
|||
|
|
@ -99,6 +99,7 @@ CONTROLS = "CONTROLS"
|
|||
N64_BINDS = "ニンテンドウ64のボタン割り当て"
|
||||
EXTRA_BINDS = "追加のボタン割り当て"
|
||||
BACKGROUND_GAMEPAD = "バックグラウンドでのコントローラー認識"
|
||||
EXTENDED_REPORTS = "拡張レポート"
|
||||
DISABLE_GAMEPADS = "コントローラーを無効化"
|
||||
GAMEPAD = "コントローラー"
|
||||
DEADZONE = "デッドゾーン"
|
||||
|
|
|
|||
|
|
@ -99,6 +99,7 @@ CONTROLS = "STEROWANIE"
|
|||
N64_BINDS = "Przypisania N64"
|
||||
EXTRA_BINDS = "Dodatkowe Przypisania"
|
||||
BACKGROUND_GAMEPAD = "Gamepad w Tle"
|
||||
EXTENDED_REPORTS = "Rozszerzone raporty"
|
||||
DISABLE_GAMEPADS = "Wyłącz Gamepady"
|
||||
GAMEPAD = "Gamepad"
|
||||
DEADZONE = "Martwa Strefa"
|
||||
|
|
|
|||
|
|
@ -99,6 +99,7 @@ CONTROLS = "CONTROLES"
|
|||
N64_BINDS = "N64"
|
||||
EXTRA_BINDS = "Outros"
|
||||
BACKGROUND_GAMEPAD = "Controle de fundo"
|
||||
EXTENDED_REPORTS = "Relatórios detalhados"
|
||||
DISABLE_GAMEPADS = "Desativar controles"
|
||||
GAMEPAD = "Controle"
|
||||
DEADZONE = "Zona morta"
|
||||
|
|
|
|||
|
|
@ -98,6 +98,7 @@ CONTROLS = "CONTROLS"
|
|||
N64_BINDS = "Кнопки N64"
|
||||
EXTRA_BINDS = "Дополнительные кнопки"
|
||||
BACKGROUND_GAMEPAD = "Фоновый ввод"
|
||||
EXTENDED_REPORTS = "Расширенные отчеты"
|
||||
DISABLE_GAMEPADS = "Отключить геймпады"
|
||||
GAMEPAD = "Геймпад"
|
||||
DEADZONE = "Mёртвая зона"
|
||||
|
|
|
|||
|
|
@ -100,6 +100,7 @@ N64_BINDS = "Botones de N64"
|
|||
EXTRA_BINDS = "Botones Adicionales"
|
||||
BACKGROUND_GAMEPAD = "Mando en segundo plano"
|
||||
DISABLE_GAMEPADS = "Desactivar mandos"
|
||||
EXTENDED_REPORTS = "Informes ampliados"
|
||||
GAMEPAD = "Mando"
|
||||
DEADZONE = "Zona muerta"
|
||||
RUMBLE_STRENGTH = "Intensidad de vibración"
|
||||
|
|
|
|||
|
|
@ -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.
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.
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -1,843 +0,0 @@
|
|||
-------------------
|
||||
-- Birdo Moveset --
|
||||
-------------------
|
||||
|
||||
if not charSelect then return end
|
||||
|
||||
local SOUND_SPIT = audio_sample_load("z_sfx_birdo_spit.ogg") -- Load audio sample
|
||||
|
||||
---------------
|
||||
-- Birdo Egg --
|
||||
---------------
|
||||
|
||||
_G.ACT_BIRDO_HOLD_WALKING = allocate_mario_action(ACT_FLAG_MOVING | ACT_GROUP_OBJECT)
|
||||
_G.ACT_SPIT_EGG = allocate_mario_action(ACT_FLAG_STATIONARY | ACT_FLAG_IDLE | ACT_FLAG_ALLOW_FIRST_PERSON | ACT_FLAG_PAUSE_EXIT)
|
||||
_G.ACT_SPIT_EGG_WALK = allocate_mario_action(ACT_FLAG_MOVING | ACT_FLAG_ALLOW_FIRST_PERSON)
|
||||
_G.ACT_SPIT_EGG_AIR = allocate_mario_action(ACT_FLAG_AIR | ACT_FLAG_ALLOW_VERTICAL_WIND_ACTION | ACT_FLAG_CONTROL_JUMP_HEIGHT)
|
||||
|
||||
--- @param m MarioState
|
||||
local function act_birdo_hold_walking(m)
|
||||
local startYaw = m.faceAngle.y
|
||||
|
||||
if m.heldObj and m.heldObj.behavior == get_behavior_from_id(id_bhvJumpingBox) then
|
||||
return set_mario_action(m, ACT_CRAZY_BOX_BOUNCE, 0)
|
||||
end
|
||||
|
||||
if (m.marioObj.oInteractStatus & INT_STATUS_MARIO_DROP_OBJECT) ~= 0 then
|
||||
return drop_and_set_mario_action(m, ACT_WALKING, 0)
|
||||
end
|
||||
|
||||
if (should_begin_sliding(m)) ~= 0 then
|
||||
return set_mario_action(m, ACT_HOLD_BEGIN_SLIDING, 0)
|
||||
end
|
||||
|
||||
if (m.input & INPUT_B_PRESSED) ~= 0 then
|
||||
return set_mario_action(m, ACT_THROWING, 0)
|
||||
end
|
||||
|
||||
if (m.input & INPUT_A_PRESSED) ~= 0 then
|
||||
return set_jumping_action(m, ACT_HOLD_JUMP, 0)
|
||||
end
|
||||
|
||||
if (m.input & INPUT_ZERO_MOVEMENT) ~= 0 then
|
||||
return set_mario_action(m, ACT_HOLD_DECELERATING, 0)
|
||||
end
|
||||
|
||||
if (m.input & INPUT_Z_PRESSED) ~= 0 then
|
||||
return drop_and_set_mario_action(m, ACT_CROUCH_SLIDE, 0)
|
||||
end
|
||||
|
||||
update_walking_speed(m) -- normal walking speed
|
||||
|
||||
local result = perform_ground_step(m)
|
||||
if result == GROUND_STEP_LEFT_GROUND then
|
||||
set_mario_action(m, ACT_HOLD_FREEFALL, 0)
|
||||
elseif result == GROUND_STEP_HIT_WALL then
|
||||
if (m.forwardVel > 16) then
|
||||
mario_set_forward_vel(m, 16)
|
||||
end
|
||||
end
|
||||
|
||||
-- for the animation, temporarily read birdo's speed as lower so it looks less goofy
|
||||
local prevForwardVel = m.forwardVel
|
||||
local prevMag = m.intendedMag
|
||||
m.forwardVel = m.forwardVel * 0.6
|
||||
m.intendedMag = m.intendedMag * 0.6
|
||||
anim_and_audio_for_hold_walk(m)
|
||||
m.forwardVel = prevForwardVel
|
||||
m.intendedMag = prevMag
|
||||
|
||||
|
||||
-- tilt body
|
||||
local dYaw = m.faceAngle.y - startYaw
|
||||
local val02 = -(dYaw * m.forwardVel / 12)
|
||||
local val00 = (m.forwardVel * 170)
|
||||
|
||||
val02 = math.clamp(val02, -0x1555, 0x1555)
|
||||
val00 = math.clamp(val00, 0x0, 0x1555)
|
||||
|
||||
m.marioBodyState.allowPartRotation = true
|
||||
m.marioBodyState.torsoAngle.z = approach_s32(m.marioBodyState.torsoAngle.z, val02, 0x400, 0x400)
|
||||
m.marioBodyState.torsoAngle.x = approach_s32(m.marioBodyState.torsoAngle.x, val00, 0x400, 0x400)
|
||||
|
||||
if (0.4 * m.intendedMag - m.forwardVel > 10) then
|
||||
set_mario_particle_flags(m, PARTICLE_DUST, 0)
|
||||
end
|
||||
|
||||
return 0
|
||||
end
|
||||
|
||||
--- @param m MarioState
|
||||
local function act_spit_egg(m)
|
||||
local e = gCharacterStates[m.playerIndex]
|
||||
if (m.quicksandDepth > 30) then
|
||||
return set_mario_action(m, ACT_IN_QUICKSAND, 0)
|
||||
end
|
||||
|
||||
if m.actionState == 0 then
|
||||
play_custom_anim(m, "BIRDO_ANIM_IDLE_TO_AIM_IDLE")
|
||||
if is_anim_past_end(m) ~= 0 then
|
||||
m.actionState = 1
|
||||
end
|
||||
elseif e.birdo.flameCharge == 0 and e.birdo.framesSinceShoot > 10 then
|
||||
play_custom_anim(m, "BIRDO_ANIM_AIM_IDLE_TO_IDLE")
|
||||
if is_anim_past_end(m) ~= 0 then
|
||||
return set_mario_action(m, ACT_IDLE, 0)
|
||||
end
|
||||
else
|
||||
play_custom_anim(m, "BIRDO_ANIM_AIM_IDLE")
|
||||
end
|
||||
mario_drop_held_object(m)
|
||||
|
||||
m.actionTimer = m.actionTimer + 1
|
||||
|
||||
local oldActTimer = m.actionTimer
|
||||
if (m.input & INPUT_NONZERO_ANALOG) ~= 0 then
|
||||
mario_set_forward_vel(m, 0)
|
||||
local result = set_mario_action(m, ACT_SPIT_EGG_WALK, 0)
|
||||
m.actionTimer = oldActTimer
|
||||
return result
|
||||
elseif (check_common_idle_cancels(m) ~= 0) then
|
||||
if m.action & ACT_FLAG_AIR ~= 0 then
|
||||
mario_set_forward_vel(m, 0)
|
||||
set_mario_action(m, ACT_SPIT_EGG_AIR, 1)
|
||||
if m.vel.y <= 0 then
|
||||
m.actionArg = 0
|
||||
end
|
||||
m.actionTimer = oldActTimer
|
||||
end
|
||||
return 1
|
||||
end
|
||||
|
||||
mario_set_forward_vel(m, 0)
|
||||
perform_ground_step(m)
|
||||
return 0
|
||||
end
|
||||
|
||||
--- @param m MarioState
|
||||
local function act_spit_egg_walk(m)
|
||||
local e = gCharacterStates[m.playerIndex]
|
||||
local mBody = m.marioBodyState
|
||||
|
||||
mario_drop_held_object(m)
|
||||
|
||||
m.actionTimer = m.actionTimer + 1
|
||||
if e.birdo.flameCharge == 0 and e.birdo.framesSinceShoot > 10 then
|
||||
if m.forwardVel < 0 then
|
||||
m.forwardVel = m.intendedMag
|
||||
m.faceAngle.y = m.intendedYaw
|
||||
return set_mario_action(m, ACT_FINISH_TURNING_AROUND, 0)
|
||||
end
|
||||
m.forwardVel = m.intendedMag
|
||||
m.faceAngle.y = m.intendedYaw
|
||||
return set_mario_action(m, ACT_WALKING, 0)
|
||||
end
|
||||
|
||||
if mario_floor_is_slippery(m) ~= 0 then
|
||||
return set_mario_action(m, ACT_WALKING, 0)
|
||||
end
|
||||
|
||||
if (should_begin_sliding(m)) ~= 0 then
|
||||
return set_mario_action(m, ACT_BEGIN_SLIDING, 0)
|
||||
end
|
||||
|
||||
if (m.input & INPUT_FIRST_PERSON) ~= 0 then
|
||||
m.intendedMag = 0
|
||||
if m.slideVelX == 0 and m.slideVelZ == 0 then
|
||||
return begin_braking_action(m)
|
||||
end
|
||||
end
|
||||
|
||||
if (m.input & INPUT_ZERO_MOVEMENT) ~= 0 and m.slideVelX == 0 and m.slideVelZ == 0 then
|
||||
local oldActTimer = m.actionTimer
|
||||
local result = set_mario_action(m, ACT_SPIT_EGG, 0)
|
||||
m.actionTimer = oldActTimer
|
||||
return result
|
||||
end
|
||||
|
||||
if (m.input & INPUT_Z_PRESSED) ~= 0 then
|
||||
return set_mario_action(m, ACT_CROUCH_SLIDE, 0)
|
||||
end
|
||||
|
||||
-- strafe movement
|
||||
local newVelX = sins(m.intendedYaw) * m.intendedMag
|
||||
local newVelZ = coss(m.intendedYaw) * m.intendedMag
|
||||
m.slideVelX = approach_f32(m.slideVelX, newVelX, 4, 4)
|
||||
m.slideVelZ = approach_f32(m.slideVelZ, newVelZ, 4, 4)
|
||||
m.vel.x, m.vel.z = m.slideVelX, m.slideVelZ
|
||||
m.forwardVel = math.sqrt(m.vel.x ^ 2 + m.vel.z ^ 2)
|
||||
|
||||
if (m.input & INPUT_A_PRESSED) ~= 0 then
|
||||
set_mario_y_vel_based_on_fspeed(m, 42, 0.25)
|
||||
m.slideVelX = m.slideVelX * 0.8
|
||||
m.slideVelZ = m.slideVelZ * 0.8
|
||||
m.vel.x, m.vel.z = m.slideVelX, m.slideVelZ
|
||||
m.forwardVel = m.forwardVel * 0.8
|
||||
local oldActTimer = m.actionTimer
|
||||
local result = set_mario_action(m, ACT_SPIT_EGG_AIR, 1)
|
||||
m.actionTimer = oldActTimer
|
||||
return result
|
||||
end
|
||||
|
||||
local result = (perform_ground_step(m))
|
||||
if result == GROUND_STEP_LEFT_GROUND then
|
||||
m.vel.y = 0
|
||||
local oldActTimer = m.actionTimer
|
||||
set_mario_action(m, ACT_SPIT_EGG_AIR, 0)
|
||||
m.actionTimer = oldActTimer
|
||||
--set_character_animation(m, CHAR_ANIM_GENERAL_FALL)
|
||||
elseif result == GROUND_STEP_NONE then
|
||||
--anim_and_audio_for_walk(m)
|
||||
play_step_sound(m, 10, 49)
|
||||
|
||||
local dYaw = math.s16(m.faceAngle.y - m.intendedYaw)
|
||||
play_custom_anim(m, "BIRDO_ANIM_AIM_WALK", m.forwardVel / 4 * 0x10000)
|
||||
|
||||
mBody.allowPartRotation = true
|
||||
m.marioObj.header.gfx.angle.y = m.intendedYaw
|
||||
local marioAnimInfo = m.marioObj.header.gfx.animInfo
|
||||
if math.abs(dYaw) > 0x4000 then
|
||||
m.marioObj.header.gfx.angle.y = m.intendedYaw - 0x8000
|
||||
marioAnimInfo.animAccel = -math.abs(marioAnimInfo.animAccel)
|
||||
else
|
||||
marioAnimInfo.animAccel = math.abs(marioAnimInfo.animAccel)
|
||||
end
|
||||
|
||||
-- Handle manually the loop points of the animation if moving backwards
|
||||
if marioAnimInfo.animAccel < 0 and marioAnimInfo.animFrame <= marioAnimInfo.curAnim.loopStart then
|
||||
marioAnimInfo.animFrame = marioAnimInfo.curAnim.loopEnd
|
||||
marioAnimInfo.animFrameAccelAssist = marioAnimInfo.animFrame << 16
|
||||
end
|
||||
|
||||
mBody.torsoAngle.y = math.s16(m.faceAngle.y - m.marioObj.header.gfx.angle.y) * 0.4
|
||||
mBody.headAngle.y = m.faceAngle.y - m.marioObj.header.gfx.angle.y - mBody.torsoAngle.y
|
||||
|
||||
if m.intendedMag - m.forwardVel > 16 then
|
||||
set_mario_particle_flags(m, PARTICLE_DUST, 0)
|
||||
end
|
||||
end
|
||||
|
||||
check_ledge_climb_down(m)
|
||||
return 0
|
||||
end
|
||||
|
||||
---@param m MarioState
|
||||
local function act_spit_egg_air(m)
|
||||
local e = gCharacterStates[m.playerIndex]
|
||||
|
||||
play_custom_anim(m, "BIRDO_ANIM_AIM_JUMP")
|
||||
if m.actionArg ~= 1 then
|
||||
set_anim_to_frame(m, m.marioObj.header.gfx.animInfo.curAnim.loopEnd)
|
||||
else
|
||||
play_mario_sound(m, SOUND_ACTION_TERRAIN_JUMP, 0)
|
||||
end
|
||||
|
||||
m.actionTimer = m.actionTimer + 1
|
||||
|
||||
if (m.input & INPUT_Z_PRESSED) ~= 0 then
|
||||
return set_mario_action(m, ACT_GROUND_POUND, 0)
|
||||
end
|
||||
|
||||
-- air strafe
|
||||
local newVelX = sins(m.intendedYaw) * m.intendedMag
|
||||
local newVelZ = coss(m.intendedYaw) * m.intendedMag
|
||||
m.slideVelX = approach_f32(m.slideVelX, newVelX, 1, 1)
|
||||
m.slideVelZ = approach_f32(m.slideVelZ, newVelZ, 1, 1)
|
||||
m.vel.x, m.vel.z = m.slideVelX, m.slideVelZ
|
||||
m.forwardVel = m.slideVelX * sins(m.faceAngle.y) + m.slideVelZ * coss(m.faceAngle.y)
|
||||
--local absSpeed = math.max(math.abs(m.slideVelX), math.abs(m.slideVelZ))
|
||||
|
||||
local result = (perform_air_step(m, 0))
|
||||
if result == AIR_STEP_LANDED then
|
||||
if check_fall_damage_or_get_stuck(m, ACT_HARD_BACKWARD_GROUND_KB) ~= 0 then
|
||||
return 1
|
||||
elseif e.birdo.flameCharge == 0 and e.birdo.framesSinceShoot > 10 then
|
||||
set_mario_action(m, ACT_FREEFALL_LAND, 0)
|
||||
else
|
||||
local oldActTimer = m.actionTimer
|
||||
set_mario_action(m, ACT_SPIT_EGG_WALK, 0)
|
||||
m.actionTimer = oldActTimer
|
||||
end
|
||||
return 1
|
||||
elseif result == AIR_STEP_HIT_WALL then
|
||||
mario_set_forward_vel(m, 0)
|
||||
elseif result == AIR_STEP_HIT_LAVA_WALL then
|
||||
lava_boost_on_wall(m)
|
||||
end
|
||||
|
||||
return 0
|
||||
end
|
||||
|
||||
-- Egg
|
||||
|
||||
local eggIntObjLists = {
|
||||
OBJ_LIST_GENACTOR,
|
||||
OBJ_LIST_PUSHABLE,
|
||||
OBJ_LIST_SURFACE,
|
||||
OBJ_LIST_PLAYER,
|
||||
}
|
||||
|
||||
E_MODEL_EGG = smlua_model_util_get_id("egg_geo")
|
||||
---@param o Object
|
||||
function bhv_birdo_egg_init(o)
|
||||
o.oFlags = (OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_HOLDABLE | OBJ_FLAG_COMPUTE_DIST_TO_MARIO)
|
||||
o.oFaceAngleRoll = 0
|
||||
o.oMoveAngleRoll = 0
|
||||
o.oGravity = 0
|
||||
o.oBounciness = 0
|
||||
o.oFriction = 1
|
||||
o.oDragStrength = 0
|
||||
o.oBuoyancy = 0
|
||||
o.oWallHitboxRadius = 60
|
||||
o.oVelY = 0
|
||||
|
||||
o.collisionData = smlua_collision_util_get("egg_collision")
|
||||
|
||||
local hitbox = get_temp_object_hitbox()
|
||||
hitbox.interactType = INTERACT_DAMAGE
|
||||
hitbox.hurtboxRadius = 60
|
||||
hitbox.hurtboxHeight = 80
|
||||
hitbox.downOffset = 80
|
||||
hitbox.radius = 60
|
||||
hitbox.height = 80
|
||||
hitbox.damageOrCoinValue = 1
|
||||
if o.oBehParams ~= 0 then
|
||||
-- similar hitbox to fire spitter flames
|
||||
hitbox.interactType = INTERACT_FLAME
|
||||
hitbox.radius = 10
|
||||
hitbox.height = 40
|
||||
hitbox.hurtboxRadius = 10
|
||||
hitbox.hurtboxHeight = 40
|
||||
hitbox.downOffset = 30
|
||||
obj_set_billboard(o)
|
||||
o.header.gfx.scale.x = 3
|
||||
o.header.gfx.scale.y = 3
|
||||
o.header.gfx.scale.z = 3
|
||||
end
|
||||
obj_set_hitbox(o, hitbox)
|
||||
o.oIntangibleTimer = 10
|
||||
|
||||
-- do manual shadow, otherwise the shadow renders on top of itself
|
||||
o.header.gfx.disableAutomaticShadowPos = true
|
||||
o.header.gfx.shadowPos.x = o.oPosX
|
||||
o.header.gfx.shadowPos.y = o.oPosY - 50
|
||||
o.header.gfx.shadowPos.z = o.oPosZ
|
||||
|
||||
network_init_object(o, true, { 'globalPlayerIndex' })
|
||||
end
|
||||
|
||||
---@param o Object
|
||||
function bhv_birdo_egg_loop(o)
|
||||
if o.oBehParams ~= 0 then
|
||||
o.oAnimState = o.oAnimState + 1
|
||||
end
|
||||
|
||||
if o.oHeldState == HELD_FREE then
|
||||
cur_obj_enable_rendering()
|
||||
if o.oAction == 0 then
|
||||
o.oGravity = 0
|
||||
else
|
||||
o.oMoveAnglePitch = 0
|
||||
o.oFaceAnglePitch = 0
|
||||
o.oGravity = -2
|
||||
end
|
||||
|
||||
cur_obj_update_floor_and_walls()
|
||||
local oldForwardVel = o.oForwardVel
|
||||
if o.oAction == 0 then
|
||||
obj_compute_vel_from_move_pitch(o.oForwardVel)
|
||||
end
|
||||
cur_obj_move_standard(60)
|
||||
o.oForwardVel = oldForwardVel
|
||||
|
||||
local defaultVel = 20
|
||||
if o.oBehParams ~= 0 then
|
||||
defaultVel = 40
|
||||
end
|
||||
if o.oAction == 0 and o.oForwardVel > defaultVel then
|
||||
o.oForwardVel = approach_f32(o.oForwardVel, defaultVel, 3, 3)
|
||||
end
|
||||
|
||||
-- manual object collision
|
||||
local dieFromCollision = false
|
||||
o.numCollidedObjs = obj_attack_collided_from_other_object(o)
|
||||
if o.numCollidedObjs ~= 0 and o.oBehParams == 0 then
|
||||
dieFromCollision = true
|
||||
end
|
||||
if o.oDistanceToMario < 2000 then
|
||||
for _, list in ipairs(eggIntObjLists) do
|
||||
local o2 = obj_get_first(list)
|
||||
while o2 and o.numCollidedObjs < 4 do
|
||||
if o ~= o2 then
|
||||
if list ~= OBJ_LIST_PLAYER and o2.oHeldState == HELD_FREE and detect_object_hitbox_overlap(o, o2) ~= 0 then
|
||||
o2.numCollidedObjs = o2.numCollidedObjs - 1 -- prevent game crash
|
||||
local doEggInteract = birdo_egg_interaction(o2, o)
|
||||
if o.oBehParams == 0 or doEggInteract then
|
||||
dieFromCollision = true
|
||||
end
|
||||
if doEggInteract or o2.oInteractType == INTERACT_BREAKABLE or obj_is_attackable(o2) then
|
||||
if obj_has_behavior_id(o2, id_bhvBowser) == 0 then
|
||||
o2.oInteractStatus = o2.oInteractStatus | ATTACK_PUNCH | INT_STATUS_WAS_ATTACKED |
|
||||
INT_STATUS_INTERACTED | INT_STATUS_TOUCHED_BOB_OMB
|
||||
end
|
||||
end
|
||||
elseif o.oBehParams ~= 0 and birdo_fire_is_targettable(o2, o) and dist_between_objects(o2, o) <= 700 then
|
||||
local angleToObject = obj_angle_to_object(o, o2)
|
||||
if abs_angle_diff(o.oMoveAngleYaw, angleToObject) <= 0x4000 then
|
||||
cur_obj_rotate_yaw_toward(angleToObject, 0x200)
|
||||
end
|
||||
end
|
||||
end
|
||||
o2 = obj_get_next(o2)
|
||||
end
|
||||
if o.numCollidedObjs >= 4 then break end
|
||||
end
|
||||
end
|
||||
|
||||
-- surface collision
|
||||
if o.oAction == 0 and o.oBehParams == 0 and o.oMoveFlags & OBJ_MOVE_MASK_IN_WATER == 0 then
|
||||
local m0 = gMarioStates[0]
|
||||
load_object_collision_model()
|
||||
if cur_obj_is_mario_on_platform() ~= 0 then
|
||||
if (m0.action == ACT_PUNCHING or m0.action == ACT_MOVE_PUNCHING) then
|
||||
-- pick up egg
|
||||
m0.heldObj = o
|
||||
m0.marioBodyState.grabPos = GRAB_POS_LIGHT_OBJ
|
||||
o.heldByPlayerIndex = 0
|
||||
o.oHeldState = HELD_HELD
|
||||
set_mario_action(m0, ACT_HOLD_FREEFALL, 0)
|
||||
if (o.oSyncID ~= 0) then network_send_object(o, false) end
|
||||
elseif (m0.prevAction & ACT_FLAG_AIR) ~= 0 then -- prevent falling off of egg easily
|
||||
m0.pos.x = o.oPosX
|
||||
m0.pos.z = o.oPosZ
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if dieFromCollision or o.oMoveFlags & (OBJ_MOVE_HIT_WALL | OBJ_MOVE_UNDERWATER_ON_GROUND | OBJ_MOVE_MASK_ON_GROUND) ~= 0 or o.oTimer > 120 then
|
||||
o.numCollidedObjs = 0
|
||||
spawn_mist_particles()
|
||||
obj_mark_for_deletion(o)
|
||||
end
|
||||
o.oInteractStatus = 0
|
||||
o.numCollidedObjs = 0
|
||||
elseif o.oHeldState == HELD_HELD then
|
||||
o.oFaceAnglePitch = 0
|
||||
o.oMoveAnglePitch = 0
|
||||
o.oInteractType = INTERACT_GRABBABLE
|
||||
cur_obj_disable_rendering_and_become_intangible(o)
|
||||
elseif o.oHeldState == HELD_THROWN then
|
||||
o.oFaceAnglePitch = 0
|
||||
o.oMoveAnglePitch = 0
|
||||
o.oInteractType = INTERACT_DAMAGE
|
||||
cur_obj_enable_rendering_and_become_tangible(o)
|
||||
cur_obj_change_action(1)
|
||||
local m = gMarioStates[o.heldByPlayerIndex]
|
||||
o.oForwardVel = math.max(m.forwardVel + 15, 40)
|
||||
o.oVelY = 10
|
||||
o.oTimer = 0
|
||||
o.oHeldState = HELD_FREE
|
||||
o.oIntangibleTimer = 10
|
||||
elseif o.oHeldState == HELD_DROPPED then
|
||||
spawn_mist_particles()
|
||||
obj_mark_for_deletion(o)
|
||||
end
|
||||
|
||||
-- do manual shadow, otherwise the shadow renders on top of itself
|
||||
if o.activeFlags ~= ACTIVE_FLAG_DEACTIVATED then
|
||||
o.header.gfx.disableAutomaticShadowPos = true
|
||||
o.header.gfx.shadowPos.x = o.oPosX
|
||||
o.header.gfx.shadowPos.y = o.oPosY - 50
|
||||
o.header.gfx.shadowPos.z = o.oPosZ
|
||||
else
|
||||
o.header.gfx.disableAutomaticShadowPos = false
|
||||
end
|
||||
end
|
||||
|
||||
-- lua recreation
|
||||
---@param a Object
|
||||
---@param b Object
|
||||
function detect_object_hitbox_overlap(a, b)
|
||||
if not (a and b) then return 0 end
|
||||
local sp3C = a.oPosY - a.hitboxDownOffset
|
||||
local sp38 = b.oPosY - b.hitboxDownOffset
|
||||
local dx = a.oPosX - b.oPosX
|
||||
local dz = a.oPosZ - b.oPosZ
|
||||
local collisionRadius = a.hitboxRadius + b.hitboxRadius
|
||||
local distance = math.floor(math.sqrt(dx * dx + dz * dz))
|
||||
|
||||
-- do not check for player interactions here
|
||||
if ((a.oInteractType & INTERACT_PLAYER) ~= 0 and (b.oInteractType & INTERACT_PLAYER) ~= 0) then
|
||||
return 0
|
||||
end
|
||||
|
||||
if (collisionRadius > distance) then
|
||||
local sp20 = a.hitboxHeight + sp3C
|
||||
local sp1C = b.hitboxHeight + sp38
|
||||
|
||||
if (sp3C > sp1C) then
|
||||
return 0
|
||||
end
|
||||
if (sp20 < sp38) then
|
||||
return 0
|
||||
end
|
||||
if (a.numCollidedObjs >= 4) then
|
||||
return 0
|
||||
end
|
||||
if (b.numCollidedObjs >= 4) then
|
||||
return 0
|
||||
end
|
||||
-- can't reference these fields in lua
|
||||
--a.collidedObjs[a.numCollidedObjs] = b
|
||||
--b.collidedObjs[b.numCollidedObjs] = a
|
||||
a.collidedObjInteractTypes = a.collidedObjInteractTypes | b.oInteractType
|
||||
b.collidedObjInteractTypes = b.collidedObjInteractTypes | a.oInteractType
|
||||
a.numCollidedObjs = a.numCollidedObjs + 1
|
||||
b.numCollidedObjs = b.numCollidedObjs + 1
|
||||
return 1
|
||||
end
|
||||
|
||||
return 0
|
||||
end
|
||||
|
||||
id_bhvBirdoEgg = hook_behavior(nil, OBJ_LIST_SURFACE, true, bhv_birdo_egg_init, bhv_birdo_egg_loop, "bhvBirdoEgg")
|
||||
|
||||
---@param m MarioState
|
||||
function birdo_update(m)
|
||||
-- spit egg
|
||||
local e = gCharacterStates[m.playerIndex]
|
||||
local inSpitAction = (m.action == ACT_SPIT_EGG or m.action == ACT_SPIT_EGG_WALK or m.action == ACT_SPIT_EGG_AIR or m.action == ACT_FIRST_PERSON or m.action == ACT_WATER_PUNCH or m.action == ACT_FLYING)
|
||||
local headRot = m.marioBodyState.headAngle
|
||||
|
||||
if m.controller.buttonPressed & B_BUTTON ~= 0 and inSpitAction then
|
||||
-- when mashing B, stay in spit action
|
||||
e.birdo.framesSinceShoot = 0
|
||||
if e.birdo.spitTimer == 0 then
|
||||
e.birdo.flameCharge = 0
|
||||
end
|
||||
else
|
||||
-- handle shooting repeatedly/charging
|
||||
if e.birdo.framesSinceShoot ~= 255 then
|
||||
e.birdo.framesSinceShoot = e.birdo.framesSinceShoot + 1
|
||||
end
|
||||
if m.controller.buttonDown & B_BUTTON ~= 0 then
|
||||
if inSpitAction then
|
||||
e.birdo.flameCharge = e.birdo.flameCharge + 1
|
||||
end
|
||||
elseif e.birdo.spitTimer < 25 then
|
||||
if e.birdo.flameCharge >= 30 then
|
||||
e.birdo.framesSinceShoot = 0 -- shoot fireball
|
||||
else
|
||||
e.birdo.flameCharge = 0
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if (e.birdo.framesSinceShoot <= 10 or e.birdo.flameCharge ~= 0) and not m.heldObj and inSpitAction then
|
||||
local canShoot = true
|
||||
local eggCount = 0
|
||||
local gIndex = network_global_index_from_local(m.playerIndex)
|
||||
local egg = obj_get_first_with_behavior_id(id_bhvBirdoEgg)
|
||||
while egg do
|
||||
if egg.oAction == 0 and egg.oHeldState == HELD_FREE and egg.globalPlayerIndex == gIndex then
|
||||
eggCount = eggCount + 1
|
||||
if eggCount >= 3 then -- max of 3 eggs/fireballs per player
|
||||
canShoot = false
|
||||
break
|
||||
end
|
||||
end
|
||||
egg = obj_get_next_with_same_behavior_id(egg)
|
||||
end
|
||||
|
||||
if e.birdo.spitTimer ~= 0 then
|
||||
e.birdo.spitTimer = e.birdo.spitTimer - 1
|
||||
m.marioBodyState.allowPartRotation = true
|
||||
if e.birdo.spitTimer > 24 then
|
||||
headRot.x = approach_f32(headRot.x, degrees_to_sm64(-30), degrees_to_sm64(10), degrees_to_sm64(10))
|
||||
else
|
||||
headRot.x = approach_f32(headRot.x, degrees_to_sm64(0), degrees_to_sm64(3.5), degrees_to_sm64(3.5))
|
||||
end
|
||||
end
|
||||
if e.birdo.spitTimer == 0 and canShoot and e.birdo.framesSinceShoot <= 10 then
|
||||
m.actionTimer = 0
|
||||
m.actionArg = 0
|
||||
end
|
||||
|
||||
local mouthPos = gVec3fZero()
|
||||
local yaw = m.faceAngle.y
|
||||
local pitch = 0
|
||||
if canShoot then
|
||||
-- when swimming, flying, or in first person, allow shooting in any direction
|
||||
if m.action == ACT_FIRST_PERSON then
|
||||
yaw = m.statusForCamera.headRotation.y + yaw
|
||||
pitch = m.statusForCamera.headRotation.x
|
||||
mouthPos.x = m.pos.x + sins(yaw) * 60 * coss(pitch)
|
||||
mouthPos.y = m.pos.y + 120 - sins(pitch) * 120
|
||||
mouthPos.z = m.pos.z + coss(yaw) * 60 * coss(pitch)
|
||||
elseif m.action & ACT_FLAG_SWIMMING_OR_FLYING ~= 0 then
|
||||
pitch = -m.faceAngle.x
|
||||
if pitch < 0 then
|
||||
mouthPos.x = m.pos.x + sins(yaw) * 80 * coss(pitch)
|
||||
mouthPos.y = m.pos.y + 120
|
||||
mouthPos.z = m.pos.z + coss(yaw) * 80 * coss(pitch)
|
||||
else
|
||||
mouthPos.x = m.pos.x + sins(yaw) * 80
|
||||
mouthPos.y = m.pos.y + 120 - sins(pitch) * 150
|
||||
mouthPos.z = m.pos.z + coss(yaw) * 80
|
||||
end
|
||||
else
|
||||
mouthPos.x = m.marioBodyState.headPos.x + sins(yaw + m.marioBodyState.headAngle.y) * 60
|
||||
mouthPos.y = m.marioBodyState.headPos.y + 20
|
||||
mouthPos.z = m.marioBodyState.headPos.z + coss(yaw + m.marioBodyState.headAngle.y) * 60
|
||||
end
|
||||
end
|
||||
|
||||
if canShoot and e.birdo.spitTimer == 0 and e.birdo.flameCharge >= 30 and m.action & ACT_FLAG_SWIMMING == 0 then
|
||||
spawn_non_sync_object(id_bhvKoopaShellFlame, E_MODEL_RED_FLAME,
|
||||
mouthPos.x,
|
||||
mouthPos.y,
|
||||
mouthPos.z,
|
||||
function(o)
|
||||
o.oKoopaShellFlameUnkF8 = 2
|
||||
o.oMoveAngleYaw = math.random(0, 0xFFFF)
|
||||
o.oVelY = math.random(10)
|
||||
o.oAnimState = math.random(10)
|
||||
o.oGravity = -4.0
|
||||
o.oTimer = 1
|
||||
o.oForwardVel = math.random(10)
|
||||
end)
|
||||
play_sound(SOUND_AIR_BLOW_FIRE, m.marioObj.header.gfx.cameraToObject)
|
||||
end
|
||||
|
||||
if canShoot and e.birdo.spitTimer == 0 and e.birdo.framesSinceShoot <= 10 then
|
||||
e.birdo.spitTimer = 30
|
||||
elseif e.birdo.spitTimer == 25 then
|
||||
local model = E_MODEL_EGG
|
||||
local isFireball = (e.birdo.flameCharge >= 30)
|
||||
if isFireball then
|
||||
model = E_MODEL_RED_FLAME
|
||||
e.birdo.flameCharge = 0
|
||||
end
|
||||
|
||||
if not isFireball then
|
||||
audio_sample_play(SOUND_SPIT, m.pos, 1) -- Play audio sample
|
||||
else
|
||||
play_sound(SOUND_AIR_BOWSER_SPIT_FIRE, m.marioObj.header.gfx.cameraToObject)
|
||||
end
|
||||
|
||||
if m.playerIndex == 0 then
|
||||
local eggVel = m.forwardVel * 2 + 25
|
||||
-- add double floor velocity to prevent being able to platform on eggs forever
|
||||
if m.floor and m.floor.object and m.floor.object.oForwardVel ~= 0 then
|
||||
eggVel = eggVel + m.floor.object.oForwardVel * 2
|
||||
end
|
||||
spawn_sync_object(id_bhvBirdoEgg, model, mouthPos.x + sins(yaw) * 40 * coss(pitch), mouthPos.y,
|
||||
mouthPos.z + coss(yaw) * 40 * coss(pitch), function(o)
|
||||
o.oForwardVel = math.max(eggVel, 40)
|
||||
o.oMoveAngleYaw = yaw
|
||||
o.oFaceAnglePitch = pitch
|
||||
o.oMoveAnglePitch = pitch
|
||||
o.oIntangibleTimer = 100
|
||||
o.globalPlayerIndex = gIndex
|
||||
o.oBehParams = (isFireball and 1) or 0
|
||||
spawn_mist_particles_variable(20, 120, 5)
|
||||
end)
|
||||
end
|
||||
end
|
||||
elseif e.birdo.spitTimer ~= 0 then
|
||||
e.birdo.spitTimer = e.birdo.spitTimer - 1
|
||||
m.marioBodyState.allowPartRotation = true
|
||||
if e.birdo.spitTimer > 24 then
|
||||
headRot.x = approach_f32(headRot.x, degrees_to_sm64(-30), degrees_to_sm64(10), degrees_to_sm64(10))
|
||||
else
|
||||
headRot.x = approach_f32(headRot.x, degrees_to_sm64(0), degrees_to_sm64(3.5), degrees_to_sm64(3.5))
|
||||
end
|
||||
end
|
||||
|
||||
-- throw objects instantly
|
||||
if m.action == ACT_THROWING then
|
||||
if m.actionTimer < 6 then
|
||||
m.actionTimer = 6
|
||||
set_anim_to_frame(m, 6)
|
||||
end
|
||||
elseif m.action == ACT_AIR_THROW or m.action == ACT_AIR_THROW_LAND then
|
||||
if m.actionTimer < 3 then
|
||||
m.actionTimer = 3
|
||||
set_anim_to_frame(m, 3)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function birdo_on_set_action(m)
|
||||
if m.action ~= ACT_SPIT_EGG and m.action ~= ACT_SPIT_EGG_WALK and m.action ~= ACT_SPIT_EGG_AIR then
|
||||
gCharacterStates[m.playerIndex].birdo.spitTimer = 0
|
||||
end
|
||||
if m.action == ACT_HOLD_WALKING then -- switch to custom hold action
|
||||
set_mario_action(m, ACT_BIRDO_HOLD_WALKING, 0)
|
||||
end
|
||||
end
|
||||
|
||||
local shootActs = {
|
||||
[ACT_PUNCHING] = ACT_SPIT_EGG,
|
||||
[ACT_MOVE_PUNCHING] = ACT_SPIT_EGG_WALK,
|
||||
[ACT_JUMP_KICK] = ACT_SPIT_EGG_AIR,
|
||||
}
|
||||
|
||||
function birdo_before_action(m, action, actionArg)
|
||||
if m.playerIndex ~= 0 then return end
|
||||
if shootActs[action] and m.controller.buttonDown & A_BUTTON == 0 then
|
||||
if action == ACT_PUNCHING and actionArg == 9 then return end
|
||||
local e = gCharacterStates[m.playerIndex]
|
||||
e.birdo.framesSinceShoot = 0
|
||||
if e.birdo.spitTimer == 0 then
|
||||
e.birdo.flameCharge = 0
|
||||
end
|
||||
|
||||
local canShoot = true
|
||||
local eggCount = 0
|
||||
local gIndex = network_global_index_from_local(m.playerIndex)
|
||||
local egg = obj_get_first_with_behavior_id(id_bhvBirdoEgg)
|
||||
while egg do
|
||||
if egg.oAction == 0 and egg.oHeldState == HELD_FREE and egg.globalPlayerIndex == gIndex then
|
||||
eggCount = eggCount + 1
|
||||
if eggCount >= 3 then -- max of 3 eggs/fireballs per player
|
||||
canShoot = false
|
||||
break
|
||||
end
|
||||
end
|
||||
egg = obj_get_next_with_same_behavior_id(egg)
|
||||
end
|
||||
|
||||
if m.action ~= ACT_SPIT_EGG or e.birdo.spitTimer == 0 or canShoot then
|
||||
m.marioObj.header.gfx.animInfo.animFrame = 0
|
||||
return shootActs[action]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function birdo_on_interact(m, o, intType)
|
||||
local e = gCharacterStates[m.playerIndex]
|
||||
if intType == INTERACT_GRABBABLE and e.birdo.framesSinceShoot == 0 and e.birdo.flameCharge == 0 and (m.action == ACT_SPIT_EGG or m.action == ACT_SPIT_EGG_WALK) and o.oInteractionSubtype & INT_SUBTYPE_NOT_GRABBABLE == 0 then
|
||||
set_mario_action(m, ACT_MOVE_PUNCHING, 1)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
function birdo_before_phys_step(m)
|
||||
local hScale = 1.0
|
||||
local vScale = 1.0
|
||||
|
||||
-- faster ground movement and slower, floaty air movement
|
||||
if (m.action & ACT_FLAG_MOVING) ~= 0 and m.action ~= ACT_BUBBLED then
|
||||
hScale = hScale * 1.12 -- not as fast as toad
|
||||
elseif m.action & ACT_FLAG_AIR ~= 0 then
|
||||
hScale = hScale * 0.94
|
||||
if m.vel.y < 0 then
|
||||
vScale = vScale * 0.98
|
||||
end
|
||||
end
|
||||
|
||||
m.vel.x = m.vel.x * hScale
|
||||
m.vel.y = m.vel.y * vScale
|
||||
m.vel.z = m.vel.z * hScale
|
||||
end
|
||||
|
||||
-- allow shooting in first person
|
||||
function birdo_before_update(m)
|
||||
if m.action == ACT_FIRST_PERSON and m.controller.buttonPressed & B_BUTTON ~= 0 then
|
||||
local e = gCharacterStates[m.playerIndex]
|
||||
e.birdo.framesSinceShoot = 0
|
||||
if e.birdo.spitTimer == 0 then
|
||||
e.birdo.flameCharge = 0
|
||||
end
|
||||
m.controller.buttonPressed = m.controller.buttonPressed & ~B_BUTTON
|
||||
end
|
||||
end
|
||||
|
||||
-- interactions for birdo's egg/fireball
|
||||
function birdo_egg_interaction(o, egg)
|
||||
if egg.oBehParams ~= 0 and obj_has_behavior_id(o, id_bhvMrBlizzard) ~= 0 then
|
||||
o.oFaceAngleRoll = 0x3000
|
||||
o.oMrBlizzardHeldObj = nil
|
||||
o.prevObj = o.oMrBlizzardHeldObj
|
||||
o.oAction = MR_BLIZZARD_ACT_DEATH
|
||||
o.oMrBlizzardDizziness = 0
|
||||
o.oMrBlizzardChangeInDizziness = 0
|
||||
o.oTimer = 30
|
||||
return true
|
||||
end
|
||||
|
||||
if egg.oBehParams ~= 0 and obj_has_behavior_id(o, id_bhvBowser) ~= 0 then
|
||||
if o.oAction ~= 4 and o.oAction ~= 5 and o.oAction ~= 6 and o.oAction ~= 12 and o.oAction ~= 19 and o.oAction ~= 20 and math.abs(o.oVelY) <= 2 then
|
||||
o.oAction = 1
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
if o.oInteractType == INTERACT_BULLY then
|
||||
o.oBullyLastNetworkPlayerIndex = egg.globalPlayerIndex
|
||||
o.oForwardVel = (egg.oBehParams ~= 0 and 50) or 25
|
||||
o.oMoveAngleYaw = egg.oMoveAngleYaw
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
-- prevent player interaction with Birdo's egg if player interaction is not pvp (owner still interacts)
|
||||
---@param m MarioState
|
||||
---@param o Object
|
||||
---@param type integer
|
||||
function player_egg_allow_interact(m, o, type)
|
||||
if obj_has_behavior_id(o, id_bhvBirdoEgg) ~= 0 then
|
||||
local m2 = gMarioStates[network_local_index_from_global(o.globalPlayerIndex)]
|
||||
if m.playerIndex ~= m2.playerIndex and gServerSettings.playerInteractions ~= PLAYER_INTERACTIONS_PVP then
|
||||
return false
|
||||
end
|
||||
end
|
||||
end
|
||||
hook_event(HOOK_ALLOW_INTERACT, player_egg_allow_interact)
|
||||
|
||||
-- returns true if this object can be hit by birdo's fireball
|
||||
function birdo_fire_is_targettable(o, egg)
|
||||
if o.oInteractType == INTERACT_PLAYER then
|
||||
local m = gMarioStates[o.oBehParams - 1]
|
||||
if (not m) or is_player_active(m) == 0 then return false end
|
||||
local gIndex = network_global_index_from_local(m.playerIndex)
|
||||
return (gServerSettings.playerInteractions == PLAYER_INTERACTIONS_PVP) and (egg.globalPlayerIndex ~= gIndex)
|
||||
end
|
||||
|
||||
return (obj_has_behavior_id(o, id_bhvMrBlizzard) ~= 0 or obj_has_behavior_id(o, id_bhvBowser) ~= 0
|
||||
or o.oInteractType == INTERACT_BULLY or o.oInteractType == INTERACT_BREAKABLE or obj_is_attackable(o))
|
||||
end
|
||||
|
||||
hook_mario_action(ACT_BIRDO_HOLD_WALKING, act_birdo_hold_walking)
|
||||
hook_mario_action(ACT_SPIT_EGG, act_spit_egg)
|
||||
hook_mario_action(ACT_SPIT_EGG_AIR, act_spit_egg_air)
|
||||
hook_mario_action(ACT_SPIT_EGG_WALK, act_spit_egg_walk)
|
||||
|
||||
-- Fix object shadows getting messed up. Base coop bug
|
||||
---@param o Object
|
||||
function on_obj_load(o)
|
||||
o.header.gfx.disableAutomaticShadowPos = false
|
||||
o.header.gfx.shadowInvisible = false
|
||||
end
|
||||
hook_event(HOOK_ON_OBJECT_LOAD, on_obj_load)
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
-------------------
|
||||
-- Daisy Moveset --
|
||||
-------------------
|
||||
|
||||
if not charSelect then return end
|
||||
|
||||
local midairJumpActs = {
|
||||
[ACT_JUMP] = true,
|
||||
[ACT_DOUBLE_JUMP] = true,
|
||||
[ACT_TRIPLE_JUMP] = true,
|
||||
[ACT_LONG_JUMP] = true,
|
||||
[ACT_BACKFLIP] = true,
|
||||
[ACT_SIDE_FLIP] = true,
|
||||
[ACT_WALL_KICK_AIR] = true,
|
||||
}
|
||||
|
||||
_G.ACT_MIDAIR_JUMP = allocate_mario_action(ACT_GROUP_AIRBORNE | ACT_FLAG_ALLOW_VERTICAL_WIND_ACTION | ACT_FLAG_MOVING)
|
||||
|
||||
--- @param m MarioState
|
||||
local function act_midair_jump(m)
|
||||
-- apply movement when using action
|
||||
common_air_action_step(m, ACT_JUMP_LAND, CHAR_ANIM_BEND_KNESS_RIDING_SHELL, AIR_STEP_NONE)
|
||||
|
||||
-- setup when action starts (vertical speed and voiceline)
|
||||
if m.actionTimer == 0 then
|
||||
m.vel.y = m.forwardVel * 0.3 + 40
|
||||
m.forwardVel = m.forwardVel * 0.7
|
||||
play_character_sound(m, CHAR_SOUND_HELLO)
|
||||
end
|
||||
|
||||
set_mario_particle_flags(m, PARTICLE_LEAF, 0)
|
||||
|
||||
-- avoid issue with flying and then make the hover end after 2 secs or when stopping holding the button
|
||||
if m.prevAction ~= ACT_TRIPLE_JUMP and (m.flags & MARIO_WING_CAP) ~= 0 then
|
||||
if m.actionTimer >= 10 or (m.controller.buttonDown & A_BUTTON) == 0 then
|
||||
set_mario_action(m, ACT_FREEFALL, 0)
|
||||
end
|
||||
else
|
||||
if m.actionTimer >= 10 or (m.controller.buttonDown & A_BUTTON) == 0 then
|
||||
set_mario_action(m, ACT_FREEFALL, 0)
|
||||
end
|
||||
end
|
||||
|
||||
-- increment the action timer to make the hover stop
|
||||
m.actionTimer = m.actionTimer + 1
|
||||
end
|
||||
|
||||
--- @param m MarioState
|
||||
function daisy_update(m)
|
||||
if (m.input & INPUT_A_PRESSED) ~= 0 and m.vel.y < 10 and m.prevAction ~= ACT_MIDAIR_JUMP and midairJumpActs[m.action] then
|
||||
set_mario_action(m, ACT_MIDAIR_JUMP, 0)
|
||||
end
|
||||
end
|
||||
|
||||
hook_mario_action(ACT_MIDAIR_JUMP, act_midair_jump)
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue