mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2026-04-26 03:51:46 +00:00
Synchronized mips/toad star spawning
This commit is contained in:
parent
525ef6db17
commit
b673457a48
15 changed files with 108 additions and 11 deletions
|
|
@ -56,6 +56,8 @@ s16 gCurrLevelNum = LEVEL_MIN;
|
|||
|
||||
u32 gSpawnedStarDefault[8] = { 0 };
|
||||
u8 gSpawnedStarDefaultCount = 0;
|
||||
u32 gSpawnedStarNLE[8] = { 0 };
|
||||
u8 gSpawnedStarNLECount = 0;
|
||||
u8 gSpawnedStarRedCoin = 0;
|
||||
u8 gSpawnedStarHidden = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -140,6 +140,8 @@ extern s16 gCurrLevelNum;
|
|||
|
||||
extern u32 gSpawnedStarDefault[];
|
||||
extern u8 gSpawnedStarDefaultCount;
|
||||
extern u32 gSpawnedStarNLE[];
|
||||
extern u8 gSpawnedStarNLECount;
|
||||
extern u8 gSpawnedStarRedCoin;
|
||||
extern u8 gSpawnedStarHidden;
|
||||
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@
|
|||
#include "spawn_object.h"
|
||||
#include "spawn_sound.h"
|
||||
#include "thread6.h"
|
||||
#include "area.h"
|
||||
|
||||
#define o gCurrentObject
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
#define BEHAVIOR_ACTIONS_H
|
||||
|
||||
void spawn_mist_particles_variable(s32 count, s32 offsetY, f32 size);
|
||||
void bhv_spawn_star_no_level_exit(struct Object*,u32);
|
||||
void bhv_spawn_star_no_level_exit(struct Object* object, u32 params, u8 networkSendEvent);
|
||||
void bhv_star_door_loop_2(void);
|
||||
void spawn_triangle_break_particles(s16 numTris, s16 triModel, f32 triSize, s16 triAnimState);
|
||||
|
||||
|
|
|
|||
|
|
@ -211,7 +211,7 @@ void bhv_mips_act_idle(void) {
|
|||
|
||||
// Spawn a star if he was just picked up for the first time.
|
||||
if (o->oMipsStarStatus == MIPS_STAR_STATUS_SHOULD_SPAWN_STAR) {
|
||||
bhv_spawn_star_no_level_exit(o, o->oBehParams2ndByte + 3);
|
||||
bhv_spawn_star_no_level_exit(o, o->oBehParams2ndByte + 3, TRUE);
|
||||
o->oMipsStarStatus = MIPS_STAR_STATUS_ALREADY_SPAWNED_STAR;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -140,9 +140,20 @@ void bhv_spawned_star_loop(void) {
|
|||
o->oInteractStatus = 0;
|
||||
}
|
||||
|
||||
void bhv_spawn_star_no_level_exit(struct Object* object, u32 sp20) {
|
||||
void bhv_spawn_star_no_level_exit(struct Object* object, u32 sp20, u8 networkSendEvent) {
|
||||
// de-duplication checking
|
||||
for (int i = 0; i < gSpawnedStarNLECount; i++) {
|
||||
if (gSpawnedStarNLE[i] == sp20) { return; }
|
||||
}
|
||||
if (gSpawnedStarNLECount < 8) {
|
||||
gSpawnedStarNLE[gSpawnedStarNLECount++] = sp20;
|
||||
}
|
||||
|
||||
struct Object *sp1C = spawn_object(object, MODEL_STAR, bhvSpawnedStarNoLevelExit);
|
||||
sp1C->oBehParams = sp20 << 24;
|
||||
sp1C->oInteractionSubtype = INT_SUBTYPE_NO_EXIT;
|
||||
obj_set_angle(sp1C, 0, 0, 0);
|
||||
if (networkSendEvent) {
|
||||
network_send_spawn_star_nle(object, sp20);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -803,7 +803,7 @@ u32 interact_coin(struct MarioState *m, UNUSED u32 interactType, struct Object *
|
|||
|
||||
if (COURSE_IS_MAIN_COURSE(gCurrCourseNum) && m->numCoins - o->oDamageOrCoinValue < 100
|
||||
&& m->numCoins >= 100) {
|
||||
bhv_spawn_star_no_level_exit(m->marioObj, 6);
|
||||
bhv_spawn_star_no_level_exit(m->marioObj, 6, FALSE);
|
||||
}
|
||||
|
||||
if (o->oDamageOrCoinValue >= 2) {
|
||||
|
|
|
|||
|
|
@ -1312,8 +1312,10 @@ s32 init_level(void) {
|
|||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
gSpawnedStarDefault[i] = 0;
|
||||
gSpawnedStarNLE[i] = 0;
|
||||
}
|
||||
gSpawnedStarDefaultCount = 0;
|
||||
gSpawnedStarNLECount = 0;
|
||||
gSpawnedStarRedCoin = 0;
|
||||
gSpawnedStarHidden = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -131,15 +131,15 @@ static void toad_message_talking(void) {
|
|||
switch (gCurrentObject->oToadMessageDialogId) {
|
||||
case TOAD_STAR_1_DIALOG:
|
||||
gCurrentObject->oToadMessageDialogId = TOAD_STAR_1_DIALOG_AFTER;
|
||||
bhv_spawn_star_no_level_exit(gMarioStates[0].marioObj, 0);
|
||||
bhv_spawn_star_no_level_exit(gMarioStates[0].marioObj, 0, TRUE);
|
||||
break;
|
||||
case TOAD_STAR_2_DIALOG:
|
||||
gCurrentObject->oToadMessageDialogId = TOAD_STAR_2_DIALOG_AFTER;
|
||||
bhv_spawn_star_no_level_exit(gMarioStates[0].marioObj, 1);
|
||||
bhv_spawn_star_no_level_exit(gMarioStates[0].marioObj, 1, TRUE);
|
||||
break;
|
||||
case TOAD_STAR_3_DIALOG:
|
||||
gCurrentObject->oToadMessageDialogId = TOAD_STAR_3_DIALOG_AFTER;
|
||||
bhv_spawn_star_no_level_exit(gMarioStates[0].marioObj, 2);
|
||||
bhv_spawn_star_no_level_exit(gMarioStates[0].marioObj, 2, TRUE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,16 @@ u8 network_player_connected_count(void) {
|
|||
return count;
|
||||
}
|
||||
|
||||
struct NetworkPlayer* network_player_from_global_index(u8 globalIndex) {
|
||||
for (int i = 1; i < MAX_PLAYERS; i++) {
|
||||
if (!gNetworkPlayers[i].connected) { continue; }
|
||||
if (gNetworkPlayers[i].globalIndex == globalIndex) {
|
||||
return &gNetworkPlayers[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void network_player_update(void) {
|
||||
float elapsed = (clock() - gLastNetworkSend) / (float)CLOCKS_PER_SEC;
|
||||
if (elapsed > NETWORK_PLAYER_TIMEOUT / 3.0f) {
|
||||
|
|
|
|||
|
|
@ -33,6 +33,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);
|
||||
void network_player_update(void);
|
||||
u8 network_player_connected(enum NetworkPlayerType type, u8 globalIndex);
|
||||
u8 network_player_disconnected(u8 globalIndex);
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ void packet_receive(struct Packet* p) {
|
|||
case PACKET_OBJECT: network_receive_object(p); break;
|
||||
case PACKET_SPAWN_OBJECTS: network_receive_spawn_objects(p); break;
|
||||
case PACKET_SPAWN_STAR: network_receive_spawn_star(p); break;
|
||||
case PACKET_SPAWN_STAR_NLE: network_receive_spawn_star_nle(p); break;
|
||||
case PACKET_LEVEL_WARP: network_receive_level_warp(p); break;
|
||||
case PACKET_INSIDE_PAINTING: network_receive_inside_painting(p); break;
|
||||
case PACKET_COLLECT_STAR: network_receive_collect_star(p); break;
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ enum PacketType {
|
|||
PACKET_OBJECT,
|
||||
PACKET_SPAWN_OBJECTS,
|
||||
PACKET_SPAWN_STAR,
|
||||
PACKET_SPAWN_STAR_NLE,
|
||||
PACKET_LEVEL_WARP,
|
||||
PACKET_INSIDE_PAINTING,
|
||||
PACKET_COLLECT_STAR,
|
||||
|
|
@ -93,6 +94,8 @@ void network_receive_spawn_objects(struct Packet* p);
|
|||
// packet_spawn_star.c
|
||||
void network_send_spawn_star(struct Object* o, u8 starType, f32 x, f32 y, f32 z, u32 behParams);
|
||||
void network_receive_spawn_star(struct Packet* p);
|
||||
void network_send_spawn_star_nle(struct Object* o, u32 params);
|
||||
void network_receive_spawn_star_nle(struct Packet* p);
|
||||
|
||||
// packet_level_warp.c
|
||||
void network_send_level_warp_begin(void);
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
#include "src/game/object_helpers.h"
|
||||
|
||||
// defined in sparkle_spawn_star.inc.c
|
||||
void bhv_spawn_star_no_level_exit(struct Object* object, u32 sp20);
|
||||
void bhv_spawn_star_no_level_exit(struct Object* object, u32 sp20, u8 networkSendEvent);
|
||||
|
||||
static u8 localCoinId = 1;
|
||||
|
||||
|
|
@ -111,7 +111,7 @@ void network_receive_collect_coin(struct Packet* p) {
|
|||
if (COURSE_IS_MAIN_COURSE(gCurrCourseNum)
|
||||
&& gMarioStates[0].numCoins - coin->oDamageOrCoinValue < 100
|
||||
&& gMarioStates[0].numCoins >= 100) {
|
||||
bhv_spawn_star_no_level_exit(gMarioStates[1].marioObj, 6);
|
||||
bhv_spawn_star_no_level_exit(gMarioStates[1].marioObj, 6, FALSE);
|
||||
}
|
||||
|
||||
return;
|
||||
|
|
@ -125,6 +125,6 @@ SANITY_CHECK_COINS:;
|
|||
if (COURSE_IS_MAIN_COURSE(gCurrCourseNum)
|
||||
&& oldCoinCount < 100
|
||||
&& gMarioStates[0].numCoins >= 100) {
|
||||
bhv_spawn_star_no_level_exit(gMarioStates[1].marioObj, 6);
|
||||
bhv_spawn_star_no_level_exit(gMarioStates[1].marioObj, 6, FALSE);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,15 @@
|
|||
#include <stdio.h>
|
||||
#include "../network.h"
|
||||
#include "object_fields.h"
|
||||
#include "behavior_data.h"
|
||||
#include "src/game/behavior_actions.h"
|
||||
#include "pc/debuglog.h"
|
||||
|
||||
extern struct Object* gCurrentObject;
|
||||
|
||||
static u8 txSeqId = 0;
|
||||
static u8 rxLastSeqId = (u8)-1;
|
||||
|
||||
void network_send_spawn_star(struct Object* o, u8 starType, f32 x, f32 y, f32 z, u32 behParams) {
|
||||
struct Packet p;
|
||||
packet_init(&p, PACKET_SPAWN_STAR, true, true);
|
||||
|
|
@ -38,7 +43,7 @@ void network_receive_spawn_star(struct Packet* p) {
|
|||
case 0: o = spawn_default_star(x, y, z); break;
|
||||
case 1: o = spawn_red_coin_cutscene_star(x, y, z); break;
|
||||
case 2: o = spawn_no_exit_star(x, y, z); break;
|
||||
default: printf("UNKNOWN SPAWN STAR %d\n", starType);
|
||||
default: LOG_ERROR("UNKNOWN SPAWN STAR %d", starType);
|
||||
}
|
||||
gCurrentObject->oBehParams = oldBehParams;
|
||||
|
||||
|
|
@ -47,3 +52,62 @@ void network_receive_spawn_star(struct Packet* p) {
|
|||
packet_read(p, &o->oHomeX, sizeof(u32) * 3);
|
||||
}
|
||||
}
|
||||
|
||||
void network_send_spawn_star_nle(struct Object* o, u32 params) {
|
||||
u8 globalIndex = UNKNOWN_GLOBAL_INDEX;
|
||||
if (o->behavior == bhvMario) {
|
||||
u8 localIndex = o->oBehParams - 1;
|
||||
globalIndex = gNetworkPlayers[localIndex].globalIndex;
|
||||
}
|
||||
|
||||
struct Packet p;
|
||||
packet_init(&p, PACKET_SPAWN_STAR_NLE, true, true);
|
||||
packet_write(&p, &txSeqId, sizeof(u8));
|
||||
packet_write(&p, &globalIndex, sizeof(u8));
|
||||
packet_write(&p, &o->oSyncID, sizeof(u32));
|
||||
packet_write(&p, ¶ms, sizeof(u32));
|
||||
|
||||
network_send(&p);
|
||||
txSeqId++;
|
||||
}
|
||||
|
||||
void network_receive_spawn_star_nle(struct Packet* p) {
|
||||
u8 seqId = 0;
|
||||
u8 globalIndex = UNKNOWN_GLOBAL_INDEX;
|
||||
u32 syncId = 0;
|
||||
u32 params = 0;
|
||||
|
||||
packet_read(p, &seqId, sizeof(u8));
|
||||
packet_read(p, &globalIndex, sizeof(u8));
|
||||
packet_read(p, &syncId, sizeof(u32));
|
||||
packet_read(p, ¶ms, sizeof(u32));
|
||||
|
||||
// de-dup
|
||||
if (seqId == rxLastSeqId) {
|
||||
LOG_INFO("Already seen seqId %d", seqId);
|
||||
return;
|
||||
}
|
||||
|
||||
// grab network player first
|
||||
struct Object* object = NULL;
|
||||
if (globalIndex != UNKNOWN_GLOBAL_INDEX) {
|
||||
struct NetworkPlayer* np = network_player_from_global_index(globalIndex);
|
||||
if (np != NULL) {
|
||||
object = gMarioStates[np->localIndex].marioObj;
|
||||
}
|
||||
}
|
||||
|
||||
// check for sync id
|
||||
if (object == NULL) {
|
||||
object = gSyncObjects[syncId].o;
|
||||
}
|
||||
|
||||
// sanity check object
|
||||
if (object == NULL) {
|
||||
LOG_ERROR("Could not find object to attach to. %d %d", globalIndex, syncId);
|
||||
return;
|
||||
}
|
||||
|
||||
// spawn
|
||||
bhv_spawn_star_no_level_exit(object, params, FALSE);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue