Fixes for multiple players getting a star cutscene, Even if they didn't spawn it. (#22)

* Fix up star cutscene issues.
This commit is contained in:
Prince Frizzy 2022-03-13 04:22:48 -04:00 committed by GitHub
parent 75bb9b7912
commit 84aa5ad890
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 1731 additions and 1528 deletions

File diff suppressed because it is too large Load diff

View file

@ -195,9 +195,9 @@ end
--- @param player integer
--- @param targetScale integer
--- @param fadeTimer integer
--- @param fadeDuration integer
--- @return nil
function fade_volume_scale(player, targetScale, fadeTimer)
function fade_volume_scale(player, targetScale, fadeDuration)
-- ...
end
@ -283,16 +283,24 @@ function play_toads_jingle()
end
--- @param player integer
--- @param fadeTimer integer
--- @param fadeDuration integer
--- @return nil
function sequence_player_fade_out(player, fadeTimer)
function seq_player_fade_out(player, fadeDuration)
-- ...
end
--- @param player integer
--- @param fadeTimer integer
--- @param fadeDuration integer
--- @param percentage integer
--- @return nil
function sequence_player_unlower(player, fadeTimer)
function seq_player_lower_volume(player, fadeDuration, percentage)
-- ...
end
--- @param player integer
--- @param fadeDuration integer
--- @return nil
function seq_player_unlower_volume(player, fadeDuration)
-- ...
end
@ -1545,6 +1553,20 @@ function current_mario_room_check(room)
-- ...
end
--- @param m MarioState
--- @param obj Object
--- @return integer
function is_nearest_mario_state_to_object(m, obj)
-- ...
end
--- @param m Object
--- @param obj Object
--- @return integer
function is_nearest_player_to_object(m, obj)
-- ...
end
--- @param m MarioState
--- @return integer
function is_player_active(m)
@ -3369,6 +3391,29 @@ function stub_obj_helpers_4()
-- ...
end
--- @param a0 integer
--- @param a1 integer
--- @return nil
function queue_rumble_data(a0, a1)
-- ...
end
--- @param m MarioState
--- @param a0 integer
--- @param a1 integer
--- @return nil
function queue_rumble_data_mario(m, a0, a1)
-- ...
end
--- @param object Object
--- @param a0 integer
--- @param a1 integer
--- @return nil
function queue_rumble_data_object(object, a0, a1)
-- ...
end
--- @param capPos Vec3s
--- @return integer
function save_file_get_cap_pos(capPos)
@ -3772,29 +3817,6 @@ function load_object_collision_model()
-- ...
end
--- @param a0 integer
--- @param a1 integer
--- @return nil
function queue_rumble_data(a0, a1)
-- ...
end
--- @param m MarioState
--- @param a0 integer
--- @param a1 integer
--- @return nil
function queue_rumble_data_mario(m, a0, a1)
-- ...
end
--- @param object Object
--- @param a0 integer
--- @param a1 integer
--- @return nil
function queue_rumble_data_object(object, a0, a1)
-- ...
end
--- @class Pointer_BehaviorScript
--- @class Pointer_number
--- @class Pointer_integer

View file

@ -618,10 +618,10 @@
--- @field public oBBallSpawnerMaxSpawnDist number
--- @field public oBBallSpawnerPeriodMinus1 integer
--- @field public oBBallSpawnerSpawnOdds number
--- @field public oBackAndForthPlatformUnk100 number
--- @field public oBackAndForthPlatformUnkF4 number
--- @field public oBackAndForthPlatformUnkF8 number
--- @field public oBackAndForthPlatformUnkFC number
--- @field public oBackAndForthPlatformDirection number
--- @field public oBackAndForthPlatformDistance number
--- @field public oBackAndForthPlatformPathLength number
--- @field public oBackAndForthPlatformVel number
--- @field public oBehParams integer
--- @field public oBehParams2ndByte integer
--- @field public oBetaTrampolineMarioOnTrampoline integer
@ -634,7 +634,7 @@
--- @field public oBlueFishRandomAngle number
--- @field public oBlueFishRandomTime integer
--- @field public oBlueFishRandomVel number
--- @field public oBlueFlameUnkF8 number
--- @field public oBlueFlameNextScale number
--- @field public oBobombBlinkTimer integer
--- @field public oBobombBuddyBlinkTimer integer
--- @field public oBobombBuddyCannonStatus integer
@ -829,18 +829,18 @@
--- @field public oFireSpitterScaleVel number
--- @field public oFishActiveDistance number
--- @field public oFishDepthDistance number
--- @field public oFishPosY number
--- @field public oFishRandomOffset number
--- @field public oFishRandomSpeed integer
--- @field public oFishRandomVel number
--- @field public oFishRespawnDistance number
--- @field public oFishGoalVel number
--- @field public oFishGoalY number
--- @field public oFishHeightOffset number
--- @field public oFishRoamDistance number
--- @field public oFishWaterLevel number
--- @field public oFishYawVel integer
--- @field public oFlags integer
--- @field public oFlameBowser Object
--- @field public oFlameScale number
--- @field public oFlameSpeedTimerOffset integer
--- @field public oFlameThowerFlameUnk110 integer
--- @field public oFlameThowerUnk110 integer
--- @field public oFlameUnk100 Object
--- @field public oFlameUnkF4 number
--- @field public oFlameUnkF8 integer
--- @field public oFlameUnkFC number
--- @field public oFloatingPlatformUnk100 integer
--- @field public oFloatingPlatformUnkF4 integer
@ -968,9 +968,8 @@
--- @field public oMacroUnk108 number
--- @field public oMacroUnk10C number
--- @field public oMacroUnk110 number
--- @field public oMantaUnk1AC integer
--- @field public oMantaUnkF4 integer
--- @field public oMantaUnkF8 integer
--- @field public oMantaTargetPitch integer
--- @field public oMantaTargetYaw integer
--- @field public oMarioBurnTimer integer
--- @field public oMarioCannonInputYaw integer
--- @field public oMarioCannonObjectYaw integer
@ -1128,9 +1127,9 @@
--- @field public oSmallPenguinUnk88 integer
--- @field public oSmallPiranhaFlameEndSpeed number
--- @field public oSmallPiranhaFlameModel integer
--- @field public oSmallPiranhaFlameNextFlameTimer integer
--- @field public oSmallPiranhaFlameSpeed number
--- @field public oSmallPiranhaFlameStartSpeed number
--- @field public oSmallPiranhaFlameUnk100 integer
--- @field public oSmallPiranhaFlameUnk104 number
--- @field public oSmokeTimer integer
--- @field public oSnowmansBottomUnk1AC integer
--- @field public oSnowmansBottomUnkF4 number
@ -1160,6 +1159,7 @@
--- @field public oStarSelectorTimer integer
--- @field public oStarSelectorType integer
--- @field public oStarSpawnDisFromHome number
--- @field public oStarSpawnExtCutsceneFlags integer
--- @field public oStarSpawnUnkFC number
--- @field public oStrongWindParticlePenguinObj Object
--- @field public oSubAction integer
@ -1455,7 +1455,7 @@
--- @field public numWalls integer
--- @field public offsetY number
--- @field public radius number
--- @field public unk14 integer
--- @field public unused integer
--- @class WarpNode
--- @field public destArea integer

View file

@ -318,6 +318,8 @@
- [calc_new_obj_vel_and_pos_y_underwater](#calc_new_obj_vel_and_pos_y_underwater)
- [calc_obj_friction](#calc_obj_friction)
- [current_mario_room_check](#current_mario_room_check)
- [is_nearest_mario_state_to_object](#is_nearest_mario_state_to_object)
- [is_nearest_player_to_object](#is_nearest_player_to_object)
- [is_player_active](#is_player_active)
- [is_point_close_to_object](#is_point_close_to_object)
- [is_point_within_radius_of_mario](#is_point_within_radius_of_mario)
@ -5639,6 +5641,48 @@ The `reliable` field will ensure that the packet arrives, but should be used spa
<br />
## [is_nearest_mario_state_to_object](#is_nearest_mario_state_to_object)
### Lua Example
`local integerValue = is_nearest_mario_state_to_object(m, obj)`
### Parameters
| Field | Type |
| ----- | ---- |
| m | [MarioState](structs.md#MarioState) |
| obj | [Object](structs.md#Object) |
### Returns
- `integer`
### C Prototype
`u8 is_nearest_mario_state_to_object(struct MarioState *m, struct Object *obj);`
[:arrow_up_small:](#)
<br />
## [is_nearest_player_to_object](#is_nearest_player_to_object)
### Lua Example
`local integerValue = is_nearest_player_to_object(m, obj)`
### Parameters
| Field | Type |
| ----- | ---- |
| m | [Object](structs.md#Object) |
| obj | [Object](structs.md#Object) |
### Returns
- `integer`
### C Prototype
`u8 is_nearest_player_to_object(struct Object *m, struct Object *obj);`
[:arrow_up_small:](#)
<br />
## [is_player_active](#is_player_active)
### Lua Example

View file

@ -1462,6 +1462,7 @@
| oSoundEffectUnkF4 | `integer` | |
| oStarSpawnDisFromHome | `number` | |
| oStarSpawnUnkFC | `number` | |
| oStarSpawnExtCutsceneFlags | `integer` | |
| oHiddenStarTriggerCounter | `integer` | |
| oSparkleSpawnUnk1B0 | `integer` | |
| oUnlockDoorStarState | `integer` | |

View file

@ -922,8 +922,9 @@
#define /*0x0F4*/ oSoundEffectUnkF4 OBJECT_FIELD_S32(0x1B)
/* Star Spawn */
#define /*0x0F4*/ oStarSpawnDisFromHome OBJECT_FIELD_F32(0x1B)
#define /*0x0FC*/ oStarSpawnUnkFC OBJECT_FIELD_F32(0x1D)
#define /*0x0F4*/ oStarSpawnDisFromHome OBJECT_FIELD_F32(0x1B)
#define /*0x0F8*/ oStarSpawnUnkFC OBJECT_FIELD_F32(0x1D)
#define /*0x0FC*/ oStarSpawnExtCutsceneFlags OBJECT_FIELD_S16(0x1E, 0)
/* Hidden Star */
// Secrets/Red Coins

View file

@ -68,7 +68,7 @@ void king_bobomb_act_0(void) {
}
s32 mario_is_far_below_object(f32 arg0) {
for (int i = 0; i < MAX_PLAYERS; i++) {
for (s32 i = 0; i < MAX_PLAYERS; i++) {
if (!is_player_active(&gMarioStates[i])) { continue; }
if (arg0 >= o->oPosY - gMarioStates[i].marioObj->oPosY) { return FALSE; }
}
@ -159,10 +159,10 @@ void king_bobomb_act_1(void) {
o->oVelY = 0;
cur_obj_init_animation_with_sound(11);
struct MarioState* marioState = king_bobomb_nearest_mario_state();
int distanceToPlayer = (marioState != NULL) ? dist_between_objects(o, marioState->marioObj) : 3000;
s32 distanceToPlayer = (marioState != NULL) ? dist_between_objects(o, marioState->marioObj) : 3000;
if (marioState != NULL) {
int angleToPlayer = obj_angle_to_object(o, marioState->marioObj);
s32 angleToPlayer = obj_angle_to_object(o, marioState->marioObj);
o->oMoveAngleYaw = approach_s16_symmetric(o->oMoveAngleYaw, angleToPlayer, 512);
}
@ -226,6 +226,8 @@ void king_bobomb_act_7(void) {
void king_bobomb_act_8(void) {
if (!(o->header.gfx.node.flags & GRAPH_RENDER_INVISIBLE)) {
struct Object *star = NULL;
create_sound_spawner(SOUND_OBJ_KING_WHOMP_DEATH);
cur_obj_hide();
cur_obj_become_intangible();
@ -233,11 +235,20 @@ void king_bobomb_act_8(void) {
spawn_triangle_break_particles(20, 138, 3.0f, 4);
cur_obj_shake_screen(SHAKE_POS_SMALL);
#ifndef VERSION_JP
cur_obj_spawn_star_at_y_offset(2000.0f, 4500.0f, -4500.0f, 200.0f);
//cur_obj_spawn_star_at_y_offset(2000.0f, 4500.0f, -4500.0f, 200.0f);
f32 objectPosY = o->oPosY;
o->oPosY += 200.0f + gDebugInfo[5][0];
star = spawn_default_star(2000.0f, 4500.0f, -4500.0f);
o->oPosY = objectPosY;
#else
o->oPosY += 100.0f;
spawn_default_star(2000.0f, 4500.0f, -4500.0f);
star = spawn_default_star(2000.0f, 4500.0f, -4500.0f);
#endif
// If we're not the closet to King-Bombomb,
// Don't play this cutscene!
if (star != NULL && nearest_mario_state_to_object(o) != &gMarioStates[0]) {
star->oStarSpawnExtCutsceneFlags = 0;
}
}
if (o->oTimer == 60)
stop_background_music(SEQUENCE_ARGS(4, SEQ_EVENT_BOSS));

View file

@ -13,10 +13,9 @@ struct ObjectHitbox sSparkleSpawnStarHitbox = {
};
void bhv_spawned_star_init(void) {
s32 sp24;
if (!(o->oInteractionSubtype & INT_SUBTYPE_NO_EXIT))
o->oBehParams = o->parentObj->oBehParams;
sp24 = (o->oBehParams >> 24) & 0xFF;
s32 sp24 = (o->oBehParams >> 24) & 0xFF;
if (bit_shift_left(sp24) & save_file_get_star_flags(gCurrSaveFileNum - 1, gCurrCourseNum - 1))
cur_obj_set_model(smlua_model_util_load(E_MODEL_TRANSPARENT_STAR));
cur_obj_play_sound_2(SOUND_GENERAL2_STAR_APPEARS);
@ -25,12 +24,12 @@ void bhv_spawned_star_init(void) {
// path due to jankiness in oBehParams. Send the spawn event here instead.
u8 spawnedFromExclamationBox = (o->parentObj != NULL && o->parentObj->behavior == bhvExclamationBox);
if (gNetworkAreaLoaded && spawnedFromExclamationBox) {
o->oStarSpawnExtCutsceneFlags = 1;
o->parentObj = o;
struct Object* spawn_objects[] = { o };
u32 models[] = { MODEL_STAR };
network_send_spawn_objects(spawn_objects, models, 1);
}
}
void set_sparkle_spawn_star_hitbox(void) {
@ -42,10 +41,8 @@ void set_sparkle_spawn_star_hitbox(void) {
}
void set_home_to_mario(void) {
f32 sp1C;
f32 sp18;
u8 parentIsMario = FALSE;
for (int i = 0; i < MAX_PLAYERS; i++) {
for (s32 i = 0; i < MAX_PLAYERS; i++) {
if (o->parentObj == gMarioStates[i].marioObj) {
parentIsMario = TRUE;
break;
@ -63,8 +60,8 @@ void set_home_to_mario(void) {
}
o->oHomeY += 250.0f;
o->oPosY = o->oHomeY;
sp1C = o->oHomeX - o->oPosX;
sp18 = o->oHomeZ - o->oPosZ;
f32 sp1C = o->oHomeX - o->oPosX;
f32 sp18 = o->oHomeZ - o->oPosZ;
o->oForwardVel = sqrtf(sp1C * sp1C + sp18 * sp18) / 23.0f;
}
@ -80,8 +77,14 @@ void slow_star_rotation(void) {
void bhv_spawned_star_loop(void) {
if (o->oAction == 0) {
// All of these are for checking if we spawned the star, If
// we didn't. We don't need the time stop.
u8 playExclamationBoxCutscene = (is_nearest_mario_state_to_object(gMarioState, o) && o->oStarSpawnExtCutsceneFlags);
u8 playGenericSpawnCutscene = (o->parentObj != NULL && o->parentObj == gMarioStates[0].marioObj);
u8 playCutscene = (playExclamationBoxCutscene || playGenericSpawnCutscene);
if (o->oTimer == 0) {
if ((gMarioStates[0].action & ACT_GROUP_MASK) != ACT_GROUP_CUTSCENE) {
if (playCutscene && ((gMarioStates[0].action & ACT_GROUP_MASK) != ACT_GROUP_CUTSCENE)) {
cutscene_object(CUTSCENE_STAR_SPAWN, o);
gMarioStates[0].freeze = 60;
set_time_stop_flags(TIME_STOP_ENABLED | TIME_STOP_MARIO_AND_DOORS);
@ -139,22 +142,22 @@ void bhv_spawned_star_loop(void) {
o->oInteractStatus = 0;
}
void bhv_spawn_star_no_level_exit(struct Object* object, u32 sp20, u8 networkSendEvent) {
void bhv_spawn_star_no_level_exit(struct Object* object, u32 params, u8 networkSendEvent) {
// de-duplication checking
for (int i = 0; i < gSpawnedStarNLECount; i++) {
if (gSpawnedStarNLE[i] == sp20) { return; }
if (gSpawnedStarNLE[i] == params) { return; }
}
if (gSpawnedStarNLECount < 8) {
gSpawnedStarNLE[gSpawnedStarNLECount++] = sp20;
gSpawnedStarNLE[gSpawnedStarNLECount++] = params;
}
struct Object *sp1C = spawn_object(object, MODEL_STAR, bhvSpawnedStarNoLevelExit);
if (sp1C != NULL) {
sp1C->oBehParams = sp20 << 24;
sp1C->oInteractionSubtype = INT_SUBTYPE_NO_EXIT;
obj_set_angle(sp1C, 0, 0, 0);
struct Object *star = spawn_object(object, MODEL_STAR, bhvSpawnedStarNoLevelExit);
if (star != NULL) {
star->oBehParams = params << 24;
star->oInteractionSubtype = INT_SUBTYPE_NO_EXIT;
obj_set_angle(star, 0, 0, 0);
}
if (networkSendEvent) {
network_send_spawn_star_nle(object, sp20);
network_send_spawn_star_nle(object, params);
}
}

View file

@ -43,7 +43,7 @@ void bhv_star_spawn_init(void) {
o->oForwardVel = o->oStarSpawnDisFromHome / 30.0f;
o->oStarSpawnUnkFC = o->oPosY;
if ((gMarioStates[0].action & ACT_GROUP_MASK) != ACT_GROUP_CUTSCENE) {
if (o->oStarSpawnExtCutsceneFlags && ((gMarioStates[0].action & ACT_GROUP_MASK) != ACT_GROUP_CUTSCENE)) {
if (o->oBehParams2ndByte == 0 || gCurrCourseNum == COURSE_BBH)
cutscene_object(CUTSCENE_STAR_SPAWN, o);
else
@ -114,17 +114,18 @@ void bhv_star_spawn_loop(void) {
}
}
struct Object *spawn_star(struct Object *sp30, f32 sp34, f32 sp38, f32 sp3C) {
sp30 = spawn_object_abs_with_rot(o, 0, MODEL_STAR, bhvStarSpawnCoordinates, o->oPosX, o->oPosY,
struct Object *spawn_star(struct Object *obj, f32 x, f32 y, f32 z) {
obj = spawn_object_abs_with_rot(o, 0, MODEL_STAR, bhvStarSpawnCoordinates, o->oPosX, o->oPosY,
o->oPosZ, 0, 0, 0);
if (sp30 == NULL) { return NULL; }
sp30->oBehParams = o->oBehParams;
sp30->oHomeX = sp34;
sp30->oHomeY = sp38;
sp30->oHomeZ = sp3C;
sp30->oFaceAnglePitch = 0;
sp30->oFaceAngleRoll = 0;
return sp30;
if (obj == NULL) { return NULL; }
obj->oBehParams = o->oBehParams;
obj->oStarSpawnExtCutsceneFlags = 1;
obj->oHomeX = x;
obj->oHomeY = y;
obj->oHomeZ = z;
obj->oFaceAnglePitch = 0;
obj->oFaceAngleRoll = 0;
return obj;
}
static u8 spawn_star_deduplication(u32* array, u8* count, u32 behParams) {
@ -150,8 +151,10 @@ struct Object* spawn_default_star(f32 x, f32 y, f32 z) {
struct Object *star = NULL;
star = spawn_star(star, x, y, z);
star->oBehParams2ndByte = 0;
network_send_spawn_star(star, 0, x, y, z, behParams);
if (star != NULL) {
star->oBehParams2ndByte = 0;
network_send_spawn_star(star, 0, x, y, z, behParams);
}
return star;
}
@ -165,8 +168,10 @@ struct Object* spawn_red_coin_cutscene_star(f32 x, f32 y, f32 z) {
struct Object * star = NULL;
star = spawn_star(star, x, y, z);
star->oBehParams2ndByte = 1;
network_send_spawn_star(star, 1, x, y, z, behParams);
if (star != NULL) {
star->oBehParams2ndByte = 1;
network_send_spawn_star(star, 1, x, y, z, behParams);
}
return star;
}
@ -180,28 +185,26 @@ struct Object* spawn_no_exit_star(f32 x, f32 y, f32 z) {
struct Object * star = NULL;
star = spawn_star(star, x, y, z);
star->oBehParams2ndByte = 1;
star->oInteractionSubtype |= INT_SUBTYPE_NO_EXIT;
network_send_spawn_star(star, 2, x, y, z, behParams);
if (star != NULL) {
star->oBehParams2ndByte = 1;
star->oInteractionSubtype |= INT_SUBTYPE_NO_EXIT;
network_send_spawn_star(star, 2, x, y, z, behParams);
}
return star;
}
void bhv_hidden_red_coin_star_init(void) {
s16 sp36;
struct Object *sp30;
if (gCurrCourseNum != COURSE_JRB)
spawn_object(o, MODEL_TRANSPARENT_STAR, bhvRedCoinStarMarker);
sp36 = count_objects_with_behavior(bhvRedCoin);
if (sp36 == 0) {
sp30 =
spawn_object_abs_with_rot(o, 0, MODEL_STAR, bhvStar, o->oPosX, o->oPosY, o->oPosZ, 0, 0, 0);
if (sp30 != NULL) { sp30->oBehParams = o->oBehParams; }
s16 redCoins = count_objects_with_behavior(bhvRedCoin);
if (redCoins == 0) {
struct Object *star = spawn_object_abs_with_rot(o, 0, MODEL_STAR, bhvStar, o->oPosX, o->oPosY, o->oPosZ, 0, 0, 0);
if (star != NULL) { star->oBehParams = o->oBehParams; }
o->activeFlags = ACTIVE_FLAG_DEACTIVATED;
}
o->oHiddenStarTriggerCounter = 8 - sp36;
o->oHiddenStarTriggerCounter = 8 - redCoins;
}
void bhv_hidden_red_coin_star_loop(void) {

View file

@ -358,7 +358,7 @@ u8 ukiki_act_go_to_cage_continue_dialog(void) { return o->oAction == UKIKI_ACT_G
void ukiki_act_go_to_cage(void) {
struct MarioState* marioState = nearest_mario_state_to_object(o);
struct Object* player = marioState->marioObj;
int angleToPlayer = obj_angle_to_object(o, player);
s32 angleToPlayer = obj_angle_to_object(o, player);
struct Object* obj;
f32 latDistToCage = 0.0f;

View file

@ -365,7 +365,14 @@ static void wiggler_act_shrink(void) {
// 4 is the default scale, so shrink to 1/4 of regular size
if (approach_f32_ptr(&o->header.gfx.scale[0], 1.0f, 0.1f)) {
spawn_default_star(0.0f, 2048.0f, 0.0f);
struct Object *star = spawn_default_star(0.0f, 2048.0f, 0.0f);
// If we're not the closet to Wiggler,
// Don't play this cutscene!
if (star != NULL && nearest_mario_state_to_object(o) != &gMarioStates[0]) {
star->oStarSpawnExtCutsceneFlags = 0;
}
o->oAction = WIGGLER_ACT_FALL_THROUGH_FLOOR;
}
@ -421,7 +428,7 @@ void bhv_wiggler_on_received_post(UNUSED u8 localIndex) {
posDiff[0] = o->oPosX - wigglerPrePos[0];
posDiff[1] = o->oPosY - wigglerPrePos[1];
posDiff[2] = o->oPosZ - wigglerPrePos[2];
for (int i = 0; i < 3; i++) {
for (s32 i = 0; i < 3; i++) {
o->oWigglerSegments[i].posX += posDiff[0];
o->oWigglerSegments[i].posY += posDiff[1];
o->oWigglerSegments[i].posZ += posDiff[2];
@ -458,8 +465,8 @@ void bhv_wiggler_update(void) {
}
struct Object* player = nearest_player_to_object(o);
int distanceToPlayer = dist_between_objects(o, player);
int angleToPlayer = obj_angle_to_object(o, player);
s32 distanceToPlayer = dist_between_objects(o, player);
s32 angleToPlayer = obj_angle_to_object(o, player);
o->oDistanceToMario = distanceToPlayer;
o->oAngleToMario = angleToPlayer;

View file

@ -571,6 +571,26 @@ struct Object* nearest_player_to_object(struct Object *obj) {
return nearest->marioObj;
}
/**
* Returns whether or not the MarioState is the closet MarioState
* to the object.
*/
u8 is_nearest_mario_state_to_object(struct MarioState *m, struct Object *obj) {
if (m == NULL || obj == NULL) { return FALSE; }
struct MarioState *nearest = nearest_mario_state_to_object(obj);
return m == nearest;
}
/**
* Returns whether or not the player is the closet player
* to the object.
*/
u8 is_nearest_player_to_object(struct Object *m, struct Object *obj) {
if (m == NULL || obj == NULL) { return FALSE; }
struct MarioState *nearest = nearest_mario_state_to_object(obj);
return m == nearest->marioObj;
}
/**
* Checks whether a point is within distance of a given point. Test is exclusive.
*/

View file

@ -165,4 +165,6 @@ struct Object* spawn_default_star(f32 sp20, f32 sp24, f32 sp28);
u8 is_player_active(struct MarioState* m);
struct MarioState* nearest_mario_state_to_object(struct Object* obj);
struct Object* nearest_player_to_object(struct Object* obj);
u8 is_nearest_mario_state_to_object(struct MarioState* m, struct Object* obj);
u8 is_nearest_player_to_object(struct Object* m, struct Object* obj);
#endif // OBJ_BEHAVIORS_H

View file

@ -678,7 +678,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 749
#define LUA_OBJECT_FIELD_COUNT 750
static struct LuaObjectField sObjectFields[LUA_OBJECT_FIELD_COUNT] = {
{ "activeFlags", LVT_S16, offsetof(struct Object, activeFlags), false, LOT_NONE },
{ "areaTimer", LVT_U32, offsetof(struct Object, areaTimer), false, LOT_NONE },
@ -1272,6 +1272,7 @@ static struct LuaObjectField sObjectFields[LUA_OBJECT_FIELD_COUNT] = {
{ "oStarSelectorTimer", LVT_S32, offsetof(struct Object, oStarSelectorTimer), false, LOT_NONE },
{ "oStarSelectorType", LVT_S32, offsetof(struct Object, oStarSelectorType), false, LOT_NONE },
{ "oStarSpawnDisFromHome", LVT_F32, offsetof(struct Object, oStarSpawnDisFromHome), false, LOT_NONE },
{ "oStarSpawnExtCutsceneFlags", LVT_S16, offsetof(struct Object, oStarSpawnExtCutsceneFlags), false, LOT_NONE },
{ "oStarSpawnUnkFC", LVT_F32, offsetof(struct Object, oStarSpawnUnkFC), false, LOT_NONE },
{ "oStrongWindParticlePenguinObj", LVT_COBJECT_P, offsetof(struct Object, oStrongWindParticlePenguinObj), false, LOT_OBJECT },
{ "oSubAction", LVT_S32, offsetof(struct Object, oSubAction), false, LOT_NONE },

View file

@ -3252,6 +3252,34 @@ int smlua_func_geo_obj_transparency_something(lua_State* L) {
}
*/
int smlua_func_is_nearest_mario_state_to_object(lua_State* L) {
if(!smlua_functions_valid_param_count(L, 2)) { return 0; }
struct MarioState* m = (struct MarioState*)smlua_to_cobject(L, 1, LOT_MARIOSTATE);
if (!gSmLuaConvertSuccess) { return 0; }
struct Object* obj = (struct Object*)smlua_to_cobject(L, 2, LOT_OBJECT);
if (!gSmLuaConvertSuccess) { return 0; }
extern u8 is_nearest_mario_state_to_object(struct MarioState *m, struct Object *obj);
lua_pushinteger(L, is_nearest_mario_state_to_object(m, obj));
return 1;
}
int smlua_func_is_nearest_player_to_object(lua_State* L) {
if(!smlua_functions_valid_param_count(L, 2)) { return 0; }
struct Object* m = (struct Object*)smlua_to_cobject(L, 1, LOT_OBJECT);
if (!gSmLuaConvertSuccess) { return 0; }
struct Object* obj = (struct Object*)smlua_to_cobject(L, 2, LOT_OBJECT);
if (!gSmLuaConvertSuccess) { return 0; }
extern u8 is_nearest_player_to_object(struct Object *m, struct Object *obj);
lua_pushinteger(L, is_nearest_player_to_object(m, obj));
return 1;
}
int smlua_func_is_player_active(lua_State* L) {
if(!smlua_functions_valid_param_count(L, 1)) { return 0; }
@ -8408,6 +8436,8 @@ void smlua_bind_functions_autogen(void) {
smlua_bind_function(L, "calc_obj_friction", smlua_func_calc_obj_friction);
smlua_bind_function(L, "current_mario_room_check", smlua_func_current_mario_room_check);
//smlua_bind_function(L, "geo_obj_transparency_something", smlua_func_geo_obj_transparency_something); <--- UNIMPLEMENTED
smlua_bind_function(L, "is_nearest_mario_state_to_object", smlua_func_is_nearest_mario_state_to_object);
smlua_bind_function(L, "is_nearest_player_to_object", smlua_func_is_nearest_player_to_object);
smlua_bind_function(L, "is_player_active", smlua_func_is_player_active);
smlua_bind_function(L, "is_point_close_to_object", smlua_func_is_point_close_to_object);
smlua_bind_function(L, "is_point_within_radius_of_mario", smlua_func_is_point_within_radius_of_mario);

View file

@ -47,6 +47,7 @@ void network_receive_spawn_star(struct Packet* p) {
if (o != NULL) {
packet_read(p, &o->oPosX, sizeof(u32) * 3);
packet_read(p, &o->oHomeX, sizeof(u32) * 3);
o->oStarSpawnExtCutsceneFlags = 0;
}
}