Synchronized 3 types of star spawning, adjusted star interactions

This commit is contained in:
MysterD 2020-08-08 18:57:04 -07:00
parent 7f5dec337e
commit b07aa565d4
12 changed files with 147 additions and 24 deletions

View file

@ -14967,6 +14967,9 @@
<ClCompile Include="..\src\pc\network\packets\packet_collect_coin.c"> <ClCompile Include="..\src\pc\network\packets\packet_collect_coin.c">
<Filter>Source Files\src\pc\network\packets</Filter> <Filter>Source Files\src\pc\network\packets</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\src\pc\network\packets\packet_spawn_objects.c">
<Filter>Source Files\src\pc\network\packets</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\actors\common0.h"> <ClCompile Include="..\actors\common0.h">

View file

@ -53,6 +53,10 @@ u8 gWarpTransBlue = 0;
s16 gCurrSaveFileNum = 1; s16 gCurrSaveFileNum = 1;
s16 gCurrLevelNum = LEVEL_MIN; s16 gCurrLevelNum = LEVEL_MIN;
u8 gSpawnedStarDefault = 0;
u8 gSpawnedStarRedCoin = 0;
u8 gSpawnedStarHidden = 0;
/* /*
* The following two tables are used in get_mario_spawn_type() to determine spawn type * The following two tables are used in get_mario_spawn_type() to determine spawn type
* from warp behavior. * from warp behavior.

View file

@ -138,6 +138,9 @@ extern struct Area *gCurrentArea;
extern s16 gCurrSaveFileNum; extern s16 gCurrSaveFileNum;
extern s16 gCurrLevelNum; extern s16 gCurrLevelNum;
extern u8 gSpawnedStarDefault;
extern u8 gSpawnedStarRedCoin;
extern u8 gSpawnedStarHidden;
void override_viewport_and_clip(Vp *a, Vp *b, u8 c, u8 d, u8 e); void override_viewport_and_clip(Vp *a, Vp *b, u8 c, u8 d, u8 e);
void print_intro_text(void); void print_intro_text(void);

View file

@ -576,4 +576,8 @@ Gfx *geo_scale_bowser_key(s32 run, struct GraphNode *node, UNUSED f32 mtx[4][4])
extern struct WaterDropletParams gShallowWaterSplashDropletParams; extern struct WaterDropletParams gShallowWaterSplashDropletParams;
extern struct WaterDropletParams gShallowWaterWaveDropletParams; extern struct WaterDropletParams gShallowWaterWaveDropletParams;
struct Object* spawn_default_star(f32 x, f32 y, f32 z);
struct Object* spawn_red_coin_cutscene_star(f32 x, f32 y, f32 z);
struct Object* spawn_no_exit_star(f32 x, f32 y, f32 z);
#endif // BEHAVIOR_ACTIONS_H #endif // BEHAVIOR_ACTIONS_H

View file

@ -121,23 +121,35 @@ struct Object *spawn_star(struct Object *sp30, f32 sp34, f32 sp38, f32 sp3C) {
return sp30; return sp30;
} }
void spawn_default_star(f32 sp20, f32 sp24, f32 sp28) { struct Object* spawn_default_star(f32 x, f32 y, f32 z) {
struct Object *sp1C; if (gSpawnedStarDefault) { return NULL; }
sp1C = spawn_star(sp1C, sp20, sp24, sp28); struct Object *star;
sp1C->oBehParams2ndByte = 0; star = spawn_star(star, x, y, z);
star->oBehParams2ndByte = 0;
gSpawnedStarDefault = TRUE;
network_send_spawn_star(star, 0, x, y, z);
return star;
} }
void spawn_red_coin_cutscene_star(f32 sp20, f32 sp24, f32 sp28) { struct Object* spawn_red_coin_cutscene_star(f32 x, f32 y, f32 z) {
struct Object *sp1C; if (gSpawnedStarRedCoin) { return NULL; }
sp1C = spawn_star(sp1C, sp20, sp24, sp28); struct Object * star;
sp1C->oBehParams2ndByte = 1; star = spawn_star(star, x, y, z);
star->oBehParams2ndByte = 1;
gSpawnedStarRedCoin = TRUE;
network_send_spawn_star(star, 1, x, y, z);
return star;
} }
void spawn_no_exit_star(f32 sp20, f32 sp24, f32 sp28) { struct Object* spawn_no_exit_star(f32 x, f32 y, f32 z) {
struct Object *sp1C; if (gSpawnedStarHidden) { return NULL; }
sp1C = spawn_star(sp1C, sp20, sp24, sp28); struct Object * star;
sp1C->oBehParams2ndByte = 1; star = spawn_star(star, x, y, z);
sp1C->oInteractionSubtype |= INT_SUBTYPE_NO_EXIT; star->oBehParams2ndByte = 1;
star->oInteractionSubtype |= INT_SUBTYPE_NO_EXIT;
gSpawnedStarHidden = TRUE;
network_send_spawn_star(star, 2, x, y, z);
return star;
} }
void bhv_hidden_red_coin_star_init(void) { void bhv_hidden_red_coin_star_init(void) {

View file

@ -762,7 +762,7 @@ u32 interact_coin(struct MarioState *m, UNUSED u32 interactType, struct Object *
&& m->numCoins >= 100) { && m->numCoins >= 100) {
bhv_spawn_star_no_level_exit(m->marioObj, 6); bhv_spawn_star_no_level_exit(m->marioObj, 6);
} }
if (o->oDamageOrCoinValue >= 2) { if (o->oDamageOrCoinValue >= 2) {
queue_rumble_data(5, 80); queue_rumble_data(5, 80);
} }
@ -779,6 +779,9 @@ u32 interact_water_ring(struct MarioState *m, UNUSED u32 interactType, struct Ob
} }
u32 interact_star_or_key(struct MarioState *m, UNUSED u32 interactType, struct Object *o) { u32 interact_star_or_key(struct MarioState *m, UNUSED u32 interactType, struct Object *o) {
// only allow for local player
if (m != &gMarioStates[0]) { return; }
u32 starIndex; u32 starIndex;
u32 starGrabAction = ACT_STAR_DANCE_EXIT; u32 starGrabAction = ACT_STAR_DANCE_EXIT;
u32 noExit = (o->oInteractionSubtype & INT_SUBTYPE_NO_EXIT) != 0; u32 noExit = (o->oInteractionSubtype & INT_SUBTYPE_NO_EXIT) != 0;
@ -822,7 +825,7 @@ u32 interact_star_or_key(struct MarioState *m, UNUSED u32 interactType, struct O
if (m == &gMarioStates[0]) { if (m == &gMarioStates[0]) {
// sync the star collection // sync the star collection
network_send_collect_star(m->numCoins, starIndex); network_send_collect_star(o, m->numCoins, starIndex);
} }
save_file_collect_star_or_key(m->numCoins, starIndex); save_file_collect_star_or_key(m->numCoins, starIndex);
@ -1127,7 +1130,7 @@ u32 interact_tornado(struct MarioState *m, UNUSED u32 interactType, struct Objec
play_sound(SOUND_MARIO_WAAAOOOW, m->marioObj->header.gfx.cameraToObject); play_sound(SOUND_MARIO_WAAAOOOW, m->marioObj->header.gfx.cameraToObject);
queue_rumble_data(30, 60); queue_rumble_data(30, 60);
return set_mario_action(m, ACT_TORNADO_TWIRLING, m->action == ACT_TWIRLING); return set_mario_action(m, ACT_TORNADO_TWIRLING, m->action == ACT_TWIRLING);
} }
@ -1149,7 +1152,7 @@ u32 interact_whirlpool(struct MarioState *m, UNUSED u32 interactType, struct Obj
play_sound(SOUND_MARIO_WAAAOOOW, m->marioObj->header.gfx.cameraToObject); play_sound(SOUND_MARIO_WAAAOOOW, m->marioObj->header.gfx.cameraToObject);
queue_rumble_data(30, 60); queue_rumble_data(30, 60);
return set_mario_action(m, ACT_CAUGHT_IN_WHIRLPOOL, 0); return set_mario_action(m, ACT_CAUGHT_IN_WHIRLPOOL, 0);
} }
@ -1184,7 +1187,7 @@ u32 interact_flame(struct MarioState *m, UNUSED u32 interactType, struct Object
if (!sInvulnerable && !(m->flags & MARIO_METAL_CAP) && !(m->flags & MARIO_VANISH_CAP) if (!sInvulnerable && !(m->flags & MARIO_METAL_CAP) && !(m->flags & MARIO_VANISH_CAP)
&& !(o->oInteractionSubtype & get_invincibility_flag(m))) { && !(o->oInteractionSubtype & get_invincibility_flag(m))) {
queue_rumble_data(5, 80); queue_rumble_data(5, 80);
o->oInteractStatus = INT_STATUS_INTERACTED; o->oInteractStatus = INT_STATUS_INTERACTED;
m->interactObj = o; m->interactObj = o;
@ -1284,7 +1287,7 @@ u32 interact_bully(struct MarioState *m, UNUSED u32 interactType, struct Object
push_mario_out_of_object(m, o, 5.0f); push_mario_out_of_object(m, o, 5.0f);
drop_and_set_mario_action(m, bully_knock_back_mario(m), 0); drop_and_set_mario_action(m, bully_knock_back_mario(m), 0);
queue_rumble_data(5, 80); queue_rumble_data(5, 80);
return TRUE; return TRUE;
} }

View file

@ -1190,6 +1190,10 @@ s32 init_level(void) {
sTransitionTimer = 0; sTransitionTimer = 0;
D_80339EE0 = 0; D_80339EE0 = 0;
gSpawnedStarDefault = 0;
gSpawnedStarRedCoin = 0;
gSpawnedStarHidden = 0;
if (gCurrCreditsEntry == NULL) { if (gCurrCreditsEntry == NULL) {
gHudDisplay.flags = HUD_DISPLAY_DEFAULT; gHudDisplay.flags = HUD_DISPLAY_DEFAULT;
} else { } else {
@ -1237,7 +1241,7 @@ s32 init_level(void) {
set_background_music(gCurrentArea->musicParam, gCurrentArea->musicParam2, 0); set_background_music(gCurrentArea->musicParam, gCurrentArea->musicParam2, 0);
} }
} }
if (gCurrDemoInput == NULL) { if (gCurrDemoInput == NULL) {
cancel_rumble(); cancel_rumble();
} }

View file

@ -160,6 +160,6 @@ void bhv_free_bowling_ball_roll_loop(void); /* likely unused */
void bhv_free_bowling_ball_loop(void); /* likely unused */ void bhv_free_bowling_ball_loop(void); /* likely unused */
void bhv_rr_cruiser_wing_init(void); void bhv_rr_cruiser_wing_init(void);
void bhv_rr_cruiser_wing_loop(void); void bhv_rr_cruiser_wing_loop(void);
void spawn_default_star(f32 sp20, f32 sp24, f32 sp28); struct Object* spawn_default_star(f32 sp20, f32 sp24, f32 sp28);
#endif // OBJ_BEHAVIORS_H #endif // OBJ_BEHAVIORS_H

View file

@ -109,6 +109,7 @@ void network_update(void) {
case PACKET_PLAYER: network_receive_player(&p); break; case PACKET_PLAYER: network_receive_player(&p); break;
case PACKET_OBJECT: network_receive_object(&p); break; case PACKET_OBJECT: network_receive_object(&p); break;
case PACKET_SPAWN_OBJECTS: network_receive_spawn_objects(&p); break; case PACKET_SPAWN_OBJECTS: network_receive_spawn_objects(&p); break;
case PACKET_SPAWN_STAR: network_receive_spawn_star(&p); break;
case PACKET_LEVEL_WARP: network_receive_level_warp(&p); break; case PACKET_LEVEL_WARP: network_receive_level_warp(&p); break;
case PACKET_INSIDE_PAINTING: network_receive_inside_painting(&p); break; case PACKET_INSIDE_PAINTING: network_receive_inside_painting(&p); break;
case PACKET_COLLECT_STAR: network_receive_collect_star(&p); break; case PACKET_COLLECT_STAR: network_receive_collect_star(&p); break;
@ -131,4 +132,4 @@ void network_shutdown(void) {
wprintf(L"%s closesocket failed with error %d\n", NETWORKTYPESTR, WSAGetLastError()); wprintf(L"%s closesocket failed with error %d\n", NETWORKTYPESTR, WSAGetLastError());
} }
WSACleanup(); WSACleanup();
} }

View file

@ -19,6 +19,7 @@ enum PacketType {
PACKET_PLAYER, PACKET_PLAYER,
PACKET_OBJECT, PACKET_OBJECT,
PACKET_SPAWN_OBJECTS, PACKET_SPAWN_OBJECTS,
PACKET_SPAWN_STAR,
PACKET_LEVEL_WARP, PACKET_LEVEL_WARP,
PACKET_INSIDE_PAINTING, PACKET_INSIDE_PAINTING,
PACKET_COLLECT_STAR, PACKET_COLLECT_STAR,
@ -83,13 +84,16 @@ void network_receive_object(struct Packet* p);
void network_send_spawn_objects(struct Object* objects[], u32 models[], u8 objectCount); void network_send_spawn_objects(struct Object* objects[], u32 models[], u8 objectCount);
void network_receive_spawn_objects(struct Packet* p); void network_receive_spawn_objects(struct Packet* p);
void network_send_spawn_star(struct Object* o, u8 starType, f32 x, f32 y, f32 z);
void network_receive_spawn_star(struct Packet* p);
void network_update_level_warp(void); void network_update_level_warp(void);
void network_receive_level_warp(struct Packet* p); void network_receive_level_warp(struct Packet* p);
void network_update_inside_painting(void); void network_update_inside_painting(void);
void network_receive_inside_painting(struct Packet* p); void network_receive_inside_painting(struct Packet* p);
void network_send_collect_star(s16 coinScore, s16 starIndex); void network_send_collect_star(struct Object* o, s16 coinScore, s16 starIndex);
void network_receive_collect_star(struct Packet* p); void network_receive_collect_star(struct Packet* p);
void network_send_collect_coin(struct Object* o); void network_send_collect_coin(struct Object* o);

View file

@ -1,16 +1,52 @@
#include <stdio.h> #include <stdio.h>
#include "../network.h" #include "../network.h"
#include "course_table.h" #include "course_table.h"
#include "object_fields.h"
#include "object_constants.h"
#include "game/interaction.h"
extern s16 gCurrSaveFileNum; extern s16 gCurrSaveFileNum;
extern s16 gCurrCourseNum; extern s16 gCurrCourseNum;
void network_send_collect_star(s16 coinScore, s16 starIndex) { static f32 dist_to_pos(struct Object* o, f32* pos) {
f32 x = (f32)o->oPosX - pos[0]; x *= x;
f32 y = (f32)o->oPosY - pos[1]; y *= y;
f32 z = (f32)o->oPosZ - pos[2]; z *= z;
return (f32)sqrt(x + y + z);
}
static struct Object* find_nearest_star(const BehaviorScript* behavior, f32* pos, float minDist) {
uintptr_t* behaviorAddr = segmented_to_virtual(behavior);
struct Object* closestObj = NULL;
struct Object* obj;
struct ObjectNode* listHead;
extern struct ObjectNode* gObjectLists;
listHead = &gObjectLists[get_object_list_from_behavior(behaviorAddr)];
obj = (struct Object*) listHead->next;
while (obj != (struct Object*) listHead) {
if (obj->behavior == behaviorAddr && obj->activeFlags != ACTIVE_FLAG_DEACTIVATED) {
f32 objDist = dist_to_pos(obj, pos);
if (objDist < minDist) {
closestObj = obj;
minDist = objDist;
}
}
obj = (struct Object*) obj->header.next;
}
return closestObj;
}
void network_send_collect_star(struct Object* o, s16 coinScore, s16 starIndex) {
struct Packet p; struct Packet p;
packet_init(&p, PACKET_COLLECT_STAR, true); packet_init(&p, PACKET_COLLECT_STAR, true);
packet_write(&p, &gCurrSaveFileNum, sizeof(s16)); packet_write(&p, &gCurrSaveFileNum, sizeof(s16));
packet_write(&p, &gCurrCourseNum, sizeof(s16)); packet_write(&p, &gCurrCourseNum, sizeof(s16));
packet_write(&p, &o->oPosX, sizeof(u32) * 3);
packet_write(&p, &o->behavior, sizeof(void*));
packet_write(&p, &coinScore, sizeof(s16)); packet_write(&p, &coinScore, sizeof(s16));
packet_write(&p, &starIndex, sizeof(s16)); packet_write(&p, &starIndex, sizeof(s16));
@ -18,12 +54,16 @@ void network_send_collect_star(s16 coinScore, s16 starIndex) {
} }
void network_receive_collect_star(struct Packet* p) { void network_receive_collect_star(struct Packet* p) {
u32 pos[3] = { 0 };
void* behavior = NULL;
s16 coinScore, starIndex; s16 coinScore, starIndex;
s16 lastSaveFileNum = gCurrSaveFileNum; s16 lastSaveFileNum = gCurrSaveFileNum;
s16 lastCourseNum = gCurrCourseNum; s16 lastCourseNum = gCurrCourseNum;
packet_read(p, &gCurrSaveFileNum, sizeof(s16)); packet_read(p, &gCurrSaveFileNum, sizeof(s16));
packet_read(p, &gCurrCourseNum, sizeof(s16)); packet_read(p, &gCurrCourseNum, sizeof(s16));
packet_read(p, &pos, sizeof(u32) * 3);
packet_read(p, &behavior, sizeof(void*));
packet_read(p, &coinScore, sizeof(s16)); packet_read(p, &coinScore, sizeof(s16));
packet_read(p, &starIndex, sizeof(s16)); packet_read(p, &starIndex, sizeof(s16));
@ -36,4 +76,9 @@ void network_receive_collect_star(struct Packet* p) {
gCurrSaveFileNum = lastSaveFileNum; gCurrSaveFileNum = lastSaveFileNum;
gCurrCourseNum = lastCourseNum; gCurrCourseNum = lastCourseNum;
struct Object* star = find_nearest_star(behavior, pos, 500);
if (star != NULL) {
star->oInteractStatus = INT_STATUS_INTERACTED;
}
} }

View file

@ -0,0 +1,40 @@
#include <stdio.h>
#include "../network.h"
#include "object_fields.h"
void network_send_spawn_star(struct Object* o, u8 starType, f32 x, f32 y, f32 z) {
struct Packet p;
packet_init(&p, PACKET_SPAWN_STAR, true);
packet_write(&p, &starType, sizeof(u8));
packet_write(&p, &x, sizeof(f32));
packet_write(&p, &y, sizeof(f32));
packet_write(&p, &z, sizeof(f32));
packet_write(&p, &o->oPosX, sizeof(u32) * 3);
packet_write(&p, &o->oHomeX, sizeof(u32) * 3);
network_send(&p);
}
void network_receive_spawn_star(struct Packet* p) {
u8 starType;
f32 x, y, z;
packet_read(p, &starType, sizeof(u8));
packet_read(p, &x, sizeof(f32));
packet_read(p, &y, sizeof(f32));
packet_read(p, &z, sizeof(f32));
struct Object* o = NULL;
switch (starType) {
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);
}
if (o != NULL) {
packet_read(p, &o->oPosX, sizeof(u32) * 3);
packet_read(p, &o->oHomeX, sizeof(u32) * 3);
}
}