diff --git a/actors/mario/geo2.inc.c b/actors/mario/geo2.inc.c index 14685d65f..9ea0cf0ce 100644 --- a/actors/mario/geo2.inc.c +++ b/actors/mario/geo2.inc.c @@ -1,4 +1,4 @@ -// Normal Mario Geo +// Normal Luigi Geo // 0x170002E0 const GeoLayout luigi_geo_face_and_wings[] = { diff --git a/src/engine/surface_load.c b/src/engine/surface_load.c index 323b7d05a..b6366a2c3 100644 --- a/src/engine/surface_load.c +++ b/src/engine/surface_load.c @@ -765,6 +765,7 @@ void load_object_collision_model(void) { s16 *collisionData = gCurrentObject->collisionData; f32 marioDist = gCurrentObject->oDistanceToMario; + f32 luigiDist = gCurrentObject->oDistanceToMario; f32 tangibleDist = gCurrentObject->oCollisionDistance; // On an object's first frame, the distance is set to 19000.0f. @@ -772,6 +773,7 @@ void load_object_collision_model(void) { if (gCurrentObject->oDistanceToMario == 19000.0f) { marioDist = dist_between_objects(gCurrentObject, gMarioObject); } + luigiDist = dist_between_objects(gCurrentObject, gLuigiObject); // If the object collision is supposed to be loaded more than the // drawing distance of 4000, extend the drawing range. @@ -780,7 +782,8 @@ void load_object_collision_model(void) { } // Update if no Time Stop, in range, and in the current room. - if (!(gTimeStopState & TIME_STOP_ACTIVE) && marioDist < tangibleDist + if (!(gTimeStopState & TIME_STOP_ACTIVE) + && (marioDist < tangibleDist || luigiDist < tangibleDist) && !(gCurrentObject->activeFlags & ACTIVE_FLAG_IN_DIFFERENT_ROOM)) { collisionData++; transform_object_vertices(&collisionData, vertexData); diff --git a/src/game/behaviors/beta_chest.inc.c b/src/game/behaviors/beta_chest.inc.c index 7a1a786d5..690be654a 100644 --- a/src/game/behaviors/beta_chest.inc.c +++ b/src/game/behaviors/beta_chest.inc.c @@ -34,6 +34,7 @@ void bhv_beta_chest_bottom_init(void) { */ void bhv_beta_chest_bottom_loop(void) { cur_obj_push_mario_away_from_cylinder(200.0f, 200.0f); + cur_obj_push_luigi_away_from_cylinder(200.0f, 200.0f); } /** diff --git a/src/game/behaviors/flying_bookend_switch.inc.c b/src/game/behaviors/flying_bookend_switch.inc.c index d3d937bec..4ddd77ac0 100644 --- a/src/game/behaviors/flying_bookend_switch.inc.c +++ b/src/game/behaviors/flying_bookend_switch.inc.c @@ -299,5 +299,6 @@ void bhv_book_switch_loop(void) { o->oPosX += o->parentObj->oForwardVel; o->oPosZ = o->oHomeZ - o->oBookSwitchUnkF4; cur_obj_push_mario_away_from_cylinder(70.0f, 70.0f); + cur_obj_push_luigi_away_from_cylinder(70.0f, 70.0f); } } diff --git a/src/game/behaviors/haunted_chair.inc.c b/src/game/behaviors/haunted_chair.inc.c index 26d00de29..8136c7b1f 100644 --- a/src/game/behaviors/haunted_chair.inc.c +++ b/src/game/behaviors/haunted_chair.inc.c @@ -90,6 +90,7 @@ void haunted_chair_act_0(void) { } cur_obj_push_mario_away_from_cylinder(80.0f, 120.0f); + cur_obj_push_luigi_away_from_cylinder(80.0f, 120.0f); } void haunted_chair_act_1(void) { diff --git a/src/game/behaviors/koopa.inc.c b/src/game/behaviors/koopa.inc.c index 2303906e8..0c8302125 100644 --- a/src/game/behaviors/koopa.inc.c +++ b/src/game/behaviors/koopa.inc.c @@ -599,6 +599,7 @@ static void koopa_the_quick_act_race(void) { if (obj_begin_race(FALSE)) { // Hitbox is slightly larger while racing cur_obj_push_mario_away_from_cylinder(180.0f, 300.0f); + cur_obj_push_luigi_away_from_cylinder(180.0f, 300.0f); if (cur_obj_follow_path(0) == PATH_REACHED_END) { o->oAction = KOOPA_THE_QUICK_ACT_DECELERATE; @@ -781,6 +782,7 @@ static void koopa_the_quick_update(void) { } cur_obj_push_mario_away_from_cylinder(140.0f, 300.0f); + cur_obj_push_luigi_away_from_cylinder(140.0f, 300.0f); cur_obj_move_standard(-78); } diff --git a/src/game/behaviors/mad_piano.inc.c b/src/game/behaviors/mad_piano.inc.c index efefaba43..57e229df4 100644 --- a/src/game/behaviors/mad_piano.inc.c +++ b/src/game/behaviors/mad_piano.inc.c @@ -26,6 +26,7 @@ static void mad_piano_act_wait(void) { } cur_obj_push_mario_away_from_cylinder(280.0f, 150.0f); + cur_obj_push_luigi_away_from_cylinder(280.0f, 150.0f); } static void mad_piano_act_attack(void) { diff --git a/src/game/behaviors/pole_base.inc.c b/src/game/behaviors/pole_base.inc.c index 3ae63fefb..22c86062b 100644 --- a/src/game/behaviors/pole_base.inc.c +++ b/src/game/behaviors/pole_base.inc.c @@ -6,4 +6,10 @@ void bhv_pole_base_loop(void) { if (o->oTimer > 10) if (!(gMarioStates->action & MARIO_PUNCHING)) cur_obj_push_mario_away(70.0f); + + if (o->oPosY - 10.0f < gLuigiObject->oPosY + && gLuigiObject->oPosY < o->oPosY + o->hitboxHeight + 30.0f) + if (o->oTimer > 10) + if (!(gMarioStates[1].action & MARIO_PUNCHING)) + cur_obj_push_luigi_away(70.0f); } diff --git a/src/game/behaviors/racing_penguin.inc.c b/src/game/behaviors/racing_penguin.inc.c index 1703d52eb..f318e053e 100644 --- a/src/game/behaviors/racing_penguin.inc.c +++ b/src/game/behaviors/racing_penguin.inc.c @@ -185,7 +185,9 @@ void bhv_racing_penguin_update(void) { cur_obj_move_standard(78); cur_obj_align_gfx_with_floor(); cur_obj_push_mario_away_from_cylinder(sRacingPenguinData[o->oBehParams2ndByte].radius, - sRacingPenguinData[o->oBehParams2ndByte].height); + sRacingPenguinData[o->oBehParams2ndByte].height); + cur_obj_push_luigi_away_from_cylinder(sRacingPenguinData[o->oBehParams2ndByte].radius, + sRacingPenguinData[o->oBehParams2ndByte].height); } void bhv_penguin_race_finish_line_update(void) { diff --git a/src/game/behaviors/snowman.inc.c b/src/game/behaviors/snowman.inc.c index 174123d18..cec85f6b5 100644 --- a/src/game/behaviors/snowman.inc.c +++ b/src/game/behaviors/snowman.inc.c @@ -152,6 +152,7 @@ void bhv_snowmans_bottom_loop(void) { case 4: cur_obj_push_mario_away_from_cylinder(210.0f, 550); + cur_obj_push_luigi_away_from_cylinder(210.0f, 550); break; } @@ -223,6 +224,7 @@ void bhv_snowmans_head_loop(void) { } cur_obj_push_mario_away_from_cylinder(180.0f, 150.0f); + cur_obj_push_luigi_away_from_cylinder(180.0f, 150.0f); } void bhv_snowmans_body_checkpoint_loop(void) { diff --git a/src/game/behaviors/treasure_chest.inc.c b/src/game/behaviors/treasure_chest.inc.c index ca00ec2d6..765b96f8c 100644 --- a/src/game/behaviors/treasure_chest.inc.c +++ b/src/game/behaviors/treasure_chest.inc.c @@ -98,6 +98,7 @@ void bhv_treasure_chest_bottom_loop(void) { } cur_obj_push_mario_away_from_cylinder(150.0f, 150.0f); + cur_obj_push_luigi_away_from_cylinder(150.0f, 150.0f); o->oInteractStatus = 0; } diff --git a/src/game/behaviors/water_bomb_cannon.inc.c b/src/game/behaviors/water_bomb_cannon.inc.c index fb82e43cc..dc36b869e 100644 --- a/src/game/behaviors/water_bomb_cannon.inc.c +++ b/src/game/behaviors/water_bomb_cannon.inc.c @@ -87,6 +87,7 @@ void water_bomb_cannon_act_2(void) { void bhv_water_bomb_cannon_loop(void) { cur_obj_push_mario_away_from_cylinder(220.0f, 300.0f); + cur_obj_push_luigi_away_from_cylinder(220.0f, 300.0f); switch (o->oAction) { case 0: diff --git a/src/game/mario.c b/src/game/mario.c index 6dbf49341..b291c1320 100644 --- a/src/game/mario.c +++ b/src/game/mario.c @@ -1277,7 +1277,7 @@ void debug_print_speed_action_normal(struct MarioState *m) { */ void update_mario_button_inputs(struct MarioState *m) { // disable Luigi inputs - if (m != &gMarioStates[1]) { return; } + //if (m != &gMarioStates[1]) { return; } if (m->controller->buttonPressed & A_BUTTON) { m->input |= INPUT_A_PRESSED; @@ -1320,7 +1320,7 @@ void update_mario_button_inputs(struct MarioState *m) { */ void update_mario_joystick_inputs(struct MarioState *m) { // disable Luigi inputs - if (m != &gMarioStates[1]) { return; } + //if (m != &gMarioStates[1]) { return; } struct Controller *controller = m->controller; f32 mag = ((controller->stickMag / 64.0f) * (controller->stickMag / 64.0f)) * 64.0f; @@ -1891,7 +1891,7 @@ void init_mario(void) { vec3s_set(gMarioState->angleVel, 0, 0, 0); vec3s_to_vec3f(gMarioState->pos, gMarioSpawnInfo->startPos); vec3f_set(gMarioState->vel, 0, 0, 0); - if (!isMario) { gMarioState->pos[0] -= 50; } + if (!isMario) { gMarioState->pos[0] -= 150; } gMarioState->floorHeight = find_floor(gMarioState->pos[0], gMarioState->pos[1], gMarioState->pos[2], &gMarioState->floor); diff --git a/src/game/obj_behaviors_2.c b/src/game/obj_behaviors_2.c index 28461d5df..cf62a87f9 100644 --- a/src/game/obj_behaviors_2.c +++ b/src/game/obj_behaviors_2.c @@ -558,7 +558,7 @@ static s32 obj_resolve_object_collisions(s32 *targetYaw) { if (o->numCollidedObjs != 0) { otherObject = o->collidedObjs[0]; - if (otherObject != gMarioObject) { + if (otherObject != gMarioObject && otherObject != gLuigiObject) { //! If one object moves after collisions are detected and this code // runs, the objects can move toward each other (transport cloning) diff --git a/src/game/object_collision.c b/src/game/object_collision.c index 71f3268b9..d3da8e8ef 100644 --- a/src/game/object_collision.c +++ b/src/game/object_collision.c @@ -68,7 +68,7 @@ int detect_object_hurtbox_overlap(struct Object *a, struct Object *b) { f32 sp28 = a->hurtboxRadius + b->hurtboxRadius; f32 sp24 = sqrtf(sp34 * sp34 + sp2C * sp2C); - if (a == gMarioObject) { + if (a == gMarioObject || a == gLuigiObject) { b->oInteractionSubtype |= INT_SUBTYPE_DELAY_INVINCIBILITY; } @@ -82,7 +82,7 @@ int detect_object_hurtbox_overlap(struct Object *a, struct Object *b) { if (sp20 < sp38) { return 0; } - if (a == gMarioObject) { + if (a == gMarioObject || a == gLuigiObject) { b->oInteractionSubtype &= ~INT_SUBTYPE_DELAY_INVINCIBILITY; } return 1; diff --git a/src/game/object_helpers.c b/src/game/object_helpers.c index 109d7f74f..59c853e55 100644 --- a/src/game/object_helpers.c +++ b/src/game/object_helpers.c @@ -2224,6 +2224,19 @@ void cur_obj_push_mario_away(f32 radius) { } } +void cur_obj_push_luigi_away(f32 radius) { + f32 luigiRelX = gLuigiObject->oPosX - o->oPosX; + f32 luigiRelZ = gLuigiObject->oPosZ - o->oPosZ; + f32 luigiDist = sqrtf(sqr(luigiRelX) + sqr(luigiRelZ)); + + if (luigiDist < radius) { + //! If this function pushes luigi out of bounds, it will trigger luigi's + // oob failsafe + gMarioStates[1].pos[0] += (radius - luigiDist) / radius * luigiRelX; + gMarioStates[1].pos[2] += (radius - luigiDist) / radius * luigiRelZ; + } +} + void cur_obj_push_mario_away_from_cylinder(f32 radius, f32 extentY) { f32 marioRelY = gMarioObject->oPosY - o->oPosY; @@ -2236,6 +2249,18 @@ void cur_obj_push_mario_away_from_cylinder(f32 radius, f32 extentY) { } } +void cur_obj_push_luigi_away_from_cylinder(f32 radius, f32 extentY) { + f32 marioRelY = gLuigiObject->oPosY - o->oPosY; + + if (marioRelY < 0) { + marioRelY = -marioRelY; + } + + if (marioRelY < extentY) { + cur_obj_push_luigi_away(radius); + } +} + void bhv_dust_smoke_loop(void) { o->oPosX += o->oVelX; o->oPosY += o->oVelY; @@ -2794,7 +2819,7 @@ s32 obj_attack_collided_from_other_object(struct Object *obj) { if (numCollidedObjs != 0) { other = obj->collidedObjs[0]; - if (other != gMarioObject) { + if (other != gMarioObject && other != gLuigiObject) { other->oInteractStatus |= ATTACK_PUNCH | INT_STATUS_WAS_ATTACKED | INT_STATUS_INTERACTED | INT_STATUS_TOUCHED_BOB_OMB; touchedOtherObject = TRUE; diff --git a/src/game/object_helpers.h b/src/game/object_helpers.h index 895604fc9..092a07208 100644 --- a/src/game/object_helpers.h +++ b/src/game/object_helpers.h @@ -245,7 +245,9 @@ s32 cur_obj_is_mario_ground_pounding_platform(void); void spawn_mist_particles(void); void spawn_mist_particles_with_sound(u32 sp18); void cur_obj_push_mario_away(f32 radius); +void cur_obj_push_luigi_away(f32 radius); void cur_obj_push_mario_away_from_cylinder(f32 radius, f32 extentY); +void cur_obj_push_luigi_away_from_cylinder(f32 radius, f32 extentY); s32 cur_obj_set_direction_table(s8 *a0); s32 cur_obj_progress_direction_table(void); void stub_obj_helpers_3(UNUSED s32 sp0, UNUSED s32 sp4);