mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2024-11-25 13:35:12 +00:00
Made Goomba Luigi-aware, fixed Mario's hurtboxes
This commit is contained in:
parent
c437e075ff
commit
4351a6345a
10 changed files with 59 additions and 46 deletions
|
@ -91,6 +91,7 @@ static const LevelScript script_func_local_4[] = {
|
||||||
OBJECT(/*model*/ MODEL_YOSHI, /*pos*/ 0, 3174, -5625, /*angle*/ 0, 0, 0, /*behParam*/ 0x00000000, /*beh*/ bhvYoshi),
|
OBJECT(/*model*/ MODEL_YOSHI, /*pos*/ 0, 3174, -5625, /*angle*/ 0, 0, 0, /*behParam*/ 0x00000000, /*beh*/ bhvYoshi),
|
||||||
// TESTING BELOW
|
// TESTING BELOW
|
||||||
OBJECT(/*model*/ MODEL_BLACK_BOBOMB, /*pos*/ -2028, 260, 4664, /*angle*/ 0, 0, 0, /*behParam*/ 0x00000000, /*beh*/ bhvBobomb),
|
OBJECT(/*model*/ MODEL_BLACK_BOBOMB, /*pos*/ -2028, 260, 4664, /*angle*/ 0, 0, 0, /*behParam*/ 0x00000000, /*beh*/ bhvBobomb),
|
||||||
|
OBJECT(/*model*/ MODEL_GOOMBA, /*pos*/ -2028, 260, 3264, /*angle*/ 0, 0, 0, /*behParam*/ 0x00000000, /*beh*/ bhvGoomba),
|
||||||
RETURN(),
|
RETURN(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
static void bird_act_inactive(void) {
|
static void bird_act_inactive(void) {
|
||||||
// Start flying if the object is a spawned bird or if it's a spawner bird
|
// Start flying if the object is a spawned bird or if it's a spawner bird
|
||||||
// and Mario is within 2000 units.
|
// and Mario is within 2000 units.
|
||||||
struct Object* player = nearest_player_object(o->oPosX, o->oPosY, o->oPosZ);
|
struct Object* player = nearest_player_to_object(o);
|
||||||
if (o->oBehParams2ndByte == BIRD_BP_SPAWNED || dist_between_objects(o, player) < 2000.0f) {
|
if (o->oBehParams2ndByte == BIRD_BP_SPAWNED || dist_between_objects(o, player) < 2000.0f) {
|
||||||
// If the object is a spawner bird, play the sound of birds flying away,
|
// If the object is a spawner bird, play the sound of birds flying away,
|
||||||
// and spawn 6 spawned birds (which will start flying on the next frame).
|
// and spawn 6 spawned birds (which will start flying on the next frame).
|
||||||
|
|
|
@ -48,7 +48,7 @@ void bobomb_check_interactions(void) {
|
||||||
{
|
{
|
||||||
if ((o->oInteractStatus & INT_STATUS_MARIO_UNK1) != 0)
|
if ((o->oInteractStatus & INT_STATUS_MARIO_UNK1) != 0)
|
||||||
{
|
{
|
||||||
struct Object* player = nearest_player_object(o->oPosX, o->oPosY, o->oPosZ);
|
struct Object* player = nearest_player_to_object(o);
|
||||||
o->oMoveAngleYaw = player->header.gfx.angle[1];
|
o->oMoveAngleYaw = player->header.gfx.angle[1];
|
||||||
o->oForwardVel = 25.0;
|
o->oForwardVel = 25.0;
|
||||||
o->oVelY = 30.0;
|
o->oVelY = 30.0;
|
||||||
|
@ -74,7 +74,7 @@ void bobomb_act_patrol(void) {
|
||||||
o->oForwardVel = 5.0;
|
o->oForwardVel = 5.0;
|
||||||
|
|
||||||
collisionFlags = object_step();
|
collisionFlags = object_step();
|
||||||
struct Object* player = nearest_player_object(o->oPosX, o->oPosY, o->oPosZ);
|
struct Object* player = nearest_player_to_object(o);
|
||||||
if ((obj_return_home_if_safe(o, o->oHomeX, o->oHomeY, o->oHomeZ, 400) == 1)
|
if ((obj_return_home_if_safe(o, o->oHomeX, o->oHomeY, o->oHomeZ, 400) == 1)
|
||||||
&& (obj_check_if_facing_toward_angle(o->oMoveAngleYaw, obj_angle_to_object(o, player), 0x2000) == 1)) {
|
&& (obj_check_if_facing_toward_angle(o->oMoveAngleYaw, obj_angle_to_object(o, player), 0x2000) == 1)) {
|
||||||
o->oBobombFuseLit = 1;
|
o->oBobombFuseLit = 1;
|
||||||
|
@ -95,7 +95,7 @@ void bobomb_act_chase_mario(void) {
|
||||||
if (sp1a == 5 || sp1a == 16)
|
if (sp1a == 5 || sp1a == 16)
|
||||||
cur_obj_play_sound_2(SOUND_OBJ_BOBOMB_WALK);
|
cur_obj_play_sound_2(SOUND_OBJ_BOBOMB_WALK);
|
||||||
|
|
||||||
struct Object* player = nearest_player_object(o->oPosX, o->oPosY, o->oPosZ);
|
struct Object* player = nearest_player_to_object(o);
|
||||||
obj_turn_toward_object(o, player, 16, 0x800);
|
obj_turn_toward_object(o, player, 16, 0x800);
|
||||||
obj_check_floor_death(collisionFlags, sObjFloor);
|
obj_check_floor_death(collisionFlags, sObjFloor);
|
||||||
}
|
}
|
||||||
|
@ -179,7 +179,7 @@ void bobomb_free_loop(void) {
|
||||||
void bobomb_held_loop(void) {
|
void bobomb_held_loop(void) {
|
||||||
o->header.gfx.node.flags |= GRAPH_RENDER_INVISIBLE;
|
o->header.gfx.node.flags |= GRAPH_RENDER_INVISIBLE;
|
||||||
cur_obj_init_animation(1);
|
cur_obj_init_animation(1);
|
||||||
struct Object* player = nearest_player_object(o->oPosX, o->oPosY, o->oPosZ);
|
struct Object* player = nearest_player_to_object(o);
|
||||||
cur_obj_set_pos_relative(player, 0, 60.0f, 100.0);
|
cur_obj_set_pos_relative(player, 0, 60.0f, 100.0);
|
||||||
|
|
||||||
o->oBobombFuseLit = 1;
|
o->oBobombFuseLit = 1;
|
||||||
|
@ -302,7 +302,7 @@ void bobomb_buddy_act_idle(void) {
|
||||||
if ((sp1a == 5) || (sp1a == 16))
|
if ((sp1a == 5) || (sp1a == 16))
|
||||||
cur_obj_play_sound_2(SOUND_OBJ_BOBOMB_WALK);
|
cur_obj_play_sound_2(SOUND_OBJ_BOBOMB_WALK);
|
||||||
|
|
||||||
struct Object* player = nearest_player_object(o->oPosX, o->oPosY, o->oPosZ);
|
struct Object* player = nearest_player_to_object(o);
|
||||||
if (dist_between_objects(o, player) < 1000.0f)
|
if (dist_between_objects(o, player) < 1000.0f)
|
||||||
o->oMoveAngleYaw = approach_s16_symmetric(o->oMoveAngleYaw, obj_angle_to_object(o, player), 0x140);
|
o->oMoveAngleYaw = approach_s16_symmetric(o->oMoveAngleYaw, obj_angle_to_object(o, player), 0x140);
|
||||||
|
|
||||||
|
@ -392,7 +392,7 @@ void bobomb_buddy_act_turn_to_talk(void) {
|
||||||
if ((sp1e == 5) || (sp1e == 16))
|
if ((sp1e == 5) || (sp1e == 16))
|
||||||
cur_obj_play_sound_2(SOUND_OBJ_BOBOMB_WALK);
|
cur_obj_play_sound_2(SOUND_OBJ_BOBOMB_WALK);
|
||||||
|
|
||||||
struct Object* player = nearest_player_object(o->oPosX, o->oPosY, o->oPosZ);
|
struct Object* player = nearest_player_to_object(o);
|
||||||
int angleToPlayer = obj_angle_to_object(o, player);
|
int angleToPlayer = obj_angle_to_object(o, player);
|
||||||
o->oMoveAngleYaw = approach_s16_symmetric(o->oMoveAngleYaw, angleToPlayer, 0x1000);
|
o->oMoveAngleYaw = approach_s16_symmetric(o->oMoveAngleYaw, angleToPlayer, 0x1000);
|
||||||
if ((s16) o->oMoveAngleYaw == (s16) angleToPlayer)
|
if ((s16) o->oMoveAngleYaw == (s16) angleToPlayer)
|
||||||
|
|
|
@ -42,7 +42,7 @@ void butterfly_step(s32 speed) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void butterfly_calculate_angle(void) {
|
void butterfly_calculate_angle(void) {
|
||||||
struct Object* player = nearest_player_object(o->oPosX, o->oPosY, o->oPosZ);
|
struct Object* player = nearest_player_to_object(o);
|
||||||
player->oPosX += 5 * o->oButterflyYPhase / 4;
|
player->oPosX += 5 * o->oButterflyYPhase / 4;
|
||||||
player->oPosZ += 5 * o->oButterflyYPhase / 4;
|
player->oPosZ += 5 * o->oButterflyYPhase / 4;
|
||||||
obj_turn_toward_object(o, player, 16, 0x300);
|
obj_turn_toward_object(o, player, 16, 0x300);
|
||||||
|
@ -59,7 +59,7 @@ void butterfly_act_rest(void) {
|
||||||
cur_obj_init_animation(0);
|
cur_obj_init_animation(0);
|
||||||
|
|
||||||
o->oAction = BUTTERFLY_ACT_FOLLOW_MARIO;
|
o->oAction = BUTTERFLY_ACT_FOLLOW_MARIO;
|
||||||
struct Object* player = nearest_player_object(o->oPosX, o->oPosY, o->oPosZ);
|
struct Object* player = nearest_player_to_object(o);
|
||||||
o->oMoveAngleYaw = player->header.gfx.angle[1];
|
o->oMoveAngleYaw = player->header.gfx.angle[1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,12 +74,13 @@ void bhv_goomba_triplet_spawner_update(void) {
|
||||||
s32 dAngle;
|
s32 dAngle;
|
||||||
s16 dx;
|
s16 dx;
|
||||||
s16 dz;
|
s16 dz;
|
||||||
|
struct Object* player = nearest_player_to_object(o);
|
||||||
|
|
||||||
// If mario is close enough and the goombas aren't currently loaded, then
|
// If mario is close enough and the goombas aren't currently loaded, then
|
||||||
// spawn them
|
// spawn them
|
||||||
if (o->oAction == GOOMBA_TRIPLET_SPAWNER_ACT_UNLOADED) {
|
if (o->oAction == GOOMBA_TRIPLET_SPAWNER_ACT_UNLOADED) {
|
||||||
#ifndef NODRAWINGDISTANCE
|
#ifndef NODRAWINGDISTANCE
|
||||||
if (o->oDistanceToMario < 3000.0f) {
|
if (dist_between_objects(o, player) < 3000.0f) {
|
||||||
#endif
|
#endif
|
||||||
// The spawner is capable of spawning more than 3 goombas, but this
|
// The spawner is capable of spawning more than 3 goombas, but this
|
||||||
// is not used in the game
|
// is not used in the game
|
||||||
|
@ -102,7 +103,7 @@ void bhv_goomba_triplet_spawner_update(void) {
|
||||||
o->oAction += 1;
|
o->oAction += 1;
|
||||||
#ifndef NODRAWINGDISTANCE
|
#ifndef NODRAWINGDISTANCE
|
||||||
}
|
}
|
||||||
} else if (o->oDistanceToMario > 4000.0f) {
|
} else if (dist_between_objects(o, player) > 4000.0f) {
|
||||||
// If mario is too far away, enter the unloaded action. The goombas
|
// If mario is too far away, enter the unloaded action. The goombas
|
||||||
// will detect this and unload themselves
|
// will detect this and unload themselves
|
||||||
o->oAction = GOOMBA_TRIPLET_SPAWNER_ACT_UNLOADED;
|
o->oAction = GOOMBA_TRIPLET_SPAWNER_ACT_UNLOADED;
|
||||||
|
@ -176,15 +177,18 @@ static void goomba_act_walk(void) {
|
||||||
if (o->oGoombaTurningAwayFromWall) {
|
if (o->oGoombaTurningAwayFromWall) {
|
||||||
o->oGoombaTurningAwayFromWall = obj_resolve_collisions_and_turn(o->oGoombaTargetYaw, 0x200);
|
o->oGoombaTurningAwayFromWall = obj_resolve_collisions_and_turn(o->oGoombaTargetYaw, 0x200);
|
||||||
} else {
|
} 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, walk toward home.
|
// If far from home, walk toward home.
|
||||||
if (o->oDistanceToMario >= 25000.0f) {
|
if (distanceToPlayer >= 25000.0f) {
|
||||||
o->oGoombaTargetYaw = o->oAngleToMario;
|
o->oGoombaTargetYaw = angleToPlayer;
|
||||||
o->oGoombaWalkTimer = random_linear_offset(20, 30);
|
o->oGoombaWalkTimer = random_linear_offset(20, 30);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(o->oGoombaTurningAwayFromWall =
|
if (!(o->oGoombaTurningAwayFromWall =
|
||||||
obj_bounce_off_walls_edges_objects(&o->oGoombaTargetYaw))) {
|
obj_bounce_off_walls_edges_objects(&o->oGoombaTargetYaw))) {
|
||||||
if (o->oDistanceToMario < 500.0f) {
|
if (distanceToPlayer < 500.0f) {
|
||||||
// If close to mario, begin chasing him. If not already chasing
|
// If close to mario, begin chasing him. If not already chasing
|
||||||
// him, jump first
|
// him, jump first
|
||||||
|
|
||||||
|
@ -192,7 +196,7 @@ static void goomba_act_walk(void) {
|
||||||
goomba_begin_jump();
|
goomba_begin_jump();
|
||||||
}
|
}
|
||||||
|
|
||||||
o->oGoombaTargetYaw = o->oAngleToMario;
|
o->oGoombaTargetYaw = angleToPlayer;
|
||||||
o->oGoombaRelativeSpeed = 20.0f;
|
o->oGoombaRelativeSpeed = 20.0f;
|
||||||
} else {
|
} else {
|
||||||
// If mario is far away, walk at a normal pace, turning randomly
|
// If mario is far away, walk at a normal pace, turning randomly
|
||||||
|
@ -229,8 +233,10 @@ static void goomba_act_attacked_mario(void) {
|
||||||
} else {
|
} else {
|
||||||
//! This can happen even when the goomba is already in the air. It's
|
//! This can happen even when the goomba is already in the air. It's
|
||||||
// hard to chain these in practice
|
// hard to chain these in practice
|
||||||
|
struct Object* player = nearest_player_to_object(o);
|
||||||
|
int angleToPlayer = obj_angle_to_object(o, player);
|
||||||
goomba_begin_jump();
|
goomba_begin_jump();
|
||||||
o->oGoombaTargetYaw = o->oAngleToMario;
|
o->oGoombaTargetYaw = angleToPlayer;
|
||||||
o->oGoombaTurningAwayFromWall = FALSE;
|
o->oGoombaTurningAwayFromWall = FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -703,11 +703,17 @@ u32 take_damage_from_interact_object(struct MarioState *m) {
|
||||||
return damage;
|
return damage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int get_invincibility_flag(struct MarioState *m) {
|
||||||
|
return (m == &gMarioStates[0])
|
||||||
|
? INT_SUBTYPE_DELAY_INVINCIBILITY
|
||||||
|
: INT_SUBTYPE_DELAY_INVINCIBILITY_LUIGI;
|
||||||
|
}
|
||||||
|
|
||||||
u32 take_damage_and_knock_back(struct MarioState *m, struct Object *o) {
|
u32 take_damage_and_knock_back(struct MarioState *m, struct Object *o) {
|
||||||
u32 damage;
|
u32 damage;
|
||||||
|
|
||||||
if (!sInvulnerable && !(m->flags & MARIO_VANISH_CAP)
|
if (!sInvulnerable && !(m->flags & MARIO_VANISH_CAP)
|
||||||
&& !(o->oInteractionSubtype & INT_SUBTYPE_DELAY_INVINCIBILITY)) {
|
&& !(o->oInteractionSubtype & get_invincibility_flag(m))) {
|
||||||
o->oInteractStatus = INT_STATUS_INTERACTED | INT_STATUS_ATTACKED_MARIO;
|
o->oInteractStatus = INT_STATUS_INTERACTED | INT_STATUS_ATTACKED_MARIO;
|
||||||
m->interactObj = o;
|
m->interactObj = o;
|
||||||
|
|
||||||
|
@ -1143,7 +1149,7 @@ u32 interact_flame(struct MarioState *m, UNUSED u32 interactType, struct Object
|
||||||
u32 burningAction = ACT_BURNING_JUMP;
|
u32 burningAction = ACT_BURNING_JUMP;
|
||||||
|
|
||||||
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 & INT_SUBTYPE_DELAY_INVINCIBILITY)) {
|
&& !(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;
|
||||||
|
@ -1186,7 +1192,7 @@ u32 interact_snufit_bullet(struct MarioState *m, UNUSED u32 interactType, struct
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(o->oInteractionSubtype & INT_SUBTYPE_DELAY_INVINCIBILITY)) {
|
if (!(o->oInteractionSubtype & get_invincibility_flag(m))) {
|
||||||
sDelayInvincTimer = TRUE;
|
sDelayInvincTimer = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1202,7 +1208,7 @@ u32 interact_clam_or_bubba(struct MarioState *m, UNUSED u32 interactType, struct
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(o->oInteractionSubtype & INT_SUBTYPE_DELAY_INVINCIBILITY)) {
|
if (!(o->oInteractionSubtype & get_invincibility_flag(m))) {
|
||||||
sDelayInvincTimer = TRUE;
|
sDelayInvincTimer = TRUE;
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -1234,7 +1240,7 @@ u32 interact_bully(struct MarioState *m, UNUSED u32 interactType, struct Object
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (!sInvulnerable && !(m->flags & MARIO_VANISH_CAP)
|
else if (!sInvulnerable && !(m->flags & MARIO_VANISH_CAP)
|
||||||
&& !(o->oInteractionSubtype & INT_SUBTYPE_DELAY_INVINCIBILITY)) {
|
&& !(o->oInteractionSubtype & get_invincibility_flag(m))) {
|
||||||
o->oInteractStatus = INT_STATUS_INTERACTED;
|
o->oInteractStatus = INT_STATUS_INTERACTED;
|
||||||
m->invincTimer = 2;
|
m->invincTimer = 2;
|
||||||
|
|
||||||
|
@ -1254,7 +1260,7 @@ u32 interact_bully(struct MarioState *m, UNUSED u32 interactType, struct Object
|
||||||
|
|
||||||
u32 interact_shock(struct MarioState *m, UNUSED u32 interactType, struct Object *o) {
|
u32 interact_shock(struct MarioState *m, UNUSED u32 interactType, struct Object *o) {
|
||||||
if (!sInvulnerable && !(m->flags & MARIO_VANISH_CAP)
|
if (!sInvulnerable && !(m->flags & MARIO_VANISH_CAP)
|
||||||
&& !(o->oInteractionSubtype & INT_SUBTYPE_DELAY_INVINCIBILITY)) {
|
&& !(o->oInteractionSubtype & get_invincibility_flag(m))) {
|
||||||
u32 actionArg = (m->action & (ACT_FLAG_AIR | ACT_FLAG_ON_POLE | ACT_FLAG_HANGING)) == 0;
|
u32 actionArg = (m->action & (ACT_FLAG_AIR | ACT_FLAG_ON_POLE | ACT_FLAG_HANGING)) == 0;
|
||||||
|
|
||||||
o->oInteractStatus = INT_STATUS_INTERACTED | INT_STATUS_ATTACKED_MARIO;
|
o->oInteractStatus = INT_STATUS_INTERACTED | INT_STATUS_ATTACKED_MARIO;
|
||||||
|
@ -1272,14 +1278,14 @@ u32 interact_shock(struct MarioState *m, UNUSED u32 interactType, struct Object
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(o->oInteractionSubtype & INT_SUBTYPE_DELAY_INVINCIBILITY)) {
|
if (!(o->oInteractionSubtype & get_invincibility_flag(m))) {
|
||||||
sDelayInvincTimer = TRUE;
|
sDelayInvincTimer = TRUE;
|
||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 interact_stub(UNUSED struct MarioState *m, UNUSED u32 interactType, struct Object *o) {
|
static u32 interact_stub(UNUSED struct MarioState *m, UNUSED u32 interactType, struct Object *o) {
|
||||||
if (!(o->oInteractionSubtype & INT_SUBTYPE_DELAY_INVINCIBILITY)) {
|
if (!(o->oInteractionSubtype & get_invincibility_flag(m))) {
|
||||||
sDelayInvincTimer = TRUE;
|
sDelayInvincTimer = TRUE;
|
||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -1290,7 +1296,7 @@ u32 interact_mr_blizzard(struct MarioState *m, UNUSED u32 interactType, struct O
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(o->oInteractionSubtype & INT_SUBTYPE_DELAY_INVINCIBILITY)) {
|
if (!(o->oInteractionSubtype & get_invincibility_flag(m))) {
|
||||||
sDelayInvincTimer = TRUE;
|
sDelayInvincTimer = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1332,7 +1338,7 @@ u32 interact_hit_from_below(struct MarioState *m, UNUSED u32 interactType, struc
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(o->oInteractionSubtype & INT_SUBTYPE_DELAY_INVINCIBILITY)) {
|
if (!(o->oInteractionSubtype & get_invincibility_flag(m))) {
|
||||||
sDelayInvincTimer = TRUE;
|
sDelayInvincTimer = TRUE;
|
||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -1367,7 +1373,7 @@ u32 interact_bounce_top(struct MarioState *m, UNUSED u32 interactType, struct Ob
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(o->oInteractionSubtype & INT_SUBTYPE_DELAY_INVINCIBILITY)) {
|
if (!(o->oInteractionSubtype & get_invincibility_flag(m))) {
|
||||||
sDelayInvincTimer = TRUE;
|
sDelayInvincTimer = TRUE;
|
||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -1383,7 +1389,7 @@ u32 interact_unknown_08(struct MarioState *m, UNUSED u32 interactType, struct Ob
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(o->oInteractionSubtype & INT_SUBTYPE_DELAY_INVINCIBILITY)) {
|
if (!(o->oInteractionSubtype & get_invincibility_flag(m))) {
|
||||||
sDelayInvincTimer = TRUE;
|
sDelayInvincTimer = TRUE;
|
||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -1394,7 +1400,7 @@ u32 interact_damage(struct MarioState *m, UNUSED u32 interactType, struct Object
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(o->oInteractionSubtype & INT_SUBTYPE_DELAY_INVINCIBILITY)) {
|
if (!(o->oInteractionSubtype & get_invincibility_flag(m))) {
|
||||||
sDelayInvincTimer = TRUE;
|
sDelayInvincTimer = TRUE;
|
||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
|
@ -44,6 +44,7 @@
|
||||||
|
|
||||||
// Damaging interactions
|
// Damaging interactions
|
||||||
#define INT_SUBTYPE_DELAY_INVINCIBILITY 0x00000002
|
#define INT_SUBTYPE_DELAY_INVINCIBILITY 0x00000002
|
||||||
|
#define INT_SUBTYPE_DELAY_INVINCIBILITY_LUIGI 0x00008000
|
||||||
#define INT_SUBTYPE_BIG_KNOCKBACK 0x00000008 /* Used by Bowser, sets Mario's forward velocity to 40 on hit */
|
#define INT_SUBTYPE_BIG_KNOCKBACK 0x00000008 /* Used by Bowser, sets Mario's forward velocity to 40 on hit */
|
||||||
|
|
||||||
// INTERACT_GRABBABLE
|
// INTERACT_GRABBABLE
|
||||||
|
|
|
@ -517,17 +517,17 @@ s32 is_point_within_radius_of_mario(f32 x, f32 y, f32 z, s32 dist) {
|
||||||
/**
|
/**
|
||||||
* Returns either gMarioObject or gLuigiObject depending on what is closer
|
* Returns either gMarioObject or gLuigiObject depending on what is closer
|
||||||
*/
|
*/
|
||||||
struct Object* nearest_player_object(f32 x, f32 y, f32 z) {
|
struct Object* nearest_player_to_object(struct Object *obj) {
|
||||||
f32 mx = gMarioObject->header.gfx.pos[0] - x;
|
f32 mx = gMarioObject->header.gfx.pos[0] - obj->oPosX;
|
||||||
f32 my = gMarioObject->header.gfx.pos[1] - y;
|
f32 my = gMarioObject->header.gfx.pos[1] - obj->oPosY;
|
||||||
f32 mz = gMarioObject->header.gfx.pos[2] - z;
|
f32 mz = gMarioObject->header.gfx.pos[2] - obj->oPosZ;
|
||||||
mx *= mx;
|
mx *= mx;
|
||||||
my *= my;
|
my *= my;
|
||||||
mz *= mz;
|
mz *= mz;
|
||||||
|
|
||||||
f32 lx = gLuigiObject->header.gfx.pos[0] - x;
|
f32 lx = gLuigiObject->header.gfx.pos[0] - obj->oPosX;
|
||||||
f32 ly = gLuigiObject->header.gfx.pos[1] - y;
|
f32 ly = gLuigiObject->header.gfx.pos[1] - obj->oPosY;
|
||||||
f32 lz = gLuigiObject->header.gfx.pos[2] - z;
|
f32 lz = gLuigiObject->header.gfx.pos[2] - obj->oPosZ;
|
||||||
lx *= lx;
|
lx *= lx;
|
||||||
ly *= ly;
|
ly *= ly;
|
||||||
lz *= lz;
|
lz *= lz;
|
||||||
|
|
|
@ -882,9 +882,10 @@ static void treat_far_home_as_mario(f32 threshold) {
|
||||||
o->oAngleToMario = atan2s(dz, dx);
|
o->oAngleToMario = atan2s(dz, dx);
|
||||||
o->oDistanceToMario = 25000.0f;
|
o->oDistanceToMario = 25000.0f;
|
||||||
} else {
|
} else {
|
||||||
dx = o->oHomeX - gMarioObject->oPosX;
|
struct Object* player = nearest_player_to_object(o);
|
||||||
dy = o->oHomeY - gMarioObject->oPosY;
|
dx = o->oHomeX - player->oPosX;
|
||||||
dz = o->oHomeZ - gMarioObject->oPosZ;
|
dy = o->oHomeY - player->oPosY;
|
||||||
|
dz = o->oHomeZ - player->oPosZ;
|
||||||
distance = sqrtf(dx * dx + dy * dy + dz * dz);
|
distance = sqrtf(dx * dx + dy * dy + dz * dz);
|
||||||
|
|
||||||
if (distance > threshold) {
|
if (distance > threshold) {
|
||||||
|
|
|
@ -68,10 +68,9 @@ int detect_object_hurtbox_overlap(struct Object *a, struct Object *b) {
|
||||||
f32 sp28 = a->hurtboxRadius + b->hurtboxRadius;
|
f32 sp28 = a->hurtboxRadius + b->hurtboxRadius;
|
||||||
f32 sp24 = sqrtf(sp34 * sp34 + sp2C * sp2C);
|
f32 sp24 = sqrtf(sp34 * sp34 + sp2C * sp2C);
|
||||||
|
|
||||||
if (a == gMarioObject || a == gLuigiObject) {
|
if (a == gMarioObject) { b->oInteractionSubtype |= INT_SUBTYPE_DELAY_INVINCIBILITY; }
|
||||||
b->oInteractionSubtype |= INT_SUBTYPE_DELAY_INVINCIBILITY;
|
if (a == gLuigiObject) { b->oInteractionSubtype |= INT_SUBTYPE_DELAY_INVINCIBILITY_LUIGI; }
|
||||||
}
|
|
||||||
|
|
||||||
if (sp28 > sp24) {
|
if (sp28 > sp24) {
|
||||||
f32 sp20 = a->hitboxHeight + sp3C;
|
f32 sp20 = a->hitboxHeight + sp3C;
|
||||||
f32 sp1C = b->hurtboxHeight + sp38;
|
f32 sp1C = b->hurtboxHeight + sp38;
|
||||||
|
@ -82,9 +81,8 @@ int detect_object_hurtbox_overlap(struct Object *a, struct Object *b) {
|
||||||
if (sp20 < sp38) {
|
if (sp20 < sp38) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (a == gMarioObject || a == gLuigiObject) {
|
if (a == gMarioObject) { b->oInteractionSubtype &= ~INT_SUBTYPE_DELAY_INVINCIBILITY; }
|
||||||
b->oInteractionSubtype &= ~INT_SUBTYPE_DELAY_INVINCIBILITY;
|
if (a == gLuigiObject) { b->oInteractionSubtype &= ~INT_SUBTYPE_DELAY_INVINCIBILITY_LUIGI; }
|
||||||
}
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue