Skip to content

Commit faf1e7e

Browse files
committed
Implemented toggleable draw distance
1 parent 2be4b68 commit faf1e7e

26 files changed

Lines changed: 571 additions & 414 deletions

include/sm64.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <PR/gu.h>
77
#include <PR/ucode.h>
88
#include "port/Engine.h"
9+
#include "port/hooks/Events.h"
910
#include <libultra/os.h>
1011
#include "variables.h"
1112

src/engine/behavior_script.c

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -991,15 +991,19 @@ void cur_obj_update(void) {
991991
cur_obj_enable_rendering_if_mario_in_room();
992992
} else if ((objFlags & OBJ_FLAG_COMPUTE_DIST_TO_MARIO) && gCurrentObject->collisionData == NULL) {
993993
if (!(objFlags & OBJ_FLAG_ACTIVE_FROM_AFAR)) {
994-
// If the object has a render distance, check if it should be shown.
995-
if (distanceFromMario > gCurrentObject->oDrawingDistance) {
996-
// Out of render distance, hide the object.
997-
gCurrentObject->header.gfx.node.flags &= ~GRAPH_RENDER_ACTIVE;
998-
gCurrentObject->activeFlags |= ACTIVE_FLAG_FAR_AWAY;
999-
} else if (gCurrentObject->oHeldState == HELD_FREE) {
1000-
// In render distance (and not being held), show the object.
1001-
gCurrentObject->header.gfx.node.flags |= GRAPH_RENDER_ACTIVE;
1002-
gCurrentObject->activeFlags &= ~ACTIVE_FLAG_FAR_AWAY;
994+
bool visible = distanceFromMario <= gCurrentObject->oDrawingDistance;
995+
996+
CALL_CANCELLABLE_EVENT(EntityDistanceRender, &visible) {
997+
// If the object has a render distance, check if it should be shown.
998+
if (!visible) {
999+
// Out of render distance, hide the object.
1000+
gCurrentObject->header.gfx.node.flags &= ~GRAPH_RENDER_ACTIVE;
1001+
gCurrentObject->activeFlags |= ACTIVE_FLAG_FAR_AWAY;
1002+
} else if (gCurrentObject->oHeldState == HELD_FREE) {
1003+
// In render distance (and not being held), show the object.
1004+
gCurrentObject->header.gfx.node.flags |= GRAPH_RENDER_ACTIVE;
1005+
gCurrentObject->activeFlags &= ~ACTIVE_FLAG_FAR_AWAY;
1006+
}
10031007
}
10041008
}
10051009
}

src/engine/surface_load.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -789,9 +789,13 @@ void load_object_collision_model(void) {
789789
}
790790
}
791791

792-
if (marioDist < gCurrentObject->oDrawingDistance) {
793-
gCurrentObject->header.gfx.node.flags |= GRAPH_RENDER_ACTIVE;
794-
} else {
795-
gCurrentObject->header.gfx.node.flags &= ~GRAPH_RENDER_ACTIVE;
796-
}
792+
bool visible = (marioDist < gCurrentObject->oDrawingDistance);
793+
794+
CALL_CANCELLABLE_EVENT(EntityDistanceLoad, &visible) {
795+
if (visible) {
796+
gCurrentObject->header.gfx.node.flags |= GRAPH_RENDER_ACTIVE;
797+
} else {
798+
gCurrentObject->header.gfx.node.flags &= ~GRAPH_RENDER_ACTIVE;
799+
}
800+
};
797801
}

src/game/behaviors/bub.inc.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,16 @@
77
void bub_spawner_act_0(void) {
88
s32 i;
99
s32 sp18 = o->oBirdChirpChirpUnkF4;
10-
if (o->oDistanceToMario < 1500.0f) {
11-
for (i = 0; i < sp18; i++) {
12-
spawn_object(o, MODEL_BUB, bhvBub);
10+
bool visible = o->oDistanceToMario < 1500.0f;
11+
12+
CALL_CANCELLABLE_EVENT(EntityDistanceLoad, &visible) {
13+
if (visible) {
14+
for (i = 0; i < sp18; i++) {
15+
spawn_object(o, MODEL_BUB, bhvBub);
16+
}
17+
o->oAction = 1;
1318
}
14-
o->oAction = 1;
15-
}
19+
};
1620
}
1721

1822
void bub_spawner_act_1(void) {

src/game/behaviors/chain_chomp.inc.c

Lines changed: 112 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -50,35 +50,39 @@ static void chain_chomp_act_uninitialized(void) {
5050
struct ChainSegment *segments;
5151
s32 i;
5252

53-
if (o->oDistanceToMario < 3000.0f) {
54-
segments = mem_pool_alloc(gObjectMemoryPool, 5 * sizeof(struct ChainSegment));
55-
if (segments != NULL) {
56-
// Each segment represents the offset of a chain part to the pivot.
57-
// Segment 0 connects the pivot to the chain chomp itself. Segment
58-
// 1 connects the pivot to the chain part next to the chain chomp
59-
// (chain part 1), etc.
60-
o->oChainChompSegments = segments;
61-
for (i = 0; i <= 4; i++) {
62-
chain_segment_init(&segments[i]);
63-
}
53+
bool visible = o->oDistanceToMario < 3000.0f;
54+
55+
CALL_CANCELLABLE_EVENT(EntityDistanceLoad, &visible) {
56+
if (visible) {
57+
segments = mem_pool_alloc(gObjectMemoryPool, 5 * sizeof(struct ChainSegment));
58+
if (segments != NULL) {
59+
// Each segment represents the offset of a chain part to the pivot.
60+
// Segment 0 connects the pivot to the chain chomp itself. Segment
61+
// 1 connects the pivot to the chain part next to the chain chomp
62+
// (chain part 1), etc.
63+
o->oChainChompSegments = segments;
64+
for (i = 0; i <= 4; i++) {
65+
chain_segment_init(&segments[i]);
66+
}
6467

65-
cur_obj_set_pos_to_home();
68+
cur_obj_set_pos_to_home();
6669

67-
// Spawn the pivot and set to parent
68-
if ((o->parentObj =
69-
spawn_object(o, CHAIN_CHOMP_CHAIN_PART_BP_PIVOT, bhvChainChompChainPart))
70-
!= NULL) {
71-
// Spawn the non-pivot chain parts, starting from the chain
72-
// chomp and moving toward the pivot
73-
for (i = 1; i <= 4; i++) {
74-
spawn_object_relative(i, 0, 0, 0, o, MODEL_METALLIC_BALL, bhvChainChompChainPart);
75-
}
70+
// Spawn the pivot and set to parent
71+
if ((o->parentObj =
72+
spawn_object(o, CHAIN_CHOMP_CHAIN_PART_BP_PIVOT, bhvChainChompChainPart))
73+
!= NULL) {
74+
// Spawn the non-pivot chain parts, starting from the chain
75+
// chomp and moving toward the pivot
76+
for (i = 1; i <= 4; i++) {
77+
spawn_object_relative(i, 0, 0, 0, o, MODEL_METALLIC_BALL, bhvChainChompChainPart);
78+
}
7679

77-
o->oAction = CHAIN_CHOMP_ACT_MOVE;
78-
cur_obj_unhide();
80+
o->oAction = CHAIN_CHOMP_ACT_MOVE;
81+
cur_obj_unhide();
82+
}
7983
}
8084
}
81-
}
85+
};
8286
}
8387

8488
/**
@@ -355,94 +359,98 @@ static void chain_chomp_act_move(void) {
355359
f32 maxDistToPivot;
356360

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

364-
switch (o->oChainChompReleaseStatus) {
365-
case CHAIN_CHOMP_NOT_RELEASED:
366-
switch (o->oSubAction) {
367-
case CHAIN_CHOMP_SUB_ACT_TURN:
368-
chain_chomp_sub_act_turn();
369-
break;
370-
case CHAIN_CHOMP_SUB_ACT_LUNGE:
371-
chain_chomp_sub_act_lunge();
372-
break;
373-
}
374-
break;
375-
case CHAIN_CHOMP_RELEASED_TRIGGER_CUTSCENE:
376-
chain_chomp_released_trigger_cutscene();
377-
break;
378-
case CHAIN_CHOMP_RELEASED_LUNGE_AROUND:
379-
chain_chomp_released_lunge_around();
380-
break;
381-
case CHAIN_CHOMP_RELEASED_BREAK_GATE:
382-
chain_chomp_released_break_gate();
383-
break;
384-
case CHAIN_CHOMP_RELEASED_JUMP_AWAY:
385-
chain_chomp_released_jump_away();
386-
break;
387-
case CHAIN_CHOMP_RELEASED_END_CUTSCENE:
388-
chain_chomp_released_end_cutscene();
389-
break;
390-
}
364+
CALL_CANCELLABLE_EVENT(EntityDistanceRender, &visible) {
365+
if (o->oChainChompReleaseStatus == CHAIN_CHOMP_NOT_RELEASED && !visible) {
366+
o->oAction = CHAIN_CHOMP_ACT_UNLOAD_CHAIN;
367+
o->oForwardVel = o->oVelY = 0.0f;
368+
} else {
369+
cur_obj_update_floor_and_walls();
370+
371+
switch (o->oChainChompReleaseStatus) {
372+
case CHAIN_CHOMP_NOT_RELEASED:
373+
switch (o->oSubAction) {
374+
case CHAIN_CHOMP_SUB_ACT_TURN:
375+
chain_chomp_sub_act_turn();
376+
break;
377+
case CHAIN_CHOMP_SUB_ACT_LUNGE:
378+
chain_chomp_sub_act_lunge();
379+
break;
380+
}
381+
break;
382+
case CHAIN_CHOMP_RELEASED_TRIGGER_CUTSCENE:
383+
chain_chomp_released_trigger_cutscene();
384+
break;
385+
case CHAIN_CHOMP_RELEASED_LUNGE_AROUND:
386+
chain_chomp_released_lunge_around();
387+
break;
388+
case CHAIN_CHOMP_RELEASED_BREAK_GATE:
389+
chain_chomp_released_break_gate();
390+
break;
391+
case CHAIN_CHOMP_RELEASED_JUMP_AWAY:
392+
chain_chomp_released_jump_away();
393+
break;
394+
case CHAIN_CHOMP_RELEASED_END_CUTSCENE:
395+
chain_chomp_released_end_cutscene();
396+
break;
397+
}
391398

392-
cur_obj_move_standard(78);
399+
cur_obj_move_standard(78);
393400

394-
// Segment 0 connects the pivot to the chain chomp itself
395-
o->oChainChompSegments[0].posX = o->oPosX - o->parentObj->oPosX;
396-
o->oChainChompSegments[0].posY = o->oPosY - o->parentObj->oPosY;
397-
o->oChainChompSegments[0].posZ = o->oPosZ - o->parentObj->oPosZ;
398-
399-
o->oChainChompDistToPivot =
400-
sqrtf(o->oChainChompSegments[0].posX * o->oChainChompSegments[0].posX
401-
+ o->oChainChompSegments[0].posY * o->oChainChompSegments[0].posY
402-
+ o->oChainChompSegments[0].posZ * o->oChainChompSegments[0].posZ);
403-
404-
// If the chain is fully stretched
405-
maxDistToPivot = o->oChainChompMaxDistFromPivotPerChainPart * 5;
406-
if (o->oChainChompDistToPivot > maxDistToPivot) {
407-
f32 ratio = maxDistToPivot / o->oChainChompDistToPivot;
408-
o->oChainChompDistToPivot = maxDistToPivot;
409-
410-
o->oChainChompSegments[0].posX *= ratio;
411-
o->oChainChompSegments[0].posY *= ratio;
412-
o->oChainChompSegments[0].posZ *= ratio;
413-
414-
if (o->oChainChompReleaseStatus == CHAIN_CHOMP_NOT_RELEASED) {
415-
// Restrict chain chomp position
416-
o->oPosX = o->parentObj->oPosX + o->oChainChompSegments[0].posX;
417-
o->oPosY = o->parentObj->oPosY + o->oChainChompSegments[0].posY;
418-
o->oPosZ = o->parentObj->oPosZ + o->oChainChompSegments[0].posZ;
419-
420-
o->oChainChompRestrictedByChain = TRUE;
421-
} else {
422-
// Move pivot like the chain chomp is pulling it along
423-
f32 oldPivotY = o->parentObj->oPosY;
401+
// Segment 0 connects the pivot to the chain chomp itself
402+
o->oChainChompSegments[0].posX = o->oPosX - o->parentObj->oPosX;
403+
o->oChainChompSegments[0].posY = o->oPosY - o->parentObj->oPosY;
404+
o->oChainChompSegments[0].posZ = o->oPosZ - o->parentObj->oPosZ;
405+
406+
o->oChainChompDistToPivot =
407+
sqrtf(o->oChainChompSegments[0].posX * o->oChainChompSegments[0].posX
408+
+ o->oChainChompSegments[0].posY * o->oChainChompSegments[0].posY
409+
+ o->oChainChompSegments[0].posZ * o->oChainChompSegments[0].posZ);
410+
411+
// If the chain is fully stretched
412+
maxDistToPivot = o->oChainChompMaxDistFromPivotPerChainPart * 5;
413+
if (o->oChainChompDistToPivot > maxDistToPivot) {
414+
f32 ratio = maxDistToPivot / o->oChainChompDistToPivot;
415+
o->oChainChompDistToPivot = maxDistToPivot;
416+
417+
o->oChainChompSegments[0].posX *= ratio;
418+
o->oChainChompSegments[0].posY *= ratio;
419+
o->oChainChompSegments[0].posZ *= ratio;
420+
421+
if (o->oChainChompReleaseStatus == CHAIN_CHOMP_NOT_RELEASED) {
422+
// Restrict chain chomp position
423+
o->oPosX = o->parentObj->oPosX + o->oChainChompSegments[0].posX;
424+
o->oPosY = o->parentObj->oPosY + o->oChainChompSegments[0].posY;
425+
o->oPosZ = o->parentObj->oPosZ + o->oChainChompSegments[0].posZ;
426+
427+
o->oChainChompRestrictedByChain = TRUE;
428+
} else {
429+
// Move pivot like the chain chomp is pulling it along
430+
f32 oldPivotY = o->parentObj->oPosY;
424431

425-
o->parentObj->oPosX = o->oPosX - o->oChainChompSegments[0].posX;
426-
o->parentObj->oPosY = o->oPosY - o->oChainChompSegments[0].posY;
427-
o->parentObj->oVelY = o->parentObj->oPosY - oldPivotY;
428-
o->parentObj->oPosZ = o->oPosZ - o->oChainChompSegments[0].posZ;
432+
o->parentObj->oPosX = o->oPosX - o->oChainChompSegments[0].posX;
433+
o->parentObj->oPosY = o->oPosY - o->oChainChompSegments[0].posY;
434+
o->parentObj->oVelY = o->parentObj->oPosY - oldPivotY;
435+
o->parentObj->oPosZ = o->oPosZ - o->oChainChompSegments[0].posZ;
436+
}
437+
} else {
438+
o->oChainChompRestrictedByChain = FALSE;
429439
}
430-
} else {
431-
o->oChainChompRestrictedByChain = FALSE;
432-
}
433440

434-
chain_chomp_update_chain_segments();
441+
chain_chomp_update_chain_segments();
435442

436-
// Begin a lunge if mario tries to attack
437-
if (obj_check_attacks(&sChainChompHitbox, o->oAction) != 0) {
438-
o->oSubAction = CHAIN_CHOMP_SUB_ACT_LUNGE;
439-
o->oChainChompMaxDistFromPivotPerChainPart = 900.0f / 5;
440-
o->oForwardVel = 0.0f;
441-
o->oVelY = 300.0f;
442-
o->oGravity = -4.0f;
443-
o->oChainChompTargetPitch = -0x3000;
443+
// Begin a lunge if mario tries to attack
444+
if (obj_check_attacks(&sChainChompHitbox, o->oAction) != 0) {
445+
o->oSubAction = CHAIN_CHOMP_SUB_ACT_LUNGE;
446+
o->oChainChompMaxDistFromPivotPerChainPart = 900.0f / 5;
447+
o->oForwardVel = 0.0f;
448+
o->oVelY = 300.0f;
449+
o->oGravity = -4.0f;
450+
o->oChainChompTargetPitch = -0x3000;
451+
}
444452
}
445-
}
453+
};
446454
}
447455

448456
/**

0 commit comments

Comments
 (0)