Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions include/sm64.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <PR/gu.h>
#include <PR/ucode.h>
#include "port/Engine.h"
#include "port/hooks/Events.h"
#include <libultra/os.h>
#include "variables.h"

Expand Down
22 changes: 13 additions & 9 deletions src/engine/behavior_script.c
Original file line number Diff line number Diff line change
Expand Up @@ -991,15 +991,19 @@ void cur_obj_update(void) {
cur_obj_enable_rendering_if_mario_in_room();
} else if ((objFlags & OBJ_FLAG_COMPUTE_DIST_TO_MARIO) && gCurrentObject->collisionData == NULL) {
if (!(objFlags & OBJ_FLAG_ACTIVE_FROM_AFAR)) {
// If the object has a render distance, check if it should be shown.
if (distanceFromMario > gCurrentObject->oDrawingDistance) {
// Out of render distance, hide the object.
gCurrentObject->header.gfx.node.flags &= ~GRAPH_RENDER_ACTIVE;
gCurrentObject->activeFlags |= ACTIVE_FLAG_FAR_AWAY;
} else if (gCurrentObject->oHeldState == HELD_FREE) {
// In render distance (and not being held), show the object.
gCurrentObject->header.gfx.node.flags |= GRAPH_RENDER_ACTIVE;
gCurrentObject->activeFlags &= ~ACTIVE_FLAG_FAR_AWAY;
bool visible = distanceFromMario <= gCurrentObject->oDrawingDistance;

CALL_CANCELLABLE_EVENT(EntityDistanceRender, &visible) {
// If the object has a render distance, check if it should be shown.
if (!visible) {
// Out of render distance, hide the object.
gCurrentObject->header.gfx.node.flags &= ~GRAPH_RENDER_ACTIVE;
gCurrentObject->activeFlags |= ACTIVE_FLAG_FAR_AWAY;
} else if (gCurrentObject->oHeldState == HELD_FREE) {
// In render distance (and not being held), show the object.
gCurrentObject->header.gfx.node.flags |= GRAPH_RENDER_ACTIVE;
gCurrentObject->activeFlags &= ~ACTIVE_FLAG_FAR_AWAY;
}
}
}
}
Expand Down
14 changes: 9 additions & 5 deletions src/engine/surface_load.c
Original file line number Diff line number Diff line change
Expand Up @@ -789,9 +789,13 @@ void load_object_collision_model(void) {
}
}

if (marioDist < gCurrentObject->oDrawingDistance) {
gCurrentObject->header.gfx.node.flags |= GRAPH_RENDER_ACTIVE;
} else {
gCurrentObject->header.gfx.node.flags &= ~GRAPH_RENDER_ACTIVE;
}
bool visible = (marioDist < gCurrentObject->oDrawingDistance);

CALL_CANCELLABLE_EVENT(EntityDistanceLoad, &visible) {
if (visible) {
gCurrentObject->header.gfx.node.flags |= GRAPH_RENDER_ACTIVE;
} else {
gCurrentObject->header.gfx.node.flags &= ~GRAPH_RENDER_ACTIVE;
}
};
}
14 changes: 9 additions & 5 deletions src/game/behaviors/bub.inc.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,16 @@
void bub_spawner_act_0(void) {
s32 i;
s32 sp18 = o->oBirdChirpChirpUnkF4;
if (o->oDistanceToMario < 1500.0f) {
for (i = 0; i < sp18; i++) {
spawn_object(o, MODEL_BUB, bhvBub);
bool visible = o->oDistanceToMario < 1500.0f;

CALL_CANCELLABLE_EVENT(EntityDistanceLoad, &visible) {
if (visible) {
for (i = 0; i < sp18; i++) {
spawn_object(o, MODEL_BUB, bhvBub);
}
o->oAction = 1;
}
o->oAction = 1;
}
};
}

void bub_spawner_act_1(void) {
Expand Down
216 changes: 112 additions & 104 deletions src/game/behaviors/chain_chomp.inc.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,35 +50,39 @@ static void chain_chomp_act_uninitialized(void) {
struct ChainSegment *segments;
s32 i;

if (o->oDistanceToMario < 3000.0f) {
segments = mem_pool_alloc(gObjectMemoryPool, 5 * sizeof(struct ChainSegment));
if (segments != NULL) {
// Each segment represents the offset of a chain part to the pivot.
// Segment 0 connects the pivot to the chain chomp itself. Segment
// 1 connects the pivot to the chain part next to the chain chomp
// (chain part 1), etc.
o->oChainChompSegments = segments;
for (i = 0; i <= 4; i++) {
chain_segment_init(&segments[i]);
}
bool visible = o->oDistanceToMario < 3000.0f;

CALL_CANCELLABLE_EVENT(EntityDistanceLoad, &visible) {
if (visible) {
segments = mem_pool_alloc(gObjectMemoryPool, 5 * sizeof(struct ChainSegment));
if (segments != NULL) {
// Each segment represents the offset of a chain part to the pivot.
// Segment 0 connects the pivot to the chain chomp itself. Segment
// 1 connects the pivot to the chain part next to the chain chomp
// (chain part 1), etc.
o->oChainChompSegments = segments;
for (i = 0; i <= 4; i++) {
chain_segment_init(&segments[i]);
}

cur_obj_set_pos_to_home();
cur_obj_set_pos_to_home();

// Spawn the pivot and set to parent
if ((o->parentObj =
spawn_object(o, CHAIN_CHOMP_CHAIN_PART_BP_PIVOT, bhvChainChompChainPart))
!= NULL) {
// Spawn the non-pivot chain parts, starting from the chain
// chomp and moving toward the pivot
for (i = 1; i <= 4; i++) {
spawn_object_relative(i, 0, 0, 0, o, MODEL_METALLIC_BALL, bhvChainChompChainPart);
}
// Spawn the pivot and set to parent
if ((o->parentObj =
spawn_object(o, CHAIN_CHOMP_CHAIN_PART_BP_PIVOT, bhvChainChompChainPart))
!= NULL) {
// Spawn the non-pivot chain parts, starting from the chain
// chomp and moving toward the pivot
for (i = 1; i <= 4; i++) {
spawn_object_relative(i, 0, 0, 0, o, MODEL_METALLIC_BALL, bhvChainChompChainPart);
}

o->oAction = CHAIN_CHOMP_ACT_MOVE;
cur_obj_unhide();
o->oAction = CHAIN_CHOMP_ACT_MOVE;
cur_obj_unhide();
}
}
}
}
};
}

/**
Expand Down Expand Up @@ -355,94 +359,98 @@ static void chain_chomp_act_move(void) {
f32 maxDistToPivot;

// Unload chain if mario is far enough
if (o->oChainChompReleaseStatus == CHAIN_CHOMP_NOT_RELEASED && o->oDistanceToMario > 4000.0f) {
o->oAction = CHAIN_CHOMP_ACT_UNLOAD_CHAIN;
o->oForwardVel = o->oVelY = 0.0f;
} else {
cur_obj_update_floor_and_walls();
bool visible = o->oDistanceToMario <= 4000.0f;

switch (o->oChainChompReleaseStatus) {
case CHAIN_CHOMP_NOT_RELEASED:
switch (o->oSubAction) {
case CHAIN_CHOMP_SUB_ACT_TURN:
chain_chomp_sub_act_turn();
break;
case CHAIN_CHOMP_SUB_ACT_LUNGE:
chain_chomp_sub_act_lunge();
break;
}
break;
case CHAIN_CHOMP_RELEASED_TRIGGER_CUTSCENE:
chain_chomp_released_trigger_cutscene();
break;
case CHAIN_CHOMP_RELEASED_LUNGE_AROUND:
chain_chomp_released_lunge_around();
break;
case CHAIN_CHOMP_RELEASED_BREAK_GATE:
chain_chomp_released_break_gate();
break;
case CHAIN_CHOMP_RELEASED_JUMP_AWAY:
chain_chomp_released_jump_away();
break;
case CHAIN_CHOMP_RELEASED_END_CUTSCENE:
chain_chomp_released_end_cutscene();
break;
}
CALL_CANCELLABLE_EVENT(EntityDistanceRender, &visible) {
if (o->oChainChompReleaseStatus == CHAIN_CHOMP_NOT_RELEASED && !visible) {
o->oAction = CHAIN_CHOMP_ACT_UNLOAD_CHAIN;
o->oForwardVel = o->oVelY = 0.0f;
} else {
cur_obj_update_floor_and_walls();

switch (o->oChainChompReleaseStatus) {
case CHAIN_CHOMP_NOT_RELEASED:
switch (o->oSubAction) {
case CHAIN_CHOMP_SUB_ACT_TURN:
chain_chomp_sub_act_turn();
break;
case CHAIN_CHOMP_SUB_ACT_LUNGE:
chain_chomp_sub_act_lunge();
break;
}
break;
case CHAIN_CHOMP_RELEASED_TRIGGER_CUTSCENE:
chain_chomp_released_trigger_cutscene();
break;
case CHAIN_CHOMP_RELEASED_LUNGE_AROUND:
chain_chomp_released_lunge_around();
break;
case CHAIN_CHOMP_RELEASED_BREAK_GATE:
chain_chomp_released_break_gate();
break;
case CHAIN_CHOMP_RELEASED_JUMP_AWAY:
chain_chomp_released_jump_away();
break;
case CHAIN_CHOMP_RELEASED_END_CUTSCENE:
chain_chomp_released_end_cutscene();
break;
}

cur_obj_move_standard(78);
cur_obj_move_standard(78);

// Segment 0 connects the pivot to the chain chomp itself
o->oChainChompSegments[0].posX = o->oPosX - o->parentObj->oPosX;
o->oChainChompSegments[0].posY = o->oPosY - o->parentObj->oPosY;
o->oChainChompSegments[0].posZ = o->oPosZ - o->parentObj->oPosZ;

o->oChainChompDistToPivot =
sqrtf(o->oChainChompSegments[0].posX * o->oChainChompSegments[0].posX
+ o->oChainChompSegments[0].posY * o->oChainChompSegments[0].posY
+ o->oChainChompSegments[0].posZ * o->oChainChompSegments[0].posZ);

// If the chain is fully stretched
maxDistToPivot = o->oChainChompMaxDistFromPivotPerChainPart * 5;
if (o->oChainChompDistToPivot > maxDistToPivot) {
f32 ratio = maxDistToPivot / o->oChainChompDistToPivot;
o->oChainChompDistToPivot = maxDistToPivot;

o->oChainChompSegments[0].posX *= ratio;
o->oChainChompSegments[0].posY *= ratio;
o->oChainChompSegments[0].posZ *= ratio;

if (o->oChainChompReleaseStatus == CHAIN_CHOMP_NOT_RELEASED) {
// Restrict chain chomp position
o->oPosX = o->parentObj->oPosX + o->oChainChompSegments[0].posX;
o->oPosY = o->parentObj->oPosY + o->oChainChompSegments[0].posY;
o->oPosZ = o->parentObj->oPosZ + o->oChainChompSegments[0].posZ;

o->oChainChompRestrictedByChain = TRUE;
} else {
// Move pivot like the chain chomp is pulling it along
f32 oldPivotY = o->parentObj->oPosY;
// Segment 0 connects the pivot to the chain chomp itself
o->oChainChompSegments[0].posX = o->oPosX - o->parentObj->oPosX;
o->oChainChompSegments[0].posY = o->oPosY - o->parentObj->oPosY;
o->oChainChompSegments[0].posZ = o->oPosZ - o->parentObj->oPosZ;

o->oChainChompDistToPivot =
sqrtf(o->oChainChompSegments[0].posX * o->oChainChompSegments[0].posX
+ o->oChainChompSegments[0].posY * o->oChainChompSegments[0].posY
+ o->oChainChompSegments[0].posZ * o->oChainChompSegments[0].posZ);

// If the chain is fully stretched
maxDistToPivot = o->oChainChompMaxDistFromPivotPerChainPart * 5;
if (o->oChainChompDistToPivot > maxDistToPivot) {
f32 ratio = maxDistToPivot / o->oChainChompDistToPivot;
o->oChainChompDistToPivot = maxDistToPivot;

o->oChainChompSegments[0].posX *= ratio;
o->oChainChompSegments[0].posY *= ratio;
o->oChainChompSegments[0].posZ *= ratio;

if (o->oChainChompReleaseStatus == CHAIN_CHOMP_NOT_RELEASED) {
// Restrict chain chomp position
o->oPosX = o->parentObj->oPosX + o->oChainChompSegments[0].posX;
o->oPosY = o->parentObj->oPosY + o->oChainChompSegments[0].posY;
o->oPosZ = o->parentObj->oPosZ + o->oChainChompSegments[0].posZ;

o->oChainChompRestrictedByChain = TRUE;
} else {
// Move pivot like the chain chomp is pulling it along
f32 oldPivotY = o->parentObj->oPosY;

o->parentObj->oPosX = o->oPosX - o->oChainChompSegments[0].posX;
o->parentObj->oPosY = o->oPosY - o->oChainChompSegments[0].posY;
o->parentObj->oVelY = o->parentObj->oPosY - oldPivotY;
o->parentObj->oPosZ = o->oPosZ - o->oChainChompSegments[0].posZ;
o->parentObj->oPosX = o->oPosX - o->oChainChompSegments[0].posX;
o->parentObj->oPosY = o->oPosY - o->oChainChompSegments[0].posY;
o->parentObj->oVelY = o->parentObj->oPosY - oldPivotY;
o->parentObj->oPosZ = o->oPosZ - o->oChainChompSegments[0].posZ;
}
} else {
o->oChainChompRestrictedByChain = FALSE;
}
} else {
o->oChainChompRestrictedByChain = FALSE;
}

chain_chomp_update_chain_segments();
chain_chomp_update_chain_segments();

// Begin a lunge if mario tries to attack
if (obj_check_attacks(&sChainChompHitbox, o->oAction) != 0) {
o->oSubAction = CHAIN_CHOMP_SUB_ACT_LUNGE;
o->oChainChompMaxDistFromPivotPerChainPart = 900.0f / 5;
o->oForwardVel = 0.0f;
o->oVelY = 300.0f;
o->oGravity = -4.0f;
o->oChainChompTargetPitch = -0x3000;
// Begin a lunge if mario tries to attack
if (obj_check_attacks(&sChainChompHitbox, o->oAction) != 0) {
o->oSubAction = CHAIN_CHOMP_SUB_ACT_LUNGE;
o->oChainChompMaxDistFromPivotPerChainPart = 900.0f / 5;
o->oForwardVel = 0.0f;
o->oVelY = 300.0f;
o->oGravity = -4.0f;
o->oChainChompTargetPitch = -0x3000;
}
}
}
};
}

/**
Expand Down
Loading
Loading