1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
|
#include "ActorBehavior.h"
#include <libultraship/bridge/consolevariablebridge.h>
#include "2s2h/CustomItem/CustomItem.h"
#include "assets/2s2h_assets.h"
#include "2s2h/ObjectExtension/ActorListIndex.h"
#include "2s2h/ShipUtils.h"
extern "C" {
#include "variables.h"
#include "src/overlays/actors/ovl_Obj_Snowball/z_obj_snowball.h"
#include "src/overlays/actors/ovl_Obj_Snowball2/z_obj_snowball2.h"
void func_80B02D58(ObjSnowball* snowballActor, PlayState* play);
}
// clang-format off
std::map<std::tuple<s16, s16, s16>, RandoCheckId> snowballActorIdMap = {
{ { SCENE_11GORONNOSATO, 0, 29 }, RC_GORON_VILLAGE_SMALL_SNOWBALL_01 },
{ { SCENE_11GORONNOSATO, 0, 30 }, RC_GORON_VILLAGE_SMALL_SNOWBALL_02 },
{ { SCENE_11GORONNOSATO, 0, 31 }, RC_GORON_VILLAGE_SMALL_SNOWBALL_03 },
{ { SCENE_11GORONNOSATO, 0, 32 }, RC_GORON_VILLAGE_SMALL_SNOWBALL_04 },
{ { SCENE_11GORONNOSATO, 0, 33 }, RC_GORON_VILLAGE_SMALL_SNOWBALL_05 },
{ { SCENE_11GORONNOSATO, 0, 34 }, RC_GORON_VILLAGE_SMALL_SNOWBALL_06 },
{ { SCENE_11GORONNOSATO, 0, 35 }, RC_GORON_VILLAGE_SMALL_SNOWBALL_07 },
{ { SCENE_11GORONNOSATO, 0, 36 }, RC_GORON_VILLAGE_SMALL_SNOWBALL_08 },
{ { SCENE_11GORONNOSATO, 0, 37 }, RC_GORON_VILLAGE_SMALL_SNOWBALL_09 },
{ { SCENE_11GORONNOSATO, 0, 38 }, RC_GORON_VILLAGE_SMALL_SNOWBALL_10 },
{ { SCENE_11GORONNOSATO, 0, 39 }, RC_GORON_VILLAGE_SMALL_SNOWBALL_11 },
{ { SCENE_11GORONNOSATO, 0, 40 }, RC_GORON_VILLAGE_SMALL_SNOWBALL_12 },
{ { SCENE_11GORONNOSATO, 0, 50 }, RC_GORON_VILLAGE_LARGE_SNOWBALL_01 },
{ { SCENE_11GORONNOSATO, 0, 51 }, RC_GORON_VILLAGE_LARGE_SNOWBALL_02 },
{ { SCENE_11GORONNOSATO, 0, 52 }, RC_GORON_VILLAGE_LARGE_SNOWBALL_03 },
{ { SCENE_11GORONNOSATO, 0, 53 }, RC_GORON_VILLAGE_LARGE_SNOWBALL_04 },
{ { SCENE_11GORONNOSATO, 0, 54 }, RC_GORON_VILLAGE_LARGE_SNOWBALL_05 },
{ { SCENE_11GORONNOSATO, 0, 55 }, RC_GORON_VILLAGE_LARGE_SNOWBALL_06 },
{ { SCENE_11GORONNOSATO, 0, 56 }, RC_GORON_VILLAGE_LARGE_SNOWBALL_07 },
{ { SCENE_11GORONNOSATO, 0, 57 }, RC_GORON_VILLAGE_LARGE_SNOWBALL_08 },
{ { SCENE_11GORONNOSATO, 0, 58 }, RC_GORON_VILLAGE_LARGE_SNOWBALL_09 },
{ { SCENE_10YUKIYAMANOMURA, 0, 39 }, RC_MOUNTAIN_VILLAGE_SMALL_SNOWBALL_01 },
{ { SCENE_10YUKIYAMANOMURA, 0, 40 }, RC_MOUNTAIN_VILLAGE_SMALL_SNOWBALL_02 },
{ { SCENE_10YUKIYAMANOMURA, 0, 41 }, RC_MOUNTAIN_VILLAGE_SMALL_SNOWBALL_03 },
{ { SCENE_10YUKIYAMANOMURA, 0, 42 }, RC_MOUNTAIN_VILLAGE_SMALL_SNOWBALL_04 },
{ { SCENE_10YUKIYAMANOMURA, 0, 43 }, RC_MOUNTAIN_VILLAGE_SMALL_SNOWBALL_05 },
{ { SCENE_10YUKIYAMANOMURA, 0, 49 }, RC_MOUNTAIN_VILLAGE_SMALL_SNOWBALL_10 },
{ { SCENE_10YUKIYAMANOMURA, 0, 50 }, RC_MOUNTAIN_VILLAGE_SMALL_SNOWBALL_11 },
{ { SCENE_10YUKIYAMANOMURA, 0, 53 }, RC_MOUNTAIN_VILLAGE_SMALL_SNOWBALL_08 },
{ { SCENE_10YUKIYAMANOMURA, 0, 54 }, RC_MOUNTAIN_VILLAGE_SMALL_SNOWBALL_09 },
{ { SCENE_10YUKIYAMANOMURA, 0, 55 }, RC_MOUNTAIN_VILLAGE_SMALL_SNOWBALL_06 },
{ { SCENE_10YUKIYAMANOMURA, 0, 56 }, RC_MOUNTAIN_VILLAGE_SMALL_SNOWBALL_07 },
{ { SCENE_13HUBUKINOMITI, 0, 33 }, RC_PATH_TO_MOUNTAIN_VILLAGE_LARGE_SNOWBALL_08 },
{ { SCENE_13HUBUKINOMITI, 0, 34 }, RC_PATH_TO_MOUNTAIN_VILLAGE_LARGE_SNOWBALL_05 },
{ { SCENE_13HUBUKINOMITI, 0, 35 }, RC_PATH_TO_MOUNTAIN_VILLAGE_LARGE_SNOWBALL_06 },
{ { SCENE_13HUBUKINOMITI, 0, 36 }, RC_PATH_TO_MOUNTAIN_VILLAGE_LARGE_SNOWBALL_07 },
{ { SCENE_13HUBUKINOMITI, 0, 37 }, RC_PATH_TO_MOUNTAIN_VILLAGE_SMALL_SNOWBALL_01 },
{ { SCENE_13HUBUKINOMITI, 0, 38 }, RC_PATH_TO_MOUNTAIN_VILLAGE_SMALL_SNOWBALL_02 },
{ { SCENE_13HUBUKINOMITI, 0, 39 }, RC_PATH_TO_MOUNTAIN_VILLAGE_SMALL_SNOWBALL_03 },
{ { SCENE_13HUBUKINOMITI, 0, 40 }, RC_PATH_TO_MOUNTAIN_VILLAGE_SMALL_SNOWBALL_04 },
{ { SCENE_14YUKIDAMANOMITI, 0, 9 }, RC_PATH_TO_SNOWHEAD_SMALL_SNOWBALL_01 },
{ { SCENE_14YUKIDAMANOMITI, 0, 10 }, RC_PATH_TO_SNOWHEAD_SMALL_SNOWBALL_02 },
{ { SCENE_14YUKIDAMANOMITI, 0, 11 }, RC_PATH_TO_SNOWHEAD_SMALL_SNOWBALL_03 },
{ { SCENE_14YUKIDAMANOMITI, 0, 28 }, RC_PATH_TO_SNOWHEAD_LARGE_SNOWBALL_03 },
{ { SCENE_14YUKIDAMANOMITI, 0, 29 }, RC_PATH_TO_SNOWHEAD_LARGE_SNOWBALL_04 },
{ { SCENE_14YUKIDAMANOMITI, 0, 30 }, RC_PATH_TO_SNOWHEAD_LARGE_SNOWBALL_01 },
{ { SCENE_14YUKIDAMANOMITI, 0, 31 }, RC_PATH_TO_SNOWHEAD_LARGE_SNOWBALL_02 },
{ { SCENE_12HAKUGINMAE, 0, 42 }, RC_SNOWHEAD_SMALL_SNOWBALL_01 },
{ { SCENE_12HAKUGINMAE, 0, 43 }, RC_SNOWHEAD_SMALL_SNOWBALL_02 },
{ { SCENE_12HAKUGINMAE, 0, 44 }, RC_SNOWHEAD_SMALL_SNOWBALL_03 },
{ { SCENE_12HAKUGINMAE, 0, 45 }, RC_SNOWHEAD_SMALL_SNOWBALL_04 },
{ { SCENE_12HAKUGINMAE, 0, 46 }, RC_SNOWHEAD_LARGE_SNOWBALL_01 },
{ { SCENE_12HAKUGINMAE, 0, 47 }, RC_SNOWHEAD_LARGE_SNOWBALL_02 },
{ { SCENE_12HAKUGINMAE, 0, 48 }, RC_SNOWHEAD_LARGE_SNOWBALL_03 },
{ { SCENE_12HAKUGINMAE, 0, 49 }, RC_SNOWHEAD_LARGE_SNOWBALL_04 },
{ { SCENE_12HAKUGINMAE, 0, 50 }, RC_SNOWHEAD_LARGE_SNOWBALL_05 },
{ { SCENE_12HAKUGINMAE, 0, 51 }, RC_SNOWHEAD_LARGE_SNOWBALL_06 },
{ { SCENE_HAKUGIN, 2, 3 }, RC_SNOWHEAD_TEMPLE_BRIDGE_ROOM_SMALL_SNOWBALL_01 },
{ { SCENE_HAKUGIN, 2, 4 }, RC_SNOWHEAD_TEMPLE_BRIDGE_ROOM_SMALL_SNOWBALL_02 },
{ { SCENE_HAKUGIN, 4, 33 }, RC_SNOWHEAD_TEMPLE_CENTRAL_ROOM_LEVEL_2_SMALL_SNOWBALL_06 },
{ { SCENE_HAKUGIN, 4, 34 }, RC_SNOWHEAD_TEMPLE_CENTRAL_ROOM_LEVEL_2_SMALL_SNOWBALL_04 },
{ { SCENE_HAKUGIN, 4, 35 }, RC_SNOWHEAD_TEMPLE_CENTRAL_ROOM_LEVEL_2_SMALL_SNOWBALL_03 },
{ { SCENE_HAKUGIN, 4, 36 }, RC_SNOWHEAD_TEMPLE_CENTRAL_ROOM_LEVEL_2_SMALL_SNOWBALL_02 },
{ { SCENE_HAKUGIN, 4, 37 }, RC_SNOWHEAD_TEMPLE_CENTRAL_ROOM_LEVEL_2_SMALL_SNOWBALL_01 },
{ { SCENE_HAKUGIN, 4, 38 }, RC_SNOWHEAD_TEMPLE_CENTRAL_ROOM_LEVEL_2_SMALL_SNOWBALL_05 },
{ { SCENE_HAKUGIN, 4, 75 }, RC_SNOWHEAD_TEMPLE_CENTRAL_ROOM_LEVEL_3_LARGE_SNOWBALL_01 },
{ { SCENE_HAKUGIN, 4, 76 }, RC_SNOWHEAD_TEMPLE_CENTRAL_ROOM_LEVEL_3_LARGE_SNOWBALL_02 },
{ { SCENE_HAKUGIN, 4, 77 }, RC_SNOWHEAD_TEMPLE_CENTRAL_ROOM_LEVEL_3_LARGE_SNOWBALL_03 },
{ { SCENE_HAKUGIN, 4, 78 }, RC_SNOWHEAD_TEMPLE_CENTRAL_ROOM_LEVEL_3_LARGE_SNOWBALL_04 },
{ { SCENE_HAKUGIN, 7, 8 }, RC_SNOWHEAD_TEMPLE_ICICLE_ROOM_SMALL_SNOWBALL_01 },
{ { SCENE_HAKUGIN, 7, 9 }, RC_SNOWHEAD_TEMPLE_ICICLE_ROOM_SMALL_SNOWBALL_02 },
{ { SCENE_HAKUGIN, 7, 10 }, RC_SNOWHEAD_TEMPLE_ICICLE_ROOM_SMALL_SNOWBALL_03 },
{ { SCENE_HAKUGIN, 7, 11 }, RC_SNOWHEAD_TEMPLE_ICICLE_ROOM_SMALL_SNOWBALL_04 },
{ { SCENE_HAKUGIN, 7, 12 }, RC_SNOWHEAD_TEMPLE_ICICLE_ROOM_SMALL_SNOWBALL_05 },
{ { SCENE_HAKUGIN, 7, 26 }, RC_SNOWHEAD_TEMPLE_ICICLE_ROOM_LARGE_SNOWBALL_01 },
{ { SCENE_HAKUGIN, 10, 8 }, RC_SNOWHEAD_TEMPLE_SNOW_ROOM_SMALL_SNOWBALL_01 },
{ { SCENE_HAKUGIN, 10, 9 }, RC_SNOWHEAD_TEMPLE_SNOW_ROOM_SMALL_SNOWBALL_02 },
{ { SCENE_HAKUGIN, 10, 10 }, RC_SNOWHEAD_TEMPLE_SNOW_ROOM_SMALL_SNOWBALL_03 },
{ { SCENE_HAKUGIN, 10, 11 }, RC_SNOWHEAD_TEMPLE_SNOW_ROOM_SMALL_SNOWBALL_04 },
{ { SCENE_HAKUGIN, 10, 12 }, RC_SNOWHEAD_TEMPLE_SNOW_ROOM_SMALL_SNOWBALL_05 },
{ { SCENE_HAKUGIN, 10, 13 }, RC_SNOWHEAD_TEMPLE_SNOW_ROOM_SMALL_SNOWBALL_06 },
{ { SCENE_HAKUGIN, 10, 14 }, RC_SNOWHEAD_TEMPLE_SNOW_ROOM_SMALL_SNOWBALL_07 },
{ { SCENE_HAKUGIN, 10, 15 }, RC_SNOWHEAD_TEMPLE_SNOW_ROOM_SMALL_SNOWBALL_08 },
{ { SCENE_17SETUGEN, 0, 62 }, RC_TWIN_ISLANDS_SMALL_SNOWBALL_01 },
{ { SCENE_17SETUGEN, 0, 63 }, RC_TWIN_ISLANDS_SMALL_SNOWBALL_02 },
{ { SCENE_17SETUGEN, 0, 64 }, RC_TWIN_ISLANDS_SMALL_SNOWBALL_03 },
{ { SCENE_17SETUGEN, 0, 65 }, RC_TWIN_ISLANDS_SMALL_SNOWBALL_04 },
{ { SCENE_17SETUGEN, 0, 66 }, RC_TWIN_ISLANDS_SMALL_SNOWBALL_05 },
{ { SCENE_17SETUGEN, 0, 67 }, RC_TWIN_ISLANDS_SMALL_SNOWBALL_06 },
// The following large snowballs have different ActorListIndex values each day. Having repeat check map entries is
// fine, so long as there are no overlaps in values for a given scene. Duplicates are organized by Day 1, 2, 3:
{ { SCENE_10YUKIYAMANOMURA, 0, 14 }, RC_MOUNTAIN_VILLAGE_LARGE_SNOWBALL_01 },
{ { SCENE_10YUKIYAMANOMURA, 0, 45 }, RC_MOUNTAIN_VILLAGE_LARGE_SNOWBALL_01 },
{ { SCENE_10YUKIYAMANOMURA, 0, 16 }, RC_MOUNTAIN_VILLAGE_LARGE_SNOWBALL_01 },
{ { SCENE_10YUKIYAMANOMURA, 0, 17 }, RC_MOUNTAIN_VILLAGE_LARGE_SNOWBALL_02 },
{ { SCENE_10YUKIYAMANOMURA, 0, 13 }, RC_MOUNTAIN_VILLAGE_LARGE_SNOWBALL_02 },
{ { SCENE_10YUKIYAMANOMURA, 0, 12 }, RC_MOUNTAIN_VILLAGE_LARGE_SNOWBALL_02 },
{ { SCENE_10YUKIYAMANOMURA, 0, 18 }, RC_MOUNTAIN_VILLAGE_LARGE_SNOWBALL_03 },
{ { SCENE_10YUKIYAMANOMURA, 0, 47 }, RC_MOUNTAIN_VILLAGE_LARGE_SNOWBALL_03 },
{ { SCENE_10YUKIYAMANOMURA, 0, 44 }, RC_MOUNTAIN_VILLAGE_LARGE_SNOWBALL_03 },
{ { SCENE_10YUKIYAMANOMURA, 0, 46 }, RC_MOUNTAIN_VILLAGE_LARGE_SNOWBALL_04 },
{ { SCENE_10YUKIYAMANOMURA, 0, 48 }, RC_MOUNTAIN_VILLAGE_LARGE_SNOWBALL_04 },
{ { SCENE_10YUKIYAMANOMURA, 0, 34 }, RC_MOUNTAIN_VILLAGE_LARGE_SNOWBALL_04 },
{ { SCENE_10YUKIYAMANOMURA, 0, 52 }, RC_MOUNTAIN_VILLAGE_LARGE_SNOWBALL_05 },
{ { SCENE_10YUKIYAMANOMURA, 0, 15 }, RC_MOUNTAIN_VILLAGE_LARGE_SNOWBALL_05 },
{ { SCENE_10YUKIYAMANOMURA, 0, 51 }, RC_MOUNTAIN_VILLAGE_LARGE_SNOWBALL_05 },
{ { SCENE_13HUBUKINOMITI, 0, 26 }, RC_PATH_TO_MOUNTAIN_VILLAGE_LARGE_SNOWBALL_01 },
{ { SCENE_13HUBUKINOMITI, 0, 28 }, RC_PATH_TO_MOUNTAIN_VILLAGE_LARGE_SNOWBALL_01 },
{ { SCENE_13HUBUKINOMITI, 0, 23 }, RC_PATH_TO_MOUNTAIN_VILLAGE_LARGE_SNOWBALL_01 },
{ { SCENE_13HUBUKINOMITI, 0, 42 }, RC_PATH_TO_MOUNTAIN_VILLAGE_LARGE_SNOWBALL_02 },
{ { SCENE_13HUBUKINOMITI, 0, 24 }, RC_PATH_TO_MOUNTAIN_VILLAGE_LARGE_SNOWBALL_02 },
{ { SCENE_13HUBUKINOMITI, 0, 19 }, RC_PATH_TO_MOUNTAIN_VILLAGE_LARGE_SNOWBALL_02 },
{ { SCENE_13HUBUKINOMITI, 0, 31 }, RC_PATH_TO_MOUNTAIN_VILLAGE_LARGE_SNOWBALL_03 },
{ { SCENE_13HUBUKINOMITI, 0, 46 }, RC_PATH_TO_MOUNTAIN_VILLAGE_LARGE_SNOWBALL_03 },
{ { SCENE_13HUBUKINOMITI, 0, 22 }, RC_PATH_TO_MOUNTAIN_VILLAGE_LARGE_SNOWBALL_03 },
{ { SCENE_13HUBUKINOMITI, 0, 30 }, RC_PATH_TO_MOUNTAIN_VILLAGE_LARGE_SNOWBALL_04 },
{ { SCENE_13HUBUKINOMITI, 0, 27 }, RC_PATH_TO_MOUNTAIN_VILLAGE_LARGE_SNOWBALL_04 },
{ { SCENE_13HUBUKINOMITI, 0, 29 }, RC_PATH_TO_MOUNTAIN_VILLAGE_LARGE_SNOWBALL_04 },
{ { SCENE_13HUBUKINOMITI, 0, 41 }, RC_PATH_TO_MOUNTAIN_VILLAGE_LARGE_SNOWBALL_09 },
{ { SCENE_13HUBUKINOMITI, 0, 45 }, RC_PATH_TO_MOUNTAIN_VILLAGE_LARGE_SNOWBALL_09 },
{ { SCENE_13HUBUKINOMITI, 0, 47 }, RC_PATH_TO_MOUNTAIN_VILLAGE_LARGE_SNOWBALL_09 },
{ { SCENE_13HUBUKINOMITI, 0, 43 }, RC_PATH_TO_MOUNTAIN_VILLAGE_LARGE_SNOWBALL_10 },
{ { SCENE_13HUBUKINOMITI, 0, 48 }, RC_PATH_TO_MOUNTAIN_VILLAGE_LARGE_SNOWBALL_10 },
{ { SCENE_13HUBUKINOMITI, 0, 20 }, RC_PATH_TO_MOUNTAIN_VILLAGE_LARGE_SNOWBALL_10 },
{ { SCENE_13HUBUKINOMITI, 0, 44 }, RC_PATH_TO_MOUNTAIN_VILLAGE_LARGE_SNOWBALL_11 },
{ { SCENE_13HUBUKINOMITI, 0, 25 }, RC_PATH_TO_MOUNTAIN_VILLAGE_LARGE_SNOWBALL_11 },
{ { SCENE_13HUBUKINOMITI, 0, 21 }, RC_PATH_TO_MOUNTAIN_VILLAGE_LARGE_SNOWBALL_11 },
{ { SCENE_17SETUGEN, 0, 18 }, RC_TWIN_ISLANDS_LARGE_SNOWBALL_01 },
{ { SCENE_17SETUGEN, 0, 53 }, RC_TWIN_ISLANDS_LARGE_SNOWBALL_01 },
{ { SCENE_17SETUGEN, 0, 43 }, RC_TWIN_ISLANDS_LARGE_SNOWBALL_01 },
{ { SCENE_17SETUGEN, 0, 19 }, RC_TWIN_ISLANDS_LARGE_SNOWBALL_02 },
{ { SCENE_17SETUGEN, 0, 49 }, RC_TWIN_ISLANDS_LARGE_SNOWBALL_02 },
{ { SCENE_17SETUGEN, 0, 45 }, RC_TWIN_ISLANDS_LARGE_SNOWBALL_02 },
{ { SCENE_17SETUGEN, 0, 22 }, RC_TWIN_ISLANDS_LARGE_SNOWBALL_03 },
{ { SCENE_17SETUGEN, 0, 17 }, RC_TWIN_ISLANDS_LARGE_SNOWBALL_03 },
{ { SCENE_17SETUGEN, 0, 42 }, RC_TWIN_ISLANDS_LARGE_SNOWBALL_03 },
{ { SCENE_17SETUGEN, 0, 30 }, RC_TWIN_ISLANDS_LARGE_SNOWBALL_04 },
{ { SCENE_17SETUGEN, 0, 52 }, RC_TWIN_ISLANDS_LARGE_SNOWBALL_04 },
{ { SCENE_17SETUGEN, 0, 44 }, RC_TWIN_ISLANDS_LARGE_SNOWBALL_04 },
{ { SCENE_17SETUGEN, 0, 54 }, RC_TWIN_ISLANDS_LARGE_SNOWBALL_05 },
{ { SCENE_17SETUGEN, 0, 21 }, RC_TWIN_ISLANDS_LARGE_SNOWBALL_05 },
{ { SCENE_17SETUGEN, 0, 28 }, RC_TWIN_ISLANDS_LARGE_SNOWBALL_05 },
{ { SCENE_17SETUGEN, 0, 55 }, RC_TWIN_ISLANDS_LARGE_SNOWBALL_06 },
{ { SCENE_17SETUGEN, 0, 51 }, RC_TWIN_ISLANDS_LARGE_SNOWBALL_06 },
{ { SCENE_17SETUGEN, 0, 13 }, RC_TWIN_ISLANDS_LARGE_SNOWBALL_06 },
{ { SCENE_17SETUGEN, 0, 56 }, RC_TWIN_ISLANDS_LARGE_SNOWBALL_07 },
{ { SCENE_17SETUGEN, 0, 47 }, RC_TWIN_ISLANDS_LARGE_SNOWBALL_07 },
{ { SCENE_17SETUGEN, 0, 40 }, RC_TWIN_ISLANDS_LARGE_SNOWBALL_07 },
{ { SCENE_17SETUGEN, 0, 57 }, RC_TWIN_ISLANDS_LARGE_SNOWBALL_08 },
{ { SCENE_17SETUGEN, 0, 48 }, RC_TWIN_ISLANDS_LARGE_SNOWBALL_08 },
{ { SCENE_17SETUGEN, 0, 20 }, RC_TWIN_ISLANDS_LARGE_SNOWBALL_08 },
{ { SCENE_17SETUGEN, 0, 58 }, RC_TWIN_ISLANDS_LARGE_SNOWBALL_09 },
{ { SCENE_17SETUGEN, 0, 16 }, RC_TWIN_ISLANDS_LARGE_SNOWBALL_09 },
{ { SCENE_17SETUGEN, 0, 46 }, RC_TWIN_ISLANDS_LARGE_SNOWBALL_09 },
{ { SCENE_17SETUGEN, 0, 59 }, RC_TWIN_ISLANDS_LARGE_SNOWBALL_10 },
{ { SCENE_17SETUGEN, 0, 11 }, RC_TWIN_ISLANDS_LARGE_SNOWBALL_10 },
{ { SCENE_17SETUGEN, 0, 14 }, RC_TWIN_ISLANDS_LARGE_SNOWBALL_10 },
{ { SCENE_17SETUGEN, 0, 60 }, RC_TWIN_ISLANDS_LARGE_SNOWBALL_11 },
{ { SCENE_17SETUGEN, 0, 29 }, RC_TWIN_ISLANDS_LARGE_SNOWBALL_11 },
{ { SCENE_17SETUGEN, 0, 41 }, RC_TWIN_ISLANDS_LARGE_SNOWBALL_11 },
{ { SCENE_17SETUGEN, 0, 61 }, RC_TWIN_ISLANDS_LARGE_SNOWBALL_12 },
// Note: RC_TWIN_ISLANDS_LARGE_SNOWBALL_12 does not exist on Day 2
{ { SCENE_17SETUGEN, 0, 15 }, RC_TWIN_ISLANDS_LARGE_SNOWBALL_12 },
{ { SCENE_17SETUGEN, 0, 12 }, RC_TWIN_ISLANDS_LARGE_SNOWBALL_13 },
{ { SCENE_17SETUGEN, 0, 50 }, RC_TWIN_ISLANDS_LARGE_SNOWBALL_13 },
{ { SCENE_17SETUGEN, 0, 4 }, RC_TWIN_ISLANDS_LARGE_SNOWBALL_13 },
};
// clang-format on
// Identify the snowball based on scene ID, room, and actor list index
void IdentifySnowball(Actor* actor, bool* should) {
s16 actorListIndex = GetActorListIndex(actor);
RandoCheckId randoCheckId = RC_UNKNOWN;
auto it = snowballActorIdMap.find({ gPlayState->sceneId, gPlayState->roomCtx.curRoom.num, actorListIndex });
if (it != snowballActorIdMap.end()) {
randoCheckId = it->second;
}
if (!RANDO_SAVE_CHECKS[randoCheckId].shuffled || RANDO_SAVE_CHECKS[randoCheckId].cycleObtained) {
return;
}
Rando::ActorBehavior::SetObjectRandoCheckId(actor, randoCheckId);
}
void SpawnSnowballDrop(Vec3f pos, RandoCheckId randoCheckId) {
CustomItem::Spawn(
pos.x, pos.y, pos.z, 0, CustomItem::KILL_ON_TOUCH | CustomItem::TOSS_ON_SPAWN | CustomItem::ABLE_TO_ZORA_RANG,
randoCheckId,
[](Actor* actor, PlayState* play) {
RandoSaveCheck& randoSaveCheck = RANDO_SAVE_CHECKS[CUSTOM_ITEM_PARAM];
randoSaveCheck.eligible = true;
},
[](Actor* actor, PlayState* play) {
auto& randoSaveCheck = RANDO_SAVE_CHECKS[CUSTOM_ITEM_PARAM];
Matrix_Scale(30.0f, 30.0f, 30.0f, MTXMODE_APPLY);
Rando::DrawItem(Rando::ConvertItem(randoSaveCheck.randoItemId, (RandoCheckId)CUSTOM_ITEM_PARAM),
(RandoCheckId)CUSTOM_ITEM_PARAM, actor);
});
}
void Rando::ActorBehavior::InitObjSnowballBehavior() {
COND_ID_HOOK(ShouldActorInit, ACTOR_OBJ_SNOWBALL, IS_RANDO, IdentifySnowball);
COND_ID_HOOK(ShouldActorInit, ACTOR_OBJ_SNOWBALL2, IS_RANDO, IdentifySnowball);
COND_VB_SHOULD(VB_SNOWBALL_DROP_COLLECTIBLE, IS_RANDO, {
Actor* actor = va_arg(args, Actor*);
RandoCheckId randoCheckId = GetObjectRandoCheckId(actor);
if (randoCheckId == RC_UNKNOWN) {
return;
}
if (!RANDO_SAVE_CHECKS[randoCheckId].cycleObtained) {
SpawnSnowballDrop(actor->world.pos, randoCheckId);
*should = false;
}
});
COND_VB_SHOULD(VB_SNOWBALL_SET_FLAG, IS_RANDO, {
Actor* actor = va_arg(args, Actor*);
ActorId actorToSpawn = (ActorId)va_arg(args, s32);
ObjSnowballActionFunc actorFunction = va_arg(args, ObjSnowballActionFunc);
// Ignore snowballs that drop a collectable, those are handled above with VB_SNOWBALL_DROP_COLLECTIBLE
if (actorFunction == func_80B02D58) {
return;
}
RandoCheckId randoCheckId = GetObjectRandoCheckId(actor);
if (randoCheckId == RC_UNKNOWN) {
return;
}
if (!RANDO_SAVE_CHECKS[randoCheckId].cycleObtained) {
SpawnSnowballDrop(actor->world.pos, randoCheckId);
}
});
}
|