Cleanup ; recursive descent fixes ; fixed behavior override comparisons

Moved dynos parsing for bhvs and models to a common file
Fixed recursive descent to correctly parse the entire expression
Adjusted bhv generation to use recursive descent
Switched all known behavior comparisons to the overridden versions
Fixed issue with Chain Chomp in star road
This commit is contained in:
MysterD 2022-06-02 19:07:43 -07:00
parent 40e1fa9e58
commit b2bdf8859c
42 changed files with 1242 additions and 2230 deletions

View file

@ -4,8 +4,6 @@
#include "dynos.h"
#include <string>
extern "C" {
#include "engine/behavior_script.h"
#include "engine/math_util.h"
@ -958,5 +956,8 @@ 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);
s64 DynOS_Common_ParseBhvConstants(const String &_Arg, bool *found);
s64 DynOS_Common_ParseModelConstants(const String &_Arg, bool *found);
#endif
#endif

File diff suppressed because it is too large Load diff

1027
data/dynos_bin_common.cpp Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -179,6 +179,11 @@ static bool ParseOperator(const char* op) {
return false;
}
static bool PeekOperator(const char* op) {
size_t opLen = strlen(op);
return (!strncmp(sRdString, op, opLen));
}
static s64 ParseNumeric() {
String numeric = "";
char* c = sRdString;
@ -275,12 +280,14 @@ static s64 ParseFactor() {
static s64 ParseTerm() {
s64 f1 = ParseFactor();
while (PeekOperator("*") || PeekOperator("/") || PeekOperator("%")) {
if (ParseOperator("*")) {
return f1 * ParseFactor();
f1 *= ParseFactor();
} else if (ParseOperator("/")) {
return f1 / ParseFactor();
f1 /= ParseFactor();
} else if (ParseOperator("%")) {
return f1 % ParseFactor();
f1 %= ParseFactor();
}
}
return f1;
@ -289,10 +296,12 @@ static s64 ParseTerm() {
static s64 ParseAddSubExpression() {
s64 t1 = ParseTerm();
while (PeekOperator("+") || PeekOperator("-")) {
if (ParseOperator("+")) {
return t1 + ParseTerm();
t1 += ParseTerm();
} else if (ParseOperator("-")) {
return t1 - ParseTerm();
t1 -= ParseTerm();
}
}
return t1;
@ -301,10 +310,12 @@ static s64 ParseAddSubExpression() {
static s64 ParseShiftExpression() {
s64 e1 = ParseAddSubExpression();
while (PeekOperator("<<") || PeekOperator(">>")) {
if (ParseOperator("<<")) {
return e1 << ParseAddSubExpression();
e1 = e1 << ParseAddSubExpression();
} else if (ParseOperator(">>")) {
return e1 >> ParseAddSubExpression();
e1 = e1 >> ParseAddSubExpression();
}
}
return e1;
@ -313,8 +324,10 @@ static s64 ParseShiftExpression() {
static s64 ParseBitAndExpression() {
s64 e1 = ParseShiftExpression();
while (PeekOperator("&")) {
if (ParseOperator("&")) {
return e1 & ParseShiftExpression();
e1 &= ParseShiftExpression();
}
}
return e1;
@ -323,8 +336,10 @@ static s64 ParseBitAndExpression() {
static s64 ParseBitXorExpression() {
s64 e1 = ParseBitAndExpression();
while (PeekOperator("^")) {
if (ParseOperator("^")) {
return e1 ^ ParseBitAndExpression();
e1 ^= ParseBitAndExpression();
}
}
return e1;
@ -333,8 +348,10 @@ static s64 ParseBitXorExpression() {
static s64 ParseBitOrExpression() {
s64 e1 = ParseBitXorExpression();
while (PeekOperator("|")) {
if (ParseOperator("|")) {
return e1 | ParseBitXorExpression();
e1 |= ParseBitXorExpression();
}
}
return e1;
@ -349,6 +366,9 @@ s64 DynOS_RecursiveDescent_Parse(const char* expr, bool* success, RDConstantFunc
sRdError = false;
sRdConstantFunc = func;
s64 value = ParseExpression();
if (strlen(sRdString) > 0) {
sRdError = true;
}
sRdString = NULL;
*success = !sRdError;
return value;

View file

@ -15,4 +15,4 @@ if [ ! -f "$FILE" ]; then
WINPTY=
fi
$WINPTY cgdb $FILE -ex 'r'
$WINPTY cgdb $FILE

View file

@ -1151,7 +1151,7 @@ static s32 bhv_cmd_spawn_obj_ext(void) {
// Command 0x40: Loads the animations for the object. <field> 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);
//u8 field = BHV_CMD_GET_2ND_U8(0);
printf("LOAD_ANIMATIONS_EXT is not yet supported! Skipping behavior command.\n");

View file

@ -18,6 +18,7 @@
#include "engine/math_util.h"
#include "game/level_update.h"
#include "pc/network/network.h"
#include "pc/lua/smlua_hooks.h"
s32 unused8038BE90;
@ -744,7 +745,7 @@ void load_object_surfaces(s16** data, s16* vertexData) {
// The DDD warp is initially loaded at the origin and moved to the proper
// position in paintings.c and doesn't update its room, so set it here.
if (gCurrentObject->behavior == segmented_to_virtual(bhvDddWarp)) {
if (gCurrentObject->behavior == segmented_to_virtual(smlua_override_behavior(bhvDddWarp))) {
room = 5;
} else {
room = 0;

View file

@ -47,6 +47,7 @@
#include "rumble_init.h"
#include "hardcoded.h"
#include "pc/lua/utils/smlua_model_utils.h"
#include "pc/lua/smlua_hooks.h"
#define o gCurrentObject
@ -174,7 +175,7 @@ Gfx *geo_move_mario_part_from_parent(s32 run, UNUSED struct GraphNode *node, Mat
if (run == TRUE) {
sp1C = (struct Object *) gCurGraphNodeObject;
if (sp1C->behavior == bhvMario && sp1C->prevObj != NULL) {
if (sp1C->behavior == smlua_override_behavior(bhvMario) && sp1C->prevObj != NULL) {
create_transformation_from_matrices(sp20, mtx, *gCurGraphNodeCamera->matrixPtr);
obj_update_pos_from_parent_transformation(sp20, sp1C->prevObj);
obj_set_gfx_pos_from_pos(sp1C->prevObj);

View file

@ -751,7 +751,7 @@ u8 big_boo_ignore_update(void) {
void big_boo_on_forget(void) {
if (o == NULL) { return; }
if (o->behavior != bhvGhostHuntBigBoo) { return; }
if (o->behavior != smlua_override_behavior(bhvGhostHuntBigBoo)) { return; }
struct Object* spawnedBridge = cur_obj_nearest_object_with_behavior(bhvBooBossSpawnedBridge);
if (spawnedBridge == NULL && o->oBehParams2ndByte == 0) {
obj_set_pos(o, 973, 0, 717);

View file

@ -61,10 +61,10 @@ void bhv_boo_cage_loop(void) {
// If the cage's parent boo is killed, set the action to BOO_CAGE_ACT_FALLING,
// give the cage an initial Y velocity of 60 units/frame, and play the puzzle jingle.
// Otherwise, stay inside the boo.
if (o->parentObj == NULL || o->parentObj->behavior != bhvBooWithCage || o->parentObj->oBooDeathStatus != BOO_DEATH_STATUS_ALIVE) {
if (o->parentObj == NULL || o->parentObj->behavior != smlua_override_behavior(bhvBooWithCage) || o->parentObj->oBooDeathStatus != BOO_DEATH_STATUS_ALIVE) {
o->oAction++;
o->oVelY = 60.0f;
if (o->parentObj != NULL && o->parentObj->behavior == bhvBooWithCage) {
if (o->parentObj != NULL && o->parentObj->behavior == smlua_override_behavior(bhvBooWithCage)) {
play_puzzle_jingle();
}
struct MarioState* marioState = nearest_mario_state_to_object(o);

View file

@ -32,7 +32,7 @@ void bhv_chain_chomp_chain_part_update(void) {
network_init_object(o, SYNC_DISTANCE_ONLY_DEATH);
}
if (o->parentObj->behavior != (BehaviorScript *)&bhvChainChomp || o->parentObj->oAction == CHAIN_CHOMP_ACT_UNLOAD_CHAIN) {
if (o->parentObj->activeFlags == ACTIVE_FLAG_DEACTIVATED || o->parentObj->oAction == CHAIN_CHOMP_ACT_UNLOAD_CHAIN) {
obj_mark_for_deletion(o);
network_send_object(o);
} else if (o->oBehParams2ndByte != CHAIN_CHOMP_CHAIN_PART_BP_PIVOT) {

View file

@ -224,7 +224,7 @@ void coin_inside_boo_act_0(void) {
cur_obj_become_intangible();
if (parent == NULL || (parent->behavior != bhvMerryGoRoundBoo && parent->behavior != bhvGhostHuntBoo && parent->behavior != bhvBoo)) {
if (parent == NULL || (parent->behavior != smlua_override_behavior(bhvMerryGoRoundBoo) && parent->behavior != smlua_override_behavior(bhvGhostHuntBoo) && parent->behavior != smlua_override_behavior(bhvBoo))) {
o->parentObj = NULL;
obj_mark_for_deletion(o);
return;

View file

@ -199,7 +199,7 @@ static void enemy_lakitu_act_main(void) {
obj_update_blinking(&o->oEnemyLakituBlinkTimer, 20, 40, 4);
if (o->prevObj != NULL) {
if (o->prevObj->behavior != bhvSpiny || o->prevObj->activeFlags == ACTIVE_FLAG_DEACTIVATED) {
if (o->prevObj->behavior != smlua_override_behavior(bhvSpiny) || o->prevObj->activeFlags == ACTIVE_FLAG_DEACTIVATED) {
o->prevObj = NULL;
}
}

View file

@ -147,9 +147,9 @@ void exclamation_box_spawn_contents(struct Struct802C0DF0 *a0, u8 a1) {
// send non-star spawn events
// stars cant be sent here to due jankiness in oBehParams
if (a0->behavior != bhvSpawnedStar && sp1C != NULL) {
if (a0->behavior != smlua_override_behavior(bhvSpawnedStar) && sp1C != NULL) {
// hack: if any other sync objects get spawned here we have to check for them
if (a0->behavior == bhvKoopaShell) {
if (a0->behavior == smlua_override_behavior(bhvKoopaShell)) {
network_set_sync_id(sp1C);
}
struct Object* spawn_objects[] = { sp1C };

View file

@ -32,7 +32,7 @@ void bhv_black_smoke_mario_loop(void) {
}
void bhv_flame_mario_loop(void) {
if (o->parentObj == NULL || o->parentObj->behavior != bhvMario) {
if (o->parentObj == NULL || o->parentObj->behavior != smlua_override_behavior(bhvMario)) {
obj_mark_for_deletion(o);
return;
}

View file

@ -229,7 +229,7 @@ void bookshelf_manager_act_2(void) {
void bookshelf_manager_act_3(void) {
// opening bookshelf
if (o->parentObj == NULL || o->parentObj->behavior != bhvHauntedBookshelf) {
if (o->parentObj == NULL || o->parentObj->behavior != smlua_override_behavior(bhvHauntedBookshelf)) {
o->parentObj = cur_obj_nearest_object_with_behavior(bhvHauntedBookshelf);
}

View file

@ -30,6 +30,7 @@ f32 sMontyMoleLastKilledPosZ;
* start of this list.
*/
static struct Object *link_objects_with_behavior(const BehaviorScript *behavior) {
behavior = smlua_override_behavior(behavior);
const BehaviorScript *behaviorAddr;
struct Object *obj;
struct Object *lastObject;

View file

@ -45,7 +45,7 @@ void bhv_pokey_body_part_update(void) {
s16 offsetAngle;
f32 baseHeight;
if (o->parentObj == NULL || o->parentObj->behavior != bhvPokey || o->parentObj->activeFlags == ACTIVE_FLAG_DEACTIVATED) {
if (o->parentObj == NULL || o->parentObj->behavior != smlua_override_behavior(bhvPokey) || o->parentObj->activeFlags == ACTIVE_FLAG_DEACTIVATED) {
obj_mark_for_deletion(o);
return;
}

View file

@ -22,7 +22,7 @@ void bhv_spawned_star_init(void) {
// exclamation box stars are not sent through the normal exclamation box
// path due to jankiness in oBehParams. Send the spawn event here instead.
u8 spawnedFromExclamationBox = (o->parentObj != NULL && o->parentObj->behavior == bhvExclamationBox);
u8 spawnedFromExclamationBox = (o->parentObj != NULL && o->parentObj->behavior == smlua_override_behavior(bhvExclamationBox));
if (gNetworkAreaLoaded && spawnedFromExclamationBox) {
o->oStarSpawnExtCutsceneFlags = 1;
o->parentObj = o;

View file

@ -76,7 +76,7 @@ static s32 spiny_check_active(void) {
struct Object* player = nearest_player_to_object(o);
s32 distanceToPlayer = dist_between_objects(o, player);
if (o->parentObj == NULL || o->parentObj->behavior != bhvEnemyLakitu) {
if (o->parentObj == NULL || o->parentObj->behavior != smlua_override_behavior(bhvEnemyLakitu)) {
obj_mark_for_deletion(o);
return FALSE;
}
@ -224,7 +224,7 @@ static void spiny_act_thrown_by_lakitu(void) {
void bhv_spiny_override_ownership(u8* shouldOverride, u8* shouldOwn) {
if (o->parentObj == NULL || o->parentObj->activeFlags == ACTIVE_FLAG_DEACTIVATED) { return; }
*shouldOverride = (o->parentObj->behavior == bhvEnemyLakitu);
*shouldOverride = (o->parentObj->behavior == smlua_override_behavior(bhvEnemyLakitu));
*shouldOwn = network_owns_object(o->parentObj);
}

View file

@ -3,7 +3,7 @@
void bhv_water_mist_spawn_loop(void) {
clear_particle_flags(0x20000);
if (o->parentObj == NULL || o->parentObj->behavior != bhvMario) {
if (o->parentObj == NULL || o->parentObj->behavior != smlua_override_behavior(bhvMario)) {
obj_mark_for_deletion(o);
return;
}
@ -11,7 +11,7 @@ void bhv_water_mist_spawn_loop(void) {
}
void bhv_water_mist_loop(void) {
if (o->parentObj == NULL || o->parentObj->behavior != bhvMario) {
if (o->parentObj == NULL || o->parentObj->behavior != smlua_override_behavior(bhvMario)) {
obj_mark_for_deletion(o);
return;
}

View file

@ -93,7 +93,7 @@ void bhv_water_droplet_loop(void) {
}
void bhv_idle_water_wave_loop(void) {
if (o->parentObj == NULL || o->parentObj->behavior != bhvMario) {
if (o->parentObj == NULL || o->parentObj->behavior != smlua_override_behavior(bhvMario)) {
obj_mark_for_deletion(o);
return;
}

View file

@ -3,9 +3,9 @@ static u32 sWaterDiamondPicked = 0;
static void bhv_init_changing_water_level_on_received_post(UNUSED u8 fromLocalIndex) {
struct SyncObject* diamondSo = &gSyncObjects[sWaterDiamondPicked];
if (diamondSo == NULL || diamondSo->behavior != bhvWaterLevelDiamond) { return; }
if (diamondSo == NULL || diamondSo->behavior != smlua_override_behavior(bhvWaterLevelDiamond)) { return; }
struct Object* diamond = get_sync_objects_object(sWaterDiamondPicked);
if (diamond == NULL || diamond->behavior != bhvWaterLevelDiamond) { return; }
if (diamond == NULL || diamond->behavior != smlua_override_behavior(bhvWaterLevelDiamond)) { return; }
diamond->oAction = WATER_LEVEL_DIAMOND_ACT_CHANGE_WATER_LEVEL;
gWDWWaterLevelChanging = 1;

View file

@ -326,7 +326,7 @@ void mario_drop_held_object(struct MarioState *m) {
if (m->playerIndex != 0) { return; }
if (m->heldObj != NULL) {
if (m->heldObj->behavior == segmented_to_virtual(bhvKoopaShellUnderwater)) {
if (m->heldObj->behavior == segmented_to_virtual(smlua_override_behavior(bhvKoopaShellUnderwater))) {
stop_shell_music();
}
@ -353,7 +353,7 @@ void mario_throw_held_object(struct MarioState *m) {
if (m->playerIndex != 0) { return; }
if (m->heldObj != NULL) {
if (m->heldObj->behavior == segmented_to_virtual(bhvKoopaShellUnderwater)) {
if (m->heldObj->behavior == segmented_to_virtual(smlua_override_behavior(bhvKoopaShellUnderwater))) {
if (m->playerIndex == 0) { stop_shell_music(); }
}

View file

@ -1854,7 +1854,7 @@ void func_sh_8025574C(void) {
} else if (gMarioState->particleFlags & PARTICLE_TRIANGLE) {
queue_rumble_data_mario(gMarioState, 5, 80);
}
if(gMarioState->heldObj && gMarioState->heldObj->behavior == segmented_to_virtual(bhvBobomb)) {
if(gMarioState->heldObj && gMarioState->heldObj->behavior == segmented_to_virtual(smlua_override_behavior(bhvBobomb))) {
reset_rumble_timers(gMarioState);
}
}

View file

@ -1955,7 +1955,7 @@ s32 act_flying(struct MarioState *m) {
}
s32 act_riding_hoot(struct MarioState *m) {
if (m->usedObj == NULL || m->usedObj->behavior != bhvHoot) {
if (m->usedObj == NULL || m->usedObj->behavior != smlua_override_behavior(bhvHoot)) {
m->usedObj = cur_obj_nearest_object_with_behavior(bhvHoot);
if (m->usedObj == NULL) { return FALSE; }
m->usedObj->heldByPlayerIndex = m->playerIndex;

View file

@ -36,7 +36,7 @@
void add_tree_leaf_particles(struct MarioState *m) {
f32 leafHeight;
if (m->usedObj != NULL && m->usedObj->behavior == segmented_to_virtual(bhvTree)) {
if (m->usedObj != NULL && m->usedObj->behavior == segmented_to_virtual(smlua_override_behavior(bhvTree))) {
// make leaf effect spawn higher on the Shifting Sand Land palm tree
if (gCurrLevelNum == LEVEL_SSL) {
leafHeight = 250.0f;
@ -50,7 +50,7 @@ void add_tree_leaf_particles(struct MarioState *m) {
}
void play_climbing_sounds(struct MarioState *m, s32 b) {
s32 isOnTree = (m->usedObj != NULL && m->usedObj->behavior == segmented_to_virtual(bhvTree));
s32 isOnTree = (m->usedObj != NULL && m->usedObj->behavior == segmented_to_virtual(smlua_override_behavior(bhvTree)));
if (b == 1) {
if (is_anim_past_frame(m, 1)) {
@ -169,7 +169,7 @@ s32 act_holding_pole(struct MarioState *m) {
return set_mario_action(m, ACT_CLIMBING_POLE, 0);
}
if (poleBehavior != bhvGiantPole && m->controller->stickY > 50.0f) {
if (poleBehavior != smlua_override_behavior(bhvGiantPole) && m->controller->stickY > 50.0f) {
return set_mario_action(m, ACT_TOP_OF_POLE_TRANSITION, 0);
}
}
@ -183,7 +183,7 @@ s32 act_holding_pole(struct MarioState *m) {
m->faceAngle[1] += marioObj->oMarioPoleYawVel;
marioObj->oMarioPolePos -= marioObj->oMarioPoleYawVel / 0x100;
if (m->usedObj->behavior == segmented_to_virtual(bhvTree)) {
if (m->usedObj->behavior == segmented_to_virtual(smlua_override_behavior(bhvTree))) {
//! The Shifting Sand Land palm tree check is done climbing up in
// add_tree_leaf_particles, but not here, when climbing down.
if (m->pos[1] - m->floorHeight > 100.0f) {

View file

@ -432,7 +432,7 @@ s32 act_reading_npc_dialog(struct MarioState *m) {
continueDialogCallback = gContinueDialogFunction();
gCurrentObject = tmp;
}
if (!continueDialogCallback || m->usedObj == NULL || m->usedObj->activeFlags == ACTIVE_FLAG_DEACTIVATED || m->usedObj->behavior != localDialogNPCBehavior) {
if (!continueDialogCallback || m->usedObj == NULL || m->usedObj->activeFlags == ACTIVE_FLAG_DEACTIVATED || m->usedObj->behavior != smlua_override_behavior(localDialogNPCBehavior)) {
set_mario_npc_dialog(m, 0, NULL);
}
}

View file

@ -887,7 +887,7 @@ s32 act_move_punching(struct MarioState *m) {
}
s32 act_hold_walking(struct MarioState *m) {
if (m->heldObj != NULL && m->heldObj->behavior == segmented_to_virtual(bhvJumpingBox)) {
if (m->heldObj != NULL && m->heldObj->behavior == segmented_to_virtual(smlua_override_behavior(bhvJumpingBox))) {
return set_mario_action(m, ACT_CRAZY_BOX_BOUNCE, 0);
}

View file

@ -869,7 +869,7 @@ static s32 act_water_punch(struct MarioState *m) {
case 2:
set_mario_animation(m, MARIO_ANIM_WATER_PICK_UP_OBJ);
if (is_anim_at_end(m)) {
if (m->heldObj != NULL && m->heldObj->behavior == segmented_to_virtual(bhvKoopaShellUnderwater)) {
if (m->heldObj != NULL && m->heldObj->behavior == segmented_to_virtual(smlua_override_behavior(bhvKoopaShellUnderwater))) {
if (m->playerIndex == 0) { play_shell_music(); }
set_mario_action(m, ACT_WATER_SHELL_SWIMMING, 0);
} else {

View file

@ -49,6 +49,7 @@
#include "pc/network/network.h"
#include "pc/network/reservation_area.h"
#include "pc/lua/utils/smlua_model_utils.h"
#include "pc/lua/smlua_hooks.h"
#define POS_OP_SAVE_POSITION 0
#define POS_OP_COMPUTE_VELOCITY 1

View file

@ -313,21 +313,21 @@ void obj_set_held_state(struct Object *obj, const BehaviorScript *heldBehavior)
obj->parentObj = o;
if (obj->oFlags & OBJ_FLAG_HOLDABLE) {
if (heldBehavior == bhvCarrySomething3) {
if (heldBehavior == smlua_override_behavior(bhvCarrySomething3)) {
obj->oHeldState = HELD_HELD;
}
if (heldBehavior == bhvCarrySomething5) {
if (heldBehavior == smlua_override_behavior(bhvCarrySomething5)) {
obj->oHeldState = HELD_THROWN;
obj->heldByPlayerIndex = 0;
}
if (heldBehavior == bhvCarrySomething4) {
if (heldBehavior == smlua_override_behavior(bhvCarrySomething4)) {
obj->oHeldState = HELD_DROPPED;
obj->heldByPlayerIndex = 0;
}
} else {
obj->curBhvCommand = segmented_to_virtual(heldBehavior);
obj->curBhvCommand = segmented_to_virtual(smlua_override_behavior(heldBehavior));
obj->bhvStackIndex = 0;
}
}
@ -1011,6 +1011,7 @@ struct Object *cur_obj_find_nearest_object_with_behavior(const BehaviorScript *b
}
u16 cur_obj_count_objects_with_behavior(const BehaviorScript* behavior, f32 dist) {
behavior = smlua_override_behavior(behavior);
u16 numObjs = 0;
uintptr_t* behaviorAddr = segmented_to_virtual(behavior);
struct Object* obj;
@ -1093,6 +1094,7 @@ struct Object *find_object_with_behavior(const BehaviorScript *behavior) {
}
struct Object *cur_obj_find_nearby_held_actor(const BehaviorScript *behavior, f32 maxDist) {
behavior = smlua_override_behavior(behavior);
const BehaviorScript *behaviorAddr = segmented_to_virtual(behavior);
struct ObjectNode *listHead;
struct Object *obj;
@ -1658,6 +1660,7 @@ void obj_set_behavior(struct Object *obj, const BehaviorScript *behavior) {
}
s32 cur_obj_has_behavior(const BehaviorScript *behavior) {
behavior = smlua_override_behavior(behavior);
if (o->behavior == segmented_to_virtual(behavior)) {
return TRUE;
} else {
@ -1666,6 +1669,7 @@ s32 cur_obj_has_behavior(const BehaviorScript *behavior) {
}
s32 obj_has_behavior(struct Object *obj, const BehaviorScript *behavior) {
behavior = smlua_override_behavior(behavior);
if (obj->behavior == segmented_to_virtual(behavior)) {
return TRUE;
} else {

View file

@ -540,7 +540,7 @@ void spawn_objects_from_info(UNUSED s32 unused, struct SpawnInfo *spawnInfo) {
object->respawnInfo = &spawnInfo->behaviorArg;
// found a player
if (spawnInfo->behaviorArg & ((u32)1 << 31) && object->behavior == bhvMario) {
if (spawnInfo->behaviorArg & ((u32)1 << 31) && object->behavior == smlua_override_behavior(bhvMario)) {
u16 playerIndex = (spawnInfo->behaviorArg & ~(1 << 31));
object->oBehParams = playerIndex + 1;
gMarioObjects[playerIndex] = object;

View file

@ -86,7 +86,7 @@ struct Object* spawn_non_sync_object(enum BehaviorId behaviorId, enum ModelExten
s32 obj_has_behavior_id(struct Object *o, enum BehaviorId behaviorId) {
const BehaviorScript *behavior = get_behavior_from_id(behaviorId);
return o->behavior == behavior;
return o->behavior == smlua_override_behavior(behavior);
}
s32 obj_has_model_extended(struct Object *o, enum ModelExtendedId modelId) {
@ -119,6 +119,7 @@ struct Object *obj_get_first(enum ObjectList objList) {
struct Object *obj_get_first_with_behavior_id(enum BehaviorId behaviorId) {
const BehaviorScript* behavior = get_behavior_from_id(behaviorId);
behavior = smlua_override_behavior(behavior);
if (behavior) {
enum ObjectList objList = get_object_list_from_behavior(behavior);
for (struct Object *obj = obj_get_first(objList); obj != NULL; obj = obj_get_next(obj)) {
@ -132,6 +133,7 @@ struct Object *obj_get_first_with_behavior_id(enum BehaviorId behaviorId) {
struct Object *obj_get_first_with_behavior_id_and_field_s32(enum BehaviorId behaviorId, s32 fieldIndex, s32 value) {
const BehaviorScript* behavior = get_behavior_from_id(behaviorId);
behavior = smlua_override_behavior(behavior);
if (behavior) {
enum ObjectList objList = get_object_list_from_behavior(behavior);
for (struct Object *obj = obj_get_first(objList); obj != NULL; obj = obj_get_next(obj)) {
@ -145,6 +147,7 @@ struct Object *obj_get_first_with_behavior_id_and_field_s32(enum BehaviorId beha
struct Object *obj_get_first_with_behavior_id_and_field_f32(enum BehaviorId behaviorId, s32 fieldIndex, f32 value) {
const BehaviorScript* behavior = get_behavior_from_id(behaviorId);
behavior = smlua_override_behavior(behavior);
if (behavior) {
enum ObjectList objList = get_object_list_from_behavior(behavior);
for (struct Object *obj = obj_get_first(objList); obj != NULL; obj = obj_get_next(obj)) {
@ -159,6 +162,7 @@ struct Object *obj_get_first_with_behavior_id_and_field_f32(enum BehaviorId beha
struct Object *obj_get_nearest_object_with_behavior_id(struct Object *o, enum BehaviorId behaviorId) {
f32 minDist = 0x20000;
const BehaviorScript *behavior = get_behavior_from_id(behaviorId);
behavior = smlua_override_behavior(behavior);
struct Object *closestObj = NULL;
if (behavior) {
@ -178,6 +182,7 @@ struct Object *obj_get_nearest_object_with_behavior_id(struct Object *o, enum Be
s32 obj_count_objects_with_behavior_id(enum BehaviorId behaviorId) {
const BehaviorScript *behavior = get_behavior_from_id(behaviorId);
behavior = smlua_override_behavior(behavior);
s32 count = 0;
if (behavior) {

View file

@ -11,6 +11,7 @@
#include "object_fields.h"
#include "model_ids.h"
#include "pc/utils/misc.h"
#include "pc/lua/smlua_hooks.h"
//#define DISABLE_MODULE_LOG 1
#include "pc/debuglog.h"
@ -68,7 +69,7 @@ void network_send_area(struct NetworkPlayer* toNp) {
u8 respawnerCount = 0;
for (s32 i = 0; i < MAX_SYNC_OBJECTS; i++) {
struct SyncObject* so = &gSyncObjects[i];
if (so == NULL || so->o == NULL || so->o->behavior != bhvRespawner) { continue; }
if (so == NULL || so->o == NULL || so->o->behavior != smlua_override_behavior(bhvRespawner)) { continue; }
respawnerCount++;
}
packet_write(&p, &respawnerCount, sizeof(u8));
@ -76,7 +77,7 @@ void network_send_area(struct NetworkPlayer* toNp) {
// write respawners
for (s32 i = 0; i < MAX_SYNC_OBJECTS; i++) {
struct SyncObject* so = &gSyncObjects[i];
if (so == NULL || so->o == NULL || so->o->behavior != bhvRespawner) { continue; }
if (so == NULL || so->o == NULL || so->o->behavior != smlua_override_behavior(bhvRespawner)) { continue; }
u32 behaviorToRespawn = get_id_from_behavior(so->o->oRespawnerBehaviorToRespawn);
packet_write(&p, &so->o->oPosX, sizeof(f32));
packet_write(&p, &so->o->oPosY, sizeof(f32));
@ -96,7 +97,7 @@ void network_send_area(struct NetworkPlayer* toNp) {
for (s32 i = RESERVED_IDS_SYNC_OBJECT_OFFSET; i < MAX_SYNC_OBJECTS; i++) {
struct SyncObject* so = &gSyncObjects[i];
if (so == NULL || so->o == NULL || so->o->oSyncID != (u32)i) { continue; }
if (so->o->behavior == bhvRespawner) { continue; }
if (so->o->behavior == smlua_override_behavior(bhvRespawner)) { continue; }
struct Object* spawn_objects[] = { so->o };
// TODO: move find model to a utility file/function

View file

@ -9,6 +9,7 @@
#include "src/engine/math_util.h"
#include "src/game/memory.h"
#include "src/game/object_helpers.h"
#include "pc/lua/smlua_hooks.h"
#include "pc/debuglog.h"
extern s16 gCurrCourseNum, gCurrAreaIndex;
@ -24,6 +25,7 @@ static f32 dist_to_pos(struct Object* o, f32* pos) {
}
static struct Object* find_nearest_coin(const BehaviorScript *behavior, f32* pos, s32 coinValue, float minDist) {
behavior = smlua_override_behavior(behavior);
uintptr_t *behaviorAddr = segmented_to_virtual(behavior);
struct Object *closestObj = NULL;
struct Object *obj;
@ -84,7 +86,7 @@ void network_receive_collect_coin(struct Packet* p) {
if (behavior == NULL) { goto SANITY_CHECK_COINS; }
// find the coin
float minDist = (behavior == bhvRedCoin) ? 200 : 1000;
float minDist = (behavior == smlua_override_behavior(bhvRedCoin)) ? 200 : 1000;
struct Object* coin = find_nearest_coin(behavior, pos, coinValue, minDist);
if (coin == NULL) { goto SANITY_CHECK_COINS; }

View file

@ -8,6 +8,7 @@
#include "src/engine/math_util.h"
#include "src/game/memory.h"
#include "src/game/object_helpers.h"
#include "pc/lua/smlua_hooks.h"
static f32 dist_to_pos(struct Object* o, f32* pos) {
f32 x = o->oPosX - pos[0]; x *= x;
@ -17,6 +18,7 @@ static f32 dist_to_pos(struct Object* o, f32* pos) {
}
static struct Object* find_nearest_item(const BehaviorScript *behavior, f32* pos, float minDist) {
behavior = smlua_override_behavior(behavior);
uintptr_t *behaviorAddr = segmented_to_virtual(behavior);
struct Object *closestObj = NULL;
struct Object *obj;

View file

@ -8,6 +8,7 @@
#include "src/game/memory.h"
#include "src/game/object_helpers.h"
#include "src/game/save_file.h"
#include "pc/lua/smlua_hooks.h"
#include "pc/debuglog.h"
extern s16 gCurrSaveFileNum;
@ -22,6 +23,7 @@ static f32 dist_to_pos(struct Object* o, f32* pos) {
}
static struct Object* find_nearest_star(const BehaviorScript* behavior, f32* pos, f32 minDist) {
behavior = smlua_override_behavior(behavior);
uintptr_t* behaviorAddr = segmented_to_virtual(behavior);
struct Object* closestObj = NULL;
struct Object* obj;

View file

@ -11,6 +11,7 @@
#include "object_fields.h"
#include "behavior_table.h"
#include "model_ids.h"
#include "pc/lua/smlua_hooks.h"
//#define DISABLE_MODULE_LOG 1
#include "pc/debuglog.h"
@ -190,7 +191,7 @@ void network_receive_level_macro(struct Packet* p) {
if (o != NULL) {
LOG_INFO("rx macro special: object");
// coin formation
if (behavior == bhvCoinFormation) {
if (behavior == smlua_override_behavior(bhvCoinFormation)) {
o->oBehParams = *respawnInfo;
o->oCoinUnkF4 = (o->oBehParams >> 8) & 0xFF;
@ -199,7 +200,7 @@ void network_receive_level_macro(struct Packet* p) {
struct Object* o2 = &gObjectPool[i];
if (o2->parentObj != o) { continue; }
if (o2 == o) { continue; }
if (o2->behavior != bhvCoinFormationSpawn && o2->behavior != bhvYellowCoin) { continue; }
if (o2->behavior != smlua_override_behavior(bhvCoinFormationSpawn) && o2->behavior != smlua_override_behavior(bhvYellowCoin)) { continue; }
if (o->oCoinUnkF4 & (1 << childIndex++)) {
obj_mark_for_deletion(o2);
}
@ -210,7 +211,7 @@ void network_receive_level_macro(struct Packet* p) {
struct Object* o2 = &gObjectPool[i];
if (o2->parentObj != o) { continue; }
if (o2 == o) { continue; }
if (o2->behavior != bhvGoomba) { continue; }
if (o2->behavior != smlua_override_behavior(bhvGoomba)) { continue; }
u16 info = (*respawnInfo >> 8);
u8 mask = ((o2->oBehParams2ndByte & GOOMBA_BP_TRIPLET_FLAG_MASK) >> 2);
if (info & mask) {

View file

@ -11,6 +11,7 @@
#include "src/game/obj_behaviors.h"
#include "src/game/object_list_processor.h"
#include "src/game/area.h"
#include "pc/lua/smlua_hooks.h"
#include "pc/debuglog.h"
#include "pc/utils/misc.h"
@ -302,8 +303,8 @@ static bool allowable_behavior_change(struct SyncObject* so, BehaviorScript* beh
struct Object* o = so->o;
// bhvPenguinBaby can be set to bhvSmallPenguin
bool oBehaviorPenguin = (o->behavior == segmented_to_virtual(bhvPenguinBaby) || o->behavior == segmented_to_virtual(bhvSmallPenguin));
bool inBehaviorPenguin = (behavior == segmented_to_virtual(bhvPenguinBaby) || behavior == segmented_to_virtual(bhvSmallPenguin));
bool oBehaviorPenguin = (o->behavior == segmented_to_virtual(smlua_override_behavior(bhvPenguinBaby)) || o->behavior == segmented_to_virtual(smlua_override_behavior(bhvSmallPenguin)));
bool inBehaviorPenguin = (behavior == segmented_to_virtual(smlua_override_behavior(bhvPenguinBaby)) || behavior == segmented_to_virtual(smlua_override_behavior(bhvSmallPenguin)));
bool allow = (oBehaviorPenguin && inBehaviorPenguin);
if (!allow) { return false; }
@ -503,7 +504,7 @@ void network_send_object(struct Object* o) {
LOG_ERROR("tried to send uninitialized sync obj");
return;
}
if (o->behavior == bhvRespawner) {
if (o->behavior == smlua_override_behavior(bhvRespawner)) {
LOG_INFO("tried to send respawner sync obj");
return;
}

View file

@ -3,6 +3,7 @@
#include "object_fields.h"
#include "behavior_data.h"
#include "src/game/behavior_actions.h"
#include "pc/lua/smlua_hooks.h"
#include "pc/debuglog.h"
extern struct Object* gCurrentObject;
@ -68,7 +69,7 @@ void network_receive_spawn_star(struct Packet* p) {
void network_send_spawn_star_nle(struct Object* o, u32 params) {
u8 globalIndex = UNKNOWN_GLOBAL_INDEX;
if (o->behavior == bhvMario) {
if (o->behavior == smlua_override_behavior(bhvMario)) {
u8 localIndex = o->oBehParams - 1;
globalIndex = gNetworkPlayers[localIndex].globalIndex;
}