mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2024-11-22 20:15:17 +00:00
Merge branch 'unstable' of github.com:sm64ex-coop-dev/sm64ex-coop into unstable
This commit is contained in:
commit
473c318f71
28 changed files with 486 additions and 295 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -42,6 +42,9 @@
|
|||
# Stackdumps
|
||||
*.stackdump
|
||||
|
||||
# Backup files
|
||||
*.bak
|
||||
|
||||
# datadump
|
||||
/tools/ddump/*
|
||||
|
||||
|
|
|
@ -1218,10 +1218,11 @@
|
|||
--- @field public oToadMessageRecentlyTalked integer
|
||||
--- @field public oToadMessageState integer
|
||||
--- @field public oToxBoxMovementStep integer
|
||||
--- @field public oTreasureChestCurrentAnswer integer
|
||||
--- @field public oTreasureChestIsAboveWater integer
|
||||
--- @field public oTreasureChestIsLastInteractionIncorrect integer
|
||||
--- @field public oTreasureChestLastNetworkPlayerIndex integer
|
||||
--- @field public oTreasureChestSound integer
|
||||
--- @field public oTreasureChestUnkF4 integer
|
||||
--- @field public oTreasureChestUnkF8 integer
|
||||
--- @field public oTreasureChestUnkFC integer
|
||||
--- @field public oTreeSnowOrLeafUnkF4 integer
|
||||
--- @field public oTreeSnowOrLeafUnkF8 integer
|
||||
--- @field public oTreeSnowOrLeafUnkFC integer
|
||||
|
|
|
@ -1526,10 +1526,11 @@
|
|||
| oTTCSpinnerDir | `integer` | |
|
||||
| oTTCChangeDirTimer | `integer` | |
|
||||
| oBetaTrampolineMarioOnTrampoline | `integer` | |
|
||||
| oTreasureChestUnkF4 | `integer` | |
|
||||
| oTreasureChestUnkF8 | `integer` | |
|
||||
| oTreasureChestUnkFC | `integer` | |
|
||||
| oTreasureChestCurrentAnswer | `integer` | |
|
||||
| oTreasureChestIsLastInteractionIncorrect | `integer` | |
|
||||
| oTreasureChestIsAboveWater | `integer` | |
|
||||
| oTreasureChestSound | `integer` | |
|
||||
| oTreasureChestLastNetworkPlayerIndex | `integer` | |
|
||||
| oTreeSnowOrLeafUnkF4 | `integer` | |
|
||||
| oTreeSnowOrLeafUnkF8 | `integer` | |
|
||||
| oTreeSnowOrLeafUnkFC | `integer` | |
|
||||
|
|
|
@ -929,6 +929,7 @@
|
|||
/* Hidden Star */
|
||||
// Secrets/Red Coins
|
||||
#define /*0x0F4*/ oHiddenStarTriggerCounter OBJECT_FIELD_S32(0x1B)
|
||||
#define /*0x0F8*/ oHiddenStarLastInteractedObject OBJECT_FIELD_VPTR(0x1D)
|
||||
|
||||
// Overall very difficult to determine usage, mostly stubbed code.
|
||||
/* Sparkle Spawn Star */
|
||||
|
@ -1037,10 +1038,11 @@
|
|||
#define /*0x110*/ oBetaTrampolineMarioOnTrampoline OBJECT_FIELD_S32(0x22)
|
||||
|
||||
/* Treasure Chest */
|
||||
#define /*0x0F4*/ oTreasureChestUnkF4 OBJECT_FIELD_S32(0x1B)
|
||||
#define /*0x0F8*/ oTreasureChestUnkF8 OBJECT_FIELD_S32(0x1C)
|
||||
#define /*0x0FC*/ oTreasureChestUnkFC OBJECT_FIELD_S32(0x1D)
|
||||
#define /*0x0F4*/ oTreasureChestCurrentAnswer OBJECT_FIELD_S32(0x1B)
|
||||
#define /*0x0F8*/ oTreasureChestIsLastInteractionIncorrect OBJECT_FIELD_S32(0x1C)
|
||||
#define /*0x0FC*/ oTreasureChestIsAboveWater OBJECT_FIELD_S32(0x1D)
|
||||
#define /*0x100*/ oTreasureChestSound OBJECT_FIELD_S32(0x1E)
|
||||
#define /*0x104*/ oTreasureChestLastNetworkPlayerIndex OBJECT_FIELD_S16(0x21, 0)
|
||||
|
||||
/* Tree Snow Or Leaf */
|
||||
#define /*0x0F4*/ oTreeSnowOrLeafUnkF4 OBJECT_FIELD_S32(0x1B)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
-- name: Mario RUN!
|
||||
-- description: Mario Is contantly runing
|
||||
-- description: Mario is constantly running.
|
||||
|
||||
Threshold = 50 --set Threshold to 50
|
||||
|
||||
|
|
|
@ -97,7 +97,7 @@ static void homing_amp_appear_loop(void) {
|
|||
*/
|
||||
static void homing_amp_chase_loop(void) {
|
||||
struct Object* player = nearest_player_to_object(o);
|
||||
int angleToPlayer = obj_angle_to_object(o, player);
|
||||
s32 angleToPlayer = obj_angle_to_object(o, player);
|
||||
|
||||
// Lock on to Mario if he ever goes within 11.25 degrees of the amp's line of sight
|
||||
if ((angleToPlayer - 0x400 < o->oMoveAngleYaw)
|
||||
|
@ -199,7 +199,8 @@ static void amp_attack_cooldown_loop(void) {
|
|||
*/
|
||||
void bhv_homing_amp_loop(void) {
|
||||
if (!network_sync_object_initialized(o)) {
|
||||
network_init_object(o, 4000.0f);
|
||||
struct SyncObject *so = network_init_object(o, 4000.0f);
|
||||
if (so) {
|
||||
network_init_object_field(o, &o->oAmpYPhase);
|
||||
network_init_object_field(o, &o->oAnimState);
|
||||
network_init_object_field(o, &o->oFaceAnglePitch);
|
||||
|
@ -209,6 +210,7 @@ void bhv_homing_amp_loop(void) {
|
|||
network_init_object_field(o, &o->oHomingAmpAvgY);
|
||||
network_init_object_field(o, &o->oHomingAmpLockedOn);
|
||||
}
|
||||
}
|
||||
|
||||
switch (o->oAction) {
|
||||
case HOMING_AMP_ACT_INACTIVE:
|
||||
|
@ -342,7 +344,8 @@ static void circling_amp_idle_loop(void) {
|
|||
*/
|
||||
void bhv_circling_amp_loop(void) {
|
||||
if (!network_sync_object_initialized(o)) {
|
||||
network_init_object(o, 4000.0f);
|
||||
struct SyncObject *so = network_init_object(o, 4000.0f);
|
||||
if (so) {
|
||||
network_init_object_field(o, &o->oAmpYPhase);
|
||||
network_init_object_field(o, &o->oAnimState);
|
||||
network_init_object_field(o, &o->oFaceAnglePitch);
|
||||
|
@ -350,6 +353,7 @@ void bhv_circling_amp_loop(void) {
|
|||
network_init_object_field(o, &o->oForwardVel);
|
||||
network_init_object_field(o, &o->oFriction);
|
||||
}
|
||||
}
|
||||
|
||||
switch (o->oAction) {
|
||||
case AMP_ACT_IDLE:
|
||||
|
|
|
@ -60,11 +60,13 @@ static s8 arrow_lift_move_back(void) {
|
|||
*/
|
||||
void bhv_arrow_lift_loop(void) {
|
||||
if (!network_sync_object_initialized(o)) {
|
||||
network_init_object(o, SYNC_DISTANCE_ONLY_EVENTS);
|
||||
struct SyncObject *so = network_init_object(o, SYNC_DISTANCE_ONLY_EVENTS);
|
||||
if (so) {
|
||||
network_init_object_field(o, &o->oTimer);
|
||||
network_init_object_field(o, &o->oPrevAction);
|
||||
network_init_object_field(o, &o->oAction);
|
||||
}
|
||||
}
|
||||
|
||||
switch (o->oAction) {
|
||||
case ARROW_LIFT_ACT_IDLE:
|
||||
|
|
|
@ -21,14 +21,13 @@ static void handle_merry_go_round_music(void) {
|
|||
}
|
||||
} else {
|
||||
// Get Mario's floor and floor surface type
|
||||
struct Surface *marioFloor;
|
||||
u16 marioFloorType;
|
||||
struct Surface *marioFloor = NULL;
|
||||
struct Object *marioObject = gMarioObjects[0];
|
||||
u16 marioFloorType = 0;
|
||||
|
||||
find_floor(gMarioObject->oPosX, gMarioObject->oPosY, gMarioObject->oPosZ, &marioFloor);
|
||||
find_floor(marioObject->oPosX, marioObject->oPosY, marioObject->oPosZ, &marioFloor);
|
||||
|
||||
if (marioFloor == NULL) {
|
||||
marioFloorType = 0;
|
||||
} else {
|
||||
if (marioFloor != NULL) {
|
||||
marioFloorType = marioFloor->type;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ static u8 boo_ignore_update(void) {
|
|||
}
|
||||
|
||||
struct SyncObject* boo_network_init_object(void) {
|
||||
struct SyncObject* so = network_init_object(o, 4000.0f);
|
||||
struct SyncObject *so = network_init_object(o, 4000.0f);
|
||||
if (so == NULL) { return NULL; }
|
||||
so->ignore_if_true = boo_ignore_update;
|
||||
network_init_object_field(o, &o->oBooBaseScale);
|
||||
|
|
|
@ -48,8 +48,8 @@ void bub_act_0(void) {
|
|||
|
||||
void bub_act_1(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);
|
||||
f32 dy;
|
||||
if (o->oTimer == 0) {
|
||||
o->oForwardVel = random_float() * 2 + 2;
|
||||
|
@ -80,8 +80,8 @@ void bub_act_1(void) {
|
|||
|
||||
void bub_act_2(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);
|
||||
f32 dy;
|
||||
if (o->oTimer < 20) {
|
||||
if (o->oInteractStatus & INT_STATUS_INTERACTED)
|
||||
|
@ -116,13 +116,15 @@ void (*sCheepCheepActions[])(void) = { bub_act_0, bub_act_1, bub_act_2 };
|
|||
|
||||
void bhv_bub_loop(void) {
|
||||
if (!network_sync_object_initialized(o)) {
|
||||
network_init_object(o, 4000.0f);
|
||||
struct SyncObject *so = network_init_object(o, 4000.0f);
|
||||
if (so) {
|
||||
network_init_object_field(o, &o->oCheepCheepUnkF4);
|
||||
network_init_object_field(o, &o->oCheepCheepUnkF8);
|
||||
network_init_object_field(o, &o->oCheepCheepUnkFC);
|
||||
network_init_object_field(o, &o->oCheepCheepUnk104);
|
||||
network_init_object_field(o, &o->oCheepCheepUnk108);
|
||||
}
|
||||
}
|
||||
|
||||
struct Object* player = nearest_player_to_object(o);
|
||||
|
||||
|
|
|
@ -39,7 +39,8 @@ void bhv_camera_lakitu_init(void) {
|
|||
}
|
||||
lakituTargetLocalIndex = UNKNOWN_LOCAL_INDEX;
|
||||
|
||||
struct SyncObject* so = network_init_object(o, 4000.0f);
|
||||
if (!network_sync_object_initialized(o)) {
|
||||
struct SyncObject *so = network_init_object(o, 4000.0f);
|
||||
if (so) {
|
||||
so->ignore_if_true = bhv_camera_lakitu_ignore_if_true;
|
||||
so->override_ownership = bhv_camera_lakitu_override_ownership;
|
||||
|
@ -53,6 +54,7 @@ void bhv_camera_lakitu_init(void) {
|
|||
network_init_object_field(o, &o->oCameraLakituUnk104);
|
||||
network_init_object_field(o, &o->oCameraLakituPitchVel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static u8 camera_lakitu_intro_act_trigger_cutscene_continue_dialog(void) {
|
||||
|
@ -112,8 +114,8 @@ static void camera_lakitu_intro_act_show_dialog(void) {
|
|||
marioState = &gMarioStates[lakituTargetLocalIndex];
|
||||
}
|
||||
struct Object* player = marioState->marioObj;
|
||||
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);
|
||||
|
||||
s16 targetMovePitch = 0;
|
||||
s16 targetMoveYaw = 0;
|
||||
|
|
|
@ -19,7 +19,7 @@ void opened_cannon_act_0(void) {
|
|||
cur_obj_enable_rendering();
|
||||
|
||||
struct Object* player = nearest_player_to_object(o);
|
||||
int distanceToPlayer = dist_between_objects(o, player);
|
||||
s32 distanceToPlayer = dist_between_objects(o, player);
|
||||
|
||||
if (distanceToPlayer < 500.0f) {
|
||||
//cur_obj_become_tangible();
|
||||
|
|
|
@ -28,8 +28,13 @@ static struct ObjectHitbox sChainChompHitbox = {
|
|||
* Update function for chain chomp part / pivot.
|
||||
*/
|
||||
void bhv_chain_chomp_chain_part_update(void) {
|
||||
if (o->parentObj->behavior != (BehaviorScript*)&bhvChainChomp || o->parentObj->oAction == CHAIN_CHOMP_ACT_UNLOAD_CHAIN) {
|
||||
if (!network_sync_object_initialized(o)) {
|
||||
network_init_object(o, SYNC_DISTANCE_ONLY_DEATH);
|
||||
}
|
||||
|
||||
if (o->parentObj->behavior != (BehaviorScript *)&bhvChainChomp || 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) {
|
||||
struct ChainSegment *segment = &o->parentObj->oChainChompSegments[o->oBehParams2ndByte];
|
||||
|
||||
|
@ -47,17 +52,14 @@ void bhv_chain_chomp_chain_part_update(void) {
|
|||
* When mario gets close enough, allocate chain segments and spawn their objects.
|
||||
*/
|
||||
static void chain_chomp_act_uninitialized(void) {
|
||||
struct ChainSegment *segments;
|
||||
s32 i;
|
||||
|
||||
segments = mem_pool_alloc(gObjectMemoryPool, 5 * sizeof(struct ChainSegment));
|
||||
struct ChainSegment *segments = mem_pool_alloc(gObjectMemoryPool, 5 * sizeof(struct ChainSegment));
|
||||
if (segments != NULL) {
|
||||
// Each segment represents the offset of a chain part to the pivot.
|
||||
// Segment 0 connects the pivot to the chain chomp itself. Segment
|
||||
// 1 connects the pivot to the chain part next to the chain chomp
|
||||
// (chain part 1), etc.
|
||||
o->oChainChompSegments = segments;
|
||||
for (i = 0; i <= 4; i++) {
|
||||
for (s32 i = 0; i <= 4; i++) {
|
||||
chain_segment_init(&segments[i]);
|
||||
}
|
||||
|
||||
|
@ -69,7 +71,7 @@ static void chain_chomp_act_uninitialized(void) {
|
|||
!= NULL) {
|
||||
// Spawn the non-pivot chain parts, starting from the chain
|
||||
// chomp and moving toward the pivot
|
||||
for (i = 1; i <= 4; i++) {
|
||||
for (s32 i = 1; i <= 4; i++) {
|
||||
spawn_object_relative(i, 0, 0, 0, o, MODEL_METALLIC_BALL, bhvChainChompChainPart);
|
||||
}
|
||||
|
||||
|
@ -84,15 +86,7 @@ static void chain_chomp_act_uninitialized(void) {
|
|||
* part as well as from the pivot.
|
||||
*/
|
||||
static void chain_chomp_update_chain_segments(void) {
|
||||
struct ChainSegment *prevSegment;
|
||||
struct ChainSegment *segment;
|
||||
f32 offsetX;
|
||||
f32 offsetY;
|
||||
f32 offsetZ;
|
||||
f32 offset;
|
||||
f32 segmentVelY;
|
||||
f32 maxTotalOffset;
|
||||
s32 i;
|
||||
|
||||
if (o->oVelY < 0.0f) {
|
||||
segmentVelY = o->oVelY;
|
||||
|
@ -103,9 +97,9 @@ static void chain_chomp_update_chain_segments(void) {
|
|||
// Segment 0 connects the pivot to the chain chomp itself, and segment i>0
|
||||
// connects the pivot to chain part i (1 is closest to the chain chomp).
|
||||
|
||||
for (i = 1; i <= 4; i++) {
|
||||
prevSegment = &o->oChainChompSegments[i - 1];
|
||||
segment = &o->oChainChompSegments[i];
|
||||
for (s32 i = 1; i <= 4; i++) {
|
||||
struct ChainSegment *prevSegment = &o->oChainChompSegments[i - 1];
|
||||
struct ChainSegment *segment = &o->oChainChompSegments[i];
|
||||
|
||||
// Apply gravity
|
||||
|
||||
|
@ -116,10 +110,10 @@ static void chain_chomp_update_chain_segments(void) {
|
|||
// Cap distance to previous chain part (so that the tail follows the
|
||||
// chomp)
|
||||
|
||||
offsetX = segment->posX - prevSegment->posX;
|
||||
offsetY = segment->posY - prevSegment->posY;
|
||||
offsetZ = segment->posZ - prevSegment->posZ;
|
||||
offset = sqrtf(offsetX * offsetX + offsetY * offsetY + offsetZ * offsetZ);
|
||||
f32 offsetX = segment->posX - prevSegment->posX;
|
||||
f32 offsetY = segment->posY - prevSegment->posY;
|
||||
f32 offsetZ = segment->posZ - prevSegment->posZ;
|
||||
f32 offset = sqrtf(offsetX * offsetX + offsetY * offsetY + offsetZ * offsetZ);
|
||||
|
||||
if (offset > o->oChainChompMaxDistBetweenChainParts) {
|
||||
offset = o->oChainChompMaxDistBetweenChainParts / offset;
|
||||
|
@ -136,7 +130,7 @@ static void chain_chomp_update_chain_segments(void) {
|
|||
offsetZ += prevSegment->posZ;
|
||||
offset = sqrtf(offsetX * offsetX + offsetY * offsetY + offsetZ * offsetZ);
|
||||
|
||||
maxTotalOffset = o->oChainChompMaxDistFromPivotPerChainPart * (5 - i);
|
||||
f32 maxTotalOffset = o->oChainChompMaxDistFromPivotPerChainPart * (5 - i);
|
||||
if (offset > maxTotalOffset) {
|
||||
offset = maxTotalOffset / offset;
|
||||
offsetX *= offset;
|
||||
|
@ -168,9 +162,9 @@ static void chain_chomp_sub_act_turn(void) {
|
|||
chain_chomp_restore_normal_chain_lengths();
|
||||
obj_move_pitch_approach(0, 0x100);
|
||||
|
||||
struct Object* player = nearest_player_to_object(o);
|
||||
int distanceToPlayer = dist_between_objects(o, player);
|
||||
int angleToPlayer = obj_angle_to_object(o, player);
|
||||
struct Object *player = nearest_player_to_object(o);
|
||||
s32 distanceToPlayer = dist_between_objects(o, player);
|
||||
s32 angleToPlayer = obj_angle_to_object(o, player);
|
||||
|
||||
if (o->oMoveFlags & OBJ_MOVE_MASK_ON_GROUND) {
|
||||
cur_obj_rotate_yaw_toward(angleToPlayer, 0x400);
|
||||
|
@ -343,8 +337,6 @@ static void chain_chomp_released_end_cutscene(void) {
|
|||
* released.
|
||||
*/
|
||||
static void chain_chomp_act_move(void) {
|
||||
f32 maxDistToPivot;
|
||||
|
||||
// Unload chain if mario is far enough
|
||||
cur_obj_update_floor_and_walls();
|
||||
|
||||
|
@ -389,7 +381,7 @@ static void chain_chomp_act_move(void) {
|
|||
+ o->oChainChompSegments[0].posZ * o->oChainChompSegments[0].posZ);
|
||||
|
||||
// If the chain is fully stretched
|
||||
maxDistToPivot = o->oChainChompMaxDistFromPivotPerChainPart * 5;
|
||||
f32 maxDistToPivot = o->oChainChompMaxDistFromPivotPerChainPart * 5;
|
||||
if (o->oChainChompDistToPivot > maxDistToPivot) {
|
||||
f32 ratio = maxDistToPivot / o->oChainChompDistToPivot;
|
||||
o->oChainChompDistToPivot = maxDistToPivot;
|
||||
|
@ -524,9 +516,9 @@ void bhv_wooden_post_update(void) {
|
|||
if (o->oWoodenPostOffsetY != 0.0f) {
|
||||
o->oPosY = o->oHomeY + o->oWoodenPostOffsetY;
|
||||
} else if (!(o->oBehParams & WOODEN_POST_BP_NO_COINS_MASK)) {
|
||||
struct Object* player = nearest_player_to_object(o);
|
||||
int distanceToPlayer = dist_between_objects(o, player);
|
||||
int angleToPlayer = obj_angle_to_object(o, player);
|
||||
struct Object *player = nearest_player_to_object(o);
|
||||
s32 distanceToPlayer = dist_between_objects(o, player);
|
||||
s32 angleToPlayer = obj_angle_to_object(o, player);
|
||||
|
||||
// Reset the timer once mario is far enough
|
||||
if (distanceToPlayer > 400.0f) {
|
||||
|
@ -536,9 +528,9 @@ void bhv_wooden_post_update(void) {
|
|||
// coins
|
||||
o->oWoodenPostTotalMarioAngle += (s16)(angleToPlayer - o->oWoodenPostPrevAngleToMario);
|
||||
if (absi(o->oWoodenPostTotalMarioAngle) > 0x30000 && o->oTimer < 200) {
|
||||
network_send_object(o);
|
||||
obj_spawn_loot_yellow_coins(o, 5, 20.0f);
|
||||
set_object_respawn_info_bits(o, 1);
|
||||
network_send_object(o);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,31 +1,55 @@
|
|||
// hidden_star.c.inc
|
||||
|
||||
void bhv_hidden_star_init(void) {
|
||||
s16 sp36;
|
||||
struct Object *sp30;
|
||||
|
||||
sp36 = count_objects_with_behavior(bhvHiddenStarTrigger);
|
||||
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 count = count_objects_with_behavior(bhvHiddenStarTrigger);
|
||||
if (count == 0) {
|
||||
struct Object *obj = spawn_object_abs_with_rot(o, 0, MODEL_STAR, bhvStar, o->oPosX, o->oPosY, o->oPosZ, 0, 0, 0);
|
||||
if (obj != NULL) { obj->oBehParams = o->oBehParams; }
|
||||
o->activeFlags = ACTIVE_FLAG_DEACTIVATED;
|
||||
}
|
||||
|
||||
o->oHiddenStarTriggerCounter = 5 - sp36;
|
||||
o->oHiddenStarTriggerCounter = 5 - count;
|
||||
|
||||
// We haven't interacted with a player yet.
|
||||
// We also don't sync this as not only is it not required
|
||||
// but it also is only set for an interaction.
|
||||
// Therefore this object must already be loaded for it to be set
|
||||
// and if it wasn't. You couldn't of possibly been the one
|
||||
// who last interacted to begin with.
|
||||
o->oHiddenStarLastInteractedObject = NULL;
|
||||
|
||||
if (!network_sync_object_initialized(o)) {
|
||||
struct SyncObject *so = network_init_object(o, SYNC_DISTANCE_ONLY_EVENTS);
|
||||
if (so) {
|
||||
network_init_object_field(o, &o->oAction);
|
||||
network_init_object_field(o, &o->oHiddenStarTriggerCounter);
|
||||
network_init_object_field(o, &o->oPosX);
|
||||
network_init_object_field(o, &o->oPosY);
|
||||
network_init_object_field(o, &o->oPosZ);
|
||||
network_init_object_field(o, &o->oTimer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void bhv_hidden_star_loop(void) {
|
||||
switch (o->oAction) {
|
||||
case 0:
|
||||
if (o->oHiddenStarTriggerCounter == 5)
|
||||
if (o->oHiddenStarTriggerCounter == 5) {
|
||||
o->oAction = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if (o->oTimer > 2) {
|
||||
spawn_red_coin_cutscene_star(o->oPosX, o->oPosY, o->oPosZ);
|
||||
struct Object *obj = spawn_red_coin_cutscene_star(o->oPosX, o->oPosY, o->oPosZ);
|
||||
if (obj != NULL) {
|
||||
if (o->oHiddenStarLastInteractedObject == &gMarioStates[0]) {
|
||||
obj->oStarSpawnExtCutsceneFlags = 1;
|
||||
} else {
|
||||
obj->oStarSpawnExtCutsceneFlags = 0;
|
||||
}
|
||||
spawn_mist_particles();
|
||||
}
|
||||
o->activeFlags = ACTIVE_FLAG_DEACTIVATED;
|
||||
}
|
||||
break;
|
||||
|
@ -34,15 +58,21 @@ void bhv_hidden_star_loop(void) {
|
|||
|
||||
/* TODO: this is likely not a checkpoint but a Secret */
|
||||
void bhv_hidden_star_trigger_loop(void) {
|
||||
struct Object *hiddenStar;
|
||||
if ((o->oInteractStatus & INT_STATUS_INTERACTED) || obj_check_if_collided_with_object(o, gMarioObject) == 1) {
|
||||
hiddenStar = cur_obj_nearest_object_with_behavior(bhvHiddenStar);
|
||||
if ((o->oInteractStatus & INT_STATUS_INTERACTED) || obj_check_if_collided_with_object(o, gMarioObjects[0]) == 1) {
|
||||
struct Object *hiddenStar = cur_obj_nearest_object_with_behavior(bhvHiddenStar);
|
||||
if (hiddenStar != NULL) {
|
||||
hiddenStar->oHiddenStarTriggerCounter++;
|
||||
if (hiddenStar->oHiddenStarTriggerCounter != 5) {
|
||||
spawn_orange_number(hiddenStar->oHiddenStarTriggerCounter, 0, 0, 0);
|
||||
}
|
||||
|
||||
// Set the last person who interacted with a secret to the
|
||||
// parent so only they get the star cutscene.
|
||||
struct MarioState *player = nearest_mario_state_to_object(o);
|
||||
if (player) {
|
||||
hiddenStar->oHiddenStarLastInteractedObject = player;
|
||||
}
|
||||
|
||||
#ifdef VERSION_JP
|
||||
play_sound(SOUND_MENU_STAR_SOUND, gGlobalSoundSource);
|
||||
#else
|
||||
|
@ -63,14 +93,22 @@ void bhv_bowser_course_red_coin_star_loop(void) {
|
|||
gRedCoinsCollected = o->oHiddenStarTriggerCounter;
|
||||
switch (o->oAction) {
|
||||
case 0:
|
||||
if (o->oHiddenStarTriggerCounter == 8)
|
||||
if (o->oHiddenStarTriggerCounter == 8) {
|
||||
o->oAction = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if (o->oTimer > 2) {
|
||||
spawn_no_exit_star(o->oPosX, o->oPosY, o->oPosZ);
|
||||
struct Object *obj = spawn_no_exit_star(o->oPosX, o->oPosY, o->oPosZ);
|
||||
if (obj != NULL) {
|
||||
if (o->oHiddenStarLastInteractedObject == &gMarioStates[0]) {
|
||||
obj->oStarSpawnExtCutsceneFlags = 1;
|
||||
} else {
|
||||
obj->oStarSpawnExtCutsceneFlags = 0;
|
||||
}
|
||||
spawn_mist_particles();
|
||||
}
|
||||
o->activeFlags = ACTIVE_FLAG_DEACTIVATED;
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -23,24 +23,19 @@ static struct ObjectHitbox sRedCoinHitbox = {
|
|||
* Red coin initialization function. Sets the coin's hitbox and parent object.
|
||||
*/
|
||||
void bhv_red_coin_init(void) {
|
||||
// This floor and floor height are unused. Perhaps for orange number spawns originally?
|
||||
struct Surface *dummyFloor;
|
||||
UNUSED f32 floorHeight = find_floor(o->oPosX, o->oPosY, o->oPosZ, &dummyFloor);
|
||||
|
||||
struct Object *hiddenRedCoinStar;
|
||||
|
||||
// Set the red coins to have a parent of the closest red coin star.
|
||||
hiddenRedCoinStar = cur_obj_nearest_object_with_behavior(bhvHiddenRedCoinStar);
|
||||
if (hiddenRedCoinStar != NULL)
|
||||
o->parentObj = hiddenRedCoinStar;
|
||||
else {
|
||||
struct Object *hiddenRedCoinStar = cur_obj_nearest_object_with_behavior(bhvHiddenRedCoinStar);
|
||||
// If it's not a typical red coin star, it's a Bowser one.
|
||||
if (hiddenRedCoinStar == NULL) {
|
||||
hiddenRedCoinStar = cur_obj_nearest_object_with_behavior(bhvBowserCourseRedCoinStar);
|
||||
}
|
||||
|
||||
// If we found a red coin star, It's our parent.
|
||||
if (hiddenRedCoinStar != NULL) {
|
||||
o->parentObj = hiddenRedCoinStar;
|
||||
} else {
|
||||
o->parentObj = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
obj_set_hitbox(o, &sRedCoinHitbox);
|
||||
}
|
||||
|
@ -57,6 +52,13 @@ void bhv_red_coin_loop(void) {
|
|||
// ...increment the star's counter.
|
||||
o->parentObj->oHiddenStarTriggerCounter++;
|
||||
|
||||
// Set the last person who interacted with a red coin to the
|
||||
// parent so only they get the star cutscene.
|
||||
struct MarioState *player = nearest_mario_state_to_object(o);
|
||||
if (player) {
|
||||
o->parentObj->oHiddenStarLastInteractedObject = player;
|
||||
}
|
||||
|
||||
// For JP version, play an identical sound for all coins.
|
||||
#ifdef VERSION_JP
|
||||
create_sound_spawner(SOUND_GENERAL_RED_COIN);
|
||||
|
|
|
@ -7,7 +7,9 @@
|
|||
// a rolling log of another variation.
|
||||
|
||||
static void bhv_rolling_log_network_init(void) {
|
||||
network_init_object(o, 4000.0f);
|
||||
if (!network_sync_object_initialized(o)) {
|
||||
struct SyncObject *so = network_init_object(o, 4000.0f);
|
||||
if (so) {
|
||||
network_init_object_field(o, &o->oAngleVelPitch);
|
||||
network_init_object_field(o, &o->oFaceAnglePitch);
|
||||
network_init_object_field(o, &o->oMoveAnglePitch);
|
||||
|
@ -15,6 +17,8 @@ static void bhv_rolling_log_network_init(void) {
|
|||
network_init_object_field(o, &o->oPitouneUnkF8);
|
||||
network_init_object_field(o, &o->oPitouneUnkFC);
|
||||
network_init_object_field(o, &o->oForwardVel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void bhv_ttm_rolling_log_init(void) {
|
||||
|
@ -143,11 +147,13 @@ void volcano_act_3(void) {
|
|||
|
||||
void bhv_volcano_trap_loop(void) {
|
||||
if (!network_sync_object_initialized(o)) {
|
||||
network_init_object(o, 2000.0f);
|
||||
struct SyncObject *so = network_init_object(o, 2000.0f);
|
||||
if (so) {
|
||||
network_init_object_field(o, &o->oRollingLogUnkF4);
|
||||
network_init_object_field(o, &o->oAngleVelPitch);
|
||||
network_init_object_field(o, &o->oFaceAnglePitch);
|
||||
}
|
||||
}
|
||||
|
||||
switch (o->oAction) {
|
||||
case 0:
|
||||
|
|
|
@ -25,7 +25,8 @@ s32 update_angle_from_move_flags(s32 *angle) {
|
|||
|
||||
void bhv_scuttlebug_loop(void) {
|
||||
if (!network_sync_object_initialized(o)) {
|
||||
network_init_object(o, 4000.0f);
|
||||
struct SyncObject *so = network_init_object(o, 4000.0f);
|
||||
if (so) {
|
||||
network_init_object_field(o, &o->oFlags);
|
||||
network_init_object_field(o, &o->oForwardVel);
|
||||
network_init_object_field(o, &o->oHomeX);
|
||||
|
@ -34,12 +35,11 @@ void bhv_scuttlebug_loop(void) {
|
|||
network_init_object_field(o, &o->oInteractStatus);
|
||||
network_init_object_field(o, &o->oScuttlebugUnkF4);
|
||||
}
|
||||
}
|
||||
|
||||
struct Object* player = nearest_player_to_object(o);
|
||||
int angleToPlayer = obj_angle_to_object(o, player);
|
||||
struct Object *player = nearest_player_to_object(o);
|
||||
s32 angleToPlayer = obj_angle_to_object(o, player);
|
||||
|
||||
UNUSED s32 unused;
|
||||
f32 sp18;
|
||||
cur_obj_update_floor_and_walls();
|
||||
if (o->oSubAction != 0
|
||||
&& cur_obj_set_hitbox_and_die_if_attacked(&sScuttlebugHitbox, SOUND_OBJ_DYING_ENEMY1,
|
||||
|
@ -114,13 +114,16 @@ void bhv_scuttlebug_loop(void) {
|
|||
o->oSubAction = 0;
|
||||
break;
|
||||
}
|
||||
if (o->oForwardVel < 10.0f)
|
||||
f32 sp18;
|
||||
if (o->oForwardVel < 10.0f) {
|
||||
sp18 = 1.0f;
|
||||
else
|
||||
} else {
|
||||
sp18 = 3.0f;
|
||||
}
|
||||
cur_obj_init_animation_with_accel_and_sound(0, sp18);
|
||||
if (o->oMoveFlags & OBJ_MOVE_MASK_ON_GROUND)
|
||||
if (o->oMoveFlags & OBJ_MOVE_MASK_ON_GROUND) {
|
||||
set_obj_anim_with_accel_and_sound(1, 23, SOUND_OBJ2_SCUTTLEBUG_WALK);
|
||||
}
|
||||
if (o->parentObj != o) {
|
||||
if (obj_is_hidden(o))
|
||||
obj_mark_for_deletion(o);
|
||||
|
@ -134,31 +137,32 @@ void bhv_scuttlebug_loop(void) {
|
|||
|
||||
void bhv_scuttlebug_spawn_loop(void) {
|
||||
if (!network_sync_object_initialized(o)) {
|
||||
network_init_object(o, SYNC_DISTANCE_ONLY_EVENTS);
|
||||
struct SyncObject *so = network_init_object(o, SYNC_DISTANCE_ONLY_EVENTS);
|
||||
if (so) {
|
||||
network_init_object_field(o, &o->oAction);
|
||||
network_init_object_field(o, &o->oTimer);
|
||||
network_init_object_field(o, &o->oScuttlebugSpawnerUnkF4);
|
||||
network_init_object_field(o, &o->oScuttlebugSpawnerUnk88);
|
||||
}
|
||||
}
|
||||
|
||||
struct MarioState* marioState = nearest_mario_state_to_object(o);
|
||||
if (marioState->playerIndex != 0) { return; }
|
||||
|
||||
struct Object* player = marioState->marioObj;
|
||||
int distanceToPlayer = dist_between_objects(o, player);
|
||||
s32 distanceToPlayer = dist_between_objects(o, player);
|
||||
|
||||
struct Object *scuttlebug;
|
||||
if (o->oAction == 0) {
|
||||
if (o->oTimer > 30 && 500.0f < distanceToPlayer && distanceToPlayer < 1500.0f) {
|
||||
cur_obj_play_sound_2(SOUND_OBJ2_SCUTTLEBUG_ALERT);
|
||||
scuttlebug = spawn_object(o, MODEL_SCUTTLEBUG, bhvScuttlebug);
|
||||
struct Object *scuttlebug = spawn_object(o, MODEL_SCUTTLEBUG, bhvScuttlebug);
|
||||
if (scuttlebug != NULL) {
|
||||
scuttlebug->oScuttlebugUnkF4 = o->oScuttlebugSpawnerUnkF4;
|
||||
scuttlebug->oForwardVel = 30.0f;
|
||||
scuttlebug->oVelY = 80.0f;
|
||||
|
||||
network_set_sync_id(scuttlebug);
|
||||
struct Object* spawn_objects[] = { scuttlebug };
|
||||
struct Object *spawn_objects[] = { scuttlebug };
|
||||
u32 models[] = { MODEL_SCUTTLEBUG };
|
||||
network_send_spawn_objects(spawn_objects, models, 1);
|
||||
}
|
||||
|
|
|
@ -24,16 +24,19 @@ void bhv_seesaw_platform_init(void) {
|
|||
o->oCollisionDistance = 2000.0f;
|
||||
}
|
||||
|
||||
network_init_object(o, 1000.0f);
|
||||
if (!network_sync_object_initialized(o)) {
|
||||
struct SyncObject *so = network_init_object(o, 1000.0f);
|
||||
if (so) {
|
||||
network_init_object_field(o, &o->oSeesawPlatformPitchVel);
|
||||
network_init_object_field(o, &o->oFaceAnglePitch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update function for bhvSeesawPlatform.
|
||||
*/
|
||||
void bhv_seesaw_platform_update(void) {
|
||||
UNUSED s32 startPitch = o->oFaceAnglePitch;
|
||||
o->oFaceAnglePitch += (s32) o->oSeesawPlatformPitchVel;
|
||||
|
||||
if (absf(o->oSeesawPlatformPitchVel) > 10.0f) {
|
||||
|
@ -44,7 +47,7 @@ void bhv_seesaw_platform_update(void) {
|
|||
f32 y = 0;
|
||||
f32 z = 0;
|
||||
u8 playersTouched = 0;
|
||||
for (int i = 0; i < MAX_PLAYERS; i++) {
|
||||
for (s32 i = 0; i < MAX_PLAYERS; i++) {
|
||||
if (!is_player_active(&gMarioStates[i])) { continue; }
|
||||
if (gMarioStates[i].marioObj->platform == o) {
|
||||
x += gMarioStates[i].marioObj->oPosX;
|
||||
|
@ -59,12 +62,11 @@ void bhv_seesaw_platform_update(void) {
|
|||
y /= (f32)playersTouched;
|
||||
z /= (f32)playersTouched;
|
||||
|
||||
int distanceToPlayer = dist_between_object_and_point(o, x, y, z);
|
||||
int angleToPlayer = obj_angle_to_point(o, x, z);
|
||||
s32 distanceToPlayer = dist_between_object_and_point(o, x, y, z);
|
||||
s32 angleToPlayer = obj_angle_to_point(o, x, z);
|
||||
|
||||
// Rotate toward mario
|
||||
f32 rotation = distanceToPlayer * coss(angleToPlayer - o->oMoveAngleYaw);
|
||||
UNUSED s32 unused;
|
||||
|
||||
// Deceleration is faster than acceleration
|
||||
if (o->oSeesawPlatformPitchVel * rotation < 0) {
|
||||
|
|
|
@ -4,18 +4,19 @@ u8 bhv_sl_snowman_wind_loop_continue_dialog(void) { return o->oSubAction == SL_S
|
|||
|
||||
void bhv_sl_snowman_wind_loop(void) {
|
||||
if (!network_sync_object_initialized(o)) {
|
||||
network_init_object(o, SYNC_DISTANCE_ONLY_EVENTS);
|
||||
struct SyncObject *so = network_init_object(o, SYNC_DISTANCE_ONLY_EVENTS);
|
||||
if (so) {
|
||||
network_init_object_field(o, &o->oAction);
|
||||
network_init_object_field(o, &o->oPrevAction);
|
||||
network_init_object_field(o, &o->oTimer);
|
||||
network_init_object_field(o, &o->oSubAction);
|
||||
}
|
||||
}
|
||||
|
||||
struct Object* player = nearest_player_to_object(o);
|
||||
int distanceToPlayer = dist_between_objects(o, player);
|
||||
int angleToPlayer = obj_angle_to_object(o, player);
|
||||
struct Object *player = nearest_player_to_object(o);
|
||||
s32 distanceToPlayer = dist_between_objects(o, player);
|
||||
s32 angleToPlayer = obj_angle_to_object(o, player);
|
||||
|
||||
UNUSED s32 unusedVar = 0;
|
||||
s16 marioAngleFromWindSource;
|
||||
Vec3f tempPos;
|
||||
|
||||
|
|
|
@ -38,7 +38,8 @@ void bhv_sl_walking_penguin_loop(void) {
|
|||
f32 perpendicularOffset = 100.0f;
|
||||
|
||||
if (!network_sync_object_initialized(o)) {
|
||||
network_init_object(o, 4000.0f);
|
||||
struct SyncObject *so = network_init_object(o, 4000.0f);
|
||||
if (so) {
|
||||
network_init_object_field(o, &o->oTimer);
|
||||
network_init_object_field(o, &o->oAction);
|
||||
network_init_object_field(o, &o->oPrevAction);
|
||||
|
@ -47,6 +48,7 @@ void bhv_sl_walking_penguin_loop(void) {
|
|||
network_init_object_field(o, &o->oSLWalkingPenguinWindCollisionXPos);
|
||||
network_init_object_field(o, &o->oSLWalkingPenguinWindCollisionZPos);
|
||||
}
|
||||
}
|
||||
|
||||
o->oAngleVelYaw = 0;
|
||||
cur_obj_update_floor_and_walls();
|
||||
|
|
|
@ -36,7 +36,6 @@ void bhv_sliding_plat_2_init(void) {
|
|||
void bhv_sliding_plat_2_loop(void) {
|
||||
if (!network_sync_object_initialized(o)) {
|
||||
struct SyncObject* so = network_init_object(o, 4000.0f);
|
||||
|
||||
if (so) {
|
||||
so->minUpdateRate = 5.0f;
|
||||
network_init_object_field(o, &o->oBackAndForthPlatformDirection);
|
||||
|
|
|
@ -140,7 +140,7 @@ static u8 spawn_star_deduplication(u32* array, u8* count, u32 behParams) {
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
struct Object* spawn_default_star(f32 x, f32 y, f32 z) {
|
||||
struct Object *spawn_default_star(f32 x, f32 y, f32 z) {
|
||||
if (sCurrPlayMode != PLAY_MODE_NORMAL && sCurrPlayMode != PLAY_MODE_PAUSED) { return NULL; }
|
||||
if (o == NULL) { return NULL; }
|
||||
u32 behParams = o->oBehParams;
|
||||
|
@ -154,12 +154,12 @@ struct Object* spawn_default_star(f32 x, f32 y, f32 z) {
|
|||
star = spawn_star(star, x, y, z);
|
||||
if (star != NULL) {
|
||||
star->oBehParams2ndByte = 0;
|
||||
network_send_spawn_star(star, 0, x, y, z, behParams);
|
||||
network_send_spawn_star(star, 0, x, y, z, behParams, UNKNOWN_GLOBAL_INDEX);
|
||||
}
|
||||
return star;
|
||||
}
|
||||
|
||||
struct Object* spawn_red_coin_cutscene_star(f32 x, f32 y, f32 z) {
|
||||
struct Object *spawn_red_coin_cutscene_star(f32 x, f32 y, f32 z) {
|
||||
u32 behParams = o->oBehParams;
|
||||
|
||||
// de-duplication checking
|
||||
|
@ -171,12 +171,12 @@ struct Object* spawn_red_coin_cutscene_star(f32 x, f32 y, f32 z) {
|
|||
star = spawn_star(star, x, y, z);
|
||||
if (star != NULL) {
|
||||
star->oBehParams2ndByte = 1;
|
||||
network_send_spawn_star(star, 1, x, y, z, behParams);
|
||||
network_send_spawn_star(star, 1, x, y, z, behParams, UNKNOWN_GLOBAL_INDEX);
|
||||
}
|
||||
return star;
|
||||
}
|
||||
|
||||
struct Object* spawn_no_exit_star(f32 x, f32 y, f32 z) {
|
||||
struct Object *spawn_no_exit_star(f32 x, f32 y, f32 z) {
|
||||
u32 behParams = o->oBehParams;
|
||||
|
||||
// de-duplication checking
|
||||
|
@ -189,14 +189,45 @@ struct Object* spawn_no_exit_star(f32 x, f32 y, f32 z) {
|
|||
if (star != NULL) {
|
||||
star->oBehParams2ndByte = 1;
|
||||
star->oInteractionSubtype |= INT_SUBTYPE_NO_EXIT;
|
||||
network_send_spawn_star(star, 2, x, y, z, behParams);
|
||||
network_send_spawn_star(star, 2, x, y, z, behParams, UNKNOWN_GLOBAL_INDEX);
|
||||
}
|
||||
return star;
|
||||
}
|
||||
|
||||
/**
|
||||
* A special star spawning routine just for a networked stars.
|
||||
* These stars require the global index for a network player for proper
|
||||
* cutscene functionality.
|
||||
*/
|
||||
struct Object *spawn_networked_default_star(f32 x, f32 y, f32 z, u8 networkPlayerIndex) {
|
||||
if (sCurrPlayMode != PLAY_MODE_NORMAL && sCurrPlayMode != PLAY_MODE_PAUSED) { return NULL; }
|
||||
if (o == NULL) { return NULL; }
|
||||
u32 behParams = o->oBehParams;
|
||||
|
||||
// de-duplication checking
|
||||
if (spawn_star_deduplication(gSpawnedStarDefault, &gSpawnedStarDefaultCount, behParams)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct Object *star = NULL;
|
||||
star = spawn_star(star, x, y, z);
|
||||
if (star != NULL) {
|
||||
star->oBehParams2ndByte = 0;
|
||||
//printf("spawn_networked_default_star: Network Player Index is %i, Our Global Index is %i.\n", networkPlayerIndex, gNetworkPlayers[0].globalIndex);
|
||||
if (networkPlayerIndex == gNetworkPlayers[0].globalIndex) {
|
||||
star->oStarSpawnExtCutsceneFlags = 1;
|
||||
} else {
|
||||
star->oStarSpawnExtCutsceneFlags = 0;
|
||||
}
|
||||
network_send_spawn_star(star, 0, x, y, z, behParams, networkPlayerIndex);
|
||||
}
|
||||
return star;
|
||||
}
|
||||
|
||||
void bhv_hidden_red_coin_star_init(void) {
|
||||
if (gCurrCourseNum != COURSE_JRB)
|
||||
if (gCurrCourseNum != COURSE_JRB) {
|
||||
spawn_object(o, MODEL_TRANSPARENT_STAR, bhvRedCoinStarMarker);
|
||||
}
|
||||
|
||||
s16 redCoins = count_objects_with_behavior(bhvRedCoin);
|
||||
if (redCoins == 0) {
|
||||
|
@ -206,20 +237,48 @@ void bhv_hidden_red_coin_star_init(void) {
|
|||
}
|
||||
|
||||
o->oHiddenStarTriggerCounter = 8 - redCoins;
|
||||
|
||||
// We haven't interacted with a player yet.
|
||||
// We also don't sync this as not only is it not required
|
||||
// but it also is only set for an interaction.
|
||||
// Therefore this object must already be loaded for it to be set
|
||||
// and if it wasn't. You couldn't of possibly been the one
|
||||
// who last interacted to begin with.
|
||||
o->oHiddenStarLastInteractedObject = NULL;
|
||||
|
||||
if (!network_sync_object_initialized(o)) {
|
||||
struct SyncObject *so = network_init_object(o, SYNC_DISTANCE_ONLY_EVENTS);
|
||||
if (so) {
|
||||
network_init_object_field(o, &o->oAction);
|
||||
network_init_object_field(o, &o->oHiddenStarTriggerCounter);
|
||||
network_init_object_field(o, &o->oPosX);
|
||||
network_init_object_field(o, &o->oPosY);
|
||||
network_init_object_field(o, &o->oPosZ);
|
||||
network_init_object_field(o, &o->oTimer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void bhv_hidden_red_coin_star_loop(void) {
|
||||
gRedCoinsCollected = o->oHiddenStarTriggerCounter;
|
||||
switch (o->oAction) {
|
||||
case 0:
|
||||
if (o->oHiddenStarTriggerCounter == 8)
|
||||
if (o->oHiddenStarTriggerCounter == 8) {
|
||||
o->oAction = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if (o->oTimer > 2) {
|
||||
spawn_red_coin_cutscene_star(o->oPosX, o->oPosY, o->oPosZ);
|
||||
struct Object *obj = spawn_red_coin_cutscene_star(o->oPosX, o->oPosY, o->oPosZ);
|
||||
if (obj != NULL) {
|
||||
if (o->oHiddenStarLastInteractedObject == &gMarioStates[0]) {
|
||||
obj->oStarSpawnExtCutsceneFlags = 1;
|
||||
} else {
|
||||
obj->oStarSpawnExtCutsceneFlags = 0;
|
||||
}
|
||||
spawn_mist_particles();
|
||||
}
|
||||
o->activeFlags = ACTIVE_FLAG_DEACTIVATED;
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
// treasure_chest.c.inc
|
||||
|
||||
#include "pc/network/network_player.h"
|
||||
|
||||
/**
|
||||
* Hitbox for treasure chest bottom.
|
||||
*/
|
||||
|
@ -15,8 +17,9 @@ static struct ObjectHitbox sTreasureChestBottomHitbox = {
|
|||
/* hurtboxHeight: */ 310,
|
||||
};
|
||||
|
||||
|
||||
void bhv_treasure_chest_top_loop(void) {
|
||||
struct Object* sp34 = o->parentObj->parentObj;
|
||||
struct Object *rootParent = o->parentObj->parentObj;
|
||||
|
||||
switch (o->oAction) {
|
||||
case 0:
|
||||
|
@ -27,7 +30,7 @@ void bhv_treasure_chest_top_loop(void) {
|
|||
|
||||
case 1:
|
||||
if (o->oTimer == 0) {
|
||||
if (sp34->oTreasureChestUnkFC == 0) {
|
||||
if (rootParent->oTreasureChestIsAboveWater == 0) {
|
||||
spawn_object_relative(0, 0, -80, 120, o, MODEL_BUBBLE, bhvWaterAirBubble);
|
||||
play_sound(SOUND_GENERAL_CLAM_SHELL1, o->header.gfx.cameraToObject);
|
||||
} else {
|
||||
|
@ -39,9 +42,10 @@ void bhv_treasure_chest_top_loop(void) {
|
|||
if (o->oFaceAnglePitch < -0x4000) {
|
||||
o->oFaceAnglePitch = -0x4000;
|
||||
o->oAction++;
|
||||
if (o->parentObj->oBehParams2ndByte != 4)
|
||||
if (o->parentObj->oBehParams2ndByte != 4) {
|
||||
spawn_orange_number(o->parentObj->oBehParams2ndByte, 0, -40, 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
|
@ -74,36 +78,35 @@ void bhv_treasure_chest_bottom_loop(void) {
|
|||
}
|
||||
o->parentObj->oTreasureChestSound = 0;
|
||||
}
|
||||
struct Object* player = nearest_player_to_object(o);
|
||||
struct MarioState *player = nearest_mario_state_to_object(o);
|
||||
switch (o->oAction) {
|
||||
case 0:
|
||||
if (network_owns_object(o->parentObj) && obj_check_if_facing_toward_angle(o->oMoveAngleYaw, player->header.gfx.angle[1] + 0x8000, 0x3000)) {
|
||||
if (player && network_owns_object(o->parentObj) && obj_check_if_facing_toward_angle(o->oMoveAngleYaw, player->marioObj->header.gfx.angle[1] + 0x8000, 0x3000)) {
|
||||
if (is_point_within_radius_of_mario(o->oPosX, o->oPosY, o->oPosZ, 150)) {
|
||||
if (!o->parentObj->oTreasureChestUnkF8) {
|
||||
if (o->parentObj->oTreasureChestUnkF4 == o->oBehParams2ndByte) {
|
||||
if (!o->parentObj->oTreasureChestIsLastInteractionIncorrect) {
|
||||
if (o->parentObj->oTreasureChestCurrentAnswer == o->oBehParams2ndByte) {
|
||||
play_sound(SOUND_GENERAL2_RIGHT_ANSWER, gGlobalSoundSource);
|
||||
o->parentObj->oTreasureChestUnkF4++;
|
||||
o->parentObj->oTreasureChestCurrentAnswer++;
|
||||
o->oAction = 1;
|
||||
o->parentObj->oTreasureChestSound = 1;
|
||||
network_send_object(o->parentObj);
|
||||
o->parentObj->oTreasureChestSound = 0;
|
||||
} else {
|
||||
o->parentObj->oTreasureChestUnkF4 = 1;
|
||||
o->parentObj->oTreasureChestUnkF8 = 1;
|
||||
o->parentObj->oTreasureChestCurrentAnswer = 1;
|
||||
o->parentObj->oTreasureChestIsLastInteractionIncorrect = 1;
|
||||
o->oAction = 2;
|
||||
cur_obj_become_tangible();
|
||||
play_sound(SOUND_MENU_CAMERA_BUZZ, gGlobalSoundSource);
|
||||
o->parentObj->oTreasureChestSound = 2;
|
||||
}
|
||||
o->parentObj->oTreasureChestLastNetworkPlayerIndex = gNetworkPlayers[player->playerIndex].globalIndex;
|
||||
network_send_object(o->parentObj);
|
||||
o->parentObj->oTreasureChestSound = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if (o->parentObj->oTreasureChestUnkF8 == 1) {
|
||||
if (o->parentObj->oTreasureChestIsLastInteractionIncorrect == 1) {
|
||||
o->oAction = 0;
|
||||
}
|
||||
break;
|
||||
|
@ -111,7 +114,7 @@ void bhv_treasure_chest_bottom_loop(void) {
|
|||
case 2:
|
||||
cur_obj_become_intangible();
|
||||
if (!is_point_within_radius_of_mario(o->oPosX, o->oPosY, o->oPosZ, 500)) {
|
||||
o->parentObj->oTreasureChestUnkF8 = 0;
|
||||
o->parentObj->oTreasureChestIsLastInteractionIncorrect = 0;
|
||||
o->oAction = 0;
|
||||
}
|
||||
}
|
||||
|
@ -120,44 +123,56 @@ void bhv_treasure_chest_bottom_loop(void) {
|
|||
o->oInteractStatus = 0;
|
||||
}
|
||||
|
||||
struct Object* spawn_treasure_chest(s8 sp3B, s32 sp3C, s32 sp40, s32 sp44, s16 sp4A) {
|
||||
struct Object* sp34;
|
||||
sp34 = spawn_object_abs_with_rot(o, 0, MODEL_TREASURE_CHEST_BASE, bhvTreasureChestBottom, sp3C,
|
||||
sp40, sp44, 0, sp4A, 0);
|
||||
if (sp34 != NULL) { sp34->oBehParams2ndByte = sp3B; }
|
||||
return sp34;
|
||||
struct Object* spawn_treasure_chest(s8 index, s32 x, s32 y, s32 z, s16 r) {
|
||||
struct Object *obj = spawn_object_abs_with_rot(o, 0, MODEL_TREASURE_CHEST_BASE, bhvTreasureChestBottom, x, y, z, 0, r, 0);
|
||||
if (obj != NULL) { obj->oBehParams2ndByte = index; }
|
||||
return obj;
|
||||
}
|
||||
|
||||
void bhv_treasure_chest_ship_init(void) {
|
||||
struct Object* chests[4] = { 0 };
|
||||
struct Object *chests[4] = { 0 };
|
||||
chests[0] = spawn_treasure_chest(1, 400, -350, -2700, 0);
|
||||
chests[1] = spawn_treasure_chest(2, 650, -350, -940, -0x6001);
|
||||
chests[2] = spawn_treasure_chest(3, -550, -350, -770, 0x5FFF);
|
||||
chests[3] = spawn_treasure_chest(4, 100, -350, -1700, 0);
|
||||
o->oTreasureChestUnkF4 = 1;
|
||||
o->oTreasureChestUnkFC = 0;
|
||||
|
||||
network_init_object(o, SYNC_DISTANCE_ONLY_EVENTS);
|
||||
o->oTreasureChestCurrentAnswer = 1;
|
||||
o->oTreasureChestIsAboveWater = 0;
|
||||
|
||||
// We haven't interacted with a player yet.
|
||||
// We also don't sync this as not only is it not required
|
||||
// but it also is only set for an interaction.
|
||||
// Therefore this object must already be loaded for it to be set
|
||||
// and if it wasn't. You couldn't of possibly been the one
|
||||
// who last interacted to begin with.
|
||||
o->oTreasureChestLastNetworkPlayerIndex = UNKNOWN_GLOBAL_INDEX;
|
||||
|
||||
if (!network_sync_object_initialized(o)) {
|
||||
struct SyncObject *so = network_init_object(o, SYNC_DISTANCE_ONLY_EVENTS);
|
||||
if (so) {
|
||||
network_init_object_field(o, &o->oAction);
|
||||
network_init_object_field(o, &o->oPrevAction);
|
||||
network_init_object_field(o, &o->oTimer);
|
||||
network_init_object_field(o, &o->oTreasureChestUnkF4);
|
||||
network_init_object_field(o, &o->oTreasureChestUnkF8);
|
||||
network_init_object_field(o, &o->oTreasureChestUnkFC);
|
||||
network_init_object_field(o, &o->oTreasureChestCurrentAnswer);
|
||||
network_init_object_field(o, &o->oTreasureChestIsLastInteractionIncorrect);
|
||||
network_init_object_field(o, &o->oTreasureChestIsAboveWater);
|
||||
network_init_object_field(o, &o->oTreasureChestSound);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
struct Object* chest = chests[i];
|
||||
network_init_object_field(o, &o->oTreasureChestLastNetworkPlayerIndex);
|
||||
for (s32 i = 0; i < 4; i++) {
|
||||
struct Object *chest = chests[i];
|
||||
network_init_object_field(o, &chest->oAction);
|
||||
network_init_object_field(o, &chest->oPrevAction);
|
||||
network_init_object_field(o, &chest->oTimer);
|
||||
network_init_object_field(o, &chest->oIntangibleTimer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void bhv_treasure_chest_ship_loop(void) {
|
||||
switch (o->oAction) {
|
||||
case 0:
|
||||
if (network_owns_object(o) && o->oTreasureChestUnkF4 == 5) {
|
||||
if (network_owns_object(o) && o->oTreasureChestCurrentAnswer == 5) {
|
||||
play_puzzle_jingle();
|
||||
fade_volume_scale(0, 127, 1000);
|
||||
o->oAction = 1;
|
||||
|
@ -185,35 +200,49 @@ void bhv_treasure_chest_ship_loop(void) {
|
|||
}
|
||||
|
||||
void bhv_treasure_chest_jrb_init(void) {
|
||||
struct Object* chests[4] = { 0 };
|
||||
struct Object *chests[4] = { 0 };
|
||||
chests[0] = spawn_treasure_chest(1, -1700, -2812, -1150, 0x7FFF);
|
||||
chests[1] = spawn_treasure_chest(2, -1150, -2812, -1550, 0x7FFF);
|
||||
chests[2] = spawn_treasure_chest(3, -2400, -2812, -1800, 0x7FFF);
|
||||
chests[3] = spawn_treasure_chest(4, -1800, -2812, -2100, 0x7FFF);
|
||||
o->oTreasureChestUnkF4 = 1;
|
||||
o->oTreasureChestUnkFC = 1;
|
||||
|
||||
network_init_object(o, SYNC_DISTANCE_ONLY_EVENTS);
|
||||
o->oTreasureChestCurrentAnswer = 1;
|
||||
o->oTreasureChestIsAboveWater = 1;
|
||||
|
||||
// We haven't interacted with a player yet.
|
||||
// We also don't sync this as not only is it not required
|
||||
// but it also is only set for an interaction.
|
||||
// Therefore this object must already be loaded for it to be set
|
||||
// and if it wasn't. You couldn't of possibly been the one
|
||||
// who last interacted to begin with.
|
||||
o->oTreasureChestLastNetworkPlayerIndex = UNKNOWN_GLOBAL_INDEX;
|
||||
|
||||
if (!network_sync_object_initialized(o)) {
|
||||
struct SyncObject *so = network_init_object(o, SYNC_DISTANCE_ONLY_EVENTS);
|
||||
if (so) {
|
||||
network_init_object_field(o, &o->oAction);
|
||||
network_init_object_field(o, &o->oPrevAction);
|
||||
network_init_object_field(o, &o->oTimer);
|
||||
network_init_object_field(o, &o->oTreasureChestUnkF4);
|
||||
network_init_object_field(o, &o->oTreasureChestUnkF8);
|
||||
network_init_object_field(o, &o->oTreasureChestUnkFC);
|
||||
network_init_object_field(o, &o->oTreasureChestCurrentAnswer);
|
||||
network_init_object_field(o, &o->oTreasureChestIsLastInteractionIncorrect);
|
||||
network_init_object_field(o, &o->oTreasureChestIsAboveWater);
|
||||
network_init_object_field(o, &o->oTreasureChestSound);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
struct Object* chest = chests[i];
|
||||
network_init_object_field(o, &o->oTreasureChestLastNetworkPlayerIndex);
|
||||
for (s32 i = 0; i < 4; i++) {
|
||||
struct Object *chest = chests[i];
|
||||
network_init_object_field(o, &chest->oAction);
|
||||
network_init_object_field(o, &chest->oPrevAction);
|
||||
network_init_object_field(o, &chest->oTimer);
|
||||
network_init_object_field(o, &chest->oIntangibleTimer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void bhv_treasure_chest_jrb_loop(void) {
|
||||
switch (o->oAction) {
|
||||
case 0:
|
||||
if (network_owns_object(o) && o->oTreasureChestUnkF4 == 5) {
|
||||
if (network_owns_object(o) && o->oTreasureChestCurrentAnswer == 5) {
|
||||
play_puzzle_jingle();
|
||||
o->oAction = 1;
|
||||
o->oTreasureChestSound = 4;
|
||||
|
@ -225,7 +254,7 @@ void bhv_treasure_chest_jrb_loop(void) {
|
|||
case 1:
|
||||
if (o->oTimer == 60) {
|
||||
spawn_mist_particles();
|
||||
spawn_default_star(-1800.0f, -2500.0f, -1700.0f);
|
||||
spawn_networked_default_star(-1800.0f, -2500.0f, -1700.0f, o->oTreasureChestLastNetworkPlayerIndex);
|
||||
o->oAction = 2;
|
||||
}
|
||||
break;
|
||||
|
@ -236,36 +265,49 @@ void bhv_treasure_chest_jrb_loop(void) {
|
|||
}
|
||||
|
||||
void bhv_treasure_chest_init(void) {
|
||||
struct Object* chests[4] = { 0 };
|
||||
struct Object *chests[4] = { 0 };
|
||||
chests[0] = spawn_treasure_chest(1, -4500, -5119, 1300, -0x6001);
|
||||
chests[1] = spawn_treasure_chest(2, -1800, -5119, 1050, 0x1FFF);
|
||||
chests[2] = spawn_treasure_chest(3, -4500, -5119, -1100, 9102);
|
||||
chests[3] = spawn_treasure_chest(4, -2400, -4607, 125, 16019);
|
||||
|
||||
o->oTreasureChestUnkF4 = 1;
|
||||
o->oTreasureChestUnkFC = 0;
|
||||
o->oTreasureChestCurrentAnswer = 1;
|
||||
o->oTreasureChestIsAboveWater = 0;
|
||||
|
||||
network_init_object(o, SYNC_DISTANCE_ONLY_EVENTS);
|
||||
// We haven't interacted with a player yet.
|
||||
// We also don't sync this as not only is it not required
|
||||
// but it also is only set for an interaction.
|
||||
// Therefore this object must already be loaded for it to be set
|
||||
// and if it wasn't. You couldn't of possibly been the one
|
||||
// who last interacted to begin with.
|
||||
o->oTreasureChestLastNetworkPlayerIndex = UNKNOWN_GLOBAL_INDEX;
|
||||
|
||||
if (!network_sync_object_initialized(o)) {
|
||||
struct SyncObject *so = network_init_object(o, SYNC_DISTANCE_ONLY_EVENTS);
|
||||
if (so) {
|
||||
network_init_object_field(o, &o->oAction);
|
||||
network_init_object_field(o, &o->oPrevAction);
|
||||
network_init_object_field(o, &o->oTimer);
|
||||
network_init_object_field(o, &o->oTreasureChestUnkF4);
|
||||
network_init_object_field(o, &o->oTreasureChestUnkF8);
|
||||
network_init_object_field(o, &o->oTreasureChestUnkFC);
|
||||
network_init_object_field(o, &o->oTreasureChestCurrentAnswer);
|
||||
network_init_object_field(o, &o->oTreasureChestIsLastInteractionIncorrect);
|
||||
network_init_object_field(o, &o->oTreasureChestIsAboveWater);
|
||||
network_init_object_field(o, &o->oTreasureChestSound);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
struct Object* chest = chests[i];
|
||||
network_init_object_field(o, &o->oTreasureChestLastNetworkPlayerIndex);
|
||||
for (s32 i = 0; i < 4; i++) {
|
||||
struct Object *chest = chests[i];
|
||||
network_init_object_field(o, &chest->oAction);
|
||||
network_init_object_field(o, &chest->oPrevAction);
|
||||
network_init_object_field(o, &chest->oTimer);
|
||||
network_init_object_field(o, &chest->oIntangibleTimer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void bhv_treasure_chest_loop(void) {
|
||||
switch (o->oAction) {
|
||||
case 0:
|
||||
if (network_owns_object(o) && o->oTreasureChestUnkF4 == 5) {
|
||||
if (network_owns_object(o) && o->oTreasureChestCurrentAnswer == 5) {
|
||||
play_puzzle_jingle();
|
||||
o->oAction = 1;
|
||||
o->oTreasureChestSound = 4;
|
||||
|
@ -277,7 +319,7 @@ void bhv_treasure_chest_loop(void) {
|
|||
case 1:
|
||||
if (o->oTimer == 60) {
|
||||
spawn_mist_particles();
|
||||
spawn_default_star(-1900.0f, -4000.0f, -1400.0f);
|
||||
spawn_networked_default_star(-1900.0f, -4000.0f, -1400.0f, o->oTreasureChestLastNetworkPlayerIndex);
|
||||
o->oAction = 2;
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -1369,10 +1369,16 @@ u32 interact_player(struct MarioState* m, UNUSED u32 interactType, struct Object
|
|||
Vec3f velDiff;
|
||||
vec3f_dif(velDiff, m->vel, m2->vel);
|
||||
|
||||
if (vec3f_length(velDiff) < 40) {
|
||||
if (m->action == ACT_SLIDE_KICK_SLIDE || m->action == ACT_SLIDE_KICK) {
|
||||
if (vec3f_length(m->vel) < 15) {
|
||||
return FALSE;
|
||||
}
|
||||
} else {
|
||||
if (vec3f_length(m->vel) < 40) {
|
||||
// the difference vectors are not different enough, do not attack
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
if (vec3f_length(m2->vel) > vec3f_length(m->vel)) {
|
||||
// the one being attacked is going faster, do not attack
|
||||
return FALSE;
|
||||
|
|
|
@ -380,6 +380,11 @@ static bool smlua_is_valid_object_field(struct Object* obj, struct LuaObjectFiel
|
|||
case id_bhvHauntedChair:
|
||||
if (!smlua_field_valid(data, LOT_NONE, offsetof(struct Object, oHauntedChairUnk100))) { return false; }
|
||||
break;
|
||||
case id_bhvHiddenStar:
|
||||
case id_bhvHiddenRedCoinStar:
|
||||
case id_bhvBowserCourseRedCoinStar:
|
||||
if (!smlua_field_valid(data, LOT_NONE, offsetof(struct Object, oHiddenStarLastInteractedObject ))) { return false; }
|
||||
break;
|
||||
case id_bhvBreakableBox:
|
||||
case id_bhvHiddenObject:
|
||||
if (!smlua_field_valid(data, LOT_OBJECT, offsetof(struct Object, oHiddenObjectUnkF4))) { return false; }
|
||||
|
|
|
@ -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 750
|
||||
#define LUA_OBJECT_FIELD_COUNT 751
|
||||
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 },
|
||||
|
@ -999,6 +999,7 @@ static struct LuaObjectField sObjectFields[LUA_OBJECT_FIELD_COUNT] = {
|
|||
{ "oHeldState", LVT_U32, offsetof(struct Object, oHeldState), false, LOT_NONE },
|
||||
{ "oHiddenBlueCoinSwitch", LVT_COBJECT_P, offsetof(struct Object, oHiddenBlueCoinSwitch), false, LOT_OBJECT },
|
||||
{ "oHiddenObjectUnkF4", LVT_COBJECT_P, offsetof(struct Object, oHiddenObjectUnkF4), false, LOT_OBJECT },
|
||||
// { "oHiddenStarLastInteractedObject", LVT_???, offsetof(struct Object, oHiddenStarLastInteractedObject), false, LOT_??? }, <--- UNIMPLEMENTED
|
||||
{ "oHiddenStarTriggerCounter", LVT_S32, offsetof(struct Object, oHiddenStarTriggerCounter), false, LOT_NONE },
|
||||
{ "oHomeX", LVT_F32, offsetof(struct Object, oHomeX), false, LOT_NONE },
|
||||
{ "oHomeY", LVT_F32, offsetof(struct Object, oHomeY), false, LOT_NONE },
|
||||
|
@ -1332,10 +1333,11 @@ static struct LuaObjectField sObjectFields[LUA_OBJECT_FIELD_COUNT] = {
|
|||
{ "oToadMessageState", LVT_S32, offsetof(struct Object, oToadMessageState), false, LOT_NONE },
|
||||
// { "oToxBoxMovementPattern", LVT_???, offsetof(struct Object, oToxBoxMovementPattern), false, LOT_??? }, <--- UNIMPLEMENTED
|
||||
{ "oToxBoxMovementStep", LVT_S32, offsetof(struct Object, oToxBoxMovementStep), false, LOT_NONE },
|
||||
{ "oTreasureChestCurrentAnswer", LVT_S32, offsetof(struct Object, oTreasureChestCurrentAnswer), false, LOT_NONE },
|
||||
{ "oTreasureChestIsAboveWater", LVT_S32, offsetof(struct Object, oTreasureChestIsAboveWater), false, LOT_NONE },
|
||||
{ "oTreasureChestIsLastInteractionIncorrect", LVT_S32, offsetof(struct Object, oTreasureChestIsLastInteractionIncorrect), false, LOT_NONE },
|
||||
{ "oTreasureChestLastNetworkPlayerIndex", LVT_S16, offsetof(struct Object, oTreasureChestLastNetworkPlayerIndex), false, LOT_NONE },
|
||||
{ "oTreasureChestSound", LVT_S32, offsetof(struct Object, oTreasureChestSound), false, LOT_NONE },
|
||||
{ "oTreasureChestUnkF4", LVT_S32, offsetof(struct Object, oTreasureChestUnkF4), false, LOT_NONE },
|
||||
{ "oTreasureChestUnkF8", LVT_S32, offsetof(struct Object, oTreasureChestUnkF8), false, LOT_NONE },
|
||||
{ "oTreasureChestUnkFC", LVT_S32, offsetof(struct Object, oTreasureChestUnkFC), false, LOT_NONE },
|
||||
{ "oTreeSnowOrLeafUnkF4", LVT_S32, offsetof(struct Object, oTreeSnowOrLeafUnkF4), false, LOT_NONE },
|
||||
{ "oTreeSnowOrLeafUnkF8", LVT_S32, offsetof(struct Object, oTreeSnowOrLeafUnkF8), false, LOT_NONE },
|
||||
{ "oTreeSnowOrLeafUnkFC", LVT_S32, offsetof(struct Object, oTreeSnowOrLeafUnkFC), false, LOT_NONE },
|
||||
|
|
|
@ -187,7 +187,7 @@ void network_send_spawn_objects_to(u8 sendToLocalIndex, struct Object* objects[]
|
|||
void network_receive_spawn_objects(struct Packet* p);
|
||||
|
||||
// packet_spawn_star.c
|
||||
void network_send_spawn_star(struct Object* o, u8 starType, f32 x, f32 y, f32 z, u32 behParams);
|
||||
void network_send_spawn_star(struct Object* o, u8 starType, f32 x, f32 y, f32 z, u32 behParams, u8 networkPlayerIndex);
|
||||
void network_receive_spawn_star(struct Packet* p);
|
||||
void network_send_spawn_star_nle(struct Object* o, u32 params);
|
||||
void network_receive_spawn_star_nle(struct Packet* p);
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
extern struct Object* gCurrentObject;
|
||||
|
||||
void network_send_spawn_star(struct Object* o, u8 starType, f32 x, f32 y, f32 z, u32 behParams) {
|
||||
void network_send_spawn_star(struct Object* o, u8 starType, f32 x, f32 y, f32 z, u32 behParams, u8 networkPlayerIndex) {
|
||||
struct Packet p = { 0 };
|
||||
packet_init(&p, PACKET_SPAWN_STAR, true, PLMT_AREA);
|
||||
packet_write(&p, &starType, sizeof(u8));
|
||||
|
@ -15,6 +15,7 @@ void network_send_spawn_star(struct Object* o, u8 starType, f32 x, f32 y, f32 z,
|
|||
packet_write(&p, &y, sizeof(f32));
|
||||
packet_write(&p, &z, sizeof(f32));
|
||||
packet_write(&p, &behParams, sizeof(u32));
|
||||
packet_write(&p, &networkPlayerIndex, sizeof(u8));
|
||||
|
||||
packet_write(&p, &o->oPosX, sizeof(u32) * 3);
|
||||
packet_write(&p, &o->oHomeX, sizeof(u32) * 3);
|
||||
|
@ -26,12 +27,14 @@ void network_receive_spawn_star(struct Packet* p) {
|
|||
u8 starType;
|
||||
f32 x, y, z;
|
||||
u32 behParams;
|
||||
u8 networkPlayerIndex = UNKNOWN_GLOBAL_INDEX;
|
||||
|
||||
packet_read(p, &starType, sizeof(u8));
|
||||
packet_read(p, &x, sizeof(f32));
|
||||
packet_read(p, &y, sizeof(f32));
|
||||
packet_read(p, &z, sizeof(f32));
|
||||
packet_read(p, &behParams, sizeof(u32));
|
||||
packet_read(p, &networkPlayerIndex, sizeof(u8));
|
||||
|
||||
u32 oldBehParams = gCurrentObject->oBehParams;
|
||||
gCurrentObject->oBehParams = behParams;
|
||||
|
@ -47,8 +50,20 @@ 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);
|
||||
|
||||
// Here we check if we're supposed to play the cutscene or not depending on if
|
||||
// the global player index sent matches us.
|
||||
// If the network player index is -1, Then the cutscene will always be skipped.
|
||||
// This check is vital for objects which are network owned specfically.
|
||||
// Leaving this the only way to properly set the cutscene flags
|
||||
// for those who don't own the object.
|
||||
//printf("network_receive_spawn_star: Network Player Index is %i, Our Global Index is %i.\n", networkPlayerIndex, gNetworkPlayers[0].globalIndex);
|
||||
if (networkPlayerIndex == gNetworkPlayers[0].globalIndex) {
|
||||
o->oStarSpawnExtCutsceneFlags = 1;
|
||||
} else {
|
||||
o->oStarSpawnExtCutsceneFlags = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void network_send_spawn_star_nle(struct Object* o, u32 params) {
|
||||
|
|
Loading…
Reference in a new issue