mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2025-10-30 08:01:01 +00:00
Synchronized 3 types of star spawning, adjusted star interactions
This commit is contained in:
parent
7f5dec337e
commit
b07aa565d4
12 changed files with 147 additions and 24 deletions
|
|
@ -14967,6 +14967,9 @@
|
|||
<ClCompile Include="..\src\pc\network\packets\packet_collect_coin.c">
|
||||
<Filter>Source Files\src\pc\network\packets</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\pc\network\packets\packet_spawn_objects.c">
|
||||
<Filter>Source Files\src\pc\network\packets</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\actors\common0.h">
|
||||
|
|
|
|||
|
|
@ -53,6 +53,10 @@ u8 gWarpTransBlue = 0;
|
|||
s16 gCurrSaveFileNum = 1;
|
||||
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
|
||||
* from warp behavior.
|
||||
|
|
|
|||
|
|
@ -138,6 +138,9 @@ extern struct Area *gCurrentArea;
|
|||
extern s16 gCurrSaveFileNum;
|
||||
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 print_intro_text(void);
|
||||
|
|
|
|||
|
|
@ -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 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
|
||||
|
|
|
|||
|
|
@ -121,23 +121,35 @@ struct Object *spawn_star(struct Object *sp30, f32 sp34, f32 sp38, f32 sp3C) {
|
|||
return sp30;
|
||||
}
|
||||
|
||||
void spawn_default_star(f32 sp20, f32 sp24, f32 sp28) {
|
||||
struct Object *sp1C;
|
||||
sp1C = spawn_star(sp1C, sp20, sp24, sp28);
|
||||
sp1C->oBehParams2ndByte = 0;
|
||||
struct Object* spawn_default_star(f32 x, f32 y, f32 z) {
|
||||
if (gSpawnedStarDefault) { return NULL; }
|
||||
struct Object *star;
|
||||
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 *sp1C;
|
||||
sp1C = spawn_star(sp1C, sp20, sp24, sp28);
|
||||
sp1C->oBehParams2ndByte = 1;
|
||||
struct Object* spawn_red_coin_cutscene_star(f32 x, f32 y, f32 z) {
|
||||
if (gSpawnedStarRedCoin) { return NULL; }
|
||||
struct Object * star;
|
||||
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 *sp1C;
|
||||
sp1C = spawn_star(sp1C, sp20, sp24, sp28);
|
||||
sp1C->oBehParams2ndByte = 1;
|
||||
sp1C->oInteractionSubtype |= INT_SUBTYPE_NO_EXIT;
|
||||
struct Object* spawn_no_exit_star(f32 x, f32 y, f32 z) {
|
||||
if (gSpawnedStarHidden) { return NULL; }
|
||||
struct Object * star;
|
||||
star = spawn_star(star, x, y, z);
|
||||
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) {
|
||||
|
|
|
|||
|
|
@ -762,7 +762,7 @@ u32 interact_coin(struct MarioState *m, UNUSED u32 interactType, struct Object *
|
|||
&& m->numCoins >= 100) {
|
||||
bhv_spawn_star_no_level_exit(m->marioObj, 6);
|
||||
}
|
||||
|
||||
|
||||
if (o->oDamageOrCoinValue >= 2) {
|
||||
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) {
|
||||
// only allow for local player
|
||||
if (m != &gMarioStates[0]) { return; }
|
||||
|
||||
u32 starIndex;
|
||||
u32 starGrabAction = ACT_STAR_DANCE_EXIT;
|
||||
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]) {
|
||||
// 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);
|
||||
|
||||
|
|
@ -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);
|
||||
queue_rumble_data(30, 60);
|
||||
|
||||
|
||||
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);
|
||||
queue_rumble_data(30, 60);
|
||||
|
||||
|
||||
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)
|
||||
&& !(o->oInteractionSubtype & get_invincibility_flag(m))) {
|
||||
queue_rumble_data(5, 80);
|
||||
|
||||
|
||||
o->oInteractStatus = INT_STATUS_INTERACTED;
|
||||
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);
|
||||
drop_and_set_mario_action(m, bully_knock_back_mario(m), 0);
|
||||
queue_rumble_data(5, 80);
|
||||
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1190,6 +1190,10 @@ s32 init_level(void) {
|
|||
sTransitionTimer = 0;
|
||||
D_80339EE0 = 0;
|
||||
|
||||
gSpawnedStarDefault = 0;
|
||||
gSpawnedStarRedCoin = 0;
|
||||
gSpawnedStarHidden = 0;
|
||||
|
||||
if (gCurrCreditsEntry == NULL) {
|
||||
gHudDisplay.flags = HUD_DISPLAY_DEFAULT;
|
||||
} else {
|
||||
|
|
@ -1237,7 +1241,7 @@ s32 init_level(void) {
|
|||
set_background_music(gCurrentArea->musicParam, gCurrentArea->musicParam2, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (gCurrDemoInput == NULL) {
|
||||
cancel_rumble();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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_rr_cruiser_wing_init(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
|
||||
|
|
|
|||
|
|
@ -109,6 +109,7 @@ void network_update(void) {
|
|||
case PACKET_PLAYER: network_receive_player(&p); break;
|
||||
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_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;
|
||||
|
|
@ -131,4 +132,4 @@ void network_shutdown(void) {
|
|||
wprintf(L"%s closesocket failed with error %d\n", NETWORKTYPESTR, WSAGetLastError());
|
||||
}
|
||||
WSACleanup();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ enum PacketType {
|
|||
PACKET_PLAYER,
|
||||
PACKET_OBJECT,
|
||||
PACKET_SPAWN_OBJECTS,
|
||||
PACKET_SPAWN_STAR,
|
||||
PACKET_LEVEL_WARP,
|
||||
PACKET_INSIDE_PAINTING,
|
||||
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_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_receive_level_warp(struct Packet* p);
|
||||
|
||||
void network_update_inside_painting(void);
|
||||
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_send_collect_coin(struct Object* o);
|
||||
|
|
|
|||
|
|
@ -1,16 +1,52 @@
|
|||
#include <stdio.h>
|
||||
#include "../network.h"
|
||||
#include "course_table.h"
|
||||
#include "object_fields.h"
|
||||
#include "object_constants.h"
|
||||
#include "game/interaction.h"
|
||||
|
||||
extern s16 gCurrSaveFileNum;
|
||||
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;
|
||||
packet_init(&p, PACKET_COLLECT_STAR, true);
|
||||
|
||||
packet_write(&p, &gCurrSaveFileNum, 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, &starIndex, sizeof(s16));
|
||||
|
||||
|
|
@ -18,12 +54,16 @@ void network_send_collect_star(s16 coinScore, s16 starIndex) {
|
|||
}
|
||||
|
||||
void network_receive_collect_star(struct Packet* p) {
|
||||
u32 pos[3] = { 0 };
|
||||
void* behavior = NULL;
|
||||
s16 coinScore, starIndex;
|
||||
s16 lastSaveFileNum = gCurrSaveFileNum;
|
||||
s16 lastCourseNum = gCurrCourseNum;
|
||||
|
||||
packet_read(p, &gCurrSaveFileNum, 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, &starIndex, sizeof(s16));
|
||||
|
||||
|
|
@ -36,4 +76,9 @@ void network_receive_collect_star(struct Packet* p) {
|
|||
|
||||
gCurrSaveFileNum = lastSaveFileNum;
|
||||
gCurrCourseNum = lastCourseNum;
|
||||
|
||||
struct Object* star = find_nearest_star(behavior, pos, 500);
|
||||
if (star != NULL) {
|
||||
star->oInteractStatus = INT_STATUS_INTERACTED;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
40
src/pc/network/packets/packet_spawn_star.c
Normal file
40
src/pc/network/packets/packet_spawn_star.c
Normal 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);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue