mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2024-11-25 13:35:12 +00:00
Fixed max sync distance issue, synced Koopas
This commit is contained in:
parent
e61b137160
commit
0a2c76c76e
11 changed files with 120 additions and 28 deletions
|
@ -3949,6 +3949,7 @@
|
|||
<ClCompile Include="..\src\pc\network\packets\packet_object.c" />
|
||||
<ClCompile Include="..\src\pc\network\packets\packet_player.c" />
|
||||
<ClCompile Include="..\src\pc\network\packets\packet_read_write.c" />
|
||||
<ClCompile Include="..\src\pc\network\packets\packet_reliable.c" />
|
||||
<ClCompile Include="..\src\pc\pc_main.c" />
|
||||
<ClCompile Include="..\src\pc\platform.c" />
|
||||
<ClCompile Include="..\src\pc\ultra_reimplementation.c" />
|
||||
|
|
|
@ -14955,6 +14955,12 @@
|
|||
<ClCompile Include="..\src\pc\network\packets\packet_level_warp.c">
|
||||
<Filter>Source Files\src\pc\network\packets</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\pc\network\packets\packet_reliable.c">
|
||||
<Filter>Source Files\src\pc\network\packets</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\pc\network\packets\packet_inside_painting.c">
|
||||
<Filter>Source Files\src\pc\network\packets</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\actors\common0.h">
|
||||
|
|
|
@ -104,6 +104,7 @@ const LevelScript level_wf_entry[] = {
|
|||
LOAD_RAW( /*seg*/ 0x0F, _common0_geoSegmentRomStart, _common0_geoSegmentRomEnd),
|
||||
ALLOC_LEVEL_POOL(),
|
||||
MARIO(/*model*/ MODEL_MARIO, /*behParam*/ 0x00000001, /*beh*/ bhvMario),
|
||||
LUIGI(/*model*/ MODEL_LUIGI, /*behParam*/ 0x00000002, /*beh*/ bhvLuigi),
|
||||
JUMP_LINK(script_func_global_1),
|
||||
JUMP_LINK(script_func_global_2),
|
||||
JUMP_LINK(script_func_global_15),
|
||||
|
|
|
@ -17,7 +17,7 @@ void bhv_bobomb_init(void) {
|
|||
o->oFriction = 0.8;
|
||||
o->oBuoyancy = 1.3;
|
||||
o->oInteractionSubtype = INT_SUBTYPE_KICKABLE;
|
||||
network_init_object(o, 4000);
|
||||
network_init_object(o, 4000.0f);
|
||||
}
|
||||
|
||||
void bobomb_spawn_coin(void) {
|
||||
|
|
|
@ -20,7 +20,7 @@ void bhv_breakable_box_small_init(void) {
|
|||
obj_set_hitbox(o, &sBreakableBoxSmallHitbox);
|
||||
o->oAnimState = 1;
|
||||
o->activeFlags |= ACTIVE_FLAG_UNK9;
|
||||
network_init_object(o, 500);
|
||||
network_init_object(o, 500.0f);
|
||||
}
|
||||
|
||||
void small_breakable_box_spawn_dust(void) {
|
||||
|
|
|
@ -127,7 +127,7 @@ void bhv_goomba_init(void) {
|
|||
|
||||
o->oGravity = -8.0f / 3.0f * o->oGoombaScale;
|
||||
|
||||
network_init_object(o, 4000);
|
||||
network_init_object(o, 4000.0f);
|
||||
network_init_object_field(o, &o->oGoombaTargetYaw);
|
||||
network_init_object_field(o, &o->oGoombaWalkTimer);
|
||||
}
|
||||
|
|
|
@ -84,6 +84,12 @@ void bhv_koopa_init(void) {
|
|||
} else {
|
||||
o->oKoopaAgility = 1.0f;
|
||||
}
|
||||
|
||||
network_init_object(o, 4000.0f);
|
||||
network_init_object_field(o, &o->oSubAction);
|
||||
network_init_object_field(o, &o->oKoopaTargetYaw);
|
||||
network_init_object_field(o, &o->oKoopaCountdown);
|
||||
network_init_object_field(o, &o->oKoopaMovementType);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -105,8 +111,10 @@ static void koopa_play_footstep_sound(s8 animFrame1, s8 animFrame2) {
|
|||
* running away.
|
||||
*/
|
||||
static s32 koopa_check_run_from_mario(void) {
|
||||
if (o->oKoopaDistanceToMario < 300.0f
|
||||
&& abs_angle_diff(o->oKoopaAngleToMario, o->oMoveAngleYaw) < 0x3000) {
|
||||
struct Object* player = nearest_player_to_object(o);
|
||||
int distanceToPlayer = dist_between_objects(o, player);
|
||||
int angleToPlayer = obj_angle_to_object(o, player);
|
||||
if (distanceToPlayer < 300.0f && abs_angle_diff(angleToPlayer, o->oMoveAngleYaw) < 0x3000) {
|
||||
o->oAction = KOOPA_SHELLED_ACT_RUN_FROM_MARIO;
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -170,9 +178,12 @@ static void koopa_shelled_act_walk(void) {
|
|||
if (o->oKoopaTurningAwayFromWall) {
|
||||
o->oKoopaTurningAwayFromWall = obj_resolve_collisions_and_turn(o->oKoopaTargetYaw, 0x200);
|
||||
} else {
|
||||
struct Object* player = nearest_player_to_object(o);
|
||||
int distanceToPlayer = dist_between_objects(o, player);
|
||||
int angleToPlayer = obj_angle_to_object(o, player);
|
||||
// If far from home, then begin turning toward home
|
||||
if (o->oDistanceToMario >= 25000.0f) {
|
||||
o->oKoopaTargetYaw = o->oAngleToMario;
|
||||
if (distanceToPlayer >= 25000.0f) {
|
||||
o->oKoopaTargetYaw = angleToPlayer;
|
||||
}
|
||||
|
||||
o->oKoopaTurningAwayFromWall = obj_bounce_off_walls_edges_objects(&o->oKoopaTargetYaw);
|
||||
|
@ -202,18 +213,22 @@ static void koopa_shelled_act_run_from_mario(void) {
|
|||
cur_obj_init_animation_with_sound(1);
|
||||
koopa_play_footstep_sound(0, 11);
|
||||
|
||||
struct Object* player = nearest_player_to_object(o);
|
||||
int distanceToPlayer = dist_between_objects(o, player);
|
||||
int angleToPlayer = obj_angle_to_object(o, player);
|
||||
|
||||
// If far from home, run toward it
|
||||
if (o->oDistanceToMario >= 25000.0f) {
|
||||
o->oAngleToMario += 0x8000;
|
||||
o->oDistanceToMario = 0.0f;
|
||||
if (distanceToPlayer >= 25000.0f) {
|
||||
angleToPlayer += 0x8000;
|
||||
distanceToPlayer = 0.0f;
|
||||
}
|
||||
|
||||
if (o->oTimer > 30 && o->oDistanceToMario > 800.0f) {
|
||||
if (o->oTimer > 30 && distanceToPlayer > 800.0f) {
|
||||
if (obj_forward_vel_approach(0.0f, 1.0f)) {
|
||||
o->oAction = KOOPA_SHELLED_ACT_STOPPED;
|
||||
}
|
||||
} else {
|
||||
cur_obj_rotate_yaw_toward(o->oAngleToMario + 0x8000, 0x400);
|
||||
cur_obj_rotate_yaw_toward(angleToPlayer + 0x8000, 0x400);
|
||||
obj_forward_vel_approach(17.0f, 1.0f);
|
||||
}
|
||||
}
|
||||
|
@ -265,7 +280,9 @@ void shelled_koopa_attack_handler(s32 attackType) {
|
|||
|
||||
// If attacked from the side, get knocked away from mario
|
||||
if (attackType != ATTACK_FROM_ABOVE && attackType != ATTACK_GROUND_POUND_OR_TWIRL) {
|
||||
o->oMoveAngleYaw = obj_angle_to_object(gMarioObject, o);
|
||||
struct Object* player = nearest_player_to_object(o);
|
||||
int angleToPlayer = obj_angle_to_object(o, player);
|
||||
o->oMoveAngleYaw = angleToPlayer;
|
||||
}
|
||||
|
||||
cur_obj_set_model(MODEL_KOOPA_WITHOUT_SHELL);
|
||||
|
@ -285,6 +302,10 @@ void shelled_koopa_attack_handler(s32 attackType) {
|
|||
* Update function for both regular and tiny shelled koopa.
|
||||
*/
|
||||
static void koopa_shelled_update(void) {
|
||||
if (!cur_obj_has_model(MODEL_KOOPA_WITH_SHELL)) {
|
||||
cur_obj_set_model(MODEL_KOOPA_WITH_SHELL);
|
||||
}
|
||||
|
||||
cur_obj_update_floor_and_walls();
|
||||
obj_update_blinking(&o->oKoopaBlinkTimer, 20, 50, 4);
|
||||
|
||||
|
@ -336,9 +357,13 @@ static void koopa_unshelled_act_run(void) {
|
|||
if (o->oKoopaTurningAwayFromWall) {
|
||||
o->oKoopaTurningAwayFromWall = obj_resolve_collisions_and_turn(o->oKoopaTargetYaw, 0x600);
|
||||
} else {
|
||||
struct Object* player = nearest_player_to_object(o);
|
||||
int distanceToPlayer = dist_between_objects(o, player);
|
||||
int angleToPlayer = obj_angle_to_object(o, player);
|
||||
|
||||
// If far from home, then turn toward home
|
||||
if (o->oDistanceToMario >= 25000.0f) {
|
||||
o->oKoopaTargetYaw = o->oAngleToMario;
|
||||
if (distanceToPlayer >= 25000.0f) {
|
||||
o->oKoopaTargetYaw = angleToPlayer;
|
||||
}
|
||||
|
||||
// If shell exists, then turn toward shell
|
||||
|
@ -358,9 +383,9 @@ static void koopa_unshelled_act_run(void) {
|
|||
|
||||
// If mario is far away, or our running away from mario coincides with
|
||||
// running toward the shell
|
||||
if (o->oDistanceToMario > 800.0f
|
||||
if (distanceToPlayer > 800.0f
|
||||
|| (shell != NULL
|
||||
&& abs_angle_diff(o->oKoopaTargetYaw, o->oAngleToMario + 0x8000) < 0x2000)) {
|
||||
&& abs_angle_diff(o->oKoopaTargetYaw, angleToPlayer + 0x8000) < 0x2000)) {
|
||||
// then turn toward the shell
|
||||
cur_obj_rotate_yaw_toward(o->oKoopaTargetYaw, 0x600);
|
||||
} else {
|
||||
|
@ -395,6 +420,10 @@ static void koopa_unshelled_act_dive(void) {
|
|||
if (o->oTimer > 10) {
|
||||
shell = cur_obj_find_nearest_object_with_behavior(bhvKoopaShell, &distToShell);
|
||||
|
||||
struct Object* player = nearest_player_to_object(o);
|
||||
int distanceToPlayer = dist_between_objects(o, player);
|
||||
int angleToPlayer = obj_angle_to_object(o, player);
|
||||
|
||||
// If we got the shell and mario didn't, put on the shell
|
||||
//! The shell comes after koopa in processing order, and the shell is
|
||||
// responsible for positioning itself under mario.
|
||||
|
@ -403,8 +432,7 @@ static void koopa_unshelled_act_dive(void) {
|
|||
// units behind mario.
|
||||
// Using this, we can get the koopa to pick up and despawn its shell
|
||||
// while mario is riding it.
|
||||
if (shell != NULL && dist_between_objects(shell, gMarioObject) > 200.0f
|
||||
&& distToShell < 50.0f) {
|
||||
if (shell != NULL && distanceToPlayer && distToShell < 50.0f) {
|
||||
o->oKoopaMovementType = KOOPA_BP_NORMAL;
|
||||
o->oAction = KOOPA_SHELLED_ACT_LYING;
|
||||
o->oForwardVel *= 0.5f;
|
||||
|
@ -444,6 +472,10 @@ static void koopa_unshelled_act_unused3(void) {
|
|||
* Update function for koopa after losing his shell.
|
||||
*/
|
||||
static void koopa_unshelled_update(void) {
|
||||
if (!cur_obj_has_model(MODEL_KOOPA_WITHOUT_SHELL)) {
|
||||
cur_obj_set_model(MODEL_KOOPA_WITHOUT_SHELL);
|
||||
}
|
||||
|
||||
cur_obj_update_floor_and_walls();
|
||||
obj_update_blinking(&o->oKoopaBlinkTimer, 10, 15, 3);
|
||||
|
||||
|
@ -615,7 +647,10 @@ static void koopa_the_quick_act_race(void) {
|
|||
case KOOPA_THE_QUICK_SUB_ACT_RUN:
|
||||
koopa_the_quick_animate_footsteps();
|
||||
|
||||
if (o->parentObj->oKoopaRaceEndpointRaceStatus != 0 && o->oDistanceToMario > 1500.0f
|
||||
struct Object* player = nearest_player_to_object(o);
|
||||
int distanceToPlayer = dist_between_objects(o, player);
|
||||
|
||||
if (o->parentObj->oKoopaRaceEndpointRaceStatus != 0 && distanceToPlayer > 1500.0f
|
||||
&& (o->oPathedPrevWaypointFlags & WAYPOINT_MASK_00FF) < 28) {
|
||||
// Move faster if mario has already finished the race or
|
||||
// cheated by shooting from cannon
|
||||
|
@ -796,8 +831,12 @@ void bhv_koopa_update(void) {
|
|||
if (o->oKoopaMovementType >= KOOPA_BP_KOOPA_THE_QUICK_BASE) {
|
||||
koopa_the_quick_update();
|
||||
} else if (obj_update_standard_actions(o->oKoopaAgility * 1.5f)) {
|
||||
o->oKoopaDistanceToMario = o->oDistanceToMario;
|
||||
o->oKoopaAngleToMario = o->oAngleToMario;
|
||||
struct Object* player = nearest_player_to_object(o);
|
||||
int distanceToPlayer = dist_between_objects(o, player);
|
||||
int angleToPlayer = obj_angle_to_object(o, player);
|
||||
|
||||
o->oKoopaDistanceToMario = distanceToPlayer;
|
||||
o->oKoopaAngleToMario = angleToPlayer;
|
||||
treat_far_home_as_mario(1000.0f);
|
||||
|
||||
switch (o->oKoopaMovementType) {
|
||||
|
@ -824,7 +863,9 @@ void bhv_koopa_update(void) {
|
|||
*/
|
||||
void bhv_koopa_race_endpoint_update(void) {
|
||||
if (o->oKoopaRaceEndpointRaceBegun && !o->oKoopaRaceEndpointRaceEnded) {
|
||||
if (o->oKoopaRaceEndpointKoopaFinished || o->oDistanceToMario < 400.0f) {
|
||||
struct Object* player = nearest_player_to_object(o);
|
||||
int distanceToPlayer = dist_between_objects(o, player);
|
||||
if (o->oKoopaRaceEndpointKoopaFinished || distanceToPlayer < 400.0f) {
|
||||
o->oKoopaRaceEndpointRaceEnded = TRUE;
|
||||
level_control_timer(TIMER_CONTROL_STOP);
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ void koopa_shell_spawn_water_drop(void) {
|
|||
UNUSED s32 unused;
|
||||
struct Object *drop;
|
||||
spawn_object(o, MODEL_WAVE_TRAIL, bhvObjectWaveTrail);
|
||||
if (gMarioStates->forwardVel > 10.0f) {
|
||||
if (gMarioStates[o->heldByPlayerIndex].forwardVel > 10.0f) {
|
||||
drop = spawn_object_with_scale(o, MODEL_WHITE_PARTICLE_SMALL, bhvWaterDroplet, 1.5f);
|
||||
drop->oVelY = random_float() * 30.0f;
|
||||
obj_translate_xz_random(drop, 110.0f);
|
||||
|
@ -52,21 +52,32 @@ void koopa_shell_spawn_sparkles(f32 a) {
|
|||
}
|
||||
|
||||
void bhv_koopa_shell_loop(void) {
|
||||
if (o->oSyncID == 0) {
|
||||
network_init_object(o, 500.0f);
|
||||
network_init_object_field(o, &o->oInteractStatus);
|
||||
network_init_object_field(o, &o->oAction);
|
||||
}
|
||||
|
||||
struct Surface *sp34;
|
||||
obj_set_hitbox(o, &sKoopaShellHitbox);
|
||||
cur_obj_scale(1.0f);
|
||||
struct Object* player = NULL;
|
||||
switch (o->oAction) {
|
||||
case 0:
|
||||
cur_obj_update_floor_and_walls();
|
||||
cur_obj_if_hit_wall_bounce_away();
|
||||
if (o->oInteractStatus & INT_STATUS_INTERACTED)
|
||||
if (o->oInteractStatus & INT_STATUS_INTERACTED) {
|
||||
o->oAction++;
|
||||
player = nearest_player_to_object(o);
|
||||
o->heldByPlayerIndex = (player == gMarioObject) ? 0 : 1;
|
||||
}
|
||||
o->oFaceAngleYaw += 0x1000;
|
||||
cur_obj_move_standard(-20);
|
||||
koopa_shell_spawn_sparkles(10.0f);
|
||||
break;
|
||||
case 1:
|
||||
obj_copy_pos(o, gMarioObject);
|
||||
player = gMarioStates[o->heldByPlayerIndex].marioObj;
|
||||
obj_copy_pos(o, player);
|
||||
sp34 = cur_obj_update_floor_height_and_get_floor();
|
||||
if (absf(find_water_level(o->oPosX, o->oPosZ) - o->oPosY) < 10.0f)
|
||||
koopa_shell_spawn_water_drop();
|
||||
|
@ -77,7 +88,7 @@ void bhv_koopa_shell_loop(void) {
|
|||
koopa_shell_spawn_sparkles(10.0f);
|
||||
} else
|
||||
koopa_shell_spawn_sparkles(10.0f);
|
||||
o->oFaceAngleYaw = gMarioObject->oMoveAngleYaw;
|
||||
o->oFaceAngleYaw = player->oMoveAngleYaw;
|
||||
if (o->oInteractStatus & INT_STATUS_STOP_RIDING) {
|
||||
obj_mark_for_deletion(o);
|
||||
spawn_mist_particles();
|
||||
|
|
|
@ -515,6 +515,27 @@ s32 is_point_within_radius_of_mario(f32 x, f32 y, f32 z, s32 dist) {
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns either gMarioObject or gLuigiObject depending on what is closer
|
||||
*/
|
||||
struct MarioState* nearest_mario_state_to_object(struct Object *obj) {
|
||||
f32 mx = gMarioState[0].marioObj->header.gfx.pos[0] - obj->oPosX;
|
||||
f32 my = gMarioState[0].marioObj->header.gfx.pos[1] - obj->oPosY;
|
||||
f32 mz = gMarioState[0].marioObj->header.gfx.pos[2] - obj->oPosZ;
|
||||
mx *= mx;
|
||||
my *= my;
|
||||
mz *= mz;
|
||||
|
||||
f32 lx = gMarioState[1].marioObj->header.gfx.pos[0] - obj->oPosX;
|
||||
f32 ly = gMarioState[1].marioObj->header.gfx.pos[1] - obj->oPosY;
|
||||
f32 lz = gMarioState[1].marioObj->header.gfx.pos[2] - obj->oPosZ;
|
||||
lx *= lx;
|
||||
ly *= ly;
|
||||
lz *= lz;
|
||||
|
||||
return (mx + my + mz <= lx + ly + lz) ? &gMarioState[0] : &gMarioState[1];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns either gMarioObject or gLuigiObject depending on what is closer
|
||||
*/
|
||||
|
|
|
@ -35,6 +35,7 @@ struct SyncObject {
|
|||
float maxSyncDistance;
|
||||
bool owned;
|
||||
unsigned int ticksSinceUpdate;
|
||||
void* behavior;
|
||||
u8 extraFieldCount;
|
||||
void* extraFields[MAX_SYNC_OBJECT_FIELDS];
|
||||
};
|
||||
|
|
|
@ -23,6 +23,7 @@ void network_init_object(struct Object *o, float maxSyncDistance) {
|
|||
so->owned = false;
|
||||
so->ticksSinceUpdate = -1;
|
||||
so->extraFieldCount = 0;
|
||||
so->behavior = o->behavior;
|
||||
memset(so->extraFields, 0, sizeof(void*) * MAX_SYNC_OBJECT_FIELDS);
|
||||
}
|
||||
|
||||
|
@ -41,6 +42,7 @@ void network_send_object(struct Object* o) {
|
|||
struct Packet p;
|
||||
packet_init(&p, PACKET_OBJECT, reliable);
|
||||
packet_write(&p, &o->oSyncID, 4);
|
||||
packet_write(&p, &so->behavior, sizeof(void*));
|
||||
packet_write(&p, &o->activeFlags, 2);
|
||||
packet_write(&p, &o->oPosX, 28);
|
||||
packet_write(&p, &o->oAction, 4);
|
||||
|
@ -57,6 +59,10 @@ void network_send_object(struct Object* o) {
|
|||
|
||||
if (o->activeFlags == ACTIVE_FLAG_DEACTIVATED) { forget_sync_object(so); }
|
||||
|
||||
if (o->behavior != so->behavior) {
|
||||
printf("network_send_object() BEHAVIOR MISMATCH!\n");
|
||||
}
|
||||
|
||||
network_send(&p);
|
||||
}
|
||||
|
||||
|
@ -91,6 +97,7 @@ void network_receive_object(struct Packet* p) {
|
|||
}
|
||||
|
||||
// write object flags
|
||||
packet_read(p, &so->behavior, sizeof(void*));
|
||||
packet_read(p, &o->activeFlags, 2);
|
||||
packet_read(p, &o->oPosX, 28);
|
||||
packet_read(p, &o->oAction, 4);
|
||||
|
@ -106,11 +113,14 @@ void network_receive_object(struct Packet* p) {
|
|||
packet_read(p, so->extraFields[i], 4);
|
||||
}
|
||||
|
||||
if (o->behavior != so->behavior) {
|
||||
printf("network_receive_object() BEHAVIOR MISMATCH!\n");
|
||||
}
|
||||
|
||||
// deactivated
|
||||
if (o->activeFlags == ACTIVE_FLAG_DEACTIVATED) {
|
||||
forget_sync_object(so);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
float player_distance(struct MarioState* marioState, struct Object* o) {
|
||||
|
|
Loading…
Reference in a new issue