summaryrefslogtreecommitdiff
path: root/src/Game/DLC/aocManager.h
blob: 9dd19636191e8c5359de3c3373c3f39f15942781 (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
#pragma once

#include <container/seadSafeArray.h>
#include <heap/seadDisposer.h>
#include <math/seadVector.h>
#include <prim/seadBitFlag.h>
#include <prim/seadEnum.h>
#include <prim/seadSafeString.h>
#include "KingSystem/GameData/gdtManager.h"
#include "KingSystem/Resource/resHandle.h"
#include "KingSystem/Resource/resResourceMgrTask.h"
#include "KingSystem/Utils/Types.h"

namespace ksys {
class OverlayArena;
}

namespace sead {
class FileDevice;
}

namespace uking::aoc {

// TODO
class Manager {
    SEAD_SINGLETON_DISPOSER(Manager)
    Manager();
    ~Manager();

public:
    void init(sead::Heap* heap);

    u32 getVersion() const { return mVersion; }

    /// @return Whether the Master Trials DLC is supported.
    bool hasAoc2() const { return mVersion >= 0x200; }

    /// @return Whether the Champion's Ballad DLC is supported.
    bool hasAoc3() const { return mVersion >= 0x300; }

    void loadAocMainFieldPack(ksys::OverlayArena* arena);
    void registerAocMainFieldPack();
    void unloadAocMainFieldPack();

    sead::FileDevice* getFileDeviceForMapFile(const sead::SafeString& path) const;
    bool getFileDeviceForMap(sead::FileDevice** p_file_device, ksys::res::Handle** p_handle,
                             const sead::SafeString& path);
    sead::FileDevice* getFileDeviceForStaticCompound(const sead::SafeString& path) const;
    sead::FileDevice* getFileDeviceForTeraMesh(const sead::SafeString& path) const;
    sead::FileDevice* getFileDeviceForNavMesh(const sead::SafeString& path) const;
    sead::FileDevice* getFileDeviceForTerrain(const sead::SafeString& path) const;
    sead::FileDevice* getFileDeviceForGame(const sead::SafeString& path) const;
    sead::FileDevice* getFileDeviceForUI(const sead::SafeString& path) const;

    bool isAocFile(const sead::SafeString& path, const sead::SafeString& dir,
                   const sead::SafeString& dir_aoc_field,
                   const sead::SafeString& dir_main_field_dungeon,
                   const sead::SafeString& dir_cdungeon) const;
    static bool isAocDungeon(const sead::SafeString& map_name);
    static bool isAocMap(const sead::SafeString& map_type, const sead::SafeString& map_name);
    static bool isAocField(const sead::SafeString& map_type);

    sead::FileDevice* getFileDeviceForDungeonPack(const sead::SafeString& path) const;
    void registerAocPack(ksys::res::Handle* pack);
    bool aocPackHasFile(const sead::SafeString& path) const;

    bool changeMoviePath(sead::BufferedSafeString& path) const;

    void parseAocMainFieldStaticInfo(const al::ByamlIter& iter);
    // TODO: figure out what this does
    bool getSomePos(sead::Vector3f* translate, u32* p_mask, u32* mask);

    bool parseVersion();
    void setGameDataFlags() const;

private:
    SEAD_ENUM(GameDataFlag, AoCVerAtLastPlay ,LatestAoCVerPlayed ,HasAoCVer1 ,HasAoCVer2 ,HasAoCVer3)
    SEAD_ENUM(VersionError, TooNew, TooOld)

    struct DLCPosition {
        sead::Vector3f translate = sead::Vector3f::zero;
        sead::Vector3f rotate = sead::Vector3f::zero;
        sead::Vector3f translate2 = sead::Vector3f::zero;
        float scale = 0.0;
        ksys::gdt::FlagHandle flag_handle = ksys::gdt::InvalidHandle;
    };
    KSYS_CHECK_SIZE_NX150(DLCPosition, 0x2c);

    struct VersionFile {
        bool readVersion();

        ksys::res::Handle file_handle;
        sead::FixedSafeString<16> string;
    };
    KSYS_CHECK_SIZE_NX150(VersionFile, 0x78);

    void loadVersionFile();
    void checkVersion();

    void resetFlags();
    void initGameData();
    void reinitFlags();
    void onGdtReinit(ksys::gdt::Manager::ReinitEvent* event);

    sead::FileDevice* mFileDevice{};

    ksys::res::FileDevicePrefix mVersionFileDevPrefix;
    VersionFile mVersionFile{};
    u32 mVersion{};

    ksys::res::Handle mAocMainFieldPack;
    ksys::res::FileDevicePrefix mAocMainFieldPackPrefix;
    ksys::res::Handle* mAocPack{};
    ksys::res::FileDevicePrefix mAocPackPrefix;

    sead::SafeArray<DLCPosition, 20> mDLCPositions;

    ksys::gdt::FlagHandle mFlagAocVerAtLastPlay{};
    ksys::gdt::FlagHandle mFlagLatestAocVerPlayed{};
    ksys::gdt::FlagHandle mFlagHasAocVer1{};
    ksys::gdt::FlagHandle mFlagHasAocVer2{};
    ksys::gdt::FlagHandle mFlagHasAocVer3{};
    ksys::gdt::Manager::ReinitSignal::Slot mGdtReinitSlot;

    sead::BitFlag8 mVersionFlags{};
#ifdef NNSDK
    u8* mAocFsCache{};
#endif
};
KSYS_CHECK_SIZE_NX150(Manager, 0x598);

}  // namespace uking::aoc