mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2024-12-22 16:30:23 +00:00
Improvements to late-join synchronization
Removed (slightly) old coin and static ent removal system Resynchronized respawners Added packet for macro deletions better than previous system since the entities don't need a sync id and we can synchronize deletion station across areas allows the synchronization of odd entities like lines of coins Added packet for spawn info deletions Split packet_location_request into multiple files
This commit is contained in:
parent
6e7c542068
commit
0b3a97d405
26 changed files with 1045 additions and 744 deletions
|
@ -3968,10 +3968,15 @@
|
|||
<ClCompile Include="..\src\pc\network\packets\packet_collect_star.c" />
|
||||
<ClCompile Include="..\src\pc\network\packets\packet_custom.c" />
|
||||
<ClCompile Include="..\src\pc\network\packets\packet_death.c" />
|
||||
<ClCompile Include="..\src\pc\network\packets\packet_location_request.c" />
|
||||
<ClCompile Include="..\src\pc\network\packets\packet_kick.c" />
|
||||
<ClCompile Include="..\src\pc\network\packets\packet_join.c" />
|
||||
<ClCompile Include="..\src\pc\network\packets\packet_keep_alive.c" />
|
||||
<ClCompile Include="..\src\pc\network\packets\packet_leaving.c" />
|
||||
<ClCompile Include="..\src\pc\network\packets\packet_level_area.c" />
|
||||
<ClCompile Include="..\src\pc\network\packets\packet_location_request_client.c" />
|
||||
<ClCompile Include="..\src\pc\network\packets\packet_location_response.c" />
|
||||
<ClCompile Include="..\src\pc\network\packets\packet_macro_deletions.c" />
|
||||
<ClCompile Include="..\src\pc\network\packets\packet_network_players.c" />
|
||||
<ClCompile Include="..\src\pc\network\packets\packet_object.c" />
|
||||
<ClCompile Include="..\src\pc\network\packets\packet_player.c" />
|
||||
|
@ -3979,6 +3984,7 @@
|
|||
<ClCompile Include="..\src\pc\network\packets\packet_reliable.c" />
|
||||
<ClCompile Include="..\src\pc\network\packets\packet_reservation.c" />
|
||||
<ClCompile Include="..\src\pc\network\packets\packet_save_file.c" />
|
||||
<ClCompile Include="..\src\pc\network\packets\packet_spawn_info_deletions.c" />
|
||||
<ClCompile Include="..\src\pc\network\packets\packet_spawn_objects.c" />
|
||||
<ClCompile Include="..\src\pc\network\packets\packet_spawn_star.c" />
|
||||
<ClCompile Include="..\src\pc\network\socket\socket.c" />
|
||||
|
|
|
@ -529,20 +529,3 @@ const BehaviorScript* get_behavior_from_id(enum BehaviorId id) {
|
|||
}
|
||||
return gBehaviorTable[id];
|
||||
}
|
||||
|
||||
u8 is_behavior_a_coin(const BehaviorScript* behavior) {
|
||||
return behavior == bhvCoinFormationSpawn
|
||||
|| behavior == bhvCoinFormation
|
||||
|| behavior == bhvOneCoin
|
||||
|| behavior == bhvYellowCoin
|
||||
|| behavior == bhvTemporaryYellowCoin
|
||||
|| behavior == bhvThreeCoinsSpawn
|
||||
|| behavior == bhvTenCoinsSpawn
|
||||
|| behavior == bhvHiddenBlueCoin
|
||||
|| behavior == bhvMovingYellowCoin
|
||||
|| behavior == bhvMovingBlueCoin
|
||||
|| behavior == bhvBlueCoinSliding
|
||||
|| behavior == bhvBlueCoinJumping
|
||||
|| behavior == bhvRedCoin
|
||||
|| behavior == bhvBowserCourseRedCoinStar;
|
||||
}
|
||||
|
|
|
@ -18,10 +18,10 @@ fi
|
|||
#exit
|
||||
|
||||
# no debug, direct
|
||||
$FILE --server 27015 --configfile sm64config_server.txt &
|
||||
sleep 7
|
||||
$FILE --client 127.0.0.1 27015 --configfile sm64config_client.txt &
|
||||
exit
|
||||
#$FILE --server 27015 --configfile sm64config_server.txt &
|
||||
#sleep 7
|
||||
#$FILE --client 127.0.0.1 27015 --configfile sm64config_client.txt &
|
||||
#exit
|
||||
|
||||
# debug on server
|
||||
#$FILE --client 127.0.0.1 27015 --configfile sm64config_client.txt &
|
||||
|
|
|
@ -526,6 +526,5 @@ enum BehaviorId {
|
|||
|
||||
enum BehaviorId get_id_from_behavior(const BehaviorScript* behavior);
|
||||
const BehaviorScript* get_behavior_from_id(enum BehaviorId id);
|
||||
u8 is_behavior_a_coin(const BehaviorScript* behavior);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -12,373 +12,6 @@ struct MacroPreset
|
|||
/*0x06*/ s16 param;
|
||||
};
|
||||
|
||||
struct MacroPreset MacroObjectPresets[] = {
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvOneCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvMovingBlueCoin, MODEL_BLUE_COIN, 0},
|
||||
{bhvBlueCoinSliding, MODEL_BLUE_COIN, 0}, // unused
|
||||
{bhvRedCoin, MODEL_RED_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvCoinFormation, MODEL_NONE, 0},
|
||||
{bhvCoinFormation, MODEL_NONE, COIN_FORMATION_FLAG_RING},
|
||||
{bhvCoinFormation, MODEL_NONE, COIN_FORMATION_FLAG_ARROW},
|
||||
{bhvCoinFormation, MODEL_NONE, COIN_FORMATION_FLAG_FLYING},
|
||||
{bhvCoinFormation, MODEL_NONE, COIN_FORMATION_FLAG_FLYING | COIN_FORMATION_FLAG_VERTICAL},
|
||||
{bhvCoinFormation, MODEL_NONE, COIN_FORMATION_FLAG_FLYING | COIN_FORMATION_FLAG_RING},
|
||||
{bhvCoinFormation, MODEL_NONE, COIN_FORMATION_FLAG_FLYING | COIN_FORMATION_FLAG_RING | COIN_FORMATION_FLAG_VERTICAL},
|
||||
{bhvCoinFormation, MODEL_NONE, COIN_FORMATION_FLAG_FLYING | COIN_FORMATION_FLAG_ARROW}, // unused
|
||||
{bhvHiddenStarTrigger, MODEL_NONE, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvUnusedFakeStar, MODEL_STAR, 0}, // unused
|
||||
{bhvMessagePanel, MODEL_WOODEN_SIGNPOST, 0},
|
||||
{bhvCannonClosed, MODEL_DL_CANNON_LID, 0},
|
||||
{bhvBobombBuddyOpensCannon, MODEL_BOBOMB_BUDDY, 0},
|
||||
{bhvButterfly, MODEL_BUTTERFLY, 0}, // unused
|
||||
{bhvBouncingFireball, MODEL_NONE, 0}, // unused
|
||||
{bhvLargeFishGroup, MODEL_NONE, 0}, // unused
|
||||
{bhvLargeFishGroup, MODEL_NONE, 1},
|
||||
{bhvBetaFishSplashSpawner, MODEL_NONE, 0},
|
||||
{bhvHidden1upInPoleSpawner, MODEL_NONE, 0},
|
||||
{bhvGoomba, MODEL_GOOMBA, 1},
|
||||
{bhvGoomba, MODEL_GOOMBA, 2},
|
||||
{bhvGoombaTripletSpawner, MODEL_NONE, 0},
|
||||
{bhvGoombaTripletSpawner, MODEL_NONE, 8}, // unused
|
||||
{bhvSignOnWall, MODEL_NONE, 0},
|
||||
{bhvChuckya, MODEL_CHUCKYA, 0},
|
||||
{bhvCannon, MODEL_CANNON_BASE, 0},
|
||||
{bhvGoomba, MODEL_GOOMBA, 0},
|
||||
{bhvHomingAmp, MODEL_AMP, 0},
|
||||
{bhvCirclingAmp, MODEL_AMP, 0},
|
||||
{bhvCarrySomething1, MODEL_UNKNOWN_7D, 0}, // unused
|
||||
{bhvBetaTrampolineTop, MODEL_TRAMPOLINE, 0}, // unused
|
||||
{bhvFreeBowlingBall, MODEL_BOWLING_BALL, 0}, // unused
|
||||
{bhvSnufit, MODEL_SNUFIT, 0},
|
||||
{bhvRecoveryHeart, MODEL_HEART, 0},
|
||||
{bhv1upSliding, MODEL_1UP, 0},
|
||||
{bhv1Up, MODEL_1UP, 0},
|
||||
{bhv1upJumpOnApproach, MODEL_1UP, 0}, // unused
|
||||
{bhvHidden1up, MODEL_1UP, 0},
|
||||
{bhvHidden1upTrigger, MODEL_NONE, 0},
|
||||
{bhv1Up, MODEL_1UP, 1},
|
||||
{bhv1Up, MODEL_1UP, 2},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvBlueCoinSwitch, MODEL_BLUE_COIN_SWITCH, 0},
|
||||
{bhvHiddenBlueCoin, MODEL_BLUE_COIN, 0},
|
||||
{bhvCapSwitch, MODEL_CAP_SWITCH, 0}, // unused
|
||||
{bhvCapSwitch, MODEL_CAP_SWITCH, 1}, // unused
|
||||
{bhvCapSwitch, MODEL_CAP_SWITCH, 2}, // unused
|
||||
{bhvCapSwitch, MODEL_CAP_SWITCH, 3}, // unused
|
||||
{bhvWaterLevelDiamond, MODEL_BREAKABLE_BOX, 0}, // unused
|
||||
{bhvExclamationBox, MODEL_EXCLAMATION_BOX, 0},
|
||||
{bhvExclamationBox, MODEL_EXCLAMATION_BOX, 1},
|
||||
{bhvExclamationBox, MODEL_EXCLAMATION_BOX, 2},
|
||||
{bhvExclamationBox, MODEL_EXCLAMATION_BOX, 3},
|
||||
{bhvExclamationBox, MODEL_EXCLAMATION_BOX, 4}, // unused
|
||||
{bhvExclamationBox, MODEL_EXCLAMATION_BOX, 5},
|
||||
{bhvExclamationBox, MODEL_EXCLAMATION_BOX, 6},
|
||||
{bhvExclamationBox, MODEL_EXCLAMATION_BOX, 7},
|
||||
{bhvExclamationBox, MODEL_EXCLAMATION_BOX, 8},
|
||||
{bhvBreakableBox, MODEL_BREAKABLE_BOX, 0},
|
||||
{bhvBreakableBox, MODEL_BREAKABLE_BOX, 1},
|
||||
{bhvPushableMetalBox, MODEL_METAL_BOX, 0},
|
||||
{bhvBreakableBoxSmall, MODEL_BREAKABLE_BOX_SMALL, 0},
|
||||
{bhvFloorSwitchHiddenObjects, MODEL_PURPLE_SWITCH, 0},
|
||||
{bhvHiddenObject, MODEL_BREAKABLE_BOX, 0},
|
||||
{bhvHiddenObject, MODEL_BREAKABLE_BOX, 1}, // unused
|
||||
{bhvHiddenObject, MODEL_BREAKABLE_BOX, 2}, // unused
|
||||
{bhvBreakableBox, MODEL_BREAKABLE_BOX, 3},
|
||||
{bhvKoopaShellUnderwater, MODEL_KOOPA_SHELL, 0},
|
||||
{bhvExclamationBox, MODEL_EXCLAMATION_BOX, 9},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvBulletBill, MODEL_BULLET_BILL, 0}, // unused
|
||||
{bhvHeaveHo, MODEL_HEAVE_HO, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvThwomp2, MODEL_THWOMP, 0}, // unused
|
||||
{bhvFireSpitter, MODEL_BOWLING_BALL, 0},
|
||||
{bhvFlyGuy, MODEL_FLYGUY, 1},
|
||||
{bhvJumpingBox, MODEL_BREAKABLE_BOX, 0},
|
||||
{bhvTripletButterfly, MODEL_BUTTERFLY, 0},
|
||||
{bhvTripletButterfly, MODEL_BUTTERFLY, 4},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvSmallBully, MODEL_BULLY, 0},
|
||||
{bhvSmallBully, MODEL_BULLY_BOSS, 0}, // unused
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvStub1D0C, MODEL_UNKNOWN_58, 0}, // unused
|
||||
{bhvBouncingFireball, MODEL_NONE, 0},
|
||||
{bhvFlamethrower, MODEL_NONE, 4},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvWoodenPost, MODEL_WOODEN_POST, 0},
|
||||
{bhvWaterBombSpawner, MODEL_NONE, 0},
|
||||
{bhvEnemyLakitu, MODEL_ENEMY_LAKITU, 0},
|
||||
{bhvKoopa, MODEL_KOOPA_WITH_SHELL, 2}, // unused
|
||||
{bhvKoopaRaceEndpoint, MODEL_NONE, 0}, // unused
|
||||
{bhvBobomb, MODEL_BLACK_BOBOMB, 0},
|
||||
{bhvWaterBombCannon, MODEL_CANNON_BASE, 0}, // unused
|
||||
{bhvBobombBuddyOpensCannon, MODEL_BOBOMB_BUDDY, 0}, // unused
|
||||
{bhvWaterBombCannon, MODEL_CANNON_BASE, 0},
|
||||
{bhvBobomb, MODEL_BLACK_BOBOMB, 1},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvUnusedFakeStar, MODEL_UNKNOWN_54, 0}, // unused
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvUnagi, MODEL_UNAGI, 0}, // unused
|
||||
{bhvSushiShark, MODEL_SUSHI, 0}, // unused
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvStaticObject, MODEL_KLEPTO, 0}, // unused
|
||||
{bhvTweester, MODEL_TWEESTER, 0}, // unused
|
||||
{bhvPokey, MODEL_NONE, 0},
|
||||
{bhvPokey, MODEL_NONE, 0}, // unused
|
||||
{bhvToxBox, MODEL_SSL_TOX_BOX, 0}, // unused
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvMontyMole, MODEL_MONTY_MOLE, 0}, // unused
|
||||
{bhvMontyMole, MODEL_MONTY_MOLE, 1},
|
||||
{bhvMontyMoleHole, MODEL_DL_MONTY_MOLE_HOLE, 0},
|
||||
{bhvFlyGuy, MODEL_FLYGUY, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvWigglerHead, MODEL_WIGGLER_HEAD, 0}, // unused
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvSpindrift, MODEL_SPINDRIFT, 0},
|
||||
{bhvMrBlizzard, MODEL_MR_BLIZZARD_HIDDEN, 0},
|
||||
{bhvMrBlizzard, MODEL_MR_BLIZZARD_HIDDEN, 0}, // unused
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvSmallPenguin, MODEL_PENGUIN, 0}, // unused
|
||||
{bhvTuxiesMother, MODEL_PENGUIN, 0}, // unused
|
||||
{bhvTuxiesMother, MODEL_PENGUIN, 0}, // unused
|
||||
{bhvMrBlizzard, MODEL_MR_BLIZZARD_HIDDEN, 1}, // unused
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvHauntedChair, MODEL_HAUNTED_CHAIR, 0}, // unused
|
||||
{bhvHauntedChair, MODEL_HAUNTED_CHAIR, 0},
|
||||
{bhvHauntedChair, MODEL_HAUNTED_CHAIR, 0}, // unused
|
||||
{bhvGhostHuntBoo, MODEL_BOO, 0}, // unused
|
||||
{bhvGhostHuntBoo, MODEL_BOO, 0}, // unused
|
||||
{bhvCourtyardBooTriplet, MODEL_BOO, 0}, // unused
|
||||
{bhvBooWithCage, MODEL_BOO, 0}, // unused
|
||||
{bhvAlphaBooKey, MODEL_BETA_BOO_KEY, 0}, // unused
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvChirpChirp, MODEL_NONE, 0},
|
||||
{bhvSeaweedBundle, MODEL_NONE, 0},
|
||||
{bhvBetaChestBottom, MODEL_TREASURE_CHEST_BASE, 0}, // unused
|
||||
{bhvBowserBomb, MODEL_WATER_MINE, 0}, // unused
|
||||
{bhvLargeFishGroup, MODEL_NONE, 2}, // unused
|
||||
{bhvLargeFishGroup, MODEL_NONE, 3},
|
||||
{bhvJetStreamRingSpawner, MODEL_WATER_RING, 0}, // unused
|
||||
{bhvJetStreamRingSpawner, MODEL_WATER_RING, 0}, // unused
|
||||
{bhvSkeeter, MODEL_SKEETER, 0},
|
||||
{bhvClamShell, MODEL_CLAM_SHELL, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvMacroUkiki, MODEL_UKIKI, 0}, // unused
|
||||
{bhvMacroUkiki, MODEL_UKIKI, 1}, // unused
|
||||
{bhvPiranhaPlant, MODEL_PIRANHA_PLANT, 0}, // unused
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvSmallWhomp, MODEL_WHOMP, 0},
|
||||
{bhvChainChomp, MODEL_CHAIN_CHOMP, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvKoopa, MODEL_KOOPA_WITH_SHELL, 1},
|
||||
{bhvKoopa, MODEL_KOOPA_WITHOUT_SHELL, 0}, // unused
|
||||
{bhvWoodenPost, MODEL_WOODEN_POST, 0}, // unused
|
||||
{bhvFirePiranhaPlant, MODEL_PIRANHA_PLANT, 0},
|
||||
{bhvFirePiranhaPlant, MODEL_PIRANHA_PLANT, 1}, // unused
|
||||
{bhvKoopa, MODEL_KOOPA_WITH_SHELL, 4},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvMoneybagHidden, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvSwoop, MODEL_SWOOP, 0},
|
||||
{bhvSwoop, MODEL_SWOOP, 1},
|
||||
{bhvMrI, MODEL_NONE, 0},
|
||||
{bhvScuttlebugSpawn, MODEL_NONE, 0},
|
||||
{bhvScuttlebug, MODEL_SCUTTLEBUG, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_UNKNOWN_54, 0}, // unused
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvTTCRotatingSolid, MODEL_TTC_ROTATING_CUBE, 0},
|
||||
{bhvTTCRotatingSolid, MODEL_TTC_ROTATING_PRISM, 1},
|
||||
{bhvTTCPendulum, MODEL_TTC_PENDULUM, 0},
|
||||
{bhvTTCTreadmill, MODEL_TTC_LARGE_TREADMILL, 0},
|
||||
{bhvTTCTreadmill, MODEL_TTC_SMALL_TREADMILL, 1},
|
||||
{bhvTTCMovingBar, MODEL_TTC_PUSH_BLOCK, 0},
|
||||
{bhvTTCCog, MODEL_TTC_ROTATING_HEXAGON, 0},
|
||||
{bhvTTCCog, MODEL_TTC_ROTATING_TRIANGLE, 2},
|
||||
{bhvTTCPitBlock, MODEL_TTC_PIT_BLOCK, 0},
|
||||
{bhvTTCPitBlock, MODEL_TTC_PIT_BLOCK_UNUSED, 1}, // unused
|
||||
{bhvTTCElevator, MODEL_TTC_ELEVATOR_PLATFORM, 0},
|
||||
{bhvTTC2DRotator, MODEL_TTC_CLOCK_HAND, 0},
|
||||
{bhvTTCSpinner, MODEL_TTC_SPINNER, 0},
|
||||
{bhvTTC2DRotator, MODEL_TTC_SMALL_GEAR, 1},
|
||||
{bhvTTC2DRotator, MODEL_TTC_LARGE_GEAR, 1},
|
||||
{bhvTTCTreadmill, MODEL_TTC_LARGE_TREADMILL, 2},
|
||||
{bhvTTCTreadmill, MODEL_TTC_SMALL_TREADMILL, 3},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvExclamationBox, MODEL_EXCLAMATION_BOX, 10},
|
||||
{bhvExclamationBox, MODEL_EXCLAMATION_BOX, 11},
|
||||
{bhvExclamationBox, MODEL_EXCLAMATION_BOX, 12},
|
||||
{bhvExclamationBox, MODEL_EXCLAMATION_BOX, 13}, // unused
|
||||
{bhvExclamationBox, MODEL_EXCLAMATION_BOX, 14},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvSlidingPlatform2, MODEL_BITS_SLIDING_PLATFORM, 0}, // unused
|
||||
{bhvSlidingPlatform2, MODEL_BITS_TWIN_SLIDING_PLATFORMS, 0}, // unused
|
||||
{bhvAnotherTiltingPlatform, MODEL_BITDW_SLIDING_PLATFORM, 0}, // unused
|
||||
{bhvOctagonalPlatformRotating, MODEL_BITS_OCTAGONAL_PLATFORM, 0}, // unused
|
||||
{bhvAnimatesOnFloorSwitchPress, MODEL_BITS_STAIRCASE, 0}, // unused
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvFerrisWheelAxle, MODEL_BITS_FERRIS_WHEEL_AXLE, 0}, // unused
|
||||
{bhvActivatedBackAndForthPlatform, MODEL_BITS_ARROW_PLATFORM, 0}, // unused
|
||||
{bhvSeesawPlatform, MODEL_BITS_SEESAW_PLATFORM, 0}, // unused
|
||||
{bhvSeesawPlatform, MODEL_BITS_TILTING_W_PLATFORM, 0}, // unused
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0}
|
||||
};
|
||||
extern struct MacroPreset MacroObjectPresets[];
|
||||
|
||||
#endif // MACRO_PRESETS_H
|
||||
|
|
|
@ -406,7 +406,6 @@
|
|||
#ifndef VERSION_JP
|
||||
#define /*0x1B0*/ oCoinUnk1B0 OBJECT_FIELD_S32(0x4A)
|
||||
#endif
|
||||
#define /*0x110*/ oCoinID OBJECT_FIELD_S16(0x49, 0)
|
||||
|
||||
/* Collision Particle */
|
||||
#define /*0x0F4*/ oCollisionParticleUnkF4 OBJECT_FIELD_F32(0x1B)
|
||||
|
|
|
@ -39,7 +39,7 @@ void bobomb_act_explode(void) {
|
|||
explosion->oGraphYOffset += 100.0f;
|
||||
|
||||
bobomb_spawn_coin();
|
||||
create_respawner(MODEL_BLACK_BOBOMB, bhvBobomb, 3000, o->oSyncID);
|
||||
create_respawner(MODEL_BLACK_BOBOMB, bhvBobomb, 3000);
|
||||
o->activeFlags = ACTIVE_FLAG_DEACTIVATED;
|
||||
}
|
||||
}
|
||||
|
@ -130,12 +130,12 @@ void generic_bobomb_free_loop(void) {
|
|||
|
||||
case BOBOMB_ACT_LAVA_DEATH:
|
||||
if (obj_lava_death() == 1)
|
||||
create_respawner(MODEL_BLACK_BOBOMB, bhvBobomb, 3000, o->oSyncID);
|
||||
create_respawner(MODEL_BLACK_BOBOMB, bhvBobomb, 3000);
|
||||
break;
|
||||
|
||||
case BOBOMB_ACT_DEATH_PLANE_DEATH:
|
||||
o->activeFlags = ACTIVE_FLAG_DEACTIVATED;
|
||||
create_respawner(MODEL_BLACK_BOBOMB, bhvBobomb, 3000, o->oSyncID);
|
||||
create_respawner(MODEL_BLACK_BOBOMB, bhvBobomb, 3000);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -157,12 +157,12 @@ void stationary_bobomb_free_loop(void) {
|
|||
|
||||
case BOBOMB_ACT_LAVA_DEATH:
|
||||
if (obj_lava_death() == 1)
|
||||
create_respawner(MODEL_BLACK_BOBOMB, bhvBobomb, 3000, o->oSyncID);
|
||||
create_respawner(MODEL_BLACK_BOBOMB, bhvBobomb, 3000);
|
||||
break;
|
||||
|
||||
case BOBOMB_ACT_DEATH_PLANE_DEATH:
|
||||
o->activeFlags = ACTIVE_FLAG_DEACTIVATED;
|
||||
create_respawner(MODEL_BLACK_BOBOMB, bhvBobomb, 3000, o->oSyncID);
|
||||
create_respawner(MODEL_BLACK_BOBOMB, bhvBobomb, 3000);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -70,7 +70,7 @@ void breakable_box_small_released_loop(void) {
|
|||
|
||||
// Despawn, and create a corkbox respawner
|
||||
if (o->oBreakableBoxSmallFramesSinceReleased > 900) {
|
||||
create_respawner(MODEL_BREAKABLE_BOX_SMALL, bhvBreakableBoxSmall, 3000, o->oSyncID);
|
||||
create_respawner(MODEL_BREAKABLE_BOX_SMALL, bhvBreakableBoxSmall, 3000);
|
||||
o->activeFlags = ACTIVE_FLAG_DEACTIVATED;
|
||||
}
|
||||
}
|
||||
|
@ -87,7 +87,7 @@ void breakable_box_small_idle_loop(void) {
|
|||
|
||||
case 101:
|
||||
o->activeFlags = ACTIVE_FLAG_DEACTIVATED;
|
||||
create_respawner(MODEL_BREAKABLE_BOX_SMALL, bhvBreakableBoxSmall, 3000, o->oSyncID);
|
||||
create_respawner(MODEL_BREAKABLE_BOX_SMALL, bhvBreakableBoxSmall, 3000);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -42,23 +42,30 @@ void bhv_respawner_loop(void) {
|
|||
struct Object *spawnedObject;
|
||||
|
||||
if (!is_point_within_radius_of_mario(o->oPosX, o->oPosY, o->oPosZ, o->oRespawnerMinSpawnDist)) {
|
||||
u32 syncID = o->oSyncID;
|
||||
spawnedObject = spawn_object(o, o->oRespawnerModelToRespawn, o->oRespawnerBehaviorToRespawn);
|
||||
spawnedObject->oBehParams = o->oBehParams;
|
||||
spawnedObject->oSyncID = o->oSyncID;
|
||||
spawnedObject->oSyncID = syncID;
|
||||
network_override_object(syncID, spawnedObject);
|
||||
o->oSyncID = 0;
|
||||
|
||||
o->activeFlags = ACTIVE_FLAG_DEACTIVATED;
|
||||
}
|
||||
}
|
||||
|
||||
void create_respawner(s32 model, const BehaviorScript *behToSpawn, s32 minSpawnDist, u32 syncID) {
|
||||
void create_respawner(s32 model, const BehaviorScript *behToSpawn, s32 minSpawnDist) {
|
||||
struct Object *respawner = spawn_object_abs_with_rot(o, 0, MODEL_NONE, bhvRespawner, o->oHomeX,
|
||||
o->oHomeY, o->oHomeZ, 0, 0, 0);
|
||||
u8 syncID = o->oSyncID;
|
||||
respawner->oBehParams = o->oBehParams;
|
||||
respawner->oRespawnerModelToRespawn = model;
|
||||
respawner->oRespawnerMinSpawnDist = minSpawnDist;
|
||||
respawner->oRespawnerBehaviorToRespawn = behToSpawn;
|
||||
respawner->oSyncID = syncID;
|
||||
|
||||
network_forget_sync_object(&gSyncObjects[syncID]);
|
||||
network_init_object(respawner, SYNC_DISTANCE_ONLY_EVENTS);
|
||||
o->oSyncID = 0;
|
||||
if (gSyncObjects[syncID].staticLevelSpawn) {
|
||||
network_override_object(syncID, respawner);
|
||||
o->oSyncID = 0;
|
||||
o->oFlags |= OBJ_FLAG_PERSISTENT_RESPAWN; // pretty sure this is required
|
||||
}
|
||||
}
|
||||
|
|
|
@ -103,7 +103,7 @@ void snowmans_bottom_act_2(void) {
|
|||
}
|
||||
|
||||
if (o->oTimer == 200) {
|
||||
create_respawner(MODEL_CCM_SNOWMAN_BASE, bhvSnowmansBottom, 3000, o->oSyncID);
|
||||
create_respawner(MODEL_CCM_SNOWMAN_BASE, bhvSnowmansBottom, 3000);
|
||||
o->activeFlags = ACTIVE_FLAG_DEACTIVATED;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ void yoshi_walk_loop(void) {
|
|||
o->oAction = YOSHI_ACT_TALK;
|
||||
|
||||
if (o->oPosY < 2100.0f) {
|
||||
create_respawner(MODEL_YOSHI, bhvYoshi, 3000, o->oSyncID);
|
||||
create_respawner(MODEL_YOSHI, bhvYoshi, 3000);
|
||||
o->activeFlags = ACTIVE_FLAG_DEACTIVATED;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -838,9 +838,6 @@ u32 interact_coin(struct MarioState *m, UNUSED u32 interactType, struct Object *
|
|||
}
|
||||
|
||||
network_send_collect_coin(o);
|
||||
if (o->oCoinID > 0) {
|
||||
coin_collection_remember(o->oCoinID);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
|
370
src/game/macro_presets.c
Normal file
370
src/game/macro_presets.c
Normal file
|
@ -0,0 +1,370 @@
|
|||
#include "macro_presets.h"
|
||||
|
||||
struct MacroPreset MacroObjectPresets[] = {
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvOneCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvMovingBlueCoin, MODEL_BLUE_COIN, 0},
|
||||
{bhvBlueCoinSliding, MODEL_BLUE_COIN, 0}, // unused
|
||||
{bhvRedCoin, MODEL_RED_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvCoinFormation, MODEL_NONE, 0},
|
||||
{bhvCoinFormation, MODEL_NONE, COIN_FORMATION_FLAG_RING},
|
||||
{bhvCoinFormation, MODEL_NONE, COIN_FORMATION_FLAG_ARROW},
|
||||
{bhvCoinFormation, MODEL_NONE, COIN_FORMATION_FLAG_FLYING},
|
||||
{bhvCoinFormation, MODEL_NONE, COIN_FORMATION_FLAG_FLYING | COIN_FORMATION_FLAG_VERTICAL},
|
||||
{bhvCoinFormation, MODEL_NONE, COIN_FORMATION_FLAG_FLYING | COIN_FORMATION_FLAG_RING},
|
||||
{bhvCoinFormation, MODEL_NONE, COIN_FORMATION_FLAG_FLYING | COIN_FORMATION_FLAG_RING | COIN_FORMATION_FLAG_VERTICAL},
|
||||
{bhvCoinFormation, MODEL_NONE, COIN_FORMATION_FLAG_FLYING | COIN_FORMATION_FLAG_ARROW}, // unused
|
||||
{bhvHiddenStarTrigger, MODEL_NONE, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvUnusedFakeStar, MODEL_STAR, 0}, // unused
|
||||
{bhvMessagePanel, MODEL_WOODEN_SIGNPOST, 0},
|
||||
{bhvCannonClosed, MODEL_DL_CANNON_LID, 0},
|
||||
{bhvBobombBuddyOpensCannon, MODEL_BOBOMB_BUDDY, 0},
|
||||
{bhvButterfly, MODEL_BUTTERFLY, 0}, // unused
|
||||
{bhvBouncingFireball, MODEL_NONE, 0}, // unused
|
||||
{bhvLargeFishGroup, MODEL_NONE, 0}, // unused
|
||||
{bhvLargeFishGroup, MODEL_NONE, 1},
|
||||
{bhvBetaFishSplashSpawner, MODEL_NONE, 0},
|
||||
{bhvHidden1upInPoleSpawner, MODEL_NONE, 0},
|
||||
{bhvGoomba, MODEL_GOOMBA, 1},
|
||||
{bhvGoomba, MODEL_GOOMBA, 2},
|
||||
{bhvGoombaTripletSpawner, MODEL_NONE, 0},
|
||||
{bhvGoombaTripletSpawner, MODEL_NONE, 8}, // unused
|
||||
{bhvSignOnWall, MODEL_NONE, 0},
|
||||
{bhvChuckya, MODEL_CHUCKYA, 0},
|
||||
{bhvCannon, MODEL_CANNON_BASE, 0},
|
||||
{bhvGoomba, MODEL_GOOMBA, 0},
|
||||
{bhvHomingAmp, MODEL_AMP, 0},
|
||||
{bhvCirclingAmp, MODEL_AMP, 0},
|
||||
{bhvCarrySomething1, MODEL_UNKNOWN_7D, 0}, // unused
|
||||
{bhvBetaTrampolineTop, MODEL_TRAMPOLINE, 0}, // unused
|
||||
{bhvFreeBowlingBall, MODEL_BOWLING_BALL, 0}, // unused
|
||||
{bhvSnufit, MODEL_SNUFIT, 0},
|
||||
{bhvRecoveryHeart, MODEL_HEART, 0},
|
||||
{bhv1upSliding, MODEL_1UP, 0},
|
||||
{bhv1Up, MODEL_1UP, 0},
|
||||
{bhv1upJumpOnApproach, MODEL_1UP, 0}, // unused
|
||||
{bhvHidden1up, MODEL_1UP, 0},
|
||||
{bhvHidden1upTrigger, MODEL_NONE, 0},
|
||||
{bhv1Up, MODEL_1UP, 1},
|
||||
{bhv1Up, MODEL_1UP, 2},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvBlueCoinSwitch, MODEL_BLUE_COIN_SWITCH, 0},
|
||||
{bhvHiddenBlueCoin, MODEL_BLUE_COIN, 0},
|
||||
{bhvCapSwitch, MODEL_CAP_SWITCH, 0}, // unused
|
||||
{bhvCapSwitch, MODEL_CAP_SWITCH, 1}, // unused
|
||||
{bhvCapSwitch, MODEL_CAP_SWITCH, 2}, // unused
|
||||
{bhvCapSwitch, MODEL_CAP_SWITCH, 3}, // unused
|
||||
{bhvWaterLevelDiamond, MODEL_BREAKABLE_BOX, 0}, // unused
|
||||
{bhvExclamationBox, MODEL_EXCLAMATION_BOX, 0},
|
||||
{bhvExclamationBox, MODEL_EXCLAMATION_BOX, 1},
|
||||
{bhvExclamationBox, MODEL_EXCLAMATION_BOX, 2},
|
||||
{bhvExclamationBox, MODEL_EXCLAMATION_BOX, 3},
|
||||
{bhvExclamationBox, MODEL_EXCLAMATION_BOX, 4}, // unused
|
||||
{bhvExclamationBox, MODEL_EXCLAMATION_BOX, 5},
|
||||
{bhvExclamationBox, MODEL_EXCLAMATION_BOX, 6},
|
||||
{bhvExclamationBox, MODEL_EXCLAMATION_BOX, 7},
|
||||
{bhvExclamationBox, MODEL_EXCLAMATION_BOX, 8},
|
||||
{bhvBreakableBox, MODEL_BREAKABLE_BOX, 0},
|
||||
{bhvBreakableBox, MODEL_BREAKABLE_BOX, 1},
|
||||
{bhvPushableMetalBox, MODEL_METAL_BOX, 0},
|
||||
{bhvBreakableBoxSmall, MODEL_BREAKABLE_BOX_SMALL, 0},
|
||||
{bhvFloorSwitchHiddenObjects, MODEL_PURPLE_SWITCH, 0},
|
||||
{bhvHiddenObject, MODEL_BREAKABLE_BOX, 0},
|
||||
{bhvHiddenObject, MODEL_BREAKABLE_BOX, 1}, // unused
|
||||
{bhvHiddenObject, MODEL_BREAKABLE_BOX, 2}, // unused
|
||||
{bhvBreakableBox, MODEL_BREAKABLE_BOX, 3},
|
||||
{bhvKoopaShellUnderwater, MODEL_KOOPA_SHELL, 0},
|
||||
{bhvExclamationBox, MODEL_EXCLAMATION_BOX, 9},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvBulletBill, MODEL_BULLET_BILL, 0}, // unused
|
||||
{bhvHeaveHo, MODEL_HEAVE_HO, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvThwomp2, MODEL_THWOMP, 0}, // unused
|
||||
{bhvFireSpitter, MODEL_BOWLING_BALL, 0},
|
||||
{bhvFlyGuy, MODEL_FLYGUY, 1},
|
||||
{bhvJumpingBox, MODEL_BREAKABLE_BOX, 0},
|
||||
{bhvTripletButterfly, MODEL_BUTTERFLY, 0},
|
||||
{bhvTripletButterfly, MODEL_BUTTERFLY, 4},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvSmallBully, MODEL_BULLY, 0},
|
||||
{bhvSmallBully, MODEL_BULLY_BOSS, 0}, // unused
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvStub1D0C, MODEL_UNKNOWN_58, 0}, // unused
|
||||
{bhvBouncingFireball, MODEL_NONE, 0},
|
||||
{bhvFlamethrower, MODEL_NONE, 4},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvWoodenPost, MODEL_WOODEN_POST, 0},
|
||||
{bhvWaterBombSpawner, MODEL_NONE, 0},
|
||||
{bhvEnemyLakitu, MODEL_ENEMY_LAKITU, 0},
|
||||
{bhvKoopa, MODEL_KOOPA_WITH_SHELL, 2}, // unused
|
||||
{bhvKoopaRaceEndpoint, MODEL_NONE, 0}, // unused
|
||||
{bhvBobomb, MODEL_BLACK_BOBOMB, 0},
|
||||
{bhvWaterBombCannon, MODEL_CANNON_BASE, 0}, // unused
|
||||
{bhvBobombBuddyOpensCannon, MODEL_BOBOMB_BUDDY, 0}, // unused
|
||||
{bhvWaterBombCannon, MODEL_CANNON_BASE, 0},
|
||||
{bhvBobomb, MODEL_BLACK_BOBOMB, 1},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvUnusedFakeStar, MODEL_UNKNOWN_54, 0}, // unused
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvUnagi, MODEL_UNAGI, 0}, // unused
|
||||
{bhvSushiShark, MODEL_SUSHI, 0}, // unused
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvStaticObject, MODEL_KLEPTO, 0}, // unused
|
||||
{bhvTweester, MODEL_TWEESTER, 0}, // unused
|
||||
{bhvPokey, MODEL_NONE, 0},
|
||||
{bhvPokey, MODEL_NONE, 0}, // unused
|
||||
{bhvToxBox, MODEL_SSL_TOX_BOX, 0}, // unused
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvMontyMole, MODEL_MONTY_MOLE, 0}, // unused
|
||||
{bhvMontyMole, MODEL_MONTY_MOLE, 1},
|
||||
{bhvMontyMoleHole, MODEL_DL_MONTY_MOLE_HOLE, 0},
|
||||
{bhvFlyGuy, MODEL_FLYGUY, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvWigglerHead, MODEL_WIGGLER_HEAD, 0}, // unused
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvSpindrift, MODEL_SPINDRIFT, 0},
|
||||
{bhvMrBlizzard, MODEL_MR_BLIZZARD_HIDDEN, 0},
|
||||
{bhvMrBlizzard, MODEL_MR_BLIZZARD_HIDDEN, 0}, // unused
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvSmallPenguin, MODEL_PENGUIN, 0}, // unused
|
||||
{bhvTuxiesMother, MODEL_PENGUIN, 0}, // unused
|
||||
{bhvTuxiesMother, MODEL_PENGUIN, 0}, // unused
|
||||
{bhvMrBlizzard, MODEL_MR_BLIZZARD_HIDDEN, 1}, // unused
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvHauntedChair, MODEL_HAUNTED_CHAIR, 0}, // unused
|
||||
{bhvHauntedChair, MODEL_HAUNTED_CHAIR, 0},
|
||||
{bhvHauntedChair, MODEL_HAUNTED_CHAIR, 0}, // unused
|
||||
{bhvGhostHuntBoo, MODEL_BOO, 0}, // unused
|
||||
{bhvGhostHuntBoo, MODEL_BOO, 0}, // unused
|
||||
{bhvCourtyardBooTriplet, MODEL_BOO, 0}, // unused
|
||||
{bhvBooWithCage, MODEL_BOO, 0}, // unused
|
||||
{bhvAlphaBooKey, MODEL_BETA_BOO_KEY, 0}, // unused
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvChirpChirp, MODEL_NONE, 0},
|
||||
{bhvSeaweedBundle, MODEL_NONE, 0},
|
||||
{bhvBetaChestBottom, MODEL_TREASURE_CHEST_BASE, 0}, // unused
|
||||
{bhvBowserBomb, MODEL_WATER_MINE, 0}, // unused
|
||||
{bhvLargeFishGroup, MODEL_NONE, 2}, // unused
|
||||
{bhvLargeFishGroup, MODEL_NONE, 3},
|
||||
{bhvJetStreamRingSpawner, MODEL_WATER_RING, 0}, // unused
|
||||
{bhvJetStreamRingSpawner, MODEL_WATER_RING, 0}, // unused
|
||||
{bhvSkeeter, MODEL_SKEETER, 0},
|
||||
{bhvClamShell, MODEL_CLAM_SHELL, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvMacroUkiki, MODEL_UKIKI, 0}, // unused
|
||||
{bhvMacroUkiki, MODEL_UKIKI, 1}, // unused
|
||||
{bhvPiranhaPlant, MODEL_PIRANHA_PLANT, 0}, // unused
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvSmallWhomp, MODEL_WHOMP, 0},
|
||||
{bhvChainChomp, MODEL_CHAIN_CHOMP, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvKoopa, MODEL_KOOPA_WITH_SHELL, 1},
|
||||
{bhvKoopa, MODEL_KOOPA_WITHOUT_SHELL, 0}, // unused
|
||||
{bhvWoodenPost, MODEL_WOODEN_POST, 0}, // unused
|
||||
{bhvFirePiranhaPlant, MODEL_PIRANHA_PLANT, 0},
|
||||
{bhvFirePiranhaPlant, MODEL_PIRANHA_PLANT, 1}, // unused
|
||||
{bhvKoopa, MODEL_KOOPA_WITH_SHELL, 4},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvMoneybagHidden, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvSwoop, MODEL_SWOOP, 0},
|
||||
{bhvSwoop, MODEL_SWOOP, 1},
|
||||
{bhvMrI, MODEL_NONE, 0},
|
||||
{bhvScuttlebugSpawn, MODEL_NONE, 0},
|
||||
{bhvScuttlebug, MODEL_SCUTTLEBUG, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_UNKNOWN_54, 0}, // unused
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvTTCRotatingSolid, MODEL_TTC_ROTATING_CUBE, 0},
|
||||
{bhvTTCRotatingSolid, MODEL_TTC_ROTATING_PRISM, 1},
|
||||
{bhvTTCPendulum, MODEL_TTC_PENDULUM, 0},
|
||||
{bhvTTCTreadmill, MODEL_TTC_LARGE_TREADMILL, 0},
|
||||
{bhvTTCTreadmill, MODEL_TTC_SMALL_TREADMILL, 1},
|
||||
{bhvTTCMovingBar, MODEL_TTC_PUSH_BLOCK, 0},
|
||||
{bhvTTCCog, MODEL_TTC_ROTATING_HEXAGON, 0},
|
||||
{bhvTTCCog, MODEL_TTC_ROTATING_TRIANGLE, 2},
|
||||
{bhvTTCPitBlock, MODEL_TTC_PIT_BLOCK, 0},
|
||||
{bhvTTCPitBlock, MODEL_TTC_PIT_BLOCK_UNUSED, 1}, // unused
|
||||
{bhvTTCElevator, MODEL_TTC_ELEVATOR_PLATFORM, 0},
|
||||
{bhvTTC2DRotator, MODEL_TTC_CLOCK_HAND, 0},
|
||||
{bhvTTCSpinner, MODEL_TTC_SPINNER, 0},
|
||||
{bhvTTC2DRotator, MODEL_TTC_SMALL_GEAR, 1},
|
||||
{bhvTTC2DRotator, MODEL_TTC_LARGE_GEAR, 1},
|
||||
{bhvTTCTreadmill, MODEL_TTC_LARGE_TREADMILL, 2},
|
||||
{bhvTTCTreadmill, MODEL_TTC_SMALL_TREADMILL, 3},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvExclamationBox, MODEL_EXCLAMATION_BOX, 10},
|
||||
{bhvExclamationBox, MODEL_EXCLAMATION_BOX, 11},
|
||||
{bhvExclamationBox, MODEL_EXCLAMATION_BOX, 12},
|
||||
{bhvExclamationBox, MODEL_EXCLAMATION_BOX, 13}, // unused
|
||||
{bhvExclamationBox, MODEL_EXCLAMATION_BOX, 14},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvSlidingPlatform2, MODEL_BITS_SLIDING_PLATFORM, 0}, // unused
|
||||
{bhvSlidingPlatform2, MODEL_BITS_TWIN_SLIDING_PLATFORMS, 0}, // unused
|
||||
{bhvAnotherTiltingPlatform, MODEL_BITDW_SLIDING_PLATFORM, 0}, // unused
|
||||
{bhvOctagonalPlatformRotating, MODEL_BITS_OCTAGONAL_PLATFORM, 0}, // unused
|
||||
{bhvAnimatesOnFloorSwitchPress, MODEL_BITS_STAIRCASE, 0}, // unused
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvFerrisWheelAxle, MODEL_BITS_FERRIS_WHEEL_AXLE, 0}, // unused
|
||||
{bhvActivatedBackAndForthPlatform, MODEL_BITS_ARROW_PLATFORM, 0}, // unused
|
||||
{bhvSeesawPlatform, MODEL_BITS_SEESAW_PLATFORM, 0}, // unused
|
||||
{bhvSeesawPlatform, MODEL_BITS_TILTING_W_PLATFORM, 0}, // unused
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0},
|
||||
{bhvYellowCoin, MODEL_YELLOW_COIN, 0}
|
||||
};
|
|
@ -87,7 +87,7 @@ void bhv_bobomb_bully_death_smoke_init(void);
|
|||
void bhv_bobomb_explosion_bubble_init(void);
|
||||
void bhv_bobomb_explosion_bubble_loop(void);
|
||||
void bhv_respawner_loop(void);
|
||||
void create_respawner(s32 arg0, const BehaviorScript *behToSpawn, s32 minSpawnDist, u32 syncID);
|
||||
void create_respawner(s32 arg0, const BehaviorScript *behToSpawn, s32 minSpawnDist);
|
||||
void bhv_small_bully_init(void);
|
||||
void bhv_big_bully_init(void);
|
||||
void bully_check_mario_collision(void);
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
#ifdef DEBUG
|
||||
|
||||
static u8 warpToLevel = LEVEL_BOB;
|
||||
static u8 warpToLevel = LEVEL_CCM;
|
||||
|
||||
#define SCANCODE_0 0x0B
|
||||
#define SCANCODE_1 0x02
|
||||
|
|
|
@ -100,15 +100,6 @@ void network_on_loaded_level(void) {
|
|||
gSyncObjects[i].staticLevelSpawn = true;
|
||||
}
|
||||
|
||||
// give all coins an ID
|
||||
u8 coinId = 0;
|
||||
for (int i = 0; i < OBJECT_POOL_CAPACITY; i++) {
|
||||
struct Object* o = &gObjectPool[i];
|
||||
if (o->activeFlags & ACTIVE_FLAG_DEACTIVATED) { continue; }
|
||||
if (!is_behavior_a_coin(o->behavior)) { continue; }
|
||||
o->oCoinID = ++coinId;
|
||||
}
|
||||
|
||||
// check for level change
|
||||
struct NetworkPlayer* np = gNetworkPlayerLocal;
|
||||
if (np != NULL) {
|
||||
|
|
|
@ -33,6 +33,20 @@ struct NetworkPlayer* network_player_from_global_index(u8 globalIndex) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
struct NetworkPlayer* get_network_player_from_valid_location(s16 courseNum, s16 actNum, s16 levelNum, s16 areaIndex) {
|
||||
for (int i = 0; i < MAX_PLAYERS; i++) {
|
||||
struct NetworkPlayer* np = &gNetworkPlayers[i];
|
||||
if (!np->connected) { continue; }
|
||||
if (!np->currAreaSyncValid) { continue; }
|
||||
if (np->currCourseNum != courseNum) { continue; }
|
||||
if (np->currActNum != actNum) { continue; }
|
||||
if (np->currLevelNum != levelNum) { continue; }
|
||||
if (np->currAreaIndex != areaIndex) { continue; }
|
||||
return np;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void network_player_update(void) {
|
||||
float elapsed = (clock() - gLastNetworkSend) / (float)CLOCKS_PER_SEC;
|
||||
if (elapsed > NETWORK_PLAYER_TIMEOUT / 3.0f) {
|
||||
|
|
|
@ -41,6 +41,7 @@ extern struct NetworkPlayer* gNetworkPlayerServer;
|
|||
bool network_player_any_connected(void);
|
||||
u8 network_player_connected_count(void);
|
||||
struct NetworkPlayer* network_player_from_global_index(u8 globalIndex);
|
||||
struct NetworkPlayer* get_network_player_from_valid_location(s16 courseNum, s16 actNum, s16 levelNum, s16 areaIndex);
|
||||
void network_player_update(void);
|
||||
u8 network_player_connected(enum NetworkPlayerType type, u8 globalIndex);
|
||||
u8 network_player_disconnected(u8 globalIndex);
|
||||
|
|
|
@ -62,8 +62,10 @@ void packet_receive(struct Packet* p) {
|
|||
case PACKET_LEVEL_AREA: network_receive_level_area(p); break;
|
||||
case PACKET_LEVEL_AREA_VALID: network_receive_level_area_valid(p); break;
|
||||
case PACKET_LOCATION_REQUEST: network_receive_location_request(p); break;
|
||||
case PACKET_CLIENT_LOCATION_REQUEST: network_receive_client_location_request(p); break;
|
||||
case PACKET_LOCATION_REQUEST_CLIENT: network_receive_location_request_client(p); break;
|
||||
case PACKET_LOCATION_RESPONSE: network_receive_location_response(p); break;
|
||||
case PACKET_MACRO_DELETIONS: network_receive_macro_deletions(p); break;
|
||||
case PACKET_SPAWN_INFO_DELETIONS: network_receive_spawn_info_deletions(p); break;
|
||||
///
|
||||
case PACKET_CUSTOM: network_receive_custom(p); break;
|
||||
default: LOG_ERROR("received unknown packet: %d", p->buffer[0]);
|
||||
|
|
|
@ -34,8 +34,10 @@ enum PacketType {
|
|||
PACKET_LEVEL_AREA,
|
||||
PACKET_LEVEL_AREA_VALID,
|
||||
PACKET_LOCATION_REQUEST,
|
||||
PACKET_CLIENT_LOCATION_REQUEST,
|
||||
PACKET_LOCATION_REQUEST_CLIENT,
|
||||
PACKET_LOCATION_RESPONSE,
|
||||
PACKET_MACRO_DELETIONS,
|
||||
PACKET_SPAWN_INFO_DELETIONS,
|
||||
///
|
||||
PACKET_CUSTOM = 255,
|
||||
};
|
||||
|
@ -87,6 +89,7 @@ void network_receive_player(struct Packet* p);
|
|||
// packet_object.c
|
||||
struct Packet* get_last_sync_ent_reliable_packet(u8 syncId);
|
||||
void forget_ent_reliable_packet(struct Object* o);
|
||||
void network_override_object(u8 syncId, struct Object* o);
|
||||
struct SyncObject* network_init_object(struct Object* object, float maxSyncDistance);
|
||||
void network_init_object_field(struct Object* o, void* field);
|
||||
bool network_owns_object(struct Object* o);
|
||||
|
@ -174,15 +177,23 @@ void network_send_level_area_valid(u8 toGlobalIndex);
|
|||
void network_receive_level_area_valid(struct Packet* p);
|
||||
|
||||
// packet_location_request.c
|
||||
void coin_collection_remember(u8 coinId);
|
||||
void coin_collection_clear(void);
|
||||
void static_spawn_removal_remember(u8 syncId);
|
||||
void static_spawn_removal_clear(void);
|
||||
void network_send_location_request(void);
|
||||
void network_receive_location_request(struct Packet* p);
|
||||
void network_send_client_location_request(u8 destGlobalIndex, u8 srcGlobalIndex);
|
||||
void network_receive_client_location_request(struct Packet* p);
|
||||
|
||||
// packet_location_request_client.c
|
||||
void network_send_location_request_client(u8 destGlobalIndex, u8 srcGlobalIndex);
|
||||
void network_receive_location_request_client(struct Packet* p);
|
||||
|
||||
// packet_location_response.c
|
||||
void network_send_location_response(u8 destGlobalIndex);
|
||||
void network_receive_location_response(struct Packet* p);
|
||||
|
||||
// packet_macro_deletions.c
|
||||
void network_send_macro_deletions(u8 destGlobalIndex);
|
||||
void network_receive_macro_deletions(struct Packet* p);
|
||||
|
||||
// packet_spawn_info_deletions.c
|
||||
void network_send_spawn_info_deletions(u8 destGlobalIndex);
|
||||
void network_receive_spawn_info_deletions(struct Packet* p);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,62 +1,10 @@
|
|||
#include <stdio.h>
|
||||
#include "../network.h"
|
||||
#include "menu/custom_menu_system.h"
|
||||
#include "game/interaction.h"
|
||||
#include "game/object_list_processor.h"
|
||||
#include "game/object_helpers.h"
|
||||
#include "game/interaction.h"
|
||||
#include "game/level_update.h"
|
||||
#include "object_constants.h"
|
||||
#include "object_fields.h"
|
||||
#include "behavior_table.h"
|
||||
#include "model_ids.h"
|
||||
//#define DISABLE_MODULE_LOG 1
|
||||
#include "pc/debuglog.h"
|
||||
|
||||
extern s16 gCurrCourseNum, gCurrActNum, gCurrLevelNum, gCurrAreaIndex;
|
||||
|
||||
#define MAX_STATIC_SPAWN_REMOVAL 256
|
||||
u8 sStaticSpawnRemoval[MAX_STATIC_SPAWN_REMOVAL] = { 0 };
|
||||
u8 sStaticSpawnRemovalIndex = 0;
|
||||
|
||||
#define MAX_COIN_COLLECTION 128
|
||||
u8 sCoinCollection[MAX_STATIC_SPAWN_REMOVAL] = { 0 };
|
||||
u8 sCoinCollectionIndex = 0;
|
||||
|
||||
void coin_collection_remember(u8 coinId) {
|
||||
sCoinCollection[sCoinCollectionIndex++] = coinId;
|
||||
if (sStaticSpawnRemovalIndex >= MAX_COIN_COLLECTION) { sStaticSpawnRemovalIndex = MAX_COIN_COLLECTION - 1; }
|
||||
}
|
||||
|
||||
void coin_collection_clear(void) {
|
||||
sCoinCollectionIndex = 0;
|
||||
}
|
||||
|
||||
void static_spawn_removal_remember(u8 syncId) {
|
||||
sStaticSpawnRemoval[sStaticSpawnRemovalIndex++] = syncId;
|
||||
if (sStaticSpawnRemovalIndex == 0) { sStaticSpawnRemovalIndex = MAX_STATIC_SPAWN_REMOVAL - 1; }
|
||||
}
|
||||
|
||||
void static_spawn_removal_clear(void) {
|
||||
sStaticSpawnRemovalIndex = 0;
|
||||
}
|
||||
|
||||
struct NetworkPlayer* get_network_player_from_valid_location(s16 courseNum, s16 actNum, s16 levelNum, s16 areaIndex) {
|
||||
for (int i = 0; i < MAX_PLAYERS; i++) {
|
||||
struct NetworkPlayer* np = &gNetworkPlayers[i];
|
||||
if (!np->connected) { continue; }
|
||||
if (!np->currAreaSyncValid) { continue; }
|
||||
if (np->currCourseNum != courseNum) { continue; }
|
||||
if (np->currActNum != actNum) { continue; }
|
||||
if (np->currLevelNum != levelNum) { continue; }
|
||||
if (np->currAreaIndex != areaIndex) { continue; }
|
||||
return np;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void network_send_location_request(void) {
|
||||
if (gNetworkType == NT_SERVER) {
|
||||
struct NetworkPlayer* np = get_network_player_from_valid_location(gCurrCourseNum, gCurrActNum, gCurrLevelNum, gCurrAreaIndex);
|
||||
|
@ -64,7 +12,7 @@ void network_send_location_request(void) {
|
|||
gNetworkPlayerLocal->currAreaSyncValid = true;
|
||||
return;
|
||||
}
|
||||
network_send_client_location_request(gNetworkPlayerLocal->globalIndex, np->globalIndex);
|
||||
network_send_location_request_client(gNetworkPlayerLocal->globalIndex, np->globalIndex);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -107,263 +55,6 @@ void network_receive_location_request(struct Packet* p) {
|
|||
} else if (np2 == gNetworkPlayerLocal) {
|
||||
network_send_location_response(np->globalIndex);
|
||||
} else {
|
||||
network_send_client_location_request(np->globalIndex, np2->globalIndex);
|
||||
network_send_location_request_client(np->globalIndex, np2->globalIndex);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void network_send_client_location_request(u8 destGlobalIndex, u8 srcGlobalIndex) {
|
||||
if (gNetworkType != NT_SERVER) {
|
||||
LOG_ERROR("client can't send a 'client location request'");
|
||||
return;
|
||||
}
|
||||
|
||||
struct NetworkPlayer* destNp = network_player_from_global_index(destGlobalIndex);
|
||||
if (destNp == NULL || !destNp->connected) {
|
||||
LOG_ERROR("network_send_client_location_request: dest np is invalid (global %d)", destGlobalIndex);
|
||||
return;
|
||||
}
|
||||
|
||||
struct Packet p;
|
||||
packet_init(&p, PACKET_CLIENT_LOCATION_REQUEST, true, false);
|
||||
packet_write(&p, &destGlobalIndex, sizeof(u8));
|
||||
packet_write(&p, &destNp->currCourseNum, sizeof(s16));
|
||||
packet_write(&p, &destNp->currActNum, sizeof(s16));
|
||||
packet_write(&p, &destNp->currLevelNum, sizeof(s16));
|
||||
packet_write(&p, &destNp->currAreaIndex, sizeof(s16));
|
||||
|
||||
struct NetworkPlayer* srcNp = network_player_from_global_index(srcGlobalIndex);
|
||||
if (srcNp == NULL || !srcNp->connected || !srcNp->currAreaSyncValid) {
|
||||
LOG_ERROR("network_send_client_location_request: source np is invalid (global %d)", srcGlobalIndex);
|
||||
return;
|
||||
}
|
||||
|
||||
network_send_to(srcNp->localIndex, &p);
|
||||
}
|
||||
|
||||
void network_receive_client_location_request(struct Packet* p) {
|
||||
if (gNetworkType == NT_SERVER) {
|
||||
LOG_ERROR("server is receiving a 'client location request'!");
|
||||
return;
|
||||
}
|
||||
|
||||
u8 destGlobalIndex;
|
||||
s16 courseNum, actNum, levelNum, areaIndex;
|
||||
packet_read(p, &destGlobalIndex, sizeof(u8));
|
||||
packet_read(p, &courseNum, sizeof(s16));
|
||||
packet_read(p, &actNum, sizeof(s16));
|
||||
packet_read(p, &levelNum, sizeof(s16));
|
||||
packet_read(p, &areaIndex, sizeof(s16));
|
||||
|
||||
if (courseNum != gCurrCourseNum || actNum != gCurrActNum || levelNum != gCurrLevelNum || areaIndex != gCurrAreaIndex) {
|
||||
LOG_ERROR("Receiving 'client location request' with the wrong location!");
|
||||
return;
|
||||
}
|
||||
|
||||
network_send_location_response(destGlobalIndex);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void network_send_location_response(u8 destGlobalIndex) {
|
||||
if (!gNetworkPlayerLocal->currAreaSyncValid) {
|
||||
LOG_ERROR("my area is invalid");
|
||||
return;
|
||||
}
|
||||
|
||||
struct NetworkPlayer* destNp = network_player_from_global_index(destGlobalIndex);
|
||||
if (destNp == NULL || !destNp->connected) {
|
||||
LOG_ERROR("network_send_location_response: dest np is invalid");
|
||||
return;
|
||||
}
|
||||
|
||||
struct Packet p;
|
||||
packet_init(&p, PACKET_LOCATION_RESPONSE, true, false);
|
||||
packet_write(&p, &gCurrCourseNum, sizeof(s16));
|
||||
packet_write(&p, &gCurrActNum, sizeof(s16));
|
||||
packet_write(&p, &gCurrLevelNum, sizeof(s16));
|
||||
packet_write(&p, &gCurrAreaIndex, sizeof(s16));
|
||||
|
||||
// level variables
|
||||
packet_write(&p, &gMarioStates[0].numCoins, sizeof(s16));
|
||||
packet_write(&p, &gPssSlideStarted, sizeof(u8));
|
||||
packet_write(&p, &gHudDisplay.timer, sizeof(u16));
|
||||
|
||||
// static spawn removal
|
||||
packet_write(&p, &sStaticSpawnRemovalIndex, sizeof(u8));
|
||||
for (int i = 0; i < sStaticSpawnRemovalIndex; i++) {
|
||||
packet_write(&p, &sStaticSpawnRemoval[i], sizeof(u8));
|
||||
}
|
||||
|
||||
// coin collection
|
||||
packet_write(&p, &sCoinCollectionIndex, sizeof(u8));
|
||||
for (int i = 0; i < sCoinCollectionIndex; i++) {
|
||||
packet_write(&p, &sCoinCollection[i], sizeof(u8));
|
||||
}
|
||||
|
||||
// respawners
|
||||
u8 respawnerCount = 0;
|
||||
for (int i = 0; i < MAX_SYNC_OBJECTS; i++) {
|
||||
struct SyncObject* so = &gSyncObjects[i];
|
||||
if (so == NULL || so->o == NULL || so->behavior != bhvRespawner) { continue; }
|
||||
respawnerCount++;
|
||||
}
|
||||
|
||||
packet_write(&p, &respawnerCount, sizeof(u8));
|
||||
for (int i = 0; i < MAX_SYNC_OBJECTS; i++) {
|
||||
struct SyncObject* so = &gSyncObjects[i];
|
||||
if (so == NULL || so->o == NULL || so->behavior != bhvRespawner) { continue; }
|
||||
u32 behaviorToRespawn = get_id_from_behavior(so->o->oRespawnerBehaviorToRespawn);
|
||||
packet_write(&p, &so->o->oPosX, sizeof(f32));
|
||||
packet_write(&p, &so->o->oPosY, sizeof(f32));
|
||||
packet_write(&p, &so->o->oPosZ, sizeof(f32));
|
||||
packet_write(&p, &so->o->oBehParams, sizeof(s32));
|
||||
packet_write(&p, &so->o->oRespawnerModelToRespawn, sizeof(s32));
|
||||
packet_write(&p, &so->o->oRespawnerMinSpawnDist, sizeof(f32));
|
||||
packet_write(&p, &behaviorToRespawn, sizeof(s32));
|
||||
packet_write(&p, &so->o->oSyncID, sizeof(u32));
|
||||
}
|
||||
|
||||
network_send_to(destNp->localIndex, &p);
|
||||
|
||||
// send non-static objects
|
||||
for (int i = 0; i < MAX_SYNC_OBJECTS; i++) {
|
||||
struct SyncObject* so = &gSyncObjects[i];
|
||||
if (so == NULL || so->o == NULL || so->o->oSyncID != i) { continue; }
|
||||
if (so->staticLevelSpawn) { continue; }
|
||||
if (so->o->behavior == bhvRespawner) { continue; }
|
||||
struct Object* spawn_objects[] = { so->o };
|
||||
|
||||
// TODO: move find model to a utility file/function
|
||||
// find model
|
||||
u32 model = 0;
|
||||
for (int j = 0; j < 256; j++) {
|
||||
if (so->o->header.gfx.sharedChild == gLoadedGraphNodes[j]) {
|
||||
model = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
u32 models[] = { model };
|
||||
network_send_spawn_objects_to(destNp->localIndex, spawn_objects, models, 1);
|
||||
}
|
||||
|
||||
// send last reliable ent packet
|
||||
for (int i = 0; i < MAX_SYNC_OBJECTS; i++) {
|
||||
struct SyncObject* so = &gSyncObjects[i];
|
||||
if (so == NULL || so->o == NULL) { continue; }
|
||||
struct Packet* entPacket = get_last_sync_ent_reliable_packet(i);
|
||||
if (entPacket->error) { continue; }
|
||||
struct Packet p2 = { 0 };
|
||||
packet_duplicate(entPacket, &p2);
|
||||
network_send_to(destNp->localIndex, &p2);
|
||||
}
|
||||
}
|
||||
|
||||
void network_receive_location_response(struct Packet* p) {
|
||||
s16 courseNum, actNum, levelNum, areaIndex;
|
||||
packet_read(p, &courseNum, sizeof(s16));
|
||||
packet_read(p, &actNum, sizeof(s16));
|
||||
packet_read(p, &levelNum, sizeof(s16));
|
||||
packet_read(p, &areaIndex, sizeof(s16));
|
||||
|
||||
if (courseNum != gCurrCourseNum || actNum != gCurrActNum || levelNum != gCurrLevelNum || areaIndex != gCurrAreaIndex) {
|
||||
LOG_ERROR("Receiving 'location response' with the wrong location!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (gNetworkPlayerLocal->currAreaSyncValid) {
|
||||
LOG_ERROR("Receiving 'location response' when our location is already valid!");
|
||||
return;
|
||||
}
|
||||
|
||||
s16 numCoins;
|
||||
packet_read(p, &numCoins, sizeof(s16));
|
||||
|
||||
u8 pssSlideStarted;
|
||||
u16 hudDisplayTimer;
|
||||
packet_read(p, &pssSlideStarted, sizeof(u8));
|
||||
packet_read(p, &hudDisplayTimer, sizeof(u16));
|
||||
if (pssSlideStarted) {
|
||||
level_control_timer(TIMER_CONTROL_SHOW);
|
||||
level_control_timer(TIMER_CONTROL_START);
|
||||
gPssSlideStarted = TRUE;
|
||||
gHudDisplay.timer = hudDisplayTimer;
|
||||
}
|
||||
|
||||
u8 staticSpawnRemovals;
|
||||
static_spawn_removal_clear();
|
||||
|
||||
// read static spawn removals
|
||||
packet_read(p, &staticSpawnRemovals, sizeof(u8));
|
||||
for (int i = 0; i < staticSpawnRemovals; i++) {
|
||||
u8 syncId;
|
||||
packet_read(p, &syncId, sizeof(u8));
|
||||
struct SyncObject* so = &gSyncObjects[syncId];
|
||||
if (so != NULL) {
|
||||
if (so->o != NULL) {
|
||||
obj_mark_for_deletion(so->o);
|
||||
}
|
||||
network_forget_sync_object(so);
|
||||
}
|
||||
}
|
||||
|
||||
// read coin collections
|
||||
packet_read(p, &sCoinCollectionIndex, sizeof(u8));
|
||||
for (int i = 0; i < sCoinCollectionIndex; i++) {
|
||||
packet_read(p, &sCoinCollection[i], sizeof(u8));
|
||||
}
|
||||
|
||||
// collect the coins
|
||||
for (int i = 0; i < OBJECT_POOL_CAPACITY; i++) {
|
||||
struct Object* o = &gObjectPool[i];
|
||||
if (o->activeFlags & ACTIVE_FLAG_DEACTIVATED) { continue; }
|
||||
if (!is_behavior_a_coin(o->behavior)) { continue; }
|
||||
for (int j = 0; j < sCoinCollectionIndex; j++) {
|
||||
if (o->oCoinID == sCoinCollection[j]) {
|
||||
o->oInteractStatus = INT_STATUS_INTERACTED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// read respawners
|
||||
u8 respawnerCount = 0;
|
||||
packet_read(p, &respawnerCount, sizeof(u8));
|
||||
|
||||
for (int i = 0; i < respawnerCount; i++) {
|
||||
f32 posX, posY, posZ;
|
||||
packet_read(p, &posX, sizeof(f32));
|
||||
packet_read(p, &posY, sizeof(f32));
|
||||
packet_read(p, &posZ, sizeof(f32));
|
||||
|
||||
s32 behParams, respawnerModelToRespawn;
|
||||
packet_read(p, &behParams, sizeof(s32));
|
||||
packet_read(p, &respawnerModelToRespawn, sizeof(s32));
|
||||
|
||||
f32 respawnerMinSpawnDist;
|
||||
packet_read(p, &respawnerMinSpawnDist, sizeof(f32));
|
||||
|
||||
u32 behaviorToRespawn, syncId;
|
||||
packet_read(p, &behaviorToRespawn, sizeof(u32));
|
||||
packet_read(p, &syncId, sizeof(u32));
|
||||
|
||||
struct Object* respawner = spawn_object_abs_with_rot(gMarioStates[0].marioObj, 0, MODEL_NONE, bhvRespawner, posX, posY, posZ, 0, 0, 0);
|
||||
respawner->parentObj = respawner;
|
||||
respawner->oBehParams = behParams;
|
||||
respawner->oRespawnerModelToRespawn = respawnerModelToRespawn;
|
||||
respawner->oRespawnerMinSpawnDist = respawnerMinSpawnDist;
|
||||
respawner->oRespawnerBehaviorToRespawn = get_behavior_from_id(behaviorToRespawn);
|
||||
respawner->oSyncID = syncId;
|
||||
|
||||
network_forget_sync_object(&gSyncObjects[syncId]);
|
||||
network_init_object(respawner, SYNC_DISTANCE_ONLY_EVENTS);
|
||||
}
|
||||
|
||||
gMarioStates[0].numCoins = numCoins;
|
||||
gNetworkPlayerLocal->currAreaSyncValid = true;
|
||||
|
||||
if (gNetworkType != NT_SERVER) {
|
||||
network_send_level_area_valid(0);
|
||||
}
|
||||
}
|
57
src/pc/network/packets/packet_location_request_client.c
Normal file
57
src/pc/network/packets/packet_location_request_client.c
Normal file
|
@ -0,0 +1,57 @@
|
|||
#include <stdio.h>
|
||||
#include "../network.h"
|
||||
//#define DISABLE_MODULE_LOG 1
|
||||
#include "pc/debuglog.h"
|
||||
|
||||
extern s16 gCurrCourseNum, gCurrActNum, gCurrLevelNum, gCurrAreaIndex;
|
||||
|
||||
void network_send_location_request_client(u8 destGlobalIndex, u8 srcGlobalIndex) {
|
||||
if (gNetworkType != NT_SERVER) {
|
||||
LOG_ERROR("client can't send a 'client location request'");
|
||||
return;
|
||||
}
|
||||
|
||||
struct NetworkPlayer* destNp = network_player_from_global_index(destGlobalIndex);
|
||||
if (destNp == NULL || !destNp->connected) {
|
||||
LOG_ERROR("network_send_client_location_request: dest np is invalid (global %d)", destGlobalIndex);
|
||||
return;
|
||||
}
|
||||
|
||||
struct Packet p;
|
||||
packet_init(&p, PACKET_LOCATION_REQUEST_CLIENT, true, false);
|
||||
packet_write(&p, &destGlobalIndex, sizeof(u8));
|
||||
packet_write(&p, &destNp->currCourseNum, sizeof(s16));
|
||||
packet_write(&p, &destNp->currActNum, sizeof(s16));
|
||||
packet_write(&p, &destNp->currLevelNum, sizeof(s16));
|
||||
packet_write(&p, &destNp->currAreaIndex, sizeof(s16));
|
||||
|
||||
struct NetworkPlayer* srcNp = network_player_from_global_index(srcGlobalIndex);
|
||||
if (srcNp == NULL || !srcNp->connected || !srcNp->currAreaSyncValid) {
|
||||
LOG_ERROR("network_send_client_location_request: source np is invalid (global %d)", srcGlobalIndex);
|
||||
return;
|
||||
}
|
||||
|
||||
network_send_to(srcNp->localIndex, &p);
|
||||
}
|
||||
|
||||
void network_receive_location_request_client(struct Packet* p) {
|
||||
if (gNetworkType == NT_SERVER) {
|
||||
LOG_ERROR("server is receiving a 'client location request'!");
|
||||
return;
|
||||
}
|
||||
|
||||
u8 destGlobalIndex;
|
||||
s16 courseNum, actNum, levelNum, areaIndex;
|
||||
packet_read(p, &destGlobalIndex, sizeof(u8));
|
||||
packet_read(p, &courseNum, sizeof(s16));
|
||||
packet_read(p, &actNum, sizeof(s16));
|
||||
packet_read(p, &levelNum, sizeof(s16));
|
||||
packet_read(p, &areaIndex, sizeof(s16));
|
||||
|
||||
if (courseNum != gCurrCourseNum || actNum != gCurrActNum || levelNum != gCurrLevelNum || areaIndex != gCurrAreaIndex) {
|
||||
LOG_ERROR("Receiving 'client location request' with the wrong location!");
|
||||
return;
|
||||
}
|
||||
|
||||
network_send_location_response(destGlobalIndex);
|
||||
}
|
189
src/pc/network/packets/packet_location_response.c
Normal file
189
src/pc/network/packets/packet_location_response.c
Normal file
|
@ -0,0 +1,189 @@
|
|||
#include <stdio.h>
|
||||
#include "../network.h"
|
||||
#include "game/interaction.h"
|
||||
#include "game/object_list_processor.h"
|
||||
#include "game/object_helpers.h"
|
||||
#include "game/interaction.h"
|
||||
#include "game/level_update.h"
|
||||
#include "game/macro_special_objects.h"
|
||||
#include "object_constants.h"
|
||||
#include "object_fields.h"
|
||||
#include "behavior_table.h"
|
||||
#include "model_ids.h"
|
||||
//#define DISABLE_MODULE_LOG 1
|
||||
#include "pc/debuglog.h"
|
||||
|
||||
void network_send_location_response(u8 destGlobalIndex) {
|
||||
if (!gNetworkPlayerLocal->currAreaSyncValid) {
|
||||
LOG_ERROR("my area is invalid");
|
||||
return;
|
||||
}
|
||||
|
||||
struct NetworkPlayer* destNp = network_player_from_global_index(destGlobalIndex);
|
||||
if (destNp == NULL || !destNp->connected) {
|
||||
LOG_ERROR("network_send_location_response: dest np is invalid");
|
||||
return;
|
||||
}
|
||||
|
||||
struct Packet p;
|
||||
packet_init(&p, PACKET_LOCATION_RESPONSE, true, false);
|
||||
packet_write(&p, &gCurrCourseNum, sizeof(s16));
|
||||
packet_write(&p, &gCurrActNum, sizeof(s16));
|
||||
packet_write(&p, &gCurrLevelNum, sizeof(s16));
|
||||
packet_write(&p, &gCurrAreaIndex, sizeof(s16));
|
||||
|
||||
// level variables
|
||||
packet_write(&p, &gMarioStates[0].numCoins, sizeof(s16));
|
||||
packet_write(&p, &gPssSlideStarted, sizeof(u8));
|
||||
packet_write(&p, &gHudDisplay.timer, sizeof(u16));
|
||||
|
||||
// respawners
|
||||
u8 respawnerCount = 0;
|
||||
for (int i = 0; i < MAX_SYNC_OBJECTS; i++) {
|
||||
struct SyncObject* so = &gSyncObjects[i];
|
||||
if (so == NULL || so->o == NULL || so->o->behavior != bhvRespawner) { continue; }
|
||||
respawnerCount++;
|
||||
}
|
||||
|
||||
packet_write(&p, &respawnerCount, sizeof(u8));
|
||||
for (int i = 0; i < MAX_SYNC_OBJECTS; i++) {
|
||||
struct SyncObject* so = &gSyncObjects[i];
|
||||
if (so == NULL || so->o == NULL || so->o->behavior != bhvRespawner) { continue; }
|
||||
u32 behaviorToRespawn = get_id_from_behavior(so->o->oRespawnerBehaviorToRespawn);
|
||||
packet_write(&p, &so->o->oPosX, sizeof(f32));
|
||||
packet_write(&p, &so->o->oPosY, sizeof(f32));
|
||||
packet_write(&p, &so->o->oPosZ, sizeof(f32));
|
||||
packet_write(&p, &so->o->oBehParams, sizeof(s32));
|
||||
packet_write(&p, &so->o->oRespawnerModelToRespawn, sizeof(s32));
|
||||
packet_write(&p, &so->o->oRespawnerMinSpawnDist, sizeof(f32));
|
||||
packet_write(&p, &behaviorToRespawn, sizeof(s32));
|
||||
packet_write(&p, &so->o->oSyncID, sizeof(u32));
|
||||
LOG_INFO("tx respawner");
|
||||
}
|
||||
|
||||
network_send_to(destNp->localIndex, &p);
|
||||
|
||||
// send macro deletions
|
||||
network_send_macro_deletions(destGlobalIndex);
|
||||
|
||||
// send spawn info
|
||||
network_send_spawn_info_deletions(destGlobalIndex);
|
||||
|
||||
// send non-static objects
|
||||
for (int i = 0; i < MAX_SYNC_OBJECTS; i++) {
|
||||
struct SyncObject* so = &gSyncObjects[i];
|
||||
if (so == NULL || so->o == NULL || so->o->oSyncID != i) { continue; }
|
||||
if (so->staticLevelSpawn) { continue; }
|
||||
if (so->o->behavior == bhvRespawner) { continue; }
|
||||
struct Object* spawn_objects[] = { so->o };
|
||||
|
||||
// TODO: move find model to a utility file/function
|
||||
// find model
|
||||
u32 model = 0;
|
||||
for (int j = 0; j < 256; j++) {
|
||||
if (so->o->header.gfx.sharedChild == gLoadedGraphNodes[j]) {
|
||||
model = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
u32 models[] = { model };
|
||||
network_send_spawn_objects_to(destNp->localIndex, spawn_objects, models, 1);
|
||||
LOG_INFO("tx non-static");
|
||||
}
|
||||
|
||||
// send last reliable ent packet
|
||||
for (int i = 0; i < MAX_SYNC_OBJECTS; i++) {
|
||||
struct SyncObject* so = &gSyncObjects[i];
|
||||
if (so == NULL || so->o == NULL) { continue; }
|
||||
struct Packet* entPacket = get_last_sync_ent_reliable_packet(i);
|
||||
if (entPacket->error) { continue; }
|
||||
struct Packet p2 = { 0 };
|
||||
packet_duplicate(entPacket, &p2);
|
||||
network_send_to(destNp->localIndex, &p2);
|
||||
}
|
||||
|
||||
LOG_INFO("tx location response");
|
||||
}
|
||||
|
||||
void network_receive_location_response(struct Packet* p) {
|
||||
s16 courseNum, actNum, levelNum, areaIndex;
|
||||
packet_read(p, &courseNum, sizeof(s16));
|
||||
packet_read(p, &actNum, sizeof(s16));
|
||||
packet_read(p, &levelNum, sizeof(s16));
|
||||
packet_read(p, &areaIndex, sizeof(s16));
|
||||
|
||||
if (courseNum != gCurrCourseNum || actNum != gCurrActNum || levelNum != gCurrLevelNum || areaIndex != gCurrAreaIndex) {
|
||||
LOG_ERROR("Receiving 'location response' with the wrong location!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (gNetworkPlayerLocal->currAreaSyncValid) {
|
||||
LOG_ERROR("Receiving 'location response' when our location is already valid!");
|
||||
return;
|
||||
}
|
||||
|
||||
s16 numCoins;
|
||||
packet_read(p, &numCoins, sizeof(s16));
|
||||
|
||||
u8 pssSlideStarted;
|
||||
u16 hudDisplayTimer;
|
||||
packet_read(p, &pssSlideStarted, sizeof(u8));
|
||||
packet_read(p, &hudDisplayTimer, sizeof(u16));
|
||||
if (pssSlideStarted) {
|
||||
level_control_timer(TIMER_CONTROL_SHOW);
|
||||
level_control_timer(TIMER_CONTROL_START);
|
||||
gPssSlideStarted = TRUE;
|
||||
gHudDisplay.timer = hudDisplayTimer;
|
||||
}
|
||||
|
||||
// read respawners
|
||||
u8 respawnerCount = 0;
|
||||
packet_read(p, &respawnerCount, sizeof(u8));
|
||||
|
||||
for (int i = 0; i < respawnerCount; i++) {
|
||||
f32 posX, posY, posZ;
|
||||
packet_read(p, &posX, sizeof(f32));
|
||||
packet_read(p, &posY, sizeof(f32));
|
||||
packet_read(p, &posZ, sizeof(f32));
|
||||
|
||||
s32 behParams, respawnerModelToRespawn;
|
||||
packet_read(p, &behParams, sizeof(s32));
|
||||
packet_read(p, &respawnerModelToRespawn, sizeof(s32));
|
||||
|
||||
f32 respawnerMinSpawnDist;
|
||||
packet_read(p, &respawnerMinSpawnDist, sizeof(f32));
|
||||
|
||||
u32 behaviorToRespawn, syncId;
|
||||
packet_read(p, &behaviorToRespawn, sizeof(u32));
|
||||
packet_read(p, &syncId, sizeof(u32));
|
||||
|
||||
struct SyncObject* so = &gSyncObjects[syncId];
|
||||
|
||||
LOG_INFO("rx respawner");
|
||||
if (so->staticLevelSpawn) {
|
||||
struct Object* respawner = spawn_object_abs_with_rot(gMarioStates[0].marioObj, 0, MODEL_NONE, bhvRespawner, posX, posY, posZ, 0, 0, 0);
|
||||
respawner->parentObj = respawner;
|
||||
respawner->oBehParams = behParams;
|
||||
respawner->oRespawnerModelToRespawn = respawnerModelToRespawn;
|
||||
respawner->oRespawnerMinSpawnDist = respawnerMinSpawnDist;
|
||||
respawner->oRespawnerBehaviorToRespawn = get_behavior_from_id(behaviorToRespawn);
|
||||
respawner->oSyncID = syncId;
|
||||
|
||||
struct Object* o = so->o;
|
||||
o->oSyncID = 0;
|
||||
o->activeFlags = ACTIVE_FLAG_DEACTIVATED;
|
||||
|
||||
so->o = respawner;
|
||||
LOG_INFO("rx respawner replaced!");
|
||||
}
|
||||
}
|
||||
|
||||
gMarioStates[0].numCoins = numCoins;
|
||||
gNetworkPlayerLocal->currAreaSyncValid = true;
|
||||
|
||||
if (gNetworkType != NT_SERVER) {
|
||||
network_send_level_area_valid(0);
|
||||
}
|
||||
LOG_INFO("rx location response");
|
||||
}
|
205
src/pc/network/packets/packet_macro_deletions.c
Normal file
205
src/pc/network/packets/packet_macro_deletions.c
Normal file
|
@ -0,0 +1,205 @@
|
|||
#include <stdio.h>
|
||||
#include "../network.h"
|
||||
#include "game/interaction.h"
|
||||
#include "game/object_list_processor.h"
|
||||
#include "game/object_helpers.h"
|
||||
#include "game/interaction.h"
|
||||
#include "game/level_update.h"
|
||||
#include "game/macro_special_objects.h"
|
||||
#include "macro_presets.h"
|
||||
#include "object_constants.h"
|
||||
#include "object_fields.h"
|
||||
#include "behavior_table.h"
|
||||
#include "model_ids.h"
|
||||
#define DISABLE_MODULE_LOG 1
|
||||
#include "pc/debuglog.h"
|
||||
|
||||
static struct Object* get_object_matching_respawn_info(s16* respawnInfo) {
|
||||
for (int i = 0; i < OBJECT_POOL_CAPACITY; i++) {
|
||||
struct Object* o = &gObjectPool[i];
|
||||
if (o->respawnInfo == respawnInfo) { return o; }
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
////
|
||||
|
||||
void network_send_macro_deletions_area(u8 destGlobalIndex, u8 areaIndex) {
|
||||
// check that the area is active
|
||||
struct Area* area = &gAreaData[areaIndex];
|
||||
if (area->unk04 == NULL) { return; }
|
||||
|
||||
struct NetworkPlayer* destNp = network_player_from_global_index(destGlobalIndex);
|
||||
if (destNp == NULL || !destNp->connected) {
|
||||
LOG_ERROR("network_send_macro_deletions_area: dest np is invalid");
|
||||
return;
|
||||
}
|
||||
|
||||
// write header
|
||||
struct Packet p;
|
||||
packet_init(&p, PACKET_MACRO_DELETIONS, true, false);
|
||||
packet_write(&p, &gCurrCourseNum, sizeof(s16));
|
||||
packet_write(&p, &gCurrActNum, sizeof(s16));
|
||||
packet_write(&p, &gCurrLevelNum, sizeof(s16));
|
||||
packet_write(&p, &gCurrAreaIndex, sizeof(s16));
|
||||
|
||||
// write this area's index
|
||||
packet_write(&p, &areaIndex, sizeof(u8));
|
||||
|
||||
// write the amount of deletions
|
||||
u8 zero = 0;
|
||||
u8* macroDeletionCount = &p.buffer[p.cursor];
|
||||
packet_write(&p, &zero, sizeof(u8));
|
||||
|
||||
// loop through macro objects for deletions
|
||||
s16* macroObjList = area->macroObjects;
|
||||
while (*macroObjList != -1) {
|
||||
// grab preset ID
|
||||
s32 presetID = (*macroObjList & 0x1FF) - 31; // Preset identifier for MacroObjectPresets array
|
||||
if (presetID < 0) { break; }
|
||||
|
||||
// parse respawn info
|
||||
macroObjList += 4;
|
||||
s16* respawnInfo = macroObjList++;
|
||||
|
||||
// if a macro object was destroyed, send its respawnInfo offset
|
||||
if (((*respawnInfo >> 8) & RESPAWN_INFO_DONT_RESPAWN) == RESPAWN_INFO_DONT_RESPAWN) {
|
||||
*macroDeletionCount = *macroDeletionCount + 1;
|
||||
u16 offset = respawnInfo - area->macroObjects;
|
||||
packet_write(&p, &offset, sizeof(u16));
|
||||
LOG_INFO("tx macro deletion: offset %d", offset);
|
||||
}
|
||||
}
|
||||
|
||||
// write the amount of special cases
|
||||
u8* macroSpecialCount = &p.buffer[p.cursor];
|
||||
packet_write(&p, &zero, sizeof(u8));
|
||||
|
||||
// loop through macro objects for special cases
|
||||
macroObjList = area->macroObjects;
|
||||
while (*macroObjList != -1) {
|
||||
// grab preset ID
|
||||
s32 presetID = (*macroObjList & 0x1FF) - 31; // Preset identifier for MacroObjectPresets array
|
||||
if (presetID < 0) { break; }
|
||||
|
||||
// parse respawn info
|
||||
macroObjList += 4;
|
||||
s16* respawnInfo = macroObjList++;
|
||||
|
||||
// check for special cases
|
||||
const BehaviorScript* behavior = MacroObjectPresets[presetID].behavior;
|
||||
if (behavior == bhvCoinFormation && *respawnInfo != 0) {
|
||||
*macroSpecialCount = *macroSpecialCount + 1;
|
||||
u16 offset = respawnInfo - area->macroObjects;
|
||||
packet_write(&p, &offset, sizeof(u16));
|
||||
packet_write(&p, respawnInfo, sizeof(s16));
|
||||
LOG_INFO("tx macro special: offset %d, respawnInfo %d", offset, *respawnInfo);
|
||||
}
|
||||
}
|
||||
|
||||
// send the packet if there are deletions
|
||||
if (*macroDeletionCount > 0 || *macroSpecialCount > 0) {
|
||||
network_send_to(destNp->localIndex, &p);
|
||||
LOG_INFO("tx macro deletion for area %d (count %d)", areaIndex, *macroDeletionCount);
|
||||
}
|
||||
}
|
||||
|
||||
void network_send_macro_deletions(u8 destGlobalIndex) {
|
||||
if (!gNetworkPlayerLocal->currAreaSyncValid) {
|
||||
LOG_ERROR("my area is invalid");
|
||||
return;
|
||||
}
|
||||
|
||||
struct NetworkPlayer* destNp = network_player_from_global_index(destGlobalIndex);
|
||||
if (destNp == NULL || !destNp->connected) {
|
||||
LOG_ERROR("network_send_macro_deletions: dest np is invalid");
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
network_send_macro_deletions_area(destGlobalIndex, i);
|
||||
}
|
||||
}
|
||||
|
||||
void network_receive_macro_deletions(struct Packet* p) {
|
||||
s16 courseNum, actNum, levelNum, areaIndex;
|
||||
packet_read(p, &courseNum, sizeof(s16));
|
||||
packet_read(p, &actNum, sizeof(s16));
|
||||
packet_read(p, &levelNum, sizeof(s16));
|
||||
packet_read(p, &areaIndex, sizeof(s16));
|
||||
|
||||
if (courseNum != gCurrCourseNum || actNum != gCurrActNum || levelNum != gCurrLevelNum) {
|
||||
LOG_ERROR("Receiving 'location response' with the wrong location!");
|
||||
return;
|
||||
}
|
||||
|
||||
u8 thisAreaIndex;
|
||||
packet_read(p, &thisAreaIndex, sizeof(u8));
|
||||
|
||||
// read and execute macro deletions
|
||||
u8 macroDeletionCount;
|
||||
packet_read(p, ¯oDeletionCount, sizeof(u8));
|
||||
LOG_INFO("rx macro deletions (count %d)", macroDeletionCount);
|
||||
|
||||
while (macroDeletionCount-- > 0) {
|
||||
u16 offset;
|
||||
packet_read(p, &offset, sizeof(u16));
|
||||
LOG_INFO("rx macro deletion: offset %d", offset);
|
||||
|
||||
// mark respawninfo as dont respawn
|
||||
s16* respawnInfo = gAreaData[thisAreaIndex].macroObjects + offset;
|
||||
*respawnInfo |= RESPAWN_INFO_DONT_RESPAWN << 8;
|
||||
|
||||
struct Object* o = get_object_matching_respawn_info(respawnInfo);
|
||||
if (o != NULL) {
|
||||
obj_mark_for_deletion(o);
|
||||
LOG_INFO("rx macro deletion: object");
|
||||
if (o->oSyncID != 0) {
|
||||
struct SyncObject* so = &gSyncObjects[o->oSyncID];
|
||||
if (so->o == o) {
|
||||
network_forget_sync_object(so);
|
||||
LOG_INFO("rx macro deletion: sync object");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// read and execute macro specials
|
||||
|
||||
u8 macroSpecialCount;
|
||||
packet_read(p, ¯oSpecialCount, sizeof(u8));
|
||||
while (macroSpecialCount-- > 0) {
|
||||
u16 offset;
|
||||
packet_read(p, &offset, sizeof(u16));
|
||||
|
||||
s16* respawnInfo = gAreaData[thisAreaIndex].macroObjects + offset;
|
||||
packet_read(p, respawnInfo, sizeof(s16));
|
||||
LOG_INFO("rx macro special: offset %d, respawnInfo %d", offset, *respawnInfo);
|
||||
|
||||
s32 presetID = (*(respawnInfo - 4) & 0x1FF) - 31;
|
||||
const BehaviorScript* behavior = MacroObjectPresets[presetID].behavior;
|
||||
|
||||
struct Object* o = get_object_matching_respawn_info(respawnInfo);
|
||||
if (o != NULL) {
|
||||
LOG_INFO("rx macro special: object");
|
||||
// coin formation
|
||||
if (behavior == bhvCoinFormation) {
|
||||
o->oBehParams = *respawnInfo;
|
||||
o->oCoinUnkF4 = (o->oBehParams >> 8) & 0xFF;
|
||||
|
||||
u8 childIndex = 0;
|
||||
for (int i = 0; i < OBJECT_POOL_CAPACITY; i++) {
|
||||
struct Object* o2 = &gObjectPool[i];
|
||||
if (o2->parentObj != o) { continue; }
|
||||
if (o2 == o) { continue; }
|
||||
if (o2->behavior != bhvCoinFormationSpawn && o2->behavior != bhvYellowCoin) { continue; }
|
||||
if (o->oCoinUnkF4 & (1 << childIndex++)) {
|
||||
obj_mark_for_deletion(o2);
|
||||
}
|
||||
}
|
||||
LOG_INFO("rx macro special: coin formation");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -63,7 +63,14 @@ static bool should_own_object(struct SyncObject* so) {
|
|||
return true;
|
||||
}
|
||||
|
||||
void network_override_object(u8 syncId, struct Object* o) {
|
||||
gSyncObjects[syncId].o = o;
|
||||
}
|
||||
|
||||
struct SyncObject* network_init_object(struct Object *o, float maxSyncDistance) {
|
||||
// HACK: an odd way to detect if this entity was spawned from a staticLevel respawner
|
||||
bool wasStaticRespawner = (o->oSyncID != 0 && gSyncObjects[o->oSyncID].o == o && gSyncObjects[o->oSyncID].staticLevelSpawn);
|
||||
|
||||
// generate new sync ID
|
||||
network_set_sync_id(o);
|
||||
|
||||
|
@ -90,7 +97,7 @@ struct SyncObject* network_init_object(struct Object *o, float maxSyncDistance)
|
|||
so->override_ownership = NULL;
|
||||
so->syncDeathEvent = true;
|
||||
so->randomSeed = (u16)(o->oSyncID * 7951);
|
||||
so->staticLevelSpawn = false;
|
||||
so->staticLevelSpawn = wasStaticRespawner;
|
||||
memset(so->extraFields, 0, sizeof(void*) * MAX_SYNC_OBJECT_FIELDS);
|
||||
|
||||
sLastSyncEntReliablePacket[o->oSyncID].error = true;
|
||||
|
@ -137,8 +144,6 @@ void network_clear_sync_objects(void) {
|
|||
network_forget_sync_object(&gSyncObjects[i]);
|
||||
}
|
||||
nextSyncID = 1;
|
||||
static_spawn_removal_clear();
|
||||
coin_collection_clear();
|
||||
}
|
||||
|
||||
void network_set_sync_id(struct Object* o) {
|
||||
|
@ -372,6 +377,8 @@ static void packet_read_object_only_death(struct Packet* p, struct Object* o) {
|
|||
void network_send_object(struct Object* o) {
|
||||
// sanity check SyncObject
|
||||
if (!network_sync_object_initialized(o)) { return; }
|
||||
if (o->behavior == bhvRespawner) { return; }
|
||||
|
||||
struct SyncObject* so = &gSyncObjects[o->oSyncID];
|
||||
if (so == NULL) { return; }
|
||||
if (o != so->o) {
|
||||
|
@ -493,20 +500,19 @@ void network_receive_object(struct Packet* p) {
|
|||
}
|
||||
|
||||
void network_forget_sync_object(struct SyncObject* so) {
|
||||
// invalidate last packet sent
|
||||
if (so->staticLevelSpawn && so->o != NULL) {
|
||||
u8 syncId = so->o->oSyncID;
|
||||
struct SyncObject* so2 = &gSyncObjects[syncId];
|
||||
if (so == so2) {
|
||||
static_spawn_removal_remember(syncId);
|
||||
sLastSyncEntReliablePacket[syncId].error = true;
|
||||
}
|
||||
}
|
||||
|
||||
so->o = NULL;
|
||||
so->behavior = NULL;
|
||||
so->reserved = 0;
|
||||
so->owned = false;
|
||||
so->staticLevelSpawn = false;
|
||||
|
||||
}
|
||||
|
||||
void network_update_objects(void) {
|
||||
|
|
140
src/pc/network/packets/packet_spawn_info_deletions.c
Normal file
140
src/pc/network/packets/packet_spawn_info_deletions.c
Normal file
|
@ -0,0 +1,140 @@
|
|||
#include <stdio.h>
|
||||
#include "../network.h"
|
||||
#include "game/interaction.h"
|
||||
#include "game/object_list_processor.h"
|
||||
#include "game/object_helpers.h"
|
||||
#include "game/interaction.h"
|
||||
#include "game/level_update.h"
|
||||
#include "game/macro_special_objects.h"
|
||||
#include "object_constants.h"
|
||||
#include "object_fields.h"
|
||||
#include "behavior_table.h"
|
||||
#include "model_ids.h"
|
||||
#define DISABLE_MODULE_LOG 1
|
||||
#include "pc/debuglog.h"
|
||||
|
||||
static struct Object* get_object_matching_respawn_info(s32* respawnInfo) {
|
||||
for (int i = 0; i < OBJECT_POOL_CAPACITY; i++) {
|
||||
struct Object* o = &gObjectPool[i];
|
||||
if (o->respawnInfo == respawnInfo) { return o; }
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
////
|
||||
|
||||
void network_send_spawn_info_deletions_area(u8 destGlobalIndex, u8 areaIndex) {
|
||||
// check that the area is active
|
||||
struct Area* area = &gAreaData[areaIndex];
|
||||
if (area->unk04 == NULL) { return; }
|
||||
|
||||
struct NetworkPlayer* destNp = network_player_from_global_index(destGlobalIndex);
|
||||
if (destNp == NULL || !destNp->connected) {
|
||||
LOG_ERROR("network_send_spawn_info_deletions_area: dest np is invalid");
|
||||
return;
|
||||
}
|
||||
|
||||
// write header
|
||||
struct Packet p;
|
||||
packet_init(&p, PACKET_SPAWN_INFO_DELETIONS, true, false);
|
||||
packet_write(&p, &gCurrCourseNum, sizeof(s16));
|
||||
packet_write(&p, &gCurrActNum, sizeof(s16));
|
||||
packet_write(&p, &gCurrLevelNum, sizeof(s16));
|
||||
packet_write(&p, &gCurrAreaIndex, sizeof(s16));
|
||||
|
||||
// write this area's index
|
||||
packet_write(&p, &areaIndex, sizeof(u8));
|
||||
|
||||
// write the amount of deletions
|
||||
u8 zero = 0;
|
||||
u8* spawnInfoDeletionCount = &p.buffer[p.cursor];
|
||||
packet_write(&p, &zero, sizeof(u8));
|
||||
|
||||
// loop through spawn infos
|
||||
struct SpawnInfo* spawnInfo = area->objectSpawnInfos;
|
||||
u16 spawnInfoIndex = 0;
|
||||
|
||||
while (spawnInfo != NULL) {
|
||||
// if a spawn info object was destroyed, send its spawn info index
|
||||
if (((spawnInfo->behaviorArg >> 8) & RESPAWN_INFO_DONT_RESPAWN) == RESPAWN_INFO_DONT_RESPAWN) {
|
||||
*spawnInfoDeletionCount = *spawnInfoDeletionCount + 1;
|
||||
packet_write(&p, &spawnInfoIndex, sizeof(u16));
|
||||
LOG_INFO("tx spawn info deletion: index %d", spawnInfoIndex);
|
||||
}
|
||||
|
||||
spawnInfo = spawnInfo->next;
|
||||
spawnInfoIndex++;
|
||||
}
|
||||
|
||||
// send the packet if there are deletions
|
||||
if (*spawnInfoDeletionCount > 0) {
|
||||
network_send_to(destNp->localIndex, &p);
|
||||
LOG_INFO("tx spawn info deletion for area %d (count %d)", areaIndex, *spawnInfoDeletionCount);
|
||||
}
|
||||
}
|
||||
|
||||
void network_send_spawn_info_deletions(u8 destGlobalIndex) {
|
||||
if (!gNetworkPlayerLocal->currAreaSyncValid) {
|
||||
LOG_ERROR("my area is invalid");
|
||||
return;
|
||||
}
|
||||
|
||||
struct NetworkPlayer* destNp = network_player_from_global_index(destGlobalIndex);
|
||||
if (destNp == NULL || !destNp->connected) {
|
||||
LOG_ERROR("network_send_spawn_info_deletions: dest np is invalid");
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
network_send_spawn_info_deletions_area(destGlobalIndex, i);
|
||||
}
|
||||
}
|
||||
|
||||
void network_receive_spawn_info_deletions(struct Packet* p) {
|
||||
s16 courseNum, actNum, levelNum, areaIndex;
|
||||
packet_read(p, &courseNum, sizeof(s16));
|
||||
packet_read(p, &actNum, sizeof(s16));
|
||||
packet_read(p, &levelNum, sizeof(s16));
|
||||
packet_read(p, &areaIndex, sizeof(s16));
|
||||
|
||||
if (courseNum != gCurrCourseNum || actNum != gCurrActNum || levelNum != gCurrLevelNum) {
|
||||
LOG_ERROR("Receiving 'location response' with the wrong location!");
|
||||
return;
|
||||
}
|
||||
|
||||
u8 thisAreaIndex, spawnInfoDeletionCount;
|
||||
packet_read(p, &thisAreaIndex, sizeof(u8));
|
||||
packet_read(p, &spawnInfoDeletionCount, sizeof(u8));
|
||||
LOG_INFO("rx spawn info deletions (count %d)", spawnInfoDeletionCount);
|
||||
if (spawnInfoDeletionCount <= 0) { return; }
|
||||
|
||||
struct SpawnInfo* spawnInfo = gAreaData[thisAreaIndex].objectSpawnInfos;
|
||||
u16 spawnInfoIndex = 0;
|
||||
|
||||
u16 spawnInfoDeleteIndex;
|
||||
packet_read(p, &spawnInfoDeleteIndex, sizeof(u16));
|
||||
|
||||
while (spawnInfo != NULL && spawnInfoDeletionCount > 0) {
|
||||
if (spawnInfoIndex == spawnInfoDeleteIndex) {
|
||||
u32* respawnInfo = &spawnInfo->behaviorArg;
|
||||
struct Object* o = get_object_matching_respawn_info(respawnInfo);
|
||||
if (o != NULL) {
|
||||
obj_mark_for_deletion(o);
|
||||
LOG_INFO("rx spawn info deletion: object");
|
||||
if (o->oSyncID != 0) {
|
||||
struct SyncObject* so = &gSyncObjects[o->oSyncID];
|
||||
if (so->o == o) {
|
||||
network_forget_sync_object(so);
|
||||
LOG_INFO("rx spawn info deletion: sync object");
|
||||
}
|
||||
}
|
||||
}
|
||||
spawnInfoDeletionCount--;
|
||||
packet_read(p, &spawnInfoDeleteIndex, sizeof(u16));
|
||||
}
|
||||
|
||||
spawnInfo = spawnInfo->next;
|
||||
spawnInfoIndex++;
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue