Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
MorsGames
GitHub Repository: MorsGames/sm64plus
Path: blob/master/src/game/behaviors/bird.inc.c
7861 views
1
/**
2
* Behavior for bhvBird. These are the birds in the castle grounds
3
* that fly away and scatter when Mario comes near them. There are
4
* 2 types of birds; spawner birds and spawned birds. Spawner birds
5
* are loaded by the level, and are inactive until Mario comes within
6
* 2000 units of them, when they spawn 6 spawned birds and start flying.
7
* Spawned birds are only spawned by a spawner bird, and start flying
8
* immediately after spawning.
9
*/
10
11
/**
12
* If the object is a spawned bird, start flying; if it's a spawner bird,
13
* spawn spawned birds if Mario comes within 2000 units of it.
14
*/
15
static void bird_act_inactive(void) {
16
// Start flying if the object is a spawned bird or if it's a spawner bird
17
// and Mario is within 2000 units.
18
if (o->oBehParams2ndByte == BIRD_BP_SPAWNED || o->oDistanceToMario < 2000.0f) {
19
// If the object is a spawner bird, play the sound of birds flying away,
20
// and spawn 6 spawned birds (which will start flying on the next frame).
21
if (o->oBehParams2ndByte != BIRD_BP_SPAWNED) {
22
s32 i;
23
24
cur_obj_play_sound_2(SOUND_GENERAL_BIRDS_FLY_AWAY);
25
26
for (i = 0; i < 6; i++) {
27
spawn_object(o, MODEL_BIRDS, bhvBird);
28
}
29
30
// The spawner bird's home acts as its target location.
31
o->oHomeX = -20.0f;
32
o->oHomeZ = -3990.0f;
33
}
34
35
// Start flying
36
o->oAction = BIRD_ACT_FLY;
37
38
// Start with a random yaw, and a random pitch from 1000 to 5000.
39
// Positive pitch is downwards.
40
o->oMoveAnglePitch = 5000 - (s32)(4000.0f * random_float());
41
o->oMoveAngleYaw = random_u16();
42
43
o->oBirdSpeed = 40.0f;
44
45
cur_obj_unhide();
46
}
47
}
48
49
/**
50
* Make the bird fly.
51
* The bird flies laterally towards a target; (-20, -3990) if it's a spawner bird,
52
* and the parent spawner bird if it's a spawned bird.
53
*/
54
static void bird_act_fly(void) {
55
UNUSED s32 unused;
56
f32 distance;
57
58
// Compute forward velocity and vertical velocity from oBirdSpeed and pitch
59
obj_compute_vel_from_move_pitch(o->oBirdSpeed);
60
61
// If the bird's parent is higher than 8000 units, despawn the bird.
62
// A spawned bird's parent is its spawner bird. A spawner bird's parent
63
// is itself. In other words, when a group of birds has its spawner bird
64
// fly past Y=8000, they will all despawn simultaneously. Otherwise, fly.
65
if (o->parentObj->oPosY > 8000.0f) {
66
obj_mark_for_deletion(o);
67
} else {
68
// If the bird is a spawner bird, fly towards its home; otherwise,
69
// fly towards the bird's spawner bird.
70
if (o->oBehParams2ndByte != BIRD_BP_SPAWNED) {
71
distance = cur_obj_lateral_dist_to_home();
72
73
// The spawner bird will start with its downwards (positive) pitch
74
// and will continuously decrease its pitch (i.e. make itself face more upwards)
75
// until it reaches its home, at which point it will face directly up.
76
// This is done by making its target pitch the arctangent of its distance
77
// to its home and its position - 10,000 (which is always negative).
78
o->oBirdTargetPitch = atan2s(distance, o->oPosY - 10000.0f);
79
o->oBirdTargetYaw = cur_obj_angle_to_home();
80
} else {
81
distance = lateral_dist_between_objects(o, o->parentObj);
82
83
// The bird's target pitch will face directly to its spawner bird.
84
o->oBirdTargetPitch = atan2s(distance, o->oPosY - o->parentObj->oPosY);
85
o->oBirdTargetYaw = obj_angle_to_object(o, o->parentObj);
86
87
// The bird goes faster the farther it is from its spawner bird so it can catch up.
88
o->oBirdSpeed = 0.04f * dist_between_objects(o, o->parentObj) + 20.0f;
89
}
90
91
// Approach to match the bird's target yaw and pitch.
92
obj_move_pitch_approach(o->oBirdTargetPitch, 140);
93
cur_obj_rotate_yaw_toward(o->oBirdTargetYaw, 800);
94
obj_roll_to_match_yaw_turn(o->oBirdTargetYaw, 0x3000, 600);
95
}
96
97
// The bird has no gravity, so this function only
98
// moves the bird using its forward velocity.
99
// Even if it did have gravity, it would only act as
100
// a constant added to its Y position every frame since
101
// its Y velocity is reset every frame by
102
// obj_compute_vel_from_move_pitch.
103
cur_obj_move_using_fvel_and_gravity();
104
}
105
106
/**
107
* Update function for bhvBird.
108
*/
109
void bhv_bird_update(void) {
110
switch (o->oAction) {
111
case BIRD_ACT_INACTIVE:
112
bird_act_inactive();
113
break;
114
case BIRD_ACT_FLY:
115
bird_act_fly();
116
break;
117
}
118
}
119
120