summaryrefslogtreecommitdiff
path: root/mm/2s2h/Rando/ActorBehavior/ObjTaru.cpp
blob: 7c62711a405b41e86fefef8edf2b6e71129581ea (plain)
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
#include "ActorBehavior.h"
#include <libultraship/bridge/consolevariablebridge.h>
#include "2s2h/ObjectExtension/ActorListIndex.h"
#include "2s2h/CustomItem/CustomItem.h"
#include "assets/2s2h_assets.h"

extern "C" {
#include "variables.h"
#include "src/overlays/actors/ovl_Obj_Taru/z_obj_taru.h"
}

std::map<std::tuple<s16, s16, s16>, RandoCheckId> barrelMap = {
    // Great Bay Temple //
    { { SCENE_SEA, 13, 0 }, RC_GREAT_BAY_TEMPLE_ENTRANCE_BARREL_01 },
    { { SCENE_SEA, 13, 1 }, RC_GREAT_BAY_TEMPLE_ENTRANCE_BARREL_02 },
    { { SCENE_SEA, 13, 2 }, RC_GREAT_BAY_TEMPLE_ENTRANCE_BARREL_03 },
    { { SCENE_SEA, 13, 3 }, RC_GREAT_BAY_TEMPLE_ENTRANCE_BARREL_04 },
    { { SCENE_SEA, 13, 4 }, RC_GREAT_BAY_TEMPLE_ENTRANCE_BARREL_05 },
    { { SCENE_SEA, 13, 5 }, RC_GREAT_BAY_TEMPLE_ENTRANCE_BARREL_06 },
    { { SCENE_SEA, 13, 6 }, RC_GREAT_BAY_TEMPLE_ENTRANCE_BARREL_07 },
    { { SCENE_SEA, 13, 7 }, RC_GREAT_BAY_TEMPLE_ENTRANCE_BARREL_08 },
    { { SCENE_SEA, 12, 11 }, RC_GREAT_BAY_TEMPLE_GREEN_PIPE_1_BARREL_01 },
    { { SCENE_SEA, 12, 12 }, RC_GREAT_BAY_TEMPLE_GREEN_PIPE_1_BARREL_02 },
    { { SCENE_SEA, 12, 10 }, RC_GREAT_BAY_TEMPLE_GREEN_PIPE_1_BARREL_03 },
    { { SCENE_SEA, 9, 7 }, RC_GREAT_BAY_TEMPLE_GREEN_PIPE_2_BARREL_01 },
    { { SCENE_SEA, 9, 6 }, RC_GREAT_BAY_TEMPLE_GREEN_PIPE_2_BARREL_02 },
    { { SCENE_SEA, 2, 2 }, RC_GREAT_BAY_TEMPLE_RED_PIPE_SWITCH_ROOM_BARREL_01 },
    { { SCENE_SEA, 2, 5 }, RC_GREAT_BAY_TEMPLE_RED_PIPE_SWITCH_ROOM_BARREL_02 },
    { { SCENE_SEA, 2, 6 }, RC_GREAT_BAY_TEMPLE_RED_PIPE_SWITCH_ROOM_BARREL_03 },
    { { SCENE_SEA, 2, 4 }, RC_GREAT_BAY_TEMPLE_RED_PIPE_SWITCH_ROOM_BARREL_04 },
    { { SCENE_SEA, 2, 3 }, RC_GREAT_BAY_TEMPLE_RED_PIPE_SWITCH_ROOM_BARREL_05 },

    // Pirates Fortress //
    { { SCENE_PIRATE, 3, 7 }, RC_PIRATE_FORTRESS_CAPTAIN_ROOM_BARREL_01 },
    { { SCENE_PIRATE, 3, 6 }, RC_PIRATE_FORTRESS_CAPTAIN_ROOM_BARREL_02 },
    { { SCENE_TORIDE, 0, 7 }, RC_PIRATE_FORTRESS_ENTRANCE_BARREL },
    { { SCENE_PIRATE, 13, 1 }, RC_PIRATE_FORTRESS_INTERIOR_GUARDED_BARREL },
    { { SCENE_KAIZOKU, 0, 8 }, RC_PIRATE_FORTRESS_PLAZA_BARREL },
    { { SCENE_PIRATE, 9, 8 }, RC_PIRATE_FORTRESS_SEWERS_END_BARREL_01 },
    { { SCENE_PIRATE, 9, 9 }, RC_PIRATE_FORTRESS_SEWERS_END_BARREL_02 },
    { { SCENE_PIRATE, 9, 7 }, RC_PIRATE_FORTRESS_SEWERS_END_BARREL_03 },
    { { SCENE_PIRATE, 9, 6 }, RC_PIRATE_FORTRESS_SEWERS_END_BARREL_04 },
    { { SCENE_PIRATE, 9, 5 }, RC_PIRATE_FORTRESS_SEWERS_END_BARREL_05 },
    { { SCENE_PIRATE, 11, 21 }, RC_PIRATE_FORTRESS_SEWERS_HEART_PIECE_ROOM_BARREL_01 },
    { { SCENE_PIRATE, 11, 20 }, RC_PIRATE_FORTRESS_SEWERS_HEART_PIECE_ROOM_BARREL_02 },
    { { SCENE_PIRATE, 11, 19 }, RC_PIRATE_FORTRESS_SEWERS_HEART_PIECE_ROOM_BARREL_03 },
    { { SCENE_PIRATE, 11, 18 }, RC_PIRATE_FORTRESS_SEWERS_HEART_PIECE_ROOM_BARREL_04 },
    { { SCENE_PIRATE, 11, 17 }, RC_PIRATE_FORTRESS_SEWERS_HEART_PIECE_ROOM_BARREL_05 },
    { { SCENE_PIRATE, 11, 16 }, RC_PIRATE_FORTRESS_SEWERS_HEART_PIECE_ROOM_BARREL_06 },
    { { SCENE_PIRATE, 11, 12 }, RC_PIRATE_FORTRESS_SEWERS_HEART_PIECE_ROOM_BARREL_07 },
    { { SCENE_PIRATE, 11, 10 }, RC_PIRATE_FORTRESS_SEWERS_HEART_PIECE_ROOM_BARREL_08 },
    { { SCENE_PIRATE, 11, 9 }, RC_PIRATE_FORTRESS_SEWERS_HEART_PIECE_ROOM_BARREL_09 },
    { { SCENE_PIRATE, 11, 15 }, RC_PIRATE_FORTRESS_SEWERS_HEART_PIECE_ROOM_BARREL_10 },
    { { SCENE_PIRATE, 11, 7 }, RC_PIRATE_FORTRESS_SEWERS_HEART_PIECE_ROOM_BARREL_11 },
    { { SCENE_PIRATE, 11, 6 }, RC_PIRATE_FORTRESS_SEWERS_HEART_PIECE_ROOM_BARREL_12 },
    { { SCENE_PIRATE, 11, 11 }, RC_PIRATE_FORTRESS_SEWERS_HEART_PIECE_ROOM_BARREL_13 },
    { { SCENE_PIRATE, 11, 14 }, RC_PIRATE_FORTRESS_SEWERS_HEART_PIECE_ROOM_BARREL_14 },
    { { SCENE_PIRATE, 11, 8 }, RC_PIRATE_FORTRESS_SEWERS_HEART_PIECE_ROOM_BARREL_15 },
    { { SCENE_PIRATE, 11, 13 }, RC_PIRATE_FORTRESS_SEWERS_HEART_PIECE_ROOM_BARREL_16 },
};

void ObjTaru_RandoDraw(Actor* actor, PlayState* play) {
    if (!CVarGetInteger("gRando.CSMC", 0)) {
        Gfx_DrawDListOpa(play, (Gfx*)gBarrelJunkDL);
        return;
    }

    RandoCheckId randoCheckId = Rando::ActorBehavior::GetObjectRandoCheckId(actor);
    RandoItemId randoItemId = Rando::ConvertItem(RANDO_SAVE_CHECKS[randoCheckId].randoItemId, randoCheckId);
    RandoItemType randoItemType = Rando::StaticData::Items[randoItemId].randoItemType;

    switch (randoItemType) {
        case RITYPE_BOSS_KEY:
            Gfx_DrawDListOpa(play, (Gfx*)gBarrelBossKeyDL);
            break;
        case RITYPE_HEALTH:
            Gfx_DrawDListOpa(play, (Gfx*)gBarrelHeartDL);
            break;
        case RITYPE_LESSER:
            Gfx_DrawDListOpa(play, (Gfx*)gBarrelMinorDL);
            break;
        case RITYPE_MAJOR:
            Gfx_DrawDListOpa(play, (Gfx*)gBarrelMajorDL);
            break;
        case RITYPE_MASK:
            Gfx_DrawDListOpa(play, (Gfx*)gBarrelMaskDL);
            break;
        case RITYPE_SKULLTULA_TOKEN:
            Gfx_DrawDListOpa(play, (Gfx*)gBarrelTokenDL);
            break;
        case RITYPE_SMALL_KEY:
            Gfx_DrawDListOpa(play, (Gfx*)gBarrelSmallKeyDL);
            break;
        case RITYPE_STRAY_FAIRY:
            Gfx_DrawDListOpa(play, (Gfx*)gBarrelFairyDL);
            break;
        default:
            Gfx_DrawDListOpa(play, (Gfx*)gBarrelJunkDL);
            break;
    }
}

void Rando::ActorBehavior::InitObjTaruBehavior() {
    // Identify the barrel based on scene ID, room, and actor list index
    COND_ID_HOOK(OnActorInit, ACTOR_OBJ_TARU, IS_RANDO, [](Actor* actor) {
        RandoCheckId randoCheckId = RC_UNKNOWN;

        s16 actorListIndex = GetActorListIndex(actor);
        auto it = barrelMap.find({ gPlayState->sceneId, gPlayState->roomCtx.curRoom.num, actorListIndex });
        if (it != barrelMap.end()) {
            randoCheckId = it->second;
        }

        if (!RANDO_SAVE_CHECKS[randoCheckId].shuffled || RANDO_SAVE_CHECKS[randoCheckId].cycleObtained) {
            return;
        }

        Rando::ActorBehavior::SetObjectRandoCheckId(actor, randoCheckId);
        if (!RANDO_SAVE_CHECKS[randoCheckId].obtained) {
            actor->draw = ObjTaru_RandoDraw;
        }
    });

    COND_VB_SHOULD(VB_BARREL_OR_CRATE_DROP_COLLECTIBLE, IS_RANDO, {
        Actor* actor = va_arg(args, Actor*);
        RandoCheckId randoCheckId = GetObjectRandoCheckId(actor);

        if (actor->id != ACTOR_OBJ_TARU || randoCheckId == RC_UNKNOWN) {
            return;
        }

        *should = false;

        EnItem00* spawn = CustomItem::Spawn(
            actor->world.pos.x, actor->world.pos.y, actor->world.pos.z, 0,
            CustomItem::KILL_ON_TOUCH | CustomItem::TOSS_ON_SPAWN, randoCheckId,
            [](Actor* actor, PlayState* play) {
                auto& randoStaticCheck = Rando::StaticData::Checks[(RandoCheckId)CUSTOM_ITEM_PARAM];
                switch (randoStaticCheck.flagType) {
                    case FLAG_NONE:
                        if (RANDO_SAVE_CHECKS[CUSTOM_ITEM_PARAM].shuffled) {
                            RANDO_SAVE_CHECKS[CUSTOM_ITEM_PARAM].eligible = true;
                        }
                        break;
                    case FLAG_CYCL_SCENE_COLLECTIBLE:
                        Flags_SetCollectible(play, randoStaticCheck.flag);
                        break;
                    default:
                        break;
                }
            },
            [](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);
            });
    });
}