Fixed visual bug when both players are sliding
This commit is contained in:
parent
bdf269c262
commit
48f42d1873
|
@ -493,6 +493,9 @@
|
|||
<ClCompile Include="..\actors\lakitu_enemy\model.inc.c" />
|
||||
<ClCompile Include="..\actors\leaves\geo.inc.c" />
|
||||
<ClCompile Include="..\actors\leaves\model.inc.c" />
|
||||
<ClCompile Include="..\actors\luigi\geo.inc.c" />
|
||||
<ClCompile Include="..\actors\luigi\geo2.inc.c" />
|
||||
<ClCompile Include="..\actors\luigi\model.inc.c" />
|
||||
<ClCompile Include="..\actors\mad_piano\anims\anim_05009A04.inc.c" />
|
||||
<ClCompile Include="..\actors\mad_piano\anims\anim_05009AFC.inc.c" />
|
||||
<ClCompile Include="..\actors\mad_piano\anims\data.inc.c" />
|
||||
|
|
|
@ -303,7 +303,7 @@ struct MarioAnimation
|
|||
|
||||
struct MarioState
|
||||
{
|
||||
/*0x00*/ u16 unk00;
|
||||
/*0x00*/ u16 playerIndex;
|
||||
/*0x02*/ u16 input;
|
||||
/*0x04*/ u32 flags;
|
||||
/*0x08*/ u32 particleFlags;
|
||||
|
|
|
@ -130,9 +130,11 @@ static s32 find_wall_collisions_from_list(struct SurfaceNode *surfaceNode,
|
|||
}
|
||||
|
||||
// If Mario has a vanish cap, pass through the vanish cap wall.
|
||||
if (gCurrentObject != NULL && gCurrentObject == gMarioObject
|
||||
&& (gMarioState->flags & MARIO_VANISH_CAP)) {
|
||||
continue;
|
||||
for (int i = 0; i < MAX_PLAYERS; i++) {
|
||||
if (gCurrentObject != NULL && gCurrentObject == gMarioStates[i].marioObj
|
||||
&& (gMarioStates[i].flags & MARIO_VANISH_CAP)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -837,40 +839,40 @@ s32 ray_surface_intersect(Vec3f orig, Vec3f dir, f32 dir_length, struct Surface
|
|||
Vec3f v0, v1, v2, e1, e2, h, s, q;
|
||||
f32 a, f, u, v;
|
||||
Vec3f add_dir;
|
||||
|
||||
|
||||
// Get surface normal and some other stuff
|
||||
vec3s_to_vec3f(v0, surface->vertex1);
|
||||
vec3s_to_vec3f(v1, surface->vertex2);
|
||||
vec3s_to_vec3f(v2, surface->vertex3);
|
||||
|
||||
|
||||
vec3f_dif(e1, v1, v0);
|
||||
vec3f_dif(e2, v2, v0);
|
||||
|
||||
|
||||
vec3f_cross(h, dir, e2);
|
||||
|
||||
|
||||
// Check if we're perpendicular from the surface
|
||||
a = vec3f_dot(e1, h);
|
||||
if (a > -0.00001f && a < 0.00001f)
|
||||
return FALSE;
|
||||
|
||||
|
||||
// Check if we're making contact with the surface
|
||||
f = 1.0f / a;
|
||||
|
||||
|
||||
vec3f_dif(s, orig, v0);
|
||||
u = f * vec3f_dot(s, h);
|
||||
if (u < 0.0f || u > 1.0f)
|
||||
return FALSE;
|
||||
|
||||
|
||||
vec3f_cross(q, s, e1);
|
||||
v = f * vec3f_dot(dir, q);
|
||||
if (v < 0.0f || u + v > 1.0f)
|
||||
return FALSE;
|
||||
|
||||
|
||||
// Get the length between our origin and the surface contact point
|
||||
*length = f * vec3f_dot(e2, q);
|
||||
if (*length <= 0.00001 || *length > dir_length)
|
||||
return FALSE;
|
||||
|
||||
|
||||
// Successful contact
|
||||
vec3f_copy(add_dir, dir);
|
||||
vec3f_mul(add_dir, *length);
|
||||
|
@ -884,7 +886,7 @@ void find_surface_on_ray_list(struct SurfaceNode *list, Vec3f orig, Vec3f dir, f
|
|||
f32 length;
|
||||
Vec3f chk_hit_pos;
|
||||
f32 top, bottom;
|
||||
|
||||
|
||||
// Get upper and lower bounds of ray
|
||||
if (dir[1] >= 0.0f)
|
||||
{
|
||||
|
@ -896,17 +898,17 @@ void find_surface_on_ray_list(struct SurfaceNode *list, Vec3f orig, Vec3f dir, f
|
|||
top = orig[1];
|
||||
bottom = orig[1] + dir[1] * dir_length;
|
||||
}
|
||||
|
||||
|
||||
// Iterate through every surface of the list
|
||||
for (; list != NULL; list = list->next)
|
||||
{
|
||||
// Reject surface if out of vertical bounds
|
||||
if (list->surface->lowerY > top || list->surface->upperY < bottom)
|
||||
continue;
|
||||
|
||||
|
||||
// Check intersection between the ray and this surface
|
||||
if ((hit = ray_surface_intersect(orig, dir, dir_length, list->surface, chk_hit_pos, &length)) != 0)
|
||||
{
|
||||
{
|
||||
if (length <= *max_length)
|
||||
{
|
||||
*hit_surface = list->surface;
|
||||
|
@ -948,43 +950,43 @@ void find_surface_on_ray(Vec3f orig, Vec3f dir, struct Surface **hit_surface, Ve
|
|||
Vec3f normalized_dir;
|
||||
f32 step, dx, dz;
|
||||
u32 i;
|
||||
|
||||
|
||||
// Set that no surface has been hit
|
||||
*hit_surface = NULL;
|
||||
vec3f_sum(hit_pos, orig, dir);
|
||||
|
||||
|
||||
// Get normalized direction
|
||||
dir_length = vec3f_length(dir);
|
||||
max_length = dir_length;
|
||||
vec3f_copy(normalized_dir, dir);
|
||||
vec3f_normalize(normalized_dir);
|
||||
|
||||
|
||||
// Get our cell coordinate
|
||||
fCellX = (orig[0] + LEVEL_BOUNDARY_MAX) / CELL_SIZE;
|
||||
fCellZ = (orig[2] + LEVEL_BOUNDARY_MAX) / CELL_SIZE;
|
||||
cellX = (s16)fCellX;
|
||||
cellZ = (s16)fCellZ;
|
||||
|
||||
|
||||
// Don't do DDA if straight down
|
||||
if (normalized_dir[1] >= 1.0f || normalized_dir[1] <= -1.0f)
|
||||
{
|
||||
find_surface_on_ray_cell(cellX, cellZ, orig, normalized_dir, dir_length, hit_surface, hit_pos, &max_length);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Get cells we cross using DDA
|
||||
if (absx(dir[0]) >= absx(dir[2]))
|
||||
step = absx(dir[0]) / CELL_SIZE;
|
||||
else
|
||||
step = absx(dir[2]) / CELL_SIZE;
|
||||
|
||||
|
||||
dx = dir[0] / step / CELL_SIZE;
|
||||
dz = dir[2] / step / CELL_SIZE;
|
||||
|
||||
|
||||
for (i = 0; i < step && *hit_surface == NULL; i++)
|
||||
{
|
||||
find_surface_on_ray_cell(cellX, cellZ, orig, normalized_dir, dir_length, hit_surface, hit_pos, &max_length);
|
||||
|
||||
|
||||
// Move cell coordinate
|
||||
fCellX += dx;
|
||||
fCellZ += dz;
|
||||
|
|
|
@ -773,6 +773,7 @@ void load_object_collision_model(void) {
|
|||
if (gCurrentObject->oDistanceToMario == 19000.0f) {
|
||||
marioDist = dist_between_objects(gCurrentObject, gMarioObject);
|
||||
}
|
||||
// two-player hack
|
||||
mario2Dist = dist_between_objects(gCurrentObject, gMario2Object);
|
||||
|
||||
// If the object collision is supposed to be loaded more than the
|
||||
|
|
|
@ -289,6 +289,7 @@ void mario_grab_used_object(struct MarioState *m) {
|
|||
if (m->usedObj == NULL || m->usedObj->oHeldState == HELD_HELD) { return; }
|
||||
if (m->heldObj == NULL) {
|
||||
m->heldObj = m->usedObj;
|
||||
// two-player hack
|
||||
m->heldObj->heldByPlayerIndex = (m == &gMarioStates[0]) ? 0 : 1;
|
||||
obj_set_held_state(m->heldObj, bhvCarrySomething3);
|
||||
}
|
||||
|
@ -709,6 +710,7 @@ u32 take_damage_from_interact_object(struct MarioState *m) {
|
|||
}
|
||||
|
||||
int get_invincibility_flag(struct MarioState *m) {
|
||||
// two-player hack
|
||||
return (m == &gMarioStates[0])
|
||||
? INT_SUBTYPE_DELAY_INVINCIBILITY
|
||||
: INT_SUBTYPE_DELAY_INVINCIBILITY_MARIO2;
|
||||
|
|
|
@ -1862,6 +1862,9 @@ void init_mario(void) {
|
|||
if (isLocal && gMarioObject == NULL) { goto skippy; }
|
||||
if (!isLocal && gMario2Object == NULL) { goto skippy; }
|
||||
|
||||
// two-player hack
|
||||
gMarioState->playerIndex = isLocal ? 0 : 1;
|
||||
|
||||
Vec3s capPos;
|
||||
struct Object *capObject;
|
||||
|
||||
|
@ -1898,6 +1901,7 @@ void init_mario(void) {
|
|||
find_water_level(gMarioSpawnInfo->startPos[0], gMarioSpawnInfo->startPos[2]);
|
||||
|
||||
gMarioState->area = gCurrentArea;
|
||||
// two-player hack
|
||||
gMarioState->marioObj = isLocal ? gMarioObject : gMario2Object;
|
||||
gMarioState->marioObj->header.gfx.unk38.animID = -1;
|
||||
vec3s_copy(gMarioState->faceAngle, gMarioSpawnInfo->startAngle);
|
||||
|
@ -1961,7 +1965,8 @@ skippy:
|
|||
|
||||
void init_mario_from_save_file(void) {
|
||||
bool isLocal = (gMarioState == &gMarioStates[0]);
|
||||
gMarioState->unk00 = isLocal ? 0 : 1;
|
||||
// two-player hack
|
||||
gMarioState->playerIndex = isLocal ? 0 : 1;
|
||||
gMarioState->flags = 0;
|
||||
gMarioState->action = 0;
|
||||
int i = isLocal ? 0 : 1;
|
||||
|
|
|
@ -89,8 +89,8 @@ void play_step_sound(struct MarioState *m, s16 frame1, s16 frame2) {
|
|||
|
||||
void align_with_floor(struct MarioState *m) {
|
||||
m->pos[1] = m->floorHeight;
|
||||
mtxf_align_terrain_triangle(sFloorAlignMatrix[m->unk00], m->pos, m->faceAngle[1], 40.0f);
|
||||
m->marioObj->header.gfx.throwMatrix = &sFloorAlignMatrix[m->unk00];
|
||||
mtxf_align_terrain_triangle(sFloorAlignMatrix[m->playerIndex], m->pos, m->faceAngle[1], 40.0f);
|
||||
m->marioObj->header.gfx.throwMatrix = &sFloorAlignMatrix[m->playerIndex];
|
||||
}
|
||||
|
||||
s32 begin_walking_action(struct MarioState *m, f32 forwardVel, u32 action, u32 actionArg) {
|
||||
|
|
|
@ -30,6 +30,7 @@ void network_receive_player(struct Packet* p) {
|
|||
u32 heldSyncID = NULL;
|
||||
u32 heldBySyncID = NULL;
|
||||
|
||||
u16 playerIndex = gMarioStates[1].playerIndex;
|
||||
packet_read(p, &gMarioStates[1], sizeof(u32) * 24);
|
||||
packet_read(p, gMarioStates[1].controller, 20);
|
||||
packet_read(p, &gMarioStates[1].marioObj->rawData.asU32, sizeof(u32) * 80);
|
||||
|
@ -37,6 +38,7 @@ void network_receive_player(struct Packet* p) {
|
|||
packet_read(p, &gMarioStates[1].marioObj->header.gfx.node.flags, sizeof(s16));
|
||||
packet_read(p, &heldSyncID, sizeof(u32));
|
||||
packet_read(p, &heldBySyncID, sizeof(u32));
|
||||
gMarioStates[1].playerIndex = playerIndex;
|
||||
|
||||
if (heldSyncID != NULL && syncObjects[heldSyncID].o != NULL) {
|
||||
// TODO: do we have to move graphics nodes around to make this visible?
|
||||
|
|
Loading…
Reference in New Issue