From 40e1fa9e5880f8ac3c760bf41eea5610e14c90eb Mon Sep 17 00:00:00 2001 From: Prince Frizzy Date: Thu, 2 Jun 2022 15:19:54 -0400 Subject: [PATCH] Added a full new custom behavior system (#124) --- data/behavior_data.c | 280 +- data/behavior_table.c | 2 +- data/dynos.c.h | 7 + data/dynos.cpp.h | 61 +- data/dynos_bin_behavior.cpp | 3739 ++++++++++++++++++++++ data/dynos_bin_lvl.cpp | 4 +- data/dynos_bin_pointer.cpp | 33 +- data/dynos_bin_read.cpp | 35 +- data/dynos_bin_utils.cpp | 4 + data/dynos_c.cpp | 18 + data/dynos_file.cpp | 10 + data/dynos_gfx_init.cpp | 6 + data/dynos_main.cpp | 1 + data/dynos_mgr_bhv.cpp | 105 + data/dynos_mgr_builtin.cpp | 779 ++++- data/dynos_mgr_col.cpp | 2 +- data/dynos_mgr_lvl.cpp | 1 + include/behavior_commands.h | 332 ++ include/level_commands.h | 2 +- src/engine/behavior_script.c | 305 +- src/engine/level_script.c | 18 +- src/game/obj_behaviors_2.h | 111 + src/game/spawn_object.c | 3 +- src/pc/lua/smlua_hooks.c | 107 +- src/pc/lua/smlua_hooks.h | 9 +- src/pc/lua/smlua_utils.c | 71 +- src/pc/lua/smlua_utils.h | 7 +- src/pc/lua/utils/smlua_anim_utils.c | 3 + src/pc/lua/utils/smlua_anim_utils.h | 3 + src/pc/lua/utils/smlua_collision_utils.c | 2 + src/pc/lua/utils/smlua_collision_utils.h | 2 + src/pc/mods/mod.c | 32 + src/pc/network/network.c | 2 + src/pc/network/packets/packet_join.c | 1 + 34 files changed, 5734 insertions(+), 363 deletions(-) create mode 100644 data/dynos_bin_behavior.cpp create mode 100644 data/dynos_file.cpp create mode 100644 data/dynos_mgr_bhv.cpp create mode 100644 include/behavior_commands.h diff --git a/data/behavior_data.c b/data/behavior_data.c index cabc2f1c..6b899cb4 100644 --- a/data/behavior_data.c +++ b/data/behavior_data.c @@ -59,285 +59,7 @@ #include "make_const_nonconst.h" #include "behavior_data.h" #include "behavior_table.h" - -#define BC_B(a) _SHIFTL(a, 24, 8) -#define BC_BB(a, b) (_SHIFTL(a, 24, 8) | _SHIFTL(b, 16, 8)) -#define BC_BBBB(a, b, c, d) (_SHIFTL(a, 24, 8) | _SHIFTL(b, 16, 8) | _SHIFTL(c, 8, 8) | _SHIFTL(d, 0, 8)) -#define BC_BBH(a, b, c) (_SHIFTL(a, 24, 8) | _SHIFTL(b, 16, 8) | _SHIFTL(c, 0, 16)) -#define BC_B0H(a, b) (_SHIFTL(a, 24, 8) | _SHIFTL(b, 0, 16)) -#define BC_H(a) _SHIFTL(a, 16, 16) -#define BC_HH(a, b) (_SHIFTL(a, 16, 16) | _SHIFTL(b, 0, 16)) -#define BC_W(a) ((uintptr_t)(u32)(a)) -#define BC_PTR(a) ((uintptr_t)(a)) - - -// Defines the id of the behavior script -#define ID(id) \ - BC_B0H(0x39, id) - -// Defines the start of the behavior script as well as the object list the object belongs to. -// Has some special behavior for certain objects. -#define BEGIN(objList) \ - BC_BB(0x00, objList) - -// Delays the behavior script for a certain number of frames. -#define DELAY(num) \ - BC_B0H(0x01, num) - -// Jumps to a new behavior command and stores the return address in the object's stack. -#define CALL(addr) \ - BC_B(0x02), \ - BC_PTR(addr) - -// Jumps back to the behavior command stored in the object's stack. -#define RETURN() \ - BC_B(0x03) - -// Jumps to a new behavior script without saving anything. -#define GOTO(addr) \ - BC_B(0x04), \ - BC_PTR(addr) - -// Marks the start of a loop that will repeat a certain number of times. -#define BEGIN_REPEAT(count) \ - BC_B0H(0x05, count) - -// Marks the end of a repeating loop. -#define END_REPEAT() \ - BC_B(0x06) - -// Also marks the end of a repeating loop, but continues executing commands following the loop on the same frame. -#define END_REPEAT_CONTINUE() \ - BC_B(0x07) - -// Marks the beginning of an infinite loop. -#define BEGIN_LOOP() \ - BC_B(0x08) - -// Marks the end of an infinite loop. -#define END_LOOP() \ - BC_B(0x09) - -// Exits the behavior script. -// Often used to end behavior scripts that do not contain an infinite loop. -#define BREAK() \ - BC_B(0x0A) - -// Exits the behavior script, unused. -#define BREAK_UNUSED() \ - BC_B(0x0B) - -// Executes a native game function. -#define CALL_NATIVE(func) \ - BC_B(0x0C), \ - BC_PTR(func) - -// Adds a float to the specified field. -#define ADD_FLOAT(field, value) \ - BC_BBH(0x0D, field, value) - -// Sets the specified field to a float. -#define SET_FLOAT(field, value) \ - BC_BBH(0x0E, field, value) - -// Adds an integer to the specified field. -#define ADD_INT(field, value) \ - BC_BBH(0x0F, field, value) - -// Sets the specified field to an integer. -#define SET_INT(field, value) \ - BC_BBH(0x10, field, value) - -// Performs a bitwise OR with the specified field and the given integer. -// Usually used to set an object's flags. -#define OR_INT(field, value) \ - BC_BBH(0x11, field, value) - -// Performs a bit clear with the specified short. Unused in favor of the 32-bit version. -#define BIT_CLEAR(field, value) \ - BC_BBH(0x12, field, value) - -// TODO: this one needs a better name / labelling -// Gets a random short, right shifts it the specified amount and adds min to it, then sets the specified field to that value. -#define SET_INT_RAND_RSHIFT(field, min, rshift) \ - BC_BBH(0x13, field, min), \ - BC_H(rshift) - -// Sets the specified field to a random float in the given range. -#define SET_RANDOM_FLOAT(field, min, range) \ - BC_BBH(0x14, field, min), \ - BC_H(range) - -// Sets the specified field to a random integer in the given range. -#define SET_RANDOM_INT(field, min, range) \ - BC_BBH(0x15, field, min), \ - BC_H(range) - -// Adds a random float in the given range to the specified field. -#define ADD_RANDOM_FLOAT(field, min, range) \ - BC_BBH(0x16, field, min), \ - BC_H(range) - -// TODO: better name (unused anyway) -// Gets a random short, right shifts it the specified amount and adds min to it, then adds the value to the specified field. Unused. -#define ADD_INT_RAND_RSHIFT(field, min, rshift) \ - BC_BBH(0x17, field, min), \ - BC_H(rshift) - -// No operation. Unused. -#define CMD_NOP_1(field) \ - BC_BB(0x18, field) - -// No operation. Unused. -#define CMD_NOP_2(field) \ - BC_BB(0x19, field) - -// No operation. Unused. -#define CMD_NOP_3(field) \ - BC_BB(0x1A, field) - -// Sets the current model ID of the object. -#define SET_MODEL(modelID) \ - BC_B0H(0x1B, modelID) - -// Spawns a child object with the specified model and behavior. -#define SPAWN_CHILD(modelID, behavior) \ - BC_B(0x1C), \ - BC_W(modelID), \ - BC_PTR(behavior) - -// Exits the behavior script and despawns the object. -// Often used to end behavior scripts that do not contain an infinite loop. -#define DEACTIVATE() \ - BC_B(0x1D) - -// Finds the floor triangle directly under the object and moves the object down to it. -#define DROP_TO_FLOOR() \ - BC_B(0x1E) - -// Sets the destination float field to the sum of the values of the given float fields. -#define SUM_FLOAT(fieldDst, fieldSrc1, fieldSrc2) \ - BC_BBBB(0x1F, fieldDst, fieldSrc1, fieldSrc2) - -// Sets the destination integer field to the sum of the values of the given integer fields. Unused. -#define SUM_INT(fieldDst, fieldSrc1, fieldSrc2) \ - BC_BBBB(0x20, fieldDst, fieldSrc1, fieldSrc2) - -// Billboards the current object, making it always face the camera. -#define BILLBOARD() \ - BC_B(0x21) - -#define CYLBOARD() \ - BC_B(0x38) - -// Hides the current object. -#define HIDE() \ - BC_B(0x22) - -// Sets the size of the object's cylindrical hitbox. -#define SET_HITBOX(radius, height) \ - BC_B(0x23), \ - BC_HH(radius, height) - -// No operation. Unused. -#define CMD_NOP_4(field, value) \ - BC_BBH(0x24, field, value) - -// Delays the behavior script for the number of frames given by the value of the specified field. -#define DELAY_VAR(field) \ - BC_BB(0x25, field) - -// Unused. Marks the start of a loop that will repeat a certain number of times. -// Uses a u8 as the argument, instead of a s16 like the other version does. -#define BEGIN_REPEAT_UNUSED(count) \ - BC_BB(0x26, count) - -// Loads the animations for the object. is always set to oAnimations. -#define LOAD_ANIMATIONS(field, anims) \ - BC_BB(0x27, field), \ - BC_PTR(anims) - -// Begins animation and sets the object's current animation index to the specified value. -#define ANIMATE(animIndex) \ - BC_BB(0x28, animIndex) - -// Spawns a child object with the specified model and behavior, plus a behavior param. -#define SPAWN_CHILD_WITH_PARAM(bhvParam, modelID, behavior) \ - BC_B0H(0x29, bhvParam), \ - BC_W(modelID), \ - BC_PTR(behavior) - -// Loads collision data for the object. -#define LOAD_COLLISION_DATA(collisionData) \ - BC_B(0x2A), \ - BC_PTR(collisionData) - -// Sets the size of the object's cylindrical hitbox, and applies a downwards offset. -#define SET_HITBOX_WITH_OFFSET(radius, height, downOffset) \ - BC_B(0x2B), \ - BC_HH(radius, height), \ - BC_H(downOffset) - -// Spawns a new object with the specified model and behavior. -#define SPAWN_OBJ(modelID, behavior) \ - BC_B(0x2C), \ - BC_W(modelID), \ - BC_PTR(behavior) - -// Sets the home position of the object to its current position. -#define SET_HOME() \ - BC_B(0x2D) - -// Sets the size of the object's cylindrical hurtbox. -#define SET_HURTBOX(radius, height) \ - BC_B(0x2E), \ - BC_HH(radius, height) - -// Sets the object's interaction type. -#define SET_INTERACT_TYPE(type) \ - BC_B(0x2F), \ - BC_W(type) - -// Sets various parameters that the object uses for calculating physics. -#define SET_OBJ_PHYSICS(wallHitboxRadius, gravity, bounciness, dragStrength, friction, buoyancy, unused1, unused2) \ - BC_B(0x30), \ - BC_HH(wallHitboxRadius, gravity), \ - BC_HH(bounciness, dragStrength), \ - BC_HH(friction, buoyancy), \ - BC_HH(unused1, unused2) - -// Sets the object's interaction subtype. Unused. -#define SET_INTERACT_SUBTYPE(subtype) \ - BC_B(0x31), \ - BC_W(subtype) - -// Sets the object's size to the specified percentage. -#define SCALE(unusedField, percent) \ - BC_BBH(0x32, unusedField, percent) - -// Performs a bit clear on the object's parent's field with the specified value. -// Used for clearing active particle flags fron Mario's object. -#define PARENT_BIT_CLEAR(field, flags) \ - BC_BB(0x33, field), \ - BC_W(flags) - -// Animates an object using texture animation. is always set to oAnimState. -#define ANIMATE_TEXTURE(field, rate) \ - BC_BBH(0x34, field, rate) - -// Disables rendering for the object. -#define DISABLE_RENDERING() \ - BC_B(0x35) - -// Unused. Sets the specified field to an integer. Wastes 4 bytes of space for no reason at all. -#define SET_INT_UNUSED(field, value) \ - BC_BB(0x36, field), \ - BC_HH(0, value) - -// Spawns a water droplet with the given parameters. -#define SPAWN_WATER_DROPLET(dropletParams) \ - BC_B(0x37), \ - BC_PTR(dropletParams) +#include "behavior_commands.h" const BehaviorScript bhvStarDoor[] = { diff --git a/data/behavior_table.c b/data/behavior_table.c index ff139183..2a034bfd 100644 --- a/data/behavior_table.c +++ b/data/behavior_table.c @@ -563,7 +563,7 @@ enum BehaviorId get_id_from_vanilla_behavior(const BehaviorScript* behavior) { } const BehaviorScript* get_behavior_from_id(enum BehaviorId id) { - const BehaviorScript* behavior = get_lua_behavior_from_id(id, true); + const BehaviorScript* behavior = get_hooked_behavior_from_id(id, true); if (behavior != NULL) { return behavior; } if (id < 0 || id >= id_bhv_max_count) { diff --git a/data/dynos.c.h b/data/dynos.c.h index 491c7c0e..6408fbb9 100644 --- a/data/dynos.c.h +++ b/data/dynos.c.h @@ -4,6 +4,7 @@ #include "dynos.h" #include "types.h" +#include "engine/behavior_script.h" #include "src/game/moving_texture.h" void *dynos_swap_cmd(void *cmd); @@ -54,6 +55,12 @@ const char* dynos_level_get_token(u32 index); Trajectory* dynos_level_get_trajectory(const char* name); void dynos_level_load_background(void *ptr); +// -- behaviors -- // +void dynos_add_behavior(s32 modIndex, const char *filePath, const char *behaviorName); +s32 dynos_behavior_get_active_mod_index(BehaviorScript *bhvScript); +const char *dynos_behavior_get_token(BehaviorScript *bhvScript, u32 index); +void dynos_behavior_hook_all_custom_behaviors(void); + // -- other -- // void dynos_mod_shutdown(void); diff --git a/data/dynos.cpp.h b/data/dynos.cpp.h index 7439dc39..49b49a98 100644 --- a/data/dynos.cpp.h +++ b/data/dynos.cpp.h @@ -3,7 +3,11 @@ #ifdef __cplusplus #include "dynos.h" + +#include + extern "C" { +#include "engine/behavior_script.h" #include "engine/math_util.h" #include "src/game/moving_texture.h" } @@ -42,6 +46,7 @@ enum { DATA_TYPE_AMBIENT_T, DATA_TYPE_TEXTURE_LIST, DATA_TYPE_TEXTURE_RAW, + DATA_TYPE_BEHAVIOR_SCRIPT, DATA_TYPE_UNUSED, }; @@ -190,7 +195,7 @@ private: // A fixed-size string that doesn't require heap memory allocation // -#define STRING_SIZE 127 +#define STRING_SIZE 256 class String { public: inline String() : mCount(0) { @@ -418,6 +423,7 @@ struct GfxData : NoCopy { DataNodes mDisplayLists; DataNodes mGeoLayouts; DataNodes mCollisions; + DataNodes mBehaviorScripts; DataNodes mLevelScripts; DataNodes mMacroObjects; DataNodes mTrajectories; @@ -548,13 +554,6 @@ void Delete(T *& aPtr) { aPtr = NULL; } -template -T *CopyBytes(const T *aPtr, u64 aSize) { - T *_Ptr = (T *) calloc(1, aSize); - memcpy(_Ptr, aPtr, aSize); - return _Ptr; -} - template Array Split(const char *aBuffer, const String &aDelimiters, const String &aEndCharacters = {}, bool aHandleDoubleQuotedStrings = false) { Array _Tokens; @@ -585,18 +584,35 @@ Array Split(const char *aBuffer, const String &aDelimiters, const String return _Tokens; } +template +T *CopyBytes(const T *aPtr, u64 aSize) { + T *_Ptr = (T *) calloc(1, aSize); + memcpy(_Ptr, aPtr, aSize); + return _Ptr; +} + template T ReadBytes(FILE* aFile) { T _Item = { 0 }; - fread(&_Item, sizeof(T), 1, aFile); + + // If we're at end of file. Just return the default. + if (feof(aFile)) { return _Item; } + + size_t nread = fread(&_Item, sizeof(T), 1, aFile); + // If we failed to read bytes. Print the error. + //if (nread != sizeof(T)) { perror("The following error occured when reading bytes"); } return _Item; } template void WriteBytes(FILE* aFile, const T& aItem) { - fwrite(&aItem, sizeof(T), 1, aFile); + size_t nwrote = fwrite(&aItem, sizeof(T), 1, aFile); + // If we failed to write bytes. Print the error. + //if (nwrote != sizeof(T)) { perror("The following error occured when writing bytes"); } } +void SkipBytes(FILE *aFile, size_t amount); + template void PrintNoNewLine(const char *aFmt, Args... aArgs) { printf(aFmt, aArgs...); @@ -734,14 +750,17 @@ const char* DynOS_Builtin_Actor_GetNameFromIndex(s32 aIndex); s32 DynOS_Builtin_Actor_GetCount(); const GeoLayout* DynOS_Builtin_LvlGeo_GetFromName(const char* aDataName); const char* DynOS_Builtin_LvlGeo_GetFromData(const GeoLayout* aData); -const Collision* DynOS_Builtin_LvlCol_GetFromName(const char* aDataName); -const char* DynOS_Builtin_LvlCol_GetFromData(const Collision* aData); +const Collision* DynOS_Builtin_Col_GetFromName(const char* aDataName); +const char* DynOS_Builtin_Col_GetFromData(const Collision* aData); +const Animation *DynOS_Builtin_Anim_GetFromName(const char *aDataName); +const char * DynOS_Builtin_Anim_GetFromData(const Animation *aData); const Texture* DynOS_Builtin_Tex_GetFromName(const char* aDataName); const char* DynOS_Builtin_Tex_GetFromData(const Texture* aData); const char* DynOS_Builtin_Tex_GetNameFromFileName(const char* aDataName); const struct BuiltinTexInfo* DynOS_Builtin_Tex_GetInfoFromName(const char* aDataName); const void* DynOS_Builtin_Func_GetFromName(const char* aDataName); const void* DynOS_Builtin_Func_GetFromIndex(s32 aIndex); +const char * DynOS_Builtin_Func_GetNameFromIndex(s64 aIndex); s32 DynOS_Builtin_Func_GetIndexFromData(const void* aData); // @@ -807,6 +826,18 @@ void DynOS_Lvl_LoadBackground(void *aPtr); void* DynOS_Lvl_Override(void *aCmd); void DynOS_Lvl_ModShutdown(); +// +// Bhv Manager +// + +Array> &DynOS_Bhv_GetArray(); +void DynOS_Bhv_Activate(s32 modIndex, const SysPath &aFilename, const char *aBehaviorName); +GfxData *DynOS_Bhv_GetActiveGfx(BehaviorScript *bhvScript); +s32 DynOS_Bhv_GetActiveModIndex(BehaviorScript *bhvScript); +const char *DynOS_Bhv_GetToken(BehaviorScript *bhvScript, u32 index); +void DynOS_Bhv_HookAllCustomBehaviors(); +void DynOS_Bhv_ModShutdown(); + // // Col Manager // @@ -921,5 +952,11 @@ GfxData *DynOS_Lvl_LoadFromBinary(const SysPath &aFilename, const char *aLevelNa void DynOS_Lvl_GeneratePack(const SysPath &aPackFolder); s64 DynOS_Lvl_ParseLevelScriptConstants(const String& _Arg, bool* found); +DataNode *DynOS_Bhv_Parse(GfxData *aGfxData, DataNode *aNode, bool aDisplayPercent); +GfxData *DynOS_Bhv_LoadFromBinary(const SysPath &aFilename, const char *aBehaviorName); +void DynOS_Bhv_GeneratePack(const SysPath &aPackFolder); +s64 DynOS_Bhv_ParseBehaviorScriptConstants(const String &_Arg, bool *found); +s64 DynOS_Bhv_ParseBehaviorIntegerScriptConstants(const String &_Arg, bool *found); + #endif #endif diff --git a/data/dynos_bin_behavior.cpp b/data/dynos_bin_behavior.cpp new file mode 100644 index 00000000..b10e0fe1 --- /dev/null +++ b/data/dynos_bin_behavior.cpp @@ -0,0 +1,3739 @@ +#include "dynos.cpp.h" + +#define OBJECT_FIELDS_INDEX_DIRECTLY + +extern "C" { +#include "include/behavior_commands.h" +#include "include/behavior_data.h" +#include "include/behavior_table.h" +#include "include/model_ids.h" +#include "include/object_constants.h" +#include "include/object_fields.h" +#include "src/game/area.h" +#include "src/game/object_list_processor.h" +#include "src/game/interaction.h" +#include "src/pc/lua/utils/smlua_anim_utils.h" +#include "src/pc/lua/utils/smlua_collision_utils.h" + +// Models and Animations +#include "actors/common0.h" +#include "actors/common1.h" +#include "actors/custom0.h" +#include "actors/group0.h" +#include "actors/group1.h" +#include "actors/group2.h" +#include "actors/group3.h" +#include "actors/group4.h" +#include "actors/group5.h" +#include "actors/group6.h" +#include "actors/group7.h" +#include "actors/group8.h" +#include "actors/group9.h" +#include "actors/group10.h" +#include "actors/group11.h" +#include "actors/group12.h" +#include "actors/group13.h" +#include "actors/group14.h" +#include "actors/group15.h" +#include "actors/group16.h" +#include "actors/group17.h" +#include "actors/zcustom0.h" +#include "levels/castle_grounds/header.h" +} + +// Current Behavior Version +#define BEHAVIOR_MAJOR_VER 1 +#define BEHAVIOR_MINOR_VER 0 +#define BEHAVIOR_PATCH_VER 0 + +// Minimum Behavior Version (That can be read) +#define BEHAVIOR_MIN_MAJOR_VER 1 +#define BEHAVIOR_MIN_MINOR_VER 0 +#define BEHAVIOR_MIN_PATCH_VER 0 + +#undef OBJECT_FIELDS_INDEX_DIRECTLY + +// Free data pointers, but keep nodes and tokens intact +// Delete nodes generated from GfxDynCmds +template +void ClearBhvDataNodes(DataNodes &aDataNodes) { + for (s32 i = aDataNodes.Count(); i != 0; --i) { + Delete(aDataNodes[i - 1]->mData); + } +} + + ///////////// + // Parsing // +///////////// + +#define BEHAVIOR_SCRIPT_SIZE_PER_TOKEN 4 + +#define bhv_constant(x) if (_Arg == #x) { return (BehaviorScript) (x); } +#define bhv_legacy_constant(x, y) if (_Arg == #x) { return (BehaviorScript) (y); } + +s64 DynOS_Bhv_ParseBehaviorIntegerScriptConstants(const String &_Arg, bool *found) { + *found = true; + + // All of these eveluate down into a integer which can be worked with. + // Be it for flags or otherwise. + + // Active Flags + bhv_constant(ACTIVE_FLAG_DEACTIVATED); + bhv_constant(ACTIVE_FLAG_ACTIVE); + bhv_constant(ACTIVE_FLAG_FAR_AWAY); + bhv_constant(ACTIVE_FLAG_UNK2); + bhv_constant(ACTIVE_FLAG_IN_DIFFERENT_ROOM); + bhv_constant(ACTIVE_FLAG_UNIMPORTANT); + bhv_constant(ACTIVE_FLAG_INITIATED_TIME_STOP); + bhv_constant(ACTIVE_FLAG_MOVE_THROUGH_GRATE); + bhv_constant(ACTIVE_FLAG_DITHERED_ALPHA); + bhv_constant(ACTIVE_FLAG_UNK8); + bhv_constant(ACTIVE_FLAG_UNK9); + bhv_constant(ACTIVE_FLAG_UNK10); + + + // Interact Flags + bhv_constant(INTERACT_HOOT); + bhv_constant(INTERACT_GRABBABLE); + bhv_constant(INTERACT_DOOR); + bhv_constant(INTERACT_DAMAGE); + bhv_constant(INTERACT_COIN); + bhv_constant(INTERACT_CAP); + bhv_constant(INTERACT_POLE); + bhv_constant(INTERACT_KOOPA); + bhv_constant(INTERACT_UNKNOWN_08); + bhv_constant(INTERACT_BREAKABLE); + bhv_constant(INTERACT_STRONG_WIND); + bhv_constant(INTERACT_WARP_DOOR); + bhv_constant(INTERACT_STAR_OR_KEY); + bhv_constant(INTERACT_WARP); + bhv_constant(INTERACT_CANNON_BASE); + bhv_constant(INTERACT_BOUNCE_TOP); + bhv_constant(INTERACT_WATER_RING); + bhv_constant(INTERACT_BULLY); + bhv_constant(INTERACT_FLAME); + bhv_constant(INTERACT_KOOPA_SHELL); + bhv_constant(INTERACT_BOUNCE_TOP2); + bhv_constant(INTERACT_MR_BLIZZARD); + bhv_constant(INTERACT_HIT_FROM_BELOW); + bhv_constant(INTERACT_TEXT); + bhv_constant(INTERACT_TORNADO); + bhv_constant(INTERACT_WHIRLPOOL); + bhv_constant(INTERACT_CLAM_OR_BUBBA); + bhv_constant(INTERACT_BBH_ENTRANCE); + bhv_constant(INTERACT_SNUFIT_BULLET); + bhv_constant(INTERACT_SHOCK); + bhv_constant(INTERACT_IGLOO_BARRIER); + bhv_constant(INTERACT_PLAYER); + + + // Interact Subtype Flags + + // INTERACT_WARP + bhv_constant(INT_SUBTYPE_FADING_WARP); + + // Damaging interactions + bhv_constant(INT_SUBTYPE_DELAY_INVINCIBILITY); + bhv_constant(INT_SUBTYPE_BIG_KNOCKBACK); /* Used by Bowser, sets Mario's forward velocity to 40 on hit */ + + // INTERACT_GRABBABLE + bhv_constant(INT_SUBTYPE_GRABS_MARIO); /* Also makes the object heavy */ + bhv_constant(INT_SUBTYPE_HOLDABLE_NPC); /* Allows the object to be gently dropped, and sets vertical speed to 0 when dropped with no forwards velocity */ + bhv_constant(INT_SUBTYPE_DROP_IMMEDIATELY); /* This gets set by grabbable NPCs that talk to Mario to make him drop them after the dialog is finished */ + bhv_constant(INT_SUBTYPE_KICKABLE); + bhv_constant(INT_SUBTYPE_NOT_GRABBABLE); /* Used by Heavy-Ho to allow it to throw Mario, without Mario being able to pick it up */ + + // INTERACT_DOOR + bhv_constant(INT_SUBTYPE_STAR_DOOR); + + //INTERACT_BOUNCE_TOP + bhv_constant(INT_SUBTYPE_TWIRL_BOUNCE); + + // INTERACT_STAR_OR_KEY + bhv_constant(INT_SUBTYPE_NO_EXIT); + bhv_constant(INT_SUBTYPE_GRAND_STAR); + + // INTERACT_TEXT + bhv_constant(INT_SUBTYPE_SIGN); + bhv_constant(INT_SUBTYPE_NPC); + + // INTERACT_CLAM_OR_BUBBA + bhv_constant(INT_SUBTYPE_EATS_MARIO); + + + // Object List Types + bhv_constant(OBJ_LIST_PLAYER); + bhv_constant(OBJ_LIST_UNUSED_1); + bhv_constant(OBJ_LIST_DESTRUCTIVE); + bhv_constant(OBJ_LIST_UNUSED_3); + bhv_constant(OBJ_LIST_GENACTOR); + bhv_constant(OBJ_LIST_PUSHABLE); + bhv_constant(OBJ_LIST_LEVEL); + bhv_constant(OBJ_LIST_UNUSED_7); + bhv_constant(OBJ_LIST_DEFAULT); + bhv_constant(OBJ_LIST_SURFACE); + bhv_constant(OBJ_LIST_POLELIKE); + bhv_constant(OBJ_LIST_SPAWNER); + bhv_constant(OBJ_LIST_UNIMPORTANT); + + + // Object Flags + bhv_constant(OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE); + bhv_constant(OBJ_FLAG_MOVE_XZ_USING_FVEL); + bhv_constant(OBJ_FLAG_MOVE_Y_WITH_TERMINAL_VEL); + bhv_constant(OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW); + bhv_constant(OBJ_FLAG_SET_FACE_ANGLE_TO_MOVE_ANGLE); + bhv_constant(OBJ_FLAG_0020); + bhv_constant(OBJ_FLAG_COMPUTE_DIST_TO_MARIO); + bhv_constant(OBJ_FLAG_ACTIVE_FROM_AFAR); + bhv_constant(OBJ_FLAG_0100); + bhv_constant(OBJ_FLAG_TRANSFORM_RELATIVE_TO_PARENT); + bhv_constant(OBJ_FLAG_HOLDABLE); + bhv_constant(OBJ_FLAG_SET_THROW_MATRIX_FROM_TRANSFORM); + bhv_constant(OBJ_FLAG_1000); + bhv_constant(OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO); + bhv_constant(OBJ_FLAG_PERSISTENT_RESPAWN); + bhv_constant(OBJ_FLAG_8000); + bhv_constant(OBJ_FLAG_30); + + + // Particle Flags + bhv_constant(ACTIVE_PARTICLE_DUST); + bhv_constant(ACTIVE_PARTICLE_UNUSED_1); + bhv_constant(ACTIVE_PARTICLE_UNUSED_2); + bhv_constant(ACTIVE_PARTICLE_SPARKLES); + bhv_constant(ACTIVE_PARTICLE_H_STAR); + bhv_constant(ACTIVE_PARTICLE_BUBBLE); + bhv_constant(ACTIVE_PARTICLE_WATER_SPLASH); + bhv_constant(ACTIVE_PARTICLE_IDLE_WATER_WAVE); + bhv_constant(ACTIVE_PARTICLE_SHALLOW_WATER_WAVE); + bhv_constant(ACTIVE_PARTICLE_PLUNGE_BUBBLE); + bhv_constant(ACTIVE_PARTICLE_WAVE_TRAIL); + bhv_constant(ACTIVE_PARTICLE_FIRE); + bhv_constant(ACTIVE_PARTICLE_SHALLOW_WATER_SPLASH); + bhv_constant(ACTIVE_PARTICLE_LEAF); + bhv_constant(ACTIVE_PARTICLE_DIRT); + bhv_constant(ACTIVE_PARTICLE_MIST_CIRCLE); + bhv_constant(ACTIVE_PARTICLE_SNOW); + bhv_constant(ACTIVE_PARTICLE_BREATH); + bhv_constant(ACTIVE_PARTICLE_V_STAR); + bhv_constant(ACTIVE_PARTICLE_TRIANGLE); + + // Other constants + bhv_constant(NULL); + bhv_constant(FALSE); + + *found = false; + return 0; +} + +s64 DynOS_Bhv_ParseBehaviorScriptConstants(const String &_Arg, bool *found) { + *found = true; + + // Behavior names + bhv_constant(bhvStarDoor); + bhv_constant(bhvMrI); + bhv_constant(bhvMrIBody); + bhv_constant(bhvMrIParticle); + bhv_constant(bhvPurpleParticle); + bhv_constant(bhvGiantPole); + bhv_constant(bhvPoleGrabbing); + bhv_constant(bhvThiHugeIslandTop); + bhv_constant(bhvThiTinyIslandTop); + bhv_constant(bhvCapSwitchBase); + bhv_constant(bhvCapSwitch); + bhv_constant(bhvKingBobomb); + bhv_constant(bhvBobombAnchorMario); + bhv_constant(bhvBetaChestBottom); + bhv_constant(bhvBetaChestLid); + bhv_constant(bhvBubbleParticleSpawner); + bhv_constant(bhvBubbleMaybe); + bhv_constant(bhvBubblePlayer); + bhv_constant(bhvSmallWaterWave); + bhv_constant(bhvSmallWaterWave398); + bhv_constant(bhvWaterAirBubble); + bhv_constant(bhvSmallParticle); + bhv_constant(bhvPlungeBubble); + bhv_constant(bhvSmallParticleSnow); + bhv_constant(bhvSmallParticleBubbles); + bhv_constant(bhvFishGroup); + bhv_constant(bhvCannon); + bhv_constant(bhvCannonBarrel); + bhv_constant(bhvCannonBaseUnused); + bhv_constant(bhvChuckya); + bhv_constant(bhvChuckyaAnchorMario); + bhv_constant(bhvUnused05A8); + bhv_constant(bhvRotatingPlatform); + bhv_constant(bhvTower); + bhv_constant(bhvBulletBillCannon); + bhv_constant(bhvWfBreakableWallRight); + bhv_constant(bhvWfBreakableWallLeft); + bhv_constant(bhvKickableBoard); + bhv_constant(bhvTowerDoor); + bhv_constant(bhvRotatingCounterClockwise); + bhv_constant(bhvWfRotatingWoodenPlatform); + bhv_constant(bhvKoopaShellUnderwater); + bhv_constant(bhvExitPodiumWarp); + bhv_constant(bhvFadingWarp); + bhv_constant(bhvWarp); + bhv_constant(bhvWarpPipe); + bhv_constant(bhvWhitePuffExplosion); + bhv_constant(bhvSpawnedStar); + bhv_constant(bhvSpawnedStarNoLevelExit); + bhv_constant(bhvMrIBlueCoin); + bhv_constant(bhvCoinInsideBoo); + bhv_constant(bhvCoinFormationSpawn); + bhv_constant(bhvCoinFormation); + bhv_constant(bhvOneCoin); + bhv_constant(bhvYellowCoin); + bhv_constant(bhvTemporaryYellowCoin); + bhv_constant(bhvThreeCoinsSpawn); + bhv_constant(bhvTenCoinsSpawn); + bhv_constant(bhvSingleCoinGetsSpawned); + bhv_constant(bhvCoinSparkles); + bhv_constant(bhvGoldenCoinSparkles); + bhv_constant(bhvWallTinyStarParticle); + bhv_constant(bhvVertStarParticleSpawner); + bhv_constant(bhvPoundTinyStarParticle); + bhv_constant(bhvHorStarParticleSpawner); + bhv_constant(bhvPunchTinyTriangle); + bhv_constant(bhvTriangleParticleSpawner); + bhv_constant(bhvDoorWarp); + bhv_constant(bhvDoor); + bhv_constant(bhvGrindel); + bhv_constant(bhvThwomp2); + bhv_constant(bhvThwomp); + bhv_constant(bhvTumblingBridgePlatform); + bhv_constant(bhvWfTumblingBridge); + bhv_constant(bhvBbhTumblingBridge); + bhv_constant(bhvLllTumblingBridge); + bhv_constant(bhvFlame); + bhv_constant(bhvAnotherElavator); + bhv_constant(bhvRrElevatorPlatform); + bhv_constant(bhvHmcElevatorPlatform); + bhv_constant(bhvWaterMist); + bhv_constant(bhvBreathParticleSpawner); + bhv_constant(bhvBreakBoxTriangle); + bhv_constant(bhvWaterMist2); + bhv_constant(bhvUnused0DFC); + bhv_constant(bhvMistCircParticleSpawner); + bhv_constant(bhvDirtParticleSpawner); + bhv_constant(bhvSnowParticleSpawner); + bhv_constant(bhvWind); + bhv_constant(bhvEndToad); + bhv_constant(bhvEndPeach); + bhv_constant(bhvUnusedParticleSpawn); + bhv_constant(bhvUkiki); + bhv_constant(bhvUkikiCageChild); + bhv_constant(bhvUkikiCageStar); + bhv_constant(bhvUkikiCage); + bhv_constant(bhvBitfsSinkingPlatforms); + bhv_constant(bhvBitfsSinkingCagePlatform); + bhv_constant(bhvDddMovingPole); + bhv_constant(bhvBitfsTiltingInvertedPyramid); + bhv_constant(bhvSquishablePlatform); + bhv_constant(bhvCutOutObject); + bhv_constant(bhvBetaMovingFlamesSpawn); + bhv_constant(bhvBetaMovingFlames); + bhv_constant(bhvRrRotatingBridgePlatform); + bhv_constant(bhvFlamethrower); + bhv_constant(bhvFlamethrowerFlame); + bhv_constant(bhvBouncingFireball); + bhv_constant(bhvBouncingFireballFlame); + bhv_constant(bhvBowserShockWave); + bhv_constant(bhvFireParticleSpawner); + bhv_constant(bhvBlackSmokeMario); + bhv_constant(bhvBlackSmokeBowser); + bhv_constant(bhvBlackSmokeUpward); + bhv_constant(bhvBetaFishSplashSpawner); + bhv_constant(bhvSpindrift); + bhv_constant(bhvTowerPlatformGroup); + bhv_constant(bhvWfSlidingTowerPlatform); + bhv_constant(bhvWfElevatorTowerPlatform); + bhv_constant(bhvWfSolidTowerPlatform); + bhv_constant(bhvLeafParticleSpawner); + bhv_constant(bhvTreeSnow); + bhv_constant(bhvTreeLeaf); + bhv_constant(bhvAnotherTiltingPlatform); + bhv_constant(bhvSquarishPathMoving); + bhv_constant(bhvSquarishPathParent); + bhv_constant(bhvPiranhaPlantBubble); + bhv_constant(bhvPiranhaPlantWakingBubbles); + bhv_constant(bhvFloorSwitchAnimatesObject); + bhv_constant(bhvFloorSwitchGrills); + bhv_constant(bhvFloorSwitchHardcodedModel); + bhv_constant(bhvFloorSwitchHiddenObjects); + bhv_constant(bhvHiddenObject); + bhv_constant(bhvBreakableBox); + bhv_constant(bhvPushableMetalBox); + bhv_constant(bhvHeaveHo); + bhv_constant(bhvHeaveHoThrowMario); + bhv_constant(bhvCcmTouchedStarSpawn); + bhv_constant(bhvUnusedPoundablePlatform); + bhv_constant(bhvBetaTrampolineTop); + bhv_constant(bhvBetaTrampolineSpring); + bhv_constant(bhvJumpingBox); + bhv_constant(bhvBooCage); + bhv_constant(bhvStub); + bhv_constant(bhvIgloo); + bhv_constant(bhvBowserKey); + bhv_constant(bhvGrandStar); + bhv_constant(bhvBetaBooKey); + bhv_constant(bhvAlphaBooKey); + bhv_constant(bhvBulletBill); + bhv_constant(bhvWhitePuffSmoke); + bhv_constant(bhvUnused1820); + bhv_constant(bhvBowserTailAnchor); + bhv_constant(bhvBowser); + bhv_constant(bhvBowserBodyAnchor); + bhv_constant(bhvBowserFlameSpawn); + bhv_constant(bhvTiltingBowserLavaPlatform); + bhv_constant(bhvFallingBowserPlatform); + bhv_constant(bhvBlueBowserFlame); + bhv_constant(bhvFlameFloatingLanding); + bhv_constant(bhvBlueFlamesGroup); + bhv_constant(bhvFlameBouncing); + bhv_constant(bhvFlameMovingForwardGrowing); + bhv_constant(bhvFlameBowser); + bhv_constant(bhvFlameLargeBurningOut); + bhv_constant(bhvBlueFish); + bhv_constant(bhvTankFishGroup); + bhv_constant(bhvCheckerboardElevatorGroup); + bhv_constant(bhvCheckerboardPlatformSub); + bhv_constant(bhvBowserKeyUnlockDoor); + bhv_constant(bhvBowserKeyCourseExit); + bhv_constant(bhvInvisibleObjectsUnderBridge); + bhv_constant(bhvWaterLevelPillar); + bhv_constant(bhvDddWarp); + bhv_constant(bhvMoatGrills); + bhv_constant(bhvClockMinuteHand); + bhv_constant(bhvClockHourHand); + bhv_constant(bhvMacroUkiki); + bhv_constant(bhvStub1D0C); + bhv_constant(bhvLllRotatingHexagonalPlatform); + bhv_constant(bhvLllSinkingRockBlock); + bhv_constant(bhvStub1D70); + bhv_constant(bhvLllMovingOctagonalMeshPlatform); + bhv_constant(bhvSnowBall); + bhv_constant(bhvLllRotatingBlockWithFireBars); + bhv_constant(bhvLllRotatingHexFlame); + bhv_constant(bhvLllWoodPiece); + bhv_constant(bhvLllFloatingWoodBridge); + bhv_constant(bhvVolcanoFlames); + bhv_constant(bhvLllRotatingHexagonalRing); + bhv_constant(bhvLllSinkingRectangularPlatform); + bhv_constant(bhvLllSinkingSquarePlatforms); + bhv_constant(bhvLllTiltingInvertedPyramid); + bhv_constant(bhvUnused1F30); + bhv_constant(bhvKoopaShell); + bhv_constant(bhvKoopaShellFlame); + bhv_constant(bhvToxBox); + bhv_constant(bhvPiranhaPlant); + bhv_constant(bhvLllHexagonalMesh); + bhv_constant(bhvLllBowserPuzzlePiece); + bhv_constant(bhvLllBowserPuzzle); + bhv_constant(bhvTuxiesMother); + bhv_constant(bhvPenguinBaby); + bhv_constant(bhvUnused20E0); + bhv_constant(bhvSmallPenguin); + bhv_constant(bhvManyBlueFishSpawner); + bhv_constant(bhvFewBlueFishSpawner); + bhv_constant(bhvFishSpawner); + bhv_constant(bhvFish); + bhv_constant(bhvWdwExpressElevator); + bhv_constant(bhvWdwExpressElevatorPlatform); + bhv_constant(bhvChirpChirp); + bhv_constant(bhvChirpChirpUnused); + bhv_constant(bhvBub); + bhv_constant(bhvExclamationBox); + bhv_constant(bhvRotatingExclamationMark); + bhv_constant(bhvSoundSpawner); + bhv_constant(bhvRockSolid); + bhv_constant(bhvBowserSubDoor); + bhv_constant(bhvBowsersSub); + bhv_constant(bhvSushiShark); + bhv_constant(bhvSushiSharkCollisionChild); + bhv_constant(bhvJrbSlidingBox); + bhv_constant(bhvShipPart3); + bhv_constant(bhvInSunkenShip3); + bhv_constant(bhvSunkenShipPart); + bhv_constant(bhvSunkenShipSetRotation); + bhv_constant(bhvSunkenShipPart2); + bhv_constant(bhvInSunkenShip); + bhv_constant(bhvInSunkenShip2); + bhv_constant(bhvMistParticleSpawner); + bhv_constant(bhvWhitePuff1); + bhv_constant(bhvWhitePuff2); + bhv_constant(bhvWhitePuffSmoke2); + bhv_constant(bhvPurpleSwitchHiddenBoxes); + bhv_constant(bhvBlueCoinSwitch); + bhv_constant(bhvHiddenBlueCoin); + bhv_constant(bhvOpenableCageDoor); + bhv_constant(bhvOpenableGrill); + bhv_constant(bhvWaterLevelDiamond); + bhv_constant(bhvInitializeChangingWaterLevel); + bhv_constant(bhvTweesterSandParticle); + bhv_constant(bhvTweester); + bhv_constant(bhvMerryGoRoundBooManager); + bhv_constant(bhvPlaysMusicTrackWhenTouched); + bhv_constant(bhvAnimatedTexture); + bhv_constant(bhvBooInCastle); + bhv_constant(bhvBooWithCage); + bhv_constant(bhvBalconyBigBoo); + bhv_constant(bhvMerryGoRoundBigBoo); + bhv_constant(bhvGhostHuntBigBoo); + bhv_constant(bhvCourtyardBooTriplet); + bhv_constant(bhvBoo); + bhv_constant(bhvMerryGoRoundBoo); + bhv_constant(bhvGhostHuntBoo); + bhv_constant(bhvHiddenStaircaseStep); + bhv_constant(bhvBooBossSpawnedBridge); + bhv_constant(bhvBbhTiltingTrapPlatform); + bhv_constant(bhvHauntedBookshelf); + bhv_constant(bhvMeshElevator); + bhv_constant(bhvMerryGoRound); + bhv_constant(bhvInsideCannon); + bhv_constant(bhvBetaBowserAnchor); + bhv_constant(bhvStaticCheckeredPlatform); + bhv_constant(bhvUnused2A10); + bhv_constant(bhvStar); + bhv_constant(bhvStaticObject); + bhv_constant(bhvUnused2A54); + bhv_constant(bhvCastleFloorTrap); + bhv_constant(bhvFloorTrapInCastle); + bhv_constant(bhvTree); + bhv_constant(bhvSparkle); + bhv_constant(bhvSparkleSpawn); + bhv_constant(bhvSparkleParticleSpawner); + bhv_constant(bhvScuttlebug); + bhv_constant(bhvScuttlebugSpawn); + bhv_constant(bhvWhompKingBoss); + bhv_constant(bhvSmallWhomp); + bhv_constant(bhvWaterSplash); + bhv_constant(bhvWaterDroplet); + bhv_constant(bhvWaterDropletSplash); + bhv_constant(bhvBubbleSplash); + bhv_constant(bhvIdleWaterWave); + bhv_constant(bhvObjectWaterSplash); + bhv_constant(bhvShallowWaterWave); + bhv_constant(bhvShallowWaterSplash); + bhv_constant(bhvObjectWaveTrail); + bhv_constant(bhvWaveTrail); + bhv_constant(bhvTinyStrongWindParticle); + bhv_constant(bhvStrongWindParticle); + bhv_constant(bhvSLSnowmanWind); + bhv_constant(bhvSLWalkingPenguin); + bhv_constant(bhvYellowBall); + bhv_constant(bhvMario); + bhv_constant(bhvToadMessage); + bhv_constant(bhvUnlockDoorStar); + bhv_constant(bhvInstantActiveWarp); + bhv_constant(bhvAirborneWarp); + bhv_constant(bhvHardAirKnockBackWarp); + bhv_constant(bhvSpinAirborneCircleWarp); + bhv_constant(bhvDeathWarp); + bhv_constant(bhvSpinAirborneWarp); + bhv_constant(bhvFlyingWarp); + bhv_constant(bhvPaintingStarCollectWarp); + bhv_constant(bhvPaintingDeathWarp); + bhv_constant(bhvAirborneDeathWarp); + bhv_constant(bhvAirborneStarCollectWarp); + bhv_constant(bhvLaunchStarCollectWarp); + bhv_constant(bhvLaunchDeathWarp); + bhv_constant(bhvSwimmingWarp); + bhv_constant(bhvRandomAnimatedTexture); + bhv_constant(bhvYellowBackgroundInMenu); + bhv_constant(bhvMenuButton); + bhv_constant(bhvMenuButtonManager); + bhv_constant(bhvActSelectorStarType); + bhv_constant(bhvActSelector); + bhv_constant(bhvMovingYellowCoin); + bhv_constant(bhvMovingBlueCoin); + bhv_constant(bhvBlueCoinSliding); + bhv_constant(bhvBlueCoinJumping); + bhv_constant(bhvSeaweed); + bhv_constant(bhvSeaweedBundle); + bhv_constant(bhvBobomb); + bhv_constant(bhvBobombFuseSmoke); + bhv_constant(bhvBobombBuddy); + bhv_constant(bhvBobombBuddyOpensCannon); + bhv_constant(bhvCannonClosed); + bhv_constant(bhvWhirlpool); + bhv_constant(bhvJetStream); + bhv_constant(bhvMessagePanel); + bhv_constant(bhvSignOnWall); + bhv_constant(bhvHomingAmp); + bhv_constant(bhvCirclingAmp); + bhv_constant(bhvButterfly); + bhv_constant(bhvHoot); + bhv_constant(bhvBetaHoldableObject); + bhv_constant(bhvCarrySomething1); + bhv_constant(bhvCarrySomething2); + bhv_constant(bhvCarrySomething3); + bhv_constant(bhvCarrySomething4); + bhv_constant(bhvCarrySomething5); + bhv_constant(bhvCarrySomething6); + bhv_constant(bhvObjectBubble); + bhv_constant(bhvObjectWaterWave); + bhv_constant(bhvExplosion); + bhv_constant(bhvBobombBullyDeathSmoke); + bhv_constant(bhvSmoke); + bhv_constant(bhvBobombExplosionBubble); + bhv_constant(bhvBobombExplosionBubble3600); + bhv_constant(bhvRespawner); + bhv_constant(bhvSmallBully); + bhv_constant(bhvBigBully); + bhv_constant(bhvBigBullyWithMinions); + bhv_constant(bhvSmallChillBully); + bhv_constant(bhvBigChillBully); + bhv_constant(bhvJetStreamRingSpawner); + bhv_constant(bhvJetStreamWaterRing); + bhv_constant(bhvMantaRayWaterRing); + bhv_constant(bhvMantaRayRingManager); + bhv_constant(bhvBowserBomb); + bhv_constant(bhvBowserBombExplosion); + bhv_constant(bhvBowserBombSmoke); + bhv_constant(bhvCelebrationStar); + bhv_constant(bhvCelebrationStarSparkle); + bhv_constant(bhvStarKeyCollectionPuffSpawner); + bhv_constant(bhvLllDrawbridgeSpawner); + bhv_constant(bhvLllDrawbridge); + bhv_constant(bhvSmallBomp); + bhv_constant(bhvLargeBomp); + bhv_constant(bhvWfSlidingPlatform); + bhv_constant(bhvMoneybag); + bhv_constant(bhvMoneybagHidden); + bhv_constant(bhvPitBowlingBall); + bhv_constant(bhvFreeBowlingBall); + bhv_constant(bhvBowlingBall); + bhv_constant(bhvTtmBowlingBallSpawner); + bhv_constant(bhvBobBowlingBallSpawner); + bhv_constant(bhvThiBowlingBallSpawner); + bhv_constant(bhvRrCruiserWing); + bhv_constant(bhvSpindel); + bhv_constant(bhvSslMovingPyramidWall); + bhv_constant(bhvPyramidElevator); + bhv_constant(bhvPyramidElevatorTrajectoryMarkerBall); + bhv_constant(bhvPyramidTop); + bhv_constant(bhvPyramidTopFragment); + bhv_constant(bhvPyramidPillarTouchDetector); + bhv_constant(bhvWaterfallSoundLoop); + bhv_constant(bhvVolcanoSoundLoop); + bhv_constant(bhvCastleFlagWaving); + bhv_constant(bhvBirdsSoundLoop); + bhv_constant(bhvAmbientSounds); + bhv_constant(bhvSandSoundLoop); + bhv_constant(bhvHiddenAt120Stars); + bhv_constant(bhvSnowmansBottom); + bhv_constant(bhvSnowmansHead); + bhv_constant(bhvSnowmansBodyCheckpoint); + bhv_constant(bhvBigSnowmanWhole); + bhv_constant(bhvBigBoulder); + bhv_constant(bhvBigBoulderGenerator); + bhv_constant(bhvWingCap); + bhv_constant(bhvMetalCap); + bhv_constant(bhvNormalCap); + bhv_constant(bhvVanishCap); + bhv_constant(bhvStar); + bhv_constant(bhvStarSpawnCoordinates); + bhv_constant(bhvHiddenRedCoinStar); + bhv_constant(bhvRedCoin); + bhv_constant(bhvBowserCourseRedCoinStar); + bhv_constant(bhvHiddenStar); + bhv_constant(bhvHiddenStarTrigger); + bhv_constant(bhvTtmRollingLog); + bhv_constant(bhvLllVolcanoFallingTrap); + bhv_constant(bhvLllRollingLog); + bhv_constant(bhv1upWalking); + bhv_constant(bhv1upRunningAway); + bhv_constant(bhv1upSliding); + bhv_constant(bhv1Up); + bhv_constant(bhv1upJumpOnApproach); + bhv_constant(bhvHidden1up); + bhv_constant(bhvHidden1upTrigger); + bhv_constant(bhvHidden1upInPole); + bhv_constant(bhvHidden1upInPoleTrigger); + bhv_constant(bhvHidden1upInPoleSpawner); + bhv_constant(bhvControllablePlatform); + bhv_constant(bhvControllablePlatformSub); + bhv_constant(bhvBreakableBoxSmall); + bhv_constant(bhvSlidingSnowMound); + bhv_constant(bhvSnowMoundSpawn); + bhv_constant(bhvWdwSquareFloatingPlatform); + bhv_constant(bhvWdwRectangularFloatingPlatform); + bhv_constant(bhvJrbFloatingPlatform); + bhv_constant(bhvArrowLift); + bhv_constant(bhvOrangeNumber); + bhv_constant(bhvMantaRay); + bhv_constant(bhvFallingPillar); + bhv_constant(bhvFallingPillarHitbox); + bhv_constant(bhvPillarBase); + bhv_constant(bhvJrbFloatingBox); + bhv_constant(bhvDecorativePendulum); + bhv_constant(bhvTreasureChestsShip); + bhv_constant(bhvTreasureChestsJrb); + bhv_constant(bhvTreasureChests); + bhv_constant(bhvTreasureChestBottom); + bhv_constant(bhvTreasureChestTop); + bhv_constant(bhvMips); + bhv_constant(bhvYoshi); + bhv_constant(bhvKoopa); + bhv_constant(bhvKoopaRaceEndpoint); + bhv_constant(bhvKoopaFlag); + bhv_constant(bhvPokey); + bhv_constant(bhvPokeyBodyPart); + bhv_constant(bhvSwoop); + bhv_constant(bhvFlyGuy); + bhv_constant(bhvGoomba); + bhv_constant(bhvGoombaTripletSpawner); + bhv_constant(bhvChainChomp); + bhv_constant(bhvChainChompChainPart); + bhv_constant(bhvWoodenPost); + bhv_constant(bhvChainChompGate); + bhv_constant(bhvWigglerHead); + bhv_constant(bhvWigglerBody); + bhv_constant(bhvEnemyLakitu); + bhv_constant(bhvCameraLakitu); + bhv_constant(bhvCloud); + bhv_constant(bhvCloudPart); + bhv_constant(bhvSpiny); + bhv_constant(bhvMontyMole); + bhv_constant(bhvMontyMoleHole); + bhv_constant(bhvMontyMoleRock); + bhv_constant(bhvPlatformOnTrack); + bhv_constant(bhvTrackBall); + bhv_constant(bhvSeesawPlatform); + bhv_constant(bhvFerrisWheelAxle); + bhv_constant(bhvFerrisWheelPlatform); + bhv_constant(bhvWaterBombSpawner); + bhv_constant(bhvWaterBomb); + bhv_constant(bhvWaterBombShadow); + bhv_constant(bhvTTCRotatingSolid); + bhv_constant(bhvTTCPendulum); + bhv_constant(bhvTTCTreadmill); + bhv_constant(bhvTTCMovingBar); + bhv_constant(bhvTTCCog); + bhv_constant(bhvTTCPitBlock); + bhv_constant(bhvTTCElevator); + bhv_constant(bhvTTC2DRotator); + bhv_constant(bhvTTCSpinner); + bhv_constant(bhvMrBlizzard); + bhv_constant(bhvMrBlizzardSnowball); + bhv_constant(bhvSlidingPlatform2); + bhv_constant(bhvOctagonalPlatformRotating); + bhv_constant(bhvAnimatesOnFloorSwitchPress); + bhv_constant(bhvActivatedBackAndForthPlatform); + bhv_constant(bhvRecoveryHeart); + bhv_constant(bhvWaterBombCannon); + bhv_constant(bhvCannonBarrelBubbles); + bhv_constant(bhvUnagi); + bhv_constant(bhvUnagiSubobject); + bhv_constant(bhvDorrie); + bhv_constant(bhvHauntedChair); + bhv_constant(bhvMadPiano); + bhv_constant(bhvFlyingBookend); + bhv_constant(bhvBookendSpawn); + bhv_constant(bhvHauntedBookshelfManager); + bhv_constant(bhvBookSwitch); + bhv_constant(bhvFirePiranhaPlant); + bhv_constant(bhvSmallPiranhaFlame); + bhv_constant(bhvFireSpitter); + bhv_constant(bhvFlyguyFlame); + bhv_constant(bhvSnufit); + bhv_constant(bhvSnufitBalls); + bhv_constant(bhvHorizontalGrindel); + bhv_constant(bhvEyerokBoss); + bhv_constant(bhvEyerokHand); + bhv_constant(bhvKlepto); + bhv_constant(bhvBird); + bhv_constant(bhvRacingPenguin); + bhv_constant(bhvPenguinRaceFinishLine); + bhv_constant(bhvPenguinRaceShortcutCheck); + bhv_constant(bhvCoffinSpawner); + bhv_constant(bhvCoffin); + bhv_constant(bhvClamShell); + bhv_constant(bhvSkeeter); + bhv_constant(bhvSkeeterWave); + bhv_constant(bhvSwingPlatform); + bhv_constant(bhvDonutPlatformSpawner); + bhv_constant(bhvDonutPlatform); + bhv_constant(bhvDDDPole); + bhv_constant(bhvRedCoinStarMarker); + bhv_constant(bhvTripletButterfly); + bhv_constant(bhvBubba); + bhv_constant(bhvBeginningLakitu); + bhv_constant(bhvBeginningPeach); + bhv_constant(bhvEndBirds1); + bhv_constant(bhvEndBirds2); + bhv_constant(bhvIntroScene); + bhv_constant(bhvUnusedFakeStar); + + // Legacy behavior names + bhv_legacy_constant(bhvFish2, bhvManyBlueFishSpawner); + bhv_legacy_constant(bhvFish3, bhvFewBlueFishSpawner); + bhv_legacy_constant(bhvLargeFishGroup, bhvFishSpawner); + + + // Behavior ids + bhv_constant(id_bhv1Up); + bhv_constant(id_bhv1upJumpOnApproach); + bhv_constant(id_bhv1upRunningAway); + bhv_constant(id_bhv1upSliding); + bhv_constant(id_bhv1upWalking); + bhv_constant(id_bhvActivatedBackAndForthPlatform); + bhv_constant(id_bhvActSelector); + bhv_constant(id_bhvActSelectorStarType); + bhv_constant(id_bhvAirborneDeathWarp); + bhv_constant(id_bhvAirborneStarCollectWarp); + bhv_constant(id_bhvAirborneWarp); + bhv_constant(id_bhvAlphaBooKey); + bhv_constant(id_bhvAmbientSounds); + bhv_constant(id_bhvAnimatedTexture); + bhv_constant(id_bhvAnimatesOnFloorSwitchPress); + bhv_constant(id_bhvAnotherElavator); + bhv_constant(id_bhvAnotherTiltingPlatform); + bhv_constant(id_bhvArrowLift); + bhv_constant(id_bhvBalconyBigBoo); + bhv_constant(id_bhvBbhTiltingTrapPlatform); + bhv_constant(id_bhvBbhTumblingBridge); + bhv_constant(id_bhvBeginningLakitu); + bhv_constant(id_bhvBeginningPeach); + bhv_constant(id_bhvBetaBooKey); + bhv_constant(id_bhvBetaBowserAnchor); + bhv_constant(id_bhvBetaChestBottom); + bhv_constant(id_bhvBetaChestLid); + bhv_constant(id_bhvBetaFishSplashSpawner); + bhv_constant(id_bhvBetaHoldableObject); + bhv_constant(id_bhvBetaMovingFlames); + bhv_constant(id_bhvBetaMovingFlamesSpawn); + bhv_constant(id_bhvBetaTrampolineSpring); + bhv_constant(id_bhvBetaTrampolineTop); + bhv_constant(id_bhvBigBoulder); + bhv_constant(id_bhvBigBoulderGenerator); + bhv_constant(id_bhvBigBully); + bhv_constant(id_bhvBigBullyWithMinions); + bhv_constant(id_bhvBigChillBully); + bhv_constant(id_bhvBigSnowmanWhole); + bhv_constant(id_bhvBird); + bhv_constant(id_bhvBirdsSoundLoop); + bhv_constant(id_bhvBitfsSinkingCagePlatform); + bhv_constant(id_bhvBitfsSinkingPlatforms); + bhv_constant(id_bhvBitfsTiltingInvertedPyramid); + bhv_constant(id_bhvBlackSmokeBowser); + bhv_constant(id_bhvBlackSmokeMario); + bhv_constant(id_bhvBlackSmokeUpward); + bhv_constant(id_bhvBlueBowserFlame); + bhv_constant(id_bhvBlueCoinJumping); + bhv_constant(id_bhvBlueCoinSliding); + bhv_constant(id_bhvBlueCoinSwitch); + bhv_constant(id_bhvBlueFish); + bhv_constant(id_bhvBlueFlamesGroup); + bhv_constant(id_bhvBobBowlingBallSpawner); + bhv_constant(id_bhvBobomb); + bhv_constant(id_bhvBobombAnchorMario); + bhv_constant(id_bhvBobombBuddy); + bhv_constant(id_bhvBobombBuddyOpensCannon); + bhv_constant(id_bhvBobombBullyDeathSmoke); + bhv_constant(id_bhvBobombExplosionBubble); + bhv_constant(id_bhvBobombExplosionBubble3600); + bhv_constant(id_bhvBobombFuseSmoke); + bhv_constant(id_bhvBoo); + bhv_constant(id_bhvBooBossSpawnedBridge); + bhv_constant(id_bhvBooCage); + bhv_constant(id_bhvBooInCastle); + bhv_constant(id_bhvBookendSpawn); + bhv_constant(id_bhvBookSwitch); + bhv_constant(id_bhvBooWithCage); + bhv_constant(id_bhvBouncingFireball); + bhv_constant(id_bhvBouncingFireballFlame); + bhv_constant(id_bhvBowlingBall); + bhv_constant(id_bhvBowser); + bhv_constant(id_bhvBowserBodyAnchor); + bhv_constant(id_bhvBowserBomb); + bhv_constant(id_bhvBowserBombExplosion); + bhv_constant(id_bhvBowserBombSmoke); + bhv_constant(id_bhvBowserCourseRedCoinStar); + bhv_constant(id_bhvBowserFlameSpawn); + bhv_constant(id_bhvBowserKey); + bhv_constant(id_bhvBowserKeyCourseExit); + bhv_constant(id_bhvBowserKeyUnlockDoor); + bhv_constant(id_bhvBowserShockWave); + bhv_constant(id_bhvBowsersSub); + bhv_constant(id_bhvBowserSubDoor); + bhv_constant(id_bhvBowserTailAnchor); + bhv_constant(id_bhvBreakableBox); + bhv_constant(id_bhvBreakableBoxSmall); + bhv_constant(id_bhvBreakBoxTriangle); + bhv_constant(id_bhvBreathParticleSpawner); + bhv_constant(id_bhvBub); + bhv_constant(id_bhvBubba); + bhv_constant(id_bhvBubbleMaybe); + bhv_constant(id_bhvBubbleParticleSpawner); + bhv_constant(id_bhvBubblePlayer); + bhv_constant(id_bhvBubbleSplash); + bhv_constant(id_bhvBulletBill); + bhv_constant(id_bhvBulletBillCannon); + bhv_constant(id_bhvButterfly); + bhv_constant(id_bhvCameraLakitu); + bhv_constant(id_bhvCannon); + bhv_constant(id_bhvCannonBarrel); + bhv_constant(id_bhvCannonBarrelBubbles); + bhv_constant(id_bhvCannonBaseUnused); + bhv_constant(id_bhvCannonClosed); + bhv_constant(id_bhvCapSwitch); + bhv_constant(id_bhvCapSwitchBase); + bhv_constant(id_bhvCarrySomething1); + bhv_constant(id_bhvCarrySomething2); + bhv_constant(id_bhvCarrySomething3); + bhv_constant(id_bhvCarrySomething4); + bhv_constant(id_bhvCarrySomething5); + bhv_constant(id_bhvCarrySomething6); + bhv_constant(id_bhvCastleFlagWaving); + bhv_constant(id_bhvCastleFloorTrap); + bhv_constant(id_bhvCcmTouchedStarSpawn); + bhv_constant(id_bhvCelebrationStar); + bhv_constant(id_bhvCelebrationStarSparkle); + bhv_constant(id_bhvChainChomp); + bhv_constant(id_bhvChainChompChainPart); + bhv_constant(id_bhvChainChompGate); + bhv_constant(id_bhvCheckerboardElevatorGroup); + bhv_constant(id_bhvCheckerboardPlatformSub); + bhv_constant(id_bhvChirpChirp); + bhv_constant(id_bhvChirpChirpUnused); + bhv_constant(id_bhvChuckya); + bhv_constant(id_bhvChuckyaAnchorMario); + bhv_constant(id_bhvCirclingAmp); + bhv_constant(id_bhvClamShell); + bhv_constant(id_bhvClockHourHand); + bhv_constant(id_bhvClockMinuteHand); + bhv_constant(id_bhvCloud); + bhv_constant(id_bhvCloudPart); + bhv_constant(id_bhvCoffin); + bhv_constant(id_bhvCoffinSpawner); + bhv_constant(id_bhvCoinFormation); + bhv_constant(id_bhvCoinFormationSpawn); + bhv_constant(id_bhvCoinInsideBoo); + bhv_constant(id_bhvCoinSparkles); + bhv_constant(id_bhvControllablePlatform); + bhv_constant(id_bhvControllablePlatformSub); + bhv_constant(id_bhvCourtyardBooTriplet); + bhv_constant(id_bhvCutOutObject); + bhv_constant(id_bhvDddMovingPole); + bhv_constant(id_bhvDDDPole); + bhv_constant(id_bhvDddWarp); + bhv_constant(id_bhvDeathWarp); + bhv_constant(id_bhvDecorativePendulum); + bhv_constant(id_bhvDirtParticleSpawner); + bhv_constant(id_bhvDonutPlatform); + bhv_constant(id_bhvDonutPlatformSpawner); + bhv_constant(id_bhvDoor); + bhv_constant(id_bhvDoorWarp); + bhv_constant(id_bhvDorrie); + bhv_constant(id_bhvEndBirds1); + bhv_constant(id_bhvEndBirds2); + bhv_constant(id_bhvEndPeach); + bhv_constant(id_bhvEndToad); + bhv_constant(id_bhvEnemyLakitu); + bhv_constant(id_bhvExclamationBox); + bhv_constant(id_bhvExitPodiumWarp); + bhv_constant(id_bhvExplosion); + bhv_constant(id_bhvEyerokBoss); + bhv_constant(id_bhvEyerokHand); + bhv_constant(id_bhvFadingWarp); + bhv_constant(id_bhvFallingBowserPlatform); + bhv_constant(id_bhvFallingPillar); + bhv_constant(id_bhvFallingPillarHitbox); + bhv_constant(id_bhvFerrisWheelAxle); + bhv_constant(id_bhvFerrisWheelPlatform); + bhv_constant(id_bhvFewBlueFishSpawner); + bhv_constant(id_bhvFireParticleSpawner); + bhv_constant(id_bhvFirePiranhaPlant); + bhv_constant(id_bhvFireSpitter); + bhv_constant(id_bhvFish); + bhv_constant(id_bhvFishGroup); + bhv_constant(id_bhvFishSpawner); + bhv_constant(id_bhvFlame); + bhv_constant(id_bhvFlameBouncing); + bhv_constant(id_bhvFlameBowser); + bhv_constant(id_bhvFlameFloatingLanding); + bhv_constant(id_bhvFlameLargeBurningOut); + bhv_constant(id_bhvFlameMovingForwardGrowing); + bhv_constant(id_bhvFlamethrower); + bhv_constant(id_bhvFlamethrowerFlame); + bhv_constant(id_bhvFloorSwitchAnimatesObject); + bhv_constant(id_bhvFloorSwitchGrills); + bhv_constant(id_bhvFloorSwitchHardcodedModel); + bhv_constant(id_bhvFloorSwitchHiddenObjects); + bhv_constant(id_bhvFloorTrapInCastle); + bhv_constant(id_bhvFlyGuy); + bhv_constant(id_bhvFlyguyFlame); + bhv_constant(id_bhvFlyingBookend); + bhv_constant(id_bhvFlyingWarp); + bhv_constant(id_bhvFreeBowlingBall); + bhv_constant(id_bhvGhostHuntBigBoo); + bhv_constant(id_bhvGhostHuntBoo); + bhv_constant(id_bhvGiantPole); + bhv_constant(id_bhvGoldenCoinSparkles); + bhv_constant(id_bhvGoomba); + bhv_constant(id_bhvGoombaTripletSpawner); + bhv_constant(id_bhvGrandStar); + bhv_constant(id_bhvGrindel); + bhv_constant(id_bhvHardAirKnockBackWarp); + bhv_constant(id_bhvHauntedBookshelf); + bhv_constant(id_bhvHauntedBookshelfManager); + bhv_constant(id_bhvHauntedChair); + bhv_constant(id_bhvHeaveHo); + bhv_constant(id_bhvHeaveHoThrowMario); + bhv_constant(id_bhvHidden1up); + bhv_constant(id_bhvHidden1upInPole); + bhv_constant(id_bhvHidden1upInPoleSpawner); + bhv_constant(id_bhvHidden1upInPoleTrigger); + bhv_constant(id_bhvHidden1upTrigger); + bhv_constant(id_bhvHiddenAt120Stars); + bhv_constant(id_bhvHiddenBlueCoin); + bhv_constant(id_bhvHiddenObject); + bhv_constant(id_bhvHiddenRedCoinStar); + bhv_constant(id_bhvHiddenStaircaseStep); + bhv_constant(id_bhvHiddenStar); + bhv_constant(id_bhvHiddenStarTrigger); + bhv_constant(id_bhvHmcElevatorPlatform); + bhv_constant(id_bhvHomingAmp); + bhv_constant(id_bhvHoot); + bhv_constant(id_bhvHorizontalGrindel); + bhv_constant(id_bhvHorStarParticleSpawner); + bhv_constant(id_bhvIdleWaterWave); + bhv_constant(id_bhvIgloo); + bhv_constant(id_bhvInitializeChangingWaterLevel); + bhv_constant(id_bhvInsideCannon); + bhv_constant(id_bhvInstantActiveWarp); + bhv_constant(id_bhvInSunkenShip); + bhv_constant(id_bhvInSunkenShip2); + bhv_constant(id_bhvInSunkenShip3); + bhv_constant(id_bhvIntroScene); + bhv_constant(id_bhvInvisibleObjectsUnderBridge); + bhv_constant(id_bhvJetStream); + bhv_constant(id_bhvJetStreamRingSpawner); + bhv_constant(id_bhvJetStreamWaterRing); + bhv_constant(id_bhvJrbFloatingBox); + bhv_constant(id_bhvJrbFloatingPlatform); + bhv_constant(id_bhvJrbSlidingBox); + bhv_constant(id_bhvJumpingBox); + bhv_constant(id_bhvKickableBoard); + bhv_constant(id_bhvKingBobomb); + bhv_constant(id_bhvKlepto); + bhv_constant(id_bhvKoopa); + bhv_constant(id_bhvKoopaFlag); + bhv_constant(id_bhvKoopaRaceEndpoint); + bhv_constant(id_bhvKoopaShell); + bhv_constant(id_bhvKoopaShellFlame); + bhv_constant(id_bhvKoopaShellUnderwater); + bhv_constant(id_bhvLargeBomp); + bhv_constant(id_bhvLaunchDeathWarp); + bhv_constant(id_bhvLaunchStarCollectWarp); + bhv_constant(id_bhvLeafParticleSpawner); + bhv_constant(id_bhvLllBowserPuzzle); + bhv_constant(id_bhvLllBowserPuzzlePiece); + bhv_constant(id_bhvLllDrawbridge); + bhv_constant(id_bhvLllDrawbridgeSpawner); + bhv_constant(id_bhvLllFloatingWoodBridge); + bhv_constant(id_bhvLllHexagonalMesh); + bhv_constant(id_bhvLllMovingOctagonalMeshPlatform); + bhv_constant(id_bhvLllRollingLog); + bhv_constant(id_bhvLllRotatingBlockWithFireBars); + bhv_constant(id_bhvLllRotatingHexagonalPlatform); + bhv_constant(id_bhvLllRotatingHexagonalRing); + bhv_constant(id_bhvLllRotatingHexFlame); + bhv_constant(id_bhvLllSinkingRectangularPlatform); + bhv_constant(id_bhvLllSinkingRockBlock); + bhv_constant(id_bhvLllSinkingSquarePlatforms); + bhv_constant(id_bhvLllTiltingInvertedPyramid); + bhv_constant(id_bhvLllTumblingBridge); + bhv_constant(id_bhvLllVolcanoFallingTrap); + bhv_constant(id_bhvLllWoodPiece); + bhv_constant(id_bhvMacroUkiki); + bhv_constant(id_bhvMadPiano); + bhv_constant(id_bhvMantaRay); + bhv_constant(id_bhvMantaRayRingManager); + bhv_constant(id_bhvMantaRayWaterRing); + bhv_constant(id_bhvManyBlueFishSpawner); + bhv_constant(id_bhvMario); + bhv_constant(id_bhvMenuButton); + bhv_constant(id_bhvMenuButtonManager); + bhv_constant(id_bhvMerryGoRound); + bhv_constant(id_bhvMerryGoRoundBigBoo); + bhv_constant(id_bhvMerryGoRoundBoo); + bhv_constant(id_bhvMerryGoRoundBooManager); + bhv_constant(id_bhvMeshElevator); + bhv_constant(id_bhvMessagePanel); + bhv_constant(id_bhvMetalCap); + bhv_constant(id_bhvMips); + bhv_constant(id_bhvMistCircParticleSpawner); + bhv_constant(id_bhvMistParticleSpawner); + bhv_constant(id_bhvMoatGrills); + bhv_constant(id_bhvMoneybag); + bhv_constant(id_bhvMoneybagHidden); + bhv_constant(id_bhvMontyMole); + bhv_constant(id_bhvMontyMoleHole); + bhv_constant(id_bhvMontyMoleRock); + bhv_constant(id_bhvMovingBlueCoin); + bhv_constant(id_bhvMovingYellowCoin); + bhv_constant(id_bhvMrBlizzard); + bhv_constant(id_bhvMrBlizzardSnowball); + bhv_constant(id_bhvMrI); + bhv_constant(id_bhvMrIBlueCoin); + bhv_constant(id_bhvMrIBody); + bhv_constant(id_bhvMrIParticle); + bhv_constant(id_bhvNormalCap); + bhv_constant(id_bhvObjectBubble); + bhv_constant(id_bhvObjectWaterSplash); + bhv_constant(id_bhvObjectWaterWave); + bhv_constant(id_bhvObjectWaveTrail); + bhv_constant(id_bhvOctagonalPlatformRotating); + bhv_constant(id_bhvOneCoin); + bhv_constant(id_bhvOpenableCageDoor); + bhv_constant(id_bhvOpenableGrill); + bhv_constant(id_bhvOrangeNumber); + bhv_constant(id_bhvPaintingDeathWarp); + bhv_constant(id_bhvPaintingStarCollectWarp); + bhv_constant(id_bhvPenguinBaby); + bhv_constant(id_bhvPenguinRaceFinishLine); + bhv_constant(id_bhvPenguinRaceShortcutCheck); + bhv_constant(id_bhvPillarBase); + bhv_constant(id_bhvPiranhaPlant); + bhv_constant(id_bhvPiranhaPlantBubble); + bhv_constant(id_bhvPiranhaPlantWakingBubbles); + bhv_constant(id_bhvPitBowlingBall); + bhv_constant(id_bhvPlatformOnTrack); + bhv_constant(id_bhvPlaysMusicTrackWhenTouched); + bhv_constant(id_bhvPlungeBubble); + bhv_constant(id_bhvPokey); + bhv_constant(id_bhvPokeyBodyPart); + bhv_constant(id_bhvPoleGrabbing); + bhv_constant(id_bhvPoundTinyStarParticle); + bhv_constant(id_bhvPunchTinyTriangle); + bhv_constant(id_bhvPurpleParticle); + bhv_constant(id_bhvPurpleSwitchHiddenBoxes); + bhv_constant(id_bhvPushableMetalBox); + bhv_constant(id_bhvPyramidElevator); + bhv_constant(id_bhvPyramidElevatorTrajectoryMarkerBall); + bhv_constant(id_bhvPyramidPillarTouchDetector); + bhv_constant(id_bhvPyramidTop); + bhv_constant(id_bhvPyramidTopFragment); + bhv_constant(id_bhvRacingPenguin); + bhv_constant(id_bhvRandomAnimatedTexture); + bhv_constant(id_bhvRecoveryHeart); + bhv_constant(id_bhvRedCoin); + bhv_constant(id_bhvRedCoinStarMarker); + bhv_constant(id_bhvRespawner); + bhv_constant(id_bhvRockSolid); + bhv_constant(id_bhvRotatingCounterClockwise); + bhv_constant(id_bhvRotatingExclamationMark); + bhv_constant(id_bhvRotatingPlatform); + bhv_constant(id_bhvRrCruiserWing); + bhv_constant(id_bhvRrElevatorPlatform); + bhv_constant(id_bhvRrRotatingBridgePlatform); + bhv_constant(id_bhvSandSoundLoop); + bhv_constant(id_bhvScuttlebug); + bhv_constant(id_bhvScuttlebugSpawn); + bhv_constant(id_bhvSeaweed); + bhv_constant(id_bhvSeaweedBundle); + bhv_constant(id_bhvSeesawPlatform); + bhv_constant(id_bhvShallowWaterSplash); + bhv_constant(id_bhvShallowWaterWave); + bhv_constant(id_bhvShipPart3); + bhv_constant(id_bhvSignOnWall); + bhv_constant(id_bhvSingleCoinGetsSpawned); + bhv_constant(id_bhvSkeeter); + bhv_constant(id_bhvSkeeterWave); + bhv_constant(id_bhvSlidingPlatform2); + bhv_constant(id_bhvSlidingSnowMound); + bhv_constant(id_bhvSLSnowmanWind); + bhv_constant(id_bhvSLWalkingPenguin); + bhv_constant(id_bhvSmallBomp); + bhv_constant(id_bhvSmallBully); + bhv_constant(id_bhvSmallChillBully); + bhv_constant(id_bhvSmallParticle); + bhv_constant(id_bhvSmallParticleBubbles); + bhv_constant(id_bhvSmallParticleSnow); + bhv_constant(id_bhvSmallPenguin); + bhv_constant(id_bhvSmallPiranhaFlame); + bhv_constant(id_bhvSmallWaterWave); + bhv_constant(id_bhvSmallWaterWave398); + bhv_constant(id_bhvSmallWhomp); + bhv_constant(id_bhvSmoke); + bhv_constant(id_bhvSnowBall); + bhv_constant(id_bhvSnowmansBodyCheckpoint); + bhv_constant(id_bhvSnowmansBottom); + bhv_constant(id_bhvSnowmansHead); + bhv_constant(id_bhvSnowMoundSpawn); + bhv_constant(id_bhvSnowParticleSpawner); + bhv_constant(id_bhvSnufit); + bhv_constant(id_bhvSnufitBalls); + bhv_constant(id_bhvSoundSpawner); + bhv_constant(id_bhvSparkle); + bhv_constant(id_bhvSparkleParticleSpawner); + bhv_constant(id_bhvSparkleSpawn); + bhv_constant(id_bhvSpawnedStar); + bhv_constant(id_bhvSpawnedStarNoLevelExit); + bhv_constant(id_bhvSpinAirborneCircleWarp); + bhv_constant(id_bhvSpinAirborneWarp); + bhv_constant(id_bhvSpindel); + bhv_constant(id_bhvSpindrift); + bhv_constant(id_bhvSpiny); + bhv_constant(id_bhvSquarishPathMoving); + bhv_constant(id_bhvSquarishPathParent); + bhv_constant(id_bhvSquishablePlatform); + bhv_constant(id_bhvSslMovingPyramidWall); + bhv_constant(id_bhvStar); + bhv_constant(id_bhvStarDoor); + bhv_constant(id_bhvStarKeyCollectionPuffSpawner); + bhv_constant(id_bhvStarSpawnCoordinates); + bhv_constant(id_bhvStaticCheckeredPlatform); + bhv_constant(id_bhvStaticObject); + bhv_constant(id_bhvStrongWindParticle); + bhv_constant(id_bhvStub); + bhv_constant(id_bhvStub1D0C); + bhv_constant(id_bhvStub1D70); + bhv_constant(id_bhvSunkenShipPart); + bhv_constant(id_bhvSunkenShipPart2); + bhv_constant(id_bhvSunkenShipSetRotation); + bhv_constant(id_bhvSushiShark); + bhv_constant(id_bhvSushiSharkCollisionChild); + bhv_constant(id_bhvSwimmingWarp); + bhv_constant(id_bhvSwingPlatform); + bhv_constant(id_bhvSwoop); + bhv_constant(id_bhvTankFishGroup); + bhv_constant(id_bhvTemporaryYellowCoin); + bhv_constant(id_bhvTenCoinsSpawn); + bhv_constant(id_bhvThiBowlingBallSpawner); + bhv_constant(id_bhvThiHugeIslandTop); + bhv_constant(id_bhvThiTinyIslandTop); + bhv_constant(id_bhvThreeCoinsSpawn); + bhv_constant(id_bhvThwomp); + bhv_constant(id_bhvThwomp2); + bhv_constant(id_bhvTiltingBowserLavaPlatform); + bhv_constant(id_bhvTinyStrongWindParticle); + bhv_constant(id_bhvToadMessage); + bhv_constant(id_bhvTower); + bhv_constant(id_bhvTowerDoor); + bhv_constant(id_bhvTowerPlatformGroup); + bhv_constant(id_bhvToxBox); + bhv_constant(id_bhvTrackBall); + bhv_constant(id_bhvTreasureChestBottom); + bhv_constant(id_bhvTreasureChests); + bhv_constant(id_bhvTreasureChestsJrb); + bhv_constant(id_bhvTreasureChestsShip); + bhv_constant(id_bhvTreasureChestTop); + bhv_constant(id_bhvTree); + bhv_constant(id_bhvTreeLeaf); + bhv_constant(id_bhvTreeSnow); + bhv_constant(id_bhvTriangleParticleSpawner); + bhv_constant(id_bhvTripletButterfly); + bhv_constant(id_bhvTTC2DRotator); + bhv_constant(id_bhvTTCCog); + bhv_constant(id_bhvTTCElevator); + bhv_constant(id_bhvTTCMovingBar); + bhv_constant(id_bhvTTCPendulum); + bhv_constant(id_bhvTTCPitBlock); + bhv_constant(id_bhvTTCRotatingSolid); + bhv_constant(id_bhvTTCSpinner); + bhv_constant(id_bhvTTCTreadmill); + bhv_constant(id_bhvTtmBowlingBallSpawner); + bhv_constant(id_bhvTtmRollingLog); + bhv_constant(id_bhvTumblingBridgePlatform); + bhv_constant(id_bhvTuxiesMother); + bhv_constant(id_bhvTweester); + bhv_constant(id_bhvTweesterSandParticle); + bhv_constant(id_bhvUkiki); + bhv_constant(id_bhvUkikiCage); + bhv_constant(id_bhvUkikiCageChild); + bhv_constant(id_bhvUkikiCageStar); + bhv_constant(id_bhvUnagi); + bhv_constant(id_bhvUnagiSubobject); + bhv_constant(id_bhvUnlockDoorStar); + bhv_constant(id_bhvUnused05A8); + bhv_constant(id_bhvUnused0DFC); + bhv_constant(id_bhvUnused1820); + bhv_constant(id_bhvUnused1F30); + bhv_constant(id_bhvUnused20E0); + bhv_constant(id_bhvUnused2A10); + bhv_constant(id_bhvUnused2A54); + bhv_constant(id_bhvUnusedFakeStar); + bhv_constant(id_bhvUnusedParticleSpawn); + bhv_constant(id_bhvUnusedPoundablePlatform); + bhv_constant(id_bhvVanishCap); + bhv_constant(id_bhvVertStarParticleSpawner); + bhv_constant(id_bhvVolcanoFlames); + bhv_constant(id_bhvVolcanoSoundLoop); + bhv_constant(id_bhvWallTinyStarParticle); + bhv_constant(id_bhvWarp); + bhv_constant(id_bhvWarpPipe); + bhv_constant(id_bhvWaterAirBubble); + bhv_constant(id_bhvWaterBomb); + bhv_constant(id_bhvWaterBombCannon); + bhv_constant(id_bhvWaterBombShadow); + bhv_constant(id_bhvWaterBombSpawner); + bhv_constant(id_bhvWaterDroplet); + bhv_constant(id_bhvWaterDropletSplash); + bhv_constant(id_bhvWaterfallSoundLoop); + bhv_constant(id_bhvWaterLevelDiamond); + bhv_constant(id_bhvWaterLevelPillar); + bhv_constant(id_bhvWaterMist); + bhv_constant(id_bhvWaterMist2); + bhv_constant(id_bhvWaterSplash); + bhv_constant(id_bhvWaveTrail); + bhv_constant(id_bhvWdwExpressElevator); + bhv_constant(id_bhvWdwExpressElevatorPlatform); + bhv_constant(id_bhvWdwRectangularFloatingPlatform); + bhv_constant(id_bhvWdwSquareFloatingPlatform); + bhv_constant(id_bhvWfBreakableWallLeft); + bhv_constant(id_bhvWfBreakableWallRight); + bhv_constant(id_bhvWfElevatorTowerPlatform); + bhv_constant(id_bhvWfRotatingWoodenPlatform); + bhv_constant(id_bhvWfSlidingPlatform); + bhv_constant(id_bhvWfSlidingTowerPlatform); + bhv_constant(id_bhvWfSolidTowerPlatform); + bhv_constant(id_bhvWfTumblingBridge); + bhv_constant(id_bhvWhirlpool); + bhv_constant(id_bhvWhitePuff1); + bhv_constant(id_bhvWhitePuff2); + bhv_constant(id_bhvWhitePuffExplosion); + bhv_constant(id_bhvWhitePuffSmoke); + bhv_constant(id_bhvWhitePuffSmoke2); + bhv_constant(id_bhvWhompKingBoss); + bhv_constant(id_bhvWigglerBody); + bhv_constant(id_bhvWigglerHead); + bhv_constant(id_bhvWind); + bhv_constant(id_bhvWingCap); + bhv_constant(id_bhvWoodenPost); + bhv_constant(id_bhvYellowBackgroundInMenu); + bhv_constant(id_bhvYellowBall); + bhv_constant(id_bhvYellowCoin); + bhv_constant(id_bhvYoshi); + + // Define a special type for new ids that don't override. + if (_Arg == "id_bhvNewId") { return (BehaviorScript) (0xFFFF); } + + // Legacy behavior ids + bhv_legacy_constant(id_bhvFish2, id_bhvManyBlueFishSpawner); + bhv_legacy_constant(id_bhvFish3, id_bhvFewBlueFishSpawner); + bhv_legacy_constant(id_bhvLargeFishGroup, id_bhvFishSpawner); + + + // Model constants + bhv_constant(ACT_1); + bhv_constant(ACT_2); + bhv_constant(ACT_3); + bhv_constant(ACT_4); + bhv_constant(ACT_5); + bhv_constant(ACT_6); + bhv_constant(ALL_ACTS_MACRO); + bhv_constant(ALL_ACTS); + bhv_constant(COIN_FORMATION_FLAG_VERTICAL); + bhv_constant(COIN_FORMATION_FLAG_RING); + bhv_constant(COIN_FORMATION_FLAG_ARROW); + bhv_constant(COIN_FORMATION_FLAG_FLYING); + bhv_constant(MODEL_NONE); + bhv_constant(MODEL_MARIO); + bhv_constant(MODEL_LEVEL_GEOMETRY_03); + bhv_constant(MODEL_LEVEL_GEOMETRY_04); + bhv_constant(MODEL_LEVEL_GEOMETRY_05); + bhv_constant(MODEL_LEVEL_GEOMETRY_06); + bhv_constant(MODEL_LEVEL_GEOMETRY_07); + bhv_constant(MODEL_LEVEL_GEOMETRY_08); + bhv_constant(MODEL_LEVEL_GEOMETRY_09); + bhv_constant(MODEL_LEVEL_GEOMETRY_0A); + bhv_constant(MODEL_LEVEL_GEOMETRY_0B); + bhv_constant(MODEL_LEVEL_GEOMETRY_0C); + bhv_constant(MODEL_LEVEL_GEOMETRY_0D); + bhv_constant(MODEL_LEVEL_GEOMETRY_0E); + bhv_constant(MODEL_LEVEL_GEOMETRY_0F); + bhv_constant(MODEL_LEVEL_GEOMETRY_10); + bhv_constant(MODEL_LEVEL_GEOMETRY_11); + bhv_constant(MODEL_LEVEL_GEOMETRY_12); + bhv_constant(MODEL_LEVEL_GEOMETRY_13); + bhv_constant(MODEL_LEVEL_GEOMETRY_14); + bhv_constant(MODEL_LEVEL_GEOMETRY_15); + bhv_constant(MODEL_LEVEL_GEOMETRY_16); + bhv_constant(MODEL_BOB_BUBBLY_TREE); + bhv_constant(MODEL_WDW_BUBBLY_TREE); + bhv_constant(MODEL_CASTLE_GROUNDS_BUBBLY_TREE); + bhv_constant(MODEL_WF_BUBBLY_TREE); + bhv_constant(MODEL_THI_BUBBLY_TREE); + bhv_constant(MODEL_COURTYARD_SPIKY_TREE); + bhv_constant(MODEL_CCM_SNOW_TREE); + bhv_constant(MODEL_SL_SNOW_TREE); + bhv_constant(MODEL_UNKNOWN_TREE_1A); + bhv_constant(MODEL_SSL_PALM_TREE); + bhv_constant(MODEL_CASTLE_CASTLE_DOOR_UNUSED); + bhv_constant(MODEL_CASTLE_WOODEN_DOOR_UNUSED); + bhv_constant(MODEL_BBH_HAUNTED_DOOR); + bhv_constant(MODEL_HMC_WOODEN_DOOR); + bhv_constant(MODEL_UNKNOWN_DOOR_1E); + bhv_constant(MODEL_HMC_METAL_DOOR); + bhv_constant(MODEL_HMC_HAZY_MAZE_DOOR); + bhv_constant(MODEL_UNKNOWN_DOOR_21); + bhv_constant(MODEL_CASTLE_DOOR_0_STARS); + bhv_constant(MODEL_CASTLE_DOOR_1_STAR); + bhv_constant(MODEL_CASTLE_DOOR_3_STARS); + bhv_constant(MODEL_CASTLE_KEY_DOOR); + bhv_constant(MODEL_CASTLE_CASTLE_DOOR); + bhv_constant(MODEL_CASTLE_GROUNDS_CASTLE_DOOR); + bhv_constant(MODEL_CASTLE_WOODEN_DOOR); + bhv_constant(MODEL_COURTYARD_WOODEN_DOOR); + bhv_constant(MODEL_CCM_CABIN_DOOR); + bhv_constant(MODEL_UNKNOWN_DOOR_28); + bhv_constant(MODEL_CASTLE_METAL_DOOR); + bhv_constant(MODEL_CASTLE_GROUNDS_METAL_DOOR); + bhv_constant(MODEL_UNKNOWN_DOOR_2A); + bhv_constant(MODEL_UNKNOWN_DOOR_2B); + bhv_constant(MODEL_WF_TOWER_TRAPEZOID_PLATORM); + bhv_constant(MODEL_WF_TOWER_SQUARE_PLATORM); + bhv_constant(MODEL_WF_TOWER_SQUARE_PLATORM_UNUSED); + bhv_constant(MODEL_WF_TOWER_SQUARE_PLATORM_ELEVATOR); + bhv_constant(MODEL_BBH_STAIRCASE_STEP); + bhv_constant(MODEL_BBH_TILTING_FLOOR_PLATFORM); + bhv_constant(MODEL_BBH_TUMBLING_PLATFORM); + bhv_constant(MODEL_BBH_TUMBLING_PLATFORM_PART); + bhv_constant(MODEL_BBH_MOVING_BOOKSHELF); + bhv_constant(MODEL_BBH_MESH_ELEVATOR); + bhv_constant(MODEL_BBH_MERRY_GO_ROUND); + bhv_constant(MODEL_BBH_WOODEN_TOMB); + bhv_constant(MODEL_CCM_ROPEWAY_LIFT); + bhv_constant(MODEL_CCM_SNOWMAN_HEAD); + bhv_constant(MODEL_CASTLE_BOWSER_TRAP); + bhv_constant(MODEL_CASTLE_WATER_LEVEL_PILLAR); + bhv_constant(MODEL_CASTLE_CLOCK_MINUTE_HAND); + bhv_constant(MODEL_CASTLE_CLOCK_HOUR_HAND); + bhv_constant(MODEL_CASTLE_CLOCK_PENDULUM); + bhv_constant(MODEL_HMC_METAL_PLATFORM); + bhv_constant(MODEL_HMC_METAL_ARROW_PLATFORM); + bhv_constant(MODEL_HMC_ELEVATOR_PLATFORM); + bhv_constant(MODEL_HMC_ROLLING_ROCK); + bhv_constant(MODEL_HMC_ROCK_PIECE); + bhv_constant(MODEL_HMC_ROCK_SMALL_PIECE); + bhv_constant(MODEL_HMC_RED_GRILLS); + bhv_constant(MODEL_SSL_PYRAMID_TOP); + bhv_constant(MODEL_SSL_GRINDEL); + bhv_constant(MODEL_SSL_SPINDEL); + bhv_constant(MODEL_SSL_MOVING_PYRAMID_WALL); + bhv_constant(MODEL_SSL_PYRAMID_ELEVATOR); + bhv_constant(MODEL_BOB_CHAIN_CHOMP_GATE); + bhv_constant(MODEL_BOB_SEESAW_PLATFORM); + bhv_constant(MODEL_BOB_BARS_GRILLS); + bhv_constant(MODEL_SL_SNOW_TRIANGLE); + bhv_constant(MODEL_SL_CRACKED_ICE); + bhv_constant(MODEL_SL_CRACKED_ICE_CHUNK); + bhv_constant(MODEL_WDW_SQUARE_FLOATING_PLATFORM); + bhv_constant(MODEL_WDW_ARROW_LIFT); + bhv_constant(MODEL_WDW_WATER_LEVEL_DIAMOND); + bhv_constant(MODEL_WDW_HIDDEN_PLATFORM); + bhv_constant(MODEL_WDW_EXPRESS_ELEVATOR); + bhv_constant(MODEL_WDW_RECTANGULAR_FLOATING_PLATFORM); + bhv_constant(MODEL_WDW_ROTATING_PLATFORM); + bhv_constant(MODEL_JRB_SHIP_LEFT_HALF_PART); + bhv_constant(MODEL_JRB_SHIP_BACK_LEFT_PART); + bhv_constant(MODEL_JRB_SHIP_RIGHT_HALF_PART); + bhv_constant(MODEL_JRB_SHIP_BACK_RIGHT_PART); + bhv_constant(MODEL_JRB_SUNKEN_SHIP); + bhv_constant(MODEL_JRB_SUNKEN_SHIP_BACK); + bhv_constant(MODEL_JRB_ROCK); + bhv_constant(MODEL_JRB_SLIDING_BOX); + bhv_constant(MODEL_JRB_FALLING_PILLAR); + bhv_constant(MODEL_JRB_FALLING_PILLAR_BASE); + bhv_constant(MODEL_JRB_FLOATING_PLATFORM); + bhv_constant(MODEL_THI_HUGE_ISLAND_TOP); + bhv_constant(MODEL_THI_TINY_ISLAND_TOP); + bhv_constant(MODEL_TTC_ROTATING_CUBE); + bhv_constant(MODEL_TTC_ROTATING_PRISM); + bhv_constant(MODEL_TTC_PENDULUM); + bhv_constant(MODEL_TTC_LARGE_TREADMILL); + bhv_constant(MODEL_TTC_SMALL_TREADMILL); + bhv_constant(MODEL_TTC_PUSH_BLOCK); + bhv_constant(MODEL_TTC_ROTATING_HEXAGON); + bhv_constant(MODEL_TTC_ROTATING_TRIANGLE); + bhv_constant(MODEL_TTC_PIT_BLOCK); + bhv_constant(MODEL_TTC_PIT_BLOCK_UNUSED); + bhv_constant(MODEL_TTC_ELEVATOR_PLATFORM); + bhv_constant(MODEL_TTC_CLOCK_HAND); + bhv_constant(MODEL_TTC_SPINNER); + bhv_constant(MODEL_TTC_SMALL_GEAR); + bhv_constant(MODEL_TTC_LARGE_GEAR); + bhv_constant(MODEL_RR_SLIDING_PLATFORM); + bhv_constant(MODEL_RR_FLYING_CARPET); + bhv_constant(MODEL_RR_OCTAGONAL_PLATFORM); + bhv_constant(MODEL_RR_ROTATING_BRIDGE_PLATFORM); + bhv_constant(MODEL_RR_TRIANGLE_PLATFORM); + bhv_constant(MODEL_RR_CRUISER_WING); + bhv_constant(MODEL_RR_SEESAW_PLATFORM); + bhv_constant(MODEL_RR_L_SHAPED_PLATFORM); + bhv_constant(MODEL_RR_SWINGING_PLATFORM); + bhv_constant(MODEL_RR_DONUT_PLATFORM); + bhv_constant(MODEL_RR_ELEVATOR_PLATFORM); + bhv_constant(MODEL_RR_TRICKY_TRIANGLES); + bhv_constant(MODEL_RR_TRICKY_TRIANGLES_FRAME1); + bhv_constant(MODEL_RR_TRICKY_TRIANGLES_FRAME2); + bhv_constant(MODEL_RR_TRICKY_TRIANGLES_FRAME3); + bhv_constant(MODEL_RR_TRICKY_TRIANGLES_FRAME4); + bhv_constant(MODEL_BITDW_SQUARE_PLATFORM); + bhv_constant(MODEL_BITDW_SEESAW_PLATFORM); + bhv_constant(MODEL_BITDW_SLIDING_PLATFORM); + bhv_constant(MODEL_BITDW_FERRIS_WHEEL_AXLE); + bhv_constant(MODEL_BITDW_BLUE_PLATFORM); + bhv_constant(MODEL_BITDW_STAIRCASE_FRAME4); + bhv_constant(MODEL_BITDW_STAIRCASE_FRAME3); + bhv_constant(MODEL_BITDW_STAIRCASE_FRAME2); + bhv_constant(MODEL_BITDW_STAIRCASE_FRAME1); + bhv_constant(MODEL_BITDW_STAIRCASE); + bhv_constant(MODEL_VCUTM_SEESAW_PLATFORM); + bhv_constant(MODEL_VCUTM_CHECKERBOARD_PLATFORM_SPAWNER); + bhv_constant(MODEL_BITFS_PLATFORM_ON_TRACK); + bhv_constant(MODEL_BITFS_TILTING_SQUARE_PLATFORM); + bhv_constant(MODEL_BITFS_SINKING_PLATFORMS); + bhv_constant(MODEL_BITFS_BLUE_POLE); + bhv_constant(MODEL_BITFS_SINKING_CAGE_PLATFORM); + bhv_constant(MODEL_BITFS_ELEVATOR); + bhv_constant(MODEL_BITFS_STRETCHING_PLATFORMS); + bhv_constant(MODEL_BITFS_SEESAW_PLATFORM); + bhv_constant(MODEL_BITFS_MOVING_SQUARE_PLATFORM); + bhv_constant(MODEL_BITFS_SLIDING_PLATFORM); + bhv_constant(MODEL_BITFS_TUMBLING_PLATFORM_PART); + bhv_constant(MODEL_BITFS_TUMBLING_PLATFORM); + bhv_constant(MODEL_BITS_SLIDING_PLATFORM); + bhv_constant(MODEL_BITS_TWIN_SLIDING_PLATFORMS); + bhv_constant(MODEL_BITS_OCTAGONAL_PLATFORM); + bhv_constant(MODEL_BITS_BLUE_PLATFORM); + bhv_constant(MODEL_BITS_FERRIS_WHEEL_AXLE); + bhv_constant(MODEL_BITS_ARROW_PLATFORM); + bhv_constant(MODEL_BITS_SEESAW_PLATFORM); + bhv_constant(MODEL_BITS_TILTING_W_PLATFORM); + bhv_constant(MODEL_BITS_STAIRCASE); + bhv_constant(MODEL_BITS_STAIRCASE_FRAME1); + bhv_constant(MODEL_BITS_STAIRCASE_FRAME2); + bhv_constant(MODEL_BITS_STAIRCASE_FRAME3); + bhv_constant(MODEL_BITS_STAIRCASE_FRAME4); + bhv_constant(MODEL_BITS_WARP_PIPE); + bhv_constant(MODEL_LLL_DRAWBRIDGE_PART); + bhv_constant(MODEL_LLL_ROTATING_BLOCK_FIRE_BARS); + bhv_constant(MODEL_LLL_ROTATING_HEXAGONAL_RING); + bhv_constant(MODEL_LLL_SINKING_RECTANGULAR_PLATFORM); + bhv_constant(MODEL_LLL_SINKING_SQUARE_PLATFORMS); + bhv_constant(MODEL_LLL_TILTING_SQUARE_PLATFORM); + bhv_constant(MODEL_LLL_BOWSER_PIECE_1); + bhv_constant(MODEL_LLL_BOWSER_PIECE_2); + bhv_constant(MODEL_LLL_BOWSER_PIECE_3); + bhv_constant(MODEL_LLL_BOWSER_PIECE_4); + bhv_constant(MODEL_LLL_BOWSER_PIECE_5); + bhv_constant(MODEL_LLL_BOWSER_PIECE_6); + bhv_constant(MODEL_LLL_BOWSER_PIECE_7); + bhv_constant(MODEL_LLL_BOWSER_PIECE_8); + bhv_constant(MODEL_LLL_BOWSER_PIECE_9); + bhv_constant(MODEL_LLL_BOWSER_PIECE_10); + bhv_constant(MODEL_LLL_BOWSER_PIECE_11); + bhv_constant(MODEL_LLL_BOWSER_PIECE_12); + bhv_constant(MODEL_LLL_BOWSER_PIECE_13); + bhv_constant(MODEL_LLL_BOWSER_PIECE_14); + bhv_constant(MODEL_LLL_MOVING_OCTAGONAL_MESH_PLATFORM); + bhv_constant(MODEL_LLL_SINKING_ROCK_BLOCK); + bhv_constant(MODEL_LLL_ROLLING_LOG); + bhv_constant(MODEL_LLL_WOOD_BRIDGE); + bhv_constant(MODEL_LLL_LARGE_WOOD_BRIDGE); + bhv_constant(MODEL_LLL_FALLING_PLATFORM); + bhv_constant(MODEL_LLL_LARGE_FALLING_PLATFORM); + bhv_constant(MODEL_LLL_VOLCANO_FALLING_TRAP); + bhv_constant(MODEL_DDD_BOWSER_SUB_DOOR); + bhv_constant(MODEL_DDD_BOWSER_SUB); + bhv_constant(MODEL_DDD_POLE); + bhv_constant(MODEL_WF_BREAKABLE_WALL_RIGHT); + bhv_constant(MODEL_WF_BREAKABLE_WALL_LEFT); + bhv_constant(MODEL_WF_KICKABLE_BOARD); + bhv_constant(MODEL_WF_TOWER_DOOR); + bhv_constant(MODEL_WF_KICKABLE_BOARD_FELLED); + bhv_constant(MODEL_CASTLE_GROUNDS_VCUTM_GRILL); + bhv_constant(MODEL_CASTLE_GROUNDS_FLAG); + bhv_constant(MODEL_CASTLE_GROUNDS_CANNON_GRILL); + bhv_constant(MODEL_BOWSER_2_TILTING_ARENA); + bhv_constant(MODEL_BOWSER_3_FALLING_PLATFORM_1); + bhv_constant(MODEL_BOWSER_3_FALLING_PLATFORM_2); + bhv_constant(MODEL_BOWSER_3_FALLING_PLATFORM_3); + bhv_constant(MODEL_BOWSER_3_FALLING_PLATFORM_4); + bhv_constant(MODEL_BOWSER_3_FALLING_PLATFORM_5); + bhv_constant(MODEL_BOWSER_3_FALLING_PLATFORM_6); + bhv_constant(MODEL_BOWSER_3_FALLING_PLATFORM_7); + bhv_constant(MODEL_BOWSER_3_FALLING_PLATFORM_8); + bhv_constant(MODEL_BOWSER_3_FALLING_PLATFORM_9); + bhv_constant(MODEL_BOWSER_3_FALLING_PLATFORM_10); + bhv_constant(MODEL_TTM_ROLLING_LOG); + bhv_constant(MODEL_TTM_STAR_CAGE); + bhv_constant(MODEL_TTM_BLUE_SMILEY); + bhv_constant(MODEL_TTM_YELLOW_SMILEY); + bhv_constant(MODEL_TTM_STAR_SMILEY); + bhv_constant(MODEL_TTM_MOON_SMILEY); + bhv_constant(MODEL_BULLET_BILL); + bhv_constant(MODEL_YELLOW_SPHERE); + bhv_constant(MODEL_HOOT); + bhv_constant(MODEL_YOSHI_EGG); + bhv_constant(MODEL_THWOMP); + bhv_constant(MODEL_HEAVE_HO); + bhv_constant(MODEL_BLARGG); + bhv_constant(MODEL_BULLY); + bhv_constant(MODEL_BULLY_BOSS); + bhv_constant(MODEL_WATER_BOMB); + bhv_constant(MODEL_WATER_BOMB_SHADOW); + bhv_constant(MODEL_KING_BOBOMB); + bhv_constant(MODEL_MANTA_RAY); + bhv_constant(MODEL_UNAGI); + bhv_constant(MODEL_SUSHI); + bhv_constant(MODEL_DL_WHIRLPOOL); + bhv_constant(MODEL_CLAM_SHELL); + bhv_constant(MODEL_POKEY_HEAD); + bhv_constant(MODEL_POKEY_BODY_PART); + bhv_constant(MODEL_TWEESTER); + bhv_constant(MODEL_KLEPTO); + bhv_constant(MODEL_EYEROK_LEFT_HAND); + bhv_constant(MODEL_EYEROK_RIGHT_HAND); + bhv_constant(MODEL_DL_MONTY_MOLE_HOLE); + bhv_constant(MODEL_MONTY_MOLE); + bhv_constant(MODEL_UKIKI); + bhv_constant(MODEL_FWOOSH); + bhv_constant(MODEL_SPINDRIFT); + bhv_constant(MODEL_MR_BLIZZARD_HIDDEN); + bhv_constant(MODEL_MR_BLIZZARD); + bhv_constant(MODEL_PENGUIN); + bhv_constant(MODEL_CAP_SWITCH_EXCLAMATION); + bhv_constant(MODEL_CAP_SWITCH); + bhv_constant(MODEL_CAP_SWITCH_BASE); + bhv_constant(MODEL_BOO); + bhv_constant(MODEL_BETA_BOO_KEY); + bhv_constant(MODEL_HAUNTED_CHAIR); + bhv_constant(MODEL_MAD_PIANO); + bhv_constant(MODEL_BOOKEND_PART); + bhv_constant(MODEL_BOOKEND); + bhv_constant(MODEL_HAUNTED_CAGE); + bhv_constant(MODEL_BIRDS); + bhv_constant(MODEL_YOSHI); + bhv_constant(MODEL_ENEMY_LAKITU); + bhv_constant(MODEL_SPINY_BALL); + bhv_constant(MODEL_SPINY); + bhv_constant(MODEL_WIGGLER_HEAD); + bhv_constant(MODEL_WIGGLER_BODY); + bhv_constant(MODEL_BUBBA); + bhv_constant(MODEL_UNKNOWN_54); + bhv_constant(MODEL_UNKNOWN_58); + bhv_constant(MODEL_BOWSER); + bhv_constant(MODEL_BOWSER_BOMB_CHILD_OBJ); + bhv_constant(MODEL_BOWSER_SMOKE); + bhv_constant(MODEL_BOWSER_FLAMES); + bhv_constant(MODEL_BOWSER_WAVE); + bhv_constant(MODEL_BOWSER2); + bhv_constant(MODEL_BUB); + bhv_constant(MODEL_TREASURE_CHEST_BASE); + bhv_constant(MODEL_TREASURE_CHEST_LID); + bhv_constant(MODEL_CYAN_FISH); + bhv_constant(MODEL_WATER_RING); + bhv_constant(MODEL_SKEETER); + bhv_constant(MODEL_PIRANHA_PLANT); + bhv_constant(MODEL_WHOMP); + bhv_constant(MODEL_KOOPA_WITH_SHELL); + bhv_constant(MODEL_METALLIC_BALL); + bhv_constant(MODEL_CHAIN_CHOMP); + bhv_constant(MODEL_KOOPA_FLAG); + bhv_constant(MODEL_WOODEN_POST); + bhv_constant(MODEL_MIPS); + bhv_constant(MODEL_BOO_CASTLE); + bhv_constant(MODEL_LAKITU); + bhv_constant(MODEL_CHILL_BULLY); + bhv_constant(MODEL_BIG_CHILL_BULLY); + bhv_constant(MODEL_MONEYBAG); + bhv_constant(MODEL_SWOOP); + bhv_constant(MODEL_SCUTTLEBUG); + bhv_constant(MODEL_MR_I_IRIS); + bhv_constant(MODEL_MR_I); + bhv_constant(MODEL_DORRIE); + bhv_constant(MODEL_YELLOW_COIN); + bhv_constant(MODEL_YELLOW_COIN_NO_SHADOW); + bhv_constant(MODEL_BLUE_COIN); + bhv_constant(MODEL_BLUE_COIN_NO_SHADOW); + bhv_constant(MODEL_HEART); + bhv_constant(MODEL_TRANSPARENT_STAR); + bhv_constant(MODEL_STAR); + bhv_constant(MODEL_TTM_SLIDE_EXIT_PODIUM); + bhv_constant(MODEL_WOODEN_SIGNPOST); + bhv_constant(MODEL_UNKNOWN_7D); + bhv_constant(MODEL_CANNON_BARREL); + bhv_constant(MODEL_CANNON_BASE); + bhv_constant(MODEL_BREAKABLE_BOX); + bhv_constant(MODEL_BREAKABLE_BOX_SMALL); + bhv_constant(MODEL_EXCLAMATION_BOX_OUTLINE); + bhv_constant(MODEL_EXCLAMATION_POINT); + bhv_constant(MODEL_MARIOS_WINGED_METAL_CAP); + bhv_constant(MODEL_MARIOS_METAL_CAP); + bhv_constant(MODEL_MARIOS_WING_CAP); + bhv_constant(MODEL_MARIOS_CAP); + bhv_constant(MODEL_EXCLAMATION_BOX); + bhv_constant(MODEL_DIRT_ANIMATION); + bhv_constant(MODEL_CARTOON_STAR); + bhv_constant(MODEL_BLUE_COIN_SWITCH); + bhv_constant(MODEL_MIST); + bhv_constant(MODEL_SPARKLES_ANIMATION); + bhv_constant(MODEL_RED_FLAME); + bhv_constant(MODEL_BLUE_FLAME); + bhv_constant(MODEL_BURN_SMOKE); + bhv_constant(MODEL_SPARKLES); + bhv_constant(MODEL_SMOKE); + bhv_constant(MODEL_BURN_SMOKE_UNUSED); + bhv_constant(MODEL_WHITE_PARTICLE_DL); + bhv_constant(MODEL_SAND_DUST); + bhv_constant(MODEL_WHITE_PARTICLE); + bhv_constant(MODEL_PEBBLE); + bhv_constant(MODEL_LEAVES); + bhv_constant(MODEL_WAVE_TRAIL); + bhv_constant(MODEL_WHITE_PARTICLE_SMALL); + bhv_constant(MODEL_SMALL_WATER_SPLASH); + bhv_constant(MODEL_IDLE_WATER_WAVE); + bhv_constant(MODEL_WATER_SPLASH); + bhv_constant(MODEL_BUBBLE); + bhv_constant(MODEL_PURPLE_MARBLE); + bhv_constant(MODEL_UNKNOWN_AC); + bhv_constant(MODEL_WF_SLIDING_PLATFORM); + bhv_constant(MODEL_WF_SMALL_BOMP); + bhv_constant(MODEL_WF_ROTATING_WOODEN_PLATFORM); + bhv_constant(MODEL_WF_TUMBLING_BRIDGE_PART); + bhv_constant(MODEL_WF_LARGE_BOMP); + bhv_constant(MODEL_WF_TUMBLING_BRIDGE); + bhv_constant(MODEL_BOWSER_BOMB); + bhv_constant(MODEL_WATER_MINE); + bhv_constant(MODEL_BOWLING_BALL); + bhv_constant(MODEL_TRAMPOLINE); + bhv_constant(MODEL_TRAMPOLINE_CENTER); + bhv_constant(MODEL_TRAMPOLINE_BASE); + bhv_constant(MODEL_UNKNOWN_B8); + bhv_constant(MODEL_FISH); + bhv_constant(MODEL_FISH_SHADOW); + bhv_constant(MODEL_BUTTERFLY); + bhv_constant(MODEL_BLACK_BOBOMB); + bhv_constant(MODEL_KOOPA_SHELL); + bhv_constant(MODEL_KOOPA_WITHOUT_SHELL); + bhv_constant(MODEL_GOOMBA); + bhv_constant(MODEL_SEAWEED); + bhv_constant(MODEL_AMP); + bhv_constant(MODEL_BOBOMB_BUDDY); + bhv_constant(MODEL_SSL_TOX_BOX); + bhv_constant(MODEL_BOWSER_KEY_CUTSCENE); + bhv_constant(MODEL_DL_CANNON_LID); + bhv_constant(MODEL_CHECKERBOARD_PLATFORM); + bhv_constant(MODEL_RED_FLAME_SHADOW); + bhv_constant(MODEL_BOWSER_KEY); + bhv_constant(MODEL_EXPLOSION); + bhv_constant(MODEL_SNUFIT); + bhv_constant(MODEL_PURPLE_SWITCH); + bhv_constant(MODEL_CASTLE_STAR_DOOR_30_STARS); + bhv_constant(MODEL_CASTLE_STAR_DOOR_50_STARS); + bhv_constant(MODEL_CCM_SNOWMAN_BASE); + bhv_constant(MODEL_1UP); + bhv_constant(MODEL_CASTLE_STAR_DOOR_8_STARS); + bhv_constant(MODEL_CASTLE_STAR_DOOR_70_STARS); + bhv_constant(MODEL_RED_COIN); + bhv_constant(MODEL_RED_COIN_NO_SHADOW); + bhv_constant(MODEL_METAL_BOX); + bhv_constant(MODEL_METAL_BOX_DL); + bhv_constant(MODEL_NUMBER); + bhv_constant(MODEL_FLYGUY); + bhv_constant(MODEL_TOAD); + bhv_constant(MODEL_PEACH); + bhv_constant(MODEL_CHUCKYA); + bhv_constant(MODEL_WHITE_PUFF); + bhv_constant(MODEL_TRAJECTORY_MARKER_BALL); + bhv_constant(MODEL_MAIN_MENU_MARIO_SAVE_BUTTON); + bhv_constant(MODEL_MAIN_MENU_RED_ERASE_BUTTON); + bhv_constant(MODEL_MAIN_MENU_BLUE_COPY_BUTTON); + bhv_constant(MODEL_MAIN_MENU_YELLOW_FILE_BUTTON); + bhv_constant(MODEL_MAIN_MENU_GREEN_SCORE_BUTTON); + bhv_constant(MODEL_MAIN_MENU_MARIO_SAVE_BUTTON_FADE); + bhv_constant(MODEL_MAIN_MENU_MARIO_NEW_BUTTON); + bhv_constant(MODEL_MAIN_MENU_MARIO_NEW_BUTTON_FADE); + bhv_constant(MODEL_MAIN_MENU_PURPLE_SOUND_BUTTON); + bhv_constant(MODEL_MAIN_MENU_GENERIC_BUTTON); + bhv_constant(MODEL_LLL_ROTATING_HEXAGONAL_PLATFORM); + bhv_constant(MODEL_WF_GIANT_POLE); + bhv_constant(MODEL_WF_ROTATING_PLATFORM); + bhv_constant(MODEL_BITDW_WARP_PIPE); + bhv_constant(MODEL_THI_WARP_PIPE); + bhv_constant(MODEL_VCUTM_WARP_PIPE); + bhv_constant(MODEL_CASTLE_GROUNDS_WARP_PIPE); + bhv_constant(MODEL_BUBBLE_PLAYER); + bhv_constant(MODEL_LUIGI); + bhv_constant(MODEL_LUIGIS_CAP); + bhv_constant(MODEL_LUIGIS_METAL_CAP); + bhv_constant(MODEL_LUIGIS_WING_CAP); + bhv_constant(MODEL_LUIGIS_WINGED_METAL_CAP); + bhv_constant(MODEL_TOAD_PLAYER); + bhv_constant(MODEL_TOADS_CAP); + bhv_constant(MODEL_TOADS_METAL_CAP); + bhv_constant(MODEL_TOADS_WING_CAP); + bhv_constant(MODEL_WALUIGI); + bhv_constant(MODEL_WALUIGIS_CAP); + bhv_constant(MODEL_WALUIGIS_METAL_CAP); + bhv_constant(MODEL_WALUIGIS_WING_CAP); + bhv_constant(MODEL_WALUIGIS_WINGED_METAL_CAP); + bhv_constant(MODEL_WARIO); + bhv_constant(MODEL_WARIOS_CAP); + bhv_constant(MODEL_WARIOS_METAL_CAP); + bhv_constant(MODEL_WARIOS_WING_CAP); + bhv_constant(MODEL_WARIOS_WINGED_METAL_CAP); + bhv_constant(MODEL_ERROR_MODEL); + + + // Object Fields + bhv_constant(oFlags); + bhv_constant(oDialogResponse); + bhv_constant(oDialogState); + bhv_constant(oUnk94); + bhv_constant(oSyncID); + bhv_constant(oIntangibleTimer); + bhv_constant(oPosX); + bhv_constant(oPosY); + bhv_constant(oPosZ); + bhv_constant(oVelX); + bhv_constant(oVelY); + bhv_constant(oVelZ); + bhv_constant(oForwardVel); + bhv_constant(oForwardVelS32); + bhv_constant(oUnkBC); + bhv_constant(oUnkC0); + bhv_constant(oMoveAnglePitch); + bhv_constant(oMoveAngleYaw); + bhv_constant(oMoveAngleRoll); + bhv_constant(oFaceAnglePitch); + bhv_constant(oFaceAngleYaw); + bhv_constant(oFaceAngleRoll); + bhv_constant(oGraphYOffset); + bhv_constant(oActiveParticleFlags); + bhv_constant(oGravity); + bhv_constant(oFloorHeight); + bhv_constant(oMoveFlags); + bhv_constant(oAnimState); + bhv_constant(oAngleVelPitch); + bhv_constant(oAngleVelYaw); + bhv_constant(oAngleVelRoll); + bhv_constant(oAnimations); + bhv_constant(oHeldState); + bhv_constant(oWallHitboxRadius); + bhv_constant(oDragStrength); + bhv_constant(oInteractType); + bhv_constant(oInteractStatus); + bhv_constant(oParentRelativePosX); + bhv_constant(oParentRelativePosY); + bhv_constant(oParentRelativePosZ); + bhv_constant(oBehParams2ndByte); + bhv_constant(oAction); + bhv_constant(oSubAction); + bhv_constant(oTimer); + bhv_constant(oBounciness); + bhv_constant(oDistanceToMario); + bhv_constant(oAngleToMario); + bhv_constant(oHomeX); + bhv_constant(oHomeY); + bhv_constant(oHomeZ); + bhv_constant(oFriction); + bhv_constant(oBuoyancy); + bhv_constant(oSoundStateID); + bhv_constant(oOpacity); + bhv_constant(oDamageOrCoinValue); + bhv_constant(oHealth); + bhv_constant(oBehParams); + bhv_constant(oPrevAction); + bhv_constant(oInteractionSubtype); + bhv_constant(oCollisionDistance); + bhv_constant(oNumLootCoins); + bhv_constant(oDrawingDistance); + bhv_constant(oRoom); + bhv_constant(oSyncDeath); + bhv_constant(oUnk1A8); + bhv_constant(oWallAngle); + bhv_constant(oFloorType); + bhv_constant(oFloorRoom); + bhv_constant(oAngleToHome); + bhv_constant(oFloor); + bhv_constant(oDeathSound); + bhv_constant(oPathedStartWaypoint); + bhv_constant(oPathedPrevWaypoint); + bhv_constant(oPathedPrevWaypointFlags); + bhv_constant(oPathedTargetPitch); + bhv_constant(oPathedTargetYaw); + bhv_constant(oMacroUnk108); + bhv_constant(oMacroUnk10C); + bhv_constant(oMacroUnk110); + + /* 1-UpHidden */ + bhv_constant(o1UpHiddenUnkF4); + bhv_constant(o1UpForceSpawn); + + /* ActivatedBackandForthPlatform */ + bhv_constant(oActivatedBackAndForthPlatformMaxOffset); + bhv_constant(oActivatedBackAndForthPlatformOffset); + bhv_constant(oActivatedBackAndForthPlatformVel); + bhv_constant(oActivatedBackAndForthPlatformCountdown); + bhv_constant(oActivatedBackAndForthPlatformStartYaw); + bhv_constant(oActivatedBackAndForthPlatformVertical); + bhv_constant(oActivatedBackAndForthPlatformFlipRotation); + + /* Amp */ + bhv_constant(oAmpRadiusOfRotation); + bhv_constant(oAmpYPhase); + + /* HomingAmp */ + bhv_constant(oHomingAmpLockedOn); + bhv_constant(oHomingAmpAvgY); + + /* ArrowLift */ + bhv_constant(oArrowLiftDisplacement); + bhv_constant(oArrowLiftUnk100); + + /* Back-and-ForthPlatform */ + bhv_constant(oBackAndForthPlatformDirection); + bhv_constant(oBackAndForthPlatformPathLength); + bhv_constant(oBackAndForthPlatformDistance); + bhv_constant(oBackAndForthPlatformVel); + + /* Bird */ + bhv_constant(oBirdSpeed); + bhv_constant(oBirdTargetPitch); + bhv_constant(oBirdTargetYaw); + + /* BirdChirpChirp */ + bhv_constant(oBirdChirpChirpUnkF4); + + /* EndBirds */ + bhv_constant(oEndBirdUnk104); + + /* HiddenBlueCoin */ + bhv_constant(oHiddenBlueCoinSwitch); + + /* Bob-omb */ + bhv_constant(oBobombBlinkTimer); + bhv_constant(oBobombFuseLit); + bhv_constant(oBobombFuseTimer); + + /* Bob-ombBuddy */ + bhv_constant(oBobombBuddyBlinkTimer); + bhv_constant(oBobombBuddyHasTalkedToMario); + bhv_constant(oBobombBuddyRole); + bhv_constant(oBobombBuddyCannonStatus); + bhv_constant(oBobombBuddyPosXCopy); + bhv_constant(oBobombBuddyPosYCopy); + bhv_constant(oBobombBuddyPosZCopy); + + /* Bob-ombExplosionBubble */ + bhv_constant(oBobombExpBubGfxScaleFacX); + bhv_constant(oBobombExpBubGfxScaleFacY); + bhv_constant(oBobombExpBubGfxExpRateX); + bhv_constant(oBobombExpBubGfxExpRateY); + + /* Bomp(Small) */ + bhv_constant(oSmallBompInitX); + + /* Boo */ + bhv_constant(oBooDeathStatus); + bhv_constant(oBooTargetOpacity); + bhv_constant(oBooBaseScale); + bhv_constant(oBooOscillationTimer); + bhv_constant(oBooMoveYawDuringHit); + bhv_constant(oBooMoveYawBeforeHit); + bhv_constant(oBooParentBigBoo); + bhv_constant(oBooNegatedAggressiveness); + bhv_constant(oBooInitialMoveYaw); + bhv_constant(oBooTurningSpeed); + + /* BigBoo */ + bhv_constant(oBigBooNumMinionBoosKilled); + + /* Bookend */ + bhv_constant(oBookendUnkF4); + bhv_constant(oBookendUnkF8); + + /* BookSwitch */ + bhv_constant(oBookSwitchUnkF4); + + /* BookSwitchManager */ + bhv_constant(oBookSwitchManagerUnkF4); + bhv_constant(oBookSwitchManagerUnkF8); + + /* HauntedBookshelf */ + bhv_constant(oHauntedBookshelfShouldOpen); + + /* BouncingFireBall */ + bhv_constant(oBouncingFireBallUnkF4); + + /* BowlingBall */ + bhv_constant(oBowlingBallTargetYaw); + //-reservedforpathing + + /* BowlingBallSpawner(Generic) */ + bhv_constant(oBBallSpawnerMaxSpawnDist); + bhv_constant(oBBallSpawnerSpawnOdds); + bhv_constant(oBBallSpawnerPeriodMinus1); + + /* Bowser */ + bhv_constant(oBowserUnk88); + bhv_constant(oBowserUnkF4); + bhv_constant(oBowserUnkF8); + bhv_constant(oBowserDistToCentre); + bhv_constant(oBowserUnk106); + bhv_constant(oBowserUnk108); + bhv_constant(oBowserHeldAnglePitch); + bhv_constant(oBowserHeldAngleVelYaw); + bhv_constant(oBowserUnk10E); + bhv_constant(oBowserUnk110); + bhv_constant(oBowserAngleToCentre); + bhv_constant(oBowserUnk1AC); + bhv_constant(oBowserUnk1AE); + bhv_constant(oBowserEyesShut); + bhv_constant(oBowserUnk1B2); + + /* BowserShockwave */ + bhv_constant(oBowserShockWaveUnkF4); + + /* BlackSmokeBowser */ + bhv_constant(oBlackSmokeBowserUnkF4); + + /* BowserKeyCutscene */ + bhv_constant(oBowserKeyScale); + + /* BowserPuzzle */ + bhv_constant(oBowserPuzzleCompletionFlags); + + /* BowserPuzzlePiece */ + bhv_constant(oBowserPuzzlePieceOffsetX); + bhv_constant(oBowserPuzzlePieceOffsetY); + bhv_constant(oBowserPuzzlePieceOffsetZ); + bhv_constant(oBowserPuzzlePieceContinuePerformingAction); + bhv_constant(oBowserPuzzlePieceActionList); + bhv_constant(oBowserPuzzlePieceNextAction); + + /* Bubba */ + bhv_constant(oBubbaUnkF4); + bhv_constant(oBubbaUnkF8); + bhv_constant(oBubbaUnkFC); + bhv_constant(oBubbaUnk100); + bhv_constant(oBubbaUnk104); + bhv_constant(oBubbaUnk108); + bhv_constant(oBubbaUnk10C); + bhv_constant(oBubbaUnk1AC); + bhv_constant(oBubbaUnk1AE); + bhv_constant(oBubbaUnk1B0); + bhv_constant(oBubbaUnk1B2); + + /* BulletBill */ + bhv_constant(oBulletBillInitialMoveYaw); + + /* Bully(allvariants) */ + bhv_constant(oBullySubtype); + bhv_constant(oBullyPrevX); + bhv_constant(oBullyPrevY); + bhv_constant(oBullyPrevZ); + bhv_constant(oBullyKBTimerAndMinionKOCounter); + bhv_constant(oBullyMarioCollisionAngle); + bhv_constant(oBullyLastNetworkPlayerIndex); + + /* Butterfly */ + bhv_constant(oButterflyYPhase); + + /* TripletButterfly */ + bhv_constant(oTripletButterflyScale); + bhv_constant(oTripletButterflySpeed); + bhv_constant(oTripletButterflyBaseYaw); + bhv_constant(oTripletButterflyTargetPitch); + bhv_constant(oTripletButterflyTargetYaw); + bhv_constant(oTripletButterflyType); + bhv_constant(oTripletButterflyModel); + bhv_constant(oTripletButterflySelectedButterfly); + bhv_constant(oTripletButterflyScalePhase); + + /* Cannon */ + bhv_constant(oCannonUnkF4); + bhv_constant(oCannonUnkF8); + bhv_constant(oCannonUnk10C); + bhv_constant(oCannonPlayerIndex); + + /* Cap */ + bhv_constant(oCapUnkF4); + bhv_constant(oCapUnkF8); + + /* ChainChomp */ + bhv_constant(oChainChompSegments); + bhv_constant(oChainChompMaxDistFromPivotPerChainPart); + bhv_constant(oChainChompMaxDistBetweenChainParts); + bhv_constant(oChainChompDistToPivot); + bhv_constant(oChainChompUnk104); + bhv_constant(oChainChompRestrictedByChain); + bhv_constant(oChainChompTargetPitch); + bhv_constant(oChainChompNumLunges); + bhv_constant(oChainChompReleaseStatus); + bhv_constant(oChainChompHitGate); + + /* CheckerboardPlatform */ + bhv_constant(oCheckerBoardPlatformUnkF8); + bhv_constant(oCheckerBoardPlatformUnkFC); + bhv_constant(oCheckerBoardPlatformUnk1AC); + + /* CheepCheep */ + bhv_constant(oCheepCheepUnkF4); + bhv_constant(oCheepCheepUnkF8); + bhv_constant(oCheepCheepUnkFC); + bhv_constant(oCheepCheepUnk104); + bhv_constant(oCheepCheepUnk108); + + /* Chuckya */ + bhv_constant(oChuckyaUnk88); + bhv_constant(oChuckyaUnkF8); + bhv_constant(oChuckyaUnkFC); + bhv_constant(oChuckyaUnk100); + + /* Clam */ + bhv_constant(oClamUnkF4); + + /* Cloud */ + bhv_constant(oCloudCenterX); + bhv_constant(oCloudCenterY); + bhv_constant(oCloudBlowing); + bhv_constant(oCloudGrowSpeed); + bhv_constant(oCloudFwooshMovementRadius); + + /* Coin */ + bhv_constant(oCoinUnkF4); + bhv_constant(oCoinUnkF8); + bhv_constant(oCoinUnk110); +#ifndef VERSION_JP + bhv_constant(oCoinUnk1B0); +#endif + + /* CollisionParticle */ + bhv_constant(oCollisionParticleUnkF4); + + /* ControllablePlatform */ + bhv_constant(oControllablePlatformUnkF8); + bhv_constant(oControllablePlatformUnkFC); + bhv_constant(oControllablePlatformUnk100); + + /* BreakableBoxSmall(SmallCorkBox) */ + bhv_constant(oBreakableBoxSmallReleased); + bhv_constant(oBreakableBoxSmallFramesSinceReleased); + + /* JumpingBox(CrazyBox) */ + bhv_constant(oJumpingBoxUnkF4); + bhv_constant(oJumpingBoxUnkF8); + + /* RRCruiserWing */ + bhv_constant(oRRCruiserWingUnkF4); + bhv_constant(oRRCruiserWingUnkF8); + + /* DonutPlatformSpawner */ + bhv_constant(oDonutPlatformSpawnerSpawnedPlatforms); + + /* Door */ + bhv_constant(oDoorUnk88); + bhv_constant(oDoorUnkF8); + bhv_constant(oDoorUnkFC); + bhv_constant(oDoorUnk100); + + /* Dorrie */ + bhv_constant(oDorrieDistToHome); + bhv_constant(oDorrieOffsetY); + bhv_constant(oDorrieVelY); + bhv_constant(oDorrieForwardDistToMario); + bhv_constant(oDorrieYawVel); + bhv_constant(oDorrieLiftingMario); + bhv_constant(oDorrieGroundPounded); + bhv_constant(oDorrieAngleToHome); + bhv_constant(oDorrieNeckAngle); + bhv_constant(oDorrieHeadRaiseSpeed); + + /* Elevator */ + bhv_constant(oElevatorUnkF4); + bhv_constant(oElevatorUnkF8); + bhv_constant(oElevatorUnkFC); + bhv_constant(oElevatorUnk100); + + /* ExclamationBox */ + bhv_constant(oExclamationBoxUnkF4); + bhv_constant(oExclamationBoxUnkF8); + bhv_constant(oExclamationBoxUnkFC); + bhv_constant(oExclamationBoxForce); + + /* EyerokBoss */ + bhv_constant(oEyerokBossNumHands); + bhv_constant(oEyerokBossUnkFC); + bhv_constant(oEyerokBossActiveHand); + bhv_constant(oEyerokBossUnk104); + bhv_constant(oEyerokBossUnk108); + bhv_constant(oEyerokBossUnk10C); + bhv_constant(oEyerokBossUnk110); + bhv_constant(oEyerokBossUnk1AC); + + /* EyerokHand */ + bhv_constant(oEyerokHandWakeUpTimer); + bhv_constant(oEyerokReceivedAttack); + bhv_constant(oEyerokHandUnkFC); + bhv_constant(oEyerokHandUnk100); + bhv_constant(oEyerokHandDead); + + /* FallingPillar */ + bhv_constant(oFallingPillarPitchAcceleration); + + /* FireSpitter */ + bhv_constant(oFireSpitterScaleVel); + bhv_constant(oFireSpitterLastWaterY); + + /* BlueFish */ + bhv_constant(oBlueFishRandomVel); + bhv_constant(oBlueFishRandomTime); + bhv_constant(oBlueFishRandomAngle); + + /* FishGroup */ + bhv_constant(oFishWaterLevel); + bhv_constant(oFishGoalY); + bhv_constant(oFishHeightOffset); + bhv_constant(oFishYawVel); + bhv_constant(oFishRoamDistance); + bhv_constant(oFishGoalVel); + bhv_constant(oFishDepthDistance); + bhv_constant(oFishActiveDistance); + + /* Flame */ + bhv_constant(oFlameScale); + bhv_constant(oFlameSpeedTimerOffset); + bhv_constant(oFlameUnkFC); + bhv_constant(oFlameBowser); + + /* BlueFlame */ + bhv_constant(oBlueFlameNextScale); + + /* SmallPiranhaFlame */ + bhv_constant(oSmallPiranhaFlameStartSpeed); + bhv_constant(oSmallPiranhaFlameEndSpeed); + bhv_constant(oSmallPiranhaFlameModel); + bhv_constant(oSmallPiranhaFlameNextFlameTimer); + bhv_constant(oSmallPiranhaFlameSpeed); + + /* MovingFlame */ + bhv_constant(oMovingFlameTimer); + + /* FlamethrowerFlame */ + bhv_constant(oFlameThowerFlameUnk110); + + /* Flamethrower */ + bhv_constant(oFlameThowerUnk110); + + /* FloatingPlatform */ + bhv_constant(oFloatingPlatformUnkF4); + bhv_constant(oFloatingPlatformUnkF8); + bhv_constant(oFloatingPlatformUnkFC); + bhv_constant(oFloatingPlatformUnk100); + + /* FloorSwitchPressAnimation */ + bhv_constant(oFloorSwitchPressAnimationUnkF4); + bhv_constant(oFloorSwitchPressAnimationUnkF8); + bhv_constant(oFloorSwitchPressAnimationUnkFC); + bhv_constant(oFloorSwitchPressAnimationUnk100); + + /* FlyGuy */ + bhv_constant(oFlyGuyIdleTimer); + bhv_constant(oFlyGuyOscTimer); + bhv_constant(oFlyGuyUnusedJitter); + bhv_constant(oFlyGuyLungeYDecel); + bhv_constant(oFlyGuyLungeTargetPitch); + bhv_constant(oFlyGuyTargetRoll); + bhv_constant(oFlyGuyScaleVel); + + /* GrandStar */ + bhv_constant(oGrandStarUnk108); + + /* HorizontalGrindel */ + bhv_constant(oHorizontalGrindelTargetYaw); + bhv_constant(oHorizontalGrindelDistToHome); + bhv_constant(oHorizontalGrindelOnGround); + + /* Goomba */ + bhv_constant(oGoombaSize); + bhv_constant(oGoombaScale); + bhv_constant(oGoombaWalkTimer); + bhv_constant(oGoombaTargetYaw); + bhv_constant(oGoombaBlinkTimer); + bhv_constant(oGoombaTurningAwayFromWall); + bhv_constant(oGoombaRelativeSpeed); + bhv_constant(oGoombaJumpCooldown); + + /* HauntedChair */ + bhv_constant(oHauntedChairUnkF4); + bhv_constant(oHauntedChairUnkF8); + bhv_constant(oHauntedChairUnkFC); + bhv_constant(oHauntedChairUnk100); + bhv_constant(oHauntedChairUnk104); + + /* Heave-Ho */ + bhv_constant(oHeaveHoUnk88); + bhv_constant(oHeaveHoUnkF4); + + /* HiddenObject */ + bhv_constant(oHiddenObjectUnkF4); + + /* Hoot */ + bhv_constant(oHootAvailability); + bhv_constant(oHootMarioReleaseTime); + + /* HorizontalMovement */ + bhv_constant(oHorizontalMovementUnkF4); + bhv_constant(oHorizontalMovementUnkF8); + bhv_constant(oHorizontalMovementUnk100); + bhv_constant(oHorizontalMovementUnk104); + bhv_constant(oHorizontalMovementUnk108); + + /* KickableBoard */ + bhv_constant(oKickableBoardF4); + bhv_constant(oKickableBoardF8); + + /* KingBob-omb */ + bhv_constant(oKingBobombUnk88); + bhv_constant(oKingBobombUnkF8); + bhv_constant(oKingBobombUnkFC); + bhv_constant(oKingBobombUnk100); + bhv_constant(oKingBobombUnk104); + bhv_constant(oKingBobombUnk108); + + /* Klepto */ + bhv_constant(oKleptoDistanceToTarget); + bhv_constant(oKleptoUnkF8); + bhv_constant(oKleptoUnkFC); + bhv_constant(oKleptoSpeed); + bhv_constant(oKleptoStartPosX); + bhv_constant(oKleptoStartPosY); + bhv_constant(oKleptoStartPosZ); + bhv_constant(oKleptoTimeUntilTargetChange); + bhv_constant(oKleptoTargetNumber); + bhv_constant(oKleptoUnk1AE); + bhv_constant(oKleptoUnk1B0); + bhv_constant(oKleptoYawToTarget); + + /* Koopa */ + bhv_constant(oKoopaAgility); + bhv_constant(oKoopaMovementType); + bhv_constant(oKoopaTargetYaw); + bhv_constant(oKoopaUnshelledTimeUntilTurn); + bhv_constant(oKoopaTurningAwayFromWall); + bhv_constant(oKoopaDistanceToMario); + bhv_constant(oKoopaAngleToMario); + bhv_constant(oKoopaBlinkTimer); + bhv_constant(oKoopaCountdown); + bhv_constant(oKoopaTheQuickRaceIndex); + bhv_constant(oKoopaTheQuickInitTextboxCooldown); + //-forkoopathequickreservedforpathing + + /* KoopaRaceEndpoint */ + bhv_constant(oKoopaRaceEndpointRaceBegun); + bhv_constant(oKoopaRaceEndpointKoopaFinished); + bhv_constant(oKoopaRaceEndpointRaceStatus); + bhv_constant(oKoopaRaceEndpointUnk100); + bhv_constant(oKoopaRaceEndpointRaceEnded); + + /* KoopaShellFlame */ + bhv_constant(oKoopaShellFlameUnkF4); + bhv_constant(oKoopaShellFlameUnkF8); + + /* CameraLakitu */ + bhv_constant(oCameraLakituBlinkTimer); + bhv_constant(oCameraLakituSpeed); + bhv_constant(oCameraLakituCircleRadius); + bhv_constant(oCameraLakituFinishedDialog); +#ifndef VERSION_JP + bhv_constant(oCameraLakituUnk104); +#endif + bhv_constant(oCameraLakituPitchVel); + bhv_constant(oCameraLakituYawVel); + + /* EvilLakitu */ + bhv_constant(oEnemyLakituNumSpinies); + bhv_constant(oEnemyLakituBlinkTimer); + bhv_constant(oEnemyLakituSpinyCooldown); + bhv_constant(oEnemyLakituFaceForwardCountdown); + + /* IntroCutsceneLakitu */ + bhv_constant(oIntroLakituSplineSegmentProgress); + bhv_constant(oIntroLakituSplineSegment); + bhv_constant(oIntroLakituUnk100); + bhv_constant(oIntroLakituUnk104); + bhv_constant(oIntroLakituUnk108); + bhv_constant(oIntroLakituUnk10C); + bhv_constant(oIntroLakituUnk110); + bhv_constant(oIntroLakituCloud); + + /* MainMenuButton */ + bhv_constant(oMenuButtonState); + bhv_constant(oMenuButtonTimer); + bhv_constant(oMenuButtonOrigPosX); + bhv_constant(oMenuButtonOrigPosY); + bhv_constant(oMenuButtonOrigPosZ); + bhv_constant(oMenuButtonScale); + bhv_constant(oMenuButtonActionPhase); + bhv_constant(oMenuButtonIsCustom); + + /* MantaRay */ + bhv_constant(oMantaTargetPitch); + bhv_constant(oMantaTargetYaw); + + /* Merry-Go-Round */ + bhv_constant(oMerryGoRoundStopped); + bhv_constant(oMerryGoRoundMusicShouldPlay); + bhv_constant(oMerryGoRoundMarioIsOutside); + + /* Merry-Go-RoundBooManager */ + bhv_constant(oMerryGoRoundBooManagerNumBoosKilled); + bhv_constant(oMerryGoRoundBooManagerNumBoosSpawned); + + /* Mips */ + bhv_constant(oMipsStarStatus); + bhv_constant(oMipsStartWaypointIndex); + //-reservedforpathing + bhv_constant(oMipsForwardVelocity); + + /* Moneybag */ + bhv_constant(oMoneybagJumpState); + + /* MontyMole */ + bhv_constant(oMontyMoleCurrentHole); + bhv_constant(oMontyMoleHeightRelativeToFloor); + bhv_constant(oMontyMoleHoleX); + bhv_constant(oMontyMoleHoleY); + bhv_constant(oMontyMoleHoleZ); + + /* MontyMoleHole */ + bhv_constant(oMontyMoleHoleCooldown); + + /* Mr.Blizzard */ + bhv_constant(oMrBlizzardScale); + bhv_constant(oMrBlizzardHeldObj); + bhv_constant(oMrBlizzardGraphYVel); + bhv_constant(oMrBlizzardTimer); + bhv_constant(oMrBlizzardDizziness); + bhv_constant(oMrBlizzardChangeInDizziness); + bhv_constant(oMrBlizzardGraphYOffset); + bhv_constant(oMrBlizzardDistFromHome); + bhv_constant(oMrBlizzardTargetMoveYaw); + + /* Mr.I */ + bhv_constant(oMrIUnkF4); + bhv_constant(oMrIUnkFC); + bhv_constant(oMrIUnk100); + bhv_constant(oMrIUnk104); + bhv_constant(oMrIUnk108); + bhv_constant(oMrISize); + bhv_constant(oMrIUnk110); + + /* ObjectRespawner */ + bhv_constant(oRespawnerModelToRespawn); + bhv_constant(oRespawnerMinSpawnDist); + bhv_constant(oRespawnerBehaviorToRespawn); + + /* OpenableGrill */ + bhv_constant(oOpenableGrillUnk88); + bhv_constant(oOpenableGrillUnkF4); + + /* IntroCutscenePeach */ + bhv_constant(oIntroPeachYawFromFocus); + bhv_constant(oIntroPeachPitchFromFocus); + bhv_constant(oIntroPeachDistToCamera); + + /* RacingPenguin */ + bhv_constant(oRacingPenguinInitTextCooldown); + //-reservedforpathing + bhv_constant(oRacingPenguinWeightedNewTargetSpeed); + bhv_constant(oRacingPenguinFinalTextbox); + bhv_constant(oRacingPenguinMarioWon); + bhv_constant(oRacingPenguinReachedBottom); + bhv_constant(oRacingPenguinMarioCheated); + + /* SmallPenguin */ + bhv_constant(oSmallPenguinUnk88); + bhv_constant(oSmallPenguinUnk100); + bhv_constant(oSmallPenguinUnk104); + bhv_constant(oSmallPenguinUnk108); + bhv_constant(oSmallPenguinUnk110); + + /* SLWalkingPenguin */ + bhv_constant(oSLWalkingPenguinWindCollisionXPos); + bhv_constant(oSLWalkingPenguinWindCollisionZPos); + bhv_constant(oSLWalkingPenguinCurStep); + bhv_constant(oSLWalkingPenguinCurStepTimer); + + /* PiranhaPlant */ + bhv_constant(oPiranhaPlantSleepMusicState); + bhv_constant(oPiranhaPlantScale); + + /* FirePiranhaPlant */ + bhv_constant(oFirePiranhaPlantNeutralScale); + bhv_constant(oFirePiranhaPlantScale); + bhv_constant(oFirePiranhaPlantActive); + bhv_constant(oFirePiranhaPlantDeathSpinTimer); + bhv_constant(oFirePiranhaPlantDeathSpinVel); + + /* Pitoune */ + bhv_constant(oPitouneUnkF4); + bhv_constant(oPitouneUnkF8); + bhv_constant(oPitouneUnkFC); + + /* Platform */ + bhv_constant(oPlatformTimer); + bhv_constant(oPlatformUnkF8); + bhv_constant(oPlatformUnkFC); + bhv_constant(oPlatformUnk10C); + bhv_constant(oPlatformUnk110); + + /* PlatformonTracks */ + bhv_constant(oPlatformOnTrackBaseBallIndex); + bhv_constant(oPlatformOnTrackDistMovedSinceLastBall); + bhv_constant(oPlatformOnTrackSkiLiftRollVel); + bhv_constant(oPlatformOnTrackStartWaypoint); + bhv_constant(oPlatformOnTrackPrevWaypoint); + bhv_constant(oPlatformOnTrackPrevWaypointFlags); + bhv_constant(oPlatformOnTrackPitch); + bhv_constant(oPlatformOnTrackYaw); + bhv_constant(oPlatformOnTrackOffsetY); + bhv_constant(oPlatformOnTrackIsNotSkiLift); + bhv_constant(oPlatformOnTrackIsNotHMC); + bhv_constant(oPlatformOnTrackType); + bhv_constant(oPlatformOnTrackWasStoodOn); + + /* PlatformSpawner */ + bhv_constant(oPlatformSpawnerUnkF4); + bhv_constant(oPlatformSpawnerUnkF8); + bhv_constant(oPlatformSpawnerUnkFC); + bhv_constant(oPlatformSpawnerUnk100); + bhv_constant(oPlatformSpawnerUnk104); + bhv_constant(oPlatformSpawnerUnk108); + + /* Pokey */ + bhv_constant(oPokeyAliveBodyPartFlags); + bhv_constant(oPokeyNumAliveBodyParts); + bhv_constant(oPokeyBottomBodyPartSize); + bhv_constant(oPokeyHeadWasKilled); + bhv_constant(oPokeyTargetYaw); + bhv_constant(oPokeyChangeTargetTimer); + bhv_constant(oPokeyTurningAwayFromWall); + + /* PokeyBodyPart */ + bhv_constant(oPokeyBodyPartDeathDelayAfterHeadKilled); + bhv_constant(oPokeyBodyPartBlinkTimer); + + /* DDDPole */ + bhv_constant(oDDDPoleVel); + bhv_constant(oDDDPoleMaxOffset); + bhv_constant(oDDDPoleOffset); + + /* PyramidTop */ + bhv_constant(oPyramidTopPillarsTouched); + + /* PyramidTopExplosion */ + bhv_constant(oPyramidTopFragmentsScale); + + /* RollingLog */ + bhv_constant(oRollingLogUnkF4); + + /* LllRotatingHexFlame */ + bhv_constant(oLllRotatingHexFlameUnkF4); + bhv_constant(oLllRotatingHexFlameUnkF8); + bhv_constant(oLllRotatingHexFlameUnkFC); + + /* Scuttlebug */ + bhv_constant(oScuttlebugUnkF4); + bhv_constant(oScuttlebugUnkF8); + bhv_constant(oScuttlebugUnkFC); + + /* ScuttlebugSpawner */ + bhv_constant(oScuttlebugSpawnerUnk88); + bhv_constant(oScuttlebugSpawnerUnkF4); + + /* SeesawPlatform */ + bhv_constant(oSeesawPlatformPitchVel); + + /* ShipPart3 */ + bhv_constant(oShipPart3UnkF4); + bhv_constant(oShipPart3UnkF8); + + /* SinkWhenSteppedOn */ + bhv_constant(oSinkWhenSteppedOnUnk104); + bhv_constant(oSinkWhenSteppedOnUnk108); + + /* Skeeter */ + bhv_constant(oSkeeterTargetAngle); + bhv_constant(oSkeeterUnkF8); + bhv_constant(oSkeeterUnkFC); + bhv_constant(oSkeeterWaitTime); + bhv_constant(oSkeeterLastWaterY); + bhv_constant(oSkeeterUnk1AC); + + /* JrbSlidingBox */ + bhv_constant(oJrbSlidingBoxUnkF4); + bhv_constant(oJrbSlidingBoxUnkF8); + bhv_constant(oJrbSlidingBoxUnkFC); + + /* WFSlidingBrickPlatform */ + bhv_constant(oWFSlidBrickPtfmMovVel); + + /* Smoke */ + bhv_constant(oSmokeTimer); + + /* Snowman'sBottom */ + bhv_constant(oSnowmansBottomUnkF4); + bhv_constant(oSnowmansBottomUnkF8); + bhv_constant(oSnowmansBottomUnk1AC); + //-reservedforpathing + + /* Snowman'sHead */ + bhv_constant(oSnowmansHeadUnkF4); + + /* SnowmanWindBlowing */ + bhv_constant(oSLSnowmanWindOriginalYaw); + + /* Snufit */ + bhv_constant(oSnufitRecoil); + bhv_constant(oSnufitScale); + bhv_constant(oSnufitCircularPeriod); + bhv_constant(oSnufitBodyScalePeriod); + bhv_constant(oSnufitBodyBaseScale); + bhv_constant(oSnufitBullets); + bhv_constant(oSnufitXOffset); + bhv_constant(oSnufitYOffset); + bhv_constant(oSnufitZOffset); + bhv_constant(oSnufitBodyScale); + + /* Spindel */ + bhv_constant(oSpindelUnkF4); + bhv_constant(oSpindelUnkF8); + + /* SpinningHeart */ + bhv_constant(oSpinningHeartTotalSpin); + bhv_constant(oSpinningHeartPlayedSound); + + /* Spiny */ + bhv_constant(oSpinyTimeUntilTurn); + bhv_constant(oSpinyTargetYaw); + bhv_constant(oSpinyTurningAwayFromWall); + + /* SoundEffect */ + bhv_constant(oSoundEffectUnkF4); + + /* StarSpawn */ + bhv_constant(oStarSpawnDisFromHome); + bhv_constant(oStarSpawnUnkFC); + bhv_constant(oStarSpawnExtCutsceneFlags); + + /* HiddenStar */ + //Secrets/RedCoins + bhv_constant(oHiddenStarTriggerCounter); + bhv_constant(oHiddenStarLastInteractedObject); + + //Overallverydifficulttodetermineusage,mostlystubbedcode. + /* SparkleSpawnStar */ + bhv_constant(oSparkleSpawnUnk1B0); + + /* SealedDoorStar */ + bhv_constant(oUnlockDoorStarState); + bhv_constant(oUnlockDoorStarTimer); + bhv_constant(oUnlockDoorStarYawVel); + + /* CelebrationStar */ + bhv_constant(oCelebStarUnkF4); + bhv_constant(oCelebStarDiameterOfRotation); + + /* StarSelector */ + bhv_constant(oStarSelectorType); + bhv_constant(oStarSelectorTimer); + bhv_constant(oStarSelectorSize); + + /* SushiShark */ + bhv_constant(oSushiSharkUnkF4); + + /* SwingPlatform */ + bhv_constant(oSwingPlatformAngle); + bhv_constant(oSwingPlatformSpeed); + + /* Swoop */ + bhv_constant(oSwoopBonkCountdown); + bhv_constant(oSwoopTargetPitch); + bhv_constant(oSwoopTargetYaw); + + /* Thwomp */ + bhv_constant(oThwompRandomTimer); + + /* TiltingPlatform */ + bhv_constant(oTiltingPyramidNormalX); + bhv_constant(oTiltingPyramidNormalY); + bhv_constant(oTiltingPyramidNormalZ); + bhv_constant(oTiltingPyramidMarioOnPlatform); + + /* ToadMessage */ + bhv_constant(oToadMessageDialogId); + bhv_constant(oToadMessageRecentlyTalked); + bhv_constant(oToadMessageState); + + /* ToxBox */ + bhv_constant(oToxBoxMovementPattern); + bhv_constant(oToxBoxMovementStep); + + /* TTCRotatingSolid */ + bhv_constant(oTTCRotatingSolidNumTurns); + bhv_constant(oTTCRotatingSolidNumSides); + bhv_constant(oTTCRotatingSolidRotationDelay); + bhv_constant(oTTCRotatingSolidVelY); + bhv_constant(oTTCRotatingSolidSoundTimer); + + /* TTCPendulum */ + bhv_constant(oTTCPendulumAccelDir); + bhv_constant(oTTCPendulumAngle); + bhv_constant(oTTCPendulumAngleVel); + bhv_constant(oTTCPendulumAngleAccel); + bhv_constant(oTTCPendulumDelay); + bhv_constant(oTTCPendulumSoundTimer); + + /* TTCTreadmill */ + bhv_constant(oTTCTreadmillBigSurface); + bhv_constant(oTTCTreadmillSmallSurface); + bhv_constant(oTTCTreadmillSpeed); + bhv_constant(oTTCTreadmillTargetSpeed); + bhv_constant(oTTCTreadmillTimeUntilSwitch); + + /* TTCMovingBar */ + bhv_constant(oTTCMovingBarDelay); + bhv_constant(oTTCMovingBarStoppedTimer); + bhv_constant(oTTCMovingBarOffset); + bhv_constant(oTTCMovingBarSpeed); + bhv_constant(oTTCMovingBarStartOffset); + + /* TTCCog */ + bhv_constant(oTTCCogDir); + bhv_constant(oTTCCogSpeed); + bhv_constant(oTTCCogTargetVel); + + /* TTCPitBlock */ + bhv_constant(oTTCPitBlockPeakY); + bhv_constant(oTTCPitBlockDir); + bhv_constant(oTTCPitBlockWaitTime); + + /* TTCElevator */ + bhv_constant(oTTCElevatorDir); + bhv_constant(oTTCElevatorPeakY); + bhv_constant(oTTCElevatorMoveTime); + + /* TTC2DRotator */ + bhv_constant(oTTC2DRotatorMinTimeUntilNextTurn); + bhv_constant(oTTC2DRotatorTargetYaw); + bhv_constant(oTTC2DRotatorIncrement); + bhv_constant(oTTC2DRotatorRandomDirTimer); + bhv_constant(oTTC2DRotatorSpeed); + + /* TTCSpinner */ + bhv_constant(oTTCSpinnerDir); + bhv_constant(oTTCChangeDirTimer); + + /* BetaTrampoline */ + bhv_constant(oBetaTrampolineMarioOnTrampoline); + + /* TreasureChest */ + bhv_constant(oTreasureChestCurrentAnswer); + bhv_constant(oTreasureChestIsLastInteractionIncorrect); + bhv_constant(oTreasureChestIsAboveWater); + bhv_constant(oTreasureChestSound); + bhv_constant(oTreasureChestLastNetworkPlayerIndex); + + /* TreeSnowOrLeaf */ + bhv_constant(oTreeSnowOrLeafUnkF4); + bhv_constant(oTreeSnowOrLeafUnkF8); + bhv_constant(oTreeSnowOrLeafUnkFC); + + /* TumblingBridge */ + bhv_constant(oTumblingBridgeUnkF4); + + /* Tweester */ + bhv_constant(oTweesterScaleTimer); + bhv_constant(oTweesterUnused); + + /* Ukiki */ + bhv_constant(oUkikiTauntCounter); + bhv_constant(oUkikiTauntsToBeDone); + //-reservedforpathing + bhv_constant(oUkikiChaseFleeRange); + bhv_constant(oUkikiTextState); + bhv_constant(oUkikiTextboxTimer); + bhv_constant(oUkikiCageSpinTimer); + bhv_constant(oUkikiHasCap); + + /* UkikiCage */ + bhv_constant(oUkikiCageNextAction); + + /* Unagi */ + bhv_constant(oUnagiUnkF4); + bhv_constant(oUnagiUnkF8); + //-reservedforpathing + bhv_constant(oUnagiUnk110); + bhv_constant(oUnagiUnk1AC); + bhv_constant(oUnagiUnk1B0); + bhv_constant(oUnagiUnk1B2); + + /* WaterBomb */ + bhv_constant(oWaterBombVerticalStretch); + bhv_constant(oWaterBombStretchSpeed); + bhv_constant(oWaterBombOnGround); + bhv_constant(oWaterBombNumBounces); + + /* WaterBombSpawner */ + bhv_constant(oWaterBombSpawnerBombActive); + bhv_constant(oWaterBombSpawnerTimeToSpawn); + + /* WaterBombCannon */ + bhv_constant(oWaterCannonUnkF4); + bhv_constant(oWaterCannonUnkF8); + bhv_constant(oWaterCannonUnkFC); + bhv_constant(oWaterCannonUnk100); + + /* CannonBarrelBubbles */ + bhv_constant(oCannonBarrelBubblesUnkF4); + + /* WaterLevelPillar */ + bhv_constant(oWaterLevelPillarDrained); + + /* WaterLevelTrigger */ + bhv_constant(oWaterLevelTriggerUnkF4); + bhv_constant(oWaterLevelTriggerTargetWaterLevel); + + /* WaterObjects */ + bhv_constant(oWaterObjUnkF4); + bhv_constant(oWaterObjUnkF8); + bhv_constant(oWaterObjUnkFC); + bhv_constant(oWaterObjUnk100); + + /* WaterRing(bothvariants) */ + bhv_constant(oWaterRingScalePhaseX); + bhv_constant(oWaterRingScalePhaseY); + bhv_constant(oWaterRingScalePhaseZ); + bhv_constant(oWaterRingNormalX); + bhv_constant(oWaterRingNormalY); + bhv_constant(oWaterRingNormalZ); + bhv_constant(oWaterRingMarioDistInFront); + bhv_constant(oWaterRingIndex); + bhv_constant(oWaterRingAvgScale); + + /* WaterRingSpawner(JetStreamRingSpawnerandMantaRay) */ + bhv_constant(oWaterRingSpawnerRingsCollected); + + /* WaterRingManager(JetStreamRingSpawnerandMantaRayRingManager) */ + bhv_constant(oWaterRingMgrNextRingIndex); + bhv_constant(oWaterRingMgrLastRingCollected); + + /* WaveTrail */ + bhv_constant(oWaveTrailSize); + + /* Whirlpool */ + bhv_constant(oWhirlpoolInitFacePitch); + bhv_constant(oWhirlpoolInitFaceRoll); + bhv_constant(oWhirlpoolTimeout); + + /* WhitePuffExplode */ + bhv_constant(oWhitePuffUnkF4); + bhv_constant(oWhitePuffUnkF8); + bhv_constant(oWhitePuffUnkFC); + + /* WhiteWindParticle */ + bhv_constant(oStrongWindParticlePenguinObj); + + /* Whomp */ + bhv_constant(oWhompShakeVal); + + /* Wiggler */ + bhv_constant(oWigglerFallThroughFloorsHeight); + bhv_constant(oWigglerSegments); + bhv_constant(oWigglerWalkAnimSpeed); + bhv_constant(oWigglerSquishSpeed); + bhv_constant(oWigglerTimeUntilRandomTurn); + bhv_constant(oWigglerTargetYaw); + bhv_constant(oWigglerWalkAwayFromWallTimer); + bhv_constant(oWigglerUnused); + bhv_constant(oWigglerTextStatus); + + /* LllWoodPiece */ + bhv_constant(oLllWoodPieceOscillationTimer); + + /* WoodenPost */ + bhv_constant(oWoodenPostTotalMarioAngle); + bhv_constant(oWoodenPostPrevAngleToMario); + bhv_constant(oWoodenPostSpeedY); + bhv_constant(oWoodenPostMarioPounding); + bhv_constant(oWoodenPostOffsetY); + + /* Yoshi */ + bhv_constant(oYoshiBlinkTimer); + bhv_constant(oYoshiChosenHome); + bhv_constant(oYoshiTargetYaw); + + /* BreakableWall */ + bhv_constant(oBreakableWallForce); + + *found = false; + return 0; +} + +template +DataNode *FindDataNode(DataNodes &aDataNodes, String &aName, u32 aModelIdentifier) { + DataNode *best = NULL; + for (auto& node : aDataNodes) { + if (aName == node->mName) { + if (aModelIdentifier == node->mModelIdentifier) { + return node; + } + best = node; + } + } + return best; +} + +static BehaviorScript ParseBehaviorScriptSymbolArgInternal(GfxData *aGfxData, DataNode *aNode, u64 &aTokenIndex, bool *found) { + String _Arg = aNode->mTokens[aTokenIndex++]; + u64 _ModelIdentifier = aNode->mModelIdentifier; + *found = true; + + // Built-in functions + const void *_FunctionPtr = DynOS_Builtin_Func_GetFromName(_Arg.begin()); + if (_FunctionPtr != NULL) { + return (s64) _FunctionPtr; + } + + // Built-in actors + auto builtinActor = DynOS_Builtin_Actor_GetFromName(_Arg.begin()); + if (builtinActor != NULL) { + return (BehaviorScript)builtinActor; + } + + // Built-in Lvl Geos + auto builtinGeo = DynOS_Builtin_LvlGeo_GetFromName(_Arg.begin()); + if (builtinGeo != NULL) { + return (BehaviorScript)builtinGeo; + } + + // Built-in Cols + auto builtinCol = DynOS_Builtin_Col_GetFromName(_Arg.begin()); + if (builtinCol != NULL) { + return (BehaviorScript)builtinCol; + } + + // Built-in Animations + auto builtinAnim = DynOS_Builtin_Anim_GetFromName(_Arg.begin()); + if (builtinAnim != NULL) { + return (BehaviorScript)builtinAnim; + } + + // Brackets + // Make sure we parse out the brackets if they are present. + if (_Arg[0] == '(') { + // Remove first bracket. + _Arg = _Arg.SubString(1); + + s32 _Brk = _Arg.FindLast(')'); + + // Remove last bracket. + if (_Brk != -1) { _Arg = _Arg.SubString(0, _Brk); } + } + + /* + // Offset + s32 _Offset = 0; + s32 _Plus = -1; + // Make sure we parse out all additions or offsets. + do { + _Plus = _Arg.FindLast('+'); + + // If we didn't find anything. Break early. + if (_Plus == -1) { break; } + + _Offset += _Arg.SubString(_Plus + 1).ParseInt(); + _Arg = _Arg.SubString(0, _Plus); + } + while(_Plus != -1); + */ + + // OR Operations + s32 _OrValue = 0; + s32 _Or = -1; + // Make sure we parse out all or operations. + do { + _Or = _Arg.FindLast('|'); + + // If we didn't find anything. Break early. + if (_Or == -1) { break; } + + bool constantFound = false; + s64 constantValue = DynOS_Bhv_ParseBehaviorIntegerScriptConstants(_Arg.SubString(_Or + 1), &constantFound); + + if (constantFound) { + _OrValue |= constantValue; + } else { + _OrValue |= _Arg.SubString(_Or + 1).ParseInt(); + } + + _Arg = _Arg.SubString(0, _Or); + } + while(_Or != -1); + + // Integers + bool integerFound = false; + s64 integerValue = DynOS_Misc_ParseInteger(_Arg, &integerFound); + if (integerFound) { + // Support OR operations on integers. + if (_OrValue != 0) { integerValue |= _OrValue; } + return integerValue; + } + + // Parse integer constants + bool intConstantFound = false; + s64 constantIntValue = DynOS_Bhv_ParseBehaviorIntegerScriptConstants(_Arg, &intConstantFound); + if (intConstantFound) { + // Support OR operations on integer constants. + if (_OrValue != 0) { constantIntValue |= _OrValue; } + return (BehaviorScript) constantIntValue; + } + + // Recursive descent parsing + bool rdIntSuccess = false; + s64 rdIntValue = DynOS_RecursiveDescent_Parse(_Arg.begin(), &rdIntSuccess, DynOS_Bhv_ParseBehaviorIntegerScriptConstants); + if (rdIntSuccess) { + // Support OR operations on integer constants. + if (_OrValue != 0) { rdIntValue |= _OrValue; } + return (BehaviorScript)rdIntValue; + } + + // Parse all other constants last so everything else is found for certain. + bool constantFound = false; + s64 constantValue = DynOS_Bhv_ParseBehaviorScriptConstants(_Arg, &constantFound); + if (constantFound) { + return (BehaviorScript) constantValue; + } + + // Recursive descent parsing + bool rdSuccess = false; + s64 rdValue = DynOS_RecursiveDescent_Parse(_Arg.begin(), &rdSuccess, DynOS_Bhv_ParseBehaviorScriptConstants); + if (rdSuccess) { + return (BehaviorScript)rdValue; + } + + *found = false; + return 0; +} + +static BehaviorScript ParseBehaviorScriptSymbolArg(GfxData *aGfxData, DataNode *aNode, u64 &aTokenIndex) { + bool found = true; + BehaviorScript value = ParseBehaviorScriptSymbolArgInternal(aGfxData, aNode, aTokenIndex, &found); + if (!found) { + const String &_Arg = aNode->mTokens[aTokenIndex - 1]; + PrintError(" ERROR: Unknown bhv arg: %s", _Arg.begin()); + } + return value; +} + +#define AddPointerToList(symbol, aGfxData, pointer) \ + /*Print("%s: Adding pointer %x to list.", symbol, pointer);*/ \ + aGfxData->mPointerList.Add(pointer); \ + +#define bhv_symbol_0(symb) \ + if (_Symbol == #symb) { \ + BehaviorScript _Bs[] = { symb() }; \ + memcpy(aHead, _Bs, sizeof(_Bs)); \ + aHead += (sizeof(_Bs) / sizeof(_Bs[0])); \ + return; \ + } + +#define bhv_symbol_1(symb, n) \ + if (_Symbol == #symb) { \ + BehaviorScript _Arg0 = ParseBehaviorScriptSymbolArg(aGfxData, aNode, aTokenIndex); \ + if (n != 0) { AddPointerToList(#symb, aGfxData, aHead + n); } \ + BehaviorScript _Bs[] = { symb(_Arg0) }; \ + memcpy(aHead, _Bs, sizeof(_Bs)); \ + aHead += (sizeof(_Bs) / sizeof(_Bs[0])); \ + return; \ + } + +#define bhv_symbol_2(symb, n1, n2) \ + if (_Symbol == #symb) { \ + BehaviorScript _Arg0 = ParseBehaviorScriptSymbolArg(aGfxData, aNode, aTokenIndex); \ + BehaviorScript _Arg1 = ParseBehaviorScriptSymbolArg(aGfxData, aNode, aTokenIndex); \ + if (n1 != 0) { AddPointerToList(#symb, aGfxData, aHead + n1); } \ + if (n2 != 0) { AddPointerToList(#symb, aGfxData, aHead + n2); } \ + BehaviorScript _Bs[] = { symb(_Arg0, _Arg1) }; \ + memcpy(aHead, _Bs, sizeof(_Bs)); \ + aHead += (sizeof(_Bs) / sizeof(_Bs[0])); \ + return; \ + } + +#define bhv_symbol_3(symb, n1, n2, n3) \ + if (_Symbol == #symb) { \ + BehaviorScript _Arg0 = ParseBehaviorScriptSymbolArg(aGfxData, aNode, aTokenIndex); \ + BehaviorScript _Arg1 = ParseBehaviorScriptSymbolArg(aGfxData, aNode, aTokenIndex); \ + BehaviorScript _Arg2 = ParseBehaviorScriptSymbolArg(aGfxData, aNode, aTokenIndex); \ + if (n1 != 0) { AddPointerToList(#symb, aGfxData, aHead + n1); } \ + if (n2 != 0) { AddPointerToList(#symb, aGfxData, aHead + n2); } \ + if (n3 != 0) { AddPointerToList(#symb, aGfxData, aHead + n3); } \ + BehaviorScript _Bs[] = { symb(_Arg0, _Arg1, _Arg2) }; \ + memcpy(aHead, _Bs, sizeof(_Bs)); \ + aHead += (sizeof(_Bs) / sizeof(_Bs[0])); \ + return; \ + } + +#define bhv_symbol_4(symb, n1, n2, n3, n4) \ + if (_Symbol == #symb) { \ + BehaviorScript _Arg0 = ParseBehaviorScriptSymbolArg(aGfxData, aNode, aTokenIndex); \ + BehaviorScript _Arg1 = ParseBehaviorScriptSymbolArg(aGfxData, aNode, aTokenIndex); \ + BehaviorScript _Arg2 = ParseBehaviorScriptSymbolArg(aGfxData, aNode, aTokenIndex); \ + BehaviorScript _Arg3 = ParseBehaviorScriptSymbolArg(aGfxData, aNode, aTokenIndex); \ + BehaviorScript _Arg4 = ParseBehaviorScriptSymbolArg(aGfxData, aNode, aTokenIndex); \ + BehaviorScript _Arg5 = ParseBehaviorScriptSymbolArg(aGfxData, aNode, aTokenIndex); \ + BehaviorScript _Arg6 = ParseBehaviorScriptSymbolArg(aGfxData, aNode, aTokenIndex); \ + BehaviorScript _Arg7 = ParseBehaviorScriptSymbolArg(aGfxData, aNode, aTokenIndex); \ + if (n1 != 0) { AddPointerToList(#symb, aGfxData, aHead + n1); } \ + if (n2 != 0) { AddPointerToList(#symb, aGfxData, aHead + n2); } \ + if (n3 != 0) { AddPointerToList(#symb, aGfxData, aHead + n3); } \ + if (n4 != 0) { AddPointerToList(#symb, aGfxData, aHead + n4); } \ + BehaviorScript _Bs[] = { symb(_Arg0, _Arg1, _Arg2, _Arg3, _Arg4, _Arg5, _Arg6, _Arg7) }; \ + memcpy(aHead, _Bs, sizeof(_Bs)); \ + aHead += (sizeof(_Bs) / sizeof(_Bs[0])); \ + return; \ + } + +static void ParseBehaviorScriptSymbol(GfxData *aGfxData, DataNode *aNode, BehaviorScript *&aHead, u64 &aTokenIndex, Array &aSwitchNodes) { + const String &_Symbol = aNode->mTokens[aTokenIndex++]; + + bhv_symbol_0(RETURN); + bhv_symbol_0(END_REPEAT); + bhv_symbol_0(END_REPEAT_CONTINUE); + bhv_symbol_0(BEGIN_LOOP); + bhv_symbol_0(END_LOOP); + bhv_symbol_0(BREAK); + bhv_symbol_0(BREAK_UNUSED); + bhv_symbol_0(DEACTIVATE); + bhv_symbol_0(DROP_TO_FLOOR); + bhv_symbol_0(BILLBOARD); + bhv_symbol_0(CYLBOARD); + bhv_symbol_0(HIDE); + bhv_symbol_0(SET_HOME); + bhv_symbol_0(DISABLE_RENDERING); + + bhv_symbol_1(ID, 0); + bhv_symbol_1(BEGIN, 0); + bhv_symbol_1(DELAY, 0); + bhv_symbol_1(BEGIN_REPEAT, 0); + bhv_symbol_1(CMD_NOP_1, 0); + bhv_symbol_1(CMD_NOP_2, 0); + bhv_symbol_1(CMD_NOP_3, 0); + bhv_symbol_1(SET_MODEL, 0); + bhv_symbol_1(DELAY_VAR, 0); + bhv_symbol_1(BEGIN_REPEAT_UNUSED, 0); + bhv_symbol_1(ANIMATE, 0); + bhv_symbol_1(SET_INTERACT_TYPE, 0); + bhv_symbol_1(SET_INTERACT_SUBTYPE, 0); + //bhv_symbol_1(SPAWN_WATER_DROPLET, 1); + + bhv_symbol_2(ADD_FLOAT, 0, 0); + bhv_symbol_2(SET_FLOAT, 0, 0); + bhv_symbol_2(ADD_INT, 0, 0); + bhv_symbol_2(SET_INT, 0, 0); + bhv_symbol_2(OR_INT, 0, 0); + bhv_symbol_2(BIT_CLEAR, 0, 0); + bhv_symbol_2(SET_HITBOX, 0, 0); + bhv_symbol_2(CMD_NOP_4, 0, 0); + bhv_symbol_2(SET_HURTBOX, 0, 0); + bhv_symbol_2(SCALE, 0, 0); + bhv_symbol_2(PARENT_BIT_CLEAR, 0, 0); + bhv_symbol_2(ANIMATE_TEXTURE, 0, 0); + bhv_symbol_2(SET_INT_UNUSED, 0, 0); + + bhv_symbol_3(SET_INT_RAND_RSHIFT, 0, 0, 0); + bhv_symbol_3(SET_RANDOM_INT, 0, 0, 0); + bhv_symbol_3(ADD_RANDOM_FLOAT, 0, 0, 0); + bhv_symbol_3(ADD_INT_RAND_RSHIFT, 0, 0, 0); + bhv_symbol_3(SUM_FLOAT, 0, 0, 0); + bhv_symbol_3(SUM_INT, 0, 0, 0); + bhv_symbol_3(SET_HITBOX_WITH_OFFSET, 0, 0, 0); + + bhv_symbol_4(SET_OBJ_PHYSICS, 0, 0, 0, 0); + + // Both CALL and GOTO can have a offset to their addresses + // in their non-extended counterparts. + // We might be able to support this in DynOS. But I would not know how. + + // Call Behavior + if (_Symbol == "CALL") { + u64 topTokenIndex = aTokenIndex; + + bool foundBeh = true; + + BehaviorScript behavior = ParseBehaviorScriptSymbolArgInternal(aGfxData, aNode, aTokenIndex, &foundBeh); + + if (foundBeh) { + aGfxData->mPointerList.Add(aHead + 1); + BehaviorScript _Bs[] = { CALL(behavior) }; + memcpy(aHead, _Bs, sizeof(_Bs)); + aHead += (sizeof(_Bs) / sizeof(_Bs[0])); + } else { + u32 behIndex = DynOS_Lua_RememberVariable(aGfxData, aHead + 1, aNode->mTokens[topTokenIndex + 0]); + BehaviorScript _Bs[] = { CALL_EXT(behIndex) }; + memcpy(aHead, _Bs, sizeof(_Bs)); + aHead += (sizeof(_Bs) / sizeof(_Bs[0])); + } + return; + } + + // Call Behavior + if (_Symbol == "CALL_NATIVE") { + u64 topTokenIndex = aTokenIndex; + + bool foundFunc = true; + + BehaviorScript function = ParseBehaviorScriptSymbolArgInternal(aGfxData, aNode, aTokenIndex, &foundFunc); + + if (foundFunc) { + aGfxData->mPointerList.Add(aHead + 1); + BehaviorScript _Bs[] = { CALL_NATIVE(function) }; + memcpy(aHead, _Bs, sizeof(_Bs)); + aHead += (sizeof(_Bs) / sizeof(_Bs[0])); + } else { + u32 funcIndex = DynOS_Lua_RememberVariable(aGfxData, aHead + 1, aNode->mTokens[topTokenIndex + 0]); + BehaviorScript _Bs[] = { CALL_NATIVE_EXT(funcIndex) }; + memcpy(aHead, _Bs, sizeof(_Bs)); + aHead += (sizeof(_Bs) / sizeof(_Bs[0])); + } + return; + } + + // Jump to Behavior (Goto) + if (_Symbol == "GOTO") { + u64 topTokenIndex = aTokenIndex; + + bool foundBeh = true; + + BehaviorScript behavior = ParseBehaviorScriptSymbolArgInternal(aGfxData, aNode, aTokenIndex, &foundBeh); + + if (foundBeh) { + aGfxData->mPointerList.Add(aHead + 1); + BehaviorScript _Bs[] = { GOTO(behavior) }; + memcpy(aHead, _Bs, sizeof(_Bs)); + aHead += (sizeof(_Bs) / sizeof(_Bs[0])); + } else { + u32 behIndex = DynOS_Lua_RememberVariable(aGfxData, aHead + 1, aNode->mTokens[topTokenIndex + 0]); + BehaviorScript _Bs[] = { GOTO_EXT(behIndex) }; + memcpy(aHead, _Bs, sizeof(_Bs)); + aHead += (sizeof(_Bs) / sizeof(_Bs[0])); + } + return; + } + + + // Spawn Child + if (_Symbol == "SPAWN_CHILD") { + u64 topTokenIndex = aTokenIndex; + + bool foundBeh = true; + + BehaviorScript modelID = ParseBehaviorScriptSymbolArg(aGfxData, aNode, aTokenIndex); + BehaviorScript behavior = ParseBehaviorScriptSymbolArgInternal(aGfxData, aNode, aTokenIndex, &foundBeh); + + if (foundBeh) { + aGfxData->mPointerList.Add(aHead + 2); + BehaviorScript _Bs[] = { SPAWN_CHILD(modelID, behavior) }; + memcpy(aHead, _Bs, sizeof(_Bs)); + aHead += (sizeof(_Bs) / sizeof(_Bs[0])); + } else { + u32 behIndex = DynOS_Lua_RememberVariable(aGfxData, aHead + 2, aNode->mTokens[topTokenIndex + 1]); + BehaviorScript _Bs[] = { SPAWN_CHILD_EXT(modelID, behIndex) }; + memcpy(aHead, _Bs, sizeof(_Bs)); + aHead += (sizeof(_Bs) / sizeof(_Bs[0])); + } + return; + } + + // Spawn Child with Parameter + if (_Symbol == "SPAWN_CHILD_WITH_PARAM") { + u64 topTokenIndex = aTokenIndex; + + bool foundBeh = true; + + BehaviorScript bhvParam = ParseBehaviorScriptSymbolArg(aGfxData, aNode, aTokenIndex); + BehaviorScript modelID = ParseBehaviorScriptSymbolArg(aGfxData, aNode, aTokenIndex); + BehaviorScript behavior = ParseBehaviorScriptSymbolArgInternal(aGfxData, aNode, aTokenIndex, &foundBeh); + + if (foundBeh) { + aGfxData->mPointerList.Add(aHead + 2); + BehaviorScript _Bs[] = { SPAWN_CHILD_WITH_PARAM(bhvParam, modelID, behavior) }; + memcpy(aHead, _Bs, sizeof(_Bs)); + aHead += (sizeof(_Bs) / sizeof(_Bs[0])); + } else { + u32 behIndex = DynOS_Lua_RememberVariable(aGfxData, aHead + 2, aNode->mTokens[topTokenIndex + 2]); + BehaviorScript _Bs[] = { SPAWN_CHILD_WITH_PARAM_EXT(bhvParam, modelID, behIndex) }; + memcpy(aHead, _Bs, sizeof(_Bs)); + aHead += (sizeof(_Bs) / sizeof(_Bs[0])); + } + return; + } + + // Spawn Object + if (_Symbol == "SPAWN_OBJ") { + u64 topTokenIndex = aTokenIndex; + + bool foundBeh = true; + + BehaviorScript modelID = ParseBehaviorScriptSymbolArg(aGfxData, aNode, aTokenIndex); + BehaviorScript behavior = ParseBehaviorScriptSymbolArgInternal(aGfxData, aNode, aTokenIndex, &foundBeh); + + if (foundBeh) { + aGfxData->mPointerList.Add(aHead + 2); + BehaviorScript _Bs[] = { SPAWN_OBJ(modelID, behavior) }; + memcpy(aHead, _Bs, sizeof(_Bs)); + aHead += (sizeof(_Bs) / sizeof(_Bs[0])); + } else { + u32 behIndex = DynOS_Lua_RememberVariable(aGfxData, aHead + 2, aNode->mTokens[topTokenIndex + 1]); + BehaviorScript _Bs[] = { SPAWN_OBJ_EXT(modelID, behIndex) }; + memcpy(aHead, _Bs, sizeof(_Bs)); + aHead += (sizeof(_Bs) / sizeof(_Bs[0])); + } + return; + } + + if (_Symbol == "LOAD_ANIMATIONS") { + u64 topTokenIndex = aTokenIndex; + + bool foundAnimation = true; + + BehaviorScript field = ParseBehaviorScriptSymbolArg(aGfxData, aNode, aTokenIndex); + BehaviorScript animations = ParseBehaviorScriptSymbolArgInternal(aGfxData, aNode, aTokenIndex, &foundAnimation); + + if (foundAnimation) { + aGfxData->mPointerList.Add(aHead + 1); + BehaviorScript _Bs[] = { LOAD_ANIMATIONS(field, animations) }; + memcpy(aHead, _Bs, sizeof(_Bs)); + aHead += (sizeof(_Bs) / sizeof(_Bs[0])); + } else { + //u32 animIndex = DynOS_Lua_RememberVariable(aGfxData, aHead + 1, aNode->mTokens[topTokenIndex + 0]); + //BehaviorScript _Bs[] = { LOAD_ANIMATIONS_EXT(field, animIndex) }; + //memcpy(aHead, _Bs, sizeof(_Bs)); + //aHead += (sizeof(_Bs) / sizeof(_Bs[0])); + PrintError(" ERROR: : Custom external animations are currently not supported. Skipping LOAD_ANIMATIONS_EXT."); + } + return; + } + + + if (_Symbol == "LOAD_COLLISION_DATA") { + u64 topTokenIndex = aTokenIndex; + + bool foundCollisionData = true; + + BehaviorScript collisionData = ParseBehaviorScriptSymbolArgInternal(aGfxData, aNode, aTokenIndex, &foundCollisionData); + + if (foundCollisionData) { + aGfxData->mPointerList.Add(aHead + 1); + BehaviorScript _Bs[] = { LOAD_COLLISION_DATA(collisionData) }; + memcpy(aHead, _Bs, sizeof(_Bs)); + aHead += (sizeof(_Bs) / sizeof(_Bs[0])); + } else { + u32 colDataIndex = DynOS_Lua_RememberVariable(aGfxData, aHead + 1, aNode->mTokens[topTokenIndex + 0]); + BehaviorScript _Bs[] = { LOAD_COLLISION_DATA_EXT(colDataIndex) }; + memcpy(aHead, _Bs, sizeof(_Bs)); + aHead += (sizeof(_Bs) / sizeof(_Bs[0])); + } + return; + } + + // We support directly using some extended types if needed. + + if (_Symbol == "CALL_EXT" || _Symbol == "CALL_CUSTOM") { + u64 topTokenIndex = aTokenIndex; + + bool foundBeh = true; + ParseBehaviorScriptSymbolArgInternal(aGfxData, aNode, aTokenIndex, &foundBeh); + + u32 behIndex = DynOS_Lua_RememberVariable(aGfxData, aHead + 1, aNode->mTokens[topTokenIndex + 0]); + BehaviorScript _Bs[] = { CALL_EXT(behIndex) }; + memcpy(aHead, _Bs, sizeof(_Bs)); + aHead += (sizeof(_Bs) / sizeof(_Bs[0])); + return; + } + + if (_Symbol == "CALL_NATIVE_EXT" || _Symbol == "CALL_CUSTOM_NATIVE") { + u64 topTokenIndex = aTokenIndex; + + bool foundFunc = true; + ParseBehaviorScriptSymbolArgInternal(aGfxData, aNode, aTokenIndex, &foundFunc); + + u32 funcIndex = DynOS_Lua_RememberVariable(aGfxData, aHead + 1, aNode->mTokens[topTokenIndex + 0]); + BehaviorScript _Bs[] = { CALL_NATIVE_EXT(funcIndex) }; + memcpy(aHead, _Bs, sizeof(_Bs)); + aHead += (sizeof(_Bs) / sizeof(_Bs[0])); + return; + } + + if (_Symbol == "GOTO_EXT") { + u64 topTokenIndex = aTokenIndex; + + bool foundBeh = true; + ParseBehaviorScriptSymbolArgInternal(aGfxData, aNode, aTokenIndex, &foundBeh); + + u32 behIndex = DynOS_Lua_RememberVariable(aGfxData, aHead + 1, aNode->mTokens[topTokenIndex + 0]); + BehaviorScript _Bs[] = { GOTO_EXT(behIndex) }; + memcpy(aHead, _Bs, sizeof(_Bs)); + aHead += (sizeof(_Bs) / sizeof(_Bs[0])); + return; + } + + if (_Symbol == "SPAWN_CHILD_EXT" || _Symbol == "SPAWN_LUA_CHILD") { + u64 topTokenIndex = aTokenIndex; + + bool foundBeh = true; + BehaviorScript modelID = ParseBehaviorScriptSymbolArg(aGfxData, aNode, aTokenIndex); + ParseBehaviorScriptSymbolArgInternal(aGfxData, aNode, aTokenIndex, &foundBeh); + + u32 behIndex = DynOS_Lua_RememberVariable(aGfxData, aHead + 2, aNode->mTokens[topTokenIndex + 1]); + BehaviorScript _Bs[] = { SPAWN_CHILD_EXT(modelID, behIndex) }; + memcpy(aHead, _Bs, sizeof(_Bs)); + aHead += (sizeof(_Bs) / sizeof(_Bs[0])); + return; + } + + if (_Symbol == "SPAWN_CHILD_WITH_PARAM_EXT" || _Symbol == "SPAWN_LUA_CHILD_WITH_PARAM") { + u64 topTokenIndex = aTokenIndex; + + bool foundBeh = true; + BehaviorScript bhvParam = ParseBehaviorScriptSymbolArg(aGfxData, aNode, aTokenIndex); + BehaviorScript modelID = ParseBehaviorScriptSymbolArg(aGfxData, aNode, aTokenIndex); + ParseBehaviorScriptSymbolArgInternal(aGfxData, aNode, aTokenIndex, &foundBeh); + + u32 behIndex = DynOS_Lua_RememberVariable(aGfxData, aHead + 2, aNode->mTokens[topTokenIndex + 2]); + BehaviorScript _Bs[] = { SPAWN_CHILD_WITH_PARAM_EXT(bhvParam, modelID, behIndex) }; + memcpy(aHead, _Bs, sizeof(_Bs)); + aHead += (sizeof(_Bs) / sizeof(_Bs[0])); + return; + } + + if (_Symbol == "SPAWN_OBJ_EXT" || _Symbol == "SPAWN_LUA_OBJ") { + u64 topTokenIndex = aTokenIndex; + + bool foundBeh = true; + BehaviorScript modelID = ParseBehaviorScriptSymbolArg(aGfxData, aNode, aTokenIndex); + ParseBehaviorScriptSymbolArgInternal(aGfxData, aNode, aTokenIndex, &foundBeh); + + u32 behIndex = DynOS_Lua_RememberVariable(aGfxData, aHead + 2, aNode->mTokens[topTokenIndex + 1]); + BehaviorScript _Bs[] = { SPAWN_OBJ_EXT(modelID, behIndex) }; + memcpy(aHead, _Bs, sizeof(_Bs)); + aHead += (sizeof(_Bs) / sizeof(_Bs[0])); + return; + } + + /* + if (_Symbol == "LOAD_ANIMATIONS_EXT" || _Symbol == "LOAD_CUSTOM_ANIMATIONS") { + u64 topTokenIndex = aTokenIndex; + + bool foundAnimation = true; + BehaviorScript field = ParseBehaviorScriptSymbolArg(aGfxData, aNode, aTokenIndex); + ParseBehaviorScriptSymbolArgInternal(aGfxData, aNode, aTokenIndex, &foundAnimation); + + u32 animIndex = DynOS_Lua_RememberVariable(aGfxData, aHead + 1, aNode->mTokens[topTokenIndex + 0]); + BehaviorScript _Bs[] = { LOAD_ANIMATIONS_EXT(field, animIndex) }; + memcpy(aHead, _Bs, sizeof(_Bs)); + aHead += (sizeof(_Bs) / sizeof(_Bs[0])); + return; + } + */ + + if (_Symbol == "LOAD_COLLISION_DATA_EXT" || _Symbol == "LOAD_CUSTOM_COLLISION_DATA") { + u64 topTokenIndex = aTokenIndex; + + bool foundCollisionData = true; + ParseBehaviorScriptSymbolArgInternal(aGfxData, aNode, aTokenIndex, &foundCollisionData); + + u32 colDataIndex = DynOS_Lua_RememberVariable(aGfxData, aHead + 1, aNode->mTokens[topTokenIndex + 0]); + BehaviorScript _Bs[] = { LOAD_COLLISION_DATA_EXT(colDataIndex) }; + memcpy(aHead, _Bs, sizeof(_Bs)); + aHead += (sizeof(_Bs) / sizeof(_Bs[0])); + return; + } + + // Unknown + PrintError(" ERROR: Unknown behavior symbol: %s", _Symbol.begin()); +} + +DataNode *DynOS_Bhv_Parse(GfxData *aGfxData, DataNode *aNode, bool aDisplayPercent) { + if (aNode->mData) return aNode; + + // Behavior script data + aNode->mData = New(aNode->mTokens.Count() * BEHAVIOR_SCRIPT_SIZE_PER_TOKEN); + BehaviorScript *_Head = aNode->mData; + Array _SwitchNodes; + for (u64 _TokenIndex = 0; _TokenIndex < aNode->mTokens.Count();) { // Don't increment _TokenIndex here! + ParseBehaviorScriptSymbol(aGfxData, aNode, _Head, _TokenIndex, _SwitchNodes); + if (aDisplayPercent && aGfxData->mErrorCount == 0) { PrintNoNewLine("%3d%%\b\b\b\b", (s32) (_TokenIndex * 100) / aNode->mTokens.Count()); } + } + if (aDisplayPercent && aGfxData->mErrorCount == 0) { Print("100%%"); } + aNode->mSize = (u32)(_Head - aNode->mData); + aNode->mLoadIndex = aGfxData->mLoadIndex++; + return aNode; +} + +static DataNode *GetBehaviorScript(GfxData *aGfxData, const String &aBhvRoot) { + for (DataNode *_Node : aGfxData->mBehaviorScripts) { + if (_Node->mName == aBhvRoot) { + return _Node; + } + } + return NULL; +} + + ///////////// + // Writing // +///////////// + +static void DynOS_Bhv_Write(FILE* aFile, GfxData* aGfxData, DataNode *aNode) { + if (!aNode->mData) return; + + // Name + WriteBytes(aFile, DATA_TYPE_BEHAVIOR_SCRIPT); + aNode->mName.Write(aFile); + + // Version + WriteBytes(aFile, BEHAVIOR_MAJOR_VER); + WriteBytes(aFile, BEHAVIOR_MINOR_VER); + WriteBytes(aFile, BEHAVIOR_PATCH_VER); + + // Data + WriteBytes(aFile, aNode->mSize); + for (u32 i = 0; i != aNode->mSize; ++i) { + BehaviorScript *_Head = &aNode->mData[i]; + if (aGfxData->mPointerList.Find((void *) _Head) != -1) { + DynOS_Pointer_Write(aFile, (const void *) (*_Head), aGfxData); + } else if (aGfxData->mLuaPointerList.Find((void *) _Head) != -1) { + DynOS_Pointer_Lua_Write(aFile, *(u32 *)_Head, aGfxData); + } else { + WriteBytes(aFile, *((u32 *) _Head)); + } + } +} + + +static bool DynOS_Bhv_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->mBehaviorScripts) { + if (_Node->mLoadIndex == i) { + DynOS_Bhv_Write(_File, aGfxData, _Node); + } + } + } + + fclose(_File); + return true; +} + + ///////////// + // Reading // +///////////// + +static DataNode *DynOS_Bhv_Load(FILE *aFile, GfxData *aGfxData) { + DataNode *_Node = New>(); + + // Name + _Node->mName.Read(aFile); + + // Version + u8 majorVersion = ReadBytes(aFile); + u8 minorVersion = ReadBytes(aFile); + u8 patchVersion = ReadBytes(aFile); + + // Version Sanity Check + // + // If the major version doesn't match, then a drasitc change has happened and + // we can't read it no matter what. If it's just minor or patch. We might have + // code to support it. + u32 dataSize = ReadBytes(aFile); + if (majorVersion != BEHAVIOR_MIN_MAJOR_VER || (minorVersion < BEHAVIOR_MIN_MINOR_VER || patchVersion < BEHAVIOR_MIN_PATCH_VER)) { + PrintError(" ERROR: Behavior version is %u.%u.%u, but reading behaviors under %u.%u.%u is not supported!", majorVersion, minorVersion, patchVersion, BEHAVIOR_MIN_MAJOR_VER, BEHAVIOR_MIN_MINOR_VER, BEHAVIOR_MIN_PATCH_VER); + + // Skip the rest of the bytes saved for this behavior. + SkipBytes(aFile, dataSize); + // We don't return this since we failed to read the behavior. + Delete(_Node); + // We have nothing to return, So return NULL. + return NULL; + } + + // Data + _Node->mSize = dataSize; + _Node->mData = New(_Node->mSize); + + // Add it + if (aGfxData != NULL) { + aGfxData->mBehaviorScripts.Add(_Node); + } + + // Read it + for (u32 i = 0; i != _Node->mSize; ++i) { + if (feof(aFile)) { + PrintError(" ERROR: Reached EOF when reading file! Expected %llx bytes!", _Node->mSize * sizeof(u32)); + break; + } + u32 _Value = ReadBytes(aFile); + void *_Ptr = DynOS_Pointer_Load(aFile, aGfxData, _Value, &_Node->mFlags); + if (_Ptr) { + _Node->mData[i] = (uintptr_t) _Ptr; + } else { + _Node->mData[i] = (uintptr_t) _Value; + } + } + + return _Node; +} + +GfxData *DynOS_Bhv_LoadFromBinary(const SysPath &aFilename, const char *aBehaviorName) { + + // Load data from binary file + GfxData *_GfxData = NULL; + FILE *_File = fopen(aFilename.c_str(), "rb"); + if (_File != NULL) { + _GfxData = New(); + for (bool _Done = false; !_Done;) { + switch (ReadBytes(_File)) { + case DATA_TYPE_BEHAVIOR_SCRIPT: DynOS_Bhv_Load(_File, _GfxData); break; + default: _Done = true; break; + } + } + fclose(_File); + } + + return _GfxData; +} + + ////////////// + // Generate // +////////////// + +static String GetBehaviorFolder(const Array> &aBehaviorsFolders, u64 aModelIdentifier) { + for (const auto &_Pair : aBehaviorsFolders) { + if (_Pair.first == aModelIdentifier) { + return _Pair.second; + } + } + return String(); +} + +static void DynOS_Bhv_Generate(const SysPath &aPackFolder, Array> _BehaviorsFolders, GfxData *_GfxData) { + // do not regen this folder if we find any existing bins + for (s32 bhvIndex = _GfxData->mBehaviorScripts.Count() - 1; bhvIndex >= 0; bhvIndex--) { + auto &_BhvNode = _GfxData->mBehaviorScripts[bhvIndex]; + String _BhvRootName = _BhvNode->mName; + + // If there is an existing binary file for this layout, skip and go to the next behavior. + SysPath _BinFilename = fstring("%s/%s.bhv", aPackFolder.c_str(), _BhvRootName.begin()); + if (fs_sys_file_exists(_BinFilename.c_str())) { + return; + } + } + + // generate in reverse order to detect children + for (s32 bhvIndex = _GfxData->mBehaviorScripts.Count() - 1; bhvIndex >= 0; bhvIndex--) { + auto &_BhvNode = _GfxData->mBehaviorScripts[bhvIndex]; + + String _BhvRootName = _BhvNode->mName; + + // If there is an existing binary file for this layout, skip and go to the next behavior. + SysPath _BinFilename = fstring("%s/%s.bhv", aPackFolder.c_str(), _BhvRootName.begin()); + + // Init + _GfxData->mLoadIndex = 0; + _GfxData->mErrorCount = 0; + _GfxData->mModelIdentifier = _BhvNode->mModelIdentifier; + _GfxData->mPackFolder = aPackFolder; + _GfxData->mPointerList = { NULL }; // The NULL pointer is needed, so we add it here + _GfxData->mPointerOffsetList = { }; + _GfxData->mLuaPointerList = { }; + _GfxData->mLuaTokenList = { }; + _GfxData->mGfxContext.mCurrentTexture = NULL; + _GfxData->mGfxContext.mCurrentPalette = NULL; + _GfxData->mGeoNodeStack.Clear(); + + // Parse data + PrintNoNewLine("%s.bhv: Model identifier: %X - Processing... ", _BhvRootName.begin(), _GfxData->mModelIdentifier); + DynOS_Bhv_Parse(_GfxData, _BhvNode, true); + + // Write if no error + if (_GfxData->mErrorCount == 0) { + DynOS_Bhv_WriteBinary(_BinFilename, _GfxData); + } else { + Print(" %u error(s): Unable to parse data", _GfxData->mErrorCount); + } + + // Clear data pointers + ClearBhvDataNodes(_GfxData->mBehaviorScripts); + + _GfxData->mPointerList.Clear(); + _GfxData->mPointerOffsetList.Clear(); + _GfxData->mLuaPointerList.Clear(); + _GfxData->mLuaTokenList.Clear(); + } +} + +void DynOS_Bhv_GeneratePack(const SysPath &aPackFolder) { + Print("---------- Behavior Pack folder: \"%s\" ----------", aPackFolder.c_str()); + Array> _BehaviorsFolders; + GfxData *_GfxData = New(); + + // Read the behavior_data.c files from the pack folder and any subfolders. + + // Read the main folder. + if (fs_sys_dir_exists(aPackFolder.c_str())) { + _GfxData->mModelIdentifier = 0; + + DynOS_Read_Source(_GfxData, fstring("%s/behavior_data.c", aPackFolder.c_str())); + + if (_GfxData->mModelIdentifier != 0) { + _BehaviorsFolders.Add({ _GfxData->mModelIdentifier, String(aPackFolder.c_str()) }); + } + } + + // Read the subfolders. + DIR *aPackDir = opendir(aPackFolder.c_str()); + if (aPackDir) { + // Read the subfolders. + struct dirent *_PackEnt = NULL; + while ((_PackEnt = readdir(aPackDir)) != NULL) { + + // Skip . and .. + if (SysPath(_PackEnt->d_name) == ".") continue; + if (SysPath(_PackEnt->d_name) == "..") continue; + + // For each subfolder, read tokens from behavior_data.c + SysPath _Folder = fstring("%s/%s", aPackFolder.c_str(), _PackEnt->d_name); + if (fs_sys_dir_exists(_Folder.c_str())) { + _GfxData->mModelIdentifier = 0; + + DynOS_Read_Source(_GfxData, fstring("%s/behavior_data.c", _Folder.c_str())); + + if (_GfxData->mModelIdentifier != 0) { + _BehaviorsFolders.Add({ _GfxData->mModelIdentifier, String(_PackEnt->d_name) }); + } + } + } + closedir(aPackDir); + } + + // Generate a binary file for each behavior found in the GfxData + DynOS_Bhv_Generate(aPackFolder, _BehaviorsFolders, _GfxData); + + DynOS_Gfx_Free(_GfxData); +} \ No newline at end of file diff --git a/data/dynos_bin_lvl.cpp b/data/dynos_bin_lvl.cpp index 9efd2501..ab9bc83f 100644 --- a/data/dynos_bin_lvl.cpp +++ b/data/dynos_bin_lvl.cpp @@ -1494,8 +1494,8 @@ static LevelScript ParseLevelScriptSymbolArgInternal(GfxData* aGfxData, DataNode return (LevelScript)builtinGeo; } - // Built-in Lvl Cols - auto builtinCol = DynOS_Builtin_LvlCol_GetFromName(_Arg.begin()); + // Built-in Cols + auto builtinCol = DynOS_Builtin_Col_GetFromName(_Arg.begin()); if (builtinCol != NULL) { return (LevelScript)builtinCol; } diff --git a/data/dynos_bin_pointer.cpp b/data/dynos_bin_pointer.cpp index 91bb014a..7b1980a1 100644 --- a/data/dynos_bin_pointer.cpp +++ b/data/dynos_bin_pointer.cpp @@ -71,7 +71,7 @@ static PointerData GetDataFromPointer(const void* aPtr, GfxData* aGfxData) { return { _Node->mName, 0 }; } } - + // Collisions for (auto& _Node : aGfxData->mCollisions) { if (_Node->mData == aPtr) { @@ -132,11 +132,17 @@ static PointerData GetDataFromPointer(const void* aPtr, GfxData* aGfxData) { return { builtinGeo, 0 }; } - // Built-in Lvl Cols - auto builtinCol = DynOS_Builtin_LvlCol_GetFromData((const Collision*)aPtr); + // Built-in Cols + auto builtinCol = DynOS_Builtin_Col_GetFromData((const Collision*)aPtr); if (builtinCol != NULL) { return { builtinCol, 0 }; } + + // Built-in Animations + auto builtinAnim = DynOS_Builtin_Anim_GetFromData((const Animation *)aPtr); + if (builtinAnim != NULL) { + return { builtinAnim, 0 }; + } // Built-in Script Pointers auto builtinScriptPtr = DynOS_Builtin_ScriptPtr_GetFromData(aPtr); @@ -177,7 +183,7 @@ static PointerData GetDataFromPointer(const void* aPtr, GfxData* aGfxData) { } } - PrintError("Unable to find pointer!"); + PrintError("Unable to find pointer %x!", aPtr); return { "", 0 }; } @@ -320,6 +326,13 @@ static void *GetPointerFromData(GfxData *aGfxData, const String &aPtrName, u32 a return (void *) (_Node->mData + aPtrData); } } + + // Behavior scripts + for (auto &_Node : aGfxData->mBehaviorScripts) { + if (_Node->mName == aPtrName) { + return (void *) _Node->mData; + } + } // Macro objects for (auto &_Node : aGfxData->mMacroObjects) { @@ -356,7 +369,7 @@ static void *GetPointerFromData(GfxData *aGfxData, const String &aPtrName, u32 a } } - // Behaviors + // Lua Behaviors enum BehaviorId id = get_id_from_behavior_name(aPtrName.begin()); if (id >= 0 && id < id_bhv_max_count) { return (void*)get_behavior_from_id(id); @@ -374,11 +387,17 @@ static void *GetPointerFromData(GfxData *aGfxData, const String &aPtrName, u32 a return (void*)builtinGeo; } - // Built-in Lvl Cols - auto builtinCol = DynOS_Builtin_LvlCol_GetFromName(aPtrName.begin()); + // Built-in Cols + auto builtinCol = DynOS_Builtin_Col_GetFromName(aPtrName.begin()); if (builtinCol != NULL) { return (void*)builtinCol; } + + // Built-in Animations + auto builtinAnim = DynOS_Builtin_Anim_GetFromName(aPtrName.begin()); + if (builtinAnim != NULL) { + return (void *)builtinAnim; + } // Built-in Script Pointers auto builtinScriptPtr = DynOS_Builtin_ScriptPtr_GetFromName(aPtrName.begin()); diff --git a/data/dynos_bin_read.cpp b/data/dynos_bin_read.cpp index e19aef5d..e3e6f277 100644 --- a/data/dynos_bin_read.cpp +++ b/data/dynos_bin_read.cpp @@ -214,6 +214,8 @@ void DynOS_Read_Source(GfxData *aGfxData, const SysPath &aFilename) { _DataType = DATA_TYPE_MOVTEX; } else if (_Buffer == "MovtexQuadCollection") { _DataType = DATA_TYPE_MOVTEXQC; + } else if (_Buffer == "BehaviorScript") { + _DataType = DATA_TYPE_BEHAVIOR_SCRIPT; } else { PrintError(" ERROR: Unknown type name: %s", _Buffer.begin()); } @@ -237,22 +239,23 @@ void DynOS_Read_Source(GfxData *aGfxData, const SysPath &aFilename) { // Adding new data node else if (_Buffer.Length() != 0) { switch (_DataType) { - case DATA_TYPE_LIGHT: AppendNewNode(aGfxData, aGfxData->mLights, _Buffer, pDataName, pDataTokens); break; - case DATA_TYPE_LIGHT_T: AppendNewNode(aGfxData, aGfxData->mLightTs, _Buffer, pDataName, pDataTokens); break; - case DATA_TYPE_AMBIENT_T: AppendNewNode(aGfxData, aGfxData->mAmbientTs, _Buffer, pDataName, pDataTokens); break; - case DATA_TYPE_TEXTURE: AppendNewNode(aGfxData, aGfxData->mTextures, _Buffer, pDataName, pDataTokens); break; - case DATA_TYPE_TEXTURE_LIST: AppendNewNode(aGfxData, aGfxData->mTextureLists, _Buffer, pDataName, pDataTokens); break; - case DATA_TYPE_VERTEX: AppendNewNode(aGfxData, aGfxData->mVertices, _Buffer, pDataName, pDataTokens); break; - case DATA_TYPE_DISPLAY_LIST: AppendNewNode(aGfxData, aGfxData->mDisplayLists, _Buffer, pDataName, pDataTokens); break; - case DATA_TYPE_GEO_LAYOUT: AppendNewNode(aGfxData, aGfxData->mGeoLayouts, _Buffer, pDataName, pDataTokens); break; - case DATA_TYPE_COLLISION: AppendNewNode(aGfxData, aGfxData->mCollisions, _Buffer, pDataName, pDataTokens); break; - case DATA_TYPE_LEVEL_SCRIPT: AppendNewNode(aGfxData, aGfxData->mLevelScripts, _Buffer, pDataName, pDataTokens); break; - case DATA_TYPE_MACRO_OBJECT: AppendNewNode(aGfxData, aGfxData->mMacroObjects, _Buffer, pDataName, pDataTokens); break; - case DATA_TYPE_TRAJECTORY: AppendNewNode(aGfxData, aGfxData->mTrajectories, _Buffer, pDataName, pDataTokens); break; - case DATA_TYPE_MOVTEX: AppendNewNode(aGfxData, aGfxData->mMovtexs, _Buffer, pDataName, pDataTokens); break; - case DATA_TYPE_MOVTEXQC: AppendNewNode(aGfxData, aGfxData->mMovtexQCs, _Buffer, pDataName, pDataTokens); break; - case DATA_TYPE_ROOMS: AppendNewNode(aGfxData, aGfxData->mRooms, _Buffer, pDataName, pDataTokens); break; - case DATA_TYPE_UNUSED: pDataTokens = (Array *) 1; break; + case DATA_TYPE_LIGHT: AppendNewNode(aGfxData, aGfxData->mLights, _Buffer, pDataName, pDataTokens); break; + case DATA_TYPE_LIGHT_T: AppendNewNode(aGfxData, aGfxData->mLightTs, _Buffer, pDataName, pDataTokens); break; + case DATA_TYPE_AMBIENT_T: AppendNewNode(aGfxData, aGfxData->mAmbientTs, _Buffer, pDataName, pDataTokens); break; + case DATA_TYPE_TEXTURE: AppendNewNode(aGfxData, aGfxData->mTextures, _Buffer, pDataName, pDataTokens); break; + case DATA_TYPE_TEXTURE_LIST: AppendNewNode(aGfxData, aGfxData->mTextureLists, _Buffer, pDataName, pDataTokens); break; + case DATA_TYPE_VERTEX: AppendNewNode(aGfxData, aGfxData->mVertices, _Buffer, pDataName, pDataTokens); break; + case DATA_TYPE_DISPLAY_LIST: AppendNewNode(aGfxData, aGfxData->mDisplayLists, _Buffer, pDataName, pDataTokens); break; + case DATA_TYPE_GEO_LAYOUT: AppendNewNode(aGfxData, aGfxData->mGeoLayouts, _Buffer, pDataName, pDataTokens); break; + case DATA_TYPE_COLLISION: AppendNewNode(aGfxData, aGfxData->mCollisions, _Buffer, pDataName, pDataTokens); break; + case DATA_TYPE_LEVEL_SCRIPT: AppendNewNode(aGfxData, aGfxData->mLevelScripts, _Buffer, pDataName, pDataTokens); break; + case DATA_TYPE_MACRO_OBJECT: AppendNewNode(aGfxData, aGfxData->mMacroObjects, _Buffer, pDataName, pDataTokens); break; + case DATA_TYPE_TRAJECTORY: AppendNewNode(aGfxData, aGfxData->mTrajectories, _Buffer, pDataName, pDataTokens); break; + case DATA_TYPE_MOVTEX: AppendNewNode(aGfxData, aGfxData->mMovtexs, _Buffer, pDataName, pDataTokens); break; + case DATA_TYPE_MOVTEXQC: AppendNewNode(aGfxData, aGfxData->mMovtexQCs, _Buffer, pDataName, pDataTokens); break; + case DATA_TYPE_ROOMS: AppendNewNode(aGfxData, aGfxData->mRooms, _Buffer, pDataName, pDataTokens); break; + case DATA_TYPE_BEHAVIOR_SCRIPT: AppendNewNode(aGfxData, aGfxData->mBehaviorScripts, _Buffer, pDataName, pDataTokens); break; + case DATA_TYPE_UNUSED: pDataTokens = (Array *) 1; break; } _Buffer.Clear(); } diff --git a/data/dynos_bin_utils.cpp b/data/dynos_bin_utils.cpp index ee18784b..af13e436 100644 --- a/data/dynos_bin_utils.cpp +++ b/data/dynos_bin_utils.cpp @@ -89,6 +89,10 @@ void DynOS_Gfx_Free(GfxData* aGfxData) { Delete(_Node->mData); Delete(_Node); } + for (auto& _Node : aGfxData->mBehaviorScripts) { + Delete(_Node->mData); + Delete(_Node); + } for (auto& _Node : aGfxData->mLevelScripts) { Delete(_Node->mData); Delete(_Node); diff --git a/data/dynos_c.cpp b/data/dynos_c.cpp index 154013dc..c01d4ef3 100644 --- a/data/dynos_c.cpp +++ b/data/dynos_c.cpp @@ -160,6 +160,24 @@ void dynos_level_load_background(void *ptr) { DynOS_Lvl_LoadBackground(ptr); } +// -- Behaviors -- // + +void dynos_add_behavior(s32 modIndex, const char *filePath, const char *behaviorName) { + DynOS_Bhv_Activate(modIndex, filePath, behaviorName); +} + +s32 dynos_behavior_get_active_mod_index(BehaviorScript *bhvScript) { + return DynOS_Bhv_GetActiveModIndex(bhvScript); +} + +const char *dynos_behavior_get_token(BehaviorScript *bhvScript, u32 index) { + return DynOS_Bhv_GetToken(bhvScript, index); +} + +void dynos_behavior_hook_all_custom_behaviors(void) { + DynOS_Bhv_HookAllCustomBehaviors(); +} + // -- other -- // void dynos_mod_shutdown(void) { DynOS_Mod_Shutdown(); diff --git a/data/dynos_file.cpp b/data/dynos_file.cpp new file mode 100644 index 00000000..2b995627 --- /dev/null +++ b/data/dynos_file.cpp @@ -0,0 +1,10 @@ +#include "dynos.cpp.h" + +void SkipBytes(FILE *aFile, size_t amount) { + // If we're at end of file. There is no more to skip. + if (feof(aFile)) { return; } + + int failure = fseek(aFile, amount, SEEK_CUR); + // If we failed to skip bytes. Print the error. + if (failure) { perror("The following error occured when skipping bytes"); } +} \ No newline at end of file diff --git a/data/dynos_gfx_init.cpp b/data/dynos_gfx_init.cpp index 726dce21..468cd265 100644 --- a/data/dynos_gfx_init.cpp +++ b/data/dynos_gfx_init.cpp @@ -19,6 +19,12 @@ void DynOS_Gfx_GeneratePacks(const char* directory) { if (fs_sys_dir_exists(_ActorPackFolder.c_str())) { DynOS_Actor_GeneratePack(_ActorPackFolder); } + + SysPath _BehaviorPackFolder = fstring("%s/%s/data", directory, dir->d_name); + if (fs_sys_dir_exists(_BehaviorPackFolder.c_str())) { + DynOS_Bhv_GeneratePack(_BehaviorPackFolder); + } + SysPath _TexturePackFolder = fstring("%s/%s", directory, dir->d_name); SysPath _TexturePackOutputFolder = fstring("%s/%s/textures", directory, dir->d_name); if (fs_sys_dir_exists(_TexturePackFolder.c_str())) { diff --git a/data/dynos_main.cpp b/data/dynos_main.cpp index c66439ff..3c54c8a7 100644 --- a/data/dynos_main.cpp +++ b/data/dynos_main.cpp @@ -78,6 +78,7 @@ void DynOS_Mod_Update() { DynOS_Actor_ModShutdown(); DynOS_Col_ModShutdown(); DynOS_Lvl_ModShutdown(); + DynOS_Bhv_ModShutdown(); DynOS_MovtexQC_ModShutdown(); DynOS_Tex_ModShutdown(); } diff --git a/data/dynos_mgr_bhv.cpp b/data/dynos_mgr_bhv.cpp new file mode 100644 index 00000000..10b25a03 --- /dev/null +++ b/data/dynos_mgr_bhv.cpp @@ -0,0 +1,105 @@ +#include "dynos.cpp.h" + +extern "C" { +#include "engine/behavior_script.h" +#include "src/pc/lua/smlua_hooks.h" +} + +Array> &DynOS_Bhv_GetArray() { + static Array> sDynosCustomBehaviorScripts; + return sDynosCustomBehaviorScripts; +} + +void DynOS_Bhv_Activate(s32 modIndex, const SysPath &aFilename, const char *aBehaviorName) { + auto &_CustomBehaviorScripts = DynOS_Bhv_GetArray(); + + // check for duplicates + for (s32 i = 0; i < _CustomBehaviorScripts.Count(); ++i) { + if (!strcmp(_CustomBehaviorScripts[i].first, aBehaviorName)) { + return; + } + } + + u16 behaviorLen = strlen(aBehaviorName); + char *behaviorName = (char *)calloc(1, sizeof(char) * (behaviorLen + 1)); + strcpy(behaviorName, aBehaviorName); + + GfxData *_Node = DynOS_Bhv_LoadFromBinary(aFilename, behaviorName); + if (!_Node) { + free(behaviorName); + return; + } + + // Remember index + _Node->mModIndex = modIndex; + + // Add to behaviors + _CustomBehaviorScripts.Add({ behaviorName, _Node }); +} + +void DynOS_Bhv_ModShutdown() { + auto &_CustomBehaviorScripts = DynOS_Bhv_GetArray(); + while (_CustomBehaviorScripts.Count() > 0) { + auto &pair = _CustomBehaviorScripts[0]; + Delete(pair.second); + free((void *)pair.first); + _CustomBehaviorScripts.Remove(0); + } +} + +GfxData *DynOS_Bhv_GetActiveGfx(BehaviorScript *bhvScript) { + auto &_CustomBehaviorScripts = DynOS_Bhv_GetArray(); + + for (s32 i = 0; i < _CustomBehaviorScripts.Count(); ++i) { + auto &gfxData = _CustomBehaviorScripts[i].second; + auto &scripts = gfxData->mBehaviorScripts; + if (bhvScript == scripts[scripts.Count() - 1]->mData) { + return gfxData; + } + } + return NULL; +} + +s32 DynOS_Bhv_GetActiveModIndex(BehaviorScript *bhvScript) { + auto &_CustomBehaviorScripts = DynOS_Bhv_GetArray(); + + for (s32 i = 0; i < _CustomBehaviorScripts.Count(); ++i) { + auto &gfxData = _CustomBehaviorScripts[i].second; + auto &scripts = gfxData->mBehaviorScripts; + if (bhvScript == scripts[scripts.Count() - 1]->mData) { + return gfxData->mModIndex; + } + } + return -1; +} + +const char *DynOS_Bhv_GetToken(BehaviorScript *bhvScript, u32 index) { + GfxData *gfxData = DynOS_Bhv_GetActiveGfx(bhvScript); + if (gfxData == NULL) { + return NULL; + } + + // have to 1-index due to to pointer read code + index = index - 1; + + if (index >= gfxData->mLuaTokenList.Count()) { + return NULL; + } + + return gfxData->mLuaTokenList[index].begin(); +} + +void DynOS_Bhv_HookAllCustomBehaviors() { + auto &_CustomBehaviorScripts = DynOS_Bhv_GetArray(); + + for (s32 i = 0; i < _CustomBehaviorScripts.Count(); ++i) { + auto &scriptName = _CustomBehaviorScripts[i].first; + auto &aGfxData = _CustomBehaviorScripts[i].second; + auto &script = aGfxData->mBehaviorScripts[aGfxData->mBehaviorScripts.Count() - 1]->mData; + + // Theres currently no better place but to do this here. + if (hook_behavior(script, scriptName) == 0) { + PrintError(" ERROR: Failed to add custom behavior '%s'!", scriptName); + } + } +} \ No newline at end of file diff --git a/data/dynos_mgr_builtin.cpp b/data/dynos_mgr_builtin.cpp index 1b478b02..c0c1af43 100644 --- a/data/dynos_mgr_builtin.cpp +++ b/data/dynos_mgr_builtin.cpp @@ -4,6 +4,7 @@ extern "C" { #include "levels/scripts.h" #include "object_fields.h" #include "engine/level_script.h" +#include "engine/surface_load.h" #include "game/object_helpers.h" #include "game/segment2.h" #include "game/level_geo.h" @@ -13,6 +14,8 @@ extern "C" { #include "game/geo_misc.h" #include "game/mario_misc.h" #include "game/mario_actions_cutscene.h" +#include "game/obj_behaviors.h" +#include "game/obj_behaviors_2.h" #include "game/screen_transition.h" #include "game/object_list_processor.h" #include "game/behavior_actions.h" @@ -81,6 +84,8 @@ extern "C" { #define define_builtin(_ptr) (const void*)#_ptr, (const void*)_ptr +#define define_animation_builtin(_ptr) (const void*)#_ptr, (const void*)_ptr + #define MGR_FIND_DATA(_DataTable, _Cast) \ size_t _count = sizeof(_DataTable) / (2 * sizeof(_DataTable[0])); \ for (u32 _i = 0; _i < _count; _i++) { \ @@ -89,6 +94,21 @@ extern "C" { } \ } \ return NULL; + +#define MGR_FIND_DATA_FROM_TABLES(_DataTable, _DataTable2, _Cast) \ + size_t _count = sizeof(_DataTable) / (2 * sizeof(_DataTable[0])); \ + for (u32 _i = 0; _i < _count; _i++) { \ + if (!strcmp((const char*)_DataTable[_i * 2 + 0], aDataName)) { \ + return _Cast _DataTable[_i * 2 + 1]; \ + } \ + } \ + _count = sizeof(_DataTable2) / (2 * sizeof(_DataTable2[0])); \ + for (u32 _i = 0; _i < _count; _i++) { \ + if (!strcmp((const char*)_DataTable2[_i * 2 + 0], aDataName)) { \ + return _Cast _DataTable2[_i * 2 + 1]; \ + } \ + } \ + return NULL; #define MGR_FIND_NAME(_DataTable) \ size_t _count = sizeof(_DataTable) / (2 * sizeof(_DataTable[0])); \ @@ -854,10 +874,11 @@ const char* DynOS_Builtin_LvlGeo_GetFromData(const GeoLayout* aData) { } //////////////// - // Level Cols // + // Collisions // //////////////// -static const void* sDynosBuiltinLvlCols[] = { +static const void* sDynosBuiltinCols[] = { + // Level Collisions define_builtin(bbh_seg7_collision_07026B1C), define_builtin(bbh_seg7_collision_coffin), define_builtin(bbh_seg7_collision_haunted_bookshelf), @@ -1060,14 +1081,187 @@ static const void* sDynosBuiltinLvlCols[] = { define_builtin(wf_seg7_collision_trapezoid), define_builtin(wf_seg7_collision_tumbling_bridge), define_builtin(wmotr_seg7_collision), + + // Actor Collisions + define_builtin(bbh_seg7_collision_coffin), + define_builtin(bbh_seg7_collision_haunted_bookshelf), + define_builtin(bbh_seg7_collision_merry_go_round), + define_builtin(bbh_seg7_collision_mesh_elevator), + define_builtin(bbh_seg7_collision_staircase_step), + define_builtin(bbh_seg7_collision_tilt_floor_platform), + define_builtin(bitdw_seg7_collision_moving_pyramid), + define_builtin(bitfs_seg7_collision_inverted_pyramid), + define_builtin(bitfs_seg7_collision_sinking_cage_platform), + define_builtin(bitfs_seg7_collision_sinking_platform), + define_builtin(bitfs_seg7_collision_squishable_platform), + define_builtin(blue_coin_switch_seg8_collision_08000E98), + define_builtin(bob_seg7_collision_chain_chomp_gate), + define_builtin(bowser_2_seg7_collision_tilting_platform), + define_builtin(breakable_box_seg8_collision_08012D70), + define_builtin(cannon_lid_seg8_collision_08004950), + define_builtin(capswitch_collision_050033D0), + define_builtin(capswitch_collision_05003448), + define_builtin(castle_grounds_seg7_collision_cannon_grill), + define_builtin(castle_grounds_seg7_collision_moat_grills), + define_builtin(checkerboard_platform_seg8_collision_0800D710), + define_builtin(ddd_seg7_collision_bowser_sub_door), + define_builtin(ddd_seg7_collision_submarine), + define_builtin(door_seg3_collision_0301CE78), + define_builtin(dorrie_seg6_collision_0600F644), + define_builtin(dorrie_seg6_collision_0600FBB8), + define_builtin(exclamation_box_outline_seg8_collision_08025F78), + define_builtin(hmc_seg7_collision_controllable_platform), + define_builtin(hmc_seg7_collision_controllable_platform_sub), + define_builtin(hmc_seg7_collision_elevator), + define_builtin(inside_castle_seg7_collision_floor_trap), + define_builtin(inside_castle_seg7_collision_star_door), + define_builtin(inside_castle_seg7_collision_water_level_pillar), + define_builtin(jrb_seg7_collision_floating_box), + define_builtin(jrb_seg7_collision_floating_platform), + define_builtin(jrb_seg7_collision_in_sunken_ship), + define_builtin(jrb_seg7_collision_in_sunken_ship_2), + define_builtin(jrb_seg7_collision_in_sunken_ship_3), + define_builtin(jrb_seg7_collision_pillar_base), + define_builtin(jrb_seg7_collision_rock_solid), + define_builtin(lll_hexagonal_mesh_seg3_collision_0301CECC), + define_builtin(lll_seg7_collision_drawbridge), + define_builtin(lll_seg7_collision_falling_wall), + define_builtin(lll_seg7_collision_floating_block), + define_builtin(lll_seg7_collision_hexagonal_platform), + define_builtin(lll_seg7_collision_inverted_pyramid), + define_builtin(lll_seg7_collision_octagonal_moving_platform), + define_builtin(lll_seg7_collision_pitoune), + define_builtin(lll_seg7_collision_puzzle_piece), + define_builtin(lll_seg7_collision_rotating_fire_bars), + define_builtin(lll_seg7_collision_rotating_platform), + define_builtin(lll_seg7_collision_sinking_pyramids), + define_builtin(lll_seg7_collision_slow_tilting_platform), + define_builtin(lll_seg7_collision_wood_piece), + define_builtin(metal_box_seg8_collision_08024C28), + define_builtin(penguin_seg5_collision_05008B88), + define_builtin(poundable_pole_collision_06002490), + define_builtin(purple_switch_seg8_collision_0800C7A8), + define_builtin(rr_seg7_collision_donut_platform), + define_builtin(rr_seg7_collision_elevator_platform), + define_builtin(rr_seg7_collision_pendulum), + define_builtin(rr_seg7_collision_rotating_platform_with_fire), + define_builtin(sl_seg7_collision_pound_explodes), + define_builtin(sl_seg7_collision_sliding_snow_mound), + define_builtin(springboard_collision_05001A28), + define_builtin(ssl_seg7_collision_0702808C), + define_builtin(ssl_seg7_collision_grindel), + define_builtin(ssl_seg7_collision_pyramid_elevator), + define_builtin(ssl_seg7_collision_pyramid_top), + define_builtin(ssl_seg7_collision_spindel), + define_builtin(ssl_seg7_collision_tox_box), + define_builtin(thi_seg7_collision_top_trap), + define_builtin(thwomp_seg5_collision_0500B7D0), + define_builtin(thwomp_seg5_collision_0500B92C), + define_builtin(ttc_seg7_collision_clock_main_rotation), + define_builtin(ttc_seg7_collision_clock_pendulum), + define_builtin(ttc_seg7_collision_clock_platform), + define_builtin(ttc_seg7_collision_rotating_clock_platform2), + define_builtin(ttc_seg7_collision_sliding_surface), + define_builtin(ttm_seg7_collision_pitoune_2), + define_builtin(ttm_seg7_collision_podium_warp), + define_builtin(ttm_seg7_collision_ukiki_cage), + define_builtin(unknown_seg8_collision_080262F8), + define_builtin(warp_pipe_seg3_collision_03009AC8), + define_builtin(wdw_seg7_collision_arrow_lift), + define_builtin(wdw_seg7_collision_express_elevator_platform), + define_builtin(wdw_seg7_collision_rect_floating_platform), + define_builtin(wdw_seg7_collision_square_floating_platform), + define_builtin(wf_seg7_collision_breakable_wall), + define_builtin(wf_seg7_collision_breakable_wall_2), + define_builtin(wf_seg7_collision_bullet_bill_cannon), + define_builtin(wf_seg7_collision_clocklike_rotation), + define_builtin(wf_seg7_collision_kickable_board), + define_builtin(wf_seg7_collision_large_bomp), + define_builtin(wf_seg7_collision_platform), + define_builtin(wf_seg7_collision_sliding_brick_platform), + define_builtin(wf_seg7_collision_small_bomp), + define_builtin(wf_seg7_collision_tower), + define_builtin(wf_seg7_collision_tower_door), + define_builtin(whomp_seg6_collision_06020A0C), + define_builtin(wooden_signpost_seg3_collision_0302DD80), }; -const Collision* DynOS_Builtin_LvlCol_GetFromName(const char* aDataName) { - MGR_FIND_DATA(sDynosBuiltinLvlCols, (const Collision*)); +const Collision* DynOS_Builtin_Col_GetFromName(const char* aDataName) { + MGR_FIND_DATA(sDynosBuiltinCols, (const Collision*)); } -const char* DynOS_Builtin_LvlCol_GetFromData(const Collision* aData) { - MGR_FIND_NAME(sDynosBuiltinLvlCols); +const char* DynOS_Builtin_Col_GetFromData(const Collision* aData) { + MGR_FIND_NAME(sDynosBuiltinCols); +} + + //////////////// + // Animations // +//////////////// + +static const void* sDynosBuiltinAnims[] = { + define_builtin(amp_seg8_anims_08004034), + define_builtin(bobomb_seg8_anims_0802396C), + define_builtin(chuckya_seg8_anims_0800C070), + define_builtin(flyguy_seg8_anims_08011A64), + define_builtin(goomba_seg8_anims_0801DA4C), + define_builtin(blue_fish_seg3_anims_0301C2B0), + define_builtin(bowser_key_seg3_anims_list), + define_builtin(butterfly_seg3_anims_030056B0), + define_builtin(door_seg3_anims_030156C0), + define_builtin(heave_ho_seg5_anims_0501534C), + define_builtin(hoot_seg5_anims_05005768), + define_builtin(blargg_seg5_anims_0500616C), + define_builtin(bully_seg5_anims_0500470C), + define_builtin(king_bobomb_seg5_anims_0500FE30), + define_builtin(clam_shell_seg5_anims_05001744), + define_builtin(manta_seg5_anims_05008EB4), + define_builtin(sushi_seg5_anims_0500AE54), + define_builtin(unagi_seg5_anims_05012824), + define_builtin(eyerok_seg5_anims_050116E4), + define_builtin(klepto_seg5_anims_05008CFC), + define_builtin(monty_mole_seg5_anims_05007248), + define_builtin(ukiki_seg5_anims_05015784), + define_builtin(penguin_seg5_anims_05008B74), + define_builtin(snowman_seg5_anims_0500D118), + define_builtin(spindrift_seg5_anims_05002D68), + define_builtin(bookend_seg5_anims_05002540), + define_builtin(chair_seg5_anims_05005784), + define_builtin(mad_piano_seg5_anims_05009B14), + define_builtin(birds_seg5_anims_050009E8), + define_builtin(peach_seg5_anims_0501C41C), + define_builtin(yoshi_seg5_anims_05024100), + define_builtin(lakitu_enemy_seg5_anims_050144D4), + define_builtin(spiny_seg5_anims_05016EAC), + define_builtin(spiny_egg_seg5_anims_050157E4), + define_builtin(wiggler_seg5_anims_0500C874), + define_builtin(wiggler_seg5_anims_0500EC8C), + define_builtin(bowser_seg6_anims_06057690), + define_builtin(bub_seg6_anims_06012354), + define_builtin(cyan_fish_seg6_anims_0600E264), + define_builtin(seaweed_seg6_anims_0600A4D4), + define_builtin(skeeter_seg6_anims_06007DE0), + define_builtin(water_ring_seg6_anims_06013F7C), + define_builtin(chain_chomp_seg6_anims_06025178), + define_builtin(koopa_seg6_anims_06011364), + define_builtin(koopa_flag_seg6_anims_06001028), + define_builtin(piranha_plant_seg6_anims_0601C31C), + define_builtin(whomp_seg6_anims_06020A04), + define_builtin(lakitu_seg6_anims_060058F8), + define_builtin(mips_seg6_anims_06015634), + define_builtin(toad_seg6_anims_0600FB58), + define_builtin(chilly_chief_seg6_anims_06003994), + define_builtin(moneybag_seg6_anims_06005E5C), + define_builtin(dorrie_seg6_anims_0600F638), + define_builtin(scuttlebug_seg6_anims_06015064), + define_builtin(swoop_seg6_anims_060070D0), +}; + +const Animation *DynOS_Builtin_Anim_GetFromName(const char *aDataName) { + MGR_FIND_DATA(sDynosBuiltinAnims, (const Animation *)); +} + +const char *DynOS_Builtin_Anim_GetFromData(const Animation *aData) { + MGR_FIND_NAME(sDynosBuiltinAnims); } //////////////////// @@ -1140,11 +1334,570 @@ static const void* sDynosBuiltinFuncs[] = { (const void *) "geo_rotate_coin", (const void *) geo_rotate_3d_coin, define_builtin(geo_offset_klepto_held_object), define_builtin(geo_switch_peach_eyes), - // coop-specific + + // Co-op specific define_builtin(geo_mario_set_player_colors), define_builtin(geo_movtex_draw_water_regions_ext), define_builtin(lvl_init_or_update), define_builtin(geo_choose_area_ext), + + // Behaviors + define_builtin(bhv_cap_switch_loop), + define_builtin(bhv_tiny_star_particles_init), + define_builtin(bhv_grindel_thwomp_loop), + define_builtin(bhv_koopa_shell_underwater_loop), + define_builtin(bhv_door_init), + define_builtin(bhv_door_loop), + define_builtin(bhv_star_door_loop), + define_builtin(bhv_star_door_loop_2), + define_builtin(bhv_mr_i_loop), + define_builtin(bhv_mr_i_body_loop), + define_builtin(bhv_mr_i_particle_loop), + define_builtin(bhv_piranha_particle_loop), + define_builtin(bhv_giant_pole_loop), + define_builtin(bhv_pole_init), + define_builtin(bhv_pole_base_loop), + define_builtin(bhv_thi_huge_island_top_loop), + define_builtin(bhv_thi_tiny_island_top_loop), + define_builtin(bhv_king_bobomb_loop), + define_builtin(bhv_bobomb_anchor_mario_loop), + define_builtin(bhv_beta_chest_bottom_init), + define_builtin(bhv_beta_chest_bottom_loop), + define_builtin(bhv_beta_chest_lid_loop), + define_builtin(bhv_bubble_wave_init), + define_builtin(bhv_bubble_maybe_loop), + define_builtin(bhv_bubble_player_loop), + define_builtin(bhv_water_air_bubble_init), + define_builtin(bhv_water_air_bubble_loop), + define_builtin(bhv_particle_init), + define_builtin(bhv_particle_loop), + define_builtin(bhv_water_waves_init), + define_builtin(bhv_small_bubbles_loop), + define_builtin(bhv_fish_group_loop), + define_builtin(bhv_cannon_base_loop), + define_builtin(bhv_cannon_barrel_loop), + define_builtin(bhv_cannon_base_unused_loop), + define_builtin(bhv_chuckya_loop), + define_builtin(bhv_chuckya_anchor_mario_loop), + define_builtin(bhv_rotating_platform_loop), + define_builtin(bhv_wf_breakable_wall_loop), + define_builtin(bhv_kickable_board_loop), + define_builtin(bhv_tower_door_loop), + define_builtin(bhv_wf_rotating_wooden_platform_init), + define_builtin(bhv_wf_rotating_wooden_platform_loop), + define_builtin(bhv_fading_warp_loop), + define_builtin(bhv_warp_loop), + define_builtin(bhv_white_puff_exploding_loop), + define_builtin(bhv_spawned_star_init), + define_builtin(bhv_spawned_star_loop), + define_builtin(bhv_coin_init), + define_builtin(bhv_coin_loop), + define_builtin(bhv_coin_inside_boo_loop), + define_builtin(bhv_coin_formation_init), + define_builtin(bhv_coin_formation_spawn_loop), + define_builtin(bhv_coin_formation_loop), + define_builtin(bhv_temp_coin_loop), + define_builtin(bhv_coin_sparkles_loop), + define_builtin(bhv_golden_coin_sparkles_loop), + define_builtin(bhv_wall_tiny_star_particle_loop), + define_builtin(bhv_pound_tiny_star_particle_loop), + define_builtin(bhv_pound_tiny_star_particle_init), + define_builtin(bhv_punch_tiny_triangle_loop), + define_builtin(bhv_punch_tiny_triangle_init), + define_builtin(bhv_tumbling_bridge_platform_loop), + define_builtin(bhv_tumbling_bridge_loop), + define_builtin(bhv_elevator_init), + define_builtin(bhv_elevator_loop), + define_builtin(bhv_water_mist_loop), + define_builtin(bhv_water_mist_spawn_loop), + define_builtin(bhv_water_mist_2_loop), + define_builtin(bhv_pound_white_puffs_init), + define_builtin(bhv_ground_sand_init), + define_builtin(bhv_ground_snow_init), + define_builtin(bhv_wind_loop), + define_builtin(bhv_unused_particle_spawn_loop), + define_builtin(bhv_ukiki_cage_star_loop), + define_builtin(bhv_ukiki_cage_loop), + define_builtin(bhv_bitfs_sinking_platform_loop), + define_builtin(bhv_bitfs_sinking_cage_platform_loop), + define_builtin(bhv_ddd_moving_pole_loop), + define_builtin(bhv_platform_normals_init), + define_builtin(bhv_tilting_inverted_pyramid_loop), + define_builtin(bhv_squishable_platform_loop), + define_builtin(bhv_beta_moving_flames_spawn_loop), + define_builtin(bhv_beta_moving_flames_loop), + define_builtin(bhv_rr_rotating_bridge_platform_loop), + define_builtin(bhv_flamethrower_loop), + define_builtin(bhv_flamethrower_flame_loop), + define_builtin(bhv_bouncing_fireball_loop), + define_builtin(bhv_bouncing_fireball_flame_loop), + define_builtin(bhv_bowser_shock_wave_loop), + define_builtin(bhv_flame_mario_loop), + define_builtin(bhv_black_smoke_mario_loop), + define_builtin(bhv_black_smoke_bowser_loop), + define_builtin(bhv_black_smoke_upward_loop), + define_builtin(bhv_beta_fish_splash_spawner_loop), + define_builtin(bhv_spindrift_loop), + define_builtin(bhv_tower_platform_group_init), + define_builtin(bhv_tower_platform_group_loop), + define_builtin(bhv_wf_sliding_tower_platform_loop), + define_builtin(bhv_wf_elevator_tower_platform_loop), + define_builtin(bhv_wf_solid_tower_platform_loop), + define_builtin(bhv_snow_leaf_particle_spawn_init), + define_builtin(bhv_tree_snow_or_leaf_loop), + define_builtin(bhv_piranha_plant_bubble_loop), + define_builtin(bhv_piranha_plant_waking_bubbles_loop), + define_builtin(bhv_purple_switch_loop), + define_builtin(bhv_hidden_object_loop), + define_builtin(bhv_breakable_box_loop), + define_builtin(bhv_pushable_loop), + define_builtin(bhv_init_room), + define_builtin(bhv_small_water_wave_loop), + define_builtin(bhv_yellow_coin_init), + define_builtin(bhv_yellow_coin_loop), + define_builtin(bhv_squarish_path_moving_loop), + define_builtin(bhv_squarish_path_parent_init), + define_builtin(bhv_squarish_path_parent_loop), + define_builtin(bhv_heave_ho_loop), + define_builtin(bhv_heave_ho_throw_mario_loop), + define_builtin(bhv_ccm_touched_star_spawn_loop), + define_builtin(bhv_unused_poundable_platform), + define_builtin(bhv_beta_trampoline_top_loop), + define_builtin(bhv_beta_trampoline_spring_loop), + define_builtin(bhv_jumping_box_loop), + define_builtin(bhv_boo_cage_init), + define_builtin(bhv_boo_cage_loop), + define_builtin(bhv_bowser_key_init), + define_builtin(bhv_bowser_key_loop), + define_builtin(bhv_grand_star_init), + define_builtin(bhv_grand_star_loop), + define_builtin(bhv_beta_boo_key_loop), + define_builtin(bhv_alpha_boo_key_loop), + define_builtin(bhv_bullet_bill_init), + define_builtin(bhv_bullet_bill_loop), + define_builtin(bhv_white_puff_smoke_init), + define_builtin(bhv_bowser_tail_anchor_init), + define_builtin(bhv_bowser_tail_anchor_loop), + define_builtin(bhv_bowser_init), + define_builtin(bhv_bowser_loop), + define_builtin(bhv_bowser_body_anchor_init), + define_builtin(bhv_bowser_body_anchor_loop), + define_builtin(bhv_bowser_flame_spawn_loop), + define_builtin(bhv_tilting_bowser_lava_platform_init), + define_builtin(bhv_falling_bowser_platform_loop), + define_builtin(bhv_blue_bowser_flame_init), + define_builtin(bhv_blue_bowser_flame_loop), + define_builtin(bhv_flame_floating_landing_init), + define_builtin(bhv_flame_floating_landing_loop), + define_builtin(bhv_blue_flames_group_loop), + define_builtin(bhv_flame_bouncing_init), + define_builtin(bhv_flame_bouncing_loop), + define_builtin(bhv_flame_moving_forward_growing_init), + define_builtin(bhv_flame_moving_forward_growing_loop), + define_builtin(bhv_flame_bowser_init), + define_builtin(bhv_flame_bowser_loop), + define_builtin(bhv_flame_large_burning_out_init), + define_builtin(bhv_blue_fish_movement_loop), + define_builtin(bhv_tank_fish_group_loop), + define_builtin(bhv_checkerboard_elevator_group_init), + define_builtin(bhv_checkerboard_elevator_group_loop), + define_builtin(bhv_checkerboard_platform_init), + define_builtin(bhv_checkerboard_platform_loop), + define_builtin(bhv_bowser_key_unlock_door_loop), + define_builtin(bhv_bowser_key_course_exit_loop), + define_builtin(bhv_invisible_objects_under_bridge_init), + define_builtin(bhv_invisible_objects_under_bridge_loop), + define_builtin(bhv_water_level_pillar_init), + define_builtin(bhv_water_level_pillar_loop), + define_builtin(bhv_ddd_warp_loop), + define_builtin(bhv_moat_grills_loop), + define_builtin(bhv_rotating_clock_arm_loop), + define_builtin(bhv_ukiki_init), + define_builtin(bhv_ukiki_loop), + define_builtin(bhv_lll_sinking_rock_block_loop), + define_builtin(bhv_lll_moving_octagonal_mesh_platform_loop), + define_builtin(bhv_lll_rotating_block_fire_bars_loop), + define_builtin(bhv_lll_rotating_hex_flame_loop), + define_builtin(bhv_lll_wood_piece_loop), + define_builtin(bhv_lll_floating_wood_bridge_loop), + define_builtin(bhv_volcano_flames_loop), + define_builtin(bhv_lll_rotating_hexagonal_ring_loop), + define_builtin(bhv_lll_sinking_rectangular_platform_loop), + define_builtin(bhv_lll_sinking_square_platforms_loop), + define_builtin(bhv_koopa_shell_loop), + define_builtin(bhv_koopa_shell_flame_loop), + define_builtin(bhv_tox_box_loop), + define_builtin(bhv_piranha_plant_loop), + define_builtin(bhv_lll_bowser_puzzle_piece_loop), + define_builtin(bhv_lll_bowser_puzzle_loop), + define_builtin(bhv_tuxies_mother_loop), + define_builtin(bhv_small_penguin_loop), + define_builtin(bhv_fish_spawner_loop), + define_builtin(bhv_fish_loop), + define_builtin(bhv_wdw_express_elevator_loop), + define_builtin(bhv_bub_spawner_loop), + define_builtin(bhv_bub_loop), + define_builtin(bhv_exclamation_box_init), + define_builtin(bhv_exclamation_box_loop), + define_builtin(bhv_rotating_exclamation_box_loop), + define_builtin(bhv_sound_spawner_init), + define_builtin(bhv_bowsers_sub_loop), + define_builtin(bhv_sushi_shark_loop), + define_builtin(bhv_sushi_shark_collision_loop), + define_builtin(bhv_jrb_sliding_box_loop), + define_builtin(bhv_ship_part_3_loop), + define_builtin(bhv_sunken_ship_part_loop), + define_builtin(bhv_white_puff_1_loop), + define_builtin(bhv_white_puff_2_loop), + define_builtin(bhv_blue_coin_switch_loop), + define_builtin(bhv_hidden_blue_coin_loop), + define_builtin(bhv_openable_cage_door_loop), + define_builtin(bhv_openable_grill_loop), + define_builtin(bhv_water_level_diamond_loop), + define_builtin(bhv_init_changing_water_level_loop), + define_builtin(bhv_tweester_sand_particle_loop), + define_builtin(bhv_tweester_loop), + define_builtin(bhv_merry_go_round_boo_manager_loop), + define_builtin(bhv_animated_texture_loop), + define_builtin(bhv_boo_in_castle_loop), + define_builtin(bhv_boo_with_cage_init), + define_builtin(bhv_boo_with_cage_loop), + define_builtin(bhv_boo_init), + define_builtin(bhv_big_boo_loop), + define_builtin(bhv_courtyard_boo_triplet_init), + define_builtin(bhv_boo_loop), + define_builtin(bhv_boo_boss_spawned_bridge_loop), + define_builtin(bhv_bbh_tilting_trap_platform_loop), + define_builtin(bhv_haunted_bookshelf_loop), + define_builtin(bhv_merry_go_round_loop), + define_builtin(bhv_play_music_track_when_touched_loop), + define_builtin(bhv_beta_bowser_anchor_loop), + define_builtin(bhv_static_checkered_platform_loop), + define_builtin(bhv_castle_floor_trap_init), + define_builtin(bhv_castle_floor_trap_loop), + define_builtin(bhv_floor_trap_in_castle_loop), + define_builtin(bhv_sparkle_spawn_loop), + define_builtin(bhv_scuttlebug_loop), + define_builtin(bhv_scuttlebug_spawn_loop), + define_builtin(bhv_whomp_loop), + define_builtin(bhv_water_splash_spawn_droplets), + define_builtin(bhv_water_droplet_loop), + define_builtin(bhv_water_droplet_splash_init), + define_builtin(bhv_bubble_splash_init), + define_builtin(bhv_idle_water_wave_loop), + define_builtin(bhv_shallow_water_splash_init), + define_builtin(bhv_wave_trail_shrink), + define_builtin(bhv_strong_wind_particle_loop), + define_builtin(bhv_sl_snowman_wind_loop), + define_builtin(bhv_sl_walking_penguin_loop), + define_builtin(bhv_menu_button_init), + define_builtin(bhv_menu_button_loop), + define_builtin(bhv_menu_button_manager_init), + define_builtin(bhv_menu_button_manager_loop), + define_builtin(bhv_act_selector_star_type_loop), + define_builtin(bhv_act_selector_init), + define_builtin(bhv_act_selector_loop), + define_builtin(bhv_moving_yellow_coin_init), + define_builtin(bhv_moving_yellow_coin_loop), + define_builtin(bhv_moving_blue_coin_init), + define_builtin(bhv_moving_blue_coin_loop), + define_builtin(bhv_blue_coin_sliding_jumping_init), + define_builtin(bhv_blue_coin_sliding_loop), + define_builtin(bhv_blue_coin_jumping_loop), + define_builtin(bhv_seaweed_init), + define_builtin(bhv_seaweed_bundle_init), + define_builtin(bhv_bobomb_init), + define_builtin(bhv_bobomb_loop), + define_builtin(bhv_bobomb_fuse_smoke_init), + define_builtin(bhv_bobomb_buddy_init), + define_builtin(bhv_bobomb_buddy_loop), + define_builtin(bhv_cannon_closed_init), + define_builtin(bhv_cannon_closed_loop), + define_builtin(bhv_whirlpool_init), + define_builtin(bhv_whirlpool_loop), + define_builtin(bhv_jet_stream_loop), + define_builtin(bhv_homing_amp_init), + define_builtin(bhv_homing_amp_loop), + define_builtin(bhv_circling_amp_init), + define_builtin(bhv_circling_amp_loop), + define_builtin(bhv_butterfly_init), + define_builtin(bhv_butterfly_loop), + define_builtin(bhv_hoot_init), + define_builtin(bhv_hoot_loop), + define_builtin(bhv_beta_holdable_object_init), + define_builtin(bhv_beta_holdable_object_loop), + define_builtin(bhv_object_bubble_init), + define_builtin(bhv_object_bubble_loop), + define_builtin(bhv_object_water_wave_init), + define_builtin(bhv_object_water_wave_loop), + define_builtin(bhv_explosion_init), + define_builtin(bhv_explosion_loop), + define_builtin(bhv_bobomb_bully_death_smoke_init), + define_builtin(bhv_bobomb_explosion_bubble_init), + define_builtin(bhv_bobomb_explosion_bubble_loop), + define_builtin(bhv_respawner_loop), + define_builtin(bhv_small_bully_init), + define_builtin(bhv_bully_loop), + define_builtin(bhv_big_bully_init), + define_builtin(bhv_big_bully_with_minions_init), + define_builtin(bhv_big_bully_with_minions_loop), + define_builtin(bhv_jet_stream_ring_spawner_loop), + define_builtin(bhv_jet_stream_water_ring_init), + define_builtin(bhv_jet_stream_water_ring_loop), + define_builtin(bhv_manta_ray_water_ring_init), + define_builtin(bhv_manta_ray_water_ring_loop), + define_builtin(bhv_bowser_bomb_loop), + define_builtin(bhv_bowser_bomb_explosion_loop), + define_builtin(bhv_bowser_bomb_smoke_loop), + define_builtin(bhv_celebration_star_init), + define_builtin(bhv_celebration_star_loop), + define_builtin(bhv_celebration_star_sparkle_loop), + define_builtin(bhv_star_key_collection_puff_spawner_loop), + define_builtin(bhv_lll_drawbridge_spawner_init), + define_builtin(bhv_lll_drawbridge_spawner_loop), + define_builtin(bhv_lll_drawbridge_loop), + define_builtin(bhv_small_bomp_init), + define_builtin(bhv_small_bomp_loop), + define_builtin(bhv_large_bomp_init), + define_builtin(bhv_large_bomp_loop), + define_builtin(bhv_wf_sliding_platform_init), + define_builtin(bhv_wf_sliding_platform_loop), + define_builtin(bhv_moneybag_init), + define_builtin(bhv_moneybag_loop), + define_builtin(bhv_moneybag_hidden_loop), + define_builtin(bhv_bob_pit_bowling_ball_init), + define_builtin(bhv_bob_pit_bowling_ball_loop), + define_builtin(bhv_free_bowling_ball_init), + define_builtin(bhv_free_bowling_ball_loop), + define_builtin(bhv_bowling_ball_init), + define_builtin(bhv_bowling_ball_loop), + define_builtin(bhv_generic_bowling_ball_spawner_init), + define_builtin(bhv_generic_bowling_ball_spawner_loop), + define_builtin(bhv_thi_bowling_ball_spawner_loop), + define_builtin(bhv_rr_cruiser_wing_init), + define_builtin(bhv_rr_cruiser_wing_loop), + define_builtin(bhv_spindel_init), + define_builtin(bhv_spindel_loop), + define_builtin(bhv_ssl_moving_pyramid_wall_init), + define_builtin(bhv_ssl_moving_pyramid_wall_loop), + define_builtin(bhv_pyramid_elevator_init), + define_builtin(bhv_pyramid_elevator_loop), + define_builtin(bhv_pyramid_elevator_trajectory_marker_ball_loop), + define_builtin(bhv_pyramid_top_init), + define_builtin(bhv_pyramid_top_loop), + define_builtin(bhv_pyramid_top_fragment_init), + define_builtin(bhv_pyramid_top_fragment_loop), + define_builtin(bhv_pyramid_pillar_touch_detector_loop), + define_builtin(bhv_waterfall_sound_loop), + define_builtin(bhv_volcano_sound_loop), + define_builtin(bhv_castle_flag_init), + define_builtin(bhv_birds_sound_loop), + define_builtin(bhv_ambient_sounds_init), + define_builtin(bhv_sand_sound_loop), + define_builtin(bhv_castle_cannon_grate_init), + define_builtin(bhv_snowmans_bottom_init), + define_builtin(bhv_snowmans_bottom_loop), + define_builtin(bhv_snowmans_head_init), + define_builtin(bhv_snowmans_head_loop), + define_builtin(bhv_snowmans_body_checkpoint_loop), + define_builtin(bhv_big_boulder_init), + define_builtin(bhv_big_boulder_loop), + define_builtin(bhv_big_boulder_generator_loop), + define_builtin(bhv_wing_cap_init), + define_builtin(bhv_wing_vanish_cap_loop), + define_builtin(bhv_metal_cap_init), + define_builtin(bhv_metal_cap_loop), + define_builtin(bhv_normal_cap_init), + define_builtin(bhv_normal_cap_loop), + define_builtin(bhv_vanish_cap_init), + define_builtin(bhv_collect_star_init), + define_builtin(bhv_collect_star_loop), + define_builtin(bhv_star_spawn_init), + define_builtin(bhv_star_spawn_loop), + define_builtin(bhv_hidden_red_coin_star_init), + define_builtin(bhv_hidden_red_coin_star_loop), + define_builtin(bhv_red_coin_init), + define_builtin(bhv_red_coin_loop), + define_builtin(bhv_bowser_course_red_coin_star_loop), + define_builtin(bhv_hidden_star_init), + define_builtin(bhv_hidden_star_loop), + define_builtin(bhv_hidden_star_trigger_loop), + define_builtin(bhv_ttm_rolling_log_init), + define_builtin(bhv_rolling_log_loop), + define_builtin(bhv_lll_rolling_log_init), + define_builtin(bhv_1up_common_init), + define_builtin(bhv_1up_walking_loop), + define_builtin(bhv_1up_running_away_loop), + define_builtin(bhv_1up_sliding_loop), + define_builtin(bhv_1up_init), + define_builtin(bhv_1up_loop), + define_builtin(bhv_1up_jump_on_approach_loop), + define_builtin(bhv_1up_hidden_loop), + define_builtin(bhv_1up_hidden_trigger_loop), + define_builtin(bhv_1up_hidden_in_pole_loop), + define_builtin(bhv_1up_hidden_in_pole_trigger_loop), + define_builtin(bhv_1up_hidden_in_pole_spawner_loop), + define_builtin(bhv_controllable_platform_init), + define_builtin(bhv_controllable_platform_loop), + define_builtin(bhv_controllable_platform_sub_loop), + define_builtin(bhv_breakable_box_small_init), + define_builtin(bhv_breakable_box_small_loop), + define_builtin(bhv_sliding_snow_mound_loop), + define_builtin(bhv_snow_mound_spawn_loop), + define_builtin(bhv_floating_platform_loop), + define_builtin(bhv_arrow_lift_loop), + define_builtin(bhv_orange_number_init), + define_builtin(bhv_orange_number_loop), + define_builtin(bhv_manta_ray_init), + define_builtin(bhv_manta_ray_loop), + define_builtin(bhv_falling_pillar_init), + define_builtin(bhv_falling_pillar_loop), + define_builtin(bhv_falling_pillar_hitbox_loop), + define_builtin(bhv_jrb_floating_box_loop), + define_builtin(bhv_decorative_pendulum_init), + define_builtin(bhv_decorative_pendulum_loop), + define_builtin(bhv_treasure_chest_ship_init), + define_builtin(bhv_treasure_chest_ship_loop), + define_builtin(bhv_treasure_chest_jrb_init), + define_builtin(bhv_treasure_chest_jrb_loop), + define_builtin(bhv_treasure_chest_init), + define_builtin(bhv_treasure_chest_loop), + define_builtin(bhv_treasure_chest_bottom_init), + define_builtin(bhv_treasure_chest_bottom_loop), + define_builtin(bhv_treasure_chest_top_loop), + define_builtin(bhv_mips_init), + define_builtin(bhv_mips_loop), + define_builtin(bhv_yoshi_init), + define_builtin(bhv_koopa_init), + define_builtin(bhv_koopa_update), + define_builtin(bhv_koopa_race_endpoint_update), + define_builtin(bhv_pokey_update), + define_builtin(bhv_pokey_body_part_update), + define_builtin(bhv_swoop_update), + define_builtin(bhv_fly_guy_update), + define_builtin(bhv_goomba_init), + define_builtin(bhv_goomba_update), + define_builtin(bhv_goomba_triplet_spawner_update), + define_builtin(bhv_chain_chomp_update), + define_builtin(bhv_chain_chomp_chain_part_update), + define_builtin(bhv_wooden_post_update), + define_builtin(bhv_chain_chomp_gate_init), + define_builtin(bhv_chain_chomp_gate_update), + define_builtin(bhv_wiggler_update), + define_builtin(bhv_wiggler_body_part_update), + define_builtin(bhv_enemy_lakitu_update), + define_builtin(bhv_camera_lakitu_init), + define_builtin(bhv_camera_lakitu_update), + define_builtin(bhv_cloud_update), + define_builtin(bhv_cloud_part_update), + define_builtin(bhv_spiny_update), + define_builtin(bhv_monty_mole_init), + define_builtin(bhv_monty_mole_update), + define_builtin(bhv_monty_mole_hole_update), + define_builtin(bhv_monty_mole_rock_update), + define_builtin(bhv_platform_on_track_init), + define_builtin(bhv_platform_on_track_update), + define_builtin(bhv_track_ball_update), + define_builtin(bhv_seesaw_platform_init), + define_builtin(bhv_seesaw_platform_update), + define_builtin(bhv_ferris_wheel_axle_init), + define_builtin(bhv_ferris_wheel_platform_update), + define_builtin(bhv_water_bomb_spawner_update), + define_builtin(bhv_water_bomb_update), + define_builtin(bhv_water_bomb_shadow_update), + define_builtin(bhv_ttc_rotating_solid_init), + define_builtin(bhv_ttc_rotating_solid_update), + define_builtin(bhv_ttc_pendulum_init), + define_builtin(bhv_ttc_pendulum_update), + define_builtin(bhv_ttc_treadmill_init), + define_builtin(bhv_ttc_treadmill_update), + define_builtin(bhv_ttc_moving_bar_init), + define_builtin(bhv_ttc_moving_bar_update), + define_builtin(bhv_ttc_cog_init), + define_builtin(bhv_ttc_cog_update), + define_builtin(bhv_ttc_pit_block_init), + define_builtin(bhv_ttc_pit_block_update), + define_builtin(bhv_ttc_elevator_init), + define_builtin(bhv_ttc_elevator_update), + define_builtin(bhv_ttc_2d_rotator_init), + define_builtin(bhv_ttc_2d_rotator_update), + define_builtin(bhv_ttc_spinner_update), + define_builtin(bhv_mr_blizzard_init), + define_builtin(bhv_mr_blizzard_update), + define_builtin(bhv_mr_blizzard_snowball), + define_builtin(bhv_sliding_plat_2_init), + define_builtin(bhv_sliding_plat_2_loop), + define_builtin(bhv_rotating_octagonal_plat_init), + define_builtin(bhv_rotating_octagonal_plat_loop), + define_builtin(bhv_animates_on_floor_switch_press_init), + define_builtin(bhv_animates_on_floor_switch_press_loop), + define_builtin(bhv_activated_back_and_forth_platform_init), + define_builtin(bhv_activated_back_and_forth_platform_update), + define_builtin(bhv_recovery_heart_loop), + define_builtin(bhv_water_bomb_cannon_loop), + define_builtin(bhv_bubble_cannon_barrel_loop), + define_builtin(bhv_unagi_init), + define_builtin(bhv_unagi_loop), + define_builtin(bhv_unagi_subobject_loop), + define_builtin(bhv_dorrie_update), + define_builtin(bhv_haunted_chair_init), + define_builtin(bhv_haunted_chair_loop), + define_builtin(bhv_mad_piano_update), + define_builtin(bhv_flying_bookend_loop), + define_builtin(bhv_bookend_spawn_loop), + define_builtin(bhv_haunted_bookshelf_manager_loop), + define_builtin(bhv_book_switch_loop), + define_builtin(bhv_fire_piranha_plant_init), + define_builtin(bhv_fire_piranha_plant_update), + define_builtin(bhv_small_piranha_flame_loop), + define_builtin(bhv_fire_spitter_update), + define_builtin(bhv_fly_guy_flame_loop), + define_builtin(bhv_snufit_loop), + define_builtin(bhv_snufit_balls_loop), + define_builtin(bhv_horizontal_grindel_init), + define_builtin(bhv_horizontal_grindel_update), + define_builtin(bhv_eyerok_boss_init), + define_builtin(bhv_eyerok_boss_loop), + define_builtin(bhv_eyerok_hand_loop), + define_builtin(bhv_klepto_init), + define_builtin(bhv_klepto_update), + define_builtin(bhv_bird_update), + define_builtin(bhv_racing_penguin_init), + define_builtin(bhv_racing_penguin_update), + define_builtin(bhv_penguin_race_finish_line_update), + define_builtin(bhv_penguin_race_shortcut_check_update), + define_builtin(bhv_coffin_spawner_loop), + define_builtin(bhv_coffin_loop), + define_builtin(bhv_clam_loop), + define_builtin(bhv_skeeter_update), + define_builtin(bhv_skeeter_wave_update), + define_builtin(bhv_swing_platform_init), + define_builtin(bhv_swing_platform_update), + define_builtin(bhv_donut_platform_spawner_update), + define_builtin(bhv_donut_platform_update), + define_builtin(bhv_ddd_pole_init), + define_builtin(bhv_ddd_pole_update), + define_builtin(bhv_red_coin_star_marker_init), + define_builtin(bhv_triplet_butterfly_update), + define_builtin(bhv_bubba_loop), + define_builtin(bhv_intro_lakitu_loop), + define_builtin(bhv_intro_peach_loop), + define_builtin(bhv_end_birds_1_loop), + define_builtin(bhv_end_birds_2_loop), + define_builtin(bhv_intro_scene_loop), + define_builtin(bhv_dust_smoke_loop), + define_builtin(bhv_yoshi_loop), + define_builtin(bhv_volcano_trap_loop), + + // mario_misc.h + define_builtin(bhv_toad_message_init), + define_builtin(bhv_toad_message_loop), + define_builtin(bhv_unlock_door_star_init), + define_builtin(bhv_unlock_door_star_loop), + + // Other + define_builtin(load_object_collision_model), + define_builtin(obj_set_secondary_camera_focus), }; const void* DynOS_Builtin_Func_GetFromName(const char* aDataName) { @@ -1153,8 +1906,14 @@ const void* DynOS_Builtin_Func_GetFromName(const char* aDataName) { const void* DynOS_Builtin_Func_GetFromIndex(s32 aIndex) { size_t count = sizeof(sDynosBuiltinFuncs) / (2 * sizeof(sDynosBuiltinFuncs[0])); - if (aIndex < 0 || aIndex >= count) { return NULL; } - return (const void*)sDynosBuiltinFuncs[aIndex * 2 + 1]; + if (aIndex >= 0 && aIndex < count) { return (const void*)sDynosBuiltinFuncs[aIndex * 2 + 1]; } + return NULL; +} + +const char *DynOS_Builtin_Func_GetNameFromIndex(s64 aIndex) { + size_t count = sizeof(sDynosBuiltinFuncs) / (2 * sizeof(sDynosBuiltinFuncs[0])); + if (aIndex >= 0 && aIndex < count) { return (const char *)sDynosBuiltinFuncs[aIndex * 2 + 0]; } + return NULL; } s32 DynOS_Builtin_Func_GetIndexFromData(const void* aData) { @@ -1165,4 +1924,4 @@ s32 DynOS_Builtin_Func_GetIndexFromData(const void* aData) { } } return -1; -} +} \ No newline at end of file diff --git a/data/dynos_mgr_col.cpp b/data/dynos_mgr_col.cpp index c7346a99..9a6d5f4d 100644 --- a/data/dynos_mgr_col.cpp +++ b/data/dynos_mgr_col.cpp @@ -52,7 +52,7 @@ Collision* DynOS_Col_Get(const char* collisionName) { } // check builtin collisions - return (Collision*)DynOS_Builtin_LvlCol_GetFromName(collisionName); + return (Collision*)DynOS_Builtin_Col_GetFromName(collisionName); } void DynOS_Col_ModShutdown() { diff --git a/data/dynos_mgr_lvl.cpp b/data/dynos_mgr_lvl.cpp index 54a1fb5e..e8659e37 100644 --- a/data/dynos_mgr_lvl.cpp +++ b/data/dynos_mgr_lvl.cpp @@ -1,4 +1,5 @@ #include "dynos.cpp.h" + extern "C" { #include "engine/level_script.h" #include "game/skybox.h" diff --git a/include/behavior_commands.h b/include/behavior_commands.h new file mode 100644 index 00000000..df5534d5 --- /dev/null +++ b/include/behavior_commands.h @@ -0,0 +1,332 @@ +#ifndef BEHAVIOR_COMMANDS_H +#define BEHAVIOR_COMMANDS_H + +#define BC_B(a) _SHIFTL(a, 24, 8) +#define BC_BB(a, b) (_SHIFTL(a, 24, 8) | _SHIFTL(b, 16, 8)) +#define BC_BBBB(a, b, c, d) (_SHIFTL(a, 24, 8) | _SHIFTL(b, 16, 8) | _SHIFTL(c, 8, 8) | _SHIFTL(d, 0, 8)) +#define BC_BBH(a, b, c) (_SHIFTL(a, 24, 8) | _SHIFTL(b, 16, 8) | _SHIFTL(c, 0, 16)) +#define BC_B0H(a, b) (_SHIFTL(a, 24, 8) | _SHIFTL(b, 0, 16)) +#define BC_H(a) _SHIFTL(a, 16, 16) +#define BC_HH(a, b) (_SHIFTL(a, 16, 16) | _SHIFTL(b, 0, 16)) +#define BC_W(a) ((uintptr_t)(u32)(a)) +#define BC_PTR(a) ((uintptr_t)(a)) + +// Defines the start of the behavior script as well as the object list the object belongs to. +// Has some special behavior for certain objects. +#define BEGIN(objList) \ + BC_BB(0x00, objList) + +// Delays the behavior script for a certain number of frames. +#define DELAY(num) \ + BC_B0H(0x01, num) + +// Jumps to a new behavior command and stores the return address in the object's stack. +#define CALL(addr) \ + BC_B(0x02), \ + BC_PTR(addr) + +// Jumps back to the behavior command stored in the object's stack. +#define RETURN() \ + BC_B(0x03) + +// Jumps to a new behavior script without saving anything. +#define GOTO(addr) \ + BC_B(0x04), \ + BC_PTR(addr) + +// Marks the start of a loop that will repeat a certain number of times. +#define BEGIN_REPEAT(count) \ + BC_B0H(0x05, count) + +// Marks the end of a repeating loop. +#define END_REPEAT() \ + BC_B(0x06) + +// Also marks the end of a repeating loop, but continues executing commands following the loop on the same frame. +#define END_REPEAT_CONTINUE() \ + BC_B(0x07) + +// Marks the beginning of an infinite loop. +#define BEGIN_LOOP() \ + BC_B(0x08) + +// Marks the end of an infinite loop. +#define END_LOOP() \ + BC_B(0x09) + +// Exits the behavior script. +// Often used to end behavior scripts that do not contain an infinite loop. +#define BREAK() \ + BC_B(0x0A) + +// Exits the behavior script, unused. +#define BREAK_UNUSED() \ + BC_B(0x0B) + +// Executes a native game function. +#define CALL_NATIVE(func) \ + BC_B(0x0C), \ + BC_PTR(func) + +// Adds a float to the specified field. +#define ADD_FLOAT(field, value) \ + BC_BBH(0x0D, field, value) + +// Sets the specified field to a float. +#define SET_FLOAT(field, value) \ + BC_BBH(0x0E, field, value) + +// Adds an integer to the specified field. +#define ADD_INT(field, value) \ + BC_BBH(0x0F, field, value) + +// Sets the specified field to an integer. +#define SET_INT(field, value) \ + BC_BBH(0x10, field, value) + +// Performs a bitwise OR with the specified field and the given integer. +// Usually used to set an object's flags. +#define OR_INT(field, value) \ + BC_BBH(0x11, field, value) + +// Performs a bit clear with the specified short. Unused in favor of the 32-bit version. +#define BIT_CLEAR(field, value) \ + BC_BBH(0x12, field, value) + +// TODO: this one needs a better name / labelling +// Gets a random short, right shifts it the specified amount and adds min to it, then sets the specified field to that value. +#define SET_INT_RAND_RSHIFT(field, min, rshift) \ + BC_BBH(0x13, field, min), \ + BC_H(rshift) + +// Sets the specified field to a random float in the given range. +#define SET_RANDOM_FLOAT(field, min, range) \ + BC_BBH(0x14, field, min), \ + BC_H(range) + +// Sets the specified field to a random integer in the given range. +#define SET_RANDOM_INT(field, min, range) \ + BC_BBH(0x15, field, min), \ + BC_H(range) + +// Adds a random float in the given range to the specified field. +#define ADD_RANDOM_FLOAT(field, min, range) \ + BC_BBH(0x16, field, min), \ + BC_H(range) + +// TODO: better name (unused anyway) +// Gets a random short, right shifts it the specified amount and adds min to it, then adds the value to the specified field. Unused. +#define ADD_INT_RAND_RSHIFT(field, min, rshift) \ + BC_BBH(0x17, field, min), \ + BC_H(rshift) + +// No operation. Unused. +#define CMD_NOP_1(field) \ + BC_BB(0x18, field) + +// No operation. Unused. +#define CMD_NOP_2(field) \ + BC_BB(0x19, field) + +// No operation. Unused. +#define CMD_NOP_3(field) \ + BC_BB(0x1A, field) + +// Sets the current model ID of the object. +#define SET_MODEL(modelID) \ + BC_B0H(0x1B, modelID) + +// Spawns a child object with the specified model and behavior. +#define SPAWN_CHILD(modelID, behavior) \ + BC_B(0x1C), \ + BC_W(modelID), \ + BC_PTR(behavior) + +// Exits the behavior script and despawns the object. +// Often used to end behavior scripts that do not contain an infinite loop. +#define DEACTIVATE() \ + BC_B(0x1D) + +// Finds the floor triangle directly under the object and moves the object down to it. +#define DROP_TO_FLOOR() \ + BC_B(0x1E) + +// Sets the destination float field to the sum of the values of the given float fields. +#define SUM_FLOAT(fieldDst, fieldSrc1, fieldSrc2) \ + BC_BBBB(0x1F, fieldDst, fieldSrc1, fieldSrc2) + +// Sets the destination integer field to the sum of the values of the given integer fields. Unused. +#define SUM_INT(fieldDst, fieldSrc1, fieldSrc2) \ + BC_BBBB(0x20, fieldDst, fieldSrc1, fieldSrc2) + +// Billboards the current object, making it always face the camera. +#define BILLBOARD() \ + BC_B(0x21) + +#define CYLBOARD() \ + BC_B(0x38) + +// Hides the current object. +#define HIDE() \ + BC_B(0x22) + +// Sets the size of the object's cylindrical hitbox. +#define SET_HITBOX(radius, height) \ + BC_B(0x23), \ + BC_HH(radius, height) + +// No operation. Unused. +#define CMD_NOP_4(field, value) \ + BC_BBH(0x24, field, value) + +// Delays the behavior script for the number of frames given by the value of the specified field. +#define DELAY_VAR(field) \ + BC_BB(0x25, field) + +// Unused. Marks the start of a loop that will repeat a certain number of times. +// Uses a u8 as the argument, instead of a s16 like the other version does. +#define BEGIN_REPEAT_UNUSED(count) \ + BC_BB(0x26, count) + +// Loads the animations for the object. is always set to oAnimations. +#define LOAD_ANIMATIONS(field, anims) \ + BC_BB(0x27, field), \ + BC_PTR(anims) + +// Begins animation and sets the object's current animation index to the specified value. +#define ANIMATE(animIndex) \ + BC_BB(0x28, animIndex) + +// Spawns a child object with the specified model and behavior, plus a behavior param. +#define SPAWN_CHILD_WITH_PARAM(bhvParam, modelID, behavior) \ + BC_B0H(0x29, bhvParam), \ + BC_W(modelID), \ + BC_PTR(behavior) + +// Loads collision data for the object. +#define LOAD_COLLISION_DATA(collisionData) \ + BC_B(0x2A), \ + BC_PTR(collisionData) + +// Sets the size of the object's cylindrical hitbox, and applies a downwards offset. +#define SET_HITBOX_WITH_OFFSET(radius, height, downOffset) \ + BC_B(0x2B), \ + BC_HH(radius, height), \ + BC_H(downOffset) + +// Spawns a new object with the specified model and behavior. +#define SPAWN_OBJ(modelID, behavior) \ + BC_B(0x2C), \ + BC_W(modelID), \ + BC_PTR(behavior) + +// Sets the home position of the object to its current position. +#define SET_HOME() \ + BC_B(0x2D) + +// Sets the size of the object's cylindrical hurtbox. +#define SET_HURTBOX(radius, height) \ + BC_B(0x2E), \ + BC_HH(radius, height) + +// Sets the object's interaction type. +#define SET_INTERACT_TYPE(type) \ + BC_B(0x2F), \ + BC_W(type) + +// Sets various parameters that the object uses for calculating physics. +#define SET_OBJ_PHYSICS(wallHitboxRadius, gravity, bounciness, dragStrength, friction, buoyancy, unused1, unused2) \ + BC_B(0x30), \ + BC_HH(wallHitboxRadius, gravity), \ + BC_HH(bounciness, dragStrength), \ + BC_HH(friction, buoyancy), \ + BC_HH(unused1, unused2) + +// Sets the object's interaction subtype. Unused. +#define SET_INTERACT_SUBTYPE(subtype) \ + BC_B(0x31), \ + BC_W(subtype) + +// Sets the object's size to the specified percentage. +#define SCALE(unusedField, percent) \ + BC_BBH(0x32, unusedField, percent) + +// Performs a bit clear on the object's parent's field with the specified value. +// Used for clearing active particle flags fron Mario's object. +#define PARENT_BIT_CLEAR(field, flags) \ + BC_BB(0x33, field), \ + BC_W(flags) + +// Animates an object using texture animation. is always set to oAnimState. +#define ANIMATE_TEXTURE(field, rate) \ + BC_BBH(0x34, field, rate) + +// Disables rendering for the object. +#define DISABLE_RENDERING() \ + BC_B(0x35) + +// Unused. Sets the specified field to an integer. Wastes 4 bytes of space for no reason at all. +#define SET_INT_UNUSED(field, value) \ + BC_BB(0x36, field), \ + BC_HH(0, value) + +// Spawns a water droplet with the given parameters. +#define SPAWN_WATER_DROPLET(dropletParams) \ + BC_B(0x37), \ + BC_PTR(dropletParams) + +// coop + +// Defines the id of the behavior script +#define ID(id) \ + BC_B0H(0x39, id) + +// Jumps to a new behavior command and stores the return address in the object's stack. +#define CALL_EXT(addr) \ + BC_B(0x3A), \ + BC_PTR(addr) + +// Jumps to a new behavior script without saving anything. +#define GOTO_EXT(addr) \ + BC_B(0x3B), \ + BC_PTR(addr) + +// Executes a native game function. +#define CALL_NATIVE_EXT(func) \ + BC_B(0x3C), \ + BC_PTR(func) + +// Spawns a child object with the specified model and behavior. +#define SPAWN_CHILD_EXT(modelID, behavior) \ + BC_B(0x3D), \ + BC_W(modelID), \ + BC_PTR(behavior) + +// Spawns a child object with the specified model and behavior, plus a behavior param. +#define SPAWN_CHILD_WITH_PARAM_EXT(bhvParam, modelID, behavior) \ + BC_B0H(0x3E, bhvParam), \ + BC_W(modelID), \ + BC_PTR(behavior) + +// Spawns a new object with the specified model and behavior. +#define SPAWN_OBJ_EXT(modelID, behavior) \ + BC_B(0x3F), \ + BC_W(modelID), \ + BC_PTR(behavior) + +// Loads the animations for the object. is always set to oAnimations. +#define LOAD_ANIMATIONS_EXT(field, anims) \ + BC_BB(0x40, field), \ + BC_PTR(anims) + +// Loads collision data for the object. +#define LOAD_COLLISION_DATA_EXT(collisionData) \ + BC_B(0x41), \ + BC_PTR(collisionData) + +// This is a special case for behaviors hooked from LUA. +#define CALL_LUA_FUNC(func) \ + BC_B(0x42), \ + BC_W(func) + +#endif // BEHAVIOR_COMMANDS_H \ No newline at end of file diff --git a/include/level_commands.h b/include/level_commands.h index 049cabe4..c8a72d91 100644 --- a/include/level_commands.h +++ b/include/level_commands.h @@ -312,4 +312,4 @@ CMD_W(arg), \ CMD_PTR(target) -#endif // LEVEL_COMMANDS_H +#endif // LEVEL_COMMANDS_H \ No newline at end of file diff --git a/src/engine/behavior_script.c b/src/engine/behavior_script.c index 7e3e55e4..50d26e50 100644 --- a/src/engine/behavior_script.c +++ b/src/engine/behavior_script.c @@ -3,6 +3,7 @@ #include "sm64.h" #include "behavior_data.h" #include "behavior_script.h" +#include "engine/level_script.h" #include "game/area.h" #include "game/behavior_actions.h" #include "game/game_init.h" @@ -14,7 +15,10 @@ #include "graph_node.h" #include "surface_collision.h" #include "pc/network/network.h" +#include "pc/mods/mods.h" +#include "pc/lua/smlua.h" #include "pc/lua/smlua_hooks.h" +#include "pc/lua/smlua_utils.h" #include "game/rng_position.h" // Macros for retrieving arguments from behavior scripts. @@ -892,6 +896,295 @@ static s32 bhv_cmd_id(void) { return BHV_PROC_CONTINUE; } +// Command 0x3A: Jumps to a new behavior command and stores the return address in the object's behavior stack. +// Usage: CALL_EXT(addr) +static s32 bhv_cmd_call_ext(void) { + gCurBhvCommand++; + + BehaviorScript *behavior = (BehaviorScript *)gCurrentObject->behavior; + + s32 modIndex = dynos_behavior_get_active_mod_index(behavior); + if (modIndex == -1) { + LOG_ERROR("Could not find behavior script mod index."); + return BHV_PROC_CONTINUE; + } + + const char *behStr = dynos_behavior_get_token(behavior, BHV_CMD_GET_U32(0)); + + gSmLuaConvertSuccess = true; + enum BehaviorId behId = smlua_get_integer_mod_variable(modIndex, behStr); + + if (!gSmLuaConvertSuccess) { + gSmLuaConvertSuccess = true; + behId = smlua_get_any_integer_mod_variable(behStr); + } + + if (!gSmLuaConvertSuccess) { + LOG_LUA("Failed to call address, could not find behavior '%s'", behStr); + return BHV_PROC_CONTINUE; + } + + cur_obj_bhv_stack_push(BHV_CMD_GET_ADDR_OF_CMD(1)); // Store address of the next bhv command in the stack. + const BehaviorScript *jumpAddress = (BehaviorScript *)get_behavior_from_id(behId); + gCurBhvCommand = jumpAddress; // Jump to the new address. + + return BHV_PROC_CONTINUE; +} + +// Command 0x3B: Jumps to a new behavior script without saving anything. +// Usage: GOTO_EXT(addr) +static s32 bhv_cmd_goto_ext(void) { + BehaviorScript *behavior = (BehaviorScript *)gCurrentObject->behavior; + + s32 modIndex = dynos_behavior_get_active_mod_index(behavior); + if (modIndex == -1) { + LOG_ERROR("Could not find behavior script mod index."); + return BHV_PROC_CONTINUE; + } + + const char *behStr = dynos_behavior_get_token(behavior, BHV_CMD_GET_U32(0)); + + gSmLuaConvertSuccess = true; + enum BehaviorId behId = smlua_get_integer_mod_variable(modIndex, behStr); + + if (!gSmLuaConvertSuccess) { + gSmLuaConvertSuccess = true; + behId = smlua_get_any_integer_mod_variable(behStr); + } + + if (!gSmLuaConvertSuccess) { + LOG_LUA("Failed to jump to address, could not find behavior '%s'", behStr); + return BHV_PROC_CONTINUE; + } + + gCurBhvCommand = (BehaviorScript *)get_behavior_from_id(behId); // Jump directly to address + return BHV_PROC_CONTINUE; +} + +// Command 0x3C: Executes a lua function. Function must not take or return any values. +// Usage: CALL_NATIVE_EXT(func) +static s32 bhv_cmd_call_native_ext(void) { + BehaviorScript *behavior = (BehaviorScript *)gCurrentObject->behavior; + + s32 modIndex = dynos_behavior_get_active_mod_index(behavior); + if (modIndex == -1) { + LOG_ERROR("Could not find behavior script mod index."); + gCurBhvCommand += 2; + return BHV_PROC_CONTINUE; + } + + const char *funcStr = dynos_behavior_get_token(behavior, BHV_CMD_GET_U32(1)); + + gSmLuaConvertSuccess = true; + LuaFunction funcRef = smlua_get_function_mod_variable(modIndex, funcStr); + + if (!gSmLuaConvertSuccess) { + gSmLuaConvertSuccess = true; + funcRef = smlua_get_any_function_mod_variable(funcStr); + } + + if (!gSmLuaConvertSuccess || funcRef == 0) { + LOG_LUA("Failed to call lua function, could not find lua function '%s'", funcStr); + gCurBhvCommand += 2; + return BHV_PROC_CONTINUE; + } + + // Get our mod. + struct Mod *mod = gActiveMods.entries[modIndex]; + + // Push the callback onto the stack + lua_rawgeti(gLuaState, LUA_REGISTRYINDEX, funcRef); + + // Push object + smlua_push_object(gLuaState, LOT_OBJECT, gCurrentObject); + + // Call the callback + if (0 != smlua_call_hook(gLuaState, 1, 0, 0, mod)) { + LOG_LUA("Failed to call the function callback: '%s'", funcStr); + } + + gCurBhvCommand += 2; + return BHV_PROC_CONTINUE; +} + +// Command 0x3D: Spawns a child object with the specified model and behavior. +// Usage: SPAWN_CHILD_EXT(modelID, behavior) +static s32 bhv_cmd_spawn_child_ext(void) { + u32 model = BHV_CMD_GET_U32(1); + + BehaviorScript *behavior = (BehaviorScript *)gCurrentObject->behavior; + + s32 modIndex = dynos_behavior_get_active_mod_index(behavior); + if (modIndex == -1) { + LOG_ERROR("Could not find behavior script mod index."); + gCurBhvCommand += 3; + return BHV_PROC_CONTINUE; + } + + const char *behStr = dynos_behavior_get_token(behavior, BHV_CMD_GET_U32(2)); + + gSmLuaConvertSuccess = true; + enum BehaviorId behId = smlua_get_integer_mod_variable(modIndex, behStr); + + if (!gSmLuaConvertSuccess) { + gSmLuaConvertSuccess = true; + behId = smlua_get_any_integer_mod_variable(behStr); + } + + if (!gSmLuaConvertSuccess) { + LOG_LUA("Failed to spawn custom child, could not find behavior '%s'", behStr); + gCurBhvCommand += 3; + return BHV_PROC_CONTINUE; + } + + BehaviorScript *childBhvScript = (BehaviorScript *)get_behavior_from_id(behId); + if (childBhvScript == NULL) { + LOG_LUA("Failed to spawn custom child, could not get behavior '%s' from the id %u.", behStr, behId); + gCurBhvCommand += 3; + return BHV_PROC_CONTINUE; + } + + struct Object *child = spawn_object_at_origin(gCurrentObject, 0, model, childBhvScript); + if (child != NULL) { + obj_copy_pos_and_angle(child, gCurrentObject); + } + + gCurBhvCommand += 3; + return BHV_PROC_CONTINUE; +} + +// Command 0x3E: Spawns a child object with the specified model and behavior, plus a behavior param. +// Usage: SPAWN_CHILD_WITH_PARAM_EXT(bhvParam, modelID, behavior) +static s32 bhv_cmd_spawn_child_with_param_ext(void) { + u32 bhvParam = BHV_CMD_GET_2ND_S16(0); + u32 modelID = BHV_CMD_GET_U32(1); + + BehaviorScript *behavior = (BehaviorScript *)gCurrentObject->behavior; + + s32 modIndex = dynos_behavior_get_active_mod_index(behavior); + if (modIndex == -1) { + LOG_ERROR("Could not find behavior script mod index."); + gCurBhvCommand += 3; + return BHV_PROC_CONTINUE; + } + + const char *behStr = dynos_behavior_get_token(behavior, BHV_CMD_GET_U32(2)); + + gSmLuaConvertSuccess = true; + enum BehaviorId behId = smlua_get_integer_mod_variable(modIndex, behStr); + + if (!gSmLuaConvertSuccess) { + gSmLuaConvertSuccess = true; + behId = smlua_get_any_integer_mod_variable(behStr); + } + + if (!gSmLuaConvertSuccess) { + LOG_LUA("Failed to spawn custom child with params, could not find behavior '%s'", behStr); + gCurBhvCommand += 3; + return BHV_PROC_CONTINUE; + } + + BehaviorScript *childBhvScript = (BehaviorScript *)get_behavior_from_id(behId); + if (childBhvScript == NULL) { + LOG_LUA("Failed to spawn custom child with params, could not get behavior '%s' from the id %u.", behStr, behId); + gCurBhvCommand += 3; + return BHV_PROC_CONTINUE; + } + + struct Object *child = spawn_object_at_origin(gCurrentObject, 0, modelID, childBhvScript); + if (child != NULL) { + obj_copy_pos_and_angle(child, gCurrentObject); + child->oBehParams2ndByte = bhvParam; + } + + gCurBhvCommand += 3; + return BHV_PROC_CONTINUE; +} + +// Command 0x3F: Spawns a new object with the specified model and behavior. +// Usage: SPAWN_OBJ_EXT(modelID, behavior) +static s32 bhv_cmd_spawn_obj_ext(void) { + u32 modelID = BHV_CMD_GET_U32(1); + + BehaviorScript *behavior = (BehaviorScript *)gCurrentObject->behavior; + + s32 modIndex = dynos_behavior_get_active_mod_index(behavior); + if (modIndex == -1) { + LOG_ERROR("Could not find behavior script mod index."); + gCurBhvCommand += 3; + return BHV_PROC_CONTINUE; + } + + const char *behStr = dynos_behavior_get_token(behavior, BHV_CMD_GET_U32(2)); + + gSmLuaConvertSuccess = true; + enum BehaviorId behId = smlua_get_integer_mod_variable(modIndex, behStr); + + if (!gSmLuaConvertSuccess) { + gSmLuaConvertSuccess = true; + behId = smlua_get_any_integer_mod_variable(behStr); + } + + if (!gSmLuaConvertSuccess) { + LOG_LUA("Failed to spawn custom object, could not find behavior '%s'", behStr); + gCurBhvCommand += 3; + return BHV_PROC_CONTINUE; + } + + BehaviorScript *objBhvScript = (BehaviorScript *)get_behavior_from_id(behId); + if (objBhvScript == NULL) { + LOG_LUA("Failed to spawn custom object, could not get behavior '%s' from the id %u.", behStr, behId); + gCurBhvCommand += 3; + return BHV_PROC_CONTINUE; + } + + struct Object *object = spawn_object_at_origin(gCurrentObject, 0, modelID, objBhvScript); + if (object != NULL) { + obj_copy_pos_and_angle(object, gCurrentObject); + gCurrentObject->prevObj = object; + } + + gCurBhvCommand += 3; + return BHV_PROC_CONTINUE; +} + +// Command 0x40: Loads the animations for the object. is always set to oAnimations. +// Usage: LOAD_ANIMATIONS_EXT(field, anims) +static s32 bhv_cmd_load_animations_ext(void) { + u8 field = BHV_CMD_GET_2ND_U8(0); + + printf("LOAD_ANIMATIONS_EXT is not yet supported! Skipping behavior command.\n"); + + //BehaviorScript *behavior = (BehaviorScript *)gCurrentObject->behavior; + + //const char *animStr = dynos_behavior_get_token(behavior, BHV_CMD_GET_U32(1)); + + //cur_obj_set_vptr(field, BHV_CMD_GET_VPTR(1)); + + gCurBhvCommand += 2; + return BHV_PROC_CONTINUE; +} + +// Command 0x41: Loads collision data for the object. +// Usage: LOAD_COLLISION_DATA_EXT(collisionData) +static s32 bhv_cmd_load_collision_data_ext(void) { + BehaviorScript *behavior = (BehaviorScript *)gCurrentObject->behavior; + + const char *collisionDataStr = dynos_behavior_get_token(behavior, BHV_CMD_GET_U32(1)); + + Collision *collisionData = dynos_collision_get(collisionDataStr); + if (collisionData == NULL) { + LOG_ERROR("Failed to load custom collision, could not get collision from name '%s'", collisionDataStr); + gCurBhvCommand += 2; + return BHV_PROC_CONTINUE; + } + + gCurrentObject->collisionData = collisionData; + + gCurBhvCommand += 2; + return BHV_PROC_CONTINUE; +} + void stub_behavior_script_2(void) { } @@ -954,7 +1247,15 @@ static BhvCommandProc BehaviorCmdTable[] = { bhv_cmd_set_int_unused, //36 bhv_cmd_spawn_water_droplet, //37 bhv_cmd_cylboard, //38 - bhv_cmd_id //39 + bhv_cmd_id, //39 + bhv_cmd_call_ext, //3A + bhv_cmd_goto_ext, //3B + bhv_cmd_call_native_ext, //3C + bhv_cmd_spawn_child_ext, //3D + bhv_cmd_spawn_child_with_param_ext, //3E + bhv_cmd_spawn_obj_ext, //3F + bhv_cmd_load_animations_ext, //40 + bhv_cmd_load_collision_data_ext, //41 }; // Execute the behavior script of the current object, process the object flags, and other miscellaneous code for updating objects. @@ -1000,7 +1301,7 @@ cur_obj_update_begin:; s16 objFlags = gCurrentObject->oFlags; f32 distanceFromMario; - BhvCommandProc bhvCmdProc; + BhvCommandProc bhvCmdProc = NULL; s32 bhvProcResult; // Calculate the distance from the object to Mario. diff --git a/src/engine/level_script.c b/src/engine/level_script.c index ade7021f..3d69bfed 100644 --- a/src/engine/level_script.c +++ b/src/engine/level_script.c @@ -887,13 +887,11 @@ static void level_cmd_place_object_ext(void) { } gSmLuaConvertSuccess = true; - gSmLuaSuppressErrors = true; - enum BehaviorId behId = smlua_get_mod_variable(modIndex, behStr); - gSmLuaSuppressErrors = false; + enum BehaviorId behId = smlua_get_integer_mod_variable(modIndex, behStr); if (!gSmLuaConvertSuccess) { gSmLuaConvertSuccess = true; - behId = smlua_get_any_mod_variable(behStr); + behId = smlua_get_any_integer_mod_variable(behStr); } if (!gSmLuaConvertSuccess) { @@ -945,12 +943,10 @@ static void level_cmd_place_object_ext2(void) { } gSmLuaConvertSuccess = true; - gSmLuaSuppressErrors = true; - enum ModelExtendedId modelId = smlua_get_mod_variable(modIndex, modelStr); - gSmLuaSuppressErrors = false; + enum ModelExtendedId modelId = smlua_get_integer_mod_variable(modIndex, modelStr); if (!gSmLuaConvertSuccess) { gSmLuaConvertSuccess = true; - modelId = smlua_get_any_mod_variable(modelStr); + modelId = smlua_get_any_integer_mod_variable(modelStr); } if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to place custom object, could not find model '%s'", modelStr); @@ -959,12 +955,10 @@ static void level_cmd_place_object_ext2(void) { } gSmLuaConvertSuccess = true; - gSmLuaSuppressErrors = true; - enum BehaviorId behId = smlua_get_mod_variable(modIndex, behStr); - gSmLuaSuppressErrors = false; + enum BehaviorId behId = smlua_get_integer_mod_variable(modIndex, behStr); if (!gSmLuaConvertSuccess) { gSmLuaConvertSuccess = true; - behId = smlua_get_any_mod_variable(behStr); + behId = smlua_get_any_integer_mod_variable(behStr); } if (!gSmLuaConvertSuccess) { diff --git a/src/game/obj_behaviors_2.h b/src/game/obj_behaviors_2.h index 60381746..1b7ebffa 100644 --- a/src/game/obj_behaviors_2.h +++ b/src/game/obj_behaviors_2.h @@ -20,4 +20,115 @@ struct Object* obj_spit_fire(s16 relativePosX, s16 relativePosY, s16 relativePos f32 startSpeed, f32 endSpeed, s16 movePitch); void obj_set_speed_to_zero(void); +void bhv_koopa_init(void); +void bhv_koopa_update(void); +void bhv_koopa_race_endpoint_update(void); +void bhv_pokey_body_part_update(void); +void bhv_pokey_update(void); +void bhv_swoop_update(void); +void bhv_fly_guy_update(void); +void bhv_goomba_triplet_spawner_update(void); +void bhv_goomba_init(void); +void bhv_goomba_update(void); +void bhv_chain_chomp_chain_part_update(void); +void bhv_chain_chomp_update(void); +void bhv_wooden_post_update(void); +void bhv_chain_chomp_gate_init(void); +void bhv_chain_chomp_gate_update(void); +void bhv_wiggler_body_part_update(void); +void bhv_wiggler_update(void); +void bhv_spiny_update(void); +void bhv_enemy_lakitu_update(void); +void bhv_cloud_update(void); +void bhv_cloud_part_update(void); +void bhv_camera_lakitu_init(void); +void bhv_camera_lakitu_update(void); +void bhv_monty_mole_hole_update(void); +void bhv_monty_mole_init(void); +void bhv_monty_mole_update(void); +void bhv_monty_mole_rock_update(void); +void bhv_platform_on_track_init(void); +void bhv_platform_on_track_update(void); +void bhv_track_ball_update(void); +void bhv_seesaw_platform_init(void); +void bhv_seesaw_platform_update(void); +void bhv_ferris_wheel_axle_init(void); +void bhv_ferris_wheel_platform_update(void); +void bhv_water_bomb_spawner_update(void); +void bhv_water_bomb_update(void); +void bhv_water_bomb_shadow_update(void); +void bhv_ttc_rotating_solid_init(void); +void bhv_ttc_rotating_solid_update(void); +void bhv_ttc_pendulum_init(void); +void bhv_ttc_pendulum_update(void); +void bhv_ttc_treadmill_init(void); +void bhv_ttc_treadmill_update(void); +void bhv_ttc_moving_bar_init(void); +void bhv_ttc_moving_bar_update(void); +void bhv_ttc_cog_init(void); +void bhv_ttc_cog_update(void); +void bhv_ttc_pit_block_init(void); +void bhv_ttc_pit_block_update(void); +void bhv_ttc_elevator_init(void); +void bhv_ttc_elevator_update(void); +void bhv_ttc_2d_rotator_init(void); +void bhv_ttc_2d_rotator_update(void); +void bhv_ttc_spinner_update(void); +void bhv_mr_blizzard_init(void); +void bhv_mr_blizzard_update(void); +void bhv_mr_blizzard_snowball(void); +void bhv_sliding_plat_2_init(void); +void bhv_sliding_plat_2_loop(void); +void bhv_rotating_octagonal_plat_init(void); +void bhv_rotating_octagonal_plat_loop(void); +void bhv_animates_on_floor_switch_press_init(void); +void bhv_animates_on_floor_switch_press_loop(void); +void bhv_activated_back_and_forth_platform_init(void); +void bhv_activated_back_and_forth_platform_update(void); +void bhv_recovery_heart_loop(void); +void bhv_bubble_cannon_barrel_loop(void); +void bhv_water_bomb_cannon_loop(void); +void bhv_unagi_init(void); +void bhv_unagi_loop(void); +void bhv_unagi_subobject_loop(void); +void bhv_dorrie_update(void); +void bhv_haunted_chair_init(void); +void bhv_haunted_chair_loop(void); +void bhv_mad_piano_update(void); +void bhv_flying_bookend_loop(void); +void bhv_bookend_spawn_loop(void); +void bhv_haunted_bookshelf_manager_loop(void); +void bhv_book_switch_loop(void); +void bhv_fire_piranha_plant_init(void); +void bhv_fire_piranha_plant_update(void); +void bhv_fire_spitter_update(void); +void bhv_small_piranha_flame_loop(void); +void bhv_fly_guy_flame_loop(void); +void bhv_snufit_loop(void); +void bhv_snufit_balls_loop(void); +void bhv_horizontal_grindel_init(void); +void bhv_horizontal_grindel_update(void); +void bhv_eyerok_boss_init(void); +void bhv_eyerok_boss_loop(void); +void bhv_eyerok_hand_loop(void); +void bhv_klepto_init(void); +void bhv_klepto_update(void); +void bhv_bird_update(void); +void bhv_racing_penguin_init(void); +void bhv_racing_penguin_update(void); +void bhv_coffin_spawner_loop(void); +void bhv_coffin_loop(void); +void bhv_clam_loop(void); +void bhv_skeeter_update(void); +void bhv_skeeter_wave_update(void); +void bhv_swing_platform_init(void); +void bhv_swing_platform_update(void); +void bhv_donut_platform_spawner_update(void); +void bhv_donut_platform_update(void); +void bhv_ddd_pole_init(void); +void bhv_ddd_pole_update(void); +void bhv_red_coin_star_marker_init(void); +void bhv_triplet_butterfly_update(void); +void bhv_bubba_loop(void); + #endif // OBJ_BEHAVIORS_2_H diff --git a/src/game/spawn_object.c b/src/game/spawn_object.c index 6d3e2440..a5583400 100644 --- a/src/game/spawn_object.c +++ b/src/game/spawn_object.c @@ -354,6 +354,7 @@ static void snap_object_to_floor(struct Object *obj) { struct Object *create_object(const BehaviorScript *bhvScript) { if (!bhvScript) { return NULL; } s32 objListIndex = OBJ_LIST_DEFAULT; + bool luaBehavior = is_behavior_hooked_from_lua(bhvScript); const BehaviorScript *behavior = smlua_override_behavior(bhvScript); // If the first behavior script command is "begin ", then @@ -371,7 +372,7 @@ struct Object *create_object(const BehaviorScript *bhvScript) { struct Object *obj = allocate_object(objList); if (obj == NULL) { return NULL; } - obj->curBhvCommand = bhvScript; + obj->curBhvCommand = luaBehavior ? bhvScript : behavior; obj->behavior = behavior; if (objListIndex == OBJ_LIST_UNIMPORTANT) { diff --git a/src/pc/lua/smlua_hooks.c b/src/pc/lua/smlua_hooks.c index fc1f3c18..5fae94ef 100644 --- a/src/pc/lua/smlua_hooks.c +++ b/src/pc/lua/smlua_hooks.c @@ -1,4 +1,5 @@ #include "smlua.h" +#include "behavior_commands.h" #include "pc/mods/mod.h" #include "src/game/object_list_processor.h" #include "pc/djui/djui_chat_message.h" @@ -84,7 +85,7 @@ struct LuaHookedEvent { static struct LuaHookedEvent sHookedEvents[HOOK_MAX] = { 0 }; -static int smlua_call_hook(lua_State* L, int nargs, int nresults, int errfunc, struct Mod* activeMod) { +int smlua_call_hook(lua_State* L, int nargs, int nresults, int errfunc, struct Mod* activeMod) { struct Mod* prev = gLuaActiveMod; gLuaActiveMod = activeMod; gLuaLastHookMod = activeMod; @@ -617,11 +618,13 @@ u32 smlua_get_action_interaction_type(struct MarioState* m) { struct LuaHookedBehavior { u32 behaviorId; u32 overrideId; - BehaviorScript behavior[2]; + u32 originalId; + BehaviorScript *behavior; const BehaviorScript* originalBehavior; int initReference; int loopReference; bool replace; + bool luaBehavior; struct Mod* mod; }; @@ -641,19 +644,20 @@ enum BehaviorId smlua_get_original_behavior_id(const BehaviorScript* behavior) { return id; } -const BehaviorScript* smlua_override_behavior(const BehaviorScript* behavior) { - lua_State* L = gLuaState; +const BehaviorScript* smlua_override_behavior(const BehaviorScript *behavior) { + lua_State *L = gLuaState; if (L == NULL) { return behavior; } enum BehaviorId id = get_id_from_behavior(behavior); - const BehaviorScript* luaBehavior = get_lua_behavior_from_id(id, false); - if (luaBehavior != NULL) { return luaBehavior; } + const BehaviorScript *hookedBehavior = get_hooked_behavior_from_id(id, false); + if (hookedBehavior != NULL) { return hookedBehavior; } return behavior + *sBehaviorOffset; } -const BehaviorScript* get_lua_behavior_from_id(enum BehaviorId id, bool returnOriginal) { - lua_State* L = gLuaState; - if (L == NULL) { return false; } +const BehaviorScript* get_hooked_behavior_from_id(enum BehaviorId id, bool returnOriginal) { + lua_State *L = gLuaState; + if (L == NULL) { return NULL; } + for (int i = 0; i < sHookedBehaviorsCount; i++) { struct LuaHookedBehavior* hooked = &sHookedBehaviors[i]; if (hooked->behaviorId != id && hooked->overrideId != id) { continue; } @@ -663,6 +667,56 @@ const BehaviorScript* get_lua_behavior_from_id(enum BehaviorId id, bool returnOr return NULL; } +bool is_behavior_hooked_from_lua(const BehaviorScript *behavior) { + lua_State *L = gLuaState; + if (L == NULL) { return false; } + + enum BehaviorId id = get_id_from_behavior(behavior); + for (int i = 0; i < sHookedBehaviorsCount; i++) { + struct LuaHookedBehavior *hooked = &sHookedBehaviors[i]; + if (hooked->behaviorId != id && hooked->overrideId != id) { continue; } + return hooked->luaBehavior; + } + + return false; +} + +int hook_behavior(BehaviorScript *bhvScript, const char *bhvName) { + if (sHookedBehaviorsCount >= MAX_HOOKED_BEHAVIORS) { + LOG_ERROR("Hooked behaviors exceeded maximum references!"); + return 0; + } + + u32 originalBehaviorId = get_id_from_behavior(bhvScript); + u8 newBehavior = originalBehaviorId >= id_bhv_max_count; + + struct LuaHookedBehavior *hooked = &sHookedBehaviors[sHookedBehaviorsCount]; + u16 customBehaviorId = (sHookedBehaviorsCount & 0xFFFF) | LUA_BEHAVIOR_FLAG; + hooked->behavior = bhvScript; + hooked->behavior[1] = (BehaviorScript)BC_B0H(0x39, customBehaviorId); // This is ID(customBehaviorId) + hooked->behaviorId = customBehaviorId; + hooked->overrideId = newBehavior ? customBehaviorId : originalBehaviorId; + hooked->originalId = originalBehaviorId; + hooked->originalBehavior = newBehavior ? bhvScript : get_behavior_from_id(originalBehaviorId); + hooked->initReference = 0; + hooked->loopReference = 0; + hooked->replace = true; + hooked->luaBehavior = false; + hooked->mod = gLuaActiveMod; + + sHookedBehaviorsCount++; + + // We want to push the behavior into the global LUA state. So mods can access it. + // It's also used for some things that would normally access a LUA behavior instead. + lua_State* L = gLuaState; + if (L != NULL) { + lua_pushinteger(L, customBehaviorId); + lua_setglobal(L, bhvName); + } + + return 1; +} + int smlua_hook_behavior(lua_State* L) { if (L == NULL) { return 0; } if (!smlua_functions_valid_param_count(L, 5)) { return 0; } @@ -729,14 +783,18 @@ int smlua_hook_behavior(lua_State* L) { struct LuaHookedBehavior* hooked = &sHookedBehaviors[sHookedBehaviorsCount]; u16 customBehaviorId = (sHookedBehaviorsCount & 0xFFFF) | LUA_BEHAVIOR_FLAG; + hooked->behavior = calloc(3, sizeof(BehaviorScript)); + hooked->behavior[0] = (BehaviorScript)BC_BB(0x00, objectList); // This is BEGIN(objectList) + hooked->behavior[1] = (BehaviorScript)BC_B0H(0x39, customBehaviorId); // This is ID(customBehaviorId) + hooked->behavior[2] = 0; hooked->behaviorId = customBehaviorId; hooked->overrideId = noOverrideId ? customBehaviorId : overrideBehaviorId; - hooked->behavior[0] = (((unsigned int) (((unsigned int)(0x00) & ((0x01 << (8)) - 1)) << (24))) | ((unsigned int) (((unsigned int)(objectList) & ((0x01 << (8)) - 1)) << (16)))); // gross. this is BEGIN(objectList) - hooked->behavior[1] = (((unsigned int) (((unsigned int)(0x39) & ((0x01 << (8)) - 1)) << (24))) | ((unsigned int) (((unsigned int)(customBehaviorId) & ((0x01 << (16)) - 1)) << (0)))); // gross. this is ID(customBehaviorId) + hooked->originalId = customBehaviorId; // For LUA behaviors. The only behavior id they have IS their custom one. hooked->originalBehavior = originalBehavior ? originalBehavior : hooked->behavior; hooked->initReference = initReference; hooked->loopReference = loopReference; hooked->replace = replaceBehavior; + hooked->luaBehavior = true; hooked->mod = gLuaActiveMod; sHookedBehaviorsCount++; @@ -758,13 +816,19 @@ bool smlua_call_behavior_hook(const BehaviorScript** behavior, struct Object* ob continue; } - // figure out whether to run before or after + // Figure out whether to run before or after if (before && !hooked->replace) { return false; } if (!before && hooked->replace) { return false; } + + // This behavior doesn't call it's LUA functions in this manner. It actually uses the normal behavior + // system. + if (!hooked->luaBehavior) { + return false; + } // retrieve and remember first run bool firstRun = (object->curBhvCommand == hooked->originalBehavior) || (object->curBhvCommand == hooked->behavior); @@ -1010,13 +1074,28 @@ void smlua_clear_hooks(void) { for (int i = 0; i < sHookedBehaviorsCount; i++) { struct LuaHookedBehavior* hooked = &sHookedBehaviors[i]; + + // If this is NULL. We can't do anything with it. + if (hooked->behavior != NULL) { + // If it's a LUA made behavior, The behavior is allocated so reset and free it. + // Otherwise it's a DynOS behavior and it needs to have it's original id put back where it belongs. + if (hooked->luaBehavior) { + // Just free the allocated behavior. + free(hooked->behavior); + } else { + hooked->behavior[1] = (BehaviorScript)BC_B0H(0x39, hooked->originalId); // This is ID(hooked->originalId) + } + } + // Reset the variables. hooked->behaviorId = 0; - hooked->behavior[0] = 0; - hooked->behavior[1] = 0; + hooked->overrideId = 0; + hooked->originalId = 0; + hooked->behavior = NULL; hooked->originalBehavior = NULL; hooked->initReference = 0; hooked->loopReference = 0; hooked->replace = false; + hooked->luaBehavior = false; hooked->mod = NULL; } sHookedBehaviorsCount = 0; diff --git a/src/pc/lua/smlua_hooks.h b/src/pc/lua/smlua_hooks.h index 4ae109de..b25c472b 100644 --- a/src/pc/lua/smlua_hooks.h +++ b/src/pc/lua/smlua_hooks.h @@ -4,6 +4,9 @@ #include #include "include/behavior_table.h" +#include "smlua.h" +#include "pc/mods/mod.h" + // forward declare struct Camera; @@ -63,6 +66,8 @@ static const char* LuaHookedEventTypeName[] = { extern u32 gLuaMarioActionIndex; +int hook_behavior(BehaviorScript *bhvScript, const char *bhvName); + void smlua_call_event_hooks(enum LuaHookedEventType hookType); void smlua_call_event_hooks_bool_param(enum LuaHookedEventType hookType, bool value); void smlua_call_event_hooks_bool_param_ret_bool(enum LuaHookedEventType hookType, bool value, bool* returnValue); @@ -79,9 +84,11 @@ void smlua_call_event_hooks_value_param(enum LuaHookedEventType hookType, int mo enum BehaviorId smlua_get_original_behavior_id(const BehaviorScript* behavior); const BehaviorScript* smlua_override_behavior(const BehaviorScript* behavior); -const BehaviorScript* get_lua_behavior_from_id(enum BehaviorId id, bool returnOriginal); +const BehaviorScript* get_hooked_behavior_from_id(enum BehaviorId id, bool returnOriginal); +bool is_behavior_hooked_from_lua(const BehaviorScript *behavior); bool smlua_call_behavior_hook(const BehaviorScript** behavior, struct Object* object, bool before); +int smlua_call_hook(lua_State* L, int nargs, int nresults, int errfunc, struct Mod* activeMod); bool smlua_call_action_hook(struct MarioState* m, s32* returnValue); u32 smlua_get_action_interaction_type(struct MarioState* m); diff --git a/src/pc/lua/smlua_utils.c b/src/pc/lua/smlua_utils.c index 5ed2f903..158001be 100644 --- a/src/pc/lua/smlua_utils.c +++ b/src/pc/lua/smlua_utils.c @@ -496,9 +496,21 @@ lua_Number smlua_get_number_field(int index, char* name) { return val; } +LuaFunction smlua_get_function_field(int index, char *name) { + if (lua_type(gLuaState, index) != LUA_TTABLE) { + LOG_LUA_LINE("smlua_get_function_field received improper type '%d'", lua_type(gLuaState, index)); + gSmLuaConvertSuccess = false; + return 0; + } + lua_getfield(gLuaState, index, name); + LuaFunction val = smlua_to_lua_function(gLuaState, -1); + lua_pop(gLuaState, 1); + return val; +} + /////////////////////////////////////////////////////////////////////////////////////////// -s64 smlua_get_mod_variable(u16 modIndex, const char* variable) { +s64 smlua_get_integer_mod_variable(u16 modIndex, const char* variable) { lua_State* L = gLuaState; // figure out entry @@ -507,18 +519,22 @@ s64 smlua_get_mod_variable(u16 modIndex, const char* variable) { LOG_ERROR("Could not find mod list entry for modIndex: %u", modIndex); return 0; } + + u8 prevSuppress = gSmLuaSuppressErrors; int prevTop = lua_gettop(L); lua_getglobal(L, "_G"); // get global table lua_getfield(L, LUA_REGISTRYINDEX, mod->relativePath); // get the file's "global" table + gSmLuaSuppressErrors = true; s64 value = smlua_get_integer_field(-1, (char*)variable); lua_settop(L, prevTop); // return variable + gSmLuaSuppressErrors = prevSuppress; return value; } -s64 smlua_get_any_mod_variable(const char* variable) { +s64 smlua_get_any_integer_mod_variable(const char* variable) { lua_State* L = gLuaState; u8 prevSuppress = gSmLuaSuppressErrors; @@ -545,6 +561,57 @@ s64 smlua_get_any_mod_variable(const char* variable) { return value; } +LuaFunction smlua_get_function_mod_variable(u16 modIndex, const char *variable) { + lua_State *L = gLuaState; + + // figure out entry + struct Mod *mod = gActiveMods.entries[modIndex]; + if (mod == NULL) { + LOG_ERROR("Could not find mod list entry for modIndex: %u", modIndex); + return 0; + } + + u8 prevSuppress = gSmLuaSuppressErrors; + + int prevTop = lua_gettop(L); + lua_getglobal(L, "_G"); // get global table + lua_getfield(L, LUA_REGISTRYINDEX, mod->relativePath); // get the file's "global" table + gSmLuaSuppressErrors = true; + LuaFunction value = smlua_get_function_field(-1, (char *)variable); + lua_settop(L, prevTop); + + // return variable + gSmLuaSuppressErrors = prevSuppress; + return value; +} + +LuaFunction smlua_get_any_function_mod_variable(const char *variable) { + lua_State *L = gLuaState; + u8 prevSuppress = gSmLuaSuppressErrors; + + LuaFunction value = 0; + for (s32 i = 0; i < gActiveMods.entryCount; i++) { + // figure out entry + struct Mod *mod = gActiveMods.entries[i]; + + int prevTop = lua_gettop(L); + lua_getglobal(L, "_G"); // get global table + lua_getfield(L, LUA_REGISTRYINDEX, mod->relativePath); // get the file's "global" table + gSmLuaSuppressErrors = true; + value = smlua_get_function_field(-1, (char *)variable); + lua_settop(L, prevTop); + + if (gSmLuaConvertSuccess) { + gSmLuaSuppressErrors = prevSuppress; + return value; + } + } + + // return variable + gSmLuaSuppressErrors = prevSuppress; + return value; +} + /////////////////////////////////////////////////////////////////////////////////////////// char* smlua_lnt_to_str(struct LSTNetworkType* lnt) { diff --git a/src/pc/lua/smlua_utils.h b/src/pc/lua/smlua_utils.h index f1d7928f..b50399b6 100644 --- a/src/pc/lua/smlua_utils.h +++ b/src/pc/lua/smlua_utils.h @@ -37,11 +37,14 @@ void smlua_push_lnt(struct LSTNetworkType* lnt); lua_Integer smlua_get_integer_field(int index, char* name); lua_Number smlua_get_number_field(int index, char* name); +LuaFunction smlua_get_function_field(int index, char *name); char* smlua_lnt_to_str(struct LSTNetworkType* lnt); -s64 smlua_get_mod_variable(u16 modIndex, const char* variable) ; -s64 smlua_get_any_mod_variable(const char* variable) ; +s64 smlua_get_integer_mod_variable(u16 modIndex, const char* variable); +s64 smlua_get_any_integer_mod_variable(const char* variable); +LuaFunction smlua_get_function_mod_variable(u16 modIndex, const char *variable); +LuaFunction smlua_get_any_function_mod_variable(const char *variable); void smlua_logline(void); void smlua_dump_stack(void); diff --git a/src/pc/lua/utils/smlua_anim_utils.c b/src/pc/lua/utils/smlua_anim_utils.c index f42eaebf..851ad49f 100644 --- a/src/pc/lua/utils/smlua_anim_utils.c +++ b/src/pc/lua/utils/smlua_anim_utils.c @@ -32,6 +32,7 @@ struct GlobalObjectAnimations gGlobalObjectAnimations = { .amp_seg8_anims_08004034 = (struct Animation**) amp_seg8_anims_08004034, .birds_seg5_anims_050009E8 = (struct Animation**) birds_seg5_anims_050009E8, + .blargg_seg5_anims_0500616C = (struct Animation**) blargg_seg5_anims_0500616C, .blue_fish_seg3_anims_0301C2B0 = (struct Animation**) blue_fish_seg3_anims_0301C2B0, .bobomb_seg8_anims_0802396C = (struct Animation**) bobomb_seg8_anims_0802396C, .bookend_seg5_anims_05002540 = (struct Animation**) bookend_seg5_anims_05002540, @@ -46,6 +47,7 @@ struct GlobalObjectAnimations gGlobalObjectAnimations = { .chilly_chief_seg6_anims_06003994 = (struct Animation**) chilly_chief_seg6_anims_06003994, .chuckya_seg8_anims_0800C070 = (struct Animation**) chuckya_seg8_anims_0800C070, .clam_shell_seg5_anims_05001744 = (struct Animation**) clam_shell_seg5_anims_05001744, + .cyan_fish_seg6_anims_0600E264 = (struct Animation**) cyan_fish_seg6_anims_0600E264, .door_seg3_anims_030156C0 = (struct Animation**) door_seg3_anims_030156C0, .dorrie_seg6_anims_0600F638 = (struct Animation**) dorrie_seg6_anims_0600F638, .eyerok_seg5_anims_050116E4 = (struct Animation**) eyerok_seg5_anims_050116E4, @@ -73,6 +75,7 @@ struct GlobalObjectAnimations gGlobalObjectAnimations = { .snowman_seg5_anims_0500D118 = (struct Animation**) snowman_seg5_anims_0500D118, .spindrift_seg5_anims_05002D68 = (struct Animation**) spindrift_seg5_anims_05002D68, .spiny_seg5_anims_05016EAC = (struct Animation**) spiny_seg5_anims_05016EAC, + .spiny_egg_seg5_anims_050157E4 = (struct Animation**) spiny_egg_seg5_anims_050157E4, .sushi_seg5_anims_0500AE54 = (struct Animation**) sushi_seg5_anims_0500AE54, .swoop_seg6_anims_060070D0 = (struct Animation**) swoop_seg6_anims_060070D0, .toad_seg6_anims_0600FB58 = (struct Animation**) toad_seg6_anims_0600FB58, diff --git a/src/pc/lua/utils/smlua_anim_utils.h b/src/pc/lua/utils/smlua_anim_utils.h index 53742620..6991a7f5 100644 --- a/src/pc/lua/utils/smlua_anim_utils.h +++ b/src/pc/lua/utils/smlua_anim_utils.h @@ -6,6 +6,7 @@ typedef struct Animation* ObjectAnimPointer; struct GlobalObjectAnimations { ObjectAnimPointer* amp_seg8_anims_08004034; ObjectAnimPointer* birds_seg5_anims_050009E8; + ObjectAnimPointer* blargg_seg5_anims_0500616C; ObjectAnimPointer* blue_fish_seg3_anims_0301C2B0; ObjectAnimPointer* bobomb_seg8_anims_0802396C; ObjectAnimPointer* bookend_seg5_anims_05002540; @@ -20,6 +21,7 @@ struct GlobalObjectAnimations { ObjectAnimPointer* chilly_chief_seg6_anims_06003994; ObjectAnimPointer* chuckya_seg8_anims_0800C070; ObjectAnimPointer* clam_shell_seg5_anims_05001744; + ObjectAnimPointer* cyan_fish_seg6_anims_0600E264; ObjectAnimPointer* door_seg3_anims_030156C0; ObjectAnimPointer* dorrie_seg6_anims_0600F638; ObjectAnimPointer* eyerok_seg5_anims_050116E4; @@ -47,6 +49,7 @@ struct GlobalObjectAnimations { ObjectAnimPointer* snowman_seg5_anims_0500D118; ObjectAnimPointer* spindrift_seg5_anims_05002D68; ObjectAnimPointer* spiny_seg5_anims_05016EAC; + ObjectAnimPointer* spiny_egg_seg5_anims_050157E4; ObjectAnimPointer* sushi_seg5_anims_0500AE54; ObjectAnimPointer* swoop_seg6_anims_060070D0; ObjectAnimPointer* toad_seg6_anims_0600FB58; diff --git a/src/pc/lua/utils/smlua_collision_utils.c b/src/pc/lua/utils/smlua_collision_utils.c index 01818efd..a078550b 100644 --- a/src/pc/lua/utils/smlua_collision_utils.c +++ b/src/pc/lua/utils/smlua_collision_utils.c @@ -78,6 +78,7 @@ struct GlobalObjectCollisionData gGlobalObjectCollisionData = { .ddd_seg7_collision_submarine = (Collision*) ddd_seg7_collision_submarine, .door_seg3_collision_0301CE78 = (Collision*) door_seg3_collision_0301CE78, .dorrie_seg6_collision_0600F644 = (Collision*) dorrie_seg6_collision_0600F644, + .dorrie_seg6_collision_0600FBB8 = (Collision*) dorrie_seg6_collision_0600FBB8, .exclamation_box_outline_seg8_collision_08025F78 = (Collision*) exclamation_box_outline_seg8_collision_08025F78, .hmc_seg7_collision_controllable_platform = (Collision*) hmc_seg7_collision_controllable_platform, .hmc_seg7_collision_controllable_platform_sub = (Collision*) hmc_seg7_collision_controllable_platform_sub, @@ -134,6 +135,7 @@ struct GlobalObjectCollisionData gGlobalObjectCollisionData = { .ttm_seg7_collision_pitoune_2 = (Collision*) ttm_seg7_collision_pitoune_2, .ttm_seg7_collision_podium_warp = (Collision*) ttm_seg7_collision_podium_warp, .ttm_seg7_collision_ukiki_cage = (Collision*) ttm_seg7_collision_ukiki_cage, + .unknown_seg8_collision_080262F8 = (Collision*) unknown_seg8_collision_080262F8, .warp_pipe_seg3_collision_03009AC8 = (Collision*) warp_pipe_seg3_collision_03009AC8, .wdw_seg7_collision_arrow_lift = (Collision*) wdw_seg7_collision_arrow_lift, .wdw_seg7_collision_express_elevator_platform = (Collision*) wdw_seg7_collision_express_elevator_platform, diff --git a/src/pc/lua/utils/smlua_collision_utils.h b/src/pc/lua/utils/smlua_collision_utils.h index f3da975b..87e95479 100644 --- a/src/pc/lua/utils/smlua_collision_utils.h +++ b/src/pc/lua/utils/smlua_collision_utils.h @@ -32,6 +32,7 @@ struct GlobalObjectCollisionData { Collision* ddd_seg7_collision_submarine; Collision* door_seg3_collision_0301CE78; Collision* dorrie_seg6_collision_0600F644; + Collision* dorrie_seg6_collision_0600FBB8; Collision* exclamation_box_outline_seg8_collision_08025F78; Collision* hmc_seg7_collision_controllable_platform; Collision* hmc_seg7_collision_controllable_platform_sub; @@ -88,6 +89,7 @@ struct GlobalObjectCollisionData { Collision* ttm_seg7_collision_pitoune_2; Collision* ttm_seg7_collision_podium_warp; Collision* ttm_seg7_collision_ukiki_cage; + Collision* unknown_seg8_collision_080262F8; Collision* warp_pipe_seg3_collision_03009AC8; Collision* wdw_seg7_collision_arrow_lift; Collision* wdw_seg7_collision_express_elevator_platform; diff --git a/src/pc/mods/mod.c b/src/pc/mods/mod.c index a9f602e0..c475f077 100644 --- a/src/pc/mods/mod.c +++ b/src/pc/mods/mod.c @@ -99,6 +99,29 @@ static void mod_activate_lvl(struct Mod* mod, struct ModFile* file) { dynos_add_level(mod->index, file->cachedPath, lvlName); } +static void mod_activate_bhv(struct Mod *mod, struct ModFile *file) { + // copy bhv name + char bhvName[64] = { 0 }; + if (snprintf(bhvName, 63, "%s", path_basename(file->relativePath)) < 0) { + LOG_ERROR("Truncated bhv name"); + return; + } + + // remove '.bhv' + char *g = bhvName; + while (*g != '\0') { + if (*g == '.') { + *g = '\0'; + break; + } + g++; + } + + // Add to levels + LOG_INFO("Activating DynOS bhv: '%s', '%s'", file->cachedPath, bhvName); + dynos_add_behavior(mod->index, file->cachedPath, bhvName); +} + void mod_activate(struct Mod* mod) { // activate dynos models for (int i = 0; i < mod->fileCount; i++) { @@ -113,6 +136,9 @@ void mod_activate(struct Mod* mod) { if (str_ends_with(file->relativePath, ".lvl")) { mod_activate_lvl(mod, file); } + if (str_ends_with(file->relativePath, ".bhv")) { + mod_activate_bhv(mod, file); + } if (str_ends_with(file->relativePath, ".tex")) { mod_activate_tex(file); } @@ -273,6 +299,12 @@ static bool mod_load_files(struct Mod* mod, char* modName, char* fullPath) { const char* fileTypes[] = { ".bin", ".col", NULL }; if (!mod_load_files_dir(mod, fullPath, "actors", fileTypes)) { return false; } } + + // deal with behaviors directory + { + const char* fileTypes[] = { ".bhv", NULL }; + if (!mod_load_files_dir(mod, fullPath, "data", fileTypes)) { return false; } + } // deal with textures directory { diff --git a/src/pc/network/network.c b/src/pc/network/network.c index 03f456e5..b3da7fa2 100644 --- a/src/pc/network/network.c +++ b/src/pc/network/network.c @@ -121,6 +121,8 @@ bool network_init(enum NetworkType inNetworkType) { mods_activate(&gLocalMods); smlua_init(); + + dynos_behavior_hook_all_custom_behaviors(); network_player_connected(NPT_LOCAL, 0, configPlayerModel, configPlayerPalette, configPlayerName); extern u8* gOverrideEeprom; diff --git a/src/pc/network/packets/packet_join.c b/src/pc/network/packets/packet_join.c index 549187c1..688b1c56 100644 --- a/src/pc/network/packets/packet_join.c +++ b/src/pc/network/packets/packet_join.c @@ -236,6 +236,7 @@ void network_receive_join(struct Packet* p) { mods_activate(&gRemoteMods); djui_panel_modlist_create(NULL); smlua_init(); + dynos_behavior_hook_all_custom_behaviors(); network_send_network_players_request(); network_send_lua_sync_table_request();