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
|
# Stackdumps
|
||||||
*.stackdump
|
*.stackdump
|
||||||
|
|
||||||
|
# Backup files
|
||||||
|
*.bak
|
||||||
|
|
||||||
# datadump
|
# datadump
|
||||||
/tools/ddump/*
|
/tools/ddump/*
|
||||||
|
|
||||||
|
|
|
@ -1218,10 +1218,11 @@
|
||||||
--- @field public oToadMessageRecentlyTalked integer
|
--- @field public oToadMessageRecentlyTalked integer
|
||||||
--- @field public oToadMessageState integer
|
--- @field public oToadMessageState integer
|
||||||
--- @field public oToxBoxMovementStep 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 oTreasureChestSound integer
|
||||||
--- @field public oTreasureChestUnkF4 integer
|
|
||||||
--- @field public oTreasureChestUnkF8 integer
|
|
||||||
--- @field public oTreasureChestUnkFC integer
|
|
||||||
--- @field public oTreeSnowOrLeafUnkF4 integer
|
--- @field public oTreeSnowOrLeafUnkF4 integer
|
||||||
--- @field public oTreeSnowOrLeafUnkF8 integer
|
--- @field public oTreeSnowOrLeafUnkF8 integer
|
||||||
--- @field public oTreeSnowOrLeafUnkFC integer
|
--- @field public oTreeSnowOrLeafUnkFC integer
|
||||||
|
|
|
@ -1526,10 +1526,11 @@
|
||||||
| oTTCSpinnerDir | `integer` | |
|
| oTTCSpinnerDir | `integer` | |
|
||||||
| oTTCChangeDirTimer | `integer` | |
|
| oTTCChangeDirTimer | `integer` | |
|
||||||
| oBetaTrampolineMarioOnTrampoline | `integer` | |
|
| oBetaTrampolineMarioOnTrampoline | `integer` | |
|
||||||
| oTreasureChestUnkF4 | `integer` | |
|
| oTreasureChestCurrentAnswer | `integer` | |
|
||||||
| oTreasureChestUnkF8 | `integer` | |
|
| oTreasureChestIsLastInteractionIncorrect | `integer` | |
|
||||||
| oTreasureChestUnkFC | `integer` | |
|
| oTreasureChestIsAboveWater | `integer` | |
|
||||||
| oTreasureChestSound | `integer` | |
|
| oTreasureChestSound | `integer` | |
|
||||||
|
| oTreasureChestLastNetworkPlayerIndex | `integer` | |
|
||||||
| oTreeSnowOrLeafUnkF4 | `integer` | |
|
| oTreeSnowOrLeafUnkF4 | `integer` | |
|
||||||
| oTreeSnowOrLeafUnkF8 | `integer` | |
|
| oTreeSnowOrLeafUnkF8 | `integer` | |
|
||||||
| oTreeSnowOrLeafUnkFC | `integer` | |
|
| oTreeSnowOrLeafUnkFC | `integer` | |
|
||||||
|
|
|
@ -928,7 +928,8 @@
|
||||||
|
|
||||||
/* Hidden Star */
|
/* Hidden Star */
|
||||||
// Secrets/Red Coins
|
// Secrets/Red Coins
|
||||||
#define /*0x0F4*/ oHiddenStarTriggerCounter OBJECT_FIELD_S32(0x1B)
|
#define /*0x0F4*/ oHiddenStarTriggerCounter OBJECT_FIELD_S32(0x1B)
|
||||||
|
#define /*0x0F8*/ oHiddenStarLastInteractedObject OBJECT_FIELD_VPTR(0x1D)
|
||||||
|
|
||||||
// Overall very difficult to determine usage, mostly stubbed code.
|
// Overall very difficult to determine usage, mostly stubbed code.
|
||||||
/* Sparkle Spawn Star */
|
/* Sparkle Spawn Star */
|
||||||
|
@ -1037,10 +1038,11 @@
|
||||||
#define /*0x110*/ oBetaTrampolineMarioOnTrampoline OBJECT_FIELD_S32(0x22)
|
#define /*0x110*/ oBetaTrampolineMarioOnTrampoline OBJECT_FIELD_S32(0x22)
|
||||||
|
|
||||||
/* Treasure Chest */
|
/* Treasure Chest */
|
||||||
#define /*0x0F4*/ oTreasureChestUnkF4 OBJECT_FIELD_S32(0x1B)
|
#define /*0x0F4*/ oTreasureChestCurrentAnswer OBJECT_FIELD_S32(0x1B)
|
||||||
#define /*0x0F8*/ oTreasureChestUnkF8 OBJECT_FIELD_S32(0x1C)
|
#define /*0x0F8*/ oTreasureChestIsLastInteractionIncorrect OBJECT_FIELD_S32(0x1C)
|
||||||
#define /*0x0FC*/ oTreasureChestUnkFC OBJECT_FIELD_S32(0x1D)
|
#define /*0x0FC*/ oTreasureChestIsAboveWater OBJECT_FIELD_S32(0x1D)
|
||||||
#define /*0x100*/ oTreasureChestSound OBJECT_FIELD_S32(0x1E)
|
#define /*0x100*/ oTreasureChestSound OBJECT_FIELD_S32(0x1E)
|
||||||
|
#define /*0x104*/ oTreasureChestLastNetworkPlayerIndex OBJECT_FIELD_S16(0x21, 0)
|
||||||
|
|
||||||
/* Tree Snow Or Leaf */
|
/* Tree Snow Or Leaf */
|
||||||
#define /*0x0F4*/ oTreeSnowOrLeafUnkF4 OBJECT_FIELD_S32(0x1B)
|
#define /*0x0F4*/ oTreeSnowOrLeafUnkF4 OBJECT_FIELD_S32(0x1B)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
-- name: Mario RUN!
|
-- name: Mario RUN!
|
||||||
-- description: Mario Is contantly runing
|
-- description: Mario is constantly running.
|
||||||
|
|
||||||
Threshold = 50 --set Threshold to 50
|
Threshold = 50 --set Threshold to 50
|
||||||
|
|
||||||
|
|
|
@ -97,7 +97,7 @@ static void homing_amp_appear_loop(void) {
|
||||||
*/
|
*/
|
||||||
static void homing_amp_chase_loop(void) {
|
static void homing_amp_chase_loop(void) {
|
||||||
struct Object* player = nearest_player_to_object(o);
|
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
|
// Lock on to Mario if he ever goes within 11.25 degrees of the amp's line of sight
|
||||||
if ((angleToPlayer - 0x400 < o->oMoveAngleYaw)
|
if ((angleToPlayer - 0x400 < o->oMoveAngleYaw)
|
||||||
|
@ -199,15 +199,17 @@ static void amp_attack_cooldown_loop(void) {
|
||||||
*/
|
*/
|
||||||
void bhv_homing_amp_loop(void) {
|
void bhv_homing_amp_loop(void) {
|
||||||
if (!network_sync_object_initialized(o)) {
|
if (!network_sync_object_initialized(o)) {
|
||||||
network_init_object(o, 4000.0f);
|
struct SyncObject *so = network_init_object(o, 4000.0f);
|
||||||
network_init_object_field(o, &o->oAmpYPhase);
|
if (so) {
|
||||||
network_init_object_field(o, &o->oAnimState);
|
network_init_object_field(o, &o->oAmpYPhase);
|
||||||
network_init_object_field(o, &o->oFaceAnglePitch);
|
network_init_object_field(o, &o->oAnimState);
|
||||||
network_init_object_field(o, &o->oFaceAngleYaw);
|
network_init_object_field(o, &o->oFaceAnglePitch);
|
||||||
network_init_object_field(o, &o->oForwardVel);
|
network_init_object_field(o, &o->oFaceAngleYaw);
|
||||||
network_init_object_field(o, &o->oFriction);
|
network_init_object_field(o, &o->oForwardVel);
|
||||||
network_init_object_field(o, &o->oHomingAmpAvgY);
|
network_init_object_field(o, &o->oFriction);
|
||||||
network_init_object_field(o, &o->oHomingAmpLockedOn);
|
network_init_object_field(o, &o->oHomingAmpAvgY);
|
||||||
|
network_init_object_field(o, &o->oHomingAmpLockedOn);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (o->oAction) {
|
switch (o->oAction) {
|
||||||
|
@ -342,13 +344,15 @@ static void circling_amp_idle_loop(void) {
|
||||||
*/
|
*/
|
||||||
void bhv_circling_amp_loop(void) {
|
void bhv_circling_amp_loop(void) {
|
||||||
if (!network_sync_object_initialized(o)) {
|
if (!network_sync_object_initialized(o)) {
|
||||||
network_init_object(o, 4000.0f);
|
struct SyncObject *so = network_init_object(o, 4000.0f);
|
||||||
network_init_object_field(o, &o->oAmpYPhase);
|
if (so) {
|
||||||
network_init_object_field(o, &o->oAnimState);
|
network_init_object_field(o, &o->oAmpYPhase);
|
||||||
network_init_object_field(o, &o->oFaceAnglePitch);
|
network_init_object_field(o, &o->oAnimState);
|
||||||
network_init_object_field(o, &o->oFaceAngleYaw);
|
network_init_object_field(o, &o->oFaceAnglePitch);
|
||||||
network_init_object_field(o, &o->oForwardVel);
|
network_init_object_field(o, &o->oFaceAngleYaw);
|
||||||
network_init_object_field(o, &o->oFriction);
|
network_init_object_field(o, &o->oForwardVel);
|
||||||
|
network_init_object_field(o, &o->oFriction);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (o->oAction) {
|
switch (o->oAction) {
|
||||||
|
|
|
@ -60,10 +60,12 @@ static s8 arrow_lift_move_back(void) {
|
||||||
*/
|
*/
|
||||||
void bhv_arrow_lift_loop(void) {
|
void bhv_arrow_lift_loop(void) {
|
||||||
if (!network_sync_object_initialized(o)) {
|
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);
|
||||||
network_init_object_field(o, &o->oTimer);
|
if (so) {
|
||||||
network_init_object_field(o, &o->oPrevAction);
|
network_init_object_field(o, &o->oTimer);
|
||||||
network_init_object_field(o, &o->oAction);
|
network_init_object_field(o, &o->oPrevAction);
|
||||||
|
network_init_object_field(o, &o->oAction);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (o->oAction) {
|
switch (o->oAction) {
|
||||||
|
|
|
@ -21,14 +21,13 @@ static void handle_merry_go_round_music(void) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Get Mario's floor and floor surface type
|
// Get Mario's floor and floor surface type
|
||||||
struct Surface *marioFloor;
|
struct Surface *marioFloor = NULL;
|
||||||
u16 marioFloorType;
|
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) {
|
if (marioFloor != NULL) {
|
||||||
marioFloorType = 0;
|
|
||||||
} else {
|
|
||||||
marioFloorType = marioFloor->type;
|
marioFloorType = marioFloor->type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ static u8 boo_ignore_update(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SyncObject* boo_network_init_object(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; }
|
if (so == NULL) { return NULL; }
|
||||||
so->ignore_if_true = boo_ignore_update;
|
so->ignore_if_true = boo_ignore_update;
|
||||||
network_init_object_field(o, &o->oBooBaseScale);
|
network_init_object_field(o, &o->oBooBaseScale);
|
||||||
|
|
|
@ -48,8 +48,8 @@ void bub_act_0(void) {
|
||||||
|
|
||||||
void bub_act_1(void) {
|
void bub_act_1(void) {
|
||||||
struct Object* player = nearest_player_to_object(o);
|
struct Object* player = nearest_player_to_object(o);
|
||||||
int distanceToPlayer = dist_between_objects(o, player);
|
s32 distanceToPlayer = dist_between_objects(o, player);
|
||||||
int angleToPlayer = obj_angle_to_object(o, player);
|
s32 angleToPlayer = obj_angle_to_object(o, player);
|
||||||
f32 dy;
|
f32 dy;
|
||||||
if (o->oTimer == 0) {
|
if (o->oTimer == 0) {
|
||||||
o->oForwardVel = random_float() * 2 + 2;
|
o->oForwardVel = random_float() * 2 + 2;
|
||||||
|
@ -80,8 +80,8 @@ void bub_act_1(void) {
|
||||||
|
|
||||||
void bub_act_2(void) {
|
void bub_act_2(void) {
|
||||||
struct Object* player = nearest_player_to_object(o);
|
struct Object* player = nearest_player_to_object(o);
|
||||||
int distanceToPlayer = dist_between_objects(o, player);
|
s32 distanceToPlayer = dist_between_objects(o, player);
|
||||||
int angleToPlayer = obj_angle_to_object(o, player);
|
s32 angleToPlayer = obj_angle_to_object(o, player);
|
||||||
f32 dy;
|
f32 dy;
|
||||||
if (o->oTimer < 20) {
|
if (o->oTimer < 20) {
|
||||||
if (o->oInteractStatus & INT_STATUS_INTERACTED)
|
if (o->oInteractStatus & INT_STATUS_INTERACTED)
|
||||||
|
@ -116,12 +116,14 @@ void (*sCheepCheepActions[])(void) = { bub_act_0, bub_act_1, bub_act_2 };
|
||||||
|
|
||||||
void bhv_bub_loop(void) {
|
void bhv_bub_loop(void) {
|
||||||
if (!network_sync_object_initialized(o)) {
|
if (!network_sync_object_initialized(o)) {
|
||||||
network_init_object(o, 4000.0f);
|
struct SyncObject *so = network_init_object(o, 4000.0f);
|
||||||
network_init_object_field(o, &o->oCheepCheepUnkF4);
|
if (so) {
|
||||||
network_init_object_field(o, &o->oCheepCheepUnkF8);
|
network_init_object_field(o, &o->oCheepCheepUnkF4);
|
||||||
network_init_object_field(o, &o->oCheepCheepUnkFC);
|
network_init_object_field(o, &o->oCheepCheepUnkF8);
|
||||||
network_init_object_field(o, &o->oCheepCheepUnk104);
|
network_init_object_field(o, &o->oCheepCheepUnkFC);
|
||||||
network_init_object_field(o, &o->oCheepCheepUnk108);
|
network_init_object_field(o, &o->oCheepCheepUnk104);
|
||||||
|
network_init_object_field(o, &o->oCheepCheepUnk108);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Object* player = nearest_player_to_object(o);
|
struct Object* player = nearest_player_to_object(o);
|
||||||
|
|
|
@ -38,20 +38,22 @@ void bhv_camera_lakitu_init(void) {
|
||||||
spawn_object_relative_with_scale(CLOUD_BP_LAKITU_CLOUD, 0, 0, 0, 2.0f, o, MODEL_MIST, bhvCloud);
|
spawn_object_relative_with_scale(CLOUD_BP_LAKITU_CLOUD, 0, 0, 0, 2.0f, o, MODEL_MIST, bhvCloud);
|
||||||
}
|
}
|
||||||
lakituTargetLocalIndex = UNKNOWN_LOCAL_INDEX;
|
lakituTargetLocalIndex = UNKNOWN_LOCAL_INDEX;
|
||||||
|
|
||||||
struct SyncObject* so = network_init_object(o, 4000.0f);
|
if (!network_sync_object_initialized(o)) {
|
||||||
if (so) {
|
struct SyncObject *so = network_init_object(o, 4000.0f);
|
||||||
so->ignore_if_true = bhv_camera_lakitu_ignore_if_true;
|
if (so) {
|
||||||
so->override_ownership = bhv_camera_lakitu_override_ownership;
|
so->ignore_if_true = bhv_camera_lakitu_ignore_if_true;
|
||||||
so->on_received_post = bhv_camera_lakitu_on_received_post;
|
so->override_ownership = bhv_camera_lakitu_override_ownership;
|
||||||
network_init_object_field(o, &o->oAngleVelPitch);
|
so->on_received_post = bhv_camera_lakitu_on_received_post;
|
||||||
network_init_object_field(o, &o->oFaceAnglePitch);
|
network_init_object_field(o, &o->oAngleVelPitch);
|
||||||
network_init_object_field(o, &o->oCameraLakituBlinkTimer);
|
network_init_object_field(o, &o->oFaceAnglePitch);
|
||||||
network_init_object_field(o, &o->oCameraLakituSpeed);
|
network_init_object_field(o, &o->oCameraLakituBlinkTimer);
|
||||||
network_init_object_field(o, &o->oCameraLakituCircleRadius);
|
network_init_object_field(o, &o->oCameraLakituSpeed);
|
||||||
network_init_object_field(o, &o->oCameraLakituFinishedDialog);
|
network_init_object_field(o, &o->oCameraLakituCircleRadius);
|
||||||
network_init_object_field(o, &o->oCameraLakituUnk104);
|
network_init_object_field(o, &o->oCameraLakituFinishedDialog);
|
||||||
network_init_object_field(o, &o->oCameraLakituPitchVel);
|
network_init_object_field(o, &o->oCameraLakituUnk104);
|
||||||
|
network_init_object_field(o, &o->oCameraLakituPitchVel);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,8 +114,8 @@ static void camera_lakitu_intro_act_show_dialog(void) {
|
||||||
marioState = &gMarioStates[lakituTargetLocalIndex];
|
marioState = &gMarioStates[lakituTargetLocalIndex];
|
||||||
}
|
}
|
||||||
struct Object* player = marioState->marioObj;
|
struct Object* player = marioState->marioObj;
|
||||||
int distanceToPlayer = dist_between_objects(o, player);
|
s32 distanceToPlayer = dist_between_objects(o, player);
|
||||||
int angleToPlayer = obj_angle_to_object(o, player);
|
s32 angleToPlayer = obj_angle_to_object(o, player);
|
||||||
|
|
||||||
s16 targetMovePitch = 0;
|
s16 targetMovePitch = 0;
|
||||||
s16 targetMoveYaw = 0;
|
s16 targetMoveYaw = 0;
|
||||||
|
|
|
@ -19,7 +19,7 @@ void opened_cannon_act_0(void) {
|
||||||
cur_obj_enable_rendering();
|
cur_obj_enable_rendering();
|
||||||
|
|
||||||
struct Object* player = nearest_player_to_object(o);
|
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) {
|
if (distanceToPlayer < 500.0f) {
|
||||||
//cur_obj_become_tangible();
|
//cur_obj_become_tangible();
|
||||||
|
|
|
@ -28,8 +28,13 @@ static struct ObjectHitbox sChainChompHitbox = {
|
||||||
* Update function for chain chomp part / pivot.
|
* Update function for chain chomp part / pivot.
|
||||||
*/
|
*/
|
||||||
void bhv_chain_chomp_chain_part_update(void) {
|
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);
|
obj_mark_for_deletion(o);
|
||||||
|
network_send_object(o);
|
||||||
} else if (o->oBehParams2ndByte != CHAIN_CHOMP_CHAIN_PART_BP_PIVOT) {
|
} else if (o->oBehParams2ndByte != CHAIN_CHOMP_CHAIN_PART_BP_PIVOT) {
|
||||||
struct ChainSegment *segment = &o->parentObj->oChainChompSegments[o->oBehParams2ndByte];
|
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.
|
* When mario gets close enough, allocate chain segments and spawn their objects.
|
||||||
*/
|
*/
|
||||||
static void chain_chomp_act_uninitialized(void) {
|
static void chain_chomp_act_uninitialized(void) {
|
||||||
struct ChainSegment *segments;
|
struct ChainSegment *segments = mem_pool_alloc(gObjectMemoryPool, 5 * sizeof(struct ChainSegment));
|
||||||
s32 i;
|
|
||||||
|
|
||||||
segments = mem_pool_alloc(gObjectMemoryPool, 5 * sizeof(struct ChainSegment));
|
|
||||||
if (segments != NULL) {
|
if (segments != NULL) {
|
||||||
// Each segment represents the offset of a chain part to the pivot.
|
// Each segment represents the offset of a chain part to the pivot.
|
||||||
// Segment 0 connects the pivot to the chain chomp itself. Segment
|
// Segment 0 connects the pivot to the chain chomp itself. Segment
|
||||||
// 1 connects the pivot to the chain part next to the chain chomp
|
// 1 connects the pivot to the chain part next to the chain chomp
|
||||||
// (chain part 1), etc.
|
// (chain part 1), etc.
|
||||||
o->oChainChompSegments = segments;
|
o->oChainChompSegments = segments;
|
||||||
for (i = 0; i <= 4; i++) {
|
for (s32 i = 0; i <= 4; i++) {
|
||||||
chain_segment_init(&segments[i]);
|
chain_segment_init(&segments[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,7 +71,7 @@ static void chain_chomp_act_uninitialized(void) {
|
||||||
!= NULL) {
|
!= NULL) {
|
||||||
// Spawn the non-pivot chain parts, starting from the chain
|
// Spawn the non-pivot chain parts, starting from the chain
|
||||||
// chomp and moving toward the pivot
|
// 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);
|
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.
|
* part as well as from the pivot.
|
||||||
*/
|
*/
|
||||||
static void chain_chomp_update_chain_segments(void) {
|
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 segmentVelY;
|
||||||
f32 maxTotalOffset;
|
|
||||||
s32 i;
|
|
||||||
|
|
||||||
if (o->oVelY < 0.0f) {
|
if (o->oVelY < 0.0f) {
|
||||||
segmentVelY = o->oVelY;
|
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
|
// 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).
|
// connects the pivot to chain part i (1 is closest to the chain chomp).
|
||||||
|
|
||||||
for (i = 1; i <= 4; i++) {
|
for (s32 i = 1; i <= 4; i++) {
|
||||||
prevSegment = &o->oChainChompSegments[i - 1];
|
struct ChainSegment *prevSegment = &o->oChainChompSegments[i - 1];
|
||||||
segment = &o->oChainChompSegments[i];
|
struct ChainSegment *segment = &o->oChainChompSegments[i];
|
||||||
|
|
||||||
// Apply gravity
|
// 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
|
// Cap distance to previous chain part (so that the tail follows the
|
||||||
// chomp)
|
// chomp)
|
||||||
|
|
||||||
offsetX = segment->posX - prevSegment->posX;
|
f32 offsetX = segment->posX - prevSegment->posX;
|
||||||
offsetY = segment->posY - prevSegment->posY;
|
f32 offsetY = segment->posY - prevSegment->posY;
|
||||||
offsetZ = segment->posZ - prevSegment->posZ;
|
f32 offsetZ = segment->posZ - prevSegment->posZ;
|
||||||
offset = sqrtf(offsetX * offsetX + offsetY * offsetY + offsetZ * offsetZ);
|
f32 offset = sqrtf(offsetX * offsetX + offsetY * offsetY + offsetZ * offsetZ);
|
||||||
|
|
||||||
if (offset > o->oChainChompMaxDistBetweenChainParts) {
|
if (offset > o->oChainChompMaxDistBetweenChainParts) {
|
||||||
offset = o->oChainChompMaxDistBetweenChainParts / offset;
|
offset = o->oChainChompMaxDistBetweenChainParts / offset;
|
||||||
|
@ -136,7 +130,7 @@ static void chain_chomp_update_chain_segments(void) {
|
||||||
offsetZ += prevSegment->posZ;
|
offsetZ += prevSegment->posZ;
|
||||||
offset = sqrtf(offsetX * offsetX + offsetY * offsetY + offsetZ * offsetZ);
|
offset = sqrtf(offsetX * offsetX + offsetY * offsetY + offsetZ * offsetZ);
|
||||||
|
|
||||||
maxTotalOffset = o->oChainChompMaxDistFromPivotPerChainPart * (5 - i);
|
f32 maxTotalOffset = o->oChainChompMaxDistFromPivotPerChainPart * (5 - i);
|
||||||
if (offset > maxTotalOffset) {
|
if (offset > maxTotalOffset) {
|
||||||
offset = maxTotalOffset / offset;
|
offset = maxTotalOffset / offset;
|
||||||
offsetX *= offset;
|
offsetX *= offset;
|
||||||
|
@ -168,9 +162,9 @@ static void chain_chomp_sub_act_turn(void) {
|
||||||
chain_chomp_restore_normal_chain_lengths();
|
chain_chomp_restore_normal_chain_lengths();
|
||||||
obj_move_pitch_approach(0, 0x100);
|
obj_move_pitch_approach(0, 0x100);
|
||||||
|
|
||||||
struct Object* player = nearest_player_to_object(o);
|
struct Object *player = nearest_player_to_object(o);
|
||||||
int distanceToPlayer = dist_between_objects(o, player);
|
s32 distanceToPlayer = dist_between_objects(o, player);
|
||||||
int angleToPlayer = obj_angle_to_object(o, player);
|
s32 angleToPlayer = obj_angle_to_object(o, player);
|
||||||
|
|
||||||
if (o->oMoveFlags & OBJ_MOVE_MASK_ON_GROUND) {
|
if (o->oMoveFlags & OBJ_MOVE_MASK_ON_GROUND) {
|
||||||
cur_obj_rotate_yaw_toward(angleToPlayer, 0x400);
|
cur_obj_rotate_yaw_toward(angleToPlayer, 0x400);
|
||||||
|
@ -343,8 +337,6 @@ static void chain_chomp_released_end_cutscene(void) {
|
||||||
* released.
|
* released.
|
||||||
*/
|
*/
|
||||||
static void chain_chomp_act_move(void) {
|
static void chain_chomp_act_move(void) {
|
||||||
f32 maxDistToPivot;
|
|
||||||
|
|
||||||
// Unload chain if mario is far enough
|
// Unload chain if mario is far enough
|
||||||
cur_obj_update_floor_and_walls();
|
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);
|
+ o->oChainChompSegments[0].posZ * o->oChainChompSegments[0].posZ);
|
||||||
|
|
||||||
// If the chain is fully stretched
|
// If the chain is fully stretched
|
||||||
maxDistToPivot = o->oChainChompMaxDistFromPivotPerChainPart * 5;
|
f32 maxDistToPivot = o->oChainChompMaxDistFromPivotPerChainPart * 5;
|
||||||
if (o->oChainChompDistToPivot > maxDistToPivot) {
|
if (o->oChainChompDistToPivot > maxDistToPivot) {
|
||||||
f32 ratio = maxDistToPivot / o->oChainChompDistToPivot;
|
f32 ratio = maxDistToPivot / o->oChainChompDistToPivot;
|
||||||
o->oChainChompDistToPivot = maxDistToPivot;
|
o->oChainChompDistToPivot = maxDistToPivot;
|
||||||
|
@ -524,9 +516,9 @@ void bhv_wooden_post_update(void) {
|
||||||
if (o->oWoodenPostOffsetY != 0.0f) {
|
if (o->oWoodenPostOffsetY != 0.0f) {
|
||||||
o->oPosY = o->oHomeY + o->oWoodenPostOffsetY;
|
o->oPosY = o->oHomeY + o->oWoodenPostOffsetY;
|
||||||
} else if (!(o->oBehParams & WOODEN_POST_BP_NO_COINS_MASK)) {
|
} else if (!(o->oBehParams & WOODEN_POST_BP_NO_COINS_MASK)) {
|
||||||
struct Object* player = nearest_player_to_object(o);
|
struct Object *player = nearest_player_to_object(o);
|
||||||
int distanceToPlayer = dist_between_objects(o, player);
|
s32 distanceToPlayer = dist_between_objects(o, player);
|
||||||
int angleToPlayer = obj_angle_to_object(o, player);
|
s32 angleToPlayer = obj_angle_to_object(o, player);
|
||||||
|
|
||||||
// Reset the timer once mario is far enough
|
// Reset the timer once mario is far enough
|
||||||
if (distanceToPlayer > 400.0f) {
|
if (distanceToPlayer > 400.0f) {
|
||||||
|
@ -536,9 +528,9 @@ void bhv_wooden_post_update(void) {
|
||||||
// coins
|
// coins
|
||||||
o->oWoodenPostTotalMarioAngle += (s16)(angleToPlayer - o->oWoodenPostPrevAngleToMario);
|
o->oWoodenPostTotalMarioAngle += (s16)(angleToPlayer - o->oWoodenPostPrevAngleToMario);
|
||||||
if (absi(o->oWoodenPostTotalMarioAngle) > 0x30000 && o->oTimer < 200) {
|
if (absi(o->oWoodenPostTotalMarioAngle) > 0x30000 && o->oTimer < 200) {
|
||||||
network_send_object(o);
|
|
||||||
obj_spawn_loot_yellow_coins(o, 5, 20.0f);
|
obj_spawn_loot_yellow_coins(o, 5, 20.0f);
|
||||||
set_object_respawn_info_bits(o, 1);
|
set_object_respawn_info_bits(o, 1);
|
||||||
|
network_send_object(o);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,31 +1,55 @@
|
||||||
// hidden_star.c.inc
|
// hidden_star.c.inc
|
||||||
|
|
||||||
void bhv_hidden_star_init(void) {
|
void bhv_hidden_star_init(void) {
|
||||||
s16 sp36;
|
s16 count = count_objects_with_behavior(bhvHiddenStarTrigger);
|
||||||
struct Object *sp30;
|
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);
|
||||||
sp36 = count_objects_with_behavior(bhvHiddenStarTrigger);
|
if (obj != NULL) { obj->oBehParams = o->oBehParams; }
|
||||||
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; }
|
|
||||||
o->activeFlags = ACTIVE_FLAG_DEACTIVATED;
|
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) {
|
void bhv_hidden_star_loop(void) {
|
||||||
switch (o->oAction) {
|
switch (o->oAction) {
|
||||||
case 0:
|
case 0:
|
||||||
if (o->oHiddenStarTriggerCounter == 5)
|
if (o->oHiddenStarTriggerCounter == 5) {
|
||||||
o->oAction = 1;
|
o->oAction = 1;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
if (o->oTimer > 2) {
|
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);
|
||||||
spawn_mist_particles();
|
if (obj != NULL) {
|
||||||
|
if (o->oHiddenStarLastInteractedObject == &gMarioStates[0]) {
|
||||||
|
obj->oStarSpawnExtCutsceneFlags = 1;
|
||||||
|
} else {
|
||||||
|
obj->oStarSpawnExtCutsceneFlags = 0;
|
||||||
|
}
|
||||||
|
spawn_mist_particles();
|
||||||
|
}
|
||||||
o->activeFlags = ACTIVE_FLAG_DEACTIVATED;
|
o->activeFlags = ACTIVE_FLAG_DEACTIVATED;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -34,14 +58,20 @@ void bhv_hidden_star_loop(void) {
|
||||||
|
|
||||||
/* TODO: this is likely not a checkpoint but a Secret */
|
/* TODO: this is likely not a checkpoint but a Secret */
|
||||||
void bhv_hidden_star_trigger_loop(void) {
|
void bhv_hidden_star_trigger_loop(void) {
|
||||||
struct Object *hiddenStar;
|
if ((o->oInteractStatus & INT_STATUS_INTERACTED) || obj_check_if_collided_with_object(o, gMarioObjects[0]) == 1) {
|
||||||
if ((o->oInteractStatus & INT_STATUS_INTERACTED) || obj_check_if_collided_with_object(o, gMarioObject) == 1) {
|
struct Object *hiddenStar = cur_obj_nearest_object_with_behavior(bhvHiddenStar);
|
||||||
hiddenStar = cur_obj_nearest_object_with_behavior(bhvHiddenStar);
|
|
||||||
if (hiddenStar != NULL) {
|
if (hiddenStar != NULL) {
|
||||||
hiddenStar->oHiddenStarTriggerCounter++;
|
hiddenStar->oHiddenStarTriggerCounter++;
|
||||||
if (hiddenStar->oHiddenStarTriggerCounter != 5) {
|
if (hiddenStar->oHiddenStarTriggerCounter != 5) {
|
||||||
spawn_orange_number(hiddenStar->oHiddenStarTriggerCounter, 0, 0, 0);
|
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
|
#ifdef VERSION_JP
|
||||||
play_sound(SOUND_MENU_STAR_SOUND, gGlobalSoundSource);
|
play_sound(SOUND_MENU_STAR_SOUND, gGlobalSoundSource);
|
||||||
|
@ -63,14 +93,22 @@ void bhv_bowser_course_red_coin_star_loop(void) {
|
||||||
gRedCoinsCollected = o->oHiddenStarTriggerCounter;
|
gRedCoinsCollected = o->oHiddenStarTriggerCounter;
|
||||||
switch (o->oAction) {
|
switch (o->oAction) {
|
||||||
case 0:
|
case 0:
|
||||||
if (o->oHiddenStarTriggerCounter == 8)
|
if (o->oHiddenStarTriggerCounter == 8) {
|
||||||
o->oAction = 1;
|
o->oAction = 1;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
if (o->oTimer > 2) {
|
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);
|
||||||
spawn_mist_particles();
|
if (obj != NULL) {
|
||||||
|
if (o->oHiddenStarLastInteractedObject == &gMarioStates[0]) {
|
||||||
|
obj->oStarSpawnExtCutsceneFlags = 1;
|
||||||
|
} else {
|
||||||
|
obj->oStarSpawnExtCutsceneFlags = 0;
|
||||||
|
}
|
||||||
|
spawn_mist_particles();
|
||||||
|
}
|
||||||
o->activeFlags = ACTIVE_FLAG_DEACTIVATED;
|
o->activeFlags = ACTIVE_FLAG_DEACTIVATED;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -23,23 +23,18 @@ static struct ObjectHitbox sRedCoinHitbox = {
|
||||||
* Red coin initialization function. Sets the coin's hitbox and parent object.
|
* Red coin initialization function. Sets the coin's hitbox and parent object.
|
||||||
*/
|
*/
|
||||||
void bhv_red_coin_init(void) {
|
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.
|
// Set the red coins to have a parent of the closest red coin star.
|
||||||
hiddenRedCoinStar = cur_obj_nearest_object_with_behavior(bhvHiddenRedCoinStar);
|
struct Object *hiddenRedCoinStar = cur_obj_nearest_object_with_behavior(bhvHiddenRedCoinStar);
|
||||||
if (hiddenRedCoinStar != NULL)
|
// If it's not a typical red coin star, it's a Bowser one.
|
||||||
o->parentObj = hiddenRedCoinStar;
|
if (hiddenRedCoinStar == NULL) {
|
||||||
else {
|
|
||||||
hiddenRedCoinStar = cur_obj_nearest_object_with_behavior(bhvBowserCourseRedCoinStar);
|
hiddenRedCoinStar = cur_obj_nearest_object_with_behavior(bhvBowserCourseRedCoinStar);
|
||||||
if (hiddenRedCoinStar != NULL) {
|
}
|
||||||
o->parentObj = hiddenRedCoinStar;
|
|
||||||
} else {
|
// If we found a red coin star, It's our parent.
|
||||||
o->parentObj = NULL;
|
if (hiddenRedCoinStar != NULL) {
|
||||||
}
|
o->parentObj = hiddenRedCoinStar;
|
||||||
|
} else {
|
||||||
|
o->parentObj = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
obj_set_hitbox(o, &sRedCoinHitbox);
|
obj_set_hitbox(o, &sRedCoinHitbox);
|
||||||
|
@ -56,6 +51,13 @@ void bhv_red_coin_loop(void) {
|
||||||
if (o->parentObj != NULL) {
|
if (o->parentObj != NULL) {
|
||||||
// ...increment the star's counter.
|
// ...increment the star's counter.
|
||||||
o->parentObj->oHiddenStarTriggerCounter++;
|
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.
|
// For JP version, play an identical sound for all coins.
|
||||||
#ifdef VERSION_JP
|
#ifdef VERSION_JP
|
||||||
|
|
|
@ -7,14 +7,18 @@
|
||||||
// a rolling log of another variation.
|
// a rolling log of another variation.
|
||||||
|
|
||||||
static void bhv_rolling_log_network_init(void) {
|
static void bhv_rolling_log_network_init(void) {
|
||||||
network_init_object(o, 4000.0f);
|
if (!network_sync_object_initialized(o)) {
|
||||||
network_init_object_field(o, &o->oAngleVelPitch);
|
struct SyncObject *so = network_init_object(o, 4000.0f);
|
||||||
network_init_object_field(o, &o->oFaceAnglePitch);
|
if (so) {
|
||||||
network_init_object_field(o, &o->oMoveAnglePitch);
|
network_init_object_field(o, &o->oAngleVelPitch);
|
||||||
network_init_object_field(o, &o->oPitouneUnkF4);
|
network_init_object_field(o, &o->oFaceAnglePitch);
|
||||||
network_init_object_field(o, &o->oPitouneUnkF8);
|
network_init_object_field(o, &o->oMoveAnglePitch);
|
||||||
network_init_object_field(o, &o->oPitouneUnkFC);
|
network_init_object_field(o, &o->oPitouneUnkF4);
|
||||||
network_init_object_field(o, &o->oForwardVel);
|
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) {
|
void bhv_ttm_rolling_log_init(void) {
|
||||||
|
@ -143,10 +147,12 @@ void volcano_act_3(void) {
|
||||||
|
|
||||||
void bhv_volcano_trap_loop(void) {
|
void bhv_volcano_trap_loop(void) {
|
||||||
if (!network_sync_object_initialized(o)) {
|
if (!network_sync_object_initialized(o)) {
|
||||||
network_init_object(o, 2000.0f);
|
struct SyncObject *so = network_init_object(o, 2000.0f);
|
||||||
network_init_object_field(o, &o->oRollingLogUnkF4);
|
if (so) {
|
||||||
network_init_object_field(o, &o->oAngleVelPitch);
|
network_init_object_field(o, &o->oRollingLogUnkF4);
|
||||||
network_init_object_field(o, &o->oFaceAnglePitch);
|
network_init_object_field(o, &o->oAngleVelPitch);
|
||||||
|
network_init_object_field(o, &o->oFaceAnglePitch);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (o->oAction) {
|
switch (o->oAction) {
|
||||||
|
|
|
@ -25,21 +25,21 @@ s32 update_angle_from_move_flags(s32 *angle) {
|
||||||
|
|
||||||
void bhv_scuttlebug_loop(void) {
|
void bhv_scuttlebug_loop(void) {
|
||||||
if (!network_sync_object_initialized(o)) {
|
if (!network_sync_object_initialized(o)) {
|
||||||
network_init_object(o, 4000.0f);
|
struct SyncObject *so = network_init_object(o, 4000.0f);
|
||||||
network_init_object_field(o, &o->oFlags);
|
if (so) {
|
||||||
network_init_object_field(o, &o->oForwardVel);
|
network_init_object_field(o, &o->oFlags);
|
||||||
network_init_object_field(o, &o->oHomeX);
|
network_init_object_field(o, &o->oForwardVel);
|
||||||
network_init_object_field(o, &o->oHomeY);
|
network_init_object_field(o, &o->oHomeX);
|
||||||
network_init_object_field(o, &o->oHomeZ);
|
network_init_object_field(o, &o->oHomeY);
|
||||||
network_init_object_field(o, &o->oInteractStatus);
|
network_init_object_field(o, &o->oHomeZ);
|
||||||
network_init_object_field(o, &o->oScuttlebugUnkF4);
|
network_init_object_field(o, &o->oInteractStatus);
|
||||||
|
network_init_object_field(o, &o->oScuttlebugUnkF4);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Object* player = nearest_player_to_object(o);
|
struct Object *player = nearest_player_to_object(o);
|
||||||
int angleToPlayer = obj_angle_to_object(o, player);
|
s32 angleToPlayer = obj_angle_to_object(o, player);
|
||||||
|
|
||||||
UNUSED s32 unused;
|
|
||||||
f32 sp18;
|
|
||||||
cur_obj_update_floor_and_walls();
|
cur_obj_update_floor_and_walls();
|
||||||
if (o->oSubAction != 0
|
if (o->oSubAction != 0
|
||||||
&& cur_obj_set_hitbox_and_die_if_attacked(&sScuttlebugHitbox, SOUND_OBJ_DYING_ENEMY1,
|
&& 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;
|
o->oSubAction = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (o->oForwardVel < 10.0f)
|
f32 sp18;
|
||||||
|
if (o->oForwardVel < 10.0f) {
|
||||||
sp18 = 1.0f;
|
sp18 = 1.0f;
|
||||||
else
|
} else {
|
||||||
sp18 = 3.0f;
|
sp18 = 3.0f;
|
||||||
|
}
|
||||||
cur_obj_init_animation_with_accel_and_sound(0, sp18);
|
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);
|
set_obj_anim_with_accel_and_sound(1, 23, SOUND_OBJ2_SCUTTLEBUG_WALK);
|
||||||
|
}
|
||||||
if (o->parentObj != o) {
|
if (o->parentObj != o) {
|
||||||
if (obj_is_hidden(o))
|
if (obj_is_hidden(o))
|
||||||
obj_mark_for_deletion(o);
|
obj_mark_for_deletion(o);
|
||||||
|
@ -134,31 +137,32 @@ void bhv_scuttlebug_loop(void) {
|
||||||
|
|
||||||
void bhv_scuttlebug_spawn_loop(void) {
|
void bhv_scuttlebug_spawn_loop(void) {
|
||||||
if (!network_sync_object_initialized(o)) {
|
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);
|
||||||
network_init_object_field(o, &o->oAction);
|
if (so) {
|
||||||
network_init_object_field(o, &o->oTimer);
|
network_init_object_field(o, &o->oAction);
|
||||||
network_init_object_field(o, &o->oScuttlebugSpawnerUnkF4);
|
network_init_object_field(o, &o->oTimer);
|
||||||
network_init_object_field(o, &o->oScuttlebugSpawnerUnk88);
|
network_init_object_field(o, &o->oScuttlebugSpawnerUnkF4);
|
||||||
|
network_init_object_field(o, &o->oScuttlebugSpawnerUnk88);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct MarioState* marioState = nearest_mario_state_to_object(o);
|
struct MarioState* marioState = nearest_mario_state_to_object(o);
|
||||||
if (marioState->playerIndex != 0) { return; }
|
if (marioState->playerIndex != 0) { return; }
|
||||||
|
|
||||||
struct Object* player = marioState->marioObj;
|
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->oAction == 0) {
|
||||||
if (o->oTimer > 30 && 500.0f < distanceToPlayer && distanceToPlayer < 1500.0f) {
|
if (o->oTimer > 30 && 500.0f < distanceToPlayer && distanceToPlayer < 1500.0f) {
|
||||||
cur_obj_play_sound_2(SOUND_OBJ2_SCUTTLEBUG_ALERT);
|
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) {
|
if (scuttlebug != NULL) {
|
||||||
scuttlebug->oScuttlebugUnkF4 = o->oScuttlebugSpawnerUnkF4;
|
scuttlebug->oScuttlebugUnkF4 = o->oScuttlebugSpawnerUnkF4;
|
||||||
scuttlebug->oForwardVel = 30.0f;
|
scuttlebug->oForwardVel = 30.0f;
|
||||||
scuttlebug->oVelY = 80.0f;
|
scuttlebug->oVelY = 80.0f;
|
||||||
|
|
||||||
network_set_sync_id(scuttlebug);
|
network_set_sync_id(scuttlebug);
|
||||||
struct Object* spawn_objects[] = { scuttlebug };
|
struct Object *spawn_objects[] = { scuttlebug };
|
||||||
u32 models[] = { MODEL_SCUTTLEBUG };
|
u32 models[] = { MODEL_SCUTTLEBUG };
|
||||||
network_send_spawn_objects(spawn_objects, models, 1);
|
network_send_spawn_objects(spawn_objects, models, 1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,16 +24,19 @@ void bhv_seesaw_platform_init(void) {
|
||||||
o->oCollisionDistance = 2000.0f;
|
o->oCollisionDistance = 2000.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
network_init_object(o, 1000.0f);
|
if (!network_sync_object_initialized(o)) {
|
||||||
network_init_object_field(o, &o->oSeesawPlatformPitchVel);
|
struct SyncObject *so = network_init_object(o, 1000.0f);
|
||||||
network_init_object_field(o, &o->oFaceAnglePitch);
|
if (so) {
|
||||||
|
network_init_object_field(o, &o->oSeesawPlatformPitchVel);
|
||||||
|
network_init_object_field(o, &o->oFaceAnglePitch);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update function for bhvSeesawPlatform.
|
* Update function for bhvSeesawPlatform.
|
||||||
*/
|
*/
|
||||||
void bhv_seesaw_platform_update(void) {
|
void bhv_seesaw_platform_update(void) {
|
||||||
UNUSED s32 startPitch = o->oFaceAnglePitch;
|
|
||||||
o->oFaceAnglePitch += (s32) o->oSeesawPlatformPitchVel;
|
o->oFaceAnglePitch += (s32) o->oSeesawPlatformPitchVel;
|
||||||
|
|
||||||
if (absf(o->oSeesawPlatformPitchVel) > 10.0f) {
|
if (absf(o->oSeesawPlatformPitchVel) > 10.0f) {
|
||||||
|
@ -44,7 +47,7 @@ void bhv_seesaw_platform_update(void) {
|
||||||
f32 y = 0;
|
f32 y = 0;
|
||||||
f32 z = 0;
|
f32 z = 0;
|
||||||
u8 playersTouched = 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 (!is_player_active(&gMarioStates[i])) { continue; }
|
||||||
if (gMarioStates[i].marioObj->platform == o) {
|
if (gMarioStates[i].marioObj->platform == o) {
|
||||||
x += gMarioStates[i].marioObj->oPosX;
|
x += gMarioStates[i].marioObj->oPosX;
|
||||||
|
@ -59,12 +62,11 @@ void bhv_seesaw_platform_update(void) {
|
||||||
y /= (f32)playersTouched;
|
y /= (f32)playersTouched;
|
||||||
z /= (f32)playersTouched;
|
z /= (f32)playersTouched;
|
||||||
|
|
||||||
int distanceToPlayer = dist_between_object_and_point(o, x, y, z);
|
s32 distanceToPlayer = dist_between_object_and_point(o, x, y, z);
|
||||||
int angleToPlayer = obj_angle_to_point(o, x, z);
|
s32 angleToPlayer = obj_angle_to_point(o, x, z);
|
||||||
|
|
||||||
// Rotate toward mario
|
// Rotate toward mario
|
||||||
f32 rotation = distanceToPlayer * coss(angleToPlayer - o->oMoveAngleYaw);
|
f32 rotation = distanceToPlayer * coss(angleToPlayer - o->oMoveAngleYaw);
|
||||||
UNUSED s32 unused;
|
|
||||||
|
|
||||||
// Deceleration is faster than acceleration
|
// Deceleration is faster than acceleration
|
||||||
if (o->oSeesawPlatformPitchVel * rotation < 0) {
|
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) {
|
void bhv_sl_snowman_wind_loop(void) {
|
||||||
if (!network_sync_object_initialized(o)) {
|
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);
|
||||||
network_init_object_field(o, &o->oAction);
|
if (so) {
|
||||||
network_init_object_field(o, &o->oPrevAction);
|
network_init_object_field(o, &o->oAction);
|
||||||
network_init_object_field(o, &o->oTimer);
|
network_init_object_field(o, &o->oPrevAction);
|
||||||
network_init_object_field(o, &o->oSubAction);
|
network_init_object_field(o, &o->oTimer);
|
||||||
|
network_init_object_field(o, &o->oSubAction);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Object* player = nearest_player_to_object(o);
|
struct Object *player = nearest_player_to_object(o);
|
||||||
int distanceToPlayer = dist_between_objects(o, player);
|
s32 distanceToPlayer = dist_between_objects(o, player);
|
||||||
int angleToPlayer = obj_angle_to_object(o, player);
|
s32 angleToPlayer = obj_angle_to_object(o, player);
|
||||||
|
|
||||||
UNUSED s32 unusedVar = 0;
|
|
||||||
s16 marioAngleFromWindSource;
|
s16 marioAngleFromWindSource;
|
||||||
Vec3f tempPos;
|
Vec3f tempPos;
|
||||||
|
|
||||||
|
|
|
@ -38,14 +38,16 @@ void bhv_sl_walking_penguin_loop(void) {
|
||||||
f32 perpendicularOffset = 100.0f;
|
f32 perpendicularOffset = 100.0f;
|
||||||
|
|
||||||
if (!network_sync_object_initialized(o)) {
|
if (!network_sync_object_initialized(o)) {
|
||||||
network_init_object(o, 4000.0f);
|
struct SyncObject *so = network_init_object(o, 4000.0f);
|
||||||
network_init_object_field(o, &o->oTimer);
|
if (so) {
|
||||||
network_init_object_field(o, &o->oAction);
|
network_init_object_field(o, &o->oTimer);
|
||||||
network_init_object_field(o, &o->oPrevAction);
|
network_init_object_field(o, &o->oAction);
|
||||||
network_init_object_field(o, &o->oSLWalkingPenguinCurStep);
|
network_init_object_field(o, &o->oPrevAction);
|
||||||
network_init_object_field(o, &o->oSLWalkingPenguinCurStepTimer);
|
network_init_object_field(o, &o->oSLWalkingPenguinCurStep);
|
||||||
network_init_object_field(o, &o->oSLWalkingPenguinWindCollisionXPos);
|
network_init_object_field(o, &o->oSLWalkingPenguinCurStepTimer);
|
||||||
network_init_object_field(o, &o->oSLWalkingPenguinWindCollisionZPos);
|
network_init_object_field(o, &o->oSLWalkingPenguinWindCollisionXPos);
|
||||||
|
network_init_object_field(o, &o->oSLWalkingPenguinWindCollisionZPos);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
o->oAngleVelYaw = 0;
|
o->oAngleVelYaw = 0;
|
||||||
|
|
|
@ -36,7 +36,6 @@ void bhv_sliding_plat_2_init(void) {
|
||||||
void bhv_sliding_plat_2_loop(void) {
|
void bhv_sliding_plat_2_loop(void) {
|
||||||
if (!network_sync_object_initialized(o)) {
|
if (!network_sync_object_initialized(o)) {
|
||||||
struct SyncObject* so = network_init_object(o, 4000.0f);
|
struct SyncObject* so = network_init_object(o, 4000.0f);
|
||||||
|
|
||||||
if (so) {
|
if (so) {
|
||||||
so->minUpdateRate = 5.0f;
|
so->minUpdateRate = 5.0f;
|
||||||
network_init_object_field(o, &o->oBackAndForthPlatformDirection);
|
network_init_object_field(o, &o->oBackAndForthPlatformDirection);
|
||||||
|
|
|
@ -140,7 +140,7 @@ static u8 spawn_star_deduplication(u32* array, u8* count, u32 behParams) {
|
||||||
return TRUE;
|
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 (sCurrPlayMode != PLAY_MODE_NORMAL && sCurrPlayMode != PLAY_MODE_PAUSED) { return NULL; }
|
||||||
if (o == NULL) { return NULL; }
|
if (o == NULL) { return NULL; }
|
||||||
u32 behParams = o->oBehParams;
|
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);
|
star = spawn_star(star, x, y, z);
|
||||||
if (star != NULL) {
|
if (star != NULL) {
|
||||||
star->oBehParams2ndByte = 0;
|
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;
|
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;
|
u32 behParams = o->oBehParams;
|
||||||
|
|
||||||
// de-duplication checking
|
// 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);
|
star = spawn_star(star, x, y, z);
|
||||||
if (star != NULL) {
|
if (star != NULL) {
|
||||||
star->oBehParams2ndByte = 1;
|
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;
|
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;
|
u32 behParams = o->oBehParams;
|
||||||
|
|
||||||
// de-duplication checking
|
// de-duplication checking
|
||||||
|
@ -189,14 +189,45 @@ struct Object* spawn_no_exit_star(f32 x, f32 y, f32 z) {
|
||||||
if (star != NULL) {
|
if (star != NULL) {
|
||||||
star->oBehParams2ndByte = 1;
|
star->oBehParams2ndByte = 1;
|
||||||
star->oInteractionSubtype |= INT_SUBTYPE_NO_EXIT;
|
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;
|
return star;
|
||||||
}
|
}
|
||||||
|
|
||||||
void bhv_hidden_red_coin_star_init(void) {
|
void bhv_hidden_red_coin_star_init(void) {
|
||||||
if (gCurrCourseNum != COURSE_JRB)
|
if (gCurrCourseNum != COURSE_JRB) {
|
||||||
spawn_object(o, MODEL_TRANSPARENT_STAR, bhvRedCoinStarMarker);
|
spawn_object(o, MODEL_TRANSPARENT_STAR, bhvRedCoinStarMarker);
|
||||||
|
}
|
||||||
|
|
||||||
s16 redCoins = count_objects_with_behavior(bhvRedCoin);
|
s16 redCoins = count_objects_with_behavior(bhvRedCoin);
|
||||||
if (redCoins == 0) {
|
if (redCoins == 0) {
|
||||||
|
@ -206,20 +237,48 @@ void bhv_hidden_red_coin_star_init(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
o->oHiddenStarTriggerCounter = 8 - redCoins;
|
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) {
|
void bhv_hidden_red_coin_star_loop(void) {
|
||||||
gRedCoinsCollected = o->oHiddenStarTriggerCounter;
|
gRedCoinsCollected = o->oHiddenStarTriggerCounter;
|
||||||
switch (o->oAction) {
|
switch (o->oAction) {
|
||||||
case 0:
|
case 0:
|
||||||
if (o->oHiddenStarTriggerCounter == 8)
|
if (o->oHiddenStarTriggerCounter == 8) {
|
||||||
o->oAction = 1;
|
o->oAction = 1;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
if (o->oTimer > 2) {
|
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);
|
||||||
spawn_mist_particles();
|
if (obj != NULL) {
|
||||||
|
if (o->oHiddenStarLastInteractedObject == &gMarioStates[0]) {
|
||||||
|
obj->oStarSpawnExtCutsceneFlags = 1;
|
||||||
|
} else {
|
||||||
|
obj->oStarSpawnExtCutsceneFlags = 0;
|
||||||
|
}
|
||||||
|
spawn_mist_particles();
|
||||||
|
}
|
||||||
o->activeFlags = ACTIVE_FLAG_DEACTIVATED;
|
o->activeFlags = ACTIVE_FLAG_DEACTIVATED;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
// treasure_chest.c.inc
|
// treasure_chest.c.inc
|
||||||
|
|
||||||
|
#include "pc/network/network_player.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hitbox for treasure chest bottom.
|
* Hitbox for treasure chest bottom.
|
||||||
*/
|
*/
|
||||||
|
@ -15,8 +17,9 @@ static struct ObjectHitbox sTreasureChestBottomHitbox = {
|
||||||
/* hurtboxHeight: */ 310,
|
/* hurtboxHeight: */ 310,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
void bhv_treasure_chest_top_loop(void) {
|
void bhv_treasure_chest_top_loop(void) {
|
||||||
struct Object* sp34 = o->parentObj->parentObj;
|
struct Object *rootParent = o->parentObj->parentObj;
|
||||||
|
|
||||||
switch (o->oAction) {
|
switch (o->oAction) {
|
||||||
case 0:
|
case 0:
|
||||||
|
@ -27,7 +30,7 @@ void bhv_treasure_chest_top_loop(void) {
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
if (o->oTimer == 0) {
|
if (o->oTimer == 0) {
|
||||||
if (sp34->oTreasureChestUnkFC == 0) {
|
if (rootParent->oTreasureChestIsAboveWater == 0) {
|
||||||
spawn_object_relative(0, 0, -80, 120, o, MODEL_BUBBLE, bhvWaterAirBubble);
|
spawn_object_relative(0, 0, -80, 120, o, MODEL_BUBBLE, bhvWaterAirBubble);
|
||||||
play_sound(SOUND_GENERAL_CLAM_SHELL1, o->header.gfx.cameraToObject);
|
play_sound(SOUND_GENERAL_CLAM_SHELL1, o->header.gfx.cameraToObject);
|
||||||
} else {
|
} else {
|
||||||
|
@ -39,8 +42,9 @@ void bhv_treasure_chest_top_loop(void) {
|
||||||
if (o->oFaceAnglePitch < -0x4000) {
|
if (o->oFaceAnglePitch < -0x4000) {
|
||||||
o->oFaceAnglePitch = -0x4000;
|
o->oFaceAnglePitch = -0x4000;
|
||||||
o->oAction++;
|
o->oAction++;
|
||||||
if (o->parentObj->oBehParams2ndByte != 4)
|
if (o->parentObj->oBehParams2ndByte != 4) {
|
||||||
spawn_orange_number(o->parentObj->oBehParams2ndByte, 0, -40, 0);
|
spawn_orange_number(o->parentObj->oBehParams2ndByte, 0, -40, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -69,41 +73,40 @@ void bhv_treasure_chest_bottom_loop(void) {
|
||||||
switch (o->parentObj->oTreasureChestSound) {
|
switch (o->parentObj->oTreasureChestSound) {
|
||||||
case 1: play_sound(SOUND_GENERAL2_RIGHT_ANSWER, gGlobalSoundSource); break;
|
case 1: play_sound(SOUND_GENERAL2_RIGHT_ANSWER, gGlobalSoundSource); break;
|
||||||
case 2: play_sound(SOUND_MENU_CAMERA_BUZZ, gGlobalSoundSource); break;
|
case 2: play_sound(SOUND_MENU_CAMERA_BUZZ, gGlobalSoundSource); break;
|
||||||
case 3: play_puzzle_jingle(); fade_volume_scale(0, 127, 1000); break;
|
case 3: play_puzzle_jingle(); fade_volume_scale(0, 127, 1000); break;
|
||||||
case 4: play_puzzle_jingle(); break;
|
case 4: play_puzzle_jingle(); break;
|
||||||
}
|
}
|
||||||
o->parentObj->oTreasureChestSound = 0;
|
o->parentObj->oTreasureChestSound = 0;
|
||||||
}
|
}
|
||||||
struct Object* player = nearest_player_to_object(o);
|
struct MarioState *player = nearest_mario_state_to_object(o);
|
||||||
switch (o->oAction) {
|
switch (o->oAction) {
|
||||||
case 0:
|
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 (is_point_within_radius_of_mario(o->oPosX, o->oPosY, o->oPosZ, 150)) {
|
||||||
if (!o->parentObj->oTreasureChestUnkF8) {
|
if (!o->parentObj->oTreasureChestIsLastInteractionIncorrect) {
|
||||||
if (o->parentObj->oTreasureChestUnkF4 == o->oBehParams2ndByte) {
|
if (o->parentObj->oTreasureChestCurrentAnswer == o->oBehParams2ndByte) {
|
||||||
play_sound(SOUND_GENERAL2_RIGHT_ANSWER, gGlobalSoundSource);
|
play_sound(SOUND_GENERAL2_RIGHT_ANSWER, gGlobalSoundSource);
|
||||||
o->parentObj->oTreasureChestUnkF4++;
|
o->parentObj->oTreasureChestCurrentAnswer++;
|
||||||
o->oAction = 1;
|
o->oAction = 1;
|
||||||
o->parentObj->oTreasureChestSound = 1;
|
o->parentObj->oTreasureChestSound = 1;
|
||||||
network_send_object(o->parentObj);
|
|
||||||
o->parentObj->oTreasureChestSound = 0;
|
|
||||||
} else {
|
} else {
|
||||||
o->parentObj->oTreasureChestUnkF4 = 1;
|
o->parentObj->oTreasureChestCurrentAnswer = 1;
|
||||||
o->parentObj->oTreasureChestUnkF8 = 1;
|
o->parentObj->oTreasureChestIsLastInteractionIncorrect = 1;
|
||||||
o->oAction = 2;
|
o->oAction = 2;
|
||||||
cur_obj_become_tangible();
|
cur_obj_become_tangible();
|
||||||
play_sound(SOUND_MENU_CAMERA_BUZZ, gGlobalSoundSource);
|
play_sound(SOUND_MENU_CAMERA_BUZZ, gGlobalSoundSource);
|
||||||
o->parentObj->oTreasureChestSound = 2;
|
o->parentObj->oTreasureChestSound = 2;
|
||||||
network_send_object(o->parentObj);
|
|
||||||
o->parentObj->oTreasureChestSound = 0;
|
|
||||||
}
|
}
|
||||||
|
o->parentObj->oTreasureChestLastNetworkPlayerIndex = gNetworkPlayers[player->playerIndex].globalIndex;
|
||||||
|
network_send_object(o->parentObj);
|
||||||
|
o->parentObj->oTreasureChestSound = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
if (o->parentObj->oTreasureChestUnkF8 == 1) {
|
if (o->parentObj->oTreasureChestIsLastInteractionIncorrect == 1) {
|
||||||
o->oAction = 0;
|
o->oAction = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -111,7 +114,7 @@ void bhv_treasure_chest_bottom_loop(void) {
|
||||||
case 2:
|
case 2:
|
||||||
cur_obj_become_intangible();
|
cur_obj_become_intangible();
|
||||||
if (!is_point_within_radius_of_mario(o->oPosX, o->oPosY, o->oPosZ, 500)) {
|
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;
|
o->oAction = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -120,44 +123,56 @@ void bhv_treasure_chest_bottom_loop(void) {
|
||||||
o->oInteractStatus = 0;
|
o->oInteractStatus = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Object* spawn_treasure_chest(s8 sp3B, s32 sp3C, s32 sp40, s32 sp44, s16 sp4A) {
|
struct Object* spawn_treasure_chest(s8 index, s32 x, s32 y, s32 z, s16 r) {
|
||||||
struct Object* sp34;
|
struct Object *obj = spawn_object_abs_with_rot(o, 0, MODEL_TREASURE_CHEST_BASE, bhvTreasureChestBottom, x, y, z, 0, r, 0);
|
||||||
sp34 = spawn_object_abs_with_rot(o, 0, MODEL_TREASURE_CHEST_BASE, bhvTreasureChestBottom, sp3C,
|
if (obj != NULL) { obj->oBehParams2ndByte = index; }
|
||||||
sp40, sp44, 0, sp4A, 0);
|
return obj;
|
||||||
if (sp34 != NULL) { sp34->oBehParams2ndByte = sp3B; }
|
|
||||||
return sp34;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void bhv_treasure_chest_ship_init(void) {
|
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[0] = spawn_treasure_chest(1, 400, -350, -2700, 0);
|
||||||
chests[1] = spawn_treasure_chest(2, 650, -350, -940, -0x6001);
|
chests[1] = spawn_treasure_chest(2, 650, -350, -940, -0x6001);
|
||||||
chests[2] = spawn_treasure_chest(3, -550, -350, -770, 0x5FFF);
|
chests[2] = spawn_treasure_chest(3, -550, -350, -770, 0x5FFF);
|
||||||
chests[3] = spawn_treasure_chest(4, 100, -350, -1700, 0);
|
chests[3] = spawn_treasure_chest(4, 100, -350, -1700, 0);
|
||||||
o->oTreasureChestUnkF4 = 1;
|
|
||||||
o->oTreasureChestUnkFC = 0;
|
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;
|
||||||
|
|
||||||
network_init_object(o, SYNC_DISTANCE_ONLY_EVENTS);
|
if (!network_sync_object_initialized(o)) {
|
||||||
network_init_object_field(o, &o->oAction);
|
struct SyncObject *so = network_init_object(o, SYNC_DISTANCE_ONLY_EVENTS);
|
||||||
network_init_object_field(o, &o->oPrevAction);
|
if (so) {
|
||||||
network_init_object_field(o, &o->oTimer);
|
network_init_object_field(o, &o->oAction);
|
||||||
network_init_object_field(o, &o->oTreasureChestUnkF4);
|
network_init_object_field(o, &o->oPrevAction);
|
||||||
network_init_object_field(o, &o->oTreasureChestUnkF8);
|
network_init_object_field(o, &o->oTimer);
|
||||||
network_init_object_field(o, &o->oTreasureChestUnkFC);
|
network_init_object_field(o, &o->oTreasureChestCurrentAnswer);
|
||||||
network_init_object_field(o, &o->oTreasureChestSound);
|
network_init_object_field(o, &o->oTreasureChestIsLastInteractionIncorrect);
|
||||||
for (int i = 0; i < 4; i++) {
|
network_init_object_field(o, &o->oTreasureChestIsAboveWater);
|
||||||
struct Object* chest = chests[i];
|
network_init_object_field(o, &o->oTreasureChestSound);
|
||||||
network_init_object_field(o, &chest->oAction);
|
network_init_object_field(o, &o->oTreasureChestLastNetworkPlayerIndex);
|
||||||
network_init_object_field(o, &chest->oPrevAction);
|
for (s32 i = 0; i < 4; i++) {
|
||||||
network_init_object_field(o, &chest->oTimer);
|
struct Object *chest = chests[i];
|
||||||
network_init_object_field(o, &chest->oIntangibleTimer);
|
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) {
|
void bhv_treasure_chest_ship_loop(void) {
|
||||||
switch (o->oAction) {
|
switch (o->oAction) {
|
||||||
case 0:
|
case 0:
|
||||||
if (network_owns_object(o) && o->oTreasureChestUnkF4 == 5) {
|
if (network_owns_object(o) && o->oTreasureChestCurrentAnswer == 5) {
|
||||||
play_puzzle_jingle();
|
play_puzzle_jingle();
|
||||||
fade_volume_scale(0, 127, 1000);
|
fade_volume_scale(0, 127, 1000);
|
||||||
o->oAction = 1;
|
o->oAction = 1;
|
||||||
|
@ -185,35 +200,49 @@ void bhv_treasure_chest_ship_loop(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void bhv_treasure_chest_jrb_init(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[0] = spawn_treasure_chest(1, -1700, -2812, -1150, 0x7FFF);
|
||||||
chests[1] = spawn_treasure_chest(2, -1150, -2812, -1550, 0x7FFF);
|
chests[1] = spawn_treasure_chest(2, -1150, -2812, -1550, 0x7FFF);
|
||||||
chests[2] = spawn_treasure_chest(3, -2400, -2812, -1800, 0x7FFF);
|
chests[2] = spawn_treasure_chest(3, -2400, -2812, -1800, 0x7FFF);
|
||||||
chests[3] = spawn_treasure_chest(4, -1800, -2812, -2100, 0x7FFF);
|
chests[3] = spawn_treasure_chest(4, -1800, -2812, -2100, 0x7FFF);
|
||||||
o->oTreasureChestUnkF4 = 1;
|
|
||||||
o->oTreasureChestUnkFC = 1;
|
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;
|
||||||
|
|
||||||
network_init_object(o, SYNC_DISTANCE_ONLY_EVENTS);
|
if (!network_sync_object_initialized(o)) {
|
||||||
network_init_object_field(o, &o->oAction);
|
struct SyncObject *so = network_init_object(o, SYNC_DISTANCE_ONLY_EVENTS);
|
||||||
network_init_object_field(o, &o->oPrevAction);
|
if (so) {
|
||||||
network_init_object_field(o, &o->oTimer);
|
network_init_object_field(o, &o->oAction);
|
||||||
network_init_object_field(o, &o->oTreasureChestUnkF4);
|
network_init_object_field(o, &o->oPrevAction);
|
||||||
network_init_object_field(o, &o->oTreasureChestUnkF8);
|
network_init_object_field(o, &o->oTimer);
|
||||||
network_init_object_field(o, &o->oTreasureChestUnkFC);
|
network_init_object_field(o, &o->oTreasureChestCurrentAnswer);
|
||||||
network_init_object_field(o, &o->oTreasureChestSound);
|
network_init_object_field(o, &o->oTreasureChestIsLastInteractionIncorrect);
|
||||||
for (int i = 0; i < 4; i++) {
|
network_init_object_field(o, &o->oTreasureChestIsAboveWater);
|
||||||
struct Object* chest = chests[i];
|
network_init_object_field(o, &o->oTreasureChestSound);
|
||||||
network_init_object_field(o, &chest->oAction);
|
network_init_object_field(o, &o->oTreasureChestLastNetworkPlayerIndex);
|
||||||
network_init_object_field(o, &chest->oPrevAction);
|
for (s32 i = 0; i < 4; i++) {
|
||||||
network_init_object_field(o, &chest->oTimer);
|
struct Object *chest = chests[i];
|
||||||
network_init_object_field(o, &chest->oIntangibleTimer);
|
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) {
|
void bhv_treasure_chest_jrb_loop(void) {
|
||||||
switch (o->oAction) {
|
switch (o->oAction) {
|
||||||
case 0:
|
case 0:
|
||||||
if (network_owns_object(o) && o->oTreasureChestUnkF4 == 5) {
|
if (network_owns_object(o) && o->oTreasureChestCurrentAnswer == 5) {
|
||||||
play_puzzle_jingle();
|
play_puzzle_jingle();
|
||||||
o->oAction = 1;
|
o->oAction = 1;
|
||||||
o->oTreasureChestSound = 4;
|
o->oTreasureChestSound = 4;
|
||||||
|
@ -225,7 +254,7 @@ void bhv_treasure_chest_jrb_loop(void) {
|
||||||
case 1:
|
case 1:
|
||||||
if (o->oTimer == 60) {
|
if (o->oTimer == 60) {
|
||||||
spawn_mist_particles();
|
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;
|
o->oAction = 2;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -236,36 +265,49 @@ void bhv_treasure_chest_jrb_loop(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void bhv_treasure_chest_init(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[0] = spawn_treasure_chest(1, -4500, -5119, 1300, -0x6001);
|
||||||
chests[1] = spawn_treasure_chest(2, -1800, -5119, 1050, 0x1FFF);
|
chests[1] = spawn_treasure_chest(2, -1800, -5119, 1050, 0x1FFF);
|
||||||
chests[2] = spawn_treasure_chest(3, -4500, -5119, -1100, 9102);
|
chests[2] = spawn_treasure_chest(3, -4500, -5119, -1100, 9102);
|
||||||
chests[3] = spawn_treasure_chest(4, -2400, -4607, 125, 16019);
|
chests[3] = spawn_treasure_chest(4, -2400, -4607, 125, 16019);
|
||||||
|
|
||||||
o->oTreasureChestUnkF4 = 1;
|
o->oTreasureChestCurrentAnswer = 1;
|
||||||
o->oTreasureChestUnkFC = 0;
|
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;
|
||||||
|
|
||||||
network_init_object(o, SYNC_DISTANCE_ONLY_EVENTS);
|
if (!network_sync_object_initialized(o)) {
|
||||||
network_init_object_field(o, &o->oAction);
|
struct SyncObject *so = network_init_object(o, SYNC_DISTANCE_ONLY_EVENTS);
|
||||||
network_init_object_field(o, &o->oPrevAction);
|
if (so) {
|
||||||
network_init_object_field(o, &o->oTimer);
|
network_init_object_field(o, &o->oAction);
|
||||||
network_init_object_field(o, &o->oTreasureChestUnkF4);
|
network_init_object_field(o, &o->oPrevAction);
|
||||||
network_init_object_field(o, &o->oTreasureChestUnkF8);
|
network_init_object_field(o, &o->oTimer);
|
||||||
network_init_object_field(o, &o->oTreasureChestUnkFC);
|
network_init_object_field(o, &o->oTreasureChestCurrentAnswer);
|
||||||
network_init_object_field(o, &o->oTreasureChestSound);
|
network_init_object_field(o, &o->oTreasureChestIsLastInteractionIncorrect);
|
||||||
for (int i = 0; i < 4; i++) {
|
network_init_object_field(o, &o->oTreasureChestIsAboveWater);
|
||||||
struct Object* chest = chests[i];
|
network_init_object_field(o, &o->oTreasureChestSound);
|
||||||
network_init_object_field(o, &chest->oAction);
|
network_init_object_field(o, &o->oTreasureChestLastNetworkPlayerIndex);
|
||||||
network_init_object_field(o, &chest->oPrevAction);
|
for (s32 i = 0; i < 4; i++) {
|
||||||
network_init_object_field(o, &chest->oTimer);
|
struct Object *chest = chests[i];
|
||||||
network_init_object_field(o, &chest->oIntangibleTimer);
|
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) {
|
void bhv_treasure_chest_loop(void) {
|
||||||
switch (o->oAction) {
|
switch (o->oAction) {
|
||||||
case 0:
|
case 0:
|
||||||
if (network_owns_object(o) && o->oTreasureChestUnkF4 == 5) {
|
if (network_owns_object(o) && o->oTreasureChestCurrentAnswer == 5) {
|
||||||
play_puzzle_jingle();
|
play_puzzle_jingle();
|
||||||
o->oAction = 1;
|
o->oAction = 1;
|
||||||
o->oTreasureChestSound = 4;
|
o->oTreasureChestSound = 4;
|
||||||
|
@ -277,7 +319,7 @@ void bhv_treasure_chest_loop(void) {
|
||||||
case 1:
|
case 1:
|
||||||
if (o->oTimer == 60) {
|
if (o->oTimer == 60) {
|
||||||
spawn_mist_particles();
|
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;
|
o->oAction = 2;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1369,9 +1369,15 @@ u32 interact_player(struct MarioState* m, UNUSED u32 interactType, struct Object
|
||||||
Vec3f velDiff;
|
Vec3f velDiff;
|
||||||
vec3f_dif(velDiff, m->vel, m2->vel);
|
vec3f_dif(velDiff, m->vel, m2->vel);
|
||||||
|
|
||||||
if (vec3f_length(velDiff) < 40) {
|
if (m->action == ACT_SLIDE_KICK_SLIDE || m->action == ACT_SLIDE_KICK) {
|
||||||
// the difference vectors are not different enough, do not attack
|
if (vec3f_length(m->vel) < 15) {
|
||||||
return FALSE;
|
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)) {
|
if (vec3f_length(m2->vel) > vec3f_length(m->vel)) {
|
||||||
// the one being attacked is going faster, do not attack
|
// the one being attacked is going faster, do not attack
|
||||||
|
|
|
@ -380,6 +380,11 @@ static bool smlua_is_valid_object_field(struct Object* obj, struct LuaObjectFiel
|
||||||
case id_bhvHauntedChair:
|
case id_bhvHauntedChair:
|
||||||
if (!smlua_field_valid(data, LOT_NONE, offsetof(struct Object, oHauntedChairUnk100))) { return false; }
|
if (!smlua_field_valid(data, LOT_NONE, offsetof(struct Object, oHauntedChairUnk100))) { return false; }
|
||||||
break;
|
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_bhvBreakableBox:
|
||||||
case id_bhvHiddenObject:
|
case id_bhvHiddenObject:
|
||||||
if (!smlua_field_valid(data, LOT_OBJECT, offsetof(struct Object, oHiddenObjectUnkF4))) { return false; }
|
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 },
|
{ "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] = {
|
static struct LuaObjectField sObjectFields[LUA_OBJECT_FIELD_COUNT] = {
|
||||||
{ "activeFlags", LVT_S16, offsetof(struct Object, activeFlags), false, LOT_NONE },
|
{ "activeFlags", LVT_S16, offsetof(struct Object, activeFlags), false, LOT_NONE },
|
||||||
{ "areaTimer", LVT_U32, offsetof(struct Object, areaTimer), 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 },
|
{ "oHeldState", LVT_U32, offsetof(struct Object, oHeldState), false, LOT_NONE },
|
||||||
{ "oHiddenBlueCoinSwitch", LVT_COBJECT_P, offsetof(struct Object, oHiddenBlueCoinSwitch), false, LOT_OBJECT },
|
{ "oHiddenBlueCoinSwitch", LVT_COBJECT_P, offsetof(struct Object, oHiddenBlueCoinSwitch), false, LOT_OBJECT },
|
||||||
{ "oHiddenObjectUnkF4", LVT_COBJECT_P, offsetof(struct Object, oHiddenObjectUnkF4), 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 },
|
{ "oHiddenStarTriggerCounter", LVT_S32, offsetof(struct Object, oHiddenStarTriggerCounter), false, LOT_NONE },
|
||||||
{ "oHomeX", LVT_F32, offsetof(struct Object, oHomeX), false, LOT_NONE },
|
{ "oHomeX", LVT_F32, offsetof(struct Object, oHomeX), false, LOT_NONE },
|
||||||
{ "oHomeY", LVT_F32, offsetof(struct Object, oHomeY), 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 },
|
{ "oToadMessageState", LVT_S32, offsetof(struct Object, oToadMessageState), false, LOT_NONE },
|
||||||
// { "oToxBoxMovementPattern", LVT_???, offsetof(struct Object, oToxBoxMovementPattern), false, LOT_??? }, <--- UNIMPLEMENTED
|
// { "oToxBoxMovementPattern", LVT_???, offsetof(struct Object, oToxBoxMovementPattern), false, LOT_??? }, <--- UNIMPLEMENTED
|
||||||
{ "oToxBoxMovementStep", LVT_S32, offsetof(struct Object, oToxBoxMovementStep), false, LOT_NONE },
|
{ "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 },
|
{ "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 },
|
{ "oTreeSnowOrLeafUnkF4", LVT_S32, offsetof(struct Object, oTreeSnowOrLeafUnkF4), false, LOT_NONE },
|
||||||
{ "oTreeSnowOrLeafUnkF8", LVT_S32, offsetof(struct Object, oTreeSnowOrLeafUnkF8), false, LOT_NONE },
|
{ "oTreeSnowOrLeafUnkF8", LVT_S32, offsetof(struct Object, oTreeSnowOrLeafUnkF8), false, LOT_NONE },
|
||||||
{ "oTreeSnowOrLeafUnkFC", LVT_S32, offsetof(struct Object, oTreeSnowOrLeafUnkFC), 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);
|
void network_receive_spawn_objects(struct Packet* p);
|
||||||
|
|
||||||
// packet_spawn_star.c
|
// 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_receive_spawn_star(struct Packet* p);
|
||||||
void network_send_spawn_star_nle(struct Object* o, u32 params);
|
void network_send_spawn_star_nle(struct Object* o, u32 params);
|
||||||
void network_receive_spawn_star_nle(struct Packet* p);
|
void network_receive_spawn_star_nle(struct Packet* p);
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
extern struct Object* gCurrentObject;
|
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 };
|
struct Packet p = { 0 };
|
||||||
packet_init(&p, PACKET_SPAWN_STAR, true, PLMT_AREA);
|
packet_init(&p, PACKET_SPAWN_STAR, true, PLMT_AREA);
|
||||||
packet_write(&p, &starType, sizeof(u8));
|
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, &y, sizeof(f32));
|
||||||
packet_write(&p, &z, sizeof(f32));
|
packet_write(&p, &z, sizeof(f32));
|
||||||
packet_write(&p, &behParams, sizeof(u32));
|
packet_write(&p, &behParams, sizeof(u32));
|
||||||
|
packet_write(&p, &networkPlayerIndex, sizeof(u8));
|
||||||
|
|
||||||
packet_write(&p, &o->oPosX, sizeof(u32) * 3);
|
packet_write(&p, &o->oPosX, sizeof(u32) * 3);
|
||||||
packet_write(&p, &o->oHomeX, 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;
|
u8 starType;
|
||||||
f32 x, y, z;
|
f32 x, y, z;
|
||||||
u32 behParams;
|
u32 behParams;
|
||||||
|
u8 networkPlayerIndex = UNKNOWN_GLOBAL_INDEX;
|
||||||
|
|
||||||
packet_read(p, &starType, sizeof(u8));
|
packet_read(p, &starType, sizeof(u8));
|
||||||
packet_read(p, &x, sizeof(f32));
|
packet_read(p, &x, sizeof(f32));
|
||||||
packet_read(p, &y, sizeof(f32));
|
packet_read(p, &y, sizeof(f32));
|
||||||
packet_read(p, &z, sizeof(f32));
|
packet_read(p, &z, sizeof(f32));
|
||||||
packet_read(p, &behParams, sizeof(u32));
|
packet_read(p, &behParams, sizeof(u32));
|
||||||
|
packet_read(p, &networkPlayerIndex, sizeof(u8));
|
||||||
|
|
||||||
u32 oldBehParams = gCurrentObject->oBehParams;
|
u32 oldBehParams = gCurrentObject->oBehParams;
|
||||||
gCurrentObject->oBehParams = behParams;
|
gCurrentObject->oBehParams = behParams;
|
||||||
|
@ -47,7 +50,19 @@ void network_receive_spawn_star(struct Packet* p) {
|
||||||
if (o != NULL) {
|
if (o != NULL) {
|
||||||
packet_read(p, &o->oPosX, sizeof(u32) * 3);
|
packet_read(p, &o->oPosX, sizeof(u32) * 3);
|
||||||
packet_read(p, &o->oHomeX, sizeof(u32) * 3);
|
packet_read(p, &o->oHomeX, sizeof(u32) * 3);
|
||||||
o->oStarSpawnExtCutsceneFlags = 0;
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue