diff --git a/autogen/lua_definitions/structs.lua b/autogen/lua_definitions/structs.lua index 992198cf1..f7e01d463 100644 --- a/autogen/lua_definitions/structs.lua +++ b/autogen/lua_definitions/structs.lua @@ -1813,6 +1813,7 @@ --- @field public oSmallPenguinUnk104 number --- @field public oSmallPenguinUnk108 number --- @field public oSmallPenguinUnk110 integer +--- @field public oSmallPenguinFound integer --- @field public oSLWalkingPenguinWindCollisionXPos number --- @field public oSLWalkingPenguinWindCollisionZPos number --- @field public oSLWalkingPenguinCurStep integer diff --git a/docs/lua/structs.md b/docs/lua/structs.md index 62aa6fac2..c07bdfdef 100644 --- a/docs/lua/structs.md +++ b/docs/lua/structs.md @@ -2422,6 +2422,7 @@ | oSmallPenguinUnk104 | `number` | | | oSmallPenguinUnk108 | `number` | | | oSmallPenguinUnk110 | `integer` | | +| oSmallPenguinFound | `integer` | | | oSLWalkingPenguinWindCollisionXPos | `number` | | | oSLWalkingPenguinWindCollisionZPos | `number` | | | oSLWalkingPenguinCurStep | `integer` | | diff --git a/include/object_fields.h b/include/object_fields.h index b4063db31..14b48e203 100644 --- a/include/object_fields.h +++ b/include/object_fields.h @@ -758,6 +758,7 @@ #define /*0x104*/ oSmallPenguinUnk104 OBJECT_FIELD_F32(0x1F) #define /*0x108*/ oSmallPenguinUnk108 OBJECT_FIELD_F32(0x20) #define /*0x110*/ oSmallPenguinUnk110 OBJECT_FIELD_S32(0x22) +#define /*0x1AC*/ oSmallPenguinFound OBJECT_FIELD_U32(0x49) /* SL Walking Penguin */ #define /*0x100*/ oSLWalkingPenguinWindCollisionXPos OBJECT_FIELD_F32(0x1E) diff --git a/src/game/behaviors/tuxie.inc.c b/src/game/behaviors/tuxie.inc.c index 6f641f243..d2583d690 100644 --- a/src/game/behaviors/tuxie.inc.c +++ b/src/game/behaviors/tuxie.inc.c @@ -29,31 +29,61 @@ static bool another_mario_talking_to_tuxie_mother(void) { return false; } -void tuxies_mother_act_2(void) { - struct Object *player = gMarioStates[0].marioObj; - s32 angleToPlayer = obj_angle_to_object(o, player); +static struct Object *get_found_baby_penguin(f32 maxDist) { + const BehaviorScript *behavior = smlua_override_behavior(bhvSmallPenguin); + const BehaviorScript *behaviorAddr = segmented_to_virtual(behavior); + struct ObjectNode *listHead; + struct Object *obj; + struct Object *foundObj; + listHead = &gObjectLists[OBJ_LIST_GENACTOR]; + obj = (struct Object *) listHead->next; + foundObj = NULL; + + while ((struct Object *) listHead != obj) { + if (obj->behavior == behaviorAddr && obj->activeFlags != ACTIVE_FLAG_DEACTIVATED) { + if (obj->oHeldState != HELD_FREE && dist_between_objects(o, obj) < maxDist) { + if (obj->oSmallPenguinFound) { + foundObj = obj; + break; + } + } + } + + obj = (struct Object *) obj->header.next; + } + + return foundObj; +} + +void tuxies_mother_act_2(void) { f32 distToSmallPenguin = 1000.0f; struct Object *smallPenguinObj = gMarioStates[0].heldObj; - if (smallPenguinObj && smallPenguinObj->behavior != bhvSmallPenguin) { + if (smallPenguinObj && (smallPenguinObj->behavior != bhvSmallPenguin || smallPenguinObj->oSmallPenguinFound == TRUE)) { smallPenguinObj = NULL; } if (smallPenguinObj) { distToSmallPenguin = dist_between_objects(o, smallPenguinObj); } - if (cur_obj_find_nearby_held_actor(bhvUnused20E0, 1000.0f) != NULL) { + struct Object *foundBabyPenguin = get_found_baby_penguin(1000.0f); + if (foundBabyPenguin != NULL) { if (o->oSubAction == 0) { cur_obj_init_animation_with_sound(0); o->oForwardVel = 10.0f; - if (800.0f < cur_obj_lateral_dist_from_obj_to_home(player)) { + if (800.0f < cur_obj_lateral_dist_from_obj_to_home(foundBabyPenguin)) { o->oSubAction = 1; + if (smallPenguinObj == foundBabyPenguin) { + // sends position of tuxie mother to everyone else if we are the one + // holding the baby penguin + network_send_object(o); + } } - cur_obj_rotate_yaw_toward(angleToPlayer, 0x400); + cur_obj_rotate_yaw_toward(obj_angle_to_object(o, foundBabyPenguin), 0x400); } else { o->oForwardVel = 0.0f; cur_obj_init_animation_with_sound(3); - if (cur_obj_lateral_dist_from_obj_to_home(player) < 700.0f) { + if (cur_obj_lateral_dist_from_obj_to_home(foundBabyPenguin) < 700.0f) { o->oSubAction = 0; } } @@ -61,7 +91,8 @@ void tuxies_mother_act_2(void) { o->oForwardVel = 0.0f; cur_obj_init_animation_with_sound(3); } - if (smallPenguinObj != NULL && distToSmallPenguin < 300.0f && smallPenguinObj->oHeldState != HELD_FREE) { + + if (smallPenguinObj && distToSmallPenguin < 300.0f && smallPenguinObj->oHeldState != HELD_FREE && !another_mario_talking_to_tuxie_mother()) { o->oAction = 1; smallPenguinObj->oSmallPenguinUnk88 = 1; o->prevObj = smallPenguinObj; @@ -109,7 +140,7 @@ void tuxies_mother_act_1(void) { // which has no effect as o->prevObj->oUnknownUnk88 is always 0 // or 1, which is not affected by the bitwise AND. o->prevObj->OBJECT_FIELD_S32(o->oInteractionSubtype) &= ~INT_SUBTYPE_DROP_IMMEDIATELY; - obj_set_behavior(o->prevObj, bhvUnused20E0); + o->prevObj->oSmallPenguinFound = TRUE; f32 *starPos = gLevelValues.starPositions.TuxieMotherStarPos; #ifndef VERSION_JP @@ -119,13 +150,14 @@ void tuxies_mother_act_1(void) { #endif o->oAction = 2; network_send_object(o); + network_send_object(o->prevObj); } break; case 2: - if (o->prevObj && o->prevObj->oHeldState == HELD_FREE && another_mario_talking_to_tuxie_mother()) { + if (o->prevObj && o->prevObj->oHeldState == HELD_FREE) { //! Same bug as above o->prevObj->OBJECT_FIELD_S32(o->oInteractionSubtype) &= ~INT_SUBTYPE_DROP_IMMEDIATELY; - obj_set_behavior(o->prevObj, bhvPenguinBaby); + o->prevObj->oSmallPenguinFound = FALSE; o->oAction = 2; } break; @@ -187,11 +219,16 @@ void (*sTuxiesMotherActions[])(void) = { tuxies_mother_act_0, tuxies_mother_act_ tuxies_mother_act_2 }; void bhv_tuxies_mother_loop(void) { - // uses event based syncing and syncs action changes + // uses distance based syncing and mainly syncs action changes along with positions and + // move angles for other certain actions if (!sync_object_is_initialized(o->oSyncID)) { sync_object_init(o, SYNC_DISTANCE_ONLY_EVENTS); sync_object_init_field(o, o->oAction); sync_object_init_field(o, o->oSubAction); + sync_object_init_field(o, o->oPosX); + sync_object_init_field(o, o->oPosY); + sync_object_init_field(o, o->oPosZ); + sync_object_init_field(o, o->oMoveAngleYaw); } o->activeFlags |= ACTIVE_FLAG_UNK10; cur_obj_update_floor_and_walls(); @@ -346,6 +383,7 @@ void bhv_small_penguin_loop(void) { // uses standard distance-based syncing if (!sync_object_is_initialized(o->oSyncID)) { sync_object_init(o, 4000.0f); + sync_object_init_field(o, o->oSmallPenguinFound); } switch (o->oHeldState) { case HELD_FREE: @@ -353,9 +391,6 @@ void bhv_small_penguin_loop(void) { break; case HELD_HELD: cur_obj_unrender_and_reset_state(0, 0); - if (cur_obj_has_behavior(bhvPenguinBaby)) { - obj_set_behavior(o, bhvSmallPenguin); - } if (o->heldByPlayerIndex < MAX_PLAYERS) { obj_copy_pos(o, gMarioStates[o->heldByPlayerIndex].marioObj); if (gGlobalTimer % 30 == 0) { diff --git a/src/pc/lua/smlua_cobject_autogen.c b/src/pc/lua/smlua_cobject_autogen.c index 20a602488..fc3100fb2 100644 --- a/src/pc/lua/smlua_cobject_autogen.c +++ b/src/pc/lua/smlua_cobject_autogen.c @@ -1602,7 +1602,7 @@ static struct LuaObjectField sNetworkPlayerFields[LUA_NETWORK_PLAYER_FIELD_COUNT { "type", LVT_U8, offsetof(struct NetworkPlayer, type), true, LOT_NONE }, }; -#define LUA_OBJECT_FIELD_COUNT 767 +#define LUA_OBJECT_FIELD_COUNT 768 static struct LuaObjectField sObjectFields[LUA_OBJECT_FIELD_COUNT] = { { "activeFlags", LVT_S16, offsetof(struct Object, activeFlags), false, LOT_NONE }, { "allowRemoteInteractions", LVT_U8, offsetof(struct Object, allowRemoteInteractions), false, LOT_NONE }, @@ -2172,6 +2172,7 @@ static struct LuaObjectField sObjectFields[LUA_OBJECT_FIELD_COUNT] = { { "oSkeeterUnkFC", LVT_F32, offsetof(struct Object, oSkeeterUnkFC), false, LOT_NONE }, { "oSkeeterWaitTime", LVT_S32, offsetof(struct Object, oSkeeterWaitTime), false, LOT_NONE }, { "oSmallBompInitX", LVT_F32, offsetof(struct Object, oSmallBompInitX), false, LOT_NONE }, + { "oSmallPenguinFound", LVT_U32, offsetof(struct Object, oSmallPenguinFound), false, LOT_NONE }, { "oSmallPenguinUnk100", LVT_S32, offsetof(struct Object, oSmallPenguinUnk100), false, LOT_NONE }, { "oSmallPenguinUnk104", LVT_F32, offsetof(struct Object, oSmallPenguinUnk104), false, LOT_NONE }, { "oSmallPenguinUnk108", LVT_F32, offsetof(struct Object, oSmallPenguinUnk108), false, LOT_NONE },