Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
MorsGames
GitHub Repository: MorsGames/sm64plus
Path: blob/master/src/game/behaviors/blue_coin.inc.c
7861 views
1
/**
2
* Behavior for bhvHiddenBlueCoin and bhvBlueCoinSwitch.
3
* bhvHiddenBlueCoin are the stationary blue coins that appear when
4
* you press a blue coin switch (a.k.a. bhvBlueCoinSwitch).
5
*/
6
7
/**
8
* Update function for bhvHiddenBlueCoin.
9
*/
10
void bhv_hidden_blue_coin_loop(void) {
11
struct Object *blueCoinSwitch;
12
13
switch (o->oAction) {
14
case HIDDEN_BLUE_COIN_ACT_INACTIVE:
15
// Become invisible and intangible
16
if (configRespawnCertainItems) {
17
cur_obj_hide();
18
}
19
else {
20
cur_obj_disable_rendering();
21
}
22
cur_obj_become_intangible();
23
24
// Set action to HIDDEN_BLUE_COIN_ACT_WAITING after the blue coin switch is found.
25
o->oHiddenBlueCoinSwitch = cur_obj_nearest_object_with_behavior(bhvBlueCoinSwitch);
26
27
if (o->oHiddenBlueCoinSwitch != NULL) {
28
o->oAction++;
29
}
30
31
break;
32
case HIDDEN_BLUE_COIN_ACT_WAITING:
33
// Wait until the blue coin switch starts ticking to activate.
34
blueCoinSwitch = o->oHiddenBlueCoinSwitch;
35
36
if (blueCoinSwitch->oAction == BLUE_COIN_SWITCH_ACT_TICKING) {
37
o->oAction++; // Set to HIDDEN_BLUE_COIN_ACT_ACTIVE
38
}
39
40
break;
41
case HIDDEN_BLUE_COIN_ACT_ACTIVE:
42
// Become tangible
43
if (configRespawnCertainItems) {
44
cur_obj_unhide();
45
}
46
else {
47
cur_obj_enable_rendering();
48
}
49
cur_obj_become_tangible();
50
51
// Delete the coin once collected
52
if (o->oInteractStatus & INT_STATUS_INTERACTED) {
53
spawn_object(o, MODEL_SPARKLES, bhvGoldenCoinSparkles);
54
obj_mark_for_deletion(o);
55
}
56
57
// After 200 frames of waiting and 20 2-frame blinks (for 240 frames total),
58
// delete the object.
59
if (cur_obj_wait_then_blink(200, 20)) {
60
if (configRespawnCertainItems) {
61
o->oAction = HIDDEN_BLUE_COIN_ACT_INACTIVE;
62
}
63
else {
64
obj_mark_for_deletion(o);
65
}
66
}
67
68
break;
69
}
70
71
o->oInteractStatus = 0;
72
}
73
74
/**
75
* Update function for bhvBlueCoinSwitch.
76
*/
77
void bhv_blue_coin_switch_loop(void) {
78
// The switch's model is 1/3 size.
79
cur_obj_scale(3.0f);
80
81
switch (o->oAction) {
82
case BLUE_COIN_SWITCH_ACT_IDLE:
83
// If Mario is on the switch and has ground-pounded,
84
// recede and get ready to start ticking.
85
if (gMarioObject->platform == o) {
86
if (gMarioStates[0].action == ACT_GROUND_POUND_LAND) {
87
// Set to BLUE_COIN_SWITCH_ACT_RECEDING
88
o->oAction++;
89
90
// Recede at a rate of 20 units/frame.
91
o->oVelY = -20.0f;
92
// Set gravity to 0 so it doesn't accelerate when receding.
93
o->oGravity = 0.0f;
94
95
cur_obj_play_sound_2(SOUND_GENERAL_SWITCH_DOOR_OPEN);
96
}
97
}
98
99
// Have collision
100
load_object_collision_model();
101
102
break;
103
case BLUE_COIN_SWITCH_ACT_RECEDING:
104
// Recede for 6 frames before going invisible and ticking.
105
// This is probably an off-by-one error, since the switch is 100 units tall
106
// and recedes at 20 units/frame, which means it will fully recede after 5 frames.
107
if (o->oTimer > 5) {
108
cur_obj_hide();
109
110
// Set to BLUE_COIN_SWITCH_ACT_TICKING
111
o->oAction++;
112
// ???
113
if (!configRespawnCertainItems) {
114
o->oPosY = gMarioObject->oPosY - 40.0f;
115
}
116
117
// Spawn particles. There's a function that calls this same function
118
// with the same arguments, spawn_mist_particles, why didn't they just call that?
119
spawn_mist_particles_variable(0, 0, 46.0f);
120
} else {
121
// Have collision while receding
122
load_object_collision_model();
123
// Recede
124
cur_obj_move_using_fvel_and_gravity();
125
}
126
127
break;
128
case BLUE_COIN_SWITCH_ACT_TICKING:
129
// Tick faster when the blue coins start blinking
130
if (o->oTimer < 200) {
131
play_sound(SOUND_GENERAL2_SWITCH_TICK_FAST, gGlobalSoundSource);
132
} else {
133
play_sound(SOUND_GENERAL2_SWITCH_TICK_SLOW, gGlobalSoundSource);
134
}
135
136
// Delete the switch (which stops the sound) after the last coin is collected,
137
// or after the coins unload after the 240-frame timer expires.
138
if (cur_obj_nearest_object_with_behavior(bhvHiddenBlueCoin) == NULL || o->oTimer > 240) {
139
if (configRespawnCertainItems && o->oTimer > 240) {
140
cur_obj_unhide();
141
o->oAction = BLUE_COIN_SWITCH_ACT_IDLE;
142
o->oPosY = o->oPosY + 120.0f;
143
}
144
else {
145
obj_mark_for_deletion(o);
146
}
147
}
148
149
break;
150
}
151
}
152
153